| 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,7 +88,10 @@ bool bignum_fits_in_bits(BigNum *bn, int bit_count, bool is_signed) { |
| 88 | 88 | ||
| 89 | void bignum_truncate(BigNum *bn, int bit_count) { | 89 | void bignum_truncate(BigNum *bn, int bit_count) { |
| 90 | assert(bn->kind == BigNumKindInt); | 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 | uint64_t bignum_to_twos_complement(BigNum *bn) { | 97 | uint64_t bignum_to_twos_complement(BigNum *bn) { |
| ... | @@ -142,11 +145,16 @@ void bignum_negate(BigNum *dest, BigNum *op) { | ... | @@ -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 | assert(op->kind == BigNumKindInt); | 149 | assert(op->kind == BigNumKindInt); |
| 147 | uint64_t bits = ~bignum_to_twos_complement(op); | 150 | uint64_t bits = ~bignum_to_twos_complement(op); |
| 148 | bits &= (1LL << bit_count) - 1; | 151 | if (bit_count < 64) { |
| 149 | bignum_init_signed(dest, bits); | 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 | void bignum_cast_to_float(BigNum *dest, BigNum *op) { | 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,7 +48,7 @@ bool bignum_shr(BigNum *dest, BigNum *op1, BigNum *op2); |
| 48 | void bignum_negate(BigNum *dest, BigNum *op); | 48 | void bignum_negate(BigNum *dest, BigNum *op); |
| 49 | void bignum_cast_to_float(BigNum *dest, BigNum *op); | 49 | void bignum_cast_to_float(BigNum *dest, BigNum *op); |
| 50 | void bignum_cast_to_int(BigNum *dest, BigNum *op); | 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 | void bignum_truncate(BigNum *dest, int bit_count); | 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,7 +7885,8 @@ static TypeTableEntry *ir_analyze_bin_not(IrAnalyze *ira, IrInstructionUnOp *ins |
| 7885 | 7885 | ||
| 7886 | bool depends_on_compile_var = value->value.depends_on_compile_var; | 7886 | bool depends_on_compile_var = value->value.depends_on_compile_var; |
| 7887 | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base, depends_on_compile_var); | 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 | return expr_type; | 7890 | return expr_type; |
| 7890 | } | 7891 | } |
| 7891 | 7892 |
test/cases/math.zig+1| ... | @@ -168,6 +168,7 @@ fn binaryNot() { | ... | @@ -168,6 +168,7 @@ fn binaryNot() { |
| 168 | @setFnTest(this); | 168 | @setFnTest(this); |
| 169 | 169 | ||
| 170 | assert(@staticEval(~u16(0b1010101010101010) == 0b0101010101010101)); | 170 | assert(@staticEval(~u16(0b1010101010101010) == 0b0101010101010101)); |
| 171 | assert(@staticEval(~u64(2147483647) == 18446744071562067968)); | ||
| 171 | testBinaryNot(0b1010101010101010); | 172 | testBinaryNot(0b1010101010101010); |
| 172 | } | 173 | } |
| 173 | 174 |