aboutsummaryrefslogtreecommitdiff
path: root/src/codegen.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/codegen.zig')
-rw-r--r--src/codegen.zig18
1 files changed, 14 insertions, 4 deletions
diff --git a/src/codegen.zig b/src/codegen.zig
index 0e70a0b..97e160c 100644
--- a/src/codegen.zig
+++ b/src/codegen.zig
@@ -585,6 +585,7 @@ const ProcedureContext = struct {
register_allocator: RegisterAllocator(compile.VReg),
lvar_allocator: RegisterAllocator(compile.LVar),
ctx: *Context,
+ proc: compile.Procedure,
// Current stuff that changes often, basically here to avoid prop drilling.
block: ?*const compile.BasicBlock = null,
@@ -664,7 +665,7 @@ const ProcedureContext = struct {
}
}
- fn genProcCall(self: *Self, call: compile.Instr.ProcCall) !void {
+ fn genCall(self: *Self, call: compile.Instr.Call) !void {
const arg = self.register_allocator.get(call.arg);
try self.freeUnusedVRegs();
@@ -752,17 +753,25 @@ const ProcedureContext = struct {
fn prologue(self: *Self) !void {
try self.emit(.addi(.sp, .sp, -8));
try self.emit(.sd(.sp, 0, .ra));
+
+ if (self.proc.param_reg) |reg| {
+ const param = try self.register_allocator.allocate(reg);
+ try self.emit(.addi(param, .a0, 0));
+ }
}
fn epilogue(self: *Self) !void {
+ if (self.proc.param_reg) |reg| {
+ self.register_allocator.free(reg);
+ }
try self.emit(.ld(.ra, .sp, 0));
try self.emit(.addi(.sp, .sp, 8));
try self.emit(.jalr(.zero, .ra, 0));
}
- fn codegenProc(self: *Self, proc: compile.Procedure) !void {
+ fn codegenProc(self: *Self) !void {
var first = true;
- for (proc.blocks) |block| {
+ for (self.proc.blocks) |block| {
try self.ctx.block_addrs.putNoClobber(block.ref, self.ctx.instructions.items.len);
if (first) {
try self.prologue();
@@ -866,10 +875,11 @@ pub fn create_elf(allocator: Allocator, mod: compile.Module) ![]u8 {
.register_allocator = try .init(allocator, &.{ .t6, .t5, .t4, .t3, .t2, .t1, .t0 }),
.lvar_allocator = try .init(allocator, &.{ .s11, .s10, .s9, .s8, .s7, .s6, .s5, .s4, .s3, .s2, .s1, .s0 }),
.ctx = &ctx,
+ .proc = proc,
};
defer proc_ctx.deinit();
- try proc_ctx.codegenProc(proc);
+ try proc_ctx.codegenProc();
std.debug.assert(proc_ctx.register_allocator.allocated.count() == 0);
}