0fd1b379d8398255de65772bfcb31ba777f3cc24
[ghc.git] / libraries / integer-gmp / GHC / Integer / GMP / Prim.hs
1 {-# LANGUAGE BangPatterns, CPP, MagicHash, NoImplicitPrelude, UnboxedTuples
2 , UnliftedFFITypes, GHCForeignImportPrim #-}
3 {-# OPTIONS_HADDOCK hide #-}
4
5 #include "MachDeps.h"
6 module GHC.Integer.GMP.Prim (
7 cmpInteger#,
8 cmpIntegerInt#,
9
10 plusInteger#,
11 minusInteger#,
12 timesInteger#,
13
14 quotRemInteger#,
15 quotInteger#,
16 remInteger#,
17 divModInteger#,
18 divInteger#,
19 modInteger#,
20 divExactInteger#,
21
22 gcdInteger#,
23 gcdExtInteger#,
24 gcdIntegerInt#,
25 gcdInt#,
26
27 decodeDouble#,
28
29 int2Integer#,
30 integer2Int#,
31
32 word2Integer#,
33 integer2Word#,
34
35 andInteger#,
36 orInteger#,
37 xorInteger#,
38 complementInteger#,
39
40 testBitInteger#,
41 mul2ExpInteger#,
42 fdivQ2ExpInteger#,
43
44 powInteger#,
45 powModInteger#,
46 powModSecInteger#,
47 recipModInteger#,
48
49 nextPrimeInteger#,
50 testPrimeInteger#,
51
52 sizeInBaseInteger#,
53 importIntegerFromByteArray#,
54 importIntegerFromAddr#,
55 exportIntegerToMutableByteArray#,
56 exportIntegerToAddr#,
57
58 #if WORD_SIZE_IN_BITS < 64
59 int64ToInteger#, integerToInt64#,
60 word64ToInteger#, integerToWord64#,
61 #endif
62
63 #ifndef WORD_SIZE_IN_BITS
64 #error WORD_SIZE_IN_BITS not defined!!!
65 #endif
66
67 ) where
68
69 import GHC.Prim
70 import GHC.Types
71
72 -- Double isn't available yet, and we shouldn't be using defaults anyway:
73 default ()
74
75 -- | Returns -1,0,1 according as first argument is less than, equal to, or greater than second argument.
76 --
77 foreign import prim "integer_cmm_cmpIntegerzh" cmpInteger#
78 :: Int# -> ByteArray# -> Int# -> ByteArray# -> Int#
79
80 -- | Returns -1,0,1 according as first argument is less than, equal to, or greater than second argument, which
81 -- is an ordinary Int\#.
82 foreign import prim "integer_cmm_cmpIntegerIntzh" cmpIntegerInt#
83 :: Int# -> ByteArray# -> Int# -> Int#
84
85 -- |
86 --
87 foreign import prim "integer_cmm_plusIntegerzh" plusInteger#
88 :: Int# -> ByteArray# -> Int# -> ByteArray# -> (# Int#, ByteArray# #)
89
90 -- |
91 --
92 foreign import prim "integer_cmm_minusIntegerzh" minusInteger#
93 :: Int# -> ByteArray# -> Int# -> ByteArray# -> (# Int#, ByteArray# #)
94
95 -- |
96 --
97 foreign import prim "integer_cmm_timesIntegerzh" timesInteger#
98 :: Int# -> ByteArray# -> Int# -> ByteArray# -> (# Int#, ByteArray# #)
99
100 -- | Compute div and mod simultaneously, where div rounds towards negative
101 -- infinity and\ @(q,r) = divModInteger#(x,y)@ implies
102 -- @plusInteger# (timesInteger# q y) r = x@.
103 --
104 foreign import prim "integer_cmm_quotRemIntegerzh" quotRemInteger#
105 :: Int# -> ByteArray# -> Int# -> ByteArray# -> (# Int#, ByteArray#, Int#, ByteArray# #)
106
107 -- | Rounds towards zero.
108 --
109 foreign import prim "integer_cmm_quotIntegerzh" quotInteger#
110 :: Int# -> ByteArray# -> Int# -> ByteArray# -> (# Int#, ByteArray# #)
111
112 -- | Satisfies \texttt{plusInteger\# (timesInteger\# (quotInteger\# x y) y) (remInteger\# x y) == x}.
113 --
114 foreign import prim "integer_cmm_remIntegerzh" remInteger#
115 :: Int# -> ByteArray# -> Int# -> ByteArray# -> (# Int#, ByteArray# #)
116
117 -- | Compute div and mod simultaneously, where div rounds towards negative infinity
118 -- and\texttt{(q,r) = divModInteger\#(x,y)} implies \texttt{plusInteger\# (timesInteger\# q y) r = x}.
119 --
120 foreign import prim "integer_cmm_divModIntegerzh" divModInteger#
121 :: Int# -> ByteArray# -> Int# -> ByteArray# -> (# Int#, ByteArray#, Int#, ByteArray# #)
122 foreign import prim "integer_cmm_divIntegerzh" divInteger#
123 :: Int# -> ByteArray# -> Int# -> ByteArray# -> (# Int#, ByteArray# #)
124 foreign import prim "integer_cmm_modIntegerzh" modInteger#
125 :: Int# -> ByteArray# -> Int# -> ByteArray# -> (# Int#, ByteArray# #)
126
127 -- | Divisor is guaranteed to be a factor of dividend.
128 --
129 foreign import prim "integer_cmm_divExactIntegerzh" divExactInteger#
130 :: Int# -> ByteArray# -> Int# -> ByteArray# -> (# Int#, ByteArray# #)
131
132 -- | Greatest common divisor.
133 --
134 foreign import prim "integer_cmm_gcdIntegerzh" gcdInteger#
135 :: Int# -> ByteArray# -> Int# -> ByteArray# -> (# Int#, ByteArray# #)
136
137 -- | Extended greatest common divisor.
138 --
139 foreign import prim "integer_cmm_gcdExtIntegerzh" gcdExtInteger#
140 :: Int# -> ByteArray# -> Int# -> ByteArray# -> (# Int#, ByteArray#, Int#, ByteArray# #)
141
142 -- | Greatest common divisor, where second argument is an ordinary {\tt Int\#}.
143 --
144 foreign import prim "integer_cmm_gcdIntegerIntzh" gcdIntegerInt#
145 :: Int# -> ByteArray# -> Int# -> Int#
146
147 -- |
148 --
149 foreign import prim "integer_cmm_gcdIntzh" gcdInt#
150 :: Int# -> Int# -> Int#
151
152 -- | Convert to arbitrary-precision integer.
153 -- First {\tt Int\#} in result is the exponent; second {\tt Int\#} and {\tt ByteArray\#}
154 -- represent an {\tt Integer\#} holding the mantissa.
155 --
156 foreign import prim "integer_cmm_decodeDoublezh" decodeDouble#
157 :: Double# -> (# Int#, Int#, ByteArray# #)
158
159 -- |
160 --
161 foreign import prim "integer_cmm_int2Integerzh" int2Integer#
162 :: Int# -> (# Int#, ByteArray# #)
163
164 -- |
165 --
166 foreign import prim "integer_cmm_word2Integerzh" word2Integer#
167 :: Word# -> (# Int#, ByteArray# #)
168
169 -- |
170 --
171 foreign import prim "integer_cmm_andIntegerzh" andInteger#
172 :: Int# -> ByteArray# -> Int# -> ByteArray# -> (# Int#, ByteArray# #)
173
174 -- |
175 --
176 foreign import prim "integer_cmm_orIntegerzh" orInteger#
177 :: Int# -> ByteArray# -> Int# -> ByteArray# -> (# Int#, ByteArray# #)
178
179 -- |
180 --
181 foreign import prim "integer_cmm_xorIntegerzh" xorInteger#
182 :: Int# -> ByteArray# -> Int# -> ByteArray# -> (# Int#, ByteArray# #)
183
184 -- |
185 --
186 foreign import prim "integer_cmm_testBitIntegerzh" testBitInteger#
187 :: Int# -> ByteArray# -> Int# -> Int#
188
189 -- |
190 --
191 foreign import prim "integer_cmm_mul2ExpIntegerzh" mul2ExpInteger#
192 :: Int# -> ByteArray# -> Int# -> (# Int#, ByteArray# #)
193
194 -- |
195 --
196 foreign import prim "integer_cmm_fdivQ2ExpIntegerzh" fdivQ2ExpInteger#
197 :: Int# -> ByteArray# -> Int# -> (# Int#, ByteArray# #)
198
199 -- |
200 --
201 foreign import prim "integer_cmm_powIntegerzh" powInteger#
202 :: Int# -> ByteArray# -> Word# -> (# Int#, ByteArray# #)
203
204 -- |
205 --
206 foreign import prim "integer_cmm_powModIntegerzh" powModInteger#
207 :: Int# -> ByteArray# -> Int# -> ByteArray# -> Int# -> ByteArray# -> (# Int#, ByteArray# #)
208
209 -- |
210 --
211 foreign import prim "integer_cmm_powModSecIntegerzh" powModSecInteger#
212 :: Int# -> ByteArray# -> Int# -> ByteArray# -> Int# -> ByteArray# -> (# Int#, ByteArray# #)
213
214 -- |
215 --
216 foreign import prim "integer_cmm_recipModIntegerzh" recipModInteger#
217 :: Int# -> ByteArray# -> Int# -> ByteArray# -> (# Int#, ByteArray# #)
218
219 -- |
220 --
221 foreign import prim "integer_cmm_nextPrimeIntegerzh" nextPrimeInteger#
222 :: Int# -> ByteArray# -> (# Int#, ByteArray# #)
223
224 -- |
225 --
226 foreign import prim "integer_cmm_testPrimeIntegerzh" testPrimeInteger#
227 :: Int# -> ByteArray# -> Int# -> Int#
228
229 -- |
230 --
231 foreign import prim "integer_cmm_sizeInBasezh" sizeInBaseInteger#
232 :: Int# -> ByteArray# -> Int# -> Word#
233
234 -- |
235 --
236 foreign import prim "integer_cmm_importIntegerFromByteArrayzh" importIntegerFromByteArray#
237 :: ByteArray# -> Word# -> Word# -> Int# -> (# Int#, ByteArray# #)
238
239 -- |
240 --
241 foreign import prim "integer_cmm_importIntegerFromAddrzh" importIntegerFromAddr#
242 :: Addr# -> Word# -> Int# -> State# s -> (# State# s, Int#, ByteArray# #)
243
244 -- |
245 --
246 foreign import prim "integer_cmm_exportIntegerToMutableByteArrayzh" exportIntegerToMutableByteArray#
247 :: Int# -> ByteArray# -> MutableByteArray# s -> Word# -> Int# -> State# s -> (# State# s, Word# #)
248
249 -- |
250 --
251 foreign import prim "integer_cmm_exportIntegerToAddrzh" exportIntegerToAddr#
252 :: Int# -> ByteArray# -> Addr# -> Int# -> State# s -> (# State# s, Word# #)
253
254 -- |
255 --
256 foreign import prim "integer_cmm_complementIntegerzh" complementInteger#
257 :: Int# -> ByteArray# -> (# Int#, ByteArray# #)
258
259 #if WORD_SIZE_IN_BITS < 64
260 foreign import prim "integer_cmm_int64ToIntegerzh" int64ToInteger#
261 :: Int64# -> (# Int#, ByteArray# #)
262
263 foreign import prim "integer_cmm_word64ToIntegerzh" word64ToInteger#
264 :: Word64# -> (# Int#, ByteArray# #)
265
266 foreign import ccall unsafe "hs_integerToInt64"
267 integerToInt64# :: Int# -> ByteArray# -> Int64#
268
269 foreign import ccall unsafe "hs_integerToWord64"
270 integerToWord64# :: Int# -> ByteArray# -> Word64#
271 #endif
272
273 -- used to be primops:
274 integer2Int# :: Int# -> ByteArray# -> Int#
275 integer2Int# s d = if isTrue# (s ==# 0#)
276 then 0#
277 else let !v = indexIntArray# d 0# in
278 if isTrue# (s <# 0#)
279 then negateInt# v
280 else v
281
282 integer2Word# :: Int# -> ByteArray# -> Word#
283 integer2Word# s d = int2Word# (integer2Int# s d)