aboutsummaryrefslogtreecommitdiff
path: root/src/arch/sparcv9/CodeGen.zig
diff options
context:
space:
mode:
authorKoakuma <koachan@protonmail.com>2022-04-01 19:28:24 +0700
committerKoakuma <koachan@protonmail.com>2022-04-14 22:18:05 +0700
commit94a84e783e32169268809e4aa4bdbfdff92d81e9 (patch)
tree058f39b3608d1fbc0e360d45d6eaccf53a02067d /src/arch/sparcv9/CodeGen.zig
parent927706e6d0cf289be979bb6f12be6636c0e07f59 (diff)
downloadzig-94a84e783e32169268809e4aa4bdbfdff92d81e9.tar.gz
zig-94a84e783e32169268809e4aa4bdbfdff92d81e9.zip
stage2: sparcv9: Implement basic prologue/epilogue Mir emission
Diffstat (limited to 'src/arch/sparcv9/CodeGen.zig')
-rw-r--r--src/arch/sparcv9/CodeGen.zig102
1 files changed, 101 insertions, 1 deletions
diff --git a/src/arch/sparcv9/CodeGen.zig b/src/arch/sparcv9/CodeGen.zig
index 0c63d992ee..c2aa082b11 100644
--- a/src/arch/sparcv9/CodeGen.zig
+++ b/src/arch/sparcv9/CodeGen.zig
@@ -382,9 +382,109 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type, is_caller: bool) !Ca
/// Caller must call `CallMCValues.deinit`.
fn gen(self: *Self) !void {
+ const cc = self.fn_type.fnCallingConvention();
+ if (cc != .Naked) {
+ // TODO Finish function prologue and epilogue for sparcv9.
+
+ // TODO Backpatch stack offset
+ // save %sp, -176, %sp
+ _ = try self.addInst(.{
+ .tag = .save,
+ .data = .{
+ .arithmetic_3op = .{
+ .is_imm = true,
+ .rd = .sp,
+ .rs1 = .sp,
+ .rs2_or_imm = .{ .imm = -176 },
+ },
+ },
+ });
+
+ _ = try self.addInst(.{
+ .tag = .dbg_prologue_end,
+ .data = .{ .nop = {} },
+ });
+
+ try self.genBody(self.air.getMainBody());
+
+ _ = try self.addInst(.{
+ .tag = .dbg_epilogue_begin,
+ .data = .{ .nop = {} },
+ });
+
+ // exitlude jumps
+ if (self.exitlude_jump_relocs.items.len > 0 and
+ self.exitlude_jump_relocs.items[self.exitlude_jump_relocs.items.len - 1] == self.mir_instructions.len - 2)
+ {
+ // If the last Mir instruction (apart from the
+ // dbg_epilogue_begin) is the last exitlude jump
+ // relocation (which would just jump one instruction
+ // further), it can be safely removed
+ self.mir_instructions.orderedRemove(self.exitlude_jump_relocs.pop());
+ }
+
+ for (self.exitlude_jump_relocs.items) |jmp_reloc| {
+ _ = jmp_reloc;
+ return self.fail("TODO add branches in sparcv9", .{});
+ }
+
+ // return %i7 + 8
+ _ = try self.addInst(.{
+ .tag = .@"return",
+ .data = .{
+ .arithmetic_2op = .{
+ .is_imm = true,
+ .rs1 = .@"i7",
+ .rs2_or_imm = .{ .imm = 8 },
+ },
+ },
+ });
+
+ // TODO Find a way to fill this slot
+ // nop
+ _ = try self.addInst(.{
+ .tag = .nop,
+ .data = .{ .nop = {} },
+ });
+ } else {
+ _ = try self.addInst(.{
+ .tag = .dbg_prologue_end,
+ .data = .{ .nop = {} },
+ });
+
+ try self.genBody(self.air.getMainBody());
+
+ _ = try self.addInst(.{
+ .tag = .dbg_epilogue_begin,
+ .data = .{ .nop = {} },
+ });
+ }
+
+ // Drop them off at the rbrace.
+ _ = try self.addInst(.{
+ .tag = .dbg_line,
+ .data = .{ .dbg_line_column = .{
+ .line = self.end_di_line,
+ .column = self.end_di_column,
+ } },
+ });
+}
+
+fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
_ = self;
+ _ = body;
+
+ @panic("TODO implement genBody");
+}
+
+fn addInst(self: *Self, inst: Mir.Inst) error{OutOfMemory}!Mir.Inst.Index {
+ const gpa = self.gpa;
+
+ try self.mir_instructions.ensureUnusedCapacity(gpa, 1);
- @panic("TODO implement gen");
+ const result_index = @intCast(Air.Inst.Index, self.mir_instructions.len);
+ self.mir_instructions.appendAssumeCapacity(inst);
+ return result_index;
}
fn fail(self: *Self, comptime format: []const u8, args: anytype) InnerError {