author | Mark J. Nelson <Mark.J.Nelson@Sun.COM> |
Wed, 06 Aug 2008 16:29:39 -0600 | |
changeset 7298 | b69e27387f74 |
parent 6812 | febeba71273d |
permissions | -rw-r--r-- |
0 | 1 |
/* |
2 |
* CDDL HEADER START |
|
3 |
* |
|
4 |
* The contents of this file are subject to the terms of the |
|
6812 | 5 |
* Common Development and Distribution License (the "License"). |
6 |
* You may not use this file except in compliance with the License. |
|
0 | 7 |
* |
8 |
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE |
|
9 |
* or http://www.opensolaris.org/os/licensing. |
|
10 |
* See the License for the specific language governing permissions |
|
11 |
* and limitations under the License. |
|
12 |
* |
|
13 |
* When distributing Covered Code, include this CDDL HEADER in each |
|
14 |
* file and include the License file at usr/src/OPENSOLARIS.LICENSE. |
|
15 |
* If applicable, add the following below this CDDL HEADER, with the |
|
16 |
* fields enclosed by brackets "[]" replaced with your own identifying |
|
17 |
* information: Portions Copyright [yyyy] [name of copyright owner] |
|
18 |
* |
|
19 |
* CDDL HEADER END |
|
20 |
*/ |
|
6812 | 21 |
|
0 | 22 |
/* |
6812 | 23 |
* Copyright 2008 Sun Microsystems, Inc. All rights reserved. |
0 | 24 |
* Use is subject to license terms. |
25 |
*/ |
|
26 |
||
7298
b69e27387f74
6733918 Teamware has retired, please welcome your new manager, Mercurial
Mark J. Nelson <Mark.J.Nelson@Sun.COM>
parents:
6812
diff
changeset
|
27 |
.file "strcpy.s" |
0 | 28 |
|
29 |
/* |
|
30 |
* strcpy(s1, s2) |
|
31 |
* |
|
32 |
* Copy string s2 to s1. s1 must be large enough. Return s1. |
|
33 |
* |
|
34 |
* Fast assembler language version of the following C-program strcpy |
|
35 |
* which represents the `standard' for the C-library. |
|
36 |
* |
|
37 |
* char * |
|
38 |
* strcpy(s1, s2) |
|
39 |
* register char *s1; |
|
40 |
* register const char *s2; |
|
41 |
* { |
|
42 |
* char *os1 = s1; |
|
43 |
* |
|
44 |
* while(*s1++ = *s2++) |
|
45 |
* ; |
|
46 |
* return(os1); |
|
47 |
* } |
|
48 |
* |
|
49 |
*/ |
|
50 |
||
51 |
#include <sys/asm_linkage.h> |
|
52 |
||
53 |
! This implementation of strcpy works by first checking the |
|
54 |
! source alignment and copying byte, half byte, or word |
|
55 |
! quantities until the source ptr is aligned at an extended |
|
56 |
! word boundary. Once this has occurred, the string is copied, |
|
57 |
! checking for zero bytes, depending upon its dst ptr alignment. |
|
58 |
! (methods for xword, word, half-word, and byte copies are present) |
|
59 |
||
60 |
ENTRY(strcpy) |
|
61 |
||
62 |
.align 32 |
|
63 |
||
64 |
sub %o1, %o0, %o3 ! src - dst |
|
65 |
andcc %o1, 7, %o4 ! dword aligned ? |
|
66 |
bz,pn %ncc, .srcaligned ! yup |
|
67 |
mov %o0, %o2 ! save dst |
|
68 |
||
69 |
.chkbyte: |
|
70 |
andcc %o1, 1, %g0 ! need to copy byte ? |
|
71 |
bz,pn %ncc, .chkhalfword ! nope, maybe halfword |
|
72 |
sub %g0, %o1, %g1 ! %g1<2:0> = # of unaligned bytes |
|
73 |
ldub [%o2 + %o3], %o5 ! src[0] |
|
74 |
tst %o5 ! src[0] == 0 ? |
|
75 |
stb %o5, [%o2] ! dst[0] = src[0] |
|
76 |
bz,pn %ncc, .done ! yup, done |
|
77 |
inc %o2 ! src++, dst++ |
|
78 |
||
79 |
.chkhalfword: |
|
80 |
andcc %g1, 2, %g0 ! need to copy half-word ? |
|
81 |
bz,pn %ncc, .chkword ! nope, maybe word |
|
82 |
nop ! |
|
83 |
lduh [%o2 + %o3], %o5 ! load src halfword |
|
84 |
srl %o5, 8, %o4 ! extract first byte |
|
85 |
tst %o4 ! first byte == 0 ? |
|
86 |
bz,pn %ncc, .done ! yup, done |
|
87 |
stb %o4, [%o2] ! store first byte |
|
88 |
andcc %o5, 0xff, %g0 ! extract second byte |
|
89 |
stb %o5, [%o2 + 1] ! store second byte |
|
90 |
bz,pn %ncc, .done ! yup, 2nd byte zero, done |
|
91 |
add %o2, 2, %o2 ! src += 2 |
|
92 |
||
93 |
.chkword: |
|
94 |
andcc %g1, 4, %g0 ! need to copy word ? |
|
95 |
bz,pn %ncc, .srcaligned ! nope |
|
96 |
nop ! |
|
97 |
lduw [%o2 + %o3], %o5 ! load src word |
|
98 |
srl %o5, 24, %o4 ! extract first byte |
|
99 |
tst %o4 ! is first byte zero ? |
|
100 |
bz,pn %ncc, .done ! yup, done |
|
101 |
stb %o4, [%o2] ! store first byte |
|
102 |
srl %o5, 16, %o4 ! extract second byte |
|
103 |
andcc %o4, 0xff, %g0 ! is second byte zero ? |
|
104 |
bz,pn %ncc, .done ! yup, done |
|
105 |
stb %o4, [%o2 + 1] ! store second byte |
|
106 |
srl %o5, 8, %o4 ! extract third byte |
|
107 |
andcc %o4, 0xff, %g0 ! third byte zero ? |
|
108 |
bz,pn %ncc, .done ! yup, done |
|
109 |
stb %o4, [%o2 + 2] ! store third byte |
|
110 |
andcc %o5, 0xff, %g0 ! fourth byte zero ? |
|
111 |
stb %o5, [%o2 + 3] ! store fourth byte |
|
112 |
bz,pn %ncc, .done ! yup, fourth byte zero, done |
|
113 |
add %o2, 4, %o2 ! src += 2 |
|
114 |
||
115 |
.srcaligned: |
|
116 |
sethi %hi(0x01010101), %o4 ! Alan Mycroft's magic1 |
|
117 |
or %o4, %lo(0x01010101),%o4! finish loading magic1 |
|
118 |
sllx %o4, 32, %o1 ! spread magic1 |
|
119 |
and %o2, 3, %g4 ! dst<1:0> to examine offset |
|
120 |
or %o4, %o1, %o4 ! to all 64 bits |
|
121 |
cmp %g4, 1 ! dst offset of 1 or 5 |
|
122 |
sllx %o4, 7, %o5 ! Alan Mycroft's magic2 |
|
123 |
be,pn %ncc, .storebyte1241 ! store 1, 2, 4, 1 bytes |
|
124 |
cmp %g4, 3 ! dst offset of 3 or 7 |
|
125 |
be,pn %ncc, .storebyte1421 ! store 1, 4, 2, 1 bytes |
|
126 |
cmp %g4, 2 ! dst halfword aligned ? |
|
127 |
be,pn %ncc, .storehalfword ! yup, store half-word wise |
|
128 |
andcc %o2, 7, %g0 ! dst word aligned ? |
|
129 |
bnz,pn %ncc, .storeword2 ! yup, store word wise |
|
130 |
.empty |
|
131 |
||
132 |
.storedword: |
|
133 |
ldx [%o2 + %o3], %o1 ! src dword |
|
134 |
add %o2, 8, %o2 ! src += 8, dst += 8 |
|
135 |
andn %o5, %o1, %g1 ! ~dword & 0x8080808080808080 |
|
136 |
sub %o1, %o4, %g4 ! dword - 0x0101010101010101 |
|
137 |
andcc %g4, %g1, %g0 ! ((dword - 0x0101010101010101) & ~dword & 0x8080808080808080) |
|
138 |
bz,a,pt %ncc, .storedword ! no zero byte if magic expression == 0 |
|
139 |
stx %o1, [%o2 - 8] ! store word to dst (address pre-incremented) |
|
140 |
||
141 |
.zerobyte: |
|
142 |
orn %o4, %g0, %o4 ! 0xffffffffffffffff |
|
143 |
sllx %o4, 56, %o4 ! 0xff00000000000000 |
|
144 |
srlx %o1, 56, %o3 ! %o3<7:0> = first byte |
|
145 |
andcc %o1, %o4, %g0 ! first byte zero? |
|
146 |
bz,pn %ncc, .done ! yup, done |
|
147 |
stb %o3, [%o2 - 8] ! store first byte |
|
148 |
srlx %o4, 8, %o4 ! 0x00ff000000000000 |
|
149 |
srlx %o1, 48, %o3 ! %o3<7:0> = second byte |
|
150 |
andcc %o1, %o4, %g0 ! second byte zero? |
|
151 |
bz,pn %ncc, .done ! yup, done |
|
152 |
stb %o3, [%o2 - 7] ! store second byte |
|
153 |
srlx %o4, 8, %o4 ! 0x0000ff0000000000 |
|
154 |
srlx %o1, 40, %o3 ! %o3<7:0> = third byte |
|
155 |
andcc %o1, %o4, %g0 ! third byte zero? |
|
156 |
bz,pn %ncc, .done ! yup, done |
|
157 |
stb %o3, [%o2 - 6] ! store third byte |
|
158 |
srlx %o4, 8, %o4 ! 0x000000ff00000000 |
|
159 |
srlx %o1, 32, %o3 ! %o3<7:0> = fourth byte |
|
160 |
andcc %o1, %o4, %g0 ! fourth byte zero? |
|
161 |
bz,pn %ncc, .done ! yup, done |
|
162 |
stb %o3, [%o2 - 5] ! store fourth byte |
|
163 |
srlx %o4, 8, %o4 ! 0x00000000ff000000 |
|
164 |
srlx %o1, 24, %o3 ! %o3<7:0> = fifth byte |
|
165 |
andcc %o1, %o4, %g0 ! fifth byte zero? |
|
166 |
bz,pn %ncc, .done ! yup, done |
|
167 |
stb %o3, [%o2 - 4] ! store fifth byte |
|
168 |
srlx %o4, 8, %o4 ! 0x0000000000ff0000 |
|
169 |
srlx %o1, 16, %o3 ! %o3<7:0> = sixth byte |
|
170 |
andcc %o1, %o4, %g0 ! sixth byte zero? |
|
171 |
bz,pn %ncc, .done ! yup, done |
|
172 |
stb %o3, [%o2 - 3] ! store sixth byte |
|
173 |
srlx %o4, 8, %o4 ! 0x000000000000ff00 |
|
174 |
andcc %o1, %o4, %g0 ! seventh byte zero? |
|
175 |
srlx %o1, 8, %o3 ! %o3<7:0> = seventh byte |
|
176 |
bz,pn %ncc, .done ! yup, done |
|
177 |
stb %o3, [%o2 - 2] ! store seventh byte |
|
178 |
stb %o1, [%o2 - 1] ! store eigth byte |
|
179 |
.done: |
|
180 |
retl ! done with leaf function |
|
181 |
||
182 |
nop ! ensure following loop 16-byte aligned |
|
183 |
||
184 |
.storebyte1421: |
|
185 |
ldx [%o2 + %o3], %o1 ! x = src[] |
|
186 |
add %o2, 8, %o2 ! src += 8, dst += 8 |
|
187 |
andn %o5, %o1, %g1 ! ~x & 0x8080808080808080 |
|
188 |
sub %o1, %o4, %g4 ! x - 0x0101010101010101 |
|
189 |
andcc %g4, %g1, %g0 ! ((x - 0x0101010101010101) & ~x & 0x8080808080808080) |
|
190 |
bnz,pn %ncc, .zerobyte ! x has zero byte, handle end cases |
|
191 |
srlx %o1, 56, %g1 ! %g1<7:0> = first byte; word aligned now |
|
192 |
stb %g1, [%o2 - 8] ! store first byte |
|
193 |
srlx %o1, 24, %g1 ! %g1<31:0> = bytes 2, 3, 4, 5 |
|
194 |
stw %g1, [%o2 - 7] ! store bytes 2, 3, 4, 5 |
|
195 |
srlx %o1, 8, %g1 ! %g1<15:0> = bytes 6, 7 |
|
196 |
sth %g1, [%o2 - 3] ! store bytes 6, 7 |
|
197 |
ba .storebyte1421 ! next dword |
|
198 |
stb %o1, [%o2 - 1] ! store eigth byte |
|
199 |
||
200 |
nop ! ensure following loop 16-byte aligned |
|
201 |
nop ! ensure following loop 16-byte aligned |
|
202 |
||
203 |
.storebyte1241: |
|
204 |
ldx [%o2 + %o3], %o1 ! x = src[] |
|
205 |
add %o2, 8, %o2 ! src += 8, dst += 8 |
|
206 |
andn %o5, %o1, %g1 ! ~x & 0x8080808080808080 |
|
207 |
sub %o1, %o4, %g4 ! x - 0x0101010101010101 |
|
208 |
andcc %g4, %g1, %g0 ! ((x - 0x0101010101010101) & ~x & 0x8080808080808080) |
|
209 |
bnz,pn %ncc, .zerobyte ! x has zero byte, handle end cases |
|
210 |
srlx %o1, 56, %g1 ! %g1<7:0> = first byte; word aligned now |
|
211 |
stb %g1, [%o2 - 8] ! store first byte |
|
212 |
srlx %o1, 40, %g1 ! %g1<15:0> = bytes 2, 3 |
|
213 |
sth %g1, [%o2 - 7] ! store bytes 2, 3 |
|
214 |
srlx %o1, 8, %g1 ! %g1<31:0> = bytes 4, 5, 6, 7 |
|
215 |
stw %g1, [%o2 - 5] ! store bytes 4, 5, 6, 7 |
|
216 |
ba .storebyte1241 ! next dword |
|
217 |
stb %o1, [%o2 - 1] ! store eigth byte |
|
218 |
||
219 |
nop ! ensure following loop 16-byte aligned |
|
220 |
nop ! ensure following loop 16-byte aligned |
|
221 |
||
222 |
.storehalfword: |
|
223 |
ldx [%o2 + %o3], %o1 ! x = src[] |
|
224 |
add %o2, 8, %o2 ! src += 8, dst += 8 |
|
225 |
andn %o5, %o1, %g1 ! ~x & 0x8080808080808080 |
|
226 |
sub %o1, %o4, %g4 ! x - 0x0101010101010101 |
|
227 |
andcc %g4, %g1, %g0 ! ((x - 0x0101010101010101) & ~x & 0x8080808080808080) |
|
228 |
bnz,pn %ncc, .zerobyte ! x has zero byte, handle end cases |
|
229 |
srlx %o1, 48, %g1 ! get first and second byte |
|
230 |
sth %g1, [%o2 - 8] ! store first and second byte; word aligned now |
|
231 |
srlx %o1, 16, %g1 ! %g1<31:0> = bytes 3, 4, 5, 6 |
|
232 |
stw %g1, [%o2 - 6] ! store bytes 3, 4, 5, 6 |
|
233 |
ba .storehalfword ! next word |
|
234 |
sth %o1, [%o2 - 2] ! store seventh and eigth byte |
|
235 |
||
236 |
.storeword: |
|
237 |
ldx [%o2 + %o3], %o1 ! x = src[] |
|
238 |
.storeword2: |
|
239 |
add %o2, 8, %o2 ! src += 8, dst += 8 |
|
240 |
andn %o5, %o1, %g1 ! ~x & 0x0x8080808080808080 |
|
241 |
sub %o1, %o4, %g4 ! x - 0x0101010101010101 |
|
242 |
andcc %g4, %g1, %g0 ! ((x - 0x0101010101010101) & ~x & 0x8080808080808080) |
|
243 |
bnz,pn %ncc, .zerobyte ! x has zero byte, handle end cases |
|
244 |
srlx %o1, 32, %g1 ! get bytes 1,2,3,4 |
|
245 |
stw %g1, [%o2 - 8] ! store bytes 1,2,3,4 (address is pre-incremented) |
|
246 |
ba .storeword ! no zero byte if magic expression == 0 |
|
247 |
stw %o1, [%o2 - 4] ! store bytes 5,6,7,8 |
|
248 |
||
249 |
nop ! padding, do not remove!!! |
|
250 |
nop ! padding, do not remove!!! |
|
251 |
SET_SIZE(strcpy) |
|
252 |