1;/*++
2;
3;Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
4;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;---------------------------------------------------------------------------
22    .686
23    .model  flat,C
24    .mmx
25    .code
26
27;---------------------------------------------------------------------------
28;VOID
29;EfiCommonLibZeroMem (
30;  IN VOID   *Buffer,
31;  IN UINTN  Count
32;  )
33;/*++
34;
35;Input:  VOID   *Buffer - Pointer to buffer to clear
36;        UINTN  Count  - Number of bytes to clear
37;
38;Output: None.
39;
40;Saves:
41;
42;Modifies:
43;
44;Description:  This function is an optimized zero-memory function.
45;
46;Notes:  This function tries to zero memory 8 bytes at a time. As a result, 
47;        it first picks up any misaligned bytes, then words, before getting 
48;        in the main loop that does the 8-byte clears.
49;
50;--*/
51EfiCommonLibZeroMem PROC
52;  UINT64 MmxSave;
53    push  ebp
54    mov   ebp, esp
55    push  ecx  ; Reserve space for local variable MmxSave
56    push  ecx
57    push  edi
58    
59    mov   ecx, [ebp + 0Ch] ; Count
60    mov   edi, [ebp + 8]; Buffer
61
62    ; Pick up misaligned start bytes (get pointer 4-byte aligned)
63_StartByteZero:
64    mov   eax, edi    
65    and   al, 3                       ; check lower 2 bits of address
66    test  al, al
67    je    _ZeroBlocks                 ; already aligned?
68    cmp   ecx, 0
69    je    _ZeroMemDone
70
71    ; Clear the byte memory location
72    mov   BYTE PTR [edi], 0           
73    inc    edi
74
75    ; Decrement our count
76    dec    ecx
77    jmp   _StartByteZero        ; back to top of loop
78
79_ZeroBlocks:
80
81    ; Compute how many 64-byte blocks we can clear 
82    mov   edx, ecx
83    shr   ecx, 6                      ; convert to 64-byte count
84    shl   ecx, 6                      ; convert back to bytes
85    sub   edx, ecx                    ; subtract from the original count
86    shr   ecx, 6                      ; and this is how many 64-byte blocks
87
88    ; If no 64-byte blocks, then skip 
89    cmp    ecx, 0
90    je    _ZeroRemaining
91
92    ; Save mm0
93    movq  [ebp - 8], mm0  ; Save mm0 to MmxSave
94
95    pxor  mm0, mm0          ; Clear mm0
96
97_B:
98    movq  QWORD PTR ds:[edi], mm0
99    movq  QWORD PTR ds:[edi+8], mm0
100    movq  QWORD PTR ds:[edi+16], mm0
101    movq  QWORD PTR ds:[edi+24], mm0
102    movq  QWORD PTR ds:[edi+32], mm0
103    movq  QWORD PTR ds:[edi+40], mm0
104    movq  QWORD PTR ds:[edi+48], mm0
105    movq  QWORD PTR ds:[edi+56], mm0
106   
107    add    edi, 64
108    dec    ecx
109    jnz    _B
110  
111; Restore mm0
112    movq  mm0, [ebp - 8] ; Restore mm0 from MmxSave
113    emms                                 ; Exit MMX Instruction
114
115_ZeroRemaining:
116    ; Zero out as many DWORDS as possible
117    mov   ecx, edx
118    shr   ecx, 2
119    xor   eax, eax
120
121    rep stosd
122
123    ; Zero out remaining as bytes
124    mov   ecx, edx
125    and   ecx, 03
126
127    rep   stosb
128 
129_ZeroMemDone:
130
131    pop    edi
132    leave
133    ret
134EfiCommonLibZeroMem ENDP	
135	END
136