X-Git-Url: http://drtracing.org/?a=blobdiff_plain;ds=sidebyside;f=opcodes%2Fi386-dis.c;h=1da05e0e27d28e03d242cd5137b2a0b6c9d2057e;hb=47dd174cba6c3e3cba9f18e8688d14176b66cc86;hp=ebbbcec0d28359463481e6a35a20fe375e881b83;hpb=c25c34f8fb8d9327c836fe841370338000306e58;p=deliverable%2Fbinutils-gdb.git diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c index ebbbcec0d2..1da05e0e27 100644 --- a/opcodes/i386-dis.c +++ b/opcodes/i386-dis.c @@ -33,10 +33,11 @@ and the small letter tells about the operand size. Refer to the Intel manual for details. */ -#include "dis-asm.h" #include "sysdep.h" +#include "dis-asm.h" #include "opintl.h" #include "opcode/i386.h" +#include "libiberty.h" #include @@ -52,6 +53,7 @@ static void oappend (const char *); static void append_seg (void); static void OP_indirE (int, int); static void print_operand_value (char *, int, bfd_vma); +static void OP_E_extended (int, int, int); static void print_displacement (char *, bfd_vma); static void OP_E (int, int); static void OP_G (int, int); @@ -94,14 +96,16 @@ static void NOP_Fixup1 (int, int); static void NOP_Fixup2 (int, int); static void OP_3DNowSuffix (int, int); static void OP_SIMD_Suffix (int, int); -static void SIMD_Fixup (int, int); -static void SVME_Fixup (int, int); -static void INVLPG_Fixup (int, int); static void BadOp (void); static void REP_Fixup (int, int); static void CMPXCHG8B_Fixup (int, int); static void XMM_Fixup (int, int); static void CRC32_Fixup (int, int); +static void print_drex_arg (unsigned int, int, int); +static void OP_DREX4 (int, int); +static void OP_DREX3 (int, int); +static void OP_DREX_ICMP (int, int); +static void OP_DREX_FCMP (int, int); struct dis_private { /* Points to first byte not fetched. */ @@ -143,6 +147,20 @@ static int rex_used; rex_used |= REX_OPCODE; \ } +/* Special 'registers' for DREX handling */ +#define DREX_REG_UNKNOWN 1000 /* not initialized */ +#define DREX_REG_MEMORY 1001 /* use MODRM/SIB/OFFSET memory */ + +/* The DREX byte has the following fields: + Bits 7-4 -- DREX.Dest, xmm destination register + Bit 3 -- DREX.OC0, operand config bit defines operand order + Bit 2 -- DREX.R, equivalent to REX_R bit, to extend ModRM register + Bit 1 -- DREX.X, equivalent to REX_X bit, to extend SIB index field + Bit 0 -- DREX.W, equivalent to REX_B bit, to extend ModRM r/m field, + SIB base field, or opcode reg field. */ +#define DREX_XMM(drex) ((drex >> 4) & 0xf) +#define DREX_OC0(drex) ((drex >> 3) & 0x1) + /* Flags for prefixes which we somehow handled when printing the current instruction. */ static int used_prefixes; @@ -363,6 +381,11 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr) #define dqb_mode 18 /* registers like dq_mode, memory like b_mode. */ #define dqd_mode 19 /* registers like dq_mode, memory like d_mode. */ +/* Flags that are OR'ed into the bytemode field to pass extra information. */ +#define DREX_OC1 0x4000 /* OC1 bit set */ +#define DREX_NO_OC0 0x2000 /* OC0 bit not used */ +#define DREX_MASK 0x6000 /* mask to delete */ + #define es_reg 100 #define cs_reg 101 #define ss_reg 102 @@ -410,186 +433,244 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr) #define indir_dx_reg 150 #define FLOATCODE 1 -#define USE_GROUPS 2 -#define USE_PREFIX_USER_TABLE 3 -#define X86_64_SPECIAL 4 -#define IS_3BYTE_OPCODE 5 -#define USE_OPC_EXT_TABLE 6 -#define USE_OPC_EXT_RM_TABLE 7 - -#define FLOAT NULL, { { NULL, FLOATCODE } } - -#define GRP1a NULL, { { NULL, USE_GROUPS }, { NULL, 0 } } -#define GRP1b NULL, { { NULL, USE_GROUPS }, { NULL, 1 } } -#define GRP1S NULL, { { NULL, USE_GROUPS }, { NULL, 2 } } -#define GRP1Ss NULL, { { NULL, USE_GROUPS }, { NULL, 3 } } -#define GRP2b NULL, { { NULL, USE_GROUPS }, { NULL, 4 } } -#define GRP2S NULL, { { NULL, USE_GROUPS }, { NULL, 5 } } -#define GRP2b_one NULL, { { NULL, USE_GROUPS }, { NULL, 6 } } -#define GRP2S_one NULL, { { NULL, USE_GROUPS }, { NULL, 7 } } -#define GRP2b_cl NULL, { { NULL, USE_GROUPS }, { NULL, 8 } } -#define GRP2S_cl NULL, { { NULL, USE_GROUPS }, { NULL, 9 } } -#define GRP3b NULL, { { NULL, USE_GROUPS }, { NULL, 10 } } -#define GRP3S NULL, { { NULL, USE_GROUPS }, { NULL, 11 } } -#define GRP4 NULL, { { NULL, USE_GROUPS }, { NULL, 12 } } -#define GRP5 NULL, { { NULL, USE_GROUPS }, { NULL, 13 } } -#define GRP6 NULL, { { NULL, USE_GROUPS }, { NULL, 14 } } -#define GRP7 NULL, { { NULL, USE_GROUPS }, { NULL, 15 } } -#define GRP8 NULL, { { NULL, USE_GROUPS }, { NULL, 16 } } -#define GRP9 NULL, { { NULL, USE_GROUPS }, { NULL, 17 } } -#define GRP11_C6 NULL, { { NULL, USE_GROUPS }, { NULL, 18 } } -#define GRP11_C7 NULL, { { NULL, USE_GROUPS }, { NULL, 19 } } -#define GRP12 NULL, { { NULL, USE_GROUPS }, { NULL, 20 } } -#define GRP13 NULL, { { NULL, USE_GROUPS }, { NULL, 21 } } -#define GRP14 NULL, { { NULL, USE_GROUPS }, { NULL, 22 } } -#define GRP15 NULL, { { NULL, USE_GROUPS }, { NULL, 23 } } -#define GRP16 NULL, { { NULL, USE_GROUPS }, { NULL, 24 } } -#define GRPAMD NULL, { { NULL, USE_GROUPS }, { NULL, 25 } } -#define GRPPADLCK1 NULL, { { NULL, USE_GROUPS }, { NULL, 26 } } -#define GRPPADLCK2 NULL, { { NULL, USE_GROUPS }, { NULL, 27 } } - -#define PREGRP0 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 0 } } -#define PREGRP1 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 1 } } -#define PREGRP2 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 2 } } -#define PREGRP3 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 3 } } -#define PREGRP4 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 4 } } -#define PREGRP5 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 5 } } -#define PREGRP6 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 6 } } -#define PREGRP7 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 7 } } -#define PREGRP8 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 8 } } -#define PREGRP9 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 9 } } -#define PREGRP10 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 10 } } -#define PREGRP11 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 11 } } -#define PREGRP12 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 12 } } -#define PREGRP13 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 13 } } -#define PREGRP14 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 14 } } -#define PREGRP15 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 15 } } -#define PREGRP16 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 16 } } -#define PREGRP17 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 17 } } -#define PREGRP18 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 18 } } -#define PREGRP19 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 19 } } -#define PREGRP20 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 20 } } -#define PREGRP21 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 21 } } -#define PREGRP22 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 22 } } -#define PREGRP23 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 23 } } -#define PREGRP24 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 24 } } -#define PREGRP25 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 25 } } -#define PREGRP26 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 26 } } -#define PREGRP27 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 27 } } -#define PREGRP28 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 28 } } -#define PREGRP29 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 29 } } -#define PREGRP30 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 30 } } -#define PREGRP31 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 31 } } -#define PREGRP32 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 32 } } -#define PREGRP33 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 33 } } -#define PREGRP34 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 34 } } -#define PREGRP35 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 35 } } -#define PREGRP36 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 36 } } -#define PREGRP37 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 37 } } -#define PREGRP38 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 38 } } -#define PREGRP39 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 39 } } -#define PREGRP40 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 40 } } -#define PREGRP41 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 41 } } -#define PREGRP42 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 42 } } -#define PREGRP43 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 43 } } -#define PREGRP44 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 44 } } -#define PREGRP45 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 45 } } -#define PREGRP46 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 46 } } -#define PREGRP47 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 47 } } -#define PREGRP48 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 48 } } -#define PREGRP49 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 49 } } -#define PREGRP50 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 50 } } -#define PREGRP51 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 51 } } -#define PREGRP52 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 52 } } -#define PREGRP53 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 53 } } -#define PREGRP54 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 54 } } -#define PREGRP55 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 55 } } -#define PREGRP56 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 56 } } -#define PREGRP57 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 57 } } -#define PREGRP58 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 58 } } -#define PREGRP59 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 59 } } -#define PREGRP60 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 60 } } -#define PREGRP61 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 61 } } -#define PREGRP62 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 62 } } -#define PREGRP63 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 63 } } -#define PREGRP64 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 64 } } -#define PREGRP65 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 65 } } -#define PREGRP66 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 66 } } -#define PREGRP67 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 67 } } -#define PREGRP68 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 68 } } -#define PREGRP69 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 69 } } -#define PREGRP70 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 70 } } -#define PREGRP71 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 71 } } -#define PREGRP72 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 72 } } -#define PREGRP73 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 73 } } -#define PREGRP74 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 74 } } -#define PREGRP75 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 75 } } -#define PREGRP76 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 76 } } -#define PREGRP77 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 77 } } -#define PREGRP78 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 78 } } -#define PREGRP79 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 79 } } -#define PREGRP80 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 80 } } -#define PREGRP81 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 81 } } -#define PREGRP82 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 82 } } -#define PREGRP83 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 83 } } -#define PREGRP84 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 84 } } -#define PREGRP85 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 85 } } -#define PREGRP86 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 86 } } -#define PREGRP87 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 87 } } -#define PREGRP88 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 88 } } -#define PREGRP89 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 89 } } -#define PREGRP90 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 90 } } -#define PREGRP91 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 91 } } -#define PREGRP92 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 92 } } -#define PREGRP93 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 93 } } -#define PREGRP94 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 94 } } -#define PREGRP95 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 95 } } -#define PREGRP96 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 96 } } -#define PREGRP97 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 97 } } -#define PREGRP98 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 98 } } -#define PREGRP99 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 99 } } -#define PREGRP100 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 100 } } - - -#define X86_64_0 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 0 } } -#define X86_64_1 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 1 } } -#define X86_64_2 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 2 } } -#define X86_64_3 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 3 } } - -#define THREE_BYTE_0 NULL, { { NULL, IS_3BYTE_OPCODE }, { NULL, 0 } } -#define THREE_BYTE_1 NULL, { { NULL, IS_3BYTE_OPCODE }, { NULL, 1 } } - -#define OPC_EXT_0 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 0 } } -#define OPC_EXT_1 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 1 } } -#define OPC_EXT_2 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 2 } } -#define OPC_EXT_3 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 3 } } -#define OPC_EXT_4 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 4 } } -#define OPC_EXT_5 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 5 } } -#define OPC_EXT_6 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 6 } } -#define OPC_EXT_7 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 7 } } -#define OPC_EXT_8 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 8 } } -#define OPC_EXT_9 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 9 } } -#define OPC_EXT_10 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 10 } } -#define OPC_EXT_11 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 11 } } -#define OPC_EXT_12 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 12 } } -#define OPC_EXT_13 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 13 } } -#define OPC_EXT_14 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 14 } } -#define OPC_EXT_15 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 15 } } -#define OPC_EXT_16 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 16 } } -#define OPC_EXT_17 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 17 } } -#define OPC_EXT_18 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 18 } } -#define OPC_EXT_19 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 19 } } -#define OPC_EXT_20 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 20 } } -#define OPC_EXT_21 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 21 } } -#define OPC_EXT_22 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 22 } } -#define OPC_EXT_23 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 23 } } -#define OPC_EXT_24 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 24 } } - -#define OPC_EXT_RM_0 NULL, { { NULL, USE_OPC_EXT_RM_TABLE }, { NULL, 0 } } -#define OPC_EXT_RM_1 NULL, { { NULL, USE_OPC_EXT_RM_TABLE }, { NULL, 1 } } -#define OPC_EXT_RM_2 NULL, { { NULL, USE_OPC_EXT_RM_TABLE }, { NULL, 2 } } -#define OPC_EXT_RM_3 NULL, { { NULL, USE_OPC_EXT_RM_TABLE }, { NULL, 3 } } -#define OPC_EXT_RM_4 NULL, { { NULL, USE_OPC_EXT_RM_TABLE }, { NULL, 4 } } +#define USE_REG_TABLE 2 +#define USE_MOD_TABLE 3 +#define USE_RM_TABLE 4 +#define USE_PREFIX_TABLE 5 +#define USE_X86_64_TABLE 6 +#define USE_3BYTE_TABLE 7 + +#define FLOAT NULL, { { NULL, FLOATCODE } } + +#define DIS386(T, I) NULL, { { NULL, (T)}, { NULL, (I) } } +#define REG_TABLE(I) DIS386 (USE_REG_TABLE, (I)) +#define MOD_TABLE(I) DIS386 (USE_MOD_TABLE, (I)) +#define RM_TABLE(I) DIS386 (USE_RM_TABLE, (I)) +#define PREFIX_TABLE(I) DIS386 (USE_PREFIX_TABLE, (I)) +#define X86_64_TABLE(I) DIS386 (USE_X86_64_TABLE, (I)) +#define THREE_BYTE_TABLE(I) DIS386 (USE_3BYTE_TABLE, (I)) + +#define REG_80 0 +#define REG_81 (REG_80 + 1) +#define REG_82 (REG_81 + 1) +#define REG_8F (REG_82 + 1) +#define REG_C0 (REG_8F + 1) +#define REG_C1 (REG_C0 + 1) +#define REG_C6 (REG_C1 + 1) +#define REG_C7 (REG_C6 + 1) +#define REG_D0 (REG_C7 + 1) +#define REG_D1 (REG_D0 + 1) +#define REG_D2 (REG_D1 + 1) +#define REG_D3 (REG_D2 + 1) +#define REG_F6 (REG_D3 + 1) +#define REG_F7 (REG_F6 + 1) +#define REG_FE (REG_F7 + 1) +#define REG_FF (REG_FE + 1) +#define REG_0F00 (REG_FF + 1) +#define REG_0F01 (REG_0F00 + 1) +#define REG_0F0E (REG_0F01 + 1) +#define REG_0F18 (REG_0F0E + 1) +#define REG_0F71 (REG_0F18 + 1) +#define REG_0F72 (REG_0F71 + 1) +#define REG_0F73 (REG_0F72 + 1) +#define REG_0FA6 (REG_0F73 + 1) +#define REG_0FA7 (REG_0FA6 + 1) +#define REG_0FAE (REG_0FA7 + 1) +#define REG_0FBA (REG_0FAE + 1) +#define REG_0FC7 (REG_0FBA + 1) + +#define MOD_8D 0 +#define MOD_0F13 (MOD_8D + 1) +#define MOD_0F17 (MOD_0F13 + 1) +#define MOD_0F20 (MOD_0F17 + 1) +#define MOD_0F21 (MOD_0F20 + 1) +#define MOD_0F22 (MOD_0F21 + 1) +#define MOD_0F23 (MOD_0F22 + 1) +#define MOD_0F24 (MOD_0F23 + 1) +#define MOD_0F26 (MOD_0F24 + 1) +#define MOD_0FB2 (MOD_0F26 + 1) +#define MOD_0FB4 (MOD_0FB2 + 1) +#define MOD_0FB5 (MOD_0FB4 + 1) +#define MOD_0F01_REG_0 (MOD_0FB5 + 1) +#define MOD_0F01_REG_1 (MOD_0F01_REG_0 + 1) +#define MOD_0F01_REG_2 (MOD_0F01_REG_1 + 1) +#define MOD_0F01_REG_3 (MOD_0F01_REG_2 + 1) +#define MOD_0F01_REG_7 (MOD_0F01_REG_3 + 1) +#define MOD_0F18_REG_0 (MOD_0F01_REG_7 + 1) +#define MOD_0F18_REG_1 (MOD_0F18_REG_0 + 1) +#define MOD_0F18_REG_2 (MOD_0F18_REG_1 + 1) +#define MOD_0F18_REG_3 (MOD_0F18_REG_2 + 1) +#define MOD_0F71_REG_2 (MOD_0F18_REG_3 + 1) +#define MOD_0F71_REG_4 (MOD_0F71_REG_2 + 1) +#define MOD_0F71_REG_6 (MOD_0F71_REG_4 + 1) +#define MOD_0F72_REG_2 (MOD_0F71_REG_6 + 1) +#define MOD_0F72_REG_4 (MOD_0F72_REG_2 + 1) +#define MOD_0F72_REG_6 (MOD_0F72_REG_4 + 1) +#define MOD_0F73_REG_2 (MOD_0F72_REG_6 + 1) +#define MOD_0F73_REG_3 (MOD_0F73_REG_2 + 1) +#define MOD_0F73_REG_6 (MOD_0F73_REG_3 + 1) +#define MOD_0F73_REG_7 (MOD_0F73_REG_6 + 1) +#define MOD_0FAE_REG_0 (MOD_0F73_REG_7 + 1) +#define MOD_0FAE_REG_1 (MOD_0FAE_REG_0 + 1) +#define MOD_0FAE_REG_2 (MOD_0FAE_REG_1 + 1) +#define MOD_0FAE_REG_3 (MOD_0FAE_REG_2 + 1) +#define MOD_0FAE_REG_5 (MOD_0FAE_REG_3 + 1) +#define MOD_0FAE_REG_6 (MOD_0FAE_REG_5 + 1) +#define MOD_0FAE_REG_7 (MOD_0FAE_REG_6 + 1) +#define MOD_0FC7_REG_6 (MOD_0FAE_REG_7 + 1) +#define MOD_0FC7_REG_7 (MOD_0FC7_REG_6 + 1) +#define MOD_0F12_PREFIX_0 (MOD_0FC7_REG_7 + 1) +#define MOD_0F16_PREFIX_0 (MOD_0F12_PREFIX_0 + 1) +#define MOD_0FF0_PREFIX_3 (MOD_0F16_PREFIX_0 + 1) +#define MOD_62_32BIT (MOD_0FF0_PREFIX_3 + 1) +#define MOD_C4_32BIT (MOD_62_32BIT + 1) +#define MOD_C5_32BIT (MOD_C4_32BIT + 1) + +#define RM_0F01_REG_0 0 +#define RM_0F01_REG_1 (RM_0F01_REG_0 + 1) +#define RM_0F01_REG_3 (RM_0F01_REG_1 + 1) +#define RM_0F01_REG_7 (RM_0F01_REG_3 + 1) +#define RM_0FAE_REG_5 (RM_0F01_REG_7 + 1) +#define RM_0FAE_REG_6 (RM_0FAE_REG_5 + 1) +#define RM_0FAE_REG_7 (RM_0FAE_REG_6 + 1) + +#define PREFIX_90 0 +#define PREFIX_0F10 (PREFIX_90 + 1) +#define PREFIX_0F11 (PREFIX_0F10 + 1) +#define PREFIX_0F12 (PREFIX_0F11 + 1) +#define PREFIX_0F16 (PREFIX_0F12 + 1) +#define PREFIX_0F2A (PREFIX_0F16 + 1) +#define PREFIX_0F2B (PREFIX_0F2A + 1) +#define PREFIX_0F2C (PREFIX_0F2B + 1) +#define PREFIX_0F2D (PREFIX_0F2C + 1) +#define PREFIX_0F2E (PREFIX_0F2D + 1) +#define PREFIX_0F2F (PREFIX_0F2E + 1) +#define PREFIX_0F51 (PREFIX_0F2F + 1) +#define PREFIX_0F52 (PREFIX_0F51 + 1) +#define PREFIX_0F53 (PREFIX_0F52 + 1) +#define PREFIX_0F58 (PREFIX_0F53 + 1) +#define PREFIX_0F59 (PREFIX_0F58 + 1) +#define PREFIX_0F5A (PREFIX_0F59 + 1) +#define PREFIX_0F5B (PREFIX_0F5A + 1) +#define PREFIX_0F5C (PREFIX_0F5B + 1) +#define PREFIX_0F5D (PREFIX_0F5C + 1) +#define PREFIX_0F5E (PREFIX_0F5D + 1) +#define PREFIX_0F5F (PREFIX_0F5E + 1) +#define PREFIX_0F60 (PREFIX_0F5F + 1) +#define PREFIX_0F61 (PREFIX_0F60 + 1) +#define PREFIX_0F62 (PREFIX_0F61 + 1) +#define PREFIX_0F6C (PREFIX_0F62 + 1) +#define PREFIX_0F6D (PREFIX_0F6C + 1) +#define PREFIX_0F6F (PREFIX_0F6D + 1) +#define PREFIX_0F70 (PREFIX_0F6F + 1) +#define PREFIX_0F78 (PREFIX_0F70 + 1) +#define PREFIX_0F79 (PREFIX_0F78 + 1) +#define PREFIX_0F7C (PREFIX_0F79 + 1) +#define PREFIX_0F7D (PREFIX_0F7C + 1) +#define PREFIX_0F7E (PREFIX_0F7D + 1) +#define PREFIX_0F7F (PREFIX_0F7E + 1) +#define PREFIX_0FB8 (PREFIX_0F7F + 1) +#define PREFIX_0FBD (PREFIX_0FB8 + 1) +#define PREFIX_0FC2 (PREFIX_0FBD + 1) +#define PREFIX_0FD0 (PREFIX_0FC2 + 1) +#define PREFIX_0FD6 (PREFIX_0FD0 + 1) +#define PREFIX_0FE6 (PREFIX_0FD6 + 1) +#define PREFIX_0FE7 (PREFIX_0FE6 + 1) +#define PREFIX_0FF0 (PREFIX_0FE7 + 1) +#define PREFIX_0FF7 (PREFIX_0FF0 + 1) +#define PREFIX_0F3810 (PREFIX_0FF7 + 1) +#define PREFIX_0F3814 (PREFIX_0F3810 + 1) +#define PREFIX_0F3815 (PREFIX_0F3814 + 1) +#define PREFIX_0F3817 (PREFIX_0F3815 + 1) +#define PREFIX_0F3820 (PREFIX_0F3817 + 1) +#define PREFIX_0F3821 (PREFIX_0F3820 + 1) +#define PREFIX_0F3822 (PREFIX_0F3821 + 1) +#define PREFIX_0F3823 (PREFIX_0F3822 + 1) +#define PREFIX_0F3824 (PREFIX_0F3823 + 1) +#define PREFIX_0F3825 (PREFIX_0F3824 + 1) +#define PREFIX_0F3828 (PREFIX_0F3825 + 1) +#define PREFIX_0F3829 (PREFIX_0F3828 + 1) +#define PREFIX_0F382A (PREFIX_0F3829 + 1) +#define PREFIX_0F382B (PREFIX_0F382A + 1) +#define PREFIX_0F3830 (PREFIX_0F382B + 1) +#define PREFIX_0F3831 (PREFIX_0F3830 + 1) +#define PREFIX_0F3832 (PREFIX_0F3831 + 1) +#define PREFIX_0F3833 (PREFIX_0F3832 + 1) +#define PREFIX_0F3834 (PREFIX_0F3833 + 1) +#define PREFIX_0F3835 (PREFIX_0F3834 + 1) +#define PREFIX_0F3837 (PREFIX_0F3835 + 1) +#define PREFIX_0F3838 (PREFIX_0F3837 + 1) +#define PREFIX_0F3839 (PREFIX_0F3838 + 1) +#define PREFIX_0F383A (PREFIX_0F3839 + 1) +#define PREFIX_0F383B (PREFIX_0F383A + 1) +#define PREFIX_0F383C (PREFIX_0F383B + 1) +#define PREFIX_0F383D (PREFIX_0F383C + 1) +#define PREFIX_0F383E (PREFIX_0F383D + 1) +#define PREFIX_0F383F (PREFIX_0F383E + 1) +#define PREFIX_0F3840 (PREFIX_0F383F + 1) +#define PREFIX_0F3841 (PREFIX_0F3840 + 1) +#define PREFIX_0F38F0 (PREFIX_0F3841 + 1) +#define PREFIX_0F38F1 (PREFIX_0F38F0 + 1) +#define PREFIX_0F3A08 (PREFIX_0F38F1 + 1) +#define PREFIX_0F3A09 (PREFIX_0F3A08 + 1) +#define PREFIX_0F3A0A (PREFIX_0F3A09 + 1) +#define PREFIX_0F3A0B (PREFIX_0F3A0A + 1) +#define PREFIX_0F3A0C (PREFIX_0F3A0B + 1) +#define PREFIX_0F3A0D (PREFIX_0F3A0C + 1) +#define PREFIX_0F3A0E (PREFIX_0F3A0D + 1) +#define PREFIX_0F3A14 (PREFIX_0F3A0E + 1) +#define PREFIX_0F3A15 (PREFIX_0F3A14 + 1) +#define PREFIX_0F3A16 (PREFIX_0F3A15 + 1) +#define PREFIX_0F3A17 (PREFIX_0F3A16 + 1) +#define PREFIX_0F3A20 (PREFIX_0F3A17 + 1) +#define PREFIX_0F3A21 (PREFIX_0F3A20 + 1) +#define PREFIX_0F3A22 (PREFIX_0F3A21 + 1) +#define PREFIX_0F3A40 (PREFIX_0F3A22 + 1) +#define PREFIX_0F3A41 (PREFIX_0F3A40 + 1) +#define PREFIX_0F3A42 (PREFIX_0F3A41 + 1) +#define PREFIX_0F3A60 (PREFIX_0F3A42 + 1) +#define PREFIX_0F3A61 (PREFIX_0F3A60 + 1) +#define PREFIX_0F3A62 (PREFIX_0F3A61 + 1) +#define PREFIX_0F3A63 (PREFIX_0F3A62 + 1) +#define PREFIX_0F73_REG_3 (PREFIX_0F3A63 + 1) +#define PREFIX_0F73_REG_7 (PREFIX_0F73_REG_3 + 1) +#define PREFIX_0FC7_REG_6 (PREFIX_0F73_REG_7 + 1) + +#define X86_64_06 0 +#define X86_64_07 (X86_64_06 + 1) +#define X86_64_0D (X86_64_07 + 1) +#define X86_64_16 (X86_64_0D + 1) +#define X86_64_17 (X86_64_16 + 1) +#define X86_64_1E (X86_64_17 + 1) +#define X86_64_1F (X86_64_1E + 1) +#define X86_64_27 (X86_64_1F + 1) +#define X86_64_2F (X86_64_27 + 1) +#define X86_64_37 (X86_64_2F + 1) +#define X86_64_3F (X86_64_37 + 1) +#define X86_64_60 (X86_64_3F + 1) +#define X86_64_61 (X86_64_60 + 1) +#define X86_64_62 (X86_64_61 + 1) +#define X86_64_63 (X86_64_62 + 1) +#define X86_64_6D (X86_64_63 + 1) +#define X86_64_6F (X86_64_6D + 1) +#define X86_64_9A (X86_64_6F + 1) +#define X86_64_C4 (X86_64_9A + 1) +#define X86_64_C5 (X86_64_C4 + 1) +#define X86_64_CE (X86_64_C5 + 1) +#define X86_64_D4 (X86_64_CE + 1) +#define X86_64_D5 (X86_64_D4 + 1) +#define X86_64_EA (X86_64_D5 + 1) +#define X86_64_0F01_REG_0 (X86_64_EA + 1) +#define X86_64_0F01_REG_1 (X86_64_0F01_REG_0 + 1) +#define X86_64_0F01_REG_2 (X86_64_0F01_REG_1 + 1) +#define X86_64_0F01_REG_3 (X86_64_0F01_REG_2 + 1) + +#define THREE_BYTE_0F24 0 +#define THREE_BYTE_0F25 (THREE_BYTE_0F24 + 1) +#define THREE_BYTE_0F38 (THREE_BYTE_0F25 + 1) +#define THREE_BYTE_0F3A (THREE_BYTE_0F38 + 1) +#define THREE_BYTE_0F7A (THREE_BYTE_0F3A + 1) +#define THREE_BYTE_0F7B (THREE_BYTE_0F7A + 1) typedef void (*op_rtn) (int bytemode, int sizeflag); @@ -638,10 +719,7 @@ struct dis386 { for the details. Braces '{' and '}', and vertical bars '|', indicate alternative - mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel - modes. In cases where there are only two alternatives, the X86_64 - instruction is reserved, and "(bad)" is printed. -*/ + mnemonic strings for AT&T and Intel. */ static const struct dis386 dis386[] = { /* 00 */ @@ -651,8 +729,8 @@ static const struct dis386 dis386[] = { { "addS", { Gv, Ev } }, { "addB", { AL, Ib } }, { "addS", { eAX, Iv } }, - { "push{T|}", { es } }, - { "pop{T|}", { es } }, + { X86_64_TABLE (X86_64_06) }, + { X86_64_TABLE (X86_64_07) }, /* 08 */ { "orB", { Eb, Gb } }, { "orS", { Ev, Gv } }, @@ -660,7 +738,7 @@ static const struct dis386 dis386[] = { { "orS", { Gv, Ev } }, { "orB", { AL, Ib } }, { "orS", { eAX, Iv } }, - { "push{T|}", { cs } }, + { X86_64_TABLE (X86_64_0D) }, { "(bad)", { XX } }, /* 0x0f extended opcode escape */ /* 10 */ { "adcB", { Eb, Gb } }, @@ -669,8 +747,8 @@ static const struct dis386 dis386[] = { { "adcS", { Gv, Ev } }, { "adcB", { AL, Ib } }, { "adcS", { eAX, Iv } }, - { "push{T|}", { ss } }, - { "pop{T|}", { ss } }, + { X86_64_TABLE (X86_64_16) }, + { X86_64_TABLE (X86_64_17) }, /* 18 */ { "sbbB", { Eb, Gb } }, { "sbbS", { Ev, Gv } }, @@ -678,8 +756,8 @@ static const struct dis386 dis386[] = { { "sbbS", { Gv, Ev } }, { "sbbB", { AL, Ib } }, { "sbbS", { eAX, Iv } }, - { "push{T|}", { ds } }, - { "pop{T|}", { ds } }, + { X86_64_TABLE (X86_64_1E) }, + { X86_64_TABLE (X86_64_1F) }, /* 20 */ { "andB", { Eb, Gb } }, { "andS", { Ev, Gv } }, @@ -688,7 +766,7 @@ static const struct dis386 dis386[] = { { "andB", { AL, Ib } }, { "andS", { eAX, Iv } }, { "(bad)", { XX } }, /* SEG ES prefix */ - { "daa{|}", { XX } }, + { X86_64_TABLE (X86_64_27) }, /* 28 */ { "subB", { Eb, Gb } }, { "subS", { Ev, Gv } }, @@ -697,7 +775,7 @@ static const struct dis386 dis386[] = { { "subB", { AL, Ib } }, { "subS", { eAX, Iv } }, { "(bad)", { XX } }, /* SEG CS prefix */ - { "das{|}", { XX } }, + { X86_64_TABLE (X86_64_2F) }, /* 30 */ { "xorB", { Eb, Gb } }, { "xorS", { Ev, Gv } }, @@ -706,7 +784,7 @@ static const struct dis386 dis386[] = { { "xorB", { AL, Ib } }, { "xorS", { eAX, Iv } }, { "(bad)", { XX } }, /* SEG SS prefix */ - { "aaa{|}", { XX } }, + { X86_64_TABLE (X86_64_37) }, /* 38 */ { "cmpB", { Eb, Gb } }, { "cmpS", { Ev, Gv } }, @@ -715,7 +793,7 @@ static const struct dis386 dis386[] = { { "cmpB", { AL, Ib } }, { "cmpS", { eAX, Iv } }, { "(bad)", { XX } }, /* SEG DS prefix */ - { "aas{|}", { XX } }, + { X86_64_TABLE (X86_64_3F) }, /* 40 */ { "inc{S|}", { RMeAX } }, { "inc{S|}", { RMeCX } }, @@ -753,10 +831,10 @@ static const struct dis386 dis386[] = { { "popV", { RMrSI } }, { "popV", { RMrDI } }, /* 60 */ - { X86_64_0 }, - { X86_64_1 }, - { X86_64_2 }, - { X86_64_3 }, + { X86_64_TABLE (X86_64_60) }, + { X86_64_TABLE (X86_64_61) }, + { X86_64_TABLE (X86_64_62) }, + { X86_64_TABLE (X86_64_63) }, { "(bad)", { XX } }, /* seg fs */ { "(bad)", { XX } }, /* seg gs */ { "(bad)", { XX } }, /* op size prefix */ @@ -766,10 +844,10 @@ static const struct dis386 dis386[] = { { "imulS", { Gv, Ev, Iv } }, { "pushT", { sIb } }, { "imulS", { Gv, Ev, sIb } }, - { "ins{b||b|}", { Ybr, indirDX } }, - { "ins{R||G|}", { Yzr, indirDX } }, - { "outs{b||b|}", { indirDXr, Xb } }, - { "outs{R||G|}", { indirDXr, Xz } }, + { "ins{b|}", { Ybr, indirDX } }, + { X86_64_TABLE (X86_64_6D) }, + { "outs{b|}", { indirDXr, Xb } }, + { X86_64_TABLE (X86_64_6F) }, /* 70 */ { "joH", { Jb, XX, cond_jump_flag } }, { "jnoH", { Jb, XX, cond_jump_flag } }, @@ -789,10 +867,10 @@ static const struct dis386 dis386[] = { { "jleH", { Jb, XX, cond_jump_flag } }, { "jgH", { Jb, XX, cond_jump_flag } }, /* 80 */ - { GRP1b }, - { GRP1S }, + { REG_TABLE (REG_80) }, + { REG_TABLE (REG_81) }, { "(bad)", { XX } }, - { GRP1Ss }, + { REG_TABLE (REG_82) }, { "testB", { Eb, Gb } }, { "testS", { Ev, Gv } }, { "xchgB", { Eb, Gb } }, @@ -803,11 +881,11 @@ static const struct dis386 dis386[] = { { "movB", { Gb, Eb } }, { "movS", { Gv, Ev } }, { "movD", { Sv, Sw } }, - { "leaS", { Gv, M } }, + { MOD_TABLE (MOD_8D) }, { "movD", { Sw, Sv } }, - { GRP1a }, + { REG_TABLE (REG_8F) }, /* 90 */ - { PREGRP38 }, + { PREFIX_TABLE (PREFIX_90) }, { "xchgS", { RMeCX, eAX } }, { "xchgS", { RMeDX, eAX } }, { "xchgS", { RMeBX, eAX } }, @@ -816,23 +894,23 @@ static const struct dis386 dis386[] = { { "xchgS", { RMeSI, eAX } }, { "xchgS", { RMeDI, eAX } }, /* 98 */ - { "cW{t||t|}R", { XX } }, - { "cR{t||t|}O", { XX } }, - { "Jcall{T|}", { Ap } }, + { "cW{t|}R", { XX } }, + { "cR{t|}O", { XX } }, + { X86_64_TABLE (X86_64_9A) }, { "(bad)", { XX } }, /* fwait */ { "pushfT", { XX } }, { "popfT", { XX } }, - { "sahf{|}", { XX } }, - { "lahf{|}", { XX } }, + { "sahf", { XX } }, + { "lahf", { XX } }, /* a0 */ { "movB", { AL, Ob } }, { "movS", { eAX, Ov } }, { "movB", { Ob, AL } }, { "movS", { Ov, eAX } }, - { "movs{b||b|}", { Ybr, Xb } }, - { "movs{R||R|}", { Yvr, Xv } }, - { "cmps{b||b|}", { Xb, Yb } }, - { "cmps{R||R|}", { Xv, Yv } }, + { "movs{b|}", { Ybr, Xb } }, + { "movs{R|}", { Yvr, Xv } }, + { "cmps{b|}", { Xb, Yb } }, + { "cmps{R|}", { Xv, Yv } }, /* a8 */ { "testB", { AL, Ib } }, { "testS", { eAX, Iv } }, @@ -861,14 +939,14 @@ static const struct dis386 dis386[] = { { "movS", { RMeSI, Iv64 } }, { "movS", { RMeDI, Iv64 } }, /* c0 */ - { GRP2b }, - { GRP2S }, + { REG_TABLE (REG_C0) }, + { REG_TABLE (REG_C1) }, { "retT", { Iw } }, { "retT", { XX } }, - { "les{S|}", { Gv, Mp } }, - { "ldsS", { Gv, Mp } }, - { GRP11_C6 }, - { GRP11_C7 }, + { X86_64_TABLE (X86_64_C4) }, + { X86_64_TABLE (X86_64_C5) }, + { REG_TABLE (REG_C6) }, + { REG_TABLE (REG_C7) }, /* c8 */ { "enterT", { Iw, Ib } }, { "leaveT", { XX } }, @@ -876,15 +954,15 @@ static const struct dis386 dis386[] = { { "lretP", { XX } }, { "int3", { XX } }, { "int", { Ib } }, - { "into{|}", { XX } }, + { X86_64_TABLE (X86_64_CE) }, { "iretP", { XX } }, /* d0 */ - { GRP2b_one }, - { GRP2S_one }, - { GRP2b_cl }, - { GRP2S_cl }, - { "aam{|}", { sIb } }, - { "aad{|}", { sIb } }, + { REG_TABLE (REG_D0) }, + { REG_TABLE (REG_D1) }, + { REG_TABLE (REG_D2) }, + { REG_TABLE (REG_D3) }, + { X86_64_TABLE (X86_64_D4) }, + { X86_64_TABLE (X86_64_D5) }, { "(bad)", { XX } }, { "xlat", { DSBX } }, /* d8 */ @@ -908,7 +986,7 @@ static const struct dis386 dis386[] = { /* e8 */ { "callT", { Jv } }, { "jmpT", { Jv } }, - { "Jjmp{T|}", { Ap } }, + { X86_64_TABLE (X86_64_EA) }, { "jmp", { Jb } }, { "inB", { AL, indirDX } }, { "inG", { zAX, indirDX } }, @@ -921,8 +999,8 @@ static const struct dis386 dis386[] = { { "(bad)", { XX } }, /* repz */ { "hlt", { XX } }, { "cmc", { XX } }, - { GRP3b }, - { GRP3S }, + { REG_TABLE (REG_F6) }, + { REG_TABLE (REG_F7) }, /* f8 */ { "clc", { XX } }, { "stc", { XX } }, @@ -930,14 +1008,14 @@ static const struct dis386 dis386[] = { { "sti", { XX } }, { "cld", { XX } }, { "std", { XX } }, - { GRP4 }, - { GRP5 }, + { REG_TABLE (REG_FE) }, + { REG_TABLE (REG_FF) }, }; static const struct dis386 dis386_twobyte[] = { /* 00 */ - { GRP6 }, - { GRP7 }, + { REG_TABLE (REG_0F00 ) }, + { REG_TABLE (REG_0F01 ) }, { "larS", { Gv, Ew } }, { "lslS", { Gv, Ew } }, { "(bad)", { XX } }, @@ -950,20 +1028,20 @@ static const struct dis386 dis386_twobyte[] = { { "(bad)", { XX } }, { "ud2a", { XX } }, { "(bad)", { XX } }, - { GRPAMD }, + { REG_TABLE (REG_0F0E) }, { "femms", { XX } }, { "", { MX, EM, OPSUF } }, /* See OP_3DNowSuffix. */ /* 10 */ - { PREGRP8 }, - { PREGRP9 }, - { PREGRP30 }, - { "movlpX", { EXq, XM, { SIMD_Fixup, 'h' } } }, - { "unpcklpX", { XM, EXq } }, - { "unpckhpX", { XM, EXq } }, - { PREGRP31 }, - { "movhpX", { EXq, XM, { SIMD_Fixup, 'l' } } }, + { PREFIX_TABLE (PREFIX_0F10) }, + { PREFIX_TABLE (PREFIX_0F11) }, + { PREFIX_TABLE (PREFIX_0F12) }, + { MOD_TABLE (MOD_0F13) }, + { "unpcklpX", { XM, EXx } }, + { "unpckhpX", { XM, EXx } }, + { PREFIX_TABLE (PREFIX_0F16) }, + { MOD_TABLE (MOD_0F17) }, /* 18 */ - { GRP16 }, + { REG_TABLE (REG_0F18) }, { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -972,23 +1050,23 @@ static const struct dis386 dis386_twobyte[] = { { "(bad)", { XX } }, { "nopQ", { Ev } }, /* 20 */ - { "movZ", { Rm, Cm } }, - { "movZ", { Rm, Dm } }, - { "movZ", { Cm, Rm } }, - { "movZ", { Dm, Rm } }, - { "movL", { Rd, Td } }, - { "(bad)", { XX } }, - { "movL", { Td, Rd } }, + { MOD_TABLE (MOD_0F20) }, + { MOD_TABLE (MOD_0F21) }, + { MOD_TABLE (MOD_0F22) }, + { MOD_TABLE (MOD_0F23) }, + { MOD_TABLE (MOD_0F24) }, + { THREE_BYTE_TABLE (THREE_BYTE_0F25) }, + { MOD_TABLE (MOD_0F26) }, { "(bad)", { XX } }, /* 28 */ { "movapX", { XM, EXx } }, { "movapX", { EXx, XM } }, - { PREGRP2 }, - { PREGRP33 }, - { PREGRP4 }, - { PREGRP3 }, - { PREGRP93 }, - { PREGRP94 }, + { PREFIX_TABLE (PREFIX_0F2A) }, + { PREFIX_TABLE (PREFIX_0F2B) }, + { PREFIX_TABLE (PREFIX_0F2C) }, + { PREFIX_TABLE (PREFIX_0F2D) }, + { PREFIX_TABLE (PREFIX_0F2E) }, + { PREFIX_TABLE (PREFIX_0F2F) }, /* 30 */ { "wrmsr", { XX } }, { "rdtsc", { XX } }, @@ -997,11 +1075,11 @@ static const struct dis386 dis386_twobyte[] = { { "sysenter", { XX } }, { "sysexit", { XX } }, { "(bad)", { XX } }, - { "(bad)", { XX } }, + { "getsec", { XX } }, /* 38 */ - { THREE_BYTE_0 }, + { THREE_BYTE_TABLE (THREE_BYTE_0F38) }, { "(bad)", { XX } }, - { THREE_BYTE_1 }, + { THREE_BYTE_TABLE (THREE_BYTE_0F3A) }, { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -1027,26 +1105,26 @@ static const struct dis386 dis386_twobyte[] = { { "cmovg", { Gv, Ev } }, /* 50 */ { "movmskpX", { Gdq, XS } }, - { PREGRP13 }, - { PREGRP12 }, - { PREGRP11 }, + { PREFIX_TABLE (PREFIX_0F51) }, + { PREFIX_TABLE (PREFIX_0F52) }, + { PREFIX_TABLE (PREFIX_0F53) }, { "andpX", { XM, EXx } }, { "andnpX", { XM, EXx } }, { "orpX", { XM, EXx } }, { "xorpX", { XM, EXx } }, /* 58 */ - { PREGRP0 }, - { PREGRP10 }, - { PREGRP17 }, - { PREGRP16 }, - { PREGRP14 }, - { PREGRP7 }, - { PREGRP5 }, - { PREGRP6 }, + { PREFIX_TABLE (PREFIX_0F58) }, + { PREFIX_TABLE (PREFIX_0F59) }, + { PREFIX_TABLE (PREFIX_0F5A) }, + { PREFIX_TABLE (PREFIX_0F5B) }, + { PREFIX_TABLE (PREFIX_0F5C) }, + { PREFIX_TABLE (PREFIX_0F5D) }, + { PREFIX_TABLE (PREFIX_0F5E) }, + { PREFIX_TABLE (PREFIX_0F5F) }, /* 60 */ - { PREGRP95 }, - { PREGRP96 }, - { PREGRP97 }, + { PREFIX_TABLE (PREFIX_0F60) }, + { PREFIX_TABLE (PREFIX_0F61) }, + { PREFIX_TABLE (PREFIX_0F62) }, { "packsswb", { MX, EM } }, { "pcmpgtb", { MX, EM } }, { "pcmpgtw", { MX, EM } }, @@ -1057,28 +1135,28 @@ static const struct dis386 dis386_twobyte[] = { { "punpckhwd", { MX, EM } }, { "punpckhdq", { MX, EM } }, { "packssdw", { MX, EM } }, - { PREGRP26 }, - { PREGRP24 }, + { PREFIX_TABLE (PREFIX_0F6C) }, + { PREFIX_TABLE (PREFIX_0F6D) }, { "movK", { MX, Edq } }, - { PREGRP19 }, + { PREFIX_TABLE (PREFIX_0F6F) }, /* 70 */ - { PREGRP22 }, - { GRP12 }, - { GRP13 }, - { GRP14 }, + { PREFIX_TABLE (PREFIX_0F70) }, + { REG_TABLE (REG_0F71) }, + { REG_TABLE (REG_0F72) }, + { REG_TABLE (REG_0F73) }, { "pcmpeqb", { MX, EM } }, { "pcmpeqw", { MX, EM } }, { "pcmpeqd", { MX, EM } }, { "emms", { XX } }, /* 78 */ - { PREGRP34 }, - { PREGRP35 }, - { "(bad)", { XX } }, - { "(bad)", { XX } }, - { PREGRP28 }, - { PREGRP29 }, - { PREGRP23 }, - { PREGRP20 }, + { PREFIX_TABLE (PREFIX_0F78) }, + { PREFIX_TABLE (PREFIX_0F79) }, + { THREE_BYTE_TABLE (THREE_BYTE_0F7A) }, + { THREE_BYTE_TABLE (THREE_BYTE_0F7B) }, + { PREFIX_TABLE (PREFIX_0F7C) }, + { PREFIX_TABLE (PREFIX_0F7D) }, + { PREFIX_TABLE (PREFIX_0F7E) }, + { PREFIX_TABLE (PREFIX_0F7F) }, /* 80 */ { "joH", { Jv, XX, cond_jump_flag } }, { "jnoH", { Jv, XX, cond_jump_flag } }, @@ -1122,8 +1200,8 @@ static const struct dis386 dis386_twobyte[] = { { "btS", { Ev, Gv } }, { "shldS", { Ev, Gv, Ib } }, { "shldS", { Ev, Gv, CL } }, - { GRPPADLCK2 }, - { GRPPADLCK1 }, + { REG_TABLE (REG_0FA6) }, + { REG_TABLE (REG_0FA7) }, /* a8 */ { "pushT", { gs } }, { "popT", { gs } }, @@ -1131,35 +1209,35 @@ static const struct dis386 dis386_twobyte[] = { { "btsS", { Ev, Gv } }, { "shrdS", { Ev, Gv, Ib } }, { "shrdS", { Ev, Gv, CL } }, - { GRP15 }, + { REG_TABLE (REG_0FAE) }, { "imulS", { Gv, Ev } }, /* b0 */ { "cmpxchgB", { Eb, Gb } }, { "cmpxchgS", { Ev, Gv } }, - { "lssS", { Gv, Mp } }, + { MOD_TABLE (MOD_0FB2) }, { "btrS", { Ev, Gv } }, - { "lfsS", { Gv, Mp } }, - { "lgsS", { Gv, Mp } }, - { "movz{bR|x|bR|x}", { Gv, Eb } }, - { "movz{wR|x|wR|x}", { Gv, Ew } }, /* yes, there really is movzww ! */ + { MOD_TABLE (MOD_0FB4) }, + { MOD_TABLE (MOD_0FB5) }, + { "movz{bR|x}", { Gv, Eb } }, + { "movz{wR|x}", { Gv, Ew } }, /* yes, there really is movzww ! */ /* b8 */ - { PREGRP37 }, + { PREFIX_TABLE (PREFIX_0FB8) }, { "ud2b", { XX } }, - { GRP8 }, + { REG_TABLE (REG_0FBA) }, { "btcS", { Ev, Gv } }, { "bsfS", { Gv, Ev } }, - { PREGRP36 }, - { "movs{bR|x|bR|x}", { Gv, Eb } }, - { "movs{wR|x|wR|x}", { Gv, Ew } }, /* yes, there really is movsww ! */ + { PREFIX_TABLE (PREFIX_0FBD) }, + { "movs{bR|x}", { Gv, Eb } }, + { "movs{wR|x}", { Gv, Ew } }, /* yes, there really is movsww ! */ /* c0 */ { "xaddB", { Eb, Gb } }, { "xaddS", { Ev, Gv } }, - { PREGRP1 }, + { PREFIX_TABLE (PREFIX_0FC2) }, { "movntiS", { Ev, Gv } }, { "pinsrw", { MX, Edqw, Ib } }, { "pextrw", { Gdq, MS, Ib } }, { "shufpX", { XM, EXx, Ib } }, - { GRP9 }, + { REG_TABLE (REG_0FC7) }, /* c8 */ { "bswap", { RMeAX } }, { "bswap", { RMeCX } }, @@ -1170,13 +1248,13 @@ static const struct dis386 dis386_twobyte[] = { { "bswap", { RMeSI } }, { "bswap", { RMeDI } }, /* d0 */ - { PREGRP27 }, + { PREFIX_TABLE (PREFIX_0FD0) }, { "psrlw", { MX, EM } }, { "psrld", { MX, EM } }, { "psrlq", { MX, EM } }, { "paddq", { MX, EM } }, { "pmullw", { MX, EM } }, - { PREGRP21 }, + { PREFIX_TABLE (PREFIX_0FD6) }, { "pmovmskb", { Gdq, MS } }, /* d8 */ { "psubusb", { MX, EM } }, @@ -1194,8 +1272,8 @@ static const struct dis386 dis386_twobyte[] = { { "pavgw", { MX, EM } }, { "pmulhuw", { MX, EM } }, { "pmulhw", { MX, EM } }, - { PREGRP15 }, - { PREGRP25 }, + { PREFIX_TABLE (PREFIX_0FE6) }, + { PREFIX_TABLE (PREFIX_0FE7) }, /* e8 */ { "psubsb", { MX, EM } }, { "psubsw", { MX, EM } }, @@ -1206,14 +1284,14 @@ static const struct dis386 dis386_twobyte[] = { { "pmaxsw", { MX, EM } }, { "pxor", { MX, EM } }, /* f0 */ - { PREGRP32 }, + { PREFIX_TABLE (PREFIX_0FF0) }, { "psllw", { MX, EM } }, { "pslld", { MX, EM } }, { "psllq", { MX, EM } }, { "pmuludq", { MX, EM } }, { "pmaddwd", { MX, EM } }, { "psadbw", { MX, EM } }, - { PREGRP18 }, + { PREFIX_TABLE (PREFIX_0FF7) }, /* f8 */ { "psubb", { MX, EM } }, { "psubw", { MX, EM } }, @@ -1253,12 +1331,12 @@ static const unsigned char twobyte_has_modrm[256] = { /* ------------------------------- */ /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */ /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1, /* 1f */ - /* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */ + /* 20 */ 1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1, /* 2f */ /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */ /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */ /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */ /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */ - /* 70 */ 1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1, /* 7f */ + /* 70 */ 1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1, /* 7f */ /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */ /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */ /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */ @@ -1303,6 +1381,8 @@ static const char **names16; static const char **names8; static const char **names8rex; static const char **names_seg; +static const char *index64; +static const char *index32; static const char **index16; static const char *intel_names64[] = { @@ -1327,6 +1407,8 @@ static const char *intel_names8rex[] = { static const char *intel_names_seg[] = { "es", "cs", "ss", "ds", "fs", "gs", "?", "?", }; +static const char *intel_index64 = "riz"; +static const char *intel_index32 = "eiz"; static const char *intel_index16[] = { "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx" }; @@ -1353,23 +1435,14 @@ static const char *att_names8rex[] = { static const char *att_names_seg[] = { "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?", }; +static const char *att_index64 = "%riz"; +static const char *att_index32 = "%eiz"; static const char *att_index16[] = { "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx" }; -static const struct dis386 grps[][8] = { - /* GRP1a */ - { - { "popU", { stackEv } }, - { "(bad)", { XX } }, - { "(bad)", { XX } }, - { "(bad)", { XX } }, - { "(bad)", { XX } }, - { "(bad)", { XX } }, - { "(bad)", { XX } }, - { "(bad)", { XX } }, - }, - /* GRP1b */ +static const struct dis386 reg_table[][8] = { + /* REG_80 */ { { "addA", { Eb, Ib } }, { "orA", { Eb, Ib } }, @@ -1380,7 +1453,7 @@ static const struct dis386 grps[][8] = { { "xorA", { Eb, Ib } }, { "cmpA", { Eb, Ib } }, }, - /* GRP1S */ + /* REG_81 */ { { "addQ", { Ev, Iv } }, { "orQ", { Ev, Iv } }, @@ -1391,7 +1464,7 @@ static const struct dis386 grps[][8] = { { "xorQ", { Ev, Iv } }, { "cmpQ", { Ev, Iv } }, }, - /* GRP1Ss */ + /* REG_82 */ { { "addQ", { Ev, sIb } }, { "orQ", { Ev, sIb } }, @@ -1402,7 +1475,18 @@ static const struct dis386 grps[][8] = { { "xorQ", { Ev, sIb } }, { "cmpQ", { Ev, sIb } }, }, - /* GRP2b */ + /* REG_8F */ + { + { "popU", { stackEv } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + }, + /* REG_C0 */ { { "rolA", { Eb, Ib } }, { "rorA", { Eb, Ib } }, @@ -1413,7 +1497,7 @@ static const struct dis386 grps[][8] = { { "(bad)", { XX } }, { "sarA", { Eb, Ib } }, }, - /* GRP2S */ + /* REG_C1 */ { { "rolQ", { Ev, Ib } }, { "rorQ", { Ev, Ib } }, @@ -1424,7 +1508,29 @@ static const struct dis386 grps[][8] = { { "(bad)", { XX } }, { "sarQ", { Ev, Ib } }, }, - /* GRP2b_one */ + /* REG_C6 */ + { + { "movA", { Eb, Ib } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + }, + /* REG_C7 */ + { + { "movQ", { Ev, Iv } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + }, + /* REG_D0 */ { { "rolA", { Eb, I1 } }, { "rorA", { Eb, I1 } }, @@ -1435,7 +1541,7 @@ static const struct dis386 grps[][8] = { { "(bad)", { XX } }, { "sarA", { Eb, I1 } }, }, - /* GRP2S_one */ + /* REG_D1 */ { { "rolQ", { Ev, I1 } }, { "rorQ", { Ev, I1 } }, @@ -1446,7 +1552,7 @@ static const struct dis386 grps[][8] = { { "(bad)", { XX } }, { "sarQ", { Ev, I1 } }, }, - /* GRP2b_cl */ + /* REG_D2 */ { { "rolA", { Eb, CL } }, { "rorA", { Eb, CL } }, @@ -1457,7 +1563,7 @@ static const struct dis386 grps[][8] = { { "(bad)", { XX } }, { "sarA", { Eb, CL } }, }, - /* GRP2S_cl */ + /* REG_D3 */ { { "rolQ", { Ev, CL } }, { "rorQ", { Ev, CL } }, @@ -1468,10 +1574,10 @@ static const struct dis386 grps[][8] = { { "(bad)", { XX } }, { "sarQ", { Ev, CL } }, }, - /* GRP3b */ + /* REG_F6 */ { { "testA", { Eb, Ib } }, - { "(bad)", { Eb } }, + { "(bad)", { XX } }, { "notA", { Eb } }, { "negA", { Eb } }, { "mulA", { Eb } }, /* Don't print the implicit %al register, */ @@ -1479,7 +1585,7 @@ static const struct dis386 grps[][8] = { { "divA", { Eb } }, /* mul/imul opcodes. Do the same for div */ { "idivA", { Eb } }, /* and idiv for consistency. */ }, - /* GRP3S */ + /* REG_F7 */ { { "testQ", { Ev, Iv } }, { "(bad)", { XX } }, @@ -1490,7 +1596,7 @@ static const struct dis386 grps[][8] = { { "divQ", { Ev } }, { "idivQ", { Ev } }, }, - /* GRP4 */ + /* REG_FE */ { { "incA", { Eb } }, { "decA", { Eb } }, @@ -1501,7 +1607,7 @@ static const struct dis386 grps[][8] = { { "(bad)", { XX } }, { "(bad)", { XX } }, }, - /* GRP5 */ + /* REG_FF */ { { "incQ", { Ev } }, { "decQ", { Ev } }, @@ -1512,7 +1618,7 @@ static const struct dis386 grps[][8] = { { "pushU", { stackEv } }, { "(bad)", { XX } }, }, - /* GRP6 */ + /* REG_0F00 */ { { "sldtD", { Sv } }, { "strD", { Sv } }, @@ -1523,432 +1629,483 @@ static const struct dis386 grps[][8] = { { "(bad)", { XX } }, { "(bad)", { XX } }, }, - /* GRP7 */ + /* REG_0F01 */ { - { OPC_EXT_0 }, - { OPC_EXT_1 }, - { "lgdt{Q|Q||}", { M } }, - { "lidt{Q|Q||}", { { SVME_Fixup, 0 } } }, + { MOD_TABLE (MOD_0F01_REG_0) }, + { MOD_TABLE (MOD_0F01_REG_1) }, + { MOD_TABLE (MOD_0F01_REG_2) }, + { MOD_TABLE (MOD_0F01_REG_3) }, { "smswD", { Sv } }, { "(bad)", { XX } }, { "lmsw", { Ew } }, - { "invlpg", { { INVLPG_Fixup, 0 } } }, + { MOD_TABLE (MOD_0F01_REG_7) }, }, - /* GRP8 */ + /* REG_0F0E */ { - { "(bad)", { XX } }, - { "(bad)", { XX } }, - { "(bad)", { XX } }, - { "(bad)", { XX } }, - { "btQ", { Ev, Ib } }, - { "btsQ", { Ev, Ib } }, - { "btrQ", { Ev, Ib } }, - { "btcQ", { Ev, Ib } }, + { "prefetch", { Eb } }, + { "prefetchw", { Eb } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, }, - /* GRP9 */ + /* REG_0F18 */ { - { "(bad)", { XX } }, - { "cmpxchg8b", { { CMPXCHG8B_Fixup, q_mode } } }, + { MOD_TABLE (MOD_0F18_REG_0) }, + { MOD_TABLE (MOD_0F18_REG_1) }, + { MOD_TABLE (MOD_0F18_REG_2) }, + { MOD_TABLE (MOD_0F18_REG_3) }, { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, - { OPC_EXT_2 }, - { OPC_EXT_3 }, }, - /* GRP11_C6 */ + /* REG_0F71 */ { - { "movA", { Eb, Ib } }, - { "(bad)", { XX } }, - { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, + { MOD_TABLE (MOD_0F71_REG_2) }, { "(bad)", { XX } }, + { MOD_TABLE (MOD_0F71_REG_4) }, { "(bad)", { XX } }, + { MOD_TABLE (MOD_0F71_REG_6) }, { "(bad)", { XX } }, }, - /* GRP11_C7 */ + /* REG_0F72 */ { - { "movQ", { Ev, Iv } }, { "(bad)", { XX } }, { "(bad)", { XX } }, + { MOD_TABLE (MOD_0F72_REG_2) }, { "(bad)", { XX } }, + { MOD_TABLE (MOD_0F72_REG_4) }, { "(bad)", { XX } }, + { MOD_TABLE (MOD_0F72_REG_6) }, { "(bad)", { XX } }, - { "(bad)", { XX } }, - { "(bad)", { XX } }, }, - /* GRP12 */ + /* REG_0F73 */ { { "(bad)", { XX } }, { "(bad)", { XX } }, - { OPC_EXT_4 }, + { MOD_TABLE (MOD_0F73_REG_2) }, + { MOD_TABLE (MOD_0F73_REG_3) }, { "(bad)", { XX } }, - { OPC_EXT_5 }, - { "(bad)", { XX } }, - { OPC_EXT_6 }, { "(bad)", { XX } }, + { MOD_TABLE (MOD_0F73_REG_6) }, + { MOD_TABLE (MOD_0F73_REG_7) }, }, - /* GRP13 */ + /* REG_0FA6 */ { + { "montmul", { { OP_0f07, 0 } } }, + { "xsha1", { { OP_0f07, 0 } } }, + { "xsha256", { { OP_0f07, 0 } } }, + { "(bad)", { { OP_0f07, 0 } } }, + { "(bad)", { { OP_0f07, 0 } } }, + { "(bad)", { { OP_0f07, 0 } } }, + { "(bad)", { { OP_0f07, 0 } } }, + { "(bad)", { { OP_0f07, 0 } } }, + }, + /* REG_0FA7 */ + { + { "xstore-rng", { { OP_0f07, 0 } } }, + { "xcrypt-ecb", { { OP_0f07, 0 } } }, + { "xcrypt-cbc", { { OP_0f07, 0 } } }, + { "xcrypt-ctr", { { OP_0f07, 0 } } }, + { "xcrypt-cfb", { { OP_0f07, 0 } } }, + { "xcrypt-ofb", { { OP_0f07, 0 } } }, + { "(bad)", { { OP_0f07, 0 } } }, + { "(bad)", { { OP_0f07, 0 } } }, + }, + /* REG_0FAE */ + { + { MOD_TABLE (MOD_0FAE_REG_0) }, + { MOD_TABLE (MOD_0FAE_REG_1) }, + { MOD_TABLE (MOD_0FAE_REG_2) }, + { MOD_TABLE (MOD_0FAE_REG_3) }, { "(bad)", { XX } }, - { "(bad)", { XX } }, - { OPC_EXT_7 }, - { "(bad)", { XX } }, - { OPC_EXT_8 }, - { "(bad)", { XX } }, - { OPC_EXT_9 }, - { "(bad)", { XX } }, + { MOD_TABLE (MOD_0FAE_REG_5) }, + { MOD_TABLE (MOD_0FAE_REG_6) }, + { MOD_TABLE (MOD_0FAE_REG_7) }, }, - /* GRP14 */ + /* REG_0FBA */ { { "(bad)", { XX } }, { "(bad)", { XX } }, - { OPC_EXT_10 }, - { OPC_EXT_11 }, { "(bad)", { XX } }, { "(bad)", { XX } }, - { OPC_EXT_12 }, - { OPC_EXT_13 }, + { "btQ", { Ev, Ib } }, + { "btsQ", { Ev, Ib } }, + { "btrQ", { Ev, Ib } }, + { "btcQ", { Ev, Ib } }, }, - /* GRP15 */ + /* REG_0FC7 */ { - { OPC_EXT_14 }, - { OPC_EXT_15 }, - { OPC_EXT_16 }, - { OPC_EXT_17 }, { "(bad)", { XX } }, - { OPC_EXT_18 }, - { OPC_EXT_19 }, - { OPC_EXT_20 }, - }, - /* GRP16 */ - { - { OPC_EXT_21 }, - { OPC_EXT_22 }, - { OPC_EXT_23 }, - { OPC_EXT_24 }, + { "cmpxchg8b", { { CMPXCHG8B_Fixup, q_mode } } }, { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, + { MOD_TABLE (MOD_0FC7_REG_6) }, + { MOD_TABLE (MOD_0FC7_REG_7) }, }, - /* GRPAMD */ +}; + +static const struct dis386 prefix_table[][4] = { + /* PREFIX_90 */ { - { "prefetch", { Eb } }, - { "prefetchw", { Eb } }, - { "(bad)", { XX } }, - { "(bad)", { XX } }, - { "(bad)", { XX } }, - { "(bad)", { XX } }, - { "(bad)", { XX } }, - { "(bad)", { XX } }, + { "xchgS", { { NOP_Fixup1, eAX_reg }, { NOP_Fixup2, eAX_reg } } }, + { "pause", { XX } }, + { "xchgS", { { NOP_Fixup1, eAX_reg }, { NOP_Fixup2, eAX_reg } } }, + { "(bad)", { XX } }, }, - /* GRPPADLCK1 */ + + /* PREFIX_0F10 */ { - { "xstore-rng", { { OP_0f07, 0 } } }, - { "xcrypt-ecb", { { OP_0f07, 0 } } }, - { "xcrypt-cbc", { { OP_0f07, 0 } } }, - { "xcrypt-ctr", { { OP_0f07, 0 } } }, - { "xcrypt-cfb", { { OP_0f07, 0 } } }, - { "xcrypt-ofb", { { OP_0f07, 0 } } }, - { "(bad)", { { OP_0f07, 0 } } }, - { "(bad)", { { OP_0f07, 0 } } }, + { "movups", { XM, EXx } }, + { "movss", { XM, EXd } }, + { "movupd", { XM, EXx } }, + { "movsd", { XM, EXq } }, }, - /* GRPPADLCK2 */ + + /* PREFIX_0F11 */ { - { "montmul", { { OP_0f07, 0 } } }, - { "xsha1", { { OP_0f07, 0 } } }, - { "xsha256", { { OP_0f07, 0 } } }, - { "(bad)", { { OP_0f07, 0 } } }, - { "(bad)", { { OP_0f07, 0 } } }, - { "(bad)", { { OP_0f07, 0 } } }, - { "(bad)", { { OP_0f07, 0 } } }, - { "(bad)", { { OP_0f07, 0 } } }, - } -}; + { "movups", { EXx, XM } }, + { "movss", { EXd, XM } }, + { "movupd", { EXx, XM } }, + { "movsd", { EXq, XM } }, + }, -static const struct dis386 prefix_user_table[][4] = { - /* PREGRP0 */ + /* PREFIX_0F12 */ { - { "addps", { XM, EXx } }, - { "addss", { XM, EXd } }, - { "addpd", { XM, EXx } }, - { "addsd", { XM, EXq } }, + { MOD_TABLE (MOD_0F12_PREFIX_0) }, + { "movsldup", { XM, EXx } }, + { "movlpd", { XM, EXq } }, + { "movddup", { XM, EXq } }, }, - /* PREGRP1 */ + + /* PREFIX_0F16 */ { - { "", { XM, EXx, OPSIMD } }, /* See OP_SIMD_SUFFIX. */ - { "", { XM, EXd, OPSIMD } }, - { "", { XM, EXx, OPSIMD } }, - { "", { XM, EXq, OPSIMD } }, + { MOD_TABLE (MOD_0F16_PREFIX_0) }, + { "movshdup", { XM, EXx } }, + { "movhpd", { XM, EXq } }, + { "(bad)", { XX } }, }, - /* PREGRP2 */ + + /* PREFIX_0F2A */ { { "cvtpi2ps", { XM, EMCq } }, { "cvtsi2ssY", { XM, Ev } }, { "cvtpi2pd", { XM, EMCq } }, { "cvtsi2sdY", { XM, Ev } }, }, - /* PREGRP3 */ + + /* PREFIX_0F2B */ { - { "cvtps2pi", { MXC, EXq } }, - { "cvtss2siY", { Gv, EXd } }, - { "cvtpd2pi", { MXC, EXx } }, - { "cvtsd2siY", { Gv, EXq } }, + {"movntps", { Ev, XM } }, + {"movntss", { Ed, XM } }, + {"movntpd", { Ev, XM } }, + {"movntsd", { Eq, XM } }, }, - /* PREGRP4 */ + + /* PREFIX_0F2C */ { { "cvttps2pi", { MXC, EXq } }, { "cvttss2siY", { Gv, EXd } }, { "cvttpd2pi", { MXC, EXx } }, { "cvttsd2siY", { Gv, EXq } }, }, - /* PREGRP5 */ + + /* PREFIX_0F2D */ { - { "divps", { XM, EXx } }, - { "divss", { XM, EXd } }, - { "divpd", { XM, EXx } }, - { "divsd", { XM, EXq } }, + { "cvtps2pi", { MXC, EXq } }, + { "cvtss2siY", { Gv, EXd } }, + { "cvtpd2pi", { MXC, EXx } }, + { "cvtsd2siY", { Gv, EXq } }, }, - /* PREGRP6 */ + + /* PREFIX_0F2E */ { - { "maxps", { XM, EXx } }, - { "maxss", { XM, EXd } }, - { "maxpd", { XM, EXx } }, - { "maxsd", { XM, EXq } }, + { "ucomiss",{ XM, EXd } }, + { "(bad)", { XX } }, + { "ucomisd",{ XM, EXq } }, + { "(bad)", { XX } }, }, - /* PREGRP7 */ + + /* PREFIX_0F2F */ { - { "minps", { XM, EXx } }, - { "minss", { XM, EXd } }, - { "minpd", { XM, EXx } }, - { "minsd", { XM, EXq } }, + { "comiss", { XM, EXd } }, + { "(bad)", { XX } }, + { "comisd", { XM, EXq } }, + { "(bad)", { XX } }, }, - /* PREGRP8 */ + + /* PREFIX_0F51 */ { - { "movups", { XM, EXx } }, - { "movss", { XM, EXd } }, - { "movupd", { XM, EXx } }, - { "movsd", { XM, EXq } }, + { "sqrtps", { XM, EXx } }, + { "sqrtss", { XM, EXd } }, + { "sqrtpd", { XM, EXx } }, + { "sqrtsd", { XM, EXq } }, }, - /* PREGRP9 */ + + /* PREFIX_0F52 */ { - { "movups", { EXx, XM } }, - { "movss", { EXd, XM } }, - { "movupd", { EXx, XM } }, - { "movsd", { EXq, XM } }, + { "rsqrtps",{ XM, EXx } }, + { "rsqrtss",{ XM, EXd } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + }, + + /* PREFIX_0F53 */ + { + { "rcpps", { XM, EXx } }, + { "rcpss", { XM, EXd } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + }, + + /* PREFIX_0F58 */ + { + { "addps", { XM, EXx } }, + { "addss", { XM, EXd } }, + { "addpd", { XM, EXx } }, + { "addsd", { XM, EXq } }, }, - /* PREGRP10 */ + + /* PREFIX_0F59 */ { { "mulps", { XM, EXx } }, { "mulss", { XM, EXd } }, { "mulpd", { XM, EXx } }, { "mulsd", { XM, EXq } }, }, - /* PREGRP11 */ - { - { "rcpps", { XM, EXx } }, - { "rcpss", { XM, EXd } }, - { "(bad)", { XM, EXx } }, - { "(bad)", { XM, EXx } }, - }, - /* PREGRP12 */ + + /* PREFIX_0F5A */ { - { "rsqrtps",{ XM, EXx } }, - { "rsqrtss",{ XM, EXd } }, - { "(bad)", { XM, EXx } }, - { "(bad)", { XM, EXx } }, + { "cvtps2pd", { XM, EXq } }, + { "cvtss2sd", { XM, EXd } }, + { "cvtpd2ps", { XM, EXx } }, + { "cvtsd2ss", { XM, EXq } }, }, - /* PREGRP13 */ + + /* PREFIX_0F5B */ { - { "sqrtps", { XM, EXx } }, - { "sqrtss", { XM, EXd } }, - { "sqrtpd", { XM, EXx } }, - { "sqrtsd", { XM, EXq } }, + { "cvtdq2ps", { XM, EXx } }, + { "cvttps2dq", { XM, EXx } }, + { "cvtps2dq", { XM, EXx } }, + { "(bad)", { XX } }, }, - /* PREGRP14 */ + + /* PREFIX_0F5C */ { { "subps", { XM, EXx } }, { "subss", { XM, EXd } }, { "subpd", { XM, EXx } }, { "subsd", { XM, EXq } }, }, - /* PREGRP15 */ - { - { "(bad)", { XM, EXx } }, - { "cvtdq2pd", { XM, EXq } }, - { "cvttpd2dq", { XM, EXx } }, - { "cvtpd2dq", { XM, EXx } }, - }, - /* PREGRP16 */ + + /* PREFIX_0F5D */ { - { "cvtdq2ps", { XM, EXx } }, - { "cvttps2dq", { XM, EXx } }, - { "cvtps2dq", { XM, EXx } }, - { "(bad)", { XM, EXx } }, + { "minps", { XM, EXx } }, + { "minss", { XM, EXd } }, + { "minpd", { XM, EXx } }, + { "minsd", { XM, EXq } }, }, - /* PREGRP17 */ + + /* PREFIX_0F5E */ { - { "cvtps2pd", { XM, EXq } }, - { "cvtss2sd", { XM, EXd } }, - { "cvtpd2ps", { XM, EXx } }, - { "cvtsd2ss", { XM, EXq } }, + { "divps", { XM, EXx } }, + { "divss", { XM, EXd } }, + { "divpd", { XM, EXx } }, + { "divsd", { XM, EXq } }, }, - /* PREGRP18 */ + + /* PREFIX_0F5F */ { - { "maskmovq", { MX, MS } }, - { "(bad)", { XM, EXx } }, - { "maskmovdqu", { XM, XS } }, - { "(bad)", { XM, EXx } }, + { "maxps", { XM, EXx } }, + { "maxss", { XM, EXd } }, + { "maxpd", { XM, EXx } }, + { "maxsd", { XM, EXq } }, }, - /* PREGRP19 */ + + /* PREFIX_0F60 */ { - { "movq", { MX, EM } }, - { "movdqu", { XM, EXx } }, - { "movdqa", { XM, EXx } }, - { "(bad)", { XM, EXx } }, + { "punpcklbw",{ MX, EMd } }, + { "(bad)", { XX } }, + { "punpcklbw",{ MX, EMx } }, + { "(bad)", { XX } }, }, - /* PREGRP20 */ + + /* PREFIX_0F61 */ { - { "movq", { EM, MX } }, - { "movdqu", { EXx, XM } }, - { "movdqa", { EXx, XM } }, - { "(bad)", { EXx, XM } }, + { "punpcklwd",{ MX, EMd } }, + { "(bad)", { XX } }, + { "punpcklwd",{ MX, EMx } }, + { "(bad)", { XX } }, }, - /* PREGRP21 */ + + /* PREFIX_0F62 */ { - { "(bad)", { EXx, XM } }, - { "movq2dq",{ XM, MS } }, - { "movq", { EXq, XM } }, - { "movdq2q",{ MX, XS } }, + { "punpckldq",{ MX, EMd } }, + { "(bad)", { XX } }, + { "punpckldq",{ MX, EMx } }, + { "(bad)", { XX } }, }, - /* PREGRP22 */ + + /* PREFIX_0F6C */ { - { "pshufw", { MX, EM, Ib } }, - { "pshufhw",{ XM, EXx, Ib } }, - { "pshufd", { XM, EXx, Ib } }, - { "pshuflw",{ XM, EXx, Ib } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "punpcklqdq", { XM, EXx } }, + { "(bad)", { XX } }, }, - /* PREGRP23 */ + + /* PREFIX_0F6D */ { - { "movK", { Edq, MX } }, - { "movq", { XM, EXq } }, - { "movK", { Edq, XM } }, - { "(bad)", { Ed, XM } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "punpckhqdq", { XM, EXx } }, + { "(bad)", { XX } }, }, - /* PREGRP24 */ + + /* PREFIX_0F6F */ { - { "(bad)", { MX, EXx } }, - { "(bad)", { XM, EXx } }, - { "punpckhqdq", { XM, EXx } }, - { "(bad)", { XM, EXx } }, + { "movq", { MX, EM } }, + { "movdqu", { XM, EXx } }, + { "movdqa", { XM, EXx } }, + { "(bad)", { XX } }, }, - /* PREGRP25 */ + + /* PREFIX_0F70 */ { - { "movntq", { EM, MX } }, - { "(bad)", { EM, XM } }, - { "movntdq",{ EM, XM } }, - { "(bad)", { EM, XM } }, + { "pshufw", { MX, EM, Ib } }, + { "pshufhw",{ XM, EXx, Ib } }, + { "pshufd", { XM, EXx, Ib } }, + { "pshuflw",{ XM, EXx, Ib } }, }, - /* PREGRP26 */ + + /* PREFIX_0F78 */ { - { "(bad)", { MX, EXx } }, - { "(bad)", { XM, EXx } }, - { "punpcklqdq", { XM, EXx } }, - { "(bad)", { XM, EXx } }, + {"vmread", { Em, Gm } }, + {"(bad)", { XX } }, + {"extrq", { XS, Ib, Ib } }, + {"insertq", { XM, XS, Ib, Ib } }, }, - /* PREGRP27 */ + + /* PREFIX_0F79 */ { - { "(bad)", { MX, EXx } }, - { "(bad)", { XM, EXx } }, - { "addsubpd", { XM, EXx } }, - { "addsubps", { XM, EXx } }, + {"vmwrite", { Gm, Em } }, + {"(bad)", { XX } }, + {"extrq", { XM, XS } }, + {"insertq", { XM, XS } }, }, - /* PREGRP28 */ + + /* PREFIX_0F7C */ { - { "(bad)", { MX, EXx } }, - { "(bad)", { XM, EXx } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, { "haddpd", { XM, EXx } }, { "haddps", { XM, EXx } }, }, - /* PREGRP29 */ + + /* PREFIX_0F7D */ { - { "(bad)", { MX, EXx } }, - { "(bad)", { XM, EXx } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, { "hsubpd", { XM, EXx } }, { "hsubps", { XM, EXx } }, }, - /* PREGRP30 */ + + /* PREFIX_0F7E */ { - { "movlpX", { XM, EXq, { SIMD_Fixup, 'h' } } }, /* really only 2 operands */ - { "movsldup", { XM, EXx } }, - { "movlpd", { XM, EXq } }, - { "movddup", { XM, EXq } }, + { "movK", { Edq, MX } }, + { "movq", { XM, EXq } }, + { "movK", { Edq, XM } }, + { "(bad)", { XX } }, }, - /* PREGRP31 */ + + /* PREFIX_0F7F */ { - { "movhpX", { XM, EXq, { SIMD_Fixup, 'l' } } }, - { "movshdup", { XM, EXx } }, - { "movhpd", { XM, EXq } }, - { "(bad)", { XM, EXq } }, + { "movq", { EM, MX } }, + { "movdqu", { EXx, XM } }, + { "movdqa", { EXx, XM } }, + { "(bad)", { XX } }, }, - /* PREGRP32 */ + + /* PREFIX_0FB8 */ { - { "(bad)", { XM, EXx } }, - { "(bad)", { XM, EXx } }, - { "(bad)", { XM, EXx } }, - { "lddqu", { XM, M } }, + { "(bad)", { XX } }, + { "popcntS", { Gv, Ev } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, }, - /* PREGRP33 */ + + /* PREFIX_0FBD */ { - {"movntps", { Ev, XM } }, - {"movntss", { Ed, XM } }, - {"movntpd", { Ev, XM } }, - {"movntsd", { Eq, XM } }, + { "bsrS", { Gv, Ev } }, + { "lzcntS", { Gv, Ev } }, + { "bsrS", { Gv, Ev } }, + { "(bad)", { XX } }, }, - /* PREGRP34 */ + /* PREFIX_0FC2 */ { - {"vmread", { Em, Gm } }, - {"(bad)", { XX } }, - {"extrq", { XS, Ib, Ib } }, - {"insertq", { XM, XS, Ib, Ib } }, + { "", { XM, EXx, OPSIMD } }, /* See OP_SIMD_SUFFIX. */ + { "", { XM, EXd, OPSIMD } }, + { "", { XM, EXx, OPSIMD } }, + { "", { XM, EXq, OPSIMD } }, }, - /* PREGRP35 */ + /* PREFIX_0FD0 */ { - {"vmwrite", { Gm, Em } }, - {"(bad)", { XX } }, - {"extrq", { XM, XS } }, - {"insertq", { XM, XS } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "addsubpd", { XM, EXx } }, + { "addsubps", { XM, EXx } }, }, - /* PREGRP36 */ + /* PREFIX_0FD6 */ { - { "bsrS", { Gv, Ev } }, - { "lzcntS", { Gv, Ev } }, - { "bsrS", { Gv, Ev } }, { "(bad)", { XX } }, + { "movq2dq",{ XM, MS } }, + { "movq", { EXq, XM } }, + { "movdq2q",{ MX, XS } }, }, - /* PREGRP37 */ + /* PREFIX_0FE6 */ { - { "(bad)", { XX } }, - { "popcntS", { Gv, Ev } }, - { "(bad)", { XX } }, - { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "cvtdq2pd", { XM, EXq } }, + { "cvttpd2dq", { XM, EXx } }, + { "cvtpd2dq", { XM, EXx } }, }, - /* PREGRP38 */ + /* PREFIX_0FE7 */ { - { "xchgS", { { NOP_Fixup1, eAX_reg }, { NOP_Fixup2, eAX_reg } } }, - { "pause", { XX } }, - { "xchgS", { { NOP_Fixup1, eAX_reg }, { NOP_Fixup2, eAX_reg } } }, - { "(bad)", { XX } }, + { "movntq", { EM, MX } }, + { "(bad)", { XX } }, + { "movntdq",{ EM, XM } }, + { "(bad)", { XX } }, + }, + + /* PREFIX_0FF0 */ + { + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { MOD_TABLE (MOD_0FF0_PREFIX_3) }, + }, + + /* PREFIX_0FF7 */ + { + { "maskmovq", { MX, MS } }, + { "(bad)", { XX } }, + { "maskmovdqu", { XM, XS } }, + { "(bad)", { XX } }, }, - /* PREGRP39 */ + /* PREFIX_0F3810 */ { { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -1956,7 +2113,7 @@ static const struct dis386 prefix_user_table[][4] = { { "(bad)", { XX } }, }, - /* PREGRP40 */ + /* PREFIX_0F3814 */ { { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -1964,7 +2121,7 @@ static const struct dis386 prefix_user_table[][4] = { { "(bad)", { XX } }, }, - /* PREGRP41 */ + /* PREFIX_0F3815 */ { { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -1972,7 +2129,7 @@ static const struct dis386 prefix_user_table[][4] = { { "(bad)", { XX } }, }, - /* PREGRP42 */ + /* PREFIX_0F3817 */ { { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -1980,7 +2137,7 @@ static const struct dis386 prefix_user_table[][4] = { { "(bad)", { XX } }, }, - /* PREGRP43 */ + /* PREFIX_0F3820 */ { { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -1988,7 +2145,7 @@ static const struct dis386 prefix_user_table[][4] = { { "(bad)", { XX } }, }, - /* PREGRP44 */ + /* PREFIX_0F3821 */ { { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -1996,7 +2153,7 @@ static const struct dis386 prefix_user_table[][4] = { { "(bad)", { XX } }, }, - /* PREGRP45 */ + /* PREFIX_0F3822 */ { { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -2004,7 +2161,7 @@ static const struct dis386 prefix_user_table[][4] = { { "(bad)", { XX } }, }, - /* PREGRP46 */ + /* PREFIX_0F3823 */ { { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -2012,7 +2169,7 @@ static const struct dis386 prefix_user_table[][4] = { { "(bad)", { XX } }, }, - /* PREGRP47 */ + /* PREFIX_0F3824 */ { { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -2020,7 +2177,7 @@ static const struct dis386 prefix_user_table[][4] = { { "(bad)", { XX } }, }, - /* PREGRP48 */ + /* PREFIX_0F3825 */ { { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -2028,7 +2185,7 @@ static const struct dis386 prefix_user_table[][4] = { { "(bad)", { XX } }, }, - /* PREGRP49 */ + /* PREFIX_0F3828 */ { { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -2036,7 +2193,7 @@ static const struct dis386 prefix_user_table[][4] = { { "(bad)", { XX } }, }, - /* PREGRP50 */ + /* PREFIX_0F3829 */ { { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -2044,7 +2201,7 @@ static const struct dis386 prefix_user_table[][4] = { { "(bad)", { XX } }, }, - /* PREGRP51 */ + /* PREFIX_0F382A */ { { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -2052,7 +2209,7 @@ static const struct dis386 prefix_user_table[][4] = { { "(bad)", { XX } }, }, - /* PREGRP52 */ + /* PREFIX_0F382B */ { { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -2060,7 +2217,7 @@ static const struct dis386 prefix_user_table[][4] = { { "(bad)", { XX } }, }, - /* PREGRP53 */ + /* PREFIX_0F3830 */ { { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -2068,7 +2225,7 @@ static const struct dis386 prefix_user_table[][4] = { { "(bad)", { XX } }, }, - /* PREGRP54 */ + /* PREFIX_0F3831 */ { { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -2076,7 +2233,7 @@ static const struct dis386 prefix_user_table[][4] = { { "(bad)", { XX } }, }, - /* PREGRP55 */ + /* PREFIX_0F3832 */ { { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -2084,7 +2241,7 @@ static const struct dis386 prefix_user_table[][4] = { { "(bad)", { XX } }, }, - /* PREGRP56 */ + /* PREFIX_0F3833 */ { { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -2092,7 +2249,7 @@ static const struct dis386 prefix_user_table[][4] = { { "(bad)", { XX } }, }, - /* PREGRP57 */ + /* PREFIX_0F3834 */ { { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -2100,7 +2257,7 @@ static const struct dis386 prefix_user_table[][4] = { { "(bad)", { XX } }, }, - /* PREGRP58 */ + /* PREFIX_0F3835 */ { { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -2108,7 +2265,15 @@ static const struct dis386 prefix_user_table[][4] = { { "(bad)", { XX } }, }, - /* PREGRP59 */ + /* PREFIX_0F3837 */ + { + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "pcmpgtq", { XM, EXx } }, + { "(bad)", { XX } }, + }, + + /* PREFIX_0F3838 */ { { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -2116,7 +2281,7 @@ static const struct dis386 prefix_user_table[][4] = { { "(bad)", { XX } }, }, - /* PREGRP60 */ + /* PREFIX_0F3839 */ { { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -2124,7 +2289,7 @@ static const struct dis386 prefix_user_table[][4] = { { "(bad)", { XX } }, }, - /* PREGRP61 */ + /* PREFIX_0F383A */ { { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -2132,7 +2297,7 @@ static const struct dis386 prefix_user_table[][4] = { { "(bad)", { XX } }, }, - /* PREGRP62 */ + /* PREFIX_0F383B */ { { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -2140,7 +2305,7 @@ static const struct dis386 prefix_user_table[][4] = { { "(bad)", { XX } }, }, - /* PREGRP63 */ + /* PREFIX_0F383C */ { { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -2148,7 +2313,7 @@ static const struct dis386 prefix_user_table[][4] = { { "(bad)", { XX } }, }, - /* PREGRP64 */ + /* PREFIX_0F383D */ { { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -2156,7 +2321,7 @@ static const struct dis386 prefix_user_table[][4] = { { "(bad)", { XX } }, }, - /* PREGRP65 */ + /* PREFIX_0F383E */ { { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -2164,7 +2329,7 @@ static const struct dis386 prefix_user_table[][4] = { { "(bad)", { XX } }, }, - /* PREGRP66 */ + /* PREFIX_0F383F */ { { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -2172,7 +2337,7 @@ static const struct dis386 prefix_user_table[][4] = { { "(bad)", { XX } }, }, - /* PREGRP67 */ + /* PREFIX_0F3840 */ { { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -2180,7 +2345,7 @@ static const struct dis386 prefix_user_table[][4] = { { "(bad)", { XX } }, }, - /* PREGRP68 */ + /* PREFIX_0F3841 */ { { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -2188,7 +2353,23 @@ static const struct dis386 prefix_user_table[][4] = { { "(bad)", { XX } }, }, - /* PREGRP69 */ + /* PREFIX_0F38F0 */ + { + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "crc32", { Gdq, { CRC32_Fixup, b_mode } } }, + }, + + /* PREFIX_0F38F1 */ + { + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "crc32", { Gdq, { CRC32_Fixup, v_mode } } }, + }, + + /* PREFIX_0F3A08 */ { { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -2196,7 +2377,7 @@ static const struct dis386 prefix_user_table[][4] = { { "(bad)", { XX } }, }, - /* PREGRP70 */ + /* PREFIX_0F3A09 */ { { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -2204,7 +2385,7 @@ static const struct dis386 prefix_user_table[][4] = { { "(bad)", { XX } }, }, - /* PREGRP71 */ + /* PREFIX_0F3A0A */ { { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -2212,7 +2393,7 @@ static const struct dis386 prefix_user_table[][4] = { { "(bad)", { XX } }, }, - /* PREGRP72 */ + /* PREFIX_0F3A0B */ { { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -2220,7 +2401,7 @@ static const struct dis386 prefix_user_table[][4] = { { "(bad)", { XX } }, }, - /* PREGRP73 */ + /* PREFIX_0F3A0C */ { { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -2228,7 +2409,7 @@ static const struct dis386 prefix_user_table[][4] = { { "(bad)", { XX } }, }, - /* PREGRP74 */ + /* PREFIX_0F3A0D */ { { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -2236,7 +2417,7 @@ static const struct dis386 prefix_user_table[][4] = { { "(bad)", { XX } }, }, - /* PREGRP75 */ + /* PREFIX_0F3A0E */ { { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -2244,7 +2425,7 @@ static const struct dis386 prefix_user_table[][4] = { { "(bad)", { XX } }, }, - /* PREGRP76 */ + /* PREFIX_0F3A14 */ { { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -2252,7 +2433,7 @@ static const struct dis386 prefix_user_table[][4] = { { "(bad)", { XX } }, }, - /* PREGRP77 */ + /* PREFIX_0F3A15 */ { { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -2260,7 +2441,7 @@ static const struct dis386 prefix_user_table[][4] = { { "(bad)", { XX } }, }, - /* PREGRP78 */ + /* PREFIX_0F3A16 */ { { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -2268,7 +2449,7 @@ static const struct dis386 prefix_user_table[][4] = { { "(bad)", { XX } }, }, - /* PREGRP79 */ + /* PREFIX_0F3A17 */ { { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -2276,7 +2457,7 @@ static const struct dis386 prefix_user_table[][4] = { { "(bad)", { XX } }, }, - /* PREGRP80 */ + /* PREFIX_0F3A20 */ { { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -2284,7 +2465,7 @@ static const struct dis386 prefix_user_table[][4] = { { "(bad)", { XX } }, }, - /* PREGRP81 */ + /* PREFIX_0F3A21 */ { { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -2292,7 +2473,7 @@ static const struct dis386 prefix_user_table[][4] = { { "(bad)", { XX } }, }, - /* PREGRP82 */ + /* PREFIX_0F3A22 */ { { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -2300,7 +2481,7 @@ static const struct dis386 prefix_user_table[][4] = { { "(bad)", { XX } }, }, - /* PREGRP83 */ + /* PREFIX_0F3A40 */ { { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -2308,7 +2489,7 @@ static const struct dis386 prefix_user_table[][4] = { { "(bad)", { XX } }, }, - /* PREGRP84 */ + /* PREFIX_0F3A41 */ { { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -2316,7 +2497,7 @@ static const struct dis386 prefix_user_table[][4] = { { "(bad)", { XX } }, }, - /* PREGRP85 */ + /* PREFIX_0F3A42 */ { { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -2324,231 +2505,1464 @@ static const struct dis386 prefix_user_table[][4] = { { "(bad)", { XX } }, }, - /* PREGRP86 */ + /* PREFIX_0F3A60 */ { { "(bad)", { XX } }, { "(bad)", { XX } }, - { "pcmpgtq", { XM, EXx } }, + { "pcmpestrm", { XM, EXx, Ib } }, { "(bad)", { XX } }, }, - /* PREGRP87 */ + /* PREFIX_0F3A61 */ { { "(bad)", { XX } }, { "(bad)", { XX } }, + { "pcmpestri", { XM, EXx, Ib } }, { "(bad)", { XX } }, - { "crc32", { Gdq, { CRC32_Fixup, b_mode } } }, }, - /* PREGRP88 */ + /* PREFIX_0F3A62 */ { { "(bad)", { XX } }, { "(bad)", { XX } }, + { "pcmpistrm", { XM, EXx, Ib } }, { "(bad)", { XX } }, - { "crc32", { Gdq, { CRC32_Fixup, v_mode } } }, }, - /* PREGRP89 */ + /* PREFIX_0F3A63 */ { { "(bad)", { XX } }, { "(bad)", { XX } }, - { "pcmpestrm", { XM, EXx, Ib } }, + { "pcmpistri", { XM, EXx, Ib } }, { "(bad)", { XX } }, }, - /* PREGRP90 */ + /* PREFIX_0F73_REG_3 */ { { "(bad)", { XX } }, { "(bad)", { XX } }, - { "pcmpestri", { XM, EXx, Ib } }, + { "psrldq", { MS, Ib } }, { "(bad)", { XX } }, }, - /* PREGRP91 */ + /* PREFIX_0F73_REG_7 */ { { "(bad)", { XX } }, { "(bad)", { XX } }, - { "pcmpistrm", { XM, EXx, Ib } }, + { "pslldq", { MS, Ib } }, { "(bad)", { XX } }, }, - /* PREGRP92 */ + /* PREFIX_0FC7_REG_6 */ { - { "(bad)", { XX } }, - { "(bad)", { XX } }, - { "pcmpistri", { XM, EXx, Ib } }, + { "vmptrld",{ Mq } }, + { "vmxon", { Mq } }, + { "vmclear",{ Mq } }, { "(bad)", { XX } }, }, +}; - /* PREGRP93 */ +static const struct dis386 x86_64_table[][2] = { + /* X86_64_06 */ { - { "ucomiss",{ XM, EXd } }, - { "(bad)", { XX } }, - { "ucomisd",{ XM, EXq } }, - { "(bad)", { XX } }, + { "push{T|}", { es } }, + { "(bad)", { XX } }, }, - /* PREGRP94 */ + /* X86_64_07 */ { - { "comiss", { XM, EXd } }, - { "(bad)", { XX } }, - { "comisd", { XM, EXq } }, - { "(bad)", { XX } }, + { "pop{T|}", { es } }, + { "(bad)", { XX } }, }, - /* PREGRP95 */ + /* X86_64_0D */ { - { "punpcklbw",{ MX, EMd } }, - { "(bad)", { XX } }, - { "punpcklbw",{ MX, EMx } }, - { "(bad)", { XX } }, + { "push{T|}", { cs } }, + { "(bad)", { XX } }, }, - /* PREGRP96 */ + /* X86_64_16 */ { - { "punpcklwd",{ MX, EMd } }, - { "(bad)", { XX } }, - { "punpcklwd",{ MX, EMx } }, - { "(bad)", { XX } }, + { "push{T|}", { ss } }, + { "(bad)", { XX } }, }, - /* PREGRP97 */ + /* X86_64_17 */ { - { "punpckldq",{ MX, EMd } }, - { "(bad)", { XX } }, - { "punpckldq",{ MX, EMx } }, - { "(bad)", { XX } }, + { "pop{T|}", { ss } }, + { "(bad)", { XX } }, }, - /* PREGRP98 */ + /* X86_64_1E */ { - { "vmptrld",{ Mq } }, - { "vmxon", { Mq } }, - { "vmclear",{ Mq } }, - { "(bad)", { XX } }, + { "push{T|}", { ds } }, + { "(bad)", { XX } }, }, - /* PREGRP99 */ + /* X86_64_1F */ { - { "(bad)", { XX } }, - { "(bad)", { XX } }, - { "psrldq", { MS, Ib } }, - { "(bad)", { XX } }, + { "pop{T|}", { ds } }, + { "(bad)", { XX } }, }, - /* PREGRP100 */ + /* X86_64_27 */ { - { "(bad)", { XX } }, - { "(bad)", { XX } }, - { "pslldq", { MS, Ib } }, - { "(bad)", { XX } }, + { "daa", { XX } }, + { "(bad)", { XX } }, }, -}; -static const struct dis386 x86_64_table[][2] = { + /* X86_64_2F */ + { + { "das", { XX } }, + { "(bad)", { XX } }, + }, + + /* X86_64_37 */ + { + { "aaa", { XX } }, + { "(bad)", { XX } }, + }, + + /* X86_64_3F */ + { + { "aas", { XX } }, + { "(bad)", { XX } }, + }, + + /* X86_64_60 */ { { "pusha{P|}", { XX } }, { "(bad)", { XX } }, - }, - { - { "popa{P|}", { XX } }, + }, + + /* X86_64_61 */ + { + { "popa{P|}", { XX } }, + { "(bad)", { XX } }, + }, + + /* X86_64_62 */ + { + { MOD_TABLE (MOD_62_32BIT) }, + { "(bad)", { XX } }, + }, + + /* X86_64_63 */ + { + { "arpl", { Ew, Gw } }, + { "movs{lq|xd}", { Gv, Ed } }, + }, + + /* X86_64_6D */ + { + { "ins{R|}", { Yzr, indirDX } }, + { "ins{G|}", { Yzr, indirDX } }, + }, + + /* X86_64_6F */ + { + { "outs{R|}", { indirDXr, Xz } }, + { "outs{G|}", { indirDXr, Xz } }, + }, + + /* X86_64_9A */ + { + { "Jcall{T|}", { Ap } }, + { "(bad)", { XX } }, + }, + + /* X86_64_C4 */ + { + { MOD_TABLE (MOD_C4_32BIT) }, + { "(bad)", { XX } }, + }, + + /* X86_64_C5 */ + { + { MOD_TABLE (MOD_C5_32BIT) }, + { "(bad)", { XX } }, + }, + + /* X86_64_CE */ + { + { "into", { XX } }, + { "(bad)", { XX } }, + }, + + /* X86_64_D4 */ + { + { "aam", { sIb } }, + { "(bad)", { XX } }, + }, + + /* X86_64_D5 */ + { + { "aad", { sIb } }, + { "(bad)", { XX } }, + }, + + /* X86_64_EA */ + { + { "Jjmp{T|}", { Ap } }, + { "(bad)", { XX } }, + }, + + /* X86_64_0F01_REG_0 */ + { + { "sgdt{Q|IQ}", { M } }, + { "sgdt", { M } }, + }, + + /* X86_64_0F01_REG_1 */ + { + { "sidt{Q|IQ}", { M } }, + { "sidt", { M } }, + }, + + /* X86_64_0F01_REG_2 */ + { + { "lgdt{Q|Q}", { M } }, + { "lgdt", { M } }, + }, + + /* X86_64_0F01_REG_3 */ + { + { "lidt{Q|Q}", { M } }, + { "lidt", { M } }, + }, +}; + +static const struct dis386 three_byte_table[][256] = { + /* THREE_BYTE_0F24 */ + { + /* 00 */ + { "fmaddps", { { OP_DREX4, q_mode } } }, + { "fmaddpd", { { OP_DREX4, q_mode } } }, + { "fmaddss", { { OP_DREX4, w_mode } } }, + { "fmaddsd", { { OP_DREX4, d_mode } } }, + { "fmaddps", { { OP_DREX4, DREX_OC1 + q_mode } } }, + { "fmaddpd", { { OP_DREX4, DREX_OC1 + q_mode } } }, + { "fmaddss", { { OP_DREX4, DREX_OC1 + w_mode } } }, + { "fmaddsd", { { OP_DREX4, DREX_OC1 + d_mode } } }, + /* 08 */ + { "fmsubps", { { OP_DREX4, q_mode } } }, + { "fmsubpd", { { OP_DREX4, q_mode } } }, + { "fmsubss", { { OP_DREX4, w_mode } } }, + { "fmsubsd", { { OP_DREX4, d_mode } } }, + { "fmsubps", { { OP_DREX4, DREX_OC1 + q_mode } } }, + { "fmsubpd", { { OP_DREX4, DREX_OC1 + q_mode } } }, + { "fmsubss", { { OP_DREX4, DREX_OC1 + w_mode } } }, + { "fmsubsd", { { OP_DREX4, DREX_OC1 + d_mode } } }, + /* 10 */ + { "fnmaddps", { { OP_DREX4, q_mode } } }, + { "fnmaddpd", { { OP_DREX4, q_mode } } }, + { "fnmaddss", { { OP_DREX4, w_mode } } }, + { "fnmaddsd", { { OP_DREX4, d_mode } } }, + { "fnmaddps", { { OP_DREX4, DREX_OC1 + q_mode } } }, + { "fnmaddpd", { { OP_DREX4, DREX_OC1 + q_mode } } }, + { "fnmaddss", { { OP_DREX4, DREX_OC1 + w_mode } } }, + { "fnmaddsd", { { OP_DREX4, DREX_OC1 + d_mode } } }, + /* 18 */ + { "fnmsubps", { { OP_DREX4, q_mode } } }, + { "fnmsubpd", { { OP_DREX4, q_mode } } }, + { "fnmsubss", { { OP_DREX4, w_mode } } }, + { "fnmsubsd", { { OP_DREX4, d_mode } } }, + { "fnmsubps", { { OP_DREX4, DREX_OC1 + q_mode } } }, + { "fnmsubpd", { { OP_DREX4, DREX_OC1 + q_mode } } }, + { "fnmsubss", { { OP_DREX4, DREX_OC1 + w_mode } } }, + { "fnmsubsd", { { OP_DREX4, DREX_OC1 + d_mode } } }, + /* 20 */ + { "permps", { { OP_DREX4, q_mode } } }, + { "permpd", { { OP_DREX4, q_mode } } }, + { "pcmov", { { OP_DREX4, q_mode } } }, + { "pperm", { { OP_DREX4, q_mode } } }, + { "permps", { { OP_DREX4, DREX_OC1 + q_mode } } }, + { "permpd", { { OP_DREX4, DREX_OC1 + q_mode } } }, + { "pcmov", { { OP_DREX4, DREX_OC1 + w_mode } } }, + { "pperm", { { OP_DREX4, DREX_OC1 + d_mode } } }, + /* 28 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 30 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 38 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 40 */ + { "protb", { { OP_DREX3, q_mode } } }, + { "protw", { { OP_DREX3, q_mode } } }, + { "protd", { { OP_DREX3, q_mode } } }, + { "protq", { { OP_DREX3, q_mode } } }, + { "pshlb", { { OP_DREX3, q_mode } } }, + { "pshlw", { { OP_DREX3, q_mode } } }, + { "pshld", { { OP_DREX3, q_mode } } }, + { "pshlq", { { OP_DREX3, q_mode } } }, + /* 48 */ + { "pshab", { { OP_DREX3, q_mode } } }, + { "pshaw", { { OP_DREX3, q_mode } } }, + { "pshad", { { OP_DREX3, q_mode } } }, + { "pshaq", { { OP_DREX3, q_mode } } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 50 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 58 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 60 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 68 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 70 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 78 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 80 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "pmacssww", { { OP_DREX4, DREX_OC1 + DREX_NO_OC0 + q_mode } } }, + { "pmacsswd", { { OP_DREX4, DREX_OC1 + DREX_NO_OC0 + q_mode } } }, + { "pmacssdql", { { OP_DREX4, DREX_OC1 + DREX_NO_OC0 + q_mode } } }, + /* 88 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "pmacssdd", { { OP_DREX4, DREX_OC1 + DREX_NO_OC0 + q_mode } } }, + { "pmacssdqh", { { OP_DREX4, DREX_OC1 + DREX_NO_OC0 + q_mode } } }, + /* 90 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "pmacsww", { { OP_DREX4, DREX_OC1 + DREX_NO_OC0 + q_mode } } }, + { "pmacswd", { { OP_DREX4, DREX_OC1 + DREX_NO_OC0 + q_mode } } }, + { "pmacsdql", { { OP_DREX4, DREX_OC1 + DREX_NO_OC0 + q_mode } } }, + /* 98 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "pmacsdd", { { OP_DREX4, DREX_OC1 + DREX_NO_OC0 + q_mode } } }, + { "pmacsdqh", { { OP_DREX4, DREX_OC1 + DREX_NO_OC0 + q_mode } } }, + /* a0 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "pmadcsswd", { { OP_DREX4, DREX_OC1 + DREX_NO_OC0 + q_mode } } }, + { "(bad)", { XX } }, + /* a8 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* b0 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "pmadcswd", { { OP_DREX4, DREX_OC1 + DREX_NO_OC0 + q_mode } } }, + { "(bad)", { XX } }, + /* b8 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* c0 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* c8 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* d0 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* d8 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* e0 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* e8 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* f0 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* f8 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + }, + /* THREE_BYTE_0F25 */ + { + /* 00 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 08 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 10 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 18 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 20 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 28 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "comps", { { OP_DREX3, q_mode }, { OP_DREX_FCMP, b_mode } } }, + { "compd", { { OP_DREX3, q_mode }, { OP_DREX_FCMP, b_mode } } }, + { "comss", { { OP_DREX3, w_mode }, { OP_DREX_FCMP, b_mode } } }, + { "comsd", { { OP_DREX3, d_mode }, { OP_DREX_FCMP, b_mode } } }, + /* 30 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 38 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 40 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 48 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "pcomb", { { OP_DREX3, q_mode }, { OP_DREX_ICMP, b_mode } } }, + { "pcomw", { { OP_DREX3, q_mode }, { OP_DREX_ICMP, b_mode } } }, + { "pcomd", { { OP_DREX3, q_mode }, { OP_DREX_ICMP, b_mode } } }, + { "pcomq", { { OP_DREX3, q_mode }, { OP_DREX_ICMP, b_mode } } }, + /* 50 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 58 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 60 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 68 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "pcomub", { { OP_DREX3, q_mode }, { OP_DREX_ICMP, b_mode } } }, + { "pcomuw", { { OP_DREX3, q_mode }, { OP_DREX_ICMP, b_mode } } }, + { "pcomud", { { OP_DREX3, q_mode }, { OP_DREX_ICMP, b_mode } } }, + { "pcomuq", { { OP_DREX3, q_mode }, { OP_DREX_ICMP, b_mode } } }, + /* 70 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 78 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 80 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 88 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 90 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 98 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* a0 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* a8 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* b0 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* b8 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* c0 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* c8 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* d0 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* d8 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* e0 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* e8 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* f0 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* f8 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + }, + /* THREE_BYTE_0F38 */ + { + /* 00 */ + { "pshufb", { MX, EM } }, + { "phaddw", { MX, EM } }, + { "phaddd", { MX, EM } }, + { "phaddsw", { MX, EM } }, + { "pmaddubsw", { MX, EM } }, + { "phsubw", { MX, EM } }, + { "phsubd", { MX, EM } }, + { "phsubsw", { MX, EM } }, + /* 08 */ + { "psignb", { MX, EM } }, + { "psignw", { MX, EM } }, + { "psignd", { MX, EM } }, + { "pmulhrsw", { MX, EM } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 10 */ + { PREFIX_TABLE (PREFIX_0F3810) }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { PREFIX_TABLE (PREFIX_0F3814) }, + { PREFIX_TABLE (PREFIX_0F3815) }, + { "(bad)", { XX } }, + { PREFIX_TABLE (PREFIX_0F3817) }, + /* 18 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "pabsb", { MX, EM } }, + { "pabsw", { MX, EM } }, + { "pabsd", { MX, EM } }, + { "(bad)", { XX } }, + /* 20 */ + { PREFIX_TABLE (PREFIX_0F3820) }, + { PREFIX_TABLE (PREFIX_0F3821) }, + { PREFIX_TABLE (PREFIX_0F3822) }, + { PREFIX_TABLE (PREFIX_0F3823) }, + { PREFIX_TABLE (PREFIX_0F3824) }, + { PREFIX_TABLE (PREFIX_0F3825) }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 28 */ + { PREFIX_TABLE (PREFIX_0F3828) }, + { PREFIX_TABLE (PREFIX_0F3829) }, + { PREFIX_TABLE (PREFIX_0F382A) }, + { PREFIX_TABLE (PREFIX_0F382B) }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 30 */ + { PREFIX_TABLE (PREFIX_0F3830) }, + { PREFIX_TABLE (PREFIX_0F3831) }, + { PREFIX_TABLE (PREFIX_0F3832) }, + { PREFIX_TABLE (PREFIX_0F3833) }, + { PREFIX_TABLE (PREFIX_0F3834) }, + { PREFIX_TABLE (PREFIX_0F3835) }, + { "(bad)", { XX } }, + { PREFIX_TABLE (PREFIX_0F3837) }, + /* 38 */ + { PREFIX_TABLE (PREFIX_0F3838) }, + { PREFIX_TABLE (PREFIX_0F3839) }, + { PREFIX_TABLE (PREFIX_0F383A) }, + { PREFIX_TABLE (PREFIX_0F383B) }, + { PREFIX_TABLE (PREFIX_0F383C) }, + { PREFIX_TABLE (PREFIX_0F383D) }, + { PREFIX_TABLE (PREFIX_0F383E) }, + { PREFIX_TABLE (PREFIX_0F383F) }, + /* 40 */ + { PREFIX_TABLE (PREFIX_0F3840) }, + { PREFIX_TABLE (PREFIX_0F3841) }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 48 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 50 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 58 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 60 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 68 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 70 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 78 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 80 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 88 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 90 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 98 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* a0 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* a8 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* b0 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* b8 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* c0 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* c8 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* d0 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* d8 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* e0 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* e8 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* f0 */ + { PREFIX_TABLE (PREFIX_0F38F0) }, + { PREFIX_TABLE (PREFIX_0F38F1) }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* f8 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + }, + /* THREE_BYTE_0F3A */ + { + /* 00 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 08 */ + { PREFIX_TABLE (PREFIX_0F3A08) }, + { PREFIX_TABLE (PREFIX_0F3A09) }, + { PREFIX_TABLE (PREFIX_0F3A0A) }, + { PREFIX_TABLE (PREFIX_0F3A0B) }, + { PREFIX_TABLE (PREFIX_0F3A0C) }, + { PREFIX_TABLE (PREFIX_0F3A0D) }, + { PREFIX_TABLE (PREFIX_0F3A0E) }, + { "palignr", { MX, EM, Ib } }, + /* 10 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { PREFIX_TABLE (PREFIX_0F3A14) }, + { PREFIX_TABLE (PREFIX_0F3A15) }, + { PREFIX_TABLE (PREFIX_0F3A16) }, + { PREFIX_TABLE (PREFIX_0F3A17) }, + /* 18 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 20 */ + { PREFIX_TABLE (PREFIX_0F3A20) }, + { PREFIX_TABLE (PREFIX_0F3A21) }, + { PREFIX_TABLE (PREFIX_0F3A22) }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 28 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 30 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 38 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 40 */ + { PREFIX_TABLE (PREFIX_0F3A40) }, + { PREFIX_TABLE (PREFIX_0F3A41) }, + { PREFIX_TABLE (PREFIX_0F3A42) }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 48 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 50 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 58 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 60 */ + { PREFIX_TABLE (PREFIX_0F3A60) }, + { PREFIX_TABLE (PREFIX_0F3A61) }, + { PREFIX_TABLE (PREFIX_0F3A62) }, + { PREFIX_TABLE (PREFIX_0F3A63) }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 68 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 70 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 78 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 80 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 88 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 90 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 98 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* a0 */ + { "(bad)", { XX } }, { "(bad)", { XX } }, - }, - { - { "bound{S|}", { Gv, Ma } }, { "(bad)", { XX } }, - }, - { - { "arpl", { Ew, Gw } }, - { "movs{||lq|xd}", { Gv, Ed } }, - }, -}; - -static const struct dis386 three_byte_table[][256] = { - /* THREE_BYTE_0 */ - { - /* 00 */ - { "pshufb", { MX, EM } }, - { "phaddw", { MX, EM } }, - { "phaddd", { MX, EM } }, - { "phaddsw", { MX, EM } }, - { "pmaddubsw", { MX, EM } }, - { "phsubw", { MX, EM } }, - { "phsubd", { MX, EM } }, - { "phsubsw", { MX, EM } }, - /* 08 */ - { "psignb", { MX, EM } }, - { "psignw", { MX, EM } }, - { "psignd", { MX, EM } }, - { "pmulhrsw", { MX, EM } }, { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, - /* 10 */ - { PREGRP39 }, { "(bad)", { XX } }, + /* a8 */ { "(bad)", { XX } }, { "(bad)", { XX } }, - { PREGRP40 }, - { PREGRP41 }, { "(bad)", { XX } }, - { PREGRP42 }, - /* 18 */ { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, - { "pabsb", { MX, EM } }, - { "pabsw", { MX, EM } }, - { "pabsd", { MX, EM } }, { "(bad)", { XX } }, - /* 20 */ - { PREGRP43 }, - { PREGRP44 }, - { PREGRP45 }, - { PREGRP46 }, - { PREGRP47 }, - { PREGRP48 }, + /* b0 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* b8 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* c0 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* c8 */ + { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* d0 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* d8 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* e0 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* e8 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* f0 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* f8 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + }, + /* THREE_BYTE_0F7A */ + { + /* 00 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 08 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 10 */ + { "frczps", { XM, EXq } }, + { "frczpd", { XM, EXq } }, + { "frczss", { XM, EXq } }, + { "frczsd", { XM, EXq } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 18 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 20 */ + { "ptest", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, /* 28 */ - { PREGRP49 }, - { PREGRP50 }, - { PREGRP51 }, - { PREGRP52 }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, /* 30 */ - { PREGRP53 }, - { PREGRP54 }, - { PREGRP55 }, - { PREGRP56 }, - { PREGRP57 }, - { PREGRP58 }, - { "(bad)", { XX } }, - { PREGRP86 }, - /* 38 */ - { PREGRP59 }, - { PREGRP60 }, - { PREGRP61 }, - { PREGRP62 }, - { PREGRP63 }, - { PREGRP64 }, - { PREGRP65 }, - { PREGRP66 }, - /* 40 */ - { PREGRP67 }, - { PREGRP68 }, + { "cvtph2ps", { XM, EXd } }, + { "cvtps2ph", { EXd, XM } }, { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, - /* 48 */ + /* 38 */ { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -2557,29 +3971,47 @@ static const struct dis386 three_byte_table[][256] = { { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, - /* 50 */ + /* 40 */ + { "(bad)", { XX } }, + { "phaddbw", { XM, EXq } }, + { "phaddbd", { XM, EXq } }, + { "phaddbq", { XM, EXq } }, { "(bad)", { XX } }, { "(bad)", { XX } }, + { "phaddwd", { XM, EXq } }, + { "phaddwq", { XM, EXq } }, + /* 48 */ { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, + { "phadddq", { XM, EXq } }, { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, - /* 58 */ { "(bad)", { XX } }, + /* 50 */ { "(bad)", { XX } }, + { "phaddubw", { XM, EXq } }, + { "phaddubd", { XM, EXq } }, + { "phaddubq", { XM, EXq } }, { "(bad)", { XX } }, { "(bad)", { XX } }, + { "phadduwd", { XM, EXq } }, + { "phadduwq", { XM, EXq } }, + /* 58 */ { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, + { "phaddudq", { XM, EXq } }, { "(bad)", { XX } }, - /* 60 */ { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, + /* 60 */ { "(bad)", { XX } }, + { "phsubbw", { XM, EXq } }, + { "phsubbd", { XM, EXq } }, + { "phsubbq", { XM, EXq } }, { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -2738,8 +4170,8 @@ static const struct dis386 three_byte_table[][256] = { { "(bad)", { XX } }, { "(bad)", { XX } }, /* f0 */ - { PREGRP87 }, - { PREGRP88 }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -2756,7 +4188,7 @@ static const struct dis386 three_byte_table[][256] = { { "(bad)", { XX } }, { "(bad)", { XX } }, }, - /* THREE_BYTE_1 */ + /* THREE_BYTE_0F7B */ { /* 00 */ { "(bad)", { XX } }, @@ -2768,42 +4200,25 @@ static const struct dis386 three_byte_table[][256] = { { "(bad)", { XX } }, { "(bad)", { XX } }, /* 08 */ - { PREGRP69 }, - { PREGRP70 }, - { PREGRP71 }, - { PREGRP72 }, - { PREGRP73 }, - { PREGRP74 }, - { PREGRP75 }, - { "palignr", { MX, EM, Ib } }, - /* 10 */ { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, - { PREGRP76 }, - { PREGRP77 }, - { PREGRP78 }, - { PREGRP79 }, - /* 18 */ { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, + /* 10 */ { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, - /* 20 */ - { PREGRP80 }, - { PREGRP81 }, - { PREGRP82 }, { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, + /* 18 */ { "(bad)", { XX } }, - /* 28 */ { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -2811,8 +4226,8 @@ static const struct dis386 three_byte_table[][256] = { { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, + /* 20 */ { "(bad)", { XX } }, - /* 30 */ { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -2820,8 +4235,8 @@ static const struct dis386 three_byte_table[][256] = { { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, + /* 28 */ { "(bad)", { XX } }, - /* 38 */ { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -2829,22 +4244,39 @@ static const struct dis386 three_byte_table[][256] = { { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, + /* 30 */ { "(bad)", { XX } }, - /* 40 */ - { PREGRP83 }, - { PREGRP84 }, - { PREGRP85 }, { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, - /* 48 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 38 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, + /* 40 */ + { "protb", { XM, EXq, Ib } }, + { "protw", { XM, EXq, Ib } }, + { "protd", { XM, EXq, Ib } }, + { "protq", { XM, EXq, Ib } }, + { "pshlb", { XM, EXq, Ib } }, + { "pshlw", { XM, EXq, Ib } }, + { "pshld", { XM, EXq, Ib } }, + { "pshlq", { XM, EXq, Ib } }, + /* 48 */ + { "pshab", { XM, EXq, Ib } }, + { "pshaw", { XM, EXq, Ib } }, + { "pshad", { XM, EXq, Ib } }, + { "pshaq", { XM, EXq, Ib } }, + { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -2867,10 +4299,10 @@ static const struct dis386 three_byte_table[][256] = { { "(bad)", { XX } }, { "(bad)", { XX } }, /* 60 */ - { PREGRP89 }, - { PREGRP90 }, - { PREGRP91 }, - { PREGRP92 }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -3049,137 +4481,242 @@ static const struct dis386 three_byte_table[][256] = { } }; -static const struct dis386 opc_ext_table[][2] = { +static const struct dis386 mod_table[][2] = { + { + /* MOD_8D */ + { "leaS", { Gv, M } }, + { "(bad)", { XX } }, + }, + { + /* MOD_0F13 */ + { "movlpX", { EXq, XM } }, + { "(bad)", { XX } }, + }, + { + /* MOD_0F17 */ + { "movhpX", { EXq, XM } }, + { "(bad)", { XX } }, + }, + { + /* MOD_0F20 */ + { "(bad)", { XX } }, + { "movZ", { Rm, Cm } }, + }, + { + /* MOD_0F21 */ + { "(bad)", { XX } }, + { "movZ", { Rm, Dm } }, + }, + { + /* MOD_0F22 */ + { "(bad)", { XX } }, + { "movZ", { Cm, Rm } }, + }, + { + /* MOD_0F23 */ + { "(bad)", { XX } }, + { "movZ", { Dm, Rm } }, + }, + { + /* MOD_0F24 */ + { THREE_BYTE_TABLE (THREE_BYTE_0F24) }, + { "movL", { Rd, Td } }, + }, + { + /* MOD_0F26 */ + { "(bad)", { XX } }, + { "movL", { Td, Rd } }, + }, + { + /* MOD_0FB2 */ + { "lssS", { Gv, Mp } }, + { "(bad)", { XX } }, + }, + { + /* MOD_0FB4 */ + { "lfsS", { Gv, Mp } }, + { "(bad)", { XX } }, + }, + { + /* MOD_0FB5 */ + { "lgsS", { Gv, Mp } }, + { "(bad)", { XX } }, + }, + { + /* MOD_0F01_REG_0 */ + { X86_64_TABLE (X86_64_0F01_REG_0) }, + { RM_TABLE (RM_0F01_REG_0) }, + }, + { + /* MOD_0F01_REG_1 */ + { X86_64_TABLE (X86_64_0F01_REG_1) }, + { RM_TABLE (RM_0F01_REG_1) }, + }, + { + /* MOD_0F01_REG_2 */ + { X86_64_TABLE (X86_64_0F01_REG_2) }, + { "(bad)", { XX } }, + }, + { + /* MOD_0F01_REG_3 */ + { X86_64_TABLE (X86_64_0F01_REG_3) }, + { RM_TABLE (RM_0F01_REG_3) }, + }, + { + /* MOD_0F01_REG_7 */ + { "invlpg", { Mb } }, + { RM_TABLE (RM_0F01_REG_7) }, + }, { - /* OPC_EXT_0 */ - { "sgdt{Q|IQ||}", { M } }, - { OPC_EXT_RM_0 }, + /* MOD_0F18_REG_0 */ + { "prefetchnta", { Mb } }, + { "(bad)", { XX } }, }, { - /* OPC_EXT_1 */ - { "sidt{Q|IQ||}", { M } }, - { OPC_EXT_RM_1 }, + /* MOD_0F18_REG_1 */ + { "prefetcht0", { Mb } }, + { "(bad)", { XX } }, }, { - /* OPC_EXT_2 */ - { PREGRP98 }, + /* MOD_0F18_REG_2 */ + { "prefetcht1", { Mb } }, { "(bad)", { XX } }, }, { - /* OPC_EXT_3 */ - { "vmptrst", { Mq } }, + /* MOD_0F18_REG_3 */ + { "prefetcht2", { Mb } }, { "(bad)", { XX } }, }, { - /* OPC_EXT_4 */ + /* MOD_0F71_REG_2 */ { "(bad)", { XX } }, { "psrlw", { MS, Ib } }, }, { - /* OPC_EXT_5 */ + /* MOD_0F71_REG_4 */ { "(bad)", { XX } }, { "psraw", { MS, Ib } }, }, { - /* OPC_EXT_6 */ + /* MOD_0F71_REG_6 */ { "(bad)", { XX } }, { "psllw", { MS, Ib } }, }, { - /* OPC_EXT_7 */ + /* MOD_0F72_REG_2 */ { "(bad)", { XX } }, { "psrld", { MS, Ib } }, }, { - /* OPC_EXT_8 */ + /* MOD_0F72_REG_4 */ { "(bad)", { XX } }, { "psrad", { MS, Ib } }, }, { - /* OPC_EXT_9 */ + /* MOD_0F72_REG_6 */ { "(bad)", { XX } }, { "pslld", { MS, Ib } }, }, { - /* OPC_EXT_10 */ + /* MOD_0F73_REG_2 */ { "(bad)", { XX } }, { "psrlq", { MS, Ib } }, }, { - /* OPC_EXT_11 */ + /* MOD_0F73_REG_3 */ { "(bad)", { XX } }, - { PREGRP99 }, + { PREFIX_TABLE (PREFIX_0F73_REG_3) }, }, { - /* OPC_EXT_12 */ + /* MOD_0F73_REG_6 */ { "(bad)", { XX } }, { "psllq", { MS, Ib } }, }, { - /* OPC_EXT_13 */ + /* MOD_0F73_REG_7 */ { "(bad)", { XX } }, - { PREGRP100 }, + { PREFIX_TABLE (PREFIX_0F73_REG_7) }, }, { - /* OPC_EXT_14 */ + /* MOD_0FAE_REG_0 */ { "fxsave", { M } }, { "(bad)", { XX } }, }, { - /* OPC_EXT_15 */ + /* MOD_0FAE_REG_1 */ { "fxrstor", { M } }, { "(bad)", { XX } }, }, { - /* OPC_EXT_16 */ + /* MOD_0FAE_REG_2 */ { "ldmxcsr", { Md } }, { "(bad)", { XX } }, }, { - /* OPC_EXT_17 */ + /* MOD_0FAE_REG_3 */ { "stmxcsr", { Md } }, { "(bad)", { XX } }, }, { - /* OPC_EXT_18 */ + /* MOD_0FAE_REG_5 */ { "(bad)", { XX } }, - { OPC_EXT_RM_2 }, + { RM_TABLE (RM_0FAE_REG_5) }, }, { - /* OPC_EXT_19 */ + /* MOD_0FAE_REG_6 */ { "(bad)", { XX } }, - { OPC_EXT_RM_3 }, + { RM_TABLE (RM_0FAE_REG_6) }, }, { - /* OPC_EXT_20 */ + /* MOD_0FAE_REG_7 */ { "clflush", { Mb } }, - { OPC_EXT_RM_4 }, + { RM_TABLE (RM_0FAE_REG_7) }, }, { - /* OPC_EXT_21 */ - { "prefetchnta", { Mb } }, + /* MOD_0FC7_REG_6 */ + { PREFIX_TABLE (PREFIX_0FC7_REG_6) }, { "(bad)", { XX } }, }, { - /* OPC_EXT_22 */ - { "prefetcht0", { Mb } }, + /* MOD_0FC7_REG_7 */ + { "vmptrst", { Mq } }, { "(bad)", { XX } }, }, { - /* OPC_EXT_23 */ - { "prefetcht1", { Mb } }, + /* MOD_0F12_PREFIX_0 */ + { "movlps", { XM, EXq } }, + { "movhlps", { XM, EXq } }, + }, + { + /* MOD_0F16_PREFIX_0 */ + { "movhps", { XM, EXq } }, + { "movlhps", { XM, EXq } }, + }, + { + /* MOD_0FF0_PREFIX_3 */ + { "lddqu", { XM, M } }, { "(bad)", { XX } }, }, { - /* OPC_EXT_24 */ - { "prefetcht2", { Mb } }, + /* MOD_62_32BIT */ + { "bound{S|}", { Gv, Ma } }, + { "(bad)", { XX } }, + }, + { + /* MOD_C4_32BIT */ + { "lesS", { Gv, Mp } }, + { "(bad)", { XX } }, + }, + { + /* MOD_C5_32BIT */ + { "ldsS", { Gv, Mp } }, { "(bad)", { XX } }, }, }; -static const struct dis386 opc_ext_rm_table[][8] = { +static const struct dis386 rm_table[][8] = { { - /* OPC_EXT_RM_0 */ + /* RM_0F01_REG_0 */ { "(bad)", { XX } }, { "vmcall", { Skip_MODRM } }, { "vmlaunch", { Skip_MODRM } }, @@ -3190,7 +4727,7 @@ static const struct dis386 opc_ext_rm_table[][8] = { { "(bad)", { XX } }, }, { - /* OPC_EXT_RM_1 */ + /* RM_0F01_REG_1 */ { "monitor", { { OP_Monitor, 0 } } }, { "mwait", { { OP_Mwait, 0 } } }, { "(bad)", { XX } }, @@ -3201,7 +4738,29 @@ static const struct dis386 opc_ext_rm_table[][8] = { { "(bad)", { XX } }, }, { - /* OPC_EXT_RM_2 */ + /* RM_0F01_REG_3 */ + { "vmrun", { Skip_MODRM } }, + { "vmmcall", { Skip_MODRM } }, + { "vmload", { Skip_MODRM } }, + { "vmsave", { Skip_MODRM } }, + { "stgi", { Skip_MODRM } }, + { "clgi", { Skip_MODRM } }, + { "skinit", { Skip_MODRM } }, + { "invlpga", { Skip_MODRM } }, + }, + { + /* RM_0F01_REG_7 */ + { "swapgs", { Skip_MODRM } }, + { "rdtscp", { Skip_MODRM } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + }, + { + /* RM_0FAE_REG_5 */ { "lfence", { Skip_MODRM } }, { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -3212,7 +4771,7 @@ static const struct dis386 opc_ext_rm_table[][8] = { { "(bad)", { XX } }, }, { - /* OPC_EXT_RM_3 */ + /* RM_0FAE_REG_6 */ { "mfence", { Skip_MODRM } }, { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -3223,7 +4782,7 @@ static const struct dis386 opc_ext_rm_table[][8] = { { "(bad)", { XX } }, }, { - /* OPC_EXT_RM_4 */ + /* RM_0FAE_REG_7 */ { "sfence", { Skip_MODRM } }, { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -3482,7 +5041,7 @@ with the -M switch (multiple options should be separated by commas):\n")); /* Get a pointer to struct dis386 with a valid name. */ static const struct dis386 * -get_valid_dis386 (const struct dis386 *dp) +get_valid_dis386 (const struct dis386 *dp, disassemble_info *info) { int index; @@ -3491,11 +5050,20 @@ get_valid_dis386 (const struct dis386 *dp) switch (dp->op[0].bytemode) { - case USE_GROUPS: - dp = &grps[dp->op[1].bytemode][modrm.reg]; + case USE_REG_TABLE: + dp = ®_table[dp->op[1].bytemode][modrm.reg]; + break; + + case USE_MOD_TABLE: + index = modrm.mod == 0x3 ? 1 : 0; + dp = &mod_table[dp->op[1].bytemode][index]; break; - case USE_PREFIX_USER_TABLE: + case USE_RM_TABLE: + dp = &rm_table[dp->op[1].bytemode][modrm.rm]; + break; + + case USE_PREFIX_TABLE: index = 0; used_prefixes |= (prefixes & PREFIX_REPZ); if (prefixes & PREFIX_REPZ) @@ -3523,22 +5091,21 @@ get_valid_dis386 (const struct dis386 *dp) } } } - dp = &prefix_user_table[dp->op[1].bytemode][index]; + dp = &prefix_table[dp->op[1].bytemode][index]; break; - case X86_64_SPECIAL: + case USE_X86_64_TABLE: index = address_mode == mode_64bit ? 1 : 0; dp = &x86_64_table[dp->op[1].bytemode][index]; break; - case USE_OPC_EXT_TABLE: - index = modrm.mod == 0x3 ? 1 : 0; - dp = &opc_ext_table[dp->op[1].bytemode][index]; - break; - - case USE_OPC_EXT_RM_TABLE: - index = modrm.rm; - dp = &opc_ext_rm_table[dp->op[1].bytemode][index]; + case USE_3BYTE_TABLE: + FETCH_DATA (info, codep + 2); + index = *codep++; + dp = &three_byte_table[dp->op[1].bytemode][index]; + modrm.mod = (*codep >> 6) & 3; + modrm.reg = (*codep >> 3) & 7; + modrm.rm = *codep & 7; break; default: @@ -3549,7 +5116,7 @@ get_valid_dis386 (const struct dis386 *dp) if (dp->name != NULL) return dp; else - return get_valid_dis386 (dp); + return get_valid_dis386 (dp, info); } static int @@ -3651,6 +5218,8 @@ print_insn (bfd_vma pc, disassemble_info *info) names8 = intel_names8; names8rex = intel_names8rex; names_seg = intel_names_seg; + index64 = intel_index64; + index32 = intel_index32; index16 = intel_index16; open_char = '['; close_char = ']'; @@ -3665,6 +5234,8 @@ print_insn (bfd_vma pc, disassemble_info *info) names8 = att_names8; names8rex = att_names8rex; names_seg = att_names_seg; + index64 = att_index64; + index32 = att_index32; index16 = att_index16; open_char = '('; close_char = ')'; @@ -3750,11 +5321,6 @@ print_insn (bfd_vma pc, disassemble_info *info) dp = &dis386_twobyte[threebyte]; need_modrm = twobyte_has_modrm[*codep]; codep++; - if (dp->name == NULL && dp->op[0].bytemode == IS_3BYTE_OPCODE) - { - FETCH_DATA (info, codep + 2); - op = *codep++; - } } else { @@ -3817,14 +5383,7 @@ print_insn (bfd_vma pc, disassemble_info *info) } } - if (dp->name == NULL && dp->op[0].bytemode == IS_3BYTE_OPCODE) - { - dp = &three_byte_table[dp->op[1].bytemode][op]; - modrm.mod = (*codep >> 6) & 3; - modrm.reg = (*codep >> 3) & 7; - modrm.rm = *codep & 7; - } - else if (need_modrm) + if (need_modrm) { FETCH_DATA (info, codep + 1); modrm.mod = (*codep >> 6) & 3; @@ -3838,7 +5397,7 @@ print_insn (bfd_vma pc, disassemble_info *info) } else { - dp = get_valid_dis386 (dp); + dp = get_valid_dis386 (dp, info); if (dp != NULL && putop (dp->name, sizeflag) == 0) { for (i = 0; i < MAX_OPERANDS; ++i) @@ -3947,55 +5506,55 @@ print_insn (bfd_vma pc, disassemble_info *info) static const char *float_mem[] = { /* d8 */ - "fadd{s||s|}", - "fmul{s||s|}", - "fcom{s||s|}", - "fcomp{s||s|}", - "fsub{s||s|}", - "fsubr{s||s|}", - "fdiv{s||s|}", - "fdivr{s||s|}", + "fadd{s|}", + "fmul{s|}", + "fcom{s|}", + "fcomp{s|}", + "fsub{s|}", + "fsubr{s|}", + "fdiv{s|}", + "fdivr{s|}", /* d9 */ - "fld{s||s|}", + "fld{s|}", "(bad)", - "fst{s||s|}", - "fstp{s||s|}", + "fst{s|}", + "fstp{s|}", "fldenvIC", "fldcw", "fNstenvIC", "fNstcw", /* da */ - "fiadd{l||l|}", - "fimul{l||l|}", - "ficom{l||l|}", - "ficomp{l||l|}", - "fisub{l||l|}", - "fisubr{l||l|}", - "fidiv{l||l|}", - "fidivr{l||l|}", + "fiadd{l|}", + "fimul{l|}", + "ficom{l|}", + "ficomp{l|}", + "fisub{l|}", + "fisubr{l|}", + "fidiv{l|}", + "fidivr{l|}", /* db */ - "fild{l||l|}", - "fisttp{l||l|}", - "fist{l||l|}", - "fistp{l||l|}", + "fild{l|}", + "fisttp{l|}", + "fist{l|}", + "fistp{l|}", "(bad)", "fld{t||t|}", "(bad)", "fstp{t||t|}", /* dc */ - "fadd{l||l|}", - "fmul{l||l|}", - "fcom{l||l|}", - "fcomp{l||l|}", - "fsub{l||l|}", - "fsubr{l||l|}", - "fdiv{l||l|}", - "fdivr{l||l|}", + "fadd{l|}", + "fmul{l|}", + "fcom{l|}", + "fcomp{l|}", + "fsub{l|}", + "fsubr{l|}", + "fdiv{l|}", + "fdivr{l|}", /* dd */ - "fld{l||l|}", - "fisttp{ll||ll|}", - "fst{l||l|}", - "fstp{l||l|}", + "fld{l|}", + "fisttp{ll|}", + "fst{l||}", + "fstp{l|}", "frstorIC", "(bad)", "fNsaveIC", @@ -4015,9 +5574,9 @@ static const char *float_mem[] = { "fist", "fistp", "fbld", - "fild{ll||ll|}", + "fild{ll|}", "fbstp", - "fistp{ll||ll|}", + "fistp{ll|}", }; static const unsigned char float_mem_mode[] = { @@ -4347,24 +5906,10 @@ putop (const char *template, int sizeflag) case '{': alt = 0; if (intel_syntax) - alt += 1; - if (address_mode == mode_64bit) - alt += 2; - while (alt != 0) { while (*++p != '|') - { - if (*p == '}') - { - /* Alternative not valid. */ - strcpy (obuf, "(bad)"); - obufp = obuf + 5; - return 1; - } - else if (*p == '\0') - abort (); - } - alt--; + if (*p == '}' || *p == '\0') + abort (); } /* Fall through. */ case 'I': @@ -4883,7 +6428,7 @@ intel_operand_size (int bytemode, int sizeflag) } static void -OP_E (int bytemode, int sizeflag) +OP_E_extended (int bytemode, int sizeflag, int has_drex) { bfd_vma disp; int add = 0; @@ -4965,12 +6510,15 @@ OP_E (int bytemode, int sizeflag) int havedisp; int havesib; int havebase; + int haveindex; + int needindex; int base; int index = 0; int scale = 0; havesib = 0; havebase = 1; + haveindex = 0; base = modrm.rm; if (base == 4) @@ -4978,17 +6526,24 @@ OP_E (int bytemode, int sizeflag) havesib = 1; FETCH_DATA (the_info, codep + 1); index = (*codep >> 3) & 7; - if (address_mode == mode_64bit || index != 0x4) - /* When INDEX == 0x4 in 32 bit mode, SCALE is ignored. */ - scale = (*codep >> 6) & 3; + scale = (*codep >> 6) & 3; base = *codep & 7; USED_REX (REX_X); if (rex & REX_X) index += 8; + haveindex = index != 4; codep++; } base += add; + /* If we have a DREX byte, skip it now + (it has already been handled) */ + if (has_drex) + { + FETCH_DATA (the_info, codep + 1); + codep++; + } + switch (modrm.mod) { case 0: @@ -5011,7 +6566,15 @@ OP_E (int bytemode, int sizeflag) break; } - havedisp = havebase || (havesib && (index != 4 || scale != 0)); + /* In 32bit mode, we need index register to tell [offset] from + [eiz*1 + offset]. */ + needindex = (havesib + && !havebase + && !haveindex + && address_mode == mode_32bit); + havedisp = (havebase + || needindex + || (havesib && (haveindex || scale != 0))); if (!intel_syntax) if (modrm.mod != 0 || (base & 7) == 5) @@ -5024,17 +6587,20 @@ OP_E (int bytemode, int sizeflag) if (riprel) { set_op (disp, 1); - oappend ("(%rip)"); + oappend (sizeflag & AFLAG ? "(%rip)" : "(%eip)"); } } + if (havebase || haveindex || riprel) + used_prefixes |= PREFIX_ADDR; + if (havedisp || (intel_syntax && riprel)) { *obufp++ = open_char; if (intel_syntax && riprel) { set_op (disp, 1); - oappend ("rip"); + oappend (sizeflag & AFLAG ? "rip" : "eip"); } *obufp = '\0'; if (havebase) @@ -5042,18 +6608,27 @@ OP_E (int bytemode, int sizeflag) ? names64[base] : names32[base]); if (havesib) { - if (index != 4) + /* ESP/RSP won't allow index. If base isn't ESP/RSP, + print index to tell base + index from base. */ + if (scale != 0 + || needindex + || haveindex + || (havebase && base != ESP_REG_NUM)) { if (!intel_syntax || havebase) { *obufp++ = separator_char; *obufp = '\0'; } - oappend (address_mode == mode_64bit && (sizeflag & AFLAG) - ? names64[index] : names32[index]); - } - if (scale != 0 || (!intel_syntax && index != 4)) - { + if (haveindex) + oappend (address_mode == mode_64bit + && (sizeflag & AFLAG) + ? names64[index] : names32[index]); + else + oappend (address_mode == mode_64bit + && (sizeflag & AFLAG) + ? index64 : index32); + *obufp++ = scale_char; *obufp = '\0'; sprintf (scratchbuf, "%d", 1 << scale); @@ -5063,7 +6638,7 @@ OP_E (int bytemode, int sizeflag) if (intel_syntax && (disp || modrm.mod != 0 || (base & 7) == 5)) { - if ((bfd_signed_vma) disp >= 0) + if (!havedisp || (bfd_signed_vma) disp >= 0) { *obufp++ = '+'; *obufp = '\0'; @@ -5075,7 +6650,10 @@ OP_E (int bytemode, int sizeflag) disp = - (bfd_signed_vma) disp; } - print_displacement (scratchbuf, disp); + if (havedisp) + print_displacement (scratchbuf, disp); + else + print_operand_value (scratchbuf, 1, disp); oappend (scratchbuf); } @@ -5174,6 +6752,13 @@ OP_E (int bytemode, int sizeflag) } } +static void +OP_E (int bytemode, int sizeflag) +{ + OP_E_extended (bytemode, sizeflag, 0); +} + + static void OP_G (int bytemode, int sizeflag) { @@ -5311,10 +6896,12 @@ static void OP_REG (int code, int sizeflag) { const char *s; - int add = 0; + int add; USED_REX (REX_B); if (rex & REX_B) add = 8; + else + add = 0; switch (code) { @@ -5787,7 +7374,7 @@ OP_DSreg (int code, int sizeflag) static void OP_C (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) { - int add = 0; + int add; if (rex & REX_R) { USED_REX (REX_R); @@ -5799,6 +7386,8 @@ OP_C (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) used_prefixes |= PREFIX_LOCK; add = 8; } + else + add = 0; sprintf (scratchbuf, "%%cr%d", modrm.reg + add); oappend (scratchbuf + intel_syntax); } @@ -5806,10 +7395,12 @@ OP_C (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) static void OP_D (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) { - int add = 0; + int add; USED_REX (REX_R); if (rex & REX_R) add = 8; + else + add = 0; if (intel_syntax) sprintf (scratchbuf, "db%d", modrm.reg + add); else @@ -5839,10 +7430,12 @@ OP_MMX (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) used_prefixes |= (prefixes & PREFIX_DATA); if (prefixes & PREFIX_DATA) { - int add = 0; + int add; USED_REX (REX_R); if (rex & REX_R) add = 8; + else + add = 0; sprintf (scratchbuf, "%%xmm%d", modrm.reg + add); } else @@ -5853,10 +7446,12 @@ OP_MMX (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) static void OP_XMM (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) { - int add = 0; + int add; USED_REX (REX_R); if (rex & REX_R) add = 8; + else + add = 0; sprintf (scratchbuf, "%%xmm%d", modrm.reg + add); oappend (scratchbuf + intel_syntax); } @@ -5881,11 +7476,13 @@ OP_EM (int bytemode, int sizeflag) used_prefixes |= (prefixes & PREFIX_DATA); if (prefixes & PREFIX_DATA) { - int add = 0; + int add; USED_REX (REX_B); if (rex & REX_B) add = 8; + else + add = 0; sprintf (scratchbuf, "%%xmm%d", modrm.rm + add); } else @@ -5931,7 +7528,7 @@ OP_MXC (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) static void OP_EX (int bytemode, int sizeflag) { - int add = 0; + int add; if (modrm.mod != 3) { OP_E (bytemode, sizeflag); @@ -5940,6 +7537,8 @@ OP_EX (int bytemode, int sizeflag) USED_REX (REX_B); if (rex & REX_B) add = 8; + else + add = 0; /* Skip mod/rm byte. */ MODRM_CHECK; @@ -6153,22 +7752,6 @@ OP_SIMD_Suffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) } } -static void -SIMD_Fixup (int extrachar, int sizeflag ATTRIBUTE_UNUSED) -{ - /* Change movlps/movhps to movhlps/movlhps for 2 register operand - forms of these instructions. */ - if (modrm.mod == 3) - { - char *p = obuf + strlen (obuf); - *(p + 1) = '\0'; - *p = *(p - 1); - *(p - 1) = *(p - 2); - *(p - 2) = *(p - 3); - *(p - 3) = extrachar; - } -} - static void OP_Mwait (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) @@ -6219,98 +7802,6 @@ OP_Monitor (int bytemode ATTRIBUTE_UNUSED, codep++; } -static void -SVME_Fixup (int bytemode, int sizeflag) -{ - const char *alt; - char *p; - - switch (*codep) - { - case 0xd8: - alt = "vmrun"; - break; - case 0xd9: - alt = "vmmcall"; - break; - case 0xda: - alt = "vmload"; - break; - case 0xdb: - alt = "vmsave"; - break; - case 0xdc: - alt = "stgi"; - break; - case 0xdd: - alt = "clgi"; - break; - case 0xde: - alt = "skinit"; - break; - case 0xdf: - alt = "invlpga"; - break; - default: - OP_M (bytemode, sizeflag); - return; - } - /* Override "lidt". */ - p = obuf + strlen (obuf) - 4; - /* We might have a suffix. */ - if (*p == 'i') - --p; - strcpy (p, alt); - if (!(prefixes & PREFIX_ADDR)) - { - ++codep; - return; - } - used_prefixes |= PREFIX_ADDR; - switch (*codep++) - { - case 0xdf: - strcpy (op_out[1], names32[1]); - two_source_ops = 1; - /* Fall through. */ - case 0xd8: - case 0xda: - case 0xdb: - *obufp++ = open_char; - if (address_mode == mode_64bit || (sizeflag & AFLAG)) - alt = names32[0]; - else - alt = names16[0]; - strcpy (obufp, alt); - obufp += strlen (alt); - *obufp++ = close_char; - *obufp = '\0'; - break; - } -} - -static void -INVLPG_Fixup (int bytemode, int sizeflag) -{ - const char *alt; - - switch (*codep) - { - case 0xf8: - alt = "swapgs"; - break; - case 0xf9: - alt = "rdtscp"; - break; - default: - OP_M (bytemode, sizeflag); - return; - } - /* Override "invlpg". */ - strcpy (obuf + strlen (obuf) - 6, alt); - codep++; -} - static void BadOp (void) { @@ -6432,3 +7923,344 @@ CRC32_Fixup (int bytemode, int sizeflag) else OP_E (bytemode, sizeflag); } + +/* Print a DREX argument as either a register or memory operation. */ +static void +print_drex_arg (unsigned int reg, int bytemode, int sizeflag) +{ + if (reg == DREX_REG_UNKNOWN) + BadOp (); + + else if (reg != DREX_REG_MEMORY) + { + sprintf (scratchbuf, "%%xmm%d", reg); + oappend (scratchbuf + intel_syntax); + } + + else + OP_E_extended (bytemode, sizeflag, 1); +} + +/* SSE5 instructions that have 4 arguments are encoded as: + 0f 24 . + + The byte has 1 bit (0x4) that is combined with 1 bit in + the DREX field (0x8) to determine how the arguments are laid out. + The destination register must be the same register as one of the + inputs, and it is encoded in the DREX byte. No REX prefix is used + for these instructions, since the DREX field contains the 3 extension + bits provided by the REX prefix. + + The bytemode argument adds 2 extra bits for passing extra information: + DREX_OC1 -- Set the OC1 bit to indicate dest == 1st arg + DREX_NO_OC0 -- OC0 in DREX is invalid + (but pretend it is set). */ + +static void +OP_DREX4 (int flag_bytemode, int sizeflag) +{ + unsigned int drex_byte; + unsigned int regs[4]; + unsigned int modrm_regmem; + unsigned int modrm_reg; + unsigned int drex_reg; + int bytemode; + int rex_save = rex; + int rex_used_save = rex_used; + int has_sib = 0; + int oc1 = (flag_bytemode & DREX_OC1) ? 2 : 0; + int oc0; + int i; + + bytemode = flag_bytemode & ~ DREX_MASK; + + for (i = 0; i < 4; i++) + regs[i] = DREX_REG_UNKNOWN; + + /* Determine if we have a SIB byte in addition to MODRM before the + DREX byte. */ + if (((sizeflag & AFLAG) || address_mode == mode_64bit) + && (modrm.mod != 3) + && (modrm.rm == 4)) + has_sib = 1; + + /* Get the DREX byte. */ + FETCH_DATA (the_info, codep + 2 + has_sib); + drex_byte = codep[has_sib+1]; + drex_reg = DREX_XMM (drex_byte); + modrm_reg = modrm.reg + ((drex_byte & REX_R) ? 8 : 0); + + /* Is OC0 legal? If not, hardwire oc0 == 1. */ + if (flag_bytemode & DREX_NO_OC0) + { + oc0 = 1; + if (DREX_OC0 (drex_byte)) + BadOp (); + } + else + oc0 = DREX_OC0 (drex_byte); + + if (modrm.mod == 3) + { + /* regmem == register */ + modrm_regmem = modrm.rm + ((drex_byte & REX_B) ? 8 : 0); + rex = rex_used = 0; + /* skip modrm/drex since we don't call OP_E_extended */ + codep += 2; + } + else + { + /* regmem == memory, fill in appropriate REX bits */ + modrm_regmem = DREX_REG_MEMORY; + rex = drex_byte & (REX_B | REX_X | REX_R); + if (rex) + rex |= REX_OPCODE; + rex_used = rex; + } + + /* Based on the OC1/OC0 bits, lay out the arguments in the correct + order. */ + switch (oc0 + oc1) + { + default: + BadOp (); + return; + + case 0: + regs[0] = modrm_regmem; + regs[1] = modrm_reg; + regs[2] = drex_reg; + regs[3] = drex_reg; + break; + + case 1: + regs[0] = modrm_reg; + regs[1] = modrm_regmem; + regs[2] = drex_reg; + regs[3] = drex_reg; + break; + + case 2: + regs[0] = drex_reg; + regs[1] = modrm_regmem; + regs[2] = modrm_reg; + regs[3] = drex_reg; + break; + + case 3: + regs[0] = drex_reg; + regs[1] = modrm_reg; + regs[2] = modrm_regmem; + regs[3] = drex_reg; + break; + } + + /* Print out the arguments. */ + for (i = 0; i < 4; i++) + { + int j = (intel_syntax) ? 3 - i : i; + if (i > 0) + { + *obufp++ = ','; + *obufp = '\0'; + } + + print_drex_arg (regs[j], bytemode, sizeflag); + } + + rex = rex_save; + rex_used = rex_used_save; +} + +/* SSE5 instructions that have 3 arguments, and are encoded as: + 0f 24 (or) + 0f 25 + + The DREX field has 1 bit (0x8) to determine how the arguments are + laid out. The destination register is encoded in the DREX byte. + No REX prefix is used for these instructions, since the DREX field + contains the 3 extension bits provided by the REX prefix. */ + +static void +OP_DREX3 (int flag_bytemode, int sizeflag) +{ + unsigned int drex_byte; + unsigned int regs[3]; + unsigned int modrm_regmem; + unsigned int modrm_reg; + unsigned int drex_reg; + int bytemode; + int rex_save = rex; + int rex_used_save = rex_used; + int has_sib = 0; + int oc0; + int i; + + bytemode = flag_bytemode & ~ DREX_MASK; + + for (i = 0; i < 3; i++) + regs[i] = DREX_REG_UNKNOWN; + + /* Determine if we have a SIB byte in addition to MODRM before the + DREX byte. */ + if (((sizeflag & AFLAG) || address_mode == mode_64bit) + && (modrm.mod != 3) + && (modrm.rm == 4)) + has_sib = 1; + + /* Get the DREX byte. */ + FETCH_DATA (the_info, codep + 2 + has_sib); + drex_byte = codep[has_sib+1]; + drex_reg = DREX_XMM (drex_byte); + modrm_reg = modrm.reg + ((drex_byte & REX_R) ? 8 : 0); + + /* Is OC0 legal? If not, hardwire oc0 == 0 */ + oc0 = DREX_OC0 (drex_byte); + if ((flag_bytemode & DREX_NO_OC0) && oc0) + BadOp (); + + if (modrm.mod == 3) + { + /* regmem == register */ + modrm_regmem = modrm.rm + ((drex_byte & REX_B) ? 8 : 0); + rex = rex_used = 0; + /* skip modrm/drex since we don't call OP_E_extended. */ + codep += 2; + } + else + { + /* regmem == memory, fill in appropriate REX bits. */ + modrm_regmem = DREX_REG_MEMORY; + rex = drex_byte & (REX_B | REX_X | REX_R); + if (rex) + rex |= REX_OPCODE; + rex_used = rex; + } + + /* Based on the OC1/OC0 bits, lay out the arguments in the correct + order. */ + switch (oc0) + { + default: + BadOp (); + return; + + case 0: + regs[0] = modrm_regmem; + regs[1] = modrm_reg; + regs[2] = drex_reg; + break; + + case 1: + regs[0] = modrm_reg; + regs[1] = modrm_regmem; + regs[2] = drex_reg; + break; + } + + /* Print out the arguments. */ + for (i = 0; i < 3; i++) + { + int j = (intel_syntax) ? 2 - i : i; + if (i > 0) + { + *obufp++ = ','; + *obufp = '\0'; + } + + print_drex_arg (regs[j], bytemode, sizeflag); + } + + rex = rex_save; + rex_used = rex_used_save; +} + +/* Emit a floating point comparison for comp instructions. */ + +static void +OP_DREX_FCMP (int bytemode ATTRIBUTE_UNUSED, + int sizeflag ATTRIBUTE_UNUSED) +{ + unsigned char byte; + + static const char *const cmp_test[] = { + "eq", + "lt", + "le", + "unord", + "ne", + "nlt", + "nle", + "ord", + "ueq", + "ult", + "ule", + "false", + "une", + "unlt", + "unle", + "true" + }; + + FETCH_DATA (the_info, codep + 1); + byte = *codep & 0xff; + + if (byte >= ARRAY_SIZE (cmp_test) + || obuf[0] != 'c' + || obuf[1] != 'o' + || obuf[2] != 'm') + { + /* The instruction isn't one we know about, so just append the + extension byte as a numeric value. */ + OP_I (b_mode, 0); + } + + else + { + sprintf (scratchbuf, "com%s%s", cmp_test[byte], obuf+3); + strcpy (obuf, scratchbuf); + codep++; + } +} + +/* Emit an integer point comparison for pcom instructions, + rewriting the instruction to have the test inside of it. */ + +static void +OP_DREX_ICMP (int bytemode ATTRIBUTE_UNUSED, + int sizeflag ATTRIBUTE_UNUSED) +{ + unsigned char byte; + + static const char *const cmp_test[] = { + "lt", + "le", + "gt", + "ge", + "eq", + "ne", + "false", + "true" + }; + + FETCH_DATA (the_info, codep + 1); + byte = *codep & 0xff; + + if (byte >= ARRAY_SIZE (cmp_test) + || obuf[0] != 'p' + || obuf[1] != 'c' + || obuf[2] != 'o' + || obuf[3] != 'm') + { + /* The instruction isn't one we know about, so just print the + comparison test byte as a numeric value. */ + OP_I (b_mode, 0); + } + + else + { + sprintf (scratchbuf, "pcom%s%s", cmp_test[byte], obuf+4); + strcpy (obuf, scratchbuf); + codep++; + } +}