Implement target independent TLS compatible with glibc's emutls.c.
[oota-llvm.git] / test / CodeGen / X86 / emutls.ll
1 ; RUN: llc < %s -emulated-tls -march=x86 -mtriple=i386-linux-gnu | FileCheck -check-prefix=X32 %s
2 ; RUN: llc < %s -emulated-tls -march=x86-64 -mtriple=x86_64-linux-gnu | FileCheck -check-prefix=X64 %s
3 ; RUN: llc < %s -emulated-tls -march=x86 -mtriple=x86-linux-android | FileCheck -check-prefix=X32 %s
4 ; RUN: llc < %s -emulated-tls -march=x86-64 -mtriple=x86_64-linux-android | FileCheck -check-prefix=X64 %s
5
6 ; Copied from tls.ll; emulated TLS model is not implemented
7 ; for *-pc-win32 and *-pc-winows targets yet.
8
9 ; Use my_emutls_get_address like __emutls_get_address.
10 @my_emutls_v_xyz = external global i8*, align 4
11 declare i8* @my_emutls_get_address(i8*)
12
13 define i32 @my_get_xyz() {
14 ; X32-LABEL: my_get_xyz:
15 ; X32:         movl $my_emutls_v_xyz, (%esp)
16 ; X32-NEXT:    calll my_emutls_get_address
17 ; X32-NEXT:    movl (%eax), %eax
18 ; X32-NEXT:    addl $12, %esp
19 ; X32-NEXT:    retl
20 ; X64-LABEL: my_get_xyz:
21 ; X64:         movl $my_emutls_v_xyz, %edi
22 ; X64-NEXT:    callq my_emutls_get_address
23 ; X64-NEXT:    movl (%rax), %eax
24 ; X64-NEXT:    popq %rdx
25 ; X64-NEXT:    retq
26
27 entry:
28   %call = call i8* @my_emutls_get_address(i8* bitcast (i8** @my_emutls_v_xyz to i8*))
29   %0 = bitcast i8* %call to i32*
30   %1 = load i32, i32* %0, align 4
31   ret i32 %1
32 }
33
34 @i1 = thread_local global i32 15
35 @i2 = external thread_local global i32
36 @i3 = internal thread_local global i32 15
37 @i4 = hidden thread_local global i32 15
38 @i5 = external hidden thread_local global i32
39 @s1 = thread_local global i16 15
40 @b1 = thread_local global i8 0
41
42 define i32 @f1() {
43 ; X32-LABEL: f1:
44 ; X32:         movl $__emutls_v.i1, (%esp)
45 ; X32-NEXT:    calll __emutls_get_address
46 ; X32-NEXT:    movl (%eax), %eax
47 ; X32-NEXT:    addl $12, %esp
48 ; X32-NEXT:    retl
49 ; X64-LABEL: f1:
50 ; X64:         movl $__emutls_v.i1, %edi
51 ; X64-NEXT:    callq __emutls_get_address
52 ; X64-NEXT:    movl (%rax), %eax
53 ; X64-NEXT:    popq %rdx
54 ; X64-NEXT:    retq
55
56 entry:
57   %tmp1 = load i32, i32* @i1
58   ret i32 %tmp1
59 }
60
61 define i32* @f2() {
62 ; X32-LABEL: f2:
63 ; X32:         movl $__emutls_v.i1, (%esp)
64 ; X32-NEXT:    calll __emutls_get_address
65 ; X32-NEXT:    addl $12, %esp
66 ; X32-NEXT:    retl
67 ; X64-LABEL: f2:
68 ; X64:         movl $__emutls_v.i1, %edi
69 ; X64-NEXT:    callq __emutls_get_address
70 ; X64-NEXT:    popq %rdx
71 ; X64-NEXT:    retq
72
73 entry:
74   ret i32* @i1
75 }
76
77 define i32 @f3() nounwind {
78 ; X32-LABEL: f3:
79 ; X32:         movl $__emutls_v.i2, (%esp)
80 ; X32-NEXT:    calll __emutls_get_address
81 ; X32-NEXT:    movl (%eax), %eax
82 ; X32-NEXT:    addl $12, %esp
83 ; X32-NEXT:    retl
84
85 entry:
86   %tmp1 = load i32, i32* @i2
87   ret i32 %tmp1
88 }
89
90 define i32* @f4() {
91 ; X32-LABEL: f4:
92 ; X32:         movl $__emutls_v.i2, (%esp)
93 ; X32-NEXT:    calll __emutls_get_address
94 ; X32-NEXT:    addl $12, %esp
95 ; X32-NEXT:    retl
96
97 entry:
98   ret i32* @i2
99 }
100
101 define i32 @f5() nounwind {
102 ; X32-LABEL: f5:
103 ; X32:         movl $__emutls_v.i3, (%esp)
104 ; X32-NEXT:    calll __emutls_get_address
105 ; X32-NEXT:    movl (%eax), %eax
106 ; X32-NEXT:    addl $12, %esp
107 ; X32-NEXT:    retl
108
109 entry:
110   %tmp1 = load i32, i32* @i3
111   ret i32 %tmp1
112 }
113
114 define i32* @f6() {
115 ; X32-LABEL: f6:
116 ; X32:         movl $__emutls_v.i3, (%esp)
117 ; X32-NEXT:    calll __emutls_get_address
118 ; X32-NEXT:    addl $12, %esp
119 ; X32-NEXT:    retl
120
121 entry:
122   ret i32* @i3
123 }
124
125 define i32 @f7() {
126 ; X32-LABEL: f7:
127 ; X32:         movl $__emutls_v.i4, (%esp)
128 ; X32-NEXT:    calll __emutls_get_address
129 ; X32-NEXT:    movl (%eax), %eax
130 ; X32-NEXT:    addl $12, %esp
131 ; X32-NEXT:    retl
132
133 entry:
134   %tmp1 = load i32, i32* @i4
135   ret i32 %tmp1
136 }
137
138 define i32* @f8() {
139 ; X32-LABEL: f8:
140 ; X32:         movl $__emutls_v.i4, (%esp)
141 ; X32-NEXT:    calll __emutls_get_address
142 ; X32-NEXT:    addl $12, %esp
143 ; X32-NEXT:    retl
144
145 entry:
146   ret i32* @i4
147 }
148
149 define i32 @f9() {
150 ; X32-LABEL: f9:
151 ; X32:         movl $__emutls_v.i5, (%esp)
152 ; X32-NEXT:    calll __emutls_get_address
153 ; X32-NEXT:    movl (%eax), %eax
154 ; X32-NEXT:    addl $12, %esp
155 ; X32-NEXT:    retl
156
157 entry:
158   %tmp1 = load i32, i32* @i5
159   ret i32 %tmp1
160 }
161
162 define i32* @f10() {
163 ; X32-LABEL: f10:
164 ; X32:         movl $__emutls_v.i5, (%esp)
165 ; X32-NEXT:    calll __emutls_get_address
166 ; X32-NEXT:    addl $12, %esp
167 ; X32-NEXT:    retl
168
169 entry:
170   ret i32* @i5
171 }
172
173 define i16 @f11() {
174 ; X32-LABEL: f11:
175 ; X32:         movl $__emutls_v.s1, (%esp)
176 ; X32-NEXT:    calll __emutls_get_address
177 ; X32-NEXT:    movzwl (%eax), %eax
178 ; X32-NEXT:    addl $12, %esp
179 ; X32-NEXT:    retl
180
181 entry:
182   %tmp1 = load i16, i16* @s1
183   ret i16 %tmp1
184 }
185
186 define i32 @f12() {
187 ; X32-LABEL: f12:
188 ; X32:         movl $__emutls_v.s1, (%esp)
189 ; X32-NEXT:    calll __emutls_get_address
190 ; X32-NEXT:    movswl (%eax), %eax
191 ; X32-NEXT:    addl $12, %esp
192 ; X32-NEXT:    retl
193
194 entry:
195   %tmp1 = load i16, i16* @s1
196   %tmp2 = sext i16 %tmp1 to i32
197   ret i32 %tmp2
198 }
199
200 define i8 @f13() {
201 ; X32-LABEL: f13:
202 ; X32:         movl $__emutls_v.b1, (%esp)
203 ; X32-NEXT:    calll __emutls_get_address
204 ; X32-NEXT:    movb (%eax), %al
205 ; X32-NEXT:    addl $12, %esp
206 ; X32-NEXT:    retl
207
208 entry:
209   %tmp1 = load i8, i8* @b1
210   ret i8 %tmp1
211 }
212
213 define i32 @f14() {
214 ; X32-LABEL: f14:
215 ; X32:         movl $__emutls_v.b1, (%esp)
216 ; X32-NEXT:    calll __emutls_get_address
217 ; X32-NEXT:    movsbl (%eax), %eax
218 ; X32-NEXT:    addl $12, %esp
219 ; X32-NEXT:    retl
220
221 entry:
222   %tmp1 = load i8, i8* @b1
223   %tmp2 = sext i8 %tmp1 to i32
224   ret i32 %tmp2
225 }
226
227 ;;;;;;;;;;;;;; 32-bit __emutls_v. and __emutls_t.
228
229 ; X32       .section .data.rel.local,
230 ; X32-LABEL: __emutls_v.i1:
231 ; X32-NEXT: .long 4
232 ; X32-NEXT: .long 4
233 ; X32-NEXT: .long 0
234 ; X32-NEXT: .long __emutls_t.i1
235
236 ; X32       .section .rodata,
237 ; X32-LABEL: __emutls_t.i1:
238 ; X32-NEXT: .long 15
239
240 ; X32-NOT:   __emutls_v.i2
241
242 ; X32       .section .data.rel.local,
243 ; X32-LABEL: __emutls_v.i3:
244 ; X32-NEXT: .long 4
245 ; X32-NEXT: .long 4
246 ; X32-NEXT: .long 0
247 ; X32-NEXT: .long __emutls_t.i3
248
249 ; X32       .section .rodata,
250 ; X32-LABEL: __emutls_t.i3:
251 ; X32-NEXT: .long 15
252
253 ; X32       .section .data.rel.local,
254 ; X32-LABEL: __emutls_v.i4:
255 ; X32-NEXT: .long 4
256 ; X32-NEXT: .long 4
257 ; X32-NEXT: .long 0
258 ; X32-NEXT: .long __emutls_t.i4
259
260 ; X32       .section .rodata,
261 ; X32-LABEL: __emutls_t.i4:
262 ; X32-NEXT: .long 15
263
264 ; X32-NOT:   __emutls_v.i5:
265 ; X32       .hidden __emutls_v.i5
266 ; X32-NOT:   __emutls_v.i5:
267
268 ; X32 .section .data.rel.local,
269 ; X32-LABEL: __emutls_v.s1:
270 ; X32-NEXT: .long 2
271 ; X32-NEXT: .long 2
272 ; X32-NEXT: .long 0
273 ; X32-NEXT: .long __emutls_t.s1
274
275 ; X32 .section .rodata,
276 ; X32-LABEL: __emutls_t.s1:
277 ; X32-NEXT: .short 15
278
279 ; X32 .section .data.rel.local,
280 ; X32-LABEL: __emutls_v.b1:
281 ; X32-NEXT: .long 1
282 ; X32-NEXT: .long 1
283 ; X32-NEXT: .long 0
284 ; X32-NEXT: .long 0
285
286 ; X32-NOT:   __emutls_t.b1
287
288 ;;;;;;;;;;;;;; 64-bit __emutls_v. and __emutls_t.
289
290 ; X64       .section .data.rel.local,
291 ; X64-LABEL: __emutls_v.i1:
292 ; X64-NEXT: .quad 4
293 ; X64-NEXT: .quad 4
294 ; X64-NEXT: .quad 0
295 ; X64-NEXT: .quad __emutls_t.i1
296
297 ; X64       .section .rodata,
298 ; X64-LABEL: __emutls_t.i1:
299 ; X64-NEXT: .long 15
300
301 ; X64-NOT:   __emutls_v.i2
302
303 ; X64       .section .data.rel.local,
304 ; X64-LABEL: __emutls_v.i3:
305 ; X64-NEXT: .quad 4
306 ; X64-NEXT: .quad 4
307 ; X64-NEXT: .quad 0
308 ; X64-NEXT: .quad __emutls_t.i3
309
310 ; X64       .section .rodata,
311 ; X64-LABEL: __emutls_t.i3:
312 ; X64-NEXT: .long 15
313
314 ; X64       .section .data.rel.local,
315 ; X64-LABEL: __emutls_v.i4:
316 ; X64-NEXT: .quad 4
317 ; X64-NEXT: .quad 4
318 ; X64-NEXT: .quad 0
319 ; X64-NEXT: .quad __emutls_t.i4
320
321 ; X64       .section .rodata,
322 ; X64-LABEL: __emutls_t.i4:
323 ; X64-NEXT: .long 15
324
325 ; X64-NOT:   __emutls_v.i5:
326 ; X64       .hidden __emutls_v.i5
327 ; X64-NOT:   __emutls_v.i5:
328
329 ; X64       .section .data.rel.local,
330 ; X64-LABEL: __emutls_v.s1:
331 ; X64-NEXT: .quad 2
332 ; X64-NEXT: .quad 2
333 ; X64-NEXT: .quad 0
334 ; X64-NEXT: .quad __emutls_t.s1
335
336 ; X64       .section .rodata,
337 ; X64-LABEL: __emutls_t.s1:
338 ; X64-NEXT: .short 15
339
340 ; X64       .section .data.rel.local,
341 ; X64-LABEL: __emutls_v.b1:
342 ; X64-NEXT: .quad 1
343 ; X64-NEXT: .quad 1
344 ; X64-NEXT: .quad 0
345 ; X64-NEXT: .quad 0
346
347 ; X64-NOT:  __emutls_t.b1