PR gas/12049
* frags.h (struct frag): Add "region" field. * write.c (relax_frag): Don't add "stretch" to forward reference target if there is an intervening org or align. (relax_segment): Set region.
This commit is contained in:
parent
8c540a24cf
commit
e35a414d3c
3 changed files with 33 additions and 9 deletions
|
@ -1,3 +1,11 @@
|
|||
2010-10-19 Alan Modra <amodra@gmail.com>
|
||||
|
||||
PR gas/12049
|
||||
* frags.h (struct frag): Add "region" field.
|
||||
* write.c (relax_frag): Don't add "stretch" to forward reference
|
||||
target if there is an intervening org or align.
|
||||
(relax_segment): Set region.
|
||||
|
||||
2010-10-18 Maciej W. Rozycki <macro@linux-mips.org>
|
||||
|
||||
* config/tc-mips.c (macro)[ldd_std]: Fix the relaxation variant
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* frags.h - Header file for the frag concept.
|
||||
Copyright 1987, 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001,
|
||||
2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
|
||||
2002, 2003, 2004, 2005, 2006, 2007, 2010 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GAS, the GNU Assembler.
|
||||
|
||||
|
@ -68,6 +68,10 @@ struct frag {
|
|||
struct list_info_struct *line;
|
||||
#endif
|
||||
|
||||
/* A serial number for a sequence of frags having at most one alignment
|
||||
or org frag, and that at the tail of the sequence. */
|
||||
unsigned int region:16;
|
||||
|
||||
/* Flipped each relax pass so we can easily determine whether
|
||||
fr_address has been adjusted. */
|
||||
unsigned int relax_marker:1;
|
||||
|
|
28
gas/write.c
28
gas/write.c
|
@ -1,7 +1,7 @@
|
|||
/* write.c - emit .o file
|
||||
Copyright 1986, 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
|
||||
1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
|
||||
Free Software Foundation, Inc.
|
||||
1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
|
||||
2010 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GAS, the GNU Assembler.
|
||||
|
||||
|
@ -2148,16 +2148,21 @@ relax_frag (segT segment, fragS *fragP, long stretch)
|
|||
|| sym_frag == &zero_address_frag);
|
||||
target += S_GET_VALUE (symbolP);
|
||||
|
||||
/* 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. */
|
||||
/* If SYM_FRAG has yet to be reached on this pass, assume it
|
||||
will move by STRETCH just as we did, unless there is an
|
||||
alignment frag between here and SYM_FRAG. An alignment may
|
||||
well absorb any STRETCH, and we don't want to choose a larger
|
||||
branch insn by overestimating the needed reach of this
|
||||
branch. It isn't critical to calculate TARGET exactly; We
|
||||
know we'll be doing another pass if STRETCH is non-zero. */
|
||||
|
||||
if (stretch != 0
|
||||
&& sym_frag->relax_marker != fragP->relax_marker
|
||||
&& S_GET_SEGMENT (symbolP) == segment)
|
||||
{
|
||||
target += stretch;
|
||||
if (stretch < 0
|
||||
|| sym_frag->region == fragP->region)
|
||||
target += stretch;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2245,6 +2250,7 @@ relax_segment (struct frag *segment_frag_root, segT segment, int pass)
|
|||
unsigned long frag_count;
|
||||
struct frag *fragP;
|
||||
relax_addressT address;
|
||||
int region;
|
||||
int ret;
|
||||
|
||||
/* In case md_estimate_size_before_relax() wants to make fixSs. */
|
||||
|
@ -2253,10 +2259,12 @@ relax_segment (struct frag *segment_frag_root, segT segment, int pass)
|
|||
/* For each frag in segment: count and store (a 1st guess of)
|
||||
fr_address. */
|
||||
address = 0;
|
||||
region = 0;
|
||||
for (frag_count = 0, fragP = segment_frag_root;
|
||||
fragP;
|
||||
fragP = fragP->fr_next, frag_count ++)
|
||||
{
|
||||
fragP->region = region;
|
||||
fragP->relax_marker = 0;
|
||||
fragP->fr_address = address;
|
||||
address += fragP->fr_fix;
|
||||
|
@ -2285,12 +2293,16 @@ relax_segment (struct frag *segment_frag_root, segT segment, int pass)
|
|||
}
|
||||
|
||||
address += offset;
|
||||
region += 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case rs_org:
|
||||
case rs_space:
|
||||
/* Assume .org is nugatory. It will grow with 1st relax. */
|
||||
region += 1;
|
||||
break;
|
||||
|
||||
case rs_space:
|
||||
break;
|
||||
|
||||
case rs_machine_dependent:
|
||||
|
|
Loading…
Reference in a new issue