llvm/llvm/test/ExecutionEngine/JITLink/ppc64/ELF_ppc64_relocations.s

# REQUIRES: system-linux
# RUN: rm -rf %t && mkdir -p %t
# RUN: llvm-mc --triple=powerpc64le-unknown-linux-gnu --filetype=obj -o \
# 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:              --abs pcrel_external_var=0x36668860 \
# RUN:              --abs pcrel_external_tls=0x36668880 \
# RUN:              --check %s %t/elf_reloc.o
# RUN: llvm-mc --triple=powerpc64-unknown-linux-gnu --filetype=obj -o \
# RUN:   %t/elf_reloc.o %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:              --abs pcrel_external_var=0x36668860 \
# RUN:              --abs pcrel_external_tls=0x36668880 \
# 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
main:
  li 3, 0
  blr
  .size main, .-main

# Check R_PPC64_REL16_HA and R_PPC64_REL16_LO
# jitlink-check: decode_operand(test_rel16, 2) & 0xffff = \
# jitlink-check:   (((__TOC__ - test_rel16) + 0x8000) >> 16) & 0xffff
# jitlink-check: decode_operand(test_rel16 + 4, 2) & 0xffff = \
# jitlink-check:   (__TOC__ - test_rel16) & 0xffff
  .global test_rel16
  .p2align 4
  .type test_re16,@function
test_rel16:
  .Ltest_rel16_begin:
  addis 2, 12, .TOC.-.Ltest_rel16_begin@ha
  addi 2, 2, .TOC.-.Ltest_rel16_begin@l
  li 3, 0
  blr
  .size test_rel16, .-test_rel16

# Check R_PPC64_ADDR64, R_PPC64_TOC16_HA and R_PPC64_TOC16_LO
# jitlink-check: *{8}(got_addr(elf_reloc.o, external_data)) = external_data
# jitlink-check: decode_operand(test_tocrel16, 2) & 0xffff = \
# jitlink-check:   (((got_addr(elf_reloc.o, external_data) - __TOC__) + 0x8000) >> 16) & 0xffff
# jitlink-check: decode_operand(test_tocrel16 + 4, 1) & 0xffff = \
# jitlink-check:   (got_addr(elf_reloc.o, external_data) - __TOC__) & 0xffff
  .global test_tocrel16
  .p2align 4
  .type test_tocrel16,@function
test_tocrel16:
  addis 3, 2, .LC0@toc@ha
  ld 3, .LC0@toc@l(3)
  blr
  .size test_tocrel16, .-test_tocrel16

# Check R_PPC64_REL24
# jitlink-check: *{8}(got_addr(elf_reloc.o, external_func)) = external_func
# jitlink-check: decode_operand(test_external_call, 0) = \
# jitlink-check:   (stub_addr(elf_reloc.o, external_func) - test_external_call) >> 2
# Check r2 is saved.
# jitlink-check: *{4}(stub_addr(elf_reloc.o, external_func)) = 0xf8410018
  .global test_external_call
  .p2align 4
  .type test_external_call,@function
test_external_call:
  bl external_func
  nop
  blr
  .size test_external_call, .-test_external_call

# FIXME: Current implementation allows only one plt call stub for a target function,
# so we can't re-use `external_func` as target here.
# Check R_PPC64_REL24_NOTOC
# jitlink-check: *{8}(got_addr(elf_reloc.o, external_func_notoc)) = external_func_notoc
# jitlink-check: decode_operand(test_external_call_notoc, 0) = \
# jitlink-check:   (stub_addr(elf_reloc.o, external_func_notoc) - test_external_call_notoc) >> 2
# jitlink-check: (*{4}(stub_addr(elf_reloc.o, external_func_notoc) + 16)) & 0xffff = \
# jitlink-check:   ((((got_addr(elf_reloc.o, external_func_notoc) - stub_addr(elf_reloc.o, external_func_notoc)) - 8) + 0x8000) >> 16) & 0xffff
# jitlink-check: (*{4}(stub_addr(elf_reloc.o, external_func_notoc) + 20)) & 0xffff = \
# jitlink-check:   ((got_addr(elf_reloc.o, external_func_notoc) - stub_addr(elf_reloc.o, external_func_notoc)) - 8) & 0xffff
  .global test_external_call_notoc
  .p2align 4
  .type test_external_call_notoc,@function
test_external_call_notoc:
  bl external_func_notoc@notoc
  blr
  .size test_external_call_notoc, .-test_external_call_notoc

# Check R_PPC64_PCREL34
# jitlink-check: (section_addr(elf_reloc.o, .rodata.str1.1) - test_pcrel34)[33:0] = \
# jitlink-check:   ((((*{4}(test_pcrel34)) & 0x3ffff) << 16) | ((*{4}(test_pcrel34 + 4)) & 0xffff))[33:0]
  .global test_pcrel34
  .p2align 4
  .type test_pcrel34,@function
test_pcrel34:
  paddi 3, 0, .L.str@PCREL, 1
  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

# Check R_PPC64_GOT_PCREL34
# jitlink-check: (got_addr(elf_reloc.o, pcrel_external_var) - reloc_got_pcrel34)[33:0] = \
# jitlink-check:   ((((*{4}(reloc_got_pcrel34)) & 0x3ffff) << 16) | ((*{4}(reloc_got_pcrel34 + 4)) & 0xffff))[33:0]
  .global reloc_got_pcrel34
  .p2align 4
  .type reloc_got_pcrel34,@function
reloc_got_pcrel34:
  pld 3,pcrel_external_var@got@pcrel(0),1
.Lpcrel0:
  .reloc .Lpcrel0-8,R_PPC64_PCREL_OPT,.-(.Lpcrel0-8)
  blr
  .size reloc_got_pcrel34,.-reloc_got_pcrel34

  .global reloc_tlsgd_pcrel34
  .p2align 4
  .type reloc_tlsgd_pcrel34,@function
reloc_tlsgd_pcrel34:
  mflr 0
  std 0, 16(1)
  stdu 1, -32(1)
  paddi 3, 0, pcrel_external_tls@got@tlsgd@pcrel, 1
  bl __tls_get_addr@notoc(a@tlsgd)
  lwa 3, 0(3)
  addi 1, 1, 32
  ld 0, 16(1)
  mtlr 0
  blr
  .size reloc_tlsgd_pcrel34,.-reloc_tlsgd_pcrel34

  .type	.L.str,@object
	.section	.rodata.str1.1,"aMS",@progbits,1
.L.str:
	.asciz	"Hey!"
	.size	.L.str, 5

 .section .toc,"aw",@progbits
.LC0:
  .tc external_data[TC],external_data