| ... | ... | @@ -141,6 +141,8 @@ const MCValue = union(enum) { |
| 141 | 141 | /// The value is one of the stack variables. |
| 142 | 142 | /// If the type is a pointer, it means the pointer address is in the stack at this offset. |
| 143 | 143 | /// Note that this stores the plain value (i.e without the effects of the stack bias). |
| 144 | /// Always convert this value into machine offsets with realStackOffset() before |
| 145 | /// lowering into asm! |
| 144 | 146 | stack_offset: u32, |
| 145 | 147 | /// The value is a pointer to one of the stack variables (payload is stack offset). |
| 146 | 148 | ptr_stack_offset: u32, |
| ... | ... | @@ -3651,7 +3653,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 3651 | 3653 | return self.genSetReg(ty, reg, .{ .immediate = 0xaaaaaaaaaaaaaaaa }); |
| 3652 | 3654 | }, |
| 3653 | 3655 | .ptr_stack_offset => |off| { |
| 3654 | | const real_offset = off + abi.stack_bias + abi.stack_reserved_area; |
| 3656 | const real_offset = realStackOffset(off); |
| 3655 | 3657 | const simm13 = math.cast(i13, real_offset) orelse |
| 3656 | 3658 | return self.fail("TODO larger stack offsets: {}", .{real_offset}); |
| 3657 | 3659 | |
| ... | ... | @@ -3783,7 +3785,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 3783 | 3785 | try self.genLoad(reg, reg, i13, 0, ty.abiSize(self.target.*)); |
| 3784 | 3786 | }, |
| 3785 | 3787 | .stack_offset => |off| { |
| 3786 | | const real_offset = off + abi.stack_bias + abi.stack_reserved_area; |
| 3788 | const real_offset = realStackOffset(off); |
| 3787 | 3789 | const simm13 = math.cast(i13, real_offset) orelse |
| 3788 | 3790 | return self.fail("TODO larger stack offsets: {}", .{real_offset}); |
| 3789 | 3791 | try self.genLoad(reg, .sp, i13, simm13, ty.abiSize(self.target.*)); |
| ... | ... | @@ -3817,7 +3819,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro |
| 3817 | 3819 | return self.genSetStack(ty, stack_offset, MCValue{ .register = reg }); |
| 3818 | 3820 | }, |
| 3819 | 3821 | .register => |reg| { |
| 3820 | | const real_offset = stack_offset + abi.stack_bias + abi.stack_reserved_area; |
| 3822 | const real_offset = realStackOffset(stack_offset); |
| 3821 | 3823 | const simm13 = math.cast(i13, real_offset) orelse |
| 3822 | 3824 | return self.fail("TODO larger stack offsets: {}", .{real_offset}); |
| 3823 | 3825 | return self.genStore(reg, .sp, i13, simm13, abi_size); |
| ... | ... | @@ -4252,6 +4254,17 @@ fn processDeath(self: *Self, inst: Air.Inst.Index) void { |
| 4252 | 4254 | } |
| 4253 | 4255 | } |
| 4254 | 4256 | |
| 4257 | /// Turns stack_offset MCV into a real SPARCv9 stack offset usable for asm. |
| 4258 | fn realStackOffset(off: u32) u32 { |
| 4259 | return off |
| 4260 | // SPARCv9 %sp points away from the stack by some amount. |
| 4261 | + abi.stack_bias |
| 4262 | // The first couple bytes of each stack frame is reserved |
| 4263 | // for ABI and hardware purposes. |
| 4264 | + abi.stack_reserved_area; |
| 4265 | // Only after that we have the usable stack frame portion. |
| 4266 | } |
| 4267 | |
| 4255 | 4268 | /// Caller must call `CallMCValues.deinit`. |
| 4256 | 4269 | fn resolveCallingConventionValues(self: *Self, fn_ty: Type, role: RegisterView) !CallMCValues { |
| 4257 | 4270 | const cc = fn_ty.fnCallingConvention(); |