7c28ce2c2bde4908222bb2259f6b8a90c548619e
[packages/integer-gmp.git] / GHC / Integer / GMP / Prim.hs
1 {-# LANGUAGE ForeignFunctionInterface, GHCForeignImportPrim, CPP,
2 MagicHash, UnboxedTuples, UnliftedFFITypes, BangPatterns #-}
3 {-# OPTIONS_GHC -XNoImplicitPrelude #-}
4 {-# OPTIONS_HADDOCK hide #-}
5
6 #include "MachDeps.h"
7 module GHC.Integer.GMP.Prim (
8 cmpInteger#,
9 cmpIntegerInt#,
10
11 plusInteger#,
12 minusInteger#,
13 timesInteger#,
14
15 quotRemInteger#,
16 quotInteger#,
17 remInteger#,
18 divModInteger#,
19 divInteger#,
20 modInteger#,
21 divExactInteger#,
22
23 gcdInteger#,
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 #if WORD_SIZE_IN_BITS < 64
45 int64ToInteger#, integerToInt64#,
46 word64ToInteger#, integerToWord64#,
47 #endif
48
49 #ifndef WORD_SIZE_IN_BITS
50 #error WORD_SIZE_IN_BITS not defined!!!
51 #endif
52
53 ) where
54
55 import GHC.Prim
56 import GHC.Types
57
58 -- Double isn't available yet, and we shouldn't be using defaults anyway:
59 default ()
60
61 -- | Returns -1,0,1 according as first argument is less than, equal to, or greater than second argument.
62 --
63 foreign import prim "integer_cmm_cmpIntegerzh" cmpInteger#
64 :: Int# -> ByteArray# -> Int# -> ByteArray# -> Int#
65
66 -- | Returns -1,0,1 according as first argument is less than, equal to, or greater than second argument, which
67 -- is an ordinary Int\#.
68 foreign import prim "integer_cmm_cmpIntegerIntzh" cmpIntegerInt#
69 :: Int# -> ByteArray# -> Int# -> Int#
70
71 -- |
72 --
73 foreign import prim "integer_cmm_plusIntegerzh" plusInteger#
74 :: Int# -> ByteArray# -> Int# -> ByteArray# -> (# Int#, ByteArray# #)
75
76 -- |
77 --
78 foreign import prim "integer_cmm_minusIntegerzh" minusInteger#
79 :: Int# -> ByteArray# -> Int# -> ByteArray# -> (# Int#, ByteArray# #)
80
81 -- |
82 --
83 foreign import prim "integer_cmm_timesIntegerzh" timesInteger#
84 :: Int# -> ByteArray# -> Int# -> ByteArray# -> (# Int#, ByteArray# #)
85
86 -- | Compute div and mod simultaneously, where div rounds towards negative
87 -- infinity and\ @(q,r) = divModInteger#(x,y)@ implies
88 -- @plusInteger# (timesInteger# q y) r = x@.
89 --
90 foreign import prim "integer_cmm_quotRemIntegerzh" quotRemInteger#
91 :: Int# -> ByteArray# -> Int# -> ByteArray# -> (# Int#, ByteArray#, Int#, ByteArray# #)
92
93 -- | Rounds towards zero.
94 --
95 foreign import prim "integer_cmm_quotIntegerzh" quotInteger#
96 :: Int# -> ByteArray# -> Int# -> ByteArray# -> (# Int#, ByteArray# #)
97
98 -- | Satisfies \texttt{plusInteger\# (timesInteger\# (quotInteger\# x y) y) (remInteger\# x y) == x}.
99 --
100 foreign import prim "integer_cmm_remIntegerzh" remInteger#
101 :: Int# -> ByteArray# -> Int# -> ByteArray# -> (# Int#, ByteArray# #)
102
103 -- | Compute div and mod simultaneously, where div rounds towards negative infinity
104 -- and\texttt{(q,r) = divModInteger\#(x,y)} implies \texttt{plusInteger\# (timesInteger\# q y) r = x}.
105 --
106 foreign import prim "integer_cmm_divModIntegerzh" divModInteger#
107 :: Int# -> ByteArray# -> Int# -> ByteArray# -> (# Int#, ByteArray#, Int#, ByteArray# #)
108 foreign import prim "integer_cmm_divIntegerzh" divInteger#
109 :: Int# -> ByteArray# -> Int# -> ByteArray# -> (# Int#, ByteArray# #)
110 foreign import prim "integer_cmm_modIntegerzh" modInteger#
111 :: Int# -> ByteArray# -> Int# -> ByteArray# -> (# Int#, ByteArray# #)
112
113 -- | Divisor is guaranteed to be a factor of dividend.
114 --
115 foreign import prim "integer_cmm_divExactIntegerzh" divExactInteger#
116 :: Int# -> ByteArray# -> Int# -> ByteArray# -> (# Int#, ByteArray# #)
117
118 -- | Greatest common divisor.
119 --
120 foreign import prim "integer_cmm_gcdIntegerzh" gcdInteger#
121 :: Int# -> ByteArray# -> Int# -> ByteArray# -> (# Int#, ByteArray# #)
122
123 -- | Greatest common divisor, where second argument is an ordinary {\tt Int\#}.
124 --
125 foreign import prim "integer_cmm_gcdIntegerIntzh" gcdIntegerInt#
126 :: Int# -> ByteArray# -> Int# -> Int#
127
128 -- |
129 --
130 foreign import prim "integer_cmm_gcdIntzh" gcdInt#
131 :: Int# -> Int# -> Int#
132
133 -- | Convert to arbitrary-precision integer.
134 -- First {\tt Int\#} in result is the exponent; second {\tt Int\#} and {\tt ByteArray\#}
135 -- represent an {\tt Integer\#} holding the mantissa.
136 --
137 foreign import prim "integer_cmm_decodeDoublezh" decodeDouble#
138 :: Double# -> (# Int#, Int#, ByteArray# #)
139
140 -- |
141 --
142 foreign import prim "integer_cmm_int2Integerzh" int2Integer#
143 :: Int# -> (# Int#, ByteArray# #)
144
145 -- |
146 --
147 foreign import prim "integer_cmm_word2Integerzh" word2Integer#
148 :: Word# -> (# Int#, ByteArray# #)
149
150 -- |
151 --
152 foreign import prim "integer_cmm_andIntegerzh" andInteger#
153 :: Int# -> ByteArray# -> Int# -> ByteArray# -> (# Int#, ByteArray# #)
154
155 -- |
156 --
157 foreign import prim "integer_cmm_orIntegerzh" orInteger#
158 :: Int# -> ByteArray# -> Int# -> ByteArray# -> (# Int#, ByteArray# #)
159
160 -- |
161 --
162 foreign import prim "integer_cmm_xorIntegerzh" xorInteger#
163 :: Int# -> ByteArray# -> Int# -> ByteArray# -> (# Int#, ByteArray# #)
164
165 -- |
166 --
167 foreign import prim "integer_cmm_testBitIntegerzh" testBitInteger#
168 :: Int# -> ByteArray# -> Int# -> Int#
169
170 -- |
171 --
172 foreign import prim "integer_cmm_mul2ExpIntegerzh" mul2ExpInteger#
173 :: Int# -> ByteArray# -> Int# -> (# Int#, ByteArray# #)
174
175 -- |
176 --
177 foreign import prim "integer_cmm_fdivQ2ExpIntegerzh" fdivQ2ExpInteger#
178 :: Int# -> ByteArray# -> Int# -> (# Int#, ByteArray# #)
179
180 -- |
181 --
182 foreign import prim "integer_cmm_complementIntegerzh" complementInteger#
183 :: Int# -> ByteArray# -> (# Int#, ByteArray# #)
184
185 #if WORD_SIZE_IN_BITS < 64
186 foreign import prim "integer_cmm_int64ToIntegerzh" int64ToInteger#
187 :: Int64# -> (# Int#, ByteArray# #)
188
189 foreign import prim "integer_cmm_word64ToIntegerzh" word64ToInteger#
190 :: Word64# -> (# Int#, ByteArray# #)
191
192 foreign import ccall unsafe "hs_integerToInt64"
193 integerToInt64# :: Int# -> ByteArray# -> Int64#
194
195 foreign import ccall unsafe "hs_integerToWord64"
196 integerToWord64# :: Int# -> ByteArray# -> Word64#
197 #endif
198
199 -- used to be primops:
200 integer2Int# :: Int# -> ByteArray# -> Int#
201 integer2Int# s d = if isTrue# (s ==# 0#)
202 then 0#
203 else let !v = indexIntArray# d 0# in
204 if isTrue# (s <# 0#)
205 then negateInt# v
206 else v
207
208 integer2Word# :: Int# -> ByteArray# -> Word#
209 integer2Word# s d = int2Word# (integer2Int# s d)