mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-01-18 12:24:38 +08:00
* 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:
parent
6433dece0a
commit
c842b53ae1
@ -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.
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
40
gas/write.c
40
gas/write.c
@ -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;
|
||||
|
@ -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));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user