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 #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 140