diff options
author | Richard Henderson <rth@twiddle.net> | 2012-03-10 08:55:53 -0800 |
---|---|---|
committer | Richard Henderson <rth@twiddle.net> | 2012-03-19 06:49:44 -0700 |
commit | eb92c487b35e26aa1e08815c4480d0bc5cc9f370 (patch) | |
tree | 99b3d94fcac1b61ea4c23f5575c109508db5e590 /sysdeps/generic | |
parent | 7d2e8012cfb4fa30086ef330ef1b993cfcc3dd99 (diff) | |
download | glibc-eb92c487b35e26aa1e08815c4480d0bc5cc9f370.tar.gz glibc-eb92c487b35e26aa1e08815c4480d0bc5cc9f370.tar.xz glibc-eb92c487b35e26aa1e08815c4480d0bc5cc9f370.zip |
Create and use SET_RESTORE_ROUND{,_NOEX,_53BIT}{,F,L}.
Diffstat (limited to 'sysdeps/generic')
-rw-r--r-- | sysdeps/generic/math_private.h | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/sysdeps/generic/math_private.h b/sysdeps/generic/math_private.h index ab4b47bfe0..0b945f9afc 100644 --- a/sysdeps/generic/math_private.h +++ b/sysdeps/generic/math_private.h @@ -457,6 +457,75 @@ default_libc_feupdateenv (fenv_t *e) # define libc_feupdateenv_53bit libc_feupdateenv #endif +/* Save and set the rounding mode. The use of fenv_t to store the old mode + allows a target-specific version of this function to avoid converting the + rounding mode from the fpu format. By default we have no choice but to + manipulate the entire env. */ + +#ifndef libc_feholdsetround +# define libc_feholdsetround libc_feholdexcept_setround +#endif +#ifndef libc_feholdsetroundf +# define libc_feholdsetroundf libc_feholdexcept_setroundf +#endif +#ifndef libc_feholdsetroundl +# define libc_feholdsetroundl libc_feholdexcept_setroundl +#endif + +/* ... and the reverse. */ + +#ifndef libc_feresetround +# define libc_feresetround libc_feupdateenv +#endif +#ifndef libc_feresetroundf +# define libc_feresetroundf libc_feupdateenvf +#endif +#ifndef libc_feresetroundl +# define libc_feresetroundl libc_feupdateenvl +#endif + +/* ... and a version that may also discard exceptions. */ + +#ifndef libc_feresetround_noex +# define libc_feresetround_noex libc_fesetenv +#endif +#ifndef libc_feresetround_noexf +# define libc_feresetround_noexf libc_fesetenvf +#endif +#ifndef libc_feresetround_noexl +# define libc_feresetround_noexl libc_fesetenvl +#endif + +/* Save and restore the rounding mode within a lexical block. */ + +#define SET_RESTORE_ROUND(RM) \ + fenv_t __libc_save_rm __attribute__((cleanup(libc_feresetround))); \ + libc_feholdsetround (&__libc_save_rm, (RM)) +#define SET_RESTORE_ROUNDF(RM) \ + fenv_t __libc_save_rm __attribute__((cleanup(libc_feresetroundf))); \ + libc_feholdsetroundf (&__libc_save_rm, (RM)) +#define SET_RESTORE_ROUNDL(RM) \ + fenv_t __libc_save_rm __attribute__((cleanup(libc_feresetroundl))); \ + libc_feholdsetroundl (&__libc_save_rm, (RM)) + +/* Save and restore the rounding mode within a lexical block, and also + the set of exceptions raised within the block may be discarded. */ + +#define SET_RESTORE_ROUND_NOEX(RM) \ + fenv_t __libc_save_rm __attribute__((cleanup(libc_feresetround_noex))); \ + libc_feholdsetround (&__libc_save_rm, (RM)) +#define SET_RESTORE_ROUND_NOEXF(RM) \ + fenv_t __libc_save_rm __attribute__((cleanup(libc_feresetround_noexf))); \ + libc_feholdsetroundf (&__libc_save_rm, (RM)) +#define SET_RESTORE_ROUND_NOEXL(RM) \ + fenv_t __libc_save_rm __attribute__((cleanup(libc_feresetround_noexl))); \ + libc_feholdsetroundl (&__libc_save_rm, (RM)) + +/* Like SET_RESTORE_ROUND, but also set rounding precision to 53 bits. */ +#define SET_RESTORE_ROUND_53BIT(RM) \ + fenv_t __libc_save_rm __attribute__((cleanup(libc_feupdateenv_53bit))); \ + libc_feholdexcept_setround_53bit (&__libc_save_rm, (RM)) + #define __nan(str) \ (__builtin_constant_p (str) && str[0] == '\0' ? NAN : __nan (str)) #define __nanf(str) \ |