2003-10-03 Andrew Cagney <cagney@redhat.com>
[deliverable/binutils-gdb.git] / opcodes / mips-dis.c
index a2f68e96667491fadcbd5e42855ff016ffa9e369..43fcb3ca79a2b5cd957b82a8db30e66399c9a0ec 100644 (file)
@@ -1,6 +1,6 @@
 /* Print mips instructions for GDB, the GNU debugger, or for objdump.
    Copyright 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002
+   2000, 2001, 2002, 2003
    Free Software Foundation, Inc.
    Contributed by Nobuyuki Hikichi(hikichi@sra.co.jp).
 
@@ -50,7 +50,7 @@ static int _print_insn_mips
   PARAMS ((bfd_vma, struct disassemble_info *, enum bfd_endian));
 static int print_insn_mips
   PARAMS ((bfd_vma, unsigned long int, struct disassemble_info *));
-static int print_insn_arg
+static void print_insn_args
   PARAMS ((const char *, unsigned long, bfd_vma, struct disassemble_info *));
 static int print_insn_mips16
   PARAMS ((bfd_vma, struct disassemble_info *));
@@ -347,6 +347,10 @@ const struct mips_arch_choice mips_arch_choices[] = {
     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
   { "r6000",   1, bfd_mach_mips6000, CPU_R6000, ISA_MIPS2,
     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
+  { "rm7000",  1, bfd_mach_mips7000, CPU_RM7000, ISA_MIPS4,
+    mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
+  { "rm9000",  1, bfd_mach_mips7000, CPU_RM7000, ISA_MIPS4,
+    mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
   { "r8000",   1, bfd_mach_mips8000, CPU_R8000, ISA_MIPS4,
     mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
   { "r10000",  1, bfd_mach_mips10000, CPU_R10000, ISA_MIPS4,
@@ -380,6 +384,12 @@ const struct mips_arch_choice mips_arch_choices[] = {
     mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264),
     mips_hwr_names_numeric },
 
+  { "mips64r2",        1, bfd_mach_mipsisa64r2, CPU_MIPS64R2,
+    ISA_MIPS64R2 | INSN_MIPS16 | INSN_MIPS3D | INSN_MDMX,
+    mips_cp0_names_mips3264r2,
+    mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
+    mips_hwr_names_mips3264r2 },
+
   { "sb1",     1, bfd_mach_mips_sb1, CPU_SB1,
     ISA_MIPS64 | INSN_MIPS3D | INSN_SB1,
     mips_cp0_names_sb1,
@@ -495,11 +505,11 @@ set_default_mips_dis_options (info)
   mips_hwr_names = mips_hwr_names_numeric;
 
   /* If an ELF "newabi" binary, use the n32/(n)64 GPR names.  */
-  if (info->flavour == bfd_target_elf_flavour && info->symbols != NULL)
+  if (info->flavour == bfd_target_elf_flavour && info->section != NULL)
     {
       Elf_Internal_Ehdr *header;
 
-      header = elf_elfheader (bfd_asymbol_bfd (*(info->symbols)));
+      header = elf_elfheader (info->section->owner);
       if (is_newabi (header))
        mips_gpr_names = mips_gpr_names_newabi;
     }
@@ -664,342 +674,360 @@ lookup_mips_cp0sel_name(names, len, cp0reg, sel)
 \f
 /* Print insn arguments for 32/64-bit code.  */
 
-static int
-print_insn_arg (d, l, pc, info)
+static void
+print_insn_args (d, l, pc, info)
      const char *d;
      register unsigned long int l;
      bfd_vma pc;
      struct disassemble_info *info;
 {
-  int op, delta, consumed;
+  int op, delta;
+  unsigned int lsb, msb, msbd;
 
-  consumed = 1;
-  switch (*d)
-    {
-    case ',':
-    case '(':
-    case ')':
-    case '[':
-    case ']':
-      (*info->fprintf_func) (info->stream, "%c", *d);
-      break;
+  lsb = 0;
 
-    case '+':
-      /* Extension character; switch for second char.  */
-      d++;
-      consumed++;
+  for (; *d != '\0'; d++)
+    {
       switch (*d)
        {
-       case 'A':
-         (*info->fprintf_func) (info->stream, "0x%x",
-                                (l >> OP_SH_SHAMT) & OP_MASK_SHAMT);
+       case ',':
+       case '(':
+       case ')':
+       case '[':
+       case ']':
+         (*info->fprintf_func) (info->stream, "%c", *d);
          break;
+
+       case '+':
+         /* Extension character; switch for second char.  */
+         d++;
+         switch (*d)
+           {
+           case '\0':
+             /* xgettext:c-format */
+             (*info->fprintf_func) (info->stream,
+                                    _("# internal error, incomplete extension sequence (+)"));
+             return;
+
+           case 'A':
+             lsb = (l >> OP_SH_SHAMT) & OP_MASK_SHAMT;
+             (*info->fprintf_func) (info->stream, "0x%x", lsb);
+             break;
        
-       case 'B':
-         (*info->fprintf_func) (info->stream, "0x%x",
-                                (((l >> OP_SH_INSMSB) & OP_MASK_INSMSB)
-                                  - ((l >> OP_SH_SHAMT) & OP_MASK_SHAMT)
-                                 + 1));
-         break;
+           case 'B':
+             msb = (l >> OP_SH_INSMSB) & OP_MASK_INSMSB;
+             (*info->fprintf_func) (info->stream, "0x%x", msb - lsb + 1);
+             break;
+
+           case 'C':
+           case 'H':
+             msbd = (l >> OP_SH_EXTMSBD) & OP_MASK_EXTMSBD;
+             (*info->fprintf_func) (info->stream, "0x%x", msbd + 1);
+             break;
+
+           case 'D':
+             {
+               const struct mips_cp0sel_name *n;
+               unsigned int cp0reg, sel;
+
+               cp0reg = (l >> OP_SH_RD) & OP_MASK_RD;
+               sel = (l >> OP_SH_SEL) & OP_MASK_SEL;
+
+               /* CP0 register including 'sel' code for mtcN (et al.), to be
+                  printed textually if known.  If not known, print both
+                  CP0 register name and sel numerically since CP0 register
+                  with sel 0 may have a name unrelated to register being
+                  printed.  */
+               n = lookup_mips_cp0sel_name(mips_cp0sel_names,
+                                           mips_cp0sel_names_len, cp0reg, sel);
+               if (n != NULL)
+                 (*info->fprintf_func) (info->stream, "%s", n->name);
+               else
+                 (*info->fprintf_func) (info->stream, "$%d,%d", cp0reg, sel);
+               break;
+             }
 
-       case 'C':
-         (*info->fprintf_func) (info->stream, "0x%x",
-                                (((l >> OP_SH_EXTMSBD) & OP_MASK_EXTMSBD)
-                                 + 1));
+           case 'E':
+             lsb = ((l >> OP_SH_SHAMT) & OP_MASK_SHAMT) + 32;
+             (*info->fprintf_func) (info->stream, "0x%x", lsb);
+             break;
+       
+           case 'F':
+             msb = ((l >> OP_SH_INSMSB) & OP_MASK_INSMSB) + 32;
+             (*info->fprintf_func) (info->stream, "0x%x", msb - lsb + 1);
+             break;
+
+           case 'G':
+             msbd = ((l >> OP_SH_EXTMSBD) & OP_MASK_EXTMSBD) + 32;
+             (*info->fprintf_func) (info->stream, "0x%x", msbd + 1);
+             break;
+
+           default:
+             /* xgettext:c-format */
+             (*info->fprintf_func) (info->stream,
+                                    _("# internal error, undefined extension sequence (+%c)"),
+                                    *d);
+             return;
+           }
          break;
 
-       case 'D':
-         {
-           const struct mips_cp0sel_name *n;
-           unsigned int cp0reg, sel;
-
-           cp0reg = (l >> OP_SH_RD) & OP_MASK_RD;
-           sel = (l >> OP_SH_SEL) & OP_MASK_SEL;
-
-           /* CP0 register including 'sel' code for mtcN (et al.), to be
-              printed textually if known.  If not known, print both
-              CP0 register name and sel numerically since CP0 register
-              with sel 0 may have a name unrelated to register being
-              printed.  */
-           n = lookup_mips_cp0sel_name(mips_cp0sel_names,
-                                       mips_cp0sel_names_len, cp0reg, sel);
-           if (n != NULL)
-             (*info->fprintf_func) (info->stream, "%s", n->name);
-           else
-             (*info->fprintf_func) (info->stream, "$%d,%d", cp0reg, sel);
-           break;
-         }
-
-       default:
-         /* xgettext:c-format */
-         (*info->fprintf_func) (info->stream,
-                                _("# internal error, undefined extension sequence (+%c)"),
-                                *d);
-         /* Do not eat the trailing newline.  */
-         if (*d == '\0')
-           consumed--;
+       case 's':
+       case 'b':
+       case 'r':
+       case 'v':
+         (*info->fprintf_func) (info->stream, "%s",
+                                mips_gpr_names[(l >> OP_SH_RS) & OP_MASK_RS]);
          break;
-       }
-      break;
-
-    case 's':
-    case 'b':
-    case 'r':
-    case 'v':
-      (*info->fprintf_func) (info->stream, "%s",
-                            mips_gpr_names[(l >> OP_SH_RS) & OP_MASK_RS]);
-      break;
-
-    case 't':
-    case 'w':
-      (*info->fprintf_func) (info->stream, "%s",
-                            mips_gpr_names[(l >> OP_SH_RT) & OP_MASK_RT]);
-      break;
 
-    case 'i':
-    case 'u':
-      (*info->fprintf_func) (info->stream, "0x%x",
-                            (l >> OP_SH_IMMEDIATE) & OP_MASK_IMMEDIATE);
-      break;
+       case 't':
+       case 'w':
+         (*info->fprintf_func) (info->stream, "%s",
+                                mips_gpr_names[(l >> OP_SH_RT) & OP_MASK_RT]);
+         break;
 
-    case 'j': /* Same as i, but sign-extended.  */
-    case 'o':
-      delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
-      if (delta & 0x8000)
-       delta |= ~0xffff;
-      (*info->fprintf_func) (info->stream, "%d",
-                            delta);
-      break;
+       case 'i':
+       case 'u':
+         (*info->fprintf_func) (info->stream, "0x%x",
+                                (l >> OP_SH_IMMEDIATE) & OP_MASK_IMMEDIATE);
+         break;
 
-    case 'h':
-      (*info->fprintf_func) (info->stream, "0x%x",
-                            (unsigned int) ((l >> OP_SH_PREFX)
-                                            & OP_MASK_PREFX));
-      break;
+       case 'j': /* Same as i, but sign-extended.  */
+       case 'o':
+         delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
+         if (delta & 0x8000)
+           delta |= ~0xffff;
+         (*info->fprintf_func) (info->stream, "%d",
+                                delta);
+         break;
 
-    case 'k':
-      (*info->fprintf_func) (info->stream, "0x%x",
-                            (unsigned int) ((l >> OP_SH_CACHE)
-                                            & OP_MASK_CACHE));
-      break;
+       case 'h':
+         (*info->fprintf_func) (info->stream, "0x%x",
+                                (unsigned int) ((l >> OP_SH_PREFX)
+                                                & OP_MASK_PREFX));
+         break;
 
-    case 'a':
-      info->target = (((pc + 4) & ~(bfd_vma) 0x0fffffff)
-                     | (((l >> OP_SH_TARGET) & OP_MASK_TARGET) << 2));
-      (*info->print_address_func) (info->target, info);
-      break;
+       case 'k':
+         (*info->fprintf_func) (info->stream, "0x%x",
+                                (unsigned int) ((l >> OP_SH_CACHE)
+                                                & OP_MASK_CACHE));
+         break;
 
-    case 'p':
-      /* Sign extend the displacement.  */
-      delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
-      if (delta & 0x8000)
-       delta |= ~0xffff;
-      info->target = (delta << 2) + pc + INSNLEN;
-      (*info->print_address_func) (info->target, info);
-      break;
+       case 'a':
+         info->target = (((pc + 4) & ~(bfd_vma) 0x0fffffff)
+                         | (((l >> OP_SH_TARGET) & OP_MASK_TARGET) << 2));
+         (*info->print_address_func) (info->target, info);
+         break;
 
-    case 'd':
-      (*info->fprintf_func) (info->stream, "%s",
-                            mips_gpr_names[(l >> OP_SH_RD) & OP_MASK_RD]);
-      break;
+       case 'p':
+         /* Sign extend the displacement.  */
+         delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
+         if (delta & 0x8000)
+           delta |= ~0xffff;
+         info->target = (delta << 2) + pc + INSNLEN;
+         (*info->print_address_func) (info->target, info);
+         break;
 
-    case 'U':
-      {
-       /* First check for both rd and rt being equal.  */
-       unsigned int reg = (l >> OP_SH_RD) & OP_MASK_RD;
-       if (reg == ((l >> OP_SH_RT) & OP_MASK_RT))
+       case 'd':
          (*info->fprintf_func) (info->stream, "%s",
-                                mips_gpr_names[reg]);
-       else
+                                mips_gpr_names[(l >> OP_SH_RD) & OP_MASK_RD]);
+         break;
+
+       case 'U':
          {
-           /* If one is zero use the other.  */
-           if (reg == 0)
-             (*info->fprintf_func) (info->stream, "%s",
-                                    mips_gpr_names[(l >> OP_SH_RT) & OP_MASK_RT]);
-           else if (((l >> OP_SH_RT) & OP_MASK_RT) == 0)
+           /* First check for both rd and rt being equal.  */
+           unsigned int reg = (l >> OP_SH_RD) & OP_MASK_RD;
+           if (reg == ((l >> OP_SH_RT) & OP_MASK_RT))
              (*info->fprintf_func) (info->stream, "%s",
                                     mips_gpr_names[reg]);
-           else /* Bogus, result depends on processor.  */
-             (*info->fprintf_func) (info->stream, "%s or %s",
-                                    mips_gpr_names[reg],
-                                    mips_gpr_names[(l >> OP_SH_RT) & OP_MASK_RT]);
+           else
+             {
+               /* If one is zero use the other.  */
+               if (reg == 0)
+                 (*info->fprintf_func) (info->stream, "%s",
+                                        mips_gpr_names[(l >> OP_SH_RT) & OP_MASK_RT]);
+               else if (((l >> OP_SH_RT) & OP_MASK_RT) == 0)
+                 (*info->fprintf_func) (info->stream, "%s",
+                                        mips_gpr_names[reg]);
+               else /* Bogus, result depends on processor.  */
+                 (*info->fprintf_func) (info->stream, "%s or %s",
+                                        mips_gpr_names[reg],
+                                        mips_gpr_names[(l >> OP_SH_RT) & OP_MASK_RT]);
+             }
          }
-      }
-      break;
+         break;
 
-    case 'z':
-      (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[0]);
-      break;
+       case 'z':
+         (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[0]);
+         break;
 
-    case '<':
-      (*info->fprintf_func) (info->stream, "0x%x",
-                            (l >> OP_SH_SHAMT) & OP_MASK_SHAMT);
-      break;
+       case '<':
+         (*info->fprintf_func) (info->stream, "0x%x",
+                                (l >> OP_SH_SHAMT) & OP_MASK_SHAMT);
+         break;
 
-    case 'c':
-      (*info->fprintf_func) (info->stream, "0x%x",
-                            (l >> OP_SH_CODE) & OP_MASK_CODE);
-      break;
+       case 'c':
+         (*info->fprintf_func) (info->stream, "0x%x",
+                                (l >> OP_SH_CODE) & OP_MASK_CODE);
+         break;
 
-    case 'q':
-      (*info->fprintf_func) (info->stream, "0x%x",
-                            (l >> OP_SH_CODE2) & OP_MASK_CODE2);
-      break;
+       case 'q':
+         (*info->fprintf_func) (info->stream, "0x%x",
+                                (l >> OP_SH_CODE2) & OP_MASK_CODE2);
+         break;
 
-    case 'C':
-      (*info->fprintf_func) (info->stream, "0x%x",
-                            (l >> OP_SH_COPZ) & OP_MASK_COPZ);
-      break;
+       case 'C':
+         (*info->fprintf_func) (info->stream, "0x%x",
+                                (l >> OP_SH_COPZ) & OP_MASK_COPZ);
+         break;
 
-    case 'B':
-      (*info->fprintf_func) (info->stream, "0x%x",
-                            (l >> OP_SH_CODE20) & OP_MASK_CODE20);
-      break;
+       case 'B':
+         (*info->fprintf_func) (info->stream, "0x%x",
+                                (l >> OP_SH_CODE20) & OP_MASK_CODE20);
+         break;
 
-    case 'J':
-      (*info->fprintf_func) (info->stream, "0x%x",
-                            (l >> OP_SH_CODE19) & OP_MASK_CODE19);
-      break;
+       case 'J':
+         (*info->fprintf_func) (info->stream, "0x%x",
+                                (l >> OP_SH_CODE19) & OP_MASK_CODE19);
+         break;
 
-    case 'S':
-    case 'V':
-      (*info->fprintf_func) (info->stream, "%s",
-                            mips_fpr_names[(l >> OP_SH_FS) & OP_MASK_FS]);
-      break;
+       case 'S':
+       case 'V':
+         (*info->fprintf_func) (info->stream, "%s",
+                                mips_fpr_names[(l >> OP_SH_FS) & OP_MASK_FS]);
+         break;
 
-    case 'T':
-    case 'W':
-      (*info->fprintf_func) (info->stream, "%s",
-                            mips_fpr_names[(l >> OP_SH_FT) & OP_MASK_FT]);
-      break;
+       case 'T':
+       case 'W':
+         (*info->fprintf_func) (info->stream, "%s",
+                                mips_fpr_names[(l >> OP_SH_FT) & OP_MASK_FT]);
+         break;
 
-    case 'D':
-      (*info->fprintf_func) (info->stream, "%s",
-                            mips_fpr_names[(l >> OP_SH_FD) & OP_MASK_FD]);
-      break;
+       case 'D':
+         (*info->fprintf_func) (info->stream, "%s",
+                                mips_fpr_names[(l >> OP_SH_FD) & OP_MASK_FD]);
+         break;
 
-    case 'R':
-      (*info->fprintf_func) (info->stream, "%s",
-                            mips_fpr_names[(l >> OP_SH_FR) & OP_MASK_FR]);
-      break;
+       case 'R':
+         (*info->fprintf_func) (info->stream, "%s",
+                                mips_fpr_names[(l >> OP_SH_FR) & OP_MASK_FR]);
+         break;
 
-    case 'E':
-      /* Coprocessor register for lwcN instructions, et al.
-
-        Note that there is no load/store cp0 instructions, and
-        that FPU (cp1) instructions disassemble this field using
-        'T' format.  Therefore, until we gain understanding of
-        cp2 register names,
-        we can simply print the register numbers.  */
-      (*info->fprintf_func) (info->stream, "$%d",
-                            (l >> OP_SH_RT) & OP_MASK_RT);
-      break;
+       case 'E':
+         /* Coprocessor register for lwcN instructions, et al.
 
-    case 'G':
-      /* Coprocessor register for mtcN instructions, et al.
-        Note that FPU (cp1) instructions disassemble this field using
-        'S' format.  Therefore, we only need to worry about cp0, cp2,
-        and cp3.  */
-      op = (l >> OP_SH_OP) & OP_MASK_OP;
-      if (op == OP_OP_COP0)
-        (*info->fprintf_func) (info->stream, "%s",
-                              mips_cp0_names[(l >> OP_SH_RD) & OP_MASK_RD]);
-      else
-        (*info->fprintf_func) (info->stream, "$%d",
-                              (l >> OP_SH_RD) & OP_MASK_RD);
-      break;
+            Note that there is no load/store cp0 instructions, and
+            that FPU (cp1) instructions disassemble this field using
+            'T' format.  Therefore, until we gain understanding of
+            cp2 register names, we can simply print the register
+            numbers.  */
+         (*info->fprintf_func) (info->stream, "$%d",
+                                (l >> OP_SH_RT) & OP_MASK_RT);
+         break;
 
-    case 'K':
-      (*info->fprintf_func) (info->stream, "%s",
-                            mips_hwr_names[(l >> OP_SH_RD) & OP_MASK_RD]);
-      break;
+       case 'G':
+         /* Coprocessor register for mtcN instructions, et al.  Note
+            that FPU (cp1) instructions disassemble this field using
+            'S' format.  Therefore, we only need to worry about cp0,
+            cp2, and cp3.  */
+         op = (l >> OP_SH_OP) & OP_MASK_OP;
+         if (op == OP_OP_COP0)
+           (*info->fprintf_func) (info->stream, "%s",
+                                  mips_cp0_names[(l >> OP_SH_RD) & OP_MASK_RD]);
+         else
+           (*info->fprintf_func) (info->stream, "$%d",
+                                  (l >> OP_SH_RD) & OP_MASK_RD);
+         break;
 
-    case 'N':
-      (*info->fprintf_func) (info->stream, "$fcc%d",
-                            (l >> OP_SH_BCC) & OP_MASK_BCC);
-      break;
+       case 'K':
+         (*info->fprintf_func) (info->stream, "%s",
+                                mips_hwr_names[(l >> OP_SH_RD) & OP_MASK_RD]);
+         break;
 
-    case 'M':
-      (*info->fprintf_func) (info->stream, "$fcc%d",
-                            (l >> OP_SH_CCC) & OP_MASK_CCC);
-      break;
+       case 'N':
+         (*info->fprintf_func) (info->stream, "$fcc%d",
+                                (l >> OP_SH_BCC) & OP_MASK_BCC);
+         break;
 
-    case 'P':
-      (*info->fprintf_func) (info->stream, "%d",
-                            (l >> OP_SH_PERFREG) & OP_MASK_PERFREG);
-      break;
+       case 'M':
+         (*info->fprintf_func) (info->stream, "$fcc%d",
+                                (l >> OP_SH_CCC) & OP_MASK_CCC);
+         break;
 
-    case 'e':
-      (*info->fprintf_func) (info->stream, "%d",
-                            (l >> OP_SH_VECBYTE) & OP_MASK_VECBYTE);
-      break;
+       case 'P':
+         (*info->fprintf_func) (info->stream, "%d",
+                                (l >> OP_SH_PERFREG) & OP_MASK_PERFREG);
+         break;
 
-    case '%':
-      (*info->fprintf_func) (info->stream, "%d",
-                            (l >> OP_SH_VECALIGN) & OP_MASK_VECALIGN);
-      break;
+       case 'e':
+         (*info->fprintf_func) (info->stream, "%d",
+                                (l >> OP_SH_VECBYTE) & OP_MASK_VECBYTE);
+         break;
 
-    case 'H':
-      (*info->fprintf_func) (info->stream, "%d",
-                            (l >> OP_SH_SEL) & OP_MASK_SEL);
-      break;
+       case '%':
+         (*info->fprintf_func) (info->stream, "%d",
+                                (l >> OP_SH_VECALIGN) & OP_MASK_VECALIGN);
+         break;
 
-    case 'O':
-      (*info->fprintf_func) (info->stream, "%d",
-                            (l >> OP_SH_ALN) & OP_MASK_ALN);
-      break;
+       case 'H':
+         (*info->fprintf_func) (info->stream, "%d",
+                                (l >> OP_SH_SEL) & OP_MASK_SEL);
+         break;
 
-    case 'Q':
-      {
-       unsigned int vsel = (l >> OP_SH_VSEL) & OP_MASK_VSEL;
-       if ((vsel & 0x10) == 0)
-         {
-           int fmt;
-           vsel &= 0x0f;
-           for (fmt = 0; fmt < 3; fmt++, vsel >>= 1)
-             if ((vsel & 1) == 0)
-               break;
-           (*info->fprintf_func) (info->stream, "$v%d[%d]",
-                                  (l >> OP_SH_FT) & OP_MASK_FT,
-                                  vsel >> 1);
-         }
-       else if ((vsel & 0x08) == 0)
-         {
-           (*info->fprintf_func) (info->stream, "$v%d",
-                                  (l >> OP_SH_FT) & OP_MASK_FT);
-         }
-       else
+       case 'O':
+         (*info->fprintf_func) (info->stream, "%d",
+                                (l >> OP_SH_ALN) & OP_MASK_ALN);
+         break;
+
+       case 'Q':
          {
-           (*info->fprintf_func) (info->stream, "0x%x",
-                                  (l >> OP_SH_FT) & OP_MASK_FT);
+           unsigned int vsel = (l >> OP_SH_VSEL) & OP_MASK_VSEL;
+           if ((vsel & 0x10) == 0)
+             {
+               int fmt;
+               vsel &= 0x0f;
+               for (fmt = 0; fmt < 3; fmt++, vsel >>= 1)
+                 if ((vsel & 1) == 0)
+                   break;
+               (*info->fprintf_func) (info->stream, "$v%d[%d]",
+                                      (l >> OP_SH_FT) & OP_MASK_FT,
+                                      vsel >> 1);
+             }
+           else if ((vsel & 0x08) == 0)
+             {
+               (*info->fprintf_func) (info->stream, "$v%d",
+                                      (l >> OP_SH_FT) & OP_MASK_FT);
+             }
+           else
+             {
+               (*info->fprintf_func) (info->stream, "0x%x",
+                                      (l >> OP_SH_FT) & OP_MASK_FT);
+             }
          }
-      }
-      break;
+         break;
 
-    case 'X':
-      (*info->fprintf_func) (info->stream, "$v%d",
-                            (l >> OP_SH_FD) & OP_MASK_FD);
-      break;
+       case 'X':
+         (*info->fprintf_func) (info->stream, "$v%d",
+                                (l >> OP_SH_FD) & OP_MASK_FD);
+         break;
 
-    case 'Y':
-      (*info->fprintf_func) (info->stream, "$v%d",
-                            (l >> OP_SH_FS) & OP_MASK_FS);
-      break;
+       case 'Y':
+         (*info->fprintf_func) (info->stream, "$v%d",
+                                (l >> OP_SH_FS) & OP_MASK_FS);
+         break;
 
-    case 'Z':
-      (*info->fprintf_func) (info->stream, "$v%d",
-                            (l >> OP_SH_FT) & OP_MASK_FT);
-      break;
+       case 'Z':
+         (*info->fprintf_func) (info->stream, "$v%d",
+                                (l >> OP_SH_FT) & OP_MASK_FT);
+         break;
 
-    default:
-      /* xgettext:c-format */
-      (*info->fprintf_func) (info->stream,
-                            _("# internal error, undefined modifier(%c)"),
-                            *d);
-      break;
+       default:
+         /* xgettext:c-format */
+         (*info->fprintf_func) (info->stream,
+                                _("# internal error, undefined modifier(%c)"),
+                                *d);
+         return;
+       }
     }
-
-  return consumed;
 }
 \f
 /* Check if the object uses NewABI conventions.  */
@@ -1106,16 +1134,8 @@ print_insn_mips (memaddr, word, info)
              d = op->args;
              if (d != NULL && *d != '\0')
                {
-                 int consumed;
-
                  (*info->fprintf_func) (info->stream, "\t");
-                 while (*d != '\0')
-                   {
-                     /* print_insn_arg will not eat the trailing NUL
-                        of (erroneous) multi-character strings.  */
-                     consumed = print_insn_arg (d, word, memaddr, info);
-                     d += consumed;
-                   }
+                 print_insn_args (d, word, memaddr, info);
                }
 
              return INSNLEN;
@@ -1764,7 +1784,7 @@ void
 print_mips_disassembler_options (stream)
      FILE *stream;
 {
-  int i;
+  unsigned int i;
 
   fprintf (stream, _("\n\
 The following MIPS specific disassembler options are supported for use\n\
@@ -1799,14 +1819,14 @@ with the -M switch (multiple options should be separated by commas):\n"));
   fprintf (stream, _("\n\
   For the options above, the following values are supported for \"ABI\":\n\
    "));
-  for (i = 0; mips_abi_choices[i].name != NULL; i++)
+  for (i = 0; i < ARRAY_SIZE (mips_abi_choices); i++)
     fprintf (stream, " %s", mips_abi_choices[i].name);
   fprintf (stream, _("\n"));
 
   fprintf (stream, _("\n\
   For the options above, The following values are supported for \"ARCH\":\n\
    "));
-  for (i = 0; mips_arch_choices[i].name != NULL; i++)
+  for (i = 0; i < ARRAY_SIZE (mips_arch_choices); i++)
     if (*mips_arch_choices[i].name != '\0')
       fprintf (stream, " %s", mips_arch_choices[i].name);
   fprintf (stream, _("\n"));
This page took 0.033802 seconds and 4 git commands to generate.