Use `relax_marker' instead of fragile address test code to determine

whether a frag's fr_address has been updated.
This commit is contained in:
Alan Modra 2001-03-20 03:12:01 +00:00
parent 486363b69b
commit 38686296b3
3 changed files with 29 additions and 38 deletions

View 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> 2001-03-19 Alan Modra <alan@linuxcare.com.au>
* config/tc-i386.c (md_assemble <REGISTER_WARNINGS>): Correct * config/tc-i386.c (md_assemble <REGISTER_WARNINGS>): Correct

View file

@ -1,5 +1,5 @@
/* frags.h - Header file for the frag concept. /* 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. Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler. This file is part of GAS, the GNU Assembler.
@ -62,6 +62,10 @@ struct frag {
struct list_info_struct *line; struct list_info_struct *line;
#endif #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? */ /* What state is my tail in? */
relax_stateT fr_type; relax_stateT fr_type;
relax_substateT fr_subtype; relax_substateT fr_subtype;

View file

@ -1996,28 +1996,6 @@ write_object_file ()
#ifdef TC_GENERIC_RELAX_TABLE #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. */ /* Relax a fragment by scanning TC_GENERIC_RELAX_TABLE. */
long long
@ -2030,17 +2008,19 @@ relax_frag (segment, fragP, stretch)
const relax_typeS *start_type; const relax_typeS *start_type;
relax_substateT next_state; relax_substateT next_state;
relax_substateT this_state; relax_substateT this_state;
long aim, target, growth; long growth;
symbolS *symbolP = fragP->fr_symbol; offsetT aim;
long offset = fragP->fr_offset; addressT target;
/* Recompute was_address by undoing "+= stretch" done by relax_segment. */ addressT address;
unsigned long was_address = fragP->fr_address - stretch; symbolS *symbolP;
unsigned long address = fragP->fr_address; const relax_typeS *table;
const relax_typeS *table = TC_GENERIC_RELAX_TABLE;
target = fragP->fr_offset;
address = fragP->fr_address;
table = TC_GENERIC_RELAX_TABLE;
this_state = fragP->fr_subtype; this_state = fragP->fr_subtype;
start_type = this_type = table + this_state; start_type = this_type = table + this_state;
target = offset; symbolP = fragP->fr_symbol;
if (symbolP) if (symbolP)
{ {
@ -2064,15 +2044,11 @@ relax_frag (segment, fragP, stretch)
/* If frag has yet to be reached on this pass, /* If frag has yet to be reached on this pass,
assume it will move by STRETCH just as we did. assume it will move by STRETCH just as we did.
If this is not so, it will be because some frag If this is not so, it will be because some frag
between grows, and that will force another pass. between grows, and that will force another pass. */
Beware zero-length frags. */
if (stretch != 0 if (stretch != 0
&& S_GET_SEGMENT (symbolP) == segment && sym_frag->relax_marker != fragP->relax_marker
&& (sym_frag->fr_address > was_address && S_GET_SEGMENT (symbolP) == segment)
|| (sym_frag->fr_address == was_address
&& is_dnrange (fragP, sym_frag))))
{ {
target += stretch; target += stretch;
} }
@ -2179,6 +2155,7 @@ relax_segment (segment_frag_root, segment)
address = 0; address = 0;
for (fragP = segment_frag_root; fragP; fragP = fragP->fr_next) for (fragP = segment_frag_root; fragP; fragP = fragP->fr_next)
{ {
fragP->relax_marker = 0;
fragP->fr_address = address; fragP->fr_address = address;
address += fragP->fr_fix; address += fragP->fr_fix;
@ -2264,6 +2241,7 @@ relax_segment (segment_frag_root, segment)
offsetT offset; offsetT offset;
symbolS *symbolP; symbolS *symbolP;
fragP->relax_marker ^= 1;
was_address = fragP->fr_address; was_address = fragP->fr_address;
address = fragP->fr_address += stretch; address = fragP->fr_address += stretch;
symbolP = fragP->fr_symbol; symbolP = fragP->fr_symbol;