Use `relax_marker' instead of fragile address test code to determine
authorAlan Modra <amodra@gmail.com>
Tue, 20 Mar 2001 03:12:01 +0000 (03:12 +0000)
committerAlan Modra <amodra@gmail.com>
Tue, 20 Mar 2001 03:12:01 +0000 (03:12 +0000)
whether a frag's fr_address has been updated.

gas/ChangeLog
gas/frags.h
gas/write.c

index 054e911dbde0d4bf7732d147d327b46f46706962..86e67bf96daf6e83a58cd421f82c0313b21928c3 100644 (file)
@@ -1,3 +1,12 @@
+2001-03-20  Alan Modra  <alan@linuxcare.com.au>
+
+       * frags.h (struct frag): Add relax_marker.
+       * write.c (is_dnrange): Delete.
+       (relax_frag): Use correct types for `aim', `target', `address'.
+       Delete `offset', `was_address'.  Test `relax_marker' instead of
+       using fragile (and slow) address test.
+       (relax_segment): Init and flip `relax_marker'.
+
 2001-03-19  Alan Modra  <alan@linuxcare.com.au>
 
        * config/tc-i386.c (md_assemble <REGISTER_WARNINGS>): Correct
index 7c2962109bc57e30d97a4ae0b952294ed277c319..e4cb0509dbc50ce7f4b5dc1abd26b9581a971dd5 100644 (file)
@@ -1,5 +1,5 @@
 /* frags.h - Header file for the frag concept.
-   Copyright 1987, 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000
+   Copyright 1987, 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001
    Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
@@ -62,6 +62,10 @@ struct frag {
   struct list_info_struct *line;
 #endif
 
+  /* Flipped each relax pass so we can easily determine whether
+     fr_address has been adjusted.  */
+  unsigned int relax_marker:1;
+
   /* What state is my tail in? */
   relax_stateT fr_type;
   relax_substateT fr_subtype;
index ec421930146c8ad15780e35573d1129a34cfedd6..b647a11d9058305794f011428a31a0ed45ee1662 100644 (file)
@@ -1996,28 +1996,6 @@ write_object_file ()
 
 #ifdef TC_GENERIC_RELAX_TABLE
 
-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_address > f2addr)
-       break;
-    }
-  return 0;
-}
-
 /* Relax a fragment by scanning TC_GENERIC_RELAX_TABLE.  */
 
 long
@@ -2030,17 +2008,19 @@ relax_frag (segment, fragP, stretch)
   const relax_typeS *start_type;
   relax_substateT next_state;
   relax_substateT this_state;
-  long aim, target, growth;
-  symbolS *symbolP = fragP->fr_symbol;
-  long offset = fragP->fr_offset;
-  /* Recompute was_address by undoing "+= stretch" done by relax_segment.  */
-  unsigned long was_address = fragP->fr_address - stretch;
-  unsigned long address = fragP->fr_address;
-  const relax_typeS *table = TC_GENERIC_RELAX_TABLE;
-
+  long growth;
+  offsetT aim;
+  addressT target;
+  addressT address;
+  symbolS *symbolP;
+  const relax_typeS *table;
+
+  target = fragP->fr_offset;
+  address = fragP->fr_address;
+  table = TC_GENERIC_RELAX_TABLE;
   this_state = fragP->fr_subtype;
   start_type = this_type = table + this_state;
-  target = offset;
+  symbolP = fragP->fr_symbol;
 
   if (symbolP)
     {
@@ -2064,15 +2044,11 @@ relax_frag (segment, fragP, stretch)
       /* 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.  */
+        between grows, and that will force another pass.  */
 
       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))))
+         && sym_frag->relax_marker != fragP->relax_marker
+         && S_GET_SEGMENT (symbolP) == segment)
        {
          target += stretch;
        }
@@ -2179,6 +2155,7 @@ relax_segment (segment_frag_root, segment)
   address = 0;
   for (fragP = segment_frag_root; fragP; fragP = fragP->fr_next)
     {
+      fragP->relax_marker = 0;
       fragP->fr_address = address;
       address += fragP->fr_fix;
 
@@ -2264,6 +2241,7 @@ relax_segment (segment_frag_root, segment)
            offsetT offset;
            symbolS *symbolP;
 
+           fragP->relax_marker ^= 1;
            was_address = fragP->fr_address;
            address = fragP->fr_address += stretch;
            symbolP = fragP->fr_symbol;