diff options
| author | Koakuma <koachan@protonmail.com> | 2022-04-21 06:02:53 +0700 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2022-05-05 19:34:04 +0200 |
| commit | f6bf3dd78c7bbb139e64ddfa05995f3896366d77 (patch) | |
| tree | 59161c9d3064ea198486a00c11b85df2f4e9fce9 | |
| parent | e03ec51b4b47c6730462bed3f8d703767a7b33d9 (diff) | |
| download | zig-f6bf3dd78c7bbb139e64ddfa05995f3896366d77.tar.gz zig-f6bf3dd78c7bbb139e64ddfa05995f3896366d77.zip | |
stage2: sparcv9: Fix stack space accounting
| -rw-r--r-- | src/arch/sparcv9/CodeGen.zig | 37 | ||||
| -rw-r--r-- | src/arch/sparcv9/abi.zig | 9 |
2 files changed, 37 insertions, 9 deletions
diff --git a/src/arch/sparcv9/CodeGen.zig b/src/arch/sparcv9/CodeGen.zig index 240b7e3a55..3715c56558 100644 --- a/src/arch/sparcv9/CodeGen.zig +++ b/src/arch/sparcv9/CodeGen.zig @@ -340,16 +340,15 @@ fn gen(self: *Self) !void { if (cc != .Naked) { // TODO Finish function prologue and epilogue for sparcv9. - // TODO Backpatch stack offset - // save %sp, -176, %sp - _ = try self.addInst(.{ + // save %sp, stack_save_area, %sp + const save_inst = try self.addInst(.{ .tag = .save, .data = .{ .arithmetic_3op = .{ .is_imm = true, .rd = .sp, .rs1 = .sp, - .rs2_or_imm = .{ .imm = -176 }, + .rs2_or_imm = .{ .imm = -abi.stack_save_area }, }, }, }); @@ -382,6 +381,28 @@ fn gen(self: *Self) !void { return self.fail("TODO add branches in sparcv9", .{}); } + // Backpatch stack offset + const total_stack_size = self.max_end_stack + abi.stack_save_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, .{ + .tag = .save, + .data = .{ + .arithmetic_3op = .{ + .is_imm = true, + .rd = .sp, + .rs1 = .sp, + .rs2_or_imm = .{ .imm = -size }, + }, + }, + }); + } else |_| { + // TODO for large stacks, replace the prologue with: + // setx stack_size, %g1 + // save %sp, %g1, %sp + return self.fail("TODO SPARCv9: allow larger stacks", .{}); + } + // return %i7 + 8 _ = try self.addInst(.{ .tag = .@"return", @@ -1367,8 +1388,8 @@ 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 biased_offset = off + abi.stack_bias; - const simm13 = math.cast(i13, biased_offset) catch + const real_offset = off + abi.stack_bias + abi.stack_save_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.*)); }, @@ -1399,8 +1420,8 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro return self.genSetStack(ty, stack_offset, MCValue{ .register = reg }); }, .register => |reg| { - const biased_offset = stack_offset + abi.stack_bias; - const simm13 = math.cast(i13, biased_offset) catch + const real_offset = stack_offset + abi.stack_bias + abi.stack_save_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/sparcv9/abi.zig b/src/arch/sparcv9/abi.zig index ae72f270be..a9001c7dc7 100644 --- a/src/arch/sparcv9/abi.zig +++ b/src/arch/sparcv9/abi.zig @@ -1,11 +1,18 @@ const bits = @import("bits.zig"); const Register = bits.Register; +// SPARCv9 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. -// See: Registers and the Stack Frame, page 3P-8, SCD 2.4.1. 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; + // There are no callee-preserved registers since the windowing // mechanism already takes care of them. // We still need to preserve %o0-%o5, %g1, %g4, and %g5 before calling |
