summaryrefslogtreecommitdiff
path: root/EDK/Foundation/Library/EfiCommonLib/Ia32/EfiSetMemSSE2.asm
blob: 5d6652d77638b3218fde29b1ddff4724439e86be (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
      TITLE   EfiSetMem.asm: Optimized setmemory routine

;------------------------------------------------------------------------------
;
; Copyright (c) 2004, 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:
;
;   EfiCommonLibSetMem.asm
; 
; Abstract:
; 
;   This is the code that supports IA32-optimized SetMem service
;
;------------------------------------------------------------------------------

; PROC:PRIVATE
  .686P
  .MMX
  .XMM
  .MODEL SMALL
  .CODE

EfiCommonLibSetMem  PROTO  C Buffer:PTR DWORD, Count:DWORD, Value:BYTE

;------------------------------------------------------------------------------
;  Procedure:  EfiCommonLibSetMem
;
;   VOID
;   EfiCommonLibSetMem (
;     IN VOID   *Buffer,
;     IN UINTN  Count,
;     IN UINT8  Value
;     )
;
;  Input:  VOID   *Buffer - Pointer to buffer to write
;          UINTN  Count   - Number of bytes to write
;          UINT8  Value    - Value to write
;
;  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.
;
;------------------------------------------------------------------------------
EfiCommonLibSetMem  PROC C Buffer:PTR DWORD, Count:DWORD, Value:BYTE
  LOCAL  QWordValue:QWORD
  LOCAL  MmxSave:QWORD

  
  mov edx, Count
  test edx, edx
  je _SetMemDone

  push edi
  push ebx
  
  mov eax, Buffer
  mov bl, Value
  mov edi, eax
  mov  bh, bl
  
  cmp edx, 256
  jb _SetRemindingByte
  
  and al, 0fh
  test al, al
  je _SetBlock
  
  mov eax, edi
  shr eax, 4
  inc eax
  shl eax, 4
  sub eax, edi
  cmp eax, edx
  jnb _SetRemindingByte
  
  sub edx, eax
  mov ecx, eax

  mov al, bl
  rep stosb

_SetBlock:
  mov eax, edx
  shr eax, 7
  test eax, eax
  je _SetRemindingByte

  shl eax, 7
  sub edx, eax
  shr eax, 7

  mov  WORD PTR QWordValue[0], bx
  mov  WORD PTR QWordValue[2], bx
  mov  WORD PTR QWordValue[4], bx
  mov  WORD PTR QWordValue[6], bx
 
  
  movq  MmxSave, mm0
  movq  mm0, QWordValue

  movq2dq  xmm1, mm0
  pshufd   xmm1, xmm1, 0

@@:
  movdqa  OWORD PTR ds:[edi], xmm1
  movdqa  OWORD PTR ds:[edi+16], xmm1
  movdqa  OWORD PTR ds:[edi+32], xmm1
  movdqa  OWORD PTR ds:[edi+48], xmm1
  movdqa  OWORD PTR ds:[edi+64], xmm1
  movdqa  OWORD PTR ds:[edi+80], xmm1
  movdqa  OWORD PTR ds:[edi+96], xmm1
  movdqa  OWORD PTR ds:[edi+112], xmm1
  add edi, 128
  dec eax
  jnz @B
  
; Restore mm0
  movq  mm0, MmxSave
  emms                                 ; Exit MMX Instruction
  
_SetRemindingByte:
  mov ecx, edx

  mov eax, ebx
  shl eax, 16
  mov ax, bx
  shr ecx, 2
  rep stosd
  
  mov ecx, edx
  and ecx, 3
  rep stosb
  
  pop ebx
  pop edi

_SetMemDone:
  ret 0

EfiCommonLibSetMem  ENDP
  END