Thu Nov 12 19:21:57 1998 Dave Brolley <brolley@cygnus.com>
[deliverable/binutils-gdb.git] / opcodes / i386-dis.c
index fa45eadfcebb7d40280dc67a997ba92152aa6a8a..eea4c00cf51c4b95b4419e5cd8253caf6e207dc8 100644 (file)
@@ -1,5 +1,5 @@
 /* Print i386 instructions for GDB, the GNU debugger.
-   Copyright (C) 1988, 89, 91, 93, 94, 95, 96, 1997
+   Copyright (C) 1988, 89, 91, 93, 94, 95, 96, 97, 1998
    Free Software Foundation, Inc.
 
 This file is part of GDB.
@@ -35,11 +35,19 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 #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
@@ -132,10 +140,11 @@ fetch_data (info, addr)
 #define Av OP_DIR, v_mode
 #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
@@ -144,37 +153,52 @@ fetch_data (info, addr)
 #define fs OP_REG, fs_reg
 #define gs OP_REG, gs_reg
 
-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));
+#define MX OP_MMX, 0
+#define EM OP_EM, v_mode
+#define MS OP_MS, b_mode
+
+/* bits in sizeflag */
+#if 0 /* leave undefined until someone adds the extra flag to objdump */
+#define SUFFIX_ALWAYS 4
+#endif
+#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_rm PARAMS ((int, int));
+static void OP_ST PARAMS ((int, int));
+static void OP_STi  PARAMS ((int, int));
 #if 0
-static int OP_ONE PARAMS ((int, int, int));
+static void OP_ONE PARAMS ((int, int));
 #endif
-
-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));
+static void OP_MMX PARAMS ((int, int));
+static void OP_EM PARAMS ((int, int));
+static void OP_MS PARAMS ((int, int));
+
+static void append_seg PARAMS ((void));
+static void set_op PARAMS ((unsigned int op));
+static void putop PARAMS ((char *template, int sizeflag));
+static void dofloat PARAMS ((int sizeflag));
 static int get16 PARAMS ((void));
 static int get32 PARAMS ((void));
 static void ckprefix PARAMS ((void));
+static void ptr_reg PARAMS ((int, int));
 
 #define b_mode 1
 #define v_mode 2
@@ -235,6 +259,9 @@ static void ckprefix PARAMS ((void));
 #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 FLOATCODE 50
 #define FLOAT NULL, NULL, FLOATCODE
@@ -249,76 +276,90 @@ struct dis386 {
   int bytemode3;
 };
 
+/* 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'
+   'S' => print 'w' or 'l' if suffix_always is true
+   'W' => print 'b' or 'w'
+*/
+
 static struct dis386 dis386[] = {
   /* 00 */
-  { "addb",    Eb, Gb },
+  { "addB",    Eb, Gb },
   { "addS",    Ev, Gv },
-  { "addb",    Gb, Eb },
+  { "addB",    Gb, Eb },
   { "addS",    Gv, Ev },
-  { "addb",    AL, Ib },
+  { "addB",    AL, Ib },
   { "addS",    eAX, Iv },
-  { "pushl",   es },
-  { "popl",    es },
+  { "pushP",   es },
+  { "popP",    es },
   /* 08 */
-  { "orb",     Eb, Gb },
+  { "orB",     Eb, Gb },
   { "orS",     Ev, Gv },
-  { "orb",     Gb, Eb },
+  { "orB",     Gb, Eb },
   { "orS",     Gv, Ev },
-  { "orb",     AL, Ib },
+  { "orB",     AL, Ib },
   { "orS",     eAX, Iv },
-  { "pushl",   cs },
+  { "pushP",   cs },
   { "(bad)" }, /* 0x0f extended opcode escape */
   /* 10 */
-  { "adcb",    Eb, Gb },
+  { "adcB",    Eb, Gb },
   { "adcS",    Ev, Gv },
-  { "adcb",    Gb, Eb },
+  { "adcB",    Gb, Eb },
   { "adcS",    Gv, Ev },
-  { "adcb",    AL, Ib },
+  { "adcB",    AL, Ib },
   { "adcS",    eAX, Iv },
-  { "pushl",   ss },
-  { "popl",    ss },
+  { "pushP",   ss },
+  { "popP",    ss },
   /* 18 */
-  { "sbbb",    Eb, Gb },
+  { "sbbB",    Eb, Gb },
   { "sbbS",    Ev, Gv },
-  { "sbbb",    Gb, Eb },
+  { "sbbB",    Gb, Eb },
   { "sbbS",    Gv, Ev },
-  { "sbbb",    AL, Ib },
+  { "sbbB",    AL, Ib },
   { "sbbS",    eAX, Iv },
-  { "pushl",   ds },
-  { "popl",    ds },
+  { "pushP",   ds },
+  { "popP",    ds },
   /* 20 */
-  { "andb",    Eb, Gb },
+  { "andB",    Eb, Gb },
   { "andS",    Ev, Gv },
-  { "andb",    Gb, Eb },
+  { "andB",    Gb, Eb },
   { "andS",    Gv, Ev },
-  { "andb",    AL, Ib },
+  { "andB",    AL, Ib },
   { "andS",    eAX, Iv },
   { "(bad)" },                 /* SEG ES prefix */
   { "daa" },
   /* 28 */
-  { "subb",    Eb, Gb },
+  { "subB",    Eb, Gb },
   { "subS",    Ev, Gv },
-  { "subb",    Gb, Eb },
+  { "subB",    Gb, Eb },
   { "subS",    Gv, Ev },
-  { "subb",    AL, Ib },
+  { "subB",    AL, Ib },
   { "subS",    eAX, Iv },
   { "(bad)" },                 /* SEG CS prefix */
   { "das" },
   /* 30 */
-  { "xorb",    Eb, Gb },
+  { "xorB",    Eb, Gb },
   { "xorS",    Ev, Gv },
-  { "xorb",    Gb, Eb },
+  { "xorB",    Gb, Eb },
   { "xorS",    Gv, Ev },
-  { "xorb",    AL, Ib },
+  { "xorB",    AL, Ib },
   { "xorS",    eAX, Iv },
   { "(bad)" },                 /* SEG SS prefix */
   { "aaa" },
   /* 38 */
-  { "cmpb",    Eb, Gb },
+  { "cmpB",    Eb, Gb },
   { "cmpS",    Ev, Gv },
-  { "cmpb",    Gb, Eb },
+  { "cmpB",    Gb, Eb },
   { "cmpS",    Gv, Ev },
-  { "cmpb",    AL, Ib },
+  { "cmpB",    AL, Ib },
   { "cmpS",    eAX, Iv },
   { "(bad)" },                 /* SEG DS prefix */
   { "aas" },
@@ -359,8 +400,8 @@ static struct dis386 dis386[] = {
   { "popS",    eSI },
   { "popS",    eDI },
   /* 60 */
-  { "pusha" },
-  { "popa" },
+  { "pushaP" },
+  { "popaP" },
   { "boundS",  Gv, Ma },
   { "arpl",    Ew, Gw },
   { "(bad)" },                 /* seg fs */
@@ -368,14 +409,14 @@ static struct dis386 dis386[] = {
   { "(bad)" },                 /* op size prefix */
   { "(bad)" },                 /* adr size prefix */
   /* 68 */
-  { "pushS",   Iv },           /* 386 book wrong */
+  { "pushP",   Iv },           /* 386 book wrong */
   { "imulS",   Gv, Ev, Iv },
-  { "pushl",   sIb },          /* push of byte really pushes 4 bytes */
-  { "imulS",   Gv, Ev, Ib },
+  { "pushP",   sIb },          /* push of byte really pushes 2 or 4 bytes */
+  { "imulS",   Gv, Ev, sIb },
   { "insb",    Yb, indirDX },
-  { "insS",    Yv, indirDX },
+  { "insR",    Yv, indirDX },
   { "outsb",   indirDX, Xb },
-  { "outsS",   indirDX, Xv },
+  { "outsR",   indirDX, Xv },
   /* 70 */
   { "jo",      Jb },
   { "jno",     Jb },
@@ -391,7 +432,7 @@ static struct dis386 dis386[] = {
   { "jp",      Jb },
   { "jnp",     Jb },
   { "jl",      Jb },
-  { "jnl",     Jb },
+  { "jge",     Jb },
   { "jle",     Jb },
   { "jg",      Jb },
   /* 80 */
@@ -399,19 +440,19 @@ static struct dis386 dis386[] = {
   { GRP1S },
   { "(bad)" },
   { GRP1Ss },
-  { "testb",   Eb, Gb },
+  { "testB",   Eb, Gb },
   { "testS",   Ev, Gv },
-  { "xchgb",   Eb, Gb },
+  { "xchgB",   Eb, Gb },
   { "xchgS",   Ev, Gv },
   /* 88 */
-  { "movb",    Eb, Gb },
+  { "movB",    Eb, Gb },
   { "movS",    Ev, Gv },
-  { "movb",    Gb, Eb },
+  { "movB",    Gb, Eb },
   { "movS",    Gv, Ev },
-  { "movw",    Ew, Sw },
+  { "movQ",    Ev, Sw },
   { "leaS",    Gv, M },
-  { "movw",    Sw, Ew },
-  { "popS",    Ev },
+  { "movQ",    Sw, Ev },
+  { "popQ",    Ev },
   /* 90 */
   { "nop" },
   { "xchgS",   eCX, eAX },
@@ -422,41 +463,41 @@ static struct dis386 dis386[] = {
   { "xchgS",   eSI, eAX },
   { "xchgS",   eDI, eAX },
   /* 98 */
-  { "cwtl" },
-  { "cltd" },
-  { "lcall",   Ap },
+  { "cWtR" },
+  { "cRtd" },
+  { "lcallP",  Ap },
   { "(bad)" },         /* fwait */
-  { "pushf" },
-  { "popf" },
+  { "pushfP" },
+  { "popfP" },
   { "sahf" },
   { "lahf" },
   /* a0 */
-  { "movb",    AL, Ob },
+  { "movB",    AL, Ob },
   { "movS",    eAX, Ov },
-  { "movb",    Ob, AL },
+  { "movB",    Ob, AL },
   { "movS",    Ov, eAX },
   { "movsb",   Yb, Xb },
-  { "movsS",   Yv, Xv },
-  { "cmpsb",   Yb, Xb },
-  { "cmpsS",   Yv, Xv },
+  { "movsR",   Yv, Xv },
+  { "cmpsb",   Xb, Yb },
+  { "cmpsR",   Xv, Yv },
   /* a8 */
-  { "testb",   AL, Ib },
+  { "testB",   AL, Ib },
   { "testS",   eAX, Iv },
-  { "stosb",   Yb, AL },
+  { "stosB",   Yb, AL },
   { "stosS",   Yv, eAX },
-  { "lodsb",   AL, Xb },
+  { "lodsB",   AL, Xb },
   { "lodsS",   eAX, Xv },
-  { "scasb",   AL, Yb },
+  { "scasB",   AL, Yb },
   { "scasS",   eAX, Yv },
   /* 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 },
+  { "movB",    CL, Ib },
+  { "movB",    DL, Ib },
+  { "movB",    BL, Ib },
+  { "movB",    AH, Ib },
+  { "movB",    CH, Ib },
+  { "movB",    DH, Ib },
+  { "movB",    BH, Ib },
   /* b8 */
   { "movS",    eAX, Iv },
   { "movS",    eCX, Iv },
@@ -469,30 +510,30 @@ static struct dis386 dis386[] = {
   /* c0 */
   { GRP2b },
   { GRP2S },
-  { "ret",     Iw },
-  { "ret" },
+  { "retP",    Iw },
+  { "retP" },
   { "lesS",    Gv, Mp },
   { "ldsS",    Gv, Mp },
-  { "movb",    Eb, Ib },
-  { "movS",    Ev, Iv },
+  { "movA",    Eb, Ib },
+  { "movQ",    Ev, Iv },
   /* c8 */
-  { "enter",   Iw, Ib },
-  { "leave" },
-  { "lret",    Iw },
-  { "lret" },
+  { "enterP",  Iw, Ib },
+  { "leaveP" },
+  { "lretP",   Iw },
+  { "lretP" },
   { "int3" },
   { "int",     Ib },
   { "into" },
-  { "iret" },
+  { "iretP" },
   /* d0 */
   { GRP2b_one },
   { GRP2S_one },
   { GRP2b_cl },
   { GRP2S_cl },
-  { "aam",     Ib },
-  { "aad",     Ib },
+  { "aam",     sIb },
+  { "aad",     sIb },
   { "(bad)" },
-  { "xlat" },
+  { "xlat",    DSBX },
   /* d8 */
   { FLOAT },
   { FLOAT },
@@ -506,19 +547,19 @@ static struct dis386 dis386[] = {
   { "loopne",  Jb },
   { "loope",   Jb },
   { "loop",    Jb },
-  { "jCcxz",   Jb },
-  { "inb",     AL, Ib },
+  { "jEcxz",   Jb },
+  { "inB",     AL, Ib },
   { "inS",     eAX, Ib },
-  { "outb",    Ib, AL },
+  { "outB",    Ib, AL },
   { "outS",    Ib, eAX },
   /* e8 */
-  { "call",    Av },
-  { "jmp",     Jv },
-  { "ljmp",    Ap },
+  { "callP",   Av },
+  { "jmpP",    Jv },
+  { "ljmpP",   Ap },
   { "jmp",     Jb },
-  { "inb",     AL, indirDX },
+  { "inB",     AL, indirDX },
   { "inS",     eAX, indirDX },
-  { "outb",    indirDX, AL },
+  { "outB",    indirDX, AL },
   { "outS",    indirDX, eAX },
   /* f0 */
   { "(bad)" },                 /* lock prefix */
@@ -553,7 +594,8 @@ static struct dis386 dis386_twobyte[] = {
   /* 08 */
   { "invd" },
   { "wbinvd" },
-  { "(bad)" },  { "ud2a" },  
+  { "(bad)" },
+  { "ud2a" },  
   { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
   /* 10 */
   { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
@@ -563,13 +605,13 @@ static struct dis386 dis386_twobyte[] = {
   { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
   /* 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 },
+  { "movL", Rd, Cd },
+  { "movL", Rd, Dd },
+  { "movL", Cd, Rd },
+  { "movL", Dd, Rd },  
+  { "movL", Rd, Td },
   { "(bad)" },
-  { "movl", Td, Rd },
+  { "movL", Td, Rd },
   { "(bad)" },  
   /* 28 */
   { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
@@ -593,17 +635,36 @@ static struct dis386 dis386_twobyte[] = {
   { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
   { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
   /* 60 */
-  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
-  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "punpcklbw", MX, EM },
+  { "punpcklwd", MX, EM },
+  { "punpckldq", MX, EM },
+  { "packsswb", MX, EM },
+  { "pcmpgtb", MX, EM },
+  { "pcmpgtw", MX, EM },
+  { "pcmpgtd", MX, EM },
+  { "packuswb", MX, EM },
   /* 68 */
-  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
-  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "punpckhbw", MX, EM },
+  { "punpckhwd", MX, EM },
+  { "punpckhdq", MX, EM },
+  { "packssdw", MX, EM },
+  { "(bad)" },  { "(bad)" },
+  { "movd", MX, Ev },
+  { "movq", MX, EM },
   /* 70 */
-  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
-  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "(bad)" },
+  { GRP10 },
+  { GRP11 },
+  { GRP12 },
+  { "pcmpeqb", MX, EM },
+  { "pcmpeqw", MX, EM },
+  { "pcmpeqd", MX, EM },
+  { "emms" },
   /* 78 */
   { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
-  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "(bad)" },  { "(bad)" },
+  { "movd", Ev, MX },
+  { "movq", EM, MX },
   /* 80 */
   { "jo", Jv },
   { "jno", Jv },
@@ -641,8 +702,8 @@ static struct dis386 dis386_twobyte[] = {
   { "setle", Eb },
   { "setg", Eb },  
   /* a0 */
-  { "pushl", fs },
-  { "popl", fs },
+  { "pushP", fs },
+  { "popP", fs },
   { "cpuid" },
   { "btS", Ev, Gv },  
   { "shldS", Ev, Gv, Ib },
@@ -650,8 +711,8 @@ static struct dis386 dis386_twobyte[] = {
   { "(bad)" },
   { "(bad)" },  
   /* a8 */
-  { "pushl", gs },
-  { "popl", gs },
+  { "pushP", gs },
+  { "popP", gs },
   { "rsm" },
   { "btsS", Ev, Gv },  
   { "shrdS", Ev, Gv, Ib },
@@ -659,25 +720,25 @@ static struct dis386 dis386_twobyte[] = {
   { "(bad)" },
   { "imulS", Gv, Ev },  
   /* b0 */
-  { "cmpxchgb", Eb, Gb },
+  { "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 },  
+  { "movzbR", Gv, Eb },
+  { "movzwR", Gv, Ew }, /* yes, there really is movzww ! */
   /* b8 */
-  { "ud2b" },
   { "(bad)" },
+  { "ud2b" },
   { GRP8 },
   { "btcS", Ev, Gv },  
   { "bsfS", Gv, Ev },
   { "bsrS", Gv, Ev },
-  { "movsbS", Gv, Eb },
-  { "movswS", Gv, Ew },  
+  { "movsbR", Gv, Eb },
+  { "movswR", Gv, Ew }, /* yes, there really is movsww ! */
   /* c0 */
-  { "xaddb", Eb, Gb },
+  { "xaddB", Eb, Gb },
   { "xaddS", Ev, Gv },
   { "(bad)" },
   { "(bad)" },  
@@ -686,7 +747,7 @@ static struct dis386 dis386_twobyte[] = {
   { "(bad)" },
   { GRP9 },  
   /* c8 */
-  { "bswap", eAX },
+  { "bswap", eAX },    /* bswap doesn't support 16 bit regs */
   { "bswap", eCX },
   { "bswap", eDX },
   { "bswap", eBX },
@@ -695,23 +756,56 @@ static struct dis386 dis386_twobyte[] = {
   { "bswap", eSI },
   { "bswap", eDI },
   /* d0 */
-  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
-  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "(bad)" },
+  { "psrlw", MX, EM },
+  { "psrld", MX, EM },
+  { "psrlq", MX, EM },
+  { "(bad)" },
+  { "pmullw", MX, EM },
+  { "(bad)" },  { "(bad)" },  
   /* d8 */
-  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
-  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "psubusb", MX, EM },
+  { "psubusw", MX, EM },
+  { "(bad)" },
+  { "pand", MX, EM },
+  { "paddusb", MX, EM },
+  { "paddusw", MX, EM },
+  { "(bad)" },
+  { "pandn", MX, EM },
   /* e0 */
-  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
-  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "(bad)" },
+  { "psraw", MX, EM },
+  { "psrad", MX, EM },
+  { "(bad)" },
+  { "(bad)" },
+  { "pmulhw", MX, EM },
+  { "(bad)" },  { "(bad)" },  
   /* e8 */
-  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
-  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "psubsb", MX, EM },
+  { "psubsw", MX, EM },
+  { "(bad)" },
+  { "por", MX, EM },
+  { "paddsb", MX, EM },
+  { "paddsw", MX, EM },
+  { "(bad)" },
+  { "pxor", MX, EM },
   /* f0 */
-  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
-  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "(bad)" },
+  { "psllw", MX, EM },
+  { "pslld", MX, EM },
+  { "psllq", MX, EM },
+  { "(bad)" },
+  { "pmaddwd", MX, EM },
+  { "(bad)" },  { "(bad)" },  
   /* f8 */
-  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
-  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "psubb", MX, EM },
+  { "psubw", MX, EM },
+  { "psubd", MX, EM },
+  { "(bad)" },  
+  { "paddb", MX, EM },
+  { "paddw", MX, EM },
+  { "paddd", MX, EM },
+  { "(bad)" }
 };
 
 static const unsigned char onebyte_has_modrm[256] = {
@@ -734,22 +828,22 @@ static const unsigned char onebyte_has_modrm[256] = {
 };
 
 static const unsigned char twobyte_has_modrm[256] = {
-  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,
-  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,
-  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,
-  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,1,1,1,1,1,0,0,0,1,1,1,1,1,
-  1,1,1,1,1,1,1,1,0,0,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,0,0,0,0,0,0,0,0
+  /* 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 */
+  /* 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 */
+  /* 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 */
+  /* 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 */
 };
 
 static char obuf[100];
@@ -782,120 +876,120 @@ static char *index16[] = {
 static 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 },
+    { "orA",   Eb, Ib },
+    { "adcA",  Eb, Ib },
+    { "sbbA",  Eb, Ib },
+    { "andA",  Eb, Ib },
+    { "subA",  Eb, Ib },
+    { "xorA",  Eb, Ib },
+    { "cmpA",  Eb, Ib }
   },
   /* 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 },
+    { "orQ",   Ev, Iv },
+    { "adcQ",  Ev, Iv },
+    { "sbbQ",  Ev, Iv },
+    { "andQ",  Ev, Iv },
+    { "subQ",  Ev, Iv },
+    { "xorQ",  Ev, Iv },
+    { "cmpQ",  Ev, Iv }
   },
   /* 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 },
+    { "orQ",   Ev, sIb },
+    { "adcQ",  Ev, sIb },
+    { "sbbQ",  Ev, sIb },
+    { "andQ",  Ev, sIb },
+    { "subQ",  Ev, sIb },
+    { "xorQ",  Ev, sIb },
+    { "cmpQ",  Ev, sIb }
   },
   /* GRP2b */
   {
-    { "rolb",  Eb, Ib },
-    { "rorb",  Eb, Ib },
-    { "rclb",  Eb, Ib },
-    { "rcrb",  Eb, Ib },
-    { "shlb",  Eb, Ib },
-    { "shrb",  Eb, Ib },
+    { "rolA",  Eb, Ib },
+    { "rorA",  Eb, Ib },
+    { "rclA",  Eb, Ib },
+    { "rcrA",  Eb, Ib },
+    { "shlA",  Eb, Ib },
+    { "shrA",  Eb, Ib },
     { "(bad)" },
-    { "sarb",  Eb, Ib },
+    { "sarA",  Eb, Ib },
   },
   /* GRP2S */
   {
-    { "rolS",  Ev, Ib },
-    { "rorS",  Ev, Ib },
-    { "rclS",  Ev, Ib },
-    { "rcrS",  Ev, Ib },
-    { "shlS",  Ev, Ib },
-    { "shrS",  Ev, Ib },
+    { "rolQ",  Ev, Ib },
+    { "rorQ",  Ev, Ib },
+    { "rclQ",  Ev, Ib },
+    { "rcrQ",  Ev, Ib },
+    { "shlQ",  Ev, Ib },
+    { "shrQ",  Ev, Ib },
     { "(bad)" },
-    { "sarS",  Ev, Ib },
+    { "sarQ",  Ev, Ib },
   },
   /* GRP2b_one */
   {
-    { "rolb",  Eb },
-    { "rorb",  Eb },
-    { "rclb",  Eb },
-    { "rcrb",  Eb },
-    { "shlb",  Eb },
-    { "shrb",  Eb },
+    { "rolA",  Eb },
+    { "rorA",  Eb },
+    { "rclA",  Eb },
+    { "rcrA",  Eb },
+    { "shlA",  Eb },
+    { "shrA",  Eb },
     { "(bad)" },
-    { "sarb",  Eb },
+    { "sarA",  Eb },
   },
   /* GRP2S_one */
   {
-    { "rolS",  Ev },
-    { "rorS",  Ev },
-    { "rclS",  Ev },
-    { "rcrS",  Ev },
-    { "shlS",  Ev },
-    { "shrS",  Ev },
+    { "rolQ",  Ev },
+    { "rorQ",  Ev },
+    { "rclQ",  Ev },
+    { "rcrQ",  Ev },
+    { "shlQ",  Ev },
+    { "shrQ",  Ev },
     { "(bad)" },
-    { "sarS",  Ev },
+    { "sarQ",  Ev },
   },
   /* GRP2b_cl */
   {
-    { "rolb",  Eb, CL },
-    { "rorb",  Eb, CL },
-    { "rclb",  Eb, CL },
-    { "rcrb",  Eb, CL },
-    { "shlb",  Eb, CL },
-    { "shrb",  Eb, CL },
+    { "rolA",  Eb, CL },
+    { "rorA",  Eb, CL },
+    { "rclA",  Eb, CL },
+    { "rcrA",  Eb, CL },
+    { "shlA",  Eb, CL },
+    { "shrA",  Eb, CL },
     { "(bad)" },
-    { "sarb",  Eb, CL },
+    { "sarA",  Eb, CL },
   },
   /* GRP2S_cl */
   {
-    { "rolS",  Ev, CL },
-    { "rorS",  Ev, CL },
-    { "rclS",  Ev, CL },
-    { "rcrS",  Ev, CL },
-    { "shlS",  Ev, CL },
-    { "shrS",  Ev, CL },
+    { "rolQ",  Ev, CL },
+    { "rorQ",  Ev, CL },
+    { "rclQ",  Ev, CL },
+    { "rcrQ",  Ev, CL },
+    { "shlQ",  Ev, CL },
+    { "shrQ",  Ev, CL },
     { "(bad)" },
-    { "sarS",  Ev, CL }
+    { "sarQ",  Ev, CL }
   },
   /* GRP3b */
   {
-    { "testb", Eb, Ib },
+    { "testA", Eb, Ib },
     { "(bad)", Eb },
-    { "notb",  Eb },
-    { "negb",  Eb },
-    { "mulb",  AL, Eb },
-    { "imulb", AL, Eb },
-    { "divb",  AL, Eb },
-    { "idivb", AL, Eb }
+    { "notA",  Eb },
+    { "negA",  Eb },
+    { "mulB",  AL, Eb },
+    { "imulB", AL, Eb },
+    { "divB",  AL, Eb },
+    { "idivB", AL, Eb }
   },
   /* GRP3S */
   {
-    { "testS", Ev, Iv },
+    { "testQ", Ev, Iv },
     { "(bad)" },
-    { "notS",  Ev },
-    { "negS",  Ev },
+    { "notQ",  Ev },
+    { "negQ",  Ev },
     { "mulS",  eAX, Ev },
     { "imulS", eAX, Ev },
     { "divS",  eAX, Ev },
@@ -903,8 +997,8 @@ static struct dis386 grps[][8] = {
   },
   /* GRP4 */
   {
-    { "incb", Eb },
-    { "decb", Eb },
+    { "incA", Eb },
+    { "decA", Eb },
     { "(bad)" },
     { "(bad)" },
     { "(bad)" },
@@ -914,13 +1008,13 @@ static struct dis386 grps[][8] = {
   },
   /* GRP5 */
   {
-    { "incS",  Ev },
-    { "decS",  Ev },
-    { "call",  indirEv },
-    { "lcall", indirEv },
-    { "jmp",   indirEv },
-    { "ljmp",  indirEv },
-    { "pushS", Ev },
+    { "incQ",  Ev },
+    { "decQ",  Ev },
+    { "callP", indirEv },
+    { "lcallP",        indirEv },
+    { "jmpP",  indirEv },
+    { "ljmpP", indirEv },
+    { "pushQ", Ev },
     { "(bad)" },
   },
   /* GRP6 */
@@ -951,10 +1045,10 @@ static struct dis386 grps[][8] = {
     { "(bad)" },
     { "(bad)" },
     { "(bad)" },
-    { "btS",   Ev, Ib },
-    { "btsS",  Ev, Ib },
-    { "btrS",  Ev, Ib },
-    { "btcS",  Ev, Ib },
+    { "btQ",   Ev, Ib },
+    { "btsQ",  Ev, Ib },
+    { "btrQ",  Ev, Ib },
+    { "btcQ",  Ev, Ib },
   },
   /* GRP9 */
   {
@@ -966,6 +1060,39 @@ static struct dis386 grps[][8] = {
     { "(bad)" },
     { "(bad)" },
     { "(bad)" },
+  },
+  /* GRP10 */
+  {
+    { "(bad)" },
+    { "(bad)" },
+    { "psrlw", MS, Ib },
+    { "(bad)" },
+    { "psraw", MS, Ib },
+    { "(bad)" },
+    { "psllw", MS, Ib },
+    { "(bad)" },
+  },
+  /* GRP11 */
+  {
+    { "(bad)" },
+    { "(bad)" },
+    { "psrld", MS, Ib },
+    { "(bad)" },
+    { "psrad", MS, Ib },
+    { "(bad)" },
+    { "pslld", MS, Ib },
+    { "(bad)" },
+  },
+  /* GRP12 */
+  {
+    { "(bad)" },
+    { "(bad)" },
+    { "psrlq", MS, Ib },
+    { "(bad)" },
+    { "(bad)" },
+    { "(bad)" },
+    { "psllq", MS, Ib },
+    { "(bad)" },
   }
 };
 
@@ -979,7 +1106,7 @@ static struct dis386 grps[][8] = {
 #define PREFIX_FS 0x80
 #define PREFIX_GS 0x100
 #define PREFIX_DATA 0x200
-#define PREFIX_ADR 0x400
+#define PREFIX_ADDR 0x400
 #define PREFIX_FWAIT 0x800
 
 static int prefixes;
@@ -1024,11 +1151,12 @@ ckprefix ()
          prefixes |= PREFIX_DATA;
          break;
        case 0x67:
-         prefixes |= PREFIX_ADR;
+         prefixes |= PREFIX_ADDR;
          break;
        case 0x9b:
          prefixes |= PREFIX_FWAIT;
-         break;
+         codep++;              /* fwait is really an instruction */
+         return;               /* so stop accumulating prefixes */
        default:
          return;
        }
@@ -1037,8 +1165,9 @@ ckprefix ()
 }
 
 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;
 
 \f
 /*
@@ -1050,29 +1179,32 @@ 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));
+int print_insn_x86 PARAMS ((bfd_vma pc, disassemble_info *info, int sizeflag));
+
 int
 print_insn_i386 (pc, info)
      bfd_vma pc;
      disassemble_info *info;
 {
+  int flags;
   if (info->mach == bfd_mach_i386_i386)
-    return print_insn_x86 (pc, info, 1, 1);
+    flags = AFLAG|DFLAG;
   else if (info->mach == bfd_mach_i386_i8086)
-    return print_insn_x86 (pc, info, 0, 0);
+    flags = 0;
   else
     abort ();
+  return print_insn_x86 (pc, info, flags);
 }
 
 int
-print_insn_x86 (pc, info, aflag, dflag)
+print_insn_x86 (pc, info, sizeflag)
      bfd_vma pc;
      disassemble_info *info;
+     int sizeflag;
 {
   struct dis386 *dp;
   int i;
-  int enter_instruction;
+  int two_source_ops;
   char *first, *second, *third;
   int needcomma;
   unsigned char need_modrm;
@@ -1106,13 +1238,19 @@ print_insn_x86 (pc, info, aflag, dflag)
   ckprefix ();
 
   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_FWAIT)
+      && ((*codep < 0xd8) || (*codep > 0xdf)))
+    {
+      /* fwait not followed by floating point instruction.  */
+      (*info->fprintf_func) (info->stream, "fwait");
+      /* There may be other prefixes.  Skip any before the fwait.  */
+      return codep - inbuf;
+    }
+  
   if (prefixes & PREFIX_REPZ)
     oappend ("repz ");
   if (prefixes & PREFIX_REPNZ)
@@ -1120,21 +1258,16 @@ print_insn_x86 (pc, info, aflag, dflag)
   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);
-    }
-  
   if (prefixes & PREFIX_DATA)
-    dflag ^= 1;
+    sizeflag ^= DFLAG;
   
-  if (prefixes & PREFIX_ADR)
+  if (prefixes & PREFIX_ADDR)
     {
-      aflag ^= 1;
-      oappend ("addr16 ");
+      sizeflag ^= AFLAG;
+      if (sizeflag & AFLAG)
+        oappend ("addr32 ");
+      else
+       oappend ("addr16 ");
     }
   
   if (*codep == 0x0f)
@@ -1160,29 +1293,29 @@ 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);
+      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);
     }
   
   obufp = obuf + strlen (obuf);
@@ -1191,11 +1324,9 @@ print_insn_x86 (pc, info, aflag, dflag)
   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 (two_source_ops)
     {
       first = op1out;
       second = op2out;
@@ -1214,7 +1345,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;
@@ -1224,7 +1355,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;
@@ -1234,11 +1365,11 @@ 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[] = {
@@ -1380,10 +1511,17 @@ static struct dis386 float_reg[][8] = {
     { "fmul",  STi, ST },
     { "(bad)" },
     { "(bad)" },
+#if UNIXWARE_COMPAT
     { "fsub",  STi, ST },
     { "fsubr", STi, ST },
     { "fdiv",  STi, ST },
     { "fdivr", STi, ST },
+#else
+    { "fsubr", STi, ST },
+    { "fsub",  STi, ST },
+    { "fdivr", STi, ST },
+    { "fdiv",  STi, ST },
+#endif
   },
   /* dd */
   {
@@ -1402,10 +1540,17 @@ static struct dis386 float_reg[][8] = {
     { "fmulp", STi, ST },
     { "(bad)" },
     { FGRPde_3 },
+#if UNIXWARE_COMPAT
     { "fsubp", STi, ST },
     { "fsubrp",        STi, ST },
     { "fdivp", STi, ST },
     { "fdivrp",        STi, ST },
+#else
+    { "fsubrp",        STi, ST },
+    { "fsubp", STi, ST },
+    { "fdivrp",        STi, ST },
+    { "fdivp", STi, ST },
+#endif
   },
   /* df */
   {
@@ -1470,9 +1615,8 @@ static char *fgrps[][8] = {
 };
 
 static void
-dofloat (aflag, dflag)
-     int aflag;
-     int dflag;
+dofloat (sizeflag)
+     int sizeflag;
 {
   struct dis386 *dp;
   unsigned char floatop;
@@ -1481,9 +1625,9 @@ dofloat (aflag, dflag)
   
   if (mod != 3)
     {
-      putop (float_mem[(floatop - 0xd8) * 8 + reg], aflag, dflag);
+      putop (float_mem[(floatop - 0xd8) * 8 + reg], sizeflag);
       obufp = op1out;
-      OP_E (v_mode, aflag, dflag);
+      OP_E (v_mode, sizeflag);
       return;
     }
   codep++;
@@ -1491,7 +1635,7 @@ dofloat (aflag, dflag)
   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)
@@ -1500,46 +1644,41 @@ dofloat (aflag, dflag)
     }
   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)
+static void
+OP_ST (ignore, sizeflag)
      int ignore;
-     int aflag;
-     int dflag;
+     int sizeflag;
 {
   oappend ("%st");
-  return (0);
 }
 
 /* ARGSUSED */
-static int
-OP_STi (ignore, aflag, dflag)
+static void
+OP_STi (ignore, sizeflag)
      int ignore;
-     int aflag;
-     int dflag;
+     int sizeflag;
 {
   sprintf (scratchbuf, "%%st(%d)", rm);
   oappend (scratchbuf);
-  return (0);
 }
 
 
 /* capital letters in template are macros */
 static void
-putop (template, aflag, dflag)
+putop (template, sizeflag)
      char *template;
-     int aflag;
-     int dflag;
+     int sizeflag;
 {
   char *p;
   
@@ -1550,21 +1689,84 @@ putop (template, aflag, dflag)
        default:
          *obufp++ = *p;
          break;
-       case 'C':               /* For jcxz/jecxz */
-         if (aflag)
+       case 'A':
+         if (mod != 3
+#ifdef SUFFIX_ALWAYS
+             || (sizeflag & SUFFIX_ALWAYS)
+#endif
+             )
+           *obufp++ = 'b';
+         break;
+       case 'B':
+#ifdef SUFFIX_ALWAYS
+         if (sizeflag & SUFFIX_ALWAYS)
+           *obufp++ = 'b';
+#endif
+         break;
+       case 'E':               /* For jcxz/jecxz */
+         if (sizeflag & AFLAG)
            *obufp++ = 'e';
          break;
+       case 'L':
+#ifdef SUFFIX_ALWAYS
+         if (sizeflag & SUFFIX_ALWAYS)
+           *obufp++ = 'l';
+#endif
+         break;
        case 'N':
          if ((prefixes & PREFIX_FWAIT) == 0)
            *obufp++ = 'n';
          break;
-       case 'S':
-         /* operand size flag */
-         if (dflag)
+       case 'P':
+         if ((prefixes & PREFIX_DATA)
+#ifdef SUFFIX_ALWAYS
+             || (sizeflag & SUFFIX_ALWAYS)
+#endif
+             )
+           {
+             if (sizeflag & DFLAG)
+               *obufp++ = 'l';
+             else
+               *obufp++ = 'w';
+           }
+         break;
+       case 'Q':
+         if (mod != 3
+#ifdef SUFFIX_ALWAYS
+             || (sizeflag & SUFFIX_ALWAYS)
+#endif
+             )
+           {
+             if (sizeflag & DFLAG)
+               *obufp++ = 'l';
+             else
+               *obufp++ = 'w';
+           }
+         break;
+       case 'R':
+         if (sizeflag & DFLAG)
            *obufp++ = 'l';
          else
            *obufp++ = 'w';
          break;
+       case 'S':
+#ifdef SUFFIX_ALWAYS
+         if (sizeflag & SUFFIX_ALWAYS)
+           {
+             if (sizeflag & DFLAG)
+               *obufp++ = 'l';
+             else
+               *obufp++ = 'w';
+           }
+#endif
+         break;
+       case 'W':
+         /* operand size flag for cwtl, cbtw */
+         if (sizeflag & DFLAG)
+           *obufp++ = 'w';
+         else
+           *obufp++ = 'b';
+         break;
        }
     }
   *obufp = 0;
@@ -1576,11 +1778,10 @@ oappend (s)
 {
   strcpy (obufp, s);
   obufp += strlen (s);
-  *obufp = 0;
 }
 
 static void
-append_prefix ()
+append_seg ()
 {
   if (prefixes & PREFIX_CS)
     oappend ("%cs:");
@@ -1596,21 +1797,19 @@ append_prefix ()
     oappend ("%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);
+  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;
 
@@ -1628,7 +1827,7 @@ OP_E (bytemode, aflag, dflag)
          oappend (names16[rm]);
          break;
        case v_mode:
-         if (dflag)
+         if (sizeflag & DFLAG)
            oappend (names32[rm]);
          else
            oappend (names16[rm]);
@@ -1637,19 +1836,19 @@ OP_E (bytemode, aflag, dflag)
          oappend ("<bad dis table>");
          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;
       int base;
-      int index;
-      int scale;
+      int index = 0;
+      int scale = 0;
 
       havesib = 0;
       havebase = 1;
@@ -1676,7 +1875,9 @@ OP_E (bytemode, aflag, dflag)
          break;
        case 1:
          FETCH_DATA (the_info, codep + 1);
-         disp = *(char *)codep++;
+         disp = *codep++;
+         if ((disp & 0x80) != 0)
+           disp -= 0x100;
          break;
        case 2:
          disp = get32 ();
@@ -1713,14 +1914,22 @@ OP_E (bytemode, aflag, dflag)
        {
        case 0:
          if (rm == 6)
-           disp = (short) get16 ();
+           {
+             disp = get16 ();
+             if ((disp & 0x8000) != 0)
+               disp -= 0x10000;
+           }
          break;
        case 1:
          FETCH_DATA (the_info, codep + 1);
-         disp = *(char *)codep++;
+         disp = *codep++;
+         if ((disp & 0x80) != 0)
+           disp -= 0x100;
          break;
        case 2:
-         disp = (short) get16 ();
+         disp = get16 ();
+         if ((disp & 0x8000) != 0)
+           disp -= 0x10000;
          break;
        }
 
@@ -1737,14 +1946,14 @@ OP_E (bytemode, aflag, dflag)
          oappend (")");
        }
     }
-  return 0;
 }
 
-static int
-OP_G (bytemode, aflag, dflag)
+#define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
+
+static void
+OP_G (bytemode, sizeflag)
      int bytemode;
-     int aflag;
-     int dflag;
+     int sizeflag;
 {
   switch (bytemode) 
     {
@@ -1758,16 +1967,15 @@ OP_G (bytemode, aflag, dflag)
       oappend (names32[reg]);
       break;
     case v_mode:
-      if (dflag)
+      if (sizeflag & DFLAG)
        oappend (names32[reg]);
       else
        oappend (names16[reg]);
       break;
     default:
-      oappend ("<internal disassembler error>");
+      oappend (INTERNAL_DISASSEMBLER_ERROR);
       break;
     }
-  return (0);
 }
 
 static int
@@ -1780,7 +1988,7 @@ get32 ()
   x |= (*codep++ & 0xff) << 8;
   x |= (*codep++ & 0xff) << 16;
   x |= (*codep++ & 0xff) << 24;
-  return (x);
+  return x;
 }
 
 static int
@@ -1791,22 +1999,21 @@ 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;
   
@@ -1827,24 +2034,22 @@ OP_REG (code, aflag, dflag)
                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)
+      if (sizeflag & DFLAG)
        s = names32[code - eAX_reg];
       else
        s = names16[code - eAX_reg];
       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;
   
@@ -1855,7 +2060,7 @@ OP_I (bytemode, aflag, dflag)
       op = *codep++ & 0xff;
       break;
     case v_mode:
-      if (dflag)
+      if (sizeflag & DFLAG)
        op = get32 ();
       else
        op = get16 ();
@@ -1864,19 +2069,17 @@ OP_I (bytemode, aflag, dflag)
       op = get16 ();
       break;
     default:
-      oappend ("<internal disassembler error>");
-      return (0);
+      oappend (INTERNAL_DISASSEMBLER_ERROR);
+      return;
     }
   sprintf (scratchbuf, "$0x%x", op);
   oappend (scratchbuf);
-  return (0);
 }
 
-static int
-OP_sI (bytemode, aflag, dflag)
+static void
+OP_sI (bytemode, sizeflag)
      int bytemode;
-     int aflag;
-     int dflag;
+     int sizeflag;
 {
   int op;
   
@@ -1884,31 +2087,37 @@ OP_sI (bytemode, aflag, dflag)
     {
     case b_mode:
       FETCH_DATA (the_info, codep + 1);
-      op = *(char *)codep++;
+      op = *codep++;
+      if ((op & 0x80) != 0)
+       op -= 0x100;
       break;
     case v_mode:
-      if (dflag)
+      if (sizeflag & DFLAG)
        op = get32 ();
       else
-       op = (short)get16();
+       {
+         op = get16();
+         if ((op & 0x8000) != 0)
+           op -= 0x10000;
+       }
       break;
     case w_mode:
-      op = (short)get16 ();
+      op = get16 ();
+      if ((op & 0x8000) != 0)
+       op -= 0x10000;
       break;
     default:
-      oappend ("<internal disassembler error>");
-      return (0);
+      oappend (INTERNAL_DISASSEMBLER_ERROR);
+      return;
     }
   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;
@@ -1917,14 +2126,18 @@ OP_J (bytemode, aflag, dflag)
     {
     case b_mode:
       FETCH_DATA (the_info, codep + 1);
-      disp = *(char *)codep++;
+      disp = *codep++;
+      if ((disp & 0x80) != 0)
+       disp -= 0x100;
       break;
     case v_mode:
-      if (dflag)
+      if (sizeflag & DFLAG)
        disp = get32 ();
       else
        {
-         disp = (short)get16 ();
+         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!  */
@@ -1932,43 +2145,39 @@ OP_J (bytemode, aflag, dflag)
        }
       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)
+static void
+OP_SEG (dummy, sizeflag)
      int dummy;
-     int aflag;
-     int dflag;
+     int sizeflag;
 {
   static char *sreg[] = {
     "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
   };
 
   oappend (sreg[reg]);
-  return (0);
 }
 
-static int
-OP_DIR (size, aflag, dflag)
+static void
+OP_DIR (size, sizeflag)
      int size;
-     int aflag;
-     int dflag;
+     int sizeflag;
 {
   int seg, offset;
   
   switch (size) 
     {
     case lptr:
-      if (aflag
+      if (sizeflag & DFLAG
        {
          offset = get32 ();
          seg = get16 ();
@@ -1978,14 +2187,18 @@ OP_DIR (size, aflag, dflag)
          offset = get16 ();
          seg = get16 ();
        }
-      sprintf (scratchbuf, "0x%x,0x%x", seg, offset);
+      sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset);
       oappend (scratchbuf);
       break;
     case v_mode:
-      if (aflag)
+      if (sizeflag & DFLAG)
        offset = get32 ();
       else
-       offset = (short)get16 ();
+       {
+         offset = get16 ();
+         if ((offset & 0x8000) != 0)
+           offset -= 0x10000;
+       }
       
       offset = start_pc + codep - start_codep + offset;
       set_op (offset);
@@ -1993,119 +2206,122 @@ OP_DIR (size, aflag, dflag)
       oappend (scratchbuf);
       break;
     default:
-      oappend ("<internal disassembler error>");
+      oappend (INTERNAL_DISASSEMBLER_ERROR);
       break;
     }
-  return (0);
 }
 
 /* ARGSUSED */
-static int
-OP_OFF (bytemode, aflag, dflag)
-     int bytemode;
-     int aflag;
-     int dflag;
+static void
+OP_OFF (ignore, sizeflag)
+     int ignore;
+     int sizeflag;
 {
   int off;
 
-  append_prefix ();
+  append_seg ();
 
-  if (aflag)
+  if (sizeflag & AFLAG)
     off = get32 ();
   else
     off = get16 ();
   
   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");
+  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 ("%ds:(");
-  oappend (aflag ? "%esi" : "%si");
-  oappend (")");
-  return (0);
+  oappend ("%es:");
+  ptr_reg (code, sizeflag);
+}
+
+static void
+OP_DSreg (code, sizeflag)
+     int code;
+     int sizeflag;
+{
+  if ((prefixes
+       & (PREFIX_CS
+         | PREFIX_DS
+         | PREFIX_SS
+         | PREFIX_ES
+         | PREFIX_FS
+         | PREFIX_GS)) == 0)
+    prefixes |= PREFIX_DS;
+  append_seg();
+  ptr_reg (code, sizeflag);
 }
 
 #if 0
 /* Not used.  */
 
 /* ARGSUSED */
-static int
-OP_ONE (dummy, aflag, dflag)
+static void
+OP_ONE (dummy, sizeflag)
      int dummy;
-     int aflag;
-     int dflag;
+     int sizeflag;
 {
   oappend ("1");
-  return (0);
 }
 
 #endif
 
 /* ARGSUSED */
-static int
-OP_C (dummy, aflag, dflag)
+static void
+OP_C (dummy, sizeflag)
      int dummy;
-     int aflag;
-     int dflag;
+     int sizeflag;
 {
   codep++; /* skip mod/rm */
   sprintf (scratchbuf, "%%cr%d", reg);
   oappend (scratchbuf);
-  return (0);
 }
 
 /* ARGSUSED */
-static int
-OP_D (dummy, aflag, dflag)
+static void
+OP_D (dummy, sizeflag)
      int dummy;
-     int aflag;
-     int dflag;
+     int sizeflag;
 {
   codep++; /* skip mod/rm */
   sprintf (scratchbuf, "%%db%d", reg);
   oappend (scratchbuf);
-  return (0);
 }
 
 /* ARGSUSED */
-static int
-OP_T (dummy, aflag, dflag)
+static void
+OP_T (dummy, sizeflag)
      int dummy;
-     int aflag;
-     int dflag;
+     int sizeflag;
 {
   codep++; /* skip mod/rm */
   sprintf (scratchbuf, "%%tr%d", reg);
   oappend (scratchbuf);
-  return (0);
 }
 
-static int
-OP_rm (bytemode, aflag, dflag)
+static void
+OP_rm (bytemode, sizeflag)
      int bytemode;
-     int aflag;
-     int dflag;
+     int sizeflag;
 {
   switch (bytemode) 
     {
@@ -2116,5 +2332,39 @@ OP_rm (bytemode, aflag, dflag)
       oappend (names16[rm]);
       break;
     }
-  return (0);
+}
+
+static void
+OP_MMX (ignore, sizeflag)
+     int ignore;
+     int sizeflag;
+{
+  sprintf (scratchbuf, "%%mm%d", reg);
+  oappend (scratchbuf);
+}
+
+static void
+OP_EM (bytemode, sizeflag)
+     int bytemode;
+     int sizeflag;
+{
+  if (mod != 3)
+    {
+      OP_E (bytemode, sizeflag);
+      return;
+    }
+
+  codep++;
+  sprintf (scratchbuf, "%%mm%d", rm);
+  oappend (scratchbuf);
+}
+
+static void
+OP_MS (ignore, sizeflag)
+     int ignore;
+     int sizeflag;
+{
+  ++codep;
+  sprintf (scratchbuf, "%%mm%d", rm);
+  oappend (scratchbuf);
 }
This page took 0.052814 seconds and 4 git commands to generate.