usr/src/lib/libc/sparcv9/gen/strcpy.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	"strcpy.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
 * strcpy(s1, s2)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    31
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    32
 * Copy string s2 to s1.  s1 must be large enough. Return s1.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    33
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    34
 * Fast assembler language version of the following C-program strcpy
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    35
 * which represents the `standard' for the C-library.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    36
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    37
 *	char *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    38
 *	strcpy(s1, s2)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    39
 *	register char *s1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    40
 *	register const char *s2;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    41
 *	{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    42
 *		char *os1 = s1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    43
 *	
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    44
 *		while(*s1++ = *s2++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    45
 *			;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    46
 *		return(os1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    47
 *	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    48
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    49
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    50
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    51
#include <sys/asm_linkage.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    52
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    53
	! This implementation of strcpy works by first checking the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    54
	! source alignment and copying byte, half byte, or word
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    55
	! quantities until the source ptr is aligned at an extended
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    56
	! word boundary.  Once this has occurred, the string is copied,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    57
	! checking for zero bytes, depending upon its dst ptr alignment.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    58
	! (methods for xword, word, half-word, and byte copies are present)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    59
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    60
	ENTRY(strcpy)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    61
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    62
	.align 32
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    63
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    64
	sub	%o1, %o0, %o3		! src - dst
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    65
	andcc	%o1, 7, %o4		! dword aligned ?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    66
	bz,pn	%ncc, .srcaligned	! yup
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    67
	mov	%o0, %o2		! save dst
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    68
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    69
.chkbyte:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    70
	andcc	%o1, 1, %g0		! need to copy byte ?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    71
	bz,pn	%ncc, .chkhalfword	! nope, maybe halfword
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    72
	sub	%g0, %o1, %g1		! %g1<2:0> = # of unaligned bytes
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    73
	ldub	[%o2 + %o3], %o5	! src[0]
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    74
	tst	%o5			! src[0] == 0 ?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    75
	stb	%o5, [%o2]		! dst[0] = src[0]
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    76
	bz,pn	%ncc, .done		! yup, done
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    77
	inc	%o2			! src++, dst++
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    78
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    79
.chkhalfword:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    80
	andcc	%g1, 2, %g0		! need to copy half-word ?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    81
	bz,pn	%ncc, .chkword		! nope, maybe word
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    82
	nop				! 
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    83
	lduh	[%o2 + %o3], %o5	! load src halfword
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    84
	srl	%o5, 8, %o4		! extract first byte
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    85
	tst	%o4			! first byte == 0 ?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    86
	bz,pn	%ncc, .done		! yup, done
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    87
	stb	%o4, [%o2]		! store first byte
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    88
	andcc	%o5, 0xff, %g0		! extract second byte
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    89
	stb 	%o5, [%o2 + 1]		! store second byte
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    90
	bz,pn	%ncc, .done		! yup, 2nd byte zero, done
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    91
	add	%o2, 2, %o2		! src += 2
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    92
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    93
.chkword:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    94
	andcc	%g1, 4, %g0		! need to copy word ?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    95
	bz,pn	%ncc, .srcaligned	! nope
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    96
	nop				! 
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    97
	lduw	[%o2 + %o3], %o5	! load src word
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    98
	srl	%o5, 24, %o4		! extract first byte
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    99
	tst	%o4			! is first byte zero ?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   100
	bz,pn	%ncc, .done		! yup, done
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   101
	stb	%o4, [%o2]		! store first byte
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   102
	srl	%o5, 16, %o4		! extract second byte
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   103
	andcc	%o4, 0xff, %g0		! is second byte zero ?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   104
	bz,pn	%ncc, .done		! yup, done
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   105
	stb	%o4, [%o2 + 1]		! store second byte
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   106
	srl	%o5, 8, %o4		! extract third byte
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   107
	andcc	%o4, 0xff, %g0		! third byte zero ?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   108
	bz,pn	%ncc, .done		! yup, done
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   109
	stb	%o4, [%o2 + 2]		! store third byte
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   110
	andcc	%o5, 0xff, %g0		! fourth byte zero ?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   111
	stb 	%o5, [%o2 + 3]		! store fourth byte
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   112
	bz,pn	%ncc, .done		! yup, fourth byte zero, done
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   113
	add	%o2, 4, %o2		! src += 2
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   114
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   115
.srcaligned:	
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   116
	sethi	%hi(0x01010101), %o4	! Alan Mycroft's magic1
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   117
	or	%o4, %lo(0x01010101),%o4!  finish loading magic1
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   118
	sllx	%o4, 32, %o1		! spread magic1
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   119
	and	%o2, 3, %g4		! dst<1:0> to examine offset
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   120
	or	%o4, %o1, %o4		!   to all 64 bits
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   121
	cmp	%g4, 1			! dst offset of 1 or 5
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   122
	sllx	%o4, 7, %o5		!  Alan Mycroft's magic2
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   123
	be,pn	%ncc, .storebyte1241	! store 1, 2, 4, 1 bytes
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   124
	cmp	%g4, 3			! dst offset of 3 or 7
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   125
	be,pn	%ncc, .storebyte1421	! store 1, 4, 2, 1 bytes
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   126
	cmp	%g4, 2			! dst halfword aligned ?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   127
	be,pn	%ncc, .storehalfword	! yup, store half-word wise
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   128
	andcc	%o2, 7, %g0		! dst word aligned ?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   129
	bnz,pn	%ncc, .storeword2	! yup, store word wise
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   130
	.empty	
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   131
	
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   132
.storedword:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   133
	ldx	[%o2 + %o3], %o1	! src dword
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   134
	add	%o2, 8, %o2		! src += 8, dst += 8
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   135
	andn	%o5, %o1, %g1		! ~dword & 0x8080808080808080
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   136
	sub	%o1, %o4, %g4		! dword - 0x0101010101010101
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   137
	andcc	%g4, %g1, %g0		! ((dword - 0x0101010101010101) & ~dword & 0x8080808080808080)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   138
	bz,a,pt	%ncc, .storedword	! no zero byte if magic expression == 0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   139
	stx	%o1, [%o2 - 8]		! store word to dst (address pre-incremented)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   140
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   141
.zerobyte:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   142
	orn	%o4, %g0, %o4		! 0xffffffffffffffff
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   143
	sllx	%o4, 56, %o4		! 0xff00000000000000
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   144
	srlx	%o1, 56, %o3		! %o3<7:0> = first byte
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   145
	andcc	%o1, %o4, %g0		! first byte zero?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   146
	bz,pn	%ncc, .done		! yup, done
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   147
	stb	%o3, [%o2 - 8]		! store first byte  
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   148
	srlx	%o4, 8, %o4		! 0x00ff000000000000
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   149
	srlx	%o1, 48, %o3		! %o3<7:0> = second byte
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   150
	andcc	%o1, %o4, %g0		! second byte zero?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   151
	bz,pn	%ncc, .done		! yup, done
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   152
	stb	%o3, [%o2 - 7]		! store second byte  
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   153
	srlx	%o4, 8, %o4		! 0x0000ff0000000000
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   154
	srlx	%o1, 40, %o3		! %o3<7:0> = third byte
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   155
	andcc	%o1, %o4, %g0		! third byte zero?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   156
	bz,pn	%ncc, .done		! yup, done
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   157
	stb	%o3, [%o2 - 6]		! store third byte  
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   158
	srlx	%o4, 8, %o4		! 0x000000ff00000000
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   159
	srlx	%o1, 32, %o3		! %o3<7:0> = fourth byte
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   160
	andcc	%o1, %o4, %g0		! fourth byte zero?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   161
	bz,pn	%ncc, .done		! yup, done
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   162
	stb	%o3, [%o2 - 5]		! store fourth byte  
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   163
	srlx	%o4, 8, %o4		! 0x00000000ff000000
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   164
	srlx	%o1, 24, %o3		! %o3<7:0> = fifth byte
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   165
	andcc	%o1, %o4, %g0		! fifth byte zero?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   166
	bz,pn	%ncc, .done		! yup, done
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   167
	stb	%o3, [%o2 - 4]		! store fifth byte  
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   168
	srlx	%o4, 8, %o4		! 0x0000000000ff0000
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   169
	srlx	%o1, 16, %o3		! %o3<7:0> = sixth byte    
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   170
	andcc	%o1, %o4, %g0		! sixth byte zero?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   171
	bz,pn	%ncc, .done		! yup, done
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   172
	stb	%o3, [%o2 - 3]		! store sixth byte
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   173
	srlx	%o4, 8, %o4		! 0x000000000000ff00
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   174
	andcc	%o1, %o4, %g0		! seventh byte zero?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   175
	srlx	%o1, 8, %o3		! %o3<7:0> = seventh byte
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   176
	bz,pn	%ncc, .done		! yup, done
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   177
	stb	%o3, [%o2 - 2]		! store seventh byte
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   178
	stb	%o1, [%o2 - 1]		! store eigth byte
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   179
.done:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   180
	retl				! done with leaf function
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   181
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   182
	nop				! ensure following loop 16-byte aligned
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   183
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   184
.storebyte1421:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   185
	ldx	[%o2 + %o3], %o1	! x = src[]
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   186
	add	%o2, 8, %o2		! src += 8, dst += 8
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   187
	andn	%o5, %o1, %g1		! ~x & 0x8080808080808080
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   188
	sub	%o1, %o4, %g4		! x - 0x0101010101010101
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   189
	andcc	%g4, %g1, %g0		! ((x - 0x0101010101010101) & ~x & 0x8080808080808080)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   190
	bnz,pn	%ncc, .zerobyte		! x has zero byte, handle end cases
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   191
	srlx	%o1, 56, %g1		! %g1<7:0> = first byte; word aligned now
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   192
	stb	%g1, [%o2 - 8]		! store first byte
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   193
	srlx	%o1, 24, %g1		! %g1<31:0> = bytes 2, 3, 4, 5
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   194
	stw	%g1, [%o2 - 7]		! store bytes 2, 3, 4, 5
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   195
	srlx	%o1, 8, %g1		! %g1<15:0> = bytes 6, 7
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   196
	sth	%g1, [%o2 - 3]		! store bytes 6, 7
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   197
	ba	.storebyte1421		! next dword
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   198
	stb	%o1, [%o2 - 1]		! store eigth byte
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   199
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   200
	nop				! ensure following loop 16-byte aligned
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   201
	nop				! ensure following loop 16-byte aligned
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   202
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   203
.storebyte1241:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   204
	ldx	[%o2 + %o3], %o1	! x = src[]
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   205
	add	%o2, 8, %o2		! src += 8, dst += 8
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   206
	andn	%o5, %o1, %g1		! ~x & 0x8080808080808080
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   207
	sub	%o1, %o4, %g4		! x - 0x0101010101010101
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   208
	andcc	%g4, %g1, %g0		! ((x - 0x0101010101010101) & ~x & 0x8080808080808080)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   209
	bnz,pn	%ncc, .zerobyte		! x has zero byte, handle end cases
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   210
	srlx	%o1, 56, %g1		! %g1<7:0> = first byte; word aligned now
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   211
	stb	%g1, [%o2 - 8]		! store first byte
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   212
	srlx	%o1, 40, %g1		! %g1<15:0> = bytes 2, 3
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   213
	sth	%g1, [%o2 - 7]		! store bytes 2, 3
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   214
	srlx	%o1, 8, %g1		! %g1<31:0> = bytes 4, 5, 6, 7
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   215
	stw	%g1, [%o2 - 5]		! store bytes 4, 5, 6, 7
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   216
	ba	.storebyte1241		! next dword
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   217
	stb	%o1, [%o2 - 1]		! store eigth byte
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   218
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   219
	nop				! ensure following loop 16-byte aligned
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   220
	nop				! ensure following loop 16-byte aligned
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   221
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   222
.storehalfword:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   223
	ldx	[%o2 + %o3], %o1	! x = src[]
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   224
	add	%o2, 8, %o2		! src += 8, dst += 8
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   225
	andn	%o5, %o1, %g1		! ~x & 0x8080808080808080
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   226
	sub	%o1, %o4, %g4		! x - 0x0101010101010101
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   227
	andcc	%g4, %g1, %g0		! ((x - 0x0101010101010101) & ~x & 0x8080808080808080)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   228
	bnz,pn	%ncc, .zerobyte		! x has zero byte, handle end cases
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   229
	srlx	%o1, 48, %g1		! get first and second byte
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   230
	sth	%g1, [%o2 - 8]		! store first and second byte; word aligned now
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   231
	srlx	%o1, 16, %g1		! %g1<31:0> = bytes 3, 4, 5, 6	
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   232
	stw	%g1, [%o2 - 6]		! store bytes 3, 4, 5, 6
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   233
	ba	.storehalfword		! next word
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   234
	sth	%o1, [%o2 - 2]		! store seventh and eigth byte
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   235
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   236
.storeword:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   237
	ldx	[%o2 + %o3], %o1	! x = src[]
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   238
.storeword2:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   239
	add	%o2, 8, %o2		! src += 8, dst += 8
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   240
	andn	%o5, %o1, %g1		! ~x & 0x0x8080808080808080
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   241
	sub	%o1, %o4, %g4		! x - 0x0101010101010101
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   242
	andcc	%g4, %g1, %g0		! ((x - 0x0101010101010101) & ~x & 0x8080808080808080)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   243
	bnz,pn	%ncc, .zerobyte		! x has zero byte, handle end cases
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   244
	srlx	%o1, 32, %g1		! get bytes 1,2,3,4
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   245
	stw	%g1, [%o2 - 8]		! store bytes 1,2,3,4 (address is pre-incremented)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   246
	ba	.storeword		! no zero byte if magic expression == 0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   247
	stw	%o1, [%o2 - 4]		! store bytes 5,6,7,8
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   248
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   249
	nop				! padding, do not remove!!!
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   250
	nop				! padding, do not remove!!!
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   251
	SET_SIZE(strcpy)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   252