* 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.
This commit is contained in:
Ian Lance Taylor 2001-02-13 21:27:52 +00:00
parent 6433dece0a
commit c842b53ae1
9 changed files with 62 additions and 26 deletions

View 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.

View 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)

View 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)

View 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)

View 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)

View 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)

View 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

View 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.
Beware zero-length frags. */
There should be a faster way to do this. */
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;

View 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));