1/* rawmemchr (str, ch) -- Return pointer to first occurrence of CH in STR.
2 For SPARC v9.
3 Copyright (C) 1999-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#endif
28
29 /* Normally, this uses
30 ((xword - 0x0101010101010101) & 0x8080808080808080) test
31 to find out if any byte in xword could be zero. This is fast, but
32 also gives false alarm for any byte in range 0x81-0xff. It does
33 not matter for correctness, as if this test tells us there could
34 be some zero byte, we check it byte by byte, but if bytes with
35 high bits set are common in the strings, then this will give poor
36 performance. You can #define EIGHTBIT_NOT_RARE and the algorithm
37 will use one tick slower, but more precise test
38 ((xword - 0x0101010101010101) & (~xword) & 0x8080808080808080),
39 which does not give any false alarms (but if some bits are set,
40 one cannot assume from it which bytes are zero and which are not).
41 It is yet to be measured, what is the correct default for glibc
42 in these days for an average user.
43 */
44
45 .text
46 .align 32
47ENTRY(__rawmemchr)
48 and %o1, 0xff, %o1 /* IEU0 Group */
49 sethi %hi(0x01010101), %g1 /* IEU1 */
50 ldub [%o0], %o3 /* Load */
51 sll %o1, 8, %o4 /* IEU0 Group */
52
53 or %g1, %lo(0x01010101), %g1 /* IEU1 */
54 sllx %g1, 32, %g2 /* IEU0 Group */
55 or %o4, %o1, %o4 /* IEU1 */
56 andcc %o0, 7, %g0 /* IEU1 Group */
57
58 sll %o4, 16, %g5 /* IEU0 */
59 or %o4, %g5, %o4 /* IEU0 Group */
60 or %g1, %g2, %g1 /* IEU1 */
61 bne,pn %icc, 32f /* CTI */
62
63 sllx %o4, 32, %g5 /* IEU0 Group */
64 cmp %o3, %o1 /* IEU1 */
65 be,pn %icc, 30f /* CTI */
66 sllx %g1, 7, %g2 /* IEU0 Group */
67
6818: ldx [%o0], %o3 /* Load */
69 or %o4, %g5, %o4 /* IEU1 */
70 add %o0, 8, %o0 /* IEU0 Group */
7119: xor %o3, %o4, %o3 /* IEU0 Group */
72
73 sub %o3, %g1, %o2 /* IEU0 Group */
74#ifdef EIGHTBIT_NOT_RARE
75 andn %o2, %o3, %o5 /* IEU0 Group */
76 ldxa [%o0] ASI_PNF, %o3 /* Load */
77 andcc %o5, %g2, %g0 /* IEU1 Group */
78#else
79 ldxa [%o0] ASI_PNF, %o3 /* Load */
80 andcc %o2, %g2, %g0 /* IEU1 Group */
81#endif
82 be,pt %xcc, 19b /* CTI */
83
84 add %o0, 8, %o0 /* IEU0 */
85 addcc %o2, %g1, %g3 /* IEU1 Group */
86 srlx %o2, 32, %o2 /* IEU0 */
8720: andcc %o2, %g2, %g0 /* IEU1 Group */
88
89 be,pn %xcc, 21f /* CTI */
90 srlx %g3, 56, %o2 /* IEU0 */
91 andcc %o2, 0xff, %g0 /* IEU1 Group */
92 be,pn %icc, 29f /* CTI */
93
94 srlx %g3, 48, %o2 /* IEU0 */
95 andcc %o2, 0xff, %g0 /* IEU1 Group */
96 be,pn %icc, 28f /* CTI */
97 srlx %g3, 40, %o2 /* IEU0 */
98
99 andcc %o2, 0xff, %g0 /* IEU1 Group */
100 be,pn %icc, 27f /* CTI */
101 srlx %g3, 32, %o2 /* IEU0 */
102 andcc %o2, 0xff, %g0 /* IEU1 Group */
103
104 be,pn %icc, 26f /* CTI */
10521: srlx %g3, 24, %o2 /* IEU0 */
106 andcc %o2, 0xff, %g0 /* IEU1 Group */
107 be,pn %icc, 25f /* CTI */
108
109 srlx %g3, 16, %o2 /* IEU0 */
110 andcc %o2, 0xff, %g0 /* IEU1 Group */
111 be,pn %icc, 24f /* CTI */
112 srlx %g3, 8, %o2 /* IEU0 */
113
114 andcc %o2, 0xff, %g0 /* IEU1 Group */
115 be,pn %icc, 23f /* CTI */
116 xor %o3, %o4, %o3 /* IEU0 */
117 andcc %g3, 0xff, %g0 /* IEU1 Group */
118
119 be,pn %icc, 22f /* CTI */
120 sub %o3, %g1, %o2 /* IEU0 */
121 ldxa [%o0] ASI_PNF, %o3 /* Load */
122 andcc %o2, %g2, %g0 /* IEU1 Group */
123
124 be,pt %xcc, 19b /* CTI */
125 add %o0, 8, %o0 /* IEU0 */
126 addcc %o2, %g1, %g3 /* IEU1 Group */
127 ba,pt %xcc, 20b /* CTI */
128
129 srlx %o2, 32, %o2 /* IEU0 */
130
131 .align 16
13222: retl /* CTI+IEU1 Group */
133 add %o0, -9, %o0 /* IEU0 */
13423: retl /* CTI+IEU1 Group */
135 add %o0, -10, %o0 /* IEU0 */
136
13724: retl /* CTI+IEU1 Group */
138 add %o0, -11, %o0 /* IEU0 */
13925: retl /* CTI+IEU1 Group */
140 add %o0, -12, %o0 /* IEU0 */
141
14226: retl /* CTI+IEU1 Group */
143 add %o0, -13, %o0 /* IEU0 */
14427: retl /* CTI+IEU1 Group */
145 add %o0, -14, %o0 /* IEU0 */
146
14728: retl /* CTI+IEU1 Group */
148 add %o0, -15, %o0 /* IEU0 */
14929: retl /* CTI+IEU1 Group */
150 add %o0, -16, %o0 /* IEU0 */
151
15230: retl /* CTI+IEU1 Group */
153 nop /* IEU0 */
154
155 .align 16
15632: andcc %o0, 7, %g0 /* IEU1 Group */
157 be,a,pn %icc, 18b /* CTI */
158 sllx %g1, 7, %g2 /* IEU0 */
159 add %o0, 1, %o0 /* IEU0 Group */
160
161 cmp %o3, %o1 /* IEU1 */
162 bne,a,pt %icc, 32b /* CTI */
163 lduba [%o0] ASI_PNF, %o3 /* Load */
164 retl /* CTI+IEU1 Group */
165
166 add %o0, -1, %o0 /* IEU0 */
167END(__rawmemchr)
168
169libc_hidden_def (__rawmemchr)
170weak_alias (__rawmemchr, rawmemchr)
171

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