2 | import public Data.Fin
7 | export infixl 8 `shiftL`
, `shiftR`
9 | export infixl 6 `xor`
18 | interface Bits a where
31 | shiftL : a -> Index -> a
34 | shiftR : a -> Index -> a
37 | bit : (i : Index) -> a
44 | complement = xor oneBits
48 | oneBits = complement zeroBits
51 | complementBit : (x : a) -> (i : Index) -> a
52 | complementBit x i = x `xor` bit i
55 | clearBit : (x : a) -> (i : Index) -> a
56 | clearBit x i = x `xor` (bit i .&. x)
59 | testBit : a -> Index -> Bool
62 | setBit : a -> (i : Index) -> a
63 | setBit x i = x .|. bit i
65 | public export %inline
68 | (.&.) = prim__and_Bits8
69 | (.|.) = prim__or_Bits8
70 | xor = prim__xor_Bits8
73 | testBit x i = (x .&. bit i) /= 0
74 | shiftR x = prim__shr_Bits8 x . cast . finToNat
75 | shiftL x = prim__shl_Bits8 x . cast . finToNat
78 | public export %inline
81 | (.&.) = prim__and_Bits16
82 | (.|.) = prim__or_Bits16
83 | xor = prim__xor_Bits16
86 | testBit x i = (x .&. bit i) /= 0
87 | shiftR x = prim__shr_Bits16 x . cast . finToNat
88 | shiftL x = prim__shl_Bits16 x . cast . finToNat
91 | public export %inline
94 | (.&.) = prim__and_Bits32
95 | (.|.) = prim__or_Bits32
96 | xor = prim__xor_Bits32
99 | testBit x i = (x .&. bit i) /= 0
100 | shiftR x = prim__shr_Bits32 x . cast . finToNat
101 | shiftL x = prim__shl_Bits32 x . cast . finToNat
102 | oneBits = 0xffffffff
104 | public export %inline
107 | (.&.) = prim__and_Bits64
108 | (.|.) = prim__or_Bits64
109 | xor = prim__xor_Bits64
112 | testBit x i = (x .&. bit i) /= 0
113 | shiftR x = prim__shr_Bits64 x . cast . finToNat
114 | shiftL x = prim__shl_Bits64 x . cast . finToNat
115 | oneBits = 0xffffffffffffffff
117 | public export %inline
120 | (.&.) = prim__and_Int
121 | (.|.) = prim__or_Int
122 | xor = prim__xor_Int
125 | testBit x i = (x .&. bit i) /= 0
126 | shiftR x = prim__shr_Int x . cast . finToNat
127 | shiftL x = prim__shl_Int x . cast . finToNat
130 | public export %inline
133 | (.&.) = prim__and_Int8
134 | (.|.) = prim__or_Int8
135 | xor = prim__xor_Int8
138 | testBit x i = (x .&. bit i) /= 0
139 | shiftR x = prim__shr_Int8 x . cast . finToNat
140 | shiftL x = prim__shl_Int8 x . cast . finToNat
143 | public export %inline
146 | (.&.) = prim__and_Int16
147 | (.|.) = prim__or_Int16
148 | xor = prim__xor_Int16
151 | testBit x i = (x .&. bit i) /= 0
152 | shiftR x = prim__shr_Int16 x . cast . finToNat
153 | shiftL x = prim__shl_Int16 x . cast . finToNat
156 | public export %inline
159 | (.&.) = prim__and_Int32
160 | (.|.) = prim__or_Int32
161 | xor = prim__xor_Int32
164 | testBit x i = (x .&. bit i) /= 0
165 | shiftR x = prim__shr_Int32 x . cast . finToNat
166 | shiftL x = prim__shl_Int32 x . cast . finToNat
169 | public export %inline
172 | (.&.) = prim__and_Int64
173 | (.|.) = prim__or_Int64
174 | xor = prim__xor_Int64
177 | testBit x i = (x .&. bit i) /= 0
178 | shiftR x = prim__shr_Int64 x . cast . finToNat
179 | shiftL x = prim__shl_Int64 x . cast . finToNat
182 | public export %inline
185 | (.&.) = prim__and_Integer
186 | (.|.) = prim__or_Integer
187 | xor = prim__xor_Integer
190 | testBit x i = (x .&. bit i) /= 0
191 | shiftR x = prim__shr_Integer x . natToInteger
192 | shiftL x = prim__shl_Integer x . natToInteger
200 | interface Bits a => FiniteBits a where
205 | bitsToIndex : Fin bitSize -> Index {a}
209 | popCount : a -> Nat
212 | rotR : a -> Fin bitSize -> a
214 | (x `shiftR` (bitsToIndex i)) .|. (x `shiftL` (bitsToIndex $
finS (complement i)))
217 | rotL : a -> Fin bitSize -> a
219 | (x `shiftL` (bitsToIndex i)) .|. (x `shiftR` (bitsToIndex $
finS (complement i)))
222 | asBitVector : FiniteBits a => a -> Vect (bitSize {a}) Bool
223 | asBitVector v = testBit v . bitsToIndex <$> allFins _
226 | asString : FiniteBits a => a -> String
227 | asString = pack . toList . map (\ b => ifThenElse b '1' '0') . reverse . asBitVector
229 | public export %inline
230 | FiniteBits Bits8 where
236 | let x1 = (x0 .&. 0x55) + ((x0 `shiftR` 1) .&. 0x55)
237 | x2 = (x1 .&. 0x33) + ((x1 `shiftR` 2) .&. 0x33)
238 | x3 = ((x2 + (x2 `shiftR` 4)) .&. 0x0F)
241 | public export %inline
242 | FiniteBits Bits16 where
248 | let x1 = (x0 .&. 0x5555) + ((x0 `shiftR` 1) .&. 0x5555)
249 | x2 = (x1 .&. 0x3333) + ((x1 `shiftR` 2) .&. 0x3333)
250 | x3 = ((x2 + (x2 `shiftR` 4)) .&. 0x0F0F)
251 | x4 = (x3 * 0x0101) `shiftR` 8
254 | public export %inline
255 | FiniteBits Bits32 where
261 | let x1 = (x0 .&. 0x55555555) + ((x0 `shiftR` 1) .&. 0x55555555)
262 | x2 = (x1 .&. 0x33333333) + ((x1 `shiftR` 2) .&. 0x33333333)
263 | x3 = ((x2 + (x2 `shiftR` 4)) .&. 0x0F0F0F0F)
264 | x4 = (x3 * 0x01010101) `shiftR` 24
267 | public export %inline
268 | FiniteBits Bits64 where
274 | let x1 = (x0 .&. 0x5555555555555555) +
275 | ((x0 `shiftR` 1) .&. 0x5555555555555555)
276 | x2 = (x1 .&. 0x3333333333333333)
277 | + ((x1 `shiftR` 2) .&. 0x3333333333333333)
278 | x3 = ((x2 + (x2 `shiftR` 4)) .&. 0x0F0F0F0F0F0F0F0F)
279 | x4 = (x3 * 0x0101010101010101) `shiftR` 56
282 | public export %inline
283 | FiniteBits Int where
293 | let x0 = x `clearBit` 63
294 | x1 = (x0 .&. 0x5555555555555555)
295 | + ((x0 `shiftR` 1) .&. 0x5555555555555555)
296 | x2 = (x1 .&. 0x3333333333333333)
297 | + ((x1 `shiftR` 2) .&. 0x3333333333333333)
298 | x3 = ((x2 + (x2 `shiftR` 4)) .&. 0x0F0F0F0F0F0F0F0F)
299 | x4 = (x3 * 0x0101010101010101) `shiftR` 56
300 | x5 = if x < 0 then x4 + 1 else x4
309 | in cast $
ux `rotR` i
314 | in cast $
ux `rotL` i
316 | public export %inline
317 | FiniteBits Int8 where
327 | let x0 = x `clearBit` 7
328 | x1 = (x0 .&. 0x55) + ((x0 `shiftR` 1) .&. 0x55)
329 | x2 = (x1 .&. 0x33) + ((x1 `shiftR` 2) .&. 0x33)
330 | x3 = ((x2 + (x2 `shiftR` 4)) .&. 0x0F)
331 | x4 = if x < 0 then x3 + 1 else x3
340 | in cast $
ux `rotR` i
345 | in cast $
ux `rotL` i
347 | public export %inline
348 | FiniteBits Int16 where
358 | let x0 = x `clearBit` 15
359 | x1 = (x0 .&. 0x5555) + ((x0 `shiftR` 1) .&. 0x5555)
360 | x2 = (x1 .&. 0x3333) + ((x1 `shiftR` 2) .&. 0x3333)
361 | x3 = ((x2 + (x2 `shiftR` 4)) .&. 0x0F0F)
362 | x4 = (x3 * 0x0101) `shiftR` 8
363 | x5 = if x < 0 then x4 + 1 else x4
372 | in cast $
ux `rotR` i
377 | in cast $
ux `rotL` i
379 | public export %inline
380 | FiniteBits Int32 where
390 | let x0 = x `clearBit` 31
391 | x1 = (x0 .&. 0x55555555) + ((x0 `shiftR` 1) .&. 0x55555555)
392 | x2 = (x1 .&. 0x33333333) + ((x1 `shiftR` 2) .&. 0x33333333)
393 | x3 = ((x2 + (x2 `shiftR` 4)) .&. 0x0F0F0F0F)
394 | x4 = (x3 * 0x01010101) `shiftR` 24
395 | x5 = if x < 0 then x4 + 1 else x4
404 | in cast $
ux `rotR` i
409 | in cast $
ux `rotL` i
411 | public export %inline
412 | FiniteBits Int64 where
422 | let x0 = x `clearBit` 63
423 | x1 = (x0 .&. 0x5555555555555555)
424 | + ((x0 `shiftR` 1) .&. 0x5555555555555555)
425 | x2 = (x1 .&. 0x3333333333333333)
426 | + ((x1 `shiftR` 2) .&. 0x3333333333333333)
427 | x3 = ((x2 + (x2 `shiftR` 4)) .&. 0x0F0F0F0F0F0F0F0F)
428 | x4 = (x3 * 0x0101010101010101) `shiftR` 56
429 | x5 = if x < 0 then x4 + 1 else x4
438 | in cast $
ux `rotR` i
443 | in cast $
ux `rotL` i