mips gas patches

Alan Modra amodra@bigpond.net.au
Thu Jun 7 23:06:00 GMT 2001


I've had these patches in my tree for a while, and thought I'd
better get them in as HJ is on the loose in tc-mips.c.  :-)
The only real changes here are in mips16_extended_frag.

gas/ChangeLog
	* Makefile.am: 'som' is not wrongly spelled 'some'.
	* Makefile.in: Regenerate.

	* config/tc-mips.c (mips16_mark_labels): Reduce number of calls to
	S_GET_VALUE by using a temp.
	(append_insn): Likewise, and for S_GET_VALUE too.
	(mips_emit_delays): Likewise.
	(my_getExpression): Likewise.
	(md_apply_fix): Likewise.  Use "valueT" rather than "long" for "value".
	(mips16_extended_frag): Remove code concerned with avoiding
	locking in a frag address now that symbols are not finalized until
	relaxation is complete.  Cater for first relaxation pass having
	bogus addresses.  Use relax_marker to reliably determine whether a
	symbol frag has been reached on the current pass.

-- 
Alan Modra

Index: Makefile.am
===================================================================
RCS file: /cvs/src/src/gas/Makefile.am,v
retrieving revision 1.37
diff -u -p -r1.37 Makefile.am
--- Makefile.am	2001/05/03 02:07:00	1.37
+++ Makefile.am	2001/06/08 05:36:13
@@ -80,7 +80,7 @@ CPU_TYPES = \
 	z8k
 
 # Object format types.  This is only used for dependency information.
-# We deliberately omit some, since it does not work as a cross assembler.
+# We deliberately omit SOM, since it does not work as a cross assembler.
 
 OBJ_FORMATS = \
 	aout \
Index: config/tc-mips.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-mips.c,v
retrieving revision 1.43
diff -u -p -r1.43 tc-mips.c
--- tc-mips.c	2001/06/07 16:52:19	1.43
+++ tc-mips.c	2001/06/08 05:36:21
@@ -1384,6 +1384,7 @@ mips16_mark_labels ()
   if (mips_opts.mips16)
     {
       struct insn_label_list *l;
+      valueT val;
 
       for (l = insn_labels; l != NULL; l = l->next)
 	{
@@ -1391,8 +1392,9 @@ mips16_mark_labels ()
 	  if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
 	    S_SET_OTHER (l->label, STO_MIPS16);
 #endif
-	  if ((S_GET_VALUE (l->label) & 1) == 0)
-	    S_SET_VALUE (l->label, S_GET_VALUE (l->label) + 1);
+	  val = S_GET_VALUE (l->label);
+	  if ((val & 1) == 0)
+	    S_SET_VALUE (l->label, val + 1);
 	}
     }
 }
@@ -1703,12 +1705,15 @@ append_insn (place, ip, address_expr, re
 
 	  for (l = insn_labels; l != NULL; l = l->next)
 	    {
+	      valueT val;
+
 	      assert (S_GET_SEGMENT (l->label) == now_seg);
 	      symbol_set_frag (l->label, frag_now);
-	      S_SET_VALUE (l->label, (valueT) frag_now_fix ());
+	      val = (valueT) frag_now_fix ();
 	      /* mips16 text labels are stored as odd.  */
 	      if (mips_opts.mips16)
-		S_SET_VALUE (l->label, S_GET_VALUE (l->label) + 1);
+		val += 1;
+	      S_SET_VALUE (l->label, val);
 	    }
 
 #ifndef NO_ECOFF_DEBUGGING
@@ -2406,12 +2411,15 @@ mips_emit_delays (insns)
 
 	  for (l = insn_labels; l != NULL; l = l->next)
 	    {
+	      valueT val;
+
 	      assert (S_GET_SEGMENT (l->label) == now_seg);
 	      symbol_set_frag (l->label, frag_now);
-	      S_SET_VALUE (l->label, (valueT) frag_now_fix ());
+	      val = (valueT) frag_now_fix ();
 	      /* mips16 text labels are stored as odd.  */
 	      if (mips_opts.mips16)
-		S_SET_VALUE (l->label, S_GET_VALUE (l->label) + 1);
+		val += 1;
+	      S_SET_VALUE (l->label, val);
 	    }
 	}
     }
@@ -8759,6 +8767,7 @@ my_getExpression (ep, str)
      char *str;
 {
   char *save_in;
+  valueT val;
 
   save_in = input_line_pointer;
   input_line_pointer = str;
@@ -8776,8 +8785,8 @@ my_getExpression (ep, str)
       && S_GET_SEGMENT (ep->X_add_symbol) == now_seg
       && symbol_get_frag (ep->X_add_symbol) == frag_now
       && symbol_constant_p (ep->X_add_symbol)
-      && S_GET_VALUE (ep->X_add_symbol) == frag_now_fix ())
-    S_SET_VALUE (ep->X_add_symbol, S_GET_VALUE (ep->X_add_symbol) + 1);
+      && (val = S_GET_VALUE (ep->X_add_symbol)) == frag_now_fix ())
+    S_SET_VALUE (ep->X_add_symbol, val + 1);
 }
 
 /* Turn a string in input_line_pointer into a floating point constant
@@ -9512,7 +9521,8 @@ md_apply_fix (fixP, valueP)
      valueT *valueP;
 {
   unsigned char *buf;
-  long insn, value;
+  long insn;
+  valueT value;
 
   assert (fixP->fx_size == 4
 	  || fixP->fx_r_type == BFD_RELOC_16
@@ -9527,27 +9537,28 @@ md_apply_fix (fixP, valueP)
 #ifdef OBJ_ELF
   if (fixP->fx_addsy != NULL && OUTPUT_FLAVOR == bfd_target_elf_flavour)
     {
-    if (S_GET_OTHER (fixP->fx_addsy) == STO_MIPS16
-        || S_IS_WEAK (fixP->fx_addsy)
-        || (symbol_used_in_reloc_p (fixP->fx_addsy)
-            && (((bfd_get_section_flags (stdoutput,
-                                         S_GET_SEGMENT (fixP->fx_addsy))
-                  & SEC_LINK_ONCE) != 0)
-                || !strncmp (segment_name (S_GET_SEGMENT (fixP->fx_addsy)),
-                             ".gnu.linkonce",
-                             sizeof (".gnu.linkonce") - 1))))
-
-      {
-        value -= S_GET_VALUE (fixP->fx_addsy);
-        if (value != 0 && ! fixP->fx_pcrel)
-          {
-            /* In this case, the bfd_install_relocation routine will
-               incorrectly add the symbol value back in.  We just want
-               the addend to appear in the object file.
-	       FIXME: If this makes VALUE zero, we're toast.  */
-            value -= S_GET_VALUE (fixP->fx_addsy);
-          }
-      }
+      if (S_GET_OTHER (fixP->fx_addsy) == STO_MIPS16
+	  || S_IS_WEAK (fixP->fx_addsy)
+	  || (symbol_used_in_reloc_p (fixP->fx_addsy)
+	      && (((bfd_get_section_flags (stdoutput,
+					   S_GET_SEGMENT (fixP->fx_addsy))
+		    & SEC_LINK_ONCE) != 0)
+		  || !strncmp (segment_name (S_GET_SEGMENT (fixP->fx_addsy)),
+			       ".gnu.linkonce",
+			       sizeof (".gnu.linkonce") - 1))))
+
+	{
+	  valueT symval = S_GET_VALUE (fixP->fx_addsy);
+	  value -= symval;
+	  if (value != 0 && ! fixP->fx_pcrel)
+	    {
+	      /* In this case, the bfd_install_relocation routine will
+		 incorrectly add the symbol value back in.  We just want
+		 the addend to appear in the object file.
+		 FIXME: If this makes VALUE zero, we're toast.  */
+	      value -= symval;
+	    }
+	}
 
       /* This code was generated using trial and error and so is
 	 fragile and not trustworthy.  If you change it, you should
@@ -9697,7 +9708,7 @@ md_apply_fix (fixP, valueP)
 	 up deleting a LO16 reloc.  See the 'o' case in mips_ip.  */
       if (fixP->fx_done)
 	{
-	  if (value < -0x8000 || value > 0x7fff)
+	  if (value + 0x8000 > 0xffff)
 	    as_bad_where (fixP->fx_file, fixP->fx_line,
 			  _("relocation overflow"));
 	  buf = (unsigned char *) fixP->fx_frag->fr_literal + fixP->fx_where;
@@ -9715,7 +9726,7 @@ md_apply_fix (fixP, valueP)
        */
       if ((value & 0x3) != 0)
 	as_bad_where (fixP->fx_file, fixP->fx_line,
-		      _("Branch to odd address (%lx)"), value);
+		      _("Branch to odd address (%lx)"), (long) value);
 
       if (!fixP->fx_done && value != 0)
 	break;
@@ -9725,7 +9736,7 @@ md_apply_fix (fixP, valueP)
       if (!fixP->fx_done)
 	value -= fixP->fx_frag->fr_address + fixP->fx_where;
 
-      value >>= 2;
+      value = (offsetT) value >> 2;
 
       /* update old instruction data */
       buf = (unsigned char *) (fixP->fx_where + fixP->fx_frag->fr_literal);
@@ -9734,7 +9745,7 @@ md_apply_fix (fixP, valueP)
       else
 	insn = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
 
-      if (value >= -0x8000 && value < 0x8000)
+      if (value + 0x8000 <= 0xffff)
 	insn |= value & 0xffff;
       else
 	{
@@ -10751,6 +10762,7 @@ mips16_extended_frag (fragp, sec, stretc
   offsetT val;
   int mintiny, maxtiny;
   segT symsec;
+  fragS *sym_frag;
 
   if (RELAX_MIPS16_USER_SMALL (fragp->fr_subtype))
     return 0;
@@ -10784,29 +10796,9 @@ mips16_extended_frag (fragp, sec, stretc
       maxtiny = (1 << (op->nbits - 1)) - 1;
     }
 
-  /* We can't always call S_GET_VALUE here, because we don't want to
-     lock in a particular frag address.  */
-  if (symbol_constant_p (fragp->fr_symbol))
-    {
-      val = (S_GET_VALUE (fragp->fr_symbol)
-	     + symbol_get_frag (fragp->fr_symbol)->fr_address);
-      symsec = S_GET_SEGMENT (fragp->fr_symbol);
-    }
-  else if (symbol_equated_p (fragp->fr_symbol)
-	   && (symbol_constant_p
-	       (symbol_get_value_expression (fragp->fr_symbol)->X_add_symbol)))
-    {
-      symbolS *eqsym;
-
-      eqsym = symbol_get_value_expression (fragp->fr_symbol)->X_add_symbol;
-      val = (S_GET_VALUE (eqsym)
-	     + symbol_get_frag (eqsym)->fr_address
-	     + symbol_get_value_expression (fragp->fr_symbol)->X_add_number
-	     + symbol_get_frag (fragp->fr_symbol)->fr_address);
-      symsec = S_GET_SEGMENT (eqsym);
-    }
-  else
-    return 1;
+  sym_frag = symbol_get_frag (fragp->fr_symbol);
+  val = S_GET_VALUE (fragp->fr_symbol) + sym_frag->fr_address;
+  symsec = S_GET_SEGMENT (fragp->fr_symbol);
 
   if (op->pcrel)
     {
@@ -10825,6 +10817,7 @@ mips16_extended_frag (fragp, sec, stretc
 	}
       else
 	{
+	  /* Must have been called from md_estimate_size_before_relax.  */
 	  if (symsec != sec)
 	    {
 	      fragp->fr_subtype =
@@ -10837,16 +10830,22 @@ mips16_extended_frag (fragp, sec, stretc
 
 	      return 1;
 	    }
+	  if (fragp != sym_frag && sym_frag->fr_address == 0)
+	    /* Assume non-extended on the first relaxation pass.
+	       The address we have calculated will be bogus if this is
+	       a forward branch to another frag, as the forward frag
+	       will have fr_address == 0.  */
+	    return 0;
 	}
 
       /* In this case, we know for sure that the symbol fragment is in
-	 the same section.  If the fr_address of the symbol fragment
-	 is greater then the address of this fragment we want to add
+	 the same section.  If the relax_marker of the symbol fragment
+	 differs from the relax_marker of this fragment, we have not
+	 yet adjusted the symbol fragment fr_address.  We want to add
 	 in STRETCH in order to get a better estimate of the address.
 	 This particularly matters because of the shift bits.  */
       if (stretch != 0
-	  && (symbol_get_frag (fragp->fr_symbol)->fr_address
-	      >= fragp->fr_address))
+	  && sym_frag->relax_marker != fragp->relax_marker)
 	{
 	  fragS *f;
 
@@ -10856,9 +10855,7 @@ mips16_extended_frag (fragp, sec, stretc
              This doesn't handle the fr_subtype field, which specifies
              a maximum number of bytes to skip when doing an
              alignment.  */
-	  for (f = fragp;
-	       f != NULL && f != symbol_get_frag (fragp->fr_symbol);
-	       f = f->fr_next)
+	  for (f = fragp; f != NULL && f != sym_frag; f = f->fr_next)
 	    {
 	      if (f->fr_type == rs_align || f->fr_type == rs_align_code)
 		{



More information about the Binutils mailing list