From: Alan Modra Date: Tue, 3 Jun 2014 01:25:29 +0000 (+0930) Subject: Support fusion for ELFv2 stubs X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=37e6f1322b94f39c7aba198e113e621f4b4ea55e;p=thirdparty%2Fbinutils-gdb.git Support fusion for ELFv2 stubs Power8 fuses addis,addi and addis,ld sequences when the target of the addis is the same as the addi/ld. Thus addis r12,r2,xxx@ha addi r12,r12,xxx@l / ld r12,xxx@l(r12) is faster than addis r11,r2,xxx@ha addi r12,r11,xxx@l / ld r12,xxx@l(r11) So use the form that allows fusion in plt call and branch stubs. bfd/ * elf64-ppc.c (ADDIS_R12_R2): Define. (build_plt_stub): Support fusion on ELFv2 stub. (ppc_build_one_stub): Likewise for plt branch stubs. gold/ * powerpc.cc (addis_12_2): Define. (Stub_table::do_write): Support fusion on ELFv2 stubs. ld/testsuite/ * ld-powerpc/elfv2exe.d: Update for changed plt call stubs. --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index d8275b55a4e..e2111618388 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,6 +1,11 @@ 2014-06-12 Alan Modra Backport mainline patches + 2014-06-03 Alan Modra + * elf64-ppc.c (ADDIS_R12_R2): Define. + (build_plt_stub): Support fusion on ELFv2 stub. + (ppc_build_one_stub): Likewise for plt branch stubs. + 2014-03-26 Alan Modra * elf64-ppc.c (ppc64_elf_check_relocs): Account for possibly needed plt entries when taking the address of functions for diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index 0d50a1d7bf7..6cd1302c41b 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -175,6 +175,7 @@ static bfd_vma opd_entry_value #define LD_R2_0R1 0xe8410000 /* ld %r2,0(%r1) */ +#define ADDIS_R12_R2 0x3d820000 /* addis %r12,%r2,xxx@ha */ #define ADDIS_R12_R12 0x3d8c0000 /* addis %r12,%r12,xxx@ha */ #define LD_R12_0R12 0xe98c0000 /* ld %r12,xxx@l(%r12) */ @@ -10198,8 +10199,16 @@ build_plt_stub (struct ppc_link_hash_table *htab, if (ALWAYS_EMIT_R2SAVE || stub_entry->stub_type == ppc_stub_plt_call_r2save) bfd_put_32 (obfd, STD_R2_0R1 + STK_TOC (htab), p), p += 4; - bfd_put_32 (obfd, ADDIS_R11_R2 | PPC_HA (offset), p), p += 4; - bfd_put_32 (obfd, LD_R12_0R11 | PPC_LO (offset), p), p += 4; + if (plt_load_toc) + { + bfd_put_32 (obfd, ADDIS_R11_R2 | PPC_HA (offset), p), p += 4; + bfd_put_32 (obfd, LD_R12_0R11 | PPC_LO (offset), p), p += 4; + } + else + { + bfd_put_32 (obfd, ADDIS_R12_R2 | PPC_HA (offset), p), p += 4; + bfd_put_32 (obfd, LD_R12_0R12 | PPC_LO (offset), p), p += 4; + } if (plt_load_toc && PPC_HA (offset + 8 + 8 * plt_static_chain) != PPC_HA (offset)) { @@ -10620,10 +10629,10 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg) { size = 16; bfd_put_32 (htab->params->stub_bfd, - ADDIS_R11_R2 | PPC_HA (off), loc); + ADDIS_R12_R2 | PPC_HA (off), loc); loc += 4; bfd_put_32 (htab->params->stub_bfd, - LD_R12_0R11 | PPC_LO (off), loc); + LD_R12_0R12 | PPC_LO (off), loc); } else { @@ -10649,10 +10658,10 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg) { size += 4; bfd_put_32 (htab->params->stub_bfd, - ADDIS_R11_R2 | PPC_HA (off), loc); + ADDIS_R12_R2 | PPC_HA (off), loc); loc += 4; bfd_put_32 (htab->params->stub_bfd, - LD_R12_0R11 | PPC_LO (off), loc); + LD_R12_0R12 | PPC_LO (off), loc); } else bfd_put_32 (htab->params->stub_bfd, LD_R12_0R2 | PPC_LO (off), loc); diff --git a/gold/ChangeLog b/gold/ChangeLog index 56450443f7c..8143675a5f3 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,6 +1,10 @@ 2014-06-12 Alan Modra Backport mainline patches + 2014-06-03 Alan Modra + * powerpc.cc (addis_12_2): Define. + (Stub_table::do_write): Support fusion on ELFv2 stubs. + 2014-06-03 Alan Modra * testsuite/plugin_test.c (parse_readelf_line): Skip non-visibility st_other output. diff --git a/gold/powerpc.cc b/gold/powerpc.cc index f1167ee7975..84fb8f9ae6f 100644 --- a/gold/powerpc.cc +++ b/gold/powerpc.cc @@ -3077,6 +3077,7 @@ static const uint32_t addis_3_13 = 0x3c6d0000; static const uint32_t addis_11_2 = 0x3d620000; static const uint32_t addis_11_11 = 0x3d6b0000; static const uint32_t addis_11_30 = 0x3d7e0000; +static const uint32_t addis_12_2 = 0x3d820000; static const uint32_t addis_12_12 = 0x3d8c0000; static const uint32_t b = 0x48000000; static const uint32_t bcl_20_31 = 0x429f0005; @@ -4210,10 +4211,20 @@ Stub_table::do_write(Output_file* of) { write_insn(p, std_2_1 + this->targ_->stk_toc()); p += 4; - write_insn(p, addis_11_2 + ha(off)); - p += 4; - write_insn(p, ld_12_11 + l(off)); - p += 4; + if (plt_load_toc) + { + write_insn(p, addis_11_2 + ha(off)); + p += 4; + write_insn(p, ld_12_11 + l(off)); + p += 4; + } + else + { + write_insn(p, addis_12_2 + ha(off)); + p += 4; + write_insn(p, ld_12_12 + l(off)); + p += 4; + } if (plt_load_toc && ha(off + 8 + 8 * static_chain) != ha(off)) { @@ -4312,8 +4323,8 @@ Stub_table::do_write(Output_file* of) } else { - write_insn(p, addis_11_2 + ha(brltoff)), p += 4; - write_insn(p, ld_12_11 + l(brltoff)), p += 4; + write_insn(p, addis_12_2 + ha(brltoff)), p += 4; + write_insn(p, ld_12_12 + l(brltoff)), p += 4; } write_insn(p, mtctr_12), p += 4; write_insn(p, bctr); diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index bac96bf5b8f..b1cebe41a61 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,6 +1,9 @@ 2014-06-12 Alan Modra Apply mainline patches + 2014-06-03 Alan Modra + * ld-powerpc/elfv2exe.d: Update for changed plt call stubs. + 2014-03-26 Alan Modra * ld-powerpc/startv1.s, * ld-powerpc/startv2.s, * ld-powerpc/funref.s, * ld-powerpc/funv1.s, * ld-powerpc/funv2.s, diff --git a/ld/testsuite/ld-powerpc/elfv2exe.d b/ld/testsuite/ld-powerpc/elfv2exe.d index 7ff9d389113..9ea816c3153 100644 --- a/ld/testsuite/ld-powerpc/elfv2exe.d +++ b/ld/testsuite/ld-powerpc/elfv2exe.d @@ -8,14 +8,14 @@ Disassembly of section \.text: 0+100000c0 <.*\.plt_branch\.f2>: -.*: (ff ff 62 3d|3d 62 ff ff) addis r11,r2,-1 -.*: (f0 7f 8b e9|e9 8b 7f f0) ld r12,32752\(r11\) +.*: (ff ff 82 3d|3d 82 ff ff) addis r12,r2,-1 +.*: (f0 7f 8c e9|e9 8c 7f f0) ld r12,32752\(r12\) .*: (a6 03 89 7d|7d 89 03 a6) mtctr r12 .*: (20 04 80 4e|4e 80 04 20) bctr 0+100000d0 <.*\.plt_branch\.f4>: -.*: (ff ff 62 3d|3d 62 ff ff) addis r11,r2,-1 -.*: (f8 7f 8b e9|e9 8b 7f f8) ld r12,32760\(r11\) +.*: (ff ff 82 3d|3d 82 ff ff) addis r12,r2,-1 +.*: (f8 7f 8c e9|e9 8c 7f f8) ld r12,32760\(r12\) .*: (a6 03 89 7d|7d 89 03 a6) mtctr r12 .*: (20 04 80 4e|4e 80 04 20) bctr