about summary refs log tree commit diff
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/atomic_arch.h21
-rw-r--r--arch/arm/pthread_arch.h16
2 files changed, 23 insertions, 14 deletions
diff --git a/arch/arm/atomic_arch.h b/arch/arm/atomic_arch.h
index 706fa1f2..d6af84d0 100644
--- a/arch/arm/atomic_arch.h
+++ b/arch/arm/atomic_arch.h
@@ -1,5 +1,11 @@
-__attribute__((__visibility__("hidden")))
-extern const void *__arm_atomics[3]; /* gettp, cas, barrier */
+#if __ARM_ARCH_4__ || __ARM_ARCH_4T__ || __ARM_ARCH == 4
+#define BLX "mov lr,pc\n\tbx"
+#else
+#define BLX "blx"
+#endif
+
+extern uintptr_t __attribute__((__visibility__("hidden")))
+	__a_cas_ptr, __a_barrier_ptr;
 
 #if ((__ARM_ARCH_6__ || __ARM_ARCH_6K__ || __ARM_ARCH_6ZK__) && !__thumb__) \
  || __ARM_ARCH_7A__ || __ARM_ARCH_7R__ ||  __ARM_ARCH >= 7
@@ -42,11 +48,12 @@ static inline int a_cas(volatile int *p, int t, int s)
 		register int r0 __asm__("r0") = t;
 		register int r1 __asm__("r1") = s;
 		register volatile int *r2 __asm__("r2") = p;
+		register uintptr_t r3 __asm__("r3") = __a_cas_ptr;
 		int old;
 		__asm__ __volatile__ (
-			"bl __a_cas"
-			: "+r"(r0) : "r"(r1), "r"(r2)
-			: "memory", "r3", "lr", "ip", "cc" );
+			BLX " r3"
+			: "+r"(r0), "+r"(r3) : "r"(r1), "r"(r2)
+			: "memory", "lr", "ip", "cc" );
 		if (!r0) return t;
 		if ((old=*p)!=t) return old;
 	}
@@ -58,8 +65,8 @@ static inline int a_cas(volatile int *p, int t, int s)
 #define a_barrier a_barrier
 static inline void a_barrier()
 {
-	__asm__ __volatile__("bl __a_barrier"
-		: : : "memory", "cc", "ip", "lr" );
+	register uintptr_t ip __asm__("ip") = __a_barrier_ptr;
+	__asm__ __volatile__( BLX " ip" : "+r"(ip) : : "memory", "cc", "lr" );
 }
 #endif
 
diff --git a/arch/arm/pthread_arch.h b/arch/arm/pthread_arch.h
index 8b8a7fb6..197752ef 100644
--- a/arch/arm/pthread_arch.h
+++ b/arch/arm/pthread_arch.h
@@ -10,15 +10,17 @@ static inline pthread_t __pthread_self()
 
 #else
 
-static inline pthread_t __pthread_self()
-{
-#ifdef __clang__
-	char *p;
-	__asm__ __volatile__ ( "bl __a_gettp\n\tmov %0,r0" : "=r"(p) : : "cc", "r0", "lr" );
+#if __ARM_ARCH_4__ || __ARM_ARCH_4T__ || __ARM_ARCH == 4
+#define BLX "mov lr,pc\n\tbx"
 #else
-	register char *p __asm__("r0");
-	__asm__ __volatile__ ( "bl __a_gettp" : "=r"(p) : : "cc", "lr" );
+#define BLX "blx"
 #endif
+
+static inline pthread_t __pthread_self()
+{
+	extern uintptr_t __attribute__((__visibility__("hidden"))) __a_gettp_ptr;
+	register uintptr_t p __asm__("r0");
+	__asm__ __volatile__ ( BLX " %1" : "=r"(p) : "r"(__a_gettp_ptr) : "cc", "lr" );
 	return (void *)(p+8-sizeof(struct pthread));
 }