aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@airs.com>2004-12-09 07:12:28 +0000
committerIan Lance Taylor <ian@airs.com>2004-12-09 07:12:28 +0000
commit1367d393bb745062d59a988a408f36bbb326764d (patch)
tree5c7fde6670180a5f992034c117c7a92eaf160d4f /bfd
parent74f79d8d758e2fda40bc52ab999b56f0e933c866 (diff)
downloadgdb-1367d393bb745062d59a988a408f36bbb326764d.zip
gdb-1367d393bb745062d59a988a408f36bbb326764d.tar.gz
gdb-1367d393bb745062d59a988a408f36bbb326764d.tar.bz2
* elfxx-mips.c (mips_elf_calculate_relocation): For R_MIPS_JALR,
return a real value, unless it is a PLT symbol. (mips_elf_perform_relocation): On the RM9000, turn a jal into a bal if possible.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog5
-rw-r--r--bfd/elfxx-mips.c39
2 files changed, 40 insertions, 4 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 5f79f68..6669277 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,10 @@
2004-12-09 Ian Lance Taylor <ian@wasabisystems.com>
+ * elfxx-mips.c (mips_elf_calculate_relocation): For R_MIPS_JALR,
+ return a real value, unless it is a PLT symbol.
+ (mips_elf_perform_relocation): On the RM9000, turn a jal into a
+ bal if possible.
+
* elfn32-mips.c (elf_mips_howto_table_rela): Change dst_mask of
R_MIPS_JALR entry to 0.
diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
index d246d41..ef4650b 100644
--- a/bfd/elfxx-mips.c
+++ b/bfd/elfxx-mips.c
@@ -3523,12 +3523,16 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
value &= howto->dst_mask;
break;
- case R_MIPS_PJUMP:
case R_MIPS_JALR:
- /* Both of these may be ignored. R_MIPS_JALR is an optimization
- hint; we could improve performance by honoring that hint. */
- return bfd_reloc_continue;
+ /* This relocation is only a hint. In some cases, we optimize
+ it into a bal instruction. But we don't try to optimize
+ branches to the PLT; that will wind up wasting time. */
+ if (h != NULL && h->root.plt.offset != (bfd_vma) -1)
+ return bfd_reloc_continue;
+ value = symbol + addend;
+ break;
+ case R_MIPS_PJUMP:
case R_MIPS_GNU_VTINHERIT:
case R_MIPS_GNU_VTENTRY:
/* We don't do anything with these at present. */
@@ -3730,6 +3734,33 @@ mips_elf_perform_relocation (struct bfd_link_info *info,
x = (x & ~(0x3f << 26)) | (jalx_opcode << 26);
}
+ /* On the RM9000, bal is faster than jal, because bal uses branch
+ prediction hardware. If we are linking for the RM9000, and we
+ see jal, and bal fits, use it instead. Note that this
+ transformation should be safe for all architectures. */
+ if (bfd_get_mach (input_bfd) == bfd_mach_mips9000
+ && !info->relocatable
+ && !require_jalx
+ && ((r_type == R_MIPS_26 && (x >> 26) == 0x3) /* jal addr */
+ || (r_type == R_MIPS_JALR && x == 0x0320f809))) /* jalr t9 */
+ {
+ bfd_vma addr;
+ bfd_vma dest;
+ bfd_signed_vma off;
+
+ addr = (input_section->output_section->vma
+ + input_section->output_offset
+ + relocation->r_offset
+ + 4);
+ if (r_type == R_MIPS_26)
+ dest = (value << 2) | ((addr >> 28) << 28);
+ else
+ dest = value;
+ off = dest - addr;
+ if (off <= 0x1ffff && off >= -0x20000)
+ x = 0x04110000 | (((bfd_vma) off >> 2) & 0xffff); /* bal addr */
+ }
+
/* Swap the high- and low-order 16 bits on little-endian systems
when doing a MIPS16 relocation. */
if ((r_type == R_MIPS16_GPREL || r_type == R_MIPS16_26)