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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22/* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 .ident "%Z%%M% %I% %E% SMI" 28 29 .file "%M%" 30 31#include <sys/asm_linkage.h> 32 33 ANSI_PRAGMA_WEAK(memmove,function) 34 ANSI_PRAGMA_WEAK(memcpy,function) 35 36#include "SYS.h" 37 38 ANSI_PRAGMA_WEAK2(_private_memcpy,memcpy,function) 39 40 ENTRY(memcpy) 41 movl %edi,%edx / save register variables 42 pushl %esi 43 movl 8(%esp),%edi / %edi = dest address 44 movl 12(%esp),%esi / %esi = source address 45 movl 16(%esp),%ecx / %ecx = length of string 46 movl %edi,%eax / return value from the call 47 48 shrl $2,%ecx / %ecx = number of words to move 49 rep ; smovl / move the words 50 51 movl 16(%esp),%ecx / %ecx = number of bytes to move 52 andl $0x3,%ecx / %ecx = number of bytes left to move 53 rep ; smovb / move the bytes 54 55 popl %esi / restore register variables 56 movl %edx,%edi 57 ret 58 SET_SIZE(memcpy) 59 60 61 ENTRY(memmove) 62 pushl %edi / save off %edi, %esi and move destination 63 movl 4+12(%esp),%ecx / get number of bytes to move 64 pushl %esi 65 testl %ecx,%ecx / if (n == 0) 66 je .CleanupReturn / return(s); 67 movl 8+ 4(%esp),%edi / destination buffer address 68 movl 8+ 8(%esp),%esi / source buffer address 69.Common: 70 movl $3,%eax / heavily used constant 71 cmpl %esi,%edi / if (source addr > dest addr) 72 leal -1(%esi,%ecx),%edx 73 jle .CopyRight / 74 cmpl %edx,%edi 75 jle .CopyLeft 76.CopyRight: 77 cmpl $8,%ecx / if (size < 8 bytes) 78 jbe .OneByteCopy / goto fast short copy loop 79.FourByteCopy: 80 movl %ecx,%edx / save count 81 movl %esi,%ecx / get source buffer 4 byte aligned 82 andl %eax,%ecx 83 jz .SkipAlignRight 84 subl %ecx,%edx 85 rep; smovb / do the byte part of copy 86.SkipAlignRight: 87 movl %edx,%ecx 88 shrl $2,%ecx 89 rep; smovl / do the long word part 90 movl %edx,%ecx / compute bytes left to move 91 andl %eax,%ecx / complete copy of remaining bytes 92 jz .CleanupReturn 93.OneByteCopy: 94 rep; smovb / do the byte part of copy 95.CleanupReturn: 96 popl %esi / } 97 popl %edi / restore registers 98 movl 4(%esp),%eax / set up return value 99.Return: 100 ret / return(dba); 101 102.CopyLeft: 103 std / reverse direction bit (RtoL) 104 cmpl $12,%ecx / if (size < 12) 105 ja .BigCopyLeft / { 106 movl %edx,%esi / src = src + size - 1 107 leal -1(%ecx,%edi),%edi / dst = dst + size - 1 108 rep; smovb / do the byte copy 109 cld / reset direction flag to LtoR 110 popl %esi / } 111 popl %edi / restore registers 112 movl 4(%esp),%eax / set up return value 113 ret / return(dba); 114.BigCopyLeft: / } else { 115 xchgl %edx,%ecx 116 movl %ecx,%esi / align source w/byte copy 117 leal -1(%edx,%edi),%edi 118 andl %eax,%ecx 119 jz .SkipAlignLeft 120 addl $1, %ecx / we need to insure that future 121 subl %ecx,%edx / copy is done on aligned boundary 122 rep; smovb 123.SkipAlignLeft: 124 movl %edx,%ecx 125 subl %eax,%esi 126 shrl $2,%ecx / do 4 byte copy RtoL 127 subl %eax,%edi 128 rep; smovl 129 andl %eax,%edx / do 1 byte copy whats left 130 jz .CleanupReturnLeft 131 movl %edx,%ecx 132 addl %eax,%esi / rep; smovl instruction will decrement 133 addl %eax,%edi / %edi, %esi by four after each copy 134 / adding 3 will restore pointers to byte 135 / before last double word copied 136 / which is where they are expected to 137 / be for the single byte copy code 138 rep; smovb 139.CleanupReturnLeft: 140 cld / reset direction flag to LtoR 141 popl %esi 142 popl %edi / restore registers 143 movl 4(%esp),%eax / set up return value 144 ret / return(dba); 145 SET_SIZE(memmove) 146