1/* stpncpy(DST, SRC, COUNT) - Copy no more than N characters of
2 SRC to DEST, returning the address of the terminating '\0' in
3 DEST, if any, or else DEST + N.
4 For SPARC v9.
5 Copyright (C) 1998-2024 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(__stpncpy)
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 or %g1, %lo(0x01010101), %g1 /* IEU1 */
59 andcc %o0, 7, %g0 /* IEU1 Group */
60
61 sllx %g1, 32, %g2 /* IEU0 */
62 bne,pn %icc, 26f /* CTI */
63 or %g1, %g2, %g1 /* IEU0 Group */
64 andcc %o1, 7, %g3 /* IEU1 */
65
66 bne,pn %icc, 28f /* CTI */
67 sllx %g1, 7, %g2 /* IEU0 Group */
68 ldx [%o1], %o3 /* Load */
691: add %o1, 8, %o1 /* IEU1 */
70
712: subcc %o2, 8, %o2 /* IEU1 Group */
72 bl,pn %XCC, 18f /* CTI */
73 sub %o3, %g1, %o4 /* IEU0 */
74 add %o0, 8, %o0 /* IEU0 Group */
75
76#ifdef EIGHTBIT_NOT_MORE
77 andn %o4, %o3, %o4 /* IEU1 */
78#endif
79 mov %o3, %g3 /* IEU1 */
80 ldxa [%o1] ASI_PNF, %o3 /* Load */
81 add %o1, 8, %o1 /* IEU0 Group */
82 andcc %o4, %g2, %g0 /* IEU1 */
83
84 be,a,pt %xcc, 2b /* CTI */
85 stx %g3, [%o0-8] /* Store Group */
86 srlx %g3, 56, %g5 /* IEU0 Group */
87 andcc %g5, 0xff, %g0 /* IEU1 Group */
88
89 be,pn %icc, 16f /* CTI */
90 srlx %g3, 48, %g4 /* IEU0 */
91 andcc %g4, 0xff, %g0 /* IEU1 Group */
92 be,pn %icc, 15f /* CTI */
93
94 srlx %g3, 40, %g5 /* IEU0 */
95 andcc %g5, 0xff, %g0 /* IEU1 Group */
96 be,pn %icc, 14f /* CTI */
97 srlx %g3, 32, %g4 /* IEU0 */
98
99 andcc %g4, 0xff, %g0 /* IEU1 Group */
100 be,pn %icc, 13f /* CTI */
101 srlx %g3, 24, %g5 /* IEU0 */
102 andcc %g5, 0xff, %g0 /* IEU1 Group */
103
104 be,pn %icc, 12f /* CTI */
105 srlx %g3, 16, %g4 /* IEU0 */
106 andcc %g4, 0xff, %g0 /* IEU1 Group */
107 be,pn %icc, 11f /* CTI */
108
109 srlx %g3, 8, %g5 /* IEU0 */
110 andcc %g5, 0xff, %g0 /* IEU1 Group */
111 be,pn %icc, 10f /* CTI */
112 sub %o0, 1, %g6 /* IEU0 */
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 */
15710: subcc %o0, 2, %g6 /* IEU1 Group */
158
159 ba,pt %xcc, 3b /* CTI */
160 sllx %g5, 8, %g3 /* IEU0 */
16111: subcc %o0, 3, %g6 /* IEU1 Group */
162 ba,pt %xcc, 3b /* CTI */
163
164 sllx %g4, 16, %g3 /* IEU0 */
16512: subcc %o0, 4, %g6 /* IEU1 Group */
166 ba,pt %xcc, 3b /* CTI */
167 sllx %g5, 24, %g3 /* IEU0 */
168
16913: subcc %o0, 5, %g6 /* IEU1 Group */
170 ba,pt %xcc, 3b /* CTI */
171 sllx %g4, 32, %g3 /* IEU0 */
17214: subcc %o0, 6, %g6 /* IEU1 Group */
173
174 ba,pt %xcc, 3b /* CTI */
175 sllx %g5, 40, %g3 /* IEU0 */
17615: subcc %o0, 7, %g6 /* IEU1 Group */
177 ba,pt %xcc, 3b /* CTI */
178
179 sllx %g4, 48, %g3 /* IEU0 */
18016: subcc %o0, 8, %g6 /* IEU1 Group */
181 ba,pt %xcc, 3b /* CTI */
182 clr %g3 /* IEU0 */
183
184 .align 16
18517: or %o3, %o4, %o3 /* IEU0 Group */
186 sub %o3, %g1, %o4 /* IEU1 */
18718: addcc %o2, 8, %o2 /* IEU1 Group */
188 be,pn %XCC, 19f /* CTI */
189
190 andcc %o4, %g2, %g0 /* IEU1 Group */
191 be,pt %xcc, 21f /* CTI */
192 srlx %o3, 56, %g5 /* IEU0 */
193 andcc %g5, 0xff, %g0 /* IEU1 Group */
194
195 be,pn %icc, 20f /* CTI */
196 stb %g5, [%o0] /* Store */
197 add %o0, 1, %o0 /* IEU0 Group */
198 subcc %o2, 1, %o2 /* IEU1 */
199
200 be,pn %XCC, 19f /* CTI */
201 srlx %o3, 48, %g5 /* IEU0 Group */
202 andcc %g5, 0xff, %g0 /* IEU1 Group */
203 be,pn %icc, 20f /* CTI */
204
205 stb %g5, [%o0] /* Store */
206 add %o0, 1, %o0 /* IEU0 Group */
207 subcc %o2, 1, %o2 /* IEU1 */
208 be,pn %XCC, 19f /* CTI */
209
210 srlx %o3, 40, %g5 /* IEU0 Group */
211 andcc %g5, 0xff, %g0 /* IEU1 Group */
212 be,pn %icc, 20f /* CTI */
213 stb %g5, [%o0] /* Store */
214
215 add %o0, 1, %o0 /* IEU0 Group */
216 subcc %o2, 1, %o2 /* IEU1 */
217 be,pn %XCC, 19f /* CTI */
218 srlx %o3, 32, %g5 /* IEU0 Group */
219
220 andcc %g5, 0xff, %g0 /* IEU1 Group */
221 be,pn %icc, 20f /* CTI */
222 stb %g5, [%o0] /* Store */
223 add %o0, 1, %o0 /* IEU0 Group */
224
225 subcc %o2, 1, %o2 /* IEU1 */
226 be,pn %XCC, 19f /* CTI */
227 srlx %o3, 24, %g5 /* IEU0 Group */
228 andcc %g5, 0xff, %g0 /* IEU1 Group */
229
230 be,pn %icc, 20f /* CTI */
231 stb %g5, [%o0] /* Store */
232 add %o0, 1, %o0 /* IEU0 Group */
233 subcc %o2, 1, %o2 /* IEU1 */
234
235 be,pn %XCC, 19f /* CTI */
236 srlx %o3, 16, %g5 /* IEU0 Group */
237 andcc %g5, 0xff, %g0 /* IEU1 Group */
238 be,pn %icc, 20f /* CTI */
239
240 stb %g5, [%o0] /* Store */
241 add %o0, 1, %o0 /* IEU0 Group */
242 subcc %o2, 1, %o2 /* IEU1 */
243 be,pn %XCC, 19f /* CTI */
244
245 srlx %o3, 8, %o3 /* IEU0 Group */
246 stb %o3, [%o0] /* Store */
24759: add %o0, 1, %o2 /* IEU1 */
248 andcc %o3, 0xff, %g0 /* IEU1 Group */
249
250 retl /* CTI+IEU1 Group */
251 movne %icc, %o2, %o0 /* Single Group */
25219: retl /* CTI+IEU1 Group */
253 nop /* IEU0 */
254
25520: mov %o0, %g6 /* IEU0 Group */
256 subcc %o2, 1, %o2 /* IEU1 */
257 be,pn %XCC, 51f /* CTI */
258 add %o0, 1, %o0 /* IEU0 Group */
259
26050: stb %g0, [%o0] /* Store Group */
261 subcc %o2, 1, %o2 /* IEU1 Group */
262 bne,pt %XCC, 50b /* CTI */
263 add %o0, 1, %o0 /* IEU0 */
264
26551: retl /* CTI+IEU1 Group */
266 mov %g6, %o0 /* IEU0 */
267
268 .align 16
26921: andcc %o2, 4, %g0 /* IEU1 Group */
270 be,pn %icc, 22f /* CTI */
271 srlx %o3, 32, %g5 /* IEU0 */
272 stw %g5, [%o0] /* Store Group */
273
274 add %o0, 4, %o0 /* IEU0 */
275 mov %o3, %g5 /* IEU1 */
27622: andcc %o2, 2, %g0 /* IEU1 Group */
277 be,pn %icc, 23f /* CTI */
278
279 srlx %g5, 16, %g4 /* IEU0 */
280 sth %g4, [%o0] /* Store Group */
281 add %o0, 2, %o0 /* IEU0 */
282 mov %g5, %g4 /* IEU1 */
283
28423: srlx %g4, 8, %g4 /* IEU0 Group */
285 andcc %o2, 1, %g0 /* IEU1 */
286 bne,a,pn %icc, 24f /* CTI */
287 stb %g4, [%o0] /* Store Group */
288
289 retl /* CTI+IEU1 Group */
290 nop /* IEU0 */
29124: retl /* CTI+IEU1 Group */
292 add %o0, 1, %o0 /* IEU0 */
293
294 .align 16
29555: sub %o0, 1, %g6 /* IEU0 Group */
29625: andcc %o0, 7, %g0 /* IEU1 */
297 be,a,pn %icc, 4b /* CTI */
298 andncc %o2, 31, %g3 /* IEU1 Group */
299
300 stb %g0, [%o0] /* Store Group */
301 subcc %o2, 1, %o2 /* IEU1 */
302 bne,pt %XCC, 25b /* CTI */
303 add %o0, 1, %o0 /* IEU0 Group */
304
305 retl /* CTI+IEU1 Group */
306 mov %g6, %o0 /* IEU0 */
307
308 .align 16
30926: ldub [%o1], %o3 /* Load */
310 sllx %g1, 7, %g2 /* IEU0 Group */
311 stb %o3, [%o0] /* Store */
31227: subcc %o2, 1, %o2 /* IEU1 */
313
314 be,pn %XCC, 59b /* CTI */
315 add %o1, 1, %o1 /* IEU0 Group */
316 add %o0, 1, %o0 /* IEU1 */
317 andcc %o3, 0xff, %g0 /* IEU1 Group */
318
319 be,pn %icc, 55b /* CTI */
320 lduba [%o1] ASI_PNF, %o3 /* Load */
321 andcc %o0, 7, %g0 /* IEU1 Group */
322 bne,a,pt %icc, 27b /* CTI */
323
324 stb %o3, [%o0] /* Store */
325 andcc %o1, 7, %g3 /* IEU1 Group */
326 be,a,pt %icc, 1b /* CTI */
327 ldx [%o1], %o3 /* Load */
328
32928: orcc %g0, 64, %g4 /* IEU1 Group */
330 sllx %g3, 3, %g5 /* IEU0 */
331 sub %g4, %g5, %g4 /* IEU0 Group */
332 sub %o1, %g3, %o1 /* IEU1 */
333 /* %g1 = 0101010101010101
334 %g2 = 8080808080808080
335 %g3 = source alignment
336 %g5 = number of bits to shift left
337 %g4 = number of bits to shift right */
338
339 ldxa [%o1] ASI_PNF, %o5 /* Load Group */
340 addcc %o1, 8, %o1 /* IEU1 */
34129: sllx %o5, %g5, %o3 /* IEU0 Group */
342 ldxa [%o1] ASI_PNF, %o5 /* Load */
343
344 subcc %o2, 8, %o2 /* IEU1 */
345 bl,pn %XCC, 17b /* CTI */
346 srlx %o5, %g4, %o4 /* IEU0 Group */
347 add %o1, 8, %o1 /* IEU1 */
348
349 or %o3, %o4, %o3 /* IEU0 Group */
350 add %o0, 8, %o0 /* IEU1 */
351 sub %o3, %g1, %o4 /* IEU0 Group */
352#ifdef EIGHTBIT_NOT_RARE
353 andn %o4, %o3, %o4 /* IEU0 Group */
354#endif
355 andcc %o4, %g2, %g0 /* IEU1 Group */
356
357 be,a,pt %xcc, 29b /* CTI */
358 stx %o3, [%o0-8] /* Store */
359 srlx %o3, 56, %o4 /* IEU0 Group */
360 andcc %o4, 0xff, %g0 /* IEU1 Group */
361
362 be,pn %icc, 36f /* CTI */
363 srlx %o3, 48, %g6 /* IEU0 */
364 andcc %g6, 0xff, %g0 /* IEU1 Group */
365 be,pn %icc, 35f /* CTI */
366
367 srlx %o3, 40, %o4 /* IEU0 */
368 andcc %o4, 0xff, %g0 /* IEU1 Group */
369 be,pn %icc, 34f /* CTI */
370 srlx %o3, 32, %g6 /* IEU0 */
371
372 andcc %g6, 0xff, %g0 /* IEU1 Group */
373 be,pn %icc, 33f /* CTI */
374 srlx %o3, 24, %o4 /* IEU0 */
375 andcc %o4, 0xff, %g0 /* IEU1 Group */
376
377 be,pn %icc, 32f /* CTI */
378 srlx %o3, 16, %g6 /* IEU0 */
379 andcc %g6, 0xff, %g0 /* IEU1 Group */
380 be,pn %icc, 31f /* CTI */
381
382 srlx %o3, 8, %o4 /* IEU0 */
383 andcc %o4, 0xff, %g0 /* IEU1 Group */
384 be,pn %icc, 30f /* CTI */
385 andcc %o3, 0xff, %g0 /* IEU1 Group */
386
387 bne,pn %icc, 29b /* CTI */
388 stx %o3, [%o0-8] /* Store */
389 sub %o0, 1, %g6 /* IEU0 Group */
390 ba,pt %xcc, 4b /* CTI */
391
392 andncc %o2, 31, %g3 /* IEU1 */
39330: subcc %o0, 2, %g6 /* IEU0 */
394 ba,pt %xcc, 3b /* CTI */
395 sllx %o4, 8, %g3 /* IEU0 Group */
396
39731: sllx %g6, 16, %g3 /* IEU0 Group */
398 ba,pt %xcc, 3b /* CTI */
399 sub %o0, 3, %g6 /* IEU1 */
40032: subcc %o0, 4, %g6 /* IEU1 Group */
401
402 ba,pt %xcc, 3b /* CTI */
403 sllx %o4, 24, %g3 /* IEU0 */
40433: sllx %g6, 32, %g3 /* IEU0 Group */
405 ba,pt %xcc, 3b /* CTI */
406
407 sub %o0, 5, %g6 /* IEU1 */
40834: subcc %o0, 6, %g6 /* IEU1 Group */
409 ba,pt %xcc, 3b /* CTI */
410 sllx %o4, 40, %g3 /* IEU0 */
411
41235: sllx %g6, 48, %g3 /* IEU0 Group */
413 ba,pt %xcc, 3b /* CTI */
414 sub %o0, 7, %g6 /* IEU1 */
41536: subcc %o0, 8, %g6 /* IEU1 Group */
416
417 ba,pt %xcc, 3b /* CTI */
418 sllx %o4, 56, %g3 /* IEU0 */
419END(__stpncpy)
420
421libc_hidden_def (__stpncpy)
422weak_alias (__stpncpy, stpncpy)
423

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