1 (* Copyright (C
) 2013-2014,2016-2017 Matthew Fluet
.
2 * Copyright (C
) 1999-2008 Henry Cejtin
, Matthew Fluet
, Suresh
3 * Jagannathan
, and Stephen Weeks
.
4 * Copyright (C
) 1997-2000 NEC Research Institute
.
6 * MLton is released under a BSD
-style license
.
7 * See the file MLton
-LICENSE for details
.
10 signature PRIM_INT_INF
=
15 val precision
: Primitive
.Int32
.int option
17 val maxInt
: int option
18 val minInt
: int option
25 Big
of C_MPLimb
.word vector
26 | Small
of ObjptrInt
.int
28 val fromRep
: rep
-> int option
30 val isSmall
: int -> bool
31 val areSmall
: int * int -> bool
34 val +! : int * int -> int
35 val +?
: int * int -> int
36 val + : int * int -> int
37 val divMod
: int * int -> int * int
38 val div: int * int -> int
39 val gcd
: int * int -> int
40 val mod: int * int -> int
41 val *! : int * int -> int
42 val *?
: int * int -> int
43 val * : int * int -> int
47 val quotRem
: int * int -> int * int
48 val quot
: int * int -> int
49 val rem
: int * int -> int
50 val -! : int * int -> int
51 val -?
: int * int -> int
52 val - : int * int -> int
54 val < : int * int -> bool
55 val <= : int * int -> bool
56 val > : int * int -> bool
57 val >= : int * int -> bool
58 val compare
: int * int -> Primitive
.Order
.order
59 val min
: int * int -> int
60 val max
: int * int -> int
61 val ltu
: int * int -> bool
62 val leu
: int * int -> bool
63 val gtu
: int * int -> bool
64 val geu
: int * int -> bool
66 val andb
: int * int -> int
67 val <<?
: int * Primitive
.Word32
.word -> int
68 val << : int * Primitive
.Word32
.word -> int
70 val orb
: int * int -> int
71 val ~
>>?
: int * Primitive
.Word32
.word -> int
72 val ~
>> : int * Primitive
.Word32
.word -> int
73 val xorb
: int * int -> int
75 val mkCvt
: ({base
: Primitive
.Int32
.int,
76 smallCvt
: ObjptrInt
.int -> Primitive
.String8
.string}
77 -> int -> Primitive
.String8
.string)
78 val mkLog2
: ({fromSmall
: {smallLog2
: Primitive
.Int32
.int} -> 'a
,
79 fromLarge
: {mostSigLimbLog2
: Primitive
.Int32
.int,
80 numLimbsMinusOne
: SeqIndex
.int} -> 'a
}
83 val zextdFromInt8
: Primitive
.Int8
.int -> int
84 val zextdFromInt16
: Primitive
.Int16
.int -> int
85 val zextdFromInt32
: Primitive
.Int32
.int -> int
86 val zextdFromInt64
: Primitive
.Int64
.int -> int
87 val zextdFromIntInf
: Primitive
.IntInf
.int -> int
88 val zextdFromWord8
: Primitive
.Word8.word -> int
89 val zextdFromWord16
: Primitive
.Word16
.word -> int
90 val zextdFromWord32
: Primitive
.Word32
.word -> int
91 val zextdFromWord64
: Primitive
.Word64
.word -> int
92 val zextdToInt8
: int -> Primitive
.Int8
.int
93 val zextdToInt16
: int -> Primitive
.Int16
.int
94 val zextdToInt32
: int -> Primitive
.Int32
.int
95 val zextdToInt64
: int -> Primitive
.Int64
.int
96 val zextdToIntInf
: int -> Primitive
.IntInf
.int
97 val zextdToWord8
: int -> Primitive
.Word8.word
98 val zextdToWord16
: int -> Primitive
.Word16
.word
99 val zextdToWord32
: int -> Primitive
.Word32
.word
100 val zextdToWord64
: int -> Primitive
.Word64
.word
102 val sextdFromInt8
: Primitive
.Int8
.int -> int
103 val sextdFromInt16
: Primitive
.Int16
.int -> int
104 val sextdFromInt32
: Primitive
.Int32
.int -> int
105 val sextdFromInt64
: Primitive
.Int64
.int -> int
106 val sextdFromIntInf
: Primitive
.IntInf
.int -> int
107 val sextdFromWord8
: Primitive
.Word8.word -> int
108 val sextdFromWord16
: Primitive
.Word16
.word -> int
109 val sextdFromWord32
: Primitive
.Word32
.word -> int
110 val sextdFromWord64
: Primitive
.Word64
.word -> int
111 val sextdToInt8
: int -> Primitive
.Int8
.int
112 val sextdToInt16
: int -> Primitive
.Int16
.int
113 val sextdToInt32
: int -> Primitive
.Int32
.int
114 val sextdToInt64
: int -> Primitive
.Int64
.int
115 val sextdToIntInf
: int -> Primitive
.IntInf
.int
116 val sextdToWord8
: int -> Primitive
.Word8.word
117 val sextdToWord16
: int -> Primitive
.Word16
.word
118 val sextdToWord32
: int -> Primitive
.Word32
.word
119 val sextdToWord64
: int -> Primitive
.Word64
.word
121 val castFromInt8
: Primitive
.Int8
.int -> int
122 val castFromInt16
: Primitive
.Int16
.int -> int
123 val castFromInt32
: Primitive
.Int32
.int -> int
124 val castFromInt64
: Primitive
.Int64
.int -> int
125 val castFromIntInf
: Primitive
.IntInf
.int -> int
126 val castFromWord8
: Primitive
.Word8.word -> int
127 val castFromWord16
: Primitive
.Word16
.word -> int
128 val castFromWord32
: Primitive
.Word32
.word -> int
129 val castFromWord64
: Primitive
.Word64
.word -> int
130 val castToInt8
: int -> Primitive
.Int8
.int
131 val castToInt16
: int -> Primitive
.Int16
.int
132 val castToInt32
: int -> Primitive
.Int32
.int
133 val castToInt64
: int -> Primitive
.Int64
.int
134 val castToIntInf
: int -> Primitive
.IntInf
.int
135 val castToWord8
: int -> Primitive
.Word8.word
136 val castToWord16
: int -> Primitive
.Word16
.word
137 val castToWord32
: int -> Primitive
.Word32
.word
138 val castToWord64
: int -> Primitive
.Word64
.word
140 val zchckFromInt8
: Primitive
.Int8
.int -> int
141 val zchckFromInt16
: Primitive
.Int16
.int -> int
142 val zchckFromInt32
: Primitive
.Int32
.int -> int
143 val zchckFromInt64
: Primitive
.Int64
.int -> int
144 val zchckFromIntInf
: Primitive
.IntInf
.int -> int
145 val zchckFromWord8
: Primitive
.Word8.word -> int
146 val zchckFromWord16
: Primitive
.Word16
.word -> int
147 val zchckFromWord32
: Primitive
.Word32
.word -> int
148 val zchckFromWord64
: Primitive
.Word64
.word -> int
149 val zchckToInt8
: int -> Primitive
.Int8
.int
150 val zchckToInt16
: int -> Primitive
.Int16
.int
151 val zchckToInt32
: int -> Primitive
.Int32
.int
152 val zchckToInt64
: int -> Primitive
.Int64
.int
153 val zchckToIntInf
: int -> Primitive
.IntInf
.int
154 val zchckToWord8
: int -> Primitive
.Word8.word
155 val zchckToWord16
: int -> Primitive
.Word16
.word
156 val zchckToWord32
: int -> Primitive
.Word32
.word
157 val zchckToWord64
: int -> Primitive
.Word64
.word
159 val schckFromInt8
: Primitive
.Int8
.int -> int
160 val schckFromInt16
: Primitive
.Int16
.int -> int
161 val schckFromInt32
: Primitive
.Int32
.int -> int
162 val schckFromInt64
: Primitive
.Int64
.int -> int
163 val schckFromIntInf
: Primitive
.IntInf
.int -> int
164 val schckFromWord8
: Primitive
.Word8.word -> int
165 val schckFromWord16
: Primitive
.Word16
.word -> int
166 val schckFromWord32
: Primitive
.Word32
.word -> int
167 val schckFromWord64
: Primitive
.Word64
.word -> int
168 val schckToInt8
: int -> Primitive
.Int8
.int
169 val schckToInt16
: int -> Primitive
.Int16
.int
170 val schckToInt32
: int -> Primitive
.Int32
.int
171 val schckToInt64
: int -> Primitive
.Int64
.int
172 val schckToIntInf
: int -> Primitive
.IntInf
.int
173 val schckToWord8
: int -> Primitive
.Word8.word
174 val schckToWord16
: int -> Primitive
.Word16
.word
175 val schckToWord32
: int -> Primitive
.Word32
.word
176 val schckToWord64
: int -> Primitive
.Word64
.word
179 signature PRIM_INTWORD_CONV
=
181 include PRIM_INTWORD_CONV
183 val idFromIntInfToIntInf
: Primitive
.IntInf
.int -> Primitive
.IntInf
.int
185 val zextdFromInt8ToIntInf
: Primitive
.Int8
.int -> Primitive
.IntInf
.int
186 val zextdFromInt16ToIntInf
: Primitive
.Int16
.int -> Primitive
.IntInf
.int
187 val zextdFromInt32ToIntInf
: Primitive
.Int32
.int -> Primitive
.IntInf
.int
188 val zextdFromInt64ToIntInf
: Primitive
.Int64
.int -> Primitive
.IntInf
.int
189 val zextdFromWord8ToIntInf
: Primitive
.Word8.word -> Primitive
.IntInf
.int
190 val zextdFromWord16ToIntInf
: Primitive
.Word16
.word -> Primitive
.IntInf
.int
191 val zextdFromWord32ToIntInf
: Primitive
.Word32
.word -> Primitive
.IntInf
.int
192 val zextdFromWord64ToIntInf
: Primitive
.Word64
.word -> Primitive
.IntInf
.int
194 val zextdFromIntInfToInt8
: Primitive
.IntInf
.int -> Primitive
.Int8
.int
195 val zextdFromIntInfToInt16
: Primitive
.IntInf
.int -> Primitive
.Int16
.int
196 val zextdFromIntInfToInt32
: Primitive
.IntInf
.int -> Primitive
.Int32
.int
197 val zextdFromIntInfToInt64
: Primitive
.IntInf
.int -> Primitive
.Int64
.int
198 val zextdFromIntInfToIntInf
: Primitive
.IntInf
.int -> Primitive
.IntInf
.int
199 val zextdFromIntInfToWord8
: Primitive
.IntInf
.int -> Primitive
.Word8.word
200 val zextdFromIntInfToWord16
: Primitive
.IntInf
.int -> Primitive
.Word16
.word
201 val zextdFromIntInfToWord32
: Primitive
.IntInf
.int -> Primitive
.Word32
.word
202 val zextdFromIntInfToWord64
: Primitive
.IntInf
.int -> Primitive
.Word64
.word
205 val sextdFromInt8ToIntInf
: Primitive
.Int8
.int -> Primitive
.IntInf
.int
206 val sextdFromInt16ToIntInf
: Primitive
.Int16
.int -> Primitive
.IntInf
.int
207 val sextdFromInt32ToIntInf
: Primitive
.Int32
.int -> Primitive
.IntInf
.int
208 val sextdFromInt64ToIntInf
: Primitive
.Int64
.int -> Primitive
.IntInf
.int
209 val sextdFromWord8ToIntInf
: Primitive
.Word8.word -> Primitive
.IntInf
.int
210 val sextdFromWord16ToIntInf
: Primitive
.Word16
.word -> Primitive
.IntInf
.int
211 val sextdFromWord32ToIntInf
: Primitive
.Word32
.word -> Primitive
.IntInf
.int
212 val sextdFromWord64ToIntInf
: Primitive
.Word64
.word -> Primitive
.IntInf
.int
214 val sextdFromIntInfToInt8
: Primitive
.IntInf
.int -> Primitive
.Int8
.int
215 val sextdFromIntInfToInt16
: Primitive
.IntInf
.int -> Primitive
.Int16
.int
216 val sextdFromIntInfToInt32
: Primitive
.IntInf
.int -> Primitive
.Int32
.int
217 val sextdFromIntInfToInt64
: Primitive
.IntInf
.int -> Primitive
.Int64
.int
218 val sextdFromIntInfToIntInf
: Primitive
.IntInf
.int -> Primitive
.IntInf
.int
219 val sextdFromIntInfToWord8
: Primitive
.IntInf
.int -> Primitive
.Word8.word
220 val sextdFromIntInfToWord16
: Primitive
.IntInf
.int -> Primitive
.Word16
.word
221 val sextdFromIntInfToWord32
: Primitive
.IntInf
.int -> Primitive
.Word32
.word
222 val sextdFromIntInfToWord64
: Primitive
.IntInf
.int -> Primitive
.Word64
.word
225 val castFromInt8ToIntInf
: Primitive
.Int8
.int -> Primitive
.IntInf
.int
226 val castFromInt16ToIntInf
: Primitive
.Int16
.int -> Primitive
.IntInf
.int
227 val castFromInt32ToIntInf
: Primitive
.Int32
.int -> Primitive
.IntInf
.int
228 val castFromInt64ToIntInf
: Primitive
.Int64
.int -> Primitive
.IntInf
.int
229 val castFromWord8ToIntInf
: Primitive
.Word8.word -> Primitive
.IntInf
.int
230 val castFromWord16ToIntInf
: Primitive
.Word16
.word -> Primitive
.IntInf
.int
231 val castFromWord32ToIntInf
: Primitive
.Word32
.word -> Primitive
.IntInf
.int
232 val castFromWord64ToIntInf
: Primitive
.Word64
.word -> Primitive
.IntInf
.int
234 val castFromIntInfToInt8
: Primitive
.IntInf
.int -> Primitive
.Int8
.int
235 val castFromIntInfToInt16
: Primitive
.IntInf
.int -> Primitive
.Int16
.int
236 val castFromIntInfToInt32
: Primitive
.IntInf
.int -> Primitive
.Int32
.int
237 val castFromIntInfToInt64
: Primitive
.IntInf
.int -> Primitive
.Int64
.int
238 val castFromIntInfToIntInf
: Primitive
.IntInf
.int -> Primitive
.IntInf
.int
239 val castFromIntInfToWord8
: Primitive
.IntInf
.int -> Primitive
.Word8.word
240 val castFromIntInfToWord16
: Primitive
.IntInf
.int -> Primitive
.Word16
.word
241 val castFromIntInfToWord32
: Primitive
.IntInf
.int -> Primitive
.Word32
.word
242 val castFromIntInfToWord64
: Primitive
.IntInf
.int -> Primitive
.Word64
.word
245 val zchckFromInt8ToIntInf
: Primitive
.Int8
.int -> Primitive
.IntInf
.int
246 val zchckFromInt16ToIntInf
: Primitive
.Int16
.int -> Primitive
.IntInf
.int
247 val zchckFromInt32ToIntInf
: Primitive
.Int32
.int -> Primitive
.IntInf
.int
248 val zchckFromInt64ToIntInf
: Primitive
.Int64
.int -> Primitive
.IntInf
.int
249 val zchckFromWord8ToIntInf
: Primitive
.Word8.word -> Primitive
.IntInf
.int
250 val zchckFromWord16ToIntInf
: Primitive
.Word16
.word -> Primitive
.IntInf
.int
251 val zchckFromWord32ToIntInf
: Primitive
.Word32
.word -> Primitive
.IntInf
.int
252 val zchckFromWord64ToIntInf
: Primitive
.Word64
.word -> Primitive
.IntInf
.int
254 val zchckFromIntInfToInt8
: Primitive
.IntInf
.int -> Primitive
.Int8
.int
255 val zchckFromIntInfToInt16
: Primitive
.IntInf
.int -> Primitive
.Int16
.int
256 val zchckFromIntInfToInt32
: Primitive
.IntInf
.int -> Primitive
.Int32
.int
257 val zchckFromIntInfToInt64
: Primitive
.IntInf
.int -> Primitive
.Int64
.int
258 val zchckFromIntInfToIntInf
: Primitive
.IntInf
.int -> Primitive
.IntInf
.int
259 val zchckFromIntInfToWord8
: Primitive
.IntInf
.int -> Primitive
.Word8.word
260 val zchckFromIntInfToWord16
: Primitive
.IntInf
.int -> Primitive
.Word16
.word
261 val zchckFromIntInfToWord32
: Primitive
.IntInf
.int -> Primitive
.Word32
.word
262 val zchckFromIntInfToWord64
: Primitive
.IntInf
.int -> Primitive
.Word64
.word
265 val schckFromInt8ToIntInf
: Primitive
.Int8
.int -> Primitive
.IntInf
.int
266 val schckFromInt16ToIntInf
: Primitive
.Int16
.int -> Primitive
.IntInf
.int
267 val schckFromInt32ToIntInf
: Primitive
.Int32
.int -> Primitive
.IntInf
.int
268 val schckFromInt64ToIntInf
: Primitive
.Int64
.int -> Primitive
.IntInf
.int
269 val schckFromWord8ToIntInf
: Primitive
.Word8.word -> Primitive
.IntInf
.int
270 val schckFromWord16ToIntInf
: Primitive
.Word16
.word -> Primitive
.IntInf
.int
271 val schckFromWord32ToIntInf
: Primitive
.Word32
.word -> Primitive
.IntInf
.int
272 val schckFromWord64ToIntInf
: Primitive
.Word64
.word -> Primitive
.IntInf
.int
274 val schckFromIntInfToInt8
: Primitive
.IntInf
.int -> Primitive
.Int8
.int
275 val schckFromIntInfToInt16
: Primitive
.IntInf
.int -> Primitive
.Int16
.int
276 val schckFromIntInfToInt32
: Primitive
.IntInf
.int -> Primitive
.Int32
.int
277 val schckFromIntInfToInt64
: Primitive
.IntInf
.int -> Primitive
.Int64
.int
278 val schckFromIntInfToIntInf
: Primitive
.IntInf
.int -> Primitive
.IntInf
.int
279 val schckFromIntInfToWord8
: Primitive
.IntInf
.int -> Primitive
.Word8.word
280 val schckFromIntInfToWord16
: Primitive
.IntInf
.int -> Primitive
.Word16
.word
281 val schckFromIntInfToWord32
: Primitive
.IntInf
.int -> Primitive
.Word32
.word
282 val schckFromIntInfToWord64
: Primitive
.IntInf
.int -> Primitive
.Word64
.word
284 signature PRIM_INTEGER
=
288 val zextdFromIntInf
: Primitive
.IntInf
.int -> int
289 val zextdToIntInf
: int -> Primitive
.IntInf
.int
291 val sextdFromIntInf
: Primitive
.IntInf
.int -> int
292 val sextdToIntInf
: int -> Primitive
.IntInf
.int
294 val castFromIntInf
: Primitive
.IntInf
.int -> int
295 val castToIntInf
: int -> Primitive
.IntInf
.int
297 val zchckFromIntInf
: Primitive
.IntInf
.int -> int
298 val zchckToIntInf
: int -> Primitive
.IntInf
.int
300 val schckFromIntInf
: Primitive
.IntInf
.int -> int
301 val schckToIntInf
: int -> Primitive
.IntInf
.int
303 signature PRIM_WORD
=
307 val zextdFromIntInf
: Primitive
.IntInf
.int -> word
308 val zextdToIntInf
: word -> Primitive
.IntInf
.int
310 val sextdFromIntInf
: Primitive
.IntInf
.int -> word
311 val sextdToIntInf
: word -> Primitive
.IntInf
.int
313 val castFromIntInf
: Primitive
.IntInf
.int -> word
314 val castToIntInf
: word -> Primitive
.IntInf
.int
316 val zchckFromIntInf
: Primitive
.IntInf
.int -> word
317 val zchckToIntInf
: word -> Primitive
.IntInf
.int
319 val schckFromIntInf
: Primitive
.IntInf
.int -> word
320 val schckToIntInf
: word -> Primitive
.IntInf
.int
323 structure Primitive
= struct
329 structure Prim
= Primitive
.IntInf
330 structure MLton
= Primitive
.MLton
332 structure A
= Primitive
.Array
333 structure V
= Primitive
.Vector
334 structure S
= SeqIndex
335 structure ObjptrWord
= struct
340 (type 'a t
= 'a
-> ObjptrWord
.word
341 val fInt8
= ObjptrWord
.zextdFromInt8
342 val fInt16
= ObjptrWord
.zextdFromInt16
343 val fInt32
= ObjptrWord
.zextdFromInt32
344 val fInt64
= ObjptrWord
.zextdFromInt64
)
346 val idFromObjptrInt
= S
.f
351 (type 'a t
= ObjptrWord
.word -> 'a
352 val fInt8
= ObjptrWord
.zextdToInt8
353 val fInt16
= ObjptrWord
.zextdToInt16
354 val fInt32
= ObjptrWord
.zextdToInt32
355 val fInt64
= ObjptrWord
.zextdToInt64
)
357 val idToObjptrInt
= S
.f
362 (type 'a t
= 'a
-> ObjptrWord
.word
363 val fWord8
= ObjptrWord
.castFromWord8
364 val fWord16
= ObjptrWord
.castFromWord16
365 val fWord32
= ObjptrWord
.castFromWord32
366 val fWord64
= ObjptrWord
.castFromWord64
)
368 val castFromMPLimb
= S
.f
373 (type 'a t
= ObjptrWord
.word -> 'a
374 val fWord8
= ObjptrWord
.castToWord8
375 val fWord16
= ObjptrWord
.castToWord16
376 val fWord32
= ObjptrWord
.castToWord32
377 val fWord64
= ObjptrWord
.castToWord64
)
379 val castToMPLimb
= S
.f
382 structure W
= ObjptrWord
383 structure I
= ObjptrInt
384 structure MPLimb
= C_MPLimb
385 structure Sz
= struct
390 (type 'a t
= 'a
-> C_Size
.word
391 val fInt8
= C_Size
.zextdFromInt8
392 val fInt16
= C_Size
.zextdFromInt16
393 val fInt32
= C_Size
.zextdFromInt32
394 val fInt64
= C_Size
.zextdFromInt64
)
396 val zextdFromSeqIndex
= S
.f
400 type bigInt
= Prim
.int
404 val negOne
: bigInt
= ~
1
406 (* Check
if an IntInf
.int is
small (i
.e
., a fixnum
). *)
407 fun isSmall (i
: bigInt
): bool =
408 0w0
<> W
.andb (Prim
.toWord i
, 0w1
)
410 (* Check
if two IntInf
.int's are both
small (i
.e
., fixnums
). *)
411 fun areSmall (i
: bigInt
, i
': bigInt
): bool =
412 0w0
<> W
.andb (W
.andb (Prim
.toWord i
, Prim
.toWord i
'), 0w1
)
414 (* Return the number
of `limbs
' in a bigInt
. *)
415 fun bigNumLimbs i
= S
.- (V
.length (Prim
.toVector i
), 1)
421 fun dropTag (w
: W
.word): W
.word = W
.~
>>?
(w
, 0w1
)
422 fun dropTagCoerce (i
: bigInt
): W
.word = dropTag (Prim
.toWord i
)
423 fun dropTagCoerceInt (i
: bigInt
): I
.int = W
.idToObjptrInt (dropTagCoerce i
)
424 fun addTag (w
: W
.word): W
.word = W
.orb (W
.<<?
(w
, 0w1
), 0w1
)
425 fun addTagCoerce (w
: W
.word): bigInt
= Prim
.fromWord (addTag w
)
426 fun addTagCoerceInt (i
: I
.int): bigInt
= addTagCoerce (W
.idFromObjptrInt i
)
427 fun zeroTag (w
: W
.word): W
.word = W
.andb (w
, W
.notb
0w1
)
428 fun oneTag (w
: W
.word): W
.word = W
.orb (w
, 0w1
)
429 fun oneTagCoerce (w
: W
.word): bigInt
= Prim
.fromWord (oneTag w
)
433 Big
of MPLimb
.t V
.vector
434 | Small
of ObjptrInt
.int
438 then Small (dropTagCoerceInt i
)
439 else Big (Prim
.toVector i
)
446 if Int32
.>= (MPLimb
.sizeInBits
, ObjptrWord
.sizeInBits
)
448 else S
.sextdFromInt32 (Int32
.quot (ObjptrWord
.sizeInBits
, MPLimb
.sizeInBits
))
452 (* sign limb
+ magnitude
limb(s
) *)
454 (* sign limb is
0w0 (positive
) or
0w1 (negative
) *)
455 MPLimb
.<= (V
.unsafeSub (v
, 0), 0w1
) andalso
456 (* most
-significant magnitude limb is non
-zero
*)
457 MPLimb
.> (V
.unsafeSub (v
, S
.- (l
, 1)), 0w0
) andalso
458 (* value exceeds Small representation
;
459 * if positive
, then mag
in [1, 2^
(ObjptrWord
.sizeInBits
- 2)].
460 * if negative
, then mag
in [0, 2^
(ObjptrWord
.sizeInBits
- 2) - 1].
462 (S
.> (l
, S
.+ (1, limbsPerObjptr
)) orelse
463 if Int32
.<= (ObjptrWord
.sizeInBits
, MPLimb
.sizeInBits
)
465 val mag
= V
.unsafeSub (v
, 1)
468 (if MPLimb
.>= (V
.unsafeSub (v
, 0), 0w1
) then MPLimb
.- (mag
, 0w1
) else mag
,
469 MPLimb
.<<?
(0w1
, Word32
.- (ObjptrWord
.sizeInBitsWord
, 0w2
)))
475 (ObjptrWord
.<<?
(mag
, MPLimb
.sizeInBitsWord
),
476 W
.castFromMPLimb (V
.unsafeSub (v
, i
)))
478 val mag
= loop (2, W
.castFromMPLimb (V
.unsafeSub (v
, 1)))
481 (if MPLimb
.>= (V
.unsafeSub (v
, 0), 0w1
) then ObjptrWord
.- (mag
, 0w1
) else mag
,
482 ObjptrWord
.<<?
(0w1
, Word32
.- (ObjptrWord
.sizeInBitsWord
, 0w2
)))
486 then SOME (Prim
.fromVector v
)
491 val w
= ObjptrWord
.idFromObjptrInt i
493 val ok
= w
= dropTag wt
496 then SOME (Prim
.fromWord wt
)
502 fun 'a make
{zextdToMPLimb
: 'a
-> MPLimb
.word,
503 zextdToObjptrWord
: 'a
-> ObjptrWord
.word,
504 sextdToObjptrWord
: 'a
-> ObjptrWord
.word,
505 other
: {sizeInBits
: Int32
.int,
511 rashift
: 'a
* Word32
.word -> 'a
,
512 rshift
: 'a
* Word32
.word -> 'a
}}
514 if Int32
.> (ObjptrWord
.sizeInBits
, #sizeInBits other
)
516 val shift
= Word32
.- (ObjptrWord
.sizeInBitsWord
, 0w2
)
517 val upperBits
= (#rashift other
) (w
, shift
)
518 val zeroBits
= #zero other
519 val oneBits
= (#notb other
) zeroBits
521 (#eq other
) (upperBits
, zeroBits
)
523 (sextd
andalso (#eq other
) (upperBits
, oneBits
))
526 then Prim
.fromWord (addTag (sextdToObjptrWord w
))
527 else Prim
.fromWord (addTag (zextdToObjptrWord w
))
529 fun loop (w
, i
, acc
) =
530 if (#eq other
) (w
, (#zero other
))
534 val limb
= zextdToMPLimb w
537 (w
, MPLimb
.sizeInBitsWord
)
539 loop (w
, S
.+ (i
, 1), (i
, limb
) :: acc
)
542 if sextd
andalso (#isNeg other
) w
543 then loop ((#neg other
) w
, 1, [(0,0w1
)])
544 else loop (w
, 1, [(0,0w0
)])
545 val a
= A
.unsafeAlloc n
549 |
(i
, v
) :: acc
=> (A
.unsafeUpdate (a
, i
, v
)
553 Prim
.fromVector (V
.unsafeFromArray a
)
556 fun extdFromWord8 (sextd
, w
) =
557 make
{zextdToMPLimb
= MPLimb
.zextdFromWord8
,
558 zextdToObjptrWord
= ObjptrWord
.zextdFromWord8
,
559 sextdToObjptrWord
= ObjptrWord
.sextdFromWord8
,
560 other
= {sizeInBits
= Word8.sizeInBits
,
562 eq
= ((op =) : Word8.word * Word8.word -> bool),
563 isNeg
= fn w
=> Int8
.< (IntWordConv
.idFromWord8ToInt8 w
, 0),
566 rashift
= Word8.~
>>?
,
569 fun zextdFromWord8 w
= extdFromWord8 (false, w
)
570 fun zextdFromInt8 i
= zextdFromWord8 (IntWordConv
.idFromInt8ToWord8 i
)
571 fun sextdFromWord8 w
= extdFromWord8 (true, w
)
572 fun sextdFromInt8 i
= sextdFromWord8 (IntWordConv
.idFromInt8ToWord8 i
)
573 val castFromInt8
= sextdFromInt8
574 val castFromWord8
= zextdFromWord8
575 val zchckFromInt8
= zextdFromInt8
576 val zchckFromWord8
= zextdFromWord8
577 val schckFromInt8
= sextdFromInt8
578 val schckFromWord8
= sextdFromWord8
580 fun extdFromWord16 (sextd
, w
) =
581 make
{zextdToMPLimb
= MPLimb
.zextdFromWord16
,
582 zextdToObjptrWord
= ObjptrWord
.zextdFromWord16
,
583 sextdToObjptrWord
= ObjptrWord
.sextdFromWord16
,
584 other
= {sizeInBits
= Word16
.sizeInBits
,
586 eq
= ((op =) : Word16
.word * Word16
.word -> bool),
587 isNeg
= fn w
=> Int16
.< (IntWordConv
.idFromWord16ToInt16 w
, 0),
590 rashift
= Word16
.~
>>?
,
591 rshift
= Word16
.>>?
}}
593 fun zextdFromWord16 w
= extdFromWord16 (false, w
)
594 fun zextdFromInt16 i
= zextdFromWord16 (IntWordConv
.idFromInt16ToWord16 i
)
595 fun sextdFromWord16 w
= extdFromWord16 (true, w
)
596 fun sextdFromInt16 i
= sextdFromWord16 (IntWordConv
.idFromInt16ToWord16 i
)
597 val castFromInt16
= sextdFromInt16
598 val castFromWord16
= zextdFromWord16
599 val zchckFromInt16
= zextdFromInt16
600 val zchckFromWord16
= zextdFromWord16
601 val schckFromInt16
= sextdFromInt16
602 val schckFromWord16
= sextdFromWord16
604 fun extdFromWord32 (sextd
, w
) =
605 make
{zextdToMPLimb
= MPLimb
.zextdFromWord32
,
606 zextdToObjptrWord
= ObjptrWord
.zextdFromWord32
,
607 sextdToObjptrWord
= ObjptrWord
.sextdFromWord32
,
608 other
= {sizeInBits
= Word32
.sizeInBits
,
610 eq
= ((op =) : Word32
.word * Word32
.word -> bool),
611 isNeg
= fn w
=> Int32
.< (IntWordConv
.idFromWord32ToInt32 w
, 0),
614 rashift
= Word32
.~
>>?
,
615 rshift
= Word32
.>>?
}}
617 fun zextdFromWord32 w
= extdFromWord32 (false, w
)
618 fun zextdFromInt32 i
= zextdFromWord32 (IntWordConv
.idFromInt32ToWord32 i
)
619 fun sextdFromWord32 w
= extdFromWord32 (true, w
)
620 fun sextdFromInt32 i
= sextdFromWord32 (IntWordConv
.idFromInt32ToWord32 i
)
621 val castFromInt32
= sextdFromInt32
622 val castFromWord32
= zextdFromWord32
623 val zchckFromInt32
= zextdFromInt32
624 val zchckFromWord32
= zextdFromWord32
625 val schckFromInt32
= sextdFromInt32
626 val schckFromWord32
= sextdFromWord32
628 fun extdFromWord64 (sextd
, w
) =
629 make
{zextdToMPLimb
= MPLimb
.zextdFromWord64
,
630 zextdToObjptrWord
= ObjptrWord
.zextdFromWord64
,
631 sextdToObjptrWord
= ObjptrWord
.sextdFromWord64
,
632 other
= {sizeInBits
= Word64
.sizeInBits
,
634 eq
= ((op =) : Word64
.word * Word64
.word -> bool),
635 isNeg
= fn w
=> Int64
.< (IntWordConv
.idFromWord64ToInt64 w
, 0),
638 rashift
= Word64
.~
>>?
,
639 rshift
= Word64
.>>?
}}
641 fun zextdFromWord64 w
= extdFromWord64 (false, w
)
642 fun zextdFromInt64 i
= zextdFromWord64 (IntWordConv
.idFromInt64ToWord64 i
)
643 fun sextdFromWord64 w
= extdFromWord64 (true, w
)
644 fun sextdFromInt64 i
= sextdFromWord64 (IntWordConv
.idFromInt64ToWord64 i
)
645 val castFromInt64
= sextdFromInt64
646 val castFromWord64
= zextdFromWord64
647 val zchckFromInt64
= zextdFromInt64
648 val zchckFromWord64
= zextdFromWord64
649 val schckFromInt64
= sextdFromInt64
650 val schckFromWord64
= sextdFromWord64
652 fun zextdFromIntInf ii
= ii
653 fun sextdFromIntInf ii
= ii
654 fun castFromIntInf ii
= ii
655 fun zchckFromIntInf ii
= ii
656 fun schckFromIntInf ii
= ii
662 (type 'a t
= 'a
-> bigInt
663 val fInt8
= sextdFromInt8
664 val fInt16
= sextdFromInt16
665 val fInt32
= sextdFromInt32
666 val fInt64
= sextdFromInt64
)
668 val sextdFromObjptrInt
= S
.f
673 Big
of bool * bool * 'a
674 | Small
of ObjptrWord
.word
675 fun 'a make
{zextdFromMPLimb
: MPLimb
.word -> 'a
,
676 other
: {sizeInBits
: Int32
.int,
677 sizeInBitsWord
: Word32
.word,
679 lshift
: 'a
* Word32
.word -> 'a
,
680 orb
: 'a
* 'a
-> 'a
}} i
=
682 then Small (dropTagCoerce i
)
684 val v
= Prim
.toVector i
686 val isneg
= V
.unsafeSub (v
, 0) <> 0w0
688 if Int32
.>= (MPLimb
.sizeInBits
, #sizeInBits other
)
690 val limbsPer
: S
.t
= 1
691 val limb
= V
.unsafeSub (v
, 1)
693 S
.> (n
, S
.+ (limbsPer
, 1))
695 (MPLimb
.>>?
(limb
, #sizeInBitsWord other
)) <> 0w0
696 val ans
= zextdFromMPLimb limb
698 Big (isneg
, extra
, ans
)
703 (Int32
.quot (#sizeInBits other
,
705 val extra
= S
.> (n
, S
.+ (limbsPer
, 1))
711 val limb
= V
.unsafeSub (v
, i
)
715 (ans
, MPLimb
.sizeInBitsWord
),
716 zextdFromMPLimb limb
)
718 loop (S
.- (i
, 1), ans
)
722 loop (S
.min (S
.- (n
, 1), limbsPer
), #zero other
)
725 Big (isneg
, extra
, ans
)
730 make
{zextdFromMPLimb
= MPLimb
.zextdToWord8
,
731 other
= {sizeInBits
= Word8.sizeInBits
,
732 sizeInBitsWord
= Word8.sizeInBitsWord
,
737 case chckToWord8Aux i
of
738 Small w
=> ObjptrWord
.sextdToWord8 w
739 |
Big (isneg
, _
, ans
) => if isneg
then Word8.~ ans
else ans
740 fun sextdToInt8 i
= IntWordConv
.idFromWord8ToInt8 (sextdToWord8 i
)
741 val zextdToWord8
= sextdToWord8
742 fun zextdToInt8 i
= IntWordConv
.idFromWord8ToInt8 (zextdToWord8 i
)
743 val castToWord8
= sextdToWord8
744 val castToInt8
= sextdToInt8
746 if not Primitive
.Controls
.detectOverflow
749 case chckToWord8Aux i
of
750 Small w
=> ObjptrWord
.schckToWord8 w
751 |
Big (isneg
, extra
, ans
) =>
756 val ans
= Word8.~ ans
757 val ans
' = IntWordConv
.idFromWord8ToInt8 ans
764 val ans
' = IntWordConv
.idFromWord8ToInt8 ans
770 fun schckToInt8 i
= IntWordConv
.idFromWord8ToInt8 (schckToWord8 i
)
772 if not Primitive
.Controls
.detectOverflow
775 case chckToWord8Aux i
of
776 Small w
=> ObjptrWord
.schckToWord8 w
777 |
Big (isneg
, extra
, ans
) =>
778 if isneg
orelse extra
781 fun zchckToInt8 i
= IntWordConv
.idFromWord8ToInt8 (zchckToWord8 i
)
783 val chckToWord16Aux
=
784 make
{zextdFromMPLimb
= MPLimb
.zextdToWord16
,
785 other
= {sizeInBits
= Word16
.sizeInBits
,
786 sizeInBitsWord
= Word16
.sizeInBitsWord
,
790 fun sextdToWord16 i
=
791 case chckToWord16Aux i
of
792 Small w
=> ObjptrWord
.sextdToWord16 w
793 |
Big (isneg
, _
, ans
) => if isneg
then Word16
.~ ans
else ans
794 fun sextdToInt16 i
= IntWordConv
.idFromWord16ToInt16 (sextdToWord16 i
)
795 val zextdToWord16
= sextdToWord16
796 fun zextdToInt16 i
= IntWordConv
.idFromWord16ToInt16 (zextdToWord16 i
)
797 val castToWord16
= sextdToWord16
798 val castToInt16
= sextdToInt16
799 fun schckToWord16 i
=
800 if not Primitive
.Controls
.detectOverflow
803 case chckToWord16Aux i
of
804 Small w
=> ObjptrWord
.schckToWord16 w
805 |
Big (isneg
, extra
, ans
) =>
810 val ans
= Word16
.~ ans
811 val ans
' = IntWordConv
.idFromWord16ToInt16 ans
818 val ans
' = IntWordConv
.idFromWord16ToInt16 ans
824 fun schckToInt16 i
= IntWordConv
.idFromWord16ToInt16 (schckToWord16 i
)
825 fun zchckToWord16 i
=
826 if not Primitive
.Controls
.detectOverflow
829 case chckToWord16Aux i
of
830 Small w
=> ObjptrWord
.schckToWord16 w
831 |
Big (isneg
, extra
, ans
) =>
832 if isneg
orelse extra
835 fun zchckToInt16 i
= IntWordConv
.idFromWord16ToInt16 (zchckToWord16 i
)
837 val chckToWord32Aux
=
838 make
{zextdFromMPLimb
= MPLimb
.zextdToWord32
,
839 other
= {sizeInBits
= Word32
.sizeInBits
,
840 sizeInBitsWord
= Word32
.sizeInBitsWord
,
844 fun sextdToWord32 i
=
845 case chckToWord32Aux i
of
846 Small w
=> ObjptrWord
.sextdToWord32 w
847 |
Big (isneg
, _
, ans
) => if isneg
then Word32
.~ ans
else ans
848 fun sextdToInt32 i
= IntWordConv
.idFromWord32ToInt32 (sextdToWord32 i
)
849 val zextdToWord32
= sextdToWord32
850 fun zextdToInt32 i
= IntWordConv
.idFromWord32ToInt32 (zextdToWord32 i
)
851 val castToWord32
= sextdToWord32
852 val castToInt32
= sextdToInt32
853 fun schckToWord32 i
=
854 if not Primitive
.Controls
.detectOverflow
857 case chckToWord32Aux i
of
858 Small w
=> ObjptrWord
.schckToWord32 w
859 |
Big (isneg
, extra
, ans
) =>
864 val ans
= Word32
.~ ans
865 val ans
' = IntWordConv
.idFromWord32ToInt32 ans
872 val ans
' = IntWordConv
.idFromWord32ToInt32 ans
878 fun schckToInt32 i
= IntWordConv
.idFromWord32ToInt32 (schckToWord32 i
)
879 fun zchckToWord32 i
=
880 if not Primitive
.Controls
.detectOverflow
883 case chckToWord32Aux i
of
884 Small w
=> ObjptrWord
.schckToWord32 w
885 |
Big (isneg
, extra
, ans
) =>
886 if isneg
orelse extra
889 fun zchckToInt32 i
= IntWordConv
.idFromWord32ToInt32 (zchckToWord32 i
)
891 val chckToWord64Aux
=
892 make
{zextdFromMPLimb
= MPLimb
.zextdToWord64
,
893 other
= {sizeInBits
= Word64
.sizeInBits
,
894 sizeInBitsWord
= Word64
.sizeInBitsWord
,
898 fun sextdToWord64 i
=
899 case chckToWord64Aux i
of
900 Small w
=> ObjptrWord
.sextdToWord64 w
901 |
Big (isneg
, _
, ans
) => if isneg
then Word64
.~ ans
else ans
902 fun sextdToInt64 i
= IntWordConv
.idFromWord64ToInt64 (sextdToWord64 i
)
903 val zextdToWord64
= sextdToWord64
904 fun zextdToInt64 i
= IntWordConv
.idFromWord64ToInt64 (zextdToWord64 i
)
905 val castToWord64
= sextdToWord64
906 val castToInt64
= sextdToInt64
907 fun schckToWord64 i
=
908 if not Primitive
.Controls
.detectOverflow
911 case chckToWord64Aux i
of
912 Small w
=> ObjptrWord
.schckToWord64 w
913 |
Big (isneg
, extra
, ans
) =>
918 val ans
= Word64
.~ ans
919 val ans
' = IntWordConv
.idFromWord64ToInt64 ans
926 val ans
' = IntWordConv
.idFromWord64ToInt64 ans
932 fun schckToInt64 i
= IntWordConv
.idFromWord64ToInt64 (schckToWord64 i
)
933 fun zchckToWord64 i
=
934 if not Primitive
.Controls
.detectOverflow
937 case chckToWord64Aux i
of
938 Small w
=> ObjptrWord
.schckToWord64 w
939 |
Big (isneg
, extra
, ans
) =>
940 if isneg
orelse extra
943 fun zchckToInt64 i
= IntWordConv
.idFromWord64ToInt64 (zchckToWord64 i
)
945 fun zextdToIntInf ii
= ii
946 fun sextdToIntInf ii
= ii
947 fun castToIntInf ii
= ii
948 fun zchckToIntInf ii
= ii
949 fun schckToIntInf ii
= ii
953 val bytesPerMPLimb
= Sz
.zextdFromInt32 (Int32
.quot (MPLimb
.sizeInBits
, 8))
955 val bytesPerArrayMetaData
= Sz
.zextdFromInt32 ArrayMetaDataSize
.bytes
956 (* Reserve heap space for a large IntInf
.int with room for num
+ extra
957 * `limbs
'. The reason for splitting this up is that extra is intended
958 * to be a constant
, and so can be combined at compile time
.
960 fun reserve (num
: S
.int, extra
: S
.int) =
961 Sz
.+ (Sz
.* (bytesPerMPLimb
, Sz
.zextdFromSeqIndex num
),
962 Sz
.+ (Sz
.* (bytesPerMPLimb
, Sz
.zextdFromSeqIndex extra
),
963 Sz
.+ (bytesPerMPLimb
, (* isneg Field
*)
964 Sz
.+ (bytesPerArrayMetaData
, (* Array MetaData
*)
965 case MLton
.Align
.align
of (* alignment
*)
966 MLton
.Align
.Align4
=> 0w3
967 | MLton
.Align
.Align8
=> 0w7
971 (* badObjptr
{Int,Word}{,Tagged
} is the fixnum IntInf
.int whose
972 * negation
and absolute values are not fixnums
.
973 * negBadIntInf is the
negation (and absolute value
) of that IntInf
.int.
975 val badObjptrInt
: I
.int = I
.~
>>?
(I
.minInt
', 0w1
)
976 val badObjptrWord
: W
.word = W
.idFromObjptrInt badObjptrInt
977 val badObjptrWordTagged
: W
.word = addTag badObjptrWord
978 (* val badObjptrIntTagged
: I
.int = W
.idToObjptrInt badObjptrWordTagged
*)
979 val negBadIntInf
: bigInt
= sextdFromObjptrInt (I
.~ badObjptrInt
)
981 (* Given two ObjptrWord
.word's
, check
if they have the same
'high
'/'sign
' bit
.
983 fun sameSignBit (lhs
: W
.word, rhs
: W
.word): bool =
984 I
.>= (W
.idToObjptrInt (W
.xorb (lhs
, rhs
)), 0)
986 (* Given a bignum bigint
, test
if it
is (strictly
) negative
.
988 fun bigIsNeg (arg
: bigInt
): bool =
989 V
.unsafeSub (Prim
.toVector arg
, 0) <> 0w0
992 fun make (smallOp
, bigOp
, limbsFn
, extra
)
993 (lhs
: bigInt
, rhs
: bigInt
): bigInt
=
996 if areSmall (lhs
, rhs
)
998 val lhsw
= dropTagCoerce lhs
999 val lhsi
= W
.idToObjptrInt lhsw
1000 val rhsw
= dropTagCoerce rhs
1001 val rhsi
= W
.idToObjptrInt rhsw
1002 val ansi
= smallOp (lhsi
, rhsi
)
1003 val answ
= W
.idFromObjptrInt ansi
1004 val ans
= addTag answ
1006 if sameSignBit (ans
, answ
)
1007 then SOME (Prim
.fromWord ans
)
1009 end handle Overflow
=> NONE
1013 NONE
=> bigOp (lhs
, rhs
,
1014 reserve (limbsFn (numLimbs lhs
, numLimbs rhs
), extra
))
1018 val bigAdd
= make (I
.+!, Prim
.+, S
.max
, 1)
1019 val bigSub
= make (I
.-!, Prim
.-, S
.max
, 1)
1020 val bigMul
= make (I
.*!, Prim
.*, S
.+, 0)
1023 fun bigNeg (arg
: bigInt
): bigInt
=
1026 val argw
= Prim
.toWord arg
1028 if argw
= badObjptrWordTagged
1030 else Prim
.fromWord (W
.- (0w2
, argw
))
1032 else Prim
.~
(arg
, reserve (numLimbs arg
, 1))
1035 fun bigQuot (num
: bigInt
, den
: bigInt
): bigInt
=
1036 if areSmall (num
, den
)
1038 val numw
= dropTagCoerce num
1039 val numi
= W
.idToObjptrInt numw
1040 val denw
= dropTagCoerce den
1041 val deni
= W
.idToObjptrInt denw
1043 if numw
= badObjptrWord
1047 val ansi
= I
.quot (numi
, deni
)
1048 val answ
= W
.idFromObjptrInt ansi
1049 val ans
= addTag answ
1055 val nlimbs
= numLimbs num
1056 val dlimbs
= numLimbs den
1058 if S
.< (nlimbs
, dlimbs
)
1062 else Prim
.quot (num
, den
,
1063 reserve (S
.- (nlimbs
, dlimbs
), 2))
1066 fun bigRem (num
: bigInt
, den
: bigInt
): bigInt
=
1067 if areSmall (num
, den
)
1069 val numw
= dropTagCoerce num
1070 val numi
= W
.idToObjptrInt numw
1071 val denw
= dropTagCoerce den
1072 val deni
= W
.idToObjptrInt denw
1073 val ansi
= I
.rem (numi
, deni
)
1074 val answ
= W
.idFromObjptrInt ansi
1075 val ans
= addTag answ
1080 val nlimbs
= numLimbs num
1081 val dlimbs
= numLimbs den
1083 if S
.< (nlimbs
, dlimbs
)
1087 else Prim
.rem (num
, den
,
1088 reserve (dlimbs
, 1))
1091 (* Based on code from PolySpace
. *)
1095 fun mod2 x
= I
.andb (x
, 1)
1096 fun div2 x
= I
.>>?
(x
, 0w1
)
1098 fun smallGcd (a
, b
, acc
) =
1104 |
(_
: I
.t
* I
.t
) =>
1117 then smallGcd (a_2
, b_2
, acc
+ acc
)
1118 else smallGcd (a_2
, b
, acc
)
1121 then smallGcd (a
, b_2
, acc
)
1124 then smallGcd (div2 (a
- b
), b
, acc
)
1125 else smallGcd (a
, div2 (b
- a
), acc
)
1128 fun bigGcd (lhs
: bigInt
, rhs
: bigInt
): bigInt
=
1129 if areSmall (lhs
, rhs
)
1130 then addTagCoerceInt
1131 (smallGcd (I
.abs (dropTagCoerceInt lhs
),
1132 I
.abs (dropTagCoerceInt rhs
),
1135 (lhs
, rhs
, reserve (S
.max (numLimbs lhs
, numLimbs rhs
), 0))
1139 fun make (smallTest
: I
.int * I
.int -> 'a
,
1140 int32Test
: Int32
.int * Int32
.int -> 'a
)
1141 (lhs
: bigInt
, rhs
: bigInt
): 'a
=
1142 if areSmall (lhs
, rhs
)
1143 then smallTest (W
.idToObjptrInt (Prim
.toWord lhs
),
1144 W
.idToObjptrInt (Prim
.toWord rhs
))
1145 else int32Test (Prim
.compare (lhs
, rhs
), 0)
1147 val bigCompare
= make (I
.compare
, Int32
.compare
)
1148 val bigLT
= make (I
.<, Int32
.<)
1149 val bigLE
= make (I
.<=, Int32
.<=)
1150 val bigGT
= make (I
.>, Int32
.>)
1151 val bigGE
= make (I
.>=, Int32
.>=)
1154 fun bigAbs (arg
: bigInt
): bigInt
=
1157 val argw
= Prim
.toWord arg
1159 if argw
= badObjptrWordTagged
1161 else if I
.< (W
.idToObjptrInt argw
, 0)
1162 then Prim
.fromWord (W
.- (0w2
, argw
))
1165 else if bigIsNeg arg
1166 then Prim
.~
(arg
, reserve (numLimbs arg
, 1))
1169 fun bigMin (lhs
: bigInt
, rhs
: bigInt
): bigInt
=
1170 if bigLE (lhs
, rhs
) then lhs
else rhs
1172 fun bigMax (lhs
: bigInt
, rhs
: bigInt
): bigInt
=
1173 if bigLE (lhs
, rhs
) then rhs
else lhs
1176 fun bigLTU (lhs
, rhs
) =
1177 case (bigCompare (lhs
, 0), bigCompare (rhs
, 0)) of
1178 (LESS
, LESS
) => bigLT (lhs
, rhs
)
1179 |
(LESS
, GREATER
) => false
1180 |
(_
, EQUAL
) => false
1181 |
(EQUAL
, _
) => true
1182 |
(GREATER
, LESS
) => true
1183 |
(GREATER
, GREATER
) => bigLT (lhs
, rhs
)
1184 structure S
= IntegralComparisons(type t
= bigInt
1209 else quot (x
- one
, y
) - one
1214 then quot (x
+ one
, y
) - one
1224 else rem (x
- one
, y
) + (one
+ y
)
1229 then rem (x
+ one
, y
) + (y
- one
)
1232 fun bigDivMod (x
, y
) = (bigDiv (x
, y
), bigMod (x
, y
))
1233 fun bigQuotRem (x
, y
) = (bigQuot (x
, y
), bigRem (x
, y
))
1237 fun make (smallOp
, bigOp
)
1238 (lhs
: bigInt
, rhs
: bigInt
) =
1239 if areSmall (lhs
, rhs
)
1242 val answ
= smallOp (Prim
.toWord lhs
, Prim
.toWord rhs
)
1243 val ans
= oneTagCoerce answ
1247 else bigOp (lhs
, rhs
,
1248 reserve (S
.max (numLimbs lhs
, numLimbs rhs
), 0))
1250 val bigAndb
= make (W
.andb
, Prim
.andb
)
1251 val bigOrb
= make (W
.orb
, Prim
.orb
)
1252 val bigXorb
= make (W
.xorb
, Prim
.xorb
)
1255 fun bigNotb (arg
: bigInt
): bigInt
=
1257 then oneTagCoerce (W
.notb (Prim
.toWord arg
))
1258 else Prim
.notb (arg
, reserve (numLimbs arg
, 0))
1261 val bitsPerLimb
= MPLimb
.sizeInBitsWord
1262 fun shiftSize shift
= S
.sextdFromWord32 (Word32
.div (shift
, bitsPerLimb
))
1264 fun bigLshift (arg
: bigInt
, shift
: Word32
.word): bigInt
=
1267 else Prim
.<< (arg
, shift
,
1268 reserve (S
.+ (numLimbs arg
, shiftSize shift
), 1))
1269 fun bigRashift (arg
: bigInt
, shift
: Word32
.word): bigInt
=
1272 else Prim
.~
>> (arg
, shift
,
1273 reserve (S
.max (0, S
.- (numLimbs arg
, shiftSize shift
)), 1))
1276 fun mkBigCvt
{base
: Int32
.int,
1277 smallCvt
: I
.int -> Primitive
.String8
.string}
1279 : Primitive
.String8
.string =
1281 then smallCvt (dropTagCoerceInt arg
)
1283 val bpd
= Int32
.log2 base
1284 val bpl
= MPLimb
.sizeInBits
1286 Int32
.+ (Int32
.quot (bpl
, bpd
),
1287 if Int32
.mod (bpl
, bpd
) = 0
1290 Sz
.+ (Sz
.+ (bytesPerArrayMetaData (* Array MetaData
*),
1291 Sz
.+ (0w1 (* sign
*),
1292 case MLton
.Align
.align
of (* alignment
*)
1293 MLton
.Align
.Align4
=> 0w3
1294 | MLton
.Align
.Align8
=> 0w7
)),
1295 Sz
.* (Sz
.zextdFromInt32 dpl
,
1296 Sz
.zextdFromSeqIndex (numLimbs arg
)))
1298 Prim
.toString (arg
, base
, bytes
)
1301 fun mkBigLog2
{fromSmall
: {smallLog2
: Primitive
.Int32
.int} -> 'a
,
1302 fromLarge
: {numLimbsMinusOne
: SeqIndex
.int,
1303 mostSigLimbLog2
: Primitive
.Int32
.int} -> 'a
}
1308 then fromSmall
{smallLog2
= W
.log2 (dropTagCoerce arg
)}
1310 val v
= Prim
.toVector arg
1312 val w
= MPLimb
.log2 (V
.unsafeSub (v
, S
.- (n
, 1)))
1314 fromLarge
{numLimbsMinusOne
= S
.- (n
, 2),
1315 mostSigLimbLog2
= w
}
1321 val precision
= NONE
1330 val divMod
= bigDivMod
1340 val quotRem
= bigQuotRem
1351 val compare
= bigCompare
1364 val ~
>>?
= bigRashift
1365 val ~
>> = bigRashift
1368 val mkCvt
= mkBigCvt
1369 val mkLog2
= mkBigLog2
1372 structure IntWordConv
: PRIM_INTWORD_CONV
=
1376 val idFromIntInfToIntInf
= fn i
=> i
1379 val zextdFromInt8ToIntInf
= IntInf
.zextdFromInt8
1380 val zextdFromInt16ToIntInf
= IntInf
.zextdFromInt16
1381 val zextdFromInt32ToIntInf
= IntInf
.zextdFromInt32
1382 val zextdFromInt64ToIntInf
= IntInf
.zextdFromInt64
1383 val zextdFromWord8ToIntInf
= IntInf
.zextdFromWord8
1384 val zextdFromWord16ToIntInf
= IntInf
.zextdFromWord16
1385 val zextdFromWord32ToIntInf
= IntInf
.zextdFromWord32
1386 val zextdFromWord64ToIntInf
= IntInf
.zextdFromWord64
1388 val zextdFromIntInfToInt8
= IntInf
.zextdToInt8
1389 val zextdFromIntInfToInt16
= IntInf
.zextdToInt16
1390 val zextdFromIntInfToInt32
= IntInf
.zextdToInt32
1391 val zextdFromIntInfToInt64
= IntInf
.zextdToInt64
1392 val zextdFromIntInfToIntInf
= IntInf
.zextdToIntInf
1393 val zextdFromIntInfToWord8
= IntInf
.zextdToWord8
1394 val zextdFromIntInfToWord16
= IntInf
.zextdToWord16
1395 val zextdFromIntInfToWord32
= IntInf
.zextdToWord32
1396 val zextdFromIntInfToWord64
= IntInf
.zextdToWord64
1399 val sextdFromInt8ToIntInf
= IntInf
.sextdFromInt8
1400 val sextdFromInt16ToIntInf
= IntInf
.sextdFromInt16
1401 val sextdFromInt32ToIntInf
= IntInf
.sextdFromInt32
1402 val sextdFromInt64ToIntInf
= IntInf
.sextdFromInt64
1403 val sextdFromWord8ToIntInf
= IntInf
.sextdFromWord8
1404 val sextdFromWord16ToIntInf
= IntInf
.sextdFromWord16
1405 val sextdFromWord32ToIntInf
= IntInf
.sextdFromWord32
1406 val sextdFromWord64ToIntInf
= IntInf
.sextdFromWord64
1408 val sextdFromIntInfToInt8
= IntInf
.sextdToInt8
1409 val sextdFromIntInfToInt16
= IntInf
.sextdToInt16
1410 val sextdFromIntInfToInt32
= IntInf
.sextdToInt32
1411 val sextdFromIntInfToInt64
= IntInf
.sextdToInt64
1412 val sextdFromIntInfToIntInf
= IntInf
.sextdToIntInf
1413 val sextdFromIntInfToWord8
= IntInf
.sextdToWord8
1414 val sextdFromIntInfToWord16
= IntInf
.sextdToWord16
1415 val sextdFromIntInfToWord32
= IntInf
.sextdToWord32
1416 val sextdFromIntInfToWord64
= IntInf
.sextdToWord64
1419 val castFromInt8ToIntInf
= IntInf
.castFromInt8
1420 val castFromInt16ToIntInf
= IntInf
.castFromInt16
1421 val castFromInt32ToIntInf
= IntInf
.castFromInt32
1422 val castFromInt64ToIntInf
= IntInf
.castFromInt64
1423 val castFromWord8ToIntInf
= IntInf
.castFromWord8
1424 val castFromWord16ToIntInf
= IntInf
.castFromWord16
1425 val castFromWord32ToIntInf
= IntInf
.castFromWord32
1426 val castFromWord64ToIntInf
= IntInf
.castFromWord64
1428 val castFromIntInfToInt8
= IntInf
.castToInt8
1429 val castFromIntInfToInt16
= IntInf
.castToInt16
1430 val castFromIntInfToInt32
= IntInf
.castToInt32
1431 val castFromIntInfToInt64
= IntInf
.castToInt64
1432 val castFromIntInfToIntInf
= IntInf
.castToIntInf
1433 val castFromIntInfToWord8
= IntInf
.castToWord8
1434 val castFromIntInfToWord16
= IntInf
.castToWord16
1435 val castFromIntInfToWord32
= IntInf
.castToWord32
1436 val castFromIntInfToWord64
= IntInf
.castToWord64
1439 val zchckFromInt8ToIntInf
= IntInf
.zchckFromInt8
1440 val zchckFromInt16ToIntInf
= IntInf
.zchckFromInt16
1441 val zchckFromInt32ToIntInf
= IntInf
.zchckFromInt32
1442 val zchckFromInt64ToIntInf
= IntInf
.zchckFromInt64
1443 val zchckFromWord8ToIntInf
= IntInf
.zchckFromWord8
1444 val zchckFromWord16ToIntInf
= IntInf
.zchckFromWord16
1445 val zchckFromWord32ToIntInf
= IntInf
.zchckFromWord32
1446 val zchckFromWord64ToIntInf
= IntInf
.zchckFromWord64
1448 val zchckFromIntInfToInt8
= IntInf
.zchckToInt8
1449 val zchckFromIntInfToInt16
= IntInf
.zchckToInt16
1450 val zchckFromIntInfToInt32
= IntInf
.zchckToInt32
1451 val zchckFromIntInfToInt64
= IntInf
.zchckToInt64
1452 val zchckFromIntInfToIntInf
= IntInf
.zchckToIntInf
1453 val zchckFromIntInfToWord8
= IntInf
.zchckToWord8
1454 val zchckFromIntInfToWord16
= IntInf
.zchckToWord16
1455 val zchckFromIntInfToWord32
= IntInf
.zchckToWord32
1456 val zchckFromIntInfToWord64
= IntInf
.zchckToWord64
1459 val schckFromInt8ToIntInf
= IntInf
.schckFromInt8
1460 val schckFromInt16ToIntInf
= IntInf
.schckFromInt16
1461 val schckFromInt32ToIntInf
= IntInf
.schckFromInt32
1462 val schckFromInt64ToIntInf
= IntInf
.schckFromInt64
1463 val schckFromWord8ToIntInf
= IntInf
.schckFromWord8
1464 val schckFromWord16ToIntInf
= IntInf
.schckFromWord16
1465 val schckFromWord32ToIntInf
= IntInf
.schckFromWord32
1466 val schckFromWord64ToIntInf
= IntInf
.schckFromWord64
1468 val schckFromIntInfToInt8
= IntInf
.schckToInt8
1469 val schckFromIntInfToInt16
= IntInf
.schckToInt16
1470 val schckFromIntInfToInt32
= IntInf
.schckToInt32
1471 val schckFromIntInfToInt64
= IntInf
.schckToInt64
1472 val schckFromIntInfToIntInf
= IntInf
.schckToIntInf
1473 val schckFromIntInfToWord8
= IntInf
.schckToWord8
1474 val schckFromIntInfToWord16
= IntInf
.schckToWord16
1475 val schckFromIntInfToWord32
= IntInf
.schckToWord32
1476 val schckFromIntInfToWord64
= IntInf
.schckToWord64
1479 structure Int8
: PRIM_INTEGER
=
1483 val zextdFromIntInf
= IntWordConv
.zextdFromIntInfToInt8
1484 val zextdToIntInf
= IntWordConv
.zextdFromInt8ToIntInf
1486 val sextdFromIntInf
= IntWordConv
.sextdFromIntInfToInt8
1487 val sextdToIntInf
= IntWordConv
.sextdFromInt8ToIntInf
1489 val castFromIntInf
= IntWordConv
.castFromIntInfToInt8
1490 val castToIntInf
= IntWordConv
.castFromInt8ToIntInf
1492 val zchckFromIntInf
= IntWordConv
.zchckFromIntInfToInt8
1493 val zchckToIntInf
= IntWordConv
.zchckFromInt8ToIntInf
1495 val schckFromIntInf
= IntWordConv
.schckFromIntInfToInt8
1496 val schckToIntInf
= IntWordConv
.schckFromInt8ToIntInf
1498 structure Int16
: PRIM_INTEGER
=
1502 val zextdFromIntInf
= IntWordConv
.zextdFromIntInfToInt16
1503 val zextdToIntInf
= IntWordConv
.zextdFromInt16ToIntInf
1505 val sextdFromIntInf
= IntWordConv
.sextdFromIntInfToInt16
1506 val sextdToIntInf
= IntWordConv
.sextdFromInt16ToIntInf
1508 val castFromIntInf
= IntWordConv
.castFromIntInfToInt16
1509 val castToIntInf
= IntWordConv
.castFromInt16ToIntInf
1511 val zchckFromIntInf
= IntWordConv
.zchckFromIntInfToInt16
1512 val zchckToIntInf
= IntWordConv
.zchckFromInt16ToIntInf
1514 val schckFromIntInf
= IntWordConv
.schckFromIntInfToInt16
1515 val schckToIntInf
= IntWordConv
.schckFromInt16ToIntInf
1517 structure Int32
: PRIM_INTEGER
=
1521 val zextdFromIntInf
= IntWordConv
.zextdFromIntInfToInt32
1522 val zextdToIntInf
= IntWordConv
.zextdFromInt32ToIntInf
1524 val sextdFromIntInf
= IntWordConv
.sextdFromIntInfToInt32
1525 val sextdToIntInf
= IntWordConv
.sextdFromInt32ToIntInf
1527 val castFromIntInf
= IntWordConv
.castFromIntInfToInt32
1528 val castToIntInf
= IntWordConv
.castFromInt32ToIntInf
1530 val zchckFromIntInf
= IntWordConv
.zchckFromIntInfToInt32
1531 val zchckToIntInf
= IntWordConv
.zchckFromInt32ToIntInf
1533 val schckFromIntInf
= IntWordConv
.schckFromIntInfToInt32
1534 val schckToIntInf
= IntWordConv
.schckFromInt32ToIntInf
1536 structure Int64
: PRIM_INTEGER
=
1540 val zextdFromIntInf
= IntWordConv
.zextdFromIntInfToInt64
1541 val zextdToIntInf
= IntWordConv
.zextdFromInt64ToIntInf
1543 val sextdFromIntInf
= IntWordConv
.sextdFromIntInfToInt64
1544 val sextdToIntInf
= IntWordConv
.sextdFromInt64ToIntInf
1546 val castFromIntInf
= IntWordConv
.castFromIntInfToInt64
1547 val castToIntInf
= IntWordConv
.castFromInt64ToIntInf
1549 val zchckFromIntInf
= IntWordConv
.zchckFromIntInfToInt64
1550 val zchckToIntInf
= IntWordConv
.zchckFromInt64ToIntInf
1552 val schckFromIntInf
= IntWordConv
.schckFromIntInfToInt64
1553 val schckToIntInf
= IntWordConv
.schckFromInt64ToIntInf
1555 structure Word8 : PRIM_WORD
=
1559 val zextdFromIntInf
= IntWordConv
.zextdFromIntInfToWord8
1560 val zextdToIntInf
= IntWordConv
.zextdFromWord8ToIntInf
1562 val sextdFromIntInf
= IntWordConv
.sextdFromIntInfToWord8
1563 val sextdToIntInf
= IntWordConv
.sextdFromWord8ToIntInf
1565 val castFromIntInf
= IntWordConv
.castFromIntInfToWord8
1566 val castToIntInf
= IntWordConv
.castFromWord8ToIntInf
1568 val zchckFromIntInf
= IntWordConv
.zchckFromIntInfToWord8
1569 val zchckToIntInf
= IntWordConv
.zchckFromWord8ToIntInf
1571 val schckFromIntInf
= IntWordConv
.schckFromIntInfToWord8
1572 val schckToIntInf
= IntWordConv
.schckFromWord8ToIntInf
1574 structure Word16
: PRIM_WORD
=
1578 val zextdFromIntInf
= IntWordConv
.zextdFromIntInfToWord16
1579 val zextdToIntInf
= IntWordConv
.zextdFromWord16ToIntInf
1581 val sextdFromIntInf
= IntWordConv
.sextdFromIntInfToWord16
1582 val sextdToIntInf
= IntWordConv
.sextdFromWord16ToIntInf
1584 val castFromIntInf
= IntWordConv
.castFromIntInfToWord16
1585 val castToIntInf
= IntWordConv
.castFromWord16ToIntInf
1587 val zchckFromIntInf
= IntWordConv
.zchckFromIntInfToWord16
1588 val zchckToIntInf
= IntWordConv
.zchckFromWord16ToIntInf
1590 val schckFromIntInf
= IntWordConv
.schckFromIntInfToWord16
1591 val schckToIntInf
= IntWordConv
.schckFromWord16ToIntInf
1593 structure Word32
: PRIM_WORD
=
1597 val zextdFromIntInf
= IntWordConv
.zextdFromIntInfToWord32
1598 val zextdToIntInf
= IntWordConv
.zextdFromWord32ToIntInf
1600 val sextdFromIntInf
= IntWordConv
.sextdFromIntInfToWord32
1601 val sextdToIntInf
= IntWordConv
.sextdFromWord32ToIntInf
1603 val castFromIntInf
= IntWordConv
.castFromIntInfToWord32
1604 val castToIntInf
= IntWordConv
.castFromWord32ToIntInf
1606 val zchckFromIntInf
= IntWordConv
.zchckFromIntInfToWord32
1607 val zchckToIntInf
= IntWordConv
.zchckFromWord32ToIntInf
1609 val schckFromIntInf
= IntWordConv
.schckFromIntInfToWord32
1610 val schckToIntInf
= IntWordConv
.schckFromWord32ToIntInf
1612 structure Word64
: PRIM_WORD
=
1616 val zextdFromIntInf
= IntWordConv
.zextdFromIntInfToWord64
1617 val zextdToIntInf
= IntWordConv
.zextdFromWord64ToIntInf
1619 val sextdFromIntInf
= IntWordConv
.sextdFromIntInfToWord64
1620 val sextdToIntInf
= IntWordConv
.sextdFromWord64ToIntInf
1622 val castFromIntInf
= IntWordConv
.castFromIntInfToWord64
1623 val castToIntInf
= IntWordConv
.castFromWord64ToIntInf
1625 val zchckFromIntInf
= IntWordConv
.zchckFromIntInfToWord64
1626 val zchckToIntInf
= IntWordConv
.zchckFromWord64ToIntInf
1628 val schckFromIntInf
= IntWordConv
.schckFromIntInfToWord64
1629 val schckToIntInf
= IntWordConv
.schckFromWord64ToIntInf
1632 structure IntInf
: PRIM_INT_INF
= IntInf