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.
This commit is contained in:
Richard Henderson 2012-03-18 10:12:16 -07:00
parent b4dabbb47a
commit 7d2e8012cf
2 changed files with 33 additions and 29 deletions

View File

@ -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.

View 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)
static __always_inline void
libc_feholdexcept_setround_53bit (fenv_t *e, int r)
{
feholdexcept (e);
fesetround (r);
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>
#include <fpu_control.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 */