OpenGrok

Cross Reference: memcpy.s
xref: /onnv/onnv-gate/usr/src/lib/libc/i386/gen/memcpy.s
Home | History | Annotate | Line # | 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 2009 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 	.file	"memcpy.s"
     28 
     29 #include <sys/asm_linkage.h>
     30 
     31 	ANSI_PRAGMA_WEAK(memmove,function)
     32 	ANSI_PRAGMA_WEAK(memcpy,function)
     33 
     34 #include "SYS.h"
     35 
     36 	ENTRY(memcpy)
     37 	movl	%edi,%edx	/ save register variables
     38 	pushl	%esi
     39 	movl	8(%esp),%edi	/ %edi = dest address
     40 	movl	12(%esp),%esi	/ %esi = source address
     41 	movl	16(%esp),%ecx	/ %ecx = length of string
     42 	movl	%edi,%eax	/ return value from the call
     43 
     44 	shrl	$2,%ecx		/ %ecx = number of words to move
     45 	rep ; smovl		/ move the words
     46 
     47 	movl	16(%esp),%ecx	/ %ecx = number of bytes to move
     48 	andl	$0x3,%ecx	/ %ecx = number of bytes left to move
     49 	rep ; smovb		/ move the bytes
     50 
     51 	popl	%esi		/ restore register variables
     52 	movl	%edx,%edi
     53 	ret
     54 	SET_SIZE(memcpy)
     55 
     56 
     57 	ENTRY(memmove)
     58 	pushl	%edi		/ save off %edi, %esi and move destination
     59 	movl	4+12(%esp),%ecx	/ get number of bytes to move
     60 	pushl	%esi
     61 	testl	%ecx,%ecx	/ if (n == 0)
     62 	je	.CleanupReturn	/    return(s);
     63 	movl	8+ 4(%esp),%edi	/ destination buffer address
     64 	movl	8+ 8(%esp),%esi	/ source buffer address
     65 .Common:
     66 	movl	$3,%eax		/ heavily used constant
     67 	cmpl	%esi,%edi	/ if (source addr > dest addr)
     68 	leal	-1(%esi,%ecx),%edx
     69 	jbe	.CopyRight	/
     70 	cmpl	%edx,%edi
     71 	jbe	.CopyLeft
     72 .CopyRight:
     73 	cmpl	$8,%ecx		/    if (size < 8 bytes)
     74 	jbe	.OneByteCopy	/        goto fast short copy loop
     75 .FourByteCopy:
     76 	movl	%ecx,%edx	/    save count
     77 	movl	%esi,%ecx	/    get source buffer 4 byte aligned
     78 	andl	%eax,%ecx
     79 	jz	.SkipAlignRight
     80 	subl	%ecx,%edx
     81 	rep;	smovb		/    do the byte part of copy
     82 .SkipAlignRight:
     83 	movl	%edx,%ecx
     84 	shrl	$2,%ecx
     85 	rep;	smovl		/    do the long word part
     86 	movl	%edx,%ecx	/    compute bytes left to move
     87 	andl	%eax,%ecx	/    complete copy of remaining bytes
     88 	jz	.CleanupReturn
     89 .OneByteCopy:
     90 	rep;	smovb		/    do the byte part of copy
     91 .CleanupReturn:
     92 	popl	%esi		/  }
     93 	popl	%edi		/  restore registers
     94 	movl	4(%esp),%eax	/  set up return value
     95 .Return:
     96 	ret			/  return(dba);
     97 
     98 .CopyLeft:
     99 	std				/ reverse direction bit (RtoL)
    100 	cmpl	$12,%ecx		/ if (size < 12)
    101 	ja	.BigCopyLeft		/ {
    102 	movl	%edx,%esi		/     src = src + size - 1
    103 	leal	-1(%ecx,%edi),%edi	/     dst = dst + size - 1
    104 	rep;	smovb			/    do the byte copy
    105 	cld				/    reset direction flag to LtoR
    106 	popl	%esi			/  }
    107 	popl	%edi			/  restore registers
    108 	movl	4(%esp),%eax		/  set up return value
    109 	ret				/  return(dba);
    110 .BigCopyLeft:				/ } else {
    111 	xchgl	%edx,%ecx
    112 	movl	%ecx,%esi		/ align source w/byte copy
    113 	leal	-1(%edx,%edi),%edi
    114 	andl	%eax,%ecx
    115 	jz	.SkipAlignLeft
    116 	addl	$1, %ecx		/ we need to insure that future
    117 	subl	%ecx,%edx		/ copy is done on aligned boundary
    118 	rep;	smovb
    119 .SkipAlignLeft:
    120 	movl	%edx,%ecx
    121 	subl	%eax,%esi
    122 	shrl	$2,%ecx			/ do 4 byte copy RtoL
    123 	subl	%eax,%edi
    124 	rep;	smovl
    125 	andl	%eax,%edx		/ do 1 byte copy whats left
    126 	jz	.CleanupReturnLeft
    127 	movl	%edx,%ecx
    128 	addl	%eax,%esi		/ rep; smovl instruction will decrement
    129 	addl	%eax,%edi		/ %edi, %esi by four after each copy
    130 					/ adding 3 will restore pointers to byte
    131 					/ before last double word copied
    132 					/ which is where they are expected to
    133 					/ be for the single byte copy code
    134 	rep;	smovb
    135 .CleanupReturnLeft:
    136 	cld				/ reset direction flag to LtoR
    137 	popl	%esi
    138 	popl	%edi			/ restore registers
    139 	movl	4(%esp),%eax		/ set up return value
    140 	ret				/ return(dba);
    141 	SET_SIZE(memmove)
    142