1/* strncpy(DST, SRC, COUNT) - Copy no more than COUNT bytes of the
2   null-terminated string from SRC to DST.  If SRC does not cover all of
3   COUNT, the balance is zeroed.
4   For SPARC v9.
5   Copyright (C) 1998-2022 Free Software Foundation, Inc.
6   This file is part of the GNU C Library.
7
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.
12
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.
17
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/>.  */
21
22#include <sysdep.h>
23#include <asm/asi.h>
24#ifndef XCC
25#define XCC xcc
26#define USE_BPR
27	.register	%g2, #scratch
28	.register	%g3, #scratch
29	.register	%g6, #scratch
30#endif
31
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.
46	 */
47
48	.text
49	.align		32
50ENTRY(strncpy)
51	sethi		%hi(0x01010101), %g1		/* IEU0		Group		*/
52#ifdef USE_BPR
53	brz,pn		%o2, 19f			/* CTI+IEU1			*/
54#else
55	tst		%o2				/* IEU1				*/
56	be,pn		%XCC, 19f			/* CTI				*/
57#endif
58	 mov		%o0, %g6			/* IEU0		Group		*/
59	or		%g1, %lo(0x01010101), %g1	/* IEU1				*/
60
61	andcc		%o0, 7, %g0			/* IEU1		Group		*/
62	sllx		%g1, 32, %g2			/* IEU0				*/
63	bne,pn		%icc, 26f			/* CTI				*/
64	 or		%g1, %g2, %g1			/* IEU0		Group		*/
65
66	andcc		%o1, 7, %g3			/* IEU1				*/
67	bne,pn		%icc, 28f			/* CTI				*/
68	 sllx		%g1, 7, %g2			/* IEU0		Group		*/
69	ldx		[%o1], %o3			/* Load				*/
70
711:	add		%o1, 8, %o1			/* IEU1				*/
722:	subcc		%o2, 8, %o2			/* IEU1		Group		*/
73	bl,pn		%XCC, 18f			/* CTI				*/
74	 sub		%o3, %g1, %o4			/* IEU0				*/
75
76	add		%o0, 8, %o0			/* IEU0		Group		*/
77#ifdef EIGHTBIT_NOT_MORE
78	andn		%o4, %o3, %o4			/* IEU1				*/
79#endif
80	mov		%o3, %g3			/* IEU1				*/
81	ldxa		[%o1] ASI_PNF, %o3		/* Load				*/
82	add		%o1, 8, %o1			/* IEU0		Group		*/
83
84	andcc		%o4, %g2, %g0			/* IEU1				*/
85	be,a,pt		%xcc, 2b			/* CTI				*/
86	 stx		%g3, [%o0-8]			/* Store	Group		*/
87	srlx		%g3, 56, %g5			/* IEU0		Group		*/
88
89	andcc		%g5, 0xff, %g0			/* IEU1		Group		*/
90	be,pn		%icc, 16f			/* CTI				*/
91	 srlx		%g3, 48, %g4			/* IEU0				*/
92	andcc		%g4, 0xff, %g0			/* IEU1		Group		*/
93
94	be,pn		%icc, 15f			/* CTI				*/
95	 srlx		%g3, 40, %g5			/* IEU0				*/
96	andcc		%g5, 0xff, %g0			/* IEU1		Group		*/
97	be,pn		%icc, 14f			/* CTI				*/
98
99	 srlx		%g3, 32, %g4			/* IEU0				*/
100	andcc		%g4, 0xff, %g0			/* IEU1		Group		*/
101	be,pn		%icc, 13f			/* CTI				*/
102	 srlx		%g3, 24, %g5			/* IEU0				*/
103
104	andcc		%g5, 0xff, %g0			/* IEU1		Group		*/
105	be,pn		%icc, 12f			/* CTI				*/
106	 srlx		%g3, 16, %g4			/* IEU0				*/
107	andcc		%g4, 0xff, %g0			/* IEU1		Group		*/
108
109	be,pn		%icc, 11f			/* CTI				*/
110	 srlx		%g3, 8, %g5			/* IEU0				*/
111	andcc		%g5, 0xff, %g0			/* IEU1		Group		*/
112	be,pn		%icc, 10f			/* CTI				*/
113
114	 andcc		%g3, 0xff, %g0			/* IEU1		Group		*/
115	bne,pt		%icc, 2b			/* CTI				*/
1163:	 stx		%g3, [%o0-8]			/* Store			*/
117	andncc		%o2, 31, %g3			/* IEU1		Group		*/
118
1194:	be,pn		%XCC, 41f			/* CTI				*/
120	 and		%o2, 31, %o2			/* IEU1		Group		*/
12140:	stx		%g0, [%o0]			/* Store			*/
122	stx		%g0, [%o0 + 8]			/* Store	Group		*/
123
124	subcc		%g3, 32, %g3			/* IEU1				*/
125	stx		%g0, [%o0 + 16]			/* Store	Group		*/
126	stx		%g0, [%o0 + 24]			/* Store	Group		*/
127	bne,pt		%XCC, 40b			/* CTI				*/
128
129	 add		%o0, 32, %o0			/* IEU0				*/
13041:	subcc		%o2, 8, %o2			/* IEU1		Group		*/
131	bl,a,pn		%XCC, 6f			/* CTI				*/
132	 andcc		%o2, 4, %g0			/* IEU1		Group		*/
133
1345:	stx		%g0, [%o0]			/* Store			*/
135	subcc		%o2, 8, %o2			/* IEU1		Group		*/
136	bge,pt		%XCC, 5b			/* CTI				*/
137	 add		%o0, 8, %o0			/* IEU0				*/
138
139	andcc		%o2, 4, %g0			/* IEU1		Group		*/
1406:	be,a,pn		%icc, 7f			/* CTI				*/
141	 andcc		%o2, 2, %g0			/* IEU1		Group		*/
142	stw		%g0, [%o0]			/* Store			*/
143
144	add		%o0, 4, %o0			/* IEU0				*/
145	andcc		%o2, 2, %g0			/* IEU1		Group		*/
1467:	be,a,pn		%icc, 8f			/* CTI				*/
147	 andcc		%o2, 1, %g0			/* IEU1		Group		*/
148
149	sth		%g0, [%o0]			/* Store			*/
150	add		%o0, 2, %o0			/* IEU0				*/
151	andcc		%o2, 1, %g0			/* IEU1		Group		*/
1528:	bne,a,pn	%icc, 9f			/* CTI				*/
153
154	 stb		%g0, [%o0]			/* Store			*/
1559:	retl						/* CTI+IEU1	Group		*/
156	 mov		%g6, %o0			/* IEU0				*/
157
158	.align		16
15910:	ba,pt		%xcc, 3b			/* CTI				*/
160	 sllx		%g5, 8, %g3			/* IEU0				*/
16111:	ba,pt		%xcc, 3b			/* CTI		Group		*/
162	 sllx		%g4, 16, %g3			/* IEU0				*/
163
16412:	ba,pt		%xcc, 3b			/* CTI		Group		*/
165	 sllx		%g5, 24, %g3			/* IEU0				*/
16613:	ba,pt		%xcc, 3b			/* CTI		Group		*/
167	 sllx		%g4, 32, %g3			/* IEU0				*/
168
16914:	ba,pt		%xcc, 3b			/* CTI		Group		*/
170	 sllx		%g5, 40, %g3			/* IEU0				*/
17115:	ba,pt		%xcc, 3b			/* CTI		Group		*/
172	 sllx		%g4, 48, %g3			/* IEU0				*/
173
17416:	ba,pt		%xcc, 3b			/* CTI				*/
175	 sllx		%g5, 56, %g3			/* IEU0				*/
17617:	or		%o3, %o4, %o3			/* IEU0		Group		*/
177	sub		%o3, %g1, %o4			/* IEU1				*/
178
17918:	addcc		%o2, 8, %o2			/* IEU1		Group		*/
180	be,pn		%XCC, 19f			/* CTI				*/
181	 andcc		%o4, %g2, %g0			/* IEU1		Group		*/
182	be,pt		%xcc, 21f			/* CTI				*/
183
184	 srlx		%o3, 56, %g5			/* IEU0				*/
185	andcc		%g5, 0xff, %g0			/* IEU1		Group		*/
186	be,pn		%icc, 20f			/* CTI				*/
187	 stb		%g5, [%o0]			/* Store			*/
188
189	add		%o0, 1, %o0			/* IEU0		Group		*/
190	subcc		%o2, 1, %o2			/* IEU1				*/
191	be,pn		%XCC, 19f			/* CTI				*/
192	 srlx		%o3, 48, %g5			/* IEU0		Group		*/
193
194	andcc		%g5, 0xff, %g0			/* IEU1		Group		*/
195	be,pn		%icc, 20f			/* CTI				*/
196	 stb		%g5, [%o0]			/* Store			*/
197	add		%o0, 1, %o0			/* IEU0		Group		*/
198
199	subcc		%o2, 1, %o2			/* IEU1				*/
200	be,pn		%XCC, 19f			/* CTI				*/
201	 srlx		%o3, 40, %g5			/* IEU0		Group		*/
202	andcc		%g5, 0xff, %g0			/* IEU1		Group		*/
203
204	be,pn		%icc, 20f			/* CTI				*/
205	 stb		%g5, [%o0]			/* Store			*/
206	add		%o0, 1, %o0			/* IEU0		Group		*/
207	subcc		%o2, 1, %o2			/* IEU1				*/
208
209	be,pn		%XCC, 19f			/* CTI				*/
210	 srlx		%o3, 32, %g5			/* IEU0		Group		*/
211	andcc		%g5, 0xff, %g0			/* IEU1		Group		*/
212	be,pn		%icc, 20f			/* CTI				*/
213
214	 stb		%g5, [%o0]			/* Store			*/
215	add		%o0, 1, %o0			/* IEU0		Group		*/
216	subcc		%o2, 1, %o2			/* IEU1				*/
217	be,pn		%XCC, 19f			/* CTI				*/
218
219	 srlx		%o3, 24, %g5			/* IEU0		Group		*/
220	andcc		%g5, 0xff, %g0			/* IEU1		Group		*/
221	be,pn		%icc, 20f			/* CTI				*/
222	 stb		%g5, [%o0]			/* Store			*/
223
224	add		%o0, 1, %o0			/* IEU0		Group		*/
225	subcc		%o2, 1, %o2			/* IEU1				*/
226	be,pn		%XCC, 19f			/* CTI				*/
227	 srlx		%o3, 16, %g5			/* IEU0		Group		*/
228
229	andcc		%g5, 0xff, %g0			/* IEU1		Group		*/
230	be,pn		%icc, 20f			/* CTI				*/
231	 stb		%g5, [%o0]			/* Store			*/
232	add		%o0, 1, %o0			/* IEU0		Group		*/
233
234	subcc		%o2, 1, %o2			/* IEU1				*/
235	be,pn		%XCC, 19f			/* CTI				*/
236	 srlx		%o3, 8, %g5			/* IEU0		Group		*/
237	stb		%g5, [%o0]			/* Store			*/
238
23919:	retl						/* CTI+IEU1	Group		*/
240	 mov		%g6, %o0			/* IEU0				*/
24150:	stb		%g0, [%o0]			/* Store	Group		*/
24220:	subcc		%o2, 1, %o2			/* IEU1		Group		*/
243
244	bne,pt		%XCC, 50b			/* CTI				*/
245	 add		%o0, 1, %o0			/* IEU0				*/
246	retl						/* CTI+IEU1	Group		*/
247	 mov		%g6, %o0			/* IEU0				*/
248
24921:	andcc		%o2, 4, %g0			/* IEU1		Group		*/
250	be,pn		%icc, 22f			/* CTI				*/
251	 srlx		%o3, 32, %g5			/* IEU0				*/
252	stw		%g5, [%o0]			/* Store	Group		*/
253
254	add		%o0, 4, %o0			/* IEU0				*/
255	mov		%o3, %g5			/* IEU1				*/
25622:	andcc		%o2, 2, %g0			/* IEU1		Group		*/
257	be,pn		%icc, 23f			/* CTI				*/
258
259	 srlx		%g5, 16, %g4			/* IEU0				*/
260	sth		%g4, [%o0]			/* Store	Group		*/
261	add		%o0, 2, %o0			/* IEU0				*/
262	mov		%g5, %g4			/* IEU1				*/
263
26423:	srlx		%g4, 8, %g4			/* IEU0		Group		*/
265	andcc		%o2, 1, %g0			/* IEU1				*/
266	bne,a,pn	%icc, 24f			/* CTI				*/
267	 stb		%g4, [%o0]			/* Store	Group		*/
268
26924:	retl						/* CTI+IEU1	Group		*/
270	 mov		%g6, %o0			/* IEU0				*/
27125:	andcc		%o0, 7, %g0			/* IEU1		Group		*/
272	be,a,pn		%icc, 4b			/* CTI				*/
273
274	 andncc		%o2, 31, %g3			/* IEU1		Group		*/
275	stb		%g0, [%o0]			/* Store	Group		*/
276	subcc		%o2, 1, %o2			/* IEU1				*/
277	bne,pt		%XCC, 25b			/* CTI				*/
278
279	 add		%o0, 1, %o0			/* IEU0		Group		*/
280	retl						/* CTI+IEU1	Group		*/
281	 mov		%g6, %o0			/* IEU0				*/
282
283	.align		16
28426:	ldub		[%o1], %o3			/* Load				*/
285	sllx		%g1, 7, %g2			/* IEU0		Group		*/
286	stb		%o3, [%o0]			/* Store			*/
28727:	subcc		%o2, 1, %o2			/* IEU1				*/
288
289	be,pn		%XCC, 9b			/* CTI				*/
290	 add		%o1, 1, %o1			/* IEU0		Group		*/
291	add		%o0, 1, %o0			/* IEU1				*/
292	andcc		%o3, 0xff, %g0			/* IEU1		Group		*/
293
294	be,pn		%icc, 25b			/* CTI				*/
295	 lduba		[%o1] ASI_PNF, %o3		/* Load				*/
296	andcc		%o0, 7, %g0			/* IEU1		Group		*/
297	bne,a,pt	%icc, 27b			/* CTI				*/
298
299	 stb		%o3, [%o0]			/* Store			*/
300	andcc		%o1, 7, %g3			/* IEU1		Group		*/
301	be,a,pt		%icc, 1b			/* CTI				*/
302	 ldx		[%o1], %o3			/* Load				*/
303
30428:	orcc		%g0, 64, %g4			/* IEU1		Group		*/
305	sllx		%g3, 3, %g5			/* IEU0				*/
306	sub		%g4, %g5, %g4			/* IEU0		Group		*/
307	sub		%o1, %g3, %o1			/* IEU1				*/
308							/* %g1 = 0101010101010101
309							   %g2 = 8080808080808080
310							   %g3 = source alignment
311							   %g5 = number of bits to shift left
312							   %g4 = number of bits to shift right */
313
314	ldxa		[%o1] ASI_PNF, %o5		/* Load		Group		*/
315	addcc		%o1, 8, %o1			/* IEU1				*/
316
31729:	sllx		%o5, %g5, %o3			/* IEU0		Group		*/
318	ldxa		[%o1] ASI_PNF, %o5		/* Load				*/
319	subcc		%o2, 8, %o2			/* IEU1				*/
320	bl,pn		%XCC, 17b			/* CTI				*/
321
322	 srlx		%o5, %g4, %o4			/* IEU0		Group		*/
323	add		%o1, 8, %o1			/* IEU1				*/
324	or		%o3, %o4, %o3			/* IEU0		Group		*/
325	add		%o0, 8, %o0			/* IEU1				*/
326
327	sub		%o3, %g1, %o4			/* IEU0		Group		*/
328#ifdef EIGHTBIT_NOT_RARE
329	andn		%o4, %o3, %o4			/* IEU0		Group		*/
330#endif
331	andcc		%o4, %g2, %g0			/* IEU1		Group		*/
332	be,a,pt		%xcc, 29b			/* CTI				*/
333	 stx		%o3, [%o0-8]			/* Store			*/
334
335	srlx		%o3, 56, %o4			/* IEU0		Group		*/
336	andcc		%o4, 0xff, %g0			/* IEU1		Group		*/
337	be,pn		%icc, 36f			/* CTI				*/
338	 srlx		%o3, 48, %o4			/* IEU0				*/
339
340	andcc		%o4, 0xff, %g0			/* IEU1		Group		*/
341	be,pn		%icc, 35f			/* CTI				*/
342	 srlx		%o3, 40, %o4			/* IEU0				*/
343	andcc		%o4, 0xff, %g0			/* IEU1		Group		*/
344
345	be,pn		%icc, 34f			/* CTI				*/
346	 srlx		%o3, 32, %o4			/* IEU0				*/
347	andcc		%o4, 0xff, %g0			/* IEU1		Group		*/
348	be,pn		%icc, 33f			/* CTI				*/
349
350	 srlx		%o3, 24, %o4			/* IEU0				*/
351	andcc		%o4, 0xff, %g0			/* IEU1		Group		*/
352	be,pn		%icc, 32f			/* CTI				*/
353	 srlx		%o3, 16, %o4			/* IEU0				*/
354
355	andcc		%o4, 0xff, %g0			/* IEU1		Group		*/
356	be,pn		%icc, 31f			/* CTI				*/
357	 srlx		%o3, 8, %o4			/* IEU0				*/
358	andcc		%o4, 0xff, %g0			/* IEU1		Group		*/
359
360	be,pn		%icc, 30f			/* CTI				*/
361	 andcc		%o3, 0xff, %g0			/* IEU1		Group		*/
362	bne,pn		%icc, 29b			/* CTI				*/
363	 stx		%o3, [%o0-8]			/* Store			*/
364
365	ba,pt		%xcc, 4b			/* CTI		Group		*/
366	 andncc		%o2, 31, %g3			/* IEU1				*/
36730:	srlx		%o3, 8, %o4			/* IEU0				*/
368	ba,pt		%xcc, 3b			/* CTI				*/
369
370	 sllx		%o4, 8, %g3			/* IEU0		Group		*/
37131:	srlx		%o3, 16, %o4			/* IEU0		Group		*/
372	ba,pt		%xcc, 3b			/* CTI				*/
373	 sllx		%o4, 16, %g3			/* IEU0		Group		*/
374
37532:	srlx		%o3, 24, %o4			/* IEU0		Group		*/
376	ba,pt		%xcc, 3b			/* CTI				*/
377	 sllx		%o4, 24, %g3			/* IEU0		Group		*/
37833:	srlx		%o3, 32, %o4			/* IEU0		Group		*/
379
380	ba,pt		%xcc, 3b			/* CTI				*/
381	 sllx		%o4, 32, %g3			/* IEU0		Group		*/
38234:	srlx		%o3, 40, %o4			/* IEU0		Group		*/
383	ba,pt		%xcc, 3b			/* CTI				*/
384
385	 sllx		%o4, 40, %g3			/* IEU0		Group		*/
38635:	srlx		%o3, 48, %o4			/* IEU0		Group		*/
387	ba,pt		%xcc, 3b			/* CTI				*/
388	 sllx		%o4, 48, %g3			/* IEU0		Group		*/
389
39036:	srlx		%o3, 56, %o4			/* IEU0		Group		*/
391	ba,pt		%xcc, 3b			/* CTI				*/
392	 sllx		%o4, 56, %g3			/* IEU0		Group		*/
393END(strncpy)
394libc_hidden_builtin_def (strncpy)
395