Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

575 lines
9.3 KiB

/*++
Copyright (c) 1992 Microsoft Corporation
Module Name:
r10math.c
Abstract:
This file contains a set of routines which will do arithmetic on
the 80-bit floating point format supported by the 80x87 family of
processors.
Author:
Jim Schaad (jimsch) 06-27-92
Environment:
Win32 - user mode
--*/
/*
* This is the constant 0 in the 80-bit format.
*/
FLOAT10 Real10_Zero = {0, 0, 0, 0, 0, 0, 0, 0, 0, 4};
int
R10Not(
FLOAT10 ld
)
/*++
Routine Description:
This function will compute the NOT of an 80-bit value.
Arguments:
ld - Supplies the long double to be NOT-ed
Return Value:
1 if ld is 0.0 and 0 otherwise
--*/
{
return 0; /* NOTENOTE jimsch return !ld */
} /* R10Not() */
void
R10Uminus(
FLOAT10 * pldDest,
FLOAT10 ldLeft
)
/*++
Routine Description:
This routine computes the uninary minus of a 80-bit real number.
Arguments:
pldDest - Supplies a pointer to the destination FLOAT10 buffer
ldLeft - Supplies the value to be negated.
Return Value:
None.
--*/
{
#ifdef i386
// NOTENOTE jimsch - need to try/except this code
_asm {
lea eax, ldLeft
fld tbyte ptr [eax] ; Load ldLeft on the float point chip;
fchs ;
mov eax, pldDest ;
fstp tbyte ptr [eax] ;
}
#else
#endif
return;
} /* R10Uminus() */
bool_t
R10Equal(
FLOAT10 ldLeft,
FLOAT10 ldRight
)
/*++
Routine Description:
This function will compare two 80-bit reals and return TRUE if
ldLeft == ldRight. This routine using an unorder compare on NANs.
Arguments:
ldLeft - Supplies long double to compare
ldRight - Supplies long double to compare
Return Value:
TRUE if the items are equal else FALSE
--*/
{
#ifdef i386
short sw;
_asm {
lea eax, ldLeft ;
fld tbyte ptr [eax] ;
lea eax, ldRight ;
fld tbyte ptr [eax] ;
fucompp ;
fstsw sw ;
}
if ((sw & 0x4700) == 0x04000) {
return TRUE;
}
return FALSE;
#else
return FALSE;
#endif
} /* R10Equal() */
bool_t
R10Lt(
FLOAT10 ldLeft,
FLOAT10 ldRight
)
/*++
Routine Description:
This function will compare two 80-bit reals and return TRUE if
ldLeft < ldRight. This routine uses an unordered compare on NANs
Arguments:
ldLeft - Supplies long double to compare
ldRight - Supplies long double to compare
Return Value:
TRUE if the items are equal else FALSE
--*/
{
#ifdef i386
short sw;
_asm {
lea eax, ldLeft ;
fld tbyte ptr [eax] ;
lea eax, ldRight ;
fld tbyte ptr [eax] ;
fucompp ;
fstsw sw ;
}
if ((sw & 0x4700) == 0x00000) {
return TRUE;
}
return FALSE;
#else
return FALSE;
#endif
} /* R10Lt() */
void
R10Plus(
FLOAT10 * pldResult,
FLOAT10 ldLeft,
FLOAT10 ldRight
)
/*++
Routine Description:
This function adds ldLeft and ldRight together and stores the result in
pldResult
Arguments:
pldResult - Supplies pointer to destination
ldLeft - Supplies parameter 1
ldRight - Supplies parameter 2
Return Value:
None.
--*/
{
#ifdef i386
_asm {
lea eax, ldLeft ;
fld tbyte ptr [eax] ;
lea eax, ldRight ;
fld tbyte ptr [eax] ;
faddp st(1),st
mov eax, pldResult ;
fstp tbyte ptr [eax] ;
}
#else
memcpy(pldResult, &ldLeft, sizeof(FLOAT10));
#endif
return;
} /* R10Plus() */
void
R10Minus(
FLOAT10 * pldResult,
FLOAT10 ldLeft,
FLOAT10 ldRight
)
/*++
Routine Description:
This function subtraces ldRight from ldLeft together and stores
the result in pldResult
Arguments:
pldResult - Supplies pointer to destination
ldLeft - Supplies parameter 1
ldRight - Supplies parameter 2
Return Value:
None.
--*/
{
#ifdef i386
_asm {
lea eax, ldLeft ;
fld tbyte ptr [eax] ;
lea eax, ldRight ;
fld tbyte ptr [eax] ;
fsubp st(1),st
mov eax, pldResult ;
fstp tbyte ptr [eax] ;
}
#else // i386
memcpy(pldResult, &ldLeft, sizeof(FLOAT10));
#endif // i386
return;
} /* R10Minus() */
void
R10Times(
FLOAT10 * pldResult,
FLOAT10 ldLeft,
FLOAT10 ldRight
)
/*++
Routine Description:
This function multiplies ldRight and ldLeft together and stores
the result in pldResult
Arguments:
pldResult - Supplies pointer to destination
ldLeft - Supplies parameter 1
ldRight - Supplies parameter 2
Return Value:
None.
--*/
{
#ifdef i386
_asm {
lea eax, ldLeft ;
fld tbyte ptr [eax] ;
lea eax, ldRight ;
fld tbyte ptr [eax] ;
fmulp st(1),st ;
mov eax, pldResult ;
fstp tbyte ptr [eax] ;
}
#else // i386
memcpy(pldResult, &ldLeft, sizeof(FLOAT10));
#endif // i386
return;
} /* R10Times() */
void
R10Divide(
FLOAT10 * pldResult,
FLOAT10 ldLeft,
FLOAT10 ldRight
)
/*++
Routine Description:
This function multiplies ldRight and ldLeft together and stores
the result in pldResult
Arguments:
pldResult - Supplies pointer to destination
ldLeft - Supplies parameter 1
ldRight - Supplies parameter 2
Return Value:
None.
--*/
{
#ifdef i386
_asm {
lea eax, ldLeft ;
fld tbyte ptr [eax] ;
lea eax, ldRight ;
fld tbyte ptr [eax] ;
fdivp st(1),st ;
mov eax, pldResult ;
fstp tbyte ptr [eax] ;
}
#else // i386
memcpy(pldResult, &ldLeft, sizeof(FLOAT10));
#endif // i386
return;
} /* R10Divide() */
double
R10CastToDouble(
FLOAT10 ld
)
/*++
Routine Description:
Convert the 80-bit real to a 64-bit real and return it
Arguments:
ld - Supplies the 80-bit real to convert
Return Value:
Returns the value ld in 64-bit format
--*/
{
#ifdef i386
double d;
_asm {
lea eax, ld
fld tbyte ptr [eax]
lea eax, d
fstp qword ptr [eax]
}
return d;
#else
return 0.0;
#endif
} /* R10CastToDouble() */
float
R10CastToFloat(
FLOAT10 ld
)
/*++
Routine Description:
Converts a 80-bit real number to a 32-bit real number
Arguments:
ld - Supplies 80-bit number to be converted
Return Value:
Returns the 32-bit equivalent value
--*/
{
#ifdef i386
float d;
_asm {
lea eax, ld
fld tbyte ptr [eax]
lea eax, d
fstp dword ptr [eax]
}
return d;
#else
return (float) 0.0;
#endif
} /* R10CastToFloat() */
long
R10CastToLong(
FLOAT10 ld
)
/*++
Routine Description:
Converts a 80-bit real number to a 32-bit long
Arguments:
ld - Supplies 80-bit number to be converted
Return Value:
returns 32-bit equvalent to ld
--*/
{
#ifdef i386
long d;
_asm {
lea eax, ld
fld tbyte ptr [eax]
lea eax, d
fistp dword ptr [eax]
}
return d;
#else
return 0;
#endif
} /* R10CastToLong() */
void
R10AssignDouble(
FLOAT10 * pld,
double d
)
/*++
Routine Description:
This function will assign a double to a 80-bit real
Arguments:
pld - Supplies pointer to destiniation buffer
d - Supplies the double to be assigned
Return Value:
None.
--*/
{
#ifdef i386
_asm {
lea eax, d
fld qword ptr [eax]
mov eax, pld
fstp tbyte ptr [eax]
}
#else
return;
#endif
} /* R10AssignDouble() */
void
R10AssignFloat(
FLOAT10 * pld,
float f
)
/*++
Routine Description:
This function will assign a float to a 80-bit real
Arguments:
pld - Supplies pointer to destiniation buffer
f - Supplies the float to be assigned
Return Value:
None.
--*/
{
return;
} /* R10AssignFloat() */