* config/tc-mips.c (mips_ip): For case 'o', when generating

embedded PIC code, accept the difference between two local symbols
	as being constant.
	(mips_force_relocation): Only force a reloc to be generated for a
	PC relative fixup.
	(md_apply_fix): For BFD_RELOC_32 and BFD_RELOC_LO16, put the fixup
	value into the file if the fixup will not generate a reloc.
This commit is contained in:
Ian Lance Taylor 1994-04-05 19:57:32 +00:00
parent 632dcce87b
commit f3645945cf
2 changed files with 54 additions and 11 deletions

View File

@ -1,3 +1,13 @@
Tue Apr 5 15:48:03 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
* config/tc-mips.c (mips_ip): For case 'o', when generating
embedded PIC code, accept the difference between two local symbols
as being constant.
(mips_force_relocation): Only force a reloc to be generated for a
PC relative fixup.
(md_apply_fix): For BFD_RELOC_32 and BFD_RELOC_LO16, put the fixup
value into the file if the fixup will not generate a reloc.
Tue Apr 5 11:14:14 1994 Ken Raeburn (raeburn@rtl.cygnus.com)
* config/tc-sparc.c (s_reserve): If section passed isn't bss,

View File

@ -4534,14 +4534,25 @@ mips_ip (str, ip)
case 'o': /* 16 bit offset */
c = my_getSmallExpression (&offset_expr, s);
/*
* If this value won't fit into a 16 bit offset, then
* go find a macro that will generate the 32 bit offset
* code pattern.
*/
if (offset_expr.X_op != O_constant
|| offset_expr.X_add_number >= 0x8000
|| offset_expr.X_add_number < -0x8000)
/* If this value won't fit into a 16 bit offset, then go
find a macro that will generate the 32 bit offset
code pattern. As a special hack, we accept the
difference of two local symbols as a constant. This
is required to suppose embedded PIC switches, which
use an instruction which looks like
lw $4,$L12-$LS12($4)
The problem with handling this in a more general
fashion is that the macro function doesn't expect to
see anything which can be handled in a single
constant instruction. */
if ((offset_expr.X_op != O_constant
|| offset_expr.X_add_number >= 0x8000
|| offset_expr.X_add_number < -0x8000)
&& (mips_pic != EMBEDDED_PIC
|| offset_expr.X_op != O_subtract
|| ! S_IS_LOCAL (offset_expr.X_add_symbol)
|| ! S_IS_LOCAL (offset_expr.X_op_symbol)))
break;
offset_reloc = BFD_RELOC_LO16;
@ -5060,7 +5071,7 @@ int
mips_force_relocation (fixp)
fixS *fixp;
{
return mips_pic == EMBEDDED_PIC;
return fixp->fx_pcrel && mips_pic == EMBEDDED_PIC;
}
/* Apply a fixup to the object file. */
@ -5083,11 +5094,9 @@ md_apply_fix (fixP, valueP)
switch (fixP->fx_r_type)
{
case BFD_RELOC_32:
case BFD_RELOC_MIPS_JMP:
case BFD_RELOC_HI16:
case BFD_RELOC_HI16_S:
case BFD_RELOC_LO16:
case BFD_RELOC_MIPS_GPREL:
case BFD_RELOC_MIPS_LITERAL:
case BFD_RELOC_MIPS_CALL16:
@ -5096,6 +5105,30 @@ md_apply_fix (fixP, valueP)
/* Nothing needed to do. The value comes from the reloc entry */
break;
case BFD_RELOC_32:
/* If we are deleting this reloc entry, we must fill in the
value now. This can happen if we have a .word which is not
resolved when it appears but is later defined. */
if (fixP->fx_done)
md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
value, 4);
break;
case BFD_RELOC_LO16:
/* When handling an embedded PIC switch statement, we can wind
up deleting a LO16 reloc. See the 'o' case in mips_ip. */
if (fixP->fx_done)
{
if (value < -0x8000 || value > 0x7fff)
as_bad_where (fixP->fx_file, fixP->fx_line,
"relocation overflow");
buf = fixP->fx_frag->fr_literal + fixP->fx_where;
if (byte_order == BIG_ENDIAN)
buf += 2;
md_number_to_chars (buf, value, 2);
}
break;
case BFD_RELOC_16_PCREL_S2:
/*
* We need to save the bits in the instruction since fixup_segment()