Author: aandrejevic
Date: Tue Feb 10 17:29:26 2015
New Revision: 66216
URL:
http://svn.reactos.org/svn/reactos?rev=66216&view=rev
Log:
[FAST486]
Implement Fast486FpuMultiply properly.
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=6621…
==============================================================================
--- trunk/reactos/lib/fast486/fpu.c [iso-8859-1] (original)
+++ trunk/reactos/lib/fast486/fpu.c [iso-8859-1] Tue Feb 10 17:29:26 2015
@@ -696,6 +696,37 @@
PFAST486_FPU_DATA_REG Result)
{
FAST486_FPU_DATA_REG TempResult;
+ LONG Exponent;
+
+ if (FPU_IS_INDEFINITE(FirstOperand)
+ || FPU_IS_INDEFINITE(SecondOperand)
+ || (FPU_IS_ZERO(FirstOperand) && FPU_IS_INFINITY(SecondOperand))
+ || (FPU_IS_INFINITY(FirstOperand) && FPU_IS_ZERO(SecondOperand)))
+ {
+ /* The result will be indefinite */
+ Result->Sign = TRUE;
+ Result->Exponent = FPU_MAX_EXPONENT + 1;
+ Result->Mantissa = FPU_INDEFINITE_MANTISSA;
+ return;
+ }
+
+ if (FPU_IS_ZERO(FirstOperand) || FPU_IS_ZERO(SecondOperand))
+ {
+ /* The result will be zero */
+ Result->Sign = FirstOperand->Sign ^ SecondOperand->Sign;
+ Result->Exponent = 0;
+ Result->Mantissa = 0ULL;
+ return;
+ }
+
+ if (FPU_IS_INFINITY(FirstOperand) || FPU_IS_INFINITY(SecondOperand))
+ {
+ /* The result will be infinity */
+ Result->Sign = FirstOperand->Sign ^ SecondOperand->Sign;
+ Result->Exponent = FPU_MAX_EXPONENT + 1;
+ Result->Mantissa = FPU_MANTISSA_HIGH_BIT;
+ return;
+ }
if ((!FPU_IS_NORMALIZED(FirstOperand) || !FPU_IS_NORMALIZED(SecondOperand)))
{
@@ -709,12 +740,51 @@
}
}
+ /* Calculate the sign */
+ TempResult.Sign = FirstOperand->Sign ^ SecondOperand->Sign;
+
+ /* Calculate the exponent */
+ Exponent = (LONG)FirstOperand->Exponent + (LONG)SecondOperand->Exponent -
FPU_REAL10_BIAS;
+
+ /* Calculate the mantissa */
UnsignedMult128(FirstOperand->Mantissa,
SecondOperand->Mantissa,
&TempResult.Mantissa);
- TempResult.Exponent = FirstOperand->Exponent + SecondOperand->Exponent;
- TempResult.Sign = FirstOperand->Sign ^ SecondOperand->Sign;
+ if (Exponent < 0)
+ {
+ /* Raise the underflow exception */
+ State->FpuStatus.Ue = TRUE;
+
+ if (!State->FpuControl.Um)
+ {
+ Fast486FpuException(State);
+ return;
+ }
+
+ /* The exponent will be zero */
+ TempResult.Exponent = 0;
+
+ /* If possible, denormalize the result, otherwise make it zero */
+ if (Exponent > -64) TempResult.Mantissa >>= (-Exponent);
+ else TempResult.Mantissa = 0ULL;
+ }
+ else if (Exponent > FPU_MAX_EXPONENT)
+ {
+ /* Raise the overflow exception */
+ State->FpuStatus.Oe = TRUE;
+
+ if (!State->FpuControl.Om)
+ {
+ Fast486FpuException(State);
+ return;
+ }
+
+ /* Make the result infinity */
+ TempResult.Exponent = FPU_MAX_EXPONENT + 1;
+ TempResult.Mantissa = FPU_MANTISSA_HIGH_BIT;
+ }
+ else TempResult.Exponent = (USHORT)Exponent;
/* Normalize the result */
Fast486FpuNormalize(State, &TempResult);