1 /* strchr (str, ch) -- Return pointer to first occurrence of CH in STR.
3 Copyright (C) 1998-2020 Free Software Foundation, Inc.
4 This file is part of the GNU C Library.
5 Contributed by Jan Vondrák <jvon4518@ss1000.ms.mff.cuni.cz> and
6 Jakub Jelinek <jj@ultra.linux.cz>.
8 The GNU C Library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public
10 License as published by the Free Software Foundation; either
11 version 2.1 of the License, or (at your option) any later version.
13 The GNU C Library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public
19 License along with the GNU C Library; if not, see
20 <https://www.gnu.org/licenses/>. */
27 .register %g2, #scratch
28 .register %g3, #scratch
29 .register %g6, #scratch
32 /* Normally, this uses
33 ((xword - 0x0101010101010101) & 0x8080808080808080) test
34 to find out if any byte in xword could be zero. This is fast, but
35 also gives false alarm for any byte in range 0x81-0xff. It does
36 not matter for correctness, as if this test tells us there could
37 be some zero byte, we check it byte by byte, but if bytes with
38 high bits set are common in the strings, then this will give poor
39 performance. You can #define EIGHTBIT_NOT_RARE and the algorithm
40 will use one tick slower, but more precise test
41 ((xword - 0x0101010101010101) & (~xword) & 0x8080808080808080),
42 which does not give any false alarms (but if some bits are set,
43 one cannot assume from it which bytes are zero and which are not).
44 It is yet to be measured, what is the correct default for glibc
45 in these days for an average user.
51 andcc %o1, 0xff, %o1 /* IEU1 Group */
52 be,pn %icc, 17f /* CTI */
53 sllx %o1, 8, %g3 /* IEU0 Group */
54 sethi %hi(0x01010101), %g1 /* IEU1 */
56 or %g3, %o1, %g3 /* IEU0 Group */
57 ldub [%o0], %o3 /* Load */
58 sllx %g3, 16, %g5 /* IEU0 Group */
59 or %g1, %lo(0x01010101), %g1 /* IEU1 */
61 sllx %g1, 32, %g2 /* IEU0 Group */
62 brz,pn %o3, 5f /* CTI+IEU1 */
63 orcc %g3, %g5, %g3 /* IEU1 Group */
64 sllx %g3, 32, %g5 /* IEU0 */
66 cmp %o3, %o1 /* IEU1 Group */
67 be,pn %xcc, 14f /* CTI */
68 or %g1, %g2, %g1 /* IEU0 */
69 andcc %o0, 7, %g0 /* IEU1 Group */
71 bne,a,pn %icc, 15f /* CTI */
72 add %o0, 1, %o0 /* IEU0 */
73 ldx [%o0], %o3 /* Load Group */
74 1: sllx %g1, 7, %g2 /* IEU0 */
76 or %g3, %g5, %g3 /* IEU1 */
77 add %o0, 8, %o0 /* IEU0 Group */
78 xor %o3, %g3, %o4 /* IEU1 */
79 /* %g1 = 0101010101010101 *
80 * %g2 = 8080088080808080 *
81 * %g3 = c c c c c c c c *
83 * %o4 = value XOR c */
84 2: sub %o3, %g1, %o2 /* IEU0 Group */
86 sub %o4, %g1, %o5 /* IEU1 */
87 #ifdef EIGHTBIT_NOT_RARE
88 andn %o2, %o3, %g6 /* IEU0 Group */
89 andn %o5, %o4, %o5 /* IEU1 */
90 ldxa [%o0] ASI_PNF, %o3 /* Load */
91 or %o5, %g6, %o5 /* IEU0 Group */
93 ldxa [%o0] ASI_PNF, %o3 /* Load */
94 or %o5, %o2, %o5 /* IEU0 Group */
96 add %o0, 8, %o0 /* IEU1 */
98 andcc %o5, %g2, %g0 /* IEU1 Group */
99 be,a,pt %xcc, 2b /* CTI */
100 xor %o3, %g3, %o4 /* IEU0 */
101 srlx %o5, 32, %g5 /* IEU0 Group */
103 add %o2, %g1, %o2 /* IEU1 */
104 3: andcc %g5, %g2, %g0 /* IEU1 Group */
105 be,pn %xcc, 4f /* CTI */
106 srlx %o2, 56, %g5 /* IEU0 */
108 andcc %g5, 0xff, %g0 /* IEU1 Group */
109 be,pn %icc, 5f /* CTI */
110 srlx %o4, 56, %g5 /* IEU0 */
111 andcc %g5, 0xff, %g0 /* IEU1 Group */
113 be,pn %icc, 6f /* CTI */
114 srlx %o2, 48, %g5 /* IEU0 */
115 andcc %g5, 0xff, %g0 /* IEU1 Group */
116 be,pn %icc, 5f /* CTI */
118 srlx %o4, 48, %g5 /* IEU0 */
119 andcc %g5, 0xff, %g0 /* IEU1 Group */
120 be,pn %icc, 7f /* CTI */
121 srlx %o2, 40, %g5 /* IEU0 */
123 andcc %g5, 0xff, %g0 /* IEU1 Group */
124 be,pn %icc, 5f /* CTI */
125 srlx %o4, 40, %g5 /* IEU0 */
126 andcc %g5, 0xff, %g0 /* IEU1 Group */
128 be,pn %icc, 8f /* CTI */
129 srlx %o2, 32, %g5 /* IEU0 */
130 andcc %g5, 0xff, %g0 /* IEU1 Group */
131 be,pn %icc, 5f /* CTI */
133 srlx %o4, 32, %g5 /* IEU0 */
134 andcc %g5, 0xff, %g0 /* IEU1 Group */
135 be,pn %icc, 9f /* CTI */
136 4: srlx %o2, 24, %g5 /* IEU0 */
138 andcc %g5, 0xff, %g0 /* IEU1 Group */
139 be,pn %icc, 5f /* CTI */
140 srlx %o4, 24, %g5 /* IEU0 */
141 andcc %g5, 0xff, %g0 /* IEU1 Group */
143 be,pn %icc, 10f /* CTI */
144 srlx %o2, 16, %g5 /* IEU0 */
145 andcc %g5, 0xff, %g0 /* IEU1 Group */
146 be,pn %icc, 5f /* CTI */
148 srlx %o4, 16, %g5 /* IEU0 */
149 andcc %g5, 0xff, %g0 /* IEU1 Group */
150 be,pn %icc, 11f /* CTI */
151 srlx %o2, 8, %g5 /* IEU0 */
153 andcc %g5, 0xff, %g0 /* IEU1 Group */
154 be,pn %icc, 5f /* CTI */
155 srlx %o4, 8, %g5 /* IEU0 */
156 andcc %g5, 0xff, %g0 /* IEU1 Group */
158 be,pn %icc, 12f /* CTI */
159 andcc %o2, 0xff, %g0 /* IEU1 Group */
160 be,pn %icc, 5f /* CTI */
161 sub %o3, %g1, %o2 /* IEU0 */
163 andcc %o4, 0xff, %g0 /* IEU1 Group */
164 be,pn %icc, 13f /* CTI */
165 xor %o3, %g3, %o4 /* IEU0 */
166 ldxa [%o0] ASI_PNF, %o3 /* Load Group */
168 sub %o4, %g1, %o5 /* IEU0 */
169 or %o5, %o2, %o5 /* IEU1 */
170 add %o0, 8, %o0 /* IEU0 Group */
171 andcc %o5, %g2, %g0 /* IEU1 */
173 be,a,pt %xcc, 2b /* CTI */
174 xor %o3, %g3, %o4 /* IEU0 Group */
175 srlx %o5, 32, %g5 /* IEU0 Group */
176 ba,pt %xcc, 3b /* CTI */
178 add %o2, %g1, %o2 /* IEU1 */
181 5: retl /* CTI+IEU1 Group */
183 6: retl /* CTI+IEU1 Group */
184 add %o0, -16, %o0 /* IEU0 */
186 7: retl /* CTI+IEU1 Group */
187 add %o0, -15, %o0 /* IEU0 */
188 8: retl /* CTI+IEU1 Group */
189 add %o0, -14, %o0 /* IEU0 */
191 9: retl /* CTI+IEU1 Group */
192 add %o0, -13, %o0 /* IEU0 */
193 10: retl /* CTI+IEU1 Group */
194 add %o0, -12, %o0 /* IEU0 */
196 11: retl /* CTI+IEU1 Group */
197 add %o0, -11, %o0 /* IEU0 */
198 12: retl /* CTI+IEU1 Group */
199 add %o0, -10, %o0 /* IEU0 */
201 13: retl /* CTI+IEU1 Group */
202 add %o0, -9, %o0 /* IEU0 */
203 14: retl /* CTI+IEU1 Group */
207 15: ldub [%o0], %o3 /* Load Group */
208 16: andcc %o0, 7, %g0 /* IEU1 */
209 be,a,pn %icc, 1b /* CTI */
210 ldx [%o0], %o3 /* Load Group */
212 andcc %o3, 0xff, %g0 /* IEU1 Group */
213 be,pn %icc, 5b /* CTI */
214 add %o0, 1, %o0 /* IEU0 */
215 cmp %o3, %o1 /* IEU1 Group */
217 bne,a,pn %icc, 16b /* CTI */
218 ldub [%o0], %o3 /* Load */
219 retl /* CTI+IEU1 Group */
220 add %o0, -1, %o0 /* IEU0 */
222 /* strchr (str, 0) */
226 17: sethi %hi(0x01010101), %g1 /* IEU0 Group */
227 ldub [%o0], %o3 /* Load */
228 or %g1, %lo(0x01010101), %g1 /* IEU0 Group */
229 sllx %g1, 32, %g2 /* IEU0 Group */
231 andcc %o0, 7, %g0 /* IEU1 */
232 or %g1, %g2, %g1 /* IEU0 Group */
233 bne,pn %icc, 32f /* CTI */
234 sllx %g1, 7, %g2 /* IEU0 Group */
236 brz,pn %o3, 30f /* CTI+IEU1 */
237 ldx [%o0], %o3 /* Load */
238 18: add %o0, 8, %o0 /* IEU0 Group */
239 19: sub %o3, %g1, %o2 /* IEU0 Group */
241 #ifdef EIGHTBIT_NOT_RARE
242 andn %o2, %o3, %g6 /* IEU0 Group */
243 ldxa [%o0] ASI_PNF, %o3 /* Load */
244 andcc %g6, %g2, %g0 /* IEU1 Group */
246 ldxa [%o0] ASI_PNF, %o3 /* Load */
247 andcc %o2, %g2, %g0 /* IEU1 Group */
249 be,pt %xcc, 19b /* CTI */
250 add %o0, 8, %o0 /* IEU0 */
252 addcc %o2, %g1, %g3 /* IEU1 Group */
253 srlx %o2, 32, %o2 /* IEU0 */
254 20: andcc %o2, %g2, %g0 /* IEU1 Group */
255 be,pn %xcc, 21f /* CTI */
257 srlx %g3, 56, %o2 /* IEU0 */
258 andcc %o2, 0xff, %g0 /* IEU1 Group */
259 be,pn %icc, 29f /* CTI */
260 srlx %g3, 48, %o2 /* IEU0 */
262 andcc %o2, 0xff, %g0 /* IEU1 Group */
263 be,pn %icc, 28f /* CTI */
264 srlx %g3, 40, %o2 /* IEU0 */
265 andcc %o2, 0xff, %g0 /* IEU1 Group */
267 be,pn %icc, 27f /* CTI */
268 srlx %g3, 32, %o2 /* IEU0 */
269 andcc %o2, 0xff, %g0 /* IEU1 Group */
270 be,pn %icc, 26f /* CTI */
272 21: srlx %g3, 24, %o2 /* IEU0 */
273 andcc %o2, 0xff, %g0 /* IEU1 Group */
274 be,pn %icc, 25f /* CTI */
275 srlx %g3, 16, %o2 /* IEU0 */
277 andcc %o2, 0xff, %g0 /* IEU1 Group */
278 be,pn %icc, 24f /* CTI */
279 srlx %g3, 8, %o2 /* IEU0 */
280 andcc %o2, 0xff, %g0 /* IEU1 Group */
282 be,pn %icc, 23f /* CTI */
283 sub %o3, %g1, %o2 /* IEU0 */
284 andcc %g3, 0xff, %g0 /* IEU1 Group */
285 be,pn %icc, 22f /* CTI */
287 ldxa [%o0] ASI_PNF, %o3 /* Load */
288 andcc %o2, %g2, %g0 /* IEU1 Group */
289 be,pt %xcc, 19b /* CTI */
290 add %o0, 8, %o0 /* IEU0 */
292 addcc %o2, %g1, %g3 /* IEU1 Group */
293 ba,pt %xcc, 20b /* CTI */
294 srlx %o2, 32, %o2 /* IEU0 */
297 22: retl /* CTI+IEU1 Group */
298 add %o0, -9, %o0 /* IEU0 */
299 23: retl /* CTI+IEU1 Group */
300 add %o0, -10, %o0 /* IEU0 */
302 24: retl /* CTI+IEU1 Group */
303 add %o0, -11, %o0 /* IEU0 */
304 25: retl /* CTI+IEU1 Group */
305 add %o0, -12, %o0 /* IEU0 */
307 26: retl /* CTI+IEU1 Group */
308 add %o0, -13, %o0 /* IEU0 */
309 27: retl /* CTI+IEU1 Group */
310 add %o0, -14, %o0 /* IEU0 */
312 28: retl /* CTI+IEU1 Group */
313 add %o0, -15, %o0 /* IEU0 */
314 29: retl /* CTI+IEU1 Group */
315 add %o0, -16, %o0 /* IEU0 */
317 30: retl /* CTI+IEU1 Group */
321 32: andcc %o0, 7, %g0 /* IEU1 Group */
322 be,a,pn %icc, 18b /* CTI */
323 ldx [%o0], %o3 /* Load */
324 add %o0, 1, %o0 /* IEU0 Group */
326 brnz,a,pt %o3, 32b /* CTI+IEU1 */
327 lduba [%o0] ASI_PNF, %o3 /* Load */
328 retl /* CTI+IEU1 Group */
329 add %o0, -1, %o0 /* IEU0 */
334 andcc %o1, 0xff, %o1 /* IEU1 Group */
335 be,pn %icc, 17b /* CTI */
337 andcc %o0, 7, %g0 /* IEU1 Group */
339 bne,pn %icc, 13f /* CTI */
340 sllx %o1, 8, %g3 /* IEU0 */
341 ldx [%o0], %o3 /* Load Group */
342 1: sethi %hi(0x01010101), %g1 /* IEU0 */
344 or %g3, %o1, %g3 /* IEU1 */
345 sllx %g3, 16, %g5 /* IEU0 Group */
346 or %g1, %lo(0x01010101), %g1 /* IEU1 */
347 sllx %g1, 32, %g2 /* IEU0 Group */
349 or %g3, %g5, %g3 /* IEU1 */
350 sllx %g3, 32, %g5 /* IEU0 Group */
351 or %g1, %g2, %g1 /* IEU1 */
352 sllx %g1, 7, %g2 /* IEU0 Group */
354 or %g3, %g5, %g3 /* IEU1 */
355 add %o0, 8, %o0 /* IEU0 Group */
356 xor %o3, %g3, %o4 /* IEU1 */
357 /* %g1 = 0101010101010101 *
358 * %g2 = 8080088080808080 *
359 * %g3 = c c c c c c c c *
361 * %o4 = value XOR c */
362 2: sub %o3, %g1, %o2 /* IEU0 Group */
364 3: sub %o4, %g1, %o5 /* IEU1 */
365 #ifdef EIGHTBIT_NOT_RARE
366 andn %o2, %o3, %g6 /* IEU0 Group */
367 andn %o5, %o4, %o5 /* IEU1 */
368 ldxa [%o0] ASI_PNF, %o3 /* Load */
370 or %o5, %g6, %o5 /* IEU0 Group */
372 ldxa [%o0] ASI_PNF, %o3 /* Load */
374 or %o5, %o2, %o5 /* IEU0 Group */
376 add %o0, 8, %o0 /* IEU1 */
377 andcc %o5, %g2, %g0 /* IEU1 Group */
378 be,a,pt %xcc, 2b /* CTI */
380 xor %o3, %g3, %o4 /* IEU0 */
381 srlx %o5, 32, %g5 /* IEU0 Group */
382 add %o2, %g1, %o2 /* IEU1 */
383 andcc %g5, %g2, %g0 /* IEU1 Group */
385 be,pn %xcc, 7f /* CTI */
386 srlx %o2, 56, %g5 /* IEU0 */
387 andcc %g5, 0xff, %g0 /* IEU1 Group */
388 be,pn %icc, 12f /* CTI */
390 srlx %o4, 56, %g5 /* IEU0 */
391 andcc %g5, 0xff, %g0 /* IEU1 Group */
392 srlx %o2, 48, %g5 /* IEU0 */
393 be,a,pn %icc, 4f /* CTI */
395 add %o0, -16, %g4 /* IEU0 Group */
396 4: andcc %g5, 0xff, %g0 /* IEU1 Group */
397 be,pn %icc, 12f /* CTI */
398 srlx %o4, 48, %g5 /* IEU0 */
400 andcc %g5, 0xff, %g0 /* IEU1 Group */
401 srlx %o2, 40, %g5 /* IEU0 */
402 be,a,pn %icc, 5f /* CTI */
403 add %o0, -15, %g4 /* IEU0 Group */
405 5: andcc %g5, 0xff, %g0 /* IEU1 Group */
406 be,pn %icc, 12f /* CTI */
407 srlx %o4, 40, %g5 /* IEU0 */
408 andcc %g5, 0xff, %g0 /* IEU1 Group */
410 srlx %o2, 32, %g5 /* IEU0 */
411 be,a,pn %icc, 6f /* CTI */
412 add %o0, -14, %g4 /* IEU0 Group */
413 6: andcc %g5, 0xff, %g0 /* IEU1 Group */
415 be,pn %icc, 12f /* CTI */
416 srlx %o4, 32, %g5 /* IEU0 */
417 andcc %g5, 0xff, %g0 /* IEU1 Group */
418 be,a,pn %icc, 7f /* CTI */
420 add %o0, -13, %g4 /* IEU0 */
421 7: srlx %o2, 24, %g5 /* IEU0 */
422 andcc %g5, 0xff, %g0 /* IEU1 Group */
423 be,pn %icc, 12f /* CTI */
425 srlx %o4, 24, %g5 /* IEU0 */
426 andcc %g5, 0xff, %g0 /* IEU1 Group */
427 srlx %o2, 16, %g5 /* IEU0 */
428 be,a,pn %icc, 8f /* CTI */
430 add %o0, -12, %g4 /* IEU0 Group */
431 8: andcc %g5, 0xff, %g0 /* IEU1 Group */
432 be,pn %icc, 12f /* CTI */
433 srlx %o4, 16, %g5 /* IEU0 */
435 andcc %g5, 0xff, %g0 /* IEU1 Group */
436 srlx %o2, 8, %g5 /* IEU0 */
437 be,a,pn %icc, 9f /* CTI */
438 add %o0, -11, %g4 /* IEU0 Group */
440 9: andcc %g5, 0xff, %g0 /* IEU1 Group */
441 be,pn %icc, 12f /* CTI */
442 srlx %o4, 8, %g5 /* IEU0 */
443 andcc %g5, 0xff, %g0 /* IEU1 Group */
445 be,a,pn %icc, 10f /* CTI */
446 add %o0, -10, %g4 /* IEU0 */
447 10: andcc %o2, 0xff, %g0 /* IEU1 Group */
448 be,pn %icc, 12f /* CTI */
450 sub %o3, %g1, %o2 /* IEU0 */
451 andcc %o4, 0xff, %g0 /* IEU1 Group */
452 be,a,pn %icc, 11f /* CTI */
453 add %o0, -9, %g4 /* IEU0 */
455 11: ba,pt %xcc, 3b /* CTI Group */
456 xor %o3, %g3, %o4 /* IEU0 Group */
457 12: retl /* CTI+IEU1 Group */
458 mov %g4, %o0 /* IEU0 */
461 13: ldub [%o0], %o3 /* Load Group */
462 add %o0, 1, %o0 /* IEU0 */
463 14: andcc %o3, 0xff, %g0 /* IEU1 Group */
464 be,pn %icc, 12b /* CTI */
466 cmp %o3, %o1 /* IEU1 Group */
467 ldub [%o0], %o3 /* Load */
468 be,a,pn %icc, 15f /* CTI */
469 add %o0, -1, %g4 /* IEU0 Group */
471 15: andcc %o0, 7, %g0 /* IEU1 Group */
472 bne,a,pt %icc, 14b /* CTI */
473 add %o0, 1, %o0 /* IEU0 */
474 ba,pt %xcc, 1b /* CTI Group */
476 ldx [%o0], %o3 /* Load */
479 weak_alias (strchr, index)
480 weak_alias (strrchr, rindex)
481 libc_hidden_builtin_def (strchr)
482 libc_hidden_builtin_def (strrchr)