diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2017-01-05 00:59:37 -0500 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2017-01-05 00:59:37 -0500 |
| commit | 6ec6589bd8d4415d0e78653a0c497981ee69b09d (patch) | |
| tree | 691ab4268c4b074be606e93b76face3add770b5c | |
| parent | c32a060d4fd432002d32ff17a4cf9ae491cddfc0 (diff) | |
| download | zig-6ec6589bd8d4415d0e78653a0c497981ee69b09d.tar.gz zig-6ec6589bd8d4415d0e78653a0c497981ee69b09d.zip | |
IR: pass MT19937_64 test
| -rw-r--r-- | src/bignum.cpp | 16 | ||||
| -rw-r--r-- | src/bignum.hpp | 2 | ||||
| -rw-r--r-- | src/ir.cpp | 3 | ||||
| -rw-r--r-- | test/cases/math.zig | 1 |
4 files changed, 16 insertions, 6 deletions
diff --git a/src/bignum.cpp b/src/bignum.cpp index 192c16e636..e3b661e81a 100644 --- a/src/bignum.cpp +++ b/src/bignum.cpp @@ -88,7 +88,10 @@ bool bignum_fits_in_bits(BigNum *bn, int bit_count, bool is_signed) { void bignum_truncate(BigNum *bn, int bit_count) { assert(bn->kind == BigNumKindInt); - bn->data.x_uint &= (1LL << bit_count) - 1; + // TODO handle case when negative = true + if (bit_count < 64) { + bn->data.x_uint &= (1LL << bit_count) - 1; + } } uint64_t bignum_to_twos_complement(BigNum *bn) { @@ -142,11 +145,16 @@ void bignum_negate(BigNum *dest, BigNum *op) { } } -void bignum_not(BigNum *dest, BigNum *op, int bit_count) { +void bignum_not(BigNum *dest, BigNum *op, int bit_count, bool is_signed) { assert(op->kind == BigNumKindInt); uint64_t bits = ~bignum_to_twos_complement(op); - bits &= (1LL << bit_count) - 1; - bignum_init_signed(dest, bits); + if (bit_count < 64) { + bits &= (1LL << bit_count) - 1; + } + if (is_signed) + bignum_init_signed(dest, bits); + else + bignum_init_unsigned(dest, bits); } void bignum_cast_to_float(BigNum *dest, BigNum *op) { diff --git a/src/bignum.hpp b/src/bignum.hpp index f028b36bef..935ffda74f 100644 --- a/src/bignum.hpp +++ b/src/bignum.hpp @@ -48,7 +48,7 @@ bool bignum_shr(BigNum *dest, BigNum *op1, BigNum *op2); void bignum_negate(BigNum *dest, BigNum *op); void bignum_cast_to_float(BigNum *dest, BigNum *op); void bignum_cast_to_int(BigNum *dest, BigNum *op); -void bignum_not(BigNum *dest, BigNum *op, int bit_count); +void bignum_not(BigNum *dest, BigNum *op, int bit_count, bool is_signed); void bignum_truncate(BigNum *dest, int bit_count); diff --git a/src/ir.cpp b/src/ir.cpp index 58f6a2c07d..eb90a52a3a 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -7885,7 +7885,8 @@ static TypeTableEntry *ir_analyze_bin_not(IrAnalyze *ira, IrInstructionUnOp *ins bool depends_on_compile_var = value->value.depends_on_compile_var; ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base, depends_on_compile_var); - bignum_not(&out_val->data.x_bignum, &target_const_val->data.x_bignum, expr_type->data.integral.bit_count); + bignum_not(&out_val->data.x_bignum, &target_const_val->data.x_bignum, + expr_type->data.integral.bit_count, expr_type->data.integral.is_signed); return expr_type; } diff --git a/test/cases/math.zig b/test/cases/math.zig index 3aab135ec0..187c971a00 100644 --- a/test/cases/math.zig +++ b/test/cases/math.zig @@ -168,6 +168,7 @@ fn binaryNot() { @setFnTest(this); assert(@staticEval(~u16(0b1010101010101010) == 0b0101010101010101)); + assert(@staticEval(~u64(2147483647) == 18446744071562067968)); testBinaryNot(0b1010101010101010); } |
