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