| ... | @@ -107,10 +107,7 @@ pub fn emitMir(emit: *Emit) Error!void { | ... | @@ -107,10 +107,7 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 107 | nav, | 107 | nav, |
| 108 | emit.lower.target.*, | 108 | emit.lower.target.*, |
| 109 | )) { | 109 | )) { |
| 110 | .mcv => |mcv| switch (mcv) { | 110 | .mcv => |mcv| mcv.lea_symbol, |
| 111 | else => std.debug.panic("{s}: {}\n", .{ @src().fn_name, mcv }), | | |
| 112 | .lea_symbol => |sym_index| sym_index, | | |
| 113 | }, | | |
| 114 | .fail => |em| { | 111 | .fail => |em| { |
| 115 | assert(emit.lower.err_msg == null); | 112 | assert(emit.lower.err_msg == null); |
| 116 | emit.lower.err_msg = em; | 113 | emit.lower.err_msg = em; |
| ... | @@ -154,10 +151,7 @@ pub fn emitMir(emit: *Emit) Error!void { | ... | @@ -154,10 +151,7 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 154 | Type.fromInterned(uav.orig_ty).ptrAlignment(emit.pt.zcu), | 151 | Type.fromInterned(uav.orig_ty).ptrAlignment(emit.pt.zcu), |
| 155 | emit.lower.src_loc, | 152 | emit.lower.src_loc, |
| 156 | )) { | 153 | )) { |
| 157 | .mcv => |mcv| switch (mcv) { | 154 | .mcv => |mcv| mcv.load_symbol, |
| 158 | else => std.debug.panic("{s}: {}\n", .{ @src().fn_name, mcv }), | | |
| 159 | .load_direct, .load_symbol => |sym_index| sym_index, | | |
| 160 | }, | | |
| 161 | .fail => |em| { | 155 | .fail => |em| { |
| 162 | assert(emit.lower.err_msg == null); | 156 | assert(emit.lower.err_msg == null); |
| 163 | emit.lower.err_msg = em; | 157 | emit.lower.err_msg = em; |
| ... | @@ -207,7 +201,9 @@ pub fn emitMir(emit: *Emit) Error!void { | ... | @@ -207,7 +201,9 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 207 | switch (lowered_inst.encoding.mnemonic) { | 201 | switch (lowered_inst.encoding.mnemonic) { |
| 208 | .call => { | 202 | .call => { |
| 209 | reloc.target.type = .branch; | 203 | reloc.target.type = .branch; |
| 210 | try emit.encodeInst(lowered_inst, reloc_info); | 204 | if (emit.bin_file.cast(.coff)) |_| try emit.encodeInst(try .new(.none, .call, &.{ |
| | 205 | .{ .mem = .initRip(.ptr, 0) }, |
| | 206 | }, emit.lower.target), reloc_info) else try emit.encodeInst(lowered_inst, reloc_info); |
| 211 | continue :lowered_inst; | 207 | continue :lowered_inst; |
| 212 | }, | 208 | }, |
| 213 | else => {}, | 209 | else => {}, |
| ... | @@ -284,6 +280,37 @@ pub fn emitMir(emit: *Emit) Error!void { | ... | @@ -284,6 +280,37 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 284 | }, emit.lower.target), reloc_info), | 280 | }, emit.lower.target), reloc_info), |
| 285 | else => unreachable, | 281 | else => unreachable, |
| 286 | } | 282 | } |
| | 283 | } else if (emit.bin_file.cast(.coff)) |_| { |
| | 284 | if (reloc.target.is_extern) switch (lowered_inst.encoding.mnemonic) { |
| | 285 | .lea => try emit.encodeInst(try .new(.none, .mov, &.{ |
| | 286 | lowered_inst.ops[0], |
| | 287 | .{ .mem = .initRip(.ptr, 0) }, |
| | 288 | }, emit.lower.target), reloc_info), |
| | 289 | .mov => { |
| | 290 | const dst_reg = lowered_inst.ops[0].reg.to64(); |
| | 291 | try emit.encodeInst(try .new(.none, .mov, &.{ |
| | 292 | .{ .reg = dst_reg }, |
| | 293 | .{ .mem = .initRip(.ptr, 0) }, |
| | 294 | }, emit.lower.target), reloc_info); |
| | 295 | try emit.encodeInst(try .new(.none, .mov, &.{ |
| | 296 | lowered_inst.ops[0], |
| | 297 | .{ .mem = .initSib(lowered_inst.ops[reloc.op_index].mem.sib.ptr_size, .{ .base = .{ |
| | 298 | .reg = dst_reg, |
| | 299 | } }) }, |
| | 300 | }, emit.lower.target), &.{}); |
| | 301 | }, |
| | 302 | else => unreachable, |
| | 303 | } else switch (lowered_inst.encoding.mnemonic) { |
| | 304 | .lea => try emit.encodeInst(try .new(.none, .lea, &.{ |
| | 305 | lowered_inst.ops[0], |
| | 306 | .{ .mem = .initRip(.none, 0) }, |
| | 307 | }, emit.lower.target), reloc_info), |
| | 308 | .mov => try emit.encodeInst(try .new(.none, .mov, &.{ |
| | 309 | lowered_inst.ops[0], |
| | 310 | .{ .mem = .initRip(lowered_inst.ops[reloc.op_index].mem.sib.ptr_size, 0) }, |
| | 311 | }, emit.lower.target), reloc_info), |
| | 312 | else => unreachable, |
| | 313 | } |
| 287 | } else return emit.fail("TODO implement relocs for {s}", .{ | 314 | } else return emit.fail("TODO implement relocs for {s}", .{ |
| 288 | @tagName(emit.bin_file.tag), | 315 | @tagName(emit.bin_file.tag), |
| 289 | }); | 316 | }); |
| ... | @@ -751,6 +778,21 @@ fn encodeInst(emit: *Emit, lowered_inst: Instruction, reloc_info: []const RelocI | ... | @@ -751,6 +778,21 @@ fn encodeInst(emit: *Emit, lowered_inst: Instruction, reloc_info: []const RelocI |
| 751 | .symbolnum = @intCast(reloc.target.index), | 778 | .symbolnum = @intCast(reloc.target.index), |
| 752 | }, | 779 | }, |
| 753 | }); | 780 | }); |
| | 781 | } else if (emit.bin_file.cast(.coff)) |coff_file| { |
| | 782 | const atom_index = coff_file.getAtomIndexForSymbol( |
| | 783 | .{ .sym_index = emit.atom_index, .file = null }, |
| | 784 | ).?; |
| | 785 | try coff_file.addRelocation(atom_index, .{ |
| | 786 | .type = if (reloc.target.is_extern) .got else .direct, |
| | 787 | .target = if (reloc.target.is_extern) |
| | 788 | coff_file.getGlobalByIndex(reloc.target.index) |
| | 789 | else |
| | 790 | .{ .sym_index = reloc.target.index, .file = null }, |
| | 791 | .offset = end_offset - 4, |
| | 792 | .addend = @intCast(reloc.off), |
| | 793 | .pcrel = true, |
| | 794 | .length = 2, |
| | 795 | }); |
| 754 | } else unreachable, | 796 | } else unreachable, |
| 755 | .branch => if (emit.bin_file.cast(.elf)) |elf_file| { | 797 | .branch => if (emit.bin_file.cast(.elf)) |elf_file| { |
| 756 | const zo = elf_file.zigObjectPtr().?; | 798 | const zo = elf_file.zigObjectPtr().?; |
| ... | @@ -781,13 +823,12 @@ fn encodeInst(emit: *Emit, lowered_inst: Instruction, reloc_info: []const RelocI | ... | @@ -781,13 +823,12 @@ fn encodeInst(emit: *Emit, lowered_inst: Instruction, reloc_info: []const RelocI |
| 781 | const atom_index = coff_file.getAtomIndexForSymbol( | 823 | const atom_index = coff_file.getAtomIndexForSymbol( |
| 782 | .{ .sym_index = emit.atom_index, .file = null }, | 824 | .{ .sym_index = emit.atom_index, .file = null }, |
| 783 | ).?; | 825 | ).?; |
| 784 | const target: link.File.Coff.SymbolWithLoc = if (link.File.Coff.global_symbol_bit & reloc.target.index != 0) | | |
| 785 | coff_file.getGlobalByIndex(link.File.Coff.global_symbol_mask & reloc.target.index) | | |
| 786 | else | | |
| 787 | .{ .sym_index = reloc.target.index, .file = null }; | | |
| 788 | try coff_file.addRelocation(atom_index, .{ | 826 | try coff_file.addRelocation(atom_index, .{ |
| 789 | .type = .direct, | 827 | .type = if (reloc.target.is_extern) .import else .got, |
| 790 | .target = target, | 828 | .target = if (reloc.target.is_extern) |
| | 829 | coff_file.getGlobalByIndex(reloc.target.index) |
| | 830 | else |
| | 831 | .{ .sym_index = reloc.target.index, .file = null }, |
| 791 | .offset = end_offset - 4, | 832 | .offset = end_offset - 4, |
| 792 | .addend = @intCast(reloc.off), | 833 | .addend = @intCast(reloc.off), |
| 793 | .pcrel = true, | 834 | .pcrel = true, |