1/*++
2
3Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
4This program and the accompanying materials
5are licensed and made available under the terms and conditions of the BSD License
6which accompanies this distribution.  The full text of the license may be found at
7http://opensource.org/licenses/bsd-license.php
8
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12Module Name:
13
14  EfiZeroMemSSE2.c
15
16Abstract:
17
18  This is the code that supports IA32-optimized ZeroMem service
19
20--*/
21
22#include "Tiano.h"
23
24VOID
25EfiCommonLibZeroMem (
26  IN VOID   *Buffer,
27  IN UINTN  Count
28  )
29/*++
30
31Input:  VOID   *Buffer - Pointer to buffer to clear
32        UINTN  Count  - Number of bytes to clear
33
34Output: None.
35
36Saves:
37
38Modifies:
39
40Description:  This function is an optimized zero-memory function.
41
42Notes:  This function tries to zero memory 8 bytes at a time. As a result,
43        it first picks up any misaligned bytes, then words, before getting
44        in the main loop that does the 8-byte clears.
45
46--*/
47{
48  __asm {
49  mov   ecx, Count
50  mov   edi, Buffer
51
52  ; Pick up misaligned start bytes (get pointer 4-byte aligned)
53_StartByteZero:
54  mov   eax, edi
55  and   al, 3                       ; check lower 2 bits of address
56  test  al, al
57  je    _ZeroBlocks                 ; already aligned?
58  cmp   ecx, 0
59  je    _ZeroMemDone
60
61  ; Clear the byte memory location
62  mov   BYTE PTR [edi], 0
63  inc    edi
64
65  ; Decrement our count
66  dec    ecx
67  jmp   _StartByteZero        ; back to top of loop
68
69_ZeroBlocks:
70
71  ; Compute how many 64-byte blocks we can clear
72  mov   edx, ecx
73  shr   ecx, 6                      ; convert to 64-byte count
74  shl   ecx, 6                      ; convert back to bytes
75  sub   edx, ecx                    ; subtract from the original count
76  shr   ecx, 6                      ; and this is how many 64-byte blocks
77
78  ; If no 64-byte blocks, then skip
79  cmp    ecx, 0
80  je    _ZeroRemaining
81
82  xorps  xmm1, xmm1
83
84_B:
85  movdqu OWORD PTR ds:[edi], xmm1
86  movdqu OWORD PTR ds:[edi+16], xmm1
87  movdqu OWORD PTR ds:[edi+32], xmm1
88  movdqu OWORD PTR ds:[edi+48], xmm1
89
90  add    edi, 64
91  dec    ecx
92  jnz    _B
93
94
95_ZeroRemaining:
96  ; Zero out as many DWORDS as possible
97  mov   ecx, edx
98  shr   ecx, 2
99  xor   eax, eax
100
101  rep stosd
102
103  ; Zero out remaining as bytes
104  mov   ecx, edx
105  and   ecx, 03
106
107  rep   stosb
108
109_ZeroMemDone:
110  }
111}
112