X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=opcodes%2Fi386-dis.c;h=ecb428fd8fc6f8650ea966a19607b768b301cb1f;hb=9a04903eea44cbc4642f10d2a8f8db416a694737;hp=243b508f721c440b8a454e2d6b8ba82a0e9408bd;hpb=bbedc8321e2c5f170b37295b9a00c2ff3b8312f8;p=deliverable%2Fbinutils-gdb.git diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c index 243b508f72..ecb428fd8f 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,12 +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 SVME_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. */ @@ -141,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; @@ -361,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 @@ -556,6 +581,10 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr) #define THREE_BYTE_0 NULL, { { NULL, IS_3BYTE_OPCODE }, { NULL, 0 } } #define THREE_BYTE_1 NULL, { { NULL, IS_3BYTE_OPCODE }, { NULL, 1 } } +#define THREE_BYTE_SSE5_0F24 NULL, { { NULL, IS_3BYTE_OPCODE }, { NULL, 2 } } +#define THREE_BYTE_SSE5_0F25 NULL, { { NULL, IS_3BYTE_OPCODE }, { NULL, 3 } } +#define THREE_BYTE_SSE5_0F7A NULL, { { NULL, IS_3BYTE_OPCODE }, { NULL, 4 } } +#define THREE_BYTE_SSE5_0F7B NULL, { { NULL, IS_3BYTE_OPCODE }, { NULL, 5 } } #define OPC_EXT_0 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 0 } } #define OPC_EXT_1 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 1 } } @@ -596,6 +625,13 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr) #define OPC_EXT_36 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 36 } } #define OPC_EXT_37 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 37 } } #define OPC_EXT_38 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 38 } } +#define OPC_EXT_39 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 39 } } +#define OPC_EXT_40 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 40 } } +#define OPC_EXT_41 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 41 } } +#define OPC_EXT_42 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 42 } } +#define OPC_EXT_43 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 43 } } +#define OPC_EXT_44 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 44 } } +#define OPC_EXT_45 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 45 } } #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 } } @@ -603,6 +639,7 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr) #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 OPC_EXT_RM_5 NULL, { { NULL, USE_OPC_EXT_RM_TABLE }, { NULL, 5 } } +#define OPC_EXT_RM_6 NULL, { { NULL, USE_OPC_EXT_RM_TABLE }, { NULL, 6 } } typedef void (*op_rtn) (int bytemode, int sizeflag); @@ -985,13 +1022,13 @@ 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 } }, + { OPC_EXT_40 }, + { OPC_EXT_41 }, + { OPC_EXT_42 }, + { OPC_EXT_43 }, + { OPC_EXT_44 }, + { THREE_BYTE_SSE5_0F25 }, + { OPC_EXT_45 }, { "(bad)", { XX } }, /* 28 */ { "movapX", { XM, EXx } }, @@ -1086,8 +1123,8 @@ static const struct dis386 dis386_twobyte[] = { /* 78 */ { PREGRP34 }, { PREGRP35 }, - { "(bad)", { XX } }, - { "(bad)", { XX } }, + { THREE_BYTE_SSE5_0F7A }, + { THREE_BYTE_SSE5_0F7B }, { PREGRP28 }, { PREGRP29 }, { PREGRP23 }, @@ -1266,12 +1303,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 */ @@ -1316,6 +1353,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[] = { @@ -1340,6 +1379,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" }; @@ -1366,6 +1407,8 @@ 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" }; @@ -1541,7 +1584,7 @@ static const struct dis386 grps[][8] = { { OPC_EXT_6 }, { OPC_EXT_7 }, { OPC_EXT_8 }, - { "lidt{Q|Q||}", { { SVME_Fixup, 0 } } }, + { OPC_EXT_39 }, { "smswD", { Sv } }, { "(bad)", { XX } }, { "lmsw", { Ew } }, @@ -2583,16 +2626,1180 @@ static const struct dis386 three_byte_table[][256] = { { "(bad)", { XX } }, { "(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 */ + { PREGRP87 }, + { PREGRP88 }, + { "(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_1 */ + { + /* 00 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(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 } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 20 */ + { PREGRP80 }, + { PREGRP81 }, + { PREGRP82 }, + { "(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 */ + { PREGRP83 }, + { PREGRP84 }, + { PREGRP85 }, + { "(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 */ + { PREGRP89 }, + { PREGRP90 }, + { PREGRP91 }, + { PREGRP92 }, + { "(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 */ + { "(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_SSE5_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_SSE5_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_SSE5_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 */ + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + { "(bad)", { XX } }, + /* 30 */ + { "cvtph2ps", { XM, EXd } }, + { "cvtps2ph", { EXd, XM } }, + { "(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 } }, + { "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 } }, + { "(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 } }, { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, /* 60 */ { "(bad)", { XX } }, - { "(bad)", { XX } }, - { "(bad)", { XX } }, - { "(bad)", { XX } }, + { "phsubbw", { XM, EXq } }, + { "phsubbd", { XM, EXq } }, + { "phsubbq", { XM, EXq } }, { "(bad)", { XX } }, { "(bad)", { XX } }, { "(bad)", { XX } }, @@ -2751,8 +3958,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 } }, @@ -2769,7 +3976,7 @@ static const struct dis386 three_byte_table[][256] = { { "(bad)", { XX } }, { "(bad)", { XX } }, }, - /* THREE_BYTE_1 */ + /* THREE_BYTE_SSE5_0F7B */ { /* 00 */ { "(bad)", { XX } }, @@ -2781,42 +3988,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 } }, @@ -2824,8 +4014,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 } }, @@ -2833,8 +4023,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 } }, @@ -2842,22 +4032,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 } }, @@ -2880,10 +4087,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 } }, @@ -3258,6 +4465,41 @@ static const struct dis386 opc_ext_table[][2] = { { "invlpg", { Mb } }, { OPC_EXT_RM_5 }, }, + { + /* OPC_EXT_39 */ + { "lidt{Q|Q||}", { M } }, + { OPC_EXT_RM_6 }, + }, + { + /* OPC_EXT_40 */ + { "(bad)", { XX } }, + { "movZ", { Rm, Cm } }, + }, + { + /* OPC_EXT_41 */ + { "(bad)", { XX } }, + { "movZ", { Rm, Dm } }, + }, + { + /* OPC_EXT_42 */ + { "(bad)", { XX } }, + { "movZ", { Cm, Rm } }, + }, + { + /* OPC_EXT_43 */ + { "(bad)", { XX } }, + { "movZ", { Dm, Rm } }, + }, + { + /* OPC_EXT_44 */ + { THREE_BYTE_SSE5_0F24 }, + { "movL", { Rd, Td } }, + }, + { + /* OPC_EXT_45 */ + { "(bad)", { XX } }, + { "movL", { Td, Rd } }, + }, }; static const struct dis386 opc_ext_rm_table[][8] = { @@ -3327,6 +4569,17 @@ static const struct dis386 opc_ext_rm_table[][8] = { { "(bad)", { XX } }, { "(bad)", { XX } }, }, + { + /* OPC_EXT_RM_6 */ + { "vmrun", { Skip_MODRM } }, + { "vmmcall", { Skip_MODRM } }, + { "vmload", { Skip_MODRM } }, + { "vmsave", { Skip_MODRM } }, + { "stgi", { Skip_MODRM } }, + { "clgi", { Skip_MODRM } }, + { "skinit", { Skip_MODRM } }, + { "invlpga", { Skip_MODRM } }, + }, }; #define INTERNAL_DISASSEMBLER_ERROR _("") @@ -3576,7 +4829,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; @@ -3625,6 +4878,15 @@ get_valid_dis386 (const struct dis386 *dp) dp = &x86_64_table[dp->op[1].bytemode][index]; break; + case IS_3BYTE_OPCODE: + 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; + case USE_OPC_EXT_TABLE: index = modrm.mod == 0x3 ? 1 : 0; dp = &opc_ext_table[dp->op[1].bytemode][index]; @@ -3643,7 +4905,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 @@ -3745,6 +5007,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 = ']'; @@ -3759,6 +5023,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 = ')'; @@ -3844,11 +5110,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 { @@ -3911,14 +5172,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; @@ -3932,7 +5186,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) @@ -4977,7 +6231,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; @@ -5059,12 +6313,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) @@ -5072,17 +6329,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: @@ -5105,7 +6369,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) @@ -5136,18 +6408,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); @@ -5157,7 +6438,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'; @@ -5169,7 +6450,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); } @@ -5268,6 +6552,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) { @@ -6297,76 +7588,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 BadOp (void) { @@ -6488,3 +7709,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++; + } +}