summaryrefslogtreecommitdiff
path: root/opcodes/i386-dis.c
diff options
context:
space:
mode:
Diffstat (limited to 'opcodes/i386-dis.c')
-rw-r--r--opcodes/i386-dis.c3193
1 files changed, 1842 insertions, 1351 deletions
diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c
index 19144cb9fc5..3c77a742d76 100644
--- a/opcodes/i386-dis.c
+++ b/opcodes/i386-dis.c
@@ -47,7 +47,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#define UNIXWARE_COMPAT 1
#endif
-
static int fetch_data PARAMS ((struct disassemble_info *, bfd_byte *));
struct dis_private
@@ -59,6 +58,31 @@ struct dis_private
jmp_buf bailout;
};
+/* The opcode for the fwait instruction, which we treat as a prefix
+ when we can. */
+#define FWAIT_OPCODE (0x9b)
+
+/* Flags for the prefixes for the current instruction. See below. */
+static int prefixes;
+
+/* Flags for prefixes which we somehow handled when printing the
+ current instruction. */
+static int used_prefixes;
+
+/* Flags stored in PREFIXES. */
+#define PREFIX_REPZ 1
+#define PREFIX_REPNZ 2
+#define PREFIX_LOCK 4
+#define PREFIX_CS 8
+#define PREFIX_SS 0x10
+#define PREFIX_DS 0x20
+#define PREFIX_ES 0x40
+#define PREFIX_FS 0x80
+#define PREFIX_GS 0x100
+#define PREFIX_DATA 0x200
+#define PREFIX_ADDR 0x400
+#define PREFIX_FWAIT 0x800
+
/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
to ADDR (exclusive) are valid. Returns 1 for success, longjmps
on error. */
@@ -81,7 +105,12 @@ fetch_data (info, addr)
info);
if (status != 0)
{
- (*info->memory_error_func) (status, start, info);
+ /* If we did manage to read at least one byte, then
+ print_insn_i386 will do something sensible. Otherwise, print
+ an error. We do that here because this is where we know
+ STATUS. */
+ if (priv->max_fetched == priv->the_buffer)
+ (*info->memory_error_func) (status, start, info);
longjmp (priv->bailout, 1);
}
else
@@ -89,28 +118,27 @@ fetch_data (info, addr)
return 1;
}
+#define XX NULL, 0
+
#define Eb OP_E, b_mode
#define indirEb OP_indirE, b_mode
#define Gb OP_G, b_mode
#define Ev OP_E, v_mode
+#define Ed OP_E, d_mode
#define indirEv OP_indirE, v_mode
#define Ew OP_E, w_mode
#define Ma OP_E, v_mode
-#define M OP_E, 0
-#define Mp OP_E, 0 /* ? */
+#define M OP_E, 0 /* lea */
+#define Mp OP_E, 0 /* 32 or 48 bit memory operand for LDS, LES etc */
#define Gv OP_G, v_mode
#define Gw OP_G, w_mode
-#define Rw OP_rm, w_mode
-#define Rd OP_rm, d_mode
+#define Rd OP_Rd, d_mode
#define Ib OP_I, b_mode
#define sIb OP_sI, b_mode /* sign extened byte */
#define Iv OP_I, v_mode
#define Iw OP_I, w_mode
#define Jb OP_J, b_mode
#define Jv OP_J, v_mode
-#if 0
-#define ONE OP_ONE, 0
-#endif
#define Cd OP_C, d_mode
#define Dd OP_D, d_mode
#define Td OP_T, d_mode
@@ -136,8 +164,7 @@ fetch_data (info, addr)
#define indirDX OP_REG, indir_dx_reg
#define Sw OP_SEG, w_mode
-#define Ap OP_DIR, lptr
-#define Av OP_DIR, v_mode
+#define Ap OP_DIR, 0
#define Ob OP_OFF, b_mode
#define Ov OP_OFF, v_mode
#define Xb OP_DSreg, eSI_reg
@@ -154,9 +181,13 @@ fetch_data (info, addr)
#define gs OP_REG, gs_reg
#define MX OP_MMX, 0
+#define XM OP_XMM, 0
#define EM OP_EM, v_mode
-#define MS OP_MS, b_mode
+#define EX OP_EX, v_mode
+#define MS OP_MS, v_mode
+#define None OP_E, 0
#define OPSUF OP_3DNowSuffix, 0
+#define OPSIMD OP_SIMD_Suffix, 0
/* bits in sizeflag */
#if 0 /* leave undefined until someone adds the extra flag to objdump */
@@ -165,7 +196,7 @@ fetch_data (info, addr)
#define AFLAG 2
#define DFLAG 1
-typedef void (*op_rtn) PARAMS ((int bytemode, int sizeflag ));
+typedef void (*op_rtn) PARAMS ((int bytemode, int sizeflag));
static void OP_E PARAMS ((int, int));
static void OP_G PARAMS ((int, int));
@@ -182,25 +213,28 @@ static void OP_SEG PARAMS ((int, int));
static void OP_C PARAMS ((int, int));
static void OP_D PARAMS ((int, int));
static void OP_T PARAMS ((int, int));
-static void OP_rm PARAMS ((int, int));
+static void OP_Rd PARAMS ((int, int));
static void OP_ST PARAMS ((int, int));
static void OP_STi PARAMS ((int, int));
-#if 0
-static void OP_ONE PARAMS ((int, int));
-#endif
static void OP_MMX PARAMS ((int, int));
+static void OP_XMM PARAMS ((int, int));
static void OP_EM PARAMS ((int, int));
+static void OP_EX PARAMS ((int, int));
static void OP_MS PARAMS ((int, int));
static void OP_3DNowSuffix PARAMS ((int, int));
+static void OP_SIMD_Suffix PARAMS ((int, int));
+static void SIMD_Fixup PARAMS ((int, int));
static void append_seg PARAMS ((void));
static void set_op PARAMS ((unsigned int op));
-static void putop PARAMS ((char *template, int sizeflag));
+static void putop PARAMS ((const char *template, int sizeflag));
static void dofloat PARAMS ((int sizeflag));
static int get16 PARAMS ((void));
static int get32 PARAMS ((void));
static void ckprefix PARAMS ((void));
+static const char *prefix_name PARAMS ((int, int));
static void ptr_reg PARAMS ((int, int));
+static void BadOp PARAMS ((void));
#define b_mode 1
#define v_mode 2
@@ -214,16 +248,15 @@ static void ptr_reg PARAMS ((int, int));
#define ds_reg 103
#define fs_reg 104
#define gs_reg 105
-#define eAX_reg 107
-#define eCX_reg 108
-#define eDX_reg 109
-#define eBX_reg 110
-#define eSP_reg 111
-#define eBP_reg 112
-#define eSI_reg 113
-#define eDI_reg 114
-#define lptr 115
+#define eAX_reg 108
+#define eCX_reg 109
+#define eDX_reg 110
+#define eBX_reg 111
+#define eSP_reg 112
+#define eBP_reg 113
+#define eSI_reg 114
+#define eDI_reg 115
#define al_reg 116
#define cl_reg 117
@@ -245,34 +278,54 @@ static void ptr_reg PARAMS ((int, int));
#define indir_dx_reg 150
-#define GRP1b NULL, NULL, 0
-#define GRP1S NULL, NULL, 1
-#define GRP1Ss NULL, NULL, 2
-#define GRP2b NULL, NULL, 3
-#define GRP2S NULL, NULL, 4
-#define GRP2b_one NULL, NULL, 5
-#define GRP2S_one NULL, NULL, 6
-#define GRP2b_cl NULL, NULL, 7
-#define GRP2S_cl NULL, NULL, 8
-#define GRP3b NULL, NULL, 9
-#define GRP3S NULL, NULL, 10
-#define GRP4 NULL, NULL, 11
-#define GRP5 NULL, NULL, 12
-#define GRP6 NULL, NULL, 13
-#define GRP7 NULL, NULL, 14
-#define GRP8 NULL, NULL, 15
-#define GRP9 NULL, NULL, 16
-#define GRP10 NULL, NULL, 17
-#define GRP11 NULL, NULL, 18
-#define GRP12 NULL, NULL, 19
-#define GRP13 NULL, NULL, 20
-#define GRP14 NULL, NULL, 21
+#define USE_GROUPS 1
+#define USE_PREFIX_USER_TABLE 2
+
+#define GRP1b NULL, NULL, 0, NULL, USE_GROUPS, NULL, 0
+#define GRP1S NULL, NULL, 1, NULL, USE_GROUPS, NULL, 0
+#define GRP1Ss NULL, NULL, 2, NULL, USE_GROUPS, NULL, 0
+#define GRP2b NULL, NULL, 3, NULL, USE_GROUPS, NULL, 0
+#define GRP2S NULL, NULL, 4, NULL, USE_GROUPS, NULL, 0
+#define GRP2b_one NULL, NULL, 5, NULL, USE_GROUPS, NULL, 0
+#define GRP2S_one NULL, NULL, 6, NULL, USE_GROUPS, NULL, 0
+#define GRP2b_cl NULL, NULL, 7, NULL, USE_GROUPS, NULL, 0
+#define GRP2S_cl NULL, NULL, 8, NULL, USE_GROUPS, NULL, 0
+#define GRP3b NULL, NULL, 9, NULL, USE_GROUPS, NULL, 0
+#define GRP3S NULL, NULL, 10, NULL, USE_GROUPS, NULL, 0
+#define GRP4 NULL, NULL, 11, NULL, USE_GROUPS, NULL, 0
+#define GRP5 NULL, NULL, 12, NULL, USE_GROUPS, NULL, 0
+#define GRP6 NULL, NULL, 13, NULL, USE_GROUPS, NULL, 0
+#define GRP7 NULL, NULL, 14, NULL, USE_GROUPS, NULL, 0
+#define GRP8 NULL, NULL, 15, NULL, USE_GROUPS, NULL, 0
+#define GRP9 NULL, NULL, 16, NULL, USE_GROUPS, NULL, 0
+#define GRP10 NULL, NULL, 17, NULL, USE_GROUPS, NULL, 0
+#define GRP11 NULL, NULL, 18, NULL, USE_GROUPS, NULL, 0
+#define GRP12 NULL, NULL, 19, NULL, USE_GROUPS, NULL, 0
+#define GRP13 NULL, NULL, 20, NULL, USE_GROUPS, NULL, 0
+#define GRP14 NULL, NULL, 21, NULL, USE_GROUPS, NULL, 0
+#define GRPAMD NULL, NULL, 22, NULL, USE_GROUPS, NULL, 0
+
+#define PREGRP0 NULL, NULL, 0, NULL, USE_PREFIX_USER_TABLE, NULL, 0
+#define PREGRP1 NULL, NULL, 1, NULL, USE_PREFIX_USER_TABLE, NULL, 0
+#define PREGRP2 NULL, NULL, 2, NULL, USE_PREFIX_USER_TABLE, NULL, 0
+#define PREGRP3 NULL, NULL, 3, NULL, USE_PREFIX_USER_TABLE, NULL, 0
+#define PREGRP4 NULL, NULL, 4, NULL, USE_PREFIX_USER_TABLE, NULL, 0
+#define PREGRP5 NULL, NULL, 5, NULL, USE_PREFIX_USER_TABLE, NULL, 0
+#define PREGRP6 NULL, NULL, 6, NULL, USE_PREFIX_USER_TABLE, NULL, 0
+#define PREGRP7 NULL, NULL, 7, NULL, USE_PREFIX_USER_TABLE, NULL, 0
+#define PREGRP8 NULL, NULL, 8, NULL, USE_PREFIX_USER_TABLE, NULL, 0
+#define PREGRP9 NULL, NULL, 9, NULL, USE_PREFIX_USER_TABLE, NULL, 0
+#define PREGRP10 NULL, NULL, 10, NULL, USE_PREFIX_USER_TABLE, NULL, 0
+#define PREGRP11 NULL, NULL, 11, NULL, USE_PREFIX_USER_TABLE, NULL, 0
+#define PREGRP12 NULL, NULL, 12, NULL, USE_PREFIX_USER_TABLE, NULL, 0
+#define PREGRP13 NULL, NULL, 13, NULL, USE_PREFIX_USER_TABLE, NULL, 0
+#define PREGRP14 NULL, NULL, 14, NULL, USE_PREFIX_USER_TABLE, NULL, 0
#define FLOATCODE 50
-#define FLOAT NULL, NULL, FLOATCODE
+#define FLOAT NULL, NULL, FLOATCODE, NULL, 0, NULL, 0
struct dis386 {
- char *name;
+ const char *name;
op_rtn op1;
int bytemode1;
op_rtn op2;
@@ -290,255 +343,255 @@ struct dis386 {
'P' => print 'w' or 'l' if instruction has an operand size prefix,
or suffix_always is true
'Q' => print 'w' or 'l' if no register operands or suffix_always is true
- 'R' => print 'w' or 'l'
+ 'R' => print 'w' or 'l' ("wd" or "dq" in intel mode)
'S' => print 'w' or 'l' if suffix_always is true
- 'W' => print 'b' or 'w'
+ 'W' => print 'b' or 'w' ("w" or "de" in intel mode)
*/
-static struct dis386 dis386_att[] = {
+static const struct dis386 dis386_att[] = {
/* 00 */
- { "addB", Eb, Gb },
- { "addS", Ev, Gv },
- { "addB", Gb, Eb },
- { "addS", Gv, Ev },
- { "addB", AL, Ib },
- { "addS", eAX, Iv },
- { "pushP", es },
- { "popP", es },
+ { "addB", Eb, Gb, XX },
+ { "addS", Ev, Gv, XX },
+ { "addB", Gb, Eb, XX },
+ { "addS", Gv, Ev, XX },
+ { "addB", AL, Ib, XX },
+ { "addS", eAX, Iv, XX },
+ { "pushP", es, XX, XX },
+ { "popP", es, XX, XX },
/* 08 */
- { "orB", Eb, Gb },
- { "orS", Ev, Gv },
- { "orB", Gb, Eb },
- { "orS", Gv, Ev },
- { "orB", AL, Ib },
- { "orS", eAX, Iv },
- { "pushP", cs },
- { "(bad)" }, /* 0x0f extended opcode escape */
+ { "orB", Eb, Gb, XX },
+ { "orS", Ev, Gv, XX },
+ { "orB", Gb, Eb, XX },
+ { "orS", Gv, Ev, XX },
+ { "orB", AL, Ib, XX },
+ { "orS", eAX, Iv, XX },
+ { "pushP", cs, XX, XX },
+ { "(bad)", XX, XX, XX }, /* 0x0f extended opcode escape */
/* 10 */
- { "adcB", Eb, Gb },
- { "adcS", Ev, Gv },
- { "adcB", Gb, Eb },
- { "adcS", Gv, Ev },
- { "adcB", AL, Ib },
- { "adcS", eAX, Iv },
- { "pushP", ss },
- { "popP", ss },
+ { "adcB", Eb, Gb, XX },
+ { "adcS", Ev, Gv, XX },
+ { "adcB", Gb, Eb, XX },
+ { "adcS", Gv, Ev, XX },
+ { "adcB", AL, Ib, XX },
+ { "adcS", eAX, Iv, XX },
+ { "pushP", ss, XX, XX },
+ { "popP", ss, XX, XX },
/* 18 */
- { "sbbB", Eb, Gb },
- { "sbbS", Ev, Gv },
- { "sbbB", Gb, Eb },
- { "sbbS", Gv, Ev },
- { "sbbB", AL, Ib },
- { "sbbS", eAX, Iv },
- { "pushP", ds },
- { "popP", ds },
+ { "sbbB", Eb, Gb, XX },
+ { "sbbS", Ev, Gv, XX },
+ { "sbbB", Gb, Eb, XX },
+ { "sbbS", Gv, Ev, XX },
+ { "sbbB", AL, Ib, XX },
+ { "sbbS", eAX, Iv, XX },
+ { "pushP", ds, XX, XX },
+ { "popP", ds, XX, XX },
/* 20 */
- { "andB", Eb, Gb },
- { "andS", Ev, Gv },
- { "andB", Gb, Eb },
- { "andS", Gv, Ev },
- { "andB", AL, Ib },
- { "andS", eAX, Iv },
- { "(bad)" }, /* SEG ES prefix */
- { "daa" },
+ { "andB", Eb, Gb, XX },
+ { "andS", Ev, Gv, XX },
+ { "andB", Gb, Eb, XX },
+ { "andS", Gv, Ev, XX },
+ { "andB", AL, Ib, XX },
+ { "andS", eAX, Iv, XX },
+ { "(bad)", XX, XX, XX }, /* SEG ES prefix */
+ { "daa", XX, XX, XX },
/* 28 */
- { "subB", Eb, Gb },
- { "subS", Ev, Gv },
- { "subB", Gb, Eb },
- { "subS", Gv, Ev },
- { "subB", AL, Ib },
- { "subS", eAX, Iv },
- { "(bad)" }, /* SEG CS prefix */
- { "das" },
+ { "subB", Eb, Gb, XX },
+ { "subS", Ev, Gv, XX },
+ { "subB", Gb, Eb, XX },
+ { "subS", Gv, Ev, XX },
+ { "subB", AL, Ib, XX },
+ { "subS", eAX, Iv, XX },
+ { "(bad)", XX, XX, XX }, /* SEG CS prefix */
+ { "das", XX, XX, XX },
/* 30 */
- { "xorB", Eb, Gb },
- { "xorS", Ev, Gv },
- { "xorB", Gb, Eb },
- { "xorS", Gv, Ev },
- { "xorB", AL, Ib },
- { "xorS", eAX, Iv },
- { "(bad)" }, /* SEG SS prefix */
- { "aaa" },
+ { "xorB", Eb, Gb, XX },
+ { "xorS", Ev, Gv, XX },
+ { "xorB", Gb, Eb, XX },
+ { "xorS", Gv, Ev, XX },
+ { "xorB", AL, Ib, XX },
+ { "xorS", eAX, Iv, XX },
+ { "(bad)", XX, XX, XX }, /* SEG SS prefix */
+ { "aaa", XX, XX, XX },
/* 38 */
- { "cmpB", Eb, Gb },
- { "cmpS", Ev, Gv },
- { "cmpB", Gb, Eb },
- { "cmpS", Gv, Ev },
- { "cmpB", AL, Ib },
- { "cmpS", eAX, Iv },
- { "(bad)" }, /* SEG DS prefix */
- { "aas" },
+ { "cmpB", Eb, Gb, XX },
+ { "cmpS", Ev, Gv, XX },
+ { "cmpB", Gb, Eb, XX },
+ { "cmpS", Gv, Ev, XX },
+ { "cmpB", AL, Ib, XX },
+ { "cmpS", eAX, Iv, XX },
+ { "(bad)", XX, XX, XX }, /* SEG DS prefix */
+ { "aas", XX, XX, XX },
/* 40 */
- { "incS", eAX },
- { "incS", eCX },
- { "incS", eDX },
- { "incS", eBX },
- { "incS", eSP },
- { "incS", eBP },
- { "incS", eSI },
- { "incS", eDI },
+ { "incS", eAX, XX, XX },
+ { "incS", eCX, XX, XX },
+ { "incS", eDX, XX, XX },
+ { "incS", eBX, XX, XX },
+ { "incS", eSP, XX, XX },
+ { "incS", eBP, XX, XX },
+ { "incS", eSI, XX, XX },
+ { "incS", eDI, XX, XX },
/* 48 */
- { "decS", eAX },
- { "decS", eCX },
- { "decS", eDX },
- { "decS", eBX },
- { "decS", eSP },
- { "decS", eBP },
- { "decS", eSI },
- { "decS", eDI },
+ { "decS", eAX, XX, XX },
+ { "decS", eCX, XX, XX },
+ { "decS", eDX, XX, XX },
+ { "decS", eBX, XX, XX },
+ { "decS", eSP, XX, XX },
+ { "decS", eBP, XX, XX },
+ { "decS", eSI, XX, XX },
+ { "decS", eDI, XX, XX },
/* 50 */
- { "pushS", eAX },
- { "pushS", eCX },
- { "pushS", eDX },
- { "pushS", eBX },
- { "pushS", eSP },
- { "pushS", eBP },
- { "pushS", eSI },
- { "pushS", eDI },
+ { "pushS", eAX, XX, XX },
+ { "pushS", eCX, XX, XX },
+ { "pushS", eDX, XX, XX },
+ { "pushS", eBX, XX, XX },
+ { "pushS", eSP, XX, XX },
+ { "pushS", eBP, XX, XX },
+ { "pushS", eSI, XX, XX },
+ { "pushS", eDI, XX, XX },
/* 58 */
- { "popS", eAX },
- { "popS", eCX },
- { "popS", eDX },
- { "popS", eBX },
- { "popS", eSP },
- { "popS", eBP },
- { "popS", eSI },
- { "popS", eDI },
+ { "popS", eAX, XX, XX },
+ { "popS", eCX, XX, XX },
+ { "popS", eDX, XX, XX },
+ { "popS", eBX, XX, XX },
+ { "popS", eSP, XX, XX },
+ { "popS", eBP, XX, XX },
+ { "popS", eSI, XX, XX },
+ { "popS", eDI, XX, XX },
/* 60 */
- { "pushaP" },
- { "popaP" },
- { "boundS", Gv, Ma },
- { "arpl", Ew, Gw },
- { "(bad)" }, /* seg fs */
- { "(bad)" }, /* seg gs */
- { "(bad)" }, /* op size prefix */
- { "(bad)" }, /* adr size prefix */
+ { "pushaP", XX, XX, XX },
+ { "popaP", XX, XX, XX },
+ { "boundS", Gv, Ma, XX },
+ { "arpl", Ew, Gw, XX },
+ { "(bad)", XX, XX, XX }, /* seg fs */
+ { "(bad)", XX, XX, XX }, /* seg gs */
+ { "(bad)", XX, XX, XX }, /* op size prefix */
+ { "(bad)", XX, XX, XX }, /* adr size prefix */
/* 68 */
- { "pushP", Iv }, /* 386 book wrong */
+ { "pushP", Iv, XX, XX }, /* 386 book wrong */
{ "imulS", Gv, Ev, Iv },
- { "pushP", sIb }, /* push of byte really pushes 2 or 4 bytes */
+ { "pushP", sIb, XX, XX }, /* push of byte really pushes 2 or 4 bytes */
{ "imulS", Gv, Ev, sIb },
- { "insb", Yb, indirDX },
- { "insR", Yv, indirDX },
- { "outsb", indirDX, Xb },
- { "outsR", indirDX, Xv },
+ { "insb", Yb, indirDX, XX },
+ { "insR", Yv, indirDX, XX },
+ { "outsb", indirDX, Xb, XX },
+ { "outsR", indirDX, Xv, XX },
/* 70 */
- { "jo", Jb },
- { "jno", Jb },
- { "jb", Jb },
- { "jae", Jb },
- { "je", Jb },
- { "jne", Jb },
- { "jbe", Jb },
- { "ja", Jb },
+ { "jo", Jb, XX, XX },
+ { "jno", Jb, XX, XX },
+ { "jb", Jb, XX, XX },
+ { "jae", Jb, XX, XX },
+ { "je", Jb, XX, XX },
+ { "jne", Jb, XX, XX },
+ { "jbe", Jb, XX, XX },
+ { "ja", Jb, XX, XX },
/* 78 */
- { "js", Jb },
- { "jns", Jb },
- { "jp", Jb },
- { "jnp", Jb },
- { "jl", Jb },
- { "jge", Jb },
- { "jle", Jb },
- { "jg", Jb },
+ { "js", Jb, XX, XX },
+ { "jns", Jb, XX, XX },
+ { "jp", Jb, XX, XX },
+ { "jnp", Jb, XX, XX },
+ { "jl", Jb, XX, XX },
+ { "jge", Jb, XX, XX },
+ { "jle", Jb, XX, XX },
+ { "jg", Jb, XX, XX },
/* 80 */
{ GRP1b },
{ GRP1S },
- { "(bad)" },
+ { "(bad)", XX, XX, XX },
{ GRP1Ss },
- { "testB", Eb, Gb },
- { "testS", Ev, Gv },
- { "xchgB", Eb, Gb },
- { "xchgS", Ev, Gv },
+ { "testB", Eb, Gb, XX },
+ { "testS", Ev, Gv, XX },
+ { "xchgB", Eb, Gb, XX },
+ { "xchgS", Ev, Gv, XX },
/* 88 */
- { "movB", Eb, Gb },
- { "movS", Ev, Gv },
- { "movB", Gb, Eb },
- { "movS", Gv, Ev },
- { "movQ", Ev, Sw },
- { "leaS", Gv, M },
- { "movQ", Sw, Ev },
- { "popQ", Ev },
+ { "movB", Eb, Gb, XX },
+ { "movS", Ev, Gv, XX },
+ { "movB", Gb, Eb, XX },
+ { "movS", Gv, Ev, XX },
+ { "movQ", Ev, Sw, XX },
+ { "leaS", Gv, M, XX },
+ { "movQ", Sw, Ev, XX },
+ { "popQ", Ev, XX, XX },
/* 90 */
- { "nop" },
- { "xchgS", eCX, eAX },
- { "xchgS", eDX, eAX },
- { "xchgS", eBX, eAX },
- { "xchgS", eSP, eAX },
- { "xchgS", eBP, eAX },
- { "xchgS", eSI, eAX },
- { "xchgS", eDI, eAX },
+ { "nop", XX, XX, XX },
+ { "xchgS", eCX, eAX, XX },
+ { "xchgS", eDX, eAX, XX },
+ { "xchgS", eBX, eAX, XX },
+ { "xchgS", eSP, eAX, XX },
+ { "xchgS", eBP, eAX, XX },
+ { "xchgS", eSI, eAX, XX },
+ { "xchgS", eDI, eAX, XX },
/* 98 */
- { "cWtR" },
- { "cRtd" },
- { "lcallP", Ap },
- { "(bad)" }, /* fwait */
- { "pushfP" },
- { "popfP" },
- { "sahf" },
- { "lahf" },
+ { "cWtR", XX, XX, XX },
+ { "cRtd", XX, XX, XX },
+ { "lcallP", Ap, XX, XX },
+ { "(bad)", XX, XX, XX }, /* fwait */
+ { "pushfP", XX, XX, XX },
+ { "popfP", XX, XX, XX },
+ { "sahf", XX, XX, XX },
+ { "lahf", XX, XX, XX },
/* a0 */
- { "movB", AL, Ob },
- { "movS", eAX, Ov },
- { "movB", Ob, AL },
- { "movS", Ov, eAX },
- { "movsb", Yb, Xb },
- { "movsR", Yv, Xv },
- { "cmpsb", Xb, Yb },
- { "cmpsR", Xv, Yv },
+ { "movB", AL, Ob, XX },
+ { "movS", eAX, Ov, XX },
+ { "movB", Ob, AL, XX },
+ { "movS", Ov, eAX, XX },
+ { "movsb", Yb, Xb, XX },
+ { "movsR", Yv, Xv, XX },
+ { "cmpsb", Xb, Yb, XX },
+ { "cmpsR", Xv, Yv, XX },
/* a8 */
- { "testB", AL, Ib },
- { "testS", eAX, Iv },
- { "stosB", Yb, AL },
- { "stosS", Yv, eAX },
- { "lodsB", AL, Xb },
- { "lodsS", eAX, Xv },
- { "scasB", AL, Yb },
- { "scasS", eAX, Yv },
+ { "testB", AL, Ib, XX },
+ { "testS", eAX, Iv, XX },
+ { "stosB", Yb, AL, XX },
+ { "stosS", Yv, eAX, XX },
+ { "lodsB", AL, Xb, XX },
+ { "lodsS", eAX, Xv, XX },
+ { "scasB", AL, Yb, XX },
+ { "scasS", eAX, Yv, XX },
/* b0 */
- { "movB", AL, Ib },
- { "movB", CL, Ib },
- { "movB", DL, Ib },
- { "movB", BL, Ib },
- { "movB", AH, Ib },
- { "movB", CH, Ib },
- { "movB", DH, Ib },
- { "movB", BH, Ib },
+ { "movB", AL, Ib, XX },
+ { "movB", CL, Ib, XX },
+ { "movB", DL, Ib, XX },
+ { "movB", BL, Ib, XX },
+ { "movB", AH, Ib, XX },
+ { "movB", CH, Ib, XX },
+ { "movB", DH, Ib, XX },
+ { "movB", BH, Ib, XX },
/* b8 */
- { "movS", eAX, Iv },
- { "movS", eCX, Iv },
- { "movS", eDX, Iv },
- { "movS", eBX, Iv },
- { "movS", eSP, Iv },
- { "movS", eBP, Iv },
- { "movS", eSI, Iv },
- { "movS", eDI, Iv },
+ { "movS", eAX, Iv, XX },
+ { "movS", eCX, Iv, XX },
+ { "movS", eDX, Iv, XX },
+ { "movS", eBX, Iv, XX },
+ { "movS", eSP, Iv, XX },
+ { "movS", eBP, Iv, XX },
+ { "movS", eSI, Iv, XX },
+ { "movS", eDI, Iv, XX },
/* c0 */
{ GRP2b },
{ GRP2S },
- { "retP", Iw },
- { "retP" },
- { "lesS", Gv, Mp },
- { "ldsS", Gv, Mp },
- { "movA", Eb, Ib },
- { "movQ", Ev, Iv },
+ { "retP", Iw, XX, XX },
+ { "retP", XX, XX, XX },
+ { "lesS", Gv, Mp, XX },
+ { "ldsS", Gv, Mp, XX },
+ { "movA", Eb, Ib, XX },
+ { "movQ", Ev, Iv, XX },
/* c8 */
- { "enterP", Iw, Ib },
- { "leaveP" },
- { "lretP", Iw },
- { "lretP" },
- { "int3" },
- { "int", Ib },
- { "into" },
- { "iretP" },
+ { "enterP", Iw, Ib, XX },
+ { "leaveP", XX, XX, XX },
+ { "lretP", Iw, XX, XX },
+ { "lretP", XX, XX, XX },
+ { "int3", XX, XX, XX },
+ { "int", Ib, XX, XX },
+ { "into", XX, XX, XX},
+ { "iretP", XX, XX, XX },
/* d0 */
{ GRP2b_one },
{ GRP2S_one },
{ GRP2b_cl },
{ GRP2S_cl },
- { "aam", sIb },
- { "aad", sIb },
- { "(bad)" },
- { "xlat", DSBX },
+ { "aam", sIb, XX, XX },
+ { "aad", sIb, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "xlat", DSBX, XX, XX },
/* d8 */
{ FLOAT },
{ FLOAT },
@@ -549,287 +602,287 @@ static struct dis386 dis386_att[] = {
{ FLOAT },
{ FLOAT },
/* e0 */
- { "loopne", Jb },
- { "loope", Jb },
- { "loop", Jb },
- { "jEcxz", Jb },
- { "inB", AL, Ib },
- { "inS", eAX, Ib },
- { "outB", Ib, AL },
- { "outS", Ib, eAX },
+ { "loopne", Jb, XX, XX },
+ { "loope", Jb, XX, XX },
+ { "loop", Jb, XX, XX },
+ { "jEcxz", Jb, XX, XX },
+ { "inB", AL, Ib, XX },
+ { "inS", eAX, Ib, XX },
+ { "outB", Ib, AL, XX },
+ { "outS", Ib, eAX, XX },
/* e8 */
- { "callP", Av },
- { "jmpP", Jv },
- { "ljmpP", Ap },
- { "jmp", Jb },
- { "inB", AL, indirDX },
- { "inS", eAX, indirDX },
- { "outB", indirDX, AL },
- { "outS", indirDX, eAX },
+ { "callP", Jv, XX, XX },
+ { "jmpP", Jv, XX, XX },
+ { "ljmpP", Ap, XX, XX },
+ { "jmp", Jb, XX, XX },
+ { "inB", AL, indirDX, XX },
+ { "inS", eAX, indirDX, XX },
+ { "outB", indirDX, AL, XX },
+ { "outS", indirDX, eAX, XX },
/* f0 */
- { "(bad)" }, /* lock prefix */
- { "(bad)" },
- { "(bad)" }, /* repne */
- { "(bad)" }, /* repz */
- { "hlt" },
- { "cmc" },
+ { "(bad)", XX, XX, XX }, /* lock prefix */
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX }, /* repne */
+ { "(bad)", XX, XX, XX }, /* repz */
+ { "hlt", XX, XX, XX },
+ { "cmc", XX, XX, XX },
{ GRP3b },
{ GRP3S },
/* f8 */
- { "clc" },
- { "stc" },
- { "cli" },
- { "sti" },
- { "cld" },
- { "std" },
+ { "clc", XX, XX, XX },
+ { "stc", XX, XX, XX },
+ { "cli", XX, XX, XX },
+ { "sti", XX, XX, XX },
+ { "cld", XX, XX, XX },
+ { "std", XX, XX, XX },
{ GRP4 },
{ GRP5 },
};
-static struct dis386 dis386_intel[] = {
+static const struct dis386 dis386_intel[] = {
/* 00 */
- { "addB", Eb, Gb },
- { "addS", Ev, Gv },
- { "addB", Gb, Eb },
- { "addS", Gv, Ev },
- { "addB", AL, Ib },
- { "addS", eAX, Iv },
- { "pushP", es },
- { "popP", es },
+ { "add", Eb, Gb, XX },
+ { "add", Ev, Gv, XX },
+ { "add", Gb, Eb, XX },
+ { "add", Gv, Ev, XX },
+ { "add", AL, Ib, XX },
+ { "add", eAX, Iv, XX },
+ { "push", es, XX, XX },
+ { "pop", es, XX, XX },
/* 08 */
- { "orB", Eb, Gb },
- { "orS", Ev, Gv },
- { "orB", Gb, Eb },
- { "orS", Gv, Ev },
- { "orB", AL, Ib },
- { "orS", eAX, Iv },
- { "pushP", cs },
- { "(bad)" }, /* 0x0f extended opcode escape */
+ { "or", Eb, Gb, XX },
+ { "or", Ev, Gv, XX },
+ { "or", Gb, Eb, XX },
+ { "or", Gv, Ev, XX },
+ { "or", AL, Ib, XX },
+ { "or", eAX, Iv, XX },
+ { "push", cs, XX, XX },
+ { "(bad)", XX, XX, XX }, /* 0x0f extended opcode escape */
/* 10 */
- { "adcB", Eb, Gb },
- { "adcS", Ev, Gv },
- { "adcB", Gb, Eb },
- { "adcS", Gv, Ev },
- { "adcB", AL, Ib },
- { "adcS", eAX, Iv },
- { "pushP", ss },
- { "popP", ss },
+ { "adc", Eb, Gb, XX },
+ { "adc", Ev, Gv, XX },
+ { "adc", Gb, Eb, XX },
+ { "adc", Gv, Ev, XX },
+ { "adc", AL, Ib, XX },
+ { "adc", eAX, Iv, XX },
+ { "push", ss, XX, XX },
+ { "pop", ss, XX, XX },
/* 18 */
- { "sbbB", Eb, Gb },
- { "sbbS", Ev, Gv },
- { "sbbB", Gb, Eb },
- { "sbbS", Gv, Ev },
- { "sbbB", AL, Ib },
- { "sbbS", eAX, Iv },
- { "pushP", ds },
- { "popP", ds },
+ { "sbb", Eb, Gb, XX },
+ { "sbb", Ev, Gv, XX },
+ { "sbb", Gb, Eb, XX },
+ { "sbb", Gv, Ev, XX },
+ { "sbb", AL, Ib, XX },
+ { "sbb", eAX, Iv, XX },
+ { "push", ds, XX, XX },
+ { "pop", ds, XX, XX },
/* 20 */
- { "andB", Eb, Gb },
- { "andS", Ev, Gv },
- { "andB", Gb, Eb },
- { "andS", Gv, Ev },
- { "andB", AL, Ib },
- { "andS", eAX, Iv },
- { "(bad)" }, /* SEG ES prefix */
- { "daa" },
+ { "and", Eb, Gb, XX },
+ { "and", Ev, Gv, XX },
+ { "and", Gb, Eb, XX },
+ { "and", Gv, Ev, XX },
+ { "and", AL, Ib, XX },
+ { "and", eAX, Iv, XX },
+ { "(bad)", XX, XX, XX }, /* SEG ES prefix */
+ { "daa", XX, XX, XX },
/* 28 */
- { "subB", Eb, Gb },
- { "subS", Ev, Gv },
- { "subB", Gb, Eb },
- { "subS", Gv, Ev },
- { "subB", AL, Ib },
- { "subS", eAX, Iv },
- { "(bad)" }, /* SEG CS prefix */
- { "das" },
+ { "sub", Eb, Gb, XX },
+ { "sub", Ev, Gv, XX },
+ { "sub", Gb, Eb, XX },
+ { "sub", Gv, Ev, XX },
+ { "sub", AL, Ib, XX },
+ { "sub", eAX, Iv, XX },
+ { "(bad)", XX, XX, XX }, /* SEG CS prefix */
+ { "das", XX, XX, XX },
/* 30 */
- { "xorB", Eb, Gb },
- { "xorS", Ev, Gv },
- { "xorB", Gb, Eb },
- { "xorS", Gv, Ev },
- { "xorB", AL, Ib },
- { "xorS", eAX, Iv },
- { "(bad)" }, /* SEG SS prefix */
- { "aaa" },
+ { "xor", Eb, Gb, XX },
+ { "xor", Ev, Gv, XX },
+ { "xor", Gb, Eb, XX },
+ { "xor", Gv, Ev, XX },
+ { "xor", AL, Ib, XX },
+ { "xor", eAX, Iv, XX },
+ { "(bad)", XX, XX, XX }, /* SEG SS prefix */
+ { "aaa", XX, XX, XX },
/* 38 */
- { "cmpB", Eb, Gb },
- { "cmpS", Ev, Gv },
- { "cmpB", Gb, Eb },
- { "cmpS", Gv, Ev },
- { "cmpB", AL, Ib },
- { "cmpS", eAX, Iv },
- { "(bad)" }, /* SEG DS prefix */
- { "aas" },
+ { "cmp", Eb, Gb, XX },
+ { "cmp", Ev, Gv, XX },
+ { "cmp", Gb, Eb, XX },
+ { "cmp", Gv, Ev, XX },
+ { "cmp", AL, Ib, XX },
+ { "cmp", eAX, Iv, XX },
+ { "(bad)", XX, XX, XX }, /* SEG DS prefix */
+ { "aas", XX, XX, XX },
/* 40 */
- { "incS", eAX },
- { "incS", eCX },
- { "incS", eDX },
- { "incS", eBX },
- { "incS", eSP },
- { "incS", eBP },
- { "incS", eSI },
- { "incS", eDI },
+ { "inc", eAX, XX, XX },
+ { "inc", eCX, XX, XX },
+ { "inc", eDX, XX, XX },
+ { "inc", eBX, XX, XX },
+ { "inc", eSP, XX, XX },
+ { "inc", eBP, XX, XX },
+ { "inc", eSI, XX, XX },
+ { "inc", eDI, XX, XX },
/* 48 */
- { "decS", eAX },
- { "decS", eCX },
- { "decS", eDX },
- { "decS", eBX },
- { "decS", eSP },
- { "decS", eBP },
- { "decS", eSI },
- { "decS", eDI },
+ { "dec", eAX, XX, XX },
+ { "dec", eCX, XX, XX },
+ { "dec", eDX, XX, XX },
+ { "dec", eBX, XX, XX },
+ { "dec", eSP, XX, XX },
+ { "dec", eBP, XX, XX },
+ { "dec", eSI, XX, XX },
+ { "dec", eDI, XX, XX },
/* 50 */
- { "pushS", eAX },
- { "pushS", eCX },
- { "pushS", eDX },
- { "pushS", eBX },
- { "pushS", eSP },
- { "pushS", eBP },
- { "pushS", eSI },
- { "pushS", eDI },
+ { "push", eAX, XX, XX },
+ { "push", eCX, XX, XX },
+ { "push", eDX, XX, XX },
+ { "push", eBX, XX, XX },
+ { "push", eSP, XX, XX },
+ { "push", eBP, XX, XX },
+ { "push", eSI, XX, XX },
+ { "push", eDI, XX, XX },
/* 58 */
- { "popS", eAX },
- { "popS", eCX },
- { "popS", eDX },
- { "popS", eBX },
- { "popS", eSP },
- { "popS", eBP },
- { "popS", eSI },
- { "popS", eDI },
+ { "pop", eAX, XX, XX },
+ { "pop", eCX, XX, XX },
+ { "pop", eDX, XX, XX },
+ { "pop", eBX, XX, XX },
+ { "pop", eSP, XX, XX },
+ { "pop", eBP, XX, XX },
+ { "pop", eSI, XX, XX },
+ { "pop", eDI, XX, XX },
/* 60 */
- { "pushaP" },
- { "popaP" },
- { "boundS", Gv, Ma },
- { "arpl", Ew, Gw },
- { "(bad)" }, /* seg fs */
- { "(bad)" }, /* seg gs */
- { "(bad)" }, /* op size prefix */
- { "(bad)" }, /* adr size prefix */
+ { "pusha", XX, XX, XX },
+ { "popa", XX, XX, XX },
+ { "bound", Gv, Ma, XX },
+ { "arpl", Ew, Gw, XX },
+ { "(bad)", XX, XX, XX }, /* seg fs */
+ { "(bad)", XX, XX, XX }, /* seg gs */
+ { "(bad)", XX, XX, XX }, /* op size prefix */
+ { "(bad)", XX, XX, XX }, /* adr size prefix */
/* 68 */
- { "pushP", Iv }, /* 386 book wrong */
- { "imulS", Gv, Ev, Iv },
- { "pushP", sIb }, /* push of byte really pushes 2 or 4 bytes */
- { "imulS", Gv, Ev, sIb },
- { "insb", Yb, indirDX },
- { "insR", Yv, indirDX },
- { "outsb", indirDX, Xb },
- { "outsR", indirDX, Xv },
+ { "push", Iv, XX, XX }, /* 386 book wrong */
+ { "imul", Gv, Ev, Iv },
+ { "push", sIb, XX, XX }, /* push of byte really pushes 2 or 4 bytes */
+ { "imul", Gv, Ev, sIb },
+ { "ins", Yb, indirDX, XX },
+ { "ins", Yv, indirDX, XX },
+ { "outs", indirDX, Xb, XX },
+ { "outs", indirDX, Xv, XX },
/* 70 */
- { "jo", Jb },
- { "jno", Jb },
- { "jb", Jb },
- { "jae", Jb },
- { "je", Jb },
- { "jne", Jb },
- { "jbe", Jb },
- { "ja", Jb },
+ { "jo", Jb, XX, XX },
+ { "jno", Jb, XX, XX },
+ { "jb", Jb, XX, XX },
+ { "jae", Jb, XX, XX },
+ { "je", Jb, XX, XX },
+ { "jne", Jb, XX, XX },
+ { "jbe", Jb, XX, XX },
+ { "ja", Jb, XX, XX },
/* 78 */
- { "js", Jb },
- { "jns", Jb },
- { "jp", Jb },
- { "jnp", Jb },
- { "jl", Jb },
- { "jge", Jb },
- { "jle", Jb },
- { "jg", Jb },
+ { "js", Jb, XX, XX },
+ { "jns", Jb, XX, XX },
+ { "jp", Jb, XX, XX },
+ { "jnp", Jb, XX, XX },
+ { "jl", Jb, XX, XX },
+ { "jge", Jb, XX, XX },
+ { "jle", Jb, XX, XX },
+ { "jg", Jb, XX, XX },
/* 80 */
{ GRP1b },
{ GRP1S },
- { "(bad)" },
+ { "(bad)", XX, XX, XX },
{ GRP1Ss },
- { "testB", Eb, Gb },
- { "testS", Ev, Gv },
- { "xchgB", Eb, Gb },
- { "xchgS", Ev, Gv },
+ { "test", Eb, Gb, XX },
+ { "test", Ev, Gv, XX },
+ { "xchg", Eb, Gb, XX },
+ { "xchg", Ev, Gv, XX },
/* 88 */
- { "movB", Eb, Gb },
- { "movS", Ev, Gv },
- { "movB", Gb, Eb },
- { "movS", Gv, Ev },
- { "movQ", Ev, Sw },
- { "leaS", Gv, M },
- { "movQ", Sw, Ev },
- { "popQ", Ev },
+ { "mov", Eb, Gb, XX },
+ { "mov", Ev, Gv, XX },
+ { "mov", Gb, Eb, XX },
+ { "mov", Gv, Ev, XX },
+ { "mov", Ev, Sw, XX },
+ { "lea", Gv, M, XX },
+ { "mov", Sw, Ev, XX },
+ { "pop", Ev, XX, XX },
/* 90 */
- { "nop" },
- { "xchgS", eCX, eAX },
- { "xchgS", eDX, eAX },
- { "xchgS", eBX, eAX },
- { "xchgS", eSP, eAX },
- { "xchgS", eBP, eAX },
- { "xchgS", eSI, eAX },
- { "xchgS", eDI, eAX },
+ { "nop", XX, XX, XX },
+ { "xchg", eCX, eAX, XX },
+ { "xchg", eDX, eAX, XX },
+ { "xchg", eBX, eAX, XX },
+ { "xchg", eSP, eAX, XX },
+ { "xchg", eBP, eAX, XX },
+ { "xchg", eSI, eAX, XX },
+ { "xchg", eDI, eAX, XX },
/* 98 */
- { "cWtR" },
- { "cRtd" },
- { "lcallP", Ap },
- { "(bad)" }, /* fwait */
- { "pushfP" },
- { "popfP" },
- { "sahf" },
- { "lahf" },
+ { "cW", XX, XX, XX }, /* cwde and cbw */
+ { "cR", XX, XX, XX }, /* cdq and cwd */
+ { "lcall", Ap, XX, XX },
+ { "(bad)", XX, XX, XX }, /* fwait */
+ { "pushf", XX, XX, XX },
+ { "popf", XX, XX, XX },
+ { "sahf", XX, XX, XX },
+ { "lahf", XX, XX, XX },
/* a0 */
- { "movB", AL, Ob },
- { "movS", eAX, Ov },
- { "movB", Ob, AL },
- { "movS", Ov, eAX },
- { "movsb", Yb, Xb },
- { "movsR", Yv, Xv },
- { "cmpsb", Xb, Yb },
- { "cmpsR", Xv, Yv },
+ { "mov", AL, Ob, XX },
+ { "mov", eAX, Ov, XX },
+ { "mov", Ob, AL, XX },
+ { "mov", Ov, eAX, XX },
+ { "movs", Yb, Xb, XX },
+ { "movs", Yv, Xv, XX },
+ { "cmps", Xb, Yb, XX },
+ { "cmps", Xv, Yv, XX },
/* a8 */
- { "testB", AL, Ib },
- { "testS", eAX, Iv },
- { "stosB", Yb, AL },
- { "stosS", Yv, eAX },
- { "lodsB", AL, Xb },
- { "lodsS", eAX, Xv },
- { "scasB", AL, Yb },
- { "scasS", eAX, Yv },
+ { "test", AL, Ib, XX },
+ { "test", eAX, Iv, XX },
+ { "stos", Yb, AL, XX },
+ { "stos", Yv, eAX, XX },
+ { "lods", AL, Xb, XX },
+ { "lods", eAX, Xv, XX },
+ { "scas", AL, Yb, XX },
+ { "scas", eAX, Yv, XX },
/* b0 */
- { "movB", AL, Ib },
- { "movB", CL, Ib },
- { "movB", DL, Ib },
- { "movB", BL, Ib },
- { "movB", AH, Ib },
- { "movB", CH, Ib },
- { "movB", DH, Ib },
- { "movB", BH, Ib },
+ { "mov", AL, Ib, XX },
+ { "mov", CL, Ib, XX },
+ { "mov", DL, Ib, XX },
+ { "mov", BL, Ib, XX },
+ { "mov", AH, Ib, XX },
+ { "mov", CH, Ib, XX },
+ { "mov", DH, Ib, XX },
+ { "mov", BH, Ib, XX },
/* b8 */
- { "movS", eAX, Iv },
- { "movS", eCX, Iv },
- { "movS", eDX, Iv },
- { "movS", eBX, Iv },
- { "movS", eSP, Iv },
- { "movS", eBP, Iv },
- { "movS", eSI, Iv },
- { "movS", eDI, Iv },
+ { "mov", eAX, Iv, XX },
+ { "mov", eCX, Iv, XX },
+ { "mov", eDX, Iv, XX },
+ { "mov", eBX, Iv, XX },
+ { "mov", eSP, Iv, XX },
+ { "mov", eBP, Iv, XX },
+ { "mov", eSI, Iv, XX },
+ { "mov", eDI, Iv, XX },
/* c0 */
{ GRP2b },
{ GRP2S },
- { "retP", Iw },
- { "retP" },
- { "lesS", Gv, Mp },
- { "ldsS", Gv, Mp },
- { "movA", Eb, Ib },
- { "movQ", Ev, Iv },
+ { "ret", Iw, XX, XX },
+ { "ret", XX, XX, XX },
+ { "les", Gv, Mp, XX },
+ { "lds", Gv, Mp, XX },
+ { "mov", Eb, Ib, XX },
+ { "mov", Ev, Iv, XX },
/* c8 */
- { "enterP", Iw, Ib },
- { "leaveP" },
- { "lretP", Iw },
- { "lretP" },
- { "int3" },
- { "int", Ib },
- { "into" },
- { "iretP" },
+ { "enter", Iw, Ib, XX },
+ { "leave", XX, XX, XX },
+ { "lret", Iw, XX, XX },
+ { "lret", XX, XX, XX },
+ { "int3", XX, XX, XX },
+ { "int", Ib, XX, XX },
+ { "into", XX, XX, XX },
+ { "iret", XX, XX, XX },
/* d0 */
{ GRP2b_one },
{ GRP2S_one },
{ GRP2b_cl },
{ GRP2S_cl },
- { "aam", sIb },
- { "aad", sIb },
- { "(bad)" },
- { "xlat", DSBX },
+ { "aam", sIb, XX, XX },
+ { "aad", sIb, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "xlat", DSBX, XX, XX },
/* d8 */
{ FLOAT },
{ FLOAT },
@@ -840,539 +893,694 @@ static struct dis386 dis386_intel[] = {
{ FLOAT },
{ FLOAT },
/* e0 */
- { "loopne", Jb },
- { "loope", Jb },
- { "loop", Jb },
- { "jEcxz", Jb },
- { "inB", AL, Ib },
- { "inS", eAX, Ib },
- { "outB", Ib, AL },
- { "outS", Ib, eAX },
+ { "loopne", Jb, XX, XX },
+ { "loope", Jb, XX, XX },
+ { "loop", Jb, XX, XX },
+ { "jEcxz", Jb, XX, XX },
+ { "in", AL, Ib, XX },
+ { "in", eAX, Ib, XX },
+ { "out", Ib, AL, XX },
+ { "out", Ib, eAX, XX },
/* e8 */
- { "callP", Av },
- { "jmpP", Jv },
- { "ljmpP", Ap },
- { "jmp", Jb },
- { "inB", AL, indirDX },
- { "inS", eAX, indirDX },
- { "outB", indirDX, AL },
- { "outS", indirDX, eAX },
+ { "call", Jv, XX, XX },
+ { "jmp", Jv, XX, XX },
+ { "ljmp", Ap, XX, XX },
+ { "jmp", Jb, XX, XX },
+ { "in", AL, indirDX, XX },
+ { "in", eAX, indirDX, XX },
+ { "out", indirDX, AL, XX },
+ { "out", indirDX, eAX, XX },
/* f0 */
- { "(bad)" }, /* lock prefix */
- { "(bad)" },
- { "(bad)" }, /* repne */
- { "(bad)" }, /* repz */
- { "hlt" },
- { "cmc" },
+ { "(bad)", XX, XX, XX }, /* lock prefix */
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX }, /* repne */
+ { "(bad)", XX, XX, XX }, /* repz */
+ { "hlt", XX, XX, XX },
+ { "cmc", XX, XX, XX },
{ GRP3b },
{ GRP3S },
/* f8 */
- { "clc" },
- { "stc" },
- { "cli" },
- { "sti" },
- { "cld" },
- { "std" },
+ { "clc", XX, XX, XX },
+ { "stc", XX, XX, XX },
+ { "cli", XX, XX, XX },
+ { "sti", XX, XX, XX },
+ { "cld", XX, XX, XX },
+ { "std", XX, XX, XX },
{ GRP4 },
{ GRP5 },
};
-static struct dis386 dis386_twobyte_att[] = {
+static const struct dis386 dis386_twobyte_att[] = {
/* 00 */
{ GRP6 },
{ GRP7 },
- { "larS", Gv, Ew },
- { "lslS", Gv, Ew },
- { "(bad)" },
- { "(bad)" },
- { "clts" },
- { "(bad)" },
+ { "larS", Gv, Ew, XX },
+ { "lslS", Gv, Ew, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "clts", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
/* 08 */
- { "invd" },
- { "wbinvd" },
- { "(bad)" },
- { "ud2a" },
- { "(bad)" },
- { GRP14 },
- { "femms" },
+ { "invd", XX, XX, XX },
+ { "wbinvd", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "ud2a", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { GRPAMD },
+ { "femms", XX, XX, XX },
{ "", MX, EM, OPSUF }, /* See OP_3DNowSuffix */
/* 10 */
- { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
- { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { PREGRP8 },
+ { PREGRP9 },
+ { "movlps", XM, EX, SIMD_Fixup, 'h' }, /* really only 2 operands */
+ { "movlps", EX, XM, SIMD_Fixup, 'h' },
+ { "unpcklps", XM, EX, XX },
+ { "unpckhps", XM, EX, XX },
+ { "movhps", XM, EX, SIMD_Fixup, 'l' },
+ { "movhps", EX, XM, SIMD_Fixup, 'l' },
/* 18 */
- { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
- { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { GRP14 },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
/* 20 */
/* these are all backward in appendix A of the intel book */
- { "movL", Rd, Cd },
- { "movL", Rd, Dd },
- { "movL", Cd, Rd },
- { "movL", Dd, Rd },
- { "movL", Rd, Td },
- { "(bad)" },
- { "movL", Td, Rd },
- { "(bad)" },
+ { "movL", Rd, Cd, XX },
+ { "movL", Rd, Dd, XX },
+ { "movL", Cd, Rd, XX },
+ { "movL", Dd, Rd, XX },
+ { "movL", Rd, Td, XX },
+ { "(bad)", XX, XX, XX },
+ { "movL", Td, Rd, XX },
+ { "(bad)", XX, XX, XX },
/* 28 */
- { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
- { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { "movaps", XM, EX, XX },
+ { "movaps", EX, XM, XX },
+ { PREGRP2 },
+ { "movntps", Ev, XM, XX },
+ { PREGRP4 },
+ { PREGRP3 },
+ { "ucomiss", XM, EX, XX },
+ { "comiss", XM, EX, XX },
/* 30 */
- { "wrmsr" }, { "rdtsc" }, { "rdmsr" }, { "rdpmc" },
- { "sysenter" }, { "sysexit" }, { "(bad)" }, { "(bad)" },
+ { "wrmsr", XX, XX, XX },
+ { "rdtsc", XX, XX, XX },
+ { "rdmsr", XX, XX, XX },
+ { "rdpmc", XX, XX, XX },
+ { "sysenter", XX, XX, XX },
+ { "sysexit", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
/* 38 */
- { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
- { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
/* 40 */
- { "cmovo", Gv,Ev }, { "cmovno", Gv,Ev }, { "cmovb", Gv,Ev }, { "cmovae", Gv,Ev },
- { "cmove", Gv,Ev }, { "cmovne", Gv,Ev }, { "cmovbe", Gv,Ev }, { "cmova", Gv,Ev },
+ { "cmovo", Gv, Ev, XX },
+ { "cmovno", Gv, Ev, XX },
+ { "cmovb", Gv, Ev, XX },
+ { "cmovae", Gv, Ev, XX },
+ { "cmove", Gv, Ev, XX },
+ { "cmovne", Gv, Ev, XX },
+ { "cmovbe", Gv, Ev, XX },
+ { "cmova", Gv, Ev, XX },
/* 48 */
- { "cmovs", Gv,Ev }, { "cmovns", Gv,Ev }, { "cmovp", Gv,Ev }, { "cmovnp", Gv,Ev },
- { "cmovl", Gv,Ev }, { "cmovge", Gv,Ev }, { "cmovle", Gv,Ev }, { "cmovg", Gv,Ev },
+ { "cmovs", Gv, Ev, XX },
+ { "cmovns", Gv, Ev, XX },
+ { "cmovp", Gv, Ev, XX },
+ { "cmovnp", Gv, Ev, XX },
+ { "cmovl", Gv, Ev, XX },
+ { "cmovge", Gv, Ev, XX },
+ { "cmovle", Gv, Ev, XX },
+ { "cmovg", Gv, Ev, XX },
/* 50 */
- { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
- { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { "movmskps", Gv, EX, XX },
+ { PREGRP13 },
+ { PREGRP12 },
+ { PREGRP11 },
+ { "andps", XM, EX, XX },
+ { "andnps", XM, EX, XX },
+ { "orps", XM, EX, XX },
+ { "xorps", XM, EX, XX },
/* 58 */
- { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
- { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { PREGRP0 },
+ { PREGRP10 },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { PREGRP14 },
+ { PREGRP7 },
+ { PREGRP5 },
+ { PREGRP6 },
/* 60 */
- { "punpcklbw", MX, EM },
- { "punpcklwd", MX, EM },
- { "punpckldq", MX, EM },
- { "packsswb", MX, EM },
- { "pcmpgtb", MX, EM },
- { "pcmpgtw", MX, EM },
- { "pcmpgtd", MX, EM },
- { "packuswb", MX, EM },
+ { "punpcklbw", MX, EM, XX },
+ { "punpcklwd", MX, EM, XX },
+ { "punpckldq", MX, EM, XX },
+ { "packsswb", MX, EM, XX },
+ { "pcmpgtb", MX, EM, XX },
+ { "pcmpgtw", MX, EM, XX },
+ { "pcmpgtd", MX, EM, XX },
+ { "packuswb", MX, EM, XX },
/* 68 */
- { "punpckhbw", MX, EM },
- { "punpckhwd", MX, EM },
- { "punpckhdq", MX, EM },
- { "packssdw", MX, EM },
- { "(bad)" }, { "(bad)" },
- { "movd", MX, Ev },
- { "movq", MX, EM },
+ { "punpckhbw", MX, EM, XX },
+ { "punpckhwd", MX, EM, XX },
+ { "punpckhdq", MX, EM, XX },
+ { "packssdw", MX, EM, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "movd", MX, Ed, XX },
+ { "movq", MX, EM, XX },
/* 70 */
- { "(bad)" },
+ { "pshufw", MX, EM, Ib },
{ GRP10 },
{ GRP11 },
{ GRP12 },
- { "pcmpeqb", MX, EM },
- { "pcmpeqw", MX, EM },
- { "pcmpeqd", MX, EM },
- { "emms" },
+ { "pcmpeqb", MX, EM, XX },
+ { "pcmpeqw", MX, EM, XX },
+ { "pcmpeqd", MX, EM, XX },
+ { "emms", XX, XX, XX },
/* 78 */
- { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
- { "(bad)" }, { "(bad)" },
- { "movd", Ev, MX },
- { "movq", EM, MX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "movd", Ed, MX, XX },
+ { "movq", EM, MX, XX },
/* 80 */
- { "jo", Jv },
- { "jno", Jv },
- { "jb", Jv },
- { "jae", Jv },
- { "je", Jv },
- { "jne", Jv },
- { "jbe", Jv },
- { "ja", Jv },
+ { "jo", Jv, XX, XX },
+ { "jno", Jv, XX, XX },
+ { "jb", Jv, XX, XX },
+ { "jae", Jv, XX, XX },
+ { "je", Jv, XX, XX },
+ { "jne", Jv, XX, XX },
+ { "jbe", Jv, XX, XX },
+ { "ja", Jv, XX, XX },
/* 88 */
- { "js", Jv },
- { "jns", Jv },
- { "jp", Jv },
- { "jnp", Jv },
- { "jl", Jv },
- { "jge", Jv },
- { "jle", Jv },
- { "jg", Jv },
+ { "js", Jv, XX, XX },
+ { "jns", Jv, XX, XX },
+ { "jp", Jv, XX, XX },
+ { "jnp", Jv, XX, XX },
+ { "jl", Jv, XX, XX },
+ { "jge", Jv, XX, XX },
+ { "jle", Jv, XX, XX },
+ { "jg", Jv, XX, XX },
/* 90 */
- { "seto", Eb },
- { "setno", Eb },
- { "setb", Eb },
- { "setae", Eb },
- { "sete", Eb },
- { "setne", Eb },
- { "setbe", Eb },
- { "seta", Eb },
+ { "seto", Eb, XX, XX },
+ { "setno", Eb, XX, XX },
+ { "setb", Eb, XX, XX },
+ { "setae", Eb, XX, XX },
+ { "sete", Eb, XX, XX },
+ { "setne", Eb, XX, XX },
+ { "setbe", Eb, XX, XX },
+ { "seta", Eb, XX, XX },
/* 98 */
- { "sets", Eb },
- { "setns", Eb },
- { "setp", Eb },
- { "setnp", Eb },
- { "setl", Eb },
- { "setge", Eb },
- { "setle", Eb },
- { "setg", Eb },
+ { "sets", Eb, XX, XX },
+ { "setns", Eb, XX, XX },
+ { "setp", Eb, XX, XX },
+ { "setnp", Eb, XX, XX },
+ { "setl", Eb, XX, XX },
+ { "setge", Eb, XX, XX },
+ { "setle", Eb, XX, XX },
+ { "setg", Eb, XX, XX },
/* a0 */
- { "pushP", fs },
- { "popP", fs },
- { "cpuid" },
- { "btS", Ev, Gv },
+ { "pushP", fs, XX, XX },
+ { "popP", fs, XX, XX },
+ { "cpuid", XX, XX, XX },
+ { "btS", Ev, Gv, XX },
{ "shldS", Ev, Gv, Ib },
{ "shldS", Ev, Gv, CL },
- { "(bad)" },
- { "(bad)" },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
/* a8 */
- { "pushP", gs },
- { "popP", gs },
- { "rsm" },
- { "btsS", Ev, Gv },
+ { "pushP", gs, XX, XX },
+ { "popP", gs, XX, XX },
+ { "rsm", XX, XX, XX },
+ { "btsS", Ev, Gv, XX },
{ "shrdS", Ev, Gv, Ib },
{ "shrdS", Ev, Gv, CL },
{ GRP13 },
- { "imulS", Gv, Ev },
+ { "imulS", Gv, Ev, XX },
/* b0 */
- { "cmpxchgB", Eb, Gb },
- { "cmpxchgS", Ev, Gv },
- { "lssS", Gv, Mp }, /* 386 lists only Mp */
- { "btrS", Ev, Gv },
- { "lfsS", Gv, Mp }, /* 386 lists only Mp */
- { "lgsS", Gv, Mp }, /* 386 lists only Mp */
- { "movzbR", Gv, Eb },
- { "movzwR", Gv, Ew }, /* yes, there really is movzww ! */
+ { "cmpxchgB", Eb, Gb, XX },
+ { "cmpxchgS", Ev, Gv, XX },
+ { "lssS", Gv, Mp, XX },
+ { "btrS", Ev, Gv, XX },
+ { "lfsS", Gv, Mp, XX },
+ { "lgsS", Gv, Mp, XX },
+ { "movzbR", Gv, Eb, XX },
+ { "movzwR", Gv, Ew, XX }, /* yes, there really is movzww ! */
/* b8 */
- { "(bad)" },
- { "ud2b" },
+ { "(bad)", XX, XX, XX },
+ { "ud2b", XX, XX, XX },
{ GRP8 },
- { "btcS", Ev, Gv },
- { "bsfS", Gv, Ev },
- { "bsrS", Gv, Ev },
- { "movsbR", Gv, Eb },
- { "movswR", Gv, Ew }, /* yes, there really is movsww ! */
+ { "btcS", Ev, Gv, XX },
+ { "bsfS", Gv, Ev, XX },
+ { "bsrS", Gv, Ev, XX },
+ { "movsbR", Gv, Eb, XX },
+ { "movswR", Gv, Ew, XX }, /* yes, there really is movsww ! */
/* c0 */
- { "xaddB", Eb, Gb },
- { "xaddS", Ev, Gv },
- { "(bad)" },
- { "(bad)" },
- { "(bad)" },
- { "(bad)" },
- { "(bad)" },
+ { "xaddB", Eb, Gb, XX },
+ { "xaddS", Ev, Gv, XX },
+ { PREGRP1 },
+ { "(bad)", XX, XX, XX },
+ { "pinsrw", MX, Ev, Ib },
+ { "pextrw", Ev, MX, Ib },
+ { "shufps", XM, EX, Ib },
{ GRP9 },
/* c8 */
- { "bswap", eAX }, /* bswap doesn't support 16 bit regs */
- { "bswap", eCX },
- { "bswap", eDX },
- { "bswap", eBX },
- { "bswap", eSP },
- { "bswap", eBP },
- { "bswap", eSI },
- { "bswap", eDI },
+ { "bswap", eAX, XX, XX }, /* bswap doesn't support 16 bit regs */
+ { "bswap", eCX, XX, XX },
+ { "bswap", eDX, XX, XX },
+ { "bswap", eBX, XX, XX },
+ { "bswap", eSP, XX, XX },
+ { "bswap", eBP, XX, XX },
+ { "bswap", eSI, XX, XX },
+ { "bswap", eDI, XX, XX },
/* d0 */
- { "(bad)" },
- { "psrlw", MX, EM },
- { "psrld", MX, EM },
- { "psrlq", MX, EM },
- { "(bad)" },
- { "pmullw", MX, EM },
- { "(bad)" }, { "(bad)" },
+ { "(bad)", XX, XX, XX },
+ { "psrlw", MX, EM, XX },
+ { "psrld", MX, EM, XX },
+ { "psrlq", MX, EM, XX },
+ { "(bad)", XX, XX, XX },
+ { "pmullw", MX, EM, XX },
+ { "(bad)", XX, XX, XX },
+ { "pmovmskb", Ev, MX, XX },
/* d8 */
- { "psubusb", MX, EM },
- { "psubusw", MX, EM },
- { "(bad)" },
- { "pand", MX, EM },
- { "paddusb", MX, EM },
- { "paddusw", MX, EM },
- { "(bad)" },
- { "pandn", MX, EM },
+ { "psubusb", MX, EM, XX },
+ { "psubusw", MX, EM, XX },
+ { "pminub", MX, EM, XX },
+ { "pand", MX, EM, XX },
+ { "paddusb", MX, EM, XX },
+ { "paddusw", MX, EM, XX },
+ { "pmaxub", MX, EM, XX },
+ { "pandn", MX, EM, XX },
/* e0 */
- { "(bad)" },
- { "psraw", MX, EM },
- { "psrad", MX, EM },
- { "(bad)" },
- { "(bad)" },
- { "pmulhw", MX, EM },
- { "(bad)" }, { "(bad)" },
+ { "pavgb", MX, EM, XX },
+ { "psraw", MX, EM, XX },
+ { "psrad", MX, EM, XX },
+ { "pavgw", MX, EM, XX },
+ { "pmulhuw", MX, EM, XX },
+ { "pmulhw", MX, EM, XX },
+ { "(bad)", XX, XX, XX },
+ { "movntq", Ev, MX, XX },
/* e8 */
- { "psubsb", MX, EM },
- { "psubsw", MX, EM },
- { "(bad)" },
- { "por", MX, EM },
- { "paddsb", MX, EM },
- { "paddsw", MX, EM },
- { "(bad)" },
- { "pxor", MX, EM },
+ { "psubsb", MX, EM, XX },
+ { "psubsw", MX, EM, XX },
+ { "pminsw", MX, EM, XX },
+ { "por", MX, EM, XX },
+ { "paddsb", MX, EM, XX },
+ { "paddsw", MX, EM, XX },
+ { "pmaxsw", MX, EM, XX },
+ { "pxor", MX, EM, XX },
/* f0 */
- { "(bad)" },
- { "psllw", MX, EM },
- { "pslld", MX, EM },
- { "psllq", MX, EM },
- { "(bad)" },
- { "pmaddwd", MX, EM },
- { "(bad)" }, { "(bad)" },
+ { "(bad)", XX, XX, XX },
+ { "psllw", MX, EM, XX },
+ { "pslld", MX, EM, XX },
+ { "psllq", MX, EM, XX },
+ { "(bad)", XX, XX, XX },
+ { "pmaddwd", MX, EM, XX },
+ { "psadbw", MX, EM, XX },
+ { "maskmovq", MX, EM, XX },
/* f8 */
- { "psubb", MX, EM },
- { "psubw", MX, EM },
- { "psubd", MX, EM },
- { "(bad)" },
- { "paddb", MX, EM },
- { "paddw", MX, EM },
- { "paddd", MX, EM },
- { "(bad)" }
+ { "psubb", MX, EM, XX },
+ { "psubw", MX, EM, XX },
+ { "psubd", MX, EM, XX },
+ { "(bad)", XX, XX, XX },
+ { "paddb", MX, EM, XX },
+ { "paddw", MX, EM, XX },
+ { "paddd", MX, EM, XX },
+ { "(bad)", XX, XX, XX }
};
-static struct dis386 dis386_twobyte_intel[] = {
+static const struct dis386 dis386_twobyte_intel[] = {
/* 00 */
{ GRP6 },
{ GRP7 },
- { "larS", Gv, Ew },
- { "lslS", Gv, Ew },
- { "(bad)" },
- { "(bad)" },
- { "clts" },
- { "(bad)" },
+ { "lar", Gv, Ew, XX },
+ { "lsl", Gv, Ew, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "clts", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
/* 08 */
- { "invd" },
- { "wbinvd" },
- { "(bad)" },
- { "ud2a" },
- { "(bad)" },
- { GRP14 },
- { "femms" },
+ { "invd", XX, XX, XX },
+ { "wbinvd", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "ud2a", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { GRPAMD },
+ { "femms" , XX, XX, XX},
{ "", MX, EM, OPSUF }, /* See OP_3DNowSuffix */
/* 10 */
- { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
- { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { PREGRP8 },
+ { PREGRP9 },
+ { "movlps", XM, EX, SIMD_Fixup, 'h' }, /* really only 2 operands */
+ { "movlps", EX, XM, SIMD_Fixup, 'h' },
+ { "unpcklps", XM, EX, XX },
+ { "unpckhps", XM, EX, XX },
+ { "movhps", XM, EX, SIMD_Fixup, 'l' },
+ { "movhps", EX, XM, SIMD_Fixup, 'l' },
/* 18 */
- { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
- { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { GRP14 },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
/* 20 */
/* these are all backward in appendix A of the intel book */
- { "movL", Rd, Cd },
- { "movL", Rd, Dd },
- { "movL", Cd, Rd },
- { "movL", Dd, Rd },
- { "movL", Rd, Td },
- { "(bad)" },
- { "movL", Td, Rd },
- { "(bad)" },
+ { "mov", Rd, Cd, XX },
+ { "mov", Rd, Dd, XX },
+ { "mov", Cd, Rd, XX },
+ { "mov", Dd, Rd, XX },
+ { "mov", Rd, Td, XX },
+ { "(bad)", XX, XX, XX },
+ { "mov", Td, Rd, XX },
+ { "(bad)", XX, XX, XX },
/* 28 */
- { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
- { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { "movaps", XM, EX, XX },
+ { "movaps", EX, XM, XX },
+ { PREGRP2 },
+ { "movntps", Ev, XM, XX },
+ { PREGRP4 },
+ { PREGRP3 },
+ { "ucomiss", XM, EX, XX },
+ { "comiss", XM, EX, XX },
/* 30 */
- { "wrmsr" }, { "rdtsc" }, { "rdmsr" }, { "rdpmc" },
- { "sysenter" }, { "sysexit" }, { "(bad)" }, { "(bad)" },
+ { "wrmsr", XX, XX, XX },
+ { "rdtsc", XX, XX, XX },
+ { "rdmsr", XX, XX, XX },
+ { "rdpmc", XX, XX, XX },
+ { "sysenter", XX, XX, XX },
+ { "sysexit", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
/* 38 */
- { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
- { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
/* 40 */
- { "cmovo", Gv,Ev }, { "cmovno", Gv,Ev }, { "cmovb", Gv,Ev }, { "cmovae", Gv,Ev },
- { "cmove", Gv,Ev }, { "cmovne", Gv,Ev }, { "cmovbe", Gv,Ev }, { "cmova", Gv,Ev },
+ { "cmovo", Gv, Ev, XX },
+ { "cmovno", Gv, Ev, XX },
+ { "cmovb", Gv, Ev, XX },
+ { "cmovae", Gv, Ev, XX },
+ { "cmove", Gv, Ev, XX },
+ { "cmovne", Gv, Ev, XX },
+ { "cmovbe", Gv, Ev, XX },
+ { "cmova", Gv, Ev, XX },
/* 48 */
- { "cmovs", Gv,Ev }, { "cmovns", Gv,Ev }, { "cmovp", Gv,Ev }, { "cmovnp", Gv,Ev },
- { "cmovl", Gv,Ev }, { "cmovge", Gv,Ev }, { "cmovle", Gv,Ev }, { "cmovg", Gv,Ev },
+ { "cmovs", Gv, Ev, XX },
+ { "cmovns", Gv, Ev, XX },
+ { "cmovp", Gv, Ev, XX },
+ { "cmovnp", Gv, Ev, XX },
+ { "cmovl", Gv, Ev, XX },
+ { "cmovge", Gv, Ev, XX },
+ { "cmovle", Gv, Ev, XX },
+ { "cmovg", Gv, Ev, XX },
/* 50 */
- { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
- { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { "movmskps", Gv, EX, XX },
+ { PREGRP13 },
+ { PREGRP12 },
+ { PREGRP11 },
+ { "andps", XM, EX, XX },
+ { "andnps", XM, EX, XX },
+ { "orps", XM, EX, XX },
+ { "xorps", XM, EX, XX },
/* 58 */
- { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
- { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { PREGRP0 },
+ { PREGRP10 },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { PREGRP14 },
+ { PREGRP7 },
+ { PREGRP5 },
+ { PREGRP6 },
/* 60 */
- { "punpcklbw", MX, EM },
- { "punpcklwd", MX, EM },
- { "punpckldq", MX, EM },
- { "packsswb", MX, EM },
- { "pcmpgtb", MX, EM },
- { "pcmpgtw", MX, EM },
- { "pcmpgtd", MX, EM },
- { "packuswb", MX, EM },
+ { "punpcklbw", MX, EM, XX },
+ { "punpcklwd", MX, EM, XX },
+ { "punpckldq", MX, EM, XX },
+ { "packsswb", MX, EM, XX },
+ { "pcmpgtb", MX, EM, XX },
+ { "pcmpgtw", MX, EM, XX },
+ { "pcmpgtd", MX, EM, XX },
+ { "packuswb", MX, EM, XX },
/* 68 */
- { "punpckhbw", MX, EM },
- { "punpckhwd", MX, EM },
- { "punpckhdq", MX, EM },
- { "packssdw", MX, EM },
- { "(bad)" }, { "(bad)" },
- { "movd", MX, Ev },
- { "movq", MX, EM },
+ { "punpckhbw", MX, EM, XX },
+ { "punpckhwd", MX, EM, XX },
+ { "punpckhdq", MX, EM, XX },
+ { "packssdw", MX, EM, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "movd", MX, Ed, XX },
+ { "movq", MX, EM, XX },
/* 70 */
- { "(bad)" },
+ { "pshufw", MX, EM, Ib },
{ GRP10 },
{ GRP11 },
{ GRP12 },
- { "pcmpeqb", MX, EM },
- { "pcmpeqw", MX, EM },
- { "pcmpeqd", MX, EM },
- { "emms" },
+ { "pcmpeqb", MX, EM, XX },
+ { "pcmpeqw", MX, EM, XX },
+ { "pcmpeqd", MX, EM, XX },
+ { "emms", XX, XX, XX },
/* 78 */
- { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
- { "(bad)" }, { "(bad)" },
- { "movd", Ev, MX },
- { "movq", EM, MX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "movd", Ed, MX, XX },
+ { "movq", EM, MX, XX },
/* 80 */
- { "jo", Jv },
- { "jno", Jv },
- { "jb", Jv },
- { "jae", Jv },
- { "je", Jv },
- { "jne", Jv },
- { "jbe", Jv },
- { "ja", Jv },
+ { "jo", Jv, XX, XX },
+ { "jno", Jv, XX, XX },
+ { "jb", Jv, XX, XX },
+ { "jae", Jv, XX, XX },
+ { "je", Jv, XX, XX },
+ { "jne", Jv, XX, XX },
+ { "jbe", Jv, XX, XX },
+ { "ja", Jv, XX, XX },
/* 88 */
- { "js", Jv },
- { "jns", Jv },
- { "jp", Jv },
- { "jnp", Jv },
- { "jl", Jv },
- { "jge", Jv },
- { "jle", Jv },
- { "jg", Jv },
+ { "js", Jv, XX, XX },
+ { "jns", Jv, XX, XX },
+ { "jp", Jv, XX, XX },
+ { "jnp", Jv, XX, XX },
+ { "jl", Jv, XX, XX },
+ { "jge", Jv, XX, XX },
+ { "jle", Jv, XX, XX },
+ { "jg", Jv, XX, XX },
/* 90 */
- { "seto", Eb },
- { "setno", Eb },
- { "setb", Eb },
- { "setae", Eb },
- { "sete", Eb },
- { "setne", Eb },
- { "setbe", Eb },
- { "seta", Eb },
+ { "seto", Eb, XX, XX },
+ { "setno", Eb, XX, XX },
+ { "setb", Eb, XX, XX },
+ { "setae", Eb, XX, XX },
+ { "sete", Eb, XX, XX },
+ { "setne", Eb, XX, XX },
+ { "setbe", Eb, XX, XX },
+ { "seta", Eb, XX, XX },
/* 98 */
- { "sets", Eb },
- { "setns", Eb },
- { "setp", Eb },
- { "setnp", Eb },
- { "setl", Eb },
- { "setge", Eb },
- { "setle", Eb },
- { "setg", Eb },
+ { "sets", Eb, XX, XX },
+ { "setns", Eb, XX, XX },
+ { "setp", Eb, XX, XX },
+ { "setnp", Eb, XX, XX },
+ { "setl", Eb, XX, XX },
+ { "setge", Eb, XX, XX },
+ { "setle", Eb, XX, XX },
+ { "setg", Eb, XX, XX },
/* a0 */
- { "pushP", fs },
- { "popP", fs },
- { "cpuid" },
- { "btS", Ev, Gv },
- { "shldS", Ev, Gv, Ib },
- { "shldS", Ev, Gv, CL },
- { "(bad)" },
- { "(bad)" },
+ { "push", fs, XX, XX },
+ { "pop", fs, XX, XX },
+ { "cpuid", XX, XX, XX },
+ { "bt", Ev, Gv, XX },
+ { "shld", Ev, Gv, Ib },
+ { "shld", Ev, Gv, CL },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
/* a8 */
- { "pushP", gs },
- { "popP", gs },
- { "rsm" },
- { "btsS", Ev, Gv },
- { "shrdS", Ev, Gv, Ib },
- { "shrdS", Ev, Gv, CL },
+ { "push", gs, XX, XX },
+ { "pop", gs, XX, XX },
+ { "rsm" , XX, XX, XX},
+ { "bts", Ev, Gv, XX },
+ { "shrd", Ev, Gv, Ib },
+ { "shrd", Ev, Gv, CL },
{ GRP13 },
- { "imulS", Gv, Ev },
+ { "imul", Gv, Ev, XX },
/* b0 */
- { "cmpxchgB", Eb, Gb },
- { "cmpxchgS", Ev, Gv },
- { "lssS", Gv, Mp }, /* 386 lists only Mp */
- { "btrS", Ev, Gv },
- { "lfsS", Gv, Mp }, /* 386 lists only Mp */
- { "lgsS", Gv, Mp }, /* 386 lists only Mp */
- { "movzx", Gv, Eb },
- { "movzx", Gv, Ew },
+ { "cmpxchg", Eb, Gb, XX },
+ { "cmpxchg", Ev, Gv, XX },
+ { "lss", Gv, Mp, XX },
+ { "btr", Ev, Gv, XX },
+ { "lfs", Gv, Mp, XX },
+ { "lgs", Gv, Mp, XX },
+ { "movzx", Gv, Eb, XX },
+ { "movzx", Gv, Ew, XX },
/* b8 */
- { "(bad)" },
- { "ud2b" },
+ { "(bad)", XX, XX, XX },
+ { "ud2b", XX, XX, XX },
{ GRP8 },
- { "btcS", Ev, Gv },
- { "bsfS", Gv, Ev },
- { "bsrS", Gv, Ev },
- { "movsx", Gv, Eb },
- { "movsx", Gv, Ew },
+ { "btc", Ev, Gv, XX },
+ { "bsf", Gv, Ev, XX },
+ { "bsr", Gv, Ev, XX },
+ { "movsx", Gv, Eb, XX },
+ { "movsx", Gv, Ew, XX },
/* c0 */
- { "xaddB", Eb, Gb },
- { "xaddS", Ev, Gv },
- { "(bad)" },
- { "(bad)" },
- { "(bad)" },
- { "(bad)" },
- { "(bad)" },
+ { "xadd", Eb, Gb, XX },
+ { "xadd", Ev, Gv, XX },
+ { PREGRP1 },
+ { "(bad)", XX, XX, XX },
+ { "pinsrw", MX, Ev, Ib },
+ { "pextrw", Ev, MX, Ib },
+ { "shufps", XM, EX, Ib },
{ GRP9 },
/* c8 */
- { "bswap", eAX }, /* bswap doesn't support 16 bit regs */
- { "bswap", eCX },
- { "bswap", eDX },
- { "bswap", eBX },
- { "bswap", eSP },
- { "bswap", eBP },
- { "bswap", eSI },
- { "bswap", eDI },
+ { "bswap", eAX, XX, XX }, /* bswap doesn't support 16 bit regs */
+ { "bswap", eCX, XX, XX },
+ { "bswap", eDX, XX, XX },
+ { "bswap", eBX, XX, XX },
+ { "bswap", eSP, XX, XX },
+ { "bswap", eBP, XX, XX },
+ { "bswap", eSI, XX, XX },
+ { "bswap", eDI, XX, XX },
/* d0 */
- { "(bad)" },
- { "psrlw", MX, EM },
- { "psrld", MX, EM },
- { "psrlq", MX, EM },
- { "(bad)" },
- { "pmullw", MX, EM },
- { "(bad)" }, { "(bad)" },
+ { "(bad)", XX, XX, XX },
+ { "psrlw", MX, EM, XX },
+ { "psrld", MX, EM, XX },
+ { "psrlq", MX, EM, XX },
+ { "(bad)", XX, XX, XX },
+ { "pmullw", MX, EM, XX },
+ { "(bad)", XX, XX, XX },
+ { "pmovmskb", Ev, MX, XX },
/* d8 */
- { "psubusb", MX, EM },
- { "psubusw", MX, EM },
- { "(bad)" },
- { "pand", MX, EM },
- { "paddusb", MX, EM },
- { "paddusw", MX, EM },
- { "(bad)" },
- { "pandn", MX, EM },
+ { "psubusb", MX, EM, XX },
+ { "psubusw", MX, EM, XX },
+ { "pminub", MX, EM, XX },
+ { "pand", MX, EM, XX },
+ { "paddusb", MX, EM, XX },
+ { "paddusw", MX, EM, XX },
+ { "pmaxub", MX, EM, XX },
+ { "pandn", MX, EM, XX },
/* e0 */
- { "(bad)" },
- { "psraw", MX, EM },
- { "psrad", MX, EM },
- { "(bad)" },
- { "(bad)" },
- { "pmulhw", MX, EM },
- { "(bad)" }, { "(bad)" },
+ { "pavgb", MX, EM, XX },
+ { "psraw", MX, EM, XX },
+ { "psrad", MX, EM, XX },
+ { "pavgw", MX, EM, XX },
+ { "pmulhuw", MX, EM, XX },
+ { "pmulhw", MX, EM, XX },
+ { "(bad)", XX, XX, XX },
+ { "movntq", Ev, MX, XX },
/* e8 */
- { "psubsb", MX, EM },
- { "psubsw", MX, EM },
- { "(bad)" },
- { "por", MX, EM },
- { "paddsb", MX, EM },
- { "paddsw", MX, EM },
- { "(bad)" },
- { "pxor", MX, EM },
+ { "psubsb", MX, EM, XX },
+ { "psubsw", MX, EM, XX },
+ { "pminsw", MX, EM, XX },
+ { "por", MX, EM, XX },
+ { "paddsb", MX, EM, XX },
+ { "paddsw", MX, EM, XX },
+ { "pmaxsw", MX, EM, XX },
+ { "pxor", MX, EM, XX },
/* f0 */
- { "(bad)" },
- { "psllw", MX, EM },
- { "pslld", MX, EM },
- { "psllq", MX, EM },
- { "(bad)" },
- { "pmaddwd", MX, EM },
- { "(bad)" }, { "(bad)" },
+ { "(bad)", XX, XX, XX },
+ { "psllw", MX, EM, XX },
+ { "pslld", MX, EM, XX },
+ { "psllq", MX, EM, XX },
+ { "(bad)", XX, XX, XX },
+ { "pmaddwd", MX, EM, XX },
+ { "psadbw", MX, EM, XX },
+ { "maskmovq", MX, EM, XX },
/* f8 */
- { "psubb", MX, EM },
- { "psubw", MX, EM },
- { "psubd", MX, EM },
- { "(bad)" },
- { "paddb", MX, EM },
- { "paddw", MX, EM },
- { "paddd", MX, EM },
- { "(bad)" }
+ { "psubb", MX, EM, XX },
+ { "psubw", MX, EM, XX },
+ { "psubd", MX, EM, XX },
+ { "(bad)", XX, XX, XX },
+ { "paddb", MX, EM, XX },
+ { "paddw", MX, EM, XX },
+ { "paddd", MX, EM, XX },
+ { "(bad)", XX, XX, XX }
};
static const unsigned char onebyte_has_modrm[256] = {
- 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
- 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
- 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
- 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0,
- 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1
+ /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
+ /* ------------------------------- */
+ /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
+ /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
+ /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
+ /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
+ /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
+ /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
+ /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
+ /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
+ /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
+ /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
+ /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
+ /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
+ /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
+ /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
+ /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
+ /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */
+ /* ------------------------------- */
+ /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
};
static const unsigned char twobyte_has_modrm[256] = {
+ /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
+ /* ------------------------------- */
/* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
- /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
- /* 20 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* 2f */
+ /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, /* 1f */
+ /* 20 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 2f */
/* 30 */ 0,0,0,0,0,0,0,0,0,0,0,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 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
+ /* 50 */ 1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1, /* 5f */
/* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1, /* 6f */
- /* 70 */ 0,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1, /* 7f */
+ /* 70 */ 1,1,1,1,1,1,1,0,0,0,0,0,0,0,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 */
/* b0 */ 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1, /* bf */
/* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
- /* d0 */ 0,1,1,1,0,1,0,0,1,1,0,1,1,1,0,1, /* df */
- /* e0 */ 0,1,1,0,0,1,0,0,1,1,0,1,1,1,0,1, /* ef */
- /* f0 */ 0,1,1,1,0,1,0,0,1,1,1,0,1,1,1,0 /* ff */
+ /* d0 */ 0,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1, /* df */
+ /* e0 */ 1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1, /* ef */
+ /* f0 */ 0,1,1,1,0,1,1,1,1,1,1,0,1,1,1,0 /* ff */
+ /* ------------------------------- */
+ /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
+};
+
+static const unsigned char twobyte_uses_f3_prefix[256] = {
+ /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
+ /* ------------------------------- */
+ /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
+ /* 10 */ 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
+ /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0, /* 2f */
+ /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
+ /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
+ /* 50 */ 0,1,1,1,0,0,0,0,1,1,0,0,1,1,1,1, /* 5f */
+ /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
+ /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
+ /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
+ /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
+ /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
+ /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
+ /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
+ /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
+ /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
+ /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* ff */
+ /* ------------------------------- */
+ /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
};
static char obuf[100];
@@ -1385,289 +1593,366 @@ static disassemble_info *the_info;
static int mod;
static int rm;
static int reg;
-static void oappend PARAMS ((char *s));
+static void oappend PARAMS ((const char *s));
-static char *names32[]={
+static const char *names32[]={
"%eax","%ecx","%edx","%ebx", "%esp","%ebp","%esi","%edi",
};
-static char *names16[] = {
+static const char *names16[] = {
"%ax","%cx","%dx","%bx","%sp","%bp","%si","%di",
};
-static char *names8[] = {
+static const char *names8[] = {
"%al","%cl","%dl","%bl","%ah","%ch","%dh","%bh",
};
-static char *names_seg[] = {
+static const char *names_seg[] = {
"%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
};
-static char *index16[] = {
+static const char *index16[] = {
"%bx,%si","%bx,%di","%bp,%si","%bp,%di","%si","%di","%bp","%bx"
};
-static struct dis386 grps[][8] = {
+static const struct dis386 grps[][8] = {
/* GRP1b */
{
- { "addA", Eb, Ib },
- { "orA", Eb, Ib },
- { "adcA", Eb, Ib },
- { "sbbA", Eb, Ib },
- { "andA", Eb, Ib },
- { "subA", Eb, Ib },
- { "xorA", Eb, Ib },
- { "cmpA", Eb, Ib }
+ { "addA", Eb, Ib, XX },
+ { "orA", Eb, Ib, XX },
+ { "adcA", Eb, Ib, XX },
+ { "sbbA", Eb, Ib, XX },
+ { "andA", Eb, Ib, XX },
+ { "subA", Eb, Ib, XX },
+ { "xorA", Eb, Ib, XX },
+ { "cmpA", Eb, Ib, XX }
},
/* GRP1S */
{
- { "addQ", Ev, Iv },
- { "orQ", Ev, Iv },
- { "adcQ", Ev, Iv },
- { "sbbQ", Ev, Iv },
- { "andQ", Ev, Iv },
- { "subQ", Ev, Iv },
- { "xorQ", Ev, Iv },
- { "cmpQ", Ev, Iv }
+ { "addQ", Ev, Iv, XX },
+ { "orQ", Ev, Iv, XX },
+ { "adcQ", Ev, Iv, XX },
+ { "sbbQ", Ev, Iv, XX },
+ { "andQ", Ev, Iv, XX },
+ { "subQ", Ev, Iv, XX },
+ { "xorQ", Ev, Iv, XX },
+ { "cmpQ", Ev, Iv, XX }
},
/* GRP1Ss */
{
- { "addQ", Ev, sIb },
- { "orQ", Ev, sIb },
- { "adcQ", Ev, sIb },
- { "sbbQ", Ev, sIb },
- { "andQ", Ev, sIb },
- { "subQ", Ev, sIb },
- { "xorQ", Ev, sIb },
- { "cmpQ", Ev, sIb }
+ { "addQ", Ev, sIb, XX },
+ { "orQ", Ev, sIb, XX },
+ { "adcQ", Ev, sIb, XX },
+ { "sbbQ", Ev, sIb, XX },
+ { "andQ", Ev, sIb, XX },
+ { "subQ", Ev, sIb, XX },
+ { "xorQ", Ev, sIb, XX },
+ { "cmpQ", Ev, sIb, XX }
},
/* GRP2b */
{
- { "rolA", Eb, Ib },
- { "rorA", Eb, Ib },
- { "rclA", Eb, Ib },
- { "rcrA", Eb, Ib },
- { "shlA", Eb, Ib },
- { "shrA", Eb, Ib },
- { "(bad)" },
- { "sarA", Eb, Ib },
+ { "rolA", Eb, Ib, XX },
+ { "rorA", Eb, Ib, XX },
+ { "rclA", Eb, Ib, XX },
+ { "rcrA", Eb, Ib, XX },
+ { "shlA", Eb, Ib, XX },
+ { "shrA", Eb, Ib, XX },
+ { "(bad)", XX, XX, XX },
+ { "sarA", Eb, Ib, XX },
},
/* GRP2S */
{
- { "rolQ", Ev, Ib },
- { "rorQ", Ev, Ib },
- { "rclQ", Ev, Ib },
- { "rcrQ", Ev, Ib },
- { "shlQ", Ev, Ib },
- { "shrQ", Ev, Ib },
- { "(bad)" },
- { "sarQ", Ev, Ib },
+ { "rolQ", Ev, Ib, XX },
+ { "rorQ", Ev, Ib, XX },
+ { "rclQ", Ev, Ib, XX },
+ { "rcrQ", Ev, Ib, XX },
+ { "shlQ", Ev, Ib, XX },
+ { "shrQ", Ev, Ib, XX },
+ { "(bad)", XX, XX, XX },
+ { "sarQ", Ev, Ib, XX },
},
/* GRP2b_one */
{
- { "rolA", Eb },
- { "rorA", Eb },
- { "rclA", Eb },
- { "rcrA", Eb },
- { "shlA", Eb },
- { "shrA", Eb },
- { "(bad)" },
- { "sarA", Eb },
+ { "rolA", Eb, XX, XX },
+ { "rorA", Eb, XX, XX },
+ { "rclA", Eb, XX, XX },
+ { "rcrA", Eb, XX, XX },
+ { "shlA", Eb, XX, XX },
+ { "shrA", Eb, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "sarA", Eb, XX, XX },
},
/* GRP2S_one */
{
- { "rolQ", Ev },
- { "rorQ", Ev },
- { "rclQ", Ev },
- { "rcrQ", Ev },
- { "shlQ", Ev },
- { "shrQ", Ev },
- { "(bad)" },
- { "sarQ", Ev },
+ { "rolQ", Ev, XX, XX },
+ { "rorQ", Ev, XX, XX },
+ { "rclQ", Ev, XX, XX },
+ { "rcrQ", Ev, XX, XX },
+ { "shlQ", Ev, XX, XX },
+ { "shrQ", Ev, XX, XX },
+ { "(bad)", XX, XX, XX},
+ { "sarQ", Ev, XX, XX },
},
/* GRP2b_cl */
{
- { "rolA", Eb, CL },
- { "rorA", Eb, CL },
- { "rclA", Eb, CL },
- { "rcrA", Eb, CL },
- { "shlA", Eb, CL },
- { "shrA", Eb, CL },
- { "(bad)" },
- { "sarA", Eb, CL },
+ { "rolA", Eb, CL, XX },
+ { "rorA", Eb, CL, XX },
+ { "rclA", Eb, CL, XX },
+ { "rcrA", Eb, CL, XX },
+ { "shlA", Eb, CL, XX },
+ { "shrA", Eb, CL, XX },
+ { "(bad)", XX, XX, XX },
+ { "sarA", Eb, CL, XX },
},
/* GRP2S_cl */
{
- { "rolQ", Ev, CL },
- { "rorQ", Ev, CL },
- { "rclQ", Ev, CL },
- { "rcrQ", Ev, CL },
- { "shlQ", Ev, CL },
- { "shrQ", Ev, CL },
- { "(bad)" },
- { "sarQ", Ev, CL }
+ { "rolQ", Ev, CL, XX },
+ { "rorQ", Ev, CL, XX },
+ { "rclQ", Ev, CL, XX },
+ { "rcrQ", Ev, CL, XX },
+ { "shlQ", Ev, CL, XX },
+ { "shrQ", Ev, CL, XX },
+ { "(bad)", XX, XX, XX },
+ { "sarQ", Ev, CL, XX }
},
/* GRP3b */
{
- { "testA", Eb, Ib },
- { "(bad)", Eb },
- { "notA", Eb },
- { "negA", Eb },
- { "mulB", AL, Eb },
- { "imulB", AL, Eb },
- { "divB", AL, Eb },
- { "idivB", AL, Eb }
+ { "testA", Eb, Ib, XX },
+ { "(bad)", Eb, XX, XX },
+ { "notA", Eb, XX, XX },
+ { "negA", Eb, XX, XX },
+ { "mulB", AL, Eb, XX },
+ { "imulB", AL, Eb, XX },
+ { "divB", AL, Eb, XX },
+ { "idivB", AL, Eb, XX }
},
/* GRP3S */
{
- { "testQ", Ev, Iv },
- { "(bad)" },
- { "notQ", Ev },
- { "negQ", Ev },
- { "mulS", eAX, Ev },
- { "imulS", eAX, Ev },
- { "divS", eAX, Ev },
- { "idivS", eAX, Ev },
+ { "testQ", Ev, Iv, XX },
+ { "(bad)", XX, XX, XX },
+ { "notQ", Ev, XX, XX },
+ { "negQ", Ev, XX, XX },
+ { "mulS", eAX, Ev, XX },
+ { "imulS", eAX, Ev, XX },
+ { "divS", eAX, Ev, XX },
+ { "idivS", eAX, Ev, XX },
},
/* GRP4 */
{
- { "incA", Eb },
- { "decA", Eb },
- { "(bad)" },
- { "(bad)" },
- { "(bad)" },
- { "(bad)" },
- { "(bad)" },
- { "(bad)" },
+ { "incA", Eb, XX, XX },
+ { "decA", Eb, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
},
/* GRP5 */
{
- { "incQ", Ev },
- { "decQ", Ev },
- { "callP", indirEv },
- { "callP", indirEv },
- { "jmpP", indirEv },
- { "ljmpP", indirEv },
- { "pushQ", Ev },
- { "(bad)" },
+ { "incQ", Ev, XX, XX },
+ { "decQ", Ev, XX, XX },
+ { "callP", indirEv, XX, XX },
+ { "callP", indirEv, XX, XX },
+ { "jmpP", indirEv, XX, XX },
+ { "ljmpP", indirEv, XX, XX },
+ { "pushQ", Ev, XX, XX },
+ { "(bad)", XX, XX, XX },
},
/* GRP6 */
{
- { "sldt", Ew },
- { "str", Ew },
- { "lldt", Ew },
- { "ltr", Ew },
- { "verr", Ew },
- { "verw", Ew },
- { "(bad)" },
- { "(bad)" }
+ { "sldt", Ew, XX, XX },
+ { "str", Ew, XX, XX },
+ { "lldt", Ew, XX, XX },
+ { "ltr", Ew, XX, XX },
+ { "verr", Ew, XX, XX },
+ { "verw", Ew, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX }
},
/* GRP7 */
{
- { "sgdt", Ew },
- { "sidt", Ew },
- { "lgdt", Ew },
- { "lidt", Ew },
- { "smsw", Ew },
- { "(bad)" },
- { "lmsw", Ew },
- { "invlpg", Ew },
+ { "sgdt", Ew, XX, XX },
+ { "sidt", Ew, XX, XX },
+ { "lgdt", Ew, XX, XX },
+ { "lidt", Ew, XX, XX },
+ { "smsw", Ew, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "lmsw", Ew, XX, XX },
+ { "invlpg", Ew, XX, XX },
},
/* GRP8 */
{
- { "(bad)" },
- { "(bad)" },
- { "(bad)" },
- { "(bad)" },
- { "btQ", Ev, Ib },
- { "btsQ", Ev, Ib },
- { "btrQ", Ev, Ib },
- { "btcQ", Ev, Ib },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "btQ", Ev, Ib, XX },
+ { "btsQ", Ev, Ib, XX },
+ { "btrQ", Ev, Ib, XX },
+ { "btcQ", Ev, Ib, XX },
},
/* GRP9 */
{
- { "(bad)" },
- { "cmpxchg8b", Ev },
- { "(bad)" },
- { "(bad)" },
- { "(bad)" },
- { "(bad)" },
- { "(bad)" },
- { "(bad)" },
+ { "(bad)", XX, XX, XX },
+ { "cmpxchg8b", Ev, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
},
/* GRP10 */
{
- { "(bad)" },
- { "(bad)" },
- { "psrlw", MS, Ib },
- { "(bad)" },
- { "psraw", MS, Ib },
- { "(bad)" },
- { "psllw", MS, Ib },
- { "(bad)" },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "psrlw", MS, Ib, XX },
+ { "(bad)", XX, XX, XX },
+ { "psraw", MS, Ib, XX },
+ { "(bad)", XX, XX, XX },
+ { "psllw", MS, Ib, XX },
+ { "(bad)", XX, XX, XX },
},
/* GRP11 */
{
- { "(bad)" },
- { "(bad)" },
- { "psrld", MS, Ib },
- { "(bad)" },
- { "psrad", MS, Ib },
- { "(bad)" },
- { "pslld", MS, Ib },
- { "(bad)" },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "psrld", MS, Ib, XX },
+ { "(bad)", XX, XX, XX },
+ { "psrad", MS, Ib, XX },
+ { "(bad)", XX, XX, XX },
+ { "pslld", MS, Ib, XX },
+ { "(bad)", XX, XX, XX },
},
/* GRP12 */
{
- { "(bad)" },
- { "(bad)" },
- { "psrlq", MS, Ib },
- { "(bad)" },
- { "(bad)" },
- { "(bad)" },
- { "psllq", MS, Ib },
- { "(bad)" },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "psrlq", MS, Ib, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "psllq", MS, Ib, XX },
+ { "(bad)", XX, XX, XX },
},
/* GRP13 */
{
- { "fxsave", Ev },
- { "fxrstor", Ev },
- { "(bad)" },
- { "(bad)" },
- { "(bad)" },
- { "(bad)" },
- { "(bad)" },
- { "(bad)" },
+ { "fxsave", Ev, XX, XX },
+ { "fxrstor", Ev, XX, XX },
+ { "ldmxcsr", Ev, XX, XX },
+ { "stmxcsr", Ev, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "sfence", None, XX, XX },
},
/* GRP14 */
{
- { "prefetch", Eb },
- { "prefetchw", Eb },
- { "(bad)" },
- { "(bad)" },
- { "(bad)" },
- { "(bad)" },
- { "(bad)" },
- { "(bad)" },
+ { "prefetchnta", Ev, XX, XX },
+ { "prefetcht0", Ev, XX, XX },
+ { "prefetcht1", Ev, XX, XX },
+ { "prefetcht2", Ev, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ },
+ /* GRPAMD */
+ {
+ { "prefetch", Eb, XX, XX },
+ { "prefetchw", Eb, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
}
};
-#define PREFIX_REPZ 1
-#define PREFIX_REPNZ 2
-#define PREFIX_LOCK 4
-#define PREFIX_CS 8
-#define PREFIX_SS 0x10
-#define PREFIX_DS 0x20
-#define PREFIX_ES 0x40
-#define PREFIX_FS 0x80
-#define PREFIX_GS 0x100
-#define PREFIX_DATA 0x200
-#define PREFIX_ADDR 0x400
-#define PREFIX_FWAIT 0x800
+static const struct dis386 prefix_user_table[][2] = {
+ /* PREGRP0 */
+ {
+ { "addps", XM, EX, XX },
+ { "addss", XM, EX, XX },
+ },
+ /* PREGRP1 */
+ {
+ { "", XM, EX, OPSIMD }, /* See OP_SIMD_SUFFIX */
+ { "", XM, EX, OPSIMD },
+ },
+ /* PREGRP2 */
+ {
+ { "cvtpi2ps", XM, EM, XX },
+ { "cvtsi2ss", XM, Ev, XX },
+ },
+ /* PREGRP3 */
+ {
+ { "cvtps2pi", MX, EX, XX },
+ { "cvtss2si", Gv, EX, XX },
+ },
+ /* PREGRP4 */
+ {
+ { "cvttps2pi", MX, EX, XX },
+ { "cvttss2si", Gv, EX, XX },
+ },
+ /* PREGRP5 */
+ {
+ { "divps", XM, EX, XX },
+ { "divss", XM, EX, XX },
+ },
+ /* PREGRP6 */
+ {
+ { "maxps", XM, EX, XX },
+ { "maxss", XM, EX, XX },
+ },
+ /* PREGRP7 */
+ {
+ { "minps", XM, EX, XX },
+ { "minss", XM, EX, XX },
+ },
+ /* PREGRP8 */
+ {
+ { "movups", XM, EX, XX },
+ { "movss", XM, EX, XX },
+ },
+ /* PREGRP9 */
+ {
+ { "movups", EX, XM, XX },
+ { "movss", EX, XM, XX },
+ },
+ /* PREGRP10 */
+ {
+ { "mulps", XM, EX, XX },
+ { "mulss", XM, EX, XX },
+ },
+ /* PREGRP11 */
+ {
+ { "rcpps", XM, EX, XX },
+ { "rcpss", XM, EX, XX },
+ },
+ /* PREGRP12 */
+ {
+ { "rsqrtps", XM, EX, XX },
+ { "rsqrtss", XM, EX, XX },
+ },
+ /* PREGRP13 */
+ {
+ { "sqrtps", XM, EX, XX },
+ { "sqrtss", XM, EX, XX },
+ },
+ /* PREGRP14 */
+ {
+ { "subps", XM, EX, XX },
+ { "subss", XM, EX, XX },
+ }
+};
-static int prefixes;
+#define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
static void
ckprefix ()
{
prefixes = 0;
+ used_prefixes = 0;
while (1)
{
FETCH_DATA (the_info, codep + 1);
@@ -1706,7 +1991,7 @@ ckprefix ()
case 0x67:
prefixes |= PREFIX_ADDR;
break;
- case 0x9b:
+ case FWAIT_OPCODE:
/* fwait is really an instruction. If there are prefixes
before the fwait, they belong to the fwait, *not* to the
following instruction. */
@@ -1725,6 +2010,45 @@ ckprefix ()
}
}
+/* Return the name of the prefix byte PREF, or NULL if PREF is not a
+ prefix byte. */
+
+static const char *
+prefix_name (pref, sizeflag)
+ int pref;
+ int sizeflag;
+{
+ switch (pref)
+ {
+ case 0xf3:
+ return "repz";
+ case 0xf2:
+ return "repnz";
+ case 0xf0:
+ return "lock";
+ case 0x2e:
+ return "cs";
+ case 0x36:
+ return "ss";
+ case 0x3e:
+ return "ds";
+ case 0x26:
+ return "es";
+ case 0x64:
+ return "fs";
+ case 0x65:
+ return "gs";
+ case 0x66:
+ return (sizeflag & DFLAG) ? "data16" : "data32";
+ case 0x67:
+ return (sizeflag & AFLAG) ? "addr16" : "addr32";
+ case FWAIT_OPCODE:
+ return "fwait";
+ default:
+ return NULL;
+ }
+}
+
static char op1out[100], op2out[100], op3out[100];
static int op_ad, op_index[3];
static unsigned int op_address[3];
@@ -1740,8 +2064,6 @@ static unsigned int start_pc;
* The function returns the length of this instruction in bytes.
*/
-static int print_insn_x86
- PARAMS ((bfd_vma pc, disassemble_info *info, int sizeflag));
static int print_insn_i386
PARAMS ((bfd_vma pc, disassemble_info *info));
@@ -1784,43 +2106,35 @@ print_insn_i386 (pc, info)
bfd_vma pc;
disassemble_info *info;
{
- int flags;
- if (info->mach == bfd_mach_i386_i386
- || info->mach == bfd_mach_i386_i386_intel_syntax)
- flags = AFLAG|DFLAG;
- else if (info->mach == bfd_mach_i386_i8086)
- flags = 0;
- else
- abort ();
- return print_insn_x86 (pc, info, flags);
-}
-
-static int
-print_insn_x86 (pc, info, sizeflag)
- bfd_vma pc;
- disassemble_info *info;
- int sizeflag;
-{
- struct dis386 *dp;
+ const struct dis386 *dp;
int i;
int two_source_ops;
char *first, *second, *third;
int needcomma;
unsigned char need_modrm;
+ unsigned char uses_f3_prefix;
+ VOLATILE int sizeflag;
+ VOLATILE int orig_sizeflag;
struct dis_private priv;
bfd_byte *inbuf = priv.the_buffer;
- /* The output looks better if we put 5 bytes on a line, since that
- puts long word instructions on a single line. */
- info->bytes_per_line = 5;
+ if (info->mach == bfd_mach_i386_i386
+ || info->mach == bfd_mach_i386_i386_intel_syntax)
+ sizeflag = AFLAG|DFLAG;
+ else if (info->mach == bfd_mach_i386_i8086)
+ sizeflag = 0;
+ else
+ abort ();
+ orig_sizeflag = sizeflag;
+
+ /* The output looks better if we put 6 bytes on a line, since that
+ puts most long word instructions on a single line. */
+ info->bytes_per_line = 6;
info->private_data = (PTR) &priv;
priv.max_fetched = priv.the_buffer;
priv.insn_start = pc;
- if (setjmp (priv.bailout) != 0)
- /* Error return. */
- return -1;
obuf[0] = 0;
op1out[0] = 0;
@@ -1834,6 +2148,31 @@ print_insn_x86 (pc, info, sizeflag)
start_codep = inbuf;
codep = inbuf;
+ if (setjmp (priv.bailout) != 0)
+ {
+ const char *name;
+
+ /* Getting here means we tried for data but didn't get it. That
+ means we have an incomplete instruction of some sort. Just
+ print the first byte as a prefix or a .byte pseudo-op. */
+ if (codep > inbuf)
+ {
+ name = prefix_name (inbuf[0], orig_sizeflag);
+ if (name != NULL)
+ (*info->fprintf_func) (info->stream, "%s", name);
+ else
+ {
+ /* Just print the first byte as a .byte instruction. */
+ (*info->fprintf_func) (info->stream, ".byte 0x%x",
+ (unsigned int) inbuf[0]);
+ }
+
+ return 1;
+ }
+
+ return -1;
+ }
+
ckprefix ();
insn_codep = codep;
@@ -1846,29 +2185,15 @@ print_insn_x86 (pc, info, sizeflag)
if ((prefixes & PREFIX_FWAIT)
&& ((*codep < 0xd8) || (*codep > 0xdf)))
{
- /* fwait not followed by floating point instruction. */
- (*info->fprintf_func) (info->stream, "fwait");
- /* There may be other prefixes. Skip any before the fwait. */
- return codep - inbuf;
- }
-
- if (prefixes & PREFIX_REPZ)
- oappend ("repz ");
- if (prefixes & PREFIX_REPNZ)
- oappend ("repnz ");
- if (prefixes & PREFIX_LOCK)
- oappend ("lock ");
-
- if (prefixes & PREFIX_DATA)
- sizeflag ^= DFLAG;
-
- if (prefixes & PREFIX_ADDR)
- {
- sizeflag ^= AFLAG;
- if (sizeflag & AFLAG)
- oappend ("addr32 ");
- else
- oappend ("addr16 ");
+ const char *name;
+
+ /* fwait not followed by floating point instruction. Print the
+ first prefix, which is probably fwait itself. */
+ name = prefix_name (inbuf[0], orig_sizeflag);
+ if (name == NULL)
+ name = INTERNAL_DISASSEMBLER_ERROR;
+ (*info->fprintf_func) (info->stream, "%s", name);
+ return 1;
}
if (*codep == 0x0f)
@@ -1879,6 +2204,7 @@ print_insn_x86 (pc, info, sizeflag)
else
dp = &dis386_twobyte_att[*++codep];
need_modrm = twobyte_has_modrm[*codep];
+ uses_f3_prefix = twobyte_uses_f3_prefix[*codep];
}
else
{
@@ -1887,9 +2213,39 @@ print_insn_x86 (pc, info, sizeflag)
else
dp = &dis386_att[*codep];
need_modrm = onebyte_has_modrm[*codep];
+ uses_f3_prefix = 0;
}
codep++;
+ if (!uses_f3_prefix && (prefixes & PREFIX_REPZ))
+ {
+ oappend ("repz ");
+ used_prefixes |= PREFIX_REPZ;
+ }
+ if (prefixes & PREFIX_REPNZ)
+ {
+ oappend ("repnz ");
+ used_prefixes |= PREFIX_REPNZ;
+ }
+ if (prefixes & PREFIX_LOCK)
+ {
+ oappend ("lock ");
+ used_prefixes |= PREFIX_LOCK;
+ }
+
+ if (prefixes & PREFIX_DATA)
+ sizeflag ^= DFLAG;
+
+ if (prefixes & PREFIX_ADDR)
+ {
+ sizeflag ^= AFLAG;
+ if (sizeflag & AFLAG)
+ oappend ("addr32 ");
+ else
+ oappend ("addr16 ");
+ used_prefixes |= PREFIX_ADDR;
+ }
+
if (need_modrm)
{
FETCH_DATA (info, codep + 1);
@@ -1905,7 +2261,21 @@ print_insn_x86 (pc, info, sizeflag)
else
{
if (dp->name == NULL)
- dp = &grps[dp->bytemode1][reg];
+ {
+ switch(dp->bytemode2)
+ {
+ case USE_GROUPS:
+ dp = &grps[dp->bytemode1][reg];
+ break;
+ case USE_PREFIX_USER_TABLE:
+ dp = &prefix_user_table[dp->bytemode1][prefixes & PREFIX_REPZ ? 1 : 0];
+ used_prefixes |= (prefixes & PREFIX_REPZ);
+ break;
+ default:
+ oappend (INTERNAL_DISASSEMBLER_ERROR);
+ break;
+ }
+ }
putop (dp->name, sizeflag);
@@ -1925,6 +2295,21 @@ print_insn_x86 (pc, info, sizeflag)
(*dp->op3)(dp->bytemode3, sizeflag);
}
+ /* See if any prefixes were not used. If so, print the first one
+ separately. If we don't do this, we'll wind up printing an
+ instruction stream which does not precisely correspond to the
+ bytes we are disassembling. */
+ if ((prefixes & ~used_prefixes) != 0)
+ {
+ const char *name;
+
+ name = prefix_name (inbuf[0], orig_sizeflag);
+ if (name == NULL)
+ name = INTERNAL_DISASSEMBLER_ERROR;
+ (*info->fprintf_func) (info->stream, "%s", name);
+ return 1;
+ }
+
obufp = obuf + strlen (obuf);
for (i = strlen (obuf); i < 6; i++)
oappend (" ");
@@ -1933,7 +2318,7 @@ print_insn_x86 (pc, info, sizeflag)
/* The enter and bound instructions are printed with operands in the same
order as the intel book; everything else is printed in reverse order. */
- if (intel_syntax || two_source_ops)
+ if (intel_syntax || two_source_ops)
{
first = op1out;
second = op2out;
@@ -1979,7 +2364,7 @@ print_insn_x86 (pc, info, sizeflag)
return codep - inbuf;
}
-static char *float_mem_att[] = {
+static const char *float_mem_att[] = {
/* d8 */
"fadds",
"fmuls",
@@ -2054,7 +2439,7 @@ static char *float_mem_att[] = {
"fistpll",
};
-static char *float_mem_intel[] = {
+static const char *float_mem_intel[] = {
/* d8 */
"fadd",
"fmul",
@@ -2132,34 +2517,34 @@ static char *float_mem_intel[] = {
#define ST OP_ST, 0
#define STi OP_STi, 0
-#define FGRPd9_2 NULL, NULL, 0
-#define FGRPd9_4 NULL, NULL, 1
-#define FGRPd9_5 NULL, NULL, 2
-#define FGRPd9_6 NULL, NULL, 3
-#define FGRPd9_7 NULL, NULL, 4
-#define FGRPda_5 NULL, NULL, 5
-#define FGRPdb_4 NULL, NULL, 6
-#define FGRPde_3 NULL, NULL, 7
-#define FGRPdf_4 NULL, NULL, 8
-
-static struct dis386 float_reg[][8] = {
+#define FGRPd9_2 NULL, NULL, 0, NULL, 0, NULL, 0
+#define FGRPd9_4 NULL, NULL, 1, NULL, 0, NULL, 0
+#define FGRPd9_5 NULL, NULL, 2, NULL, 0, NULL, 0
+#define FGRPd9_6 NULL, NULL, 3, NULL, 0, NULL, 0
+#define FGRPd9_7 NULL, NULL, 4, NULL, 0, NULL, 0
+#define FGRPda_5 NULL, NULL, 5, NULL, 0, NULL, 0
+#define FGRPdb_4 NULL, NULL, 6, NULL, 0, NULL, 0
+#define FGRPde_3 NULL, NULL, 7, NULL, 0, NULL, 0
+#define FGRPdf_4 NULL, NULL, 8, NULL, 0, NULL, 0
+
+static const struct dis386 float_reg[][8] = {
/* d8 */
{
- { "fadd", ST, STi },
- { "fmul", ST, STi },
- { "fcom", STi },
- { "fcomp", STi },
- { "fsub", ST, STi },
- { "fsubr", ST, STi },
- { "fdiv", ST, STi },
- { "fdivr", ST, STi },
+ { "fadd", ST, STi, XX },
+ { "fmul", ST, STi, XX },
+ { "fcom", STi, XX, XX },
+ { "fcomp", STi, XX, XX },
+ { "fsub", ST, STi, XX },
+ { "fsubr", ST, STi, XX },
+ { "fdiv", ST, STi, XX },
+ { "fdivr", ST, STi, XX },
},
/* d9 */
{
- { "fld", STi },
- { "fxch", STi },
+ { "fld", STi, XX, XX },
+ { "fxch", STi, XX, XX },
{ FGRPd9_2 },
- { "(bad)" },
+ { "(bad)", XX, XX, XX },
{ FGRPd9_4 },
{ FGRPd9_5 },
{ FGRPd9_6 },
@@ -2167,83 +2552,83 @@ static struct dis386 float_reg[][8] = {
},
/* da */
{
- { "fcmovb", ST, STi },
- { "fcmove", ST, STi },
- { "fcmovbe",ST, STi },
- { "fcmovu", ST, STi },
- { "(bad)" },
+ { "fcmovb", ST, STi, XX },
+ { "fcmove", ST, STi, XX },
+ { "fcmovbe",ST, STi, XX },
+ { "fcmovu", ST, STi, XX },
+ { "(bad)", XX, XX, XX },
{ FGRPda_5 },
- { "(bad)" },
- { "(bad)" },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
},
/* db */
{
- { "fcmovnb",ST, STi },
- { "fcmovne",ST, STi },
- { "fcmovnbe",ST, STi },
- { "fcmovnu",ST, STi },
+ { "fcmovnb",ST, STi, XX },
+ { "fcmovne",ST, STi, XX },
+ { "fcmovnbe",ST, STi, XX },
+ { "fcmovnu",ST, STi, XX },
{ FGRPdb_4 },
- { "fucomi", ST, STi },
- { "fcomi", ST, STi },
- { "(bad)" },
+ { "fucomi", ST, STi, XX },
+ { "fcomi", ST, STi, XX },
+ { "(bad)", XX, XX, XX },
},
/* dc */
{
- { "fadd", STi, ST },
- { "fmul", STi, ST },
- { "(bad)" },
- { "(bad)" },
+ { "fadd", STi, ST, XX },
+ { "fmul", STi, ST, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
#if UNIXWARE_COMPAT
- { "fsub", STi, ST },
- { "fsubr", STi, ST },
- { "fdiv", STi, ST },
- { "fdivr", STi, ST },
+ { "fsub", STi, ST, XX },
+ { "fsubr", STi, ST, XX },
+ { "fdiv", STi, ST, XX },
+ { "fdivr", STi, ST, XX },
#else
- { "fsubr", STi, ST },
- { "fsub", STi, ST },
- { "fdivr", STi, ST },
- { "fdiv", STi, ST },
+ { "fsubr", STi, ST, XX },
+ { "fsub", STi, ST, XX },
+ { "fdivr", STi, ST, XX },
+ { "fdiv", STi, ST, XX },
#endif
},
/* dd */
{
- { "ffree", STi },
- { "(bad)" },
- { "fst", STi },
- { "fstp", STi },
- { "fucom", STi },
- { "fucomp", STi },
- { "(bad)" },
- { "(bad)" },
+ { "ffree", STi, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "fst", STi, XX, XX },
+ { "fstp", STi, XX, XX },
+ { "fucom", STi, XX, XX },
+ { "fucomp", STi, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
},
/* de */
{
- { "faddp", STi, ST },
- { "fmulp", STi, ST },
- { "(bad)" },
+ { "faddp", STi, ST, XX },
+ { "fmulp", STi, ST, XX },
+ { "(bad)", XX, XX, XX },
{ FGRPde_3 },
#if UNIXWARE_COMPAT
- { "fsubp", STi, ST },
- { "fsubrp", STi, ST },
- { "fdivp", STi, ST },
- { "fdivrp", STi, ST },
+ { "fsubp", STi, ST, XX },
+ { "fsubrp", STi, ST, XX },
+ { "fdivp", STi, ST, XX },
+ { "fdivrp", STi, ST, XX },
#else
- { "fsubrp", STi, ST },
- { "fsubp", STi, ST },
- { "fdivrp", STi, ST },
- { "fdivp", STi, ST },
+ { "fsubrp", STi, ST, XX },
+ { "fsubp", STi, ST, XX },
+ { "fdivrp", STi, ST, XX },
+ { "fdivp", STi, ST, XX },
#endif
},
/* df */
{
- { "(bad)" },
- { "(bad)" },
- { "(bad)" },
- { "(bad)" },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
{ FGRPdf_4 },
- { "fucomip",ST, STi },
- { "fcomip", ST, STi },
- { "(bad)" },
+ { "fucomip",ST, STi, XX },
+ { "fcomip", ST, STi, XX },
+ { "(bad)", XX, XX, XX },
},
};
@@ -2300,7 +2685,7 @@ static void
dofloat (sizeflag)
int sizeflag;
{
- struct dis386 *dp;
+ const struct dis386 *dp;
unsigned char floatop;
floatop = codep[-1];
@@ -2316,7 +2701,7 @@ dofloat (sizeflag)
OP_E (x_mode, sizeflag);
else if (floatop == 0xdd)
OP_E (d_mode, sizeflag);
- else
+ else
OP_E (v_mode, sizeflag);
return;
}
@@ -2347,8 +2732,8 @@ dofloat (sizeflag)
/* ARGSUSED */
static void
OP_ST (ignore, sizeflag)
- int ignore;
- int sizeflag;
+ int ignore ATTRIBUTE_UNUSED;
+ int sizeflag ATTRIBUTE_UNUSED;
{
oappend ("%st");
}
@@ -2356,8 +2741,8 @@ OP_ST (ignore, sizeflag)
/* ARGSUSED */
static void
OP_STi (ignore, sizeflag)
- int ignore;
- int sizeflag;
+ int ignore ATTRIBUTE_UNUSED;
+ int sizeflag ATTRIBUTE_UNUSED;
{
sprintf (scratchbuf, "%%st(%d)", rm);
oappend (scratchbuf);
@@ -2367,10 +2752,10 @@ OP_STi (ignore, sizeflag)
/* capital letters in template are macros */
static void
putop (template, sizeflag)
- char *template;
+ const char *template;
int sizeflag;
{
- char *p;
+ const char *p;
for (p = template; *p; p++)
{
@@ -2412,6 +2797,8 @@ putop (template, sizeflag)
case 'N':
if ((prefixes & PREFIX_FWAIT) == 0)
*obufp++ = 'n';
+ else
+ used_prefixes |= PREFIX_FWAIT;
break;
case 'P':
if (intel_syntax)
@@ -2426,6 +2813,7 @@ putop (template, sizeflag)
*obufp++ = 'l';
else
*obufp++ = 'w';
+ used_prefixes |= (prefixes & PREFIX_DATA);
}
break;
case 'Q':
@@ -2441,15 +2829,31 @@ putop (template, sizeflag)
*obufp++ = 'l';
else
*obufp++ = 'w';
+ used_prefixes |= (prefixes & PREFIX_DATA);
}
break;
case 'R':
if (intel_syntax)
- break;
- if (sizeflag & DFLAG)
- *obufp++ = 'l';
+ {
+ if (sizeflag & DFLAG)
+ {
+ *obufp++ = 'd';
+ *obufp++ = 'q';
+ }
+ else
+ {
+ *obufp++ = 'w';
+ *obufp++ = 'd';
+ }
+ }
else
- *obufp++ = 'w';
+ {
+ if (sizeflag & DFLAG)
+ *obufp++ = 'l';
+ else
+ *obufp++ = 'w';
+ }
+ used_prefixes |= (prefixes & PREFIX_DATA);
break;
case 'S':
if (intel_syntax)
@@ -2461,17 +2865,29 @@ putop (template, sizeflag)
*obufp++ = 'l';
else
*obufp++ = 'w';
+ used_prefixes |= (prefixes & PREFIX_DATA);
}
#endif
break;
case 'W':
- if (intel_syntax)
- break;
/* operand size flag for cwtl, cbtw */
if (sizeflag & DFLAG)
*obufp++ = 'w';
else
*obufp++ = 'b';
+ if (intel_syntax)
+ {
+ if (sizeflag & DFLAG)
+ {
+ *obufp++ = 'd';
+ *obufp++ = 'e';
+ }
+ else
+ {
+ *obufp++ = 'w';
+ }
+ }
+ used_prefixes |= (prefixes & PREFIX_DATA);
break;
}
}
@@ -2480,7 +2896,7 @@ putop (template, sizeflag)
static void
oappend (s)
- char *s;
+ const char *s;
{
strcpy (obufp, s);
obufp += strlen (s);
@@ -2490,17 +2906,35 @@ static void
append_seg ()
{
if (prefixes & PREFIX_CS)
- oappend ("%cs:");
+ {
+ oappend ("%cs:");
+ used_prefixes |= PREFIX_CS;
+ }
if (prefixes & PREFIX_DS)
- oappend ("%ds:");
+ {
+ oappend ("%ds:");
+ used_prefixes |= PREFIX_DS;
+ }
if (prefixes & PREFIX_SS)
- oappend ("%ss:");
+ {
+ oappend ("%ss:");
+ used_prefixes |= PREFIX_SS;
+ }
if (prefixes & PREFIX_ES)
- oappend ("%es:");
+ {
+ oappend ("%es:");
+ used_prefixes |= PREFIX_ES;
+ }
if (prefixes & PREFIX_FS)
- oappend ("%fs:");
+ {
+ oappend ("%fs:");
+ used_prefixes |= PREFIX_FS;
+ }
if (prefixes & PREFIX_GS)
- oappend ("%gs:");
+ {
+ oappend ("%gs:");
+ used_prefixes |= PREFIX_GS;
+ }
}
static void
@@ -2533,14 +2967,22 @@ OP_E (bytemode, sizeflag)
case w_mode:
oappend (names16[rm]);
break;
+ case d_mode:
+ oappend (names32[rm]);
+ break;
case v_mode:
if (sizeflag & DFLAG)
oappend (names32[rm]);
else
oappend (names16[rm]);
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ break;
+ case 0:
+ if ( !(codep[-2] == 0xAE && codep[-1] == 0xF8 /* sfence */))
+ BadOp(); /* bad sfence,lea,lds,les,lfs,lgs,lss modrm */
break;
default:
- oappend ("<bad dis table>");
+ oappend (INTERNAL_DISASSEMBLER_ERROR);
break;
}
return;
@@ -2597,7 +3039,7 @@ OP_E (bytemode, sizeflag)
sprintf (scratchbuf, "0x%x", disp);
oappend (scratchbuf);
}
-
+
if (havebase || (havesib && (index != 4 || scale != 0)))
{
if (intel_syntax)
@@ -2645,7 +3087,7 @@ OP_E (bytemode, sizeflag)
oappend (scratchbuf);
}
if (!intel_syntax
- || (intel_syntax
+ || (intel_syntax
&& bytemode != b_mode
&& bytemode != w_mode
&& bytemode != v_mode))
@@ -2735,8 +3177,6 @@ OP_E (bytemode, sizeflag)
}
}
-#define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
-
static void
OP_G (bytemode, sizeflag)
int bytemode;
@@ -2758,6 +3198,7 @@ OP_G (bytemode, sizeflag)
oappend (names32[reg]);
else
oappend (names16[reg]);
+ used_prefixes |= (prefixes & PREFIX_DATA);
break;
default:
oappend (INTERNAL_DISASSEMBLER_ERROR);
@@ -2802,7 +3243,7 @@ OP_REG (code, sizeflag)
int code;
int sizeflag;
{
- char *s;
+ const char *s;
switch (code)
{
@@ -2827,6 +3268,7 @@ OP_REG (code, sizeflag)
s = names32[code - eAX_reg];
else
s = names16[code - eAX_reg];
+ used_prefixes |= (prefixes & PREFIX_DATA);
break;
default:
s = INTERNAL_DISASSEMBLER_ERROR;
@@ -2853,6 +3295,7 @@ OP_I (bytemode, sizeflag)
op = get32 ();
else
op = get16 ();
+ used_prefixes |= (prefixes & PREFIX_DATA);
break;
case w_mode:
op = get16 ();
@@ -2894,6 +3337,7 @@ OP_sI (bytemode, sizeflag)
if ((op & 0x8000) != 0)
op -= 0x10000;
}
+ used_prefixes |= (prefixes & PREFIX_DATA);
break;
case w_mode:
op = get16 ();
@@ -2938,6 +3382,7 @@ OP_J (bytemode, sizeflag)
displacement is added! */
mask = 0xffff;
}
+ used_prefixes |= (prefixes & PREFIX_DATA);
break;
default:
oappend (INTERNAL_DISASSEMBLER_ERROR);
@@ -2952,8 +3397,8 @@ OP_J (bytemode, sizeflag)
/* ARGSUSED */
static void
OP_SEG (dummy, sizeflag)
- int dummy;
- int sizeflag;
+ int dummy ATTRIBUTE_UNUSED;
+ int sizeflag ATTRIBUTE_UNUSED;
{
static char *sreg[] = {
"%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
@@ -2962,54 +3407,33 @@ OP_SEG (dummy, sizeflag)
oappend (sreg[reg]);
}
+/* ARGSUSED */
static void
-OP_DIR (size, sizeflag)
- int size;
+OP_DIR (dummy, sizeflag)
+ int dummy ATTRIBUTE_UNUSED;
int sizeflag;
{
int seg, offset;
- switch (size)
+ if (sizeflag & DFLAG)
{
- case lptr:
- if (sizeflag & DFLAG)
- {
- offset = get32 ();
- seg = get16 ();
- }
- else
- {
- offset = get16 ();
- seg = get16 ();
- }
- sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset);
- oappend (scratchbuf);
- break;
- case v_mode:
- if (sizeflag & DFLAG)
- offset = get32 ();
- else
- {
- offset = get16 ();
- if ((offset & 0x8000) != 0)
- offset -= 0x10000;
- }
-
- offset = start_pc + codep - start_codep + offset;
- set_op (offset);
- sprintf (scratchbuf, "0x%x", offset);
- oappend (scratchbuf);
- break;
- default:
- oappend (INTERNAL_DISASSEMBLER_ERROR);
- break;
+ offset = get32 ();
+ seg = get16 ();
+ }
+ else
+ {
+ offset = get16 ();
+ seg = get16 ();
}
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset);
+ oappend (scratchbuf);
}
/* ARGSUSED */
static void
OP_OFF (ignore, sizeflag)
- int ignore;
+ int ignore ATTRIBUTE_UNUSED;
int sizeflag;
{
int off;
@@ -3039,7 +3463,7 @@ ptr_reg (code, sizeflag)
int code;
int sizeflag;
{
- char *s;
+ const char *s;
oappend ("(");
if (sizeflag & AFLAG)
s = names32[code - eAX_reg];
@@ -3075,27 +3499,12 @@ OP_DSreg (code, sizeflag)
ptr_reg (code, sizeflag);
}
-#if 0
-/* Not used. */
-
-/* ARGSUSED */
-static void
-OP_ONE (dummy, sizeflag)
- int dummy;
- int sizeflag;
-{
- oappend ("1");
-}
-
-#endif
-
/* ARGSUSED */
static void
OP_C (dummy, sizeflag)
- int dummy;
- int sizeflag;
+ int dummy ATTRIBUTE_UNUSED;
+ int sizeflag ATTRIBUTE_UNUSED;
{
- codep++; /* skip mod/rm */
sprintf (scratchbuf, "%%cr%d", reg);
oappend (scratchbuf);
}
@@ -3103,10 +3512,9 @@ OP_C (dummy, sizeflag)
/* ARGSUSED */
static void
OP_D (dummy, sizeflag)
- int dummy;
- int sizeflag;
+ int dummy ATTRIBUTE_UNUSED;
+ int sizeflag ATTRIBUTE_UNUSED;
{
- codep++; /* skip mod/rm */
sprintf (scratchbuf, "%%db%d", reg);
oappend (scratchbuf);
}
@@ -3114,40 +3522,43 @@ OP_D (dummy, sizeflag)
/* ARGSUSED */
static void
OP_T (dummy, sizeflag)
- int dummy;
- int sizeflag;
+ int dummy ATTRIBUTE_UNUSED;
+ int sizeflag ATTRIBUTE_UNUSED;
{
- codep++; /* skip mod/rm */
sprintf (scratchbuf, "%%tr%d", reg);
oappend (scratchbuf);
}
static void
-OP_rm (bytemode, sizeflag)
+OP_Rd (bytemode, sizeflag)
int bytemode;
int sizeflag;
{
- switch (bytemode)
- {
- case d_mode:
- oappend (names32[rm]);
- break;
- case w_mode:
- oappend (names16[rm]);
- break;
- }
+ if (mod == 3)
+ OP_E (bytemode, sizeflag);
+ else
+ BadOp();
}
static void
OP_MMX (ignore, sizeflag)
- int ignore;
- int sizeflag;
+ int ignore ATTRIBUTE_UNUSED;
+ int sizeflag ATTRIBUTE_UNUSED;
{
sprintf (scratchbuf, "%%mm%d", reg);
oappend (scratchbuf);
}
static void
+OP_XMM (bytemode, sizeflag)
+ int bytemode ATTRIBUTE_UNUSED;
+ int sizeflag ATTRIBUTE_UNUSED;
+{
+ sprintf (scratchbuf, "%%xmm%d", reg);
+ oappend (scratchbuf);
+}
+
+static void
OP_EM (bytemode, sizeflag)
int bytemode;
int sizeflag;
@@ -3164,15 +3575,32 @@ OP_EM (bytemode, sizeflag)
}
static void
-OP_MS (ignore, sizeflag)
- int ignore;
+OP_EX (bytemode, sizeflag)
+ int bytemode;
int sizeflag;
{
- ++codep;
- sprintf (scratchbuf, "%%mm%d", rm);
+ if (mod != 3)
+ {
+ OP_E (bytemode, sizeflag);
+ return;
+ }
+
+ codep++;
+ sprintf (scratchbuf, "%%xmm%d", rm);
oappend (scratchbuf);
}
+static void
+OP_MS (bytemode, sizeflag)
+ int bytemode;
+ int sizeflag;
+{
+ if (mod == 3)
+ OP_EM (bytemode, sizeflag);
+ else
+ BadOp();
+}
+
static const char *Suffix3DNow[] = {
/* 00 */ NULL, NULL, NULL, NULL,
/* 04 */ NULL, NULL, NULL, NULL,
@@ -3242,8 +3670,8 @@ static const char *Suffix3DNow[] = {
static void
OP_3DNowSuffix (bytemode, sizeflag)
- int bytemode;
- int sizeflag;
+ int bytemode ATTRIBUTE_UNUSED;
+ int sizeflag ATTRIBUTE_UNUSED;
{
const char *mnemonic;
@@ -3251,18 +3679,81 @@ OP_3DNowSuffix (bytemode, sizeflag)
/* AMD 3DNow! instructions are specified by an opcode suffix in the
place where an 8-bit immediate would normally go. ie. the last
byte of the instruction. */
- mnemonic = Suffix3DNow[*codep++];
+ obufp = obuf + strlen(obuf);
+ mnemonic = Suffix3DNow[*codep++ & 0xff];
if (mnemonic)
- strcat (obuf, mnemonic);
+ oappend (mnemonic);
else
{
/* Since a variable sized modrm/sib chunk is between the start
of the opcode (0x0f0f) and the opcode suffix, we need to do
all the modrm processing first, and don't know until now that
we have a bad opcode. This necessitates some cleaning up. */
- op1out[0] = 0;
- op2out[0] = 0;
- codep = insn_codep + 1;
- strcat (obuf, "(bad)");
+ op1out[0] = '\0';
+ op2out[0] = '\0';
+ BadOp();
}
}
+
+
+static const char *simd_cmp_op [] = {
+ "eq",
+ "lt",
+ "le",
+ "unord",
+ "neq",
+ "nlt",
+ "nle",
+ "ord"
+};
+
+static void
+OP_SIMD_Suffix (bytemode, sizeflag)
+ int bytemode ATTRIBUTE_UNUSED;
+ int sizeflag ATTRIBUTE_UNUSED;
+{
+ unsigned int cmp_type;
+
+ FETCH_DATA (the_info, codep + 1);
+ obufp = obuf + strlen(obuf);
+ cmp_type = *codep++ & 0xff;
+ if (cmp_type < 8)
+ {
+ sprintf (scratchbuf, "cmp%s%cs",
+ simd_cmp_op[cmp_type],
+ prefixes & PREFIX_REPZ ? 's' : 'p');
+ used_prefixes |= (prefixes & PREFIX_REPZ);
+ oappend (scratchbuf);
+ }
+ else
+ {
+ /* We have a bad extension byte. Clean up. */
+ op1out[0] = '\0';
+ op2out[0] = '\0';
+ BadOp();
+ }
+}
+
+static void
+SIMD_Fixup (extrachar, sizeflag)
+ int extrachar;
+ int sizeflag ATTRIBUTE_UNUSED;
+{
+ /* Change movlps/movhps to movhlps/movlhps for 2 register operand
+ forms of these instructions. */
+ if (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 BadOp (void)
+{
+ codep = insn_codep + 1; /* throw away prefixes and 1st. opcode byte */
+ oappend ("(bad)");
+}