aboutsummaryrefslogtreecommitdiff
path: root/ld/emultempl/ppc64elf.em
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2020-07-17 16:47:28 +0930
committerAlan Modra <amodra@gmail.com>2020-07-19 12:27:47 +0930
commite10a07b32dc1faed25b5bbcbbc47d68e2ff537b9 (patch)
tree1eeb63b4cdb332eb53f3e8f4ae91773bda69a008 /ld/emultempl/ppc64elf.em
parent6095ca52575d8e49003a3685453bc5bd0d929f1e (diff)
downloadfsf-binutils-gdb-e10a07b32dc1faed25b5bbcbbc47d68e2ff537b9.zip
fsf-binutils-gdb-e10a07b32dc1faed25b5bbcbbc47d68e2ff537b9.tar.gz
fsf-binutils-gdb-e10a07b32dc1faed25b5bbcbbc47d68e2ff537b9.tar.bz2
Power10 stub selection
This patch better supports mixing of power10 and non-power10 code, as might be seen in a cpu-optimized library using ifuncs to select functions optimized for a given cpu. Using -Wl,--no-power10-stubs isn't that good in this situation since non-power10 notoc stubs are slower and larger than the power10 variants, which you'd like to use on power10 code paths. With this change, power10 pc-relative code that makes calls marked @notoc uses power10 stubs if stubs are necessary, and other calls use non-power10 instructions in stubs. This will mean that if gcc is generating code for -mcpu=power10 but with pc-rel disabled then you'll get the older stubs even on power10 (unless you force with -Wl,--power10-stubs). That shouldn't be too big a problem: stubs that use r2 are reasonable. It's just the ones that set up addressing using "mflr 12; bcl 20,31,.+4; mflr 11; mtlr 12" that should be avoided if possible. bfd/ * elf64-ppc.c (struct ppc_link_hash_table): Add has_power10_relocs. (select_alt_stub): New function. (ppc_get_stub_entry): Use it here. (ppc64_elf_check_relocs): Set had_power10_relocs rather than power10_stubs. (ppc64_elf_size_stubs): Clear power10_stubs here instead. Don't merge notoc stubs with other varieties when power10_stubs is "auto". Instead dup the stub hash table entry. (plt_stub_size, ppc_build_one_stub, ppc_size_one_stub): Adjust tests of power10_stubs. ld/ * emultempl/ppc64elf.em (power10-stubs): Accept optional "auto" arg. * ld.texi (power10-stubs): Update. * testsuite/ld-powerpc/callstub-1.d: Force --power10-stubs. * testsuite/ld-powerpc/callstub-2.d: Relax branch offset comparison. * testsuite/ld-powerpc/callstub-4.d: New test. * testsuite/ld-powerpc/notoc.d: Force --no-power10-stubs. * testsuite/ld-powerpc/notoc3.d, * testsuite/ld-powerpc/notoc3.s, * testsuite/ld-powerpc/notoc3.wf: New test. * testsuite/ld-powerpc/powerpc.exp: Run new tests. Pass --no-power10-stubs for notoc link.
Diffstat (limited to 'ld/emultempl/ppc64elf.em')
-rw-r--r--ld/emultempl/ppc64elf.em19
1 files changed, 16 insertions, 3 deletions
diff --git a/ld/emultempl/ppc64elf.em b/ld/emultempl/ppc64elf.em
index 4987243..1331d03 100644
--- a/ld/emultempl/ppc64elf.em
+++ b/ld/emultempl/ppc64elf.em
@@ -716,7 +716,7 @@ PARSE_AND_LIST_LONGOPTS=${PARSE_AND_LIST_LONGOPTS}'
{ "no-plt-align", no_argument, NULL, OPTION_NO_PLT_ALIGN },
{ "plt-localentry", optional_argument, NULL, OPTION_PLT_LOCALENTRY },
{ "no-plt-localentry", no_argument, NULL, OPTION_NO_PLT_LOCALENTRY },
- { "power10-stubs", no_argument, NULL, OPTION_POWER10_STUBS },
+ { "power10-stubs", optional_argument, NULL, OPTION_POWER10_STUBS },
{ "no-power10-stubs", no_argument, NULL, OPTION_NO_POWER10_STUBS },
{ "emit-stub-syms", no_argument, NULL, OPTION_STUBSYMS },
{ "no-emit-stub-syms", no_argument, NULL, OPTION_NO_STUBSYMS },
@@ -773,7 +773,7 @@ PARSE_AND_LIST_OPTIONS=${PARSE_AND_LIST_OPTIONS}'
--no-plt-localentry Don'\''t optimize ELFv2 calls\n"
));
fprintf (file, _("\
- --power10-stubs Use Power10 PLT call stubs (default auto)\n"
+ --power10-stubs [=auto] Use Power10 PLT call stubs (default auto)\n"
));
fprintf (file, _("\
--no-power10-stubs Don'\''t use Power10 PLT call stubs\n"
@@ -889,7 +889,20 @@ PARSE_AND_LIST_ARGS_CASES=${PARSE_AND_LIST_ARGS_CASES}'
break;
case OPTION_POWER10_STUBS:
- params.power10_stubs = 1;
+ if (optarg != NULL)
+ {
+ if (strcasecmp (optarg, "auto") == 0)
+ params.power10_stubs = -1;
+ else if (strcasecmp (optarg, "yes") == 0)
+ params.power10_stubs = 1;
+ else if (strcasecmp (optarg, "no") == 0)
+ params.power10_stubs = 0;
+ else
+ einfo (_("%F%P: invalid --power10-stubs argument `%s'\''\n"),
+ optarg);
+ }
+ else
+ params.power10_stubs = 1;
break;
case OPTION_NO_POWER10_STUBS: