| ... | @@ -56,10 +56,7 @@ liveness: Liveness, | ... | @@ -56,10 +56,7 @@ liveness: Liveness, |
| 56 | bin_file: *link.File, | 56 | bin_file: *link.File, |
| 57 | debug_output: DebugInfoOutput, | 57 | debug_output: DebugInfoOutput, |
| 58 | target: *const std.Target, | 58 | target: *const std.Target, |
| 59 | owner: union(enum) { | 59 | owner: Owner, |
| 60 | mod_fn: *const Module.Fn, | | |
| 61 | decl: Module.Decl.Index, | | |
| 62 | }, | | |
| 63 | err_msg: ?*ErrorMsg, | 60 | err_msg: ?*ErrorMsg, |
| 64 | args: []MCValue, | 61 | args: []MCValue, |
| 65 | ret_mcv: InstTracking, | 62 | ret_mcv: InstTracking, |
| ... | @@ -111,6 +108,44 @@ const mir_to_air_map_init = if (builtin.mode == .Debug) std.AutoHashMapUnmanaged | ... | @@ -111,6 +108,44 @@ const mir_to_air_map_init = if (builtin.mode == .Debug) std.AutoHashMapUnmanaged |
| 111 | const FrameAddr = struct { index: FrameIndex, off: i32 = 0 }; | 108 | const FrameAddr = struct { index: FrameIndex, off: i32 = 0 }; |
| 112 | const RegisterOffset = struct { reg: Register, off: i32 = 0 }; | 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 | pub const MCValue = union(enum) { | 149 | pub const MCValue = union(enum) { |
| 115 | /// No runtime bits. `void` types, empty structs, u0, enums with 1 tag, etc. | 150 | /// No runtime bits. `void` types, empty structs, u0, enums with 1 tag, etc. |
| 116 | /// TODO Look into deleting this tag and using `dead` instead, since every use | 151 | /// TODO Look into deleting this tag and using `dead` instead, since every use |
| ... | @@ -763,7 +798,7 @@ pub fn generateLazy( | ... | @@ -763,7 +798,7 @@ pub fn generateLazy( |
| 763 | .target = &bin_file.options.target, | 798 | .target = &bin_file.options.target, |
| 764 | .bin_file = bin_file, | 799 | .bin_file = bin_file, |
| 765 | .debug_output = debug_output, | 800 | .debug_output = debug_output, |
| 766 | .owner = .{ .decl = lazy_sym.ty.getOwnerDecl() }, | 801 | .owner = .{ .lazy_sym = lazy_sym }, |
| 767 | .err_msg = null, | 802 | .err_msg = null, |
| 768 | .args = undefined, | 803 | .args = undefined, |
| 769 | .ret_mcv = undefined, | 804 | .ret_mcv = undefined, |
| ... | @@ -1724,13 +1759,6 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void { | ... | @@ -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 | fn getValue(self: *Self, value: MCValue, inst: ?Air.Inst.Index) void { | 1762 | fn getValue(self: *Self, value: MCValue, inst: ?Air.Inst.Index) void { |
| 1735 | const reg = value.getReg() orelse return; | 1763 | const reg = value.getReg() orelse return; |
| 1736 | if (self.register_manager.isRegFree(reg)) { | 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,7 +6258,10 @@ fn genArgDbgInfo(self: Self, ty: Type, name: [:0]const u8, mcv: MCValue) !void { |
| 6230 | //}, | 6258 | //}, |
| 6231 | else => unreachable, // not a valid function parameter | 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 | .plan9 => {}, | 6266 | .plan9 => {}, |
| 6236 | .none => {}, | 6267 | .none => {}, |
| ... | @@ -6271,7 +6302,10 @@ fn genVarDbgInfo( | ... | @@ -6271,7 +6302,10 @@ fn genVarDbgInfo( |
| 6271 | break :blk .nop; | 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 | .plan9 => {}, | 6310 | .plan9 => {}, |
| 6277 | .none => {}, | 6311 | .none => {}, |
| ... | @@ -6403,12 +6437,14 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier | ... | @@ -6403,12 +6437,14 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 6403 | .base = .{ .reg = .ds }, | 6437 | .base = .{ .reg = .ds }, |
| 6404 | .disp = @intCast(i32, got_addr), | 6438 | .disp = @intCast(i32, got_addr), |
| 6405 | })); | 6439 | })); |
| 6406 | } else if (self.bin_file.cast(link.File.Coff)) |_| { | 6440 | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| { |
| 6407 | const sym_index = try self.getSymbolIndexForDecl(func.owner_decl); | 6441 | const atom = try coff_file.getOrCreateAtomForDecl(func.owner_decl); |
| | 6442 | const sym_index = coff_file.getAtom(atom).getSymbolIndex().?; |
| 6408 | try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index }); | 6443 | try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index }); |
| 6409 | try self.asmRegister(.call, .rax); | 6444 | try self.asmRegister(.call, .rax); |
| 6410 | } else if (self.bin_file.cast(link.File.MachO)) |_| { | 6445 | } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { |
| 6411 | const sym_index = try self.getSymbolIndexForDecl(func.owner_decl); | 6446 | const atom = try macho_file.getOrCreateAtomForDecl(func.owner_decl); |
| | 6447 | const sym_index = macho_file.getAtom(atom).getSymbolIndex().?; |
| 6412 | try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index }); | 6448 | try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index }); |
| 6413 | try self.asmRegister(.call, .rax); | 6449 | try self.asmRegister(.call, .rax); |
| 6414 | } else if (self.bin_file.cast(link.File.Plan9)) |p9| { | 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,7 +6465,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 6429 | const decl_name = mem.sliceTo(mod.declPtr(extern_fn.owner_decl).name, 0); | 6465 | const decl_name = mem.sliceTo(mod.declPtr(extern_fn.owner_decl).name, 0); |
| 6430 | const lib_name = mem.sliceTo(extern_fn.lib_name, 0); | 6466 | const lib_name = mem.sliceTo(extern_fn.lib_name, 0); |
| 6431 | if (self.bin_file.cast(link.File.Coff)) |coff_file| { | 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 | const sym_index = try coff_file.getGlobalSymbol(decl_name, lib_name); | 6469 | const sym_index = try coff_file.getGlobalSymbol(decl_name, lib_name); |
| 6434 | _ = try self.addInst(.{ | 6470 | _ = try self.addInst(.{ |
| 6435 | .tag = .mov_linker, | 6471 | .tag = .mov_linker, |
| ... | @@ -6442,8 +6478,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier | ... | @@ -6442,8 +6478,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 6442 | }); | 6478 | }); |
| 6443 | try self.asmRegister(.call, .rax); | 6479 | try self.asmRegister(.call, .rax); |
| 6444 | } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { | 6480 | } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { |
| | 6481 | const atom_index = try self.owner.getSymbolIndex(self); |
| 6445 | const sym_index = try macho_file.getGlobalSymbol(decl_name, lib_name); | 6482 | const sym_index = try macho_file.getGlobalSymbol(decl_name, lib_name); |
| 6446 | const atom_index = try self.getSymbolIndexForDecl(self.getOwnerDecl()); | | |
| 6447 | _ = try self.addInst(.{ | 6483 | _ = try self.addInst(.{ |
| 6448 | .tag = .call_extern, | 6484 | .tag = .call_extern, |
| 6449 | .ops = undefined, | 6485 | .ops = undefined, |
| ... | @@ -7719,7 +7755,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr | ... | @@ -7719,7 +7755,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr |
| 7719 | }), | 7755 | }), |
| 7720 | ), | 7756 | ), |
| 7721 | .load_direct => |sym_index| if (try self.movMirTag(ty) == .mov) { | 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 | _ = try self.addInst(.{ | 7759 | _ = try self.addInst(.{ |
| 7724 | .tag = .mov_linker, | 7760 | .tag = .mov_linker, |
| 7725 | .ops = .direct_reloc, | 7761 | .ops = .direct_reloc, |
| ... | @@ -7746,7 +7782,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr | ... | @@ -7746,7 +7782,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr |
| 7746 | ); | 7782 | ); |
| 7747 | }, | 7783 | }, |
| 7748 | .lea_direct, .lea_got => |sym_index| { | 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 | _ = try self.addInst(.{ | 7786 | _ = try self.addInst(.{ |
| 7751 | .tag = switch (src_mcv) { | 7787 | .tag = switch (src_mcv) { |
| 7752 | .lea_direct => .lea_linker, | 7788 | .lea_direct => .lea_linker, |
| ... | @@ -7766,7 +7802,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr | ... | @@ -7766,7 +7802,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr |
| 7766 | }); | 7802 | }); |
| 7767 | }, | 7803 | }, |
| 7768 | .lea_tlv => |sym_index| { | 7804 | .lea_tlv => |sym_index| { |
| 7769 | const atom_index = try self.getSymbolIndexForDecl(self.getOwnerDecl()); | 7805 | const atom_index = try self.owner.getSymbolIndex(self); |
| 7770 | if (self.bin_file.cast(link.File.MachO)) |_| { | 7806 | if (self.bin_file.cast(link.File.MachO)) |_| { |
| 7771 | _ = try self.addInst(.{ | 7807 | _ = try self.addInst(.{ |
| 7772 | .tag = .lea_linker, | 7808 | .tag = .lea_linker, |
| ... | @@ -9079,7 +9115,7 @@ fn limitImmediateType(self: *Self, operand: Air.Inst.Ref, comptime T: type) !MCV | ... | @@ -9079,7 +9115,7 @@ fn limitImmediateType(self: *Self, operand: Air.Inst.Ref, comptime T: type) !MCV |
| 9079 | } | 9115 | } |
| 9080 | | 9116 | |
| 9081 | fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue { | 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 | .mcv => |mcv| switch (mcv) { | 9119 | .mcv => |mcv| switch (mcv) { |
| 9084 | .none => .none, | 9120 | .none => .none, |
| 9085 | .undef => .undef, | 9121 | .undef => .undef, |
| ... | @@ -9390,13 +9426,3 @@ fn regBitSize(self: *Self, ty: Type) u64 { | ... | @@ -9390,13 +9426,3 @@ fn regBitSize(self: *Self, ty: Type) u64 { |
| 9390 | fn regExtraBits(self: *Self, ty: Type) u64 { | 9426 | fn regExtraBits(self: *Self, ty: Type) u64 { |
| 9391 | return self.regBitSize(ty) - ty.bitSize(self.target.*); | 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 | } | | |