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 #  EfiSetMem.asm
     15 #
     16 #Abstract:
     17 #
     18 #  This is the code that supports IA32-optimized SetMem service
     19 #
     20 #--*/
     21 #include "EfiBind.h"
     22 #---------------------------------------------------------------------------
     23     .686:
     24     #.MODEL flat,C
     25     .mmx:
     26     .code:
     27 
     28 #---------------------------------------------------------------------------
     29 .globl ASM_PFX(EfiCommonLibSetMem)
     30 
     31 #VOID
     32 #EfiCommonLibSetMem (
     33 #  IN VOID   *Buffer,
     34 #  IN UINTN  Count,
     35 #  IN UINT8  Value
     36 #  )
     37 #/*++
     38 #
     39 #Input:  VOID   *Buffer - Pointer to buffer to write
     40 #        UINTN  Count   - Number of bytes to write
     41 #        UINT8  Value   - Value to write
     42 #
     43 #Output: None.
     44 #
     45 #Saves:
     46 #
     47 #Modifies:
     48 #
     49 #Description:  This function is an optimized set-memory function.
     50 #
     51 #Notes:  This function tries to set memory 8 bytes at a time. As a result,
     52 #        it first picks up any misaligned bytes, then words, before getting
     53 #        in the main loop that does the 8-byte clears.
     54 #
     55 #--*/
     56 ASM_PFX(EfiCommonLibSetMem):
     57 
     58     pushl  %ebp
     59     movl   %esp, %ebp
     60     subl   $0x10, %esp # Reserve space for local variable UINT64 QWordValue @[ebp - 10H] & UINT64 MmxSave @[ebp - 18H]
     61     pushl  %ebx
     62     pushl  %edi
     63 
     64     movl 0xC(%ebp), %edx # Count
     65     testl %edx, %edx
     66     je _SetMemDone
     67 
     68     pushl %ebx
     69 
     70     movl 8(%ebp), %eax  # Buffer
     71     movb 0x10(%ebp), %bl # Value
     72     movl %eax, %edi
     73     movb %bl, %bh
     74 
     75     cmpl $256, %edx
     76     jb _SetRemindingByte
     77 
     78     andb $0x7, %al
     79     testb %al, %al
     80     je _SetBlock
     81 
     82     movl %edi, %eax
     83     shrl $3, %eax
     84     incl %eax
     85     shll $3, %eax
     86     subl %edi, %eax
     87     cmpl %edx, %eax
     88     jnb _SetRemindingByte
     89 
     90     subl %eax, %edx
     91     movl %eax, %ecx
     92 
     93     movb %bl, %al
     94     rep
     95     stosb
     96 
     97 _SetBlock:
     98     movl %edx, %eax
     99     shrl $6, %eax
    100     testl %eax, %eax
    101     je _SetRemindingByte
    102 
    103     shll $6, %eax
    104     subl %eax, %edx
    105     shrl $6, %eax
    106 
    107     movw %bx, -0x10(%ebp)            # QWordValue[0]
    108     movw %bx, -0x10+2(%ebp)          # QWordValue[2]
    109     movw %bx, -0x10+4(%ebp)          # QWordValue[4]
    110     movw %bx, -0x10+6(%ebp)          # QWordValue[6]
    111 
    112 
    113     movq  %mm0, -8(%ebp) # Save mm0 to MmxSave
    114     movq  -0x10(%ebp), %mm0 # Load QWordValue to mm0
    115 
    116 _B:
    117     movq  %mm0, %ds:(%edi)
    118     movq  %mm0, %ds:8(%edi)
    119     movq  %mm0, %ds:16(%edi)
    120     movq  %mm0, %ds:24(%edi)
    121     movq  %mm0, %ds:32(%edi)
    122     movq  %mm0, %ds:40(%edi)
    123     movq  %mm0, %ds:48(%edi)
    124     movq  %mm0, %ds:56(%edi)
    125     addl $64, %edi
    126     decl %eax
    127     jnz _B
    128 
    129 # Restore mm0
    130     movq  -8(%ebp), %mm0 # Restore MmxSave to mm0
    131     emms                                 # Exit MMX Instruction
    132 
    133 _SetRemindingByte:
    134     movl %edx, %ecx
    135 
    136     movl %ebx, %eax
    137     shll $16, %eax
    138     movw %bx, %ax
    139     shrl $2, %ecx
    140     rep
    141     stosl
    142 
    143     movl %edx, %ecx
    144     andl $3, %ecx
    145     rep
    146     stosb
    147 
    148     popl %ebx
    149 
    150 _SetMemDone:
    151 
    152     popl %edi
    153     popl %ebx
    154     leave
    155     ret
    156 
    157 #EfiCommonLibSetMem ENDP
    158 
    159