]> git.ipfire.org Git - thirdparty/glibc.git/blob - ports/sysdeps/tile/__tls_get_addr.S
Update copyright notices with scripts/update-copyrights
[thirdparty/glibc.git] / ports / sysdeps / tile / __tls_get_addr.S
1 /* Copyright (C) 2011-2014 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
4
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.
9
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.
14
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/>. */
18
19 #include <sysdep.h>
20 #include <tls.h>
21 #include <bits/wordsize.h>
22
23 #if __WORDSIZE == 64
24 #define LOG_SIZEOF_DTV_T 4
25 #else
26 #define LOG_SIZEOF_DTV_T 3
27 #endif
28
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. */
32
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 }
85
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)