* config/tc-mips.c (macro_build_jalr): Make sure we generate
[deliverable/binutils-gdb.git] / gas / config / tc-mips.c
index d66469e87c523a12d8c29e7fe3b5764033c476e8..c548ddec88075fde5c7e4e138bc370f33c008c60 100644 (file)
@@ -989,17 +989,26 @@ mips_target_format ()
       return "pe-mips";
     case bfd_target_elf_flavour:
 #ifdef TE_TMIPS
-      /* This is traditional mips */
+      /* This is traditional mips */
       return (target_big_endian
-             ? (HAVE_64BIT_OBJECTS ? "elf64-tradbigmips"
-                : "elf32-tradbigmips")
-             : (HAVE_64BIT_OBJECTS ? "elf64-tradlittlemips"
-                : "elf32-tradlittlemips"));
+             ? (HAVE_64BIT_OBJECTS
+                ? "elf64-tradbigmips"
+                : (HAVE_NEWABI
+                   ? "elf32-ntradbigmips" : "elf32-tradbigmips"))
+             : (HAVE_64BIT_OBJECTS
+                ? "elf64-tradlittlemips"
+                : (HAVE_NEWABI
+                   ? "elf32-ntradlittlemips" : "elf32-tradlittlemips")));
 #else
       return (target_big_endian
-             ? (HAVE_64BIT_OBJECTS ? "elf64-bigmips" : "elf32-bigmips")
-             : (HAVE_64BIT_OBJECTS ? "elf64-littlemips"
-                : "elf32-littlemips"));
+             ? (HAVE_64BIT_OBJECTS
+                ? "elf64-bigmips"
+                : (HAVE_NEWABI
+                   ? "elf32-nbigmips" : "elf32-bigmips"))
+             : (HAVE_64BIT_OBJECTS
+                ? "elf64-littlemips"
+                : (HAVE_NEWABI
+                   ? "elf32-nlittlemips" : "elf32-littlemips")));
 #endif
     default:
       abort ();
@@ -3000,12 +3009,18 @@ macro_build_jalr (icnt, ep)
      int icnt;
      expressionS *ep;
 {
+  char *f;
+  
   if (HAVE_NEWABI)
-    frag_more (0);
+    {
+      frag_grow (4);
+      f = frag_more (0);
+    }
   macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "jalr", "d,s",
               RA, PIC_CALL_REG);
   if (HAVE_NEWABI)
-    fix_new_exp (frag_now, 0, 0, ep, false, BFD_RELOC_MIPS_JALR);
+    fix_new_exp (frag_now, f - frag_now->fr_literal,
+                0, ep, false, BFD_RELOC_MIPS_JALR);
 }
 
 /*
@@ -3519,7 +3534,7 @@ load_address (counter, reg, ep, used_at)
          /* We don't do GP optimization for now because RELAX_ENCODE can't
             hold the data for such large chunks.  */
 
-         if (*used_at == 0)
+         if (*used_at == 0 && ! mips_opts.noat)
            {
              macro_build (p, counter, ep, "lui", "t,u",
                           reg, (int) BFD_RELOC_MIPS_HIGHEST);
@@ -4434,6 +4449,16 @@ macro (ip)
       if (! dbl && HAVE_64BIT_OBJECTS)
        as_warn (_("la used to load 64-bit address"));
 
+      if (offset_expr.X_op == O_constant
+         && offset_expr.X_add_number >= -0x8000
+         && offset_expr.X_add_number < 0x8000)
+       {
+         macro_build ((char *) NULL, &icnt, &offset_expr,
+                      (dbl || HAVE_64BIT_ADDRESSES) ? "daddiu" : "addiu",
+                      "t,r,j", treg, sreg, (int) BFD_RELOC_LO16);
+         return;
+       }
+
       if (treg == breg)
        {
          tempreg = AT;
@@ -4534,7 +4559,7 @@ macro (ip)
              /* We don't do GP optimization for now because RELAX_ENCODE can't
                 hold the data for such large chunks.  */
 
-             if (used_at == 0)
+             if (used_at == 0 && ! mips_opts.noat)
                {
                  macro_build (p, &icnt, &offset_expr, "lui", "t,u",
                               tempreg, (int) BFD_RELOC_MIPS_HIGHEST);
@@ -5487,7 +5512,7 @@ macro (ip)
              /* We don't do GP optimization for now because RELAX_ENCODE can't
                 hold the data for such large chunks.  */
 
-             if (used_at == 0)
+             if (used_at == 0 && ! mips_opts.noat)
                {
                  macro_build (p, &icnt, &offset_expr, "lui", "t,u",
                               tempreg, (int) BFD_RELOC_MIPS_HIGHEST);
@@ -8506,9 +8531,11 @@ mips_ip (str, ip)
                {
                  if (c != S_EX_LO)
                    {
-                     if (imm_expr.X_op == O_constant)
-                       imm_expr.X_add_number =
-                         (imm_expr.X_add_number >> 16) & 0xffff;
+                     if (c == S_EX_HI)
+                       {
+                         *imm_reloc = BFD_RELOC_HI16_S;
+                         imm_unmatched_hi = true;
+                       }
 #ifdef OBJ_ELF
                      else if (c == S_EX_HIGHEST)
                        *imm_reloc = BFD_RELOC_MIPS_HIGHEST;
@@ -8534,11 +8561,6 @@ mips_ip (str, ip)
                            }
                        }
 #endif
-                     else if (c == S_EX_HI)
-                       {
-                         *imm_reloc = BFD_RELOC_HI16_S;
-                         imm_unmatched_hi = true;
-                       }
                      else
                        *imm_reloc = BFD_RELOC_HI16;
                    }
@@ -8639,10 +8661,7 @@ mips_ip (str, ip)
                {
                  if (c != S_EX_LO)
                    {
-                     if (imm_expr.X_op == O_constant)
-                       imm_expr.X_add_number =
-                         (imm_expr.X_add_number >> 16) & 0xffff;
-                     else if (c == S_EX_HI)
+                     if (c == S_EX_HI)
                        {
                          *imm_reloc = BFD_RELOC_HI16_S;
                          imm_unmatched_hi = true;
@@ -8676,9 +8695,9 @@ mips_ip (str, ip)
                  else if (imm_expr.X_op == O_constant)
                    imm_expr.X_add_number &= 0xffff;
                }
-             if (imm_expr.X_op == O_constant
-                 && (imm_expr.X_add_number < 0
-                     || imm_expr.X_add_number >= 0x10000))
+             else if (imm_expr.X_op == O_constant
+                      && (imm_expr.X_add_number < 0
+                          || imm_expr.X_add_number >= 0x10000))
                as_bad (_("lui expression not in range 0..65535"));
              s = expr_end;
              continue;
@@ -11631,7 +11650,7 @@ s_cpsetup (ignore)
   expressionS ex_sym;
   int reg1;
   int icnt = 0;
-  char *sym;
+  char *f;
 
   /* If we are not generating SVR4 PIC code, .cpsetup is ignored.
      We also need NewABI support.  */
@@ -11670,15 +11689,7 @@ s_cpsetup (ignore)
   else
     ++input_line_pointer;
   SKIP_WHITESPACE ();
-  sym = input_line_pointer;
-  while (ISALNUM (*input_line_pointer))
-    ++input_line_pointer;
-  *input_line_pointer = 0;
-
-  ex_sym.X_op = O_symbol;
-  ex_sym.X_add_symbol = symbol_find_or_make (sym);
-  ex_sym.X_op_symbol = NULL;
-  ex_sym.X_add_number = 0;
+  expression (&ex_sym);
 
   if (mips_cpreturn_register == -1)
     {
@@ -11694,14 +11705,25 @@ s_cpsetup (ignore)
     macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "daddu",
                 "d,v,t", mips_cpreturn_register, mips_gp_register, 0);
 
+  /* Ensure there's room for the next two instructions, so that `f'
+     doesn't end up with an address in the wrong frag.  */
+  frag_grow (8);
+  f = frag_more (0);
   macro_build ((char *) NULL, &icnt, &ex_sym, "lui", "t,u", mips_gp_register,
               (int) BFD_RELOC_GPREL16);
-  fix_new (frag_now, prev_insn_where, 0, NULL, 0, 0, BFD_RELOC_MIPS_SUB);
-  fix_new (frag_now, prev_insn_where, 0, NULL, 0, 0, BFD_RELOC_HI16_S);
+  fix_new (frag_now, f - frag_now->fr_literal,
+          0, NULL, 0, 0, BFD_RELOC_MIPS_SUB);
+  fix_new (frag_now, f - frag_now->fr_literal,
+          0, NULL, 0, 0, BFD_RELOC_HI16_S);
+
+  f = frag_more (0);
   macro_build ((char *) NULL, &icnt, &ex_sym, "addiu", "t,r,j",
               mips_gp_register, mips_gp_register, (int) BFD_RELOC_GPREL16);
-  fix_new (frag_now, prev_insn_where, 0, NULL, 0, 0, BFD_RELOC_MIPS_SUB);
-  fix_new (frag_now, prev_insn_where, 0, NULL, 0, 0, BFD_RELOC_LO16);
+  fix_new (frag_now, f - frag_now->fr_literal,
+          0, NULL, 0, 0, BFD_RELOC_MIPS_SUB);
+  fix_new (frag_now, f - frag_now->fr_literal,
+          0, NULL, 0, 0, BFD_RELOC_LO16);
+
   macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
               HAVE_64BIT_ADDRESSES ? "daddu" : "addu", "d,v,t",
               mips_gp_register, mips_gp_register, reg1);
@@ -12685,7 +12707,7 @@ tc_gen_reloc (section, fixp)
      stop md_apply_fix3 from subtracting twice in the first place since
      the fake addend is required for variant frags above.  */
   if (fixp->fx_addsy != NULL && OUTPUT_FLAVOR == bfd_target_elf_flavour
-      && code == BFD_RELOC_GPREL16
+      && (code == BFD_RELOC_GPREL16 || code == BFD_RELOC_MIPS16_GPREL)
       && reloc->addend != 0
       && mips_need_elf_addend_fixup (fixp))
     reloc->addend += S_GET_VALUE (fixp->fx_addsy);
@@ -13480,11 +13502,8 @@ static const struct mips_cpu_info mips_cpu_info_table[] =
   { "5kc",            0,      ISA_MIPS64,     CPU_MIPS64 },
   { "20kc",           0,      ISA_MIPS64,     CPU_MIPS64 },
 
-  /* Broadcom SB-1 CPU */
-  { "SB-1",           0,      ISA_MIPS64,     CPU_SB1 },
-  { "sb-1250",        0,      ISA_MIPS64,     CPU_SB1 },
+  /* Broadcom SB-1 CPU core */
   { "sb1",            0,      ISA_MIPS64,     CPU_SB1 },
-  { "sb1250",         0,      ISA_MIPS64,     CPU_SB1 },
 
   /* End marker */
   { NULL, 0, 0, 0 }
This page took 0.032578 seconds and 4 git commands to generate.