diff options
author | Alan Modra <amodra@gmail.com> | 2014-06-03 10:55:29 +0930 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2014-06-03 10:55:29 +0930 |
commit | 397998fc32a34d3c8993ef46da45c3957a4dd402 (patch) | |
tree | 2dba3305c8567097b13505879d970299d2b9ad08 /gold | |
parent | 61f5c66f62502f33e1f2441a043bd29bb3ad6ea5 (diff) | |
download | fsf-binutils-gdb-397998fc32a34d3c8993ef46da45c3957a4dd402.zip fsf-binutils-gdb-397998fc32a34d3c8993ef46da45c3957a4dd402.tar.gz fsf-binutils-gdb-397998fc32a34d3c8993ef46da45c3957a4dd402.tar.bz2 |
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.
gdb/
* ppc64-tdep.c (ppc64_standard_linkage8): New.
(ppc64_skip_trampoline_code): Recognise ELFv2 stub supporting fusion.
Diffstat (limited to 'gold')
-rw-r--r-- | gold/ChangeLog | 5 | ||||
-rw-r--r-- | gold/powerpc.cc | 23 |
2 files changed, 22 insertions, 6 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog index 0bde6a1..5e15f5e 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,5 +1,10 @@ 2014-06-03 Alan Modra <amodra@gmail.com> + * powerpc.cc (addis_12_2): Define. + (Stub_table::do_write): Support fusion on ELFv2 stubs. + +2014-06-03 Alan Modra <amodra@gmail.com> + * testsuite/plugin_test.c (parse_readelf_line): Skip non-visibility st_other output. diff --git a/gold/powerpc.cc b/gold/powerpc.cc index 1078017..bd3994a 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<size, big_endian>::do_write(Output_file* of) { write_insn<big_endian>(p, std_2_1 + this->targ_->stk_toc()); p += 4; - write_insn<big_endian>(p, addis_11_2 + ha(off)); - p += 4; - write_insn<big_endian>(p, ld_12_11 + l(off)); - p += 4; + if (plt_load_toc) + { + write_insn<big_endian>(p, addis_11_2 + ha(off)); + p += 4; + write_insn<big_endian>(p, ld_12_11 + l(off)); + p += 4; + } + else + { + write_insn<big_endian>(p, addis_12_2 + ha(off)); + p += 4; + write_insn<big_endian>(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<size, big_endian>::do_write(Output_file* of) } else { - write_insn<big_endian>(p, addis_11_2 + ha(brltoff)), p += 4; - write_insn<big_endian>(p, ld_12_11 + l(brltoff)), p += 4; + write_insn<big_endian>(p, addis_12_2 + ha(brltoff)), p += 4; + write_insn<big_endian>(p, ld_12_12 + l(brltoff)), p += 4; } write_insn<big_endian>(p, mtctr_12), p += 4; write_insn<big_endian>(p, bctr); |