diff --git a/src/exact_value.cpp b/src/exact_value.cpp index b3d4e9f4f..ff740a057 100644 --- a/src/exact_value.cpp +++ b/src/exact_value.cpp @@ -317,7 +317,7 @@ ExactValue exact_unary_operator_value(TokenKind op, ExactValue v, i32 precision) return v; case ExactValue_Integer: { ExactValue i = v; - i.value_integer = i128_neg(i.value_integer); + i.value_integer = -i.value_integer; return i; } case ExactValue_Float: { @@ -339,7 +339,7 @@ ExactValue exact_unary_operator_value(TokenKind op, ExactValue v, i32 precision) case ExactValue_Invalid: return v; case ExactValue_Integer: - i = i128_not(v.value_integer); + i = ~v.value_integer; break; default: goto failure; @@ -349,7 +349,7 @@ ExactValue exact_unary_operator_value(TokenKind op, ExactValue v, i32 precision) // limited to the types precision // IMPORTANT NOTE(bill): Max precision is 64 bits as that's how integers are stored if (0 < precision && precision < 128) { - i = i128_and(i, i128_not(i128_shl(I128_NEG_ONE, precision))); + i = i & ~(I128_NEG_ONE << precision); } return exact_value_i128(i); @@ -461,19 +461,19 @@ ExactValue exact_binary_operator_value(TokenKind op, ExactValue x, ExactValue y) i128 b = y.value_integer; i128 c = I128_ZERO; switch (op) { - case Token_Add: c = i128_add(a, b); break; - case Token_Sub: c = i128_sub(a, b); break; - case Token_Mul: c = i128_mul(a, b); break; + case Token_Add: c = a + b; break; + case Token_Sub: c = a - b; break; + case Token_Mul: c = a * b; break; case Token_Quo: return exact_value_float(fmod(i128_to_f64(a), i128_to_f64(b))); - case Token_QuoEq: c = i128_quo(a, b); break; // NOTE(bill): Integer division - case Token_Mod: c = i128_mod(a, b); break; - case Token_ModMod: c = i128_mod(i128_add(i128_mod(a, b), b), b); break; - case Token_And: c = i128_and (a, b); break; - case Token_Or: c = i128_or (a, b); break; - case Token_Xor: c = i128_xor (a, b); break; - case Token_AndNot: c = i128_and_not(a, b); break; - case Token_Shl: c = i128_shl (a, i128_to_u64(b)); break; - case Token_Shr: c = i128_shr (a, i128_to_u64(b)); break; + case Token_QuoEq: c = a / b; break; // NOTE(bill): Integer division + case Token_Mod: c = a % b; break; + case Token_ModMod: c = ((a % b) + b) % b; break; + case Token_And: c = a & b; break; + case Token_Or: c = a | b; break; + case Token_Xor: c = a ^ b; break; + case Token_AndNot: c = i128_and_not(a, b); break; + case Token_Shl: c = a << i128_to_u64(b); break; + case Token_Shr: c = a >> i128_to_u64(b); break; default: goto error; } @@ -560,12 +560,12 @@ bool compare_exact_values(TokenKind op, ExactValue x, ExactValue y) { i128 a = x.value_integer; i128 b = y.value_integer; switch (op) { - case Token_CmpEq: return i128_eq(a, b); - case Token_NotEq: return i128_ne(a, b); - case Token_Lt: return i128_lt(a, b); - case Token_LtEq: return i128_le(a, b); - case Token_Gt: return i128_gt(a, b); - case Token_GtEq: return i128_ge(a, b); + case Token_CmpEq: return a == b; + case Token_NotEq: return a != b; + case Token_Lt: return a < b; + case Token_LtEq: return a <= b; + case Token_Gt: return a > b; + case Token_GtEq: return a >= b; } } break; @@ -596,15 +596,14 @@ bool compare_exact_values(TokenKind op, ExactValue x, ExactValue y) { case ExactValue_String: { String a = x.value_string; String b = y.value_string; - isize len = gb_min(a.len, b.len); // TODO(bill): gb_memcompare is used because the strings are UTF-8 switch (op) { - case Token_CmpEq: return gb_memcompare(a.text, b.text, len) == 0; - case Token_NotEq: return gb_memcompare(a.text, b.text, len) != 0; - case Token_Lt: return gb_memcompare(a.text, b.text, len) < 0; - case Token_LtEq: return gb_memcompare(a.text, b.text, len) <= 0; - case Token_Gt: return gb_memcompare(a.text, b.text, len) > 0; - case Token_GtEq: return gb_memcompare(a.text, b.text, len) >= 0; + case Token_CmpEq: return a == b; + case Token_NotEq: return a != b; + case Token_Lt: return a < b; + case Token_LtEq: return a <= b; + case Token_Gt: return a > b; + case Token_GtEq: return a >= b; } } break; } diff --git a/src/integer128.cpp b/src/integer128.cpp index 39d834ab3..73cd1c7a0 100644 --- a/src/integer128.cpp +++ b/src/integer128.cpp @@ -1,10 +1,12 @@ -typedef struct u128 {u64 lo; u64 hi;} u128; -typedef struct i128 {u64 lo; i64 hi;} i128; - #define BIT128_U64_HIGHBIT 0x8000000000000000ull #define BIT128_U64_BITS62 0x7fffffffffffffffull #define BIT128_U64_ALLBITS 0xffffffffffffffffull + +typedef struct u128 { u64 lo; u64 hi; } u128; +typedef struct i128 { u64 lo; i64 hi; } i128; + + static u128 const U128_ZERO = {0, 0}; static u128 const U128_ONE = {1, 0}; static i128 const I128_ZERO = {0, 0}; @@ -84,6 +86,48 @@ void i128_divide (i128 num, i128 den, i128 *quo, i128 *rem); i128 i128_quo (i128 a, i128 b); i128 i128_mod (i128 a, i128 b); +bool operator==(u128 a, u128 b) { return u128_eq(a, b); } +bool operator!=(u128 a, u128 b) { return u128_ne(a, b); } +bool operator< (u128 a, u128 b) { return u128_lt(a, b); } +bool operator> (u128 a, u128 b) { return u128_gt(a, b); } +bool operator<=(u128 a, u128 b) { return u128_le(a, b); } +bool operator>=(u128 a, u128 b) { return u128_ge(a, b); } + +u128 operator+(u128 a, u128 b) { return u128_add(a, b); } +u128 operator-(u128 a, u128 b) { return u128_sub(a, b); } +u128 operator*(u128 a, u128 b) { return u128_mul(a, b); } +u128 operator/(u128 a, u128 b) { return u128_quo(a, b); } +u128 operator%(u128 a, u128 b) { return u128_mod(a, b); } +u128 operator&(u128 a, u128 b) { return u128_and(a, b); } +u128 operator|(u128 a, u128 b) { return u128_or (a, b); } +u128 operator^(u128 a, u128 b) { return u128_xor(a, b); } +u128 operator~(u128 a) { return u128_not(a); } +u128 operator+(u128 a) { return a; } +u128 operator-(u128 a) { return u128_neg(a); } +u128 operator<<(u128 a, u32 b) { return u128_shl(a, b); } +u128 operator>>(u128 a, u32 b) { return u128_shr(a, b); } + + +bool operator==(i128 a, i128 b) { return i128_eq(a, b); } +bool operator!=(i128 a, i128 b) { return i128_ne(a, b); } +bool operator< (i128 a, i128 b) { return i128_lt(a, b); } +bool operator> (i128 a, i128 b) { return i128_gt(a, b); } +bool operator<=(i128 a, i128 b) { return i128_le(a, b); } +bool operator>=(i128 a, i128 b) { return i128_ge(a, b); } + +i128 operator+(i128 a, i128 b) { return i128_add(a, b); } +i128 operator-(i128 a, i128 b) { return i128_sub(a, b); } +i128 operator*(i128 a, i128 b) { return i128_mul(a, b); } +i128 operator/(i128 a, i128 b) { return i128_quo(a, b); } +i128 operator%(i128 a, i128 b) { return i128_mod(a, b); } +i128 operator&(i128 a, i128 b) { return i128_and(a, b); } +i128 operator|(i128 a, i128 b) { return i128_or (a, b); } +i128 operator^(i128 a, i128 b) { return i128_xor(a, b); } +i128 operator~(i128 a) { return i128_not(a); } +i128 operator+(i128 a) { return a; } +i128 operator-(i128 a) { return i128_neg(a); } +i128 operator<<(i128 a, u32 b) { return i128_shl(a, b); } +i128 operator>>(i128 a, u32 b) { return i128_shr(a, b); } //////////////////////////////////////////////////////////////// diff --git a/src/ir.cpp b/src/ir.cpp index e94f84e3b..bcea8a515 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -1902,12 +1902,14 @@ irValue *ir_addr_load(irProcedure *proc, irAddr addr) { return v; } + GB_ASSERT(8 > bit_inset); + irValue *shift_amount = ir_value_constant(a, int_type, exact_value_i64(bit_inset)); irValue *first_byte = ir_emit_load(proc, bytes); - irValue *res = ir_emit_arith(proc, Token_Shr, first_byte, ir_const_int(a, 8 - bit_inset), int_type); + irValue *res = ir_emit_arith(proc, Token_Shr, first_byte, shift_amount, int_type); irValue *remaining_bytes = ir_emit_load(proc, ir_emit_conv(proc, ir_emit_ptr_offset(proc, bytes, v_one), int_ptr)); - remaining_bytes = ir_emit_arith(proc, Token_Shl, remaining_bytes, ir_const_int(a, bit_inset), int_type); + remaining_bytes = ir_emit_arith(proc, Token_Shl, remaining_bytes, shift_amount, int_type); return ir_emit_arith(proc, Token_Or, res, remaining_bytes, int_type); }