kernel: remove unused utsname_set_machine()
[unleashed.git] / usr / src / lib / libc / sparc / gen / strlcpy.s
blob61ef629026db19b4084bea5172aea3bc9f5c445a
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
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.
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]
19 * CDDL HEADER END
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 .file "strlcpy.s"
29 * The strlcpy() function copies at most dstsize-1 characters
30 * (dstsize being the size of the string buffer dst) from src
31 * to dst, truncating src if necessary. The result is always
32 * null-terminated. The function returns strlen(src). Buffer
33 * overflow can be checked as follows:
35 * if (strlcpy(dst, src, dstsize) >= dstsize)
36 * return -1;
39 #include <sys/asm_linkage.h>
41 ! strlcpy implementation is similar to that of strcpy, except
42 ! in this case, the maximum size of the detination must be
43 ! tracked since it bounds our maximum copy size. However,
44 ! we must still continue to check for zero since the routine
45 ! is expected to null-terminate any string that is within
46 ! the dest size bound.
48 ! this method starts by checking for and arranging source alignment.
49 ! Once this has occurred, we copy based upon destination alignment.
50 ! This is either by word, halfword, or byte. As this occurs, we
51 ! check for a zero-byte. If one is found, we branch to a method
52 ! which checks for the exact location of a zero-byte within a
53 ! larger word/half-word quantity.
55 ENTRY(strlcpy)
57 .align 32
58 save %sp, -SA(WINDOWSIZE), %sp
59 subcc %g0, %i2, %g4 ! n = -n or n == 0 ?
60 bz,pn %icc, .getstrlen ! if 0 do nothing but strlen(src)
61 add %i1, %i2, %i3 ! i3 = src + n
62 andcc %i1, 3, %i4 ! word aligned?
63 bz,pn %icc, .wordaligned
64 add %i0, %i2, %i2 ! n = dst + n
65 sub %i4, 4, %i4 ! bytes until src aligned
67 .alignsrc:
68 ldub [%i3 + %g4], %l1 ! l1 = src[]
69 andcc %l1, 0xff, %g0 ! null byte reached?
70 stub %l1, [%i2 + %g4] ! dst[] = src[]
71 bz,a %icc, .done
72 add %i2, %g4, %i2 ! get single dest ptr for strlen
73 addcc %g4, 1, %g4 ! src++ dest++ n--
74 bz,pn %icc, .forcenullunalign ! n == 0, append null byte
75 addcc %i4, 1, %i4 ! incr, check align
76 bnz,a %icc, .alignsrc
77 nop
79 .wordaligned:
80 sethi %hi(0x01010101), %i4
81 add %i2, %g4, %l0 ! l0 = dest
82 or %i4, %lo(0x01010101), %i4
83 sub %i2, 4, %i2 ! pre-incr for in cpy loop
84 andcc %l0, 3, %g1 ! word aligned?
85 bnz %icc, .dstnotaligned
86 sll %i4, 7, %i5 ! Mycroft part deux
88 .storeword:
89 ld [%i3 + %g4], %l1 ! l1 = src[]
90 addcc %g4, 4, %g4 ! n += 4, src += 4, dst +=4
91 bcs,pn %icc, .lastword
92 andn %i5, %l1, %g1 ! ~word & 0x80808080
93 sub %l1, %i4, %l0 ! word - 0x01010101
94 andcc %l0, %g1, %g0 ! doit
95 bz,a,pt %icc, .storeword ! if expr == 0, no zero byte
96 st %l1, [%i2 + %g4] ! dst[] = src[]
98 .zerobyte:
99 add %i2, %g4, %i2 ! ptr to dest
100 srl %l1, 24, %g1 ! 1st byte
101 andcc %g1, 0xff, %g0 ! test for end
102 bz,pn %icc, .done
103 stb %g1, [%i2] ! store byte
104 add %i2, 1, %i2 ! dst ++
105 srl %l1, 16, %g1 ! 2nd byte
106 andcc %g1, 0xff, %g0 ! zero byte ?
107 bz,pn %icc, .done
108 stb %g1, [%i2] ! store byte
109 add %i2, 1, %i2 ! dst ++
110 srl %l1, 8, %g1 ! 3rd byte
111 andcc %g1, 0xff, %g0 ! zero byte ?
112 bz,pn %icc, .done
113 stb %g1, [%i2] ! store byte
114 stb %l1, [%i2 + 1] ! store last byte
115 add %i2, 1, %i2 ! dst ++
117 .done:
118 sub %i2, %i0, %i0 ! len = dst - orig dst
120 restore %i0, %g0, %o0
122 .lastword:
123 add %i2, %g4, %i2
124 sub %g4, 4, %g4 ! undo pre-incr
125 add %i3, %g4, %i3
127 srl %l1, 24, %g1 ! 1st byte
128 andcc %g1, 0xff, %g0 ! zero byte?
129 bz,pn %icc, .done
130 stb %g1, [%i2] ! store byte
131 inccc %g4 ! n--
132 bz .forcenull
133 srl %l1, 16, %g1 ! 2nd byte
134 add %i2, 1, %i2 ! dst++
135 andcc %g1, 0xff, %g0 ! zero?
136 bz,pn %icc, .done
137 stb %g1, [%i2] ! store
138 inccc %g4
139 bz .forcenull
140 srl %l1, 8, %g1 ! 3rd byte
141 add %i2, 1, %i2 ! dst++
142 andcc %g1, 0xff, %g0 ! zero?
143 bz,pn %icc, .done
144 stb %g1, [%i2] ! store
145 inccc %g4 ! n--
146 bz .forcenull
147 andcc %l1, 0xff, %g0 ! zero?
148 add %i2, 1, %i2 ! dst++
149 bz,pn %ncc, .done
150 stb %l1, [%i2]
152 .forcenull:
153 stb %g0, [%i2]
155 .searchword:
156 ld [%i3], %l1
157 .searchword2:
158 andn %i5, %l1, %g1 ! word & 0x80808080
159 sub %l1, %i4, %l0 ! word - 0x01010101
160 andcc %l0, %g1, %g0 ! do it
161 bz,a,pt %icc, .searchword
162 add %i3, 4, %i3 ! src += 4
164 mov 0xff, %i5
165 sll %i5, 24, %i5 ! mask 1st byte = 0xff000000
166 .searchbyte:
167 andcc %l1, %i5, %g0 ! cur byte 0?
168 srl %i5, 8, %i5 ! mask next byte
169 bnz,a %icc, .searchbyte ! cur !=0 continue
170 add %i3, 1, %i3
172 .endfound:
173 sub %i3, %i1, %i0 ! len = src - orig src
175 restore %i0, %g0, %o0
178 .dstnotaligned:
179 cmp %g1, 2 ! halfword aligned?
180 be .storehalfword2
181 .empty
182 .storebyte:
183 ld [%i3 + %g4], %l1 ! load src word
184 addcc %g4, 4, %g4 ! src +=4 dst +=4
185 bcs,pn %icc, .lastword
186 andn %i5, %l1, %g1 ! ~x & 0x80808080
187 sub %l1, %i4, %l0 ! x - 0x01010101
188 andcc %l0, %g1, %g0 ! get your Mycroft on
189 bnz,pn %icc, .zerobyte ! non-zero, we have zero byte
190 add %i2, %g4, %l0 ! dst in ptr form
191 srl %l1, 24, %g1 ! get 1st byte, then be hw aligned
192 stb %g1, [%l0]
193 srl %l1, 8, %g1 ! 2nd & 3rd bytes
194 sth %g1, [%l0 + 1]
195 ba .storebyte
196 stb %l1, [%l0 + 3] ! store 4th byte
198 .storehalfword:
199 ld [%i3 + %g4], %l1 ! src word
200 .storehalfword2:
201 addcc %g4, 4, %g4 ! src += 4 dst += 4
202 bcs,pn %icc, .lastword
203 andn %i5, %l1, %g1 ! ~x & 0x80808080
204 sub %l1, %i4, %l0 ! x - 0x01010101
205 andcc %l0, %g1, %g0 ! Mycroft again...
206 bnz,pn %icc, .zerobyte ! non-zer, we have zero byte
207 add %i2, %g4, %l0 ! dst in ptr form
208 srl %l1, 16, %g1 ! first two bytes
209 sth %g1, [%l0]
210 ba .storehalfword
211 sth %l1, [%l0 + 2]
213 .forcenullunalign:
214 add %i2, %g4, %i2 ! single dst ptr
215 stb %g0, [%i2 - 1] ! store terminating null byte
217 .getstrlen:
218 sethi %hi(0x01010101), %i4 ! Mycroft...
219 or %i4, %lo(0x01010101), %i4
220 sll %i4, 7, %i5
222 .getstrlenloop:
223 andcc %i3, 3, %g0 ! word aligned?
224 bz,a,pn %icc, .searchword2 ! search word at a time
225 ld [%i3], %l1 ! src word
226 ldub [%i3], %l1 ! src byte
227 andcc %l1, 0xff, %g0 ! end of src?
228 bnz,a %icc, .getstrlenloop
229 add %i3, 1, %i3 ! src ++
230 sub %i3, %i1, %i0 ! len = src - orig src
232 restore %i0, %g0, %o0
233 SET_SIZE(strlcpy)