mirror of https://github.com/acidanthera/audk.git
140 lines
3.7 KiB
ArmAsm
140 lines
3.7 KiB
ArmAsm
#/*++
|
|
#
|
|
#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 "EfiBind.h"
|
|
#---------------------------------------------------------------------------
|
|
.686:
|
|
#.MODEL flat,C
|
|
.mmx:
|
|
.code:
|
|
|
|
#---------------------------------------------------------------------------
|
|
.globl ASM_PFX(EfiCommonLibZeroMem)
|
|
#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.
|
|
#
|
|
#--*/
|
|
ASM_PFX(EfiCommonLibZeroMem):
|
|
# UINT64 MmxSave;
|
|
pushl %ebp
|
|
movl %esp, %ebp
|
|
pushl %ecx # Reserve space for local variable MmxSave
|
|
pushl %ecx
|
|
pushl %edi
|
|
|
|
movl 0xC(%ebp), %ecx # Count
|
|
movl 8(%ebp), %edi # Buffer
|
|
|
|
# Pick up misaligned start bytes (get pointer 4-byte aligned)
|
|
_StartByteZero:
|
|
movl %edi, %eax
|
|
andb $3, %al # check lower 2 bits of address
|
|
testb %al, %al
|
|
je _ZeroBlocks # already aligned?
|
|
cmpl $0, %ecx
|
|
je _ZeroMemDone
|
|
|
|
# Clear the byte memory location
|
|
movb $0, (%edi)
|
|
incl %edi
|
|
|
|
# Decrement our count
|
|
decl %ecx
|
|
jmp _StartByteZero # back to top of loop
|
|
|
|
_ZeroBlocks:
|
|
|
|
# Compute how many 64-byte blocks we can clear
|
|
movl %ecx, %edx
|
|
shrl $6, %ecx # convert to 64-byte count
|
|
shll $6, %ecx # convert back to bytes
|
|
subl %ecx, %edx # subtract from the original count
|
|
shrl $6, %ecx # and this is how many 64-byte blocks
|
|
|
|
# If no 64-byte blocks, then skip
|
|
cmpl $0, %ecx
|
|
je _ZeroRemaining
|
|
|
|
# Save mm0
|
|
movq %mm0, -8(%ebp) # Save mm0 to MmxSave
|
|
|
|
pxor %mm0, %mm0 # Clear mm0
|
|
|
|
_B:
|
|
movq %mm0, %ds:(%edi)
|
|
movq %mm0, %ds:8(%edi)
|
|
movq %mm0, %ds:16(%edi)
|
|
movq %mm0, %ds:24(%edi)
|
|
movq %mm0, %ds:32(%edi)
|
|
movq %mm0, %ds:40(%edi)
|
|
movq %mm0, %ds:48(%edi)
|
|
movq %mm0, %ds:56(%edi)
|
|
|
|
addl $64, %edi
|
|
decl %ecx
|
|
jnz _B
|
|
|
|
# Restore mm0
|
|
movq -8(%ebp), %mm0 # Restore mm0 from MmxSave
|
|
emms # Exit MMX Instruction
|
|
|
|
_ZeroRemaining:
|
|
# Zero out as many DWORDS as possible
|
|
movl %edx, %ecx
|
|
shrl $2, %ecx
|
|
xorl %eax, %eax
|
|
|
|
rep
|
|
stosl
|
|
|
|
# Zero out remaining as bytes
|
|
movl %edx, %ecx
|
|
andl $03, %ecx
|
|
|
|
rep
|
|
stosb
|
|
|
|
_ZeroMemDone:
|
|
|
|
popl %edi
|
|
leave
|
|
ret
|
|
#EfiCommonLibZeroMem ENDP
|
|
|