IR: pass MT19937_64 test

master
Andrew Kelley 2017-01-05 00:59:37 -05:00
parent c32a060d4f
commit 6ec6589bd8
4 changed files with 16 additions and 6 deletions

View File

@ -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) { void bignum_truncate(BigNum *bn, int bit_count) {
assert(bn->kind == BigNumKindInt); 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) { 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); assert(op->kind == BigNumKindInt);
uint64_t bits = ~bignum_to_twos_complement(op); uint64_t bits = ~bignum_to_twos_complement(op);
bits &= (1LL << bit_count) - 1; if (bit_count < 64) {
bignum_init_signed(dest, bits); 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) { void bignum_cast_to_float(BigNum *dest, BigNum *op) {

View File

@ -48,7 +48,7 @@ bool bignum_shr(BigNum *dest, BigNum *op1, BigNum *op2);
void bignum_negate(BigNum *dest, BigNum *op); void bignum_negate(BigNum *dest, BigNum *op);
void bignum_cast_to_float(BigNum *dest, BigNum *op); void bignum_cast_to_float(BigNum *dest, BigNum *op);
void bignum_cast_to_int(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); void bignum_truncate(BigNum *dest, int bit_count);

View File

@ -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; 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); 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; return expr_type;
} }

View File

@ -168,6 +168,7 @@ fn binaryNot() {
@setFnTest(this); @setFnTest(this);
assert(@staticEval(~u16(0b1010101010101010) == 0b0101010101010101)); assert(@staticEval(~u16(0b1010101010101010) == 0b0101010101010101));
assert(@staticEval(~u64(2147483647) == 18446744071562067968));
testBinaryNot(0b1010101010101010); testBinaryNot(0b1010101010101010);
} }