xref: /onnv-gate/usr/src/lib/libc/i386/gen/strcpy.s (revision 7298:b69e27387f74)
10Sstevel@tonic-gate/*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*7298SMark.J.Nelson@Sun.COM * Common Development and Distribution License (the "License").
6*7298SMark.J.Nelson@Sun.COM * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
210Sstevel@tonic-gate/*
220Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate * Use is subject to license terms.
240Sstevel@tonic-gate */
250Sstevel@tonic-gate
26*7298SMark.J.Nelson@Sun.COM	.file	"strcpy.s"
270Sstevel@tonic-gate
280Sstevel@tonic-gate/
290Sstevel@tonic-gate/ strcpy(s1, s2)
300Sstevel@tonic-gate/
310Sstevel@tonic-gate/ Copies string s2 to s1.  s1 must be large enough.
320Sstevel@tonic-gate/ Returns s1
330Sstevel@tonic-gate/
340Sstevel@tonic-gate/
350Sstevel@tonic-gate/ Fast assembly language version of the following C-program strcpy
360Sstevel@tonic-gate/ which represents the `standard' for the C-library.
370Sstevel@tonic-gate/
380Sstevel@tonic-gate/	char *
390Sstevel@tonic-gate/	strcpy(char *s1, const char *s2)
400Sstevel@tonic-gate/	{
410Sstevel@tonic-gate/		char	*os1 = s1;
420Sstevel@tonic-gate/
430Sstevel@tonic-gate/		while (*s1++ = *s2++)
440Sstevel@tonic-gate/			;
450Sstevel@tonic-gate/		return (os1);
460Sstevel@tonic-gate/	}
470Sstevel@tonic-gate/
480Sstevel@tonic-gate/ In this assembly language version, the following expression is used
490Sstevel@tonic-gate/ to check if a 32-bit word data contains a null byte or not:
500Sstevel@tonic-gate/	(((A & 0x7f7f7f7f) + 0x7f7f7f7f) | A) & 0x80808080
510Sstevel@tonic-gate/ If the above expression geneates a value other than 0x80808080,
520Sstevel@tonic-gate/ that means the 32-bit word data contains a null byte.
530Sstevel@tonic-gate/
540Sstevel@tonic-gate
550Sstevel@tonic-gate#include "SYS.h"
560Sstevel@tonic-gate
570Sstevel@tonic-gate	ENTRY(strcpy)
580Sstevel@tonic-gate	push	%edi				/ save reg as per calling cvntn
590Sstevel@tonic-gate	mov	12(%esp), %ecx			/ src ptr
600Sstevel@tonic-gate	mov	8(%esp), %edi			/ dst ptr
610Sstevel@tonic-gate	mov	%ecx, %eax			/ src
620Sstevel@tonic-gate	sub	%edi, %ecx			/ src - dst
630Sstevel@tonic-gate	and	$3, %eax			/ check src alignment
640Sstevel@tonic-gate	jz	load
650Sstevel@tonic-gate	sub	$4, %eax
660Sstevel@tonic-gate
670Sstevel@tonic-gatebyte_loop:
680Sstevel@tonic-gate	movb	(%edi, %ecx, 1), %dl		/ load src byte
690Sstevel@tonic-gate	movb	%dl, (%edi)			/ load dest byte
700Sstevel@tonic-gate	inc	%edi				/ increment src and dest
710Sstevel@tonic-gate	testb	%dl, %dl			/ is src zero?
720Sstevel@tonic-gate	jz 	done
730Sstevel@tonic-gate	inc	%eax				/ check src alignment
740Sstevel@tonic-gate	jnz	byte_loop
750Sstevel@tonic-gate	jmp 	load
760Sstevel@tonic-gate
770Sstevel@tonic-gatestore:
780Sstevel@tonic-gate	mov	%eax, (%edi)			/ store word
790Sstevel@tonic-gate	add	$4, %edi			/ incrment src and dest by 4
800Sstevel@tonic-gateload:
810Sstevel@tonic-gate	mov	(%edi, %ecx, 1), %eax		/ load word
820Sstevel@tonic-gate	lea	-0x01010101(%eax), %edx		/ (word - 0x01010101)
830Sstevel@tonic-gate	not	%eax				/ ~word
840Sstevel@tonic-gate	and	%eax, %edx			/ (word - 0x01010101) & ~word
850Sstevel@tonic-gate	not	%eax				/ word
860Sstevel@tonic-gate	and	$0x80808080, %edx	/ (wd - 0x01010101) & ~wd & 0x80808080
870Sstevel@tonic-gate	jz	store				/ store word w/o zero byte
880Sstevel@tonic-gate
890Sstevel@tonic-gatehas_zero_byte:
900Sstevel@tonic-gate	movb	%al, (%edi)			/ store first byte
910Sstevel@tonic-gate	testb	%al, %al			/ check first byte for zero
920Sstevel@tonic-gate	jz	done
930Sstevel@tonic-gate	movb	%ah, 1(%edi)			/ continue storing and checking
940Sstevel@tonic-gate	testb	%ah, %ah
950Sstevel@tonic-gate	jz	done
960Sstevel@tonic-gate	shr	$16, %eax			/ grab last two bytes
970Sstevel@tonic-gate	movb	%al, 2(%edi)
980Sstevel@tonic-gate	testb	%al, %al
990Sstevel@tonic-gate	jz	done
1000Sstevel@tonic-gate	movb	%ah, 3(%edi)
1010Sstevel@tonic-gatedone:
1020Sstevel@tonic-gate	mov	8(%esp), %eax			/ return ptr to dest
1030Sstevel@tonic-gate	pop	%edi				/ restore as per calling cvntn
1040Sstevel@tonic-gate	ret
1050Sstevel@tonic-gate	SET_SIZE(strcpy)
106