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

@ -22,6 +22,9 @@
<OutputFileBasename>Ebc</OutputFileBasename>
</ModuleDefinitions>
<LibraryClassDefinitions>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>BaseLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>DebugLib</Keyword>
</LibraryClass>
@ -55,15 +58,10 @@
<Filename>Ebc.dxs</Filename>
<Filename SupArchList="IA32">Ia32/EbcLowLevel.asm</Filename>
<Filename SupArchList="IA32">Ia32/EbcLowLevel.S</Filename>
<Filename SupArchList="IA32">Ia32/Ia32Math.asm</Filename>
<Filename SupArchList="IA32">Ia32/Ia32Math.S</Filename>
<Filename SupArchList="IA32">Ia32/EbcSupport.c</Filename>
<Filename SupArchList="X64">x64/EbcLowLevel.asm</Filename>
<Filename SupArchList="X64">x64/x64Math.c</Filename>
<Filename SupArchList="X64">x64/EbcSupport.c</Filename>
<Filename SupArchList="IPF">Ipf/EbcLowLevel.s</Filename>
<Filename SupArchList="IPF">Ipf/IpfMath.c</Filename>
<Filename SupArchList="IPF">Ipf/IpfMul.s</Filename>
<Filename SupArchList="IPF">Ipf/EbcSupport.c</Filename>
</SourceFiles>
<PackageDependencies>

View File

@ -2942,10 +2942,8 @@ Instruction syntax:
--*/
{
INT64 ResultHigh;
if (*VmPtr->Ip & DATAMANIP_M_64) {
return MulS64x64 (Op1, Op2, &ResultHigh);
return MultS64x64 ((INT64)Op1, (INT64)Op2);
} else {
return (UINT64) ((INT64) ((INT32) Op1 * (INT32) Op2));
}
@ -2976,9 +2974,8 @@ Instruction syntax:
--*/
{
INT64 ResultHigh;
if (*VmPtr->Ip & DATAMANIP_M_64) {
return MulU64x64 (Op1, Op2, (UINT64 *)&ResultHigh);
return MultU64x64 (Op1, Op2);
} else {
return (UINT64) ((UINT32) Op1 * (UINT32) Op2);
}
@ -3011,7 +3008,6 @@ Instruction syntax:
--*/
{
INT64 Remainder;
UINT32 Error;
//
// Check for divide-by-0
@ -3026,7 +3022,7 @@ Instruction syntax:
return 0;
} else {
if (*VmPtr->Ip & DATAMANIP_M_64) {
return (UINT64) (DivS64x64 (Op1, Op2, &Remainder, &Error));
return (UINT64) (DivS64x64Remainder (Op1, Op2, &Remainder));
} else {
return (UINT64) ((INT64) ((INT32) Op1 / (INT32) Op2));
}
@ -3059,7 +3055,6 @@ Instruction syntax:
--*/
{
UINT64 Remainder;
UINT32 Error;
//
// Check for divide-by-0
@ -3076,7 +3071,7 @@ Instruction syntax:
// Get the destination register
//
if (*VmPtr->Ip & DATAMANIP_M_64) {
return (UINT64) (DivU64x64 (Op1, Op2, &Remainder, &Error));
return (UINT64) (DivU64x64Remainder ((INT64)Op1, (INT64)Op2, &Remainder));
} else {
return (UINT64) ((UINT32) Op1 / (UINT32) Op2);
}
@ -3109,7 +3104,6 @@ Instruction syntax:
--*/
{
INT64 Remainder;
UINT32 Error;
//
// Check for divide-by-0
@ -3122,7 +3116,7 @@ Instruction syntax:
);
return 0;
} else {
DivS64x64 ((INT64) Op1, (INT64) Op2, &Remainder, &Error);
DivS64x64Remainder ((INT64)Op1, (INT64)Op2, &Remainder);
return Remainder;
}
}
@ -3153,7 +3147,6 @@ Instruction syntax:
--*/
{
UINT64 Remainder;
UINT32 Error;
//
// Check for divide-by-0
@ -3166,7 +3159,7 @@ Instruction syntax:
);
return 0;
} else {
DivU64x64 (Op1, Op2, &Remainder, &Error);
DivU64x64Remainder (Op1, Op2, &Remainder);
return Remainder;
}
}
@ -3282,7 +3275,7 @@ Instruction syntax:
--*/
{
if (*VmPtr->Ip & DATAMANIP_M_64) {
return LeftShiftU64 (Op1, Op2);
return LShiftU64 (Op1, (UINTN)Op2);
} else {
return (UINT64) ((UINT32) ((UINT32) Op1 << (UINT32) Op2));
}
@ -3314,7 +3307,7 @@ Instruction syntax:
--*/
{
if (*VmPtr->Ip & DATAMANIP_M_64) {
return RightShiftU64 (Op1, Op2);
return RShiftU64 (Op1, (UINTN)Op2);
} else {
return (UINT64) ((UINT32) Op1 >> (UINT32) Op2);
}
@ -3346,7 +3339,7 @@ Instruction syntax:
--*/
{
if (*VmPtr->Ip & DATAMANIP_M_64) {
return ARightShift64 (Op1, Op2);
return ARShiftU64 (Op1, (UINTN)Op2);
} else {
return (UINT64) ((INT64) ((INT32) Op1 >> (UINT32) Op2));
}
@ -3950,7 +3943,6 @@ Returns:
--*/
{
UINT64 Index;
UINT64 Remainder;
INT64 Offset;
INT64 C;
INT64 N;
@ -3962,17 +3954,17 @@ Returns:
//
// Get the mask for N. First get the number of bits from the index.
//
NBits = RightShiftU64 ((Index & 0x7000000000000000ULL), 60);
NBits = RShiftU64 ((Index & 0x7000000000000000ULL), 60);
//
// Scale it for 64-bit indexes (multiply by 8 by shifting left 3)
//
NBits = LeftShiftU64 (NBits, 3);
NBits = LShiftU64 ((UINT64)NBits, 3);
//
// Now using the number of bits, create a mask.
//
Mask = (LeftShiftU64 ((UINT64)~0, (UINT64) NBits));
Mask = (LShiftU64 ((UINT64)~0, (UINTN)NBits));
//
// Now using the mask, extract N from the lower bits of the index.
@ -3982,15 +3974,15 @@ Returns:
//
// Now compute C
//
C = ARightShift64 (((Index &~0xF000000000000000ULL) & Mask), (UINTN) NBits);
C = ARShiftU64 (((Index &~0xF000000000000000ULL) & Mask), (UINTN)NBits);
Offset = MulU64x64 (N, sizeof (UINTN), &Remainder) + C;
Offset = MultU64x64 (N, sizeof (UINTN)) + C;
//
// Now set the sign
//
if (Index & 0x8000000000000000ULL) {
Offset = MulS64x64 (Offset, -1, (INT64 *)&Index);
Offset = MultS64x64 (Offset, -1);
}
return Offset;

View File

@ -234,73 +234,7 @@ EbcExecute (
)
;
//
// Math library routines
//
INT64
DivS64x64 (
IN INT64 Value1,
IN INT64 Value2,
OUT INT64 *Remainder,
OUT UINT32 *Error
)
;
#if 0
UINT64
DivU64x64 (
IN UINT64 Value1,
IN UINT64 Value2,
OUT UINT64 *Remainder,
OUT UINT32 *Error
)
;
#endif
INT64
MulS64x64 (
IN INT64 Value1,
IN INT64 Value2,
OUT INT64 *ResultHigh
)
;
UINT64
MulU64x64 (
IN UINT64 Value1,
IN UINT64 Value2,
OUT UINT64 *ResultHigh
)
;
UINT64
DivU64x64 (
IN UINT64 Value1,
IN UINT64 Value2,
OUT UINT64 *Remainder,
OUT UINT32 *Error
)
;
INT64
ARightShift64 (
IN INT64 Operand,
IN INT64 Count
)
;
UINT64
LeftShiftU64 (
IN UINT64 Operand,
IN UINT64 Count
)
;
UINT64
RightShiftU64 (
IN UINT64 Operand,
IN UINT64 Count
)
;
UINT64
GetVmVersion (

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

View File

@ -339,14 +339,14 @@ Returns:
UINT8 *Ptr;
UINT8 *ThunkBase;
UINT64 Addr;
UINT64 Code[3]; // Code in a bundle
UINT64 RegNum; // register number for MOVL
UINT64 I; // bits of MOVL immediate data
UINT64 Ic; // bits of MOVL immediate data
UINT64 Imm5c; // bits of MOVL immediate data
UINT64 Imm9d; // bits of MOVL immediate data
UINT64 Imm7b; // bits of MOVL immediate data
UINT64 Br; // branch register for loading and jumping
UINT64 Code[3]; // Code in a bundle
UINT64 RegNum; // register number for MOVL
UINT64 I; // bits of MOVL immediate data
UINT64 Ic; // bits of MOVL immediate data
UINT64 Imm5c; // bits of MOVL immediate data
UINT64 Imm9d; // bits of MOVL immediate data
UINT64 Imm7b; // bits of MOVL immediate data
UINT64 Br; // branch register for loading and jumping
UINT64 *Data64Ptr;
UINT32 ThunkSize;
UINT32 Size;
@ -441,25 +441,25 @@ Returns:
//
// Next is simply Addr[62:22] (41 bits) of the address
//
Code[1] = RightShiftU64 (Addr, 22) & 0x1ffffffffff;
Code[1] = RShiftU64 (Addr, 22) & 0x1ffffffffff;
//
// Extract bits from the address for insertion into the instruction
// i = Addr[63:63]
//
I = RightShiftU64 (Addr, 63) & 0x01;
I = RShiftU64 (Addr, 63) & 0x01;
//
// ic = Addr[21:21]
//
Ic = RightShiftU64 (Addr, 21) & 0x01;
Ic = RShiftU64 (Addr, 21) & 0x01;
//
// imm5c = Addr[20:16] for 5 bits
//
Imm5c = RightShiftU64 (Addr, 16) & 0x1F;
Imm5c = RShiftU64 (Addr, 16) & 0x1F;
//
// imm9d = Addr[15:7] for 9 bits
//
Imm9d = RightShiftU64 (Addr, 7) & 0x1FF;
Imm9d = RShiftU64 (Addr, 7) & 0x1FF;
//
// imm7b = Addr[6:0] for 7 bits
//
@ -474,14 +474,14 @@ Returns:
//
// Next is jumbled data, including opcode and rest of address
//
Code[2] = LeftShiftU64 (Imm7b, 13)
| LeftShiftU64 (0x00, 20) // vc
| LeftShiftU64 (Ic, 21)
| LeftShiftU64 (Imm5c, 22)
| LeftShiftU64 (Imm9d, 27)
| LeftShiftU64 (I, 36)
| LeftShiftU64 ((UINT64)MOVL_OPCODE, 37)
| LeftShiftU64 ((RegNum & 0x7F), 6);
Code[2] = LShiftU64 (Imm7b, 13)
| LShiftU64 (0x00, 20) // vc
| LShiftU64 (Ic, 21)
| LShiftU64 (Imm5c, 22)
| LShiftU64 (Imm9d, 27)
| LShiftU64 (I, 36)
| LShiftU64 ((UINT64)MOVL_OPCODE, 37)
| LShiftU64 ((RegNum & 0x7F), 6);
WriteBundle ((VOID *) Ptr, 0x05, Code[0], Code[1], Code[2]);
@ -506,25 +506,25 @@ Returns:
//
// Next is simply Addr[62:22] (41 bits) of the address
//
Code[1] = RightShiftU64 (Addr, 22) & 0x1ffffffffff;
Code[1] = RShiftU64 (Addr, 22) & 0x1ffffffffff;
//
// Extract bits from the address for insertion into the instruction
// i = Addr[63:63]
//
I = RightShiftU64 (Addr, 63) & 0x01;
I = RShiftU64 (Addr, 63) & 0x01;
//
// ic = Addr[21:21]
//
Ic = RightShiftU64 (Addr, 21) & 0x01;
Ic = RShiftU64 (Addr, 21) & 0x01;
//
// imm5c = Addr[20:16] for 5 bits
//
Imm5c = RightShiftU64 (Addr, 16) & 0x1F;
Imm5c = RShiftU64 (Addr, 16) & 0x1F;
//
// imm9d = Addr[15:7] for 9 bits
//
Imm9d = RightShiftU64 (Addr, 7) & 0x1FF;
Imm9d = RShiftU64 (Addr, 7) & 0x1FF;
//
// imm7b = Addr[6:0] for 7 bits
//
@ -539,14 +539,14 @@ Returns:
//
// Next is jumbled data, including opcode and rest of address
//
Code[2] = LeftShiftU64 (Imm7b, 13)
| LeftShiftU64 (0x00, 20) // vc
| LeftShiftU64 (Ic, 21)
| LeftShiftU64 (Imm5c, 22)
| LeftShiftU64 (Imm9d, 27)
| LeftShiftU64 (I, 36)
| LeftShiftU64 ((UINT64)MOVL_OPCODE, 37)
| LeftShiftU64 ((RegNum & 0x7F), 6);
Code[2] = LShiftU64 (Imm7b, 13)
| LShiftU64 (0x00, 20) // vc
| LShiftU64 (Ic, 21)
| LShiftU64 (Imm5c, 22)
| LShiftU64 (Imm9d, 27)
| LShiftU64 (I, 36)
| LShiftU64 ((UINT64)MOVL_OPCODE, 37)
| LShiftU64 ((RegNum & 0x7F), 6);
WriteBundle ((VOID *) Ptr, 0x05, Code[0], Code[1], Code[2]);
@ -578,25 +578,25 @@ Returns:
//
// Next is simply Addr[62:22] (41 bits) of the address
//
Code[1] = RightShiftU64 (Addr, 22) & 0x1ffffffffff;
Code[1] = RShiftU64 (Addr, 22) & 0x1ffffffffff;
//
// Extract bits from the address for insertion into the instruction
// i = Addr[63:63]
//
I = RightShiftU64 (Addr, 63) & 0x01;
I = RShiftU64 (Addr, 63) & 0x01;
//
// ic = Addr[21:21]
//
Ic = RightShiftU64 (Addr, 21) & 0x01;
Ic = RShiftU64 (Addr, 21) & 0x01;
//
// imm5c = Addr[20:16] for 5 bits
//
Imm5c = RightShiftU64 (Addr, 16) & 0x1F;
Imm5c = RShiftU64 (Addr, 16) & 0x1F;
//
// imm9d = Addr[15:7] for 9 bits
//
Imm9d = RightShiftU64 (Addr, 7) & 0x1FF;
Imm9d = RShiftU64 (Addr, 7) & 0x1FF;
//
// imm7b = Addr[6:0] for 7 bits
//
@ -610,14 +610,14 @@ Returns:
//
// Next is jumbled data, including opcode and rest of address
//
Code[2] = LeftShiftU64(Imm7b, 13)
| LeftShiftU64 (0x00, 20) // vc
| LeftShiftU64 (Ic, 21)
| LeftShiftU64 (Imm5c, 22)
| LeftShiftU64 (Imm9d, 27)
| LeftShiftU64 (I, 36)
| LeftShiftU64 ((UINT64)MOVL_OPCODE, 37)
| LeftShiftU64 ((RegNum & 0x7F), 6);
Code[2] = LShiftU64(Imm7b, 13)
| LShiftU64 (0x00, 20) // vc
| LShiftU64 (Ic, 21)
| LShiftU64 (Imm5c, 22)
| LShiftU64 (Imm9d, 27)
| LShiftU64 (I, 36)
| LShiftU64 ((UINT64)MOVL_OPCODE, 37)
| LShiftU64 ((RegNum & 0x7F), 6);
WriteBundle ((VOID *) Ptr, 0x05, Code[0], Code[1], Code[2]);
@ -641,8 +641,8 @@ Returns:
// register and user register (same user register as previous bundle).
//
Br = 6;
Code[2] |= LeftShiftU64 (Br, 6);
Code[2] |= LeftShiftU64 (RegNum, 13);
Code[2] |= LShiftU64 (Br, 6);
Code[2] |= LShiftU64 (RegNum, 13);
WriteBundle ((VOID *) Ptr, 0x0d, Code[0], Code[1], Code[2]);
//
@ -657,7 +657,7 @@ Returns:
Code[0] = OPCODE_NOP;
Code[1] = OPCODE_NOP;
Code[2] = OPCODE_BR_COND_SPTK_FEW;
Code[2] |= LeftShiftU64 (Br, 13);
Code[2] |= LShiftU64 (Br, 13);
WriteBundle ((VOID *) Ptr, 0x1d, Code[0], Code[1], Code[2]);
//
@ -728,8 +728,8 @@ Returns:
return EFI_INVALID_PARAMETER;
}
Low64 = LeftShiftU64 (Slot1, 46) | LeftShiftU64 (Slot0, 5) | Template;
High64 = RightShiftU64 (Slot1, 18) | LeftShiftU64 (Slot2, 23);
Low64 = LShiftU64 (Slot1, 46) | LShiftU64 (Slot0, 5) | Template;
High64 = RShiftU64 (Slot1, 18) | LShiftU64 (Slot2, 23);
//
// Now write it all out
@ -737,13 +737,13 @@ Returns:
BPtr = (UINT8 *) MemPtr;
for (Index = 0; Index < 8; Index++) {
*BPtr = (UINT8) Low64;
Low64 = RightShiftU64 (Low64, 8);
Low64 = RShiftU64 (Low64, 8);
BPtr++;
}
for (Index = 0; Index < 8; Index++) {
*BPtr = (UINT8) High64;
High64 = RightShiftU64 (High64, 8);
High64 = RShiftU64 (High64, 8);
BPtr++;
}
@ -814,21 +814,21 @@ Returns:
goto Action;
}
CodeOne18 = RightShiftU64 (*((UINT64 *)CalleeAddr + 2), 46) & 0x3FFFF;
CodeOne18 = RShiftU64 (*((UINT64 *)CalleeAddr + 2), 46) & 0x3FFFF;
CodeOne23 = (*((UINT64 *)CalleeAddr + 3)) & 0x7FFFFF;
CodeTwoI = RightShiftU64 (*((UINT64 *)CalleeAddr + 3), 59) & 0x1;
CodeTwoIc = RightShiftU64 (*((UINT64 *)CalleeAddr + 3), 44) & 0x1;
CodeTwo7b = RightShiftU64 (*((UINT64 *)CalleeAddr + 3), 36) & 0x7F;
CodeTwo5c = RightShiftU64 (*((UINT64 *)CalleeAddr + 3), 45) & 0x1F;
CodeTwo9d = RightShiftU64 (*((UINT64 *)CalleeAddr + 3), 50) & 0x1FF;
CodeTwoI = RShiftU64 (*((UINT64 *)CalleeAddr + 3), 59) & 0x1;
CodeTwoIc = RShiftU64 (*((UINT64 *)CalleeAddr + 3), 44) & 0x1;
CodeTwo7b = RShiftU64 (*((UINT64 *)CalleeAddr + 3), 36) & 0x7F;
CodeTwo5c = RShiftU64 (*((UINT64 *)CalleeAddr + 3), 45) & 0x1F;
CodeTwo9d = RShiftU64 (*((UINT64 *)CalleeAddr + 3), 50) & 0x1FF;
TargetEbcAddr = CodeTwo7b
| LeftShiftU64 (CodeTwo9d, 7)
| LeftShiftU64 (CodeTwo5c, 16)
| LeftShiftU64 (CodeTwoIc, 21)
| LeftShiftU64 (CodeOne18, 22)
| LeftShiftU64 (CodeOne23, 40)
| LeftShiftU64 (CodeTwoI, 63)
| LShiftU64 (CodeTwo9d, 7)
| LShiftU64 (CodeTwo5c, 16)
| LShiftU64 (CodeTwoIc, 21)
| LShiftU64 (CodeOne18, 22)
| LShiftU64 (CodeOne23, 40)
| LShiftU64 (CodeTwoI, 63)
;
Action:

View File

@ -1,375 +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:
Ipfmath.c
Abstract:
Math routines for IPF.
--*/
UINT64
LeftShiftU64 (
IN UINT64 Operand,
IN UINT64 Count
)
/*++
Routine Description:
Left-shift a 64 bit value.
Arguments:
Operand - 64-bit value to shift
Count - shift count
Returns:
Operand << Count
--*/
{
if (Count > 63) {
return 0;
}
return Operand << Count;
}
UINT64
RightShiftU64 (
IN UINT64 Operand,
IN UINT64 Count
)
/*++
Routine Description:
Right-shift a 64 bit value.
Arguments:
Operand - 64-bit value to shift
Count - shift count
Returns:
Operand >> Count
--*/
{
if (Count > 63) {
return 0;
}
return Operand >> Count;
}
INT64
ARightShift64 (
IN INT64 Operand,
IN UINT64 Count
)
/*++
Routine Description:
Right-shift a 64 bit signed value.
Arguments:
Operand - 64-bit value to shift
Count - shift count
Returns:
Operand >> Count
--*/
{
if (Count > 63) {
if (Operand & (0x01 << 63)) {
return (INT64)~0;
}
return 0;
}
return Operand >> Count;
}
#if 0
//
// The compiler generates true assembly for these, so we don't need them.
//
INT32
ARightShift32 (
IN INT32 Operand,
IN UINTN Count
)
/*++
Routine Description:
Right shift a 32-bit value
Arguments:
Operand - value to shift
Count - shift count
Returns:
Operand >> Count
--*/
{
return Operand >> (Count & 0x1f);
}
INT32
MulS32x32 (
INT32 Value1,
INT32 Value2,
INT32 *ResultHigh
)
/*++
Routine Description:
Multiply two signed 32-bit numbers.
Arguments:
Value1 - first value to multiply
Value2 - value to multiply Value1 by
ResultHigh - overflow
Returns:
Value1 * Value2
Notes:
The 64-bit result is the concatenation of *ResultHigh and the return value
The product fits in 32 bits if
(*ResultHigh == 0x00000000 AND *ResultLow_bit31 == 0)
OR
(*ResultHigh == 0xffffffff AND *ResultLow_bit31 == 1)
--*/
{
INT64 Rres64;
INT32 Result;
Res64 = (INT64) Value1 * (INT64) Value2;
*ResultHigh = (Res64 >> 32) & 0xffffffff;
Result = Res64 & 0xffffffff;
return Result;
}
UINT32
MulU32x32 (
UINT32 Value1,
UINT32 Value2,
UINT32 *ResultHigh
)
/*++
Routine Description:
Multiply two unsigned 32-bit values.
Arguments:
Value1 - first number
Value2 - number to multiply by Value1
ResultHigh - overflow
Returns:
Value1 * Value2
Notes:
The 64-bit result is the concatenation of *ResultHigh and the return value.
The product fits in 32 bits if *ResultHigh == 0x00000000
--*/
{
UINT64 Res64;
UINT32 Result;
Res64 = (INT64) Value1 * (INT64) Value2;
*ResultHigh = (Res64 >> 32) & 0xffffffff;
Result = Res64 & 0xffffffff;
return Result;
}
INT32
DivS32x32 (
INT32 Value1,
INT32 Value2,
INT32 *Remainder,
UINTN *error
)
//
// signed 32-bit by signed 32-bit divide; the 32-bit remainder is
// in *Remainder and the quotient is the return value; *error = 1 if the
// divisor is 0, and it is 1 otherwise
//
{
INT32 Result;
*error = 0;
if (Value2 == 0x0) {
*error = 1;
Result = 0x80000000;
*Remainder = 0x80000000;
} else {
Result = Value1 / Value2;
*Remainder = Value1 - Result * Value2;
}
return Result;
}
UINT32
DivU32x32 (
UINT32 Value1,
UINT32 Value2,
UINT32 *Remainder,
UINTN *Error
)
//
// unsigned 32-bit by unsigned 32-bit divide; the 32-bit remainder is
// in *Remainder and the quotient is the return value; *error = 1 if the
// divisor is 0, and it is 1 otherwise
//
{
UINT32 Result;
*Error = 0;
if (Value2 == 0x0) {
*Error = 1;
Result = 0x80000000;
*Remainder = 0x80000000;
} else {
Result = Value1 / Value2;
*Remainder = Value1 - Result * Value2;
}
return Result;
}
#endif
INT64
DivS64x64 (
INT64 Value1,
INT64 Value2,
INT64 *Remainder,
UINTN *Error
)
/*++
Routine Description:
Divide two 64-bit signed values.
Arguments:
Value1 - dividend
Value2 - divisor
Remainder - remainder of Value1/Value2
Error - to flag errors (divide-by-0)
Returns:
Value1 / Valu2
Note:
The 64-bit remainder is in *Remainder and the quotient is the return value.
*Error = 1 if the divisor is 0, and it is 1 otherwise
--*/
{
INT64 Result;
*Error = 0;
if (Value2 == 0x0) {
*Error = 1;
Result = 0x8000000000000000;
*Remainder = 0x8000000000000000;
} else {
Result = Value1 / Value2;
*Remainder = Value1 - Result * Value2;
}
return Result;
}
UINT64
DivU64x64 (
UINT64 Value1,
UINT64 Value2,
UINT64 *Remainder,
UINTN *Error
)
/*++
Routine Description:
Divide two 64-bit unsigned values.
Arguments:
Value1 - dividend
Value2 - divisor
Remainder - remainder of Value1/Value2
Error - to flag errors (divide-by-0)
Returns:
Value1 / Valu2
Note:
The 64-bit remainder is in *Remainder and the quotient is the return value.
*Error = 1 if the divisor is 0, and it is 1 otherwise
--*/
{
UINT64 Result;
*Error = 0;
if (Value2 == 0x0) {
*Error = 1;
Result = 0x8000000000000000;
*Remainder = 0x8000000000000000;
} else {
Result = Value1 / Value2;
*Remainder = Value1 - Result * Value2;
}
return Result;
}

View File

@ -1,144 +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:
//
// IpfMul.s
//
//Abstract:
//
// Low level routines for IPF multiply support
//
//--*/
.file "IpfMul.s"
.section .text
.proc MulS64x64#
.align 32
.globl MulS64x64#
.align 32
///*++
//
//Routine Description:
//
// Multiply two 64-bit signed numbers.
//
//
//Arguments:
//
// INT64
// MulS64x64 (
// IN INT64 Value1,
// IN INT64 Value2,
// OUT INT64 *ResultHigh);
//
//Returns:
//
// 64-bit signed result
//
//--*/
MulS64x64:
// signed 64x64->128-bit multiply
// A in r32, B in r33, Q_hi stored in [r34], Q_lo returned in r8
{ .mfi
alloc r31=ar.pfs,3,0,0,0 // r32-r34
nop.f 0
nop.i 0;;
}
{.mmi
setf.sig f6=r32
setf.sig f7=r33
nop.i 0;;
}
{.mfi
nop.m 0
xma.h f8=f6,f7,f0
nop.i 0
}
{.mfi
nop.m 0
xma.l f6=f6,f7,f0
nop.i 0;;
}
{.mmb
stf8 [r34]=f8
getf.sig r8=f6
br.ret.sptk b0;;
}
.endp MulS64x64
.proc MulU64x64#
.align 32
.globl MulU64x64#
.align 32
///*++
//
//Routine Description:
//
// Multiply two 64-bit unsigned numbers.
//
//
//Arguments:
//
// UINT64
// MulU64x64 (
// IN UINT64 Value1,
// IN UINT64 Value2,
// OUT UINT64 *ResultHigh);
//
//Returns:
//
// 64-bit unsigned result
//
//--*/
MulU64x64:
// A in r32, B in r33, Q_hi stored in [r34], Q_lo returned in r8
{ .mfi
alloc r31=ar.pfs,3,0,0,0 // r32-r34
nop.f 0
nop.i 0;;
}
{.mmi
setf.sig f6=r32
setf.sig f7=r33
nop.i 0;;
}
{.mfi
nop.m 0
xma.hu f8=f6,f7,f0
nop.i 0
}
{.mfi
nop.m 0
xma.l f6=f6,f7,f0
nop.i 0;;
}
{.mmb
stf8 [r34]=f8
getf.sig r8=f6
br.ret.sptk b0;;
}
.endp MulU64x64

View File

@ -1,451 +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:
x64math.c
Abstract:
Math routines for x64.
--*/
UINT64
LeftShiftU64 (
IN UINT64 Operand,
IN UINT64 Count
)
/*++
Routine Description:
Left-shift a 64 bit value.
Arguments:
Operand - 64-bit value to shift
Count - shift count
Returns:
Operand << Count
--*/
{
if (Count > 63) {
return 0;
}
return Operand << Count;
}
UINT64
RightShiftU64 (
IN UINT64 Operand,
IN UINT64 Count
)
/*++
Routine Description:
Right-shift a 64 bit value.
Arguments:
Operand - 64-bit value to shift
Count - shift count
Returns:
Operand >> Count
--*/
{
if (Count > 63) {
return 0;
}
return Operand >> Count;
}
INT64
ARightShift64 (
IN INT64 Operand,
IN UINT64 Count
)
/*++
Routine Description:
Right-shift a 64 bit signed value.
Arguments:
Operand - 64-bit value to shift
Count - shift count
Returns:
Operand >> Count
--*/
{
if (Count > 63) {
if (Operand & 0x8000000000000000ULL) {
return (INT64)~0;
}
return 0;
}
return Operand >> Count;
}
#if 0
//
// The compiler generates true assembly for these, so we don't need them.
//
INT32
ARightShift32 (
IN INT32 Operand,
IN UINTN Count
)
/*++
Routine Description:
Right shift a 32-bit value
Arguments:
Operand - value to shift
Count - shift count
Returns:
Operand >> Count
--*/
{
return Operand >> (Count & 0x1f);
}
INT32
MulS32x32 (
INT32 Value1,
INT32 Value2,
INT32 *ResultHigh
)
/*++
Routine Description:
Multiply two signed 32-bit numbers.
Arguments:
Value1 - first value to multiply
Value2 - value to multiply Value1 by
ResultHigh - overflow
Returns:
Value1 * Value2
Notes:
The 64-bit result is the concatenation of *ResultHigh and the return value
The product fits in 32 bits if
(*ResultHigh == 0x00000000 AND *ResultLow_bit31 == 0)
OR
(*ResultHigh == 0xffffffff AND *ResultLow_bit31 == 1)
--*/
{
INT64 Rres64;
INT32 Result;
Res64 = (INT64) Value1 * (INT64) Value2;
*ResultHigh = (Res64 >> 32) & 0xffffffff;
Result = Res64 & 0xffffffff;
return Result;
}
UINT32
MulU32x32 (
UINT32 Value1,
UINT32 Value2,
UINT32 *ResultHigh
)
/*++
Routine Description:
Multiply two unsigned 32-bit values.
Arguments:
Value1 - first number
Value2 - number to multiply by Value1
ResultHigh - overflow
Returns:
Value1 * Value2
Notes:
The 64-bit result is the concatenation of *ResultHigh and the return value.
The product fits in 32 bits if *ResultHigh == 0x00000000
--*/
{
UINT64 Res64;
UINT32 Result;
Res64 = (INT64) Value1 * (INT64) Value2;
*ResultHigh = (Res64 >> 32) & 0xffffffff;
Result = Res64 & 0xffffffff;
return Result;
}
INT32
DivS32x32 (
INT32 Value1,
INT32 Value2,
INT32 *Remainder,
UINTN *error
)
//
// signed 32-bit by signed 32-bit divide; the 32-bit remainder is
// in *Remainder and the quotient is the return value; *error = 1 if the
// divisor is 0, and it is 1 otherwise
//
{
INT32 Result;
*error = 0;
if (Value2 == 0x0) {
*error = 1;
Result = 0x80000000;
*Remainder = 0x80000000;
} else {
Result = Value1 / Value2;
*Remainder = Value1 - Result * Value2;
}
return Result;
}
UINT32
DivU32x32 (
UINT32 Value1,
UINT32 Value2,
UINT32 *Remainder,
UINTN *Error
)
//
// unsigned 32-bit by unsigned 32-bit divide; the 32-bit remainder is
// in *Remainder and the quotient is the return value; *error = 1 if the
// divisor is 0, and it is 1 otherwise
//
{
UINT32 Result;
*Error = 0;
if (Value2 == 0x0) {
*Error = 1;
Result = 0x80000000;
*Remainder = 0x80000000;
} else {
Result = Value1 / Value2;
*Remainder = Value1 - Result * Value2;
}
return Result;
}
#endif
INT64
MulS64x64 (
INT64 Value1,
INT64 Value2,
INT64 *ResultHigh
)
/*++
Routine Description:
Multiply two signed 32-bit numbers.
Arguments:
Value1 - first value to multiply
Value2 - value to multiply Value1 by
ResultHigh - overflow
Returns:
Value1 * Value2
Notes:
The 64-bit result is the concatenation of *ResultHigh and the return value
The product fits in 32 bits if
(*ResultHigh == 0x00000000 AND *ResultLow_bit31 == 0)
OR
(*ResultHigh == 0xffffffff AND *ResultLow_bit31 == 1)
--*/
{
INT64 Result;
Result = Value1 * Value2;
return Result;
}
UINT64
MulU64x64 (
UINT64 Value1,
UINT64 Value2,
UINT64 *ResultHigh
)
/*++
Routine Description:
Multiply two unsigned 32-bit values.
Arguments:
Value1 - first number
Value2 - number to multiply by Value1
ResultHigh - overflow
Returns:
Value1 * Value2
Notes:
The 64-bit result is the concatenation of *ResultHigh and the return value.
The product fits in 32 bits if *ResultHigh == 0x00000000
--*/
{
UINT64 Result;
Result = Value1 * Value2;
return Result;
}
INT64
DivS64x64 (
INT64 Value1,
INT64 Value2,
INT64 *Remainder,
UINTN *Error
)
/*++
Routine Description:
Divide two 64-bit signed values.
Arguments:
Value1 - dividend
Value2 - divisor
Remainder - remainder of Value1/Value2
Error - to flag errors (divide-by-0)
Returns:
Value1 / Valu2
Note:
The 64-bit remainder is in *Remainder and the quotient is the return value.
*Error = 1 if the divisor is 0, and it is 1 otherwise
--*/
{
INT64 Result;
*Error = 0;
if (Value2 == 0x0) {
*Error = 1;
Result = 0x8000000000000000;
*Remainder = 0x8000000000000000;
} else {
Result = Value1 / Value2;
*Remainder = Value1 - Result * Value2;
}
return Result;
}
UINT64
DivU64x64 (
UINT64 Value1,
UINT64 Value2,
UINT64 *Remainder,
UINTN *Error
)
/*++
Routine Description:
Divide two 64-bit unsigned values.
Arguments:
Value1 - dividend
Value2 - divisor
Remainder - remainder of Value1/Value2
Error - to flag errors (divide-by-0)
Returns:
Value1 / Valu2
Note:
The 64-bit remainder is in *Remainder and the quotient is the return value.
*Error = 1 if the divisor is 0, and it is 1 otherwise
--*/
{
UINT64 Result;
*Error = 0;
if (Value2 == 0x0) {
*Error = 1;
Result = 0x8000000000000000;
*Remainder = 0x8000000000000000;
} else {
Result = Value1 / Value2;
*Remainder = Value1 - Result * Value2;
}
return Result;
}