aboutsummaryrefslogtreecommitdiff
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.zip
glibc-7d2e8012cfb4fa30086ef330ef1b993cfcc3dd99.tar.gz
glibc-7d2e8012cfb4fa30086ef330ef1b993cfcc3dd99.tar.bz2
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 2d6d574..aace9ef 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 6520226..9236448 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 */