MIPS: Add Imagination interAptiv MR2 MIPS32r3 processor support
[deliverable/binutils-gdb.git] / opcodes / mips-dis.c
index b541e03b8522dcabbe8c3102fb68a1f23ea87f73..e19d59a703df28adfb768e13fc2509bc9152d6a0 100644 (file)
@@ -607,6 +607,13 @@ const struct mips_arch_choice mips_arch_choices[] =
     mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
     mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
 
+  { "interaptiv-mr2",  1, bfd_mach_mips_interaptiv_mr2, CPU_INTERAPTIV_MR2,
+    ISA_MIPS32R3,
+    ASE_MT | ASE_EVA | ASE_DSP | ASE_DSPR2 | ASE_MIPS16E2 | ASE_MIPS16E2_MT,
+    mips_cp0_names_mips3264r2,
+    mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
+    mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
+
   { "sb1",     1, bfd_mach_mips_sb1, CPU_SB1,
     ISA_MIPS64 | INSN_SB1,  ASE_MIPS3D,
     mips_cp0_names_sb1,
@@ -1197,6 +1204,81 @@ mips_seen_register (struct mips_print_arg_state *state,
     }
 }
 
+/* Print SAVE/RESTORE instruction operands according to the argument
+   register mask AMASK, the number of static registers saved NSREG,
+   the $ra, $s0 and $s1 register specifiers RA, S0 and S1 respectively,
+   and the frame size FRAME_SIZE.  */
+
+static void
+mips_print_save_restore (struct disassemble_info *info, unsigned int amask,
+                        unsigned int nsreg, unsigned int ra,
+                        unsigned int s0, unsigned int s1,
+                        unsigned int frame_size)
+{
+  const fprintf_ftype infprintf = info->fprintf_func;
+  unsigned int nargs, nstatics, smask, i, j;
+  void *is = info->stream;
+  const char *sep;
+
+  if (amask == MIPS_SVRS_ALL_ARGS)
+    {
+      nargs = 4;
+      nstatics = 0;
+    }
+  else if (amask == MIPS_SVRS_ALL_STATICS)
+    {
+      nargs = 0;
+      nstatics = 4;
+    }
+  else
+    {
+      nargs = amask >> 2;
+      nstatics = amask & 3;
+    }
+
+  sep = "";
+  if (nargs > 0)
+    {
+      infprintf (is, "%s", mips_gpr_names[4]);
+      if (nargs > 1)
+       infprintf (is, "-%s", mips_gpr_names[4 + nargs - 1]);
+      sep = ",";
+    }
+
+  infprintf (is, "%s%d", sep, frame_size);
+
+  if (ra)                      /* $ra */
+    infprintf (is, ",%s", mips_gpr_names[31]);
+
+  smask = 0;
+  if (s0)                      /* $s0 */
+    smask |= 1 << 0;
+  if (s1)                      /* $s1 */
+    smask |= 1 << 1;
+  if (nsreg > 0)               /* $s2-$s8 */
+    smask |= ((1 << nsreg) - 1) << 2;
+
+  for (i = 0; i < 9; i++)
+    if (smask & (1 << i))
+      {
+       infprintf (is, ",%s", mips_gpr_names[i == 8 ? 30 : (16 + i)]);
+       /* Skip over string of set bits.  */
+       for (j = i; smask & (2 << j); j++)
+         continue;
+       if (j > i)
+         infprintf (is, "-%s", mips_gpr_names[j == 8 ? 30 : (16 + j)]);
+       i = j + 1;
+      }
+  /* Statics $ax - $a3.  */
+  if (nstatics == 1)
+    infprintf (is, ",%s", mips_gpr_names[7]);
+  else if (nstatics > 0)
+    infprintf (is, ",%s-%s",
+              mips_gpr_names[7 - nstatics + 1],
+              mips_gpr_names[7]);
+}
+
+
 /* Print operand OPERAND of OPCODE, using STATE to track inter-operand state.
    UVAL is the encoding of the operand (shifted into bit 0) and BASE_PC is
    the base address for OP_PCREL operands.  */
@@ -1429,7 +1511,7 @@ print_insn_arg (struct disassemble_info *info,
       break;
 
     case OP_SAVE_RESTORE_LIST:
-      /* Should be handled by the caller due to extend behavior.  */
+      /* Should be handled by the caller due to complex behavior.  */
       abort ();
 
     case OP_MDMX_IMM_REG:
@@ -1590,11 +1672,8 @@ validate_insn_args (const struct mips_opcode *opcode,
                case OP_VU0_MATCH_SUFFIX:
                case OP_IMM_INDEX:
                case OP_REG_INDEX:
-                 break;
-
                case OP_SAVE_RESTORE_LIST:
-               /* Should be handled by the caller due to extend behavior.  */
-                 abort ();
+                 break;
                }
            }
          if (*s == 'm' || *s == '+' || *s == '-')
@@ -1647,10 +1726,24 @@ print_insn_args (struct disassemble_info *info,
                         opcode->name, opcode->args);
              return;
            }
-         if (operand->type == OP_REG
-             && s[1] == ','
-             && s[2] == 'H'
-             && opcode->name[strlen (opcode->name) - 1] == '0')
+
+         if (operand->type == OP_SAVE_RESTORE_LIST)
+           {
+             /* Handle this case here because of the complex behavior.  */
+             unsigned int amask = (insn >> 15) & 0xf;
+             unsigned int nsreg = (insn >> 23) & 0x7;
+             unsigned int ra = insn & 0x1000;                  /* $ra */
+             unsigned int s0 = insn & 0x800;                   /* $s0 */
+             unsigned int s1 = insn & 0x400;                   /* $s1 */
+             unsigned int frame_size = (((insn >> 15) & 0xf0)
+                                        | ((insn >> 6) & 0x0f)) * 8;
+             mips_print_save_restore (info, amask, nsreg, ra, s0, s1,
+                                      frame_size);
+           }
+         else if (operand->type == OP_REG
+                  && s[1] == ','
+                  && s[2] == 'H'
+                  && opcode->name[strlen (opcode->name) - 1] == '0')
            {
              /* Coprocessor register 0 with sel field.  */
              const struct mips_cp0sel_name *n;
@@ -1864,70 +1957,15 @@ print_mips16_insn_arg (struct disassemble_info *info,
        {
          /* Handle this case here because of the complex interaction
             with the EXTEND opcode.  */
-         unsigned int amask, nargs, nstatics, nsreg, smask, frame_size, i, j;
-         const char *sep;
-
-         amask = extend & 0xf;
-         if (amask == MIPS16_ALL_ARGS)
-           {
-             nargs = 4;
-             nstatics = 0;
-           }
-         else if (amask == MIPS16_ALL_STATICS)
-           {
-             nargs = 0;
-             nstatics = 4;
-           }
-         else
-           {
-             nargs = amask >> 2;
-             nstatics = amask & 3;
-           }
-
-         sep = "";
-         if (nargs > 0)
-           {
-             infprintf (is, "%s", mips_gpr_names[4]);
-             if (nargs > 1)
-               infprintf (is, "-%s", mips_gpr_names[4 + nargs - 1]);
-             sep = ",";
-           }
-
-         frame_size = ((extend & 0xf0) | (insn & 0x0f)) * 8;
+         unsigned int amask = extend & 0xf;
+         unsigned int nsreg = (extend >> 8) & 0x7;
+         unsigned int ra = insn & 0x40;                        /* $ra */
+         unsigned int s0 = insn & 0x20;                        /* $s0 */
+         unsigned int s1 = insn & 0x10;                        /* $s1 */
+         unsigned int frame_size = ((extend & 0xf0) | (insn & 0x0f)) * 8;
          if (frame_size == 0 && !use_extend)
            frame_size = 128;
-         infprintf (is, "%s%d", sep, frame_size);
-
-         if (insn & 0x40)              /* $ra */
-           infprintf (is, ",%s", mips_gpr_names[31]);
-
-         nsreg = (extend >> 8) & 0x7;
-         smask = 0;
-         if (insn & 0x20)              /* $s0 */
-           smask |= 1 << 0;
-         if (insn & 0x10)              /* $s1 */
-           smask |= 1 << 1;
-         if (nsreg > 0)                /* $s2-$s8 */
-           smask |= ((1 << nsreg) - 1) << 2;
-
-         for (i = 0; i < 9; i++)
-           if (smask & (1 << i))
-             {
-               infprintf (is, ",%s", mips_gpr_names[i == 8 ? 30 : (16 + i)]);
-               /* Skip over string of set bits.  */
-               for (j = i; smask & (2 << j); j++)
-                 continue;
-               if (j > i)
-                 infprintf (is, "-%s", mips_gpr_names[j == 8 ? 30 : (16 + j)]);
-               i = j + 1;
-             }
-         /* Statics $ax - $a3.  */
-         if (nstatics == 1)
-           infprintf (is, ",%s", mips_gpr_names[7]);
-         else if (nstatics > 0)
-           infprintf (is, ",%s-%s",
-                      mips_gpr_names[7 - nstatics + 1],
-                      mips_gpr_names[7]);
+         mips_print_save_restore (info, amask, nsreg, ra, s0, s1, frame_size);
          break;
        }
 
This page took 0.02681 seconds and 4 git commands to generate.