Ported the EBC driver to use the MDE Base Math lib functions. Removed math functions from EBC driver. Need to check to see if MDE Math lib ASSERT behavior will cause any issues with EBC driver?

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@1814 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
ajfish
2006-10-22 08:15:46 +00:00
parent 1babed138f
commit 6d7338ae38
9 changed files with 84 additions and 2055 deletions

View File

@@ -1,303 +0,0 @@
#------------------------------------------------------------------------------
#
# 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:
#
# Ia32math.S
#
# Abstract:
#
# Generic math routines for EBC interpreter running on IA32 processor
#
#------------------------------------------------------------------------------
.globl _LeftShiftU64
_LeftShiftU64:
push %ebp
mov %esp,%ebp
push %ecx
cmpl $0x0,0x14(%ebp)
jne _LeftShiftU64+0x12
mov 0x10(%ebp),%ecx
cmp $0x3f,%ecx
jbe _LeftShiftU64+0x18
xor %eax,%eax
xor %edx,%edx
jmp _LeftShiftU64+0x2c
mov 0x8(%ebp),%eax
mov 0xc(%ebp),%edx
shld %cl,%eax,%edx
shl %cl,%eax
cmp $0x20,%ecx
jb _LeftShiftU64+0x2c
mov %eax,%edx
xor %eax,%eax
pop %ecx
leave
ret
.globl _RightShiftU64
_RightShiftU64:
push %ebp
mov %esp,%ebp
push %ecx
cmpl $0x0,0x14(%ebp)
jne _RightShiftU64+0x12
mov 0x10(%ebp),%ecx
cmp $0x3f,%ecx
jbe _RightShiftU64+0x18
xor %eax,%eax
xor %edx,%edx
jmp _RightShiftU64+0x2c
mov 0x8(%ebp),%eax
mov 0xc(%ebp),%edx
shrd %cl,%edx,%eax
shr %cl,%edx
cmp $0x20,%ecx
jb _RightShiftU64+0x2c
mov %edx,%eax
xor %edx,%edx
pop %ecx
leave
ret
.globl _ARightShift64
_ARightShift64:
push %ebp
mov %esp,%ebp
push %ecx
cmpl $0x0,0x14(%ebp)
jne _ARightShift64+0x12
mov 0x10(%ebp),%ecx
cmp $0x3f,%ecx
jbe _ARightShift64+0x27
btl $0x1f,0xc(%ebp)
jae _ARightShift64+0x21
or $0xffffffff,%eax
or $0xffffffff,%edx
jmp _ARightShift64+0x3c
xor %eax,%eax
xor %edx,%edx
jmp _ARightShift64+0x3c
mov 0x8(%ebp),%eax
mov 0xc(%ebp),%edx
shrd %cl,%edx,%eax
sar %cl,%edx
cmp $0x20,%ecx
jb _ARightShift64+0x3c
mov %edx,%eax
sar $0x1f,%edx
pop %ecx
leave
ret
.globl _MulU64x64
_MulU64x64:
push %ebp
mov %esp,%ebp
push %ebx
push %ecx
mov 0x18(%ebp),%ebx
mov 0x8(%ebp),%eax
mull 0x10(%ebp)
push %eax
mov %edx,%ecx
mov 0xc(%ebp),%eax
mull 0x10(%ebp)
add %eax,%ecx
adc $0x0,%edx
mov %edx,(%ebx)
mov 0x8(%ebp),%eax
mull 0x14(%ebp)
add %eax,%ecx
push %ecx
adc $0x0,%edx
mov %edx,%ecx
mov 0xc(%ebp),%eax
mull 0x14(%ebp)
add %eax,%ecx
adc $0x0,%edx
add %ecx,(%ebx)
adc $0x0,%edx
mov %edx,0x4(%ebx)
pop %edx
pop %eax
pop %ecx
pop %ebx
leave
ret
.globl _MulS64x64
_MulS64x64:
push %ebp
mov %esp,%ebp
push %ebx
push %ecx
mov 0x18(%ebp),%ebx
xor %ecx,%ecx
mov 0xc(%ebp),%edx
bt $0x1f,%edx
jae _MulS64x64+0x2a
mov 0x8(%ebp),%eax
not %edx
not %eax
add $0x1,%eax
adc $0x0,%edx
mov %eax,0x8(%ebp)
mov %edx,0xc(%ebp)
btc $0x0,%ecx
mov 0x14(%ebp),%edx
bt $0x1f,%edx
jae _MulS64x64+0x4a
mov 0x10(%ebp),%eax
not %edx
not %eax
add $0x1,%eax
adc $0x0,%edx
mov %eax,0x10(%ebp)
mov %edx,0x14(%ebp)
btc $0x0,%ecx
pushl 0x18(%ebp)
pushl 0x14(%ebp)
pushl 0x10(%ebp)
pushl 0xc(%ebp)
pushl 0x8(%ebp)
call _MulU64x64
add $0x14,%esp
bt $0x0,%ecx
jae _MulS64x64+0x7d
not %eax
not %edx
notl (%ebx)
notl 0x4(%ebx)
add $0x1,%eax
adc $0x0,%edx
adcl $0x0,(%ebx)
adcl $0x0,0x4(%ebx)
pop %ecx
pop %ebx
leave
ret
.globl _DivU64x64
_DivU64x64:
push %ebp
mov %esp,%ebp
push %ecx
mov 0x1c(%ebp),%eax
movl $0x0,(%eax)
cmpl $0x0,0x10(%ebp)
jne _DivU64x64+0x3e
cmpl $0x0,0x14(%ebp)
jne _DivU64x64+0x3e
movl $0x1,(%eax)
cmpl $0x0,0x18(%ebp)
je _DivU64x64+0x35
mov 0x18(%ebp),%eax
movl $0x0,(%eax)
movl $0x80000000,0x4(%eax)
xor %eax,%eax
mov $0x80000000,%edx
jmp _DivU64x64+0x7e
xor %edx,%edx
xor %eax,%eax
mov $0x40,%ecx
shll 0x8(%ebp)
rcll 0xc(%ebp)
rcl %eax
rcl %edx
cmp 0x14(%ebp),%edx
ja _DivU64x64+0x5d
jb _DivU64x64+0x68
cmp 0x10(%ebp),%eax
jb _DivU64x64+0x68
btsl $0x0,0x8(%ebp)
sub 0x10(%ebp),%eax
sbb 0x14(%ebp),%edx
loop _DivU64x64+0x47
cmpl $0x0,0x18(%ebp)
je _DivU64x64+0x78
mov 0x18(%ebp),%ecx
mov %eax,(%ecx)
mov %edx,0x4(%ecx)
mov 0x8(%ebp),%eax
mov 0xc(%ebp),%edx
pop %ecx
leave
ret
.globl _DivS64x64
_DivS64x64:
push %ebp
mov %esp,%ebp
push %ecx
mov 0x1c(%ebp),%eax
movl $0x0,(%eax)
cmpl $0x0,0x10(%ebp)
jne _DivS64x64+0x41
cmpl $0x0,0x14(%ebp)
jne _DivS64x64+0x41
movl $0x1,(%eax)
cmpl $0x0,0x18(%ebp)
je _DivS64x64+0x35
mov 0x18(%ebp),%eax
movl $0x0,(%eax)
movl $0x80000000,0x4(%eax)
xor %eax,%eax
mov $0x80000000,%edx
jmp _DivS64x64+0xc6
xor %ecx,%ecx
mov 0xc(%ebp),%edx
bt $0x1f,%edx
jae _DivS64x64+0x67
mov 0x8(%ebp),%eax
not %edx
not %eax
add $0x1,%eax
adc $0x0,%edx
mov %eax,0x8(%ebp)
mov %edx,0xc(%ebp)
btc $0x0,%ecx
btc $0x1,%ecx
mov 0x14(%ebp),%edx
bt $0x1f,%edx
jae _DivS64x64+0x87
mov 0x10(%ebp),%eax
not %edx
not %eax
add $0x1,%eax
adc $0x0,%edx
mov %eax,0x10(%ebp)
mov %edx,0x14(%ebp)
btc $0x0,%ecx
pushl 0x1c(%ebp)
pushl 0x18(%ebp)
pushl 0x14(%ebp)
pushl 0x10(%ebp)
pushl 0xc(%ebp)
pushl 0x8(%ebp)
call _DivU64x64
add $0x18,%esp
bt $0x0,%ecx
jae _DivS64x64+0xb1
not %eax
not %edx
add $0x1,%eax
adc $0x0,%edx
bt $0x1,%ecx
jae _DivS64x64+0xc6
mov 0x18(%ebp),%ecx
notl (%ecx)
notl 0x4(%ecx)
addl $0x1,(%ecx)
adcl $0x0,0x4(%ecx)
pop %ecx
leave
ret

View File

@@ -1,622 +0,0 @@
TITLE Ia32math.asm: Generic math routines for EBC interpreter running on IA32 processor
;------------------------------------------------------------------------------
;
; 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:
;
; Ia32math.asm
;
; Abstract:
;
; Generic math routines for EBC interpreter running on IA32 processor
;
;------------------------------------------------------------------------------
.686P
.XMM
.MODEL SMALL
.CODE
LeftShiftU64 PROTO C Operand: QWORD, CountIn: QWORD
RightShiftU64 PROTO C Operand: QWORD, CountIn: QWORD
ARightShift64 PROTO C Operand: QWORD, CountIn: QWORD
MulU64x64 PROTO C Value1: QWORD, Value2: QWORD, ResultHigh: DWORD
MulS64x64 PROTO C Value1: QWORD, Value2: QWORD, ResultHigh: DWORD
DivU64x64 PROTO C Dividend: QWORD, Divisor: QWORD, Remainder: DWORD, Error: DWORD
DivS64x64 PROTO C Dividend: QWORD, Divisor: QWORD, Remainder: DWORD, Error: DWORD
LeftShiftU64 PROC C Operand: QWORD, CountIn: QWORD
;------------------------------------------------------------------------------
; UINT64
; LeftShiftU64 (
; IN UINT64 Operand,
; IN UINT64 CountIn
; )
;
; Routine Description:
;
; Left-shift a 64-bit value.
;
; Arguments:
;
; Operand - the value to shift
; Count - shift count
;
; Returns:
;
; Operand << Count
;------------------------------------------------------------------------------
push ecx
;
; if (CountIn > 63) return 0;
;
cmp dword ptr CountIn[4], 0
jne _LeftShiftU64_Overflow
mov ecx, dword ptr CountIn[0]
cmp ecx, 63
jbe _LeftShiftU64_Calc
_LeftShiftU64_Overflow:
xor eax, eax
xor edx, edx
jmp _LeftShiftU64_Done
_LeftShiftU64_Calc:
mov eax, dword ptr Operand[0]
mov edx, dword ptr Operand[4]
shld edx, eax, cl
shl eax, cl
cmp ecx, 32
jc short _LeftShiftU64_Done
mov edx, eax
xor eax, eax
_LeftShiftU64_Done:
pop ecx
ret
LeftShiftU64 ENDP
RightShiftU64 PROC C Operand: QWORD, CountIn: QWORD
;------------------------------------------------------------------------------
; UINT64
; RightShiftU64 (
; IN UINT64 Operand,
; IN UINT64 CountIn
; )
;
; Routine Description:
;
; Right-shift an unsigned 64-bit value.
;
; Arguments:
;
; Operand - the value to shift
; Count - shift count
;
; Returns:
;
; Operand >> Count
;------------------------------------------------------------------------------
push ecx
;
; if (CountIn > 63) return 0;
;
cmp dword ptr CountIn[4], 0
jne _RightShiftU64_Overflow
mov ecx, dword ptr CountIn[0]
cmp ecx, 63
jbe _RightShiftU64_Calc
_RightShiftU64_Overflow:
xor eax, eax
xor edx, edx
jmp _RightShiftU64_Done
_RightShiftU64_Calc:
mov eax, dword ptr Operand[0]
mov edx, dword ptr Operand[4]
shrd eax, edx, cl
shr edx, cl
cmp ecx, 32
jc short _RightShiftU64_Done
mov eax, edx
xor edx, edx
_RightShiftU64_Done:
pop ecx
ret
RightShiftU64 ENDP
ARightShift64 PROC C Operand: QWORD, CountIn: QWORD
;------------------------------------------------------------------------------
; INT64
; ARightShift64 (
; IN INT64 Operand,
; IN UINT64 CountIn
; )
;
; Routine Description:
;
; Arithmatic shift a 64 bit signed value.
;
; Arguments:
;
; Operand - the value to shift
; Count - shift count
;
; Returns:
;
; Operand >> Count
;------------------------------------------------------------------------------
push ecx
;
; If they exceeded the max shift count, then return either 0 or all F's
; depending on the sign bit.
;
cmp dword ptr CountIn[4], 0
jne _ARightShiftU64_Overflow
mov ecx, dword ptr CountIn[0]
cmp ecx, 63
jbe _ARightShiftU64_Calc
_ARightShiftU64_Overflow:
;
; Check the sign bit of Operand
;
bt dword ptr Operand[4], 31
jnc _ARightShiftU64_Return_Zero
;
; return -1
;
or eax, 0FFFFFFFFh
or edx, 0FFFFFFFFh
jmp _ARightShiftU64_Done
_ARightShiftU64_Return_Zero:
xor eax, eax
xor edx, edx
jmp _ARightShiftU64_Done
_ARightShiftU64_Calc:
mov eax, dword ptr Operand[0]
mov edx, dword ptr Operand[4]
shrd eax, edx, cl
sar edx, cl
cmp ecx, 32
jc short _ARightShiftU64_Done
;
; if ecx >= 32, then eax = edx, and edx = sign bit
;
mov eax, edx
sar edx, 31
_ARightShiftU64_Done:
pop ecx
ret
ARightShift64 ENDP
MulU64x64 PROC C Value1: QWORD, Value2: QWORD, ResultHigh: DWORD
;------------------------------------------------------------------------------
; UINT64
; MulU64x64 (
; UINT64 Value1,
; UINT64 Value2,
; UINT64 *ResultHigh
; )
;
; Routine Description:
;
; Multiply two unsigned 64-bit values.
;
; Arguments:
;
; Value1 - first value to multiply
; Value2 - value to multiply by Value1
; ResultHigh - result to flag overflows
;
; Returns:
;
; Value1 * Value2
; The 128-bit result is the concatenation of *ResultHigh and the return value
;------------------------------------------------------------------------------
push ebx
push ecx
mov ebx, ResultHigh ; ebx points to the high 4 words of result
;
; The result consists of four double-words.
; Here we assume their names from low to high: dw0, dw1, dw2, dw3
;
mov eax, dword ptr Value1[0]
mul dword ptr Value2[0]
push eax ; eax contains final result of dw0, push it
mov ecx, edx ; ecx contains partial result of dw1
mov eax, dword ptr Value1[4]
mul dword ptr Value2[0]
add ecx, eax ; add eax to partial result of dw1
adc edx, 0
mov dword ptr [ebx], edx ; lower double-word of ResultHigh contains partial result of dw2
mov eax, dword ptr Value1[0]
mul dword ptr Value2[4]
add ecx, eax ; add eax to partial result of dw1
push ecx ; ecx contains final result of dw1, push it
adc edx, 0
mov ecx, edx ; ecx contains partial result of dw2, together with ResultHigh
mov eax, dword ptr Value1[4]
mul dword ptr Value2[4]
add ecx, eax ; add eax to partial result of dw2
adc edx, 0
add dword ptr [ebx], ecx ; lower double-word of ResultHigh contains final result of dw2
adc edx, 0
mov dword ptr [ebx + 4], edx ; high double-word of ResultHigh contains final result of dw3
pop edx ; edx contains the final result of dw1
pop eax ; edx contains the final result of dw0
pop ecx
pop ebx
ret
MulU64x64 ENDP
MulS64x64 PROC C Value1: QWORD, Value2: QWORD, ResultHigh: DWORD
;------------------------------------------------------------------------------
; INT64
; MulS64x64 (
; INT64 Value1,
; INT64 Value2,
; INT64 *ResultHigh
; )
;
; Routine Description:
;
; Multiply two signed 64-bit values.
;
; Arguments:
;
; Value1 - first value to multiply
; Value2 - value to multiply by Value1
; ResultHigh - result to flag overflows
;
; Returns:
;
; Value1 * Value2
; The 128-bit result is the concatenation of *ResultHigh and the return value
;------------------------------------------------------------------------------
push ebx
push ecx
mov ebx, ResultHigh ; ebx points to the high 4 words of result
xor ecx, ecx ; the lowest bit of ecx flags the sign
mov edx, dword ptr Value1[4]
bt edx, 31
jnc short _MulS64x64_A_Positive
;
; a is negative
;
mov eax, dword ptr Value1[0]
not edx
not eax
add eax, 1
adc edx, 0
mov dword ptr Value1[0], eax
mov dword ptr Value1[4], edx
btc ecx, 0
_MulS64x64_A_Positive:
mov edx, dword ptr Value2[4]
bt edx, 31
jnc short _MulS64x64_B_Positive
;
; b is negative
;
mov eax, dword ptr Value2[0]
not edx
not eax
add eax, 1
adc edx, 0
mov dword ptr Value2[0], eax
mov dword ptr Value2[4], edx
btc ecx, 0
_MulS64x64_B_Positive:
invoke MulU64x64, Value1, Value2, ResultHigh
bt ecx, 0
jnc short _MulS64x64_Done
;
;negate the result
;
not eax
not edx
not dword ptr [ebx]
not dword ptr [ebx + 4]
add eax, 1
adc edx, 0
adc dword ptr [ebx], 0
adc dword ptr [ebx + 4], 0
_MulS64x64_Done:
pop ecx
pop ebx
ret
MulS64x64 ENDP
DivU64x64 PROC C Dividend: QWORD, Divisor: QWORD, Remainder: DWORD, Error: DWORD,
;------------------------------------------------------------------------------
; UINT64
; DivU64x64 (
; IN UINT64 Dividend,
; IN UINT64 Divisor,
; OUT UINT64 *Remainder OPTIONAL,
; OUT UINT32 *Error
; )
;
; Routine Description:
;
; This routine allows a 64 bit value to be divided with a 64 bit value returns
; 64bit result and the Remainder
;
; Arguments:
;
; Dividend - dividend
; Divisor - divisor
; ResultHigh - result to flag overflows
; Error - flag for error
;
; Returns:
;
; Dividend / Divisor
; Remainder = Dividend mod Divisor
;------------------------------------------------------------------------------
push ecx
mov eax, Error
mov dword ptr [eax], 0
cmp dword ptr Divisor[0], 0
jne _DivU64x64_Valid
cmp dword ptr Divisor[4], 0
jne _DivU64x64_Valid
;
; the divisor is zero
;
mov dword ptr [eax], 1
cmp Remainder, 0
je _DivU64x64_Invalid_Return
;
; fill the remainder if the pointer is not null
;
mov eax, Remainder
mov dword ptr [eax], 0
mov dword ptr [eax + 4], 80000000h
_DivU64x64_Invalid_Return:
xor eax, eax
mov edx, 80000000h
jmp _DivU64x64_Done
_DivU64x64_Valid:
;
; let edx and eax contain the intermediate result of remainder
;
xor edx, edx
xor eax, eax
mov ecx, 64
_DivU64x64_Wend:
;
; shift dividend left one
;
shl dword ptr Dividend[0], 1
rcl dword ptr Dividend[4], 1
;
; rotate intermediate result of remainder left one
;
rcl eax, 1
rcl edx, 1
cmp edx, dword ptr Divisor[4]
ja _DivU64x64_Sub_Divisor
jb _DivU64x64_Cont
cmp eax, dword ptr Divisor[0]
jb _DivU64x64_Cont
_DivU64x64_Sub_Divisor:
;
; If intermediate result of remainder is larger than
; or equal to divisor, then set the lowest bit of dividend,
; and subtract divisor from intermediate remainder
;
bts dword ptr Dividend[0], 0
sub eax, dword ptr Divisor[0]
sbb edx, dword ptr Divisor[4]
_DivU64x64_Cont:
loop _DivU64x64_Wend
cmp Remainder, 0
je _DivU64x64_Assign
mov ecx, Remainder
mov dword ptr [ecx], eax
mov dword ptr [ecx + 4], edx
_DivU64x64_Assign:
mov eax, dword ptr Dividend[0]
mov edx, dword ptr Dividend[4]
_DivU64x64_Done:
pop ecx
ret
DivU64x64 ENDP
DivS64x64 PROC C Dividend: QWORD, Divisor: QWORD, Remainder: DWORD, Error: DWORD,
;------------------------------------------------------------------------------
; INT64
; DivU64x64 (
; IN INT64 Dividend,
; IN INT64 Divisor,
; OUT UINT64 *Remainder OPTIONAL,
; OUT UINT32 *Error
; )
;
; Routine Description:
;
; This routine allows a 64 bit signed value to be divided with a 64 bit
; signed value returns 64bit result and the Remainder.
;
; Arguments:
;
; Dividend - dividend
; Divisor - divisor
; ResultHigh - result to flag overflows
; Error - flag for error
;
; Returns:
;
; Dividend / Divisor
; Remainder = Dividend mod Divisor
;------------------------------------------------------------------------------
push ecx
mov eax, Error
mov dword ptr [eax], 0
cmp dword ptr Divisor[0], 0
jne _DivS64x64_Valid
cmp dword ptr Divisor[4], 0
jne _DivS64x64_Valid
;
; the divisor is zero
;
mov dword ptr [eax], 1
cmp Remainder, 0
je _DivS64x64_Invalid_Return
;
; fill the remainder if the pointer is not null
;
mov eax, Remainder
mov dword ptr [eax], 0
mov dword ptr [eax + 4], 80000000h
_DivS64x64_Invalid_Return:
xor eax, eax
mov edx, 80000000h
jmp _DivS64x64_Done
_DivS64x64_Valid:
;
; The lowest bit of ecx flags the sign of quotient,
; The seconde lowest bit flags the sign of remainder
;
xor ecx, ecx
mov edx, dword ptr Dividend[4]
bt edx, 31
jnc short _DivS64x64_Dividend_Positive
;
; dividend is negative
;
mov eax, dword ptr Dividend[0]
not edx
not eax
add eax, 1
adc edx, 0
mov dword ptr Dividend[0], eax
mov dword ptr Dividend[4], edx
;
; set both the flags for signs of quotient and remainder
;
btc ecx, 0
btc ecx, 1
_DivS64x64_Dividend_Positive:
mov edx, dword ptr Divisor[4]
bt edx, 31
jnc short _DivS64x64_Divisor_Positive
;
; divisor is negative
;
mov eax, dword ptr Divisor[0]
not edx
not eax
add eax, 1
adc edx, 0
mov dword ptr Divisor[0], eax
mov dword ptr Divisor[4], edx
;
; just complement the flag for sign of quotient
;
btc ecx, 0
_DivS64x64_Divisor_Positive:
invoke DivU64x64, Dividend, Divisor, Remainder, Error
bt ecx, 0
jnc short _DivS64x64_Remainder
;
; negate the quotient
;
not eax
not edx
add eax, 1
adc edx, 0
_DivS64x64_Remainder:
bt ecx, 1
jnc short _DivS64x64_Done
;
; negate the remainder
;
mov ecx, remainder
not dword ptr [ecx]
not dword ptr [ecx + 4]
add dword ptr [ecx], 1
adc dword ptr [ecx + 4], 0
_DivS64x64_Done:
pop ecx
ret
DivS64x64 ENDP
END