Add support for bitreverse primop
[ghc.git] / testsuite / tests / primops / should_run / T16164.hs
1 import Data.Bits (FiniteBits (..), unsafeShiftL, unsafeShiftR, (.&.),
2 (.|.))
3 import Data.Char (intToDigit)
4 import Data.Word (Word8, Word16, Word32, Word64, bitReverse8,
5 bitReverse16, bitReverse32, bitReverse64)
6 import Numeric (showIntAtBase)
7
8 -- | Given a word, check:
9 --
10 -- * if the reverse of its @String@ representation in base 2 matches the
11 -- @String@ representation of that word with its bit order reversed.
12 -- order reversed, and
13 -- * if reversing its bits and then reverse the resulting word's bits again
14 -- yields the same word.
15 -- Takes the bit reversion function as an argument so different word types
16 -- can be used with their own functions.
17 test :: (FiniteBits a, Integral a, Show a) => (a -> a) -> a -> Bool
18 test bitReverter x =
19 let -- These zeroes are to left-pad the base-2 representation of
20 -- @x@ so that the string has one ASCII character per bit in the
21 -- word type e.g. @Word8@s produce strings with 8 characters.
22 leftPad = countLeadingZeros x
23 -- These zeroes are to left-pad the base-2 representation of
24 -- bit-reversed @x@ so that the string has one ASCII character per bit
25 -- in the word type e.g. @Word8@s produce strings with 8 characters.
26 reverseLeftPad = countTrailingZeros x
27 toBinaryString a = showIntAtBase 2 intToDigit a ""
28 binaryX = replicate leftPad '0' ++ toBinaryString x
29 revX = bitReverter x
30 binaryRevX = replicate reverseLeftPad '0' ++ toBinaryString revX
31 revRevX = bitReverter revX
32 in (x == revRevX) && (reverse binaryX == binaryRevX)
33
34 word8s :: [Word8]
35 word8s = [29, 31, 61, 102, 129, 129, 153, 213, 241, 246]
36
37 word16s :: [Word16]
38 word16s = [555, 3298, 4548, 12557, 16464, 16481, 40722, 51736, 55009, 62554]
39
40 word32s :: [Word32]
41 word32s = [6585, 10944, 21639, 25202, 27228, 836732395, 848624442, 3798715760, 3909052537, 4224371164]
42
43 word64s :: [Word64]
44 word64s = [2451351, 5096456, 8248539, 13039372, 15656413, 367814400638368418, 15152819454280096771, 15184978641026131315, 16329695467052396714, 17634654963076276082]
45
46 main :: IO ()
47 main = do
48 let printer f = mapM_ (print . test f)
49 printer bitReverse8 word8s
50 printer bitReverse16 word16s
51 printer bitReverse32 word32s
52 printer bitReverse64 word64s