summaryrefslogtreecommitdiff
path: root/lld
diff options
context:
space:
mode:
authorSean Fertile <sfertile@ca.ibm.com>2018-12-20 17:00:33 +0000
committerSean Fertile <sfertile@ca.ibm.com>2018-12-20 17:00:33 +0000
commitc992a1008f899f848a031df492d758ca3baefef5 (patch)
tree700173fa7b46a012b2152ef6583182d7119a66dd /lld
parent227090455b9c78ecfebab24542b6172bec13d8ff (diff)
[PPC64] Add toc-optimizations for got based relocations.
Differential Revision: https://reviews.llvm.org/D54907
Diffstat (limited to 'lld')
-rw-r--r--lld/ELF/Arch/PPC64.cpp22
-rw-r--r--lld/test/ELF/ppc64-got-off.s17
2 files changed, 32 insertions, 7 deletions
diff --git a/lld/ELF/Arch/PPC64.cpp b/lld/ELF/Arch/PPC64.cpp
index 4d42a26ee2e..94e98a31813 100644
--- a/lld/ELF/Arch/PPC64.cpp
+++ b/lld/ELF/Arch/PPC64.cpp
@@ -597,15 +597,23 @@ static std::pair<RelType, uint64_t> toAddr16Rel(RelType Type, uint64_t Val) {
}
}
-static bool isTocRelType(RelType Type) {
- return Type == R_PPC64_TOC16_HA || Type == R_PPC64_TOC16_LO_DS ||
- Type == R_PPC64_TOC16_LO;
+static bool isTocOptType(RelType Type) {
+ switch (Type) {
+ case R_PPC64_GOT16_HA:
+ case R_PPC64_GOT16_LO_DS:
+ case R_PPC64_TOC16_HA:
+ case R_PPC64_TOC16_LO_DS:
+ case R_PPC64_TOC16_LO:
+ return true;
+ default:
+ return false;
+ }
}
void PPC64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
// We need to save the original relocation type to determine if we should
// toc-optimize the instructions being relocated.
- bool IsTocRelType = isTocRelType(Type);
+ bool ShouldTocOptimize = isTocOptType(Type);
// For TOC-relative and GOT-indirect relocations, proceed in terms of the
// corresponding ADDR16 relocation type.
std::tie(Type, Val) = toAddr16Rel(Type, Val);
@@ -635,7 +643,7 @@ void PPC64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
case R_PPC64_ADDR16_HA:
case R_PPC64_REL16_HA:
case R_PPC64_TPREL16_HA:
- if (Config->TocOptimize && IsTocRelType && ha(Val) == 0)
+ if (Config->TocOptimize && ShouldTocOptimize && ha(Val) == 0)
writeInstrFromHalf16(Loc, 0x60000000);
else
write16(Loc, ha(Val));
@@ -667,7 +675,7 @@ void PPC64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
// When the high-adjusted part of a toc relocation evalutes to 0, it is
// changed into a nop. The lo part then needs to be updated to use the
// toc-pointer register r2, as the base register.
- if (Config->TocOptimize && IsTocRelType && ha(Val) == 0) {
+ if (Config->TocOptimize && ShouldTocOptimize && ha(Val) == 0) {
uint32_t Instr = readInstrFromHalf16(Loc);
if (isInstructionUpdateForm(Instr))
error(getErrorLocation(Loc) +
@@ -685,7 +693,7 @@ void PPC64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
uint32_t Inst = readInstrFromHalf16(Loc);
uint16_t Mask = isDQFormInstruction(Inst) ? 0xF : 0x3;
checkAlignment(Loc, lo(Val), Mask + 1, Type);
- if (Config->TocOptimize && IsTocRelType && ha(Val) == 0) {
+ if (Config->TocOptimize && ShouldTocOptimize && ha(Val) == 0) {
// When the high-adjusted part of a toc relocation evalutes to 0, it is
// changed into a nop. The lo part then needs to be updated to use the toc
// pointer register r2, as the base register.
diff --git a/lld/test/ELF/ppc64-got-off.s b/lld/test/ELF/ppc64-got-off.s
index 0a1a09e1ca9..d3dff226250 100644
--- a/lld/test/ELF/ppc64-got-off.s
+++ b/lld/test/ELF/ppc64-got-off.s
@@ -8,6 +8,14 @@
# RUN: ld.lld -shared --no-toc-optimize %t.o -o %t
# RUN: llvm-objdump -d %t | FileCheck %s
+# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
+# RUN: ld.lld -shared %t.o -o %t
+# RUN: llvm-objdump -d %t | FileCheck --check-prefix=OPT %s
+
+# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
+# RUN: ld.lld -shared %t.o -o %t
+# RUN: llvm-objdump -d %t | FileCheck --check-prefix=OPT %s
+
.abiversion 2
.section ".text"
@@ -38,6 +46,15 @@ func:
# CHECK-NEXT: li 6, 0
# CHECK-NEXT: ori 6, 6, 32776
+# OPT-LABEL: func
+# OPT: nop
+# OPT-NEXT: ld 3, -32760(2)
+# OPT-NEXT: ld 4, -32760(2)
+# OPT-NEXT: lis 5, -1
+# OPT-NEXT: ori 5, 5, 32776
+# OPT-NEXT: li 6, 0
+# OPT-NEXT: ori 6, 6, 32776
+
# Since the got entry for a is .got[1] and the TOC base points to
# .got + 0x8000, the offset for a@got is -0x7FF8 --> -32760