3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. 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
34 Copy Length bytes from Source to Destination.
38 Destination - Target of copy
40 Source - Place to copy from
42 Length - Number of bytes to copy
55 ; First off
, make sure we have no overlap
. That is to say
,
56 ; if (Source
== Destination
) => do nothing
57 ; if (Source
+ Count
<= Destination
) => regular copy
58 ; if (Destination
+ Count
<= Source
) => regular copy
59 ; otherwise
, do a reverse copy
61 add eax
, ecx
; Source
+ Count
66 add eax
, ecx
; Dest
+ Count
72 jl _CopyOverlapped
; too bad
-- overlaps
74 ; Pick up misaligned start bytes to get destination pointer
4-byte aligned
77 je _CopyMemDone
; Count
== 0, all done
79 and dl
, 3 ; check lower
2 bits of address
81 je SHORT _CopyBlocks
; already aligned
?
84 mov al
, BYTE PTR
[esi
] ; get byte from Source
85 mov BYTE PTR
[edi
], al
; write byte to Destination
89 jmp _StartByteCopy
; back to top of loop
92 ; Compute how many
64-byte blocks we can clear
93 mov eax
, ecx
; get Count in eax
94 shr eax
, 6 ; convert to
64-byte count
95 shl eax
, 6 ; convert back to bytes
96 sub ecx
, eax
; subtract from the original count
97 shr eax
, 6 ; and this is how many
64-byte blocks
99 ; If no
64-byte blocks
, then skip
101 je _CopyRemainingDWords
106 movdqu xmm0
, OWORD PTR ds
:[esi
]
107 movdqu QWORD PTR ds
:[edi
], xmm0
108 movdqu xmm1
, OWORD PTR ds
:[esi
+16]
109 movdqu QWORD PTR ds
:[edi
+16], xmm1
110 movdqu xmm2
, OWORD PTR ds
:[esi
+32]
111 movdqu QWORD PTR ds
:[edi
+32], xmm2
112 movdqu xmm3
, OWORD PTR ds
:[esi
+48]
113 movdqu QWORD PTR ds
:[edi
+48], xmm3
121 ; Copy as many DWORDS as possible
122 _CopyRemainingDWords
:
124 jb _CopyRemainingBytes
126 mov eax
, DWORD PTR
[esi
] ; get data from Source
127 mov DWORD PTR
[edi
], eax
; write byte to Destination
128 sub ecx
, 4 ; decrement Count
129 add esi
, 4 ; advance Source pointer
130 add edi
, 4 ; advance Destination pointer
131 jmp _CopyRemainingDWords
; back to top
136 mov al
, BYTE PTR
[esi
] ; get byte from Source
137 mov BYTE PTR
[edi
], al
; write byte to Destination
140 inc edi
; advance Destination pointer
141 jmp SHORT _CopyRemainingBytes
; back to top of loop
144 ; We
do this block
if the source
and destination buffers overlap
. To
145 ; handle it
, copy starting at the end of the source buffer
and work
146 ; your way back
. Since
this is the atypical
case, this code has
not
147 ; been optimized
, and thus simply copies bytes
.
151 ; Move the source
and destination pointers to the end of the range
152 add esi
, ecx
; Source
+ Count
154 add edi
, ecx
; Dest
+ Count
160 mov al
, BYTE PTR
[esi
] ; get byte from Source
161 mov BYTE PTR
[edi
], al
; write byte to Destination
165 jmp _CopyOverlappedLoop
; back to top of loop