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 {...@@ -340,16 +340,15 @@ fn gen(self: *Self) !void {
340 if (cc != .Naked) {340 if (cc != .Naked) {
341 // TODO Finish function prologue and epilogue for sparcv9.341 // TODO Finish function prologue and epilogue for sparcv9.
342342
343 // TODO Backpatch stack offset343 // save %sp, stack_save_area, %sp
344 // save %sp, -176, %sp344 const save_inst = try self.addInst(.{
345 _ = try self.addInst(.{
346 .tag = .save,345 .tag = .save,
347 .data = .{346 .data = .{
348 .arithmetic_3op = .{347 .arithmetic_3op = .{
349 .is_imm = true,348 .is_imm = true,
350 .rd = .sp,349 .rd = .sp,
351 .rs1 = .sp,350 .rs1 = .sp,
352 .rs2_or_imm = .{ .imm = -176 },351 .rs2_or_imm = .{ .imm = -abi.stack_save_area },
353 },352 },
354 },353 },
355 });354 });
...@@ -382,6 +381,28 @@ fn gen(self: *Self) !void {...@@ -382,6 +381,28 @@ fn gen(self: *Self) !void {
382 return self.fail("TODO add branches in sparcv9", .{});381 return self.fail("TODO add branches in sparcv9", .{});
383 }382 }
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
385 // return %i7 + 8406 // return %i7 + 8
386 _ = try self.addInst(.{407 _ = try self.addInst(.{
387 .tag = .@"return",408 .tag = .@"return",
...@@ -1367,8 +1388,8 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void...@@ -1367,8 +1388,8 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
1367 try self.genLoad(reg, reg, i13, 0, ty.abiSize(self.target.*));1388 try self.genLoad(reg, reg, i13, 0, ty.abiSize(self.target.*));
1368 },1389 },
1369 .stack_offset => |off| {1390 .stack_offset => |off| {
1370 const biased_offset = off + abi.stack_bias;1391 const real_offset = off + abi.stack_bias + abi.stack_save_area;
1371 const simm13 = math.cast(i13, biased_offset) catch1392 const simm13 = math.cast(i13, real_offset) catch
1372 return self.fail("TODO larger stack offsets", .{});1393 return self.fail("TODO larger stack offsets", .{});
1373 try self.genLoad(reg, .sp, i13, simm13, ty.abiSize(self.target.*));1394 try self.genLoad(reg, .sp, i13, simm13, ty.abiSize(self.target.*));
1374 },1395 },
...@@ -1399,8 +1420,8 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro...@@ -1399,8 +1420,8 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
1399 return self.genSetStack(ty, stack_offset, MCValue{ .register = reg });1420 return self.genSetStack(ty, stack_offset, MCValue{ .register = reg });
1400 },1421 },
1401 .register => |reg| {1422 .register => |reg| {
1402 const biased_offset = stack_offset + abi.stack_bias;1423 const real_offset = stack_offset + abi.stack_bias + abi.stack_save_area;
1403 const simm13 = math.cast(i13, biased_offset) catch1424 const simm13 = math.cast(i13, real_offset) catch
1404 return self.fail("TODO larger stack offsets", .{});1425 return self.fail("TODO larger stack offsets", .{});
1405 return self.genStore(reg, .sp, i13, simm13, abi_size);1426 return self.genStore(reg, .sp, i13, simm13, abi_size);
1406 },1427 },
src/arch/sparcv9/abi.zig+8-1
...@@ -1,11 +1,18 @@...@@ -1,11 +1,18 @@
1const bits = @import("bits.zig");1const bits = @import("bits.zig");
2const Register = bits.Register;2const Register = bits.Register;
33
4// SPARCv9 stack constants.
5// See: Registers and the Stack Frame, page 3P-8, SCD 2.4.1.
6
4// On SPARCv9, %sp points to top of stack + stack bias,7// On SPARCv9, %sp points to top of stack + stack bias,
5// and %fp points to top of previous frame + stack bias.8// and %fp points to top of previous frame + stack bias.
6// See: Registers and the Stack Frame, page 3P-8, SCD 2.4.1.
7pub const stack_bias = 2047;9pub 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
9// There are no callee-preserved registers since the windowing16// There are no callee-preserved registers since the windowing
10// mechanism already takes care of them.17// mechanism already takes care of them.
11// We still need to preserve %o0-%o5, %g1, %g4, and %g5 before calling18// We still need to preserve %o0-%o5, %g1, %g4, and %g5 before calling