Author: aandrejevic
Date: Sun May 17 21:52:12 2015
New Revision: 67818
URL:
http://svn.reactos.org/svn/reactos?rev=67818&view=rev
Log:
[FAST486]
- Don't forget to check whether the FPU stack element exists before using it.
- Implement FSCALE.
Modified:
trunk/reactos/lib/fast486/fpu.c
Modified: trunk/reactos/lib/fast486/fpu.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/fast486/fpu.c?rev=6781…
==============================================================================
--- trunk/reactos/lib/fast486/fpu.c [iso-8859-1] (original)
+++ trunk/reactos/lib/fast486/fpu.c [iso-8859-1] Sun May 17 21:52:12 2015
@@ -1699,156 +1699,6 @@
{
FPU_SAVE_LAST_INST();
- Fast486FpuCalculateTwoPowerMinusOne(State, &FPU_ST(0),
&FPU_ST(0));
- FPU_UPDATE_TAG(0);
-
- break;
- }
-
- /* FYL2X */
- case 0x31:
- {
- // TODO: NOT IMPLEMENTED
- UNIMPLEMENTED;
-
- break;
- }
-
- /* FPTAN */
- case 0x32:
- {
- // TODO: NOT IMPLEMENTED
- UNIMPLEMENTED;
-
- break;
- }
-
- /* FPATAN */
- case 0x33:
- {
- // TODO: NOT IMPLEMENTED
- UNIMPLEMENTED;
-
- break;
- }
-
- /* FXTRACT */
- case 0x34:
- {
- FAST486_FPU_DATA_REG Value = FPU_ST(0);
-
- if ((FPU_GET_TAG(0) == FPU_TAG_EMPTY) || FPU_IS_INDEFINITE(&Value))
- {
- State->FpuStatus.Ie = TRUE;
- if (FPU_GET_TAG(0) == FPU_TAG_EMPTY) State->FpuStatus.Sf = TRUE;
-
- if (!State->FpuControl.Im) Fast486FpuException(State);
- break;
- }
-
- if (FPU_IS_ZERO(&Value))
- {
- /* The exponent of zero is negative infinity */
- FPU_ST(0).Sign = TRUE;
- FPU_ST(0).Exponent = FPU_MAX_EXPONENT + 1;
- FPU_ST(0).Mantissa = FPU_MANTISSA_HIGH_BIT;
- }
- else if (FPU_IS_INFINITY(&Value))
- {
- /* The exponent of infinity is positive infinity */
- FPU_ST(0).Sign = FALSE;
- FPU_ST(0).Exponent = FPU_MAX_EXPONENT + 1;
- FPU_ST(0).Mantissa = FPU_MANTISSA_HIGH_BIT;
- }
- else
- {
- /* Store the unbiased exponent in ST0 */
- Fast486FpuFromInteger(State,
- (LONGLONG)Value.Exponent -
(LONGLONG)FPU_REAL10_BIAS,
- &FPU_ST(0));
- }
-
- /* Now push the mantissa as a real number, with the original sign */
- Value.Exponent = FPU_REAL10_BIAS;
- Fast486FpuPush(State, &Value);
-
- break;
- }
-
- /* FPREM1 */
- case 0x35:
- {
- // TODO: NOT IMPLEMENTED
- UNIMPLEMENTED;
-
- break;
- }
-
- /* FDECSTP */
- case 0x36:
- {
- State->FpuStatus.Top--;
- break;
- }
-
- /* FINCSTP */
- case 0x37:
- {
- State->FpuStatus.Top++;
- break;
- }
-
- /* FPREM */
- case 0x38:
- {
- // TODO: NOT IMPLEMENTED
- UNIMPLEMENTED;
-
- break;
- }
-
- /* FYL2XP1 */
- case 0x39:
- {
- // TODO: NOT IMPLEMENTED
- UNIMPLEMENTED;
-
- break;
- }
-
- /* FSQRT */
- case 0x3A:
- {
- // TODO: NOT IMPLEMENTED
- UNIMPLEMENTED;
-
- break;
- }
-
- /* FSINCOS */
- case 0x3B:
- {
- 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;
- }
-
- /* FRNDINT */
- case 0x3C:
- {
- INT Bits;
- ULONGLONG Result = 0ULL;
- ULONGLONG Remainder;
-
if (FPU_GET_TAG(0) == FPU_TAG_EMPTY)
{
State->FpuStatus.Ie = TRUE;
@@ -1868,6 +1718,194 @@
}
}
+ Fast486FpuCalculateTwoPowerMinusOne(State, &FPU_ST(0),
&FPU_ST(0));
+ FPU_UPDATE_TAG(0);
+
+ break;
+ }
+
+ /* FYL2X */
+ case 0x31:
+ {
+ // TODO: NOT IMPLEMENTED
+ UNIMPLEMENTED;
+
+ break;
+ }
+
+ /* FPTAN */
+ case 0x32:
+ {
+ // TODO: NOT IMPLEMENTED
+ UNIMPLEMENTED;
+
+ break;
+ }
+
+ /* FPATAN */
+ case 0x33:
+ {
+ // TODO: NOT IMPLEMENTED
+ UNIMPLEMENTED;
+
+ break;
+ }
+
+ /* FXTRACT */
+ case 0x34:
+ {
+ FAST486_FPU_DATA_REG Value = FPU_ST(0);
+
+ if ((FPU_GET_TAG(0) == FPU_TAG_EMPTY) || FPU_IS_INDEFINITE(&Value))
+ {
+ State->FpuStatus.Ie = TRUE;
+ if (FPU_GET_TAG(0) == FPU_TAG_EMPTY) State->FpuStatus.Sf = TRUE;
+
+ if (!State->FpuControl.Im) Fast486FpuException(State);
+ break;
+ }
+
+ if (FPU_IS_ZERO(&Value))
+ {
+ /* The exponent of zero is negative infinity */
+ FPU_ST(0).Sign = TRUE;
+ FPU_ST(0).Exponent = FPU_MAX_EXPONENT + 1;
+ FPU_ST(0).Mantissa = FPU_MANTISSA_HIGH_BIT;
+ }
+ else if (FPU_IS_INFINITY(&Value))
+ {
+ /* The exponent of infinity is positive infinity */
+ FPU_ST(0).Sign = FALSE;
+ FPU_ST(0).Exponent = FPU_MAX_EXPONENT + 1;
+ FPU_ST(0).Mantissa = FPU_MANTISSA_HIGH_BIT;
+ }
+ else
+ {
+ /* Store the unbiased exponent in ST0 */
+ Fast486FpuFromInteger(State,
+ (LONGLONG)Value.Exponent -
(LONGLONG)FPU_REAL10_BIAS,
+ &FPU_ST(0));
+ }
+
+ /* Now push the mantissa as a real number, with the original sign */
+ Value.Exponent = FPU_REAL10_BIAS;
+ Fast486FpuPush(State, &Value);
+
+ break;
+ }
+
+ /* FPREM1 */
+ case 0x35:
+ {
+ // TODO: NOT IMPLEMENTED
+ UNIMPLEMENTED;
+
+ break;
+ }
+
+ /* FDECSTP */
+ case 0x36:
+ {
+ State->FpuStatus.Top--;
+ break;
+ }
+
+ /* FINCSTP */
+ case 0x37:
+ {
+ State->FpuStatus.Top++;
+ break;
+ }
+
+ /* FPREM */
+ case 0x38:
+ {
+ // TODO: NOT IMPLEMENTED
+ UNIMPLEMENTED;
+
+ break;
+ }
+
+ /* FYL2XP1 */
+ case 0x39:
+ {
+ // TODO: NOT IMPLEMENTED
+ UNIMPLEMENTED;
+
+ break;
+ }
+
+ /* FSQRT */
+ case 0x3A:
+ {
+ // TODO: NOT IMPLEMENTED
+ UNIMPLEMENTED;
+
+ break;
+ }
+
+ /* FSINCOS */
+ case 0x3B:
+ {
+ FAST486_FPU_DATA_REG Number = FPU_ST(0);
+ FPU_SAVE_LAST_INST();
+
+ if (FPU_GET_TAG(0) == FPU_TAG_EMPTY)
+ {
+ State->FpuStatus.Ie = TRUE;
+
+ if (!State->FpuControl.Im) Fast486FpuException(State);
+ break;
+ }
+
+ if (!FPU_IS_NORMALIZED(&FPU_ST(0)))
+ {
+ State->FpuStatus.De = TRUE;
+
+ if (!State->FpuControl.Dm)
+ {
+ Fast486FpuException(State);
+ break;
+ }
+ }
+
+ /* 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;
+ }
+
+ /* FRNDINT */
+ case 0x3C:
+ {
+ INT Bits;
+ ULONGLONG Result = 0ULL;
+ ULONGLONG Remainder;
+
+ if (FPU_GET_TAG(0) == FPU_TAG_EMPTY)
+ {
+ State->FpuStatus.Ie = TRUE;
+
+ if (!State->FpuControl.Im) Fast486FpuException(State);
+ break;
+ }
+
+ if (!FPU_IS_NORMALIZED(&FPU_ST(0)))
+ {
+ State->FpuStatus.De = TRUE;
+
+ if (!State->FpuControl.Dm)
+ {
+ Fast486FpuException(State);
+ break;
+ }
+ }
+
Bits = min(max(0, (INT)FPU_ST(0).Exponent - FPU_REAL10_BIAS + 1), 64);
if (Bits == 64) break;
@@ -1890,8 +1928,82 @@
/* FSCALE */
case 0x3D:
{
- // TODO: NOT IMPLEMENTED
- UNIMPLEMENTED;
+ LONGLONG Scale;
+ LONGLONG UnbiasedExp = (LONGLONG)((SHORT)FPU_ST(0).Exponent) -
FPU_REAL10_BIAS;
+
+ FPU_SAVE_LAST_INST();
+
+ 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 (!FPU_IS_NORMALIZED(&FPU_ST(0)))
+ {
+ State->FpuStatus.De = TRUE;
+
+ if (!State->FpuControl.Dm)
+ {
+ Fast486FpuException(State);
+ break;
+ }
+ }
+
+ if (!Fast486FpuToInteger(State, &FPU_ST(1), &Scale))
+ {
+ /* Exception occurred */
+ break;
+ }
+
+ /* Adjust the unbiased exponent */
+ UnbiasedExp += Scale;
+
+ /* Check for underflow */
+ if (UnbiasedExp < -1023)
+ {
+ /* Raise the underflow exception */
+ State->FpuStatus.Ue = TRUE;
+
+ if (State->FpuControl.Um)
+ {
+ /* Make the result zero */
+ FPU_ST(0) = FpuZero;
+ FPU_UPDATE_TAG(0);
+ }
+ else
+ {
+ Fast486FpuException(State);
+ }
+
+ break;
+ }
+
+ /* Check for overflow */
+ if (UnbiasedExp > 1023)
+ {
+ /* Raise the overflow exception */
+ State->FpuStatus.Oe = TRUE;
+
+ if (State->FpuControl.Om)
+ {
+ /* Make the result infinity */
+ FPU_ST(0).Mantissa = FPU_MANTISSA_HIGH_BIT;
+ FPU_ST(0).Exponent = FPU_MAX_EXPONENT + 1;
+ FPU_UPDATE_TAG(0);
+ }
+ else
+ {
+ Fast486FpuException(State);
+ }
+
+ break;
+ }
+
+ FPU_ST(0).Exponent = (USHORT)(UnbiasedExp + FPU_REAL10_BIAS);
+ FPU_UPDATE_TAG(0);
break;
}
@@ -1901,6 +2013,25 @@
{
FPU_SAVE_LAST_INST();
+ if (FPU_GET_TAG(0) == FPU_TAG_EMPTY)
+ {
+ State->FpuStatus.Ie = TRUE;
+
+ if (!State->FpuControl.Im) Fast486FpuException(State);
+ break;
+ }
+
+ if (!FPU_IS_NORMALIZED(&FPU_ST(0)))
+ {
+ State->FpuStatus.De = TRUE;
+
+ if (!State->FpuControl.Dm)
+ {
+ Fast486FpuException(State);
+ break;
+ }
+ }
+
Fast486FpuCalculateSine(State, &FPU_ST(0), &FPU_ST(0));
FPU_UPDATE_TAG(0);
@@ -1911,6 +2042,25 @@
case 0x3F:
{
FPU_SAVE_LAST_INST();
+
+ if (FPU_GET_TAG(0) == FPU_TAG_EMPTY)
+ {
+ State->FpuStatus.Ie = TRUE;
+
+ if (!State->FpuControl.Im) Fast486FpuException(State);
+ break;
+ }
+
+ if (!FPU_IS_NORMALIZED(&FPU_ST(0)))
+ {
+ State->FpuStatus.De = TRUE;
+
+ if (!State->FpuControl.Dm)
+ {
+ Fast486FpuException(State);
+ break;
+ }
+ }
Fast486FpuCalculateCosine(State, &FPU_ST(0), &FPU_ST(0));
FPU_UPDATE_TAG(0);