authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-03-07 12:57:06+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-03-11 20:05:49+01:00
logbc43cee7756d48064be0dd87f92e24c577788eec
treec188164b61113e528e991cb73ede113e2632d6f7
parentea3b3e94aba405d4364fdb06231208467ac71f87

Get more things passing


7 files changed, 474 insertions(+), 416 deletions(-)

src/arch/x86_64/CodeGen.zig+63-98
......@@ -852,10 +852,10 @@ fn processDeath(self: *Self, inst: Air.Inst.Index) void {
852852 branch.inst_table.putAssumeCapacity(inst, .dead);
853853 switch (prev_value) {
854854 .register => |reg| {
855 self.register_manager.freeReg(reg.to64());
855 self.register_manager.freeReg(reg);
856856 },
857857 .register_overflow => |ro| {
858 self.register_manager.freeReg(ro.reg.to64());
858 self.register_manager.freeReg(ro.reg);
859859 self.eflags_inst = null;
860860 },
861861 .eflags => {
......@@ -1253,7 +1253,13 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void {
12531253 };
12541254 defer if (dst_mcv_lock) |lock| self.register_manager.unlockReg(lock);
12551255
1256 const mask = ~@as(u64, 0);
1256 const mask = switch (operand_ty.abiSize(self.target.*)) {
1257 1 => ~@as(u8, 0),
1258 2 => ~@as(u16, 0),
1259 4 => ~@as(u32, 0),
1260 8 => ~@as(u64, 0),
1261 else => unreachable,
1262 };
12571263 try self.genBinOpMir(.xor, operand_ty, dst_mcv, .{ .immediate = mask });
12581264
12591265 break :result dst_mcv;
......@@ -2777,15 +2783,9 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type
27772783 1, 2, 4 => {
27782784 // TODO this is wasteful!
27792785 // introduce new MIR tag specifically for mov [reg + 0], imm
2780 const operand = switch (abi_size) {
2781 1 => @truncate(u8, imm),
2782 2 => @truncate(u16, imm),
2783 4 => @truncate(u32, imm),
2784 else => unreachable,
2785 };
27862786 const payload = try self.addExtra(Mir.ImmPair{
27872787 .dest_off = 0,
2788 .operand = operand,
2788 .operand = @intCast(u32, imm),
27892789 });
27902790 _ = try self.addInst(.{
27912791 .tag = .mov_mem_imm,
......@@ -2896,17 +2896,10 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type
28962896 return self.fail("TODO saving imm to memory for abi_size {}", .{abi_size});
28972897 }
28982898
2899 const operand = switch (abi_size) {
2900 1 => @truncate(u8, imm),
2901 2 => @truncate(u16, imm),
2902 4 => @truncate(u32, imm),
2903 8 => @truncate(u32, imm),
2904 else => unreachable,
2905 };
29062899 const payload = try self.addExtra(Mir.ImmPair{
29072900 .dest_off = 0,
29082901 // TODO check if this logic is correct
2909 .operand = operand,
2902 .operand = @intCast(u32, imm),
29102903 });
29112904 const flags: u2 = switch (abi_size) {
29122905 1 => 0b00,
......@@ -3102,8 +3095,8 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
31023095 const shift = @intCast(u8, struct_field_offset * @sizeOf(usize));
31033096 try self.genShiftBinOpMir(.shr, Type.usize, dst_mcv.register, .{ .immediate = shift });
31043097
3105 // Mask with reg.size() - struct_field_size
3106 const max_reg_bit_width = Register.rax.size();
3098 // Mask with reg.bitSize() - struct_field_size
3099 const max_reg_bit_width = Register.rax.bitSize();
31073100 const mask_shift = @intCast(u6, (max_reg_bit_width - struct_field_ty.bitSize(self.target.*)));
31083101 const mask = (~@as(u64, 0)) >> mask_shift;
31093102
......@@ -3631,13 +3624,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu
36313624 _ = try self.addInst(.{
36323625 .tag = mir_tag,
36333626 .ops = Mir.Inst.Ops.encode(.{ .reg1 = registerAlias(dst_reg, abi_size) }),
3634 .data = .{ .imm = switch (abi_size) {
3635 1 => @truncate(u8, imm),
3636 2 => @truncate(u16, imm),
3637 4 => @truncate(u32, imm),
3638 8 => @truncate(u32, imm),
3639 else => unreachable,
3640 } },
3627 .data = .{ .imm = @intCast(u32, imm) },
36413628 });
36423629 },
36433630 .memory,
......@@ -3708,16 +3695,9 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu
37083695 8 => 0b11,
37093696 else => unreachable,
37103697 };
3711 const operand = switch (abi_size) {
3712 1 => @truncate(u8, imm),
3713 2 => @truncate(u16, imm),
3714 4 => @truncate(u32, imm),
3715 8 => @truncate(u32, imm),
3716 else => unreachable,
3717 };
37183698 const payload = try self.addExtra(Mir.ImmPair{
37193699 .dest_off = -off,
3720 .operand = operand,
3700 .operand = @intCast(u32, imm),
37213701 });
37223702 _ = try self.addInst(.{
37233703 .tag = tag,
......@@ -3791,7 +3771,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M
37913771 .reg2 = dst_reg.to32(),
37923772 .flags = 0b10,
37933773 }),
3794 .data = .{ .imm = @truncate(u32, imm) },
3774 .data = .{ .imm = @intCast(u32, imm) },
37953775 });
37963776 } else {
37973777 // TODO verify we don't spill and assign to the same register as dst_mcv
......@@ -4899,13 +4879,7 @@ fn genCondSwitchMir(self: *Self, ty: Type, condition: MCValue, case: MCValue) !u
48994879 _ = try self.addInst(.{
49004880 .tag = .xor,
49014881 .ops = Mir.Inst.Ops.encode(.{ .reg1 = registerAlias(cond_reg, abi_size) }),
4902 .data = .{ .imm = switch (abi_size) {
4903 1 => @truncate(u8, imm),
4904 2 => @truncate(u16, imm),
4905 4 => @truncate(u32, imm),
4906 8 => @truncate(u32, imm),
4907 else => unreachable,
4908 } },
4882 .data = .{ .imm = @intCast(u32, imm) },
49094883 });
49104884 },
49114885 .register => |reg| {
......@@ -5416,12 +5390,6 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE
54165390 // We have a positive stack offset value but we want a twos complement negative
54175391 // offset from rbp, which is at the top of the stack frame.
54185392 // mov [rbp+offset], immediate
5419 const operand = switch (abi_size) {
5420 1 => @truncate(u8, imm),
5421 2 => @truncate(u16, imm),
5422 4 => @truncate(u32, imm),
5423 else => unreachable,
5424 };
54255393 const flags: u2 = switch (abi_size) {
54265394 1 => 0b00,
54275395 2 => 0b01,
......@@ -5430,7 +5398,7 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE
54305398 };
54315399 const payload = try self.addExtra(Mir.ImmPair{
54325400 .dest_off = -stack_offset,
5433 .operand = operand,
5401 .operand = @intCast(u32, imm),
54345402 });
54355403 _ = try self.addInst(.{
54365404 .tag = .mov_mem_imm,
......@@ -5575,7 +5543,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl
55755543 assert(ty.isError());
55765544 const payload = try self.addExtra(Mir.ImmPair{
55775545 .dest_off = -stack_offset,
5578 .operand = @truncate(u8, x_big),
5546 .operand = @intCast(u32, x_big),
55795547 });
55805548 _ = try self.addInst(.{
55815549 .tag = .mov_mem_imm,
......@@ -5587,15 +5555,9 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl
55875555 });
55885556 },
55895557 1, 2, 4 => {
5590 const operand = switch (abi_size) {
5591 1 => @truncate(u8, x_big),
5592 2 => @truncate(u16, x_big),
5593 4 => @truncate(u32, x_big),
5594 else => unreachable,
5595 };
55965558 const payload = try self.addExtra(Mir.ImmPair{
55975559 .dest_off = -stack_offset,
5598 .operand = operand,
5560 .operand = @intCast(u32, x_big),
55995561 });
56005562 _ = try self.addInst(.{
56015563 .tag = .mov_mem_imm,
......@@ -5724,7 +5686,7 @@ fn genInlineMemcpyRegisterRegister(
57245686 src_reg: Register,
57255687 offset: i32,
57265688) InnerError!void {
5727 assert(dst_reg.size() == 64);
5689 assert(dst_reg.bitSize() == 64);
57285690
57295691 const dst_reg_lock = self.register_manager.lockReg(dst_reg);
57305692 defer if (dst_reg_lock) |lock| self.register_manager.unlockReg(lock);
......@@ -5823,7 +5785,7 @@ fn genInlineMemcpy(
58235785 _ = try self.addInst(.{
58245786 .tag = .mov,
58255787 .ops = Mir.Inst.Ops.encode(.{
5826 .reg1 = registerAlias(dst_addr_reg, @divExact(reg.size(), 8)),
5788 .reg1 = registerAlias(dst_addr_reg, @intCast(u32, @divExact(reg.bitSize(), 8))),
58275789 .reg2 = reg,
58285790 }),
58295791 .data = undefined,
......@@ -5852,7 +5814,7 @@ fn genInlineMemcpy(
58525814 _ = try self.addInst(.{
58535815 .tag = .mov,
58545816 .ops = Mir.Inst.Ops.encode(.{
5855 .reg1 = registerAlias(src_addr_reg, @divExact(reg.size(), 8)),
5817 .reg1 = registerAlias(src_addr_reg, @intCast(u32, @divExact(reg.bitSize(), 8))),
58565818 .reg2 = reg,
58575819 }),
58585820 .data = undefined,
......@@ -5976,7 +5938,7 @@ fn genInlineMemset(
59765938 _ = try self.addInst(.{
59775939 .tag = .mov,
59785940 .ops = Mir.Inst.Ops.encode(.{
5979 .reg1 = registerAlias(addr_reg, @divExact(reg.size(), 8)),
5941 .reg1 = registerAlias(addr_reg, @intCast(u32, @divExact(reg.bitSize(), 8))),
59805942 .reg2 = reg,
59815943 }),
59825944 .data = undefined,
......@@ -5994,8 +5956,11 @@ fn genInlineMemset(
59945956 // cmp index_reg, -1
59955957 const loop_start = try self.addInst(.{
59965958 .tag = .cmp,
5997 .ops = Mir.Inst.Ops.encode(.{ .reg1 = index_reg }),
5998 .data = .{ .imm = @bitCast(u8, @as(i8, -1)) },
5959 .ops = Mir.Inst.Ops.encode(.{
5960 .reg1 = index_reg,
5961 .flags = 0b11,
5962 }),
5963 .data = .{ .imm_s = -1 },
59995964 });
60005965
60015966 // je end
......@@ -6016,8 +5981,14 @@ fn genInlineMemset(
60165981 // mov byte ptr [rbp + index_reg + stack_offset], imm
60175982 _ = try self.addInst(.{
60185983 .tag = .mov_mem_index_imm,
6019 .ops = Mir.Inst.Ops.encode(.{ .reg1 = addr_reg }),
6020 .data = .{ .payload = try self.addExtra(Mir.IndexRegisterDispImm.encode(index_reg, 0, @truncate(u32, x))) },
5984 .ops = Mir.Inst.Ops.encode(.{
5985 .reg1 = addr_reg,
5986 }),
5987 .data = .{ .payload = try self.addExtra(Mir.IndexRegisterDispImm.encode(
5988 index_reg,
5989 0,
5990 @intCast(u32, x),
5991 )) },
60215992 });
60225993 },
60235994 else => return self.fail("TODO inline memset for value of type {}", .{value}),
......@@ -6064,7 +6035,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
60646035 if (!self.wantSafety())
60656036 return; // The already existing value will do just fine.
60666037 // Write the debug undefined value.
6067 switch (registerAlias(reg, abi_size).size()) {
6038 switch (registerAlias(reg, abi_size).bitSize()) {
60686039 8 => return self.genSetReg(ty, reg, .{ .immediate = 0xaa }),
60696040 16 => return self.genSetReg(ty, reg, .{ .immediate = 0xaaaa }),
60706041 32 => return self.genSetReg(ty, reg, .{ .immediate = 0xaaaaaaaa }),
......@@ -6100,13 +6071,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
61006071 _ = try self.addInst(.{
61016072 .tag = .mov,
61026073 .ops = Mir.Inst.Ops.encode(.{ .reg1 = registerAlias(reg, abi_size) }),
6103 .data = .{ .imm = switch (abi_size) {
6104 1 => @truncate(u8, x),
6105 2 => @truncate(u16, x),
6106 4 => @truncate(u32, x),
6107 8 => @truncate(u32, x),
6108 else => unreachable,
6109 } },
6074 .data = .{ .imm = @intCast(u32, x) },
61106075 });
61116076 return;
61126077 }
......@@ -6273,13 +6238,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
62736238 .reg1 = registerAlias(reg, abi_size),
62746239 .flags = 0b01,
62756240 }),
6276 .data = .{ .imm = switch (abi_size) {
6277 1 => @truncate(u8, x),
6278 2 => @truncate(u16, x),
6279 4 => @truncate(u32, x),
6280 8 => @truncate(u32, x),
6281 else => unreachable,
6282 } },
6241 .data = .{ .disp = @intCast(i32, x) },
62836242 });
62846243 } else {
62856244 // If this is RAX, we can use a direct load.
......@@ -6949,7 +6908,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
69496908 if (ret_ty_size == 0) {
69506909 assert(ret_ty.isError());
69516910 result.return_value = .{ .immediate = 0 };
6952 } else if (ret_ty_size <= 8) {
6911 } else if (ret_ty_size <= 8 and !ret_ty.isRuntimeFloat()) {
69536912 const aliased_reg = registerAlias(abi.getCAbiIntReturnRegs(self.target.*)[0], ret_ty_size);
69546913 result.return_value = .{ .register = aliased_reg };
69556914 } else {
......@@ -7024,28 +6983,34 @@ fn parseRegName(name: []const u8) ?Register {
70246983
70256984/// Returns register wide enough to hold at least `size_bytes`.
70266985fn registerAlias(reg: Register, size_bytes: u32) Register {
7027 if (size_bytes == 0) {
7028 unreachable; // should be comptime-known
7029 } else if (size_bytes <= 1) {
7030 return reg.to8();
7031 } else if (size_bytes <= 2) {
7032 return reg.to16();
7033 } else if (size_bytes <= 4) {
7034 return reg.to32();
7035 } else if (size_bytes <= 8) {
7036 return reg.to64();
7037 } else if (size_bytes <= 16) {
7038 return reg.to128();
7039 } else if (size_bytes <= 32) {
7040 return reg.to256();
7041 } else unreachable;
6986 return switch (reg.class()) {
6987 .general_purpose => if (size_bytes == 0)
6988 unreachable // should be comptime-known
6989 else if (size_bytes <= 1)
6990 reg.to8()
6991 else if (size_bytes <= 2)
6992 reg.to16()
6993 else if (size_bytes <= 4)
6994 reg.to32()
6995 else if (size_bytes <= 8)
6996 reg.to64()
6997 else
6998 unreachable,
6999 .floating_point => if (size_bytes <= 16)
7000 reg.to128()
7001 else if (size_bytes <= 32)
7002 reg.to256()
7003 else
7004 unreachable,
7005 .segment => unreachable,
7006 };
70427007}
70437008
70447009/// Truncates the value in the register in place.
70457010/// Clobbers any remaining bits.
70467011fn truncateRegister(self: *Self, ty: Type, reg: Register) !void {
70477012 const int_info = ty.intInfo(self.target.*);
7048 const max_reg_bit_width = Register.rax.size();
7013 const max_reg_bit_width = Register.rax.bitSize();
70497014 switch (int_info.signedness) {
70507015 .signed => {
70517016 const shift = @intCast(u6, max_reg_bit_width - int_info.bits);
src/arch/x86_64/Emit.zig+39-35
......@@ -21,6 +21,7 @@ const CodeGen = @import("CodeGen.zig");
2121const DebugInfoOutput = @import("../../codegen.zig").DebugInfoOutput;
2222const Encoder = bits.Encoder;
2323const ErrorMsg = Module.ErrorMsg;
24const Immediate = bits.Immediate;
2425const Instruction = encoder.Instruction;
2526const MCValue = @import("CodeGen.zig").MCValue;
2627const Memory = bits.Memory;
......@@ -283,7 +284,7 @@ fn mirPushPop(emit: *Emit, mnemonic: Instruction.Mnemonic, inst: Mir.Inst.Index)
283284 0b10 => {
284285 const imm = emit.mir.instructions.items(.data)[inst].imm;
285286 return emit.encode(.push, .{
286 .op1 = .{ .imm = imm },
287 .op1 = .{ .imm = Immediate.u(imm) },
287288 });
288289 },
289290 0b11 => unreachable,
......@@ -327,9 +328,7 @@ fn mirJmpCall(emit: *Emit, mnemonic: Instruction.Mnemonic, inst: Mir.Inst.Index)
327328 const target = emit.mir.instructions.items(.data)[inst].inst;
328329 const source = emit.code.items.len;
329330 try emit.encode(mnemonic, .{
330 .op1 = .{
331 .imm = 0,
332 },
331 .op1 = .{ .imm = Immediate.s(0) },
333332 });
334333 try emit.relocs.append(emit.bin_file.allocator, .{
335334 .source = source,
......@@ -400,7 +399,7 @@ fn mirCondJmp(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
400399 };
401400 const source = emit.code.items.len;
402401 try emit.encode(mnemonic, .{
403 .op1 = .{ .imm = 0 },
402 .op1 = .{ .imm = Immediate.s(0) },
404403 });
405404 try emit.relocs.append(emit.bin_file.allocator, .{
406405 .source = source,
......@@ -521,7 +520,7 @@ fn mirTest(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
521520 const imm = emit.mir.instructions.items(.data)[inst].imm;
522521 return emit.encode(.@"test", .{
523522 .op1 = .{ .reg = ops.reg1 },
524 .op2 = .{ .imm = imm },
523 .op2 = .{ .imm = Immediate.u(imm) },
525524 });
526525 }
527526 return emit.encode(.@"test", .{
......@@ -543,7 +542,7 @@ fn mirRet(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
543542 0b10 => {
544543 const imm = emit.mir.instructions.items(.data)[inst].imm;
545544 return emit.encode(.ret, .{
546 .op1 = .{ .imm = imm },
545 .op1 = .{ .imm = Immediate.u(imm) },
547546 });
548547 },
549548 0b11 => {
......@@ -560,7 +559,7 @@ fn mirArith(emit: *Emit, mnemonic: Instruction.Mnemonic, inst: Mir.Inst.Index) I
560559 const imm = emit.mir.instructions.items(.data)[inst].imm;
561560 return emit.encode(mnemonic, .{
562561 .op1 = .{ .reg = ops.reg1 },
563 .op2 = .{ .imm = imm },
562 .op2 = .{ .imm = Immediate.u(imm) },
564563 });
565564 }
566565 return emit.encode(mnemonic, .{
......@@ -573,7 +572,7 @@ fn mirArith(emit: *Emit, mnemonic: Instruction.Mnemonic, inst: Mir.Inst.Index) I
573572 const base: ?Register = if (ops.reg2 != .none) ops.reg2 else null;
574573 return emit.encode(mnemonic, .{
575574 .op1 = .{ .reg = ops.reg1 },
576 .op2 = .{ .mem = Memory.sib(Memory.PtrSize.fromSize(ops.reg1.size()), .{
575 .op2 = .{ .mem = Memory.sib(Memory.PtrSize.fromBitSize(ops.reg1.bitSize()), .{
577576 .base = base,
578577 .disp = disp,
579578 }) },
......@@ -585,7 +584,7 @@ fn mirArith(emit: *Emit, mnemonic: Instruction.Mnemonic, inst: Mir.Inst.Index) I
585584 }
586585 const disp = emit.mir.instructions.items(.data)[inst].disp;
587586 return emit.encode(mnemonic, .{
588 .op1 = .{ .mem = Memory.sib(Memory.PtrSize.fromSize(ops.reg2.size()), .{
587 .op1 = .{ .mem = Memory.sib(Memory.PtrSize.fromBitSize(ops.reg2.bitSize()), .{
589588 .base = ops.reg1,
590589 .disp = disp,
591590 }) },
......@@ -593,7 +592,11 @@ fn mirArith(emit: *Emit, mnemonic: Instruction.Mnemonic, inst: Mir.Inst.Index) I
593592 });
594593 },
595594 0b11 => {
596 return emit.fail("TODO unused variant: mov reg1, reg2, 0b11", .{});
595 const imm_s = emit.mir.instructions.items(.data)[inst].imm_s;
596 return emit.encode(mnemonic, .{
597 .op1 = .{ .reg = ops.reg1 },
598 .op2 = .{ .imm = Immediate.s(imm_s) },
599 });
597600 },
598601 }
599602}
......@@ -614,7 +617,7 @@ fn mirArithMemImm(emit: *Emit, mnemonic: Instruction.Mnemonic, inst: Mir.Inst.In
614617 .disp = imm_pair.dest_off,
615618 .base = ops.reg1,
616619 }) },
617 .op2 = .{ .imm = imm_pair.operand },
620 .op2 = .{ .imm = Immediate.u(imm_pair.operand) },
618621 });
619622}
620623
......@@ -629,7 +632,7 @@ fn mirArithScaleSrc(emit: *Emit, mnemonic: Instruction.Mnemonic, inst: Mir.Inst.
629632 };
630633 return emit.encode(mnemonic, .{
631634 .op1 = .{ .reg = ops.reg1 },
632 .op2 = .{ .mem = Memory.sib(Memory.PtrSize.fromSize(ops.reg1.size()), .{
635 .op2 = .{ .mem = Memory.sib(Memory.PtrSize.fromBitSize(ops.reg1.bitSize()), .{
633636 .base = ops.reg2,
634637 .scale_index = scale_index,
635638 .disp = index_reg_disp.disp,
......@@ -648,7 +651,7 @@ fn mirArithScaleDst(emit: *Emit, mnemonic: Instruction.Mnemonic, inst: Mir.Inst.
648651 };
649652 assert(ops.reg2 != .none);
650653 return emit.encode(mnemonic, .{
651 .op1 = .{ .mem = Memory.sib(Memory.PtrSize.fromSize(ops.reg2.size()), .{
654 .op1 = .{ .mem = Memory.sib(Memory.PtrSize.fromBitSize(ops.reg2.bitSize()), .{
652655 .base = ops.reg1,
653656 .scale_index = scale_index,
654657 .disp = index_reg_disp.disp,
......@@ -672,7 +675,7 @@ fn mirArithScaleImm(emit: *Emit, mnemonic: Instruction.Mnemonic, inst: Mir.Inst.
672675 .disp = index_reg_disp_imm.disp,
673676 .scale_index = scale_index,
674677 }) },
675 .op2 = .{ .imm = index_reg_disp_imm.imm },
678 .op2 = .{ .imm = Immediate.u(index_reg_disp_imm.imm) },
676679 });
677680}
678681
......@@ -697,7 +700,7 @@ fn mirArithMemIndexImm(emit: *Emit, mnemonic: Instruction.Mnemonic, inst: Mir.In
697700 .base = ops.reg1,
698701 .scale_index = scale_index,
699702 }) },
700 .op2 = .{ .imm = index_reg_disp_imm.imm },
703 .op2 = .{ .imm = Immediate.u(index_reg_disp_imm.imm) },
701704 });
702705}
703706
......@@ -708,7 +711,7 @@ fn mirMovSignExtend(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
708711 const disp = if (ops.flags != 0b00) emit.mir.instructions.items(.data)[inst].disp else undefined;
709712 switch (ops.flags) {
710713 0b00 => {
711 const mnemonic: Instruction.Mnemonic = if (ops.reg2.size() == 32) .movsxd else .movsx;
714 const mnemonic: Instruction.Mnemonic = if (ops.reg2.bitSize() == 32) .movsxd else .movsx;
712715 return emit.encode(mnemonic, .{
713716 .op1 = .{ .reg = ops.reg1 },
714717 .op2 = .{ .reg = ops.reg2 },
......@@ -718,14 +721,15 @@ fn mirMovSignExtend(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
718721 const ptr_size: Memory.PtrSize = switch (ops.flags) {
719722 0b01 => .byte,
720723 0b10 => .word,
721 0b11 => .qword,
724 0b11 => .dword,
722725 else => unreachable,
723726 };
724 return emit.encode(.movsx, .{
727 const mnemonic: Instruction.Mnemonic = if (ops.flags == 0b11) .movsxd else .movsx;
728 return emit.encode(mnemonic, .{
725729 .op1 = .{ .reg = ops.reg1 },
726730 .op2 = .{ .mem = Memory.sib(ptr_size, .{
727 .disp = disp,
728731 .base = ops.reg2,
732 .disp = disp,
729733 }) },
730734 });
731735 },
......@@ -770,19 +774,19 @@ fn mirMovabs(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
770774 const ops = emit.mir.instructions.items(.ops)[inst].decode();
771775 switch (ops.flags) {
772776 0b00 => {
773 const imm: u64 = if (ops.reg1.size() == 64) blk: {
777 const imm: u64 = if (ops.reg1.bitSize() == 64) blk: {
774778 const payload = emit.mir.instructions.items(.data)[inst].payload;
775779 const imm = emit.mir.extraData(Mir.Imm64, payload).data;
776780 break :blk imm.decode();
777781 } else emit.mir.instructions.items(.data)[inst].imm;
778782 return emit.encode(.mov, .{
779783 .op1 = .{ .reg = ops.reg1 },
780 .op2 = .{ .imm = imm },
784 .op2 = .{ .imm = Immediate.u(imm) },
781785 });
782786 },
783787 0b01 => {
784788 if (ops.reg1 == .none) {
785 const imm: u64 = if (ops.reg2.size() == 64) blk: {
789 const imm: u64 = if (ops.reg2.bitSize() == 64) blk: {
786790 const payload = emit.mir.instructions.items(.data)[inst].payload;
787791 const imm = emit.mir.extraData(Mir.Imm64, payload).data;
788792 break :blk imm.decode();
......@@ -792,7 +796,7 @@ fn mirMovabs(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
792796 .op2 = .{ .reg = .rax },
793797 });
794798 }
795 const imm: u64 = if (ops.reg1.size() == 64) blk: {
799 const imm: u64 = if (ops.reg1.bitSize() == 64) blk: {
796800 const payload = emit.mir.instructions.items(.data)[inst].payload;
797801 const imm = emit.mir.extraData(Mir.Imm64, payload).data;
798802 break :blk imm.decode();
......@@ -847,7 +851,7 @@ fn mirShift(emit: *Emit, mnemonic: Instruction.Mnemonic, inst: Mir.Inst.Index) I
847851 0b00 => {
848852 return emit.encode(mnemonic, .{
849853 .op1 = .{ .reg = ops.reg1 },
850 .op2 = .{ .imm = 1 },
854 .op2 = .{ .imm = Immediate.u(1) },
851855 });
852856 },
853857 0b01 => {
......@@ -860,7 +864,7 @@ fn mirShift(emit: *Emit, mnemonic: Instruction.Mnemonic, inst: Mir.Inst.Index) I
860864 const imm = @truncate(u8, emit.mir.instructions.items(.data)[inst].imm);
861865 return emit.encode(mnemonic, .{
862866 .op1 = .{ .reg = ops.reg1 },
863 .op2 = .{ .imm = imm },
867 .op2 = .{ .imm = Immediate.u(imm) },
864868 });
865869 },
866870 0b11 => {
......@@ -920,7 +924,7 @@ fn mirIMulComplex(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
920924 return emit.encode(.imul, .{
921925 .op1 = .{ .reg = ops.reg1 },
922926 .op2 = .{ .reg = ops.reg2 },
923 .op3 = .{ .imm = imm },
927 .op3 = .{ .imm = Immediate.u(imm) },
924928 });
925929 },
926930 0b11 => {
......@@ -932,7 +936,7 @@ fn mirIMulComplex(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
932936 .base = ops.reg2,
933937 .disp = imm_pair.dest_off,
934938 }) },
935 .op3 = .{ .imm = imm_pair.operand },
939 .op3 = .{ .imm = Immediate.u(imm_pair.operand) },
936940 });
937941 },
938942 }
......@@ -959,7 +963,7 @@ fn mirLea(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
959963 const src_reg: ?Register = if (ops.reg2 != .none) ops.reg2 else null;
960964 return emit.encode(.lea, .{
961965 .op1 = .{ .reg = ops.reg1 },
962 .op2 = .{ .mem = Memory.sib(Memory.PtrSize.fromSize(ops.reg1.size()), .{
966 .op2 = .{ .mem = Memory.sib(Memory.PtrSize.fromBitSize(ops.reg1.bitSize()), .{
963967 .base = src_reg,
964968 .disp = disp,
965969 }) },
......@@ -969,7 +973,7 @@ fn mirLea(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
969973 const start_offset = emit.code.items.len;
970974 try emit.encode(.lea, .{
971975 .op1 = .{ .reg = ops.reg1 },
972 .op2 = .{ .mem = Memory.rip(Memory.PtrSize.fromSize(ops.reg1.size()), 0) },
976 .op2 = .{ .mem = Memory.rip(Memory.PtrSize.fromBitSize(ops.reg1.bitSize()), 0) },
973977 });
974978 const end_offset = emit.code.items.len;
975979 // Backpatch the displacement
......@@ -988,7 +992,7 @@ fn mirLea(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
988992 };
989993 return emit.encode(.lea, .{
990994 .op1 = .{ .reg = ops.reg1 },
991 .op2 = .{ .mem = Memory.sib(Memory.PtrSize.fromSize(ops.reg1.size()), .{
995 .op2 = .{ .mem = Memory.sib(Memory.PtrSize.fromBitSize(ops.reg1.bitSize()), .{
992996 .base = src_reg,
993997 .scale_index = scale_index,
994998 .disp = index_reg_disp.disp,
......@@ -1012,7 +1016,7 @@ fn mirLeaPic(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
10121016
10131017 try emit.encode(.lea, .{
10141018 .op1 = .{ .reg = ops.reg1 },
1015 .op2 = .{ .mem = Memory.rip(Memory.PtrSize.fromSize(ops.reg1.size()), 0) },
1019 .op2 = .{ .mem = Memory.rip(Memory.PtrSize.fromBitSize(ops.reg1.bitSize()), 0) },
10161020 });
10171021
10181022 const end_offset = emit.code.items.len;
......@@ -1065,7 +1069,7 @@ fn mirMovFloat(emit: *Emit, mnemonic: Instruction.Mnemonic, inst: Mir.Inst.Index
10651069 const disp = emit.mir.instructions.items(.data)[inst].disp;
10661070 return emit.encode(mnemonic, .{
10671071 .op1 = .{ .reg = ops.reg1 },
1068 .op2 = .{ .mem = Memory.sib(Memory.PtrSize.fromSize(ops.reg2.size()), .{
1072 .op2 = .{ .mem = Memory.sib(Memory.PtrSize.fromBitSize(ops.reg2.bitSize()), .{
10691073 .base = ops.reg2,
10701074 .disp = disp,
10711075 }) },
......@@ -1074,7 +1078,7 @@ fn mirMovFloat(emit: *Emit, mnemonic: Instruction.Mnemonic, inst: Mir.Inst.Index
10741078 0b01 => {
10751079 const disp = emit.mir.instructions.items(.data)[inst].disp;
10761080 return emit.encode(mnemonic, .{
1077 .op1 = .{ .mem = Memory.sib(Memory.PtrSize.fromSize(ops.reg1.size()), .{
1081 .op1 = .{ .mem = Memory.sib(Memory.PtrSize.fromBitSize(ops.reg1.bitSize()), .{
10781082 .base = ops.reg1,
10791083 .disp = disp,
10801084 }) },
......@@ -1127,7 +1131,7 @@ fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
11271131 const offset = blk: {
11281132 // callq
11291133 try emit.encode(.call, .{
1130 .op1 = .{ .imm = 0 },
1134 .op1 = .{ .imm = Immediate.s(0) },
11311135 });
11321136 break :blk @intCast(u32, emit.code.items.len) - 4;
11331137 };
src/arch/x86_64/Encoding.zig+58-31
......@@ -144,20 +144,20 @@ pub fn findByOpcode(opc: []const u8, prefixes: struct {
144144 // rex.W mov dil, 0x1
145145 // Here, rex.W is not needed.
146146 const rex_w_allowed = blk: {
147 const bit_size = enc.operandSize();
147 const bit_size = enc.operandBitSize();
148148 break :blk bit_size == 64 or bit_size == 8;
149149 };
150150 if (rex_w_allowed) return enc;
151151 },
152152 }
153153 } else if (prefixes.legacy.prefix_66) {
154 switch (enc.operandSize()) {
154 switch (enc.operandBitSize()) {
155155 16 => return enc,
156156 else => {},
157157 }
158158 } else {
159159 if (enc.mode == .none) {
160 switch (enc.operandSize()) {
160 switch (enc.operandBitSize()) {
161161 16 => {},
162162 else => return enc,
163163 }
......@@ -187,17 +187,17 @@ pub fn modRmExt(encoding: Encoding) u3 {
187187 };
188188}
189189
190pub fn operandSize(encoding: Encoding) u32 {
190pub fn operandBitSize(encoding: Encoding) u64 {
191191 if (encoding.mode == .long) return 64;
192 const bit_size: u32 = switch (encoding.op_en) {
192 const bit_size: u64 = switch (encoding.op_en) {
193193 .np => switch (encoding.op1) {
194194 .o16 => 16,
195195 .o32 => 32,
196196 .o64 => 64,
197197 else => 32,
198198 },
199 .td => encoding.op2.size(),
200 else => encoding.op1.size(),
199 .td => encoding.op2.bitSize(),
200 else => encoding.op1.bitSize(),
201201 };
202202 return bit_size;
203203}
......@@ -244,9 +244,9 @@ pub fn format(
244244 else => unreachable,
245245 };
246246 const tag = switch (op) {
247 .imm8 => "ib",
248 .imm16 => "iw",
249 .imm32 => "id",
247 .imm8, .imm8s => "ib",
248 .imm16, .imm16s => "iw",
249 .imm32, .imm32s => "id",
250250 .imm64 => "io",
251251 .rel8 => "cb",
252252 .rel16 => "cw",
......@@ -330,6 +330,7 @@ pub const Op = enum {
330330 o16, o32, o64,
331331 unity,
332332 imm8, imm16, imm32, imm64,
333 imm8s, imm16s, imm32s,
333334 al, ax, eax, rax,
334335 cl,
335336 r8, r16, r32, r64,
......@@ -349,7 +350,7 @@ pub const Op = enum {
349350 .reg => |reg| {
350351 switch (reg.class()) {
351352 .segment => return .sreg,
352 .floating_point => return switch (reg.size()) {
353 .floating_point => return switch (reg.bitSize()) {
353354 128 => .xmm,
354355 else => unreachable,
355356 },
......@@ -362,7 +363,7 @@ pub const Op = enum {
362363 else => unreachable,
363364 };
364365 if (reg == .cl) return .cl;
365 return switch (reg.size()) {
366 return switch (reg.bitSize()) {
366367 8 => .r8,
367368 16 => .r16,
368369 32 => .r32,
......@@ -376,7 +377,7 @@ pub const Op = enum {
376377 .mem => |mem| switch (mem) {
377378 .moffs => return .moffs,
378379 .sib, .rip => {
379 const bit_size = mem.size();
380 const bit_size = mem.bitSize();
380381 return switch (bit_size) {
381382 8 => .m8,
382383 16 => .m16,
......@@ -389,21 +390,34 @@ pub const Op = enum {
389390 },
390391
391392 .imm => |imm| {
392 if (imm == 1) return .unity;
393 if (math.cast(u8, imm)) |_| return .imm8;
394 if (math.cast(u16, imm)) |_| return .imm16;
395 if (math.cast(u32, imm)) |_| return .imm32;
396 return .imm64;
393 switch (imm) {
394 .signed => |x| {
395 if (x == 1) return .unity;
396 if (math.cast(i8, x)) |_| return .imm8s;
397 if (math.cast(i16, x)) |_| return .imm16s;
398 return .imm32s;
399 },
400 .unsigned => |x| {
401 if (x == 1) return .unity;
402 if (math.cast(i8, x)) |_| return .imm8s;
403 if (math.cast(u8, x)) |_| return .imm8;
404 if (math.cast(i16, x)) |_| return .imm16s;
405 if (math.cast(u16, x)) |_| return .imm16;
406 if (math.cast(i32, x)) |_| return .imm32s;
407 if (math.cast(u32, x)) |_| return .imm32;
408 return .imm64;
409 },
410 }
397411 },
398412 }
399413 }
400414
401 pub fn size(op: Op) u32 {
415 pub fn bitSize(op: Op) u64 {
402416 return switch (op) {
403 .none, .o16, .o32, .o64, .moffs, .m, .sreg, .unity => unreachable,
404 .imm8, .al, .cl, .r8, .m8, .rm8, .rel8 => 8,
405 .imm16, .ax, .r16, .m16, .rm16, .rel16 => 16,
406 .imm32, .eax, .r32, .m32, .rm32, .rel32, .xmm_m32 => 32,
417 .none, .o16, .o32, .o64, .moffs, .m, .sreg => unreachable,
418 .unity, .imm8, .imm8s, .al, .cl, .r8, .m8, .rm8, .rel8 => 8,
419 .imm16, .imm16s, .ax, .r16, .m16, .rm16, .rel16 => 16,
420 .imm32, .imm32s, .eax, .r32, .m32, .rm32, .rel32, .xmm_m32 => 32,
407421 .imm64, .rax, .r64, .m64, .rm64, .xmm_m64 => 64,
408422 .m80 => 80,
409423 .xmm => 128,
......@@ -428,6 +442,7 @@ pub const Op = enum {
428442 // zig fmt: off
429443 return switch (op) {
430444 .imm8, .imm16, .imm32, .imm64,
445 .imm8s, .imm16s, .imm32s,
431446 .rel8, .rel16, .rel32,
432447 .unity,
433448 => true,
......@@ -479,28 +494,40 @@ pub const Op = enum {
479494 .sse, .sse2 => return op.isFloatingPointRegister() and target.isFloatingPointRegister(),
480495 else => switch (target) {
481496 .cl, .al, .ax, .eax, .rax => return op == target,
482 else => return op.size() == target.size(),
497 else => return op.bitSize() == target.bitSize(),
483498 },
484499 }
485500 }
486501 if (op.isMemory() and target.isMemory()) {
487502 switch (target) {
488503 .m => return true,
489 else => return op.size() == target.size(),
504 else => return op.bitSize() == target.bitSize(),
490505 }
491506 }
492507 if (op.isImmediate() and target.isImmediate()) {
493508 switch (target) {
494 .imm32, .rel32 => switch (op) {
495 .unity, .imm8, .imm16, .imm32 => return true,
509 .imm32s, .rel32 => switch (op) {
510 .unity, .imm8s, .imm8, .imm16s, .imm16, .imm32s => return true,
511 else => return op == target,
512 },
513 .imm32 => switch (op) {
514 .unity, .imm8, .imm8s, .imm16, .imm16s, .imm32, .imm32s => return true,
515 else => return op == target,
516 },
517 .imm16s, .rel16 => switch (op) {
518 .unity, .imm8s, .imm8, .imm16s => return true,
519 else => return op == target,
520 },
521 .imm16 => switch (op) {
522 .unity, .imm8, .imm8s, .imm16, .imm16s => return true,
496523 else => return op == target,
497524 },
498 .imm16, .rel16 => switch (op) {
499 .unity, .imm8, .imm16 => return true,
525 .imm8s, .rel8 => switch (op) {
526 .unity, .imm8s => return true,
500527 else => return op == target,
501528 },
502 .imm8, .rel8 => switch (op) {
503 .unity, .imm8 => return true,
529 .imm8 => switch (op) {
530 .unity, .imm8, .imm8s => return true,
504531 else => return op == target,
505532 },
506533 else => return op == target,
src/arch/x86_64/Mir.zig+3
......@@ -34,6 +34,7 @@ pub const Inst = struct {
3434 /// 0b01 reg1, [reg2 + imm32]
3535 /// 0b01 reg1, [ds:imm32]
3636 /// 0b10 [reg1 + imm32], reg2
37 /// 0b11 reg1, imm_s
3738 /// Notes:
3839 /// * If reg2 is `none` then it means Data field `imm` is used as the immediate.
3940 /// * When two imm32 values are required, Data field `payload` points at `ImmPair`.
......@@ -421,6 +422,8 @@ pub const Inst = struct {
421422 inst: Index,
422423 /// A 32-bit immediate value.
423424 imm: u32,
425 /// A 32-bit signed immediate value.
426 imm_s: i32,
424427 /// A 32-bit signed displacement value.
425428 disp: i32,
426429 /// A condition code for use with EFLAGS register.
src/arch/x86_64/bits.zig+60-9
......@@ -207,7 +207,7 @@ pub const Register = enum(u7) {
207207 return @intCast(u6, @enumToInt(reg) - base);
208208 }
209209
210 pub fn size(reg: Register) u32 {
210 pub fn bitSize(reg: Register) u64 {
211211 return switch (@enumToInt(reg)) {
212212 // zig fmt: off
213213 @enumToInt(Register.rax) ... @enumToInt(Register.r15) => 64,
......@@ -273,7 +273,7 @@ pub const Register = enum(u7) {
273273 return @truncate(u3, reg.enc());
274274 }
275275
276 pub fn toSize(reg: Register, bit_size: u32) Register {
276 pub fn toBitSize(reg: Register, bit_size: u64) Register {
277277 return switch (bit_size) {
278278 8 => reg.to8(),
279279 16 => reg.to16(),
......@@ -334,7 +334,17 @@ pub const Register = enum(u7) {
334334
335335 pub fn dwarfLocOp(reg: Register) u8 {
336336 return switch (reg.class()) {
337 .general_purpose => @intCast(u8, @enumToInt(reg) - reg.gpBase()) + DW.OP.reg0,
337 .general_purpose => switch (reg.to64()) {
338 .rax => DW.OP.reg0,
339 .rdx => DW.OP.reg1,
340 .rcx => DW.OP.reg2,
341 .rbx => DW.OP.reg3,
342 .rsi => DW.OP.reg4,
343 .rdi => DW.OP.reg5,
344 .rbp => DW.OP.reg6,
345 .rsp => DW.OP.reg7,
346 else => @intCast(u8, @enumToInt(reg) - reg.gpBase()) + DW.OP.reg0,
347 },
338348 .floating_point => @intCast(u8, @enumToInt(reg) - reg.fpBase()) + DW.OP.reg17,
339349 else => unreachable,
340350 };
......@@ -345,7 +355,17 @@ pub const Register = enum(u7) {
345355 /// register to a given signed offset.
346356 pub fn dwarfLocOpDeref(reg: Register) u8 {
347357 return switch (reg.class()) {
348 .general_purpose => @intCast(u8, @enumToInt(reg) - reg.gpBase()) + DW.OP.breg0,
358 .general_purpose => switch (reg.to64()) {
359 .rax => DW.OP.breg0,
360 .rdx => DW.OP.breg1,
361 .rcx => DW.OP.breg2,
362 .rbx => DW.OP.breg3,
363 .rsi => DW.OP.breg4,
364 .rdi => DW.OP.breg5,
365 .rbp => DW.OP.breg6,
366 .rsp => DW.OP.breg7,
367 else => @intCast(u8, @enumToInt(reg) - reg.gpBase()) + DW.OP.breg0,
368 },
349369 .floating_point => @intCast(u8, @enumToInt(reg) - reg.fpBase()) + DW.OP.breg17,
350370 else => unreachable,
351371 };
......@@ -397,7 +417,7 @@ pub const Memory = union(enum) {
397417 qword,
398418 tbyte,
399419
400 pub fn fromSize(bit_size: u32) PtrSize {
420 pub fn fromBitSize(bit_size: u64) PtrSize {
401421 return switch (bit_size) {
402422 8 => .byte,
403423 16 => .word,
......@@ -408,7 +428,7 @@ pub const Memory = union(enum) {
408428 };
409429 }
410430
411 pub fn size(s: PtrSize) u32 {
431 pub fn bitSize(s: PtrSize) u64 {
412432 return switch (s) {
413433 .byte => 8,
414434 .word => 16,
......@@ -481,11 +501,42 @@ pub const Memory = union(enum) {
481501 };
482502 }
483503
484 pub fn size(mem: Memory) u32 {
504 pub fn bitSize(mem: Memory) u64 {
485505 return switch (mem) {
486 .rip => |r| r.ptr_size.size(),
487 .sib => |s| s.ptr_size.size(),
506 .rip => |r| r.ptr_size.bitSize(),
507 .sib => |s| s.ptr_size.bitSize(),
488508 .moffs => unreachable,
489509 };
490510 }
491511};
512
513pub const Immediate = union(enum) {
514 signed: i32,
515 unsigned: u64,
516
517 pub fn u(x: u64) Immediate {
518 return .{ .unsigned = x };
519 }
520
521 pub fn s(x: i32) Immediate {
522 return .{ .signed = x };
523 }
524
525 pub fn asUnsigned(imm: Immediate, bit_size: u64) u64 {
526 return switch (imm) {
527 .signed => |x| switch (bit_size) {
528 8 => @bitCast(u8, @intCast(i8, x)),
529 16 => @bitCast(u16, @intCast(i16, x)),
530 32 => @bitCast(u32, @intCast(i32, x)),
531 else => unreachable,
532 },
533 .unsigned => |x| switch (bit_size) {
534 8 => @intCast(u8, x),
535 16 => @intCast(u16, x),
536 32 => @intCast(u32, x),
537 64 => x,
538 else => unreachable,
539 },
540 };
541 }
542};
src/arch/x86_64/encoder.zig+40-33
......@@ -4,6 +4,7 @@ const math = std.math;
44
55const bits = @import("bits.zig");
66const Encoding = @import("Encoding.zig");
7const Immediate = bits.Immediate;
78const Memory = bits.Memory;
89const Moffs = bits.Moffs;
910const PtrSize = bits.PtrSize;
......@@ -22,15 +23,14 @@ pub const Instruction = struct {
2223 none,
2324 reg: Register,
2425 mem: Memory,
25 imm: u64,
26 imm: Immediate,
2627
2728 /// Returns the bitsize of the operand.
28 /// Asserts the operand is either register or memory.
29 pub fn size(op: Operand) u64 {
29 pub fn bitSize(op: Operand) u64 {
3030 return switch (op) {
3131 .none => unreachable,
32 .reg => |reg| reg.size(),
33 .mem => |mem| mem.size(),
32 .reg => |reg| reg.bitSize(),
33 .mem => |mem| mem.bitSize(),
3434 .imm => unreachable,
3535 };
3636 }
......@@ -47,7 +47,6 @@ pub const Instruction = struct {
4747 }
4848
4949 pub fn fmtPrint(op: Operand, enc_op: Encoding.Op, writer: anytype) !void {
50 _ = enc_op;
5150 switch (op) {
5251 .none => {},
5352 .reg => |reg| try writer.writeAll(@tagName(reg)),
......@@ -92,9 +91,7 @@ pub const Instruction = struct {
9291 },
9392 .moffs => |moffs| try writer.print("{s}:0x{x}", .{ @tagName(moffs.seg), moffs.offset }),
9493 },
95 .imm => |imm| {
96 try writer.print("0x{x}", .{imm});
97 },
94 .imm => |imm| try writer.print("0x{x}", .{imm.asUnsigned(enc_op.bitSize())}),
9895 }
9996 }
10097 };
......@@ -110,8 +107,17 @@ pub const Instruction = struct {
110107 .op2 = args.op2,
111108 .op3 = args.op3,
112109 .op4 = args.op4,
113 }) orelse return error.InvalidInstruction;
114 std.log.warn("{}", .{encoding});
110 }) orelse {
111 std.log.debug("{s} {s} {s} {s} {s}", .{
112 @tagName(mnemonic),
113 @tagName(Encoding.Op.fromOperand(args.op1)),
114 @tagName(Encoding.Op.fromOperand(args.op2)),
115 @tagName(Encoding.Op.fromOperand(args.op3)),
116 @tagName(Encoding.Op.fromOperand(args.op4)),
117 });
118 return error.InvalidInstruction;
119 };
120 std.log.debug("{}", .{encoding});
115121 return .{
116122 .op1 = args.op1,
117123 .op2 = args.op2,
......@@ -210,7 +216,7 @@ pub const Instruction = struct {
210216
211217 var legacy = LegacyPrefixes{};
212218 if (enc.mode == .none) {
213 const bit_size = enc.operandSize();
219 const bit_size = enc.operandBitSize();
214220 if (bit_size == 16) {
215221 legacy.set16BitOverride();
216222 }
......@@ -380,12 +386,13 @@ pub const Instruction = struct {
380386 }
381387 }
382388
383 fn encodeImm(imm: u64, kind: Encoding.Op, encoder: anytype) !void {
384 switch (kind) {
385 .imm8, .rel8 => try encoder.imm8(@bitCast(i8, @truncate(u8, imm))),
386 .imm16, .rel16 => try encoder.imm16(@bitCast(i16, @truncate(u16, imm))),
387 .imm32, .rel32 => try encoder.imm32(@bitCast(i32, @truncate(u32, imm))),
388 .imm64 => try encoder.imm64(imm),
389 fn encodeImm(imm: Immediate, kind: Encoding.Op, encoder: anytype) !void {
390 const raw = imm.asUnsigned(kind.bitSize());
391 switch (kind.bitSize()) {
392 8 => try encoder.imm8(@intCast(u8, raw)),
393 16 => try encoder.imm16(@intCast(u16, raw)),
394 32 => try encoder.imm32(@intCast(u32, raw)),
395 64 => try encoder.imm64(raw),
389396 else => unreachable,
390397 }
391398 }
......@@ -732,39 +739,39 @@ fn Encoder(comptime T: type) type {
732739 // Trivial (no bit fiddling)
733740 // -------------------------
734741
735 /// Encode an 8 bit immediate
742 /// Encode an 8 bit displacement
736743 ///
737744 /// It is sign-extended to 64 bits by the cpu.
738 pub fn imm8(self: Self, imm: i8) !void {
739 try self.writer.writeByte(@bitCast(u8, imm));
745 pub fn disp8(self: Self, disp: i8) !void {
746 try self.writer.writeByte(@bitCast(u8, disp));
740747 }
741748
742 /// Encode an 8 bit displacement
749 /// Encode an 32 bit displacement
743750 ///
744751 /// It is sign-extended to 64 bits by the cpu.
745 pub fn disp8(self: Self, disp: i8) !void {
746 try self.writer.writeByte(@bitCast(u8, disp));
752 pub fn disp32(self: Self, disp: i32) !void {
753 try self.writer.writeIntLittle(i32, disp);
747754 }
748755
749 /// Encode an 16 bit immediate
756 /// Encode an 8 bit immediate
750757 ///
751758 /// It is sign-extended to 64 bits by the cpu.
752 pub fn imm16(self: Self, imm: i16) !void {
753 try self.writer.writeIntLittle(i16, imm);
759 pub fn imm8(self: Self, imm: u8) !void {
760 try self.writer.writeByte(imm);
754761 }
755762
756 /// Encode an 32 bit immediate
763 /// Encode an 16 bit immediate
757764 ///
758765 /// It is sign-extended to 64 bits by the cpu.
759 pub fn imm32(self: Self, imm: i32) !void {
760 try self.writer.writeIntLittle(i32, imm);
766 pub fn imm16(self: Self, imm: u16) !void {
767 try self.writer.writeIntLittle(u16, imm);
761768 }
762769
763 /// Encode an 32 bit displacement
770 /// Encode an 32 bit immediate
764771 ///
765772 /// It is sign-extended to 64 bits by the cpu.
766 pub fn disp32(self: Self, disp: i32) !void {
767 try self.writer.writeIntLittle(i32, disp);
773 pub fn imm32(self: Self, imm: u32) !void {
774 try self.writer.writeIntLittle(u32, imm);
768775 }
769776
770777 /// Encode an 64 bit immediate
src/arch/x86_64/encodings.zig+211-210
......@@ -13,65 +13,65 @@ const Entry = struct { Mnemonic, OpEn, Op, Op, Op, Op, opcode_len, u8, u8, u8, m
1313// zig fmt: off
1414pub const table = &[_]Entry{
1515 // General-purpose
16 .{ .adc, .zi, .al, .imm8, .none, .none, 1, 0x14, 0x00, 0x00, 0, .none },
17 .{ .adc, .zi, .ax, .imm16, .none, .none, 1, 0x15, 0x00, 0x00, 0, .none },
18 .{ .adc, .zi, .eax, .imm32, .none, .none, 1, 0x15, 0x00, 0x00, 0, .none },
19 .{ .adc, .zi, .rax, .imm32, .none, .none, 1, 0x15, 0x00, 0x00, 0, .long },
20 .{ .adc, .mi, .rm8, .imm8, .none, .none, 1, 0x80, 0x00, 0x00, 2, .none },
21 .{ .adc, .mi, .rm16, .imm16, .none, .none, 1, 0x81, 0x00, 0x00, 2, .none },
22 .{ .adc, .mi, .rm32, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 2, .none },
23 .{ .adc, .mi, .rm64, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 2, .long },
24 .{ .adc, .mi, .rm16, .imm8, .none, .none, 1, 0x83, 0x00, 0x00, 2, .none },
25 .{ .adc, .mi, .rm32, .imm8, .none, .none, 1, 0x83, 0x00, 0x00, 2, .none },
26 .{ .adc, .mi, .rm64, .imm8, .none, .none, 1, 0x83, 0x00, 0x00, 2, .long },
27 .{ .adc, .mr, .rm8, .r8, .none, .none, 1, 0x10, 0x00, 0x00, 0, .none },
28 .{ .adc, .mr, .rm16, .r16, .none, .none, 1, 0x11, 0x00, 0x00, 0, .none },
29 .{ .adc, .mr, .rm32, .r32, .none, .none, 1, 0x11, 0x00, 0x00, 0, .none },
30 .{ .adc, .mr, .rm64, .r64, .none, .none, 1, 0x11, 0x00, 0x00, 0, .long },
31 .{ .adc, .rm, .r8, .rm8, .none, .none, 1, 0x12, 0x00, 0x00, 0, .none },
32 .{ .adc, .rm, .r16, .rm16, .none, .none, 1, 0x13, 0x00, 0x00, 0, .none },
33 .{ .adc, .rm, .r32, .rm32, .none, .none, 1, 0x13, 0x00, 0x00, 0, .none },
34 .{ .adc, .rm, .r64, .rm64, .none, .none, 1, 0x13, 0x00, 0x00, 0, .long },
35
36 .{ .add, .zi, .al, .imm8, .none, .none, 1, 0x04, 0x00, 0x00, 0, .none },
37 .{ .add, .zi, .ax, .imm16, .none, .none, 1, 0x05, 0x00, 0x00, 0, .none },
38 .{ .add, .zi, .eax, .imm32, .none, .none, 1, 0x05, 0x00, 0x00, 0, .none },
39 .{ .add, .zi, .rax, .imm32, .none, .none, 1, 0x05, 0x00, 0x00, 0, .long },
40 .{ .add, .mi, .rm8, .imm8, .none, .none, 1, 0x80, 0x00, 0x00, 0, .none },
41 .{ .add, .mi, .rm16, .imm16, .none, .none, 1, 0x81, 0x00, 0x00, 0, .none },
42 .{ .add, .mi, .rm32, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 0, .none },
43 .{ .add, .mi, .rm64, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 0, .long },
44 .{ .add, .mi, .rm16, .imm8, .none, .none, 1, 0x83, 0x00, 0x00, 0, .none },
45 .{ .add, .mi, .rm32, .imm8, .none, .none, 1, 0x83, 0x00, 0x00, 0, .none },
46 .{ .add, .mi, .rm64, .imm8, .none, .none, 1, 0x83, 0x00, 0x00, 0, .long },
47 .{ .add, .mr, .rm8, .r8, .none, .none, 1, 0x00, 0x00, 0x00, 0, .none },
48 .{ .add, .mr, .rm16, .r16, .none, .none, 1, 0x01, 0x00, 0x00, 0, .none },
49 .{ .add, .mr, .rm32, .r32, .none, .none, 1, 0x01, 0x00, 0x00, 0, .none },
50 .{ .add, .mr, .rm64, .r64, .none, .none, 1, 0x01, 0x00, 0x00, 0, .long },
51 .{ .add, .rm, .r8, .rm8, .none, .none, 1, 0x02, 0x00, 0x00, 0, .none },
52 .{ .add, .rm, .r16, .rm16, .none, .none, 1, 0x03, 0x00, 0x00, 0, .none },
53 .{ .add, .rm, .r32, .rm32, .none, .none, 1, 0x03, 0x00, 0x00, 0, .none },
54 .{ .add, .rm, .r64, .rm64, .none, .none, 1, 0x03, 0x00, 0x00, 0, .long },
55
56 .{ .@"and", .zi, .al, .imm8, .none, .none, 1, 0x24, 0x00, 0x00, 0, .none },
57 .{ .@"and", .zi, .ax, .imm16, .none, .none, 1, 0x25, 0x00, 0x00, 0, .none },
58 .{ .@"and", .zi, .eax, .imm32, .none, .none, 1, 0x25, 0x00, 0x00, 0, .none },
59 .{ .@"and", .zi, .rax, .imm32, .none, .none, 1, 0x25, 0x00, 0x00, 0, .long },
60 .{ .@"and", .mi, .rm8, .imm8, .none, .none, 1, 0x80, 0x00, 0x00, 4, .none },
61 .{ .@"and", .mi, .rm16, .imm16, .none, .none, 1, 0x81, 0x00, 0x00, 4, .none },
62 .{ .@"and", .mi, .rm32, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 4, .none },
63 .{ .@"and", .mi, .rm64, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 4, .long },
64 .{ .@"and", .mi, .rm16, .imm8, .none, .none, 1, 0x83, 0x00, 0x00, 4, .none },
65 .{ .@"and", .mi, .rm32, .imm8, .none, .none, 1, 0x83, 0x00, 0x00, 4, .none },
66 .{ .@"and", .mi, .rm64, .imm8, .none, .none, 1, 0x83, 0x00, 0x00, 4, .long },
67 .{ .@"and", .mr, .rm8, .r8, .none, .none, 1, 0x20, 0x00, 0x00, 0, .none },
68 .{ .@"and", .mr, .rm16, .r16, .none, .none, 1, 0x21, 0x00, 0x00, 0, .none },
69 .{ .@"and", .mr, .rm32, .r32, .none, .none, 1, 0x21, 0x00, 0x00, 0, .none },
70 .{ .@"and", .mr, .rm64, .r64, .none, .none, 1, 0x21, 0x00, 0x00, 0, .long },
71 .{ .@"and", .rm, .r8, .rm8, .none, .none, 1, 0x22, 0x00, 0x00, 0, .none },
72 .{ .@"and", .rm, .r16, .rm16, .none, .none, 1, 0x23, 0x00, 0x00, 0, .none },
73 .{ .@"and", .rm, .r32, .rm32, .none, .none, 1, 0x23, 0x00, 0x00, 0, .none },
74 .{ .@"and", .rm, .r64, .rm64, .none, .none, 1, 0x23, 0x00, 0x00, 0, .long },
16 .{ .adc, .zi, .al, .imm8, .none, .none, 1, 0x14, 0x00, 0x00, 0, .none },
17 .{ .adc, .zi, .ax, .imm16, .none, .none, 1, 0x15, 0x00, 0x00, 0, .none },
18 .{ .adc, .zi, .eax, .imm32, .none, .none, 1, 0x15, 0x00, 0x00, 0, .none },
19 .{ .adc, .zi, .rax, .imm32s, .none, .none, 1, 0x15, 0x00, 0x00, 0, .long },
20 .{ .adc, .mi, .rm8, .imm8, .none, .none, 1, 0x80, 0x00, 0x00, 2, .none },
21 .{ .adc, .mi, .rm16, .imm16, .none, .none, 1, 0x81, 0x00, 0x00, 2, .none },
22 .{ .adc, .mi, .rm32, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 2, .none },
23 .{ .adc, .mi, .rm64, .imm32s, .none, .none, 1, 0x81, 0x00, 0x00, 2, .long },
24 .{ .adc, .mi, .rm16, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 2, .none },
25 .{ .adc, .mi, .rm32, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 2, .none },
26 .{ .adc, .mi, .rm64, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 2, .long },
27 .{ .adc, .mr, .rm8, .r8, .none, .none, 1, 0x10, 0x00, 0x00, 0, .none },
28 .{ .adc, .mr, .rm16, .r16, .none, .none, 1, 0x11, 0x00, 0x00, 0, .none },
29 .{ .adc, .mr, .rm32, .r32, .none, .none, 1, 0x11, 0x00, 0x00, 0, .none },
30 .{ .adc, .mr, .rm64, .r64, .none, .none, 1, 0x11, 0x00, 0x00, 0, .long },
31 .{ .adc, .rm, .r8, .rm8, .none, .none, 1, 0x12, 0x00, 0x00, 0, .none },
32 .{ .adc, .rm, .r16, .rm16, .none, .none, 1, 0x13, 0x00, 0x00, 0, .none },
33 .{ .adc, .rm, .r32, .rm32, .none, .none, 1, 0x13, 0x00, 0x00, 0, .none },
34 .{ .adc, .rm, .r64, .rm64, .none, .none, 1, 0x13, 0x00, 0x00, 0, .long },
35
36 .{ .add, .zi, .al, .imm8, .none, .none, 1, 0x04, 0x00, 0x00, 0, .none },
37 .{ .add, .zi, .ax, .imm16, .none, .none, 1, 0x05, 0x00, 0x00, 0, .none },
38 .{ .add, .zi, .eax, .imm32, .none, .none, 1, 0x05, 0x00, 0x00, 0, .none },
39 .{ .add, .zi, .rax, .imm32s, .none, .none, 1, 0x05, 0x00, 0x00, 0, .long },
40 .{ .add, .mi, .rm8, .imm8, .none, .none, 1, 0x80, 0x00, 0x00, 0, .none },
41 .{ .add, .mi, .rm16, .imm16, .none, .none, 1, 0x81, 0x00, 0x00, 0, .none },
42 .{ .add, .mi, .rm32, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 0, .none },
43 .{ .add, .mi, .rm64, .imm32s, .none, .none, 1, 0x81, 0x00, 0x00, 0, .long },
44 .{ .add, .mi, .rm16, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 0, .none },
45 .{ .add, .mi, .rm32, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 0, .none },
46 .{ .add, .mi, .rm64, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 0, .long },
47 .{ .add, .mr, .rm8, .r8, .none, .none, 1, 0x00, 0x00, 0x00, 0, .none },
48 .{ .add, .mr, .rm16, .r16, .none, .none, 1, 0x01, 0x00, 0x00, 0, .none },
49 .{ .add, .mr, .rm32, .r32, .none, .none, 1, 0x01, 0x00, 0x00, 0, .none },
50 .{ .add, .mr, .rm64, .r64, .none, .none, 1, 0x01, 0x00, 0x00, 0, .long },
51 .{ .add, .rm, .r8, .rm8, .none, .none, 1, 0x02, 0x00, 0x00, 0, .none },
52 .{ .add, .rm, .r16, .rm16, .none, .none, 1, 0x03, 0x00, 0x00, 0, .none },
53 .{ .add, .rm, .r32, .rm32, .none, .none, 1, 0x03, 0x00, 0x00, 0, .none },
54 .{ .add, .rm, .r64, .rm64, .none, .none, 1, 0x03, 0x00, 0x00, 0, .long },
55
56 .{ .@"and", .zi, .al, .imm8, .none, .none, 1, 0x24, 0x00, 0x00, 0, .none },
57 .{ .@"and", .zi, .ax, .imm16, .none, .none, 1, 0x25, 0x00, 0x00, 0, .none },
58 .{ .@"and", .zi, .eax, .imm32, .none, .none, 1, 0x25, 0x00, 0x00, 0, .none },
59 .{ .@"and", .zi, .rax, .imm32s, .none, .none, 1, 0x25, 0x00, 0x00, 0, .long },
60 .{ .@"and", .mi, .rm8, .imm8, .none, .none, 1, 0x80, 0x00, 0x00, 4, .none },
61 .{ .@"and", .mi, .rm16, .imm16, .none, .none, 1, 0x81, 0x00, 0x00, 4, .none },
62 .{ .@"and", .mi, .rm32, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 4, .none },
63 .{ .@"and", .mi, .rm64, .imm32s, .none, .none, 1, 0x81, 0x00, 0x00, 4, .long },
64 .{ .@"and", .mi, .rm16, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 4, .none },
65 .{ .@"and", .mi, .rm32, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 4, .none },
66 .{ .@"and", .mi, .rm64, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 4, .long },
67 .{ .@"and", .mr, .rm8, .r8, .none, .none, 1, 0x20, 0x00, 0x00, 0, .none },
68 .{ .@"and", .mr, .rm16, .r16, .none, .none, 1, 0x21, 0x00, 0x00, 0, .none },
69 .{ .@"and", .mr, .rm32, .r32, .none, .none, 1, 0x21, 0x00, 0x00, 0, .none },
70 .{ .@"and", .mr, .rm64, .r64, .none, .none, 1, 0x21, 0x00, 0x00, 0, .long },
71 .{ .@"and", .rm, .r8, .rm8, .none, .none, 1, 0x22, 0x00, 0x00, 0, .none },
72 .{ .@"and", .rm, .r16, .rm16, .none, .none, 1, 0x23, 0x00, 0x00, 0, .none },
73 .{ .@"and", .rm, .r32, .rm32, .none, .none, 1, 0x23, 0x00, 0x00, 0, .none },
74 .{ .@"and", .rm, .r64, .rm64, .none, .none, 1, 0x23, 0x00, 0x00, 0, .long },
7575
7676 // This is M encoding according to Intel, but D makes more sense here.
7777 .{ .call, .d, .rel32, .none, .none, .none, 1, 0xe8, 0x00, 0x00, 0, .none },
......@@ -176,25 +176,25 @@ pub const table = &[_]Entry{
176176 .{ .cmovz, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x44, 0x00, 0, .none },
177177 .{ .cmovz, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x44, 0x00, 0, .long },
178178
179 .{ .cmp, .zi, .al, .imm8, .none, .none, 1, 0x3c, 0x00, 0x00, 0, .none },
180 .{ .cmp, .zi, .ax, .imm16, .none, .none, 1, 0x3d, 0x00, 0x00, 0, .none },
181 .{ .cmp, .zi, .eax, .imm32, .none, .none, 1, 0x3d, 0x00, 0x00, 0, .none },
182 .{ .cmp, .zi, .rax, .imm32, .none, .none, 1, 0x3d, 0x00, 0x00, 0, .long },
183 .{ .cmp, .mi, .rm8, .imm8, .none, .none, 1, 0x80, 0x00, 0x00, 7, .none },
184 .{ .cmp, .mi, .rm16, .imm16, .none, .none, 1, 0x81, 0x00, 0x00, 7, .none },
185 .{ .cmp, .mi, .rm32, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 7, .none },
186 .{ .cmp, .mi, .rm64, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 7, .long },
187 .{ .cmp, .mi, .rm16, .imm8, .none, .none, 1, 0x83, 0x00, 0x00, 7, .none },
188 .{ .cmp, .mi, .rm32, .imm8, .none, .none, 1, 0x83, 0x00, 0x00, 7, .none },
189 .{ .cmp, .mi, .rm64, .imm8, .none, .none, 1, 0x83, 0x00, 0x00, 7, .long },
190 .{ .cmp, .mr, .rm8, .r8, .none, .none, 1, 0x38, 0x00, 0x00, 0, .none },
191 .{ .cmp, .mr, .rm16, .r16, .none, .none, 1, 0x39, 0x00, 0x00, 0, .none },
192 .{ .cmp, .mr, .rm32, .r32, .none, .none, 1, 0x39, 0x00, 0x00, 0, .none },
193 .{ .cmp, .mr, .rm64, .r64, .none, .none, 1, 0x39, 0x00, 0x00, 0, .long },
194 .{ .cmp, .rm, .r8, .rm8, .none, .none, 1, 0x3a, 0x00, 0x00, 0, .none },
195 .{ .cmp, .rm, .r16, .rm16, .none, .none, 1, 0x3b, 0x00, 0x00, 0, .none },
196 .{ .cmp, .rm, .r32, .rm32, .none, .none, 1, 0x3b, 0x00, 0x00, 0, .none },
197 .{ .cmp, .rm, .r64, .rm64, .none, .none, 1, 0x3b, 0x00, 0x00, 0, .long },
179 .{ .cmp, .zi, .al, .imm8, .none, .none, 1, 0x3c, 0x00, 0x00, 0, .none },
180 .{ .cmp, .zi, .ax, .imm16, .none, .none, 1, 0x3d, 0x00, 0x00, 0, .none },
181 .{ .cmp, .zi, .eax, .imm32, .none, .none, 1, 0x3d, 0x00, 0x00, 0, .none },
182 .{ .cmp, .zi, .rax, .imm32s, .none, .none, 1, 0x3d, 0x00, 0x00, 0, .long },
183 .{ .cmp, .mi, .rm8, .imm8, .none, .none, 1, 0x80, 0x00, 0x00, 7, .none },
184 .{ .cmp, .mi, .rm16, .imm16, .none, .none, 1, 0x81, 0x00, 0x00, 7, .none },
185 .{ .cmp, .mi, .rm32, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 7, .none },
186 .{ .cmp, .mi, .rm64, .imm32s, .none, .none, 1, 0x81, 0x00, 0x00, 7, .long },
187 .{ .cmp, .mi, .rm16, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 7, .none },
188 .{ .cmp, .mi, .rm32, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 7, .none },
189 .{ .cmp, .mi, .rm64, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 7, .long },
190 .{ .cmp, .mr, .rm8, .r8, .none, .none, 1, 0x38, 0x00, 0x00, 0, .none },
191 .{ .cmp, .mr, .rm16, .r16, .none, .none, 1, 0x39, 0x00, 0x00, 0, .none },
192 .{ .cmp, .mr, .rm32, .r32, .none, .none, 1, 0x39, 0x00, 0x00, 0, .none },
193 .{ .cmp, .mr, .rm64, .r64, .none, .none, 1, 0x39, 0x00, 0x00, 0, .long },
194 .{ .cmp, .rm, .r8, .rm8, .none, .none, 1, 0x3a, 0x00, 0x00, 0, .none },
195 .{ .cmp, .rm, .r16, .rm16, .none, .none, 1, 0x3b, 0x00, 0x00, 0, .none },
196 .{ .cmp, .rm, .r32, .rm32, .none, .none, 1, 0x3b, 0x00, 0x00, 0, .none },
197 .{ .cmp, .rm, .r64, .rm64, .none, .none, 1, 0x3b, 0x00, 0x00, 0, .long },
198198
199199 .{ .div, .m, .rm8, .none, .none, .none, 1, 0xf6, 0x00, 0x00, 6, .none },
200200 .{ .div, .m, .rm16, .none, .none, .none, 1, 0xf7, 0x00, 0x00, 6, .none },
......@@ -214,19 +214,19 @@ pub const table = &[_]Entry{
214214 .{ .idiv, .m, .rm32, .none, .none, .none, 1, 0xf7, 0x00, 0x00, 7, .none },
215215 .{ .idiv, .m, .rm64, .none, .none, .none, 1, 0xf7, 0x00, 0x00, 7, .long },
216216
217 .{ .imul, .m, .rm8, .none, .none, .none, 1, 0xf6, 0x00, 0x00, 5, .none },
218 .{ .imul, .m, .rm16, .none, .none, .none, 1, 0xf7, 0x00, 0x00, 5, .none },
219 .{ .imul, .m, .rm32, .none, .none, .none, 1, 0xf7, 0x00, 0x00, 5, .none },
220 .{ .imul, .m, .rm64, .none, .none, .none, 1, 0xf7, 0x00, 0x00, 5, .long },
221 .{ .imul, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0xaf, 0x00, 0, .none },
222 .{ .imul, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0xaf, 0x00, 0, .none },
223 .{ .imul, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0xaf, 0x00, 0, .long },
224 .{ .imul, .rmi, .r16, .rm16, .imm8, .none, 1, 0x6b, 0x00, 0x00, 0, .none },
225 .{ .imul, .rmi, .r32, .rm32, .imm8, .none, 1, 0x6b, 0x00, 0x00, 0, .none },
226 .{ .imul, .rmi, .r64, .rm64, .imm8, .none, 1, 0x6b, 0x00, 0x00, 0, .long },
227 .{ .imul, .rmi, .r16, .rm16, .imm16, .none, 1, 0x69, 0x00, 0x00, 0, .none },
228 .{ .imul, .rmi, .r32, .rm32, .imm32, .none, 1, 0x69, 0x00, 0x00, 0, .none },
229 .{ .imul, .rmi, .r64, .rm64, .imm32, .none, 1, 0x69, 0x00, 0x00, 0, .long },
217 .{ .imul, .m, .rm8, .none, .none, .none, 1, 0xf6, 0x00, 0x00, 5, .none },
218 .{ .imul, .m, .rm16, .none, .none, .none, 1, 0xf7, 0x00, 0x00, 5, .none },
219 .{ .imul, .m, .rm32, .none, .none, .none, 1, 0xf7, 0x00, 0x00, 5, .none },
220 .{ .imul, .m, .rm64, .none, .none, .none, 1, 0xf7, 0x00, 0x00, 5, .long },
221 .{ .imul, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0xaf, 0x00, 0, .none },
222 .{ .imul, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0xaf, 0x00, 0, .none },
223 .{ .imul, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0xaf, 0x00, 0, .long },
224 .{ .imul, .rmi, .r16, .rm16, .imm8s, .none, 1, 0x6b, 0x00, 0x00, 0, .none },
225 .{ .imul, .rmi, .r32, .rm32, .imm8s, .none, 1, 0x6b, 0x00, 0x00, 0, .none },
226 .{ .imul, .rmi, .r64, .rm64, .imm8s, .none, 1, 0x6b, 0x00, 0x00, 0, .long },
227 .{ .imul, .rmi, .r16, .rm16, .imm16, .none, 1, 0x69, 0x00, 0x00, 0, .none },
228 .{ .imul, .rmi, .r32, .rm32, .imm32, .none, 1, 0x69, 0x00, 0x00, 0, .none },
229 .{ .imul, .rmi, .r64, .rm64, .imm32, .none, 1, 0x69, 0x00, 0x00, 0, .long },
230230
231231 .{ .int3, .np, .none, .none, .none, .none, 1, 0xcc, 0x00, 0x00, 0, .none },
232232
......@@ -269,34 +269,34 @@ pub const table = &[_]Entry{
269269 .{ .lea, .rm, .r32, .m, .none, .none, 1, 0x8d, 0x00, 0x00, 0, .none },
270270 .{ .lea, .rm, .r64, .m, .none, .none, 1, 0x8d, 0x00, 0x00, 0, .long },
271271
272 .{ .mov, .mr, .rm8, .r8, .none, .none, 1, 0x88, 0x00, 0x00, 0, .none },
273 .{ .mov, .mr, .rm16, .r16, .none, .none, 1, 0x89, 0x00, 0x00, 0, .none },
274 .{ .mov, .mr, .rm32, .r32, .none, .none, 1, 0x89, 0x00, 0x00, 0, .none },
275 .{ .mov, .mr, .rm64, .r64, .none, .none, 1, 0x89, 0x00, 0x00, 0, .long },
276 .{ .mov, .rm, .r8, .rm8, .none, .none, 1, 0x8a, 0x00, 0x00, 0, .none },
277 .{ .mov, .rm, .r16, .rm16, .none, .none, 1, 0x8b, 0x00, 0x00, 0, .none },
278 .{ .mov, .rm, .r32, .rm32, .none, .none, 1, 0x8b, 0x00, 0x00, 0, .none },
279 .{ .mov, .rm, .r64, .rm64, .none, .none, 1, 0x8b, 0x00, 0x00, 0, .long },
280 .{ .mov, .mr, .rm16, .sreg, .none, .none, 1, 0x8c, 0x00, 0x00, 0, .none },
281 .{ .mov, .mr, .rm64, .sreg, .none, .none, 1, 0x8c, 0x00, 0x00, 0, .long },
282 .{ .mov, .rm, .sreg, .rm16, .none, .none, 1, 0x8e, 0x00, 0x00, 0, .none },
283 .{ .mov, .rm, .sreg, .rm64, .none, .none, 1, 0x8e, 0x00, 0x00, 0, .long },
284 .{ .mov, .fd, .al, .moffs, .none, .none, 1, 0xa0, 0x00, 0x00, 0, .none },
285 .{ .mov, .fd, .ax, .moffs, .none, .none, 1, 0xa1, 0x00, 0x00, 0, .none },
286 .{ .mov, .fd, .eax, .moffs, .none, .none, 1, 0xa1, 0x00, 0x00, 0, .none },
287 .{ .mov, .fd, .rax, .moffs, .none, .none, 1, 0xa1, 0x00, 0x00, 0, .long },
288 .{ .mov, .td, .moffs, .al, .none, .none, 1, 0xa2, 0x00, 0x00, 0, .none },
289 .{ .mov, .td, .moffs, .ax, .none, .none, 1, 0xa3, 0x00, 0x00, 0, .none },
290 .{ .mov, .td, .moffs, .eax, .none, .none, 1, 0xa3, 0x00, 0x00, 0, .none },
291 .{ .mov, .td, .moffs, .rax, .none, .none, 1, 0xa3, 0x00, 0x00, 0, .long },
292 .{ .mov, .oi, .r8, .imm8, .none, .none, 1, 0xb0, 0x00, 0x00, 0, .none },
293 .{ .mov, .oi, .r16, .imm16, .none, .none, 1, 0xb8, 0x00, 0x00, 0, .none },
294 .{ .mov, .oi, .r32, .imm32, .none, .none, 1, 0xb8, 0x00, 0x00, 0, .none },
295 .{ .mov, .oi, .r64, .imm64, .none, .none, 1, 0xb8, 0x00, 0x00, 0, .long },
296 .{ .mov, .mi, .rm8, .imm8, .none, .none, 1, 0xc6, 0x00, 0x00, 0, .none },
297 .{ .mov, .mi, .rm16, .imm16, .none, .none, 1, 0xc7, 0x00, 0x00, 0, .none },
298 .{ .mov, .mi, .rm32, .imm32, .none, .none, 1, 0xc7, 0x00, 0x00, 0, .none },
299 .{ .mov, .mi, .rm64, .imm32, .none, .none, 1, 0xc7, 0x00, 0x00, 0, .long },
272 .{ .mov, .mr, .rm8, .r8, .none, .none, 1, 0x88, 0x00, 0x00, 0, .none },
273 .{ .mov, .mr, .rm16, .r16, .none, .none, 1, 0x89, 0x00, 0x00, 0, .none },
274 .{ .mov, .mr, .rm32, .r32, .none, .none, 1, 0x89, 0x00, 0x00, 0, .none },
275 .{ .mov, .mr, .rm64, .r64, .none, .none, 1, 0x89, 0x00, 0x00, 0, .long },
276 .{ .mov, .rm, .r8, .rm8, .none, .none, 1, 0x8a, 0x00, 0x00, 0, .none },
277 .{ .mov, .rm, .r16, .rm16, .none, .none, 1, 0x8b, 0x00, 0x00, 0, .none },
278 .{ .mov, .rm, .r32, .rm32, .none, .none, 1, 0x8b, 0x00, 0x00, 0, .none },
279 .{ .mov, .rm, .r64, .rm64, .none, .none, 1, 0x8b, 0x00, 0x00, 0, .long },
280 .{ .mov, .mr, .rm16, .sreg, .none, .none, 1, 0x8c, 0x00, 0x00, 0, .none },
281 .{ .mov, .mr, .rm64, .sreg, .none, .none, 1, 0x8c, 0x00, 0x00, 0, .long },
282 .{ .mov, .rm, .sreg, .rm16, .none, .none, 1, 0x8e, 0x00, 0x00, 0, .none },
283 .{ .mov, .rm, .sreg, .rm64, .none, .none, 1, 0x8e, 0x00, 0x00, 0, .long },
284 .{ .mov, .fd, .al, .moffs, .none, .none, 1, 0xa0, 0x00, 0x00, 0, .none },
285 .{ .mov, .fd, .ax, .moffs, .none, .none, 1, 0xa1, 0x00, 0x00, 0, .none },
286 .{ .mov, .fd, .eax, .moffs, .none, .none, 1, 0xa1, 0x00, 0x00, 0, .none },
287 .{ .mov, .fd, .rax, .moffs, .none, .none, 1, 0xa1, 0x00, 0x00, 0, .long },
288 .{ .mov, .td, .moffs, .al, .none, .none, 1, 0xa2, 0x00, 0x00, 0, .none },
289 .{ .mov, .td, .moffs, .ax, .none, .none, 1, 0xa3, 0x00, 0x00, 0, .none },
290 .{ .mov, .td, .moffs, .eax, .none, .none, 1, 0xa3, 0x00, 0x00, 0, .none },
291 .{ .mov, .td, .moffs, .rax, .none, .none, 1, 0xa3, 0x00, 0x00, 0, .long },
292 .{ .mov, .oi, .r8, .imm8, .none, .none, 1, 0xb0, 0x00, 0x00, 0, .none },
293 .{ .mov, .oi, .r16, .imm16, .none, .none, 1, 0xb8, 0x00, 0x00, 0, .none },
294 .{ .mov, .oi, .r32, .imm32, .none, .none, 1, 0xb8, 0x00, 0x00, 0, .none },
295 .{ .mov, .oi, .r64, .imm64, .none, .none, 1, 0xb8, 0x00, 0x00, 0, .long },
296 .{ .mov, .mi, .rm8, .imm8, .none, .none, 1, 0xc6, 0x00, 0x00, 0, .none },
297 .{ .mov, .mi, .rm16, .imm16, .none, .none, 1, 0xc7, 0x00, 0x00, 0, .none },
298 .{ .mov, .mi, .rm32, .imm32, .none, .none, 1, 0xc7, 0x00, 0x00, 0, .none },
299 .{ .mov, .mi, .rm64, .imm32s, .none, .none, 1, 0xc7, 0x00, 0x00, 0, .long },
300300
301301 .{ .movsx, .rm, .r16, .rm8, .none, .none, 2, 0x0f, 0xbe, 0x00, 0, .none },
302302 .{ .movsx, .rm, .r32, .rm8, .none, .none, 2, 0x0f, 0xbe, 0x00, 0, .none },
......@@ -321,25 +321,25 @@ pub const table = &[_]Entry{
321321
322322 .{ .nop, .np, .none, .none, .none, .none, 1, 0x90, 0x00, 0x00, 0, .none },
323323
324 .{ .@"or", .zi, .al, .imm8, .none, .none, 1, 0x0c, 0x00, 0x00, 0, .none },
325 .{ .@"or", .zi, .ax, .imm16, .none, .none, 1, 0x0d, 0x00, 0x00, 0, .none },
326 .{ .@"or", .zi, .eax, .imm32, .none, .none, 1, 0x0d, 0x00, 0x00, 0, .none },
327 .{ .@"or", .zi, .rax, .imm32, .none, .none, 1, 0x0d, 0x00, 0x00, 0, .long },
328 .{ .@"or", .mi, .rm8, .imm8, .none, .none, 1, 0x80, 0x00, 0x00, 1, .none },
329 .{ .@"or", .mi, .rm16, .imm16, .none, .none, 1, 0x81, 0x00, 0x00, 1, .none },
330 .{ .@"or", .mi, .rm32, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 1, .none },
331 .{ .@"or", .mi, .rm64, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 1, .long },
332 .{ .@"or", .mi, .rm16, .imm8, .none, .none, 1, 0x83, 0x00, 0x00, 1, .none },
333 .{ .@"or", .mi, .rm32, .imm8, .none, .none, 1, 0x83, 0x00, 0x00, 1, .none },
334 .{ .@"or", .mi, .rm64, .imm8, .none, .none, 1, 0x83, 0x00, 0x00, 1, .long },
335 .{ .@"or", .mr, .rm8, .r8, .none, .none, 1, 0x08, 0x00, 0x00, 0, .none },
336 .{ .@"or", .mr, .rm16, .r16, .none, .none, 1, 0x09, 0x00, 0x00, 0, .none },
337 .{ .@"or", .mr, .rm32, .r32, .none, .none, 1, 0x09, 0x00, 0x00, 0, .none },
338 .{ .@"or", .mr, .rm64, .r64, .none, .none, 1, 0x09, 0x00, 0x00, 0, .long },
339 .{ .@"or", .rm, .r8, .rm8, .none, .none, 1, 0x0a, 0x00, 0x00, 0, .none },
340 .{ .@"or", .rm, .r16, .rm16, .none, .none, 1, 0x0b, 0x00, 0x00, 0, .none },
341 .{ .@"or", .rm, .r32, .rm32, .none, .none, 1, 0x0b, 0x00, 0x00, 0, .none },
342 .{ .@"or", .rm, .r64, .rm64, .none, .none, 1, 0x0b, 0x00, 0x00, 0, .long },
324 .{ .@"or", .zi, .al, .imm8, .none, .none, 1, 0x0c, 0x00, 0x00, 0, .none },
325 .{ .@"or", .zi, .ax, .imm16, .none, .none, 1, 0x0d, 0x00, 0x00, 0, .none },
326 .{ .@"or", .zi, .eax, .imm32, .none, .none, 1, 0x0d, 0x00, 0x00, 0, .none },
327 .{ .@"or", .zi, .rax, .imm32s, .none, .none, 1, 0x0d, 0x00, 0x00, 0, .long },
328 .{ .@"or", .mi, .rm8, .imm8, .none, .none, 1, 0x80, 0x00, 0x00, 1, .none },
329 .{ .@"or", .mi, .rm16, .imm16, .none, .none, 1, 0x81, 0x00, 0x00, 1, .none },
330 .{ .@"or", .mi, .rm32, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 1, .none },
331 .{ .@"or", .mi, .rm64, .imm32s, .none, .none, 1, 0x81, 0x00, 0x00, 1, .long },
332 .{ .@"or", .mi, .rm16, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 1, .none },
333 .{ .@"or", .mi, .rm32, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 1, .none },
334 .{ .@"or", .mi, .rm64, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 1, .long },
335 .{ .@"or", .mr, .rm8, .r8, .none, .none, 1, 0x08, 0x00, 0x00, 0, .none },
336 .{ .@"or", .mr, .rm16, .r16, .none, .none, 1, 0x09, 0x00, 0x00, 0, .none },
337 .{ .@"or", .mr, .rm32, .r32, .none, .none, 1, 0x09, 0x00, 0x00, 0, .none },
338 .{ .@"or", .mr, .rm64, .r64, .none, .none, 1, 0x09, 0x00, 0x00, 0, .long },
339 .{ .@"or", .rm, .r8, .rm8, .none, .none, 1, 0x0a, 0x00, 0x00, 0, .none },
340 .{ .@"or", .rm, .r16, .rm16, .none, .none, 1, 0x0b, 0x00, 0x00, 0, .none },
341 .{ .@"or", .rm, .r32, .rm32, .none, .none, 1, 0x0b, 0x00, 0x00, 0, .none },
342 .{ .@"or", .rm, .r64, .rm64, .none, .none, 1, 0x0b, 0x00, 0x00, 0, .long },
343343
344344 .{ .pop, .o, .r16, .none, .none, .none, 1, 0x58, 0x00, 0x00, 0, .none },
345345 .{ .pop, .o, .r64, .none, .none, .none, 1, 0x58, 0x00, 0x00, 0, .none },
......@@ -382,25 +382,25 @@ pub const table = &[_]Entry{
382382 .{ .sar, .mi, .rm32, .imm8, .none, .none, 1, 0xc1, 0x00, 0x00, 7, .none },
383383 .{ .sar, .mi, .rm64, .imm8, .none, .none, 1, 0xc1, 0x00, 0x00, 7, .long },
384384
385 .{ .sbb, .zi, .al, .imm8, .none, .none, 1, 0x1c, 0x00, 0x00, 0, .none },
386 .{ .sbb, .zi, .ax, .imm16, .none, .none, 1, 0x1d, 0x00, 0x00, 0, .none },
387 .{ .sbb, .zi, .eax, .imm32, .none, .none, 1, 0x1d, 0x00, 0x00, 0, .none },
388 .{ .sbb, .zi, .rax, .imm32, .none, .none, 1, 0x1d, 0x00, 0x00, 0, .long },
389 .{ .sbb, .mi, .rm8, .imm8, .none, .none, 1, 0x80, 0x00, 0x00, 3, .none },
390 .{ .sbb, .mi, .rm16, .imm16, .none, .none, 1, 0x81, 0x00, 0x00, 3, .none },
391 .{ .sbb, .mi, .rm32, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 3, .none },
392 .{ .sbb, .mi, .rm64, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 3, .long },
393 .{ .sbb, .mi, .rm16, .imm8, .none, .none, 1, 0x83, 0x00, 0x00, 3, .none },
394 .{ .sbb, .mi, .rm32, .imm8, .none, .none, 1, 0x83, 0x00, 0x00, 3, .none },
395 .{ .sbb, .mi, .rm64, .imm8, .none, .none, 1, 0x83, 0x00, 0x00, 3, .long },
396 .{ .sbb, .mr, .rm8, .r8, .none, .none, 1, 0x18, 0x00, 0x00, 0, .none },
397 .{ .sbb, .mr, .rm16, .r16, .none, .none, 1, 0x19, 0x00, 0x00, 0, .none },
398 .{ .sbb, .mr, .rm32, .r32, .none, .none, 1, 0x19, 0x00, 0x00, 0, .none },
399 .{ .sbb, .mr, .rm64, .r64, .none, .none, 1, 0x19, 0x00, 0x00, 0, .long },
400 .{ .sbb, .rm, .r8, .rm8, .none, .none, 1, 0x1a, 0x00, 0x00, 0, .none },
401 .{ .sbb, .rm, .r16, .rm16, .none, .none, 1, 0x1b, 0x00, 0x00, 0, .none },
402 .{ .sbb, .rm, .r32, .rm32, .none, .none, 1, 0x1b, 0x00, 0x00, 0, .none },
403 .{ .sbb, .rm, .r64, .rm64, .none, .none, 1, 0x1b, 0x00, 0x00, 0, .long },
385 .{ .sbb, .zi, .al, .imm8, .none, .none, 1, 0x1c, 0x00, 0x00, 0, .none },
386 .{ .sbb, .zi, .ax, .imm16, .none, .none, 1, 0x1d, 0x00, 0x00, 0, .none },
387 .{ .sbb, .zi, .eax, .imm32, .none, .none, 1, 0x1d, 0x00, 0x00, 0, .none },
388 .{ .sbb, .zi, .rax, .imm32s, .none, .none, 1, 0x1d, 0x00, 0x00, 0, .long },
389 .{ .sbb, .mi, .rm8, .imm8, .none, .none, 1, 0x80, 0x00, 0x00, 3, .none },
390 .{ .sbb, .mi, .rm16, .imm16, .none, .none, 1, 0x81, 0x00, 0x00, 3, .none },
391 .{ .sbb, .mi, .rm32, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 3, .none },
392 .{ .sbb, .mi, .rm64, .imm32s, .none, .none, 1, 0x81, 0x00, 0x00, 3, .long },
393 .{ .sbb, .mi, .rm16, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 3, .none },
394 .{ .sbb, .mi, .rm32, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 3, .none },
395 .{ .sbb, .mi, .rm64, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 3, .long },
396 .{ .sbb, .mr, .rm8, .r8, .none, .none, 1, 0x18, 0x00, 0x00, 0, .none },
397 .{ .sbb, .mr, .rm16, .r16, .none, .none, 1, 0x19, 0x00, 0x00, 0, .none },
398 .{ .sbb, .mr, .rm32, .r32, .none, .none, 1, 0x19, 0x00, 0x00, 0, .none },
399 .{ .sbb, .mr, .rm64, .r64, .none, .none, 1, 0x19, 0x00, 0x00, 0, .long },
400 .{ .sbb, .rm, .r8, .rm8, .none, .none, 1, 0x1a, 0x00, 0x00, 0, .none },
401 .{ .sbb, .rm, .r16, .rm16, .none, .none, 1, 0x1b, 0x00, 0x00, 0, .none },
402 .{ .sbb, .rm, .r32, .rm32, .none, .none, 1, 0x1b, 0x00, 0x00, 0, .none },
403 .{ .sbb, .rm, .r64, .rm64, .none, .none, 1, 0x1b, 0x00, 0x00, 0, .long },
404404
405405 .{ .seta, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x97, 0x00, 0, .none },
406406 .{ .setae, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x93, 0x00, 0, .none },
......@@ -459,62 +459,62 @@ pub const table = &[_]Entry{
459459 .{ .shr, .mi, .rm32, .imm8, .none, .none, 1, 0xc1, 0x00, 0x00, 5, .none },
460460 .{ .shr, .mi, .rm64, .imm8, .none, .none, 1, 0xc1, 0x00, 0x00, 5, .long },
461461
462 .{ .sub, .zi, .al, .imm8, .none, .none, 1, 0x2c, 0x00, 0x00, 0, .none },
463 .{ .sub, .zi, .ax, .imm16, .none, .none, 1, 0x2d, 0x00, 0x00, 0, .none },
464 .{ .sub, .zi, .eax, .imm32, .none, .none, 1, 0x2d, 0x00, 0x00, 0, .none },
465 .{ .sub, .zi, .rax, .imm32, .none, .none, 1, 0x2d, 0x00, 0x00, 0, .long },
466 .{ .sub, .mi, .rm8, .imm8, .none, .none, 1, 0x80, 0x00, 0x00, 5, .none },
467 .{ .sub, .mi, .rm16, .imm16, .none, .none, 1, 0x81, 0x00, 0x00, 5, .none },
468 .{ .sub, .mi, .rm32, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 5, .none },
469 .{ .sub, .mi, .rm64, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 5, .long },
470 .{ .sub, .mi, .rm16, .imm8, .none, .none, 1, 0x83, 0x00, 0x00, 5, .none },
471 .{ .sub, .mi, .rm32, .imm8, .none, .none, 1, 0x83, 0x00, 0x00, 5, .none },
472 .{ .sub, .mi, .rm64, .imm8, .none, .none, 1, 0x83, 0x00, 0x00, 5, .long },
473 .{ .sub, .mr, .rm8, .r8, .none, .none, 1, 0x28, 0x00, 0x00, 0, .none },
474 .{ .sub, .mr, .rm16, .r16, .none, .none, 1, 0x29, 0x00, 0x00, 0, .none },
475 .{ .sub, .mr, .rm32, .r32, .none, .none, 1, 0x29, 0x00, 0x00, 0, .none },
476 .{ .sub, .mr, .rm64, .r64, .none, .none, 1, 0x29, 0x00, 0x00, 0, .long },
477 .{ .sub, .rm, .r8, .rm8, .none, .none, 1, 0x2a, 0x00, 0x00, 0, .none },
478 .{ .sub, .rm, .r16, .rm16, .none, .none, 1, 0x2b, 0x00, 0x00, 0, .none },
479 .{ .sub, .rm, .r32, .rm32, .none, .none, 1, 0x2b, 0x00, 0x00, 0, .none },
480 .{ .sub, .rm, .r64, .rm64, .none, .none, 1, 0x2b, 0x00, 0x00, 0, .long },
462 .{ .sub, .zi, .al, .imm8, .none, .none, 1, 0x2c, 0x00, 0x00, 0, .none },
463 .{ .sub, .zi, .ax, .imm16, .none, .none, 1, 0x2d, 0x00, 0x00, 0, .none },
464 .{ .sub, .zi, .eax, .imm32, .none, .none, 1, 0x2d, 0x00, 0x00, 0, .none },
465 .{ .sub, .zi, .rax, .imm32s, .none, .none, 1, 0x2d, 0x00, 0x00, 0, .long },
466 .{ .sub, .mi, .rm8, .imm8, .none, .none, 1, 0x80, 0x00, 0x00, 5, .none },
467 .{ .sub, .mi, .rm16, .imm16, .none, .none, 1, 0x81, 0x00, 0x00, 5, .none },
468 .{ .sub, .mi, .rm32, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 5, .none },
469 .{ .sub, .mi, .rm64, .imm32s, .none, .none, 1, 0x81, 0x00, 0x00, 5, .long },
470 .{ .sub, .mi, .rm16, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 5, .none },
471 .{ .sub, .mi, .rm32, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 5, .none },
472 .{ .sub, .mi, .rm64, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 5, .long },
473 .{ .sub, .mr, .rm8, .r8, .none, .none, 1, 0x28, 0x00, 0x00, 0, .none },
474 .{ .sub, .mr, .rm16, .r16, .none, .none, 1, 0x29, 0x00, 0x00, 0, .none },
475 .{ .sub, .mr, .rm32, .r32, .none, .none, 1, 0x29, 0x00, 0x00, 0, .none },
476 .{ .sub, .mr, .rm64, .r64, .none, .none, 1, 0x29, 0x00, 0x00, 0, .long },
477 .{ .sub, .rm, .r8, .rm8, .none, .none, 1, 0x2a, 0x00, 0x00, 0, .none },
478 .{ .sub, .rm, .r16, .rm16, .none, .none, 1, 0x2b, 0x00, 0x00, 0, .none },
479 .{ .sub, .rm, .r32, .rm32, .none, .none, 1, 0x2b, 0x00, 0x00, 0, .none },
480 .{ .sub, .rm, .r64, .rm64, .none, .none, 1, 0x2b, 0x00, 0x00, 0, .long },
481481
482482 .{ .syscall, .np, .none, .none, .none, .none, 2, 0x0f, 0x05, 0x00, 0, .none },
483483
484 .{ .@"test", .zi, .al, .imm8, .none, .none, 1, 0xa8, 0x00, 0x00, 0, .none },
485 .{ .@"test", .zi, .ax, .imm16, .none, .none, 1, 0xa9, 0x00, 0x00, 0, .none },
486 .{ .@"test", .zi, .eax, .imm32, .none, .none, 1, 0xa9, 0x00, 0x00, 0, .none },
487 .{ .@"test", .zi, .rax, .imm32, .none, .none, 1, 0xa9, 0x00, 0x00, 0, .long },
488 .{ .@"test", .mi, .rm8, .imm8, .none, .none, 1, 0xf6, 0x00, 0x00, 0, .none },
489 .{ .@"test", .mi, .rm16, .imm16, .none, .none, 1, 0xf7, 0x00, 0x00, 0, .none },
490 .{ .@"test", .mi, .rm32, .imm32, .none, .none, 1, 0xf7, 0x00, 0x00, 0, .none },
491 .{ .@"test", .mi, .rm64, .imm32, .none, .none, 1, 0xf7, 0x00, 0x00, 0, .long },
492 .{ .@"test", .mr, .rm8, .r8, .none, .none, 1, 0x84, 0x00, 0x00, 0, .none },
493 .{ .@"test", .mr, .rm16, .r16, .none, .none, 1, 0x85, 0x00, 0x00, 0, .none },
494 .{ .@"test", .mr, .rm32, .r32, .none, .none, 1, 0x85, 0x00, 0x00, 0, .none },
495 .{ .@"test", .mr, .rm64, .r64, .none, .none, 1, 0x85, 0x00, 0x00, 0, .long },
496
497 .{ .ud2, .np, .none, .none, .none, .none, 2, 0x0f, 0x0b, 0x00, 0, .none },
498
499 .{ .xor, .zi, .al, .imm8, .none, .none, 1, 0x34, 0x00, 0x00, 0, .none },
500 .{ .xor, .zi, .ax, .imm16, .none, .none, 1, 0x35, 0x00, 0x00, 0, .none },
501 .{ .xor, .zi, .eax, .imm32, .none, .none, 1, 0x35, 0x00, 0x00, 0, .none },
502 .{ .xor, .zi, .rax, .imm32, .none, .none, 1, 0x35, 0x00, 0x00, 0, .long },
503 .{ .xor, .mi, .rm8, .imm8, .none, .none, 1, 0x80, 0x00, 0x00, 6, .none },
504 .{ .xor, .mi, .rm16, .imm16, .none, .none, 1, 0x81, 0x00, 0x00, 6, .none },
505 .{ .xor, .mi, .rm32, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 6, .none },
506 .{ .xor, .mi, .rm64, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 6, .long },
507 .{ .xor, .mi, .rm16, .imm8, .none, .none, 1, 0x83, 0x00, 0x00, 6, .none },
508 .{ .xor, .mi, .rm32, .imm8, .none, .none, 1, 0x83, 0x00, 0x00, 6, .none },
509 .{ .xor, .mi, .rm64, .imm8, .none, .none, 1, 0x83, 0x00, 0x00, 6, .long },
510 .{ .xor, .mr, .rm8, .r8, .none, .none, 1, 0x30, 0x00, 0x00, 0, .none },
511 .{ .xor, .mr, .rm16, .r16, .none, .none, 1, 0x31, 0x00, 0x00, 0, .none },
512 .{ .xor, .mr, .rm32, .r32, .none, .none, 1, 0x31, 0x00, 0x00, 0, .none },
513 .{ .xor, .mr, .rm64, .r64, .none, .none, 1, 0x31, 0x00, 0x00, 0, .long },
514 .{ .xor, .rm, .r8, .rm8, .none, .none, 1, 0x32, 0x00, 0x00, 0, .none },
515 .{ .xor, .rm, .r16, .rm16, .none, .none, 1, 0x33, 0x00, 0x00, 0, .none },
516 .{ .xor, .rm, .r32, .rm32, .none, .none, 1, 0x33, 0x00, 0x00, 0, .none },
517 .{ .xor, .rm, .r64, .rm64, .none, .none, 1, 0x33, 0x00, 0x00, 0, .long },
484 .{ .@"test", .zi, .al, .imm8, .none, .none, 1, 0xa8, 0x00, 0x00, 0, .none },
485 .{ .@"test", .zi, .ax, .imm16, .none, .none, 1, 0xa9, 0x00, 0x00, 0, .none },
486 .{ .@"test", .zi, .eax, .imm32, .none, .none, 1, 0xa9, 0x00, 0x00, 0, .none },
487 .{ .@"test", .zi, .rax, .imm32s, .none, .none, 1, 0xa9, 0x00, 0x00, 0, .long },
488 .{ .@"test", .mi, .rm8, .imm8, .none, .none, 1, 0xf6, 0x00, 0x00, 0, .none },
489 .{ .@"test", .mi, .rm16, .imm16, .none, .none, 1, 0xf7, 0x00, 0x00, 0, .none },
490 .{ .@"test", .mi, .rm32, .imm32, .none, .none, 1, 0xf7, 0x00, 0x00, 0, .none },
491 .{ .@"test", .mi, .rm64, .imm32s, .none, .none, 1, 0xf7, 0x00, 0x00, 0, .long },
492 .{ .@"test", .mr, .rm8, .r8, .none, .none, 1, 0x84, 0x00, 0x00, 0, .none },
493 .{ .@"test", .mr, .rm16, .r16, .none, .none, 1, 0x85, 0x00, 0x00, 0, .none },
494 .{ .@"test", .mr, .rm32, .r32, .none, .none, 1, 0x85, 0x00, 0x00, 0, .none },
495 .{ .@"test", .mr, .rm64, .r64, .none, .none, 1, 0x85, 0x00, 0x00, 0, .long },
496
497 .{ .ud2, .np, .none, .none, .none, .none, 2, 0x0f, 0x0b, 0x00, 0, .none },
498
499 .{ .xor, .zi, .al, .imm8, .none, .none, 1, 0x34, 0x00, 0x00, 0, .none },
500 .{ .xor, .zi, .ax, .imm16, .none, .none, 1, 0x35, 0x00, 0x00, 0, .none },
501 .{ .xor, .zi, .eax, .imm32, .none, .none, 1, 0x35, 0x00, 0x00, 0, .none },
502 .{ .xor, .zi, .rax, .imm32s, .none, .none, 1, 0x35, 0x00, 0x00, 0, .long },
503 .{ .xor, .mi, .rm8, .imm8, .none, .none, 1, 0x80, 0x00, 0x00, 6, .none },
504 .{ .xor, .mi, .rm16, .imm16, .none, .none, 1, 0x81, 0x00, 0x00, 6, .none },
505 .{ .xor, .mi, .rm32, .imm32, .none, .none, 1, 0x81, 0x00, 0x00, 6, .none },
506 .{ .xor, .mi, .rm64, .imm32s, .none, .none, 1, 0x81, 0x00, 0x00, 6, .long },
507 .{ .xor, .mi, .rm16, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 6, .none },
508 .{ .xor, .mi, .rm32, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 6, .none },
509 .{ .xor, .mi, .rm64, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 6, .long },
510 .{ .xor, .mr, .rm8, .r8, .none, .none, 1, 0x30, 0x00, 0x00, 0, .none },
511 .{ .xor, .mr, .rm16, .r16, .none, .none, 1, 0x31, 0x00, 0x00, 0, .none },
512 .{ .xor, .mr, .rm32, .r32, .none, .none, 1, 0x31, 0x00, 0x00, 0, .none },
513 .{ .xor, .mr, .rm64, .r64, .none, .none, 1, 0x31, 0x00, 0x00, 0, .long },
514 .{ .xor, .rm, .r8, .rm8, .none, .none, 1, 0x32, 0x00, 0x00, 0, .none },
515 .{ .xor, .rm, .r16, .rm16, .none, .none, 1, 0x33, 0x00, 0x00, 0, .none },
516 .{ .xor, .rm, .r32, .rm32, .none, .none, 1, 0x33, 0x00, 0x00, 0, .none },
517 .{ .xor, .rm, .r64, .rm64, .none, .none, 1, 0x33, 0x00, 0x00, 0, .long },
518518
519519 // SSE
520520 .{ .addss, .rm, .xmm, .xmm_m32, .none, .none, 3, 0xf3, 0x0f, 0x58, 0, .sse },
......@@ -540,3 +540,4 @@ pub const table = &[_]Entry{
540540 .{ .ucomisd, .rm, .xmm, .xmm_m64, .none, .none, 3, 0x66, 0x0f, 0x2e, 0, .sse2 },
541541};
542542// zig fmt: on
543