mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 04:48:20 +00:00
x86_64: no more load/lea_symbol weirdness
This commit is contained in:
parent
0d00b7c585
commit
2be1250f24
@ -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;
|
||||
|
||||
@ -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 },
|
||||
},
|
||||
|
||||
@ -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 },
|
||||
},
|
||||
|
||||
@ -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 },
|
||||
},
|
||||
|
||||
@ -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 },
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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().?;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user