| ... |
... |
@@ -3,6 +3,7 @@ |
|
3
|
3
|
{-# LANGUAGE MagicHash #-}
|
|
4
|
4
|
{-# LANGUAGE UnboxedTuples #-}
|
|
5
|
5
|
{-# LANGUAGE UnliftedFFITypes #-}
|
|
|
6
|
+{-# LANGUAGE ExtendedLiterals #-}
|
|
6
|
7
|
|
|
7
|
8
|
-- | This test ensures that sub-word signed and unsigned parameters are correctly
|
|
8
|
9
|
-- handed over to C functions. I.e. it asserts the calling-convention.
|
| ... |
... |
@@ -16,6 +17,7 @@ import Data.Word |
|
16
|
17
|
import GHC.Exts
|
|
17
|
18
|
import GHC.Int
|
|
18
|
19
|
import System.IO
|
|
|
20
|
+import GHC.Stack
|
|
19
|
21
|
|
|
20
|
22
|
foreign import ccall "fun8"
|
|
21
|
23
|
fun8 ::
|
| ... |
... |
@@ -59,6 +61,31 @@ foreign import ccall "fun32" |
|
59
|
61
|
Int32# -> -- s1
|
|
60
|
62
|
Int64# -- result
|
|
61
|
63
|
|
|
|
64
|
+foreign import ccall "shrink32"
|
|
|
65
|
+ shrink32 ::
|
|
|
66
|
+ Int64# -> -- a0
|
|
|
67
|
+ Int32# -- result
|
|
|
68
|
+
|
|
|
69
|
+foreign import ccall "shrink16"
|
|
|
70
|
+ shrink16 ::
|
|
|
71
|
+ Int64# -> -- a0
|
|
|
72
|
+ Int16# -- result
|
|
|
73
|
+
|
|
|
74
|
+foreign import ccall "shrink8"
|
|
|
75
|
+ shrink8 ::
|
|
|
76
|
+ Int64# -> -- a0
|
|
|
77
|
+ Int8# -- result
|
|
|
78
|
+
|
|
|
79
|
+foreign import ccall "shrink32_16"
|
|
|
80
|
+ shrink32_16 ::
|
|
|
81
|
+ Int32# -> -- a0
|
|
|
82
|
+ Int16# -- result
|
|
|
83
|
+
|
|
|
84
|
+foreign import ccall "shrink32_8"
|
|
|
85
|
+ shrink32_8 ::
|
|
|
86
|
+ Int32# -> -- a0
|
|
|
87
|
+ Int8# -- result
|
|
|
88
|
+
|
|
62
|
89
|
foreign import ccall "funFloat"
|
|
63
|
90
|
funFloat ::
|
|
64
|
91
|
Float# -> -- a0
|
| ... |
... |
@@ -115,6 +142,16 @@ main = do |
|
115
|
142
|
hFlush stdout
|
|
116
|
143
|
assertEqual expected_res32 (I64# res32)
|
|
117
|
144
|
|
|
|
145
|
+ -- Shrinking/zeroing of subword sizes
|
|
|
146
|
+ do
|
|
|
147
|
+ assertTrue# (shrink32 -1#Int64 `eq32` -1#Int32)
|
|
|
148
|
+ assertTrue# (shrink16 -1#Int64 `eq16` -1#Int16)
|
|
|
149
|
+ assertTrue# (shrink8 -1#Int64 `eq8` -1#Int8)
|
|
|
150
|
+
|
|
|
151
|
+ assertTrue# (shrink32_16 -1#Int32 `eq16` -1#Int16)
|
|
|
152
|
+ assertTrue# (shrink32_8 -1#Int32 `eq8` -1#Int8)
|
|
|
153
|
+
|
|
|
154
|
+
|
|
118
|
155
|
let resFloat :: Float = F# (funFloat 1.0# 1.1# 1.2# 1.3# 1.4# 1.5# 1.6# 1.7# 1.8# 1.9#)
|
|
119
|
156
|
print $ "funFloat result:" ++ show resFloat
|
|
120
|
157
|
hFlush stdout
|
| ... |
... |
@@ -125,8 +162,26 @@ main = do |
|
125
|
162
|
hFlush stdout
|
|
126
|
163
|
assertEqual (14.5 :: Double) resDouble
|
|
127
|
164
|
|
|
|
165
|
+-- We want to avoid constant folding, hence we hide the eqInt# primops
|
|
|
166
|
+{-# NOINLINE eq8 #-}
|
|
|
167
|
+{-# NOINLINE eq16 #-}
|
|
|
168
|
+{-# NOINLINE eq32 #-}
|
|
|
169
|
+eq8 :: Int8# -> Int8# -> Int#
|
|
|
170
|
+eq16 :: Int16# -> Int16# -> Int#
|
|
|
171
|
+eq32 :: Int32# -> Int32# -> Int#
|
|
|
172
|
+eq8 = eqInt8#
|
|
|
173
|
+eq16 = eqInt16#
|
|
|
174
|
+eq32 = eqInt32#
|
|
|
175
|
+
|
|
128
|
176
|
assertEqual :: (Eq a, Show a) => a -> a -> IO ()
|
|
129
|
177
|
assertEqual a b =
|
|
130
|
178
|
if a == b
|
|
131
|
179
|
then pure ()
|
|
132
|
180
|
else error $ show a ++ " =/= " ++ show b
|
|
|
181
|
+
|
|
|
182
|
+assertTrue# :: HasCallStack => Int# -> IO ()
|
|
|
183
|
+assertTrue# x =
|
|
|
184
|
+ case (I# x) of
|
|
|
185
|
+ 1 -> pure ()
|
|
|
186
|
+ 0 -> error $ "assertTrue# failed"
|
|
|
187
|
+ |