1/* strchr (str, ch) -- Return pointer to first occurrence of CH in STR.
2   For SPARC v7.
3   Copyright (C) 1996-2021 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
39ENTRY(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
7711:	retl
78	 sub		%o0, 1, %o0
79
8013:	or		%o4, %lo(0x80808080), %o3
814:	sethi		%hi(0x01010101), %o5
825:	or		%o5, %lo(0x01010101), %o2
837:	ld		[%o0], %g4
846:	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. */
998:	srl		%g4, 24, %g5
1007:	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
1212:	retl
122	 sub		%o0, 2, %o0
1233:	retl
124	 sub		%o0, 3, %o0
1254:	retl
126	 sub		%o0, 4, %o0
1279:	retl
128	 clr		%o0
129
13011:	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
1501:	retl
151	 sub		%o0, 1, %o0
152
15312:	andcc		%o0, 3, %g0
154	bne		11b
155	 sethi		%hi(0x80808080), %o4
156	or		%o4, %lo(0x80808080), %o3
1574:	sethi		%hi(0x01010101), %o4
1585:	or		%o4, %lo(0x01010101), %o2
1596:	ld		[%o0], %o5
1607:	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
1858:	retl
186	 mov		%o4, %o0
187
18813:	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
1951:	 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
2051:	 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
2151:	 or		%o4, %lo(0x01010101), %o2
216	b		7f
217	 ld		[%o0], %g4
218END(strchr)
219
220ENTRY(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
2324:	sethi		%hi(0x01010101), %o4
2335:	or		%o4, %lo(0x01010101), %o2
2346:	ld		[%o0], %g4
2357:	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. */
2503:	srl		%g4, 24, %g5
2518:	andcc		%g5, 0xff, %g5
252	be		9f
253	 cmp		%g5, %o1
254	be,a		1f
255	 sub		%o0, 4, %o5
2561:	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
2621:	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
2681:	andcc		%g4, 0xff, %g5
269	be		9f
270	 cmp		%g5, %o1
271	be,a		1f
272	 sub		%o0, 1, %o5
2731:	b		7b
274	 ld		[%o0], %g4
2759:	retl
276	 mov		%o5, %o0
277END(strrchr)
278
279weak_alias (strchr, index)
280weak_alias (strrchr, rindex)
281libc_hidden_builtin_def (strchr)
282libc_hidden_builtin_def (strrchr)
283