| ... | @@ -141,6 +141,8 @@ const MCValue = union(enum) { | ... | @@ -141,6 +141,8 @@ const MCValue = union(enum) { |
| 141 | /// The value is one of the stack variables. | 141 | /// The value is one of the stack variables. |
| 142 | /// If the type is a pointer, it means the pointer address is in the stack at this offset. | 142 | /// If the type is a pointer, it means the pointer address is in the stack at this offset. |
| 143 | /// Note that this stores the plain value (i.e without the effects of the stack bias). | 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 | stack_offset: u32, | 146 | stack_offset: u32, |
| 145 | /// The value is a pointer to one of the stack variables (payload is stack offset). | 147 | /// The value is a pointer to one of the stack variables (payload is stack offset). |
| 146 | ptr_stack_offset: u32, | 148 | ptr_stack_offset: u32, |
| ... | @@ -3651,7 +3653,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void | ... | @@ -3651,7 +3653,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 3651 | return self.genSetReg(ty, reg, .{ .immediate = 0xaaaaaaaaaaaaaaaa }); | 3653 | return self.genSetReg(ty, reg, .{ .immediate = 0xaaaaaaaaaaaaaaaa }); |
| 3652 | }, | 3654 | }, |
| 3653 | .ptr_stack_offset => |off| { | 3655 | .ptr_stack_offset => |off| { |
| 3654 | const real_offset = off + abi.stack_bias + abi.stack_reserved_area; | 3656 | const real_offset = realStackOffset(off); |
| 3655 | const simm13 = math.cast(i13, real_offset) orelse | 3657 | const simm13 = math.cast(i13, real_offset) orelse |
| 3656 | return self.fail("TODO larger stack offsets: {}", .{real_offset}); | 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,7 +3785,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 3783 | try self.genLoad(reg, reg, i13, 0, ty.abiSize(self.target.*)); | 3785 | try self.genLoad(reg, reg, i13, 0, ty.abiSize(self.target.*)); |
| 3784 | }, | 3786 | }, |
| 3785 | .stack_offset => |off| { | 3787 | .stack_offset => |off| { |
| 3786 | const real_offset = off + abi.stack_bias + abi.stack_reserved_area; | 3788 | const real_offset = realStackOffset(off); |
| 3787 | const simm13 = math.cast(i13, real_offset) orelse | 3789 | const simm13 = math.cast(i13, real_offset) orelse |
| 3788 | return self.fail("TODO larger stack offsets: {}", .{real_offset}); | 3790 | return self.fail("TODO larger stack offsets: {}", .{real_offset}); |
| 3789 | try self.genLoad(reg, .sp, i13, simm13, ty.abiSize(self.target.*)); | 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,7 +3819,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro |
| 3817 | return self.genSetStack(ty, stack_offset, MCValue{ .register = reg }); | 3819 | return self.genSetStack(ty, stack_offset, MCValue{ .register = reg }); |
| 3818 | }, | 3820 | }, |
| 3819 | .register => |reg| { | 3821 | .register => |reg| { |
| 3820 | const real_offset = stack_offset + abi.stack_bias + abi.stack_reserved_area; | 3822 | const real_offset = realStackOffset(stack_offset); |
| 3821 | const simm13 = math.cast(i13, real_offset) orelse | 3823 | const simm13 = math.cast(i13, real_offset) orelse |
| 3822 | return self.fail("TODO larger stack offsets: {}", .{real_offset}); | 3824 | return self.fail("TODO larger stack offsets: {}", .{real_offset}); |
| 3823 | return self.genStore(reg, .sp, i13, simm13, abi_size); | 3825 | return self.genStore(reg, .sp, i13, simm13, abi_size); |
| ... | @@ -4252,6 +4254,17 @@ fn processDeath(self: *Self, inst: Air.Inst.Index) void { | ... | @@ -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 | /// Caller must call `CallMCValues.deinit`. | 4268 | /// Caller must call `CallMCValues.deinit`. |
| 4256 | fn resolveCallingConventionValues(self: *Self, fn_ty: Type, role: RegisterView) !CallMCValues { | 4269 | fn resolveCallingConventionValues(self: *Self, fn_ty: Type, role: RegisterView) !CallMCValues { |
| 4257 | const cc = fn_ty.fnCallingConvention(); | 4270 | const cc = fn_ty.fnCallingConvention(); |