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   EfiSetMemSSE2.c
     15 
     16 Abstract:
     17 
     18   This is the code that supports IA32-optimized SetMem service
     19 
     20 --*/
     21 
     22 #include "Tiano.h"
     23 
     24 VOID
     25 EfiCommonLibSetMem (
     26   IN VOID   *Buffer,
     27   IN UINTN  Count,
     28   IN UINT8  Value
     29   )
     30 /*++
     31 
     32 Input:  VOID   *Buffer - Pointer to buffer to write
     33         UINTN  Count   - Number of bytes to write
     34         UINT8  Value   - Value to write
     35 
     36 Output: None.
     37 
     38 Saves:
     39 
     40 Modifies:
     41 
     42 Description:  This function is an optimized set-memory function.
     43 
     44 Notes:  This function tries to set memory 8 bytes at a time. As a result,
     45         it first picks up any misaligned bytes, then words, before getting
     46         in the main loop that does the 8-byte clears.
     47 
     48 --*/
     49 {
     50   UINT64 QWordValue;
     51   UINT64 MmxSave;
     52   __asm {
     53     mov edx, Count
     54     test edx, edx
     55     je _SetMemDone
     56 
     57     push ebx
     58 
     59     mov eax, Buffer
     60     mov bl, Value
     61     mov edi, eax
     62     mov  bh, bl
     63 
     64     cmp edx, 256
     65     jb _SetRemindingByte
     66 
     67     and al, 0fh
     68     test al, al
     69     je _SetBlock
     70 
     71     mov eax, edi
     72     shr eax, 4
     73     inc eax
     74     shl eax, 4
     75     sub eax, edi
     76     cmp eax, edx
     77     jnb _SetRemindingByte
     78 
     79     sub edx, eax
     80     mov ecx, eax
     81 
     82     mov al, bl
     83     rep stosb
     84 
     85 _SetBlock:
     86     mov eax, edx
     87     shr eax, 7
     88     test eax, eax
     89     je _SetRemindingByte
     90 
     91     shl eax, 7
     92     sub edx, eax
     93     shr eax, 7
     94 
     95     mov  WORD PTR QWordValue[0], bx
     96     mov  WORD PTR QWordValue[2], bx
     97     mov  WORD PTR QWordValue[4], bx
     98     mov  WORD PTR QWordValue[6], bx
     99 
    100 
    101     movq  MmxSave, mm0
    102     movq  mm0, QWordValue
    103 
    104     movq2dq  xmm1, mm0
    105     pshufd   xmm1, xmm1, 0
    106 
    107 _Loop:
    108     movdqa  OWORD PTR ds:[edi], xmm1
    109     movdqa  OWORD PTR ds:[edi+16], xmm1
    110     movdqa  OWORD PTR ds:[edi+32], xmm1
    111     movdqa  OWORD PTR ds:[edi+48], xmm1
    112     movdqa  OWORD PTR ds:[edi+64], xmm1
    113     movdqa  OWORD PTR ds:[edi+80], xmm1
    114     movdqa  OWORD PTR ds:[edi+96], xmm1
    115     movdqa  OWORD PTR ds:[edi+112], xmm1
    116     add edi, 128
    117     dec eax
    118     jnz _Loop
    119 
    120 ; Restore mm0
    121     movq  mm0, MmxSave
    122     emms                                 ; Exit MMX Instruction
    123 
    124 _SetRemindingByte:
    125     mov ecx, edx
    126 
    127     mov eax, ebx
    128     shl eax, 16
    129     mov ax, bx
    130     shr ecx, 2
    131     rep stosd
    132 
    133     mov ecx, edx
    134     and ecx, 3
    135     rep stosb
    136 
    137     pop ebx
    138 
    139 _SetMemDone:
    140   }
    141 }
    142