Thu Mar 20 13:42:01 1997 H.J. Lu <hjl@lucon.org>
[binutils-gdb.git] / gas / config / tc-mips.c
index 5290f3b9d68a984f5369ce94b3bf9d456e788dcc..5a92c2490adb266e233a5fb7b0e45ac24994465d 100644 (file)
@@ -46,6 +46,7 @@
 
 #ifdef OBJ_MAYBE_ELF
 /* Clean up namespace so we can include obj-elf.h too.  */
+static int mips_output_flavor PARAMS ((void));
 static int mips_output_flavor () { return OUTPUT_FLAVOR; }
 #undef OBJ_PROCESS_STAB
 #undef OUTPUT_FLAVOR
@@ -1576,7 +1577,7 @@ append_insn (place, ip, address_expr, reloc_type, unmatched_hi)
                                          & INSN_UNCOND_BRANCH_DELAY),
                                         (prev_insn_reloc_type
                                          == BFD_RELOC_MIPS16_JMP)),
-                   make_expr_symbol (address_expr), (long) 0,
+                   make_expr_symbol (address_expr), (offsetT) 0,
                    (char *) NULL);
     }
   else if (place != NULL)
@@ -2791,8 +2792,12 @@ load_register (counter, reg, ep, dbl)
                    || ! ep->X_unsigned
                    || sizeof (ep->X_add_number) > 4
                    || (ep->X_add_number & 0x80000000) == 0))
-              || ((mips_isa < 3 || !dbl)
-                  && (ep->X_add_number &~ (offsetT) 0xffffffff) == 0))
+              || ((mips_isa < 3 || ! dbl)
+                  && (ep->X_add_number &~ (offsetT) 0xffffffff) == 0)
+              || (mips_isa < 3
+                  && ! dbl
+                  && ((ep->X_add_number &~ (offsetT) 0xffffffff)
+                      == ~ (offsetT) 0xffffffff)))
        {
          /* 32 bit values require an lui.  */
          macro_build ((char *) NULL, counter, ep, "lui", "t,u", reg,
@@ -3050,7 +3055,7 @@ load_address (counter, reg, ep)
                       "t,r,j", reg, GP, (int) BFD_RELOC_MIPS_GPREL);
          p = frag_var (rs_machine_dependent, 8, 0,
                        RELAX_ENCODE (4, 8, 0, 4, 0, mips_warn_about_macros),
-                       ep->X_add_symbol, (long) 0, (char *) NULL);
+                       ep->X_add_symbol, (offsetT) 0, (char *) NULL);
        }
       macro_build_lui (p, counter, ep, reg);
       if (p != NULL)
@@ -3079,7 +3084,7 @@ load_address (counter, reg, ep)
       macro_build ((char *) NULL, counter, (expressionS *) NULL, "nop", "");
       p = frag_var (rs_machine_dependent, 4, 0,
                    RELAX_ENCODE (0, 4, -8, 0, 0, mips_warn_about_macros),
-                   ep->X_add_symbol, (long) 0, (char *) NULL);
+                   ep->X_add_symbol, (offsetT) 0, (char *) NULL);
       macro_build (p, counter, ep,
                   mips_isa < 3 ? "addiu" : "daddiu",
                   "t,r,j", reg, reg, (int) BFD_RELOC_LO16);
@@ -3126,7 +3131,7 @@ load_address (counter, reg, ep)
       p = frag_var (rs_machine_dependent, 12 + off, 0,
                    RELAX_ENCODE (12, 12 + off, off, 8 + off, 0,
                                  mips_warn_about_macros),
-                   ep->X_add_symbol, (long) 0, (char *) NULL);
+                   ep->X_add_symbol, (offsetT) 0, (char *) NULL);
       if (off > 0)
        {
          /* We need a nop before loading from $gp.  This special
@@ -3921,7 +3926,7 @@ macro (ip)
              p = frag_var (rs_machine_dependent, 8, 0,
                            RELAX_ENCODE (4, 8, 0, 4, 0,
                                          mips_warn_about_macros),
-                           offset_expr.X_add_symbol, (long) 0,
+                           offset_expr.X_add_symbol, (offsetT) 0,
                            (char *) NULL);
            }
          macro_build_lui (p, &icnt, &offset_expr, tempreg);
@@ -3985,7 +3990,7 @@ macro (ip)
                                          (breg == 0
                                           ? mips_warn_about_macros
                                           : 0)),
-                           offset_expr.X_add_symbol, (long) 0,
+                           offset_expr.X_add_symbol, (offsetT) 0,
                            (char *) NULL);
              if (breg == 0)
                {
@@ -4009,7 +4014,7 @@ macro (ip)
                           "t,r,j", tempreg, tempreg, (int) BFD_RELOC_LO16);
              (void) frag_var (rs_machine_dependent, 0, 0,
                               RELAX_ENCODE (0, 0, -12, -4, 0, 0),
-                              offset_expr.X_add_symbol, (long) 0,
+                              offset_expr.X_add_symbol, (offsetT) 0,
                               (char *) NULL);
            }
          else
@@ -4052,7 +4057,7 @@ macro (ip)
                           "d,v,t", tempreg, tempreg, AT);
              (void) frag_var (rs_machine_dependent, 0, 0,
                               RELAX_ENCODE (0, 0, -16 + off1, -8, 0, 0),
-                              offset_expr.X_add_symbol, (long) 0,
+                              offset_expr.X_add_symbol, (offsetT) 0,
                               (char *) NULL);
              used_at = 1;
            }
@@ -4135,7 +4140,7 @@ macro (ip)
                                          (breg == 0
                                           ? mips_warn_about_macros
                                           : 0)),
-                           offset_expr.X_add_symbol, (long) 0,
+                           offset_expr.X_add_symbol, (offsetT) 0,
                            (char *) NULL);
            }
          else if (expr1.X_add_number >= -0x8000
@@ -4152,7 +4157,7 @@ macro (ip)
                                          (breg == 0
                                           ? mips_warn_about_macros
                                           : 0)),
-                           offset_expr.X_add_symbol, (long) 0,
+                           offset_expr.X_add_symbol, (offsetT) 0,
                            (char *) NULL);
            }
          else
@@ -4203,7 +4208,7 @@ macro (ip)
                                          (breg == 0
                                           ? mips_warn_about_macros
                                           : 0)),
-                           offset_expr.X_add_symbol, (long) 0,
+                           offset_expr.X_add_symbol, (offsetT) 0,
                            (char *) NULL);
 
              used_at = 1;
@@ -4369,7 +4374,8 @@ macro (ip)
                           "nop", "");
              p = frag_var (rs_machine_dependent, 4, 0,
                            RELAX_ENCODE (0, 4, -8, 0, 0, 0),
-                           offset_expr.X_add_symbol, (long) 0, (char *) NULL);
+                           offset_expr.X_add_symbol, (offsetT) 0,
+                           (char *) NULL);
            }
          else
            {
@@ -4393,7 +4399,8 @@ macro (ip)
              p = frag_var (rs_machine_dependent, 12 + gpdel, 0,
                            RELAX_ENCODE (16, 12 + gpdel, gpdel, 8 + gpdel,
                                          0, 0),
-                           offset_expr.X_add_symbol, (long) 0, (char *) NULL);
+                           offset_expr.X_add_symbol, (offsetT) 0,
+                           (char *) NULL);
              if (gpdel > 0)
                {
                  macro_build (p, &icnt, (expressionS *) NULL, "nop", "");
@@ -4647,7 +4654,7 @@ macro (ip)
                                RELAX_ENCODE (4, 8, 0, 4, 0,
                                              (mips_warn_about_macros
                                               || (used_at && mips_noat))),
-                               offset_expr.X_add_symbol, (long) 0,
+                               offset_expr.X_add_symbol, (offsetT) 0,
                                (char *) NULL);
                  used_at = 0;
                }
@@ -4672,7 +4679,7 @@ macro (ip)
                               treg, (int) BFD_RELOC_MIPS_GPREL, tempreg);
                  p = frag_var (rs_machine_dependent, 12, 0,
                                RELAX_ENCODE (8, 12, 0, 8, 0, 0),
-                               offset_expr.X_add_symbol, (long) 0,
+                               offset_expr.X_add_symbol, (offsetT) 0,
                                (char *) NULL);
                }
              macro_build_lui (p, &icnt, &offset_expr, tempreg);
@@ -4717,7 +4724,7 @@ macro (ip)
          macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "nop", "");
          p = frag_var (rs_machine_dependent, 4, 0, 
                        RELAX_ENCODE (0, 4, -8, 0, 0, 0),
-                       offset_expr.X_add_symbol, (long) 0,
+                       offset_expr.X_add_symbol, (offsetT) 0,
                        (char *) NULL);
          macro_build (p, &icnt, &offset_expr,
                       mips_isa < 3 ? "addiu" : "daddiu",
@@ -4771,7 +4778,7 @@ macro (ip)
                       tempreg);
          p = frag_var (rs_machine_dependent, 12 + gpdel, 0,
                        RELAX_ENCODE (12, 12 + gpdel, gpdel, 8 + gpdel, 0, 0),
-                       offset_expr.X_add_symbol, (long) 0, (char *) NULL);
+                       offset_expr.X_add_symbol, (offsetT) 0, (char *) NULL);
          if (gpdel > 0)
            {
              macro_build (p, &icnt, (expressionS *) NULL, "nop", "");
@@ -5114,7 +5121,7 @@ macro (ip)
              p = frag_var (rs_machine_dependent, 12 + off, 0,
                            RELAX_ENCODE (8 + off, 12 + off, 0, 4 + off, 1,
                                          used_at && mips_noat),
-                           offset_expr.X_add_symbol, (long) 0,
+                           offset_expr.X_add_symbol, (offsetT) 0,
                            (char *) NULL);
 
              /* We just generated two relocs.  When tc_gen_reloc
@@ -5206,7 +5213,7 @@ macro (ip)
 
          (void) frag_var (rs_machine_dependent, 0, 0,
                           RELAX_ENCODE (0, 0, -16 - off, -8, 1, 0),
-                          offset_expr.X_add_symbol, (long) 0,
+                          offset_expr.X_add_symbol, (offsetT) 0,
                           (char *) NULL);
        }
       else if (mips_pic == SVR4_PIC)
@@ -5276,7 +5283,7 @@ macro (ip)
          p = frag_var (rs_machine_dependent, 16 + gpdel + off, 0,
                        RELAX_ENCODE (24 + off, 16 + gpdel + off, gpdel,
                                      8 + gpdel + off, 1, 0),
-                       offset_expr.X_add_symbol, (long) 0,
+                       offset_expr.X_add_symbol, (offsetT) 0,
                        (char *) NULL);
          if (gpdel > 0)
            {
@@ -8068,12 +8075,12 @@ struct option md_longopts[] = {
   {"mips16", no_argument, NULL, OPTION_MIPS16},
 #define OPTION_NO_MIPS16 (OPTION_MD_BASE + 23)
   {"no-mips16", no_argument, NULL, OPTION_NO_MIPS16},
-  /* start-sanitize-5900 */
+  /* start-sanitize-r5900 */
 #define OPTION_M5900 (OPTION_MD_BASE + 24)
   {"m5900", no_argument, NULL, OPTION_M5900},
 #define OPTION_NO_M5900 (OPTION_MD_BASE + 25)
   {"no-m5900", no_argument, NULL, OPTION_NO_M5900},
-  /* end-sanitize-5900 */
+  /* end-sanitize-r5900 */
 
 #define OPTION_CALL_SHARED (OPTION_MD_BASE + 7)
 #define OPTION_NON_SHARED (OPTION_MD_BASE + 8)
@@ -8858,7 +8865,7 @@ md_apply_fix (fixP, valueP)
                  handle these cases, but it appears to do it
                  incorrectly.  */
              as_bad_where (fixP->fx_file, fixP->fx_line,
-                           "Relocation overflow");
+                           "Branch out of range");
            }
        }
 
@@ -9922,7 +9929,26 @@ md_estimate_size_before_relax (fragp, segtype)
     }
   else if (mips_pic == SVR4_PIC)
     {
-      asection *symsec = fragp->fr_symbol->bsym->section;
+      symbolS *sym;
+      asection *symsec;
+
+      sym = fragp->fr_symbol;
+
+      /* Handle the case of a symbol equated to another symbol.  */
+      while (sym->sy_value.X_op == O_symbol
+            && (! S_IS_DEFINED (sym) || S_IS_COMMON (sym)))
+       {
+         symbolS *n;
+
+         /* It's possible to get a loop here in a badly written
+             program.  */
+         n = sym->sy_value.X_add_symbol;
+         if (n == sym)
+           break;
+         sym = n;
+       }
+
+      symsec = S_GET_SEGMENT (sym);
 
       /* This must duplicate the test in adjust_reloc_syms.  */
       change = (symsec != &bfd_und_section
@@ -9969,7 +9995,8 @@ mips_fix_adjustable (fixp)
     return 1;
 #ifdef S_GET_OTHER
   if (OUTPUT_FLAVOR == bfd_target_elf_flavour
-      && S_GET_OTHER (fixp->fx_addsy) == STO_MIPS16)
+      && S_GET_OTHER (fixp->fx_addsy) == STO_MIPS16
+      && fixp->fx_subsy == NULL)
     return 0;
 #endif
   return 1;