]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Add in .S file for GCC tool-chain.
authorqwang12 <qwang12@6f19259b-4bc3-4df7-8a09-765794883524>
Mon, 21 Jul 2008 10:03:20 +0000 (10:03 +0000)
committerqwang12 <qwang12@6f19259b-4bc3-4df7-8a09-765794883524>
Mon, 21 Jul 2008 10:03:20 +0000 (10:03 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@5537 6f19259b-4bc3-4df7-8a09-765794883524

EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/DivU64x32.S [new file with mode: 0644]
EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/EfiCopyMem.S [new file with mode: 0644]
EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/EfiSetMem.S [new file with mode: 0644]
EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/EfiZeroMem.S [new file with mode: 0644]
EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/GetPowerOfTwo.S [new file with mode: 0644]
EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/LShiftU64.S [new file with mode: 0644]
EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/Log2.S [new file with mode: 0644]
EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/MultU64x32.S [new file with mode: 0644]
EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/Power10U64.S [new file with mode: 0644]
EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/RShiftU64.S [new file with mode: 0644]

diff --git a/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/DivU64x32.S b/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/DivU64x32.S
new file mode 100644 (file)
index 0000000..edf0dd7
--- /dev/null
@@ -0,0 +1,91 @@
+#---------------------------------------------------------------------------
+#/*++
+#
+#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 "EfiBind.h" //For ASM_PFX
+#---------------------------------------------------------------------------
+
+#---------------------------------------------------------------------------
+    .386: 
+    .code: 
+
+#---------------------------------------------------------------------------
+
+.globl ASM_PFX(DivU64x32)
+
+#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_PFX(DivU64x32):
+    pushl %ebp
+    movl %esp, %ebp
+    xorl %edx, %edx                 # Clear EDX
+
+    movl 0xC(%ebp), %eax            # Put high 32 bits of 64-bit dividend in EAX
+    movl 0x10(%ebp), %ecx           # Put 32 bits divisor in ECX
+    divl %ecx                       # Dividend   Divisor  Quoitent...Remainder
+                                    #  0:EAX  /  ECX   =  EAX      EDX   
+
+    pushl %eax                      # Push quoitent in stack
+
+    movl 8(%ebp), %eax              # Put low 32 bits of 64-bit dividend in EAX              
+    divl %ecx                       # Leave the REMAINDER in EDX as High 32-bit of new dividend
+                                    # Dividend   Divisor  Quoitent...Remainder              
+                                    #  EDX:EAX  /  ECX   =  EAX      EDX               
+
+    movl 0x14(%ebp), %ecx            # Put &REMAINDER to ecx
+
+    jecxz Label1                    # If ecx == 0, no remainder exist, return with quoitent in EDX directly 
+    movl %edx, (%ecx)               # Put EDX through REMAINDER pointer in ECX 
+
+Label1: 
+    popl %edx                       # Pop High 32-bit QUOITENT to EDX
+    popl %ebp
+
+    ret
+
diff --git a/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/EfiCopyMem.S b/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/EfiCopyMem.S
new file mode 100644 (file)
index 0000000..f71e498
--- /dev/null
@@ -0,0 +1,202 @@
+#/*++
+#
+#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 "EfiBind.h"
+#---------------------------------------------------------------------------
+    .686: 
+    #.MODEL flat,C
+    .mmx: 
+    .code: 
+
+#---------------------------------------------------------------------------
+
+.globl ASM_PFX(EfiCommonLibCopyMem)
+
+#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_PFX(EfiCommonLibCopyMem):
+
+  pushl  %ebp
+  movl   %esp, %ebp
+  pushl  %ecx # reserve space for Scratch Local variable UINT64 MmxSave
+  pushl  %ecx
+  pushl  %esi
+  pushl  %edi
+
+  movl  0x10(%ebp), %ecx  # Count
+  movl  0xC(%ebp), %esi  # Source
+  movl  8(%ebp), %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
+  movl  %esi, %eax
+  addl  %ecx, %eax                    # Source + Count
+  cmpl  %edi, %eax
+  jle   _StartByteCopy
+
+  movl  %edi, %eax
+  addl  %ecx, %eax                    # Dest + Count
+  cmpl  %esi, %eax
+  jle   _StartByteCopy
+
+  cmpl  %edi, %esi
+  je    _CopyMemDone
+  jl    _CopyOverlapped               # too bad -- overlaps
+
+  # Pick up misaligned start bytes to get destination pointer 4-byte aligned
+_StartByteCopy: 
+  cmpl  $0, %ecx
+  je    _CopyMemDone                # Count == 0, all done
+  movl  %edi, %edx
+  andb  $3, %dl                     # check lower 2 bits of address
+  testb %dl, %dl
+  je    _CopyBlocks                 # already aligned?
+
+  # Copy a byte
+  movb  (%esi), %al                 # get byte from Source
+  movb  %al, (%edi)                 # write byte to Destination
+  decl   %ecx
+  incl  %edi
+  incl  %esi
+  jmp   _StartByteCopy               # back to top of loop
+
+_CopyBlocks: 
+  # Compute how many 64-byte blocks we can clear 
+  movl  %ecx, %eax                  # get Count in eax
+  shrl  $6, %eax                    # convert to 64-byte count
+  shll  $6, %eax                    # convert back to bytes
+  subl  %eax, %ecx                  # subtract from the original count
+  shrl  $6, %eax                    # and this is how many 64-byte blocks
+
+  # If no 64-byte blocks, then skip 
+  cmpl  $0, %eax
+  je    _CopyRemainingDWords
+
+  # Save mm0 to UINT64 MmxSave
+  movq  %mm0, -8(%ebp)
+
+copymmx: 
+
+  movq  %ds:(%esi), %mm0
+  movq  %mm0, %ds:(%edi)
+  movq  %ds:8(%esi), %mm0
+  movq  %mm0, %ds:8(%edi)
+  movq  %ds:16(%esi), %mm0
+  movq  %mm0, %ds:16(%edi)
+  movq  %ds:24(%esi), %mm0
+  movq  %mm0, %ds:24(%edi)
+  movq  %ds:32(%esi), %mm0
+  movq  %mm0, %ds:32(%edi)
+  movq  %ds:40(%esi), %mm0
+  movq  %mm0, %ds:40(%edi)
+  movq  %ds:48(%esi), %mm0
+  movq  %mm0, %ds:48(%edi)
+  movq  %ds:56(%esi), %mm0
+  movq  %mm0, %ds:56(%edi)
+
+  addl  $64, %edi
+  addl  $64, %esi
+  decl  %eax
+  jnz   copymmx
+
+# Restore mm0 from MmxSave
+  movq  -8(%ebp), %mm0
+  emms                                 # Exit MMX Instruction
+
+  # Copy as many DWORDS as possible
+_CopyRemainingDWords: 
+  cmpl  $4, %ecx
+  jb    _CopyRemainingBytes
+
+  movl  (%esi), %eax                # get data from Source
+  movl  %eax, (%edi)                # write byte to Destination
+  subl  $4, %ecx                    # decrement Count
+  addl  $4, %esi                    # advance Source pointer
+  addl  $4, %edi                    # advance Destination pointer
+  jmp   _CopyRemainingDWords        # back to top
+
+_CopyRemainingBytes: 
+  cmpl  $0, %ecx
+  je    _CopyMemDone
+  movb  (%esi), %al                 # get byte from Source
+  movb  %al, (%edi)                 # write byte to Destination
+  decl   %ecx
+  incl   %esi
+  incl  %edi                     # advance Destination pointer
+  jmp   _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
+  addl  %ecx, %esi                    # Source + Count
+  decl   %esi
+  addl  %ecx, %edi                    # Dest + Count
+  decl   %edi
+
+_CopyOverlappedLoop: 
+  cmpl  $0, %ecx
+  je    _CopyMemDone
+  movb  (%esi), %al                 # get byte from Source
+  movb  %al, (%edi)                 # write byte to Destination
+  decl   %ecx
+  decl   %esi
+  decl  %edi
+  jmp   _CopyOverlappedLoop         # back to top of loop
+
+_CopyMemDone: 
+
+  popl  %edi
+  popl  %esi
+  leave
+  ret
+#EfiCommonLibCopyMem ENDP
+
diff --git a/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/EfiSetMem.S b/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/EfiSetMem.S
new file mode 100644 (file)
index 0000000..2065634
--- /dev/null
@@ -0,0 +1,158 @@
+#/*++
+#
+#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
+#
+#--*/
+#include "EfiBind.h"
+#---------------------------------------------------------------------------
+    .686: 
+    #.MODEL flat,C
+    .mmx: 
+    .code: 
+
+#---------------------------------------------------------------------------
+.globl ASM_PFX(EfiCommonLibSetMem)
+
+#VOID
+#EfiCommonLibSetMem (
+#  IN VOID   *Buffer,
+#  IN UINTN  Count,
+#  IN UINT8  Value
+#  )
+#/*++
+#
+#Input:  VOID   *Buffer - Pointer to buffer to write
+#        UINTN  Count   - Number of bytes to write
+#        UINT8  Value   - Value to write
+#
+#Output: None.
+#
+#Saves:
+#
+#Modifies:
+#
+#Description:  This function is an optimized 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.
+#
+#--*/
+ASM_PFX(EfiCommonLibSetMem):
+
+    pushl  %ebp
+    movl   %esp, %ebp
+    subl   $0x10, %esp # Reserve space for local variable UINT64 QWordValue @[ebp - 10H] & UINT64 MmxSave @[ebp - 18H]
+    pushl  %ebx
+    pushl  %edi
+
+    movl 0xC(%ebp), %edx # Count
+    testl %edx, %edx
+    je _SetMemDone
+
+    pushl %ebx
+
+    movl 8(%ebp), %eax  # Buffer
+    movb 0x10(%ebp), %bl # Value
+    movl %eax, %edi
+    movb %bl, %bh
+
+    cmpl $256, %edx
+    jb _SetRemindingByte
+
+    andb $0x7, %al
+    testb %al, %al
+    je _SetBlock
+
+    movl %edi, %eax
+    shrl $3, %eax
+    incl %eax
+    shll $3, %eax
+    subl %edi, %eax
+    cmpl %edx, %eax
+    jnb _SetRemindingByte
+
+    subl %eax, %edx
+    movl %eax, %ecx
+
+    movb %bl, %al
+    rep
+    stosb
+
+_SetBlock: 
+    movl %edx, %eax
+    shrl $6, %eax
+    testl %eax, %eax
+    je _SetRemindingByte
+
+    shll $6, %eax
+    subl %eax, %edx
+    shrl $6, %eax
+
+    movw %bx, -0x10(%ebp)            # QWordValue[0]
+    movw %bx, -0x10+2(%ebp)          # QWordValue[2]
+    movw %bx, -0x10+4(%ebp)          # QWordValue[4]
+    movw %bx, -0x10+6(%ebp)          # QWordValue[6]
+
+
+    movq  %mm0, -8(%ebp) # Save mm0 to MmxSave
+    movq  -0x10(%ebp), %mm0 # Load QWordValue to mm0
+
+_B: 
+    movq  %mm0, %ds:(%edi)
+    movq  %mm0, %ds:8(%edi)
+    movq  %mm0, %ds:16(%edi)
+    movq  %mm0, %ds:24(%edi)
+    movq  %mm0, %ds:32(%edi)
+    movq  %mm0, %ds:40(%edi)
+    movq  %mm0, %ds:48(%edi)
+    movq  %mm0, %ds:56(%edi)
+    addl $64, %edi
+    decl %eax
+    jnz _B
+
+# Restore mm0
+    movq  -8(%ebp), %mm0 # Restore MmxSave to mm0
+    emms                                 # Exit MMX Instruction
+
+_SetRemindingByte: 
+    movl %edx, %ecx
+
+    movl %ebx, %eax
+    shll $16, %eax
+    movw %bx, %ax
+    shrl $2, %ecx
+    rep
+    stosl
+
+    movl %edx, %ecx
+    andl $3, %ecx
+    rep
+    stosb
+
+    popl %ebx
+
+_SetMemDone: 
+
+    popl %edi
+    popl %ebx
+    leave
+    ret
+
+#EfiCommonLibSetMem ENDP
+
diff --git a/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/EfiZeroMem.S b/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/EfiZeroMem.S
new file mode 100644 (file)
index 0000000..e279335
--- /dev/null
@@ -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:
+#
+#  EfiZeroMem.c
+#
+#Abstract:
+#
+#  This is the code that supports IA32-optimized ZeroMem service
+#
+#--*/
+#include "EfiBind.h"
+#---------------------------------------------------------------------------
+    .686: 
+    #.MODEL flat,C
+    .mmx: 
+    .code: 
+
+#---------------------------------------------------------------------------
+.globl ASM_PFX(EfiCommonLibZeroMem)
+#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_PFX(EfiCommonLibZeroMem):
+#  UINT64 MmxSave;
+    pushl %ebp
+    movl  %esp, %ebp
+    pushl %ecx # Reserve space for local variable MmxSave
+    pushl %ecx
+    pushl %edi
+
+    movl  0xC(%ebp), %ecx  # Count
+    movl  8(%ebp), %edi # Buffer
+
+    # Pick up misaligned start bytes (get pointer 4-byte aligned)
+_StartByteZero: 
+    movl  %edi, %eax
+    andb  $3, %al                     # check lower 2 bits of address
+    testb %al, %al
+    je    _ZeroBlocks                 # already aligned?
+    cmpl  $0, %ecx
+    je    _ZeroMemDone
+
+    # Clear the byte memory location
+    movb  $0, (%edi)
+    incl   %edi
+
+    # Decrement our count
+    decl   %ecx
+    jmp   _StartByteZero        # back to top of loop
+
+_ZeroBlocks: 
+
+    # Compute how many 64-byte blocks we can clear 
+    movl  %ecx, %edx
+    shrl  $6, %ecx                    # convert to 64-byte count
+    shll  $6, %ecx                    # convert back to bytes
+    subl  %ecx, %edx                  # subtract from the original count
+    shrl  $6, %ecx                    # and this is how many 64-byte blocks
+
+    # If no 64-byte blocks, then skip 
+    cmpl   $0, %ecx
+    je    _ZeroRemaining
+
+    # Save mm0
+    movq  %mm0, -8(%ebp)  # Save mm0 to MmxSave
+
+    pxor  %mm0, %mm0        # Clear mm0
+
+_B: 
+    movq  %mm0, %ds:(%edi)
+    movq  %mm0, %ds:8(%edi)
+    movq  %mm0, %ds:16(%edi)
+    movq  %mm0, %ds:24(%edi)
+    movq  %mm0, %ds:32(%edi)
+    movq  %mm0, %ds:40(%edi)
+    movq  %mm0, %ds:48(%edi)
+    movq  %mm0, %ds:56(%edi)
+
+    addl   $64, %edi
+    decl   %ecx
+    jnz    _B
+
+# Restore mm0
+    movq  -8(%ebp), %mm0 # Restore mm0 from MmxSave
+    emms                                 # Exit MMX Instruction
+
+_ZeroRemaining: 
+    # Zero out as many DWORDS as possible
+    movl  %edx, %ecx
+    shrl  $2, %ecx
+    xorl  %eax, %eax
+
+    rep
+    stosl
+
+    # Zero out remaining as bytes
+    movl  %edx, %ecx
+    andl  $03, %ecx
+
+    rep
+    stosb
+
+_ZeroMemDone: 
+
+    popl   %edi
+    leave
+    ret
+#EfiCommonLibZeroMem ENDP
+
diff --git a/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/GetPowerOfTwo.S b/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/GetPowerOfTwo.S
new file mode 100644 (file)
index 0000000..b3ee8ee
--- /dev/null
@@ -0,0 +1,68 @@
+#/*++
+#
+#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 "EfiBind.h"
+#---------------------------------------------------------------------------
+    .686: 
+    #.MODEL flat,C
+    .code: 
+
+#---------------------------------------------------------------------------
+.globl ASM_PFX(GetPowerOfTwo)
+#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_PFX(GetPowerOfTwo):
+    xorl    %eax, %eax
+    movl    %eax, %edx
+    movl    8(%esp), %ecx  # dword ptr Input[4]
+    jecxz   _F
+    bsrl    %ecx, %ecx
+    btsl    %ecx, %edx
+    jmp     _Exit
+_F: 
+    movl    4(%esp), %ecx  # dword ptr Input[0]
+    jecxz   _Exit
+    bsrl    %ecx, %ecx
+    btsl    %ecx, %eax
+_Exit: 
+
+    ret
+#GetPowerOfTwo ENDP
+
diff --git a/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/LShiftU64.S b/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/LShiftU64.S
new file mode 100644 (file)
index 0000000..13ac202
--- /dev/null
@@ -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:
+#
+#  LShiftU64.c
+#
+#Abstract:
+#
+#  64-bit left shift function for IA-32
+#
+#--*/
+#
+#include "EfiBind.h"
+#---------------------------------------------------------------------------
+    .686: 
+    #.MODEL flat,C
+    .code: 
+
+#---------------------------------------------------------------------------
+.globl ASM_PFX(LShiftU64)
+#
+#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_PFX(LShiftU64):
+
+    movl   4(%esp), %eax # dword ptr Operand[0]
+    movl   8(%esp), %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. 
+    #
+    movl   0xC(%esp), %ecx # Count
+    andl   $63, %ecx
+    shld   %cl, %eax, %edx
+    shlb   %cl, %eax
+
+    #
+    # 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.
+    #
+    cmpl   $32, %ecx
+    jc     _LShiftU64_Done
+
+    movl   %eax, %edx
+    xorl   %eax, %eax
+
+_LShiftU64_Done: 
+
+    ret
+#LShiftU64 ENDP
+
diff --git a/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/Log2.S b/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/Log2.S
new file mode 100644 (file)
index 0000000..2451fe6
--- /dev/null
@@ -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:
+#
+#  Log2.c
+#
+#Abstract:
+#
+#  64-bit integer logarithm function for IA-32
+#
+#--*/
+#
+#---------------------------------------------------------------------------
+#include "EfiBind.h" //For ASM_PFX
+#---------------------------------------------------------------------------
+
+.globl ASM_PFX(Log2)
+
+#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_PFX(Log2):
+  movl   $64, %ecx
+
+  cmpl   $0, 4(%esp)             # (UINT32 *(&Operand))
+  jne    _Log2_Wend
+  cmpl   $0, 8(%esp)             # (UINT32 *(&Operand)) + 1
+  jne    _Log2_Wend
+  movb   $0xFF, %cl
+  jmp    _Log2_Done
+
+_Log2_Wend: 
+  decl   %ecx
+  cmpl   $32, %ecx
+  jae    _Log2_Higher
+  btl    %ecx, 4(%esp)  # (UINT32 *(&Operand))
+  jmp    _Log2_Bit
+
+_Log2_Higher: 
+  movl   %ecx, %eax
+  subl   $32, %eax
+  btl    %eax, 8(%esp)  # (UINT32 *(&Operand)) + 1
+
+_Log2_Bit: 
+  jc     _Log2_Done
+  jmp    _Log2_Wend
+
+_Log2_Done: 
+  movb   %cl, %al
+
+  ret
+
diff --git a/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/MultU64x32.S b/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/MultU64x32.S
new file mode 100644 (file)
index 0000000..1d04247
--- /dev/null
@@ -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:
+#
+#   MultU64x32.c
+#
+#Abstract:
+#
+#  64-bit Multiplication function for IA-32
+#
+#--*/
+#include "EfiBind.h"
+#---------------------------------------------------------------------------
+    .686: 
+    #.MODEL flat,C
+    .code: 
+
+#---------------------------------------------------------------------------
+.globl ASM_PFX(MultU64x32)
+#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_PFX(MultU64x32):
+
+    movl   4(%esp), %eax # dword ptr Multiplicand[0]
+    mull   0xC(%esp)             # Multiplier
+    pushl  %eax
+    pushl  %edx
+    movl   0x10(%esp), %eax # dword ptr Multiplicand[4]
+    mull   0x14(%esp)           # 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.
+    #
+    popl   %edx
+    addl   %eax, %edx
+    popl   %eax
+
+    ret
+#MultU64x32 ENDP
+
diff --git a/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/Power10U64.S b/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/Power10U64.S
new file mode 100644 (file)
index 0000000..9d4bd3b
--- /dev/null
@@ -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:
+#
+#  Power10U64.c
+#
+#Abstract:
+#
+#  Calculates Operand * 10 ^ Power
+#
+#--*/
+#
+##include "Tiano.h"
+#include "EfiBind.h"
+#---------------------------------------------------------------------------
+    .686: 
+    #.MODEL flat,C
+    .code: 
+
+.globl ASM_PFX(DivU64x32)
+#---------------------------------------------------------------------------
+#
+#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_PFX(Power10U64):
+  pushl  %ebp
+  movl   %esp, %ebp
+  movl   8(%ebp), %eax           # dword ptr Operand[0]
+  movl   0xC(%ebp), %edx           # dword ptr Operand[4]
+  movl   0x10(%ebp), %ecx           #Power
+  jcxz   _Power10U64_Done
+
+_Power10U64_Wend: 
+  pushl  $10
+  push   0xC(%ebp)
+  push   0x8(%ebp)
+  call   ASM_PFX(MultU64x32)
+  addl   $0xc, %esp
+  movl   %eax, 8(%ebp)  # dword ptr Operand[0]
+  movl   %edx, 0xC(%ebp)  # dword ptr Operand[4]
+  loopl  _Power10U64_Wend
+
+_Power10U64_Done: 
+
+  popl   %ebp
+  ret
+#Power10U64 ENDP
+
diff --git a/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/RShiftU64.S b/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/RShiftU64.S
new file mode 100644 (file)
index 0000000..7eba912
--- /dev/null
@@ -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:
+#
+#  RShiftU64.c
+#
+#Abstract:
+#
+#  64-bit right shift function for IA-32
+#
+#--*/
+#
+##include "Tiano.h"
+#
+#include "EfiBind.h"
+#---------------------------------------------------------------------------
+    .686: 
+    #.MODEL flat,C
+    .code: 
+
+#---------------------------------------------------------------------------
+.globl ASM_PFX(RShiftU64)
+#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_PFX(RShiftU64):
+
+    movl   4(%esp), %eax # dword ptr Operand[0]
+    movl   8(%esp), %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. 
+    #
+    movl   0xC(%esp), %ecx  # Count
+    andl   $63, %ecx
+    shrd   %cl, %edx, %eax
+    shrb   %cl, %edx
+
+    cmpl   $32, %ecx
+    jc     _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.
+    #
+    movl   %edx, %eax
+    xorl   %edx, %edx
+
+_RShiftU64_Done: 
+
+    ret
+#RShiftU64 ENDP
+