* configure.ac: Add mips*-sde-elf* target.
[deliverable/binutils-gdb.git] / opcodes / i386-dis.c
index 6f5ac41b2f72c9d8bf1da54784f1922076be67dd..509cc5d38a3b92f2e6af9e4a10f7868b90099ef6 100644 (file)
@@ -1,6 +1,6 @@
 /* Print i386 instructions for GDB, the GNU debugger.
    Copyright 1988, 1989, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+   2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -85,6 +85,8 @@ static void OP_MMX (int, int);
 static void OP_XMM (int, int);
 static void OP_EM (int, int);
 static void OP_EX (int, int);
+static void OP_EMC (int,int);
+static void OP_MXC (int,int);
 static void OP_MS (int, int);
 static void OP_XS (int, int);
 static void OP_M (int, int);
@@ -100,9 +102,9 @@ static void PNI_Fixup (int, int);
 static void SVME_Fixup (int, int);
 static void INVLPG_Fixup (int, int);
 static void BadOp (void);
-static void SEG_Fixup (int, int);
 static void VMX_Fixup (int, int);
 static void REP_Fixup (int, int);
+static void CMPXCHG8B_Fixup (int, int);
 
 struct dis_private {
   /* Points to first byte not fetched.  */
@@ -208,7 +210,6 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #define Eb OP_E, b_mode
 #define Ev OP_E, v_mode
 #define Ed OP_E, d_mode
-#define Eq OP_E, q_mode
 #define Edq OP_E, dq_mode
 #define Edqw OP_E, dqw_mode
 #define indirEv OP_indirE, stack_v_mode
@@ -216,9 +217,10 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #define stackEv OP_E, stack_v_mode
 #define Em OP_E, m_mode
 #define Ew OP_E, w_mode
-#define Ma OP_E, v_mode
 #define M OP_M, 0              /* lea, lgdt, etc. */
+#define Ma OP_M, v_mode
 #define Mp OP_M, f_mode                /* 32 or 48 bit memory operand for LDS, LES etc */
+#define Mq OP_M, q_mode
 #define Gb OP_G, b_mode
 #define Gv OP_G, v_mode
 #define Gd OP_G, d_mode
@@ -239,7 +241,6 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #define Cm OP_C, m_mode
 #define Dm OP_D, m_mode
 #define Td OP_T, d_mode
-#define Sv SEG_Fixup, v_mode
 
 #define RMeAX OP_REG, eAX_reg
 #define RMeBX OP_REG, eBX_reg
@@ -287,14 +288,17 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #define BH OP_IMREG, bh_reg
 #define AX OP_IMREG, ax_reg
 #define DX OP_IMREG, dx_reg
+#define zAX OP_IMREG, z_mode_ax_reg
 #define indirDX OP_IMREG, indir_dx_reg
 
 #define Sw OP_SEG, w_mode
+#define Sv OP_SEG, v_mode
 #define Ap OP_DIR, 0
 #define Ob OP_OFF64, b_mode
 #define Ov OP_OFF64, v_mode
 #define Xb OP_DSreg, eSI_reg
 #define Xv OP_DSreg, eSI_reg
+#define Xz OP_DSreg, eSI_reg
 #define Yb OP_ESreg, eDI_reg
 #define Yv OP_ESreg, eDI_reg
 #define DSBX OP_DSreg, eBX_reg
@@ -312,6 +316,8 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #define EX OP_EX, v_mode
 #define MS OP_MS, v_mode
 #define XS OP_XS, v_mode
+#define EMC OP_EMC, v_mode
+#define MXC OP_MXC, 0
 #define VM OP_VMX, q_mode
 #define OPSUF OP_3DNowSuffix, 0
 #define OPSIMD OP_SIMD_Suffix, 0
@@ -321,6 +327,7 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #define Xvr REP_Fixup, eSI_reg
 #define Ybr REP_Fixup, eDI_reg
 #define Yvr REP_Fixup, eDI_reg
+#define Yzr REP_Fixup, eDI_reg
 #define indirDXr REP_Fixup, indir_dx_reg
 #define ALr REP_Fixup, al_reg
 #define eAXr REP_Fixup, eAX_reg
@@ -348,6 +355,8 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #define f_mode 13 /* 4- or 6-byte pointer operand */
 #define const_1_mode 14
 #define stack_v_mode 15 /* v_mode for stack-related opcodes.  */
+#define z_mode 16 /* non-quad operand size depends on prefixes */
+#define o_mode 17  /* 16-byte operand */
 
 #define es_reg 100
 #define cs_reg 101
@@ -392,6 +401,7 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #define rSI_reg 138
 #define rDI_reg 139
 
+#define z_mode_ax_reg 149
 #define indir_dx_reg 150
 
 #define FLOATCODE 1
@@ -419,14 +429,16 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #define GRP7     NULL, NULL, USE_GROUPS, NULL, 14, NULL, 0, NULL, 0
 #define GRP8     NULL, NULL, USE_GROUPS, NULL, 15, NULL, 0, NULL, 0
 #define GRP9     NULL, NULL, USE_GROUPS, NULL, 16, NULL, 0, NULL, 0
-#define GRP12    NULL, NULL, USE_GROUPS, NULL, 17, NULL, 0, NULL, 0
-#define GRP13    NULL, NULL, USE_GROUPS, NULL, 18, NULL, 0, NULL, 0
-#define GRP14    NULL, NULL, USE_GROUPS, NULL, 19, NULL, 0, NULL, 0
-#define GRP15    NULL, NULL, USE_GROUPS, NULL, 20, NULL, 0, NULL, 0
-#define GRP16    NULL, NULL, USE_GROUPS, NULL, 21, NULL, 0, NULL, 0
-#define GRPAMD   NULL, NULL, USE_GROUPS, NULL, 22, NULL, 0, NULL, 0
-#define GRPPADLCK1 NULL, NULL, USE_GROUPS, NULL, 23, NULL, 0, NULL, 0
-#define GRPPADLCK2 NULL, NULL, USE_GROUPS, NULL, 24, NULL, 0, NULL, 0
+#define GRP11_C6  NULL, NULL, USE_GROUPS, NULL, 17, NULL, 0, NULL, 0
+#define GRP11_C7  NULL, NULL, USE_GROUPS, NULL, 18, NULL, 0, NULL, 0
+#define GRP12    NULL, NULL, USE_GROUPS, NULL, 19, NULL, 0, NULL, 0
+#define GRP13    NULL, NULL, USE_GROUPS, NULL, 20, NULL, 0, NULL, 0
+#define GRP14    NULL, NULL, USE_GROUPS, NULL, 21, NULL, 0, NULL, 0
+#define GRP15    NULL, NULL, USE_GROUPS, NULL, 22, NULL, 0, NULL, 0
+#define GRP16    NULL, NULL, USE_GROUPS, NULL, 23, NULL, 0, NULL, 0
+#define GRPAMD   NULL, NULL, USE_GROUPS, NULL, 24, NULL, 0, NULL, 0
+#define GRPPADLCK1 NULL, NULL, USE_GROUPS, NULL, 25, NULL, 0, NULL, 0
+#define GRPPADLCK2 NULL, NULL, USE_GROUPS, NULL, 26, NULL, 0, NULL, 0
 
 #define PREGRP0   NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  0, NULL, 0, NULL, 0
 #define PREGRP1   NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  1, NULL, 0, NULL, 0
@@ -465,8 +477,13 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #define PREGRP34  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 34, NULL, 0, NULL, 0
 #define PREGRP35  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 35, NULL, 0, NULL, 0
 #define PREGRP36  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 36, NULL, 0, NULL, 0
+#define PREGRP37  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 37, NULL, 0, NULL, 0
 
-#define X86_64_0  NULL, NULL, X86_64_SPECIAL, NULL,  0, NULL, 0, NULL, 0
+
+#define X86_64_0  NULL, NULL, X86_64_SPECIAL, NULL, 0, NULL, 0, NULL, 0
+#define X86_64_1  NULL, NULL, X86_64_SPECIAL, NULL, 1, NULL, 0, NULL, 0
+#define X86_64_2  NULL, NULL, X86_64_SPECIAL, NULL, 2, NULL, 0, NULL, 0
+#define X86_64_3  NULL, NULL, X86_64_SPECIAL, NULL, 3, NULL, 0, NULL, 0
 
 #define THREE_BYTE_0 NULL, NULL, IS_3BYTE_OPCODE, NULL, 0, NULL, 0, NULL, 0
 #define THREE_BYTE_1 NULL, NULL, IS_3BYTE_OPCODE, NULL, 1, NULL, 0, NULL, 0
@@ -490,25 +507,28 @@ struct dis386 {
    'B' => print 'b' if suffix_always is true
    'C' => print 's' or 'l' ('w' or 'd' in Intel mode) depending on operand
    .      size prefix
+   'D' => print 'w' if no register operands or 'w', 'l' or 'q', if
+   .      suffix_always is true
    'E' => print 'e' if 32-bit form of jcxz
    'F' => print 'w' or 'l' depending on address size prefix (loop insns)
+   'G' => print 'w' or 'l' depending on operand size prefix (i/o insns)
    'H' => print ",pt" or ",pn" branch hint
    'I' => honor following macro letter even in Intel mode (implemented only
    .      for some of the macro letters)
    'J' => print 'l'
    'L' => print 'l' if suffix_always is true
    'N' => print 'n' if instruction has no wait "prefix"
-   'O' => print 'd', or 'o'
+   'O' => print 'd' or 'o' (or 'q' in Intel mode)
    'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
    .      or suffix_always is true.  print 'q' if rex prefix is present.
    'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always
    .      is true
-   'R' => print 'w', 'l' or 'q' ("wd" or "dq" in intel mode)
+   'R' => print 'w', 'l' or 'q' ('d' for 'l' and 'e' in Intel mode)
    'S' => print 'w', 'l' or 'q' if suffix_always is true
    'T' => print 'q' in 64bit mode and behave as 'P' otherwise
    'U' => print 'q' in 64bit mode and behave as 'Q' otherwise
    'V' => print 'q' in 64bit mode and behave as 'S' otherwise
-   'W' => print 'b' or 'w' ("w" or "de" in intel mode)
+   'W' => print 'b', 'w' or 'l' ('d' in Intel mode)
    'X' => print 's', 'd' depending on data16 prefix (for XMM)
    'Y' => 'q' if instruction has an REX 64bit overwrite prefix
    'Z' => print 'q' in 64bit mode and behave as 'L' otherwise
@@ -536,7 +556,7 @@ static const struct dis386 dis386[] = {
   { "orB",             Eb, Gb, XX, XX },
   { "orS",             Ev, Gv, XX, XX },
   { "orB",             Gb, Eb, XX, XX },
-  { "orS",             Gv, Ev, XX , XX},
+  { "orS",             Gv, Ev, XX, XX },
   { "orB",             AL, Ib, XX, XX },
   { "orS",             eAX, Iv, XX, XX },
   { "push{T|}",                cs, XX, XX, XX },
@@ -570,7 +590,7 @@ static const struct dis386 dis386[] = {
   { "daa{|}",          XX, XX, XX, XX },
   /* 28 */
   { "subB",            Eb, Gb, XX, XX },
-  { "subS",            Ev, Gv, XX, XX},
+  { "subS",            Ev, Gv, XX, XX },
   { "subB",            Gb, Eb, XX, XX },
   { "subS",            Gv, Ev, XX, XX },
   { "subB",            AL, Ib, XX, XX },
@@ -632,10 +652,10 @@ static const struct dis386 dis386[] = {
   { "popV",            RMrSI, XX, XX, XX },
   { "popV",            RMrDI, XX, XX, XX },
   /* 60 */
-  { "pusha{P|}",       XX, XX, XX, XX},
-  { "popa{P|}",                XX, XX, XX, XX },
-  { "bound{S|}",       Gv, Ma, XX, XX },
   { X86_64_0 },
+  { X86_64_1 },
+  { X86_64_2 },
+  { X86_64_3 },
   { "(bad)",           XX, XX, XX, XX },       /* seg fs */
   { "(bad)",           XX, XX, XX, XX },       /* seg gs */
   { "(bad)",           XX, XX, XX, XX },       /* op size prefix */
@@ -646,9 +666,9 @@ static const struct dis386 dis386[] = {
   { "pushT",           sIb, XX, XX, XX },
   { "imulS",           Gv, Ev, sIb, XX },
   { "ins{b||b|}",      Ybr, indirDX, XX, XX },
-  { "ins{R||R|}",      Yvr, indirDX, XX, XX },
+  { "ins{R||G|}",      Yzr, indirDX, XX, XX },
   { "outs{b||b|}",     indirDXr, Xb, XX, XX },
-  { "outs{R||R|}",     indirDXr, Xv, XX, XX },
+  { "outs{R||G|}",     indirDXr, Xz, XX, XX },
   /* 70 */
   { "joH",             Jb, XX, cond_jump_flag, XX },
   { "jnoH",            Jb, XX, cond_jump_flag, XX },
@@ -681,9 +701,9 @@ static const struct dis386 dis386[] = {
   { "movS",            Ev, Gv, XX, XX },
   { "movB",            Gb, Eb, XX, XX },
   { "movS",            Gv, Ev, XX, XX },
-  { "movQ",            Sv, Sw, XX, XX },
+  { "movD",            Sv, Sw, XX, XX },
   { "leaS",            Gv, M, XX, XX },
-  { "movQ",            Sw, Sv, XX, XX },
+  { "movD",            Sw, Sv, XX, XX },
   { "popU",            stackEv, XX, XX, XX },
   /* 90 */
   { "xchgS",           NOP_Fixup1, eAX_reg, NOP_Fixup2, eAX_reg, XX, XX },
@@ -695,8 +715,8 @@ static const struct dis386 dis386[] = {
   { "xchgS",           RMeSI, eAX, XX, XX },
   { "xchgS",           RMeDI, eAX, XX, XX },
   /* 98 */
-  { "cW{tR||tR|}",     XX, XX, XX, XX },
-  { "cR{tO||tO|}",     XX, XX, XX, XX },
+  { "cW{t||t|}R",      XX, XX, XX, XX },
+  { "cR{t||t|}O",      XX, XX, XX, XX },
   { "Jcall{T|}",       Ap, XX, XX, XX },
   { "(bad)",           XX, XX, XX, XX },       /* fwait */
   { "pushfT",          XX, XX, XX, XX },
@@ -746,8 +766,8 @@ static const struct dis386 dis386[] = {
   { "retT",            XX, XX, XX, XX },
   { "les{S|}",         Gv, Mp, XX, XX },
   { "ldsS",            Gv, Mp, XX, XX },
-  { "movA",            Eb, Ib, XX, XX },
-  { "movQ",            Ev, Iv, XX, XX },
+  { GRP11_C6 },
+  { GRP11_C7 },
   /* c8 */
   { "enterT",          Iw, Ib, XX, XX },
   { "leaveT",          XX, XX, XX, XX },
@@ -781,18 +801,18 @@ static const struct dis386 dis386[] = {
   { "loopFH",          Jb, XX, loop_jcxz_flag, XX },
   { "jEcxzH",          Jb, XX, loop_jcxz_flag, XX },
   { "inB",             AL, Ib, XX, XX },
-  { "inS",             eAX, Ib, XX, XX },
+  { "inG",             zAX, Ib, XX, XX },
   { "outB",            Ib, AL, XX, XX },
-  { "outS",            Ib, eAX, XX, XX },
+  { "outG",            Ib, zAX, XX, XX },
   /* e8 */
   { "callT",           Jv, XX, XX, XX },
   { "jmpT",            Jv, XX, XX, XX },
   { "Jjmp{T|}",                Ap, XX, XX, XX },
   { "jmp",             Jb, XX, XX, XX },
   { "inB",             AL, indirDX, XX, XX },
-  { "inS",             eAX, indirDX, XX, XX },
+  { "inG",             zAX, indirDX, XX, XX },
   { "outB",            indirDX, AL, XX, XX },
-  { "outS",            indirDX, eAX, XX, XX },
+  { "outG",            indirDX, zAX, XX, XX },
   /* f0 */
   { "(bad)",           XX, XX, XX, XX },       /* lock prefix */
   { "icebp",           XX, XX, XX, XX },
@@ -824,7 +844,7 @@ static const struct dis386 dis386_twobyte[] = {
   { "clts",            XX, XX, XX, XX },
   { "sysretP",         XX, XX, XX, XX },
   /* 08 */
-  { "invd",            XX, XX, XX, XX},
+  { "invd",            XX, XX, XX, XX },
   { "wbinvd",          XX, XX, XX, XX },
   { "(bad)",           XX, XX, XX, XX },
   { "ud2a",            XX, XX, XX, XX },
@@ -1022,7 +1042,7 @@ static const struct dis386 dis386_twobyte[] = {
   { "movz{bR|x|bR|x}", Gv, Eb, XX, XX },
   { "movz{wR|x|wR|x}", Gv, Ew, XX, XX }, /* yes, there really is movzww ! */
   /* b8 */
-  { "popcntS",          Gv, Ev, XX, XX },
+  { PREGRP37 },
   { "ud2b",            XX, XX, XX, XX },
   { GRP8 },
   { "btcS",            Ev, Gv, XX, XX },
@@ -1150,7 +1170,7 @@ static const unsigned char twobyte_has_modrm[256] = {
   /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
 };
 
-static const unsigned char twobyte_uses_SSE_prefix[256] = {
+static const unsigned char twobyte_uses_DATA_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 */
@@ -1173,6 +1193,196 @@ static const unsigned char twobyte_uses_SSE_prefix[256] = {
   /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
 };
 
+static const unsigned char twobyte_uses_REPNZ_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,1,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,1,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,0,0,0,0,0,0,1,1,1,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 */ 1,0,0,0,0,0,0,0,1,1,0,0,1,1,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 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
+  /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
+  /* f0 */ 1,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 const unsigned char twobyte_uses_REPZ_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,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
+  /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,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,1,1,1,1,1,1, /* 5f */
+  /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, /* 6f */
+  /* 70 */ 1,0,0,0,0,0,0,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 */ 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,1,0,0,0,0,1,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,1,0,0,0,0,0,0,0,0,0, /* df */
+  /* e0 */ 0,0,0,0,0,0,1,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        */
+};
+
+/* This is used to determine if opcode 0f 38 XX uses DATA prefix.  */ 
+static const unsigned char threebyte_0x38_uses_DATA_prefix[256] = {
+  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
+  /*       -------------------------------        */
+  /* 00 */ 1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0, /* 0f */
+  /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0, /* 1f */
+  /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 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,0,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        */
+};
+
+/* This is used to determine if opcode 0f 38 XX uses REPNZ prefix.  */ 
+static const unsigned char threebyte_0x38_uses_REPNZ_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 */ 0,0,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,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 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,0,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        */
+};
+
+/* This is used to determine if opcode 0f 38 XX uses REPZ prefix.  */ 
+static const unsigned char threebyte_0x38_uses_REPZ_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 */ 0,0,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,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 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,0,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        */
+};
+
+/* This is used to determine if opcode 0f 3a XX uses DATA prefix.  */ 
+static const unsigned char threebyte_0x3a_uses_DATA_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,1, /* 0f */
+  /* 10 */ 0,0,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,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 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,0,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        */
+};
+
+/* This is used to determine if opcode 0f 3a XX uses REPNZ prefix.  */ 
+static const unsigned char threebyte_0x3a_uses_REPNZ_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 */ 0,0,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,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 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,0,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        */
+};
+
+/* This is used to determine if opcode 0f 3a XX uses REPZ prefix.  */ 
+static const unsigned char threebyte_0x3a_uses_REPZ_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 */ 0,0,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,0,0,0,0,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 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,0,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];
@@ -1396,8 +1606,8 @@ static const struct dis386 grps[][8] = {
   },
   /* GRP6 */
   {
-    { "sldtQ", Ev, XX, XX, XX },
-    { "strQ",  Ev, XX, XX, XX },
+    { "sldtD", Sv, XX, XX, XX },
+    { "strD",  Sv, XX, XX, XX },
     { "lldt",  Ew, XX, XX, XX },
     { "ltr",   Ew, XX, XX, XX },
     { "verr",  Ew, XX, XX, XX },
@@ -1411,7 +1621,7 @@ static const struct dis386 grps[][8] = {
     { "sidt{Q|IQ||}", PNI_Fixup, 0, XX, XX, XX },
     { "lgdt{Q|Q||}",    M, XX, XX, XX },
     { "lidt{Q|Q||}",    SVME_Fixup, 0, XX, XX, XX },
-    { "smswQ", Ev, XX, XX, XX },
+    { "smswD", Sv, XX, XX, XX },
     { "(bad)", XX, XX, XX, XX },
     { "lmsw",  Ew, XX, XX, XX },
     { "invlpg",        INVLPG_Fixup, w_mode, XX, XX, XX },
@@ -1430,13 +1640,35 @@ static const struct dis386 grps[][8] = {
   /* GRP9 */
   {
     { "(bad)", XX, XX, XX, XX },
-    { "cmpxchg8b", Eq, XX, XX, XX },
+    { "cmpxchg8b", CMPXCHG8B_Fixup, q_mode, XX, XX, XX },
     { "(bad)", XX, XX, XX, XX },
     { "(bad)", XX, XX, XX, XX },
     { "(bad)", XX, XX, XX, XX },
     { "(bad)", XX, XX, XX, XX },
     { "",      VM, XX, XX, XX },               /* See OP_VMX.  */
-    { "vmptrst", Eq, XX, XX, XX },
+    { "vmptrst", Mq, XX, XX, XX },
+  },
+  /* GRP11_C6 */
+  {
+    { "movA",  Eb, Ib, XX, XX },
+    { "(bad)", XX, XX, XX, XX },
+    { "(bad)", XX, XX, XX, XX },
+    { "(bad)", XX, XX, XX, XX },
+    { "(bad)", XX, XX, XX, XX },
+    { "(bad)", XX, XX, XX, XX },
+    { "(bad)", XX, XX, XX, XX },
+    { "(bad)", XX, XX, XX, XX },
+  },
+  /* GRP11_C7 */
+  {
+    { "movQ",  Ev, Iv, XX, XX },
+    { "(bad)", XX, XX, XX, XX },
+    { "(bad)", XX, XX, XX, XX },
+    { "(bad)", XX, XX, XX, XX },
+    { "(bad)", XX, XX, XX, XX },
+    { "(bad)", XX, XX, XX, XX },
+    { "(bad)", XX, XX, XX, XX },
+    { "(bad)", XX, XX, XX, XX },
   },
   /* GRP12 */
   {
@@ -1545,23 +1777,23 @@ static const struct dis386 prefix_user_table[][4] = {
   },
   /* PREGRP2 */
   {
-    { "cvtpi2ps", XM, EM, XX, XX },
+    { "cvtpi2ps", XM, EMC, XX, XX },
     { "cvtsi2ssY", XM, Ev, XX, XX },
-    { "cvtpi2pd", XM, EM, XX, XX },
+    { "cvtpi2pd", XM, EMC, XX, XX },
     { "cvtsi2sdY", XM, Ev, XX, XX },
   },
   /* PREGRP3 */
   {
-    { "cvtps2pi", MX, EX, XX, XX },
+    { "cvtps2pi", MXC, EX, XX, XX },
     { "cvtss2siY", Gv, EX, XX, XX },
-    { "cvtpd2pi", MX, EX, XX, XX },
+    { "cvtpd2pi", MXC, EX, XX, XX },
     { "cvtsd2siY", Gv, EX, XX, XX },
   },
   /* PREGRP4 */
   {
-    { "cvttps2pi", MX, EX, XX, XX },
+    { "cvttps2pi", MXC, EX, XX, XX },
     { "cvttss2siY", Gv, EX, XX, XX },
-    { "cvttpd2pi", MX, EX, XX, XX },
+    { "cvttpd2pi", MXC, EX, XX, XX },
     { "cvttsd2siY", Gv, EX, XX, XX },
   },
   /* PREGRP5 */
@@ -1636,7 +1868,7 @@ static const struct dis386 prefix_user_table[][4] = {
   },
   /* PREGRP15 */
   {
-    { "(bad)", XM, EX, XX, XX},
+    { "(bad)", XM, EX, XX, XX },
     { "cvtdq2pd", XM, EX, XX, XX },
     { "cvttpd2dq", XM, EX, XX, XX },
     { "cvtpd2dq", XM, EX, XX, XX },
@@ -1659,7 +1891,7 @@ static const struct dis386 prefix_user_table[][4] = {
   {
     { "maskmovq", MX, MS, XX, XX },
     { "(bad)", XM, EX, XX, XX },
-    { "maskmovdqu", XM, EX, XX, XX },
+    { "maskmovdqu", XM, XS, XX, XX },
     { "(bad)", XM, EX, XX, XX },
   },
   /* PREGRP19 */
@@ -1688,7 +1920,7 @@ static const struct dis386 prefix_user_table[][4] = {
     { "pshufw", MX, EM, Ib, XX },
     { "pshufhw", XM, EX, Ib, XX },
     { "pshufd", XM, EX, Ib, XX },
-    { "pshuflw", XM, EX, Ib, XX},
+    { "pshuflw", XM, EX, Ib, XX },
   },
   /* PREGRP23 */
   {
@@ -1762,26 +1994,26 @@ static const struct dis386 prefix_user_table[][4] = {
   },
   /* PREGRP33 */
   {
-    {"movntps",Ev, XM, XX, XX},
-    {"movntss",Ev, XM, XX, XX},
-    {"movntpd",Ev, XM, XX, XX},
-    {"movntsd",Ev, XM, XX, XX},
+    {"movntps",Ev, XM, XX, XX },
+    {"movntss",Ev, XM, XX, XX },
+    {"movntpd",Ev, XM, XX, XX },
+    {"movntsd",Ev, XM, XX, XX },
   },
 
   /* PREGRP34 */
   {
-    {"vmread", Em, Gm, XX, XX},
-    {"(bad)",  XX, XX, XX, XX},
-    {"extrq",  XS, Ib, Ib, XX},
-    {"insertq",XM, XS, Ib, Ib},
+    {"vmread", Em, Gm, XX, XX },
+    {"(bad)",  XX, XX, XX, XX },
+    {"extrq",  XS, Ib, Ib, XX },
+    {"insertq",XM, XS, Ib, Ib },
   },
   
  /* PREGRP35 */  
   {
-    {"vmwrite", Gm, Em, XX, XX},
-    {"(bad)",   XX, XX, XX, XX},
-    {"extrq",   XM, XS, XX, XX},
-    {"insertq", XM, XS, XX, XX},
+    {"vmwrite", Gm, Em, XX, XX },
+    {"(bad)",   XX, XX, XX, XX },
+    {"extrq",   XM, XS, XX, XX },
+    {"insertq", XM, XS, XX, XX },
   }, 
 
   /* PREGRP36 */
@@ -1792,18 +2024,38 @@ static const struct dis386 prefix_user_table[][4] = {
     { "(bad)",  XX, XX, XX, XX },
   },
 
+  /* PREGRP37 */
+  {
+    { "(bad)",  XX, XX, XX, XX },
+    { "popcntS",Gv, Ev, XX, XX },
+    { "(bad)",  XX, XX, XX, XX },
+    { "(bad)",  XX, XX, XX, XX },    
+  },
 };
 
 static const struct dis386 x86_64_table[][2] = {
   {
-    { "arpl", Ew, Gw, XX, XX },
-    { "movs{||lq|xd}", Gv, Ed, XX, XX },
+    { "pusha{P|}",     XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+  },
+  {
+    { "popa{P|}",      XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+  },
+  {
+    { "bound{S|}",     Gv, Ma, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+  },
+  {
+    { "arpl",          Ew, Gw, XX, XX },
+    { "movs{||lq|xd}", Gv, Ed, XX, XX },
   },
 };
 
-static const struct dis386 three_byte_table[][32] = {
+static const struct dis386 three_byte_table[][256] = {
   /* THREE_BYTE_0 */
   {
+    /* 00 */
     { "pshufb",                MX, EM, XX, XX },
     { "phaddw",                MX, EM, XX, XX },
     { "phaddd",                MX, EM, XX, XX },
@@ -1812,6 +2064,7 @@ static const struct dis386 three_byte_table[][32] = {
     { "phsubw",                MX, EM, XX, XX },
     { "phsubd",                MX, EM, XX, XX },
     { "phsubsw",       MX, EM, XX, XX },
+    /* 08 */
     { "psignb",                MX, EM, XX, XX },
     { "psignw",                MX, EM, XX, XX },
     { "psignd",                MX, EM, XX, XX },
@@ -1820,27 +2073,451 @@ static const struct dis386 three_byte_table[][32] = {
     { "(bad)",         XX, XX, XX, XX },
     { "(bad)",         XX, XX, XX, XX },
     { "(bad)",         XX, XX, XX, XX },
+    /* 10 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* 18 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "pabsb",         MX, EM, XX, XX },
+    { "pabsw",         MX, EM, XX, XX },
+    { "pabsd",         MX, EM, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* 20 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* 28 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* 30 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* 38 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* 40 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* 48 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* 50 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* 58 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* 60 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* 68 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* 70 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* 78 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* 80 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* 88 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* 90 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* 98 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* a0 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* a8 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* b0 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* b8 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* c0 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* c8 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* d0 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* d8 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* e0 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* e8 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* f0 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* f8 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX }
+  },
+  /* THREE_BYTE_1 */
+  {
+    /* 00 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* 08 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "palignr",       MX, EM, Ib, XX },
+    /* 10 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* 18 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* 20 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* 28 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* 30 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* 38 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* 40 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* 48 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* 50 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* 58 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* 60 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* 68 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* 70 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* 78 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* 80 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* 88 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
     { "(bad)",         XX, XX, XX, XX },
     { "(bad)",         XX, XX, XX, XX },
     { "(bad)",         XX, XX, XX, XX },
     { "(bad)",         XX, XX, XX, XX },
     { "(bad)",         XX, XX, XX, XX },
     { "(bad)",         XX, XX, XX, XX },
+    /* 90 */
     { "(bad)",         XX, XX, XX, XX },
     { "(bad)",         XX, XX, XX, XX },
     { "(bad)",         XX, XX, XX, XX },
     { "(bad)",         XX, XX, XX, XX },
     { "(bad)",         XX, XX, XX, XX },
     { "(bad)",         XX, XX, XX, XX },
-    { "pabsb",         MX, EM, XX, XX },
-    { "pabsw",         MX, EM, XX, XX },
-    { "pabsd",         MX, EM, XX, XX },
-    { "(bad)",         XX, XX, XX, XX }
-  },
-  /* THREE_BYTE_1 */
-  {
     { "(bad)",         XX, XX, XX, XX },
     { "(bad)",         XX, XX, XX, XX },
+    /* 98 */
     { "(bad)",         XX, XX, XX, XX },
     { "(bad)",         XX, XX, XX, XX },
     { "(bad)",         XX, XX, XX, XX },
@@ -1849,15 +2526,79 @@ static const struct dis386 three_byte_table[][32] = {
     { "(bad)",         XX, XX, XX, XX },
     { "(bad)",         XX, XX, XX, XX },
     { "(bad)",         XX, XX, XX, XX },
+    /* a0 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* a8 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* b0 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* b8 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* c0 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* c8 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* d0 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* d8 */
     { "(bad)",         XX, XX, XX, XX },
     { "(bad)",         XX, XX, XX, XX },
     { "(bad)",         XX, XX, XX, XX },
     { "(bad)",         XX, XX, XX, XX },
     { "(bad)",         XX, XX, XX, XX },
-    { "palignr",       MX, EM, Ib, XX },
     { "(bad)",         XX, XX, XX, XX },
     { "(bad)",         XX, XX, XX, XX },
     { "(bad)",         XX, XX, XX, XX },
+    /* e0 */
     { "(bad)",         XX, XX, XX, XX },
     { "(bad)",         XX, XX, XX, XX },
     { "(bad)",         XX, XX, XX, XX },
@@ -1866,6 +2607,28 @@ static const struct dis386 three_byte_table[][32] = {
     { "(bad)",         XX, XX, XX, XX },
     { "(bad)",         XX, XX, XX, XX },
     { "(bad)",         XX, XX, XX, XX },
+    /* e8 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* f0 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    /* f8 */
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
+    { "(bad)",         XX, XX, XX, XX },
     { "(bad)",         XX, XX, XX, XX },
     { "(bad)",         XX, XX, XX, XX },
     { "(bad)",         XX, XX, XX, XX },
@@ -2093,6 +2856,26 @@ print_insn_i386 (bfd_vma pc, disassemble_info *info)
   return print_insn (pc, info);
 }
 
+void
+print_i386_disassembler_options (FILE *stream)
+{
+  fprintf (stream, _("\n\
+The following i386/x86-64 specific disassembler options are supported for use\n\
+with the -M switch (multiple options should be separated by commas):\n"));
+
+  fprintf (stream, _("  x86-64      Disassemble in 64bit mode\n"));
+  fprintf (stream, _("  i386        Disassemble in 32bit mode\n"));
+  fprintf (stream, _("  i8086       Disassemble in 16bit mode\n"));
+  fprintf (stream, _("  att         Display instruction in AT&T syntax\n"));
+  fprintf (stream, _("  intel       Display instruction in Intel syntax\n"));
+  fprintf (stream, _("  addr64      Assume 64bit address size\n"));
+  fprintf (stream, _("  addr32      Assume 32bit address size\n"));
+  fprintf (stream, _("  addr16      Assume 16bit address size\n"));
+  fprintf (stream, _("  data32      Assume 32bit data size\n"));
+  fprintf (stream, _("  data16      Assume 16bit data size\n"));
+  fprintf (stream, _("  suffix      Always display instruction suffix in AT&T syntax\n"));
+}
+
 static int
 print_insn (bfd_vma pc, disassemble_info *info)
 {
@@ -2100,10 +2883,12 @@ print_insn (bfd_vma pc, disassemble_info *info)
   int i;
   char *first, *second, *third, *fourth;
   int needcomma;
-  unsigned char uses_SSE_prefix, uses_LOCK_prefix;
+  unsigned char uses_DATA_prefix, uses_LOCK_prefix;
+  unsigned char uses_REPNZ_prefix, uses_REPZ_prefix;
   int sizeflag;
   const char *p;
   struct dis_private priv;
+  unsigned char op;
 
   if (info->mach == bfd_mach_x86_64_intel_syntax
       || info->mach == bfd_mach_x86_64)
@@ -2127,44 +2912,54 @@ print_insn (bfd_vma pc, disassemble_info *info)
 
   for (p = info->disassembler_options; p != NULL; )
     {
-      if (strncmp (p, "x86-64", 6) == 0)
+      if (CONST_STRNEQ (p, "x86-64"))
        {
          address_mode = mode_64bit;
          priv.orig_sizeflag = AFLAG | DFLAG;
        }
-      else if (strncmp (p, "i386", 4) == 0)
+      else if (CONST_STRNEQ (p, "i386"))
        {
          address_mode = mode_32bit;
          priv.orig_sizeflag = AFLAG | DFLAG;
        }
-      else if (strncmp (p, "i8086", 5) == 0)
+      else if (CONST_STRNEQ (p, "i8086"))
        {
          address_mode = mode_16bit;
          priv.orig_sizeflag = 0;
        }
-      else if (strncmp (p, "intel", 5) == 0)
+      else if (CONST_STRNEQ (p, "intel"))
        {
          intel_syntax = 1;
        }
-      else if (strncmp (p, "att", 3) == 0)
+      else if (CONST_STRNEQ (p, "att"))
        {
          intel_syntax = 0;
        }
-      else if (strncmp (p, "addr", 4) == 0)
+      else if (CONST_STRNEQ (p, "addr"))
        {
-         if (p[4] == '1' && p[5] == '6')
-           priv.orig_sizeflag &= ~AFLAG;
-         else if (p[4] == '3' && p[5] == '2')
-           priv.orig_sizeflag |= AFLAG;
+         if (address_mode == mode_64bit)
+           {
+             if (p[4] == '3' && p[5] == '2')
+               priv.orig_sizeflag &= ~AFLAG;
+             else if (p[4] == '6' && p[5] == '4')
+               priv.orig_sizeflag |= AFLAG;
+           }
+         else
+           {
+             if (p[4] == '1' && p[5] == '6')
+               priv.orig_sizeflag &= ~AFLAG;
+             else if (p[4] == '3' && p[5] == '2')
+               priv.orig_sizeflag |= AFLAG;
+           }
        }
-      else if (strncmp (p, "data", 4) == 0)
+      else if (CONST_STRNEQ (p, "data"))
        {
          if (p[4] == '1' && p[5] == '6')
            priv.orig_sizeflag &= ~DFLAG;
          else if (p[4] == '3' && p[5] == '2')
            priv.orig_sizeflag |= DFLAG;
        }
-      else if (strncmp (p, "suffix", 6) == 0)
+      else if (CONST_STRNEQ (p, "suffix"))
        priv.orig_sizeflag |= SUFFIX_ALWAYS;
 
       p = strchr (p, ',');
@@ -2271,36 +3066,62 @@ print_insn (bfd_vma pc, disassemble_info *info)
       return 1;
     }
 
+  op = 0;
   if (*codep == 0x0f)
     {
+      unsigned char threebyte;
       FETCH_DATA (info, codep + 2);
-      dp = &dis386_twobyte[*++codep];
+      threebyte = *++codep;
+      dp = &dis386_twobyte[threebyte];
       need_modrm = twobyte_has_modrm[*codep];
-      uses_SSE_prefix = twobyte_uses_SSE_prefix[*codep];
+      uses_DATA_prefix = twobyte_uses_DATA_prefix[*codep];
+      uses_REPNZ_prefix = twobyte_uses_REPNZ_prefix[*codep];
+      uses_REPZ_prefix = twobyte_uses_REPZ_prefix[*codep];
       uses_LOCK_prefix = (*codep & ~0x02) == 0x20;
+      codep++;
+      if (dp->name == NULL && dp->bytemode1 == IS_3BYTE_OPCODE)
+       {
+         FETCH_DATA (info, codep + 2);
+         op = *codep++;
+         switch (threebyte)
+           {
+           case 0x38:
+             uses_DATA_prefix = threebyte_0x38_uses_DATA_prefix[op];
+             uses_REPNZ_prefix = threebyte_0x38_uses_REPNZ_prefix[op];
+             uses_REPZ_prefix = threebyte_0x38_uses_REPZ_prefix[op];
+             break;
+           case 0x3a:
+             uses_DATA_prefix = threebyte_0x3a_uses_DATA_prefix[op];
+             uses_REPNZ_prefix = threebyte_0x3a_uses_REPNZ_prefix[op];
+             uses_REPZ_prefix = threebyte_0x3a_uses_REPZ_prefix[op];
+             break;
+           default:
+             break;
+           }
+       }
     }
   else
     {
       dp = &dis386[*codep];
       need_modrm = onebyte_has_modrm[*codep];
-      uses_SSE_prefix = 0;
+      uses_DATA_prefix = 0;
+      uses_REPNZ_prefix = 0;
+      uses_REPZ_prefix = 0;
       uses_LOCK_prefix = 0;
+      codep++;
     }
   
-  /*"lzcnt"=0xBD is the only non-sse instruction which uses F3 in the opcode without any "rep(z|nz)"*/
-  if (!uses_SSE_prefix && (prefixes & PREFIX_REPZ) && *codep !=0xBD)
+  if (!uses_REPZ_prefix && (prefixes & PREFIX_REPZ))
     {
       oappend ("repz ");
       used_prefixes |= PREFIX_REPZ;
     }
-  if (!uses_SSE_prefix && (prefixes & PREFIX_REPNZ) && *codep !=0xBD)
+  if (!uses_REPNZ_prefix && (prefixes & PREFIX_REPNZ))
     {
       oappend ("repnz ");
       used_prefixes |= PREFIX_REPNZ;
     }
 
-  codep++;
-
   if (!uses_LOCK_prefix && (prefixes & PREFIX_LOCK))
     {
       oappend ("lock ");
@@ -2320,7 +3141,7 @@ print_insn (bfd_vma pc, disassemble_info *info)
        }
     }
 
-  if (!uses_SSE_prefix && (prefixes & PREFIX_DATA))
+  if (!uses_DATA_prefix && (prefixes & PREFIX_DATA))
     {
       sizeflag ^= DFLAG;
       if (dp->bytemode3 == cond_jump_mode
@@ -2337,8 +3158,7 @@ print_insn (bfd_vma pc, disassemble_info *info)
 
   if (dp->name == NULL && dp->bytemode1 == IS_3BYTE_OPCODE)
     {
-      FETCH_DATA (info, codep + 2);
-      dp = &three_byte_table[dp->bytemode2][*codep++];
+      dp = &three_byte_table[dp->bytemode2][op];
       mod = (*codep >> 6) & 3;
       reg = (*codep >> 3) & 7;
       rm = *codep & 7;
@@ -2373,14 +3193,16 @@ print_insn (bfd_vma pc, disassemble_info *info)
                index = 1;
              else
                {
-                 used_prefixes |= (prefixes & PREFIX_DATA);
-                 if (prefixes & PREFIX_DATA)
-                   index = 2;
+                 /* We should check PREFIX_REPNZ and PREFIX_REPZ
+                    before PREFIX_DATA.  */
+                 used_prefixes |= (prefixes & PREFIX_REPNZ);
+                 if (prefixes & PREFIX_REPNZ)
+                   index = 3;
                  else
                    {
-                     used_prefixes |= (prefixes & PREFIX_REPNZ);
-                     if (prefixes & PREFIX_REPNZ)
-                       index = 3;
+                     used_prefixes |= (prefixes & PREFIX_DATA);
+                     if (prefixes & PREFIX_DATA)
+                       index = 2;
                    }
                }
              dp = &prefix_user_table[dp->bytemode2][index];
@@ -2974,6 +3796,23 @@ putop (const char *template, int sizeflag)
              used_prefixes |= (prefixes & PREFIX_DATA);
            }
          break;
+       case 'D':
+         if (intel_syntax || !(sizeflag & SUFFIX_ALWAYS))
+           break;
+         USED_REX (REX_MODE64);
+         if (mod == 3)
+           {
+             if (rex & REX_MODE64)
+               *obufp++ = 'q';
+             else if (sizeflag & DFLAG)
+               *obufp++ = intel_syntax ? 'd' : 'l';
+             else
+               *obufp++ = 'w';
+             used_prefixes |= (prefixes & PREFIX_DATA);
+           }
+         else
+           *obufp++ = 'w';
+         break;
        case 'E':               /* For jcxz/jecxz */
          if (address_mode == mode_64bit)
            {
@@ -2999,6 +3838,16 @@ putop (const char *template, int sizeflag)
              used_prefixes |= (prefixes & PREFIX_ADDR);
            }
          break;
+       case 'G':
+         if (intel_syntax || (obufp[-1] != 's' && !(sizeflag & SUFFIX_ALWAYS)))
+           break;
+         if ((rex & REX_MODE64) || (sizeflag & DFLAG))
+           *obufp++ = 'l';
+         else
+           *obufp++ = 'w';
+         if (!(rex & REX_MODE64))
+           used_prefixes |= (prefixes & PREFIX_DATA);
+         break;
        case 'H':
          if (intel_syntax)
            break;
@@ -3044,8 +3893,12 @@ putop (const char *template, int sizeflag)
          USED_REX (REX_MODE64);
          if (rex & REX_MODE64)
            *obufp++ = 'o';
+         else if (intel_syntax && (sizeflag & DFLAG))
+           *obufp++ = 'q';
          else
            *obufp++ = 'd';
+         if (!(rex & REX_MODE64))
+           used_prefixes |= (prefixes & PREFIX_DATA);
          break;
        case 'T':
          if (intel_syntax)
@@ -3106,33 +3959,20 @@ putop (const char *template, int sizeflag)
          break;
        case 'R':
          USED_REX (REX_MODE64);
-         if (intel_syntax)
+         if (rex & REX_MODE64)
+           *obufp++ = 'q';
+         else if (sizeflag & DFLAG)
            {
-             if (rex & REX_MODE64)
-               {
-                 *obufp++ = 'q';
-                 *obufp++ = 't';
-               }
-             else if (sizeflag & DFLAG)
-               {
+             if (intel_syntax)
                  *obufp++ = 'd';
-                 *obufp++ = 'q';
-               }
              else
-               {
-                 *obufp++ = 'w';
-                 *obufp++ = 'd';
-               }
+                 *obufp++ = 'l';
            }
          else
-           {
-             if (rex & REX_MODE64)
-               *obufp++ = 'q';
-             else if (sizeflag & DFLAG)
-               *obufp++ = 'l';
-             else
-               *obufp++ = 'w';
-           }
+           *obufp++ = 'w';
+         if (intel_syntax && !p[1]
+             && ((rex & REX_MODE64) || (sizeflag & DFLAG)))
+           *obufp++ = 'e';
          if (!(rex & REX_MODE64))
            used_prefixes |= (prefixes & PREFIX_DATA);
          break;
@@ -3182,31 +4022,19 @@ putop (const char *template, int sizeflag)
          /* implicit operand size 'l' for i386 or 'q' for x86-64 */
        case 'W':
          /* operand size flag for cwtl, cbtw */
-         USED_REX (0);
-         if (rex)
-           *obufp++ = 'l';
+         USED_REX (REX_MODE64);
+         if (rex & REX_MODE64)
+           {
+             if (intel_syntax)
+               *obufp++ = 'd';
+             else
+               *obufp++ = 'l';
+           }
          else if (sizeflag & DFLAG)
            *obufp++ = 'w';
          else
            *obufp++ = 'b';
-         if (intel_syntax)
-           {
-             if (rex)
-               {
-                 *obufp++ = 'q';
-                 *obufp++ = 'e';
-               }
-             if (sizeflag & DFLAG)
-               {
-                 *obufp++ = 'd';
-                 *obufp++ = 'e';
-               }
-             else
-               {
-                 *obufp++ = 'w';
-               }
-           }
-         if (!rex)
+         if (!(rex & REX_MODE64))
            used_prefixes |= (prefixes & PREFIX_DATA);
          break;
        }
@@ -3354,6 +4182,13 @@ intel_operand_size (int bytemode, int sizeflag)
        oappend ("WORD PTR ");
       used_prefixes |= (prefixes & PREFIX_DATA);
       break;
+    case z_mode:
+      if ((rex & REX_MODE64) || (sizeflag & DFLAG))
+       *obufp++ = 'D';
+      oappend ("WORD PTR ");
+      if (!(rex & REX_MODE64))
+       used_prefixes |= (prefixes & PREFIX_DATA);
+      break;
     case d_mode:
       oappend ("DWORD PTR ");
       break;
@@ -3379,6 +4214,9 @@ intel_operand_size (int bytemode, int sizeflag)
     case x_mode:
       oappend ("XMMWORD PTR ");
       break;
+    case o_mode:
+      oappend ("OWORD PTR ");
+      break;
     default:
       break;
     }
@@ -3804,12 +4642,6 @@ OP_REG (int code, int sizeflag)
 
   switch (code)
     {
-    case indir_dx_reg:
-      if (intel_syntax)
-       s = "[dx]";
-      else
-       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 + add];
@@ -3862,7 +4694,7 @@ OP_IMREG (int code, int sizeflag)
     {
     case indir_dx_reg:
       if (intel_syntax)
-       s = "[dx]";
+       s = "dx";
       else
        s = "(%dx)";
       break;
@@ -3893,6 +4725,14 @@ OP_IMREG (int code, int sizeflag)
        s = names16[code - eAX_reg];
       used_prefixes |= (prefixes & PREFIX_DATA);
       break;
+    case z_mode_ax_reg:
+      if ((rex & REX_MODE64) || (sizeflag & DFLAG))
+       s = *names32;
+      else
+       s = *names16;
+      if (!(rex & REX_MODE64))
+       used_prefixes |= (prefixes & PREFIX_DATA);
+      break;
     default:
       s = INTERNAL_DISASSEMBLER_ERROR;
       break;
@@ -4061,6 +4901,7 @@ OP_J (int bytemode, int sizeflag)
 {
   bfd_vma disp;
   bfd_vma mask = -1;
+  bfd_vma segment = 0;
 
   switch (bytemode)
     {
@@ -4076,26 +4917,36 @@ OP_J (int bytemode, int sizeflag)
       else
        {
          disp = get16 ();
-         /* For some reason, a data16 prefix on a jump instruction
-            means that the pc is masked to 16 bits after the
-            displacement is added!  */
+         if ((disp & 0x8000) != 0)
+           disp -= 0x10000;
+         /* In 16bit mode, address is wrapped around at 64k within
+            the same segment.  Otherwise, a data16 prefix on a jump
+            instruction means that the pc is masked to 16 bits after
+            the displacement is added!  */
          mask = 0xffff;
+         if ((prefixes & PREFIX_DATA) == 0)
+           segment = ((start_pc + codep - start_codep)
+                      & ~((bfd_vma) 0xffff));
        }
+      used_prefixes |= (prefixes & PREFIX_DATA);
       break;
     default:
       oappend (INTERNAL_DISASSEMBLER_ERROR);
       return;
     }
-  disp = (start_pc + codep - start_codep + disp) & mask;
+  disp = ((start_pc + codep - start_codep + disp) & mask) | segment;
   set_op (disp, 0);
   print_operand_value (scratchbuf, 1, disp);
   oappend (scratchbuf);
 }
 
 static void
-OP_SEG (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
+OP_SEG (int bytemode, int sizeflag)
 {
-  oappend (names_seg[reg]);
+  if (bytemode == w_mode)
+    oappend (names_seg[reg]);
+  else
+    OP_E (mod == 3 ? bytemode : w_mode, sizeflag);
 }
 
 static void
@@ -4153,7 +5004,8 @@ OP_OFF64 (int bytemode, int sizeflag)
 {
   bfd_vma off;
 
-  if (address_mode != mode_64bit)
+  if (address_mode != mode_64bit
+      || (prefixes & PREFIX_ADDR))
     {
       OP_OFF (bytemode, sizeflag);
       return;
@@ -4205,7 +5057,22 @@ static void
 OP_ESreg (int code, int sizeflag)
 {
   if (intel_syntax)
-    intel_operand_size (codep[-1] & 1 ? v_mode : b_mode, sizeflag);
+    {
+      switch (codep[-1])
+       {
+       case 0x6d:      /* insw/insl */
+         intel_operand_size (z_mode, sizeflag);
+         break;
+       case 0xa5:      /* movsw/movsl/movsq */
+       case 0xa7:      /* cmpsw/cmpsl/cmpsq */
+       case 0xab:      /* stosw/stosl */
+       case 0xaf:      /* scasw/scasl */
+         intel_operand_size (v_mode, sizeflag);
+         break;
+       default:
+         intel_operand_size (b_mode, sizeflag);
+       }
+    }
   oappend ("%es:" + intel_syntax);
   ptr_reg (code, sizeflag);
 }
@@ -4214,10 +5081,21 @@ static void
 OP_DSreg (int code, int sizeflag)
 {
   if (intel_syntax)
-    intel_operand_size (codep[-1] != 0xd7 && (codep[-1] & 1)
-                       ? v_mode
-                       : b_mode,
-                       sizeflag);
+    {
+      switch (codep[-1])
+       {
+       case 0x6f:      /* outsw/outsl */
+         intel_operand_size (z_mode, sizeflag);
+         break;
+       case 0xa5:      /* movsw/movsl/movsq */
+       case 0xa7:      /* cmpsw/cmpsl/cmpsq */
+       case 0xad:      /* lodsw/lodsl/lodsq */
+         intel_operand_size (v_mode, sizeflag);
+         break;
+       default:
+         intel_operand_size (b_mode, sizeflag);
+       }
+    }
   if ((prefixes
        & (PREFIX_CS
          | PREFIX_DS
@@ -4338,6 +5216,41 @@ OP_EM (int bytemode, int sizeflag)
   oappend (scratchbuf + intel_syntax);
 }
 
+/* cvt* are the only instructions in sse2 which have 
+   both SSE and MMX operands and also have 0x66 prefix 
+   in their opcode. 0x66 was originally used to differentiate 
+   between SSE and MMX instruction(operands). So we have to handle the 
+   cvt* separately using OP_EMC and OP_MXC */
+static void
+OP_EMC (int bytemode, int sizeflag)
+{
+  if (mod != 3)
+    {
+      if (intel_syntax && bytemode == v_mode)
+       {
+         bytemode = (prefixes & PREFIX_DATA) ? x_mode : q_mode;
+         used_prefixes |= (prefixes & PREFIX_DATA);
+       }
+      OP_E (bytemode, sizeflag);
+      return;
+    }
+  
+  /* Skip mod/rm byte.  */
+  MODRM_CHECK;
+  codep++;
+  used_prefixes |= (prefixes & PREFIX_DATA);
+  sprintf (scratchbuf, "%%mm%d", rm);
+  oappend (scratchbuf + intel_syntax);
+}
+
+static void
+OP_MXC (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
+{
+  used_prefixes |= (prefixes & PREFIX_DATA);
+  sprintf (scratchbuf, "%%mm%d", reg);
+  oappend (scratchbuf + intel_syntax);
+}
+
 static void
 OP_EX (int bytemode, int sizeflag)
 {
@@ -4391,7 +5304,8 @@ static void
 OP_M (int bytemode, int sizeflag)
 {
   if (mod == 3)
-    BadOp ();  /* bad lea,lds,les,lfs,lgs,lss modrm */
+    /* bad bound,lea,lds,les,lfs,lgs,lss,cmpxchg8b,vmptrst modrm */
+    BadOp ();
   else
     OP_E (bytemode, sizeflag);
 }
@@ -4632,9 +5546,9 @@ PNI_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
          && (prefixes & PREFIX_ADDR)
          && olen >= (4 + 7)
          && *(p - 1) == ' '
-         && strncmp (p - 7, "addr", 4) == 0
-         && (strncmp (p - 3, "16", 2) == 0
-             || strncmp (p - 3, "32", 2) == 0))
+         && CONST_STRNEQ (p - 7, "addr")
+         && (CONST_STRNEQ (p - 3, "16")
+             || CONST_STRNEQ (p - 3, "32")))
        p -= 7;
 
       if (rm)
@@ -4776,55 +5690,6 @@ BadOp (void)
   oappend ("(bad)");
 }
 
-static void
-SEG_Fixup (int extrachar, int sizeflag)
-{
-  if (mod == 3)
-    {
-      /* We need to add a proper suffix with
-
-               movw %ds,%ax
-               movl %ds,%eax
-               movq %ds,%rax
-               movw %ax,%ds
-               movl %eax,%ds
-               movq %rax,%ds
-       */
-      const char *suffix;
-
-      if (prefixes & PREFIX_DATA)
-       suffix = "w";
-      else
-       {
-         USED_REX (REX_MODE64);
-         if (rex & REX_MODE64)
-           suffix = "q";
-         else
-           suffix = "l";
-       }
-      strcat (obuf, suffix);
-    }
-  else
-    {
-      /* We need to fix the suffix for
-
-               movw %ds,(%eax)
-               movw %ds,(%rax)
-               movw (%eax),%ds
-               movw (%rax),%ds
-
-        Override "mov[l|q]".  */
-      char *p = obuf + strlen (obuf) - 1;
-
-      /* We might not have a suffix.  */
-      if (*p == 'v')
-       ++p;
-      *p = 'w';
-    }
-
-  OP_E (extrachar, sizeflag);
-}
-
 static void
 VMX_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
 {
@@ -4944,3 +5809,17 @@ REP_Fixup (int bytemode, int sizeflag)
       break;
     }
 }
+
+static void
+CMPXCHG8B_Fixup (int bytemode, int sizeflag)
+{
+  USED_REX (REX_MODE64);
+  if (rex & REX_MODE64)
+    {
+      /* Change cmpxchg8b to cmpxchg16b.  */
+      char *p = obuf + strlen (obuf) - 2;
+      strcpy (p, "16b");
+      bytemode = o_mode;
+    }
+  OP_M (bytemode, sizeflag);
+}
This page took 0.048572 seconds and 4 git commands to generate.