xref: /illumos-gate/usr/src/lib/libc/i386/gen/strcpy.S (revision 5d9d9091f564c198a760790b0bfa72c44e17912b)
1*5d9d9091SRichard Lowe/*
2*5d9d9091SRichard Lowe * CDDL HEADER START
3*5d9d9091SRichard Lowe *
4*5d9d9091SRichard Lowe * The contents of this file are subject to the terms of the
5*5d9d9091SRichard Lowe * Common Development and Distribution License (the "License").
6*5d9d9091SRichard Lowe * You may not use this file except in compliance with the License.
7*5d9d9091SRichard Lowe *
8*5d9d9091SRichard Lowe * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*5d9d9091SRichard Lowe * or http://www.opensolaris.org/os/licensing.
10*5d9d9091SRichard Lowe * See the License for the specific language governing permissions
11*5d9d9091SRichard Lowe * and limitations under the License.
12*5d9d9091SRichard Lowe *
13*5d9d9091SRichard Lowe * When distributing Covered Code, include this CDDL HEADER in each
14*5d9d9091SRichard Lowe * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*5d9d9091SRichard Lowe * If applicable, add the following below this CDDL HEADER, with the
16*5d9d9091SRichard Lowe * fields enclosed by brackets "[]" replaced with your own identifying
17*5d9d9091SRichard Lowe * information: Portions Copyright [yyyy] [name of copyright owner]
18*5d9d9091SRichard Lowe *
19*5d9d9091SRichard Lowe * CDDL HEADER END
20*5d9d9091SRichard Lowe */
21*5d9d9091SRichard Lowe/*
22*5d9d9091SRichard Lowe * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
23*5d9d9091SRichard Lowe * Use is subject to license terms.
24*5d9d9091SRichard Lowe */
25*5d9d9091SRichard Lowe
26*5d9d9091SRichard Lowe	.file	"strcpy.s"
27*5d9d9091SRichard Lowe
28*5d9d9091SRichard Lowe/
29*5d9d9091SRichard Lowe/ strcpy(s1, s2)
30*5d9d9091SRichard Lowe/
31*5d9d9091SRichard Lowe/ Copies string s2 to s1.  s1 must be large enough.
32*5d9d9091SRichard Lowe/ Returns s1
33*5d9d9091SRichard Lowe/
34*5d9d9091SRichard Lowe/
35*5d9d9091SRichard Lowe/ Fast assembly language version of the following C-program strcpy
36*5d9d9091SRichard Lowe/ which represents the `standard' for the C-library.
37*5d9d9091SRichard Lowe/
38*5d9d9091SRichard Lowe/	char *
39*5d9d9091SRichard Lowe/	strcpy(char *s1, const char *s2)
40*5d9d9091SRichard Lowe/	{
41*5d9d9091SRichard Lowe/		char	*os1 = s1;
42*5d9d9091SRichard Lowe/
43*5d9d9091SRichard Lowe/		while (*s1++ = *s2++)
44*5d9d9091SRichard Lowe/			;
45*5d9d9091SRichard Lowe/		return (os1);
46*5d9d9091SRichard Lowe/	}
47*5d9d9091SRichard Lowe/
48*5d9d9091SRichard Lowe/ In this assembly language version, the following expression is used
49*5d9d9091SRichard Lowe/ to check if a 32-bit word data contains a null byte or not:
50*5d9d9091SRichard Lowe/	(((A & 0x7f7f7f7f) + 0x7f7f7f7f) | A) & 0x80808080
51*5d9d9091SRichard Lowe/ If the above expression geneates a value other than 0x80808080,
52*5d9d9091SRichard Lowe/ that means the 32-bit word data contains a null byte.
53*5d9d9091SRichard Lowe/
54*5d9d9091SRichard Lowe
55*5d9d9091SRichard Lowe#include "SYS.h"
56*5d9d9091SRichard Lowe
57*5d9d9091SRichard Lowe	ENTRY(strcpy)
58*5d9d9091SRichard Lowe	push	%edi				/ save reg as per calling cvntn
59*5d9d9091SRichard Lowe	mov	12(%esp), %ecx			/ src ptr
60*5d9d9091SRichard Lowe	mov	8(%esp), %edi			/ dst ptr
61*5d9d9091SRichard Lowe	mov	%ecx, %eax			/ src
62*5d9d9091SRichard Lowe	sub	%edi, %ecx			/ src - dst
63*5d9d9091SRichard Lowe	and	$3, %eax			/ check src alignment
64*5d9d9091SRichard Lowe	jz	load
65*5d9d9091SRichard Lowe	sub	$4, %eax
66*5d9d9091SRichard Lowe
67*5d9d9091SRichard Lowebyte_loop:
68*5d9d9091SRichard Lowe	movb	(%edi, %ecx, 1), %dl		/ load src byte
69*5d9d9091SRichard Lowe	movb	%dl, (%edi)			/ load dest byte
70*5d9d9091SRichard Lowe	inc	%edi				/ increment src and dest
71*5d9d9091SRichard Lowe	testb	%dl, %dl			/ is src zero?
72*5d9d9091SRichard Lowe	jz 	done
73*5d9d9091SRichard Lowe	inc	%eax				/ check src alignment
74*5d9d9091SRichard Lowe	jnz	byte_loop
75*5d9d9091SRichard Lowe	jmp 	load
76*5d9d9091SRichard Lowe
77*5d9d9091SRichard Lowestore:
78*5d9d9091SRichard Lowe	mov	%eax, (%edi)			/ store word
79*5d9d9091SRichard Lowe	add	$4, %edi			/ incrment src and dest by 4
80*5d9d9091SRichard Loweload:
81*5d9d9091SRichard Lowe	mov	(%edi, %ecx, 1), %eax		/ load word
82*5d9d9091SRichard Lowe	lea	-0x01010101(%eax), %edx		/ (word - 0x01010101)
83*5d9d9091SRichard Lowe	not	%eax				/ ~word
84*5d9d9091SRichard Lowe	and	%eax, %edx			/ (word - 0x01010101) & ~word
85*5d9d9091SRichard Lowe	not	%eax				/ word
86*5d9d9091SRichard Lowe	and	$0x80808080, %edx	/ (wd - 0x01010101) & ~wd & 0x80808080
87*5d9d9091SRichard Lowe	jz	store				/ store word w/o zero byte
88*5d9d9091SRichard Lowe
89*5d9d9091SRichard Lowehas_zero_byte:
90*5d9d9091SRichard Lowe	movb	%al, (%edi)			/ store first byte
91*5d9d9091SRichard Lowe	testb	%al, %al			/ check first byte for zero
92*5d9d9091SRichard Lowe	jz	done
93*5d9d9091SRichard Lowe	movb	%ah, 1(%edi)			/ continue storing and checking
94*5d9d9091SRichard Lowe	testb	%ah, %ah
95*5d9d9091SRichard Lowe	jz	done
96*5d9d9091SRichard Lowe	shr	$16, %eax			/ grab last two bytes
97*5d9d9091SRichard Lowe	movb	%al, 2(%edi)
98*5d9d9091SRichard Lowe	testb	%al, %al
99*5d9d9091SRichard Lowe	jz	done
100*5d9d9091SRichard Lowe	movb	%ah, 3(%edi)
101*5d9d9091SRichard Lowedone:
102*5d9d9091SRichard Lowe	mov	8(%esp), %eax			/ return ptr to dest
103*5d9d9091SRichard Lowe	pop	%edi				/ restore as per calling cvntn
104*5d9d9091SRichard Lowe	ret
105*5d9d9091SRichard Lowe	SET_SIZE(strcpy)
106