[llvm] b6e2eac - [JITLink][PowerPC] Add relocations included in rtdyld but missing from jitlink
Kai Luo via llvm-commits
llvm-commits at lists.llvm.org
Sat Aug 12 18:44:24 PDT 2023
Author: Kai Luo
Date: 2023-08-13T09:44:18+08:00
New Revision: b6e2eac2930e3ba8593e6bc211fa85b1783ce3de
URL: https://github.com/llvm/llvm-project/commit/b6e2eac2930e3ba8593e6bc211fa85b1783ce3de
DIFF: https://github.com/llvm/llvm-project/commit/b6e2eac2930e3ba8593e6bc211fa85b1783ce3de.diff
LOG: [JITLink][PowerPC] Add relocations included in rtdyld but missing from jitlink
RuntimeDyld has implemented more relocations than JITLink for ppc64. This patch adds relocations missing from JITLink for ppc64.
Reviewed By: lhames
Differential Revision: https://reviews.llvm.org/D157366
Added:
Modified:
llvm/include/llvm/ExecutionEngine/JITLink/ppc64.h
llvm/lib/ExecutionEngine/JITLink/ELF_ppc64.cpp
llvm/lib/ExecutionEngine/JITLink/ppc64.cpp
llvm/test/ExecutionEngine/JITLink/ppc64/ELF_ppc64_relocations.s
llvm/test/ExecutionEngine/JITLink/ppc64/ppc64-relocs.s
Removed:
################################################################################
diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/ppc64.h b/llvm/include/llvm/ExecutionEngine/JITLink/ppc64.h
index 411e2bf3ab7d30..42ab9ddd8765b4 100644
--- a/llvm/include/llvm/ExecutionEngine/JITLink/ppc64.h
+++ b/llvm/include/llvm/ExecutionEngine/JITLink/ppc64.h
@@ -23,16 +23,33 @@ namespace llvm::jitlink::ppc64 {
enum EdgeKind_ppc64 : Edge::Kind {
Pointer64 = Edge::FirstRelocation,
Pointer32,
+ Pointer16,
+ Pointer16DS,
+ Pointer16HA,
+ Pointer16HI,
+ Pointer16HIGH,
+ Pointer16HIGHA,
+ Pointer16HIGHER,
+ Pointer16HIGHERA,
+ Pointer16HIGHEST,
+ Pointer16HIGHESTA,
+ Pointer16LO,
+ Pointer16LODS,
+ Pointer14,
Delta64,
Delta34,
Delta32,
NegDelta32,
Delta16,
Delta16HA,
+ Delta16HI,
Delta16LO,
+ TOC,
+ TOCDelta16,
+ TOCDelta16DS,
TOCDelta16HA,
+ TOCDelta16HI,
TOCDelta16LO,
- TOCDelta16DS,
TOCDelta16LODS,
CallBranchDelta,
// Need to restore r2 after the bl, suggesting the bl is followed by a nop.
@@ -232,9 +249,19 @@ class PLTTableManager : public TableManager<PLTTableManager<Endianness>> {
/// only.
const char *getEdgeKindName(Edge::Kind K);
-inline static uint16_t ha16(uint64_t x) { return (x + 0x8000) >> 16; }
-
-inline static uint16_t lo16(uint64_t x) { return x & 0xffff; }
+inline static uint16_t ha(uint64_t x) { return (x + 0x8000) >> 16; }
+inline static uint64_t lo(uint64_t x) { return x & 0xffff; }
+inline static uint16_t hi(uint64_t x) { return x >> 16; }
+inline static uint64_t high(uint64_t x) { return (x >> 16) & 0xffff; }
+inline static uint64_t higha(uint64_t x) {
+ return ((x + 0x8000) >> 16) & 0xffff;
+}
+inline static uint64_t higher(uint64_t x) { return (x >> 32) & 0xffff; }
+inline static uint64_t highera(uint64_t x) {
+ return ((x + 0x8000) >> 32) & 0xffff;
+}
+inline static uint16_t highest(uint64_t x) { return x >> 48; }
+inline static uint16_t highesta(uint64_t x) { return (x + 0x8000) >> 48; }
// Prefixed instruction introduced in ISAv3.1 consists of two 32-bit words,
// prefix word and suffix word, i.e., prefixed_instruction = concat(prefix_word,
@@ -256,6 +283,63 @@ inline static void writePrefixedInstruction(char *Loc, uint64_t Inst) {
support::endian::write64<Endianness>(Loc, Inst);
}
+template <support::endianness Endianness>
+inline Error relocateHalf16(char *FixupPtr, int64_t Value, Edge::Kind K) {
+ switch (K) {
+ case Delta16:
+ case Pointer16:
+ case TOCDelta16:
+ support::endian::write16<Endianness>(FixupPtr, Value);
+ break;
+ case Pointer16DS:
+ case TOCDelta16DS:
+ support::endian::write16<Endianness>(FixupPtr, Value & ~3);
+ break;
+ case Delta16HA:
+ case Pointer16HA:
+ case TOCDelta16HA:
+ support::endian::write16<Endianness>(FixupPtr, ha(Value));
+ break;
+ case Delta16HI:
+ case Pointer16HI:
+ case TOCDelta16HI:
+ support::endian::write16<Endianness>(FixupPtr, hi(Value));
+ break;
+ case Pointer16HIGH:
+ support::endian::write16<Endianness>(FixupPtr, high(Value));
+ break;
+ case Pointer16HIGHA:
+ support::endian::write16<Endianness>(FixupPtr, higha(Value));
+ break;
+ case Pointer16HIGHER:
+ support::endian::write16<Endianness>(FixupPtr, higher(Value));
+ break;
+ case Pointer16HIGHERA:
+ support::endian::write16<Endianness>(FixupPtr, highera(Value));
+ break;
+ case Pointer16HIGHEST:
+ support::endian::write16<Endianness>(FixupPtr, highest(Value));
+ break;
+ case Pointer16HIGHESTA:
+ support::endian::write16<Endianness>(FixupPtr, highesta(Value));
+ break;
+ case Delta16LO:
+ case Pointer16LO:
+ case TOCDelta16LO:
+ support::endian::write16<Endianness>(FixupPtr, lo(Value));
+ break;
+ case Pointer16LODS:
+ case TOCDelta16LODS:
+ support::endian::write16<Endianness>(FixupPtr, lo(Value) & ~3);
+ break;
+ default:
+ return make_error<JITLinkError>(
+ StringRef(getEdgeKindName(K)) +
+ " relocation does not write at half16 field");
+ }
+ return Error::success();
+}
+
/// Apply fixup expression for edge to block content.
template <support::endianness Endianness>
inline Error applyFixup(LinkGraph &G, Block &B, const Edge &E,
@@ -282,41 +366,60 @@ inline Error applyFixup(LinkGraph &G, Block &B, const Edge &E,
support::endian::write64<Endianness>(FixupPtr, Value);
break;
}
+ case Delta16:
case Delta16HA:
+ case Delta16HI:
case Delta16LO: {
int64_t Value = S + A - P;
if (LLVM_UNLIKELY(!isInt<32>(Value))) {
return makeTargetOutOfRangeError(G, B, E);
}
- if (K == Delta16LO)
- support::endian::write16<Endianness>(FixupPtr, lo16(Value));
- else
- support::endian::write16<Endianness>(FixupPtr, ha16(Value));
- break;
+ return relocateHalf16<Endianness>(FixupPtr, Value, K);
}
- case TOCDelta16HA:
- case TOCDelta16LO: {
- int64_t Value = S + A - TOCBase;
+ case TOC:
+ support::endian::write64<Endianness>(FixupPtr, TOCBase);
+ break;
+ case Pointer16:
+ case Pointer16DS:
+ case Pointer16HA:
+ case Pointer16HI:
+ case Pointer16HIGH:
+ case Pointer16HIGHA:
+ case Pointer16HIGHER:
+ case Pointer16HIGHERA:
+ case Pointer16HIGHEST:
+ case Pointer16HIGHESTA:
+ case Pointer16LO:
+ case Pointer16LODS: {
+ uint64_t Value = S + A;
if (LLVM_UNLIKELY(!isInt<32>(Value))) {
return makeTargetOutOfRangeError(G, B, E);
}
- if (K == TOCDelta16LO)
- support::endian::write16<Endianness>(FixupPtr, lo16(Value));
- else
- support::endian::write16<Endianness>(FixupPtr, ha16(Value));
+ return relocateHalf16<Endianness>(FixupPtr, Value, K);
+ }
+ case Pointer14: {
+ static const uint32_t Low14Mask = 0xfffc;
+ uint64_t Value = S + A;
+ assert((Value & 3) == 0 && "Pointer14 requires 4-byte alignment");
+ if (LLVM_UNLIKELY(!isInt<16>(Value))) {
+ return makeTargetOutOfRangeError(G, B, E);
+ }
+ uint32_t Inst = support::endian::read32<Endianness>(FixupPtr);
+ support::endian::write32<Endianness>(FixupPtr, (Inst & ~Low14Mask) |
+ (Value & Low14Mask));
break;
}
+ case TOCDelta16:
case TOCDelta16DS:
+ case TOCDelta16HA:
+ case TOCDelta16HI:
+ case TOCDelta16LO:
case TOCDelta16LODS: {
int64_t Value = S + A - TOCBase;
if (LLVM_UNLIKELY(!isInt<32>(Value))) {
return makeTargetOutOfRangeError(G, B, E);
}
- if (K == TOCDelta16LODS)
- support::endian::write16<Endianness>(FixupPtr, lo16(Value) & ~3);
- else
- support::endian::write16<Endianness>(FixupPtr, Value & ~3);
- break;
+ return relocateHalf16<Endianness>(FixupPtr, Value, K);
}
case CallBranchDeltaRestoreTOC:
case CallBranchDelta: {
diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_ppc64.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_ppc64.cpp
index 8d1a729e405766..fb08b17f4077ee 100644
--- a/llvm/lib/ExecutionEngine/JITLink/ELF_ppc64.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/ELF_ppc64.cpp
@@ -266,9 +266,57 @@ class ELFLinkGraphBuilder_ppc64
case ELF::R_PPC64_ADDR32:
Kind = ppc64::Pointer32;
break;
+ case ELF::R_PPC64_ADDR16:
+ Kind = ppc64::Pointer16;
+ break;
+ case ELF::R_PPC64_ADDR16_DS:
+ Kind = ppc64::Pointer16DS;
+ break;
+ case ELF::R_PPC64_ADDR16_HA:
+ Kind = ppc64::Pointer16HA;
+ break;
+ case ELF::R_PPC64_ADDR16_HI:
+ Kind = ppc64::Pointer16HI;
+ break;
+ case ELF::R_PPC64_ADDR16_HIGH:
+ Kind = ppc64::Pointer16HIGH;
+ break;
+ case ELF::R_PPC64_ADDR16_HIGHA:
+ Kind = ppc64::Pointer16HIGHA;
+ break;
+ case ELF::R_PPC64_ADDR16_HIGHER:
+ Kind = ppc64::Pointer16HIGHER;
+ break;
+ case ELF::R_PPC64_ADDR16_HIGHERA:
+ Kind = ppc64::Pointer16HIGHERA;
+ break;
+ case ELF::R_PPC64_ADDR16_HIGHEST:
+ Kind = ppc64::Pointer16HIGHEST;
+ break;
+ case ELF::R_PPC64_ADDR16_HIGHESTA:
+ Kind = ppc64::Pointer16HIGHESTA;
+ break;
+ case ELF::R_PPC64_ADDR16_LO:
+ Kind = ppc64::Pointer16LO;
+ break;
+ case ELF::R_PPC64_ADDR16_LO_DS:
+ Kind = ppc64::Pointer16LODS;
+ break;
+ case ELF::R_PPC64_ADDR14:
+ Kind = ppc64::Pointer14;
+ break;
+ case ELF::R_PPC64_TOC:
+ Kind = ppc64::TOC;
+ break;
+ case ELF::R_PPC64_TOC16:
+ Kind = ppc64::TOCDelta16;
+ break;
case ELF::R_PPC64_TOC16_HA:
Kind = ppc64::TOCDelta16HA;
break;
+ case ELF::R_PPC64_TOC16_HI:
+ Kind = ppc64::TOCDelta16HI;
+ break;
case ELF::R_PPC64_TOC16_DS:
Kind = ppc64::TOCDelta16DS;
break;
@@ -284,6 +332,9 @@ class ELFLinkGraphBuilder_ppc64
case ELF::R_PPC64_REL16_HA:
Kind = ppc64::Delta16HA;
break;
+ case ELF::R_PPC64_REL16_HI:
+ Kind = ppc64::Delta16HI;
+ break;
case ELF::R_PPC64_REL16_LO:
Kind = ppc64::Delta16LO;
break;
diff --git a/llvm/lib/ExecutionEngine/JITLink/ppc64.cpp b/llvm/lib/ExecutionEngine/JITLink/ppc64.cpp
index 6cb850473fc5b8..b147ffc8dac217 100644
--- a/llvm/lib/ExecutionEngine/JITLink/ppc64.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/ppc64.cpp
@@ -64,6 +64,32 @@ const char *getEdgeKindName(Edge::Kind K) {
return "Pointer64";
case Pointer32:
return "Pointer32";
+ case Pointer16:
+ return "Pointer16";
+ case Pointer16DS:
+ return "Pointer16DS";
+ case Pointer16HA:
+ return "Pointer16HA";
+ case Pointer16HI:
+ return "Pointer16HI";
+ case Pointer16HIGH:
+ return "Pointer16HIGH";
+ case Pointer16HIGHA:
+ return "Pointer16HIGHA";
+ case Pointer16HIGHER:
+ return "Pointer16HIGHER";
+ case Pointer16HIGHERA:
+ return "Pointer16HIGHERA";
+ case Pointer16HIGHEST:
+ return "Pointer16HIGHEST";
+ case Pointer16HIGHESTA:
+ return "Pointer16HIGHESTA";
+ case Pointer16LO:
+ return "Pointer16LO";
+ case Pointer16LODS:
+ return "Pointer16LODS";
+ case Pointer14:
+ return "Pointer14";
case Delta64:
return "Delta64";
case Delta34:
@@ -76,14 +102,22 @@ const char *getEdgeKindName(Edge::Kind K) {
return "Delta16";
case Delta16HA:
return "Delta16HA";
+ case Delta16HI:
+ return "Delta16HI";
case Delta16LO:
return "Delta16LO";
+ case TOC:
+ return "TOC";
+ case TOCDelta16:
+ return "TOCDelta16";
+ case TOCDelta16DS:
+ return "TOCDelta16DS";
case TOCDelta16HA:
return "TOCDelta16HA";
+ case TOCDelta16HI:
+ return "TOCDelta16HI";
case TOCDelta16LO:
return "TOCDelta16LO";
- case TOCDelta16DS:
- return "TOCDelta16DS";
case TOCDelta16LODS:
return "TOCDelta16LODS";
case CallBranchDelta:
diff --git a/llvm/test/ExecutionEngine/JITLink/ppc64/ELF_ppc64_relocations.s b/llvm/test/ExecutionEngine/JITLink/ppc64/ELF_ppc64_relocations.s
index dcbd172c881e59..7e39a20ef6ab8b 100644
--- a/llvm/test/ExecutionEngine/JITLink/ppc64/ELF_ppc64_relocations.s
+++ b/llvm/test/ExecutionEngine/JITLink/ppc64/ELF_ppc64_relocations.s
@@ -1,10 +1,13 @@
# RUN: rm -rf %t && mkdir -p %t
# RUN: llvm-mc --triple=powerpc64le-unknown-linux-gnu --filetype=obj -o \
-# RUN: %t/elf_reloc.o %s
+# RUN: %t/elf_reloc.o --defsym LE=1 %s
# RUN: llvm-jitlink --noexec \
# RUN: --abs external_data=0xdeadbeef \
# RUN: --abs external_func=0xcafef00d \
# RUN: --abs external_func_notoc=0x88880000 \
+# RUN: --abs external_addr14_func=0x0880 \
+# RUN: --abs external_addr16_data=0x6000 \
+# RUN: --abs external_addr32_data=0x36668840 \
# RUN: --check %s %t/elf_reloc.o
# RUN: llvm-mc --triple=powerpc64-unknown-linux-gnu --filetype=obj -o \
# RUN: %t/elf_reloc.o %s
@@ -12,11 +15,16 @@
# RUN: --abs external_data=0xdeadbeef \
# RUN: --abs external_func=0xcafef00d \
# RUN: --abs external_func_notoc=0x88880000 \
+# RUN: --abs external_addr14_func=0x0880 \
+# RUN: --abs external_addr16_data=0x6000 \
+# RUN: --abs external_addr32_data=0x36668840 \
# RUN: --check %s %t/elf_reloc.o
# jitlink-check: section_addr(elf_reloc.o, $__GOT) + 0x8000 = __TOC__
.text
.abiversion 2
+ .global external_addr32_data
+ .global external_addr16_data
.global main
.p2align 4
.type main, at function
@@ -100,6 +108,138 @@ test_pcrel34:
blr
.size test_pcrel34, .-test_pcrel34
+# Check R_PPC64_ADDR14
+# jitlink-check: decode_operand(reloc_addr14, 2) << 2 = external_addr14_func
+ .global reloc_addr14
+ .p2align 4
+ .type reloc_addr14, at function
+reloc_addr14:
+ bca 21, 30, external_addr14_func
+ .size reloc_addr14, .-reloc_addr14
+
+# Check R_PPC64_TOC16
+# jitlink-check: decode_operand(reloc_toc16, 1) & 0xffff = \
+# jitlink-check: (section_addr(elf_reloc.o, .rodata.str1.1) - __TOC__) & 0xffff
+# jitlink-check: decode_operand(reloc_toc16 + 4, 1) & 0xffff = \
+# jitlink-check: ((section_addr(elf_reloc.o, .rodata.str1.1) - __TOC__) >> 16) & 0xffff
+# jitlink-check: decode_operand(reloc_toc16 + 8, 1) & 0xffff = \
+# jitlink-check: (((section_addr(elf_reloc.o, .rodata.str1.1) - __TOC__) + 0x8000) >> 16) & 0xffff
+# jitlink-check: decode_operand(reloc_toc16 + 12, 1) & 0xffff = \
+# jitlink-check: (section_addr(elf_reloc.o, .rodata.str1.1) - __TOC__) & 0xffff
+ .global reloc_toc16
+ .p2align 4
+ .type reloc_toc16, at function
+reloc_toc16:
+.ifdef LE
+ li 3, 0
+ .reloc reloc_toc16, R_PPC64_TOC16, .L.str
+ li 3, 0
+ .reloc reloc_toc16+4, R_PPC64_TOC16_HI, .L.str
+ li 3, 0
+ .reloc reloc_toc16+8, R_PPC64_TOC16_HA, .L.str
+ li 3, 0
+ .reloc reloc_toc16+12, R_PPC64_TOC16_DS, .L.str
+.else
+ li 3, 0
+ .reloc reloc_toc16+2, R_PPC64_TOC16, .L.str
+ li 3, 0
+ .reloc reloc_toc16+6, R_PPC64_TOC16_HI, .L.str
+ li 3, 0
+ .reloc reloc_toc16+10, R_PPC64_TOC16_HA, .L.str
+ li 3, 0
+ .reloc reloc_toc16+14, R_PPC64_TOC16_DS, .L.str
+.endif
+ blr
+ .size reloc_toc16, .-reloc_toc16
+
+# Check R_PPC64_ADDR16*
+# R_PPC64_ADDR16_DS
+# jitlink-check: decode_operand(reloc_addr16, 1) & 0xffff = \
+# jitlink-check: external_addr16_data
+# R_PPC64_ADDR16_LO
+# jitlink-check: decode_operand(reloc_addr16 + 4, 1) & 0xffff = \
+# jitlink-check: external_addr32_data & 0xffff
+# R_PPC64_ADDR16_LO_DS
+# jitlink-check: decode_operand(reloc_addr16 + 8, 1) & 0xffff = \
+# jitlink-check: external_addr32_data & 0xffff
+# R_PPC64_ADDR16
+# jitlink-check: decode_operand(reloc_addr16 + 12, 1) & 0xffff = \
+# jitlink-check: external_addr16_data
+# R_PPC64_ADDR16_HI
+# jitlink-check: decode_operand(reloc_addr16 + 16, 1) & 0xffff = \
+# jitlink-check: (external_addr32_data >> 16) & 0xffff
+# R_PPC64_ADDR16_HA
+# jitlink-check: decode_operand(reloc_addr16 + 20, 1) & 0xffff = \
+# jitlink-check: ((external_addr32_data + 0x8000) >> 16) & 0xffff
+# R_PPC64_ADDR16_HIGH
+# jitlink-check: decode_operand(reloc_addr16 + 24, 1) & 0xffff = \
+# jitlink-check: (external_addr32_data >> 16) & 0xffff
+# R_PPC64_ADDR16_HIGHA
+# jitlink-check: decode_operand(reloc_addr16 + 28, 1) & 0xffff = \
+# jitlink-check: ((external_addr32_data + 0x8000) >> 16) & 0xffff
+# R_PPC64_ADDR16_HIGHER
+# jitlink-check: decode_operand(reloc_addr16 + 32, 1) & 0xffff = \
+# jitlink-check: (external_addr32_data >> 32) & 0xffff
+# R_PPC64_ADDR16_HIGHERA
+# jitlink-check: decode_operand(reloc_addr16 + 36, 1) & 0xffff = \
+# jitlink-check: ((external_addr32_data + 0x8000) >> 32) & 0xffff
+# R_PPC64_ADDR16_HIGHEST
+# jitlink-check: decode_operand(reloc_addr16 + 40, 1) & 0xffff = \
+# jitlink-check: (external_addr32_data >> 48) & 0xffff
+# R_PPC64_ADDR16_HIGHESTA
+# jitlink-check: decode_operand(reloc_addr16 + 44, 1) & 0xffff = \
+# jitlink-check: ((external_addr32_data + 0x8000) >> 48) & 0xffff
+ .global reloc_addr16
+ .p2align 4
+ .type reloc_addr16, at function
+reloc_addr16:
+.ifdef LE
+ li 3, 0
+ .reloc reloc_addr16, R_PPC64_ADDR16_DS, external_addr16_data
+ li 3, 0
+ .reloc reloc_addr16+4, R_PPC64_ADDR16_LO, external_addr32_data
+ li 3, 0
+ .reloc reloc_addr16+8, R_PPC64_ADDR16_LO_DS, external_addr32_data
+ li 3, 0
+ .reloc reloc_addr16+12, R_PPC64_ADDR16, external_addr16_data
+ li 3, 0
+ .reloc reloc_addr16+16, R_PPC64_ADDR16_HI, external_addr32_data
+.else
+ li 3, 0
+ .reloc reloc_addr16+2, R_PPC64_ADDR16_DS, external_addr16_data
+ li 3, 0
+ .reloc reloc_addr16+6, R_PPC64_ADDR16_LO, external_addr32_data
+ li 3, 0
+ .reloc reloc_addr16+10, R_PPC64_ADDR16_LO_DS, external_addr32_data
+ li 3, 0
+ .reloc reloc_addr16+14, R_PPC64_ADDR16, external_addr16_data
+ li 3, 0
+ .reloc reloc_addr16+18, R_PPC64_ADDR16_HI, external_addr32_data
+.endif
+ li 3, external_addr32_data at ha
+ li 3, external_addr32_data at high
+ li 3, external_addr32_data at higha
+ li 3, external_addr32_data at higher
+ li 3, external_addr32_data at highera
+ li 3, external_addr32_data at highest
+ li 3, external_addr32_data at highesta
+ blr
+ .size reloc_addr16, .-reloc_addr16
+
+# Check R_PPC64_REL16*
+# jitlink-check: decode_operand(reloc_rel16, 1) & 0xffff = \
+# jitlink-check: (__TOC__ - reloc_rel16) & 0xffff
+# jitlink-check: decode_operand(reloc_rel16 + 4, 1) & 0xffff = \
+# jitlink-check: ((__TOC__ - reloc_rel16) >> 16) & 0xffff
+ .global reloc_rel16
+ .p2align 4
+ .type reloc_rel16, at function
+reloc_rel16:
+ li 3, .TOC.-reloc_rel16
+ li 3, .TOC.-reloc_rel16 at h
+ blr
+ .size reloc_rel16, .-reloc_rel16
+
.type .L.str, at object
.section .rodata.str1.1,"aMS", at progbits,1
.L.str:
diff --git a/llvm/test/ExecutionEngine/JITLink/ppc64/ppc64-relocs.s b/llvm/test/ExecutionEngine/JITLink/ppc64/ppc64-relocs.s
index 6f5b29eb5a33ed..fce15c2b725d41 100644
--- a/llvm/test/ExecutionEngine/JITLink/ppc64/ppc64-relocs.s
+++ b/llvm/test/ExecutionEngine/JITLink/ppc64/ppc64-relocs.s
@@ -1,9 +1,10 @@
-# RUN: llvm-mc -triple=powerpc64le-unknown-linux-gnu -filetype=obj -o %t %s
+# RUN: llvm-mc -triple=powerpc64le-unknown-linux-gnu -filetype=obj -o %t %s \
+# RUN: --defsym LE=1
# RUN: llvm-jitlink -abs external_var=0xffff0000 -abs puts=0xffff6400 -abs \
-# RUN: foo=0xffff8800 -noexec %t
+# RUN: foo=0xffff8800 -abs low_addr=0x0320 -noexec %t
# RUN: llvm-mc -triple=powerpc64-unknown-linux-gnu -filetype=obj -o %t %s
# RUN: llvm-jitlink -abs external_var=0xffff0000 -abs puts=0xffff6400 -abs \
-# RUN: foo=0xffff8800 -noexec %t
+# RUN: foo=0xffff8800 -abs low_addr=0x0320 -noexec %t
#
# Check typical relocations involving external function call, external variable
# reference, local function call and referencing global variable defined in the
@@ -197,6 +198,102 @@ foobar:
.Lfunc_end8:
.size foobar, .Lfunc_end8-.Lfunc_begin8
+ .global reloc_addr14
+ .p2align 4
+ .type reloc_addr14, at function
+reloc_addr14:
+.Lfunc_begin9:
+ bca 21, 30, low_addr
+.Lfunc_end9:
+ .size reloc_addr14, .Lfunc_end9-.Lfunc_begin9
+
+ .global reloc_half16
+ .p2align 4
+ .type reloc_half16, at function
+reloc_half16:
+.Lfunc_begin10:
+.ifdef LE
+ li 3, 0
+ .reloc .Lfunc_begin10, R_PPC64_ADDR16_DS, low_addr
+ li 3, 0
+ .reloc .Lfunc_begin10+4, R_PPC64_ADDR16_LO, low_addr
+ li 3, 0
+ .reloc .Lfunc_begin10+8, R_PPC64_ADDR16_LO_DS, low_addr
+ li 3, 0
+ .reloc .Lfunc_begin10+12, R_PPC64_ADDR16, low_addr
+ li 3, 0
+ .reloc .Lfunc_begin10+16, R_PPC64_ADDR16_HI, low_addr
+.else
+ li 3, 0
+ .reloc .Lfunc_begin10+2, R_PPC64_ADDR16_DS, low_addr
+ li 3, 0
+ .reloc .Lfunc_begin10+6, R_PPC64_ADDR16_LO, low_addr
+ li 3, 0
+ .reloc .Lfunc_begin10+10, R_PPC64_ADDR16_LO_DS, low_addr
+ li 3, 0
+ .reloc .Lfunc_begin10+14, R_PPC64_ADDR16, low_addr
+ li 3, 0
+ .reloc .Lfunc_begin10+18, R_PPC64_ADDR16_HI, low_addr
+.endif
+ li 3, low_addr at ha
+ li 3, low_addr at high
+ li 3, low_addr at higha
+ li 3, low_addr at higher
+ li 3, low_addr at highera
+ li 3, low_addr at highest
+ li 3, low_addr at highesta
+.Ldelta16:
+.ifdef LE
+ li 3, 0
+ .reloc .Ldelta16, R_PPC64_REL16, reloc_half16
+ li 3, 0
+ .reloc .Ldelta16+4, R_PPC64_REL16_HI, reloc_half16
+ li 3, 0
+ .reloc .Ldelta16+8, R_PPC64_REL16_HA, reloc_half16
+ li 3, 0
+ .reloc .Ldelta16+12, R_PPC64_REL16_LO, reloc_half16
+.else
+ li 3, 0
+ .reloc .Ldelta16+2, R_PPC64_REL16, reloc_half16
+ li 3, 0
+ .reloc .Ldelta16+6, R_PPC64_REL16_HI, reloc_half16
+ li 3, 0
+ .reloc .Ldelta16+10, R_PPC64_REL16_HA, reloc_half16
+ li 3, 0
+ .reloc .Ldelta16+14, R_PPC64_REL16_LO, reloc_half16
+.endif
+.Ltocdetal16:
+.ifdef LE
+ li 3, 0
+ .reloc .Ltocdetal16, R_PPC64_TOC16, .L.str
+ li 3, 0
+ .reloc .Ltocdetal16+4, R_PPC64_TOC16_HI, .L.str
+ li 3, 0
+ .reloc .Ltocdetal16+8, R_PPC64_TOC16_DS, .L.str
+ li 3, 0
+ .reloc .Ltocdetal16+12, R_PPC64_TOC16_HA, .L.str
+ li 3, 0
+ .reloc .Ltocdetal16+16, R_PPC64_TOC16_LO, .L.str
+ li 3, 0
+ .reloc .Ltocdetal16+20, R_PPC64_TOC16_LO_DS, .L.str
+.else
+ li 3, 0
+ .reloc .Ltocdetal16+2, R_PPC64_TOC16, .L.str
+ li 3, 0
+ .reloc .Ltocdetal16+6, R_PPC64_TOC16_HI, .L.str
+ li 3, 0
+ .reloc .Ltocdetal16+10, R_PPC64_TOC16_DS, .L.str
+ li 3, 0
+ .reloc .Ltocdetal16+14, R_PPC64_TOC16_HA, .L.str
+ li 3, 0
+ .reloc .Ltocdetal16+18, R_PPC64_TOC16_LO, .L.str
+ li 3, 0
+ .reloc .Ltocdetal16+22, R_PPC64_TOC16_LO_DS, .L.str
+.endif
+ blr
+.Lfunc_end10:
+ .size reloc_half16, .Lfunc_end10-.Lfunc_begin10
+
.type local_var, at object
.section .bss,"aw", at nobits
.globl local_var
More information about the llvm-commits
mailing list