]>
Commit | Line | Data |
---|---|---|
2cef4257 UD |
1 | /* Macros to support TLS testing in times of missing compiler support. */ |
2 | ||
3 | #define COMMON_INT_DEF(x) \ | |
4 | asm (".tls_common " #x ",4,4") | |
7331ca4d UD |
5 | /* XXX Until we get compiler support we don't need declarations. */ |
6 | #define COMMON_INT_DECL(x) | |
2cef4257 UD |
7 | |
8 | /* XXX This definition will probably be machine specific, too. */ | |
9 | #define VAR_INT_DEF(x) \ | |
10 | asm (".section .tdata\n\t" \ | |
11 | ".globl " #x "\n" \ | |
adc12574 | 12 | ".balign 4\n" \ |
2cef4257 | 13 | #x ":\t.long 0\n\t" \ |
7331ca4d | 14 | ".size " #x ",4\n\t" \ |
2cef4257 | 15 | ".previous") |
7331ca4d UD |
16 | /* XXX Until we get compiler support we don't need declarations. */ |
17 | #define VAR_INT_DECL(x) | |
2cef4257 | 18 | |
af81020e | 19 | #include_next <tls-macros.h> |
2cef4257 UD |
20 | |
21 | /* XXX Each architecture must have its own asm for now. */ | |
22 | #ifdef __i386__ | |
23 | # define TLS_LE(x) \ | |
24 | ({ int *__l; \ | |
25 | asm ("movl %%gs:0,%0\n\t" \ | |
26 | "subl $" #x "@tpoff,%0" \ | |
27 | : "=r" (__l)); \ | |
28 | __l; }) | |
29 | ||
7331ca4d UD |
30 | # ifdef PIC |
31 | # define TLS_IE(x) \ | |
32 | ({ int *__l; \ | |
33 | asm ("movl %%gs:0,%0\n\t" \ | |
34 | "subl " #x "@gottpoff(%%ebx),%0" \ | |
35 | : "=r" (__l)); \ | |
36 | __l; }) | |
37 | # else | |
38 | # define TLS_IE(x) \ | |
2cef4257 UD |
39 | ({ int *__l, __b; \ |
40 | asm ("call 1f\n\t" \ | |
41 | ".subsection 1\n" \ | |
42 | "1:\tmovl (%%esp), %%ebx\n\t" \ | |
43 | "ret\n\t" \ | |
44 | ".previous\n\t" \ | |
45 | "addl $_GLOBAL_OFFSET_TABLE_, %%ebx\n\t" \ | |
46 | "movl %%gs:0,%0\n\t" \ | |
47 | "subl " #x "@gottpoff(%%ebx),%0" \ | |
48 | : "=r" (__l), "=&b" (__b)); \ | |
49 | __l; }) | |
7331ca4d | 50 | # endif |
2cef4257 | 51 | |
7331ca4d UD |
52 | # ifdef PIC |
53 | # define TLS_LD(x) \ | |
aed283dd | 54 | ({ int *__l, __c, __d; \ |
7331ca4d UD |
55 | asm ("leal " #x "@tlsldm(%%ebx),%%eax\n\t" \ |
56 | "call ___tls_get_addr@plt\n\t" \ | |
57 | "leal " #x "@dtpoff(%%eax), %%eax" \ | |
aed283dd | 58 | : "=a" (__l), "=&c" (__c), "=&d" (__d)); \ |
7331ca4d UD |
59 | __l; }) |
60 | # else | |
61 | # define TLS_LD(x) \ | |
aed283dd | 62 | ({ int *__l, __b, __c, __d; \ |
2cef4257 UD |
63 | asm ("call 1f\n\t" \ |
64 | ".subsection 1\n" \ | |
65 | "1:\tmovl (%%esp), %%ebx\n\t" \ | |
66 | "ret\n\t" \ | |
67 | ".previous\n\t" \ | |
68 | "addl $_GLOBAL_OFFSET_TABLE_, %%ebx\n\t" \ | |
69 | "leal " #x "@tlsldm(%%ebx),%%eax\n\t" \ | |
70 | "call ___tls_get_addr@plt\n\t" \ | |
71 | "leal " #x "@dtpoff(%%eax), %%eax" \ | |
aed283dd | 72 | : "=a" (__l), "=&b" (__b), "=&c" (__c), "=&d" (__d)); \ |
2cef4257 | 73 | __l; }) |
7331ca4d | 74 | # endif |
2cef4257 | 75 | |
7331ca4d UD |
76 | # ifdef PIC |
77 | # define TLS_GD(x) \ | |
aed283dd | 78 | ({ int *__l, __c, __d; \ |
7331ca4d UD |
79 | asm ("leal " #x "@tlsgd(%%ebx),%%eax\n\t" \ |
80 | "call ___tls_get_addr@plt\n\t" \ | |
81 | "nop" \ | |
aed283dd | 82 | : "=a" (__l), "=&c" (__c), "=&d" (__d)); \ |
7331ca4d UD |
83 | __l; }) |
84 | # else | |
85 | # define TLS_GD(x) \ | |
aed283dd | 86 | ({ int *__l, __b, __c, __d; \ |
2cef4257 UD |
87 | asm ("call 1f\n\t" \ |
88 | ".subsection 1\n" \ | |
89 | "1:\tmovl (%%esp), %%ebx\n\t" \ | |
90 | "ret\n\t" \ | |
91 | ".previous\n\t" \ | |
92 | "addl $_GLOBAL_OFFSET_TABLE_, %%ebx\n\t" \ | |
93 | "leal " #x "@tlsgd(%%ebx),%%eax\n\t" \ | |
94 | "call ___tls_get_addr@plt\n\t" \ | |
95 | "nop" \ | |
aed283dd | 96 | : "=a" (__l), "=&b" (__b), "=&c" (__c), "=&d" (__d)); \ |
2cef4257 | 97 | __l; }) |
7331ca4d | 98 | # endif |
2cef4257 | 99 | |
160bb409 RM |
100 | #elif defined __x86_64__ |
101 | ||
102 | # define TLS_LE(x) \ | |
103 | ({ int *__l; \ | |
104 | asm ("movq %%fs:0,%0\n\t" \ | |
105 | "leaq " #x "@tpoff(%0), %0" \ | |
106 | : "=r" (__l)); \ | |
107 | __l; }) | |
108 | ||
109 | # define TLS_IE(x) \ | |
110 | ({ int *__l; \ | |
111 | asm ("movq %%fs:0,%0\n\t" \ | |
112 | "addq " #x "@gottpoff(%%rip),%0" \ | |
113 | : "=r" (__l)); \ | |
114 | __l; }) | |
115 | ||
116 | # define TLS_LD(x) \ | |
117 | ({ int *__l, __c, __d; \ | |
118 | asm ("leaq " #x "@tlsld(%%rip),%%rdi\n\t" \ | |
fe27057d | 119 | "call __tls_get_addr@plt\n\t" \ |
160bb409 RM |
120 | "leaq " #x "@dtpoff(%%rax), %%rax" \ |
121 | : "=a" (__l), "=&c" (__c), "=&d" (__d) \ | |
122 | : : "rdi", "rsi", "r8", "r9", "r10", "r11"); \ | |
123 | __l; }) | |
124 | ||
125 | # define TLS_GD(x) \ | |
126 | ({ int *__l, __c, __d; \ | |
cfd8a63a | 127 | asm (".byte 0x66\n\t" \ |
160bb409 | 128 | "leaq " #x "@tlsgd(%%rip),%%rdi\n\t" \ |
cfd8a63a RM |
129 | ".word 0x6666\n\t" \ |
130 | "rex64\n\t" \ | |
fe27057d | 131 | "call __tls_get_addr@plt" \ |
160bb409 RM |
132 | : "=a" (__l), "=&c" (__c), "=&d" (__d) \ |
133 | : : "rdi", "rsi", "r8", "r9", "r10", "r11"); \ | |
134 | __l; }) | |
135 | ||
3632a260 | 136 | #elif defined __sh__ |
160bb409 | 137 | |
3632a260 UD |
138 | # define TLS_LE(x) \ |
139 | ({ int *__l; void *__tp; \ | |
140 | asm ("stc gbr,%1\n\t" \ | |
141 | "mov.l 1f,%0\n\t" \ | |
142 | "bra 2f\n\t" \ | |
143 | " add %1,%0\n\t" \ | |
144 | ".align 2\n\t" \ | |
145 | "1: .long " #x "@tpoff\n\t" \ | |
146 | "2:" \ | |
147 | : "=r" (__l), "=r" (__tp)); \ | |
148 | __l; }) | |
149 | ||
d9c734e9 UD |
150 | # ifdef PIC |
151 | # define TLS_IE(x) \ | |
3632a260 | 152 | ({ int *__l; void *__tp; \ |
d9c734e9 UD |
153 | register void *__gp __asm__("r12"); \ |
154 | asm ("mov.l 1f,r0\n\t" \ | |
155 | "stc gbr,%1\n\t" \ | |
156 | "mov.l @(r0,r12),%0\n\t" \ | |
157 | "bra 2f\n\t" \ | |
158 | " add %1,%0\n\t" \ | |
159 | ".align 2\n\t" \ | |
160 | "1: .long " #x "@gottpoff\n\t" \ | |
161 | "2:" \ | |
162 | : "=r" (__l), "=r" (__tp) : "r" (__gp) : "r0"); \ | |
163 | __l; }) | |
164 | # else | |
165 | # define TLS_IE(x) \ | |
166 | ({ int *__l; void *__tp; \ | |
167 | asm ("mov.l r12,@-r15\n\t" \ | |
168 | "mova 0f,r0\n\t" \ | |
3632a260 UD |
169 | "mov.l 0f,r12\n\t" \ |
170 | "add r0,r12\n\t" \ | |
171 | "mov.l 1f,r0\n\t" \ | |
172 | "stc gbr,%1\n\t" \ | |
173 | "mov.l @(r0,r12),%0\n\t" \ | |
174 | "bra 2f\n\t" \ | |
175 | " add %1,%0\n\t" \ | |
176 | ".align 2\n\t" \ | |
3632a260 | 177 | "1: .long " #x "@gottpoff\n\t" \ |
05a51227 | 178 | "0: .long _GLOBAL_OFFSET_TABLE_\n\t" \ |
d9c734e9 UD |
179 | "2: mov.l @r15+,r12" \ |
180 | : "=r" (__l), "=r" (__tp) : : "r0"); \ | |
3632a260 | 181 | __l; }) |
d9c734e9 | 182 | #endif |
3632a260 | 183 | |
d9c734e9 UD |
184 | # ifdef PIC |
185 | # define TLS_LD(x) \ | |
186 | ({ int *__l; \ | |
187 | register void *__gp __asm__("r12"); \ | |
188 | asm ("mov.l 1f,r4\n\t" \ | |
189 | "mova 2f,r0\n\t" \ | |
190 | "mov.l 2f,r1\n\t" \ | |
191 | "add r0,r1\n\t" \ | |
192 | "jsr @r1\n\t" \ | |
193 | " add r12,r4\n\t" \ | |
194 | "bra 4f\n\t" \ | |
195 | " nop\n\t" \ | |
196 | ".align 2\n\t" \ | |
197 | "1: .long " #x "@tlsldm\n\t" \ | |
198 | "2: .long __tls_get_addr@plt\n\t" \ | |
199 | "4: mov.l 3f,%0\n\t" \ | |
200 | "bra 5f\n\t" \ | |
201 | " add r0,%0\n\t" \ | |
202 | ".align 2\n\t" \ | |
203 | "3: .long " #x "@dtpoff\n\t" \ | |
204 | "5:" \ | |
205 | : "=r" (__l) : "r" (__gp) : "r0", "r1", "r2", "r3", "r4", "r5", \ | |
206 | "r6", "r7", "pr", "t"); \ | |
207 | __l; }) | |
208 | # else | |
209 | # define TLS_LD(x) \ | |
3632a260 | 210 | ({ int *__l; \ |
d9c734e9 UD |
211 | asm ("mov.l r12,@-r15\n\t" \ |
212 | "mova 0f,r0\n\t" \ | |
3632a260 UD |
213 | "mov.l 0f,r12\n\t" \ |
214 | "add r0,r12\n\t" \ | |
215 | "mov.l 1f,r4\n\t" \ | |
3632a260 UD |
216 | "mova 2f,r0\n\t" \ |
217 | "mov.l 2f,r1\n\t" \ | |
218 | "add r0,r1\n\t" \ | |
219 | "jsr @r1\n\t" \ | |
aa298c08 | 220 | " add r12,r4\n\t" \ |
3632a260 | 221 | "bra 4f\n\t" \ |
05a51227 | 222 | " nop\n\t" \ |
3632a260 | 223 | ".align 2\n\t" \ |
3632a260 UD |
224 | "1: .long " #x "@tlsldm\n\t" \ |
225 | "2: .long __tls_get_addr@plt\n\t" \ | |
05a51227 UD |
226 | "0: .long _GLOBAL_OFFSET_TABLE_\n\t" \ |
227 | "4: mov.l 3f,%0\n\t" \ | |
228 | "bra 5f\n\t" \ | |
229 | " add r0,%0\n\t" \ | |
230 | ".align 2\n\t" \ | |
3632a260 | 231 | "3: .long " #x "@dtpoff\n\t" \ |
d9c734e9 | 232 | "5: mov.l @r15+,r12" \ |
3632a260 | 233 | : "=r" (__l) : : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \ |
d9c734e9 | 234 | "pr", "t"); \ |
3632a260 | 235 | __l; }) |
d9c734e9 | 236 | #endif |
3632a260 | 237 | |
d9c734e9 UD |
238 | # ifdef PIC |
239 | # define TLS_GD(x) \ | |
3632a260 | 240 | ({ int *__l; \ |
d9c734e9 UD |
241 | register void *__gp __asm__("r12"); \ |
242 | asm ("mov.l 1f,r4\n\t" \ | |
243 | "mova 2f,r0\n\t" \ | |
244 | "mov.l 2f,r1\n\t" \ | |
245 | "add r0,r1\n\t" \ | |
246 | "jsr @r1\n\t" \ | |
247 | " add r12,r4\n\t" \ | |
248 | "bra 3f\n\t" \ | |
249 | " mov r0,%0\n\t" \ | |
250 | ".align 2\n\t" \ | |
251 | "1: .long " #x "@tlsgd\n\t" \ | |
252 | "2: .long __tls_get_addr@plt\n\t" \ | |
253 | "3:" \ | |
254 | : "=r" (__l) : "r" (__gp) : "r0", "r1", "r2", "r3", "r4", "r5", \ | |
255 | "r6", "r7", "pr", "t"); \ | |
256 | __l; }) | |
257 | # else | |
258 | # define TLS_GD(x) \ | |
259 | ({ int *__l; \ | |
260 | asm ("mov.l r12,@-r15\n\t" \ | |
261 | "mova 0f,r0\n\t" \ | |
3632a260 UD |
262 | "mov.l 0f,r12\n\t" \ |
263 | "add r0,r12\n\t" \ | |
264 | "mov.l 1f,r4\n\t" \ | |
3632a260 UD |
265 | "mova 2f,r0\n\t" \ |
266 | "mov.l 2f,r1\n\t" \ | |
267 | "add r0,r1\n\t" \ | |
268 | "jsr @r1\n\t" \ | |
aa298c08 | 269 | " add r12,r4\n\t" \ |
3632a260 UD |
270 | "bra 3f\n\t" \ |
271 | " mov r0,%0\n\t" \ | |
272 | ".align 2\n\t" \ | |
3632a260 UD |
273 | "1: .long " #x "@tlsgd\n\t" \ |
274 | "2: .long __tls_get_addr@plt\n\t" \ | |
05a51227 | 275 | "0: .long _GLOBAL_OFFSET_TABLE_\n\t" \ |
d9c734e9 | 276 | "3: mov.l @r15+,r12" \ |
3632a260 | 277 | : "=r" (__l) : : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \ |
d9c734e9 | 278 | "pr", "t"); \ |
3632a260 | 279 | __l; }) |
d9c734e9 | 280 | #endif |
3632a260 | 281 | |
62f29da7 UD |
282 | #elif defined __sparc__ && !defined __arch64__ |
283 | ||
284 | # define TLS_LE(x) \ | |
285 | ({ int *__l; \ | |
286 | asm ("sethi %%tle_hix22(" #x "), %0" : "=r" (__l)); \ | |
287 | asm ("xor %1, %%tle_lox10(" #x "), %0" : "=r" (__l) : "r" (__l)); \ | |
288 | asm ("add %%g7, %1, %0" : "=r" (__l) : "r" (__l)); \ | |
289 | __l; }) | |
290 | ||
fbb7fc75 | 291 | # ifdef __PIC__ |
62f29da7 UD |
292 | # define TLS_LOAD_PIC \ |
293 | ({ register long pc __asm__ ("%o7"); \ | |
294 | long got; \ | |
295 | asm ("sethi %%hi(_GLOBAL_OFFSET_TABLE_-4), %1\n\t" \ | |
296 | "call .+8\n\t" \ | |
297 | "add %1, %%lo(_GLOBAL_OFFSET_TABLE_+4), %1\n\t" \ | |
298 | "add %1, %0, %1\n\t" \ | |
299 | : "=r" (pc), "=r" (got)); \ | |
300 | got; }) | |
301 | # else | |
302 | # define TLS_LOAD_PIC \ | |
303 | ({ long got; \ | |
304 | asm (".hidden _GLOBAL_OFFSET_TABLE_\n\t" \ | |
305 | "sethi %%hi(_GLOBAL_OFFSET_TABLE_), %0\n\t" \ | |
306 | "or %0, %%lo(_GLOBAL_OFFSET_TABLE_), %0" \ | |
307 | : "=r" (got)); \ | |
308 | got; }) | |
309 | # endif | |
310 | ||
311 | # define TLS_IE(x) \ | |
312 | ({ int *__l; \ | |
313 | asm ("sethi %%tie_hi22(" #x "), %0" : "=r" (__l)); \ | |
314 | asm ("add %1, %%tie_lo10(" #x "), %0" : "=r" (__l) : "r" (__l)); \ | |
315 | asm ("ld [%1 + %2], %0, %%tie_ld(" #x ")" \ | |
316 | : "=r" (__l) : "r" (TLS_LOAD_PIC), "r" (__l)); \ | |
317 | asm ("add %%g7, %1, %0, %%tie_add(" #x ")" : "=r" (__l) : "r" (__l)); \ | |
318 | __l; }) | |
319 | ||
edac0e8f UD |
320 | # define TLS_LD(x) \ |
321 | ({ int *__l; register void *__o0 asm ("%o0"); \ | |
322 | long __o; \ | |
323 | asm ("sethi %%tldm_hi22(" #x "), %0" : "=r" (__l)); \ | |
324 | asm ("add %1, %%tldm_lo10(" #x "), %0" : "=r" (__l) : "r" (__l)); \ | |
325 | asm ("add %1, %2, %0, %%tldm_add(" #x ")" \ | |
326 | : "=r" (__o0) : "r" (TLS_LOAD_PIC), "r" (__l)); \ | |
327 | asm ("call __tls_get_addr, %%tgd_call(" #x ")\n\t" \ | |
328 | " nop" \ | |
329 | : "=r" (__o0) : "0" (__o0) \ | |
330 | : "g1", "g2", "g3", "g4", "g5", "g6", "o1", "o2", "o3", "o4", \ | |
331 | "o5", "o7", "cc"); \ | |
332 | asm ("sethi %%tldo_hix22(" #x "), %0" : "=r" (__o)); \ | |
333 | asm ("xor %1, %%tldo_lox10(" #x "), %0" : "=r" (__o) : "r" (__o)); \ | |
334 | asm ("add %1, %2, %0, %%tldo_add(" #x ")" : "=r" (__l) \ | |
335 | : "r" (__o0), "r" (__o)); \ | |
336 | __l; }) | |
337 | ||
338 | # define TLS_GD(x) \ | |
339 | ({ int *__l; register void *__o0 asm ("%o0"); \ | |
340 | asm ("sethi %%tgd_hi22(" #x "), %0" : "=r" (__l)); \ | |
341 | asm ("add %1, %%tgd_lo10(" #x "), %0" : "=r" (__l) : "r" (__l)); \ | |
342 | asm ("add %1, %2, %0, %%tgd_add(" #x ")" \ | |
343 | : "=r" (__o0) : "r" (TLS_LOAD_PIC), "r" (__l)); \ | |
344 | asm ("call __tls_get_addr, %%tgd_call(" #x ")\n\t" \ | |
345 | " nop" \ | |
346 | : "=r" (__o0) : "0" (__o0) \ | |
347 | : "g1", "g2", "g3", "g4", "g5", "g6", "o1", "o2", "o3", "o4", \ | |
348 | "o5", "o7", "cc"); \ | |
349 | __o0; }) | |
350 | ||
351 | #elif defined __sparc__ && defined __arch64__ | |
352 | ||
353 | # define TLS_LE(x) \ | |
354 | ({ int *__l; \ | |
355 | asm ("sethi %%tle_hix22(" #x "), %0" : "=r" (__l)); \ | |
356 | asm ("xor %1, %%tle_lox10(" #x "), %0" : "=r" (__l) : "r" (__l)); \ | |
357 | asm ("add %%g7, %1, %0" : "=r" (__l) : "r" (__l)); \ | |
358 | __l; }) | |
359 | ||
360 | # ifdef __PIC__ | |
361 | # define TLS_LOAD_PIC \ | |
362 | ({ long pc, got; \ | |
363 | asm ("sethi %%hi(_GLOBAL_OFFSET_TABLE_-4), %1\n\t" \ | |
364 | "rd %%pc, %0\n\t" \ | |
365 | "add %1, %%lo(_GLOBAL_OFFSET_TABLE_+4), %1\n\t" \ | |
366 | "add %1, %0, %1\n\t" \ | |
367 | : "=r" (pc), "=r" (got)); \ | |
368 | got; }) | |
369 | # else | |
370 | # define TLS_LOAD_PIC \ | |
371 | ({ long got; \ | |
372 | asm (".hidden _GLOBAL_OFFSET_TABLE_\n\t" \ | |
373 | "sethi %%hi(_GLOBAL_OFFSET_TABLE_), %0\n\t" \ | |
374 | "or %0, %%lo(_GLOBAL_OFFSET_TABLE_), %0" \ | |
375 | : "=r" (got)); \ | |
376 | got; }) | |
377 | # endif | |
378 | ||
379 | # define TLS_IE(x) \ | |
380 | ({ int *__l; \ | |
381 | asm ("sethi %%tie_hi22(" #x "), %0" : "=r" (__l)); \ | |
382 | asm ("add %1, %%tie_lo10(" #x "), %0" : "=r" (__l) : "r" (__l)); \ | |
383 | asm ("ldx [%1 + %2], %0, %%tie_ldx(" #x ")" \ | |
384 | : "=r" (__l) : "r" (TLS_LOAD_PIC), "r" (__l)); \ | |
385 | asm ("add %%g7, %1, %0, %%tie_add(" #x ")" : "=r" (__l) : "r" (__l)); \ | |
386 | __l; }) | |
387 | ||
62f29da7 UD |
388 | # define TLS_LD(x) \ |
389 | ({ int *__l; register void *__o0 asm ("%o0"); \ | |
390 | long __o; \ | |
391 | asm ("sethi %%tldm_hi22(" #x "), %0" : "=r" (__l)); \ | |
392 | asm ("add %1, %%tldm_lo10(" #x "), %0" : "=r" (__l) : "r" (__l)); \ | |
393 | asm ("add %1, %2, %0, %%tldm_add(" #x ")" \ | |
394 | : "=r" (__o0) : "r" (TLS_LOAD_PIC), "r" (__l)); \ | |
395 | asm ("call __tls_get_addr, %%tgd_call(" #x ")\n\t" \ | |
396 | " nop" \ | |
397 | : "=r" (__o0) : "0" (__o0) \ | |
398 | : "g1", "g2", "g3", "g4", "g5", "g6", "o1", "o2", "o3", "o4", \ | |
75dec09e | 399 | "o5", "o7", "cc"); \ |
62f29da7 UD |
400 | asm ("sethi %%tldo_hix22(" #x "), %0" : "=r" (__o)); \ |
401 | asm ("xor %1, %%tldo_lox10(" #x "), %0" : "=r" (__o) : "r" (__o)); \ | |
402 | asm ("add %1, %2, %0, %%tldo_add(" #x ")" : "=r" (__l) \ | |
403 | : "r" (__o0), "r" (__o)); \ | |
404 | __l; }) | |
405 | ||
406 | # define TLS_GD(x) \ | |
407 | ({ int *__l; register void *__o0 asm ("%o0"); \ | |
408 | asm ("sethi %%tgd_hi22(" #x "), %0" : "=r" (__l)); \ | |
409 | asm ("add %1, %%tgd_lo10(" #x "), %0" : "=r" (__l) : "r" (__l)); \ | |
410 | asm ("add %1, %2, %0, %%tgd_add(" #x ")" \ | |
411 | : "=r" (__o0) : "r" (TLS_LOAD_PIC), "r" (__l)); \ | |
412 | asm ("call __tls_get_addr, %%tgd_call(" #x ")\n\t" \ | |
413 | " nop" \ | |
414 | : "=r" (__o0) : "0" (__o0) \ | |
415 | : "g1", "g2", "g3", "g4", "g5", "g6", "o1", "o2", "o3", "o4", \ | |
75dec09e | 416 | "o5", "o7", "cc"); \ |
62f29da7 UD |
417 | __o0; }) |
418 | ||
e6ebd2e4 UD |
419 | #elif defined __s390x__ |
420 | ||
421 | # define TLS_LE(x) \ | |
422 | ({ unsigned long __offset; \ | |
423 | asm ("bras %0,1f\n" \ | |
424 | "0:\t.quad " #x "@ntpoff\n" \ | |
425 | "1:\tlg %0,0(%0)" \ | |
426 | : "=a" (__offset) : : "cc" ); \ | |
427 | (int *) (__builtin_thread_pointer() + __offset); }) | |
428 | ||
429 | # ifdef PIC | |
430 | # define TLS_IE(x) \ | |
431 | ({ unsigned long __offset; \ | |
432 | asm ("bras %0,1f\n" \ | |
433 | "0:\t.quad " #x "@gotntpoff\n" \ | |
434 | "1:\tlg %0,0(%0)\n\t" \ | |
435 | "lg %0,0(%0,%%r12):tls_load:" #x \ | |
436 | : "=&a" (__offset) : : "cc" ); \ | |
437 | (int *) (__builtin_thread_pointer() + __offset); }) | |
438 | # else | |
439 | # define TLS_IE(x) \ | |
440 | ({ unsigned long __offset; \ | |
441 | asm ("bras %0,1f\n" \ | |
442 | "0:\t.quad " #x "@indntpoff\n" \ | |
443 | "1:\t lg %0,0(%0)\n\t" \ | |
444 | "lg %0,0(%0):tls_load:" #x \ | |
445 | : "=&a" (__offset) : : "cc" ); \ | |
446 | (int *) (__builtin_thread_pointer() + __offset); }) | |
447 | # endif | |
448 | ||
449 | # ifdef PIC | |
450 | # define TLS_LD(x) \ | |
451 | ({ unsigned long __offset, __save12; \ | |
452 | asm ("bras %0,1f\n" \ | |
453 | "0:\t.quad " #x "@tlsldm\n\t" \ | |
454 | ".quad " #x "@dtpoff\n" \ | |
455 | "1:\tlgr %1,%%r12\n\t" \ | |
664f8cb9 UD |
456 | "larl %%r12,_GLOBAL_OFFSET_TABLE_\n\t" \ |
457 | "lg %%r2,0(%0)\n\t" \ | |
e6ebd2e4 UD |
458 | "brasl %%r14,__tls_get_offset@plt:tls_ldcall:" #x "\n\t" \ |
459 | "lg %0,8(%0)\n\t" \ | |
460 | "algr %0,%%r2\n\t" \ | |
664f8cb9 | 461 | "lgr %%r12,%1" \ |
e6ebd2e4 | 462 | : "=&a" (__offset), "=&a" (__save12) \ |
664f8cb9 | 463 | : : "cc", "0", "1", "2", "3", "4", "5", "14" ); \ |
e6ebd2e4 UD |
464 | (int *) (__builtin_thread_pointer() + __offset); }) |
465 | # else | |
466 | # define TLS_LD(x) \ | |
467 | ({ unsigned long __offset; \ | |
468 | asm ("bras %0,1f\n" \ | |
469 | "0:\t.quad " #x "@tlsldm\n\t" \ | |
470 | ".quad " #x "@dtpoff\n" \ | |
471 | "1:\tlarl %%r12,_GLOBAL_OFFSET_TABLE_\n\t" \ | |
664f8cb9 | 472 | "lg %%r2,0(%0)\n\t" \ |
e6ebd2e4 UD |
473 | "brasl %%r14,__tls_get_offset@plt:tls_ldcall:" #x "\n\t" \ |
474 | "lg %0,8(%0)\n\t" \ | |
475 | "algr %0,%%r2" \ | |
b80af23a RM |
476 | : "=&a" (__offset) \ |
477 | : : "cc", "0", "1", "2", "3", "4", "5", "12", "14" ); \ | |
e6ebd2e4 UD |
478 | (int *) (__builtin_thread_pointer() + __offset); }) |
479 | # endif | |
480 | ||
481 | # ifdef PIC | |
482 | # define TLS_GD(x) \ | |
483 | ({ unsigned long __offset, __save12; \ | |
484 | asm ("bras %0,1f\n" \ | |
485 | "0:\t.quad " #x "@tlsgd\n" \ | |
486 | "1:\tlgr %1,%%r12\n\t" \ | |
487 | "larl %%r12,_GLOBAL_OFFSET_TABLE_\n\t" \ | |
664f8cb9 | 488 | "lg %%r2,0(%0)\n\t" \ |
e6ebd2e4 | 489 | "brasl %%r14,__tls_get_offset@plt:tls_gdcall:" #x "\n\t" \ |
664f8cb9 UD |
490 | "lgr %0,%%r2\n\t" \ |
491 | "lgr %%r12,%1" \ | |
e6ebd2e4 | 492 | : "=&a" (__offset), "=&a" (__save12) \ |
664f8cb9 | 493 | : : "cc", "0", "1", "2", "3", "4", "5", "14" ); \ |
e6ebd2e4 UD |
494 | (int *) (__builtin_thread_pointer() + __offset); }) |
495 | # else | |
496 | # define TLS_GD(x) \ | |
497 | ({ unsigned long __offset; \ | |
498 | asm ("bras %0,1f\n" \ | |
499 | "0:\t.quad " #x "@tlsgd\n" \ | |
500 | "1:\tlarl %%r12,_GLOBAL_OFFSET_TABLE_\n\t" \ | |
501 | "lg %%r2,0(%0)\n\t" \ | |
502 | "brasl %%r14,__tls_get_offset@plt:tls_gdcall:" #x "\n\t" \ | |
664f8cb9 | 503 | "lgr %0,%%r2" \ |
b80af23a RM |
504 | : "=&a" (__offset) \ |
505 | : : "cc", "0", "1", "2", "3", "4", "5", "12", "14" ); \ | |
e6ebd2e4 UD |
506 | (int *) (__builtin_thread_pointer() + __offset); }) |
507 | # endif | |
508 | ||
509 | #elif defined __s390__ | |
510 | ||
511 | # define TLS_LE(x) \ | |
512 | ({ unsigned long __offset; \ | |
513 | asm ("bras %0,1f\n" \ | |
514 | "0:\t.long " #x "@ntpoff\n" \ | |
515 | "1:\tl %0,0(%0)" \ | |
516 | : "=a" (__offset) : : "cc" ); \ | |
517 | (int *) (__builtin_thread_pointer() + __offset); }) | |
518 | ||
519 | # ifdef PIC | |
520 | # define TLS_IE(x) \ | |
521 | ({ unsigned long __offset; \ | |
522 | asm ("bras %0,1f\n" \ | |
523 | "0:\t.long " #x "@gotntpoff\n" \ | |
524 | "1:\tl %0,0(%0)\n\t" \ | |
525 | "l %0,0(%0,%%r12):tls_load:" #x \ | |
526 | : "=&a" (__offset) : : "cc" ); \ | |
527 | (int *) (__builtin_thread_pointer() + __offset); }) | |
528 | # else | |
529 | # define TLS_IE(x) \ | |
530 | ({ unsigned long __offset; \ | |
531 | asm ("bras %0,1f\n" \ | |
532 | "0:\t.long " #x "@indntpoff\n" \ | |
533 | "1:\t l %0,0(%0)\n\t" \ | |
534 | "l %0,0(%0):tls_load:" #x \ | |
535 | : "=&a" (__offset) : : "cc" ); \ | |
536 | (int *) (__builtin_thread_pointer() + __offset); }) | |
537 | # endif | |
538 | ||
539 | # ifdef PIC | |
540 | # define TLS_LD(x) \ | |
541 | ({ unsigned long __offset, __save12; \ | |
542 | asm ("bras %0,1f\n" \ | |
543 | "0:\t.long _GLOBAL_OFFSET_TABLE_-0b\n\t" \ | |
544 | ".long __tls_get_offset@plt-0b\n\t" \ | |
545 | ".long " #x "@tlsldm\n\t" \ | |
546 | ".long " #x "@dtpoff\n" \ | |
547 | "1:\tlr %1,%%r12\n\t" \ | |
664f8cb9 UD |
548 | "l %%r12,0(%0)\n\t" \ |
549 | "la %%r12,0(%%r12,%0)\n\t" \ | |
e6ebd2e4 UD |
550 | "l %%r1,4(%0)\n\t" \ |
551 | "l %%r2,8(%0)\n\t" \ | |
552 | "bas %%r14,0(%%r1,%0):tls_ldcall:" #x "\n\t" \ | |
553 | "l %0,12(%0)\n\t" \ | |
554 | "alr %0,%%r2\n\t" \ | |
664f8cb9 | 555 | "lr %%r12,%1" \ |
e6ebd2e4 | 556 | : "=&a" (__offset), "=&a" (__save12) \ |
664f8cb9 | 557 | : : "cc", "0", "1", "2", "3", "4", "5" ); \ |
e6ebd2e4 UD |
558 | (int *) (__builtin_thread_pointer() + __offset); }) |
559 | # else | |
560 | # define TLS_LD(x) \ | |
561 | ({ unsigned long __offset; \ | |
562 | asm ("bras %0,1f\n" \ | |
563 | "0:\t.long _GLOBAL_OFFSET_TABLE_\n\t" \ | |
564 | ".long __tls_get_offset@plt\n\t" \ | |
565 | ".long " #x "@tlsldm\n\t" \ | |
566 | ".long " #x "@dtpoff\n" \ | |
567 | "1:\tl %%r12,0(%0)\n\t" \ | |
568 | "l %%r1,4(%0)\n\t" \ | |
569 | "l %%r2,8(%0)\n\t" \ | |
570 | "bas %%r14,0(%%r1):tls_ldcall:" #x "\n\t" \ | |
571 | "l %0,12(%0)\n\t" \ | |
572 | "alr %0,%%r2" \ | |
573 | : "=&a" (__offset) : : "cc", "0", "1", "2", "3", "4", "5", "12" ); \ | |
574 | (int *) (__builtin_thread_pointer() + __offset); }) | |
575 | # endif | |
576 | ||
577 | # ifdef PIC | |
578 | # define TLS_GD(x) \ | |
579 | ({ unsigned long __offset, __save12; \ | |
580 | asm ("bras %0,1f\n" \ | |
581 | "0:\t.long _GLOBAL_OFFSET_TABLE_-0b\n\t" \ | |
582 | ".long __tls_get_offset@plt-0b\n\t" \ | |
583 | ".long " #x "@tlsgd\n" \ | |
584 | "1:\tlr %1,%%r12\n\t" \ | |
664f8cb9 UD |
585 | "l %%r12,0(%0)\n\t" \ |
586 | "la %%r12,0(%%r12,%0)\n\t" \ | |
e6ebd2e4 UD |
587 | "l %%r1,4(%0)\n\t" \ |
588 | "l %%r2,8(%0)\n\t" \ | |
589 | "bas %%r14,0(%%r1,%0):tls_gdcall:" #x "\n\t" \ | |
664f8cb9 UD |
590 | "lr %0,%%r2\n\t" \ |
591 | "lr %%r12,%1" \ | |
e6ebd2e4 | 592 | : "=&a" (__offset), "=&a" (__save12) \ |
664f8cb9 | 593 | : : "cc", "0", "1", "2", "3", "4", "5" ); \ |
e6ebd2e4 UD |
594 | (int *) (__builtin_thread_pointer() + __offset); }) |
595 | # else | |
596 | # define TLS_GD(x) \ | |
597 | ({ unsigned long __offset; \ | |
598 | asm ("bras %0,1f\n" \ | |
599 | "0:\t.long _GLOBAL_OFFSET_TABLE_\n\t" \ | |
600 | ".long __tls_get_offset@plt\n\t" \ | |
601 | ".long " #x "@tlsgd\n" \ | |
602 | "1:\tl %%r12,0(%0)\n\t" \ | |
603 | "l %%r1,4(%0)\n\t" \ | |
604 | "l %%r2,8(%0)\n\t" \ | |
605 | "bas %%r14,0(%%r1):tls_gdcall:" #x "\n\t" \ | |
664f8cb9 | 606 | "lr %0,%%r2" \ |
e6ebd2e4 UD |
607 | : "=&a" (__offset) : : "cc", "0", "1", "2", "3", "4", "5", "12" ); \ |
608 | (int *) (__builtin_thread_pointer() + __offset); }) | |
609 | # endif | |
610 | ||
c62cf60c | 611 | #elif defined __powerpc__ |
bb0ddc2f | 612 | |
c62cf60c AM |
613 | # define __TLS_CALL_CLOBBERS \ |
614 | "0", "4", "5", "6", "7", "8", "9", "10", "11", "12", \ | |
bb0ddc2f RM |
615 | "lr", "ctr", "cr0", "cr1", "cr5", "cr6", "cr7" |
616 | ||
c62cf60c AM |
617 | # ifndef __powerpc64__ |
618 | ||
619 | # include "config.h" | |
620 | ||
bb0ddc2f | 621 | /* PowerPC32 Local Exec TLS access. */ |
c62cf60c AM |
622 | # define TLS_LE(x) \ |
623 | ({ int *__result; \ | |
624 | asm ("addi %0,2," #x "@tprel" \ | |
625 | : "=r" (__result)); \ | |
bb0ddc2f RM |
626 | __result; }) |
627 | ||
628 | /* PowerPC32 Initial Exec TLS access. */ | |
c62cf60c AM |
629 | # ifdef HAVE_ASM_PPC_REL16 |
630 | # define TLS_IE(x) \ | |
631 | ({ int *__result; \ | |
632 | asm ("bcl 20,31,1f\n1:\t" \ | |
633 | "mflr %0\n\t" \ | |
634 | "addis %0,%0,_GLOBAL_OFFSET_TABLE_-1b@ha\n\t" \ | |
635 | "addi %0,%0,_GLOBAL_OFFSET_TABLE_-1b@l\n\t" \ | |
636 | "lwz %0," #x "@got@tprel(%0)\n\t" \ | |
637 | "add %0,%0," #x "@tls" \ | |
638 | : "=b" (__result) : \ | |
639 | : "lr"); \ | |
99c7f870 | 640 | __result; }) |
c62cf60c AM |
641 | # else |
642 | # define TLS_IE(x) \ | |
643 | ({ int *__result; \ | |
644 | asm ("bl _GLOBAL_OFFSET_TABLE_@local-4\n\t" \ | |
645 | "mflr %0\n\t" \ | |
646 | "lwz %0," #x "@got@tprel(%0)\n\t" \ | |
647 | "add %0,%0," #x "@tls" \ | |
648 | : "=b" (__result) : \ | |
649 | : "lr"); \ | |
bb0ddc2f | 650 | __result; }) |
c62cf60c | 651 | # endif |
bb0ddc2f RM |
652 | |
653 | /* PowerPC32 Local Dynamic TLS access. */ | |
c62cf60c AM |
654 | # ifdef HAVE_ASM_PPC_REL16 |
655 | # define TLS_LD(x) \ | |
656 | ({ int *__result; \ | |
657 | asm ("bcl 20,31,1f\n1:\t" \ | |
658 | "mflr 3\n\t" \ | |
659 | "addis 3,3,_GLOBAL_OFFSET_TABLE_-1b@ha\n\t" \ | |
660 | "addi 3,3,_GLOBAL_OFFSET_TABLE_-1b@l\n\t" \ | |
661 | "addi 3,3," #x "@got@tlsld\n\t" \ | |
662 | "bl __tls_get_addr@plt\n\t" \ | |
663 | "addi %0,3," #x "@dtprel" \ | |
664 | : "=r" (__result) : \ | |
665 | : "3", __TLS_CALL_CLOBBERS); \ | |
99c7f870 | 666 | __result; }) |
c62cf60c AM |
667 | # else |
668 | # define TLS_LD(x) \ | |
669 | ({ int *__result; \ | |
670 | asm ("bl _GLOBAL_OFFSET_TABLE_@local-4\n\t" \ | |
671 | "mflr 3\n\t" \ | |
672 | "addi 3,3," #x "@got@tlsld\n\t" \ | |
673 | "bl __tls_get_addr@plt\n\t" \ | |
674 | "addi %0,3," #x "@dtprel" \ | |
675 | : "=r" (__result) : \ | |
676 | : "3", __TLS_CALL_CLOBBERS); \ | |
bb0ddc2f | 677 | __result; }) |
c62cf60c | 678 | # endif |
bb0ddc2f RM |
679 | |
680 | /* PowerPC32 General Dynamic TLS access. */ | |
c62cf60c AM |
681 | # ifdef HAVE_ASM_PPC_REL16 |
682 | # define TLS_GD(x) \ | |
683 | ({ register int *__result __asm__ ("r3"); \ | |
684 | asm ("bcl 20,31,1f\n1:\t" \ | |
685 | "mflr 3\n\t" \ | |
686 | "addis 3,3,_GLOBAL_OFFSET_TABLE_-1b@ha\n\t" \ | |
687 | "addi 3,3,_GLOBAL_OFFSET_TABLE_-1b@l\n\t" \ | |
688 | "addi 3,3," #x "@got@tlsgd\n\t" \ | |
689 | "bl __tls_get_addr@plt" \ | |
690 | : "=r" (__result) : \ | |
691 | : __TLS_CALL_CLOBBERS); \ | |
99c7f870 | 692 | __result; }) |
c62cf60c AM |
693 | # else |
694 | # define TLS_GD(x) \ | |
695 | ({ register int *__result __asm__ ("r3"); \ | |
696 | asm ("bl _GLOBAL_OFFSET_TABLE_@local-4\n\t" \ | |
697 | "mflr 3\n\t" \ | |
698 | "addi 3,3," #x "@got@tlsgd\n\t" \ | |
699 | "bl __tls_get_addr@plt" \ | |
700 | : "=r" (__result) : \ | |
701 | : __TLS_CALL_CLOBBERS); \ | |
bb0ddc2f | 702 | __result; }) |
c62cf60c | 703 | # endif |
bb0ddc2f | 704 | |
c62cf60c | 705 | # else |
fec41719 RM |
706 | |
707 | /* PowerPC64 Local Exec TLS access. */ | |
c62cf60c AM |
708 | # define TLS_LE(x) \ |
709 | ({ int * __result; \ | |
710 | asm ("addis %0,13," #x "@tprel@ha\n\t" \ | |
711 | "addi %0,%0," #x "@tprel@l" \ | |
712 | : "=b" (__result) ); \ | |
713 | __result; \ | |
fec41719 RM |
714 | }) |
715 | /* PowerPC64 Initial Exec TLS access. */ | |
c62cf60c AM |
716 | # define TLS_IE(x) \ |
717 | ({ int * __result; \ | |
718 | asm ("ld %0," #x "@got@tprel(2)\n\t" \ | |
719 | "add %0,%0," #x "@tls" \ | |
720 | : "=r" (__result) ); \ | |
721 | __result; \ | |
fec41719 | 722 | }) |
c62cf60c AM |
723 | # ifdef HAVE_ASM_GLOBAL_DOT_NAME |
724 | # define __TLS_GET_ADDR ".__tls_get_addr" | |
725 | # else | |
726 | # define __TLS_GET_ADDR "__tls_get_addr" | |
727 | # endif | |
fec41719 | 728 | /* PowerPC64 Local Dynamic TLS access. */ |
c62cf60c AM |
729 | # define TLS_LD(x) \ |
730 | ({ int * __result; \ | |
731 | asm ("addi 3,2," #x "@got@tlsld\n\t" \ | |
732 | "bl " __TLS_GET_ADDR "\n\t" \ | |
733 | "nop \n\t" \ | |
734 | "addis %0,3," #x "@dtprel@ha\n\t" \ | |
735 | "addi %0,%0," #x "@dtprel@l" \ | |
736 | : "=b" (__result) : \ | |
737 | : "3", __TLS_CALL_CLOBBERS); \ | |
738 | __result; \ | |
fec41719 RM |
739 | }) |
740 | /* PowerPC64 General Dynamic TLS access. */ | |
c62cf60c AM |
741 | # define TLS_GD(x) \ |
742 | ({ register int *__result __asm__ ("r3"); \ | |
743 | asm ("addi 3,2," #x "@got@tlsgd\n\t" \ | |
744 | "bl " __TLS_GET_ADDR "\n\t" \ | |
745 | "nop " \ | |
746 | : "=r" (__result) : \ | |
747 | : __TLS_CALL_CLOBBERS); \ | |
748 | __result; \ | |
fec41719 | 749 | }) |
c62cf60c | 750 | # endif |
fec41719 | 751 | |
af81020e | 752 | #elif !defined TLS_LE || !defined TLS_IE \ |
729cee49 | 753 | || !defined TLS_LD || !defined TLS_GD |
2cef4257 UD |
754 | # error "No support for this architecture so far." |
755 | #endif |