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 <setjmp.h>
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);
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. */
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;
#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
#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 } }
#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_25 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 25 } }
+#define OPC_EXT_26 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 26 } }
+#define OPC_EXT_27 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 27 } }
+#define OPC_EXT_28 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 28 } }
+#define OPC_EXT_29 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 29 } }
+#define OPC_EXT_30 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 30 } }
+#define OPC_EXT_31 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 31 } }
+#define OPC_EXT_32 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 32 } }
+#define OPC_EXT_33 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 33 } }
+#define OPC_EXT_34 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 34 } }
+#define OPC_EXT_35 NULL, { { NULL, USE_OPC_EXT_TABLE }, { NULL, 35 } }
+#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 } }
#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 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);
{ "movB", { Gb, Eb } },
{ "movS", { Gv, Ev } },
{ "movD", { Sv, Sw } },
- { "leaS", { Gv, M } },
+ { OPC_EXT_0 },
{ "movD", { Sw, Sv } },
{ GRP1a },
/* 90 */
{ GRP2S },
{ "retT", { Iw } },
{ "retT", { XX } },
- { "les{S|}", { Gv, Mp } },
- { "ldsS", { Gv, Mp } },
+ { OPC_EXT_1 },
+ { OPC_EXT_2 },
{ GRP11_C6 },
{ GRP11_C7 },
/* c8 */
{ PREGRP8 },
{ PREGRP9 },
{ PREGRP30 },
- { "movlpX", { EXq, XM, { SIMD_Fixup, 'h' } } },
+ { OPC_EXT_34 },
{ "unpcklpX", { XM, EXq } },
{ "unpckhpX", { XM, EXq } },
{ PREGRP31 },
- { "movhpX", { EXq, XM, { SIMD_Fixup, 'l' } } },
+ { OPC_EXT_35 },
/* 18 */
{ GRP16 },
{ "(bad)", { XX } },
{ "(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 } },
/* 78 */
{ PREGRP34 },
{ PREGRP35 },
- { "(bad)", { XX } },
- { "(bad)", { XX } },
+ { THREE_BYTE_SSE5_0F7A },
+ { THREE_BYTE_SSE5_0F7B },
{ PREGRP28 },
{ PREGRP29 },
{ PREGRP23 },
/* b0 */
{ "cmpxchgB", { Eb, Gb } },
{ "cmpxchgS", { Ev, Gv } },
- { "lssS", { Gv, Mp } },
+ { OPC_EXT_3 },
{ "btrS", { Ev, Gv } },
- { "lfsS", { Gv, Mp } },
- { "lgsS", { Gv, Mp } },
+ { OPC_EXT_4 },
+ { OPC_EXT_5 },
{ "movz{bR|x|bR|x}", { Gv, Eb } },
{ "movz{wR|x|wR|x}", { Gv, Ew } }, /* yes, there really is movzww ! */
/* b8 */
/* ------------------------------- */
/* 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 */
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[] = {
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"
};
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"
};
},
/* GRP7 */
{
- { OPC_EXT_0 },
- { OPC_EXT_1 },
- { "lgdt{Q|Q||}", { M } },
- { "lidt{Q|Q||}", { { SVME_Fixup, 0 } } },
+ { OPC_EXT_6 },
+ { OPC_EXT_7 },
+ { OPC_EXT_8 },
+ { OPC_EXT_39 },
{ "smswD", { Sv } },
{ "(bad)", { XX } },
{ "lmsw", { Ew } },
- { "invlpg", { { INVLPG_Fixup, 0 } } },
+ { OPC_EXT_38 },
},
/* GRP8 */
{
{ "(bad)", { XX } },
{ "(bad)", { XX } },
{ "(bad)", { XX } },
- { OPC_EXT_2 },
- { OPC_EXT_3 },
+ { OPC_EXT_9 },
+ { OPC_EXT_10 },
},
/* GRP11_C6 */
{
{
{ "(bad)", { XX } },
{ "(bad)", { XX } },
- { OPC_EXT_4 },
+ { OPC_EXT_11 },
{ "(bad)", { XX } },
- { OPC_EXT_5 },
+ { OPC_EXT_12 },
{ "(bad)", { XX } },
- { OPC_EXT_6 },
+ { OPC_EXT_13 },
{ "(bad)", { XX } },
},
/* GRP13 */
{
{ "(bad)", { XX } },
{ "(bad)", { XX } },
- { OPC_EXT_7 },
+ { OPC_EXT_14 },
{ "(bad)", { XX } },
- { OPC_EXT_8 },
+ { OPC_EXT_15 },
{ "(bad)", { XX } },
- { OPC_EXT_9 },
+ { OPC_EXT_16 },
{ "(bad)", { XX } },
},
/* GRP14 */
{
{ "(bad)", { XX } },
{ "(bad)", { XX } },
- { OPC_EXT_10 },
- { OPC_EXT_11 },
- { "(bad)", { XX } },
- { "(bad)", { XX } },
- { OPC_EXT_12 },
- { OPC_EXT_13 },
- },
- /* GRP15 */
- {
- { OPC_EXT_14 },
- { OPC_EXT_15 },
- { OPC_EXT_16 },
{ OPC_EXT_17 },
- { "(bad)", { XX } },
{ OPC_EXT_18 },
+ { "(bad)", { XX } },
+ { "(bad)", { XX } },
{ OPC_EXT_19 },
{ OPC_EXT_20 },
},
- /* GRP16 */
+ /* GRP15 */
{
{ OPC_EXT_21 },
{ OPC_EXT_22 },
{ OPC_EXT_23 },
{ OPC_EXT_24 },
{ "(bad)", { XX } },
+ { OPC_EXT_25 },
+ { OPC_EXT_26 },
+ { OPC_EXT_27 },
+ },
+ /* GRP16 */
+ {
+ { OPC_EXT_28 },
+ { OPC_EXT_29 },
+ { OPC_EXT_30 },
+ { OPC_EXT_31 },
+ { "(bad)", { XX } },
{ "(bad)", { XX } },
{ "(bad)", { XX } },
{ "(bad)", { XX } },
},
/* PREGRP30 */
{
- { "movlpX", { XM, EXq, { SIMD_Fixup, 'h' } } }, /* really only 2 operands */
+ { OPC_EXT_36 },
{ "movsldup", { XM, EXx } },
{ "movlpd", { XM, EXq } },
{ "movddup", { XM, EXq } },
},
/* PREGRP31 */
{
- { "movhpX", { XM, EXq, { SIMD_Fixup, 'l' } } },
+ { OPC_EXT_37 },
{ "movshdup", { XM, EXx } },
{ "movhpd", { XM, EXq } },
{ "(bad)", { XM, EXq } },
{ "(bad)", { XM, EXx } },
{ "(bad)", { XM, EXx } },
{ "(bad)", { XM, EXx } },
- { "lddqu", { XM, M } },
+ { OPC_EXT_32 },
},
/* PREGRP33 */
{
{ "(bad)", { XX } },
},
{
- { "bound{S|}", { Gv, Ma } },
+ { OPC_EXT_33 },
{ "(bad)", { XX } },
},
{
{ "(bad)", { XX } },
{ "(bad)", { XX } },
{ "(bad)", { XX } },
- }
-};
-
-static const struct dis386 opc_ext_table[][2] = {
- {
- /* OPC_EXT_0 */
- { "sgdt{Q|IQ||}", { M } },
- { OPC_EXT_RM_0 },
- },
- {
- /* OPC_EXT_1 */
- { "sidt{Q|IQ||}", { M } },
- { OPC_EXT_RM_1 },
},
+ /* THREE_BYTE_SSE5_0F24 */
{
- /* OPC_EXT_2 */
- { PREGRP98 },
+ /* 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 } },
- },
- {
- /* OPC_EXT_3 */
- { "vmptrst", { Mq } },
{ "(bad)", { XX } },
- },
- {
- /* OPC_EXT_4 */
{ "(bad)", { XX } },
- { "psrlw", { MS, Ib } },
- },
- {
- /* OPC_EXT_5 */
{ "(bad)", { XX } },
- { "psraw", { MS, Ib } },
- },
- {
- /* OPC_EXT_6 */
{ "(bad)", { XX } },
- { "psllw", { MS, Ib } },
+ { "(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 } },
+ { "phsubbw", { XM, EXq } },
+ { "phsubbd", { XM, EXq } },
+ { "phsubbq", { XM, EXq } },
+ { "(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_0F7B */
+ {
+ /* 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 } },
+ { "(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", { 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 } },
+ /* 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 */
+ { "(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 } },
+ }
+};
+
+static const struct dis386 opc_ext_table[][2] = {
+ {
+ /* OPC_EXT_0 */
+ { "leaS", { Gv, M } },
+ { "(bad)", { XX } },
+ },
+ {
+ /* OPC_EXT_1 */
+ { "les{S|}", { Gv, Mp } },
+ { "(bad)", { XX } },
+ },
+ {
+ /* OPC_EXT_2 */
+ { "ldsS", { Gv, Mp } },
+ { "(bad)", { XX } },
+ },
+ {
+ /* OPC_EXT_3 */
+ { "lssS", { Gv, Mp } },
+ { "(bad)", { XX } },
+ },
+ {
+ /* OPC_EXT_4 */
+ { "lfsS", { Gv, Mp } },
+ { "(bad)", { XX } },
+ },
+ {
+ /* OPC_EXT_5 */
+ { "lgsS", { Gv, Mp } },
+ { "(bad)", { XX } },
+ },
+ {
+ /* OPC_EXT_6 */
+ { "sgdt{Q|IQ||}", { M } },
+ { OPC_EXT_RM_0 },
+ },
+ {
+ /* OPC_EXT_7 */
+ { "sidt{Q|IQ||}", { M } },
+ { OPC_EXT_RM_1 },
+ },
+ {
+ /* OPC_EXT_8 */
+ { "lgdt{Q|Q||}", { M } },
+ { "(bad)", { XX } },
+ },
+ {
+ /* OPC_EXT_9 */
+ { PREGRP98 },
+ { "(bad)", { XX } },
+ },
+ {
+ /* OPC_EXT_10 */
+ { "vmptrst", { Mq } },
+ { "(bad)", { XX } },
+ },
+ {
+ /* OPC_EXT_11 */
+ { "(bad)", { XX } },
+ { "psrlw", { MS, Ib } },
+ },
+ {
+ /* OPC_EXT_12 */
+ { "(bad)", { XX } },
+ { "psraw", { MS, Ib } },
+ },
+ {
+ /* OPC_EXT_13 */
+ { "(bad)", { XX } },
+ { "psllw", { MS, Ib } },
+ },
+ {
+ /* OPC_EXT_14 */
+ { "(bad)", { XX } },
+ { "psrld", { MS, Ib } },
+ },
+ {
+ /* OPC_EXT_15 */
+ { "(bad)", { XX } },
+ { "psrad", { MS, Ib } },
+ },
+ {
+ /* OPC_EXT_16 */
+ { "(bad)", { XX } },
+ { "pslld", { MS, Ib } },
+ },
+ {
+ /* OPC_EXT_17 */
+ { "(bad)", { XX } },
+ { "psrlq", { MS, Ib } },
+ },
+ {
+ /* OPC_EXT_18 */
+ { "(bad)", { XX } },
+ { PREGRP99 },
+ },
+ {
+ /* OPC_EXT_19 */
+ { "(bad)", { XX } },
+ { "psllq", { MS, Ib } },
+ },
+ {
+ /* OPC_EXT_20 */
+ { "(bad)", { XX } },
+ { PREGRP100 },
+ },
+ {
+ /* OPC_EXT_21 */
+ { "fxsave", { M } },
+ { "(bad)", { XX } },
+ },
+ {
+ /* OPC_EXT_22 */
+ { "fxrstor", { M } },
+ { "(bad)", { XX } },
+ },
+ {
+ /* OPC_EXT_23 */
+ { "ldmxcsr", { Md } },
+ { "(bad)", { XX } },
+ },
+ {
+ /* OPC_EXT_24 */
+ { "stmxcsr", { Md } },
+ { "(bad)", { XX } },
+ },
+ {
+ /* OPC_EXT_25 */
+ { "(bad)", { XX } },
+ { OPC_EXT_RM_2 },
+ },
+ {
+ /* OPC_EXT_26 */
+ { "(bad)", { XX } },
+ { OPC_EXT_RM_3 },
+ },
+ {
+ /* OPC_EXT_27 */
+ { "clflush", { Mb } },
+ { OPC_EXT_RM_4 },
},
{
- /* OPC_EXT_7 */
+ /* OPC_EXT_28 */
+ { "prefetchnta", { Mb } },
{ "(bad)", { XX } },
- { "psrld", { MS, Ib } },
},
{
- /* OPC_EXT_8 */
+ /* OPC_EXT_29 */
+ { "prefetcht0", { Mb } },
{ "(bad)", { XX } },
- { "psrad", { MS, Ib } },
},
{
- /* OPC_EXT_9 */
+ /* OPC_EXT_30 */
+ { "prefetcht1", { Mb } },
{ "(bad)", { XX } },
- { "pslld", { MS, Ib } },
},
{
- /* OPC_EXT_10 */
+ /* OPC_EXT_31 */
+ { "prefetcht2", { Mb } },
{ "(bad)", { XX } },
- { "psrlq", { MS, Ib } },
},
{
- /* OPC_EXT_11 */
+ /* OPC_EXT_32 */
+ { "lddqu", { XM, M } },
{ "(bad)", { XX } },
- { PREGRP99 },
},
{
- /* OPC_EXT_12 */
+ /* OPC_EXT_33 */
+ { "bound{S|}", { Gv, Ma } },
{ "(bad)", { XX } },
- { "psllq", { MS, Ib } },
},
{
- /* OPC_EXT_13 */
+ /* OPC_EXT_34 */
+ { "movlpX", { EXq, XM } },
{ "(bad)", { XX } },
- { PREGRP100 },
},
{
- /* OPC_EXT_14 */
- { "fxsave", { M } },
+ /* OPC_EXT_35 */
+ { "movhpX", { EXq, XM } },
{ "(bad)", { XX } },
},
{
- /* OPC_EXT_15 */
- { "fxrstor", { M } },
- { "(bad)", { XX } },
+ /* OPC_EXT_36 */
+ { "movlpX", { XM, EXq } },
+ { "movhlpX", { XM, EXq } },
},
{
- /* OPC_EXT_16 */
- { "ldmxcsr", { Md } },
- { "(bad)", { XX } },
+ /* OPC_EXT_37 */
+ { "movhpX", { XM, EXq } },
+ { "movlhpX", { XM, EXq } },
},
{
- /* OPC_EXT_17 */
- { "stmxcsr", { Md } },
- { "(bad)", { XX } },
+ /* OPC_EXT_38 */
+ { "invlpg", { Mb } },
+ { OPC_EXT_RM_5 },
},
{
- /* OPC_EXT_18 */
- { "(bad)", { XX } },
- { OPC_EXT_RM_2 },
+ /* OPC_EXT_39 */
+ { "lidt{Q|Q||}", { M } },
+ { OPC_EXT_RM_6 },
},
{
- /* OPC_EXT_19 */
+ /* OPC_EXT_40 */
{ "(bad)", { XX } },
- { OPC_EXT_RM_3 },
+ { "movZ", { Rm, Cm } },
},
{
- /* OPC_EXT_20 */
- { "clflush", { Mb } },
- { OPC_EXT_RM_4 },
+ /* OPC_EXT_41 */
+ { "(bad)", { XX } },
+ { "movZ", { Rm, Dm } },
},
{
- /* OPC_EXT_21 */
- { "prefetchnta", { Mb } },
+ /* OPC_EXT_42 */
{ "(bad)", { XX } },
+ { "movZ", { Cm, Rm } },
},
{
- /* OPC_EXT_22 */
- { "prefetcht0", { Mb } },
+ /* OPC_EXT_43 */
{ "(bad)", { XX } },
+ { "movZ", { Dm, Rm } },
},
{
- /* OPC_EXT_23 */
- { "prefetcht1", { Mb } },
- { "(bad)", { XX } },
+ /* OPC_EXT_44 */
+ { THREE_BYTE_SSE5_0F24 },
+ { "movL", { Rd, Td } },
},
{
- /* OPC_EXT_24 */
- { "prefetcht2", { Mb } },
+ /* OPC_EXT_45 */
{ "(bad)", { XX } },
+ { "movL", { Td, Rd } },
},
};
{ "(bad)", { XX } },
{ "(bad)", { XX } },
},
+ {
+ /* OPC_EXT_RM_5 */
+ { "swapgs", { Skip_MODRM } },
+ { "rdtscp", { Skip_MODRM } },
+ { "(bad)", { XX } },
+ { "(bad)", { XX } },
+ { "(bad)", { XX } },
+ { "(bad)", { XX } },
+ { "(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 _("<internal disassembler error>")
/* 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;
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];
if (dp->name != NULL)
return dp;
else
- return get_valid_dis386 (dp);
+ return get_valid_dis386 (dp, info);
}
static int
names8 = intel_names8;
names8rex = intel_names8rex;
names_seg = intel_names_seg;
+ index64 = intel_index64;
+ index32 = intel_index32;
index16 = intel_index16;
open_char = '[';
close_char = ']';
names8 = att_names8;
names8rex = att_names8rex;
names_seg = att_names_seg;
+ index64 = att_index64;
+ index32 = att_index32;
index16 = att_index16;
open_char = '(';
close_char = ')';
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
{
}
}
- 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;
}
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)
}
static void
-OP_E (int bytemode, int sizeflag)
+OP_E_extended (int bytemode, int sizeflag, int has_drex)
{
bfd_vma disp;
int add = 0;
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)
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:
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)
? 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);
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';
disp = - (bfd_signed_vma) disp;
}
- print_displacement (scratchbuf, disp);
+ if (havedisp)
+ print_displacement (scratchbuf, disp);
+ else
+ print_operand_value (scratchbuf, 1, disp);
oappend (scratchbuf);
}
}
}
+static void
+OP_E (int bytemode, int sizeflag)
+{
+ OP_E_extended (bytemode, sizeflag, 0);
+}
+
+
static void
OP_G (int bytemode, int sizeflag)
{
}
}
-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)
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)
{
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 <sub-opcode> <modrm> <optional-sib> <drex> <offset>.
+
+ The <sub-opcode> 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 <sub-opcode> <modrm> <optional-sib> <drex> <offset> (or)
+ 0f 25 <sub-opcode> <modrm> <optional-sib> <drex> <offset> <cmp-byte>
+
+ 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<xx> 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<xx> 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++;
+ }
+}