X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Farm%2Fvfp%2Fvfpsingle.c;h=dae2c2f460529c835ad74fac887d1b6e1e7c807a;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=92aa8412709e6662c0cf85ac98b5b21bfba675b7;hpb=5fc42a6ed0ec81088c37caadb45898ae6cd0ad2c;p=linux-2.6.git diff --git a/arch/arm/vfp/vfpsingle.c b/arch/arm/vfp/vfpsingle.c index 92aa84127..dae2c2f46 100644 --- a/arch/arm/vfp/vfpsingle.c +++ b/arch/arm/vfp/vfpsingle.c @@ -31,7 +31,9 @@ * =========================================================================== */ #include -#include +#include + +#include #include #include @@ -246,7 +248,7 @@ vfp_propagate_nan(struct vfp_single *vsd, struct vfp_single *vsn, /* * 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; } @@ -303,7 +305,11 @@ u32 vfp_estimate_sqrt_significand(u32 exponent, u32 significand) if (z <= a) return (s32)a >> 1; } - return (u32)(((u64)a << 31) / z) + (z >> 1); + { + u64 v = (u64)a << 31; + do_div(v, z); + return v + (z >> 1); + } } static u32 vfp_single_fsqrt(int sd, int unused, s32 m, u32 fpscr) @@ -626,6 +632,7 @@ static u32 vfp_single_ftosi(int sd, int unused, s32 m, u32 fpscr) struct vfp_single vsm; u32 d, exceptions = 0; int rmode = fpscr & FPSCR_RMODE_MASK; + int tm; vfp_single_unpack(&vsm, m); vfp_single_dump("VSM", &vsm); @@ -633,10 +640,14 @@ static u32 vfp_single_ftosi(int sd, int unused, s32 m, u32 fpscr) /* * Do we have a denormalised number? */ + tm = vfp_single_type(&vsm); if (vfp_single_type(&vsm) & VFP_DENORMAL) exceptions |= FPSCR_IDC; - if (vsm.exponent >= 127 + 32) { + if (tm & VFP_NAN) { + d = 0; + exceptions |= FPSCR_IOC; + } else if (vsm.exponent >= 127 + 32) { /* * m >= 2^31-2^7: invalid */ @@ -1107,7 +1118,11 @@ static u32 vfp_single_fdiv(int sd, int sn, s32 m, u32 fpscr) vsn.significand >>= 1; vsd.exponent++; } - vsd.significand = ((u64)vsn.significand << 32) / vsm.significand; + { + u64 significand = (u64)vsn.significand << 32; + do_div(significand, vsm.significand); + vsd.significand = significand; + } if ((vsd.significand & 0x3f) == 0) vsd.significand |= ((u64)vsm.significand * vsd.significand != (u64)vsn.significand << 32); @@ -1178,7 +1193,7 @@ u32 vfp_single_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[sn] : 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;