Thu Nov 12 19:21:57 1998 Dave Brolley <brolley@cygnus.com>
[deliverable/binutils-gdb.git] / opcodes / i386-dis.c
index 7bbd765226346550dbb83ae39b0d5472d57e3459..eea4c00cf51c4b95b4419e5cd8253caf6e207dc8 100644 (file)
@@ -1,5 +1,6 @@
 /* Print i386 instructions for GDB, the GNU debugger.
-   Copyright (C) 1988, 1989, 1991, 1993, 1994, 1995 Free Software Foundation, Inc.
+   Copyright (C) 1988, 89, 91, 93, 94, 95, 96, 97, 1998
+   Free Software Foundation, Inc.
 
 This file is part of GDB.
 
@@ -34,11 +35,21 @@ 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
 {
   /* Points to first byte not fetched.  */
@@ -97,7 +108,9 @@ fetch_data (info, addr)
 #define Iw OP_I, w_mode
 #define Jb OP_J, b_mode
 #define Jv OP_J, v_mode
+#if 0
 #define ONE OP_ONE, 0
+#endif
 #define Cd OP_C, d_mode
 #define Dd OP_D, d_mode
 #define Td OP_T, d_mode
@@ -127,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
@@ -139,13 +153,52 @@ fetch_data (info, addr)
 #define fs OP_REG, fs_reg
 #define gs OP_REG, gs_reg
 
-int OP_E(), OP_indirE(), OP_G(), OP_I(), OP_sI(), OP_REG();
-int OP_J(), OP_SEG();
-int OP_DIR(), OP_OFF(), OP_DSSI(), OP_ESDI(), OP_ONE(), OP_C();
-int OP_D(), OP_T(), OP_rm();
-
-static void dofloat (), putop (), append_prefix (), set_op ();
-static int get16 (), get32 ();
+#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 void OP_ONE PARAMS ((int, int));
+#endif
+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
@@ -206,90 +259,107 @@ static int get16 (), get32 ();
 #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
 
 struct dis386 {
   char *name;
-  int (*op1)();
+  op_rtn op1;
   int bytemode1;
-  int (*op2)();
+  op_rtn op2;
   int bytemode2;
-  int (*op3)();
+  op_rtn op3;
   int bytemode3;
 };
 
-struct dis386 dis386[] = {
+/* Upper case letters in the instruction names here are macros.
+   'A' => print 'b' if no register operands or suffix_always is true
+   'B' => print 'b' if suffix_always is true
+   'E' => print 'e' if 32-bit form of jcxz
+   'L' => print 'l' if suffix_always is true
+   'N' => print 'n' if instruction has no wait "prefix"
+   'P' => print 'w' or 'l' if instruction has an operand size prefix,
+                              or suffix_always is true
+   'Q' => print 'w' or 'l' if no register operands or suffix_always is true
+   'R' => print 'w' or 'l'
+   '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" },
@@ -330,8 +400,8 @@ struct dis386 dis386[] = {
   { "popS",    eSI },
   { "popS",    eDI },
   /* 60 */
-  { "pusha" },
-  { "popa" },
+  { "pushaP" },
+  { "popaP" },
   { "boundS",  Gv, Ma },
   { "arpl",    Ew, Gw },
   { "(bad)" },                 /* seg fs */
@@ -339,50 +409,50 @@ 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 },
+  { "jo",      Jb },
   { "jno",     Jb },
-  { "jb",              Jb },
+  { "jb",      Jb },
   { "jae",     Jb },
-  { "je",              Jb },
+  { "je",      Jb },
   { "jne",     Jb },
   { "jbe",     Jb },
-  { "ja",              Jb },
+  { "ja",      Jb },
   /* 78 */
-  { "js",              Jb },
+  { "js",      Jb },
   { "jns",     Jb },
-  { "jp",              Jb },
+  { "jp",      Jb },
   { "jnp",     Jb },
-  { "jl",              Jb },
-  { "jnl",     Jb },
+  { "jl",      Jb },
+  { "jge",     Jb },
   { "jle",     Jb },
-  { "jg",              Jb },
+  { "jg",      Jb },
   /* 80 */
   { GRP1b },
   { 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 },
@@ -393,41 +463,41 @@ 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 },
@@ -440,30 +510,30 @@ 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 },
@@ -477,19 +547,19 @@ 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 */
@@ -511,7 +581,7 @@ struct dis386 dis386[] = {
   { GRP5 },
 };
 
-struct dis386 dis386_twobyte[] = {
+static struct dis386 dis386_twobyte[] = {
   /* 00 */
   { GRP6 },
   { GRP7 },
@@ -524,7 +594,8 @@ struct dis386 dis386_twobyte[] = {
   /* 08 */
   { "invd" },
   { "wbinvd" },
-  { "(bad)" },  { "(bad)" },  
+  { "(bad)" },
+  { "ud2a" },  
   { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
   /* 10 */
   { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
@@ -534,29 +605,29 @@ 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)" },  
   { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
   /* 30 */
-  { "wrmsr" },  { "rdtsc" },  { "rdmsr" },  { "(bad)" },  
+  { "wrmsr" },  { "rdtsc" },  { "rdmsr" },  { "rdpmc" },  
   { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
   /* 38 */
   { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
   { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
   /* 40 */
-  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
-  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "cmovo", Gv,Ev }, { "cmovno", Gv,Ev }, { "cmovb", Gv,Ev }, { "cmovae", Gv,Ev },
+  { "cmove", Gv,Ev }, { "cmovne", Gv,Ev }, { "cmovbe", Gv,Ev }, { "cmova", Gv,Ev },
   /* 48 */
-  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
-  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "cmovs", Gv,Ev }, { "cmovns", Gv,Ev }, { "cmovp", Gv,Ev }, { "cmovnp", Gv,Ev },
+  { "cmovl", Gv,Ev }, { "cmovge", Gv,Ev }, { "cmovle", Gv,Ev }, { "cmovg", Gv,Ev },  
   /* 50 */
   { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
   { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
@@ -564,17 +635,36 @@ 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 },
@@ -612,8 +702,8 @@ 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 },
@@ -621,8 +711,8 @@ struct dis386 dis386_twobyte[] = {
   { "(bad)" },
   { "(bad)" },  
   /* a8 */
-  { "pushl", gs },
-  { "popl", gs },
+  { "pushP", gs },
+  { "popP", gs },
   { "rsm" },
   { "btsS", Ev, Gv },  
   { "shrdS", Ev, Gv, Ib },
@@ -630,25 +720,25 @@ 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 */
   { "(bad)" },
-  { "(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)" },  
@@ -657,7 +747,7 @@ struct dis386 dis386_twobyte[] = {
   { "(bad)" },
   { GRP9 },  
   /* c8 */
-  { "bswap", eAX },
+  { "bswap", eAX },    /* bswap doesn't support 16 bit regs */
   { "bswap", eCX },
   { "bswap", eDX },
   { "bswap", eBX },
@@ -666,23 +756,94 @@ 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] = {
+  1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
+  1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
+  1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
+  1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0,
+  1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1
+};
+
+static const unsigned char twobyte_has_modrm[256] = {
+  /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
+  /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
+  /* 20 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* 2f */
+  /* 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];
@@ -694,7 +855,7 @@ static disassemble_info *the_info;
 static int mod;
 static int rm;
 static int reg;
-static void oappend ();
+static void oappend PARAMS ((char *s));
 
 static char *names32[]={
   "%eax","%ecx","%edx","%ebx", "%esp","%ebp","%esi","%edi",
@@ -708,124 +869,127 @@ static char *names8[] = {
 static char *names_seg[] = {
   "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
 };
+static char *index16[] = {
+  "bx+si","bx+di","bp+si","bp+di","si","di","bp","bx"
+};
 
-struct dis386 grps[][8] = {
+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 },
@@ -833,8 +997,8 @@ struct dis386 grps[][8] = {
   },
   /* GRP4 */
   {
-    { "incb", Eb },
-    { "decb", Eb },
+    { "incA", Eb },
+    { "decA", Eb },
     { "(bad)" },
     { "(bad)" },
     { "(bad)" },
@@ -844,13 +1008,13 @@ 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 */
@@ -881,20 +1045,53 @@ 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 */
   {
     { "(bad)" },
-    { "cmpxch8b", Ev },
+    { "cmpxchg8b", Ev },
+    { "(bad)" },
     { "(bad)" },
     { "(bad)" },
     { "(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)" },
   }
 };
@@ -909,7 +1106,7 @@ 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;
@@ -954,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;
        }
@@ -966,12 +1164,10 @@ ckprefix ()
     }
 }
 
-static int dflag;
-static int aflag;              
-
 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
 /*
@@ -983,20 +1179,43 @@ 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 sizeflag));
+
 int
 print_insn_i386 (pc, info)
      bfd_vma pc;
      disassemble_info *info;
+{
+  int flags;
+  if (info->mach == bfd_mach_i386_i386)
+    flags = AFLAG|DFLAG;
+  else if (info->mach == bfd_mach_i386_i8086)
+    flags = 0;
+  else
+    abort ();
+  return print_insn_x86 (pc, info, flags);
+}
+
+int
+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;
+
   struct dis_private priv;
   bfd_byte *inbuf = priv.the_buffer;
 
+  /* The output looks better if we put 5 bytes on a line, since that
+     puts long word instructions on a single line.  */
+  info->bytes_per_line = 5;
+
   info->private_data = (PTR) &priv;
   priv.max_fetched = priv.the_buffer;
   priv.insn_start = pc;
@@ -1019,85 +1238,84 @@ print_insn_i386 (pc, info)
   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_REPZ)
-    oappend ("repz ");
-  if (prefixes & PREFIX_REPNZ)
-    oappend ("repnz ");
-  if (prefixes & PREFIX_LOCK)
-    oappend ("lock ");
-  
   if ((prefixes & PREFIX_FWAIT)
       && ((*codep < 0xd8) || (*codep > 0xdf)))
     {
-      /* fwait not followed by floating point instruction */
+      /* fwait not followed by floating point instruction */
       (*info->fprintf_func) (info->stream, "fwait");
-      return (1);
+      /* There may be other prefixes.  Skip any before the fwait.  */
+      return codep - inbuf;
     }
   
-  /* these would be initialized to 0 if disassembling for 8086 or 286 */
-  dflag = 1;
-  aflag = 1;
+  if (prefixes & PREFIX_REPZ)
+    oappend ("repz ");
+  if (prefixes & PREFIX_REPNZ)
+    oappend ("repnz ");
+  if (prefixes & PREFIX_LOCK)
+    oappend ("lock ");
   
   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)
     {
       FETCH_DATA (info, codep + 2);
       dp = &dis386_twobyte[*++codep];
+      need_modrm = twobyte_has_modrm[*codep];
     }
   else
-    dp = &dis386[*codep];
+    {
+      dp = &dis386[*codep];
+      need_modrm = onebyte_has_modrm[*codep];
+    }
   codep++;
 
-  /* Fetch the mod/reg/rm byte.  FIXME: We should be only fetching
-     this if we need it.  As it is, this code loses if there is a
-     one-byte instruction (without a mod/reg/rm byte) at the end of
-     the address space.  */
-
-  FETCH_DATA (info, codep + 1);
-  mod = (*codep >> 6) & 3;
-  reg = (*codep >> 3) & 7;
-  rm = *codep & 7;
+  if (need_modrm)
+    {
+      FETCH_DATA (info, codep + 1);
+      mod = (*codep >> 6) & 3;
+      reg = (*codep >> 3) & 7;
+      rm = *codep & 7;
+    }
 
   if (dp->name == NULL && dp->bytemode1 == FLOATCODE)
     {
-      dofloat ();
+      dofloat (sizeflag);
     }
   else
     {
       if (dp->name == NULL)
        dp = &grps[dp->bytemode1][reg];
       
-      putop (dp->name);
+      putop (dp->name, sizeflag);
       
       obufp = op1out;
       op_ad = 2;
       if (dp->op1)
-       (*dp->op1)(dp->bytemode1);
+       (*dp->op1)(dp->bytemode1, sizeflag);
       
       obufp = op2out;
       op_ad = 1;
       if (dp->op2)
-       (*dp->op2)(dp->bytemode2);
+       (*dp->op2)(dp->bytemode2, sizeflag);
       
       obufp = op3out;
       op_ad = 0;
       if (dp->op3)
-       (*dp->op3)(dp->bytemode3);
+       (*dp->op3)(dp->bytemode3, sizeflag);
     }
   
   obufp = obuf + strlen (obuf);
@@ -1106,11 +1324,9 @@ print_insn_i386 (pc, info)
   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;
@@ -1129,7 +1345,7 @@ print_insn_i386 (pc, info)
   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;
@@ -1139,7 +1355,7 @@ print_insn_i386 (pc, info)
       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;
@@ -1149,14 +1365,14 @@ print_insn_i386 (pc, info)
       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;
 }
 
-char *float_mem[] = {
+static char *float_mem[] = {
   /* d8 */
   "fadds",
   "fmuls",
@@ -1233,7 +1449,6 @@ char *float_mem[] = {
 
 #define ST OP_ST, 0
 #define STi OP_STi, 0
-int OP_ST(), OP_STi();
 
 #define FGRPd9_2 NULL, NULL, 0
 #define FGRPd9_4 NULL, NULL, 1
@@ -1245,7 +1460,7 @@ int OP_ST(), OP_STi();
 #define FGRPde_3 NULL, NULL, 7
 #define FGRPdf_4 NULL, NULL, 8
 
-struct dis386 float_reg[][8] = {
+static struct dis386 float_reg[][8] = {
   /* d8 */
   {
     { "fadd",  ST, STi },
@@ -1270,10 +1485,10 @@ struct dis386 float_reg[][8] = {
   },
   /* da */
   {
-    { "(bad)" },
-    { "(bad)" },
-    { "(bad)" },
-    { "(bad)" },
+    { "fcmovb",        ST, STi },
+    { "fcmove",        ST, STi },
+    { "fcmovbe",ST, STi },
+    { "fcmovu",        ST, STi },
     { "(bad)" },
     { FGRPda_5 },
     { "(bad)" },
@@ -1281,13 +1496,13 @@ struct dis386 float_reg[][8] = {
   },
   /* db */
   {
-    { "(bad)" },
-    { "(bad)" },
-    { "(bad)" },
-    { "(bad)" },
+    { "fcmovnb",ST, STi },
+    { "fcmovne",ST, STi },
+    { "fcmovnbe",ST, STi },
+    { "fcmovnu",ST, STi },
     { FGRPdb_4 },
-    { "(bad)" },
-    { "(bad)" },
+    { "fucomi",        ST, STi },
+    { "fcomi", ST, STi },
     { "(bad)" },
   },
   /* dc */
@@ -1296,10 +1511,17 @@ 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 */
   {
@@ -1318,10 +1540,17 @@ 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 */
   {
@@ -1330,14 +1559,14 @@ struct dis386 float_reg[][8] = {
     { "(bad)" },
     { "(bad)" },
     { FGRPdf_4 },
-    { "(bad)" },
-    { "(bad)" },
+    { "fucomip",ST, STi },
+    { "fcomip", ST, STi },
     { "(bad)" },
   },
 };
 
 
-char *fgrps[][8] = {
+static char *fgrps[][8] = {
   /* d9_2  0 */
   {
     "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
@@ -1386,7 +1615,8 @@ char *fgrps[][8] = {
 };
 
 static void
-dofloat ()
+dofloat (sizeflag)
+     int sizeflag;
 {
   struct dis386 *dp;
   unsigned char floatop;
@@ -1395,9 +1625,9 @@ dofloat ()
   
   if (mod != 3)
     {
-      putop (float_mem[(floatop - 0xd8) * 8 + reg]);
+      putop (float_mem[(floatop - 0xd8) * 8 + reg], sizeflag);
       obufp = op1out;
-      OP_E (v_mode);
+      OP_E (v_mode, sizeflag);
       return;
     }
   codep++;
@@ -1405,7 +1635,7 @@ dofloat ()
   dp = &float_reg[floatop - 0xd8][reg];
   if (dp->name == NULL)
     {
-      putop (fgrps[dp->bytemode1][rm]);
+      putop (fgrps[dp->bytemode1][rm], sizeflag);
       /* instruction fnstsw is only one with strange arg */
       if (floatop == 0xdf
          && FETCH_DATA (the_info, codep + 1)
@@ -1414,40 +1644,41 @@ dofloat ()
     }
   else
     {
-      putop (dp->name);
+      putop (dp->name, sizeflag);
       obufp = op1out;
       if (dp->op1)
-       (*dp->op1)(dp->bytemode1);
+       (*dp->op1)(dp->bytemode1, sizeflag);
       obufp = op2out;
       if (dp->op2)
-       (*dp->op2)(dp->bytemode2);
+       (*dp->op2)(dp->bytemode2, sizeflag);
     }
 }
 
 /* ARGSUSED */
-int
-OP_ST (ignore)
+static void
+OP_ST (ignore, sizeflag)
      int ignore;
+     int sizeflag;
 {
   oappend ("%st");
-  return (0);
 }
 
 /* ARGSUSED */
-int
-OP_STi (ignore)
+static void
+OP_STi (ignore, sizeflag)
      int ignore;
+     int sizeflag;
 {
   sprintf (scratchbuf, "%%st(%d)", rm);
   oappend (scratchbuf);
-  return (0);
 }
 
 
 /* capital letters in template are macros */
 static void
-putop (template)
+putop (template, sizeflag)
      char *template;
+     int sizeflag;
 {
   char *p;
   
@@ -1458,21 +1689,84 @@ putop (template)
        default:
          *obufp++ = *p;
          break;
-       case 'C':               /* For jcxz/jecxz */
-         if (aflag == 0)
+       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;
@@ -1484,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:");
@@ -1504,33 +1797,25 @@ append_prefix ()
     oappend ("%gs:");
 }
 
-int
-OP_indirE (bytemode)
+static void
+OP_indirE (bytemode, sizeflag)
      int bytemode;
+     int sizeflag;
 {
   oappend ("*");
-  OP_E (bytemode);
-  return (0);
+  OP_E (bytemode, sizeflag);
 }
 
-int
-OP_E (bytemode)
+static void
+OP_E (bytemode, sizeflag)
      int bytemode;
+     int sizeflag;
 {
   int disp;
-  int havesib;
-  int base;
-  int index;
-  int scale;
-  int havebase;
-  
+
   /* skip mod/rm byte */
   codep++;
-  
-  havesib = 0;
-  havebase = 0;
-  disp = 0;
-  
+
   if (mod == 3)
     {
       switch (bytemode)
@@ -1542,7 +1827,7 @@ OP_E (bytemode)
          oappend (names16[rm]);
          break;
        case v_mode:
-         if (dflag)
+         if (sizeflag & DFLAG)
            oappend (names32[rm]);
          else
            oappend (names16[rm]);
@@ -1551,90 +1836,124 @@ OP_E (bytemode)
          oappend ("<bad dis table>");
          break;
        }
-      return (0);
+      return;
     }
-  
-  append_prefix ();
-  if (rm == 4)
+
+  disp = 0;
+  append_seg ();
+
+  if (sizeflag & AFLAG) /* 32 bit address mode */
     {
-      havesib = 1;
+      int havesib;
+      int havebase;
+      int base;
+      int index = 0;
+      int scale = 0;
+
+      havesib = 0;
       havebase = 1;
-      FETCH_DATA (the_info, codep + 1);
-      scale = (*codep >> 6) & 3;
-      index = (*codep >> 3) & 7;
-      base = *codep & 7;
-      codep++;
-    }
-  
-  switch (mod)
-    {
-    case 0:
-      switch (rm)
+      base = rm;
+
+      if (base == 4)
+       {
+         havesib = 1;
+         FETCH_DATA (the_info, codep + 1);
+         scale = (*codep >> 6) & 3;
+         index = (*codep >> 3) & 7;
+         base = *codep & 7;
+         codep++;
+       }
+
+      switch (mod)
        {
-       case 4:
-         /* implies havesib and havebase */
-         if (base == 5) {
-           havebase = 0;
-           disp = get32 ();
-         }
+       case 0:
+         if (base == 5)
+           {
+             havebase = 0;
+             disp = get32 ();
+           }
          break;
-       case 5:
-         disp = get32 ();
+       case 1:
+         FETCH_DATA (the_info, codep + 1);
+         disp = *codep++;
+         if ((disp & 0x80) != 0)
+           disp -= 0x100;
          break;
-       default:
-         havebase = 1;
-         base = rm;
+       case 2:
+         disp = get32 ();
          break;
        }
-      break;
-    case 1:
-      FETCH_DATA (the_info, codep + 1);
-      disp = *(char *)codep++;
-      if (rm != 4)
+
+      if (mod != 0 || base == 5)
        {
-         havebase = 1;
-         base = rm;
+         sprintf (scratchbuf, "0x%x", disp);
+         oappend (scratchbuf);
        }
-      break;
-    case 2:
-      disp = get32 ();
-      if (rm != 4)
+
+      if (havebase || (havesib && (index != 4 || scale != 0)))
        {
-         havebase = 1;
-         base = rm;
+         oappend ("(");
+         if (havebase)
+           oappend (names32[base]);
+         if (havesib)
+           {
+             if (index != 4)
+               {
+                 sprintf (scratchbuf, ",%s", names32[index]);
+                 oappend (scratchbuf);
+               }
+             sprintf (scratchbuf, ",%d", 1 << scale);
+             oappend (scratchbuf);
+           }
+         oappend (")");
        }
-      break;
-    }
-  
-  if (mod != 0 || rm == 5 || (havesib && base == 5))
-    {
-      sprintf (scratchbuf, "0x%x", disp);
-      oappend (scratchbuf);
     }
-  
-  if (havebase || havesib) 
-    {
-      oappend ("(");
-      if (havebase)
-       oappend (names32[base]);
-      if (havesib) 
+  else
+    { /* 16 bit address mode */
+      switch (mod)
        {
-         if (index != 4) 
+       case 0:
+         if (rm == 6)
            {
-             sprintf (scratchbuf, ",%s", names32[index]);
-             oappend (scratchbuf);
+             disp = get16 ();
+             if ((disp & 0x8000) != 0)
+               disp -= 0x10000;
            }
-         sprintf (scratchbuf, ",%d", 1 << scale);
+         break;
+       case 1:
+         FETCH_DATA (the_info, codep + 1);
+         disp = *codep++;
+         if ((disp & 0x80) != 0)
+           disp -= 0x100;
+         break;
+       case 2:
+         disp = get16 ();
+         if ((disp & 0x8000) != 0)
+           disp -= 0x10000;
+         break;
+       }
+
+      if (mod != 0 || rm == 6)
+       {
+         sprintf (scratchbuf, "0x%x", disp);
          oappend (scratchbuf);
        }
-      oappend (")");
+
+      if (mod != 0 || rm != 6)
+       {
+         oappend ("(");
+         oappend (index16[rm]);
+         oappend (")");
+       }
     }
-  return (0);
 }
 
-int
-OP_G (bytemode)
+#define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
+
+static void
+OP_G (bytemode, sizeflag)
      int bytemode;
+     int sizeflag;
 {
   switch (bytemode) 
     {
@@ -1648,16 +1967,15 @@ OP_G (bytemode)
       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
@@ -1670,7 +1988,7 @@ get32 ()
   x |= (*codep++ & 0xff) << 8;
   x |= (*codep++ & 0xff) << 16;
   x |= (*codep++ & 0xff) << 24;
-  return (x);
+  return x;
 }
 
 static int
@@ -1681,20 +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;
 }
 
-int
-OP_REG (code)
+static void
+OP_REG (code, sizeflag)
      int code;
+     int sizeflag;
 {
   char *s;
   
@@ -1715,22 +2034,22 @@ OP_REG (code)
                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);
 }
 
-int
-OP_I (bytemode)
+static void
+OP_I (bytemode, sizeflag)
      int bytemode;
+     int sizeflag;
 {
   int op;
   
@@ -1741,7 +2060,7 @@ OP_I (bytemode)
       op = *codep++ & 0xff;
       break;
     case v_mode:
-      if (dflag)
+      if (sizeflag & DFLAG)
        op = get32 ();
       else
        op = get16 ();
@@ -1750,17 +2069,17 @@ OP_I (bytemode)
       op = get16 ();
       break;
     default:
-      oappend ("<internal disassembler error>");
-      return (0);
+      oappend (INTERNAL_DISASSEMBLER_ERROR);
+      return;
     }
   sprintf (scratchbuf, "$0x%x", op);
   oappend (scratchbuf);
-  return (0);
 }
 
-int
-OP_sI (bytemode)
+static void
+OP_sI (bytemode, sizeflag)
      int bytemode;
+     int sizeflag;
 {
   int op;
   
@@ -1768,29 +2087,37 @@ OP_sI (bytemode)
     {
     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);
 }
 
-int
-OP_J (bytemode)
+static void
+OP_J (bytemode, sizeflag)
      int bytemode;
+     int sizeflag;
 {
   int disp;
   int mask = -1;
@@ -1799,14 +2126,18 @@ OP_J (bytemode)
     {
     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!  */
@@ -1814,39 +2145,39 @@ OP_J (bytemode)
        }
       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 */
-int
-OP_SEG (dummy)
+static void
+OP_SEG (dummy, sizeflag)
      int dummy;
+     int sizeflag;
 {
   static char *sreg[] = {
     "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
   };
 
   oappend (sreg[reg]);
-  return (0);
 }
 
-int
-OP_DIR (size)
+static void
+OP_DIR (size, sizeflag)
      int size;
+     int sizeflag;
 {
   int seg, offset;
   
   switch (size) 
     {
     case lptr:
-      if (aflag
+      if (sizeflag & DFLAG
        {
          offset = get32 ();
          seg = get16 ();
@@ -1856,14 +2187,18 @@ OP_DIR (size)
          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);
@@ -1871,96 +2206,122 @@ OP_DIR (size)
       oappend (scratchbuf);
       break;
     default:
-      oappend ("<internal disassembler error>");
+      oappend (INTERNAL_DISASSEMBLER_ERROR);
       break;
     }
-  return (0);
 }
 
 /* ARGSUSED */
-int
-OP_OFF (bytemode)
-     int bytemode;
+static void
+OP_OFF (ignore, sizeflag)
+     int ignore;
+     int sizeflag;
 {
   int off;
-  
-  if (aflag)
+
+  append_seg ();
+
+  if (sizeflag & AFLAG)
     off = get32 ();
   else
     off = get16 ();
   
   sprintf (scratchbuf, "0x%x", off);
   oappend (scratchbuf);
-  return (0);
 }
 
-/* ARGSUSED */
-int
-OP_ESDI (dummy)
-    int dummy;
+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 */
-int
-OP_DSSI (dummy)
-    int dummy;
+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 */
-int
-OP_ONE (dummy)
-    int dummy;
+static void
+OP_ONE (dummy, sizeflag)
+     int dummy;
+     int sizeflag;
 {
   oappend ("1");
-  return (0);
 }
 
+#endif
+
 /* ARGSUSED */
-int
-OP_C (dummy)
-    int dummy;
+static void
+OP_C (dummy, sizeflag)
+     int dummy;
+     int sizeflag;
 {
   codep++; /* skip mod/rm */
   sprintf (scratchbuf, "%%cr%d", reg);
   oappend (scratchbuf);
-  return (0);
 }
 
 /* ARGSUSED */
-int
-OP_D (dummy)
-    int dummy;
+static void
+OP_D (dummy, sizeflag)
+     int dummy;
+     int sizeflag;
 {
   codep++; /* skip mod/rm */
   sprintf (scratchbuf, "%%db%d", reg);
   oappend (scratchbuf);
-  return (0);
 }
 
 /* ARGSUSED */
-int
-OP_T (dummy)
+static void
+OP_T (dummy, sizeflag)
      int dummy;
+     int sizeflag;
 {
   codep++; /* skip mod/rm */
   sprintf (scratchbuf, "%%tr%d", reg);
   oappend (scratchbuf);
-  return (0);
 }
 
-int
-OP_rm (bytemode)
+static void
+OP_rm (bytemode, sizeflag)
      int bytemode;
+     int sizeflag;
 {
   switch (bytemode) 
     {
@@ -1971,5 +2332,39 @@ OP_rm (bytemode)
       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.055304 seconds and 4 git commands to generate.