summaryrefslogtreecommitdiff
path: root/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/EfiSetMem.asm
blob: cf1657bafe6b64acf2c7f796c364e99a5c6f3912 (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
;/*++
;
;Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
;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:
;
;  EfiSetMem.asm
;
;Abstract:
;
;  This is the code that supports IA32-optimized SetMem service
;
;--*/
;---------------------------------------------------------------------------
    .686
    .model  flat,C
    .mmx
    .code

;---------------------------------------------------------------------------
;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 set-memory function.
;
;Notes:  This function tries to set 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

    push   ebp
    mov    ebp, esp
    sub    esp, 10h; Reserve space for local variable UINT64 QWordValue @[ebp - 10H] & UINT64 MmxSave @[ebp - 18H]
    push   ebx
    push   edi

    mov edx, [ebp + 0Ch] ; Count
    test edx, edx
    je _SetMemDone

    push ebx
  
    mov eax, [ebp + 8]  ; Buffer
    mov bl, [ebp + 10h] ; Value
    mov edi, eax
    mov bh, bl
  
    cmp edx, 256
    jb _SetRemindingByte
  
    and al, 07h
    test al, al
    je _SetBlock
  
    mov eax, edi
    shr eax, 3
    inc eax
    shl eax, 3
    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, 6
    test eax, eax
    je _SetRemindingByte

    shl eax, 6
    sub edx, eax
    shr eax, 6

    mov WORD PTR [ebp - 10H],     bx ; QWordValue[0]
    mov WORD PTR [ebp - 10H + 2], bx ; QWordValue[2]
    mov WORD PTR [ebp - 10H + 4], bx ; QWordValue[4]
    mov WORD PTR [ebp - 10H + 6], bx ; QWordValue[6]
 
  
    movq  [ebp - 8], mm0 ; Save mm0 to MmxSave
    movq  mm0, [ebp - 10H] ; Load QWordValue to mm0

_B:
    movq  QWORD PTR ds:[edi], mm0
    movq  QWORD PTR ds:[edi+8], mm0
    movq  QWORD PTR ds:[edi+16], mm0
    movq  QWORD PTR ds:[edi+24], mm0
    movq  QWORD PTR ds:[edi+32], mm0
    movq  QWORD PTR ds:[edi+40], mm0
    movq  QWORD PTR ds:[edi+48], mm0
    movq  QWORD PTR ds:[edi+56], mm0
    add edi, 64
    dec eax
    jnz _B
  
; Restore mm0
    movq  mm0, [ebp - 8] ; Restore MmxSave to mm0
    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

_SetMemDone:

    pop edi
    pop ebx
    leave
    ret

EfiCommonLibSetMem ENDP
	END