authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-01-17 22:38:21-05:00
committergravatar for jacobly.alt@gmail.comJacob Young <jacobly.alt@gmail.com> 2025-01-18 23:30:45-05:00
log8ee80d61f6b2355f590de9722172b93a55c4f563
tree3400c87dbd32371af5144d3153ba31af0dda5346
parentdb8ed730e7500812f1f40729e2ead081107546ce

x86_64: add a bunch of instruction encodings

Closes #19773

9 files changed, 1675 insertions(+), 491 deletions(-)

lib/std/zig/system/x86.zig+1
......@@ -419,6 +419,7 @@ fn detectNativeFeatures(cpu: *Target.Cpu, os_tag: Target.Os.Tag) void {
419419 // detecting features using the "-march=native" flag.
420420 // For more info, see X86 ISA docs.
421421 setFeature(cpu, .pconfig, bit(leaf.edx, 18));
422 setFeature(cpu, .uintr, bit(leaf.edx, 5));
422423
423424 // TODO I feel unsure about this check.
424425 // It doesn't really seem to check for 7.1, just for 7.
src/arch/x86_64/CodeGen.zig+260-190
......@@ -1375,6 +1375,14 @@ fn asmOps(self: *CodeGen, tag: Mir.Inst.FixedTag, ops: [4]Operand) !void {
13751375 },
13761376 .imm => |imm0| switch (ops[1]) {
13771377 .none => self.asmImmediate(tag, imm0),
1378 .reg => |reg1| switch (ops[2]) {
1379 .none => self.asmImmediateRegister(tag, imm0, reg1),
1380 else => error.InvalidInstruction,
1381 },
1382 .imm => |imm1| switch (ops[2]) {
1383 .none => self.asmImmediateImmediate(tag, imm0, imm1),
1384 else => error.InvalidInstruction,
1385 },
13781386 else => error.InvalidInstruction,
13791387 },
13801388 .inst => |inst0| switch (ops[1]) {
......@@ -1491,9 +1499,10 @@ fn asmSetccMemory(self: *CodeGen, cc: Condition, m: Memory) !void {
14911499
14921500fn asmJmpReloc(self: *CodeGen, target: Mir.Inst.Index) !Mir.Inst.Index {
14931501 return self.addInst(.{
1494 .tag = .jmp,
1502 .tag = .j,
14951503 .ops = .inst,
14961504 .data = .{ .inst = .{
1505 .fixes = ._mp,
14971506 .inst = target,
14981507 } },
14991508 });
......@@ -1753,6 +1762,42 @@ fn asmImmediate(self: *CodeGen, tag: Mir.Inst.FixedTag, imm: Immediate) !void {
17531762 });
17541763}
17551764
1765fn asmImmediateRegister(self: *CodeGen, tag: Mir.Inst.FixedTag, imm: Immediate, reg: Register) !void {
1766 _ = try self.addInst(.{
1767 .tag = tag[1],
1768 .ops = .ir,
1769 .data = .{ .ri = .{
1770 .fixes = tag[0],
1771 .r1 = reg,
1772 .i = @as(u8, switch (imm) {
1773 .signed => |s| @bitCast(@as(i8, @intCast(s))),
1774 .unsigned => |u| @intCast(u),
1775 .reloc => unreachable,
1776 }),
1777 } },
1778 });
1779}
1780
1781fn asmImmediateImmediate(self: *CodeGen, tag: Mir.Inst.FixedTag, imm1: Immediate, imm2: Immediate) !void {
1782 _ = try self.addInst(.{
1783 .tag = tag[1],
1784 .ops = .ii,
1785 .data = .{ .ii = .{
1786 .fixes = tag[0],
1787 .i1 = switch (imm1) {
1788 .signed => |s| @bitCast(@as(i16, @intCast(s))),
1789 .unsigned => |u| @intCast(u),
1790 .reloc => unreachable,
1791 },
1792 .i2 = switch (imm2) {
1793 .signed => |s| @bitCast(@as(i8, @intCast(s))),
1794 .unsigned => |u| @intCast(u),
1795 .reloc => unreachable,
1796 },
1797 } },
1798 });
1799}
1800
17561801fn asmRegisterRegister(self: *CodeGen, tag: Mir.Inst.FixedTag, reg1: Register, reg2: Register) !void {
17571802 _ = try self.addInst(.{
17581803 .tag = tag[1],
......@@ -4188,8 +4233,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
41884233 _ = try cg.asmJmpReloc(loop.target);
41894234 },
41904235 .br => try cg.airBr(inst),
4191 .trap => try cg.asmOpOnly(.{ ._, .ud2 }),
4192 .breakpoint => try cg.asmOpOnly(.{ ._, .int3 }),
4236 .trap => try cg.asmOpOnly(.{ ._2, .ud }),
4237 .breakpoint => try cg.asmOpOnly(.{ ._3, .int }),
41934238 .ret_addr => if (use_old) try cg.airRetAddr(inst) else {
41944239 var slot = try cg.tempInit(.usize, .{ .load_frame = .{
41954240 .index = .ret_addr,
......@@ -4233,7 +4278,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
42334278 .dst_temps = .{.{ .ref = .src0 }},
42344279 .clobbers = .{ .eflags = true },
42354280 .each = .{ .once = &.{
4236 .{ ._, ._, .inc, .dst0b, ._, ._, ._ },
4281 .{ ._, ._c, .in, .dst0b, ._, ._, ._ },
42374282 } },
42384283 }, .{
42394284 .src_constraints = .{ .{ .exact_unsigned_int = 1 }, .any },
......@@ -5643,7 +5688,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
56435688 .{ ._, ._, .lzcnt, .tmp1d, .tmp1d, ._, ._ },
56445689 .{ ._, ._, .sub, .tmp1b, .sia(32, .src0, .sub_bit_size), ._, ._ },
56455690 .{ ._, ._, .mov, .memia(.dst0b, .tmp0, .add_len), .tmp1b, ._, ._ },
5646 .{ ._, ._, .inc, .tmp0p, ._, ._, ._ },
5691 .{ ._, ._c, .in, .tmp0p, ._, ._, ._ },
56475692 .{ ._, ._nz, .j, .@"0b", ._, ._, ._ },
56485693 } },
56495694 }, .{
......@@ -5695,7 +5740,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
56955740 .{ ._, ._, .lzcnt, .tmp1d, .tmp1d, ._, ._ },
56965741 .{ ._, ._, .sub, .tmp1b, .sia(32, .src0, .sub_bit_size), ._, ._ },
56975742 .{ ._, ._, .mov, .memia(.dst0b, .tmp0, .add_len), .tmp1b, ._, ._ },
5698 .{ ._, ._, .inc, .tmp0p, ._, ._, ._ },
5743 .{ ._, ._c, .in, .tmp0p, ._, ._, ._ },
56995744 .{ ._, ._nz, .j, .@"0b", ._, ._, ._ },
57005745 } },
57015746 }, .{
......@@ -5747,7 +5792,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
57475792 .{ ._, ._, .lzcnt, .tmp1d, .tmp1d, ._, ._ },
57485793 .{ ._, ._, .sub, .tmp1b, .sia(32, .src0, .sub_bit_size), ._, ._ },
57495794 .{ ._, ._, .mov, .memia(.dst0b, .tmp0, .add_len), .tmp1b, ._, ._ },
5750 .{ ._, ._, .inc, .tmp0p, ._, ._, ._ },
5795 .{ ._, ._c, .in, .tmp0p, ._, ._, ._ },
57515796 .{ ._, ._nz, .j, .@"0b", ._, ._, ._ },
57525797 } },
57535798 }, .{
......@@ -5799,7 +5844,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
57995844 .{ ._, ._, .lzcnt, .tmp1q, .tmp1q, ._, ._ },
58005845 .{ ._, ._, .sub, .tmp1b, .sia(64, .src0, .sub_bit_size), ._, ._ },
58015846 .{ ._, ._, .mov, .memia(.dst0b, .tmp0, .add_len), .tmp1b, ._, ._ },
5802 .{ ._, ._, .inc, .tmp0p, ._, ._, ._ },
5847 .{ ._, ._c, .in, .tmp0p, ._, ._, ._ },
58035848 .{ ._, ._nz, .j, .@"0b", ._, ._, ._ },
58045849 } },
58055850 }, .{
......@@ -5857,7 +5902,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
58575902 .{ ._, ._, .mov, .tmp3b, .sia(-1, .src0, .add_bit_size), ._, ._ },
58585903 .{ ._, ._, .sub, .tmp3b, .tmp2b, ._, ._ },
58595904 .{ ._, ._, .mov, .memia(.dst0b, .tmp0, .add_len), .tmp3b, ._, ._ },
5860 .{ ._, ._, .inc, .tmp0p, ._, ._, ._ },
5905 .{ ._, ._c, .in, .tmp0p, ._, ._, ._ },
58615906 .{ ._, ._nz, .j, .@"0b", ._, ._, ._ },
58625907 } },
58635908 }, .{
......@@ -5915,7 +5960,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
59155960 .{ ._, ._c, .st, ._, ._, ._, ._ },
59165961 .{ ._, ._, .sbb, .tmp2b, .tmp1b, ._, ._ },
59175962 .{ .@"1:", ._, .mov, .memia(.dst0b, .tmp0, .add_len), .tmp2b, ._, ._ },
5918 .{ ._, ._, .inc, .tmp0p, ._, ._, ._ },
5963 .{ ._, ._c, .in, .tmp0p, ._, ._, ._ },
59195964 .{ ._, ._nz, .j, .@"0b", ._, ._, ._ },
59205965 } },
59215966 }, .{
......@@ -5970,7 +6015,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
59706015 .{ ._, ._, .mov, .tmp1b, .sia(-1, .src0, .add_bit_size), ._, ._ },
59716016 .{ ._, ._, .sub, .tmp1b, .tmp2b, ._, ._ },
59726017 .{ ._, ._, .mov, .memia(.dst0b, .tmp0, .add_len), .tmp1b, ._, ._ },
5973 .{ ._, ._, .inc, .tmp0p, ._, ._, ._ },
6018 .{ ._, ._c, .in, .tmp0p, ._, ._, ._ },
59746019 .{ ._, ._nz, .j, .@"0b", ._, ._, ._ },
59756020 } },
59766021 }, .{
......@@ -6028,7 +6073,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
60286073 .{ ._, ._, .mov, .tmp3b, .sia(-1, .src0, .add_bit_size), ._, ._ },
60296074 .{ ._, ._, .sub, .tmp3b, .tmp2b, ._, ._ },
60306075 .{ ._, ._, .mov, .memia(.dst0b, .tmp0, .add_len), .tmp3b, ._, ._ },
6031 .{ ._, ._, .inc, .tmp0p, ._, ._, ._ },
6076 .{ ._, ._c, .in, .tmp0p, ._, ._, ._ },
60326077 .{ ._, ._nz, .j, .@"0b", ._, ._, ._ },
60336078 } },
60346079 }, .{
......@@ -6086,7 +6131,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
60866131 .{ ._, ._c, .st, ._, ._, ._, ._ },
60876132 .{ ._, ._, .sbb, .tmp2b, .tmp1b, ._, ._ },
60886133 .{ .@"1:", ._, .mov, .memia(.dst0b, .tmp0, .add_len), .tmp2b, ._, ._ },
6089 .{ ._, ._, .inc, .tmp0p, ._, ._, ._ },
6134 .{ ._, ._c, .in, .tmp0p, ._, ._, ._ },
60906135 .{ ._, ._nz, .j, .@"0b", ._, ._, ._ },
60916136 } },
60926137 }, .{
......@@ -6141,7 +6186,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
61416186 .{ ._, ._, .mov, .tmp1b, .sia(-1, .src0, .add_bit_size), ._, ._ },
61426187 .{ ._, ._, .sub, .tmp1b, .tmp2b, ._, ._ },
61436188 .{ ._, ._, .mov, .memia(.dst0b, .tmp0, .add_len), .tmp1b, ._, ._ },
6144 .{ ._, ._, .inc, .tmp0p, ._, ._, ._ },
6189 .{ ._, ._c, .in, .tmp0p, ._, ._, ._ },
61456190 .{ ._, ._nz, .j, .@"0b", ._, ._, ._ },
61466191 } },
61476192 }, .{
......@@ -6199,7 +6244,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
61996244 .{ ._, ._, .mov, .tmp3b, .sia(-1, .src0, .add_bit_size), ._, ._ },
62006245 .{ ._, ._, .sub, .tmp3b, .tmp2b, ._, ._ },
62016246 .{ ._, ._, .mov, .memia(.dst0b, .tmp0, .add_len), .tmp3b, ._, ._ },
6202 .{ ._, ._, .inc, .tmp0p, ._, ._, ._ },
6247 .{ ._, ._c, .in, .tmp0p, ._, ._, ._ },
62036248 .{ ._, ._nz, .j, .@"0b", ._, ._, ._ },
62046249 } },
62056250 }, .{
......@@ -6257,7 +6302,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
62576302 .{ ._, ._c, .st, ._, ._, ._, ._ },
62586303 .{ ._, ._, .sbb, .tmp2b, .tmp1b, ._, ._ },
62596304 .{ .@"1:", ._, .mov, .memia(.dst0b, .tmp0, .add_len), .tmp2b, ._, ._ },
6260 .{ ._, ._, .inc, .tmp0p, ._, ._, ._ },
6305 .{ ._, ._c, .in, .tmp0p, ._, ._, ._ },
62616306 .{ ._, ._nz, .j, .@"0b", ._, ._, ._ },
62626307 } },
62636308 }, .{
......@@ -6312,7 +6357,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
63126357 .{ ._, ._, .mov, .tmp1b, .sia(-1, .src0, .add_bit_size), ._, ._ },
63136358 .{ ._, ._, .sub, .tmp1b, .tmp2b, ._, ._ },
63146359 .{ ._, ._, .mov, .memia(.dst0b, .tmp0, .add_len), .tmp1b, ._, ._ },
6315 .{ ._, ._, .inc, .tmp0p, ._, ._, ._ },
6360 .{ ._, ._c, .in, .tmp0p, ._, ._, ._ },
63166361 .{ ._, ._nz, .j, .@"0b", ._, ._, ._ },
63176362 } },
63186363 }, .{
......@@ -6370,7 +6415,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
63706415 .{ ._, ._, .mov, .tmp3b, .sia(-1, .src0, .add_bit_size), ._, ._ },
63716416 .{ ._, ._, .sub, .tmp3b, .tmp2b, ._, ._ },
63726417 .{ ._, ._, .mov, .memia(.dst0b, .tmp0, .add_len), .tmp3b, ._, ._ },
6373 .{ ._, ._, .inc, .tmp0p, ._, ._, ._ },
6418 .{ ._, ._c, .in, .tmp0p, ._, ._, ._ },
63746419 .{ ._, ._nz, .j, .@"0b", ._, ._, ._ },
63756420 } },
63766421 }, .{
......@@ -6428,7 +6473,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
64286473 .{ ._, ._c, .st, ._, ._, ._, ._ },
64296474 .{ ._, ._, .sbb, .tmp2b, .tmp1b, ._, ._ },
64306475 .{ .@"1:", ._, .mov, .memia(.dst0b, .tmp0, .add_len), .tmp2b, ._, ._ },
6431 .{ ._, ._, .inc, .tmp0p, ._, ._, ._ },
6476 .{ ._, ._c, .in, .tmp0p, ._, ._, ._ },
64326477 .{ ._, ._nz, .j, .@"0b", ._, ._, ._ },
64336478 } },
64346479 }, .{
......@@ -6484,7 +6529,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
64846529 .{ ._, ._, .mov, .tmp1b, .sia(-1, .src0, .add_bit_size), ._, ._ },
64856530 .{ ._, ._, .sub, .tmp1b, .tmp2b, ._, ._ },
64866531 .{ ._, ._, .mov, .memia(.dst0b, .tmp0, .add_len), .tmp1b, ._, ._ },
6487 .{ ._, ._, .inc, .tmp0p, ._, ._, ._ },
6532 .{ ._, ._c, .in, .tmp0p, ._, ._, ._ },
64886533 .{ ._, ._nz, .j, .@"0b", ._, ._, ._ },
64896534 } },
64906535 }, .{
......@@ -10094,7 +10139,7 @@ fn genLazy(self: *CodeGen, lazy_sym: link.File.LazySymbol) InnerError!void {
1009410139 data_off += @intCast(tag_name_len + 1);
1009510140 }
1009610141
10097 try self.asmOpOnly(.{ ._, .ud2 });
10142 try self.asmOpOnly(.{ ._2, .ud });
1009810143
1009910144 for (epilogue_relocs) |reloc| self.performReloc(reloc);
1010010145 try self.asmOpOnly(.{ ._, .ret });
......@@ -10373,7 +10418,7 @@ fn regClassForType(self: *CodeGen, ty: Type) Register.Class {
1037310418fn regSetForRegClass(rc: Register.Class) RegisterManager.RegisterBitSet {
1037410419 return switch (rc) {
1037510420 .general_purpose => abi.RegisterClass.gp,
10376 .segment, .ip => unreachable,
10421 .segment, .ip, .cr, .dr => unreachable,
1037710422 .x87 => abi.RegisterClass.x87,
1037810423 .mmx => @panic("TODO"),
1037910424 .sse => abi.RegisterClass.sse,
......@@ -12195,8 +12240,8 @@ fn airMulWithOverflow(self: *CodeGen, inst: Air.Inst.Index) !void {
1219512240 try self.asmRegisterImmediate(.{ ._, .add }, temp_regs[2].to32(), .u(1));
1219612241 try self.asmRegisterImmediate(.{ ._, .add }, temp_regs[3].to32(), .u(1));
1219712242 } else {
12198 try self.asmRegister(.{ ._, .inc }, temp_regs[2].to32());
12199 try self.asmRegister(.{ ._, .inc }, temp_regs[3].to32());
12243 try self.asmRegister(.{ ._c, .in }, temp_regs[2].to32());
12244 try self.asmRegister(.{ ._c, .in }, temp_regs[3].to32());
1220012245 }
1220112246 try self.asmRegisterImmediate(.{ ._, .cmp }, temp_regs[3].to32(), .u(limb_len));
1220212247 _ = try self.asmJccReloc(.b, inner_loop);
......@@ -12209,7 +12254,7 @@ fn airMulWithOverflow(self: *CodeGen, inst: Air.Inst.Index) !void {
1220912254 if (slow_inc) {
1221012255 try self.asmRegisterImmediate(.{ ._, .add }, temp_regs[2].to32(), .u(1));
1221112256 } else {
12212 try self.asmRegister(.{ ._, .inc }, temp_regs[2].to32());
12257 try self.asmRegister(.{ ._c, .in }, temp_regs[2].to32());
1221312258 }
1221412259 try self.asmMemoryImmediate(.{ ._, .cmp }, .{
1221512260 .base = .{ .frame = lhs_mcv.load_frame.index },
......@@ -12236,7 +12281,7 @@ fn airMulWithOverflow(self: *CodeGen, inst: Air.Inst.Index) !void {
1223612281 if (slow_inc) {
1223712282 try self.asmRegisterImmediate(.{ ._, .add }, temp_regs[0].to32(), .u(1));
1223812283 } else {
12239 try self.asmRegister(.{ ._, .inc }, temp_regs[0].to32());
12284 try self.asmRegister(.{ ._c, .in }, temp_regs[0].to32());
1224012285 }
1224112286 try self.asmRegisterImmediate(.{ ._, .cmp }, temp_regs[0].to32(), .u(limb_len));
1224212287 _ = try self.asmJccReloc(.b, outer_loop);
......@@ -13938,7 +13983,7 @@ fn airClz(self: *CodeGen, inst: Air.Inst.Index) !void {
1393813983 if (self.hasFeature(.slow_incdec)) {
1393913984 try self.asmRegisterImmediate(.{ ._, .sub }, index_reg.to32(), .u(1));
1394013985 } else {
13941 try self.asmRegister(.{ ._, .dec }, index_reg.to32());
13986 try self.asmRegister(.{ ._c, .de }, index_reg.to32());
1394213987 }
1394313988 try self.asmMemoryImmediate(.{ ._, .cmp }, .{
1394413989 .base = .{ .frame = src_frame_addr.index },
......@@ -14133,7 +14178,7 @@ fn airCtz(self: *CodeGen, inst: Air.Inst.Index) !void {
1413314178 if (self.hasFeature(.slow_incdec)) {
1413414179 try self.asmRegisterImmediate(.{ ._, .add }, index_reg.to32(), .u(1));
1413514180 } else {
14136 try self.asmRegister(.{ ._, .inc }, index_reg.to32());
14181 try self.asmRegister(.{ ._c, .in }, index_reg.to32());
1413714182 }
1413814183 try self.asmRegisterImmediate(.{ ._, .cmp }, index_reg.to32(), .u(limbs_len));
1413914184 const zero = try self.asmJccReloc(.nb, undefined);
......@@ -14535,8 +14580,8 @@ fn genByteSwap(
1453514580 try self.asmRegisterImmediate(.{ ._, .add }, temp_regs[0].to32(), .u(1));
1453614581 try self.asmRegisterImmediate(.{ ._, .sub }, temp_regs[1].to32(), .u(1));
1453714582 } else {
14538 try self.asmRegister(.{ ._, .inc }, temp_regs[0].to32());
14539 try self.asmRegister(.{ ._, .dec }, temp_regs[1].to32());
14583 try self.asmRegister(.{ ._c, .in }, temp_regs[0].to32());
14584 try self.asmRegister(.{ ._c, .de }, temp_regs[1].to32());
1454014585 }
1454114586 try self.asmRegisterRegister(.{ ._, .cmp }, temp_regs[0].to32(), temp_regs[1].to32());
1454214587 _ = try self.asmJccReloc(.be, loop);
......@@ -15113,7 +15158,7 @@ fn airAbs(self: *CodeGen, inst: Air.Inst.Index) !void {
1511315158 if (self.hasFeature(.slow_incdec)) {
1511415159 try self.asmRegisterImmediate(.{ ._, .add }, tmp_regs[0].to32(), .u(1));
1511515160 } else {
15116 try self.asmRegister(.{ ._, .inc }, tmp_regs[0].to32());
15161 try self.asmRegister(.{ ._c, .in }, tmp_regs[0].to32());
1511715162 }
1511815163 try self.asmRegisterImmediate(.{ ._, .cmp }, tmp_regs[0].to32(), .u(limb_len));
1511915164 _ = try self.asmJccReloc(.b, neg_loop);
......@@ -16452,8 +16497,8 @@ fn genShiftBinOpMir(
1645216497 try self.asmRegisterImmediate(.{ ._, .sub }, temp_regs[1].to32(), .u(1));
1645316498 try self.asmRegisterImmediate(.{ ._, .sub }, temp_regs[0].to32(), .u(1));
1645416499 } else {
16455 try self.asmRegister(.{ ._, .dec }, temp_regs[1].to32());
16456 try self.asmRegister(.{ ._, .dec }, temp_regs[0].to32());
16500 try self.asmRegister(.{ ._c, .de }, temp_regs[1].to32());
16501 try self.asmRegister(.{ ._c, .de }, temp_regs[0].to32());
1645716502 }
1645816503 _ = try self.asmJccReloc(.nz, loop);
1645916504 },
......@@ -16462,8 +16507,8 @@ fn genShiftBinOpMir(
1646216507 try self.asmRegisterImmediate(.{ ._, .add }, temp_regs[1].to32(), .u(1));
1646316508 try self.asmRegisterImmediate(.{ ._, .add }, temp_regs[0].to32(), .u(1));
1646416509 } else {
16465 try self.asmRegister(.{ ._, .inc }, temp_regs[1].to32());
16466 try self.asmRegister(.{ ._, .inc }, temp_regs[0].to32());
16510 try self.asmRegister(.{ ._c, .in }, temp_regs[1].to32());
16511 try self.asmRegister(.{ ._c, .in }, temp_regs[0].to32());
1646716512 }
1646816513 try self.asmRegisterImmediate(
1646916514 .{ ._, .cmp },
......@@ -16532,12 +16577,12 @@ fn genShiftBinOpMir(
1653216577 ._l => if (slow_inc_dec) {
1653316578 try self.asmRegisterImmediate(.{ ._, .sub }, temp_regs[1].to32(), .u(1));
1653416579 } else {
16535 try self.asmRegister(.{ ._, .dec }, temp_regs[1].to32());
16580 try self.asmRegister(.{ ._c, .de }, temp_regs[1].to32());
1653616581 },
1653716582 ._r => if (slow_inc_dec) {
1653816583 try self.asmRegisterImmediate(.{ ._, .add }, temp_regs[1].to32(), .u(1));
1653916584 } else {
16540 try self.asmRegister(.{ ._, .inc }, temp_regs[1].to32());
16585 try self.asmRegister(.{ ._c, .in }, temp_regs[1].to32());
1654116586 },
1654216587 else => unreachable,
1654316588 }
......@@ -17163,8 +17208,8 @@ fn genMulDivBinOp(
1716317208 try self.asmRegisterImmediate(.{ ._, .add }, temp_regs[2].to32(), .u(1));
1716417209 try self.asmRegisterImmediate(.{ ._, .add }, temp_regs[3].to32(), .u(1));
1716517210 } else {
17166 try self.asmRegister(.{ ._, .inc }, temp_regs[2].to32());
17167 try self.asmRegister(.{ ._, .inc }, temp_regs[3].to32());
17211 try self.asmRegister(.{ ._c, .in }, temp_regs[2].to32());
17212 try self.asmRegister(.{ ._c, .in }, temp_regs[3].to32());
1716817213 }
1716917214 try self.asmRegisterImmediate(.{ ._, .cmp }, temp_regs[3].to32(), .u(limb_len));
1717017215 _ = try self.asmJccReloc(.b, inner_loop);
......@@ -17173,7 +17218,7 @@ fn genMulDivBinOp(
1717317218 if (slow_inc) {
1717417219 try self.asmRegisterImmediate(.{ ._, .add }, temp_regs[0].to32(), .u(1));
1717517220 } else {
17176 try self.asmRegister(.{ ._, .inc }, temp_regs[0].to32());
17221 try self.asmRegister(.{ ._c, .in }, temp_regs[0].to32());
1717717222 }
1717817223 try self.asmRegisterImmediate(.{ ._, .cmp }, temp_regs[0].to32(), .u(limb_len));
1717917224 _ = try self.asmJccReloc(.b, outer_loop);
......@@ -19765,7 +19810,7 @@ fn airArg(self: *CodeGen, inst: Air.Inst.Index) !void {
1976519810 if (self.hasFeature(.slow_incdec)) {
1976619811 try self.asmRegisterImmediate(.{ ._, .add }, index_reg.to32(), .u(1));
1976719812 } else {
19768 try self.asmRegister(.{ ._, .inc }, index_reg.to32());
19813 try self.asmRegister(.{ ._c, .in }, index_reg.to32());
1976919814 }
1977019815 try self.asmRegisterImmediate(
1977119816 .{ ._, .cmp },
......@@ -20042,7 +20087,7 @@ fn genCall(self: *CodeGen, info: union(enum) {
2004220087 if (self.hasFeature(.slow_incdec)) {
2004320088 try self.asmRegisterImmediate(.{ ._, .add }, index_reg.to32(), .u(1));
2004420089 } else {
20045 try self.asmRegister(.{ ._, .inc }, index_reg.to32());
20090 try self.asmRegister(.{ ._c, .in }, index_reg.to32());
2004620091 }
2004720092 try self.asmRegisterImmediate(
2004820093 .{ ._, .cmp },
......@@ -21423,7 +21468,7 @@ fn lowerSwitchBr(
2142321468 defer if (condition_index_lock) |lock| self.register_manager.unlockReg(lock);
2142421469 try self.truncateRegister(condition_ty, condition_index_reg);
2142521470 const ptr_size = @divExact(self.target.ptrBitWidth(), 8);
21426 try self.asmMemory(.{ ._, .jmp }, .{
21471 try self.asmMemory(.{ ._mp, .j }, .{
2142721472 .base = .table,
2142821473 .mod = .{ .rm = .{
2142921474 .size = .ptr,
......@@ -21720,7 +21765,7 @@ fn airSwitchDispatch(self: *CodeGen, inst: Air.Inst.Index) !void {
2172021765 defer if (condition_index_lock) |lock| self.register_manager.unlockReg(lock);
2172121766 try self.truncateRegister(condition_ty, condition_index_reg);
2172221767 const ptr_size = @divExact(self.target.ptrBitWidth(), 8);
21723 try self.asmMemory(.{ ._, .jmp }, .{
21768 try self.asmMemory(.{ ._mp, .j }, .{
2172421769 .base = .table,
2172521770 .mod = .{ .rm = .{
2172621771 .size = .ptr,
......@@ -21777,7 +21822,7 @@ fn airSwitchDispatch(self: *CodeGen, inst: Air.Inst.Index) !void {
2177721822fn performReloc(self: *CodeGen, reloc: Mir.Inst.Index) void {
2177821823 const next_inst: u32 = @intCast(self.mir_instructions.len);
2177921824 switch (self.mir_instructions.items(.tag)[reloc]) {
21780 .j, .jmp => {},
21825 .j => {},
2178121826 .pseudo => switch (self.mir_instructions.items(.ops)[reloc]) {
2178221827 .pseudo_j_z_and_np_inst, .pseudo_j_nz_or_p_inst => {},
2178321828 else => unreachable,
......@@ -22149,65 +22194,52 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void {
2214922194 prefix = .directive;
2215022195 }
2215122196
22152 var mnem_size: ?Memory.Size = if (prefix == .directive)
22153 null
22154 else if (std.mem.endsWith(u8, mnem_str, "b"))
22155 .byte
22156 else if (std.mem.endsWith(u8, mnem_str, "w"))
22157 .word
22158 else if (std.mem.endsWith(u8, mnem_str, "l"))
22159 .dword
22160 else if (std.mem.endsWith(u8, mnem_str, "q") and
22161 (std.mem.indexOfScalar(u8, "vp", mnem_str[0]) == null or !std.mem.endsWith(u8, mnem_str, "dq")))
22162 .qword
22163 else if (std.mem.endsWith(u8, mnem_str, "t"))
22164 .tbyte
22165 else
22166 null;
22167 const mnem_tag = while (true) break std.meta.stringToEnum(
22197 var mnem_size: struct {
22198 used: bool,
22199 size: ?Memory.Size,
22200 fn use(size: *@This()) ?Memory.Size {
22201 size.used = true;
22202 return size.size;
22203 }
22204 } = .{
22205 .used = false,
22206 .size = if (prefix == .directive)
22207 null
22208 else if (std.mem.endsWith(u8, mnem_str, "b"))
22209 .byte
22210 else if (std.mem.endsWith(u8, mnem_str, "w"))
22211 .word
22212 else if (std.mem.endsWith(u8, mnem_str, "l"))
22213 .dword
22214 else if (std.mem.endsWith(u8, mnem_str, "q") and
22215 (std.mem.indexOfScalar(u8, "vp", mnem_str[0]) == null or !std.mem.endsWith(u8, mnem_str, "dq")))
22216 .qword
22217 else if (std.mem.endsWith(u8, mnem_str, "t"))
22218 .tbyte
22219 else
22220 null,
22221 };
22222 var mnem_tag = while (true) break std.meta.stringToEnum(
2216822223 encoder.Instruction.Mnemonic,
22169 mnem_str[0 .. mnem_str.len - @intFromBool(mnem_size != null)],
22170 ) orelse if (mnem_size) |_| {
22171 mnem_size = null;
22224 mnem_str[0 .. mnem_str.len - @intFromBool(mnem_size.size != null)],
22225 ) orelse if (mnem_size.size) |_| {
22226 mnem_size.size = null;
2217222227 continue;
2217322228 } else return self.fail("invalid mnemonic: '{s}'", .{mnem_str});
2217422229 if (@as(?Memory.Size, switch (mnem_tag) {
2217522230 .clflush => .byte,
22231 .fldcw, .fnstcw, .fstcw, .fnstsw, .fstsw => .word,
2217622232 .fldenv, .fnstenv, .fstenv => .none,
22233 .frstor, .fsave, .fnsave, .fxrstor, .fxrstor64, .fxsave, .fxsave64 => .none,
22234 .invlpg => .none,
22235 .invpcid => .xword,
2217722236 .ldmxcsr, .stmxcsr, .vldmxcsr, .vstmxcsr => .dword,
2217822237 else => null,
2217922238 })) |fixed_mnem_size| {
22180 if (mnem_size) |size| if (size != fixed_mnem_size)
22239 if (mnem_size.size) |size| if (size != fixed_mnem_size)
2218122240 return self.fail("invalid size: '{s}'", .{mnem_str});
22182 mnem_size = fixed_mnem_size;
22241 mnem_size.size = fixed_mnem_size;
2218322242 }
22184 const mnem_name = @tagName(mnem_tag);
22185 const mnem_fixed_tag: Mir.Inst.FixedTag = if (prefix == .directive)
22186 .{ ._, .pseudo }
22187 else for (std.enums.values(Mir.Inst.Fixes)) |fixes| {
22188 const fixes_name = @tagName(fixes);
22189 const space_i = std.mem.indexOfScalar(u8, fixes_name, ' ');
22190 const fixes_prefix = if (space_i) |i|
22191 std.meta.stringToEnum(encoder.Instruction.Prefix, fixes_name[0..i]).?
22192 else
22193 .none;
22194 if (fixes_prefix != prefix) continue;
22195 const pattern = fixes_name[if (space_i) |i| i + " ".len else 0..];
22196 const wildcard_i = std.mem.indexOfScalar(u8, pattern, '_').?;
22197 const mnem_prefix = pattern[0..wildcard_i];
22198 const mnem_suffix = pattern[wildcard_i + "_".len ..];
22199 if (!std.mem.startsWith(u8, mnem_name, mnem_prefix)) continue;
22200 if (!std.mem.endsWith(u8, mnem_name, mnem_suffix)) continue;
22201 break .{ fixes, std.meta.stringToEnum(
22202 Mir.Inst.Tag,
22203 mnem_name[mnem_prefix.len .. mnem_name.len - mnem_suffix.len],
22204 ) orelse continue };
22205 } else {
22206 assert(prefix != .none); // no combination of fixes produced a known mnemonic
22207 return self.fail("invalid prefix for mnemonic: '{s} {s}'", .{
22208 @tagName(prefix), mnem_name,
22209 });
22210 };
2221122243
2221222244 var ops: [4]Operand = @splat(.none);
2221322245 var ops_len: usize = 0;
......@@ -22236,12 +22268,13 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void {
2223622268 op.* = .{ .mem = .{
2223722269 .base = .{ .reg = reg },
2223822270 .mod = .{ .rm = .{
22239 .size = mnem_size orelse return self.fail("unknown size: '{s}'", .{op_str}),
22271 .size = mnem_size.use() orelse
22272 return self.fail("unknown size: '{s}'", .{op_str}),
2224022273 .disp = disp,
2224122274 } },
2224222275 } };
2224322276 } else {
22244 if (mnem_size) |size| if (reg.bitSize() != size.bitSize(self.target))
22277 if (mnem_size.use()) |size| if (reg.bitSize() != size.bitSize(self.target))
2224522278 return self.fail("invalid register size: '{s}'", .{op_str});
2224622279 op.* = .{ .reg = reg };
2224722280 }
......@@ -22260,14 +22293,17 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void {
2226022293 else
2226122294 return self.fail("invalid modifier: '{s}'", .{modifier}),
2226222295 .register => |reg| if (std.mem.eql(u8, modifier, ""))
22263 .{ .reg = reg }
22296 .{ .reg = if (mnem_size.use()) |size|
22297 registerAlias(reg, @intCast(@divExact(size.bitSize(self.target), 8)))
22298 else
22299 reg }
2226422300 else
2226522301 return self.fail("invalid modifier: '{s}'", .{modifier}),
2226622302 .memory => |addr| if (std.mem.eql(u8, modifier, "") or std.mem.eql(u8, modifier, "P"))
2226722303 .{ .mem = .{
2226822304 .base = .{ .reg = .ds },
2226922305 .mod = .{ .rm = .{
22270 .size = mnem_size orelse
22306 .size = mnem_size.use() orelse
2227122307 return self.fail("unknown size: '{s}'", .{op_str}),
2227222308 .disp = @intCast(@as(i64, @bitCast(addr))),
2227322309 } },
......@@ -22278,7 +22314,7 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void {
2227822314 .{ .mem = .{
2227922315 .base = .{ .reg = reg_off.reg },
2228022316 .mod = .{ .rm = .{
22281 .size = mnem_size orelse
22317 .size = mnem_size.use() orelse
2228222318 return self.fail("unknown size: '{s}'", .{op_str}),
2228322319 .disp = reg_off.off,
2228422320 } },
......@@ -22289,7 +22325,7 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void {
2228922325 .{ .mem = .{
2229022326 .base = .{ .frame = frame_addr.index },
2229122327 .mod = .{ .rm = .{
22292 .size = mnem_size orelse
22328 .size = mnem_size.use() orelse
2229322329 return self.fail("unknown size: '{s}'", .{op_str}),
2229422330 .disp = frame_addr.off,
2229522331 } },
......@@ -22307,21 +22343,12 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void {
2230722343 else => return self.fail("invalid constraint: '{s}'", .{op_str}),
2230822344 };
2230922345 } else if (std.mem.startsWith(u8, op_str, "$")) {
22310 if (std.fmt.parseInt(i32, op_str["$".len..], 0)) |s| {
22311 if (mnem_size) |size| {
22312 const max = @as(u64, std.math.maxInt(u64)) >> @intCast(64 - (size.bitSize(self.target) - 1));
22313 if ((if (s < 0) ~s else s) > max)
22314 return self.fail("invalid immediate size: '{s}'", .{op_str});
22315 }
22316 op.* = .{ .imm = .s(s) };
22317 } else |_| if (std.fmt.parseInt(u64, op_str["$".len..], 0)) |u| {
22318 if (mnem_size) |size| {
22319 const max = @as(u64, std.math.maxInt(u64)) >> @intCast(64 - size.bitSize(self.target));
22320 if (u > max)
22321 return self.fail("invalid immediate size: '{s}'", .{op_str});
22322 }
22323 op.* = .{ .imm = .u(u) };
22324 } else |_| return self.fail("invalid immediate: '{s}'", .{op_str});
22346 op.* = if (std.fmt.parseInt(u64, op_str["$".len..], 0)) |u|
22347 .{ .imm = .u(u) }
22348 else |_| if (std.fmt.parseInt(i32, op_str["$".len..], 0)) |s|
22349 .{ .imm = .s(s) }
22350 else |_|
22351 return self.fail("invalid immediate: '{s}'", .{op_str});
2232522352 } else if (std.mem.endsWith(u8, op_str, ")")) {
2232622353 const open = std.mem.indexOfScalar(u8, op_str, '(') orelse
2232722354 return self.fail("invalid operand: '{s}'", .{op_str});
......@@ -22348,49 +22375,47 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void {
2234822375 else
2234922376 .@"1";
2235022377 if (sib_it.next()) |_| return self.fail("invalid memory operand: '{s}'", .{op_str});
22351 op.* = .{
22352 .mem = .{
22353 .base = if (base_str.len > 0)
22354 .{ .reg = parseRegName(base_str["%%".len..]) orelse
22355 return self.fail("invalid base register: '{s}'", .{base_str}) }
22378 op.* = if (std.mem.eql(u8, base_str, "%%dx") and index_str.len == 0) .{ .reg = .dx } else .{ .mem = .{
22379 .base = if (base_str.len > 0)
22380 .{ .reg = parseRegName(base_str["%%".len..]) orelse
22381 return self.fail("invalid base register: '{s}'", .{base_str}) }
22382 else
22383 .none,
22384 .mod = .{ .rm = .{
22385 .size = mnem_size.use() orelse return self.fail("unknown size: '{s}'", .{op_str}),
22386 .index = if (index_str.len > 0)
22387 parseRegName(index_str["%%".len..]) orelse
22388 return self.fail("invalid index register: '{s}'", .{op_str})
2235622389 else
2235722390 .none,
22358 .mod = .{ .rm = .{
22359 .size = mnem_size orelse return self.fail("unknown size: '{s}'", .{op_str}),
22360 .index = if (index_str.len > 0)
22361 parseRegName(index_str["%%".len..]) orelse
22362 return self.fail("invalid index register: '{s}'", .{op_str})
22391 .scale = scale,
22392 .disp = if (std.mem.startsWith(u8, op_str[0..open], "%[") and
22393 std.mem.endsWith(u8, op_str[0..open], "]"))
22394 disp: {
22395 const colon = std.mem.indexOfScalarPos(u8, op_str[0..open], "%[".len, ':');
22396 const modifier = if (colon) |colon_pos|
22397 op_str[colon_pos + ":".len .. open - "]".len]
2236322398 else
22364 .none,
22365 .scale = scale,
22366 .disp = if (std.mem.startsWith(u8, op_str[0..open], "%[") and
22367 std.mem.endsWith(u8, op_str[0..open], "]"))
22368 disp: {
22369 const colon = std.mem.indexOfScalarPos(u8, op_str[0..open], "%[".len, ':');
22370 const modifier = if (colon) |colon_pos|
22371 op_str[colon_pos + ":".len .. open - "]".len]
22399 "";
22400 break :disp switch (args.items[
22401 arg_map.get(op_str["%[".len .. colon orelse open - "]".len]) orelse
22402 return self.fail("no matching constraint: '{s}'", .{op_str})
22403 ]) {
22404 .immediate => |imm| if (std.mem.eql(u8, modifier, "") or
22405 std.mem.eql(u8, modifier, "c"))
22406 std.math.cast(i32, @as(i64, @bitCast(imm))) orelse
22407 return self.fail("invalid displacement: '{s}'", .{op_str})
2237222408 else
22373 "";
22374 break :disp switch (args.items[
22375 arg_map.get(op_str["%[".len .. colon orelse open - "]".len]) orelse
22376 return self.fail("no matching constraint: '{s}'", .{op_str})
22377 ]) {
22378 .immediate => |imm| if (std.mem.eql(u8, modifier, "") or
22379 std.mem.eql(u8, modifier, "c"))
22380 std.math.cast(i32, @as(i64, @bitCast(imm))) orelse
22381 return self.fail("invalid displacement: '{s}'", .{op_str})
22382 else
22383 return self.fail("invalid modifier: '{s}'", .{modifier}),
22384 else => return self.fail("invalid constraint: '{s}'", .{op_str}),
22385 };
22386 } else if (open > 0)
22387 std.fmt.parseInt(i32, op_str[0..open], 0) catch
22388 return self.fail("invalid displacement: '{s}'", .{op_str})
22389 else
22390 0,
22391 } },
22392 },
22393 };
22409 return self.fail("invalid modifier: '{s}'", .{modifier}),
22410 else => return self.fail("invalid constraint: '{s}'", .{op_str}),
22411 };
22412 } else if (open > 0)
22413 std.fmt.parseInt(i32, op_str[0..open], 0) catch
22414 return self.fail("invalid displacement: '{s}'", .{op_str})
22415 else
22416 0,
22417 } },
22418 } };
2239422419 } else if (Label.isValid(.reference, op_str)) {
2239522420 const anon = std.ascii.isDigit(op_str[0]);
2239622421 const label_gop = try labels.getOrPut(self.gpa, op_str[0..if (anon) 1 else op_str.len]);
......@@ -22410,6 +22435,51 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void {
2241022435
2241122436 // convert from att syntax to intel syntax
2241222437 std.mem.reverse(Operand, ops[0..ops_len]);
22438 if (!mnem_size.used) if (mnem_size.size) |size| {
22439 comptime var max_mnem_len: usize = 0;
22440 inline for (@typeInfo(encoder.Instruction.Mnemonic).@"enum".fields) |mnem|
22441 max_mnem_len = @max(mnem.name.len, max_mnem_len);
22442 var intel_mnem_buf: [max_mnem_len + 1]u8 = undefined;
22443 const intel_mnem_str = std.fmt.bufPrint(&intel_mnem_buf, "{s}{c}", .{
22444 @tagName(mnem_tag),
22445 @as(u8, switch (size) {
22446 .byte => 'b',
22447 .word => 'w',
22448 .dword => 'd',
22449 .qword => 'q',
22450 .tbyte => 't',
22451 else => unreachable,
22452 }),
22453 }) catch unreachable;
22454 if (std.meta.stringToEnum(encoder.Instruction.Mnemonic, intel_mnem_str)) |intel_mnem_tag| mnem_tag = intel_mnem_tag;
22455 };
22456 const mnem_name = @tagName(mnem_tag);
22457 const mnem_fixed_tag: Mir.Inst.FixedTag = if (prefix == .directive)
22458 .{ ._, .pseudo }
22459 else for (std.enums.values(Mir.Inst.Fixes)) |fixes| {
22460 const fixes_name = @tagName(fixes);
22461 const space_i = std.mem.indexOfScalar(u8, fixes_name, ' ');
22462 const fixes_prefix = if (space_i) |i|
22463 std.meta.stringToEnum(encoder.Instruction.Prefix, fixes_name[0..i]).?
22464 else
22465 .none;
22466 if (fixes_prefix != prefix) continue;
22467 const pattern = fixes_name[if (space_i) |i| i + " ".len else 0..];
22468 const wildcard_i = std.mem.indexOfScalar(u8, pattern, '_').?;
22469 const mnem_prefix = pattern[0..wildcard_i];
22470 const mnem_suffix = pattern[wildcard_i + "_".len ..];
22471 if (!std.mem.startsWith(u8, mnem_name, mnem_prefix)) continue;
22472 if (!std.mem.endsWith(u8, mnem_name, mnem_suffix)) continue;
22473 break .{ fixes, std.meta.stringToEnum(
22474 Mir.Inst.Tag,
22475 mnem_name[mnem_prefix.len .. mnem_name.len - mnem_suffix.len],
22476 ) orelse continue };
22477 } else {
22478 assert(prefix != .none); // no combination of fixes produced a known mnemonic
22479 return self.fail("invalid prefix for mnemonic: '{s} {s}'", .{
22480 @tagName(prefix), mnem_name,
22481 });
22482 };
2241322483
2241422484 (if (prefix == .directive) switch (mnem_tag) {
2241522485 .@".cfi_def_cfa" => if (ops[0] == .reg and ops[1] == .imm and ops[2] == .none)
......@@ -22815,7 +22885,7 @@ fn moveStrategy(self: *CodeGen, ty: Type, class: Register.Class, aligned: bool)
2281522885 else => {},
2281622886 },
2281722887 },
22818 .ip => {},
22888 .ip, .cr, .dr => {},
2281922889 }
2282022890 return self.fail("TODO moveStrategy for {}", .{ty.fmt(pt)});
2282122891}
......@@ -22900,13 +22970,13 @@ fn genCopy(self: *CodeGen, ty: Type, dst_mcv: MCValue, src_mcv: MCValue, opts: C
2290022970 for (dst_regs, &hazard_regs, 1..) |dst_reg, src_reg, hazard_index| {
2290122971 const dst_id = dst_reg.id();
2290222972 if (dst_id == src_reg.id()) continue;
22903 var mir_tag: Mir.Inst.Tag = .mov;
22973 var mir_tag: Mir.Inst.FixedTag = .{ ._, .mov };
2290422974 for (hazard_regs[hazard_index..]) |*hazard_reg| {
2290522975 if (dst_id != hazard_reg.id()) continue;
22906 mir_tag = .xchg;
22976 mir_tag = .{ ._g, .xch };
2290722977 hazard_reg.* = src_reg;
2290822978 }
22909 try self.asmRegisterRegister(.{ ._, mir_tag }, dst_reg.to64(), src_reg.to64());
22979 try self.asmRegisterRegister(mir_tag, dst_reg.to64(), src_reg.to64());
2291022980 }
2291122981 return;
2291222982 },
......@@ -23025,7 +23095,7 @@ fn genSetReg(
2302523095 else => unreachable,
2302623096 },
2302723097 .segment, .x87, .mmx, .sse => try self.genSetReg(dst_reg, ty, try self.genTypedValue(try pt.undefValue(ty)), opts),
23028 .ip => unreachable,
23098 .ip, .cr, .dr => unreachable,
2302923099 },
2303023100 .eflags => |cc| try self.asmSetccRegister(cc, dst_reg.to8()),
2303123101 .immediate => |imm| {
......@@ -23063,7 +23133,7 @@ fn genSetReg(
2306323133 registerAlias(dst_reg, abi_size),
2306423134 src_reg,
2306523135 ),
23066 .x87, .mmx, .ip => unreachable,
23136 .x87, .mmx, .ip, .cr, .dr => unreachable,
2306723137 .sse => if (self.hasFeature(.sse2)) try self.asmRegisterRegister(
2306823138 switch (abi_size) {
2306923139 1...4 => if (self.hasFeature(.avx)) .{ .v_d, .mov } else .{ ._d, .mov },
......@@ -23092,7 +23162,7 @@ fn genSetReg(
2309223162 dst_reg,
2309323163 switch (src_reg.class()) {
2309423164 .general_purpose, .segment => registerAlias(src_reg, abi_size),
23095 .x87, .mmx, .ip => unreachable,
23165 .x87, .mmx, .ip, .cr, .dr => unreachable,
2309623166 .sse => try self.copyToTmpRegister(ty, src_mcv),
2309723167 },
2309823168 ),
......@@ -23107,7 +23177,7 @@ fn genSetReg(
2310723177 },
2310823178 else => unreachable,
2310923179 },
23110 .mmx, .sse, .ip => unreachable,
23180 .mmx, .sse, .ip, .cr, .dr => unreachable,
2311123181 },
2311223182 .mmx => unreachable,
2311323183 .sse => switch (src_reg.class()) {
......@@ -23126,7 +23196,7 @@ fn genSetReg(
2312623196 .{ .register = try self.copyToTmpRegister(ty, src_mcv) },
2312723197 opts,
2312823198 ),
23129 .x87, .mmx, .ip => unreachable,
23199 .x87, .mmx, .ip, .cr, .dr => unreachable,
2313023200 .sse => try self.asmRegisterRegister(
2313123201 @as(?Mir.Inst.FixedTag, switch (ty.scalarType(zcu).zigTypeTag(zcu)) {
2313223202 else => switch (abi_size) {
......@@ -23153,7 +23223,7 @@ fn genSetReg(
2315323223 registerAlias(src_reg, abi_size),
2315423224 ),
2315523225 },
23156 .ip => unreachable,
23226 .ip, .cr, .dr => unreachable,
2315723227 },
2315823228 inline .register_pair,
2315923229 .register_triple,
......@@ -23294,7 +23364,7 @@ fn genSetReg(
2329423364 });
2329523365 return;
2329623366 },
23297 .segment, .mmx, .ip => unreachable,
23367 .segment, .mmx, .ip, .cr, .dr => unreachable,
2329823368 .x87, .sse => {},
2329923369 },
2330023370 .load_direct => |sym_index| switch (dst_reg.class()) {
......@@ -23309,7 +23379,7 @@ fn genSetReg(
2330923379 });
2331023380 return;
2331123381 },
23312 .segment, .mmx, .ip => unreachable,
23382 .segment, .mmx, .ip, .cr, .dr => unreachable,
2331323383 .x87, .sse => {},
2331423384 },
2331523385 .load_got, .load_tlv => {},
......@@ -23456,7 +23526,7 @@ fn genSetMem(
2345623526 };
2345723527 const src_alias = registerAlias(src_reg, abi_size);
2345823528 const src_size: u32 = @intCast(switch (src_alias.class()) {
23459 .general_purpose, .segment, .x87, .ip => @divExact(src_alias.bitSize(), 8),
23529 .general_purpose, .segment, .x87, .ip, .cr, .dr => @divExact(src_alias.bitSize(), 8),
2346023530 .mmx, .sse => abi_size,
2346123531 });
2346223532 const src_align: InternPool.Alignment = .fromNonzeroByteUnits(
......@@ -24240,18 +24310,18 @@ fn atomicOp(
2424024310 };
2424124311 switch (strat) {
2424224312 .lock => {
24243 const tag: Mir.Inst.Tag = if (rmw_op) |op| switch (op) {
24244 .Xchg => if (unused) .mov else .xchg,
24245 .Add => if (unused) .add else .xadd,
24246 .Sub => if (unused) .sub else .xadd,
24247 .And => .@"and",
24248 .Or => .@"or",
24249 .Xor => .xor,
24313 const mir_tag: Mir.Inst.FixedTag = if (rmw_op) |op| switch (op) {
24314 .Xchg => if (unused) .{ ._, .mov } else .{ ._g, .xch },
24315 .Add => .{ .@"lock _", if (unused) .add else .xadd },
24316 .Sub => .{ .@"lock _", if (unused) .sub else .xadd },
24317 .And => .{ .@"lock _", .@"and" },
24318 .Or => .{ .@"lock _", .@"or" },
24319 .Xor => .{ .@"lock _", .xor },
2425024320 else => unreachable,
2425124321 } else switch (order) {
24252 .unordered, .monotonic, .release, .acq_rel => .mov,
24322 .unordered, .monotonic, .release, .acq_rel => .{ ._, .mov },
2425324323 .acquire => unreachable,
24254 .seq_cst => .xchg,
24324 .seq_cst => .{ ._g, .xch },
2425524325 };
2425624326
2425724327 const dst_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);
......@@ -24260,18 +24330,10 @@ fn atomicOp(
2426024330 defer self.register_manager.unlockReg(dst_lock);
2426124331
2426224332 try self.genSetReg(dst_reg, val_ty, val_mcv, .{});
24263 if (rmw_op == std.builtin.AtomicRmwOp.Sub and tag == .xadd) {
24333 if (rmw_op == std.builtin.AtomicRmwOp.Sub and mir_tag[1] == .xadd) {
2426424334 try self.genUnOpMir(.{ ._, .neg }, val_ty, dst_mcv);
2426524335 }
24266 try self.asmMemoryRegister(
24267 switch (tag) {
24268 .mov, .xchg => .{ ._, tag },
24269 .xadd, .add, .sub, .@"and", .@"or", .xor => .{ .@"lock _", tag },
24270 else => unreachable,
24271 },
24272 ptr_mem,
24273 registerAlias(dst_reg, val_abi_size),
24274 );
24336 try self.asmMemoryRegister(mir_tag, ptr_mem, registerAlias(dst_reg, val_abi_size));
2427524337
2427624338 return if (unused) .unreach else dst_mcv;
2427724339 },
......@@ -27599,7 +27661,7 @@ fn resolveCallingConventionValues(
2759927661 break :return_value .init(.{ .register = registerAlias(ret_gpr[0], ret_size) })
2760027662 else if (ret_gpr.len >= 2 and ret_ty.isSliceAtRuntime(zcu))
2760127663 break :return_value .init(.{ .register_pair = ret_gpr[0..2].* }),
27602 .segment, .mmx, .ip => unreachable,
27664 .segment, .mmx, .ip, .cr, .dr => unreachable,
2760327665 .x87 => break :return_value .init(.{ .register = .st0 }),
2760427666 .sse => if (ret_size <= self.vectorSize(.float)) break :return_value .init(.{
2760527667 .register = registerAlias(abi.getCAbiSseReturnRegs(cc)[0], @max(ret_size, 16)),
......@@ -27634,7 +27696,7 @@ fn resolveCallingConventionValues(
2763427696 param_gpr = param_gpr[2..];
2763527697 continue;
2763627698 },
27637 .segment, .mmx, .ip => unreachable,
27699 .segment, .mmx, .ip, .cr, .dr => unreachable,
2763827700 .x87 => if (param_x87.len >= 1) {
2763927701 arg.* = .{ .register = param_x87[0] };
2764027702 param_x87 = param_x87[1..];
......@@ -27686,9 +27748,9 @@ fn failMsg(self: *CodeGen, msg: *Zcu.ErrorMsg) error{ OutOfMemory, CodegenFail }
2768627748}
2768727749
2768827750fn parseRegName(name: []const u8) ?Register {
27689 if (@hasDecl(Register, "parseRegName")) {
27690 return Register.parseRegName(name);
27691 }
27751 if (std.mem.startsWith(u8, name, "db")) return @enumFromInt(
27752 @intFromEnum(Register.dr0) + (std.fmt.parseInt(u4, name["db".len..], 0) catch return null),
27753 );
2769227754 return std.meta.stringToEnum(Register, name);
2769327755}
2769427756
......@@ -27733,6 +27795,14 @@ fn registerAlias(reg: Register, size_bytes: u32) Register {
2773327795 .rip
2773427796 else
2773527797 unreachable,
27798 .cr => if (size_bytes <= 8)
27799 reg
27800 else
27801 unreachable,
27802 .dr => if (size_bytes <= 8)
27803 reg
27804 else
27805 unreachable,
2773627806 };
2773727807}
2773827808
src/arch/x86_64/Disassembler.zig+16-1
......@@ -80,6 +80,21 @@ pub fn next(dis: *Disassembler) Error!?Instruction {
8080 .op2 = .{ .imm = imm },
8181 });
8282 },
83 .ii => {
84 const imm1 = try dis.parseImm(enc.data.ops[0]);
85 const imm2 = try dis.parseImm(enc.data.ops[1]);
86 return inst(enc, .{
87 .op1 = .{ .imm = imm1 },
88 .op2 = .{ .imm = imm2 },
89 });
90 },
91 .ia => {
92 const imm = try dis.parseImm(enc.data.ops[0]);
93 return inst(enc, .{
94 .op1 = .{ .imm = imm },
95 .op2 = .{ .reg = .eax },
96 });
97 },
8398 .m, .mi, .m1, .mc => {
8499 const modrm = try dis.parseModRmByte();
85100 const act_enc = Encoding.findByOpcode(enc.opcode(), .{
......@@ -241,7 +256,7 @@ pub fn next(dis: *Disassembler) Error!?Instruction {
241256 .op3 = op3,
242257 });
243258 },
244 .rm0, .vmi, .rvm, .rvmr, .rvmi, .mvr, .rmv => unreachable, // TODO
259 .rm0, .vm, .vmi, .rvm, .rvmr, .rvmi, .mvr, .rmv => unreachable, // TODO
245260 }
246261}
247262
src/arch/x86_64/Encoding.zig+193-88
......@@ -60,6 +60,32 @@ pub fn findByMnemonic(
6060 next: for (mnemonic_to_encodings_map[@intFromEnum(mnemonic)]) |data| {
6161 if (!switch (data.feature) {
6262 .none => true,
63 .@"32bit" => switch (target.cpu.arch) {
64 else => unreachable,
65 .x86 => true,
66 .x86_64 => false,
67 },
68 .@"64bit" => switch (target.cpu.arch) {
69 else => unreachable,
70 .x86 => false,
71 .x86_64 => true,
72 },
73 inline .@"invpcid 32bit", .@"rdpid 32bit" => |tag| switch (target.cpu.arch) {
74 else => unreachable,
75 .x86 => std.Target.x86.featureSetHas(
76 target.cpu.features,
77 @field(std.Target.x86.Feature, @tagName(tag)[0 .. @tagName(tag).len - " 32bit".len]),
78 ),
79 .x86_64 => false,
80 },
81 inline .@"invpcid 64bit", .@"rdpid 64bit" => |tag| switch (target.cpu.arch) {
82 else => unreachable,
83 .x86 => false,
84 .x86_64 => std.Target.x86.featureSetHas(
85 target.cpu.features,
86 @field(std.Target.x86.Feature, @tagName(tag)[0 .. @tagName(tag).len - " 64bit".len]),
87 ),
88 },
6389 inline else => |tag| has_features: {
6490 comptime var feature_it = std.mem.splitScalar(u8, @tagName(tag), ' ');
6591 comptime var features: []const std.Target.x86.Feature = &.{};
......@@ -126,7 +152,7 @@ pub fn mandatoryPrefix(encoding: *const Encoding) ?u8 {
126152
127153pub fn modRmExt(encoding: Encoding) u3 {
128154 return switch (encoding.data.op_en) {
129 .m, .mi, .m1, .mc, .vmi => encoding.data.modrm_ext,
155 .ia, .m, .mi, .m1, .mc, .vm, .vmi => encoding.data.modrm_ext,
130156 else => unreachable,
131157 };
132158}
......@@ -176,7 +202,7 @@ pub fn format(
176202 for (opc) |byte| try writer.print("{x:0>2} ", .{byte});
177203
178204 switch (encoding.data.op_en) {
179 .z, .fd, .td, .i, .zi, .d => {},
205 .z, .fd, .td, .i, .zi, .ii, .d => {},
180206 .o, .zo, .oz, .oi => {
181207 const op = switch (encoding.data.op_en) {
182208 .o, .oz, .oi => encoding.data.ops[0],
......@@ -192,17 +218,24 @@ pub fn format(
192218 };
193219 try writer.print("+{s} ", .{tag});
194220 },
195 .m, .mi, .m1, .mc, .vmi => try writer.print("/{d} ", .{encoding.modRmExt()}),
221 .ia, .m, .mi, .m1, .mc, .vm, .vmi => try writer.print("/{d} ", .{encoding.modRmExt()}),
196222 .mr, .rm, .rmi, .mri, .mrc, .rm0, .rvm, .rvmr, .rvmi, .mvr, .rmv => try writer.writeAll("/r "),
197223 }
198224
199225 switch (encoding.data.op_en) {
200 .i, .d, .zi, .oi, .mi, .rmi, .mri, .vmi, .rvmi => {
201 const op = switch (encoding.data.op_en) {
202 .i, .d => encoding.data.ops[0],
203 .zi, .oi, .mi => encoding.data.ops[1],
204 .rmi, .mri, .vmi => encoding.data.ops[2],
205 .rvmi => encoding.data.ops[3],
226 .i, .d, .zi, .ii, .ia, .oi, .mi, .rmi, .mri, .vmi, .rvmi => for (0..2) |i| {
227 const op = switch (i) {
228 0 => switch (encoding.data.op_en) {
229 .i, .ii, .ia, .d => encoding.data.ops[0],
230 .zi, .oi, .mi => encoding.data.ops[1],
231 .rmi, .mri, .vmi => encoding.data.ops[2],
232 .rvmi => encoding.data.ops[3],
233 else => unreachable,
234 },
235 1 => switch (encoding.data.op_en) {
236 .ii => encoding.data.ops[1],
237 else => break,
238 },
206239 else => unreachable,
207240 };
208241 const tag = switch (op) {
......@@ -218,13 +251,13 @@ pub fn format(
218251 try writer.print("{s} ", .{tag});
219252 },
220253 .rvmr => try writer.writeAll("/is4 "),
221 .z, .fd, .td, .o, .zo, .oz, .m, .m1, .mc, .mr, .rm, .mrc, .rm0, .rvm, .mvr, .rmv => {},
254 .z, .fd, .td, .o, .zo, .oz, .m, .m1, .mc, .mr, .rm, .mrc, .rm0, .vm, .rvm, .mvr, .rmv => {},
222255 }
223256
224257 try writer.print("{s} ", .{@tagName(encoding.mnemonic)});
225258
226259 for (encoding.data.ops) |op| switch (op) {
227 .none, .o16, .o32, .o64 => break,
260 .none => break,
228261 else => try writer.print("{s} ", .{@tagName(op)}),
229262 };
230263
......@@ -253,48 +286,67 @@ pub const Mnemonic = enum {
253286 @".cfi_escape",
254287 // zig fmt: off
255288 // General-purpose
256 adc, add, @"and",
257 bsf, bsr, bswap, bt, btc, btr, bts,
289 aaa, aad, aam, aas, adc, add, @"and", arpl,
290 bound, bsf, bsr, bswap, bt, btc, btr, bts,
258291 call, cbw, cdq, cdqe,
259 clac, clc, cld, clflush, cli, clts, clui,
292 clac, clc, cld, cldemote, clflush, clflushopt, cli, clts, clui, clrssbsy, clwb, cmc,
260293 cmova, cmovae, cmovb, cmovbe, cmovc, cmove, cmovg, cmovge, cmovl, cmovle, cmovna,
261294 cmovnae, cmovnb, cmovnbe, cmovnc, cmovne, cmovng, cmovnge, cmovnl, cmovnle, cmovno,
262295 cmovnp, cmovns, cmovnz, cmovo, cmovp, cmovpe, cmovpo, cmovs, cmovz,
263 cmp,
264 cmps, cmpsb, cmpsd, cmpsq, cmpsw,
265 cmpxchg, cmpxchg8b, cmpxchg16b,
296 cmp, cmps, cmpsb, cmpsd, cmpsq, cmpsw, cmpxchg, cmpxchg8b, cmpxchg16b,
266297 cpuid, cqo, cwd, cwde,
267 dec, div, idiv, imul, inc, int3,
268 ja, jae, jb, jbe, jc, jrcxz, je, jg, jge, jl, jle, jna, jnae, jnb, jnbe,
269 jnc, jne, jng, jnge, jnl, jnle, jno, jnp, jns, jnz, jo, jp, jpe, jpo, js, jz,
270 jmp,
271 lea, lfence,
298 daa, das, dec, div,
299 endbr32, endbr64, enqcmd, enqcmds, enter,
300 hlt, hreset,
301 idiv, imul, in, inc, incsspd, incsspq, ins, insb, insd, insw,
302 int, int1, int3, into, invd, invlpg, invpcid, iret, iretd, iretq, iretw,
303 ja, jae, jb, jbe, jc, jcxz, je, jecxz, jg, jge, jl, jle, jmp, jna, jnae, jnb, jnbe,
304 jnc, jne, jng, jnge, jnl, jnle, jno, jnp, jns, jnz, jo, jp, jpe, jpo, jrcxz, js, jz,
305 lahf, lar, lea, leave, lfence, lgdt, lidt, lldt, lmsw, loop, loope, loopne,
272306 lods, lodsb, lodsd, lodsq, lodsw,
273 lzcnt,
307 lsl, ltr, lzcnt,
274308 mfence, mov, movbe,
275309 movs, movsb, movsd, movsq, movsw,
276310 movsx, movsxd, movzx, mul,
277311 neg, nop, not,
278 @"or",
279 pause, pop, popcnt, popfq, push, pushfq,
280 rcl, rcr, ret, rol, ror, rorx,
281 sal, sar, sarx, sbb,
312 @"or", out, outs, outsb, outsd, outsw,
313 pause, pop, popcnt, popf, popfd, popfq, push, pushfq,
314 rcl, rcr,
315 rdfsbase, rdgsbase, rdmsr, rdpid, rdpkru, rdpmc, rdrand, rdseed, rdssd, rdssq, rdtsc, rdtscp,
316 ret, rol, ror, rorx, rsm,
317 sahf, sal, sar, sarx, sbb,
282318 scas, scasb, scasd, scasq, scasw,
319 senduipi, serialize,
283320 shl, shld, shlx, shr, shrd, shrx,
284 stac, stc, std, sti, stui,
285 sub, syscall,
321 stac, stc, std, sti, str, stui,
322 sub, swapgs, syscall, sysenter, sysexit, sysret,
286323 seta, setae, setb, setbe, setc, sete, setg, setge, setl, setle, setna, setnae,
287324 setnb, setnbe, setnc, setne, setng, setnge, setnl, setnle, setno, setnp, setns,
288325 setnz, seto, setp, setpe, setpo, sets, setz,
289 sfence,
326 sfence, sidt, sldt, smsw,
290327 stos, stosb, stosd, stosq, stosw,
291 @"test", tzcnt,
292 ud2,
293 xadd, xchg, xgetbv, xor,
328 @"test", testui, tpause,
329 ud0, ud1, ud2, uiret, umonitor, umwait,
330 verr, verw, wrfsbase, wrgsbase, wrmsr, wrpkru, wrssd, wrssq, wrussd, wrussq,
331 xadd, xchg, xgetbv, xlat, xlatb, xor,
294332 // X87
295 fabs, fchs, ffree, fisttp, fld, fldenv, fnstenv, fst, fstenv, fstp,
333 f2xm1, fabs, fadd, faddp, fbld, fbstp, fchs, fclex,
334 fcmovb, fcmovbe, fcmove, fcmovnb, fcmovnbe, fcmovne, fcmovnu, fcmovu,
335 fcom, fcomi, fcomip, fcomp, fcompp, fcos,
336 fdecstp, fdiv, fdivp, fdivr, fdivrp, ffree,
337 fiadd, ficom, ficomp, fidiv, fidivr, fild, fimul, fincstp, finit,
338 fist, fistp, fisttp, fisub, fisubr,
339 fld, fld1, fldcw, fldenv, fldl2e, fldl2t, fldlg2, fldln2, fldpi, fldz,
340 fmul, fmulp,
341 fnclex, fninit, fnop, fnsave, fnstcw, fnstenv, fnstsw,
342 fpatan, fprem, fprem1, fptan, frndint, frstor,
343 fsave, fscale, fsin, fsincos, fsqrt,
344 fst, fstcw, fstenv, fstp, fstsw,
345 fsub, fsubp, fsubr, fsubrp,
346 ftst, fucom, fucomi, fucomip, fucomp, fucompp,
347 fwait, fxam, fxch, fxtract, fyl2x, fyl2xp1, wait,
296348 // MMX
297 movd, movq,
349 emms, movd, movq,
298350 packssdw, packsswb, packuswb,
299351 paddb, paddd, paddq, paddsb, paddsw, paddusb, paddusw, paddw,
300352 pand, pandn, por, pxor,
......@@ -312,6 +364,7 @@ pub const Mnemonic = enum {
312364 cmpps, cmpss,
313365 cvtpi2ps, cvtps2pi, cvtsi2ss, cvtss2si, cvttps2pi, cvttss2si,
314366 divps, divss,
367 fxrstor, fxrstor64, fxsave, fxsave64,
315368 ldmxcsr,
316369 maxps, maxss,
317370 minps, minss,
......@@ -333,10 +386,12 @@ pub const Mnemonic = enum {
333386 andpd,
334387 andnpd,
335388 cmppd, //cmpsd,
389 comisd, comiss,
336390 cvtdq2pd, cvtdq2ps, cvtpd2dq, cvtpd2pi, cvtpd2ps, cvtpi2pd,
337391 cvtps2dq, cvtps2pd, cvtsd2si, cvtsd2ss, cvtsi2sd, cvtss2sd,
338392 cvttpd2dq, cvttpd2pi, cvttps2dq, cvttsd2si,
339393 divpd, divsd,
394 gf2p8affineinvqb, gf2p8affineqb, gf2p8mulb,
340395 maxpd, maxsd,
341396 minpd, minsd,
342397 movapd,
......@@ -357,11 +412,12 @@ pub const Mnemonic = enum {
357412 ucomisd,
358413 xorpd,
359414 // SSE3
360 movddup, movshdup, movsldup,
415 addsubpd, addsubps, haddpd, haddps, lddqu, movddup, movshdup, movsldup,
361416 // SSSE3
362417 pabsb, pabsd, pabsw, palignr, pshufb,
363418 // SSE4.1
364419 blendpd, blendps, blendvpd, blendvps,
420 dppd, dpps,
365421 extractps,
366422 insertps,
367423 packusdw,
......@@ -376,28 +432,32 @@ pub const Mnemonic = enum {
376432 ptest,
377433 roundpd, roundps, roundsd, roundss,
378434 // SSE4.2
379 pcmpgtq,
435 crc32, pcmpgtq,
380436 // PCLMUL
381437 pclmulqdq,
382438 // AES
383439 aesdec, aesdeclast, aesenc, aesenclast, aesimc, aeskeygenassist,
384440 // SHA
385 sha256msg1, sha256msg2, sha256rnds2,
441 sha1rnds4, sha1nexte, sha1msg1, sha1msg2, sha256msg1, sha256msg2, sha256rnds2,
386442 // AVX
387 vaddpd, vaddps, vaddsd, vaddss,
443 andn, bextr, blsi, blsmsk, blsr, bzhi, tzcnt,
444 vaddpd, vaddps, vaddsd, vaddss, vaddsubpd, vaddsubps,
388445 vaesdec, vaesdeclast, vaesenc, vaesenclast, vaesimc, vaeskeygenassist,
389446 vandnpd, vandnps, vandpd, vandps,
390447 vblendpd, vblendps, vblendvpd, vblendvps,
391448 vbroadcastf128, vbroadcastsd, vbroadcastss,
392 vcmppd, vcmpps, vcmpsd, vcmpss,
449 vcmppd, vcmpps, vcmpsd, vcmpss, vcomisd, vcomiss,
393450 vcvtdq2pd, vcvtdq2ps, vcvtpd2dq, vcvtpd2ps,
394451 vcvtps2dq, vcvtps2pd, vcvtsd2si, vcvtsd2ss,
395452 vcvtsi2sd, vcvtsi2ss, vcvtss2sd, vcvtss2si,
396453 vcvttpd2dq, vcvttps2dq, vcvttsd2si, vcvttss2si,
397454 vdivpd, vdivps, vdivsd, vdivss,
455 vdppd, vdpps,
398456 vextractf128, vextractps,
457 vgf2p8affineinvqb, vgf2p8affineqb, vgf2p8mulb,
458 vhaddpd, vhaddps,
399459 vinsertf128, vinsertps,
400 vldmxcsr,
460 vlddqu, vldmxcsr,
401461 vmaxpd, vmaxps, vmaxsd, vmaxss,
402462 vminpd, vminps, vminsd, vminss,
403463 vmovapd, vmovaps,
......@@ -455,6 +515,12 @@ pub const Mnemonic = enum {
455515 // AVX2
456516 vbroadcasti128, vpbroadcastb, vpbroadcastd, vpbroadcastq, vpbroadcastw,
457517 vextracti128, vinserti128, vpblendd,
518 // ADX
519 adcx, adox,
520 // AESKLE
521 aesdec128kl, aesdec256kl, aesenc128kl, aesenc256kl, encodekey128, encodekey256, loadiwkey,
522 // AESKLEWIDE_KL
523 aesdecwide128kl, aesdecwide256kl, aesencwide128kl, aesencwide256kl,
458524 // zig fmt: on
459525};
460526
......@@ -462,24 +528,23 @@ pub const OpEn = enum {
462528 // zig fmt: off
463529 z,
464530 o, zo, oz, oi,
465 i, zi,
531 i, zi, ii, ia,
466532 d, m,
467533 fd, td,
468534 m1, mc, mi, mr, rm,
469535 rmi, mri, mrc,
470 rm0, vmi, rvm, rvmr, rvmi, mvr, rmv,
536 rm0, vm, vmi, rvm, rvmr, rvmi, mvr, rmv,
471537 // zig fmt: on
472538};
473539
474540pub const Op = enum {
475541 // zig fmt: off
476542 none,
477 o16, o32, o64,
478543 unity,
479544 imm8, imm16, imm32, imm64,
480545 imm8s, imm16s, imm32s,
481546 al, ax, eax, rax,
482 cl,
547 cl, dx,
483548 rip, eip, ip,
484549 r8, r16, r32, r64,
485550 rm8, rm16, rm32, rm64,
......@@ -489,9 +554,10 @@ pub const Op = enum {
489554 m,
490555 moffs,
491556 sreg,
492 st, mm, mm_m64,
557 st0, st, mm, mm_m64,
493558 xmm0, xmm, xmm_m8, xmm_m16, xmm_m32, xmm_m64, xmm_m128,
494559 ymm, ymm_m256,
560 cr, dr,
495561 // zig fmt: on
496562
497563 pub fn fromOperand(operand: Instruction.Operand, target: *const std.Target) Op {
......@@ -499,32 +565,34 @@ pub const Op = enum {
499565 .none => .none,
500566
501567 .reg => |reg| switch (reg.class()) {
502 .general_purpose => if (reg.to64() == .rax)
503 switch (reg) {
504 .al => .al,
505 .ax => .ax,
506 .eax => .eax,
507 .rax => .rax,
568 .general_purpose => switch (reg) {
569 .al => .al,
570 .ax => .ax,
571 .eax => .eax,
572 .rax => .rax,
573 .cl => .cl,
574 .dx => .dx,
575 else => switch (reg.bitSize()) {
576 8 => .r8,
577 16 => .r16,
578 32 => .r32,
579 64 => .r64,
508580 else => unreachable,
509 }
510 else if (reg == .cl)
511 .cl
512 else switch (reg.bitSize()) {
513 8 => .r8,
514 16 => .r16,
515 32 => .r32,
516 64 => .r64,
517 else => unreachable,
581 },
518582 },
519583 .segment => .sreg,
520 .x87 => .st,
584 .x87 => switch (reg) {
585 .st0 => .st0,
586 else => .st,
587 },
521588 .mmx => .mm,
522 .sse => if (reg == .xmm0)
523 .xmm0
524 else switch (reg.bitSize()) {
525 128 => .xmm,
526 256 => .ymm,
527 else => unreachable,
589 .sse => switch (reg) {
590 .xmm0 => .xmm0,
591 else => switch (reg.bitSize()) {
592 128 => .xmm,
593 256 => .ymm,
594 else => unreachable,
595 },
528596 },
529597 .ip => switch (reg) {
530598 .rip => .rip,
......@@ -532,6 +600,8 @@ pub const Op = enum {
532600 .ip => .ip,
533601 else => unreachable,
534602 },
603 .cr => .cr,
604 .dr => .dr,
535605 },
536606
537607 .mem => |mem| switch (mem) {
......@@ -588,24 +658,27 @@ pub const Op = enum {
588658 .eax => .eax,
589659 .rax => .rax,
590660 .cl => .cl,
661 .dx => .dx,
591662 .rip => .rip,
592663 .eip => .eip,
593664 .ip => .ip,
665 .st0 => .st0,
594666 .xmm0 => .xmm0,
595667 };
596668 }
597669
598670 pub fn immBitSize(op: Op) u64 {
599671 return switch (op) {
600 .none, .o16, .o32, .o64, .moffs, .m, .sreg => unreachable,
601 .al, .cl, .rip, .eip, .ip, .r8, .rm8, .r32_m8 => unreachable,
672 .none, .moffs, .m, .sreg => unreachable,
673 .al, .cl, .dx, .rip, .eip, .ip, .r8, .rm8, .r32_m8 => unreachable,
602674 .ax, .r16, .rm16 => unreachable,
603675 .eax, .r32, .rm32, .r32_m16 => unreachable,
604676 .rax, .r64, .rm64, .r64_m16 => unreachable,
605 .st, .mm, .mm_m64 => unreachable,
677 .st0, .st, .mm, .mm_m64 => unreachable,
606678 .xmm0, .xmm, .xmm_m8, .xmm_m16, .xmm_m32, .xmm_m64, .xmm_m128 => unreachable,
607679 .ymm, .ymm_m256 => unreachable,
608680 .m8, .m16, .m32, .m64, .m80, .m128, .m256 => unreachable,
681 .cr, .dr => unreachable,
609682 .unity => 1,
610683 .imm8, .imm8s, .rel8 => 8,
611684 .imm16, .imm16s, .rel16 => 16,
......@@ -616,15 +689,15 @@ pub const Op = enum {
616689
617690 pub fn regBitSize(op: Op) u64 {
618691 return switch (op) {
619 .none, .o16, .o32, .o64, .moffs, .m, .sreg => unreachable,
692 .none, .moffs, .m, .sreg => unreachable,
620693 .unity, .imm8, .imm8s, .imm16, .imm16s, .imm32, .imm32s, .imm64 => unreachable,
621694 .rel8, .rel16, .rel32 => unreachable,
622695 .m8, .m16, .m32, .m64, .m80, .m128, .m256 => unreachable,
623696 .al, .cl, .r8, .rm8 => 8,
624 .ax, .ip, .r16, .rm16 => 16,
697 .ax, .dx, .ip, .r16, .rm16 => 16,
625698 .eax, .eip, .r32, .rm32, .r32_m8, .r32_m16 => 32,
626 .rax, .rip, .r64, .rm64, .r64_m16, .mm, .mm_m64 => 64,
627 .st => 80,
699 .rax, .rip, .r64, .rm64, .r64_m16, .mm, .mm_m64, .cr, .dr => 64,
700 .st0, .st => 80,
628701 .xmm0, .xmm, .xmm_m8, .xmm_m16, .xmm_m32, .xmm_m64, .xmm_m128 => 128,
629702 .ymm, .ymm_m256 => 256,
630703 };
......@@ -632,11 +705,12 @@ pub const Op = enum {
632705
633706 pub fn memBitSize(op: Op) u64 {
634707 return switch (op) {
635 .none, .o16, .o32, .o64, .moffs, .m, .sreg => unreachable,
708 .none, .moffs, .m, .sreg => unreachable,
636709 .unity, .imm8, .imm8s, .imm16, .imm16s, .imm32, .imm32s, .imm64 => unreachable,
637710 .rel8, .rel16, .rel32 => unreachable,
638 .al, .cl, .r8, .ax, .ip, .r16, .eax, .eip, .r32, .rax, .rip, .r64 => unreachable,
639 .st, .mm, .xmm0, .xmm, .ymm => unreachable,
711 .al, .cl, .r8, .ax, .dx, .ip, .r16, .eax, .eip, .r32, .rax, .rip, .r64 => unreachable,
712 .st0, .st, .mm, .xmm0, .xmm, .ymm => unreachable,
713 .cr, .dr => unreachable,
640714 .m8, .rm8, .r32_m8, .xmm_m8 => 8,
641715 .m16, .rm16, .r32_m16, .r64_m16, .xmm_m16 => 16,
642716 .m32, .rm32, .xmm_m32 => 32,
......@@ -664,14 +738,15 @@ pub const Op = enum {
664738 // zig fmt: off
665739 return switch (op) {
666740 .al, .ax, .eax, .rax,
667 .cl,
741 .cl, .dx,
668742 .ip, .eip, .rip,
669743 .r8, .r16, .r32, .r64,
670744 .rm8, .rm16, .rm32, .rm64,
671745 .r32_m8, .r32_m16, .r64_m16,
672 .st, .mm, .mm_m64,
746 .st0, .st, .mm, .mm_m64,
673747 .xmm0, .xmm, .xmm_m8, .xmm_m16, .xmm_m32, .xmm_m64, .xmm_m128,
674748 .ymm, .ymm_m256,
749 .cr, .dr,
675750 => true,
676751 else => false,
677752 };
......@@ -717,33 +792,34 @@ pub const Op = enum {
717792 pub fn class(op: Op) bits.Register.Class {
718793 return switch (op) {
719794 else => unreachable,
720 .al, .ax, .eax, .rax, .cl => .general_purpose,
795 .al, .ax, .eax, .rax, .cl, .dx => .general_purpose,
721796 .r8, .r16, .r32, .r64 => .general_purpose,
722797 .rm8, .rm16, .rm32, .rm64 => .general_purpose,
723798 .r32_m8, .r32_m16, .r64_m16 => .general_purpose,
724799 .sreg => .segment,
725 .st => .x87,
800 .st0, .st => .x87,
726801 .mm, .mm_m64 => .mmx,
727802 .xmm0, .xmm, .xmm_m8, .xmm_m16, .xmm_m32, .xmm_m64, .xmm_m128 => .sse,
728803 .ymm, .ymm_m256 => .sse,
729804 .rip, .eip, .ip => .ip,
805 .cr => .cr,
806 .dr => .dr,
730807 };
731808 }
732809
733810 /// Given an operand `op` checks if `target` is a subset for the purposes of the encoding.
734811 pub fn isSubset(op: Op, target: Op) bool {
735812 switch (op) {
736 .o16, .o32, .o64 => unreachable,
737813 .moffs, .sreg => return op == target,
738814 .none => switch (target) {
739 .o16, .o32, .o64, .none => return true,
815 .none => return true,
740816 else => return false,
741817 },
742818 else => {
743819 if (op.isRegister() and target.isRegister()) {
744 return switch (target) {
745 .cl, .al, .ax, .eax, .rax, .xmm0 => op == target,
746 else => op.class() == target.class() and op.regBitSize() == target.regBitSize(),
820 return switch (target.toReg()) {
821 .none => op.class() == target.class() and op.regBitSize() == target.regBitSize(),
822 else => op == target,
747823 };
748824 }
749825 if (op.isMemory() and target.isMemory()) {
......@@ -779,6 +855,7 @@ pub const Mode = enum {
779855 none,
780856 short, long,
781857 rex, rex_short,
858 wait,
782859 vex_128_w0, vex_128_w1, vex_128_wig,
783860 vex_256_w0, vex_256_w1, vex_256_wig,
784861 vex_lig_w0, vex_lig_w1, vex_lig_wig,
......@@ -841,20 +918,46 @@ pub const Mode = enum {
841918
842919pub const Feature = enum {
843920 none,
921 @"32bit",
922 @"64bit",
923 adx,
844924 aes,
845925 @"aes avx",
846926 avx,
847927 avx2,
848928 bmi,
849929 bmi2,
930 cldemote,
931 clflushopt,
932 clwb,
850933 cmov,
934 @"cmov x87",
935 crc32,
936 enqcmd,
851937 f16c,
852938 fma,
939 fsgsbase,
940 fxsr,
941 gfni,
942 @"gfni avx",
943 hreset,
944 @"invpcid 32bit",
945 @"invpcid 64bit",
946 kl,
853947 lzcnt,
948 mmx,
854949 movbe,
855950 pclmul,
856951 @"pclmul avx",
952 pku,
857953 popcnt,
954 rdrnd,
955 rdseed,
956 @"rdpid 32bit",
957 @"rdpid 64bit",
958 sahf,
959 serialize,
960 shstk,
858961 smap,
859962 sse,
860963 sse2,
......@@ -866,6 +969,8 @@ pub const Feature = enum {
866969 uintr,
867970 vaes,
868971 vpclmulqdq,
972 waitpkg,
973 widekl,
869974 x87,
870975};
871976
......@@ -886,7 +991,7 @@ fn estimateInstructionLength(prefix: Prefix, encoding: Encoding, ops: []const Op
886991}
887992
888993const mnemonic_to_encodings_map = init: {
889 @setEvalBranchQuota(5_000);
994 @setEvalBranchQuota(5_600);
890995 const mnemonic_count = @typeInfo(Mnemonic).@"enum".fields.len;
891996 var mnemonic_map: [mnemonic_count][]Data = @splat(&.{});
892997 const encodings = @import("encodings.zig");
src/arch/x86_64/Lower.zig+13-3
......@@ -359,6 +359,8 @@ pub fn imm(lower: *const Lower, ops: Mir.Inst.Ops, i: u32) Immediate {
359359 .pseudo_dbg_local_ai_s,
360360 => .s(@bitCast(i)),
361361
362 .ii,
363 .ir,
362364 .rrri,
363365 .rri_u,
364366 .ri_u,
......@@ -548,17 +550,19 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand)
548550}
549551
550552fn generic(lower: *Lower, inst: Mir.Inst) Error!void {
553 @setEvalBranchQuota(2_400);
551554 const fixes = switch (inst.ops) {
552555 .none => inst.data.none.fixes,
553556 .inst => inst.data.inst.fixes,
554557 .i_s, .i_u => inst.data.i.fixes,
558 .ii => inst.data.ii.fixes,
555559 .r => inst.data.r.fixes,
556560 .rr => inst.data.rr.fixes,
557561 .rrr => inst.data.rrr.fixes,
558562 .rrrr => inst.data.rrrr.fixes,
559563 .rrri => inst.data.rrri.fixes,
560564 .rri_s, .rri_u => inst.data.rri.fixes,
561 .ri_s, .ri_u, .ri_64 => inst.data.ri.fixes,
565 .ri_s, .ri_u, .ri_64, .ir => inst.data.ri.fixes,
562566 .rm, .rmi_s, .mr => inst.data.rx.fixes,
563567 .mrr, .rrm, .rmr => inst.data.rrx.fixes,
564568 .rmi, .mri => inst.data.rix.fixes,
......@@ -575,8 +579,6 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void {
575579 else
576580 .none,
577581 }, mnemonic: {
578 @setEvalBranchQuota(2_000);
579
580582 comptime var max_len = 0;
581583 inline for (@typeInfo(Mnemonic).@"enum".fields) |field| max_len = @max(field.name.len, max_len);
582584 var buf: [max_len]u8 = undefined;
......@@ -598,6 +600,14 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void {
598600 .i_s, .i_u => &.{
599601 .{ .imm = lower.imm(inst.ops, inst.data.i.i) },
600602 },
603 .ii => &.{
604 .{ .imm = lower.imm(inst.ops, inst.data.ii.i1) },
605 .{ .imm = lower.imm(inst.ops, inst.data.ii.i2) },
606 },
607 .ir => &.{
608 .{ .imm = lower.imm(inst.ops, inst.data.ri.i) },
609 .{ .reg = inst.data.ri.r1 },
610 },
601611 .r => &.{
602612 .{ .reg = inst.data.r.r1 },
603613 },
src/arch/x86_64/Mir.zig+516-91
......@@ -23,8 +23,82 @@ pub const Inst = struct {
2323 /// ___
2424 @"_",
2525
26 /// ___ 0
27 _0,
28 /// ___ 1
29 _1,
30 /// ___ 2
31 _2,
32 /// ___ 3
33 _3,
34 /// ___ 4
35 _4,
36
37 /// System Call ___
38 sys_,
39
40 /// ___ crement Shadow Stack Pointer Doubleword
41 _csspd,
42 /// ___ crement Shadow Stack Pointer Quadword
43 _csspq,
44 /// ___ FS Segment Base
45 _fsbase,
46 /// ___ GS Segment Base
47 _gsbase,
48 /// ___ Model Specific Register
49 _msr,
50 /// ___ MXCSR
51 _mxcsr,
52 /// ___ Processor ID
53 _pid,
54 /// ___ Protection Key Rights For User Pages
55 _pkru,
56 /// ___ Performance-Monitoring Counters
57 _pmc,
58 /// ___ Rondam Number
59 _rand,
60 /// ___ Rondam Seed
61 _seed,
62 /// ___ Shadow Stack Pointer Doubleword
63 _sspd,
64 /// ___ Shadow Stack Pointer Quadword
65 _sspq,
66 /// ___ Time-Stamp Counter
67 _tsc,
68 /// ___ Time-Stamp Counter And Processor ID
69 _tscp,
70 /// VEX-Encoded ___ MXCSR
71 v_mxcsr,
72
73 /// Interrupt ___
2674 /// Integer ___
2775 i_,
76 /// Interrupt ___ Word
77 i_w,
78 /// Interrupt ___ Doubleword
79 i_d,
80 /// Interrupt ___ Quadword
81 i_q,
82 /// User-Interrupt ___
83 ui_,
84
85 /// ___ mp
86 _mp,
87 /// ___ if CX register is 0
88 _cxz,
89 /// ___ if ECX register is 0
90 _ecxz,
91 /// ___ if RCX register is 0
92 _rcxz,
93
94 /// ___ Addition
95 _a,
96 /// ___ Subtraction
97 _s,
98 /// ___ Multiply
99 _m,
100 /// ___ Division
101 _d,
28102
29103 /// ___ Left
30104 _l,
......@@ -33,6 +107,8 @@ pub const Inst = struct {
33107 /// ___ Left Without Affecting Flags
34108 _lx,
35109 /// ___ Right
110 /// ___ For Reading
111 /// ___ Register
36112 _r,
37113 /// ___ Right Double
38114 _rd,
......@@ -45,7 +121,7 @@ pub const Inst = struct {
45121 //_r,
46122
47123 /// ___ Above
48 _a,
124 //_a,
49125 /// ___ Above Or Equal
50126 _ae,
51127 /// ___ Below
......@@ -102,7 +178,7 @@ pub const Inst = struct {
102178 /// ___ Parity Odd
103179 _po,
104180 /// ___ Sign
105 _s,
181 //_s,
106182 /// ___ Zero
107183 _z,
108184 /// ___ Alignment Check Flag
......@@ -111,15 +187,18 @@ pub const Inst = struct {
111187 //_d,
112188 /// ___ Interrupt Flag
113189 _i,
190 /// ___ Task-Switched Flag In CR0
191 _ts,
114192 /// ___ User Interrupt Flag
115193 _ui,
116194
117195 /// ___ Byte
118196 //_b,
119197 /// ___ Word
198 /// ___ For Writing
120199 _w,
121200 /// ___ Doubleword
122 _d,
201 //_d,
123202 /// ___ QuadWord
124203 _q,
125204
......@@ -214,8 +293,72 @@ pub const Inst = struct {
214293
215294 /// Float ___
216295 f_,
296 /// Float ___ +1.0
297 /// Float ___ 1
298 f_1,
299 /// Float ___ Below
300 f_b,
301 /// Float ___ Below Or Equal
302 f_be,
303 /// Float ___ Control Word
304 f_cw,
305 /// Float ___ Equal
306 f_e,
307 /// Float ___ Environment
308 f_env,
309 /// Float ___ log_2(e)
310 f_l2e,
311 /// Float ___ log_2(10)
312 f_l2t,
313 /// Float ___ log_10(2)
314 f_lg2,
315 /// Float ___ log_e(2)
316 f_ln2,
317 /// Float ___ Not Below
318 f_nb,
319 /// Float ___ Not Below Or Equal
320 f_nbe,
321 /// Float ___ Not Equal
322 f_ne,
323 /// Float ___ Not Unordered
324 f_nu,
217325 /// Float ___ Pop
218326 f_p,
327 /// Float ___ +1
328 f_p1,
329 /// Float ___ π
330 f_pi,
331 /// Float ___ Pop Pop
332 f_pp,
333 /// Float ___ stack-top pointer
334 f_stp,
335 /// Float ___ Status Word
336 f_sw,
337 /// Float ___ Unordered
338 f_u,
339 /// Float ___ +0.0
340 f_z,
341 /// Float BCD ___
342 fb_,
343 /// Float BCD ___ Pop
344 fb_p,
345 /// Float And Integer ___
346 fi_,
347 /// Float And Integer ___ Pop
348 fi_p,
349 /// Float No Wait ___
350 fn_,
351 /// Float No Wait ___ Control Word
352 fn_cw,
353 /// Float No Wait ___ Environment
354 fn_env,
355 /// Float No Wait ___ status word
356 fn_sw,
357
358 /// ___ in 32-bit and Compatibility Mode
359 _32,
360 /// ___ in 64-bit Mode
361 _64,
219362
220363 /// Packed ___
221364 p_,
......@@ -243,6 +386,24 @@ pub const Inst = struct {
243386 /// ___ Packed Double-Precision Values
244387 _pd,
245388
389 /// ___ Internal Caches
390 //_d,
391 /// ___ TLB Entries
392 _lpg,
393 /// ___ Process-Context Identifier
394 _pcid,
395
396 /// Load ___
397 l_,
398 /// Memory ___
399 m_,
400 /// Store ___
401 s_,
402 /// Timed ___
403 t_,
404 /// User Level Monitor ___
405 um_,
406
246407 /// VEX-Encoded ___
247408 v_,
248409 /// VEX-Encoded ___ Byte
......@@ -282,6 +443,19 @@ pub const Inst = struct {
282443 /// VEX-Encoded ___ 128-Bits Of Floating-Point Data
283444 v_f128,
284445
446 /// ___ 128-bit key with key locker
447 _128,
448 /// ___ 256-bit key with key locker
449 _256,
450 /// ___ with key locker using 128-bit key
451 _128kl,
452 /// ___ with key locker using 256-bit key
453 _256kl,
454 /// ___ with key locker on 8 blocks using 128-bit key
455 _wide128kl,
456 /// ___ with key locker on 8 blocks using 256-bit key
457 _wide256kl,
458
285459 /// Mask ___ Byte
286460 k_b,
287461 /// Mask ___ Word
......@@ -300,6 +474,12 @@ pub const Inst = struct {
300474 };
301475
302476 pub const Tag = enum(u8) {
477 // General-purpose
478 /// ASCII adjust al after addition
479 /// ASCII adjust ax before division
480 /// ASCII adjust ax after multiply
481 /// ASCII adjust al after subtraction
482 aa,
303483 /// Add with carry
304484 adc,
305485 /// Add
......@@ -313,6 +493,8 @@ pub const Inst = struct {
313493 /// Bitwise logical and of packed single-precision floating-point values
314494 /// Bitwise logical and of packed double-precision floating-point values
315495 @"and",
496 /// Adjust RPL field of segment selector
497 arpl,
316498 /// Bit scan forward
317499 /// Bit scan reverse
318500 bs,
......@@ -324,6 +506,7 @@ pub const Inst = struct {
324506 /// Bit test and set
325507 bt,
326508 /// Call
509 /// Fast system call
327510 call,
328511 /// Convert byte to word
329512 cbw,
......@@ -331,12 +514,25 @@ pub const Inst = struct {
331514 cdq,
332515 /// Convert doubleword to quadword
333516 cdqe,
517 /// Clear AC flag in EFLAGS register
334518 /// Clear carry flag
335519 /// Clear direction flag
336520 /// Clear interrupt flag
521 /// Clear task-switched flag in CR0
522 /// Clear user interrupt flag
337523 cl,
524 /// Cache line demote
525 cldemote,
338526 /// Flush cache line
339527 clflush,
528 /// Flush cache line optimized
529 clflushopt,
530 /// Clear busy flag in a supervisor shadow stack token
531 clrssbsy,
532 /// Cache line write back
533 clwb,
534 /// Complement carry flag
535 cmc,
340536 /// Conditional move
341537 cmov,
342538 /// Logical compare
......@@ -355,33 +551,79 @@ pub const Inst = struct {
355551 cwd,
356552 /// Convert word to doubleword
357553 cwde,
554 /// Decimal adjust AL after addition
555 /// Decimal adjust AL after subtraction
556 da,
358557 /// Decrement by 1
359 dec,
558 /// Decrement shadow stack pointer
559 de,
360560 /// Unsigned division
361561 /// Signed division
562 /// Divide
362563 /// Divide packed single-precision floating-point values
363564 /// Divide scalar single-precision floating-point values
364565 /// Divide packed double-precision floating-point values
365566 /// Divide scalar double-precision floating-point values
366567 div,
568 /// Terminate and indirect branch in 32-bit and compatibility mode
569 /// Terminate and indirect branch in 64-bit mode
570 endbr,
571 /// Enqueue command
572 /// Enqueue command supervisor
573 enqcmd,
574 /// Make stack frame for procedure parameters
575 /// Fast system call
576 enter,
577 /// Fast return from fast system call
578 exit,
579 /// Load fence
580 /// Memory fence
581 /// Store fence
582 fence,
583 /// Halt
584 hlt,
585 /// History reset
586 hreset,
587 /// Input from port
588 /// Input from port to string
367589 /// Increment by 1
368 inc,
590 /// Increment shadow stack pointer
591 in,
369592 /// Call to interrupt procedure
370 int3,
593 int,
594 /// Invalidate internal caches
595 /// Invalidate TLB entries
596 /// Invalidate process-context identifier
597 inv,
371598 /// Conditional jump
372 j,
373599 /// Jump
374 jmp,
600 j,
601 /// Load status flags into AH register
602 lahf,
603 /// Load access right byte
604 lar,
375605 /// Load effective address
376606 lea,
607 /// High level procedure exit
608 leave,
609 /// Load global descriptor table register
610 lgdt,
611 /// Load interrupt descriptor table register
612 lidt,
613 /// Load local descriptor table register
614 lldt,
615 /// Load machine status word
616 lmsw,
377617 /// Load string
378618 lod,
379 /// Load fence
380 lfence,
619 /// Loop according to ECX counter
620 loop,
621 /// Load segment limit
622 lsl,
623 /// Load task register
624 ltr,
381625 /// Count the number of leading zero bits
382626 lzcnt,
383 /// Memory fence
384 mfence,
385627 /// Move
386628 /// Move data from string to string
387629 /// Move scalar single-precision floating-point value
......@@ -407,6 +649,7 @@ pub const Inst = struct {
407649 /// Two's complement negation
408650 neg,
409651 /// No-op
652 /// No operation
410653 nop,
411654 /// One's complement negation
412655 not,
......@@ -414,39 +657,62 @@ pub const Inst = struct {
414657 /// Bitwise logical or of packed single-precision floating-point values
415658 /// Bitwise logical or of packed double-precision floating-point values
416659 @"or",
660 /// Output to port
661 /// Output string to port
662 out,
417663 /// Spin loop hint
664 /// Timed pause
418665 pause,
419666 /// Pop
420667 pop,
421668 /// Return the count of number of bits set to 1
422669 popcnt,
423670 /// Pop stack into EFLAGS register
424 popfq,
671 popf,
425672 /// Push
426673 push,
427674 /// Push EFLAGS register onto the stack
428 pushfq,
675 pushf,
429676 /// Rotate left through carry
430677 /// Rotate right through carry
431678 rc,
679 /// Read FS segment base
680 /// Read GS segment base
681 /// Read from model specific register
682 /// Read processor ID
683 /// Read protection key rights for user pages
684 /// Read performance-monitoring counters
685 /// Read random number
686 /// Read random seed
687 /// Read shadow stack pointer
688 /// Read time-stamp counter
689 /// Read time-stamp counter and processor ID
690 rd,
432691 /// Return
692 /// Return from fast system call
693 /// Interrupt return
694 /// User-interrupt return
433695 ret,
434696 /// Rotate left
435697 /// Rotate right
436698 /// Rotate right logical without affecting flags
437699 ro,
700 /// Resume from system management mode
701 rsm,
438702 /// Arithmetic shift left
439703 /// Arithmetic shift right
440704 /// Shift left arithmetic without affecting flags
441705 sa,
706 /// Store AH into flags
707 sahf,
442708 /// Integer subtraction with borrow
443709 sbb,
444710 /// Scan string
445711 sca,
712 /// Send user interprocessor interrupt
713 senduipi,
446714 /// Set byte on condition
447715 set,
448 /// Store fence
449 sfence,
450716 /// Logical shift left
451717 /// Double precision shift left
452718 /// Logical shift right
......@@ -454,6 +720,12 @@ pub const Inst = struct {
454720 /// Shift left logical without affecting flags
455721 /// Shift right logical without affecting flags
456722 sh,
723 /// Store interrupt descriptor table register
724 sidt,
725 /// Store local descriptor table register
726 sldt,
727 /// Store machine status word
728 smsw,
457729 /// Subtract
458730 /// Subtract packed integers
459731 /// Subtract packed single-precision floating-point values
......@@ -464,46 +736,128 @@ pub const Inst = struct {
464736 /// Set carry flag
465737 /// Set direction flag
466738 /// Set interrupt flag
739 /// Store binary coded decimal integer and pop
467740 /// Store floating-point value
741 /// Store integer
742 /// Store x87 FPU control word
743 /// Store x87 FPU environment
744 /// Store x87 FPU status word
745 /// Store MXCSR register state
468746 st,
469747 /// Store string
470748 sto,
471 /// Syscall
472 syscall,
749 /// Swap GS base register
750 swapgs,
473751 /// Test condition
474752 @"test",
475 /// Count the number of trailing zero bits
476 tzcnt,
477753 /// Undefined instruction
478 ud2,
754 ud,
755 /// User level set up monitor address
756 umonitor,
757 /// Verify a segment for reading
758 /// Verify a segment for writing
759 ver,
760 /// Write to model specific register
761 /// Write to model specific register
762 /// Write to model specific register
763 wr,
479764 /// Exchange and add
480765 xadd,
481766 /// Exchange register/memory with register
482 xchg,
767 /// Exchange register contents
768 xch,
483769 /// Get value of extended control register
484770 xgetbv,
771 /// Table look-up translation
772 xlat,
485773 /// Logical exclusive-or
486774 /// Bitwise logical xor of packed single-precision floating-point values
487775 /// Bitwise logical xor of packed double-precision floating-point values
488776 xor,
489777
778 // X87
779 /// Compute 2^x-1
780 @"2xm1",
490781 /// Absolute value
491782 abs,
492783 /// Change sign
493784 chs,
785 /// Clear exceptions
786 clex,
787 /// Compare floating-point values
788 com,
789 /// Compare floating-point values and set EFLAGS
790 /// Compare scalar ordered single-precision floating-point values
791 /// Compare scalar ordered double-precision floating-point values
792 comi,
793 /// Cosine
794 cos,
795 /// Decrement stack-top pointer
796 decstp,
797 /// Reverse divide
798 divr,
494799 /// Free floating-point register
495800 free,
496 /// Store integer with truncation
497 istt,
801 /// Increment stack-top pointer
802 incstp,
803 /// Initialize floating-point unit
804 init,
805 /// Load binary coded decimal integer
498806 /// Load floating-point value
499 ld,
807 /// Load integer
808 /// Load constant
809 /// Load x87 FPU control word
500810 /// Load x87 FPU environment
501 ldenv,
502 /// Store x87 FPU environment
503 nstenv,
504 /// Store x87 FPU environment
505 stenv,
506
811 /// Load MXCSR register state
812 ld,
813 /// Partial arctangent
814 patan,
815 /// Partial remainder
816 prem,
817 /// Partial tangent
818 ptan,
819 /// Round to integer
820 rndint,
821 /// Restore x87 FPU state
822 rstor,
823 /// Store x87 FPU state
824 save,
825 /// Scale
826 scale,
827 /// Sine
828 sin,
829 /// Sine and cosine
830 sincos,
831 /// Square root
832 /// Square root of packed single-precision floating-point values
833 /// Square root of scalar single-precision floating-point value
834 /// Square root of packed double-precision floating-point values
835 /// Square root of scalar double-precision floating-point value
836 sqrt,
837 /// Store integer with truncation
838 stt,
839 /// Reverse subtract
840 subr,
841 /// Test
842 tst,
843 /// Unordered compare floating-point values
844 ucom,
845 /// Unordered compare floating-point values and set EFLAGS
846 /// Unordered compare scalar single-precision floating-point values
847 /// Unordered compare scalar double-precision floating-point values
848 ucomi,
849 /// Wait
850 /// User level monitor wait
851 wait,
852 /// Examine floating-point
853 xam,
854 /// Extract exponent and significand
855 xtract,
856 /// Compute y * log2x
857 /// Compute y * log2(x + 1)
858 yl2x,
859
860 // MMX
507861 /// Pack with signed saturation
508862 ackssw,
509863 /// Pack with signed saturation
......@@ -514,6 +868,7 @@ pub const Inst = struct {
514868 adds,
515869 /// Add packed unsigned integers with unsigned saturation
516870 addus,
871 /// Logical and not
517872 /// Bitwise logical and not of packed single-precision floating-point values
518873 /// Bitwise logical and not of packed double-precision floating-point values
519874 andn,
......@@ -521,18 +876,8 @@ pub const Inst = struct {
521876 cmpeq,
522877 /// Compare packed data for greater than
523878 cmpgt,
524 /// Maximum of packed signed integers
525 maxs,
526 /// Maximum of packed unsigned integers
527 maxu,
528 /// Minimum of packed signed integers
529 mins,
530 /// Minimum of packed unsigned integers
531 minu,
532 /// Move byte mask
533 /// Extract packed single precision floating-point sign mask
534 /// Extract packed double precision floating-point sign mask
535 movmsk,
879 /// Empty MMX technology state
880 emms,
536881 /// Multiply packed signed integers and store low result
537882 mull,
538883 /// Multiply packed signed integers and store high result
......@@ -547,12 +892,20 @@ pub const Inst = struct {
547892 subs,
548893 /// Subtract packed unsigned integers with unsigned saturation
549894 subus,
895 /// Unpack high data
896 unpckhbw,
897 /// Unpack high data
898 unpckhdq,
899 /// Unpack high data
900 unpckhwd,
901 /// Unpack low data
902 unpcklbw,
903 /// Unpack low data
904 unpckldq,
905 /// Unpack low data
906 unpcklwd,
550907
551 /// Load MXCSR register
552 ldmxcsr,
553 /// Store MXCSR register state
554 stmxcsr,
555
908 // SSE
556909 /// Convert packed doubleword integers to packed single-precision floating-point values
557910 /// Convert packed doubleword integers to packed double-precision floating-point values
558911 cvtpi2,
......@@ -567,17 +920,38 @@ pub const Inst = struct {
567920 cvttps2pi,
568921 /// Convert with truncation scalar single-precision floating-point value to doubleword integer
569922 cvttss2si,
570
923 /// Extract byte
924 /// Extract word
925 /// Extract doubleword
926 /// Extract quadword
927 extr,
928 /// Restore x87 FPU, MMX, XMM, and MXCSR state
929 fxrstor,
930 /// Save x87 FPU, MMX technology, and MXCSR state
931 fxsave,
932 /// Insert byte
933 /// Insert word
934 /// Insert doubleword
935 /// Insert quadword
936 insr,
571937 /// Maximum of packed single-precision floating-point values
572938 /// Maximum of scalar single-precision floating-point values
573939 /// Maximum of packed double-precision floating-point values
574940 /// Maximum of scalar double-precision floating-point values
575941 max,
942 /// Maximum of packed signed integers
943 maxs,
944 /// Maximum of packed unsigned integers
945 maxu,
576946 /// Minimum of packed single-precision floating-point values
577947 /// Minimum of scalar single-precision floating-point values
578948 /// Minimum of packed double-precision floating-point values
579949 /// Minimum of scalar double-precision floating-point values
580950 min,
951 /// Minimum of packed signed integers
952 mins,
953 /// Minimum of packed unsigned integers
954 minu,
581955 /// Move aligned packed single-precision floating-point values
582956 /// Move aligned packed double-precision floating-point values
583957 mova,
......@@ -591,27 +965,18 @@ pub const Inst = struct {
591965 movl,
592966 /// Move packed single-precision floating-point values low to high
593967 movlh,
968 /// Move byte mask
969 /// Extract packed single precision floating-point sign mask
970 /// Extract packed double precision floating-point sign mask
971 movmsk,
594972 /// Move unaligned packed single-precision floating-point values
595973 /// Move unaligned packed double-precision floating-point values
596974 movu,
597 /// Extract byte
598 /// Extract word
599 /// Extract doubleword
600 /// Extract quadword
601 extr,
602 /// Insert byte
603 /// Insert word
604 /// Insert doubleword
605 /// Insert quadword
606 insr,
607 /// Square root of packed single-precision floating-point values
608 /// Square root of scalar single-precision floating-point value
609 /// Square root of packed double-precision floating-point values
610 /// Square root of scalar double-precision floating-point value
611 sqrt,
612 /// Unordered compare scalar single-precision floating-point values
613 /// Unordered compare scalar double-precision floating-point values
614 ucomi,
975 /// Packed interleave shuffle of quadruplets of single-precision floating-point values
976 /// Packed interleave shuffle of pairs of double-precision floating-point values
977 /// Shuffle packed doublewords
978 /// Shuffle packed words
979 shuf,
615980 /// Unpack and interleave high packed single-precision floating-point values
616981 /// Unpack and interleave high packed double-precision floating-point values
617982 unpckh,
......@@ -619,6 +984,7 @@ pub const Inst = struct {
619984 /// Unpack and interleave low packed double-precision floating-point values
620985 unpckl,
621986
987 // SSE2
622988 /// Convert packed doubleword integers to packed single-precision floating-point values
623989 /// Convert packed doubleword integers to packed double-precision floating-point values
624990 cvtdq2,
......@@ -646,32 +1012,28 @@ pub const Inst = struct {
6461012 cvttps2dq,
6471013 /// Convert with truncation scalar double-precision floating-point value to doubleword integer
6481014 cvttsd2si,
649 /// Packed interleave shuffle of quadruplets of single-precision floating-point values
650 /// Packed interleave shuffle of pairs of double-precision floating-point values
651 /// Shuffle packed doublewords
652 /// Shuffle packed words
653 shuf,
1015 /// Galois field affine transformation inverse
1016 gf2p8affineinvq,
1017 /// Galois field affine transformation
1018 gf2p8affineq,
1019 /// Galois field multiply bytes
1020 gf2p8mul,
6541021 /// Shuffle packed high words
6551022 shufh,
6561023 /// Shuffle packed low words
6571024 shufl,
6581025 /// Unpack high data
659 unpckhbw,
660 /// Unpack high data
661 unpckhdq,
662 /// Unpack high data
6631026 unpckhqdq,
664 /// Unpack high data
665 unpckhwd,
666 /// Unpack low data
667 unpcklbw,
668 /// Unpack low data
669 unpckldq,
6701027 /// Unpack low data
6711028 unpcklqdq,
672 /// Unpack low data
673 unpcklwd,
6741029
1030 // SSE3
1031 /// Packed single-precision floating-point add/subtract
1032 /// Packed double-precision floating-point add/subtract
1033 addsub,
1034 /// Packed single-precision floating-point horizontal add
1035 /// Packed double-precision floating-point horizontal add
1036 hadd,
6751037 /// Replicate double floating-point values
6761038 movddup,
6771039 /// Replicate single floating-point values
......@@ -679,9 +1041,11 @@ pub const Inst = struct {
6791041 /// Replicate single floating-point values
6801042 movsldup,
6811043
1044 // SSSE3
6821045 /// Packed align right
6831046 alignr,
6841047
1048 // SSE4.1
6851049 /// Pack with unsigned saturation
6861050 ackusd,
6871051 /// Blend packed single-precision floating-point values
......@@ -694,6 +1058,9 @@ pub const Inst = struct {
6941058 /// Variable blend packed double-precision floating-point values
6951059 /// Variable blend scalar double-precision floating-point values
6961060 blendv,
1061 /// Dot product of packed single-precision floating-point values
1062 /// Dot product of packed double-precision floating-point values
1063 dp,
6971064 /// Extract packed floating-point values
6981065 /// Extract packed integer values
6991066 extract,
......@@ -714,14 +1081,28 @@ pub const Inst = struct {
7141081 /// Round scalar double-precision floating-point value
7151082 round,
7161083
1084 // SSE4.2
1085 /// Accumulate CRC32 value
1086 crc32,
1087
1088 // PCLMUL
7171089 /// Carry-less multiplication quadword
7181090 clmulq,
7191091
1092 // AES
7201093 /// Perform one round of an AES decryption flow
1094 /// Perform ten rounds of AES decryption flow with key locker using 128-bit key
1095 /// Perform ten rounds of AES decryption flow with key locker using 256-bit key
1096 /// Perform ten rounds of AES decryption flow with key locker on 8 blocks using 128-bit key
1097 /// Perform ten rounds of AES decryption flow with key locker on 8 blocks using 256-bit key
7211098 aesdec,
7221099 /// Perform last round of an AES decryption flow
7231100 aesdeclast,
7241101 /// Perform one round of an AES encryption flow
1102 /// Perform ten rounds of AES encryption flow with key locker using 128-bit key
1103 /// Perform ten rounds of AES encryption flow with key locker using 256-bit key
1104 /// Perform ten rounds of AES encryption flow with key locker on 8 blocks using 128-bit key
1105 /// Perform ten rounds of AES encryption flow with key locker on 8 blocks using 256-bit key
7251106 aesenc,
7261107 /// Perform last round of an AES encryption flow
7271108 aesenclast,
......@@ -730,22 +1111,42 @@ pub const Inst = struct {
7301111 /// AES round key generation assist
7311112 aeskeygenassist,
7321113
1114 // SHA
1115 /// Perform four rounds of SHA1 operation
1116 sha1rnds,
1117 /// Calculate SHA1 state variable E after four rounds
1118 sha1nexte,
1119 /// Perform an intermediate calculation for the next four SHA1 message dwords
1120 /// Perform a final calculation for the next four SHA1 message dwords
1121 sha1msg,
7331122 /// Perform an intermediate calculation for the next four SHA256 message dwords
734 sha256msg1,
7351123 /// Perform a final calculation for the next four SHA256 message dwords
736 sha256msg2,
1124 sha256msg,
7371125 /// Perform two rounds of SHA256 operation
738 sha256rnds2,
739
1126 sha256rnds,
1127
1128 // AVX
1129 /// Bit field extract
1130 bextr,
1131 /// Extract lowest set isolated bit
1132 /// Get mask up to lowest set bit
1133 /// Reset lowest set bit
1134 bls,
7401135 /// Load with broadcast floating-point data
7411136 /// Load integer and broadcast
7421137 broadcast,
1138 /// Zero high bits starting with specified bit position
1139 bzhi,
1140 /// Count the number of trailing zero bits
1141 tzcnt,
7431142
1143 // F16C
7441144 /// Convert 16-bit floating-point values to single-precision floating-point values
7451145 cvtph2,
7461146 /// Convert single-precision floating-point values to 16-bit floating-point values
7471147 cvtps2ph,
7481148
1149 // FMA
7491150 /// Fused multiply-add of packed single-precision floating-point values
7501151 /// Fused multiply-add of scalar single-precision floating-point values
7511152 /// Fused multiply-add of packed double-precision floating-point values
......@@ -762,6 +1163,19 @@ pub const Inst = struct {
7621163 /// Fused multiply-add of scalar double-precision floating-point values
7631164 fmadd231,
7641165
1166 // ADX
1167 /// Unsigned integer addition of two operands with carry flag
1168 adcx,
1169 /// Unsigned integer addition of two operands with overflow flag
1170 adox,
1171
1172 // AESKLE
1173 /// Encode 128-bit key with key locker
1174 /// Encode 256-bit key with key locker
1175 encodekey,
1176 /// Load internal wrapping key with key locker
1177 loadiwkey,
1178
7651179 /// A pseudo instruction that requires special lowering.
7661180 /// This should be the only tag in this enum that doesn't
7671181 /// directly correspond to one or more instruction mnemonics.
......@@ -804,11 +1218,17 @@ pub const Inst = struct {
8041218 /// Uses `ri` payload with `i` index of extra data of type `Imm64`.
8051219 ri_64,
8061220 /// Immediate (sign-extended) operand.
807 /// Uses `imm` payload.
1221 /// Uses `i` payload.
8081222 i_s,
8091223 /// Immediate (unsigned) operand.
810 /// Uses `imm` payload.
1224 /// Uses `i` payload.
8111225 i_u,
1226 /// Immediate (word), immediate (byte) operands.
1227 /// Uses `ii` payload.
1228 ii,
1229 /// Immediate (byte), register operands.
1230 /// Uses `ri` payload.
1231 ir,
8121232 /// Relative displacement operand.
8131233 /// Uses `reloc` payload.
8141234 rel,
......@@ -1036,6 +1456,11 @@ pub const Inst = struct {
10361456 fixes: Fixes = ._,
10371457 i: u32,
10381458 },
1459 ii: struct {
1460 fixes: Fixes = ._,
1461 i1: u16,
1462 i2: u8,
1463 },
10391464 r: struct {
10401465 fixes: Fixes = ._,
10411466 r1: Register,
......@@ -1244,7 +1669,7 @@ pub const Memory = struct {
12441669 size: bits.Memory.Size,
12451670 index: Register,
12461671 scale: bits.Memory.Scale,
1247 _: u15 = undefined,
1672 _: u14 = undefined,
12481673 };
12491674
12501675 pub fn encode(mem: bits.Memory) Memory {
src/arch/x86_64/bits.zig+24-3
......@@ -177,7 +177,7 @@ pub const Condition = enum(u5) {
177177 }
178178};
179179
180pub const Register = enum(u7) {
180pub const Register = enum(u8) {
181181 // zig fmt: off
182182 rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi,
183183 r8, r9, r10, r11, r12, r13, r14, r15,
......@@ -207,6 +207,12 @@ pub const Register = enum(u7) {
207207
208208 rip, eip, ip,
209209
210 cr0, cr1, cr2, cr3, cr4, cr5, cr6, cr7,
211 cr8, cr9, cr10, cr11, cr12, cr13, cr14, cr15,
212
213 dr0, dr1, dr2, dr3, dr4, dr5, dr6, dr7,
214 dr8, dr9, dr10, dr11, dr12, dr13, dr14, dr15,
215
210216 none,
211217 // zig fmt: on
212218
......@@ -217,6 +223,8 @@ pub const Register = enum(u7) {
217223 mmx,
218224 sse,
219225 ip,
226 cr,
227 dr,
220228 };
221229
222230 pub fn class(reg: Register) Class {
......@@ -235,13 +243,15 @@ pub const Register = enum(u7) {
235243
236244 @intFromEnum(Register.es) ... @intFromEnum(Register.gs) => .segment,
237245 @intFromEnum(Register.rip) ... @intFromEnum(Register.ip) => .ip,
246 @intFromEnum(Register.cr0) ... @intFromEnum(Register.cr15) => .cr,
247 @intFromEnum(Register.dr0) ... @intFromEnum(Register.dr15) => .dr,
238248
239249 else => unreachable,
240250 // zig fmt: on
241251 };
242252 }
243253
244 pub fn id(reg: Register) u6 {
254 pub fn id(reg: Register) u7 {
245255 const base = switch (@intFromEnum(reg)) {
246256 // zig fmt: off
247257 @intFromEnum(Register.rax) ... @intFromEnum(Register.r15) => @intFromEnum(Register.rax),
......@@ -254,8 +264,9 @@ pub const Register = enum(u7) {
254264 @intFromEnum(Register.xmm0) ... @intFromEnum(Register.xmm15) => @intFromEnum(Register.xmm0) - 16,
255265 @intFromEnum(Register.mm0) ... @intFromEnum(Register.mm7) => @intFromEnum(Register.mm0) - 32,
256266 @intFromEnum(Register.st0) ... @intFromEnum(Register.st7) => @intFromEnum(Register.st0) - 40,
257
258267 @intFromEnum(Register.es) ... @intFromEnum(Register.gs) => @intFromEnum(Register.es) - 48,
268 @intFromEnum(Register.cr0) ... @intFromEnum(Register.cr15) => @intFromEnum(Register.cr0) - 54,
269 @intFromEnum(Register.dr0) ... @intFromEnum(Register.dr15) => @intFromEnum(Register.dr0) - 70,
259270
260271 else => unreachable,
261272 // zig fmt: on
......@@ -279,6 +290,9 @@ pub const Register = enum(u7) {
279290
280291 @intFromEnum(Register.es) ... @intFromEnum(Register.gs) => 16,
281292
293 @intFromEnum(Register.cr0) ... @intFromEnum(Register.cr15) => 64,
294 @intFromEnum(Register.dr0) ... @intFromEnum(Register.dr15) => 64,
295
282296 else => unreachable,
283297 // zig fmt: on
284298 };
......@@ -295,6 +309,9 @@ pub const Register = enum(u7) {
295309 @intFromEnum(Register.ymm8) ... @intFromEnum(Register.ymm15) => true,
296310 @intFromEnum(Register.xmm8) ... @intFromEnum(Register.xmm15) => true,
297311
312 @intFromEnum(Register.cr8) ... @intFromEnum(Register.cr15) => true,
313 @intFromEnum(Register.dr8) ... @intFromEnum(Register.dr15) => true,
314
298315 else => false,
299316 // zig fmt: on
300317 };
......@@ -316,6 +333,9 @@ pub const Register = enum(u7) {
316333
317334 @intFromEnum(Register.es) ... @intFromEnum(Register.gs) => @intFromEnum(Register.es),
318335
336 @intFromEnum(Register.cr0) ... @intFromEnum(Register.cr15) => @intFromEnum(Register.cr0),
337 @intFromEnum(Register.dr0) ... @intFromEnum(Register.dr15) => @intFromEnum(Register.dr0),
338
319339 else => unreachable,
320340 // zig fmt: on
321341 };
......@@ -397,6 +417,7 @@ pub const Register = enum(u7) {
397417 .mmx => 41 + @as(u6, reg.enc()),
398418 .segment => 50 + @as(u6, reg.enc()),
399419 .ip => 16,
420 .cr, .dr => unreachable,
400421 };
401422 }
402423};
src/arch/x86_64/encoder.zig+27-15
......@@ -389,6 +389,7 @@ pub const Instruction = struct {
389389 const enc = inst.encoding;
390390 const data = enc.data;
391391
392 try inst.encodeWait(encoder);
392393 if (data.mode.isVex()) {
393394 try inst.encodeVexPrefix(encoder);
394395 const opc = inst.encoding.opcode();
......@@ -404,19 +405,24 @@ pub const Instruction = struct {
404405 .z, .o, .zo, .oz => {},
405406 .i, .d => try encodeImm(inst.ops[0].imm, data.ops[0], encoder),
406407 .zi, .oi => try encodeImm(inst.ops[1].imm, data.ops[1], encoder),
408 .ii => {
409 try encodeImm(inst.ops[0].imm, data.ops[0], encoder);
410 try encodeImm(inst.ops[1].imm, data.ops[1], encoder);
411 },
407412 .fd => try encoder.imm64(inst.ops[1].mem.moffs.offset),
408413 .td => try encoder.imm64(inst.ops[0].mem.moffs.offset),
409414 else => {
410 const mem_op = switch (data.op_en) {
415 const mem_op: Operand = switch (data.op_en) {
416 .ia => .{ .reg = .eax },
411417 .m, .mi, .m1, .mc, .mr, .mri, .mrc, .mvr => inst.ops[0],
412 .rm, .rmi, .rm0, .vmi, .rmv => inst.ops[1],
418 .rm, .rmi, .rm0, .vm, .vmi, .rmv => inst.ops[1],
413419 .rvm, .rvmr, .rvmi => inst.ops[2],
414420 else => unreachable,
415421 };
416422 switch (mem_op) {
417423 .reg => |reg| {
418424 const rm = switch (data.op_en) {
419 .m, .mi, .m1, .mc, .vmi => enc.modRmExt(),
425 .ia, .m, .mi, .m1, .mc, .vm, .vmi => enc.modRmExt(),
420426 .mr, .mri, .mrc => inst.ops[1].reg.lowEnc(),
421427 .rm, .rmi, .rm0, .rvm, .rvmr, .rvmi, .rmv => inst.ops[0].reg.lowEnc(),
422428 .mvr => inst.ops[2].reg.lowEnc(),
......@@ -426,7 +432,7 @@ pub const Instruction = struct {
426432 },
427433 .mem => |mem| {
428434 const op = switch (data.op_en) {
429 .m, .mi, .m1, .mc, .vmi => .none,
435 .m, .mi, .m1, .mc, .vm, .vmi => .none,
430436 .mr, .mri, .mrc => inst.ops[1],
431437 .rm, .rmi, .rm0, .rvm, .rvmr, .rvmi, .rmv => inst.ops[0],
432438 .mvr => inst.ops[2],
......@@ -438,6 +444,7 @@ pub const Instruction = struct {
438444 }
439445
440446 switch (data.op_en) {
447 .ia => try encodeImm(inst.ops[0].imm, data.ops[0], encoder),
441448 .mi => try encodeImm(inst.ops[1].imm, data.ops[1], encoder),
442449 .rmi, .mri, .vmi => try encodeImm(inst.ops[2].imm, data.ops[2], encoder),
443450 .rvmr => try encoder.imm8(@as(u8, inst.ops[3].reg.enc()) << 4),
......@@ -460,6 +467,13 @@ pub const Instruction = struct {
460467 }
461468 }
462469
470 fn encodeWait(inst: Instruction, encoder: anytype) !void {
471 switch (inst.encoding.data.mode) {
472 .wait => try encoder.opcode_1byte(0x9b),
473 else => {},
474 }
475 }
476
463477 fn encodeLegacyPrefixes(inst: Instruction, encoder: anytype) !void {
464478 const enc = inst.encoding;
465479 const data = enc.data;
......@@ -481,7 +495,7 @@ pub const Instruction = struct {
481495 }
482496
483497 const segment_override: ?Register = switch (op_en) {
484 .z, .i, .zi, .o, .zo, .oz, .oi, .d => null,
498 .z, .i, .zi, .ii, .ia, .o, .zo, .oz, .oi, .d => null,
485499 .fd => inst.ops[1].mem.base().reg,
486500 .td => inst.ops[0].mem.base().reg,
487501 .rm, .rmi, .rm0 => if (inst.ops[1].isSegmentRegister())
......@@ -500,7 +514,7 @@ pub const Instruction = struct {
500514 }
501515 else
502516 null,
503 .vmi, .rvm, .rvmr, .rvmi, .mvr, .rmv => unreachable,
517 .vm, .vmi, .rvm, .rvmr, .rvmi, .mvr, .rmv => unreachable,
504518 };
505519 if (segment_override) |seg| {
506520 legacy.setSegmentOverride(seg);
......@@ -517,7 +531,7 @@ pub const Instruction = struct {
517531 rex.w = inst.encoding.data.mode == .long;
518532
519533 switch (op_en) {
520 .z, .i, .zi, .fd, .td, .d => {},
534 .z, .i, .zi, .ii, .ia, .fd, .td, .d => {},
521535 .o, .oz, .oi => rex.b = inst.ops[0].reg.isExtended(),
522536 .zo => rex.b = inst.ops[1].reg.isExtended(),
523537 .m, .mi, .m1, .mc, .mr, .rm, .rmi, .mri, .mrc, .rm0, .rmv => {
......@@ -536,7 +550,7 @@ pub const Instruction = struct {
536550 rex.b = b_x_op.isBaseExtended();
537551 rex.x = b_x_op.isIndexExtended();
538552 },
539 .vmi, .rvm, .rvmr, .rvmi, .mvr => unreachable,
553 .vm, .vmi, .rvm, .rvmr, .rvmi, .mvr => unreachable,
540554 }
541555
542556 try encoder.rex(rex);
......@@ -552,21 +566,19 @@ pub const Instruction = struct {
552566 vex.w = inst.encoding.data.mode.isLong();
553567
554568 switch (op_en) {
555 .z, .i, .zi, .fd, .td, .d => {},
556 .o, .oz, .oi => vex.b = inst.ops[0].reg.isExtended(),
557 .zo => vex.b = inst.ops[1].reg.isExtended(),
558 .m, .mi, .m1, .mc, .mr, .rm, .rmi, .mri, .mrc, .rm0, .vmi, .rvm, .rvmr, .rvmi, .mvr, .rmv => {
569 .z, .i, .zi, .ii, .ia, .fd, .td, .d, .o, .oz, .oi, .zo => unreachable,
570 .m, .mi, .m1, .mc, .mr, .rm, .rmi, .mri, .mrc, .rm0, .vm, .vmi, .rvm, .rvmr, .rvmi, .mvr, .rmv => {
559571 const r_op = switch (op_en) {
560572 .rm, .rmi, .rm0, .rvm, .rvmr, .rvmi, .rmv => inst.ops[0],
561573 .mr, .mri, .mrc => inst.ops[1],
562574 .mvr => inst.ops[2],
563 .m, .mi, .m1, .mc, .vmi => .none,
575 .m, .mi, .m1, .mc, .vm, .vmi => .none,
564576 else => unreachable,
565577 };
566578 vex.r = r_op.isBaseExtended();
567579
568580 const b_x_op = switch (op_en) {
569 .rm, .rmi, .rm0, .vmi, .rmv => inst.ops[1],
581 .rm, .rmi, .rm0, .vm, .vmi, .rmv => inst.ops[1],
570582 .m, .mi, .m1, .mc, .mr, .mri, .mrc, .mvr => inst.ops[0],
571583 .rvm, .rvmr, .rvmi => inst.ops[2],
572584 else => unreachable,
......@@ -595,7 +607,7 @@ pub const Instruction = struct {
595607
596608 switch (op_en) {
597609 else => {},
598 .vmi => vex.v = inst.ops[0].reg,
610 .vm, .vmi => vex.v = inst.ops[0].reg,
599611 .rvm, .rvmr, .rvmi => vex.v = inst.ops[1].reg,
600612 .rmv => vex.v = inst.ops[2].reg,
601613 }
src/arch/x86_64/encodings.zig+625-100
......@@ -13,6 +13,16 @@ pub const Entry = struct { Mnemonic, OpEn, []const Op, []const u8, modrm_ext, Mo
1313// zig fmt: off
1414pub const table = [_]Entry{
1515 // General-purpose
16 .{ .aaa, .z, &.{}, &.{ 0x37 }, 0, .none, .@"32bit" },
17
18 .{ .aad, .z, &.{ }, &.{ 0xd5, 0x0a }, 0, .none, .@"32bit" },
19 .{ .aad, .zi, &.{ .imm8 }, &.{ 0xd5 }, 0, .none, .@"32bit" },
20
21 .{ .aam, .z, &.{ }, &.{ 0xd4, 0x0a }, 0, .none, .@"32bit" },
22 .{ .aam, .z, &.{ .imm8 }, &.{ 0xd4 }, 0, .none, .@"32bit" },
23
24 .{ .aas, .z, &.{}, &.{ 0x3f }, 0, .none, .@"32bit" },
25
1626 .{ .adc, .zi, &.{ .al, .imm8 }, &.{ 0x14 }, 0, .none, .none },
1727 .{ .adc, .zi, &.{ .ax, .imm16 }, &.{ 0x15 }, 0, .short, .none },
1828 .{ .adc, .zi, &.{ .eax, .imm32 }, &.{ 0x15 }, 0, .none, .none },
......@@ -82,6 +92,11 @@ pub const table = [_]Entry{
8292 .{ .@"and", .rm, &.{ .r32, .rm32 }, &.{ 0x23 }, 0, .none, .none },
8393 .{ .@"and", .rm, &.{ .r64, .rm64 }, &.{ 0x23 }, 0, .long, .none },
8494
95 .{ .arpl, .mr, &.{ .rm16, .r16 }, &.{ 0x63 }, 0, .none, .@"32bit" },
96
97 .{ .bound, .rm, &.{ .r16, .m }, &.{ 0x62 }, 0, .short, .@"32bit" },
98 .{ .bound, .rm, &.{ .r32, .m }, &.{ 0x62 }, 0, .short, .@"32bit" },
99
85100 .{ .bsf, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0xbc }, 0, .short, .none },
86101 .{ .bsf, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0xbc }, 0, .none, .none },
87102 .{ .bsf, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0xbc }, 0, .long, .none },
......@@ -122,15 +137,12 @@ pub const table = [_]Entry{
122137 .{ .bts, .mi, &.{ .rm64, .imm8 }, &.{ 0x0f, 0xba }, 5, .long, .none },
123138
124139 .{ .call, .d, &.{ .rel32 }, &.{ 0xe8 }, 0, .none, .none },
125 .{ .call, .m, &.{ .rm64 }, &.{ 0xff }, 2, .none, .none },
140 .{ .call, .m, &.{ .rm32 }, &.{ 0xff }, 2, .none, .@"32bit" },
141 .{ .call, .m, &.{ .rm64 }, &.{ 0xff }, 2, .none, .@"64bit" },
126142
127 .{ .cbw, .z, &.{ .o16 }, &.{ 0x98 }, 0, .short, .none },
128 .{ .cwde, .z, &.{ .o32 }, &.{ 0x98 }, 0, .none, .none },
129 .{ .cdqe, .z, &.{ .o64 }, &.{ 0x98 }, 0, .long, .none },
130
131 .{ .cwd, .z, &.{ .o16 }, &.{ 0x99 }, 0, .short, .none },
132 .{ .cdq, .z, &.{ .o32 }, &.{ 0x99 }, 0, .none, .none },
133 .{ .cqo, .z, &.{ .o64 }, &.{ 0x99 }, 0, .long, .none },
143 .{ .cbw, .z, &.{}, &.{ 0x98 }, 0, .short, .none },
144 .{ .cwde, .z, &.{}, &.{ 0x98 }, 0, .none, .none },
145 .{ .cdqe, .z, &.{}, &.{ 0x98 }, 0, .long, .none },
134146
135147 .{ .clac, .z, &.{}, &.{ 0x0f, 0x01, 0xca }, 0, .none, .smap },
136148
......@@ -138,14 +150,24 @@ pub const table = [_]Entry{
138150
139151 .{ .cld, .z, &.{}, &.{ 0xfc }, 0, .none, .none },
140152
153 .{ .cldemote, .m, &.{ .m8 }, &.{ 0x0f, 0x1c }, 0, .none, .cldemote },
154
141155 .{ .clflush, .m, &.{ .m8 }, &.{ 0x0f, 0xae }, 7, .none, .none },
142156
157 .{ .clflushopt, .m, &.{ .m8 }, &.{ 0x66, 0x0f, 0xae }, 7, .none, .clflushopt },
158
143159 .{ .cli, .z, &.{}, &.{ 0xfa }, 0, .none, .none },
144160
161 .{ .clrssbsy, .m, &.{ .m64 }, &.{ 0xf3, 0x0f, 0xae }, 6, .none, .shstk },
162
145163 .{ .clts, .z, &.{}, &.{ 0x0f, 0x06 }, 0, .none, .none },
146164
147165 .{ .clui, .z, &.{}, &.{ 0xf3, 0x0f, 0x01, 0xee }, 0, .none, .uintr },
148166
167 .{ .clwb, .m, &.{ .m8 }, &.{ 0x66, 0x0f, 0xae }, 6, .none, .clwb },
168
169 .{ .cmc, .z, &.{}, &.{ 0xf5 }, 0, .none, .none },
170
149171 .{ .cmova, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x47 }, 0, .short, .cmov },
150172 .{ .cmova, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x47 }, 0, .none, .cmov },
151173 .{ .cmova, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x47 }, 0, .long, .cmov },
......@@ -264,11 +286,10 @@ pub const table = [_]Entry{
264286 .{ .cmps, .z, &.{ .m16, .m16 }, &.{ 0xa7 }, 0, .short, .none },
265287 .{ .cmps, .z, &.{ .m32, .m32 }, &.{ 0xa7 }, 0, .none, .none },
266288 .{ .cmps, .z, &.{ .m64, .m64 }, &.{ 0xa7 }, 0, .long, .none },
267
268 .{ .cmpsb, .z, &.{}, &.{ 0xa6 }, 0, .none, .none },
269 .{ .cmpsw, .z, &.{}, &.{ 0xa7 }, 0, .short, .none },
270 .{ .cmpsd, .z, &.{}, &.{ 0xa7 }, 0, .none, .none },
271 .{ .cmpsq, .z, &.{}, &.{ 0xa7 }, 0, .long, .none },
289 .{ .cmpsb, .z, &.{ }, &.{ 0xa6 }, 0, .none, .none },
290 .{ .cmpsw, .z, &.{ }, &.{ 0xa7 }, 0, .short, .none },
291 .{ .cmpsd, .z, &.{ }, &.{ 0xa7 }, 0, .none, .none },
292 .{ .cmpsq, .z, &.{ }, &.{ 0xa7 }, 0, .long, .none },
272293
273294 .{ .cmpxchg, .mr, &.{ .rm8, .r8 }, &.{ 0x0f, 0xb0 }, 0, .none, .none },
274295 .{ .cmpxchg, .mr, &.{ .rm8, .r8 }, &.{ 0x0f, 0xb0 }, 0, .rex, .none },
......@@ -281,6 +302,14 @@ pub const table = [_]Entry{
281302
282303 .{ .cpuid, .z, &.{}, &.{ 0x0f, 0xa2 }, 0, .none, .none },
283304
305 .{ .cwd, .z, &.{}, &.{ 0x99 }, 0, .short, .none },
306 .{ .cdq, .z, &.{}, &.{ 0x99 }, 0, .none, .none },
307 .{ .cqo, .z, &.{}, &.{ 0x99 }, 0, .long, .none },
308
309 .{ .daa, .z, &.{}, &.{ 0x27 }, 0, .none, .@"32bit" },
310
311 .{ .das, .z, &.{}, &.{ 0x27 }, 0, .none, .@"32bit" },
312
284313 .{ .dec, .m, &.{ .rm8 }, &.{ 0xfe }, 1, .none, .none },
285314 .{ .dec, .m, &.{ .rm8 }, &.{ 0xfe }, 1, .rex, .none },
286315 .{ .dec, .m, &.{ .rm16 }, &.{ 0xff }, 1, .short, .none },
......@@ -293,26 +322,50 @@ pub const table = [_]Entry{
293322 .{ .div, .m, &.{ .rm32 }, &.{ 0xf7 }, 6, .none, .none },
294323 .{ .div, .m, &.{ .rm64 }, &.{ 0xf7 }, 6, .long, .none },
295324
325 .{ .endbr32, .z, &.{}, &.{ 0xf3, 0x0f, 0x1e, 0xfb }, 0, .none, .none },
326
327 .{ .endbr64, .z, &.{}, &.{ 0xf3, 0x0f, 0x1e, 0xfa }, 0, .none, .none },
328
329 .{ .enqcmd, .rm, &.{ .r32, .m }, &.{ 0xf2, 0x0f, 0x38, 0xf8 }, 0, .none, .enqcmd },
330 .{ .enqcmd, .rm, &.{ .r64, .m }, &.{ 0xf2, 0x0f, 0x38, 0xf8 }, 0, .none, .enqcmd },
331
332 .{ .enqcmds, .rm, &.{ .r32, .m }, &.{ 0xf3, 0x0f, 0x38, 0xf8 }, 0, .none, .enqcmd },
333 .{ .enqcmds, .rm, &.{ .r64, .m }, &.{ 0xf3, 0x0f, 0x38, 0xf8 }, 0, .none, .enqcmd },
334
335 .{ .enter, .ii, &.{ .imm16, .imm8 }, &.{ 0xc8 }, 0, .none, .none },
336
337 .{ .hlt, .z, &.{}, &.{ 0xf4 }, 0, .none, .none },
338
339 .{ .hreset, .ia, &.{ .imm8 }, &.{ 0xf3, 0x0f, 0x3a, 0xf0 }, 0, .none, .hreset },
340 .{ .hreset, .ia, &.{ .imm8, .eax }, &.{ 0xf3, 0x0f, 0x3a, 0xf0 }, 0, .none, .hreset },
341
296342 .{ .idiv, .m, &.{ .rm8 }, &.{ 0xf6 }, 7, .none, .none },
297343 .{ .idiv, .m, &.{ .rm8 }, &.{ 0xf6 }, 7, .rex, .none },
298344 .{ .idiv, .m, &.{ .rm16 }, &.{ 0xf7 }, 7, .short, .none },
299345 .{ .idiv, .m, &.{ .rm32 }, &.{ 0xf7 }, 7, .none, .none },
300346 .{ .idiv, .m, &.{ .rm64 }, &.{ 0xf7 }, 7, .long, .none },
301347
302 .{ .imul, .m, &.{ .rm8 }, &.{ 0xf6 }, 5, .none, .none },
303 .{ .imul, .m, &.{ .rm8 }, &.{ 0xf6 }, 5, .rex, .none },
304 .{ .imul, .m, &.{ .rm16, }, &.{ 0xf7 }, 5, .short, .none },
305 .{ .imul, .m, &.{ .rm32, }, &.{ 0xf7 }, 5, .none, .none },
306 .{ .imul, .m, &.{ .rm64, }, &.{ 0xf7 }, 5, .long, .none },
348 .{ .imul, .m, &.{ .rm8 }, &.{ 0xf6 }, 5, .none, .none },
349 .{ .imul, .m, &.{ .rm8 }, &.{ 0xf6 }, 5, .rex, .none },
350 .{ .imul, .m, &.{ .rm16, }, &.{ 0xf7 }, 5, .short, .none },
351 .{ .imul, .m, &.{ .rm32, }, &.{ 0xf7 }, 5, .none, .none },
352 .{ .imul, .m, &.{ .rm64, }, &.{ 0xf7 }, 5, .long, .none },
307353 .{ .imul, .rm, &.{ .r16, .rm16, }, &.{ 0x0f, 0xaf }, 0, .short, .none },
308354 .{ .imul, .rm, &.{ .r32, .rm32, }, &.{ 0x0f, 0xaf }, 0, .none, .none },
309355 .{ .imul, .rm, &.{ .r64, .rm64, }, &.{ 0x0f, 0xaf }, 0, .long, .none },
310 .{ .imul, .rmi, &.{ .r16, .rm16, .imm8s }, &.{ 0x6b }, 0, .short, .none },
311 .{ .imul, .rmi, &.{ .r32, .rm32, .imm8s }, &.{ 0x6b }, 0, .none, .none },
312 .{ .imul, .rmi, &.{ .r64, .rm64, .imm8s }, &.{ 0x6b }, 0, .long, .none },
313 .{ .imul, .rmi, &.{ .r16, .rm16, .imm16 }, &.{ 0x69 }, 0, .short, .none },
314 .{ .imul, .rmi, &.{ .r32, .rm32, .imm32 }, &.{ 0x69 }, 0, .none, .none },
315 .{ .imul, .rmi, &.{ .r64, .rm64, .imm32 }, &.{ 0x69 }, 0, .long, .none },
356 .{ .imul, .rmi, &.{ .r16, .rm16, .imm8s }, &.{ 0x6b }, 0, .short, .none },
357 .{ .imul, .rmi, &.{ .r32, .rm32, .imm8s }, &.{ 0x6b }, 0, .none, .none },
358 .{ .imul, .rmi, &.{ .r64, .rm64, .imm8s }, &.{ 0x6b }, 0, .long, .none },
359 .{ .imul, .rmi, &.{ .r16, .rm16, .imm16 }, &.{ 0x69 }, 0, .short, .none },
360 .{ .imul, .rmi, &.{ .r32, .rm32, .imm32 }, &.{ 0x69 }, 0, .none, .none },
361 .{ .imul, .rmi, &.{ .r64, .rm64, .imm32 }, &.{ 0x69 }, 0, .long, .none },
362
363 .{ .in, .zi, &.{ .al, .imm8 }, &.{ 0xe4 }, 0, .none, .none },
364 .{ .in, .zi, &.{ .ax, .imm8 }, &.{ 0xe5 }, 0, .short, .none },
365 .{ .in, .zi, &.{ .eax, .imm8 }, &.{ 0xe5 }, 0, .none, .none },
366 .{ .in, .z, &.{ .al, .dx }, &.{ 0xec }, 0, .none, .none },
367 .{ .in, .z, &.{ .ax, .dx }, &.{ 0xed }, 0, .short, .none },
368 .{ .in, .z, &.{ .eax, .dx }, &.{ 0xed }, 0, .none, .none },
316369
317370 .{ .inc, .m, &.{ .rm8 }, &.{ 0xfe }, 0, .none, .none },
318371 .{ .inc, .m, &.{ .rm8 }, &.{ 0xfe }, 0, .rex, .none },
......@@ -320,58 +373,108 @@ pub const table = [_]Entry{
320373 .{ .inc, .m, &.{ .rm32 }, &.{ 0xff }, 0, .none, .none },
321374 .{ .inc, .m, &.{ .rm64 }, &.{ 0xff }, 0, .long, .none },
322375
323 .{ .int3, .z, &.{}, &.{ 0xcc }, 0, .none, .none },
324
325 .{ .ja, .d, &.{ .rel32 }, &.{ 0x0f, 0x87 }, 0, .none, .none },
326 .{ .jae, .d, &.{ .rel32 }, &.{ 0x0f, 0x83 }, 0, .none, .none },
327 .{ .jb, .d, &.{ .rel32 }, &.{ 0x0f, 0x82 }, 0, .none, .none },
328 .{ .jbe, .d, &.{ .rel32 }, &.{ 0x0f, 0x86 }, 0, .none, .none },
329 .{ .jc, .d, &.{ .rel32 }, &.{ 0x0f, 0x82 }, 0, .none, .none },
330 .{ .jrcxz, .d, &.{ .rel32 }, &.{ 0xe3 }, 0, .none, .none },
331 .{ .je, .d, &.{ .rel32 }, &.{ 0x0f, 0x84 }, 0, .none, .none },
332 .{ .jg, .d, &.{ .rel32 }, &.{ 0x0f, 0x8f }, 0, .none, .none },
333 .{ .jge, .d, &.{ .rel32 }, &.{ 0x0f, 0x8d }, 0, .none, .none },
334 .{ .jl, .d, &.{ .rel32 }, &.{ 0x0f, 0x8c }, 0, .none, .none },
335 .{ .jle, .d, &.{ .rel32 }, &.{ 0x0f, 0x8e }, 0, .none, .none },
336 .{ .jna, .d, &.{ .rel32 }, &.{ 0x0f, 0x86 }, 0, .none, .none },
337 .{ .jnae, .d, &.{ .rel32 }, &.{ 0x0f, 0x82 }, 0, .none, .none },
338 .{ .jnb, .d, &.{ .rel32 }, &.{ 0x0f, 0x83 }, 0, .none, .none },
339 .{ .jnbe, .d, &.{ .rel32 }, &.{ 0x0f, 0x87 }, 0, .none, .none },
340 .{ .jnc, .d, &.{ .rel32 }, &.{ 0x0f, 0x83 }, 0, .none, .none },
341 .{ .jne, .d, &.{ .rel32 }, &.{ 0x0f, 0x85 }, 0, .none, .none },
342 .{ .jng, .d, &.{ .rel32 }, &.{ 0x0f, 0x8e }, 0, .none, .none },
343 .{ .jnge, .d, &.{ .rel32 }, &.{ 0x0f, 0x8c }, 0, .none, .none },
344 .{ .jnl, .d, &.{ .rel32 }, &.{ 0x0f, 0x8d }, 0, .none, .none },
345 .{ .jnle, .d, &.{ .rel32 }, &.{ 0x0f, 0x8f }, 0, .none, .none },
346 .{ .jno, .d, &.{ .rel32 }, &.{ 0x0f, 0x81 }, 0, .none, .none },
347 .{ .jnp, .d, &.{ .rel32 }, &.{ 0x0f, 0x8b }, 0, .none, .none },
348 .{ .jns, .d, &.{ .rel32 }, &.{ 0x0f, 0x89 }, 0, .none, .none },
349 .{ .jnz, .d, &.{ .rel32 }, &.{ 0x0f, 0x85 }, 0, .none, .none },
350 .{ .jo, .d, &.{ .rel32 }, &.{ 0x0f, 0x80 }, 0, .none, .none },
351 .{ .jp, .d, &.{ .rel32 }, &.{ 0x0f, 0x8a }, 0, .none, .none },
352 .{ .jpe, .d, &.{ .rel32 }, &.{ 0x0f, 0x8a }, 0, .none, .none },
353 .{ .jpo, .d, &.{ .rel32 }, &.{ 0x0f, 0x8b }, 0, .none, .none },
354 .{ .js, .d, &.{ .rel32 }, &.{ 0x0f, 0x88 }, 0, .none, .none },
355 .{ .jz, .d, &.{ .rel32 }, &.{ 0x0f, 0x84 }, 0, .none, .none },
376 .{ .incsspd, .m, &.{ .r32 }, &.{ 0xf3, 0x0f, 0xae }, 5, .none, .shstk },
377 .{ .incsspq, .m, &.{ .r64 }, &.{ 0xf3, 0x0f, 0xae }, 5, .long, .shstk },
378
379 .{ .ins, .z, &.{ .m8, .dx }, &.{ 0x6c }, 0, .none, .none },
380 .{ .ins, .z, &.{ .m16, .dx }, &.{ 0x6d }, 0, .short, .none },
381 .{ .ins, .z, &.{ .m32, .dx }, &.{ 0x6d }, 0, .none, .none },
382 .{ .insb, .z, &.{ }, &.{ 0x6c }, 0, .none, .none },
383 .{ .insw, .z, &.{ }, &.{ 0x6d }, 0, .short, .none },
384 .{ .insd, .z, &.{ }, &.{ 0x6d }, 0, .none, .none },
385
386 .{ .int3, .z, &.{ }, &.{ 0xcc }, 0, .none, .none },
387 .{ .int, .i, &.{ .imm8 }, &.{ 0xcd }, 0, .none, .none },
388 .{ .into, .z, &.{ }, &.{ 0xce }, 0, .none, .@"32bit" },
389 .{ .int1, .z, &.{ }, &.{ 0xf1 }, 0, .none, .none },
390
391 .{ .invd, .z, &.{}, &.{ 0x0f, 0x08 }, 0, .none, .none },
392
393 .{ .invlpg, .m, &.{ .m }, &.{ 0x0f, 0x01 }, 7, .none, .none },
394
395 .{ .invpcid, .rm, &.{ .r32, .m128 }, &.{ 0x66, 0x0f, 0x38, 0x82 }, 0, .none, .@"invpcid 32bit" },
396 .{ .invpcid, .rm, &.{ .r64, .m128 }, &.{ 0x66, 0x0f, 0x38, 0x82 }, 0, .none, .@"invpcid 64bit" },
397
398 .{ .iretw, .z, &.{}, &.{ 0xcf }, 0, .short, .none },
399 .{ .iretd, .z, &.{}, &.{ 0xcf }, 0, .none, .none },
400 .{ .iret, .z, &.{}, &.{ 0xcf }, 0, .none, .none },
401 .{ .iretq, .z, &.{}, &.{ 0xcf }, 0, .long, .none },
402
403 .{ .ja, .d, &.{ .rel32 }, &.{ 0x0f, 0x87 }, 0, .none, .none },
404 .{ .jae, .d, &.{ .rel32 }, &.{ 0x0f, 0x83 }, 0, .none, .none },
405 .{ .jb, .d, &.{ .rel32 }, &.{ 0x0f, 0x82 }, 0, .none, .none },
406 .{ .jbe, .d, &.{ .rel32 }, &.{ 0x0f, 0x86 }, 0, .none, .none },
407 .{ .jc, .d, &.{ .rel32 }, &.{ 0x0f, 0x82 }, 0, .none, .none },
408 .{ .jcxz, .d, &.{ .rel32 }, &.{ 0xe3 }, 0, .short, .@"32bit" },
409 .{ .jecxz, .d, &.{ .rel32 }, &.{ 0xe3 }, 0, .none, .@"32bit" },
410 .{ .jrcxz, .d, &.{ .rel32 }, &.{ 0xe3 }, 0, .none, .@"64bit" },
411 .{ .je, .d, &.{ .rel32 }, &.{ 0x0f, 0x84 }, 0, .none, .none },
412 .{ .jg, .d, &.{ .rel32 }, &.{ 0x0f, 0x8f }, 0, .none, .none },
413 .{ .jge, .d, &.{ .rel32 }, &.{ 0x0f, 0x8d }, 0, .none, .none },
414 .{ .jl, .d, &.{ .rel32 }, &.{ 0x0f, 0x8c }, 0, .none, .none },
415 .{ .jle, .d, &.{ .rel32 }, &.{ 0x0f, 0x8e }, 0, .none, .none },
416 .{ .jna, .d, &.{ .rel32 }, &.{ 0x0f, 0x86 }, 0, .none, .none },
417 .{ .jnae, .d, &.{ .rel32 }, &.{ 0x0f, 0x82 }, 0, .none, .none },
418 .{ .jnb, .d, &.{ .rel32 }, &.{ 0x0f, 0x83 }, 0, .none, .none },
419 .{ .jnbe, .d, &.{ .rel32 }, &.{ 0x0f, 0x87 }, 0, .none, .none },
420 .{ .jnc, .d, &.{ .rel32 }, &.{ 0x0f, 0x83 }, 0, .none, .none },
421 .{ .jne, .d, &.{ .rel32 }, &.{ 0x0f, 0x85 }, 0, .none, .none },
422 .{ .jng, .d, &.{ .rel32 }, &.{ 0x0f, 0x8e }, 0, .none, .none },
423 .{ .jnge, .d, &.{ .rel32 }, &.{ 0x0f, 0x8c }, 0, .none, .none },
424 .{ .jnl, .d, &.{ .rel32 }, &.{ 0x0f, 0x8d }, 0, .none, .none },
425 .{ .jnle, .d, &.{ .rel32 }, &.{ 0x0f, 0x8f }, 0, .none, .none },
426 .{ .jno, .d, &.{ .rel32 }, &.{ 0x0f, 0x81 }, 0, .none, .none },
427 .{ .jnp, .d, &.{ .rel32 }, &.{ 0x0f, 0x8b }, 0, .none, .none },
428 .{ .jns, .d, &.{ .rel32 }, &.{ 0x0f, 0x89 }, 0, .none, .none },
429 .{ .jnz, .d, &.{ .rel32 }, &.{ 0x0f, 0x85 }, 0, .none, .none },
430 .{ .jo, .d, &.{ .rel32 }, &.{ 0x0f, 0x80 }, 0, .none, .none },
431 .{ .jp, .d, &.{ .rel32 }, &.{ 0x0f, 0x8a }, 0, .none, .none },
432 .{ .jpe, .d, &.{ .rel32 }, &.{ 0x0f, 0x8a }, 0, .none, .none },
433 .{ .jpo, .d, &.{ .rel32 }, &.{ 0x0f, 0x8b }, 0, .none, .none },
434 .{ .js, .d, &.{ .rel32 }, &.{ 0x0f, 0x88 }, 0, .none, .none },
435 .{ .jz, .d, &.{ .rel32 }, &.{ 0x0f, 0x84 }, 0, .none, .none },
356436
357437 .{ .jmp, .d, &.{ .rel32 }, &.{ 0xe9 }, 0, .none, .none },
358438 .{ .jmp, .m, &.{ .rm64 }, &.{ 0xff }, 4, .none, .none },
359439
440 .{ .lahf, .z, &.{}, &.{ 0x9f }, 0, .none, .sahf },
441
442 .{ .lar, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x02 }, 0, .none, .none },
443 .{ .lar, .rm, &.{ .r32, .r32_m16 }, &.{ 0x0f, 0x02 }, 0, .none, .none },
444
360445 .{ .lea, .rm, &.{ .r16, .m }, &.{ 0x8d }, 0, .short, .none },
361446 .{ .lea, .rm, &.{ .r32, .m }, &.{ 0x8d }, 0, .none, .none },
362447 .{ .lea, .rm, &.{ .r64, .m }, &.{ 0x8d }, 0, .long, .none },
363448
449 .{ .leave, .z, &.{}, &.{ 0xc9 }, 0, .none, .none },
450
364451 .{ .lfence, .z, &.{}, &.{ 0x0f, 0xae, 0xe8 }, 0, .none, .none },
365452
453 .{ .lgdt, .m, &.{ .m }, &.{ 0x0f, 0x01 }, 2, .none, .none },
454 .{ .lidt, .m, &.{ .m }, &.{ 0x0f, 0x01 }, 3, .none, .none },
455
456 .{ .lldt, .m, &.{ .rm16 }, &.{ 0x0f, 0x00 }, 2, .none, .none },
457
458 .{ .lmsw, .m, &.{ .rm16 }, &.{ 0x0f, 0x01 }, 6, .none, .none },
459
366460 .{ .lods, .z, &.{ .m8 }, &.{ 0xac }, 0, .none, .none },
367461 .{ .lods, .z, &.{ .m16 }, &.{ 0xad }, 0, .short, .none },
368462 .{ .lods, .z, &.{ .m32 }, &.{ 0xad }, 0, .none, .none },
369463 .{ .lods, .z, &.{ .m64 }, &.{ 0xad }, 0, .long, .none },
464 .{ .lodsb, .z, &.{ }, &.{ 0xac }, 0, .none, .none },
465 .{ .lodsw, .z, &.{ }, &.{ 0xad }, 0, .short, .none },
466 .{ .lodsd, .z, &.{ }, &.{ 0xad }, 0, .none, .none },
467 .{ .lodsq, .z, &.{ }, &.{ 0xad }, 0, .long, .none },
468
469 .{ .loop, .d, &.{ .rel8 }, &.{ 0xe2 }, 0, .none, .none },
470 .{ .loope, .d, &.{ .rel8 }, &.{ 0xe1 }, 0, .none, .none },
471 .{ .loopne, .d, &.{ .rel8 }, &.{ 0xe0 }, 0, .none, .none },
370472
371 .{ .lodsb, .z, &.{}, &.{ 0xac }, 0, .none, .none },
372 .{ .lodsw, .z, &.{}, &.{ 0xad }, 0, .short, .none },
373 .{ .lodsd, .z, &.{}, &.{ 0xad }, 0, .none, .none },
374 .{ .lodsq, .z, &.{}, &.{ 0xad }, 0, .long, .none },
473 .{ .lsl, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x03 }, 0, .none, .none },
474 .{ .lsl, .rm, &.{ .r32, .r32_m16 }, &.{ 0x0f, 0x03 }, 0, .none, .none },
475 .{ .lsl, .rm, &.{ .r64, .r32_m16 }, &.{ 0x0f, 0x03 }, 0, .none, .none },
476
477 .{ .ltr, .m, &.{ .rm16 }, &.{ 0x0f, 0x00 }, 3, .none, .none },
375478
376479 .{ .lzcnt, .rm, &.{ .r16, .rm16 }, &.{ 0xf3, 0x0f, 0xbd }, 0, .short, .lzcnt },
377480 .{ .lzcnt, .rm, &.{ .r32, .rm32 }, &.{ 0xf3, 0x0f, 0xbd }, 0, .none, .lzcnt },
......@@ -414,6 +517,16 @@ pub const table = [_]Entry{
414517 .{ .mov, .mi, &.{ .rm32, .imm32 }, &.{ 0xc7 }, 0, .none, .none },
415518 .{ .mov, .mi, &.{ .rm64, .imm32s }, &.{ 0xc7 }, 0, .long, .none },
416519
520 .{ .mov, .mr, &.{ .r32, .cr }, &.{ 0x0f, 0x20 }, 0, .none, .@"32bit" },
521 .{ .mov, .mr, &.{ .r64, .cr }, &.{ 0x0f, 0x20 }, 0, .none, .@"64bit" },
522 .{ .mov, .rm, &.{ .cr, .r32 }, &.{ 0x0f, 0x22 }, 0, .none, .@"32bit" },
523 .{ .mov, .rm, &.{ .cr, .r64 }, &.{ 0x0f, 0x22 }, 0, .none, .@"64bit" },
524
525 .{ .mov, .mr, &.{ .r32, .dr }, &.{ 0x0f, 0x21 }, 0, .none, .@"32bit" },
526 .{ .mov, .mr, &.{ .r64, .dr }, &.{ 0x0f, 0x21 }, 0, .none, .@"64bit" },
527 .{ .mov, .rm, &.{ .dr, .r32 }, &.{ 0x0f, 0x23 }, 0, .none, .@"32bit" },
528 .{ .mov, .rm, &.{ .dr, .r64 }, &.{ 0x0f, 0x23 }, 0, .none, .@"64bit" },
529
417530 .{ .movbe, .rm, &.{ .r16, .m16 }, &.{ 0x0f, 0x38, 0xf0 }, 0, .short, .movbe },
418531 .{ .movbe, .rm, &.{ .r32, .m32 }, &.{ 0x0f, 0x38, 0xf0 }, 0, .none, .movbe },
419532 .{ .movbe, .rm, &.{ .r64, .m64 }, &.{ 0x0f, 0x38, 0xf0 }, 0, .long, .movbe },
......@@ -425,11 +538,10 @@ pub const table = [_]Entry{
425538 .{ .movs, .z, &.{ .m16, .m16 }, &.{ 0xa5 }, 0, .short, .none },
426539 .{ .movs, .z, &.{ .m32, .m32 }, &.{ 0xa5 }, 0, .none, .none },
427540 .{ .movs, .z, &.{ .m64, .m64 }, &.{ 0xa5 }, 0, .long, .none },
428
429 .{ .movsb, .z, &.{}, &.{ 0xa4 }, 0, .none, .none },
430 .{ .movsw, .z, &.{}, &.{ 0xa5 }, 0, .short, .none },
431 .{ .movsd, .z, &.{}, &.{ 0xa5 }, 0, .none, .none },
432 .{ .movsq, .z, &.{}, &.{ 0xa5 }, 0, .long, .none },
541 .{ .movsb, .z, &.{ }, &.{ 0xa4 }, 0, .none, .none },
542 .{ .movsw, .z, &.{ }, &.{ 0xa5 }, 0, .short, .none },
543 .{ .movsd, .z, &.{ }, &.{ 0xa5 }, 0, .none, .none },
544 .{ .movsq, .z, &.{ }, &.{ 0xa5 }, 0, .long, .none },
433545
434546 .{ .movsx, .rm, &.{ .r16, .rm8 }, &.{ 0x0f, 0xbe }, 0, .short, .none },
435547 .{ .movsx, .rm, &.{ .r16, .rm8 }, &.{ 0x0f, 0xbe }, 0, .rex_short, .none },
......@@ -441,8 +553,8 @@ pub const table = [_]Entry{
441553 .{ .movsx, .rm, &.{ .r64, .rm16 }, &.{ 0x0f, 0xbf }, 0, .long, .none },
442554
443555 // This instruction is discouraged.
444 .{ .movsxd, .rm, &.{ .r32, .rm32 }, &.{ 0x63 }, 0, .none, .none },
445 .{ .movsxd, .rm, &.{ .r64, .rm32 }, &.{ 0x63 }, 0, .long, .none },
556 .{ .movsxd, .rm, &.{ .r32, .rm32 }, &.{ 0x63 }, 0, .none, .@"64bit" },
557 .{ .movsxd, .rm, &.{ .r64, .rm32 }, &.{ 0x63 }, 0, .long, .@"64bit" },
446558
447559 .{ .movzx, .rm, &.{ .r16, .rm8 }, &.{ 0x0f, 0xb6 }, 0, .short, .none },
448560 .{ .movzx, .rm, &.{ .r16, .rm8 }, &.{ 0x0f, 0xb6 }, 0, .rex_short, .none },
......@@ -496,6 +608,20 @@ pub const table = [_]Entry{
496608 .{ .@"or", .rm, &.{ .r32, .rm32 }, &.{ 0x0b }, 0, .none, .none },
497609 .{ .@"or", .rm, &.{ .r64, .rm64 }, &.{ 0x0b }, 0, .long, .none },
498610
611 .{ .out, .zi, &.{ .imm8, .al }, &.{ 0xe6 }, 0, .none, .none },
612 .{ .out, .zi, &.{ .imm8, .ax }, &.{ 0xe7 }, 0, .short, .none },
613 .{ .out, .zi, &.{ .imm8, .eax }, &.{ 0xe7 }, 0, .none, .none },
614 .{ .out, .z, &.{ .dx, .al }, &.{ 0xee }, 0, .none, .none },
615 .{ .out, .z, &.{ .dx, .ax }, &.{ 0xef }, 0, .short, .none },
616 .{ .out, .z, &.{ .dx, .eax }, &.{ 0xef }, 0, .none, .none },
617
618 .{ .outs, .z, &.{ .dx, .m8 }, &.{ 0x6e }, 0, .none, .none },
619 .{ .outs, .z, &.{ .dx, .m16 }, &.{ 0x6f }, 0, .short, .none },
620 .{ .outs, .z, &.{ .dx, .m32 }, &.{ 0x6f }, 0, .none, .none },
621 .{ .outsb, .z, &.{ }, &.{ 0x6e }, 0, .none, .none },
622 .{ .outsw, .z, &.{ }, &.{ 0x6f }, 0, .short, .none },
623 .{ .outsd, .z, &.{ }, &.{ 0x6f }, 0, .none, .none },
624
499625 .{ .pause, .z, &.{}, &.{ 0xf3, 0x90 }, 0, .none, .none },
500626
501627 .{ .pop, .o, &.{ .r16 }, &.{ 0x58 }, 0, .short, .none },
......@@ -507,7 +633,9 @@ pub const table = [_]Entry{
507633 .{ .popcnt, .rm, &.{ .r32, .rm32 }, &.{ 0xf3, 0x0f, 0xb8 }, 0, .none, .popcnt },
508634 .{ .popcnt, .rm, &.{ .r64, .rm64 }, &.{ 0xf3, 0x0f, 0xb8 }, 0, .long, .popcnt },
509635
510 .{ .popfq, .z, &.{}, &.{ 0x9d }, 0, .none, .none },
636 .{ .popf, .z, &.{}, &.{ 0x9d }, 0, .short, .none },
637 .{ .popfd, .z, &.{}, &.{ 0x9d }, 0, .none, .@"32bit" },
638 .{ .popfq, .z, &.{}, &.{ 0x9d }, 0, .none, .@"64bit" },
511639
512640 .{ .push, .o, &.{ .r16 }, &.{ 0x50 }, 0, .short, .none },
513641 .{ .push, .o, &.{ .r64 }, &.{ 0x50 }, 0, .none, .none },
......@@ -553,6 +681,35 @@ pub const table = [_]Entry{
553681 .{ .rcr, .mi, &.{ .rm32, .imm8 }, &.{ 0xc1 }, 3, .none, .none },
554682 .{ .rcr, .mi, &.{ .rm64, .imm8 }, &.{ 0xc1 }, 3, .long, .none },
555683
684 .{ .rdfsbase, .m, &.{ .r32 }, &.{ 0xf3 ,0x0f, 0xae }, 0, .none, .fsgsbase },
685 .{ .rdfsbase, .m, &.{ .r64 }, &.{ 0xf3 ,0x0f, 0xae }, 0, .long, .fsgsbase },
686 .{ .rdgsbase, .m, &.{ .r32 }, &.{ 0xf3 ,0x0f, 0xae }, 1, .none, .fsgsbase },
687 .{ .rdgsbase, .m, &.{ .r64 }, &.{ 0xf3 ,0x0f, 0xae }, 1, .long, .fsgsbase },
688
689 .{ .rdmsr, .z, &.{}, &.{ 0x0f, 0x32 }, 0, .none, .none },
690
691 .{ .rdpid, .m, &.{ .r32 }, &.{ 0xf3, 0x0f, 0xc7 }, 7, .none, .@"rdpid 32bit" },
692 .{ .rdpid, .m, &.{ .r64 }, &.{ 0xf3, 0x0f, 0xc7 }, 7, .none, .@"rdpid 64bit" },
693
694 .{ .rdpkru, .z, &.{}, &.{ 0x0f, 0x01, 0xee }, 0, .none, .pku },
695
696 .{ .rdpmc, .z, &.{}, &.{ 0x0f, 0x33 }, 0, .none, .none },
697
698 .{ .rdrand, .m, &.{ .r16 }, &.{ 0x0f, 0xc7 }, 6, .short, .rdrnd },
699 .{ .rdrand, .m, &.{ .r32 }, &.{ 0x0f, 0xc7 }, 6, .none, .rdrnd },
700 .{ .rdrand, .m, &.{ .r64 }, &.{ 0x0f, 0xc7 }, 6, .long, .rdrnd },
701
702 .{ .rdseed, .m, &.{ .r16 }, &.{ 0x0f, 0xc7 }, 7, .short, .rdseed },
703 .{ .rdseed, .m, &.{ .r32 }, &.{ 0x0f, 0xc7 }, 7, .none, .rdseed },
704 .{ .rdseed, .m, &.{ .r64 }, &.{ 0x0f, 0xc7 }, 7, .long, .rdseed },
705
706 .{ .rdssd, .m, &.{ .r32 }, &.{ 0xf3, 0x0f, 0x1e }, 1, .none, .shstk },
707 .{ .rdssq, .m, &.{ .r64 }, &.{ 0xf3, 0x0f, 0x1e }, 1, .long, .shstk },
708
709 .{ .rdtsc, .z, &.{}, &.{ 0x0f, 0x31 }, 0, .none, .none },
710
711 .{ .rdtscp, .z, &.{}, &.{ 0x0f, 0x01, 0xf9 }, 0, .none, .none },
712
556713 .{ .rol, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 0, .none, .none },
557714 .{ .rol, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 0, .rex, .none },
558715 .{ .rol, .mc, &.{ .rm8, .cl }, &.{ 0xd2 }, 0, .none, .none },
......@@ -585,6 +742,10 @@ pub const table = [_]Entry{
585742 .{ .ror, .mi, &.{ .rm32, .imm8 }, &.{ 0xc1 }, 1, .none, .none },
586743 .{ .ror, .mi, &.{ .rm64, .imm8 }, &.{ 0xc1 }, 1, .long, .none },
587744
745 .{ .rsm, .z, &.{}, &.{ 0x0f, 0xaa }, 0, .none, .none },
746
747 .{ .sahf, .z, &.{}, &.{ 0x9e }, 0, .none, .sahf },
748
588749 .{ .sal, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 4, .none, .none },
589750 .{ .sal, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 4, .rex, .none },
590751 .{ .sal, .m1, &.{ .rm16, .unity }, &.{ 0xd1 }, 4, .short, .none },
......@@ -644,11 +805,14 @@ pub const table = [_]Entry{
644805 .{ .scas, .z, &.{ .m16 }, &.{ 0xaf }, 0, .short, .none },
645806 .{ .scas, .z, &.{ .m32 }, &.{ 0xaf }, 0, .none, .none },
646807 .{ .scas, .z, &.{ .m64 }, &.{ 0xaf }, 0, .long, .none },
808 .{ .scasb, .z, &.{ }, &.{ 0xae }, 0, .none, .none },
809 .{ .scasw, .z, &.{ }, &.{ 0xaf }, 0, .short, .none },
810 .{ .scasd, .z, &.{ }, &.{ 0xaf }, 0, .none, .none },
811 .{ .scasq, .z, &.{ }, &.{ 0xaf }, 0, .long, .none },
812
813 .{ .senduipi, .m, &.{ .r64 }, &.{ 0xf3, 0x0f, 0xc7 }, 6, .none, .uintr },
647814
648 .{ .scasb, .z, &.{}, &.{ 0xae }, 0, .none, .none },
649 .{ .scasw, .z, &.{}, &.{ 0xaf }, 0, .short, .none },
650 .{ .scasd, .z, &.{}, &.{ 0xaf }, 0, .none, .none },
651 .{ .scasq, .z, &.{}, &.{ 0xaf }, 0, .long, .none },
815 .{ .serialize, .z, &.{}, &.{ 0x0f, 0x01, 0xe8 }, 0, .none, .serialize },
652816
653817 .{ .seta, .m, &.{ .rm8 }, &.{ 0x0f, 0x97 }, 0, .none, .none },
654818 .{ .seta, .m, &.{ .rm8 }, &.{ 0x0f, 0x97 }, 0, .rex, .none },
......@@ -713,6 +877,14 @@ pub const table = [_]Entry{
713877
714878 .{ .sfence, .z, &.{}, &.{ 0x0f, 0xae, 0xf8 }, 0, .none, .none },
715879
880 .{ .sidt, .m, &.{ .m }, &.{ 0x0f, 0x01 }, 1, .none, .none },
881
882 .{ .sldt, .m, &.{ .rm16 }, &.{ 0x0f, 0x00 }, 0, .none, .none },
883
884 .{ .smsw, .m, &.{ .rm16 }, &.{ 0x0f, 0x01 }, 4, .short, .none },
885 .{ .smsw, .m, &.{ .r32_m16 }, &.{ 0x0f, 0x01 }, 4, .none, .none },
886 .{ .smsw, .m, &.{ .r64_m16 }, &.{ 0x0f, 0x01 }, 4, .long, .none },
887
716888 .{ .shl, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 4, .none, .none },
717889 .{ .shl, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 4, .rex, .none },
718890 .{ .shl, .m1, &.{ .rm16, .unity }, &.{ 0xd1 }, 4, .short, .none },
......@@ -767,17 +939,18 @@ pub const table = [_]Entry{
767939
768940 .{ .sti, .z, &.{}, &.{ 0xfb }, 0, .none, .none },
769941
942 .{ .str, .m, &.{ .rm16 }, &.{ 0x0f, 0x00 }, 1, .none, .none },
943
770944 .{ .stui, .z, &.{}, &.{ 0xf3, 0x0f, 0x01, 0xef }, 0, .none, .uintr },
771945
772946 .{ .stos, .z, &.{ .m8 }, &.{ 0xaa }, 0, .none, .none },
773947 .{ .stos, .z, &.{ .m16 }, &.{ 0xab }, 0, .short, .none },
774948 .{ .stos, .z, &.{ .m32 }, &.{ 0xab }, 0, .none, .none },
775949 .{ .stos, .z, &.{ .m64 }, &.{ 0xab }, 0, .long, .none },
776
777 .{ .stosb, .z, &.{}, &.{ 0xaa }, 0, .none, .none },
778 .{ .stosw, .z, &.{}, &.{ 0xab }, 0, .short, .none },
779 .{ .stosd, .z, &.{}, &.{ 0xab }, 0, .none, .none },
780 .{ .stosq, .z, &.{}, &.{ 0xab }, 0, .long, .none },
950 .{ .stosb, .z, &.{ }, &.{ 0xaa }, 0, .none, .none },
951 .{ .stosw, .z, &.{ }, &.{ 0xab }, 0, .short, .none },
952 .{ .stosd, .z, &.{ }, &.{ 0xab }, 0, .none, .none },
953 .{ .stosq, .z, &.{ }, &.{ 0xab }, 0, .long, .none },
781954
782955 .{ .sub, .zi, &.{ .al, .imm8 }, &.{ 0x2c }, 0, .none, .none },
783956 .{ .sub, .zi, &.{ .ax, .imm16 }, &.{ 0x2d }, 0, .short, .none },
......@@ -802,7 +975,17 @@ pub const table = [_]Entry{
802975 .{ .sub, .rm, &.{ .r32, .rm32 }, &.{ 0x2b }, 0, .none, .none },
803976 .{ .sub, .rm, &.{ .r64, .rm64 }, &.{ 0x2b }, 0, .long, .none },
804977
805 .{ .syscall, .z, &.{}, &.{ 0x0f, 0x05 }, 0, .none, .none },
978 .{ .swapgs, .z, &.{}, &.{ 0x0f, 0x01, 0xf8 }, 0, .none, .@"64bit" },
979
980 .{ .syscall, .z, &.{}, &.{ 0x0f, 0x05 }, 0, .none, .@"64bit" },
981
982 .{ .sysenter, .z, &.{}, &.{ 0x0f, 0x34 }, 0, .none, .none },
983
984 .{ .sysexit, .z, &.{}, &.{ 0x0f, 0x35 }, 0, .none, .none },
985 .{ .sysexit, .z, &.{}, &.{ 0x0f, 0x35 }, 0, .long, .none },
986
987 .{ .sysret, .z, &.{}, &.{ 0x0f, 0x37 }, 0, .none, .none },
988 .{ .sysret, .z, &.{}, &.{ 0x0f, 0x37 }, 0, .long, .none },
806989
807990 .{ .@"test", .zi, &.{ .al, .imm8 }, &.{ 0xa8 }, 0, .none, .none },
808991 .{ .@"test", .zi, &.{ .ax, .imm16 }, &.{ 0xa9 }, 0, .short, .none },
......@@ -819,12 +1002,38 @@ pub const table = [_]Entry{
8191002 .{ .@"test", .mr, &.{ .rm32, .r32 }, &.{ 0x85 }, 0, .none, .none },
8201003 .{ .@"test", .mr, &.{ .rm64, .r64 }, &.{ 0x85 }, 0, .long, .none },
8211004
822 .{ .tzcnt, .rm, &.{ .r16, .rm16 }, &.{ 0xf3, 0x0f, 0xbc }, 0, .short, .bmi },
823 .{ .tzcnt, .rm, &.{ .r32, .rm32 }, &.{ 0xf3, 0x0f, 0xbc }, 0, .none, .bmi },
824 .{ .tzcnt, .rm, &.{ .r64, .rm64 }, &.{ 0xf3, 0x0f, 0xbc }, 0, .long, .bmi },
1005 .{ .testui, .z, &.{}, &.{ 0xf3, 0x0f, 0x01, 0xed }, 0, .none, .uintr },
1006
1007 .{ .tpause, .m, &.{ .r32 }, &.{ 0x66, 0x0f, 0xae }, 6, .none, .waitpkg },
8251008
1009 .{ .ud0, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0xff }, 0, .none, .none },
1010 .{ .ud1, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0xb9 }, 0, .none, .none },
8261011 .{ .ud2, .z, &.{}, &.{ 0x0f, 0x0b }, 0, .none, .none },
8271012
1013 .{ .uiret, .z, &.{}, &.{ 0xf3, 0x0f, 0x01, 0xec }, 0, .none, .uintr },
1014
1015 .{ .umonitor, .m, &.{ .r64 }, &.{ 0xf3, 0x0f, 0xae }, 6, .none, .waitpkg },
1016
1017 .{ .umwait, .m, &.{ .r32 }, &.{ 0xf2, 0x0f, 0xae }, 6, .none, .waitpkg },
1018
1019 .{ .verr, .m, &.{ .rm16 }, &.{ 0x0f, 0x00 }, 4, .none, .none },
1020 .{ .verw, .m, &.{ .rm16 }, &.{ 0x0f, 0x00 }, 5, .none, .none },
1021
1022 .{ .wrfsbase, .m, &.{ .r32 }, &.{ 0xf3 ,0x0f, 0xae }, 2, .none, .fsgsbase },
1023 .{ .wrfsbase, .m, &.{ .r64 }, &.{ 0xf3 ,0x0f, 0xae }, 2, .long, .fsgsbase },
1024 .{ .wrgsbase, .m, &.{ .r32 }, &.{ 0xf3 ,0x0f, 0xae }, 3, .none, .fsgsbase },
1025 .{ .wrgsbase, .m, &.{ .r64 }, &.{ 0xf3 ,0x0f, 0xae }, 3, .long, .fsgsbase },
1026
1027 .{ .wrmsr, .z, &.{}, &.{ 0x0f, 0x30 }, 0, .none, .none },
1028
1029 .{ .wrpkru, .z, &.{}, &.{ 0x0f, 0x01, 0xef }, 0, .none, .pku },
1030
1031 .{ .wrssd, .mr, &.{ .m32, .r32 }, &.{ 0x0f, 0x38, 0xf6 }, 0, .none, .shstk },
1032 .{ .wrssq, .mr, &.{ .m64, .r64 }, &.{ 0x0f, 0x38, 0xf6 }, 0, .long, .shstk },
1033
1034 .{ .wrussd, .mr, &.{ .m32, .r32 }, &.{ 0x66, 0x0f, 0x38, 0xf5 }, 0, .none, .shstk },
1035 .{ .wrussq, .mr, &.{ .m64, .r64 }, &.{ 0x66, 0x0f, 0x38, 0xf5 }, 0, .long, .shstk },
1036
8281037 .{ .xadd, .mr, &.{ .rm8, .r8 }, &.{ 0x0f, 0xc0 }, 0, .none, .none },
8291038 .{ .xadd, .mr, &.{ .rm8, .r8 }, &.{ 0x0f, 0xc0 }, 0, .rex, .none },
8301039 .{ .xadd, .mr, &.{ .rm16, .r16 }, &.{ 0x0f, 0xc1 }, 0, .short, .none },
......@@ -850,6 +1059,11 @@ pub const table = [_]Entry{
8501059
8511060 .{ .xgetbv, .z, &.{}, &.{ 0x0f, 0x01, 0xd0 }, 0, .none, .none },
8521061
1062 .{ .xlat, .z, &.{ .m8 }, &.{ 0xd7 }, 0, .none, .@"32bit" },
1063 .{ .xlat, .z, &.{ .m8 }, &.{ 0xd7 }, 0, .long, .@"64bit" },
1064 .{ .xlatb, .z, &.{ }, &.{ 0xd7 }, 0, .none, .@"32bit" },
1065 .{ .xlatb, .z, &.{ }, &.{ 0xd7 }, 0, .long, .@"64bit" },
1066
8531067 .{ .xor, .zi, &.{ .al, .imm8 }, &.{ 0x34 }, 0, .none, .none },
8541068 .{ .xor, .zi, &.{ .ax, .imm16 }, &.{ 0x35 }, 0, .short, .none },
8551069 .{ .xor, .zi, &.{ .eax, .imm32 }, &.{ 0x35 }, 0, .none, .none },
......@@ -874,12 +1088,96 @@ pub const table = [_]Entry{
8741088 .{ .xor, .rm, &.{ .r64, .rm64 }, &.{ 0x33 }, 0, .long, .none },
8751089
8761090 // X87
1091 .{ .f2xm1, .z, &.{}, &.{ 0xd9, 0xf0 }, 0, .none, .x87 },
1092
8771093 .{ .fabs, .z, &.{}, &.{ 0xd9, 0xe1 }, 0, .none, .x87 },
8781094
1095 .{ .fadd, .m, &.{ .m32 }, &.{ 0xd8 }, 0, .none, .x87 },
1096 .{ .fadd, .m, &.{ .m64 }, &.{ 0xdc }, 0, .none, .x87 },
1097 .{ .fadd, .zo, &.{ .st0, .st }, &.{ 0xd8, 0xc0 }, 0, .none, .x87 },
1098 .{ .fadd, .oz, &.{ .st, .st0 }, &.{ 0xdc, 0xc0 }, 0, .none, .x87 },
1099 .{ .faddp, .oz, &.{ .st, .st0 }, &.{ 0xde, 0xc0 }, 0, .none, .x87 },
1100 .{ .faddp, .z, &.{ }, &.{ 0xde, 0xc1 }, 0, .none, .x87 },
1101 .{ .fiadd, .m, &.{ .m32 }, &.{ 0xda }, 0, .none, .x87 },
1102 .{ .fiadd, .m, &.{ .m16 }, &.{ 0xde }, 0, .none, .x87 },
1103
1104 .{ .fbld, .m, &.{ .m80 }, &.{ 0xdf }, 4, .none, .x87 },
1105
1106 .{ .fbstp, .m, &.{ .m80 }, &.{ 0xdf }, 6, .none, .x87 },
1107
8791108 .{ .fchs, .z, &.{}, &.{ 0xd9, 0xe0 }, 0, .none, .x87 },
8801109
1110 .{ .fclex, .z, &.{}, &.{ 0xdb, 0xe2 }, 0, .wait, .x87 },
1111 .{ .fnclex, .z, &.{}, &.{ 0xdb, 0xe2 }, 0, .none, .x87 },
1112
1113 .{ .fcmovb, .zo, &.{ .st0, .st }, &.{ 0xda, 0xc0 }, 0, .none, .@"cmov x87" },
1114 .{ .fcmove, .zo, &.{ .st0, .st }, &.{ 0xda, 0xc8 }, 0, .none, .@"cmov x87" },
1115 .{ .fcmovbe, .zo, &.{ .st0, .st }, &.{ 0xda, 0xd0 }, 0, .none, .@"cmov x87" },
1116 .{ .fcmovu, .zo, &.{ .st0, .st }, &.{ 0xda, 0xd8 }, 0, .none, .@"cmov x87" },
1117 .{ .fcmovnb, .zo, &.{ .st0, .st }, &.{ 0xdb, 0xc0 }, 0, .none, .@"cmov x87" },
1118 .{ .fcmovne, .zo, &.{ .st0, .st }, &.{ 0xdb, 0xc8 }, 0, .none, .@"cmov x87" },
1119 .{ .fcmovnbe, .zo, &.{ .st0, .st }, &.{ 0xdb, 0xd0 }, 0, .none, .@"cmov x87" },
1120 .{ .fcmovnu, .zo, &.{ .st0, .st }, &.{ 0xdb, 0xd8 }, 0, .none, .@"cmov x87" },
1121
1122 .{ .fcom, .m, &.{ .m32 }, &.{ 0xd8 }, 2, .none, .x87 },
1123 .{ .fcom, .m, &.{ .m64 }, &.{ 0xdc }, 2, .none, .x87 },
1124 .{ .fcom, .o, &.{ .st }, &.{ 0xd8, 0xd0 }, 0, .none, .x87 },
1125 .{ .fcom, .z, &.{ }, &.{ 0xd8, 0xd1 }, 0, .none, .x87 },
1126 .{ .fcomp, .m, &.{ .m32 }, &.{ 0xd8 }, 3, .none, .x87 },
1127 .{ .fcomp, .m, &.{ .m64 }, &.{ 0xdc }, 3, .none, .x87 },
1128 .{ .fcomp, .o, &.{ .st }, &.{ 0xd8, 0xd8 }, 0, .none, .x87 },
1129 .{ .fcomp, .z, &.{ }, &.{ 0xd8, 0xd9 }, 0, .none, .x87 },
1130 .{ .fcompp, .z, &.{ }, &.{ 0xde, 0xd9 }, 0, .none, .x87 },
1131
1132 .{ .fcomi, .zo, &.{ .st0, .st }, &.{ 0xdb, 0xf0 }, 0, .none, .x87 },
1133 .{ .fcomip, .zo, &.{ .st0, .st }, &.{ 0xdf, 0xf0 }, 0, .none, .x87 },
1134 .{ .fucomi, .zo, &.{ .st0, .st }, &.{ 0xdb, 0xe8 }, 0, .none, .x87 },
1135 .{ .fucomip, .zo, &.{ .st0, .st }, &.{ 0xdf, 0xe8 }, 0, .none, .x87 },
1136
1137 .{ .fcos, .z, &.{}, &.{ 0xd9, 0xff }, 0, .none, .x87 },
1138
1139 .{ .fdecstp, .z, &.{}, &.{ 0xd9, 0xf6 }, 0, .none, .x87 },
1140
1141 .{ .fdiv, .m, &.{ .m32 }, &.{ 0xd8 }, 6, .none, .x87 },
1142 .{ .fdiv, .m, &.{ .m64 }, &.{ 0xdc }, 6, .none, .x87 },
1143 .{ .fdiv, .zo, &.{ .st0, .st }, &.{ 0xd8, 0xf0 }, 0, .none, .x87 },
1144 .{ .fdiv, .oz, &.{ .st, .st0 }, &.{ 0xdc, 0xf8 }, 0, .none, .x87 },
1145 .{ .fdivp, .oz, &.{ .st, .st0 }, &.{ 0xde, 0xf8 }, 0, .none, .x87 },
1146 .{ .fdivp, .z, &.{ }, &.{ 0xde, 0xf9 }, 0, .none, .x87 },
1147 .{ .fidiv, .m, &.{ .m32 }, &.{ 0xda }, 6, .none, .x87 },
1148 .{ .fidiv, .m, &.{ .m16 }, &.{ 0xde }, 6, .none, .x87 },
1149
1150 .{ .fdivr, .m, &.{ .m32 }, &.{ 0xd8 }, 7, .none, .x87 },
1151 .{ .fdivr, .m, &.{ .m64 }, &.{ 0xdc }, 7, .none, .x87 },
1152 .{ .fdivr, .zo, &.{ .st0, .st }, &.{ 0xd8, 0xf8 }, 0, .none, .x87 },
1153 .{ .fdivr, .oz, &.{ .st, .st0 }, &.{ 0xdc, 0xf0 }, 0, .none, .x87 },
1154 .{ .fdivrp, .oz, &.{ .st, .st0 }, &.{ 0xde, 0xf0 }, 0, .none, .x87 },
1155 .{ .fdivrp, .z, &.{ }, &.{ 0xde, 0xf1 }, 0, .none, .x87 },
1156 .{ .fidivr, .m, &.{ .m32 }, &.{ 0xda }, 7, .none, .x87 },
1157 .{ .fidivr, .m, &.{ .m16 }, &.{ 0xde }, 7, .none, .x87 },
1158
8811159 .{ .ffree, .o, &.{ .st }, &.{ 0xdd, 0xc0 }, 0, .none, .x87 },
8821160
1161 .{ .ficom, .m, &.{ .m16 }, &.{ 0xde }, 2, .none, .x87 },
1162 .{ .ficom, .m, &.{ .m32 }, &.{ 0xda }, 2, .none, .x87 },
1163 .{ .ficomp, .m, &.{ .m16 }, &.{ 0xde }, 3, .none, .x87 },
1164 .{ .ficomp, .m, &.{ .m32 }, &.{ 0xda }, 3, .none, .x87 },
1165
1166 .{ .fild, .m, &.{ .m16 }, &.{ 0xdf }, 0, .none, .x87 },
1167 .{ .fild, .m, &.{ .m32 }, &.{ 0xdb }, 0, .none, .x87 },
1168 .{ .fild, .m, &.{ .m64 }, &.{ 0xdf }, 5, .none, .x87 },
1169
1170 .{ .fincstp, .z, &.{}, &.{ 0xd9, 0xf7 }, 0, .none, .x87 },
1171
1172 .{ .finit, .z, &.{}, &.{ 0xdb, 0xe3 }, 0, .wait, .x87 },
1173 .{ .fninit, .z, &.{}, &.{ 0xdb, 0xe3 }, 0, .none, .x87 },
1174
1175 .{ .fist, .m, &.{ .m16 }, &.{ 0xdf }, 2, .none, .x87 },
1176 .{ .fist, .m, &.{ .m32 }, &.{ 0xdb }, 2, .none, .x87 },
1177 .{ .fistp, .m, &.{ .m16 }, &.{ 0xdf }, 3, .none, .x87 },
1178 .{ .fistp, .m, &.{ .m32 }, &.{ 0xdb }, 3, .none, .x87 },
1179 .{ .fistp, .m, &.{ .m64 }, &.{ 0xdf }, 7, .none, .x87 },
1180
8831181 .{ .fisttp, .m, &.{ .m16 }, &.{ 0xdf }, 1, .none, .x87 },
8841182 .{ .fisttp, .m, &.{ .m32 }, &.{ 0xdb }, 1, .none, .x87 },
8851183 .{ .fisttp, .m, &.{ .m64 }, &.{ 0xdd }, 1, .none, .x87 },
......@@ -889,8 +1187,52 @@ pub const table = [_]Entry{
8891187 .{ .fld, .m, &.{ .m80 }, &.{ 0xdb }, 5, .none, .x87 },
8901188 .{ .fld, .o, &.{ .st }, &.{ 0xd9, 0xc0 }, 0, .none, .x87 },
8911189
1190 .{ .fld1, .z, &.{}, &.{ 0xd9, 0xe8 }, 0, .none, .x87 },
1191 .{ .fldl2t, .z, &.{}, &.{ 0xd9, 0xe9 }, 0, .none, .x87 },
1192 .{ .fldl2e, .z, &.{}, &.{ 0xd9, 0xea }, 0, .none, .x87 },
1193 .{ .fldpi, .z, &.{}, &.{ 0xd9, 0xeb }, 0, .none, .x87 },
1194 .{ .fldlg2, .z, &.{}, &.{ 0xd9, 0xec }, 0, .none, .x87 },
1195 .{ .fldln2, .z, &.{}, &.{ 0xd9, 0xed }, 0, .none, .x87 },
1196 .{ .fldz, .z, &.{}, &.{ 0xd9, 0xee }, 0, .none, .x87 },
1197
1198 .{ .fldcw, .m, &.{ .m16 }, &.{ 0xd9 }, 5, .none, .x87 },
1199
8921200 .{ .fldenv, .m, &.{ .m }, &.{ 0xd9 }, 4, .none, .x87 },
8931201
1202 .{ .fmul, .m, &.{ .m32 }, &.{ 0xd8 }, 1, .none, .x87 },
1203 .{ .fmul, .m, &.{ .m64 }, &.{ 0xdc }, 1, .none, .x87 },
1204 .{ .fmul, .zo, &.{ .st0, .st }, &.{ 0xd8, 0xc8 }, 0, .none, .x87 },
1205 .{ .fmul, .oz, &.{ .st, .st0 }, &.{ 0xdc, 0xc8 }, 0, .none, .x87 },
1206 .{ .fmulp, .oz, &.{ .st, .st0 }, &.{ 0xde, 0xc8 }, 0, .none, .x87 },
1207 .{ .fmulp, .z, &.{ }, &.{ 0xde, 0xc9 }, 0, .none, .x87 },
1208 .{ .fimul, .m, &.{ .m32 }, &.{ 0xda }, 1, .none, .x87 },
1209 .{ .fimul, .m, &.{ .m16 }, &.{ 0xde }, 1, .none, .x87 },
1210
1211 .{ .fnop, .z, &.{}, &.{ 0xd9, 0xd0 }, 0, .none, .x87 },
1212
1213 .{ .fpatan, .z, &.{}, &.{ 0xd9, 0xf3 }, 0, .none, .x87 },
1214
1215 .{ .fprem, .z, &.{}, &.{ 0xd9, 0xf8 }, 0, .none, .x87 },
1216
1217 .{ .fprem1, .z, &.{}, &.{ 0xd9, 0xf5 }, 0, .none, .x87 },
1218
1219 .{ .fptan, .z, &.{}, &.{ 0xd9, 0xf2 }, 0, .none, .x87 },
1220
1221 .{ .frndint, .z, &.{}, &.{ 0xd9, 0xfc }, 0, .none, .x87 },
1222
1223 .{ .frstor, .m, &.{ .m }, &.{ 0xdd }, 4, .none, .x87 },
1224
1225 .{ .fsave, .m, &.{ .m }, &.{ 0xdd }, 6, .wait, .x87 },
1226 .{ .fnsave, .m, &.{ .m }, &.{ 0xdd }, 6, .none, .x87 },
1227
1228 .{ .fscale, .z, &.{}, &.{ 0xd9, 0xfd }, 0, .none, .x87 },
1229
1230 .{ .fsin, .z, &.{}, &.{ 0xd9, 0xfe }, 0, .none, .x87 },
1231
1232 .{ .fsincos, .z, &.{}, &.{ 0xd9, 0xfb }, 0, .none, .x87 },
1233
1234 .{ .fsqrt, .z, &.{}, &.{ 0xd9, 0xfa }, 0, .none, .x87 },
1235
8941236 .{ .fst, .m, &.{ .m32 }, &.{ 0xd9 }, 2, .none, .x87 },
8951237 .{ .fst, .m, &.{ .m64 }, &.{ 0xdd }, 2, .none, .x87 },
8961238 .{ .fst, .o, &.{ .st }, &.{ 0xdd, 0xd0 }, 0, .none, .x87 },
......@@ -899,8 +1241,59 @@ pub const table = [_]Entry{
8991241 .{ .fstp, .m, &.{ .m80 }, &.{ 0xdb }, 7, .none, .x87 },
9001242 .{ .fstp, .o, &.{ .st }, &.{ 0xdd, 0xd8 }, 0, .none, .x87 },
9011243
902 .{ .fstenv, .m, &.{ .m }, &.{ 0x9b, 0xd9 }, 6, .none, .x87 },
903 .{ .fnstenv, .m, &.{ .m }, &.{ 0xd9 }, 6, .none, .x87 },
1244 .{ .fstcw, .m, &.{ .m16 }, &.{ 0xd9 }, 7, .wait, .x87 },
1245 .{ .fnstcw, .m, &.{ .m16 }, &.{ 0xd9 }, 7, .none, .x87 },
1246
1247 .{ .fstenv, .m, &.{ .m }, &.{ 0xd9 }, 6, .wait, .x87 },
1248 .{ .fnstenv, .m, &.{ .m }, &.{ 0xd9 }, 6, .none, .x87 },
1249
1250 .{ .fstsw, .m, &.{ .m16 }, &.{ 0xdd }, 7, .wait, .x87 },
1251 .{ .fstsw, .m, &.{ .ax }, &.{ 0xdf }, 4, .wait, .x87 },
1252 .{ .fnstsw, .m, &.{ .m16 }, &.{ 0xdd }, 7, .none, .x87 },
1253 .{ .fnstsw, .m, &.{ .ax }, &.{ 0xdf }, 4, .none, .x87 },
1254
1255 .{ .fsub, .m, &.{ .m32 }, &.{ 0xd8 }, 4, .none, .x87 },
1256 .{ .fsub, .m, &.{ .m64 }, &.{ 0xdc }, 4, .none, .x87 },
1257 .{ .fsub, .zo, &.{ .st0, .st }, &.{ 0xd8, 0xe0 }, 0, .none, .x87 },
1258 .{ .fsub, .oz, &.{ .st, .st0 }, &.{ 0xdc, 0xe8 }, 0, .none, .x87 },
1259 .{ .fsubp, .oz, &.{ .st, .st0 }, &.{ 0xde, 0xe8 }, 0, .none, .x87 },
1260 .{ .fsubp, .z, &.{ }, &.{ 0xde, 0xe9 }, 0, .none, .x87 },
1261 .{ .fisub, .m, &.{ .m32 }, &.{ 0xda }, 4, .none, .x87 },
1262 .{ .fisub, .m, &.{ .m16 }, &.{ 0xde }, 4, .none, .x87 },
1263
1264 .{ .fsubr, .m, &.{ .m32 }, &.{ 0xd8 }, 5, .none, .x87 },
1265 .{ .fsubr, .m, &.{ .m64 }, &.{ 0xdc }, 5, .none, .x87 },
1266 .{ .fsubr, .zo, &.{ .st0, .st }, &.{ 0xd8, 0xe8 }, 0, .none, .x87 },
1267 .{ .fsubr, .oz, &.{ .st, .st0 }, &.{ 0xdc, 0xe0 }, 0, .none, .x87 },
1268 .{ .fsubrp, .oz, &.{ .st, .st0 }, &.{ 0xde, 0xe0 }, 0, .none, .x87 },
1269 .{ .fsubrp, .z, &.{ }, &.{ 0xde, 0xe1 }, 0, .none, .x87 },
1270 .{ .fisubr, .m, &.{ .m32 }, &.{ 0xda }, 5, .none, .x87 },
1271 .{ .fisubr, .m, &.{ .m16 }, &.{ 0xde }, 5, .none, .x87 },
1272
1273 .{ .ftst, .z, &.{}, &.{ 0xd9, 0xe4 }, 0, .none, .x87 },
1274
1275 .{ .fucom, .o, &.{ .st }, &.{ 0xdd, 0xe0 }, 0, .none, .x87 },
1276 .{ .fucom, .z, &.{ }, &.{ 0xdd, 0xe1 }, 0, .none, .x87 },
1277 .{ .fucomp, .o, &.{ .st }, &.{ 0xdd, 0xe8 }, 0, .none, .x87 },
1278 .{ .fucomp, .z, &.{ }, &.{ 0xdd, 0xe9 }, 0, .none, .x87 },
1279 .{ .fucompp, .z, &.{ }, &.{ 0xda, 0xe9 }, 0, .none, .x87 },
1280
1281 .{ .fxam, .z, &.{}, &.{ 0xd9, 0xe5 }, 0, .none, .x87 },
1282
1283 .{ .fxch, .o, &.{ .st }, &.{ 0xd9, 0xc8 }, 0, .none, .x87 },
1284 .{ .fxch, .z, &.{ }, &.{ 0xd9, 0xc9 }, 0, .none, .x87 },
1285
1286 .{ .fxtract, .z, &.{}, &.{ 0xd9, 0xf4 }, 0, .none, .x87 },
1287
1288 .{ .fyl2x, .z, &.{}, &.{ 0xd9, 0xf1 }, 0, .none, .x87 },
1289
1290 .{ .fyl2xp1, .z, &.{}, &.{ 0xd9, 0xf9 }, 0, .none, .x87 },
1291
1292 .{ .wait, .z, &.{}, &.{ 0x9b }, 0, .none, .x87 },
1293 .{ .fwait, .z, &.{}, &.{ 0x9b }, 0, .none, .x87 },
1294
1295 // MMX
1296 .{ .emms, .z, &.{}, &.{ 0x0f, 0x77 }, 0, .none, .mmx },
9041297
9051298 // SSE
9061299 .{ .addps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x58 }, 0, .none, .sse },
......@@ -915,6 +1308,8 @@ pub const table = [_]Entry{
9151308
9161309 .{ .cmpss, .rmi, &.{ .xmm, .xmm_m32, .imm8 }, &.{ 0xf3, 0x0f, 0xc2 }, 0, .none, .sse },
9171310
1311 .{ .comiss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0x0f, 0x2f }, 0, .none, .sse },
1312
9181313 .{ .cvtpi2ps, .rm, &.{ .xmm, .mm_m64 }, &.{ 0x0f, 0x2a }, 0, .none, .sse },
9191314
9201315 .{ .cvtps2pi, .rm, &.{ .mm, .xmm_m64 }, &.{ 0x0f, 0x2d }, 0, .none, .sse },
......@@ -934,6 +1329,12 @@ pub const table = [_]Entry{
9341329
9351330 .{ .divss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5e }, 0, .none, .sse },
9361331
1332 .{ .fxrstor, .m, &.{ .m }, &.{ 0x0f, 0xae }, 1, .none, .fxsr },
1333 .{ .fxrstor64, .m, &.{ .m }, &.{ 0x0f, 0xae }, 1, .long, .fxsr },
1334
1335 .{ .fxsave, .m, &.{ .m }, &.{ 0x0f, 0xae }, 0, .none, .fxsr },
1336 .{ .fxsave64, .m, &.{ .m }, &.{ 0x0f, 0xae }, 0, .long, .fxsr },
1337
9371338 .{ .ldmxcsr, .m, &.{ .m32 }, &.{ 0x0f, 0xae }, 2, .none, .sse },
9381339
9391340 .{ .maxps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x5f }, 0, .none, .sse },
......@@ -1004,6 +1405,8 @@ pub const table = [_]Entry{
10041405
10051406 .{ .cmpsd, .rmi, &.{ .xmm, .xmm_m64, .imm8 }, &.{ 0xf2, 0x0f, 0xc2 }, 0, .none, .sse2 },
10061407
1408 .{ .comisd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0x66, 0x0f, 0x2f }, 0, .none, .sse2 },
1409
10071410 .{ .cvtdq2pd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf3, 0x0f, 0xe6 }, 0, .none, .sse2 },
10081411
10091412 .{ .cvtdq2ps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x5b }, 0, .none, .sse2 },
......@@ -1043,6 +1446,12 @@ pub const table = [_]Entry{
10431446
10441447 .{ .divsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x5e }, 0, .none, .sse2 },
10451448
1449 .{ .gf2p8affineinvqb, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0xcf }, 0, .none, .gfni },
1450
1451 .{ .gf2p8affineqb, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0xce }, 0, .none, .gfni },
1452
1453 .{ .gf2p8mulb, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0xcf }, 0, .none, .gfni },
1454
10461455 .{ .maxpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x5f }, 0, .none, .sse2 },
10471456
10481457 .{ .maxsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x5f }, 0, .none, .sse2 },
......@@ -1203,6 +1612,16 @@ pub const table = [_]Entry{
12031612 .{ .xorpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x57 }, 0, .none, .sse2 },
12041613
12051614 // SSE3
1615 .{ .addsubpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xd0 }, 0, .none, .sse3 },
1616
1617 .{ .addsubps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0xf2, 0x0f, 0xd0 }, 0, .none, .sse3 },
1618
1619 .{ .haddpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x7c }, 0, .none, .sse3 },
1620
1621 .{ .haddps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0xf2, 0x0f, 0x7c }, 0, .none, .sse3 },
1622
1623 .{ .lddqu, .rm, &.{ .xmm, .m128 }, &.{ 0xf2, 0x0f, 0xf0 }, 0, .none, .sse3 },
1624
12061625 .{ .movddup, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x12 }, 0, .none, .sse3 },
12071626
12081627 .{ .movshdup, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0xf3, 0x0f, 0x16 }, 0, .none, .sse3 },
......@@ -1226,20 +1645,24 @@ pub const table = [_]Entry{
12261645
12271646 .{ .blendps, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x0c }, 0, .none, .sse4_1 },
12281647
1229 .{ .blendvpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x15 }, 0, .none, .sse4_1 },
1648 .{ .blendvpd, .rm0, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x15 }, 0, .none, .sse4_1 },
12301649 .{ .blendvpd, .rm0, &.{ .xmm, .xmm_m128, .xmm0 }, &.{ 0x66, 0x0f, 0x38, 0x15 }, 0, .none, .sse4_1 },
12311650
1232 .{ .blendvps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x14 }, 0, .none, .sse4_1 },
1651 .{ .blendvps, .rm0, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x14 }, 0, .none, .sse4_1 },
12331652 .{ .blendvps, .rm0, &.{ .xmm, .xmm_m128, .xmm0 }, &.{ 0x66, 0x0f, 0x38, 0x14 }, 0, .none, .sse4_1 },
12341653
1654 .{ .dppd, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x41 }, 0, .none, .sse4_1 },
1655
1656 .{ .dpps, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x40 }, 0, .none, .sse4_1 },
1657
12351658 .{ .extractps, .mri, &.{ .rm32, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x17 }, 0, .none, .sse4_1 },
12361659
12371660 .{ .insertps, .rmi, &.{ .xmm, .xmm_m32, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x21 }, 0, .none, .sse4_1 },
12381661
12391662 .{ .packusdw, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x2b }, 0, .none, .sse4_1 },
12401663
1241 .{ .pblendvb, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x10 }, 0, .none, .sse4_1 },
1242 .{ .pblendvb, .rm, &.{ .xmm, .xmm_m128, .xmm0 }, &.{ 0x66, 0x0f, 0x38, 0x10 }, 0, .none, .sse4_1 },
1664 .{ .pblendvb, .rm0, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x10 }, 0, .none, .sse4_1 },
1665 .{ .pblendvb, .rm0, &.{ .xmm, .xmm_m128, .xmm0 }, &.{ 0x66, 0x0f, 0x38, 0x10 }, 0, .none, .sse4_1 },
12431666
12441667 .{ .pblendw, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x0e }, 0, .none, .sse4_1 },
12451668
......@@ -1296,6 +1719,13 @@ pub const table = [_]Entry{
12961719 .{ .roundss, .rmi, &.{ .xmm, .xmm_m32, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x0a }, 0, .none, .sse4_1 },
12971720
12981721 // SSE4.2
1722 .{ .crc32, .rm, &.{ .r32, .rm8 }, &.{ 0xf2, 0x0f, 0x38, 0xf0 }, 0, .none, .crc32 },
1723 .{ .crc32, .rm, &.{ .r32, .rm8 }, &.{ 0xf2, 0x0f, 0x38, 0xf0 }, 0, .rex, .crc32 },
1724 .{ .crc32, .rm, &.{ .r32, .rm16 }, &.{ 0xf2, 0x0f, 0x38, 0xf1 }, 0, .short, .crc32 },
1725 .{ .crc32, .rm, &.{ .r32, .rm32 }, &.{ 0xf2, 0x0f, 0x38, 0xf1 }, 0, .none, .crc32 },
1726 .{ .crc32, .rm, &.{ .r64, .rm8 }, &.{ 0xf2, 0x0f, 0x38, 0xf0 }, 0, .long, .crc32 },
1727 .{ .crc32, .rm, &.{ .r64, .rm64 }, &.{ 0xf2, 0x0f, 0x38, 0xf1 }, 0, .long, .crc32 },
1728
12991729 .{ .pcmpgtq, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x37 }, 0, .none, .sse4_2 },
13001730
13011731 // PCLMUL
......@@ -1315,14 +1745,40 @@ pub const table = [_]Entry{
13151745 .{ .aeskeygenassist, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0xdf }, 0, .none, .aes },
13161746
13171747 // SHA
1318 .{ .sha256msg1, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x38, 0xcc }, 0, .none, .sha },
1748 .{ .sha1rnds4, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0x0f, 0x3a, 0xcc }, 0, .none, .sha },
13191749
1320 .{ .sha256msg2, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x38, 0xcd }, 0, .none, .sha },
1750 .{ .sha1nexte, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x38, 0xc8 }, 0, .none, .sha },
1751
1752 .{ .sha1msg1, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x38, 0xc9 }, 0, .none, .sha },
1753
1754 .{ .sha1msg2, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x38, 0xca }, 0, .none, .sha },
13211755
1322 .{ .sha256rnds2, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x38, 0xcb }, 0, .none, .sha },
1756 .{ .sha256rnds2, .rm0, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x38, 0xcb }, 0, .none, .sha },
13231757 .{ .sha256rnds2, .rm0, &.{ .xmm, .xmm_m128, .xmm0 }, &.{ 0x0f, 0x38, 0xcb }, 0, .none, .sha },
13241758
1759 .{ .sha256msg1, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x38, 0xcc }, 0, .none, .sha },
1760
1761 .{ .sha256msg2, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x38, 0xcd }, 0, .none, .sha },
1762
13251763 // AVX
1764 .{ .andn, .rvm, &.{ .r32, .r32, .rm32 }, &.{ 0x0f, 0x38, 0xf2 }, 0, .vex_lz_w0, .bmi },
1765 .{ .andn, .rvm, &.{ .r64, .r64, .rm64 }, &.{ 0x0f, 0x38, 0xf2 }, 0, .vex_lz_w1, .bmi },
1766
1767 .{ .bextr, .rmv, &.{ .r32, .rm32, .r32 }, &.{ 0x0f, 0x38, 0xf7 }, 0, .vex_lz_w0, .bmi },
1768 .{ .bextr, .rmv, &.{ .r64, .rm64, .r64 }, &.{ 0x0f, 0x38, 0xf7 }, 0, .vex_lz_w1, .bmi },
1769
1770 .{ .blsi, .vm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x38, 0xf3 }, 3, .vex_lz_w0, .bmi },
1771 .{ .blsi, .vm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x38, 0xf3 }, 3, .vex_lz_w1, .bmi },
1772
1773 .{ .blsmsk, .vm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x38, 0xf3 }, 2, .vex_lz_w0, .bmi },
1774 .{ .blsmsk, .vm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x38, 0xf3 }, 2, .vex_lz_w1, .bmi },
1775
1776 .{ .blsr, .vm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x38, 0xf3 }, 1, .vex_lz_w0, .bmi },
1777 .{ .blsr, .vm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x38, 0xf3 }, 1, .vex_lz_w1, .bmi },
1778
1779 .{ .bzhi, .rmv, &.{ .r32, .rm32, .r32 }, &.{ 0x0f, 0x38, 0xf5 }, 0, .vex_lz_w0, .bmi2 },
1780 .{ .bzhi, .rmv, &.{ .r64, .rm64, .r64 }, &.{ 0x0f, 0x38, 0xf5 }, 0, .vex_lz_w1, .bmi2 },
1781
13261782 .{ .rorx, .rmi, &.{ .r32, .rm32, .imm8 }, &.{ 0xf2, 0x0f, 0x3a }, 0, .vex_lz_w0, .bmi2 },
13271783 .{ .rorx, .rmi, &.{ .r64, .rm64, .imm8 }, &.{ 0xf2, 0x0f, 0x3a }, 0, .vex_lz_w1, .bmi2 },
13281784
......@@ -1333,6 +1789,10 @@ pub const table = [_]Entry{
13331789 .{ .shlx, .rmv, &.{ .r64, .rm64, .r64 }, &.{ 0x66, 0x0f, 0x38, 0xf7 }, 0, .vex_lz_w1, .bmi2 },
13341790 .{ .shrx, .rmv, &.{ .r64, .rm64, .r64 }, &.{ 0xf2, 0x0f, 0x38, 0xf7 }, 0, .vex_lz_w1, .bmi2 },
13351791
1792 .{ .tzcnt, .rm, &.{ .r16, .rm16 }, &.{ 0xf3, 0x0f, 0xbc }, 0, .short, .bmi },
1793 .{ .tzcnt, .rm, &.{ .r32, .rm32 }, &.{ 0xf3, 0x0f, 0xbc }, 0, .none, .bmi },
1794 .{ .tzcnt, .rm, &.{ .r64, .rm64 }, &.{ 0xf3, 0x0f, 0xbc }, 0, .long, .bmi },
1795
13361796 .{ .vaddpd, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x58 }, 0, .vex_128_wig, .avx },
13371797 .{ .vaddpd, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x58 }, 0, .vex_256_wig, .avx },
13381798
......@@ -1343,6 +1803,12 @@ pub const table = [_]Entry{
13431803
13441804 .{ .vaddss, .rvm, &.{ .xmm, .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x58 }, 0, .vex_lig_wig, .avx },
13451805
1806 .{ .vaddsubpd, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0xd0 }, 0, .vex_128_wig, .avx },
1807 .{ .vaddsubpd, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xd0 }, 0, .vex_256_wig, .avx },
1808
1809 .{ .vaddsubps, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0xf2, 0x0f, 0xd0 }, 0, .vex_128_wig, .avx },
1810 .{ .vaddsubps, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0xf2, 0x0f, 0xd0 }, 0, .vex_256_wig, .avx },
1811
13461812 .{ .vaesdec, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0xde }, 0, .vex_128_wig, .@"aes avx" },
13471813
13481814 .{ .vaesdeclast, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0xdf }, 0, .vex_128_wig, .@"aes avx" },
......@@ -1394,6 +1860,10 @@ pub const table = [_]Entry{
13941860
13951861 .{ .vcmpss, .rvmi, &.{ .xmm, .xmm, .xmm_m32, .imm8 }, &.{ 0xf3, 0x0f, 0xc2 }, 0, .vex_lig_wig, .avx },
13961862
1863 .{ .vcomisd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0x66, 0x0f, 0x2f }, 0, .vex_lig_wig, .avx },
1864
1865 .{ .vcomiss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0x0f, 0x2f }, 0, .vex_lig_wig, .avx },
1866
13971867 .{ .vcvtdq2pd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf3, 0x0f, 0xe6 }, 0, .vex_128_wig, .avx },
13981868 .{ .vcvtdq2pd, .rm, &.{ .ymm, .xmm_m128 }, &.{ 0xf3, 0x0f, 0xe6 }, 0, .vex_256_wig, .avx },
13991869
......@@ -1440,6 +1910,11 @@ pub const table = [_]Entry{
14401910 .{ .vcvttss2si, .rm, &.{ .r32, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x2c }, 0, .vex_lig_w0, .avx },
14411911 .{ .vcvttss2si, .rm, &.{ .r64, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x2c }, 0, .vex_lig_w1, .avx },
14421912
1913 .{ .vdppd, .rvmi, &.{ .xmm, .xmm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x41 }, 0, .vex_128_wig, .avx },
1914
1915 .{ .vdpps, .rvmi, &.{ .xmm, .xmm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x40 }, 0, .vex_128_wig, .avx },
1916 .{ .vdpps, .rvmi, &.{ .ymm, .ymm, .ymm_m256, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x40 }, 0, .vex_256_wig, .avx },
1917
14431918 .{ .vdivpd, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x5e }, 0, .vex_128_wig, .avx },
14441919 .{ .vdivpd, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x5e }, 0, .vex_256_wig, .avx },
14451920
......@@ -1454,10 +1929,28 @@ pub const table = [_]Entry{
14541929
14551930 .{ .vextractps, .mri, &.{ .rm32, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x17 }, 0, .vex_128_wig, .avx },
14561931
1932 .{ .vgf2p8affineinvqb, .rvmi, &.{ .xmm, .xmm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0xcf }, 0, .vex_128_w1, .@"gfni avx" },
1933 .{ .vgf2p8affineinvqb, .rvmi, &.{ .ymm, .ymm, .ymm_m256, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0xcf }, 0, .vex_256_w1, .@"gfni avx" },
1934
1935 .{ .vgf2p8affineqb, .rvmi, &.{ .xmm, .xmm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0xce }, 0, .vex_128_w1, .@"gfni avx" },
1936 .{ .vgf2p8affineqb, .rvmi, &.{ .ymm, .ymm, .ymm_m256, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0xce }, 0, .vex_256_w1, .@"gfni avx" },
1937
1938 .{ .vgf2p8mulb, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0xcf }, 0, .vex_128_w0, .@"gfni avx" },
1939 .{ .vgf2p8mulb, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x38, 0xcf }, 0, .vex_256_w0, .@"gfni avx" },
1940
1941 .{ .vhaddpd, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x7c }, 0, .vex_128_wig, .avx },
1942 .{ .vhaddpd, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x7c }, 0, .vex_256_wig, .avx },
1943
1944 .{ .vhaddps, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0xf2, 0x0f, 0x7c }, 0, .vex_128_wig, .avx },
1945 .{ .vhaddps, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0xf2, 0x0f, 0x7c }, 0, .vex_256_wig, .avx },
1946
14571947 .{ .vinsertf128, .rvmi, &.{ .ymm, .ymm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x18 }, 0, .vex_256_w0, .avx },
14581948
14591949 .{ .vinsertps, .rvmi, &.{ .xmm, .xmm, .xmm_m32, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x21 }, 0, .vex_128_wig, .avx },
14601950
1951 .{ .vlddqu, .rm, &.{ .xmm, .m128 }, &.{ 0xf2, 0x0f, 0xf0 }, 0, .vex_128_wig, .avx },
1952 .{ .vlddqu, .rm, &.{ .ymm, .m256 }, &.{ 0xf2, 0x0f, 0xf0 }, 0, .vex_256_wig, .avx },
1953
14611954 .{ .vldmxcsr, .m, &.{ .m32 }, &.{ 0x0f, 0xae }, 2, .vex_lz_wig, .avx },
14621955
14631956 .{ .vmaxpd, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x5f }, 0, .vex_128_wig, .avx },
......@@ -1821,15 +2314,6 @@ pub const table = [_]Entry{
18212314 // VPCLMULQDQ
18222315 .{ .vpclmulqdq, .rvmi, &.{ .ymm, .ymm, .ymm_m256, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x44 }, 0, .vex_256_wig, .vpclmulqdq },
18232316
1824 // VAES
1825 .{ .vaesdec, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x38, 0xde }, 0, .vex_256_wig, .vaes },
1826
1827 .{ .vaesdeclast, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x38, 0xdf }, 0, .vex_256_wig, .vaes },
1828
1829 .{ .vaesenc, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x38, 0xdc }, 0, .vex_256_wig, .vaes },
1830
1831 .{ .vaesenclast, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x38, 0xdd }, 0, .vex_256_wig, .vaes },
1832
18332317 // AVX2
18342318 .{ .vbroadcastss, .rm, &.{ .xmm, .xmm }, &.{ 0x66, 0x0f, 0x38, 0x18 }, 0, .vex_128_w0, .avx2 },
18352319 .{ .vbroadcastss, .rm, &.{ .ymm, .xmm }, &.{ 0x66, 0x0f, 0x38, 0x18 }, 0, .vex_256_w0, .avx2 },
......@@ -1992,5 +2476,46 @@ pub const table = [_]Entry{
19922476 .{ .vpunpcklqdq, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x6c }, 0, .vex_256_wig, .avx2 },
19932477
19942478 .{ .vpxor, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0xef }, 0, .vex_256_wig, .avx2 },
2479
2480 // ADX
2481 .{ .adcx, .rm, &.{ .r32, .rm32 }, &.{ 0x66, 0x0f, 0x38, 0xf6 }, 0, .none, .adx },
2482 .{ .adcx, .rm, &.{ .r64, .rm64 }, &.{ 0x66, 0x0f, 0x38, 0xf6 }, 0, .long, .adx },
2483
2484 .{ .adox, .rm, &.{ .r32, .rm32 }, &.{ 0xf3, 0x0f, 0x38, 0xf6 }, 0, .none, .adx },
2485 .{ .adox, .rm, &.{ .r64, .rm64 }, &.{ 0xf3, 0x0f, 0x38, 0xf6 }, 0, .long, .adx },
2486
2487 // VAES
2488 .{ .vaesdec, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x38, 0xde }, 0, .vex_256_wig, .vaes },
2489
2490 .{ .vaesdeclast, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x38, 0xdf }, 0, .vex_256_wig, .vaes },
2491
2492 .{ .vaesenc, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x38, 0xdc }, 0, .vex_256_wig, .vaes },
2493
2494 .{ .vaesenclast, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x38, 0xdd }, 0, .vex_256_wig, .vaes },
2495
2496 // AESKLE
2497 .{ .aesdec128kl, .rm, &.{ .xmm, .m }, &.{ 0xf3, 0x0f, 0x38, 0xdd }, 0, .none, .kl },
2498
2499 .{ .aesdec256kl, .rm, &.{ .xmm, .m }, &.{ 0xf3, 0x0f, 0x38, 0xdf }, 0, .none, .kl },
2500
2501 .{ .aesenc128kl, .rm, &.{ .xmm, .m }, &.{ 0xf3, 0x0f, 0x38, 0xdc }, 0, .none, .kl },
2502
2503 .{ .aesenc256kl, .rm, &.{ .xmm, .m }, &.{ 0xf3, 0x0f, 0x38, 0xde }, 0, .none, .kl },
2504
2505 .{ .encodekey128, .rm, &.{ .r32, .r32 }, &.{ 0xf3, 0x0f, 0x38, 0xfa }, 0, .none, .kl },
2506
2507 .{ .encodekey256, .rm, &.{ .r32, .r32 }, &.{ 0xf3, 0x0f, 0x38, 0xfb }, 0, .none, .kl },
2508
2509 .{ .loadiwkey, .rm, &.{ .xmm, .xmm }, &.{ 0xf3, 0x0f, 0x38, 0xdc }, 0, .none, .kl },
2510 .{ .loadiwkey, .rm, &.{ .xmm, .xmm, .eax, .xmm0 }, &.{ 0xf3, 0x0f, 0x38, 0xdc }, 0, .none, .kl },
2511
2512 // AESKLEWIDE_KL
2513 .{ .aesdecwide128kl, .m, &.{ .m }, &.{ 0xf3, 0x0f, 0x38, 0xd8 }, 1, .none, .widekl },
2514
2515 .{ .aesdecwide256kl, .m, &.{ .m }, &.{ 0xf3, 0x0f, 0x38, 0xd8 }, 3, .none, .widekl },
2516
2517 .{ .aesencwide128kl, .m, &.{ .m }, &.{ 0xf3, 0x0f, 0x38, 0xd8 }, 0, .none, .widekl },
2518
2519 .{ .aesencwide256kl, .m, &.{ .m }, &.{ 0xf3, 0x0f, 0x38, 0xd8 }, 2, .none, .widekl },
19952520};
19962521// zig fmt: on