fenv.h fixes for softfloat
David Schultz
das at freebsd.org
Mon Jan 16 02:26:50 UTC 2012
On Sat, Jan 14, 2012, Ian Lepore wrote:
> With the original value 1.1 instead of 1.0, rint() itself raises
> FE_INVALID, in the path that falls out the bottom. I added printfs:
>
> printf("rint 7a: except %#x\n", fetestexcept(FE_ALL_EXCEPT));
> INSERT_WORDS(x,i0,i1);
> printf("rint 7b: except %#x\n", fetestexcept(FE_ALL_EXCEPT));
> STRICT_ASSIGN(double,w,TWO52[sx]+x);
> printf("rint 7c: except %#x\n", fetestexcept(FE_ALL_EXCEPT));
> result = w-TWO52[sx];
> printf("rint 8: except %#x i0=%#x i1=%#x x=%g w=%g result=%g\n", fetestexcept(FE_ALL_EXCEPT), i0, i1, x, w, result);
> return result;
>
> And a run using rint(1.1) gave this output:
>
> rint 7a: except 0
> rint 7b: except 0
> rint 7c: except 0x10
> rint 8: except 0x10 i0=0x3ff20000 i1=0x9999999a x=1.125 w=4.5036e+15 result=1
I believe 0x10 is FE_INEXACT on arm, not FE_INVALID. FE_INEXACT
is correct here, because w+TWO52[sx] is inexact. That still
doesn't explain the lrint() failures, but it makes them less
mysterious. For instance, the implementation of the cast from
double to int could raise a bogus inexact exception when the
number is an integer to begin with. In practice, I think the
emulated casts don't raise the proper exceptions even when they
should. It might depend on whether it's linking against libgcc's
__fixdfsi() or libc's.
Nice catch with the _fpmath.h bug, by the way. I'll commit that
fix as well.
More information about the freebsd-arm
mailing list