Home | History | Annotate | Download | only in gen
      1     0  stevel /*
      2     0  stevel  * CDDL HEADER START
      3     0  stevel  *
      4     0  stevel  * The contents of this file are subject to the terms of the
      5  6812     raf  * Common Development and Distribution License (the "License").
      6  6812     raf  * You may not use this file except in compliance with the License.
      7     0  stevel  *
      8     0  stevel  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9     0  stevel  * or http://www.opensolaris.org/os/licensing.
     10     0  stevel  * See the License for the specific language governing permissions
     11     0  stevel  * and limitations under the License.
     12     0  stevel  *
     13     0  stevel  * When distributing Covered Code, include this CDDL HEADER in each
     14     0  stevel  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15     0  stevel  * If applicable, add the following below this CDDL HEADER, with the
     16     0  stevel  * fields enclosed by brackets "[]" replaced with your own identifying
     17     0  stevel  * information: Portions Copyright [yyyy] [name of copyright owner]
     18     0  stevel  *
     19     0  stevel  * CDDL HEADER END
     20     0  stevel  */
     21  6812     raf 
     22     0  stevel /*
     23  6812     raf  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
     24     0  stevel  * Use is subject to license terms.
     25     0  stevel  */
     26     0  stevel 
     27  7298    Mark 	.file	"strlcpy.s"
     28     0  stevel 
     29     0  stevel /*
     30     0  stevel  * The strlcpy() function copies at most dstsize-1 characters
     31     0  stevel  * (dstsize being the size of the string buffer dst) from src
     32     0  stevel  * to dst, truncating src if necessary. The result is always
     33     0  stevel  * null-terminated.  The function returns strlen(src). Buffer
     34     0  stevel  * overflow can be checked as follows:
     35     0  stevel  *
     36     0  stevel  *   if (strlcpy(dst, src, dstsize) >= dstsize)
     37     0  stevel  *           return -1;
     38     0  stevel  */
     39     0  stevel 
     40     0  stevel #include <sys/asm_linkage.h>
     41     0  stevel 
     42     0  stevel 	! strlcpy implementation is similar to that of strcpy, except
     43     0  stevel 	! in this case, the maximum size of the detination must be
     44     0  stevel 	! tracked since it bounds our maximum copy size.  However,
     45     0  stevel 	! we must still continue to check for zero since the routine
     46     0  stevel 	! is expected to null-terminate any string that is within
     47     0  stevel 	! the dest size bound.
     48     0  stevel 	!
     49     0  stevel 	! this method starts by checking for and arranging source alignment.
     50     0  stevel 	! Once this has occurred, we copy based upon destination alignment.
     51     0  stevel 	! This is either by xword, word, halfword, or byte.  As this occurs, we
     52     0  stevel 	! check for a zero-byte.  If one is found, we branch to a method
     53     0  stevel 	! which checks for the exact location of a zero-byte within a
     54     0  stevel 	! larger xword/word/half-word quantity.
     55     0  stevel 
     56     0  stevel 
     57     0  stevel 	ENTRY(strlcpy)
     58     0  stevel 
     59     0  stevel 	.align 32
     60     0  stevel 
     61     0  stevel 	save	%sp, -SA(WINDOWSIZE), %sp
     62     0  stevel 	subcc	%g0, %i2, %g4		! n = -n, n == 0 ?
     63     0  stevel 	bz,pn	%ncc, .getstrlen	! n == 0, must determine strlen
     64     0  stevel 	add	%i1, %i2, %i3		! src = src + n
     65     0  stevel 	andcc	%i1, 7, %i4		! src dword aligned ?
     66     0  stevel 	bz,pn	%ncc, .dwordaligned	! yup
     67     0  stevel 	add	%i0, %i2, %i2		! dst = dst + n
     68     0  stevel 	sub	%i4, 8, %i4		! bytes until src aligned
     69     0  stevel 
     70     0  stevel .alignsrc:
     71     0  stevel 	ldub	[%i3 + %g4], %l1	! src[]
     72     0  stevel 	andcc	%l1, 0xff, %g0		! end of src reached (null byte) ?
     73     0  stevel 	stub	%l1, [%i2 + %g4]	! dst[] = src[]
     74     0  stevel 	bz,a	%ncc, .done		! yes, done
     75     0  stevel 	add 	%i2, %g4, %i2		! need single dest pointer for strlen
     76     0  stevel 	addcc	%g4, 1, %g4		! src++, dst++, n--
     77     0  stevel 	bz,pn	%ncc, .forcenullunalign	! n == 0, force null byte, compute len
     78     0  stevel 	addcc	%i4, 1, %i4		! src aligned now?
     79     0  stevel 	bnz,a	%ncc, .alignsrc		! no, copy another byte
     80     0  stevel 	nop				! pad
     81     0  stevel 
     82     0  stevel .dwordaligned:
     83     0  stevel 	sethi	%hi(0x01010101), %i4	! Alan Mycroft's magic1
     84     0  stevel 	add	%i2, %g4, %l0		! dst
     85     0  stevel 	or	%i4, %lo(0x01010101),%i4!  finish loading magic1
     86     0  stevel 	and	%l0, 3, %g1		! dst<1:0> to examine offset
     87     0  stevel 	sllx	%i4, 32, %l1		! spread magic1
     88     0  stevel 	cmp	%g1, 1			! dst offset of 1 or 5
     89     0  stevel 	or	%i4, %l1, %i4		!   to all 64 bits
     90     0  stevel 	sub	%i2, 8, %i2		! adjust for dest pre-incr in cpy loops
     91     0  stevel 	be,pn	%ncc, .storebyte1241	! store 1, 2, 4, 1 bytes
     92     0  stevel 	sllx	%i4, 7, %i5		!  Alan Mycroft's magic2
     93     0  stevel 	cmp	%g1, 3			! dst offset of 3 or 7
     94     0  stevel 	be,pn	%ncc, .storebyte1421	! store 1, 4, 2, 1 bytes
     95     0  stevel 	cmp	%g1, 2			! dst halfword aligned ?
     96     0  stevel 	be,pn	%ncc, .storehalfword	! yup, store half-word wise
     97     0  stevel 	andcc	%l0, 7, %g0		! dst word aligned ?
     98     0  stevel 	bnz,pn	%ncc, .storeword2	! yup, store word wise
     99     0  stevel 	nop				! ensure loop is 16-byte aligned
    100     0  stevel 	nop				! ensure loop is 16-byte aligned
    101     0  stevel 
    102     0  stevel .storedword:
    103     0  stevel 	ldx	[%i3 + %g4], %l1	! src dword
    104     0  stevel 	addcc	%g4, 8, %g4		! n += 8, src += 8, dst += 8
    105     0  stevel 	bcs,pn	%ncc, .lastword		! if counter wraps, last word
    106     0  stevel 	andn	%i5, %l1, %g1		! ~dword & 0x8080808080808080
    107     0  stevel 	sub	%l1, %i4, %l0		! dword - 0x0101010101010101
    108     0  stevel 	andcc	%l0, %g1, %g0		! ((dword - 0x0101010101010101) & ~dword & 0x8080808080808080)
    109     0  stevel 	bz,a,pt	%ncc, .storedword	! no zero byte if magic expression == 0
    110     0  stevel 	stx	%l1, [%i2 + %g4]	! store word to dst (address pre-incremented)
    111     0  stevel 
    112     0  stevel 	! n has not expired, but src is at the end. we need to push out the
    113     0  stevel 	! remaining src bytes. Since strlen(dts) == strlen(src), we can
    114     0  stevel 	! compute the return value as the difference of final dst pointer
    115     0  stevel 	! and the pointer to the start of dst
    116     0  stevel 
    117     0  stevel .zerobyte:
    118     0  stevel 	add	%i2, %g4, %i2		! pointer to dest string
    119     0  stevel 	srlx	%l1, 56, %g1		! first byte
    120     0  stevel 	andcc	%g1, 0xff, %g0		! end of string ?
    121     0  stevel 	bz,pn	%ncc, .done		! yup, copy done, return length
    122     0  stevel 	stb	%g1, [%i2]		! store it
    123     0  stevel 	add	%i2, 1, %i2		! dst++
    124     0  stevel 	srlx	%l1, 48, %g1		! second byte
    125     0  stevel 	andcc	%g1, 0xff, %g0		! end of string ?
    126     0  stevel 	bz,pn	%ncc, .done		! yup, copy done, return length
    127     0  stevel 	stb	%g1, [%i2]		! store it
    128     0  stevel 	add	%i2, 1, %i2		! dst++
    129     0  stevel 	srlx	%l1, 40, %g1		! third byte
    130     0  stevel 	andcc	%g1, 0xff, %g0		! end of string ?
    131     0  stevel 	bz,pn	%ncc, .done		! yup, copy done, return length
    132     0  stevel 	stb	%g1, [%i2]		! store it
    133     0  stevel 	add	%i2, 1, %i2		! dst++
    134     0  stevel 	srlx	%l1, 32, %g1		! fourth byte
    135     0  stevel 	andcc	%g1, 0xff, %g0		! end of string ?
    136     0  stevel 	bz,pn	%ncc, .done		! yup, copy done, return length
    137     0  stevel 	stb	%g1, [%i2]		! store it
    138     0  stevel 	add	%i2, 1, %i2		! dst++
    139     0  stevel 	srlx	%l1, 24, %g1		! fifth byte
    140     0  stevel 	andcc	%g1, 0xff, %g0		! end of string ?
    141     0  stevel 	bz,pn	%ncc, .done		! yup, copy done, return length
    142     0  stevel 	stb	%g1, [%i2]		! store it
    143     0  stevel 	add	%i2, 1, %i2		! dst++
    144     0  stevel 	srlx	%l1, 16, %g1		! sixth byte
    145     0  stevel 	andcc	%g1, 0xff, %g0		! end of string ?
    146     0  stevel 	bz,pn	%ncc, .done		! yup, copy done, return length
    147     0  stevel 	stb	%g1, [%i2]		! store it
    148     0  stevel 	add	%i2, 1, %i2		! dst++
    149     0  stevel 	srlx	%l1, 8, %g1		! seventh byte
    150     0  stevel 	andcc	%g1, 0xff, %g0		! end of string ?
    151     0  stevel 	bz,pn	%ncc, .done		! yup, copy done, return length
    152     0  stevel 	stb	%g1, [%i2]		! store it
    153     0  stevel 	stb	%l1, [%i2 + 1]		! store eigth byte
    154     0  stevel 	add	%i2, 1, %i2		! dst++
    155     0  stevel 
    156     0  stevel .done:
    157     0  stevel 	sub	%i2, %i0, %i0		! len = dst - orig dst
    158     0  stevel 	ret				! subroutine done
    159     0  stevel 	restore	%i0, %g0, %o0		! restore register window, return len
    160     0  stevel 
    161     0  stevel 	! n expired, so this is the last word. It may contain null bytes.
    162     0  stevel 	! Store bytes until n == 0. If a null byte is encountered during
    163     0  stevel 	! processing of this last src word, we are done. Otherwise continue
    164     0  stevel 	! to scan src until we hit the end, and compute strlen from the
    165     0  stevel 	! difference between the pointer past the last byte of src and the
    166     0  stevel 	! original pointer to the start of src
    167     0  stevel 
    168     0  stevel .lastword:
    169     0  stevel 	add	%i2, %g4, %i2		! we want a single dst pointer here
    170     0  stevel 	sub	%g4, 8, %g4		! undo counter pre-increment
    171     0  stevel 	add	%i3, %g4, %i3		! we want a single src pointer here
    172     0  stevel 
    173     0  stevel 	srlx	%l1, 56, %g1		! first byte
    174     0  stevel 	andcc	%g1, 0xff, %g0		! end of src reached ?
    175     0  stevel 	bz,pn	%ncc, .done		! yup
    176     0  stevel 	stb	%g1, [%i2]		! store it
    177     0  stevel 	inccc	%g4			! n--
    178     0  stevel 	bz	.forcenull		! if n == 0, force null byte, compute len
    179     0  stevel 	srlx	%l1, 48, %g1		! second byte
    180     0  stevel 	add	%i2, 1, %i2		! dst++
    181     0  stevel 	andcc	%g1, 0xff, %g0		! end of src reached ?
    182     0  stevel 	bz,pn	%ncc, .done		! yup
    183     0  stevel 	stb	%g1, [%i2]		! store it
    184     0  stevel 	inccc	%g4			! n--
    185     0  stevel 	bz	.forcenull		! if n == 0, force null byte, compute len
    186     0  stevel 	srlx	%l1, 40, %g1		! third byte
    187     0  stevel 	add	%i2, 1, %i2		! dst++
    188     0  stevel 	andcc	%g1, 0xff, %g0		! end of src reached ?
    189     0  stevel 	bz,pn	%ncc, .done		! yup
    190     0  stevel 	stb	%g1, [%i2]		! store it
    191     0  stevel 	inccc	%g4			! n--
    192     0  stevel 	bz	.forcenull		! if n == 0, force null byte, compute strlen
    193     0  stevel 	srlx	%l1, 32, %g1		! fourth byte
    194     0  stevel 	add	%i2, 1, %i2		! dst++
    195     0  stevel 	andcc	%g1, 0xff, %g0		! end of src reached ?
    196     0  stevel 	bz,pn	%ncc, .done		! yup
    197     0  stevel 	stb	%g1, [%i2]		! store it
    198     0  stevel 	inccc	%g4			! n--
    199     0  stevel 	bz	.forcenull		! if n == 0, force null byte, compute strlen
    200     0  stevel 	srlx	%l1, 24, %g1		! fifth byte
    201     0  stevel 	add	%i2, 1, %i2		! dst++
    202     0  stevel 	andcc	%g1, 0xff, %g0		! end of src reached ?
    203     0  stevel 	bz,pn	%ncc, .done		! yup
    204     0  stevel 	stb	%g1, [%i2]		! store it
    205     0  stevel 	inccc	%g4			! n--
    206     0  stevel 	bz	.forcenull		! if n == 0, force null byte, compute strlen
    207     0  stevel 	srlx	%l1, 16, %g1		! sixth byte
    208     0  stevel 	add	%i2, 1, %i2		! dst++
    209     0  stevel 	andcc	%g1, 0xff, %g0		! end of src reached ?
    210     0  stevel 	bz,pn	%ncc, .done		! yup
    211     0  stevel 	stb	%g1, [%i2]		! store it
    212     0  stevel 	inccc	%g4			! n--
    213     0  stevel 	bz	.forcenull		! if n == 0, force null byte, compute strlen
    214     0  stevel 	srlx	%l1, 8, %g1		! seventh byte
    215     0  stevel 	add	%i2, 1, %i2		! dst++
    216     0  stevel 	andcc	%g1, 0xff, %g0		! end of src reached ?
    217     0  stevel 	bz,pn	%ncc, .done		! yup
    218     0  stevel 	stb	%g1, [%i2]		! store it
    219     0  stevel 	inccc	%g4			! n--
    220     0  stevel 	bz	.forcenull		! if n == 0, force null byte, compute strlen
    221     0  stevel 	andcc	%l1, 0xff, %g0		! end of src reached ?
    222     0  stevel 	add	%i2, 1, %i2		! dst++
    223     0  stevel 	bz,pn	%ncc, .done		! yup
    224     0  stevel 	stb	%l1, [%i2]		! store eigth byte
    225     0  stevel 
    226     0  stevel 	! we need to force a null byte in the last position of dst
    227     0  stevel 	! %i2 points to the location
    228     0  stevel 
    229     0  stevel .forcenull:
    230     0  stevel 	stb	%g0, [%i2]		! force string terminating null byte
    231     0  stevel 
    232     0  stevel 	! here: %i1 points to src start
    233     0  stevel 	!	%i3 points is current src ptr (8-byte aligned)
    234     0  stevel 
    235     0  stevel .searchword:
    236     0  stevel 	ldx	[%i3], %l1		! src dword
    237     0  stevel .searchword2:
    238     0  stevel 	andn	%i5, %l1, %g1		! ~dword & 0x8080808080808080
    239     0  stevel 	sub	%l1, %i4, %l0		! dword - 0x0101010101010101
    240     0  stevel 	andcc	%l0, %g1, %g0		! ((dword - 0x0101010101010101) & ~dword & 0x80808080
    241     0  stevel 	bz,a,pt	%ncc, .searchword	! no null byte if expression is 0
    242     0  stevel 	add	%i3, 8, %i3		! src += 8
    243     0  stevel 
    244     0  stevel 	mov	0xff, %i5		! create byte mask for null byte scanning
    245     0  stevel 	sllx	%i5, 56, %i5		! mask for 1st byte = 0xff0000000000000000
    246     0  stevel .searchbyte:
    247     0  stevel 	andcc	%l1, %i5, %g0		! current byte zero?
    248     0  stevel 	srlx	%i5, 8, %i5		! byte mask for next byte
    249     0  stevel 	bnz,a	%ncc, .searchbyte	! current byte != zero, continue search
    250     0  stevel 	add	%i3, 1, %i3		! src++
    251     0  stevel 
    252     0  stevel .endfound:
    253     0  stevel 	sub	%i3, %i1, %i0		! len = src - orig src
    254     0  stevel 	ret				! done
    255     0  stevel 	restore	%i0, %g0, %o0		! restore register window, return len
    256     0  stevel 	nop				! align loop on 16-byte
    257     0  stevel 
    258     0  stevel .storebyte1421:
    259     0  stevel 	ldx	[%i3 + %g4], %l1	! x = src[]
    260     0  stevel 	addcc	%g4, 8, %g4		! src += 8, dst += 8
    261     0  stevel 	bcs,pn	%ncc, .lastword		! if counter wraps, last word
    262     0  stevel 	andn	%i5, %l1, %g1		! ~x & 0x8080808080808080
    263     0  stevel 	sub	%l1, %i4, %l0		! x - 0x0101010101010101
    264     0  stevel 	andcc	%l0, %g1, %g0		! ((x - 0x0101010101010101) & ~x & 0x8080808080808080)
    265     0  stevel 	bnz,pn	%ncc, .zerobyte		! end of src found, may need to pad
    266     0  stevel 	add	%i2, %g4, %l0		! dst (in pointer form)
    267     0  stevel 	srlx	%l1, 56, %g1		! %g1<7:0> = first byte; word aligned now
    268     0  stevel 	stb	%g1, [%l0]		! store first byte
    269     0  stevel 	srlx	%l1, 24, %g1		! %g1<31:0> = bytes 2, 3, 4, 5
    270     0  stevel 	stw	%g1, [%l0 + 1]		! store bytes 2, 3, 4, 5
    271     0  stevel 	srlx	%l1, 8, %g1		! %g1<15:0> = bytes 6, 7
    272     0  stevel 	sth	%g1, [%l0 + 5]		! store bytes 6, 7
    273     0  stevel 	ba	.storebyte1421		! next dword
    274     0  stevel 	stb	%l1, [%l0 + 7]		! store eigth byte
    275     0  stevel 
    276     0  stevel .storebyte1241:
    277     0  stevel 	ldx	[%i3 + %g4], %l1	! x = src[]
    278     0  stevel 	addcc	%g4, 8, %g4		! src += 8, dst += 8
    279     0  stevel 	bcs,pn	%ncc, .lastword		! if counter wraps, last word
    280     0  stevel 	andn	%i5, %l1, %g1		! ~x & 0x8080808080808080
    281     0  stevel 	sub	%l1, %i4, %l0		! x - 0x0101010101010101
    282     0  stevel 	andcc	%l0, %g1, %g0		! ((x - 0x0101010101010101) & ~x & 0x8080808080808080)
    283     0  stevel 	bnz,pn	%ncc, .zerobyte		! x has zero byte, handle end cases
    284     0  stevel 	add	%i2, %g4, %l0		! dst (in pointer form)
    285     0  stevel 	srlx	%l1, 56, %g1		! %g1<7:0> = first byte; half-word aligned now
    286     0  stevel 	stb	%g1, [%l0]		! store first byte
    287     0  stevel 	srlx	%l1, 40, %g1		! %g1<15:0> = bytes 2, 3
    288     0  stevel 	sth	%g1, [%l0 + 1]		! store bytes 2, 3
    289     0  stevel 	srlx	%l1, 8, %g1		! %g1<31:0> = bytes 4, 5, 6, 7
    290     0  stevel 	stw	%g1, [%l0 + 3]		! store bytes 4, 5, 6, 7
    291     0  stevel 	ba	.storebyte1241		! next dword
    292     0  stevel 	stb	%l1, [%l0 + 7]		! store eigth byte
    293     0  stevel 
    294     0  stevel .storehalfword:
    295     0  stevel 	ldx	[%i3 + %g4], %l1	! x = src[]
    296     0  stevel 	addcc	%g4, 8, %g4		! src += 8, dst += 8
    297     0  stevel 	bcs,pn	%ncc, .lastword		! if counter wraps, last word
    298     0  stevel 	andn	%i5, %l1, %g1		! ~x & 0x8080808080808080
    299     0  stevel 	sub	%l1, %i4, %l0		! x - 0x0101010101010101
    300     0  stevel 	andcc	%l0, %g1, %g0		! ((x - 0x0101010101010101) & ~x & 0x8080808080808080)
    301     0  stevel 	bnz,pn	%ncc, .zerobyte		! x has zero byte, handle end cases
    302     0  stevel 	add	%i2, %g4, %l0		! dst (in pointer form)
    303     0  stevel 	srlx	%l1, 48, %g1		! %g1<15:0> = bytes 1, 2; word aligned now
    304     0  stevel 	sth	%g1, [%l0]		! store bytes 1, 2
    305     0  stevel 	srlx	%l1, 16, %g1		! %g1<31:0> = bytes 3, 4, 5, 6
    306     0  stevel 	stw	%g1, [%l0 + 2]		! store bytes 3, 4, 5, 6
    307     0  stevel 	ba	.storehalfword		! next dword
    308     0  stevel 	sth	%l1, [%l0 + 6]		! store bytes 7, 8
    309     0  stevel 	nop				! align next loop to 16-byte boundary
    310     0  stevel 	nop				! align next loop to 16-byte boundary
    311     0  stevel 
    312     0  stevel .storeword2:
    313     0  stevel 	ldx	[%i3 + %g4], %l1	! x = src[]
    314     0  stevel 	addcc	%g4, 8, %g4		! src += 8, dst += 8
    315     0  stevel 	bcs,pn	%ncc, .lastword		! if counter wraps, last word
    316     0  stevel 	andn	%i5, %l1, %g1		! ~x & 0x8080808080808080
    317     0  stevel 	sub	%l1, %i4, %l0		! x - 0x0101010101010101
    318     0  stevel 	andcc	%l0, %g1, %g0		! ((x - 0x0101010101010101) & ~x & 0x8080808080808080)
    319     0  stevel 	bnz,pn	%ncc, .zerobyte		! x has zero byte, handle end cases
    320     0  stevel 	add	%i2, %g4, %l0		! dst (in pointer form)
    321     0  stevel 	srlx	%l1, 32, %g1		! %g1<31:0> = bytes 1, 2, 3, 4
    322     0  stevel 	stw	%g1, [%l0]		! store bytes 1, 2, 3, 4
    323     0  stevel 	ba	.storeword2		! next dword
    324     0  stevel 	stw	%l1, [%l0 + 4]		! store bytes 5, 6, 7, 8
    325     0  stevel 
    326     0  stevel 	! n expired, i.e. end of destination buffer reached. Force null
    327     0  stevel 	! null termination of dst, then scan src until end foudn for
    328     0  stevel 	! determination of strlen(src)
    329     0  stevel 	!
    330     0  stevel 	! here: %i3 points to current src byte
    331     0  stevel 	!       %i2 points one byte past end of dst
    332     0  stevel 	! magic constants not loaded
    333     0  stevel 
    334     0  stevel .forcenullunalign:
    335     0  stevel 	add	%i2, %g4, %i2		! we need a single dst ptr
    336     0  stevel 	stb	%g0, [%i2 - 1]		! force string terminating null byte
    337     0  stevel 
    338     0  stevel .getstrlen:
    339     0  stevel 	sethi	%hi(0x01010101), %i4	! Alan Mycroft's magic1
    340     0  stevel 	or	%i4, %lo(0x01010101),%i4!  finish loading magic1
    341     0  stevel 	sllx	%i4, 32, %i2		! spread magic1
    342     0  stevel 	or	%i4, %i2, %i4		!   to all 64 bits
    343     0  stevel 	sllx	%i4, 7, %i5		!  Alan Mycroft's magic2
    344     0  stevel 	nop				! align loop to 16-byte boundary
    345     0  stevel 
    346     0  stevel .getstrlenloop:
    347     0  stevel 	andcc	%i3, 7, %g0		! src dword aligned?
    348     0  stevel 	bz,a,pn	%ncc, .searchword2	! yup, now search a dword at a time
    349     0  stevel 	ldx	[%i3], %l1		! src dword
    350     0  stevel 	ldub	[%i3], %l1		! load src byte
    351     0  stevel 	andcc	%l1, 0xff, %g0		! end of src reached?
    352     0  stevel 	bnz,a	%ncc, .getstrlenloop	! yup, return length
    353     0  stevel 	add	%i3, 1, %i3		! src++
    354     0  stevel 	sub	%i3, %i1, %i0		! len = src - orig src
    355     0  stevel 	ret				! done
    356     0  stevel 	restore	%i0, %g0, %o0		! restore register window, return len
    357     0  stevel 
    358     0  stevel 	nop				! pad tp 16-byte boundary
    359     0  stevel 	nop				! pad tp 16-byte boundary
    360     0  stevel 	SET_SIZE(strlcpy)
    361