diff options
author | qwang12 <qwang12@6f19259b-4bc3-4df7-8a09-765794883524> | 2008-07-21 10:03:20 +0000 |
---|---|---|
committer | qwang12 <qwang12@6f19259b-4bc3-4df7-8a09-765794883524> | 2008-07-21 10:03:20 +0000 |
commit | b962b6b54d90ef655c2567712e6cfe00bc3c3450 (patch) | |
tree | b096de4a6d004201fb54ed96d8b26614140bcf96 | |
parent | a1cb16bd836fca1363c9e3a5218348615d39fcbb (diff) | |
download | edk2-platforms-b962b6b54d90ef655c2567712e6cfe00bc3c3450.tar.xz |
Add in .S file for GCC tool-chain.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@5537 6f19259b-4bc3-4df7-8a09-765794883524
10 files changed, 1051 insertions, 0 deletions
diff --git a/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/DivU64x32.S b/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/DivU64x32.S new file mode 100644 index 0000000000..edf0dd7042 --- /dev/null +++ b/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/DivU64x32.S @@ -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 index 0000000000..f71e498929 --- /dev/null +++ b/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/EfiCopyMem.S @@ -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 index 0000000000..206563438b --- /dev/null +++ b/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/EfiSetMem.S @@ -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 index 0000000000..e279335499 --- /dev/null +++ b/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/EfiZeroMem.S @@ -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 index 0000000000..b3ee8ee126 --- /dev/null +++ b/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/GetPowerOfTwo.S @@ -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 index 0000000000..13ac2026f9 --- /dev/null +++ b/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/LShiftU64.S @@ -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 index 0000000000..2451fe6700 --- /dev/null +++ b/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/Log2.S @@ -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 index 0000000000..1d04247001 --- /dev/null +++ b/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/MultU64x32.S @@ -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 index 0000000000..9d4bd3bee1 --- /dev/null +++ b/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/Power10U64.S @@ -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 index 0000000000..7eba91298a --- /dev/null +++ b/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/Ia32/RShiftU64.S @@ -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 + |