| #ifdef __thumb2__ |
| #define ARM_PC_OFFSET "4" |
| #else |
| #define ARM_PC_OFFSET "8" |
| #endif |
| |
| #define TLS_LE(x) \ |
| ({ int *__result; \ |
| void *tp = __builtin_thread_pointer (); \ |
| asm ("ldr %0, 1f; " \ |
| "add %0, %1, %0; " \ |
| "b 2f; " \ |
| ".align 2; " \ |
| "1: .word " #x "(tpoff); " \ |
| "2: " \ |
| : "=&r" (__result) : "r" (tp)); \ |
| __result; }) |
| |
| #ifdef __thumb2__ |
| #define TLS_IE(x) \ |
| ({ int *__result; \ |
| void *tp = __builtin_thread_pointer (); \ |
| asm ("ldr %0, 1f; " \ |
| "3: add %0, pc, %0;" \ |
| "ldr %0, [%0];" \ |
| "add %0, %1, %0; " \ |
| "b 2f; " \ |
| ".align 2; " \ |
| "1: .word " #x "(gottpoff) + (. - 3b - 4); " \ |
| "2: " \ |
| : "=&r" (__result) : "r" (tp)); \ |
| __result; }) |
| #else |
| #define TLS_IE(x) \ |
| ({ int *__result; \ |
| void *tp = __builtin_thread_pointer (); \ |
| asm ("ldr %0, 1f; " \ |
| "3: ldr %0, [pc, %0];" \ |
| "add %0, %1, %0; " \ |
| "b 2f; " \ |
| ".align 2; " \ |
| "1: .word " #x "(gottpoff) + (. - 3b - 8); " \ |
| "2: " \ |
| : "=&r" (__result) : "r" (tp)); \ |
| __result; }) |
| #endif |
| |
| #define TLS_LD(x) \ |
| ({ char *__result; \ |
| int __offset; \ |
| extern void *__tls_get_addr (void *); \ |
| asm ("ldr %0, 2f; " \ |
| "1: add %0, pc, %0; " \ |
| "b 3f; " \ |
| ".align 2; " \ |
| "2: .word " #x "(tlsldm) + (. - 1b - "ARM_PC_OFFSET"); " \ |
| "3: " \ |
| : "=r" (__result)); \ |
| __result = (char *)__tls_get_addr (__result); \ |
| asm ("ldr %0, 1f; " \ |
| "b 2f; " \ |
| ".align 2; " \ |
| "1: .word " #x "(tlsldo); " \ |
| "2: " \ |
| : "=r" (__offset)); \ |
| (int *) (__result + __offset); }) |
| |
| #define TLS_GD(x) \ |
| ({ int *__result; \ |
| extern void *__tls_get_addr (void *); \ |
| asm ("ldr %0, 2f; " \ |
| "1: add %0, pc, %0; " \ |
| "b 3f; " \ |
| ".align 2; " \ |
| "2: .word " #x "(tlsgd) + (. - 1b - "ARM_PC_OFFSET"); " \ |
| "3: " \ |
| : "=r" (__result)); \ |
| (int *)__tls_get_addr (__result); }) |