Commit 2be1250f24

Jakub Konka <kubkon@jakubkonka.com>
2023-10-27 19:43:38
x86_64: no more load/lea_symbol weirdness
1 parent 0d00b7c
Changed files (8)
src/arch/aarch64/CodeGen.zig
@@ -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;
src/arch/arm/CodeGen.zig
@@ -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 },
         },
src/arch/riscv64/CodeGen.zig
@@ -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 },
         },
src/arch/sparc64/CodeGen.zig
@@ -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 },
         },
src/arch/x86_64/CodeGen.zig
@@ -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 },
src/arch/x86_64/Emit.zig
@@ -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;
src/arch/x86_64/Lower.zig
@@ -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;
src/codegen.zig
@@ -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().?;