hurd: Break errnos.d / libc-modules.h dependency loop
[glibc.git] / sysdeps / tile / __tls_get_addr.S
blob089dccfeaaaaa8a6c87d8123d362ea626544e6a9
1 /* Copyright (C) 2011-2016 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
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 <tls.h>
21 #include <bits/wordsize.h>
23 #if __WORDSIZE == 64
24 #define LOG_SIZEOF_DTV_T 4
25 #else
26 #define LOG_SIZEOF_DTV_T 3
27 #endif
29 /* On entry, r0 points to two words, the module and the offset.
30    On return, r0 holds the pointer to the relevant TLS memory.
31    Only registers r25..r29 are clobbered by the call.  */
33         .text
34 ENTRY (__tls_get_addr)
35         {
36          lnk r25
37          ADDI_PTR r27, tp, DTV_OFFSET
38         }
39 .Llnk:
40 #ifdef __tilegx__
41         {
42          LD_PTR r27, r27        /* r27 = THREAD_DTV() */
43          moveli r26, hw1_last(_rtld_local + TLS_GENERATION_OFFSET - .Llnk)
44         }
45         shl16insli r26, r26, hw0(_rtld_local + TLS_GENERATION_OFFSET - .Llnk)
46         {
47          ADD_PTR r25, r25, r26
48          LD_PTR r26, r0         /* r26 = ti_module */
49         }
50 #else
51         {
52          LD_PTR r27, r27        /* r27 = THREAD_DTV() */
53          addli r25, r25, lo16(_rtld_local + TLS_GENERATION_OFFSET - .Llnk)
54         }
55         {
56          auli r25, r25, ha16(_rtld_local + TLS_GENERATION_OFFSET - .Llnk)
57          LD_PTR r26, r0         /* r26 = ti_module */
58         }
59 #endif
60         LD_PTR r25, r25         /* r25 = DL(dl_tls_generation) */
61         {
62          LD_PTR r28, r27        /* r28 = THREAD_DTV()->counter */
63          ADDI_PTR r29, r0, __SIZEOF_POINTER__
64         }
65         {
66          LD_PTR r29, r29        /* r29 = ti_offset */
67          CMPEQ r25, r28, r25    /* r25 nonzero if generation OK */
68          shli r28, r26, LOG_SIZEOF_DTV_T  /* byte index into dtv array */
69         }
70         {
71          BEQZ r25, .Lslowpath
72          CMPEQI r25, r26, -1    /* r25 nonzero if ti_module invalid */
73         }
74         {
75          BNEZ r25, .Lslowpath
76          ADD_PTR r28, r28, r27  /* pointer into module array */
77         }
78         LD_PTR r26, r28         /* r26 = module TLS pointer */
79         CMPEQI r25, r26, -1     /* check r26 == TLS_DTV_UNALLOCATED */
80         BNEZ r25, .Lslowpath
81         {
82          ADD_PTR r0, r26, r29
83          jrp lr
84         }
86 .Lslowpath:
87         {
88          ST sp, lr
89          ADDLI_PTR r29, sp, - (25 * REGSIZE)
90         }
91         cfi_offset (lr, 0)
92         {
93          ST r29, sp
94          ADDLI_PTR sp, sp, - (26 * REGSIZE)
95         }
96         cfi_def_cfa_offset (26 * REGSIZE)
97         ADDI_PTR r29, sp, (2 * REGSIZE)
98         { ST r29, r1;  ADDI_PTR r29, r29, REGSIZE }
99         { ST r29, r2;  ADDI_PTR r29, r29, REGSIZE }
100         { ST r29, r3;  ADDI_PTR r29, r29, REGSIZE }
101         { ST r29, r4;  ADDI_PTR r29, r29, REGSIZE }
102         { ST r29, r5;  ADDI_PTR r29, r29, REGSIZE }
103         { ST r29, r6;  ADDI_PTR r29, r29, REGSIZE }
104         { ST r29, r7;  ADDI_PTR r29, r29, REGSIZE }
105         { ST r29, r8;  ADDI_PTR r29, r29, REGSIZE }
106         { ST r29, r9;  ADDI_PTR r29, r29, REGSIZE }
107         { ST r29, r10; ADDI_PTR r29, r29, REGSIZE }
108         { ST r29, r11; ADDI_PTR r29, r29, REGSIZE }
109         { ST r29, r12; ADDI_PTR r29, r29, REGSIZE }
110         { ST r29, r13; ADDI_PTR r29, r29, REGSIZE }
111         { ST r29, r14; ADDI_PTR r29, r29, REGSIZE }
112         { ST r29, r15; ADDI_PTR r29, r29, REGSIZE }
113         { ST r29, r16; ADDI_PTR r29, r29, REGSIZE }
114         { ST r29, r17; ADDI_PTR r29, r29, REGSIZE }
115         { ST r29, r18; ADDI_PTR r29, r29, REGSIZE }
116         { ST r29, r19; ADDI_PTR r29, r29, REGSIZE }
117         { ST r29, r20; ADDI_PTR r29, r29, REGSIZE }
118         { ST r29, r21; ADDI_PTR r29, r29, REGSIZE }
119         { ST r29, r22; ADDI_PTR r29, r29, REGSIZE }
120         { ST r29, r23; ADDI_PTR r29, r29, REGSIZE }
121         { ST r29, r24; ADDI_PTR r29, r29, REGSIZE }
122         .hidden __tls_get_addr_slow
123         jal __tls_get_addr_slow
124         ADDI_PTR r29, sp, (2 * REGSIZE)
125         { LD r1,  r29; ADDI_PTR r29, r29, REGSIZE }
126         { LD r2,  r29; ADDI_PTR r29, r29, REGSIZE }
127         { LD r3,  r29; ADDI_PTR r29, r29, REGSIZE }
128         { LD r4,  r29; ADDI_PTR r29, r29, REGSIZE }
129         { LD r5,  r29; ADDI_PTR r29, r29, REGSIZE }
130         { LD r6,  r29; ADDI_PTR r29, r29, REGSIZE }
131         { LD r7,  r29; ADDI_PTR r29, r29, REGSIZE }
132         { LD r8,  r29; ADDI_PTR r29, r29, REGSIZE }
133         { LD r9,  r29; ADDI_PTR r29, r29, REGSIZE }
134         { LD r10, r29; ADDI_PTR r29, r29, REGSIZE }
135         { LD r11, r29; ADDI_PTR r29, r29, REGSIZE }
136         { LD r12, r29; ADDI_PTR r29, r29, REGSIZE }
137         { LD r13, r29; ADDI_PTR r29, r29, REGSIZE }
138         { LD r14, r29; ADDI_PTR r29, r29, REGSIZE }
139         { LD r15, r29; ADDI_PTR r29, r29, REGSIZE }
140         { LD r16, r29; ADDI_PTR r29, r29, REGSIZE }
141         { LD r17, r29; ADDI_PTR r29, r29, REGSIZE }
142         { LD r18, r29; ADDI_PTR r29, r29, REGSIZE }
143         { LD r19, r29; ADDI_PTR r29, r29, REGSIZE }
144         { LD r20, r29; ADDI_PTR r29, r29, REGSIZE }
145         { LD r21, r29; ADDI_PTR r29, r29, REGSIZE }
146         { LD r22, r29; ADDI_PTR r29, r29, REGSIZE }
147         { LD r23, r29; ADDI_PTR r29, r29, REGSIZE }
148         { LD r24, r29; ADDLI_PTR sp, sp, (26 * REGSIZE) }
149         cfi_def_cfa_offset (0)
150         LD lr, sp
151         jrp lr
152 END (__tls_get_addr)