on master help sign in
Get more data from bigint when truncating

Systems with 32-bit longs only got 32 bits even when truncating to 64 bits. Fixes #2967

commitd52a69623f6a76c7bc8f83e63cb737d5c0eaf998 authorNiklas Larsson <niklas@mm.st> dateFri 12 Feb 2016, 03:11 (11 years ago) parent1cf8fe9
3 files changed+17
rts/idris_gmp.c+13 rts/idris_gmp.h+2 src/IRTS/CodegenC.hs+2
rts/idris_gmp.c+13
@@ -488,3 +488,16 @@ VAL idris_castBigStr(VM* vm, VAL i) {
488488 return MKSTR(vm, str);
489489}
490490
491+// Get 64 bits out of a big int with special handling
492+// for systems that have 32-bit longs which needs two limbs to
493+// fill that.
494+uint64_t idris_truncBigB64(const mpz_t bi) {
495+ if (sizeof(mp_limb_t) == 8) {
496+ return mpz_get_ui(bi);
497+ }
498+ int64_t out = mpz_get_ui(bi);
499+ if (bi->_mp_size > 1 ) {
500+ out |= (uint64_t)bi->_mp_d[1] << 32;
501+ }
502+ return out;
503+}
rts/idris_gmp.h+2
@@ -43,6 +43,8 @@ VAL idris_bigOr(VM* vm, VAL x, VAL y);
4343VAL idris_bigShiftLeft(VM* vm, VAL x, VAL y);
4444VAL idris_bigShiftRight(VM* vm, VAL x, VAL y);
4545
46+uint64_t idris_truncBigB64(const mpz_t bi);
47+
4648#define GETMPZ(x) *((mpz_t*)((x)->info.ptr))
4749
4850#endif
src/IRTS/CodegenC.hs+2
@@ -557,6 +557,8 @@ doOp v (LTrunc (ITFixed from) ITNative) [x]
557557 = v ++ "MKINT((i_int)" ++ creg x ++ "->info.bits" ++ show (nativeTyWidth from) ++ ")"
558558doOp v (LTrunc (ITFixed from) ITChar) [x]
559559 = doOp v (LTrunc (ITFixed from) ITNative) [x]
560+doOp v (LTrunc ITBig (ITFixed IT64)) [x]
561+ = v ++ "idris_b64const(vm, ISINT(" ++ creg x ++ ") ? GETINT(" ++ creg x ++ ") : idris_truncBigB64(GETMPZ(" ++ creg x ++ ")))"
560562doOp v (LTrunc ITBig (ITFixed to)) [x]
561563 = v ++ "idris_b" ++ show (nativeTyWidth to) ++ "const(vm, ISINT(" ++ creg x ++ ") ? GETINT(" ++ creg x ++ ") : mpz_get_ui(GETMPZ(" ++ creg x ++ ")))"
562564doOp v (LTrunc (ITFixed from) (ITFixed to)) [x]