Add sysdeps/ieee754/soft-fp.
[glibc.git] / sysdeps / arm / dl-tlsdesc.S
blob99d4b8327feda0f6d2326e54216b5bd4e76f8854
1 /* Thread-local storage handling in the ELF dynamic linker.  ARM version.
2    Copyright (C) 2006-2017 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library.  If not, see
17    <http://www.gnu.org/licenses/>.  */
19 #include <sysdep.h>
20 #include <arm-features.h>
21 #include <tls.h>
22 #include "tlsdesc.h"
24         .text
25         @ emit debug information with cfi
26         @ use arm-specific pseudos for unwinding itself
27         CFI_SECTIONS
28         .hidden _dl_tlsdesc_return
29         .global _dl_tlsdesc_return
30         .type   _dl_tlsdesc_return,#function
31         cfi_startproc
32         eabi_fnstart
33         .align 2
34 _dl_tlsdesc_return:
35         ldr     r0, [r0]
36         BX      (lr)
37         eabi_fnend
38         cfi_endproc
39         .size   _dl_tlsdesc_return, .-_dl_tlsdesc_return
41         .hidden _dl_tlsdesc_undefweak
42         .global _dl_tlsdesc_undefweak
43         .type   _dl_tlsdesc_undefweak,#function
44         cfi_startproc
45         eabi_fnstart
46         .align 2
47 _dl_tlsdesc_undefweak:
48         GET_TLS (r1)
49         rsb     r0, r0, #0
50         BX      (lr)
51         cfi_endproc
52         eabi_fnend
53         .size   _dl_tlsdesc_undefweak, .-_dl_tlsdesc_undefweak
55 #ifdef SHARED
56         .hidden _dl_tlsdesc_dynamic
57         .global _dl_tlsdesc_dynamic
58         .type   _dl_tlsdesc_dynamic,#function
62         The assembly code that follows is a rendition of the following
63         C code, hand-optimized a little bit.
65 ptrdiff_t
66 _dl_tlsdesc_dynamic(struct tlsdesc *tdp)
68        struct tlsdesc_dynamic_arg *td = tdp->argument.pointer;
69        dtv_t *dtv = (dtv_t *)THREAD_DTV();
70        if (__builtin_expect (td->gen_count <= dtv[0].counter
71                              && dtv[td->tlsinfo.ti_module].pointer.val
72                                 != TLS_DTV_UNALLOCATED,
73                              1))
74                return dtv[td->tlsinfo.ti_module].pointer.val +
75                        td->tlsinfo.ti_offset - __builtin_thread_pointer();
77        return __tls_get_addr (&td->tlsinfo) - __builtin_thread_pointer();
81         cfi_startproc
82         eabi_fnstart
83         .align 2
84 _dl_tlsdesc_dynamic:
85         /* Our calling convention is to clobber r0, r1 and the processor
86            flags.  All others that are modified must be saved */
87         eabi_save ({r2,r3,r4,lr})
88         push    {r2,r3,r4,lr}
89         cfi_adjust_cfa_offset (16)
90         cfi_rel_offset (r2,0)
91         cfi_rel_offset (r3,4)
92         cfi_rel_offset (r4,8)
93         cfi_rel_offset (lr,12)
94         ldr     r1, [r0] /* td */
95         GET_TLS (lr)
96         mov     r4, r0 /* r4 = tp */
97         ldr     r0, [r0]
98         ldr     r2, [r1, #8] /* gen_count */
99         ldr     r3, [r0]
100         cmp     r2, r3
101         bhi     1f
102         ldr     r3, [r1]
103 #ifndef ARM_NO_INDEX_REGISTER
104         ldr     r2, [r0, r3, lsl #3]
105 #else
106         add     lr, r0, r3, lsl #3
107         ldr     r2, [lr]
108 #endif
109         cmn     r2, #1
110         ittt    ne
111         ldrne   r3, [r1, #4]
112         addne   r3, r2, r3
113         rsbne   r0, r4, r3
114         bne     2f
115 1:      mov     r0, r1
116         bl      __tls_get_addr
117         rsb     r0, r4, r0
119 #if ((defined (__ARM_ARCH_4T__) && defined (__THUMB_INTERWORK__)) \
120      || defined (ARM_ALWAYS_BX))
121         pop     {r2,r3,r4, lr}
122         cfi_adjust_cfa_offset (-16)
123         cfi_restore (lr)
124         cfi_restore (r4)
125         cfi_restore (r3)
126         cfi_restore (r2)
127         bx      lr
128 #else
129         pop     {r2,r3,r4, pc}
130 #endif
131         eabi_fnend
132         cfi_endproc
133         .size   _dl_tlsdesc_dynamic, .-_dl_tlsdesc_dynamic
134 #endif /* SHARED */