mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 18:52:57 +00:00
[FAST486]
Implement FYL2X and FYL2XP1. svn path=/trunk/; revision=67821
This commit is contained in:
parent
de0880752b
commit
b96fb17aab
1 changed files with 160 additions and 4 deletions
|
@ -1019,6 +1019,110 @@ Fast486FpuCalculateTwoPowerMinusOne(PFAST486_STATE State,
|
||||||
*Result = TempResult;
|
*Result = TempResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Calculates using the identities:
|
||||||
|
* log2(x) = log10(x) / log10(2)
|
||||||
|
* log10(x)= sum { -1^(n+1) * x^n / n!, n >= 1 }
|
||||||
|
*/
|
||||||
|
static inline BOOLEAN FASTCALL
|
||||||
|
Fast486FpuCalculateLogBase2(PFAST486_STATE State,
|
||||||
|
PFAST486_FPU_DATA_REG Operand,
|
||||||
|
PFAST486_FPU_DATA_REG Result)
|
||||||
|
{
|
||||||
|
INT i;
|
||||||
|
FAST486_FPU_DATA_REG Value = *Operand;
|
||||||
|
FAST486_FPU_DATA_REG SeriesElement;
|
||||||
|
FAST486_FPU_DATA_REG TempResult;
|
||||||
|
FAST486_FPU_DATA_REG TempValue;
|
||||||
|
LONGLONG UnbiasedExp = (LONGLONG)Operand->Exponent - FPU_REAL10_BIAS;
|
||||||
|
|
||||||
|
if (Operand->Sign)
|
||||||
|
{
|
||||||
|
/* Raise the invalid operation exception */
|
||||||
|
State->FpuStatus.Ie = TRUE;
|
||||||
|
|
||||||
|
if (State->FpuControl.Im)
|
||||||
|
{
|
||||||
|
/* Return the indefinite NaN */
|
||||||
|
Result->Sign = TRUE;
|
||||||
|
Result->Exponent = FPU_MAX_EXPONENT + 1;
|
||||||
|
Result->Mantissa = FPU_INDEFINITE_MANTISSA;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Fast486FpuException(State);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get only the mantissa as a floating-pointer number between 1 and 2 */
|
||||||
|
Value.Exponent = FPU_REAL10_BIAS;
|
||||||
|
|
||||||
|
/* Check if it's denormalized */
|
||||||
|
if (!FPU_IS_NORMALIZED(&Value))
|
||||||
|
{
|
||||||
|
ULONG Bits;
|
||||||
|
State->FpuStatus.De = TRUE;
|
||||||
|
|
||||||
|
if (!State->FpuControl.Dm)
|
||||||
|
{
|
||||||
|
Fast486FpuException(State);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Normalize the number */
|
||||||
|
Bits = CountLeadingZeros64(Value.Mantissa);
|
||||||
|
UnbiasedExp -= Bits;
|
||||||
|
Value.Mantissa <<= Bits;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Subtract one from the value */
|
||||||
|
if (!Fast486FpuSubtract(State, &Value, &FpuOne, &Value)) return FALSE;
|
||||||
|
|
||||||
|
/* Calculate the base 10 logarithm */
|
||||||
|
SeriesElement = TempResult = Value;
|
||||||
|
|
||||||
|
for (i = 2; i < INVERSE_NUMBERS_COUNT / 2; i++)
|
||||||
|
{
|
||||||
|
if (!Fast486FpuMultiply(State, &SeriesElement, &Value, &SeriesElement))
|
||||||
|
{
|
||||||
|
/* An exception occurred */
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Toggle the sign of the series element */
|
||||||
|
SeriesElement.Sign = !SeriesElement.Sign;
|
||||||
|
|
||||||
|
/* Divide it by the counter */
|
||||||
|
if (!Fast486FpuMultiply(State, &SeriesElement, &FpuInverseNumber[i - 1], &TempValue))
|
||||||
|
{
|
||||||
|
/* An exception occurred */
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* And add it to the result */
|
||||||
|
if (!Fast486FpuAdd(State, &TempResult, &TempValue, &TempResult))
|
||||||
|
{
|
||||||
|
/* An exception occurred */
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now convert the base 10 logarithm into a base 2 logarithm */
|
||||||
|
if (!Fast486FpuDivide(State, &TempResult, &FpuLgTwo, &TempResult)) return FALSE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add the exponent to the result
|
||||||
|
* log2(x * 2^y) = log2(x) + log2(2^y) = log2(x) + y
|
||||||
|
*/
|
||||||
|
Fast486FpuFromInteger(State, UnbiasedExp, &TempValue);
|
||||||
|
if (!Fast486FpuAdd(State, &TempValue, &TempResult, &TempResult)) return FALSE;
|
||||||
|
|
||||||
|
*Result = TempResult;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Calculates using the identity:
|
* Calculates using the identity:
|
||||||
* sin(x) = sum { -1^n * x^(2n + 1) / (2n + 1)!, n >= 0 }
|
* sin(x) = sum { -1^n * x^(2n + 1) / (2n + 1)!, n >= 0 }
|
||||||
|
@ -1726,8 +1830,31 @@ FAST486_OPCODE_HANDLER(Fast486FpuOpcodeD9)
|
||||||
/* FYL2X */
|
/* FYL2X */
|
||||||
case 0x31:
|
case 0x31:
|
||||||
{
|
{
|
||||||
// TODO: NOT IMPLEMENTED
|
FAST486_FPU_DATA_REG Logarithm;
|
||||||
UNIMPLEMENTED;
|
|
||||||
|
if (FPU_GET_TAG(0) == FPU_TAG_EMPTY || FPU_GET_TAG(1) == FPU_TAG_EMPTY)
|
||||||
|
{
|
||||||
|
State->FpuStatus.Ie = TRUE;
|
||||||
|
|
||||||
|
if (!State->FpuControl.Im) Fast486FpuException(State);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Fast486FpuCalculateLogBase2(State, &FPU_ST(0), &Logarithm))
|
||||||
|
{
|
||||||
|
/* Exception occurred */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Fast486FpuMultiply(State, &Logarithm, &FPU_ST(1), &FPU_ST(1)))
|
||||||
|
{
|
||||||
|
/* Exception occurred */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Pop the stack so that the result ends up in ST0 */
|
||||||
|
Fast486FpuPop(State);
|
||||||
|
FPU_UPDATE_TAG(0);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1828,8 +1955,37 @@ FAST486_OPCODE_HANDLER(Fast486FpuOpcodeD9)
|
||||||
/* FYL2XP1 */
|
/* FYL2XP1 */
|
||||||
case 0x39:
|
case 0x39:
|
||||||
{
|
{
|
||||||
// TODO: NOT IMPLEMENTED
|
FAST486_FPU_DATA_REG Value, Logarithm;
|
||||||
UNIMPLEMENTED;
|
|
||||||
|
if (FPU_GET_TAG(0) == FPU_TAG_EMPTY || FPU_GET_TAG(1) == FPU_TAG_EMPTY)
|
||||||
|
{
|
||||||
|
State->FpuStatus.Ie = TRUE;
|
||||||
|
|
||||||
|
if (!State->FpuControl.Im) Fast486FpuException(State);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Fast486FpuAdd(State, &FPU_ST(0), &FpuOne, &Value))
|
||||||
|
{
|
||||||
|
/* Exception occurred */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Fast486FpuCalculateLogBase2(State, &Value, &Logarithm))
|
||||||
|
{
|
||||||
|
/* Exception occurred */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Fast486FpuMultiply(State, &Logarithm, &FPU_ST(1), &FPU_ST(1)))
|
||||||
|
{
|
||||||
|
/* Exception occurred */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Pop the stack so that the result ends up in ST0 */
|
||||||
|
Fast486FpuPop(State);
|
||||||
|
FPU_UPDATE_TAG(0);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue