Author: aandrejevic
Date: Sat May 23 23:44:10 2015
New Revision: 67874
URL:
http://svn.reactos.org/svn/reactos?rev=67874&view=rev
Log:
[FAST486]
Implement FSQRT using the Babylonian method.
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=6787…
==============================================================================
--- trunk/reactos/lib/fast486/fpu.c [iso-8859-1] (original)
+++ trunk/reactos/lib/fast486/fpu.c [iso-8859-1] Sat May 23 23:44:10 2015
@@ -1390,6 +1390,63 @@
}
}
+/*
+ * Calculates using:
+ * x[0] = s
+ * x[n + 1] = (x[n] + s / x[n]) / 2
+ */
+static inline BOOLEAN FASTCALL
+Fast486FpuCalculateSquareRoot(PFAST486_STATE State,
+ PCFAST486_FPU_DATA_REG Operand,
+ PFAST486_FPU_DATA_REG Result)
+{
+ FAST486_FPU_DATA_REG Value = *Operand;
+ FAST486_FPU_DATA_REG PrevValue = FpuZero;
+
+ if (Operand->Sign)
+ {
+ /* Raise the invalid operation exception */
+ State->FpuStatus.Ie = TRUE;
+
+ if (State->FpuControl.Im)
+ {
+ /* Return the indefinite NaN */
+ Result->Sign = TRUE;
+ Result->Exponent = FPU_MAX_EXPONENT + 1;
+ Result->Mantissa = FPU_INDEFINITE_MANTISSA;
+ return TRUE;
+ }
+ else
+ {
+ Fast486FpuException(State);
+ return FALSE;
+ }
+ }
+
+ /* Loop until it converges */
+ while (Value.Sign != PrevValue.Sign
+ || Value.Exponent != PrevValue.Exponent
+ || Value.Mantissa != PrevValue.Mantissa)
+ {
+ FAST486_FPU_DATA_REG Temp;
+
+ /* Save the current value */
+ PrevValue = Value;
+
+ /* Divide the operand by the current value */
+ if (!Fast486FpuDivide(State, Operand, &Value, &Temp)) return FALSE;
+
+ /* Add the result of that division to the current value */
+ if (!Fast486FpuAdd(State, &Value, &Temp, &Value)) return FALSE;
+
+ /* Halve the current value */
+ if (!Fast486FpuMultiply(State, &Value, &FpuInverseNumber[1], &Value))
return FALSE;
+ }
+
+ *Result = Value;
+ return TRUE;
+}
+
static inline BOOLEAN FASTCALL
Fast486FpuLoadEnvironment(PFAST486_STATE State,
INT Segment,
@@ -2111,8 +2168,8 @@
/* FSQRT */
case 0x3A:
{
- // TODO: NOT IMPLEMENTED
- UNIMPLEMENTED;
+ Fast486FpuCalculateSquareRoot(State, &FPU_ST(0), &FPU_ST(0));
+ FPU_UPDATE_TAG(0);
break;
}