;;;; The bit operators at every integer width, typed. Every operand is a ;;;; global or a parameter, so -O2 folds nothing and the x86 backend lowers ;;;; each one; the three builds must print the same lines. One generic body ;;;; covers the widths, which also walks the integer? bound. (defn bits [a $t b $t n $t] () {:where (integer? $t)} (println (bit-and a b) (bit-or a b) (bit-xor a b) (bit-not a) (bit-and a b n) (&& a b) (|| a b) (^^ a b)) (println (<< a n) (>> a n) (rotate-left a n) (rotate-right a n)) (println (popcount a) (leading-zeros a) (trailing-zeros a) (popcount b) (leading-zeros b) (trailing-zeros b))) (defonce i8a i8 -100) (defonce i8b i8 45) (defonce i8n i8 3) (defonce i16a i16 -30000) (defonce i16b i16 12345) (defonce i16n i16 5) (defonce i32a i32 -2000000000) (defonce i32b i32 123456789) (defonce i32n i32 7) (defonce i64a i64 -9000000000000000000) (defonce i64b i64 1234567890123) (defonce i64n i64 13) (defonce u8a u8 200) (defonce u8b u8 45) (defonce u8n u8 3) (defonce u16a u16 60000) (defonce u16b u16 12345) (defonce u16n u16 5) (defonce u32a u32 4000000000) (defonce u32b u32 123456789) (defonce u32n u32 7) (defonce u64a u64 18000000000000000000) (defonce u64b u64 1234567890123) (defonce u64n u64 13) ;; Zero, for the counts: leading-zeros and trailing-zeros answer the width. (defonce z8 i8 0) (defonce z16 u16 0) (defonce z32 i32 0) (defonce z64 u64 0) ;; A rotation count past the width, and a negative one: both modulo the width. (defonce big32 i32 35) (defonce neg32 i32 -1) (defonce big8 u8 11) (defn main [] i32 (bits i8a i8b i8n) (bits i16a i16b i16n) (bits i32a i32b i32n) (bits i64a i64b i64n) (bits u8a u8b u8n) (bits u16a u16b u16n) (bits u32a u32b u32n) (bits u64a u64b u64n) (println (leading-zeros z8) (trailing-zeros z8) (leading-zeros z16) (trailing-zeros z16) (leading-zeros z32) (trailing-zeros z32) (leading-zeros z64) (trailing-zeros z64) (popcount z64)) (println (rotate-left i32b big32) (rotate-right i32b big32) (rotate-left i32b neg32) (rotate-left u8a big8) (rotate-right u8a big8)) ;; A narrower count widens to the value's type. (println (<< i64b u8n) (rotate-left u64b u8n)) 0)