authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-08-13 09:56:17+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-08-13 13:30:24+02:00
logd25c93a868585e4e2f5941fcff15fa49c90510e9
tree191902004783169c5c4fadb5a50e4af5ab87793a
parentffcf0478fe646569465ac509b3e60faadd9b3697

x86_64: emit call rel32 for near calls with linker reloc


7 files changed, 138 insertions(+), 118 deletions(-)

src/arch/x86_64/CodeGen.zig+26-34
...@@ -1379,14 +1379,19 @@ fn asmImmediate(self: *Self, tag: Mir.Inst.FixedTag, imm: Immediate) !void {...@@ -1379,14 +1379,19 @@ fn asmImmediate(self: *Self, tag: Mir.Inst.FixedTag, imm: Immediate) !void {
1379 .ops = switch (imm) {1379 .ops = switch (imm) {
1380 .signed => .i_s,1380 .signed => .i_s,
1381 .unsigned => .i_u,1381 .unsigned => .i_u,
1382 .reloc => .rel,
1383 },
1384 .data = switch (imm) {
1385 .reloc => |x| .{ .reloc = x },
1386 .signed, .unsigned => .{ .i = .{
1387 .fixes = tag[0],
1388 .i = switch (imm) {
1389 .signed => |s| @bitCast(s),
1390 .unsigned => |u| @intCast(u),
1391 .reloc => unreachable,
1392 },
1393 } },
1382 },1394 },
1383 .data = .{ .i = .{
1384 .fixes = tag[0],
1385 .i = switch (imm) {
1386 .signed => |s| @bitCast(s),
1387 .unsigned => |u| @intCast(u),
1388 },
1389 } },
1390 });1395 });
1391}1396}
13921397
...@@ -1406,6 +1411,7 @@ fn asmRegisterImmediate(self: *Self, tag: Mir.Inst.FixedTag, reg: Register, imm:...@@ -1406,6 +1411,7 @@ fn asmRegisterImmediate(self: *Self, tag: Mir.Inst.FixedTag, reg: Register, imm:
1406 const ops: Mir.Inst.Ops = switch (imm) {1411 const ops: Mir.Inst.Ops = switch (imm) {
1407 .signed => .ri_s,1412 .signed => .ri_s,
1408 .unsigned => |u| if (math.cast(u32, u)) |_| .ri_u else .ri64,1413 .unsigned => |u| if (math.cast(u32, u)) |_| .ri_u else .ri64,
1414 .reloc => unreachable,
1409 };1415 };
1410 _ = try self.addInst(.{1416 _ = try self.addInst(.{
1411 .tag = tag[1],1417 .tag = tag[1],
...@@ -1417,6 +1423,7 @@ fn asmRegisterImmediate(self: *Self, tag: Mir.Inst.FixedTag, reg: Register, imm:...@@ -1417,6 +1423,7 @@ fn asmRegisterImmediate(self: *Self, tag: Mir.Inst.FixedTag, reg: Register, imm:
1417 .i = switch (imm) {1423 .i = switch (imm) {
1418 .signed => |s| @bitCast(s),1424 .signed => |s| @bitCast(s),
1419 .unsigned => |u| @intCast(u),1425 .unsigned => |u| @intCast(u),
1426 .reloc => unreachable,
1420 },1427 },
1421 } },1428 } },
1422 .ri64 => .{ .rx = .{1429 .ri64 => .{ .rx = .{
...@@ -1488,6 +1495,7 @@ fn asmRegisterRegisterRegisterImmediate(...@@ -1488,6 +1495,7 @@ fn asmRegisterRegisterRegisterImmediate(
1488 .i = switch (imm) {1495 .i = switch (imm) {
1489 .signed => |s| @bitCast(@as(i8, @intCast(s))),1496 .signed => |s| @bitCast(@as(i8, @intCast(s))),
1490 .unsigned => |u| @intCast(u),1497 .unsigned => |u| @intCast(u),
1498 .reloc => unreachable,
1491 },1499 },
1492 } },1500 } },
1493 });1501 });
...@@ -1505,6 +1513,7 @@ fn asmRegisterRegisterImmediate(...@@ -1505,6 +1513,7 @@ fn asmRegisterRegisterImmediate(
1505 .ops = switch (imm) {1513 .ops = switch (imm) {
1506 .signed => .rri_s,1514 .signed => .rri_s,
1507 .unsigned => .rri_u,1515 .unsigned => .rri_u,
1516 .reloc => unreachable,
1508 },1517 },
1509 .data = .{ .rri = .{1518 .data = .{ .rri = .{
1510 .fixes = tag[0],1519 .fixes = tag[0],
...@@ -1513,6 +1522,7 @@ fn asmRegisterRegisterImmediate(...@@ -1513,6 +1522,7 @@ fn asmRegisterRegisterImmediate(
1513 .i = switch (imm) {1522 .i = switch (imm) {
1514 .signed => |s| @bitCast(s),1523 .signed => |s| @bitCast(s),
1515 .unsigned => |u| @intCast(u),1524 .unsigned => |u| @intCast(u),
1525 .reloc => unreachable,
1516 },1526 },
1517 } },1527 } },
1518 });1528 });
...@@ -1610,6 +1620,7 @@ fn asmRegisterMemoryImmediate(...@@ -1610,6 +1620,7 @@ fn asmRegisterMemoryImmediate(
1610 if (switch (imm) {1620 if (switch (imm) {
1611 .signed => |s| if (math.cast(i16, s)) |x| @as(u16, @bitCast(x)) else null,1621 .signed => |s| if (math.cast(i16, s)) |x| @as(u16, @bitCast(x)) else null,
1612 .unsigned => |u| math.cast(u16, u),1622 .unsigned => |u| math.cast(u16, u),
1623 .reloc => unreachable,
1613 }) |small_imm| {1624 }) |small_imm| {
1614 _ = try self.addInst(.{1625 _ = try self.addInst(.{
1615 .tag = tag[1],1626 .tag = tag[1],
...@@ -1625,6 +1636,7 @@ fn asmRegisterMemoryImmediate(...@@ -1625,6 +1636,7 @@ fn asmRegisterMemoryImmediate(
1625 const payload = try self.addExtra(Mir.Imm32{ .imm = switch (imm) {1636 const payload = try self.addExtra(Mir.Imm32{ .imm = switch (imm) {
1626 .signed => |s| @bitCast(s),1637 .signed => |s| @bitCast(s),
1627 .unsigned => unreachable,1638 .unsigned => unreachable,
1639 .reloc => unreachable,
1628 } });1640 } });
1629 assert(payload + 1 == try self.addExtra(Mir.Memory.encode(m)));1641 assert(payload + 1 == try self.addExtra(Mir.Memory.encode(m)));
1630 _ = try self.addInst(.{1642 _ = try self.addInst(.{
...@@ -1632,6 +1644,7 @@ fn asmRegisterMemoryImmediate(...@@ -1632,6 +1644,7 @@ fn asmRegisterMemoryImmediate(
1632 .ops = switch (imm) {1644 .ops = switch (imm) {
1633 .signed => .rmi_s,1645 .signed => .rmi_s,
1634 .unsigned => .rmi_u,1646 .unsigned => .rmi_u,
1647 .reloc => unreachable,
1635 },1648 },
1636 .data = .{ .rx = .{1649 .data = .{ .rx = .{
1637 .fixes = tag[0],1650 .fixes = tag[0],
...@@ -1679,6 +1692,7 @@ fn asmMemoryImmediate(self: *Self, tag: Mir.Inst.FixedTag, m: Memory, imm: Immed...@@ -1679,6 +1692,7 @@ fn asmMemoryImmediate(self: *Self, tag: Mir.Inst.FixedTag, m: Memory, imm: Immed
1679 const payload = try self.addExtra(Mir.Imm32{ .imm = switch (imm) {1692 const payload = try self.addExtra(Mir.Imm32{ .imm = switch (imm) {
1680 .signed => |s| @bitCast(s),1693 .signed => |s| @bitCast(s),
1681 .unsigned => |u| @intCast(u),1694 .unsigned => |u| @intCast(u),
1695 .reloc => unreachable,
1682 } });1696 } });
1683 assert(payload + 1 == try self.addExtra(Mir.Memory.encode(m)));1697 assert(payload + 1 == try self.addExtra(Mir.Memory.encode(m)));
1684 _ = try self.addInst(.{1698 _ = try self.addInst(.{
...@@ -1686,6 +1700,7 @@ fn asmMemoryImmediate(self: *Self, tag: Mir.Inst.FixedTag, m: Memory, imm: Immed...@@ -1686,6 +1700,7 @@ fn asmMemoryImmediate(self: *Self, tag: Mir.Inst.FixedTag, m: Memory, imm: Immed
1686 .ops = switch (imm) {1700 .ops = switch (imm) {
1687 .signed => .mi_s,1701 .signed => .mi_s,
1688 .unsigned => .mi_u,1702 .unsigned => .mi_u,
1703 .reloc => unreachable,
1689 },1704 },
1690 .data = .{ .x = .{1705 .data = .{ .x = .{
1691 .fixes = tag[0],1706 .fixes = tag[0],
...@@ -12310,33 +12325,10 @@ fn genCall(self: *Self, info: union(enum) {...@@ -12310,33 +12325,10 @@ fn genCall(self: *Self, info: union(enum) {
12310 if (self.bin_file.cast(.elf)) |elf_file| {12325 if (self.bin_file.cast(.elf)) |elf_file| {
12311 const zo = elf_file.zigObjectPtr().?;12326 const zo = elf_file.zigObjectPtr().?;
12312 const sym_index = try zo.getOrCreateMetadataForNav(elf_file, func.owner_nav);12327 const sym_index = try zo.getOrCreateMetadataForNav(elf_file, func.owner_nav);
12313 if (self.mod.pic) {12328 try self.asmImmediate(.{ ._, .call }, Immediate.rel(.{
12314 const callee_reg: Register = switch (resolved_cc) {12329 .atom_index = try self.owner.getSymbolIndex(self),
12315 .SysV => callee: {12330 .sym_index = sym_index,
12316 if (!fn_info.is_var_args) break :callee .rax;12331 }));
12317 const param_regs = abi.getCAbiIntParamRegs(resolved_cc);
12318 break :callee if (call_info.gp_count < param_regs.len)
12319 param_regs[call_info.gp_count]
12320 else
12321 .r10;
12322 },
12323 .Win64 => .rax,
12324 else => unreachable,
12325 };
12326 try self.genSetReg(
12327 callee_reg,
12328 Type.usize,
12329 .{ .lea_symbol = .{ .sym = sym_index } },
12330 .{},
12331 );
12332 try self.asmRegister(.{ ._, .call }, callee_reg);
12333 } else try self.asmMemory(.{ ._, .call }, .{
12334 .base = .{ .reloc = .{
12335 .atom_index = try self.owner.getSymbolIndex(self),
12336 .sym_index = sym_index,
12337 } },
12338 .mod = .{ .rm = .{ .size = .qword } },
12339 });
12340 } else if (self.bin_file.cast(.coff)) |coff_file| {12332 } else if (self.bin_file.cast(.coff)) |coff_file| {
12341 const atom = try coff_file.getOrCreateAtomForNav(func.owner_nav);12333 const atom = try coff_file.getOrCreateAtomForNav(func.owner_nav);
12342 const sym_index = coff_file.getAtom(atom).getSymbolIndex().?;12334 const sym_index = coff_file.getAtom(atom).getSymbolIndex().?;
src/arch/x86_64/Disassembler.zig+1-1
...@@ -8,7 +8,7 @@ const bits = @import("bits.zig");...@@ -8,7 +8,7 @@ const bits = @import("bits.zig");
8const encoder = @import("encoder.zig");8const encoder = @import("encoder.zig");
99
10const Encoding = @import("Encoding.zig");10const Encoding = @import("Encoding.zig");
11const Immediate = bits.Immediate;11const Immediate = Instruction.Immediate;
12const Instruction = encoder.Instruction;12const Instruction = encoder.Instruction;
13const LegacyPrefixes = encoder.LegacyPrefixes;13const LegacyPrefixes = encoder.LegacyPrefixes;
14const Memory = Instruction.Memory;14const Memory = Instruction.Memory;
src/arch/x86_64/Lower.zig+3-3
...@@ -475,7 +475,7 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void {...@@ -475,7 +475,7 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void {
475 .rrmi => inst.data.rrix.fixes,475 .rrmi => inst.data.rrix.fixes,
476 .mi_u, .mi_s => inst.data.x.fixes,476 .mi_u, .mi_s => inst.data.x.fixes,
477 .m => inst.data.x.fixes,477 .m => inst.data.x.fixes,
478 .extern_fn_reloc, .got_reloc, .direct_reloc, .import_reloc, .tlv_reloc => ._,478 .extern_fn_reloc, .got_reloc, .direct_reloc, .import_reloc, .tlv_reloc, .rel => ._,
479 else => return lower.fail("TODO lower .{s}", .{@tagName(inst.ops)}),479 else => return lower.fail("TODO lower .{s}", .{@tagName(inst.ops)}),
480 };480 };
481 try lower.emit(switch (fixes) {481 try lower.emit(switch (fixes) {
...@@ -607,7 +607,7 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void {...@@ -607,7 +607,7 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void {
607 .{ .mem = lower.mem(inst.data.rrix.payload) },607 .{ .mem = lower.mem(inst.data.rrix.payload) },
608 .{ .imm = lower.imm(inst.ops, inst.data.rrix.i) },608 .{ .imm = lower.imm(inst.ops, inst.data.rrix.i) },
609 },609 },
610 .extern_fn_reloc => &.{610 .extern_fn_reloc, .rel => &.{
611 .{ .imm = lower.reloc(.{ .linker_extern_fn = inst.data.reloc }) },611 .{ .imm = lower.reloc(.{ .linker_extern_fn = inst.data.reloc }) },
612 },612 },
613 .got_reloc, .direct_reloc, .import_reloc => ops: {613 .got_reloc, .direct_reloc, .import_reloc => ops: {
...@@ -650,7 +650,7 @@ const std = @import("std");...@@ -650,7 +650,7 @@ const std = @import("std");
650const Air = @import("../../Air.zig");650const Air = @import("../../Air.zig");
651const Allocator = std.mem.Allocator;651const Allocator = std.mem.Allocator;
652const ErrorMsg = Zcu.ErrorMsg;652const ErrorMsg = Zcu.ErrorMsg;
653const Immediate = bits.Immediate;653const Immediate = Instruction.Immediate;
654const Instruction = encoder.Instruction;654const Instruction = encoder.Instruction;
655const Lower = @This();655const Lower = @This();
656const Memory = Instruction.Memory;656const Memory = Instruction.Memory;
src/arch/x86_64/Mir.zig+1-1
...@@ -769,7 +769,7 @@ pub const Inst = struct {...@@ -769,7 +769,7 @@ pub const Inst = struct {
769 /// Uses `imm` payload.769 /// Uses `imm` payload.
770 i_u,770 i_u,
771 /// Relative displacement operand.771 /// Relative displacement operand.
772 /// Uses `imm` payload.772 /// Uses `reloc` payload.
773 rel,773 rel,
774 /// Register, memory operands.774 /// Register, memory operands.
775 /// Uses `rx` payload with extra data of type `Memory`.775 /// Uses `rx` payload with extra data of type `Memory`.
src/arch/x86_64/bits.zig+13-32
...@@ -569,6 +569,7 @@ pub const Memory = struct {...@@ -569,6 +569,7 @@ pub const Memory = struct {
569pub const Immediate = union(enum) {569pub const Immediate = union(enum) {
570 signed: i32,570 signed: i32,
571 unsigned: u64,571 unsigned: u64,
572 reloc: Symbol,
572573
573 pub fn u(x: u64) Immediate {574 pub fn u(x: u64) Immediate {
574 return .{ .unsigned = x };575 return .{ .unsigned = x };
...@@ -578,39 +579,19 @@ pub const Immediate = union(enum) {...@@ -578,39 +579,19 @@ pub const Immediate = union(enum) {
578 return .{ .signed = x };579 return .{ .signed = x };
579 }580 }
580581
581 pub fn asSigned(imm: Immediate, bit_size: u64) i64 {582 pub fn rel(symbol: Symbol) Immediate {
582 return switch (imm) {583 return .{ .reloc = symbol };
583 .signed => |x| switch (bit_size) {
584 1, 8 => @as(i8, @intCast(x)),
585 16 => @as(i16, @intCast(x)),
586 32, 64 => x,
587 else => unreachable,
588 },
589 .unsigned => |x| switch (bit_size) {
590 1, 8 => @as(i8, @bitCast(@as(u8, @intCast(x)))),
591 16 => @as(i16, @bitCast(@as(u16, @intCast(x)))),
592 32 => @as(i32, @bitCast(@as(u32, @intCast(x)))),
593 64 => @bitCast(x),
594 else => unreachable,
595 },
596 };
597 }584 }
598585
599 pub fn asUnsigned(imm: Immediate, bit_size: u64) u64 {586 pub fn format(
600 return switch (imm) {587 imm: Immediate,
601 .signed => |x| switch (bit_size) {588 comptime fmt: []const u8,
602 1, 8 => @as(u8, @bitCast(@as(i8, @intCast(x)))),589 options: std.fmt.FormatOptions,
603 16 => @as(u16, @bitCast(@as(i16, @intCast(x)))),590 writer: anytype,
604 32, 64 => @as(u32, @bitCast(x)),591 ) @TypeOf(writer).Error!void {
605 else => unreachable,592 switch (imm) {
606 },593 .reloc => |x| try std.fmt.formatType(x, fmt, options, writer, 0),
607 .unsigned => |x| switch (bit_size) {594 inline else => |x| try writer.print("{d}", .{x}),
608 1, 8 => @as(u8, @intCast(x)),595 }
609 16 => @as(u16, @intCast(x)),
610 32 => @as(u32, @intCast(x)),
611 64 => x,
612 else => unreachable,
613 },
614 };
615 }596 }
616};597};
src/arch/x86_64/encoder.zig+91-43
...@@ -7,7 +7,6 @@ const testing = std.testing;...@@ -7,7 +7,6 @@ const testing = std.testing;
7const bits = @import("bits.zig");7const bits = @import("bits.zig");
8const Encoding = @import("Encoding.zig");8const Encoding = @import("Encoding.zig");
9const FrameIndex = bits.FrameIndex;9const FrameIndex = bits.FrameIndex;
10const Immediate = bits.Immediate;
11const Register = bits.Register;10const Register = bits.Register;
12const Symbol = bits.Symbol;11const Symbol = bits.Symbol;
1312
...@@ -28,6 +27,55 @@ pub const Instruction = struct {...@@ -28,6 +27,55 @@ pub const Instruction = struct {
28 repnz,27 repnz,
29 };28 };
3029
30 pub const Immediate = union(enum) {
31 signed: i32,
32 unsigned: u64,
33
34 pub fn u(x: u64) Immediate {
35 return .{ .unsigned = x };
36 }
37
38 pub fn s(x: i32) Immediate {
39 return .{ .signed = x };
40 }
41
42 pub fn asSigned(imm: Immediate, bit_size: u64) i64 {
43 return switch (imm) {
44 .signed => |x| switch (bit_size) {
45 1, 8 => @as(i8, @intCast(x)),
46 16 => @as(i16, @intCast(x)),
47 32, 64 => x,
48 else => unreachable,
49 },
50 .unsigned => |x| switch (bit_size) {
51 1, 8 => @as(i8, @bitCast(@as(u8, @intCast(x)))),
52 16 => @as(i16, @bitCast(@as(u16, @intCast(x)))),
53 32 => @as(i32, @bitCast(@as(u32, @intCast(x)))),
54 64 => @bitCast(x),
55 else => unreachable,
56 },
57 };
58 }
59
60 pub fn asUnsigned(imm: Immediate, bit_size: u64) u64 {
61 return switch (imm) {
62 .signed => |x| switch (bit_size) {
63 1, 8 => @as(u8, @bitCast(@as(i8, @intCast(x)))),
64 16 => @as(u16, @bitCast(@as(i16, @intCast(x)))),
65 32, 64 => @as(u32, @bitCast(x)),
66 else => unreachable,
67 },
68 .unsigned => |x| switch (bit_size) {
69 1, 8 => @as(u8, @intCast(x)),
70 16 => @as(u16, @intCast(x)),
71 32 => @as(u32, @intCast(x)),
72 64 => x,
73 else => unreachable,
74 },
75 };
76 }
77 };
78
31 pub const Memory = union(enum) {79 pub const Memory = union(enum) {
32 sib: Sib,80 sib: Sib,
33 rip: Rip,81 rip: Rip,
...@@ -1119,7 +1167,7 @@ test "encode" {...@@ -1119,7 +1167,7 @@ test "encode" {
11191167
1120 const inst = try Instruction.new(.none, .mov, &.{1168 const inst = try Instruction.new(.none, .mov, &.{
1121 .{ .reg = .rbx },1169 .{ .reg = .rbx },
1122 .{ .imm = Immediate.u(4) },1170 .{ .imm = Instruction.Immediate.u(4) },
1123 });1171 });
1124 try inst.encode(buf.writer(), .{});1172 try inst.encode(buf.writer(), .{});
1125 try testing.expectEqualSlices(u8, &.{ 0x48, 0xc7, 0xc3, 0x4, 0x0, 0x0, 0x0 }, buf.items);1173 try testing.expectEqualSlices(u8, &.{ 0x48, 0xc7, 0xc3, 0x4, 0x0, 0x0, 0x0 }, buf.items);
...@@ -1129,47 +1177,47 @@ test "lower I encoding" {...@@ -1129,47 +1177,47 @@ test "lower I encoding" {
1129 var enc = TestEncode{};1177 var enc = TestEncode{};
11301178
1131 try enc.encode(.push, &.{1179 try enc.encode(.push, &.{
1132 .{ .imm = Immediate.u(0x10) },1180 .{ .imm = Instruction.Immediate.u(0x10) },
1133 });1181 });
1134 try expectEqualHexStrings("\x6A\x10", enc.code(), "push 0x10");1182 try expectEqualHexStrings("\x6A\x10", enc.code(), "push 0x10");
11351183
1136 try enc.encode(.push, &.{1184 try enc.encode(.push, &.{
1137 .{ .imm = Immediate.u(0x1000) },1185 .{ .imm = Instruction.Immediate.u(0x1000) },
1138 });1186 });
1139 try expectEqualHexStrings("\x66\x68\x00\x10", enc.code(), "push 0x1000");1187 try expectEqualHexStrings("\x66\x68\x00\x10", enc.code(), "push 0x1000");
11401188
1141 try enc.encode(.push, &.{1189 try enc.encode(.push, &.{
1142 .{ .imm = Immediate.u(0x10000000) },1190 .{ .imm = Instruction.Immediate.u(0x10000000) },
1143 });1191 });
1144 try expectEqualHexStrings("\x68\x00\x00\x00\x10", enc.code(), "push 0x10000000");1192 try expectEqualHexStrings("\x68\x00\x00\x00\x10", enc.code(), "push 0x10000000");
11451193
1146 try enc.encode(.adc, &.{1194 try enc.encode(.adc, &.{
1147 .{ .reg = .rax },1195 .{ .reg = .rax },
1148 .{ .imm = Immediate.u(0x10000000) },1196 .{ .imm = Instruction.Immediate.u(0x10000000) },
1149 });1197 });
1150 try expectEqualHexStrings("\x48\x15\x00\x00\x00\x10", enc.code(), "adc rax, 0x10000000");1198 try expectEqualHexStrings("\x48\x15\x00\x00\x00\x10", enc.code(), "adc rax, 0x10000000");
11511199
1152 try enc.encode(.add, &.{1200 try enc.encode(.add, &.{
1153 .{ .reg = .al },1201 .{ .reg = .al },
1154 .{ .imm = Immediate.u(0x10) },1202 .{ .imm = Instruction.Immediate.u(0x10) },
1155 });1203 });
1156 try expectEqualHexStrings("\x04\x10", enc.code(), "add al, 0x10");1204 try expectEqualHexStrings("\x04\x10", enc.code(), "add al, 0x10");
11571205
1158 try enc.encode(.add, &.{1206 try enc.encode(.add, &.{
1159 .{ .reg = .rax },1207 .{ .reg = .rax },
1160 .{ .imm = Immediate.u(0x10) },1208 .{ .imm = Instruction.Immediate.u(0x10) },
1161 });1209 });
1162 try expectEqualHexStrings("\x48\x83\xC0\x10", enc.code(), "add rax, 0x10");1210 try expectEqualHexStrings("\x48\x83\xC0\x10", enc.code(), "add rax, 0x10");
11631211
1164 try enc.encode(.sbb, &.{1212 try enc.encode(.sbb, &.{
1165 .{ .reg = .ax },1213 .{ .reg = .ax },
1166 .{ .imm = Immediate.u(0x10) },1214 .{ .imm = Instruction.Immediate.u(0x10) },
1167 });1215 });
1168 try expectEqualHexStrings("\x66\x1D\x10\x00", enc.code(), "sbb ax, 0x10");1216 try expectEqualHexStrings("\x66\x1D\x10\x00", enc.code(), "sbb ax, 0x10");
11691217
1170 try enc.encode(.xor, &.{1218 try enc.encode(.xor, &.{
1171 .{ .reg = .al },1219 .{ .reg = .al },
1172 .{ .imm = Immediate.u(0x10) },1220 .{ .imm = Instruction.Immediate.u(0x10) },
1173 });1221 });
1174 try expectEqualHexStrings("\x34\x10", enc.code(), "xor al, 0x10");1222 try expectEqualHexStrings("\x34\x10", enc.code(), "xor al, 0x10");
1175}1223}
...@@ -1179,43 +1227,43 @@ test "lower MI encoding" {...@@ -1179,43 +1227,43 @@ test "lower MI encoding" {
11791227
1180 try enc.encode(.mov, &.{1228 try enc.encode(.mov, &.{
1181 .{ .reg = .r12 },1229 .{ .reg = .r12 },
1182 .{ .imm = Immediate.u(0x1000) },1230 .{ .imm = Instruction.Immediate.u(0x1000) },
1183 });1231 });
1184 try expectEqualHexStrings("\x49\xC7\xC4\x00\x10\x00\x00", enc.code(), "mov r12, 0x1000");1232 try expectEqualHexStrings("\x49\xC7\xC4\x00\x10\x00\x00", enc.code(), "mov r12, 0x1000");
11851233
1186 try enc.encode(.mov, &.{1234 try enc.encode(.mov, &.{
1187 .{ .mem = Instruction.Memory.sib(.byte, .{ .base = .{ .reg = .r12 } }) },1235 .{ .mem = Instruction.Memory.sib(.byte, .{ .base = .{ .reg = .r12 } }) },
1188 .{ .imm = Immediate.u(0x10) },1236 .{ .imm = Instruction.Immediate.u(0x10) },
1189 });1237 });
1190 try expectEqualHexStrings("\x41\xC6\x04\x24\x10", enc.code(), "mov BYTE PTR [r12], 0x10");1238 try expectEqualHexStrings("\x41\xC6\x04\x24\x10", enc.code(), "mov BYTE PTR [r12], 0x10");
11911239
1192 try enc.encode(.mov, &.{1240 try enc.encode(.mov, &.{
1193 .{ .reg = .r12 },1241 .{ .reg = .r12 },
1194 .{ .imm = Immediate.u(0x1000) },1242 .{ .imm = Instruction.Immediate.u(0x1000) },
1195 });1243 });
1196 try expectEqualHexStrings("\x49\xC7\xC4\x00\x10\x00\x00", enc.code(), "mov r12, 0x1000");1244 try expectEqualHexStrings("\x49\xC7\xC4\x00\x10\x00\x00", enc.code(), "mov r12, 0x1000");
11971245
1198 try enc.encode(.mov, &.{1246 try enc.encode(.mov, &.{
1199 .{ .reg = .r12 },1247 .{ .reg = .r12 },
1200 .{ .imm = Immediate.u(0x1000) },1248 .{ .imm = Instruction.Immediate.u(0x1000) },
1201 });1249 });
1202 try expectEqualHexStrings("\x49\xC7\xC4\x00\x10\x00\x00", enc.code(), "mov r12, 0x1000");1250 try expectEqualHexStrings("\x49\xC7\xC4\x00\x10\x00\x00", enc.code(), "mov r12, 0x1000");
12031251
1204 try enc.encode(.mov, &.{1252 try enc.encode(.mov, &.{
1205 .{ .reg = .rax },1253 .{ .reg = .rax },
1206 .{ .imm = Immediate.u(0x10) },1254 .{ .imm = Instruction.Immediate.u(0x10) },
1207 });1255 });
1208 try expectEqualHexStrings("\x48\xc7\xc0\x10\x00\x00\x00", enc.code(), "mov rax, 0x10");1256 try expectEqualHexStrings("\x48\xc7\xc0\x10\x00\x00\x00", enc.code(), "mov rax, 0x10");
12091257
1210 try enc.encode(.mov, &.{1258 try enc.encode(.mov, &.{
1211 .{ .mem = Instruction.Memory.sib(.dword, .{ .base = .{ .reg = .r11 } }) },1259 .{ .mem = Instruction.Memory.sib(.dword, .{ .base = .{ .reg = .r11 } }) },
1212 .{ .imm = Immediate.u(0x10) },1260 .{ .imm = Instruction.Immediate.u(0x10) },
1213 });1261 });
1214 try expectEqualHexStrings("\x41\xc7\x03\x10\x00\x00\x00", enc.code(), "mov DWORD PTR [r11], 0x10");1262 try expectEqualHexStrings("\x41\xc7\x03\x10\x00\x00\x00", enc.code(), "mov DWORD PTR [r11], 0x10");
12151263
1216 try enc.encode(.mov, &.{1264 try enc.encode(.mov, &.{
1217 .{ .mem = Instruction.Memory.rip(.qword, 0x10) },1265 .{ .mem = Instruction.Memory.rip(.qword, 0x10) },
1218 .{ .imm = Immediate.u(0x10) },1266 .{ .imm = Instruction.Immediate.u(0x10) },
1219 });1267 });
1220 try expectEqualHexStrings(1268 try expectEqualHexStrings(
1221 "\x48\xC7\x05\x10\x00\x00\x00\x10\x00\x00\x00",1269 "\x48\xC7\x05\x10\x00\x00\x00\x10\x00\x00\x00",
...@@ -1225,19 +1273,19 @@ test "lower MI encoding" {...@@ -1225,19 +1273,19 @@ test "lower MI encoding" {
12251273
1226 try enc.encode(.mov, &.{1274 try enc.encode(.mov, &.{
1227 .{ .mem = Instruction.Memory.sib(.qword, .{ .base = .{ .reg = .rbp }, .disp = -8 }) },1275 .{ .mem = Instruction.Memory.sib(.qword, .{ .base = .{ .reg = .rbp }, .disp = -8 }) },
1228 .{ .imm = Immediate.u(0x10) },1276 .{ .imm = Instruction.Immediate.u(0x10) },
1229 });1277 });
1230 try expectEqualHexStrings("\x48\xc7\x45\xf8\x10\x00\x00\x00", enc.code(), "mov QWORD PTR [rbp - 8], 0x10");1278 try expectEqualHexStrings("\x48\xc7\x45\xf8\x10\x00\x00\x00", enc.code(), "mov QWORD PTR [rbp - 8], 0x10");
12311279
1232 try enc.encode(.mov, &.{1280 try enc.encode(.mov, &.{
1233 .{ .mem = Instruction.Memory.sib(.word, .{ .base = .{ .reg = .rbp }, .disp = -2 }) },1281 .{ .mem = Instruction.Memory.sib(.word, .{ .base = .{ .reg = .rbp }, .disp = -2 }) },
1234 .{ .imm = Immediate.s(-16) },1282 .{ .imm = Instruction.Immediate.s(-16) },
1235 });1283 });
1236 try expectEqualHexStrings("\x66\xC7\x45\xFE\xF0\xFF", enc.code(), "mov WORD PTR [rbp - 2], -16");1284 try expectEqualHexStrings("\x66\xC7\x45\xFE\xF0\xFF", enc.code(), "mov WORD PTR [rbp - 2], -16");
12371285
1238 try enc.encode(.mov, &.{1286 try enc.encode(.mov, &.{
1239 .{ .mem = Instruction.Memory.sib(.byte, .{ .base = .{ .reg = .rbp }, .disp = -1 }) },1287 .{ .mem = Instruction.Memory.sib(.byte, .{ .base = .{ .reg = .rbp }, .disp = -1 }) },
1240 .{ .imm = Immediate.u(0x10) },1288 .{ .imm = Instruction.Immediate.u(0x10) },
1241 });1289 });
1242 try expectEqualHexStrings("\xC6\x45\xFF\x10", enc.code(), "mov BYTE PTR [rbp - 1], 0x10");1290 try expectEqualHexStrings("\xC6\x45\xFF\x10", enc.code(), "mov BYTE PTR [rbp - 1], 0x10");
12431291
...@@ -1247,7 +1295,7 @@ test "lower MI encoding" {...@@ -1247,7 +1295,7 @@ test "lower MI encoding" {
1247 .disp = 0x10000000,1295 .disp = 0x10000000,
1248 .scale_index = .{ .scale = 2, .index = .rcx },1296 .scale_index = .{ .scale = 2, .index = .rcx },
1249 }) },1297 }) },
1250 .{ .imm = Immediate.u(0x10) },1298 .{ .imm = Instruction.Immediate.u(0x10) },
1251 });1299 });
1252 try expectEqualHexStrings(1300 try expectEqualHexStrings(
1253 "\x48\xC7\x04\x4D\x00\x00\x00\x10\x10\x00\x00\x00",1301 "\x48\xC7\x04\x4D\x00\x00\x00\x10\x10\x00\x00\x00",
...@@ -1257,43 +1305,43 @@ test "lower MI encoding" {...@@ -1257,43 +1305,43 @@ test "lower MI encoding" {
12571305
1258 try enc.encode(.adc, &.{1306 try enc.encode(.adc, &.{
1259 .{ .mem = Instruction.Memory.sib(.byte, .{ .base = .{ .reg = .rbp }, .disp = -0x10 }) },1307 .{ .mem = Instruction.Memory.sib(.byte, .{ .base = .{ .reg = .rbp }, .disp = -0x10 }) },
1260 .{ .imm = Immediate.u(0x10) },1308 .{ .imm = Instruction.Immediate.u(0x10) },
1261 });1309 });
1262 try expectEqualHexStrings("\x80\x55\xF0\x10", enc.code(), "adc BYTE PTR [rbp - 0x10], 0x10");1310 try expectEqualHexStrings("\x80\x55\xF0\x10", enc.code(), "adc BYTE PTR [rbp - 0x10], 0x10");
12631311
1264 try enc.encode(.adc, &.{1312 try enc.encode(.adc, &.{
1265 .{ .mem = Instruction.Memory.rip(.qword, 0) },1313 .{ .mem = Instruction.Memory.rip(.qword, 0) },
1266 .{ .imm = Immediate.u(0x10) },1314 .{ .imm = Instruction.Immediate.u(0x10) },
1267 });1315 });
1268 try expectEqualHexStrings("\x48\x83\x15\x00\x00\x00\x00\x10", enc.code(), "adc QWORD PTR [rip], 0x10");1316 try expectEqualHexStrings("\x48\x83\x15\x00\x00\x00\x00\x10", enc.code(), "adc QWORD PTR [rip], 0x10");
12691317
1270 try enc.encode(.adc, &.{1318 try enc.encode(.adc, &.{
1271 .{ .reg = .rax },1319 .{ .reg = .rax },
1272 .{ .imm = Immediate.u(0x10) },1320 .{ .imm = Instruction.Immediate.u(0x10) },
1273 });1321 });
1274 try expectEqualHexStrings("\x48\x83\xD0\x10", enc.code(), "adc rax, 0x10");1322 try expectEqualHexStrings("\x48\x83\xD0\x10", enc.code(), "adc rax, 0x10");
12751323
1276 try enc.encode(.add, &.{1324 try enc.encode(.add, &.{
1277 .{ .mem = Instruction.Memory.sib(.dword, .{ .base = .{ .reg = .rdx }, .disp = -8 }) },1325 .{ .mem = Instruction.Memory.sib(.dword, .{ .base = .{ .reg = .rdx }, .disp = -8 }) },
1278 .{ .imm = Immediate.u(0x10) },1326 .{ .imm = Instruction.Immediate.u(0x10) },
1279 });1327 });
1280 try expectEqualHexStrings("\x83\x42\xF8\x10", enc.code(), "add DWORD PTR [rdx - 8], 0x10");1328 try expectEqualHexStrings("\x83\x42\xF8\x10", enc.code(), "add DWORD PTR [rdx - 8], 0x10");
12811329
1282 try enc.encode(.add, &.{1330 try enc.encode(.add, &.{
1283 .{ .reg = .rax },1331 .{ .reg = .rax },
1284 .{ .imm = Immediate.u(0x10) },1332 .{ .imm = Instruction.Immediate.u(0x10) },
1285 });1333 });
1286 try expectEqualHexStrings("\x48\x83\xC0\x10", enc.code(), "add rax, 0x10");1334 try expectEqualHexStrings("\x48\x83\xC0\x10", enc.code(), "add rax, 0x10");
12871335
1288 try enc.encode(.add, &.{1336 try enc.encode(.add, &.{
1289 .{ .mem = Instruction.Memory.sib(.qword, .{ .base = .{ .reg = .rbp }, .disp = -0x10 }) },1337 .{ .mem = Instruction.Memory.sib(.qword, .{ .base = .{ .reg = .rbp }, .disp = -0x10 }) },
1290 .{ .imm = Immediate.s(-0x10) },1338 .{ .imm = Instruction.Immediate.s(-0x10) },
1291 });1339 });
1292 try expectEqualHexStrings("\x48\x83\x45\xF0\xF0", enc.code(), "add QWORD PTR [rbp - 0x10], -0x10");1340 try expectEqualHexStrings("\x48\x83\x45\xF0\xF0", enc.code(), "add QWORD PTR [rbp - 0x10], -0x10");
12931341
1294 try enc.encode(.@"and", &.{1342 try enc.encode(.@"and", &.{
1295 .{ .mem = Instruction.Memory.sib(.dword, .{ .base = .{ .reg = .ds }, .disp = 0x10000000 }) },1343 .{ .mem = Instruction.Memory.sib(.dword, .{ .base = .{ .reg = .ds }, .disp = 0x10000000 }) },
1296 .{ .imm = Immediate.u(0x10) },1344 .{ .imm = Instruction.Immediate.u(0x10) },
1297 });1345 });
1298 try expectEqualHexStrings(1346 try expectEqualHexStrings(
1299 "\x83\x24\x25\x00\x00\x00\x10\x10",1347 "\x83\x24\x25\x00\x00\x00\x10\x10",
...@@ -1303,7 +1351,7 @@ test "lower MI encoding" {...@@ -1303,7 +1351,7 @@ test "lower MI encoding" {
13031351
1304 try enc.encode(.@"and", &.{1352 try enc.encode(.@"and", &.{
1305 .{ .mem = Instruction.Memory.sib(.dword, .{ .base = .{ .reg = .es }, .disp = 0x10000000 }) },1353 .{ .mem = Instruction.Memory.sib(.dword, .{ .base = .{ .reg = .es }, .disp = 0x10000000 }) },
1306 .{ .imm = Immediate.u(0x10) },1354 .{ .imm = Instruction.Immediate.u(0x10) },
1307 });1355 });
1308 try expectEqualHexStrings(1356 try expectEqualHexStrings(
1309 "\x26\x83\x24\x25\x00\x00\x00\x10\x10",1357 "\x26\x83\x24\x25\x00\x00\x00\x10\x10",
...@@ -1313,7 +1361,7 @@ test "lower MI encoding" {...@@ -1313,7 +1361,7 @@ test "lower MI encoding" {
13131361
1314 try enc.encode(.@"and", &.{1362 try enc.encode(.@"and", &.{
1315 .{ .mem = Instruction.Memory.sib(.dword, .{ .base = .{ .reg = .r12 }, .disp = 0x10000000 }) },1363 .{ .mem = Instruction.Memory.sib(.dword, .{ .base = .{ .reg = .r12 }, .disp = 0x10000000 }) },
1316 .{ .imm = Immediate.u(0x10) },1364 .{ .imm = Instruction.Immediate.u(0x10) },
1317 });1365 });
1318 try expectEqualHexStrings(1366 try expectEqualHexStrings(
1319 "\x41\x83\xA4\x24\x00\x00\x00\x10\x10",1367 "\x41\x83\xA4\x24\x00\x00\x00\x10\x10",
...@@ -1323,7 +1371,7 @@ test "lower MI encoding" {...@@ -1323,7 +1371,7 @@ test "lower MI encoding" {
13231371
1324 try enc.encode(.sub, &.{1372 try enc.encode(.sub, &.{
1325 .{ .mem = Instruction.Memory.sib(.dword, .{ .base = .{ .reg = .r11 }, .disp = 0x10000000 }) },1373 .{ .mem = Instruction.Memory.sib(.dword, .{ .base = .{ .reg = .r11 }, .disp = 0x10000000 }) },
1326 .{ .imm = Immediate.u(0x10) },1374 .{ .imm = Instruction.Immediate.u(0x10) },
1327 });1375 });
1328 try expectEqualHexStrings(1376 try expectEqualHexStrings(
1329 "\x41\x83\xAB\x00\x00\x00\x10\x10",1377 "\x41\x83\xAB\x00\x00\x00\x10\x10",
...@@ -1542,14 +1590,14 @@ test "lower RMI encoding" {...@@ -1542,14 +1590,14 @@ test "lower RMI encoding" {
1542 try enc.encode(.imul, &.{1590 try enc.encode(.imul, &.{
1543 .{ .reg = .r11 },1591 .{ .reg = .r11 },
1544 .{ .reg = .r12 },1592 .{ .reg = .r12 },
1545 .{ .imm = Immediate.s(-2) },1593 .{ .imm = Instruction.Immediate.s(-2) },
1546 });1594 });
1547 try expectEqualHexStrings("\x4D\x6B\xDC\xFE", enc.code(), "imul r11, r12, -2");1595 try expectEqualHexStrings("\x4D\x6B\xDC\xFE", enc.code(), "imul r11, r12, -2");
15481596
1549 try enc.encode(.imul, &.{1597 try enc.encode(.imul, &.{
1550 .{ .reg = .r11 },1598 .{ .reg = .r11 },
1551 .{ .mem = Instruction.Memory.rip(.qword, -16) },1599 .{ .mem = Instruction.Memory.rip(.qword, -16) },
1552 .{ .imm = Immediate.s(-1024) },1600 .{ .imm = Instruction.Immediate.s(-1024) },
1553 });1601 });
1554 try expectEqualHexStrings(1602 try expectEqualHexStrings(
1555 "\x4C\x69\x1D\xF0\xFF\xFF\xFF\x00\xFC\xFF\xFF",1603 "\x4C\x69\x1D\xF0\xFF\xFF\xFF\x00\xFC\xFF\xFF",
...@@ -1560,7 +1608,7 @@ test "lower RMI encoding" {...@@ -1560,7 +1608,7 @@ test "lower RMI encoding" {
1560 try enc.encode(.imul, &.{1608 try enc.encode(.imul, &.{
1561 .{ .reg = .bx },1609 .{ .reg = .bx },
1562 .{ .mem = Instruction.Memory.sib(.word, .{ .base = .{ .reg = .rbp }, .disp = -16 }) },1610 .{ .mem = Instruction.Memory.sib(.word, .{ .base = .{ .reg = .rbp }, .disp = -16 }) },
1563 .{ .imm = Immediate.s(-1024) },1611 .{ .imm = Instruction.Immediate.s(-1024) },
1564 });1612 });
1565 try expectEqualHexStrings(1613 try expectEqualHexStrings(
1566 "\x66\x69\x5D\xF0\x00\xFC",1614 "\x66\x69\x5D\xF0\x00\xFC",
...@@ -1571,7 +1619,7 @@ test "lower RMI encoding" {...@@ -1571,7 +1619,7 @@ test "lower RMI encoding" {
1571 try enc.encode(.imul, &.{1619 try enc.encode(.imul, &.{
1572 .{ .reg = .bx },1620 .{ .reg = .bx },
1573 .{ .mem = Instruction.Memory.sib(.word, .{ .base = .{ .reg = .rbp }, .disp = -16 }) },1621 .{ .mem = Instruction.Memory.sib(.word, .{ .base = .{ .reg = .rbp }, .disp = -16 }) },
1574 .{ .imm = Immediate.u(1024) },1622 .{ .imm = Instruction.Immediate.u(1024) },
1575 });1623 });
1576 try expectEqualHexStrings(1624 try expectEqualHexStrings(
1577 "\x66\x69\x5D\xF0\x00\x04",1625 "\x66\x69\x5D\xF0\x00\x04",
...@@ -1687,7 +1735,7 @@ test "lower M encoding" {...@@ -1687,7 +1735,7 @@ test "lower M encoding" {
1687 try expectEqualHexStrings("\x65\xFF\x14\x25\x00\x00\x00\x00", enc.code(), "call gs:0x0");1735 try expectEqualHexStrings("\x65\xFF\x14\x25\x00\x00\x00\x00", enc.code(), "call gs:0x0");
16881736
1689 try enc.encode(.call, &.{1737 try enc.encode(.call, &.{
1690 .{ .imm = Immediate.s(0) },1738 .{ .imm = Instruction.Immediate.s(0) },
1691 });1739 });
1692 try expectEqualHexStrings("\xE8\x00\x00\x00\x00", enc.code(), "call 0x0");1740 try expectEqualHexStrings("\xE8\x00\x00\x00\x00", enc.code(), "call 0x0");
16931741
...@@ -1746,7 +1794,7 @@ test "lower OI encoding" {...@@ -1746,7 +1794,7 @@ test "lower OI encoding" {
17461794
1747 try enc.encode(.mov, &.{1795 try enc.encode(.mov, &.{
1748 .{ .reg = .rax },1796 .{ .reg = .rax },
1749 .{ .imm = Immediate.u(0x1000000000000000) },1797 .{ .imm = Instruction.Immediate.u(0x1000000000000000) },
1750 });1798 });
1751 try expectEqualHexStrings(1799 try expectEqualHexStrings(
1752 "\x48\xB8\x00\x00\x00\x00\x00\x00\x00\x10",1800 "\x48\xB8\x00\x00\x00\x00\x00\x00\x00\x10",
...@@ -1756,7 +1804,7 @@ test "lower OI encoding" {...@@ -1756,7 +1804,7 @@ test "lower OI encoding" {
17561804
1757 try enc.encode(.mov, &.{1805 try enc.encode(.mov, &.{
1758 .{ .reg = .r11 },1806 .{ .reg = .r11 },
1759 .{ .imm = Immediate.u(0x1000000000000000) },1807 .{ .imm = Instruction.Immediate.u(0x1000000000000000) },
1760 });1808 });
1761 try expectEqualHexStrings(1809 try expectEqualHexStrings(
1762 "\x49\xBB\x00\x00\x00\x00\x00\x00\x00\x10",1810 "\x49\xBB\x00\x00\x00\x00\x00\x00\x00\x10",
...@@ -1766,19 +1814,19 @@ test "lower OI encoding" {...@@ -1766,19 +1814,19 @@ test "lower OI encoding" {
17661814
1767 try enc.encode(.mov, &.{1815 try enc.encode(.mov, &.{
1768 .{ .reg = .r11d },1816 .{ .reg = .r11d },
1769 .{ .imm = Immediate.u(0x10000000) },1817 .{ .imm = Instruction.Immediate.u(0x10000000) },
1770 });1818 });
1771 try expectEqualHexStrings("\x41\xBB\x00\x00\x00\x10", enc.code(), "mov r11d, 0x10000000");1819 try expectEqualHexStrings("\x41\xBB\x00\x00\x00\x10", enc.code(), "mov r11d, 0x10000000");
17721820
1773 try enc.encode(.mov, &.{1821 try enc.encode(.mov, &.{
1774 .{ .reg = .r11w },1822 .{ .reg = .r11w },
1775 .{ .imm = Immediate.u(0x1000) },1823 .{ .imm = Instruction.Immediate.u(0x1000) },
1776 });1824 });
1777 try expectEqualHexStrings("\x66\x41\xBB\x00\x10", enc.code(), "mov r11w, 0x1000");1825 try expectEqualHexStrings("\x66\x41\xBB\x00\x10", enc.code(), "mov r11w, 0x1000");
17781826
1779 try enc.encode(.mov, &.{1827 try enc.encode(.mov, &.{
1780 .{ .reg = .r11b },1828 .{ .reg = .r11b },
1781 .{ .imm = Immediate.u(0x10) },1829 .{ .imm = Instruction.Immediate.u(0x10) },
1782 });1830 });
1783 try expectEqualHexStrings("\x41\xB3\x10", enc.code(), "mov r11b, 0x10");1831 try expectEqualHexStrings("\x41\xB3\x10", enc.code(), "mov r11b, 0x10");
1784}1832}
...@@ -1900,7 +1948,7 @@ test "invalid instruction" {...@@ -1900,7 +1948,7 @@ test "invalid instruction" {
1900 .{ .reg = .r12d },1948 .{ .reg = .r12d },
1901 });1949 });
1902 try invalidInstruction(.push, &.{1950 try invalidInstruction(.push, &.{
1903 .{ .imm = Immediate.u(0x1000000000000000) },1951 .{ .imm = Instruction.Immediate.u(0x1000000000000000) },
1904 });1952 });
1905}1953}
19061954
...@@ -2213,7 +2261,7 @@ const Assembler = struct {...@@ -2213,7 +2261,7 @@ const Assembler = struct {
2213 .immediate => {2261 .immediate => {
2214 const is_neg = if (as.expect(.minus)) |_| true else |_| false;2262 const is_neg = if (as.expect(.minus)) |_| true else |_| false;
2215 const imm_tok = try as.expect(.numeral);2263 const imm_tok = try as.expect(.numeral);
2216 const imm: Immediate = if (is_neg) blk: {2264 const imm: Instruction.Immediate = if (is_neg) blk: {
2217 const imm = try std.fmt.parseInt(i32, as.source(imm_tok), 0);2265 const imm = try std.fmt.parseInt(i32, as.source(imm_tok), 0);
2218 break :blk .{ .signed = imm * -1 };2266 break :blk .{ .signed = imm * -1 };
2219 } else .{ .unsigned = try std.fmt.parseInt(u64, as.source(imm_tok), 0) };2267 } else .{ .unsigned = try std.fmt.parseInt(u64, as.source(imm_tok), 0) };
src/link/Elf/Atom.zig+3-4
...@@ -1215,12 +1215,11 @@ const x86_64 = struct {...@@ -1215,12 +1215,11 @@ const x86_64 = struct {
1215 );1215 );
1216 },1216 },
12171217
1218 .PLT32 => try cwriter.writeInt(i32, @as(i32, @intCast(S + A - P)), .little),1218 .PLT32 => {
1219
1220 .PC32 => {
1221 const S_ = if (target.flags.zig_jump_table) ZJT else S;1219 const S_ = if (target.flags.zig_jump_table) ZJT else S;
1222 try cwriter.writeInt(i32, @as(i32, @intCast(S_ + A - P)), .little);1220 try cwriter.writeInt(i32, @as(i32, @intCast(S_ + A - P)), .little);
1223 },1221 },
1222 .PC32 => try cwriter.writeInt(i32, @as(i32, @intCast(S + A - P)), .little),
12241223
1225 .GOTPCREL => try cwriter.writeInt(i32, @as(i32, @intCast(G + GOT + A - P)), .little),1224 .GOTPCREL => try cwriter.writeInt(i32, @as(i32, @intCast(G + GOT + A - P)), .little),
1226 .GOTPC32 => try cwriter.writeInt(i32, @as(i32, @intCast(GOT + A - P)), .little),1225 .GOTPC32 => try cwriter.writeInt(i32, @as(i32, @intCast(GOT + A - P)), .little),
...@@ -1620,7 +1619,7 @@ const x86_64 = struct {...@@ -1620,7 +1619,7 @@ const x86_64 = struct {
1620 const bits = @import("../../arch/x86_64/bits.zig");1619 const bits = @import("../../arch/x86_64/bits.zig");
1621 const encoder = @import("../../arch/x86_64/encoder.zig");1620 const encoder = @import("../../arch/x86_64/encoder.zig");
1622 const Disassembler = @import("../../arch/x86_64/Disassembler.zig");1621 const Disassembler = @import("../../arch/x86_64/Disassembler.zig");
1623 const Immediate = bits.Immediate;1622 const Immediate = Instruction.Immediate;
1624 const Instruction = encoder.Instruction;1623 const Instruction = encoder.Instruction;
1625};1624};
16261625