T9430.hs 5.65 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE UnboxedTuples #-}

module Main where

import GHC.Exts

checkI
    :: (Int, Int)                          -- ^ expected results
    -> (Int# -> Int# -> (# Int#, Int# #))  -- ^ primop
    -> Int                                 -- ^ first argument
    -> Int                                 -- ^ second argument
    -> Maybe String                        -- ^ maybe error
checkI (expX, expY) op (I# a) (I# b) =
  case op a b of
      (# x, y #)
          | I# x == expX && I# y == expY -> Nothing
          | otherwise ->
              Just $
                  "Expected " ++ show expX ++ " and " ++ show expY
                      ++ " but got " ++ show (I# x) ++ " and " ++ show (I# y)
checkW
    :: (Word, Word)                            -- ^ expected results
    -> (Word# -> Word# -> (# Word#, Word# #))  -- ^ primop
    -> Word                                    -- ^ first argument
    -> Word                                    -- ^ second argument
    -> Maybe String                            -- ^ maybe error
checkW (expX, expY) op (W# a) (W# b) =
    case op a b of
        (# x, y #)
            | W# x == expX && W# y == expY -> Nothing
            | otherwise ->
                Just $
                    "Expected " ++ show expX ++ " and " ++ show expY
                        ++ " but got " ++ show (W# x) ++ " and " ++ show (W# y)

37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
checkW2
    :: (Word, Word)  -- ^ expected results
    -> (Word# -> Word# -> Word# -> (# Word#, Word# #))
                     -- ^ primop
    -> Word          -- ^ first argument
    -> Word          -- ^ second argument
    -> Word          -- ^ third argument
    -> Maybe String  -- ^ maybe error
checkW2 (expX, expY) op (W# a) (W# b) (W# c) =
    case op a b c of
        (# x, y #)
            | W# x == expX && W# y == expY -> Nothing
            | otherwise ->
                Just $
                    "Expected " ++ show expX ++ " and " ++ show expY
                        ++ " but got " ++ show (W# x) ++ " and " ++ show (W# y)

54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
check :: String -> Maybe String -> IO ()
check s (Just err) = error $ "Error for " ++ s ++ ": " ++ err
check _ Nothing    = return ()

main :: IO ()
main = do
    -- First something trivial
    check "addIntC# maxBound 0" $ checkI (maxBound, 0) addIntC# maxBound 0
    check "addIntC# 0 maxBound" $ checkI (maxBound, 0) addIntC# 0 maxBound
    -- Overflows
    check "addIntC# maxBound 1" $ checkI (minBound, 1) addIntC# maxBound 1
    check "addIntC# 1 maxBound" $ checkI (minBound, 1) addIntC# 1 maxBound
    check "addIntC# maxBound 2" $ checkI (minBound + 1, 1) addIntC# maxBound 2
    check "addIntC# 2 maxBound" $ checkI (minBound + 1, 1) addIntC# 2 maxBound
    check "addIntC# minBound minBound" $
      checkI (0, 1) addIntC# minBound minBound

    -- First something trivial
    check "subIntC# minBound 0" $ checkI (minBound, 0) subIntC# minBound 0
    -- Overflows
    check "subIntC# minBound 1" $ checkI (maxBound, 1) subIntC# minBound 1
    check "subIntC# minBound 1" $ checkI (maxBound - 1, 1) subIntC# minBound 2
    check "subIntC# 0 minBound" $ checkI (minBound, 1) subIntC# 0 minBound
    check "subIntC# -1 minBound" $ checkI (maxBound, 0) subIntC# (-1) minBound
    check "subIntC# minBound -1" $
      checkI (minBound + 1, 0) subIntC# minBound (-1)

    -- First something trivial (note that the order of results is different!)
    check "plusWord2# maxBound 0" $ checkW (0, maxBound) plusWord2# maxBound 0
    check "plusWord2# 0 maxBound" $ checkW (0, maxBound) plusWord2# 0 maxBound
    -- Overflows
    check "plusWord2# maxBound 1" $
      checkW (1, minBound) plusWord2# maxBound 1
    check "plusWord2# 1 maxBound" $
      checkW (1, minBound) plusWord2# 1 maxBound
    check "plusWord2# maxBound 2" $
      checkW (1, minBound + 1) plusWord2# maxBound 2
    check "plusWord2# 2 maxBound" $
      checkW (1, minBound + 1) plusWord2# 2 maxBound
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110

    check "timesWord2# maxBound 0" $ checkW (0, 0) timesWord2# maxBound 0
    check "timesWord2# 0 maxBound" $ checkW (0, 0) timesWord2# 0 maxBound
    check "timesWord2# maxBound 1" $ checkW (0, maxBound) timesWord2# maxBound 1
    check "timesWord2# 1 maxBound" $ checkW (0, maxBound) timesWord2# 1 maxBound
    -- Overflows
    check "timesWord2# " $ checkW (1, 0) timesWord2# (2 ^ 63) 2
    check "timesWord2# " $ checkW (2, 0) timesWord2# (2 ^ 63) (2 ^ 2)
    check "timesWord2# " $ checkW (4, 0) timesWord2# (2 ^ 63) (2 ^ 3)
    check "timesWord2# " $ checkW (8, 0) timesWord2# (2 ^ 63) (2 ^ 4)
    check "timesWord2# maxBound 2" $
      checkW (1, maxBound - 1) timesWord2# maxBound 2
    check "timesWord2# 2 maxBound" $
      checkW (1, maxBound - 1) timesWord2# 2 maxBound
    check "timesWord2# maxBound 3" $
      checkW (2, maxBound - 2) timesWord2# maxBound 3
    check "timesWord2# 3 maxBound" $
      checkW (2, maxBound - 2) timesWord2# 3 maxBound
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128

    check "quotRemWord2# 0 0 1" $ checkW2 (0, 0) quotRemWord2# 0 0 1
    check "quotRemWord2# 0 4 2" $ checkW2 (2, 0) quotRemWord2# 0 4 2
    check "quotRemWord2# 0 7 3" $ checkW2 (2, 1) quotRemWord2# 0 7 3
    check "quotRemWord2# 1 0 (2 ^ 63)" $
      checkW2 (2, 0) quotRemWord2# 1 0 (2 ^ 63)
    check "quotRemWord2# 1 1 (2 ^ 63)" $
      checkW2 (2, 1) quotRemWord2# 1 1 (2 ^ 63)
    check "quotRemWord2# 1 0 maxBound" $
      checkW2 (1, 1) quotRemWord2# 1 0 maxBound
    check "quotRemWord2# 2 0 maxBound" $
      checkW2 (2, 2) quotRemWord2# 2 0 maxBound
    check "quotRemWord2# 1 maxBound maxBound" $
      checkW2 (2, 1) quotRemWord2# 1 maxBound maxBound
    check "quotRemWord2# (2 ^ 63) 0 maxBound" $
      checkW2 (2 ^ 63, 2 ^ 63) quotRemWord2# (2 ^ 63) 0 maxBound
    check "quotRemWord2# (2 ^ 63) maxBound maxBound" $
      checkW2 (2 ^ 63 + 1, 2 ^ 63) quotRemWord2# (2 ^ 63) maxBound maxBound