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=67818... ============================================================================== --- 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);