Define XTABS to TAB3 on alpha to match Linux 4.16.
[glibc.git] / sysdeps / tile / __tls_get_addr.S
blob078f37750c49f9daf01b37af7e4efd237690fe31
1 /* Copyright (C) 2011-2018 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         {
41          LD_PTR r27, r27        /* r27 = THREAD_DTV() */
42          moveli r26, hw1_last(_rtld_local + TLS_GENERATION_OFFSET - .Llnk)
43         }
44         shl16insli r26, r26, hw0(_rtld_local + TLS_GENERATION_OFFSET - .Llnk)
45         {
46          ADD_PTR r25, r25, r26
47          LD_PTR r26, r0         /* r26 = ti_module */
48         }
49         LD_PTR r25, r25         /* r25 = DL(dl_tls_generation) */
50         {
51          LD_PTR r28, r27        /* r28 = THREAD_DTV()->counter */
52          ADDI_PTR r29, r0, __SIZEOF_POINTER__
53         }
54         {
55          LD_PTR r29, r29        /* r29 = ti_offset */
56          cmpeq r25, r28, r25    /* r25 nonzero if generation OK */
57          shli r28, r26, LOG_SIZEOF_DTV_T  /* byte index into dtv array */
58         }
59         {
60          beqz r25, .Lslowpath
61          cmpeqi r25, r26, -1    /* r25 nonzero if ti_module invalid */
62         }
63         {
64          bnez r25, .Lslowpath
65          ADD_PTR r28, r28, r27  /* pointer into module array */
66         }
67         LD_PTR r26, r28         /* r26 = module TLS pointer */
68         cmpeqi r25, r26, -1     /* check r26 == TLS_DTV_UNALLOCATED */
69         bnez r25, .Lslowpath
70         {
71          ADD_PTR r0, r26, r29
72          jrp lr
73         }
75 .Lslowpath:
76         {
77          st sp, lr
78          ADDLI_PTR r29, sp, - (25 * REGSIZE)
79         }
80         cfi_offset (lr, 0)
81         {
82          st r29, sp
83          ADDLI_PTR sp, sp, - (26 * REGSIZE)
84         }
85         cfi_def_cfa_offset (26 * REGSIZE)
86         ADDI_PTR r29, sp, (2 * REGSIZE)
87         { st r29, r1;  ADDI_PTR r29, r29, REGSIZE }
88         { st r29, r2;  ADDI_PTR r29, r29, REGSIZE }
89         { st r29, r3;  ADDI_PTR r29, r29, REGSIZE }
90         { st r29, r4;  ADDI_PTR r29, r29, REGSIZE }
91         { st r29, r5;  ADDI_PTR r29, r29, REGSIZE }
92         { st r29, r6;  ADDI_PTR r29, r29, REGSIZE }
93         { st r29, r7;  ADDI_PTR r29, r29, REGSIZE }
94         { st r29, r8;  ADDI_PTR r29, r29, REGSIZE }
95         { st r29, r9;  ADDI_PTR r29, r29, REGSIZE }
96         { st r29, r10; ADDI_PTR r29, r29, REGSIZE }
97         { st r29, r11; ADDI_PTR r29, r29, REGSIZE }
98         { st r29, r12; ADDI_PTR r29, r29, REGSIZE }
99         { st r29, r13; ADDI_PTR r29, r29, REGSIZE }
100         { st r29, r14; ADDI_PTR r29, r29, REGSIZE }
101         { st r29, r15; ADDI_PTR r29, r29, REGSIZE }
102         { st r29, r16; ADDI_PTR r29, r29, REGSIZE }
103         { st r29, r17; ADDI_PTR r29, r29, REGSIZE }
104         { st r29, r18; ADDI_PTR r29, r29, REGSIZE }
105         { st r29, r19; ADDI_PTR r29, r29, REGSIZE }
106         { st r29, r20; ADDI_PTR r29, r29, REGSIZE }
107         { st r29, r21; ADDI_PTR r29, r29, REGSIZE }
108         { st r29, r22; ADDI_PTR r29, r29, REGSIZE }
109         { st r29, r23; ADDI_PTR r29, r29, REGSIZE }
110         { st r29, r24; ADDI_PTR r29, r29, REGSIZE }
111         .hidden __tls_get_addr_slow
112         jal __tls_get_addr_slow
113         ADDI_PTR r29, sp, (2 * REGSIZE)
114         { ld r1,  r29; ADDI_PTR r29, r29, REGSIZE }
115         { ld r2,  r29; ADDI_PTR r29, r29, REGSIZE }
116         { ld r3,  r29; ADDI_PTR r29, r29, REGSIZE }
117         { ld r4,  r29; ADDI_PTR r29, r29, REGSIZE }
118         { ld r5,  r29; ADDI_PTR r29, r29, REGSIZE }
119         { ld r6,  r29; ADDI_PTR r29, r29, REGSIZE }
120         { ld r7,  r29; ADDI_PTR r29, r29, REGSIZE }
121         { ld r8,  r29; ADDI_PTR r29, r29, REGSIZE }
122         { ld r9,  r29; ADDI_PTR r29, r29, REGSIZE }
123         { ld r10, r29; ADDI_PTR r29, r29, REGSIZE }
124         { ld r11, r29; ADDI_PTR r29, r29, REGSIZE }
125         { ld r12, r29; ADDI_PTR r29, r29, REGSIZE }
126         { ld r13, r29; ADDI_PTR r29, r29, REGSIZE }
127         { ld r14, r29; ADDI_PTR r29, r29, REGSIZE }
128         { ld r15, r29; ADDI_PTR r29, r29, REGSIZE }
129         { ld r16, r29; ADDI_PTR r29, r29, REGSIZE }
130         { ld r17, r29; ADDI_PTR r29, r29, REGSIZE }
131         { ld r18, r29; ADDI_PTR r29, r29, REGSIZE }
132         { ld r19, r29; ADDI_PTR r29, r29, REGSIZE }
133         { ld r20, r29; ADDI_PTR r29, r29, REGSIZE }
134         { ld r21, r29; ADDI_PTR r29, r29, REGSIZE }
135         { ld r22, r29; ADDI_PTR r29, r29, REGSIZE }
136         { ld r23, r29; ADDI_PTR r29, r29, REGSIZE }
137         { ld r24, r29; ADDLI_PTR sp, sp, (26 * REGSIZE) }
138         cfi_def_cfa_offset (0)
139         ld lr, sp
140         jrp lr
141 END (__tls_get_addr)