mirror of git://sourceware.org/git/glibc.git
math: Set 387 and SSE2 rounding mode for tgamma on i386 [BZ #23253]
Previously, only the SSE2 rounding mode was set, so the assembler implementations using 387 were not following the expecting rounding mode.
This commit is contained in:
parent
99c7adf99f
commit
f496b28e61
22
ChangeLog
22
ChangeLog
|
@ -1,3 +1,25 @@
|
||||||
|
2018-06-21 Florian Weimer <fweimer@redhat.com>
|
||||||
|
|
||||||
|
[BZ #23253]
|
||||||
|
* sysdeps/generic/math_private.h (default_libc_feholdsetround_ctx):
|
||||||
|
Renamed from libc_feholdsetround_ctx.
|
||||||
|
(default_libc_feresetround_ctx): Renamed from
|
||||||
|
libc_feresetround_ctx.
|
||||||
|
(default_libc_feholdsetround_noex_ctx): Renamed from
|
||||||
|
libc_feholdsetround_noex_ctx.
|
||||||
|
(default_libc_feresetround_noex_ctx): Renamed from
|
||||||
|
libc_feresetround_noex_ctx.
|
||||||
|
[!HAVE_RM_CTX] (libc_feholdsetround_ctx, libc_feresetround_ctx)
|
||||||
|
(libc_feholdsetround_noex_ctx, libc_feresetround_noex_ctx): Macros
|
||||||
|
forwardning to the old implementations under the new names.
|
||||||
|
* sysdeps/i386/fpu/fenv_private.h [__SSE_MATH__]
|
||||||
|
(libc_feholdexcept_setround_ctx, libc_fesetenv_ctx)
|
||||||
|
(libc_feupdateenv_ctx, libc_feholdsetround_ctx)
|
||||||
|
(libc_feresetround_ctx): Forward to default implements for i386
|
||||||
|
and MATH_SET_BOTH_ROUNDING_MODES.
|
||||||
|
* sysdeps/i386/Makefile [$(subdir) == math] (CFLAGS-e_gamma_r.c):
|
||||||
|
Add -DMATH_SET_BOTH_ROUNDING_MODES.
|
||||||
|
|
||||||
2018-06-20 Joseph Myers <joseph@codesourcery.com>
|
2018-06-20 Joseph Myers <joseph@codesourcery.com>
|
||||||
|
|
||||||
* string/tst-cmp.c: Include <libc-diag.h>.
|
* string/tst-cmp.c: Include <libc-diag.h>.
|
||||||
|
|
|
@ -428,6 +428,53 @@ default_libc_feupdateenv_test (fenv_t *e, int ex)
|
||||||
# define HAVE_RM_CTX 0
|
# define HAVE_RM_CTX 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Default implementation using standard fenv functions.
|
||||||
|
Avoid unnecessary rounding mode changes by first checking the
|
||||||
|
current rounding mode. Note the use of __glibc_unlikely is
|
||||||
|
important for performance. */
|
||||||
|
|
||||||
|
static __always_inline void
|
||||||
|
default_libc_feholdsetround_ctx (struct rm_ctx *ctx, int round)
|
||||||
|
{
|
||||||
|
ctx->updated_status = false;
|
||||||
|
|
||||||
|
/* Update rounding mode only if different. */
|
||||||
|
if (__glibc_unlikely (round != get_rounding_mode ()))
|
||||||
|
{
|
||||||
|
ctx->updated_status = true;
|
||||||
|
__fegetenv (&ctx->env);
|
||||||
|
__fesetround (round);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static __always_inline void
|
||||||
|
default_libc_feresetround_ctx (struct rm_ctx *ctx)
|
||||||
|
{
|
||||||
|
/* Restore the rounding mode if updated. */
|
||||||
|
if (__glibc_unlikely (ctx->updated_status))
|
||||||
|
__feupdateenv (&ctx->env);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __always_inline void
|
||||||
|
default_libc_feholdsetround_noex_ctx (struct rm_ctx *ctx, int round)
|
||||||
|
{
|
||||||
|
/* Save exception flags and rounding mode, and disable exception
|
||||||
|
traps. */
|
||||||
|
__feholdexcept (&ctx->env);
|
||||||
|
|
||||||
|
/* Update rounding mode only if different. */
|
||||||
|
if (__glibc_unlikely (round != get_rounding_mode ()))
|
||||||
|
__fesetround (round);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __always_inline void
|
||||||
|
default_libc_feresetround_noex_ctx (struct rm_ctx *ctx)
|
||||||
|
{
|
||||||
|
/* Restore exception flags and rounding mode. */
|
||||||
|
__fesetenv (&ctx->env);
|
||||||
|
}
|
||||||
|
|
||||||
#if HAVE_RM_CTX
|
#if HAVE_RM_CTX
|
||||||
/* Set/Restore Rounding Modes only when necessary. If defined, these functions
|
/* Set/Restore Rounding Modes only when necessary. If defined, these functions
|
||||||
set/restore floating point state only if the state needed within the lexical
|
set/restore floating point state only if the state needed within the lexical
|
||||||
|
@ -456,51 +503,10 @@ default_libc_feupdateenv_test (fenv_t *e, int ex)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
/* Default implementation using standard fenv functions.
|
# define libc_feholdsetround_ctx default_libc_feholdsetround_ctx
|
||||||
Avoid unnecessary rounding mode changes by first checking the
|
# define libc_feresetround_ctx default_libc_feresetround_ctx
|
||||||
current rounding mode. Note the use of __glibc_unlikely is
|
# define libc_feholdsetround_noex_ctx default_libc_feholdsetround_noex_ctx
|
||||||
important for performance. */
|
# define libc_feresetround_noex_ctx default_libc_feresetround_noex_ctx
|
||||||
|
|
||||||
static __always_inline void
|
|
||||||
libc_feholdsetround_ctx (struct rm_ctx *ctx, int round)
|
|
||||||
{
|
|
||||||
ctx->updated_status = false;
|
|
||||||
|
|
||||||
/* Update rounding mode only if different. */
|
|
||||||
if (__glibc_unlikely (round != get_rounding_mode ()))
|
|
||||||
{
|
|
||||||
ctx->updated_status = true;
|
|
||||||
__fegetenv (&ctx->env);
|
|
||||||
__fesetround (round);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static __always_inline void
|
|
||||||
libc_feresetround_ctx (struct rm_ctx *ctx)
|
|
||||||
{
|
|
||||||
/* Restore the rounding mode if updated. */
|
|
||||||
if (__glibc_unlikely (ctx->updated_status))
|
|
||||||
__feupdateenv (&ctx->env);
|
|
||||||
}
|
|
||||||
|
|
||||||
static __always_inline void
|
|
||||||
libc_feholdsetround_noex_ctx (struct rm_ctx *ctx, int round)
|
|
||||||
{
|
|
||||||
/* Save exception flags and rounding mode, and disable exception
|
|
||||||
traps. */
|
|
||||||
__feholdexcept (&ctx->env);
|
|
||||||
|
|
||||||
/* Update rounding mode only if different. */
|
|
||||||
if (__glibc_unlikely (round != get_rounding_mode ()))
|
|
||||||
__fesetround (round);
|
|
||||||
}
|
|
||||||
|
|
||||||
static __always_inline void
|
|
||||||
libc_feresetround_noex_ctx (struct rm_ctx *ctx)
|
|
||||||
{
|
|
||||||
/* Restore exception flags and rounding mode. */
|
|
||||||
__fesetenv (&ctx->env);
|
|
||||||
}
|
|
||||||
|
|
||||||
# define libc_feholdsetroundf_ctx libc_feholdsetround_ctx
|
# define libc_feholdsetroundf_ctx libc_feholdsetround_ctx
|
||||||
# define libc_feholdsetroundl_ctx libc_feholdsetround_ctx
|
# define libc_feholdsetroundl_ctx libc_feholdsetround_ctx
|
||||||
|
|
|
@ -5,6 +5,14 @@ asm-CPPFLAGS += -DGAS_SYNTAX
|
||||||
# The i386 `long double' is a distinct type we support.
|
# The i386 `long double' is a distinct type we support.
|
||||||
long-double-fcts = yes
|
long-double-fcts = yes
|
||||||
|
|
||||||
|
ifeq ($(subdir),math)
|
||||||
|
# These functions change the rounding mode internally and need to
|
||||||
|
# update both the SSE2 rounding mode and the 387 rounding mode. See
|
||||||
|
# the handling of MATH_SET_BOTH_ROUNDING_MODES in
|
||||||
|
# sysdeps/i386/fpu/fenv_private.h.
|
||||||
|
CFLAGS-e_gamma_r.c += -DMATH_SET_BOTH_ROUNDING_MODES
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(subdir),string)
|
ifeq ($(subdir),string)
|
||||||
sysdep_routines += cacheinfo
|
sysdep_routines += cacheinfo
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -460,11 +460,19 @@ libc_feupdateenv_387_ctx (struct rm_ctx *ctx)
|
||||||
#endif /* __SSE_MATH__ */
|
#endif /* __SSE_MATH__ */
|
||||||
|
|
||||||
#ifdef __SSE2_MATH__
|
#ifdef __SSE2_MATH__
|
||||||
# define libc_feholdexcept_setround_ctx libc_feholdexcept_setround_sse_ctx
|
# if defined (__x86_64__) || !defined (MATH_SET_BOTH_ROUNDING_MODES)
|
||||||
# define libc_fesetenv_ctx libc_fesetenv_sse_ctx
|
# define libc_feholdexcept_setround_ctx libc_feholdexcept_setround_sse_ctx
|
||||||
# define libc_feupdateenv_ctx libc_feupdateenv_sse_ctx
|
# define libc_fesetenv_ctx libc_fesetenv_sse_ctx
|
||||||
# define libc_feholdsetround_ctx libc_feholdsetround_sse_ctx
|
# define libc_feupdateenv_ctx libc_feupdateenv_sse_ctx
|
||||||
# define libc_feresetround_ctx libc_feresetround_sse_ctx
|
# define libc_feholdsetround_ctx libc_feholdsetround_sse_ctx
|
||||||
|
# define libc_feresetround_ctx libc_feresetround_sse_ctx
|
||||||
|
# else
|
||||||
|
# define libc_feholdexcept_setround_ctx default_libc_feholdexcept_setround_ctx
|
||||||
|
# define libc_fesetenv_ctx default_libc_fesetenv_ctx
|
||||||
|
# define libc_feupdateenv_ctx default_libc_feupdateenv_ctx
|
||||||
|
# define libc_feholdsetround_ctx default_libc_feholdsetround_ctx
|
||||||
|
# define libc_feresetround_ctx default_libc_feresetround_ctx
|
||||||
|
# endif
|
||||||
#else
|
#else
|
||||||
# define libc_feholdexcept_setround_ctx libc_feholdexcept_setround_387_ctx
|
# define libc_feholdexcept_setround_ctx libc_feholdexcept_setround_387_ctx
|
||||||
# define libc_feupdateenv_ctx libc_feupdateenv_387_ctx
|
# define libc_feupdateenv_ctx libc_feupdateenv_387_ctx
|
||||||
|
|
Loading…
Reference in New Issue