diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/ppc64.h b/llvm/include/llvm/ExecutionEngine/JITLink/ppc64.h --- a/llvm/include/llvm/ExecutionEngine/JITLink/ppc64.h +++ b/llvm/include/llvm/ExecutionEngine/JITLink/ppc64.h @@ -23,16 +23,33 @@ 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 @@ /// 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 @@ support::endian::write64(Loc, Inst); } +template +inline Error relocateHalf16(char *FixupPtr, int64_t Value, Edge::Kind K) { + switch (K) { + case Delta16: + case Pointer16: + case TOCDelta16: + support::endian::write16(FixupPtr, Value); + break; + case Pointer16DS: + case TOCDelta16DS: + support::endian::write16(FixupPtr, Value & ~3); + break; + case Delta16HA: + case Pointer16HA: + case TOCDelta16HA: + support::endian::write16(FixupPtr, ha(Value)); + break; + case Delta16HI: + case Pointer16HI: + case TOCDelta16HI: + support::endian::write16(FixupPtr, hi(Value)); + break; + case Pointer16HIGH: + support::endian::write16(FixupPtr, high(Value)); + break; + case Pointer16HIGHA: + support::endian::write16(FixupPtr, higha(Value)); + break; + case Pointer16HIGHER: + support::endian::write16(FixupPtr, higher(Value)); + break; + case Pointer16HIGHERA: + support::endian::write16(FixupPtr, highera(Value)); + break; + case Pointer16HIGHEST: + support::endian::write16(FixupPtr, highest(Value)); + break; + case Pointer16HIGHESTA: + support::endian::write16(FixupPtr, highesta(Value)); + break; + case Delta16LO: + case Pointer16LO: + case TOCDelta16LO: + support::endian::write16(FixupPtr, lo(Value)); + break; + case Pointer16LODS: + case TOCDelta16LODS: + support::endian::write16(FixupPtr, lo(Value) & ~3); + break; + default: + return make_error( + StringRef(getEdgeKindName(K)) + + " relocation does not write at half16 field"); + } + return Error::success(); +} + /// Apply fixup expression for edge to block content. template inline Error applyFixup(LinkGraph &G, Block &B, const Edge &E, @@ -282,41 +366,60 @@ support::endian::write64(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(FixupPtr, lo16(Value)); - else - support::endian::write16(FixupPtr, ha16(Value)); - break; + return relocateHalf16(FixupPtr, Value, K); } - case TOCDelta16HA: - case TOCDelta16LO: { - int64_t Value = S + A - TOCBase; + case TOC: + support::endian::write64(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(FixupPtr, lo16(Value)); - else - support::endian::write16(FixupPtr, ha16(Value)); + return relocateHalf16(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(FixupPtr); + support::endian::write32(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(FixupPtr, lo16(Value) & ~3); - else - support::endian::write16(FixupPtr, Value & ~3); - break; + return relocateHalf16(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 --- a/llvm/lib/ExecutionEngine/JITLink/ELF_ppc64.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/ELF_ppc64.cpp @@ -266,9 +266,57 @@ 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 @@ 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 --- a/llvm/lib/ExecutionEngine/JITLink/ppc64.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/ppc64.cpp @@ -64,6 +64,32 @@ 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 @@ 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 --- 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,@function @@ -100,6 +108,138 @@ 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,@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,@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,@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@ha + li 3, external_addr32_data@high + li 3, external_addr32_data@higha + li 3, external_addr32_data@higher + li 3, external_addr32_data@highera + li 3, external_addr32_data@highest + li 3, external_addr32_data@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,@function +reloc_rel16: + li 3, .TOC.-reloc_rel16 + li 3, .TOC.-reloc_rel16@h + blr + .size reloc_rel16, .-reloc_rel16 + .type .L.str,@object .section .rodata.str1.1,"aMS",@progbits,1 .L.str: diff --git a/llvm/test/ExecutionEngine/JITLink/ppc64/ppc64-relocs.s b/llvm/test/ExecutionEngine/JITLink/ppc64/ppc64-relocs.s --- 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 @@ .Lfunc_end8: .size foobar, .Lfunc_end8-.Lfunc_begin8 + .global reloc_addr14 + .p2align 4 + .type reloc_addr14,@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,@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@ha + li 3, low_addr@high + li 3, low_addr@higha + li 3, low_addr@higher + li 3, low_addr@highera + li 3, low_addr@highest + li 3, low_addr@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,@object .section .bss,"aw",@nobits .globl local_var