diff --git a/src/arch/aarch64/CodeGen.zig b/src/arch/aarch64/CodeGen.zig index 9abd3ce687..94f389c4a9 100644 --- a/src/arch/aarch64/CodeGen.zig +++ b/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 }; diff --git a/src/arch/aarch64/Emit.zig b/src/arch/aarch64/Emit.zig index 9de98a17e1..f43210dc3c 100644 --- a/src/arch/aarch64/Emit.zig +++ b/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.