3 #Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
4 #This program and the accompanying materials
5 #are licensed and made available under the terms and conditions of the BSD License
6 #which accompanies this distribution. The full text of the license may be found at
7 #http://opensource.org/licenses/bsd-license.php
9 #THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 #WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 # This is the code that supports IA32-optimized CopyMem service
22 #---------------------------------------------------------------------------
28 #---------------------------------------------------------------------------
30 .globl ASM_PFX(EfiCommonLibCopyMem)
33 #EfiCommonLibCopyMem (
34 # IN VOID *Destination,
42 # Copy Length bytes from Source to Destination.
46 # Destination - Target of copy
48 # Source - Place to copy from
50 # Length - Number of bytes to copy
57 ASM_PFX(EfiCommonLibCopyMem):
61 pushl %ecx # reserve space for Scratch Local variable UINT64 MmxSave
66 movl 0x10(%ebp), %ecx # Count
67 movl 0xC(%ebp), %esi # Source
68 movl 8(%ebp), %edi # Destination
70 ##First off, make sure we have no overlap. That is to say,
71 ## if (Source == Destination) => do nothing
72 ## if (Source + Count <= Destination) => regular copy
73 ## if (Destination + Count <= Source) => regular copy
74 ## otherwise, do a reverse copy
76 addl %ecx, %eax # Source + Count
81 addl %ecx, %eax # Dest + Count
87 jb _CopyOverlapped # too bad -- overlaps
89 # Pick up misaligned start bytes to get destination pointer 4-byte aligned
92 je _CopyMemDone # Count == 0, all done
94 andb $3, %dl # check lower 2 bits of address
96 je _CopyBlocks # already aligned?
99 movb (%esi), %al # get byte from Source
100 movb %al, (%edi) # write byte to Destination
104 jmp _StartByteCopy # back to top of loop
107 # Compute how many 64-byte blocks we can clear
108 movl %ecx, %eax # get Count in eax
109 shrl $6, %eax # convert to 64-byte count
110 shll $6, %eax # convert back to bytes
111 subl %eax, %ecx # subtract from the original count
112 shrl $6, %eax # and this is how many 64-byte blocks
114 # If no 64-byte blocks, then skip
116 je _CopyRemainingDWords
118 # Save mm0 to UINT64 MmxSave
123 movq %ds:(%esi), %mm0
124 movq %mm0, %ds:(%edi)
125 movq %ds:8(%esi), %mm0
126 movq %mm0, %ds:8(%edi)
127 movq %ds:16(%esi), %mm0
128 movq %mm0, %ds:16(%edi)
129 movq %ds:24(%esi), %mm0
130 movq %mm0, %ds:24(%edi)
131 movq %ds:32(%esi), %mm0
132 movq %mm0, %ds:32(%edi)
133 movq %ds:40(%esi), %mm0
134 movq %mm0, %ds:40(%edi)
135 movq %ds:48(%esi), %mm0
136 movq %mm0, %ds:48(%edi)
137 movq %ds:56(%esi), %mm0
138 movq %mm0, %ds:56(%edi)
145 # Restore mm0 from MmxSave
147 emms # Exit MMX Instruction
149 # Copy as many DWORDS as possible
150 _CopyRemainingDWords:
152 jb _CopyRemainingBytes
154 movl (%esi), %eax # get data from Source
155 movl %eax, (%edi) # write byte to Destination
156 subl $4, %ecx # decrement Count
157 addl $4, %esi # advance Source pointer
158 addl $4, %edi # advance Destination pointer
159 jmp _CopyRemainingDWords # back to top
164 movb (%esi), %al # get byte from Source
165 movb %al, (%edi) # write byte to Destination
168 incl %edi # advance Destination pointer
169 jmp _CopyRemainingBytes # back to top of loop
172 # We do this block if the source and destination buffers overlap. To
173 # handle it, copy starting at the end of the source buffer and work
174 # your way back. Since this is the atypical case, this code has not
175 # been optimized, and thus simply copies bytes.
179 # Move the source and destination pointers to the end of the range
180 addl %ecx, %esi # Source + Count
182 addl %ecx, %edi # Dest + Count
188 movb (%esi), %al # get byte from Source
189 movb %al, (%edi) # write byte to Destination
193 jmp _CopyOverlappedLoop # back to top of loop
201 #EfiCommonLibCopyMem ENDP