authorgravatar for koachan@protonmail.comKoakuma <koachan@protonmail.com> 2022-04-21 06:02:53+07:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-05-05 19:34:04+02:00
logf6bf3dd78c7bbb139e64ddfa05995f3896366d77
tree59161c9d3064ea198486a00c11b85df2f4e9fce9
parente03ec51b4b47c6730462bed3f8d703767a7b33d9

stage2: sparcv9: Fix stack space accounting


2 files changed, 37 insertions(+), 9 deletions(-)

src/arch/sparcv9/CodeGen.zig+29-8
......@@ -340,16 +340,15 @@ fn gen(self: *Self) !void {
340340 if (cc != .Naked) {
341341 // TODO Finish function prologue and epilogue for sparcv9.
342342
343 // TODO Backpatch stack offset
344 // save %sp, -176, %sp
345 _ = try self.addInst(.{
343 // save %sp, stack_save_area, %sp
344 const save_inst = try self.addInst(.{
346345 .tag = .save,
347346 .data = .{
348347 .arithmetic_3op = .{
349348 .is_imm = true,
350349 .rd = .sp,
351350 .rs1 = .sp,
352 .rs2_or_imm = .{ .imm = -176 },
351 .rs2_or_imm = .{ .imm = -abi.stack_save_area },
353352 },
354353 },
355354 });
......@@ -382,6 +381,28 @@ fn gen(self: *Self) !void {
382381 return self.fail("TODO add branches in sparcv9", .{});
383382 }
384383
384 // Backpatch stack offset
385 const total_stack_size = self.max_end_stack + abi.stack_save_area; // TODO + self.saved_regs_stack_space;
386 const stack_size = mem.alignForwardGeneric(u32, total_stack_size, self.stack_align);
387 if (math.cast(i13, stack_size)) |size| {
388 self.mir_instructions.set(save_inst, .{
389 .tag = .save,
390 .data = .{
391 .arithmetic_3op = .{
392 .is_imm = true,
393 .rd = .sp,
394 .rs1 = .sp,
395 .rs2_or_imm = .{ .imm = -size },
396 },
397 },
398 });
399 } else |_| {
400 // TODO for large stacks, replace the prologue with:
401 // setx stack_size, %g1
402 // save %sp, %g1, %sp
403 return self.fail("TODO SPARCv9: allow larger stacks", .{});
404 }
405
385406 // return %i7 + 8
386407 _ = try self.addInst(.{
387408 .tag = .@"return",
......@@ -1367,8 +1388,8 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
13671388 try self.genLoad(reg, reg, i13, 0, ty.abiSize(self.target.*));
13681389 },
13691390 .stack_offset => |off| {
1370 const biased_offset = off + abi.stack_bias;
1371 const simm13 = math.cast(i13, biased_offset) catch
1391 const real_offset = off + abi.stack_bias + abi.stack_save_area;
1392 const simm13 = math.cast(i13, real_offset) catch
13721393 return self.fail("TODO larger stack offsets", .{});
13731394 try self.genLoad(reg, .sp, i13, simm13, ty.abiSize(self.target.*));
13741395 },
......@@ -1399,8 +1420,8 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
13991420 return self.genSetStack(ty, stack_offset, MCValue{ .register = reg });
14001421 },
14011422 .register => |reg| {
1402 const biased_offset = stack_offset + abi.stack_bias;
1403 const simm13 = math.cast(i13, biased_offset) catch
1423 const real_offset = stack_offset + abi.stack_bias + abi.stack_save_area;
1424 const simm13 = math.cast(i13, real_offset) catch
14041425 return self.fail("TODO larger stack offsets", .{});
14051426 return self.genStore(reg, .sp, i13, simm13, abi_size);
14061427 },
src/arch/sparcv9/abi.zig+8-1
......@@ -1,11 +1,18 @@
11const bits = @import("bits.zig");
22const Register = bits.Register;
33
4// SPARCv9 stack constants.
5// See: Registers and the Stack Frame, page 3P-8, SCD 2.4.1.
6
47// On SPARCv9, %sp points to top of stack + stack bias,
58// and %fp points to top of previous frame + stack bias.
6// See: Registers and the Stack Frame, page 3P-8, SCD 2.4.1.
79pub const stack_bias = 2047;
810
11// The first 176 bytes of the stack is reserved for register saving purposes.
12// SPARCv9 requires to reserve space in the stack for the first six arguments,
13// even though they are usually passed in registers.
14pub const stack_save_area = 176;
15
916// There are no callee-preserved registers since the windowing
1017// mechanism already takes care of them.
1118// We still need to preserve %o0-%o5, %g1, %g4, and %g5 before calling