diff options
author | Ian Lance Taylor <ian@airs.com> | 2004-12-09 07:12:28 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@airs.com> | 2004-12-09 07:12:28 +0000 |
commit | 1367d393bb745062d59a988a408f36bbb326764d (patch) | |
tree | 5c7fde6670180a5f992034c117c7a92eaf160d4f /bfd/elfxx-mips.c | |
parent | 74f79d8d758e2fda40bc52ab999b56f0e933c866 (diff) | |
download | gdb-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/elfxx-mips.c')
-rw-r--r-- | bfd/elfxx-mips.c | 39 |
1 files changed, 35 insertions, 4 deletions
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) |