* remote.c (minitelnet): Don't redeclare escape_count, echo_check.
[binutils-gdb.git] / opcodes / i386-dis.c
index 7d9c18c30c0822c29348eb00ac8b1734db5eb7e3..79faee676e50bda28a35a51d3320ae8044676430 100644 (file)
@@ -1,7 +1,6 @@
 /* Print i386 instructions for GDB, the GNU debugger.
    Copyright 1988, 1989, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2001
-   Free Software Foundation, Inc.
+   2001, 2002, 2003 Free Software Foundation, Inc.
 
 This file is part of GDB.
 
@@ -52,7 +51,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 static int fetch_data PARAMS ((struct disassemble_info *, bfd_byte *));
 static void ckprefix PARAMS ((void));
 static const char *prefix_name PARAMS ((int, int));
-static int print_insn_i386 PARAMS ((bfd_vma, disassemble_info *));
+static int print_insn PARAMS ((bfd_vma, disassemble_info *));
 static void dofloat PARAMS ((int));
 static void OP_ST PARAMS ((int, int));
 static void OP_STi  PARAMS ((int, int));
@@ -101,6 +100,7 @@ struct dis_private {
   bfd_byte *max_fetched;
   bfd_byte the_buffer[MAXLEN];
   bfd_vma insn_start;
+  int orig_sizeflag;
   jmp_buf bailout;
 };
 
@@ -175,9 +175,9 @@ fetch_data (info, addr)
   if (status != 0)
     {
       /* If we did manage to read at least one byte, then
-         print_insn_i386 will do something sensible.  Otherwise, print
-         an error.  We do that here because this is where we know
-         STATUS.  */
+        print_insn_i386 will do something sensible.  Otherwise, print
+        an error.  We do that here because this is where we know
+        STATUS.  */
       if (priv->max_fetched == priv->the_buffer)
        (*info->memory_error_func) (status, start, info);
       longjmp (priv->bailout, 1);
@@ -192,6 +192,7 @@ fetch_data (info, addr)
 #define Eb OP_E, b_mode
 #define Ev OP_E, v_mode
 #define Ed OP_E, d_mode
+#define Edq OP_E, dq_mode
 #define indirEb OP_indirE, b_mode
 #define indirEv OP_indirE, v_mode
 #define Ew OP_E, w_mode
@@ -298,9 +299,7 @@ fetch_data (info, addr)
 #define loop_jcxz_flag NULL, loop_jcxz_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
 
@@ -313,6 +312,7 @@ fetch_data (info, addr)
 #define m_mode 7  /* d_mode in 32bit, q_mode in 64bit mode.  */
 #define cond_jump_mode 8
 #define loop_jcxz_mode 9
+#define dq_mode 10 /* operand size depends on REX prefixes.  */
 
 #define es_reg 100
 #define cs_reg 101
@@ -442,9 +442,9 @@ struct dis386 {
    'N' => print 'n' if instruction has no wait "prefix"
    'O' => print 'd', or 'o'
    'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
-                              or suffix_always is true
-         print 'q' if rex prefix is present.
-   'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always is true
+   .      or suffix_always is true.  print 'q' if rex prefix is present.
+   'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always
+   .      is true
    'R' => print 'w', 'l' or 'q' ("wd" or "dq" in intel mode)
    'S' => print 'w', 'l' or 'q' if suffix_always is true
    'T' => print 'q' in 64bit mode and behave as 'P' otherwise
@@ -736,7 +736,7 @@ static const struct dis386 dis386[] = {
   { "outS",            indirDX, eAX, XX },
   /* f0 */
   { "(bad)",           XX, XX, XX },   /* lock prefix */
-  { "(bad)",           XX, XX, XX },
+  { "icebp",           XX, XX, XX },
   { "(bad)",           XX, XX, XX },   /* repne */
   { "(bad)",           XX, XX, XX },   /* repz */
   { "hlt",             XX, XX, XX },
@@ -879,7 +879,7 @@ static const struct dis386 dis386_twobyte[] = {
   { "packssdw",                MX, EM, XX },
   { PREGRP26 },
   { PREGRP24 },
-  { "movd",            MX, Ed, XX },
+  { "movd",            MX, Edq, XX },
   { PREGRP19 },
   /* 70 */
   { PREGRP22 },
@@ -1297,10 +1297,10 @@ static const struct dis386 grps[][8] = {
     { "(bad)", Eb, XX, XX },
     { "notA",  Eb, XX, XX },
     { "negA",  Eb, XX, XX },
-    { "mulB",  AL, Eb, XX },
-    { "imulB", AL, Eb, XX },
-    { "divB",  AL, Eb, XX },
-    { "idivB", AL, Eb, XX }
+    { "mulA",  Eb, XX, XX },   /* Don't print the implicit %al register,  */
+    { "imulA", Eb, XX, XX },   /* to distinguish these opcodes from other */
+    { "divA",  Eb, XX, XX },   /* mul/imul opcodes.  Do the same for div  */
+    { "idivA", Eb, XX, XX }    /* and idiv for consistency.               */
   },
   /* GRP3S */
   {
@@ -1308,10 +1308,10 @@ static const struct dis386 grps[][8] = {
     { "(bad)", XX, XX, XX },
     { "notQ",  Ev, XX, XX },
     { "negQ",  Ev, XX, XX },
-    { "mulS",  eAX, Ev, XX },
-    { "imulS", eAX, Ev, XX },
-    { "divS",  eAX, Ev, XX },
-    { "idivS", eAX, Ev, XX },
+    { "mulQ",  Ev, XX, XX },   /* Don't print the implicit register.  */
+    { "imulQ", Ev, XX, XX },
+    { "divQ",  Ev, XX, XX },
+    { "idivQ", Ev, XX, XX },
   },
   /* GRP4 */
   {
@@ -1337,8 +1337,8 @@ static const struct dis386 grps[][8] = {
   },
   /* GRP6 */
   {
-    { "sldt",  Ew, XX, XX },
-    { "str",   Ew, XX, XX },
+    { "sldtQ", Ev, XX, XX },
+    { "strQ",  Ev, XX, XX },
     { "lldt",  Ew, XX, XX },
     { "ltr",   Ew, XX, XX },
     { "verr",  Ew, XX, XX },
@@ -1352,7 +1352,7 @@ static const struct dis386 grps[][8] = {
     { "sidtQ",  M, XX, XX },
     { "lgdtQ",  M, XX, XX },
     { "lidtQ",  M, XX, XX },
-    { "smsw",  Ew, XX, XX },
+    { "smswQ", Ev, XX, XX },
     { "(bad)", XX, XX, XX },
     { "lmsw",  Ew, XX, XX },
     { "invlpg",        Ew, XX, XX },
@@ -1612,9 +1612,9 @@ static const struct dis386 prefix_user_table[][4] = {
   },
   /* PREGRP23 */
   {
-    { "movd", Ed, MX, XX },
+    { "movd", Edq, MX, XX },
     { "movq", XM, EX, XX },
-    { "movd", Ed, XM, XX },
+    { "movd", Edq, XM, XX },
     { "(bad)", Ed, XM, XX },
   },
   /* PREGRP24 */
@@ -1808,7 +1808,10 @@ prefix_name (pref, sizeflag)
     case 0x66:
       return (sizeflag & DFLAG) ? "data16" : "data32";
     case 0x67:
-      return (sizeflag & AFLAG) ? "addr16" : "addr32";
+      if (mode_64bit)
+       return (sizeflag & AFLAG) ? "addr32" : "addr64";
+      else
+       return ((sizeflag & AFLAG) && !mode_64bit) ? "addr16" : "addr32";
     case FWAIT_OPCODE:
       return "fwait";
     default:
@@ -1837,25 +1840,17 @@ static char close_char;
 static char separator_char;
 static char scale_char;
 
+/* Here for backwards compatibility.  When gdb stops using
+   print_insn_i386_att and print_insn_i386_intel these functions can
+   disappear, and print_insn_i386 be merged into print_insn.  */
 int
 print_insn_i386_att (pc, info)
      bfd_vma pc;
      disassemble_info *info;
 {
   intel_syntax = 0;
-  names64 = att_names64;
-  names32 = att_names32;
-  names16 = att_names16;
-  names8 = att_names8;
-  names8rex = att_names8rex;
-  names_seg = att_names_seg;
-  index16 = att_index16;
-  open_char = '(';
-  close_char =  ')';
-  separator_char = ',';
-  scale_char = ',';
-
-  return print_insn_i386 (pc, info);
+
+  return print_insn (pc, info);
 }
 
 int
@@ -1864,25 +1859,24 @@ print_insn_i386_intel (pc, info)
      disassemble_info *info;
 {
   intel_syntax = 1;
-  names64 = intel_names64;
-  names32 = intel_names32;
-  names16 = intel_names16;
-  names8 = intel_names8;
-  names8rex = intel_names8rex;
-  names_seg = intel_names_seg;
-  index16 = intel_index16;
-  open_char = '[';
-  close_char = ']';
-  separator_char = '+';
-  scale_char = '*';
-
-  return print_insn_i386 (pc, info);
+
+  return print_insn (pc, info);
 }
 
-static int
+int
 print_insn_i386 (pc, info)
      bfd_vma pc;
      disassemble_info *info;
+{
+  intel_syntax = -1;
+
+  return print_insn (pc, info);
+}
+
+static int
+print_insn (pc, info)
+     bfd_vma pc;
+     disassemble_info *info;
 {
   const struct dis386 *dp;
   int i;
@@ -1890,25 +1884,102 @@ print_insn_i386 (pc, info)
   char *first, *second, *third;
   int needcomma;
   unsigned char uses_SSE_prefix;
-  VOLATILE int sizeflag;
-  VOLATILE int orig_sizeflag;
-
+  int sizeflag;
+  const char *p;
   struct dis_private priv;
-  bfd_byte *inbuf = priv.the_buffer;
 
   mode_64bit = (info->mach == bfd_mach_x86_64_intel_syntax
                || info->mach == bfd_mach_x86_64);
 
+  if (intel_syntax == -1)
+    intel_syntax = (info->mach == bfd_mach_i386_i386_intel_syntax
+                   || info->mach == bfd_mach_x86_64_intel_syntax);
+
   if (info->mach == bfd_mach_i386_i386
       || info->mach == bfd_mach_x86_64
       || info->mach == bfd_mach_i386_i386_intel_syntax
       || info->mach == bfd_mach_x86_64_intel_syntax)
-    sizeflag = AFLAG | DFLAG;
+    priv.orig_sizeflag = AFLAG | DFLAG;
   else if (info->mach == bfd_mach_i386_i8086)
-    sizeflag = 0;
+    priv.orig_sizeflag = 0;
   else
     abort ();
-  orig_sizeflag = sizeflag;
+
+  for (p = info->disassembler_options; p != NULL; )
+    {
+      if (strncmp (p, "x86-64", 6) == 0)
+       {
+         mode_64bit = 1;
+         priv.orig_sizeflag = AFLAG | DFLAG;
+       }
+      else if (strncmp (p, "i386", 4) == 0)
+       {
+         mode_64bit = 0;
+         priv.orig_sizeflag = AFLAG | DFLAG;
+       }
+      else if (strncmp (p, "i8086", 5) == 0)
+       {
+         mode_64bit = 0;
+         priv.orig_sizeflag = 0;
+       }
+      else if (strncmp (p, "intel", 5) == 0)
+       {
+         intel_syntax = 1;
+       }
+      else if (strncmp (p, "att", 3) == 0)
+       {
+         intel_syntax = 0;
+       }
+      else if (strncmp (p, "addr", 4) == 0)
+       {
+         if (p[4] == '1' && p[5] == '6')
+           priv.orig_sizeflag &= ~AFLAG;
+         else if (p[4] == '3' && p[5] == '2')
+           priv.orig_sizeflag |= AFLAG;
+       }
+      else if (strncmp (p, "data", 4) == 0)
+       {
+         if (p[4] == '1' && p[5] == '6')
+           priv.orig_sizeflag &= ~DFLAG;
+         else if (p[4] == '3' && p[5] == '2')
+           priv.orig_sizeflag |= DFLAG;
+       }
+      else if (strncmp (p, "suffix", 6) == 0)
+       priv.orig_sizeflag |= SUFFIX_ALWAYS;
+
+      p = strchr (p, ',');
+      if (p != NULL)
+       p++;
+    }
+
+  if (intel_syntax)
+    {
+      names64 = intel_names64;
+      names32 = intel_names32;
+      names16 = intel_names16;
+      names8 = intel_names8;
+      names8rex = intel_names8rex;
+      names_seg = intel_names_seg;
+      index16 = intel_index16;
+      open_char = '[';
+      close_char = ']';
+      separator_char = '+';
+      scale_char = '*';
+    }
+  else
+    {
+      names64 = att_names64;
+      names32 = att_names32;
+      names16 = att_names16;
+      names8 = att_names8;
+      names8rex = att_names8rex;
+      names_seg = att_names_seg;
+      index16 = att_index16;
+      open_char = '(';
+      close_char =  ')';
+      separator_char = ',';
+      scale_char = ',';
+    }
 
   /* The output looks better if we put 7 bytes on a line, since that
      puts most long word instructions on a single line.  */
@@ -1927,26 +1998,26 @@ print_insn_i386 (pc, info)
 
   the_info = info;
   start_pc = pc;
-  start_codep = inbuf;
-  codep = inbuf;
+  start_codep = priv.the_buffer;
+  codep = priv.the_buffer;
 
   if (setjmp (priv.bailout) != 0)
     {
       const char *name;
 
       /* Getting here means we tried for data but didn't get it.  That
-         means we have an incomplete instruction of some sort.  Just
-         print the first byte as a prefix or a .byte pseudo-op.  */
-      if (codep > inbuf)
+        means we have an incomplete instruction of some sort.  Just
+        print the first byte as a prefix or a .byte pseudo-op.  */
+      if (codep > priv.the_buffer)
        {
-         name = prefix_name (inbuf[0], orig_sizeflag);
+         name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
          if (name != NULL)
            (*info->fprintf_func) (info->stream, "%s", name);
          else
            {
              /* Just print the first byte as a .byte instruction.  */
              (*info->fprintf_func) (info->stream, ".byte 0x%x",
-                                    (unsigned int) inbuf[0]);
+                                    (unsigned int) priv.the_buffer[0]);
            }
 
          return 1;
@@ -1959,6 +2030,7 @@ print_insn_i386 (pc, info)
   ckprefix ();
 
   insn_codep = codep;
+  sizeflag = priv.orig_sizeflag;
 
   FETCH_DATA (info, codep + 1);
   two_source_ops = (*codep == 0x62) || (*codep == 0xc8);
@@ -1969,8 +2041,8 @@ print_insn_i386 (pc, info)
       const char *name;
 
       /* fwait not followed by floating point instruction.  Print the
-         first prefix, which is probably fwait itself.  */
-      name = prefix_name (inbuf[0], orig_sizeflag);
+        first prefix, which is probably fwait itself.  */
+      name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
       if (name == NULL)
        name = INTERNAL_DISASSEMBLER_ERROR;
       (*info->fprintf_func) (info->stream, "%s", name);
@@ -2013,7 +2085,7 @@ print_insn_i386 (pc, info)
       sizeflag ^= AFLAG;
       if (dp->bytemode3 != loop_jcxz_mode || intel_syntax)
        {
-         if (sizeflag & AFLAG)
+         if ((sizeflag & AFLAG) || mode_64bit)
            oappend ("addr32 ");
          else
            oappend ("addr16 ");
@@ -2116,7 +2188,7 @@ print_insn_i386 (pc, info)
     {
       const char *name;
 
-      name = prefix_name (inbuf[0], orig_sizeflag);
+      name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
       if (name == NULL)
        name = INTERNAL_DISASSEMBLER_ERROR;
       (*info->fprintf_func) (info->stream, "%s", name);
@@ -2125,7 +2197,7 @@ print_insn_i386 (pc, info)
   if (rex & ~rex_used)
     {
       const char *name;
-      name = prefix_name (rex | 0x40, orig_sizeflag);
+      name = prefix_name (rex | 0x40, priv.orig_sizeflag);
       if (name == NULL)
        name = INTERNAL_DISASSEMBLER_ERROR;
       (*info->fprintf_func) (info->stream, "%s ", name);
@@ -2189,7 +2261,7 @@ print_insn_i386 (pc, info)
        (*info->print_address_func) ((bfd_vma) (start_pc + codep - start_codep
                                                + op_address[op_index[i]]), info);
       }
-  return codep - inbuf;
+  return codep - priv.the_buffer;
 }
 
 static const char *float_mem[] = {
@@ -2202,7 +2274,7 @@ static const char *float_mem[] = {
   "fsubr{s||s|}",
   "fdiv{s||s|}",
   "fdivr{s||s|}",
-  /*  d9 */
+  /* d9 */
   "fld{s||s|}",
   "(bad)",
   "fst{s||s|}",
@@ -2447,11 +2519,11 @@ dofloat (sizeflag)
       putop (float_mem[(floatop - 0xd8) * 8 + reg], sizeflag);
       obufp = op1out;
       if (floatop == 0xdb)
-        OP_E (x_mode, sizeflag);
+       OP_E (x_mode, sizeflag);
       else if (floatop == 0xdd)
-        OP_E (d_mode, sizeflag);
+       OP_E (d_mode, sizeflag);
       else
-        OP_E (v_mode, sizeflag);
+       OP_E (v_mode, sizeflag);
       return;
     }
   /* Skip mod/rm byte.  */
@@ -2546,47 +2618,45 @@ putop (template, sizeflag)
        case '}':
          break;
        case 'A':
-          if (intel_syntax)
-            break;
-         if (mod != 3
-#ifdef SUFFIX_ALWAYS
-             || (sizeflag & SUFFIX_ALWAYS)
-#endif
-             )
+         if (intel_syntax)
+           break;
+         if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
            *obufp++ = 'b';
          break;
        case 'B':
-          if (intel_syntax)
-            break;
-#ifdef SUFFIX_ALWAYS
+         if (intel_syntax)
+           break;
          if (sizeflag & SUFFIX_ALWAYS)
            *obufp++ = 'b';
-#endif
          break;
        case 'E':               /* For jcxz/jecxz */
-         if (sizeflag & AFLAG)
-           *obufp++ = 'e';
+         if (mode_64bit)
+           {
+             if (sizeflag & AFLAG)
+               *obufp++ = 'r';
+             else
+               *obufp++ = 'e';
+           }
+         else
+           if (sizeflag & AFLAG)
+             *obufp++ = 'e';
          used_prefixes |= (prefixes & PREFIX_ADDR);
          break;
        case 'F':
-          if (intel_syntax)
-            break;
-         if ((prefixes & PREFIX_ADDR)
-#ifdef SUFFIX_ALWAYS
-             || (sizeflag & SUFFIX_ALWAYS)
-#endif
-             )
+         if (intel_syntax)
+           break;
+         if ((prefixes & PREFIX_ADDR) || (sizeflag & SUFFIX_ALWAYS))
            {
              if (sizeflag & AFLAG)
-               *obufp++ = 'l';
+               *obufp++ = mode_64bit ? 'q' : 'l';
              else
-               *obufp++ = 'w';
+               *obufp++ = mode_64bit ? 'l' : 'w';
              used_prefixes |= (prefixes & PREFIX_ADDR);
            }
          break;
        case 'H':
-          if (intel_syntax)
-            break;
+         if (intel_syntax)
+           break;
          if ((prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_CS
              || (prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_DS)
            {
@@ -2600,12 +2670,10 @@ putop (template, sizeflag)
            }
          break;
        case 'L':
-          if (intel_syntax)
-            break;
-#ifdef SUFFIX_ALWAYS
+         if (intel_syntax)
+           break;
          if (sizeflag & SUFFIX_ALWAYS)
            *obufp++ = 'l';
-#endif
          break;
        case 'N':
          if ((prefixes & PREFIX_FWAIT) == 0)
@@ -2621,8 +2689,8 @@ putop (template, sizeflag)
            *obufp++ = 'd';
          break;
        case 'T':
-          if (intel_syntax)
-            break;
+         if (intel_syntax)
+           break;
          if (mode_64bit)
            {
              *obufp++ = 'q';
@@ -2630,14 +2698,11 @@ putop (template, sizeflag)
            }
          /* Fall through.  */
        case 'P':
-          if (intel_syntax)
-            break;
+         if (intel_syntax)
+           break;
          if ((prefixes & PREFIX_DATA)
              || (rex & REX_MODE64)
-#ifdef SUFFIX_ALWAYS
-             || (sizeflag & SUFFIX_ALWAYS)
-#endif
-             )
+             || (sizeflag & SUFFIX_ALWAYS))
            {
              USED_REX (REX_MODE64);
              if (rex & REX_MODE64)
@@ -2653,8 +2718,8 @@ putop (template, sizeflag)
            }
          break;
        case 'U':
-          if (intel_syntax)
-            break;
+         if (intel_syntax)
+           break;
          if (mode_64bit)
            {
              *obufp++ = 'q';
@@ -2662,14 +2727,10 @@ putop (template, sizeflag)
            }
          /* Fall through.  */
        case 'Q':
-          if (intel_syntax)
-            break;
+         if (intel_syntax)
+           break;
          USED_REX (REX_MODE64);
-         if (mod != 3
-#ifdef SUFFIX_ALWAYS
-             || (sizeflag & SUFFIX_ALWAYS)
-#endif
-             )
+         if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
            {
              if (rex & REX_MODE64)
                *obufp++ = 'q';
@@ -2685,7 +2746,7 @@ putop (template, sizeflag)
          break;
        case 'R':
          USED_REX (REX_MODE64);
-          if (intel_syntax)
+         if (intel_syntax)
            {
              if (rex & REX_MODE64)
                {
@@ -2716,9 +2777,8 @@ putop (template, sizeflag)
            used_prefixes |= (prefixes & PREFIX_DATA);
          break;
        case 'S':
-          if (intel_syntax)
-            break;
-#ifdef SUFFIX_ALWAYS
+         if (intel_syntax)
+           break;
          if (sizeflag & SUFFIX_ALWAYS)
            {
              if (rex & REX_MODE64)
@@ -2732,18 +2792,17 @@ putop (template, sizeflag)
                  used_prefixes |= (prefixes & PREFIX_DATA);
                }
            }
-#endif
          break;
        case 'X':
          if (prefixes & PREFIX_DATA)
            *obufp++ = 'd';
          else
            *obufp++ = 's';
-          used_prefixes |= (prefixes & PREFIX_DATA);
+         used_prefixes |= (prefixes & PREFIX_DATA);
          break;
        case 'Y':
-          if (intel_syntax)
-            break;
+         if (intel_syntax)
+           break;
          if (rex & REX_MODE64)
            {
              USED_REX (REX_MODE64);
@@ -2760,7 +2819,7 @@ putop (template, sizeflag)
            *obufp++ = 'w';
          else
            *obufp++ = 'b';
-          if (intel_syntax)
+         if (intel_syntax)
            {
              if (rex)
                {
@@ -2942,10 +3001,11 @@ OP_E (bytemode, sizeflag)
            oappend (names32[rm + add]);
          break;
        case v_mode:
+       case dq_mode:
          USED_REX (REX_MODE64);
          if (rex & REX_MODE64)
            oappend (names64[rm + add]);
-         else if (sizeflag & DFLAG)
+         else if ((sizeflag & DFLAG) || bytemode == dq_mode)
            oappend (names32[rm + add]);
          else
            oappend (names16[rm + add]);
@@ -2967,7 +3027,7 @@ OP_E (bytemode, sizeflag)
   disp = 0;
   append_seg ();
 
-  if (sizeflag & AFLAG) /* 32 bit address mode */
+  if ((sizeflag & AFLAG) || mode_64bit) /* 32 bit address mode */
     {
       int havesib;
       int havebase;
@@ -3001,7 +3061,7 @@ OP_E (bytemode, sizeflag)
          if ((base & 7) == 5)
            {
              havebase = 0;
-             if (mode_64bit && !havesib)
+             if (mode_64bit && !havesib && (sizeflag & AFLAG))
                riprel = 1;
              disp = get32s ();
            }
@@ -3018,94 +3078,97 @@ OP_E (bytemode, sizeflag)
        }
 
       if (!intel_syntax)
-        if (mod != 0 || (base & 7) == 5)
-          {
+       if (mod != 0 || (base & 7) == 5)
+         {
            print_operand_value (scratchbuf, !riprel, disp);
-            oappend (scratchbuf);
+           oappend (scratchbuf);
            if (riprel)
              {
                set_op (disp, 1);
                oappend ("(%rip)");
              }
-          }
+         }
 
       if (havebase || (havesib && (index != 4 || scale != 0)))
        {
-          if (intel_syntax)
-            {
-              switch (bytemode)
-                {
-                case b_mode:
-                  oappend ("BYTE PTR ");
-                  break;
-                case w_mode:
-                  oappend ("WORD PTR ");
-                  break;
-                case v_mode:
-                  oappend ("DWORD PTR ");
-                  break;
-                case d_mode:
-                  oappend ("QWORD PTR ");
-                  break;
-                case m_mode:
+         if (intel_syntax)
+           {
+             switch (bytemode)
+               {
+               case b_mode:
+                 oappend ("BYTE PTR ");
+                 break;
+               case w_mode:
+                 oappend ("WORD PTR ");
+                 break;
+               case v_mode:
+                 oappend ("DWORD PTR ");
+                 break;
+               case d_mode:
+                 oappend ("QWORD PTR ");
+                 break;
+               case m_mode:
                  if (mode_64bit)
                    oappend ("DWORD PTR ");
                  else
                    oappend ("QWORD PTR ");
                  break;
-                case x_mode:
-                  oappend ("XWORD PTR ");
-                  break;
-                default:
-                  break;
-                }
-             }
+               case x_mode:
+                 oappend ("XWORD PTR ");
+                 break;
+               default:
+                 break;
+               }
+            }
          *obufp++ = open_char;
          if (intel_syntax && riprel)
            oappend ("rip + ");
-          *obufp = '\0';
+         *obufp = '\0';
          USED_REX (REX_EXTZ);
          if (!havesib && (rex & REX_EXTZ))
            base += 8;
          if (havebase)
-           oappend (mode_64bit ? names64[base] : names32[base]);
+           oappend (mode_64bit && (sizeflag & AFLAG)
+                    ? names64[base] : names32[base]);
          if (havesib)
            {
              if (index != 4)
                {
-                  if (intel_syntax)
-                    {
-                      if (havebase)
-                        {
-                          *obufp++ = separator_char;
-                          *obufp = '\0';
-                        }
-                      sprintf (scratchbuf, "%s",
-                              mode_64bit ? names64[index] : names32[index]);
-                    }
-                  else
+                 if (intel_syntax)
+                   {
+                     if (havebase)
+                       {
+                         *obufp++ = separator_char;
+                         *obufp = '\0';
+                       }
+                     sprintf (scratchbuf, "%s",
+                              mode_64bit && (sizeflag & AFLAG)
+                              ? names64[index] : names32[index]);
+                   }
+                 else
                    sprintf (scratchbuf, ",%s",
-                            mode_64bit ? names64[index] : names32[index]);
+                            mode_64bit && (sizeflag & AFLAG)
+                            ? names64[index] : names32[index]);
+                 oappend (scratchbuf);
+               }
+             if (!intel_syntax
+                 || (intel_syntax
+                     && bytemode != b_mode
+                     && bytemode != w_mode
+                     && bytemode != v_mode))
+               {
+                 *obufp++ = scale_char;
+                 *obufp = '\0';
+                 sprintf (scratchbuf, "%d", 1 << scale);
                  oappend (scratchbuf);
                }
-              if (!intel_syntax
-                  || (intel_syntax
-                      && bytemode != b_mode
-                      && bytemode != w_mode
-                      && bytemode != v_mode))
-                {
-                  *obufp++ = scale_char;
-                  *obufp = '\0';
-                 sprintf (scratchbuf, "%d", 1 << scale);
-                 oappend (scratchbuf);
-                }
            }
-          if (intel_syntax)
-            if (mod != 0 || (base & 7) == 5)
-              {
+         if (intel_syntax)
+           if (mod != 0 || (base & 7) == 5)
+             {
                /* Don't print zero displacements.  */
-                if (disp != 0)
-                  {
+               if (disp != 0)
+                 {
                    if ((bfd_signed_vma) disp > 0)
                      {
                        *obufp++ = '+';
@@ -3113,17 +3176,17 @@ OP_E (bytemode, sizeflag)
                      }
 
                    print_operand_value (scratchbuf, 0, disp);
-                    oappend (scratchbuf);
-                  }
-              }
+                   oappend (scratchbuf);
+                 }
+             }
 
          *obufp++ = close_char;
-          *obufp = '\0';
+         *obufp = '\0';
        }
       else if (intel_syntax)
-        {
-          if (mod != 0 || (base & 7) == 5)
-            {
+       {
+         if (mod != 0 || (base & 7) == 5)
+           {
              if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
                              | PREFIX_ES | PREFIX_FS | PREFIX_GS))
                ;
@@ -3133,9 +3196,9 @@ OP_E (bytemode, sizeflag)
                  oappend (":");
                }
              print_operand_value (scratchbuf, 1, disp);
-              oappend (scratchbuf);
-            }
-        }
+             oappend (scratchbuf);
+           }
+       }
     }
   else
     { /* 16 bit address mode */
@@ -3163,19 +3226,19 @@ OP_E (bytemode, sizeflag)
        }
 
       if (!intel_syntax)
-        if (mod != 0 || (rm & 7) == 6)
-          {
+       if (mod != 0 || (rm & 7) == 6)
+         {
            print_operand_value (scratchbuf, 0, disp);
-            oappend (scratchbuf);
-          }
+           oappend (scratchbuf);
+         }
 
       if (mod != 0 || (rm & 7) != 6)
        {
          *obufp++ = open_char;
-          *obufp = '\0';
+         *obufp = '\0';
          oappend (index16[rm + add]);
-          *obufp++ = close_char;
-          *obufp = '\0';
+         *obufp++ = close_char;
+         *obufp = '\0';
        }
     }
 }
@@ -3322,9 +3385,9 @@ OP_REG (code, sizeflag)
     {
     case indir_dx_reg:
       if (intel_syntax)
-        s = "[dx]";
+       s = "[dx]";
       else
-        s = "(%dx)";
+       s = "(%dx)";
       break;
     case ax_reg: case cx_reg: case dx_reg: case bx_reg:
     case sp_reg: case bp_reg: case si_reg: case di_reg:
@@ -3380,9 +3443,9 @@ OP_IMREG (code, sizeflag)
     {
     case indir_dx_reg:
       if (intel_syntax)
-        s = "[dx]";
+       s = "[dx]";
       else
-        s = "(%dx)";
+       s = "(%dx)";
       break;
     case ax_reg: case cx_reg: case dx_reg: case bx_reg:
     case sp_reg: case bp_reg: case si_reg: case di_reg:
@@ -3656,7 +3719,7 @@ OP_OFF (bytemode, sizeflag)
 
   append_seg ();
 
-  if (sizeflag & AFLAG)
+  if ((sizeflag & AFLAG) || mode_64bit)
     off = get32 ();
   else
     off = get16 ();
@@ -3664,7 +3727,7 @@ OP_OFF (bytemode, sizeflag)
   if (intel_syntax)
     {
       if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
-                       | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
+                       | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
        {
          oappend (names_seg[ds_reg - es_reg]);
          oappend (":");
@@ -3694,7 +3757,7 @@ OP_OFF64 (bytemode, sizeflag)
   if (intel_syntax)
     {
       if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
-                       | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
+                       | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
        {
          oappend (names_seg[ds_reg - es_reg]);
          oappend (":");
@@ -3717,7 +3780,12 @@ ptr_reg (code, sizeflag)
 
   USED_REX (REX_MODE64);
   if (rex & REX_MODE64)
-    s = names64[code - eAX_reg];
+    {
+      if (!(sizeflag & AFLAG))
+       s = names32[code - eAX_reg];
+      else
+       s = names64[code - eAX_reg];
+    }
   else if (sizeflag & AFLAG)
     s = names32[code - eAX_reg];
   else
@@ -3904,7 +3972,7 @@ OP_XS (bytemode, sizeflag)
     BadOp ();
 }
 
-static const char *Suffix3DNow[] = {
+static const char *const Suffix3DNow[] = {
 /* 00 */       NULL,           NULL,           NULL,           NULL,
 /* 04 */       NULL,           NULL,           NULL,           NULL,
 /* 08 */       NULL,           NULL,           NULL,           NULL,