Commit 8a55e6b6c4

joachimschmidt557 <joachim.schmidt557@outlook.com>
2021-10-31 14:27:05
stage2 AArch64: introduce Emit.fail for handling errors in MIR emit
1 parent 0bdb367
Changed files (2)
src
arch
src/arch/aarch64/CodeGen.zig
@@ -309,12 +309,16 @@ pub fn generate(
         .bin_file = bin_file,
         .debug_output = debug_output,
         .target = &bin_file.options.target,
+        .src_loc = src_loc,
         .code = code,
         .prev_di_pc = 0,
         .prev_di_line = module_fn.lbrace_line,
         .prev_di_column = module_fn.lbrace_column,
     };
-    try emit.emitMir();
+    emit.emitMir() catch |err| switch (err) {
+        error.EmitFail => return FnResult{ .fail = emit.err_msg.? },
+        else => |e| return e,
+    };
 
     if (function.err_msg) |em| {
         return FnResult{ .fail = em };
src/arch/aarch64/Emit.zig
@@ -7,6 +7,8 @@ const math = std.math;
 const Mir = @import("Mir.zig");
 const bits = @import("bits.zig");
 const link = @import("../../link.zig");
+const Module = @import("../../Module.zig");
+const ErrorMsg = Module.ErrorMsg;
 const assert = std.debug.assert;
 const DW = std.dwarf;
 const leb128 = std.leb;
@@ -18,6 +20,8 @@ mir: Mir,
 bin_file: *link.File,
 debug_output: DebugInfoOutput,
 target: *const std.Target,
+err_msg: ?*ErrorMsg = null,
+src_loc: Module.SrcLoc,
 code: *std.ArrayList(u8),
 
 prev_di_line: u32,
@@ -25,6 +29,11 @@ prev_di_column: u32,
 /// Relative to the beginning of `code`.
 prev_di_pc: usize,
 
+const InnerError = error{
+    OutOfMemory,
+    EmitFail,
+};
+
 pub fn emitMir(
     emit: *Emit,
 ) !void {
@@ -80,6 +89,13 @@ fn writeInstruction(emit: *Emit, instruction: Instruction) !void {
     std.mem.writeInt(u32, try emit.code.addManyAsArray(4), instruction.toU32(), endian);
 }
 
+fn fail(emit: *Emit, comptime format: []const u8, args: anytype) InnerError {
+    @setCold(true);
+    assert(emit.err_msg == null);
+    emit.err_msg = try ErrorMsg.create(emit.bin_file.allocator, emit.src_loc, format, args);
+    return error.EmitFail;
+}
+
 fn moveImmediate(emit: *Emit, reg: Register, imm64: u64) !void {
     try emit.writeInstruction(Instruction.movz(reg, @truncate(u16, imm64), 0));
 
@@ -173,8 +189,8 @@ fn mirBranch(emit: *Emit, inst: Mir.Inst.Index) !void {
     _ = target_inst;
 
     switch (tag) {
-        .b => @panic("Implement mirBranch"),
-        .bl => @panic("Implement mirBranch"),
+        .b => return emit.fail("Implement mirBranch", .{}),
+        .bl => return emit.fail("Implement mirBranch", .{}),
         else => unreachable,
     }
 }
@@ -255,7 +271,7 @@ fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) !void {
             .@"type" = @enumToInt(std.macho.reloc_type_arm64.ARM64_RELOC_BRANCH26),
         });
     } else {
-        @panic("Implement call_extern for linking backends != MachO");
+        return emit.fail("Implement call_extern for linking backends != MachO", .{});
     }
 }
 
@@ -304,7 +320,7 @@ fn mirLoadMemory(emit: *Emit, inst: Mir.Inst.Index) !void {
                 .@"type" = @enumToInt(std.macho.reloc_type_arm64.ARM64_RELOC_GOT_LOAD_PAGEOFF12),
             });
         } else {
-            return @panic("TODO implement load_memory for PIE GOT indirection on this platform");
+            return emit.fail("TODO implement load_memory for PIE GOT indirection on this platform", .{});
         }
     } else {
         // The value is in memory at a hard-coded address.