]> git.proxmox.com Git - mirror_edk2.git/blob - EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/EfiZeroMem.S
c72f12295c31bb3128e8220e372e1e5000fddd22
[mirror_edk2.git] / EdkCompatibilityPkg / Foundation / Library / EfiCommonLib / Ia32 / EfiZeroMem.S
1 #/*++
2 #
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
8 #
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.
11 #
12 #Module Name:
13 #
14 # EfiZeroMem.c
15 #
16 #Abstract:
17 #
18 # This is the code that supports IA32-optimized ZeroMem service
19 #
20 #--*/
21 #include "EfiBind.h"
22 #---------------------------------------------------------------------------
23 .686:
24 #.MODEL flat,C
25 .mmx:
26 .code:
27
28 #---------------------------------------------------------------------------
29 .globl ASM_PFX(EfiCommonLibZeroMem)
30 #VOID
31 #EfiCommonLibZeroMem (
32 # IN VOID *Buffer,
33 # IN UINTN Count
34 # )
35 #/*++
36 #
37 #Input: VOID *Buffer - Pointer to buffer to clear
38 # UINTN Count - Number of bytes to clear
39 #
40 #Output: None.
41 #
42 #Saves:
43 #
44 #Modifies:
45 #
46 #Description: This function is an optimized zero-memory function.
47 #
48 #Notes: This function tries to zero memory 8 bytes at a time. As a result,
49 # it first picks up any misaligned bytes, then words, before getting
50 # in the main loop that does the 8-byte clears.
51 #
52 #--*/
53 ASM_PFX(EfiCommonLibZeroMem):
54 # UINT64 MmxSave;
55 pushl %ebp
56 movl %esp, %ebp
57 pushl %ecx # Reserve space for local variable MmxSave
58 pushl %ecx
59 pushl %edi
60
61 movl 0xC(%ebp), %ecx # Count
62 movl 8(%ebp), %edi # Buffer
63
64 # Pick up misaligned start bytes (get pointer 4-byte aligned)
65 _StartByteZero:
66 movl %edi, %eax
67 andb $3, %al # check lower 2 bits of address
68 testb %al, %al
69 je _ZeroBlocks # already aligned?
70 cmpl $0, %ecx
71 je _ZeroMemDone
72
73 # Clear the byte memory location
74 movb $0, (%edi)
75 incl %edi
76
77 # Decrement our count
78 decl %ecx
79 jmp _StartByteZero # back to top of loop
80
81 _ZeroBlocks:
82
83 # Compute how many 64-byte blocks we can clear
84 movl %ecx, %edx
85 shrl $6, %ecx # convert to 64-byte count
86 shll $6, %ecx # convert back to bytes
87 subl %ecx, %edx # subtract from the original count
88 shrl $6, %ecx # and this is how many 64-byte blocks
89
90 # If no 64-byte blocks, then skip
91 cmpl $0, %ecx
92 je _ZeroRemaining
93
94 # Save mm0
95 movq %mm0, -8(%ebp) # Save mm0 to MmxSave
96
97 pxor %mm0, %mm0 # Clear mm0
98
99 _B:
100 movq %mm0, %ds:(%edi)
101 movq %mm0, %ds:8(%edi)
102 movq %mm0, %ds:16(%edi)
103 movq %mm0, %ds:24(%edi)
104 movq %mm0, %ds:32(%edi)
105 movq %mm0, %ds:40(%edi)
106 movq %mm0, %ds:48(%edi)
107 movq %mm0, %ds:56(%edi)
108
109 addl $64, %edi
110 decl %ecx
111 jnz _B
112
113 # Restore mm0
114 movq -8(%ebp), %mm0 # Restore mm0 from MmxSave
115 emms # Exit MMX Instruction
116
117 _ZeroRemaining:
118 # Zero out as many DWORDS as possible
119 movl %edx, %ecx
120 shrl $2, %ecx
121 xorl %eax, %eax
122
123 rep
124 stosl
125
126 # Zero out remaining as bytes
127 movl %edx, %ecx
128 andl $03, %ecx
129
130 rep
131 stosb
132
133 _ZeroMemDone:
134
135 popl %edi
136 leave
137 ret
138 #EfiCommonLibZeroMem ENDP
139