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