* Makefile.am: 'som' is not wrongly spelled 'some'.

* Makefile.in: Regenerate.

	* config/tc-mips.c (mips16_mark_labels): Reduce number of calls to
	S_GET_VALUE by using a temp.
	(append_insn): Likewise, and for S_GET_VALUE too.
	(mips_emit_delays): Likewise.
	(my_getExpression): Likewise.
	(md_apply_fix): Likewise.  Use "valueT" rather than "long" for "value".
	(mips16_extended_frag): Remove code concerned with avoiding
	locking in a frag address now that symbols are not finalized until
	relaxation is complete.  Cater for first relaxation pass having
	bogus addresses.  Use relax_marker to reliably determine whether a
	symbol frag has been reached on the current pass.
This commit is contained in:
Alan Modra 2001-06-08 06:07:13 +00:00
parent dc70af013c
commit 98aa84af0e
4 changed files with 79 additions and 65 deletions

View file

@ -1,3 +1,20 @@
2001-06-08 Alan Modra <amodra@bigpond.net.au>
* Makefile.am: 'som' is not wrongly spelled 'some'.
* Makefile.in: Regenerate.
* config/tc-mips.c (mips16_mark_labels): Reduce number of calls to
S_GET_VALUE by using a temp.
(append_insn): Likewise, and for S_GET_VALUE too.
(mips_emit_delays): Likewise.
(my_getExpression): Likewise.
(md_apply_fix): Likewise. Use "valueT" rather than "long" for "value".
(mips16_extended_frag): Remove code concerned with avoiding
locking in a frag address now that symbols are not finalized until
relaxation is complete. Cater for first relaxation pass having
bogus addresses. Use relax_marker to reliably determine whether a
symbol frag has been reached on the current pass.
2001-06-07 H.J. Lu <hjl@gnu.org> 2001-06-07 H.J. Lu <hjl@gnu.org>
* configure.in: Move "mips-*-linux-gnu*" before "mips-*-gnu*". * configure.in: Move "mips-*-linux-gnu*" before "mips-*-gnu*".

View file

@ -80,7 +80,7 @@ CPU_TYPES = \
z8k z8k
# Object format types. This is only used for dependency information. # Object format types. This is only used for dependency information.
# We deliberately omit some, since it does not work as a cross assembler. # We deliberately omit SOM, since it does not work as a cross assembler.
OBJ_FORMATS = \ OBJ_FORMATS = \
aout \ aout \

View file

@ -192,7 +192,7 @@ CPU_TYPES = \
# Object format types. This is only used for dependency information. # Object format types. This is only used for dependency information.
# We deliberately omit some, since it does not work as a cross assembler. # We deliberately omit SOM, since it does not work as a cross assembler.
OBJ_FORMATS = \ OBJ_FORMATS = \
aout \ aout \

View file

@ -1384,6 +1384,7 @@ mips16_mark_labels ()
if (mips_opts.mips16) if (mips_opts.mips16)
{ {
struct insn_label_list *l; struct insn_label_list *l;
valueT val;
for (l = insn_labels; l != NULL; l = l->next) for (l = insn_labels; l != NULL; l = l->next)
{ {
@ -1391,8 +1392,9 @@ mips16_mark_labels ()
if (OUTPUT_FLAVOR == bfd_target_elf_flavour) if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
S_SET_OTHER (l->label, STO_MIPS16); S_SET_OTHER (l->label, STO_MIPS16);
#endif #endif
if ((S_GET_VALUE (l->label) & 1) == 0) val = S_GET_VALUE (l->label);
S_SET_VALUE (l->label, S_GET_VALUE (l->label) + 1); if ((val & 1) == 0)
S_SET_VALUE (l->label, val + 1);
} }
} }
} }
@ -1703,12 +1705,15 @@ append_insn (place, ip, address_expr, reloc_type, unmatched_hi)
for (l = insn_labels; l != NULL; l = l->next) for (l = insn_labels; l != NULL; l = l->next)
{ {
valueT val;
assert (S_GET_SEGMENT (l->label) == now_seg); assert (S_GET_SEGMENT (l->label) == now_seg);
symbol_set_frag (l->label, frag_now); symbol_set_frag (l->label, frag_now);
S_SET_VALUE (l->label, (valueT) frag_now_fix ()); val = (valueT) frag_now_fix ();
/* mips16 text labels are stored as odd. */ /* mips16 text labels are stored as odd. */
if (mips_opts.mips16) if (mips_opts.mips16)
S_SET_VALUE (l->label, S_GET_VALUE (l->label) + 1); val += 1;
S_SET_VALUE (l->label, val);
} }
#ifndef NO_ECOFF_DEBUGGING #ifndef NO_ECOFF_DEBUGGING
@ -2406,12 +2411,15 @@ mips_emit_delays (insns)
for (l = insn_labels; l != NULL; l = l->next) for (l = insn_labels; l != NULL; l = l->next)
{ {
valueT val;
assert (S_GET_SEGMENT (l->label) == now_seg); assert (S_GET_SEGMENT (l->label) == now_seg);
symbol_set_frag (l->label, frag_now); symbol_set_frag (l->label, frag_now);
S_SET_VALUE (l->label, (valueT) frag_now_fix ()); val = (valueT) frag_now_fix ();
/* mips16 text labels are stored as odd. */ /* mips16 text labels are stored as odd. */
if (mips_opts.mips16) if (mips_opts.mips16)
S_SET_VALUE (l->label, S_GET_VALUE (l->label) + 1); val += 1;
S_SET_VALUE (l->label, val);
} }
} }
} }
@ -8759,6 +8767,7 @@ my_getExpression (ep, str)
char *str; char *str;
{ {
char *save_in; char *save_in;
valueT val;
save_in = input_line_pointer; save_in = input_line_pointer;
input_line_pointer = str; input_line_pointer = str;
@ -8776,8 +8785,8 @@ my_getExpression (ep, str)
&& S_GET_SEGMENT (ep->X_add_symbol) == now_seg && S_GET_SEGMENT (ep->X_add_symbol) == now_seg
&& symbol_get_frag (ep->X_add_symbol) == frag_now && symbol_get_frag (ep->X_add_symbol) == frag_now
&& symbol_constant_p (ep->X_add_symbol) && symbol_constant_p (ep->X_add_symbol)
&& S_GET_VALUE (ep->X_add_symbol) == frag_now_fix ()) && (val = S_GET_VALUE (ep->X_add_symbol)) == frag_now_fix ())
S_SET_VALUE (ep->X_add_symbol, S_GET_VALUE (ep->X_add_symbol) + 1); S_SET_VALUE (ep->X_add_symbol, val + 1);
} }
/* Turn a string in input_line_pointer into a floating point constant /* Turn a string in input_line_pointer into a floating point constant
@ -9512,7 +9521,8 @@ md_apply_fix (fixP, valueP)
valueT *valueP; valueT *valueP;
{ {
unsigned char *buf; unsigned char *buf;
long insn, value; long insn;
valueT value;
assert (fixP->fx_size == 4 assert (fixP->fx_size == 4
|| fixP->fx_r_type == BFD_RELOC_16 || fixP->fx_r_type == BFD_RELOC_16
@ -9527,27 +9537,28 @@ md_apply_fix (fixP, valueP)
#ifdef OBJ_ELF #ifdef OBJ_ELF
if (fixP->fx_addsy != NULL && OUTPUT_FLAVOR == bfd_target_elf_flavour) if (fixP->fx_addsy != NULL && OUTPUT_FLAVOR == bfd_target_elf_flavour)
{ {
if (S_GET_OTHER (fixP->fx_addsy) == STO_MIPS16 if (S_GET_OTHER (fixP->fx_addsy) == STO_MIPS16
|| S_IS_WEAK (fixP->fx_addsy) || S_IS_WEAK (fixP->fx_addsy)
|| (symbol_used_in_reloc_p (fixP->fx_addsy) || (symbol_used_in_reloc_p (fixP->fx_addsy)
&& (((bfd_get_section_flags (stdoutput, && (((bfd_get_section_flags (stdoutput,
S_GET_SEGMENT (fixP->fx_addsy)) S_GET_SEGMENT (fixP->fx_addsy))
& SEC_LINK_ONCE) != 0) & SEC_LINK_ONCE) != 0)
|| !strncmp (segment_name (S_GET_SEGMENT (fixP->fx_addsy)), || !strncmp (segment_name (S_GET_SEGMENT (fixP->fx_addsy)),
".gnu.linkonce", ".gnu.linkonce",
sizeof (".gnu.linkonce") - 1)))) sizeof (".gnu.linkonce") - 1))))
{ {
value -= S_GET_VALUE (fixP->fx_addsy); valueT symval = S_GET_VALUE (fixP->fx_addsy);
if (value != 0 && ! fixP->fx_pcrel) value -= symval;
{ if (value != 0 && ! fixP->fx_pcrel)
/* In this case, the bfd_install_relocation routine will {
incorrectly add the symbol value back in. We just want /* In this case, the bfd_install_relocation routine will
the addend to appear in the object file. incorrectly add the symbol value back in. We just want
FIXME: If this makes VALUE zero, we're toast. */ the addend to appear in the object file.
value -= S_GET_VALUE (fixP->fx_addsy); FIXME: If this makes VALUE zero, we're toast. */
} value -= symval;
} }
}
/* This code was generated using trial and error and so is /* This code was generated using trial and error and so is
fragile and not trustworthy. If you change it, you should fragile and not trustworthy. If you change it, you should
@ -9697,7 +9708,7 @@ md_apply_fix (fixP, valueP)
up deleting a LO16 reloc. See the 'o' case in mips_ip. */ up deleting a LO16 reloc. See the 'o' case in mips_ip. */
if (fixP->fx_done) if (fixP->fx_done)
{ {
if (value < -0x8000 || value > 0x7fff) if (value + 0x8000 > 0xffff)
as_bad_where (fixP->fx_file, fixP->fx_line, as_bad_where (fixP->fx_file, fixP->fx_line,
_("relocation overflow")); _("relocation overflow"));
buf = (unsigned char *) fixP->fx_frag->fr_literal + fixP->fx_where; buf = (unsigned char *) fixP->fx_frag->fr_literal + fixP->fx_where;
@ -9715,7 +9726,7 @@ md_apply_fix (fixP, valueP)
*/ */
if ((value & 0x3) != 0) if ((value & 0x3) != 0)
as_bad_where (fixP->fx_file, fixP->fx_line, as_bad_where (fixP->fx_file, fixP->fx_line,
_("Branch to odd address (%lx)"), value); _("Branch to odd address (%lx)"), (long) value);
if (!fixP->fx_done && value != 0) if (!fixP->fx_done && value != 0)
break; break;
@ -9725,7 +9736,7 @@ md_apply_fix (fixP, valueP)
if (!fixP->fx_done) if (!fixP->fx_done)
value -= fixP->fx_frag->fr_address + fixP->fx_where; value -= fixP->fx_frag->fr_address + fixP->fx_where;
value >>= 2; value = (offsetT) value >> 2;
/* update old instruction data */ /* update old instruction data */
buf = (unsigned char *) (fixP->fx_where + fixP->fx_frag->fr_literal); buf = (unsigned char *) (fixP->fx_where + fixP->fx_frag->fr_literal);
@ -9734,7 +9745,7 @@ md_apply_fix (fixP, valueP)
else else
insn = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; insn = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
if (value >= -0x8000 && value < 0x8000) if (value + 0x8000 <= 0xffff)
insn |= value & 0xffff; insn |= value & 0xffff;
else else
{ {
@ -10751,6 +10762,7 @@ mips16_extended_frag (fragp, sec, stretch)
offsetT val; offsetT val;
int mintiny, maxtiny; int mintiny, maxtiny;
segT symsec; segT symsec;
fragS *sym_frag;
if (RELAX_MIPS16_USER_SMALL (fragp->fr_subtype)) if (RELAX_MIPS16_USER_SMALL (fragp->fr_subtype))
return 0; return 0;
@ -10784,29 +10796,9 @@ mips16_extended_frag (fragp, sec, stretch)
maxtiny = (1 << (op->nbits - 1)) - 1; maxtiny = (1 << (op->nbits - 1)) - 1;
} }
/* We can't always call S_GET_VALUE here, because we don't want to sym_frag = symbol_get_frag (fragp->fr_symbol);
lock in a particular frag address. */ val = S_GET_VALUE (fragp->fr_symbol) + sym_frag->fr_address;
if (symbol_constant_p (fragp->fr_symbol)) symsec = S_GET_SEGMENT (fragp->fr_symbol);
{
val = (S_GET_VALUE (fragp->fr_symbol)
+ symbol_get_frag (fragp->fr_symbol)->fr_address);
symsec = S_GET_SEGMENT (fragp->fr_symbol);
}
else if (symbol_equated_p (fragp->fr_symbol)
&& (symbol_constant_p
(symbol_get_value_expression (fragp->fr_symbol)->X_add_symbol)))
{
symbolS *eqsym;
eqsym = symbol_get_value_expression (fragp->fr_symbol)->X_add_symbol;
val = (S_GET_VALUE (eqsym)
+ symbol_get_frag (eqsym)->fr_address
+ symbol_get_value_expression (fragp->fr_symbol)->X_add_number
+ symbol_get_frag (fragp->fr_symbol)->fr_address);
symsec = S_GET_SEGMENT (eqsym);
}
else
return 1;
if (op->pcrel) if (op->pcrel)
{ {
@ -10825,6 +10817,7 @@ mips16_extended_frag (fragp, sec, stretch)
} }
else else
{ {
/* Must have been called from md_estimate_size_before_relax. */
if (symsec != sec) if (symsec != sec)
{ {
fragp->fr_subtype = fragp->fr_subtype =
@ -10837,16 +10830,22 @@ mips16_extended_frag (fragp, sec, stretch)
return 1; return 1;
} }
if (fragp != sym_frag && sym_frag->fr_address == 0)
/* Assume non-extended on the first relaxation pass.
The address we have calculated will be bogus if this is
a forward branch to another frag, as the forward frag
will have fr_address == 0. */
return 0;
} }
/* In this case, we know for sure that the symbol fragment is in /* In this case, we know for sure that the symbol fragment is in
the same section. If the fr_address of the symbol fragment the same section. If the relax_marker of the symbol fragment
is greater then the address of this fragment we want to add differs from the relax_marker of this fragment, we have not
yet adjusted the symbol fragment fr_address. We want to add
in STRETCH in order to get a better estimate of the address. in STRETCH in order to get a better estimate of the address.
This particularly matters because of the shift bits. */ This particularly matters because of the shift bits. */
if (stretch != 0 if (stretch != 0
&& (symbol_get_frag (fragp->fr_symbol)->fr_address && sym_frag->relax_marker != fragp->relax_marker)
>= fragp->fr_address))
{ {
fragS *f; fragS *f;
@ -10856,9 +10855,7 @@ mips16_extended_frag (fragp, sec, stretch)
This doesn't handle the fr_subtype field, which specifies This doesn't handle the fr_subtype field, which specifies
a maximum number of bytes to skip when doing an a maximum number of bytes to skip when doing an
alignment. */ alignment. */
for (f = fragp; for (f = fragp; f != NULL && f != sym_frag; f = f->fr_next)
f != NULL && f != symbol_get_frag (fragp->fr_symbol);
f = f->fr_next)
{ {
if (f->fr_type == rs_align || f->fr_type == rs_align_code) if (f->fr_type == rs_align || f->fr_type == rs_align_code)
{ {