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 2008 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 jle .CopyRight / 70 cmpl %edx,%edi 71 jle .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