tls-macros.h 30 KB

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