Back to index

glibc  2.9
tls-macros.h
Go to the documentation of this file.
00001 /* Macros to support TLS testing in times of missing compiler support.  */
00002 
00003 #include <sys/cdefs.h>
00004 #include <sys/asm.h>
00005 
00006 #define __STRING2(X) __STRING(X)
00007 #define ADDU __STRING2(PTR_ADDU)
00008 #define ADDIU __STRING2(PTR_ADDIU)
00009 #define LW __STRING2(PTR_L)
00010 
00011 /* Load the GOT pointer, which may not be in $28 in a non-PIC
00012    (abicalls pic0) function.  */
00013 #ifndef __PIC__
00014 # if _MIPS_SIM != _ABI64
00015 #  define LOAD_GP "move %[tmp], $28\n\tla $28, __gnu_local_gp\n\t"
00016 # else
00017 #  define LOAD_GP "move %[tmp], $28\n\tdla $28, __gnu_local_gp\n\t"
00018 # endif
00019 # define UNLOAD_GP "\n\tmove $28, %[tmp]"
00020 #else
00021 # define LOAD_GP
00022 # define UNLOAD_GP
00023 #endif
00024 
00025 # define TLS_GD(x)                               \
00026   ({ void *__result, *__tmp;                            \
00027      extern void *__tls_get_addr (void *);              \
00028      asm (LOAD_GP ADDIU " %0, $28, %%tlsgd(" #x ")"     \
00029          UNLOAD_GP                               \
00030          : "=r" (__result), [tmp] "=&r" (__tmp));       \
00031      (int *)__tls_get_addr (__result); })
00032 # define TLS_LD(x)                               \
00033   ({ void *__result, *__tmp;                            \
00034      extern void *__tls_get_addr (void *);              \
00035      asm (LOAD_GP ADDIU " %0, $28, %%tlsldm(" #x ")"    \
00036          UNLOAD_GP                               \
00037          : "=r" (__result), [tmp] "=&r" (__tmp));       \
00038      __result = __tls_get_addr (__result);              \
00039      asm ("lui $3,%%dtprel_hi(" #x ")\n\t"              \
00040          "addiu $3,$3,%%dtprel_lo(" #x ")\n\t"          \
00041          ADDU " %0,%0,$3"                        \
00042          : "+r" (__result) : : "$3");                   \
00043      __result; })
00044 # define TLS_IE(x)                               \
00045   ({ void *__result, *__tmp;                            \
00046      asm (".set push\n\t.set mips32r2\n\t"              \
00047          "rdhwr\t%0,$29\n\t.set pop"                    \
00048          : "=v" (__result));                            \
00049      asm (LOAD_GP LW " $3,%%gottprel(" #x ")($28)\n\t"  \
00050          ADDU " %0,%0,$3"                        \
00051          UNLOAD_GP                               \
00052          : "+r" (__result), [tmp] "=&r" (__tmp)  \
00053          : : "$3");                              \
00054      __result; })
00055 # define TLS_LE(x)                               \
00056   ({ void *__result;                             \
00057      asm (".set push\n\t.set mips32r2\n\t"              \
00058          "rdhwr\t%0,$29\n\t.set pop"                    \
00059          : "=v" (__result));                            \
00060      asm ("lui $3,%%tprel_hi(" #x ")\n\t"        \
00061          "addiu $3,$3,%%tprel_lo(" #x ")\n\t"           \
00062          ADDU " %0,%0,$3"                        \
00063          : "+r" (__result) : : "$3");                   \
00064      __result; })