diff options
10 files changed, 1026 insertions, 0 deletions
diff --git a/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/DivU64x32.asm b/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/DivU64x32.asm new file mode 100644 index 0000000000..6e5d71e009 --- /dev/null +++ b/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/DivU64x32.asm @@ -0,0 +1,82 @@ +;---------------------------------------------------------------------------
+;/*++
+;
+;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
+;
+;--*/
+
+;---------------------------------------------------------------------------
+ .386
+ .model flat,C
+ .code
+
+;---------------------------------------------------------------------------
+;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!!
+;
+;--*/
+;---------------------------------------------------------------------------
+
+DivU64x32 PROC
+ xor edx, edx ; Clear EDX
+
+ mov eax, [esp + 8] ; Put high 32 bits of 64-bit dividend in EAX
+ mov ecx, [esp + 12] ; 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, [esp + 4] ; 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, [esp + 16] ; 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
+
+DivU64x32 ENDP
+ END
diff --git a/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/EfiCopyMem.asm b/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/EfiCopyMem.asm new file mode 100644 index 0000000000..752f4627c2 --- /dev/null +++ b/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/EfiCopyMem.asm @@ -0,0 +1,200 @@ +;/*++
+;
+;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
+;
+;--*/
+
+;---------------------------------------------------------------------------
+ .686
+ .model flat,C
+ .mmx
+ .code
+
+;---------------------------------------------------------------------------
+
+;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
+;
+;--*/
+EfiCommonLibCopyMem PROC
+
+ push ebp
+ mov ebp, esp
+ push ecx ; reserve space for Scratch Local variable UINT64 MmxSave
+ push ecx
+ push esi
+ push edi
+
+ mov ecx, [ebp + 10h] ; Count
+ mov esi, [ebp + 0Ch] ; Source
+ mov edi, [ebp + 8] ; 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 to UINT64 MmxSave
+ movq [ebp - 8], 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 from MmxSave
+ movq mm0, [ebp - 8]
+ 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:
+
+ pop edi
+ pop esi
+ leave
+ ret
+EfiCommonLibCopyMem ENDP
+ END
diff --git a/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/EfiSetMem.asm b/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/EfiSetMem.asm new file mode 100644 index 0000000000..052de590d8 --- /dev/null +++ b/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/EfiSetMem.asm @@ -0,0 +1,152 @@ +;/*++
+;
+;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.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
diff --git a/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/EfiZeroMem.asm b/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/EfiZeroMem.asm new file mode 100644 index 0000000000..ea8f1ab281 --- /dev/null +++ b/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/EfiZeroMem.asm @@ -0,0 +1,135 @@ +;/*++
+;
+;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
+;
+;--*/
+;---------------------------------------------------------------------------
+ .686
+ .model flat,C
+ .mmx
+ .code
+
+;---------------------------------------------------------------------------
+;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.
+;
+;--*/
+EfiCommonLibZeroMem PROC
+; UINT64 MmxSave;
+ push ebp
+ mov ebp, esp
+ push ecx ; Reserve space for local variable MmxSave
+ push ecx
+ push edi
+
+ mov ecx, [ebp + 0Ch] ; Count
+ mov edi, [ebp + 8]; 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 [ebp - 8], mm0 ; Save mm0 to MmxSave
+
+ 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, [ebp - 8] ; Restore mm0 from 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:
+
+ pop edi
+ leave
+ ret
+EfiCommonLibZeroMem ENDP
+ END
diff --git a/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/GetPowerOfTwo.asm b/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/GetPowerOfTwo.asm new file mode 100644 index 0000000000..2d7b6de7a3 --- /dev/null +++ b/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/GetPowerOfTwo.asm @@ -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:
+;
+; GetPowerOfTwo.c
+;
+;Abstract:
+;
+; Calculates the largest integer that is both
+; a power of two and less than Input
+;
+;--*/
+;---------------------------------------------------------------------------
+ .686
+ .model flat,C
+ .code
+
+;---------------------------------------------------------------------------
+
+;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
+;
+;--*/
+GetPowerOfTow PROC
+ xor eax, eax
+ mov edx, eax
+ mov ecx, [esp + 8] ; dword ptr Input[4]
+ jecxz _F
+ bsr ecx, ecx
+ bts edx, ecx
+ jmp _Exit
+_F:
+ mov ecx, [esp + 4] ; dword ptr Input[0]
+ jecxz _Exit
+ bsr ecx, ecx
+ bts eax, ecx
+_Exit:
+
+ ret
+GetPowerOfTow ENDP
+ END
diff --git a/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/LShiftU64.asm b/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/LShiftU64.asm new file mode 100644 index 0000000000..8ee94e6324 --- /dev/null +++ b/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/LShiftU64.asm @@ -0,0 +1,80 @@ +;/*++
+;
+;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
+;
+;--*/
+;
+;---------------------------------------------------------------------------
+ .686
+ .model flat,C
+ .code
+
+;---------------------------------------------------------------------------
+;
+;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.
+;
+;--*/
+LShiftU64 PROC
+
+ mov eax, [esp + 4]; dword ptr Operand[0]
+ mov edx, [esp + 8]; 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, [esp + 0Ch]; 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:
+
+ ret
+LShiftU64 ENDP
+ END
diff --git a/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/Log2.asm b/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/Log2.asm new file mode 100644 index 0000000000..8f5f71fb98 --- /dev/null +++ b/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/Log2.asm @@ -0,0 +1,81 @@ +;/*++
+;
+;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
+;
+;--*/
+;
+;---------------------------------------------------------------------------
+ .686
+ .model flat,C
+ .code
+
+;---------------------------------------------------------------------------
+
+;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
+;
+;--*/
+Log2 PROC
+ mov ecx, 64
+
+ cmp dword ptr [esp + 4], 0 ; (UINT32 *(&Operand))
+ jne _Log2_Wend
+ cmp dword ptr [esp + 8], 0 ; (UINT32 *(&Operand)) + 1
+ jne _Log2_Wend
+ mov cl, 0FFH
+ jmp _Log2_Done
+
+_Log2_Wend:
+ dec ecx
+ cmp ecx, 32
+ jae _Log2_Higher
+ bt [esp + 4], ecx ; (UINT32 *(&Operand))
+ jmp _Log2_Bit
+
+_Log2_Higher:
+ mov eax, ecx
+ sub eax, 32
+ bt [esp + 8], eax ; (UINT32 *(&Operand)) + 1
+
+_Log2_Bit:
+ jc _Log2_Done
+ jmp _Log2_Wend
+
+_Log2_Done:
+ mov al, cl
+
+ ret
+
+ Log2 ENDP
+ END
diff --git a/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/MultU64x32.asm b/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/MultU64x32.asm new file mode 100644 index 0000000000..fa6085f8ea --- /dev/null +++ b/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/MultU64x32.asm @@ -0,0 +1,70 @@ +;/*++
+;
+;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
+;
+;--*/
+;---------------------------------------------------------------------------
+ .686
+ .model flat,C
+ .code
+
+;---------------------------------------------------------------------------
+
+;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
+;
+;--*/
+MultU64x32 PROC
+
+ mov eax, [esp + 4]; dword ptr Multiplicand[0]
+ mul dword ptr [esp + 0Ch] ; Multiplier
+ push eax
+ push edx
+ mov eax, [esp + 10h]; dword ptr Multiplicand[4]
+ mul dword ptr [esp + 14h]; 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
+
+ ret
+MultU64x32 ENDP
+ END
diff --git a/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/Power10U64.asm b/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/Power10U64.asm new file mode 100644 index 0000000000..9d33083416 --- /dev/null +++ b/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/Power10U64.asm @@ -0,0 +1,81 @@ +;/*++
+;
+;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"
+;---------------------------------------------------------------------------
+ .686
+ .model flat,C
+ .code
+
+MultU64x32 PROTO C
+;---------------------------------------------------------------------------
+;
+;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
+;
+;--*/
+Power10U64 PROC
+ push ebp
+ mov ebp, esp
+ mov eax, dword ptr [ebp + 8]; dword ptr Operand[0]
+ mov edx, dword ptr [ebp + 0Ch]; dword ptr Operand[4]
+ mov ecx, dword ptr [ebp + 10h] ;Power
+ jcxz _Power10U64_Done
+
+_Power10U64_Wend:
+ push 10
+ push [ebp + 0Ch]; dword ptr Operand[4]
+ push [ebp + 8]; dword ptr Operand[0]
+ call MultU64x32
+ add esp, 0cH
+ mov [ebp + 8] , eax; dword ptr Operand[0]
+ mov [ebp + 0Ch] , edx; dword ptr Operand[4]
+ loop _Power10U64_Wend
+
+_Power10U64_Done:
+
+ pop ebp
+ ret
+Power10U64 ENDP
+ END
diff --git a/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/RShiftU64.asm b/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/RShiftU64.asm new file mode 100644 index 0000000000..3336e93606 --- /dev/null +++ b/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/RShiftU64.asm @@ -0,0 +1,78 @@ +;/*++
+;
+;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"
+;
+;---------------------------------------------------------------------------
+ .686
+ .model flat,C
+ .code
+
+;---------------------------------------------------------------------------
+;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.
+;
+;--*/
+RShiftU64 PROC
+
+ mov eax, [esp + 4]; dword ptr Operand[0]
+ mov edx, [esp + 8]; 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, [esp + 0Ch] ; 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:
+
+ ret
+RShiftU64 ENDP
+ END
|