| ... | ... | @@ -5707,6 +5707,7 @@ fn airShlWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5707 | 5707 | const lhs = try func.resolveInst(extra.lhs); |
| 5708 | 5708 | const rhs = try func.resolveInst(extra.rhs); |
| 5709 | 5709 | const lhs_ty = func.air.typeOf(extra.lhs); |
| 5710 | const rhs_ty = func.air.typeOf(extra.rhs); |
| 5710 | 5711 | |
| 5711 | 5712 | if (lhs_ty.zigTypeTag() == .Vector) { |
| 5712 | 5713 | return func.fail("TODO: Implement overflow arithmetic for vectors", .{}); |
| ... | ... | @@ -5718,7 +5719,15 @@ fn airShlWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5718 | 5719 | return func.fail("TODO: Implement shl_with_overflow for integer bitsize: {d}", .{int_info.bits}); |
| 5719 | 5720 | }; |
| 5720 | 5721 | |
| 5721 | | var shl = try (try func.binOp(lhs, rhs, lhs_ty, .shl)).toLocal(func, lhs_ty); |
| 5722 | // Ensure rhs is coerced to lhs as they must have the same WebAssembly types |
| 5723 | // before we can perform any binary operation. |
| 5724 | const rhs_wasm_bits = toWasmBits(rhs_ty.intInfo(func.target).bits).?; |
| 5725 | const rhs_final = if (wasm_bits != rhs_wasm_bits) blk: { |
| 5726 | const rhs_casted = try func.intcast(rhs, rhs_ty, lhs_ty); |
| 5727 | break :blk try rhs_casted.toLocal(func, lhs_ty); |
| 5728 | } else rhs; |
| 5729 | |
| 5730 | var shl = try (try func.binOp(lhs, rhs_final, lhs_ty, .shl)).toLocal(func, lhs_ty); |
| 5722 | 5731 | defer shl.free(func); |
| 5723 | 5732 | var result = if (wasm_bits != int_info.bits) blk: { |
| 5724 | 5733 | break :blk try (try func.wrapOperand(shl, lhs_ty)).toLocal(func, lhs_ty); |
| ... | ... | @@ -5729,11 +5738,11 @@ fn airShlWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5729 | 5738 | // emit lhs to stack to we can keep 'wrapped' on the stack also |
| 5730 | 5739 | try func.emitWValue(lhs); |
| 5731 | 5740 | const abs = try func.signAbsValue(shl, lhs_ty); |
| 5732 | | const wrapped = try func.wrapBinOp(abs, rhs, lhs_ty, .shr); |
| 5741 | const wrapped = try func.wrapBinOp(abs, rhs_final, lhs_ty, .shr); |
| 5733 | 5742 | break :blk try func.cmp(.{ .stack = {} }, wrapped, lhs_ty, .neq); |
| 5734 | 5743 | } else blk: { |
| 5735 | 5744 | try func.emitWValue(lhs); |
| 5736 | | const shr = try func.binOp(result, rhs, lhs_ty, .shr); |
| 5745 | const shr = try func.binOp(result, rhs_final, lhs_ty, .shr); |
| 5737 | 5746 | break :blk try func.cmp(.{ .stack = {} }, shr, lhs_ty, .neq); |
| 5738 | 5747 | }; |
| 5739 | 5748 | var overflow_local = try overflow_bit.toLocal(func, Type.initTag(.u1)); |