|  | // REQUIRES: ppc | 
|  | // RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o | 
|  | // RUN: ld.lld  %t.o -o %t | 
|  | // RUN: llvm-readelf -relocations --wide %t.o | FileCheck --check-prefix=InputRelocs %s | 
|  | // RUN: llvm-objdump -D %t | FileCheck --check-prefix=Dis %s | 
|  |  | 
|  | .text | 
|  | .abiversion 2 | 
|  | .globl	test_local_exec                    # -- Begin function test_local_exec | 
|  | .p2align	4 | 
|  | .type	test_local_exec,@function | 
|  | test_local_exec:                                   # @test_local_exec | 
|  | .Lfunc_begin0: | 
|  | # %bb.0:                                # %entry | 
|  | li 3, 0 | 
|  | stw 3, -12(1) | 
|  | addis 3, 13, a@tprel@ha | 
|  | addi 3, 3, a@tprel@l | 
|  | ld 3, 0(3) | 
|  | mr 4, 3 | 
|  | extsw 3, 4 | 
|  | blr | 
|  | .long	0 | 
|  | .quad	0 | 
|  | .Lfunc_end0: | 
|  | .size	test_local_exec, .Lfunc_end0-.Lfunc_begin0 | 
|  | # -- End function | 
|  | test_tprel: | 
|  | .Lfunc_gep1: | 
|  | addis 2, 12, .TOC.-.Lfunc_gep1@ha | 
|  | addi 2, 2, .TOC.-.Lfunc_gep1@l | 
|  | .Lfunc_lep1: | 
|  | .localentry test_tprel, .Lfunc_lep1-.Lfunc_gep1 | 
|  | addi 3, 13, b@tprel | 
|  | blr | 
|  |  | 
|  |  | 
|  | test_hi: | 
|  | .Lfunc_gep2: | 
|  | addis 2, 12, .TOC.-.Lfunc_gep2@ha | 
|  | addi  2, 2,  .TOC.-.Lfunc_gep2@l | 
|  | .Lfunc_lep2: | 
|  | .localentry test_hi, .Lfunc_lep2-.Lfunc_gep2 | 
|  | addis 3, 13, b@tprel@h | 
|  | blr | 
|  |  | 
|  | test_ds: | 
|  | .Lfunc_gep3: | 
|  | addis 2, 12, .TOC.-.Lfunc_gep3@ha | 
|  | addi 2, 2, .TOC.-.Lfunc_gep3@l | 
|  | .Lfunc_lep3: | 
|  | .localentry test_ds, .Lfunc_lep3-.Lfunc_gep3 | 
|  | ld 3, b@tprel, 13 | 
|  | blr | 
|  |  | 
|  | test_lo_ds: | 
|  | .Lfunc_gep4: | 
|  | addis 2, 12, .TOC.-.Lfunc_gep4@ha | 
|  | addi 2, 2, .TOC.-.Lfunc_gep4@l | 
|  | .Lfunc_lep4: | 
|  | .localentry test_lo_ds, .Lfunc_lep4-.Lfunc_gep4 | 
|  | ld 3, b@tprel@l, 13 | 
|  | blr | 
|  |  | 
|  | test_highest_a: | 
|  | .Lfunc_gep5: | 
|  | addis 2, 12, .TOC.-.Lfunc_gep5@ha | 
|  | addi  2, 2,  .TOC.-.Lfunc_gep5@l | 
|  | .Lfunc_lep5: | 
|  | .localentry test_highest_a, .Lfunc_lep5-.Lfunc_gep5 | 
|  | lis 4, b@tprel@highesta | 
|  | ori 4, 4, b@tprel@highera | 
|  | lis 5, b@tprel@ha | 
|  | addi 5, 5, b@tprel@l | 
|  | sldi 4, 4, 32 | 
|  | or   4, 4, 5 | 
|  | add  3, 13, 4 | 
|  | blr | 
|  |  | 
|  | test_highest: | 
|  | .Lfunc_gep6: | 
|  | addis 2, 12, .TOC.-.Lfunc_gep6@ha | 
|  | addi  2, 2,  .TOC.-.Lfunc_gep6@l | 
|  | .Lfunc_lep6: | 
|  | .localentry test_highest, .Lfunc_lep6-.Lfunc_gep6 | 
|  | lis 4, b@tprel@highest | 
|  | ori 4, 4, b@tprel@higher | 
|  | sldi 4, 4, 32 | 
|  | oris  4, 4, b@tprel@h | 
|  | ori   4, 4, b@tprel@l | 
|  | add  3, 13, 4 | 
|  | blr | 
|  |  | 
|  | .type	a,@object               # @a | 
|  | .type	b,@object               # @b | 
|  | .section	.tdata,"awT",@progbits | 
|  | .p2align	3 | 
|  | a: | 
|  | .quad	55                      # 0x37 | 
|  | .size	a, 8 | 
|  |  | 
|  | b: | 
|  | .quad	55                      # 0x37 | 
|  | .size	b, 8 | 
|  |  | 
|  | // Verify that the input has every initial-exec tls relocation type. | 
|  | // InputRelocs: Relocation section '.rela.text' | 
|  | // InputRelocs: R_PPC64_TPREL16_HA {{0+}} a + 0 | 
|  | // InputRelocs: R_PPC64_TPREL16_LO {{0+}} a + 0 | 
|  | // InputRelocs: R_PPC64_TPREL16 {{0+8}} b + 0 | 
|  | // InputRelocs: R_PPC64_TPREL16_HI {{0+8}} b + 0 | 
|  | // InputRelocs: R_PPC64_TPREL16_DS {{0+8}} b + 0 | 
|  | // InputRelocs: R_PPC64_TPREL16_LO_DS {{0+8}} b + 0 | 
|  | // InputRelocs: R_PPC64_TPREL16_HIGHESTA {{0+8}} b + 0 | 
|  | // InputRelocs: R_PPC64_TPREL16_HIGHERA {{0+8}} b + 0 | 
|  | // InputRelocs: R_PPC64_TPREL16_HIGHEST {{0+8}} b + 0 | 
|  | // InputRelocs: R_PPC64_TPREL16_HIGHER {{0+8}} b + 0 | 
|  |  | 
|  | // The start of the TLS storage area is 0x7000 bytes before the thread pointer (r13). | 
|  | // We are building the address of the first TLS variable, relative to the thread pointer. | 
|  | // #ha(a@tprel) --> (0 - 0x7000 + 0x8000) >> 16 = 0 | 
|  | // #lo(a@tprel)) --> (0 - 0x7000) &  0xFFFF =  -0x7000 = -28672 | 
|  | // Dis: test_local_exec: | 
|  | // Dis: addis 3, 13, 0 | 
|  | // Dis: addi 3, 3, -28672 | 
|  |  | 
|  | // We are building the offset for the second TLS variable | 
|  | // Offset within tls storage - 0x7000 | 
|  | // b@tprel = 8 - 0x7000 = 28664 | 
|  | // Dis: test_tprel: | 
|  | // Dis: addi 3, 13, -28664 | 
|  |  | 
|  | // #hi(b@tprel) --> (8 - 0x7000) >> 16 = -1 | 
|  | // Dis: test_hi: | 
|  | // Dis: addis 3, 13, -1 | 
|  |  | 
|  | // b@tprel = 8 - 0x7000 = -28664 | 
|  | // Dis: test_ds: | 
|  | // Dis: ld 3, -28664(13) | 
|  |  | 
|  | // #lo(b@tprel) --> (8 - 0x7000) & 0xFFFF = -28664 | 
|  | // Dis: test_lo_ds: | 
|  | // Dis: ld 3, -28664(13) | 
|  |  | 
|  | // #highesta(b@tprel) --> ((0x8 - 0x7000 + 0x8000) >> 48) & 0xFFFF = 0 | 
|  | // #highera(b@tprel)  --> ((0x8 - 0x7000 + 0x8000) >> 32) & 0xFFFF = 0 | 
|  | // #ha(k@dtprel)       --> ((0x8 - 0x7000 + 0x8000) >> 16) & 0xFFFF = 0 | 
|  | // #lo(k@dtprel)       --> ((0x8 - 0x7000) & 0xFFFF = -28664 | 
|  | // Dis: test_highest_a: | 
|  | // Dis: lis 4, 0 | 
|  | // Dis: ori 4, 4, 0 | 
|  | // Dis: lis 5, 0 | 
|  | // Dis: addi 5, 5, -28664 | 
|  |  | 
|  | // #highest(b@tprel) --> ((0x8 - 0x7000) >> 48) & 0xFFFF = 0xFFFF = -1 | 
|  | // #higher(b@tprel)  --> ((0x8 - 0x7000) >> 32) & 0xFFFF = 0xFFFF = 65535 | 
|  | // #hi(k@dtprel)      --> ((0x8 - 0x7000) >> 16) & 0xFFFF = 0xFFFF = 65535 | 
|  | // #lo(k@dtprel)      --> ((0x8 - 0x7000) & 0xFFFF = 33796 | 
|  | // Dis: test_highest: | 
|  | // Dis: lis 4, -1 | 
|  | // Dis: ori 4, 4, 65535 | 
|  | // Dis: oris 4, 4, 65535 | 
|  | // Dis: ori 4, 4, 36872 |