| ... | @@ -3715,15 +3715,54 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerErro | ... | @@ -3715,15 +3715,54 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerErro |
| 3715 | if (stack_offset > math.maxInt(i32)) { | 3715 | if (stack_offset > math.maxInt(i32)) { |
| 3716 | return self.fail("stack offset too large", .{}); | 3716 | return self.fail("stack offset too large", .{}); |
| 3717 | } | 3717 | } |
| 3718 | _ = try self.addInst(.{ | 3718 | |
| 3719 | .tag = .mov, | 3719 | const is_power_of_two = (abi_size % 2) == 0; |
| 3720 | .ops = (Mir.Ops{ | 3720 | if (!is_power_of_two) { |
| 3721 | .reg1 = .rbp, | 3721 | self.register_manager.freezeRegs(&.{reg}); |
| 3722 | .reg2 = registerAlias(reg, @intCast(u32, abi_size)), | 3722 | defer self.register_manager.unfreezeRegs(&.{reg}); |
| 3723 | .flags = 0b10, | 3723 | |
| 3724 | }).encode(), | 3724 | const tmp_reg = try self.copyToTmpRegister(ty, mcv); |
| 3725 | .data = .{ .imm = @bitCast(u32, -stack_offset) }, | 3725 | |
| 3726 | }); | 3726 | var next_offset = stack_offset; |
| | 3727 | var remainder = abi_size; |
| | 3728 | while (remainder > 0) { |
| | 3729 | const closest_power_of_two = @as(u6, 1) << @intCast(u3, math.log2(remainder)); |
| | 3730 | |
| | 3731 | _ = try self.addInst(.{ |
| | 3732 | .tag = .mov, |
| | 3733 | .ops = (Mir.Ops{ |
| | 3734 | .reg1 = .rbp, |
| | 3735 | .reg2 = registerAlias(tmp_reg, closest_power_of_two), |
| | 3736 | .flags = 0b10, |
| | 3737 | }).encode(), |
| | 3738 | .data = .{ .imm = @bitCast(u32, -next_offset) }, |
| | 3739 | }); |
| | 3740 | |
| | 3741 | if (closest_power_of_two > 1) { |
| | 3742 | _ = try self.addInst(.{ |
| | 3743 | .tag = .shr, |
| | 3744 | .ops = (Mir.Ops{ |
| | 3745 | .reg1 = tmp_reg, |
| | 3746 | .flags = 0b10, |
| | 3747 | }).encode(), |
| | 3748 | .data = .{ .imm = closest_power_of_two * 8 }, |
| | 3749 | }); |
| | 3750 | } |
| | 3751 | |
| | 3752 | remainder -= closest_power_of_two; |
| | 3753 | next_offset -= closest_power_of_two; |
| | 3754 | } |
| | 3755 | } else { |
| | 3756 | _ = try self.addInst(.{ |
| | 3757 | .tag = .mov, |
| | 3758 | .ops = (Mir.Ops{ |
| | 3759 | .reg1 = .rbp, |
| | 3760 | .reg2 = registerAlias(reg, @intCast(u32, abi_size)), |
| | 3761 | .flags = 0b10, |
| | 3762 | }).encode(), |
| | 3763 | .data = .{ .imm = @bitCast(u32, -stack_offset) }, |
| | 3764 | }); |
| | 3765 | } |
| 3727 | }, | 3766 | }, |
| 3728 | .memory, | 3767 | .memory, |
| 3729 | .embedded_in_code, | 3768 | .embedded_in_code, |