in vfp/vfpsingle.c [547:620]
static u32 vfp_single_ftoui(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);
/*
* Do we have a denormalised number?
*/
tm = vfp_single_type(&vsm);
if (tm & VFP_DENORMAL)
exceptions |= FPSCR_IDC;
if (tm & VFP_NAN)
vsm.sign = 0;
if (vsm.exponent >= 127 + 32) {
d = vsm.sign ? 0 : 0xffffffff;
exceptions = FPSCR_IOC;
} else if (vsm.exponent >= 127 - 1) {
int shift = 127 + 31 - vsm.exponent;
u32 rem, incr = 0;
/*
* 2^0 <= m < 2^32-2^8
*/
d = (vsm.significand << 1) >> shift;
rem = vsm.significand << (33 - shift);
if (rmode == FPSCR_ROUND_NEAREST) {
incr = 0x80000000;
if ((d & 1) == 0)
incr -= 1;
} else if (rmode == FPSCR_ROUND_TOZERO) {
incr = 0;
} else if ((rmode == FPSCR_ROUND_PLUSINF) ^ (vsm.sign != 0)) {
incr = ~0;
}
if ((rem + incr) < rem) {
if (d < 0xffffffff)
d += 1;
else
exceptions |= FPSCR_IOC;
}
if (d && vsm.sign) {
d = 0;
exceptions |= FPSCR_IOC;
} else if (rem)
exceptions |= FPSCR_IXC;
} else {
d = 0;
if (vsm.exponent | vsm.significand) {
exceptions |= FPSCR_IXC;
if (rmode == FPSCR_ROUND_PLUSINF && vsm.sign == 0)
d = 1;
else if (rmode == FPSCR_ROUND_MINUSINF && vsm.sign) {
d = 0;
exceptions |= FPSCR_IOC;
}
}
}
pr_debug("VFP: ftoui: d(s%d)=%08x exceptions=%08x\n", sd, d, exceptions);
vfp_put_float(d, sd);
return exceptions;
}