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
This commit is contained in:
qwang12 2008-07-21 10:03:20 +00:00
parent a1cb16bd83
commit b962b6b54d
10 changed files with 1051 additions and 0 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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