Rewrite prefix processing.
[deliverable/binutils-gdb.git] / opcodes / i386-dis.c
index a8bfa0f3433df56df7aee62fc7f19432ed154b9c..4d71a00909dba7bdd4123146a6bb1ffe2bdc931b 100644 (file)
@@ -42,9 +42,6 @@
 
 #include <setjmp.h>
 
-static int fetch_data (struct disassemble_info *, bfd_byte *);
-static void ckprefix (void);
-static const char *prefix_name (int, int);
 static int print_insn (bfd_vma, disassemble_info *);
 static void dofloat (int);
 static void OP_ST (int, int);
@@ -1992,12 +1989,17 @@ static char scratchbuf[100];
 static unsigned char *start_codep;
 static unsigned char *insn_codep;
 static unsigned char *codep;
-static const char *lock_prefix;
-static const char *data_prefix;
-static const char *addr_prefix;
-static const char *repz_prefix;
-static const char *repnz_prefix;
-static const char **all_prefixes[5];
+static int last_lock_prefix;
+static int last_repz_prefix;
+static int last_repnz_prefix;
+static int last_data_prefix;
+static int last_addr_prefix;
+static int last_rex_prefix;
+static int last_seg_prefix;
+#define MAX_CODE_LENGTH 15
+/* We can up to 14 prefixes since the maximum instruction length is
+   15bytes.  */
+static int all_prefixes[MAX_CODE_LENGTH - 1];
 static disassemble_info *the_info;
 static struct
   {
@@ -9570,20 +9572,37 @@ static const struct dis386 rm_table[][8] = {
 
 #define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
 
-static void
+/* We use the high bit to indicate different name for the same
+   prefix.  */
+#define ADDR16_PREFIX  (0x67 | 0x100)
+#define ADDR32_PREFIX  (0x67 | 0x200)
+#define DATA16_PREFIX  (0x66 | 0x100)
+#define DATA32_PREFIX  (0x66 | 0x200)
+#define REP_PREFIX     (0xf3 | 0x100)
+
+static int
 ckprefix (void)
 {
-  int newrex, i;
+  int newrex, i, length;
   rex = 0;
   rex_original = 0;
   rex_ignored = 0;
   prefixes = 0;
   used_prefixes = 0;
   rex_used = 0;
+  last_lock_prefix = -1;
+  last_repz_prefix = -1;
+  last_repnz_prefix = -1;
+  last_data_prefix = -1;
+  last_addr_prefix = -1;
+  last_rex_prefix = -1;
+  last_seg_prefix = -1;
   for (i = 0; i < (int) ARRAY_SIZE (all_prefixes); i++)
     all_prefixes[i] = 0;
   i = 0;
-  while (1)
+  length = 0;
+  /* The maximum instruction length is 15bytes.  */
+  while (length < MAX_CODE_LENGTH - 1)
     {
       FETCH_DATA (the_info, codep + 1);
       newrex = 0;
@@ -9606,68 +9625,55 @@ ckprefix (void)
        case 0x4d:
        case 0x4e:
        case 0x4f:
-           if (address_mode == mode_64bit)
-             newrex = *codep;
-           else
-             return;
+         if (address_mode == mode_64bit)
+           newrex = *codep;
+         else
+           return 1;
+         last_rex_prefix = i;
          break;
        case 0xf3:
-         if ((prefixes & PREFIX_REPZ) == 0)
-           {
-             all_prefixes[i] = &repz_prefix;
-             i++;
-           }
          prefixes |= PREFIX_REPZ;
+         last_repz_prefix = i;
          break;
        case 0xf2:
-         if ((prefixes & PREFIX_REPNZ) == 0)
-           {
-             all_prefixes[i] = &repnz_prefix;
-             i++;
-           }
          prefixes |= PREFIX_REPNZ;
+         last_repnz_prefix = i;
          break;
        case 0xf0:
-         if ((prefixes & PREFIX_LOCK) == 0)
-           {
-             all_prefixes[i] = &lock_prefix;
-             i++;
-           }
          prefixes |= PREFIX_LOCK;
+         last_lock_prefix = i;
          break;
        case 0x2e:
          prefixes |= PREFIX_CS;
+         last_seg_prefix = i;
          break;
        case 0x36:
          prefixes |= PREFIX_SS;
+         last_seg_prefix = i;
          break;
        case 0x3e:
          prefixes |= PREFIX_DS;
+         last_seg_prefix = i;
          break;
        case 0x26:
          prefixes |= PREFIX_ES;
+         last_seg_prefix = i;
          break;
        case 0x64:
          prefixes |= PREFIX_FS;
+         last_seg_prefix = i;
          break;
        case 0x65:
          prefixes |= PREFIX_GS;
+         last_seg_prefix = i;
          break;
        case 0x66:
-         if ((prefixes & PREFIX_DATA) == 0)
-           {
-             all_prefixes[i] = &data_prefix;
-             i++;
-           }
          prefixes |= PREFIX_DATA;
+         last_data_prefix = i;
          break;
        case 0x67:
-         if ((prefixes & PREFIX_ADDR) == 0)
-           {
-             all_prefixes[i] = &addr_prefix;
-             i++;
-           }
          prefixes |= PREFIX_ADDR;
+         last_addr_prefix = i;
          break;
        case FWAIT_OPCODE:
          /* fwait is really an instruction.  If there are prefixes
@@ -9677,22 +9683,48 @@ ckprefix (void)
            {
              prefixes |= PREFIX_FWAIT;
              codep++;
-             return;
+             return 1;
            }
          prefixes = PREFIX_FWAIT;
          break;
        default:
-         return;
+         return 1;
        }
       /* Rex is ignored when followed by another prefix.  */
       if (rex)
        {
          rex_used = rex;
-         return;
+         return 1;
        }
+      if (*codep != FWAIT_OPCODE)
+       all_prefixes[i++] = *codep;
       rex = newrex;
       rex_original = rex;
       codep++;
+      length++;
+    }
+  return 0;
+}
+
+static int
+seg_prefix (int pref)
+{
+  switch (pref)
+    {
+    case 0x2e:
+      return PREFIX_CS;
+    case 0x36:
+      return PREFIX_SS;
+    case 0x3e:
+      return PREFIX_DS;
+    case 0x26:
+      return PREFIX_ES;
+    case 0x64:
+      return PREFIX_FS;
+    case 0x65:
+      return PREFIX_GS;
+    default:
+      return 0;
     }
 }
 
@@ -9769,6 +9801,16 @@ prefix_name (int pref, int sizeflag)
        return (sizeflag & AFLAG) ? "addr16" : "addr32";
     case FWAIT_OPCODE:
       return "fwait";
+    case ADDR16_PREFIX:
+      return "addr16";
+    case ADDR32_PREFIX:
+      return "addr32";
+    case DATA16_PREFIX:
+      return "data16";
+    case DATA32_PREFIX:
+      return "data32";
+    case REP_PREFIX:
+      return "rep";
     default:
       return NULL;
     }
@@ -9903,7 +9945,7 @@ get_valid_dis386 (const struct dis386 *dp, disassemble_info *info)
          if (prefixes & PREFIX_REPZ)
            {
              index = 1;
-             repz_prefix = NULL;
+             all_prefixes[last_repz_prefix] = 0;
            }
          else
            {
@@ -9913,7 +9955,7 @@ get_valid_dis386 (const struct dis386 *dp, disassemble_info *info)
              if (prefixes & PREFIX_REPNZ)
                {
                  index = 3;
-                 repnz_prefix = NULL;
+                 all_prefixes[last_repnz_prefix] = 0;
                }
              else
                {
@@ -9921,7 +9963,7 @@ get_valid_dis386 (const struct dis386 *dp, disassemble_info *info)
                  if (prefixes & PREFIX_DATA)
                    {
                      index = 2;
-                     data_prefix = NULL;
+                     all_prefixes[last_data_prefix] = 0;
                    }
                }
            }
@@ -10142,8 +10184,8 @@ print_insn (bfd_vma pc, disassemble_info *info)
   const char *p;
   struct dis_private priv;
   unsigned char op;
-  char prefix_obuf[32];
-  char *prefix_obufp;
+  int prefix_length;
+  int default_prefixes;
 
   if (info->mach == bfd_mach_x86_64_intel_syntax
       || info->mach == bfd_mach_x86_64
@@ -10315,26 +10357,28 @@ print_insn (bfd_vma pc, disassemble_info *info)
     }
 
   obufp = obuf;
-  ckprefix ();
+  sizeflag = priv.orig_sizeflag;
+
+  if (!ckprefix () || rex_used)
+    {
+      /* Too many prefixes or unused REX prefixes.  */
+      for (i = 0;
+          all_prefixes[i] && i < (int) ARRAY_SIZE (all_prefixes);
+          i++)
+       (*info->fprintf_func) (info->stream, "%s",
+                              prefix_name (all_prefixes[i], sizeflag));
+      return 1;
+    }
 
   insn_codep = codep;
-  sizeflag = priv.orig_sizeflag;
 
   FETCH_DATA (info, codep + 1);
   two_source_ops = (*codep == 0x62) || (*codep == 0xc8);
 
   if (((prefixes & PREFIX_FWAIT)
-       && ((*codep < 0xd8) || (*codep > 0xdf)))
-      || (rex && rex_used))
+       && ((*codep < 0xd8) || (*codep > 0xdf))))
     {
-      const char *name;
-
-      /* fwait not followed by floating point instruction, or rex followed
-        by other prefixes.  Print the first prefix.  */
-      name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
-      if (name == NULL)
-       name = INTERNAL_DISASSEMBLER_ERROR;
-      (*info->fprintf_func) (info->stream, "%s", name);
+      (*info->fprintf_func) (info->stream, "fwait");
       return 1;
     }
 
@@ -10357,44 +10401,26 @@ print_insn (bfd_vma pc, disassemble_info *info)
     }
 
   if ((prefixes & PREFIX_REPZ))
-    {
-      repz_prefix = "repz ";
-      used_prefixes |= PREFIX_REPZ;
-    }
-  else
-    repz_prefix = NULL;
-
+    used_prefixes |= PREFIX_REPZ;
   if ((prefixes & PREFIX_REPNZ))
-    {
-      repnz_prefix = "repnz ";
-      used_prefixes |= PREFIX_REPNZ;
-    }
-  else
-    repnz_prefix = NULL;
-
+    used_prefixes |= PREFIX_REPNZ;
   if ((prefixes & PREFIX_LOCK))
-    {
-      lock_prefix = "lock ";
-      used_prefixes |= PREFIX_LOCK;
-    }
-  else
-    lock_prefix = NULL;
+    used_prefixes |= PREFIX_LOCK;
 
-  addr_prefix = NULL;
+  default_prefixes = 0;
   if (prefixes & PREFIX_ADDR)
     {
       sizeflag ^= AFLAG;
       if (dp->op[2].bytemode != loop_jcxz_mode || intel_syntax)
        {
          if ((sizeflag & AFLAG) || address_mode == mode_64bit)
-           addr_prefix = "addr32 ";
+           all_prefixes[last_addr_prefix] = ADDR32_PREFIX;
          else
-           addr_prefix = "addr16 ";
-         used_prefixes |= PREFIX_ADDR;
+           all_prefixes[last_addr_prefix] = ADDR16_PREFIX;
+         default_prefixes |= PREFIX_ADDR;
        }
     }
 
-  data_prefix = NULL;
   if ((prefixes & PREFIX_DATA))
     {
       sizeflag ^= DFLAG;
@@ -10403,10 +10429,15 @@ print_insn (bfd_vma pc, disassemble_info *info)
          && !intel_syntax)
        {
          if (sizeflag & DFLAG)
-           data_prefix = "data32 ";
+           all_prefixes[last_data_prefix] = DATA32_PREFIX;
          else
-           data_prefix = "data16 ";
-         used_prefixes |= PREFIX_DATA;
+           all_prefixes[last_data_prefix] = DATA16_PREFIX;
+         default_prefixes |= PREFIX_DATA;
+       }
+      else if (rex & REX_W)
+       {
+         /* REX_W will override PREFIX_DATA.  */
+         default_prefixes |= PREFIX_DATA;
        }
     }
 
@@ -10445,36 +10476,62 @@ print_insn (bfd_vma pc, disassemble_info *info)
      separately.  If we don't do this, we'll wind up printing an
      instruction stream which does not precisely correspond to the
      bytes we are disassembling.  */
-  if ((prefixes & ~used_prefixes) != 0)
+  if ((prefixes & ~(used_prefixes | default_prefixes)) != 0)
     {
-      const char *name;
-
-      name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
-      if (name == NULL)
-       name = INTERNAL_DISASSEMBLER_ERROR;
-      (*info->fprintf_func) (info->stream, "%s", name);
-      return 1;
-    }
-  if ((rex_original & ~rex_used) || rex_ignored)
-    {
-      const char *name;
-      name = prefix_name (rex_original, priv.orig_sizeflag);
-      if (name == NULL)
-       name = INTERNAL_DISASSEMBLER_ERROR;
-      (*info->fprintf_func) (info->stream, "%s ", name);
+      for (i = 0; i < (int) ARRAY_SIZE (all_prefixes); i++)
+       if (all_prefixes[i])
+         {
+           const char *name;
+           name = prefix_name (all_prefixes[i], priv.orig_sizeflag);
+           if (name == NULL)
+             name = INTERNAL_DISASSEMBLER_ERROR;
+           (*info->fprintf_func) (info->stream, "%s", name);
+           return 1;
+         }
     }
 
-  prefix_obuf[0] = 0;
-  prefix_obufp = prefix_obuf;
+  /* Check if the REX prefix used.  */
+  if ((rex ^ rex_used) == 0)
+    all_prefixes[last_rex_prefix] = 0;
+
+  /* Check if the SEG prefix used.  */
+  if ((prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS | PREFIX_ES
+                  | PREFIX_FS | PREFIX_GS)) != 0
+      && (used_prefixes
+         & seg_prefix (all_prefixes[last_seg_prefix])) != 0)
+    all_prefixes[last_seg_prefix] = 0;
+
+  /* Check if the ADDR prefix used.  */
+  if ((prefixes & PREFIX_ADDR) != 0
+      && (used_prefixes & PREFIX_ADDR) != 0)
+    all_prefixes[last_addr_prefix] = 0;
+
+  /* Check if the DATA prefix used.  */
+  if ((prefixes & PREFIX_DATA) != 0
+      && (used_prefixes & PREFIX_DATA) != 0)
+    all_prefixes[last_data_prefix] = 0;
+
+  prefix_length = 0;
   for (i = 0; i < (int) ARRAY_SIZE (all_prefixes); i++)
-    if (all_prefixes[i] && *all_prefixes[i])
-      prefix_obufp = stpcpy (prefix_obufp, *all_prefixes[i]);
+    if (all_prefixes[i])
+      {
+       const char *name;
+       name = prefix_name (all_prefixes[i], sizeflag);
+       if (name == NULL)
+         abort ();
+       prefix_length += strlen (name) + 1;
+       (*info->fprintf_func) (info->stream, "%s ", name);
+      }
 
-  if (prefix_obuf[0] != 0)
-    (*info->fprintf_func) (info->stream, "%s", prefix_obuf);
+  /* Check maximum code length.  */
+  if ((codep - start_codep) > MAX_CODE_LENGTH)
+    {
+      (*info->fprintf_func) (info->stream, "(bad)");
+      return MAX_CODE_LENGTH;
+    }
 
   obufp = mnemonicendp;
-  for (i = strlen (obuf) + strlen (prefix_obuf); i < 6; i++)
+  for (i = strlen (obuf) + prefix_length; i < 6; i++)
     oappend (" ");
   oappend (" ");
   (*info->fprintf_func) (info->stream, "%s", obuf);
@@ -11013,11 +11070,14 @@ case_B:
            {
              if (rex & REX_W)
                *obufp++ = 'q';
-             else if (sizeflag & DFLAG)
-               *obufp++ = intel_syntax ? 'd' : 'l';
              else
-               *obufp++ = 'w';
-             used_prefixes |= (prefixes & PREFIX_DATA);
+               {
+                 if (sizeflag & DFLAG)
+                   *obufp++ = intel_syntax ? 'd' : 'l';
+                 else
+                   *obufp++ = 'w';
+                 used_prefixes |= (prefixes & PREFIX_DATA);
+               }
            }
          else
            *obufp++ = 'w';
@@ -11152,8 +11212,8 @@ case_L:
                      *obufp++ = 'l';
                   else
                     *obufp++ = 'w';
+                  used_prefixes |= (prefixes & PREFIX_DATA);
                }
-             used_prefixes |= (prefixes & PREFIX_DATA);
            }
          break;
        case 'U':
@@ -11184,8 +11244,8 @@ case_Q:
                        *obufp++ = intel_syntax ? 'd' : 'l';
                      else
                        *obufp++ = 'w';
+                     used_prefixes |= (prefixes & PREFIX_DATA);
                    }
-                 used_prefixes |= (prefixes & PREFIX_DATA);
                }
            }
          else
@@ -11311,11 +11371,14 @@ case_S:
              else
                *obufp++ = 's';
            }
-         else if (prefixes & PREFIX_DATA)
-           *obufp++ = 'd';
          else
-           *obufp++ = 's';
-         used_prefixes |= (prefixes & PREFIX_DATA);
+           {
+             if (prefixes & PREFIX_DATA)
+               *obufp++ = 'd';
+             else
+               *obufp++ = 's';
+             used_prefixes |= (prefixes & PREFIX_DATA);
+           }
          break;
        case 'Y':
          if (l == 0 && len == 1)
@@ -11561,7 +11624,6 @@ intel_operand_size (int bytemode, int sizeflag)
       if (address_mode == mode_64bit && (sizeflag & DFLAG))
        {
          oappend ("QWORD PTR ");
-         used_prefixes |= (prefixes & PREFIX_DATA);
          break;
        }
       /* FALLTHRU */
@@ -11571,11 +11633,14 @@ intel_operand_size (int bytemode, int sizeflag)
       USED_REX (REX_W);
       if (rex & REX_W)
        oappend ("QWORD PTR ");
-      else if ((sizeflag & DFLAG) || bytemode == dq_mode)
-       oappend ("DWORD PTR ");
       else
-       oappend ("WORD PTR ");
-      used_prefixes |= (prefixes & PREFIX_DATA);
+       {
+         if ((sizeflag & DFLAG) || bytemode == dq_mode)
+           oappend ("DWORD PTR ");
+         else
+           oappend ("WORD PTR ");
+         used_prefixes |= (prefixes & PREFIX_DATA);
+       }
       break;
     case z_mode:
       if ((rex & REX_W) || (sizeflag & DFLAG))
@@ -11727,7 +11792,6 @@ OP_E_register (int bytemode, int sizeflag)
       if (address_mode == mode_64bit && (sizeflag & DFLAG))
        {
          names = names64;
-         used_prefixes |= (prefixes & PREFIX_DATA);
          break;
        }
       bytemode = v_mode;
@@ -11741,13 +11805,16 @@ OP_E_register (int bytemode, int sizeflag)
       USED_REX (REX_W);
       if (rex & REX_W)
        names = names64;
-      else if ((sizeflag & DFLAG) 
-              || (bytemode != v_mode
-                  && bytemode != v_swap_mode))
-       names = names32;
       else
-       names = names16;
-      used_prefixes |= (prefixes & PREFIX_DATA);
+       {
+         if ((sizeflag & DFLAG) 
+             || (bytemode != v_mode
+                 && bytemode != v_swap_mode))
+           names = names32;
+         else
+           names = names16;
+         used_prefixes |= (prefixes & PREFIX_DATA);
+       }
       break;
     case 0:
       return;
@@ -11936,7 +12003,9 @@ OP_E_memory (int bytemode, int sizeflag)
        }
     }
   else
-    { /* 16 bit address mode */
+    {
+      /* 16 bit address mode */
+      used_prefixes |= prefixes & PREFIX_ADDR;
       switch (modrm.mod)
        {
        case 0:
@@ -12063,11 +12132,14 @@ OP_G (int bytemode, int sizeflag)
       USED_REX (REX_W);
       if (rex & REX_W)
        oappend (names64[modrm.reg + add]);
-      else if ((sizeflag & DFLAG) || bytemode != v_mode)
-       oappend (names32[modrm.reg + add]);
       else
-       oappend (names16[modrm.reg + add]);
-      used_prefixes |= (prefixes & PREFIX_DATA);
+       {
+         if ((sizeflag & DFLAG) || bytemode != v_mode)
+           oappend (names32[modrm.reg + add]);
+         else
+           oappend (names16[modrm.reg + add]);
+         used_prefixes |= (prefixes & PREFIX_DATA);
+       }
       break;
     case m_mode:
       if (address_mode == mode_64bit)
@@ -12206,11 +12278,14 @@ OP_REG (int code, int sizeflag)
       USED_REX (REX_W);
       if (rex & REX_W)
        s = names64[code - eAX_reg + add];
-      else if (sizeflag & DFLAG)
-       s = names32[code - eAX_reg + add];
       else
-       s = names16[code - eAX_reg + add];
-      used_prefixes |= (prefixes & PREFIX_DATA);
+       {
+         if (sizeflag & DFLAG)
+           s = names32[code - eAX_reg + add];
+         else
+           s = names16[code - eAX_reg + add];
+         used_prefixes |= (prefixes & PREFIX_DATA);
+       }
       break;
     default:
       s = INTERNAL_DISASSEMBLER_ERROR;
@@ -12253,11 +12328,14 @@ OP_IMREG (int code, int sizeflag)
       USED_REX (REX_W);
       if (rex & REX_W)
        s = names64[code - eAX_reg];
-      else if (sizeflag & DFLAG)
-       s = names32[code - eAX_reg];
       else
-       s = names16[code - eAX_reg];
-      used_prefixes |= (prefixes & PREFIX_DATA);
+       {
+         if (sizeflag & DFLAG)
+           s = names32[code - eAX_reg];
+         else
+           s = names16[code - eAX_reg];
+         used_prefixes |= (prefixes & PREFIX_DATA);
+       }
       break;
     case z_mode_ax_reg:
       if ((rex & REX_W) || (sizeflag & DFLAG))
@@ -12298,17 +12376,20 @@ OP_I (int bytemode, int sizeflag)
       USED_REX (REX_W);
       if (rex & REX_W)
        op = get32s ();
-      else if (sizeflag & DFLAG)
-       {
-         op = get32 ();
-         mask = 0xffffffff;
-       }
       else
        {
-         op = get16 ();
-         mask = 0xfffff;
+         if (sizeflag & DFLAG)
+           {
+             op = get32 ();
+             mask = 0xffffffff;
+           }
+         else
+           {
+             op = get16 ();
+             mask = 0xfffff;
+           }
+         used_prefixes |= (prefixes & PREFIX_DATA);
        }
-      used_prefixes |= (prefixes & PREFIX_DATA);
       break;
     case w_mode:
       mask = 0xfffff;
@@ -12353,17 +12434,20 @@ OP_I64 (int bytemode, int sizeflag)
       USED_REX (REX_W);
       if (rex & REX_W)
        op = get64 ();
-      else if (sizeflag & DFLAG)
-       {
-         op = get32 ();
-         mask = 0xffffffff;
-       }
       else
        {
-         op = get16 ();
-         mask = 0xfffff;
+         if (sizeflag & DFLAG)
+           {
+             op = get32 ();
+             mask = 0xffffffff;
+           }
+         else
+           {
+             op = get16 ();
+             mask = 0xfffff;
+           }
+         used_prefixes |= (prefixes & PREFIX_DATA);
        }
-      used_prefixes |= (prefixes & PREFIX_DATA);
       break;
     case w_mode:
       mask = 0xfffff;
@@ -12400,19 +12484,22 @@ OP_sI (int bytemode, int sizeflag)
       USED_REX (REX_W);
       if (rex & REX_W)
        op = get32s ();
-      else if (sizeflag & DFLAG)
-       {
-         op = get32s ();
-         mask = 0xffffffff;
-       }
       else
        {
-         mask = 0xffffffff;
-         op = get16 ();
-         if ((op & 0x8000) != 0)
-           op -= 0x10000;
+         if (sizeflag & DFLAG)
+           {
+             op = get32s ();
+             mask = 0xffffffff;
+           }
+         else
+           {
+             mask = 0xffffffff;
+             op = get16 ();
+             if ((op & 0x8000) != 0)
+               op -= 0x10000;
+           }
+         used_prefixes |= (prefixes & PREFIX_DATA);
        }
-      used_prefixes |= (prefixes & PREFIX_DATA);
       break;
     case w_mode:
       op = get16 ();
@@ -12446,6 +12533,7 @@ OP_J (int bytemode, int sizeflag)
        disp -= 0x100;
       break;
     case v_mode:
+      USED_REX (REX_W);
       if ((sizeflag & DFLAG) || (rex & REX_W))
        disp = get32s ();
       else
@@ -12462,7 +12550,8 @@ OP_J (int bytemode, int sizeflag)
            segment = ((start_pc + codep - start_codep)
                       & ~((bfd_vma) 0xffff));
        }
-      used_prefixes |= (prefixes & PREFIX_DATA);
+      if (!(rex & REX_W))
+       used_prefixes |= (prefixes & PREFIX_DATA);
       break;
     default:
       oappend (INTERNAL_DISASSEMBLER_ERROR);
@@ -12653,7 +12742,7 @@ OP_C (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
     }
   else if (address_mode != mode_64bit && (prefixes & PREFIX_LOCK))
     {
-      lock_prefix = NULL;
+      all_prefixes[last_lock_prefix] = 0;
       used_prefixes |= PREFIX_LOCK;
       add = 8;
     }
@@ -13092,7 +13181,7 @@ OP_Monitor (int bytemode ATTRIBUTE_UNUSED,
       else
        {
          /* Remove "addr16/addr32".  */
-         addr_prefix = NULL;
+         all_prefixes[last_addr_prefix] = 0;
          op1_names = (address_mode != mode_32bit
                       ? names32 : names16);
          used_prefixes |= PREFIX_ADDR;
@@ -13121,7 +13210,7 @@ REP_Fixup (int bytemode, int sizeflag)
   /* The 0xf3 prefix should be displayed as "rep" for ins, outs, movs,
      lods and stos.  */
   if (prefixes & PREFIX_REPZ)
-    repz_prefix = "rep ";
+    all_prefixes[last_repz_prefix] = REP_PREFIX;
 
   switch (bytemode)
     {
@@ -13199,11 +13288,14 @@ CRC32_Fixup (int bytemode, int sizeflag)
       USED_REX (REX_W);
       if (rex & REX_W)
        *p++ = 'q';
-      else if (sizeflag & DFLAG)
-       *p++ = 'l';
-      else
-       *p++ = 'w';
-      used_prefixes |= (prefixes & PREFIX_DATA);
+      else 
+       {
+         if (sizeflag & DFLAG)
+           *p++ = 'l';
+         else
+           *p++ = 'w';
+         used_prefixes |= (prefixes & PREFIX_DATA);
+       }
       break;
     default:
       oappend (INTERNAL_DISASSEMBLER_ERROR);
@@ -13636,12 +13728,15 @@ MOVBE_Fixup (int bytemode, int sizeflag)
        {
          if (rex & REX_W)
            *p++ = 'q';
-         else if (sizeflag & DFLAG)
-           *p++ = 'l';
          else
-           *p++ = 'w';
+           {
+             if (sizeflag & DFLAG)
+               *p++ = 'l';
+             else
+               *p++ = 'w';
+             used_prefixes |= (prefixes & PREFIX_DATA);
+           }
        }
-      used_prefixes |= (prefixes & PREFIX_DATA);
       break;
     default:
       oappend (INTERNAL_DISASSEMBLER_ERROR);
This page took 0.052929 seconds and 4 git commands to generate.