mirror of
git://sourceware.org/git/glibc.git
synced 2025-04-06 14:10:30 +08:00
arm: Implement hard-tp for GET_TLS
This commit is contained in:
parent
3377126b0a
commit
79fd873111
@ -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__.
|
||||
|
@ -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
|
||||
@ -187,10 +190,14 @@
|
||||
/* 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); \
|
||||
@ -201,6 +208,7 @@
|
||||
bl __aeabi_read_tp; \
|
||||
pop { r1, r2, r3, lr }; \
|
||||
cfi_restore_state
|
||||
# endif /* ARCH_HAS_HARD_TP */
|
||||
|
||||
#endif /* __ASSEMBLER__ */
|
||||
|
||||
|
@ -41,7 +41,10 @@
|
||||
|
||||
.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
|
||||
|
@ -45,26 +45,27 @@
|
||||
|
||||
#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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user