summaryrefslogtreecommitdiff
path: root/libc/sysdeps/generic/math_private.h
diff options
context:
space:
mode:
authorjoseph <joseph@7b3dc134-2b1b-0410-93df-9e9f96275f8d>2013-06-15 17:37:04 +0000
committerjoseph <joseph@7b3dc134-2b1b-0410-93df-9e9f96275f8d>2013-06-15 17:37:04 +0000
commit3625809e03b7287e244a6a2563d5217426e88d5c (patch)
treefecf84cbf45a9412ad727953f17ad0e5ef804e9f /libc/sysdeps/generic/math_private.h
parent8548b3be8c48bf62bd4e20fb0ee958338b01bc6c (diff)
downloadeglibc2-3625809e03b7287e244a6a2563d5217426e88d5c.tar.gz
Merge changes between r23217 and r23296 from /fsf/trunk.
git-svn-id: svn://svn.eglibc.org/trunk@23297 7b3dc134-2b1b-0410-93df-9e9f96275f8d
Diffstat (limited to 'libc/sysdeps/generic/math_private.h')
-rw-r--r--libc/sysdeps/generic/math_private.h63
1 files changed, 45 insertions, 18 deletions
diff --git a/libc/sysdeps/generic/math_private.h b/libc/sysdeps/generic/math_private.h
index 9d6ecade6..c0fc03d38 100644
--- a/libc/sysdeps/generic/math_private.h
+++ b/libc/sysdeps/generic/math_private.h
@@ -446,8 +446,8 @@ default_libc_feholdexcept_setround (fenv_t *e, int r)
# define libc_feholdexcept_setroundl default_libc_feholdexcept_setround
#endif
-#ifndef libc_feholdexcept_setround_53bit
-# define libc_feholdexcept_setround_53bit libc_feholdexcept_setround
+#ifndef libc_feholdsetround_53bit
+# define libc_feholdsetround_53bit libc_feholdsetround
#endif
#ifndef libc_fetestexcept
@@ -492,8 +492,8 @@ default_libc_feupdateenv (fenv_t *e)
# define libc_feupdateenvl default_libc_feupdateenv
#endif
-#ifndef libc_feupdateenv_53bit
-# define libc_feupdateenv_53bit libc_feupdateenv
+#ifndef libc_feresetround_53bit
+# define libc_feresetround_53bit libc_feresetround
#endif
static __always_inline int
@@ -553,35 +553,62 @@ default_libc_feupdateenv_test (fenv_t *e, int ex)
# define libc_feresetround_noexl libc_fesetenvl
#endif
+#if HAVE_RM_CTX
+/* Set/Restore Rounding Modes only when necessary. If defined, these functions
+ set/restore floating point state only if the state needed within the lexical
+ block is different from the current state. This saves a lot of time when
+ the floating point unit is much slower than the fixed point units. */
+
+# ifndef libc_feresetround_noex_ctx
+# define libc_feresetround_noex_ctx libc_fesetenv_ctx
+# endif
+# ifndef libc_feresetround_noexf_ctx
+# define libc_feresetround_noexf_ctx libc_fesetenvf_ctx
+# endif
+# ifndef libc_feresetround_noexl_ctx
+# define libc_feresetround_noexl_ctx libc_fesetenvl_ctx
+# endif
+
+# ifndef libc_feholdsetround_53bit_ctx
+# define libc_feholdsetround_53bit_ctx libc_feholdsetround_ctx
+# endif
+
+# ifndef libc_feresetround_53bit_ctx
+# define libc_feresetround_53bit_ctx libc_feresetround_ctx
+# endif
+
+# define SET_RESTORE_ROUND_GENERIC(RM,ROUNDFUNC,CLEANUPFUNC) \
+ struct rm_ctx ctx __attribute__((cleanup(CLEANUPFUNC ## _ctx))); \
+ ROUNDFUNC ## _ctx (&ctx, (RM))
+#else
+# define SET_RESTORE_ROUND_GENERIC(RM, ROUNDFUNC, CLEANUPFUNC) \
+ fenv_t __libc_save_rm __attribute__((cleanup(CLEANUPFUNC))); \
+ ROUNDFUNC (&__libc_save_rm, (RM))
+#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))
+ SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetround, libc_feresetround)
#define SET_RESTORE_ROUNDF(RM) \
- fenv_t __libc_save_rm __attribute__((cleanup(libc_feresetroundf))); \
- libc_feholdsetroundf (&__libc_save_rm, (RM))
+ SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetroundf, libc_feresetroundf)
#define SET_RESTORE_ROUNDL(RM) \
- fenv_t __libc_save_rm __attribute__((cleanup(libc_feresetroundl))); \
- libc_feholdsetroundl (&__libc_save_rm, (RM))
+ SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetroundl, libc_feresetroundl)
/* 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))
+ SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetround, libc_feresetround_noex)
#define SET_RESTORE_ROUND_NOEXF(RM) \
- fenv_t __libc_save_rm __attribute__((cleanup(libc_feresetround_noexf))); \
- libc_feholdsetroundf (&__libc_save_rm, (RM))
+ SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetroundf, libc_feresetround_noexf)
#define SET_RESTORE_ROUND_NOEXL(RM) \
- fenv_t __libc_save_rm __attribute__((cleanup(libc_feresetround_noexl))); \
- libc_feholdsetroundl (&__libc_save_rm, (RM))
+ SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetroundl, libc_feresetround_noexl)
/* 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))
+ SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetround_53bit, \
+ libc_feresetround_53bit)
#define __nan(str) \
(__builtin_constant_p (str) && str[0] == '\0' ? NAN : __nan (str))