about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRichard Henderson <rth@twiddle.net>2012-03-18 10:12:16 -0700
committerRichard Henderson <rth@twiddle.net>2012-03-19 06:49:04 -0700
commit7d2e8012cfb4fa30086ef330ef1b993cfcc3dd99 (patch)
treecd4cb429c364286f515a65090132166fad505d14
parentb4dabbb47a174e1075b5b93f29093319eab69f2c (diff)
downloadglibc-7d2e8012cfb4fa30086ef330ef1b993cfcc3dd99.tar.gz
glibc-7d2e8012cfb4fa30086ef330ef1b993cfcc3dd99.tar.xz
glibc-7d2e8012cfb4fa30086ef330ef1b993cfcc3dd99.zip
i386: Convert libc_{feholdexcept_setround,updateenv}_53bit to functions.
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.
-rw-r--r--ChangeLog4
-rw-r--r--sysdeps/i386/fpu/math_private.h58
2 files changed, 33 insertions, 29 deletions
diff --git a/ChangeLog b/ChangeLog
index 2d6d574804..aace9ef3db 100644
--- 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.
diff --git a/sysdeps/i386/fpu/math_private.h b/sysdeps/i386/fpu/math_private.h
index 65202269b0..9236448978 100644
--- a/sysdeps/i386/fpu/math_private.h
+++ b/sysdeps/i386/fpu/math_private.h
@@ -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 */