| author | |
| committer | |
| log | 6ec6589bd8d4415d0e78653a0c497981ee69b09d |
| tree | 691ab4268c4b074be606e93b76face3add770b5c |
| parent | c32a060d4fd432002d32ff17a4cf9ae491cddfc0 |
4 files changed, 16 insertions(+), 6 deletions(-)
src/bignum.cpp+12-4| ... | ... | @@ -88,7 +88,10 @@ bool bignum_fits_in_bits(BigNum *bn, int bit_count, bool is_signed) { |
| 88 | 88 | |
| 89 | 89 | void bignum_truncate(BigNum *bn, int bit_count) { |
| 90 | 90 | assert(bn->kind == BigNumKindInt); |
| 91 | bn->data.x_uint &= (1LL << bit_count) - 1; | |
| 91 | // TODO handle case when negative = true | |
| 92 | if (bit_count < 64) { | |
| 93 | bn->data.x_uint &= (1LL << bit_count) - 1; | |
| 94 | } | |
| 92 | 95 | } |
| 93 | 96 | |
| 94 | 97 | uint64_t bignum_to_twos_complement(BigNum *bn) { |
| ... | ... | @@ -142,11 +145,16 @@ void bignum_negate(BigNum *dest, BigNum *op) { |
| 142 | 145 | } |
| 143 | 146 | } |
| 144 | 147 | |
| 145 | void bignum_not(BigNum *dest, BigNum *op, int bit_count) { | |
| 148 | void bignum_not(BigNum *dest, BigNum *op, int bit_count, bool is_signed) { | |
| 146 | 149 | assert(op->kind == BigNumKindInt); |
| 147 | 150 | uint64_t bits = ~bignum_to_twos_complement(op); |
| 148 | bits &= (1LL << bit_count) - 1; | |
| 149 | bignum_init_signed(dest, bits); | |
| 151 | if (bit_count < 64) { | |
| 152 | bits &= (1LL << bit_count) - 1; | |
| 153 | } | |
| 154 | if (is_signed) | |
| 155 | bignum_init_signed(dest, bits); | |
| 156 | else | |
| 157 | bignum_init_unsigned(dest, bits); | |
| 150 | 158 | } |
| 151 | 159 | |
| 152 | 160 | void bignum_cast_to_float(BigNum *dest, BigNum *op) { |
src/bignum.hpp+1-1| ... | ... | @@ -48,7 +48,7 @@ bool bignum_shr(BigNum *dest, BigNum *op1, BigNum *op2); |
| 48 | 48 | void bignum_negate(BigNum *dest, BigNum *op); |
| 49 | 49 | void bignum_cast_to_float(BigNum *dest, BigNum *op); |
| 50 | 50 | void bignum_cast_to_int(BigNum *dest, BigNum *op); |
| 51 | void bignum_not(BigNum *dest, BigNum *op, int bit_count); | |
| 51 | void bignum_not(BigNum *dest, BigNum *op, int bit_count, bool is_signed); | |
| 52 | 52 | |
| 53 | 53 | void bignum_truncate(BigNum *dest, int bit_count); |
| 54 | 54 |
src/ir.cpp+2-1| ... | ... | @@ -7885,7 +7885,8 @@ static TypeTableEntry *ir_analyze_bin_not(IrAnalyze *ira, IrInstructionUnOp *ins |
| 7885 | 7885 | |
| 7886 | 7886 | bool depends_on_compile_var = value->value.depends_on_compile_var; |
| 7887 | 7887 | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base, depends_on_compile_var); |
| 7888 | bignum_not(&out_val->data.x_bignum, &target_const_val->data.x_bignum, expr_type->data.integral.bit_count); | |
| 7888 | bignum_not(&out_val->data.x_bignum, &target_const_val->data.x_bignum, | |
| 7889 | expr_type->data.integral.bit_count, expr_type->data.integral.is_signed); | |
| 7889 | 7890 | return expr_type; |
| 7890 | 7891 | } |
| 7891 | 7892 |
test/cases/math.zig+1| ... | ... | @@ -168,6 +168,7 @@ fn binaryNot() { |
| 168 | 168 | @setFnTest(this); |
| 169 | 169 | |
| 170 | 170 | assert(@staticEval(~u16(0b1010101010101010) == 0b0101010101010101)); |
| 171 | assert(@staticEval(~u64(2147483647) == 18446744071562067968)); | |
| 171 | 172 | testBinaryNot(0b1010101010101010); |
| 172 | 173 | } |
| 173 | 174 |