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-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(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

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