1478db76bbe37e93416297d37f146ba76ab296380qwang;/*++ 2478db76bbe37e93416297d37f146ba76ab296380qwang; 34ea9375a2d02a43671437e0d3d808d85afb30afahhtian;Copyright (c) 2006, Intel Corporation. All rights reserved.<BR> 44ea9375a2d02a43671437e0d3d808d85afb30afahhtian;This program and the accompanying materials 5478db76bbe37e93416297d37f146ba76ab296380qwang;are licensed and made available under the terms and conditions of the BSD License 6478db76bbe37e93416297d37f146ba76ab296380qwang;which accompanies this distribution. The full text of the license may be found at 7478db76bbe37e93416297d37f146ba76ab296380qwang;http://opensource.org/licenses/bsd-license.php 8478db76bbe37e93416297d37f146ba76ab296380qwang; 9478db76bbe37e93416297d37f146ba76ab296380qwang;THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 10478db76bbe37e93416297d37f146ba76ab296380qwang;WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 11478db76bbe37e93416297d37f146ba76ab296380qwang; 12478db76bbe37e93416297d37f146ba76ab296380qwang;Module Name: 13478db76bbe37e93416297d37f146ba76ab296380qwang; 14478db76bbe37e93416297d37f146ba76ab296380qwang; EfiCopyMem.c 15478db76bbe37e93416297d37f146ba76ab296380qwang; 16478db76bbe37e93416297d37f146ba76ab296380qwang;Abstract: 17478db76bbe37e93416297d37f146ba76ab296380qwang; 18478db76bbe37e93416297d37f146ba76ab296380qwang; This is the code that supports IA32-optimized CopyMem service 19478db76bbe37e93416297d37f146ba76ab296380qwang; 20478db76bbe37e93416297d37f146ba76ab296380qwang;--*/ 21478db76bbe37e93416297d37f146ba76ab296380qwang 22478db76bbe37e93416297d37f146ba76ab296380qwang;--------------------------------------------------------------------------- 23478db76bbe37e93416297d37f146ba76ab296380qwang .686 24478db76bbe37e93416297d37f146ba76ab296380qwang .model flat,C 25478db76bbe37e93416297d37f146ba76ab296380qwang .mmx 26478db76bbe37e93416297d37f146ba76ab296380qwang .code 27478db76bbe37e93416297d37f146ba76ab296380qwang 28478db76bbe37e93416297d37f146ba76ab296380qwang;--------------------------------------------------------------------------- 29478db76bbe37e93416297d37f146ba76ab296380qwang 30478db76bbe37e93416297d37f146ba76ab296380qwang;VOID 31478db76bbe37e93416297d37f146ba76ab296380qwang;EfiCommonLibCopyMem ( 32478db76bbe37e93416297d37f146ba76ab296380qwang; IN VOID *Destination, 33478db76bbe37e93416297d37f146ba76ab296380qwang; IN VOID *Source, 34478db76bbe37e93416297d37f146ba76ab296380qwang; IN UINTN Count 35478db76bbe37e93416297d37f146ba76ab296380qwang; ) 36478db76bbe37e93416297d37f146ba76ab296380qwang;/*++ 37478db76bbe37e93416297d37f146ba76ab296380qwang; 38478db76bbe37e93416297d37f146ba76ab296380qwang;Routine Description: 39478db76bbe37e93416297d37f146ba76ab296380qwang; 40478db76bbe37e93416297d37f146ba76ab296380qwang; Copy Length bytes from Source to Destination. 41478db76bbe37e93416297d37f146ba76ab296380qwang; 42478db76bbe37e93416297d37f146ba76ab296380qwang;Arguments: 43478db76bbe37e93416297d37f146ba76ab296380qwang; 44478db76bbe37e93416297d37f146ba76ab296380qwang; Destination - Target of copy 45478db76bbe37e93416297d37f146ba76ab296380qwang; 46478db76bbe37e93416297d37f146ba76ab296380qwang; Source - Place to copy from 47478db76bbe37e93416297d37f146ba76ab296380qwang; 48478db76bbe37e93416297d37f146ba76ab296380qwang; Length - Number of bytes to copy 49478db76bbe37e93416297d37f146ba76ab296380qwang; 50478db76bbe37e93416297d37f146ba76ab296380qwang;Returns: 51478db76bbe37e93416297d37f146ba76ab296380qwang; 52478db76bbe37e93416297d37f146ba76ab296380qwang; None 53478db76bbe37e93416297d37f146ba76ab296380qwang; 54478db76bbe37e93416297d37f146ba76ab296380qwang;--*/ 55478db76bbe37e93416297d37f146ba76ab296380qwangEfiCommonLibCopyMem PROC 56478db76bbe37e93416297d37f146ba76ab296380qwang 57478db76bbe37e93416297d37f146ba76ab296380qwang push ebp 58478db76bbe37e93416297d37f146ba76ab296380qwang mov ebp, esp 59478db76bbe37e93416297d37f146ba76ab296380qwang push ecx ; reserve space for Scratch Local variable UINT64 MmxSave 60478db76bbe37e93416297d37f146ba76ab296380qwang push ecx 61478db76bbe37e93416297d37f146ba76ab296380qwang push esi 62478db76bbe37e93416297d37f146ba76ab296380qwang push edi 63478db76bbe37e93416297d37f146ba76ab296380qwang 64478db76bbe37e93416297d37f146ba76ab296380qwang mov ecx, [ebp + 10h] ; Count 65478db76bbe37e93416297d37f146ba76ab296380qwang mov esi, [ebp + 0Ch] ; Source 66478db76bbe37e93416297d37f146ba76ab296380qwang mov edi, [ebp + 8] ; Destination 67478db76bbe37e93416297d37f146ba76ab296380qwang 68478db76bbe37e93416297d37f146ba76ab296380qwang ; First off, make sure we have no overlap. That is to say, 69478db76bbe37e93416297d37f146ba76ab296380qwang ; if (Source == Destination) => do nothing 70478db76bbe37e93416297d37f146ba76ab296380qwang ; if (Source + Count <= Destination) => regular copy 71478db76bbe37e93416297d37f146ba76ab296380qwang ; if (Destination + Count <= Source) => regular copy 72478db76bbe37e93416297d37f146ba76ab296380qwang ; otherwise, do a reverse copy 73478db76bbe37e93416297d37f146ba76ab296380qwang mov eax, esi 74478db76bbe37e93416297d37f146ba76ab296380qwang add eax, ecx ; Source + Count 75478db76bbe37e93416297d37f146ba76ab296380qwang cmp eax, edi 763e99020dbf0a159e34b84e7ae9125f2e368d5390lgao jbe _StartByteCopy 77478db76bbe37e93416297d37f146ba76ab296380qwang 78478db76bbe37e93416297d37f146ba76ab296380qwang mov eax, edi 79478db76bbe37e93416297d37f146ba76ab296380qwang add eax, ecx ; Dest + Count 80478db76bbe37e93416297d37f146ba76ab296380qwang cmp eax, esi 813e99020dbf0a159e34b84e7ae9125f2e368d5390lgao jbe _StartByteCopy 82478db76bbe37e93416297d37f146ba76ab296380qwang 83478db76bbe37e93416297d37f146ba76ab296380qwang cmp esi, edi 84478db76bbe37e93416297d37f146ba76ab296380qwang je _CopyMemDone 853e99020dbf0a159e34b84e7ae9125f2e368d5390lgao jb _CopyOverlapped ; too bad -- overlaps 86478db76bbe37e93416297d37f146ba76ab296380qwang 87478db76bbe37e93416297d37f146ba76ab296380qwang ; Pick up misaligned start bytes to get destination pointer 4-byte aligned 88478db76bbe37e93416297d37f146ba76ab296380qwang_StartByteCopy: 89478db76bbe37e93416297d37f146ba76ab296380qwang cmp ecx, 0 90478db76bbe37e93416297d37f146ba76ab296380qwang je _CopyMemDone ; Count == 0, all done 91478db76bbe37e93416297d37f146ba76ab296380qwang mov edx, edi 92478db76bbe37e93416297d37f146ba76ab296380qwang and dl, 3 ; check lower 2 bits of address 93478db76bbe37e93416297d37f146ba76ab296380qwang test dl, dl 94478db76bbe37e93416297d37f146ba76ab296380qwang je SHORT _CopyBlocks ; already aligned? 95478db76bbe37e93416297d37f146ba76ab296380qwang 96478db76bbe37e93416297d37f146ba76ab296380qwang ; Copy a byte 97478db76bbe37e93416297d37f146ba76ab296380qwang mov al, BYTE PTR [esi] ; get byte from Source 98478db76bbe37e93416297d37f146ba76ab296380qwang mov BYTE PTR [edi], al ; write byte to Destination 99478db76bbe37e93416297d37f146ba76ab296380qwang dec ecx 100478db76bbe37e93416297d37f146ba76ab296380qwang inc edi 101478db76bbe37e93416297d37f146ba76ab296380qwang inc esi 102478db76bbe37e93416297d37f146ba76ab296380qwang jmp _StartByteCopy ; back to top of loop 103478db76bbe37e93416297d37f146ba76ab296380qwang 104478db76bbe37e93416297d37f146ba76ab296380qwang_CopyBlocks: 105478db76bbe37e93416297d37f146ba76ab296380qwang ; Compute how many 64-byte blocks we can clear 106478db76bbe37e93416297d37f146ba76ab296380qwang mov eax, ecx ; get Count in eax 107478db76bbe37e93416297d37f146ba76ab296380qwang shr eax, 6 ; convert to 64-byte count 108478db76bbe37e93416297d37f146ba76ab296380qwang shl eax, 6 ; convert back to bytes 109478db76bbe37e93416297d37f146ba76ab296380qwang sub ecx, eax ; subtract from the original count 110478db76bbe37e93416297d37f146ba76ab296380qwang shr eax, 6 ; and this is how many 64-byte blocks 111478db76bbe37e93416297d37f146ba76ab296380qwang 112478db76bbe37e93416297d37f146ba76ab296380qwang ; If no 64-byte blocks, then skip 113478db76bbe37e93416297d37f146ba76ab296380qwang cmp eax, 0 114478db76bbe37e93416297d37f146ba76ab296380qwang je _CopyRemainingDWords 115478db76bbe37e93416297d37f146ba76ab296380qwang 116478db76bbe37e93416297d37f146ba76ab296380qwang ; Save mm0 to UINT64 MmxSave 117478db76bbe37e93416297d37f146ba76ab296380qwang movq [ebp - 8], mm0 118478db76bbe37e93416297d37f146ba76ab296380qwang 119478db76bbe37e93416297d37f146ba76ab296380qwangcopymmx: 120478db76bbe37e93416297d37f146ba76ab296380qwang 121478db76bbe37e93416297d37f146ba76ab296380qwang movq mm0, QWORD PTR ds:[esi] 122478db76bbe37e93416297d37f146ba76ab296380qwang movq QWORD PTR ds:[edi], mm0 123478db76bbe37e93416297d37f146ba76ab296380qwang movq mm0, QWORD PTR ds:[esi+8] 124478db76bbe37e93416297d37f146ba76ab296380qwang movq QWORD PTR ds:[edi+8], mm0 125478db76bbe37e93416297d37f146ba76ab296380qwang movq mm0, QWORD PTR ds:[esi+16] 126478db76bbe37e93416297d37f146ba76ab296380qwang movq QWORD PTR ds:[edi+16], mm0 127478db76bbe37e93416297d37f146ba76ab296380qwang movq mm0, QWORD PTR ds:[esi+24] 128478db76bbe37e93416297d37f146ba76ab296380qwang movq QWORD PTR ds:[edi+24], mm0 129478db76bbe37e93416297d37f146ba76ab296380qwang movq mm0, QWORD PTR ds:[esi+32] 130478db76bbe37e93416297d37f146ba76ab296380qwang movq QWORD PTR ds:[edi+32], mm0 131478db76bbe37e93416297d37f146ba76ab296380qwang movq mm0, QWORD PTR ds:[esi+40] 132478db76bbe37e93416297d37f146ba76ab296380qwang movq QWORD PTR ds:[edi+40], mm0 133478db76bbe37e93416297d37f146ba76ab296380qwang movq mm0, QWORD PTR ds:[esi+48] 134478db76bbe37e93416297d37f146ba76ab296380qwang movq QWORD PTR ds:[edi+48], mm0 135478db76bbe37e93416297d37f146ba76ab296380qwang movq mm0, QWORD PTR ds:[esi+56] 136478db76bbe37e93416297d37f146ba76ab296380qwang movq QWORD PTR ds:[edi+56], mm0 137478db76bbe37e93416297d37f146ba76ab296380qwang 138478db76bbe37e93416297d37f146ba76ab296380qwang add edi, 64 139478db76bbe37e93416297d37f146ba76ab296380qwang add esi, 64 140478db76bbe37e93416297d37f146ba76ab296380qwang dec eax 141478db76bbe37e93416297d37f146ba76ab296380qwang jnz copymmx 142478db76bbe37e93416297d37f146ba76ab296380qwang 143478db76bbe37e93416297d37f146ba76ab296380qwang; Restore mm0 from MmxSave 144478db76bbe37e93416297d37f146ba76ab296380qwang movq mm0, [ebp - 8] 145478db76bbe37e93416297d37f146ba76ab296380qwang emms ; Exit MMX Instruction 146478db76bbe37e93416297d37f146ba76ab296380qwang 147478db76bbe37e93416297d37f146ba76ab296380qwang ; Copy as many DWORDS as possible 148478db76bbe37e93416297d37f146ba76ab296380qwang_CopyRemainingDWords: 149478db76bbe37e93416297d37f146ba76ab296380qwang cmp ecx, 4 150478db76bbe37e93416297d37f146ba76ab296380qwang jb _CopyRemainingBytes 151478db76bbe37e93416297d37f146ba76ab296380qwang 152478db76bbe37e93416297d37f146ba76ab296380qwang mov eax, DWORD PTR [esi] ; get data from Source 153478db76bbe37e93416297d37f146ba76ab296380qwang mov DWORD PTR [edi], eax ; write byte to Destination 154478db76bbe37e93416297d37f146ba76ab296380qwang sub ecx, 4 ; decrement Count 155478db76bbe37e93416297d37f146ba76ab296380qwang add esi, 4 ; advance Source pointer 156478db76bbe37e93416297d37f146ba76ab296380qwang add edi, 4 ; advance Destination pointer 157478db76bbe37e93416297d37f146ba76ab296380qwang jmp _CopyRemainingDWords ; back to top 158478db76bbe37e93416297d37f146ba76ab296380qwang 159478db76bbe37e93416297d37f146ba76ab296380qwang_CopyRemainingBytes: 160478db76bbe37e93416297d37f146ba76ab296380qwang cmp ecx, 0 161478db76bbe37e93416297d37f146ba76ab296380qwang je _CopyMemDone 162478db76bbe37e93416297d37f146ba76ab296380qwang mov al, BYTE PTR [esi] ; get byte from Source 163478db76bbe37e93416297d37f146ba76ab296380qwang mov BYTE PTR [edi], al ; write byte to Destination 164478db76bbe37e93416297d37f146ba76ab296380qwang dec ecx 165478db76bbe37e93416297d37f146ba76ab296380qwang inc esi 166478db76bbe37e93416297d37f146ba76ab296380qwang inc edi ; advance Destination pointer 167478db76bbe37e93416297d37f146ba76ab296380qwang jmp SHORT _CopyRemainingBytes ; back to top of loop 168478db76bbe37e93416297d37f146ba76ab296380qwang 169478db76bbe37e93416297d37f146ba76ab296380qwang ; 170478db76bbe37e93416297d37f146ba76ab296380qwang ; We do this block if the source and destination buffers overlap. To 171478db76bbe37e93416297d37f146ba76ab296380qwang ; handle it, copy starting at the end of the source buffer and work 172478db76bbe37e93416297d37f146ba76ab296380qwang ; your way back. Since this is the atypical case, this code has not 173478db76bbe37e93416297d37f146ba76ab296380qwang ; been optimized, and thus simply copies bytes. 174478db76bbe37e93416297d37f146ba76ab296380qwang ; 175478db76bbe37e93416297d37f146ba76ab296380qwang_CopyOverlapped: 176478db76bbe37e93416297d37f146ba76ab296380qwang 177478db76bbe37e93416297d37f146ba76ab296380qwang ; Move the source and destination pointers to the end of the range 178478db76bbe37e93416297d37f146ba76ab296380qwang add esi, ecx ; Source + Count 179478db76bbe37e93416297d37f146ba76ab296380qwang dec esi 180478db76bbe37e93416297d37f146ba76ab296380qwang add edi, ecx ; Dest + Count 181478db76bbe37e93416297d37f146ba76ab296380qwang dec edi 182478db76bbe37e93416297d37f146ba76ab296380qwang 183478db76bbe37e93416297d37f146ba76ab296380qwang_CopyOverlappedLoop: 184478db76bbe37e93416297d37f146ba76ab296380qwang cmp ecx, 0 185478db76bbe37e93416297d37f146ba76ab296380qwang je _CopyMemDone 186478db76bbe37e93416297d37f146ba76ab296380qwang mov al, BYTE PTR [esi] ; get byte from Source 187478db76bbe37e93416297d37f146ba76ab296380qwang mov BYTE PTR [edi], al ; write byte to Destination 188478db76bbe37e93416297d37f146ba76ab296380qwang dec ecx 189478db76bbe37e93416297d37f146ba76ab296380qwang dec esi 190478db76bbe37e93416297d37f146ba76ab296380qwang dec edi 191478db76bbe37e93416297d37f146ba76ab296380qwang jmp _CopyOverlappedLoop ; back to top of loop 192478db76bbe37e93416297d37f146ba76ab296380qwang 193478db76bbe37e93416297d37f146ba76ab296380qwang_CopyMemDone: 194478db76bbe37e93416297d37f146ba76ab296380qwang 195478db76bbe37e93416297d37f146ba76ab296380qwang pop edi 196478db76bbe37e93416297d37f146ba76ab296380qwang pop esi 197478db76bbe37e93416297d37f146ba76ab296380qwang leave 198478db76bbe37e93416297d37f146ba76ab296380qwang ret 199478db76bbe37e93416297d37f146ba76ab296380qwangEfiCommonLibCopyMem ENDP 200478db76bbe37e93416297d37f146ba76ab296380qwang END 201