| ... | @@ -2962,7 +2962,7 @@ fn intcast(self: *Self, operand: WValue, given: Type, wanted: Type) InnerError!W | ... | @@ -2962,7 +2962,7 @@ fn intcast(self: *Self, operand: WValue, given: Type, wanted: Type) InnerError!W |
| 2962 | try self.store(stack_ptr, .{ .imm64 = 0 }, Type.u64, 8); | 2962 | try self.store(stack_ptr, .{ .imm64 = 0 }, Type.u64, 8); |
| 2963 | } | 2963 | } |
| 2964 | return stack_ptr; | 2964 | return stack_ptr; |
| 2965 | } else unreachable; | 2965 | } else return self.fail("todo Wasm @intCast to 128bit integers", .{}); |
| 2966 | | 2966 | |
| 2967 | const result = try self.allocLocal(wanted); | 2967 | const result = try self.allocLocal(wanted); |
| 2968 | try self.addLabel(.local_set, result.local); | 2968 | try self.addLabel(.local_set, result.local); |
| ... | @@ -3710,35 +3710,44 @@ fn cmpOptionals(self: *Self, lhs: WValue, rhs: WValue, operand_ty: Type, op: std | ... | @@ -3710,35 +3710,44 @@ fn cmpOptionals(self: *Self, lhs: WValue, rhs: WValue, operand_ty: Type, op: std |
| 3710 | } | 3710 | } |
| 3711 | | 3711 | |
| 3712 | /// Compares big integers by checking both its high bits and low bits. | 3712 | /// Compares big integers by checking both its high bits and low bits. |
| 3713 | /// TODO: Lower this to compiler_rt call | 3713 | /// TODO: Lower this to compiler_rt call when bitsize > 128 |
| 3714 | fn cmpBigInt(self: *Self, lhs: WValue, rhs: WValue, operand_ty: Type, op: std.math.CompareOperator) InnerError!WValue { | 3714 | fn cmpBigInt(self: *Self, lhs: WValue, rhs: WValue, operand_ty: Type, op: std.math.CompareOperator) InnerError!WValue { |
| 3715 | if (operand_ty.intInfo(self.target).bits > 128) { | 3715 | if (operand_ty.intInfo(self.target).bits > 128) { |
| 3716 | return self.fail("TODO: Support cmpBigInt for integer bitsize: '{d}'", .{operand_ty.intInfo(self.target).bits}); | 3716 | return self.fail("TODO: Support cmpBigInt for integer bitsize: '{d}'", .{operand_ty.intInfo(self.target).bits}); |
| 3717 | } | 3717 | } |
| 3718 | | 3718 | |
| 3719 | const result = try self.allocLocal(Type.initTag(.i32)); | 3719 | const lhs_high_bit = try self.load(lhs, Type.u64, 0); |
| 3720 | { | 3720 | const lhs_low_bit = try self.load(lhs, Type.u64, 8); |
| 3721 | try self.startBlock(.block, wasm.block_empty); | 3721 | const rhs_high_bit = try self.load(rhs, Type.u64, 0); |
| 3722 | const lhs_high_bit = try self.load(lhs, Type.u64, 0); | 3722 | const rhs_low_bit = try self.load(rhs, Type.u64, 8); |
| 3723 | const lhs_low_bit = try self.load(lhs, Type.u64, 8); | 3723 | |
| 3724 | const rhs_high_bit = try self.load(rhs, Type.u64, 0); | 3724 | try self.emitWValue(or_result); |
| 3725 | const rhs_low_bit = try self.load(rhs, Type.u64, 8); | 3725 | switch (op) { |
| 3726 | try self.emitWValue(lhs_high_bit); | 3726 | .eq, .neq => { |
| 3727 | try self.emitWValue(rhs_high_bit); | 3727 | const xor_high = try self.binOp(lhs_high_bit, rhs_high_bit, Type.u64, .xor); |
| 3728 | try self.addTag(.i64_ne); | 3728 | const xor_low = try self.binOp(lhs_low_bit, rhs_low_bit, Type.u64, .xor); |
| 3729 | try self.addLabel(.br_if, 0); | 3729 | const or_result = try self.binOp(xor_high, xor_low, Type.u64, .@"or"); |
| 3730 | try self.emitWValue(lhs_low_bit); | 3730 | |
| 3731 | try self.emitWValue(rhs_low_bit); | 3731 | switch (op) { |
| 3732 | try self.addTag(.i64_ne); | 3732 | .eq => try self.addTag(.i64_eqz), |
| 3733 | try self.addLabel(.br_if, 0); | 3733 | .neq => return self.cmp(or_result, .{ .imm32 = 0 }, Type.u32, .neq), |
| 3734 | try self.addImm32(1); | 3734 | else => unreachable, |
| 3735 | try self.addLabel(.local_set, result.local); | 3735 | } |
| 3736 | try self.endBlock(); | 3736 | }, |
| | 3737 | else => { |
| | 3738 | const ty = if (operand_ty.isSignedInt()) Type.i64 else Type.u64; |
| | 3739 | const low_bit_eql = try self.cmp(lhs_low_bit, rhs_low_bit, ty, .eq); |
| | 3740 | const high_bit_cmp = try self.cmp(lhs_high_bit, rhs_high_bit, ty, op); |
| | 3741 | const low_bit_cmp = try self.cmp(lhs_low_bit, rhs_low_bit, ty, op); |
| | 3742 | |
| | 3743 | try self.emitWValue(low_bit_cmp); |
| | 3744 | try self.emitWValue(high_bit_cmp); |
| | 3745 | try self.emitWValue(low_bit_eql); |
| | 3746 | try self.addTag(.select); |
| | 3747 | }, |
| 3737 | } | 3748 | } |
| 3738 | | 3749 | |
| 3739 | try self.emitWValue(result); | 3750 | const result = try self.allocLocal(Type.initTag(.i32)); |
| 3740 | try self.addImm32(0); | | |
| 3741 | try self.addTag(if (op == .eq) .i32_ne else .i32_eq); | | |
| 3742 | try self.addLabel(.local_set, result.local); | 3751 | try self.addLabel(.local_set, result.local); |
| 3743 | return result; | 3752 | return result; |
| 3744 | } | 3753 | } |