Add in the 1st version of ECP.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2832 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, 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:
|
||||
|
||||
DivU64x32.c
|
||||
|
||||
Abstract:
|
||||
|
||||
64-bit division function for IA-32
|
||||
|
||||
--*/
|
||||
|
||||
#include "Tiano.h"
|
||||
|
||||
UINT64
|
||||
DivU64x32 (
|
||||
IN UINT64 Dividend,
|
||||
IN UINTN Divisor,
|
||||
OUT UINTN *Remainder OPTIONAL
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
This routine allows a 64 bit value to be divided with a 32 bit value returns
|
||||
64bit result and the Remainder.
|
||||
|
||||
Arguments:
|
||||
|
||||
Dividend - dividend
|
||||
Divisor - divisor
|
||||
Remainder - buffer for remainder
|
||||
|
||||
Returns:
|
||||
|
||||
Dividend / Divisor
|
||||
Remainder = Dividend mod Divisor
|
||||
|
||||
N.B. only works for 31bit divisors!!
|
||||
|
||||
--*/
|
||||
{
|
||||
__asm {
|
||||
xor edx, edx ; Clear EDX
|
||||
|
||||
mov eax, dword ptr Dividend[4] ; Put high 32 bits of 64-bit dividend in EAX
|
||||
mov ecx, Divisor ; Put 32 bits divisor in ECX
|
||||
div ecx ; Dividend Divisor Quoitent...Remainder
|
||||
; 0:EAX / ECX = EAX EDX
|
||||
|
||||
push eax ; Push quoitent in stack
|
||||
|
||||
mov eax, dword ptr Dividend[0] ; Put low 32 bits of 64-bit dividend in EAX
|
||||
div ecx ; Leave the REMAINDER in EDX as High 32-bit of new dividend
|
||||
; Dividend Divisor Quoitent...Remainder
|
||||
; EDX:EAX / ECX = EAX EDX
|
||||
|
||||
mov ecx, Remainder ; Put &REMAINDER to ecx
|
||||
|
||||
jecxz Label1 ; If ecx == 0, no remainder exist, return with quoitent in EDX directly
|
||||
mov dword ptr [ecx], edx ; Put EDX through REMAINDER pointer in ECX
|
||||
|
||||
Label1:
|
||||
pop edx ; Pop High 32-bit QUOITENT to EDX
|
||||
}
|
||||
}
|
@@ -0,0 +1,184 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, 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:
|
||||
|
||||
EfiCopyMem.c
|
||||
|
||||
Abstract:
|
||||
|
||||
This is the code that supports IA32-optimized CopyMem service
|
||||
|
||||
--*/
|
||||
|
||||
#include "Tiano.h"
|
||||
|
||||
VOID
|
||||
EfiCommonLibCopyMem (
|
||||
IN VOID *Destination,
|
||||
IN VOID *Source,
|
||||
IN UINTN Count
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Copy Length bytes from Source to Destination.
|
||||
|
||||
Arguments:
|
||||
|
||||
Destination - Target of copy
|
||||
|
||||
Source - Place to copy from
|
||||
|
||||
Length - Number of bytes to copy
|
||||
|
||||
Returns:
|
||||
|
||||
None
|
||||
|
||||
--*/
|
||||
{
|
||||
UINT64 MmxSave;
|
||||
__asm {
|
||||
|
||||
mov ecx, Count
|
||||
mov esi, Source
|
||||
mov edi, Destination
|
||||
|
||||
; First off, make sure we have no overlap. That is to say,
|
||||
; if (Source == Destination) => do nothing
|
||||
; if (Source + Count <= Destination) => regular copy
|
||||
; if (Destination + Count <= Source) => regular copy
|
||||
; otherwise, do a reverse copy
|
||||
mov eax, esi
|
||||
add eax, ecx ; Source + Count
|
||||
cmp eax, edi
|
||||
jle _StartByteCopy
|
||||
|
||||
mov eax, edi
|
||||
add eax, ecx ; Dest + Count
|
||||
cmp eax, esi
|
||||
jle _StartByteCopy
|
||||
|
||||
cmp esi, edi
|
||||
je _CopyMemDone
|
||||
jl _CopyOverlapped ; too bad -- overlaps
|
||||
|
||||
; Pick up misaligned start bytes to get destination pointer 4-byte aligned
|
||||
_StartByteCopy:
|
||||
cmp ecx, 0
|
||||
je _CopyMemDone ; Count == 0, all done
|
||||
mov edx, edi
|
||||
and dl, 3 ; check lower 2 bits of address
|
||||
test dl, dl
|
||||
je SHORT _CopyBlocks ; already aligned?
|
||||
|
||||
; Copy a byte
|
||||
mov al, BYTE PTR [esi] ; get byte from Source
|
||||
mov BYTE PTR [edi], al ; write byte to Destination
|
||||
dec ecx
|
||||
inc edi
|
||||
inc esi
|
||||
jmp _StartByteCopy ; back to top of loop
|
||||
|
||||
_CopyBlocks:
|
||||
; Compute how many 64-byte blocks we can clear
|
||||
mov eax, ecx ; get Count in eax
|
||||
shr eax, 6 ; convert to 64-byte count
|
||||
shl eax, 6 ; convert back to bytes
|
||||
sub ecx, eax ; subtract from the original count
|
||||
shr eax, 6 ; and this is how many 64-byte blocks
|
||||
|
||||
; If no 64-byte blocks, then skip
|
||||
cmp eax, 0
|
||||
je _CopyRemainingDWords
|
||||
|
||||
; Save mm0
|
||||
movq MmxSave, mm0
|
||||
|
||||
copymmx:
|
||||
|
||||
movq mm0, QWORD PTR ds:[esi]
|
||||
movq QWORD PTR ds:[edi], mm0
|
||||
movq mm0, QWORD PTR ds:[esi+8]
|
||||
movq QWORD PTR ds:[edi+8], mm0
|
||||
movq mm0, QWORD PTR ds:[esi+16]
|
||||
movq QWORD PTR ds:[edi+16], mm0
|
||||
movq mm0, QWORD PTR ds:[esi+24]
|
||||
movq QWORD PTR ds:[edi+24], mm0
|
||||
movq mm0, QWORD PTR ds:[esi+32]
|
||||
movq QWORD PTR ds:[edi+32], mm0
|
||||
movq mm0, QWORD PTR ds:[esi+40]
|
||||
movq QWORD PTR ds:[edi+40], mm0
|
||||
movq mm0, QWORD PTR ds:[esi+48]
|
||||
movq QWORD PTR ds:[edi+48], mm0
|
||||
movq mm0, QWORD PTR ds:[esi+56]
|
||||
movq QWORD PTR ds:[edi+56], mm0
|
||||
|
||||
add edi, 64
|
||||
add esi, 64
|
||||
dec eax
|
||||
jnz copymmx
|
||||
|
||||
; Restore mm0
|
||||
movq mm0, MmxSave
|
||||
emms ; Exit MMX Instruction
|
||||
|
||||
; Copy as many DWORDS as possible
|
||||
_CopyRemainingDWords:
|
||||
cmp ecx, 4
|
||||
jb _CopyRemainingBytes
|
||||
|
||||
mov eax, DWORD PTR [esi] ; get data from Source
|
||||
mov DWORD PTR [edi], eax ; write byte to Destination
|
||||
sub ecx, 4 ; decrement Count
|
||||
add esi, 4 ; advance Source pointer
|
||||
add edi, 4 ; advance Destination pointer
|
||||
jmp _CopyRemainingDWords ; back to top
|
||||
|
||||
_CopyRemainingBytes:
|
||||
cmp ecx, 0
|
||||
je _CopyMemDone
|
||||
mov al, BYTE PTR [esi] ; get byte from Source
|
||||
mov BYTE PTR [edi], al ; write byte to Destination
|
||||
dec ecx
|
||||
inc esi
|
||||
inc edi ; advance Destination pointer
|
||||
jmp SHORT _CopyRemainingBytes ; back to top of loop
|
||||
|
||||
;
|
||||
; We do this block if the source and destination buffers overlap. To
|
||||
; handle it, copy starting at the end of the source buffer and work
|
||||
; your way back. Since this is the atypical case, this code has not
|
||||
; been optimized, and thus simply copies bytes.
|
||||
;
|
||||
_CopyOverlapped:
|
||||
|
||||
; Move the source and destination pointers to the end of the range
|
||||
add esi, ecx ; Source + Count
|
||||
dec esi
|
||||
add edi, ecx ; Dest + Count
|
||||
dec edi
|
||||
|
||||
_CopyOverlappedLoop:
|
||||
cmp ecx, 0
|
||||
je _CopyMemDone
|
||||
mov al, BYTE PTR [esi] ; get byte from Source
|
||||
mov BYTE PTR [edi], al ; write byte to Destination
|
||||
dec ecx
|
||||
dec esi
|
||||
dec edi
|
||||
jmp _CopyOverlappedLoop ; back to top of loop
|
||||
|
||||
_CopyMemDone:
|
||||
}
|
||||
}
|
@@ -0,0 +1,169 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, 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:
|
||||
|
||||
EfiCopyMemSSE2.c
|
||||
|
||||
Abstract:
|
||||
|
||||
This is the code that supports IA32-optimized CopyMem service
|
||||
|
||||
--*/
|
||||
|
||||
#include "Tiano.h"
|
||||
|
||||
VOID
|
||||
EfiCommonLibCopyMem (
|
||||
IN VOID *Destination,
|
||||
IN VOID *Source,
|
||||
IN UINTN Count
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Copy Length bytes from Source to Destination.
|
||||
|
||||
Arguments:
|
||||
|
||||
Destination - Target of copy
|
||||
|
||||
Source - Place to copy from
|
||||
|
||||
Length - Number of bytes to copy
|
||||
|
||||
Returns:
|
||||
|
||||
None
|
||||
|
||||
--*/
|
||||
{
|
||||
__asm {
|
||||
mov ecx, Count
|
||||
mov esi, Source
|
||||
mov edi, Destination
|
||||
|
||||
; First off, make sure we have no overlap. That is to say,
|
||||
; if (Source == Destination) => do nothing
|
||||
; if (Source + Count <= Destination) => regular copy
|
||||
; if (Destination + Count <= Source) => regular copy
|
||||
; otherwise, do a reverse copy
|
||||
mov eax, esi
|
||||
add eax, ecx ; Source + Count
|
||||
cmp eax, edi
|
||||
jle _StartByteCopy
|
||||
|
||||
mov eax, edi
|
||||
add eax, ecx ; Dest + Count
|
||||
cmp eax, esi
|
||||
jle _StartByteCopy
|
||||
|
||||
cmp esi, edi
|
||||
je _CopyMemDone
|
||||
jl _CopyOverlapped ; too bad -- overlaps
|
||||
|
||||
; Pick up misaligned start bytes to get destination pointer 4-byte aligned
|
||||
_StartByteCopy:
|
||||
cmp ecx, 0
|
||||
je _CopyMemDone ; Count == 0, all done
|
||||
mov edx, edi
|
||||
and dl, 3 ; check lower 2 bits of address
|
||||
test dl, dl
|
||||
je SHORT _CopyBlocks ; already aligned?
|
||||
|
||||
; Copy a byte
|
||||
mov al, BYTE PTR [esi] ; get byte from Source
|
||||
mov BYTE PTR [edi], al ; write byte to Destination
|
||||
dec ecx
|
||||
inc edi
|
||||
inc esi
|
||||
jmp _StartByteCopy ; back to top of loop
|
||||
|
||||
_CopyBlocks:
|
||||
; Compute how many 64-byte blocks we can clear
|
||||
mov eax, ecx ; get Count in eax
|
||||
shr eax, 6 ; convert to 64-byte count
|
||||
shl eax, 6 ; convert back to bytes
|
||||
sub ecx, eax ; subtract from the original count
|
||||
shr eax, 6 ; and this is how many 64-byte blocks
|
||||
|
||||
; If no 64-byte blocks, then skip
|
||||
cmp eax, 0
|
||||
je _CopyRemainingDWords
|
||||
|
||||
|
||||
copyxmm:
|
||||
|
||||
movdqu xmm0, OWORD PTR ds:[esi]
|
||||
movdqu QWORD PTR ds:[edi], xmm0
|
||||
movdqu xmm1, OWORD PTR ds:[esi+16]
|
||||
movdqu QWORD PTR ds:[edi+16], xmm1
|
||||
movdqu xmm2, OWORD PTR ds:[esi+32]
|
||||
movdqu QWORD PTR ds:[edi+32], xmm2
|
||||
movdqu xmm3, OWORD PTR ds:[esi+48]
|
||||
movdqu QWORD PTR ds:[edi+48], xmm3
|
||||
|
||||
add edi, 64
|
||||
add esi, 64
|
||||
dec eax
|
||||
jnz copyxmm
|
||||
|
||||
|
||||
; Copy as many DWORDS as possible
|
||||
_CopyRemainingDWords:
|
||||
cmp ecx, 4
|
||||
jb _CopyRemainingBytes
|
||||
|
||||
mov eax, DWORD PTR [esi] ; get data from Source
|
||||
mov DWORD PTR [edi], eax ; write byte to Destination
|
||||
sub ecx, 4 ; decrement Count
|
||||
add esi, 4 ; advance Source pointer
|
||||
add edi, 4 ; advance Destination pointer
|
||||
jmp _CopyRemainingDWords ; back to top
|
||||
|
||||
_CopyRemainingBytes:
|
||||
cmp ecx, 0
|
||||
je _CopyMemDone
|
||||
mov al, BYTE PTR [esi] ; get byte from Source
|
||||
mov BYTE PTR [edi], al ; write byte to Destination
|
||||
dec ecx
|
||||
inc esi
|
||||
inc edi ; advance Destination pointer
|
||||
jmp SHORT _CopyRemainingBytes ; back to top of loop
|
||||
|
||||
;
|
||||
; We do this block if the source and destination buffers overlap. To
|
||||
; handle it, copy starting at the end of the source buffer and work
|
||||
; your way back. Since this is the atypical case, this code has not
|
||||
; been optimized, and thus simply copies bytes.
|
||||
;
|
||||
_CopyOverlapped:
|
||||
|
||||
; Move the source and destination pointers to the end of the range
|
||||
add esi, ecx ; Source + Count
|
||||
dec esi
|
||||
add edi, ecx ; Dest + Count
|
||||
dec edi
|
||||
|
||||
_CopyOverlappedLoop:
|
||||
cmp ecx, 0
|
||||
je _CopyMemDone
|
||||
mov al, BYTE PTR [esi] ; get byte from Source
|
||||
mov BYTE PTR [edi], al ; write byte to Destination
|
||||
dec ecx
|
||||
dec esi
|
||||
dec edi
|
||||
jmp _CopyOverlappedLoop ; back to top of loop
|
||||
|
||||
_CopyMemDone:
|
||||
}
|
||||
}
|
@@ -0,0 +1,139 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, 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:
|
||||
|
||||
EfiSetMem.c
|
||||
|
||||
Abstract:
|
||||
|
||||
This is the code that supports IA32-optimized SetMem service
|
||||
|
||||
--*/
|
||||
|
||||
#include "Tiano.h"
|
||||
|
||||
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.
|
||||
|
||||
--*/
|
||||
{
|
||||
UINT64 QWordValue;
|
||||
UINT64 MmxSave;
|
||||
__asm {
|
||||
mov edx, Count
|
||||
test edx, edx
|
||||
je _SetMemDone
|
||||
|
||||
push ebx
|
||||
|
||||
mov eax, Buffer
|
||||
mov bl, 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 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
|
||||
|
||||
_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, 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
|
||||
|
||||
_SetMemDone:
|
||||
|
||||
}
|
||||
}
|
@@ -0,0 +1,141 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, 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:
|
||||
|
||||
EfiSetMemSSE2.c
|
||||
|
||||
Abstract:
|
||||
|
||||
This is the code that supports IA32-optimized SetMem service
|
||||
|
||||
--*/
|
||||
|
||||
#include "Tiano.h"
|
||||
|
||||
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.
|
||||
|
||||
--*/
|
||||
{
|
||||
UINT64 QWordValue;
|
||||
UINT64 MmxSave;
|
||||
__asm {
|
||||
mov edx, Count
|
||||
test edx, edx
|
||||
je _SetMemDone
|
||||
|
||||
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
|
||||
|
||||
_Loop:
|
||||
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 _Loop
|
||||
|
||||
; 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
|
||||
|
||||
_SetMemDone:
|
||||
}
|
||||
}
|
@@ -0,0 +1,122 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, 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:
|
||||
|
||||
EfiZeroMem.c
|
||||
|
||||
Abstract:
|
||||
|
||||
This is the code that supports IA32-optimized ZeroMem service
|
||||
|
||||
--*/
|
||||
|
||||
#include "Tiano.h"
|
||||
|
||||
VOID
|
||||
EfiCommonLibZeroMem (
|
||||
IN VOID *Buffer,
|
||||
IN UINTN Count
|
||||
)
|
||||
/*++
|
||||
|
||||
Input: VOID *Buffer - Pointer to buffer to clear
|
||||
UINTN Count - Number of bytes to clear
|
||||
|
||||
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.
|
||||
|
||||
--*/
|
||||
{
|
||||
UINT64 MmxSave;
|
||||
__asm {
|
||||
mov ecx, Count
|
||||
mov edi, Buffer
|
||||
|
||||
; Pick up misaligned start bytes (get pointer 4-byte aligned)
|
||||
_StartByteZero:
|
||||
mov eax, edi
|
||||
and al, 3 ; check lower 2 bits of address
|
||||
test al, al
|
||||
je _ZeroBlocks ; already aligned?
|
||||
cmp ecx, 0
|
||||
je _ZeroMemDone
|
||||
|
||||
; Clear the byte memory location
|
||||
mov BYTE PTR [edi], 0
|
||||
inc edi
|
||||
|
||||
; Decrement our count
|
||||
dec ecx
|
||||
jmp _StartByteZero ; back to top of loop
|
||||
|
||||
_ZeroBlocks:
|
||||
|
||||
; Compute how many 64-byte blocks we can clear
|
||||
mov edx, ecx
|
||||
shr ecx, 6 ; convert to 64-byte count
|
||||
shl ecx, 6 ; convert back to bytes
|
||||
sub edx, ecx ; subtract from the original count
|
||||
shr ecx, 6 ; and this is how many 64-byte blocks
|
||||
|
||||
; If no 64-byte blocks, then skip
|
||||
cmp ecx, 0
|
||||
je _ZeroRemaining
|
||||
|
||||
; Save mm0
|
||||
movq MmxSave, mm0
|
||||
|
||||
pxor mm0, mm0 ; Clear 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 ecx
|
||||
jnz _B
|
||||
|
||||
; Restore mm0
|
||||
movq mm0, MmxSave
|
||||
emms ; Exit MMX Instruction
|
||||
|
||||
_ZeroRemaining:
|
||||
; Zero out as many DWORDS as possible
|
||||
mov ecx, edx
|
||||
shr ecx, 2
|
||||
xor eax, eax
|
||||
|
||||
rep stosd
|
||||
|
||||
; Zero out remaining as bytes
|
||||
mov ecx, edx
|
||||
and ecx, 03
|
||||
|
||||
rep stosb
|
||||
|
||||
_ZeroMemDone:
|
||||
}
|
||||
}
|
@@ -0,0 +1,111 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, 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:
|
||||
|
||||
EfiZeroMemSSE2.c
|
||||
|
||||
Abstract:
|
||||
|
||||
This is the code that supports IA32-optimized ZeroMem service
|
||||
|
||||
--*/
|
||||
|
||||
#include "Tiano.h"
|
||||
|
||||
VOID
|
||||
EfiCommonLibZeroMem (
|
||||
IN VOID *Buffer,
|
||||
IN UINTN Count
|
||||
)
|
||||
/*++
|
||||
|
||||
Input: VOID *Buffer - Pointer to buffer to clear
|
||||
UINTN Count - Number of bytes to clear
|
||||
|
||||
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.
|
||||
|
||||
--*/
|
||||
{
|
||||
__asm {
|
||||
mov ecx, Count
|
||||
mov edi, Buffer
|
||||
|
||||
; Pick up misaligned start bytes (get pointer 4-byte aligned)
|
||||
_StartByteZero:
|
||||
mov eax, edi
|
||||
and al, 3 ; check lower 2 bits of address
|
||||
test al, al
|
||||
je _ZeroBlocks ; already aligned?
|
||||
cmp ecx, 0
|
||||
je _ZeroMemDone
|
||||
|
||||
; Clear the byte memory location
|
||||
mov BYTE PTR [edi], 0
|
||||
inc edi
|
||||
|
||||
; Decrement our count
|
||||
dec ecx
|
||||
jmp _StartByteZero ; back to top of loop
|
||||
|
||||
_ZeroBlocks:
|
||||
|
||||
; Compute how many 64-byte blocks we can clear
|
||||
mov edx, ecx
|
||||
shr ecx, 6 ; convert to 64-byte count
|
||||
shl ecx, 6 ; convert back to bytes
|
||||
sub edx, ecx ; subtract from the original count
|
||||
shr ecx, 6 ; and this is how many 64-byte blocks
|
||||
|
||||
; If no 64-byte blocks, then skip
|
||||
cmp ecx, 0
|
||||
je _ZeroRemaining
|
||||
|
||||
xorps xmm1, xmm1
|
||||
|
||||
_B:
|
||||
movdqu OWORD PTR ds:[edi], xmm1
|
||||
movdqu OWORD PTR ds:[edi+16], xmm1
|
||||
movdqu OWORD PTR ds:[edi+32], xmm1
|
||||
movdqu OWORD PTR ds:[edi+48], xmm1
|
||||
|
||||
add edi, 64
|
||||
dec ecx
|
||||
jnz _B
|
||||
|
||||
|
||||
_ZeroRemaining:
|
||||
; Zero out as many DWORDS as possible
|
||||
mov ecx, edx
|
||||
shr ecx, 2
|
||||
xor eax, eax
|
||||
|
||||
rep stosd
|
||||
|
||||
; Zero out remaining as bytes
|
||||
mov ecx, edx
|
||||
and ecx, 03
|
||||
|
||||
rep stosb
|
||||
|
||||
_ZeroMemDone:
|
||||
}
|
||||
}
|
@@ -0,0 +1,62 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, 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:
|
||||
|
||||
GetPowerOfTwo.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Calculates the largest integer that is both
|
||||
a power of two and less than Input
|
||||
|
||||
--*/
|
||||
|
||||
#include "Tiano.h"
|
||||
|
||||
UINT64
|
||||
GetPowerOfTwo (
|
||||
IN UINT64 Input
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Calculates the largest integer that is both
|
||||
a power of two and less than Input
|
||||
|
||||
Arguments:
|
||||
|
||||
Input - value to calculate power of two
|
||||
|
||||
Returns:
|
||||
|
||||
the largest integer that is both a power of
|
||||
two and less than Input
|
||||
|
||||
--*/
|
||||
{
|
||||
__asm {
|
||||
xor eax, eax
|
||||
mov edx, eax
|
||||
mov ecx, dword ptr Input[4]
|
||||
jecxz _F
|
||||
bsr ecx, ecx
|
||||
bts edx, ecx
|
||||
jmp _Exit
|
||||
_F:
|
||||
mov ecx, dword ptr Input[0]
|
||||
jecxz _Exit
|
||||
bsr ecx, ecx
|
||||
bts eax, ecx
|
||||
_Exit:
|
||||
}
|
||||
}
|
@@ -0,0 +1,74 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, 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:
|
||||
|
||||
LShiftU64.c
|
||||
|
||||
Abstract:
|
||||
|
||||
64-bit left shift function for IA-32
|
||||
|
||||
--*/
|
||||
|
||||
#include "Tiano.h"
|
||||
|
||||
UINT64
|
||||
LShiftU64 (
|
||||
IN UINT64 Operand,
|
||||
IN UINTN Count
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
This routine allows a 64 bit value to be left shifted by 32 bits and
|
||||
returns the shifted value.
|
||||
Count is valid up 63. (Only Bits 0-5 is valid for Count)
|
||||
|
||||
Arguments:
|
||||
|
||||
Operand - Value to be shifted
|
||||
Count - Number of times to shift left.
|
||||
|
||||
Returns:
|
||||
|
||||
Value shifted left identified by the Count.
|
||||
|
||||
--*/
|
||||
{
|
||||
__asm {
|
||||
|
||||
mov eax, dword ptr Operand[0]
|
||||
mov edx, dword ptr Operand[4]
|
||||
|
||||
;
|
||||
; CL is valid from 0 - 31. shld will move EDX:EAX by CL times but EAX is not touched
|
||||
; For CL of 32 - 63, it will be shifted 0 - 31 so we will move eax to edx later.
|
||||
;
|
||||
mov ecx, Count
|
||||
and ecx, 63
|
||||
shld edx, eax, cl
|
||||
shl eax, cl
|
||||
|
||||
;
|
||||
; Since Count is 32 - 63, eax will have been shifted by 0 - 31
|
||||
; If shifted by 32 or more, set lower 32 bits to zero.
|
||||
;
|
||||
cmp ecx, 32
|
||||
jc short _LShiftU64_Done
|
||||
|
||||
mov edx, eax
|
||||
xor eax, eax
|
||||
|
||||
_LShiftU64_Done:
|
||||
}
|
||||
}
|
@@ -0,0 +1,74 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, 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:
|
||||
|
||||
Log2.c
|
||||
|
||||
Abstract:
|
||||
|
||||
64-bit integer logarithm function for IA-32
|
||||
|
||||
--*/
|
||||
|
||||
#include "Tiano.h"
|
||||
|
||||
UINT8
|
||||
Log2 (
|
||||
IN UINT64 Operand
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Calculates and floors logarithms based on 2
|
||||
|
||||
Arguments:
|
||||
|
||||
Operand - value to calculate logarithm
|
||||
|
||||
Returns:
|
||||
|
||||
The largest integer that is less than or equal
|
||||
to the logarithm of Operand based on 2
|
||||
|
||||
--*/
|
||||
{
|
||||
__asm {
|
||||
mov ecx, 64
|
||||
|
||||
cmp dword ptr Operand[0], 0
|
||||
jne _Log2_Wend
|
||||
cmp dword ptr Operand[4], 0
|
||||
jne _Log2_Wend
|
||||
mov cl, 0FFH
|
||||
jmp _Log2_Done
|
||||
|
||||
_Log2_Wend:
|
||||
dec ecx
|
||||
cmp ecx, 32
|
||||
jae _Log2_Higher
|
||||
bt dword ptr Operand[0], ecx
|
||||
jmp _Log2_Bit
|
||||
|
||||
_Log2_Higher:
|
||||
mov eax, ecx
|
||||
sub eax, 32
|
||||
bt dword ptr Operand[4], eax
|
||||
|
||||
_Log2_Bit:
|
||||
jc _Log2_Done
|
||||
jmp _Log2_Wend
|
||||
|
||||
_Log2_Done:
|
||||
mov al, cl
|
||||
}
|
||||
}
|
@@ -0,0 +1,64 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, 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:
|
||||
|
||||
MultU64x32.c
|
||||
|
||||
Abstract:
|
||||
|
||||
64-bit Multiplication function for IA-32
|
||||
|
||||
--*/
|
||||
|
||||
#include "Tiano.h"
|
||||
|
||||
UINT64
|
||||
MultU64x32 (
|
||||
IN UINT64 Multiplicand,
|
||||
IN UINTN Multiplier
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
This routine allows a 64 bit value to be multiplied with a 32 bit
|
||||
value returns 64bit result.
|
||||
No checking if the result is greater than 64bits
|
||||
|
||||
Arguments:
|
||||
|
||||
Multiplicand - multiplicand
|
||||
Multiplier - multiplier
|
||||
|
||||
Returns:
|
||||
|
||||
Multiplicand * Multiplier
|
||||
|
||||
--*/
|
||||
{
|
||||
__asm {
|
||||
mov eax, dword ptr Multiplicand[0]
|
||||
mul Multiplier
|
||||
push eax
|
||||
push edx
|
||||
mov eax, dword ptr Multiplicand[4]
|
||||
mul Multiplier
|
||||
;
|
||||
; The value in edx stored by second multiplication overflows
|
||||
; the output and should be discarded. So here we overwrite it
|
||||
; with the edx value of first multiplication.
|
||||
;
|
||||
pop edx
|
||||
add edx, eax
|
||||
pop eax
|
||||
}
|
||||
}
|
@@ -0,0 +1,67 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, 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:
|
||||
|
||||
Power10U64.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Calculates Operand * 10 ^ Power
|
||||
|
||||
--*/
|
||||
|
||||
#include "Tiano.h"
|
||||
|
||||
UINT64
|
||||
MultU64x32 (
|
||||
IN UINT64 Multiplicand,
|
||||
IN UINTN Multiplier
|
||||
);
|
||||
|
||||
UINT64
|
||||
Power10U64 (
|
||||
IN UINT64 Operand,
|
||||
IN UINTN Power
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Raise 10 to the power of Power, and multiply the result with Operand
|
||||
|
||||
Arguments:
|
||||
|
||||
Operand - multiplicand
|
||||
Power - power
|
||||
|
||||
Returns:
|
||||
|
||||
Operand * 10 ^ Power
|
||||
|
||||
--*/
|
||||
{
|
||||
__asm {
|
||||
mov ecx, Power
|
||||
jcxz _Power10U64_Done
|
||||
|
||||
_Power10U64_Wend:
|
||||
push 10
|
||||
push dword ptr Operand[4]
|
||||
push dword ptr Operand[0]
|
||||
call MultU64x32
|
||||
mov dword ptr Operand[0], eax
|
||||
mov dword ptr Operand[4], edx
|
||||
loop _Power10U64_Wend
|
||||
|
||||
_Power10U64_Done:
|
||||
}
|
||||
}
|
@@ -0,0 +1,71 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, 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:
|
||||
|
||||
RShiftU64.c
|
||||
|
||||
Abstract:
|
||||
|
||||
64-bit right shift function for IA-32
|
||||
|
||||
--*/
|
||||
|
||||
#include "Tiano.h"
|
||||
|
||||
UINT64
|
||||
RShiftU64 (
|
||||
IN UINT64 Operand,
|
||||
IN UINTN Count
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This routine allows a 64 bit value to be right shifted by 32 bits and returns the
|
||||
shifted value.
|
||||
Count is valid up 63. (Only Bits 0-5 is valid for Count)
|
||||
Arguments:
|
||||
Operand - Value to be shifted
|
||||
Count - Number of times to shift right.
|
||||
|
||||
Returns:
|
||||
|
||||
Value shifted right identified by the Count.
|
||||
|
||||
--*/
|
||||
{
|
||||
__asm {
|
||||
|
||||
mov eax, dword ptr Operand[0]
|
||||
mov edx, dword ptr Operand[4]
|
||||
|
||||
;
|
||||
; CL is valid from 0 - 31. shld will move EDX:EAX by CL times but EDX is not touched
|
||||
; For CL of 32 - 63, it will be shifted 0 - 31 so we will move edx to eax later.
|
||||
;
|
||||
mov ecx, Count
|
||||
and ecx, 63
|
||||
shrd eax, edx, cl
|
||||
shr edx, cl
|
||||
|
||||
cmp ecx, 32
|
||||
jc short _RShiftU64_Done
|
||||
|
||||
;
|
||||
; Since Count is 32 - 63, edx will have been shifted by 0 - 31
|
||||
; If shifted by 32 or more, set upper 32 bits to zero.
|
||||
;
|
||||
mov eax, edx
|
||||
xor edx, edx
|
||||
|
||||
_RShiftU64_Done:
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user