Index: lib/msun/tests/fenv_test.c =================================================================== --- lib/msun/tests/fenv_test.c +++ lib/msun/tests/fenv_test.c @@ -250,7 +250,7 @@ test_fegsetexceptflag(void) { fexcept_t flag; - int excepts, i; + int excepts, i, expected_result; assert(fetestexcept(FE_ALL_EXCEPT) == 0); for (i = 0; i < 1 << NEXCEPTS; i++) { @@ -259,16 +259,23 @@ assert(fegetexceptflag(&flag, excepts) == 0); raiseexcept(ALL_STD_EXCEPT); assert(fesetexceptflag(&flag, excepts) == 0); - assert(fetestexcept(ALL_STD_EXCEPT) == - (ALL_STD_EXCEPT ^ excepts)); + + expected_result = (ALL_STD_EXCEPT ^ excepts); + #if __powerpc__ + /* + * On PowerPC, all invalid flags are cleared when FE_INVALID is cleared + */ + if (excepts & FE_INVALID) + expected_result = 0; + #endif + assert(fetestexcept(ALL_STD_EXCEPT) == expected_result); assert(fegetexceptflag(&flag, FE_ALL_EXCEPT) == 0); assert(feclearexcept(FE_ALL_EXCEPT) == 0); assert(fesetexceptflag(&flag, excepts) == 0); assert(fetestexcept(ALL_STD_EXCEPT) == 0); assert(fesetexceptflag(&flag, ALL_STD_EXCEPT ^ excepts) == 0); - assert(fetestexcept(ALL_STD_EXCEPT) == - (ALL_STD_EXCEPT ^ excepts)); + assert(fetestexcept(ALL_STD_EXCEPT) == expected_result); assert(feclearexcept(FE_ALL_EXCEPT) == 0); } @@ -362,6 +369,14 @@ * exceptions that afflict raiseexcept(). */ raiseexcept(excepts); + #if __powerpc__ + /* + * To raise FE_INVALID, raiseexcept() divides 0 by 0 but + * on PowerPC another flag is raised by 0 / 0 -> FE_VXZDZ + */ + if (excepts & FE_INVALID) + excepts |= FE_VXZDZ; + #endif if ((excepts & (FE_UNDERFLOW | FE_OVERFLOW)) != 0 && (excepts & FE_INEXACT) == 0) assert(feclearexcept(FE_INEXACT) == 0); Index: lib/msun/tests/lrint_test.c =================================================================== --- lib/msun/tests/lrint_test.c +++ lib/msun/tests/lrint_test.c @@ -41,6 +41,15 @@ #include #endif +#ifdef __powerpc__ +/* + * PowerPC raises FE_VXCVI when FE_INVALID is raised + */ + #define FE_INVALID_ALT (FE_INVALID | FE_VXCVI) +#else + #define FE_INVALID_ALT FE_INVALID +#endif + /* * XXX The volatile here is to avoid gcc's bogus constant folding and work * around the lack of support for the FENV_ACCESS pragma. @@ -48,7 +57,7 @@ #define test(func, x, result, excepts) do { \ volatile double _d = x; \ assert(feclearexcept(FE_ALL_EXCEPT) == 0); \ - assert((func)(_d) == (result) || fetestexcept(FE_INVALID)); \ + assert((func)(_d) == (result) || fetestexcept(FE_INVALID_ALT)); \ assert(fetestexcept(FE_ALL_EXCEPT) == (excepts)); \ } while (0) @@ -81,35 +90,35 @@ testall(1.0, 1, 0); testall(0x12345000p0, 0x12345000, 0); testall(0x1234.fp0, 0x1235, FE_INEXACT); - testall(INFINITY, IGNORE, FE_INVALID); - testall(NAN, IGNORE, FE_INVALID); + testall(INFINITY, IGNORE, FE_INVALID_ALT); + testall(NAN, IGNORE, FE_INVALID_ALT); #if (LONG_MAX == 0x7fffffffl) assert(fesetround(FE_UPWARD) == 0); - test(lrint, 0x7fffffff.8p0, IGNORE, FE_INVALID); + test(lrint, 0x7fffffff.8p0, IGNORE, FE_INVALID_ALT); test(lrint, -0x80000000.4p0, -0x80000000l, FE_INEXACT); assert(fesetround(FE_DOWNWARD) == 0); - test(lrint, -0x80000000.8p0, IGNORE, FE_INVALID); - test(lrint, 0x80000000.0p0, IGNORE, FE_INVALID); + test(lrint, -0x80000000.8p0, IGNORE, FE_INVALID_ALT); + test(lrint, 0x80000000.0p0, IGNORE, FE_INVALID_ALT); test(lrint, 0x7fffffff.4p0, 0x7fffffffl, FE_INEXACT); - test(lrintf, 0x80000000.0p0f, IGNORE, FE_INVALID); + test(lrintf, 0x80000000.0p0f, IGNORE, FE_INVALID_ALT); test(lrintf, 0x7fffff80.0p0f, 0x7fffff80l, 0); assert(fesetround(FE_TOWARDZERO) == 0); test(lrint, 0x7fffffff.8p0, 0x7fffffffl, FE_INEXACT); test(lrint, -0x80000000.8p0, -0x80000000l, FE_INEXACT); - test(lrint, 0x80000000.0p0, IGNORE, FE_INVALID); - test(lrintf, 0x80000000.0p0f, IGNORE, FE_INVALID); + test(lrint, 0x80000000.0p0, IGNORE, FE_INVALID_ALT); + test(lrintf, 0x80000000.0p0f, IGNORE, FE_INVALID_ALT); test(lrintf, 0x7fffff80.0p0f, 0x7fffff80l, 0); #elif (LONG_MAX == 0x7fffffffffffffffll) assert(fesetround(FE_TONEAREST) == 0); - test(lrint, 0x8000000000000000.0p0, IGNORE, FE_INVALID); - test(lrintf, 0x8000000000000000.0p0f, IGNORE, FE_INVALID); + test(lrint, 0x8000000000000000.0p0, IGNORE, FE_INVALID_ALT); + test(lrintf, 0x8000000000000000.0p0f, IGNORE, FE_INVALID_ALT); test(lrint, 0x7ffffffffffffc00.0p0, 0x7ffffffffffffc00l, 0); test(lrintf, 0x7fffff8000000000.0p0f, 0x7fffff8000000000l, 0); - test(lrint, -0x8000000000000800.0p0, IGNORE, FE_INVALID); - test(lrintf, -0x8000010000000000.0p0f, IGNORE, FE_INVALID); + test(lrint, -0x8000000000000800.0p0, IGNORE, FE_INVALID_ALT); + test(lrintf, -0x8000010000000000.0p0f, IGNORE, FE_INVALID_ALT); test(lrint, -0x8000000000000000.0p0, -0x8000000000000000l, 0); test(lrintf, -0x8000000000000000.0p0f, -0x8000000000000000l, 0); #else @@ -118,12 +127,12 @@ #if (LLONG_MAX == 0x7fffffffffffffffLL) assert(fesetround(FE_TONEAREST) == 0); - test(llrint, 0x8000000000000000.0p0, IGNORE, FE_INVALID); - test(llrintf, 0x8000000000000000.0p0f, IGNORE, FE_INVALID); + test(llrint, 0x8000000000000000.0p0, IGNORE, FE_INVALID_ALT); + test(llrintf, 0x8000000000000000.0p0f, IGNORE, FE_INVALID_ALT); test(llrint, 0x7ffffffffffffc00.0p0, 0x7ffffffffffffc00ll, 0); test(llrintf, 0x7fffff8000000000.0p0f, 0x7fffff8000000000ll, 0); - test(llrint, -0x8000000000000800.0p0, IGNORE, FE_INVALID); - test(llrintf, -0x8000010000000000.0p0f, IGNORE, FE_INVALID); + test(llrint, -0x8000000000000800.0p0, IGNORE, FE_INVALID_ALT); + test(llrintf, -0x8000010000000000.0p0f, IGNORE, FE_INVALID_ALT); test(llrint, -0x8000000000000000.0p0, -0x8000000000000000ll, 0); test(llrintf, -0x8000000000000000.0p0f, -0x8000000000000000ll, 0); #else