1 | /* strchr (str, ch) -- Return pointer to first occurrence of CH in STR. |
2 | For SPARC v7. |
3 | Copyright (C) 1996-2024 Free Software Foundation, Inc. |
4 | This file is part of the GNU C Library. |
5 | |
6 | The GNU C Library is free software; you can redistribute it and/or |
7 | modify it under the terms of the GNU Lesser General Public |
8 | License as published by the Free Software Foundation; either |
9 | version 2.1 of the License, or (at your option) any later version. |
10 | |
11 | The GNU C Library is distributed in the hope that it will be useful, |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | Lesser General Public License for more details. |
15 | |
16 | You should have received a copy of the GNU Lesser General Public |
17 | License along with the GNU C Library; if not, see |
18 | <https://www.gnu.org/licenses/>. */ |
19 | |
20 | #include <sysdep.h> |
21 | |
22 | /* Normally, this uses ((xword - 0x01010101) & 0x80808080) test |
23 | to find out if any byte in xword could be zero. This is fast, but |
24 | also gives false alarm for any byte in range 0x81-0xff. It does |
25 | not matter for correctness, as if this test tells us there could |
26 | be some zero byte, we check it byte by byte, but if bytes with |
27 | high bits set are common in the strings, then this will give poor |
28 | performance. You can #define EIGHTBIT_NOT_RARE and the algorithm |
29 | will use one tick slower, but more precise test |
30 | ((xword - 0x01010101) & (~xword) & 0x80808080), |
31 | which does not give any false alarms (but if some bits are set, |
32 | one cannot assume from it which bytes are zero and which are not). |
33 | It is yet to be measured, what is the correct default for glibc |
34 | in these days for an average user. |
35 | */ |
36 | |
37 | .text |
38 | .align 4 |
39 | ENTRY(strchr) |
40 | andcc %o1, 0xff, %o1 |
41 | be 12f |
42 | sll %o1, 8, %o2 |
43 | andcc %o0, 3, %g0 |
44 | or %o1, %o2, %o2 |
45 | sethi %hi(0x80808080), %o4 |
46 | sll %o2, 16, %o3 |
47 | be 13f |
48 | or %o3, %o2, %g2 |
49 | |
50 | ldub [%o0], %g4 |
51 | cmp %g4, %o1 |
52 | be 11f |
53 | add %o0, 1, %o0 |
54 | cmp %g4, 0 |
55 | be 9f |
56 | andcc %o0, 3, %g0 |
57 | be 4f |
58 | or %o4, %lo(0x80808080), %o3 |
59 | ldub [%o0], %g4 |
60 | cmp %g4, %o1 |
61 | be 11f |
62 | add %o0, 1, %o0 |
63 | cmp %g4, 0 |
64 | be 9f |
65 | andcc %o0, 3, %g0 |
66 | be 5f |
67 | sethi %hi(0x01010101), %o5 |
68 | ldub [%o0], %g4 |
69 | cmp %g4, %o1 |
70 | be 11f |
71 | add %o0, 1, %o0 |
72 | cmp %g4, 0 |
73 | be 9f |
74 | or %o5, %lo(0x01010101), %o2 |
75 | b 6f |
76 | ld [%o0], %g4 |
77 | 11: retl |
78 | sub %o0, 1, %o0 |
79 | |
80 | 13: or %o4, %lo(0x80808080), %o3 |
81 | 4: sethi %hi(0x01010101), %o5 |
82 | 5: or %o5, %lo(0x01010101), %o2 |
83 | 7: ld [%o0], %g4 |
84 | 6: xor %g4, %g2, %g5 |
85 | sub %g4, %o2, %o4 |
86 | #ifdef EIGHTBIT_NOT_RARE |
87 | sub %g5, %o2, %g6 |
88 | andn %o4, %g4, %o4 |
89 | andn %g6, %g5, %g5 |
90 | #else |
91 | sub %g5, %o2, %g5 |
92 | #endif |
93 | or %g5, %o4, %o4 |
94 | andcc %o4, %o3, %g0 |
95 | be 7b |
96 | add %o0, 4, %o0 |
97 | |
98 | /* Check every byte. */ |
99 | 8: srl %g4, 24, %g5 |
100 | 7: andcc %g5, 0xff, %g5 |
101 | be 9f |
102 | cmp %g5, %o1 |
103 | be 4f |
104 | srl %g4, 16, %g5 |
105 | andcc %g5, 0xff, %g5 |
106 | be 9f |
107 | cmp %g5, %o1 |
108 | be 3f |
109 | srl %g4, 8, %g5 |
110 | andcc %g5, 0xff, %g5 |
111 | be 9f |
112 | cmp %g5, %o1 |
113 | be 2f |
114 | andcc %g4, 0xff, %g5 |
115 | be 9f |
116 | cmp %g5, %o1 |
117 | bne,a 6b |
118 | ld [%o0], %g4 |
119 | retl |
120 | sub %o0, 1, %o0 |
121 | 2: retl |
122 | sub %o0, 2, %o0 |
123 | 3: retl |
124 | sub %o0, 3, %o0 |
125 | 4: retl |
126 | sub %o0, 4, %o0 |
127 | 9: retl |
128 | clr %o0 |
129 | |
130 | 11: ldub [%o0], %o5 |
131 | cmp %o5, 0 |
132 | be 1f |
133 | add %o0, 1, %o0 |
134 | andcc %o0, 3, %g0 |
135 | be 4f |
136 | or %o4, %lo(0x80808080), %o3 |
137 | ldub [%o0], %o5 |
138 | cmp %o5, 0 |
139 | be 1f |
140 | add %o0, 1, %o0 |
141 | andcc %o0, 3, %g0 |
142 | be 5f |
143 | sethi %hi(0x01010101), %o4 |
144 | ldub [%o0], %o5 |
145 | cmp %o5, 0 |
146 | be 1f |
147 | add %o0, 1, %o0 |
148 | b 6f |
149 | or %o4, %lo(0x01010101), %o2 |
150 | 1: retl |
151 | sub %o0, 1, %o0 |
152 | |
153 | 12: andcc %o0, 3, %g0 |
154 | bne 11b |
155 | sethi %hi(0x80808080), %o4 |
156 | or %o4, %lo(0x80808080), %o3 |
157 | 4: sethi %hi(0x01010101), %o4 |
158 | 5: or %o4, %lo(0x01010101), %o2 |
159 | 6: ld [%o0], %o5 |
160 | 7: sub %o5, %o2, %o4 |
161 | #ifdef EIGHTBIT_NOT_RARE |
162 | andn %o4, %o5, %o4 |
163 | #endif |
164 | andcc %o4, %o3, %g0 |
165 | be 6b |
166 | add %o0, 4, %o0 |
167 | |
168 | /* Check every byte. */ |
169 | srl %o5, 24, %g5 |
170 | andcc %g5, 0xff, %g0 |
171 | be 8f |
172 | add %o0, -4, %o4 |
173 | srl %o5, 16, %g5 |
174 | andcc %g5, 0xff, %g0 |
175 | be 8f |
176 | add %o4, 1, %o4 |
177 | srl %o5, 8, %g5 |
178 | andcc %g5, 0xff, %g0 |
179 | be 8f |
180 | add %o4, 1, %o4 |
181 | andcc %o5, 0xff, %g0 |
182 | bne,a 7b |
183 | ld [%o0], %o5 |
184 | add %o4, 1, %o4 |
185 | 8: retl |
186 | mov %o4, %o0 |
187 | |
188 | 13: ldub [%o0], %g4 |
189 | cmp %g4, %o1 |
190 | add %o0, 1, %o0 |
191 | be,a 1f |
192 | sub %o0, 1, %o5 |
193 | cmp %g4, 0 |
194 | be 9f |
195 | 1: andcc %o0, 3, %g0 |
196 | be 4f |
197 | or %o4, %lo(0x80808080), %o3 |
198 | ldub [%o0], %g4 |
199 | cmp %g4, %o1 |
200 | add %o0, 1, %o0 |
201 | be,a 1f |
202 | sub %o0, 1, %o5 |
203 | cmp %g4, 0 |
204 | be 9f |
205 | 1: andcc %o0, 3, %g0 |
206 | be 5f |
207 | sethi %hi(0x01010101), %o4 |
208 | ldub [%o0], %g4 |
209 | cmp %g4, %o1 |
210 | add %o0, 1, %o0 |
211 | be,a 1f |
212 | sub %o0, 1, %o5 |
213 | cmp %g4, 0 |
214 | be 9f |
215 | 1: or %o4, %lo(0x01010101), %o2 |
216 | b 7f |
217 | ld [%o0], %g4 |
218 | END(strchr) |
219 | |
220 | ENTRY(strrchr) |
221 | andcc %o1, 0xff, %o1 |
222 | clr %o5 |
223 | be 12b |
224 | sll %o1, 8, %o2 |
225 | andcc %o0, 3, %g0 |
226 | or %o1, %o2, %o2 |
227 | sethi %hi(0x80808080), %o4 |
228 | sll %o2, 16, %o3 |
229 | bne 13b |
230 | or %o3, %o2, %g2 |
231 | or %o4, %lo(0x80808080), %o3 |
232 | 4: sethi %hi(0x01010101), %o4 |
233 | 5: or %o4, %lo(0x01010101), %o2 |
234 | 6: ld [%o0], %g4 |
235 | 7: xor %g4, %g2, %g5 |
236 | sub %g4, %o2, %o4 |
237 | #ifdef EIGHTBIT_NOT_RARE |
238 | sub %g5, %o2, %g6 |
239 | andn %o4, %g4, %o4 |
240 | andn %g6, %g5, %g5 |
241 | #else |
242 | sub %g5, %o2, %g5 |
243 | #endif |
244 | or %g5, %o4, %o4 |
245 | andcc %o4, %o3, %g0 |
246 | be 6b |
247 | add %o0, 4, %o0 |
248 | |
249 | /* Check every byte. */ |
250 | 3: srl %g4, 24, %g5 |
251 | 8: andcc %g5, 0xff, %g5 |
252 | be 9f |
253 | cmp %g5, %o1 |
254 | be,a 1f |
255 | sub %o0, 4, %o5 |
256 | 1: srl %g4, 16, %g5 |
257 | andcc %g5, 0xff, %g5 |
258 | be 9f |
259 | cmp %g5, %o1 |
260 | be,a 1f |
261 | sub %o0, 3, %o5 |
262 | 1: srl %g4, 8, %g5 |
263 | andcc %g5, 0xff, %g5 |
264 | be 9f |
265 | cmp %g5, %o1 |
266 | be,a 1f |
267 | sub %o0, 2, %o5 |
268 | 1: andcc %g4, 0xff, %g5 |
269 | be 9f |
270 | cmp %g5, %o1 |
271 | be,a 1f |
272 | sub %o0, 1, %o5 |
273 | 1: b 7b |
274 | ld [%o0], %g4 |
275 | 9: retl |
276 | mov %o5, %o0 |
277 | END(strrchr) |
278 | |
279 | weak_alias (strchr, index) |
280 | weak_alias (strrchr, rindex) |
281 | libc_hidden_builtin_def (strchr) |
282 | libc_hidden_builtin_def (strrchr) |
283 | |