| ... | ... | @@ -2153,8 +2153,8 @@ fn binOpBigInt(self: *Self, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerErr |
| 2153 | 2153 | const rhs_high_bit = try self.load(rhs, Type.u64, 0); |
| 2154 | 2154 | const rhs_low_bit = try self.load(rhs, Type.u64, 8); |
| 2155 | 2155 | |
| 2156 | | const low_op_res = try (try self.binOp(lhs_low_bit, rhs_low_bit, Type.u64, op)).toLocal(self, Type.u64); |
| 2157 | 2156 | const high_op_res = try (try self.binOp(lhs_high_bit, rhs_high_bit, Type.u64, op)).toLocal(self, Type.u64); |
| 2157 | const low_op_res = try self.binOp(lhs_low_bit, rhs_low_bit, Type.u64, op); |
| 2158 | 2158 | |
| 2159 | 2159 | const lt = if (op == .add) blk: { |
| 2160 | 2160 | break :blk try self.cmp(high_op_res, rhs_high_bit, Type.u64, .lt); |
| ... | ... | @@ -3190,12 +3190,13 @@ fn airIntcast(self: *Self, inst: Air.Inst.Index) InnerError!WValue { |
| 3190 | 3190 | return self.fail("todo Wasm intcast for bitsize > 128", .{}); |
| 3191 | 3191 | } |
| 3192 | 3192 | |
| 3193 | | return self.intcast(operand, operand_ty, ty); |
| 3193 | return (try self.intcast(operand, operand_ty, ty)).toLocal(self, ty); |
| 3194 | 3194 | } |
| 3195 | 3195 | |
| 3196 | 3196 | /// Upcasts or downcasts an integer based on the given and wanted types, |
| 3197 | 3197 | /// and stores the result in a new operand. |
| 3198 | 3198 | /// Asserts type's bitsize <= 128 |
| 3199 | /// NOTE: May leave the result on the top of the stack. |
| 3199 | 3200 | fn intcast(self: *Self, operand: WValue, given: Type, wanted: Type) InnerError!WValue { |
| 3200 | 3201 | const given_info = given.intInfo(self.target); |
| 3201 | 3202 | const wanted_info = wanted.intInfo(self.target); |
| ... | ... | @@ -3227,7 +3228,7 @@ fn intcast(self: *Self, operand: WValue, given: Type, wanted: Type) InnerError!W |
| 3227 | 3228 | given, |
| 3228 | 3229 | if (wanted.isSignedInt()) Type.i64 else Type.u64, |
| 3229 | 3230 | ); |
| 3230 | | break :blk tmp; |
| 3231 | break :blk try tmp.toLocal(self, Type.u64); |
| 3231 | 3232 | } else operand; |
| 3232 | 3233 | |
| 3233 | 3234 | // store msb first |
| ... | ... | @@ -3244,9 +3245,7 @@ fn intcast(self: *Self, operand: WValue, given: Type, wanted: Type) InnerError!W |
| 3244 | 3245 | return stack_ptr; |
| 3245 | 3246 | } else return self.load(operand, wanted, 0); |
| 3246 | 3247 | |
| 3247 | | const result = try self.allocLocal(wanted); |
| 3248 | | try self.addLabel(.local_set, result.local); |
| 3249 | | return result; |
| 3248 | return WValue{ .stack = {} }; |
| 3250 | 3249 | } |
| 3251 | 3250 | |
| 3252 | 3251 | fn airIsNull(self: *Self, inst: Air.Inst.Index, opcode: wasm.Opcode, op_kind: enum { value, ptr }) InnerError!WValue { |
| ... | ... | @@ -3478,7 +3477,7 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) InnerError!WValue { |
| 3478 | 3477 | if (wasm_bits != wanted_bits) { |
| 3479 | 3478 | return self.wrapOperand(result, wanted_ty); |
| 3480 | 3479 | } |
| 3481 | | return result; |
| 3480 | return result.toLocal(self, wanted_ty); |
| 3482 | 3481 | } |
| 3483 | 3482 | |
| 3484 | 3483 | fn airBoolToInt(self: *Self, inst: Air.Inst.Index) InnerError!WValue { |
| ... | ... | @@ -4387,7 +4386,7 @@ fn airAddSubWithOverflowBigInt(self: *Self, lhs: WValue, rhs: WValue, ty: Type, |
| 4387 | 4386 | } else if (op == .sub) blk: { |
| 4388 | 4387 | break :blk try (try self.cmp(lhs_high_bit, rhs_high_bit, Type.u64, .lt)).toLocal(self, Type.u32); |
| 4389 | 4388 | } else unreachable; |
| 4390 | | const tmp = try self.intcast(lt, Type.u32, Type.u64); |
| 4389 | const tmp = try (try self.intcast(lt, Type.u32, Type.u64)).toLocal(self, Type.u64); |
| 4391 | 4390 | const tmp_op = try (try self.binOp(low_op_res, tmp, Type.u64, op)).toLocal(self, Type.u64); |
| 4392 | 4391 | |
| 4393 | 4392 | const overflow_bit = if (is_signed) blk: { |
| ... | ... | @@ -4500,9 +4499,9 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) InnerError!WValue { |
| 4500 | 4499 | const wrap = try self.intcast(shr, new_ty, lhs_ty); |
| 4501 | 4500 | _ = try self.cmp(wrap, zero, lhs_ty, .neq); |
| 4502 | 4501 | try self.addLabel(.local_set, overflow_bit.local); |
| 4503 | | break :blk try self.intcast(bin_op, new_ty, lhs_ty); |
| 4502 | break :blk try (try self.intcast(bin_op, new_ty, lhs_ty)).toLocal(self, lhs_ty); |
| 4504 | 4503 | } else { |
| 4505 | | const down_cast = try self.intcast(bin_op, new_ty, lhs_ty); |
| 4504 | const down_cast = try (try self.intcast(bin_op, new_ty, lhs_ty)).toLocal(self, lhs_ty); |
| 4506 | 4505 | const shr = try (try self.binOp(down_cast, .{ .imm32 = int_info.bits - 1 }, lhs_ty, .shr)).toLocal(self, lhs_ty); |
| 4507 | 4506 | |
| 4508 | 4507 | const shr_res = try self.binOp(bin_op, .{ .imm64 = int_info.bits }, new_ty, .shr); |