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