Revert to Fedora kernel-2.6.17-1.2187_FC5 patched with vs2.0.2.1; there are too many...
[linux-2.6.git] / arch / arm / vfp / vfpdouble.c
index 54649c1..009038c 100644 (file)
@@ -31,7 +31,9 @@
  * ===========================================================================
  */
 #include <linux/kernel.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
+
+#include <asm/div64.h>
 #include <asm/ptrace.h>
 #include <asm/vfp.h>
 
@@ -240,7 +242,7 @@ vfp_propagate_nan(struct vfp_double *vdd, struct vfp_double *vdn,
        /*
         * If one was a signalling NAN, raise invalid operation.
         */
-       return tn == VFP_SNAN || tm == VFP_SNAN ? FPSCR_IOC : 0x100;
+       return tn == VFP_SNAN || tm == VFP_SNAN ? FPSCR_IOC : VFP_NAN_FLAG;
 }
 
 /*
@@ -427,12 +429,12 @@ static u32 vfp_double_fcmpe(int dd, int unused, int dm, u32 fpscr)
 
 static u32 vfp_double_fcmpz(int dd, int unused, int dm, u32 fpscr)
 {
-       return vfp_compare(dd, 0, -1, fpscr);
+       return vfp_compare(dd, 0, VFP_REG_ZERO, fpscr);
 }
 
 static u32 vfp_double_fcmpez(int dd, int unused, int dm, u32 fpscr)
 {
-       return vfp_compare(dd, 1, -1, fpscr);
+       return vfp_compare(dd, 1, VFP_REG_ZERO, fpscr);
 }
 
 static u32 vfp_double_fcvts(int sd, int unused, int dm, u32 fpscr)
@@ -586,6 +588,7 @@ static u32 vfp_double_ftosi(int sd, int unused, int dm, u32 fpscr)
        struct vfp_double vdm;
        u32 d, exceptions = 0;
        int rmode = fpscr & FPSCR_RMODE_MASK;
+       int tm;
 
        vfp_double_unpack(&vdm, vfp_get_double(dm));
        vfp_double_dump("VDM", &vdm);
@@ -593,10 +596,14 @@ static u32 vfp_double_ftosi(int sd, int unused, int dm, u32 fpscr)
        /*
         * Do we have denormalised number?
         */
-       if (vfp_double_type(&vdm) & VFP_DENORMAL)
+       tm = vfp_double_type(&vdm);
+       if (tm & VFP_DENORMAL)
                exceptions |= FPSCR_IDC;
 
-       if (vdm.exponent >= 1023 + 32) {
+       if (tm & VFP_NAN) {
+               d = 0;
+               exceptions |= FPSCR_IOC;
+       } else if (vdm.exponent >= 1023 + 32) {
                d = 0x7fffffff;
                if (vdm.sign)
                        d = ~d;
@@ -768,6 +775,9 @@ vfp_double_add(struct vfp_double *vdd, struct vfp_double *vdn,
                if ((s64)m_sig < 0) {
                        vdd->sign = vfp_sign_negate(vdd->sign);
                        m_sig = -m_sig;
+               } else if (m_sig == 0) {
+                       vdd->sign = (fpscr & FPSCR_RMODE_MASK) ==
+                                     FPSCR_ROUND_MINUSINF ? 0x8000 : 0;
                }
        } else {
                m_sig += vdn->significand;
@@ -1117,9 +1127,9 @@ u32 vfp_double_cpdo(u32 inst, u32 fpscr)
 {
        u32 op = inst & FOP_MASK;
        u32 exceptions = 0;
-       unsigned int dd = vfp_get_sd(inst);
-       unsigned int dn = vfp_get_sn(inst);
-       unsigned int dm = vfp_get_sm(inst);
+       unsigned int dd = vfp_get_dd(inst);
+       unsigned int dn = vfp_get_dn(inst);
+       unsigned int dm = vfp_get_dm(inst);
        unsigned int vecitr, veclen, vecstride;
        u32 (*fop)(int, int, s32, u32);
 
@@ -1136,7 +1146,7 @@ u32 vfp_double_cpdo(u32 inst, u32 fpscr)
        pr_debug("VFP: vecstride=%u veclen=%u\n", vecstride,
                 (veclen >> FPSCR_LENGTH_BIT) + 1);
 
-       fop = (op == FOP_EXT) ? fop_extfns[dn] : fop_fns[FOP_TO_IDX(op)];
+       fop = (op == FOP_EXT) ? fop_extfns[FEXT_TO_IDX(inst)] : fop_fns[FOP_TO_IDX(op)];
        if (!fop)
                goto invalid;
 
@@ -1144,17 +1154,13 @@ u32 vfp_double_cpdo(u32 inst, u32 fpscr)
                u32 except;
 
                if (op == FOP_EXT)
-                       pr_debug("VFP: itr%d (d%u.%u) = op[%u] (d%u.%u)\n",
+                       pr_debug("VFP: itr%d (d%u) = op[%u] (d%u)\n",
                                 vecitr >> FPSCR_LENGTH_BIT,
-                                dd >> 1, dd & 1, dn,
-                                dm >> 1, dm & 1);
+                                dd, dn, dm);
                else
-                       pr_debug("VFP: itr%d (d%u.%u) = (d%u.%u) op[%u] (d%u.%u)\n",
+                       pr_debug("VFP: itr%d (d%u) = (d%u) op[%u] (d%u)\n",
                                 vecitr >> FPSCR_LENGTH_BIT,
-                                dd >> 1, dd & 1,
-                                dn >> 1, dn & 1,
-                                FOP_TO_IDX(op),
-                                dm >> 1, dm & 1);
+                                dd, dn, FOP_TO_IDX(op), dm);
 
                except = fop(dd, dn, dm, fpscr);
                pr_debug("VFP: itr%d: exceptions=%08x\n",