diff options
Diffstat (limited to 'EDK/Foundation/Library/EfiCommonLib/Ia32/EfiZeroMemSSE2.asm')
-rw-r--r-- | EDK/Foundation/Library/EfiCommonLib/Ia32/EfiZeroMemSSE2.asm | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/EDK/Foundation/Library/EfiCommonLib/Ia32/EfiZeroMemSSE2.asm b/EDK/Foundation/Library/EfiCommonLib/Ia32/EfiZeroMemSSE2.asm new file mode 100644 index 0000000..a5efd4d --- /dev/null +++ b/EDK/Foundation/Library/EfiCommonLib/Ia32/EfiZeroMemSSE2.asm @@ -0,0 +1,127 @@ + TITLE EfiZeroMem.asm: Optimized memory-zero routine + +;------------------------------------------------------------------------------ +; +; Copyright (c) 2004, Intel Corporation +; All rights reserved. This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +; Module Name: +; +; EfiZeroMem.asm +; +; Abstract: +; +; This is the code that supports IA32-optimized ZeroMem service +; +;------------------------------------------------------------------------------ + +; PROC:PRIVATE + .686P + .XMM + .MODEL SMALL + .CODE + +EfiCommonLibZeroMem PROTO C Buffer:PTR DWORD, Count:DWORD + +;------------------------------------------------------------------------------ +; Procedure: EfiCommonLibZeroMem +; +; VOID +; EfiCommonLibZeroMem ( +; IN VOID *Buffer, +; IN UINTN Count +; ) +; +; Input: VOID *Buffer - Pointer to buffer to clear +; UINTN Count - Number of bytes to clear +; +; Output: None. +; +; Saves: +; +; Modifies: +; +; Description: This function is an optimized zero-memory function. +; +; Notes: This function tries to zero memory 8 bytes at a time. As a result, +; it first picks up any misaligned bytes, then words, before getting +; in the main loop that does the 8-byte clears. +; +;------------------------------------------------------------------------------ +EfiCommonLibZeroMem PROC C Buffer:PTR DWORD, Count:DWORD + + ; Save edi, then put the buffer pointer into it. + push edi + mov ecx, Count + mov edi, Buffer + + ; Pick up misaligned start bytes (get pointer 4-byte aligned) +_StartByteZero: + mov eax, edi + and al, 3 ; check lower 2 bits of address + test al, al + je _ZeroBlocks ; already aligned? + cmp ecx, 0 + je _ZeroMemDone + + ; Clear the byte memory location + mov BYTE PTR [edi], 0 + inc edi + + ; Decrement our count + dec ecx + jmp _StartByteZero ; back to top of loop + +_ZeroBlocks: + + ; Compute how many 64-byte blocks we can clear + mov edx, ecx + shr ecx, 6 ; convert to 64-byte count + shl ecx, 6 ; convert back to bytes + sub edx, ecx ; subtract from the original count + shr ecx, 6 ; and this is how many 64-byte blocks + + ; If no 64-byte blocks, then skip + cmp ecx, 0 + je _ZeroRemaining + + xorps xmm1, xmm1 + +@@: + movdqu OWORD PTR ds:[edi], xmm1 + movdqu OWORD PTR ds:[edi+16], xmm1 + movdqu OWORD PTR ds:[edi+32], xmm1 + movdqu OWORD PTR ds:[edi+48], xmm1 + + add edi, 64 + dec ecx + jnz @B + + +_ZeroRemaining: + ; Zero out as many DWORDS as possible + mov ecx, edx + shr ecx, 2 + xor eax, eax + + rep stosd + + ; Zero out remaining as bytes + mov ecx, edx + and ecx, 03 + + rep stosb + +_ZeroMemDone: + pop edi + + ret + +EfiCommonLibZeroMem ENDP + END |