math: support platforms with limited FP rounding or exception support
authorChris Metcalf <cmetcalf@tilera.com>
Thu, 17 May 2012 12:49:19 +0000 (08:49 -0400)
committerChris Metcalf <cmetcalf@tilera.com>
Thu, 17 May 2012 12:50:41 +0000 (08:50 -0400)
For some tests, just claim that fetestexcept() always returns true,
so the rest of the test can be compiled.

For libm-test, provide known bogus values for unsupported rounding
modes, so fesetround() will return failure.

Elsewhere, just add some #ifdefs to avoid code that uses particular
FP exceptions if the exceptions aren't supported.

ChangeLog
math/bug-nextafter.c
math/bug-nexttoward.c
math/libm-test.inc
math/test-fenv.c
math/test-misc.c
stdlib/bug-getcontext.c

index f6dbf40..8970d74 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2012-05-17  Chris Metcalf  <cmetcalf@tilera.com>
+
+       * math/libm-test.c: Support platforms without multiple rounding modes.
+       * math/bug-nextafter.c: Support platforms without FP exceptions.
+       * math/bug-nexttoward.c: Likewise.
+       * math/test-fenv.c: Likewise.
+       * math/test-misc.c: Likewise.
+       * stdlib/bug-getcontext.c: Likewise.
+
 2012-05-17  Andreas Jaeger  <aj@suse.de>
 
        * manual/examples/search.c (critter_cmp): Change signature to
index 1d21841..558b158 100644 (file)
@@ -4,6 +4,12 @@
 #include <stdlib.h>
 #include <stdio.h>
 
+#if !defined(FE_OVERFLOW) && !defined(FE_UNDERFLOW)
+/* If there's no support for the exceptions this test is checking,
+   then just return success and allow the test to be compiled.  */
+# define fetestexcept(e) 1
+#endif
+
 float zero = 0.0;
 float inf = INFINITY;
 
index ff57e5e..cedb776 100644 (file)
@@ -4,6 +4,12 @@
 #include <stdlib.h>
 #include <stdio.h>
 
+#if !defined(FE_OVERFLOW) && !defined(FE_UNDERFLOW)
+/* If there's no support for the exceptions this test is checking,
+   then just return success and allow the test to be compiled.  */
+# define fetestexcept(e) 1
+#endif
+
 float zero = 0.0;
 float inf = INFINITY;
 
index 5a38dbf..47bbd5f 100644 (file)
 #include <string.h>
 #include <argp.h>
 
+/* Allow platforms without all rounding modes to test properly,
+   assuming they provide an __FE_UNDEFINED in <bits/fenv.h> which
+   causes fesetround() to return failure.  */
+#ifndef FE_TONEAREST
+# define FE_TONEAREST  __FE_UNDEFINED
+#endif
+#ifndef FE_TOWARDZERO
+# define FE_TOWARDZERO __FE_UNDEFINED
+#endif
+#ifndef FE_UPWARD
+# define FE_UPWARD     __FE_UNDEFINED
+#endif
+#ifndef FE_DOWNWARD
+# define FE_DOWNWARD   __FE_UNDEFINED
+#endif
+
 /* Possible exceptions */
 #define NO_EXCEPTION                   0x0
 #define INVALID_EXCEPTION              0x1
index 39c7c33..19e5415 100644 (file)
@@ -664,9 +664,11 @@ feholdexcept_tests (void)
     }
 #endif
   test_exceptions ("feholdexcept_tests 0 test", NO_EXC, 0);
+#ifdef FE_INVALID
   feraiseexcept (FE_INVALID);
   test_exceptions ("feholdexcept_tests FE_INVALID test",
                   INVALID_EXC, 0);
+#endif
   res = feupdateenv (&saved);
   if (res != 0)
     {
@@ -684,7 +686,9 @@ feholdexcept_tests (void)
   test_exceptions ("feholdexcept_tests FE_DIVBYZERO|FE_INVALID test",
                   DIVBYZERO_EXC | INVALID_EXC, 0);
   feclearexcept (FE_ALL_EXCEPT);
+#ifdef FE_INVALID
   feraiseexcept (FE_INVALID);
+#endif
 #if defined FE_TONEAREST && defined FE_UPWARD
   res = fesetround (FE_UPWARD);
   if (res != 0)
@@ -708,9 +712,11 @@ feholdexcept_tests (void)
     }
 #endif
   test_exceptions ("feholdexcept_tests 0 2nd test", NO_EXC, 0);
+#ifdef FE_INEXACT
   feraiseexcept (FE_INEXACT);
   test_exceptions ("feholdexcept_tests FE_INEXACT test",
                   INEXACT_EXC, 0);
+#endif
   res = feupdateenv (&saved2);
   if (res != 0)
     {
index c0fe5f7..55da359 100644 (file)
@@ -1186,12 +1186,14 @@ main (void)
   (void) &f2;
   feclearexcept (FE_ALL_EXCEPT);
   f2 += f1;
+#if defined(FE_OVERFLOW) && defined(FE_INEXACT)
   int fe = fetestexcept (FE_ALL_EXCEPT);
   if (fe != (FE_OVERFLOW | FE_INEXACT))
     {
       printf ("float overflow test failed: %x\n", fe);
       result = 1;
     }
+#endif
 
   volatile double d1 = DBL_MAX;
   volatile double d2 = DBL_MAX / 2;
@@ -1199,12 +1201,14 @@ main (void)
   (void) &d2;
   feclearexcept (FE_ALL_EXCEPT);
   d2 += d1;
+#if defined(FE_OVERFLOW) && defined(FE_INEXACT)
   fe = fetestexcept (FE_ALL_EXCEPT);
   if (fe != (FE_OVERFLOW | FE_INEXACT))
     {
       printf ("double overflow test failed: %x\n", fe);
       result = 1;
     }
+#endif
 
 #ifndef NO_LONG_DOUBLE
   volatile long double ld1 = LDBL_MAX;
@@ -1213,12 +1217,14 @@ main (void)
   (void) &ld2;
   feclearexcept (FE_ALL_EXCEPT);
   ld2 += ld1;
+# if defined(FE_OVERFLOW) && defined(FE_INEXACT)
   fe = fetestexcept (FE_ALL_EXCEPT);
   if (fe != (FE_OVERFLOW | FE_INEXACT))
     {
       printf ("long double overflow test failed: %x\n", fe);
       result = 1;
     }
+# endif
 #endif
 
 #if !defined NO_LONG_DOUBLE && LDBL_MANT_DIG == 113
index 745aa1f..7db49c8 100644 (file)
@@ -9,6 +9,9 @@
 static int
 do_test (void)
 {
+#if FE_ALL_EXCEPT == 0
+  printf("Skipping test; no support for FP exceptions.\n");
+#else
   int except_mask =  FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW;
   int status = feenableexcept (except_mask);
 
@@ -41,6 +44,7 @@ do_test (void)
 
   printf("\nAt end fegetexcept() returned %d, expected: %d.\n",
         mask, except_mask);
+#endif
   return 0;
 }