Home | History | Annotate | Download | only in Ia32
      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