Home | History | Annotate | Download | only in gen
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 
     22 /*
     23  * Copyright 2006 Sun Microsystems Laboratories.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 /*
     28  *   Solaris C Library Routine
     29  *====================================================================
     30  *
     31  *   Function: memcpy
     32  *
     33  */
     34 
     35 .ident "@(#)memcpy.s 1.12      95/09/27 SMI"
     36 
     37 /*
     38  * memcpy(s1, s2, len)
     39  *
     40  * Copy s2 to s1, always copy n bytes.
     41  * Note: this does not work for overlapped copies, bcopy() does
     42  *
     43  * Fast assembler language version of the following C-program for memcpy
     44  * which represents the `standard' for the C-library.
     45  *
     46  *	void *
     47  *	memcpy(s, s0, n)
     48  *	void *s;
     49  *	const void *s0;
     50  *	register size_t n;
     51  *	{
     52  *		if (n != 0) {
     53  *	   	    register char *s1 = s;
     54  *		    register const char *s2 = s0;
     55  *		    do {
     56  *			*s1++ = *s2++;
     57  *		    } while (--n != 0);
     58  *		}
     59  *		return ( s );
     60  *	}
     61  */
     62 
     63 #include <sys/asm_linkage.h>
     64 
     65 	ANSI_PRAGMA_WEAK(memcpy,function)
     66 	ANSI_PRAGMA_WEAK2(_private_memcpy,memcpy,function)
     67 
     68 #include "synonyms.h"
     69 
     70 /*
     71  *	WARNING : This code assumes NBPW == 4
     72  */
     73 
     74 	ENTRY(memcpy)
     75 
     76 	cmpwi	%r5,0
     77 	beqlr
     78 
     79 	mr	%r9,%r3
     80 
     81 
     82 	andi.	%r11,%r9,3
     83 	andi.	%r12,%r4,3
     84 	or.	%r12,%r12,%r11
     85 	beq	.wordcpy		! if both word-aligned wordcpy
     86 
     87 	mtctr	%r5
     88 	addi	%r4, %r4, -1
     89 	addi	%r9, %r9, -1
     90 
     91 .bytecpy:
     92 	lbzu	%r11,1(%r4)
     93 	stbu	%r11,1(%r9)
     94 	bdnz	.bytecpy
     95 
     96 	blr
     97 
     98 .wordcpy:
     99 
    100 	addi	%r4, %r4, -4
    101 	addi	%r9, %r9, -4
    102 
    103 	andi.	%r12,%r5,3		! r12 = remainder-bytes
    104 	srwi.	%r10,%r5,2		! r10 = nwords
    105 	beq	.bytes
    106 
    107 	mtctr	%r10
    108 
    109 .wordloop:
    110 	lwzu	%r11,4(%r4)
    111 	stwu	%r11,4(%r9)		! *(r9) = *(r4)
    112 	bdnz	.wordloop
    113 
    114 .bytes:
    115 	cmpwi	%r12,0
    116 	beqlr				! if remain_bytes==0 return
    117 
    118 	mtctr	%r12
    119 	addi	%r4, %r4, +3
    120 	addi	%r9, %r9, +3
    121 
    122 .byteloop:
    123 	lbzu	%r11,1(%r4)
    124 	stbu	%r11,1(%r9)
    125 	bdnz	.byteloop
    126 
    127 	blr
    128 
    129 	SET_SIZE(memcpy)
    130