* write.c (is_dnrange): Stop as soon as the address becomes
authorIan Lance Taylor <ian@airs.com>
Tue, 13 Feb 2001 21:27:52 +0000 (21:27 +0000)
committerIan Lance Taylor <ian@airs.com>
Tue, 13 Feb 2001 21:27:52 +0000 (21:27 +0000)
larger.
(relax_frag): Add segment parameter.  Only call symbol_get_frag
once.  Only call is_dnrange if the symbol is in the same segment,
and the symbol address is larger.
(relax_segment): Pass segment to md_relax_frag and relax_frag.
* write.h (relax_frag): Update declaration.
* config/tc-fr30.c (fr30_relax_frag): Add segment parameter.  Pass
it to relax_frag.
* config/tc-m32r.c (m32r_relax_frag): Likewise.
* config/tc-m32r.h (md_relax_frag): Add segment parameter.
(m32r_relax_frag): Update declaration.
* config/tc-mips.h (md_relax_frag): Add segment parameter.
* config/tc-tic54x.h (md_relax_frag): Likewise.
* doc/internals.texi (CPU backend): Update documentation for
md_relax_frag.

gas/ChangeLog
gas/config/tc-fr30.c
gas/config/tc-m32r.c
gas/config/tc-m32r.h
gas/config/tc-mips.h
gas/config/tc-tic54x.h
gas/doc/internals.texi
gas/write.c
gas/write.h

index b9be46907cdaa66c4068a1ddcbf1bb71fbc44ead..a2e30b1c92b1d07005c0f1bb4a7cbdafd117b88e 100644 (file)
@@ -1,3 +1,22 @@
+2001-02-13  Ian Lance Taylor  <ian@zembu.com>
+
+       * write.c (is_dnrange): Stop as soon as the address becomes
+       larger.
+       (relax_frag): Add segment parameter.  Only call symbol_get_frag
+       once.  Only call is_dnrange if the symbol is in the same segment,
+       and the symbol address is larger.
+       (relax_segment): Pass segment to md_relax_frag and relax_frag.
+       * write.h (relax_frag): Update declaration.
+       * config/tc-fr30.c (fr30_relax_frag): Add segment parameter.  Pass
+       it to relax_frag.
+       * config/tc-m32r.c (m32r_relax_frag): Likewise.
+       * config/tc-m32r.h (md_relax_frag): Add segment parameter.
+       (m32r_relax_frag): Update declaration.
+       * config/tc-mips.h (md_relax_frag): Add segment parameter.
+       * config/tc-tic54x.h (md_relax_frag): Likewise.
+       * doc/internals.texi (CPU backend): Update documentation for
+       md_relax_frag.
+
 2001-02-13  Alan Modra  <alan@linuxcare.com.au>
 
        * doc/c-i386.texi (i386-Arch): Add "jumps"/"nojumps" blurb.
index c61a8affedd5d9f23ed82dfa6ec46eb256d3a1c2..ea7ffb5701b3ad46088223d75d8f875a562b2405 100644 (file)
@@ -208,7 +208,8 @@ const relax_typeS md_relax_table[] =
 };
 
 long
-fr30_relax_frag (fragP, stretch)
+fr30_relax_frag (segment, fragP, stretch)
+     segT    segment;
      fragS * fragP;
      long    stretch;
 {
@@ -235,7 +236,7 @@ fr30_relax_frag (fragP, stretch)
     }
   else
     {
-      growth = relax_frag (fragP, stretch);
+      growth = relax_frag (segment, fragP, stretch);
 
       /* Long jump on odd halfword boundary?  */
       if (fragP->fr_subtype == 2 && (address & 3) != 0)
index 062181e05ed75b98cff7c6b42b0f60f3201c0542..cf68fe346e5cdd8e00710ede27174cc4753da08f 100644 (file)
@@ -1384,7 +1384,8 @@ const relax_typeS md_relax_table[] =
 };
 
 long
-m32r_relax_frag (fragP, stretch)
+m32r_relax_frag (segment, fragP, stretch)
+     segT segment;
      fragS *fragP;
      long stretch;
 {
@@ -1411,7 +1412,7 @@ m32r_relax_frag (fragP, stretch)
     }
   else
     {
-      growth = relax_frag (fragP, stretch);
+      growth = relax_frag (segment, fragP, stretch);
 
       /* Long jump on odd halfword boundary?  */
       if (fragP->fr_subtype == 2 && (address & 3) != 0)
index 9e04c19158ce68670670203f8285301f86b35f60..98bfb8da012e40eb43c0c599b8c649124737aa26 100644 (file)
@@ -54,9 +54,9 @@ extern void m32r_prepare_relax_scan ();
 #define md_prepare_relax_scan(fragP, address, aim, this_state, this_type) \
 m32r_prepare_relax_scan (fragP, address, aim, this_state, this_type)
 #else
-extern long m32r_relax_frag PARAMS ((fragS *, long));
-#define md_relax_frag(fragP, stretch) \
-m32r_relax_frag (fragP, stretch)
+extern long m32r_relax_frag PARAMS ((segT, fragS *, long));
+#define md_relax_frag(segment, fragP, stretch) \
+m32r_relax_frag (segment, fragP, stretch)
 #endif
 /* Account for nop if 32 bit insn falls on odd halfword boundary.  */
 #define TC_CGEN_MAX_RELAX(insn, len) (6)
index 561d5d7f0d557d7a38f1eee6ae8b91260cf61b60..72e734f221b83d48c31490f51e12d4095caa65a0 100644 (file)
@@ -49,7 +49,7 @@ struct expressionS;
    relocation: */
 #define MAX_GPREL_OFFSET (0x7FF4)
 
-#define md_relax_frag(fragp, stretch) mips_relax_frag(fragp, stretch)
+#define md_relax_frag(segment, fragp, stretch) mips_relax_frag(fragp, stretch)
 extern int mips_relax_frag PARAMS ((struct frag *, long));
 
 #define md_undefined_symbol(name)      (0)
index b43cce1fdd87986e392d9dc56ded592b14611a98..d162da615dcc90fc249b8c4f9c734151ddc82f86 100644 (file)
@@ -108,7 +108,7 @@ extern void tic54x_start_line_hook ();
 tic54x_estimate_size_before_relax(f,s)
 extern int tic54x_estimate_size_before_relax(fragS *, segT);
 
-#define md_relax_frag(f,s) tic54x_relax_frag(f,s)
+#define md_relax_frag(seg, f,s) tic54x_relax_frag(f,s)
 extern int tic54x_relax_frag(fragS *, long);
 
 #define md_convert_frag(b,s,f) tic54x_convert_frag(b,s,f)
index a42bc0f50bd40fb4e02a80c30609edda1fe00232..5f203ca6dc08c8c3a63927a0b36dc04aad855cda 100644 (file)
@@ -1166,9 +1166,10 @@ relocations.
 
 @item md_relax_frag
 @cindex md_relax_frag
-This macro may be defined to relax a frag.  GAS will call this with the frag
-and the change in size of all previous frags; @code{md_relax_frag} should
-return the change in size of the frag.  @xref{Relaxation}.
+This macro may be defined to relax a frag.  GAS will call this with the
+segment, the frag, and the change in size of all previous frags;
+@code{md_relax_frag} should return the change in size of the frag.
+@xref{Relaxation}.
 
 @item TC_GENERIC_RELAX_TABLE
 @cindex TC_GENERIC_RELAX_TABLE
index 24b387e649f7b9aacd4450f5f3e6563065b2ece9..2ae110d259aa1c59d170d1c73cc0041203a6bf0a 100644 (file)
@@ -1998,21 +1998,30 @@ write_object_file ()
 static int is_dnrange PARAMS ((fragS *, fragS *));
 
 /* Subroutines of relax_segment.  */
+
 static int
 is_dnrange (f1, f2)
      fragS *f1;
      fragS *f2;
 {
+  addressT f2addr;
+
+  f2addr = f2->fr_address;
   for (; f1; f1 = f1->fr_next)
-    if (f1->fr_next == f2)
-      return 1;
+    {
+      if (f1->fr_next == f2)
+       return 1;
+      if (f1->fr_address > f2addr)
+       break;
+    }
   return 0;
 }
 
 /* Relax a fragment by scanning TC_GENERIC_RELAX_TABLE.  */
 
 long
-relax_frag (fragP, stretch)
+relax_frag (segment, fragP, stretch)
+     segT segment;
      fragS *fragP;
      long stretch;
 {
@@ -2034,6 +2043,10 @@ relax_frag (fragP, stretch)
 
   if (symbolP)
     {
+      fragS *sym_frag;
+
+      sym_frag = symbol_get_frag (symbolP);
+
 #ifndef DIFF_EXPR_OK
 #if !defined (MANY_SEGMENTS) && !defined (BFD_ASSEMBLER)
       know ((S_GET_SEGMENT (symbolP) == SEG_ABSOLUTE)
@@ -2041,23 +2054,24 @@ relax_frag (fragP, stretch)
            || (S_GET_SEGMENT (symbolP) == SEG_BSS)
            || (S_GET_SEGMENT (symbolP) == SEG_TEXT));
 #endif
-      know (symbolP->sy_frag);
+      know (sym_frag != NULL);
 #endif
       know (!(S_GET_SEGMENT (symbolP) == absolute_section)
-           || symbolP->sy_frag == &zero_address_frag);
-      target += S_GET_VALUE (symbolP) + symbol_get_frag (symbolP)->fr_address;
+           || sym_frag == &zero_address_frag);
+      target += S_GET_VALUE (symbolP) + sym_frag->fr_address;
 
       /* If frag has yet to be reached on this pass,
         assume it will move by STRETCH just as we did.
         If this is not so, it will be because some frag
         between grows, and that will force another pass.
 
-        Beware zero-length frags.
-
-        There should be a faster way to do this.  */
+        Beware zero-length frags.  */
 
-      if (symbol_get_frag (symbolP)->fr_address >= was_address
-         && is_dnrange (fragP, symbol_get_frag (symbolP)))
+      if (stretch != 0
+         && S_GET_SEGMENT (symbolP) == segment
+         && (sym_frag->fr_address > was_address
+             || (sym_frag->fr_address == was_address
+                 && is_dnrange (fragP, sym_frag))))
        {
          target += stretch;
        }
@@ -2413,12 +2427,12 @@ relax_segment (segment_frag_root, segment)
 
              case rs_machine_dependent:
 #ifdef md_relax_frag
-               growth = md_relax_frag (fragP, stretch);
+               growth = md_relax_frag (segment, fragP, stretch);
 #else
 #ifdef TC_GENERIC_RELAX_TABLE
                /* The default way to relax a frag is to look through
                   TC_GENERIC_RELAX_TABLE.  */
-               growth = relax_frag (fragP, stretch);
+               growth = relax_frag (segment, fragP, stretch);
 #endif /* TC_GENERIC_RELAX_TABLE  */
 #endif
                break;
index 9872e9d82b435540d9b9e96a0792c7b78d38211c..9a63dc5cd1442c851489ee8e5e455c778c2555da 100644 (file)
@@ -181,7 +181,7 @@ extern void record_alignment PARAMS ((segT seg, int align));
 extern int get_recorded_alignment PARAMS ((segT seg));
 extern void subsegs_finish PARAMS ((void));
 extern void write_object_file PARAMS ((void));
-extern long relax_frag PARAMS ((fragS *, long));
+extern long relax_frag PARAMS ((segT, fragS *, long));
 extern void relax_segment
   PARAMS ((struct frag * seg_frag_root, segT seg_type));