summaryrefslogtreecommitdiff
path: root/EdkCompatibilityPkg/Foundation
diff options
context:
space:
mode:
authorqwang12 <qwang12@6f19259b-4bc3-4df7-8a09-765794883524>2008-07-21 01:49:04 +0000
committerqwang12 <qwang12@6f19259b-4bc3-4df7-8a09-765794883524>2008-07-21 01:49:04 +0000
commit478db76bbe37e93416297d37f146ba76ab296380 (patch)
tree785f3c004fe95c8fca713dbeb95a9ec11abf2a7b /EdkCompatibilityPkg/Foundation
parent22353b17c02eff5e6b24519fc8b106470fe830a7 (diff)
downloadedk2-platforms-478db76bbe37e93416297d37f146ba76ab296380.tar.xz
Inline ASM in .c file is specific to MS tool-chain. Other tool-chain (such as Intel compiler) may not support it. Add in .asm files to make these function to be built by Assembler so that they are avaliable too for other tool-chain.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@5529 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'EdkCompatibilityPkg/Foundation')
-rw-r--r--EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/DivU64x32.asm82
-rw-r--r--EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/EfiCopyMem.asm200
-rw-r--r--EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/EfiSetMem.asm152
-rw-r--r--EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/EfiZeroMem.asm135
-rw-r--r--EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/GetPowerOfTwo.asm67
-rw-r--r--EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/LShiftU64.asm80
-rw-r--r--EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/Log2.asm81
-rw-r--r--EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/MultU64x32.asm70
-rw-r--r--EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/Power10U64.asm81
-rw-r--r--EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/RShiftU64.asm78
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