Alan Modra wrote: > On Sat, Dec 14, 2013 at 10:13:29PM +0100, Ulrich Weigand wrote: > > I'm wondering now what the best way to fix this would be. I'm a little bit > > confused about the original intentions of the test, however. Why does it > > attempt to move to another word? If it simply attempted to set the > > *second* highest mantissa bit, everything would work out OK. And if it > > does move to another word, why the NWORDS / 2 test? Should we trust the > > gl_BIGENDIAN macro instead? > > I would say "LDBL_EXPBIT0_WORD < NWORDS / 2" is testing for floating > point endianness (which seemingly can be different to integer > endianness, at least it looks that way from code in gcc). Now gcc has > predefined macros to test for exactly that, so.. > > #ifdef __FLOAT_WORD_ORDER__ > #define FLOAT_BIG_ENDIAN (__FLOAT_WORD_ORDER__ != __ORDER_LITTLE_ENDIAN__) > #else > #define FLOAT_BIG_ENDIAN (LDBL_EXPBIT0_WORD < NWORDS / 2) > #endif > > then use FLOAT_BIG_ENDIAN everywhere you see LDBL_EXPBIT0_WORD < NWORDS / 2
I guess that would be one way. I've been working on another patch along these lines in the meantime: > > Or should the test simply hardcode the information about the IBM double > > double format, and treat the first half as 64-bit IEEE double? This seems a bit more natural to me, as it addresses the actual underlying problem with those test cases (IBM double double simply is not an IEEE format, and treating it as such really only worked by accident). The patch below fixes all the isfinite/isinf*/isnan*/signbit module tests for me on powerpc64le-linux, and does not regress on powerpc64-linux. Does this look reasonable? Bye, Ulrich diff --git a/ChangeLog b/ChangeLog index 1753c8e..52ec0df 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2013-12-18 Ulrich Weigand <uweig...@de.ibm.com> + + Fix math tests for little-endian PowerPC + + * tests/test-isfinite.c (test_isfinitel): Only manipulate the + first double of a PowerPC "double double" pair. + * tests/test-isinf.c (test_isinfl): Likewise. + * tests/test-isnan.c (test_long_double): Likewise. + * tests/test-isnanl.h (main): Likewise. + * tests/test-signbit.c (test_signbitl): Likewise. + 2013-12-17 Paul Eggert <egg...@cs.ucla.edu> gettimeofday: port recent C++ fix to Emacs diff --git a/tests/test-isfinite.c b/tests/test-isfinite.c index 9e8dd0d..a762ceb 100644 --- a/tests/test-isfinite.c +++ b/tests/test-isfinite.c @@ -152,6 +152,15 @@ test_isfinitel () /* A bit pattern that is different from a Quiet NaN. With a bit of luck, it's a Signalling NaN. */ { +#if defined __powerpc__ && LDBL_MANT_DIG == 106 + /* This is PowerPC "double double", a pair of two doubles. Inf and Nan are + represented as the corresponding 64-bit IEEE values in the first double; + the second is ignored. Manipulate only the first double. */ + #undef NWORDS + #define NWORDS \ + ((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int)) +#endif + memory_long_double m; m.value = zerol / zerol; # if LDBL_EXPBIT0_BIT > 0 diff --git a/tests/test-isinf.c b/tests/test-isinf.c index 276e480..eb1b7f2 100644 --- a/tests/test-isinf.c +++ b/tests/test-isinf.c @@ -158,6 +158,15 @@ test_isinfl () /* A bit pattern that is different from a Quiet NaN. With a bit of luck, it's a Signalling NaN. */ { +#if defined __powerpc__ && LDBL_MANT_DIG == 106 + /* This is PowerPC "double double", a pair of two doubles. Inf and Nan are + represented as the corresponding 64-bit IEEE values in the first double; + the second is ignored. Manipulate only the first double. */ + #undef NWORDS + #define NWORDS \ + ((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int)) +#endif + memory_long_double m; m.value = zerol / zerol; # if LDBL_EXPBIT0_BIT > 0 diff --git a/tests/test-isnan.c b/tests/test-isnan.c index ccebe3d..a11233a 100644 --- a/tests/test-isnan.c +++ b/tests/test-isnan.c @@ -139,6 +139,15 @@ test_long_double (void) /* A bit pattern that is different from a Quiet NaN. With a bit of luck, it's a Signalling NaN. */ { +#if defined __powerpc__ && LDBL_MANT_DIG == 106 + /* This is PowerPC "double double", a pair of two doubles. Inf and Nan are + represented as the corresponding 64-bit IEEE values in the first double; + the second is ignored. Manipulate only the first double. */ + #undef NWORDSL + #define NWORDSL \ + ((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int)) +#endif + memory_long_double m; m.value = NaNl (); # if LDBL_EXPBIT0_BIT > 0 diff --git a/tests/test-isnanl.h b/tests/test-isnanl.h index 06e6a7c..2df10f8 100644 --- a/tests/test-isnanl.h +++ b/tests/test-isnanl.h @@ -51,6 +51,15 @@ main () /* A bit pattern that is different from a Quiet NaN. With a bit of luck, it's a Signalling NaN. */ { +#if defined __powerpc__ && LDBL_MANT_DIG == 106 + /* This is PowerPC "double double", a pair of two doubles. Inf and Nan are + represented as the corresponding 64-bit IEEE values in the first double; + the second is ignored. Manipulate only the first double. */ + #undef NWORDS + #define NWORDS \ + ((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int)) +#endif + memory_long_double m; m.value = NaNl (); # if LDBL_EXPBIT0_BIT > 0 diff --git a/tests/test-signbit.c b/tests/test-signbit.c index e8ea097..7e24292 100644 --- a/tests/test-signbit.c +++ b/tests/test-signbit.c @@ -151,6 +151,16 @@ test_signbitl () #define NWORDS \ ((sizeof (long double) + sizeof (unsigned int) - 1) / sizeof (unsigned int)) typedef union { long double value; unsigned int word[NWORDS]; } memory_long_double; + +#if defined __powerpc__ && LDBL_MANT_DIG == 106 + /* This is PowerPC "double double", a pair of two doubles. Inf and Nan are + represented as the corresponding 64-bit IEEE values in the first double; + the second is ignored. Manipulate only the first double. */ + #undef NWORDS + #define NWORDS \ + ((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int)) +#endif + memory_long_double m; m.value = zerol / zerol; # if LDBL_EXPBIT0_BIT > 0 -- Dr. Ulrich Weigand GNU/Linux compilers and toolchain ulrich.weig...@de.ibm.com