import less(1)
[unleashed/tickless.git] / usr / src / lib / libc / i386 / gen / memcpy.s
blobc050a67a093ea3e6c5ecc6b79c6c5e77dd64cd13
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 .file "memcpy.s"
29 #include <sys/asm_linkage.h>
31 ANSI_PRAGMA_WEAK(memmove,function)
32 ANSI_PRAGMA_WEAK(memcpy,function)
34 #include "SYS.h"
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
44 shrl $2,%ecx / %ecx = number of words to move
45 rep ; smovl / move the words
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
51 popl %esi / restore register variables
52 movl %edx,%edi
53 ret
54 SET_SIZE(memcpy)
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);
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)