mirror of
https://github.com/reactos/reactos.git
synced 2025-05-18 16:51:18 +00:00
[FAST486]
Fix F2XM1. Implement FSIN, FCOS and FSINCOS. svn path=/trunk/; revision=67817
This commit is contained in:
parent
df9f3a9e44
commit
5be848439a
2 changed files with 153 additions and 12 deletions
|
@ -75,6 +75,36 @@ static const FAST486_FPU_DATA_REG FpuInverseNumber[INVERSE_NUMBERS_COUNT] =
|
|||
{0xE38E38E38E38E38EULL, FPU_REAL10_BIAS - 5, FALSE}, /* 1 / 18 */
|
||||
{0xD79435E50D79435EULL, FPU_REAL10_BIAS - 5, FALSE}, /* 1 / 19 */
|
||||
{0xCCCCCCCCCCCCCCCDULL, FPU_REAL10_BIAS - 5, FALSE}, /* 1 / 20 */
|
||||
{0xC30C30C30C30C30CULL, FPU_REAL10_BIAS - 5, FALSE}, /* 1 / 21 */
|
||||
{0xBA2E8BA2E8BA2E8BULL, FPU_REAL10_BIAS - 5, FALSE}, /* 1 / 22 */
|
||||
{0xB21642C8590B2164ULL, FPU_REAL10_BIAS - 5, FALSE}, /* 1 / 23 */
|
||||
{0xAAAAAAAAAAAAAAABULL, FPU_REAL10_BIAS - 5, FALSE}, /* 1 / 24 */
|
||||
{0xA3D70A3D70A3D70AULL, FPU_REAL10_BIAS - 5, FALSE}, /* 1 / 25 */
|
||||
{0x9D89D89D89D89D8AULL, FPU_REAL10_BIAS - 5, FALSE}, /* 1 / 26 */
|
||||
{0x97B425ED097B425FULL, FPU_REAL10_BIAS - 5, FALSE}, /* 1 / 27 */
|
||||
{0x9249249249249249ULL, FPU_REAL10_BIAS - 5, FALSE}, /* 1 / 28 */
|
||||
{0x8D3DCB08D3DCB08DULL, FPU_REAL10_BIAS - 5, FALSE}, /* 1 / 29 */
|
||||
{0x8888888888888889ULL, FPU_REAL10_BIAS - 5, FALSE}, /* 1 / 30 */
|
||||
{0x8421084210842108ULL, FPU_REAL10_BIAS - 5, FALSE}, /* 1 / 31 */
|
||||
{0x8000000000000000ULL, FPU_REAL10_BIAS - 5, FALSE}, /* 1 / 32 */
|
||||
{0xF83E0F83E0F83E0FULL, FPU_REAL10_BIAS - 6, FALSE}, /* 1 / 33 */
|
||||
{0xF0F0F0F0F0F0F0F0ULL, FPU_REAL10_BIAS - 6, FALSE}, /* 1 / 34 */
|
||||
{0xEA0EA0EA0EA0EA0EULL, FPU_REAL10_BIAS - 6, FALSE}, /* 1 / 35 */
|
||||
{0xE38E38E38E38E38EULL, FPU_REAL10_BIAS - 6, FALSE}, /* 1 / 36 */
|
||||
{0xDD67C8A60DD67C8AULL, FPU_REAL10_BIAS - 6, FALSE}, /* 1 / 37 */
|
||||
{0xD79435E50D79435EULL, FPU_REAL10_BIAS - 6, FALSE}, /* 1 / 38 */
|
||||
{0xD20D20D20D20D20DULL, FPU_REAL10_BIAS - 6, FALSE}, /* 1 / 39 */
|
||||
{0xCCCCCCCCCCCCCCCDULL, FPU_REAL10_BIAS - 6, FALSE}, /* 1 / 40 */
|
||||
{0xC7CE0C7CE0C7CE0CULL, FPU_REAL10_BIAS - 6, FALSE}, /* 1 / 41 */
|
||||
{0xC30C30C30C30C30CULL, FPU_REAL10_BIAS - 6, FALSE}, /* 1 / 42 */
|
||||
{0xBE82FA0BE82FA0BFULL, FPU_REAL10_BIAS - 6, FALSE}, /* 1 / 43 */
|
||||
{0xBA2E8BA2E8BA2E8BULL, FPU_REAL10_BIAS - 6, FALSE}, /* 1 / 44 */
|
||||
{0xB60B60B60B60B60BULL, FPU_REAL10_BIAS - 6, FALSE}, /* 1 / 45 */
|
||||
{0xB21642C8590B2164ULL, FPU_REAL10_BIAS - 6, FALSE}, /* 1 / 46 */
|
||||
{0xAE4C415C9882B931ULL, FPU_REAL10_BIAS - 6, FALSE}, /* 1 / 47 */
|
||||
{0xAAAAAAAAAAAAAAABULL, FPU_REAL10_BIAS - 6, FALSE}, /* 1 / 48 */
|
||||
{0xA72F05397829CBC1ULL, FPU_REAL10_BIAS - 6, FALSE}, /* 1 / 49 */
|
||||
{0xA3D70A3D70A3D70AULL, FPU_REAL10_BIAS - 6, FALSE}, /* 1 / 50 */
|
||||
};
|
||||
|
||||
/* PRIVATE FUNCTIONS **********************************************************/
|
||||
|
@ -953,11 +983,11 @@ Fast486FpuCalculateTwoPowerMinusOne(PFAST486_STATE State,
|
|||
FAST486_FPU_DATA_REG SeriesElement;
|
||||
|
||||
/* Calculate the first series element, which is 2 * (x - 1) * ln(2) */
|
||||
Fast486FpuSubtract(State, Operand, &FpuOne, &Value);
|
||||
Fast486FpuMultiply(State, &Value, &FpuLnTwo, &Value);
|
||||
Fast486FpuAdd(State, &Value, &Value, &SeriesElement);
|
||||
if (!Fast486FpuSubtract(State, Operand, &FpuOne, &Value)) return;
|
||||
if (!Fast486FpuMultiply(State, &Value, &FpuLnTwo, &Value)) return;
|
||||
if (!Fast486FpuAdd(State, &Value, &Value, &SeriesElement)) return;
|
||||
|
||||
for (i = 2; i < INVERSE_NUMBERS_COUNT; i++)
|
||||
for (i = 2; i <= INVERSE_NUMBERS_COUNT / 2; i++)
|
||||
{
|
||||
/* Add the series element to the final sum */
|
||||
if (!Fast486FpuAdd(State, &TempResult, &SeriesElement, &TempResult))
|
||||
|
@ -977,7 +1007,10 @@ Fast486FpuCalculateTwoPowerMinusOne(PFAST486_STATE State,
|
|||
}
|
||||
|
||||
/* And now multiply the series element by the inverse counter */
|
||||
if (!Fast486FpuMultiply(State, &SeriesElement, &FpuInverseNumber[i], &SeriesElement))
|
||||
if (!Fast486FpuMultiply(State,
|
||||
&SeriesElement,
|
||||
&FpuInverseNumber[i - 1],
|
||||
&SeriesElement))
|
||||
{
|
||||
/* An exception occurred */
|
||||
return;
|
||||
|
@ -987,6 +1020,102 @@ Fast486FpuCalculateTwoPowerMinusOne(PFAST486_STATE State,
|
|||
*Result = TempResult;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculates using the identity:
|
||||
* sin(x) = sum { -1^n * x^(2n + 1) / (2n + 1)!, n >= 0 }
|
||||
*/
|
||||
static inline BOOLEAN FASTCALL
|
||||
Fast486FpuCalculateSine(PFAST486_STATE State,
|
||||
PFAST486_FPU_DATA_REG Operand,
|
||||
PFAST486_FPU_DATA_REG Result)
|
||||
{
|
||||
INT i;
|
||||
FAST486_FPU_DATA_REG TempResult = *Operand;
|
||||
FAST486_FPU_DATA_REG OperandSquared = *Operand;
|
||||
FAST486_FPU_DATA_REG SeriesElement = *Operand;
|
||||
|
||||
/* Calculate the square of the operand */
|
||||
if (!Fast486FpuMultiply(State, Operand, Operand, &OperandSquared)) return FALSE;
|
||||
|
||||
for (i = 2; (i * (i + 1)) <= INVERSE_NUMBERS_COUNT; i += 2)
|
||||
{
|
||||
if (!Fast486FpuMultiply(State, &SeriesElement, &OperandSquared, &SeriesElement))
|
||||
{
|
||||
/* An exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!Fast486FpuMultiply(State,
|
||||
&SeriesElement,
|
||||
&FpuInverseNumber[i * (i + 1) - 1],
|
||||
&SeriesElement))
|
||||
{
|
||||
/* An exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Toggle the sign of the series element */
|
||||
SeriesElement.Sign = !SeriesElement.Sign;
|
||||
|
||||
if (!Fast486FpuAdd(State, &TempResult, &SeriesElement, &TempResult))
|
||||
{
|
||||
/* An exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
*Result = TempResult;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculates using the identity:
|
||||
* cos(x) = sum { -1^n * x^(2n) / (2n)!, n >= 0 }
|
||||
*/
|
||||
static inline BOOLEAN FASTCALL
|
||||
Fast486FpuCalculateCosine(PFAST486_STATE State,
|
||||
PFAST486_FPU_DATA_REG Operand,
|
||||
PFAST486_FPU_DATA_REG Result)
|
||||
{
|
||||
INT i;
|
||||
FAST486_FPU_DATA_REG TempResult = FpuOne;
|
||||
FAST486_FPU_DATA_REG OperandSquared = *Operand;
|
||||
FAST486_FPU_DATA_REG SeriesElement = FpuOne;
|
||||
|
||||
/* Calculate the square of the operand */
|
||||
if (!Fast486FpuMultiply(State, Operand, Operand, &OperandSquared)) return FALSE;
|
||||
|
||||
for (i = 1; (i * (i + 1)) <= INVERSE_NUMBERS_COUNT; i += 2)
|
||||
{
|
||||
if (!Fast486FpuMultiply(State, &SeriesElement, &OperandSquared, &SeriesElement))
|
||||
{
|
||||
/* An exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!Fast486FpuMultiply(State,
|
||||
&SeriesElement,
|
||||
&FpuInverseNumber[i * (i + 1) - 1],
|
||||
&SeriesElement))
|
||||
{
|
||||
/* An exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Toggle the sign of the series element */
|
||||
SeriesElement.Sign = !SeriesElement.Sign;
|
||||
|
||||
if (!Fast486FpuAdd(State, &TempResult, &SeriesElement, &TempResult))
|
||||
{
|
||||
/* An exception occurred */
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
*Result = TempResult;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static inline VOID FASTCALL
|
||||
Fast486FpuArithmeticOperation(PFAST486_STATE State,
|
||||
INT Operation,
|
||||
|
@ -1699,8 +1828,16 @@ FAST486_OPCODE_HANDLER(Fast486FpuOpcodeD9)
|
|||
/* FSINCOS */
|
||||
case 0x3B:
|
||||
{
|
||||
// TODO: NOT IMPLEMENTED
|
||||
UNIMPLEMENTED;
|
||||
FAST486_FPU_DATA_REG Number = FPU_ST(0);
|
||||
FPU_SAVE_LAST_INST();
|
||||
|
||||
/* Replace FP0 with the sine */
|
||||
if (!Fast486FpuCalculateSine(State, &Number, &FPU_ST(0))) break;
|
||||
FPU_UPDATE_TAG(0);
|
||||
|
||||
/* Push the cosine */
|
||||
if (!Fast486FpuCalculateCosine(State, &Number, &Number)) break;
|
||||
Fast486FpuPush(State, &Number);
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -1762,8 +1899,10 @@ FAST486_OPCODE_HANDLER(Fast486FpuOpcodeD9)
|
|||
/* FSIN */
|
||||
case 0x3E:
|
||||
{
|
||||
// TODO: NOT IMPLEMENTED
|
||||
UNIMPLEMENTED;
|
||||
FPU_SAVE_LAST_INST();
|
||||
|
||||
Fast486FpuCalculateSine(State, &FPU_ST(0), &FPU_ST(0));
|
||||
FPU_UPDATE_TAG(0);
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -1771,8 +1910,10 @@ FAST486_OPCODE_HANDLER(Fast486FpuOpcodeD9)
|
|||
/* FCOS */
|
||||
case 0x3F:
|
||||
{
|
||||
// TODO: NOT IMPLEMENTED
|
||||
UNIMPLEMENTED;
|
||||
FPU_SAVE_LAST_INST();
|
||||
|
||||
Fast486FpuCalculateCosine(State, &FPU_ST(0), &FPU_ST(0));
|
||||
FPU_UPDATE_TAG(0);
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@
|
|||
#define FPU_IS_NEG_INF(x) (FPU_IS_INFINITY(x) && (x)->Sign)
|
||||
#define FPU_IS_INDEFINITE(x) (FPU_IS_NAN(x) && !FPU_IS_INFINITY(x))
|
||||
|
||||
#define INVERSE_NUMBERS_COUNT 21
|
||||
#define INVERSE_NUMBERS_COUNT 50
|
||||
|
||||
enum
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue