| ... | @@ -7,6 +7,8 @@ const math = std.math; | ... | @@ -7,6 +7,8 @@ const math = std.math; |
| 7 | const Mir = @import("Mir.zig"); | 7 | const Mir = @import("Mir.zig"); |
| 8 | const bits = @import("bits.zig"); | 8 | const bits = @import("bits.zig"); |
| 9 | const link = @import("../../link.zig"); | 9 | const link = @import("../../link.zig"); |
| | 10 | const Module = @import("../../Module.zig"); |
| | 11 | const ErrorMsg = Module.ErrorMsg; |
| 10 | const assert = std.debug.assert; | 12 | const assert = std.debug.assert; |
| 11 | const DW = std.dwarf; | 13 | const DW = std.dwarf; |
| 12 | const leb128 = std.leb; | 14 | const leb128 = std.leb; |
| ... | @@ -18,6 +20,8 @@ mir: Mir, | ... | @@ -18,6 +20,8 @@ mir: Mir, |
| 18 | bin_file: *link.File, | 20 | bin_file: *link.File, |
| 19 | debug_output: DebugInfoOutput, | 21 | debug_output: DebugInfoOutput, |
| 20 | target: *const std.Target, | 22 | target: *const std.Target, |
| | 23 | err_msg: ?*ErrorMsg = null, |
| | 24 | src_loc: Module.SrcLoc, |
| 21 | code: *std.ArrayList(u8), | 25 | code: *std.ArrayList(u8), |
| 22 | | 26 | |
| 23 | prev_di_line: u32, | 27 | prev_di_line: u32, |
| ... | @@ -25,6 +29,11 @@ prev_di_column: u32, | ... | @@ -25,6 +29,11 @@ prev_di_column: u32, |
| 25 | /// Relative to the beginning of `code`. | 29 | /// Relative to the beginning of `code`. |
| 26 | prev_di_pc: usize, | 30 | prev_di_pc: usize, |
| 27 | | 31 | |
| | 32 | const InnerError = error{ |
| | 33 | OutOfMemory, |
| | 34 | EmitFail, |
| | 35 | }; |
| | 36 | |
| 28 | pub fn emitMir( | 37 | pub fn emitMir( |
| 29 | emit: *Emit, | 38 | emit: *Emit, |
| 30 | ) !void { | 39 | ) !void { |
| ... | @@ -80,6 +89,13 @@ fn writeInstruction(emit: *Emit, instruction: Instruction) !void { | ... | @@ -80,6 +89,13 @@ fn writeInstruction(emit: *Emit, instruction: Instruction) !void { |
| 80 | std.mem.writeInt(u32, try emit.code.addManyAsArray(4), instruction.toU32(), endian); | 89 | std.mem.writeInt(u32, try emit.code.addManyAsArray(4), instruction.toU32(), endian); |
| 81 | } | 90 | } |
| 82 | | 91 | |
| | 92 | fn fail(emit: *Emit, comptime format: []const u8, args: anytype) InnerError { |
| | 93 | @setCold(true); |
| | 94 | assert(emit.err_msg == null); |
| | 95 | emit.err_msg = try ErrorMsg.create(emit.bin_file.allocator, emit.src_loc, format, args); |
| | 96 | return error.EmitFail; |
| | 97 | } |
| | 98 | |
| 83 | fn moveImmediate(emit: *Emit, reg: Register, imm64: u64) !void { | 99 | fn moveImmediate(emit: *Emit, reg: Register, imm64: u64) !void { |
| 84 | try emit.writeInstruction(Instruction.movz(reg, @truncate(u16, imm64), 0)); | 100 | try emit.writeInstruction(Instruction.movz(reg, @truncate(u16, imm64), 0)); |
| 85 | | 101 | |
| ... | @@ -173,8 +189,8 @@ fn mirBranch(emit: *Emit, inst: Mir.Inst.Index) !void { | ... | @@ -173,8 +189,8 @@ fn mirBranch(emit: *Emit, inst: Mir.Inst.Index) !void { |
| 173 | _ = target_inst; | 189 | _ = target_inst; |
| 174 | | 190 | |
| 175 | switch (tag) { | 191 | switch (tag) { |
| 176 | .b => @panic("Implement mirBranch"), | 192 | .b => return emit.fail("Implement mirBranch", .{}), |
| 177 | .bl => @panic("Implement mirBranch"), | 193 | .bl => return emit.fail("Implement mirBranch", .{}), |
| 178 | else => unreachable, | 194 | else => unreachable, |
| 179 | } | 195 | } |
| 180 | } | 196 | } |
| ... | @@ -255,7 +271,7 @@ fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) !void { | ... | @@ -255,7 +271,7 @@ fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) !void { |
| 255 | .@"type" = @enumToInt(std.macho.reloc_type_arm64.ARM64_RELOC_BRANCH26), | 271 | .@"type" = @enumToInt(std.macho.reloc_type_arm64.ARM64_RELOC_BRANCH26), |
| 256 | }); | 272 | }); |
| 257 | } else { | 273 | } else { |
| 258 | @panic("Implement call_extern for linking backends != MachO"); | 274 | return emit.fail("Implement call_extern for linking backends != MachO", .{}); |
| 259 | } | 275 | } |
| 260 | } | 276 | } |
| 261 | | 277 | |
| ... | @@ -304,7 +320,7 @@ fn mirLoadMemory(emit: *Emit, inst: Mir.Inst.Index) !void { | ... | @@ -304,7 +320,7 @@ fn mirLoadMemory(emit: *Emit, inst: Mir.Inst.Index) !void { |
| 304 | .@"type" = @enumToInt(std.macho.reloc_type_arm64.ARM64_RELOC_GOT_LOAD_PAGEOFF12), | 320 | .@"type" = @enumToInt(std.macho.reloc_type_arm64.ARM64_RELOC_GOT_LOAD_PAGEOFF12), |
| 305 | }); | 321 | }); |
| 306 | } else { | 322 | } else { |
| 307 | return @panic("TODO implement load_memory for PIE GOT indirection on this platform"); | 323 | return emit.fail("TODO implement load_memory for PIE GOT indirection on this platform", .{}); |
| 308 | } | 324 | } |
| 309 | } else { | 325 | } else { |
| 310 | // The value is in memory at a hard-coded address. | 326 | // The value is in memory at a hard-coded address. |