summaryrefslogtreecommitdiffstats
path: root/contrib/binutils/opcodes/i386-dis.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/binutils/opcodes/i386-dis.c')
-rw-r--r--contrib/binutils/opcodes/i386-dis.c3749
1 files changed, 2604 insertions, 1145 deletions
diff --git a/contrib/binutils/opcodes/i386-dis.c b/contrib/binutils/opcodes/i386-dis.c
index 63b7d9c..a75d6e3 100644
--- a/contrib/binutils/opcodes/i386-dis.c
+++ b/contrib/binutils/opcodes/i386-dis.c
@@ -1,5 +1,5 @@
/* Print i386 instructions for GDB, the GNU debugger.
- Copyright (C) 1988, 89, 91, 93, 94, 95, 96, 97, 1998
+ Copyright (C) 1988, 89, 91, 93, 94, 95, 96, 97, 98, 1999
Free Software Foundation, Inc.
This file is part of GDB.
@@ -29,17 +29,24 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
* of the "Opcode Map" chapter (Appendix A) of the Intel 80386
* Programmers Manual. Usually, there is a capital letter, followed
* by a small letter. The capital letter tell the addressing mode,
- * and the small letter tells about the operand size. Refer to
+ * and the small letter tells about the operand size. Refer to
* the Intel manual for details.
*/
#include "dis-asm.h"
#include "sysdep.h"
+#include "opintl.h"
#define MAXLEN 20
#include <setjmp.h>
+#ifndef UNIXWARE_COMPAT
+/* Set non-zero for broken, compatible instructions. Set to zero for
+ non-broken opcodes. */
+#define UNIXWARE_COMPAT 1
+#endif
+
static int fetch_data PARAMS ((struct disassemble_info *, bfd_byte *));
struct dis_private
@@ -51,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. */
@@ -73,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
@@ -81,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
@@ -128,14 +164,14 @@ 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_DSSI, b_mode
-#define Xv OP_DSSI, v_mode
-#define Yb OP_ESDI, b_mode
-#define Yv OP_ESDI, v_mode
+#define Xb OP_DSreg, eSI_reg
+#define Xv OP_DSreg, eSI_reg
+#define Yb OP_ESreg, eDI_reg
+#define Yv OP_ESreg, eDI_reg
+#define DSBX OP_DSreg, eBX_reg
#define es OP_REG, es_reg
#define ss OP_REG, ss_reg
@@ -145,48 +181,66 @@ 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
-
-typedef int (*op_rtn) PARAMS ((int bytemode, int aflag, int dflag));
-
-static int OP_E PARAMS ((int, int, int));
-static int OP_G PARAMS ((int, int, int));
-static int OP_I PARAMS ((int, int, int));
-static int OP_indirE PARAMS ((int, int, int));
-static int OP_sI PARAMS ((int, int, int));
-static int OP_REG PARAMS ((int, int, int));
-static int OP_J PARAMS ((int, int, int));
-static int OP_DIR PARAMS ((int, int, int));
-static int OP_OFF PARAMS ((int, int, int));
-static int OP_ESDI PARAMS ((int, int, int));
-static int OP_DSSI PARAMS ((int, int, int));
-static int OP_SEG PARAMS ((int, int, int));
-static int OP_C PARAMS ((int, int, int));
-static int OP_D PARAMS ((int, int, int));
-static int OP_T PARAMS ((int, int, int));
-static int OP_rm PARAMS ((int, int, int));
-static int OP_ST PARAMS ((int, int, int));
-static int OP_STi PARAMS ((int, int, int));
-#if 0
-static int OP_ONE PARAMS ((int, int, int));
+#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 */
+#define SUFFIX_ALWAYS 4
#endif
-static int OP_MMX PARAMS ((int, int, int));
-static int OP_EM PARAMS ((int, int, int));
-static int OP_MS PARAMS ((int, int, int));
-
-static void append_prefix PARAMS ((void));
-static void set_op PARAMS ((int op));
-static void putop PARAMS ((char *template, int aflag, int dflag));
-static void dofloat PARAMS ((int aflag, int dflag));
+#define AFLAG 2
+#define DFLAG 1
+
+typedef void (*op_rtn) PARAMS ((int bytemode, int sizeflag));
+
+static void OP_E PARAMS ((int, int));
+static void OP_G PARAMS ((int, int));
+static void OP_I PARAMS ((int, int));
+static void OP_indirE PARAMS ((int, int));
+static void OP_sI PARAMS ((int, int));
+static void OP_REG PARAMS ((int, int));
+static void OP_J PARAMS ((int, int));
+static void OP_DIR PARAMS ((int, int));
+static void OP_OFF PARAMS ((int, int));
+static void OP_ESreg PARAMS ((int, int));
+static void OP_DSreg PARAMS ((int, int));
+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_Rd PARAMS ((int, int));
+static void OP_ST PARAMS ((int, int));
+static void OP_STi PARAMS ((int, int));
+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 ((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
#define w_mode 3
#define d_mode 4
+#define x_mode 5
#define es_reg 100
#define cs_reg 101
@@ -194,16 +248,15 @@ static void ckprefix PARAMS ((void));
#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
@@ -225,32 +278,54 @@ static void ckprefix PARAMS ((void));
#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 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;
@@ -259,250 +334,264 @@ struct dis386 {
int bytemode3;
};
-static struct dis386 dis386[] = {
+/* Upper case letters in the instruction names here are macros.
+ 'A' => print 'b' if no register operands or suffix_always is true
+ 'B' => print 'b' if suffix_always is true
+ 'E' => print 'e' if 32-bit form of jcxz
+ 'L' => print 'l' if suffix_always is true
+ 'N' => print 'n' if instruction has no wait "prefix"
+ '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' ("wd" or "dq" in intel mode)
+ 'S' => print 'w' or 'l' if suffix_always is true
+ 'W' => print 'b' or 'w' ("w" or "de" in intel mode)
+*/
+
+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 },
- { "pushS", es },
- { "popS", 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 },
- { "pushS", 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 },
- { "pushS", ss },
- { "popS", 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 },
- { "pushS", ds },
- { "popS", 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 */
- { "pusha" },
- { "popa" },
- { "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 */
- { "pushS", Iv }, /* 386 book wrong */
+ { "pushP", Iv, XX, XX }, /* 386 book wrong */
{ "imulS", Gv, Ev, Iv },
- { "pushS", sIb }, /* push of byte really pushes 2 or 4 bytes */
- { "imulS", Gv, Ev, Ib },
- { "insb", Yb, indirDX },
- { "insS", Yv, indirDX },
- { "outsb", indirDX, Xb },
- { "outsS", indirDX, Xv },
+ { "pushP", sIb, XX, XX }, /* push of byte really pushes 2 or 4 bytes */
+ { "imulS", Gv, Ev, sIb },
+ { "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 },
- { "jnl", 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 },
- { "movS", Ev, Sw },
- { "leaS", Gv, M },
- { "movS", Sw, Ev },
- { "popS", 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 */
- { "cWtS" },
- { "cStd" },
- { "lcall", Ap },
- { "(bad)" }, /* fwait */
- { "pushf" },
- { "popf" },
- { "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 },
- { "movsS", Yv, Xv },
- { "cmpsb", Yb, Xb },
- { "cmpsS", Yv, Xv },
+ { "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 },
- { "ret", Iw },
- { "ret" },
- { "lesS", Gv, Mp },
- { "ldsS", Gv, Mp },
- { "movb", Eb, Ib },
- { "movS", 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 */
- { "enter", Iw, Ib },
- { "leave" },
- { "lret", Iw },
- { "lret" },
- { "int3" },
- { "int", Ib },
- { "into" },
- { "iret" },
+ { "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", Ib },
- { "aad", Ib },
- { "(bad)" },
- { "xlat" },
+ { "aam", sIb, XX, XX },
+ { "aad", sIb, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "xlat", DSBX, XX, XX },
/* d8 */
{ FLOAT },
{ FLOAT },
@@ -513,576 +602,1357 @@ static struct dis386 dis386[] = {
{ FLOAT },
{ FLOAT },
/* e0 */
- { "loopne", Jb },
- { "loope", Jb },
- { "loop", Jb },
- { "jCcxz", 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 */
- { "call", Av },
- { "jmp", Jv },
- { "ljmp", 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_twobyte[] = {
+static const struct dis386 dis386_intel[] = {
+ /* 00 */
+ { "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 */
+ { "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 */
+ { "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 */
+ { "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 */
+ { "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 */
+ { "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 */
+ { "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 */
+ { "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 */
+ { "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 */
+ { "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 */
+ { "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 */
+ { "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 */
+ { "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 */
+ { "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, 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, 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)", XX, XX, XX },
+ { GRP1Ss },
+ { "test", Eb, Gb, XX },
+ { "test", Ev, Gv, XX },
+ { "xchg", Eb, Gb, XX },
+ { "xchg", Ev, Gv, XX },
+ /* 88 */
+ { "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", 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 */
+ { "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 */
+ { "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 */
+ { "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 */
+ { "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 */
+ { "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 },
+ { "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 */
+ { "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, XX, XX },
+ { "aad", sIb, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "xlat", DSBX, XX, XX },
+ /* d8 */
+ { FLOAT },
+ { FLOAT },
+ { FLOAT },
+ { FLOAT },
+ { FLOAT },
+ { FLOAT },
+ { FLOAT },
+ { FLOAT },
+ /* e0 */
+ { "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 */
+ { "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)", 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", 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 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)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
+ { "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" },
- { "(bad)" }, { "(bad)" }, { "(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 */
- { "pushS", fs },
- { "popS", 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 */
- { "pushS", gs },
- { "popS", 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 },
- { "(bad)" },
- { "imulS", Gv, Ev },
+ { GRP13 },
+ { "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 */
- { "movzbS", Gv, Eb },
- { "movzwS", Gv, Ew },
+ { "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 */
- { "ud2b" },
- { "(bad)" },
+ { "(bad)", XX, XX, XX },
+ { "ud2b", XX, XX, XX },
{ GRP8 },
- { "btcS", Ev, Gv },
- { "bsfS", Gv, Ev },
- { "bsrS", Gv, Ev },
- { "movsbS", Gv, Eb },
- { "movswS", Gv, Ew },
+ { "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)" },
- { GRP9 },
+ { "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", 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 struct dis386 dis386_twobyte_intel[] = {
+ /* 00 */
+ { GRP6 },
+ { GRP7 },
+ { "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", 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 */
+ { 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 */
+ { 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 */
+ { "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 */
+ { "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", 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)", 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, 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, 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 */
+ { "movmskps", Gv, EX, XX },
+ { PREGRP13 },
+ { PREGRP12 },
+ { PREGRP11 },
+ { "andps", XM, EX, XX },
+ { "andnps", XM, EX, XX },
+ { "orps", XM, EX, XX },
+ { "xorps", XM, EX, XX },
+ /* 58 */
+ { PREGRP0 },
+ { PREGRP10 },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { PREGRP14 },
+ { PREGRP7 },
+ { PREGRP5 },
+ { PREGRP6 },
+ /* 60 */
+ { "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, 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 */
+ { "pshufw", MX, EM, Ib },
+ { GRP10 },
+ { GRP11 },
+ { GRP12 },
+ { "pcmpeqb", MX, EM, XX },
+ { "pcmpeqw", MX, EM, XX },
+ { "pcmpeqd", MX, EM, XX },
+ { "emms", XX, XX, XX },
+ /* 78 */
+ { "(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, 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, 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, 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, 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 */
+ { "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 */
+ { "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 },
+ { "imul", Gv, Ev, XX },
+ /* b0 */
+ { "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)", XX, XX, XX },
+ { "ud2b", XX, XX, XX },
+ { GRP8 },
+ { "btc", Ev, Gv, XX },
+ { "bsf", Gv, Ev, XX },
+ { "bsr", Gv, Ev, XX },
+ { "movsx", Gv, Eb, XX },
+ { "movsx", Gv, Ew, XX },
+ /* c0 */
+ { "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, 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)", 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, 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 */
+ { "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, 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)", 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, 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] = {
- /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0, /* 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 */
+ /* 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 */ 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];
static char *obufp;
static char scratchbuf[100];
static unsigned char *start_codep;
+static unsigned char *insn_codep;
static unsigned char *codep;
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[] = {
- "bx+si","bx+di","bp+si","bp+di","si","di","bp","bx"
+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 */
{
- { "addb", Eb, Ib },
- { "orb", Eb, Ib },
- { "adcb", Eb, Ib },
- { "sbbb", Eb, Ib },
- { "andb", Eb, Ib },
- { "subb", Eb, Ib },
- { "xorb", Eb, Ib },
- { "cmpb", 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 */
{
- { "addS", Ev, Iv },
- { "orS", Ev, Iv },
- { "adcS", Ev, Iv },
- { "sbbS", Ev, Iv },
- { "andS", Ev, Iv },
- { "subS", Ev, Iv },
- { "xorS", Ev, Iv },
- { "cmpS", 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 */
{
- { "addS", Ev, sIb },
- { "orS", Ev, sIb },
- { "adcS", Ev, sIb },
- { "sbbS", Ev, sIb },
- { "andS", Ev, sIb },
- { "subS", Ev, sIb },
- { "xorS", Ev, sIb },
- { "cmpS", 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 */
{
- { "rolb", Eb, Ib },
- { "rorb", Eb, Ib },
- { "rclb", Eb, Ib },
- { "rcrb", Eb, Ib },
- { "shlb", Eb, Ib },
- { "shrb", Eb, Ib },
- { "(bad)" },
- { "sarb", 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 */
{
- { "rolS", Ev, Ib },
- { "rorS", Ev, Ib },
- { "rclS", Ev, Ib },
- { "rcrS", Ev, Ib },
- { "shlS", Ev, Ib },
- { "shrS", Ev, Ib },
- { "(bad)" },
- { "sarS", 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 */
{
- { "rolb", Eb },
- { "rorb", Eb },
- { "rclb", Eb },
- { "rcrb", Eb },
- { "shlb", Eb },
- { "shrb", Eb },
- { "(bad)" },
- { "sarb", 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 */
{
- { "rolS", Ev },
- { "rorS", Ev },
- { "rclS", Ev },
- { "rcrS", Ev },
- { "shlS", Ev },
- { "shrS", Ev },
- { "(bad)" },
- { "sarS", 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 */
{
- { "rolb", Eb, CL },
- { "rorb", Eb, CL },
- { "rclb", Eb, CL },
- { "rcrb", Eb, CL },
- { "shlb", Eb, CL },
- { "shrb", Eb, CL },
- { "(bad)" },
- { "sarb", 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 */
{
- { "rolS", Ev, CL },
- { "rorS", Ev, CL },
- { "rclS", Ev, CL },
- { "rcrS", Ev, CL },
- { "shlS", Ev, CL },
- { "shrS", Ev, CL },
- { "(bad)" },
- { "sarS", 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 */
{
- { "testb", Eb, Ib },
- { "(bad)", Eb },
- { "notb", Eb },
- { "negb", 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 */
{
- { "testS", Ev, Iv },
- { "(bad)" },
- { "notS", Ev },
- { "negS", 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 */
{
- { "incb", Eb },
- { "decb", 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 */
{
- { "incS", Ev },
- { "decS", Ev },
- { "call", indirEv },
- { "lcall", indirEv },
- { "jmp", indirEv },
- { "ljmp", indirEv },
- { "pushS", Ev },
- { "(bad)" },
+ { "incQ", Ev, XX, XX },
+ { "decQ", Ev, XX, XX },
+ { "callP", indirEv, XX, XX },
+ { "lcallP", 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)" },
- { "btS", Ev, Ib },
- { "btsS", Ev, Ib },
- { "btrS", Ev, Ib },
- { "btcS", 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, 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 */
+ {
+ { "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_ADR 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);
@@ -1119,10 +1989,19 @@ ckprefix ()
prefixes |= PREFIX_DATA;
break;
case 0x67:
- prefixes |= PREFIX_ADR;
+ prefixes |= PREFIX_ADDR;
break;
- case 0x9b:
- prefixes |= PREFIX_FWAIT;
+ 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. */
+ if (prefixes)
+ {
+ prefixes |= PREFIX_FWAIT;
+ codep++;
+ return;
+ }
+ prefixes = PREFIX_FWAIT;
break;
default:
return;
@@ -1131,9 +2010,49 @@ 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_address[3], op_ad, op_index[3];
-static int start_pc;
+static int op_ad, op_index[3];
+static unsigned int op_address[3];
+static unsigned int start_pc;
/*
@@ -1145,48 +2064,77 @@ static int start_pc;
* The function returns the length of this instruction in bytes.
*/
-int print_insn_x86 PARAMS ((bfd_vma pc, disassemble_info *info, int aflag,
- int dflag));
+static int print_insn_i386
+ PARAMS ((bfd_vma pc, disassemble_info *info));
+
+static char intel_syntax;
+static char open_char;
+static char close_char;
+static char separator_char;
+static char scale_char;
+
int
-print_insn_i386 (pc, info)
+print_insn_i386_att (pc, info)
bfd_vma pc;
disassemble_info *info;
{
- if (info->mach == bfd_mach_i386_i386)
- return print_insn_x86 (pc, info, 1, 1);
- else if (info->mach == bfd_mach_i386_i8086)
- return print_insn_x86 (pc, info, 0, 0);
- else
- abort ();
+ intel_syntax = 0;
+ open_char = '(';
+ close_char = ')';
+ separator_char = ',';
+ scale_char = ',';
+
+ return print_insn_i386 (pc, info);
}
int
-print_insn_x86 (pc, info, aflag, dflag)
+print_insn_i386_intel (pc, info)
bfd_vma pc;
disassemble_info *info;
- int aflag;
- int dflag;
{
- struct dis386 *dp;
+ intel_syntax = 1;
+ open_char = '[';
+ close_char = ']';
+ separator_char = '+';
+ scale_char = '*';
+
+ return print_insn_i386 (pc, info);
+}
+
+static int
+print_insn_i386 (pc, info)
+ bfd_vma pc;
+ disassemble_info *info;
+{
+ const struct dis386 *dp;
int i;
- int enter_instruction;
+ 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 7 bytes on a line, since that
+ puts most long word instructions on a single line. */
+ info->bytes_per_line = 7;
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;
@@ -1199,57 +2147,105 @@ print_insn_x86 (pc, info, aflag, dflag)
start_pc = pc;
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;
+
FETCH_DATA (info, codep + 1);
- if (*codep == 0xc8)
- enter_instruction = 1;
- else
- enter_instruction = 0;
-
+ two_source_ops = (*codep == 0x62) || (*codep == 0xc8);
+
obufp = obuf;
-
- if (prefixes & PREFIX_REPZ)
- oappend ("repz ");
- if (prefixes & PREFIX_REPNZ)
- oappend ("repnz ");
- if (prefixes & PREFIX_LOCK)
- oappend ("lock ");
-
+
if ((prefixes & PREFIX_FWAIT)
&& ((*codep < 0xd8) || (*codep > 0xdf)))
{
- /* fwait not followed by floating point instruction */
- (*info->fprintf_func) (info->stream, "fwait");
- return (1);
+ 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 (prefixes & PREFIX_DATA)
- dflag ^= 1;
-
- if (prefixes & PREFIX_ADR)
- {
- aflag ^= 1;
- if (aflag)
- oappend ("addr32 ");
- else
- oappend ("addr16 ");
- }
-
+
if (*codep == 0x0f)
{
FETCH_DATA (info, codep + 2);
- dp = &dis386_twobyte[*++codep];
+ if (intel_syntax)
+ dp = &dis386_twobyte_intel[*++codep];
+ else
+ dp = &dis386_twobyte_att[*++codep];
need_modrm = twobyte_has_modrm[*codep];
+ uses_f3_prefix = twobyte_uses_f3_prefix[*codep];
}
else
{
- dp = &dis386[*codep];
+ if (intel_syntax)
+ dp = &dis386_intel[*codep];
+ 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);
@@ -1260,42 +2256,69 @@ print_insn_x86 (pc, info, aflag, dflag)
if (dp->name == NULL && dp->bytemode1 == FLOATCODE)
{
- dofloat (aflag, dflag);
+ dofloat (sizeflag);
}
else
{
if (dp->name == NULL)
- dp = &grps[dp->bytemode1][reg];
-
- putop (dp->name, aflag, dflag);
-
+ {
+ 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);
+
obufp = op1out;
op_ad = 2;
if (dp->op1)
- (*dp->op1)(dp->bytemode1, aflag, dflag);
-
+ (*dp->op1)(dp->bytemode1, sizeflag);
+
obufp = op2out;
op_ad = 1;
if (dp->op2)
- (*dp->op2)(dp->bytemode2, aflag, dflag);
-
+ (*dp->op2)(dp->bytemode2, sizeflag);
+
obufp = op3out;
op_ad = 0;
if (dp->op3)
- (*dp->op3)(dp->bytemode3, aflag, dflag);
+ (*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 (" ");
oappend (" ");
(*info->fprintf_func) (info->stream, "%s", obuf);
-
- /* enter instruction is printed with operands in the
- * same order as the intel book; everything else
- * is printed in reverse order
- */
- if (enter_instruction)
+
+ /* 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)
{
first = op1out;
second = op2out;
@@ -1314,7 +2337,7 @@ print_insn_x86 (pc, info, aflag, dflag)
if (*first)
{
if (op_index[0] != -1)
- (*info->print_address_func) (op_address[op_index[0]], info);
+ (*info->print_address_func) ((bfd_vma) op_address[op_index[0]], info);
else
(*info->fprintf_func) (info->stream, "%s", first);
needcomma = 1;
@@ -1324,7 +2347,7 @@ print_insn_x86 (pc, info, aflag, dflag)
if (needcomma)
(*info->fprintf_func) (info->stream, ",");
if (op_index[1] != -1)
- (*info->print_address_func) (op_address[op_index[1]], info);
+ (*info->print_address_func) ((bfd_vma) op_address[op_index[1]], info);
else
(*info->fprintf_func) (info->stream, "%s", second);
needcomma = 1;
@@ -1334,14 +2357,14 @@ print_insn_x86 (pc, info, aflag, dflag)
if (needcomma)
(*info->fprintf_func) (info->stream, ",");
if (op_index[2] != -1)
- (*info->print_address_func) (op_address[op_index[2]], info);
+ (*info->print_address_func) ((bfd_vma) op_address[op_index[2]], info);
else
(*info->fprintf_func) (info->stream, "%s", third);
}
- return (codep - inbuf);
+ return codep - inbuf;
}
-static char *float_mem[] = {
+static const char *float_mem_att[] = {
/* d8 */
"fadds",
"fmuls",
@@ -1416,37 +2439,112 @@ static char *float_mem[] = {
"fistpll",
};
+static const char *float_mem_intel[] = {
+ /* d8 */
+ "fadd",
+ "fmul",
+ "fcom",
+ "fcomp",
+ "fsub",
+ "fsubr",
+ "fdiv",
+ "fdivr",
+ /* d9 */
+ "fld",
+ "(bad)",
+ "fst",
+ "fstp",
+ "fldenv",
+ "fldcw",
+ "fNstenv",
+ "fNstcw",
+ /* da */
+ "fiadd",
+ "fimul",
+ "ficom",
+ "ficomp",
+ "fisub",
+ "fisubr",
+ "fidiv",
+ "fidivr",
+ /* db */
+ "fild",
+ "(bad)",
+ "fist",
+ "fistp",
+ "(bad)",
+ "fld",
+ "(bad)",
+ "fstp",
+ /* dc */
+ "fadd",
+ "fmul",
+ "fcom",
+ "fcomp",
+ "fsub",
+ "fsubr",
+ "fdiv",
+ "fdivr",
+ /* dd */
+ "fld",
+ "(bad)",
+ "fst",
+ "fstp",
+ "frstor",
+ "(bad)",
+ "fNsave",
+ "fNstsw",
+ /* de */
+ "fiadd",
+ "fimul",
+ "ficom",
+ "ficomp",
+ "fisub",
+ "fisubr",
+ "fidiv",
+ "fidivr",
+ /* df */
+ "fild",
+ "(bad)",
+ "fist",
+ "fistp",
+ "fbld",
+ "fild",
+ "fbstp",
+ "fistpll",
+};
+
#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 },
@@ -1454,69 +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)" },
- { "fsub", STi, ST },
- { "fsubr", STi, ST },
- { "fdiv", STi, ST },
- { "fdivr", STi, ST },
+ { "fadd", STi, ST, XX },
+ { "fmul", STi, ST, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+#if UNIXWARE_COMPAT
+ { "fsub", STi, ST, XX },
+ { "fsubr", STi, ST, XX },
+ { "fdiv", STi, ST, XX },
+ { "fdivr", STi, ST, XX },
+#else
+ { "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 },
- { "fsubp", STi, ST },
- { "fsubrp", STi, ST },
- { "fdivp", STi, ST },
- { "fdivrp", STi, ST },
+#if UNIXWARE_COMPAT
+ { "fsubp", STi, ST, XX },
+ { "fsubrp", STi, ST, XX },
+ { "fdivp", STi, ST, XX },
+ { "fdivrp", STi, ST, XX },
+#else
+ { "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 },
},
};
@@ -1570,79 +2682,81 @@ static char *fgrps[][8] = {
};
static void
-dofloat (aflag, dflag)
- int aflag;
- int dflag;
+dofloat (sizeflag)
+ int sizeflag;
{
- struct dis386 *dp;
+ const struct dis386 *dp;
unsigned char floatop;
-
+
floatop = codep[-1];
-
+
if (mod != 3)
{
- putop (float_mem[(floatop - 0xd8) * 8 + reg], aflag, dflag);
+ if (intel_syntax)
+ putop (float_mem_intel[(floatop - 0xd8 ) * 8 + reg], sizeflag);
+ else
+ putop (float_mem_att[(floatop - 0xd8 ) * 8 + reg], sizeflag);
obufp = op1out;
- OP_E (v_mode, aflag, dflag);
+ if (floatop == 0xdb)
+ OP_E (x_mode, sizeflag);
+ else if (floatop == 0xdd)
+ OP_E (d_mode, sizeflag);
+ else
+ OP_E (v_mode, sizeflag);
return;
}
codep++;
-
+
dp = &float_reg[floatop - 0xd8][reg];
if (dp->name == NULL)
{
- putop (fgrps[dp->bytemode1][rm], aflag, dflag);
+ putop (fgrps[dp->bytemode1][rm], sizeflag);
+
/* instruction fnstsw is only one with strange arg */
- if (floatop == 0xdf
- && FETCH_DATA (the_info, codep + 1)
- && *codep == 0xe0)
- strcpy (op1out, "%eax");
+ if (floatop == 0xdf && codep[-1] == 0xe0)
+ strcpy (op1out, names16[0]);
}
else
{
- putop (dp->name, aflag, dflag);
+ putop (dp->name, sizeflag);
+
obufp = op1out;
if (dp->op1)
- (*dp->op1)(dp->bytemode1, aflag, dflag);
+ (*dp->op1)(dp->bytemode1, sizeflag);
obufp = op2out;
if (dp->op2)
- (*dp->op2)(dp->bytemode2, aflag, dflag);
+ (*dp->op2)(dp->bytemode2, sizeflag);
}
}
/* ARGSUSED */
-static int
-OP_ST (ignore, aflag, dflag)
- int ignore;
- int aflag;
- int dflag;
+static void
+OP_ST (ignore, sizeflag)
+ int ignore ATTRIBUTE_UNUSED;
+ int sizeflag ATTRIBUTE_UNUSED;
{
oappend ("%st");
- return (0);
}
/* ARGSUSED */
-static int
-OP_STi (ignore, aflag, dflag)
- int ignore;
- int aflag;
- int dflag;
+static void
+OP_STi (ignore, sizeflag)
+ int ignore ATTRIBUTE_UNUSED;
+ int sizeflag ATTRIBUTE_UNUSED;
{
sprintf (scratchbuf, "%%st(%d)", rm);
oappend (scratchbuf);
- return (0);
}
/* capital letters in template are macros */
static void
-putop (template, aflag, dflag)
- char *template;
- int aflag;
- int dflag;
+putop (template, sizeflag)
+ const char *template;
+ int sizeflag;
{
- char *p;
-
+ const char *p;
+
for (p = template; *p; p++)
{
switch (*p)
@@ -1650,27 +2764,130 @@ putop (template, aflag, dflag)
default:
*obufp++ = *p;
break;
- case 'C': /* For jcxz/jecxz */
- if (aflag)
+ case 'A':
+ if (intel_syntax)
+ break;
+ if (mod != 3
+#ifdef SUFFIX_ALWAYS
+ || (sizeflag & SUFFIX_ALWAYS)
+#endif
+ )
+ *obufp++ = 'b';
+ break;
+ case 'B':
+ if (intel_syntax)
+ break;
+#ifdef SUFFIX_ALWAYS
+ if (sizeflag & SUFFIX_ALWAYS)
+ *obufp++ = 'b';
+#endif
+ break;
+ case 'E': /* For jcxz/jecxz */
+ if (sizeflag & AFLAG)
*obufp++ = 'e';
break;
+ case 'L':
+ if (intel_syntax)
+ break;
+#ifdef SUFFIX_ALWAYS
+ if (sizeflag & SUFFIX_ALWAYS)
+ *obufp++ = 'l';
+#endif
+ break;
case 'N':
if ((prefixes & PREFIX_FWAIT) == 0)
*obufp++ = 'n';
+ else
+ used_prefixes |= PREFIX_FWAIT;
break;
- case 'S':
- /* operand size flag */
- if (dflag)
- *obufp++ = 'l';
+ case 'P':
+ if (intel_syntax)
+ break;
+ if ((prefixes & PREFIX_DATA)
+#ifdef SUFFIX_ALWAYS
+ || (sizeflag & SUFFIX_ALWAYS)
+#endif
+ )
+ {
+ if (sizeflag & DFLAG)
+ *obufp++ = 'l';
+ else
+ *obufp++ = 'w';
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ }
+ break;
+ case 'Q':
+ if (intel_syntax)
+ break;
+ if (mod != 3
+#ifdef SUFFIX_ALWAYS
+ || (sizeflag & SUFFIX_ALWAYS)
+#endif
+ )
+ {
+ if (sizeflag & DFLAG)
+ *obufp++ = 'l';
+ else
+ *obufp++ = 'w';
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ }
+ break;
+ case 'R':
+ if (intel_syntax)
+ {
+ 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)
+ break;
+#ifdef SUFFIX_ALWAYS
+ if (sizeflag & SUFFIX_ALWAYS)
+ {
+ if (sizeflag & DFLAG)
+ *obufp++ = 'l';
+ else
+ *obufp++ = 'w';
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ }
+#endif
break;
case 'W':
/* operand size flag for cwtl, cbtw */
- if (dflag)
+ 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;
}
}
@@ -1679,45 +2896,61 @@ putop (template, aflag, dflag)
static void
oappend (s)
- char *s;
+ const char *s;
{
strcpy (obufp, s);
obufp += strlen (s);
- *obufp = 0;
}
static void
-append_prefix ()
+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 int
-OP_indirE (bytemode, aflag, dflag)
+static void
+OP_indirE (bytemode, sizeflag)
int bytemode;
- int aflag;
- int dflag;
+ int sizeflag;
{
- oappend ("*");
- return OP_E (bytemode, aflag, dflag);
+ if (!intel_syntax)
+ oappend ("*");
+ OP_E (bytemode, sizeflag);
}
-static int
-OP_E (bytemode, aflag, dflag)
+static void
+OP_E (bytemode, sizeflag)
int bytemode;
- int aflag;
- int dflag;
+ int sizeflag;
{
int disp;
@@ -1734,23 +2967,31 @@ OP_E (bytemode, aflag, dflag)
case w_mode:
oappend (names16[rm]);
break;
+ case d_mode:
+ oappend (names32[rm]);
+ break;
case v_mode:
- if (dflag)
+ 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 0;
+ return;
}
disp = 0;
- append_prefix ();
+ append_seg ();
- if (aflag) /* 32 bit address mode */
+ if (sizeflag & AFLAG) /* 32 bit address mode */
{
int havesib;
int havebase;
@@ -1792,29 +3033,106 @@ OP_E (bytemode, aflag, dflag)
break;
}
- if (mod != 0 || base == 5)
- {
- sprintf (scratchbuf, "0x%x", disp);
- oappend (scratchbuf);
- }
+ if (!intel_syntax)
+ if (mod != 0 || base == 5)
+ {
+ sprintf (scratchbuf, "0x%x", disp);
+ oappend (scratchbuf);
+ }
if (havebase || (havesib && (index != 4 || scale != 0)))
{
- oappend ("(");
+ if (intel_syntax)
+ {
+ switch (bytemode)
+ {
+ case b_mode:
+ oappend("BYTE PTR ");
+ break;
+ case w_mode:
+ oappend("WORD PTR ");
+ break;
+ case v_mode:
+ oappend("DWORD PTR ");
+ break;
+ case d_mode:
+ oappend("QWORD PTR ");
+ break;
+ case x_mode:
+ oappend("XWORD PTR ");
+ break;
+ default:
+ break;
+ }
+ }
+ *obufp++ = open_char;
+ *obufp = '\0';
if (havebase)
oappend (names32[base]);
if (havesib)
{
if (index != 4)
{
- sprintf (scratchbuf, ",%s", names32[index]);
+ if (intel_syntax)
+ {
+ if (havebase)
+ {
+ *obufp++ = separator_char;
+ *obufp = '\0';
+ }
+ sprintf (scratchbuf, "%s", names32[index]);
+ }
+ else
+ sprintf (scratchbuf, ",%s", names32[index]);
oappend (scratchbuf);
}
- sprintf (scratchbuf, ",%d", 1 << scale);
- oappend (scratchbuf);
+ if (!intel_syntax
+ || (intel_syntax
+ && bytemode != b_mode
+ && bytemode != w_mode
+ && bytemode != v_mode))
+ {
+ *obufp++ = scale_char;
+ *obufp = '\0';
+ sprintf (scratchbuf, "%d", 1 << scale);
+ oappend (scratchbuf);
+ }
}
- oappend (")");
+ if (intel_syntax)
+ if (mod != 0 || base == 5)
+ {
+ /* Don't print zero displacements */
+ if (disp > 0)
+ {
+ sprintf (scratchbuf, "+%d", disp);
+ oappend (scratchbuf);
+ }
+ else if (disp < 0)
+ {
+ sprintf (scratchbuf, "%d", disp);
+ oappend (scratchbuf);
+ }
+ }
+
+ *obufp++ = close_char;
+ *obufp = '\0';
}
+ else if (intel_syntax)
+ {
+ if (mod != 0 || base == 5)
+ {
+ if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
+ | PREFIX_ES | PREFIX_FS | PREFIX_GS))
+ ;
+ else
+ {
+ oappend (names_seg[3]);
+ oappend (":");
+ }
+ sprintf (scratchbuf, "0x%x", disp);
+ oappend (scratchbuf);
+ }
+ }
}
else
{ /* 16 bit address mode */
@@ -1841,29 +3159,30 @@ OP_E (bytemode, aflag, dflag)
break;
}
- if (mod != 0 || rm == 6)
- {
- sprintf (scratchbuf, "0x%x", disp);
- oappend (scratchbuf);
- }
+ if (!intel_syntax)
+ if (mod != 0 || rm == 6)
+ {
+ sprintf (scratchbuf, "%d", disp);
+ oappend (scratchbuf);
+ }
if (mod != 0 || rm != 6)
{
- oappend ("(");
+ *obufp++ = open_char;
+ *obufp = '\0';
oappend (index16[rm]);
- oappend (")");
+ *obufp++ = close_char;
+ *obufp = '\0';
}
}
- return 0;
}
-static int
-OP_G (bytemode, aflag, dflag)
+static void
+OP_G (bytemode, sizeflag)
int bytemode;
- int aflag;
- int dflag;
+ int sizeflag;
{
- switch (bytemode)
+ switch (bytemode)
{
case b_mode:
oappend (names8[reg]);
@@ -1875,16 +3194,16 @@ OP_G (bytemode, aflag, dflag)
oappend (names32[reg]);
break;
case v_mode:
- if (dflag)
+ if (sizeflag & DFLAG)
oappend (names32[reg]);
else
oappend (names16[reg]);
+ used_prefixes |= (prefixes & PREFIX_DATA);
break;
default:
- oappend ("<internal disassembler error>");
+ oappend (INTERNAL_DISASSEMBLER_ERROR);
break;
}
- return (0);
}
static int
@@ -1897,7 +3216,7 @@ get32 ()
x |= (*codep++ & 0xff) << 8;
x |= (*codep++ & 0xff) << 16;
x |= (*codep++ & 0xff) << 24;
- return (x);
+ return x;
}
static int
@@ -1908,96 +3227,100 @@ get16 ()
FETCH_DATA (the_info, codep + 2);
x = *codep++ & 0xff;
x |= (*codep++ & 0xff) << 8;
- return (x);
+ return x;
}
static void
set_op (op)
- int op;
+ unsigned int op;
{
op_index[op_ad] = op_ad;
op_address[op_ad] = op;
}
-static int
-OP_REG (code, aflag, dflag)
+static void
+OP_REG (code, sizeflag)
int code;
- int aflag;
- int dflag;
+ int sizeflag;
{
- char *s;
-
- switch (code)
+ const char *s;
+
+ switch (code)
{
- case indir_dx_reg: s = "(%dx)"; break;
- case ax_reg: case cx_reg: case dx_reg: case bx_reg:
- case sp_reg: case bp_reg: case si_reg: case di_reg:
- s = names16[code - ax_reg];
- break;
- case es_reg: case ss_reg: case cs_reg:
- case ds_reg: case fs_reg: case gs_reg:
- s = names_seg[code - es_reg];
- break;
- case al_reg: case ah_reg: case cl_reg: case ch_reg:
- case dl_reg: case dh_reg: case bl_reg: case bh_reg:
- s = names8[code - al_reg];
- break;
- case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
- case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
- if (dflag)
+ case indir_dx_reg:
+ s = "(%dx)";
+ break;
+ case ax_reg: case cx_reg: case dx_reg: case bx_reg:
+ case sp_reg: case bp_reg: case si_reg: case di_reg:
+ s = names16[code - ax_reg];
+ break;
+ case es_reg: case ss_reg: case cs_reg:
+ case ds_reg: case fs_reg: case gs_reg:
+ s = names_seg[code - es_reg];
+ break;
+ case al_reg: case ah_reg: case cl_reg: case ch_reg:
+ case dl_reg: case dh_reg: case bl_reg: case bh_reg:
+ s = names8[code - al_reg];
+ break;
+ case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
+ case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
+ if (sizeflag & DFLAG)
s = names32[code - eAX_reg];
else
s = names16[code - eAX_reg];
+ used_prefixes |= (prefixes & PREFIX_DATA);
break;
default:
- s = "<internal disassembler error>";
+ s = INTERNAL_DISASSEMBLER_ERROR;
break;
}
oappend (s);
- return (0);
}
-static int
-OP_I (bytemode, aflag, dflag)
+static void
+OP_I (bytemode, sizeflag)
int bytemode;
- int aflag;
- int dflag;
+ int sizeflag;
{
int op;
-
- switch (bytemode)
+
+ switch (bytemode)
{
case b_mode:
FETCH_DATA (the_info, codep + 1);
op = *codep++ & 0xff;
break;
case v_mode:
- if (dflag)
+ if (sizeflag & DFLAG)
op = get32 ();
else
op = get16 ();
+ used_prefixes |= (prefixes & PREFIX_DATA);
break;
case w_mode:
op = get16 ();
break;
default:
- oappend ("<internal disassembler error>");
- return (0);
+ oappend (INTERNAL_DISASSEMBLER_ERROR);
+ return;
}
- sprintf (scratchbuf, "$0x%x", op);
+
+ if (intel_syntax)
+ sprintf (scratchbuf, "0x%x", op);
+ else
+ sprintf (scratchbuf, "$0x%x", op);
oappend (scratchbuf);
- return (0);
+ scratchbuf[0] = '\0';
}
-static int
-OP_sI (bytemode, aflag, dflag)
+static void
+OP_sI (bytemode, sizeflag)
int bytemode;
- int aflag;
- int dflag;
+ int sizeflag;
{
int op;
-
- switch (bytemode)
+
+ switch (bytemode)
{
case b_mode:
FETCH_DATA (the_info, codep + 1);
@@ -2006,7 +3329,7 @@ OP_sI (bytemode, aflag, dflag)
op -= 0x100;
break;
case v_mode:
- if (dflag)
+ if (sizeflag & DFLAG)
op = get32 ();
else
{
@@ -2014,6 +3337,7 @@ OP_sI (bytemode, aflag, dflag)
if ((op & 0x8000) != 0)
op -= 0x10000;
}
+ used_prefixes |= (prefixes & PREFIX_DATA);
break;
case w_mode:
op = get16 ();
@@ -2021,24 +3345,25 @@ OP_sI (bytemode, aflag, dflag)
op -= 0x10000;
break;
default:
- oappend ("<internal disassembler error>");
- return (0);
+ oappend (INTERNAL_DISASSEMBLER_ERROR);
+ return;
}
- sprintf (scratchbuf, "$0x%x", op);
+ if (intel_syntax)
+ sprintf (scratchbuf, "%d", op);
+ else
+ sprintf (scratchbuf, "$0x%x", op);
oappend (scratchbuf);
- return (0);
}
-static int
-OP_J (bytemode, aflag, dflag)
+static void
+OP_J (bytemode, sizeflag)
int bytemode;
- int aflag;
- int dflag;
+ int sizeflag;
{
int disp;
int mask = -1;
-
- switch (bytemode)
+
+ switch (bytemode)
{
case b_mode:
FETCH_DATA (the_info, codep + 1);
@@ -2047,131 +3372,120 @@ OP_J (bytemode, aflag, dflag)
disp -= 0x100;
break;
case v_mode:
- if (dflag)
+ if (sizeflag & DFLAG)
disp = get32 ();
else
{
disp = get16 ();
- if ((disp & 0x8000) != 0)
- disp -= 0x10000;
/* for some reason, a data16 prefix on a jump instruction
means that the pc is masked to 16 bits after the
displacement is added! */
mask = 0xffff;
}
+ used_prefixes |= (prefixes & PREFIX_DATA);
break;
default:
- oappend ("<internal disassembler error>");
- return (0);
+ oappend (INTERNAL_DISASSEMBLER_ERROR);
+ return;
}
disp = (start_pc + codep - start_codep + disp) & mask;
set_op (disp);
sprintf (scratchbuf, "0x%x", disp);
oappend (scratchbuf);
- return (0);
}
/* ARGSUSED */
-static int
-OP_SEG (dummy, aflag, dflag)
- int dummy;
- int aflag;
- int dflag;
+static void
+OP_SEG (dummy, sizeflag)
+ int dummy ATTRIBUTE_UNUSED;
+ int sizeflag ATTRIBUTE_UNUSED;
{
static char *sreg[] = {
"%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
};
oappend (sreg[reg]);
- return (0);
}
-static int
-OP_DIR (size, aflag, dflag)
- int size;
- int aflag;
- int dflag;
+/* ARGSUSED */
+static void
+OP_DIR (dummy, sizeflag)
+ int dummy ATTRIBUTE_UNUSED;
+ int sizeflag;
{
int seg, offset;
-
- switch (size)
+
+ if (sizeflag & DFLAG)
{
- case lptr:
- if (aflag)
- {
- offset = get32 ();
- seg = get16 ();
- }
- else
- {
- offset = get16 ();
- seg = get16 ();
- }
- sprintf (scratchbuf, "0x%x,0x%x", seg, offset);
- oappend (scratchbuf);
- break;
- case v_mode:
- if (aflag)
- 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 ();
}
- return (0);
+ else
+ {
+ offset = get16 ();
+ seg = get16 ();
+ }
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset);
+ oappend (scratchbuf);
}
/* ARGSUSED */
-static int
-OP_OFF (bytemode, aflag, dflag)
- int bytemode;
- int aflag;
- int dflag;
+static void
+OP_OFF (ignore, sizeflag)
+ int ignore ATTRIBUTE_UNUSED;
+ int sizeflag;
{
int off;
- append_prefix ();
+ append_seg ();
- if (aflag)
+ if (sizeflag & AFLAG)
off = get32 ();
else
off = get16 ();
-
+
+ if (intel_syntax)
+ {
+ if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
+ | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
+ {
+ oappend (names_seg[3]);
+ oappend (":");
+ }
+ }
sprintf (scratchbuf, "0x%x", off);
oappend (scratchbuf);
- return (0);
}
-/* ARGSUSED */
-static int
-OP_ESDI (dummy, aflag, dflag)
- int dummy;
- int aflag;
- int dflag;
+static void
+ptr_reg (code, sizeflag)
+ int code;
+ int sizeflag;
{
- oappend ("%es:(");
- oappend (aflag ? "%edi" : "%di");
+ const char *s;
+ oappend ("(");
+ if (sizeflag & AFLAG)
+ s = names32[code - eAX_reg];
+ else
+ s = names16[code - eAX_reg];
+ oappend (s);
oappend (")");
- return (0);
}
-/* ARGSUSED */
-static int
-OP_DSSI (dummy, aflag, dflag)
- int dummy;
- int aflag;
- int dflag;
+static void
+OP_ESreg (code, sizeflag)
+ int code;
+ int sizeflag;
+{
+ oappend ("%es:");
+ ptr_reg (code, sizeflag);
+}
+
+static void
+OP_DSreg (code, sizeflag)
+ int code;
+ int sizeflag;
{
if ((prefixes
& (PREFIX_CS
@@ -2181,120 +3495,265 @@ OP_DSSI (dummy, aflag, dflag)
| PREFIX_FS
| PREFIX_GS)) == 0)
prefixes |= PREFIX_DS;
- append_prefix ();
- oappend ("(");
- oappend (aflag ? "%esi" : "%si");
- oappend (")");
- return (0);
+ append_seg();
+ ptr_reg (code, sizeflag);
}
-#if 0
-/* Not used. */
-
/* ARGSUSED */
-static int
-OP_ONE (dummy, aflag, dflag)
- int dummy;
- int aflag;
- int dflag;
-{
- oappend ("1");
- return (0);
-}
-
-#endif
-
-/* ARGSUSED */
-static int
-OP_C (dummy, aflag, dflag)
- int dummy;
- int aflag;
- int dflag;
+static void
+OP_C (dummy, sizeflag)
+ int dummy ATTRIBUTE_UNUSED;
+ int sizeflag ATTRIBUTE_UNUSED;
{
- codep++; /* skip mod/rm */
sprintf (scratchbuf, "%%cr%d", reg);
oappend (scratchbuf);
- return (0);
}
/* ARGSUSED */
-static int
-OP_D (dummy, aflag, dflag)
- int dummy;
- int aflag;
- int dflag;
+static void
+OP_D (dummy, sizeflag)
+ int dummy ATTRIBUTE_UNUSED;
+ int sizeflag ATTRIBUTE_UNUSED;
{
- codep++; /* skip mod/rm */
sprintf (scratchbuf, "%%db%d", reg);
oappend (scratchbuf);
- return (0);
}
/* ARGSUSED */
-static int
-OP_T (dummy, aflag, dflag)
- int dummy;
- int aflag;
- int dflag;
+static void
+OP_T (dummy, sizeflag)
+ int dummy ATTRIBUTE_UNUSED;
+ int sizeflag ATTRIBUTE_UNUSED;
{
- codep++; /* skip mod/rm */
sprintf (scratchbuf, "%%tr%d", reg);
oappend (scratchbuf);
- return (0);
}
-static int
-OP_rm (bytemode, aflag, dflag)
+static void
+OP_Rd (bytemode, sizeflag)
int bytemode;
- int aflag;
- int dflag;
+ int sizeflag;
{
- switch (bytemode)
- {
- case d_mode:
- oappend (names32[rm]);
- break;
- case w_mode:
- oappend (names16[rm]);
- break;
- }
- return (0);
+ if (mod == 3)
+ OP_E (bytemode, sizeflag);
+ else
+ BadOp();
}
-static int
-OP_MMX (bytemode, aflag, dflag)
- int bytemode;
- int aflag;
- int dflag;
+static void
+OP_MMX (ignore, sizeflag)
+ int ignore ATTRIBUTE_UNUSED;
+ int sizeflag ATTRIBUTE_UNUSED;
{
sprintf (scratchbuf, "%%mm%d", reg);
oappend (scratchbuf);
- return 0;
}
-static int
-OP_EM (bytemode, aflag, dflag)
+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 aflag;
- int dflag;
+ int sizeflag;
{
if (mod != 3)
- return OP_E (bytemode, aflag, dflag);
+ {
+ OP_E (bytemode, sizeflag);
+ return;
+ }
codep++;
sprintf (scratchbuf, "%%mm%d", rm);
oappend (scratchbuf);
- return 0;
}
-static int
-OP_MS (bytemode, aflag, dflag)
+static void
+OP_EX (bytemode, sizeflag)
int bytemode;
- int aflag;
- int dflag;
+ int sizeflag;
{
- ++codep;
- sprintf (scratchbuf, "%%mm%d", rm);
+ if (mod != 3)
+ {
+ OP_E (bytemode, sizeflag);
+ return;
+ }
+
+ codep++;
+ sprintf (scratchbuf, "%%xmm%d", rm);
oappend (scratchbuf);
- return 0;
+}
+
+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,
+/* 08 */ NULL, NULL, NULL, NULL,
+/* 0C */ "pi2fw", "pi2fd", NULL, NULL,
+/* 10 */ NULL, NULL, NULL, NULL,
+/* 14 */ NULL, NULL, NULL, NULL,
+/* 18 */ NULL, NULL, NULL, NULL,
+/* 1C */ "pf2iw", "pf2id", NULL, NULL,
+/* 20 */ NULL, NULL, NULL, NULL,
+/* 24 */ NULL, NULL, NULL, NULL,
+/* 28 */ NULL, NULL, NULL, NULL,
+/* 2C */ NULL, NULL, NULL, NULL,
+/* 30 */ NULL, NULL, NULL, NULL,
+/* 34 */ NULL, NULL, NULL, NULL,
+/* 38 */ NULL, NULL, NULL, NULL,
+/* 3C */ NULL, NULL, NULL, NULL,
+/* 40 */ NULL, NULL, NULL, NULL,
+/* 44 */ NULL, NULL, NULL, NULL,
+/* 48 */ NULL, NULL, NULL, NULL,
+/* 4C */ NULL, NULL, NULL, NULL,
+/* 50 */ NULL, NULL, NULL, NULL,
+/* 54 */ NULL, NULL, NULL, NULL,
+/* 58 */ NULL, NULL, NULL, NULL,
+/* 5C */ NULL, NULL, NULL, NULL,
+/* 60 */ NULL, NULL, NULL, NULL,
+/* 64 */ NULL, NULL, NULL, NULL,
+/* 68 */ NULL, NULL, NULL, NULL,
+/* 6C */ NULL, NULL, NULL, NULL,
+/* 70 */ NULL, NULL, NULL, NULL,
+/* 74 */ NULL, NULL, NULL, NULL,
+/* 78 */ NULL, NULL, NULL, NULL,
+/* 7C */ NULL, NULL, NULL, NULL,
+/* 80 */ NULL, NULL, NULL, NULL,
+/* 84 */ NULL, NULL, NULL, NULL,
+/* 88 */ NULL, NULL, "pfnacc", NULL,
+/* 8C */ NULL, NULL, "pfpnacc", NULL,
+/* 90 */ "pfcmpge", NULL, NULL, NULL,
+/* 94 */ "pfmin", NULL, "pfrcp", "pfrsqrt",
+/* 98 */ NULL, NULL, "pfsub", NULL,
+/* 9C */ NULL, NULL, "pfadd", NULL,
+/* A0 */ "pfcmpgt", NULL, NULL, NULL,
+/* A4 */ "pfmax", NULL, "pfrcpit1", "pfrsqit1",
+/* A8 */ NULL, NULL, "pfsubr", NULL,
+/* AC */ NULL, NULL, "pfacc", NULL,
+/* B0 */ "pfcmpeq", NULL, NULL, NULL,
+/* B4 */ "pfmul", NULL, "pfrcpit2", "pfmulhrw",
+/* B8 */ NULL, NULL, NULL, "pswapd",
+/* BC */ NULL, NULL, NULL, "pavgusb",
+/* C0 */ NULL, NULL, NULL, NULL,
+/* C4 */ NULL, NULL, NULL, NULL,
+/* C8 */ NULL, NULL, NULL, NULL,
+/* CC */ NULL, NULL, NULL, NULL,
+/* D0 */ NULL, NULL, NULL, NULL,
+/* D4 */ NULL, NULL, NULL, NULL,
+/* D8 */ NULL, NULL, NULL, NULL,
+/* DC */ NULL, NULL, NULL, NULL,
+/* E0 */ NULL, NULL, NULL, NULL,
+/* E4 */ NULL, NULL, NULL, NULL,
+/* E8 */ NULL, NULL, NULL, NULL,
+/* EC */ NULL, NULL, NULL, NULL,
+/* F0 */ NULL, NULL, NULL, NULL,
+/* F4 */ NULL, NULL, NULL, NULL,
+/* F8 */ NULL, NULL, NULL, NULL,
+/* FC */ NULL, NULL, NULL, NULL,
+};
+
+static void
+OP_3DNowSuffix (bytemode, sizeflag)
+ int bytemode ATTRIBUTE_UNUSED;
+ int sizeflag ATTRIBUTE_UNUSED;
+{
+ const char *mnemonic;
+
+ FETCH_DATA (the_info, codep + 1);
+ /* 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. */
+ obufp = obuf + strlen(obuf);
+ mnemonic = Suffix3DNow[*codep++ & 0xff];
+ if (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';
+ 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)");
}
OpenPOWER on IntegriCloud