summaryrefslogtreecommitdiff
path: root/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/EfiZeroMem.c
diff options
context:
space:
mode:
Diffstat (limited to 'EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/EfiZeroMem.c')
-rw-r--r--EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/EfiZeroMem.c122
1 files changed, 122 insertions, 0 deletions
diff --git a/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/EfiZeroMem.c b/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/EfiZeroMem.c
new file mode 100644
index 0000000000..fc9ed7b621
--- /dev/null
+++ b/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/EfiZeroMem.c
@@ -0,0 +1,122 @@
+/*++
+
+Copyright (c) 2006, 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.c
+
+Abstract:
+
+ This is the code that supports IA32-optimized ZeroMem service
+
+--*/
+
+#include "Tiano.h"
+
+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.
+
+--*/
+{
+ UINT64 MmxSave;
+ __asm {
+ 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
+
+_B:
+ 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:
+ }
+}