i386: Convert libc_{feholdexcept_setround,updateenv}_53bit to functions.
authorRichard Henderson <rth@twiddle.net>
Sun, 18 Mar 2012 17:12:16 +0000 (10:12 -0700)
committerRichard Henderson <rth@twiddle.net>
Mon, 19 Mar 2012 13:49:04 +0000 (06:49 -0700)
Also fix a bug in libc_feupdateenv_53bit: don't force the rounding
precision back to _FPU_EXTENDED, instead restore the precision that
the user had in effect beforehand.

ChangeLog
sysdeps/i386/fpu/math_private.h

index 2d6d574..aace9ef 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2012-03-19  Richard Henderson  <rth@twiddle.net>
 
+       * sysdeps/i386/fpu/math_private.h: Include <fenv.h>, <fpu_control.h>.
+       (libc_feholdexcept_setround_53bit): Convert from macro to function.
+       (libc_feupdateenv_53bit): Likewise.  Don't force _FPU_EXTENDED.
+
        * sysdeps/generic/math_private.h: Include <fenv.h>.
        (default_libc_feholdexcept): New.
        (default_libc_feholdexcept_setround): New.
index 6520226..9236448 100644 (file)
@@ -1,5 +1,8 @@
 #ifndef _MATH_PRIVATE_H
 
+#include <fenv.h>
+#include <fpu_control.h>
+
 #define math_opt_barrier(x) \
 ({ __typeof (x) __x;                                   \
    __asm ("" : "=t" (__x) : "0" (x));                  \
@@ -15,34 +18,31 @@ do                                                  \
   }                                                    \
 while (0)
 
-#include_next <math_private.h>
+static __always_inline void
+libc_feholdexcept_setround_53bit (fenv_t *e, int r)
+{
+  feholdexcept (e);
+  fesetround (r);
 
-#include <fpu_control.h>
+  fpu_control_t cw;
+  _FPU_GETCW (cw);
+  cw &= ~(fpu_control_t) _FPU_EXTENDED;
+  cw |= _FPU_DOUBLE;
+  _FPU_SETCW (cw);
+}
+#define libc_feholdexcept_setround_53bit libc_feholdexcept_setround_53bit
+
+static __always_inline void
+libc_feupdateenv_53bit (fenv_t *e)
+{
+  feupdateenv (e);
+
+  /* Unfortunately, feupdateenv fails to affect the rounding precision.
+     We can get that back by restoring the exact control word we saved.  */
+  _FPU_SETCW (e->__control_word);
+}
+#define libc_feupdateenv_53bit libc_feupdateenv_53bit
+
+#include_next <math_private.h>
 
-#undef libc_feholdexcept_setround_53bit
-#define libc_feholdexcept_setround_53bit(e, r) \
-  do                                           \
-    {                                          \
-      fpu_control_t cw;                                \
-      libc_feholdexcept_setround (e, r);       \
-      _FPU_GETCW (cw);                         \
-      cw &= ~(fpu_control_t) _FPU_EXTENDED;    \
-      cw |= _FPU_DOUBLE;                       \
-      _FPU_SETCW (cw);                         \
-    }                                          \
-  while (0)
-
-#undef libc_feupdateenv_53bit
-#define libc_feupdateenv_53bit(e)              \
-  do                                           \
-    {                                          \
-      fpu_control_t cw;                                \
-      libc_feupdateenv (e);                    \
-      _FPU_GETCW (cw);                         \
-      cw &= ~(fpu_control_t) _FPU_EXTENDED;    \
-      cw |= _FPU_EXTENDED;                     \
-      _FPU_SETCW (cw);                         \
-    }                                          \
-  while (0)
-
-#endif
+#endif /* _MATH_PRIVATE_H */