]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
arm: Implement hard-tp for GET_TLS
authorRichard Henderson <rth@twiddle.net>
Fri, 1 Mar 2013 05:37:02 +0000 (21:37 -0800)
committerRichard Henderson <rth@twiddle.net>
Wed, 6 Mar 2013 15:47:21 +0000 (07:47 -0800)
ports/ChangeLog.arm
ports/sysdeps/arm/sysdep.h
ports/sysdeps/unix/sysv/linux/arm/aeabi_read_tp.S
ports/sysdeps/unix/sysv/linux/arm/sysdep.h

index 2c3f220e1314f97a2575d30155f0c4fddb90452a..288dfb4c09dfa73b55d2985ffd1fb00910d9350f 100644 (file)
@@ -1,5 +1,11 @@
 2013-03-06  Richard Henderson <rth@redhat.com>
 
+       * sysdeps/arm/sysdep.h (ARCH_HAS_HARD_TP): New macro.
+       (GET_TLS): Use hard-tp if ARCH_HAS_HARD_TP.
+       * sysdeps/unix/sysv/linux/arm/aeabi_read_tp.S: Likewise.
+       * sysdeps/unix/sysv/linux/arm/sysdep.h (GET_TLS): Don't override
+       the default definition if ARCH_HAS_HARD_TP.
+
        * sysdeps/arm/sysdep.h (__ARM_ARCH): New macro.
        (ARCH_HAS_BX, ARCH_HAS_BLX, ARCH_HAS_T2): New macros.
        (BX): Select on ARCH_HAS_BX instead of __USE_BX__.
index 156bc017345e513bc6d581f75d856b7c280902f2..4a7a13f6fb3b2f4ca7b5aa1ed50d4ed097bb18db 100644 (file)
@@ -50,6 +50,9 @@
 #if __ARM_ARCH > 4
 # define ARCH_HAS_BLX
 #endif
+#if __ARM_ARCH > 6 || defined (__ARM_ARCH_6K__) || defined (__ARM_ARCH_6ZK__)
+# define ARCH_HAS_HARD_TP
+#endif
 #if __ARM_ARCH > 6 || defined (__ARM_ARCH_6T2__)
 # define ARCH_HAS_T2
 #endif
 /* Helper to get the TLS base pointer.  The interface is that TMP is a
    register that may be used to hold the LR, if necessary.  TMP may be
    LR itself to indicate that LR need not be saved.  The base pointer
-   is returned in R0.  Only R0 and TMP are modified.
+   is returned in R0.  Only R0 and TMP are modified.  */
 
-   At this generic level we have no tricks to pull.  Call the ABI routine.  */
-# define GET_TLS(TMP)                                  \
+# ifdef ARCH_HAS_HARD_TP
+/* If the cpu has cp15 available, use it.  */
+#  define GET_TLS(TMP)         mrc p15, 0, r0, c13, c0, 3
+# else
+/* At this generic level we have no tricks to pull.  Call the ABI routine.  */
+#  define GET_TLS(TMP)                                 \
        push    { r1, r2, r3, lr };                     \
        cfi_remember_state;                             \
        cfi_adjust_cfa_offset (16);                     \
        bl      __aeabi_read_tp;                        \
        pop     { r1, r2, r3, lr };                     \
        cfi_restore_state
+# endif /* ARCH_HAS_HARD_TP */
 
 #endif /* __ASSEMBLER__ */
 
index ecdc3228a33bfa5a8c51bc99b473f5ee69c383c7..21e322986a77b3c166fbd5c1320f3794fe29cba0 100644 (file)
 
        .hidden __aeabi_read_tp
 ENTRY (__aeabi_read_tp)
-#ifdef __thumb2__
+#ifdef ARCH_HAS_HARD_TP
+       mrc     p15, 0, r0, c13, c0, 3
+       bx      lr
+#elif defined(__thumb2__)
        movw    r0, #0x0fe0
        movt    r0, #0xffff
        bx      r0
index f2ab5f589f06238aa379ae721685e5ac2ed362e0..b195d8ea1d4149be38bbeaa10ae964cb8d0145e9 100644 (file)
 
 #ifdef __ASSEMBLER__
 
+#ifndef ARCH_HAS_HARD_TP
 /* Internal macro calling the linux kernel kuser_get_tls helper.
    Note that in thumb mode, a constant pool break is often out of range, so
    we always expand the constant inline.  */
-#ifdef __thumb2__
-# define GET_TLS_BODY                  \
+# ifdef __thumb2__
+#  define GET_TLS_BODY                 \
        movw    r0, #0x0fe0;            \
        movt    r0, #0xffff;            \
        blx     r0
-#else
-# define GET_TLS_BODY \
+# else
+#  define GET_TLS_BODY \
        mov     r0, #0xffff0fff;        /* Point to the high page.  */  \
        mov     lr, pc;                 /* Save our return address.  */ \
        sub     pc, r0, #31             /* Jump to the TLS entry.  */
-#endif
+# endif
 
 /* Helper to get the TLS base pointer.  Save LR in TMP, return in R0,
    and no other registers clobbered.  TMP may be LR itself to indicate
    that no save is necessary.  */
-#undef GET_TLS
-#define GET_TLS(TMP)                   \
+# undef GET_TLS
+# define GET_TLS(TMP)                  \
   .ifnc TMP, lr;                       \
        mov     TMP, lr;                \
        cfi_register (lr, TMP);         \
@@ -74,6 +75,7 @@
   .else;                               \
        GET_TLS_BODY;                   \
   .endif
+#endif /* ARCH_HAS_HARD_TP */
 
 /* Linux uses a negative return value to indicate syscall errors,
    unlike most Unices, which use the condition codes' carry flag.