[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