* mini-arm-tls.S: tls getters and setters for arm platforms
*
* Copyright 2015 Xamarin, Inc.
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
*/
#include <config.h>
* within can be tracked. The tls value is returned in R0.
*/
+.macro DECLARE_GLOBAL_SYMBOL name
+#ifdef TARGET_MACH
+ .global _\name
+_\name:
+#else
+ .global \name
+\name:
+#endif
+.endm
+
.text
/* no .arch on clang. it only supports armv6+ anyway */
#ifndef TARGET_MACH
#endif
.arm
.align 4
-#ifdef TARGET_MACH
- .global _mono_fast_get_tls_key
-_mono_fast_get_tls_key :
-#else
- .global mono_fast_get_tls_key
-mono_fast_get_tls_key :
-#endif
+
+DECLARE_GLOBAL_SYMBOL mono_fast_get_tls_key
#if defined(__linux__)
mrc p15, 0, r1, c13, c0, 3
#if defined(HAVE_KW_THREAD)
ldr r0, [r1, r0, lsl #2]
bx lr
#endif
+DECLARE_GLOBAL_SYMBOL mono_fast_get_tls_key_end
/*
* The following thunks fetch the value corresponding to the key/offset
*/
.align 4
-#ifdef TARGET_MACH
- .global _mono_fallback_get_tls_key
-_mono_fallback_get_tls_key :
-#else
- .global mono_fallback_get_tls_key
-mono_fallback_get_tls_key :
-#endif
-#if defined(__linux__)
- mov r1, r0
- mvn r0, #0xf000
- sub r0, r0, #31
+DECLARE_GLOBAL_SYMBOL mono_fallback_get_tls_key
+#if defined(__linux__) && defined(HAVE_KW_THREAD) && defined(__ARM_EABI__)
push {lr}
- blx r0
-#if defined(HAVE_KW_THREAD)
+ mov r1, r0
+ bl __aeabi_read_tp
ldr r0, [r0, r1]
-#elif defined(TARGET_ANDROID)
- ldr r0, [r0, r1, lsl #2]
-#endif
pop {pc}
#elif defined(TARGET_IOS)
- push {lr}
+ push {r7, lr}
+ mov r7, sp
bl _pthread_getspecific
+ pop {r7, pc}
+#elif defined(TARGET_ANDROID)
+ push {lr}
+ bl pthread_getspecific
pop {pc}
#endif
-
/*
* The following thunks set the value corresponding to the key/offset
* passed in R0. These thunks don't do jumps to external code so execution
*/
.align 4
-#ifdef TARGET_MACH
- .global _mono_fast_set_tls_key
-_mono_fast_set_tls_key :
-#else
- .global mono_fast_set_tls_key
-mono_fast_set_tls_key :
-#endif
+DECLARE_GLOBAL_SYMBOL mono_fast_set_tls_key
#if defined(__linux__)
mrc p15, 0, r2, c13, c0, 3
#if defined(HAVE_KW_THREAD)
str r1, [r2, r0, lsl #2]
bx lr
#endif
+DECLARE_GLOBAL_SYMBOL mono_fast_set_tls_key_end
/*
* The following thunks set the value corresponding to the key/offset
*/
.align 4
-#ifdef TARGET_MACH
- .global _mono_fallback_set_tls_key
-_mono_fallback_set_tls_key :
-#else
- .global mono_fallback_set_tls_key
-mono_fallback_set_tls_key :
-#endif
-#if defined(__linux__)
- mov r2, r0
- mvn r0, #0xf000
- sub r0, r0, #31
+DECLARE_GLOBAL_SYMBOL mono_fallback_set_tls_key
+#if defined(__linux__) && defined(HAVE_KW_THREAD) && defined(__ARM_EABI__)
push {lr}
- blx r0
-#if defined(HAVE_KW_THREAD)
+ mov r2, r0
+ bl __aeabi_read_tp
str r1, [r0, r2]
-#elif defined(TARGET_ANDROID)
- str r1, [r0, r2, lsl #2]
-#endif
pop {pc}
#elif defined(TARGET_IOS)
- push {lr}
+ push {r7, lr}
+ mov r7, sp
bl _pthread_setspecific
+ pop {r7, pc}
+#elif defined(TARGET_ANDROID)
+ push {lr}
+ bl pthread_setspecific
pop {pc}
#endif
+
+ /* Additional tls getters/setters */
+
+#if defined(TARGET_ANDROID)
+ .align 4
+DECLARE_GLOBAL_SYMBOL mono_fast_get_tls_key2
+ bic r0, r0, #0x80000000
+ mrc 15, 0, r1, cr13, cr0, #3
+ lsls r0, r0, #3
+ ldr r1, [r1, #4]
+ add r0, r1
+ ldr r0, [r0, #0x68]
+ bx lr
+DECLARE_GLOBAL_SYMBOL mono_fast_get_tls_key2_end
+
+ /*
+ * In order to use this fast setter we need to make sure that the key was
+ * already set at least once using the pthread api, otherwise it will not
+ * interwork with the api.
+ */
+ .align 4
+DECLARE_GLOBAL_SYMBOL mono_fast_set_tls_key2
+ bic r0, r0, #0x80000000
+ mrc 15, 0, r2, cr13, cr0, #3
+ lsls r0, r0, #3
+ ldr r2, [r2, #4]
+ add r0, r2
+ str r1, [r0, #0x68]
+ bx lr
+DECLARE_GLOBAL_SYMBOL mono_fast_set_tls_key2_end
+#endif
+
#endif