aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@airs.com>1994-04-05 19:57:32 +0000
committerIan Lance Taylor <ian@airs.com>1994-04-05 19:57:32 +0000
commitf3645945cfd49e1e1a33cc4273e4951cf6020202 (patch)
tree6272051a82323ef9349a4e61fb08e55cf772c695
parent632dcce87bf708e7261bf9912a358a3a5b06c335 (diff)
downloadgdb-f3645945cfd49e1e1a33cc4273e4951cf6020202.zip
gdb-f3645945cfd49e1e1a33cc4273e4951cf6020202.tar.gz
gdb-f3645945cfd49e1e1a33cc4273e4951cf6020202.tar.bz2
* 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.
-rw-r--r--gas/ChangeLog10
-rw-r--r--gas/config/tc-mips.c55
2 files changed, 54 insertions, 11 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index c8c80a4..0c46784 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -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,
diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c
index 08c5bb6..b118316 100644
--- a/gas/config/tc-mips.c
+++ b/gas/config/tc-mips.c
@@ -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()