Make integer-gmp suitable to be used directly, rather than via integer
[packages/integer-gmp.git] / GHC / Integer / GMP / 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.GMP.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 import GHC.Integer.Type
53
54 #if WORD_SIZE_IN_BITS < 64
55 import GHC.Prim (Int64#, Word64#)
56 #endif
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
109 -- | Divisor is guaranteed to be a factor of dividend.
110 --
111 foreign import prim "integer_cmm_divExactIntegerzh" divExactInteger#
112 :: Int# -> ByteArray# -> Int# -> ByteArray# -> (# Int#, ByteArray# #)
113
114 -- | Greatest common divisor.
115 --
116 foreign import prim "integer_cmm_gcdIntegerzh" gcdInteger#
117 :: Int# -> ByteArray# -> Int# -> ByteArray# -> (# Int#, ByteArray# #)
118
119 -- | Greatest common divisor, where second argument is an ordinary {\tt Int\#}.
120 --
121 foreign import prim "integer_cmm_gcdIntegerIntzh" gcdIntegerInt#
122 :: Int# -> ByteArray# -> Int# -> Int#
123
124 -- |
125 --
126 foreign import prim "integer_cmm_gcdIntzh" gcdInt#
127 :: Int# -> Int# -> Int#
128
129 -- | Convert to arbitrary-precision integer.
130 -- First {\tt Int\#} in result is the exponent; second {\tt Int\#} and {\tt ByteArray\#}
131 -- represent an {\tt Integer\#} holding the mantissa.
132 --
133 foreign import prim "integer_cmm_decodeDoublezh" decodeDouble#
134 :: Double# -> (# Int#, Int#, ByteArray# #)
135
136 -- |
137 --
138 foreign import prim "integer_cmm_int2Integerzh" int2Integer#
139 :: Int# -> (# Int#, ByteArray# #)
140
141 -- |
142 --
143 foreign import prim "integer_cmm_integer2Intzh" integer2Int#
144 :: Int# -> ByteArray# -> Int#
145
146 -- |
147 --
148 foreign import prim "integer_cmm_word2Integerzh" word2Integer#
149 :: Word# -> (# Int#, ByteArray# #)
150
151 -- |
152 --
153 foreign import prim "integer_cmm_integer2Wordzh" integer2Word#
154 :: Int# -> ByteArray# -> Word#
155
156 -- |
157 --
158 foreign import prim "integer_cmm_andIntegerzh" andInteger#
159 :: Int# -> ByteArray# -> Int# -> ByteArray# -> (# Int#, ByteArray# #)
160
161 -- |
162 --
163 foreign import prim "integer_cmm_orIntegerzh" orInteger#
164 :: Int# -> ByteArray# -> Int# -> ByteArray# -> (# Int#, ByteArray# #)
165
166 -- |
167 --
168 foreign import prim "integer_cmm_xorIntegerzh" xorInteger#
169 :: Int# -> ByteArray# -> Int# -> ByteArray# -> (# Int#, ByteArray# #)
170
171 -- |
172 --
173 foreign import prim "integer_cmm_complementIntegerzh" complementInteger#
174 :: Int# -> ByteArray# -> (# Int#, ByteArray# #)
175
176 #if WORD_SIZE_IN_BITS < 64
177 foreign import prim "integer_cmm_int64ToIntegerzh" int64ToInteger#
178 :: Int64# -> (# Int#, ByteArray# #)
179
180 foreign import prim "integer_cmm_word64ToIntegerzh" word64ToInteger#
181 :: Word64# -> (# Int#, ByteArray# #)
182
183 foreign import ccall unsafe "hs_integerToInt64"
184 integerToInt64# :: Int# -> ByteArray# -> Int64#
185
186 foreign import ccall unsafe "hs_integerToWord64"
187 integerToWord64# :: Int# -> ByteArray# -> Word64#
188 #endif