authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-03-26 21:33:56-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-03-27 05:58:00-04:00
logabb37a7cb8d4bfae2da6d2cb9e9e6305ef6e52c4
treefb30cd3257f76d7026d1fd930c8157b959b50e38
parent0e5e001278465e508130eb159327e6aa11895f1c

x86_64: factor out lowering from emitting


8 files changed, 2167 insertions(+), 2127 deletions(-)

src/arch/x86_64/CodeGen.zig+9-12
...@@ -341,19 +341,22 @@ pub fn generate(...@@ -341,19 +341,22 @@ pub fn generate(
341 defer mir.deinit(bin_file.allocator);341 defer mir.deinit(bin_file.allocator);
342342
343 var emit = Emit{343 var emit = Emit{
344 .mir = mir,344 .lower = .{
345 .allocator = bin_file.allocator,
346 .mir = mir,
347 .target = &bin_file.options.target,
348 .src_loc = src_loc,
349 },
345 .bin_file = bin_file,350 .bin_file = bin_file,
346 .debug_output = debug_output,351 .debug_output = debug_output,
347 .target = &bin_file.options.target,
348 .src_loc = src_loc,
349 .code = code,352 .code = code,
350 .prev_di_pc = 0,353 .prev_di_pc = 0,
351 .prev_di_line = module_fn.lbrace_line,354 .prev_di_line = module_fn.lbrace_line,
352 .prev_di_column = module_fn.lbrace_column,355 .prev_di_column = module_fn.lbrace_column,
353 };356 };
354 defer emit.deinit();357 defer emit.deinit();
355 emit.lowerMir() catch |err| switch (err) {358 emit.emitMir() catch |err| switch (err) {
356 error.EmitFail => return Result{ .fail = emit.err_msg.? },359 error.LowerFail, error.EmitFail => return Result{ .fail = emit.lower.err_msg.? },
357 error.InvalidInstruction, error.CannotEncode => |e| {360 error.InvalidInstruction, error.CannotEncode => |e| {
358 const msg = switch (e) {361 const msg = switch (e) {
359 error.InvalidInstruction => "CodeGen failed to find a viable instruction.",362 error.InvalidInstruction => "CodeGen failed to find a viable instruction.",
...@@ -7070,16 +7073,10 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void...@@ -7070,16 +7073,10 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
7070 if (reg.to64() == .rax) {7073 if (reg.to64() == .rax) {
7071 // If this is RAX, we can use a direct load.7074 // If this is RAX, we can use a direct load.
7072 // Otherwise, we need to load the address, then indirectly load the value.7075 // Otherwise, we need to load the address, then indirectly load the value.
7073 var moffs: Mir.MemoryMoffs = .{
7074 .seg = @enumToInt(Register.ds),
7075 .msb = undefined,
7076 .lsb = undefined,
7077 };
7078 moffs.encodeOffset(x);
7079 _ = try self.addInst(.{7076 _ = try self.addInst(.{
7080 .tag = .mov_moffs,7077 .tag = .mov_moffs,
7081 .ops = .rax_moffs,7078 .ops = .rax_moffs,
7082 .data = .{ .payload = try self.addExtra(moffs) },7079 .data = .{ .payload = try self.addExtra(Mir.MemoryMoffs.encode(.ds, x)) },
7083 });7080 });
7084 } else {7081 } else {
7085 // Rather than duplicate the logic used for the move, we just use a self-call with a new MCValue.7082 // Rather than duplicate the logic used for the move, we just use a self-call with a new MCValue.
src/arch/x86_64/Emit.zig+168-737
...@@ -1,40 +1,8 @@...@@ -1,40 +1,8 @@
1//! This file contains the functionality for lowering x86_64 MIR into1//! This file contains the functionality for emitting x86_64 MIR as machine code
2//! machine code
32
4const Emit = @This();3lower: Lower,
5
6const std = @import("std");
7const assert = std.debug.assert;
8const bits = @import("bits.zig");
9const abi = @import("abi.zig");
10const encoder = @import("encoder.zig");
11const link = @import("../../link.zig");
12const log = std.log.scoped(.codegen);
13const math = std.math;
14const mem = std.mem;
15const testing = std.testing;
16
17const Air = @import("../../Air.zig");
18const Allocator = mem.Allocator;
19const CodeGen = @import("CodeGen.zig");
20const DebugInfoOutput = @import("../../codegen.zig").DebugInfoOutput;
21const Encoder = bits.Encoder;
22const ErrorMsg = Module.ErrorMsg;
23const Immediate = bits.Immediate;
24const Instruction = encoder.Instruction;
25const MCValue = @import("CodeGen.zig").MCValue;
26const Memory = bits.Memory;
27const Mir = @import("Mir.zig");
28const Module = @import("../../Module.zig");
29const Register = bits.Register;
30const Type = @import("../../type.zig").Type;
31
32mir: Mir,
33bin_file: *link.File,4bin_file: *link.File,
34debug_output: DebugInfoOutput,5debug_output: DebugInfoOutput,
35target: *const std.Target,
36err_msg: ?*ErrorMsg = null,
37src_loc: Module.SrcLoc,
38code: *std.ArrayList(u8),6code: *std.ArrayList(u8),
397
40prev_di_line: u32,8prev_di_line: u32,
...@@ -45,166 +13,176 @@ prev_di_pc: usize,...@@ -45,166 +13,176 @@ prev_di_pc: usize,
45code_offset_mapping: std.AutoHashMapUnmanaged(Mir.Inst.Index, usize) = .{},13code_offset_mapping: std.AutoHashMapUnmanaged(Mir.Inst.Index, usize) = .{},
46relocs: std.ArrayListUnmanaged(Reloc) = .{},14relocs: std.ArrayListUnmanaged(Reloc) = .{},
4715
48const InnerError = error{16pub const Error = Lower.Error || error{EmitFail};
49 OutOfMemory,17
50 EmitFail,18pub fn emitMir(emit: *Emit) Error!void {
51 InvalidInstruction,19 for (0..emit.lower.mir.instructions.len) |i| {
52 CannotEncode,20 const index = @intCast(Mir.Inst.Index, i);
53};21 const inst = emit.lower.mir.instructions.get(index);
5422
55const Reloc = struct {23 const start_offset = @intCast(u32, emit.code.items.len);
56 /// Offset of the instruction.24 try emit.code_offset_mapping.putNoClobber(emit.lower.allocator, index, start_offset);
57 source: usize,25 for (try emit.lower.lowerMir(inst)) |lower_inst| try lower_inst.encode(emit.code.writer());
58 /// Target of the relocation.26 const end_offset = @intCast(u32, emit.code.items.len);
59 target: Mir.Inst.Index,27
60 /// Offset of the relocation within the instruction.28 switch (inst.tag) {
61 offset: usize,29 else => {},
62 /// Length of the instruction.30
63 length: u5,31 .jmp_reloc => try emit.relocs.append(emit.lower.allocator, .{
64};32 .source = start_offset,
6533 .target = inst.data.inst,
66pub fn lowerMir(emit: *Emit) InnerError!void {34 .offset = end_offset - 4,
67 const mir_tags = emit.mir.instructions.items(.tag);35 .length = 5,
6836 }),
69 for (mir_tags, 0..) |tag, index| {37
70 const inst = @intCast(u32, index);38 .call_extern => if (emit.bin_file.cast(link.File.MachO)) |macho_file| {
71 try emit.code_offset_mapping.putNoClobber(emit.bin_file.allocator, inst, emit.code.items.len);39 // Add relocation to the decl.
72 switch (tag) {40 const atom_index = macho_file.getAtomIndexForSymbol(
73 .adc,41 .{ .sym_index = inst.data.relocation.atom_index, .file = null },
74 .add,42 ).?;
75 .@"and",43 const target = macho_file.getGlobalByIndex(inst.data.relocation.sym_index);
76 .bsf,44 try link.File.MachO.Atom.addRelocation(macho_file, atom_index, .{
77 .bsr,45 .type = @enumToInt(std.macho.reloc_type_x86_64.X86_64_RELOC_BRANCH),
78 .bswap,46 .target = target,
79 .bt,47 .offset = end_offset - 4,
80 .btc,48 .addend = 0,
81 .btr,49 .pcrel = true,
82 .bts,50 .length = 2,
83 .call,51 });
84 .cbw,52 } else if (emit.bin_file.cast(link.File.Coff)) |coff_file| {
85 .cwde,53 // Add relocation to the decl.
86 .cdqe,54 const atom_index = coff_file.getAtomIndexForSymbol(
87 .cwd,55 .{ .sym_index = inst.data.relocation.atom_index, .file = null },
88 .cdq,56 ).?;
89 .cqo,57 const target = coff_file.getGlobalByIndex(inst.data.relocation.sym_index);
90 .cmp,58 try link.File.Coff.Atom.addRelocation(coff_file, atom_index, .{
91 .cmpxchg,59 .type = .direct,
92 .div,60 .target = target,
93 .fisttp,61 .offset = end_offset - 4,
94 .fld,62 .addend = 0,
95 .idiv,63 .pcrel = true,
96 .imul,64 .length = 2,
97 .int3,65 });
98 .jmp,66 } else return emit.fail("TODO implement {} for {}", .{ inst.tag, emit.bin_file.tag }),
99 .lea,67
100 .lfence,68 .lea_linker => if (emit.bin_file.cast(link.File.MachO)) |macho_file| {
101 .lzcnt,69 const metadata =
102 .mfence,70 emit.lower.mir.extraData(Mir.LeaRegisterReloc, inst.data.payload).data;
103 .mov,71 const reloc_type = switch (inst.ops) {
104 .movbe,72 .got_reloc => @enumToInt(std.macho.reloc_type_x86_64.X86_64_RELOC_GOT),
105 .movzx,73 .direct_reloc => @enumToInt(std.macho.reloc_type_x86_64.X86_64_RELOC_SIGNED),
106 .mul,74 else => unreachable,
107 .neg,75 };
108 .nop,76 const atom_index = macho_file.getAtomIndexForSymbol(.{
109 .not,77 .sym_index = metadata.atom_index,
110 .@"or",78 .file = null,
111 .pop,79 }).?;
112 .popcnt,80 try link.File.MachO.Atom.addRelocation(macho_file, atom_index, .{
113 .push,81 .type = reloc_type,
114 .rcl,82 .target = .{ .sym_index = metadata.sym_index, .file = null },
115 .rcr,83 .offset = @intCast(u32, end_offset - 4),
116 .ret,84 .addend = 0,
117 .rol,85 .pcrel = true,
118 .ror,86 .length = 2,
119 .sal,87 });
120 .sar,88 } else if (emit.bin_file.cast(link.File.Coff)) |coff_file| {
121 .sbb,89 const metadata =
122 .sfence,90 emit.lower.mir.extraData(Mir.LeaRegisterReloc, inst.data.payload).data;
123 .shl,91 const atom_index = coff_file.getAtomIndexForSymbol(.{
124 .shld,92 .sym_index = metadata.atom_index,
125 .shr,93 .file = null,
126 .shrd,94 }).?;
127 .sub,95 try link.File.Coff.Atom.addRelocation(coff_file, atom_index, .{
128 .syscall,96 .type = switch (inst.ops) {
129 .@"test",97 .got_reloc => .got,
130 .tzcnt,98 .direct_reloc => .direct,
131 .ud2,99 .import_reloc => .import,
132 .xadd,100 else => unreachable,
133 .xchg,101 },
134 .xor,102 .target = switch (inst.ops) {
135103 .got_reloc,
136 .addss,104 .direct_reloc,
137 .cmpss,105 => .{ .sym_index = metadata.sym_index, .file = null },
138 .divss,106 .import_reloc => coff_file.getGlobalByIndex(metadata.sym_index),
139 .maxss,107 else => unreachable,
140 .minss,108 },
141 .movss,109 .offset = @intCast(u32, end_offset - 4),
142 .mulss,110 .addend = 0,
143 .roundss,111 .pcrel = true,
144 .subss,112 .length = 2,
145 .ucomiss,113 });
146 .addsd,114 } else return emit.fail("TODO implement {} for {}", .{ inst.tag, emit.bin_file.tag }),
147 .cmpsd,115
148 .divsd,116 .jcc => try emit.relocs.append(emit.lower.allocator, .{
149 .maxsd,117 .source = start_offset,
150 .minsd,118 .target = inst.data.inst_cc.inst,
151 .movsd,119 .offset = end_offset - 4,
152 .mulsd,120 .length = 6,
153 .roundsd,121 }),
154 .subsd,
155 .ucomisd,
156 => try emit.mirEncodeGeneric(tag, inst),
157
158 .cmps,
159 .lods,
160 .movs,
161 .scas,
162 .stos,
163 => try emit.mirString(tag, inst),
164
165 .cmpxchgb => try emit.mirCmpxchgBytes(inst),
166
167 .jmp_reloc => try emit.mirJmpReloc(inst),
168
169 .call_extern => try emit.mirCallExtern(inst),
170
171 .lea_linker => try emit.mirLeaLinker(inst),
172
173 .mov_moffs => try emit.mirMovMoffs(inst),
174
175 .movsx => try emit.mirMovsx(inst),
176 .cmovcc => try emit.mirCmovcc(inst),
177 .setcc => try emit.mirSetcc(inst),
178 .jcc => try emit.mirJcc(inst),
179122
180 .dbg_line => try emit.mirDbgLine(inst),123 .dbg_line => {
181 .dbg_prologue_end => try emit.mirDbgPrologueEnd(inst),124 const dbg_line_column =
182 .dbg_epilogue_begin => try emit.mirDbgEpilogueBegin(inst),125 emit.lower.mir.extraData(Mir.DbgLineColumn, inst.data.payload).data;
126 try emit.dbgAdvancePCAndLine(dbg_line_column.line, dbg_line_column.column);
127 },
183128
184 .push_regs => try emit.mirPushPopRegisterList(.push, inst),129 .dbg_prologue_end => {
185 .pop_regs => try emit.mirPushPopRegisterList(.pop, inst),130 switch (emit.debug_output) {
131 .dwarf => |dw| {
132 try dw.setPrologueEnd();
133 log.debug("mirDbgPrologueEnd (line={d}, col={d})", .{
134 emit.prev_di_line, emit.prev_di_column,
135 });
136 try emit.dbgAdvancePCAndLine(emit.prev_di_line, emit.prev_di_column);
137 },
138 .plan9 => {},
139 .none => {},
140 }
141 },
186142
187 .dead => {},143 .dbg_epilogue_begin => {
144 switch (emit.debug_output) {
145 .dwarf => |dw| {
146 try dw.setEpilogueBegin();
147 log.debug("mirDbgEpilogueBegin (line={d}, col={d})", .{
148 emit.prev_di_line, emit.prev_di_column,
149 });
150 try emit.dbgAdvancePCAndLine(emit.prev_di_line, emit.prev_di_column);
151 },
152 .plan9 => {},
153 .none => {},
154 }
155 },
188 }156 }
189 }157 }
190
191 try emit.fixupRelocs();158 try emit.fixupRelocs();
192}159}
193160
194pub fn deinit(emit: *Emit) void {161pub fn deinit(emit: *Emit) void {
195 emit.relocs.deinit(emit.bin_file.allocator);162 emit.relocs.deinit(emit.lower.allocator);
196 emit.code_offset_mapping.deinit(emit.bin_file.allocator);163 emit.code_offset_mapping.deinit(emit.lower.allocator);
197 emit.* = undefined;164 emit.* = undefined;
198}165}
199166
200fn fail(emit: *Emit, comptime format: []const u8, args: anytype) InnerError {167fn fail(emit: *Emit, comptime format: []const u8, args: anytype) Error {
201 @setCold(true);168 return switch (emit.lower.fail(format, args)) {
202 assert(emit.err_msg == null);169 error.LowerFail => error.EmitFail,
203 emit.err_msg = try ErrorMsg.create(emit.bin_file.allocator, emit.src_loc, format, args);170 else => |e| e,
204 return error.EmitFail;171 };
205}172}
206173
207fn fixupRelocs(emit: *Emit) InnerError!void {174const Reloc = struct {
175 /// Offset of the instruction.
176 source: usize,
177 /// Target of the relocation.
178 target: Mir.Inst.Index,
179 /// Offset of the relocation within the instruction.
180 offset: usize,
181 /// Length of the instruction.
182 length: u5,
183};
184
185fn fixupRelocs(emit: *Emit) Error!void {
208 // TODO this function currently assumes all relocs via JMP/CALL instructions are 32bit in size.186 // TODO this function currently assumes all relocs via JMP/CALL instructions are 32bit in size.
209 // This should be reversed like it is done in aarch64 MIR emit code: start with the smallest187 // This should be reversed like it is done in aarch64 MIR emit code: start with the smallest
210 // possible resolution, i.e., 8bit, and iteratively converge on the minimum required resolution188 // possible resolution, i.e., 8bit, and iteratively converge on the minimum required resolution
...@@ -217,532 +195,7 @@ fn fixupRelocs(emit: *Emit) InnerError!void {...@@ -217,532 +195,7 @@ fn fixupRelocs(emit: *Emit) InnerError!void {
217 }195 }
218}196}
219197
220fn encode(emit: *Emit, mnemonic: Instruction.Mnemonic, ops: Instruction.Init) InnerError!void {198fn dbgAdvancePCAndLine(emit: *Emit, line: u32, column: u32) Error!void {
221 const inst = try Instruction.new(mnemonic, ops);
222 return inst.encode(emit.code.writer());
223}
224
225fn mirEncodeGeneric(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) InnerError!void {
226 const mnemonic = inline for (@typeInfo(Instruction.Mnemonic).Enum.fields) |field| {
227 if (mem.eql(u8, field.name, @tagName(tag))) break @field(Instruction.Mnemonic, field.name);
228 } else unreachable;
229
230 const ops = emit.mir.instructions.items(.ops)[inst];
231 const data = emit.mir.instructions.items(.data)[inst];
232
233 const prefix: Instruction.Prefix = switch (ops) {
234 .lock_m_sib,
235 .lock_m_rip,
236 .lock_mi_sib_u,
237 .lock_mi_rip_u,
238 .lock_mi_sib_s,
239 .lock_mi_rip_s,
240 .lock_mr_sib,
241 .lock_mr_rip,
242 .lock_moffs_rax,
243 => .lock,
244 else => .none,
245 };
246
247 var op1: Instruction.Operand = .none;
248 var op2: Instruction.Operand = .none;
249 var op3: Instruction.Operand = .none;
250 var op4: Instruction.Operand = .none;
251
252 switch (ops) {
253 .none => {},
254 .i_s => op1 = .{ .imm = Immediate.s(@bitCast(i32, data.i)) },
255 .i_u => op1 = .{ .imm = Immediate.u(data.i) },
256 .r => op1 = .{ .reg = data.r },
257 .rr => {
258 op1 = .{ .reg = data.rr.r1 };
259 op2 = .{ .reg = data.rr.r2 };
260 },
261 .rrr => {
262 op1 = .{ .reg = data.rrr.r1 };
263 op2 = .{ .reg = data.rrr.r2 };
264 op3 = .{ .reg = data.rrr.r3 };
265 },
266 .ri_s, .ri_u => {
267 const imm = switch (ops) {
268 .ri_s => Immediate.s(@bitCast(i32, data.ri.i)),
269 .ri_u => Immediate.u(data.ri.i),
270 else => unreachable,
271 };
272 op1 = .{ .reg = data.ri.r };
273 op2 = .{ .imm = imm };
274 },
275 .ri64 => {
276 const imm64 = emit.mir.extraData(Mir.Imm64, data.rx.payload).data;
277 op1 = .{ .reg = data.rx.r };
278 op2 = .{ .imm = Immediate.u(Mir.Imm64.decode(imm64)) };
279 },
280 .rri_s, .rri_u => {
281 const imm = switch (ops) {
282 .rri_s => Immediate.s(@bitCast(i32, data.rri.i)),
283 .rri_u => Immediate.u(data.rri.i),
284 else => unreachable,
285 };
286 op1 = .{ .reg = data.rri.r1 };
287 op2 = .{ .reg = data.rri.r2 };
288 op3 = .{ .imm = imm };
289 },
290 .m_sib, .lock_m_sib => {
291 const msib = emit.mir.extraData(Mir.MemorySib, data.payload).data;
292 op1 = .{ .mem = Mir.MemorySib.decode(msib) };
293 },
294 .m_rip, .lock_m_rip => {
295 const mrip = emit.mir.extraData(Mir.MemoryRip, data.payload).data;
296 op1 = .{ .mem = Mir.MemoryRip.decode(mrip) };
297 },
298 .mi_sib_s, .mi_sib_u, .lock_mi_sib_s, .lock_mi_sib_u => {
299 const msib = emit.mir.extraData(Mir.MemorySib, data.ix.payload).data;
300 const imm = switch (ops) {
301 .mi_sib_s, .lock_mi_sib_s => Immediate.s(@bitCast(i32, data.ix.i)),
302 .mi_sib_u, .lock_mi_sib_u => Immediate.u(data.ix.i),
303 else => unreachable,
304 };
305 op1 = .{ .mem = Mir.MemorySib.decode(msib) };
306 op2 = .{ .imm = imm };
307 },
308 .mi_rip_u, .mi_rip_s, .lock_mi_rip_u, .lock_mi_rip_s => {
309 const mrip = emit.mir.extraData(Mir.MemoryRip, data.ix.payload).data;
310 const imm = switch (ops) {
311 .mi_rip_s, .lock_mi_rip_s => Immediate.s(@bitCast(i32, data.ix.i)),
312 .mi_rip_u, .lock_mi_rip_u => Immediate.u(data.ix.i),
313 else => unreachable,
314 };
315 op1 = .{ .mem = Mir.MemoryRip.decode(mrip) };
316 op2 = .{ .imm = imm };
317 },
318 .rm_sib, .mr_sib, .lock_mr_sib => {
319 const msib = emit.mir.extraData(Mir.MemorySib, data.rx.payload).data;
320 const op_r = .{ .reg = data.rx.r };
321 const op_m = .{ .mem = Mir.MemorySib.decode(msib) };
322 switch (ops) {
323 .rm_sib => {
324 op1 = op_r;
325 op2 = op_m;
326 },
327 .mr_sib, .lock_mr_sib => {
328 op1 = op_m;
329 op2 = op_r;
330 },
331 else => unreachable,
332 }
333 },
334 .rm_rip, .mr_rip, .lock_mr_rip => {
335 const mrip = emit.mir.extraData(Mir.MemoryRip, data.rx.payload).data;
336 const op_r = .{ .reg = data.rx.r };
337 const op_m = .{ .mem = Mir.MemoryRip.decode(mrip) };
338 switch (ops) {
339 .rm_rip => {
340 op1 = op_r;
341 op2 = op_m;
342 },
343 .mr_rip, .lock_mr_rip => {
344 op1 = op_m;
345 op2 = op_r;
346 },
347 else => unreachable,
348 }
349 },
350 .mrr_sib => {
351 const msib = emit.mir.extraData(Mir.MemorySib, data.rrx.payload).data;
352 op1 = .{ .mem = Mir.MemorySib.decode(msib) };
353 op2 = .{ .reg = data.rrx.r1 };
354 op2 = .{ .reg = data.rrx.r2 };
355 },
356 .mrr_rip => {
357 const mrip = emit.mir.extraData(Mir.MemoryRip, data.rrx.payload).data;
358 op1 = .{ .mem = Mir.MemoryRip.decode(mrip) };
359 op2 = .{ .reg = data.rrx.r1 };
360 op2 = .{ .reg = data.rrx.r2 };
361 },
362 .mri_sib => {
363 const msib = emit.mir.extraData(Mir.MemorySib, data.rix.payload).data;
364 op1 = .{ .mem = Mir.MemorySib.decode(msib) };
365 op2 = .{ .reg = data.rix.r };
366 op3 = .{ .imm = Immediate.u(data.rix.i) };
367 },
368 .mri_rip => {
369 const mrip = emit.mir.extraData(Mir.MemoryRip, data.rix.payload).data;
370 op1 = .{ .mem = Mir.MemoryRip.decode(mrip) };
371 op2 = .{ .reg = data.rix.r };
372 op3 = .{ .imm = Immediate.u(data.rix.i) };
373 },
374 else => return emit.fail("TODO handle generic encoding: {s}, {s}", .{
375 @tagName(mnemonic),
376 @tagName(ops),
377 }),
378 }
379
380 return emit.encode(mnemonic, .{
381 .prefix = prefix,
382 .op1 = op1,
383 .op2 = op2,
384 .op3 = op3,
385 .op4 = op4,
386 });
387}
388
389fn mirString(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) InnerError!void {
390 const ops = emit.mir.instructions.items(.ops)[inst];
391 switch (ops) {
392 .string => {
393 const data = emit.mir.instructions.items(.data)[inst].string;
394 const mnemonic = switch (tag) {
395 inline .cmps, .lods, .movs, .scas, .stos => |comptime_tag| switch (data.width) {
396 inline else => |comptime_width| @field(
397 Instruction.Mnemonic,
398 @tagName(comptime_tag) ++ @tagName(comptime_width),
399 ),
400 },
401 else => unreachable,
402 };
403 return emit.encode(mnemonic, .{ .prefix = switch (data.repeat) {
404 inline else => |comptime_repeat| @field(Instruction.Prefix, @tagName(comptime_repeat)),
405 } });
406 },
407 else => unreachable,
408 }
409}
410
411fn mirCmpxchgBytes(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
412 const ops = emit.mir.instructions.items(.ops)[inst];
413 const data = emit.mir.instructions.items(.data)[inst];
414
415 var op1: Instruction.Operand = .none;
416 switch (ops) {
417 .m_sib, .lock_m_sib => {
418 const sib = emit.mir.extraData(Mir.MemorySib, data.payload).data;
419 op1 = .{ .mem = Mir.MemorySib.decode(sib) };
420 },
421 .m_rip, .lock_m_rip => {
422 const rip = emit.mir.extraData(Mir.MemoryRip, data.payload).data;
423 op1 = .{ .mem = Mir.MemoryRip.decode(rip) };
424 },
425 else => unreachable,
426 }
427
428 const mnemonic: Instruction.Mnemonic = switch (op1.mem.bitSize()) {
429 64 => .cmpxchg8b,
430 128 => .cmpxchg16b,
431 else => unreachable,
432 };
433
434 return emit.encode(mnemonic, .{
435 .prefix = switch (ops) {
436 .m_sib, .m_rip => .none,
437 .lock_m_sib, .lock_m_rip => .lock,
438 else => unreachable,
439 },
440 .op1 = op1,
441 });
442}
443
444fn mirMovMoffs(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
445 const ops = emit.mir.instructions.items(.ops)[inst];
446 const payload = emit.mir.instructions.items(.data)[inst].payload;
447 const moffs = emit.mir.extraData(Mir.MemoryMoffs, payload).data;
448 const seg = @intToEnum(Register, moffs.seg);
449 const offset = moffs.decodeOffset();
450 switch (ops) {
451 .rax_moffs => {
452 try emit.encode(.mov, .{
453 .op1 = .{ .reg = .rax },
454 .op2 = .{ .mem = Memory.moffs(seg, offset) },
455 });
456 },
457 .moffs_rax, .lock_moffs_rax => {
458 try emit.encode(.mov, .{
459 .prefix = switch (ops) {
460 .moffs_rax => .none,
461 .lock_moffs_rax => .lock,
462 else => unreachable,
463 },
464 .op1 = .{ .mem = Memory.moffs(seg, offset) },
465 .op2 = .{ .reg = .rax },
466 });
467 },
468 else => unreachable,
469 }
470}
471
472fn mirMovsx(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
473 const ops = emit.mir.instructions.items(.ops)[inst];
474 const data = emit.mir.instructions.items(.data)[inst];
475
476 var op1: Instruction.Operand = .none;
477 var op2: Instruction.Operand = .none;
478 switch (ops) {
479 .rr => {
480 op1 = .{ .reg = data.rr.r1 };
481 op2 = .{ .reg = data.rr.r2 };
482 },
483 .rm_sib => {
484 const msib = emit.mir.extraData(Mir.MemorySib, data.rx.payload).data;
485 op1 = .{ .reg = data.rx.r };
486 op2 = .{ .mem = Mir.MemorySib.decode(msib) };
487 },
488 .rm_rip => {
489 const mrip = emit.mir.extraData(Mir.MemoryRip, data.rx.payload).data;
490 op1 = .{ .reg = data.rx.r };
491 op2 = .{ .mem = Mir.MemoryRip.decode(mrip) };
492 },
493 else => unreachable, // TODO
494 }
495
496 const mnemonic: Instruction.Mnemonic = switch (op1.bitSize()) {
497 32, 64 => if (op2.bitSize() == 32) .movsxd else .movsx,
498 else => .movsx,
499 };
500
501 return emit.encode(mnemonic, .{
502 .op1 = op1,
503 .op2 = op2,
504 });
505}
506
507fn mnemonicFromConditionCode(comptime basename: []const u8, cc: bits.Condition) Instruction.Mnemonic {
508 return switch (cc) {
509 inline else => |comptime_cc| @field(Instruction.Mnemonic, basename ++ @tagName(comptime_cc)),
510 };
511}
512
513fn mirCmovcc(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
514 const ops = emit.mir.instructions.items(.ops)[inst];
515 switch (ops) {
516 .rr_cc => {
517 const data = emit.mir.instructions.items(.data)[inst].rr_cc;
518 const mnemonic = mnemonicFromConditionCode("cmov", data.cc);
519 return emit.encode(mnemonic, .{
520 .op1 = .{ .reg = data.r1 },
521 .op2 = .{ .reg = data.r2 },
522 });
523 },
524 .rm_sib_cc => {
525 const data = emit.mir.instructions.items(.data)[inst].rx_cc;
526 const extra = emit.mir.extraData(Mir.MemorySib, data.payload).data;
527 const mnemonic = mnemonicFromConditionCode("cmov", data.cc);
528 return emit.encode(mnemonic, .{
529 .op1 = .{ .reg = data.r },
530 .op2 = .{ .mem = Mir.MemorySib.decode(extra) },
531 });
532 },
533 .rm_rip_cc => {
534 const data = emit.mir.instructions.items(.data)[inst].rx_cc;
535 const extra = emit.mir.extraData(Mir.MemoryRip, data.payload).data;
536 const mnemonic = mnemonicFromConditionCode("cmov", data.cc);
537 return emit.encode(mnemonic, .{
538 .op1 = .{ .reg = data.r },
539 .op2 = .{ .mem = Mir.MemoryRip.decode(extra) },
540 });
541 },
542 else => unreachable,
543 }
544}
545
546fn mirSetcc(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
547 const ops = emit.mir.instructions.items(.ops)[inst];
548 switch (ops) {
549 .r_cc => {
550 const data = emit.mir.instructions.items(.data)[inst].r_cc;
551 const mnemonic = mnemonicFromConditionCode("set", data.cc);
552 return emit.encode(mnemonic, .{
553 .op1 = .{ .reg = data.r },
554 });
555 },
556 .m_sib_cc => {
557 const data = emit.mir.instructions.items(.data)[inst].x_cc;
558 const extra = emit.mir.extraData(Mir.MemorySib, data.payload).data;
559 const mnemonic = mnemonicFromConditionCode("set", data.cc);
560 return emit.encode(mnemonic, .{
561 .op1 = .{ .mem = Mir.MemorySib.decode(extra) },
562 });
563 },
564 .m_rip_cc => {
565 const data = emit.mir.instructions.items(.data)[inst].x_cc;
566 const extra = emit.mir.extraData(Mir.MemoryRip, data.payload).data;
567 const mnemonic = mnemonicFromConditionCode("set", data.cc);
568 return emit.encode(mnemonic, .{
569 .op1 = .{ .mem = Mir.MemoryRip.decode(extra) },
570 });
571 },
572 else => unreachable, // TODO
573 }
574}
575
576fn mirJcc(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
577 const ops = emit.mir.instructions.items(.ops)[inst];
578 switch (ops) {
579 .inst_cc => {
580 const data = emit.mir.instructions.items(.data)[inst].inst_cc;
581 const mnemonic = mnemonicFromConditionCode("j", data.cc);
582 const source = emit.code.items.len;
583 try emit.encode(mnemonic, .{
584 .op1 = .{ .imm = Immediate.s(0) },
585 });
586 try emit.relocs.append(emit.bin_file.allocator, .{
587 .source = source,
588 .target = data.inst,
589 .offset = emit.code.items.len - 4,
590 .length = 6,
591 });
592 },
593 else => unreachable, // TODO
594 }
595}
596
597fn mirJmpReloc(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
598 const target = emit.mir.instructions.items(.data)[inst].inst;
599 const source = emit.code.items.len;
600 try emit.encode(.jmp, .{
601 .op1 = .{ .imm = Immediate.s(0) },
602 });
603 try emit.relocs.append(emit.bin_file.allocator, .{
604 .source = source,
605 .target = target,
606 .offset = emit.code.items.len - 4,
607 .length = 5,
608 });
609}
610
611fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
612 const relocation = emit.mir.instructions.items(.data)[inst].relocation;
613
614 const offset = blk: {
615 try emit.encode(.call, .{
616 .op1 = .{ .imm = Immediate.s(0) },
617 });
618 break :blk @intCast(u32, emit.code.items.len) - 4;
619 };
620
621 if (emit.bin_file.cast(link.File.MachO)) |macho_file| {
622 // Add relocation to the decl.
623 const atom_index = macho_file.getAtomIndexForSymbol(.{ .sym_index = relocation.atom_index, .file = null }).?;
624 const target = macho_file.getGlobalByIndex(relocation.sym_index);
625 try link.File.MachO.Atom.addRelocation(macho_file, atom_index, .{
626 .type = @enumToInt(std.macho.reloc_type_x86_64.X86_64_RELOC_BRANCH),
627 .target = target,
628 .offset = offset,
629 .addend = 0,
630 .pcrel = true,
631 .length = 2,
632 });
633 } else if (emit.bin_file.cast(link.File.Coff)) |coff_file| {
634 // Add relocation to the decl.
635 const atom_index = coff_file.getAtomIndexForSymbol(.{ .sym_index = relocation.atom_index, .file = null }).?;
636 const target = coff_file.getGlobalByIndex(relocation.sym_index);
637 try link.File.Coff.Atom.addRelocation(coff_file, atom_index, .{
638 .type = .direct,
639 .target = target,
640 .offset = offset,
641 .addend = 0,
642 .pcrel = true,
643 .length = 2,
644 });
645 } else {
646 return emit.fail("TODO implement call_extern for linking backends different than MachO and COFF", .{});
647 }
648}
649
650fn mirPushPopRegisterList(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) InnerError!void {
651 const payload = emit.mir.instructions.items(.data)[inst].payload;
652 const save_reg_list = emit.mir.extraData(Mir.SaveRegisterList, payload).data;
653 const base = @intToEnum(Register, save_reg_list.base_reg);
654 var disp: i32 = -@intCast(i32, save_reg_list.stack_end);
655 const reg_list = Mir.RegisterList.fromInt(save_reg_list.register_list);
656 const callee_preserved_regs = abi.getCalleePreservedRegs(emit.target.*);
657 for (callee_preserved_regs) |reg| {
658 if (reg_list.isSet(callee_preserved_regs, reg)) {
659 const op1: Instruction.Operand = .{ .mem = Memory.sib(.qword, .{
660 .base = base,
661 .disp = disp,
662 }) };
663 const op2: Instruction.Operand = .{ .reg = reg };
664 switch (tag) {
665 .push => try emit.encode(.mov, .{
666 .op1 = op1,
667 .op2 = op2,
668 }),
669 .pop => try emit.encode(.mov, .{
670 .op1 = op2,
671 .op2 = op1,
672 }),
673 else => unreachable,
674 }
675 disp += 8;
676 }
677 }
678}
679
680fn mirLeaLinker(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
681 const ops = emit.mir.instructions.items(.ops)[inst];
682 const payload = emit.mir.instructions.items(.data)[inst].payload;
683 const metadata = emit.mir.extraData(Mir.LeaRegisterReloc, payload).data;
684 const reg = @intToEnum(Register, metadata.reg);
685
686 try emit.encode(.lea, .{
687 .op1 = .{ .reg = reg },
688 .op2 = .{ .mem = Memory.rip(Memory.PtrSize.fromBitSize(reg.bitSize()), 0) },
689 });
690
691 const end_offset = emit.code.items.len;
692
693 if (emit.bin_file.cast(link.File.MachO)) |macho_file| {
694 const reloc_type = switch (ops) {
695 .got_reloc => @enumToInt(std.macho.reloc_type_x86_64.X86_64_RELOC_GOT),
696 .direct_reloc => @enumToInt(std.macho.reloc_type_x86_64.X86_64_RELOC_SIGNED),
697 else => unreachable,
698 };
699 const atom_index = macho_file.getAtomIndexForSymbol(.{
700 .sym_index = metadata.atom_index,
701 .file = null,
702 }).?;
703 try link.File.MachO.Atom.addRelocation(macho_file, atom_index, .{
704 .type = reloc_type,
705 .target = .{ .sym_index = metadata.sym_index, .file = null },
706 .offset = @intCast(u32, end_offset - 4),
707 .addend = 0,
708 .pcrel = true,
709 .length = 2,
710 });
711 } else if (emit.bin_file.cast(link.File.Coff)) |coff_file| {
712 const atom_index = coff_file.getAtomIndexForSymbol(.{
713 .sym_index = metadata.atom_index,
714 .file = null,
715 }).?;
716 try link.File.Coff.Atom.addRelocation(coff_file, atom_index, .{
717 .type = switch (ops) {
718 .got_reloc => .got,
719 .direct_reloc => .direct,
720 .import_reloc => .import,
721 else => unreachable,
722 },
723 .target = switch (ops) {
724 .got_reloc, .direct_reloc => .{ .sym_index = metadata.sym_index, .file = null },
725 .import_reloc => coff_file.getGlobalByIndex(metadata.sym_index),
726 else => unreachable,
727 },
728 .offset = @intCast(u32, end_offset - 4),
729 .addend = 0,
730 .pcrel = true,
731 .length = 2,
732 });
733 } else {
734 return emit.fail("TODO implement lea reg, [rip + reloc] for linking backends different than MachO", .{});
735 }
736}
737
738fn mirDbgLine(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
739 const payload = emit.mir.instructions.items(.data)[inst].payload;
740 const dbg_line_column = emit.mir.extraData(Mir.DbgLineColumn, payload).data;
741 log.debug("mirDbgLine", .{});
742 try emit.dbgAdvancePCAndLine(dbg_line_column.line, dbg_line_column.column);
743}
744
745fn dbgAdvancePCAndLine(emit: *Emit, line: u32, column: u32) InnerError!void {
746 const delta_line = @intCast(i32, line) - @intCast(i32, emit.prev_di_line);199 const delta_line = @intCast(i32, line) - @intCast(i32, emit.prev_di_line);
747 const delta_pc: usize = emit.code.items.len - emit.prev_di_pc;200 const delta_pc: usize = emit.code.items.len - emit.prev_di_pc;
748 log.debug(" (advance pc={d} and line={d})", .{ delta_line, delta_pc });201 log.debug(" (advance pc={d} and line={d})", .{ delta_line, delta_pc });
...@@ -756,7 +209,7 @@ fn dbgAdvancePCAndLine(emit: *Emit, line: u32, column: u32) InnerError!void {...@@ -756,7 +209,7 @@ fn dbgAdvancePCAndLine(emit: *Emit, line: u32, column: u32) InnerError!void {
756 .plan9 => |dbg_out| {209 .plan9 => |dbg_out| {
757 if (delta_pc <= 0) return; // only do this when the pc changes210 if (delta_pc <= 0) return; // only do this when the pc changes
758 // we have already checked the target in the linker to make sure it is compatable211 // we have already checked the target in the linker to make sure it is compatable
759 const quant = @import("../../link/Plan9/aout.zig").getPCQuant(emit.target.cpu.arch) catch unreachable;212 const quant = @import("../../link/Plan9/aout.zig").getPCQuant(emit.lower.target.cpu.arch) catch unreachable;
760213
761 // increasing the line number214 // increasing the line number
762 try @import("../../link/Plan9.zig").changeLine(dbg_out.dbg_line, delta_line);215 try @import("../../link/Plan9.zig").changeLine(dbg_out.dbg_line, delta_line);
...@@ -792,34 +245,12 @@ fn dbgAdvancePCAndLine(emit: *Emit, line: u32, column: u32) InnerError!void {...@@ -792,34 +245,12 @@ fn dbgAdvancePCAndLine(emit: *Emit, line: u32, column: u32) InnerError!void {
792 }245 }
793}246}
794247
795fn mirDbgPrologueEnd(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {248const link = @import("../../link.zig");
796 _ = inst;249const log = std.log.scoped(.emit);
797 switch (emit.debug_output) {250const mem = std.mem;
798 .dwarf => |dw| {251const std = @import("std");
799 try dw.setPrologueEnd();
800 log.debug("mirDbgPrologueEnd (line={d}, col={d})", .{
801 emit.prev_di_line,
802 emit.prev_di_column,
803 });
804 try emit.dbgAdvancePCAndLine(emit.prev_di_line, emit.prev_di_column);
805 },
806 .plan9 => {},
807 .none => {},
808 }
809}
810252
811fn mirDbgEpilogueBegin(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {253const DebugInfoOutput = @import("../../codegen.zig").DebugInfoOutput;
812 _ = inst;254const Emit = @This();
813 switch (emit.debug_output) {255const Lower = @import("Lower.zig");
814 .dwarf => |dw| {256const Mir = @import("Mir.zig");
815 try dw.setEpilogueBegin();
816 log.debug("mirDbgEpilogueBegin (line={d}, col={d})", .{
817 emit.prev_di_line,
818 emit.prev_di_column,
819 });
820 try emit.dbgAdvancePCAndLine(emit.prev_di_line, emit.prev_di_column);
821 },
822 .plan9 => {},
823 .none => {},
824 }
825}
src/arch/x86_64/Encoding.zig+137-157
...@@ -7,30 +7,32 @@ const math = std.math;...@@ -7,30 +7,32 @@ const math = std.math;
7const bits = @import("bits.zig");7const bits = @import("bits.zig");
8const encoder = @import("encoder.zig");8const encoder = @import("encoder.zig");
9const Instruction = encoder.Instruction;9const Instruction = encoder.Instruction;
10const Operand = Instruction.Operand;
11const Prefix = Instruction.Prefix;
10const Register = bits.Register;12const Register = bits.Register;
11const Rex = encoder.Rex;13const Rex = encoder.Rex;
12const LegacyPrefixes = encoder.LegacyPrefixes;14const LegacyPrefixes = encoder.LegacyPrefixes;
1315
14const table = @import("encodings.zig").table;
15
16mnemonic: Mnemonic,16mnemonic: Mnemonic,
17op_en: OpEn,17data: Data,
18op1: Op,18
19op2: Op,19const Data = struct {
20op3: Op,20 op_en: OpEn,
21op4: Op,21 ops: [4]Op,
22opc_len: u3,22 opc_len: u3,
23opc: [7]u8,23 opc: [7]u8,
24modrm_ext: u3,24 modrm_ext: u3,
25mode: Mode,25 mode: Mode,
2626};
27pub fn findByMnemonic(mnemonic: Mnemonic, args: Instruction.Init) !?Encoding {27
28 const input_op1 = Op.fromOperand(args.op1);28pub fn findByMnemonic(
29 const input_op2 = Op.fromOperand(args.op2);29 prefix: Instruction.Prefix,
30 const input_op3 = Op.fromOperand(args.op3);30 mnemonic: Mnemonic,
31 const input_op4 = Op.fromOperand(args.op4);31 ops: []const Instruction.Operand,
3232) !?Encoding {
33 const ops = &[_]Instruction.Operand{ args.op1, args.op2, args.op3, args.op4 };33 var input_ops = [1]Op{.none} ** 4;
34 for (input_ops[0..ops.len], ops) |*input_op, op| input_op.* = Op.fromOperand(op);
35
34 const rex_required = for (ops) |op| switch (op) {36 const rex_required = for (ops) |op| switch (op) {
35 .reg => |r| switch (r) {37 .reg => |r| switch (r) {
36 .spl, .bpl, .sil, .dil => break true,38 .spl, .bpl, .sil, .dil => break true,
...@@ -60,88 +62,29 @@ pub fn findByMnemonic(mnemonic: Mnemonic, args: Instruction.Init) !?Encoding {...@@ -60,88 +62,29 @@ pub fn findByMnemonic(mnemonic: Mnemonic, args: Instruction.Init) !?Encoding {
6062
61 if ((rex_required or rex_extended) and rex_invalid) return error.CannotEncode;63 if ((rex_required or rex_extended) and rex_invalid) return error.CannotEncode;
6264
63 // TODO work out what is the maximum number of variants we can actually find in one swoop.65 var shortest_enc: ?Encoding = null;
64 var candidates: [10]Encoding = undefined;66 var shortest_len: ?usize = null;
65 var count: usize = 0;67 next: for (mnemonic_to_encodings_map[@enumToInt(mnemonic)]) |data| {
66 for (table) |entry| {68 switch (data.mode) {
67 var enc = Encoding{69 .rex => if (!rex_required) continue,
68 .mnemonic = entry[0],70 .long => {},
69 .op_en = entry[1],71 else => if (rex_required) continue,
70 .op1 = entry[2],
71 .op2 = entry[3],
72 .op3 = entry[4],
73 .op4 = entry[5],
74 .opc_len = @intCast(u3, entry[6].len),
75 .opc = undefined,
76 .modrm_ext = entry[7],
77 .mode = entry[8],
78 };
79 std.mem.copy(u8, &enc.opc, entry[6]);
80 if (enc.mnemonic == mnemonic and
81 input_op1.isSubset(enc.op1, enc.mode) and
82 input_op2.isSubset(enc.op2, enc.mode) and
83 input_op3.isSubset(enc.op3, enc.mode) and
84 input_op4.isSubset(enc.op4, enc.mode))
85 {
86 if (rex_required) {
87 switch (enc.mode) {
88 .rex, .long => {
89 candidates[count] = enc;
90 count += 1;
91 },
92 else => {},
93 }
94 } else {
95 if (enc.mode != .rex) {
96 candidates[count] = enc;
97 count += 1;
98 }
99 }
100 }72 }
73 for (input_ops, data.ops) |input_op, data_op|
74 if (!input_op.isSubset(data_op, data.mode)) continue :next;
75
76 const enc = Encoding{ .mnemonic = mnemonic, .data = data };
77 if (shortest_enc) |previous_shortest_enc| {
78 const len = estimateInstructionLength(prefix, enc, ops);
79 const previous_shortest_len = shortest_len orelse
80 estimateInstructionLength(prefix, previous_shortest_enc, ops);
81 if (len < previous_shortest_len) {
82 shortest_enc = enc;
83 shortest_len = len;
84 } else shortest_len = previous_shortest_len;
85 } else shortest_enc = enc;
101 }86 }
10287 return shortest_enc;
103 if (count == 0) return null;
104 if (count == 1) return candidates[0];
105
106 const EncodingLength = struct {
107 fn estimate(encoding: Encoding, params: Instruction.Init) usize {
108 var inst = Instruction{
109 .op1 = params.op1,
110 .op2 = params.op2,
111 .op3 = params.op3,
112 .op4 = params.op4,
113 .prefix = params.prefix,
114 .encoding = encoding,
115 };
116 var cwriter = std.io.countingWriter(std.io.null_writer);
117 inst.encode(cwriter.writer()) catch unreachable; // Not allowed to fail here unless OOM.
118 return @intCast(usize, cwriter.bytes_written);
119 }
120 };
121
122 var shortest_encoding: ?struct {
123 index: usize,
124 len: usize,
125 } = null;
126 var i: usize = 0;
127 while (i < count) : (i += 1) {
128 const candidate = candidates[i];
129 switch (candidate.mode) {
130 .long, .rex => if (rex_invalid) return error.CannotEncode,
131 else => {},
132 }
133
134 const len = EncodingLength.estimate(candidate, args);
135 const current = shortest_encoding orelse {
136 shortest_encoding = .{ .index = i, .len = len };
137 continue;
138 };
139 if (len < current.len) {
140 shortest_encoding = .{ .index = i, .len = len };
141 }
142 }
143
144 return candidates[shortest_encoding.?.index];
145}88}
14689
147/// Returns first matching encoding by opcode.90/// Returns first matching encoding by opcode.
...@@ -149,57 +92,45 @@ pub fn findByOpcode(opc: []const u8, prefixes: struct {...@@ -149,57 +92,45 @@ pub fn findByOpcode(opc: []const u8, prefixes: struct {
149 legacy: LegacyPrefixes,92 legacy: LegacyPrefixes,
150 rex: Rex,93 rex: Rex,
151}, modrm_ext: ?u3) ?Encoding {94}, modrm_ext: ?u3) ?Encoding {
152 for (table) |entry| {95 for (mnemonic_to_encodings_map, 0..) |encs, mnemonic_int| for (encs) |data| {
153 const enc = Encoding{96 const enc = Encoding{ .mnemonic = @intToEnum(Mnemonic, mnemonic_int), .data = data };
154 .mnemonic = entry[0],97 if (modrm_ext) |ext| if (ext != data.modrm_ext) continue;
155 .op_en = entry[1],98 if (!std.mem.eql(u8, opc, enc.opcode())) continue;
156 .op1 = entry[2],99 if (prefixes.rex.w) {
157 .op2 = entry[3],100 switch (data.mode) {
158 .op3 = entry[4],101 .short, .fpu, .sse, .sse2, .sse4_1, .none => continue,
159 .op4 = entry[5],102 .long, .rex => {},
160 .opc_len = entry[6],
161 .opc = .{ entry[7], entry[8], entry[9] },
162 .modrm_ext = entry[10],
163 .mode = entry[11],
164 };
165 const match = match: {
166 if (modrm_ext) |ext| {
167 break :match ext == enc.modrm_ext and std.mem.eql(u8, enc.opcode(), opc);
168 }103 }
169 break :match std.mem.eql(u8, enc.opcode(), opc);104 } else if (prefixes.rex.present and !prefixes.rex.isSet()) {
170 };105 switch (data.mode) {
171 if (match) {106 .rex => {},
172 if (prefixes.rex.w) {107 else => continue,
173 switch (enc.mode) {108 }
174 .fpu, .sse, .sse2, .sse4_1, .none => {},109 } else if (prefixes.legacy.prefix_66) {
175 .long, .rex => return enc,110 switch (enc.operandBitSize()) {
176 }111 16 => {},
177 } else if (prefixes.rex.present and !prefixes.rex.isSet()) {112 else => continue,
178 if (enc.mode == .rex) return enc;113 }
179 } else if (prefixes.legacy.prefix_66) {114 } else {
180 switch (enc.operandBitSize()) {115 switch (data.mode) {
181 16 => return enc,116 .none => switch (enc.operandBitSize()) {
117 16 => continue,
182 else => {},118 else => {},
183 }119 },
184 } else {120 else => continue,
185 if (enc.mode == .none) {
186 switch (enc.operandBitSize()) {
187 16 => {},
188 else => return enc,
189 }
190 }
191 }121 }
192 }122 }
193 }123 return enc;
124 };
194 return null;125 return null;
195}126}
196127
197pub fn opcode(encoding: *const Encoding) []const u8 {128pub fn opcode(encoding: *const Encoding) []const u8 {
198 return encoding.opc[0..encoding.opc_len];129 return encoding.data.opc[0..encoding.data.opc_len];
199}130}
200131
201pub fn mandatoryPrefix(encoding: *const Encoding) ?u8 {132pub fn mandatoryPrefix(encoding: *const Encoding) ?u8 {
202 const prefix = encoding.opc[0];133 const prefix = encoding.data.opc[0];
203 return switch (prefix) {134 return switch (prefix) {
204 0x66, 0xf2, 0xf3 => prefix,135 0x66, 0xf2, 0xf3 => prefix,
205 else => null,136 else => null,
...@@ -207,27 +138,27 @@ pub fn mandatoryPrefix(encoding: *const Encoding) ?u8 {...@@ -207,27 +138,27 @@ pub fn mandatoryPrefix(encoding: *const Encoding) ?u8 {
207}138}
208139
209pub fn modRmExt(encoding: Encoding) u3 {140pub fn modRmExt(encoding: Encoding) u3 {
210 return switch (encoding.op_en) {141 return switch (encoding.data.op_en) {
211 .m, .mi, .m1, .mc => encoding.modrm_ext,142 .m, .mi, .m1, .mc => encoding.data.modrm_ext,
212 else => unreachable,143 else => unreachable,
213 };144 };
214}145}
215146
216pub fn operandBitSize(encoding: Encoding) u64 {147pub fn operandBitSize(encoding: Encoding) u64 {
217 switch (encoding.mode) {148 switch (encoding.data.mode) {
218 .short => return 16,149 .short => return 16,
219 .long => return 64,150 .long => return 64,
220 else => {},151 else => {},
221 }152 }
222 const bit_size: u64 = switch (encoding.op_en) {153 const bit_size: u64 = switch (encoding.data.op_en) {
223 .np => switch (encoding.op1) {154 .np => switch (encoding.data.ops[0]) {
224 .o16 => 16,155 .o16 => 16,
225 .o32 => 32,156 .o32 => 32,
226 .o64 => 64,157 .o64 => 64,
227 else => 32,158 else => 32,
228 },159 },
229 .td => encoding.op2.bitSize(),160 .td => encoding.data.ops[1].bitSize(),
230 else => encoding.op1.bitSize(),161 else => encoding.data.ops[0].bitSize(),
231 };162 };
232 return bit_size;163 return bit_size;
233}164}
...@@ -240,7 +171,7 @@ pub fn format(...@@ -240,7 +171,7 @@ pub fn format(
240) !void {171) !void {
241 _ = options;172 _ = options;
242 _ = fmt;173 _ = fmt;
243 switch (encoding.mode) {174 switch (encoding.data.mode) {
244 .long => try writer.writeAll("REX.W + "),175 .long => try writer.writeAll("REX.W + "),
245 else => {},176 else => {},
246 }177 }
...@@ -249,10 +180,10 @@ pub fn format(...@@ -249,10 +180,10 @@ pub fn format(
249 try writer.print("{x:0>2} ", .{byte});180 try writer.print("{x:0>2} ", .{byte});
250 }181 }
251182
252 switch (encoding.op_en) {183 switch (encoding.data.op_en) {
253 .np, .fd, .td, .i, .zi, .d => {},184 .np, .fd, .td, .i, .zi, .d => {},
254 .o, .oi => {185 .o, .oi => {
255 const tag = switch (encoding.op1) {186 const tag = switch (encoding.data.ops[0]) {
256 .r8 => "rb",187 .r8 => "rb",
257 .r16 => "rw",188 .r16 => "rw",
258 .r32 => "rd",189 .r32 => "rd",
...@@ -265,12 +196,12 @@ pub fn format(...@@ -265,12 +196,12 @@ pub fn format(
265 .mr, .rm, .rmi, .mri, .mrc => try writer.writeAll("/r "),196 .mr, .rm, .rmi, .mri, .mrc => try writer.writeAll("/r "),
266 }197 }
267198
268 switch (encoding.op_en) {199 switch (encoding.data.op_en) {
269 .i, .d, .zi, .oi, .mi, .rmi, .mri => {200 .i, .d, .zi, .oi, .mi, .rmi, .mri => {
270 const op = switch (encoding.op_en) {201 const op = switch (encoding.data.op_en) {
271 .i, .d => encoding.op1,202 .i, .d => encoding.data.ops[0],
272 .zi, .oi, .mi => encoding.op2,203 .zi, .oi, .mi => encoding.data.ops[1],
273 .rmi, .mri => encoding.op3,204 .rmi, .mri => encoding.data.ops[2],
274 else => unreachable,205 else => unreachable,
275 };206 };
276 const tag = switch (op) {207 const tag = switch (op) {
...@@ -290,13 +221,12 @@ pub fn format(...@@ -290,13 +221,12 @@ pub fn format(
290221
291 try writer.print("{s} ", .{@tagName(encoding.mnemonic)});222 try writer.print("{s} ", .{@tagName(encoding.mnemonic)});
292223
293 const ops = &[_]Op{ encoding.op1, encoding.op2, encoding.op3, encoding.op4 };224 for (encoding.data.ops) |op| switch (op) {
294 for (ops) |op| switch (op) {
295 .none, .o16, .o32, .o64 => break,225 .none, .o16, .o32, .o64 => break,
296 else => try writer.print("{s} ", .{@tagName(op)}),226 else => try writer.print("{s} ", .{@tagName(op)}),
297 };227 };
298228
299 const op_en = switch (encoding.op_en) {229 const op_en = switch (encoding.data.op_en) {
300 .zi => .i,230 .zi => .i,
301 else => |op_en| op_en,231 else => |op_en| op_en,
302 };232 };
...@@ -604,3 +534,53 @@ pub const Mode = enum {...@@ -604,3 +534,53 @@ pub const Mode = enum {
604 sse2,534 sse2,
605 sse4_1,535 sse4_1,
606};536};
537
538fn estimateInstructionLength(prefix: Prefix, encoding: Encoding, ops: []const Operand) usize {
539 var inst = Instruction{
540 .prefix = prefix,
541 .encoding = encoding,
542 .ops = [1]Operand{.none} ** 4,
543 };
544 std.mem.copy(Operand, &inst.ops, ops);
545
546 var cwriter = std.io.countingWriter(std.io.null_writer);
547 inst.encode(cwriter.writer()) catch unreachable; // Not allowed to fail here unless OOM.
548 return @intCast(usize, cwriter.bytes_written);
549}
550
551const mnemonic_to_encodings_map = init: {
552 @setEvalBranchQuota(100_000);
553 const encodings = @import("encodings.zig");
554 var entries = encodings.table;
555 std.sort.sort(encodings.Entry, &entries, {}, struct {
556 fn lessThan(_: void, lhs: encodings.Entry, rhs: encodings.Entry) bool {
557 return @enumToInt(lhs[0]) < @enumToInt(rhs[0]);
558 }
559 }.lessThan);
560 var data_storage: [entries.len]Data = undefined;
561 var mnemonic_map: [@typeInfo(Mnemonic).Enum.fields.len][]const Data = undefined;
562 var mnemonic_int = 0;
563 var mnemonic_start = 0;
564 for (&data_storage, entries, 0..) |*data, entry, data_index| {
565 data.* = .{
566 .op_en = entry[1],
567 .ops = undefined,
568 .opc_len = entry[3].len,
569 .opc = undefined,
570 .modrm_ext = entry[4],
571 .mode = entry[5],
572 };
573 std.mem.copy(Op, &data.ops, entry[2]);
574 std.mem.copy(u8, &data.opc, entry[3]);
575
576 while (mnemonic_int < @enumToInt(entry[0])) : (mnemonic_int += 1) {
577 mnemonic_map[mnemonic_int] = data_storage[mnemonic_start..data_index];
578 mnemonic_start = data_index;
579 }
580 }
581 while (mnemonic_int < mnemonic_map.len) : (mnemonic_int += 1) {
582 mnemonic_map[mnemonic_int] = data_storage[mnemonic_start..];
583 mnemonic_start = data_storage.len;
584 }
585 break :init mnemonic_map;
586};
src/arch/x86_64/Lower.zig created+465
...@@ -0,0 +1,465 @@
1//! This file contains the functionality for lowering x86_64 MIR to Instructions
2
3allocator: Allocator,
4mir: Mir,
5target: *const std.Target,
6err_msg: ?*ErrorMsg = null,
7src_loc: Module.SrcLoc,
8result: [
9 std.mem.max(usize, &.{
10 abi.Win64.callee_preserved_regs.len,
11 abi.SysV.callee_preserved_regs.len,
12 })
13]Instruction = undefined,
14result_len: usize = undefined,
15
16pub const Error = error{
17 OutOfMemory,
18 LowerFail,
19 InvalidInstruction,
20 CannotEncode,
21};
22
23/// The returned slice is overwritten by the next call to lowerMir.
24pub fn lowerMir(lower: *Lower, inst: Mir.Inst) Error![]const Instruction {
25 lower.result = undefined;
26 errdefer lower.result = undefined;
27 lower.result_len = 0;
28 defer lower.result_len = undefined;
29
30 switch (inst.tag) {
31 .adc,
32 .add,
33 .@"and",
34 .bsf,
35 .bsr,
36 .bswap,
37 .bt,
38 .btc,
39 .btr,
40 .bts,
41 .call,
42 .cbw,
43 .cwde,
44 .cdqe,
45 .cwd,
46 .cdq,
47 .cqo,
48 .cmp,
49 .cmpxchg,
50 .div,
51 .fisttp,
52 .fld,
53 .idiv,
54 .imul,
55 .int3,
56 .jmp,
57 .lea,
58 .lfence,
59 .lzcnt,
60 .mfence,
61 .mov,
62 .movbe,
63 .movzx,
64 .mul,
65 .neg,
66 .nop,
67 .not,
68 .@"or",
69 .pop,
70 .popcnt,
71 .push,
72 .rcl,
73 .rcr,
74 .ret,
75 .rol,
76 .ror,
77 .sal,
78 .sar,
79 .sbb,
80 .sfence,
81 .shl,
82 .shld,
83 .shr,
84 .shrd,
85 .sub,
86 .syscall,
87 .@"test",
88 .tzcnt,
89 .ud2,
90 .xadd,
91 .xchg,
92 .xor,
93
94 .addss,
95 .cmpss,
96 .divss,
97 .maxss,
98 .minss,
99 .movss,
100 .mulss,
101 .roundss,
102 .subss,
103 .ucomiss,
104 .addsd,
105 .cmpsd,
106 .divsd,
107 .maxsd,
108 .minsd,
109 .movsd,
110 .mulsd,
111 .roundsd,
112 .subsd,
113 .ucomisd,
114 => try lower.mirGeneric(inst),
115
116 .cmps,
117 .lods,
118 .movs,
119 .scas,
120 .stos,
121 => try lower.mirString(inst),
122
123 .cmpxchgb => try lower.mirCmpxchgBytes(inst),
124
125 .jmp_reloc => try lower.emit(.none, .jmp, &.{.{ .imm = Immediate.s(0) }}),
126
127 .call_extern => try lower.emit(.none, .call, &.{.{ .imm = Immediate.s(0) }}),
128
129 .lea_linker => try lower.mirLeaLinker(inst),
130
131 .mov_moffs => try lower.mirMovMoffs(inst),
132
133 .movsx => try lower.mirMovsx(inst),
134 .cmovcc => try lower.mirCmovcc(inst),
135 .setcc => try lower.mirSetcc(inst),
136 .jcc => try lower.emit(.none, mnem_cc(.j, inst.data.inst_cc.cc), &.{.{ .imm = Immediate.s(0) }}),
137
138 .push_regs, .pop_regs => try lower.mirPushPopRegisterList(inst),
139
140 .dbg_line,
141 .dbg_prologue_end,
142 .dbg_epilogue_begin,
143 .dead,
144 => {},
145 }
146
147 return lower.result[0..lower.result_len];
148}
149
150pub fn fail(lower: *Lower, comptime format: []const u8, args: anytype) Error {
151 @setCold(true);
152 assert(lower.err_msg == null);
153 lower.err_msg = try ErrorMsg.create(lower.allocator, lower.src_loc, format, args);
154 return error.LowerFail;
155}
156
157fn mnem_cc(comptime base: @Type(.EnumLiteral), cc: bits.Condition) Mnemonic {
158 return switch (cc) {
159 inline else => |c| @field(Mnemonic, @tagName(base) ++ @tagName(c)),
160 };
161}
162
163fn imm(lower: Lower, ops: Mir.Inst.Ops, i: u32) Immediate {
164 return switch (ops) {
165 .rri_s,
166 .ri_s,
167 .i_s,
168 .mi_sib_s,
169 .mi_rip_s,
170 .lock_mi_sib_s,
171 .lock_mi_rip_s,
172 => Immediate.s(@bitCast(i32, i)),
173
174 .rri_u,
175 .ri_u,
176 .i_u,
177 .mi_sib_u,
178 .mi_rip_u,
179 .lock_mi_sib_u,
180 .lock_mi_rip_u,
181 .mri_sib,
182 .mri_rip,
183 => Immediate.u(i),
184
185 .ri64 => Immediate.u(lower.mir.extraData(Mir.Imm64, i).data.decode()),
186
187 else => unreachable,
188 };
189}
190
191fn mem(lower: Lower, ops: Mir.Inst.Ops, payload: u32) Memory {
192 return switch (ops) {
193 .rm_sib,
194 .rm_sib_cc,
195 .m_sib,
196 .m_sib_cc,
197 .mi_sib_u,
198 .mi_sib_s,
199 .mr_sib,
200 .mrr_sib,
201 .mri_sib,
202 .lock_m_sib,
203 .lock_mi_sib_u,
204 .lock_mi_sib_s,
205 .lock_mr_sib,
206 => lower.mir.extraData(Mir.MemorySib, payload).data.decode(),
207
208 .rm_rip,
209 .rm_rip_cc,
210 .m_rip,
211 .m_rip_cc,
212 .mi_rip_u,
213 .mi_rip_s,
214 .mr_rip,
215 .mrr_rip,
216 .mri_rip,
217 .lock_m_rip,
218 .lock_mi_rip_u,
219 .lock_mi_rip_s,
220 .lock_mr_rip,
221 => lower.mir.extraData(Mir.MemoryRip, payload).data.decode(),
222
223 .rax_moffs,
224 .moffs_rax,
225 .lock_moffs_rax,
226 => lower.mir.extraData(Mir.MemoryMoffs, payload).data.decode(),
227
228 else => unreachable,
229 };
230}
231
232fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand) Error!void {
233 lower.result[lower.result_len] = try Instruction.new(prefix, mnemonic, ops);
234 lower.result_len += 1;
235}
236
237fn mirGeneric(lower: *Lower, inst: Mir.Inst) Error!void {
238 try lower.emit(switch (inst.ops) {
239 else => .none,
240 .lock_m_sib,
241 .lock_m_rip,
242 .lock_mi_sib_u,
243 .lock_mi_rip_u,
244 .lock_mi_sib_s,
245 .lock_mi_rip_s,
246 .lock_mr_sib,
247 .lock_mr_rip,
248 .lock_moffs_rax,
249 => .lock,
250 }, switch (inst.tag) {
251 inline else => |tag| if (@hasField(Mnemonic, @tagName(tag)))
252 @field(Mnemonic, @tagName(tag))
253 else
254 unreachable,
255 }, switch (inst.ops) {
256 .none => &.{},
257 .i_s, .i_u => &.{
258 .{ .imm = lower.imm(inst.ops, inst.data.i) },
259 },
260 .r => &.{
261 .{ .reg = inst.data.r },
262 },
263 .rr => &.{
264 .{ .reg = inst.data.rr.r1 },
265 .{ .reg = inst.data.rr.r2 },
266 },
267 .rrr => &.{
268 .{ .reg = inst.data.rrr.r1 },
269 .{ .reg = inst.data.rrr.r2 },
270 .{ .reg = inst.data.rrr.r3 },
271 },
272 .ri_s, .ri_u => &.{
273 .{ .reg = inst.data.ri.r },
274 .{ .imm = lower.imm(inst.ops, inst.data.ri.i) },
275 },
276 .ri64 => &.{
277 .{ .reg = inst.data.rx.r },
278 .{ .imm = lower.imm(inst.ops, inst.data.rx.payload) },
279 },
280 .rri_s, .rri_u => &.{
281 .{ .reg = inst.data.rri.r1 },
282 .{ .reg = inst.data.rri.r2 },
283 .{ .imm = lower.imm(inst.ops, inst.data.rri.i) },
284 },
285 .m_sib, .lock_m_sib, .m_rip, .lock_m_rip => &.{
286 .{ .mem = lower.mem(inst.ops, inst.data.payload) },
287 },
288 .mi_sib_s,
289 .lock_mi_sib_s,
290 .mi_sib_u,
291 .lock_mi_sib_u,
292 .mi_rip_u,
293 .lock_mi_rip_u,
294 .mi_rip_s,
295 .lock_mi_rip_s,
296 => &.{
297 .{ .mem = lower.mem(inst.ops, inst.data.ix.payload) },
298 .{ .imm = lower.imm(inst.ops, inst.data.ix.i) },
299 },
300 .rm_sib, .rm_rip => &.{
301 .{ .reg = inst.data.rx.r },
302 .{ .mem = lower.mem(inst.ops, inst.data.rx.payload) },
303 },
304 .mr_sib, .lock_mr_sib, .mr_rip, .lock_mr_rip => &.{
305 .{ .mem = lower.mem(inst.ops, inst.data.rx.payload) },
306 .{ .reg = inst.data.rx.r },
307 },
308 .mrr_sib, .mrr_rip => &.{
309 .{ .mem = lower.mem(inst.ops, inst.data.rrx.payload) },
310 .{ .reg = inst.data.rrx.r1 },
311 .{ .reg = inst.data.rrx.r2 },
312 },
313 .mri_sib, .mri_rip => &.{
314 .{ .mem = lower.mem(inst.ops, inst.data.rix.payload) },
315 .{ .reg = inst.data.rix.r },
316 .{ .imm = lower.imm(inst.ops, inst.data.rix.i) },
317 },
318 else => return lower.fail("TODO lower {s} {s}", .{ @tagName(inst.tag), @tagName(inst.ops) }),
319 });
320}
321
322fn mirString(lower: *Lower, inst: Mir.Inst) Error!void {
323 switch (inst.ops) {
324 .string => try lower.emit(switch (inst.data.string.repeat) {
325 inline else => |repeat| @field(Prefix, @tagName(repeat)),
326 }, switch (inst.tag) {
327 inline .cmps, .lods, .movs, .scas, .stos => |tag| switch (inst.data.string.width) {
328 inline else => |width| @field(Mnemonic, @tagName(tag) ++ @tagName(width)),
329 },
330 else => unreachable,
331 }, &.{}),
332 else => return lower.fail("TODO lower {s} {s}", .{ @tagName(inst.tag), @tagName(inst.ops) }),
333 }
334}
335
336fn mirCmpxchgBytes(lower: *Lower, inst: Mir.Inst) Error!void {
337 const ops: [1]Operand = switch (inst.ops) {
338 .m_sib, .lock_m_sib, .m_rip, .lock_m_rip => .{
339 .{ .mem = lower.mem(inst.ops, inst.data.payload) },
340 },
341 else => return lower.fail("TODO lower {s} {s}", .{ @tagName(inst.tag), @tagName(inst.ops) }),
342 };
343 try lower.emit(switch (inst.ops) {
344 .m_sib, .m_rip => .none,
345 .lock_m_sib, .lock_m_rip => .lock,
346 else => unreachable,
347 }, switch (@divExact(ops[0].bitSize(), 8)) {
348 8 => .cmpxchg8b,
349 16 => .cmpxchg16b,
350 else => return lower.fail("invalid operand for {s}", .{@tagName(inst.tag)}),
351 }, &ops);
352}
353
354fn mirMovMoffs(lower: *Lower, inst: Mir.Inst) Error!void {
355 try lower.emit(switch (inst.ops) {
356 .rax_moffs, .moffs_rax => .none,
357 .lock_moffs_rax => .lock,
358 else => return lower.fail("TODO lower {s} {s}", .{ @tagName(inst.tag), @tagName(inst.ops) }),
359 }, .mov, switch (inst.ops) {
360 .rax_moffs => &.{
361 .{ .reg = .rax },
362 .{ .mem = lower.mem(inst.ops, inst.data.payload) },
363 },
364 .moffs_rax, .lock_moffs_rax => &.{
365 .{ .mem = lower.mem(inst.ops, inst.data.payload) },
366 .{ .reg = .rax },
367 },
368 else => unreachable,
369 });
370}
371
372fn mirMovsx(lower: *Lower, inst: Mir.Inst) Error!void {
373 const ops: [2]Operand = switch (inst.ops) {
374 .rr => .{
375 .{ .reg = inst.data.rr.r1 },
376 .{ .reg = inst.data.rr.r2 },
377 },
378 .rm_sib, .rm_rip => .{
379 .{ .reg = inst.data.rx.r },
380 .{ .mem = lower.mem(inst.ops, inst.data.rx.payload) },
381 },
382 else => return lower.fail("TODO lower {s} {s}", .{ @tagName(inst.tag), @tagName(inst.ops) }),
383 };
384 try lower.emit(.none, switch (ops[0].bitSize()) {
385 32, 64 => switch (ops[1].bitSize()) {
386 32 => .movsxd,
387 else => .movsx,
388 },
389 else => .movsx,
390 }, &ops);
391}
392
393fn mirCmovcc(lower: *Lower, inst: Mir.Inst) Error!void {
394 switch (inst.ops) {
395 .rr_cc => try lower.emit(.none, mnem_cc(.cmov, inst.data.rr_cc.cc), &.{
396 .{ .reg = inst.data.rr_cc.r1 },
397 .{ .reg = inst.data.rr_cc.r2 },
398 }),
399 .rm_sib_cc, .rm_rip_cc => try lower.emit(.none, mnem_cc(.cmov, inst.data.rx_cc.cc), &.{
400 .{ .reg = inst.data.rx_cc.r },
401 .{ .mem = lower.mem(inst.ops, inst.data.rx_cc.payload) },
402 }),
403 else => return lower.fail("TODO lower {s} {s}", .{ @tagName(inst.tag), @tagName(inst.ops) }),
404 }
405}
406
407fn mirSetcc(lower: *Lower, inst: Mir.Inst) Error!void {
408 switch (inst.ops) {
409 .r_cc => try lower.emit(.none, mnem_cc(.set, inst.data.r_cc.cc), &.{
410 .{ .reg = inst.data.r_cc.r },
411 }),
412 .m_sib_cc, .m_rip_cc => try lower.emit(.none, mnem_cc(.set, inst.data.x_cc.cc), &.{
413 .{ .mem = lower.mem(inst.ops, inst.data.x_cc.payload) },
414 }),
415 else => return lower.fail("TODO lower {s} {s}", .{ @tagName(inst.tag), @tagName(inst.ops) }),
416 }
417}
418
419fn mirPushPopRegisterList(lower: *Lower, inst: Mir.Inst) Error!void {
420 const save_reg_list = lower.mir.extraData(Mir.SaveRegisterList, inst.data.payload).data;
421 const base = @intToEnum(Register, save_reg_list.base_reg);
422 var disp: i32 = -@intCast(i32, save_reg_list.stack_end);
423 const reg_list = Mir.RegisterList.fromInt(save_reg_list.register_list);
424 const callee_preserved_regs = abi.getCalleePreservedRegs(lower.target.*);
425 for (callee_preserved_regs) |callee_preserved_reg| {
426 if (!reg_list.isSet(callee_preserved_regs, callee_preserved_reg)) continue;
427 const reg_op = Operand{ .reg = callee_preserved_reg };
428 const mem_op = Operand{ .mem = Memory.sib(.qword, .{ .base = base, .disp = disp }) };
429 try lower.emit(.none, .mov, switch (inst.tag) {
430 .push_regs => &.{ mem_op, reg_op },
431 .pop_regs => &.{ reg_op, mem_op },
432 else => unreachable,
433 });
434 disp += 8;
435 }
436}
437
438fn mirLeaLinker(lower: *Lower, inst: Mir.Inst) Error!void {
439 const metadata = lower.mir.extraData(Mir.LeaRegisterReloc, inst.data.payload).data;
440 const reg = @intToEnum(Register, metadata.reg);
441 try lower.emit(.none, .lea, &.{
442 .{ .reg = reg },
443 .{ .mem = Memory.rip(Memory.PtrSize.fromBitSize(reg.bitSize()), 0) },
444 });
445}
446
447const abi = @import("abi.zig");
448const assert = std.debug.assert;
449const bits = @import("bits.zig");
450const encoder = @import("encoder.zig");
451const std = @import("std");
452
453const Air = @import("../../Air.zig");
454const Allocator = std.mem.Allocator;
455const ErrorMsg = Module.ErrorMsg;
456const Immediate = bits.Immediate;
457const Instruction = encoder.Instruction;
458const Lower = @This();
459const Memory = bits.Memory;
460const Mir = @import("Mir.zig");
461const Mnemonic = Instruction.Mnemonic;
462const Module = @import("../../Module.zig");
463const Operand = Instruction.Operand;
464const Prefix = Instruction.Prefix;
465const Register = bits.Register;
src/arch/x86_64/Mir.zig+11-8
...@@ -655,16 +655,19 @@ pub const MemoryMoffs = struct {...@@ -655,16 +655,19 @@ pub const MemoryMoffs = struct {
655 msb: u32,655 msb: u32,
656 lsb: u32,656 lsb: u32,
657657
658 pub fn encodeOffset(moffs: *MemoryMoffs, v: u64) void {658 pub fn encode(seg: Register, offset: u64) MemoryMoffs {
659 moffs.msb = @truncate(u32, v >> 32);659 return .{
660 moffs.lsb = @truncate(u32, v);660 .seg = @enumToInt(seg),
661 .msb = @truncate(u32, offset >> 32),
662 .lsb = @truncate(u32, offset >> 0),
663 };
661 }664 }
662665
663 pub fn decodeOffset(moffs: *const MemoryMoffs) u64 {666 pub fn decode(moffs: MemoryMoffs) Memory {
664 var res: u64 = 0;667 return .{ .moffs = .{
665 res |= (@intCast(u64, moffs.msb) << 32);668 .seg = @intToEnum(Register, moffs.seg),
666 res |= @intCast(u64, moffs.lsb);669 .offset = @as(u64, moffs.msb) << 32 | @as(u64, moffs.lsb) << 0,
667 return res;670 } };
668 }671 }
669};672};
670673
src/arch/x86_64/bits.zig+1-1
...@@ -515,7 +515,7 @@ pub const Memory = union(enum) {...@@ -515,7 +515,7 @@ pub const Memory = union(enum) {
515 return switch (mem) {515 return switch (mem) {
516 .rip => |r| r.ptr_size.bitSize(),516 .rip => |r| r.ptr_size.bitSize(),
517 .sib => |s| s.ptr_size.bitSize(),517 .sib => |s| s.ptr_size.bitSize(),
518 .moffs => unreachable,518 .moffs => 64,
519 };519 };
520 }520 }
521};521};
src/arch/x86_64/encoder.zig+539-380
...@@ -11,12 +11,9 @@ const Memory = bits.Memory;...@@ -11,12 +11,9 @@ const Memory = bits.Memory;
11const Register = bits.Register;11const Register = bits.Register;
1212
13pub const Instruction = struct {13pub const Instruction = struct {
14 op1: Operand = .none,
15 op2: Operand = .none,
16 op3: Operand = .none,
17 op4: Operand = .none,
18 prefix: Prefix = .none,14 prefix: Prefix = .none,
19 encoding: Encoding,15 encoding: Encoding,
16 ops: [4]Operand = .{.none} ** 4,
2017
21 pub const Mnemonic = Encoding.Mnemonic;18 pub const Mnemonic = Encoding.Mnemonic;
2219
...@@ -107,102 +104,87 @@ pub const Instruction = struct {...@@ -107,102 +104,87 @@ pub const Instruction = struct {
107 }104 }
108 };105 };
109106
110 pub const Init = struct {107 pub fn new(prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand) !Instruction {
111 prefix: Prefix = .none,108 const encoding = (try Encoding.findByMnemonic(prefix, mnemonic, ops)) orelse {
112 op1: Operand = .none,
113 op2: Operand = .none,
114 op3: Operand = .none,
115 op4: Operand = .none,
116 };
117
118 pub fn new(mnemonic: Mnemonic, args: Init) !Instruction {
119 const encoding = (try Encoding.findByMnemonic(mnemonic, args)) orelse {
120 log.err("no encoding found for: {s} {s} {s} {s} {s} {s}", .{109 log.err("no encoding found for: {s} {s} {s} {s} {s} {s}", .{
121 @tagName(args.prefix),110 @tagName(prefix),
122 @tagName(mnemonic),111 @tagName(mnemonic),
123 @tagName(Encoding.Op.fromOperand(args.op1)),112 @tagName(if (ops.len > 0) Encoding.Op.fromOperand(ops[0]) else .none),
124 @tagName(Encoding.Op.fromOperand(args.op2)),113 @tagName(if (ops.len > 1) Encoding.Op.fromOperand(ops[1]) else .none),
125 @tagName(Encoding.Op.fromOperand(args.op3)),114 @tagName(if (ops.len > 2) Encoding.Op.fromOperand(ops[2]) else .none),
126 @tagName(Encoding.Op.fromOperand(args.op4)),115 @tagName(if (ops.len > 3) Encoding.Op.fromOperand(ops[3]) else .none),
127 });116 });
128 return error.InvalidInstruction;117 return error.InvalidInstruction;
129 };118 };
130 log.debug("selected encoding: {}", .{encoding});119 log.debug("selected encoding: {}", .{encoding});
131 return .{120
132 .prefix = args.prefix,121 var inst = Instruction{
133 .op1 = args.op1,122 .prefix = prefix,
134 .op2 = args.op2,
135 .op3 = args.op3,
136 .op4 = args.op4,
137 .encoding = encoding,123 .encoding = encoding,
124 .ops = [1]Operand{.none} ** 4,
138 };125 };
126 std.mem.copy(Operand, &inst.ops, ops);
127 return inst;
139 }128 }
140129
141 pub fn fmtPrint(inst: Instruction, writer: anytype) !void {130 pub fn fmtPrint(inst: Instruction, writer: anytype) !void {
142 if (inst.prefix != .none) try writer.print("{s} ", .{@tagName(inst.prefix)});131 if (inst.prefix != .none) try writer.print("{s} ", .{@tagName(inst.prefix)});
143 try writer.print("{s}", .{@tagName(inst.encoding.mnemonic)});132 try writer.print("{s}", .{@tagName(inst.encoding.mnemonic)});
144 const ops = [_]struct { Operand, Encoding.Op }{133 for (inst.ops, inst.encodings.ops, 0..) |op, enc, i| {
145 .{ inst.op1, inst.encoding.op1 },134 if (op == .none) break;
146 .{ inst.op2, inst.encoding.op2 },135 if (i > 0) try writer.writeByte(',');
147 .{ inst.op3, inst.encoding.op3 },
148 .{ inst.op4, inst.encoding.op4 },
149 };
150 for (&ops, 0..) |op, i| {
151 if (op[0] == .none) break;
152 if (i > 0) {
153 try writer.writeByte(',');
154 }
155 try writer.writeByte(' ');136 try writer.writeByte(' ');
156 try op[0].fmtPrint(op[1], writer);137 try op.fmtPrint(enc, writer);
157 }138 }
158 }139 }
159140
160 pub fn encode(inst: Instruction, writer: anytype) !void {141 pub fn encode(inst: Instruction, writer: anytype) !void {
161 const encoder = Encoder(@TypeOf(writer)){ .writer = writer };142 const encoder = Encoder(@TypeOf(writer)){ .writer = writer };
162 const encoding = inst.encoding;143 const enc = inst.encoding;
144 const data = enc.data;
163145
164 try inst.encodeLegacyPrefixes(encoder);146 try inst.encodeLegacyPrefixes(encoder);
165 try inst.encodeMandatoryPrefix(encoder);147 try inst.encodeMandatoryPrefix(encoder);
166 try inst.encodeRexPrefix(encoder);148 try inst.encodeRexPrefix(encoder);
167 try inst.encodeOpcode(encoder);149 try inst.encodeOpcode(encoder);
168150
169 switch (encoding.op_en) {151 switch (data.op_en) {
170 .np, .o => {},152 .np, .o => {},
171 .i, .d => try encodeImm(inst.op1.imm, encoding.op1, encoder),153 .i, .d => try encodeImm(inst.ops[0].imm, data.ops[0], encoder),
172 .zi, .oi => try encodeImm(inst.op2.imm, encoding.op2, encoder),154 .zi, .oi => try encodeImm(inst.ops[1].imm, data.ops[1], encoder),
173 .fd => try encoder.imm64(inst.op2.mem.moffs.offset),155 .fd => try encoder.imm64(inst.ops[1].mem.moffs.offset),
174 .td => try encoder.imm64(inst.op1.mem.moffs.offset),156 .td => try encoder.imm64(inst.ops[0].mem.moffs.offset),
175 else => {157 else => {
176 const mem_op = switch (encoding.op_en) {158 const mem_op = switch (data.op_en) {
177 .m, .mi, .m1, .mc, .mr, .mri, .mrc => inst.op1,159 .m, .mi, .m1, .mc, .mr, .mri, .mrc => inst.ops[0],
178 .rm, .rmi => inst.op2,160 .rm, .rmi => inst.ops[1],
179 else => unreachable,161 else => unreachable,
180 };162 };
181 switch (mem_op) {163 switch (mem_op) {
182 .reg => |reg| {164 .reg => |reg| {
183 const rm = switch (encoding.op_en) {165 const rm = switch (data.op_en) {
184 .m, .mi, .m1, .mc => encoding.modRmExt(),166 .m, .mi, .m1, .mc => enc.modRmExt(),
185 .mr, .mri, .mrc => inst.op2.reg.lowEnc(),167 .mr, .mri, .mrc => inst.ops[1].reg.lowEnc(),
186 .rm, .rmi => inst.op1.reg.lowEnc(),168 .rm, .rmi => inst.ops[0].reg.lowEnc(),
187 else => unreachable,169 else => unreachable,
188 };170 };
189 try encoder.modRm_direct(rm, reg.lowEnc());171 try encoder.modRm_direct(rm, reg.lowEnc());
190 },172 },
191 .mem => |mem| {173 .mem => |mem| {
192 const op = switch (encoding.op_en) {174 const op = switch (data.op_en) {
193 .m, .mi, .m1, .mc => .none,175 .m, .mi, .m1, .mc => .none,
194 .mr, .mri, .mrc => inst.op2,176 .mr, .mri, .mrc => inst.ops[1],
195 .rm, .rmi => inst.op1,177 .rm, .rmi => inst.ops[0],
196 else => unreachable,178 else => unreachable,
197 };179 };
198 try encodeMemory(encoding, mem, op, encoder);180 try encodeMemory(enc, mem, op, encoder);
199 },181 },
200 else => unreachable,182 else => unreachable,
201 }183 }
202184
203 switch (encoding.op_en) {185 switch (data.op_en) {
204 .mi => try encodeImm(inst.op2.imm, encoding.op2, encoder),186 .mi => try encodeImm(inst.ops[1].imm, data.ops[1], encoder),
205 .rmi, .mri => try encodeImm(inst.op3.imm, encoding.op3, encoder),187 .rmi, .mri => try encodeImm(inst.ops[2].imm, data.ops[2], encoder),
206 else => {},188 else => {},
207 }189 }
208 },190 },
...@@ -214,15 +196,16 @@ pub const Instruction = struct {...@@ -214,15 +196,16 @@ pub const Instruction = struct {
214 const first = @boolToInt(inst.encoding.mandatoryPrefix() != null);196 const first = @boolToInt(inst.encoding.mandatoryPrefix() != null);
215 const final = opcode.len - 1;197 const final = opcode.len - 1;
216 for (opcode[first..final]) |byte| try encoder.opcode_1byte(byte);198 for (opcode[first..final]) |byte| try encoder.opcode_1byte(byte);
217 switch (inst.encoding.op_en) {199 switch (inst.encoding.data.op_en) {
218 .o, .oi => try encoder.opcode_withReg(opcode[final], inst.op1.reg.lowEnc()),200 .o, .oi => try encoder.opcode_withReg(opcode[final], inst.ops[0].reg.lowEnc()),
219 else => try encoder.opcode_1byte(opcode[final]),201 else => try encoder.opcode_1byte(opcode[final]),
220 }202 }
221 }203 }
222204
223 fn encodeLegacyPrefixes(inst: Instruction, encoder: anytype) !void {205 fn encodeLegacyPrefixes(inst: Instruction, encoder: anytype) !void {
224 const enc = inst.encoding;206 const enc = inst.encoding;
225 const op_en = enc.op_en;207 const data = enc.data;
208 const op_en = data.op_en;
226209
227 var legacy = LegacyPrefixes{};210 var legacy = LegacyPrefixes{};
228211
...@@ -233,7 +216,7 @@ pub const Instruction = struct {...@@ -233,7 +216,7 @@ pub const Instruction = struct {
233 .rep, .repe, .repz => legacy.prefix_f3 = true,216 .rep, .repe, .repz => legacy.prefix_f3 = true,
234 }217 }
235218
236 if (enc.mode == .none) {219 if (data.mode == .none) {
237 const bit_size = enc.operandBitSize();220 const bit_size = enc.operandBitSize();
238 if (bit_size == 16) {221 if (bit_size == 16) {
239 legacy.set16BitOverride();222 legacy.set16BitOverride();
...@@ -242,17 +225,17 @@ pub const Instruction = struct {...@@ -242,17 +225,17 @@ pub const Instruction = struct {
242225
243 const segment_override: ?Register = switch (op_en) {226 const segment_override: ?Register = switch (op_en) {
244 .i, .zi, .o, .oi, .d, .np => null,227 .i, .zi, .o, .oi, .d, .np => null,
245 .fd => inst.op2.mem.base().?,228 .fd => inst.ops[1].mem.base().?,
246 .td => inst.op1.mem.base().?,229 .td => inst.ops[0].mem.base().?,
247 .rm, .rmi => if (inst.op2.isSegmentRegister()) blk: {230 .rm, .rmi => if (inst.ops[1].isSegmentRegister()) blk: {
248 break :blk switch (inst.op2) {231 break :blk switch (inst.ops[1]) {
249 .reg => |r| r,232 .reg => |r| r,
250 .mem => |m| m.base().?,233 .mem => |m| m.base().?,
251 else => unreachable,234 else => unreachable,
252 };235 };
253 } else null,236 } else null,
254 .m, .mi, .m1, .mc, .mr, .mri, .mrc => if (inst.op1.isSegmentRegister()) blk: {237 .m, .mi, .m1, .mc, .mr, .mri, .mrc => if (inst.ops[0].isSegmentRegister()) blk: {
255 break :blk switch (inst.op1) {238 break :blk switch (inst.ops[0]) {
256 .reg => |r| r,239 .reg => |r| r,
257 .mem => |m| m.base().?,240 .mem => |m| m.base().?,
258 else => unreachable,241 else => unreachable,
...@@ -267,19 +250,19 @@ pub const Instruction = struct {...@@ -267,19 +250,19 @@ pub const Instruction = struct {
267 }250 }
268251
269 fn encodeRexPrefix(inst: Instruction, encoder: anytype) !void {252 fn encodeRexPrefix(inst: Instruction, encoder: anytype) !void {
270 const op_en = inst.encoding.op_en;253 const op_en = inst.encoding.data.op_en;
271254
272 var rex = Rex{};255 var rex = Rex{};
273 rex.present = inst.encoding.mode == .rex;256 rex.present = inst.encoding.data.mode == .rex;
274 rex.w = inst.encoding.mode == .long;257 rex.w = inst.encoding.data.mode == .long;
275258
276 switch (op_en) {259 switch (op_en) {
277 .np, .i, .zi, .fd, .td, .d => {},260 .np, .i, .zi, .fd, .td, .d => {},
278 .o, .oi => rex.b = inst.op1.reg.isExtended(),261 .o, .oi => rex.b = inst.ops[0].reg.isExtended(),
279 .m, .mi, .m1, .mc, .mr, .rm, .rmi, .mri, .mrc => {262 .m, .mi, .m1, .mc, .mr, .rm, .rmi, .mri, .mrc => {
280 const r_op = switch (op_en) {263 const r_op = switch (op_en) {
281 .rm, .rmi => inst.op1,264 .rm, .rmi => inst.ops[0],
282 .mr, .mri, .mrc => inst.op2,265 .mr, .mri, .mrc => inst.ops[1],
283 else => null,266 else => null,
284 };267 };
285 if (r_op) |op| {268 if (r_op) |op| {
...@@ -287,8 +270,8 @@ pub const Instruction = struct {...@@ -287,8 +270,8 @@ pub const Instruction = struct {
287 }270 }
288271
289 const b_x_op = switch (op_en) {272 const b_x_op = switch (op_en) {
290 .rm, .rmi => inst.op2,273 .rm, .rmi => inst.ops[1],
291 .m, .mi, .m1, .mc, .mr, .mri, .mrc => inst.op1,274 .m, .mi, .m1, .mc, .mr, .mri, .mrc => inst.ops[0],
292 else => unreachable,275 else => unreachable,
293 };276 };
294 switch (b_x_op) {277 switch (b_x_op) {
...@@ -827,16 +810,14 @@ const TestEncode = struct {...@@ -827,16 +810,14 @@ const TestEncode = struct {
827 buffer: [32]u8 = undefined,810 buffer: [32]u8 = undefined,
828 index: usize = 0,811 index: usize = 0,
829812
830 fn encode(enc: *TestEncode, mnemonic: Instruction.Mnemonic, args: Instruction.Init) !void {813 fn encode(
814 enc: *TestEncode,
815 mnemonic: Instruction.Mnemonic,
816 ops: []const Instruction.Operand,
817 ) !void {
831 var stream = std.io.fixedBufferStream(&enc.buffer);818 var stream = std.io.fixedBufferStream(&enc.buffer);
832 var count_writer = std.io.countingWriter(stream.writer());819 var count_writer = std.io.countingWriter(stream.writer());
833 const inst = try Instruction.new(mnemonic, .{820 const inst = try Instruction.new(.none, mnemonic, ops);
834 .prefix = args.prefix,
835 .op1 = args.op1,
836 .op2 = args.op2,
837 .op3 = args.op3,
838 .op4 = args.op4,
839 });
840 try inst.encode(count_writer.writer());821 try inst.encode(count_writer.writer());
841 enc.index = count_writer.bytes_written;822 enc.index = count_writer.bytes_written;
842 }823 }
...@@ -850,9 +831,9 @@ test "encode" {...@@ -850,9 +831,9 @@ test "encode" {
850 var buf = std.ArrayList(u8).init(testing.allocator);831 var buf = std.ArrayList(u8).init(testing.allocator);
851 defer buf.deinit();832 defer buf.deinit();
852833
853 const inst = try Instruction.new(.mov, .{834 const inst = try Instruction.new(.none, .mov, &.{
854 .op1 = .{ .reg = .rbx },835 .{ .reg = .rbx },
855 .op2 = .{ .imm = Immediate.u(4) },836 .{ .imm = Immediate.u(4) },
856 });837 });
857 try inst.encode(buf.writer());838 try inst.encode(buf.writer());
858 try testing.expectEqualSlices(u8, &.{ 0x48, 0xc7, 0xc3, 0x4, 0x0, 0x0, 0x0 }, buf.items);839 try testing.expectEqualSlices(u8, &.{ 0x48, 0xc7, 0xc3, 0x4, 0x0, 0x0, 0x0 }, buf.items);
...@@ -861,61 +842,94 @@ test "encode" {...@@ -861,61 +842,94 @@ test "encode" {
861test "lower I encoding" {842test "lower I encoding" {
862 var enc = TestEncode{};843 var enc = TestEncode{};
863844
864 try enc.encode(.push, .{ .op1 = .{ .imm = Immediate.u(0x10) } });845 try enc.encode(.push, &.{
846 .{ .imm = Immediate.u(0x10) },
847 });
865 try expectEqualHexStrings("\x6A\x10", enc.code(), "push 0x10");848 try expectEqualHexStrings("\x6A\x10", enc.code(), "push 0x10");
866849
867 try enc.encode(.push, .{ .op1 = .{ .imm = Immediate.u(0x1000) } });850 try enc.encode(.push, &.{
851 .{ .imm = Immediate.u(0x1000) },
852 });
868 try expectEqualHexStrings("\x66\x68\x00\x10", enc.code(), "push 0x1000");853 try expectEqualHexStrings("\x66\x68\x00\x10", enc.code(), "push 0x1000");
869854
870 try enc.encode(.push, .{ .op1 = .{ .imm = Immediate.u(0x10000000) } });855 try enc.encode(.push, &.{
856 .{ .imm = Immediate.u(0x10000000) },
857 });
871 try expectEqualHexStrings("\x68\x00\x00\x00\x10", enc.code(), "push 0x10000000");858 try expectEqualHexStrings("\x68\x00\x00\x00\x10", enc.code(), "push 0x10000000");
872859
873 try enc.encode(.adc, .{ .op1 = .{ .reg = .rax }, .op2 = .{ .imm = Immediate.u(0x10000000) } });860 try enc.encode(.adc, &.{
861 .{ .reg = .rax },
862 .{ .imm = Immediate.u(0x10000000) },
863 });
874 try expectEqualHexStrings("\x48\x15\x00\x00\x00\x10", enc.code(), "adc rax, 0x10000000");864 try expectEqualHexStrings("\x48\x15\x00\x00\x00\x10", enc.code(), "adc rax, 0x10000000");
875865
876 try enc.encode(.add, .{ .op1 = .{ .reg = .al }, .op2 = .{ .imm = Immediate.u(0x10) } });866 try enc.encode(.add, &.{
867 .{ .reg = .al },
868 .{ .imm = Immediate.u(0x10) },
869 });
877 try expectEqualHexStrings("\x04\x10", enc.code(), "add al, 0x10");870 try expectEqualHexStrings("\x04\x10", enc.code(), "add al, 0x10");
878871
879 try enc.encode(.add, .{ .op1 = .{ .reg = .rax }, .op2 = .{ .imm = Immediate.u(0x10) } });872 try enc.encode(.add, &.{
873 .{ .reg = .rax },
874 .{ .imm = Immediate.u(0x10) },
875 });
880 try expectEqualHexStrings("\x48\x83\xC0\x10", enc.code(), "add rax, 0x10");876 try expectEqualHexStrings("\x48\x83\xC0\x10", enc.code(), "add rax, 0x10");
881877
882 try enc.encode(.sbb, .{ .op1 = .{ .reg = .ax }, .op2 = .{ .imm = Immediate.u(0x10) } });878 try enc.encode(.sbb, &.{
879 .{ .reg = .ax },
880 .{ .imm = Immediate.u(0x10) },
881 });
883 try expectEqualHexStrings("\x66\x1D\x10\x00", enc.code(), "sbb ax, 0x10");882 try expectEqualHexStrings("\x66\x1D\x10\x00", enc.code(), "sbb ax, 0x10");
884883
885 try enc.encode(.xor, .{ .op1 = .{ .reg = .al }, .op2 = .{ .imm = Immediate.u(0x10) } });884 try enc.encode(.xor, &.{
885 .{ .reg = .al },
886 .{ .imm = Immediate.u(0x10) },
887 });
886 try expectEqualHexStrings("\x34\x10", enc.code(), "xor al, 0x10");888 try expectEqualHexStrings("\x34\x10", enc.code(), "xor al, 0x10");
887}889}
888890
889test "lower MI encoding" {891test "lower MI encoding" {
890 var enc = TestEncode{};892 var enc = TestEncode{};
891893
892 try enc.encode(.mov, .{ .op1 = .{ .reg = .r12 }, .op2 = .{ .imm = Immediate.u(0x1000) } });894 try enc.encode(.mov, &.{
895 .{ .reg = .r12 },
896 .{ .imm = Immediate.u(0x1000) },
897 });
893 try expectEqualHexStrings("\x49\xC7\xC4\x00\x10\x00\x00", enc.code(), "mov r12, 0x1000");898 try expectEqualHexStrings("\x49\xC7\xC4\x00\x10\x00\x00", enc.code(), "mov r12, 0x1000");
894899
895 try enc.encode(.mov, .{900 try enc.encode(.mov, &.{
896 .op1 = .{ .mem = Memory.sib(.byte, .{ .base = .r12 }) },901 .{ .mem = Memory.sib(.byte, .{ .base = .r12 }) },
897 .op2 = .{ .imm = Immediate.u(0x10) },902 .{ .imm = Immediate.u(0x10) },
898 });903 });
899 try expectEqualHexStrings("\x41\xC6\x04\x24\x10", enc.code(), "mov BYTE PTR [r12], 0x10");904 try expectEqualHexStrings("\x41\xC6\x04\x24\x10", enc.code(), "mov BYTE PTR [r12], 0x10");
900905
901 try enc.encode(.mov, .{ .op1 = .{ .reg = .r12 }, .op2 = .{ .imm = Immediate.u(0x1000) } });906 try enc.encode(.mov, &.{
907 .{ .reg = .r12 },
908 .{ .imm = Immediate.u(0x1000) },
909 });
902 try expectEqualHexStrings("\x49\xC7\xC4\x00\x10\x00\x00", enc.code(), "mov r12, 0x1000");910 try expectEqualHexStrings("\x49\xC7\xC4\x00\x10\x00\x00", enc.code(), "mov r12, 0x1000");
903911
904 try enc.encode(.mov, .{ .op1 = .{ .reg = .r12 }, .op2 = .{ .imm = Immediate.u(0x1000) } });912 try enc.encode(.mov, &.{
913 .{ .reg = .r12 },
914 .{ .imm = Immediate.u(0x1000) },
915 });
905 try expectEqualHexStrings("\x49\xC7\xC4\x00\x10\x00\x00", enc.code(), "mov r12, 0x1000");916 try expectEqualHexStrings("\x49\xC7\xC4\x00\x10\x00\x00", enc.code(), "mov r12, 0x1000");
906917
907 try enc.encode(.mov, .{ .op1 = .{ .reg = .rax }, .op2 = .{ .imm = Immediate.u(0x10) } });918 try enc.encode(.mov, &.{
919 .{ .reg = .rax },
920 .{ .imm = Immediate.u(0x10) },
921 });
908 try expectEqualHexStrings("\x48\xc7\xc0\x10\x00\x00\x00", enc.code(), "mov rax, 0x10");922 try expectEqualHexStrings("\x48\xc7\xc0\x10\x00\x00\x00", enc.code(), "mov rax, 0x10");
909923
910 try enc.encode(.mov, .{924 try enc.encode(.mov, &.{
911 .op1 = .{ .mem = Memory.sib(.dword, .{ .base = .r11 }) },925 .{ .mem = Memory.sib(.dword, .{ .base = .r11 }) },
912 .op2 = .{ .imm = Immediate.u(0x10) },926 .{ .imm = Immediate.u(0x10) },
913 });927 });
914 try expectEqualHexStrings("\x41\xc7\x03\x10\x00\x00\x00", enc.code(), "mov DWORD PTR [r11], 0x10");928 try expectEqualHexStrings("\x41\xc7\x03\x10\x00\x00\x00", enc.code(), "mov DWORD PTR [r11], 0x10");
915929
916 try enc.encode(.mov, .{930 try enc.encode(.mov, &.{
917 .op1 = .{ .mem = Memory.rip(.qword, 0x10) },931 .{ .mem = Memory.rip(.qword, 0x10) },
918 .op2 = .{ .imm = Immediate.u(0x10) },932 .{ .imm = Immediate.u(0x10) },
919 });933 });
920 try expectEqualHexStrings(934 try expectEqualHexStrings(
921 "\x48\xC7\x05\x10\x00\x00\x00\x10\x00\x00\x00",935 "\x48\xC7\x05\x10\x00\x00\x00\x10\x00\x00\x00",
...@@ -923,99 +937,108 @@ test "lower MI encoding" {...@@ -923,99 +937,108 @@ test "lower MI encoding" {
923 "mov QWORD PTR [rip + 0x10], 0x10",937 "mov QWORD PTR [rip + 0x10], 0x10",
924 );938 );
925939
926 try enc.encode(.mov, .{ .op1 = .{ .mem = Memory.sib(.qword, .{940 try enc.encode(.mov, &.{
927 .base = .rbp,941 .{ .mem = Memory.sib(.qword, .{ .base = .rbp, .disp = -8 }) },
928 .disp = -8,942 .{ .imm = Immediate.u(0x10) },
929 }) }, .op2 = .{ .imm = Immediate.u(0x10) } });943 });
930 try expectEqualHexStrings("\x48\xc7\x45\xf8\x10\x00\x00\x00", enc.code(), "mov QWORD PTR [rbp - 8], 0x10");944 try expectEqualHexStrings("\x48\xc7\x45\xf8\x10\x00\x00\x00", enc.code(), "mov QWORD PTR [rbp - 8], 0x10");
931945
932 try enc.encode(.mov, .{ .op1 = .{ .mem = Memory.sib(.word, .{946 try enc.encode(.mov, &.{
933 .base = .rbp,947 .{ .mem = Memory.sib(.word, .{ .base = .rbp, .disp = -2 }) },
934 .disp = -2,948 .{ .imm = Immediate.s(-16) },
935 }) }, .op2 = .{ .imm = Immediate.s(-16) } });949 });
936 try expectEqualHexStrings("\x66\xC7\x45\xFE\xF0\xFF", enc.code(), "mov WORD PTR [rbp - 2], -16");950 try expectEqualHexStrings("\x66\xC7\x45\xFE\xF0\xFF", enc.code(), "mov WORD PTR [rbp - 2], -16");
937951
938 try enc.encode(.mov, .{ .op1 = .{ .mem = Memory.sib(.byte, .{952 try enc.encode(.mov, &.{
939 .base = .rbp,953 .{ .mem = Memory.sib(.byte, .{ .base = .rbp, .disp = -1 }) },
940 .disp = -1,954 .{ .imm = Immediate.u(0x10) },
941 }) }, .op2 = .{ .imm = Immediate.u(0x10) } });955 });
942 try expectEqualHexStrings("\xC6\x45\xFF\x10", enc.code(), "mov BYTE PTR [rbp - 1], 0x10");956 try expectEqualHexStrings("\xC6\x45\xFF\x10", enc.code(), "mov BYTE PTR [rbp - 1], 0x10");
943957
944 try enc.encode(.mov, .{ .op1 = .{ .mem = Memory.sib(.qword, .{958 try enc.encode(.mov, &.{
945 .base = .ds,959 .{ .mem = Memory.sib(.qword, .{
946 .disp = 0x10000000,960 .base = .ds,
947 .scale_index = .{961 .disp = 0x10000000,
948 .scale = 2,962 .scale_index = .{ .scale = 2, .index = .rcx },
949 .index = .rcx,963 }) },
950 },964 .{ .imm = Immediate.u(0x10) },
951 }) }, .op2 = .{ .imm = Immediate.u(0x10) } });965 });
952 try expectEqualHexStrings(966 try expectEqualHexStrings(
953 "\x48\xC7\x04\x4D\x00\x00\x00\x10\x10\x00\x00\x00",967 "\x48\xC7\x04\x4D\x00\x00\x00\x10\x10\x00\x00\x00",
954 enc.code(),968 enc.code(),
955 "mov QWORD PTR [rcx*2 + 0x10000000], 0x10",969 "mov QWORD PTR [rcx*2 + 0x10000000], 0x10",
956 );970 );
957971
958 try enc.encode(.adc, .{ .op1 = .{ .mem = Memory.sib(.byte, .{972 try enc.encode(.adc, &.{
959 .base = .rbp,973 .{ .mem = Memory.sib(.byte, .{ .base = .rbp, .disp = -0x10 }) },
960 .disp = -0x10,974 .{ .imm = Immediate.u(0x10) },
961 }) }, .op2 = .{ .imm = Immediate.u(0x10) } });975 });
962 try expectEqualHexStrings("\x80\x55\xF0\x10", enc.code(), "adc BYTE PTR [rbp - 0x10], 0x10");976 try expectEqualHexStrings("\x80\x55\xF0\x10", enc.code(), "adc BYTE PTR [rbp - 0x10], 0x10");
963977
964 try enc.encode(.adc, .{ .op1 = .{ .mem = Memory.rip(.qword, 0) }, .op2 = .{ .imm = Immediate.u(0x10) } });978 try enc.encode(.adc, &.{
979 .{ .mem = Memory.rip(.qword, 0) },
980 .{ .imm = Immediate.u(0x10) },
981 });
965 try expectEqualHexStrings("\x48\x83\x15\x00\x00\x00\x00\x10", enc.code(), "adc QWORD PTR [rip], 0x10");982 try expectEqualHexStrings("\x48\x83\x15\x00\x00\x00\x00\x10", enc.code(), "adc QWORD PTR [rip], 0x10");
966983
967 try enc.encode(.adc, .{ .op1 = .{ .reg = .rax }, .op2 = .{ .imm = Immediate.u(0x10) } });984 try enc.encode(.adc, &.{
985 .{ .reg = .rax },
986 .{ .imm = Immediate.u(0x10) },
987 });
968 try expectEqualHexStrings("\x48\x83\xD0\x10", enc.code(), "adc rax, 0x10");988 try expectEqualHexStrings("\x48\x83\xD0\x10", enc.code(), "adc rax, 0x10");
969989
970 try enc.encode(.add, .{ .op1 = .{ .mem = Memory.sib(.dword, .{990 try enc.encode(.add, &.{
971 .base = .rdx,991 .{ .mem = Memory.sib(.dword, .{ .base = .rdx, .disp = -8 }) },
972 .disp = -8,992 .{ .imm = Immediate.u(0x10) },
973 }) }, .op2 = .{ .imm = Immediate.u(0x10) } });993 });
974 try expectEqualHexStrings("\x83\x42\xF8\x10", enc.code(), "add DWORD PTR [rdx - 8], 0x10");994 try expectEqualHexStrings("\x83\x42\xF8\x10", enc.code(), "add DWORD PTR [rdx - 8], 0x10");
975995
976 try enc.encode(.add, .{ .op1 = .{ .reg = .rax }, .op2 = .{ .imm = Immediate.u(0x10) } });996 try enc.encode(.add, &.{
997 .{ .reg = .rax },
998 .{ .imm = Immediate.u(0x10) },
999 });
977 try expectEqualHexStrings("\x48\x83\xC0\x10", enc.code(), "add rax, 0x10");1000 try expectEqualHexStrings("\x48\x83\xC0\x10", enc.code(), "add rax, 0x10");
9781001
979 try enc.encode(.add, .{ .op1 = .{ .mem = Memory.sib(.qword, .{1002 try enc.encode(.add, &.{
980 .base = .rbp,1003 .{ .mem = Memory.sib(.qword, .{ .base = .rbp, .disp = -0x10 }) },
981 .disp = -0x10,1004 .{ .imm = Immediate.s(-0x10) },
982 }) }, .op2 = .{ .imm = Immediate.s(-0x10) } });1005 });
983 try expectEqualHexStrings("\x48\x83\x45\xF0\xF0", enc.code(), "add QWORD PTR [rbp - 0x10], -0x10");1006 try expectEqualHexStrings("\x48\x83\x45\xF0\xF0", enc.code(), "add QWORD PTR [rbp - 0x10], -0x10");
9841007
985 try enc.encode(.@"and", .{ .op1 = .{ .mem = Memory.sib(.dword, .{1008 try enc.encode(.@"and", &.{
986 .base = .ds,1009 .{ .mem = Memory.sib(.dword, .{ .base = .ds, .disp = 0x10000000 }) },
987 .disp = 0x10000000,1010 .{ .imm = Immediate.u(0x10) },
988 }) }, .op2 = .{ .imm = Immediate.u(0x10) } });1011 });
989 try expectEqualHexStrings(1012 try expectEqualHexStrings(
990 "\x83\x24\x25\x00\x00\x00\x10\x10",1013 "\x83\x24\x25\x00\x00\x00\x10\x10",
991 enc.code(),1014 enc.code(),
992 "and DWORD PTR ds:0x10000000, 0x10",1015 "and DWORD PTR ds:0x10000000, 0x10",
993 );1016 );
9941017
995 try enc.encode(.@"and", .{ .op1 = .{ .mem = Memory.sib(.dword, .{1018 try enc.encode(.@"and", &.{
996 .base = .es,1019 .{ .mem = Memory.sib(.dword, .{ .base = .es, .disp = 0x10000000 }) },
997 .disp = 0x10000000,1020 .{ .imm = Immediate.u(0x10) },
998 }) }, .op2 = .{ .imm = Immediate.u(0x10) } });1021 });
999 try expectEqualHexStrings(1022 try expectEqualHexStrings(
1000 "\x26\x83\x24\x25\x00\x00\x00\x10\x10",1023 "\x26\x83\x24\x25\x00\x00\x00\x10\x10",
1001 enc.code(),1024 enc.code(),
1002 "and DWORD PTR es:0x10000000, 0x10",1025 "and DWORD PTR es:0x10000000, 0x10",
1003 );1026 );
10041027
1005 try enc.encode(.@"and", .{ .op1 = .{ .mem = Memory.sib(.dword, .{1028 try enc.encode(.@"and", &.{
1006 .base = .r12,1029 .{ .mem = Memory.sib(.dword, .{ .base = .r12, .disp = 0x10000000 }) },
1007 .disp = 0x10000000,1030 .{ .imm = Immediate.u(0x10) },
1008 }) }, .op2 = .{ .imm = Immediate.u(0x10) } });1031 });
1009 try expectEqualHexStrings(1032 try expectEqualHexStrings(
1010 "\x41\x83\xA4\x24\x00\x00\x00\x10\x10",1033 "\x41\x83\xA4\x24\x00\x00\x00\x10\x10",
1011 enc.code(),1034 enc.code(),
1012 "and DWORD PTR [r12 + 0x10000000], 0x10",1035 "and DWORD PTR [r12 + 0x10000000], 0x10",
1013 );1036 );
10141037
1015 try enc.encode(.sub, .{ .op1 = .{ .mem = Memory.sib(.dword, .{1038 try enc.encode(.sub, &.{
1016 .base = .r11,1039 .{ .mem = Memory.sib(.dword, .{ .base = .r11, .disp = 0x10000000 }) },
1017 .disp = 0x10000000,1040 .{ .imm = Immediate.u(0x10) },
1018 }) }, .op2 = .{ .imm = Immediate.u(0x10) } });1041 });
1019 try expectEqualHexStrings(1042 try expectEqualHexStrings(
1020 "\x41\x83\xAB\x00\x00\x00\x10\x10",1043 "\x41\x83\xAB\x00\x00\x00\x10\x10",
1021 enc.code(),1044 enc.code(),
...@@ -1026,185 +1049,227 @@ test "lower MI encoding" {...@@ -1026,185 +1049,227 @@ test "lower MI encoding" {
1026test "lower RM encoding" {1049test "lower RM encoding" {
1027 var enc = TestEncode{};1050 var enc = TestEncode{};
10281051
1029 try enc.encode(.mov, .{1052 try enc.encode(.mov, &.{
1030 .op1 = .{ .reg = .rax },1053 .{ .reg = .rax },
1031 .op2 = .{ .mem = Memory.sib(.qword, .{ .base = .r11 }) },1054 .{ .mem = Memory.sib(.qword, .{ .base = .r11 }) },
1032 });1055 });
1033 try expectEqualHexStrings("\x49\x8b\x03", enc.code(), "mov rax, QWORD PTR [r11]");1056 try expectEqualHexStrings("\x49\x8b\x03", enc.code(), "mov rax, QWORD PTR [r11]");
10341057
1035 try enc.encode(.mov, .{ .op1 = .{ .reg = .rbx }, .op2 = .{ .mem = Memory.sib(.qword, .{1058 try enc.encode(.mov, &.{
1036 .base = .ds,1059 .{ .reg = .rbx },
1037 .disp = 0x10,1060 .{ .mem = Memory.sib(.qword, .{ .base = .ds, .disp = 0x10 }) },
1038 }) } });1061 });
1039 try expectEqualHexStrings("\x48\x8B\x1C\x25\x10\x00\x00\x00", enc.code(), "mov rbx, QWORD PTR ds:0x10");1062 try expectEqualHexStrings("\x48\x8B\x1C\x25\x10\x00\x00\x00", enc.code(), "mov rbx, QWORD PTR ds:0x10");
10401063
1041 try enc.encode(.mov, .{ .op1 = .{ .reg = .rax }, .op2 = .{ .mem = Memory.sib(.qword, .{1064 try enc.encode(.mov, &.{
1042 .base = .rbp,1065 .{ .reg = .rax },
1043 .disp = -4,1066 .{ .mem = Memory.sib(.qword, .{ .base = .rbp, .disp = -4 }) },
1044 }) } });1067 });
1045 try expectEqualHexStrings("\x48\x8B\x45\xFC", enc.code(), "mov rax, QWORD PTR [rbp - 4]");1068 try expectEqualHexStrings("\x48\x8B\x45\xFC", enc.code(), "mov rax, QWORD PTR [rbp - 4]");
10461069
1047 try enc.encode(.mov, .{ .op1 = .{ .reg = .rax }, .op2 = .{ .mem = Memory.sib(.qword, .{1070 try enc.encode(.mov, &.{
1048 .base = .rbp,1071 .{ .reg = .rax },
1049 .scale_index = .{1072 .{ .mem = Memory.sib(.qword, .{
1050 .scale = 1,1073 .base = .rbp,
1051 .index = .rcx,1074 .scale_index = .{ .scale = 1, .index = .rcx },
1052 },1075 .disp = -8,
1053 .disp = -8,1076 }) },
1054 }) } });1077 });
1055 try expectEqualHexStrings("\x48\x8B\x44\x0D\xF8", enc.code(), "mov rax, QWORD PTR [rbp + rcx*1 - 8]");1078 try expectEqualHexStrings("\x48\x8B\x44\x0D\xF8", enc.code(), "mov rax, QWORD PTR [rbp + rcx*1 - 8]");
10561079
1057 try enc.encode(.mov, .{ .op1 = .{ .reg = .eax }, .op2 = .{ .mem = Memory.sib(.dword, .{1080 try enc.encode(.mov, &.{
1058 .base = .rbp,1081 .{ .reg = .eax },
1059 .scale_index = .{1082 .{ .mem = Memory.sib(.dword, .{
1060 .scale = 4,1083 .base = .rbp,
1061 .index = .rdx,1084 .scale_index = .{ .scale = 4, .index = .rdx },
1062 },1085 .disp = -4,
1063 .disp = -4,1086 }) },
1064 }) } });1087 });
1065 try expectEqualHexStrings("\x8B\x44\x95\xFC", enc.code(), "mov eax, dword ptr [rbp + rdx*4 - 4]");1088 try expectEqualHexStrings("\x8B\x44\x95\xFC", enc.code(), "mov eax, dword ptr [rbp + rdx*4 - 4]");
10661089
1067 try enc.encode(.mov, .{ .op1 = .{ .reg = .rax }, .op2 = .{ .mem = Memory.sib(.qword, .{1090 try enc.encode(.mov, &.{
1068 .base = .rbp,1091 .{ .reg = .rax },
1069 .scale_index = .{1092 .{ .mem = Memory.sib(.qword, .{
1070 .scale = 8,1093 .base = .rbp,
1071 .index = .rcx,1094 .scale_index = .{ .scale = 8, .index = .rcx },
1072 },1095 .disp = -8,
1073 .disp = -8,1096 }) },
1074 }) } });1097 });
1075 try expectEqualHexStrings("\x48\x8B\x44\xCD\xF8", enc.code(), "mov rax, QWORD PTR [rbp + rcx*8 - 8]");1098 try expectEqualHexStrings("\x48\x8B\x44\xCD\xF8", enc.code(), "mov rax, QWORD PTR [rbp + rcx*8 - 8]");
10761099
1077 try enc.encode(.mov, .{ .op1 = .{ .reg = .r8b }, .op2 = .{ .mem = Memory.sib(.byte, .{1100 try enc.encode(.mov, &.{
1078 .base = .rsi,1101 .{ .reg = .r8b },
1079 .scale_index = .{1102 .{ .mem = Memory.sib(.byte, .{
1080 .scale = 1,1103 .base = .rsi,
1081 .index = .rcx,1104 .scale_index = .{ .scale = 1, .index = .rcx },
1082 },1105 .disp = -24,
1083 .disp = -24,1106 }) },
1084 }) } });1107 });
1085 try expectEqualHexStrings("\x44\x8A\x44\x0E\xE8", enc.code(), "mov r8b, BYTE PTR [rsi + rcx*1 - 24]");1108 try expectEqualHexStrings("\x44\x8A\x44\x0E\xE8", enc.code(), "mov r8b, BYTE PTR [rsi + rcx*1 - 24]");
10861109
1087 // TODO this mnemonic needs cleanup as some prefixes are obsolete.1110 // TODO this mnemonic needs cleanup as some prefixes are obsolete.
1088 try enc.encode(.mov, .{ .op1 = .{ .reg = .rax }, .op2 = .{ .reg = .cs } });1111 try enc.encode(.mov, &.{
1112 .{ .reg = .rax },
1113 .{ .reg = .cs },
1114 });
1089 try expectEqualHexStrings("\x48\x8C\xC8", enc.code(), "mov rax, cs");1115 try expectEqualHexStrings("\x48\x8C\xC8", enc.code(), "mov rax, cs");
10901116
1091 try enc.encode(.mov, .{ .op1 = .{ .mem = Memory.sib(.qword, .{1117 try enc.encode(.mov, &.{
1092 .base = .rbp,1118 .{ .mem = Memory.sib(.qword, .{ .base = .rbp, .disp = -16 }) },
1093 .disp = -16,1119 .{ .reg = .fs },
1094 }) }, .op2 = .{ .reg = .fs } });1120 });
1095 try expectEqualHexStrings("\x48\x8C\x65\xF0", enc.code(), "mov QWORD PTR [rbp - 16], fs");1121 try expectEqualHexStrings("\x48\x8C\x65\xF0", enc.code(), "mov QWORD PTR [rbp - 16], fs");
10961122
1097 try enc.encode(.mov, .{ .op1 = .{ .reg = .r12w }, .op2 = .{ .reg = .cs } });1123 try enc.encode(.mov, &.{
1124 .{ .reg = .r12w },
1125 .{ .reg = .cs },
1126 });
1098 try expectEqualHexStrings("\x66\x41\x8C\xCC", enc.code(), "mov r12w, cs");1127 try expectEqualHexStrings("\x66\x41\x8C\xCC", enc.code(), "mov r12w, cs");
10991128
1100 try enc.encode(.mov, .{ .op1 = .{ .mem = Memory.sib(.word, .{1129 try enc.encode(.mov, &.{
1101 .base = .rbp,1130 .{ .mem = Memory.sib(.word, .{ .base = .rbp, .disp = -16 }) },
1102 .disp = -16,1131 .{ .reg = .fs },
1103 }) }, .op2 = .{ .reg = .fs } });1132 });
1104 try expectEqualHexStrings("\x66\x8C\x65\xF0", enc.code(), "mov WORD PTR [rbp - 16], fs");1133 try expectEqualHexStrings("\x66\x8C\x65\xF0", enc.code(), "mov WORD PTR [rbp - 16], fs");
11051134
1106 try enc.encode(.movsx, .{ .op1 = .{ .reg = .eax }, .op2 = .{ .reg = .bx } });1135 try enc.encode(.movsx, &.{
1136 .{ .reg = .eax },
1137 .{ .reg = .bx },
1138 });
1107 try expectEqualHexStrings("\x0F\xBF\xC3", enc.code(), "movsx eax, bx");1139 try expectEqualHexStrings("\x0F\xBF\xC3", enc.code(), "movsx eax, bx");
11081140
1109 try enc.encode(.movsx, .{ .op1 = .{ .reg = .eax }, .op2 = .{ .reg = .bl } });1141 try enc.encode(.movsx, &.{
1142 .{ .reg = .eax },
1143 .{ .reg = .bl },
1144 });
1110 try expectEqualHexStrings("\x0F\xBE\xC3", enc.code(), "movsx eax, bl");1145 try expectEqualHexStrings("\x0F\xBE\xC3", enc.code(), "movsx eax, bl");
11111146
1112 try enc.encode(.movsx, .{ .op1 = .{ .reg = .ax }, .op2 = .{ .reg = .bl } });1147 try enc.encode(.movsx, &.{
1148 .{ .reg = .ax },
1149 .{ .reg = .bl },
1150 });
1113 try expectEqualHexStrings("\x66\x0F\xBE\xC3", enc.code(), "movsx ax, bl");1151 try expectEqualHexStrings("\x66\x0F\xBE\xC3", enc.code(), "movsx ax, bl");
11141152
1115 try enc.encode(.movsx, .{1153 try enc.encode(.movsx, &.{
1116 .op1 = .{ .reg = .eax },1154 .{ .reg = .eax },
1117 .op2 = .{ .mem = Memory.sib(.word, .{ .base = .rbp }) },1155 .{ .mem = Memory.sib(.word, .{ .base = .rbp }) },
1118 });1156 });
1119 try expectEqualHexStrings("\x0F\xBF\x45\x00", enc.code(), "movsx eax, BYTE PTR [rbp]");1157 try expectEqualHexStrings("\x0F\xBF\x45\x00", enc.code(), "movsx eax, BYTE PTR [rbp]");
11201158
1121 try enc.encode(.movsx, .{1159 try enc.encode(.movsx, &.{
1122 .op1 = .{ .reg = .eax },1160 .{ .reg = .eax },
1123 .op2 = .{ .mem = Memory.sib(.byte, .{ .scale_index = .{ .index = .rax, .scale = 2 } }) },1161 .{ .mem = Memory.sib(.byte, .{ .scale_index = .{ .index = .rax, .scale = 2 } }) },
1124 });1162 });
1125 try expectEqualHexStrings("\x0F\xBE\x04\x45\x00\x00\x00\x00", enc.code(), "movsx eax, BYTE PTR [rax * 2]");1163 try expectEqualHexStrings("\x0F\xBE\x04\x45\x00\x00\x00\x00", enc.code(), "movsx eax, BYTE PTR [rax * 2]");
11261164
1127 try enc.encode(.movsx, .{ .op1 = .{ .reg = .ax }, .op2 = .{ .mem = Memory.rip(.byte, 0x10) } });1165 try enc.encode(.movsx, &.{
1166 .{ .reg = .ax },
1167 .{ .mem = Memory.rip(.byte, 0x10) },
1168 });
1128 try expectEqualHexStrings("\x66\x0F\xBE\x05\x10\x00\x00\x00", enc.code(), "movsx ax, BYTE PTR [rip + 0x10]");1169 try expectEqualHexStrings("\x66\x0F\xBE\x05\x10\x00\x00\x00", enc.code(), "movsx ax, BYTE PTR [rip + 0x10]");
11291170
1130 try enc.encode(.movsx, .{ .op1 = .{ .reg = .rax }, .op2 = .{ .reg = .bx } });1171 try enc.encode(.movsx, &.{
1172 .{ .reg = .rax },
1173 .{ .reg = .bx },
1174 });
1131 try expectEqualHexStrings("\x48\x0F\xBF\xC3", enc.code(), "movsx rax, bx");1175 try expectEqualHexStrings("\x48\x0F\xBF\xC3", enc.code(), "movsx rax, bx");
11321176
1133 try enc.encode(.movsxd, .{ .op1 = .{ .reg = .rax }, .op2 = .{ .reg = .ebx } });1177 try enc.encode(.movsxd, &.{
1178 .{ .reg = .rax },
1179 .{ .reg = .ebx },
1180 });
1134 try expectEqualHexStrings("\x48\x63\xC3", enc.code(), "movsxd rax, ebx");1181 try expectEqualHexStrings("\x48\x63\xC3", enc.code(), "movsxd rax, ebx");
11351182
1136 try enc.encode(.lea, .{ .op1 = .{ .reg = .rax }, .op2 = .{ .mem = Memory.rip(.qword, 0x10) } });1183 try enc.encode(.lea, &.{
1184 .{ .reg = .rax },
1185 .{ .mem = Memory.rip(.qword, 0x10) },
1186 });
1137 try expectEqualHexStrings("\x48\x8D\x05\x10\x00\x00\x00", enc.code(), "lea rax, QWORD PTR [rip + 0x10]");1187 try expectEqualHexStrings("\x48\x8D\x05\x10\x00\x00\x00", enc.code(), "lea rax, QWORD PTR [rip + 0x10]");
11381188
1139 try enc.encode(.lea, .{ .op1 = .{ .reg = .rax }, .op2 = .{ .mem = Memory.rip(.dword, 0x10) } });1189 try enc.encode(.lea, &.{
1190 .{ .reg = .rax },
1191 .{ .mem = Memory.rip(.dword, 0x10) },
1192 });
1140 try expectEqualHexStrings("\x48\x8D\x05\x10\x00\x00\x00", enc.code(), "lea rax, DWORD PTR [rip + 0x10]");1193 try expectEqualHexStrings("\x48\x8D\x05\x10\x00\x00\x00", enc.code(), "lea rax, DWORD PTR [rip + 0x10]");
11411194
1142 try enc.encode(.lea, .{ .op1 = .{ .reg = .eax }, .op2 = .{ .mem = Memory.rip(.dword, 0x10) } });1195 try enc.encode(.lea, &.{
1196 .{ .reg = .eax },
1197 .{ .mem = Memory.rip(.dword, 0x10) },
1198 });
1143 try expectEqualHexStrings("\x8D\x05\x10\x00\x00\x00", enc.code(), "lea eax, DWORD PTR [rip + 0x10]");1199 try expectEqualHexStrings("\x8D\x05\x10\x00\x00\x00", enc.code(), "lea eax, DWORD PTR [rip + 0x10]");
11441200
1145 try enc.encode(.lea, .{ .op1 = .{ .reg = .eax }, .op2 = .{ .mem = Memory.rip(.word, 0x10) } });1201 try enc.encode(.lea, &.{
1202 .{ .reg = .eax },
1203 .{ .mem = Memory.rip(.word, 0x10) },
1204 });
1146 try expectEqualHexStrings("\x8D\x05\x10\x00\x00\x00", enc.code(), "lea eax, WORD PTR [rip + 0x10]");1205 try expectEqualHexStrings("\x8D\x05\x10\x00\x00\x00", enc.code(), "lea eax, WORD PTR [rip + 0x10]");
11471206
1148 try enc.encode(.lea, .{ .op1 = .{ .reg = .ax }, .op2 = .{ .mem = Memory.rip(.byte, 0x10) } });1207 try enc.encode(.lea, &.{
1208 .{ .reg = .ax },
1209 .{ .mem = Memory.rip(.byte, 0x10) },
1210 });
1149 try expectEqualHexStrings("\x66\x8D\x05\x10\x00\x00\x00", enc.code(), "lea ax, BYTE PTR [rip + 0x10]");1211 try expectEqualHexStrings("\x66\x8D\x05\x10\x00\x00\x00", enc.code(), "lea ax, BYTE PTR [rip + 0x10]");
11501212
1151 try enc.encode(.lea, .{1213 try enc.encode(.lea, &.{
1152 .op1 = .{ .reg = .rsi },1214 .{ .reg = .rsi },
1153 .op2 = .{ .mem = Memory.sib(.qword, .{1215 .{ .mem = Memory.sib(.qword, .{
1154 .base = .rbp,1216 .base = .rbp,
1155 .scale_index = .{ .scale = 1, .index = .rcx },1217 .scale_index = .{ .scale = 1, .index = .rcx },
1156 }) },1218 }) },
1157 });1219 });
1158 try expectEqualHexStrings("\x48\x8D\x74\x0D\x00", enc.code(), "lea rsi, QWORD PTR [rbp + rcx*1 + 0]");1220 try expectEqualHexStrings("\x48\x8D\x74\x0D\x00", enc.code(), "lea rsi, QWORD PTR [rbp + rcx*1 + 0]");
11591221
1160 try enc.encode(.add, .{ .op1 = .{ .reg = .r11 }, .op2 = .{ .mem = Memory.sib(.qword, .{1222 try enc.encode(.add, &.{
1161 .base = .ds,1223 .{ .reg = .r11 },
1162 .disp = 0x10000000,1224 .{ .mem = Memory.sib(.qword, .{ .base = .ds, .disp = 0x10000000 }) },
1163 }) } });1225 });
1164 try expectEqualHexStrings("\x4C\x03\x1C\x25\x00\x00\x00\x10", enc.code(), "add r11, QWORD PTR ds:0x10000000");1226 try expectEqualHexStrings("\x4C\x03\x1C\x25\x00\x00\x00\x10", enc.code(), "add r11, QWORD PTR ds:0x10000000");
11651227
1166 try enc.encode(.add, .{ .op1 = .{ .reg = .r12b }, .op2 = .{ .mem = Memory.sib(.byte, .{1228 try enc.encode(.add, &.{
1167 .base = .ds,1229 .{ .reg = .r12b },
1168 .disp = 0x10000000,1230 .{ .mem = Memory.sib(.byte, .{ .base = .ds, .disp = 0x10000000 }) },
1169 }) } });1231 });
1170 try expectEqualHexStrings("\x44\x02\x24\x25\x00\x00\x00\x10", enc.code(), "add r11b, BYTE PTR ds:0x10000000");1232 try expectEqualHexStrings("\x44\x02\x24\x25\x00\x00\x00\x10", enc.code(), "add r11b, BYTE PTR ds:0x10000000");
11711233
1172 try enc.encode(.add, .{ .op1 = .{ .reg = .r12b }, .op2 = .{ .mem = Memory.sib(.byte, .{1234 try enc.encode(.add, &.{
1173 .base = .fs,1235 .{ .reg = .r12b },
1174 .disp = 0x10000000,1236 .{ .mem = Memory.sib(.byte, .{ .base = .fs, .disp = 0x10000000 }) },
1175 }) } });1237 });
1176 try expectEqualHexStrings("\x64\x44\x02\x24\x25\x00\x00\x00\x10", enc.code(), "add r11b, BYTE PTR fs:0x10000000");1238 try expectEqualHexStrings("\x64\x44\x02\x24\x25\x00\x00\x00\x10", enc.code(), "add r11b, BYTE PTR fs:0x10000000");
11771239
1178 try enc.encode(.sub, .{ .op1 = .{ .reg = .r11 }, .op2 = .{ .mem = Memory.sib(.qword, .{1240 try enc.encode(.sub, &.{
1179 .base = .r13,1241 .{ .reg = .r11 },
1180 .disp = 0x10000000,1242 .{ .mem = Memory.sib(.qword, .{ .base = .r13, .disp = 0x10000000 }) },
1181 }) } });1243 });
1182 try expectEqualHexStrings("\x4D\x2B\x9D\x00\x00\x00\x10", enc.code(), "sub r11, QWORD PTR [r13 + 0x10000000]");1244 try expectEqualHexStrings("\x4D\x2B\x9D\x00\x00\x00\x10", enc.code(), "sub r11, QWORD PTR [r13 + 0x10000000]");
11831245
1184 try enc.encode(.sub, .{ .op1 = .{ .reg = .r11 }, .op2 = .{ .mem = Memory.sib(.qword, .{1246 try enc.encode(.sub, &.{
1185 .base = .r12,1247 .{ .reg = .r11 },
1186 .disp = 0x10000000,1248 .{ .mem = Memory.sib(.qword, .{ .base = .r12, .disp = 0x10000000 }) },
1187 }) } });1249 });
1188 try expectEqualHexStrings("\x4D\x2B\x9C\x24\x00\x00\x00\x10", enc.code(), "sub r11, QWORD PTR [r12 + 0x10000000]");1250 try expectEqualHexStrings("\x4D\x2B\x9C\x24\x00\x00\x00\x10", enc.code(), "sub r11, QWORD PTR [r12 + 0x10000000]");
11891251
1190 try enc.encode(.imul, .{ .op1 = .{ .reg = .r11 }, .op2 = .{ .reg = .r12 } });1252 try enc.encode(.imul, &.{
1253 .{ .reg = .r11 },
1254 .{ .reg = .r12 },
1255 });
1191 try expectEqualHexStrings("\x4D\x0F\xAF\xDC", enc.code(), "mov r11, r12");1256 try expectEqualHexStrings("\x4D\x0F\xAF\xDC", enc.code(), "mov r11, r12");
1192}1257}
11931258
1194test "lower RMI encoding" {1259test "lower RMI encoding" {
1195 var enc = TestEncode{};1260 var enc = TestEncode{};
11961261
1197 try enc.encode(.imul, .{1262 try enc.encode(.imul, &.{
1198 .op1 = .{ .reg = .r11 },1263 .{ .reg = .r11 },
1199 .op2 = .{ .reg = .r12 },1264 .{ .reg = .r12 },
1200 .op3 = .{ .imm = Immediate.s(-2) },1265 .{ .imm = Immediate.s(-2) },
1201 });1266 });
1202 try expectEqualHexStrings("\x4D\x6B\xDC\xFE", enc.code(), "imul r11, r12, -2");1267 try expectEqualHexStrings("\x4D\x6B\xDC\xFE", enc.code(), "imul r11, r12, -2");
12031268
1204 try enc.encode(.imul, .{1269 try enc.encode(.imul, &.{
1205 .op1 = .{ .reg = .r11 },1270 .{ .reg = .r11 },
1206 .op2 = .{ .mem = Memory.rip(.qword, -16) },1271 .{ .mem = Memory.rip(.qword, -16) },
1207 .op3 = .{ .imm = Immediate.s(-1024) },1272 .{ .imm = Immediate.s(-1024) },
1208 });1273 });
1209 try expectEqualHexStrings(1274 try expectEqualHexStrings(
1210 "\x4C\x69\x1D\xF0\xFF\xFF\xFF\x00\xFC\xFF\xFF",1275 "\x4C\x69\x1D\xF0\xFF\xFF\xFF\x00\xFC\xFF\xFF",
...@@ -1212,13 +1277,10 @@ test "lower RMI encoding" {...@@ -1212,13 +1277,10 @@ test "lower RMI encoding" {
1212 "imul r11, QWORD PTR [rip - 16], -1024",1277 "imul r11, QWORD PTR [rip - 16], -1024",
1213 );1278 );
12141279
1215 try enc.encode(.imul, .{1280 try enc.encode(.imul, &.{
1216 .op1 = .{ .reg = .bx },1281 .{ .reg = .bx },
1217 .op2 = .{ .mem = Memory.sib(.word, .{1282 .{ .mem = Memory.sib(.word, .{ .base = .rbp, .disp = -16 }) },
1218 .base = .rbp,1283 .{ .imm = Immediate.s(-1024) },
1219 .disp = -16,
1220 }) },
1221 .op3 = .{ .imm = Immediate.s(-1024) },
1222 });1284 });
1223 try expectEqualHexStrings(1285 try expectEqualHexStrings(
1224 "\x66\x69\x5D\xF0\x00\xFC",1286 "\x66\x69\x5D\xF0\x00\xFC",
...@@ -1226,13 +1288,10 @@ test "lower RMI encoding" {...@@ -1226,13 +1288,10 @@ test "lower RMI encoding" {
1226 "imul bx, WORD PTR [rbp - 16], -1024",1288 "imul bx, WORD PTR [rbp - 16], -1024",
1227 );1289 );
12281290
1229 try enc.encode(.imul, .{1291 try enc.encode(.imul, &.{
1230 .op1 = .{ .reg = .bx },1292 .{ .reg = .bx },
1231 .op2 = .{ .mem = Memory.sib(.word, .{1293 .{ .mem = Memory.sib(.word, .{ .base = .rbp, .disp = -16 }) },
1232 .base = .rbp,1294 .{ .imm = Immediate.u(1024) },
1233 .disp = -16,
1234 }) },
1235 .op3 = .{ .imm = Immediate.u(1024) },
1236 });1295 });
1237 try expectEqualHexStrings(1296 try expectEqualHexStrings(
1238 "\x66\x69\x5D\xF0\x00\x04",1297 "\x66\x69\x5D\xF0\x00\x04",
...@@ -1244,238 +1303,343 @@ test "lower RMI encoding" {...@@ -1244,238 +1303,343 @@ test "lower RMI encoding" {
1244test "lower MR encoding" {1303test "lower MR encoding" {
1245 var enc = TestEncode{};1304 var enc = TestEncode{};
12461305
1247 try enc.encode(.mov, .{ .op1 = .{ .reg = .rax }, .op2 = .{ .reg = .rbx } });1306 try enc.encode(.mov, &.{
1307 .{ .reg = .rax },
1308 .{ .reg = .rbx },
1309 });
1248 try expectEqualHexStrings("\x48\x89\xD8", enc.code(), "mov rax, rbx");1310 try expectEqualHexStrings("\x48\x89\xD8", enc.code(), "mov rax, rbx");
12491311
1250 try enc.encode(.mov, .{ .op1 = .{ .mem = Memory.sib(.qword, .{1312 try enc.encode(.mov, &.{
1251 .base = .rbp,1313 .{ .mem = Memory.sib(.qword, .{ .base = .rbp, .disp = -4 }) },
1252 .disp = -4,1314 .{ .reg = .r11 },
1253 }) }, .op2 = .{ .reg = .r11 } });1315 });
1254 try expectEqualHexStrings("\x4c\x89\x5d\xfc", enc.code(), "mov QWORD PTR [rbp - 4], r11");1316 try expectEqualHexStrings("\x4c\x89\x5d\xfc", enc.code(), "mov QWORD PTR [rbp - 4], r11");
12551317
1256 try enc.encode(.mov, .{ .op1 = .{ .mem = Memory.rip(.qword, 0x10) }, .op2 = .{ .reg = .r12 } });1318 try enc.encode(.mov, &.{
1319 .{ .mem = Memory.rip(.qword, 0x10) },
1320 .{ .reg = .r12 },
1321 });
1257 try expectEqualHexStrings("\x4C\x89\x25\x10\x00\x00\x00", enc.code(), "mov QWORD PTR [rip + 0x10], r12");1322 try expectEqualHexStrings("\x4C\x89\x25\x10\x00\x00\x00", enc.code(), "mov QWORD PTR [rip + 0x10], r12");
12581323
1259 try enc.encode(.mov, .{ .op1 = .{ .mem = Memory.sib(.qword, .{1324 try enc.encode(.mov, &.{
1260 .base = .r11,1325 .{ .mem = Memory.sib(.qword, .{
1261 .scale_index = .{1326 .base = .r11,
1262 .scale = 2,1327 .scale_index = .{ .scale = 2, .index = .r12 },
1263 .index = .r12,1328 .disp = 0x10,
1264 },1329 }) },
1265 .disp = 0x10,1330 .{ .reg = .r13 },
1266 }) }, .op2 = .{ .reg = .r13 } });1331 });
1267 try expectEqualHexStrings("\x4F\x89\x6C\x63\x10", enc.code(), "mov QWORD PTR [r11 + 2 * r12 + 0x10], r13");1332 try expectEqualHexStrings("\x4F\x89\x6C\x63\x10", enc.code(), "mov QWORD PTR [r11 + 2 * r12 + 0x10], r13");
12681333
1269 try enc.encode(.mov, .{ .op1 = .{ .mem = Memory.rip(.word, -0x10) }, .op2 = .{ .reg = .r12w } });1334 try enc.encode(.mov, &.{
1335 .{ .mem = Memory.rip(.word, -0x10) },
1336 .{ .reg = .r12w },
1337 });
1270 try expectEqualHexStrings("\x66\x44\x89\x25\xF0\xFF\xFF\xFF", enc.code(), "mov WORD PTR [rip - 0x10], r12w");1338 try expectEqualHexStrings("\x66\x44\x89\x25\xF0\xFF\xFF\xFF", enc.code(), "mov WORD PTR [rip - 0x10], r12w");
12711339
1272 try enc.encode(.mov, .{ .op1 = .{ .mem = Memory.sib(.byte, .{1340 try enc.encode(.mov, &.{
1273 .base = .r11,1341 .{ .mem = Memory.sib(.byte, .{
1274 .scale_index = .{1342 .base = .r11,
1275 .scale = 2,1343 .scale_index = .{ .scale = 2, .index = .r12 },
1276 .index = .r12,1344 .disp = 0x10,
1277 },1345 }) },
1278 .disp = 0x10,1346 .{ .reg = .r13b },
1279 }) }, .op2 = .{ .reg = .r13b } });1347 });
1280 try expectEqualHexStrings("\x47\x88\x6C\x63\x10", enc.code(), "mov BYTE PTR [r11 + 2 * r12 + 0x10], r13b");1348 try expectEqualHexStrings("\x47\x88\x6C\x63\x10", enc.code(), "mov BYTE PTR [r11 + 2 * r12 + 0x10], r13b");
12811349
1282 try enc.encode(.add, .{ .op1 = .{ .mem = Memory.sib(.byte, .{1350 try enc.encode(.add, &.{
1283 .base = .ds,1351 .{ .mem = Memory.sib(.byte, .{ .base = .ds, .disp = 0x10000000 }) },
1284 .disp = 0x10000000,1352 .{ .reg = .r12b },
1285 }) }, .op2 = .{ .reg = .r12b } });1353 });
1286 try expectEqualHexStrings("\x44\x00\x24\x25\x00\x00\x00\x10", enc.code(), "add BYTE PTR ds:0x10000000, r12b");1354 try expectEqualHexStrings("\x44\x00\x24\x25\x00\x00\x00\x10", enc.code(), "add BYTE PTR ds:0x10000000, r12b");
12871355
1288 try enc.encode(.add, .{ .op1 = .{ .mem = Memory.sib(.dword, .{1356 try enc.encode(.add, &.{
1289 .base = .ds,1357 .{ .mem = Memory.sib(.dword, .{ .base = .ds, .disp = 0x10000000 }) },
1290 .disp = 0x10000000,1358 .{ .reg = .r12d },
1291 }) }, .op2 = .{ .reg = .r12d } });1359 });
1292 try expectEqualHexStrings("\x44\x01\x24\x25\x00\x00\x00\x10", enc.code(), "add DWORD PTR [ds:0x10000000], r12d");1360 try expectEqualHexStrings("\x44\x01\x24\x25\x00\x00\x00\x10", enc.code(), "add DWORD PTR [ds:0x10000000], r12d");
12931361
1294 try enc.encode(.add, .{ .op1 = .{ .mem = Memory.sib(.dword, .{1362 try enc.encode(.add, &.{
1295 .base = .gs,1363 .{ .mem = Memory.sib(.dword, .{ .base = .gs, .disp = 0x10000000 }) },
1296 .disp = 0x10000000,1364 .{ .reg = .r12d },
1297 }) }, .op2 = .{ .reg = .r12d } });1365 });
1298 try expectEqualHexStrings("\x65\x44\x01\x24\x25\x00\x00\x00\x10", enc.code(), "add DWORD PTR [gs:0x10000000], r12d");1366 try expectEqualHexStrings("\x65\x44\x01\x24\x25\x00\x00\x00\x10", enc.code(), "add DWORD PTR [gs:0x10000000], r12d");
12991367
1300 try enc.encode(.sub, .{ .op1 = .{ .mem = Memory.sib(.qword, .{1368 try enc.encode(.sub, &.{
1301 .base = .r11,1369 .{ .mem = Memory.sib(.qword, .{ .base = .r11, .disp = 0x10000000 }) },
1302 .disp = 0x10000000,1370 .{ .reg = .r12 },
1303 }) }, .op2 = .{ .reg = .r12 } });1371 });
1304 try expectEqualHexStrings("\x4D\x29\xA3\x00\x00\x00\x10", enc.code(), "sub QWORD PTR [r11 + 0x10000000], r12");1372 try expectEqualHexStrings("\x4D\x29\xA3\x00\x00\x00\x10", enc.code(), "sub QWORD PTR [r11 + 0x10000000], r12");
1305}1373}
13061374
1307test "lower M encoding" {1375test "lower M encoding" {
1308 var enc = TestEncode{};1376 var enc = TestEncode{};
13091377
1310 try enc.encode(.call, .{ .op1 = .{ .reg = .r12 } });1378 try enc.encode(.call, &.{
1379 .{ .reg = .r12 },
1380 });
1311 try expectEqualHexStrings("\x41\xFF\xD4", enc.code(), "call r12");1381 try expectEqualHexStrings("\x41\xFF\xD4", enc.code(), "call r12");
13121382
1313 try enc.encode(.call, .{ .op1 = .{ .mem = Memory.sib(.qword, .{ .base = .r12 }) } });1383 try enc.encode(.call, &.{
1384 .{ .mem = Memory.sib(.qword, .{ .base = .r12 }) },
1385 });
1314 try expectEqualHexStrings("\x41\xFF\x14\x24", enc.code(), "call QWORD PTR [r12]");1386 try expectEqualHexStrings("\x41\xFF\x14\x24", enc.code(), "call QWORD PTR [r12]");
13151387
1316 try enc.encode(.call, .{1388 try enc.encode(.call, &.{
1317 .op1 = .{ .mem = Memory.sib(.qword, .{1389 .{ .mem = Memory.sib(.qword, .{
1318 .base = null,1390 .base = null,
1319 .scale_index = .{ .index = .r11, .scale = 2 },1391 .scale_index = .{ .index = .r11, .scale = 2 },
1320 }) },1392 }) },
1321 });1393 });
1322 try expectEqualHexStrings("\x42\xFF\x14\x5D\x00\x00\x00\x00", enc.code(), "call QWORD PTR [r11 * 2]");1394 try expectEqualHexStrings("\x42\xFF\x14\x5D\x00\x00\x00\x00", enc.code(), "call QWORD PTR [r11 * 2]");
13231395
1324 try enc.encode(.call, .{1396 try enc.encode(.call, &.{
1325 .op1 = .{ .mem = Memory.sib(.qword, .{1397 .{ .mem = Memory.sib(.qword, .{
1326 .base = null,1398 .base = null,
1327 .scale_index = .{ .index = .r12, .scale = 2 },1399 .scale_index = .{ .index = .r12, .scale = 2 },
1328 }) },1400 }) },
1329 });1401 });
1330 try expectEqualHexStrings("\x42\xFF\x14\x65\x00\x00\x00\x00", enc.code(), "call QWORD PTR [r12 * 2]");1402 try expectEqualHexStrings("\x42\xFF\x14\x65\x00\x00\x00\x00", enc.code(), "call QWORD PTR [r12 * 2]");
13311403
1332 try enc.encode(.call, .{ .op1 = .{ .mem = Memory.sib(.qword, .{ .base = .gs }) } });1404 try enc.encode(.call, &.{
1405 .{ .mem = Memory.sib(.qword, .{ .base = .gs }) },
1406 });
1333 try expectEqualHexStrings("\x65\xFF\x14\x25\x00\x00\x00\x00", enc.code(), "call gs:0x0");1407 try expectEqualHexStrings("\x65\xFF\x14\x25\x00\x00\x00\x00", enc.code(), "call gs:0x0");
13341408
1335 try enc.encode(.call, .{ .op1 = .{ .imm = Immediate.s(0) } });1409 try enc.encode(.call, &.{
1410 .{ .imm = Immediate.s(0) },
1411 });
1336 try expectEqualHexStrings("\xE8\x00\x00\x00\x00", enc.code(), "call 0x0");1412 try expectEqualHexStrings("\xE8\x00\x00\x00\x00", enc.code(), "call 0x0");
13371413
1338 try enc.encode(.push, .{ .op1 = .{ .mem = Memory.sib(.qword, .{ .base = .rbp }) } });1414 try enc.encode(.push, &.{
1415 .{ .mem = Memory.sib(.qword, .{ .base = .rbp }) },
1416 });
1339 try expectEqualHexStrings("\xFF\x75\x00", enc.code(), "push QWORD PTR [rbp]");1417 try expectEqualHexStrings("\xFF\x75\x00", enc.code(), "push QWORD PTR [rbp]");
13401418
1341 try enc.encode(.push, .{ .op1 = .{ .mem = Memory.sib(.word, .{ .base = .rbp }) } });1419 try enc.encode(.push, &.{
1420 .{ .mem = Memory.sib(.word, .{ .base = .rbp }) },
1421 });
1342 try expectEqualHexStrings("\x66\xFF\x75\x00", enc.code(), "push QWORD PTR [rbp]");1422 try expectEqualHexStrings("\x66\xFF\x75\x00", enc.code(), "push QWORD PTR [rbp]");
13431423
1344 try enc.encode(.pop, .{ .op1 = .{ .mem = Memory.rip(.qword, 0) } });1424 try enc.encode(.pop, &.{
1425 .{ .mem = Memory.rip(.qword, 0) },
1426 });
1345 try expectEqualHexStrings("\x8F\x05\x00\x00\x00\x00", enc.code(), "pop QWORD PTR [rip]");1427 try expectEqualHexStrings("\x8F\x05\x00\x00\x00\x00", enc.code(), "pop QWORD PTR [rip]");
13461428
1347 try enc.encode(.pop, .{ .op1 = .{ .mem = Memory.rip(.word, 0) } });1429 try enc.encode(.pop, &.{
1430 .{ .mem = Memory.rip(.word, 0) },
1431 });
1348 try expectEqualHexStrings("\x66\x8F\x05\x00\x00\x00\x00", enc.code(), "pop WORD PTR [rbp]");1432 try expectEqualHexStrings("\x66\x8F\x05\x00\x00\x00\x00", enc.code(), "pop WORD PTR [rbp]");
13491433
1350 try enc.encode(.imul, .{ .op1 = .{ .reg = .rax } });1434 try enc.encode(.imul, &.{
1435 .{ .reg = .rax },
1436 });
1351 try expectEqualHexStrings("\x48\xF7\xE8", enc.code(), "imul rax");1437 try expectEqualHexStrings("\x48\xF7\xE8", enc.code(), "imul rax");
13521438
1353 try enc.encode(.imul, .{ .op1 = .{ .reg = .r12 } });1439 try enc.encode(.imul, &.{
1440 .{ .reg = .r12 },
1441 });
1354 try expectEqualHexStrings("\x49\xF7\xEC", enc.code(), "imul r12");1442 try expectEqualHexStrings("\x49\xF7\xEC", enc.code(), "imul r12");
1355}1443}
13561444
1357test "lower O encoding" {1445test "lower O encoding" {
1358 var enc = TestEncode{};1446 var enc = TestEncode{};
13591447
1360 try enc.encode(.push, .{ .op1 = .{ .reg = .rax } });1448 try enc.encode(.push, &.{
1449 .{ .reg = .rax },
1450 });
1361 try expectEqualHexStrings("\x50", enc.code(), "push rax");1451 try expectEqualHexStrings("\x50", enc.code(), "push rax");
13621452
1363 try enc.encode(.push, .{ .op1 = .{ .reg = .r12w } });1453 try enc.encode(.push, &.{
1454 .{ .reg = .r12w },
1455 });
1364 try expectEqualHexStrings("\x66\x41\x54", enc.code(), "push r12w");1456 try expectEqualHexStrings("\x66\x41\x54", enc.code(), "push r12w");
13651457
1366 try enc.encode(.pop, .{ .op1 = .{ .reg = .r12 } });1458 try enc.encode(.pop, &.{
1459 .{ .reg = .r12 },
1460 });
1367 try expectEqualHexStrings("\x41\x5c", enc.code(), "pop r12");1461 try expectEqualHexStrings("\x41\x5c", enc.code(), "pop r12");
1368}1462}
13691463
1370test "lower OI encoding" {1464test "lower OI encoding" {
1371 var enc = TestEncode{};1465 var enc = TestEncode{};
13721466
1373 try enc.encode(.mov, .{ .op1 = .{ .reg = .rax }, .op2 = .{ .imm = Immediate.u(0x1000000000000000) } });1467 try enc.encode(.mov, &.{
1468 .{ .reg = .rax },
1469 .{ .imm = Immediate.u(0x1000000000000000) },
1470 });
1374 try expectEqualHexStrings(1471 try expectEqualHexStrings(
1375 "\x48\xB8\x00\x00\x00\x00\x00\x00\x00\x10",1472 "\x48\xB8\x00\x00\x00\x00\x00\x00\x00\x10",
1376 enc.code(),1473 enc.code(),
1377 "movabs rax, 0x1000000000000000",1474 "movabs rax, 0x1000000000000000",
1378 );1475 );
13791476
1380 try enc.encode(.mov, .{ .op1 = .{ .reg = .r11 }, .op2 = .{ .imm = Immediate.u(0x1000000000000000) } });1477 try enc.encode(.mov, &.{
1478 .{ .reg = .r11 },
1479 .{ .imm = Immediate.u(0x1000000000000000) },
1480 });
1381 try expectEqualHexStrings(1481 try expectEqualHexStrings(
1382 "\x49\xBB\x00\x00\x00\x00\x00\x00\x00\x10",1482 "\x49\xBB\x00\x00\x00\x00\x00\x00\x00\x10",
1383 enc.code(),1483 enc.code(),
1384 "movabs r11, 0x1000000000000000",1484 "movabs r11, 0x1000000000000000",
1385 );1485 );
13861486
1387 try enc.encode(.mov, .{ .op1 = .{ .reg = .r11d }, .op2 = .{ .imm = Immediate.u(0x10000000) } });1487 try enc.encode(.mov, &.{
1488 .{ .reg = .r11d },
1489 .{ .imm = Immediate.u(0x10000000) },
1490 });
1388 try expectEqualHexStrings("\x41\xBB\x00\x00\x00\x10", enc.code(), "mov r11d, 0x10000000");1491 try expectEqualHexStrings("\x41\xBB\x00\x00\x00\x10", enc.code(), "mov r11d, 0x10000000");
13891492
1390 try enc.encode(.mov, .{ .op1 = .{ .reg = .r11w }, .op2 = .{ .imm = Immediate.u(0x1000) } });1493 try enc.encode(.mov, &.{
1494 .{ .reg = .r11w },
1495 .{ .imm = Immediate.u(0x1000) },
1496 });
1391 try expectEqualHexStrings("\x66\x41\xBB\x00\x10", enc.code(), "mov r11w, 0x1000");1497 try expectEqualHexStrings("\x66\x41\xBB\x00\x10", enc.code(), "mov r11w, 0x1000");
13921498
1393 try enc.encode(.mov, .{ .op1 = .{ .reg = .r11b }, .op2 = .{ .imm = Immediate.u(0x10) } });1499 try enc.encode(.mov, &.{
1500 .{ .reg = .r11b },
1501 .{ .imm = Immediate.u(0x10) },
1502 });
1394 try expectEqualHexStrings("\x41\xB3\x10", enc.code(), "mov r11b, 0x10");1503 try expectEqualHexStrings("\x41\xB3\x10", enc.code(), "mov r11b, 0x10");
1395}1504}
13961505
1397test "lower FD/TD encoding" {1506test "lower FD/TD encoding" {
1398 var enc = TestEncode{};1507 var enc = TestEncode{};
13991508
1400 try enc.encode(.mov, .{ .op1 = .{ .reg = .rax }, .op2 = .{ .mem = Memory.moffs(.cs, 0x10) } });1509 try enc.encode(.mov, &.{
1510 .{ .reg = .rax },
1511 .{ .mem = Memory.moffs(.cs, 0x10) },
1512 });
1401 try expectEqualHexStrings("\x2E\x48\xA1\x10\x00\x00\x00\x00\x00\x00\x00", enc.code(), "movabs rax, cs:0x10");1513 try expectEqualHexStrings("\x2E\x48\xA1\x10\x00\x00\x00\x00\x00\x00\x00", enc.code(), "movabs rax, cs:0x10");
14021514
1403 try enc.encode(.mov, .{ .op1 = .{ .reg = .eax }, .op2 = .{ .mem = Memory.moffs(.fs, 0x10) } });1515 try enc.encode(.mov, &.{
1516 .{ .reg = .eax },
1517 .{ .mem = Memory.moffs(.fs, 0x10) },
1518 });
1404 try expectEqualHexStrings("\x64\xA1\x10\x00\x00\x00\x00\x00\x00\x00", enc.code(), "movabs eax, fs:0x10");1519 try expectEqualHexStrings("\x64\xA1\x10\x00\x00\x00\x00\x00\x00\x00", enc.code(), "movabs eax, fs:0x10");
14051520
1406 try enc.encode(.mov, .{ .op1 = .{ .reg = .ax }, .op2 = .{ .mem = Memory.moffs(.gs, 0x10) } });1521 try enc.encode(.mov, &.{
1522 .{ .reg = .ax },
1523 .{ .mem = Memory.moffs(.gs, 0x10) },
1524 });
1407 try expectEqualHexStrings("\x65\x66\xA1\x10\x00\x00\x00\x00\x00\x00\x00", enc.code(), "movabs ax, gs:0x10");1525 try expectEqualHexStrings("\x65\x66\xA1\x10\x00\x00\x00\x00\x00\x00\x00", enc.code(), "movabs ax, gs:0x10");
14081526
1409 try enc.encode(.mov, .{ .op1 = .{ .reg = .al }, .op2 = .{ .mem = Memory.moffs(.ds, 0x10) } });1527 try enc.encode(.mov, &.{
1528 .{ .reg = .al },
1529 .{ .mem = Memory.moffs(.ds, 0x10) },
1530 });
1410 try expectEqualHexStrings("\xA0\x10\x00\x00\x00\x00\x00\x00\x00", enc.code(), "movabs al, ds:0x10");1531 try expectEqualHexStrings("\xA0\x10\x00\x00\x00\x00\x00\x00\x00", enc.code(), "movabs al, ds:0x10");
14111532
1412 try enc.encode(.mov, .{ .op1 = .{ .mem = Memory.moffs(.cs, 0x10) }, .op2 = .{ .reg = .rax } });1533 try enc.encode(.mov, &.{
1534 .{ .mem = Memory.moffs(.cs, 0x10) },
1535 .{ .reg = .rax },
1536 });
1413 try expectEqualHexStrings("\x2E\x48\xA3\x10\x00\x00\x00\x00\x00\x00\x00", enc.code(), "movabs cs:0x10, rax");1537 try expectEqualHexStrings("\x2E\x48\xA3\x10\x00\x00\x00\x00\x00\x00\x00", enc.code(), "movabs cs:0x10, rax");
14141538
1415 try enc.encode(.mov, .{ .op1 = .{ .mem = Memory.moffs(.fs, 0x10) }, .op2 = .{ .reg = .eax } });1539 try enc.encode(.mov, &.{
1540 .{ .mem = Memory.moffs(.fs, 0x10) },
1541 .{ .reg = .eax },
1542 });
1416 try expectEqualHexStrings("\x64\xA3\x10\x00\x00\x00\x00\x00\x00\x00", enc.code(), "movabs fs:0x10, eax");1543 try expectEqualHexStrings("\x64\xA3\x10\x00\x00\x00\x00\x00\x00\x00", enc.code(), "movabs fs:0x10, eax");
14171544
1418 try enc.encode(.mov, .{ .op1 = .{ .mem = Memory.moffs(.gs, 0x10) }, .op2 = .{ .reg = .ax } });1545 try enc.encode(.mov, &.{
1546 .{ .mem = Memory.moffs(.gs, 0x10) },
1547 .{ .reg = .ax },
1548 });
1419 try expectEqualHexStrings("\x65\x66\xA3\x10\x00\x00\x00\x00\x00\x00\x00", enc.code(), "movabs gs:0x10, ax");1549 try expectEqualHexStrings("\x65\x66\xA3\x10\x00\x00\x00\x00\x00\x00\x00", enc.code(), "movabs gs:0x10, ax");
14201550
1421 try enc.encode(.mov, .{ .op1 = .{ .mem = Memory.moffs(.ds, 0x10) }, .op2 = .{ .reg = .al } });1551 try enc.encode(.mov, &.{
1552 .{ .mem = Memory.moffs(.ds, 0x10) },
1553 .{ .reg = .al },
1554 });
1422 try expectEqualHexStrings("\xA2\x10\x00\x00\x00\x00\x00\x00\x00", enc.code(), "movabs ds:0x10, al");1555 try expectEqualHexStrings("\xA2\x10\x00\x00\x00\x00\x00\x00\x00", enc.code(), "movabs ds:0x10, al");
1423}1556}
14241557
1425test "lower NP encoding" {1558test "lower NP encoding" {
1426 var enc = TestEncode{};1559 var enc = TestEncode{};
14271560
1428 try enc.encode(.int3, .{});1561 try enc.encode(.int3, &.{});
1429 try expectEqualHexStrings("\xCC", enc.code(), "int3");1562 try expectEqualHexStrings("\xCC", enc.code(), "int3");
14301563
1431 try enc.encode(.nop, .{});1564 try enc.encode(.nop, &.{});
1432 try expectEqualHexStrings("\x90", enc.code(), "nop");1565 try expectEqualHexStrings("\x90", enc.code(), "nop");
14331566
1434 try enc.encode(.ret, .{});1567 try enc.encode(.ret, &.{});
1435 try expectEqualHexStrings("\xC3", enc.code(), "ret");1568 try expectEqualHexStrings("\xC3", enc.code(), "ret");
14361569
1437 try enc.encode(.syscall, .{});1570 try enc.encode(.syscall, &.{});
1438 try expectEqualHexStrings("\x0f\x05", enc.code(), "syscall");1571 try expectEqualHexStrings("\x0f\x05", enc.code(), "syscall");
1439}1572}
14401573
1441fn invalidInstruction(mnemonic: Instruction.Mnemonic, args: Instruction.Init) !void {1574fn invalidInstruction(mnemonic: Instruction.Mnemonic, ops: []const Instruction.Operand) !void {
1442 const err = Instruction.new(mnemonic, args);1575 const err = Instruction.new(.none, mnemonic, ops);
1443 try testing.expectError(error.InvalidInstruction, err);1576 try testing.expectError(error.InvalidInstruction, err);
1444}1577}
14451578
1446test "invalid instruction" {1579test "invalid instruction" {
1447 try invalidInstruction(.call, .{ .op1 = .{ .reg = .eax } });1580 try invalidInstruction(.call, &.{
1448 try invalidInstruction(.call, .{ .op1 = .{ .reg = .ax } });1581 .{ .reg = .eax },
1449 try invalidInstruction(.call, .{ .op1 = .{ .reg = .al } });1582 });
1450 try invalidInstruction(.call, .{ .op1 = .{ .mem = Memory.rip(.dword, 0) } });1583 try invalidInstruction(.call, &.{
1451 try invalidInstruction(.call, .{ .op1 = .{ .mem = Memory.rip(.word, 0) } });1584 .{ .reg = .ax },
1452 try invalidInstruction(.call, .{ .op1 = .{ .mem = Memory.rip(.byte, 0) } });1585 });
1453 try invalidInstruction(.mov, .{ .op1 = .{ .mem = Memory.rip(.word, 0x10) }, .op2 = .{ .reg = .r12 } });1586 try invalidInstruction(.call, &.{
1454 try invalidInstruction(.lea, .{ .op1 = .{ .reg = .rax }, .op2 = .{ .reg = .rbx } });1587 .{ .reg = .al },
1455 try invalidInstruction(.lea, .{ .op1 = .{ .reg = .al }, .op2 = .{ .mem = Memory.rip(.byte, 0) } });1588 });
1456 try invalidInstruction(.pop, .{ .op1 = .{ .reg = .r12b } });1589 try invalidInstruction(.call, &.{
1457 try invalidInstruction(.pop, .{ .op1 = .{ .reg = .r12d } });1590 .{ .mem = Memory.rip(.dword, 0) },
1458 try invalidInstruction(.push, .{ .op1 = .{ .reg = .r12b } });1591 });
1459 try invalidInstruction(.push, .{ .op1 = .{ .reg = .r12d } });1592 try invalidInstruction(.call, &.{
1460 try invalidInstruction(.push, .{ .op1 = .{ .imm = Immediate.u(0x1000000000000000) } });1593 .{ .mem = Memory.rip(.word, 0) },
1594 });
1595 try invalidInstruction(.call, &.{
1596 .{ .mem = Memory.rip(.byte, 0) },
1597 });
1598 try invalidInstruction(.mov, &.{
1599 .{ .mem = Memory.rip(.word, 0x10) },
1600 .{ .reg = .r12 },
1601 });
1602 try invalidInstruction(.lea, &.{
1603 .{ .reg = .rax },
1604 .{ .reg = .rbx },
1605 });
1606 try invalidInstruction(.lea, &.{
1607 .{ .reg = .al },
1608 .{ .mem = Memory.rip(.byte, 0) },
1609 });
1610 try invalidInstruction(.pop, &.{
1611 .{ .reg = .r12b },
1612 });
1613 try invalidInstruction(.pop, &.{
1614 .{ .reg = .r12d },
1615 });
1616 try invalidInstruction(.push, &.{
1617 .{ .reg = .r12b },
1618 });
1619 try invalidInstruction(.push, &.{
1620 .{ .reg = .r12d },
1621 });
1622 try invalidInstruction(.push, &.{
1623 .{ .imm = Immediate.u(0x1000000000000000) },
1624 });
1461}1625}
14621626
1463fn cannotEncode(mnemonic: Instruction.Mnemonic, args: Instruction.Init) !void {1627fn cannotEncode(mnemonic: Instruction.Mnemonic, ops: []const Instruction.Operand) !void {
1464 try testing.expectError(error.CannotEncode, Instruction.new(mnemonic, args));1628 try testing.expectError(error.CannotEncode, Instruction.new(.none, mnemonic, ops));
1465}1629}
14661630
1467test "cannot encode" {1631test "cannot encode" {
1468 try cannotEncode(.@"test", .{1632 try cannotEncode(.@"test", &.{
1469 .op1 = .{ .mem = Memory.sib(.byte, .{ .base = .r12 }) },1633 .{ .mem = Memory.sib(.byte, .{ .base = .r12 }) },
1470 .op2 = .{ .reg = .ah },1634 .{ .reg = .ah },
1471 });1635 });
1472 try cannotEncode(.@"test", .{1636 try cannotEncode(.@"test", &.{
1473 .op1 = .{ .reg = .r11b },1637 .{ .reg = .r11b },
1474 .op2 = .{ .reg = .bh },1638 .{ .reg = .bh },
1475 });1639 });
1476 try cannotEncode(.mov, .{1640 try cannotEncode(.mov, &.{
1477 .op1 = .{ .reg = .sil },1641 .{ .reg = .sil },
1478 .op2 = .{ .reg = .ah },1642 .{ .reg = .ah },
1479 });1643 });
1480}1644}
14811645
...@@ -1645,12 +1809,7 @@ const Assembler = struct {...@@ -1645,12 +1809,7 @@ const Assembler = struct {
16451809
1646 pub fn assemble(as: *Assembler, writer: anytype) !void {1810 pub fn assemble(as: *Assembler, writer: anytype) !void {
1647 while (try as.next()) |parsed_inst| {1811 while (try as.next()) |parsed_inst| {
1648 const inst = try Instruction.new(parsed_inst.mnemonic, .{1812 const inst = try Instruction.new(.none, parsed_inst.mnemonic, &parsed_inst.ops);
1649 .op1 = parsed_inst.ops[0],
1650 .op2 = parsed_inst.ops[1],
1651 .op3 = parsed_inst.ops[2],
1652 .op4 = parsed_inst.ops[3],
1653 });
1654 try inst.encode(writer);1813 try inst.encode(writer);
1655 }1814 }
1656 }1815 }
src/arch/x86_64/encodings.zig+837-832
...@@ -6,869 +6,874 @@ const Mode = Encoding.Mode;...@@ -6,869 +6,874 @@ const Mode = Encoding.Mode;
66
7const modrm_ext = u3;7const modrm_ext = u3;
88
9const Entry = struct { Mnemonic, OpEn, Op, Op, Op, Op, []const u8, modrm_ext, Mode };9pub const Entry = struct { Mnemonic, OpEn, []const Op, []const u8, modrm_ext, Mode };
1010
11// TODO move this into a .zon file when Zig is capable of importing .zon files11// TODO move this into a .zon file when Zig is capable of importing .zon files
12// zig fmt: off12// zig fmt: off
13pub const table = &[_]Entry{13pub const table = [_]Entry{
14 // General-purpose14 // General-purpose
15 .{ .adc, .zi, .al, .imm8, .none, .none, &.{ 0x14 }, 0, .none },15 .{ .adc, .zi, &.{ .al, .imm8 }, &.{ 0x14 }, 0, .none },
16 .{ .adc, .zi, .ax, .imm16, .none, .none, &.{ 0x15 }, 0, .none },16 .{ .adc, .zi, &.{ .ax, .imm16 }, &.{ 0x15 }, 0, .none },
17 .{ .adc, .zi, .eax, .imm32, .none, .none, &.{ 0x15 }, 0, .none },17 .{ .adc, .zi, &.{ .eax, .imm32 }, &.{ 0x15 }, 0, .none },
18 .{ .adc, .zi, .rax, .imm32s, .none, .none, &.{ 0x15 }, 0, .long },18 .{ .adc, .zi, &.{ .rax, .imm32s }, &.{ 0x15 }, 0, .long },
19 .{ .adc, .mi, .rm8, .imm8, .none, .none, &.{ 0x80 }, 2, .none },19 .{ .adc, .mi, &.{ .rm8, .imm8 }, &.{ 0x80 }, 2, .none },
20 .{ .adc, .mi, .rm8, .imm8, .none, .none, &.{ 0x80 }, 2, .rex },20 .{ .adc, .mi, &.{ .rm8, .imm8 }, &.{ 0x80 }, 2, .rex },
21 .{ .adc, .mi, .rm16, .imm16, .none, .none, &.{ 0x81 }, 2, .none },21 .{ .adc, .mi, &.{ .rm16, .imm16 }, &.{ 0x81 }, 2, .none },
22 .{ .adc, .mi, .rm32, .imm32, .none, .none, &.{ 0x81 }, 2, .none },22 .{ .adc, .mi, &.{ .rm32, .imm32 }, &.{ 0x81 }, 2, .none },
23 .{ .adc, .mi, .rm64, .imm32s, .none, .none, &.{ 0x81 }, 2, .long },23 .{ .adc, .mi, &.{ .rm64, .imm32s }, &.{ 0x81 }, 2, .long },
24 .{ .adc, .mi, .rm16, .imm8s, .none, .none, &.{ 0x83 }, 2, .none },24 .{ .adc, .mi, &.{ .rm16, .imm8s }, &.{ 0x83 }, 2, .none },
25 .{ .adc, .mi, .rm32, .imm8s, .none, .none, &.{ 0x83 }, 2, .none },25 .{ .adc, .mi, &.{ .rm32, .imm8s }, &.{ 0x83 }, 2, .none },
26 .{ .adc, .mi, .rm64, .imm8s, .none, .none, &.{ 0x83 }, 2, .long },26 .{ .adc, .mi, &.{ .rm64, .imm8s }, &.{ 0x83 }, 2, .long },
27 .{ .adc, .mr, .rm8, .r8, .none, .none, &.{ 0x10 }, 0, .none },27 .{ .adc, .mr, &.{ .rm8, .r8 }, &.{ 0x10 }, 0, .none },
28 .{ .adc, .mr, .rm8, .r8, .none, .none, &.{ 0x10 }, 0, .rex },28 .{ .adc, .mr, &.{ .rm8, .r8 }, &.{ 0x10 }, 0, .rex },
29 .{ .adc, .mr, .rm16, .r16, .none, .none, &.{ 0x11 }, 0, .none },29 .{ .adc, .mr, &.{ .rm16, .r16 }, &.{ 0x11 }, 0, .none },
30 .{ .adc, .mr, .rm32, .r32, .none, .none, &.{ 0x11 }, 0, .none },30 .{ .adc, .mr, &.{ .rm32, .r32 }, &.{ 0x11 }, 0, .none },
31 .{ .adc, .mr, .rm64, .r64, .none, .none, &.{ 0x11 }, 0, .long },31 .{ .adc, .mr, &.{ .rm64, .r64 }, &.{ 0x11 }, 0, .long },
32 .{ .adc, .rm, .r8, .rm8, .none, .none, &.{ 0x12 }, 0, .none },32 .{ .adc, .rm, &.{ .r8, .rm8 }, &.{ 0x12 }, 0, .none },
33 .{ .adc, .rm, .r8, .rm8, .none, .none, &.{ 0x12 }, 0, .rex },33 .{ .adc, .rm, &.{ .r8, .rm8 }, &.{ 0x12 }, 0, .rex },
34 .{ .adc, .rm, .r16, .rm16, .none, .none, &.{ 0x13 }, 0, .none },34 .{ .adc, .rm, &.{ .r16, .rm16 }, &.{ 0x13 }, 0, .none },
35 .{ .adc, .rm, .r32, .rm32, .none, .none, &.{ 0x13 }, 0, .none },35 .{ .adc, .rm, &.{ .r32, .rm32 }, &.{ 0x13 }, 0, .none },
36 .{ .adc, .rm, .r64, .rm64, .none, .none, &.{ 0x13 }, 0, .long },36 .{ .adc, .rm, &.{ .r64, .rm64 }, &.{ 0x13 }, 0, .long },
3737
38 .{ .add, .zi, .al, .imm8, .none, .none, &.{ 0x04 }, 0, .none },38 .{ .add, .zi, &.{ .al, .imm8 }, &.{ 0x04 }, 0, .none },
39 .{ .add, .zi, .ax, .imm16, .none, .none, &.{ 0x05 }, 0, .none },39 .{ .add, .zi, &.{ .ax, .imm16 }, &.{ 0x05 }, 0, .none },
40 .{ .add, .zi, .eax, .imm32, .none, .none, &.{ 0x05 }, 0, .none },40 .{ .add, .zi, &.{ .eax, .imm32 }, &.{ 0x05 }, 0, .none },
41 .{ .add, .zi, .rax, .imm32s, .none, .none, &.{ 0x05 }, 0, .long },41 .{ .add, .zi, &.{ .rax, .imm32s }, &.{ 0x05 }, 0, .long },
42 .{ .add, .mi, .rm8, .imm8, .none, .none, &.{ 0x80 }, 0, .none },42 .{ .add, .mi, &.{ .rm8, .imm8 }, &.{ 0x80 }, 0, .none },
43 .{ .add, .mi, .rm8, .imm8, .none, .none, &.{ 0x80 }, 0, .rex },43 .{ .add, .mi, &.{ .rm8, .imm8 }, &.{ 0x80 }, 0, .rex },
44 .{ .add, .mi, .rm16, .imm16, .none, .none, &.{ 0x81 }, 0, .none },44 .{ .add, .mi, &.{ .rm16, .imm16 }, &.{ 0x81 }, 0, .none },
45 .{ .add, .mi, .rm32, .imm32, .none, .none, &.{ 0x81 }, 0, .none },45 .{ .add, .mi, &.{ .rm32, .imm32 }, &.{ 0x81 }, 0, .none },
46 .{ .add, .mi, .rm64, .imm32s, .none, .none, &.{ 0x81 }, 0, .long },46 .{ .add, .mi, &.{ .rm64, .imm32s }, &.{ 0x81 }, 0, .long },
47 .{ .add, .mi, .rm16, .imm8s, .none, .none, &.{ 0x83 }, 0, .none },47 .{ .add, .mi, &.{ .rm16, .imm8s }, &.{ 0x83 }, 0, .none },
48 .{ .add, .mi, .rm32, .imm8s, .none, .none, &.{ 0x83 }, 0, .none },48 .{ .add, .mi, &.{ .rm32, .imm8s }, &.{ 0x83 }, 0, .none },
49 .{ .add, .mi, .rm64, .imm8s, .none, .none, &.{ 0x83 }, 0, .long },49 .{ .add, .mi, &.{ .rm64, .imm8s }, &.{ 0x83 }, 0, .long },
50 .{ .add, .mr, .rm8, .r8, .none, .none, &.{ 0x00 }, 0, .none },50 .{ .add, .mr, &.{ .rm8, .r8 }, &.{ 0x00 }, 0, .none },
51 .{ .add, .mr, .rm8, .r8, .none, .none, &.{ 0x00 }, 0, .rex },51 .{ .add, .mr, &.{ .rm8, .r8 }, &.{ 0x00 }, 0, .rex },
52 .{ .add, .mr, .rm16, .r16, .none, .none, &.{ 0x01 }, 0, .none },52 .{ .add, .mr, &.{ .rm16, .r16 }, &.{ 0x01 }, 0, .none },
53 .{ .add, .mr, .rm32, .r32, .none, .none, &.{ 0x01 }, 0, .none },53 .{ .add, .mr, &.{ .rm32, .r32 }, &.{ 0x01 }, 0, .none },
54 .{ .add, .mr, .rm64, .r64, .none, .none, &.{ 0x01 }, 0, .long },54 .{ .add, .mr, &.{ .rm64, .r64 }, &.{ 0x01 }, 0, .long },
55 .{ .add, .rm, .r8, .rm8, .none, .none, &.{ 0x02 }, 0, .none },55 .{ .add, .rm, &.{ .r8, .rm8 }, &.{ 0x02 }, 0, .none },
56 .{ .add, .rm, .r8, .rm8, .none, .none, &.{ 0x02 }, 0, .rex },56 .{ .add, .rm, &.{ .r8, .rm8 }, &.{ 0x02 }, 0, .rex },
57 .{ .add, .rm, .r16, .rm16, .none, .none, &.{ 0x03 }, 0, .none },57 .{ .add, .rm, &.{ .r16, .rm16 }, &.{ 0x03 }, 0, .none },
58 .{ .add, .rm, .r32, .rm32, .none, .none, &.{ 0x03 }, 0, .none },58 .{ .add, .rm, &.{ .r32, .rm32 }, &.{ 0x03 }, 0, .none },
59 .{ .add, .rm, .r64, .rm64, .none, .none, &.{ 0x03 }, 0, .long },59 .{ .add, .rm, &.{ .r64, .rm64 }, &.{ 0x03 }, 0, .long },
6060
61 .{ .@"and", .zi, .al, .imm8, .none, .none, &.{ 0x24 }, 0, .none },61 .{ .@"and", .zi, &.{ .al, .imm8 }, &.{ 0x24 }, 0, .none },
62 .{ .@"and", .zi, .ax, .imm16, .none, .none, &.{ 0x25 }, 0, .none },62 .{ .@"and", .zi, &.{ .ax, .imm16 }, &.{ 0x25 }, 0, .none },
63 .{ .@"and", .zi, .eax, .imm32, .none, .none, &.{ 0x25 }, 0, .none },63 .{ .@"and", .zi, &.{ .eax, .imm32 }, &.{ 0x25 }, 0, .none },
64 .{ .@"and", .zi, .rax, .imm32s, .none, .none, &.{ 0x25 }, 0, .long },64 .{ .@"and", .zi, &.{ .rax, .imm32s }, &.{ 0x25 }, 0, .long },
65 .{ .@"and", .mi, .rm8, .imm8, .none, .none, &.{ 0x80 }, 4, .none },65 .{ .@"and", .mi, &.{ .rm8, .imm8 }, &.{ 0x80 }, 4, .none },
66 .{ .@"and", .mi, .rm8, .imm8, .none, .none, &.{ 0x80 }, 4, .rex },66 .{ .@"and", .mi, &.{ .rm8, .imm8 }, &.{ 0x80 }, 4, .rex },
67 .{ .@"and", .mi, .rm16, .imm16, .none, .none, &.{ 0x81 }, 4, .none },67 .{ .@"and", .mi, &.{ .rm16, .imm16 }, &.{ 0x81 }, 4, .none },
68 .{ .@"and", .mi, .rm32, .imm32, .none, .none, &.{ 0x81 }, 4, .none },68 .{ .@"and", .mi, &.{ .rm32, .imm32 }, &.{ 0x81 }, 4, .none },
69 .{ .@"and", .mi, .rm64, .imm32s, .none, .none, &.{ 0x81 }, 4, .long },69 .{ .@"and", .mi, &.{ .rm64, .imm32s }, &.{ 0x81 }, 4, .long },
70 .{ .@"and", .mi, .rm16, .imm8s, .none, .none, &.{ 0x83 }, 4, .none },70 .{ .@"and", .mi, &.{ .rm16, .imm8s }, &.{ 0x83 }, 4, .none },
71 .{ .@"and", .mi, .rm32, .imm8s, .none, .none, &.{ 0x83 }, 4, .none },71 .{ .@"and", .mi, &.{ .rm32, .imm8s }, &.{ 0x83 }, 4, .none },
72 .{ .@"and", .mi, .rm64, .imm8s, .none, .none, &.{ 0x83 }, 4, .long },72 .{ .@"and", .mi, &.{ .rm64, .imm8s }, &.{ 0x83 }, 4, .long },
73 .{ .@"and", .mr, .rm8, .r8, .none, .none, &.{ 0x20 }, 0, .none },73 .{ .@"and", .mr, &.{ .rm8, .r8 }, &.{ 0x20 }, 0, .none },
74 .{ .@"and", .mr, .rm8, .r8, .none, .none, &.{ 0x20 }, 0, .rex },74 .{ .@"and", .mr, &.{ .rm8, .r8 }, &.{ 0x20 }, 0, .rex },
75 .{ .@"and", .mr, .rm16, .r16, .none, .none, &.{ 0x21 }, 0, .none },75 .{ .@"and", .mr, &.{ .rm16, .r16 }, &.{ 0x21 }, 0, .none },
76 .{ .@"and", .mr, .rm32, .r32, .none, .none, &.{ 0x21 }, 0, .none },76 .{ .@"and", .mr, &.{ .rm32, .r32 }, &.{ 0x21 }, 0, .none },
77 .{ .@"and", .mr, .rm64, .r64, .none, .none, &.{ 0x21 }, 0, .long },77 .{ .@"and", .mr, &.{ .rm64, .r64 }, &.{ 0x21 }, 0, .long },
78 .{ .@"and", .rm, .r8, .rm8, .none, .none, &.{ 0x22 }, 0, .none },78 .{ .@"and", .rm, &.{ .r8, .rm8 }, &.{ 0x22 }, 0, .none },
79 .{ .@"and", .rm, .r8, .rm8, .none, .none, &.{ 0x22 }, 0, .rex },79 .{ .@"and", .rm, &.{ .r8, .rm8 }, &.{ 0x22 }, 0, .rex },
80 .{ .@"and", .rm, .r16, .rm16, .none, .none, &.{ 0x23 }, 0, .none },80 .{ .@"and", .rm, &.{ .r16, .rm16 }, &.{ 0x23 }, 0, .none },
81 .{ .@"and", .rm, .r32, .rm32, .none, .none, &.{ 0x23 }, 0, .none },81 .{ .@"and", .rm, &.{ .r32, .rm32 }, &.{ 0x23 }, 0, .none },
82 .{ .@"and", .rm, .r64, .rm64, .none, .none, &.{ 0x23 }, 0, .long },82 .{ .@"and", .rm, &.{ .r64, .rm64 }, &.{ 0x23 }, 0, .long },
8383
84 .{ .bsf, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0xbc }, 0, .none },84 .{ .bsf, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0xbc }, 0, .none },
85 .{ .bsf, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0xbc }, 0, .none },85 .{ .bsf, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0xbc }, 0, .none },
86 .{ .bsf, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0xbc }, 0, .long },86 .{ .bsf, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0xbc }, 0, .long },
8787
88 .{ .bsr, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0xbd }, 0, .none },88 .{ .bsr, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0xbd }, 0, .none },
89 .{ .bsr, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0xbd }, 0, .none },89 .{ .bsr, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0xbd }, 0, .none },
90 .{ .bsr, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0xbd }, 0, .long },90 .{ .bsr, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0xbd }, 0, .long },
9191
92 .{ .bswap, .o, .r32, .none, .none, .none, &.{ 0x0f, 0xc8 }, 0, .none },92 .{ .bswap, .o, &.{ .r32 }, &.{ 0x0f, 0xc8 }, 0, .none },
93 .{ .bswap, .o, .r64, .none, .none, .none, &.{ 0x0f, 0xc8 }, 0, .long },93 .{ .bswap, .o, &.{ .r64 }, &.{ 0x0f, 0xc8 }, 0, .long },
9494
95 .{ .bt, .mr, .rm16, .r16, .none, .none, &.{ 0x0f, 0xa3 }, 0, .none },95 .{ .bt, .mr, &.{ .rm16, .r16 }, &.{ 0x0f, 0xa3 }, 0, .none },
96 .{ .bt, .mr, .rm32, .r32, .none, .none, &.{ 0x0f, 0xa3 }, 0, .none },96 .{ .bt, .mr, &.{ .rm32, .r32 }, &.{ 0x0f, 0xa3 }, 0, .none },
97 .{ .bt, .mr, .rm64, .r64, .none, .none, &.{ 0x0f, 0xa3 }, 0, .long },97 .{ .bt, .mr, &.{ .rm64, .r64 }, &.{ 0x0f, 0xa3 }, 0, .long },
98 .{ .bt, .mi, .rm16, .imm8, .none, .none, &.{ 0x0f, 0xba }, 4, .none },98 .{ .bt, .mi, &.{ .rm16, .imm8 }, &.{ 0x0f, 0xba }, 4, .none },
99 .{ .bt, .mi, .rm32, .imm8, .none, .none, &.{ 0x0f, 0xba }, 4, .none },99 .{ .bt, .mi, &.{ .rm32, .imm8 }, &.{ 0x0f, 0xba }, 4, .none },
100 .{ .bt, .mi, .rm64, .imm8, .none, .none, &.{ 0x0f, 0xba }, 4, .long },100 .{ .bt, .mi, &.{ .rm64, .imm8 }, &.{ 0x0f, 0xba }, 4, .long },
101101
102 .{ .btc, .mr, .rm16, .r16, .none, .none, &.{ 0x0f, 0xbb }, 0, .none },102 .{ .btc, .mr, &.{ .rm16, .r16 }, &.{ 0x0f, 0xbb }, 0, .none },
103 .{ .btc, .mr, .rm32, .r32, .none, .none, &.{ 0x0f, 0xbb }, 0, .none },103 .{ .btc, .mr, &.{ .rm32, .r32 }, &.{ 0x0f, 0xbb }, 0, .none },
104 .{ .btc, .mr, .rm64, .r64, .none, .none, &.{ 0x0f, 0xbb }, 0, .long },104 .{ .btc, .mr, &.{ .rm64, .r64 }, &.{ 0x0f, 0xbb }, 0, .long },
105 .{ .btc, .mi, .rm16, .imm8, .none, .none, &.{ 0x0f, 0xba }, 7, .none },105 .{ .btc, .mi, &.{ .rm16, .imm8 }, &.{ 0x0f, 0xba }, 7, .none },
106 .{ .btc, .mi, .rm32, .imm8, .none, .none, &.{ 0x0f, 0xba }, 7, .none },106 .{ .btc, .mi, &.{ .rm32, .imm8 }, &.{ 0x0f, 0xba }, 7, .none },
107 .{ .btc, .mi, .rm64, .imm8, .none, .none, &.{ 0x0f, 0xba }, 7, .long },107 .{ .btc, .mi, &.{ .rm64, .imm8 }, &.{ 0x0f, 0xba }, 7, .long },
108108
109 .{ .btr, .mr, .rm16, .r16, .none, .none, &.{ 0x0f, 0xb3 }, 0, .none },109 .{ .btr, .mr, &.{ .rm16, .r16 }, &.{ 0x0f, 0xb3 }, 0, .none },
110 .{ .btr, .mr, .rm32, .r32, .none, .none, &.{ 0x0f, 0xb3 }, 0, .none },110 .{ .btr, .mr, &.{ .rm32, .r32 }, &.{ 0x0f, 0xb3 }, 0, .none },
111 .{ .btr, .mr, .rm64, .r64, .none, .none, &.{ 0x0f, 0xb3 }, 0, .long },111 .{ .btr, .mr, &.{ .rm64, .r64 }, &.{ 0x0f, 0xb3 }, 0, .long },
112 .{ .btr, .mi, .rm16, .imm8, .none, .none, &.{ 0x0f, 0xba }, 6, .none },112 .{ .btr, .mi, &.{ .rm16, .imm8 }, &.{ 0x0f, 0xba }, 6, .none },
113 .{ .btr, .mi, .rm32, .imm8, .none, .none, &.{ 0x0f, 0xba }, 6, .none },113 .{ .btr, .mi, &.{ .rm32, .imm8 }, &.{ 0x0f, 0xba }, 6, .none },
114 .{ .btr, .mi, .rm64, .imm8, .none, .none, &.{ 0x0f, 0xba }, 6, .long },114 .{ .btr, .mi, &.{ .rm64, .imm8 }, &.{ 0x0f, 0xba }, 6, .long },
115115
116 .{ .bts, .mr, .rm16, .r16, .none, .none, &.{ 0x0f, 0xab }, 0, .none },116 .{ .bts, .mr, &.{ .rm16, .r16 }, &.{ 0x0f, 0xab }, 0, .none },
117 .{ .bts, .mr, .rm32, .r32, .none, .none, &.{ 0x0f, 0xab }, 0, .none },117 .{ .bts, .mr, &.{ .rm32, .r32 }, &.{ 0x0f, 0xab }, 0, .none },
118 .{ .bts, .mr, .rm64, .r64, .none, .none, &.{ 0x0f, 0xab }, 0, .long },118 .{ .bts, .mr, &.{ .rm64, .r64 }, &.{ 0x0f, 0xab }, 0, .long },
119 .{ .bts, .mi, .rm16, .imm8, .none, .none, &.{ 0x0f, 0xba }, 5, .none },119 .{ .bts, .mi, &.{ .rm16, .imm8 }, &.{ 0x0f, 0xba }, 5, .none },
120 .{ .bts, .mi, .rm32, .imm8, .none, .none, &.{ 0x0f, 0xba }, 5, .none },120 .{ .bts, .mi, &.{ .rm32, .imm8 }, &.{ 0x0f, 0xba }, 5, .none },
121 .{ .bts, .mi, .rm64, .imm8, .none, .none, &.{ 0x0f, 0xba }, 5, .long },121 .{ .bts, .mi, &.{ .rm64, .imm8 }, &.{ 0x0f, 0xba }, 5, .long },
122122
123 // This is M encoding according to Intel, but D makes more sense here.123 // This is M encoding according to Intel, but D makes more sense here.
124 .{ .call, .d, .rel32, .none, .none, .none, &.{ 0xe8 }, 0, .none },124 .{ .call, .d, &.{ .rel32 }, &.{ 0xe8 }, 0, .none },
125 .{ .call, .m, .rm64, .none, .none, .none, &.{ 0xff }, 2, .none },125 .{ .call, .m, &.{ .rm64 }, &.{ 0xff }, 2, .none },
126126
127 .{ .cbw, .np, .o16, .none, .none, .none, &.{ 0x98 }, 0, .none },127 .{ .cbw, .np, &.{ .o16 }, &.{ 0x98 }, 0, .none },
128 .{ .cwde, .np, .o32, .none, .none, .none, &.{ 0x98 }, 0, .none },128 .{ .cwde, .np, &.{ .o32 }, &.{ 0x98 }, 0, .none },
129 .{ .cdqe, .np, .o64, .none, .none, .none, &.{ 0x98 }, 0, .long },129 .{ .cdqe, .np, &.{ .o64 }, &.{ 0x98 }, 0, .long },
130130
131 .{ .cwd, .np, .o16, .none, .none, .none, &.{ 0x99 }, 0, .none },131 .{ .cwd, .np, &.{ .o16 }, &.{ 0x99 }, 0, .none },
132 .{ .cdq, .np, .o32, .none, .none, .none, &.{ 0x99 }, 0, .none },132 .{ .cdq, .np, &.{ .o32 }, &.{ 0x99 }, 0, .none },
133 .{ .cqo, .np, .o64, .none, .none, .none, &.{ 0x99 }, 0, .long },133 .{ .cqo, .np, &.{ .o64 }, &.{ 0x99 }, 0, .long },
134134
135 .{ .cmova, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x47 }, 0, .none },135 .{ .cmova, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x47 }, 0, .none },
136 .{ .cmova, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x47 }, 0, .none },136 .{ .cmova, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x47 }, 0, .none },
137 .{ .cmova, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x47 }, 0, .long },137 .{ .cmova, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x47 }, 0, .long },
138 .{ .cmovae, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x43 }, 0, .none },138 .{ .cmovae, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x43 }, 0, .none },
139 .{ .cmovae, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x43 }, 0, .none },139 .{ .cmovae, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x43 }, 0, .none },
140 .{ .cmovae, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x43 }, 0, .long },140 .{ .cmovae, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x43 }, 0, .long },
141 .{ .cmovb, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x42 }, 0, .none },141 .{ .cmovb, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x42 }, 0, .none },
142 .{ .cmovb, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x42 }, 0, .none },142 .{ .cmovb, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x42 }, 0, .none },
143 .{ .cmovb, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x42 }, 0, .long },143 .{ .cmovb, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x42 }, 0, .long },
144 .{ .cmovbe, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x46 }, 0, .none },144 .{ .cmovbe, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x46 }, 0, .none },
145 .{ .cmovbe, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x46 }, 0, .none },145 .{ .cmovbe, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x46 }, 0, .none },
146 .{ .cmovbe, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x46 }, 0, .long },146 .{ .cmovbe, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x46 }, 0, .long },
147 .{ .cmovc, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x42 }, 0, .none },147 .{ .cmovc, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x42 }, 0, .none },
148 .{ .cmovc, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x42 }, 0, .none },148 .{ .cmovc, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x42 }, 0, .none },
149 .{ .cmovc, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x42 }, 0, .long },149 .{ .cmovc, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x42 }, 0, .long },
150 .{ .cmove, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x44 }, 0, .none },150 .{ .cmove, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x44 }, 0, .none },
151 .{ .cmove, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x44 }, 0, .none },151 .{ .cmove, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x44 }, 0, .none },
152 .{ .cmove, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x44 }, 0, .long },152 .{ .cmove, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x44 }, 0, .long },
153 .{ .cmovg, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x4f }, 0, .none },153 .{ .cmovg, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x4f }, 0, .none },
154 .{ .cmovg, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x4f }, 0, .none },154 .{ .cmovg, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x4f }, 0, .none },
155 .{ .cmovg, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x4f }, 0, .long },155 .{ .cmovg, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x4f }, 0, .long },
156 .{ .cmovge, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x4d }, 0, .none },156 .{ .cmovge, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x4d }, 0, .none },
157 .{ .cmovge, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x4d }, 0, .none },157 .{ .cmovge, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x4d }, 0, .none },
158 .{ .cmovge, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x4d }, 0, .long },158 .{ .cmovge, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x4d }, 0, .long },
159 .{ .cmovl, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x4c }, 0, .none },159 .{ .cmovl, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x4c }, 0, .none },
160 .{ .cmovl, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x4c }, 0, .none },160 .{ .cmovl, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x4c }, 0, .none },
161 .{ .cmovl, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x4c }, 0, .long },161 .{ .cmovl, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x4c }, 0, .long },
162 .{ .cmovle, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x4e }, 0, .none },162 .{ .cmovle, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x4e }, 0, .none },
163 .{ .cmovle, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x4e }, 0, .none },163 .{ .cmovle, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x4e }, 0, .none },
164 .{ .cmovle, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x4e }, 0, .long },164 .{ .cmovle, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x4e }, 0, .long },
165 .{ .cmovna, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x46 }, 0, .none },165 .{ .cmovna, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x46 }, 0, .none },
166 .{ .cmovna, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x46 }, 0, .none },166 .{ .cmovna, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x46 }, 0, .none },
167 .{ .cmovna, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x46 }, 0, .long },167 .{ .cmovna, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x46 }, 0, .long },
168 .{ .cmovnae, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x42 }, 0, .none },168 .{ .cmovnae, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x42 }, 0, .none },
169 .{ .cmovnae, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x42 }, 0, .none },169 .{ .cmovnae, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x42 }, 0, .none },
170 .{ .cmovnae, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x42 }, 0, .long },170 .{ .cmovnae, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x42 }, 0, .long },
171 .{ .cmovnb, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x43 }, 0, .none },171 .{ .cmovnb, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x43 }, 0, .none },
172 .{ .cmovnb, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x43 }, 0, .none },172 .{ .cmovnb, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x43 }, 0, .none },
173 .{ .cmovnb, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x43 }, 0, .long },173 .{ .cmovnb, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x43 }, 0, .long },
174 .{ .cmovnbe, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x47 }, 0, .none },174 .{ .cmovnbe, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x47 }, 0, .none },
175 .{ .cmovnbe, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x47 }, 0, .none },175 .{ .cmovnbe, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x47 }, 0, .none },
176 .{ .cmovnbe, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x47 }, 0, .long },176 .{ .cmovnbe, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x47 }, 0, .long },
177 .{ .cmovnc, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x43 }, 0, .none },177 .{ .cmovnc, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x43 }, 0, .none },
178 .{ .cmovnc, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x43 }, 0, .none },178 .{ .cmovnc, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x43 }, 0, .none },
179 .{ .cmovnc, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x43 }, 0, .long },179 .{ .cmovnc, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x43 }, 0, .long },
180 .{ .cmovne, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x45 }, 0, .none },180 .{ .cmovne, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x45 }, 0, .none },
181 .{ .cmovne, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x45 }, 0, .none },181 .{ .cmovne, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x45 }, 0, .none },
182 .{ .cmovne, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x45 }, 0, .long },182 .{ .cmovne, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x45 }, 0, .long },
183 .{ .cmovng, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x4e }, 0, .none },183 .{ .cmovng, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x4e }, 0, .none },
184 .{ .cmovng, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x4e }, 0, .none },184 .{ .cmovng, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x4e }, 0, .none },
185 .{ .cmovng, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x4e }, 0, .long },185 .{ .cmovng, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x4e }, 0, .long },
186 .{ .cmovnge, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x4c }, 0, .none },186 .{ .cmovnge, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x4c }, 0, .none },
187 .{ .cmovnge, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x4c }, 0, .none },187 .{ .cmovnge, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x4c }, 0, .none },
188 .{ .cmovnge, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x4c }, 0, .long },188 .{ .cmovnge, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x4c }, 0, .long },
189 .{ .cmovnl, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x4d }, 0, .none },189 .{ .cmovnl, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x4d }, 0, .none },
190 .{ .cmovnl, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x4d }, 0, .none },190 .{ .cmovnl, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x4d }, 0, .none },
191 .{ .cmovnl, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x4d }, 0, .long },191 .{ .cmovnl, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x4d }, 0, .long },
192 .{ .cmovnle, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x4f }, 0, .none },192 .{ .cmovnle, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x4f }, 0, .none },
193 .{ .cmovnle, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x4f }, 0, .none },193 .{ .cmovnle, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x4f }, 0, .none },
194 .{ .cmovnle, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x4f }, 0, .long },194 .{ .cmovnle, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x4f }, 0, .long },
195 .{ .cmovno, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x41 }, 0, .none },195 .{ .cmovno, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x41 }, 0, .none },
196 .{ .cmovno, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x41 }, 0, .none },196 .{ .cmovno, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x41 }, 0, .none },
197 .{ .cmovno, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x41 }, 0, .long },197 .{ .cmovno, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x41 }, 0, .long },
198 .{ .cmovnp, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x4b }, 0, .none },198 .{ .cmovnp, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x4b }, 0, .none },
199 .{ .cmovnp, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x4b }, 0, .none },199 .{ .cmovnp, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x4b }, 0, .none },
200 .{ .cmovnp, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x4b }, 0, .long },200 .{ .cmovnp, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x4b }, 0, .long },
201 .{ .cmovns, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x49 }, 0, .none },201 .{ .cmovns, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x49 }, 0, .none },
202 .{ .cmovns, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x49 }, 0, .none },202 .{ .cmovns, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x49 }, 0, .none },
203 .{ .cmovns, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x49 }, 0, .long },203 .{ .cmovns, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x49 }, 0, .long },
204 .{ .cmovnz, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x45 }, 0, .none },204 .{ .cmovnz, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x45 }, 0, .none },
205 .{ .cmovnz, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x45 }, 0, .none },205 .{ .cmovnz, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x45 }, 0, .none },
206 .{ .cmovnz, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x45 }, 0, .long },206 .{ .cmovnz, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x45 }, 0, .long },
207 .{ .cmovo, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x40 }, 0, .none },207 .{ .cmovo, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x40 }, 0, .none },
208 .{ .cmovo, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x40 }, 0, .none },208 .{ .cmovo, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x40 }, 0, .none },
209 .{ .cmovo, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x40 }, 0, .long },209 .{ .cmovo, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x40 }, 0, .long },
210 .{ .cmovp, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x4a }, 0, .none },210 .{ .cmovp, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x4a }, 0, .none },
211 .{ .cmovp, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x4a }, 0, .none },211 .{ .cmovp, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x4a }, 0, .none },
212 .{ .cmovp, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x4a }, 0, .long },212 .{ .cmovp, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x4a }, 0, .long },
213 .{ .cmovpe, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x4a }, 0, .none },213 .{ .cmovpe, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x4a }, 0, .none },
214 .{ .cmovpe, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x4a }, 0, .none },214 .{ .cmovpe, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x4a }, 0, .none },
215 .{ .cmovpe, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x4a }, 0, .long },215 .{ .cmovpe, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x4a }, 0, .long },
216 .{ .cmovpo, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x4b }, 0, .none },216 .{ .cmovpo, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x4b }, 0, .none },
217 .{ .cmovpo, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x4b }, 0, .none },217 .{ .cmovpo, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x4b }, 0, .none },
218 .{ .cmovpo, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x4b }, 0, .long },218 .{ .cmovpo, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x4b }, 0, .long },
219 .{ .cmovs, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x48 }, 0, .none },219 .{ .cmovs, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x48 }, 0, .none },
220 .{ .cmovs, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x48 }, 0, .none },220 .{ .cmovs, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x48 }, 0, .none },
221 .{ .cmovs, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x48 }, 0, .long },221 .{ .cmovs, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x48 }, 0, .long },
222 .{ .cmovz, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0x44 }, 0, .none },222 .{ .cmovz, .rm, &.{ .r16, .rm16 }, &.{ 0x0f, 0x44 }, 0, .none },
223 .{ .cmovz, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0x44 }, 0, .none },223 .{ .cmovz, .rm, &.{ .r32, .rm32 }, &.{ 0x0f, 0x44 }, 0, .none },
224 .{ .cmovz, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0x44 }, 0, .long },224 .{ .cmovz, .rm, &.{ .r64, .rm64 }, &.{ 0x0f, 0x44 }, 0, .long },
225225
226 .{ .cmp, .zi, .al, .imm8, .none, .none, &.{ 0x3c }, 0, .none },226 .{ .cmp, .zi, &.{ .al, .imm8 }, &.{ 0x3c }, 0, .none },
227 .{ .cmp, .zi, .ax, .imm16, .none, .none, &.{ 0x3d }, 0, .none },227 .{ .cmp, .zi, &.{ .ax, .imm16 }, &.{ 0x3d }, 0, .none },
228 .{ .cmp, .zi, .eax, .imm32, .none, .none, &.{ 0x3d }, 0, .none },228 .{ .cmp, .zi, &.{ .eax, .imm32 }, &.{ 0x3d }, 0, .none },
229 .{ .cmp, .zi, .rax, .imm32s, .none, .none, &.{ 0x3d }, 0, .long },229 .{ .cmp, .zi, &.{ .rax, .imm32s }, &.{ 0x3d }, 0, .long },
230 .{ .cmp, .mi, .rm8, .imm8, .none, .none, &.{ 0x80 }, 7, .none },230 .{ .cmp, .mi, &.{ .rm8, .imm8 }, &.{ 0x80 }, 7, .none },
231 .{ .cmp, .mi, .rm8, .imm8, .none, .none, &.{ 0x80 }, 7, .rex },231 .{ .cmp, .mi, &.{ .rm8, .imm8 }, &.{ 0x80 }, 7, .rex },
232 .{ .cmp, .mi, .rm16, .imm16, .none, .none, &.{ 0x81 }, 7, .none },232 .{ .cmp, .mi, &.{ .rm16, .imm16 }, &.{ 0x81 }, 7, .none },
233 .{ .cmp, .mi, .rm32, .imm32, .none, .none, &.{ 0x81 }, 7, .none },233 .{ .cmp, .mi, &.{ .rm32, .imm32 }, &.{ 0x81 }, 7, .none },
234 .{ .cmp, .mi, .rm64, .imm32s, .none, .none, &.{ 0x81 }, 7, .long },234 .{ .cmp, .mi, &.{ .rm64, .imm32s }, &.{ 0x81 }, 7, .long },
235 .{ .cmp, .mi, .rm16, .imm8s, .none, .none, &.{ 0x83 }, 7, .none },235 .{ .cmp, .mi, &.{ .rm16, .imm8s }, &.{ 0x83 }, 7, .none },
236 .{ .cmp, .mi, .rm32, .imm8s, .none, .none, &.{ 0x83 }, 7, .none },236 .{ .cmp, .mi, &.{ .rm32, .imm8s }, &.{ 0x83 }, 7, .none },
237 .{ .cmp, .mi, .rm64, .imm8s, .none, .none, &.{ 0x83 }, 7, .long },237 .{ .cmp, .mi, &.{ .rm64, .imm8s }, &.{ 0x83 }, 7, .long },
238 .{ .cmp, .mr, .rm8, .r8, .none, .none, &.{ 0x38 }, 0, .none },238 .{ .cmp, .mr, &.{ .rm8, .r8 }, &.{ 0x38 }, 0, .none },
239 .{ .cmp, .mr, .rm8, .r8, .none, .none, &.{ 0x38 }, 0, .rex },239 .{ .cmp, .mr, &.{ .rm8, .r8 }, &.{ 0x38 }, 0, .rex },
240 .{ .cmp, .mr, .rm16, .r16, .none, .none, &.{ 0x39 }, 0, .none },240 .{ .cmp, .mr, &.{ .rm16, .r16 }, &.{ 0x39 }, 0, .none },
241 .{ .cmp, .mr, .rm32, .r32, .none, .none, &.{ 0x39 }, 0, .none },241 .{ .cmp, .mr, &.{ .rm32, .r32 }, &.{ 0x39 }, 0, .none },
242 .{ .cmp, .mr, .rm64, .r64, .none, .none, &.{ 0x39 }, 0, .long },242 .{ .cmp, .mr, &.{ .rm64, .r64 }, &.{ 0x39 }, 0, .long },
243 .{ .cmp, .rm, .r8, .rm8, .none, .none, &.{ 0x3a }, 0, .none },243 .{ .cmp, .rm, &.{ .r8, .rm8 }, &.{ 0x3a }, 0, .none },
244 .{ .cmp, .rm, .r8, .rm8, .none, .none, &.{ 0x3a }, 0, .rex },244 .{ .cmp, .rm, &.{ .r8, .rm8 }, &.{ 0x3a }, 0, .rex },
245 .{ .cmp, .rm, .r16, .rm16, .none, .none, &.{ 0x3b }, 0, .none },245 .{ .cmp, .rm, &.{ .r16, .rm16 }, &.{ 0x3b }, 0, .none },
246 .{ .cmp, .rm, .r32, .rm32, .none, .none, &.{ 0x3b }, 0, .none },246 .{ .cmp, .rm, &.{ .r32, .rm32 }, &.{ 0x3b }, 0, .none },
247 .{ .cmp, .rm, .r64, .rm64, .none, .none, &.{ 0x3b }, 0, .long },247 .{ .cmp, .rm, &.{ .r64, .rm64 }, &.{ 0x3b }, 0, .long },
248248
249 .{ .cmps, .np, .m8, .m8, .none, .none, &.{ 0xa6 }, 0, .none },249 .{ .cmps, .np, &.{ .m8, .m8 }, &.{ 0xa6 }, 0, .none },
250 .{ .cmps, .np, .m16, .m16, .none, .none, &.{ 0xa7 }, 0, .none },250 .{ .cmps, .np, &.{ .m16, .m16 }, &.{ 0xa7 }, 0, .none },
251 .{ .cmps, .np, .m32, .m32, .none, .none, &.{ 0xa7 }, 0, .none },251 .{ .cmps, .np, &.{ .m32, .m32 }, &.{ 0xa7 }, 0, .none },
252 .{ .cmps, .np, .m64, .m64, .none, .none, &.{ 0xa7 }, 0, .long },252 .{ .cmps, .np, &.{ .m64, .m64 }, &.{ 0xa7 }, 0, .long },
253 .{ .cmpsb, .np, .none, .none, .none, .none, &.{ 0xa6 }, 0, .none },253
254 .{ .cmpsw, .np, .none, .none, .none, .none, &.{ 0xa7 }, 0, .short },254 .{ .cmpsb, .np, &.{}, &.{ 0xa6 }, 0, .none },
255 .{ .cmpsd, .np, .none, .none, .none, .none, &.{ 0xa7 }, 0, .none },255 .{ .cmpsw, .np, &.{}, &.{ 0xa7 }, 0, .short },
256 .{ .cmpsq, .np, .none, .none, .none, .none, &.{ 0xa7 }, 0, .long },256 .{ .cmpsd, .np, &.{}, &.{ 0xa7 }, 0, .none },
257257 .{ .cmpsq, .np, &.{}, &.{ 0xa7 }, 0, .long },
258 .{ .cmpxchg, .mr, .rm8, .r8, .none, .none, &.{ 0x0f, 0xb0 }, 0, .none },258
259 .{ .cmpxchg, .mr, .rm8, .r8, .none, .none, &.{ 0x0f, 0xb0 }, 0, .rex },259 .{ .cmpxchg, .mr, &.{ .rm8, .r8 }, &.{ 0x0f, 0xb0 }, 0, .none },
260 .{ .cmpxchg, .mr, .rm16, .r16, .none, .none, &.{ 0x0f, 0xb1 }, 0, .none },260 .{ .cmpxchg, .mr, &.{ .rm8, .r8 }, &.{ 0x0f, 0xb0 }, 0, .rex },
261 .{ .cmpxchg, .mr, .rm32, .r32, .none, .none, &.{ 0x0f, 0xb1 }, 0, .none },261 .{ .cmpxchg, .mr, &.{ .rm16, .r16 }, &.{ 0x0f, 0xb1 }, 0, .none },
262 .{ .cmpxchg, .mr, .rm64, .r64, .none, .none, &.{ 0x0f, 0xb1 }, 0, .long },262 .{ .cmpxchg, .mr, &.{ .rm32, .r32 }, &.{ 0x0f, 0xb1 }, 0, .none },
263263 .{ .cmpxchg, .mr, &.{ .rm64, .r64 }, &.{ 0x0f, 0xb1 }, 0, .long },
264 .{ .cmpxchg8b , .m, .m64, .none, .none, .none, &.{ 0x0f, 0xc7 }, 1, .none },264
265 .{ .cmpxchg16b, .m, .m128, .none, .none, .none, &.{ 0x0f, 0xc7 }, 1, .long },265 .{ .cmpxchg8b , .m, &.{ .m64 }, &.{ 0x0f, 0xc7 }, 1, .none },
266266 .{ .cmpxchg16b, .m, &.{ .m128 }, &.{ 0x0f, 0xc7 }, 1, .long },
267 .{ .div, .m, .rm8, .none, .none, .none, &.{ 0xf6 }, 6, .none },267
268 .{ .div, .m, .rm8, .none, .none, .none, &.{ 0xf6 }, 6, .rex },268 .{ .div, .m, &.{ .rm8 }, &.{ 0xf6 }, 6, .none },
269 .{ .div, .m, .rm16, .none, .none, .none, &.{ 0xf7 }, 6, .none },269 .{ .div, .m, &.{ .rm8 }, &.{ 0xf6 }, 6, .rex },
270 .{ .div, .m, .rm32, .none, .none, .none, &.{ 0xf7 }, 6, .none },270 .{ .div, .m, &.{ .rm16 }, &.{ 0xf7 }, 6, .none },
271 .{ .div, .m, .rm64, .none, .none, .none, &.{ 0xf7 }, 6, .long },271 .{ .div, .m, &.{ .rm32 }, &.{ 0xf7 }, 6, .none },
272272 .{ .div, .m, &.{ .rm64 }, &.{ 0xf7 }, 6, .long },
273 .{ .fisttp, .m, .m16, .none, .none, .none, &.{ 0xdf }, 1, .fpu },273
274 .{ .fisttp, .m, .m32, .none, .none, .none, &.{ 0xdb }, 1, .fpu },274 .{ .fisttp, .m, &.{ .m16 }, &.{ 0xdf }, 1, .fpu },
275 .{ .fisttp, .m, .m64, .none, .none, .none, &.{ 0xdd }, 1, .fpu },275 .{ .fisttp, .m, &.{ .m32 }, &.{ 0xdb }, 1, .fpu },
276276 .{ .fisttp, .m, &.{ .m64 }, &.{ 0xdd }, 1, .fpu },
277 .{ .fld, .m, .m32, .none, .none, .none, &.{ 0xd9 }, 0, .fpu },277
278 .{ .fld, .m, .m64, .none, .none, .none, &.{ 0xdd }, 0, .fpu },278 .{ .fld, .m, &.{ .m32 }, &.{ 0xd9 }, 0, .fpu },
279 .{ .fld, .m, .m80, .none, .none, .none, &.{ 0xdb }, 5, .fpu },279 .{ .fld, .m, &.{ .m64 }, &.{ 0xdd }, 0, .fpu },
280280 .{ .fld, .m, &.{ .m80 }, &.{ 0xdb }, 5, .fpu },
281 .{ .idiv, .m, .rm8, .none, .none, .none, &.{ 0xf6 }, 7, .none },281
282 .{ .idiv, .m, .rm8, .none, .none, .none, &.{ 0xf6 }, 7, .rex },282 .{ .idiv, .m, &.{ .rm8 }, &.{ 0xf6 }, 7, .none },
283 .{ .idiv, .m, .rm16, .none, .none, .none, &.{ 0xf7 }, 7, .none },283 .{ .idiv, .m, &.{ .rm8 }, &.{ 0xf6 }, 7, .rex },
284 .{ .idiv, .m, .rm32, .none, .none, .none, &.{ 0xf7 }, 7, .none },284 .{ .idiv, .m, &.{ .rm16 }, &.{ 0xf7 }, 7, .none },
285 .{ .idiv, .m, .rm64, .none, .none, .none, &.{ 0xf7 }, 7, .long },285 .{ .idiv, .m, &.{ .rm32 }, &.{ 0xf7 }, 7, .none },
286286 .{ .idiv, .m, &.{ .rm64 }, &.{ 0xf7 }, 7, .long },
287 .{ .imul, .m, .rm8, .none, .none, .none, &.{ 0xf6 }, 5, .none },287
288 .{ .imul, .m, .rm8, .none, .none, .none, &.{ 0xf6 }, 5, .rex },288 .{ .imul, .m, &.{ .rm8 }, &.{ 0xf6 }, 5, .none },
289 .{ .imul, .m, .rm16, .none, .none, .none, &.{ 0xf7 }, 5, .none },289 .{ .imul, .m, &.{ .rm8 }, &.{ 0xf6 }, 5, .rex },
290 .{ .imul, .m, .rm32, .none, .none, .none, &.{ 0xf7 }, 5, .none },290 .{ .imul, .m, &.{ .rm16, }, &.{ 0xf7 }, 5, .none },
291 .{ .imul, .m, .rm64, .none, .none, .none, &.{ 0xf7 }, 5, .long },291 .{ .imul, .m, &.{ .rm32, }, &.{ 0xf7 }, 5, .none },
292 .{ .imul, .rm, .r16, .rm16, .none, .none, &.{ 0x0f, 0xaf }, 0, .none },292 .{ .imul, .m, &.{ .rm64, }, &.{ 0xf7 }, 5, .long },
293 .{ .imul, .rm, .r32, .rm32, .none, .none, &.{ 0x0f, 0xaf }, 0, .none },293 .{ .imul, .rm, &.{ .r16, .rm16, }, &.{ 0x0f, 0xaf }, 0, .none },
294 .{ .imul, .rm, .r64, .rm64, .none, .none, &.{ 0x0f, 0xaf }, 0, .long },294 .{ .imul, .rm, &.{ .r32, .rm32, }, &.{ 0x0f, 0xaf }, 0, .none },
295 .{ .imul, .rmi, .r16, .rm16, .imm8s, .none, &.{ 0x6b }, 0, .none },295 .{ .imul, .rm, &.{ .r64, .rm64, }, &.{ 0x0f, 0xaf }, 0, .long },
296 .{ .imul, .rmi, .r32, .rm32, .imm8s, .none, &.{ 0x6b }, 0, .none },296 .{ .imul, .rmi, &.{ .r16, .rm16, .imm8s }, &.{ 0x6b }, 0, .none },
297 .{ .imul, .rmi, .r64, .rm64, .imm8s, .none, &.{ 0x6b }, 0, .long },297 .{ .imul, .rmi, &.{ .r32, .rm32, .imm8s }, &.{ 0x6b }, 0, .none },
298 .{ .imul, .rmi, .r16, .rm16, .imm16, .none, &.{ 0x69 }, 0, .none },298 .{ .imul, .rmi, &.{ .r64, .rm64, .imm8s }, &.{ 0x6b }, 0, .long },
299 .{ .imul, .rmi, .r32, .rm32, .imm32, .none, &.{ 0x69 }, 0, .none },299 .{ .imul, .rmi, &.{ .r16, .rm16, .imm16 }, &.{ 0x69 }, 0, .none },
300 .{ .imul, .rmi, .r64, .rm64, .imm32, .none, &.{ 0x69 }, 0, .long },300 .{ .imul, .rmi, &.{ .r32, .rm32, .imm32 }, &.{ 0x69 }, 0, .none },
301301 .{ .imul, .rmi, &.{ .r64, .rm64, .imm32 }, &.{ 0x69 }, 0, .long },
302 .{ .int3, .np, .none, .none, .none, .none, &.{ 0xcc }, 0, .none },302
303303 .{ .int3, .np, &.{}, &.{ 0xcc }, 0, .none },
304 .{ .ja, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x87 }, 0, .none },304
305 .{ .jae, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x83 }, 0, .none },305 .{ .ja, .d, &.{ .rel32 }, &.{ 0x0f, 0x87 }, 0, .none },
306 .{ .jb, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x82 }, 0, .none },306 .{ .jae, .d, &.{ .rel32 }, &.{ 0x0f, 0x83 }, 0, .none },
307 .{ .jbe, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x86 }, 0, .none },307 .{ .jb, .d, &.{ .rel32 }, &.{ 0x0f, 0x82 }, 0, .none },
308 .{ .jc, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x82 }, 0, .none },308 .{ .jbe, .d, &.{ .rel32 }, &.{ 0x0f, 0x86 }, 0, .none },
309 .{ .jrcxz, .d, .rel32, .none, .none, .none, &.{ 0xe3 }, 0, .none },309 .{ .jc, .d, &.{ .rel32 }, &.{ 0x0f, 0x82 }, 0, .none },
310 .{ .je, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x84 }, 0, .none },310 .{ .jrcxz, .d, &.{ .rel32 }, &.{ 0xe3 }, 0, .none },
311 .{ .jg, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x8f }, 0, .none },311 .{ .je, .d, &.{ .rel32 }, &.{ 0x0f, 0x84 }, 0, .none },
312 .{ .jge, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x8d }, 0, .none },312 .{ .jg, .d, &.{ .rel32 }, &.{ 0x0f, 0x8f }, 0, .none },
313 .{ .jl, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x8c }, 0, .none },313 .{ .jge, .d, &.{ .rel32 }, &.{ 0x0f, 0x8d }, 0, .none },
314 .{ .jle, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x8e }, 0, .none },314 .{ .jl, .d, &.{ .rel32 }, &.{ 0x0f, 0x8c }, 0, .none },
315 .{ .jna, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x86 }, 0, .none },315 .{ .jle, .d, &.{ .rel32 }, &.{ 0x0f, 0x8e }, 0, .none },
316 .{ .jnae, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x82 }, 0, .none },316 .{ .jna, .d, &.{ .rel32 }, &.{ 0x0f, 0x86 }, 0, .none },
317 .{ .jnb, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x83 }, 0, .none },317 .{ .jnae, .d, &.{ .rel32 }, &.{ 0x0f, 0x82 }, 0, .none },
318 .{ .jnbe, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x87 }, 0, .none },318 .{ .jnb, .d, &.{ .rel32 }, &.{ 0x0f, 0x83 }, 0, .none },
319 .{ .jnc, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x83 }, 0, .none },319 .{ .jnbe, .d, &.{ .rel32 }, &.{ 0x0f, 0x87 }, 0, .none },
320 .{ .jne, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x85 }, 0, .none },320 .{ .jnc, .d, &.{ .rel32 }, &.{ 0x0f, 0x83 }, 0, .none },
321 .{ .jng, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x8e }, 0, .none },321 .{ .jne, .d, &.{ .rel32 }, &.{ 0x0f, 0x85 }, 0, .none },
322 .{ .jnge, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x8c }, 0, .none },322 .{ .jng, .d, &.{ .rel32 }, &.{ 0x0f, 0x8e }, 0, .none },
323 .{ .jnl, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x8d }, 0, .none },323 .{ .jnge, .d, &.{ .rel32 }, &.{ 0x0f, 0x8c }, 0, .none },
324 .{ .jnle, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x8f }, 0, .none },324 .{ .jnl, .d, &.{ .rel32 }, &.{ 0x0f, 0x8d }, 0, .none },
325 .{ .jno, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x81 }, 0, .none },325 .{ .jnle, .d, &.{ .rel32 }, &.{ 0x0f, 0x8f }, 0, .none },
326 .{ .jnp, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x8b }, 0, .none },326 .{ .jno, .d, &.{ .rel32 }, &.{ 0x0f, 0x81 }, 0, .none },
327 .{ .jns, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x89 }, 0, .none },327 .{ .jnp, .d, &.{ .rel32 }, &.{ 0x0f, 0x8b }, 0, .none },
328 .{ .jnz, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x85 }, 0, .none },328 .{ .jns, .d, &.{ .rel32 }, &.{ 0x0f, 0x89 }, 0, .none },
329 .{ .jo, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x80 }, 0, .none },329 .{ .jnz, .d, &.{ .rel32 }, &.{ 0x0f, 0x85 }, 0, .none },
330 .{ .jp, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x8a }, 0, .none },330 .{ .jo, .d, &.{ .rel32 }, &.{ 0x0f, 0x80 }, 0, .none },
331 .{ .jpe, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x8a }, 0, .none },331 .{ .jp, .d, &.{ .rel32 }, &.{ 0x0f, 0x8a }, 0, .none },
332 .{ .jpo, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x8b }, 0, .none },332 .{ .jpe, .d, &.{ .rel32 }, &.{ 0x0f, 0x8a }, 0, .none },
333 .{ .js, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x88 }, 0, .none },333 .{ .jpo, .d, &.{ .rel32 }, &.{ 0x0f, 0x8b }, 0, .none },
334 .{ .jz, .d, .rel32, .none, .none, .none, &.{ 0x0f, 0x84 }, 0, .none },334 .{ .js, .d, &.{ .rel32 }, &.{ 0x0f, 0x88 }, 0, .none },
335335 .{ .jz, .d, &.{ .rel32 }, &.{ 0x0f, 0x84 }, 0, .none },
336 .{ .jmp, .d, .rel32, .none, .none, .none, &.{ 0xe9 }, 0, .none },336
337 .{ .jmp, .m, .rm64, .none, .none, .none, &.{ 0xff }, 4, .none },337 .{ .jmp, .d, &.{ .rel32 }, &.{ 0xe9 }, 0, .none },
338338 .{ .jmp, .m, &.{ .rm64 }, &.{ 0xff }, 4, .none },
339 .{ .lea, .rm, .r16, .m, .none, .none, &.{ 0x8d }, 0, .none },339
340 .{ .lea, .rm, .r32, .m, .none, .none, &.{ 0x8d }, 0, .none },340 .{ .lea, .rm, &.{ .r16, .m }, &.{ 0x8d }, 0, .none },
341 .{ .lea, .rm, .r64, .m, .none, .none, &.{ 0x8d }, 0, .long },341 .{ .lea, .rm, &.{ .r32, .m }, &.{ 0x8d }, 0, .none },
342342 .{ .lea, .rm, &.{ .r64, .m }, &.{ 0x8d }, 0, .long },
343 .{ .lfence, .np, .none, .none, .none, .none, &.{ 0x0f, 0xae, 0xe8 }, 0, .none },343
344344 .{ .lfence, .np, &.{}, &.{ 0x0f, 0xae, 0xe8 }, 0, .none },
345 .{ .lods, .np, .m8, .none, .none, .none, &.{ 0xac }, 0, .none },345
346 .{ .lods, .np, .m16, .none, .none, .none, &.{ 0xad }, 0, .none },346 .{ .lods, .np, &.{ .m8 }, &.{ 0xac }, 0, .none },
347 .{ .lods, .np, .m32, .none, .none, .none, &.{ 0xad }, 0, .none },347 .{ .lods, .np, &.{ .m16 }, &.{ 0xad }, 0, .none },
348 .{ .lods, .np, .m64, .none, .none, .none, &.{ 0xad }, 0, .long },348 .{ .lods, .np, &.{ .m32 }, &.{ 0xad }, 0, .none },
349 .{ .lodsb, .np, .none, .none, .none, .none, &.{ 0xac }, 0, .none },349 .{ .lods, .np, &.{ .m64 }, &.{ 0xad }, 0, .long },
350 .{ .lodsw, .np, .none, .none, .none, .none, &.{ 0xad }, 0, .short },350
351 .{ .lodsd, .np, .none, .none, .none, .none, &.{ 0xad }, 0, .none },351 .{ .lodsb, .np, &.{}, &.{ 0xac }, 0, .none },
352 .{ .lodsq, .np, .none, .none, .none, .none, &.{ 0xad }, 0, .long },352 .{ .lodsw, .np, &.{}, &.{ 0xad }, 0, .short },
353353 .{ .lodsd, .np, &.{}, &.{ 0xad }, 0, .none },
354 .{ .lzcnt, .rm, .r16, .rm16, .none, .none, &.{ 0xf3, 0x0f, 0xbd }, 0, .none },354 .{ .lodsq, .np, &.{}, &.{ 0xad }, 0, .long },
355 .{ .lzcnt, .rm, .r32, .rm32, .none, .none, &.{ 0xf3, 0x0f, 0xbd }, 0, .none },355
356 .{ .lzcnt, .rm, .r64, .rm64, .none, .none, &.{ 0xf3, 0x0f, 0xbd }, 0, .long },356 .{ .lzcnt, .rm, &.{ .r16, .rm16 }, &.{ 0xf3, 0x0f, 0xbd }, 0, .none },
357357 .{ .lzcnt, .rm, &.{ .r32, .rm32 }, &.{ 0xf3, 0x0f, 0xbd }, 0, .none },
358 .{ .mfence, .np, .none, .none, .none, .none, &.{ 0x0f, 0xae, 0xf0 }, 0, .none },358 .{ .lzcnt, .rm, &.{ .r64, .rm64 }, &.{ 0xf3, 0x0f, 0xbd }, 0, .long },
359359
360 .{ .mov, .mr, .rm8, .r8, .none, .none, &.{ 0x88 }, 0, .none },360 .{ .mfence, .np, &.{}, &.{ 0x0f, 0xae, 0xf0 }, 0, .none },
361 .{ .mov, .mr, .rm8, .r8, .none, .none, &.{ 0x88 }, 0, .rex },361
362 .{ .mov, .mr, .rm16, .r16, .none, .none, &.{ 0x89 }, 0, .none },362 .{ .mov, .mr, &.{ .rm8, .r8 }, &.{ 0x88 }, 0, .none },
363 .{ .mov, .mr, .rm32, .r32, .none, .none, &.{ 0x89 }, 0, .none },363 .{ .mov, .mr, &.{ .rm8, .r8 }, &.{ 0x88 }, 0, .rex },
364 .{ .mov, .mr, .rm64, .r64, .none, .none, &.{ 0x89 }, 0, .long },364 .{ .mov, .mr, &.{ .rm16, .r16 }, &.{ 0x89 }, 0, .none },
365 .{ .mov, .rm, .r8, .rm8, .none, .none, &.{ 0x8a }, 0, .none },365 .{ .mov, .mr, &.{ .rm32, .r32 }, &.{ 0x89 }, 0, .none },
366 .{ .mov, .rm, .r8, .rm8, .none, .none, &.{ 0x8a }, 0, .rex },366 .{ .mov, .mr, &.{ .rm64, .r64 }, &.{ 0x89 }, 0, .long },
367 .{ .mov, .rm, .r16, .rm16, .none, .none, &.{ 0x8b }, 0, .none },367 .{ .mov, .rm, &.{ .r8, .rm8 }, &.{ 0x8a }, 0, .none },
368 .{ .mov, .rm, .r32, .rm32, .none, .none, &.{ 0x8b }, 0, .none },368 .{ .mov, .rm, &.{ .r8, .rm8 }, &.{ 0x8a }, 0, .rex },
369 .{ .mov, .rm, .r64, .rm64, .none, .none, &.{ 0x8b }, 0, .long },369 .{ .mov, .rm, &.{ .r16, .rm16 }, &.{ 0x8b }, 0, .none },
370 .{ .mov, .mr, .rm16, .sreg, .none, .none, &.{ 0x8c }, 0, .none },370 .{ .mov, .rm, &.{ .r32, .rm32 }, &.{ 0x8b }, 0, .none },
371 .{ .mov, .mr, .rm64, .sreg, .none, .none, &.{ 0x8c }, 0, .long },371 .{ .mov, .rm, &.{ .r64, .rm64 }, &.{ 0x8b }, 0, .long },
372 .{ .mov, .rm, .sreg, .rm16, .none, .none, &.{ 0x8e }, 0, .none },372 .{ .mov, .mr, &.{ .rm16, .sreg }, &.{ 0x8c }, 0, .none },
373 .{ .mov, .rm, .sreg, .rm64, .none, .none, &.{ 0x8e }, 0, .long },373 .{ .mov, .mr, &.{ .rm64, .sreg }, &.{ 0x8c }, 0, .long },
374 .{ .mov, .fd, .al, .moffs, .none, .none, &.{ 0xa0 }, 0, .none },374 .{ .mov, .rm, &.{ .sreg, .rm16 }, &.{ 0x8e }, 0, .none },
375 .{ .mov, .fd, .ax, .moffs, .none, .none, &.{ 0xa1 }, 0, .none },375 .{ .mov, .rm, &.{ .sreg, .rm64 }, &.{ 0x8e }, 0, .long },
376 .{ .mov, .fd, .eax, .moffs, .none, .none, &.{ 0xa1 }, 0, .none },376 .{ .mov, .fd, &.{ .al, .moffs }, &.{ 0xa0 }, 0, .none },
377 .{ .mov, .fd, .rax, .moffs, .none, .none, &.{ 0xa1 }, 0, .long },377 .{ .mov, .fd, &.{ .ax, .moffs }, &.{ 0xa1 }, 0, .none },
378 .{ .mov, .td, .moffs, .al, .none, .none, &.{ 0xa2 }, 0, .none },378 .{ .mov, .fd, &.{ .eax, .moffs }, &.{ 0xa1 }, 0, .none },
379 .{ .mov, .td, .moffs, .ax, .none, .none, &.{ 0xa3 }, 0, .none },379 .{ .mov, .fd, &.{ .rax, .moffs }, &.{ 0xa1 }, 0, .long },
380 .{ .mov, .td, .moffs, .eax, .none, .none, &.{ 0xa3 }, 0, .none },380 .{ .mov, .td, &.{ .moffs, .al }, &.{ 0xa2 }, 0, .none },
381 .{ .mov, .td, .moffs, .rax, .none, .none, &.{ 0xa3 }, 0, .long },381 .{ .mov, .td, &.{ .moffs, .ax }, &.{ 0xa3 }, 0, .none },
382 .{ .mov, .oi, .r8, .imm8, .none, .none, &.{ 0xb0 }, 0, .none },382 .{ .mov, .td, &.{ .moffs, .eax }, &.{ 0xa3 }, 0, .none },
383 .{ .mov, .oi, .r8, .imm8, .none, .none, &.{ 0xb0 }, 0, .rex },383 .{ .mov, .td, &.{ .moffs, .rax }, &.{ 0xa3 }, 0, .long },
384 .{ .mov, .oi, .r16, .imm16, .none, .none, &.{ 0xb8 }, 0, .none },384 .{ .mov, .oi, &.{ .r8, .imm8 }, &.{ 0xb0 }, 0, .none },
385 .{ .mov, .oi, .r32, .imm32, .none, .none, &.{ 0xb8 }, 0, .none },385 .{ .mov, .oi, &.{ .r8, .imm8 }, &.{ 0xb0 }, 0, .rex },
386 .{ .mov, .oi, .r64, .imm64, .none, .none, &.{ 0xb8 }, 0, .long },386 .{ .mov, .oi, &.{ .r16, .imm16 }, &.{ 0xb8 }, 0, .none },
387 .{ .mov, .mi, .rm8, .imm8, .none, .none, &.{ 0xc6 }, 0, .none },387 .{ .mov, .oi, &.{ .r32, .imm32 }, &.{ 0xb8 }, 0, .none },
388 .{ .mov, .mi, .rm8, .imm8, .none, .none, &.{ 0xc6 }, 0, .rex },388 .{ .mov, .oi, &.{ .r64, .imm64 }, &.{ 0xb8 }, 0, .long },
389 .{ .mov, .mi, .rm16, .imm16, .none, .none, &.{ 0xc7 }, 0, .none },389 .{ .mov, .mi, &.{ .rm8, .imm8 }, &.{ 0xc6 }, 0, .none },
390 .{ .mov, .mi, .rm32, .imm32, .none, .none, &.{ 0xc7 }, 0, .none },390 .{ .mov, .mi, &.{ .rm8, .imm8 }, &.{ 0xc6 }, 0, .rex },
391 .{ .mov, .mi, .rm64, .imm32s, .none, .none, &.{ 0xc7 }, 0, .long },391 .{ .mov, .mi, &.{ .rm16, .imm16 }, &.{ 0xc7 }, 0, .none },
392392 .{ .mov, .mi, &.{ .rm32, .imm32 }, &.{ 0xc7 }, 0, .none },
393 .{ .movbe, .rm, .r16, .m16, .none, .none, &.{ 0x0f, 0x38, 0xf0 }, 0, .none },393 .{ .mov, .mi, &.{ .rm64, .imm32s }, &.{ 0xc7 }, 0, .long },
394 .{ .movbe, .rm, .r32, .m32, .none, .none, &.{ 0x0f, 0x38, 0xf0 }, 0, .none },394
395 .{ .movbe, .rm, .r64, .m64, .none, .none, &.{ 0x0f, 0x38, 0xf0 }, 0, .long },395 .{ .movbe, .rm, &.{ .r16, .m16 }, &.{ 0x0f, 0x38, 0xf0 }, 0, .none },
396 .{ .movbe, .mr, .m16, .r16, .none, .none, &.{ 0x0f, 0x38, 0xf1 }, 0, .none },396 .{ .movbe, .rm, &.{ .r32, .m32 }, &.{ 0x0f, 0x38, 0xf0 }, 0, .none },
397 .{ .movbe, .mr, .m32, .r32, .none, .none, &.{ 0x0f, 0x38, 0xf1 }, 0, .none },397 .{ .movbe, .rm, &.{ .r64, .m64 }, &.{ 0x0f, 0x38, 0xf0 }, 0, .long },
398 .{ .movbe, .mr, .m64, .r64, .none, .none, &.{ 0x0f, 0x38, 0xf1 }, 0, .long },398 .{ .movbe, .mr, &.{ .m16, .r16 }, &.{ 0x0f, 0x38, 0xf1 }, 0, .none },
399399 .{ .movbe, .mr, &.{ .m32, .r32 }, &.{ 0x0f, 0x38, 0xf1 }, 0, .none },
400 .{ .movs, .np, .m8, .m8, .none, .none, &.{ 0xa4 }, 0, .none },400 .{ .movbe, .mr, &.{ .m64, .r64 }, &.{ 0x0f, 0x38, 0xf1 }, 0, .long },
401 .{ .movs, .np, .m16, .m16, .none, .none, &.{ 0xa5 }, 0, .none },401
402 .{ .movs, .np, .m32, .m32, .none, .none, &.{ 0xa5 }, 0, .none },402 .{ .movs, .np, &.{ .m8, .m8 }, &.{ 0xa4 }, 0, .none },
403 .{ .movs, .np, .m64, .m64, .none, .none, &.{ 0xa5 }, 0, .long },403 .{ .movs, .np, &.{ .m16, .m16 }, &.{ 0xa5 }, 0, .none },
404 .{ .movsb, .np, .none, .none, .none, .none, &.{ 0xa4 }, 0, .none },404 .{ .movs, .np, &.{ .m32, .m32 }, &.{ 0xa5 }, 0, .none },
405 .{ .movsw, .np, .none, .none, .none, .none, &.{ 0xa5 }, 0, .short },405 .{ .movs, .np, &.{ .m64, .m64 }, &.{ 0xa5 }, 0, .long },
406 .{ .movsd, .np, .none, .none, .none, .none, &.{ 0xa5 }, 0, .none },406
407 .{ .movsq, .np, .none, .none, .none, .none, &.{ 0xa5 }, 0, .long },407 .{ .movsb, .np, &.{}, &.{ 0xa4 }, 0, .none },
408408 .{ .movsw, .np, &.{}, &.{ 0xa5 }, 0, .short },
409 .{ .movsx, .rm, .r16, .rm8, .none, .none, &.{ 0x0f, 0xbe }, 0, .none },409 .{ .movsd, .np, &.{}, &.{ 0xa5 }, 0, .none },
410 .{ .movsx, .rm, .r16, .rm8, .none, .none, &.{ 0x0f, 0xbe }, 0, .rex },410 .{ .movsq, .np, &.{}, &.{ 0xa5 }, 0, .long },
411 .{ .movsx, .rm, .r32, .rm8, .none, .none, &.{ 0x0f, 0xbe }, 0, .none },411
412 .{ .movsx, .rm, .r32, .rm8, .none, .none, &.{ 0x0f, 0xbe }, 0, .rex },412 .{ .movsx, .rm, &.{ .r16, .rm8 }, &.{ 0x0f, 0xbe }, 0, .none },
413 .{ .movsx, .rm, .r64, .rm8, .none, .none, &.{ 0x0f, 0xbe }, 0, .long },413 .{ .movsx, .rm, &.{ .r16, .rm8 }, &.{ 0x0f, 0xbe }, 0, .rex },
414 .{ .movsx, .rm, .r32, .rm16, .none, .none, &.{ 0x0f, 0xbf }, 0, .none },414 .{ .movsx, .rm, &.{ .r32, .rm8 }, &.{ 0x0f, 0xbe }, 0, .none },
415 .{ .movsx, .rm, .r64, .rm16, .none, .none, &.{ 0x0f, 0xbf }, 0, .long },415 .{ .movsx, .rm, &.{ .r32, .rm8 }, &.{ 0x0f, 0xbe }, 0, .rex },
416 .{ .movsx, .rm, &.{ .r64, .rm8 }, &.{ 0x0f, 0xbe }, 0, .long },
417 .{ .movsx, .rm, &.{ .r32, .rm16 }, &.{ 0x0f, 0xbf }, 0, .none },
418 .{ .movsx, .rm, &.{ .r64, .rm16 }, &.{ 0x0f, 0xbf }, 0, .long },
416419
417 // This instruction is discouraged.420 // This instruction is discouraged.
418 .{ .movsxd, .rm, .r32, .rm32, .none, .none, &.{ 0x63 }, 0, .none },421 .{ .movsxd, .rm, &.{ .r32, .rm32 }, &.{ 0x63 }, 0, .none },
419 .{ .movsxd, .rm, .r64, .rm32, .none, .none, &.{ 0x63 }, 0, .long },422 .{ .movsxd, .rm, &.{ .r64, .rm32 }, &.{ 0x63 }, 0, .long },
420423
421 .{ .movzx, .rm, .r16, .rm8, .none, .none, &.{ 0x0f, 0xb6 }, 0, .none },424 .{ .movzx, .rm, &.{ .r16, .rm8 }, &.{ 0x0f, 0xb6 }, 0, .none },
422 .{ .movzx, .rm, .r32, .rm8, .none, .none, &.{ 0x0f, 0xb6 }, 0, .none },425 .{ .movzx, .rm, &.{ .r32, .rm8 }, &.{ 0x0f, 0xb6 }, 0, .none },
423 .{ .movzx, .rm, .r64, .rm8, .none, .none, &.{ 0x0f, 0xb6 }, 0, .long },426 .{ .movzx, .rm, &.{ .r64, .rm8 }, &.{ 0x0f, 0xb6 }, 0, .long },
424 .{ .movzx, .rm, .r32, .rm16, .none, .none, &.{ 0x0f, 0xb7 }, 0, .none },427 .{ .movzx, .rm, &.{ .r32, .rm16 }, &.{ 0x0f, 0xb7 }, 0, .none },
425 .{ .movzx, .rm, .r64, .rm16, .none, .none, &.{ 0x0f, 0xb7 }, 0, .long },428 .{ .movzx, .rm, &.{ .r64, .rm16 }, &.{ 0x0f, 0xb7 }, 0, .long },
426429
427 .{ .mul, .m, .rm8, .none, .none, .none, &.{ 0xf6 }, 4, .none },430 .{ .mul, .m, &.{ .rm8 }, &.{ 0xf6 }, 4, .none },
428 .{ .mul, .m, .rm8, .none, .none, .none, &.{ 0xf6 }, 4, .rex },431 .{ .mul, .m, &.{ .rm8 }, &.{ 0xf6 }, 4, .rex },
429 .{ .mul, .m, .rm16, .none, .none, .none, &.{ 0xf7 }, 4, .none },432 .{ .mul, .m, &.{ .rm16 }, &.{ 0xf7 }, 4, .none },
430 .{ .mul, .m, .rm32, .none, .none, .none, &.{ 0xf7 }, 4, .none },433 .{ .mul, .m, &.{ .rm32 }, &.{ 0xf7 }, 4, .none },
431 .{ .mul, .m, .rm64, .none, .none, .none, &.{ 0xf7 }, 4, .long },434 .{ .mul, .m, &.{ .rm64 }, &.{ 0xf7 }, 4, .long },
432435
433 .{ .neg, .m, .rm8, .none, .none, .none, &.{ 0xf6 }, 3, .none },436 .{ .neg, .m, &.{ .rm8 }, &.{ 0xf6 }, 3, .none },
434 .{ .neg, .m, .rm8, .none, .none, .none, &.{ 0xf6 }, 3, .rex },437 .{ .neg, .m, &.{ .rm8 }, &.{ 0xf6 }, 3, .rex },
435 .{ .neg, .m, .rm16, .none, .none, .none, &.{ 0xf7 }, 3, .none },438 .{ .neg, .m, &.{ .rm16 }, &.{ 0xf7 }, 3, .none },
436 .{ .neg, .m, .rm32, .none, .none, .none, &.{ 0xf7 }, 3, .none },439 .{ .neg, .m, &.{ .rm32 }, &.{ 0xf7 }, 3, .none },
437 .{ .neg, .m, .rm64, .none, .none, .none, &.{ 0xf7 }, 3, .long },440 .{ .neg, .m, &.{ .rm64 }, &.{ 0xf7 }, 3, .long },
438441
439 .{ .nop, .np, .none, .none, .none, .none, &.{ 0x90 }, 0, .none },442 .{ .nop, .np, &.{}, &.{ 0x90 }, 0, .none },
440443
441 .{ .not, .m, .rm8, .none, .none, .none, &.{ 0xf6 }, 2, .none },444 .{ .not, .m, &.{ .rm8 }, &.{ 0xf6 }, 2, .none },
442 .{ .not, .m, .rm8, .none, .none, .none, &.{ 0xf6 }, 2, .rex },445 .{ .not, .m, &.{ .rm8 }, &.{ 0xf6 }, 2, .rex },
443 .{ .not, .m, .rm16, .none, .none, .none, &.{ 0xf7 }, 2, .none },446 .{ .not, .m, &.{ .rm16 }, &.{ 0xf7 }, 2, .none },
444 .{ .not, .m, .rm32, .none, .none, .none, &.{ 0xf7 }, 2, .none },447 .{ .not, .m, &.{ .rm32 }, &.{ 0xf7 }, 2, .none },
445 .{ .not, .m, .rm64, .none, .none, .none, &.{ 0xf7 }, 2, .long },448 .{ .not, .m, &.{ .rm64 }, &.{ 0xf7 }, 2, .long },
446449
447 .{ .@"or", .zi, .al, .imm8, .none, .none, &.{ 0x0c }, 0, .none },450 .{ .@"or", .zi, &.{ .al, .imm8 }, &.{ 0x0c }, 0, .none },
448 .{ .@"or", .zi, .ax, .imm16, .none, .none, &.{ 0x0d }, 0, .none },451 .{ .@"or", .zi, &.{ .ax, .imm16 }, &.{ 0x0d }, 0, .none },
449 .{ .@"or", .zi, .eax, .imm32, .none, .none, &.{ 0x0d }, 0, .none },452 .{ .@"or", .zi, &.{ .eax, .imm32 }, &.{ 0x0d }, 0, .none },
450 .{ .@"or", .zi, .rax, .imm32s, .none, .none, &.{ 0x0d }, 0, .long },453 .{ .@"or", .zi, &.{ .rax, .imm32s }, &.{ 0x0d }, 0, .long },
451 .{ .@"or", .mi, .rm8, .imm8, .none, .none, &.{ 0x80 }, 1, .none },454 .{ .@"or", .mi, &.{ .rm8, .imm8 }, &.{ 0x80 }, 1, .none },
452 .{ .@"or", .mi, .rm8, .imm8, .none, .none, &.{ 0x80 }, 1, .rex },455 .{ .@"or", .mi, &.{ .rm8, .imm8 }, &.{ 0x80 }, 1, .rex },
453 .{ .@"or", .mi, .rm16, .imm16, .none, .none, &.{ 0x81 }, 1, .none },456 .{ .@"or", .mi, &.{ .rm16, .imm16 }, &.{ 0x81 }, 1, .none },
454 .{ .@"or", .mi, .rm32, .imm32, .none, .none, &.{ 0x81 }, 1, .none },457 .{ .@"or", .mi, &.{ .rm32, .imm32 }, &.{ 0x81 }, 1, .none },
455 .{ .@"or", .mi, .rm64, .imm32s, .none, .none, &.{ 0x81 }, 1, .long },458 .{ .@"or", .mi, &.{ .rm64, .imm32s }, &.{ 0x81 }, 1, .long },
456 .{ .@"or", .mi, .rm16, .imm8s, .none, .none, &.{ 0x83 }, 1, .none },459 .{ .@"or", .mi, &.{ .rm16, .imm8s }, &.{ 0x83 }, 1, .none },
457 .{ .@"or", .mi, .rm32, .imm8s, .none, .none, &.{ 0x83 }, 1, .none },460 .{ .@"or", .mi, &.{ .rm32, .imm8s }, &.{ 0x83 }, 1, .none },
458 .{ .@"or", .mi, .rm64, .imm8s, .none, .none, &.{ 0x83 }, 1, .long },461 .{ .@"or", .mi, &.{ .rm64, .imm8s }, &.{ 0x83 }, 1, .long },
459 .{ .@"or", .mr, .rm8, .r8, .none, .none, &.{ 0x08 }, 0, .none },462 .{ .@"or", .mr, &.{ .rm8, .r8 }, &.{ 0x08 }, 0, .none },
460 .{ .@"or", .mr, .rm8, .r8, .none, .none, &.{ 0x08 }, 0, .rex },463 .{ .@"or", .mr, &.{ .rm8, .r8 }, &.{ 0x08 }, 0, .rex },
461 .{ .@"or", .mr, .rm16, .r16, .none, .none, &.{ 0x09 }, 0, .none },464 .{ .@"or", .mr, &.{ .rm16, .r16 }, &.{ 0x09 }, 0, .none },
462 .{ .@"or", .mr, .rm32, .r32, .none, .none, &.{ 0x09 }, 0, .none },465 .{ .@"or", .mr, &.{ .rm32, .r32 }, &.{ 0x09 }, 0, .none },
463 .{ .@"or", .mr, .rm64, .r64, .none, .none, &.{ 0x09 }, 0, .long },466 .{ .@"or", .mr, &.{ .rm64, .r64 }, &.{ 0x09 }, 0, .long },
464 .{ .@"or", .rm, .r8, .rm8, .none, .none, &.{ 0x0a }, 0, .none },467 .{ .@"or", .rm, &.{ .r8, .rm8 }, &.{ 0x0a }, 0, .none },
465 .{ .@"or", .rm, .r8, .rm8, .none, .none, &.{ 0x0a }, 0, .rex },468 .{ .@"or", .rm, &.{ .r8, .rm8 }, &.{ 0x0a }, 0, .rex },
466 .{ .@"or", .rm, .r16, .rm16, .none, .none, &.{ 0x0b }, 0, .none },469 .{ .@"or", .rm, &.{ .r16, .rm16 }, &.{ 0x0b }, 0, .none },
467 .{ .@"or", .rm, .r32, .rm32, .none, .none, &.{ 0x0b }, 0, .none },470 .{ .@"or", .rm, &.{ .r32, .rm32 }, &.{ 0x0b }, 0, .none },
468 .{ .@"or", .rm, .r64, .rm64, .none, .none, &.{ 0x0b }, 0, .long },471 .{ .@"or", .rm, &.{ .r64, .rm64 }, &.{ 0x0b }, 0, .long },
469472
470 .{ .pop, .o, .r16, .none, .none, .none, &.{ 0x58 }, 0, .none },473 .{ .pop, .o, &.{ .r16 }, &.{ 0x58 }, 0, .none },
471 .{ .pop, .o, .r64, .none, .none, .none, &.{ 0x58 }, 0, .none },474 .{ .pop, .o, &.{ .r64 }, &.{ 0x58 }, 0, .none },
472 .{ .pop, .m, .rm16, .none, .none, .none, &.{ 0x8f }, 0, .none },475 .{ .pop, .m, &.{ .rm16 }, &.{ 0x8f }, 0, .none },
473 .{ .pop, .m, .rm64, .none, .none, .none, &.{ 0x8f }, 0, .none },476 .{ .pop, .m, &.{ .rm64 }, &.{ 0x8f }, 0, .none },
474477
475 .{ .popcnt, .rm, .r16, .rm16, .none, .none, &.{ 0xf3, 0x0f, 0xb8 }, 0, .none },478 .{ .popcnt, .rm, &.{ .r16, .rm16 }, &.{ 0xf3, 0x0f, 0xb8 }, 0, .none },
476 .{ .popcnt, .rm, .r32, .rm32, .none, .none, &.{ 0xf3, 0x0f, 0xb8 }, 0, .none },479 .{ .popcnt, .rm, &.{ .r32, .rm32 }, &.{ 0xf3, 0x0f, 0xb8 }, 0, .none },
477 .{ .popcnt, .rm, .r64, .rm64, .none, .none, &.{ 0xf3, 0x0f, 0xb8 }, 0, .long },480 .{ .popcnt, .rm, &.{ .r64, .rm64 }, &.{ 0xf3, 0x0f, 0xb8 }, 0, .long },
478481
479 .{ .push, .o, .r16, .none, .none, .none, &.{ 0x50 }, 0, .none },482 .{ .push, .o, &.{ .r16 }, &.{ 0x50 }, 0, .none },
480 .{ .push, .o, .r64, .none, .none, .none, &.{ 0x50 }, 0, .none },483 .{ .push, .o, &.{ .r64 }, &.{ 0x50 }, 0, .none },
481 .{ .push, .m, .rm16, .none, .none, .none, &.{ 0xff }, 6, .none },484 .{ .push, .m, &.{ .rm16 }, &.{ 0xff }, 6, .none },
482 .{ .push, .m, .rm64, .none, .none, .none, &.{ 0xff }, 6, .none },485 .{ .push, .m, &.{ .rm64 }, &.{ 0xff }, 6, .none },
483 .{ .push, .i, .imm8, .none, .none, .none, &.{ 0x6a }, 0, .none },486 .{ .push, .i, &.{ .imm8 }, &.{ 0x6a }, 0, .none },
484 .{ .push, .i, .imm16, .none, .none, .none, &.{ 0x68 }, 0, .none },487 .{ .push, .i, &.{ .imm16 }, &.{ 0x68 }, 0, .none },
485 .{ .push, .i, .imm32, .none, .none, .none, &.{ 0x68 }, 0, .none },488 .{ .push, .i, &.{ .imm32 }, &.{ 0x68 }, 0, .none },
486489
487 .{ .ret, .np, .none, .none, .none, .none, &.{ 0xc3 }, 0, .none },490 .{ .ret, .np, &.{}, &.{ 0xc3 }, 0, .none },
488491
489 .{ .rcl, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 2, .none },492 .{ .rcl, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 2, .none },
490 .{ .rcl, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 2, .rex },493 .{ .rcl, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 2, .rex },
491 .{ .rcl, .mc, .rm8, .cl, .none, .none, &.{ 0xd2 }, 2, .none },494 .{ .rcl, .mc, &.{ .rm8, .cl }, &.{ 0xd2 }, 2, .none },
492 .{ .rcl, .mc, .rm8, .cl, .none, .none, &.{ 0xd2 }, 2, .rex },495 .{ .rcl, .mc, &.{ .rm8, .cl }, &.{ 0xd2 }, 2, .rex },
493 .{ .rcl, .mi, .rm8, .imm8, .none, .none, &.{ 0xc0 }, 2, .none },496 .{ .rcl, .mi, &.{ .rm8, .imm8 }, &.{ 0xc0 }, 2, .none },
494 .{ .rcl, .mi, .rm8, .imm8, .none, .none, &.{ 0xc0 }, 2, .rex },497 .{ .rcl, .mi, &.{ .rm8, .imm8 }, &.{ 0xc0 }, 2, .rex },
495 .{ .rcl, .m1, .rm16, .unity, .none, .none, &.{ 0xd1 }, 2, .none },498 .{ .rcl, .m1, &.{ .rm16, .unity }, &.{ 0xd1 }, 2, .none },
496 .{ .rcl, .mc, .rm16, .cl, .none, .none, &.{ 0xd3 }, 2, .none },499 .{ .rcl, .mc, &.{ .rm16, .cl }, &.{ 0xd3 }, 2, .none },
497 .{ .rcl, .mi, .rm16, .imm8, .none, .none, &.{ 0xc1 }, 2, .none },500 .{ .rcl, .mi, &.{ .rm16, .imm8 }, &.{ 0xc1 }, 2, .none },
498 .{ .rcl, .m1, .rm32, .unity, .none, .none, &.{ 0xd1 }, 2, .none },501 .{ .rcl, .m1, &.{ .rm32, .unity }, &.{ 0xd1 }, 2, .none },
499 .{ .rcl, .m1, .rm64, .unity, .none, .none, &.{ 0xd1 }, 2, .long },502 .{ .rcl, .m1, &.{ .rm64, .unity }, &.{ 0xd1 }, 2, .long },
500 .{ .rcl, .mc, .rm32, .cl, .none, .none, &.{ 0xd3 }, 2, .none },503 .{ .rcl, .mc, &.{ .rm32, .cl }, &.{ 0xd3 }, 2, .none },
501 .{ .rcl, .mc, .rm64, .cl, .none, .none, &.{ 0xd3 }, 2, .long },504 .{ .rcl, .mc, &.{ .rm64, .cl }, &.{ 0xd3 }, 2, .long },
502 .{ .rcl, .mi, .rm32, .imm8, .none, .none, &.{ 0xc1 }, 2, .none },505 .{ .rcl, .mi, &.{ .rm32, .imm8 }, &.{ 0xc1 }, 2, .none },
503 .{ .rcl, .mi, .rm64, .imm8, .none, .none, &.{ 0xc1 }, 2, .long },506 .{ .rcl, .mi, &.{ .rm64, .imm8 }, &.{ 0xc1 }, 2, .long },
504507
505 .{ .rcr, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 3, .none },508 .{ .rcr, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 3, .none },
506 .{ .rcr, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 3, .rex },509 .{ .rcr, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 3, .rex },
507 .{ .rcr, .mc, .rm8, .cl, .none, .none, &.{ 0xd2 }, 3, .none },510 .{ .rcr, .mc, &.{ .rm8, .cl }, &.{ 0xd2 }, 3, .none },
508 .{ .rcr, .mc, .rm8, .cl, .none, .none, &.{ 0xd2 }, 3, .rex },511 .{ .rcr, .mc, &.{ .rm8, .cl }, &.{ 0xd2 }, 3, .rex },
509 .{ .rcr, .mi, .rm8, .imm8, .none, .none, &.{ 0xc0 }, 3, .none },512 .{ .rcr, .mi, &.{ .rm8, .imm8 }, &.{ 0xc0 }, 3, .none },
510 .{ .rcr, .mi, .rm8, .imm8, .none, .none, &.{ 0xc0 }, 3, .rex },513 .{ .rcr, .mi, &.{ .rm8, .imm8 }, &.{ 0xc0 }, 3, .rex },
511 .{ .rcr, .m1, .rm16, .unity, .none, .none, &.{ 0xd1 }, 3, .none },514 .{ .rcr, .m1, &.{ .rm16, .unity }, &.{ 0xd1 }, 3, .none },
512 .{ .rcr, .mc, .rm16, .cl, .none, .none, &.{ 0xd3 }, 3, .none },515 .{ .rcr, .mc, &.{ .rm16, .cl }, &.{ 0xd3 }, 3, .none },
513 .{ .rcr, .mi, .rm16, .imm8, .none, .none, &.{ 0xc1 }, 3, .none },516 .{ .rcr, .mi, &.{ .rm16, .imm8 }, &.{ 0xc1 }, 3, .none },
514 .{ .rcr, .m1, .rm32, .unity, .none, .none, &.{ 0xd1 }, 3, .none },517 .{ .rcr, .m1, &.{ .rm32, .unity }, &.{ 0xd1 }, 3, .none },
515 .{ .rcr, .m1, .rm64, .unity, .none, .none, &.{ 0xd1 }, 3, .long },518 .{ .rcr, .m1, &.{ .rm64, .unity }, &.{ 0xd1 }, 3, .long },
516 .{ .rcr, .mc, .rm32, .cl, .none, .none, &.{ 0xd3 }, 3, .none },519 .{ .rcr, .mc, &.{ .rm32, .cl }, &.{ 0xd3 }, 3, .none },
517 .{ .rcr, .mc, .rm64, .cl, .none, .none, &.{ 0xd3 }, 3, .long },520 .{ .rcr, .mc, &.{ .rm64, .cl }, &.{ 0xd3 }, 3, .long },
518 .{ .rcr, .mi, .rm32, .imm8, .none, .none, &.{ 0xc1 }, 3, .none },521 .{ .rcr, .mi, &.{ .rm32, .imm8 }, &.{ 0xc1 }, 3, .none },
519 .{ .rcr, .mi, .rm64, .imm8, .none, .none, &.{ 0xc1 }, 3, .long },522 .{ .rcr, .mi, &.{ .rm64, .imm8 }, &.{ 0xc1 }, 3, .long },
520523
521 .{ .rol, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 0, .none },524 .{ .rol, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 0, .none },
522 .{ .rol, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 0, .rex },525 .{ .rol, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 0, .rex },
523 .{ .rol, .mc, .rm8, .cl, .none, .none, &.{ 0xd2 }, 0, .none },526 .{ .rol, .mc, &.{ .rm8, .cl }, &.{ 0xd2 }, 0, .none },
524 .{ .rol, .mc, .rm8, .cl, .none, .none, &.{ 0xd2 }, 0, .rex },527 .{ .rol, .mc, &.{ .rm8, .cl }, &.{ 0xd2 }, 0, .rex },
525 .{ .rol, .mi, .rm8, .imm8, .none, .none, &.{ 0xc0 }, 0, .none },528 .{ .rol, .mi, &.{ .rm8, .imm8 }, &.{ 0xc0 }, 0, .none },
526 .{ .rol, .mi, .rm8, .imm8, .none, .none, &.{ 0xc0 }, 0, .rex },529 .{ .rol, .mi, &.{ .rm8, .imm8 }, &.{ 0xc0 }, 0, .rex },
527 .{ .rol, .m1, .rm16, .unity, .none, .none, &.{ 0xd1 }, 0, .none },530 .{ .rol, .m1, &.{ .rm16, .unity }, &.{ 0xd1 }, 0, .none },
528 .{ .rol, .mc, .rm16, .cl, .none, .none, &.{ 0xd3 }, 0, .none },531 .{ .rol, .mc, &.{ .rm16, .cl }, &.{ 0xd3 }, 0, .none },
529 .{ .rol, .mi, .rm16, .imm8, .none, .none, &.{ 0xc1 }, 0, .none },532 .{ .rol, .mi, &.{ .rm16, .imm8 }, &.{ 0xc1 }, 0, .none },
530 .{ .rol, .m1, .rm32, .unity, .none, .none, &.{ 0xd1 }, 0, .none },533 .{ .rol, .m1, &.{ .rm32, .unity }, &.{ 0xd1 }, 0, .none },
531 .{ .rol, .m1, .rm64, .unity, .none, .none, &.{ 0xd1 }, 0, .long },534 .{ .rol, .m1, &.{ .rm64, .unity }, &.{ 0xd1 }, 0, .long },
532 .{ .rol, .mc, .rm32, .cl, .none, .none, &.{ 0xd3 }, 0, .none },535 .{ .rol, .mc, &.{ .rm32, .cl }, &.{ 0xd3 }, 0, .none },
533 .{ .rol, .mc, .rm64, .cl, .none, .none, &.{ 0xd3 }, 0, .long },536 .{ .rol, .mc, &.{ .rm64, .cl }, &.{ 0xd3 }, 0, .long },
534 .{ .rol, .mi, .rm32, .imm8, .none, .none, &.{ 0xc1 }, 0, .none },537 .{ .rol, .mi, &.{ .rm32, .imm8 }, &.{ 0xc1 }, 0, .none },
535 .{ .rol, .mi, .rm64, .imm8, .none, .none, &.{ 0xc1 }, 0, .long },538 .{ .rol, .mi, &.{ .rm64, .imm8 }, &.{ 0xc1 }, 0, .long },
536539
537 .{ .ror, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 1, .none },540 .{ .ror, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 1, .none },
538 .{ .ror, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 1, .rex },541 .{ .ror, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 1, .rex },
539 .{ .ror, .mc, .rm8, .cl, .none, .none, &.{ 0xd2 }, 1, .none },542 .{ .ror, .mc, &.{ .rm8, .cl }, &.{ 0xd2 }, 1, .none },
540 .{ .ror, .mc, .rm8, .cl, .none, .none, &.{ 0xd2 }, 1, .rex },543 .{ .ror, .mc, &.{ .rm8, .cl }, &.{ 0xd2 }, 1, .rex },
541 .{ .ror, .mi, .rm8, .imm8, .none, .none, &.{ 0xc0 }, 1, .none },544 .{ .ror, .mi, &.{ .rm8, .imm8 }, &.{ 0xc0 }, 1, .none },
542 .{ .ror, .mi, .rm8, .imm8, .none, .none, &.{ 0xc0 }, 1, .rex },545 .{ .ror, .mi, &.{ .rm8, .imm8 }, &.{ 0xc0 }, 1, .rex },
543 .{ .ror, .m1, .rm16, .unity, .none, .none, &.{ 0xd1 }, 1, .none },546 .{ .ror, .m1, &.{ .rm16, .unity }, &.{ 0xd1 }, 1, .none },
544 .{ .ror, .mc, .rm16, .cl, .none, .none, &.{ 0xd3 }, 1, .none },547 .{ .ror, .mc, &.{ .rm16, .cl }, &.{ 0xd3 }, 1, .none },
545 .{ .ror, .mi, .rm16, .imm8, .none, .none, &.{ 0xc1 }, 1, .none },548 .{ .ror, .mi, &.{ .rm16, .imm8 }, &.{ 0xc1 }, 1, .none },
546 .{ .ror, .m1, .rm32, .unity, .none, .none, &.{ 0xd1 }, 1, .none },549 .{ .ror, .m1, &.{ .rm32, .unity }, &.{ 0xd1 }, 1, .none },
547 .{ .ror, .m1, .rm64, .unity, .none, .none, &.{ 0xd1 }, 1, .long },550 .{ .ror, .m1, &.{ .rm64, .unity }, &.{ 0xd1 }, 1, .long },
548 .{ .ror, .mc, .rm32, .cl, .none, .none, &.{ 0xd3 }, 1, .none },551 .{ .ror, .mc, &.{ .rm32, .cl }, &.{ 0xd3 }, 1, .none },
549 .{ .ror, .mc, .rm64, .cl, .none, .none, &.{ 0xd3 }, 1, .long },552 .{ .ror, .mc, &.{ .rm64, .cl }, &.{ 0xd3 }, 1, .long },
550 .{ .ror, .mi, .rm32, .imm8, .none, .none, &.{ 0xc1 }, 1, .none },553 .{ .ror, .mi, &.{ .rm32, .imm8 }, &.{ 0xc1 }, 1, .none },
551 .{ .ror, .mi, .rm64, .imm8, .none, .none, &.{ 0xc1 }, 1, .long },554 .{ .ror, .mi, &.{ .rm64, .imm8 }, &.{ 0xc1 }, 1, .long },
552555
553 .{ .sal, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 4, .none },556 .{ .sal, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 4, .none },
554 .{ .sal, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 4, .rex },557 .{ .sal, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 4, .rex },
555 .{ .sal, .m1, .rm16, .unity, .none, .none, &.{ 0xd1 }, 4, .none },558 .{ .sal, .m1, &.{ .rm16, .unity }, &.{ 0xd1 }, 4, .none },
556 .{ .sal, .m1, .rm32, .unity, .none, .none, &.{ 0xd1 }, 4, .none },559 .{ .sal, .m1, &.{ .rm32, .unity }, &.{ 0xd1 }, 4, .none },
557 .{ .sal, .m1, .rm64, .unity, .none, .none, &.{ 0xd1 }, 4, .long },560 .{ .sal, .m1, &.{ .rm64, .unity }, &.{ 0xd1 }, 4, .long },
558 .{ .sal, .mc, .rm8, .cl, .none, .none, &.{ 0xd2 }, 4, .none },561 .{ .sal, .mc, &.{ .rm8, .cl }, &.{ 0xd2 }, 4, .none },
559 .{ .sal, .mc, .rm8, .cl, .none, .none, &.{ 0xd2 }, 4, .rex },562 .{ .sal, .mc, &.{ .rm8, .cl }, &.{ 0xd2 }, 4, .rex },
560 .{ .sal, .mc, .rm16, .cl, .none, .none, &.{ 0xd3 }, 4, .none },563 .{ .sal, .mc, &.{ .rm16, .cl }, &.{ 0xd3 }, 4, .none },
561 .{ .sal, .mc, .rm32, .cl, .none, .none, &.{ 0xd3 }, 4, .none },564 .{ .sal, .mc, &.{ .rm32, .cl }, &.{ 0xd3 }, 4, .none },
562 .{ .sal, .mc, .rm64, .cl, .none, .none, &.{ 0xd3 }, 4, .long },565 .{ .sal, .mc, &.{ .rm64, .cl }, &.{ 0xd3 }, 4, .long },
563 .{ .sal, .mi, .rm8, .imm8, .none, .none, &.{ 0xc0 }, 4, .none },566 .{ .sal, .mi, &.{ .rm8, .imm8 }, &.{ 0xc0 }, 4, .none },
564 .{ .sal, .mi, .rm8, .imm8, .none, .none, &.{ 0xc0 }, 4, .rex },567 .{ .sal, .mi, &.{ .rm8, .imm8 }, &.{ 0xc0 }, 4, .rex },
565 .{ .sal, .mi, .rm16, .imm8, .none, .none, &.{ 0xc1 }, 4, .none },568 .{ .sal, .mi, &.{ .rm16, .imm8 }, &.{ 0xc1 }, 4, .none },
566 .{ .sal, .mi, .rm32, .imm8, .none, .none, &.{ 0xc1 }, 4, .none },569 .{ .sal, .mi, &.{ .rm32, .imm8 }, &.{ 0xc1 }, 4, .none },
567 .{ .sal, .mi, .rm64, .imm8, .none, .none, &.{ 0xc1 }, 4, .long },570 .{ .sal, .mi, &.{ .rm64, .imm8 }, &.{ 0xc1 }, 4, .long },
568571
569 .{ .sar, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 7, .none },572 .{ .sar, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 7, .none },
570 .{ .sar, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 7, .rex },573 .{ .sar, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 7, .rex },
571 .{ .sar, .m1, .rm16, .unity, .none, .none, &.{ 0xd1 }, 7, .none },574 .{ .sar, .m1, &.{ .rm16, .unity }, &.{ 0xd1 }, 7, .none },
572 .{ .sar, .m1, .rm32, .unity, .none, .none, &.{ 0xd1 }, 7, .none },575 .{ .sar, .m1, &.{ .rm32, .unity }, &.{ 0xd1 }, 7, .none },
573 .{ .sar, .m1, .rm64, .unity, .none, .none, &.{ 0xd1 }, 7, .long },576 .{ .sar, .m1, &.{ .rm64, .unity }, &.{ 0xd1 }, 7, .long },
574 .{ .sar, .mc, .rm8, .cl, .none, .none, &.{ 0xd2 }, 7, .none },577 .{ .sar, .mc, &.{ .rm8, .cl }, &.{ 0xd2 }, 7, .none },
575 .{ .sar, .mc, .rm8, .cl, .none, .none, &.{ 0xd2 }, 7, .rex },578 .{ .sar, .mc, &.{ .rm8, .cl }, &.{ 0xd2 }, 7, .rex },
576 .{ .sar, .mc, .rm16, .cl, .none, .none, &.{ 0xd3 }, 7, .none },579 .{ .sar, .mc, &.{ .rm16, .cl }, &.{ 0xd3 }, 7, .none },
577 .{ .sar, .mc, .rm32, .cl, .none, .none, &.{ 0xd3 }, 7, .none },580 .{ .sar, .mc, &.{ .rm32, .cl }, &.{ 0xd3 }, 7, .none },
578 .{ .sar, .mc, .rm64, .cl, .none, .none, &.{ 0xd3 }, 7, .long },581 .{ .sar, .mc, &.{ .rm64, .cl }, &.{ 0xd3 }, 7, .long },
579 .{ .sar, .mi, .rm8, .imm8, .none, .none, &.{ 0xc0 }, 7, .none },582 .{ .sar, .mi, &.{ .rm8, .imm8 }, &.{ 0xc0 }, 7, .none },
580 .{ .sar, .mi, .rm8, .imm8, .none, .none, &.{ 0xc0 }, 7, .rex },583 .{ .sar, .mi, &.{ .rm8, .imm8 }, &.{ 0xc0 }, 7, .rex },
581 .{ .sar, .mi, .rm16, .imm8, .none, .none, &.{ 0xc1 }, 7, .none },584 .{ .sar, .mi, &.{ .rm16, .imm8 }, &.{ 0xc1 }, 7, .none },
582 .{ .sar, .mi, .rm32, .imm8, .none, .none, &.{ 0xc1 }, 7, .none },585 .{ .sar, .mi, &.{ .rm32, .imm8 }, &.{ 0xc1 }, 7, .none },
583 .{ .sar, .mi, .rm64, .imm8, .none, .none, &.{ 0xc1 }, 7, .long },586 .{ .sar, .mi, &.{ .rm64, .imm8 }, &.{ 0xc1 }, 7, .long },
584587
585 .{ .sbb, .zi, .al, .imm8, .none, .none, &.{ 0x1c }, 0, .none },588 .{ .sbb, .zi, &.{ .al, .imm8 }, &.{ 0x1c }, 0, .none },
586 .{ .sbb, .zi, .ax, .imm16, .none, .none, &.{ 0x1d }, 0, .none },589 .{ .sbb, .zi, &.{ .ax, .imm16 }, &.{ 0x1d }, 0, .none },
587 .{ .sbb, .zi, .eax, .imm32, .none, .none, &.{ 0x1d }, 0, .none },590 .{ .sbb, .zi, &.{ .eax, .imm32 }, &.{ 0x1d }, 0, .none },
588 .{ .sbb, .zi, .rax, .imm32s, .none, .none, &.{ 0x1d }, 0, .long },591 .{ .sbb, .zi, &.{ .rax, .imm32s }, &.{ 0x1d }, 0, .long },
589 .{ .sbb, .mi, .rm8, .imm8, .none, .none, &.{ 0x80 }, 3, .none },592 .{ .sbb, .mi, &.{ .rm8, .imm8 }, &.{ 0x80 }, 3, .none },
590 .{ .sbb, .mi, .rm8, .imm8, .none, .none, &.{ 0x80 }, 3, .rex },593 .{ .sbb, .mi, &.{ .rm8, .imm8 }, &.{ 0x80 }, 3, .rex },
591 .{ .sbb, .mi, .rm16, .imm16, .none, .none, &.{ 0x81 }, 3, .none },594 .{ .sbb, .mi, &.{ .rm16, .imm16 }, &.{ 0x81 }, 3, .none },
592 .{ .sbb, .mi, .rm32, .imm32, .none, .none, &.{ 0x81 }, 3, .none },595 .{ .sbb, .mi, &.{ .rm32, .imm32 }, &.{ 0x81 }, 3, .none },
593 .{ .sbb, .mi, .rm64, .imm32s, .none, .none, &.{ 0x81 }, 3, .long },596 .{ .sbb, .mi, &.{ .rm64, .imm32s }, &.{ 0x81 }, 3, .long },
594 .{ .sbb, .mi, .rm16, .imm8s, .none, .none, &.{ 0x83 }, 3, .none },597 .{ .sbb, .mi, &.{ .rm16, .imm8s }, &.{ 0x83 }, 3, .none },
595 .{ .sbb, .mi, .rm32, .imm8s, .none, .none, &.{ 0x83 }, 3, .none },598 .{ .sbb, .mi, &.{ .rm32, .imm8s }, &.{ 0x83 }, 3, .none },
596 .{ .sbb, .mi, .rm64, .imm8s, .none, .none, &.{ 0x83 }, 3, .long },599 .{ .sbb, .mi, &.{ .rm64, .imm8s }, &.{ 0x83 }, 3, .long },
597 .{ .sbb, .mr, .rm8, .r8, .none, .none, &.{ 0x18 }, 0, .none },600 .{ .sbb, .mr, &.{ .rm8, .r8 }, &.{ 0x18 }, 0, .none },
598 .{ .sbb, .mr, .rm8, .r8, .none, .none, &.{ 0x18 }, 0, .rex },601 .{ .sbb, .mr, &.{ .rm8, .r8 }, &.{ 0x18 }, 0, .rex },
599 .{ .sbb, .mr, .rm16, .r16, .none, .none, &.{ 0x19 }, 0, .none },602 .{ .sbb, .mr, &.{ .rm16, .r16 }, &.{ 0x19 }, 0, .none },
600 .{ .sbb, .mr, .rm32, .r32, .none, .none, &.{ 0x19 }, 0, .none },603 .{ .sbb, .mr, &.{ .rm32, .r32 }, &.{ 0x19 }, 0, .none },
601 .{ .sbb, .mr, .rm64, .r64, .none, .none, &.{ 0x19 }, 0, .long },604 .{ .sbb, .mr, &.{ .rm64, .r64 }, &.{ 0x19 }, 0, .long },
602 .{ .sbb, .rm, .r8, .rm8, .none, .none, &.{ 0x1a }, 0, .none },605 .{ .sbb, .rm, &.{ .r8, .rm8 }, &.{ 0x1a }, 0, .none },
603 .{ .sbb, .rm, .r8, .rm8, .none, .none, &.{ 0x1a }, 0, .rex },606 .{ .sbb, .rm, &.{ .r8, .rm8 }, &.{ 0x1a }, 0, .rex },
604 .{ .sbb, .rm, .r16, .rm16, .none, .none, &.{ 0x1b }, 0, .none },607 .{ .sbb, .rm, &.{ .r16, .rm16 }, &.{ 0x1b }, 0, .none },
605 .{ .sbb, .rm, .r32, .rm32, .none, .none, &.{ 0x1b }, 0, .none },608 .{ .sbb, .rm, &.{ .r32, .rm32 }, &.{ 0x1b }, 0, .none },
606 .{ .sbb, .rm, .r64, .rm64, .none, .none, &.{ 0x1b }, 0, .long },609 .{ .sbb, .rm, &.{ .r64, .rm64 }, &.{ 0x1b }, 0, .long },
607610
608 .{ .scas, .np, .m8, .none, .none, .none, &.{ 0xae }, 0, .none },611 .{ .scas, .np, &.{ .m8 }, &.{ 0xae }, 0, .none },
609 .{ .scas, .np, .m16, .none, .none, .none, &.{ 0xaf }, 0, .none },612 .{ .scas, .np, &.{ .m16 }, &.{ 0xaf }, 0, .none },
610 .{ .scas, .np, .m32, .none, .none, .none, &.{ 0xaf }, 0, .none },613 .{ .scas, .np, &.{ .m32 }, &.{ 0xaf }, 0, .none },
611 .{ .scas, .np, .m64, .none, .none, .none, &.{ 0xaf }, 0, .long },614 .{ .scas, .np, &.{ .m64 }, &.{ 0xaf }, 0, .long },
612 .{ .scasb, .np, .none, .none, .none, .none, &.{ 0xae }, 0, .none },615
613 .{ .scasw, .np, .none, .none, .none, .none, &.{ 0xaf }, 0, .short },616 .{ .scasb, .np, &.{}, &.{ 0xae }, 0, .none },
614 .{ .scasd, .np, .none, .none, .none, .none, &.{ 0xaf }, 0, .none },617 .{ .scasw, .np, &.{}, &.{ 0xaf }, 0, .short },
615 .{ .scasq, .np, .none, .none, .none, .none, &.{ 0xaf }, 0, .long },618 .{ .scasd, .np, &.{}, &.{ 0xaf }, 0, .none },
616619 .{ .scasq, .np, &.{}, &.{ 0xaf }, 0, .long },
617 .{ .seta, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x97 }, 0, .none },620
618 .{ .seta, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x97 }, 0, .rex },621 .{ .seta, .m, &.{ .rm8 }, &.{ 0x0f, 0x97 }, 0, .none },
619 .{ .setae, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x93 }, 0, .none },622 .{ .seta, .m, &.{ .rm8 }, &.{ 0x0f, 0x97 }, 0, .rex },
620 .{ .setae, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x93 }, 0, .rex },623 .{ .setae, .m, &.{ .rm8 }, &.{ 0x0f, 0x93 }, 0, .none },
621 .{ .setb, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x92 }, 0, .none },624 .{ .setae, .m, &.{ .rm8 }, &.{ 0x0f, 0x93 }, 0, .rex },
622 .{ .setb, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x92 }, 0, .rex },625 .{ .setb, .m, &.{ .rm8 }, &.{ 0x0f, 0x92 }, 0, .none },
623 .{ .setbe, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x96 }, 0, .none },626 .{ .setb, .m, &.{ .rm8 }, &.{ 0x0f, 0x92 }, 0, .rex },
624 .{ .setbe, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x96 }, 0, .rex },627 .{ .setbe, .m, &.{ .rm8 }, &.{ 0x0f, 0x96 }, 0, .none },
625 .{ .setc, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x92 }, 0, .none },628 .{ .setbe, .m, &.{ .rm8 }, &.{ 0x0f, 0x96 }, 0, .rex },
626 .{ .setc, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x92 }, 0, .rex },629 .{ .setc, .m, &.{ .rm8 }, &.{ 0x0f, 0x92 }, 0, .none },
627 .{ .sete, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x94 }, 0, .none },630 .{ .setc, .m, &.{ .rm8 }, &.{ 0x0f, 0x92 }, 0, .rex },
628 .{ .sete, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x94 }, 0, .rex },631 .{ .sete, .m, &.{ .rm8 }, &.{ 0x0f, 0x94 }, 0, .none },
629 .{ .setg, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9f }, 0, .none },632 .{ .sete, .m, &.{ .rm8 }, &.{ 0x0f, 0x94 }, 0, .rex },
630 .{ .setg, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9f }, 0, .rex },633 .{ .setg, .m, &.{ .rm8 }, &.{ 0x0f, 0x9f }, 0, .none },
631 .{ .setge, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9d }, 0, .none },634 .{ .setg, .m, &.{ .rm8 }, &.{ 0x0f, 0x9f }, 0, .rex },
632 .{ .setge, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9d }, 0, .rex },635 .{ .setge, .m, &.{ .rm8 }, &.{ 0x0f, 0x9d }, 0, .none },
633 .{ .setl, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9c }, 0, .none },636 .{ .setge, .m, &.{ .rm8 }, &.{ 0x0f, 0x9d }, 0, .rex },
634 .{ .setl, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9c }, 0, .rex },637 .{ .setl, .m, &.{ .rm8 }, &.{ 0x0f, 0x9c }, 0, .none },
635 .{ .setle, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9e }, 0, .none },638 .{ .setl, .m, &.{ .rm8 }, &.{ 0x0f, 0x9c }, 0, .rex },
636 .{ .setle, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9e }, 0, .rex },639 .{ .setle, .m, &.{ .rm8 }, &.{ 0x0f, 0x9e }, 0, .none },
637 .{ .setna, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x96 }, 0, .none },640 .{ .setle, .m, &.{ .rm8 }, &.{ 0x0f, 0x9e }, 0, .rex },
638 .{ .setna, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x96 }, 0, .rex },641 .{ .setna, .m, &.{ .rm8 }, &.{ 0x0f, 0x96 }, 0, .none },
639 .{ .setnae, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x92 }, 0, .none },642 .{ .setna, .m, &.{ .rm8 }, &.{ 0x0f, 0x96 }, 0, .rex },
640 .{ .setnae, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x92 }, 0, .rex },643 .{ .setnae, .m, &.{ .rm8 }, &.{ 0x0f, 0x92 }, 0, .none },
641 .{ .setnb, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x93 }, 0, .none },644 .{ .setnae, .m, &.{ .rm8 }, &.{ 0x0f, 0x92 }, 0, .rex },
642 .{ .setnb, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x93 }, 0, .rex },645 .{ .setnb, .m, &.{ .rm8 }, &.{ 0x0f, 0x93 }, 0, .none },
643 .{ .setnbe, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x97 }, 0, .none },646 .{ .setnb, .m, &.{ .rm8 }, &.{ 0x0f, 0x93 }, 0, .rex },
644 .{ .setnbe, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x97 }, 0, .rex },647 .{ .setnbe, .m, &.{ .rm8 }, &.{ 0x0f, 0x97 }, 0, .none },
645 .{ .setnc, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x93 }, 0, .none },648 .{ .setnbe, .m, &.{ .rm8 }, &.{ 0x0f, 0x97 }, 0, .rex },
646 .{ .setnc, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x93 }, 0, .rex },649 .{ .setnc, .m, &.{ .rm8 }, &.{ 0x0f, 0x93 }, 0, .none },
647 .{ .setne, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x95 }, 0, .none },650 .{ .setnc, .m, &.{ .rm8 }, &.{ 0x0f, 0x93 }, 0, .rex },
648 .{ .setne, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x95 }, 0, .rex },651 .{ .setne, .m, &.{ .rm8 }, &.{ 0x0f, 0x95 }, 0, .none },
649 .{ .setng, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9e }, 0, .none },652 .{ .setne, .m, &.{ .rm8 }, &.{ 0x0f, 0x95 }, 0, .rex },
650 .{ .setng, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9e }, 0, .rex },653 .{ .setng, .m, &.{ .rm8 }, &.{ 0x0f, 0x9e }, 0, .none },
651 .{ .setnge, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9c }, 0, .none },654 .{ .setng, .m, &.{ .rm8 }, &.{ 0x0f, 0x9e }, 0, .rex },
652 .{ .setnge, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9c }, 0, .rex },655 .{ .setnge, .m, &.{ .rm8 }, &.{ 0x0f, 0x9c }, 0, .none },
653 .{ .setnl, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9d }, 0, .none },656 .{ .setnge, .m, &.{ .rm8 }, &.{ 0x0f, 0x9c }, 0, .rex },
654 .{ .setnl, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9d }, 0, .rex },657 .{ .setnl, .m, &.{ .rm8 }, &.{ 0x0f, 0x9d }, 0, .none },
655 .{ .setnle, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9f }, 0, .none },658 .{ .setnl, .m, &.{ .rm8 }, &.{ 0x0f, 0x9d }, 0, .rex },
656 .{ .setnle, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9f }, 0, .rex },659 .{ .setnle, .m, &.{ .rm8 }, &.{ 0x0f, 0x9f }, 0, .none },
657 .{ .setno, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x91 }, 0, .none },660 .{ .setnle, .m, &.{ .rm8 }, &.{ 0x0f, 0x9f }, 0, .rex },
658 .{ .setno, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x91 }, 0, .rex },661 .{ .setno, .m, &.{ .rm8 }, &.{ 0x0f, 0x91 }, 0, .none },
659 .{ .setnp, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9b }, 0, .none },662 .{ .setno, .m, &.{ .rm8 }, &.{ 0x0f, 0x91 }, 0, .rex },
660 .{ .setnp, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9b }, 0, .rex },663 .{ .setnp, .m, &.{ .rm8 }, &.{ 0x0f, 0x9b }, 0, .none },
661 .{ .setns, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x99 }, 0, .none },664 .{ .setnp, .m, &.{ .rm8 }, &.{ 0x0f, 0x9b }, 0, .rex },
662 .{ .setns, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x99 }, 0, .rex },665 .{ .setns, .m, &.{ .rm8 }, &.{ 0x0f, 0x99 }, 0, .none },
663 .{ .setnz, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x95 }, 0, .none },666 .{ .setns, .m, &.{ .rm8 }, &.{ 0x0f, 0x99 }, 0, .rex },
664 .{ .setnz, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x95 }, 0, .rex },667 .{ .setnz, .m, &.{ .rm8 }, &.{ 0x0f, 0x95 }, 0, .none },
665 .{ .seto, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x90 }, 0, .none },668 .{ .setnz, .m, &.{ .rm8 }, &.{ 0x0f, 0x95 }, 0, .rex },
666 .{ .seto, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x90 }, 0, .rex },669 .{ .seto, .m, &.{ .rm8 }, &.{ 0x0f, 0x90 }, 0, .none },
667 .{ .setp, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9a }, 0, .none },670 .{ .seto, .m, &.{ .rm8 }, &.{ 0x0f, 0x90 }, 0, .rex },
668 .{ .setp, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9a }, 0, .rex },671 .{ .setp, .m, &.{ .rm8 }, &.{ 0x0f, 0x9a }, 0, .none },
669 .{ .setpe, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9a }, 0, .none },672 .{ .setp, .m, &.{ .rm8 }, &.{ 0x0f, 0x9a }, 0, .rex },
670 .{ .setpe, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9a }, 0, .rex },673 .{ .setpe, .m, &.{ .rm8 }, &.{ 0x0f, 0x9a }, 0, .none },
671 .{ .setpo, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9b }, 0, .none },674 .{ .setpe, .m, &.{ .rm8 }, &.{ 0x0f, 0x9a }, 0, .rex },
672 .{ .setpo, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x9b }, 0, .rex },675 .{ .setpo, .m, &.{ .rm8 }, &.{ 0x0f, 0x9b }, 0, .none },
673 .{ .sets, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x98 }, 0, .none },676 .{ .setpo, .m, &.{ .rm8 }, &.{ 0x0f, 0x9b }, 0, .rex },
674 .{ .sets, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x98 }, 0, .rex },677 .{ .sets, .m, &.{ .rm8 }, &.{ 0x0f, 0x98 }, 0, .none },
675 .{ .setz, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x94 }, 0, .none },678 .{ .sets, .m, &.{ .rm8 }, &.{ 0x0f, 0x98 }, 0, .rex },
676 .{ .setz, .m, .rm8, .none, .none, .none, &.{ 0x0f, 0x94 }, 0, .rex },679 .{ .setz, .m, &.{ .rm8 }, &.{ 0x0f, 0x94 }, 0, .none },
677680 .{ .setz, .m, &.{ .rm8 }, &.{ 0x0f, 0x94 }, 0, .rex },
678 .{ .sfence, .np, .none, .none, .none, .none, &.{ 0x0f, 0xae, 0xf8 }, 0, .none },681
679682 .{ .sfence, .np, &.{}, &.{ 0x0f, 0xae, 0xf8 }, 0, .none },
680 .{ .shl, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 4, .none },683
681 .{ .shl, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 4, .rex },684 .{ .shl, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 4, .none },
682 .{ .shl, .m1, .rm16, .unity, .none, .none, &.{ 0xd1 }, 4, .none },685 .{ .shl, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 4, .rex },
683 .{ .shl, .m1, .rm32, .unity, .none, .none, &.{ 0xd1 }, 4, .none },686 .{ .shl, .m1, &.{ .rm16, .unity }, &.{ 0xd1 }, 4, .none },
684 .{ .shl, .m1, .rm64, .unity, .none, .none, &.{ 0xd1 }, 4, .long },687 .{ .shl, .m1, &.{ .rm32, .unity }, &.{ 0xd1 }, 4, .none },
685 .{ .shl, .mc, .rm8, .cl, .none, .none, &.{ 0xd2 }, 4, .none },688 .{ .shl, .m1, &.{ .rm64, .unity }, &.{ 0xd1 }, 4, .long },
686 .{ .shl, .mc, .rm8, .cl, .none, .none, &.{ 0xd2 }, 4, .rex },689 .{ .shl, .mc, &.{ .rm8, .cl }, &.{ 0xd2 }, 4, .none },
687 .{ .shl, .mc, .rm16, .cl, .none, .none, &.{ 0xd3 }, 4, .none },690 .{ .shl, .mc, &.{ .rm8, .cl }, &.{ 0xd2 }, 4, .rex },
688 .{ .shl, .mc, .rm32, .cl, .none, .none, &.{ 0xd3 }, 4, .none },691 .{ .shl, .mc, &.{ .rm16, .cl }, &.{ 0xd3 }, 4, .none },
689 .{ .shl, .mc, .rm64, .cl, .none, .none, &.{ 0xd3 }, 4, .long },692 .{ .shl, .mc, &.{ .rm32, .cl }, &.{ 0xd3 }, 4, .none },
690 .{ .shl, .mi, .rm8, .imm8, .none, .none, &.{ 0xc0 }, 4, .none },693 .{ .shl, .mc, &.{ .rm64, .cl }, &.{ 0xd3 }, 4, .long },
691 .{ .shl, .mi, .rm8, .imm8, .none, .none, &.{ 0xc0 }, 4, .rex },694 .{ .shl, .mi, &.{ .rm8, .imm8 }, &.{ 0xc0 }, 4, .none },
692 .{ .shl, .mi, .rm16, .imm8, .none, .none, &.{ 0xc1 }, 4, .none },695 .{ .shl, .mi, &.{ .rm8, .imm8 }, &.{ 0xc0 }, 4, .rex },
693 .{ .shl, .mi, .rm32, .imm8, .none, .none, &.{ 0xc1 }, 4, .none },696 .{ .shl, .mi, &.{ .rm16, .imm8 }, &.{ 0xc1 }, 4, .none },
694 .{ .shl, .mi, .rm64, .imm8, .none, .none, &.{ 0xc1 }, 4, .long },697 .{ .shl, .mi, &.{ .rm32, .imm8 }, &.{ 0xc1 }, 4, .none },
695698 .{ .shl, .mi, &.{ .rm64, .imm8 }, &.{ 0xc1 }, 4, .long },
696 .{ .shld, .mri, .rm16, .r16, .imm8, .none, &.{ 0x0f, 0xa4 }, 0, .none },699
697 .{ .shld, .mrc, .rm16, .r16, .cl, .none, &.{ 0x0f, 0xa5 }, 0, .none },700 .{ .shld, .mri, &.{ .rm16, .r16, .imm8 }, &.{ 0x0f, 0xa4 }, 0, .none },
698 .{ .shld, .mri, .rm32, .r32, .imm8, .none, &.{ 0x0f, 0xa4 }, 0, .none },701 .{ .shld, .mrc, &.{ .rm16, .r16, .cl }, &.{ 0x0f, 0xa5 }, 0, .none },
699 .{ .shld, .mri, .rm64, .r64, .imm8, .none, &.{ 0x0f, 0xa4 }, 0, .long },702 .{ .shld, .mri, &.{ .rm32, .r32, .imm8 }, &.{ 0x0f, 0xa4 }, 0, .none },
700 .{ .shld, .mrc, .rm32, .r32, .cl, .none, &.{ 0x0f, 0xa5 }, 0, .none },703 .{ .shld, .mri, &.{ .rm64, .r64, .imm8 }, &.{ 0x0f, 0xa4 }, 0, .long },
701 .{ .shld, .mrc, .rm64, .r64, .cl, .none, &.{ 0x0f, 0xa5 }, 0, .long },704 .{ .shld, .mrc, &.{ .rm32, .r32, .cl }, &.{ 0x0f, 0xa5 }, 0, .none },
702705 .{ .shld, .mrc, &.{ .rm64, .r64, .cl }, &.{ 0x0f, 0xa5 }, 0, .long },
703 .{ .shr, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 5, .none },706
704 .{ .shr, .m1, .rm8, .unity, .none, .none, &.{ 0xd0 }, 5, .rex },707 .{ .shr, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 5, .none },
705 .{ .shr, .m1, .rm16, .unity, .none, .none, &.{ 0xd1 }, 5, .none },708 .{ .shr, .m1, &.{ .rm8, .unity }, &.{ 0xd0 }, 5, .rex },
706 .{ .shr, .m1, .rm32, .unity, .none, .none, &.{ 0xd1 }, 5, .none },709 .{ .shr, .m1, &.{ .rm16, .unity }, &.{ 0xd1 }, 5, .none },
707 .{ .shr, .m1, .rm64, .unity, .none, .none, &.{ 0xd1 }, 5, .long },710 .{ .shr, .m1, &.{ .rm32, .unity }, &.{ 0xd1 }, 5, .none },
708 .{ .shr, .mc, .rm8, .cl, .none, .none, &.{ 0xd2 }, 5, .none },711 .{ .shr, .m1, &.{ .rm64, .unity }, &.{ 0xd1 }, 5, .long },
709 .{ .shr, .mc, .rm8, .cl, .none, .none, &.{ 0xd2 }, 5, .rex },712 .{ .shr, .mc, &.{ .rm8, .cl }, &.{ 0xd2 }, 5, .none },
710 .{ .shr, .mc, .rm16, .cl, .none, .none, &.{ 0xd3 }, 5, .none },713 .{ .shr, .mc, &.{ .rm8, .cl }, &.{ 0xd2 }, 5, .rex },
711 .{ .shr, .mc, .rm32, .cl, .none, .none, &.{ 0xd3 }, 5, .none },714 .{ .shr, .mc, &.{ .rm16, .cl }, &.{ 0xd3 }, 5, .none },
712 .{ .shr, .mc, .rm64, .cl, .none, .none, &.{ 0xd3 }, 5, .long },715 .{ .shr, .mc, &.{ .rm32, .cl }, &.{ 0xd3 }, 5, .none },
713 .{ .shr, .mi, .rm8, .imm8, .none, .none, &.{ 0xc0 }, 5, .none },716 .{ .shr, .mc, &.{ .rm64, .cl }, &.{ 0xd3 }, 5, .long },
714 .{ .shr, .mi, .rm8, .imm8, .none, .none, &.{ 0xc0 }, 5, .rex },717 .{ .shr, .mi, &.{ .rm8, .imm8 }, &.{ 0xc0 }, 5, .none },
715 .{ .shr, .mi, .rm16, .imm8, .none, .none, &.{ 0xc1 }, 5, .none },718 .{ .shr, .mi, &.{ .rm8, .imm8 }, &.{ 0xc0 }, 5, .rex },
716 .{ .shr, .mi, .rm32, .imm8, .none, .none, &.{ 0xc1 }, 5, .none },719 .{ .shr, .mi, &.{ .rm16, .imm8 }, &.{ 0xc1 }, 5, .none },
717 .{ .shr, .mi, .rm64, .imm8, .none, .none, &.{ 0xc1 }, 5, .long },720 .{ .shr, .mi, &.{ .rm32, .imm8 }, &.{ 0xc1 }, 5, .none },
718721 .{ .shr, .mi, &.{ .rm64, .imm8 }, &.{ 0xc1 }, 5, .long },
719 .{ .shrd, .mri, .rm16, .r16, .imm8, .none, &.{ 0x0f, 0xac }, 0, .none },722
720 .{ .shrd, .mrc, .rm16, .r16, .cl, .none, &.{ 0x0f, 0xad }, 0, .none },723 .{ .shrd, .mri, &.{ .rm16, .r16, .imm8 }, &.{ 0x0f, 0xac }, 0, .none },
721 .{ .shrd, .mri, .rm32, .r32, .imm8, .none, &.{ 0x0f, 0xac }, 0, .none },724 .{ .shrd, .mrc, &.{ .rm16, .r16, .cl }, &.{ 0x0f, 0xad }, 0, .none },
722 .{ .shrd, .mri, .rm64, .r64, .imm8, .none, &.{ 0x0f, 0xac }, 0, .long },725 .{ .shrd, .mri, &.{ .rm32, .r32, .imm8 }, &.{ 0x0f, 0xac }, 0, .none },
723 .{ .shrd, .mrc, .rm32, .r32, .cl, .none, &.{ 0x0f, 0xad }, 0, .none },726 .{ .shrd, .mri, &.{ .rm64, .r64, .imm8 }, &.{ 0x0f, 0xac }, 0, .long },
724 .{ .shrd, .mrc, .rm64, .r64, .cl, .none, &.{ 0x0f, 0xad }, 0, .long },727 .{ .shrd, .mrc, &.{ .rm32, .r32, .cl }, &.{ 0x0f, 0xad }, 0, .none },
725728 .{ .shrd, .mrc, &.{ .rm64, .r64, .cl }, &.{ 0x0f, 0xad }, 0, .long },
726 .{ .stos, .np, .m8, .none, .none, .none, &.{ 0xaa }, 0, .none },729
727 .{ .stos, .np, .m16, .none, .none, .none, &.{ 0xab }, 0, .none },730 .{ .stos, .np, &.{ .m8 }, &.{ 0xaa }, 0, .none },
728 .{ .stos, .np, .m32, .none, .none, .none, &.{ 0xab }, 0, .none },731 .{ .stos, .np, &.{ .m16 }, &.{ 0xab }, 0, .none },
729 .{ .stos, .np, .m64, .none, .none, .none, &.{ 0xab }, 0, .long },732 .{ .stos, .np, &.{ .m32 }, &.{ 0xab }, 0, .none },
730 .{ .stosb, .np, .none, .none, .none, .none, &.{ 0xaa }, 0, .none },733 .{ .stos, .np, &.{ .m64 }, &.{ 0xab }, 0, .long },
731 .{ .stosw, .np, .none, .none, .none, .none, &.{ 0xab }, 0, .short },734
732 .{ .stosd, .np, .none, .none, .none, .none, &.{ 0xab }, 0, .none },735 .{ .stosb, .np, &.{}, &.{ 0xaa }, 0, .none },
733 .{ .stosq, .np, .none, .none, .none, .none, &.{ 0xab }, 0, .long },736 .{ .stosw, .np, &.{}, &.{ 0xab }, 0, .short },
734737 .{ .stosd, .np, &.{}, &.{ 0xab }, 0, .none },
735 .{ .sub, .zi, .al, .imm8, .none, .none, &.{ 0x2c }, 0, .none },738 .{ .stosq, .np, &.{}, &.{ 0xab }, 0, .long },
736 .{ .sub, .zi, .ax, .imm16, .none, .none, &.{ 0x2d }, 0, .none },739
737 .{ .sub, .zi, .eax, .imm32, .none, .none, &.{ 0x2d }, 0, .none },740 .{ .sub, .zi, &.{ .al, .imm8 }, &.{ 0x2c }, 0, .none },
738 .{ .sub, .zi, .rax, .imm32s, .none, .none, &.{ 0x2d }, 0, .long },741 .{ .sub, .zi, &.{ .ax, .imm16 }, &.{ 0x2d }, 0, .none },
739 .{ .sub, .mi, .rm8, .imm8, .none, .none, &.{ 0x80 }, 5, .none },742 .{ .sub, .zi, &.{ .eax, .imm32 }, &.{ 0x2d }, 0, .none },
740 .{ .sub, .mi, .rm8, .imm8, .none, .none, &.{ 0x80 }, 5, .rex },743 .{ .sub, .zi, &.{ .rax, .imm32s }, &.{ 0x2d }, 0, .long },
741 .{ .sub, .mi, .rm16, .imm16, .none, .none, &.{ 0x81 }, 5, .none },744 .{ .sub, .mi, &.{ .rm8, .imm8 }, &.{ 0x80 }, 5, .none },
742 .{ .sub, .mi, .rm32, .imm32, .none, .none, &.{ 0x81 }, 5, .none },745 .{ .sub, .mi, &.{ .rm8, .imm8 }, &.{ 0x80 }, 5, .rex },
743 .{ .sub, .mi, .rm64, .imm32s, .none, .none, &.{ 0x81 }, 5, .long },746 .{ .sub, .mi, &.{ .rm16, .imm16 }, &.{ 0x81 }, 5, .none },
744 .{ .sub, .mi, .rm16, .imm8s, .none, .none, &.{ 0x83 }, 5, .none },747 .{ .sub, .mi, &.{ .rm32, .imm32 }, &.{ 0x81 }, 5, .none },
745 .{ .sub, .mi, .rm32, .imm8s, .none, .none, &.{ 0x83 }, 5, .none },748 .{ .sub, .mi, &.{ .rm64, .imm32s }, &.{ 0x81 }, 5, .long },
746 .{ .sub, .mi, .rm64, .imm8s, .none, .none, &.{ 0x83 }, 5, .long },749 .{ .sub, .mi, &.{ .rm16, .imm8s }, &.{ 0x83 }, 5, .none },
747 .{ .sub, .mr, .rm8, .r8, .none, .none, &.{ 0x28 }, 0, .none },750 .{ .sub, .mi, &.{ .rm32, .imm8s }, &.{ 0x83 }, 5, .none },
748 .{ .sub, .mr, .rm8, .r8, .none, .none, &.{ 0x28 }, 0, .rex },751 .{ .sub, .mi, &.{ .rm64, .imm8s }, &.{ 0x83 }, 5, .long },
749 .{ .sub, .mr, .rm16, .r16, .none, .none, &.{ 0x29 }, 0, .none },752 .{ .sub, .mr, &.{ .rm8, .r8 }, &.{ 0x28 }, 0, .none },
750 .{ .sub, .mr, .rm32, .r32, .none, .none, &.{ 0x29 }, 0, .none },753 .{ .sub, .mr, &.{ .rm8, .r8 }, &.{ 0x28 }, 0, .rex },
751 .{ .sub, .mr, .rm64, .r64, .none, .none, &.{ 0x29 }, 0, .long },754 .{ .sub, .mr, &.{ .rm16, .r16 }, &.{ 0x29 }, 0, .none },
752 .{ .sub, .rm, .r8, .rm8, .none, .none, &.{ 0x2a }, 0, .none },755 .{ .sub, .mr, &.{ .rm32, .r32 }, &.{ 0x29 }, 0, .none },
753 .{ .sub, .rm, .r8, .rm8, .none, .none, &.{ 0x2a }, 0, .rex },756 .{ .sub, .mr, &.{ .rm64, .r64 }, &.{ 0x29 }, 0, .long },
754 .{ .sub, .rm, .r16, .rm16, .none, .none, &.{ 0x2b }, 0, .none },757 .{ .sub, .rm, &.{ .r8, .rm8 }, &.{ 0x2a }, 0, .none },
755 .{ .sub, .rm, .r32, .rm32, .none, .none, &.{ 0x2b }, 0, .none },758 .{ .sub, .rm, &.{ .r8, .rm8 }, &.{ 0x2a }, 0, .rex },
756 .{ .sub, .rm, .r64, .rm64, .none, .none, &.{ 0x2b }, 0, .long },759 .{ .sub, .rm, &.{ .r16, .rm16 }, &.{ 0x2b }, 0, .none },
757760 .{ .sub, .rm, &.{ .r32, .rm32 }, &.{ 0x2b }, 0, .none },
758 .{ .syscall, .np, .none, .none, .none, .none, &.{ 0x0f, 0x05 }, 0, .none }761 .{ .sub, .rm, &.{ .r64, .rm64 }, &.{ 0x2b }, 0, .long },
762
763 .{ .syscall, .np, &.{}, &.{ 0x0f, 0x05 }, 0, .none }
759,764,
760 .{ .@"test", .zi, .al, .imm8, .none, .none, &.{ 0xa8 }, 0, .none },765 .{ .@"test", .zi, &.{ .al, .imm8 }, &.{ 0xa8 }, 0, .none },
761 .{ .@"test", .zi, .ax, .imm16, .none, .none, &.{ 0xa9 }, 0, .none },766 .{ .@"test", .zi, &.{ .ax, .imm16 }, &.{ 0xa9 }, 0, .none },
762 .{ .@"test", .zi, .eax, .imm32, .none, .none, &.{ 0xa9 }, 0, .none },767 .{ .@"test", .zi, &.{ .eax, .imm32 }, &.{ 0xa9 }, 0, .none },
763 .{ .@"test", .zi, .rax, .imm32s, .none, .none, &.{ 0xa9 }, 0, .long },768 .{ .@"test", .zi, &.{ .rax, .imm32s }, &.{ 0xa9 }, 0, .long },
764 .{ .@"test", .mi, .rm8, .imm8, .none, .none, &.{ 0xf6 }, 0, .none },769 .{ .@"test", .mi, &.{ .rm8, .imm8 }, &.{ 0xf6 }, 0, .none },
765 .{ .@"test", .mi, .rm8, .imm8, .none, .none, &.{ 0xf6 }, 0, .rex },770 .{ .@"test", .mi, &.{ .rm8, .imm8 }, &.{ 0xf6 }, 0, .rex },
766 .{ .@"test", .mi, .rm16, .imm16, .none, .none, &.{ 0xf7 }, 0, .none },771 .{ .@"test", .mi, &.{ .rm16, .imm16 }, &.{ 0xf7 }, 0, .none },
767 .{ .@"test", .mi, .rm32, .imm32, .none, .none, &.{ 0xf7 }, 0, .none },772 .{ .@"test", .mi, &.{ .rm32, .imm32 }, &.{ 0xf7 }, 0, .none },
768 .{ .@"test", .mi, .rm64, .imm32s, .none, .none, &.{ 0xf7 }, 0, .long },773 .{ .@"test", .mi, &.{ .rm64, .imm32s }, &.{ 0xf7 }, 0, .long },
769 .{ .@"test", .mr, .rm8, .r8, .none, .none, &.{ 0x84 }, 0, .none },774 .{ .@"test", .mr, &.{ .rm8, .r8 }, &.{ 0x84 }, 0, .none },
770 .{ .@"test", .mr, .rm8, .r8, .none, .none, &.{ 0x84 }, 0, .rex },775 .{ .@"test", .mr, &.{ .rm8, .r8 }, &.{ 0x84 }, 0, .rex },
771 .{ .@"test", .mr, .rm16, .r16, .none, .none, &.{ 0x85 }, 0, .none },776 .{ .@"test", .mr, &.{ .rm16, .r16 }, &.{ 0x85 }, 0, .none },
772 .{ .@"test", .mr, .rm32, .r32, .none, .none, &.{ 0x85 }, 0, .none },777 .{ .@"test", .mr, &.{ .rm32, .r32 }, &.{ 0x85 }, 0, .none },
773 .{ .@"test", .mr, .rm64, .r64, .none, .none, &.{ 0x85 }, 0, .long },778 .{ .@"test", .mr, &.{ .rm64, .r64 }, &.{ 0x85 }, 0, .long },
774779
775 .{ .tzcnt, .rm, .r16, .rm16, .none, .none, &.{ 0xf3, 0x0f, 0xbc }, 0, .none },780 .{ .tzcnt, .rm, &.{ .r16, .rm16 }, &.{ 0xf3, 0x0f, 0xbc }, 0, .none },
776 .{ .tzcnt, .rm, .r32, .rm32, .none, .none, &.{ 0xf3, 0x0f, 0xbc }, 0, .none },781 .{ .tzcnt, .rm, &.{ .r32, .rm32 }, &.{ 0xf3, 0x0f, 0xbc }, 0, .none },
777 .{ .tzcnt, .rm, .r64, .rm64, .none, .none, &.{ 0xf3, 0x0f, 0xbc }, 0, .long },782 .{ .tzcnt, .rm, &.{ .r64, .rm64 }, &.{ 0xf3, 0x0f, 0xbc }, 0, .long },
778783
779 .{ .ud2, .np, .none, .none, .none, .none, &.{ 0x0f, 0x0b }, 0, .none },784 .{ .ud2, .np, &.{}, &.{ 0x0f, 0x0b }, 0, .none },
780785
781 .{ .xadd, .mr, .rm8, .r8, .none, .none, &.{ 0x0f, 0xc0 }, 0, .none },786 .{ .xadd, .mr, &.{ .rm8, .r8 }, &.{ 0x0f, 0xc0 }, 0, .none },
782 .{ .xadd, .mr, .rm8, .r8, .none, .none, &.{ 0x0f, 0xc0 }, 0, .rex },787 .{ .xadd, .mr, &.{ .rm8, .r8 }, &.{ 0x0f, 0xc0 }, 0, .rex },
783 .{ .xadd, .mr, .rm16, .r16, .none, .none, &.{ 0x0f, 0xc1 }, 0, .none },788 .{ .xadd, .mr, &.{ .rm16, .r16 }, &.{ 0x0f, 0xc1 }, 0, .none },
784 .{ .xadd, .mr, .rm32, .r32, .none, .none, &.{ 0x0f, 0xc1 }, 0, .none },789 .{ .xadd, .mr, &.{ .rm32, .r32 }, &.{ 0x0f, 0xc1 }, 0, .none },
785 .{ .xadd, .mr, .rm64, .r64, .none, .none, &.{ 0x0f, 0xc1 }, 0, .long },790 .{ .xadd, .mr, &.{ .rm64, .r64 }, &.{ 0x0f, 0xc1 }, 0, .long },
786791
787 .{ .xchg, .o, .ax, .r16, .none, .none, &.{ 0x90 }, 0, .none },792 .{ .xchg, .o, &.{ .ax, .r16 }, &.{ 0x90 }, 0, .none },
788 .{ .xchg, .o, .r16, .ax, .none, .none, &.{ 0x90 }, 0, .none },793 .{ .xchg, .o, &.{ .r16, .ax }, &.{ 0x90 }, 0, .none },
789 .{ .xchg, .o, .eax, .r32, .none, .none, &.{ 0x90 }, 0, .none },794 .{ .xchg, .o, &.{ .eax, .r32 }, &.{ 0x90 }, 0, .none },
790 .{ .xchg, .o, .rax, .r64, .none, .none, &.{ 0x90 }, 0, .long },795 .{ .xchg, .o, &.{ .rax, .r64 }, &.{ 0x90 }, 0, .long },
791 .{ .xchg, .o, .r32, .eax, .none, .none, &.{ 0x90 }, 0, .none },796 .{ .xchg, .o, &.{ .r32, .eax }, &.{ 0x90 }, 0, .none },
792 .{ .xchg, .o, .r64, .rax, .none, .none, &.{ 0x90 }, 0, .long },797 .{ .xchg, .o, &.{ .r64, .rax }, &.{ 0x90 }, 0, .long },
793 .{ .xchg, .mr, .rm8, .r8, .none, .none, &.{ 0x86 }, 0, .none },798 .{ .xchg, .mr, &.{ .rm8, .r8 }, &.{ 0x86 }, 0, .none },
794 .{ .xchg, .mr, .rm8, .r8, .none, .none, &.{ 0x86 }, 0, .rex },799 .{ .xchg, .mr, &.{ .rm8, .r8 }, &.{ 0x86 }, 0, .rex },
795 .{ .xchg, .rm, .r8, .rm8, .none, .none, &.{ 0x86 }, 0, .none },800 .{ .xchg, .rm, &.{ .r8, .rm8 }, &.{ 0x86 }, 0, .none },
796 .{ .xchg, .rm, .r8, .rm8, .none, .none, &.{ 0x86 }, 0, .rex },801 .{ .xchg, .rm, &.{ .r8, .rm8 }, &.{ 0x86 }, 0, .rex },
797 .{ .xchg, .mr, .rm16, .r16, .none, .none, &.{ 0x87 }, 0, .none },802 .{ .xchg, .mr, &.{ .rm16, .r16 }, &.{ 0x87 }, 0, .none },
798 .{ .xchg, .rm, .r16, .rm16, .none, .none, &.{ 0x87 }, 0, .none },803 .{ .xchg, .rm, &.{ .r16, .rm16 }, &.{ 0x87 }, 0, .none },
799 .{ .xchg, .mr, .rm32, .r32, .none, .none, &.{ 0x87 }, 0, .none },804 .{ .xchg, .mr, &.{ .rm32, .r32 }, &.{ 0x87 }, 0, .none },
800 .{ .xchg, .mr, .rm64, .r64, .none, .none, &.{ 0x87 }, 0, .long },805 .{ .xchg, .mr, &.{ .rm64, .r64 }, &.{ 0x87 }, 0, .long },
801 .{ .xchg, .rm, .r32, .rm32, .none, .none, &.{ 0x87 }, 0, .none },806 .{ .xchg, .rm, &.{ .r32, .rm32 }, &.{ 0x87 }, 0, .none },
802 .{ .xchg, .rm, .r64, .rm64, .none, .none, &.{ 0x87 }, 0, .long },807 .{ .xchg, .rm, &.{ .r64, .rm64 }, &.{ 0x87 }, 0, .long },
803808
804 .{ .xor, .zi, .al, .imm8, .none, .none, &.{ 0x34 }, 0, .none },809 .{ .xor, .zi, &.{ .al, .imm8 }, &.{ 0x34 }, 0, .none },
805 .{ .xor, .zi, .ax, .imm16, .none, .none, &.{ 0x35 }, 0, .none },810 .{ .xor, .zi, &.{ .ax, .imm16 }, &.{ 0x35 }, 0, .none },
806 .{ .xor, .zi, .eax, .imm32, .none, .none, &.{ 0x35 }, 0, .none },811 .{ .xor, .zi, &.{ .eax, .imm32 }, &.{ 0x35 }, 0, .none },
807 .{ .xor, .zi, .rax, .imm32s, .none, .none, &.{ 0x35 }, 0, .long },812 .{ .xor, .zi, &.{ .rax, .imm32s }, &.{ 0x35 }, 0, .long },
808 .{ .xor, .mi, .rm8, .imm8, .none, .none, &.{ 0x80 }, 6, .none },813 .{ .xor, .mi, &.{ .rm8, .imm8 }, &.{ 0x80 }, 6, .none },
809 .{ .xor, .mi, .rm8, .imm8, .none, .none, &.{ 0x80 }, 6, .rex },814 .{ .xor, .mi, &.{ .rm8, .imm8 }, &.{ 0x80 }, 6, .rex },
810 .{ .xor, .mi, .rm16, .imm16, .none, .none, &.{ 0x81 }, 6, .none },815 .{ .xor, .mi, &.{ .rm16, .imm16 }, &.{ 0x81 }, 6, .none },
811 .{ .xor, .mi, .rm32, .imm32, .none, .none, &.{ 0x81 }, 6, .none },816 .{ .xor, .mi, &.{ .rm32, .imm32 }, &.{ 0x81 }, 6, .none },
812 .{ .xor, .mi, .rm64, .imm32s, .none, .none, &.{ 0x81 }, 6, .long },817 .{ .xor, .mi, &.{ .rm64, .imm32s }, &.{ 0x81 }, 6, .long },
813 .{ .xor, .mi, .rm16, .imm8s, .none, .none, &.{ 0x83 }, 6, .none },818 .{ .xor, .mi, &.{ .rm16, .imm8s }, &.{ 0x83 }, 6, .none },
814 .{ .xor, .mi, .rm32, .imm8s, .none, .none, &.{ 0x83 }, 6, .none },819 .{ .xor, .mi, &.{ .rm32, .imm8s }, &.{ 0x83 }, 6, .none },
815 .{ .xor, .mi, .rm64, .imm8s, .none, .none, &.{ 0x83 }, 6, .long },820 .{ .xor, .mi, &.{ .rm64, .imm8s }, &.{ 0x83 }, 6, .long },
816 .{ .xor, .mr, .rm8, .r8, .none, .none, &.{ 0x30 }, 0, .none },821 .{ .xor, .mr, &.{ .rm8, .r8 }, &.{ 0x30 }, 0, .none },
817 .{ .xor, .mr, .rm8, .r8, .none, .none, &.{ 0x30 }, 0, .rex },822 .{ .xor, .mr, &.{ .rm8, .r8 }, &.{ 0x30 }, 0, .rex },
818 .{ .xor, .mr, .rm16, .r16, .none, .none, &.{ 0x31 }, 0, .none },823 .{ .xor, .mr, &.{ .rm16, .r16 }, &.{ 0x31 }, 0, .none },
819 .{ .xor, .mr, .rm32, .r32, .none, .none, &.{ 0x31 }, 0, .none },824 .{ .xor, .mr, &.{ .rm32, .r32 }, &.{ 0x31 }, 0, .none },
820 .{ .xor, .mr, .rm64, .r64, .none, .none, &.{ 0x31 }, 0, .long },825 .{ .xor, .mr, &.{ .rm64, .r64 }, &.{ 0x31 }, 0, .long },
821 .{ .xor, .rm, .r8, .rm8, .none, .none, &.{ 0x32 }, 0, .none },826 .{ .xor, .rm, &.{ .r8, .rm8 }, &.{ 0x32 }, 0, .none },
822 .{ .xor, .rm, .r8, .rm8, .none, .none, &.{ 0x32 }, 0, .rex },827 .{ .xor, .rm, &.{ .r8, .rm8 }, &.{ 0x32 }, 0, .rex },
823 .{ .xor, .rm, .r16, .rm16, .none, .none, &.{ 0x33 }, 0, .none },828 .{ .xor, .rm, &.{ .r16, .rm16 }, &.{ 0x33 }, 0, .none },
824 .{ .xor, .rm, .r32, .rm32, .none, .none, &.{ 0x33 }, 0, .none },829 .{ .xor, .rm, &.{ .r32, .rm32 }, &.{ 0x33 }, 0, .none },
825 .{ .xor, .rm, .r64, .rm64, .none, .none, &.{ 0x33 }, 0, .long },830 .{ .xor, .rm, &.{ .r64, .rm64 }, &.{ 0x33 }, 0, .long },
826831
827 // SSE832 // SSE
828 .{ .addss, .rm, .xmm, .xmm_m32, .none, .none, &.{ 0xf3, 0x0f, 0x58 }, 0, .sse },833 .{ .addss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x58 }, 0, .sse },
829834
830 .{ .cmpss, .rmi, .xmm, .xmm_m32, .imm8, .none, &.{ 0xf3, 0x0f, 0xc2 }, 0, .sse },835 .{ .cmpss, .rmi, &.{ .xmm, .xmm_m32, .imm8 }, &.{ 0xf3, 0x0f, 0xc2 }, 0, .sse },
831836
832 .{ .divss, .rm, .xmm, .xmm_m32, .none, .none, &.{ 0xf3, 0x0f, 0x5e }, 0, .sse },837 .{ .divss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5e }, 0, .sse },
833838
834 .{ .maxss, .rm, .xmm, .xmm_m32, .none, .none, &.{ 0xf3, 0x0f, 0x5f }, 0, .sse },839 .{ .maxss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5f }, 0, .sse },
835840
836 .{ .minss, .rm, .xmm, .xmm_m32, .none, .none, &.{ 0xf3, 0x0f, 0x5d }, 0, .sse },841 .{ .minss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5d }, 0, .sse },
837842
838 .{ .movss, .rm, .xmm, .xmm_m32, .none, .none, &.{ 0xf3, 0x0f, 0x10 }, 0, .sse },843 .{ .movss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x10 }, 0, .sse },
839 .{ .movss, .mr, .xmm_m32, .xmm, .none, .none, &.{ 0xf3, 0x0f, 0x11 }, 0, .sse },844 .{ .movss, .mr, &.{ .xmm_m32, .xmm }, &.{ 0xf3, 0x0f, 0x11 }, 0, .sse },
840845
841 .{ .mulss, .rm, .xmm, .xmm_m32, .none, .none, &.{ 0xf3, 0x0f, 0x59 }, 0, .sse },846 .{ .mulss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x59 }, 0, .sse },
842847
843 .{ .subss, .rm, .xmm, .xmm_m32, .none, .none, &.{ 0xf3, 0x0f, 0x5c }, 0, .sse },848 .{ .subss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5c }, 0, .sse },
844849
845 .{ .ucomiss, .rm, .xmm, .xmm_m32, .none, .none, &.{ 0x0f, 0x2e }, 0, .sse },850 .{ .ucomiss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0x0f, 0x2e }, 0, .sse },
846851
847 // SSE2852 // SSE2
848 .{ .addsd, .rm, .xmm, .xmm_m64, .none, .none, &.{ 0xf2, 0x0f, 0x58 }, 0, .sse2 },853 .{ .addsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x58 }, 0, .sse2 },
849854
850 .{ .cmpsd, .rmi, .xmm, .xmm_m64, .imm8, .none, &.{ 0xf2, 0x0f, 0xc2 }, 0, .sse2 },855 .{ .cmpsd, .rmi, &.{ .xmm, .xmm_m64, .imm8 }, &.{ 0xf2, 0x0f, 0xc2 }, 0, .sse2 },
851856
852 .{ .divsd, .rm, .xmm, .xmm_m64, .none, .none, &.{ 0xf2, 0x0f, 0x5e }, 0, .sse2 },857 .{ .divsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x5e }, 0, .sse2 },
853858
854 .{ .maxsd, .rm, .xmm, .xmm_m64, .none, .none, &.{ 0xf2, 0x0f, 0x5f }, 0, .sse2 },859 .{ .maxsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x5f }, 0, .sse2 },
855860
856 .{ .minsd, .rm, .xmm, .xmm_m64, .none, .none, &.{ 0xf2, 0x0f, 0x5d }, 0, .sse2 },861 .{ .minsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x5d }, 0, .sse2 },
857862
858 .{ .movq, .rm, .xmm, .xmm_m64, .none, .none, &.{ 0xf3, 0x0f, 0x7e }, 0, .sse2 },863 .{ .movq, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf3, 0x0f, 0x7e }, 0, .sse2 },
859 .{ .movq, .mr, .xmm_m64, .xmm, .none, .none, &.{ 0x66, 0x0f, 0xd6 }, 0, .sse2 },864 .{ .movq, .mr, &.{ .xmm_m64, .xmm }, &.{ 0x66, 0x0f, 0xd6 }, 0, .sse2 },
860865
861 .{ .mulsd, .rm, .xmm, .xmm_m64, .none, .none, &.{ 0xf2, 0x0f, 0x59 }, 0, .sse2 },866 .{ .mulsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x59 }, 0, .sse2 },
862867
863 .{ .subsd, .rm, .xmm, .xmm_m64, .none, .none, &.{ 0xf2, 0x0f, 0x5c }, 0, .sse2 },868 .{ .subsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x5c }, 0, .sse2 },
864869
865 .{ .movsd, .rm, .xmm, .xmm_m64, .none, .none, &.{ 0xf2, 0x0f, 0x10 }, 0, .sse2 },870 .{ .movsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x10 }, 0, .sse2 },
866 .{ .movsd, .mr, .xmm_m64, .xmm, .none, .none, &.{ 0xf2, 0x0f, 0x11 }, 0, .sse2 },871 .{ .movsd, .mr, &.{ .xmm_m64, .xmm }, &.{ 0xf2, 0x0f, 0x11 }, 0, .sse2 },
867872
868 .{ .ucomisd, .rm, .xmm, .xmm_m64, .none, .none, &.{ 0x66, 0x0f, 0x2e }, 0, .sse2 },873 .{ .ucomisd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0x66, 0x0f, 0x2e }, 0, .sse2 },
869874
870 // SSE4.1875 // SSE4.1
871 .{ .roundss, .rmi, .xmm, .xmm_m32, .imm8, .none, &.{ 0x66, 0x0f, 0x3a, 0x0a }, 0, .sse4_1 },876 .{ .roundss, .rmi, &.{ .xmm, .xmm_m32, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x0a }, 0, .sse4_1 },
872 .{ .roundsd, .rmi, .xmm, .xmm_m64, .imm8, .none, &.{ 0x66, 0x0f, 0x3a, 0x0b }, 0, .sse4_1 },877 .{ .roundsd, .rmi, &.{ .xmm, .xmm_m64, .imm8 }, &.{ 0x66, 0x0f, 0x3a, 0x0b }, 0, .sse4_1 },
873};878};
874// zig fmt: on879// zig fmt: on