Add mangled names to addr2line -i output.
[deliverable/binutils-gdb.git] / gas / config / tc-mips.c
index 0e9969038d438840a6521ca5ba9372908d182a3e..b4b76f018b56675f835eea6d695081f0f077eade 100644 (file)
@@ -20,8 +20,8 @@
 
    You should have received a copy of the GNU General Public License
    along with GAS; see the file COPYING.  If not, write to the Free
-   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-   02111-1307, USA.  */
+   Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
+   02110-1301, USA.  */
 
 #include "as.h"
 #include "config.h"
@@ -193,6 +193,8 @@ struct mips_set_options
      command line options, and based on the default architecture.  */
   int ase_mips3d;
   int ase_mdmx;
+  int ase_dsp;
+  int ase_mt;
   /* Whether we are assembling for the mips16 processor.  0 if we are
      not, 1 if we are, and -1 if the value has not been initialized.
      Changed by `.set mips16' and `.set nomips16', and the -mips16 and
@@ -243,7 +245,7 @@ static int file_mips_fp32 = -1;
 
 static struct mips_set_options mips_opts =
 {
-  ISA_UNKNOWN, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, CPU_UNKNOWN, FALSE
+  ISA_UNKNOWN, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, CPU_UNKNOWN, FALSE
 };
 
 /* These variables are filled in with the masks of registers used.
@@ -267,6 +269,14 @@ static int file_ase_mips3d;
    command line (e.g., by -march).  */
 static int file_ase_mdmx;
 
+/* True if -mdsp was passed or implied by arguments passed on the
+   command line (e.g., by -march).  */
+static int file_ase_dsp;
+
+/* True if -mmt was passed or implied by arguments passed on the
+   command line (e.g., by -march).  */
+static int file_ase_mt;
+
 /* The argument of the -march= flag.  The architecture we are assembling.  */
 static int file_mips_arch = CPU_UNKNOWN;
 static const char *mips_arch_string;
@@ -365,6 +375,14 @@ static int mips_32bitmode = 0;
 #define CPU_HAS_MDMX(cpu)      (FALSE                 \
                                 )
 
+/* Return true if the given CPU supports the DSP ASE.  */
+#define CPU_HAS_DSP(cpu)       (FALSE                 \
+                                )
+
+/* Return true if the given CPU supports the MT ASE.  */
+#define CPU_HAS_MT(cpu)                (FALSE                 \
+                                )
+
 /* True if CPU has a dror instruction.  */
 #define CPU_HAS_DROR(CPU)      ((CPU) == CPU_VR5400 || (CPU) == CPU_VR5500)
 
@@ -2294,10 +2312,11 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
   else if (mips_opts.mips16
           && ! ip->use_extend
           && *reloc_type != BFD_RELOC_MIPS16_JMP)
-    {
-      /* Make sure there is enough room to swap this instruction with
-         a following jump instruction.  */
-      frag_grow (6);
+    {     
+      if ((pinfo & INSN_UNCOND_BRANCH_DELAY) == 0)
+       /* Make sure there is enough room to swap this instruction with
+          a following jump instruction.  */
+       frag_grow (6);
       add_fixed_insn (ip);
     }
   else
@@ -2690,7 +2709,7 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
              if (mips_opts.mips16)
                {
                  know (delay.frag == ip->frag);
-                 move_insn (ip, delay.frag, delay.where);
+                  move_insn (ip, delay.frag, delay.where);
                  move_insn (&delay, ip->frag, ip->where + insn_length (ip));
                }
              else if (relaxed_branch)
@@ -3265,7 +3284,7 @@ mips16_macro_build (expressionS *ep, const char *name, const char *fmt,
 static void
 normalize_constant_expr (expressionS *ex)
 {
-  if ((ex->X_op == O_constant && HAVE_32BIT_GPRS)
+  if (ex->X_op == O_constant
       && IS_ZEXT_32BIT_NUM (ex->X_add_number))
     ex->X_add_number = (((ex->X_add_number & 0xffffffff) ^ 0x80000000)
                        - 0x80000000);
@@ -3425,9 +3444,11 @@ check_absolute_expr (struct mips_cl_insn *ip, expressionS *ex)
   if (ex->X_op == O_big)
     as_bad (_("unsupported large constant"));
   else if (ex->X_op != O_constant)
-    as_bad (_("Instruction %s requires absolute expression"), ip->insn_mo->name);
+    as_bad (_("Instruction %s requires absolute expression"),
+           ip->insn_mo->name);
 
-  normalize_constant_expr (ex);
+  if (HAVE_32BIT_GPRS)
+    normalize_constant_expr (ex);
 }
 
 /* Count the leading zeroes by performing a binary chop. This is a
@@ -3553,9 +3574,10 @@ load_register (int reg, expressionS *ep, int dbl)
 
   if (!dbl || HAVE_32BIT_GPRS)
     {
-      as_bad (_("Number (0x%lx%08lx) larger than 32 bits"),
-             (unsigned long) (ep->X_add_number >> 32),
-             (unsigned long) (ep->X_add_number & 0xffffffff));
+      char value[32];
+
+      sprintf_vma (value, ep->X_add_number);
+      as_bad (_("Number (0x%s) larger than 32 bits"), value);
       macro_build (ep, "addiu", "t,r,j", reg, 0, BFD_RELOC_LO16);
       return;
     }
@@ -5798,9 +5820,12 @@ macro (struct mips_cl_insn *ip)
 
       if (HAVE_32BIT_ADDRESSES
          && !IS_SEXT_32BIT_NUM (offset_expr.X_add_number))
-       as_bad (_("Number (0x%lx%08lx) larger than 32 bits"),
-               (unsigned long) (offset_expr.X_add_number >> 32),
-               (unsigned long) (offset_expr.X_add_number & 0xffffffff));
+       {
+         char value [32];
+
+         sprintf_vma (value, offset_expr.X_add_number);
+         as_bad (_("Number (0x%s) larger than 32 bits"), value);
+       }
 
       /* A constant expression in PIC code can be handled just as it
         is in non PIC code.  */
@@ -6389,9 +6414,12 @@ macro (struct mips_cl_insn *ip)
 
       if (HAVE_32BIT_ADDRESSES
          && !IS_SEXT_32BIT_NUM (offset_expr.X_add_number))
-       as_bad (_("Number (0x%lx%08lx) larger than 32 bits"),
-               (unsigned long) (offset_expr.X_add_number >> 32),
-               (unsigned long) (offset_expr.X_add_number & 0xffffffff));
+       {
+         char value [32];
+
+         sprintf_vma (value, offset_expr.X_add_number);
+         as_bad (_("Number (0x%s) larger than 32 bits"), value);
+       }
 
       /* Even on a big endian machine $fn comes before $fn+1.  We have
         to adjust when loading from memory.  We set coproc if we must
@@ -7747,6 +7775,9 @@ validate_mips_insn (const struct mips_opcode *opc)
          case 'G': USE_BITS (OP_MASK_EXTMSBD,  OP_SH_EXTMSBD); break;
          case 'H': USE_BITS (OP_MASK_EXTMSBD,  OP_SH_EXTMSBD); break;
          case 'I': break;
+         case 't': USE_BITS (OP_MASK_RT,       OP_SH_RT);      break;
+         case 'T': USE_BITS (OP_MASK_RT,       OP_SH_RT);
+                   USE_BITS (OP_MASK_SEL,      OP_SH_SEL);     break;
          default:
            as_bad (_("internal: bad mips opcode (unknown extension operand type `+%c'): %s %s"),
                    c, opc->name, opc->args);
@@ -7808,6 +7839,22 @@ validate_mips_insn (const struct mips_opcode *opc)
       case '%': USE_BITS (OP_MASK_VECALIGN,    OP_SH_VECALIGN); break;
       case '[': break;
       case ']': break;
+      case '3': USE_BITS (OP_MASK_SA3,         OP_SH_SA3);     break;
+      case '4': USE_BITS (OP_MASK_SA4,         OP_SH_SA4);     break;
+      case '5': USE_BITS (OP_MASK_IMM8,        OP_SH_IMM8);    break;
+      case '6': USE_BITS (OP_MASK_RS,          OP_SH_RS);      break;
+      case '7': USE_BITS (OP_MASK_DSPACC,      OP_SH_DSPACC);  break;
+      case '8': USE_BITS (OP_MASK_WRDSP,       OP_SH_WRDSP);   break;
+      case '9': USE_BITS (OP_MASK_DSPACC_S,    OP_SH_DSPACC_S);break;
+      case '0': USE_BITS (OP_MASK_DSPSFT,      OP_SH_DSPSFT);  break;
+      case '\'': USE_BITS (OP_MASK_RDDSP,      OP_SH_RDDSP);   break;
+      case ':': USE_BITS (OP_MASK_DSPSFT_7,    OP_SH_DSPSFT_7);break;
+      case '@': USE_BITS (OP_MASK_IMM10,       OP_SH_IMM10);   break;
+      case '!': USE_BITS (OP_MASK_MT_U,                OP_SH_MT_U);    break;
+      case '$': USE_BITS (OP_MASK_MT_H,                OP_SH_MT_H);    break;
+      case '*': USE_BITS (OP_MASK_MTACC_T,     OP_SH_MTACC_T); break;
+      case '&': USE_BITS (OP_MASK_MTACC_D,     OP_SH_MTACC_D); break;
+      case 'g': USE_BITS (OP_MASK_RD,          OP_SH_RD);      break;
       default:
        as_bad (_("internal: bad mips opcode (unknown operand type `%c'): %s %s"),
                c, opc->name, opc->args);
@@ -7842,6 +7889,7 @@ mips_ip (char *str, struct mips_cl_insn *ip)
   unsigned int limlo, limhi;
   char *s_reset;
   char save_c = 0;
+  offsetT min_range, max_range;
 
   insn_error = NULL;
 
@@ -7904,6 +7952,8 @@ mips_ip (char *str, struct mips_cl_insn *ip)
                            (mips_opts.isa
                             | (file_ase_mips16 ? INSN_MIPS16 : 0)
                             | (mips_opts.ase_mdmx ? INSN_MDMX : 0)
+                            | (mips_opts.ase_dsp ? INSN_DSP : 0)
+                            | (mips_opts.ase_mt ? INSN_MT : 0)
                             | (mips_opts.ase_mips3d ? INSN_MIPS3D : 0)),
                            mips_opts.arch))
        ok = TRUE;
@@ -7956,6 +8006,229 @@ mips_ip (char *str, struct mips_cl_insn *ip)
                return;
              break;
 
+           case '3': /* dsp 3-bit unsigned immediate in bit 21 */
+             my_getExpression (&imm_expr, s);
+             check_absolute_expr (ip, &imm_expr);
+             if (imm_expr.X_add_number & ~OP_MASK_SA3)
+               {
+                 as_warn (_("DSP immediate not in range 0..%d (%lu)"),
+                          OP_MASK_SA3, (unsigned long) imm_expr.X_add_number);
+                 imm_expr.X_add_number &= OP_MASK_SA3;
+               }
+             ip->insn_opcode |= imm_expr.X_add_number << OP_SH_SA3;
+             imm_expr.X_op = O_absent;
+             s = expr_end;
+             continue;
+
+           case '4': /* dsp 4-bit unsigned immediate in bit 21 */
+             my_getExpression (&imm_expr, s);
+             check_absolute_expr (ip, &imm_expr);
+             if (imm_expr.X_add_number & ~OP_MASK_SA4)
+               {
+                 as_warn (_("DSP immediate not in range 0..%d (%lu)"),
+                          OP_MASK_SA4, (unsigned long) imm_expr.X_add_number);
+                 imm_expr.X_add_number &= OP_MASK_SA4;
+               }
+             ip->insn_opcode |= imm_expr.X_add_number << OP_SH_SA4;
+             imm_expr.X_op = O_absent;
+             s = expr_end;
+             continue;
+
+           case '5': /* dsp 8-bit unsigned immediate in bit 16 */
+             my_getExpression (&imm_expr, s);
+             check_absolute_expr (ip, &imm_expr);
+             if (imm_expr.X_add_number & ~OP_MASK_IMM8)
+               {
+                 as_warn (_("DSP immediate not in range 0..%d (%lu)"),
+                          OP_MASK_IMM8, (unsigned long) imm_expr.X_add_number);
+                 imm_expr.X_add_number &= OP_MASK_IMM8;
+               }
+             ip->insn_opcode |= imm_expr.X_add_number << OP_SH_IMM8;
+             imm_expr.X_op = O_absent;
+             s = expr_end;
+             continue;
+
+           case '6': /* dsp 5-bit unsigned immediate in bit 21 */
+             my_getExpression (&imm_expr, s);
+             check_absolute_expr (ip, &imm_expr);
+             if (imm_expr.X_add_number & ~OP_MASK_RS)
+               {
+                 as_warn (_("DSP immediate not in range 0..%d (%lu)"),
+                          OP_MASK_RS, (unsigned long) imm_expr.X_add_number);
+                 imm_expr.X_add_number &= OP_MASK_RS;
+               }
+             ip->insn_opcode |= imm_expr.X_add_number << OP_SH_RS;
+             imm_expr.X_op = O_absent;
+             s = expr_end;
+             continue;
+
+           case '7': /* four dsp accumulators in bits 11,12 */ 
+             if (s[0] == '$' && s[1] == 'a' && s[2] == 'c' &&
+                 s[3] >= '0' && s[3] <= '3')
+               {
+                 regno = s[3] - '0';
+                 s += 4;
+                 ip->insn_opcode |= regno << OP_SH_DSPACC;
+                 continue;
+               }
+             else
+               as_bad (_("Invalid dsp acc register"));
+             break;
+
+           case '8': /* dsp 6-bit unsigned immediate in bit 11 */
+             my_getExpression (&imm_expr, s);
+             check_absolute_expr (ip, &imm_expr);
+             if (imm_expr.X_add_number & ~OP_MASK_WRDSP)
+               {
+                 as_warn (_("DSP immediate not in range 0..%d (%lu)"),
+                          OP_MASK_WRDSP,
+                          (unsigned long) imm_expr.X_add_number);
+                 imm_expr.X_add_number &= OP_MASK_WRDSP;
+               }
+             ip->insn_opcode |= imm_expr.X_add_number << OP_SH_WRDSP;
+             imm_expr.X_op = O_absent;
+             s = expr_end;
+             continue;
+
+           case '9': /* four dsp accumulators in bits 21,22 */
+             if (s[0] == '$' && s[1] == 'a' && s[2] == 'c' &&
+                 s[3] >= '0' && s[3] <= '3')
+               {
+                 regno = s[3] - '0';
+                 s += 4;
+                 ip->insn_opcode |= regno << OP_SH_DSPACC_S;
+                 continue;
+               }
+             else
+               as_bad (_("Invalid dsp acc register"));
+             break;
+
+           case '0': /* dsp 6-bit signed immediate in bit 20 */
+             my_getExpression (&imm_expr, s);
+             check_absolute_expr (ip, &imm_expr);
+             min_range = -((OP_MASK_DSPSFT + 1) >> 1);
+             max_range = ((OP_MASK_DSPSFT + 1) >> 1) - 1;
+             if (imm_expr.X_add_number < min_range ||
+                 imm_expr.X_add_number > max_range)
+               {
+                 as_warn (_("DSP immediate not in range %ld..%ld (%ld)"),
+                          (long) min_range, (long) max_range,
+                          (long) imm_expr.X_add_number);
+               }
+             imm_expr.X_add_number &= OP_MASK_DSPSFT;
+             ip->insn_opcode |= ((unsigned long) imm_expr.X_add_number
+                                 << OP_SH_DSPSFT);
+             imm_expr.X_op = O_absent;
+             s = expr_end;
+             continue;
+
+           case '\'': /* dsp 6-bit unsigned immediate in bit 16 */
+             my_getExpression (&imm_expr, s);
+             check_absolute_expr (ip, &imm_expr);
+             if (imm_expr.X_add_number & ~OP_MASK_RDDSP)
+               {
+                 as_warn (_("DSP immediate not in range 0..%d (%lu)"),
+                          OP_MASK_RDDSP,
+                          (unsigned long) imm_expr.X_add_number);
+                 imm_expr.X_add_number &= OP_MASK_RDDSP;
+               }
+             ip->insn_opcode |= imm_expr.X_add_number << OP_SH_RDDSP;
+             imm_expr.X_op = O_absent;
+             s = expr_end;
+             continue;
+
+           case ':': /* dsp 7-bit signed immediate in bit 19 */
+             my_getExpression (&imm_expr, s);
+             check_absolute_expr (ip, &imm_expr);
+             min_range = -((OP_MASK_DSPSFT_7 + 1) >> 1);
+             max_range = ((OP_MASK_DSPSFT_7 + 1) >> 1) - 1;
+             if (imm_expr.X_add_number < min_range ||
+                 imm_expr.X_add_number > max_range)
+               {
+                 as_warn (_("DSP immediate not in range %ld..%ld (%ld)"),
+                          (long) min_range, (long) max_range,
+                          (long) imm_expr.X_add_number);
+               }
+             imm_expr.X_add_number &= OP_MASK_DSPSFT_7;
+             ip->insn_opcode |= ((unsigned long) imm_expr.X_add_number
+                                 << OP_SH_DSPSFT_7);
+             imm_expr.X_op = O_absent;
+             s = expr_end;
+             continue;
+
+           case '@': /* dsp 10-bit signed immediate in bit 16 */
+             my_getExpression (&imm_expr, s);
+             check_absolute_expr (ip, &imm_expr);
+             min_range = -((OP_MASK_IMM10 + 1) >> 1);
+             max_range = ((OP_MASK_IMM10 + 1) >> 1) - 1;
+             if (imm_expr.X_add_number < min_range ||
+                 imm_expr.X_add_number > max_range)
+               {
+                 as_warn (_("DSP immediate not in range %ld..%ld (%ld)"),
+                          (long) min_range, (long) max_range,
+                          (long) imm_expr.X_add_number);
+               }
+             imm_expr.X_add_number &= OP_MASK_IMM10;
+             ip->insn_opcode |= ((unsigned long) imm_expr.X_add_number
+                                 << OP_SH_IMM10);
+             imm_expr.X_op = O_absent;
+             s = expr_end;
+             continue;
+
+            case '!': /* mt 1-bit unsigned immediate in bit 5 */
+             my_getExpression (&imm_expr, s);
+             check_absolute_expr (ip, &imm_expr);
+             if (imm_expr.X_add_number & ~OP_MASK_MT_U)
+               {
+                 as_warn (_("MT immediate not in range 0..%d (%lu)"),
+                          OP_MASK_MT_U, (unsigned long) imm_expr.X_add_number);
+                 imm_expr.X_add_number &= OP_MASK_MT_U;
+               }
+             ip->insn_opcode |= imm_expr.X_add_number << OP_SH_MT_U;
+             imm_expr.X_op = O_absent;
+             s = expr_end;
+             continue;
+
+            case '$': /* mt 1-bit unsigned immediate in bit 4 */
+             my_getExpression (&imm_expr, s);
+             check_absolute_expr (ip, &imm_expr);
+             if (imm_expr.X_add_number & ~OP_MASK_MT_H)
+               {
+                 as_warn (_("MT immediate not in range 0..%d (%lu)"),
+                          OP_MASK_MT_H, (unsigned long) imm_expr.X_add_number);
+                 imm_expr.X_add_number &= OP_MASK_MT_H;
+               }
+             ip->insn_opcode |= imm_expr.X_add_number << OP_SH_MT_H;
+             imm_expr.X_op = O_absent;
+             s = expr_end;
+             continue;
+
+           case '*': /* four dsp accumulators in bits 18,19 */ 
+             if (s[0] == '$' && s[1] == 'a' && s[2] == 'c' &&
+                 s[3] >= '0' && s[3] <= '3')
+               {
+                 regno = s[3] - '0';
+                 s += 4;
+                 ip->insn_opcode |= regno << OP_SH_MTACC_T;
+                 continue;
+               }
+             else
+               as_bad (_("Invalid dsp/smartmips acc register"));
+             break;
+
+           case '&': /* four dsp accumulators in bits 13,14 */ 
+             if (s[0] == '$' && s[1] == 'a' && s[2] == 'c' &&
+                 s[3] >= '0' && s[3] <= '3')
+               {
+                 regno = s[3] - '0';
+                 s += 4;
+                 ip->insn_opcode |= regno << OP_SH_MTACC_D;
+                 continue;
+               }
+             else
+               as_bad (_("Invalid dsp/smartmips acc register"));
+             break;
+
            case ',':
              if (*s++ == *args)
                continue;
@@ -8103,10 +8376,39 @@ do_msbd:
                  if (imm2_expr.X_op != O_big
                      && imm2_expr.X_op != O_constant)
                  insn_error = _("absolute expression required");
-                 normalize_constant_expr (&imm2_expr);
+                 if (HAVE_32BIT_GPRS)
+                   normalize_constant_expr (&imm2_expr);
                  s = expr_end;
                  continue;
 
+               case 'T': /* Coprocessor register */
+                 /* +T is for disassembly only; never match.  */
+                 break;
+
+               case 't': /* Coprocessor register number */
+                 if (s[0] == '$' && ISDIGIT (s[1]))
+                   {
+                     ++s;
+                     regno = 0;
+                     do
+                       {
+                         regno *= 10;
+                         regno += *s - '0';
+                         ++s;
+                       }
+                     while (ISDIGIT (*s));
+                     if (regno > 31)
+                       as_bad (_("Invalid register number (%d)"), regno);
+                     else
+                       {
+                         ip->insn_opcode |= regno << OP_SH_RT;
+                         continue;
+                       }
+                   }
+                 else
+                   as_bad (_("Invalid coprocessor 0 register number"));
+                 break;
+
                default:
                  as_bad (_("internal: bad mips opcode (unknown extension operand type `+%c'): %s %s"),
                    *args, insn->name, insn->args);
@@ -8241,6 +8543,7 @@ do_msbd:
            case 'x':           /* ignore register name */
            case 'z':           /* must be zero register */
            case 'U':           /* destination register (clo/clz).  */
+           case 'g':           /* coprocessor destination register */
              s_reset = s;
              if (s[0] == '$')
                {
@@ -8365,6 +8668,7 @@ do_msbd:
                    case 'd':
                    case 'G':
                    case 'K':
+                   case 'g':
                      INSERT_OPERAND (RD, *ip, regno);
                      break;
                    case 'U':
@@ -8480,7 +8784,13 @@ do_msbd:
                            || strcmp (str, "lwc1") == 0
                            || strcmp (str, "swc1") == 0
                            || strcmp (str, "l.s") == 0
-                           || strcmp (str, "s.s") == 0))
+                           || strcmp (str, "s.s") == 0
+                           || strcmp (str, "mftc1") == 0
+                           || strcmp (str, "mfthc1") == 0
+                           || strcmp (str, "cftc1") == 0
+                           || strcmp (str, "mttc1") == 0
+                           || strcmp (str, "mtthc1") == 0
+                           || strcmp (str, "cttc1") == 0))
                    as_warn (_("Float register should be even, was %d"),
                             regno);
 
@@ -8571,7 +8881,8 @@ do_msbd:
              if (imm_expr.X_op != O_big
                  && imm_expr.X_op != O_constant)
                insn_error = _("absolute expression required");
-             normalize_constant_expr (&imm_expr);
+             if (HAVE_32BIT_GPRS)
+               normalize_constant_expr (&imm_expr);
              s = expr_end;
              continue;
 
@@ -10016,9 +10327,17 @@ struct option md_longopts[] =
   {"mdmx", no_argument, NULL, OPTION_MDMX},
 #define OPTION_NO_MDMX (OPTION_ASE_BASE + 5)
   {"no-mdmx", no_argument, NULL, OPTION_NO_MDMX},
+#define OPTION_DSP (OPTION_ASE_BASE + 6)
+  {"mdsp", no_argument, NULL, OPTION_DSP},
+#define OPTION_NO_DSP (OPTION_ASE_BASE + 7)
+  {"mno-dsp", no_argument, NULL, OPTION_NO_DSP},
+#define OPTION_MT (OPTION_ASE_BASE + 8)
+  {"mmt", no_argument, NULL, OPTION_MT},
+#define OPTION_NO_MT (OPTION_ASE_BASE + 9)
+  {"mno-mt", no_argument, NULL, OPTION_NO_MT},
 
   /* Old-style architecture options.  Don't add more of these.  */
-#define OPTION_COMPAT_ARCH_BASE (OPTION_ASE_BASE + 6)
+#define OPTION_COMPAT_ARCH_BASE (OPTION_ASE_BASE + 10)
 #define OPTION_M4650 (OPTION_COMPAT_ARCH_BASE + 0)
   {"m4650", no_argument, NULL, OPTION_M4650},
 #define OPTION_NO_M4650 (OPTION_COMPAT_ARCH_BASE + 1)
@@ -10270,6 +10589,22 @@ md_parse_option (int c, char *arg)
       mips_opts.ase_mdmx = 0;
       break;
 
+    case OPTION_DSP:
+      mips_opts.ase_dsp = 1;
+      break;
+
+    case OPTION_NO_DSP:
+      mips_opts.ase_dsp = 0;
+      break;
+
+    case OPTION_MT:
+      mips_opts.ase_mt = 1;
+      break;
+
+    case OPTION_NO_MT:
+      mips_opts.ase_mt = 0;
+      break;
+
     case OPTION_MIPS16:
       mips_opts.mips16 = 1;
       mips_no_prev_insn ();
@@ -10624,11 +10959,17 @@ mips_after_parse_args (void)
     mips_opts.ase_mips3d = (CPU_HAS_MIPS3D (file_mips_arch)) ? 1 : 0;
   if (mips_opts.ase_mdmx == -1)
     mips_opts.ase_mdmx = (CPU_HAS_MDMX (file_mips_arch)) ? 1 : 0;
+  if (mips_opts.ase_dsp == -1)
+    mips_opts.ase_dsp = (CPU_HAS_DSP (file_mips_arch)) ? 1 : 0;
+  if (mips_opts.ase_mt == -1)
+    mips_opts.ase_mt = (CPU_HAS_MT (file_mips_arch)) ? 1 : 0;
 
   file_mips_isa = mips_opts.isa;
   file_ase_mips16 = mips_opts.mips16;
   file_ase_mips3d = mips_opts.ase_mips3d;
   file_ase_mdmx = mips_opts.ase_mdmx;
+  file_ase_dsp = mips_opts.ase_dsp;
+  file_ase_mt = mips_opts.ase_mt;
   mips_opts.gp32 = file_mips_gp32;
   mips_opts.fp32 = file_mips_fp32;
 
@@ -10685,7 +11026,7 @@ mips_frob_file_before_adjust (void)
 }
 
 /* Sort any unmatched HI16 and GOT16 relocs so that they immediately precede
-   the corresponding LO16 reloc.  This is called before md_apply_fix3 and
+   the corresponding LO16 reloc.  This is called before md_apply_fix and
    tc_gen_reloc.  Unmatched relocs can only be generated by use of explicit
    relocation operators.
 
@@ -10904,7 +11245,7 @@ mips_validate_fix (struct fix *fixP, asection *seg)
 /* Apply a fixup to the object file.  */
 
 void
-md_apply_fix3 (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
+md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
 {
   bfd_byte *buf;
   long insn;
@@ -11396,35 +11737,50 @@ s_mips_globl (int x ATTRIBUTE_UNUSED)
   symbolS *symbolP;
   flagword flag;
 
-  name = input_line_pointer;
-  c = get_symbol_end ();
-  symbolP = symbol_find_or_make (name);
-  *input_line_pointer = c;
-  SKIP_WHITESPACE ();
-
-  /* On Irix 5, every global symbol that is not explicitly labelled as
-     being a function is apparently labelled as being an object.  */
-  flag = BSF_OBJECT;
-
-  if (! is_end_of_line[(unsigned char) *input_line_pointer])
+  do
     {
-      char *secname;
-      asection *sec;
-
-      secname = input_line_pointer;
+      name = input_line_pointer;
       c = get_symbol_end ();
-      sec = bfd_get_section_by_name (stdoutput, secname);
-      if (sec == NULL)
-       as_bad (_("%s: no such section"), secname);
+      symbolP = symbol_find_or_make (name);
+      S_SET_EXTERNAL (symbolP);
+
       *input_line_pointer = c;
+      SKIP_WHITESPACE ();
 
-      if (sec != NULL && (sec->flags & SEC_CODE) != 0)
-       flag = BSF_FUNCTION;
-    }
+      /* On Irix 5, every global symbol that is not explicitly labelled as
+         being a function is apparently labelled as being an object.  */
+      flag = BSF_OBJECT;
+
+      if (!is_end_of_line[(unsigned char) *input_line_pointer]
+         && (*input_line_pointer != ','))
+       {
+         char *secname;
+         asection *sec;
 
-  symbol_get_bfdsym (symbolP)->flags |= flag;
+         secname = input_line_pointer;
+         c = get_symbol_end ();
+         sec = bfd_get_section_by_name (stdoutput, secname);
+         if (sec == NULL)
+           as_bad (_("%s: no such section"), secname);
+         *input_line_pointer = c;
+
+         if (sec != NULL && (sec->flags & SEC_CODE) != 0)
+           flag = BSF_FUNCTION;
+       }
+
+      symbol_get_bfdsym (symbolP)->flags |= flag;
+
+      c = *input_line_pointer;
+      if (c == ',')
+       {
+         input_line_pointer++;
+         SKIP_WHITESPACE ();
+         if (is_end_of_line[(unsigned char) *input_line_pointer])
+           c = '\n';
+       }
+    }
+  while (c == ',');
 
-  S_SET_EXTERNAL (symbolP);
   demand_empty_rest_of_line ();
 }
 
@@ -11551,6 +11907,14 @@ s_mipsset (int x ATTRIBUTE_UNUSED)
     mips_opts.ase_mdmx = 1;
   else if (strcmp (name, "nomdmx") == 0)
     mips_opts.ase_mdmx = 0;
+  else if (strcmp (name, "dsp") == 0)
+    mips_opts.ase_dsp = 1;
+  else if (strcmp (name, "nodsp") == 0)
+    mips_opts.ase_dsp = 0;
+  else if (strcmp (name, "mt") == 0)
+    mips_opts.ase_mt = 1;
+  else if (strcmp (name, "nomt") == 0)
+    mips_opts.ase_mt = 0;
   else if (strncmp (name, "mips", 4) == 0 || strncmp (name, "arch=", 5) == 0)
     {
       int reset = 0;
@@ -13285,6 +13649,10 @@ mips_elf_final_processing (void)
     elf_elfheader (stdoutput)->e_flags |= EF_MIPS_CPIC;
 
   /* Set MIPS ELF flags for ASEs.  */
+  /* We may need to define a new flag for DSP ASE, and set this flag when
+     file_ase_dsp is true.  */
+  /* We may need to define a new flag for MT ASE, and set this flag when
+     file_ase_mt is true.  */
   if (file_ase_mips16)
     elf_elfheader (stdoutput)->e_flags |= EF_MIPS_ARCH_ASE_M16;
 #if 0 /* XXX FIXME */
@@ -13767,8 +14135,16 @@ static const struct mips_cpu_info mips_cpu_info_table[] =
   { "4km",            0,      ISA_MIPS32,     CPU_MIPS32 },
   { "4kp",            0,      ISA_MIPS32,     CPU_MIPS32 },
 
+  /* MIPS32 Release 2 */
+  { "m4k",            0,      ISA_MIPS32R2,   CPU_MIPS32R2 },
+  { "24k",            0,      ISA_MIPS32R2,   CPU_MIPS32R2 },
+  { "24kc",           0,      ISA_MIPS32R2,   CPU_MIPS32R2 },
+  { "24kf",           0,      ISA_MIPS32R2,   CPU_MIPS32R2 },
+  { "24kx",           0,      ISA_MIPS32R2,   CPU_MIPS32R2 },
+
   /* MIPS 64 */
   { "5kc",            0,      ISA_MIPS64,     CPU_MIPS64 },
+  { "5kf",            0,      ISA_MIPS64,     CPU_MIPS64 },
   { "20kc",           0,      ISA_MIPS64,     CPU_MIPS64 },
 
   /* Broadcom SB-1 CPU core */
@@ -13981,6 +14357,12 @@ MIPS options:\n\
 -mips16                        generate mips16 instructions\n\
 -no-mips16             do not generate mips16 instructions\n"));
   fprintf (stream, _("\
+-mdsp                  generate DSP instructions\n\
+-mno-dsp               do not generate DSP instructions\n"));
+  fprintf (stream, _("\
+-mmt                   generate MT instructions\n\
+-mno-mt                        do not generate MT instructions\n"));
+  fprintf (stream, _("\
 -mfix-vr4120           work around certain VR4120 errata\n\
 -mfix-vr4130           work around VR4130 mflo/mfhi errata\n\
 -mgp32                 use 32-bit GPRs, regardless of the chosen ISA\n\
This page took 0.037669 seconds and 4 git commands to generate.