| /* |
| * x86 identifier recognition and instruction handling |
| * |
| * Copyright (C) 2002 Peter Johnson |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS'' |
| * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE |
| * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| * POSSIBILITY OF SUCH DAMAGE. |
| */ |
| #include <util.h> |
| RCSID("$IdPath$"); |
| |
| #define YASM_LIB_INTERNAL |
| #define YASM_BC_INTERNAL |
| #define YASM_EXPR_INTERNAL |
| #include <libyasm.h> |
| |
| #include "modules/arch/x86/x86arch.h" |
| |
| |
| /* Opcode modifiers. The opcode bytes are in "reverse" order because the |
| * parameters are read from the arch-specific data in LSB->MSB order. |
| * (only for asthetic reasons in the lexer code below, no practical reason). |
| */ |
| #define MOD_Op2Add (1UL<<0) /* Parameter adds to opcode byte 2 */ |
| #define MOD_Gap0 (1UL<<1) /* Eats a parameter */ |
| #define MOD_Op1Add (1UL<<2) /* Parameter adds to opcode byte 1 */ |
| #define MOD_Gap1 (1UL<<3) /* Eats a parameter */ |
| #define MOD_Op0Add (1UL<<4) /* Parameter adds to opcode byte 0 */ |
| #define MOD_SpAdd (1UL<<5) /* Parameter adds to "spare" value */ |
| #define MOD_OpSizeR (1UL<<6) /* Parameter replaces opersize */ |
| #define MOD_Imm8 (1UL<<7) /* Parameter is included as immediate byte */ |
| #define MOD_AdSizeR (1UL<<8) /* Parameter replaces addrsize (jmp only) */ |
| #define MOD_DOpS64R (1UL<<9) /* Parameter replaces default 64-bit opersize */ |
| |
| /* Modifiers that aren't actually used as modifiers. Rather, if set, bits |
| * 20-27 in the modifier are used as an index into an array. |
| * Obviously, only one of these may be set at a time. |
| */ |
| #define MOD_ExtNone (0UL<<28) /* No extended modifier */ |
| #define MOD_ExtErr (1UL<<28) /* Extended error: index into error strings */ |
| #define MOD_ExtWarn (2UL<<28) /* Extended warning: index into warning strs */ |
| #define MOD_Ext_MASK (0xFUL<<28) |
| #define MOD_ExtIndex_SHIFT 20 |
| #define MOD_ExtIndex(indx) (((unsigned long)(indx))<<MOD_ExtIndex_SHIFT) |
| #define MOD_ExtIndex_MASK (0xFFUL<<MOD_ExtIndex_SHIFT) |
| |
| /* Operand types. These are more detailed than the "general" types for all |
| * architectures, as they include the size, for instance. |
| * Bit Breakdown (from LSB to MSB): |
| * - 5 bits = general type (must be exact match, except for =3): |
| * 0 = immediate |
| * 1 = any general purpose or FPU register |
| * 2 = memory |
| * 3 = any general purpose or FPU register OR memory |
| * 4 = any MMX or XMM register |
| * 5 = any MMX or XMM register OR memory |
| * 6 = any segment register |
| * 7 = any CR register |
| * 8 = any DR register |
| * 9 = any TR register |
| * A = ST0 |
| * B = AL/AX/EAX/RAX (depending on size) |
| * C = CL/CX/ECX/RCX (depending on size) |
| * D = DL/DX/EDX/RDX (depending on size) |
| * E = CS |
| * F = DS |
| * 10 = ES |
| * 11 = FS |
| * 12 = GS |
| * 13 = SS |
| * 14 = CR4 |
| * 15 = memory offset (an EA, but with no registers allowed) |
| * [special case for MOV opcode] |
| * - 3 bits = size (user-specified, or from register size): |
| * 0 = any size acceptable/no size spec acceptable (dep. on strict) |
| * 1/2/3/4 = 8/16/32/64 bits (from user or reg size) |
| * 5/6 = 80/128 bits (from user) |
| * - 1 bit = size implicit or explicit ("strictness" of size matching on |
| * non-registers -- registers are always strictly matched): |
| * 0 = user size must exactly match size above. |
| * 1 = user size either unspecified or exactly match size above. |
| * - 3 bits = target modification. |
| * 0 = no target mod acceptable |
| * 1 = NEAR |
| * 2 = SHORT |
| * 3 = FAR |
| * 4 = TO |
| * |
| * MSBs than the above are actions: what to do with the operand if the |
| * instruction matches. Essentially describes what part of the output bytecode |
| * gets the operand. This may require conversion (e.g. a register going into |
| * an ea field). Naturally, only one of each of these may be contained in the |
| * operands of a single insn_info structure. |
| * - 4 bits = action: |
| * 0 = does nothing (operand data is discarded) |
| * 1 = operand data goes into ea field |
| * 2 = operand data goes into imm field |
| * 3 = operand data goes into sign-extended imm field |
| * 4 = operand data goes into "spare" field |
| * 5 = operand data is added to opcode byte 0 |
| * 6 = operand data is added to opcode byte 1 |
| * 7 = operand data goes into BOTH ea and spare |
| * [special case for imul opcode] |
| * 8 = relative jump (outputs a jmp instead of normal insn) |
| * 9 = operand size goes into address size (jmp only) |
| * The below describes postponed actions: actions which can't be completed at |
| * parse-time due to things like EQU and complex expressions. For these, some |
| * additional data (stored in the second byte of the opcode with a one-byte |
| * opcode) is passed to later stages of the assembler with flags set to |
| * indicate postponed actions. |
| * - 2 bits = postponed action: |
| * 0 = none |
| * 1 = shift operation with a ,1 short form (instead of imm8). |
| * 2 = large imm16/32 that can become a sign-extended imm8. |
| * 3 = can be far jump |
| */ |
| #define OPT_Imm 0x0 |
| #define OPT_Reg 0x1 |
| #define OPT_Mem 0x2 |
| #define OPT_RM 0x3 |
| #define OPT_SIMDReg 0x4 |
| #define OPT_SIMDRM 0x5 |
| #define OPT_SegReg 0x6 |
| #define OPT_CRReg 0x7 |
| #define OPT_DRReg 0x8 |
| #define OPT_TRReg 0x9 |
| #define OPT_ST0 0xA |
| #define OPT_Areg 0xB |
| #define OPT_Creg 0xC |
| #define OPT_Dreg 0xD |
| #define OPT_CS 0xE |
| #define OPT_DS 0xF |
| #define OPT_ES 0x10 |
| #define OPT_FS 0x11 |
| #define OPT_GS 0x12 |
| #define OPT_SS 0x13 |
| #define OPT_CR4 0x14 |
| #define OPT_MemOffs 0x15 |
| #define OPT_MASK 0x1F |
| |
| #define OPS_Any (0UL<<5) |
| #define OPS_8 (1UL<<5) |
| #define OPS_16 (2UL<<5) |
| #define OPS_32 (3UL<<5) |
| #define OPS_64 (4UL<<5) |
| #define OPS_80 (5UL<<5) |
| #define OPS_128 (6UL<<5) |
| #define OPS_MASK (7UL<<5) |
| #define OPS_SHIFT 5 |
| |
| #define OPS_Relaxed (1UL<<8) |
| #define OPS_RMASK (1UL<<8) |
| |
| #define OPTM_None (0UL<<9) |
| #define OPTM_Near (1UL<<9) |
| #define OPTM_Short (2UL<<9) |
| #define OPTM_Far (3UL<<9) |
| #define OPTM_To (4UL<<9) |
| #define OPTM_MASK (7UL<<9) |
| |
| #define OPA_None (0UL<<12) |
| #define OPA_EA (1UL<<12) |
| #define OPA_Imm (2UL<<12) |
| #define OPA_SImm (3UL<<12) |
| #define OPA_Spare (4UL<<12) |
| #define OPA_Op0Add (5UL<<12) |
| #define OPA_Op1Add (6UL<<12) |
| #define OPA_SpareEA (7UL<<12) |
| #define OPA_JmpRel (8UL<<12) |
| #define OPA_AdSizeR (9UL<<12) |
| #define OPA_MASK (0xFUL<<12) |
| |
| #define OPAP_None (0UL<<16) |
| #define OPAP_ShiftOp (1UL<<16) |
| #define OPAP_SImm8Avail (2UL<<16) |
| #define OPAP_JmpFar (3UL<<16) |
| #define OPAP_MASK (3UL<<16) |
| |
| typedef struct x86_insn_info { |
| /* The CPU feature flags needed to execute this instruction. This is OR'ed |
| * with arch-specific data[2]. This combined value is compared with |
| * cpu_enabled to see if all bits set here are set in cpu_enabled--if so, |
| * the instruction is available on this CPU. |
| */ |
| unsigned long cpu; |
| |
| /* Opcode modifiers for variations of instruction. As each modifier reads |
| * its parameter in LSB->MSB order from the arch-specific data[1] from the |
| * lexer data, and the LSB of the arch-specific data[1] is reserved for the |
| * count of insn_info structures in the instruction grouping, there can |
| * only be a maximum of 3 modifiers. |
| */ |
| unsigned long modifiers; |
| |
| /* Operand Size */ |
| unsigned char opersize; |
| |
| /* Default operand size in 64-bit mode (0 = 32-bit for readability). */ |
| unsigned char def_opersize_64; |
| |
| /* The length of the basic opcode */ |
| unsigned char opcode_len; |
| |
| /* The basic 1-3 byte opcode */ |
| unsigned char opcode[3]; |
| |
| /* The 3-bit "spare" value (extended opcode) for the R/M byte field */ |
| unsigned char spare; |
| |
| /* The number of operands this form of the instruction takes */ |
| unsigned char num_operands; |
| |
| /* The types of each operand, see above */ |
| unsigned long operands[3]; |
| } x86_insn_info; |
| |
| /* Define lexer arch-specific data with 0-3 modifiers. */ |
| #define DEF_INSN_DATA(group, mod, cpu) do { \ |
| data[0] = (unsigned long)group##_insn; \ |
| data[1] = ((mod)<<8) | \ |
| ((unsigned char)(sizeof(group##_insn)/sizeof(x86_insn_info))); \ |
| data[2] = cpu; \ |
| } while (0) |
| |
| #define RET_INSN(group, mod, cpu) do { \ |
| DEF_INSN_DATA(group, mod, cpu); \ |
| return YASM_ARCH_CHECK_ID_INSN; \ |
| } while (0) |
| |
| /* |
| * General instruction groupings |
| */ |
| |
| /* Placeholder for instructions invalid in 64-bit mode */ |
| static const x86_insn_info not64_insn[] = { |
| { CPU_Not64, 0, 0, 0, 0, {0, 0, 0}, 0, 0, {0, 0, 0} } |
| }; |
| |
| /* One byte opcode instructions with no operands */ |
| static const x86_insn_info onebyte_insn[] = { |
| { CPU_Any, MOD_Op0Add|MOD_OpSizeR|MOD_DOpS64R, 0, 0, 1, {0, 0, 0}, 0, 0, |
| {0, 0, 0} } |
| }; |
| |
| /* Two byte opcode instructions with no operands */ |
| static const x86_insn_info twobyte_insn[] = { |
| { CPU_Any, MOD_Op1Add|MOD_Op0Add, 0, 0, 2, {0, 0, 0}, 0, 0, {0, 0, 0} } |
| }; |
| |
| /* Three byte opcode instructions with no operands */ |
| static const x86_insn_info threebyte_insn[] = { |
| { CPU_Any, MOD_Op2Add|MOD_Op1Add|MOD_Op0Add, 0, 0, 3, {0, 0, 0}, 0, 0, |
| {0, 0, 0} } |
| }; |
| |
| /* One byte opcode instructions with general memory operand */ |
| static const x86_insn_info onebytemem_insn[] = { |
| { CPU_Any, MOD_Op0Add|MOD_SpAdd, 0, 0, 1, {0, 0, 0}, 0, 1, |
| {OPT_Mem|OPS_Any|OPA_EA, 0, 0} } |
| }; |
| |
| /* Two byte opcode instructions with general memory operand */ |
| static const x86_insn_info twobytemem_insn[] = { |
| { CPU_Any, MOD_Op1Add|MOD_Op0Add|MOD_SpAdd, 0, 0, 2, {0, 0, 0}, 0, 1, |
| {OPT_Mem|OPS_Any|OPA_EA, 0, 0} } |
| }; |
| |
| /* Move instructions */ |
| static const x86_insn_info mov_insn[] = { |
| { CPU_Any, 0, 0, 0, 1, {0xA0, 0, 0}, 0, 2, |
| {OPT_Areg|OPS_8|OPA_None, OPT_MemOffs|OPS_8|OPS_Relaxed|OPA_EA, 0} }, |
| { CPU_Any, 0, 16, 0, 1, {0xA1, 0, 0}, 0, 2, |
| {OPT_Areg|OPS_16|OPA_None, OPT_MemOffs|OPS_16|OPS_Relaxed|OPA_EA, 0} }, |
| { CPU_386, 0, 32, 0, 1, {0xA1, 0, 0}, 0, 2, |
| {OPT_Areg|OPS_32|OPA_None, OPT_MemOffs|OPS_32|OPS_Relaxed|OPA_EA, 0} }, |
| { CPU_Hammer|CPU_64, 0, 64, 0, 1, {0xA1, 0, 0}, 0, 2, |
| {OPT_Areg|OPS_64|OPA_None, OPT_MemOffs|OPS_64|OPS_Relaxed|OPA_EA, 0} }, |
| |
| { CPU_Any, 0, 0, 0, 1, {0xA2, 0, 0}, 0, 2, |
| {OPT_MemOffs|OPS_8|OPS_Relaxed|OPA_EA, OPT_Areg|OPS_8|OPA_None, 0} }, |
| { CPU_Any, 0, 16, 0, 1, {0xA3, 0, 0}, 0, 2, |
| {OPT_MemOffs|OPS_16|OPS_Relaxed|OPA_EA, OPT_Areg|OPS_16|OPA_None, 0} }, |
| { CPU_386, 0, 32, 0, 1, {0xA3, 0, 0}, 0, 2, |
| {OPT_MemOffs|OPS_32|OPS_Relaxed|OPA_EA, OPT_Areg|OPS_32|OPA_None, 0} }, |
| { CPU_Hammer|CPU_64, 0, 64, 0, 1, {0xA3, 0, 0}, 0, 2, |
| {OPT_MemOffs|OPS_64|OPS_Relaxed|OPA_EA, OPT_Areg|OPS_64|OPA_None, 0} }, |
| |
| { CPU_Any, 0, 0, 0, 1, {0x88, 0, 0}, 0, 2, |
| {OPT_RM|OPS_8|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_8|OPA_Spare, 0} }, |
| { CPU_Any, 0, 16, 0, 1, {0x89, 0, 0}, 0, 2, |
| {OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_16|OPA_Spare, 0} }, |
| { CPU_386, 0, 32, 0, 1, {0x89, 0, 0}, 0, 2, |
| {OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_32|OPA_Spare, 0} }, |
| { CPU_Hammer|CPU_64, 0, 64, 0, 1, {0x89, 0, 0}, 0, 2, |
| {OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_64|OPA_Spare, 0} }, |
| |
| { CPU_Any, 0, 0, 0, 1, {0x8A, 0, 0}, 0, 2, |
| {OPT_Reg|OPS_8|OPA_Spare, OPT_RM|OPS_8|OPS_Relaxed|OPA_EA, 0} }, |
| { CPU_Any, 0, 16, 0, 1, {0x8B, 0, 0}, 0, 2, |
| {OPT_Reg|OPS_16|OPA_Spare, OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, 0} }, |
| { CPU_386, 0, 32, 0, 1, {0x8B, 0, 0}, 0, 2, |
| {OPT_Reg|OPS_32|OPA_Spare, OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, 0} }, |
| { CPU_Hammer|CPU_64, 0, 64, 0, 1, {0x8B, 0, 0}, 0, 2, |
| {OPT_Reg|OPS_64|OPA_Spare, OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, 0} }, |
| |
| { CPU_Any, 0, 0, 0, 1, {0x8C, 0, 0}, 0, 2, |
| {OPT_Mem|OPS_16|OPS_Relaxed|OPA_EA, |
| OPT_SegReg|OPS_16|OPS_Relaxed|OPA_Spare, 0} }, |
| { CPU_Any, 0, 16, 0, 1, {0x8C, 0, 0}, 0, 2, |
| {OPT_Reg|OPS_16|OPA_EA, OPT_SegReg|OPS_16|OPS_Relaxed|OPA_Spare, 0} }, |
| { CPU_386, 0, 32, 0, 1, {0x8C, 0, 0}, 0, 2, |
| {OPT_Reg|OPS_32|OPA_EA, OPT_SegReg|OPS_16|OPS_Relaxed|OPA_Spare, 0} }, |
| { CPU_Hammer|CPU_64, 0, 64, 0, 1, {0x8C, 0, 0}, 0, 2, |
| {OPT_Reg|OPS_64|OPA_EA, OPT_SegReg|OPS_16|OPS_Relaxed|OPA_Spare, 0} }, |
| |
| { CPU_Any, 0, 0, 0, 1, {0x8E, 0, 0}, 0, 2, |
| {OPT_SegReg|OPS_16|OPS_Relaxed|OPA_Spare, |
| OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, 0} }, |
| { CPU_386, 0, 0, 0, 1, {0x8E, 0, 0}, 0, 2, |
| {OPT_SegReg|OPS_16|OPS_Relaxed|OPA_Spare, OPT_Reg|OPS_32|OPA_EA, 0} }, |
| { CPU_Hammer|CPU_64, 0, 0, 0, 1, {0x8E, 0, 0}, 0, 2, |
| {OPT_SegReg|OPS_16|OPS_Relaxed|OPA_Spare, OPT_Reg|OPS_64|OPA_EA, 0} }, |
| |
| { CPU_Any, 0, 0, 0, 1, {0xB0, 0, 0}, 0, 2, |
| {OPT_Reg|OPS_8|OPA_Op0Add, OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm, 0} }, |
| { CPU_Any, 0, 16, 0, 1, {0xB8, 0, 0}, 0, 2, |
| {OPT_Reg|OPS_16|OPA_Op0Add, OPT_Imm|OPS_16|OPS_Relaxed|OPA_Imm, 0} }, |
| { CPU_386, 0, 32, 0, 1, {0xB8, 0, 0}, 0, 2, |
| {OPT_Reg|OPS_32|OPA_Op0Add, OPT_Imm|OPS_32|OPS_Relaxed|OPA_Imm, 0} }, |
| { CPU_Hammer|CPU_64, 0, 64, 0, 1, {0xB8, 0, 0}, 0, 2, |
| {OPT_Reg|OPS_64|OPA_Op0Add, OPT_Imm|OPS_64|OPS_Relaxed|OPA_Imm, 0} }, |
| /* Need two sets here, one for strictness on left side, one for right. */ |
| { CPU_Any, 0, 0, 0, 1, {0xC6, 0, 0}, 0, 2, |
| {OPT_RM|OPS_8|OPS_Relaxed|OPA_EA, OPT_Imm|OPS_8|OPA_Imm, 0} }, |
| { CPU_Any, 0, 16, 0, 1, {0xC7, 0, 0}, 0, 2, |
| {OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, OPT_Imm|OPS_16|OPA_Imm, 0} }, |
| { CPU_386, 0, 32, 0, 1, {0xC7, 0, 0}, 0, 2, |
| {OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, OPT_Imm|OPS_32|OPA_Imm, 0} }, |
| { CPU_Hammer|CPU_64, 0, 64, 0, 1, {0xC7, 0, 0}, 0, 2, |
| {OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, OPT_Imm|OPS_32|OPA_Imm, 0} }, |
| { CPU_Any, 0, 0, 0, 1, {0xC6, 0, 0}, 0, 2, |
| {OPT_RM|OPS_8|OPA_EA, OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm, 0} }, |
| { CPU_Any, 0, 16, 0, 1, {0xC7, 0, 0}, 0, 2, |
| {OPT_RM|OPS_16|OPA_EA, OPT_Imm|OPS_16|OPS_Relaxed|OPA_Imm, 0} }, |
| { CPU_386, 0, 32, 0, 1, {0xC7, 0, 0}, 0, 2, |
| {OPT_RM|OPS_32|OPA_EA, OPT_Imm|OPS_32|OPS_Relaxed|OPA_Imm, 0} }, |
| { CPU_Hammer|CPU_64, 0, 64, 0, 1, {0xC7, 0, 0}, 0, 2, |
| {OPT_RM|OPS_64|OPA_EA, OPT_Imm|OPS_32|OPS_Relaxed|OPA_Imm, 0} }, |
| |
| { CPU_586|CPU_Priv|CPU_Not64, 0, 0, 0, 2, {0x0F, 0x22, 0}, 0, 2, |
| {OPT_CR4|OPS_32|OPA_Spare, OPT_Reg|OPS_32|OPA_EA, 0} }, |
| { CPU_386|CPU_Priv|CPU_Not64, 0, 0, 0, 2, {0x0F, 0x22, 0}, 0, 2, |
| {OPT_CRReg|OPS_32|OPA_Spare, OPT_Reg|OPS_32|OPA_EA, 0} }, |
| { CPU_Hammer|CPU_Priv|CPU_64, 0, 0, 0, 2, {0x0F, 0x22, 0}, 0, 2, |
| {OPT_CRReg|OPS_32|OPA_Spare, OPT_Reg|OPS_64|OPA_EA, 0} }, |
| { CPU_586|CPU_Priv|CPU_Not64, 0, 0, 0, 2, {0x0F, 0x20, 0}, 0, 2, |
| {OPT_Reg|OPS_32|OPA_EA, OPT_CR4|OPS_32|OPA_Spare, 0} }, |
| { CPU_386|CPU_Priv|CPU_Not64, 0, 0, 0, 2, {0x0F, 0x20, 0}, 0, 2, |
| {OPT_Reg|OPS_32|OPA_EA, OPT_CRReg|OPS_32|OPA_Spare, 0} }, |
| { CPU_Hammer|CPU_Priv|CPU_64, 0, 0, 0, 2, {0x0F, 0x20, 0}, 0, 2, |
| {OPT_Reg|OPS_64|OPA_EA, OPT_CRReg|OPS_32|OPA_Spare, 0} }, |
| |
| { CPU_386|CPU_Priv|CPU_Not64, 0, 0, 0, 2, {0x0F, 0x23, 0}, 0, 2, |
| {OPT_DRReg|OPS_32|OPA_Spare, OPT_Reg|OPS_32|OPA_EA, 0} }, |
| { CPU_Hammer|CPU_Priv|CPU_64, 0, 0, 0, 2, {0x0F, 0x23, 0}, 0, 2, |
| {OPT_DRReg|OPS_32|OPA_Spare, OPT_Reg|OPS_64|OPA_EA, 0} }, |
| { CPU_386|CPU_Priv|CPU_Not64, 0, 0, 0, 2, {0x0F, 0x21, 0}, 0, 2, |
| {OPT_Reg|OPS_32|OPA_EA, OPT_DRReg|OPS_32|OPA_Spare, 0} }, |
| { CPU_Hammer|CPU_Priv|CPU_64, 0, 0, 0, 2, {0x0F, 0x21, 0}, 0, 2, |
| {OPT_Reg|OPS_64|OPA_EA, OPT_DRReg|OPS_32|OPA_Spare, 0} } |
| }; |
| |
| /* Move with sign/zero extend */ |
| static const x86_insn_info movszx_insn[] = { |
| { CPU_386, MOD_Op1Add, 16, 0, 2, {0x0F, 0, 0}, 0, 2, |
| {OPT_Reg|OPS_16|OPA_Spare, OPT_RM|OPS_8|OPS_Relaxed|OPA_EA, 0} }, |
| { CPU_386, MOD_Op1Add, 32, 0, 2, {0x0F, 0, 0}, 0, 2, |
| {OPT_Reg|OPS_32|OPA_Spare, OPT_RM|OPS_8|OPA_EA, 0} }, |
| { CPU_Hammer|CPU_64, MOD_Op1Add, 64, 0, 2, {0x0F, 0, 0}, 0, 2, |
| {OPT_Reg|OPS_64|OPA_Spare, OPT_RM|OPS_8|OPA_EA, 0} }, |
| { CPU_386, MOD_Op1Add, 32, 0, 2, {0x0F, 1, 0}, 0, 2, |
| {OPT_Reg|OPS_32|OPA_Spare, OPT_RM|OPS_16|OPA_EA, 0} }, |
| { CPU_Hammer|CPU_64, MOD_Op1Add, 64, 0, 2, {0x0F, 1, 0}, 0, 2, |
| {OPT_Reg|OPS_64|OPA_Spare, OPT_RM|OPS_16|OPA_EA, 0} } |
| }; |
| |
| /* Move with sign-extend doubleword (64-bit mode only) */ |
| static const x86_insn_info movsxd_insn[] = { |
| { CPU_Hammer|CPU_64, 0, 64, 0, 1, {0x63, 0, 0}, 0, 2, |
| {OPT_Reg|OPS_64|OPA_Spare, OPT_RM|OPS_32|OPA_EA, 0} } |
| }; |
| |
| /* Push instructions */ |
| static const x86_insn_info push_insn[] = { |
| { CPU_Any, 0, 16, 64, 1, {0x50, 0, 0}, 0, 1, |
| {OPT_Reg|OPS_16|OPA_Op0Add, 0, 0} }, |
| { CPU_386|CPU_Not64, 0, 32, 0, 1, {0x50, 0, 0}, 0, 1, |
| {OPT_Reg|OPS_32|OPA_Op0Add, 0, 0} }, |
| { CPU_Hammer|CPU_64, 0, 0, 64, 1, {0x50, 0, 0}, 0, 1, |
| {OPT_Reg|OPS_64|OPA_Op0Add, 0, 0} }, |
| { CPU_Any, 0, 16, 64, 1, {0xFF, 0, 0}, 6, 1, {OPT_RM|OPS_16|OPA_EA, 0, 0} }, |
| { CPU_386|CPU_Not64, 0, 32, 0, 1, {0xFF, 0, 0}, 6, 1, |
| {OPT_RM|OPS_32|OPA_EA, 0, 0} }, |
| { CPU_Hammer|CPU_64, 0, 0, 64, 1, {0xFF, 0, 0}, 6, 1, |
| {OPT_RM|OPS_64|OPA_EA, 0, 0} }, |
| { CPU_Any, 0, 0, 64, 1, {0x6A, 0, 0}, 0, 1, {OPT_Imm|OPS_8|OPA_Imm, 0, 0} }, |
| { CPU_Any, 0, 16, 64, 1, {0x68, 0, 0}, 0, 1, {OPT_Imm|OPS_16|OPA_Imm, 0, 0} }, |
| { CPU_386|CPU_Not64, 0, 32, 0, 1, {0x68, 0, 0}, 0, 1, |
| {OPT_Imm|OPS_32|OPA_Imm, 0, 0} }, |
| { CPU_Hammer|CPU_64, 0, 64, 64, 1, {0x68, 0, 0}, 0, 1, |
| {OPT_Imm|OPS_64|OPA_Imm, 0, 0} }, |
| { CPU_Not64, 0, 0, 0, 1, {0x0E, 0, 0}, 0, 1, {OPT_CS|OPS_Any|OPA_None, 0, 0} }, |
| { CPU_Not64, 0, 16, 0, 1, {0x0E, 0, 0}, 0, 1, {OPT_CS|OPS_16|OPA_None, 0, 0} }, |
| { CPU_Not64, 0, 32, 0, 1, {0x0E, 0, 0}, 0, 1, {OPT_CS|OPS_32|OPA_None, 0, 0} }, |
| { CPU_Not64, 0, 0, 0, 1, {0x16, 0, 0}, 0, 1, {OPT_SS|OPS_Any|OPA_None, 0, 0} }, |
| { CPU_Not64, 0, 16, 0, 1, {0x16, 0, 0}, 0, 1, {OPT_SS|OPS_16|OPA_None, 0, 0} }, |
| { CPU_Not64, 0, 32, 0, 1, {0x16, 0, 0}, 0, 1, {OPT_SS|OPS_32|OPA_None, 0, 0} }, |
| { CPU_Not64, 0, 0, 0, 1, {0x1E, 0, 0}, 0, 1, {OPT_DS|OPS_Any|OPA_None, 0, 0} }, |
| { CPU_Not64, 0, 16, 0, 1, {0x1E, 0, 0}, 0, 1, {OPT_DS|OPS_16|OPA_None, 0, 0} }, |
| { CPU_Not64, 0, 32, 0, 1, {0x1E, 0, 0}, 0, 1, {OPT_DS|OPS_32|OPA_None, 0, 0} }, |
| { CPU_Not64, 0, 0, 0, 1, {0x06, 0, 0}, 0, 1, {OPT_ES|OPS_Any|OPA_None, 0, 0} }, |
| { CPU_Not64, 0, 16, 0, 1, {0x06, 0, 0}, 0, 1, {OPT_ES|OPS_16|OPA_None, 0, 0} }, |
| { CPU_Not64, 0, 32, 0, 1, {0x06, 0, 0}, 0, 1, {OPT_ES|OPS_32|OPA_None, 0, 0} }, |
| { CPU_386, 0, 0, 0, 2, {0x0F, 0xA0, 0}, 0, 1, |
| {OPT_FS|OPS_Any|OPA_None, 0, 0} }, |
| { CPU_386, 0, 16, 0, 2, {0x0F, 0xA0, 0}, 0, 1, |
| {OPT_FS|OPS_16|OPA_None, 0, 0} }, |
| { CPU_386, 0, 32, 0, 2, {0x0F, 0xA0, 0}, 0, 1, |
| {OPT_FS|OPS_32|OPA_None, 0, 0} }, |
| { CPU_386, 0, 0, 0, 2, {0x0F, 0xA8, 0}, 0, 1, |
| {OPT_GS|OPS_Any|OPA_None, 0, 0} }, |
| { CPU_386, 0, 16, 0, 2, {0x0F, 0xA8, 0}, 0, 1, |
| {OPT_GS|OPS_16|OPA_None, 0, 0} }, |
| { CPU_386, 0, 32, 0, 2, {0x0F, 0xA8, 0}, 0, 1, |
| {OPT_GS|OPS_32|OPA_None, 0, 0} } |
| }; |
| |
| /* Pop instructions */ |
| static const x86_insn_info pop_insn[] = { |
| { CPU_Any, 0, 16, 64, 1, {0x58, 0, 0}, 0, 1, |
| {OPT_Reg|OPS_16|OPA_Op0Add, 0, 0} }, |
| { CPU_386|CPU_Not64, 0, 32, 0, 1, {0x58, 0, 0}, 0, 1, |
| {OPT_Reg|OPS_32|OPA_Op0Add, 0, 0} }, |
| { CPU_Hammer|CPU_64, 0, 0, 64, 1, {0x58, 0, 0}, 0, 1, |
| {OPT_Reg|OPS_64|OPA_Op0Add, 0, 0} }, |
| { CPU_Any, 0, 16, 64, 1, {0x8F, 0, 0}, 0, 1, {OPT_RM|OPS_16|OPA_EA, 0, 0} }, |
| { CPU_386|CPU_Not64, 0, 32, 0, 1, {0x8F, 0, 0}, 0, 1, |
| {OPT_RM|OPS_32|OPA_EA, 0, 0} }, |
| { CPU_Hammer|CPU_64, 0, 0, 64, 1, {0x8F, 0, 0}, 0, 1, |
| {OPT_RM|OPS_64|OPA_EA, 0, 0} }, |
| /* POP CS is debateably valid on the 8086, if obsolete and undocumented. |
| * We don't include it because it's VERY unlikely it will ever be used |
| * anywhere. If someone really wants it they can db 0x0F it. |
| */ |
| /*{ CPU_Any|CPU_Undoc|CPU_Obs, 0, 0, 1, {0x0F, 0, 0}, 0, 1, |
| {OPT_CS|OPS_Any|OPA_None, 0, 0} },*/ |
| { CPU_Not64, 0, 0, 0, 1, {0x17, 0, 0}, 0, 1, {OPT_SS|OPS_Any|OPA_None, 0, 0} }, |
| { CPU_Not64, 0, 16, 0, 1, {0x17, 0, 0}, 0, 1, {OPT_SS|OPS_16|OPA_None, 0, 0} }, |
| { CPU_Not64, 0, 32, 0, 1, {0x17, 0, 0}, 0, 1, {OPT_SS|OPS_32|OPA_None, 0, 0} }, |
| { CPU_Not64, 0, 0, 0, 1, {0x1F, 0, 0}, 0, 1, {OPT_DS|OPS_Any|OPA_None, 0, 0} }, |
| { CPU_Not64, 0, 16, 0, 1, {0x1F, 0, 0}, 0, 1, {OPT_DS|OPS_16|OPA_None, 0, 0} }, |
| { CPU_Not64, 0, 32, 0, 1, {0x1F, 0, 0}, 0, 1, {OPT_DS|OPS_32|OPA_None, 0, 0} }, |
| { CPU_Not64, 0, 0, 0, 1, {0x07, 0, 0}, 0, 1, {OPT_ES|OPS_Any|OPA_None, 0, 0} }, |
| { CPU_Not64, 0, 16, 0, 1, {0x07, 0, 0}, 0, 1, {OPT_ES|OPS_16|OPA_None, 0, 0} }, |
| { CPU_Not64, 0, 32, 0, 1, {0x07, 0, 0}, 0, 1, {OPT_ES|OPS_32|OPA_None, 0, 0} }, |
| { CPU_386, 0, 0, 0, 2, {0x0F, 0xA1, 0}, 0, 1, |
| {OPT_FS|OPS_Any|OPA_None, 0, 0} }, |
| { CPU_386, 0, 16, 0, 2, {0x0F, 0xA1, 0}, 0, 1, |
| {OPT_FS|OPS_16|OPA_None, 0, 0} }, |
| { CPU_386, 0, 32, 0, 2, {0x0F, 0xA1, 0}, 0, 1, |
| {OPT_FS|OPS_32|OPA_None, 0, 0} }, |
| { CPU_386, 0, 0, 0, 2, {0x0F, 0xA9, 0}, 0, 1, |
| {OPT_GS|OPS_Any|OPA_None, 0, 0} }, |
| { CPU_386, 0, 16, 0, 2, {0x0F, 0xA9, 0}, 0, 1, |
| {OPT_GS|OPS_16|OPA_None, 0, 0} }, |
| { CPU_386, 0, 32, 0, 2, {0x0F, 0xA9, 0}, 0, 1, |
| {OPT_GS|OPS_32|OPA_None, 0, 0} } |
| }; |
| |
| /* Exchange instructions */ |
| static const x86_insn_info xchg_insn[] = { |
| { CPU_Any, 0, 0, 0, 1, {0x86, 0, 0}, 0, 2, |
| {OPT_RM|OPS_8|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_8|OPA_Spare, 0} }, |
| { CPU_Any, 0, 0, 0, 1, {0x86, 0, 0}, 0, 2, |
| {OPT_Reg|OPS_8|OPA_Spare, OPT_RM|OPS_8|OPS_Relaxed|OPA_EA, 0} }, |
| { CPU_Any, 0, 16, 0, 1, {0x90, 0, 0}, 0, 2, |
| {OPT_Areg|OPS_16|OPA_None, OPT_Reg|OPS_16|OPA_Op0Add, 0} }, |
| { CPU_Any, 0, 16, 0, 1, {0x90, 0, 0}, 0, 2, |
| {OPT_Reg|OPS_16|OPA_Op0Add, OPT_Areg|OPS_16|OPA_None, 0} }, |
| { CPU_Any, 0, 16, 0, 1, {0x87, 0, 0}, 0, 2, |
| {OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_16|OPA_Spare, 0} }, |
| { CPU_Any, 0, 16, 0, 1, {0x87, 0, 0}, 0, 2, |
| {OPT_Reg|OPS_16|OPA_Spare, OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, 0} }, |
| { CPU_386, 0, 32, 0, 1, {0x90, 0, 0}, 0, 2, |
| {OPT_Areg|OPS_32|OPA_None, OPT_Reg|OPS_32|OPA_Op0Add, 0} }, |
| { CPU_386, 0, 32, 0, 1, {0x90, 0, 0}, 0, 2, |
| {OPT_Reg|OPS_32|OPA_Op0Add, OPT_Areg|OPS_32|OPA_None, 0} }, |
| { CPU_386, 0, 32, 0, 1, {0x87, 0, 0}, 0, 2, |
| {OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_32|OPA_Spare, 0} }, |
| { CPU_386, 0, 32, 0, 1, {0x87, 0, 0}, 0, 2, |
| {OPT_Reg|OPS_32|OPA_Spare, OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, 0} }, |
| { CPU_Hammer|CPU_64, 0, 64, 0, 1, {0x90, 0, 0}, 0, 2, |
| {OPT_Areg|OPS_64|OPA_None, OPT_Reg|OPS_64|OPA_Op0Add, 0} }, |
| { CPU_Hammer|CPU_64, 0, 64, 0, 1, {0x90, 0, 0}, 0, 2, |
| {OPT_Reg|OPS_64|OPA_Op0Add, OPT_Areg|OPS_64|OPA_None, 0} }, |
| { CPU_Hammer|CPU_64, 0, 64, 0, 1, {0x87, 0, 0}, 0, 2, |
| {OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_64|OPA_Spare, 0} }, |
| { CPU_Hammer|CPU_64, 0, 64, 0, 1, {0x87, 0, 0}, 0, 2, |
| {OPT_Reg|OPS_64|OPA_Spare, OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, 0} } |
| }; |
| |
| /* In/out from ports */ |
| static const x86_insn_info in_insn[] = { |
| { CPU_Any, 0, 0, 0, 1, {0xE4, 0, 0}, 0, 2, |
| {OPT_Areg|OPS_8|OPA_None, OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm, 0} }, |
| { CPU_Any, 0, 16, 0, 1, {0xE5, 0, 0}, 0, 2, |
| {OPT_Areg|OPS_16|OPA_None, OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm, 0} }, |
| { CPU_386, 0, 32, 0, 1, {0xE5, 0, 0}, 0, 2, |
| {OPT_Areg|OPS_32|OPA_None, OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm, 0} }, |
| { CPU_Any, 0, 0, 0, 1, {0xEC, 0, 0}, 0, 2, |
| {OPT_Areg|OPS_8|OPA_None, OPT_Dreg|OPS_16|OPA_None, 0} }, |
| { CPU_Any, 0, 16, 0, 1, {0xED, 0, 0}, 0, 2, |
| {OPT_Areg|OPS_16|OPA_None, OPT_Dreg|OPS_16|OPA_None, 0} }, |
| { CPU_386, 0, 32, 0, 1, {0xED, 0, 0}, 0, 2, |
| {OPT_Areg|OPS_32|OPA_None, OPT_Dreg|OPS_16|OPA_None, 0} } |
| }; |
| static const x86_insn_info out_insn[] = { |
| { CPU_Any, 0, 0, 0, 1, {0xE6, 0, 0}, 0, 2, |
| {OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm, OPT_Areg|OPS_8|OPA_None, 0} }, |
| { CPU_Any, 0, 16, 0, 1, {0xE7, 0, 0}, 0, 2, |
| {OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm, OPT_Areg|OPS_16|OPA_None, 0} }, |
| { CPU_386, 0, 32, 0, 1, {0xE7, 0, 0}, 0, 2, |
| {OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm, OPT_Areg|OPS_32|OPA_None, 0} }, |
| { CPU_Any, 0, 0, 0, 1, {0xEE, 0, 0}, 0, 2, |
| {OPT_Dreg|OPS_16|OPA_None, OPT_Areg|OPS_8|OPA_None, 0} }, |
| { CPU_Any, 0, 16, 0, 1, {0xEF, 0, 0}, 0, 2, |
| {OPT_Dreg|OPS_16|OPA_None, OPT_Areg|OPS_16|OPA_None, 0} }, |
| { CPU_386, 0, 32, 0, 1, {0xEF, 0, 0}, 0, 2, |
| {OPT_Dreg|OPS_16|OPA_None, OPT_Areg|OPS_32|OPA_None, 0} } |
| }; |
| |
| /* Load effective address */ |
| static const x86_insn_info lea_insn[] = { |
| { CPU_Any, 0, 16, 0, 1, {0x8D, 0, 0}, 0, 2, |
| {OPT_Reg|OPS_16|OPA_Spare, OPT_Mem|OPS_16|OPS_Relaxed|OPA_EA, 0} }, |
| { CPU_386, 0, 32, 0, 1, {0x8D, 0, 0}, 0, 2, |
| {OPT_Reg|OPS_32|OPA_Spare, OPT_Mem|OPS_32|OPS_Relaxed|OPA_EA, 0} }, |
| { CPU_Hammer|CPU_64, 0, 64, 0, 1, {0x8D, 0, 0}, 0, 2, |
| {OPT_Reg|OPS_64|OPA_Spare, OPT_Mem|OPS_64|OPS_Relaxed|OPA_EA, 0} } |
| }; |
| |
| /* Load segment registers from memory */ |
| static const x86_insn_info ldes_insn[] = { |
| { CPU_Not64, MOD_Op0Add, 16, 0, 1, {0, 0, 0}, 0, 2, |
| {OPT_Reg|OPS_16|OPA_Spare, OPT_Mem|OPS_Any|OPA_EA, 0} }, |
| { CPU_386|CPU_Not64, MOD_Op0Add, 32, 0, 1, {0, 0, 0}, 0, 2, |
| {OPT_Reg|OPS_32|OPA_Spare, OPT_Mem|OPS_Any|OPA_EA, 0} } |
| }; |
| static const x86_insn_info lfgss_insn[] = { |
| { CPU_386, MOD_Op1Add, 16, 0, 2, {0x0F, 0x00, 0}, 0, 2, |
| {OPT_Reg|OPS_16|OPA_Spare, OPT_Mem|OPS_Any|OPA_EA, 0} }, |
| { CPU_386, MOD_Op1Add, 32, 0, 2, {0x0F, 0x00, 0}, 0, 2, |
| {OPT_Reg|OPS_32|OPA_Spare, OPT_Mem|OPS_Any|OPA_EA, 0} } |
| }; |
| |
| /* Arithmetic - general */ |
| static const x86_insn_info arith_insn[] = { |
| { CPU_Any, MOD_Op0Add, 0, 0, 1, {0x04, 0, 0}, 0, 2, |
| {OPT_Areg|OPS_8|OPA_None, OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm, 0} }, |
| { CPU_Any, MOD_Op0Add, 16, 0, 1, {0x05, 0, 0}, 0, 2, |
| {OPT_Areg|OPS_16|OPA_None, OPT_Imm|OPS_16|OPS_Relaxed|OPA_Imm, 0} }, |
| { CPU_386, MOD_Op0Add, 32, 0, 1, {0x05, 0, 0}, 0, 2, |
| {OPT_Areg|OPS_32|OPA_None, OPT_Imm|OPS_32|OPS_Relaxed|OPA_Imm, 0} }, |
| { CPU_Hammer|CPU_64, MOD_Op0Add, 64, 0, 1, {0x05, 0, 0}, 0, 2, |
| {OPT_Areg|OPS_64|OPA_None, OPT_Imm|OPS_32|OPS_Relaxed|OPA_Imm, 0} }, |
| |
| { CPU_Any, MOD_Gap0|MOD_SpAdd, 0, 0, 1, {0x80, 0, 0}, 0, 2, |
| {OPT_RM|OPS_8|OPA_EA, OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm, 0} }, |
| { CPU_Any, MOD_Gap0|MOD_SpAdd, 0, 0, 1, {0x80, 0, 0}, 0, 2, |
| {OPT_RM|OPS_8|OPS_Relaxed|OPA_EA, OPT_Imm|OPS_8|OPA_Imm, 0} }, |
| { CPU_Any, MOD_Gap0|MOD_SpAdd, 16, 0, 1, {0x83, 0, 0}, 0, 2, |
| {OPT_RM|OPS_16|OPA_EA, OPT_Imm|OPS_8|OPA_SImm, 0} }, |
| { CPU_Any, MOD_Gap0|MOD_SpAdd, 16, 0, 1, {0x81, 0x83, 0}, 0, 2, |
| {OPT_RM|OPS_16|OPA_EA, |
| OPT_Imm|OPS_16|OPS_Relaxed|OPA_Imm|OPAP_SImm8Avail, 0} }, |
| { CPU_Any, MOD_Gap0|MOD_SpAdd, 16, 0, 1, {0x81, 0, 0}, 0, 2, |
| {OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, OPT_Imm|OPS_16|OPA_Imm, 0} }, |
| { CPU_386, MOD_Gap0|MOD_SpAdd, 32, 0, 1, {0x83, 0, 0}, 0, 2, |
| {OPT_RM|OPS_32|OPA_EA, OPT_Imm|OPS_8|OPA_SImm, 0} }, |
| { CPU_386, MOD_Gap0|MOD_SpAdd, 32, 0, 1, {0x81, 0x83, 0}, 0, 2, |
| {OPT_RM|OPS_32|OPA_EA, |
| OPT_Imm|OPS_32|OPS_Relaxed|OPA_Imm|OPAP_SImm8Avail, 0} }, |
| { CPU_386, MOD_Gap0|MOD_SpAdd, 32, 0, 1, {0x81, 0, 0}, 0, 2, |
| {OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, OPT_Imm|OPS_32|OPA_Imm, 0} }, |
| { CPU_Hammer|CPU_64, MOD_Gap0|MOD_SpAdd, 64, 0, 1, {0x83, 0, 0}, 0, 2, |
| {OPT_RM|OPS_64|OPA_EA, OPT_Imm|OPS_8|OPA_SImm, 0} }, |
| { CPU_Hammer|CPU_64, MOD_Gap0|MOD_SpAdd, 64, 0, 1, {0x81, 0x83, 0}, 0, 2, |
| {OPT_RM|OPS_64|OPA_EA, |
| OPT_Imm|OPS_32|OPS_Relaxed|OPA_Imm|OPAP_SImm8Avail, 0} }, |
| { CPU_Hammer|CPU_64, MOD_Gap0|MOD_SpAdd, 64, 0, 1, {0x81, 0, 0}, 0, 2, |
| {OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, OPT_Imm|OPS_32|OPA_Imm, 0} }, |
| |
| { CPU_Any, MOD_Op0Add, 0, 0, 1, {0x00, 0, 0}, 0, 2, |
| {OPT_RM|OPS_8|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_8|OPA_Spare, 0} }, |
| { CPU_Any, MOD_Op0Add, 16, 0, 1, {0x01, 0, 0}, 0, 2, |
| {OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_16|OPA_Spare, 0} }, |
| { CPU_386, MOD_Op0Add, 32, 0, 1, {0x01, 0, 0}, 0, 2, |
| {OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_32|OPA_Spare, 0} }, |
| { CPU_Hammer|CPU_64, MOD_Op0Add, 64, 0, 1, {0x01, 0, 0}, 0, 2, |
| {OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_64|OPA_Spare, 0} }, |
| { CPU_Any, MOD_Op0Add, 0, 0, 1, {0x02, 0, 0}, 0, 2, |
| {OPT_Reg|OPS_8|OPA_Spare, OPT_RM|OPS_8|OPS_Relaxed|OPA_EA, 0} }, |
| { CPU_Any, MOD_Op0Add, 16, 0, 1, {0x03, 0, 0}, 0, 2, |
| {OPT_Reg|OPS_16|OPA_Spare, OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, 0} }, |
| { CPU_386, MOD_Op0Add, 32, 0, 1, {0x03, 0, 0}, 0, 2, |
| {OPT_Reg|OPS_32|OPA_Spare, OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, 0} }, |
| { CPU_Hammer|CPU_64, MOD_Op0Add, 64, 0, 1, {0x03, 0, 0}, 0, 2, |
| {OPT_Reg|OPS_64|OPA_Spare, OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, 0} } |
| }; |
| |
| /* Arithmetic - inc/dec */ |
| static const x86_insn_info incdec_insn[] = { |
| { CPU_Any, MOD_Gap0|MOD_SpAdd, 0, 0, 1, {0xFE, 0, 0}, 0, 1, |
| {OPT_RM|OPS_8|OPA_EA, 0, 0} }, |
| { CPU_Not64, MOD_Op0Add, 16, 0, 1, {0, 0, 0}, 0, 1, |
| {OPT_Reg|OPS_16|OPA_Op0Add, 0, 0} }, |
| { CPU_Any, MOD_Gap0|MOD_SpAdd, 16, 0, 1, {0xFF, 0, 0}, 0, 1, |
| {OPT_RM|OPS_16|OPA_EA, 0, 0} }, |
| { CPU_386|CPU_Not64, MOD_Op0Add, 32, 0, 1, {0, 0, 0}, 0, 1, |
| {OPT_Reg|OPS_32|OPA_Op0Add, 0, 0} }, |
| { CPU_386, MOD_Gap0|MOD_SpAdd, 32, 0, 1, {0xFF, 0, 0}, 0, 1, |
| {OPT_RM|OPS_32|OPA_EA, 0, 0} }, |
| { CPU_Hammer|CPU_64, MOD_Gap0|MOD_SpAdd, 64, 0, 1, {0xFF, 0, 0}, 0, 1, |
| {OPT_RM|OPS_64|OPA_EA, 0, 0} }, |
| }; |
| |
| /* Arithmetic - "F6" opcodes (div/idiv/mul/neg/not) */ |
| static const x86_insn_info f6_insn[] = { |
| { CPU_Any, MOD_SpAdd, 0, 0, 1, {0xF6, 0, 0}, 0, 1, |
| {OPT_RM|OPS_8|OPA_EA, 0, 0} }, |
| { CPU_Any, MOD_SpAdd, 16, 0, 1, {0xF7, 0, 0}, 0, 1, |
| {OPT_RM|OPS_16|OPA_EA, 0, 0} }, |
| { CPU_386, MOD_SpAdd, 32, 0, 1, {0xF7, 0, 0}, 0, 1, |
| {OPT_RM|OPS_32|OPA_EA, 0, 0} }, |
| { CPU_Hammer|CPU_64, MOD_SpAdd, 64, 0, 1, {0xF7, 0, 0}, 0, 1, |
| {OPT_RM|OPS_64|OPA_EA, 0, 0} }, |
| }; |
| |
| /* Arithmetic - test instruction */ |
| static const x86_insn_info test_insn[] = { |
| { CPU_Any, 0, 0, 0, 1, {0xA8, 0, 0}, 0, 2, |
| {OPT_Areg|OPS_8|OPA_None, OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm, 0} }, |
| { CPU_Any, 0, 16, 0, 1, {0xA9, 0, 0}, 0, 2, |
| {OPT_Areg|OPS_16|OPA_None, OPT_Imm|OPS_16|OPS_Relaxed|OPA_Imm, 0} }, |
| { CPU_386, 0, 32, 0, 1, {0xA9, 0, 0}, 0, 2, |
| {OPT_Areg|OPS_32|OPA_None, OPT_Imm|OPS_32|OPS_Relaxed|OPA_Imm, 0} }, |
| { CPU_Hammer|CPU_64, 0, 64, 0, 1, {0xA9, 0, 0}, 0, 2, |
| {OPT_Areg|OPS_64|OPA_None, OPT_Imm|OPS_32|OPS_Relaxed|OPA_Imm, 0} }, |
| |
| { CPU_Any, 0, 0, 0, 1, {0xF6, 0, 0}, 0, 2, |
| {OPT_RM|OPS_8|OPA_EA, OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm, 0} }, |
| { CPU_Any, 0, 0, 0, 1, {0xF6, 0, 0}, 0, 2, |
| {OPT_RM|OPS_8|OPS_Relaxed|OPA_EA, OPT_Imm|OPS_8|OPA_Imm, 0} }, |
| { CPU_Any, 0, 16, 0, 1, {0xF7, 0, 0}, 0, 2, |
| {OPT_RM|OPS_16|OPA_EA, OPT_Imm|OPS_16|OPS_Relaxed|OPA_Imm, 0} }, |
| { CPU_Any, 0, 16, 0, 1, {0xF7, 0, 0}, 0, 2, |
| {OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, OPT_Imm|OPS_16|OPA_Imm, 0} }, |
| { CPU_386, 0, 32, 0, 1, {0xF7, 0, 0}, 0, 2, |
| {OPT_RM|OPS_32|OPA_EA, OPT_Imm|OPS_32|OPS_Relaxed|OPA_Imm, 0} }, |
| { CPU_386, 0, 32, 0, 1, {0xF7, 0, 0}, 0, 2, |
| {OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, OPT_Imm|OPS_32|OPA_Imm, 0} }, |
| { CPU_Hammer|CPU_64, 0, 64, 0, 1, {0xF7, 0, 0}, 0, 2, |
| {OPT_RM|OPS_64|OPA_EA, OPT_Imm|OPS_32|OPS_Relaxed|OPA_Imm, 0} }, |
| { CPU_Hammer|CPU_64, 0, 64, 0, 1, {0xF7, 0, 0}, 0, 2, |
| {OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, OPT_Imm|OPS_32|OPA_Imm, 0} }, |
| |
| { CPU_Any, 0, 0, 0, 1, {0x84, 0, 0}, 0, 2, |
| {OPT_RM|OPS_8|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_8|OPA_Spare, 0} }, |
| { CPU_Any, 0, 16, 0, 1, {0x85, 0, 0}, 0, 2, |
| {OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_16|OPA_Spare, 0} }, |
| { CPU_386, 0, 32, 0, 1, {0x85, 0, 0}, 0, 2, |
| {OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_32|OPA_Spare, 0} }, |
| { CPU_Hammer|CPU_64, 0, 64, 0, 1, {0x85, 0, 0}, 0, 2, |
| {OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_64|OPA_Spare, 0} }, |
| |
| { CPU_Any, 0, 0, 0, 1, {0x84, 0, 0}, 0, 2, |
| {OPT_Reg|OPS_8|OPA_Spare, OPT_RM|OPS_8|OPS_Relaxed|OPA_EA, 0} }, |
| { CPU_Any, 0, 16, 0, 1, {0x85, 0, 0}, 0, 2, |
| {OPT_Reg|OPS_16|OPA_Spare, OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, 0} }, |
| { CPU_386, 0, 32, 0, 1, {0x85, 0, 0}, 0, 2, |
| {OPT_Reg|OPS_32|OPA_Spare, OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, 0} }, |
| { CPU_Hammer|CPU_64, 0, 64, 0, 1, {0x85, 0, 0}, 0, 2, |
| {OPT_Reg|OPS_64|OPA_Spare, OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, 0} } |
| }; |
| |
| /* Arithmetic - aad/aam */ |
| static const x86_insn_info aadm_insn[] = { |
| { CPU_Any, MOD_Op0Add, 0, 0, 2, {0xD4, 0x0A, 0}, 0, 0, {0, 0, 0} }, |
| { CPU_Any, MOD_Op0Add, 0, 0, 1, {0xD4, 0, 0}, 0, 1, |
| {OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm, 0, 0} } |
| }; |
| |
| /* Arithmetic - imul */ |
| static const x86_insn_info imul_insn[] = { |
| { CPU_Any, 0, 0, 0, 1, {0xF6, 0, 0}, 5, 1, {OPT_RM|OPS_8|OPA_EA, 0, 0} }, |
| { CPU_Any, 0, 16, 0, 1, {0xF7, 0, 0}, 5, 1, {OPT_RM|OPS_16|OPA_EA, 0, 0} }, |
| { CPU_386, 0, 32, 0, 1, {0xF7, 0, 0}, 5, 1, {OPT_RM|OPS_32|OPA_EA, 0, 0} }, |
| { CPU_Hammer|CPU_64, 0, 64, 0, 1, {0xF7, 0, 0}, 5, 1, |
| {OPT_RM|OPS_64|OPA_EA, 0, 0} }, |
| |
| { CPU_386, 0, 16, 0, 2, {0x0F, 0xAF, 0}, 0, 2, |
| {OPT_Reg|OPS_16|OPA_Spare, OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, 0} }, |
| { CPU_386, 0, 32, 0, 2, {0x0F, 0xAF, 0}, 0, 2, |
| {OPT_Reg|OPS_32|OPA_Spare, OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, 0} }, |
| { CPU_Hammer|CPU_64, 0, 64, 0, 2, {0x0F, 0xAF, 0}, 0, 2, |
| {OPT_Reg|OPS_64|OPA_Spare, OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, 0} }, |
| |
| { CPU_186, 0, 16, 0, 1, {0x6B, 0, 0}, 0, 3, |
| {OPT_Reg|OPS_16|OPA_Spare, OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, |
| OPT_Imm|OPS_8|OPA_SImm} }, |
| { CPU_386, 0, 32, 0, 1, {0x6B, 0, 0}, 0, 3, |
| {OPT_Reg|OPS_32|OPA_Spare, OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, |
| OPT_Imm|OPS_8|OPA_SImm} }, |
| { CPU_Hammer|CPU_64, 0, 64, 0, 1, {0x6B, 0, 0}, 0, 3, |
| {OPT_Reg|OPS_64|OPA_Spare, OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, |
| OPT_Imm|OPS_8|OPA_SImm} }, |
| |
| { CPU_186, 0, 16, 0, 1, {0x6B, 0, 0}, 0, 2, |
| {OPT_Reg|OPS_16|OPA_SpareEA, OPT_Imm|OPS_8|OPA_SImm, 0} }, |
| { CPU_386, 0, 32, 0, 1, {0x6B, 0, 0}, 0, 2, |
| {OPT_Reg|OPS_32|OPA_SpareEA, OPT_Imm|OPS_8|OPA_SImm, 0} }, |
| { CPU_Hammer|CPU_64, 0, 64, 0, 1, {0x6B, 0, 0}, 0, 2, |
| {OPT_Reg|OPS_64|OPA_SpareEA, OPT_Imm|OPS_8|OPA_SImm, 0} }, |
| |
| { CPU_186, 0, 16, 0, 1, {0x69, 0x6B, 0}, 0, 3, |
| {OPT_Reg|OPS_16|OPA_Spare, OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, |
| OPT_Imm|OPS_16|OPS_Relaxed|OPA_SImm|OPAP_SImm8Avail} }, |
| { CPU_386, 0, 32, 0, 1, {0x69, 0x6B, 0}, 0, 3, |
| {OPT_Reg|OPS_32|OPA_Spare, OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, |
| OPT_Imm|OPS_32|OPS_Relaxed|OPA_SImm|OPAP_SImm8Avail} }, |
| { CPU_Hammer|CPU_64, 0, 64, 0, 1, {0x69, 0x6B, 0}, 0, 3, |
| {OPT_Reg|OPS_64|OPA_Spare, OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, |
| OPT_Imm|OPS_32|OPS_Relaxed|OPA_SImm|OPAP_SImm8Avail} }, |
| |
| { CPU_186, 0, 16, 0, 1, {0x69, 0x6B, 0}, 0, 2, |
| {OPT_Reg|OPS_16|OPA_SpareEA, |
| OPT_Imm|OPS_16|OPS_Relaxed|OPA_SImm|OPAP_SImm8Avail, 0} }, |
| { CPU_386, 0, 32, 0, 1, {0x69, 0x6B, 0}, 0, 2, |
| {OPT_Reg|OPS_32|OPA_SpareEA, |
| OPT_Imm|OPS_32|OPS_Relaxed|OPA_SImm|OPAP_SImm8Avail, 0} }, |
| { CPU_Hammer|CPU_64, 0, 64, 0, 1, {0x69, 0x6B, 0}, 0, 2, |
| {OPT_Reg|OPS_64|OPA_SpareEA, |
| OPT_Imm|OPS_32|OPS_Relaxed|OPA_SImm|OPAP_SImm8Avail, 0} } |
| }; |
| |
| /* Shifts - standard */ |
| static const x86_insn_info shift_insn[] = { |
| { CPU_Any, MOD_SpAdd, 0, 0, 1, {0xD2, 0, 0}, 0, 2, |
| {OPT_RM|OPS_8|OPA_EA, OPT_Creg|OPS_8|OPA_None, 0} }, |
| /* FIXME: imm8 is only avail on 186+, but we use imm8 to get to postponed |
| * ,1 form, so it has to be marked as Any. We need to store the active |
| * CPU flags somewhere to pass that parse-time info down the line. |
| */ |
| { CPU_Any, MOD_SpAdd, 0, 0, 1, {0xC0, 0xD0, 0}, 0, 2, |
| {OPT_RM|OPS_8|OPA_EA, OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm|OPAP_ShiftOp, |
| 0} }, |
| { CPU_Any, MOD_SpAdd, 16, 0, 1, {0xD3, 0, 0}, 0, 2, |
| {OPT_RM|OPS_16|OPA_EA, OPT_Creg|OPS_8|OPA_None, 0} }, |
| { CPU_Any, MOD_SpAdd, 16, 0, 1, {0xC1, 0xD1, 0}, 0, 2, |
| {OPT_RM|OPS_16|OPA_EA, OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm|OPAP_ShiftOp, |
| 0} }, |
| { CPU_Any, MOD_SpAdd, 32, 0, 1, {0xD3, 0, 0}, 0, 2, |
| {OPT_RM|OPS_32|OPA_EA, OPT_Creg|OPS_8|OPA_None, 0} }, |
| { CPU_Any, MOD_SpAdd, 32, 0, 1, {0xC1, 0xD1, 0}, 0, 2, |
| {OPT_RM|OPS_32|OPA_EA, OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm|OPAP_ShiftOp, |
| 0} }, |
| { CPU_Hammer|CPU_64, MOD_SpAdd, 64, 0, 1, {0xD3, 0, 0}, 0, 2, |
| {OPT_RM|OPS_64|OPA_EA, OPT_Creg|OPS_8|OPA_None, 0} }, |
| { CPU_Hammer|CPU_64, MOD_SpAdd, 64, 0, 1, {0xC1, 0xD1, 0}, 0, 2, |
| {OPT_RM|OPS_64|OPA_EA, OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm|OPAP_ShiftOp, |
| 0} } |
| }; |
| |
| /* Shifts - doubleword */ |
| static const x86_insn_info shlrd_insn[] = { |
| { CPU_386, MOD_Op1Add, 16, 0, 2, {0x0F, 0x00, 0}, 0, 3, |
| {OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_16|OPA_Spare, |
| OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm} }, |
| { CPU_386, MOD_Op1Add, 16, 0, 2, {0x0F, 0x01, 0}, 0, 3, |
| {OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_16|OPA_Spare, |
| OPT_Creg|OPS_8|OPA_None} }, |
| { CPU_386, MOD_Op1Add, 32, 0, 2, {0x0F, 0x00, 0}, 0, 3, |
| {OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_32|OPA_Spare, |
| OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm} }, |
| { CPU_386, MOD_Op1Add, 32, 0, 2, {0x0F, 0x01, 0}, 0, 3, |
| {OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_32|OPA_Spare, |
| OPT_Creg|OPS_8|OPA_None} }, |
| { CPU_Hammer|CPU_64, MOD_Op1Add, 64, 0, 2, {0x0F, 0x00, 0}, 0, 3, |
| {OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_64|OPA_Spare, |
| OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm} }, |
| { CPU_Hammer|CPU_64, MOD_Op1Add, 64, 0, 2, {0x0F, 0x01, 0}, 0, 3, |
| {OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_64|OPA_Spare, |
| OPT_Creg|OPS_8|OPA_None} } |
| }; |
| |
| /* Control transfer instructions (unconditional) */ |
| static const x86_insn_info call_insn[] = { |
| { CPU_Any, 0, 0, 0, 0, {0, 0, 0}, 0, 1, |
| {OPT_Imm|OPS_Any|OPA_JmpRel, 0, 0} }, |
| { CPU_Any, 0, 16, 0, 0, {0, 0, 0}, 0, 1, |
| {OPT_Imm|OPS_16|OPA_JmpRel, 0, 0} }, |
| { CPU_386|CPU_Not64, 0, 32, 0, 0, {0, 0, 0}, 0, 1, |
| {OPT_Imm|OPS_32|OPA_JmpRel, 0, 0} }, |
| { CPU_Hammer|CPU_64, 0, 64, 0, 0, {0, 0, 0}, 0, 1, |
| {OPT_Imm|OPS_32|OPA_JmpRel, 0, 0} }, |
| |
| { CPU_Any, 0, 16, 64, 1, {0xE8, 0x9A, 0}, 0, 1, |
| {OPT_Imm|OPS_16|OPTM_Near|OPA_JmpRel|OPAP_JmpFar, 0, 0} }, |
| { CPU_386|CPU_Not64, 0, 32, 0, 1, {0xE8, 0x9A, 0}, 0, 1, |
| {OPT_Imm|OPS_32|OPTM_Near|OPA_JmpRel|OPAP_JmpFar, 0, 0} }, |
| { CPU_Hammer|CPU_64, 0, 64, 64, 1, {0xE8, 0, 0}, 0, 1, |
| {OPT_Imm|OPS_32|OPTM_Near|OPA_JmpRel, 0, 0} }, |
| { CPU_Any, 0, 0, 64, 1, {0xE8, 0x9A, 0}, 0, 1, |
| {OPT_Imm|OPS_Any|OPTM_Near|OPA_JmpRel|OPAP_JmpFar, 0, 0} }, |
| |
| { CPU_Any, 0, 16, 0, 1, {0xFF, 0, 0}, 2, 1, {OPT_RM|OPS_16|OPA_EA, 0, 0} }, |
| { CPU_386|CPU_Not64, 0, 32, 0, 1, {0xFF, 0, 0}, 2, 1, |
| {OPT_RM|OPS_32|OPA_EA, 0, 0} }, |
| { CPU_Hammer|CPU_64, 0, 64, 64, 1, {0xFF, 0, 0}, 2, 1, |
| {OPT_RM|OPS_64|OPA_EA, 0, 0} }, |
| { CPU_Any, 0, 0, 64, 1, {0xFF, 0, 0}, 2, 1, |
| {OPT_Mem|OPS_Any|OPA_EA, 0, 0} }, |
| { CPU_Any, 0, 16, 64, 1, {0xFF, 0, 0}, 2, 1, |
| {OPT_RM|OPS_16|OPTM_Near|OPA_EA, 0, 0} }, |
| { CPU_386|CPU_Not64, 0, 32, 0, 1, {0xFF, 0, 0}, 2, 1, |
| {OPT_RM|OPS_32|OPTM_Near|OPA_EA, 0, 0} }, |
| { CPU_Hammer|CPU_64, 0, 64, 64, 1, {0xFF, 0, 0}, 2, 1, |
| {OPT_RM|OPS_64|OPTM_Near|OPA_EA, 0, 0} }, |
| { CPU_Any, 0, 0, 64, 1, {0xFF, 0, 0}, 2, 1, |
| {OPT_Mem|OPS_Any|OPTM_Near|OPA_EA, 0, 0} }, |
| |
| { CPU_Not64, 0, 16, 0, 1, {0x9A, 0, 0}, 3, 1, |
| {OPT_Imm|OPS_16|OPTM_Far|OPA_JmpRel, 0, 0} }, |
| { CPU_386|CPU_Not64, 0, 32, 0, 1, {0x9A, 0, 0}, 3, 1, |
| {OPT_Imm|OPS_32|OPTM_Far|OPA_JmpRel, 0, 0} }, |
| { CPU_Not64, 0, 0, 0, 1, {0x9A, 0, 0}, 3, 1, |
| {OPT_Imm|OPS_Any|OPTM_Far|OPA_JmpRel, 0, 0} }, |
| |
| { CPU_Any, 0, 16, 0, 1, {0xFF, 0, 0}, 3, 1, |
| {OPT_Mem|OPS_16|OPTM_Far|OPA_EA, 0, 0} }, |
| { CPU_386, 0, 32, 0, 1, {0xFF, 0, 0}, 3, 1, |
| {OPT_Mem|OPS_32|OPTM_Far|OPA_EA, 0, 0} }, |
| { CPU_Any, 0, 0, 0, 1, {0xFF, 0, 0}, 3, 1, |
| {OPT_Mem|OPS_Any|OPTM_Far|OPA_EA, 0, 0} } |
| }; |
| static const x86_insn_info jmp_insn[] = { |
| { CPU_Any, 0, 0, 0, 0, {0, 0, 0}, 0, 1, |
| {OPT_Imm|OPS_Any|OPA_JmpRel, 0, 0} }, |
| { CPU_Any, 0, 16, 0, 0, {0, 0, 0}, 0, 1, |
| {OPT_Imm|OPS_16|OPA_JmpRel, 0, 0} }, |
| { CPU_386|CPU_Not64, 0, 32, 0, 1, {0, 0, 0}, 0, 1, |
| {OPT_Imm|OPS_32|OPA_JmpRel, 0, 0} }, |
| { CPU_Hammer|CPU_64, 0, 64, 0, 1, {0, 0, 0}, 0, 1, |
| {OPT_Imm|OPS_32|OPA_JmpRel, 0, 0} }, |
| |
| { CPU_Any, 0, 0, 64, 1, {0xEB, 0, 0}, 0, 1, |
| {OPT_Imm|OPS_Any|OPTM_Short|OPA_JmpRel, 0, 0} }, |
| { CPU_Any, 0, 16, 64, 1, {0xE9, 0xEA, 0}, 0, 1, |
| {OPT_Imm|OPS_16|OPTM_Near|OPA_JmpRel|OPAP_JmpFar, 0, 0} }, |
| { CPU_386|CPU_Not64, 0, 32, 0, 1, {0xE9, 0xEA, 0}, 0, 1, |
| {OPT_Imm|OPS_32|OPTM_Near|OPA_JmpRel|OPAP_JmpFar, 0, 0} }, |
| { CPU_Hammer|CPU_64, 0, 64, 64, 1, {0xE9, 0, 0}, 0, 1, |
| {OPT_Imm|OPS_32|OPTM_Near|OPA_JmpRel, 0, 0} }, |
| { CPU_Any, 0, 0, 64, 1, {0xE9, 0xEA, 0}, 0, 1, |
| {OPT_Imm|OPS_Any|OPTM_Near|OPA_JmpRel|OPAP_JmpFar, 0, 0} }, |
| |
| { CPU_Any, 0, 16, 64, 1, {0xFF, 0, 0}, 4, 1, {OPT_RM|OPS_16|OPA_EA, 0, 0} }, |
| { CPU_386|CPU_Not64, 0, 32, 0, 1, {0xFF, 0, 0}, 4, 1, |
| {OPT_RM|OPS_32|OPA_EA, 0, 0} }, |
| { CPU_Hammer|CPU_64, 0, 64, 64, 1, {0xFF, 0, 0}, 4, 1, |
| {OPT_RM|OPS_64|OPA_EA, 0, 0} }, |
| { CPU_Any, 0, 0, 64, 1, {0xFF, 0, 0}, 4, 1, |
| {OPT_Mem|OPS_Any|OPA_EA, 0, 0} }, |
| { CPU_Any, 0, 16, 64, 1, {0xFF, 0, 0}, 4, 1, |
| {OPT_RM|OPS_16|OPTM_Near|OPA_EA, 0, 0} }, |
| { CPU_386|CPU_Not64, 0, 32, 0, 1, {0xFF, 0, 0}, 4, 1, |
| {OPT_RM|OPS_32|OPTM_Near|OPA_EA, 0, 0} }, |
| { CPU_Hammer|CPU_64, 0, 64, 64, 1, {0xFF, 0, 0}, 4, 1, |
| {OPT_RM|OPS_64|OPTM_Near|OPA_EA, 0, 0} }, |
| { CPU_Any, 0, 0, 64, 1, {0xFF, 0, 0}, 4, 1, |
| {OPT_Mem|OPS_Any|OPTM_Near|OPA_EA, 0, 0} }, |
| |
| { CPU_Not64, 0, 16, 0, 1, {0xEA, 0, 0}, 3, 1, |
| {OPT_Imm|OPS_16|OPTM_Far|OPA_JmpRel, 0, 0} }, |
| { CPU_386|CPU_Not64, 0, 32, 0, 1, {0xEA, 0, 0}, 3, 1, |
| {OPT_Imm|OPS_32|OPTM_Far|OPA_JmpRel, 0, 0} }, |
| { CPU_Not64, 0, 0, 0, 1, {0xEA, 0, 0}, 3, 1, |
| {OPT_Imm|OPS_Any|OPTM_Far|OPA_JmpRel, 0, 0} }, |
| |
| { CPU_Any, 0, 16, 0, 1, {0xFF, 0, 0}, 5, 1, |
| {OPT_Mem|OPS_16|OPTM_Far|OPA_EA, 0, 0} }, |
| { CPU_386, 0, 32, 0, 1, {0xFF, 0, 0}, 5, 1, |
| {OPT_Mem|OPS_32|OPTM_Far|OPA_EA, 0, 0} }, |
| { CPU_Any, 0, 0, 0, 1, {0xFF, 0, 0}, 5, 1, |
| {OPT_Mem|OPS_Any|OPTM_Far|OPA_EA, 0, 0} } |
| }; |
| static const x86_insn_info retnf_insn[] = { |
| { CPU_Any, MOD_Op0Add, 0, 0, 1, {0x01, 0, 0}, 0, 0, {0, 0, 0} }, |
| { CPU_Any, MOD_Op0Add, 0, 0, 1, {0x00, 0, 0}, 0, 1, |
| {OPT_Imm|OPS_16|OPS_Relaxed|OPA_Imm, 0, 0} } |
| }; |
| static const x86_insn_info enter_insn[] = { |
| { CPU_186|CPU_Not64, 0, 0, 0, 1, {0xC8, 0, 0}, 0, 2, |
| {OPT_Imm|OPS_16|OPS_Relaxed|OPA_EA, OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm, |
| 0} }, |
| { CPU_Hammer|CPU_64, 0, 64, 64, 1, {0xC8, 0, 0}, 0, 2, |
| {OPT_Imm|OPS_16|OPS_Relaxed|OPA_EA, OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm, |
| 0} } |
| }; |
| |
| /* Conditional jumps */ |
| static const x86_insn_info jcc_insn[] = { |
| { CPU_Any, 0, 0, 0, 0, {0, 0, 0}, 0, 1, |
| {OPT_Imm|OPS_Any|OPA_JmpRel, 0, 0} }, |
| { CPU_Any, 0, 16, 0, 0, {0, 0, 0}, 0, 1, |
| {OPT_Imm|OPS_16|OPA_JmpRel, 0, 0} }, |
| { CPU_386|CPU_Not64, 0, 32, 0, 0, {0, 0, 0}, 0, 1, |
| {OPT_Imm|OPS_32|OPA_JmpRel, 0, 0} }, |
| { CPU_Hammer|CPU_64, 0, 64, 0, 0, {0, 0, 0}, 0, 1, |
| {OPT_Imm|OPS_32|OPA_JmpRel, 0, 0} }, |
| |
| { CPU_Any, MOD_Op0Add, 0, 64, 1, {0x70, 0, 0}, 0, 1, |
| {OPT_Imm|OPS_Any|OPTM_Short|OPA_JmpRel, 0, 0} }, |
| { CPU_386, MOD_Op1Add, 16, 64, 2, {0x0F, 0x80, 0}, 0, 1, |
| {OPT_Imm|OPS_16|OPTM_Near|OPA_JmpRel, 0, 0} }, |
| { CPU_386|CPU_Not64, MOD_Op1Add, 32, 0, 2, {0x0F, 0x80, 0}, 0, 1, |
| {OPT_Imm|OPS_32|OPTM_Near|OPA_JmpRel, 0, 0} }, |
| { CPU_Hammer|CPU_64, MOD_Op1Add, 64, 64, 2, {0x0F, 0x80, 0}, 0, 1, |
| {OPT_Imm|OPS_32|OPTM_Near|OPA_JmpRel, 0, 0} }, |
| { CPU_386, MOD_Op1Add, 0, 64, 2, {0x0F, 0x80, 0}, 0, 1, |
| {OPT_Imm|OPS_Any|OPTM_Near|OPA_JmpRel, 0, 0} } |
| }; |
| static const x86_insn_info jcxz_insn[] = { |
| { CPU_Any, MOD_AdSizeR, 0, 0, 0, {0, 0, 0}, 0, 1, |
| {OPT_Imm|OPS_Any|OPA_JmpRel, 0, 0} }, |
| { CPU_Any, MOD_AdSizeR, 0, 64, 1, {0xE3, 0, 0}, 0, 1, |
| {OPT_Imm|OPS_Any|OPTM_Short|OPA_JmpRel, 0, 0} } |
| }; |
| |
| /* Loop instructions */ |
| static const x86_insn_info loop_insn[] = { |
| { CPU_Any, 0, 0, 0, 0, {0, 0, 0}, 0, 1, {OPT_Imm|OPS_Any|OPA_JmpRel, 0, 0} }, |
| { CPU_Not64, 0, 0, 0, 0, {0, 0, 0}, 0, 2, |
| {OPT_Imm|OPS_Any|OPA_JmpRel, OPT_Creg|OPS_16|OPA_AdSizeR, 0} }, |
| { CPU_386, 0, 0, 64, 0, {0, 0, 0}, 0, 2, |
| {OPT_Imm|OPS_Any|OPA_JmpRel, OPT_Creg|OPS_32|OPA_AdSizeR, 0} }, |
| { CPU_Hammer|CPU_64, 0, 0, 64, 0, {0, 0, 0}, 0, 2, |
| {OPT_Imm|OPS_Any|OPA_JmpRel, OPT_Creg|OPS_64|OPA_AdSizeR, 0} }, |
| |
| { CPU_Not64, MOD_Op0Add, 0, 0, 1, {0xE0, 0, 0}, 0, 1, |
| {OPT_Imm|OPS_Any|OPTM_Short|OPA_JmpRel, 0, 0} }, |
| { CPU_Any, MOD_Op0Add, 0, 64, 1, {0xE0, 0, 0}, 0, 2, |
| {OPT_Imm|OPS_Any|OPTM_Short|OPA_JmpRel, OPT_Creg|OPS_16|OPA_AdSizeR, 0} |
| }, |
| { CPU_386, MOD_Op0Add, 0, 64, 1, {0xE0, 0, 0}, 0, 2, |
| {OPT_Imm|OPS_Any|OPTM_Short|OPA_JmpRel, OPT_Creg|OPS_32|OPA_AdSizeR, 0} |
| }, |
| { CPU_Hammer|CPU_64, MOD_Op0Add, 0, 64, 1, {0xE0, 0, 0}, 0, 2, |
| {OPT_Imm|OPS_Any|OPTM_Short|OPA_JmpRel, OPT_Creg|OPS_64|OPA_AdSizeR, 0} } |
| }; |
| |
| /* Set byte on flag instructions */ |
| static const x86_insn_info setcc_insn[] = { |
| { CPU_386, MOD_Op1Add, 0, 0, 2, {0x0F, 0x90, 0}, 2, 1, |
| {OPT_RM|OPS_8|OPS_Relaxed|OPA_EA, 0, 0} } |
| }; |
| |
| /* Bit manipulation - bit tests */ |
| static const x86_insn_info bittest_insn[] = { |
| { CPU_386, MOD_Op1Add, 16, 0, 2, {0x0F, 0x00, 0}, 0, 2, |
| {OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_16|OPA_Spare, 0} }, |
| { CPU_386, MOD_Op1Add, 32, 0, 2, {0x0F, 0x00, 0}, 0, 2, |
| {OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_32|OPA_Spare, 0} }, |
| { CPU_Hammer|CPU_64, MOD_Op1Add, 64, 0, 2, {0x0F, 0x00, 0}, 0, 2, |
| {OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_64|OPA_Spare, 0} }, |
| { CPU_386, MOD_Gap0|MOD_SpAdd, 16, 0, 2, {0x0F, 0xBA, 0}, 0, 2, |
| {OPT_RM|OPS_16|OPA_EA, OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm, 0} }, |
| { CPU_386, MOD_Gap0|MOD_SpAdd, 32, 0, 2, {0x0F, 0xBA, 0}, 0, 2, |
| {OPT_RM|OPS_32|OPA_EA, OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm, 0} }, |
| { CPU_Hammer|CPU_64, MOD_Gap0|MOD_SpAdd, 64, 0, 2, {0x0F, 0xBA, 0}, 0, 2, |
| {OPT_RM|OPS_64|OPA_EA, OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm, 0} } |
| }; |
| |
| /* Bit manipulation - bit scans - also used for lar/lsl */ |
| static const x86_insn_info bsfr_insn[] = { |
| { CPU_286, MOD_Op1Add, 16, 0, 2, {0x0F, 0x00, 0}, 0, 2, |
| {OPT_Reg|OPS_16|OPA_Spare, OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, 0} }, |
| { CPU_386, MOD_Op1Add, 32, 0, 2, {0x0F, 0x00, 0}, 0, 2, |
| {OPT_Reg|OPS_32|OPA_Spare, OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, 0} }, |
| { CPU_Hammer|CPU_64, MOD_Op1Add, 64, 0, 2, {0x0F, 0x00, 0}, 0, 2, |
| {OPT_Reg|OPS_64|OPA_Spare, OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, 0} } |
| }; |
| |
| /* Interrupts and operating system instructions */ |
| static const x86_insn_info int_insn[] = { |
| { CPU_Any, 0, 0, 0, 1, {0xCD, 0, 0}, 0, 1, |
| {OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm, 0, 0} } |
| }; |
| static const x86_insn_info bound_insn[] = { |
| { CPU_186, 0, 16, 0, 1, {0x62, 0, 0}, 0, 2, |
| {OPT_Reg|OPS_16|OPA_Spare, OPT_Mem|OPS_16|OPS_Relaxed|OPA_EA, 0} }, |
| { CPU_386, 0, 32, 0, 1, {0x62, 0, 0}, 0, 2, |
| {OPT_Reg|OPS_32|OPA_Spare, OPT_Mem|OPS_32|OPS_Relaxed|OPA_EA, 0} } |
| }; |
| |
| /* Protection control */ |
| static const x86_insn_info arpl_insn[] = { |
| { CPU_286|CPU_Prot, 0, 0, 0, 1, {0x63, 0, 0}, 0, 2, |
| {OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_16|OPA_Spare, 0} } |
| }; |
| static const x86_insn_info str_insn[] = { |
| { CPU_Hammer, 0, 16, 0, 2, {0x0F, 0x00, 0}, 1, 1, |
| {OPT_Reg|OPS_16|OPA_EA, 0, 0} }, |
| { CPU_Hammer, 0, 32, 0, 2, {0x0F, 0x00, 0}, 1, 1, |
| {OPT_Reg|OPS_32|OPA_EA, 0, 0} }, |
| { CPU_Hammer|CPU_64, 0, 64, 0, 2, {0x0F, 0x00, 0}, 1, 1, |
| {OPT_Reg|OPS_64|OPA_EA, 0, 0} }, |
| { CPU_286, MOD_Op1Add|MOD_SpAdd, 0, 0, 2, {0x0F, 0x00, 0}, 0, 1, |
| {OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, 0, 0} } |
| }; |
| static const x86_insn_info prot286_insn[] = { |
| { CPU_286, MOD_Op1Add|MOD_SpAdd, 0, 0, 2, {0x0F, 0x00, 0}, 0, 1, |
| {OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, 0, 0} } |
| }; |
| static const x86_insn_info sldtmsw_insn[] = { |
| { CPU_286, MOD_Op1Add|MOD_SpAdd, 0, 0, 2, {0x0F, 0x00, 0}, 0, 1, |
| {OPT_Mem|OPS_16|OPS_Relaxed|OPA_EA, 0, 0} }, |
| { CPU_386, MOD_Op1Add|MOD_SpAdd, 0, 0, 2, {0x0F, 0x00, 0}, 0, 1, |
| {OPT_Mem|OPS_32|OPS_Relaxed|OPA_EA, 0, 0} }, |
| { CPU_Hammer|CPU_64, MOD_Op1Add|MOD_SpAdd, 0, 0, 2, {0x0F, 0x00, 0}, 0, 1, |
| {OPT_Mem|OPS_64|OPS_Relaxed|OPA_EA, 0, 0} }, |
| { CPU_286, MOD_Op1Add|MOD_SpAdd, 16, 0, 2, {0x0F, 0x00, 0}, 0, 1, |
| {OPT_Reg|OPS_16|OPA_EA, 0, 0} }, |
| { CPU_386, MOD_Op1Add|MOD_SpAdd, 32, 0, 2, {0x0F, 0x00, 0}, 0, 1, |
| {OPT_Reg|OPS_32|OPA_EA, 0, 0} }, |
| { CPU_Hammer|CPU_64, MOD_Op1Add|MOD_SpAdd, 64, 0, 2, {0x0F, 0x00, 0}, 0, 1, |
| {OPT_Reg|OPS_64|OPA_EA, 0, 0} } |
| }; |
| |
| /* Floating point instructions - load/store with pop (integer and normal) */ |
| static const x86_insn_info fldstp_insn[] = { |
| { CPU_FPU, MOD_Gap0|MOD_SpAdd, 0, 0, 1, {0xD9, 0, 0}, 0, 1, |
| {OPT_Mem|OPS_32|OPA_EA, 0, 0} }, |
| { CPU_FPU, MOD_Gap0|MOD_SpAdd, 0, 0, 1, {0xDD, 0, 0}, 0, 1, |
| {OPT_Mem|OPS_64|OPA_EA, 0, 0} }, |
| { CPU_FPU, MOD_Gap0|MOD_Gap1|MOD_SpAdd, 0, 0, 1, {0xDB, 0, 0}, 0, 1, |
| {OPT_Mem|OPS_80|OPA_EA, 0, 0} }, |
| { CPU_FPU, MOD_Op1Add, 0, 0, 2, {0xD9, 0x00, 0}, 0, 1, |
| {OPT_Reg|OPS_80|OPA_Op1Add, 0, 0} } |
| }; |
| static const x86_insn_info fildstp_insn[] = { |
| { CPU_FPU, MOD_SpAdd, 0, 0, 1, {0xDF, 0, 0}, 0, 1, |
| {OPT_Mem|OPS_16|OPA_EA, 0, 0} }, |
| { CPU_FPU, MOD_SpAdd, 0, 0, 1, {0xDB, 0, 0}, 0, 1, |
| {OPT_Mem|OPS_32|OPA_EA, 0, 0} }, |
| { CPU_FPU, MOD_Gap0|MOD_SpAdd, 0, 0, 1, {0xDF, 0, 0}, 0, 1, |
| {OPT_Mem|OPS_64|OPA_EA, 0, 0} } |
| }; |
| static const x86_insn_info fbldstp_insn[] = { |
| { CPU_FPU, MOD_SpAdd, 0, 0, 1, {0xDF, 0, 0}, 0, 1, |
| {OPT_Mem|OPS_80|OPS_Relaxed|OPA_EA, 0, 0} } |
| }; |
| /* Floating point instructions - store (normal) */ |
| static const x86_insn_info fst_insn[] = { |
| { CPU_FPU, 0, 0, 0, 1, {0xD9, 0, 0}, 2, 1, {OPT_Mem|OPS_32|OPA_EA, 0, 0} }, |
| { CPU_FPU, 0, 0, 0, 1, {0xDD, 0, 0}, 2, 1, {OPT_Mem|OPS_64|OPA_EA, 0, 0} }, |
| { CPU_FPU, 0, 0, 0, 2, {0xDD, 0xD0, 0}, 0, 1, |
| {OPT_Reg|OPS_80|OPA_Op1Add, 0, 0} } |
| }; |
| /* Floating point instructions - exchange (with ST0) */ |
| static const x86_insn_info fxch_insn[] = { |
| { CPU_FPU, 0, 0, 0, 2, {0xD9, 0xC8, 0}, 0, 1, |
| {OPT_Reg|OPS_80|OPA_Op1Add, 0, 0} }, |
| { CPU_FPU, 0, 0, 0, 2, {0xD9, 0xC8, 0}, 0, 2, |
| {OPT_ST0|OPS_80|OPA_None, OPT_Reg|OPS_80|OPA_Op1Add, 0} }, |
| { CPU_FPU, 0, 0, 0, 2, {0xD9, 0xC8, 0}, 0, 2, |
| {OPT_Reg|OPS_80|OPA_Op1Add, OPT_ST0|OPS_80|OPA_None, 0} }, |
| { CPU_FPU, 0, 0, 0, 2, {0xD9, 0xC9, 0}, 0, 0, {0, 0, 0} } |
| }; |
| /* Floating point instructions - comparisons */ |
| static const x86_insn_info fcom_insn[] = { |
| { CPU_FPU, MOD_Gap0|MOD_SpAdd, 0, 0, 1, {0xD8, 0, 0}, 0, 1, |
| {OPT_Mem|OPS_32|OPA_EA, 0, 0} }, |
| { CPU_FPU, MOD_Gap0|MOD_SpAdd, 0, 0, 1, {0xDC, 0, 0}, 0, 1, |
| {OPT_Mem|OPS_64|OPA_EA, 0, 0} }, |
| { CPU_FPU, MOD_Op1Add, 0, 0, 2, {0xD8, 0x00, 0}, 0, 1, |
| {OPT_Reg|OPS_80|OPA_Op1Add, 0, 0} }, |
| { CPU_FPU, MOD_Op1Add, 0, 0, 2, {0xD8, 0x00, 0}, 0, 2, |
| {OPT_ST0|OPS_80|OPA_None, OPT_Reg|OPS_80|OPA_Op1Add, 0} } |
| }; |
| /* Floating point instructions - extended comparisons */ |
| static const x86_insn_info fcom2_insn[] = { |
| { CPU_286|CPU_FPU, MOD_Op0Add|MOD_Op1Add, 0, 0, 2, {0x00, 0x00, 0}, 0, 1, |
| {OPT_Reg|OPS_80|OPA_Op1Add, 0, 0} }, |
| { CPU_286|CPU_FPU, MOD_Op0Add|MOD_Op1Add, 0, 0, 2, {0x00, 0x00, 0}, 0, 2, |
| {OPT_ST0|OPS_80|OPA_None, OPT_Reg|OPS_80|OPA_Op1Add, 0} } |
| }; |
| /* Floating point instructions - arithmetic */ |
| static const x86_insn_info farith_insn[] = { |
| { CPU_FPU, MOD_Gap0|MOD_Gap1|MOD_SpAdd, 0, 0, 1, {0xD8, 0, 0}, 0, 1, |
| {OPT_Mem|OPS_32|OPA_EA, 0, 0} }, |
| { CPU_FPU, MOD_Gap0|MOD_Gap1|MOD_SpAdd, 0, 0, 1, {0xDC, 0, 0}, 0, 1, |
| {OPT_Mem|OPS_64|OPA_EA, 0, 0} }, |
| { CPU_FPU, MOD_Gap0|MOD_Op1Add, 0, 0, 2, {0xD8, 0x00, 0}, 0, 1, |
| {OPT_Reg|OPS_80|OPA_Op1Add, 0, 0} }, |
| { CPU_FPU, MOD_Gap0|MOD_Op1Add, 0, 0, 2, {0xD8, 0x00, 0}, 0, 2, |
| {OPT_ST0|OPS_80|OPA_None, OPT_Reg|OPS_80|OPA_Op1Add, 0} }, |
| { CPU_FPU, MOD_Op1Add, 0, 0, 2, {0xDC, 0x00, 0}, 0, 1, |
| {OPT_Reg|OPS_80|OPTM_To|OPA_Op1Add, 0, 0} }, |
| { CPU_FPU, MOD_Op1Add, 0, 0, 2, {0xDC, 0x00, 0}, 0, 2, |
| {OPT_Reg|OPS_80|OPA_Op1Add, OPT_ST0|OPS_80|OPA_None, 0} } |
| }; |
| static const x86_insn_info farithp_insn[] = { |
| { CPU_FPU, MOD_Op1Add, 0, 0, 2, {0xDE, 0x01, 0}, 0, 0, {0, 0, 0} }, |
| { CPU_FPU, MOD_Op1Add, 0, 0, 2, {0xDE, 0x00, 0}, 0, 1, |
| {OPT_Reg|OPS_80|OPA_Op1Add, 0, 0} }, |
| { CPU_FPU, MOD_Op1Add, 0, 0, 2, {0xDE, 0x00, 0}, 0, 2, |
| {OPT_Reg|OPS_80|OPA_Op1Add, OPT_ST0|OPS_80|OPA_None, 0} } |
| }; |
| /* Floating point instructions - integer arith/store wo pop/compare */ |
| static const x86_insn_info fiarith_insn[] = { |
| { CPU_FPU, MOD_Op0Add|MOD_SpAdd, 0, 0, 1, {0x04, 0, 0}, 0, 1, |
| {OPT_Mem|OPS_16|OPA_EA, 0, 0} }, |
| { CPU_FPU, MOD_Op0Add|MOD_SpAdd, 0, 0, 1, {0x00, 0, 0}, 0, 1, |
| {OPT_Mem|OPS_32|OPA_EA, 0, 0} } |
| }; |
| /* Floating point instructions - processor control */ |
| static const x86_insn_info fldnstcw_insn[] = { |
| { CPU_FPU, MOD_SpAdd, 0, 0, 1, {0xD9, 0, 0}, 0, 1, |
| {OPT_Mem|OPS_16|OPS_Relaxed|OPA_EA, 0, 0} } |
| }; |
| static const x86_insn_info fstcw_insn[] = { |
| { CPU_FPU, 0, 0, 0, 2, {0x9B, 0xD9, 0}, 7, 1, |
| {OPT_Mem|OPS_16|OPS_Relaxed|OPA_EA, 0, 0} } |
| }; |
| static const x86_insn_info fnstsw_insn[] = { |
| { CPU_FPU, 0, 0, 0, 1, {0xDD, 0, 0}, 7, 1, |
| {OPT_Mem|OPS_16|OPS_Relaxed|OPA_EA, 0, 0} }, |
| { CPU_FPU, 0, 0, 0, 2, {0xDF, 0xE0, 0}, 0, 1, |
| {OPT_Areg|OPS_16|OPA_None, 0, 0} } |
| }; |
| static const x86_insn_info fstsw_insn[] = { |
| { CPU_FPU, 0, 0, 0, 2, {0x9B, 0xDD, 0}, 7, 1, |
| {OPT_Mem|OPS_16|OPS_Relaxed|OPA_EA, 0, 0} }, |
| { CPU_FPU, 0, 0, 0, 3, {0x9B, 0xDF, 0xE0}, 0, 1, |
| {OPT_Areg|OPS_16|OPA_None, 0, 0} } |
| }; |
| static const x86_insn_info ffree_insn[] = { |
| { CPU_FPU, MOD_Op0Add, 0, 0, 2, {0x00, 0xC0, 0}, 0, 1, |
| {OPT_Reg|OPS_80|OPA_Op1Add, 0, 0} } |
| }; |
| |
| /* 486 extensions */ |
| static const x86_insn_info bswap_insn[] = { |
| { CPU_486, 0, 32, 0, 2, {0x0F, 0xC8, 0}, 0, 1, |
| {OPT_Reg|OPS_32|OPA_Op1Add, 0, 0} }, |
| { CPU_Hammer|CPU_64, 0, 64, 0, 2, {0x0F, 0xC8, 0}, 0, 1, |
| {OPT_Reg|OPS_64|OPA_Op1Add, 0, 0} } |
| }; |
| static const x86_insn_info cmpxchgxadd_insn[] = { |
| { CPU_486, MOD_Op1Add, 0, 0, 2, {0x0F, 0x00, 0}, 0, 2, |
| {OPT_RM|OPS_8|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_8|OPA_Spare, 0} }, |
| { CPU_486, MOD_Op1Add, 16, 0, 2, {0x0F, 0x01, 0}, 0, 2, |
| {OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_16|OPA_Spare, 0} }, |
| { CPU_486, MOD_Op1Add, 32, 0, 2, {0x0F, 0x01, 0}, 0, 2, |
| {OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_32|OPA_Spare, 0} }, |
| { CPU_Hammer|CPU_64, MOD_Op1Add, 64, 0, 2, {0x0F, 0x01, 0}, 0, 2, |
| {OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_64|OPA_Spare, 0} } |
| }; |
| |
| /* Pentium extensions */ |
| static const x86_insn_info cmpxchg8b_insn[] = { |
| { CPU_586, 0, 0, 0, 2, {0x0F, 0xC7, 0}, 1, 1, |
| {OPT_Mem|OPS_64|OPS_Relaxed|OPA_EA, 0, 0} } |
| }; |
| |
| /* Pentium II/Pentium Pro extensions */ |
| static const x86_insn_info cmovcc_insn[] = { |
| { CPU_686, MOD_Op1Add, 16, 0, 2, {0x0F, 0x40, 0}, 0, 2, |
| {OPT_Reg|OPS_16|OPA_Spare, OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, 0} }, |
| { CPU_686, MOD_Op1Add, 32, 0, 2, {0x0F, 0x40, 0}, 0, 2, |
| {OPT_Reg|OPS_32|OPA_Spare, OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, 0} }, |
| { CPU_Hammer|CPU_64, MOD_Op1Add, 64, 0, 2, {0x0F, 0x40, 0}, 0, 2, |
| {OPT_Reg|OPS_64|OPA_Spare, OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, 0} } |
| }; |
| static const x86_insn_info fcmovcc_insn[] = { |
| { CPU_686|CPU_FPU, MOD_Op0Add|MOD_Op1Add, 0, 0, 2, {0x00, 0x00, 0}, 0, 2, |
| {OPT_ST0|OPS_80|OPA_None, OPT_Reg|OPS_80|OPA_Op1Add, 0} } |
| }; |
| |
| /* Pentium4 extensions */ |
| static const x86_insn_info movnti_insn[] = { |
| { CPU_P4, 0, 0, 0, 2, {0x0F, 0xC3, 0}, 0, 2, |
| {OPT_Mem|OPS_32|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_32|OPA_Spare, 0} }, |
| { CPU_Hammer|CPU_64, 0, 64, 0, 2, {0x0F, 0xC3, 0}, 0, 2, |
| {OPT_Mem|OPS_64|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_64|OPA_Spare, 0} } |
| }; |
| static const x86_insn_info clflush_insn[] = { |
| { CPU_P3, 0, 0, 0, 2, {0x0F, 0xAE, 0}, 7, 1, |
| {OPT_Mem|OPS_8|OPS_Relaxed|OPA_EA, 0, 0} } |
| }; |
| |
| /* MMX/SSE2 instructions */ |
| static const x86_insn_info movd_insn[] = { |
| { CPU_MMX, 0, 0, 0, 2, {0x0F, 0x6E, 0}, 0, 2, |
| {OPT_SIMDReg|OPS_64|OPA_Spare, OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, 0} }, |
| { CPU_MMX|CPU_Hammer|CPU_64, 0, 64, 0, 2, {0x0F, 0x6E, 0}, 0, 2, |
| {OPT_SIMDReg|OPS_64|OPA_Spare, OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, 0} }, |
| { CPU_MMX, 0, 0, 0, 2, {0x0F, 0x7E, 0}, 0, 2, |
| {OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, OPT_SIMDReg|OPS_64|OPA_Spare, 0} }, |
| { CPU_MMX|CPU_Hammer|CPU_64, 0, 64, 0, 2, {0x0F, 0x7E, 0}, 0, 2, |
| {OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, OPT_SIMDReg|OPS_64|OPA_Spare, 0} }, |
| { CPU_SSE2, 0, 0, 0, 3, {0x66, 0x0F, 0x6E}, 0, 2, |
| {OPT_SIMDReg|OPS_128|OPA_Spare, OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, 0} }, |
| { CPU_SSE2|CPU_Hammer|CPU_64, 0, 64, 0, 3, {0x66, 0x0F, 0x6E}, 0, 2, |
| {OPT_SIMDReg|OPS_128|OPA_Spare, OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, 0} }, |
| { CPU_SSE2, 0, 0, 0, 3, {0x66, 0x0F, 0x7E}, 0, 2, |
| {OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, OPT_SIMDReg|OPS_128|OPA_Spare, 0} }, |
| { CPU_SSE2|CPU_Hammer|CPU_64, 0, 64, 0, 3, {0x66, 0x0F, 0x7E}, 0, 2, |
| {OPT_RM|OPS_64|OPS_Relaxed|OPA_EA, OPT_SIMDReg|OPS_128|OPA_Spare, 0} } |
| }; |
| static const x86_insn_info movq_insn[] = { |
| { CPU_MMX, 0, 0, 0, 2, {0x0F, 0x6F, 0}, 0, 2, |
| {OPT_SIMDReg|OPS_64|OPA_Spare, OPT_SIMDRM|OPS_64|OPS_Relaxed|OPA_EA, 0} |
| }, |
| { CPU_MMX, 0, 0, 0, 2, {0x0F, 0x7F, 0}, 0, 2, |
| {OPT_SIMDRM|OPS_64|OPS_Relaxed|OPA_EA, OPT_SIMDReg|OPS_64|OPA_Spare, 0} |
| }, |
| { CPU_SSE2, 0, 0, 0, 3, {0xF3, 0x0F, 0x7E}, 0, 2, |
| {OPT_SIMDReg|OPS_128|OPA_Spare, OPT_SIMDReg|OPS_128|OPA_EA, 0} }, |
| { CPU_SSE2, 0, 0, 0, 3, {0xF3, 0x0F, 0x7E}, 0, 2, |
| {OPT_SIMDReg|OPS_128|OPA_Spare, OPT_SIMDRM|OPS_64|OPS_Relaxed|OPA_EA, 0} |
| }, |
| { CPU_SSE2, 0, 0, 0, 3, {0x66, 0x0F, 0xD6}, 0, 2, |
| {OPT_SIMDRM|OPS_64|OPS_Relaxed|OPA_EA, OPT_SIMDReg|OPS_128|OPA_Spare, 0} |
| } |
| }; |
| static const x86_insn_info mmxsse2_insn[] = { |
| { CPU_MMX, MOD_Op1Add, 0, 0, 2, {0x0F, 0x00, 0}, 0, 2, |
| {OPT_SIMDReg|OPS_64|OPA_Spare, OPT_SIMDRM|OPS_64|OPS_Relaxed|OPA_EA, 0} |
| }, |
| { CPU_SSE2, MOD_Op2Add, 0, 0, 3, {0x66, 0x0F, 0x00}, 0, 2, |
| {OPT_SIMDReg|OPS_128|OPA_Spare, OPT_SIMDRM|OPS_128|OPS_Relaxed|OPA_EA, 0} |
| } |
| }; |
| static const x86_insn_info pshift_insn[] = { |
| { CPU_MMX, MOD_Op1Add, 0, 0, 2, {0x0F, 0x00, 0}, 0, 2, |
| {OPT_SIMDReg|OPS_64|OPA_Spare, OPT_SIMDRM|OPS_64|OPS_Relaxed|OPA_EA, 0} |
| }, |
| { CPU_MMX, MOD_Gap0|MOD_Op1Add|MOD_SpAdd, 0, 0, 2, {0x0F, 0x00, 0}, 0, |
| 2, {OPT_SIMDReg|OPS_64|OPA_EA, OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm, 0} }, |
| { CPU_SSE2, MOD_Op2Add, 0, 0, 3, {0x66, 0x0F, 0x00}, 0, 2, |
| {OPT_SIMDReg|OPS_128|OPA_Spare, OPT_SIMDRM|OPS_128|OPS_Relaxed|OPA_EA, 0} |
| }, |
| { CPU_SSE2, MOD_Gap0|MOD_Op2Add|MOD_SpAdd, 0, 0, 3, {0x66, 0x0F, 0x00}, 0, 2, |
| {OPT_SIMDReg|OPS_128|OPA_EA, OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm, 0} } |
| }; |
| |
| /* PIII (Katmai) new instructions / SIMD instructiosn */ |
| static const x86_insn_info sseps_insn[] = { |
| { CPU_SSE, MOD_Op1Add, 0, 0, 2, {0x0F, 0x00, 0}, 0, 2, |
| {OPT_SIMDReg|OPS_128|OPA_Spare, OPT_SIMDRM|OPS_128|OPS_Relaxed|OPA_EA, 0} |
| } |
| }; |
| static const x86_insn_info ssess_insn[] = { |
| { CPU_SSE, MOD_Op0Add|MOD_Op2Add, 0, 0, 3, {0x00, 0x0F, 0x00}, 0, 2, |
| {OPT_SIMDReg|OPS_128|OPA_Spare, OPT_SIMDRM|OPS_128|OPS_Relaxed|OPA_EA, 0} |
| } |
| }; |
| static const x86_insn_info ssecmpps_insn[] = { |
| { CPU_SSE, MOD_Imm8, 0, 0, 2, {0x0F, 0xC2, 0}, 0, 2, |
| {OPT_SIMDReg|OPS_128|OPA_Spare, OPT_SIMDRM|OPS_128|OPS_Relaxed|OPA_EA, 0} |
| } |
| }; |
| static const x86_insn_info ssecmpss_insn[] = { |
| { CPU_SSE, MOD_Op0Add|MOD_Imm8, 0, 0, 3, {0x00, 0x0F, 0xC2}, 0, 2, |
| {OPT_SIMDReg|OPS_128|OPA_Spare, OPT_SIMDRM|OPS_128|OPS_Relaxed|OPA_EA, 0} |
| } |
| }; |
| static const x86_insn_info ssepsimm_insn[] = { |
| { CPU_SSE, MOD_Op1Add, 0, 0, 2, {0x0F, 0x00, 0}, 0, 3, |
| {OPT_SIMDReg|OPS_128|OPA_Spare, OPT_SIMDRM|OPS_128|OPS_Relaxed|OPA_EA, |
| OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm} } |
| }; |
| static const x86_insn_info ssessimm_insn[] = { |
| { CPU_SSE, MOD_Op0Add|MOD_Op2Add, 0, 0, 3, {0x00, 0x0F, 0x00}, 0, 3, |
| {OPT_SIMDReg|OPS_128|OPA_Spare, OPT_SIMDRM|OPS_128|OPS_Relaxed|OPA_EA, |
| OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm} } |
| }; |
| static const x86_insn_info ldstmxcsr_insn[] = { |
| { CPU_SSE, MOD_SpAdd, 0, 0, 2, {0x0F, 0xAE, 0}, 0, 1, |
| {OPT_Mem|OPS_32|OPS_Relaxed|OPA_EA, 0, 0} } |
| }; |
| static const x86_insn_info maskmovq_insn[] = { |
| { CPU_P3|CPU_MMX, 0, 0, 0, 2, {0x0F, 0xF7, 0}, 0, 2, |
| {OPT_SIMDReg|OPS_64|OPA_Spare, OPT_SIMDReg|OPS_64|OPA_EA, 0} } |
| }; |
| static const x86_insn_info movaups_insn[] = { |
| { CPU_SSE, MOD_Op1Add, 0, 0, 2, {0x0F, 0x00, 0}, 0, 2, |
| {OPT_SIMDReg|OPS_128|OPA_Spare, OPT_SIMDRM|OPS_128|OPS_Relaxed|OPA_EA, 0} |
| }, |
| { CPU_SSE, MOD_Op1Add, 0, 0, 2, {0x0F, 0x01, 0}, 0, 2, |
| {OPT_SIMDRM|OPS_128|OPS_Relaxed|OPA_EA, OPT_SIMDReg|OPS_128|OPA_Spare, 0} |
| } |
| }; |
| static const x86_insn_info movhllhps_insn[] = { |
| { CPU_SSE, MOD_Op1Add, 0, 0, 2, {0x0F, 0x00, 0}, 0, 2, |
| {OPT_SIMDReg|OPS_128|OPA_Spare, OPT_SIMDReg|OPS_128|OPA_EA, 0} } |
| }; |
| static const x86_insn_info movhlps_insn[] = { |
| { CPU_SSE, MOD_Op1Add, 0, 0, 2, {0x0F, 0x00, 0}, 0, 2, |
| {OPT_SIMDReg|OPS_128|OPA_Spare, OPT_Mem|OPS_64|OPS_Relaxed|OPA_EA, 0} }, |
| { CPU_SSE, MOD_Op1Add, 0, 0, 2, {0x0F, 0x01, 0}, 0, 2, |
| {OPT_Mem|OPS_64|OPS_Relaxed|OPA_EA, OPT_SIMDReg|OPS_128|OPA_Spare, 0} } |
| }; |
| static const x86_insn_info movmskps_insn[] = { |
| { CPU_SSE, 0, 0, 0, 2, {0x0F, 0x50, 0}, 0, 2, |
| {OPT_Reg|OPS_32|OPA_EA, OPT_SIMDReg|OPS_128|OPA_Spare, 0} } |
| }; |
| static const x86_insn_info movntps_insn[] = { |
| { CPU_SSE, 0, 0, 0, 2, {0x0F, 0x2B, 0}, 0, 2, |
| {OPT_Mem|OPS_128|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_128|OPA_Spare, 0} } |
| }; |
| static const x86_insn_info movntq_insn[] = { |
| { CPU_SSE, 0, 0, 0, 2, {0x0F, 0xE7, 0}, 0, 2, |
| {OPT_Mem|OPS_64|OPS_Relaxed|OPA_EA, OPT_SIMDReg|OPS_128|OPA_Spare, 0} } |
| }; |
| static const x86_insn_info movss_insn[] = { |
| { CPU_SSE, 0, 0, 0, 3, {0xF3, 0x0F, 0x10}, 0, 2, |
| {OPT_SIMDReg|OPS_128|OPA_Spare, OPT_SIMDReg|OPS_128|OPA_EA, 0} }, |
| { CPU_SSE, 0, 0, 0, 3, {0xF3, 0x0F, 0x10}, 0, 2, |
| {OPT_SIMDReg|OPS_128|OPA_Spare, OPT_Mem|OPS_64|OPS_Relaxed|OPA_EA, 0} }, |
| { CPU_SSE, 0, 0, 0, 3, {0xF3, 0x0F, 0x11}, 0, 2, |
| {OPT_Mem|OPS_64|OPS_Relaxed|OPA_EA, OPT_SIMDReg|OPS_128|OPA_Spare, 0} } |
| }; |
| static const x86_insn_info pextrw_insn[] = { |
| { CPU_P3|CPU_MMX, 0, 0, 0, 2, {0x0F, 0xC5, 0}, 0, 3, |
| {OPT_Reg|OPS_32|OPA_EA, OPT_SIMDReg|OPS_64|OPA_Spare, |
| OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm} }, |
| { CPU_SSE2, 0, 0, 0, 3, {0x66, 0x0F, 0xC5}, 0, 3, |
| {OPT_Reg|OPS_32|OPA_EA, OPT_SIMDReg|OPS_128|OPA_Spare, |
| OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm} } |
| }; |
| static const x86_insn_info pinsrw_insn[] = { |
| { CPU_P3|CPU_MMX, 0, 0, 0, 2, {0x0F, 0xC4, 0}, 0, 3, |
| {OPT_SIMDReg|OPS_64|OPA_Spare, OPT_Reg|OPS_32|OPA_EA, |
| OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm} }, |
| { CPU_P3|CPU_MMX, 0, 0, 0, 2, {0x0F, 0xC4, 0}, 0, 3, |
| {OPT_SIMDReg|OPS_64|OPA_Spare, OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, |
| OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm} }, |
| { CPU_SSE2, 0, 0, 0, 3, {0x66, 0x0F, 0xC4}, 0, 3, |
| {OPT_SIMDReg|OPS_128|OPA_Spare, OPT_Reg|OPS_32|OPA_EA, |
| OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm} }, |
| { CPU_SSE2, 0, 0, 0, 3, {0x66, 0x0F, 0xC4}, 0, 3, |
| {OPT_SIMDReg|OPS_64|OPA_Spare, OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, |
| OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm} } |
| }; |
| static const x86_insn_info pmovmskb_insn[] = { |
| { CPU_P3|CPU_MMX, 0, 0, 0, 2, {0x0F, 0xD7, 0}, 0, 2, |
| {OPT_Reg|OPS_32|OPA_EA, OPT_SIMDReg|OPS_64|OPA_Spare, 0} }, |
| { CPU_SSE2, 0, 0, 0, 3, {0x66, 0x0F, 0xD7}, 0, 2, |
| {OPT_Reg|OPS_32|OPA_EA, OPT_SIMDReg|OPS_128|OPA_Spare, 0} } |
| }; |
| static const x86_insn_info pshufw_insn[] = { |
| { CPU_P3|CPU_MMX, 0, 0, 0, 2, {0x0F, 0x70, 0}, 0, 3, |
| {OPT_SIMDReg|OPS_64|OPA_Spare, OPT_SIMDRM|OPS_64|OPS_Relaxed|OPA_EA, |
| OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm} } |
| }; |
| |
| /* SSE2 instructions */ |
| static const x86_insn_info cmpsd_insn[] = { |
| { CPU_Any, 0, 32, 0, 1, {0xA7, 0, 0}, 0, 0, {0, 0, 0} }, |
| { CPU_SSE2, 0, 0, 0, 3, {0xF2, 0x0F, 0xC2}, 0, 3, |
| {OPT_SIMDReg|OPS_128|OPA_Spare, OPT_SIMDRM|OPS_128|OPS_Relaxed|OPA_EA, |
| OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm} } |
| }; |
| static const x86_insn_info movaupd_insn[] = { |
| { CPU_SSE2, MOD_Op2Add, 0, 0, 3, {0x66, 0x0F, 0x00}, 0, 2, |
| {OPT_SIMDReg|OPS_128|OPA_Spare, OPT_SIMDRM|OPS_128|OPS_Relaxed|OPA_EA, 0} |
| }, |
| { CPU_SSE2, MOD_Op2Add, 0, 0, 3, {0x66, 0x0F, 0x01}, 0, 2, |
| {OPT_SIMDRM|OPS_128|OPS_Relaxed|OPA_EA, OPT_SIMDReg|OPS_128|OPA_Spare, 0} |
| } |
| }; |
| static const x86_insn_info movhlpd_insn[] = { |
| { CPU_SSE2, MOD_Op2Add, 0, 0, 3, {0x66, 0x0F, 0x00}, 0, 2, |
| {OPT_SIMDReg|OPS_128|OPA_Spare, OPT_Mem|OPS_64|OPS_Relaxed|OPA_EA, 0} }, |
| { CPU_SSE2, MOD_Op2Add, 0, 0, 3, {0x66, 0x0F, 0x01}, 0, 2, |
| {OPT_Mem|OPS_64|OPS_Relaxed|OPA_EA, OPT_SIMDReg|OPS_128|OPA_Spare, 0} } |
| }; |
| static const x86_insn_info movmskpd_insn[] = { |
| { CPU_SSE2, 0, 0, 0, 3, {0x66, 0x0F, 0x50}, 0, 2, |
| {OPT_Reg|OPS_32|OPA_EA, OPT_SIMDReg|OPS_128|OPA_Spare, 0} } |
| }; |
| static const x86_insn_info movntpddq_insn[] = { |
| { CPU_SSE2, MOD_Op2Add, 0, 0, 3, {0x66, 0x0F, 0x00}, 0, 2, |
| {OPT_Mem|OPS_128|OPS_Relaxed|OPA_EA, OPT_SIMDReg|OPS_128|OPA_Spare, 0} } |
| }; |
| static const x86_insn_info movsd_insn[] = { |
| { CPU_Any, 0, 32, 0, 1, {0xA5, 0, 0}, 0, 0, {0, 0, 0} }, |
| { CPU_SSE2, 0, 0, 0, 3, {0xF2, 0x0F, 0x10}, 0, 2, |
| {OPT_SIMDReg|OPS_128|OPA_Spare, OPT_SIMDReg|OPS_128|OPA_EA, 0} }, |
| { CPU_SSE2, 0, 0, 0, 3, {0xF2, 0x0F, 0x10}, 0, 2, |
| {OPT_SIMDReg|OPS_128|OPA_Spare, OPT_Mem|OPS_64|OPS_Relaxed|OPA_EA, 0} }, |
| { CPU_SSE2, 0, 0, 0, 3, {0xF2, 0x0F, 0x11}, 0, 2, |
| {OPT_Mem|OPS_64|OPS_Relaxed|OPA_EA, OPT_SIMDReg|OPS_128|OPA_Spare, 0} } |
| }; |
| static const x86_insn_info maskmovdqu_insn[] = { |
| { CPU_SSE2, 0, 0, 0, 3, {0x66, 0x0F, 0xF7}, 0, 2, |
| {OPT_SIMDReg|OPS_128|OPA_Spare, OPT_SIMDReg|OPS_128|OPA_EA, 0} } |
| }; |
| static const x86_insn_info movdqau_insn[] = { |
| { CPU_SSE2, MOD_Op0Add, 0, 0, 3, {0x00, 0x0F, 0x6F}, 0, 2, |
| {OPT_SIMDReg|OPS_128|OPA_Spare, OPT_SIMDRM|OPS_128|OPS_Relaxed|OPA_EA, 0} |
| }, |
| { CPU_SSE2, MOD_Op0Add, 0, 0, 3, {0x00, 0x0F, 0x7F}, 0, 2, |
| {OPT_SIMDRM|OPS_128|OPS_Relaxed|OPA_EA, OPT_SIMDReg|OPS_128|OPA_Spare, 0} |
| } |
| }; |
| static const x86_insn_info movdq2q_insn[] = { |
| { CPU_SSE2, 0, 0, 0, 3, {0xF2, 0x0F, 0xD6}, 0, 2, |
| {OPT_SIMDReg|OPS_64|OPA_Spare, OPT_SIMDReg|OPS_128|OPA_EA, 0} } |
| }; |
| static const x86_insn_info movq2dq_insn[] = { |
| { CPU_SSE2, 0, 0, 0, 3, {0xF3, 0x0F, 0xD6}, 0, 2, |
| {OPT_SIMDReg|OPS_128|OPA_Spare, OPT_SIMDReg|OPS_64|OPA_EA, 0} } |
| }; |
| static const x86_insn_info pslrldq_insn[] = { |
| { CPU_SSE2, MOD_SpAdd, 0, 0, 3, {0x66, 0x0F, 0x73}, 0, 2, |
| {OPT_SIMDReg|OPS_128|OPA_EA, OPT_Imm|OPS_8|OPS_Relaxed|OPA_Imm, 0} } |
| }; |
| |
| /* AMD 3DNow! instructions */ |
| static const x86_insn_info now3d_insn[] = { |
| { CPU_3DNow, MOD_Imm8, 0, 0, 2, {0x0F, 0x0F, 0}, 0, 2, |
| {OPT_SIMDReg|OPS_64|OPA_Spare, OPT_SIMDRM|OPS_64|OPS_Relaxed|OPA_EA, 0} } |
| }; |
| |
| /* Cyrix MMX instructions */ |
| static const x86_insn_info cyrixmmx_insn[] = { |
| { CPU_Cyrix|CPU_MMX, MOD_Op1Add, 0, 0, 2, {0x0F, 0x00, 0}, 0, 2, |
| {OPT_SIMDReg|OPS_64|OPA_Spare, OPT_SIMDRM|OPS_64|OPS_Relaxed|OPA_EA, 0} } |
| }; |
| static const x86_insn_info pmachriw_insn[] = { |
| { CPU_Cyrix|CPU_MMX, 0, 0, 0, 2, {0x0F, 0x5E, 0}, 0, 2, |
| {OPT_SIMDReg|OPS_64|OPA_Spare, OPT_Mem|OPS_64|OPS_Relaxed|OPA_EA, 0} } |
| }; |
| |
| /* Cyrix extensions */ |
| static const x86_insn_info rsdc_insn[] = { |
| { CPU_486|CPU_Cyrix|CPU_SMM, 0, 0, 0, 2, {0x0F, 0x79, 0}, 0, 2, |
| {OPT_SegReg|OPS_16|OPA_Spare, OPT_Mem|OPS_80|OPS_Relaxed|OPA_EA, 0} } |
| }; |
| static const x86_insn_info cyrixsmm_insn[] = { |
| { CPU_486|CPU_Cyrix|CPU_SMM, MOD_Op1Add, 0, 0, 2, {0x0F, 0x00, 0}, 0, 1, |
| {OPT_Mem|OPS_80|OPS_Relaxed|OPA_EA, 0, 0} } |
| }; |
| static const x86_insn_info svdc_insn[] = { |
| { CPU_486|CPU_Cyrix|CPU_SMM, 0, 0, 0, 2, {0x0F, 0x78, 0}, 0, 2, |
| {OPT_Mem|OPS_80|OPS_Relaxed|OPA_EA, OPT_SegReg|OPS_16|OPA_Spare, 0} } |
| }; |
| |
| /* Obsolete/undocumented instructions */ |
| static const x86_insn_info ibts_insn[] = { |
| { CPU_386|CPU_Undoc|CPU_Obs, 0, 16, 0, 2, {0x0F, 0xA7, 0}, 0, 2, |
| {OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_16|OPA_Spare, 0} }, |
| { CPU_386|CPU_Undoc|CPU_Obs, 0, 32, 0, 2, {0x0F, 0xA7, 0}, 0, 2, |
| {OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_32|OPA_Spare, 0} } |
| }; |
| static const x86_insn_info umov_insn[] = { |
| { CPU_386|CPU_Undoc, 0, 0, 0, 2, {0x0F, 0x10, 0}, 0, 2, |
| {OPT_RM|OPS_8|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_8|OPA_Spare, 0} }, |
| { CPU_386|CPU_Undoc, 0, 16, 0, 2, {0x0F, 0x11, 0}, 0, 2, |
| {OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_16|OPA_Spare, 0} }, |
| { CPU_386|CPU_Undoc, 0, 32, 0, 2, {0x0F, 0x11, 0}, 0, 2, |
| {OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, OPT_Reg|OPS_32|OPA_Spare, 0} }, |
| { CPU_386|CPU_Undoc, 0, 0, 0, 2, {0x0F, 0x12, 0}, 0, 2, |
| {OPT_Reg|OPS_8|OPA_Spare, OPT_RM|OPS_8|OPS_Relaxed|OPA_EA, 0} }, |
| { CPU_386|CPU_Undoc, 0, 16, 0, 2, {0x0F, 0x13, 0}, 0, 2, |
| {OPT_Reg|OPS_16|OPA_Spare, OPT_RM|OPS_16|OPS_Relaxed|OPA_EA, 0} }, |
| { CPU_386|CPU_Undoc, 0, 32, 0, 2, {0x0F, 0x13, 0}, 0, 2, |
| {OPT_Reg|OPS_32|OPA_Spare, OPT_RM|OPS_32|OPS_Relaxed|OPA_EA, 0} } |
| }; |
| static const x86_insn_info xbts_insn[] = { |
| { CPU_386|CPU_Undoc|CPU_Obs, 0, 16, 0, 2, {0x0F, 0xA6, 0}, 0, 2, |
| {OPT_Reg|OPS_16|OPA_Spare, OPT_Mem|OPS_16|OPS_Relaxed|OPA_EA, 0} }, |
| { CPU_386|CPU_Undoc|CPU_Obs, 0, 32, 0, 2, {0x0F, 0xA6, 0}, 0, 2, |
| {OPT_Reg|OPS_32|OPA_Spare, OPT_Mem|OPS_32|OPS_Relaxed|OPA_EA, 0} } |
| }; |
| |
| |
| static yasm_bytecode * |
| x86_new_jmp(yasm_arch *arch, const unsigned long data[4], int num_operands, |
| yasm_insn_operandhead *operands, x86_insn_info *jinfo, |
| yasm_bytecode *prev_bc, unsigned long line) |
| { |
| yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch; |
| x86_new_jmp_data d; |
| int num_info = (int)(data[1]&0xFF); |
| x86_insn_info *info = (x86_insn_info *)data[0]; |
| unsigned long mod_data = data[1] >> 8; |
| yasm_insn_operand *op; |
| static const unsigned char size_lookup[] = {0, 8, 16, 32, 64, 80, 128, 0}; |
| |
| d.line = line; |
| |
| /* We know the target is in operand 0, but sanity check for Imm. */ |
| op = yasm_ops_first(operands); |
| if (op->type != YASM_INSN__OPERAND_IMM) |
| yasm_internal_error(N_("invalid operand conversion")); |
| |
| /* Far target needs to become "seg imm:imm". */ |
| if ((jinfo->operands[0] & OPTM_MASK) == OPTM_Far) |
| d.target = yasm_expr_create_tree( |
| yasm_expr_create_branch(YASM_EXPR_SEG, op->data.val, line), |
| YASM_EXPR_SEGOFF, yasm_expr_copy(op->data.val), line); |
| else |
| d.target = op->data.val; |
| |
| /* Need to save jump origin for relative jumps. */ |
| d.origin = yasm_symtab_define_label2("$", prev_bc, 0, line); |
| |
| /* Initially assume no far opcode is available. */ |
| d.far_op_len = 0; |
| |
| /* See if the user explicitly specified short/near/far. */ |
| switch ((int)(jinfo->operands[0] & OPTM_MASK)) { |
| case OPTM_Short: |
| d.op_sel = JMP_SHORT_FORCED; |
| break; |
| case OPTM_Near: |
| d.op_sel = JMP_NEAR_FORCED; |
| break; |
| case OPTM_Far: |
| d.op_sel = JMP_FAR; |
| d.far_op_len = info->opcode_len; |
| d.far_op[0] = info->opcode[0]; |
| d.far_op[1] = info->opcode[1]; |
| d.far_op[2] = info->opcode[2]; |
| break; |
| default: |
| d.op_sel = JMP_NONE; |
| } |
| |
| /* Set operand size */ |
| d.opersize = jinfo->opersize; |
| |
| /* Check for address size setting in second operand, if present */ |
| if (jinfo->num_operands > 1 && |
| (jinfo->operands[1] & OPA_MASK) == OPA_AdSizeR) |
| d.addrsize = (unsigned char)size_lookup[(jinfo->operands[1] & |
| OPS_MASK)>>OPS_SHIFT]; |
| else |
| d.addrsize = 0; |
| |
| /* Check for address size override */ |
| if (jinfo->modifiers & MOD_AdSizeR) |
| d.addrsize = (unsigned char)(mod_data & 0xFF); |
| |
| /* Scan through other infos for this insn looking for short/near versions. |
| * Needs to match opersize and number of operands, also be within CPU. |
| */ |
| d.short_op_len = 0; |
| d.near_op_len = 0; |
| for (; num_info>0 && (d.short_op_len == 0 || d.near_op_len == 0); |
| num_info--, info++) { |
| unsigned long cpu = info->cpu | data[2]; |
| |
| if ((cpu & CPU_64) && arch_x86->mode_bits != 64) |
| continue; |
| if ((cpu & CPU_Not64) && arch_x86->mode_bits == 64) |
| continue; |
| cpu &= ~(CPU_64 | CPU_Not64); |
| |
| if ((arch_x86->cpu_enabled & cpu) != cpu) |
| continue; |
| |
| if (info->num_operands == 0) |
| continue; |
| |
| if ((info->operands[0] & OPA_MASK) != OPA_JmpRel) |
| continue; |
| |
| if (info->opersize != d.opersize) |
| continue; |
| |
| switch ((int)(info->operands[0] & OPTM_MASK)) { |
| case OPTM_Short: |
| d.short_op_len = info->opcode_len; |
| d.short_op[0] = info->opcode[0]; |
| d.short_op[1] = info->opcode[1]; |
| d.short_op[2] = info->opcode[2]; |
| if (info->modifiers & MOD_Op0Add) |
| d.short_op[0] += (unsigned char)(mod_data & 0xFF); |
| break; |
| case OPTM_Near: |
| d.near_op_len = info->opcode_len; |
| d.near_op[0] = info->opcode[0]; |
| d.near_op[1] = info->opcode[1]; |
| d.near_op[2] = info->opcode[2]; |
| if (info->modifiers & MOD_Op1Add) |
| d.near_op[1] += (unsigned char)(mod_data & 0xFF); |
| if ((info->operands[0] & OPAP_MASK) == OPAP_JmpFar) { |
| d.far_op_len = 1; |
| d.far_op[0] = info->opcode[info->opcode_len]; |
| } |
| break; |
| } |
| } |
| |
| return yasm_x86__bc_create_jmp(arch, &d); |
| } |
| |
| yasm_bytecode * |
| yasm_x86__parse_insn(yasm_arch *arch, const unsigned long data[4], |
| int num_operands, yasm_insn_operandhead *operands, |
| yasm_bytecode *prev_bc, unsigned long line) |
| { |
| yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch; |
| x86_new_insn_data d; |
| int num_info = (int)(data[1]&0xFF); |
| x86_insn_info *info = (x86_insn_info *)data[0]; |
| unsigned long mod_data = data[1] >> 8; |
| int found = 0; |
| yasm_insn_operand *op; |
| int i; |
| static const unsigned int size_lookup[] = {0, 1, 2, 4, 8, 10, 16, 0}; |
| |
| /* Just do a simple linear search through the info array for a match. |
| * First match wins. |
| */ |
| for (; num_info>0 && !found; num_info--, info++) { |
| unsigned long cpu; |
| unsigned int size; |
| int mismatch = 0; |
| |
| /* Match CPU */ |
| cpu = info->cpu | data[2]; |
| |
| if ((cpu & CPU_64) && arch_x86->mode_bits != 64) |
| continue; |
| if ((cpu & CPU_Not64) && arch_x86->mode_bits == 64) |
| continue; |
| cpu &= ~(CPU_64 | CPU_Not64); |
| |
| if ((arch_x86->cpu_enabled & cpu) != cpu) |
| continue; |
| |
| /* Match # of operands */ |
| if (num_operands != info->num_operands) |
| continue; |
| |
| if (!operands) { |
| found = 1; /* no operands -> must have a match here. */ |
| break; |
| } |
| |
| /* Match each operand type and size */ |
| for(i = 0, op = yasm_ops_first(operands); op && i<info->num_operands && |
| !mismatch; op = yasm_operand_next(op), i++) { |
| /* Check operand type */ |
| switch ((int)(info->operands[i] & OPT_MASK)) { |
| case OPT_Imm: |
| if (op->type != YASM_INSN__OPERAND_IMM) |
| mismatch = 1; |
| break; |
| case OPT_RM: |
| if (op->type == YASM_INSN__OPERAND_MEMORY) |
| break; |
| /*@fallthrough@*/ |
| case OPT_Reg: |
| if (op->type != YASM_INSN__OPERAND_REG) |
| mismatch = 1; |
| else { |
| switch ((x86_expritem_reg_size)(op->data.reg&~0xFUL)) { |
| case X86_REG8: |
| case X86_REG8X: |
| case X86_REG16: |
| case X86_REG32: |
| case X86_REG64: |
| case X86_FPUREG: |
| break; |
| default: |
| mismatch = 1; |
| break; |
| } |
| } |
| break; |
| case OPT_Mem: |
| if (op->type != YASM_INSN__OPERAND_MEMORY) |
| mismatch = 1; |
| break; |
| case OPT_SIMDRM: |
| if (op->type == YASM_INSN__OPERAND_MEMORY) |
| break; |
| /*@fallthrough@*/ |
| case OPT_SIMDReg: |
| if (op->type != YASM_INSN__OPERAND_REG) |
| mismatch = 1; |
| else { |
| switch ((x86_expritem_reg_size)(op->data.reg&~0xFUL)) { |
| case X86_MMXREG: |
| case X86_XMMREG: |
| break; |
| default: |
| mismatch = 1; |
| break; |
| } |
| } |
| break; |
| case OPT_SegReg: |
| if (op->type != YASM_INSN__OPERAND_SEGREG) |
| mismatch = 1; |
| break; |
| case OPT_CRReg: |
| if (op->type != YASM_INSN__OPERAND_REG || |
| (op->data.reg & ~0xFUL) != X86_CRREG) |
| mismatch = 1; |
| break; |
| case OPT_DRReg: |
| if (op->type != YASM_INSN__OPERAND_REG || |
| (op->data.reg & ~0xFUL) != X86_DRREG) |
| mismatch = 1; |
| break; |
| case OPT_TRReg: |
| if (op->type != YASM_INSN__OPERAND_REG || |
| (op->data.reg & ~0xFUL) != X86_TRREG) |
| mismatch = 1; |
| break; |
| case OPT_ST0: |
| if (op->type != YASM_INSN__OPERAND_REG || |
| op->data.reg != X86_FPUREG) |
| mismatch = 1; |
| break; |
| case OPT_Areg: |
| if (op->type != YASM_INSN__OPERAND_REG || |
| ((info->operands[i] & OPS_MASK) == OPS_8 && |
| op->data.reg != (X86_REG8 | 0) && |
| op->data.reg != (X86_REG8X | 0)) || |
| ((info->operands[i] & OPS_MASK) == OPS_16 && |
| op->data.reg != (X86_REG16 | 0)) || |
| ((info->operands[i] & OPS_MASK) == OPS_32 && |
| op->data.reg != (X86_REG32 | 0)) || |
| ((info->operands[i] & OPS_MASK) == OPS_64 && |
| op->data.reg != (X86_REG64 | 0))) |
| mismatch = 1; |
| break; |
| case OPT_Creg: |
| if (op->type != YASM_INSN__OPERAND_REG || |
| ((info->operands[i] & OPS_MASK) == OPS_8 && |
| op->data.reg != (X86_REG8 | 1) && |
| op->data.reg != (X86_REG8X | 1)) || |
| ((info->operands[i] & OPS_MASK) == OPS_16 && |
| op->data.reg != (X86_REG16 | 1)) || |
| ((info->operands[i] & OPS_MASK) == OPS_32 && |
| op->data.reg != (X86_REG32 | 1)) || |
| ((info->operands[i] & OPS_MASK) == OPS_64 && |
| op->data.reg != (X86_REG64 | 1))) |
| mismatch = 1; |
| break; |
| case OPT_Dreg: |
| if (op->type != YASM_INSN__OPERAND_REG || |
| ((info->operands[i] & OPS_MASK) == OPS_8 && |
| op->data.reg != (X86_REG8 | 2) && |
| op->data.reg != (X86_REG8X | 2)) || |
| ((info->operands[i] & OPS_MASK) == OPS_16 && |
| op->data.reg != (X86_REG16 | 2)) || |
| ((info->operands[i] & OPS_MASK) == OPS_32 && |
| op->data.reg != (X86_REG32 | 2)) || |
| ((info->operands[i] & OPS_MASK) == OPS_64 && |
| op->data.reg != (X86_REG64 | 2))) |
| mismatch = 1; |
| break; |
| case OPT_CS: |
| if (op->type != YASM_INSN__OPERAND_SEGREG || |
| (op->data.reg & 0xF) != 1) |
| mismatch = 1; |
| break; |
| case OPT_DS: |
| if (op->type != YASM_INSN__OPERAND_SEGREG || |
| (op->data.reg & 0xF) != 3) |
| mismatch = 1; |
| break; |
| case OPT_ES: |
| if (op->type != YASM_INSN__OPERAND_SEGREG || |
| (op->data.reg & 0xF) != 0) |
| mismatch = 1; |
| break; |
| case OPT_FS: |
| if (op->type != YASM_INSN__OPERAND_SEGREG || |
| (op->data.reg & 0xF) != 4) |
| mismatch = 1; |
| break; |
| case OPT_GS: |
| if (op->type != YASM_INSN__OPERAND_SEGREG || |
| (op->data.reg & 0xF) != 5) |
| mismatch = 1; |
| break; |
| case OPT_SS: |
| if (op->type != YASM_INSN__OPERAND_SEGREG || |
| (op->data.reg & 0xF) != 2) |
| mismatch = 1; |
| break; |
| case OPT_CR4: |
| if (op->type != YASM_INSN__OPERAND_REG || |
| op->data.reg != (X86_CRREG | 4)) |
| mismatch = 1; |
| break; |
| case OPT_MemOffs: |
| if (op->type != YASM_INSN__OPERAND_MEMORY || |
| yasm_expr__contains(yasm_ea_get_disp(op->data.ea), |
| YASM_EXPR_REG)) |
| mismatch = 1; |
| break; |
| default: |
| yasm_internal_error(N_("invalid operand type")); |
| } |
| |
| if (mismatch) |
| break; |
| |
| /* Check operand size */ |
| size = size_lookup[(info->operands[i] & OPS_MASK)>>OPS_SHIFT]; |
| if (op->type == YASM_INSN__OPERAND_REG && op->size == 0) { |
| /* Register size must exactly match */ |
| if (yasm_x86__get_reg_size(arch, op->data.reg) != size) |
| mismatch = 1; |
| } else { |
| if ((info->operands[i] & OPS_RMASK) == OPS_Relaxed) { |
| /* Relaxed checking */ |
| if (size != 0 && op->size != size && op->size != 0) |
| mismatch = 1; |
| } else { |
| /* Strict checking */ |
| if (op->size != size) |
| mismatch = 1; |
| } |
| } |
| |
| if (mismatch) |
| break; |
| |
| /* Check target modifier */ |
| switch ((int)(info->operands[i] & OPTM_MASK)) { |
| case OPTM_None: |
| if (op->targetmod != 0) |
| mismatch = 1; |
| break; |
| case OPTM_Near: |
| if (op->targetmod != X86_NEAR) |
| mismatch = 1; |
| break; |
| case OPTM_Short: |
| if (op->targetmod != X86_SHORT) |
| mismatch = 1; |
| break; |
| case OPTM_Far: |
| if (op->targetmod != X86_FAR) |
| mismatch = 1; |
| break; |
| case OPTM_To: |
| if (op->targetmod != X86_TO) |
| mismatch = 1; |
| break; |
| default: |
| yasm_internal_error(N_("invalid target modifier type")); |
| } |
| } |
| |
| if (!mismatch) { |
| found = 1; |
| break; |
| } |
| } |
| |
| if (!found) { |
| /* Didn't find a matching one */ |
| yasm__error(line, N_("invalid combination of opcode and operands")); |
| return NULL; |
| } |
| |
| /* Extended error/warning handling */ |
| switch ((int)(info->modifiers & MOD_Ext_MASK)) { |
| case MOD_ExtNone: |
| /* No extended modifier, so just continue */ |
| break; |
| case MOD_ExtErr: |
| switch ((int)((info->modifiers & MOD_ExtIndex_MASK) |
| >> MOD_ExtIndex_SHIFT)) { |
| case 0: |
| yasm__error(line, N_("mismatch in operand sizes")); |
| break; |
| case 1: |
| yasm__error(line, N_("operand size not specified")); |
| break; |
| default: |
| yasm_internal_error(N_("unrecognized x86 ext mod index")); |
| } |
| return NULL; /* It was an error */ |
| case MOD_ExtWarn: |
| switch ((int)((info->modifiers & MOD_ExtIndex_MASK) |
| >> MOD_ExtIndex_SHIFT)) { |
| default: |
| yasm_internal_error(N_("unrecognized x86 ext mod index")); |
| } |
| break; |
| default: |
| yasm_internal_error(N_("unrecognized x86 extended modifier")); |
| } |
| |
| /* Shortcut to JmpRel */ |
| if (operands && (info->operands[0] & OPA_MASK) == OPA_JmpRel) |
| return x86_new_jmp(arch, data, num_operands, operands, info, prev_bc, |
| line); |
| |
| /* Copy what we can from info */ |
| d.line = line; |
| d.ea = NULL; |
| d.ea_origin = NULL; |
| d.imm = NULL; |
| d.opersize = info->opersize; |
| d.def_opersize_64 = info->def_opersize_64; |
| d.op_len = info->opcode_len; |
| d.op[0] = info->opcode[0]; |
| d.op[1] = info->opcode[1]; |
| d.op[2] = info->opcode[2]; |
| d.spare = info->spare; |
| d.im_len = 0; |
| d.im_sign = 0; |
| d.shift_op = 0; |
| d.signext_imm8_op = 0; |
| d.rex = 0; |
| |
| /* Apply modifiers */ |
| if (info->modifiers & MOD_Op2Add) { |
| d.op[2] += (unsigned char)(mod_data & 0xFF); |
| mod_data >>= 8; |
| } |
| if (info->modifiers & MOD_Gap0) |
| mod_data >>= 8; |
| if (info->modifiers & MOD_Op1Add) { |
| d.op[1] += (unsigned char)(mod_data & 0xFF); |
| mod_data >>= 8; |
| } |
| if (info->modifiers & MOD_Gap1) |
| mod_data >>= 8; |
| if (info->modifiers & MOD_Op0Add) { |
| d.op[0] += (unsigned char)(mod_data & 0xFF); |
| mod_data >>= 8; |
| } |
| if (info->modifiers & MOD_SpAdd) { |
| d.spare += (unsigned char)(mod_data & 0xFF); |
| mod_data >>= 8; |
| } |
| if (info->modifiers & MOD_OpSizeR) { |
| d.opersize = (unsigned char)(mod_data & 0xFF); |
| mod_data >>= 8; |
| } |
| if (info->modifiers & MOD_Imm8) { |
| d.imm = yasm_expr_create_ident(yasm_expr_int( |
| yasm_intnum_create_uint(mod_data & 0xFF)), line); |
| d.im_len = 1; |
| mod_data >>= 8; |
| } |
| if (info->modifiers & MOD_DOpS64R) { |
| d.def_opersize_64 = (unsigned char)(mod_data & 0xFF); |
| /*mod_data >>= 8;*/ |
| } |
| |
| /* Go through operands and assign */ |
| if (operands) { |
| for(i = 0, op = yasm_ops_first(operands); op && i<info->num_operands; |
| op = yasm_operand_next(op), i++) { |
| switch ((int)(info->operands[i] & OPA_MASK)) { |
| case OPA_None: |
| /* Throw away the operand contents */ |
| switch (op->type) { |
| case YASM_INSN__OPERAND_REG: |
| case YASM_INSN__OPERAND_SEGREG: |
| break; |
| case YASM_INSN__OPERAND_MEMORY: |
| yasm_ea_destroy(op->data.ea); |
| break; |
| case YASM_INSN__OPERAND_IMM: |
| yasm_expr_destroy(op->data.val); |
| break; |
| } |
| break; |
| case OPA_EA: |
| switch (op->type) { |
| case YASM_INSN__OPERAND_REG: |
| d.ea = |
| yasm_x86__ea_create_reg(op->data.reg, &d.rex, |
| arch_x86->mode_bits); |
| break; |
| case YASM_INSN__OPERAND_SEGREG: |
| yasm_internal_error( |
| N_("invalid operand conversion")); |
| case YASM_INSN__OPERAND_MEMORY: |
| d.ea = op->data.ea; |
| if ((info->operands[i] & OPT_MASK) == OPT_MemOffs) |
| /* Special-case for MOV MemOffs instruction */ |
| yasm_x86__ea_set_disponly(d.ea); |
| else if (arch_x86->mode_bits == 64) |
| /* Save origin for possible RIP-relative */ |
| d.ea_origin = yasm_symtab_define_label2("$", |
| prev_bc, 0, line); |
| break; |
| case YASM_INSN__OPERAND_IMM: |
| d.ea = yasm_x86__ea_create_imm(op->data.val, |
| size_lookup[(info->operands[i] & |
| OPS_MASK)>>OPS_SHIFT]); |
| break; |
| } |
| break; |
| case OPA_Imm: |
| if (op->type == YASM_INSN__OPERAND_IMM) { |
| d.imm = op->data.val; |
| d.im_len = size_lookup[(info->operands[i] & |
| OPS_MASK)>>OPS_SHIFT]; |
| } else |
| yasm_internal_error(N_("invalid operand conversion")); |
| break; |
| case OPA_SImm: |
| if (op->type == YASM_INSN__OPERAND_IMM) { |
| d.imm = op->data.val; |
| d.im_len = size_lookup[(info->operands[i] & |
| OPS_MASK)>>OPS_SHIFT]; |
| d.im_sign = 1; |
| } else |
| yasm_internal_error(N_("invalid operand conversion")); |
| break; |
| case OPA_Spare: |
| if (op->type == YASM_INSN__OPERAND_SEGREG) |
| d.spare = (unsigned char)(op->data.reg&7); |
| else if (op->type == YASM_INSN__OPERAND_REG) { |
| if (yasm_x86__set_rex_from_reg(&d.rex, &d.spare, |
| op->data.reg, arch_x86->mode_bits, |
| X86_REX_R)) { |
| yasm__error(line, |
| N_("invalid combination of opcode and operands")); |
| return NULL; |
| } |
| } else |
| yasm_internal_error(N_("invalid operand conversion")); |
| break; |
| case OPA_Op0Add: |
| if (op->type == YASM_INSN__OPERAND_REG) { |
| unsigned char opadd; |
| if (yasm_x86__set_rex_from_reg(&d.rex, &opadd, |
| op->data.reg, arch_x86->mode_bits, |
| X86_REX_B)) { |
| yasm__error(line, |
| N_("invalid combination of opcode and operands")); |
| return NULL; |
| } |
| d.op[0] += opadd; |
| } else |
| yasm_internal_error(N_("invalid operand conversion")); |
| break; |
| case OPA_Op1Add: |
| /* Op1Add is only used for FPU, so no need to do REX */ |
| if (op->type == YASM_INSN__OPERAND_REG) |
| d.op[1] += (unsigned char)(op->data.reg&7); |
| else |
| yasm_internal_error(N_("invalid operand conversion")); |
| break; |
| case OPA_SpareEA: |
| if (op->type == YASM_INSN__OPERAND_REG) { |
| d.ea = yasm_x86__ea_create_reg(op->data.reg, &d.rex, |
| arch_x86->mode_bits); |
| if (!d.ea || |
| yasm_x86__set_rex_from_reg(&d.rex, &d.spare, |
| op->data.reg, arch_x86->mode_bits, |
| X86_REX_R)) { |
| yasm__error(line, |
| N_("invalid combination of opcode and operands")); |
| if (d.ea) |
| yasm_xfree(d.ea); |
| return NULL; |
| } |
| } else |
| yasm_internal_error(N_("invalid operand conversion")); |
| break; |
| default: |
| yasm_internal_error(N_("unknown operand action")); |
| } |
| |
| switch ((int)(info->operands[i] & OPAP_MASK)) { |
| case OPAP_None: |
| break; |
| case OPAP_ShiftOp: |
| d.shift_op = 1; |
| break; |
| case OPAP_SImm8Avail: |
| d.signext_imm8_op = 1; |
| break; |
| default: |
| yasm_internal_error( |
| N_("unknown operand postponed action")); |
| } |
| } |
| } |
| |
| /* Create the bytecode and return it */ |
| return yasm_x86__bc_create_insn(arch, &d); |
| } |
| |
| |
| #define YYCTYPE char |
| #define YYCURSOR id |
| #define YYLIMIT id |
| #define YYMARKER marker |
| #define YYFILL(n) |
| |
| /*!re2c |
| any = [\000-\377]; |
| A = [aA]; |
| B = [bB]; |
| C = [cC]; |
| D = [dD]; |
| E = [eE]; |
| F = [fF]; |
| G = [gG]; |
| H = [hH]; |
| I = [iI]; |
| J = [jJ]; |
| K = [kK]; |
| L = [lL]; |
| M = [mM]; |
| N = [nN]; |
| O = [oO]; |
| P = [pP]; |
| Q = [qQ]; |
| R = [rR]; |
| S = [sS]; |
| T = [tT]; |
| U = [uU]; |
| V = [vV]; |
| W = [wW]; |
| X = [xX]; |
| Y = [yY]; |
| Z = [zZ]; |
| */ |
| |
| void |
| yasm_x86__parse_cpu(yasm_arch *arch, const char *id, unsigned long line) |
| { |
| yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch; |
| /*const char *marker;*/ |
| |
| /*!re2c |
| /* The standard CPU names /set/ cpu_enabled. */ |
| "8086" { |
| arch_x86->cpu_enabled = CPU_Priv; |
| return; |
| } |
| ("80" | I)? "186" { |
| arch_x86->cpu_enabled = CPU_186|CPU_Priv; |
| return; |
| } |
| ("80" | I)? "286" { |
| arch_x86->cpu_enabled = CPU_186|CPU_286|CPU_Priv; |
| return; |
| } |
| ("80" | I)? "386" { |
| arch_x86->cpu_enabled = |
| CPU_186|CPU_286|CPU_386|CPU_SMM|CPU_Prot|CPU_Priv; |
| return; |
| } |
| ("80" | I)? "486" { |
| arch_x86->cpu_enabled = |
| CPU_186|CPU_286|CPU_386|CPU_486|CPU_FPU|CPU_SMM|CPU_Prot| |
| CPU_Priv; |
| return; |
| } |
| (I? "586") | (P E N T I U M) | (P "5") { |
| arch_x86->cpu_enabled = |
| CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_FPU|CPU_SMM| |
| CPU_Prot|CPU_Priv; |
| return; |
| } |
| (I? "686") | (P "6") | (P P R O) | (P E N T I U M P R O) { |
| arch_x86->cpu_enabled = |
| CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_686|CPU_FPU| |
| CPU_SMM|CPU_Prot|CPU_Priv; |
| return; |
| } |
| (P "2") | (P E N T I U M "-"? ("2" | (I I))) { |
| arch_x86->cpu_enabled = |
| CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_686|CPU_FPU| |
| CPU_MMX|CPU_SMM|CPU_Prot|CPU_Priv; |
| return; |
| } |
| (P "3") | (P E N T I U M "-"? ("3" | (I I I))) | (K A T M A I) { |
| arch_x86->cpu_enabled = |
| CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_686|CPU_P3|CPU_FPU| |
| CPU_MMX|CPU_SSE|CPU_SMM|CPU_Prot|CPU_Priv; |
| return; |
| } |
| (P "4") | (P E N T I U M "-"? ("4" | (I V))) | (W I L L I A M E T T E) { |
| arch_x86->cpu_enabled = |
| CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_686|CPU_P3|CPU_P4| |
| CPU_FPU|CPU_MMX|CPU_SSE|CPU_SSE2|CPU_SMM|CPU_Prot|CPU_Priv; |
| return; |
| } |
| (I A "-"? "64") | (I T A N I U M) { |
| arch_x86->cpu_enabled = |
| CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_686|CPU_P3|CPU_P4| |
| CPU_IA64|CPU_FPU|CPU_MMX|CPU_SSE|CPU_SSE2|CPU_SMM|CPU_Prot| |
| CPU_Priv; |
| return; |
| } |
| K "6" { |
| arch_x86->cpu_enabled = |
| CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_686|CPU_K6|CPU_FPU| |
| CPU_MMX|CPU_3DNow|CPU_SMM|CPU_Prot|CPU_Priv; |
| return; |
| } |
| (A T H L O N) | (K "7") { |
| arch_x86->cpu_enabled = |
| CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_686|CPU_K6| |
| CPU_Athlon|CPU_FPU|CPU_MMX|CPU_SSE|CPU_3DNow|CPU_SMM|CPU_Prot| |
| CPU_Priv; |
| return; |
| } |
| ((S L E D G E)? (H A M M E R)) | (O P T E R O N) | |
| (A T H L O N "-"? "64") { |
| arch_x86->cpu_enabled = |
| CPU_186|CPU_286|CPU_386|CPU_486|CPU_586|CPU_686|CPU_K6| |
| CPU_Athlon|CPU_Hammer|CPU_FPU|CPU_MMX|CPU_SSE|CPU_3DNow| |
| CPU_SMM|CPU_Prot|CPU_Priv; |
| return; |
| } |
| |
| /* Features have "no" versions to disable them, and only set/reset the |
| * specific feature being changed. All other bits are left alone. |
| */ |
| F P U { arch_x86->cpu_enabled |= CPU_FPU; return; } |
| N O F P U { arch_x86->cpu_enabled &= ~CPU_FPU; return; } |
| M M X { arch_x86->cpu_enabled |= CPU_MMX; return; } |
| N O M M X { arch_x86->cpu_enabled &= ~CPU_MMX; return; } |
| S S E { arch_x86->cpu_enabled |= CPU_SSE; return; } |
| N O S S E { arch_x86->cpu_enabled &= ~CPU_SSE; return; } |
| S S E "2" { arch_x86->cpu_enabled |= CPU_SSE2; return; } |
| N O S S E "2" { arch_x86->cpu_enabled &= ~CPU_SSE2; return; } |
| "3" D N O W { arch_x86->cpu_enabled |= CPU_3DNow; return; } |
| N O "3" D N O W { arch_x86->cpu_enabled &= ~CPU_3DNow; return; } |
| C Y R I X { arch_x86->cpu_enabled |= CPU_Cyrix; return; } |
| N O C Y R I X { arch_x86->cpu_enabled &= ~CPU_Cyrix; return; } |
| A M D { arch_x86->cpu_enabled |= CPU_AMD; return; } |
| N O A M D { arch_x86->cpu_enabled &= ~CPU_AMD; return; } |
| S M M { arch_x86->cpu_enabled |= CPU_SMM; return; } |
| N O S M M { arch_x86->cpu_enabled &= ~CPU_SMM; return; } |
| P R O T { arch_x86->cpu_enabled |= CPU_Prot; return; } |
| N O P R O T { arch_x86->cpu_enabled &= ~CPU_Prot; return; } |
| U N D O C { arch_x86->cpu_enabled |= CPU_Undoc; return; } |
| N O U N D O C { arch_x86->cpu_enabled &= ~CPU_Undoc; return; } |
| O B S { arch_x86->cpu_enabled |= CPU_Obs; return; } |
| N O O B S { arch_x86->cpu_enabled &= ~CPU_Obs; return; } |
| P R I V { arch_x86->cpu_enabled |= CPU_Priv; return; } |
| N O P R I V { arch_x86->cpu_enabled &= ~CPU_Priv; return; } |
| |
| /* catchalls */ |
| [\001-\377]+ { |
| yasm__warning(YASM_WARN_GENERAL, line, |
| N_("unrecognized CPU identifier `%s'"), id); |
| return; |
| } |
| [\000] { |
| yasm__warning(YASM_WARN_GENERAL, line, |
| N_("unrecognized CPU identifier `%s'"), id); |
| return; |
| } |
| */ |
| } |
| |
| yasm_arch_check_id_retval |
| yasm_x86__parse_check_id(yasm_arch *arch, unsigned long data[4], |
| const char *id, unsigned long line) |
| { |
| yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch; |
| const char *oid = id; |
| /*const char *marker;*/ |
| /*!re2c |
| /* target modifiers */ |
| N E A R { |
| data[0] = X86_NEAR; |
| return YASM_ARCH_CHECK_ID_TARGETMOD; |
| } |
| S H O R T { |
| data[0] = X86_SHORT; |
| return YASM_ARCH_CHECK_ID_TARGETMOD; |
| } |
| F A R { |
| data[0] = X86_FAR; |
| return YASM_ARCH_CHECK_ID_TARGETMOD; |
| } |
| T O { |
| data[0] = X86_TO; |
| return YASM_ARCH_CHECK_ID_TARGETMOD; |
| } |
| |
| /* operand size overrides */ |
| O "16" { |
| data[0] = X86_OPERSIZE; |
| data[1] = 16; |
| return YASM_ARCH_CHECK_ID_PREFIX; |
| } |
| O "32" { |
| data[0] = X86_OPERSIZE; |
| data[1] = 32; |
| return YASM_ARCH_CHECK_ID_PREFIX; |
| } |
| O "64" { |
| if (arch_x86->mode_bits != 64) { |
| yasm__warning(YASM_WARN_GENERAL, line, |
| N_("`%s' is a prefix in 64-bit mode"), oid); |
| return YASM_ARCH_CHECK_ID_NONE; |
| } |
| data[0] = X86_OPERSIZE; |
| data[1] = 64; |
| return YASM_ARCH_CHECK_ID_PREFIX; |
| } |
| /* address size overrides */ |
| A "16" { |
| if (arch_x86->mode_bits == 64) { |
| yasm__error(line, |
| N_("Cannot override address size to 16 bits in 64-bit mode")); |
| return YASM_ARCH_CHECK_ID_NONE; |
| } |
| data[0] = X86_ADDRSIZE; |
| data[1] = 16; |
| return YASM_ARCH_CHECK_ID_PREFIX; |
| } |
| A "32" { |
| data[0] = X86_ADDRSIZE; |
| data[1] = 32; |
| return YASM_ARCH_CHECK_ID_PREFIX; |
| } |
| A "64" { |
| if (arch_x86->mode_bits != 64) { |
| yasm__warning(YASM_WARN_GENERAL, line, |
| N_("`%s' is a prefix in 64-bit mode"), oid); |
| return YASM_ARCH_CHECK_ID_NONE; |
| } |
| data[0] = X86_ADDRSIZE; |
| data[1] = 64; |
| return YASM_ARCH_CHECK_ID_PREFIX; |
| } |
| |
| /* instruction prefixes */ |
| L O C K { |
| data[0] = X86_LOCKREP; |
| data[1] = 0xF0; |
| return YASM_ARCH_CHECK_ID_PREFIX; |
| } |
| R E P N E { |
| data[0] = X86_LOCKREP; |
| data[1] = 0xF2; |
| return YASM_ARCH_CHECK_ID_PREFIX; |
| } |
| R E P N Z { |
| data[0] = X86_LOCKREP; |
| data[1] = 0xF2; |
| return YASM_ARCH_CHECK_ID_PREFIX; |
| } |
| R E P { |
| data[0] = X86_LOCKREP; |
| data[1] = 0xF3; |
| return YASM_ARCH_CHECK_ID_PREFIX; |
| } |
| R E P E { |
| data[0] = X86_LOCKREP; |
| data[1] = 0xF4; |
| return YASM_ARCH_CHECK_ID_PREFIX; |
| } |
| R E P Z { |
| data[0] = X86_LOCKREP; |
| data[1] = 0xF4; |
| return YASM_ARCH_CHECK_ID_PREFIX; |
| } |
| |
| /* control, debug, and test registers */ |
| C R [02-48] { |
| if (arch_x86->mode_bits != 64 && oid[2] == '8') { |
| yasm__warning(YASM_WARN_GENERAL, line, |
| N_("`%s' is a register in 64-bit mode"), oid); |
| return YASM_ARCH_CHECK_ID_NONE; |
| } |
| data[0] = X86_CRREG | (oid[2]-'0'); |
| return YASM_ARCH_CHECK_ID_REG; |
| } |
| D R [0-7] { |
| data[0] = X86_DRREG | (oid[2]-'0'); |
| return YASM_ARCH_CHECK_ID_REG; |
| } |
| T R [0-7] { |
| data[0] = X86_TRREG | (oid[2]-'0'); |
| return YASM_ARCH_CHECK_ID_REG; |
| } |
| |
| /* floating point, MMX, and SSE/SSE2 registers */ |
| S T [0-7] { |
| data[0] = X86_FPUREG | (oid[2]-'0'); |
| return YASM_ARCH_CHECK_ID_REG; |
| } |
| M M [0-7] { |
| data[0] = X86_MMXREG | (oid[2]-'0'); |
| return YASM_ARCH_CHECK_ID_REG; |
| } |
| X M M [0-9] { |
| if (arch_x86->mode_bits != 64 && |
| (oid[3] == '8' || oid[3] == '9')) { |
| yasm__warning(YASM_WARN_GENERAL, line, |
| N_("`%s' is a register in 64-bit mode"), oid); |
| return YASM_ARCH_CHECK_ID_NONE; |
| } |
| data[0] = X86_XMMREG | (oid[3]-'0'); |
| return YASM_ARCH_CHECK_ID_REG; |
| } |
| X M M "1" [0-5] { |
| if (arch_x86->mode_bits != 64) { |
| yasm__warning(YASM_WARN_GENERAL, line, |
| N_("`%s' is a register in 64-bit mode"), oid); |
| return YASM_ARCH_CHECK_ID_NONE; |
| } |
| data[0] = X86_REG64 | (10+oid[4]-'0'); |
| return YASM_ARCH_CHECK_ID_REG; |
| } |
| |
| /* integer registers */ |
| R A X { |
| if (arch_x86->mode_bits != 64) { |
| yasm__warning(YASM_WARN_GENERAL, line, |
| N_("`%s' is a register in 64-bit mode"), oid); |
| return YASM_ARCH_CHECK_ID_NONE; |
| } |
| data[0] = X86_REG64 | 0; |
| return YASM_ARCH_CHECK_ID_REG; |
| } |
| R C X { |
| if (arch_x86->mode_bits != 64) { |
| yasm__warning(YASM_WARN_GENERAL, line, |
| N_("`%s' is a register in 64-bit mode"), oid); |
| return YASM_ARCH_CHECK_ID_NONE; |
| } |
| data[0] = X86_REG64 | 1; |
| return YASM_ARCH_CHECK_ID_REG; |
| } |
| R D X { |
| if (arch_x86->mode_bits != 64) { |
| yasm__warning(YASM_WARN_GENERAL, line, |
| N_("`%s' is a register in 64-bit mode"), oid); |
| return YASM_ARCH_CHECK_ID_NONE; |
| } |
| data[0] = X86_REG64 | 2; |
| return YASM_ARCH_CHECK_ID_REG; |
| } |
| R B X { |
| if (arch_x86->mode_bits != 64) { |
| yasm__warning(YASM_WARN_GENERAL, line, |
| N_("`%s' is a register in 64-bit mode"), oid); |
| return YASM_ARCH_CHECK_ID_NONE; |
| } |
| data[0] = X86_REG64 | 3; |
| return YASM_ARCH_CHECK_ID_REG; |
| } |
| R S P { |
| if (arch_x86->mode_bits != 64) { |
| yasm__warning(YASM_WARN_GENERAL, line, |
| N_("`%s' is a register in 64-bit mode"), oid); |
| return YASM_ARCH_CHECK_ID_NONE; |
| } |
| data[0] = X86_REG64 | 4; |
| return YASM_ARCH_CHECK_ID_REG; |
| } |
| R B P { |
| if (arch_x86->mode_bits != 64) { |
| yasm__warning(YASM_WARN_GENERAL, line, |
| N_("`%s' is a register in 64-bit mode"), oid); |
| return YASM_ARCH_CHECK_ID_NONE; |
| } |
| data[0] = X86_REG64 | 5; |
| return YASM_ARCH_CHECK_ID_REG; |
| } |
| R S I { |
| if (arch_x86->mode_bits != 64) { |
| yasm__warning(YASM_WARN_GENERAL, line, |
| N_("`%s' is a register in 64-bit mode"), oid); |
| return YASM_ARCH_CHECK_ID_NONE; |
| } |
| data[0] = X86_REG64 | 6; |
| return YASM_ARCH_CHECK_ID_REG; |
| } |
| R D I { |
| if (arch_x86->mode_bits != 64) { |
| yasm__warning(YASM_WARN_GENERAL, line, |
| N_("`%s' is a register in 64-bit mode"), oid); |
| return YASM_ARCH_CHECK_ID_NONE; |
| } |
| data[0] = X86_REG64 | 7; |
| return YASM_ARCH_CHECK_ID_REG; |
| } |
| R [8-9] { |
| if (arch_x86->mode_bits != 64) { |
| yasm__warning(YASM_WARN_GENERAL, line, |
| N_("`%s' is a register in 64-bit mode"), oid); |
| return YASM_ARCH_CHECK_ID_NONE; |
| } |
| data[0] = X86_REG64 | (oid[1]-'0'); |
| return YASM_ARCH_CHECK_ID_REG; |
| } |
| R "1" [0-5] { |
| if (arch_x86->mode_bits != 64) { |
| yasm__warning(YASM_WARN_GENERAL, line, |
| N_("`%s' is a register in 64-bit mode"), oid); |
| return YASM_ARCH_CHECK_ID_NONE; |
| } |
| data[0] = X86_REG64 | (10+oid[2]-'0'); |
| return YASM_ARCH_CHECK_ID_REG; |
| } |
| |
| E A X { data[0] = X86_REG32 | 0; return YASM_ARCH_CHECK_ID_REG; } |
| E C X { data[0] = X86_REG32 | 1; return YASM_ARCH_CHECK_ID_REG; } |
| E D X { data[0] = X86_REG32 | 2; return YASM_ARCH_CHECK_ID_REG; } |
| E B X { data[0] = X86_REG32 | 3; return YASM_ARCH_CHECK_ID_REG; } |
| E S P { data[0] = X86_REG32 | 4; return YASM_ARCH_CHECK_ID_REG; } |
| E B P { data[0] = X86_REG32 | 5; return YASM_ARCH_CHECK_ID_REG; } |
| E S I { data[0] = X86_REG32 | 6; return YASM_ARCH_CHECK_ID_REG; } |
| E D I { data[0] = X86_REG32 | 7; return YASM_ARCH_CHECK_ID_REG; } |
| R [8-9] D { |
| if (arch_x86->mode_bits != 64) { |
| yasm__warning(YASM_WARN_GENERAL, line, |
| N_("`%s' is a register in 64-bit mode"), oid); |
| return YASM_ARCH_CHECK_ID_NONE; |
| } |
| data[0] = X86_REG32 | (oid[1]-'0'); |
| return YASM_ARCH_CHECK_ID_REG; |
| } |
| R "1" [0-5] D { |
| if (arch_x86->mode_bits != 64) { |
| yasm__warning(YASM_WARN_GENERAL, line, |
| N_("`%s' is a register in 64-bit mode"), oid); |
| return YASM_ARCH_CHECK_ID_NONE; |
| } |
| data[0] = X86_REG32 | (10+oid[2]-'0'); |
| return YASM_ARCH_CHECK_ID_REG; |
| } |
| |
| A X { data[0] = X86_REG16 | 0; return YASM_ARCH_CHECK_ID_REG; } |
| C X { data[0] = X86_REG16 | 1; return YASM_ARCH_CHECK_ID_REG; } |
| D X { data[0] = X86_REG16 | 2; return YASM_ARCH_CHECK_ID_REG; } |
| B X { data[0] = X86_REG16 | 3; return YASM_ARCH_CHECK_ID_REG; } |
| S P { data[0] = X86_REG16 | 4; return YASM_ARCH_CHECK_ID_REG; } |
| B P { data[0] = X86_REG16 | 5; return YASM_ARCH_CHECK_ID_REG; } |
| S I { data[0] = X86_REG16 | 6; return YASM_ARCH_CHECK_ID_REG; } |
| D I { data[0] = X86_REG16 | 7; return YASM_ARCH_CHECK_ID_REG; } |
| R [8-9] W { |
| if (arch_x86->mode_bits != 64) { |
| yasm__warning(YASM_WARN_GENERAL, line, |
| N_("`%s' is a register in 64-bit mode"), oid); |
| return YASM_ARCH_CHECK_ID_NONE; |
| } |
| data[0] = X86_REG16 | (oid[1]-'0'); |
| return YASM_ARCH_CHECK_ID_REG; |
| } |
| R "1" [0-5] W { |
| if (arch_x86->mode_bits != 64) { |
| yasm__warning(YASM_WARN_GENERAL, line, |
| N_("`%s' is a register in 64-bit mode"), oid); |
| return YASM_ARCH_CHECK_ID_NONE; |
| } |
| data[0] = X86_REG16 | (10+oid[2]-'0'); |
| return YASM_ARCH_CHECK_ID_REG; |
| } |
| |
| A L { data[0] = X86_REG8 | 0; return YASM_ARCH_CHECK_ID_REG; } |
| C L { data[0] = X86_REG8 | 1; return YASM_ARCH_CHECK_ID_REG; } |
| D L { data[0] = X86_REG8 | 2; return YASM_ARCH_CHECK_ID_REG; } |
| B L { data[0] = X86_REG8 | 3; return YASM_ARCH_CHECK_ID_REG; } |
| A H { data[0] = X86_REG8 | 4; return YASM_ARCH_CHECK_ID_REG; } |
| C H { data[0] = X86_REG8 | 5; return YASM_ARCH_CHECK_ID_REG; } |
| D H { data[0] = X86_REG8 | 6; return YASM_ARCH_CHECK_ID_REG; } |
| B H { data[0] = X86_REG8 | 7; return YASM_ARCH_CHECK_ID_REG; } |
| S P L { |
| if (arch_x86->mode_bits != 64) { |
| yasm__warning(YASM_WARN_GENERAL, line, |
| N_("`%s' is a register in 64-bit mode"), oid); |
| return YASM_ARCH_CHECK_ID_NONE; |
| } |
| data[0] = X86_REG8X | 4; |
| return YASM_ARCH_CHECK_ID_REG; |
| } |
| B P L { |
| if (arch_x86->mode_bits != 64) { |
| yasm__warning(YASM_WARN_GENERAL, line, |
| N_("`%s' is a register in 64-bit mode"), oid); |
| return YASM_ARCH_CHECK_ID_NONE; |
| } |
| data[0] = X86_REG8X | 5; |
| return YASM_ARCH_CHECK_ID_REG; |
| } |
| S I L { |
| if (arch_x86->mode_bits != 64) { |
| yasm__warning(YASM_WARN_GENERAL, line, |
| N_("`%s' is a register in 64-bit mode"), oid); |
| return YASM_ARCH_CHECK_ID_NONE; |
| } |
| data[0] = X86_REG8X | 6; |
| return YASM_ARCH_CHECK_ID_REG; |
| } |
| D I L { |
| if (arch_x86->mode_bits != 64) { |
| yasm__warning(YASM_WARN_GENERAL, line, |
| N_("`%s' is a register in 64-bit mode"), oid); |
| return YASM_ARCH_CHECK_ID_NONE; |
| } |
| data[0] = X86_REG8X | 7; |
| return YASM_ARCH_CHECK_ID_REG; |
| } |
| R [8-9] B { |
| if (arch_x86->mode_bits != 64) { |
| yasm__warning(YASM_WARN_GENERAL, line, |
| N_("`%s' is a register in 64-bit mode"), oid); |
| return YASM_ARCH_CHECK_ID_NONE; |
| } |
| data[0] = X86_REG8 | (oid[1]-'0'); |
| return YASM_ARCH_CHECK_ID_REG; |
| } |
| R "1" [0-5] B { |
| if (arch_x86->mode_bits != 64) { |
| yasm__warning(YASM_WARN_GENERAL, line, |
| N_("`%s' is a register in 64-bit mode"), oid); |
| return YASM_ARCH_CHECK_ID_NONE; |
| } |
| data[0] = X86_REG8 | (10+oid[2]-'0'); |
| return YASM_ARCH_CHECK_ID_REG; |
| } |
| |
| /* segment registers */ |
| E S { |
| if (arch_x86->mode_bits == 64) |
| yasm__warning(YASM_WARN_GENERAL, line, |
| N_("`%s' segment register ignored in 64-bit mode"), oid); |
| data[0] = 0x2600; |
| return YASM_ARCH_CHECK_ID_SEGREG; |
| } |
| C S { data[0] = 0x2e01; return YASM_ARCH_CHECK_ID_SEGREG; } |
| S S { |
| if (arch_x86->mode_bits == 64) |
| yasm__warning(YASM_WARN_GENERAL, line, |
| N_("`%s' segment register ignored in 64-bit mode"), oid); |
| data[0] = 0x3602; |
| return YASM_ARCH_CHECK_ID_SEGREG; |
| } |
| D S { |
| if (arch_x86->mode_bits == 64) |
| yasm__warning(YASM_WARN_GENERAL, line, |
| N_("`%s' segment register ignored in 64-bit mode"), oid); |
| data[0] = 0x3e03; |
| return YASM_ARCH_CHECK_ID_SEGREG; |
| } |
| F S { data[0] = 0x6404; return YASM_ARCH_CHECK_ID_SEGREG; } |
| G S { data[0] = 0x6505; return YASM_ARCH_CHECK_ID_SEGREG; } |
| |
| /* RIP for 64-bit mode IP-relative offsets */ |
| R I P { |
| if (arch_x86->mode_bits != 64) { |
| yasm__warning(YASM_WARN_GENERAL, line, |
| N_("`%s' is a register in 64-bit mode"), oid); |
| return YASM_ARCH_CHECK_ID_NONE; |
| } |
| data[0] = X86_RIP; |
| return YASM_ARCH_CHECK_ID_REG; |
| } |
| |
| /* instructions */ |
| |
| /* Move */ |
| M O V { RET_INSN(mov, 0, CPU_Any); } |
| /* Move with sign/zero extend */ |
| M O V S X { RET_INSN(movszx, 0xBE, CPU_386); } |
| M O V S X D { |
| if (arch_x86->mode_bits != 64) { |
| yasm__warning(YASM_WARN_GENERAL, line, |
| N_("`%s' is an instruction in 64-bit mode"), |
| oid); |
| return YASM_ARCH_CHECK_ID_NONE; |
| } |
| RET_INSN(movsxd, 0, CPU_Hammer|CPU_64); |
| } |
| M O V Z X { RET_INSN(movszx, 0xB6, CPU_386); } |
| /* Push instructions */ |
| P U S H { RET_INSN(push, 0, CPU_Any); } |
| P U S H A { |
| if (arch_x86->mode_bits == 64) { |
| yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid); |
| RET_INSN(not64, 0, CPU_Not64); |
| } |
| RET_INSN(onebyte, 0x0060, CPU_186); |
| } |
| P U S H A D { |
| if (arch_x86->mode_bits == 64) { |
| yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid); |
| RET_INSN(not64, 0, CPU_Not64); |
| } |
| RET_INSN(onebyte, 0x2060, CPU_386); |
| } |
| P U S H A W { |
| if (arch_x86->mode_bits == 64) { |
| yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid); |
| RET_INSN(not64, 0, CPU_Not64); |
| } |
| RET_INSN(onebyte, 0x1060, CPU_186); |
| } |
| /* Pop instructions */ |
| P O P { RET_INSN(pop, 0, CPU_Any); } |
| P O P A { |
| if (arch_x86->mode_bits == 64) { |
| yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid); |
| RET_INSN(not64, 0, CPU_Not64); |
| } |
| RET_INSN(onebyte, 0x0061, CPU_186); |
| } |
| P O P A D { |
| if (arch_x86->mode_bits == 64) { |
| yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid); |
| RET_INSN(not64, 0, CPU_Not64); |
| } |
| RET_INSN(onebyte, 0x2061, CPU_386); |
| } |
| P O P A W { |
| if (arch_x86->mode_bits == 64) { |
| yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid); |
| RET_INSN(not64, 0, CPU_Not64); |
| } |
| RET_INSN(onebyte, 0x1061, CPU_186); |
| } |
| /* Exchange */ |
| X C H G { RET_INSN(xchg, 0, CPU_Any); } |
| /* In/out from ports */ |
| I N { RET_INSN(in, 0, CPU_Any); } |
| O U T { RET_INSN(out, 0, CPU_Any); } |
| /* Load effective address */ |
| L E A { RET_INSN(lea, 0, CPU_Any); } |
| /* Load segment registers from memory */ |
| L D S { |
| if (arch_x86->mode_bits == 64) { |
| yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid); |
| RET_INSN(not64, 0, CPU_Not64); |
| } |
| RET_INSN(ldes, 0xC5, CPU_Any); |
| } |
| L E S { |
| if (arch_x86->mode_bits == 64) { |
| yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid); |
| RET_INSN(not64, 0, CPU_Not64); |
| } |
| RET_INSN(ldes, 0xC4, CPU_Any); |
| } |
| L F S { RET_INSN(lfgss, 0xB4, CPU_386); } |
| L G S { RET_INSN(lfgss, 0xB5, CPU_386); } |
| L S S { RET_INSN(lfgss, 0xB6, CPU_386); } |
| /* Flags register instructions */ |
| C L C { RET_INSN(onebyte, 0x00F8, CPU_Any); } |
| C L D { RET_INSN(onebyte, 0x00FC, CPU_Any); } |
| C L I { RET_INSN(onebyte, 0x00FA, CPU_Any); } |
| C L T S { RET_INSN(twobyte, 0x0F06, CPU_286|CPU_Priv); } |
| C M C { RET_INSN(onebyte, 0x00F5, CPU_Any); } |
| L A H F { |
| if (arch_x86->mode_bits == 64) { |
| yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid); |
| RET_INSN(not64, 0, CPU_Not64); |
| } |
| RET_INSN(onebyte, 0x009F, CPU_Any); |
| } |
| S A H F { |
| if (arch_x86->mode_bits == 64) { |
| yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid); |
| RET_INSN(not64, 0, CPU_Not64); |
| } |
| RET_INSN(onebyte, 0x009E, CPU_Any); |
| } |
| P U S H F { RET_INSN(onebyte, 0x009C, CPU_Any); } |
| P U S H F D { RET_INSN(onebyte, 0x209C, CPU_386); } |
| P U S H F W { RET_INSN(onebyte, 0x109C, CPU_Any); } |
| P U S H F Q { |
| if (arch_x86->mode_bits != 64) { |
| yasm__warning(YASM_WARN_GENERAL, line, |
| N_("`%s' is an instruction in 64-bit mode"), |
| oid); |
| return YASM_ARCH_CHECK_ID_NONE; |
| } |
| RET_INSN(onebyte, 0x409C, CPU_Hammer|CPU_64); |
| } |
| P O P F { RET_INSN(onebyte, 0x40009D, CPU_Any); } |
| P O P F D { |
| if (arch_x86->mode_bits == 64) { |
| yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid); |
| RET_INSN(not64, 0, CPU_Not64); |
| } |
| RET_INSN(onebyte, 0x00209D, CPU_386); |
| } |
| P O P F W { RET_INSN(onebyte, 0x40109D, CPU_Any); } |
| P O P F Q { |
| if (arch_x86->mode_bits != 64) { |
| yasm__warning(YASM_WARN_GENERAL, line, |
| N_("`%s' is an instruction in 64-bit mode"), |
| oid); |
| return YASM_ARCH_CHECK_ID_NONE; |
| } |
| RET_INSN(onebyte, 0x40409D, CPU_Hammer|CPU_64); |
| } |
| S T C { RET_INSN(onebyte, 0x00F9, CPU_Any); } |
| S T D { RET_INSN(onebyte, 0x00FD, CPU_Any); } |
| S T I { RET_INSN(onebyte, 0x00FB, CPU_Any); } |
| /* Arithmetic */ |
| A D D { RET_INSN(arith, 0x0000, CPU_Any); } |
| I N C { RET_INSN(incdec, 0x0040, CPU_Any); } |
| S U B { RET_INSN(arith, 0x0528, CPU_Any); } |
| D E C { RET_INSN(incdec, 0x0148, CPU_Any); } |
| S B B { RET_INSN(arith, 0x0318, CPU_Any); } |
| C M P { RET_INSN(arith, 0x0738, CPU_Any); } |
| T E S T { RET_INSN(test, 0, CPU_Any); } |
| A N D { RET_INSN(arith, 0x0420, CPU_Any); } |
| O R { RET_INSN(arith, 0x0108, CPU_Any); } |
| X O R { RET_INSN(arith, 0x0630, CPU_Any); } |
| A D C { RET_INSN(arith, 0x0210, CPU_Any); } |
| N E G { RET_INSN(f6, 0x03, CPU_Any); } |
| N O T { RET_INSN(f6, 0x02, CPU_Any); } |
| A A A { |
| if (arch_x86->mode_bits == 64) { |
| yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid); |
| RET_INSN(not64, 0, CPU_Not64); |
| } |
| RET_INSN(onebyte, 0x0037, CPU_Any); |
| } |
| A A S { |
| if (arch_x86->mode_bits == 64) { |
| yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid); |
| RET_INSN(not64, 0, CPU_Not64); |
| } |
| RET_INSN(onebyte, 0x003F, CPU_Any); |
| } |
| D A A { |
| if (arch_x86->mode_bits == 64) { |
| yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid); |
| RET_INSN(not64, 0, CPU_Not64); |
| } |
| RET_INSN(onebyte, 0x0027, CPU_Any); |
| } |
| D A S { |
| if (arch_x86->mode_bits == 64) { |
| yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid); |
| RET_INSN(not64, 0, CPU_Not64); |
| } |
| RET_INSN(onebyte, 0x002F, CPU_Any); |
| } |
| A A D { |
| if (arch_x86->mode_bits == 64) { |
| yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid); |
| RET_INSN(not64, 0, CPU_Not64); |
| } |
| RET_INSN(aadm, 0x01, CPU_Any); |
| } |
| A A M { |
| if (arch_x86->mode_bits == 64) { |
| yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid); |
| RET_INSN(not64, 0, CPU_Not64); |
| } |
| RET_INSN(aadm, 0x00, CPU_Any); |
| } |
| /* Conversion instructions */ |
| C B W { RET_INSN(onebyte, 0x1098, CPU_Any); } |
| C W D E { RET_INSN(onebyte, 0x2098, CPU_386); } |
| C D Q E { |
| if (arch_x86->mode_bits != 64) { |
| yasm__warning(YASM_WARN_GENERAL, line, |
| N_("`%s' is an instruction in 64-bit mode"), |
| oid); |
| return YASM_ARCH_CHECK_ID_NONE; |
| } |
| RET_INSN(onebyte, 0x4098, CPU_Hammer|CPU_64); |
| } |
| C W D { RET_INSN(onebyte, 0x1099, CPU_Any); } |
| C D Q { RET_INSN(onebyte, 0x2099, CPU_386); } |
| C D O { |
| if (arch_x86->mode_bits != 64) { |
| yasm__warning(YASM_WARN_GENERAL, line, |
| N_("`%s' is an instruction in 64-bit mode"), |
| oid); |
| return YASM_ARCH_CHECK_ID_NONE; |
| } |
| RET_INSN(onebyte, 0x4099, CPU_Hammer|CPU_64); |
| } |
| /* Multiplication and division */ |
| M U L { RET_INSN(f6, 0x04, CPU_Any); } |
| I M U L { RET_INSN(imul, 0, CPU_Any); } |
| D I V { RET_INSN(f6, 0x06, CPU_Any); } |
| I D I V { RET_INSN(f6, 0x07, CPU_Any); } |
| /* Shifts */ |
| R O L { RET_INSN(shift, 0x00, CPU_Any); } |
| R O R { RET_INSN(shift, 0x01, CPU_Any); } |
| R C L { RET_INSN(shift, 0x02, CPU_Any); } |
| R C R { RET_INSN(shift, 0x03, CPU_Any); } |
| S A L { RET_INSN(shift, 0x04, CPU_Any); } |
| S H L { RET_INSN(shift, 0x04, CPU_Any); } |
| S H R { RET_INSN(shift, 0x05, CPU_Any); } |
| S A R { RET_INSN(shift, 0x07, CPU_Any); } |
| S H L D { RET_INSN(shlrd, 0xA4, CPU_386); } |
| S H R D { RET_INSN(shlrd, 0xAC, CPU_386); } |
| /* Control transfer instructions (unconditional) */ |
| C A L L { RET_INSN(call, 0, CPU_Any); } |
| J M P { RET_INSN(jmp, 0, CPU_Any); } |
| R E T { RET_INSN(retnf, 0xC2, CPU_Any); } |
| R E T N { RET_INSN(retnf, 0xC2, CPU_Any); } |
| R E T F { RET_INSN(retnf, 0xCA, CPU_Any); } |
| E N T E R { RET_INSN(enter, 0, CPU_186); } |
| L E A V E { RET_INSN(onebyte, 0x4000C9, CPU_186); } |
| /* Conditional jumps */ |
| J O { RET_INSN(jcc, 0x00, CPU_Any); } |
| J N O { RET_INSN(jcc, 0x01, CPU_Any); } |
| J B { RET_INSN(jcc, 0x02, CPU_Any); } |
| J C { RET_INSN(jcc, 0x02, CPU_Any); } |
| J N A E { RET_INSN(jcc, 0x02, CPU_Any); } |
| J N B { RET_INSN(jcc, 0x03, CPU_Any); } |
| J N C { RET_INSN(jcc, 0x03, CPU_Any); } |
| J A E { RET_INSN(jcc, 0x03, CPU_Any); } |
| J E { RET_INSN(jcc, 0x04, CPU_Any); } |
| J Z { RET_INSN(jcc, 0x04, CPU_Any); } |
| J N E { RET_INSN(jcc, 0x05, CPU_Any); } |
| J N Z { RET_INSN(jcc, 0x05, CPU_Any); } |
| J B E { RET_INSN(jcc, 0x06, CPU_Any); } |
| J N A { RET_INSN(jcc, 0x06, CPU_Any); } |
| J N B E { RET_INSN(jcc, 0x07, CPU_Any); } |
| J A { RET_INSN(jcc, 0x07, CPU_Any); } |
| J S { RET_INSN(jcc, 0x08, CPU_Any); } |
| J N S { RET_INSN(jcc, 0x09, CPU_Any); } |
| J P { RET_INSN(jcc, 0x0A, CPU_Any); } |
| J P E { RET_INSN(jcc, 0x0A, CPU_Any); } |
| J N P { RET_INSN(jcc, 0x0B, CPU_Any); } |
| J P O { RET_INSN(jcc, 0x0B, CPU_Any); } |
| J L { RET_INSN(jcc, 0x0C, CPU_Any); } |
| J N G E { RET_INSN(jcc, 0x0C, CPU_Any); } |
| J N L { RET_INSN(jcc, 0x0D, CPU_Any); } |
| J G E { RET_INSN(jcc, 0x0D, CPU_Any); } |
| J L E { RET_INSN(jcc, 0x0E, CPU_Any); } |
| J N G { RET_INSN(jcc, 0x0E, CPU_Any); } |
| J N L E { RET_INSN(jcc, 0x0F, CPU_Any); } |
| J G { RET_INSN(jcc, 0x0F, CPU_Any); } |
| J C X Z { RET_INSN(jcxz, 16, CPU_Any); } |
| J E C X Z { RET_INSN(jcxz, 32, CPU_386); } |
| J R C X Z { |
| if (arch_x86->mode_bits != 64) { |
| yasm__warning(YASM_WARN_GENERAL, line, |
| N_("`%s' is an instruction in 64-bit mode"), |
| oid); |
| return YASM_ARCH_CHECK_ID_NONE; |
| } |
| RET_INSN(jcxz, 64, CPU_Hammer|CPU_64); |
| } |
| /* Loop instructions */ |
| L O O P { RET_INSN(loop, 0x02, CPU_Any); } |
| L O O P Z { RET_INSN(loop, 0x01, CPU_Any); } |
| L O O P E { RET_INSN(loop, 0x01, CPU_Any); } |
| L O O P N Z { RET_INSN(loop, 0x00, CPU_Any); } |
| L O O P N E { RET_INSN(loop, 0x00, CPU_Any); } |
| /* Set byte on flag instructions */ |
| S E T O { RET_INSN(setcc, 0x00, CPU_386); } |
| S E T N O { RET_INSN(setcc, 0x01, CPU_386); } |
| S E T B { RET_INSN(setcc, 0x02, CPU_386); } |
| S E T C { RET_INSN(setcc, 0x02, CPU_386); } |
| S E T N A E { RET_INSN(setcc, 0x02, CPU_386); } |
| S E T N B { RET_INSN(setcc, 0x03, CPU_386); } |
| S E T N C { RET_INSN(setcc, 0x03, CPU_386); } |
| S E T A E { RET_INSN(setcc, 0x03, CPU_386); } |
| S E T E { RET_INSN(setcc, 0x04, CPU_386); } |
| S E T Z { RET_INSN(setcc, 0x04, CPU_386); } |
| S E T N E { RET_INSN(setcc, 0x05, CPU_386); } |
| S E T N Z { RET_INSN(setcc, 0x05, CPU_386); } |
| S E T B E { RET_INSN(setcc, 0x06, CPU_386); } |
| S E T N A { RET_INSN(setcc, 0x06, CPU_386); } |
| S E T N B E { RET_INSN(setcc, 0x07, CPU_386); } |
| S E T A { RET_INSN(setcc, 0x07, CPU_386); } |
| S E T S { RET_INSN(setcc, 0x08, CPU_386); } |
| S E T N S { RET_INSN(setcc, 0x09, CPU_386); } |
| S E T P { RET_INSN(setcc, 0x0A, CPU_386); } |
| S E T P E { RET_INSN(setcc, 0x0A, CPU_386); } |
| S E T N P { RET_INSN(setcc, 0x0B, CPU_386); } |
| S E T P O { RET_INSN(setcc, 0x0B, CPU_386); } |
| S E T L { RET_INSN(setcc, 0x0C, CPU_386); } |
| S E T N G E { RET_INSN(setcc, 0x0C, CPU_386); } |
| S E T N L { RET_INSN(setcc, 0x0D, CPU_386); } |
| S E T G E { RET_INSN(setcc, 0x0D, CPU_386); } |
| S E T L E { RET_INSN(setcc, 0x0E, CPU_386); } |
| S E T N G { RET_INSN(setcc, 0x0E, CPU_386); } |
| S E T N L E { RET_INSN(setcc, 0x0F, CPU_386); } |
| S E T G { RET_INSN(setcc, 0x0F, CPU_386); } |
| /* String instructions. */ |
| C M P S B { RET_INSN(onebyte, 0x00A6, CPU_Any); } |
| C M P S W { RET_INSN(onebyte, 0x10A7, CPU_Any); } |
| C M P S D { RET_INSN(cmpsd, 0, CPU_Any); } |
| C M P S Q { |
| if (arch_x86->mode_bits != 64) { |
| yasm__warning(YASM_WARN_GENERAL, line, |
| N_("`%s' is an instruction in 64-bit mode"), |
| oid); |
| return YASM_ARCH_CHECK_ID_NONE; |
| } |
| RET_INSN(onebyte, 0x40A7, CPU_Hammer|CPU_64); |
| } |
| I N S B { RET_INSN(onebyte, 0x006C, CPU_Any); } |
| I N S W { RET_INSN(onebyte, 0x106D, CPU_Any); } |
| I N S D { RET_INSN(onebyte, 0x206D, CPU_386); } |
| O U T S B { RET_INSN(onebyte, 0x006E, CPU_Any); } |
| O U T S W { RET_INSN(onebyte, 0x106F, CPU_Any); } |
| O U T S D { RET_INSN(onebyte, 0x206F, CPU_386); } |
| L O D S B { RET_INSN(onebyte, 0x00AC, CPU_Any); } |
| L O D S W { RET_INSN(onebyte, 0x10AD, CPU_Any); } |
| L O D S D { RET_INSN(onebyte, 0x20AD, CPU_386); } |
| L O D S Q { |
| if (arch_x86->mode_bits != 64) { |
| yasm__warning(YASM_WARN_GENERAL, line, |
| N_("`%s' is an instruction in 64-bit mode"), |
| oid); |
| return YASM_ARCH_CHECK_ID_NONE; |
| } |
| RET_INSN(onebyte, 0x40AD, CPU_Hammer|CPU_64); |
| } |
| M O V S B { RET_INSN(onebyte, 0x00A4, CPU_Any); } |
| M O V S W { RET_INSN(onebyte, 0x10A5, CPU_Any); } |
| M O V S D { RET_INSN(movsd, 0, CPU_Any); } |
| M O V S Q { |
| if (arch_x86->mode_bits != 64) { |
| yasm__warning(YASM_WARN_GENERAL, line, |
| N_("`%s' is an instruction in 64-bit mode"), |
| oid); |
| return YASM_ARCH_CHECK_ID_NONE; |
| } |
| RET_INSN(onebyte, 0x40A5, CPU_Any); |
| } |
| S C A S B { RET_INSN(onebyte, 0x00AE, CPU_Any); } |
| S C A S W { RET_INSN(onebyte, 0x10AF, CPU_Any); } |
| S C A S D { RET_INSN(onebyte, 0x20AF, CPU_386); } |
| S C A S Q { |
| if (arch_x86->mode_bits != 64) { |
| yasm__warning(YASM_WARN_GENERAL, line, |
| N_("`%s' is an instruction in 64-bit mode"), |
| oid); |
| return YASM_ARCH_CHECK_ID_NONE; |
| } |
| RET_INSN(onebyte, 0x40AF, CPU_Hammer|CPU_64); |
| } |
| S T O S B { RET_INSN(onebyte, 0x00AA, CPU_Any); } |
| S T O S W { RET_INSN(onebyte, 0x10AB, CPU_Any); } |
| S T O S D { RET_INSN(onebyte, 0x20AB, CPU_386); } |
| S T O S Q { |
| if (arch_x86->mode_bits != 64) { |
| yasm__warning(YASM_WARN_GENERAL, line, |
| N_("`%s' is an instruction in 64-bit mode"), |
| oid); |
| return YASM_ARCH_CHECK_ID_NONE; |
| } |
| RET_INSN(onebyte, 0x40AB, CPU_Hammer|CPU_64); |
| } |
| X L A T B? { RET_INSN(onebyte, 0x00D7, CPU_Any); } |
| /* Bit manipulation */ |
| B S F { RET_INSN(bsfr, 0xBC, CPU_386); } |
| B S R { RET_INSN(bsfr, 0xBD, CPU_386); } |
| B T { RET_INSN(bittest, 0x04A3, CPU_386); } |
| B T C { RET_INSN(bittest, 0x07BB, CPU_386); } |
| B T R { RET_INSN(bittest, 0x06B3, CPU_386); } |
| B T S { RET_INSN(bittest, 0x05AB, CPU_386); } |
| /* Interrupts and operating system instructions */ |
| I N T { RET_INSN(int, 0, CPU_Any); } |
| I N T "3" { RET_INSN(onebyte, 0x00CC, CPU_Any); } |
| I N T "03" { RET_INSN(onebyte, 0x00CC, CPU_Any); } |
| I N T O { |
| if (arch_x86->mode_bits == 64) { |
| yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid); |
| RET_INSN(not64, 0, CPU_Not64); |
| } |
| RET_INSN(onebyte, 0x00CE, CPU_Any); |
| } |
| I R E T { RET_INSN(onebyte, 0x00CF, CPU_Any); } |
| I R E T W { RET_INSN(onebyte, 0x10CF, CPU_Any); } |
| I R E T D { RET_INSN(onebyte, 0x20CF, CPU_386); } |
| I R E T Q { |
| if (arch_x86->mode_bits != 64) { |
| yasm__warning(YASM_WARN_GENERAL, line, |
| N_("`%s' is an instruction in 64-bit mode"), |
| oid); |
| return YASM_ARCH_CHECK_ID_NONE; |
| } |
| RET_INSN(onebyte, 0x40CF, CPU_Hammer|CPU_64); |
| } |
| R S M { RET_INSN(twobyte, 0x0FAA, CPU_586|CPU_SMM); } |
| B O U N D { |
| if (arch_x86->mode_bits == 64) { |
| yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid); |
| RET_INSN(not64, 0, CPU_Not64); |
| } |
| RET_INSN(bound, 0, CPU_186); |
| } |
| H L T { RET_INSN(onebyte, 0x00F4, CPU_Priv); } |
| N O P { RET_INSN(onebyte, 0x0090, CPU_Any); } |
| /* Protection control */ |
| A R P L { |
| if (arch_x86->mode_bits == 64) { |
| yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid); |
| RET_INSN(not64, 0, CPU_Not64); |
| } |
| RET_INSN(arpl, 0, CPU_286|CPU_Prot); |
| } |
| L A R { RET_INSN(bsfr, 0x02, CPU_286|CPU_Prot); } |
| L G D T { RET_INSN(twobytemem, 0x020F01, CPU_286|CPU_Priv); } |
| L I D T { RET_INSN(twobytemem, 0x030F01, CPU_286|CPU_Priv); } |
| L L D T { RET_INSN(prot286, 0x0200, CPU_286|CPU_Prot|CPU_Priv); } |
| L M S W { RET_INSN(prot286, 0x0601, CPU_286|CPU_Priv); } |
| L S L { RET_INSN(bsfr, 0x03, CPU_286|CPU_Prot); } |
| L T R { RET_INSN(prot286, 0x0300, CPU_286|CPU_Prot|CPU_Priv); } |
| S G D T { RET_INSN(twobytemem, 0x000F01, CPU_286|CPU_Priv); } |
| S I D T { RET_INSN(twobytemem, 0x010F01, CPU_286|CPU_Priv); } |
| S L D T { RET_INSN(sldtmsw, 0x0000, CPU_286); } |
| S M S W { RET_INSN(sldtmsw, 0x0401, CPU_286); } |
| S T R { RET_INSN(str, 0, CPU_286|CPU_Prot); } |
| V E R R { RET_INSN(prot286, 0x0400, CPU_286|CPU_Prot); } |
| V E R W { RET_INSN(prot286, 0x0500, CPU_286|CPU_Prot); } |
| /* Floating point instructions */ |
| F L D { RET_INSN(fldstp, 0x0500C0, CPU_FPU); } |
| F I L D { RET_INSN(fildstp, 0x0500, CPU_FPU); } |
| F B L D { RET_INSN(fbldstp, 0x04, CPU_FPU); } |
| F S T { RET_INSN(fst, 0, CPU_FPU); } |
| F I S T { RET_INSN(fiarith, 0x02DB, CPU_FPU); } |
| F S T P { RET_INSN(fldstp, 0x0703D8, CPU_FPU); } |
| F I S T P { RET_INSN(fildstp, 0x0703, CPU_FPU); } |
| F B S T P { RET_INSN(fbldstp, 0x06, CPU_FPU); } |
| F X C H { RET_INSN(fxch, 0, CPU_FPU); } |
| F C O M { RET_INSN(fcom, 0x02D0, CPU_FPU); } |
| F I C O M { RET_INSN(fiarith, 0x02DA, CPU_FPU); } |
| F C O M P { RET_INSN(fcom, 0x03D8, CPU_FPU); } |
| F I C O M P { RET_INSN(fiarith, 0x03DA, CPU_FPU); } |
| F C O M P P { RET_INSN(twobyte, 0xDED9, CPU_FPU); } |
| F U C O M { RET_INSN(fcom2, 0xDDE0, CPU_286|CPU_FPU); } |
| F U C O M P { RET_INSN(fcom2, 0xDDE8, CPU_286|CPU_FPU); } |
| F U C O M P P { RET_INSN(twobyte, 0xDAE9, CPU_286|CPU_FPU); } |
| F T S T { RET_INSN(twobyte, 0xD9E4, CPU_FPU); } |
| F X A M { RET_INSN(twobyte, 0xD9E5, CPU_FPU); } |
| F L D "1" { RET_INSN(twobyte, 0xD9E8, CPU_FPU); } |
| F L D L "2" T { RET_INSN(twobyte, 0xD9E9, CPU_FPU); } |
| F L D L "2" E { RET_INSN(twobyte, 0xD9EA, CPU_FPU); } |
| F L D P I { RET_INSN(twobyte, 0xD9EB, CPU_FPU); } |
| F L D L G "2" { RET_INSN(twobyte, 0xD9EC, CPU_FPU); } |
| F L D L N "2" { RET_INSN(twobyte, 0xD9ED, CPU_FPU); } |
| F L D Z { RET_INSN(twobyte, 0xD9EE, CPU_FPU); } |
| F A D D { RET_INSN(farith, 0x00C0C0, CPU_FPU); } |
| F A D D P { RET_INSN(farithp, 0xC0, CPU_FPU); } |
| F I A D D { RET_INSN(fiarith, 0x00DA, CPU_FPU); } |
| F S U B { RET_INSN(farith, 0x04E0E8, CPU_FPU); } |
| F I S U B { RET_INSN(fiarith, 0x04DA, CPU_FPU); } |
| F S U B P { RET_INSN(farithp, 0xE8, CPU_FPU); } |
| F S U B R { RET_INSN(farith, 0x05E8E0, CPU_FPU); } |
| F I S U B R { RET_INSN(fiarith, 0x05DA, CPU_FPU); } |
| F S U B R P { RET_INSN(farithp, 0xE0, CPU_FPU); } |
| F M U L { RET_INSN(farith, 0x01C8C8, CPU_FPU); } |
| F I M U L { RET_INSN(fiarith, 0x01DA, CPU_FPU); } |
| F M U L P { RET_INSN(farithp, 0xC8, CPU_FPU); } |
| F D I V { RET_INSN(farith, 0x06F0F8, CPU_FPU); } |
| F I D I V { RET_INSN(fiarith, 0x06DA, CPU_FPU); } |
| F D I V P { RET_INSN(farithp, 0xF8, CPU_FPU); } |
| F D I V R { RET_INSN(farith, 0x07F8F0, CPU_FPU); } |
| F I D I V R { RET_INSN(fiarith, 0x07DA, CPU_FPU); } |
| F D I V R P { RET_INSN(farithp, 0xF0, CPU_FPU); } |
| F "2" X M "1" { RET_INSN(twobyte, 0xD9F0, CPU_FPU); } |
| F Y L "2" X { RET_INSN(twobyte, 0xD9F1, CPU_FPU); } |
| F P T A N { RET_INSN(twobyte, 0xD9F2, CPU_FPU); } |
| F P A T A N { RET_INSN(twobyte, 0xD9F3, CPU_FPU); } |
| F X T R A C T { RET_INSN(twobyte, 0xD9F4, CPU_FPU); } |
| F P R E M "1" { RET_INSN(twobyte, 0xD9F5, CPU_286|CPU_FPU); } |
| F D E C S T P { RET_INSN(twobyte, 0xD9F6, CPU_FPU); } |
| F I N C S T P { RET_INSN(twobyte, 0xD9F7, CPU_FPU); } |
| F P R E M { RET_INSN(twobyte, 0xD9F8, CPU_FPU); } |
| F Y L "2" X P "1" { RET_INSN(twobyte, 0xD9F9, CPU_FPU); } |
| F S Q R T { RET_INSN(twobyte, 0xD9FA, CPU_FPU); } |
| F S I N C O S { RET_INSN(twobyte, 0xD9FB, CPU_286|CPU_FPU); } |
| F R N D I N T { RET_INSN(twobyte, 0xD9FC, CPU_FPU); } |
| F S C A L E { RET_INSN(twobyte, 0xD9FD, CPU_FPU); } |
| F S I N { RET_INSN(twobyte, 0xD9FE, CPU_286|CPU_FPU); } |
| F C O S { RET_INSN(twobyte, 0xD9FF, CPU_286|CPU_FPU); } |
| F C H S { RET_INSN(twobyte, 0xD9E0, CPU_FPU); } |
| F A B S { RET_INSN(twobyte, 0xD9E1, CPU_FPU); } |
| F N I N I T { RET_INSN(twobyte, 0xDBE3, CPU_FPU); } |
| F I N I T { RET_INSN(threebyte, 0x98DBE3UL, CPU_FPU); } |
| F L D C W { RET_INSN(fldnstcw, 0x05, CPU_FPU); } |
| F N S T C W { RET_INSN(fldnstcw, 0x07, CPU_FPU); } |
| F S T C W { RET_INSN(fstcw, 0, CPU_FPU); } |
| F N S T S W { RET_INSN(fnstsw, 0, CPU_FPU); } |
| F S T S W { RET_INSN(fstsw, 0, CPU_FPU); } |
| F N C L E X { RET_INSN(twobyte, 0xDBE2, CPU_FPU); } |
| F C L E X { RET_INSN(threebyte, 0x98DBE2UL, CPU_FPU); } |
| F N S T E N V { RET_INSN(onebytemem, 0x06D9, CPU_FPU); } |
| F S T E N V { RET_INSN(twobytemem, 0x069BD9, CPU_FPU); } |
| F L D E N V { RET_INSN(onebytemem, 0x04D9, CPU_FPU); } |
| F N S A V E { RET_INSN(onebytemem, 0x06DD, CPU_FPU); } |
| F S A V E { RET_INSN(twobytemem, 0x069BDD, CPU_FPU); } |
| F R S T O R { RET_INSN(onebytemem, 0x04DD, CPU_FPU); } |
| F F R E E { RET_INSN(ffree, 0xDD, CPU_FPU); } |
| F F R E E P { RET_INSN(ffree, 0xDF, CPU_686|CPU_FPU|CPU_Undoc); } |
| F N O P { RET_INSN(twobyte, 0xD9D0, CPU_FPU); } |
| F W A I T { RET_INSN(onebyte, 0x009B, CPU_FPU); } |
| /* Prefixes (should the others be here too? should wait be a prefix? */ |
| W A I T { RET_INSN(onebyte, 0x009B, CPU_Any); } |
| /* 486 extensions */ |
| B S W A P { RET_INSN(bswap, 0, CPU_486); } |
| X A D D { RET_INSN(cmpxchgxadd, 0xC0, CPU_486); } |
| C M P X C H G { RET_INSN(cmpxchgxadd, 0xB0, CPU_486); } |
| C M P X C H G "486" { RET_INSN(cmpxchgxadd, 0xA6, CPU_486|CPU_Undoc); } |
| I N V D { RET_INSN(twobyte, 0x0F08, CPU_486|CPU_Priv); } |
| W B I N V D { RET_INSN(twobyte, 0x0F09, CPU_486|CPU_Priv); } |
| I N V L P G { RET_INSN(twobytemem, 0x070F01, CPU_486|CPU_Priv); } |
| /* 586+ and late 486 extensions */ |
| C P U I D { RET_INSN(twobyte, 0x0FA2, CPU_486); } |
| /* Pentium extensions */ |
| W R M S R { RET_INSN(twobyte, 0x0F30, CPU_586|CPU_Priv); } |
| R D T S C { RET_INSN(twobyte, 0x0F31, CPU_586); } |
| R D M S R { RET_INSN(twobyte, 0x0F32, CPU_586|CPU_Priv); } |
| C M P X C H G "8" B { RET_INSN(cmpxchg8b, 0, CPU_586); } |
| /* Pentium II/Pentium Pro extensions */ |
| S Y S E N T E R { |
| if (arch_x86->mode_bits == 64) { |
| yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid); |
| RET_INSN(not64, 0, CPU_Not64); |
| } |
| RET_INSN(twobyte, 0x0F34, CPU_686); |
| } |
| S Y S E X I T { |
| if (arch_x86->mode_bits == 64) { |
| yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid); |
| RET_INSN(not64, 0, CPU_Not64); |
| } |
| RET_INSN(twobyte, 0x0F35, CPU_686|CPU_Priv); |
| } |
| F X S A V E { RET_INSN(twobytemem, 0x000FAE, CPU_686|CPU_FPU); } |
| F X R S T O R { RET_INSN(twobytemem, 0x010FAE, CPU_686|CPU_FPU); } |
| R D P M C { RET_INSN(twobyte, 0x0F33, CPU_686); } |
| U D "2" { RET_INSN(twobyte, 0x0F0B, CPU_286); } |
| U D "1" { RET_INSN(twobyte, 0x0FB9, CPU_286|CPU_Undoc); } |
| C M O V O { RET_INSN(cmovcc, 0x00, CPU_686); } |
| C M O V N O { RET_INSN(cmovcc, 0x01, CPU_686); } |
| C M O V B { RET_INSN(cmovcc, 0x02, CPU_686); } |
| C M O V C { RET_INSN(cmovcc, 0x02, CPU_686); } |
| C M O V N A E { RET_INSN(cmovcc, 0x02, CPU_686); } |
| C M O V N B { RET_INSN(cmovcc, 0x03, CPU_686); } |
| C M O V N C { RET_INSN(cmovcc, 0x03, CPU_686); } |
| C M O V A E { RET_INSN(cmovcc, 0x03, CPU_686); } |
| C M O V E { RET_INSN(cmovcc, 0x04, CPU_686); } |
| C M O V Z { RET_INSN(cmovcc, 0x04, CPU_686); } |
| C M O V N E { RET_INSN(cmovcc, 0x05, CPU_686); } |
| C M O V N Z { RET_INSN(cmovcc, 0x05, CPU_686); } |
| C M O V B E { RET_INSN(cmovcc, 0x06, CPU_686); } |
| C M O V N A { RET_INSN(cmovcc, 0x06, CPU_686); } |
| C M O V N B E { RET_INSN(cmovcc, 0x07, CPU_686); } |
| C M O V A { RET_INSN(cmovcc, 0x07, CPU_686); } |
| C M O V S { RET_INSN(cmovcc, 0x08, CPU_686); } |
| C M O V N S { RET_INSN(cmovcc, 0x09, CPU_686); } |
| C M O V P { RET_INSN(cmovcc, 0x0A, CPU_686); } |
| C M O V P E { RET_INSN(cmovcc, 0x0A, CPU_686); } |
| C M O V N P { RET_INSN(cmovcc, 0x0B, CPU_686); } |
| C M O V P O { RET_INSN(cmovcc, 0x0B, CPU_686); } |
| C M O V L { RET_INSN(cmovcc, 0x0C, CPU_686); } |
| C M O V N G E { RET_INSN(cmovcc, 0x0C, CPU_686); } |
| C M O V N L { RET_INSN(cmovcc, 0x0D, CPU_686); } |
| C M O V G E { RET_INSN(cmovcc, 0x0D, CPU_686); } |
| C M O V L E { RET_INSN(cmovcc, 0x0E, CPU_686); } |
| C M O V N G { RET_INSN(cmovcc, 0x0E, CPU_686); } |
| C M O V N L E { RET_INSN(cmovcc, 0x0F, CPU_686); } |
| C M O V G { RET_INSN(cmovcc, 0x0F, CPU_686); } |
| F C M O V B { RET_INSN(fcmovcc, 0xDAC0, CPU_686|CPU_FPU); } |
| F C M O V E { RET_INSN(fcmovcc, 0xDAC8, CPU_686|CPU_FPU); } |
| F C M O V B E { RET_INSN(fcmovcc, 0xDAD0, CPU_686|CPU_FPU); } |
| F C M O V U { RET_INSN(fcmovcc, 0xDAD8, CPU_686|CPU_FPU); } |
| F C M O V N B { RET_INSN(fcmovcc, 0xDBC0, CPU_686|CPU_FPU); } |
| F C M O V N E { RET_INSN(fcmovcc, 0xDBC8, CPU_686|CPU_FPU); } |
| F C M O V N B E { RET_INSN(fcmovcc, 0xDBD0, CPU_686|CPU_FPU); } |
| F C M O V U { RET_INSN(fcmovcc, 0xDBD8, CPU_686|CPU_FPU); } |
| F C O M I { RET_INSN(fcom2, 0xDBF0, CPU_686|CPU_FPU); } |
| F U C O M I { RET_INSN(fcom2, 0xDBE8, CPU_686|CPU_FPU); } |
| F C O M I P { RET_INSN(fcom2, 0xDFF0, CPU_686|CPU_FPU); } |
| F U C O M I P { RET_INSN(fcom2, 0xDFE8, CPU_686|CPU_FPU); } |
| /* Pentium4 extensions */ |
| M O V N T I { RET_INSN(movnti, 0, CPU_P4); } |
| C L F L U S H { RET_INSN(clflush, 0, CPU_P3); } |
| L F E N C E { RET_INSN(threebyte, 0x0FAEE8, CPU_P3); } |
| M F E N C E { RET_INSN(threebyte, 0x0FAEF0, CPU_P3); } |
| P A U S E { RET_INSN(twobyte, 0xF390, CPU_P4); } |
| /* MMX/SSE2 instructions */ |
| E M M S { RET_INSN(twobyte, 0x0F77, CPU_MMX); } |
| M O V D { RET_INSN(movd, 0, CPU_MMX); } |
| M O V Q { RET_INSN(movq, 0, CPU_MMX); } |
| P A C K S S D W { RET_INSN(mmxsse2, 0x6B, CPU_MMX); } |
| P A C K S S W B { RET_INSN(mmxsse2, 0x63, CPU_MMX); } |
| P A C K U S W B { RET_INSN(mmxsse2, 0x67, CPU_MMX); } |
| P A D D B { RET_INSN(mmxsse2, 0xFC, CPU_MMX); } |
| P A D D W { RET_INSN(mmxsse2, 0xFD, CPU_MMX); } |
| P A D D D { RET_INSN(mmxsse2, 0xFE, CPU_MMX); } |
| P A D D Q { RET_INSN(mmxsse2, 0xD4, CPU_MMX); } |
| P A D D S B { RET_INSN(mmxsse2, 0xEC, CPU_MMX); } |
| P A D D S W { RET_INSN(mmxsse2, 0xED, CPU_MMX); } |
| P A D D U S B { RET_INSN(mmxsse2, 0xDC, CPU_MMX); } |
| P A D D U S W { RET_INSN(mmxsse2, 0xDD, CPU_MMX); } |
| P A N D { RET_INSN(mmxsse2, 0xDB, CPU_MMX); } |
| P A N D N { RET_INSN(mmxsse2, 0xDF, CPU_MMX); } |
| P A C M P E Q B { RET_INSN(mmxsse2, 0x74, CPU_MMX); } |
| P A C M P E Q W { RET_INSN(mmxsse2, 0x75, CPU_MMX); } |
| P A C M P E Q D { RET_INSN(mmxsse2, 0x76, CPU_MMX); } |
| P A C M P G T B { RET_INSN(mmxsse2, 0x64, CPU_MMX); } |
| P A C M P G T W { RET_INSN(mmxsse2, 0x65, CPU_MMX); } |
| P A C M P G T D { RET_INSN(mmxsse2, 0x66, CPU_MMX); } |
| P M A D D W D { RET_INSN(mmxsse2, 0xF5, CPU_MMX); } |
| P M U L H W { RET_INSN(mmxsse2, 0xE5, CPU_MMX); } |
| P M U L L W { RET_INSN(mmxsse2, 0xD5, CPU_MMX); } |
| P O R { RET_INSN(mmxsse2, 0xEB, CPU_MMX); } |
| P S L L W { RET_INSN(pshift, 0x0671F1, CPU_MMX); } |
| P S L L D { RET_INSN(pshift, 0x0672F2, CPU_MMX); } |
| P S L L Q { RET_INSN(pshift, 0x0673F3, CPU_MMX); } |
| P S R A W { RET_INSN(pshift, 0x0471E1, CPU_MMX); } |
| P S R A D { RET_INSN(pshift, 0x0472E2, CPU_MMX); } |
| P S R L W { RET_INSN(pshift, 0x0271D1, CPU_MMX); } |
| P S R L D { RET_INSN(pshift, 0x0272D2, CPU_MMX); } |
| P S R L Q { RET_INSN(pshift, 0x0273D3, CPU_MMX); } |
| P S U B B { RET_INSN(mmxsse2, 0xF8, CPU_MMX); } |
| P S U B W { RET_INSN(mmxsse2, 0xF9, CPU_MMX); } |
| P S U B D { RET_INSN(mmxsse2, 0xFA, CPU_MMX); } |
| P S U B Q { RET_INSN(mmxsse2, 0xFB, CPU_MMX); } |
| P S U B S B { RET_INSN(mmxsse2, 0xE8, CPU_MMX); } |
| P S U B S W { RET_INSN(mmxsse2, 0xE9, CPU_MMX); } |
| P S U B U S B { RET_INSN(mmxsse2, 0xD8, CPU_MMX); } |
| P S U B U S W { RET_INSN(mmxsse2, 0xD9, CPU_MMX); } |
| P U N P C K H B W { RET_INSN(mmxsse2, 0x68, CPU_MMX); } |
| P U N P C K H W D { RET_INSN(mmxsse2, 0x69, CPU_MMX); } |
| P U N P C K H D Q { RET_INSN(mmxsse2, 0x6A, CPU_MMX); } |
| P U N P C K L B W { RET_INSN(mmxsse2, 0x60, CPU_MMX); } |
| P U N P C K L W D { RET_INSN(mmxsse2, 0x61, CPU_MMX); } |
| P U N P C K L D Q { RET_INSN(mmxsse2, 0x62, CPU_MMX); } |
| P X O R { RET_INSN(mmxsse2, 0xEF, CPU_MMX); } |
| /* PIII (Katmai) new instructions / SIMD instructions */ |
| A D D P S { RET_INSN(sseps, 0x58, CPU_SSE); } |
| A D D S S { RET_INSN(ssess, 0xF358, CPU_SSE); } |
| A N D N P S { RET_INSN(sseps, 0x55, CPU_SSE); } |
| A N D P S { RET_INSN(sseps, 0x54, CPU_SSE); } |
| C M P E Q P S { RET_INSN(ssecmpps, 0x00, CPU_SSE); } |
| C M P E Q S S { RET_INSN(ssecmpss, 0x00F3, CPU_SSE); } |
| C M P L E P S { RET_INSN(ssecmpps, 0x02, CPU_SSE); } |
| C M P L E S S { RET_INSN(ssecmpss, 0x02F3, CPU_SSE); } |
| C M P L T P S { RET_INSN(ssecmpps, 0x01, CPU_SSE); } |
| C M P L T S S { RET_INSN(ssecmpss, 0x01F3, CPU_SSE); } |
| C M P N E Q P S { RET_INSN(ssecmpps, 0x04, CPU_SSE); } |
| C M P N E Q S S { RET_INSN(ssecmpss, 0x04F3, CPU_SSE); } |
| C M P N L E P S { RET_INSN(ssecmpps, 0x06, CPU_SSE); } |
| C M P N L E S S { RET_INSN(ssecmpss, 0x06F3, CPU_SSE); } |
| C M P N L T P S { RET_INSN(ssecmpps, 0x05, CPU_SSE); } |
| C M P N L T S S { RET_INSN(ssecmpss, 0x05F3, CPU_SSE); } |
| C M P O R D P S { RET_INSN(ssecmpps, 0x07, CPU_SSE); } |
| C M P O R D S S { RET_INSN(ssecmpss, 0x07F3, CPU_SSE); } |
| C M P U N O R D P S { RET_INSN(ssecmpps, 0x03, CPU_SSE); } |
| C M P U N O R D S S { RET_INSN(ssecmpss, 0x03F3, CPU_SSE); } |
| C M P P S { RET_INSN(ssepsimm, 0xC2, CPU_SSE); } |
| C M P S S { RET_INSN(ssessimm, 0xF3C2, CPU_SSE); } |
| C O M I S S { RET_INSN(sseps, 0x2F, CPU_SSE); } |
| C V T P I "2" P S { RET_INSN(sseps, 0x2A, CPU_SSE); } |
| C V T P S "2" P I { RET_INSN(sseps, 0x2D, CPU_SSE); } |
| C V T S I "2" S S { RET_INSN(ssess, 0xF32A, CPU_SSE); } |
| C V T S S "2" S I { RET_INSN(ssess, 0xF32D, CPU_SSE); } |
| C V T T P S "2" P I { RET_INSN(sseps, 0x2C, CPU_SSE); } |
| C V T T S S "2" S I { RET_INSN(ssess, 0xF32C, CPU_SSE); } |
| D I V P S { RET_INSN(sseps, 0x5E, CPU_SSE); } |
| D I V S S { RET_INSN(ssess, 0xF35E, CPU_SSE); } |
| L D M X C S R { RET_INSN(ldstmxcsr, 0x02, CPU_SSE); } |
| M A S K M O V Q { RET_INSN(maskmovq, 0, CPU_P3|CPU_MMX); } |
| M A X P S { RET_INSN(sseps, 0x5F, CPU_SSE); } |
| M A X S S { RET_INSN(ssess, 0xF35F, CPU_SSE); } |
| M I N P S { RET_INSN(sseps, 0x5D, CPU_SSE); } |
| M I N S S { RET_INSN(ssess, 0xF35D, CPU_SSE); } |
| M O V A P S { RET_INSN(movaups, 0x28, CPU_SSE); } |
| M O V H L P S { RET_INSN(movhllhps, 0x12, CPU_SSE); } |
| M O V H P S { RET_INSN(movhlps, 0x16, CPU_SSE); } |
| M O V L H P S { RET_INSN(movhllhps, 0x16, CPU_SSE); } |
| M O V L P S { RET_INSN(movhlps, 0x12, CPU_SSE); } |
| M O V M S K P S { RET_INSN(movmskps, 0, CPU_SSE); } |
| M O V N T P S { RET_INSN(movntps, 0, CPU_SSE); } |
| M O V N T Q { RET_INSN(movntq, 0, CPU_SSE); } |
| M O V S S { RET_INSN(movss, 0, CPU_SSE); } |
| M O V U P S { RET_INSN(movaups, 0x10, CPU_SSE); } |
| M U L P S { RET_INSN(sseps, 0x59, CPU_SSE); } |
| M U L S S { RET_INSN(ssess, 0xF359, CPU_SSE); } |
| O R P S { RET_INSN(sseps, 0x56, CPU_SSE); } |
| P A V G B { RET_INSN(mmxsse2, 0xE0, CPU_P3|CPU_MMX); } |
| P A V G W { RET_INSN(mmxsse2, 0xE3, CPU_P3|CPU_MMX); } |
| P E X T R W { RET_INSN(pextrw, 0, CPU_P3|CPU_MMX); } |
| P I N S R W { RET_INSN(pinsrw, 0, CPU_P3|CPU_MMX); } |
| P M A X S W { RET_INSN(mmxsse2, 0xEE, CPU_P3|CPU_MMX); } |
| P M A X U B { RET_INSN(mmxsse2, 0xDE, CPU_P3|CPU_MMX); } |
| P M I N S W { RET_INSN(mmxsse2, 0xEA, CPU_P3|CPU_MMX); } |
| P M I N U B { RET_INSN(mmxsse2, 0xDA, CPU_P3|CPU_MMX); } |
| P M O V M S K B { RET_INSN(pmovmskb, 0, CPU_SSE); } |
| P M U L H U W { RET_INSN(mmxsse2, 0xE4, CPU_P3|CPU_MMX); } |
| P R E F E T C H N T A { RET_INSN(twobytemem, 0x000F18, CPU_P3); } |
| P R E F E T C H T "0" { RET_INSN(twobytemem, 0x010F18, CPU_P3); } |
| P R E F E T C H T "1" { RET_INSN(twobytemem, 0x020F18, CPU_P3); } |
| P R E F E T C H T "2" { RET_INSN(twobytemem, 0x030F18, CPU_P3); } |
| P S A D B W { RET_INSN(mmxsse2, 0xF6, CPU_P3|CPU_MMX); } |
| P S H U F W { RET_INSN(pshufw, 0, CPU_P3|CPU_MMX); } |
| R C P P S { RET_INSN(sseps, 0x53, CPU_SSE); } |
| R C P S S { RET_INSN(ssess, 0xF353, CPU_SSE); } |
| R S Q R T P S { RET_INSN(sseps, 0x52, CPU_SSE); } |
| R S Q R T S S { RET_INSN(ssess, 0xF352, CPU_SSE); } |
| S F E N C E { RET_INSN(threebyte, 0x0FAEF8, CPU_P3); } |
| S H U F P S { RET_INSN(ssepsimm, 0xC6, CPU_SSE); } |
| S Q R T P S { RET_INSN(sseps, 0x51, CPU_SSE); } |
| S Q R T S S { RET_INSN(ssess, 0xF351, CPU_SSE); } |
| S T M X C S R { RET_INSN(ldstmxcsr, 0x03, CPU_SSE); } |
| S U B P S { RET_INSN(sseps, 0x5C, CPU_SSE); } |
| S U B S S { RET_INSN(ssess, 0xF35C, CPU_SSE); } |
| U C O M I S S { RET_INSN(ssess, 0xF32E, CPU_SSE); } |
| U N P C K H P S { RET_INSN(sseps, 0x15, CPU_SSE); } |
| U N P C K L P S { RET_INSN(sseps, 0x14, CPU_SSE); } |
| X O R P S { RET_INSN(sseps, 0x57, CPU_SSE); } |
| /* SSE2 instructions */ |
| A D D P D { RET_INSN(ssess, 0x6658, CPU_SSE2); } |
| A D D S D { RET_INSN(ssess, 0xF258, CPU_SSE2); } |
| A N D N P D { RET_INSN(ssess, 0x6655, CPU_SSE2); } |
| A N D P D { RET_INSN(ssess, 0x6654, CPU_SSE2); } |
| C M P E Q P D { RET_INSN(ssecmpss, 0x0066, CPU_SSE2); } |
| C M P E Q S D { RET_INSN(ssecmpss, 0x00F2, CPU_SSE2); } |
| C M P L E P D { RET_INSN(ssecmpss, 0x0266, CPU_SSE2); } |
| C M P L E S D { RET_INSN(ssecmpss, 0x02F2, CPU_SSE2); } |
| C M P L T P D { RET_INSN(ssecmpss, 0x0166, CPU_SSE2); } |
| C M P L T S D { RET_INSN(ssecmpss, 0x01F2, CPU_SSE2); } |
| C M P N E Q P D { RET_INSN(ssecmpss, 0x0466, CPU_SSE2); } |
| C M P N E Q S D { RET_INSN(ssecmpss, 0x04F2, CPU_SSE2); } |
| C M P N L E P D { RET_INSN(ssecmpss, 0x0666, CPU_SSE2); } |
| C M P N L E S D { RET_INSN(ssecmpss, 0x06F2, CPU_SSE2); } |
| C M P N L T P D { RET_INSN(ssecmpss, 0x0566, CPU_SSE2); } |
| C M P N L T S D { RET_INSN(ssecmpss, 0x05F2, CPU_SSE2); } |
| C M P O R D P D { RET_INSN(ssecmpss, 0x0766, CPU_SSE2); } |
| C M P O R D S D { RET_INSN(ssecmpss, 0x07F2, CPU_SSE2); } |
| C M P U N O R D P D { RET_INSN(ssecmpss, 0x0366, CPU_SSE2); } |
| C M P U N O R D S D { RET_INSN(ssecmpss, 0x03F2, CPU_SSE2); } |
| C M P P D { RET_INSN(ssessimm, 0x66C2, CPU_SSE2); } |
| /* C M P S D is in string instructions above */ |
| C O M I S D { RET_INSN(ssess, 0x662F, CPU_SSE2); } |
| C V T P I "2" P D { RET_INSN(ssess, 0x662A, CPU_SSE2); } |
| C V T S I "2" S D { RET_INSN(ssess, 0xF22A, CPU_SSE2); } |
| D I V P D { RET_INSN(ssess, 0x665E, CPU_SSE2); } |
| D I V S D { RET_INSN(ssess, 0xF25E, CPU_SSE2); } |
| M A X P D { RET_INSN(ssess, 0x665F, CPU_SSE2); } |
| M A X S D { RET_INSN(ssess, 0xF25F, CPU_SSE2); } |
| M I N P D { RET_INSN(ssess, 0x665D, CPU_SSE2); } |
| M I N S D { RET_INSN(ssess, 0xF25D, CPU_SSE2); } |
| M O V A P D { RET_INSN(movaupd, 0x28, CPU_SSE2); } |
| M O V H P D { RET_INSN(movhlpd, 0x16, CPU_SSE2); } |
| M O V L P D { RET_INSN(movhlpd, 0x12, CPU_SSE2); } |
| M O V M S K P D { RET_INSN(movmskpd, 0, CPU_SSE2); } |
| M O V N T P D { RET_INSN(movntpddq, 0x2B, CPU_SSE2); } |
| M O V N T D Q { RET_INSN(movntpddq, 0xE7, CPU_SSE2); } |
| /* M O V S D is in string instructions above */ |
| M O V U P D { RET_INSN(movaupd, 0x10, CPU_SSE2); } |
| M U L P D { RET_INSN(ssess, 0x6659, CPU_SSE2); } |
| M U L S D { RET_INSN(ssess, 0xF259, CPU_SSE2); } |
| O R P D { RET_INSN(ssess, 0x6656, CPU_SSE2); } |
| S H U F P D { RET_INSN(ssessimm, 0x66C6, CPU_SSE2); } |
| S Q R T P D { RET_INSN(ssess, 0x6651, CPU_SSE2); } |
| S Q R T S D { RET_INSN(ssess, 0xF251, CPU_SSE2); } |
| S U B P D { RET_INSN(ssess, 0x665C, CPU_SSE2); } |
| S U B S D { RET_INSN(ssess, 0xF25C, CPU_SSE2); } |
| U C O M I S D { RET_INSN(ssess, 0xF22E, CPU_SSE2); } |
| U N P C K H P D { RET_INSN(ssess, 0x6615, CPU_SSE2); } |
| U N P C K L P D { RET_INSN(ssess, 0x6614, CPU_SSE2); } |
| X O R P D { RET_INSN(ssess, 0x6657, CPU_SSE2); } |
| C V T D Q "2" P D { RET_INSN(ssess, 0xF3E6, CPU_SSE2); } |
| C V T P D "2" D Q { RET_INSN(ssess, 0xF2E6, CPU_SSE2); } |
| C V T D Q "2" P S { RET_INSN(sseps, 0x5B, CPU_SSE2); } |
| C V T P D "2" P I { RET_INSN(ssess, 0x662D, CPU_SSE2); } |
| C V T P D "2" P S { RET_INSN(ssess, 0x665A, CPU_SSE2); } |
| C V T P S "2" P D { RET_INSN(sseps, 0x5A, CPU_SSE2); } |
| C V T P S "2" D Q { RET_INSN(ssess, 0x665B, CPU_SSE2); } |
| C V T S D "2" S I { RET_INSN(ssess, 0xF22D, CPU_SSE2); } |
| C V T S D "2" S S { RET_INSN(ssess, 0xF25A, CPU_SSE2); } |
| C V T S S "2" S D { RET_INSN(ssess, 0xF35A, CPU_SSE2); } |
| C V T T P D "2" P I { RET_INSN(ssess, 0x662C, CPU_SSE2); } |
| C V T T S D "2" S I { RET_INSN(ssess, 0xF22C, CPU_SSE2); } |
| C V T T P D "2" D Q { RET_INSN(ssess, 0x66E6, CPU_SSE2); } |
| C V T T P S "2" D Q { RET_INSN(ssess, 0xF35B, CPU_SSE2); } |
| M A S K M O V D Q U { RET_INSN(maskmovdqu, 0, CPU_SSE2); } |
| M O V D Q A { RET_INSN(movdqau, 0x66, CPU_SSE2); } |
| M O V D Q U { RET_INSN(movdqau, 0xF3, CPU_SSE2); } |
| M O V D Q "2" Q { RET_INSN(movdq2q, 0, CPU_SSE2); } |
| M O V Q "2" D Q { RET_INSN(movq2dq, 0, CPU_SSE2); } |
| P M U L U D Q { RET_INSN(mmxsse2, 0xF4, CPU_SSE2); } |
| P S H U F D { RET_INSN(ssessimm, 0x6670, CPU_SSE2); } |
| P S H U F H W { RET_INSN(ssessimm, 0xF370, CPU_SSE2); } |
| P S H U F L W { RET_INSN(ssessimm, 0xF270, CPU_SSE2); } |
| P S L L D Q { RET_INSN(pslrldq, 0x07, CPU_SSE2); } |
| P S R L D Q { RET_INSN(pslrldq, 0x03, CPU_SSE2); } |
| P U N P C K H Q D Q { RET_INSN(ssess, 0x666D, CPU_SSE2); } |
| P U N P C K L Q D Q { RET_INSN(ssess, 0x666C, CPU_SSE2); } |
| /* AMD 3DNow! instructions */ |
| P R E F E T C H { RET_INSN(twobytemem, 0x000F0D, CPU_3DNow); } |
| P R E F E T C H W { RET_INSN(twobytemem, 0x010F0D, CPU_3DNow); } |
| F E M M S { RET_INSN(twobyte, 0x0F0E, CPU_3DNow); } |
| P A V G U S B { RET_INSN(now3d, 0xBF, CPU_3DNow); } |
| P F "2" I D { RET_INSN(now3d, 0x1D, CPU_3DNow); } |
| P F "2" I W { RET_INSN(now3d, 0x1C, CPU_Athlon|CPU_3DNow); } |
| P F A C C { RET_INSN(now3d, 0xAE, CPU_3DNow); } |
| P F A D D { RET_INSN(now3d, 0x9E, CPU_3DNow); } |
| P F C M P E Q { RET_INSN(now3d, 0xB0, CPU_3DNow); } |
| P F C M P G E { RET_INSN(now3d, 0x90, CPU_3DNow); } |
| P F C M P G T { RET_INSN(now3d, 0xA0, CPU_3DNow); } |
| P F M A X { RET_INSN(now3d, 0xA4, CPU_3DNow); } |
| P F M I N { RET_INSN(now3d, 0x94, CPU_3DNow); } |
| P F M U L { RET_INSN(now3d, 0xB4, CPU_3DNow); } |
| P F N A C C { RET_INSN(now3d, 0x8A, CPU_Athlon|CPU_3DNow); } |
| P F P N A C C { RET_INSN(now3d, 0x8E, CPU_Athlon|CPU_3DNow); } |
| P F R C P { RET_INSN(now3d, 0x96, CPU_3DNow); } |
| P F R C P I T "1" { RET_INSN(now3d, 0xA6, CPU_3DNow); } |
| P F R C P I T "2" { RET_INSN(now3d, 0xB6, CPU_3DNow); } |
| P F R S Q I T "1" { RET_INSN(now3d, 0xA7, CPU_3DNow); } |
| P F R S Q R T { RET_INSN(now3d, 0x97, CPU_3DNow); } |
| P F S U B { RET_INSN(now3d, 0x9A, CPU_3DNow); } |
| P F S U B R { RET_INSN(now3d, 0xAA, CPU_3DNow); } |
| P I "2" F D { RET_INSN(now3d, 0x0D, CPU_3DNow); } |
| P I "2" F W { RET_INSN(now3d, 0x0C, CPU_Athlon|CPU_3DNow); } |
| P M U L H R W A { RET_INSN(now3d, 0xB7, CPU_3DNow); } |
| P S W A P D { RET_INSN(now3d, 0xBB, CPU_Athlon|CPU_3DNow); } |
| /* AMD extensions */ |
| S Y S C A L L { RET_INSN(twobyte, 0x0F05, CPU_686|CPU_AMD); } |
| S Y S R E T { RET_INSN(twobyte, 0x0F07, CPU_686|CPU_AMD|CPU_Priv); } |
| /* AMD x86-64 extensions */ |
| S W A P G S { |
| if (arch_x86->mode_bits != 64) { |
| yasm__warning(YASM_WARN_GENERAL, line, |
| N_("`%s' is an instruction in 64-bit mode"), |
| oid); |
| return YASM_ARCH_CHECK_ID_NONE; |
| } |
| RET_INSN(threebyte, 0x0F01F8, CPU_Hammer|CPU_64); |
| } |
| /* Cyrix MMX instructions */ |
| P A D D S I W { RET_INSN(cyrixmmx, 0x51, CPU_Cyrix|CPU_MMX); } |
| P A V E B { RET_INSN(cyrixmmx, 0x50, CPU_Cyrix|CPU_MMX); } |
| P D I S T I B { RET_INSN(cyrixmmx, 0x54, CPU_Cyrix|CPU_MMX); } |
| P M A C H R I W { RET_INSN(pmachriw, 0, CPU_Cyrix|CPU_MMX); } |
| P M A G W { RET_INSN(cyrixmmx, 0x52, CPU_Cyrix|CPU_MMX); } |
| P M U L H R I W { RET_INSN(cyrixmmx, 0x5D, CPU_Cyrix|CPU_MMX); } |
| P M U L H R W C { RET_INSN(cyrixmmx, 0x59, CPU_Cyrix|CPU_MMX); } |
| P M V G E Z B { RET_INSN(cyrixmmx, 0x5C, CPU_Cyrix|CPU_MMX); } |
| P M V L Z B { RET_INSN(cyrixmmx, 0x5B, CPU_Cyrix|CPU_MMX); } |
| P M V N Z B { RET_INSN(cyrixmmx, 0x5A, CPU_Cyrix|CPU_MMX); } |
| P M V Z B { RET_INSN(cyrixmmx, 0x58, CPU_Cyrix|CPU_MMX); } |
| P S U B S I W { RET_INSN(cyrixmmx, 0x55, CPU_Cyrix|CPU_MMX); } |
| /* Cyrix extensions */ |
| R D S H R { RET_INSN(twobyte, 0x0F36, CPU_686|CPU_Cyrix|CPU_SMM); } |
| R S D C { RET_INSN(rsdc, 0, CPU_486|CPU_Cyrix|CPU_SMM); } |
| R S L D T { RET_INSN(cyrixsmm, 0x7B, CPU_486|CPU_Cyrix|CPU_SMM); } |
| R S T S { RET_INSN(cyrixsmm, 0x7D, CPU_486|CPU_Cyrix|CPU_SMM); } |
| S V D C { RET_INSN(svdc, 0, CPU_486|CPU_Cyrix|CPU_SMM); } |
| S V L D T { RET_INSN(cyrixsmm, 0x7A, CPU_486|CPU_Cyrix|CPU_SMM); } |
| S V T S { RET_INSN(cyrixsmm, 0x7C, CPU_486|CPU_Cyrix|CPU_SMM); } |
| S M I N T { RET_INSN(twobyte, 0x0F38, CPU_686|CPU_Cyrix); } |
| S M I N T O L D { RET_INSN(twobyte, 0x0F7E, CPU_486|CPU_Cyrix|CPU_Obs); } |
| W R S H R { RET_INSN(twobyte, 0x0F37, CPU_686|CPU_Cyrix|CPU_SMM); } |
| /* Obsolete/undocumented instructions */ |
| F S E T P M { RET_INSN(twobyte, 0xDBE4, CPU_286|CPU_FPU|CPU_Obs); } |
| I B T S { RET_INSN(ibts, 0, CPU_386|CPU_Undoc|CPU_Obs); } |
| L O A D A L L { RET_INSN(twobyte, 0x0F07, CPU_386|CPU_Undoc); } |
| L O A D A L L "286" { RET_INSN(twobyte, 0x0F05, CPU_286|CPU_Undoc); } |
| S A L C { |
| if (arch_x86->mode_bits == 64) { |
| yasm__error(line, N_("`%s' invalid in 64-bit mode"), oid); |
| RET_INSN(not64, 0, CPU_Not64); |
| } |
| RET_INSN(onebyte, 0x00D6, CPU_Undoc); |
| } |
| S M I { RET_INSN(onebyte, 0x00F1, CPU_386|CPU_Undoc); } |
| U M O V { RET_INSN(umov, 0, CPU_386|CPU_Undoc); } |
| X B T S { RET_INSN(xbts, 0, CPU_386|CPU_Undoc|CPU_Obs); } |
| |
| |
| /* catchalls */ |
| [\001-\377]+ { |
| return YASM_ARCH_CHECK_ID_NONE; |
| } |
| [\000] { |
| return YASM_ARCH_CHECK_ID_NONE; |
| } |
| */ |
| } |