Commit 3923722cc6

Koakuma <koachan@protonmail.com>
2022-05-26 08:24:57
stage2: sparc64: Account for stack bias & reserved area in genSetReg
genSetReg with ptr_stack_offset should add the bias and reserved area before emitting the instruction.
1 parent 5fa9716
Changed files (2)
src
arch
src/arch/sparc64/abi.zig
@@ -3,17 +3,17 @@ const bits = @import("bits.zig");
 const Register = bits.Register;
 const RegisterManagerFn = @import("../../register_manager.zig").RegisterManager;
 
-// SPARCv9 stack constants.
+// SPARCv9 SysV ABI stack constants.
 // See: Registers and the Stack Frame, page 3P-8, SCD 2.4.1.
 
-// On SPARCv9, %sp points to top of stack + stack bias,
-// and %fp points to top of previous frame + stack bias.
+// The ABI specifies that %sp points to top of stack - stack bias,
+// and %fp points to top of previous frame - stack bias.
 pub const stack_bias = 2047;
 
-// The first 176 bytes of the stack is reserved for register saving purposes.
-// SPARCv9 requires to reserve space in the stack for the first six arguments,
-// even though they are usually passed in registers.
-pub const stack_save_area = 176;
+// The first 128 bytes of the stack is reserved for register saving purposes.
+// The ABI also requires to reserve space in the stack for the first six
+// outgoing arguments, even though they are usually passed in registers.
+pub const stack_reserved_area = 128 + 48;
 
 // There are no callee-preserved registers since the windowing
 // mechanism already takes care of them.
src/arch/sparc64/CodeGen.zig
@@ -352,7 +352,7 @@ fn gen(self: *Self) !void {
     if (cc != .Naked) {
         // TODO Finish function prologue and epilogue for sparc64.
 
-        // save %sp, stack_save_area, %sp
+        // save %sp, stack_reserved_area, %sp
         const save_inst = try self.addInst(.{
             .tag = .save,
             .data = .{
@@ -360,7 +360,7 @@ fn gen(self: *Self) !void {
                     .is_imm = true,
                     .rd = .sp,
                     .rs1 = .sp,
-                    .rs2_or_imm = .{ .imm = -abi.stack_save_area },
+                    .rs2_or_imm = .{ .imm = -abi.stack_reserved_area },
                 },
             },
         });
@@ -407,7 +407,7 @@ fn gen(self: *Self) !void {
         }
 
         // Backpatch stack offset
-        const total_stack_size = self.max_end_stack + abi.stack_save_area; // TODO + self.saved_regs_stack_space;
+        const total_stack_size = self.max_end_stack + abi.stack_reserved_area; // TODO + self.saved_regs_stack_space;
         const stack_size = mem.alignForwardGeneric(u32, total_stack_size, self.stack_align);
         if (math.cast(i13, stack_size)) |size| {
             self.mir_instructions.set(save_inst, .{
@@ -2299,7 +2299,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
             return self.genSetReg(ty, reg, .{ .immediate = 0xaaaaaaaaaaaaaaaa });
         },
         .ptr_stack_offset => |off| {
-            const simm13 = math.cast(u12, off) catch
+            const simm13 = math.cast(u12, off + abi.stack_bias + abi.stack_reserved_area) catch
                 return self.fail("TODO larger stack offsets", .{});
 
             _ = try self.addInst(.{
@@ -2431,7 +2431,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
             try self.genLoad(reg, reg, i13, 0, ty.abiSize(self.target.*));
         },
         .stack_offset => |off| {
-            const real_offset = off + abi.stack_bias + abi.stack_save_area;
+            const real_offset = off + abi.stack_bias + abi.stack_reserved_area;
             const simm13 = math.cast(i13, real_offset) catch
                 return self.fail("TODO larger stack offsets", .{});
             try self.genLoad(reg, .sp, i13, simm13, ty.abiSize(self.target.*));
@@ -2465,7 +2465,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
             return self.genSetStack(ty, stack_offset, MCValue{ .register = reg });
         },
         .register => |reg| {
-            const real_offset = stack_offset + abi.stack_bias + abi.stack_save_area;
+            const real_offset = stack_offset + abi.stack_bias + abi.stack_reserved_area;
             const simm13 = math.cast(i13, real_offset) catch
                 return self.fail("TODO larger stack offsets", .{});
             return self.genStore(reg, .sp, i13, simm13, abi_size);