Merge pull request #1952 from esdrubal/proc_name
[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  */
6
7 #include <config.h>
8
9 #ifndef MONO_CROSS_COMPILE
10
11         /*
12          * The following thunks fetch the value corresponding to the key/offset
13          * passed in R0. These thunks don't do jumps to external code so execution
14          * within can be tracked. The tls value is returned in R0.
15          */
16
17 .macro DECLARE_GLOBAL_SYMBOL name
18 #ifdef TARGET_MACH
19         .global _\name
20 _\name:
21 #else
22         .global \name
23 \name:
24 #endif
25 .endm
26
27         .text
28 /* no .arch on clang. it only supports armv6+ anyway */
29 #ifndef TARGET_MACH
30         .arch armv5
31 #endif
32         .arm
33         .align 4
34
35 DECLARE_GLOBAL_SYMBOL mono_fast_get_tls_key
36 #if defined(__linux__)
37         mrc     p15, 0, r1, c13, c0, 3
38 #if defined(HAVE_KW_THREAD)
39         ldr     r0, [r1, r0]
40 #elif defined(TARGET_ANDROID)
41         ldr     r0, [r1, r0, lsl #2]
42 #endif
43         bx      lr
44 #elif defined(TARGET_IOS)
45         mrc     p15, 0, r1, c13, c0, 3
46         bic     r1, r1, #3
47         ldr     r0, [r1, r0, lsl #2]
48         bx      lr
49 #endif
50 DECLARE_GLOBAL_SYMBOL mono_fast_get_tls_key_end
51
52         /*
53          * The following thunks fetch the value corresponding to the key/offset
54          * passed in R0. These thunks are used in the unlikely cases where we determine
55          * at runtime that the current implementation is not accounted for.
56          */
57
58         .align 4
59 DECLARE_GLOBAL_SYMBOL mono_fallback_get_tls_key
60 #if defined(__linux__)
61         mov     r1, r0
62         mvn     r0, #0xf000
63         sub     r0, r0, #31
64         push    {lr}
65         blx     r0
66 #if defined(HAVE_KW_THREAD)
67         ldr     r0, [r0, r1]
68 #elif defined(TARGET_ANDROID)
69         ldr     r0, [r0, r1, lsl #2]
70 #endif
71         pop     {pc}
72 #elif defined(TARGET_IOS)
73         push    {lr}
74         bl      _pthread_getspecific
75         pop     {pc}
76 #endif
77
78         /*
79          * The following thunks set the value corresponding to the key/offset
80          * passed in R0. These thunks don't do jumps to external code so execution
81          * within can be tracked. The tls value is passed in R1.
82          */
83
84         .align 4
85 DECLARE_GLOBAL_SYMBOL mono_fast_set_tls_key
86 #if defined(__linux__)
87         mrc     p15, 0, r2, c13, c0, 3
88 #if defined(HAVE_KW_THREAD)
89         str     r1, [r2, r0]
90 #elif defined(TARGET_ANDROID)
91         str     r1, [r2, r0, lsl #2]
92 #endif
93         bx      lr
94 #elif defined(TARGET_IOS)
95         mrc     p15, 0, r2, c13, c0, 3
96         bic     r2, r2, #3
97         str     r1, [r2, r0, lsl #2]
98         bx      lr
99 #endif
100 DECLARE_GLOBAL_SYMBOL mono_fast_set_tls_key_end
101
102         /*
103          * The following thunks set the value corresponding to the key/offset
104          * passed in R0. These thunks are used in the unlikely cases where we determine
105          * at runtime that the current implementation is not accounted for.
106          */
107
108         .align 4
109 DECLARE_GLOBAL_SYMBOL mono_fallback_set_tls_key
110 #if defined(__linux__)
111         mov     r2, r0
112         mvn     r0, #0xf000
113         sub     r0, r0, #31
114         push    {lr}
115         blx     r0
116 #if defined(HAVE_KW_THREAD)
117         str     r1, [r0, r2]
118 #elif defined(TARGET_ANDROID)
119         str     r1, [r0, r2, lsl #2]
120 #endif
121         pop     {pc}
122 #elif defined(TARGET_IOS)
123         push    {lr}
124         bl      _pthread_setspecific
125         pop     {pc}
126 #endif
127
128 #endif
129