From 397998fc32a34d3c8993ef46da45c3957a4dd402 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Tue, 3 Jun 2014 10:55:29 +0930 Subject: 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. --- gold/powerpc.cc | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) (limited to 'gold/powerpc.cc') 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::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); -- cgit v1.1