* 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:
parent
dc70af013c
commit
98aa84af0e
4 changed files with 79 additions and 65 deletions
|
@ -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>
|
||||
|
||||
* configure.in: Move "mips-*-linux-gnu*" before "mips-*-gnu*".
|
||||
|
|
|
@ -80,7 +80,7 @@ CPU_TYPES = \
|
|||
z8k
|
||||
|
||||
# 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 = \
|
||||
aout \
|
||||
|
|
|
@ -192,7 +192,7 @@ CPU_TYPES = \
|
|||
|
||||
|
||||
# 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 = \
|
||||
aout \
|
||||
|
|
|
@ -1384,6 +1384,7 @@ mips16_mark_labels ()
|
|||
if (mips_opts.mips16)
|
||||
{
|
||||
struct insn_label_list *l;
|
||||
valueT val;
|
||||
|
||||
for (l = insn_labels; l != NULL; l = l->next)
|
||||
{
|
||||
|
@ -1391,8 +1392,9 @@ mips16_mark_labels ()
|
|||
if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
|
||||
S_SET_OTHER (l->label, STO_MIPS16);
|
||||
#endif
|
||||
if ((S_GET_VALUE (l->label) & 1) == 0)
|
||||
S_SET_VALUE (l->label, S_GET_VALUE (l->label) + 1);
|
||||
val = S_GET_VALUE (l->label);
|
||||
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)
|
||||
{
|
||||
valueT val;
|
||||
|
||||
assert (S_GET_SEGMENT (l->label) == now_seg);
|
||||
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. */
|
||||
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
|
||||
|
@ -2406,12 +2411,15 @@ mips_emit_delays (insns)
|
|||
|
||||
for (l = insn_labels; l != NULL; l = l->next)
|
||||
{
|
||||
valueT val;
|
||||
|
||||
assert (S_GET_SEGMENT (l->label) == now_seg);
|
||||
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. */
|
||||
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 *save_in;
|
||||
valueT val;
|
||||
|
||||
save_in = input_line_pointer;
|
||||
input_line_pointer = str;
|
||||
|
@ -8776,8 +8785,8 @@ my_getExpression (ep, str)
|
|||
&& S_GET_SEGMENT (ep->X_add_symbol) == now_seg
|
||||
&& symbol_get_frag (ep->X_add_symbol) == frag_now
|
||||
&& symbol_constant_p (ep->X_add_symbol)
|
||||
&& 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);
|
||||
&& (val = S_GET_VALUE (ep->X_add_symbol)) == frag_now_fix ())
|
||||
S_SET_VALUE (ep->X_add_symbol, val + 1);
|
||||
}
|
||||
|
||||
/* Turn a string in input_line_pointer into a floating point constant
|
||||
|
@ -9512,7 +9521,8 @@ md_apply_fix (fixP, valueP)
|
|||
valueT *valueP;
|
||||
{
|
||||
unsigned char *buf;
|
||||
long insn, value;
|
||||
long insn;
|
||||
valueT value;
|
||||
|
||||
assert (fixP->fx_size == 4
|
||||
|| fixP->fx_r_type == BFD_RELOC_16
|
||||
|
@ -9527,27 +9537,28 @@ md_apply_fix (fixP, valueP)
|
|||
#ifdef OBJ_ELF
|
||||
if (fixP->fx_addsy != NULL && OUTPUT_FLAVOR == bfd_target_elf_flavour)
|
||||
{
|
||||
if (S_GET_OTHER (fixP->fx_addsy) == STO_MIPS16
|
||||
|| S_IS_WEAK (fixP->fx_addsy)
|
||||
|| (symbol_used_in_reloc_p (fixP->fx_addsy)
|
||||
&& (((bfd_get_section_flags (stdoutput,
|
||||
S_GET_SEGMENT (fixP->fx_addsy))
|
||||
& SEC_LINK_ONCE) != 0)
|
||||
|| !strncmp (segment_name (S_GET_SEGMENT (fixP->fx_addsy)),
|
||||
".gnu.linkonce",
|
||||
sizeof (".gnu.linkonce") - 1))))
|
||||
if (S_GET_OTHER (fixP->fx_addsy) == STO_MIPS16
|
||||
|| S_IS_WEAK (fixP->fx_addsy)
|
||||
|| (symbol_used_in_reloc_p (fixP->fx_addsy)
|
||||
&& (((bfd_get_section_flags (stdoutput,
|
||||
S_GET_SEGMENT (fixP->fx_addsy))
|
||||
& SEC_LINK_ONCE) != 0)
|
||||
|| !strncmp (segment_name (S_GET_SEGMENT (fixP->fx_addsy)),
|
||||
".gnu.linkonce",
|
||||
sizeof (".gnu.linkonce") - 1))))
|
||||
|
||||
{
|
||||
value -= S_GET_VALUE (fixP->fx_addsy);
|
||||
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
|
||||
the addend to appear in the object file.
|
||||
FIXME: If this makes VALUE zero, we're toast. */
|
||||
value -= S_GET_VALUE (fixP->fx_addsy);
|
||||
}
|
||||
}
|
||||
{
|
||||
valueT symval = S_GET_VALUE (fixP->fx_addsy);
|
||||
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
|
||||
the addend to appear in the object file.
|
||||
FIXME: If this makes VALUE zero, we're toast. */
|
||||
value -= symval;
|
||||
}
|
||||
}
|
||||
|
||||
/* This code was generated using trial and error and so is
|
||||
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. */
|
||||
if (fixP->fx_done)
|
||||
{
|
||||
if (value < -0x8000 || value > 0x7fff)
|
||||
if (value + 0x8000 > 0xffff)
|
||||
as_bad_where (fixP->fx_file, fixP->fx_line,
|
||||
_("relocation overflow"));
|
||||
buf = (unsigned char *) fixP->fx_frag->fr_literal + fixP->fx_where;
|
||||
|
@ -9715,7 +9726,7 @@ md_apply_fix (fixP, valueP)
|
|||
*/
|
||||
if ((value & 0x3) != 0)
|
||||
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)
|
||||
break;
|
||||
|
@ -9725,7 +9736,7 @@ md_apply_fix (fixP, valueP)
|
|||
if (!fixP->fx_done)
|
||||
value -= fixP->fx_frag->fr_address + fixP->fx_where;
|
||||
|
||||
value >>= 2;
|
||||
value = (offsetT) value >> 2;
|
||||
|
||||
/* update old instruction data */
|
||||
buf = (unsigned char *) (fixP->fx_where + fixP->fx_frag->fr_literal);
|
||||
|
@ -9734,7 +9745,7 @@ md_apply_fix (fixP, valueP)
|
|||
else
|
||||
insn = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
|
||||
|
||||
if (value >= -0x8000 && value < 0x8000)
|
||||
if (value + 0x8000 <= 0xffff)
|
||||
insn |= value & 0xffff;
|
||||
else
|
||||
{
|
||||
|
@ -10751,6 +10762,7 @@ mips16_extended_frag (fragp, sec, stretch)
|
|||
offsetT val;
|
||||
int mintiny, maxtiny;
|
||||
segT symsec;
|
||||
fragS *sym_frag;
|
||||
|
||||
if (RELAX_MIPS16_USER_SMALL (fragp->fr_subtype))
|
||||
return 0;
|
||||
|
@ -10784,29 +10796,9 @@ mips16_extended_frag (fragp, sec, stretch)
|
|||
maxtiny = (1 << (op->nbits - 1)) - 1;
|
||||
}
|
||||
|
||||
/* We can't always call S_GET_VALUE here, because we don't want to
|
||||
lock in a particular frag address. */
|
||||
if (symbol_constant_p (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;
|
||||
sym_frag = symbol_get_frag (fragp->fr_symbol);
|
||||
val = S_GET_VALUE (fragp->fr_symbol) + sym_frag->fr_address;
|
||||
symsec = S_GET_SEGMENT (fragp->fr_symbol);
|
||||
|
||||
if (op->pcrel)
|
||||
{
|
||||
|
@ -10825,6 +10817,7 @@ mips16_extended_frag (fragp, sec, stretch)
|
|||
}
|
||||
else
|
||||
{
|
||||
/* Must have been called from md_estimate_size_before_relax. */
|
||||
if (symsec != sec)
|
||||
{
|
||||
fragp->fr_subtype =
|
||||
|
@ -10837,16 +10830,22 @@ mips16_extended_frag (fragp, sec, stretch)
|
|||
|
||||
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
|
||||
the same section. If the fr_address of the symbol fragment
|
||||
is greater then the address of this fragment we want to add
|
||||
the same section. If the relax_marker of the symbol fragment
|
||||
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.
|
||||
This particularly matters because of the shift bits. */
|
||||
if (stretch != 0
|
||||
&& (symbol_get_frag (fragp->fr_symbol)->fr_address
|
||||
>= fragp->fr_address))
|
||||
&& sym_frag->relax_marker != fragp->relax_marker)
|
||||
{
|
||||
fragS *f;
|
||||
|
||||
|
@ -10856,9 +10855,7 @@ mips16_extended_frag (fragp, sec, stretch)
|
|||
This doesn't handle the fr_subtype field, which specifies
|
||||
a maximum number of bytes to skip when doing an
|
||||
alignment. */
|
||||
for (f = fragp;
|
||||
f != NULL && f != symbol_get_frag (fragp->fr_symbol);
|
||||
f = f->fr_next)
|
||||
for (f = fragp; f != NULL && f != sym_frag; f = f->fr_next)
|
||||
{
|
||||
if (f->fr_type == rs_align || f->fr_type == rs_align_code)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue