diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2024-08-13 09:56:17 +0200 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2024-08-13 13:30:24 +0200 |
| commit | d25c93a868585e4e2f5941fcff15fa49c90510e9 (patch) | |
| tree | 191902004783169c5c4fadb5a50e4af5ab87793a /src | |
| parent | ffcf0478fe646569465ac509b3e60faadd9b3697 (diff) | |
| download | zig-d25c93a868585e4e2f5941fcff15fa49c90510e9.tar.gz zig-d25c93a868585e4e2f5941fcff15fa49c90510e9.zip | |
x86_64: emit call rel32 for near calls with linker reloc
Diffstat (limited to 'src')
| -rw-r--r-- | src/arch/x86_64/CodeGen.zig | 60 | ||||
| -rw-r--r-- | src/arch/x86_64/Disassembler.zig | 2 | ||||
| -rw-r--r-- | src/arch/x86_64/Lower.zig | 6 | ||||
| -rw-r--r-- | src/arch/x86_64/Mir.zig | 2 | ||||
| -rw-r--r-- | src/arch/x86_64/bits.zig | 45 | ||||
| -rw-r--r-- | src/arch/x86_64/encoder.zig | 134 | ||||
| -rw-r--r-- | src/link/Elf/Atom.zig | 7 |
7 files changed, 138 insertions, 118 deletions
diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index f6fbc67ff1..ea4c7ae358 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -1379,14 +1379,19 @@ fn asmImmediate(self: *Self, tag: Mir.Inst.FixedTag, imm: Immediate) !void { .ops = switch (imm) { .signed => .i_s, .unsigned => .i_u, + .reloc => .rel, + }, + .data = switch (imm) { + .reloc => |x| .{ .reloc = x }, + .signed, .unsigned => .{ .i = .{ + .fixes = tag[0], + .i = switch (imm) { + .signed => |s| @bitCast(s), + .unsigned => |u| @intCast(u), + .reloc => unreachable, + }, + } }, }, - .data = .{ .i = .{ - .fixes = tag[0], - .i = switch (imm) { - .signed => |s| @bitCast(s), - .unsigned => |u| @intCast(u), - }, - } }, }); } @@ -1406,6 +1411,7 @@ fn asmRegisterImmediate(self: *Self, tag: Mir.Inst.FixedTag, reg: Register, imm: const ops: Mir.Inst.Ops = switch (imm) { .signed => .ri_s, .unsigned => |u| if (math.cast(u32, u)) |_| .ri_u else .ri64, + .reloc => unreachable, }; _ = try self.addInst(.{ .tag = tag[1], @@ -1417,6 +1423,7 @@ fn asmRegisterImmediate(self: *Self, tag: Mir.Inst.FixedTag, reg: Register, imm: .i = switch (imm) { .signed => |s| @bitCast(s), .unsigned => |u| @intCast(u), + .reloc => unreachable, }, } }, .ri64 => .{ .rx = .{ @@ -1488,6 +1495,7 @@ fn asmRegisterRegisterRegisterImmediate( .i = switch (imm) { .signed => |s| @bitCast(@as(i8, @intCast(s))), .unsigned => |u| @intCast(u), + .reloc => unreachable, }, } }, }); @@ -1505,6 +1513,7 @@ fn asmRegisterRegisterImmediate( .ops = switch (imm) { .signed => .rri_s, .unsigned => .rri_u, + .reloc => unreachable, }, .data = .{ .rri = .{ .fixes = tag[0], @@ -1513,6 +1522,7 @@ fn asmRegisterRegisterImmediate( .i = switch (imm) { .signed => |s| @bitCast(s), .unsigned => |u| @intCast(u), + .reloc => unreachable, }, } }, }); @@ -1610,6 +1620,7 @@ fn asmRegisterMemoryImmediate( if (switch (imm) { .signed => |s| if (math.cast(i16, s)) |x| @as(u16, @bitCast(x)) else null, .unsigned => |u| math.cast(u16, u), + .reloc => unreachable, }) |small_imm| { _ = try self.addInst(.{ .tag = tag[1], @@ -1625,6 +1636,7 @@ fn asmRegisterMemoryImmediate( const payload = try self.addExtra(Mir.Imm32{ .imm = switch (imm) { .signed => |s| @bitCast(s), .unsigned => unreachable, + .reloc => unreachable, } }); assert(payload + 1 == try self.addExtra(Mir.Memory.encode(m))); _ = try self.addInst(.{ @@ -1632,6 +1644,7 @@ fn asmRegisterMemoryImmediate( .ops = switch (imm) { .signed => .rmi_s, .unsigned => .rmi_u, + .reloc => unreachable, }, .data = .{ .rx = .{ .fixes = tag[0], @@ -1679,6 +1692,7 @@ fn asmMemoryImmediate(self: *Self, tag: Mir.Inst.FixedTag, m: Memory, imm: Immed const payload = try self.addExtra(Mir.Imm32{ .imm = switch (imm) { .signed => |s| @bitCast(s), .unsigned => |u| @intCast(u), + .reloc => unreachable, } }); assert(payload + 1 == try self.addExtra(Mir.Memory.encode(m))); _ = try self.addInst(.{ @@ -1686,6 +1700,7 @@ fn asmMemoryImmediate(self: *Self, tag: Mir.Inst.FixedTag, m: Memory, imm: Immed .ops = switch (imm) { .signed => .mi_s, .unsigned => .mi_u, + .reloc => unreachable, }, .data = .{ .x = .{ .fixes = tag[0], @@ -12310,33 +12325,10 @@ fn genCall(self: *Self, info: union(enum) { if (self.bin_file.cast(.elf)) |elf_file| { const zo = elf_file.zigObjectPtr().?; const sym_index = try zo.getOrCreateMetadataForNav(elf_file, func.owner_nav); - if (self.mod.pic) { - const callee_reg: Register = switch (resolved_cc) { - .SysV => callee: { - if (!fn_info.is_var_args) break :callee .rax; - const param_regs = abi.getCAbiIntParamRegs(resolved_cc); - break :callee if (call_info.gp_count < param_regs.len) - param_regs[call_info.gp_count] - else - .r10; - }, - .Win64 => .rax, - else => unreachable, - }; - try self.genSetReg( - callee_reg, - Type.usize, - .{ .lea_symbol = .{ .sym = sym_index } }, - .{}, - ); - try self.asmRegister(.{ ._, .call }, callee_reg); - } else try self.asmMemory(.{ ._, .call }, .{ - .base = .{ .reloc = .{ - .atom_index = try self.owner.getSymbolIndex(self), - .sym_index = sym_index, - } }, - .mod = .{ .rm = .{ .size = .qword } }, - }); + try self.asmImmediate(.{ ._, .call }, Immediate.rel(.{ + .atom_index = try self.owner.getSymbolIndex(self), + .sym_index = sym_index, + })); } else if (self.bin_file.cast(.coff)) |coff_file| { const atom = try coff_file.getOrCreateAtomForNav(func.owner_nav); const sym_index = coff_file.getAtom(atom).getSymbolIndex().?; diff --git a/src/arch/x86_64/Disassembler.zig b/src/arch/x86_64/Disassembler.zig index e0117fa17b..d21cec28ab 100644 --- a/src/arch/x86_64/Disassembler.zig +++ b/src/arch/x86_64/Disassembler.zig @@ -8,7 +8,7 @@ const bits = @import("bits.zig"); const encoder = @import("encoder.zig"); const Encoding = @import("Encoding.zig"); -const Immediate = bits.Immediate; +const Immediate = Instruction.Immediate; const Instruction = encoder.Instruction; const LegacyPrefixes = encoder.LegacyPrefixes; const Memory = Instruction.Memory; diff --git a/src/arch/x86_64/Lower.zig b/src/arch/x86_64/Lower.zig index 9ad1579ecc..56cd2669d6 100644 --- a/src/arch/x86_64/Lower.zig +++ b/src/arch/x86_64/Lower.zig @@ -475,7 +475,7 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void { .rrmi => inst.data.rrix.fixes, .mi_u, .mi_s => inst.data.x.fixes, .m => inst.data.x.fixes, - .extern_fn_reloc, .got_reloc, .direct_reloc, .import_reloc, .tlv_reloc => ._, + .extern_fn_reloc, .got_reloc, .direct_reloc, .import_reloc, .tlv_reloc, .rel => ._, else => return lower.fail("TODO lower .{s}", .{@tagName(inst.ops)}), }; try lower.emit(switch (fixes) { @@ -607,7 +607,7 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void { .{ .mem = lower.mem(inst.data.rrix.payload) }, .{ .imm = lower.imm(inst.ops, inst.data.rrix.i) }, }, - .extern_fn_reloc => &.{ + .extern_fn_reloc, .rel => &.{ .{ .imm = lower.reloc(.{ .linker_extern_fn = inst.data.reloc }) }, }, .got_reloc, .direct_reloc, .import_reloc => ops: { @@ -650,7 +650,7 @@ const std = @import("std"); const Air = @import("../../Air.zig"); const Allocator = std.mem.Allocator; const ErrorMsg = Zcu.ErrorMsg; -const Immediate = bits.Immediate; +const Immediate = Instruction.Immediate; const Instruction = encoder.Instruction; const Lower = @This(); const Memory = Instruction.Memory; diff --git a/src/arch/x86_64/Mir.zig b/src/arch/x86_64/Mir.zig index d2dd6237a5..08f2cc3b25 100644 --- a/src/arch/x86_64/Mir.zig +++ b/src/arch/x86_64/Mir.zig @@ -769,7 +769,7 @@ pub const Inst = struct { /// Uses `imm` payload. i_u, /// Relative displacement operand. - /// Uses `imm` payload. + /// Uses `reloc` payload. rel, /// Register, memory operands. /// Uses `rx` payload with extra data of type `Memory`. diff --git a/src/arch/x86_64/bits.zig b/src/arch/x86_64/bits.zig index 6896d6c2e7..79f9b20924 100644 --- a/src/arch/x86_64/bits.zig +++ b/src/arch/x86_64/bits.zig @@ -569,6 +569,7 @@ pub const Memory = struct { pub const Immediate = union(enum) { signed: i32, unsigned: u64, + reloc: Symbol, pub fn u(x: u64) Immediate { return .{ .unsigned = x }; @@ -578,39 +579,19 @@ pub const Immediate = union(enum) { return .{ .signed = x }; } - pub fn asSigned(imm: Immediate, bit_size: u64) i64 { - return switch (imm) { - .signed => |x| switch (bit_size) { - 1, 8 => @as(i8, @intCast(x)), - 16 => @as(i16, @intCast(x)), - 32, 64 => x, - else => unreachable, - }, - .unsigned => |x| switch (bit_size) { - 1, 8 => @as(i8, @bitCast(@as(u8, @intCast(x)))), - 16 => @as(i16, @bitCast(@as(u16, @intCast(x)))), - 32 => @as(i32, @bitCast(@as(u32, @intCast(x)))), - 64 => @bitCast(x), - else => unreachable, - }, - }; + pub fn rel(symbol: Symbol) Immediate { + return .{ .reloc = symbol }; } - pub fn asUnsigned(imm: Immediate, bit_size: u64) u64 { - return switch (imm) { - .signed => |x| switch (bit_size) { - 1, 8 => @as(u8, @bitCast(@as(i8, @intCast(x)))), - 16 => @as(u16, @bitCast(@as(i16, @intCast(x)))), - 32, 64 => @as(u32, @bitCast(x)), - else => unreachable, - }, - .unsigned => |x| switch (bit_size) { - 1, 8 => @as(u8, @intCast(x)), - 16 => @as(u16, @intCast(x)), - 32 => @as(u32, @intCast(x)), - 64 => x, - else => unreachable, - }, - }; + pub fn format( + imm: Immediate, + comptime fmt: []const u8, + options: std.fmt.FormatOptions, + writer: anytype, + ) @TypeOf(writer).Error!void { + switch (imm) { + .reloc => |x| try std.fmt.formatType(x, fmt, options, writer, 0), + inline else => |x| try writer.print("{d}", .{x}), + } } }; diff --git a/src/arch/x86_64/encoder.zig b/src/arch/x86_64/encoder.zig index 5f49443934..b525b0e11e 100644 --- a/src/arch/x86_64/encoder.zig +++ b/src/arch/x86_64/encoder.zig @@ -7,7 +7,6 @@ const testing = std.testing; const bits = @import("bits.zig"); const Encoding = @import("Encoding.zig"); const FrameIndex = bits.FrameIndex; -const Immediate = bits.Immediate; const Register = bits.Register; const Symbol = bits.Symbol; @@ -28,6 +27,55 @@ pub const Instruction = struct { repnz, }; + pub const Immediate = union(enum) { + signed: i32, + unsigned: u64, + + pub fn u(x: u64) Immediate { + return .{ .unsigned = x }; + } + + pub fn s(x: i32) Immediate { + return .{ .signed = x }; + } + + pub fn asSigned(imm: Immediate, bit_size: u64) i64 { + return switch (imm) { + .signed => |x| switch (bit_size) { + 1, 8 => @as(i8, @intCast(x)), + 16 => @as(i16, @intCast(x)), + 32, 64 => x, + else => unreachable, + }, + .unsigned => |x| switch (bit_size) { + 1, 8 => @as(i8, @bitCast(@as(u8, @intCast(x)))), + 16 => @as(i16, @bitCast(@as(u16, @intCast(x)))), + 32 => @as(i32, @bitCast(@as(u32, @intCast(x)))), + 64 => @bitCast(x), + else => unreachable, + }, + }; + } + + pub fn asUnsigned(imm: Immediate, bit_size: u64) u64 { + return switch (imm) { + .signed => |x| switch (bit_size) { + 1, 8 => @as(u8, @bitCast(@as(i8, @intCast(x)))), + 16 => @as(u16, @bitCast(@as(i16, @intCast(x)))), + 32, 64 => @as(u32, @bitCast(x)), + else => unreachable, + }, + .unsigned => |x| switch (bit_size) { + 1, 8 => @as(u8, @intCast(x)), + 16 => @as(u16, @intCast(x)), + 32 => @as(u32, @intCast(x)), + 64 => x, + else => unreachable, + }, + }; + } + }; + pub const Memory = union(enum) { sib: Sib, rip: Rip, @@ -1119,7 +1167,7 @@ test "encode" { const inst = try Instruction.new(.none, .mov, &.{ .{ .reg = .rbx }, - .{ .imm = Immediate.u(4) }, + .{ .imm = Instruction.Immediate.u(4) }, }); try inst.encode(buf.writer(), .{}); try testing.expectEqualSlices(u8, &.{ 0x48, 0xc7, 0xc3, 0x4, 0x0, 0x0, 0x0 }, buf.items); @@ -1129,47 +1177,47 @@ test "lower I encoding" { var enc = TestEncode{}; try enc.encode(.push, &.{ - .{ .imm = Immediate.u(0x10) }, + .{ .imm = Instruction.Immediate.u(0x10) }, }); try expectEqualHexStrings("\x6A\x10", enc.code(), "push 0x10"); try enc.encode(.push, &.{ - .{ .imm = Immediate.u(0x1000) }, + .{ .imm = Instruction.Immediate.u(0x1000) }, }); try expectEqualHexStrings("\x66\x68\x00\x10", enc.code(), "push 0x1000"); try enc.encode(.push, &.{ - .{ .imm = Immediate.u(0x10000000) }, + .{ .imm = Instruction.Immediate.u(0x10000000) }, }); try expectEqualHexStrings("\x68\x00\x00\x00\x10", enc.code(), "push 0x10000000"); try enc.encode(.adc, &.{ .{ .reg = .rax }, - .{ .imm = Immediate.u(0x10000000) }, + .{ .imm = Instruction.Immediate.u(0x10000000) }, }); try expectEqualHexStrings("\x48\x15\x00\x00\x00\x10", enc.code(), "adc rax, 0x10000000"); try enc.encode(.add, &.{ .{ .reg = .al }, - .{ .imm = Immediate.u(0x10) }, + .{ .imm = Instruction.Immediate.u(0x10) }, }); try expectEqualHexStrings("\x04\x10", enc.code(), "add al, 0x10"); try enc.encode(.add, &.{ .{ .reg = .rax }, - .{ .imm = Immediate.u(0x10) }, + .{ .imm = Instruction.Immediate.u(0x10) }, }); try expectEqualHexStrings("\x48\x83\xC0\x10", enc.code(), "add rax, 0x10"); try enc.encode(.sbb, &.{ .{ .reg = .ax }, - .{ .imm = Immediate.u(0x10) }, + .{ .imm = Instruction.Immediate.u(0x10) }, }); try expectEqualHexStrings("\x66\x1D\x10\x00", enc.code(), "sbb ax, 0x10"); try enc.encode(.xor, &.{ .{ .reg = .al }, - .{ .imm = Immediate.u(0x10) }, + .{ .imm = Instruction.Immediate.u(0x10) }, }); try expectEqualHexStrings("\x34\x10", enc.code(), "xor al, 0x10"); } @@ -1179,43 +1227,43 @@ test "lower MI encoding" { try enc.encode(.mov, &.{ .{ .reg = .r12 }, - .{ .imm = Immediate.u(0x1000) }, + .{ .imm = Instruction.Immediate.u(0x1000) }, }); try expectEqualHexStrings("\x49\xC7\xC4\x00\x10\x00\x00", enc.code(), "mov r12, 0x1000"); try enc.encode(.mov, &.{ .{ .mem = Instruction.Memory.sib(.byte, .{ .base = .{ .reg = .r12 } }) }, - .{ .imm = Immediate.u(0x10) }, + .{ .imm = Instruction.Immediate.u(0x10) }, }); try expectEqualHexStrings("\x41\xC6\x04\x24\x10", enc.code(), "mov BYTE PTR [r12], 0x10"); try enc.encode(.mov, &.{ .{ .reg = .r12 }, - .{ .imm = Immediate.u(0x1000) }, + .{ .imm = Instruction.Immediate.u(0x1000) }, }); try expectEqualHexStrings("\x49\xC7\xC4\x00\x10\x00\x00", enc.code(), "mov r12, 0x1000"); try enc.encode(.mov, &.{ .{ .reg = .r12 }, - .{ .imm = Immediate.u(0x1000) }, + .{ .imm = Instruction.Immediate.u(0x1000) }, }); try expectEqualHexStrings("\x49\xC7\xC4\x00\x10\x00\x00", enc.code(), "mov r12, 0x1000"); try enc.encode(.mov, &.{ .{ .reg = .rax }, - .{ .imm = Immediate.u(0x10) }, + .{ .imm = Instruction.Immediate.u(0x10) }, }); try expectEqualHexStrings("\x48\xc7\xc0\x10\x00\x00\x00", enc.code(), "mov rax, 0x10"); try enc.encode(.mov, &.{ .{ .mem = Instruction.Memory.sib(.dword, .{ .base = .{ .reg = .r11 } }) }, - .{ .imm = Immediate.u(0x10) }, + .{ .imm = Instruction.Immediate.u(0x10) }, }); try expectEqualHexStrings("\x41\xc7\x03\x10\x00\x00\x00", enc.code(), "mov DWORD PTR [r11], 0x10"); try enc.encode(.mov, &.{ .{ .mem = Instruction.Memory.rip(.qword, 0x10) }, - .{ .imm = Immediate.u(0x10) }, + .{ .imm = Instruction.Immediate.u(0x10) }, }); try expectEqualHexStrings( "\x48\xC7\x05\x10\x00\x00\x00\x10\x00\x00\x00", @@ -1225,19 +1273,19 @@ test "lower MI encoding" { try enc.encode(.mov, &.{ .{ .mem = Instruction.Memory.sib(.qword, .{ .base = .{ .reg = .rbp }, .disp = -8 }) }, - .{ .imm = Immediate.u(0x10) }, + .{ .imm = Instruction.Immediate.u(0x10) }, }); try expectEqualHexStrings("\x48\xc7\x45\xf8\x10\x00\x00\x00", enc.code(), "mov QWORD PTR [rbp - 8], 0x10"); try enc.encode(.mov, &.{ .{ .mem = Instruction.Memory.sib(.word, .{ .base = .{ .reg = .rbp }, .disp = -2 }) }, - .{ .imm = Immediate.s(-16) }, + .{ .imm = Instruction.Immediate.s(-16) }, }); try expectEqualHexStrings("\x66\xC7\x45\xFE\xF0\xFF", enc.code(), "mov WORD PTR [rbp - 2], -16"); try enc.encode(.mov, &.{ .{ .mem = Instruction.Memory.sib(.byte, .{ .base = .{ .reg = .rbp }, .disp = -1 }) }, - .{ .imm = Immediate.u(0x10) }, + .{ .imm = Instruction.Immediate.u(0x10) }, }); try expectEqualHexStrings("\xC6\x45\xFF\x10", enc.code(), "mov BYTE PTR [rbp - 1], 0x10"); @@ -1247,7 +1295,7 @@ test "lower MI encoding" { .disp = 0x10000000, .scale_index = .{ .scale = 2, .index = .rcx }, }) }, - .{ .imm = Immediate.u(0x10) }, + .{ .imm = Instruction.Immediate.u(0x10) }, }); try expectEqualHexStrings( "\x48\xC7\x04\x4D\x00\x00\x00\x10\x10\x00\x00\x00", @@ -1257,43 +1305,43 @@ test "lower MI encoding" { try enc.encode(.adc, &.{ .{ .mem = Instruction.Memory.sib(.byte, .{ .base = .{ .reg = .rbp }, .disp = -0x10 }) }, - .{ .imm = Immediate.u(0x10) }, + .{ .imm = Instruction.Immediate.u(0x10) }, }); try expectEqualHexStrings("\x80\x55\xF0\x10", enc.code(), "adc BYTE PTR [rbp - 0x10], 0x10"); try enc.encode(.adc, &.{ .{ .mem = Instruction.Memory.rip(.qword, 0) }, - .{ .imm = Immediate.u(0x10) }, + .{ .imm = Instruction.Immediate.u(0x10) }, }); try expectEqualHexStrings("\x48\x83\x15\x00\x00\x00\x00\x10", enc.code(), "adc QWORD PTR [rip], 0x10"); try enc.encode(.adc, &.{ .{ .reg = .rax }, - .{ .imm = Immediate.u(0x10) }, + .{ .imm = Instruction.Immediate.u(0x10) }, }); try expectEqualHexStrings("\x48\x83\xD0\x10", enc.code(), "adc rax, 0x10"); try enc.encode(.add, &.{ .{ .mem = Instruction.Memory.sib(.dword, .{ .base = .{ .reg = .rdx }, .disp = -8 }) }, - .{ .imm = Immediate.u(0x10) }, + .{ .imm = Instruction.Immediate.u(0x10) }, }); try expectEqualHexStrings("\x83\x42\xF8\x10", enc.code(), "add DWORD PTR [rdx - 8], 0x10"); try enc.encode(.add, &.{ .{ .reg = .rax }, - .{ .imm = Immediate.u(0x10) }, + .{ .imm = Instruction.Immediate.u(0x10) }, }); try expectEqualHexStrings("\x48\x83\xC0\x10", enc.code(), "add rax, 0x10"); try enc.encode(.add, &.{ .{ .mem = Instruction.Memory.sib(.qword, .{ .base = .{ .reg = .rbp }, .disp = -0x10 }) }, - .{ .imm = Immediate.s(-0x10) }, + .{ .imm = Instruction.Immediate.s(-0x10) }, }); try expectEqualHexStrings("\x48\x83\x45\xF0\xF0", enc.code(), "add QWORD PTR [rbp - 0x10], -0x10"); try enc.encode(.@"and", &.{ .{ .mem = Instruction.Memory.sib(.dword, .{ .base = .{ .reg = .ds }, .disp = 0x10000000 }) }, - .{ .imm = Immediate.u(0x10) }, + .{ .imm = Instruction.Immediate.u(0x10) }, }); try expectEqualHexStrings( "\x83\x24\x25\x00\x00\x00\x10\x10", @@ -1303,7 +1351,7 @@ test "lower MI encoding" { try enc.encode(.@"and", &.{ .{ .mem = Instruction.Memory.sib(.dword, .{ .base = .{ .reg = .es }, .disp = 0x10000000 }) }, - .{ .imm = Immediate.u(0x10) }, + .{ .imm = Instruction.Immediate.u(0x10) }, }); try expectEqualHexStrings( "\x26\x83\x24\x25\x00\x00\x00\x10\x10", @@ -1313,7 +1361,7 @@ test "lower MI encoding" { try enc.encode(.@"and", &.{ .{ .mem = Instruction.Memory.sib(.dword, .{ .base = .{ .reg = .r12 }, .disp = 0x10000000 }) }, - .{ .imm = Immediate.u(0x10) }, + .{ .imm = Instruction.Immediate.u(0x10) }, }); try expectEqualHexStrings( "\x41\x83\xA4\x24\x00\x00\x00\x10\x10", @@ -1323,7 +1371,7 @@ test "lower MI encoding" { try enc.encode(.sub, &.{ .{ .mem = Instruction.Memory.sib(.dword, .{ .base = .{ .reg = .r11 }, .disp = 0x10000000 }) }, - .{ .imm = Immediate.u(0x10) }, + .{ .imm = Instruction.Immediate.u(0x10) }, }); try expectEqualHexStrings( "\x41\x83\xAB\x00\x00\x00\x10\x10", @@ -1542,14 +1590,14 @@ test "lower RMI encoding" { try enc.encode(.imul, &.{ .{ .reg = .r11 }, .{ .reg = .r12 }, - .{ .imm = Immediate.s(-2) }, + .{ .imm = Instruction.Immediate.s(-2) }, }); try expectEqualHexStrings("\x4D\x6B\xDC\xFE", enc.code(), "imul r11, r12, -2"); try enc.encode(.imul, &.{ .{ .reg = .r11 }, .{ .mem = Instruction.Memory.rip(.qword, -16) }, - .{ .imm = Immediate.s(-1024) }, + .{ .imm = Instruction.Immediate.s(-1024) }, }); try expectEqualHexStrings( "\x4C\x69\x1D\xF0\xFF\xFF\xFF\x00\xFC\xFF\xFF", @@ -1560,7 +1608,7 @@ test "lower RMI encoding" { try enc.encode(.imul, &.{ .{ .reg = .bx }, .{ .mem = Instruction.Memory.sib(.word, .{ .base = .{ .reg = .rbp }, .disp = -16 }) }, - .{ .imm = Immediate.s(-1024) }, + .{ .imm = Instruction.Immediate.s(-1024) }, }); try expectEqualHexStrings( "\x66\x69\x5D\xF0\x00\xFC", @@ -1571,7 +1619,7 @@ test "lower RMI encoding" { try enc.encode(.imul, &.{ .{ .reg = .bx }, .{ .mem = Instruction.Memory.sib(.word, .{ .base = .{ .reg = .rbp }, .disp = -16 }) }, - .{ .imm = Immediate.u(1024) }, + .{ .imm = Instruction.Immediate.u(1024) }, }); try expectEqualHexStrings( "\x66\x69\x5D\xF0\x00\x04", @@ -1687,7 +1735,7 @@ test "lower M encoding" { try expectEqualHexStrings("\x65\xFF\x14\x25\x00\x00\x00\x00", enc.code(), "call gs:0x0"); try enc.encode(.call, &.{ - .{ .imm = Immediate.s(0) }, + .{ .imm = Instruction.Immediate.s(0) }, }); try expectEqualHexStrings("\xE8\x00\x00\x00\x00", enc.code(), "call 0x0"); @@ -1746,7 +1794,7 @@ test "lower OI encoding" { try enc.encode(.mov, &.{ .{ .reg = .rax }, - .{ .imm = Immediate.u(0x1000000000000000) }, + .{ .imm = Instruction.Immediate.u(0x1000000000000000) }, }); try expectEqualHexStrings( "\x48\xB8\x00\x00\x00\x00\x00\x00\x00\x10", @@ -1756,7 +1804,7 @@ test "lower OI encoding" { try enc.encode(.mov, &.{ .{ .reg = .r11 }, - .{ .imm = Immediate.u(0x1000000000000000) }, + .{ .imm = Instruction.Immediate.u(0x1000000000000000) }, }); try expectEqualHexStrings( "\x49\xBB\x00\x00\x00\x00\x00\x00\x00\x10", @@ -1766,19 +1814,19 @@ test "lower OI encoding" { try enc.encode(.mov, &.{ .{ .reg = .r11d }, - .{ .imm = Immediate.u(0x10000000) }, + .{ .imm = Instruction.Immediate.u(0x10000000) }, }); try expectEqualHexStrings("\x41\xBB\x00\x00\x00\x10", enc.code(), "mov r11d, 0x10000000"); try enc.encode(.mov, &.{ .{ .reg = .r11w }, - .{ .imm = Immediate.u(0x1000) }, + .{ .imm = Instruction.Immediate.u(0x1000) }, }); try expectEqualHexStrings("\x66\x41\xBB\x00\x10", enc.code(), "mov r11w, 0x1000"); try enc.encode(.mov, &.{ .{ .reg = .r11b }, - .{ .imm = Immediate.u(0x10) }, + .{ .imm = Instruction.Immediate.u(0x10) }, }); try expectEqualHexStrings("\x41\xB3\x10", enc.code(), "mov r11b, 0x10"); } @@ -1900,7 +1948,7 @@ test "invalid instruction" { .{ .reg = .r12d }, }); try invalidInstruction(.push, &.{ - .{ .imm = Immediate.u(0x1000000000000000) }, + .{ .imm = Instruction.Immediate.u(0x1000000000000000) }, }); } @@ -2213,7 +2261,7 @@ const Assembler = struct { .immediate => { const is_neg = if (as.expect(.minus)) |_| true else |_| false; const imm_tok = try as.expect(.numeral); - const imm: Immediate = if (is_neg) blk: { + const imm: Instruction.Immediate = if (is_neg) blk: { const imm = try std.fmt.parseInt(i32, as.source(imm_tok), 0); break :blk .{ .signed = imm * -1 }; } else .{ .unsigned = try std.fmt.parseInt(u64, as.source(imm_tok), 0) }; diff --git a/src/link/Elf/Atom.zig b/src/link/Elf/Atom.zig index 31ba0d642e..32583b39d7 100644 --- a/src/link/Elf/Atom.zig +++ b/src/link/Elf/Atom.zig @@ -1215,12 +1215,11 @@ const x86_64 = struct { ); }, - .PLT32 => try cwriter.writeInt(i32, @as(i32, @intCast(S + A - P)), .little), - - .PC32 => { + .PLT32 => { const S_ = if (target.flags.zig_jump_table) ZJT else S; try cwriter.writeInt(i32, @as(i32, @intCast(S_ + A - P)), .little); }, + .PC32 => try cwriter.writeInt(i32, @as(i32, @intCast(S + A - P)), .little), .GOTPCREL => try cwriter.writeInt(i32, @as(i32, @intCast(G + GOT + A - P)), .little), .GOTPC32 => try cwriter.writeInt(i32, @as(i32, @intCast(GOT + A - P)), .little), @@ -1620,7 +1619,7 @@ const x86_64 = struct { const bits = @import("../../arch/x86_64/bits.zig"); const encoder = @import("../../arch/x86_64/encoder.zig"); const Disassembler = @import("../../arch/x86_64/Disassembler.zig"); - const Immediate = bits.Immediate; + const Immediate = Instruction.Immediate; const Instruction = encoder.Instruction; }; |
