blob: 1fe854961316e20d8705045b7677e0602664013c [file] [log] [blame]
yuezonghe824eb0c2024-06-27 02:32:26 -07001/* Determine the length of a string. For SPARC v9.
2 Copyright (C) 1998, 1999, 2003 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4 Contributed by Jan Vondrak <jvon4518@ss1000.ms.mff.cuni.cz> and
5 Jakub Jelinek <jj@ultra.linux.cz>.
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, write to the Free
19 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20 02111-1307 USA. */
21
22#include <asm/asi.h>
23
24 /* Normally, this uses
25 ((xword - 0x0101010101010101) & 0x8080808080808080) test
26 to find out if any byte in xword could be zero. This is fast, but
27 also gives false alarm for any byte in range 0x81-0xff. It does
28 not matter for correctness, as if this test tells us there could
29 be some zero byte, we check it byte by byte, but if bytes with
30 high bits set are common in the strings, then this will give poor
31 performance. You can #define EIGHTBIT_NOT_RARE and the algorithm
32 will use one tick slower, but more precise test
33 ((xword - 0x0101010101010101) & (~xword) & 0x8080808080808080),
34 which does not give any false alarms (but if some bits are set,
35 one cannot assume from it which bytes are zero and which are not).
36 It is yet to be measured, what is the correct default for glibc
37 in these days for an average user.
38 */
39
40 .text
41 .align 32
42ENTRY(strlen)
43 sethi %hi(0x01010101), %g1 /* IEU0 Group */
44 ldub [%o0], %o3 /* Load */
45 or %g1, %lo(0x01010101), %g1 /* IEU0 Group */
46 mov %o0, %o1 /* IEU1 */
47
48 sllx %g1, 32, %g4 /* IEU0 Group */
49 andcc %o0, 7, %g0 /* IEU1 */
50 or %g1, %g4, %g1 /* IEU0 Group */
51 brz,pn %o3, 13f /* CTI+IEU1 */
52
53 sllx %g1, 7, %g4 /* IEU0 Group */
54 bne,a,pn %icc, 15f /* CTI */
55 add %o0, 1, %o0 /* IEU1 */
56 /* %g1 = 0x0101010101010101 *
57 * %g4 = 0x8080808080808080 *
58 * %o0 = string pointer *
59 * %o1 = start of string */
601: ldx [%o0], %o3 /* Load Group */
61
62 add %o0, 8, %o0 /* IEU1 */
632: sub %o3, %g1, %o2 /* IEU0 Group */
64#ifdef EIGHTBIT_NOT_RARE
65 andn %o2, %o3, %o5 /* IEU0 Group */
66 ldxa [%o0] ASI_PNF, %o3 /* Load */
67 andcc %o5, %g4, %g0 /* IEU1 Group */
68#else
69 ldxa [%o0] ASI_PNF, %o3 /* Load */
70 andcc %o2, %g4, %g0 /* IEU1 Group */
71#endif
72
73 be,pt %xcc, 2b /* CTI */
74 add %o0, 8, %o0 /* IEU0 */
75 addcc %o2, %g1, %g5 /* IEU1 Group */
76#ifdef EIGHTBIT_NOT_RARE
77 srlx %o5, 32, %o5 /* IEU0 */
78
793: andcc %o5, %g4, %g0 /* IEU1 Group */
80#else
81 srlx %o2, 32, %o2 /* IEU0 */
82
833: andcc %o2, %g4, %g0 /* IEU1 Group */
84#endif
85 be,pn %xcc, 4f /* CTI */
86 srlx %g5, 56, %o2 /* IEU0 */
87 andcc %o2, 0xff, %g0 /* IEU1 Group */
88
89 be,pn %icc, 12f /* CTI */
90 srlx %g5, 48, %o2 /* IEU0 */
91 andcc %o2, 0xff, %g0 /* IEU1 Group */
92 be,pn %icc, 11f /* CTI */
93
94 srlx %g5, 40, %o2 /* IEU0 */
95 andcc %o2, 0xff, %g0 /* IEU1 Group */
96 be,pn %icc, 10f /* CTI */
97 srlx %g5, 32, %o2 /* IEU0 */
98
99 andcc %o2, 0xff, %g0 /* IEU1 Group */
100 be,pn %icc, 9f /* CTI */
1014: srlx %g5, 24, %o2 /* IEU0 */
102 andcc %o2, 0xff, %g0 /* IEU1 Group */
103
104 be,pn %icc, 8f /* CTI */
105 srlx %g5, 16, %o2 /* IEU0 */
106 andcc %o2, 0xff, %g0 /* IEU1 Group */
107 be,pn %icc, 7f /* CTI */
108
109 srlx %g5, 8, %o2 /* IEU0 */
110 andcc %o2, 0xff, %g0 /* IEU1 Group */
111 be,pn %icc, 6f /* CTI */
112 sub %o3, %g1, %o2 /* IEU0 */
113
114 andcc %g5, 0xff, %g0 /* IEU1 Group */
115 be,pn %icc, 5f /* CTI */
116 ldxa [%o0] ASI_PNF, %o3 /* Load */
117 andcc %o2, %g4, %g0 /* IEU1 Group */
118
119 be,pt %xcc, 2b /* CTI */
120 add %o0, 8, %o0 /* IEU0 */
121 addcc %o2, %g1, %g5 /* IEU1 Group */
122 ba,pt %xcc, 3b /* CTI */
123
124 srlx %o2, 32, %o2 /* IEU0 */
1255: add %o0, -9, %o0 /* IEU0 Group */
126 retl /* CTI+IEU1 Group */
127 sub %o0, %o1, %o0 /* IEU0 */
128
1296: add %o0, -10, %o0 /* IEU0 Group */
130 retl /* CTI+IEU1 Group */
131 sub %o0, %o1, %o0 /* IEU0 */
1327: add %o0, -11, %o0 /* IEU0 Group */
133
134 retl /* CTI+IEU1 Group */
135 sub %o0, %o1, %o0 /* IEU0 */
1368: add %o0, -12, %o0 /* IEU0 Group */
137 retl /* CTI+IEU1 Group */
138
139 sub %o0, %o1, %o0 /* IEU0 */
1409: add %o0, -13, %o0 /* IEU0 Group */
141 retl /* CTI+IEU1 Group */
142 sub %o0, %o1, %o0 /* IEU0 */
143
14410: add %o0, -14, %o0 /* IEU0 Group */
145 retl /* CTI+IEU1 Group */
146 sub %o0, %o1, %o0 /* IEU0 */
14711: add %o0, -15, %o0 /* IEU0 Group */
148
149 retl /* CTI+IEU1 Group */
150 sub %o0, %o1, %o0 /* IEU0 */
15112: add %o0, -16, %o0 /* IEU0 Group */
152 retl /* CTI+IEU1 Group */
153
154 sub %o0, %o1, %o0 /* IEU0 */
15513: retl /* CTI+IEU1 Group */
156 mov 0, %o0 /* IEU0 */
157 nop
158
15915: ldub [%o0], %o3 /* Load Group */
16016: andcc %o0, 7, %g0 /* IEU1 */
161 be,pn %icc, 1b /* CTI */
162 nop /* IEU0 Group */
163
164 add %o0, 1, %o0 /* IEU1 */
165 andcc %o3, 0xff, %g0 /* IEU1 Group */
166 bne,a,pt %icc, 16b /* CTI */
167 lduba [%o0] ASI_PNF, %o3 /* Load */
168
169 add %o0, -1, %o0 /* IEU0 Group */
170 retl /* CTI+IEU1 Group */
171 sub %o0, %o1, %o0 /* IEU0 */
172END(strlen)
173libc_hidden_def(strlen)