1// REQUIRES: ppc
2// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
3// RUN: ld.lld  %t.o -o %t
4// RUN: llvm-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
5// RUN: llvm-objdump -d %t | FileCheck --check-prefix=Dis %s
6
7	.text
8	.abiversion 2
9	.globl	test_local_exec                    # -- Begin function test_local_exec
10	.p2align	4
11	.type	test_local_exec,@function
12test_local_exec:                                   # @test_local_exec
13.Lfunc_begin0:
14# %bb.0:                                # %entry
15	li 3, 0
16	stw 3, -12(1)
17	addis 3, 13, a@tprel@ha
18	addi 3, 3, a@tprel@l
19	ld 3, 0(3)
20	mr 4, 3
21	extsw 3, 4
22	blr
23	.long	0
24	.quad	0
25.Lfunc_end0:
26	.size	test_local_exec, .Lfunc_end0-.Lfunc_begin0
27                                        # -- End function
28test_tprel:
29.Lfunc_gep1:
30  addis 2, 12, .TOC.-.Lfunc_gep1@ha
31  addi 2, 2, .TOC.-.Lfunc_gep1@l
32.Lfunc_lep1:
33  .localentry test_tprel, .Lfunc_lep1-.Lfunc_gep1
34  addi 3, 13, b@tprel
35  blr
36
37
38test_hi:
39.Lfunc_gep2:
40  addis 2, 12, .TOC.-.Lfunc_gep2@ha
41  addi  2, 2,  .TOC.-.Lfunc_gep2@l
42.Lfunc_lep2:
43  .localentry test_hi, .Lfunc_lep2-.Lfunc_gep2
44  addis 3, 13, b@tprel@h
45  blr
46
47test_ds:
48.Lfunc_gep3:
49  addis 2, 12, .TOC.-.Lfunc_gep3@ha
50  addi 2, 2, .TOC.-.Lfunc_gep3@l
51.Lfunc_lep3:
52  .localentry test_ds, .Lfunc_lep3-.Lfunc_gep3
53  ld 3, b@tprel, 13
54  blr
55
56test_lo_ds:
57.Lfunc_gep4:
58  addis 2, 12, .TOC.-.Lfunc_gep4@ha
59  addi 2, 2, .TOC.-.Lfunc_gep4@l
60.Lfunc_lep4:
61  .localentry test_lo_ds, .Lfunc_lep4-.Lfunc_gep4
62  ld 3, b@tprel@l, 13
63  blr
64
65test_highest_a:
66.Lfunc_gep5:
67  addis 2, 12, .TOC.-.Lfunc_gep5@ha
68  addi  2, 2,  .TOC.-.Lfunc_gep5@l
69.Lfunc_lep5:
70  .localentry test_highest_a, .Lfunc_lep5-.Lfunc_gep5
71  lis 4, b@tprel@highesta
72  ori 4, 4, b@tprel@highera
73  lis 5, b@tprel@ha
74  addi 5, 5, b@tprel@l
75  sldi 4, 4, 32
76  or   4, 4, 5
77  add  3, 13, 4
78  blr
79
80test_highest:
81.Lfunc_gep6:
82  addis 2, 12, .TOC.-.Lfunc_gep6@ha
83  addi  2, 2,  .TOC.-.Lfunc_gep6@l
84.Lfunc_lep6:
85  .localentry test_highest, .Lfunc_lep6-.Lfunc_gep6
86  lis 4, b@tprel@highest
87  ori 4, 4, b@tprel@higher
88  sldi 4, 4, 32
89  oris  4, 4, b@tprel@h
90  ori   4, 4, b@tprel@l
91  add  3, 13, 4
92  blr
93
94	.type	a,@object               # @a
95	.type	b,@object               # @b
96	.section	.tdata,"awT",@progbits
97	.p2align	3
98a:
99	.quad	55                      # 0x37
100	.size	a, 8
101
102b:
103	.quad	55                      # 0x37
104	.size	b, 8
105
106// Verify that the input has every initial-exec tls relocation type.
107// InputRelocs: Relocation section '.rela.text'
108// InputRelocs: R_PPC64_TPREL16_HA {{0+}} a + 0
109// InputRelocs: R_PPC64_TPREL16_LO {{0+}} a + 0
110// InputRelocs: R_PPC64_TPREL16 {{0+8}} b + 0
111// InputRelocs: R_PPC64_TPREL16_HI {{0+8}} b + 0
112// InputRelocs: R_PPC64_TPREL16_DS {{0+8}} b + 0
113// InputRelocs: R_PPC64_TPREL16_LO_DS {{0+8}} b + 0
114// InputRelocs: R_PPC64_TPREL16_HIGHESTA {{0+8}} b + 0
115// InputRelocs: R_PPC64_TPREL16_HIGHERA {{0+8}} b + 0
116// InputRelocs: R_PPC64_TPREL16_HIGHEST {{0+8}} b + 0
117// InputRelocs: R_PPC64_TPREL16_HIGHER {{0+8}} b + 0
118
119// The start of the TLS storage area is 0x7000 bytes before the thread pointer (r13).
120// We are building the address of the first TLS variable, relative to the thread pointer.
121// #ha(a@tprel) --> (0 - 0x7000 + 0x8000) >> 16 = 0
122// #lo(a@tprel)) --> (0 - 0x7000) &  0xFFFF =  -0x7000 = -28672
123// Dis: <test_local_exec>:
124// Dis: addis 3, 13, 0
125// Dis: addi 3, 3, -28672
126
127// We are building the offset for the second TLS variable
128// Offset within tls storage - 0x7000
129// b@tprel = 8 - 0x7000 = 28664
130// Dis: <test_tprel>:
131// Dis: addi 3, 13, -28664
132
133// #hi(b@tprel) --> (8 - 0x7000) >> 16 = -1
134// Dis: <test_hi>:
135// Dis: addis 3, 13, -1
136
137// b@tprel = 8 - 0x7000 = -28664
138// Dis: <test_ds>:
139// Dis: ld 3, -28664(13)
140
141// #lo(b@tprel) --> (8 - 0x7000) & 0xFFFF = -28664
142// Dis: <test_lo_ds>:
143// Dis: ld 3, -28664(13)
144
145// #highesta(b@tprel) --> ((0x8 - 0x7000 + 0x8000) >> 48) & 0xFFFF = 0
146// #highera(b@tprel)  --> ((0x8 - 0x7000 + 0x8000) >> 32) & 0xFFFF = 0
147// #ha(k@dtprel)       --> ((0x8 - 0x7000 + 0x8000) >> 16) & 0xFFFF = 0
148// #lo(k@dtprel)       --> ((0x8 - 0x7000) & 0xFFFF = -28664
149// Dis: <test_highest_a>:
150// Dis: lis 4, 0
151// Dis: ori 4, 4, 0
152// Dis: lis 5, 0
153// Dis: addi 5, 5, -28664
154
155// #highest(b@tprel) --> ((0x8 - 0x7000) >> 48) & 0xFFFF = 0xFFFF = -1
156// #higher(b@tprel)  --> ((0x8 - 0x7000) >> 32) & 0xFFFF = 0xFFFF = 65535
157// #hi(k@dtprel)      --> ((0x8 - 0x7000) >> 16) & 0xFFFF = 0xFFFF = 65535
158// #lo(k@dtprel)      --> ((0x8 - 0x7000) & 0xFFFF = 33796
159// Dis: <test_highest>:
160// Dis: lis 4, -1
161// Dis: ori 4, 4, 65535
162// Dis: oris 4, 4, 65535
163// Dis: ori 4, 4, 36872
164