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