|
@@ -1042,3 +1042,61 @@ static u32 vfp_single_fsub(int sd, int sn, s32 m, u32 fpscr)
|
|
|
* Subtraction is addition with one sign inverted.
|
|
|
*/
|
|
|
return vfp_single_fadd(sd, sn, vfp_single_packed_negate(m), fpscr);
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * sd = sn / sm
|
|
|
+ */
|
|
|
+static u32 vfp_single_fdiv(int sd, int sn, s32 m, u32 fpscr)
|
|
|
+{
|
|
|
+ struct vfp_single vsd, vsn, vsm;
|
|
|
+ u32 exceptions = 0;
|
|
|
+ s32 n = vfp_get_float(sn);
|
|
|
+ int tm, tn;
|
|
|
+
|
|
|
+ pr_debug("VFP: s%u = %08x\n", sn, n);
|
|
|
+
|
|
|
+ vfp_single_unpack(&vsn, n);
|
|
|
+ vfp_single_unpack(&vsm, m);
|
|
|
+
|
|
|
+ vsd.sign = vsn.sign ^ vsm.sign;
|
|
|
+
|
|
|
+ tn = vfp_single_type(&vsn);
|
|
|
+ tm = vfp_single_type(&vsm);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Is n a NAN?
|
|
|
+ */
|
|
|
+ if (tn & VFP_NAN)
|
|
|
+ goto vsn_nan;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Is m a NAN?
|
|
|
+ */
|
|
|
+ if (tm & VFP_NAN)
|
|
|
+ goto vsm_nan;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * If n and m are infinity, the result is invalid
|
|
|
+ * If n and m are zero, the result is invalid
|
|
|
+ */
|
|
|
+ if (tm & tn & (VFP_INFINITY|VFP_ZERO))
|
|
|
+ goto invalid;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * If n is infinity, the result is infinity
|
|
|
+ */
|
|
|
+ if (tn & VFP_INFINITY)
|
|
|
+ goto infinity;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * If m is zero, raise div0 exception
|
|
|
+ */
|
|
|
+ if (tm & VFP_ZERO)
|
|
|
+ goto divzero;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * If m is infinity, or n is zero, the result is zero
|
|
|
+ */
|
|
|
+ if (tm & VFP_INFINITY || tn & VFP_ZERO)
|
|
|
+ goto zero;
|