[FAST486]

Fix F2XM1.
Implement FSIN, FCOS and FSINCOS.


svn path=/trunk/; revision=67817
This commit is contained in:
Aleksandar Andrejevic 2015-05-17 19:48:57 +00:00
parent df9f3a9e44
commit 5be848439a
2 changed files with 153 additions and 12 deletions

View file

@ -75,6 +75,36 @@ static const FAST486_FPU_DATA_REG FpuInverseNumber[INVERSE_NUMBERS_COUNT] =
{0xE38E38E38E38E38EULL, FPU_REAL10_BIAS - 5, FALSE}, /* 1 / 18 */ {0xE38E38E38E38E38EULL, FPU_REAL10_BIAS - 5, FALSE}, /* 1 / 18 */
{0xD79435E50D79435EULL, FPU_REAL10_BIAS - 5, FALSE}, /* 1 / 19 */ {0xD79435E50D79435EULL, FPU_REAL10_BIAS - 5, FALSE}, /* 1 / 19 */
{0xCCCCCCCCCCCCCCCDULL, FPU_REAL10_BIAS - 5, FALSE}, /* 1 / 20 */ {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 **********************************************************/ /* PRIVATE FUNCTIONS **********************************************************/
@ -953,11 +983,11 @@ Fast486FpuCalculateTwoPowerMinusOne(PFAST486_STATE State,
FAST486_FPU_DATA_REG SeriesElement; FAST486_FPU_DATA_REG SeriesElement;
/* Calculate the first series element, which is 2 * (x - 1) * ln(2) */ /* Calculate the first series element, which is 2 * (x - 1) * ln(2) */
Fast486FpuSubtract(State, Operand, &FpuOne, &Value); if (!Fast486FpuSubtract(State, Operand, &FpuOne, &Value)) return;
Fast486FpuMultiply(State, &Value, &FpuLnTwo, &Value); if (!Fast486FpuMultiply(State, &Value, &FpuLnTwo, &Value)) return;
Fast486FpuAdd(State, &Value, &Value, &SeriesElement); 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 */ /* Add the series element to the final sum */
if (!Fast486FpuAdd(State, &TempResult, &SeriesElement, &TempResult)) if (!Fast486FpuAdd(State, &TempResult, &SeriesElement, &TempResult))
@ -977,7 +1007,10 @@ Fast486FpuCalculateTwoPowerMinusOne(PFAST486_STATE State,
} }
/* And now multiply the series element by the inverse counter */ /* 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 */ /* An exception occurred */
return; return;
@ -987,6 +1020,102 @@ Fast486FpuCalculateTwoPowerMinusOne(PFAST486_STATE State,
*Result = TempResult; *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 static inline VOID FASTCALL
Fast486FpuArithmeticOperation(PFAST486_STATE State, Fast486FpuArithmeticOperation(PFAST486_STATE State,
INT Operation, INT Operation,
@ -1699,8 +1828,16 @@ FAST486_OPCODE_HANDLER(Fast486FpuOpcodeD9)
/* FSINCOS */ /* FSINCOS */
case 0x3B: case 0x3B:
{ {
// TODO: NOT IMPLEMENTED FAST486_FPU_DATA_REG Number = FPU_ST(0);
UNIMPLEMENTED; 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; break;
} }
@ -1762,8 +1899,10 @@ FAST486_OPCODE_HANDLER(Fast486FpuOpcodeD9)
/* FSIN */ /* FSIN */
case 0x3E: case 0x3E:
{ {
// TODO: NOT IMPLEMENTED FPU_SAVE_LAST_INST();
UNIMPLEMENTED;
Fast486FpuCalculateSine(State, &FPU_ST(0), &FPU_ST(0));
FPU_UPDATE_TAG(0);
break; break;
} }
@ -1771,8 +1910,10 @@ FAST486_OPCODE_HANDLER(Fast486FpuOpcodeD9)
/* FCOS */ /* FCOS */
case 0x3F: case 0x3F:
{ {
// TODO: NOT IMPLEMENTED FPU_SAVE_LAST_INST();
UNIMPLEMENTED;
Fast486FpuCalculateCosine(State, &FPU_ST(0), &FPU_ST(0));
FPU_UPDATE_TAG(0);
break; break;
} }

View file

@ -71,7 +71,7 @@
#define FPU_IS_NEG_INF(x) (FPU_IS_INFINITY(x) && (x)->Sign) #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 FPU_IS_INDEFINITE(x) (FPU_IS_NAN(x) && !FPU_IS_INFINITY(x))
#define INVERSE_NUMBERS_COUNT 21 #define INVERSE_NUMBERS_COUNT 50
enum enum
{ {