1/* memchr (str, ch, n) -- Return pointer to first occurrence of CH in STR less
2   than N.
3   For SPARC v9.
4   Copyright (C) 1998-2022 Free Software Foundation, Inc.
5   This file is part of the GNU C Library.
6
7   The GNU C Library is free software; you can redistribute it and/or
8   modify it under the terms of the GNU Lesser General Public
9   License as published by the Free Software Foundation; either
10   version 2.1 of the License, or (at your option) any later version.
11
12   The GNU C Library is distributed in the hope that it will be useful,
13   but WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15   Lesser General Public License for more details.
16
17   You should have received a copy of the GNU Lesser General Public
18   License along with the GNU C Library; if not, see
19   <https://www.gnu.org/licenses/>.  */
20
21#include <sysdep.h>
22#include <asm/asi.h>
23#ifndef XCC
24#define XCC xcc
25#define USE_BPR
26	.register	%g2, #scratch
27	.register	%g3, #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(__memchr)
49	and		%o1, 0xff, %o1			/* IEU0		Group		*/
50#ifdef USE_BPR
51	brz,pn		%o2, 12f			/* CTI+IEU1			*/
52#else
53	tst		%o2				/* IEU1				*/
54	be,pn		%XCC, 12f			/* CTI				*/
55#endif
56	 sll		%o1, 8, %g3			/* IEU0		Group		*/
57	addcc		%o0, %o2, %o2			/* IEU1				*/
58	movcs		%XCC, -1, %o2			/* IEU0		Group		*/
59
60	sethi		%hi(0x01010101), %g1		/* IEU0		Group		*/
61	or		%g3, %o1, %g3			/* IEU1				*/
62	ldub		[%o0], %o3			/* Load				*/
63	sllx		%g3, 16, %g5			/* IEU0		Group		*/
64
65	or		%g1, %lo(0x01010101), %g1	/* IEU1				*/
66	sllx		%g1, 32, %g2			/* IEU0		Group		*/
67	or		%g3, %g5, %g3			/* IEU1				*/
68	sllx		%g3, 32, %g5			/* IEU0		Group		*/
69
70	cmp		%o3, %o1			/* IEU1				*/
71	be,pn		%xcc, 13f			/* CTI				*/
72	 or		%g1, %g2, %g1			/* IEU0		Group		*/
73	andcc		%o0, 7, %g0			/* IEU1				*/
74
75	bne,a,pn	%icc, 21f			/* CTI				*/
76	 add		%o0, 1, %o0			/* IEU0		Group		*/
77	ldx		[%o0], %o3			/* Load		Group		*/
78	sllx		%g1, 7, %g2			/* IEU0				*/
79
80	or		%g3, %g5, %g3			/* IEU1				*/
811:	add		%o0, 8, %o0			/* IEU0		Group		*/
82	xor		%o3, %g3, %o4			/* IEU1				*/
83							/* %g1 = 0101010101010101	*
84							 * %g2 = 8080088080808080	*
85							 * %g3 =  c c c c c c c c	*
86							 * %o3 =      value		*
87							 * %o4 =   value XOR c		*/
882:	cmp		%o0, %o2			/* IEU1		Group		*/
89
90	bgu,pn		%XCC, 11f			/* CTI				*/
91	 ldxa		[%o0] ASI_PNF, %o3		/* Load				*/
92	sub		%o4, %g1, %o5			/* IEU0		Group		*/
93	add		%o0, 8, %o0			/* IEU1				*/
94#ifdef EIGHTBIT_NOT_RARE
95	andn		%o5, %o4, %o5			/* IEU0		Group		*/
96#endif
97
98	andcc		%o5, %g2, %g0			/* IEU1		Group		*/
99	be,a,pt		%xcc, 2b			/* CTI				*/
100	 xor		%o3, %g3, %o4			/* IEU0				*/
101	srlx		%o4, 56, %g5			/* IEU0				*/
102
103	andcc		%g5, 0xff, %g0			/* IEU1		Group		*/
104	be,pn		%icc, 3f			/* CTI				*/
105	 srlx		%o4, 48, %g5			/* IEU0				*/
106	andcc		%g5, 0xff, %g0			/* IEU1		Group		*/
107
108	be,pn		%icc, 4f			/* CTI				*/
109	 srlx		%o4, 40, %g5			/* IEU0				*/
110	andcc		%g5, 0xff, %g0			/* IEU1		Group		*/
111	be,pn		%icc, 5f			/* CTI				*/
112
113	 srlx		%o4, 32, %g5			/* IEU0				*/
114	andcc		%g5, 0xff, %g0			/* IEU1		Group		*/
115	be,pn		%icc, 6f			/* CTI				*/
116	 srlx		%o4, 24, %g5			/* IEU0				*/
117
118	andcc		%g5, 0xff, %g0			/* IEU1		Group		*/
119	be,pn		%icc, 7f			/* CTI				*/
120	 srlx		%o4, 16, %g5			/* IEU0				*/
121	andcc		%g5, 0xff, %g0			/* IEU1		Group		*/
122
123	be,pn		%icc, 8f			/* CTI				*/
124	 srlx		%o4, 8, %g5			/* IEU0				*/
125	andcc		%g5, 0xff, %g0			/* IEU1		Group		*/
126	be,pn		%icc, 9f			/* CTI				*/
127
128	 andcc		%o4, 0xff, %g0			/* IEU1		Group		*/
129	bne,pt		%icc, 2b			/* CTI				*/
130	 xor		%o3, %g3, %o4			/* IEU0				*/
131	retl						/* CTI+IEU1	Group		*/
132
133	 add		%o0, -9, %o0			/* IEU0				*/
134
135	.align		16
1363:	retl						/* CTI+IEU1	Group		*/
137	 add		%o0, -16, %o0			/* IEU0				*/
1384:   	retl						/* CTI+IEU1	Group		*/
139	 add		%o0, -15, %o0			/* IEU0				*/
140
1415:	retl						/* CTI+IEU1	Group		*/
142	 add		%o0, -14, %o0			/* IEU0				*/
1436:	retl						/* CTI+IEU1	Group		*/
144	 add		%o0, -13, %o0			/* IEU0				*/
145
1467:	retl						/* CTI+IEU1	Group		*/
147	 add		%o0, -12, %o0			/* IEU0				*/
1488:	retl						/* CTI+IEU1	Group		*/
149	 add		%o0, -11, %o0			/* IEU0				*/
150
1519:	retl						/* CTI+IEU1	Group		*/
152	 add		%o0, -10, %o0			/* IEU0				*/
15311:	sub		%o4, %g1, %o5			/* IEU0		Group		*/
154	sub		%o0, 8, %o0			/* IEU1				*/
155
156	andcc		%o5, %g2, %g0			/* IEU1		Group		*/
157	be,pt		%xcc, 12f			/* CTI				*/
158	 sub		%o2, %o0, %o2			/* IEU0				*/
159	tst		%o2				/* IEU1		Group		*/
160
161	be,pn		%XCC, 12f			/* CTI				*/
162	 srlx		%o4, 56, %g5			/* IEU0				*/
163	andcc		%g5, 0xff, %g0			/* IEU1		Group		*/
164	be,pn		%icc, 13f			/* CTI				*/
165
166	 cmp		%o2, 1				/* IEU0				*/
167	be,pn		%XCC, 12f			/* CTI		Group		*/
168	 srlx		%o4, 48, %g5			/* IEU0				*/
169	andcc		%g5, 0xff, %g0			/* IEU1		Group		*/
170
171	be,pn		%icc, 14f			/* CTI				*/
172	 cmp		%o2, 2				/* IEU1		Group		*/
173	be,pn		%XCC, 12f			/* CTI				*/
174	 srlx		%o4, 40, %g5			/* IEU0				*/
175
176	andcc		%g5, 0xff, %g0			/* IEU1		Group		*/
177	be,pn		%icc, 15f			/* CTI				*/
178	 cmp		%o2, 3				/* IEU1		Group		*/
179	be,pn		%XCC, 12f			/* CTI				*/
180
181	 srlx		%o4, 32, %g5			/* IEU0				*/
182	andcc		%g5, 0xff, %g0			/* IEU1		Group		*/
183	be,pn		%icc, 16f			/* CTI				*/
184	 cmp		%o2, 4				/* IEU1		Group		*/
185
186	be,pn		%XCC, 12f			/* CTI				*/
187	 srlx		%o4, 24, %g5			/* IEU0				*/
188	andcc		%g5, 0xff, %g0			/* IEU1		Group		*/
189	be,pn		%icc, 17f			/* CTI				*/
190
191	 cmp		%o2, 5				/* IEU1		Group		*/
192	be,pn		%XCC, 12f			/* CTI				*/
193	 srlx		%o4, 16, %g5			/* IEU0				*/
194	andcc		%g5, 0xff, %g0			/* IEU1		Group		*/
195
196	be,pn		%icc, 18f			/* CTI				*/
197	 cmp		%o2, 6				/* IEU1		Group		*/
198	be,pn		%XCC, 12f			/* CTI				*/
199	 srlx		%o4, 8, %g5			/* IEU0				*/
200
201	andcc		%g5, 0xff, %g0			/* IEU1		Group		*/
202	be,pn		%icc, 19f			/* CTI				*/
203	 nop						/* IEU0				*/
20412:	retl						/* CTI+IEU1	Group		*/
205
206	 clr		%o0				/* IEU0				*/
207	nop						/* Stub				*/
20813:	retl						/* CTI+IEU1	Group		*/
209	 nop						/* IEU0				*/
210
21114:	retl						/* CTI+IEU1	Group		*/
212	 add		%o0, 1, %o0			/* IEU0				*/
21315:	retl						/* CTI+IEU1	Group		*/
214	 add		%o0, 2, %o0			/* IEU0				*/
215
21616:	retl						/* CTI+IEU1	Group		*/
217	 add		%o0, 3, %o0			/* IEU0				*/
21817:	retl						/* CTI+IEU1	Group		*/
219	 add		%o0, 4, %o0			/* IEU0				*/
220
22118:	retl						/* CTI+IEU1	Group		*/
222	 add		%o0, 5, %o0			/* IEU0				*/
22319:	retl						/* CTI+IEU1	Group		*/
224	 add		%o0, 6, %o0			/* IEU0				*/
225
22621:	cmp		%o0, %o2			/* IEU1				*/
227	be,pn		%XCC, 12b			/* CTI				*/
228	 sllx		%g1, 7, %g2			/* IEU0		Group		*/
229	ldub		[%o0], %o3			/* Load				*/
230
231	or		%g3, %g5, %g3			/* IEU1				*/
23222:	andcc		%o0, 7, %g0			/* IEU1		Group		*/
233	be,a,pn		%icc, 1b			/* CTI				*/
234	 ldx		[%o0], %o3			/* Load				*/
235
236	cmp		%o3, %o1			/* IEU1		Group		*/
237	be,pn		%xcc, 23f			/* CTI				*/
238	 add		%o0, 1, %o0			/* IEU0				*/
239	cmp		%o0, %o2			/* IEU1		Group		*/
240
241	bne,a,pt	%XCC, 22b			/* CTI				*/
242	 ldub		[%o0], %o3			/* Load				*/
243	retl						/* CTI+IEU1	Group		*/
244	 clr		%o0				/* IEU0				*/
245
24623:	retl						/* CTI+IEU1	Group		*/
247	 add		%o0, -1, %o0			/* IEU0				*/
248END(__memchr)
249
250weak_alias (__memchr, memchr)
251libc_hidden_builtin_def (memchr)
252