x86_64: no more load/lea_symbol weirdness

This commit is contained in:
Jakub Konka 2023-10-27 19:43:38 +02:00 committed by Jacob Young
parent 0d00b7c585
commit 2be1250f24
8 changed files with 62 additions and 68 deletions

View File

@ -6176,7 +6176,7 @@ fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue {
.memory => |addr| .{ .memory = addr },
.load_got => |sym_index| .{ .linker_load = .{ .type = .got, .sym_index = sym_index } },
.load_direct => |sym_index| .{ .linker_load = .{ .type = .direct, .sym_index = sym_index } },
.load_symbol, .lea_symbol, .load_tlv => unreachable, // TODO
.load_symbol, .load_tlv => unreachable, // TODO
},
.fail => |msg| {
self.err_msg = msg;

View File

@ -6135,7 +6135,7 @@ fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue {
.mcv => |mcv| switch (mcv) {
.none => .none,
.undef => .undef,
.load_got, .load_symbol, .lea_symbol, .load_direct, .load_tlv => unreachable, // TODO
.load_got, .load_symbol, .load_direct, .load_tlv => unreachable, // TODO
.immediate => |imm| .{ .immediate = @as(u32, @truncate(imm)) },
.memory => |addr| .{ .memory = addr },
},

View File

@ -2591,7 +2591,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
.mcv => |mcv| switch (mcv) {
.none => .none,
.undef => .undef,
.load_got, .load_symbol, .lea_symbol, .load_direct, .load_tlv => unreachable, // TODO
.load_got, .load_symbol, .load_direct, .load_tlv => unreachable, // TODO
.immediate => |imm| .{ .immediate = imm },
.memory => |addr| .{ .memory = addr },
},

View File

@ -4137,7 +4137,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
.mcv => |mcv| switch (mcv) {
.none => .none,
.undef => .undef,
.load_got, .load_symbol, .lea_symbol, .load_direct, .load_tlv => unreachable, // TODO
.load_got, .load_symbol, .load_direct, .load_tlv => unreachable, // TODO
.immediate => |imm| .{ .immediate = imm },
.memory => |addr| .{ .memory = addr },
},

View File

@ -453,8 +453,8 @@ pub const MCValue = union(enum) {
.lea_frame => |pl| try writer.print("{} + 0x{x}", .{ pl.index, pl.off }),
.reserved_frame => |pl| try writer.print("(dead:{})", .{pl}),
.air_ref => |pl| try writer.print("(air:0x{x})", .{@intFromEnum(pl)}),
.load_symbol => |pl| try writer.print("[mem:{d}]", .{pl}),
.lea_symbol => |pl| try writer.print("mem:{d}", .{pl}),
.load_symbol => |pl| try writer.print("[symbol:{d}]", .{pl}),
.lea_symbol => |pl| try writer.print("symbol:{d}", .{pl}),
}
}
};
@ -11627,8 +11627,8 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
.{ .reg = try self.copyToTmpRegister(Type.usize, .{ .lea_got = sym_index }) }
else
return self.fail("invalid modifier: '{s}'", .{modifier}),
.lea_symbol => |sym_index| if (mem.eql(u8, modifier, "P"))
.{ .reg = try self.copyToTmpRegister(Type.usize, .{ .lea_symbol = sym_index }) }
.load_symbol => |sym_index| if (mem.eql(u8, modifier, "P"))
.{ .reg = try self.copyToTmpRegister(Type.usize, .{ .load_symbol = sym_index }) }
else
return self.fail("invalid modifier: '{s}'", .{modifier}),
else => return self.fail("invalid constraint: '{s}'", .{op_str}),
@ -12489,10 +12489,9 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
},
.lea_symbol, .lea_direct, .lea_got => |sym_index| {
const atom_index = try self.owner.getSymbolIndex(self);
if (self.bin_file.cast(link.File.Elf)) |elf_file| {
const sym = elf_file.symbol(elf_file.zigModulePtr().symbol(sym_index));
if (self.bin_file.cast(link.File.Elf)) |_| {
_ = try self.addInst(.{
.tag = if (sym.flags.has_zig_got) .mov else .lea,
.tag = .lea,
.ops = .linker_reloc,
.data = .{ .rx = .{
.r1 = dst_reg.to64(),
@ -12783,7 +12782,7 @@ fn genLazySymbolRef(
};
switch (tag) {
.lea, .mov => _ = try self.addInst(.{
.tag = .mov,
.tag = tag,
.ops = .linker_reloc,
.data = .{ .rx = .{
.r1 = reg.to64(),
@ -12797,15 +12796,6 @@ fn genLazySymbolRef(
}),
else => unreachable,
}
switch (tag) {
.lea, .call => {},
.mov => try self.asmRegisterMemory(
.{ ._, tag },
reg.to64(),
Memory.sib(.qword, .{ .base = .{ .reg = reg.to64() } }),
),
else => unreachable,
}
}
} else if (self.bin_file.cast(link.File.Plan9)) |p9_file| {
const atom_index = p9_file.getOrCreateAtomForLazySymbol(lazy_sym) catch |err|
@ -14692,10 +14682,12 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue {
} else mcv: {
const ip_index = Air.refToInterned(ref).?;
const gop = try self.const_tracking.getOrPut(self.gpa, ip_index);
if (!gop.found_existing) gop.value_ptr.* = InstTracking.init(try self.genTypedValue(.{
const mcv = try self.genTypedValue(.{
.ty = ty,
.val = ip_index.toValue(),
}));
});
std.debug.print("genTypedValue: {any}\n", .{mcv});
if (!gop.found_existing) gop.value_ptr.* = InstTracking.init(mcv);
break :mcv gop.value_ptr.short;
};
@ -14743,7 +14735,6 @@ fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue {
.immediate => |imm| .{ .immediate = imm },
.memory => |addr| .{ .memory = addr },
.load_symbol => |sym_index| .{ .load_symbol = sym_index },
.lea_symbol => |sym_index| .{ .lea_symbol = sym_index },
.load_direct => |sym_index| .{ .load_direct = sym_index },
.load_got => |sym_index| .{ .lea_got = sym_index },
.load_tlv => |sym_index| .{ .lea_tlv = sym_index },

View File

@ -96,7 +96,7 @@ pub fn emitMir(emit: *Emit) Error!void {
} else {
const r_type: u32 = if (sym.flags.has_zig_got)
link.File.Elf.R_X86_64_ZIG_GOT32
else if (sym.flags.has_got)
else if (sym.flags.needs_got)
std.elf.R_X86_64_GOT32
else
std.elf.R_X86_64_32;

View File

@ -415,7 +415,49 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void {
=> ._,
else => return lower.fail("TODO lower .{s}", .{@tagName(inst.ops)}),
};
try lower.emit(switch (fixes) {
if (inst.ops == .linker_reloc) {
if (lower.bin_file.options.pic) {
const reg = inst.data.rx.r1;
const extra = lower.mir.extraData(Mir.Reloc, inst.data.rx.payload).data;
_ = lower.reloc(.{ .linker_reloc = extra });
const mnemonic: Mnemonic = switch (inst.tag) {
.mov => .mov,
.lea => .lea,
else => unreachable,
};
try lower.emit(.none, mnemonic, &.{
.{ .reg = reg },
.{ .mem = Memory.rip(Memory.PtrSize.fromBitSize(reg.bitSize()), 0) },
});
} else {
switch (inst.tag) {
.call => {
_ = lower.reloc(.{ .linker_reloc = inst.data.reloc });
try lower.emit(.none, .call, &.{
.{ .mem = Memory.sib(.qword, .{ .base = .{ .reg = .ds }, .disp = 0 }) },
});
},
.lea => {
const reg = inst.data.rx.r1;
const extra = lower.mir.extraData(Mir.Reloc, inst.data.rx.payload).data;
try lower.emit(.none, .mov, &.{
.{ .reg = reg },
.{ .imm = lower.reloc(.{ .linker_reloc = extra }) },
});
},
.mov => {
const reg = inst.data.rx.r1;
const extra = lower.mir.extraData(Mir.Reloc, inst.data.rx.payload).data;
_ = lower.reloc(.{ .linker_reloc = extra });
try lower.emit(.none, .mov, &.{
.{ .reg = reg },
.{ .mem = Memory.sib(.qword, .{ .base = .{ .reg = .ds }, .disp = 0 }) },
});
},
else => return lower.fail("TODO lower {s} {s}", .{ @tagName(inst.tag), @tagName(inst.ops) }),
}
}
} else try lower.emit(switch (fixes) {
inline else => |tag| comptime if (std.mem.indexOfScalar(u8, @tagName(tag), ' ')) |space|
@field(Prefix, @tagName(tag)[0..space])
else
@ -544,45 +586,7 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void {
.extern_fn_reloc => &.{
.{ .imm = lower.reloc(.{ .linker_extern_fn = inst.data.reloc }) },
},
.linker_reloc => ops: {
if (lower.bin_file.options.pic) {
const reg = inst.data.rx.r1;
const extra = lower.mir.extraData(Mir.Reloc, inst.data.rx.payload).data;
_ = lower.reloc(.{ .linker_reloc = extra });
break :ops &.{
.{ .reg = reg },
.{ .mem = Memory.rip(Memory.PtrSize.fromBitSize(reg.bitSize()), 0) },
};
} else {
switch (inst.tag) {
.call => {
_ = lower.reloc(.{ .linker_reloc = inst.data.reloc });
break :ops &.{
.{ .mem = Memory.sib(.qword, .{ .base = .{ .reg = .ds }, .disp = 0 }) },
};
},
.mov => {
const reg = inst.data.rx.r1;
const extra = lower.mir.extraData(Mir.Reloc, inst.data.rx.payload).data;
_ = lower.reloc(.{ .linker_reloc = extra });
break :ops &.{
.{ .reg = reg },
.{ .mem = Memory.sib(.qword, .{ .base = .{ .reg = .ds }, .disp = 0 }) },
};
},
.lea => {
const reg = inst.data.rx.r1;
const extra = lower.mir.extraData(Mir.Reloc, inst.data.rx.payload).data;
_ = lower.reloc(.{ .linker_reloc = extra });
break :ops &.{
.{ .reg = reg },
.{ .mem = Memory.sib(.qword, .{ .base = .{ .reg = .ds }, .disp = 0 }) },
};
},
else => return lower.fail("TODO lower {s} {s}", .{ @tagName(inst.tag), @tagName(inst.ops) }),
}
}
},
.linker_reloc => unreachable,
.got_reloc, .direct_reloc, .import_reloc, .tlv_reloc => ops: {
const reg = inst.data.rx.r1;
const extra = lower.mir.extraData(Mir.Reloc, inst.data.rx.payload).data;

View File

@ -828,7 +828,6 @@ pub const GenResult = union(enum) {
/// Reference to memory location but deferred until linker allocated the Decl in memory.
/// Traditionally, this corresponds to emitting a relocation in a relocatable object file.
load_symbol: u32,
lea_symbol: u32,
};
fn mcv(val: MCValue) GenResult {
@ -905,12 +904,12 @@ fn genDeclRef(
null;
const sym_index = try elf_file.getGlobalSymbol(name, lib_name);
elf_file.symbol(elf_file.zigModulePtr().symbol(sym_index)).flags.needs_got = true;
return GenResult.mcv(.{ .lea_symbol = sym_index });
return GenResult.mcv(.{ .load_symbol = sym_index });
}
const sym_index = try elf_file.getOrCreateMetadataForDecl(decl_index);
const sym = elf_file.symbol(sym_index);
_ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);
return GenResult.mcv(.{ .lea_symbol = sym.esym_index });
return GenResult.mcv(.{ .load_symbol = sym.esym_index });
} else if (bin_file.cast(link.File.MachO)) |macho_file| {
const atom_index = try macho_file.getOrCreateAtomForDecl(decl_index);
const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?;