From b7c51c9cf4864df6aabb99a1ae843becd577237c Mon Sep 17 00:00:00 2001 From: raywu Date: Fri, 15 Jun 2018 00:00:50 +0800 Subject: init. 1AQQW051 --- .../Library/EfiCommonLib/Ia32/EfiZeroMem.asm | 138 +++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 EDK/Foundation/Library/EfiCommonLib/Ia32/EfiZeroMem.asm (limited to 'EDK/Foundation/Library/EfiCommonLib/Ia32/EfiZeroMem.asm') diff --git a/EDK/Foundation/Library/EfiCommonLib/Ia32/EfiZeroMem.asm b/EDK/Foundation/Library/EfiCommonLib/Ia32/EfiZeroMem.asm new file mode 100644 index 0000000..7188e29 --- /dev/null +++ b/EDK/Foundation/Library/EfiCommonLib/Ia32/EfiZeroMem.asm @@ -0,0 +1,138 @@ + 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 + .MMX + .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 + LOCAL MmxSave:QWORD + + ; 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 + + ; Save mm0 + movq MmxSave, mm0 + + pxor mm0, mm0 ; Clear mm0 + +@@: + movq QWORD PTR ds:[edi], mm0 + movq QWORD PTR ds:[edi+8], mm0 + movq QWORD PTR ds:[edi+16], mm0 + movq QWORD PTR ds:[edi+24], mm0 + movq QWORD PTR ds:[edi+32], mm0 + movq QWORD PTR ds:[edi+40], mm0 + movq QWORD PTR ds:[edi+48], mm0 + movq QWORD PTR ds:[edi+56], mm0 + + add edi, 64 + dec ecx + jnz @B + +; Restore mm0 + movq mm0, MmxSave + emms ; Exit MMX Instruction + +_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 -- cgit v1.2.3