mirror of https://github.com/acidanthera/audk.git
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:
parent
a1cb16bd83
commit
b962b6b54d
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
Loading…
Reference in New Issue