1/* strchr (str, ch) -- Return pointer to first occurrence of CH in STR.
2 For SPARC v9.
3 Copyright (C) 1998-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#include <asm/asi.h>
22#ifndef XCC
23#define XCC xcc
24#define USE_BPR
25 .register %g2, #scratch
26 .register %g3, #scratch
27 .register %g6, #scratch
28#endif
29
30 /* Normally, this uses
31 ((xword - 0x0101010101010101) & 0x8080808080808080) test
32 to find out if any byte in xword could be zero. This is fast, but
33 also gives false alarm for any byte in range 0x81-0xff. It does
34 not matter for correctness, as if this test tells us there could
35 be some zero byte, we check it byte by byte, but if bytes with
36 high bits set are common in the strings, then this will give poor
37 performance. You can #define EIGHTBIT_NOT_RARE and the algorithm
38 will use one tick slower, but more precise test
39 ((xword - 0x0101010101010101) & (~xword) & 0x8080808080808080),
40 which does not give any false alarms (but if some bits are set,
41 one cannot assume from it which bytes are zero and which are not).
42 It is yet to be measured, what is the correct default for glibc
43 in these days for an average user.
44 */
45
46 .text
47 .align 32
48ENTRY(strchr)
49 andcc %o1, 0xff, %o1 /* IEU1 Group */
50 be,pn %icc, 17f /* CTI */
51 sllx %o1, 8, %g3 /* IEU0 Group */
52 sethi %hi(0x01010101), %g1 /* IEU1 */
53
54 or %g3, %o1, %g3 /* IEU0 Group */
55 ldub [%o0], %o3 /* Load */
56 sllx %g3, 16, %g5 /* IEU0 Group */
57 or %g1, %lo(0x01010101), %g1 /* IEU1 */
58
59 sllx %g1, 32, %g2 /* IEU0 Group */
60 brz,pn %o3, 5f /* CTI+IEU1 */
61 orcc %g3, %g5, %g3 /* IEU1 Group */
62 sllx %g3, 32, %g5 /* IEU0 */
63
64 cmp %o3, %o1 /* IEU1 Group */
65 be,pn %xcc, 14f /* CTI */
66 or %g1, %g2, %g1 /* IEU0 */
67 andcc %o0, 7, %g0 /* IEU1 Group */
68
69 bne,a,pn %icc, 15f /* CTI */
70 add %o0, 1, %o0 /* IEU0 */
71 ldx [%o0], %o3 /* Load Group */
721: sllx %g1, 7, %g2 /* IEU0 */
73
74 or %g3, %g5, %g3 /* IEU1 */
75 add %o0, 8, %o0 /* IEU0 Group */
76 xor %o3, %g3, %o4 /* IEU1 */
77 /* %g1 = 0101010101010101 *
78 * %g2 = 8080088080808080 *
79 * %g3 = c c c c c c c c *
80 * %o3 = value *
81 * %o4 = value XOR c */
822: sub %o3, %g1, %o2 /* IEU0 Group */
83
84 sub %o4, %g1, %o5 /* IEU1 */
85#ifdef EIGHTBIT_NOT_RARE
86 andn %o2, %o3, %g6 /* IEU0 Group */
87 andn %o5, %o4, %o5 /* IEU1 */
88 ldxa [%o0] ASI_PNF, %o3 /* Load */
89 or %o5, %g6, %o5 /* IEU0 Group */
90#else
91 ldxa [%o0] ASI_PNF, %o3 /* Load */
92 or %o5, %o2, %o5 /* IEU0 Group */
93#endif
94 add %o0, 8, %o0 /* IEU1 */
95
96 andcc %o5, %g2, %g0 /* IEU1 Group */
97 be,a,pt %xcc, 2b /* CTI */
98 xor %o3, %g3, %o4 /* IEU0 */
99 srlx %o5, 32, %g5 /* IEU0 Group */
100
101 add %o2, %g1, %o2 /* IEU1 */
1023: andcc %g5, %g2, %g0 /* IEU1 Group */
103 be,pn %xcc, 4f /* CTI */
104 srlx %o2, 56, %g5 /* IEU0 */
105
106 andcc %g5, 0xff, %g0 /* IEU1 Group */
107 be,pn %icc, 5f /* CTI */
108 srlx %o4, 56, %g5 /* IEU0 */
109 andcc %g5, 0xff, %g0 /* IEU1 Group */
110
111 be,pn %icc, 6f /* CTI */
112 srlx %o2, 48, %g5 /* IEU0 */
113 andcc %g5, 0xff, %g0 /* IEU1 Group */
114 be,pn %icc, 5f /* CTI */
115
116 srlx %o4, 48, %g5 /* IEU0 */
117 andcc %g5, 0xff, %g0 /* IEU1 Group */
118 be,pn %icc, 7f /* CTI */
119 srlx %o2, 40, %g5 /* IEU0 */
120
121 andcc %g5, 0xff, %g0 /* IEU1 Group */
122 be,pn %icc, 5f /* CTI */
123 srlx %o4, 40, %g5 /* IEU0 */
124 andcc %g5, 0xff, %g0 /* IEU1 Group */
125
126 be,pn %icc, 8f /* CTI */
127 srlx %o2, 32, %g5 /* IEU0 */
128 andcc %g5, 0xff, %g0 /* IEU1 Group */
129 be,pn %icc, 5f /* CTI */
130
131 srlx %o4, 32, %g5 /* IEU0 */
132 andcc %g5, 0xff, %g0 /* IEU1 Group */
133 be,pn %icc, 9f /* CTI */
1344: srlx %o2, 24, %g5 /* IEU0 */
135
136 andcc %g5, 0xff, %g0 /* IEU1 Group */
137 be,pn %icc, 5f /* CTI */
138 srlx %o4, 24, %g5 /* IEU0 */
139 andcc %g5, 0xff, %g0 /* IEU1 Group */
140
141 be,pn %icc, 10f /* CTI */
142 srlx %o2, 16, %g5 /* IEU0 */
143 andcc %g5, 0xff, %g0 /* IEU1 Group */
144 be,pn %icc, 5f /* CTI */
145
146 srlx %o4, 16, %g5 /* IEU0 */
147 andcc %g5, 0xff, %g0 /* IEU1 Group */
148 be,pn %icc, 11f /* CTI */
149 srlx %o2, 8, %g5 /* IEU0 */
150
151 andcc %g5, 0xff, %g0 /* IEU1 Group */
152 be,pn %icc, 5f /* CTI */
153 srlx %o4, 8, %g5 /* IEU0 */
154 andcc %g5, 0xff, %g0 /* IEU1 Group */
155
156 be,pn %icc, 12f /* CTI */
157 andcc %o2, 0xff, %g0 /* IEU1 Group */
158 be,pn %icc, 5f /* CTI */
159 sub %o3, %g1, %o2 /* IEU0 */
160
161 andcc %o4, 0xff, %g0 /* IEU1 Group */
162 be,pn %icc, 13f /* CTI */
163 xor %o3, %g3, %o4 /* IEU0 */
164 ldxa [%o0] ASI_PNF, %o3 /* Load Group */
165
166 sub %o4, %g1, %o5 /* IEU0 */
167 or %o5, %o2, %o5 /* IEU1 */
168 add %o0, 8, %o0 /* IEU0 Group */
169 andcc %o5, %g2, %g0 /* IEU1 */
170
171 be,a,pt %xcc, 2b /* CTI */
172 xor %o3, %g3, %o4 /* IEU0 Group */
173 srlx %o5, 32, %g5 /* IEU0 Group */
174 ba,pt %xcc, 3b /* CTI */
175
176 add %o2, %g1, %o2 /* IEU1 */
177
178 .align 16
1795: retl /* CTI+IEU1 Group */
180 clr %o0 /* IEU0 */
1816: retl /* CTI+IEU1 Group */
182 add %o0, -16, %o0 /* IEU0 */
183
1847: retl /* CTI+IEU1 Group */
185 add %o0, -15, %o0 /* IEU0 */
1868: retl /* CTI+IEU1 Group */
187 add %o0, -14, %o0 /* IEU0 */
188
1899: retl /* CTI+IEU1 Group */
190 add %o0, -13, %o0 /* IEU0 */
19110: retl /* CTI+IEU1 Group */
192 add %o0, -12, %o0 /* IEU0 */
193
19411: retl /* CTI+IEU1 Group */
195 add %o0, -11, %o0 /* IEU0 */
19612: retl /* CTI+IEU1 Group */
197 add %o0, -10, %o0 /* IEU0 */
198
19913: retl /* CTI+IEU1 Group */
200 add %o0, -9, %o0 /* IEU0 */
20114: retl /* CTI+IEU1 Group */
202 nop /* IEU0 */
203
204 .align 16
20515: ldub [%o0], %o3 /* Load Group */
20616: andcc %o0, 7, %g0 /* IEU1 */
207 be,a,pn %icc, 1b /* CTI */
208 ldx [%o0], %o3 /* Load Group */
209
210 andcc %o3, 0xff, %g0 /* IEU1 Group */
211 be,pn %icc, 5b /* CTI */
212 add %o0, 1, %o0 /* IEU0 */
213 cmp %o3, %o1 /* IEU1 Group */
214
215 bne,a,pn %icc, 16b /* CTI */
216 ldub [%o0], %o3 /* Load */
217 retl /* CTI+IEU1 Group */
218 add %o0, -1, %o0 /* IEU0 */
219
220 /* strchr (str, 0) */
221 .align 32
222 nop
223 .align 16
22417: sethi %hi(0x01010101), %g1 /* IEU0 Group */
225 ldub [%o0], %o3 /* Load */
226 or %g1, %lo(0x01010101), %g1 /* IEU0 Group */
227 sllx %g1, 32, %g2 /* IEU0 Group */
228
229 andcc %o0, 7, %g0 /* IEU1 */
230 or %g1, %g2, %g1 /* IEU0 Group */
231 bne,pn %icc, 32f /* CTI */
232 sllx %g1, 7, %g2 /* IEU0 Group */
233
234 brz,pn %o3, 30f /* CTI+IEU1 */
235 ldx [%o0], %o3 /* Load */
23618: add %o0, 8, %o0 /* IEU0 Group */
23719: sub %o3, %g1, %o2 /* IEU0 Group */
238
239#ifdef EIGHTBIT_NOT_RARE
240 andn %o2, %o3, %g6 /* IEU0 Group */
241 ldxa [%o0] ASI_PNF, %o3 /* Load */
242 andcc %g6, %g2, %g0 /* IEU1 Group */
243#else
244 ldxa [%o0] ASI_PNF, %o3 /* Load */
245 andcc %o2, %g2, %g0 /* IEU1 Group */
246#endif
247 be,pt %xcc, 19b /* CTI */
248 add %o0, 8, %o0 /* IEU0 */
249
250 addcc %o2, %g1, %g3 /* IEU1 Group */
251 srlx %o2, 32, %o2 /* IEU0 */
25220: andcc %o2, %g2, %g0 /* IEU1 Group */
253 be,pn %xcc, 21f /* CTI */
254
255 srlx %g3, 56, %o2 /* IEU0 */
256 andcc %o2, 0xff, %g0 /* IEU1 Group */
257 be,pn %icc, 29f /* CTI */
258 srlx %g3, 48, %o2 /* IEU0 */
259
260 andcc %o2, 0xff, %g0 /* IEU1 Group */
261 be,pn %icc, 28f /* CTI */
262 srlx %g3, 40, %o2 /* IEU0 */
263 andcc %o2, 0xff, %g0 /* IEU1 Group */
264
265 be,pn %icc, 27f /* CTI */
266 srlx %g3, 32, %o2 /* IEU0 */
267 andcc %o2, 0xff, %g0 /* IEU1 Group */
268 be,pn %icc, 26f /* CTI */
269
27021: srlx %g3, 24, %o2 /* IEU0 */
271 andcc %o2, 0xff, %g0 /* IEU1 Group */
272 be,pn %icc, 25f /* CTI */
273 srlx %g3, 16, %o2 /* IEU0 */
274
275 andcc %o2, 0xff, %g0 /* IEU1 Group */
276 be,pn %icc, 24f /* CTI */
277 srlx %g3, 8, %o2 /* IEU0 */
278 andcc %o2, 0xff, %g0 /* IEU1 Group */
279
280 be,pn %icc, 23f /* CTI */
281 sub %o3, %g1, %o2 /* IEU0 */
282 andcc %g3, 0xff, %g0 /* IEU1 Group */
283 be,pn %icc, 22f /* CTI */
284
285 ldxa [%o0] ASI_PNF, %o3 /* Load */
286 andcc %o2, %g2, %g0 /* IEU1 Group */
287 be,pt %xcc, 19b /* CTI */
288 add %o0, 8, %o0 /* IEU0 */
289
290 addcc %o2, %g1, %g3 /* IEU1 Group */
291 ba,pt %xcc, 20b /* CTI */
292 srlx %o2, 32, %o2 /* IEU0 */
293
294 .align 16
29522: retl /* CTI+IEU1 Group */
296 add %o0, -9, %o0 /* IEU0 */
29723: retl /* CTI+IEU1 Group */
298 add %o0, -10, %o0 /* IEU0 */
299
30024: retl /* CTI+IEU1 Group */
301 add %o0, -11, %o0 /* IEU0 */
30225: retl /* CTI+IEU1 Group */
303 add %o0, -12, %o0 /* IEU0 */
304
30526: retl /* CTI+IEU1 Group */
306 add %o0, -13, %o0 /* IEU0 */
30727: retl /* CTI+IEU1 Group */
308 add %o0, -14, %o0 /* IEU0 */
309
31028: retl /* CTI+IEU1 Group */
311 add %o0, -15, %o0 /* IEU0 */
31229: retl /* CTI+IEU1 Group */
313 add %o0, -16, %o0 /* IEU0 */
314
31530: retl /* CTI+IEU1 Group */
316 nop /* IEU0 */
317
318 .align 16
31932: andcc %o0, 7, %g0 /* IEU1 Group */
320 be,a,pn %icc, 18b /* CTI */
321 ldx [%o0], %o3 /* Load */
322 add %o0, 1, %o0 /* IEU0 Group */
323
324 brnz,a,pt %o3, 32b /* CTI+IEU1 */
325 lduba [%o0] ASI_PNF, %o3 /* Load */
326 retl /* CTI+IEU1 Group */
327 add %o0, -1, %o0 /* IEU0 */
328END(strchr)
329
330 .align 32
331ENTRY(strrchr)
332 andcc %o1, 0xff, %o1 /* IEU1 Group */
333 be,pn %icc, 17b /* CTI */
334 clr %g4 /* IEU0 */
335 andcc %o0, 7, %g0 /* IEU1 Group */
336
337 bne,pn %icc, 13f /* CTI */
338 sllx %o1, 8, %g3 /* IEU0 */
339 ldx [%o0], %o3 /* Load Group */
3401: sethi %hi(0x01010101), %g1 /* IEU0 */
341
342 or %g3, %o1, %g3 /* IEU1 */
343 sllx %g3, 16, %g5 /* IEU0 Group */
344 or %g1, %lo(0x01010101), %g1 /* IEU1 */
345 sllx %g1, 32, %g2 /* IEU0 Group */
346
347 or %g3, %g5, %g3 /* IEU1 */
348 sllx %g3, 32, %g5 /* IEU0 Group */
349 or %g1, %g2, %g1 /* IEU1 */
350 sllx %g1, 7, %g2 /* IEU0 Group */
351
352 or %g3, %g5, %g3 /* IEU1 */
353 add %o0, 8, %o0 /* IEU0 Group */
354 xor %o3, %g3, %o4 /* IEU1 */
355 /* %g1 = 0101010101010101 *
356 * %g2 = 8080088080808080 *
357 * %g3 = c c c c c c c c *
358 * %o3 = value *
359 * %o4 = value XOR c */
3602: sub %o3, %g1, %o2 /* IEU0 Group */
361
3623: sub %o4, %g1, %o5 /* IEU1 */
363#ifdef EIGHTBIT_NOT_RARE
364 andn %o2, %o3, %g6 /* IEU0 Group */
365 andn %o5, %o4, %o5 /* IEU1 */
366 ldxa [%o0] ASI_PNF, %o3 /* Load */
367
368 or %o5, %g6, %o5 /* IEU0 Group */
369#else
370 ldxa [%o0] ASI_PNF, %o3 /* Load */
371
372 or %o5, %o2, %o5 /* IEU0 Group */
373#endif
374 add %o0, 8, %o0 /* IEU1 */
375 andcc %o5, %g2, %g0 /* IEU1 Group */
376 be,a,pt %xcc, 2b /* CTI */
377
378 xor %o3, %g3, %o4 /* IEU0 */
379 srlx %o5, 32, %g5 /* IEU0 Group */
380 add %o2, %g1, %o2 /* IEU1 */
381 andcc %g5, %g2, %g0 /* IEU1 Group */
382
383 be,pn %xcc, 7f /* CTI */
384 srlx %o2, 56, %g5 /* IEU0 */
385 andcc %g5, 0xff, %g0 /* IEU1 Group */
386 be,pn %icc, 12f /* CTI */
387
388 srlx %o4, 56, %g5 /* IEU0 */
389 andcc %g5, 0xff, %g0 /* IEU1 Group */
390 srlx %o2, 48, %g5 /* IEU0 */
391 be,a,pn %icc, 4f /* CTI */
392
393 add %o0, -16, %g4 /* IEU0 Group */
3944: andcc %g5, 0xff, %g0 /* IEU1 Group */
395 be,pn %icc, 12f /* CTI */
396 srlx %o4, 48, %g5 /* IEU0 */
397
398 andcc %g5, 0xff, %g0 /* IEU1 Group */
399 srlx %o2, 40, %g5 /* IEU0 */
400 be,a,pn %icc, 5f /* CTI */
401 add %o0, -15, %g4 /* IEU0 Group */
402
4035: andcc %g5, 0xff, %g0 /* IEU1 Group */
404 be,pn %icc, 12f /* CTI */
405 srlx %o4, 40, %g5 /* IEU0 */
406 andcc %g5, 0xff, %g0 /* IEU1 Group */
407
408 srlx %o2, 32, %g5 /* IEU0 */
409 be,a,pn %icc, 6f /* CTI */
410 add %o0, -14, %g4 /* IEU0 Group */
4116: andcc %g5, 0xff, %g0 /* IEU1 Group */
412
413 be,pn %icc, 12f /* CTI */
414 srlx %o4, 32, %g5 /* IEU0 */
415 andcc %g5, 0xff, %g0 /* IEU1 Group */
416 be,a,pn %icc, 7f /* CTI */
417
418 add %o0, -13, %g4 /* IEU0 */
4197: srlx %o2, 24, %g5 /* IEU0 */
420 andcc %g5, 0xff, %g0 /* IEU1 Group */
421 be,pn %icc, 12f /* CTI */
422
423 srlx %o4, 24, %g5 /* IEU0 */
424 andcc %g5, 0xff, %g0 /* IEU1 Group */
425 srlx %o2, 16, %g5 /* IEU0 */
426 be,a,pn %icc, 8f /* CTI */
427
428 add %o0, -12, %g4 /* IEU0 Group */
4298: andcc %g5, 0xff, %g0 /* IEU1 Group */
430 be,pn %icc, 12f /* CTI */
431 srlx %o4, 16, %g5 /* IEU0 */
432
433 andcc %g5, 0xff, %g0 /* IEU1 Group */
434 srlx %o2, 8, %g5 /* IEU0 */
435 be,a,pn %icc, 9f /* CTI */
436 add %o0, -11, %g4 /* IEU0 Group */
437
4389: andcc %g5, 0xff, %g0 /* IEU1 Group */
439 be,pn %icc, 12f /* CTI */
440 srlx %o4, 8, %g5 /* IEU0 */
441 andcc %g5, 0xff, %g0 /* IEU1 Group */
442
443 be,a,pn %icc, 10f /* CTI */
444 add %o0, -10, %g4 /* IEU0 */
44510: andcc %o2, 0xff, %g0 /* IEU1 Group */
446 be,pn %icc, 12f /* CTI */
447
448 sub %o3, %g1, %o2 /* IEU0 */
449 andcc %o4, 0xff, %g0 /* IEU1 Group */
450 be,a,pn %icc, 11f /* CTI */
451 add %o0, -9, %g4 /* IEU0 */
452
45311: ba,pt %xcc, 3b /* CTI Group */
454 xor %o3, %g3, %o4 /* IEU0 Group */
45512: retl /* CTI+IEU1 Group */
456 mov %g4, %o0 /* IEU0 */
457
458 .align 16
45913: ldub [%o0], %o3 /* Load Group */
460 add %o0, 1, %o0 /* IEU0 */
46114: andcc %o3, 0xff, %g0 /* IEU1 Group */
462 be,pn %icc, 12b /* CTI */
463
464 cmp %o3, %o1 /* IEU1 Group */
465 ldub [%o0], %o3 /* Load */
466 be,a,pn %icc, 15f /* CTI */
467 add %o0, -1, %g4 /* IEU0 Group */
468
46915: andcc %o0, 7, %g0 /* IEU1 Group */
470 bne,a,pt %icc, 14b /* CTI */
471 add %o0, 1, %o0 /* IEU0 */
472 ba,pt %xcc, 1b /* CTI Group */
473
474 ldx [%o0], %o3 /* Load */
475END(strrchr)
476
477weak_alias (strchr, index)
478weak_alias (strrchr, rindex)
479libc_hidden_builtin_def (strchr)
480libc_hidden_builtin_def (strrchr)
481

source code of glibc/sysdeps/sparc/sparc64/strchr.S