| author | |
| committer | |
| log | 8ee80d61f6b2355f590de9722172b93a55c4f563 |
| tree | 3400c87dbd32371af5144d3153ba31af0dda5346 |
| parent | db8ed730e7500812f1f40729e2ead081107546ce |
Closes #197739 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 { |
| 419 | 419 | // detecting features using the "-march=native" flag. |
| 420 | 420 | // For more info, see X86 ISA docs. |
| 421 | 421 | setFeature(cpu, .pconfig, bit(leaf.edx, 18)); |
| 422 | setFeature(cpu, .uintr, bit(leaf.edx, 5)); | |
| 422 | 423 | |
| 423 | 424 | // TODO I feel unsure about this check. |
| 424 | 425 | // 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 { |
| 1375 | 1375 | }, |
| 1376 | 1376 | .imm => |imm0| switch (ops[1]) { |
| 1377 | 1377 | .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 | }, | |
| 1378 | 1386 | else => error.InvalidInstruction, |
| 1379 | 1387 | }, |
| 1380 | 1388 | .inst => |inst0| switch (ops[1]) { |
| ... | ... | @@ -1491,9 +1499,10 @@ fn asmSetccMemory(self: *CodeGen, cc: Condition, m: Memory) !void { |
| 1491 | 1499 | |
| 1492 | 1500 | fn asmJmpReloc(self: *CodeGen, target: Mir.Inst.Index) !Mir.Inst.Index { |
| 1493 | 1501 | return self.addInst(.{ |
| 1494 | .tag = .jmp, | |
| 1502 | .tag = .j, | |
| 1495 | 1503 | .ops = .inst, |
| 1496 | 1504 | .data = .{ .inst = .{ |
| 1505 | .fixes = ._mp, | |
| 1497 | 1506 | .inst = target, |
| 1498 | 1507 | } }, |
| 1499 | 1508 | }); |
| ... | ... | @@ -1753,6 +1762,42 @@ fn asmImmediate(self: *CodeGen, tag: Mir.Inst.FixedTag, imm: Immediate) !void { |
| 1753 | 1762 | }); |
| 1754 | 1763 | } |
| 1755 | 1764 | |
| 1765 | fn 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 | ||
| 1781 | fn 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 | ||
| 1756 | 1801 | fn asmRegisterRegister(self: *CodeGen, tag: Mir.Inst.FixedTag, reg1: Register, reg2: Register) !void { |
| 1757 | 1802 | _ = try self.addInst(.{ |
| 1758 | 1803 | .tag = tag[1], |
| ... | ... | @@ -4188,8 +4233,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 4188 | 4233 | _ = try cg.asmJmpReloc(loop.target); |
| 4189 | 4234 | }, |
| 4190 | 4235 | .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 }), | |
| 4193 | 4238 | .ret_addr => if (use_old) try cg.airRetAddr(inst) else { |
| 4194 | 4239 | var slot = try cg.tempInit(.usize, .{ .load_frame = .{ |
| 4195 | 4240 | .index = .ret_addr, |
| ... | ... | @@ -4233,7 +4278,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 4233 | 4278 | .dst_temps = .{.{ .ref = .src0 }}, |
| 4234 | 4279 | .clobbers = .{ .eflags = true }, |
| 4235 | 4280 | .each = .{ .once = &.{ |
| 4236 | .{ ._, ._, .inc, .dst0b, ._, ._, ._ }, | |
| 4281 | .{ ._, ._c, .in, .dst0b, ._, ._, ._ }, | |
| 4237 | 4282 | } }, |
| 4238 | 4283 | }, .{ |
| 4239 | 4284 | .src_constraints = .{ .{ .exact_unsigned_int = 1 }, .any }, |
| ... | ... | @@ -5643,7 +5688,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 5643 | 5688 | .{ ._, ._, .lzcnt, .tmp1d, .tmp1d, ._, ._ }, |
| 5644 | 5689 | .{ ._, ._, .sub, .tmp1b, .sia(32, .src0, .sub_bit_size), ._, ._ }, |
| 5645 | 5690 | .{ ._, ._, .mov, .memia(.dst0b, .tmp0, .add_len), .tmp1b, ._, ._ }, |
| 5646 | .{ ._, ._, .inc, .tmp0p, ._, ._, ._ }, | |
| 5691 | .{ ._, ._c, .in, .tmp0p, ._, ._, ._ }, | |
| 5647 | 5692 | .{ ._, ._nz, .j, .@"0b", ._, ._, ._ }, |
| 5648 | 5693 | } }, |
| 5649 | 5694 | }, .{ |
| ... | ... | @@ -5695,7 +5740,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 5695 | 5740 | .{ ._, ._, .lzcnt, .tmp1d, .tmp1d, ._, ._ }, |
| 5696 | 5741 | .{ ._, ._, .sub, .tmp1b, .sia(32, .src0, .sub_bit_size), ._, ._ }, |
| 5697 | 5742 | .{ ._, ._, .mov, .memia(.dst0b, .tmp0, .add_len), .tmp1b, ._, ._ }, |
| 5698 | .{ ._, ._, .inc, .tmp0p, ._, ._, ._ }, | |
| 5743 | .{ ._, ._c, .in, .tmp0p, ._, ._, ._ }, | |
| 5699 | 5744 | .{ ._, ._nz, .j, .@"0b", ._, ._, ._ }, |
| 5700 | 5745 | } }, |
| 5701 | 5746 | }, .{ |
| ... | ... | @@ -5747,7 +5792,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 5747 | 5792 | .{ ._, ._, .lzcnt, .tmp1d, .tmp1d, ._, ._ }, |
| 5748 | 5793 | .{ ._, ._, .sub, .tmp1b, .sia(32, .src0, .sub_bit_size), ._, ._ }, |
| 5749 | 5794 | .{ ._, ._, .mov, .memia(.dst0b, .tmp0, .add_len), .tmp1b, ._, ._ }, |
| 5750 | .{ ._, ._, .inc, .tmp0p, ._, ._, ._ }, | |
| 5795 | .{ ._, ._c, .in, .tmp0p, ._, ._, ._ }, | |
| 5751 | 5796 | .{ ._, ._nz, .j, .@"0b", ._, ._, ._ }, |
| 5752 | 5797 | } }, |
| 5753 | 5798 | }, .{ |
| ... | ... | @@ -5799,7 +5844,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 5799 | 5844 | .{ ._, ._, .lzcnt, .tmp1q, .tmp1q, ._, ._ }, |
| 5800 | 5845 | .{ ._, ._, .sub, .tmp1b, .sia(64, .src0, .sub_bit_size), ._, ._ }, |
| 5801 | 5846 | .{ ._, ._, .mov, .memia(.dst0b, .tmp0, .add_len), .tmp1b, ._, ._ }, |
| 5802 | .{ ._, ._, .inc, .tmp0p, ._, ._, ._ }, | |
| 5847 | .{ ._, ._c, .in, .tmp0p, ._, ._, ._ }, | |
| 5803 | 5848 | .{ ._, ._nz, .j, .@"0b", ._, ._, ._ }, |
| 5804 | 5849 | } }, |
| 5805 | 5850 | }, .{ |
| ... | ... | @@ -5857,7 +5902,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 5857 | 5902 | .{ ._, ._, .mov, .tmp3b, .sia(-1, .src0, .add_bit_size), ._, ._ }, |
| 5858 | 5903 | .{ ._, ._, .sub, .tmp3b, .tmp2b, ._, ._ }, |
| 5859 | 5904 | .{ ._, ._, .mov, .memia(.dst0b, .tmp0, .add_len), .tmp3b, ._, ._ }, |
| 5860 | .{ ._, ._, .inc, .tmp0p, ._, ._, ._ }, | |
| 5905 | .{ ._, ._c, .in, .tmp0p, ._, ._, ._ }, | |
| 5861 | 5906 | .{ ._, ._nz, .j, .@"0b", ._, ._, ._ }, |
| 5862 | 5907 | } }, |
| 5863 | 5908 | }, .{ |
| ... | ... | @@ -5915,7 +5960,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 5915 | 5960 | .{ ._, ._c, .st, ._, ._, ._, ._ }, |
| 5916 | 5961 | .{ ._, ._, .sbb, .tmp2b, .tmp1b, ._, ._ }, |
| 5917 | 5962 | .{ .@"1:", ._, .mov, .memia(.dst0b, .tmp0, .add_len), .tmp2b, ._, ._ }, |
| 5918 | .{ ._, ._, .inc, .tmp0p, ._, ._, ._ }, | |
| 5963 | .{ ._, ._c, .in, .tmp0p, ._, ._, ._ }, | |
| 5919 | 5964 | .{ ._, ._nz, .j, .@"0b", ._, ._, ._ }, |
| 5920 | 5965 | } }, |
| 5921 | 5966 | }, .{ |
| ... | ... | @@ -5970,7 +6015,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 5970 | 6015 | .{ ._, ._, .mov, .tmp1b, .sia(-1, .src0, .add_bit_size), ._, ._ }, |
| 5971 | 6016 | .{ ._, ._, .sub, .tmp1b, .tmp2b, ._, ._ }, |
| 5972 | 6017 | .{ ._, ._, .mov, .memia(.dst0b, .tmp0, .add_len), .tmp1b, ._, ._ }, |
| 5973 | .{ ._, ._, .inc, .tmp0p, ._, ._, ._ }, | |
| 6018 | .{ ._, ._c, .in, .tmp0p, ._, ._, ._ }, | |
| 5974 | 6019 | .{ ._, ._nz, .j, .@"0b", ._, ._, ._ }, |
| 5975 | 6020 | } }, |
| 5976 | 6021 | }, .{ |
| ... | ... | @@ -6028,7 +6073,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 6028 | 6073 | .{ ._, ._, .mov, .tmp3b, .sia(-1, .src0, .add_bit_size), ._, ._ }, |
| 6029 | 6074 | .{ ._, ._, .sub, .tmp3b, .tmp2b, ._, ._ }, |
| 6030 | 6075 | .{ ._, ._, .mov, .memia(.dst0b, .tmp0, .add_len), .tmp3b, ._, ._ }, |
| 6031 | .{ ._, ._, .inc, .tmp0p, ._, ._, ._ }, | |
| 6076 | .{ ._, ._c, .in, .tmp0p, ._, ._, ._ }, | |
| 6032 | 6077 | .{ ._, ._nz, .j, .@"0b", ._, ._, ._ }, |
| 6033 | 6078 | } }, |
| 6034 | 6079 | }, .{ |
| ... | ... | @@ -6086,7 +6131,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 6086 | 6131 | .{ ._, ._c, .st, ._, ._, ._, ._ }, |
| 6087 | 6132 | .{ ._, ._, .sbb, .tmp2b, .tmp1b, ._, ._ }, |
| 6088 | 6133 | .{ .@"1:", ._, .mov, .memia(.dst0b, .tmp0, .add_len), .tmp2b, ._, ._ }, |
| 6089 | .{ ._, ._, .inc, .tmp0p, ._, ._, ._ }, | |
| 6134 | .{ ._, ._c, .in, .tmp0p, ._, ._, ._ }, | |
| 6090 | 6135 | .{ ._, ._nz, .j, .@"0b", ._, ._, ._ }, |
| 6091 | 6136 | } }, |
| 6092 | 6137 | }, .{ |
| ... | ... | @@ -6141,7 +6186,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 6141 | 6186 | .{ ._, ._, .mov, .tmp1b, .sia(-1, .src0, .add_bit_size), ._, ._ }, |
| 6142 | 6187 | .{ ._, ._, .sub, .tmp1b, .tmp2b, ._, ._ }, |
| 6143 | 6188 | .{ ._, ._, .mov, .memia(.dst0b, .tmp0, .add_len), .tmp1b, ._, ._ }, |
| 6144 | .{ ._, ._, .inc, .tmp0p, ._, ._, ._ }, | |
| 6189 | .{ ._, ._c, .in, .tmp0p, ._, ._, ._ }, | |
| 6145 | 6190 | .{ ._, ._nz, .j, .@"0b", ._, ._, ._ }, |
| 6146 | 6191 | } }, |
| 6147 | 6192 | }, .{ |
| ... | ... | @@ -6199,7 +6244,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 6199 | 6244 | .{ ._, ._, .mov, .tmp3b, .sia(-1, .src0, .add_bit_size), ._, ._ }, |
| 6200 | 6245 | .{ ._, ._, .sub, .tmp3b, .tmp2b, ._, ._ }, |
| 6201 | 6246 | .{ ._, ._, .mov, .memia(.dst0b, .tmp0, .add_len), .tmp3b, ._, ._ }, |
| 6202 | .{ ._, ._, .inc, .tmp0p, ._, ._, ._ }, | |
| 6247 | .{ ._, ._c, .in, .tmp0p, ._, ._, ._ }, | |
| 6203 | 6248 | .{ ._, ._nz, .j, .@"0b", ._, ._, ._ }, |
| 6204 | 6249 | } }, |
| 6205 | 6250 | }, .{ |
| ... | ... | @@ -6257,7 +6302,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 6257 | 6302 | .{ ._, ._c, .st, ._, ._, ._, ._ }, |
| 6258 | 6303 | .{ ._, ._, .sbb, .tmp2b, .tmp1b, ._, ._ }, |
| 6259 | 6304 | .{ .@"1:", ._, .mov, .memia(.dst0b, .tmp0, .add_len), .tmp2b, ._, ._ }, |
| 6260 | .{ ._, ._, .inc, .tmp0p, ._, ._, ._ }, | |
| 6305 | .{ ._, ._c, .in, .tmp0p, ._, ._, ._ }, | |
| 6261 | 6306 | .{ ._, ._nz, .j, .@"0b", ._, ._, ._ }, |
| 6262 | 6307 | } }, |
| 6263 | 6308 | }, .{ |
| ... | ... | @@ -6312,7 +6357,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 6312 | 6357 | .{ ._, ._, .mov, .tmp1b, .sia(-1, .src0, .add_bit_size), ._, ._ }, |
| 6313 | 6358 | .{ ._, ._, .sub, .tmp1b, .tmp2b, ._, ._ }, |
| 6314 | 6359 | .{ ._, ._, .mov, .memia(.dst0b, .tmp0, .add_len), .tmp1b, ._, ._ }, |
| 6315 | .{ ._, ._, .inc, .tmp0p, ._, ._, ._ }, | |
| 6360 | .{ ._, ._c, .in, .tmp0p, ._, ._, ._ }, | |
| 6316 | 6361 | .{ ._, ._nz, .j, .@"0b", ._, ._, ._ }, |
| 6317 | 6362 | } }, |
| 6318 | 6363 | }, .{ |
| ... | ... | @@ -6370,7 +6415,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 6370 | 6415 | .{ ._, ._, .mov, .tmp3b, .sia(-1, .src0, .add_bit_size), ._, ._ }, |
| 6371 | 6416 | .{ ._, ._, .sub, .tmp3b, .tmp2b, ._, ._ }, |
| 6372 | 6417 | .{ ._, ._, .mov, .memia(.dst0b, .tmp0, .add_len), .tmp3b, ._, ._ }, |
| 6373 | .{ ._, ._, .inc, .tmp0p, ._, ._, ._ }, | |
| 6418 | .{ ._, ._c, .in, .tmp0p, ._, ._, ._ }, | |
| 6374 | 6419 | .{ ._, ._nz, .j, .@"0b", ._, ._, ._ }, |
| 6375 | 6420 | } }, |
| 6376 | 6421 | }, .{ |
| ... | ... | @@ -6428,7 +6473,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 6428 | 6473 | .{ ._, ._c, .st, ._, ._, ._, ._ }, |
| 6429 | 6474 | .{ ._, ._, .sbb, .tmp2b, .tmp1b, ._, ._ }, |
| 6430 | 6475 | .{ .@"1:", ._, .mov, .memia(.dst0b, .tmp0, .add_len), .tmp2b, ._, ._ }, |
| 6431 | .{ ._, ._, .inc, .tmp0p, ._, ._, ._ }, | |
| 6476 | .{ ._, ._c, .in, .tmp0p, ._, ._, ._ }, | |
| 6432 | 6477 | .{ ._, ._nz, .j, .@"0b", ._, ._, ._ }, |
| 6433 | 6478 | } }, |
| 6434 | 6479 | }, .{ |
| ... | ... | @@ -6484,7 +6529,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 6484 | 6529 | .{ ._, ._, .mov, .tmp1b, .sia(-1, .src0, .add_bit_size), ._, ._ }, |
| 6485 | 6530 | .{ ._, ._, .sub, .tmp1b, .tmp2b, ._, ._ }, |
| 6486 | 6531 | .{ ._, ._, .mov, .memia(.dst0b, .tmp0, .add_len), .tmp1b, ._, ._ }, |
| 6487 | .{ ._, ._, .inc, .tmp0p, ._, ._, ._ }, | |
| 6532 | .{ ._, ._c, .in, .tmp0p, ._, ._, ._ }, | |
| 6488 | 6533 | .{ ._, ._nz, .j, .@"0b", ._, ._, ._ }, |
| 6489 | 6534 | } }, |
| 6490 | 6535 | }, .{ |
| ... | ... | @@ -10094,7 +10139,7 @@ fn genLazy(self: *CodeGen, lazy_sym: link.File.LazySymbol) InnerError!void { |
| 10094 | 10139 | data_off += @intCast(tag_name_len + 1); |
| 10095 | 10140 | } |
| 10096 | 10141 | |
| 10097 | try self.asmOpOnly(.{ ._, .ud2 }); | |
| 10142 | try self.asmOpOnly(.{ ._2, .ud }); | |
| 10098 | 10143 | |
| 10099 | 10144 | for (epilogue_relocs) |reloc| self.performReloc(reloc); |
| 10100 | 10145 | try self.asmOpOnly(.{ ._, .ret }); |
| ... | ... | @@ -10373,7 +10418,7 @@ fn regClassForType(self: *CodeGen, ty: Type) Register.Class { |
| 10373 | 10418 | fn regSetForRegClass(rc: Register.Class) RegisterManager.RegisterBitSet { |
| 10374 | 10419 | return switch (rc) { |
| 10375 | 10420 | .general_purpose => abi.RegisterClass.gp, |
| 10376 | .segment, .ip => unreachable, | |
| 10421 | .segment, .ip, .cr, .dr => unreachable, | |
| 10377 | 10422 | .x87 => abi.RegisterClass.x87, |
| 10378 | 10423 | .mmx => @panic("TODO"), |
| 10379 | 10424 | .sse => abi.RegisterClass.sse, |
| ... | ... | @@ -12195,8 +12240,8 @@ fn airMulWithOverflow(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 12195 | 12240 | try self.asmRegisterImmediate(.{ ._, .add }, temp_regs[2].to32(), .u(1)); |
| 12196 | 12241 | try self.asmRegisterImmediate(.{ ._, .add }, temp_regs[3].to32(), .u(1)); |
| 12197 | 12242 | } 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()); | |
| 12200 | 12245 | } |
| 12201 | 12246 | try self.asmRegisterImmediate(.{ ._, .cmp }, temp_regs[3].to32(), .u(limb_len)); |
| 12202 | 12247 | _ = try self.asmJccReloc(.b, inner_loop); |
| ... | ... | @@ -12209,7 +12254,7 @@ fn airMulWithOverflow(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 12209 | 12254 | if (slow_inc) { |
| 12210 | 12255 | try self.asmRegisterImmediate(.{ ._, .add }, temp_regs[2].to32(), .u(1)); |
| 12211 | 12256 | } else { |
| 12212 | try self.asmRegister(.{ ._, .inc }, temp_regs[2].to32()); | |
| 12257 | try self.asmRegister(.{ ._c, .in }, temp_regs[2].to32()); | |
| 12213 | 12258 | } |
| 12214 | 12259 | try self.asmMemoryImmediate(.{ ._, .cmp }, .{ |
| 12215 | 12260 | .base = .{ .frame = lhs_mcv.load_frame.index }, |
| ... | ... | @@ -12236,7 +12281,7 @@ fn airMulWithOverflow(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 12236 | 12281 | if (slow_inc) { |
| 12237 | 12282 | try self.asmRegisterImmediate(.{ ._, .add }, temp_regs[0].to32(), .u(1)); |
| 12238 | 12283 | } else { |
| 12239 | try self.asmRegister(.{ ._, .inc }, temp_regs[0].to32()); | |
| 12284 | try self.asmRegister(.{ ._c, .in }, temp_regs[0].to32()); | |
| 12240 | 12285 | } |
| 12241 | 12286 | try self.asmRegisterImmediate(.{ ._, .cmp }, temp_regs[0].to32(), .u(limb_len)); |
| 12242 | 12287 | _ = try self.asmJccReloc(.b, outer_loop); |
| ... | ... | @@ -13938,7 +13983,7 @@ fn airClz(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 13938 | 13983 | if (self.hasFeature(.slow_incdec)) { |
| 13939 | 13984 | try self.asmRegisterImmediate(.{ ._, .sub }, index_reg.to32(), .u(1)); |
| 13940 | 13985 | } else { |
| 13941 | try self.asmRegister(.{ ._, .dec }, index_reg.to32()); | |
| 13986 | try self.asmRegister(.{ ._c, .de }, index_reg.to32()); | |
| 13942 | 13987 | } |
| 13943 | 13988 | try self.asmMemoryImmediate(.{ ._, .cmp }, .{ |
| 13944 | 13989 | .base = .{ .frame = src_frame_addr.index }, |
| ... | ... | @@ -14133,7 +14178,7 @@ fn airCtz(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 14133 | 14178 | if (self.hasFeature(.slow_incdec)) { |
| 14134 | 14179 | try self.asmRegisterImmediate(.{ ._, .add }, index_reg.to32(), .u(1)); |
| 14135 | 14180 | } else { |
| 14136 | try self.asmRegister(.{ ._, .inc }, index_reg.to32()); | |
| 14181 | try self.asmRegister(.{ ._c, .in }, index_reg.to32()); | |
| 14137 | 14182 | } |
| 14138 | 14183 | try self.asmRegisterImmediate(.{ ._, .cmp }, index_reg.to32(), .u(limbs_len)); |
| 14139 | 14184 | const zero = try self.asmJccReloc(.nb, undefined); |
| ... | ... | @@ -14535,8 +14580,8 @@ fn genByteSwap( |
| 14535 | 14580 | try self.asmRegisterImmediate(.{ ._, .add }, temp_regs[0].to32(), .u(1)); |
| 14536 | 14581 | try self.asmRegisterImmediate(.{ ._, .sub }, temp_regs[1].to32(), .u(1)); |
| 14537 | 14582 | } 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()); | |
| 14540 | 14585 | } |
| 14541 | 14586 | try self.asmRegisterRegister(.{ ._, .cmp }, temp_regs[0].to32(), temp_regs[1].to32()); |
| 14542 | 14587 | _ = try self.asmJccReloc(.be, loop); |
| ... | ... | @@ -15113,7 +15158,7 @@ fn airAbs(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 15113 | 15158 | if (self.hasFeature(.slow_incdec)) { |
| 15114 | 15159 | try self.asmRegisterImmediate(.{ ._, .add }, tmp_regs[0].to32(), .u(1)); |
| 15115 | 15160 | } else { |
| 15116 | try self.asmRegister(.{ ._, .inc }, tmp_regs[0].to32()); | |
| 15161 | try self.asmRegister(.{ ._c, .in }, tmp_regs[0].to32()); | |
| 15117 | 15162 | } |
| 15118 | 15163 | try self.asmRegisterImmediate(.{ ._, .cmp }, tmp_regs[0].to32(), .u(limb_len)); |
| 15119 | 15164 | _ = try self.asmJccReloc(.b, neg_loop); |
| ... | ... | @@ -16452,8 +16497,8 @@ fn genShiftBinOpMir( |
| 16452 | 16497 | try self.asmRegisterImmediate(.{ ._, .sub }, temp_regs[1].to32(), .u(1)); |
| 16453 | 16498 | try self.asmRegisterImmediate(.{ ._, .sub }, temp_regs[0].to32(), .u(1)); |
| 16454 | 16499 | } 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()); | |
| 16457 | 16502 | } |
| 16458 | 16503 | _ = try self.asmJccReloc(.nz, loop); |
| 16459 | 16504 | }, |
| ... | ... | @@ -16462,8 +16507,8 @@ fn genShiftBinOpMir( |
| 16462 | 16507 | try self.asmRegisterImmediate(.{ ._, .add }, temp_regs[1].to32(), .u(1)); |
| 16463 | 16508 | try self.asmRegisterImmediate(.{ ._, .add }, temp_regs[0].to32(), .u(1)); |
| 16464 | 16509 | } 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()); | |
| 16467 | 16512 | } |
| 16468 | 16513 | try self.asmRegisterImmediate( |
| 16469 | 16514 | .{ ._, .cmp }, |
| ... | ... | @@ -16532,12 +16577,12 @@ fn genShiftBinOpMir( |
| 16532 | 16577 | ._l => if (slow_inc_dec) { |
| 16533 | 16578 | try self.asmRegisterImmediate(.{ ._, .sub }, temp_regs[1].to32(), .u(1)); |
| 16534 | 16579 | } else { |
| 16535 | try self.asmRegister(.{ ._, .dec }, temp_regs[1].to32()); | |
| 16580 | try self.asmRegister(.{ ._c, .de }, temp_regs[1].to32()); | |
| 16536 | 16581 | }, |
| 16537 | 16582 | ._r => if (slow_inc_dec) { |
| 16538 | 16583 | try self.asmRegisterImmediate(.{ ._, .add }, temp_regs[1].to32(), .u(1)); |
| 16539 | 16584 | } else { |
| 16540 | try self.asmRegister(.{ ._, .inc }, temp_regs[1].to32()); | |
| 16585 | try self.asmRegister(.{ ._c, .in }, temp_regs[1].to32()); | |
| 16541 | 16586 | }, |
| 16542 | 16587 | else => unreachable, |
| 16543 | 16588 | } |
| ... | ... | @@ -17163,8 +17208,8 @@ fn genMulDivBinOp( |
| 17163 | 17208 | try self.asmRegisterImmediate(.{ ._, .add }, temp_regs[2].to32(), .u(1)); |
| 17164 | 17209 | try self.asmRegisterImmediate(.{ ._, .add }, temp_regs[3].to32(), .u(1)); |
| 17165 | 17210 | } 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()); | |
| 17168 | 17213 | } |
| 17169 | 17214 | try self.asmRegisterImmediate(.{ ._, .cmp }, temp_regs[3].to32(), .u(limb_len)); |
| 17170 | 17215 | _ = try self.asmJccReloc(.b, inner_loop); |
| ... | ... | @@ -17173,7 +17218,7 @@ fn genMulDivBinOp( |
| 17173 | 17218 | if (slow_inc) { |
| 17174 | 17219 | try self.asmRegisterImmediate(.{ ._, .add }, temp_regs[0].to32(), .u(1)); |
| 17175 | 17220 | } else { |
| 17176 | try self.asmRegister(.{ ._, .inc }, temp_regs[0].to32()); | |
| 17221 | try self.asmRegister(.{ ._c, .in }, temp_regs[0].to32()); | |
| 17177 | 17222 | } |
| 17178 | 17223 | try self.asmRegisterImmediate(.{ ._, .cmp }, temp_regs[0].to32(), .u(limb_len)); |
| 17179 | 17224 | _ = try self.asmJccReloc(.b, outer_loop); |
| ... | ... | @@ -19765,7 +19810,7 @@ fn airArg(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 19765 | 19810 | if (self.hasFeature(.slow_incdec)) { |
| 19766 | 19811 | try self.asmRegisterImmediate(.{ ._, .add }, index_reg.to32(), .u(1)); |
| 19767 | 19812 | } else { |
| 19768 | try self.asmRegister(.{ ._, .inc }, index_reg.to32()); | |
| 19813 | try self.asmRegister(.{ ._c, .in }, index_reg.to32()); | |
| 19769 | 19814 | } |
| 19770 | 19815 | try self.asmRegisterImmediate( |
| 19771 | 19816 | .{ ._, .cmp }, |
| ... | ... | @@ -20042,7 +20087,7 @@ fn genCall(self: *CodeGen, info: union(enum) { |
| 20042 | 20087 | if (self.hasFeature(.slow_incdec)) { |
| 20043 | 20088 | try self.asmRegisterImmediate(.{ ._, .add }, index_reg.to32(), .u(1)); |
| 20044 | 20089 | } else { |
| 20045 | try self.asmRegister(.{ ._, .inc }, index_reg.to32()); | |
| 20090 | try self.asmRegister(.{ ._c, .in }, index_reg.to32()); | |
| 20046 | 20091 | } |
| 20047 | 20092 | try self.asmRegisterImmediate( |
| 20048 | 20093 | .{ ._, .cmp }, |
| ... | ... | @@ -21423,7 +21468,7 @@ fn lowerSwitchBr( |
| 21423 | 21468 | defer if (condition_index_lock) |lock| self.register_manager.unlockReg(lock); |
| 21424 | 21469 | try self.truncateRegister(condition_ty, condition_index_reg); |
| 21425 | 21470 | const ptr_size = @divExact(self.target.ptrBitWidth(), 8); |
| 21426 | try self.asmMemory(.{ ._, .jmp }, .{ | |
| 21471 | try self.asmMemory(.{ ._mp, .j }, .{ | |
| 21427 | 21472 | .base = .table, |
| 21428 | 21473 | .mod = .{ .rm = .{ |
| 21429 | 21474 | .size = .ptr, |
| ... | ... | @@ -21720,7 +21765,7 @@ fn airSwitchDispatch(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 21720 | 21765 | defer if (condition_index_lock) |lock| self.register_manager.unlockReg(lock); |
| 21721 | 21766 | try self.truncateRegister(condition_ty, condition_index_reg); |
| 21722 | 21767 | const ptr_size = @divExact(self.target.ptrBitWidth(), 8); |
| 21723 | try self.asmMemory(.{ ._, .jmp }, .{ | |
| 21768 | try self.asmMemory(.{ ._mp, .j }, .{ | |
| 21724 | 21769 | .base = .table, |
| 21725 | 21770 | .mod = .{ .rm = .{ |
| 21726 | 21771 | .size = .ptr, |
| ... | ... | @@ -21777,7 +21822,7 @@ fn airSwitchDispatch(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 21777 | 21822 | fn performReloc(self: *CodeGen, reloc: Mir.Inst.Index) void { |
| 21778 | 21823 | const next_inst: u32 = @intCast(self.mir_instructions.len); |
| 21779 | 21824 | switch (self.mir_instructions.items(.tag)[reloc]) { |
| 21780 | .j, .jmp => {}, | |
| 21825 | .j => {}, | |
| 21781 | 21826 | .pseudo => switch (self.mir_instructions.items(.ops)[reloc]) { |
| 21782 | 21827 | .pseudo_j_z_and_np_inst, .pseudo_j_nz_or_p_inst => {}, |
| 21783 | 21828 | else => unreachable, |
| ... | ... | @@ -22149,65 +22194,52 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 22149 | 22194 | prefix = .directive; |
| 22150 | 22195 | } |
| 22151 | 22196 | |
| 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( | |
| 22168 | 22223 | 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; | |
| 22172 | 22227 | continue; |
| 22173 | 22228 | } else return self.fail("invalid mnemonic: '{s}'", .{mnem_str}); |
| 22174 | 22229 | if (@as(?Memory.Size, switch (mnem_tag) { |
| 22175 | 22230 | .clflush => .byte, |
| 22231 | .fldcw, .fnstcw, .fstcw, .fnstsw, .fstsw => .word, | |
| 22176 | 22232 | .fldenv, .fnstenv, .fstenv => .none, |
| 22233 | .frstor, .fsave, .fnsave, .fxrstor, .fxrstor64, .fxsave, .fxsave64 => .none, | |
| 22234 | .invlpg => .none, | |
| 22235 | .invpcid => .xword, | |
| 22177 | 22236 | .ldmxcsr, .stmxcsr, .vldmxcsr, .vstmxcsr => .dword, |
| 22178 | 22237 | else => null, |
| 22179 | 22238 | })) |fixed_mnem_size| { |
| 22180 | if (mnem_size) |size| if (size != fixed_mnem_size) | |
| 22239 | if (mnem_size.size) |size| if (size != fixed_mnem_size) | |
| 22181 | 22240 | return self.fail("invalid size: '{s}'", .{mnem_str}); |
| 22182 | mnem_size = fixed_mnem_size; | |
| 22241 | mnem_size.size = fixed_mnem_size; | |
| 22183 | 22242 | } |
| 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 | }; | |
| 22211 | 22243 | |
| 22212 | 22244 | var ops: [4]Operand = @splat(.none); |
| 22213 | 22245 | var ops_len: usize = 0; |
| ... | ... | @@ -22236,12 +22268,13 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 22236 | 22268 | op.* = .{ .mem = .{ |
| 22237 | 22269 | .base = .{ .reg = reg }, |
| 22238 | 22270 | .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}), | |
| 22240 | 22273 | .disp = disp, |
| 22241 | 22274 | } }, |
| 22242 | 22275 | } }; |
| 22243 | 22276 | } 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)) | |
| 22245 | 22278 | return self.fail("invalid register size: '{s}'", .{op_str}); |
| 22246 | 22279 | op.* = .{ .reg = reg }; |
| 22247 | 22280 | } |
| ... | ... | @@ -22260,14 +22293,17 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 22260 | 22293 | else |
| 22261 | 22294 | return self.fail("invalid modifier: '{s}'", .{modifier}), |
| 22262 | 22295 | .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 } | |
| 22264 | 22300 | else |
| 22265 | 22301 | return self.fail("invalid modifier: '{s}'", .{modifier}), |
| 22266 | 22302 | .memory => |addr| if (std.mem.eql(u8, modifier, "") or std.mem.eql(u8, modifier, "P")) |
| 22267 | 22303 | .{ .mem = .{ |
| 22268 | 22304 | .base = .{ .reg = .ds }, |
| 22269 | 22305 | .mod = .{ .rm = .{ |
| 22270 | .size = mnem_size orelse | |
| 22306 | .size = mnem_size.use() orelse | |
| 22271 | 22307 | return self.fail("unknown size: '{s}'", .{op_str}), |
| 22272 | 22308 | .disp = @intCast(@as(i64, @bitCast(addr))), |
| 22273 | 22309 | } }, |
| ... | ... | @@ -22278,7 +22314,7 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 22278 | 22314 | .{ .mem = .{ |
| 22279 | 22315 | .base = .{ .reg = reg_off.reg }, |
| 22280 | 22316 | .mod = .{ .rm = .{ |
| 22281 | .size = mnem_size orelse | |
| 22317 | .size = mnem_size.use() orelse | |
| 22282 | 22318 | return self.fail("unknown size: '{s}'", .{op_str}), |
| 22283 | 22319 | .disp = reg_off.off, |
| 22284 | 22320 | } }, |
| ... | ... | @@ -22289,7 +22325,7 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 22289 | 22325 | .{ .mem = .{ |
| 22290 | 22326 | .base = .{ .frame = frame_addr.index }, |
| 22291 | 22327 | .mod = .{ .rm = .{ |
| 22292 | .size = mnem_size orelse | |
| 22328 | .size = mnem_size.use() orelse | |
| 22293 | 22329 | return self.fail("unknown size: '{s}'", .{op_str}), |
| 22294 | 22330 | .disp = frame_addr.off, |
| 22295 | 22331 | } }, |
| ... | ... | @@ -22307,21 +22343,12 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 22307 | 22343 | else => return self.fail("invalid constraint: '{s}'", .{op_str}), |
| 22308 | 22344 | }; |
| 22309 | 22345 | } 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}); | |
| 22325 | 22352 | } else if (std.mem.endsWith(u8, op_str, ")")) { |
| 22326 | 22353 | const open = std.mem.indexOfScalar(u8, op_str, '(') orelse |
| 22327 | 22354 | return self.fail("invalid operand: '{s}'", .{op_str}); |
| ... | ... | @@ -22348,49 +22375,47 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void { |
| 22348 | 22375 | else |
| 22349 | 22376 | .@"1"; |
| 22350 | 22377 | 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}) | |
| 22356 | 22389 | else |
| 22357 | 22390 | .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] | |
| 22363 | 22398 | 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}) | |
| 22372 | 22408 | 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 | } }; | |
| 22394 | 22419 | } else if (Label.isValid(.reference, op_str)) { |
| 22395 | 22420 | const anon = std.ascii.isDigit(op_str[0]); |
| 22396 | 22421 | 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 { |
| 22410 | 22435 | |
| 22411 | 22436 | // convert from att syntax to intel syntax |
| 22412 | 22437 | 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 | }; | |
| 22413 | 22483 | |
| 22414 | 22484 | (if (prefix == .directive) switch (mnem_tag) { |
| 22415 | 22485 | .@".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) |
| 22815 | 22885 | else => {}, |
| 22816 | 22886 | }, |
| 22817 | 22887 | }, |
| 22818 | .ip => {}, | |
| 22888 | .ip, .cr, .dr => {}, | |
| 22819 | 22889 | } |
| 22820 | 22890 | return self.fail("TODO moveStrategy for {}", .{ty.fmt(pt)}); |
| 22821 | 22891 | } |
| ... | ... | @@ -22900,13 +22970,13 @@ fn genCopy(self: *CodeGen, ty: Type, dst_mcv: MCValue, src_mcv: MCValue, opts: C |
| 22900 | 22970 | for (dst_regs, &hazard_regs, 1..) |dst_reg, src_reg, hazard_index| { |
| 22901 | 22971 | const dst_id = dst_reg.id(); |
| 22902 | 22972 | if (dst_id == src_reg.id()) continue; |
| 22903 | var mir_tag: Mir.Inst.Tag = .mov; | |
| 22973 | var mir_tag: Mir.Inst.FixedTag = .{ ._, .mov }; | |
| 22904 | 22974 | for (hazard_regs[hazard_index..]) |*hazard_reg| { |
| 22905 | 22975 | if (dst_id != hazard_reg.id()) continue; |
| 22906 | mir_tag = .xchg; | |
| 22976 | mir_tag = .{ ._g, .xch }; | |
| 22907 | 22977 | hazard_reg.* = src_reg; |
| 22908 | 22978 | } |
| 22909 | try self.asmRegisterRegister(.{ ._, mir_tag }, dst_reg.to64(), src_reg.to64()); | |
| 22979 | try self.asmRegisterRegister(mir_tag, dst_reg.to64(), src_reg.to64()); | |
| 22910 | 22980 | } |
| 22911 | 22981 | return; |
| 22912 | 22982 | }, |
| ... | ... | @@ -23025,7 +23095,7 @@ fn genSetReg( |
| 23025 | 23095 | else => unreachable, |
| 23026 | 23096 | }, |
| 23027 | 23097 | .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, | |
| 23029 | 23099 | }, |
| 23030 | 23100 | .eflags => |cc| try self.asmSetccRegister(cc, dst_reg.to8()), |
| 23031 | 23101 | .immediate => |imm| { |
| ... | ... | @@ -23063,7 +23133,7 @@ fn genSetReg( |
| 23063 | 23133 | registerAlias(dst_reg, abi_size), |
| 23064 | 23134 | src_reg, |
| 23065 | 23135 | ), |
| 23066 | .x87, .mmx, .ip => unreachable, | |
| 23136 | .x87, .mmx, .ip, .cr, .dr => unreachable, | |
| 23067 | 23137 | .sse => if (self.hasFeature(.sse2)) try self.asmRegisterRegister( |
| 23068 | 23138 | switch (abi_size) { |
| 23069 | 23139 | 1...4 => if (self.hasFeature(.avx)) .{ .v_d, .mov } else .{ ._d, .mov }, |
| ... | ... | @@ -23092,7 +23162,7 @@ fn genSetReg( |
| 23092 | 23162 | dst_reg, |
| 23093 | 23163 | switch (src_reg.class()) { |
| 23094 | 23164 | .general_purpose, .segment => registerAlias(src_reg, abi_size), |
| 23095 | .x87, .mmx, .ip => unreachable, | |
| 23165 | .x87, .mmx, .ip, .cr, .dr => unreachable, | |
| 23096 | 23166 | .sse => try self.copyToTmpRegister(ty, src_mcv), |
| 23097 | 23167 | }, |
| 23098 | 23168 | ), |
| ... | ... | @@ -23107,7 +23177,7 @@ fn genSetReg( |
| 23107 | 23177 | }, |
| 23108 | 23178 | else => unreachable, |
| 23109 | 23179 | }, |
| 23110 | .mmx, .sse, .ip => unreachable, | |
| 23180 | .mmx, .sse, .ip, .cr, .dr => unreachable, | |
| 23111 | 23181 | }, |
| 23112 | 23182 | .mmx => unreachable, |
| 23113 | 23183 | .sse => switch (src_reg.class()) { |
| ... | ... | @@ -23126,7 +23196,7 @@ fn genSetReg( |
| 23126 | 23196 | .{ .register = try self.copyToTmpRegister(ty, src_mcv) }, |
| 23127 | 23197 | opts, |
| 23128 | 23198 | ), |
| 23129 | .x87, .mmx, .ip => unreachable, | |
| 23199 | .x87, .mmx, .ip, .cr, .dr => unreachable, | |
| 23130 | 23200 | .sse => try self.asmRegisterRegister( |
| 23131 | 23201 | @as(?Mir.Inst.FixedTag, switch (ty.scalarType(zcu).zigTypeTag(zcu)) { |
| 23132 | 23202 | else => switch (abi_size) { |
| ... | ... | @@ -23153,7 +23223,7 @@ fn genSetReg( |
| 23153 | 23223 | registerAlias(src_reg, abi_size), |
| 23154 | 23224 | ), |
| 23155 | 23225 | }, |
| 23156 | .ip => unreachable, | |
| 23226 | .ip, .cr, .dr => unreachable, | |
| 23157 | 23227 | }, |
| 23158 | 23228 | inline .register_pair, |
| 23159 | 23229 | .register_triple, |
| ... | ... | @@ -23294,7 +23364,7 @@ fn genSetReg( |
| 23294 | 23364 | }); |
| 23295 | 23365 | return; |
| 23296 | 23366 | }, |
| 23297 | .segment, .mmx, .ip => unreachable, | |
| 23367 | .segment, .mmx, .ip, .cr, .dr => unreachable, | |
| 23298 | 23368 | .x87, .sse => {}, |
| 23299 | 23369 | }, |
| 23300 | 23370 | .load_direct => |sym_index| switch (dst_reg.class()) { |
| ... | ... | @@ -23309,7 +23379,7 @@ fn genSetReg( |
| 23309 | 23379 | }); |
| 23310 | 23380 | return; |
| 23311 | 23381 | }, |
| 23312 | .segment, .mmx, .ip => unreachable, | |
| 23382 | .segment, .mmx, .ip, .cr, .dr => unreachable, | |
| 23313 | 23383 | .x87, .sse => {}, |
| 23314 | 23384 | }, |
| 23315 | 23385 | .load_got, .load_tlv => {}, |
| ... | ... | @@ -23456,7 +23526,7 @@ fn genSetMem( |
| 23456 | 23526 | }; |
| 23457 | 23527 | const src_alias = registerAlias(src_reg, abi_size); |
| 23458 | 23528 | 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), | |
| 23460 | 23530 | .mmx, .sse => abi_size, |
| 23461 | 23531 | }); |
| 23462 | 23532 | const src_align: InternPool.Alignment = .fromNonzeroByteUnits( |
| ... | ... | @@ -24240,18 +24310,18 @@ fn atomicOp( |
| 24240 | 24310 | }; |
| 24241 | 24311 | switch (strat) { |
| 24242 | 24312 | .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 }, | |
| 24250 | 24320 | else => unreachable, |
| 24251 | 24321 | } else switch (order) { |
| 24252 | .unordered, .monotonic, .release, .acq_rel => .mov, | |
| 24322 | .unordered, .monotonic, .release, .acq_rel => .{ ._, .mov }, | |
| 24253 | 24323 | .acquire => unreachable, |
| 24254 | .seq_cst => .xchg, | |
| 24324 | .seq_cst => .{ ._g, .xch }, | |
| 24255 | 24325 | }; |
| 24256 | 24326 | |
| 24257 | 24327 | const dst_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp); |
| ... | ... | @@ -24260,18 +24330,10 @@ fn atomicOp( |
| 24260 | 24330 | defer self.register_manager.unlockReg(dst_lock); |
| 24261 | 24331 | |
| 24262 | 24332 | 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) { | |
| 24264 | 24334 | try self.genUnOpMir(.{ ._, .neg }, val_ty, dst_mcv); |
| 24265 | 24335 | } |
| 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)); | |
| 24275 | 24337 | |
| 24276 | 24338 | return if (unused) .unreach else dst_mcv; |
| 24277 | 24339 | }, |
| ... | ... | @@ -27599,7 +27661,7 @@ fn resolveCallingConventionValues( |
| 27599 | 27661 | break :return_value .init(.{ .register = registerAlias(ret_gpr[0], ret_size) }) |
| 27600 | 27662 | else if (ret_gpr.len >= 2 and ret_ty.isSliceAtRuntime(zcu)) |
| 27601 | 27663 | break :return_value .init(.{ .register_pair = ret_gpr[0..2].* }), |
| 27602 | .segment, .mmx, .ip => unreachable, | |
| 27664 | .segment, .mmx, .ip, .cr, .dr => unreachable, | |
| 27603 | 27665 | .x87 => break :return_value .init(.{ .register = .st0 }), |
| 27604 | 27666 | .sse => if (ret_size <= self.vectorSize(.float)) break :return_value .init(.{ |
| 27605 | 27667 | .register = registerAlias(abi.getCAbiSseReturnRegs(cc)[0], @max(ret_size, 16)), |
| ... | ... | @@ -27634,7 +27696,7 @@ fn resolveCallingConventionValues( |
| 27634 | 27696 | param_gpr = param_gpr[2..]; |
| 27635 | 27697 | continue; |
| 27636 | 27698 | }, |
| 27637 | .segment, .mmx, .ip => unreachable, | |
| 27699 | .segment, .mmx, .ip, .cr, .dr => unreachable, | |
| 27638 | 27700 | .x87 => if (param_x87.len >= 1) { |
| 27639 | 27701 | arg.* = .{ .register = param_x87[0] }; |
| 27640 | 27702 | param_x87 = param_x87[1..]; |
| ... | ... | @@ -27686,9 +27748,9 @@ fn failMsg(self: *CodeGen, msg: *Zcu.ErrorMsg) error{ OutOfMemory, CodegenFail } |
| 27686 | 27748 | } |
| 27687 | 27749 | |
| 27688 | 27750 | fn 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 | ); | |
| 27692 | 27754 | return std.meta.stringToEnum(Register, name); |
| 27693 | 27755 | } |
| 27694 | 27756 | |
| ... | ... | @@ -27733,6 +27795,14 @@ fn registerAlias(reg: Register, size_bytes: u32) Register { |
| 27733 | 27795 | .rip |
| 27734 | 27796 | else |
| 27735 | 27797 | 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, | |
| 27736 | 27806 | }; |
| 27737 | 27807 | } |
| 27738 | 27808 |
src/arch/x86_64/Disassembler.zig+16-1| ... | ... | @@ -80,6 +80,21 @@ pub fn next(dis: *Disassembler) Error!?Instruction { |
| 80 | 80 | .op2 = .{ .imm = imm }, |
| 81 | 81 | }); |
| 82 | 82 | }, |
| 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 | }, | |
| 83 | 98 | .m, .mi, .m1, .mc => { |
| 84 | 99 | const modrm = try dis.parseModRmByte(); |
| 85 | 100 | const act_enc = Encoding.findByOpcode(enc.opcode(), .{ |
| ... | ... | @@ -241,7 +256,7 @@ pub fn next(dis: *Disassembler) Error!?Instruction { |
| 241 | 256 | .op3 = op3, |
| 242 | 257 | }); |
| 243 | 258 | }, |
| 244 | .rm0, .vmi, .rvm, .rvmr, .rvmi, .mvr, .rmv => unreachable, // TODO | |
| 259 | .rm0, .vm, .vmi, .rvm, .rvmr, .rvmi, .mvr, .rmv => unreachable, // TODO | |
| 245 | 260 | } |
| 246 | 261 | } |
| 247 | 262 |
src/arch/x86_64/Encoding.zig+193-88| ... | ... | @@ -60,6 +60,32 @@ pub fn findByMnemonic( |
| 60 | 60 | next: for (mnemonic_to_encodings_map[@intFromEnum(mnemonic)]) |data| { |
| 61 | 61 | if (!switch (data.feature) { |
| 62 | 62 | .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 | }, | |
| 63 | 89 | inline else => |tag| has_features: { |
| 64 | 90 | comptime var feature_it = std.mem.splitScalar(u8, @tagName(tag), ' '); |
| 65 | 91 | comptime var features: []const std.Target.x86.Feature = &.{}; |
| ... | ... | @@ -126,7 +152,7 @@ pub fn mandatoryPrefix(encoding: *const Encoding) ?u8 { |
| 126 | 152 | |
| 127 | 153 | pub fn modRmExt(encoding: Encoding) u3 { |
| 128 | 154 | 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, | |
| 130 | 156 | else => unreachable, |
| 131 | 157 | }; |
| 132 | 158 | } |
| ... | ... | @@ -176,7 +202,7 @@ pub fn format( |
| 176 | 202 | for (opc) |byte| try writer.print("{x:0>2} ", .{byte}); |
| 177 | 203 | |
| 178 | 204 | switch (encoding.data.op_en) { |
| 179 | .z, .fd, .td, .i, .zi, .d => {}, | |
| 205 | .z, .fd, .td, .i, .zi, .ii, .d => {}, | |
| 180 | 206 | .o, .zo, .oz, .oi => { |
| 181 | 207 | const op = switch (encoding.data.op_en) { |
| 182 | 208 | .o, .oz, .oi => encoding.data.ops[0], |
| ... | ... | @@ -192,17 +218,24 @@ pub fn format( |
| 192 | 218 | }; |
| 193 | 219 | try writer.print("+{s} ", .{tag}); |
| 194 | 220 | }, |
| 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()}), | |
| 196 | 222 | .mr, .rm, .rmi, .mri, .mrc, .rm0, .rvm, .rvmr, .rvmi, .mvr, .rmv => try writer.writeAll("/r "), |
| 197 | 223 | } |
| 198 | 224 | |
| 199 | 225 | 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 | }, | |
| 206 | 239 | else => unreachable, |
| 207 | 240 | }; |
| 208 | 241 | const tag = switch (op) { |
| ... | ... | @@ -218,13 +251,13 @@ pub fn format( |
| 218 | 251 | try writer.print("{s} ", .{tag}); |
| 219 | 252 | }, |
| 220 | 253 | .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 => {}, | |
| 222 | 255 | } |
| 223 | 256 | |
| 224 | 257 | try writer.print("{s} ", .{@tagName(encoding.mnemonic)}); |
| 225 | 258 | |
| 226 | 259 | for (encoding.data.ops) |op| switch (op) { |
| 227 | .none, .o16, .o32, .o64 => break, | |
| 260 | .none => break, | |
| 228 | 261 | else => try writer.print("{s} ", .{@tagName(op)}), |
| 229 | 262 | }; |
| 230 | 263 | |
| ... | ... | @@ -253,48 +286,67 @@ pub const Mnemonic = enum { |
| 253 | 286 | @".cfi_escape", |
| 254 | 287 | // zig fmt: off |
| 255 | 288 | // 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, | |
| 258 | 291 | 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, | |
| 260 | 293 | cmova, cmovae, cmovb, cmovbe, cmovc, cmove, cmovg, cmovge, cmovl, cmovle, cmovna, |
| 261 | 294 | cmovnae, cmovnb, cmovnbe, cmovnc, cmovne, cmovng, cmovnge, cmovnl, cmovnle, cmovno, |
| 262 | 295 | 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, | |
| 266 | 297 | 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, | |
| 272 | 306 | lods, lodsb, lodsd, lodsq, lodsw, |
| 273 | lzcnt, | |
| 307 | lsl, ltr, lzcnt, | |
| 274 | 308 | mfence, mov, movbe, |
| 275 | 309 | movs, movsb, movsd, movsq, movsw, |
| 276 | 310 | movsx, movsxd, movzx, mul, |
| 277 | 311 | 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, | |
| 282 | 318 | scas, scasb, scasd, scasq, scasw, |
| 319 | senduipi, serialize, | |
| 283 | 320 | 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, | |
| 286 | 323 | seta, setae, setb, setbe, setc, sete, setg, setge, setl, setle, setna, setnae, |
| 287 | 324 | setnb, setnbe, setnc, setne, setng, setnge, setnl, setnle, setno, setnp, setns, |
| 288 | 325 | setnz, seto, setp, setpe, setpo, sets, setz, |
| 289 | sfence, | |
| 326 | sfence, sidt, sldt, smsw, | |
| 290 | 327 | 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, | |
| 294 | 332 | // 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, | |
| 296 | 348 | // MMX |
| 297 | movd, movq, | |
| 349 | emms, movd, movq, | |
| 298 | 350 | packssdw, packsswb, packuswb, |
| 299 | 351 | paddb, paddd, paddq, paddsb, paddsw, paddusb, paddusw, paddw, |
| 300 | 352 | pand, pandn, por, pxor, |
| ... | ... | @@ -312,6 +364,7 @@ pub const Mnemonic = enum { |
| 312 | 364 | cmpps, cmpss, |
| 313 | 365 | cvtpi2ps, cvtps2pi, cvtsi2ss, cvtss2si, cvttps2pi, cvttss2si, |
| 314 | 366 | divps, divss, |
| 367 | fxrstor, fxrstor64, fxsave, fxsave64, | |
| 315 | 368 | ldmxcsr, |
| 316 | 369 | maxps, maxss, |
| 317 | 370 | minps, minss, |
| ... | ... | @@ -333,10 +386,12 @@ pub const Mnemonic = enum { |
| 333 | 386 | andpd, |
| 334 | 387 | andnpd, |
| 335 | 388 | cmppd, //cmpsd, |
| 389 | comisd, comiss, | |
| 336 | 390 | cvtdq2pd, cvtdq2ps, cvtpd2dq, cvtpd2pi, cvtpd2ps, cvtpi2pd, |
| 337 | 391 | cvtps2dq, cvtps2pd, cvtsd2si, cvtsd2ss, cvtsi2sd, cvtss2sd, |
| 338 | 392 | cvttpd2dq, cvttpd2pi, cvttps2dq, cvttsd2si, |
| 339 | 393 | divpd, divsd, |
| 394 | gf2p8affineinvqb, gf2p8affineqb, gf2p8mulb, | |
| 340 | 395 | maxpd, maxsd, |
| 341 | 396 | minpd, minsd, |
| 342 | 397 | movapd, |
| ... | ... | @@ -357,11 +412,12 @@ pub const Mnemonic = enum { |
| 357 | 412 | ucomisd, |
| 358 | 413 | xorpd, |
| 359 | 414 | // SSE3 |
| 360 | movddup, movshdup, movsldup, | |
| 415 | addsubpd, addsubps, haddpd, haddps, lddqu, movddup, movshdup, movsldup, | |
| 361 | 416 | // SSSE3 |
| 362 | 417 | pabsb, pabsd, pabsw, palignr, pshufb, |
| 363 | 418 | // SSE4.1 |
| 364 | 419 | blendpd, blendps, blendvpd, blendvps, |
| 420 | dppd, dpps, | |
| 365 | 421 | extractps, |
| 366 | 422 | insertps, |
| 367 | 423 | packusdw, |
| ... | ... | @@ -376,28 +432,32 @@ pub const Mnemonic = enum { |
| 376 | 432 | ptest, |
| 377 | 433 | roundpd, roundps, roundsd, roundss, |
| 378 | 434 | // SSE4.2 |
| 379 | pcmpgtq, | |
| 435 | crc32, pcmpgtq, | |
| 380 | 436 | // PCLMUL |
| 381 | 437 | pclmulqdq, |
| 382 | 438 | // AES |
| 383 | 439 | aesdec, aesdeclast, aesenc, aesenclast, aesimc, aeskeygenassist, |
| 384 | 440 | // SHA |
| 385 | sha256msg1, sha256msg2, sha256rnds2, | |
| 441 | sha1rnds4, sha1nexte, sha1msg1, sha1msg2, sha256msg1, sha256msg2, sha256rnds2, | |
| 386 | 442 | // AVX |
| 387 | vaddpd, vaddps, vaddsd, vaddss, | |
| 443 | andn, bextr, blsi, blsmsk, blsr, bzhi, tzcnt, | |
| 444 | vaddpd, vaddps, vaddsd, vaddss, vaddsubpd, vaddsubps, | |
| 388 | 445 | vaesdec, vaesdeclast, vaesenc, vaesenclast, vaesimc, vaeskeygenassist, |
| 389 | 446 | vandnpd, vandnps, vandpd, vandps, |
| 390 | 447 | vblendpd, vblendps, vblendvpd, vblendvps, |
| 391 | 448 | vbroadcastf128, vbroadcastsd, vbroadcastss, |
| 392 | vcmppd, vcmpps, vcmpsd, vcmpss, | |
| 449 | vcmppd, vcmpps, vcmpsd, vcmpss, vcomisd, vcomiss, | |
| 393 | 450 | vcvtdq2pd, vcvtdq2ps, vcvtpd2dq, vcvtpd2ps, |
| 394 | 451 | vcvtps2dq, vcvtps2pd, vcvtsd2si, vcvtsd2ss, |
| 395 | 452 | vcvtsi2sd, vcvtsi2ss, vcvtss2sd, vcvtss2si, |
| 396 | 453 | vcvttpd2dq, vcvttps2dq, vcvttsd2si, vcvttss2si, |
| 397 | 454 | vdivpd, vdivps, vdivsd, vdivss, |
| 455 | vdppd, vdpps, | |
| 398 | 456 | vextractf128, vextractps, |
| 457 | vgf2p8affineinvqb, vgf2p8affineqb, vgf2p8mulb, | |
| 458 | vhaddpd, vhaddps, | |
| 399 | 459 | vinsertf128, vinsertps, |
| 400 | vldmxcsr, | |
| 460 | vlddqu, vldmxcsr, | |
| 401 | 461 | vmaxpd, vmaxps, vmaxsd, vmaxss, |
| 402 | 462 | vminpd, vminps, vminsd, vminss, |
| 403 | 463 | vmovapd, vmovaps, |
| ... | ... | @@ -455,6 +515,12 @@ pub const Mnemonic = enum { |
| 455 | 515 | // AVX2 |
| 456 | 516 | vbroadcasti128, vpbroadcastb, vpbroadcastd, vpbroadcastq, vpbroadcastw, |
| 457 | 517 | 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, | |
| 458 | 524 | // zig fmt: on |
| 459 | 525 | }; |
| 460 | 526 | |
| ... | ... | @@ -462,24 +528,23 @@ pub const OpEn = enum { |
| 462 | 528 | // zig fmt: off |
| 463 | 529 | z, |
| 464 | 530 | o, zo, oz, oi, |
| 465 | i, zi, | |
| 531 | i, zi, ii, ia, | |
| 466 | 532 | d, m, |
| 467 | 533 | fd, td, |
| 468 | 534 | m1, mc, mi, mr, rm, |
| 469 | 535 | rmi, mri, mrc, |
| 470 | rm0, vmi, rvm, rvmr, rvmi, mvr, rmv, | |
| 536 | rm0, vm, vmi, rvm, rvmr, rvmi, mvr, rmv, | |
| 471 | 537 | // zig fmt: on |
| 472 | 538 | }; |
| 473 | 539 | |
| 474 | 540 | pub const Op = enum { |
| 475 | 541 | // zig fmt: off |
| 476 | 542 | none, |
| 477 | o16, o32, o64, | |
| 478 | 543 | unity, |
| 479 | 544 | imm8, imm16, imm32, imm64, |
| 480 | 545 | imm8s, imm16s, imm32s, |
| 481 | 546 | al, ax, eax, rax, |
| 482 | cl, | |
| 547 | cl, dx, | |
| 483 | 548 | rip, eip, ip, |
| 484 | 549 | r8, r16, r32, r64, |
| 485 | 550 | rm8, rm16, rm32, rm64, |
| ... | ... | @@ -489,9 +554,10 @@ pub const Op = enum { |
| 489 | 554 | m, |
| 490 | 555 | moffs, |
| 491 | 556 | sreg, |
| 492 | st, mm, mm_m64, | |
| 557 | st0, st, mm, mm_m64, | |
| 493 | 558 | xmm0, xmm, xmm_m8, xmm_m16, xmm_m32, xmm_m64, xmm_m128, |
| 494 | 559 | ymm, ymm_m256, |
| 560 | cr, dr, | |
| 495 | 561 | // zig fmt: on |
| 496 | 562 | |
| 497 | 563 | pub fn fromOperand(operand: Instruction.Operand, target: *const std.Target) Op { |
| ... | ... | @@ -499,32 +565,34 @@ pub const Op = enum { |
| 499 | 565 | .none => .none, |
| 500 | 566 | |
| 501 | 567 | .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, | |
| 508 | 580 | 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 | }, | |
| 518 | 582 | }, |
| 519 | 583 | .segment => .sreg, |
| 520 | .x87 => .st, | |
| 584 | .x87 => switch (reg) { | |
| 585 | .st0 => .st0, | |
| 586 | else => .st, | |
| 587 | }, | |
| 521 | 588 | .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 | }, | |
| 528 | 596 | }, |
| 529 | 597 | .ip => switch (reg) { |
| 530 | 598 | .rip => .rip, |
| ... | ... | @@ -532,6 +600,8 @@ pub const Op = enum { |
| 532 | 600 | .ip => .ip, |
| 533 | 601 | else => unreachable, |
| 534 | 602 | }, |
| 603 | .cr => .cr, | |
| 604 | .dr => .dr, | |
| 535 | 605 | }, |
| 536 | 606 | |
| 537 | 607 | .mem => |mem| switch (mem) { |
| ... | ... | @@ -588,24 +658,27 @@ pub const Op = enum { |
| 588 | 658 | .eax => .eax, |
| 589 | 659 | .rax => .rax, |
| 590 | 660 | .cl => .cl, |
| 661 | .dx => .dx, | |
| 591 | 662 | .rip => .rip, |
| 592 | 663 | .eip => .eip, |
| 593 | 664 | .ip => .ip, |
| 665 | .st0 => .st0, | |
| 594 | 666 | .xmm0 => .xmm0, |
| 595 | 667 | }; |
| 596 | 668 | } |
| 597 | 669 | |
| 598 | 670 | pub fn immBitSize(op: Op) u64 { |
| 599 | 671 | 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, | |
| 602 | 674 | .ax, .r16, .rm16 => unreachable, |
| 603 | 675 | .eax, .r32, .rm32, .r32_m16 => unreachable, |
| 604 | 676 | .rax, .r64, .rm64, .r64_m16 => unreachable, |
| 605 | .st, .mm, .mm_m64 => unreachable, | |
| 677 | .st0, .st, .mm, .mm_m64 => unreachable, | |
| 606 | 678 | .xmm0, .xmm, .xmm_m8, .xmm_m16, .xmm_m32, .xmm_m64, .xmm_m128 => unreachable, |
| 607 | 679 | .ymm, .ymm_m256 => unreachable, |
| 608 | 680 | .m8, .m16, .m32, .m64, .m80, .m128, .m256 => unreachable, |
| 681 | .cr, .dr => unreachable, | |
| 609 | 682 | .unity => 1, |
| 610 | 683 | .imm8, .imm8s, .rel8 => 8, |
| 611 | 684 | .imm16, .imm16s, .rel16 => 16, |
| ... | ... | @@ -616,15 +689,15 @@ pub const Op = enum { |
| 616 | 689 | |
| 617 | 690 | pub fn regBitSize(op: Op) u64 { |
| 618 | 691 | return switch (op) { |
| 619 | .none, .o16, .o32, .o64, .moffs, .m, .sreg => unreachable, | |
| 692 | .none, .moffs, .m, .sreg => unreachable, | |
| 620 | 693 | .unity, .imm8, .imm8s, .imm16, .imm16s, .imm32, .imm32s, .imm64 => unreachable, |
| 621 | 694 | .rel8, .rel16, .rel32 => unreachable, |
| 622 | 695 | .m8, .m16, .m32, .m64, .m80, .m128, .m256 => unreachable, |
| 623 | 696 | .al, .cl, .r8, .rm8 => 8, |
| 624 | .ax, .ip, .r16, .rm16 => 16, | |
| 697 | .ax, .dx, .ip, .r16, .rm16 => 16, | |
| 625 | 698 | .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, | |
| 628 | 701 | .xmm0, .xmm, .xmm_m8, .xmm_m16, .xmm_m32, .xmm_m64, .xmm_m128 => 128, |
| 629 | 702 | .ymm, .ymm_m256 => 256, |
| 630 | 703 | }; |
| ... | ... | @@ -632,11 +705,12 @@ pub const Op = enum { |
| 632 | 705 | |
| 633 | 706 | pub fn memBitSize(op: Op) u64 { |
| 634 | 707 | return switch (op) { |
| 635 | .none, .o16, .o32, .o64, .moffs, .m, .sreg => unreachable, | |
| 708 | .none, .moffs, .m, .sreg => unreachable, | |
| 636 | 709 | .unity, .imm8, .imm8s, .imm16, .imm16s, .imm32, .imm32s, .imm64 => unreachable, |
| 637 | 710 | .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, | |
| 640 | 714 | .m8, .rm8, .r32_m8, .xmm_m8 => 8, |
| 641 | 715 | .m16, .rm16, .r32_m16, .r64_m16, .xmm_m16 => 16, |
| 642 | 716 | .m32, .rm32, .xmm_m32 => 32, |
| ... | ... | @@ -664,14 +738,15 @@ pub const Op = enum { |
| 664 | 738 | // zig fmt: off |
| 665 | 739 | return switch (op) { |
| 666 | 740 | .al, .ax, .eax, .rax, |
| 667 | .cl, | |
| 741 | .cl, .dx, | |
| 668 | 742 | .ip, .eip, .rip, |
| 669 | 743 | .r8, .r16, .r32, .r64, |
| 670 | 744 | .rm8, .rm16, .rm32, .rm64, |
| 671 | 745 | .r32_m8, .r32_m16, .r64_m16, |
| 672 | .st, .mm, .mm_m64, | |
| 746 | .st0, .st, .mm, .mm_m64, | |
| 673 | 747 | .xmm0, .xmm, .xmm_m8, .xmm_m16, .xmm_m32, .xmm_m64, .xmm_m128, |
| 674 | 748 | .ymm, .ymm_m256, |
| 749 | .cr, .dr, | |
| 675 | 750 | => true, |
| 676 | 751 | else => false, |
| 677 | 752 | }; |
| ... | ... | @@ -717,33 +792,34 @@ pub const Op = enum { |
| 717 | 792 | pub fn class(op: Op) bits.Register.Class { |
| 718 | 793 | return switch (op) { |
| 719 | 794 | else => unreachable, |
| 720 | .al, .ax, .eax, .rax, .cl => .general_purpose, | |
| 795 | .al, .ax, .eax, .rax, .cl, .dx => .general_purpose, | |
| 721 | 796 | .r8, .r16, .r32, .r64 => .general_purpose, |
| 722 | 797 | .rm8, .rm16, .rm32, .rm64 => .general_purpose, |
| 723 | 798 | .r32_m8, .r32_m16, .r64_m16 => .general_purpose, |
| 724 | 799 | .sreg => .segment, |
| 725 | .st => .x87, | |
| 800 | .st0, .st => .x87, | |
| 726 | 801 | .mm, .mm_m64 => .mmx, |
| 727 | 802 | .xmm0, .xmm, .xmm_m8, .xmm_m16, .xmm_m32, .xmm_m64, .xmm_m128 => .sse, |
| 728 | 803 | .ymm, .ymm_m256 => .sse, |
| 729 | 804 | .rip, .eip, .ip => .ip, |
| 805 | .cr => .cr, | |
| 806 | .dr => .dr, | |
| 730 | 807 | }; |
| 731 | 808 | } |
| 732 | 809 | |
| 733 | 810 | /// Given an operand `op` checks if `target` is a subset for the purposes of the encoding. |
| 734 | 811 | pub fn isSubset(op: Op, target: Op) bool { |
| 735 | 812 | switch (op) { |
| 736 | .o16, .o32, .o64 => unreachable, | |
| 737 | 813 | .moffs, .sreg => return op == target, |
| 738 | 814 | .none => switch (target) { |
| 739 | .o16, .o32, .o64, .none => return true, | |
| 815 | .none => return true, | |
| 740 | 816 | else => return false, |
| 741 | 817 | }, |
| 742 | 818 | else => { |
| 743 | 819 | 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, | |
| 747 | 823 | }; |
| 748 | 824 | } |
| 749 | 825 | if (op.isMemory() and target.isMemory()) { |
| ... | ... | @@ -779,6 +855,7 @@ pub const Mode = enum { |
| 779 | 855 | none, |
| 780 | 856 | short, long, |
| 781 | 857 | rex, rex_short, |
| 858 | wait, | |
| 782 | 859 | vex_128_w0, vex_128_w1, vex_128_wig, |
| 783 | 860 | vex_256_w0, vex_256_w1, vex_256_wig, |
| 784 | 861 | vex_lig_w0, vex_lig_w1, vex_lig_wig, |
| ... | ... | @@ -841,20 +918,46 @@ pub const Mode = enum { |
| 841 | 918 | |
| 842 | 919 | pub const Feature = enum { |
| 843 | 920 | none, |
| 921 | @"32bit", | |
| 922 | @"64bit", | |
| 923 | adx, | |
| 844 | 924 | aes, |
| 845 | 925 | @"aes avx", |
| 846 | 926 | avx, |
| 847 | 927 | avx2, |
| 848 | 928 | bmi, |
| 849 | 929 | bmi2, |
| 930 | cldemote, | |
| 931 | clflushopt, | |
| 932 | clwb, | |
| 850 | 933 | cmov, |
| 934 | @"cmov x87", | |
| 935 | crc32, | |
| 936 | enqcmd, | |
| 851 | 937 | f16c, |
| 852 | 938 | fma, |
| 939 | fsgsbase, | |
| 940 | fxsr, | |
| 941 | gfni, | |
| 942 | @"gfni avx", | |
| 943 | hreset, | |
| 944 | @"invpcid 32bit", | |
| 945 | @"invpcid 64bit", | |
| 946 | kl, | |
| 853 | 947 | lzcnt, |
| 948 | mmx, | |
| 854 | 949 | movbe, |
| 855 | 950 | pclmul, |
| 856 | 951 | @"pclmul avx", |
| 952 | pku, | |
| 857 | 953 | popcnt, |
| 954 | rdrnd, | |
| 955 | rdseed, | |
| 956 | @"rdpid 32bit", | |
| 957 | @"rdpid 64bit", | |
| 958 | sahf, | |
| 959 | serialize, | |
| 960 | shstk, | |
| 858 | 961 | smap, |
| 859 | 962 | sse, |
| 860 | 963 | sse2, |
| ... | ... | @@ -866,6 +969,8 @@ pub const Feature = enum { |
| 866 | 969 | uintr, |
| 867 | 970 | vaes, |
| 868 | 971 | vpclmulqdq, |
| 972 | waitpkg, | |
| 973 | widekl, | |
| 869 | 974 | x87, |
| 870 | 975 | }; |
| 871 | 976 | |
| ... | ... | @@ -886,7 +991,7 @@ fn estimateInstructionLength(prefix: Prefix, encoding: Encoding, ops: []const Op |
| 886 | 991 | } |
| 887 | 992 | |
| 888 | 993 | const mnemonic_to_encodings_map = init: { |
| 889 | @setEvalBranchQuota(5_000); | |
| 994 | @setEvalBranchQuota(5_600); | |
| 890 | 995 | const mnemonic_count = @typeInfo(Mnemonic).@"enum".fields.len; |
| 891 | 996 | var mnemonic_map: [mnemonic_count][]Data = @splat(&.{}); |
| 892 | 997 | 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 { |
| 359 | 359 | .pseudo_dbg_local_ai_s, |
| 360 | 360 | => .s(@bitCast(i)), |
| 361 | 361 | |
| 362 | .ii, | |
| 363 | .ir, | |
| 362 | 364 | .rrri, |
| 363 | 365 | .rri_u, |
| 364 | 366 | .ri_u, |
| ... | ... | @@ -548,17 +550,19 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand) |
| 548 | 550 | } |
| 549 | 551 | |
| 550 | 552 | fn generic(lower: *Lower, inst: Mir.Inst) Error!void { |
| 553 | @setEvalBranchQuota(2_400); | |
| 551 | 554 | const fixes = switch (inst.ops) { |
| 552 | 555 | .none => inst.data.none.fixes, |
| 553 | 556 | .inst => inst.data.inst.fixes, |
| 554 | 557 | .i_s, .i_u => inst.data.i.fixes, |
| 558 | .ii => inst.data.ii.fixes, | |
| 555 | 559 | .r => inst.data.r.fixes, |
| 556 | 560 | .rr => inst.data.rr.fixes, |
| 557 | 561 | .rrr => inst.data.rrr.fixes, |
| 558 | 562 | .rrrr => inst.data.rrrr.fixes, |
| 559 | 563 | .rrri => inst.data.rrri.fixes, |
| 560 | 564 | .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, | |
| 562 | 566 | .rm, .rmi_s, .mr => inst.data.rx.fixes, |
| 563 | 567 | .mrr, .rrm, .rmr => inst.data.rrx.fixes, |
| 564 | 568 | .rmi, .mri => inst.data.rix.fixes, |
| ... | ... | @@ -575,8 +579,6 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void { |
| 575 | 579 | else |
| 576 | 580 | .none, |
| 577 | 581 | }, mnemonic: { |
| 578 | @setEvalBranchQuota(2_000); | |
| 579 | ||
| 580 | 582 | comptime var max_len = 0; |
| 581 | 583 | inline for (@typeInfo(Mnemonic).@"enum".fields) |field| max_len = @max(field.name.len, max_len); |
| 582 | 584 | var buf: [max_len]u8 = undefined; |
| ... | ... | @@ -598,6 +600,14 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void { |
| 598 | 600 | .i_s, .i_u => &.{ |
| 599 | 601 | .{ .imm = lower.imm(inst.ops, inst.data.i.i) }, |
| 600 | 602 | }, |
| 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 | }, | |
| 601 | 611 | .r => &.{ |
| 602 | 612 | .{ .reg = inst.data.r.r1 }, |
| 603 | 613 | }, |
src/arch/x86_64/Mir.zig+516-91| ... | ... | @@ -23,8 +23,82 @@ pub const Inst = struct { |
| 23 | 23 | /// ___ |
| 24 | 24 | @"_", |
| 25 | 25 | |
| 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 ___ | |
| 26 | 74 | /// Integer ___ |
| 27 | 75 | 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, | |
| 28 | 102 | |
| 29 | 103 | /// ___ Left |
| 30 | 104 | _l, |
| ... | ... | @@ -33,6 +107,8 @@ pub const Inst = struct { |
| 33 | 107 | /// ___ Left Without Affecting Flags |
| 34 | 108 | _lx, |
| 35 | 109 | /// ___ Right |
| 110 | /// ___ For Reading | |
| 111 | /// ___ Register | |
| 36 | 112 | _r, |
| 37 | 113 | /// ___ Right Double |
| 38 | 114 | _rd, |
| ... | ... | @@ -45,7 +121,7 @@ pub const Inst = struct { |
| 45 | 121 | //_r, |
| 46 | 122 | |
| 47 | 123 | /// ___ Above |
| 48 | _a, | |
| 124 | //_a, | |
| 49 | 125 | /// ___ Above Or Equal |
| 50 | 126 | _ae, |
| 51 | 127 | /// ___ Below |
| ... | ... | @@ -102,7 +178,7 @@ pub const Inst = struct { |
| 102 | 178 | /// ___ Parity Odd |
| 103 | 179 | _po, |
| 104 | 180 | /// ___ Sign |
| 105 | _s, | |
| 181 | //_s, | |
| 106 | 182 | /// ___ Zero |
| 107 | 183 | _z, |
| 108 | 184 | /// ___ Alignment Check Flag |
| ... | ... | @@ -111,15 +187,18 @@ pub const Inst = struct { |
| 111 | 187 | //_d, |
| 112 | 188 | /// ___ Interrupt Flag |
| 113 | 189 | _i, |
| 190 | /// ___ Task-Switched Flag In CR0 | |
| 191 | _ts, | |
| 114 | 192 | /// ___ User Interrupt Flag |
| 115 | 193 | _ui, |
| 116 | 194 | |
| 117 | 195 | /// ___ Byte |
| 118 | 196 | //_b, |
| 119 | 197 | /// ___ Word |
| 198 | /// ___ For Writing | |
| 120 | 199 | _w, |
| 121 | 200 | /// ___ Doubleword |
| 122 | _d, | |
| 201 | //_d, | |
| 123 | 202 | /// ___ QuadWord |
| 124 | 203 | _q, |
| 125 | 204 | |
| ... | ... | @@ -214,8 +293,72 @@ pub const Inst = struct { |
| 214 | 293 | |
| 215 | 294 | /// Float ___ |
| 216 | 295 | 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, | |
| 217 | 325 | /// Float ___ Pop |
| 218 | 326 | 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, | |
| 219 | 362 | |
| 220 | 363 | /// Packed ___ |
| 221 | 364 | p_, |
| ... | ... | @@ -243,6 +386,24 @@ pub const Inst = struct { |
| 243 | 386 | /// ___ Packed Double-Precision Values |
| 244 | 387 | _pd, |
| 245 | 388 | |
| 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 | ||
| 246 | 407 | /// VEX-Encoded ___ |
| 247 | 408 | v_, |
| 248 | 409 | /// VEX-Encoded ___ Byte |
| ... | ... | @@ -282,6 +443,19 @@ pub const Inst = struct { |
| 282 | 443 | /// VEX-Encoded ___ 128-Bits Of Floating-Point Data |
| 283 | 444 | v_f128, |
| 284 | 445 | |
| 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 | ||
| 285 | 459 | /// Mask ___ Byte |
| 286 | 460 | k_b, |
| 287 | 461 | /// Mask ___ Word |
| ... | ... | @@ -300,6 +474,12 @@ pub const Inst = struct { |
| 300 | 474 | }; |
| 301 | 475 | |
| 302 | 476 | 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, | |
| 303 | 483 | /// Add with carry |
| 304 | 484 | adc, |
| 305 | 485 | /// Add |
| ... | ... | @@ -313,6 +493,8 @@ pub const Inst = struct { |
| 313 | 493 | /// Bitwise logical and of packed single-precision floating-point values |
| 314 | 494 | /// Bitwise logical and of packed double-precision floating-point values |
| 315 | 495 | @"and", |
| 496 | /// Adjust RPL field of segment selector | |
| 497 | arpl, | |
| 316 | 498 | /// Bit scan forward |
| 317 | 499 | /// Bit scan reverse |
| 318 | 500 | bs, |
| ... | ... | @@ -324,6 +506,7 @@ pub const Inst = struct { |
| 324 | 506 | /// Bit test and set |
| 325 | 507 | bt, |
| 326 | 508 | /// Call |
| 509 | /// Fast system call | |
| 327 | 510 | call, |
| 328 | 511 | /// Convert byte to word |
| 329 | 512 | cbw, |
| ... | ... | @@ -331,12 +514,25 @@ pub const Inst = struct { |
| 331 | 514 | cdq, |
| 332 | 515 | /// Convert doubleword to quadword |
| 333 | 516 | cdqe, |
| 517 | /// Clear AC flag in EFLAGS register | |
| 334 | 518 | /// Clear carry flag |
| 335 | 519 | /// Clear direction flag |
| 336 | 520 | /// Clear interrupt flag |
| 521 | /// Clear task-switched flag in CR0 | |
| 522 | /// Clear user interrupt flag | |
| 337 | 523 | cl, |
| 524 | /// Cache line demote | |
| 525 | cldemote, | |
| 338 | 526 | /// Flush cache line |
| 339 | 527 | 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, | |
| 340 | 536 | /// Conditional move |
| 341 | 537 | cmov, |
| 342 | 538 | /// Logical compare |
| ... | ... | @@ -355,33 +551,79 @@ pub const Inst = struct { |
| 355 | 551 | cwd, |
| 356 | 552 | /// Convert word to doubleword |
| 357 | 553 | cwde, |
| 554 | /// Decimal adjust AL after addition | |
| 555 | /// Decimal adjust AL after subtraction | |
| 556 | da, | |
| 358 | 557 | /// Decrement by 1 |
| 359 | dec, | |
| 558 | /// Decrement shadow stack pointer | |
| 559 | de, | |
| 360 | 560 | /// Unsigned division |
| 361 | 561 | /// Signed division |
| 562 | /// Divide | |
| 362 | 563 | /// Divide packed single-precision floating-point values |
| 363 | 564 | /// Divide scalar single-precision floating-point values |
| 364 | 565 | /// Divide packed double-precision floating-point values |
| 365 | 566 | /// Divide scalar double-precision floating-point values |
| 366 | 567 | 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 | |
| 367 | 589 | /// Increment by 1 |
| 368 | inc, | |
| 590 | /// Increment shadow stack pointer | |
| 591 | in, | |
| 369 | 592 | /// Call to interrupt procedure |
| 370 | int3, | |
| 593 | int, | |
| 594 | /// Invalidate internal caches | |
| 595 | /// Invalidate TLB entries | |
| 596 | /// Invalidate process-context identifier | |
| 597 | inv, | |
| 371 | 598 | /// Conditional jump |
| 372 | j, | |
| 373 | 599 | /// Jump |
| 374 | jmp, | |
| 600 | j, | |
| 601 | /// Load status flags into AH register | |
| 602 | lahf, | |
| 603 | /// Load access right byte | |
| 604 | lar, | |
| 375 | 605 | /// Load effective address |
| 376 | 606 | 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, | |
| 377 | 617 | /// Load string |
| 378 | 618 | 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, | |
| 381 | 625 | /// Count the number of leading zero bits |
| 382 | 626 | lzcnt, |
| 383 | /// Memory fence | |
| 384 | mfence, | |
| 385 | 627 | /// Move |
| 386 | 628 | /// Move data from string to string |
| 387 | 629 | /// Move scalar single-precision floating-point value |
| ... | ... | @@ -407,6 +649,7 @@ pub const Inst = struct { |
| 407 | 649 | /// Two's complement negation |
| 408 | 650 | neg, |
| 409 | 651 | /// No-op |
| 652 | /// No operation | |
| 410 | 653 | nop, |
| 411 | 654 | /// One's complement negation |
| 412 | 655 | not, |
| ... | ... | @@ -414,39 +657,62 @@ pub const Inst = struct { |
| 414 | 657 | /// Bitwise logical or of packed single-precision floating-point values |
| 415 | 658 | /// Bitwise logical or of packed double-precision floating-point values |
| 416 | 659 | @"or", |
| 660 | /// Output to port | |
| 661 | /// Output string to port | |
| 662 | out, | |
| 417 | 663 | /// Spin loop hint |
| 664 | /// Timed pause | |
| 418 | 665 | pause, |
| 419 | 666 | /// Pop |
| 420 | 667 | pop, |
| 421 | 668 | /// Return the count of number of bits set to 1 |
| 422 | 669 | popcnt, |
| 423 | 670 | /// Pop stack into EFLAGS register |
| 424 | popfq, | |
| 671 | popf, | |
| 425 | 672 | /// Push |
| 426 | 673 | push, |
| 427 | 674 | /// Push EFLAGS register onto the stack |
| 428 | pushfq, | |
| 675 | pushf, | |
| 429 | 676 | /// Rotate left through carry |
| 430 | 677 | /// Rotate right through carry |
| 431 | 678 | 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, | |
| 432 | 691 | /// Return |
| 692 | /// Return from fast system call | |
| 693 | /// Interrupt return | |
| 694 | /// User-interrupt return | |
| 433 | 695 | ret, |
| 434 | 696 | /// Rotate left |
| 435 | 697 | /// Rotate right |
| 436 | 698 | /// Rotate right logical without affecting flags |
| 437 | 699 | ro, |
| 700 | /// Resume from system management mode | |
| 701 | rsm, | |
| 438 | 702 | /// Arithmetic shift left |
| 439 | 703 | /// Arithmetic shift right |
| 440 | 704 | /// Shift left arithmetic without affecting flags |
| 441 | 705 | sa, |
| 706 | /// Store AH into flags | |
| 707 | sahf, | |
| 442 | 708 | /// Integer subtraction with borrow |
| 443 | 709 | sbb, |
| 444 | 710 | /// Scan string |
| 445 | 711 | sca, |
| 712 | /// Send user interprocessor interrupt | |
| 713 | senduipi, | |
| 446 | 714 | /// Set byte on condition |
| 447 | 715 | set, |
| 448 | /// Store fence | |
| 449 | sfence, | |
| 450 | 716 | /// Logical shift left |
| 451 | 717 | /// Double precision shift left |
| 452 | 718 | /// Logical shift right |
| ... | ... | @@ -454,6 +720,12 @@ pub const Inst = struct { |
| 454 | 720 | /// Shift left logical without affecting flags |
| 455 | 721 | /// Shift right logical without affecting flags |
| 456 | 722 | sh, |
| 723 | /// Store interrupt descriptor table register | |
| 724 | sidt, | |
| 725 | /// Store local descriptor table register | |
| 726 | sldt, | |
| 727 | /// Store machine status word | |
| 728 | smsw, | |
| 457 | 729 | /// Subtract |
| 458 | 730 | /// Subtract packed integers |
| 459 | 731 | /// Subtract packed single-precision floating-point values |
| ... | ... | @@ -464,46 +736,128 @@ pub const Inst = struct { |
| 464 | 736 | /// Set carry flag |
| 465 | 737 | /// Set direction flag |
| 466 | 738 | /// Set interrupt flag |
| 739 | /// Store binary coded decimal integer and pop | |
| 467 | 740 | /// 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 | |
| 468 | 746 | st, |
| 469 | 747 | /// Store string |
| 470 | 748 | sto, |
| 471 | /// Syscall | |
| 472 | syscall, | |
| 749 | /// Swap GS base register | |
| 750 | swapgs, | |
| 473 | 751 | /// Test condition |
| 474 | 752 | @"test", |
| 475 | /// Count the number of trailing zero bits | |
| 476 | tzcnt, | |
| 477 | 753 | /// 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, | |
| 479 | 764 | /// Exchange and add |
| 480 | 765 | xadd, |
| 481 | 766 | /// Exchange register/memory with register |
| 482 | xchg, | |
| 767 | /// Exchange register contents | |
| 768 | xch, | |
| 483 | 769 | /// Get value of extended control register |
| 484 | 770 | xgetbv, |
| 771 | /// Table look-up translation | |
| 772 | xlat, | |
| 485 | 773 | /// Logical exclusive-or |
| 486 | 774 | /// Bitwise logical xor of packed single-precision floating-point values |
| 487 | 775 | /// Bitwise logical xor of packed double-precision floating-point values |
| 488 | 776 | xor, |
| 489 | 777 | |
| 778 | // X87 | |
| 779 | /// Compute 2^x-1 | |
| 780 | @"2xm1", | |
| 490 | 781 | /// Absolute value |
| 491 | 782 | abs, |
| 492 | 783 | /// Change sign |
| 493 | 784 | 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, | |
| 494 | 799 | /// Free floating-point register |
| 495 | 800 | 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 | |
| 498 | 806 | /// Load floating-point value |
| 499 | ld, | |
| 807 | /// Load integer | |
| 808 | /// Load constant | |
| 809 | /// Load x87 FPU control word | |
| 500 | 810 | /// 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 | |
| 507 | 861 | /// Pack with signed saturation |
| 508 | 862 | ackssw, |
| 509 | 863 | /// Pack with signed saturation |
| ... | ... | @@ -514,6 +868,7 @@ pub const Inst = struct { |
| 514 | 868 | adds, |
| 515 | 869 | /// Add packed unsigned integers with unsigned saturation |
| 516 | 870 | addus, |
| 871 | /// Logical and not | |
| 517 | 872 | /// Bitwise logical and not of packed single-precision floating-point values |
| 518 | 873 | /// Bitwise logical and not of packed double-precision floating-point values |
| 519 | 874 | andn, |
| ... | ... | @@ -521,18 +876,8 @@ pub const Inst = struct { |
| 521 | 876 | cmpeq, |
| 522 | 877 | /// Compare packed data for greater than |
| 523 | 878 | 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, | |
| 536 | 881 | /// Multiply packed signed integers and store low result |
| 537 | 882 | mull, |
| 538 | 883 | /// Multiply packed signed integers and store high result |
| ... | ... | @@ -547,12 +892,20 @@ pub const Inst = struct { |
| 547 | 892 | subs, |
| 548 | 893 | /// Subtract packed unsigned integers with unsigned saturation |
| 549 | 894 | 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, | |
| 550 | 907 | |
| 551 | /// Load MXCSR register | |
| 552 | ldmxcsr, | |
| 553 | /// Store MXCSR register state | |
| 554 | stmxcsr, | |
| 555 | ||
| 908 | // SSE | |
| 556 | 909 | /// Convert packed doubleword integers to packed single-precision floating-point values |
| 557 | 910 | /// Convert packed doubleword integers to packed double-precision floating-point values |
| 558 | 911 | cvtpi2, |
| ... | ... | @@ -567,17 +920,38 @@ pub const Inst = struct { |
| 567 | 920 | cvttps2pi, |
| 568 | 921 | /// Convert with truncation scalar single-precision floating-point value to doubleword integer |
| 569 | 922 | 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, | |
| 571 | 937 | /// Maximum of packed single-precision floating-point values |
| 572 | 938 | /// Maximum of scalar single-precision floating-point values |
| 573 | 939 | /// Maximum of packed double-precision floating-point values |
| 574 | 940 | /// Maximum of scalar double-precision floating-point values |
| 575 | 941 | max, |
| 942 | /// Maximum of packed signed integers | |
| 943 | maxs, | |
| 944 | /// Maximum of packed unsigned integers | |
| 945 | maxu, | |
| 576 | 946 | /// Minimum of packed single-precision floating-point values |
| 577 | 947 | /// Minimum of scalar single-precision floating-point values |
| 578 | 948 | /// Minimum of packed double-precision floating-point values |
| 579 | 949 | /// Minimum of scalar double-precision floating-point values |
| 580 | 950 | min, |
| 951 | /// Minimum of packed signed integers | |
| 952 | mins, | |
| 953 | /// Minimum of packed unsigned integers | |
| 954 | minu, | |
| 581 | 955 | /// Move aligned packed single-precision floating-point values |
| 582 | 956 | /// Move aligned packed double-precision floating-point values |
| 583 | 957 | mova, |
| ... | ... | @@ -591,27 +965,18 @@ pub const Inst = struct { |
| 591 | 965 | movl, |
| 592 | 966 | /// Move packed single-precision floating-point values low to high |
| 593 | 967 | 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, | |
| 594 | 972 | /// Move unaligned packed single-precision floating-point values |
| 595 | 973 | /// Move unaligned packed double-precision floating-point values |
| 596 | 974 | 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, | |
| 615 | 980 | /// Unpack and interleave high packed single-precision floating-point values |
| 616 | 981 | /// Unpack and interleave high packed double-precision floating-point values |
| 617 | 982 | unpckh, |
| ... | ... | @@ -619,6 +984,7 @@ pub const Inst = struct { |
| 619 | 984 | /// Unpack and interleave low packed double-precision floating-point values |
| 620 | 985 | unpckl, |
| 621 | 986 | |
| 987 | // SSE2 | |
| 622 | 988 | /// Convert packed doubleword integers to packed single-precision floating-point values |
| 623 | 989 | /// Convert packed doubleword integers to packed double-precision floating-point values |
| 624 | 990 | cvtdq2, |
| ... | ... | @@ -646,32 +1012,28 @@ pub const Inst = struct { |
| 646 | 1012 | cvttps2dq, |
| 647 | 1013 | /// Convert with truncation scalar double-precision floating-point value to doubleword integer |
| 648 | 1014 | 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, | |
| 654 | 1021 | /// Shuffle packed high words |
| 655 | 1022 | shufh, |
| 656 | 1023 | /// Shuffle packed low words |
| 657 | 1024 | shufl, |
| 658 | 1025 | /// Unpack high data |
| 659 | unpckhbw, | |
| 660 | /// Unpack high data | |
| 661 | unpckhdq, | |
| 662 | /// Unpack high data | |
| 663 | 1026 | unpckhqdq, |
| 664 | /// Unpack high data | |
| 665 | unpckhwd, | |
| 666 | /// Unpack low data | |
| 667 | unpcklbw, | |
| 668 | /// Unpack low data | |
| 669 | unpckldq, | |
| 670 | 1027 | /// Unpack low data |
| 671 | 1028 | unpcklqdq, |
| 672 | /// Unpack low data | |
| 673 | unpcklwd, | |
| 674 | 1029 | |
| 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, | |
| 675 | 1037 | /// Replicate double floating-point values |
| 676 | 1038 | movddup, |
| 677 | 1039 | /// Replicate single floating-point values |
| ... | ... | @@ -679,9 +1041,11 @@ pub const Inst = struct { |
| 679 | 1041 | /// Replicate single floating-point values |
| 680 | 1042 | movsldup, |
| 681 | 1043 | |
| 1044 | // SSSE3 | |
| 682 | 1045 | /// Packed align right |
| 683 | 1046 | alignr, |
| 684 | 1047 | |
| 1048 | // SSE4.1 | |
| 685 | 1049 | /// Pack with unsigned saturation |
| 686 | 1050 | ackusd, |
| 687 | 1051 | /// Blend packed single-precision floating-point values |
| ... | ... | @@ -694,6 +1058,9 @@ pub const Inst = struct { |
| 694 | 1058 | /// Variable blend packed double-precision floating-point values |
| 695 | 1059 | /// Variable blend scalar double-precision floating-point values |
| 696 | 1060 | blendv, |
| 1061 | /// Dot product of packed single-precision floating-point values | |
| 1062 | /// Dot product of packed double-precision floating-point values | |
| 1063 | dp, | |
| 697 | 1064 | /// Extract packed floating-point values |
| 698 | 1065 | /// Extract packed integer values |
| 699 | 1066 | extract, |
| ... | ... | @@ -714,14 +1081,28 @@ pub const Inst = struct { |
| 714 | 1081 | /// Round scalar double-precision floating-point value |
| 715 | 1082 | round, |
| 716 | 1083 | |
| 1084 | // SSE4.2 | |
| 1085 | /// Accumulate CRC32 value | |
| 1086 | crc32, | |
| 1087 | ||
| 1088 | // PCLMUL | |
| 717 | 1089 | /// Carry-less multiplication quadword |
| 718 | 1090 | clmulq, |
| 719 | 1091 | |
| 1092 | // AES | |
| 720 | 1093 | /// 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 | |
| 721 | 1098 | aesdec, |
| 722 | 1099 | /// Perform last round of an AES decryption flow |
| 723 | 1100 | aesdeclast, |
| 724 | 1101 | /// 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 | |
| 725 | 1106 | aesenc, |
| 726 | 1107 | /// Perform last round of an AES encryption flow |
| 727 | 1108 | aesenclast, |
| ... | ... | @@ -730,22 +1111,42 @@ pub const Inst = struct { |
| 730 | 1111 | /// AES round key generation assist |
| 731 | 1112 | aeskeygenassist, |
| 732 | 1113 | |
| 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, | |
| 733 | 1122 | /// Perform an intermediate calculation for the next four SHA256 message dwords |
| 734 | sha256msg1, | |
| 735 | 1123 | /// Perform a final calculation for the next four SHA256 message dwords |
| 736 | sha256msg2, | |
| 1124 | sha256msg, | |
| 737 | 1125 | /// 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, | |
| 740 | 1135 | /// Load with broadcast floating-point data |
| 741 | 1136 | /// Load integer and broadcast |
| 742 | 1137 | broadcast, |
| 1138 | /// Zero high bits starting with specified bit position | |
| 1139 | bzhi, | |
| 1140 | /// Count the number of trailing zero bits | |
| 1141 | tzcnt, | |
| 743 | 1142 | |
| 1143 | // F16C | |
| 744 | 1144 | /// Convert 16-bit floating-point values to single-precision floating-point values |
| 745 | 1145 | cvtph2, |
| 746 | 1146 | /// Convert single-precision floating-point values to 16-bit floating-point values |
| 747 | 1147 | cvtps2ph, |
| 748 | 1148 | |
| 1149 | // FMA | |
| 749 | 1150 | /// Fused multiply-add of packed single-precision floating-point values |
| 750 | 1151 | /// Fused multiply-add of scalar single-precision floating-point values |
| 751 | 1152 | /// Fused multiply-add of packed double-precision floating-point values |
| ... | ... | @@ -762,6 +1163,19 @@ pub const Inst = struct { |
| 762 | 1163 | /// Fused multiply-add of scalar double-precision floating-point values |
| 763 | 1164 | fmadd231, |
| 764 | 1165 | |
| 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 | ||
| 765 | 1179 | /// A pseudo instruction that requires special lowering. |
| 766 | 1180 | /// This should be the only tag in this enum that doesn't |
| 767 | 1181 | /// directly correspond to one or more instruction mnemonics. |
| ... | ... | @@ -804,11 +1218,17 @@ pub const Inst = struct { |
| 804 | 1218 | /// Uses `ri` payload with `i` index of extra data of type `Imm64`. |
| 805 | 1219 | ri_64, |
| 806 | 1220 | /// Immediate (sign-extended) operand. |
| 807 | /// Uses `imm` payload. | |
| 1221 | /// Uses `i` payload. | |
| 808 | 1222 | i_s, |
| 809 | 1223 | /// Immediate (unsigned) operand. |
| 810 | /// Uses `imm` payload. | |
| 1224 | /// Uses `i` payload. | |
| 811 | 1225 | 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, | |
| 812 | 1232 | /// Relative displacement operand. |
| 813 | 1233 | /// Uses `reloc` payload. |
| 814 | 1234 | rel, |
| ... | ... | @@ -1036,6 +1456,11 @@ pub const Inst = struct { |
| 1036 | 1456 | fixes: Fixes = ._, |
| 1037 | 1457 | i: u32, |
| 1038 | 1458 | }, |
| 1459 | ii: struct { | |
| 1460 | fixes: Fixes = ._, | |
| 1461 | i1: u16, | |
| 1462 | i2: u8, | |
| 1463 | }, | |
| 1039 | 1464 | r: struct { |
| 1040 | 1465 | fixes: Fixes = ._, |
| 1041 | 1466 | r1: Register, |
| ... | ... | @@ -1244,7 +1669,7 @@ pub const Memory = struct { |
| 1244 | 1669 | size: bits.Memory.Size, |
| 1245 | 1670 | index: Register, |
| 1246 | 1671 | scale: bits.Memory.Scale, |
| 1247 | _: u15 = undefined, | |
| 1672 | _: u14 = undefined, | |
| 1248 | 1673 | }; |
| 1249 | 1674 | |
| 1250 | 1675 | pub fn encode(mem: bits.Memory) Memory { |
src/arch/x86_64/bits.zig+24-3| ... | ... | @@ -177,7 +177,7 @@ pub const Condition = enum(u5) { |
| 177 | 177 | } |
| 178 | 178 | }; |
| 179 | 179 | |
| 180 | pub const Register = enum(u7) { | |
| 180 | pub const Register = enum(u8) { | |
| 181 | 181 | // zig fmt: off |
| 182 | 182 | rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi, |
| 183 | 183 | r8, r9, r10, r11, r12, r13, r14, r15, |
| ... | ... | @@ -207,6 +207,12 @@ pub const Register = enum(u7) { |
| 207 | 207 | |
| 208 | 208 | rip, eip, ip, |
| 209 | 209 | |
| 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 | ||
| 210 | 216 | none, |
| 211 | 217 | // zig fmt: on |
| 212 | 218 | |
| ... | ... | @@ -217,6 +223,8 @@ pub const Register = enum(u7) { |
| 217 | 223 | mmx, |
| 218 | 224 | sse, |
| 219 | 225 | ip, |
| 226 | cr, | |
| 227 | dr, | |
| 220 | 228 | }; |
| 221 | 229 | |
| 222 | 230 | pub fn class(reg: Register) Class { |
| ... | ... | @@ -235,13 +243,15 @@ pub const Register = enum(u7) { |
| 235 | 243 | |
| 236 | 244 | @intFromEnum(Register.es) ... @intFromEnum(Register.gs) => .segment, |
| 237 | 245 | @intFromEnum(Register.rip) ... @intFromEnum(Register.ip) => .ip, |
| 246 | @intFromEnum(Register.cr0) ... @intFromEnum(Register.cr15) => .cr, | |
| 247 | @intFromEnum(Register.dr0) ... @intFromEnum(Register.dr15) => .dr, | |
| 238 | 248 | |
| 239 | 249 | else => unreachable, |
| 240 | 250 | // zig fmt: on |
| 241 | 251 | }; |
| 242 | 252 | } |
| 243 | 253 | |
| 244 | pub fn id(reg: Register) u6 { | |
| 254 | pub fn id(reg: Register) u7 { | |
| 245 | 255 | const base = switch (@intFromEnum(reg)) { |
| 246 | 256 | // zig fmt: off |
| 247 | 257 | @intFromEnum(Register.rax) ... @intFromEnum(Register.r15) => @intFromEnum(Register.rax), |
| ... | ... | @@ -254,8 +264,9 @@ pub const Register = enum(u7) { |
| 254 | 264 | @intFromEnum(Register.xmm0) ... @intFromEnum(Register.xmm15) => @intFromEnum(Register.xmm0) - 16, |
| 255 | 265 | @intFromEnum(Register.mm0) ... @intFromEnum(Register.mm7) => @intFromEnum(Register.mm0) - 32, |
| 256 | 266 | @intFromEnum(Register.st0) ... @intFromEnum(Register.st7) => @intFromEnum(Register.st0) - 40, |
| 257 | ||
| 258 | 267 | @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, | |
| 259 | 270 | |
| 260 | 271 | else => unreachable, |
| 261 | 272 | // zig fmt: on |
| ... | ... | @@ -279,6 +290,9 @@ pub const Register = enum(u7) { |
| 279 | 290 | |
| 280 | 291 | @intFromEnum(Register.es) ... @intFromEnum(Register.gs) => 16, |
| 281 | 292 | |
| 293 | @intFromEnum(Register.cr0) ... @intFromEnum(Register.cr15) => 64, | |
| 294 | @intFromEnum(Register.dr0) ... @intFromEnum(Register.dr15) => 64, | |
| 295 | ||
| 282 | 296 | else => unreachable, |
| 283 | 297 | // zig fmt: on |
| 284 | 298 | }; |
| ... | ... | @@ -295,6 +309,9 @@ pub const Register = enum(u7) { |
| 295 | 309 | @intFromEnum(Register.ymm8) ... @intFromEnum(Register.ymm15) => true, |
| 296 | 310 | @intFromEnum(Register.xmm8) ... @intFromEnum(Register.xmm15) => true, |
| 297 | 311 | |
| 312 | @intFromEnum(Register.cr8) ... @intFromEnum(Register.cr15) => true, | |
| 313 | @intFromEnum(Register.dr8) ... @intFromEnum(Register.dr15) => true, | |
| 314 | ||
| 298 | 315 | else => false, |
| 299 | 316 | // zig fmt: on |
| 300 | 317 | }; |
| ... | ... | @@ -316,6 +333,9 @@ pub const Register = enum(u7) { |
| 316 | 333 | |
| 317 | 334 | @intFromEnum(Register.es) ... @intFromEnum(Register.gs) => @intFromEnum(Register.es), |
| 318 | 335 | |
| 336 | @intFromEnum(Register.cr0) ... @intFromEnum(Register.cr15) => @intFromEnum(Register.cr0), | |
| 337 | @intFromEnum(Register.dr0) ... @intFromEnum(Register.dr15) => @intFromEnum(Register.dr0), | |
| 338 | ||
| 319 | 339 | else => unreachable, |
| 320 | 340 | // zig fmt: on |
| 321 | 341 | }; |
| ... | ... | @@ -397,6 +417,7 @@ pub const Register = enum(u7) { |
| 397 | 417 | .mmx => 41 + @as(u6, reg.enc()), |
| 398 | 418 | .segment => 50 + @as(u6, reg.enc()), |
| 399 | 419 | .ip => 16, |
| 420 | .cr, .dr => unreachable, | |
| 400 | 421 | }; |
| 401 | 422 | } |
| 402 | 423 | }; |
src/arch/x86_64/encoder.zig+27-15| ... | ... | @@ -389,6 +389,7 @@ pub const Instruction = struct { |
| 389 | 389 | const enc = inst.encoding; |
| 390 | 390 | const data = enc.data; |
| 391 | 391 | |
| 392 | try inst.encodeWait(encoder); | |
| 392 | 393 | if (data.mode.isVex()) { |
| 393 | 394 | try inst.encodeVexPrefix(encoder); |
| 394 | 395 | const opc = inst.encoding.opcode(); |
| ... | ... | @@ -404,19 +405,24 @@ pub const Instruction = struct { |
| 404 | 405 | .z, .o, .zo, .oz => {}, |
| 405 | 406 | .i, .d => try encodeImm(inst.ops[0].imm, data.ops[0], encoder), |
| 406 | 407 | .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 | }, | |
| 407 | 412 | .fd => try encoder.imm64(inst.ops[1].mem.moffs.offset), |
| 408 | 413 | .td => try encoder.imm64(inst.ops[0].mem.moffs.offset), |
| 409 | 414 | else => { |
| 410 | const mem_op = switch (data.op_en) { | |
| 415 | const mem_op: Operand = switch (data.op_en) { | |
| 416 | .ia => .{ .reg = .eax }, | |
| 411 | 417 | .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], | |
| 413 | 419 | .rvm, .rvmr, .rvmi => inst.ops[2], |
| 414 | 420 | else => unreachable, |
| 415 | 421 | }; |
| 416 | 422 | switch (mem_op) { |
| 417 | 423 | .reg => |reg| { |
| 418 | 424 | const rm = switch (data.op_en) { |
| 419 | .m, .mi, .m1, .mc, .vmi => enc.modRmExt(), | |
| 425 | .ia, .m, .mi, .m1, .mc, .vm, .vmi => enc.modRmExt(), | |
| 420 | 426 | .mr, .mri, .mrc => inst.ops[1].reg.lowEnc(), |
| 421 | 427 | .rm, .rmi, .rm0, .rvm, .rvmr, .rvmi, .rmv => inst.ops[0].reg.lowEnc(), |
| 422 | 428 | .mvr => inst.ops[2].reg.lowEnc(), |
| ... | ... | @@ -426,7 +432,7 @@ pub const Instruction = struct { |
| 426 | 432 | }, |
| 427 | 433 | .mem => |mem| { |
| 428 | 434 | const op = switch (data.op_en) { |
| 429 | .m, .mi, .m1, .mc, .vmi => .none, | |
| 435 | .m, .mi, .m1, .mc, .vm, .vmi => .none, | |
| 430 | 436 | .mr, .mri, .mrc => inst.ops[1], |
| 431 | 437 | .rm, .rmi, .rm0, .rvm, .rvmr, .rvmi, .rmv => inst.ops[0], |
| 432 | 438 | .mvr => inst.ops[2], |
| ... | ... | @@ -438,6 +444,7 @@ pub const Instruction = struct { |
| 438 | 444 | } |
| 439 | 445 | |
| 440 | 446 | switch (data.op_en) { |
| 447 | .ia => try encodeImm(inst.ops[0].imm, data.ops[0], encoder), | |
| 441 | 448 | .mi => try encodeImm(inst.ops[1].imm, data.ops[1], encoder), |
| 442 | 449 | .rmi, .mri, .vmi => try encodeImm(inst.ops[2].imm, data.ops[2], encoder), |
| 443 | 450 | .rvmr => try encoder.imm8(@as(u8, inst.ops[3].reg.enc()) << 4), |
| ... | ... | @@ -460,6 +467,13 @@ pub const Instruction = struct { |
| 460 | 467 | } |
| 461 | 468 | } |
| 462 | 469 | |
| 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 | ||
| 463 | 477 | fn encodeLegacyPrefixes(inst: Instruction, encoder: anytype) !void { |
| 464 | 478 | const enc = inst.encoding; |
| 465 | 479 | const data = enc.data; |
| ... | ... | @@ -481,7 +495,7 @@ pub const Instruction = struct { |
| 481 | 495 | } |
| 482 | 496 | |
| 483 | 497 | 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, | |
| 485 | 499 | .fd => inst.ops[1].mem.base().reg, |
| 486 | 500 | .td => inst.ops[0].mem.base().reg, |
| 487 | 501 | .rm, .rmi, .rm0 => if (inst.ops[1].isSegmentRegister()) |
| ... | ... | @@ -500,7 +514,7 @@ pub const Instruction = struct { |
| 500 | 514 | } |
| 501 | 515 | else |
| 502 | 516 | null, |
| 503 | .vmi, .rvm, .rvmr, .rvmi, .mvr, .rmv => unreachable, | |
| 517 | .vm, .vmi, .rvm, .rvmr, .rvmi, .mvr, .rmv => unreachable, | |
| 504 | 518 | }; |
| 505 | 519 | if (segment_override) |seg| { |
| 506 | 520 | legacy.setSegmentOverride(seg); |
| ... | ... | @@ -517,7 +531,7 @@ pub const Instruction = struct { |
| 517 | 531 | rex.w = inst.encoding.data.mode == .long; |
| 518 | 532 | |
| 519 | 533 | switch (op_en) { |
| 520 | .z, .i, .zi, .fd, .td, .d => {}, | |
| 534 | .z, .i, .zi, .ii, .ia, .fd, .td, .d => {}, | |
| 521 | 535 | .o, .oz, .oi => rex.b = inst.ops[0].reg.isExtended(), |
| 522 | 536 | .zo => rex.b = inst.ops[1].reg.isExtended(), |
| 523 | 537 | .m, .mi, .m1, .mc, .mr, .rm, .rmi, .mri, .mrc, .rm0, .rmv => { |
| ... | ... | @@ -536,7 +550,7 @@ pub const Instruction = struct { |
| 536 | 550 | rex.b = b_x_op.isBaseExtended(); |
| 537 | 551 | rex.x = b_x_op.isIndexExtended(); |
| 538 | 552 | }, |
| 539 | .vmi, .rvm, .rvmr, .rvmi, .mvr => unreachable, | |
| 553 | .vm, .vmi, .rvm, .rvmr, .rvmi, .mvr => unreachable, | |
| 540 | 554 | } |
| 541 | 555 | |
| 542 | 556 | try encoder.rex(rex); |
| ... | ... | @@ -552,21 +566,19 @@ pub const Instruction = struct { |
| 552 | 566 | vex.w = inst.encoding.data.mode.isLong(); |
| 553 | 567 | |
| 554 | 568 | 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 => { | |
| 559 | 571 | const r_op = switch (op_en) { |
| 560 | 572 | .rm, .rmi, .rm0, .rvm, .rvmr, .rvmi, .rmv => inst.ops[0], |
| 561 | 573 | .mr, .mri, .mrc => inst.ops[1], |
| 562 | 574 | .mvr => inst.ops[2], |
| 563 | .m, .mi, .m1, .mc, .vmi => .none, | |
| 575 | .m, .mi, .m1, .mc, .vm, .vmi => .none, | |
| 564 | 576 | else => unreachable, |
| 565 | 577 | }; |
| 566 | 578 | vex.r = r_op.isBaseExtended(); |
| 567 | 579 | |
| 568 | 580 | 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], | |
| 570 | 582 | .m, .mi, .m1, .mc, .mr, .mri, .mrc, .mvr => inst.ops[0], |
| 571 | 583 | .rvm, .rvmr, .rvmi => inst.ops[2], |
| 572 | 584 | else => unreachable, |
| ... | ... | @@ -595,7 +607,7 @@ pub const Instruction = struct { |
| 595 | 607 | |
| 596 | 608 | switch (op_en) { |
| 597 | 609 | else => {}, |
| 598 | .vmi => vex.v = inst.ops[0].reg, | |
| 610 | .vm, .vmi => vex.v = inst.ops[0].reg, | |
| 599 | 611 | .rvm, .rvmr, .rvmi => vex.v = inst.ops[1].reg, |
| 600 | 612 | .rmv => vex.v = inst.ops[2].reg, |
| 601 | 613 | } |
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 |
| 13 | 13 | // zig fmt: off |
| 14 | 14 | pub const table = [_]Entry{ |
| 15 | 15 | // 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 | ||
| 16 | 26 | .{ .adc, .zi, &.{ .al, .imm8 }, &.{ 0x14 }, 0, .none, .none }, |
| 17 | 27 | .{ .adc, .zi, &.{ .ax, .imm16 }, &.{ 0x15 }, 0, .short, .none }, |
| 18 | 28 | .{ .adc, .zi, &.{ .eax, .imm32 }, &.{ 0x15 }, 0, .none, .none }, |
| ... | ... | @@ -82,6 +92,11 @@ pub const table = [_]Entry{ |
| 82 | 92 | .{ .@"and", .rm, &.{ .r32, .rm32 }, &.{ 0x23 }, 0, .none, .none }, |
| 83 | 93 | .{ .@"and", .rm, &.{ .r64, .rm64 }, &.{ 0x23 }, 0, .long, .none }, |
| 84 | 94 | |
| 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 | ||
| 85 | 100 | .{ .bsf, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0xbc }, 0, .short, .none }, |
| 86 | 101 | .{ .bsf, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0xbc }, 0, .none, .none }, |
| 87 | 102 | .{ .bsf, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0xbc }, 0, .long, .none }, |
| ... | ... | @@ -122,15 +137,12 @@ pub const table = [_]Entry{ |
| 122 | 137 | .{ .bts, .mi, &.{ .rm64, .imm8 }, &.{ 0x0f, 0xba }, 5, .long, .none }, |
| 123 | 138 | |
| 124 | 139 | .{ .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" }, | |
| 126 | 142 | |
| 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 }, | |
| 134 | 146 | |
| 135 | 147 | .{ .clac, .z, &.{}, &.{ 0x0f, 0x01, 0xca }, 0, .none, .smap }, |
| 136 | 148 | |
| ... | ... | @@ -138,14 +150,24 @@ pub const table = [_]Entry{ |
| 138 | 150 | |
| 139 | 151 | .{ .cld, .z, &.{}, &.{ 0xfc }, 0, .none, .none }, |
| 140 | 152 | |
| 153 | .{ .cldemote, .m, &.{ .m8 }, &.{ 0x0f, 0x1c }, 0, .none, .cldemote }, | |
| 154 | ||
| 141 | 155 | .{ .clflush, .m, &.{ .m8 }, &.{ 0x0f, 0xae }, 7, .none, .none }, |
| 142 | 156 | |
| 157 | .{ .clflushopt, .m, &.{ .m8 }, &.{ 0x66, 0x0f, 0xae }, 7, .none, .clflushopt }, | |
| 158 | ||
| 143 | 159 | .{ .cli, .z, &.{}, &.{ 0xfa }, 0, .none, .none }, |
| 144 | 160 | |
| 161 | .{ .clrssbsy, .m, &.{ .m64 }, &.{ 0xf3, 0x0f, 0xae }, 6, .none, .shstk }, | |
| 162 | ||
| 145 | 163 | .{ .clts, .z, &.{}, &.{ 0x0f, 0x06 }, 0, .none, .none }, |
| 146 | 164 | |
| 147 | 165 | .{ .clui, .z, &.{}, &.{ 0xf3, 0x0f, 0x01, 0xee }, 0, .none, .uintr }, |
| 148 | 166 | |
| 167 | .{ .clwb, .m, &.{ .m8 }, &.{ 0x66, 0x0f, 0xae }, 6, .none, .clwb }, | |
| 168 | ||
| 169 | .{ .cmc, .z, &.{}, &.{ 0xf5 }, 0, .none, .none }, | |
| 170 | ||
| 149 | 171 | .{ .cmova, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x47 }, 0, .short, .cmov }, |
| 150 | 172 | .{ .cmova, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x47 }, 0, .none, .cmov }, |
| 151 | 173 | .{ .cmova, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x47 }, 0, .long, .cmov }, |
| ... | ... | @@ -264,11 +286,10 @@ pub const table = [_]Entry{ |
| 264 | 286 | .{ .cmps, .z, &.{ .m16, .m16 }, &.{ 0xa7 }, 0, .short, .none }, |
| 265 | 287 | .{ .cmps, .z, &.{ .m32, .m32 }, &.{ 0xa7 }, 0, .none, .none }, |
| 266 | 288 | .{ .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 }, | |
| 272 | 293 | |
| 273 | 294 | .{ .cmpxchg, .mr, &.{ .rm8, .r8 }, &.{ 0x0f, 0xb0 }, 0, .none, .none }, |
| 274 | 295 | .{ .cmpxchg, .mr, &.{ .rm8, .r8 }, &.{ 0x0f, 0xb0 }, 0, .rex, .none }, |
| ... | ... | @@ -281,6 +302,14 @@ pub const table = [_]Entry{ |
| 281 | 302 | |
| 282 | 303 | .{ .cpuid, .z, &.{}, &.{ 0x0f, 0xa2 }, 0, .none, .none }, |
| 283 | 304 | |
| 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 | ||
| 284 | 313 | .{ .dec, .m, &.{ .rm8 }, &.{ 0xfe }, 1, .none, .none }, |
| 285 | 314 | .{ .dec, .m, &.{ .rm8 }, &.{ 0xfe }, 1, .rex, .none }, |
| 286 | 315 | .{ .dec, .m, &.{ .rm16 }, &.{ 0xff }, 1, .short, .none }, |
| ... | ... | @@ -293,26 +322,50 @@ pub const table = [_]Entry{ |
| 293 | 322 | .{ .div, .m, &.{ .rm32 }, &.{ 0xf7 }, 6, .none, .none }, |
| 294 | 323 | .{ .div, .m, &.{ .rm64 }, &.{ 0xf7 }, 6, .long, .none }, |
| 295 | 324 | |
| 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 | ||
| 296 | 342 | .{ .idiv, .m, &.{ .rm8 }, &.{ 0xf6 }, 7, .none, .none }, |
| 297 | 343 | .{ .idiv, .m, &.{ .rm8 }, &.{ 0xf6 }, 7, .rex, .none }, |
| 298 | 344 | .{ .idiv, .m, &.{ .rm16 }, &.{ 0xf7 }, 7, .short, .none }, |
| 299 | 345 | .{ .idiv, .m, &.{ .rm32 }, &.{ 0xf7 }, 7, .none, .none }, |
| 300 | 346 | .{ .idiv, .m, &.{ .rm64 }, &.{ 0xf7 }, 7, .long, .none }, |
| 301 | 347 | |
| 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 }, | |
| 307 | 353 | .{ .imul, .rm, &.{ .r16, .rm16, }, &.{ 0x0f, 0xaf }, 0, .short, .none }, |
| 308 | 354 | .{ .imul, .rm, &.{ .r32, .rm32, }, &.{ 0x0f, 0xaf }, 0, .none, .none }, |
| 309 | 355 | .{ .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 }, | |
| 316 | 369 | |
| 317 | 370 | .{ .inc, .m, &.{ .rm8 }, &.{ 0xfe }, 0, .none, .none }, |
| 318 | 371 | .{ .inc, .m, &.{ .rm8 }, &.{ 0xfe }, 0, .rex, .none }, |
| ... | ... | @@ -320,58 +373,108 @@ pub const table = [_]Entry{ |
| 320 | 373 | .{ .inc, .m, &.{ .rm32 }, &.{ 0xff }, 0, .none, .none }, |
| 321 | 374 | .{ .inc, .m, &.{ .rm64 }, &.{ 0xff }, 0, .long, .none }, |
| 322 | 375 | |
| 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 }, | |
| 356 | 436 | |
| 357 | 437 | .{ .jmp, .d, &.{ .rel32 }, &.{ 0xe9 }, 0, .none, .none }, |
| 358 | 438 | .{ .jmp, .m, &.{ .rm64 }, &.{ 0xff }, 4, .none, .none }, |
| 359 | 439 | |
| 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 | ||
| 360 | 445 | .{ .lea, .rm, &.{ .r16, .m }, &.{ 0x8d }, 0, .short, .none }, |
| 361 | 446 | .{ .lea, .rm, &.{ .r32, .m }, &.{ 0x8d }, 0, .none, .none }, |
| 362 | 447 | .{ .lea, .rm, &.{ .r64, .m }, &.{ 0x8d }, 0, .long, .none }, |
| 363 | 448 | |
| 449 | .{ .leave, .z, &.{}, &.{ 0xc9 }, 0, .none, .none }, | |
| 450 | ||
| 364 | 451 | .{ .lfence, .z, &.{}, &.{ 0x0f, 0xae, 0xe8 }, 0, .none, .none }, |
| 365 | 452 | |
| 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 | ||
| 366 | 460 | .{ .lods, .z, &.{ .m8 }, &.{ 0xac }, 0, .none, .none }, |
| 367 | 461 | .{ .lods, .z, &.{ .m16 }, &.{ 0xad }, 0, .short, .none }, |
| 368 | 462 | .{ .lods, .z, &.{ .m32 }, &.{ 0xad }, 0, .none, .none }, |
| 369 | 463 | .{ .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 }, | |
| 370 | 472 | |
| 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 }, | |
| 375 | 478 | |
| 376 | 479 | .{ .lzcnt, .rm, &.{ .r16, .rm16 }, &.{ 0xf3, 0x0f, 0xbd }, 0, .short, .lzcnt }, |
| 377 | 480 | .{ .lzcnt, .rm, &.{ .r32, .rm32 }, &.{ 0xf3, 0x0f, 0xbd }, 0, .none, .lzcnt }, |
| ... | ... | @@ -414,6 +517,16 @@ pub const table = [_]Entry{ |
| 414 | 517 | .{ .mov, .mi, &.{ .rm32, .imm32 }, &.{ 0xc7 }, 0, .none, .none }, |
| 415 | 518 | .{ .mov, .mi, &.{ .rm64, .imm32s }, &.{ 0xc7 }, 0, .long, .none }, |
| 416 | 519 | |
| 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 | ||
| 417 | 530 | .{ .movbe, .rm, &.{ .r16, .m16 }, &.{ 0x0f, 0x38, 0xf0 }, 0, .short, .movbe }, |
| 418 | 531 | .{ .movbe, .rm, &.{ .r32, .m32 }, &.{ 0x0f, 0x38, 0xf0 }, 0, .none, .movbe }, |
| 419 | 532 | .{ .movbe, .rm, &.{ .r64, .m64 }, &.{ 0x0f, 0x38, 0xf0 }, 0, .long, .movbe }, |
| ... | ... | @@ -425,11 +538,10 @@ pub const table = [_]Entry{ |
| 425 | 538 | .{ .movs, .z, &.{ .m16, .m16 }, &.{ 0xa5 }, 0, .short, .none }, |
| 426 | 539 | .{ .movs, .z, &.{ .m32, .m32 }, &.{ 0xa5 }, 0, .none, .none }, |
| 427 | 540 | .{ .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 }, | |
| 433 | 545 | |
| 434 | 546 | .{ .movsx, .rm, &.{ .r16, .rm8 }, &.{ 0x0f, 0xbe }, 0, .short, .none }, |
| 435 | 547 | .{ .movsx, .rm, &.{ .r16, .rm8 }, &.{ 0x0f, 0xbe }, 0, .rex_short, .none }, |
| ... | ... | @@ -441,8 +553,8 @@ pub const table = [_]Entry{ |
| 441 | 553 | .{ .movsx, .rm, &.{ .r64, .rm16 }, &.{ 0x0f, 0xbf }, 0, .long, .none }, |
| 442 | 554 | |
| 443 | 555 | // 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" }, | |
| 446 | 558 | |
| 447 | 559 | .{ .movzx, .rm, &.{ .r16, .rm8 }, &.{ 0x0f, 0xb6 }, 0, .short, .none }, |
| 448 | 560 | .{ .movzx, .rm, &.{ .r16, .rm8 }, &.{ 0x0f, 0xb6 }, 0, .rex_short, .none }, |
| ... | ... | @@ -496,6 +608,20 @@ pub const table = [_]Entry{ |
| 496 | 608 | .{ .@"or", .rm, &.{ .r32, .rm32 }, &.{ 0x0b }, 0, .none, .none }, |
| 497 | 609 | .{ .@"or", .rm, &.{ .r64, .rm64 }, &.{ 0x0b }, 0, .long, .none }, |
| 498 | 610 | |
| 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 | ||
| 499 | 625 | .{ .pause, .z, &.{}, &.{ 0xf3, 0x90 }, 0, .none, .none }, |
| 500 | 626 | |
| 501 | 627 | .{ .pop, .o, &.{ .r16 }, &.{ 0x58 }, 0, .short, .none }, |
| ... | ... | @@ -507,7 +633,9 @@ pub const table = [_]Entry{ |
| 507 | 633 | .{ .popcnt, .rm, &.{ .r32, .rm32 }, &.{ 0xf3, 0x0f, 0xb8 }, 0, .none, .popcnt }, |
| 508 | 634 | .{ .popcnt, .rm, &.{ .r64, .rm64 }, &.{ 0xf3, 0x0f, 0xb8 }, 0, .long, .popcnt }, |
| 509 | 635 | |
| 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" }, | |
| 511 | 639 | |
| 512 | 640 | .{ .push, .o, &.{ .r16 }, &.{ 0x50 }, 0, .short, .none }, |
| 513 | 641 | .{ .push, .o, &.{ .r64 }, &.{ 0x50 }, 0, .none, .none }, |
| ... | ... | @@ -553,6 +681,35 @@ pub const table = [_]Entry{ |
| 553 | 681 | .{ .rcr, .mi, &.{ .rm32, .imm8 }, &.{ 0xc1 }, 3, .none, .none }, |
| 554 | 682 | .{ .rcr, .mi, &.{ .rm64, .imm8 }, &.{ 0xc1 }, 3, .long, .none }, |
| 555 | 683 | |
| 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 | ||
| 556 | 713 | .{ .rol, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 0, .none, .none }, |
| 557 | 714 | .{ .rol, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 0, .rex, .none }, |
| 558 | 715 | .{ .rol, .mc, &.{ .rm8, .cl }, &.{ 0xd2 }, 0, .none, .none }, |
| ... | ... | @@ -585,6 +742,10 @@ pub const table = [_]Entry{ |
| 585 | 742 | .{ .ror, .mi, &.{ .rm32, .imm8 }, &.{ 0xc1 }, 1, .none, .none }, |
| 586 | 743 | .{ .ror, .mi, &.{ .rm64, .imm8 }, &.{ 0xc1 }, 1, .long, .none }, |
| 587 | 744 | |
| 745 | .{ .rsm, .z, &.{}, &.{ 0x0f, 0xaa }, 0, .none, .none }, | |
| 746 | ||
| 747 | .{ .sahf, .z, &.{}, &.{ 0x9e }, 0, .none, .sahf }, | |
| 748 | ||
| 588 | 749 | .{ .sal, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 4, .none, .none }, |
| 589 | 750 | .{ .sal, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 4, .rex, .none }, |
| 590 | 751 | .{ .sal, .m1, &.{ .rm16, .unity }, &.{ 0xd1 }, 4, .short, .none }, |
| ... | ... | @@ -644,11 +805,14 @@ pub const table = [_]Entry{ |
| 644 | 805 | .{ .scas, .z, &.{ .m16 }, &.{ 0xaf }, 0, .short, .none }, |
| 645 | 806 | .{ .scas, .z, &.{ .m32 }, &.{ 0xaf }, 0, .none, .none }, |
| 646 | 807 | .{ .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 }, | |
| 647 | 814 | |
| 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 }, | |
| 652 | 816 | |
| 653 | 817 | .{ .seta, .m, &.{ .rm8 }, &.{ 0x0f, 0x97 }, 0, .none, .none }, |
| 654 | 818 | .{ .seta, .m, &.{ .rm8 }, &.{ 0x0f, 0x97 }, 0, .rex, .none }, |
| ... | ... | @@ -713,6 +877,14 @@ pub const table = [_]Entry{ |
| 713 | 877 | |
| 714 | 878 | .{ .sfence, .z, &.{}, &.{ 0x0f, 0xae, 0xf8 }, 0, .none, .none }, |
| 715 | 879 | |
| 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 | ||
| 716 | 888 | .{ .shl, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 4, .none, .none }, |
| 717 | 889 | .{ .shl, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 4, .rex, .none }, |
| 718 | 890 | .{ .shl, .m1, &.{ .rm16, .unity }, &.{ 0xd1 }, 4, .short, .none }, |
| ... | ... | @@ -767,17 +939,18 @@ pub const table = [_]Entry{ |
| 767 | 939 | |
| 768 | 940 | .{ .sti, .z, &.{}, &.{ 0xfb }, 0, .none, .none }, |
| 769 | 941 | |
| 942 | .{ .str, .m, &.{ .rm16 }, &.{ 0x0f, 0x00 }, 1, .none, .none }, | |
| 943 | ||
| 770 | 944 | .{ .stui, .z, &.{}, &.{ 0xf3, 0x0f, 0x01, 0xef }, 0, .none, .uintr }, |
| 771 | 945 | |
| 772 | 946 | .{ .stos, .z, &.{ .m8 }, &.{ 0xaa }, 0, .none, .none }, |
| 773 | 947 | .{ .stos, .z, &.{ .m16 }, &.{ 0xab }, 0, .short, .none }, |
| 774 | 948 | .{ .stos, .z, &.{ .m32 }, &.{ 0xab }, 0, .none, .none }, |
| 775 | 949 | .{ .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 }, | |
| 781 | 954 | |
| 782 | 955 | .{ .sub, .zi, &.{ .al, .imm8 }, &.{ 0x2c }, 0, .none, .none }, |
| 783 | 956 | .{ .sub, .zi, &.{ .ax, .imm16 }, &.{ 0x2d }, 0, .short, .none }, |
| ... | ... | @@ -802,7 +975,17 @@ pub const table = [_]Entry{ |
| 802 | 975 | .{ .sub, .rm, &.{ .r32, .rm32 }, &.{ 0x2b }, 0, .none, .none }, |
| 803 | 976 | .{ .sub, .rm, &.{ .r64, .rm64 }, &.{ 0x2b }, 0, .long, .none }, |
| 804 | 977 | |
| 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 }, | |
| 806 | 989 | |
| 807 | 990 | .{ .@"test", .zi, &.{ .al, .imm8 }, &.{ 0xa8 }, 0, .none, .none }, |
| 808 | 991 | .{ .@"test", .zi, &.{ .ax, .imm16 }, &.{ 0xa9 }, 0, .short, .none }, |
| ... | ... | @@ -819,12 +1002,38 @@ pub const table = [_]Entry{ |
| 819 | 1002 | .{ .@"test", .mr, &.{ .rm32, .r32 }, &.{ 0x85 }, 0, .none, .none }, |
| 820 | 1003 | .{ .@"test", .mr, &.{ .rm64, .r64 }, &.{ 0x85 }, 0, .long, .none }, |
| 821 | 1004 | |
| 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 }, | |
| 825 | 1008 | |
| 1009 | .{ .ud0, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0xff }, 0, .none, .none }, | |
| 1010 | .{ .ud1, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0xb9 }, 0, .none, .none }, | |
| 826 | 1011 | .{ .ud2, .z, &.{}, &.{ 0x0f, 0x0b }, 0, .none, .none }, |
| 827 | 1012 | |
| 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 | ||
| 828 | 1037 | .{ .xadd, .mr, &.{ .rm8, .r8 }, &.{ 0x0f, 0xc0 }, 0, .none, .none }, |
| 829 | 1038 | .{ .xadd, .mr, &.{ .rm8, .r8 }, &.{ 0x0f, 0xc0 }, 0, .rex, .none }, |
| 830 | 1039 | .{ .xadd, .mr, &.{ .rm16, .r16 }, &.{ 0x0f, 0xc1 }, 0, .short, .none }, |
| ... | ... | @@ -850,6 +1059,11 @@ pub const table = [_]Entry{ |
| 850 | 1059 | |
| 851 | 1060 | .{ .xgetbv, .z, &.{}, &.{ 0x0f, 0x01, 0xd0 }, 0, .none, .none }, |
| 852 | 1061 | |
| 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 | ||
| 853 | 1067 | .{ .xor, .zi, &.{ .al, .imm8 }, &.{ 0x34 }, 0, .none, .none }, |
| 854 | 1068 | .{ .xor, .zi, &.{ .ax, .imm16 }, &.{ 0x35 }, 0, .short, .none }, |
| 855 | 1069 | .{ .xor, .zi, &.{ .eax, .imm32 }, &.{ 0x35 }, 0, .none, .none }, |
| ... | ... | @@ -874,12 +1088,96 @@ pub const table = [_]Entry{ |
| 874 | 1088 | .{ .xor, .rm, &.{ .r64, .rm64 }, &.{ 0x33 }, 0, .long, .none }, |
| 875 | 1089 | |
| 876 | 1090 | // X87 |
| 1091 | .{ .f2xm1, .z, &.{}, &.{ 0xd9, 0xf0 }, 0, .none, .x87 }, | |
| 1092 | ||
| 877 | 1093 | .{ .fabs, .z, &.{}, &.{ 0xd9, 0xe1 }, 0, .none, .x87 }, |
| 878 | 1094 | |
| 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 | ||
| 879 | 1108 | .{ .fchs, .z, &.{}, &.{ 0xd9, 0xe0 }, 0, .none, .x87 }, |
| 880 | 1109 | |
| 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 | ||
| 881 | 1159 | .{ .ffree, .o, &.{ .st }, &.{ 0xdd, 0xc0 }, 0, .none, .x87 }, |
| 882 | 1160 | |
| 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 | ||
| 883 | 1181 | .{ .fisttp, .m, &.{ .m16 }, &.{ 0xdf }, 1, .none, .x87 }, |
| 884 | 1182 | .{ .fisttp, .m, &.{ .m32 }, &.{ 0xdb }, 1, .none, .x87 }, |
| 885 | 1183 | .{ .fisttp, .m, &.{ .m64 }, &.{ 0xdd }, 1, .none, .x87 }, |
| ... | ... | @@ -889,8 +1187,52 @@ pub const table = [_]Entry{ |
| 889 | 1187 | .{ .fld, .m, &.{ .m80 }, &.{ 0xdb }, 5, .none, .x87 }, |
| 890 | 1188 | .{ .fld, .o, &.{ .st }, &.{ 0xd9, 0xc0 }, 0, .none, .x87 }, |
| 891 | 1189 | |
| 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 | ||
| 892 | 1200 | .{ .fldenv, .m, &.{ .m }, &.{ 0xd9 }, 4, .none, .x87 }, |
| 893 | 1201 | |
| 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 | ||
| 894 | 1236 | .{ .fst, .m, &.{ .m32 }, &.{ 0xd9 }, 2, .none, .x87 }, |
| 895 | 1237 | .{ .fst, .m, &.{ .m64 }, &.{ 0xdd }, 2, .none, .x87 }, |
| 896 | 1238 | .{ .fst, .o, &.{ .st }, &.{ 0xdd, 0xd0 }, 0, .none, .x87 }, |
| ... | ... | @@ -899,8 +1241,59 @@ pub const table = [_]Entry{ |
| 899 | 1241 | .{ .fstp, .m, &.{ .m80 }, &.{ 0xdb }, 7, .none, .x87 }, |
| 900 | 1242 | .{ .fstp, .o, &.{ .st }, &.{ 0xdd, 0xd8 }, 0, .none, .x87 }, |
| 901 | 1243 | |
| 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 }, | |
| 904 | 1297 | |
| 905 | 1298 | // SSE |
| 906 | 1299 | .{ .addps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x58 }, 0, .none, .sse }, |
| ... | ... | @@ -915,6 +1308,8 @@ pub const table = [_]Entry{ |
| 915 | 1308 | |
| 916 | 1309 | .{ .cmpss, .rmi, &.{ .xmm, .xmm_m32, .imm8 }, &.{ 0xf3, 0x0f, 0xc2 }, 0, .none, .sse }, |
| 917 | 1310 | |
| 1311 | .{ .comiss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0x0f, 0x2f }, 0, .none, .sse }, | |
| 1312 | ||
| 918 | 1313 | .{ .cvtpi2ps, .rm, &.{ .xmm, .mm_m64 }, &.{ 0x0f, 0x2a }, 0, .none, .sse }, |
| 919 | 1314 | |
| 920 | 1315 | .{ .cvtps2pi, .rm, &.{ .mm, .xmm_m64 }, &.{ 0x0f, 0x2d }, 0, .none, .sse }, |
| ... | ... | @@ -934,6 +1329,12 @@ pub const table = [_]Entry{ |
| 934 | 1329 | |
| 935 | 1330 | .{ .divss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5e }, 0, .none, .sse }, |
| 936 | 1331 | |
| 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 | ||
| 937 | 1338 | .{ .ldmxcsr, .m, &.{ .m32 }, &.{ 0x0f, 0xae }, 2, .none, .sse }, |
| 938 | 1339 | |
| 939 | 1340 | .{ .maxps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x5f }, 0, .none, .sse }, |
| ... | ... | @@ -1004,6 +1405,8 @@ pub const table = [_]Entry{ |
| 1004 | 1405 | |
| 1005 | 1406 | .{ .cmpsd, .rmi, &.{ .xmm, .xmm_m64, .imm8 }, &.{ 0xf2, 0x0f, 0xc2 }, 0, .none, .sse2 }, |
| 1006 | 1407 | |
| 1408 | .{ .comisd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0x66, 0x0f, 0x2f }, 0, .none, .sse2 }, | |
| 1409 | ||
| 1007 | 1410 | .{ .cvtdq2pd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf3, 0x0f, 0xe6 }, 0, .none, .sse2 }, |
| 1008 | 1411 | |
| 1009 | 1412 | .{ .cvtdq2ps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x5b }, 0, .none, .sse2 }, |
| ... | ... | @@ -1043,6 +1446,12 @@ pub const table = [_]Entry{ |
| 1043 | 1446 | |
| 1044 | 1447 | .{ .divsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x5e }, 0, .none, .sse2 }, |
| 1045 | 1448 | |
| 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 | ||
| 1046 | 1455 | .{ .maxpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x5f }, 0, .none, .sse2 }, |
| 1047 | 1456 | |
| 1048 | 1457 | .{ .maxsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x5f }, 0, .none, .sse2 }, |
| ... | ... | @@ -1203,6 +1612,16 @@ pub const table = [_]Entry{ |
| 1203 | 1612 | .{ .xorpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x57 }, 0, .none, .sse2 }, |
| 1204 | 1613 | |
| 1205 | 1614 | // 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 | ||
| 1206 | 1625 | .{ .movddup, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x12 }, 0, .none, .sse3 }, |
| 1207 | 1626 | |
| 1208 | 1627 | .{ .movshdup, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0xf3, 0x0f, 0x16 }, 0, .none, .sse3 }, |
| ... | ... | @@ -1226,20 +1645,24 @@ pub const table = [_]Entry{ |
| 1226 | 1645 | |
| 1227 | 1646 | .{ .blendps, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x0c }, 0, .none, .sse4_1 }, |
| 1228 | 1647 | |
| 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 }, | |
| 1230 | 1649 | .{ .blendvpd, .rm0, &.{ .xmm, .xmm_m128, .xmm0 }, &.{ 0x66, 0x0f, 0x38, 0x15 }, 0, .none, .sse4_1 }, |
| 1231 | 1650 | |
| 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 }, | |
| 1233 | 1652 | .{ .blendvps, .rm0, &.{ .xmm, .xmm_m128, .xmm0 }, &.{ 0x66, 0x0f, 0x38, 0x14 }, 0, .none, .sse4_1 }, |
| 1234 | 1653 | |
| 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 | ||
| 1235 | 1658 | .{ .extractps, .mri, &.{ .rm32, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x17 }, 0, .none, .sse4_1 }, |
| 1236 | 1659 | |
| 1237 | 1660 | .{ .insertps, .rmi, &.{ .xmm, .xmm_m32, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x21 }, 0, .none, .sse4_1 }, |
| 1238 | 1661 | |
| 1239 | 1662 | .{ .packusdw, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x2b }, 0, .none, .sse4_1 }, |
| 1240 | 1663 | |
| 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 }, | |
| 1243 | 1666 | |
| 1244 | 1667 | .{ .pblendw, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x0e }, 0, .none, .sse4_1 }, |
| 1245 | 1668 | |
| ... | ... | @@ -1296,6 +1719,13 @@ pub const table = [_]Entry{ |
| 1296 | 1719 | .{ .roundss, .rmi, &.{ .xmm, .xmm_m32, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x0a }, 0, .none, .sse4_1 }, |
| 1297 | 1720 | |
| 1298 | 1721 | // 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 | ||
| 1299 | 1729 | .{ .pcmpgtq, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0x37 }, 0, .none, .sse4_2 }, |
| 1300 | 1730 | |
| 1301 | 1731 | // PCLMUL |
| ... | ... | @@ -1315,14 +1745,40 @@ pub const table = [_]Entry{ |
| 1315 | 1745 | .{ .aeskeygenassist, .rmi, &.{ .xmm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0xdf }, 0, .none, .aes }, |
| 1316 | 1746 | |
| 1317 | 1747 | // 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 }, | |
| 1319 | 1749 | |
| 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 }, | |
| 1321 | 1755 | |
| 1322 | .{ .sha256rnds2, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x38, 0xcb }, 0, .none, .sha }, | |
| 1756 | .{ .sha256rnds2, .rm0, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x38, 0xcb }, 0, .none, .sha }, | |
| 1323 | 1757 | .{ .sha256rnds2, .rm0, &.{ .xmm, .xmm_m128, .xmm0 }, &.{ 0x0f, 0x38, 0xcb }, 0, .none, .sha }, |
| 1324 | 1758 | |
| 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 | ||
| 1325 | 1763 | // 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 | ||
| 1326 | 1782 | .{ .rorx, .rmi, &.{ .r32, .rm32, .imm8 }, &.{ 0xf2, 0x0f, 0x3a }, 0, .vex_lz_w0, .bmi2 }, |
| 1327 | 1783 | .{ .rorx, .rmi, &.{ .r64, .rm64, .imm8 }, &.{ 0xf2, 0x0f, 0x3a }, 0, .vex_lz_w1, .bmi2 }, |
| 1328 | 1784 | |
| ... | ... | @@ -1333,6 +1789,10 @@ pub const table = [_]Entry{ |
| 1333 | 1789 | .{ .shlx, .rmv, &.{ .r64, .rm64, .r64 }, &.{ 0x66, 0x0f, 0x38, 0xf7 }, 0, .vex_lz_w1, .bmi2 }, |
| 1334 | 1790 | .{ .shrx, .rmv, &.{ .r64, .rm64, .r64 }, &.{ 0xf2, 0x0f, 0x38, 0xf7 }, 0, .vex_lz_w1, .bmi2 }, |
| 1335 | 1791 | |
| 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 | ||
| 1336 | 1796 | .{ .vaddpd, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x58 }, 0, .vex_128_wig, .avx }, |
| 1337 | 1797 | .{ .vaddpd, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x58 }, 0, .vex_256_wig, .avx }, |
| 1338 | 1798 | |
| ... | ... | @@ -1343,6 +1803,12 @@ pub const table = [_]Entry{ |
| 1343 | 1803 | |
| 1344 | 1804 | .{ .vaddss, .rvm, &.{ .xmm, .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x58 }, 0, .vex_lig_wig, .avx }, |
| 1345 | 1805 | |
| 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 | ||
| 1346 | 1812 | .{ .vaesdec, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0xde }, 0, .vex_128_wig, .@"aes avx" }, |
| 1347 | 1813 | |
| 1348 | 1814 | .{ .vaesdeclast, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x38, 0xdf }, 0, .vex_128_wig, .@"aes avx" }, |
| ... | ... | @@ -1394,6 +1860,10 @@ pub const table = [_]Entry{ |
| 1394 | 1860 | |
| 1395 | 1861 | .{ .vcmpss, .rvmi, &.{ .xmm, .xmm, .xmm_m32, .imm8 }, &.{ 0xf3, 0x0f, 0xc2 }, 0, .vex_lig_wig, .avx }, |
| 1396 | 1862 | |
| 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 | ||
| 1397 | 1867 | .{ .vcvtdq2pd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf3, 0x0f, 0xe6 }, 0, .vex_128_wig, .avx }, |
| 1398 | 1868 | .{ .vcvtdq2pd, .rm, &.{ .ymm, .xmm_m128 }, &.{ 0xf3, 0x0f, 0xe6 }, 0, .vex_256_wig, .avx }, |
| 1399 | 1869 | |
| ... | ... | @@ -1440,6 +1910,11 @@ pub const table = [_]Entry{ |
| 1440 | 1910 | .{ .vcvttss2si, .rm, &.{ .r32, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x2c }, 0, .vex_lig_w0, .avx }, |
| 1441 | 1911 | .{ .vcvttss2si, .rm, &.{ .r64, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x2c }, 0, .vex_lig_w1, .avx }, |
| 1442 | 1912 | |
| 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 | ||
| 1443 | 1918 | .{ .vdivpd, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x5e }, 0, .vex_128_wig, .avx }, |
| 1444 | 1919 | .{ .vdivpd, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x5e }, 0, .vex_256_wig, .avx }, |
| 1445 | 1920 | |
| ... | ... | @@ -1454,10 +1929,28 @@ pub const table = [_]Entry{ |
| 1454 | 1929 | |
| 1455 | 1930 | .{ .vextractps, .mri, &.{ .rm32, .xmm, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x17 }, 0, .vex_128_wig, .avx }, |
| 1456 | 1931 | |
| 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 | ||
| 1457 | 1947 | .{ .vinsertf128, .rvmi, &.{ .ymm, .ymm, .xmm_m128, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x18 }, 0, .vex_256_w0, .avx }, |
| 1458 | 1948 | |
| 1459 | 1949 | .{ .vinsertps, .rvmi, &.{ .xmm, .xmm, .xmm_m32, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x21 }, 0, .vex_128_wig, .avx }, |
| 1460 | 1950 | |
| 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 | ||
| 1461 | 1954 | .{ .vldmxcsr, .m, &.{ .m32 }, &.{ 0x0f, 0xae }, 2, .vex_lz_wig, .avx }, |
| 1462 | 1955 | |
| 1463 | 1956 | .{ .vmaxpd, .rvm, &.{ .xmm, .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x5f }, 0, .vex_128_wig, .avx }, |
| ... | ... | @@ -1821,15 +2314,6 @@ pub const table = [_]Entry{ |
| 1821 | 2314 | // VPCLMULQDQ |
| 1822 | 2315 | .{ .vpclmulqdq, .rvmi, &.{ .ymm, .ymm, .ymm_m256, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x44 }, 0, .vex_256_wig, .vpclmulqdq }, |
| 1823 | 2316 | |
| 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 | ||
| 1833 | 2317 | // AVX2 |
| 1834 | 2318 | .{ .vbroadcastss, .rm, &.{ .xmm, .xmm }, &.{ 0x66, 0x0f, 0x38, 0x18 }, 0, .vex_128_w0, .avx2 }, |
| 1835 | 2319 | .{ .vbroadcastss, .rm, &.{ .ymm, .xmm }, &.{ 0x66, 0x0f, 0x38, 0x18 }, 0, .vex_256_w0, .avx2 }, |
| ... | ... | @@ -1992,5 +2476,46 @@ pub const table = [_]Entry{ |
| 1992 | 2476 | .{ .vpunpcklqdq, .rvm, &.{ .ymm, .ymm, .ymm_m256 }, &.{ 0x66, 0x0f, 0x6c }, 0, .vex_256_wig, .avx2 }, |
| 1993 | 2477 | |
| 1994 | 2478 | .{ .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 }, | |
| 1995 | 2520 | }; |
| 1996 | 2521 | // zig fmt: on |