From 3923722cc617251de91d5bc9a5d4f9c0ca93ee1a Mon Sep 17 00:00:00 2001 From: Koakuma Date: Thu, 26 May 2022 13:24:57 +0700 Subject: [PATCH] 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. --- src/arch/sparc64/CodeGen.zig | 12 ++++++------ src/arch/sparc64/abi.zig | 14 +++++++------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/arch/sparc64/CodeGen.zig b/src/arch/sparc64/CodeGen.zig index 228691721d..bf08e9a309 100644 --- a/src/arch/sparc64/CodeGen.zig +++ b/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); diff --git a/src/arch/sparc64/abi.zig b/src/arch/sparc64/abi.zig index 1c6d40941f..99f83eee7b 100644 --- a/src/arch/sparc64/abi.zig +++ b/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.