summaryrefslogtreecommitdiff
path: root/ports/sysdeps/unix/sysv/linux/arm
diff options
context:
space:
mode:
authorRichard Henderson <rth@twiddle.net>2013-02-28 21:37:02 -0800
committerRichard Henderson <rth@twiddle.net>2013-03-06 07:47:21 -0800
commit79fd8731113e8402732190ff921aebaaef9218b0 (patch)
tree2e9b2d8f7c4441b6e7a9450ea3ab73c0087b615e /ports/sysdeps/unix/sysv/linux/arm
parent3377126b0a055e6addaa6bd69f51dd557d774b99 (diff)
downloadglibc-79fd8731113e8402732190ff921aebaaef9218b0.tar.gz
arm: Implement hard-tp for GET_TLS
Diffstat (limited to 'ports/sysdeps/unix/sysv/linux/arm')
-rw-r--r--ports/sysdeps/unix/sysv/linux/arm/aeabi_read_tp.S5
-rw-r--r--ports/sysdeps/unix/sysv/linux/arm/sysdep.h16
2 files changed, 13 insertions, 8 deletions
diff --git a/ports/sysdeps/unix/sysv/linux/arm/aeabi_read_tp.S b/ports/sysdeps/unix/sysv/linux/arm/aeabi_read_tp.S
index ecdc3228a3..21e322986a 100644
--- a/ports/sysdeps/unix/sysv/linux/arm/aeabi_read_tp.S
+++ b/ports/sysdeps/unix/sysv/linux/arm/aeabi_read_tp.S
@@ -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
diff --git a/ports/sysdeps/unix/sysv/linux/arm/sysdep.h b/ports/sysdeps/unix/sysv/linux/arm/sysdep.h
index f2ab5f589f..b195d8ea1d 100644
--- a/ports/sysdeps/unix/sysv/linux/arm/sysdep.h
+++ b/ports/sysdeps/unix/sysv/linux/arm/sysdep.h
@@ -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.