| ... | ... | @@ -56,10 +56,7 @@ liveness: Liveness, |
| 56 | 56 | bin_file: *link.File, |
| 57 | 57 | debug_output: DebugInfoOutput, |
| 58 | 58 | target: *const std.Target, |
| 59 | | owner: union(enum) { |
| 60 | | mod_fn: *const Module.Fn, |
| 61 | | decl: Module.Decl.Index, |
| 62 | | }, |
| 59 | owner: Owner, |
| 63 | 60 | err_msg: ?*ErrorMsg, |
| 64 | 61 | args: []MCValue, |
| 65 | 62 | ret_mcv: InstTracking, |
| ... | ... | @@ -111,6 +108,44 @@ const mir_to_air_map_init = if (builtin.mode == .Debug) std.AutoHashMapUnmanaged |
| 111 | 108 | const FrameAddr = struct { index: FrameIndex, off: i32 = 0 }; |
| 112 | 109 | const RegisterOffset = struct { reg: Register, off: i32 = 0 }; |
| 113 | 110 | |
| 111 | const Owner = union(enum) { |
| 112 | mod_fn: *const Module.Fn, |
| 113 | lazy_sym: link.File.LazySymbol, |
| 114 | |
| 115 | fn getOwnerDecl(owner: Owner) Module.Decl.Index { |
| 116 | return switch (owner) { |
| 117 | .mod_fn => |mod_fn| mod_fn.owner_decl, |
| 118 | .lazy_sym => |lazy_sym| lazy_sym.ty.getOwnerDecl(), |
| 119 | }; |
| 120 | } |
| 121 | |
| 122 | fn getSymbolIndex(owner: Owner, ctx: *Self) !u32 { |
| 123 | switch (owner) { |
| 124 | .mod_fn => |mod_fn| { |
| 125 | const decl_index = mod_fn.owner_decl; |
| 126 | if (ctx.bin_file.cast(link.File.MachO)) |macho_file| { |
| 127 | const atom = try macho_file.getOrCreateAtomForDecl(decl_index); |
| 128 | return macho_file.getAtom(atom).getSymbolIndex().?; |
| 129 | } else if (ctx.bin_file.cast(link.File.Coff)) |coff_file| { |
| 130 | const atom = try coff_file.getOrCreateAtomForDecl(decl_index); |
| 131 | return coff_file.getAtom(atom).getSymbolIndex().?; |
| 132 | } else unreachable; |
| 133 | }, |
| 134 | .lazy_sym => |lazy_sym| { |
| 135 | if (ctx.bin_file.cast(link.File.MachO)) |macho_file| { |
| 136 | const atom = macho_file.getOrCreateAtomForLazySymbol(lazy_sym) catch |err| |
| 137 | return ctx.fail("{s} creating lazy symbol", .{@errorName(err)}); |
| 138 | return macho_file.getAtom(atom).getSymbolIndex().?; |
| 139 | } else if (ctx.bin_file.cast(link.File.Coff)) |coff_file| { |
| 140 | const atom = coff_file.getOrCreateAtomForLazySymbol(lazy_sym) catch |err| |
| 141 | return ctx.fail("{s} creating lazy symbol", .{@errorName(err)}); |
| 142 | return coff_file.getAtom(atom).getSymbolIndex().?; |
| 143 | } else unreachable; |
| 144 | }, |
| 145 | } |
| 146 | } |
| 147 | }; |
| 148 | |
| 114 | 149 | pub const MCValue = union(enum) { |
| 115 | 150 | /// No runtime bits. `void` types, empty structs, u0, enums with 1 tag, etc. |
| 116 | 151 | /// TODO Look into deleting this tag and using `dead` instead, since every use |
| ... | ... | @@ -763,7 +798,7 @@ pub fn generateLazy( |
| 763 | 798 | .target = &bin_file.options.target, |
| 764 | 799 | .bin_file = bin_file, |
| 765 | 800 | .debug_output = debug_output, |
| 766 | | .owner = .{ .decl = lazy_sym.ty.getOwnerDecl() }, |
| 801 | .owner = .{ .lazy_sym = lazy_sym }, |
| 767 | 802 | .err_msg = null, |
| 768 | 803 | .args = undefined, |
| 769 | 804 | .ret_mcv = undefined, |
| ... | ... | @@ -1724,13 +1759,6 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void { |
| 1724 | 1759 | } |
| 1725 | 1760 | } |
| 1726 | 1761 | |
| 1727 | | fn getOwnerDecl(self: *const Self) Module.Decl.Index { |
| 1728 | | return switch (self.owner) { |
| 1729 | | .mod_fn => |mod_fn| mod_fn.owner_decl, |
| 1730 | | .decl => |index| index, |
| 1731 | | }; |
| 1732 | | } |
| 1733 | | |
| 1734 | 1762 | fn getValue(self: *Self, value: MCValue, inst: ?Air.Inst.Index) void { |
| 1735 | 1763 | const reg = value.getReg() orelse return; |
| 1736 | 1764 | if (self.register_manager.isRegFree(reg)) { |
| ... | ... | @@ -6230,7 +6258,10 @@ fn genArgDbgInfo(self: Self, ty: Type, name: [:0]const u8, mcv: MCValue) !void { |
| 6230 | 6258 | //}, |
| 6231 | 6259 | else => unreachable, // not a valid function parameter |
| 6232 | 6260 | }; |
| 6233 | | try dw.genArgDbgInfo(name, ty, self.getOwnerDecl(), loc); |
| 6261 | // TODO: this might need adjusting like the linkers do. |
| 6262 | // Instead of flattening the owner and passing Decl.Index here we may |
| 6263 | // want to special case LazySymbol in DWARF linker too. |
| 6264 | try dw.genArgDbgInfo(name, ty, self.owner.getOwnerDecl(), loc); |
| 6234 | 6265 | }, |
| 6235 | 6266 | .plan9 => {}, |
| 6236 | 6267 | .none => {}, |
| ... | ... | @@ -6271,7 +6302,10 @@ fn genVarDbgInfo( |
| 6271 | 6302 | break :blk .nop; |
| 6272 | 6303 | }, |
| 6273 | 6304 | }; |
| 6274 | | try dw.genVarDbgInfo(name, ty, self.getOwnerDecl(), is_ptr, loc); |
| 6305 | // TODO: this might need adjusting like the linkers do. |
| 6306 | // Instead of flattening the owner and passing Decl.Index here we may |
| 6307 | // want to special case LazySymbol in DWARF linker too. |
| 6308 | try dw.genVarDbgInfo(name, ty, self.owner.getOwnerDecl(), is_ptr, loc); |
| 6275 | 6309 | }, |
| 6276 | 6310 | .plan9 => {}, |
| 6277 | 6311 | .none => {}, |
| ... | ... | @@ -6403,12 +6437,14 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 6403 | 6437 | .base = .{ .reg = .ds }, |
| 6404 | 6438 | .disp = @intCast(i32, got_addr), |
| 6405 | 6439 | })); |
| 6406 | | } else if (self.bin_file.cast(link.File.Coff)) |_| { |
| 6407 | | const sym_index = try self.getSymbolIndexForDecl(func.owner_decl); |
| 6440 | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| { |
| 6441 | const atom = try coff_file.getOrCreateAtomForDecl(func.owner_decl); |
| 6442 | const sym_index = coff_file.getAtom(atom).getSymbolIndex().?; |
| 6408 | 6443 | try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index }); |
| 6409 | 6444 | try self.asmRegister(.call, .rax); |
| 6410 | | } else if (self.bin_file.cast(link.File.MachO)) |_| { |
| 6411 | | const sym_index = try self.getSymbolIndexForDecl(func.owner_decl); |
| 6445 | } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { |
| 6446 | const atom = try macho_file.getOrCreateAtomForDecl(func.owner_decl); |
| 6447 | const sym_index = macho_file.getAtom(atom).getSymbolIndex().?; |
| 6412 | 6448 | try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index }); |
| 6413 | 6449 | try self.asmRegister(.call, .rax); |
| 6414 | 6450 | } else if (self.bin_file.cast(link.File.Plan9)) |p9| { |
| ... | ... | @@ -6429,7 +6465,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 6429 | 6465 | const decl_name = mem.sliceTo(mod.declPtr(extern_fn.owner_decl).name, 0); |
| 6430 | 6466 | const lib_name = mem.sliceTo(extern_fn.lib_name, 0); |
| 6431 | 6467 | if (self.bin_file.cast(link.File.Coff)) |coff_file| { |
| 6432 | | const atom_index = try self.getSymbolIndexForDecl(self.getOwnerDecl()); |
| 6468 | const atom_index = try self.owner.getSymbolIndex(self); |
| 6433 | 6469 | const sym_index = try coff_file.getGlobalSymbol(decl_name, lib_name); |
| 6434 | 6470 | _ = try self.addInst(.{ |
| 6435 | 6471 | .tag = .mov_linker, |
| ... | ... | @@ -6442,8 +6478,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 6442 | 6478 | }); |
| 6443 | 6479 | try self.asmRegister(.call, .rax); |
| 6444 | 6480 | } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { |
| 6481 | const atom_index = try self.owner.getSymbolIndex(self); |
| 6445 | 6482 | const sym_index = try macho_file.getGlobalSymbol(decl_name, lib_name); |
| 6446 | | const atom_index = try self.getSymbolIndexForDecl(self.getOwnerDecl()); |
| 6447 | 6483 | _ = try self.addInst(.{ |
| 6448 | 6484 | .tag = .call_extern, |
| 6449 | 6485 | .ops = undefined, |
| ... | ... | @@ -7719,7 +7755,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr |
| 7719 | 7755 | }), |
| 7720 | 7756 | ), |
| 7721 | 7757 | .load_direct => |sym_index| if (try self.movMirTag(ty) == .mov) { |
| 7722 | | const atom_index = try self.getSymbolIndexForDecl(self.getOwnerDecl()); |
| 7758 | const atom_index = try self.owner.getSymbolIndex(self); |
| 7723 | 7759 | _ = try self.addInst(.{ |
| 7724 | 7760 | .tag = .mov_linker, |
| 7725 | 7761 | .ops = .direct_reloc, |
| ... | ... | @@ -7746,7 +7782,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr |
| 7746 | 7782 | ); |
| 7747 | 7783 | }, |
| 7748 | 7784 | .lea_direct, .lea_got => |sym_index| { |
| 7749 | | const atom_index = try self.getSymbolIndexForDecl(self.getOwnerDecl()); |
| 7785 | const atom_index = try self.owner.getSymbolIndex(self); |
| 7750 | 7786 | _ = try self.addInst(.{ |
| 7751 | 7787 | .tag = switch (src_mcv) { |
| 7752 | 7788 | .lea_direct => .lea_linker, |
| ... | ... | @@ -7766,7 +7802,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr |
| 7766 | 7802 | }); |
| 7767 | 7803 | }, |
| 7768 | 7804 | .lea_tlv => |sym_index| { |
| 7769 | | const atom_index = try self.getSymbolIndexForDecl(self.getOwnerDecl()); |
| 7805 | const atom_index = try self.owner.getSymbolIndex(self); |
| 7770 | 7806 | if (self.bin_file.cast(link.File.MachO)) |_| { |
| 7771 | 7807 | _ = try self.addInst(.{ |
| 7772 | 7808 | .tag = .lea_linker, |
| ... | ... | @@ -9079,7 +9115,7 @@ fn limitImmediateType(self: *Self, operand: Air.Inst.Ref, comptime T: type) !MCV |
| 9079 | 9115 | } |
| 9080 | 9116 | |
| 9081 | 9117 | fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue { |
| 9082 | | return switch (try codegen.genTypedValue(self.bin_file, self.src_loc, arg_tv, self.getOwnerDecl())) { |
| 9118 | return switch (try codegen.genTypedValue(self.bin_file, self.src_loc, arg_tv, self.owner.getOwnerDecl())) { |
| 9083 | 9119 | .mcv => |mcv| switch (mcv) { |
| 9084 | 9120 | .none => .none, |
| 9085 | 9121 | .undef => .undef, |
| ... | ... | @@ -9390,13 +9426,3 @@ fn regBitSize(self: *Self, ty: Type) u64 { |
| 9390 | 9426 | fn regExtraBits(self: *Self, ty: Type) u64 { |
| 9391 | 9427 | return self.regBitSize(ty) - ty.bitSize(self.target.*); |
| 9392 | 9428 | } |
| 9393 | | |
| 9394 | | fn getSymbolIndexForDecl(self: *Self, decl_index: Module.Decl.Index) !u32 { |
| 9395 | | if (self.bin_file.cast(link.File.MachO)) |macho_file| { |
| 9396 | | const atom = try macho_file.getOrCreateAtomForDecl(decl_index); |
| 9397 | | return macho_file.getAtom(atom).getSymbolIndex().?; |
| 9398 | | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| { |
| 9399 | | const atom = try coff_file.getOrCreateAtomForDecl(decl_index); |
| 9400 | | return coff_file.getAtom(atom).getSymbolIndex().?; |
| 9401 | | } else unreachable; |
| 9402 | | } |