Merge pull request #2816 from xmcclure/profile-clean-0
[mono.git] / mono / mini / mini-arm-tls.S
1 /*
2  * mini-arm-tls.S: tls getters and setters for arm platforms
3  *
4  * Copyright 2015 Xamarin, Inc.
5          * Licensed under the MIT license. See LICENSE file in the project root for full license information.
6  */
7
8 #include <config.h>
9
10 #ifndef MONO_CROSS_COMPILE
11
12         /*
13          * The following thunks fetch the value corresponding to the key/offset
14          * passed in R0. These thunks don't do jumps to external code so execution
15          * within can be tracked. The tls value is returned in R0.
16          */
17
18 .macro DECLARE_GLOBAL_SYMBOL name
19 #ifdef TARGET_MACH
20         .global _\name
21 _\name:
22 #else
23         .global \name
24 \name:
25 #endif
26 .endm
27
28         .text
29 /* no .arch on clang. it only supports armv6+ anyway */
30 #ifndef TARGET_MACH
31         .arch armv5
32 #endif
33         .arm
34         .align 4
35
36 DECLARE_GLOBAL_SYMBOL mono_fast_get_tls_key
37 #if defined(__linux__)
38         mrc     p15, 0, r1, c13, c0, 3
39 #if defined(HAVE_KW_THREAD)
40         ldr     r0, [r1, r0]
41 #elif defined(TARGET_ANDROID)
42         ldr     r0, [r1, r0, lsl #2]
43 #endif
44         bx      lr
45 #elif defined(TARGET_IOS)
46         mrc     p15, 0, r1, c13, c0, 3
47         bic     r1, r1, #3
48         ldr     r0, [r1, r0, lsl #2]
49         bx      lr
50 #endif
51 DECLARE_GLOBAL_SYMBOL mono_fast_get_tls_key_end
52
53         /*
54          * The following thunks fetch the value corresponding to the key/offset
55          * passed in R0. These thunks are used in the unlikely cases where we determine
56          * at runtime that the current implementation is not accounted for.
57          */
58
59         .align 4
60 DECLARE_GLOBAL_SYMBOL mono_fallback_get_tls_key
61 #if defined(__linux__) && defined(HAVE_KW_THREAD) && defined(__ARM_EABI__)
62         push    {lr}
63         mov     r1, r0
64         bl      __aeabi_read_tp
65         ldr     r0, [r0, r1]
66         pop     {pc}
67 #elif defined(TARGET_IOS)
68         push    {r7, lr}
69         mov     r7, sp
70         bl      _pthread_getspecific
71         pop     {r7, pc}
72 #elif defined(TARGET_ANDROID)
73         push    {lr}
74         bl      pthread_getspecific
75         pop     {pc}
76 #endif
77         /*
78          * The following thunks set the value corresponding to the key/offset
79          * passed in R0. These thunks don't do jumps to external code so execution
80          * within can be tracked. The tls value is passed in R1.
81          */
82
83         .align 4
84 DECLARE_GLOBAL_SYMBOL mono_fast_set_tls_key
85 #if defined(__linux__)
86         mrc     p15, 0, r2, c13, c0, 3
87 #if defined(HAVE_KW_THREAD)
88         str     r1, [r2, r0]
89 #elif defined(TARGET_ANDROID)
90         str     r1, [r2, r0, lsl #2]
91 #endif
92         bx      lr
93 #elif defined(TARGET_IOS)
94         mrc     p15, 0, r2, c13, c0, 3
95         bic     r2, r2, #3
96         str     r1, [r2, r0, lsl #2]
97         bx      lr
98 #endif
99 DECLARE_GLOBAL_SYMBOL mono_fast_set_tls_key_end
100
101         /*
102          * The following thunks set the value corresponding to the key/offset
103          * passed in R0. These thunks are used in the unlikely cases where we determine
104          * at runtime that the current implementation is not accounted for.
105          */
106
107         .align 4
108 DECLARE_GLOBAL_SYMBOL mono_fallback_set_tls_key
109 #if defined(__linux__) && defined(HAVE_KW_THREAD) && defined(__ARM_EABI__)
110         push    {lr}
111         mov     r2, r0
112         bl      __aeabi_read_tp
113         str     r1, [r0, r2]
114         pop     {pc}
115 #elif defined(TARGET_IOS)
116         push    {r7, lr}
117         mov     r7, sp
118         bl      _pthread_setspecific
119         pop     {r7, pc}
120 #elif defined(TARGET_ANDROID)
121         push    {lr}
122         bl      pthread_setspecific
123         pop     {pc}
124 #endif
125
126
127         /* Additional tls getters/setters */
128
129 #if defined(TARGET_ANDROID)
130         .align 4
131 DECLARE_GLOBAL_SYMBOL mono_fast_get_tls_key2
132         bic     r0, r0, #0x80000000
133         mrc     15, 0, r1, cr13, cr0, #3
134         lsls    r0, r0, #3
135         ldr     r1, [r1, #4]
136         add     r0, r1
137         ldr     r0, [r0, #0x68]
138         bx      lr
139 DECLARE_GLOBAL_SYMBOL mono_fast_get_tls_key2_end
140
141         /*
142          * In order to use this fast setter we need to make sure that the key was
143          * already set at least once using the pthread api, otherwise it will not
144          * interwork with the api.
145          */
146         .align 4
147 DECLARE_GLOBAL_SYMBOL mono_fast_set_tls_key2
148         bic     r0, r0, #0x80000000
149         mrc     15, 0, r2, cr13, cr0, #3
150         lsls    r0, r0, #3
151         ldr     r2, [r2, #4]
152         add     r0, r2
153         str     r1, [r0, #0x68]
154         bx      lr
155 DECLARE_GLOBAL_SYMBOL mono_fast_set_tls_key2_end
156 #endif
157
158 #endif
159