On Mon, Jun 30, 2014 at 09:56:35PM +0100, Al Viro wrote: > FWIW, it might be better to do what float64_to_int64_round_to_zero() is doing > - > i.e. > if (shift >= 0) { > if (shift < 64) > ret = frac << shift; > if (shift < 11 || a == LIT64(0xC3E0000000000000)) > exc = 0; > } > since frac is between 1ULL<<52 and (1ULL<<53)-1, i.e. shift greater than 11 > is guaranteed to overflow, shift less than 11 is guaranteed not to and shift > exactly 11 won't overflow only in one case - frac == 1ULL<<52, sign = 1 (i.e. > when we have -2^63 there). BTW, shift == 63 is interesting - we certainly > overflow, but we want the result to be 0 or 2^63 depending on the least > significant bit of mantissa, not "always 0". IOW, 0x4720000000000000 should > yield IOV|INE, with result being 0 and 0x4720000000000001 - IOV|INE and > result 0x8000000000000000. Again, verified on actual hardware; the last > patch I posted had been incorrect in the last case (both cases yield 0 with > it, > same as in mainline qemu).
While we are at it, CVTTQ yields INV on +-infinity, just as it does for NaNs. IOW, in inline_cvttq() exc = (frac ? float_flag_invalid : float_flag_int_overflow | float_flag_inexact); should be simply exc = float_flag_invalid; VAX operations are serious mess, but I'm not sure if we have them actually used anywhere in Linux kernel or userland. Always possible, of course, but...