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