From 0fa2f445eb7140214471074fc544adfd0f8a524f Mon Sep 17 00:00:00 2001 From: Mathias Magnusson Date: Thu, 24 Jul 2025 22:15:03 +0200 Subject: continue implementing procedure calls multiple procedures can now exist, but you cannot call them, the first one is the "main" procedure since it happens to be placed first in the binary, and all procedures end with an exit system call --- src/codegen.zig | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) (limited to 'src/codegen.zig') diff --git a/src/codegen.zig b/src/codegen.zig index a1c2171..00b3857 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -563,7 +563,7 @@ const Relocation = struct { const Context = struct { instructions: std.ArrayList(Instruction), relocations: std.ArrayList(Relocation), - block_starts: std.ArrayList(usize), + block_addrs: std.AutoHashMap(compile.BlockRef, usize), print_block: compile.BlockRef, read_int_block: compile.BlockRef, @@ -767,7 +767,7 @@ const ProcedureContext = struct { fn codegenProc(self: *Self, proc: compile.Procedure) !void { for (proc.blocks) |block| { - try self.ctx.block_starts.append(self.ctx.instructions.items.len); + try self.ctx.block_addrs.putNoClobber(block.ref, self.ctx.instructions.items.len); try self.codegenBlock(block); } } @@ -845,17 +845,23 @@ fn codegenReadInt(self: *Context) !void { try self.emit(.jalr(.zero, .ra, 0)); } -pub fn create_elf(allocator: Allocator, proc: compile.Procedure) ![]u8 { +pub fn create_elf(allocator: Allocator, mod: compile.Module) ![]u8 { + var maxBlockRef: usize = 0; + for (mod.procedures) |proc| { + for (proc.blocks) |block| { + maxBlockRef = @max(maxBlockRef, @intFromEnum(block.ref)); + } + } var ctx: Context = .{ .instructions = .init(allocator), .relocations = .init(allocator), - .block_starts = .init(allocator), - .print_block = @enumFromInt(proc.blocks.len), - .read_int_block = @enumFromInt(proc.blocks.len + 1), + .block_addrs = .init(allocator), + .print_block = @enumFromInt(maxBlockRef + 1), + .read_int_block = @enumFromInt(maxBlockRef + 2), }; defer ctx.deinit(); - { + for (mod.procedures) |proc| { var proc_ctx: ProcedureContext = .{ .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 }), @@ -867,15 +873,15 @@ pub fn create_elf(allocator: Allocator, proc: compile.Procedure) ![]u8 { std.debug.assert(proc_ctx.register_allocator.allocated.count() == 0); } - try ctx.block_starts.append(ctx.instructions.items.len); + try ctx.block_addrs.putNoClobber(ctx.print_block, ctx.instructions.items.len); try codegenPrint(&ctx); - try ctx.block_starts.append(ctx.instructions.items.len); + try ctx.block_addrs.putNoClobber(ctx.read_int_block, ctx.instructions.items.len); try codegenReadInt(&ctx); // TODO: make this less sheiße for (ctx.relocations.items) |relocation| { const instr = &ctx.instructions.items[relocation.instr]; - const target: isize = @intCast(ctx.block_starts.items[@intFromEnum(relocation.target)]); + const target: isize = @intCast(ctx.block_addrs.get(relocation.target).?); const from: isize = @intCast(relocation.instr); switch (instr.*) { .j => |j| { -- cgit v1.2.3