Browse Source

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.
ibm/2.28/master
Florian Weimer 8 years ago
parent
commit
f496b28e61
  1. 22
      ChangeLog
  2. 68
      sysdeps/generic/math_private.h
  3. 8
      sysdeps/i386/Makefile
  4. 18
      sysdeps/i386/fpu/fenv_private.h

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>
* string/tst-cmp.c: Include <libc-diag.h>.

68
sysdeps/generic/math_private.h

@ -428,33 +428,6 @@ default_libc_feupdateenv_test (fenv_t *e, int ex)
# define HAVE_RM_CTX 0
#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_feholdsetround_noex_ctx
# define libc_feholdsetround_noex_ctx libc_feholdsetround_ctx
# endif
# ifndef libc_feholdsetround_noexf_ctx
# define libc_feholdsetround_noexf_ctx libc_feholdsetroundf_ctx
# endif
# ifndef libc_feholdsetround_noexl_ctx
# define libc_feholdsetround_noexl_ctx libc_feholdsetroundl_ctx
# endif
# 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
#else
/* Default implementation using standard fenv functions.
Avoid unnecessary rounding mode changes by first checking the
@ -462,7 +435,7 @@ default_libc_feupdateenv_test (fenv_t *e, int ex)
important for performance. */
static __always_inline void
libc_feholdsetround_ctx (struct rm_ctx *ctx, int round)
default_libc_feholdsetround_ctx (struct rm_ctx *ctx, int round)
{
ctx->updated_status = false;
@ -476,7 +449,7 @@ libc_feholdsetround_ctx (struct rm_ctx *ctx, int round)
}
static __always_inline void
libc_feresetround_ctx (struct rm_ctx *ctx)
default_libc_feresetround_ctx (struct rm_ctx *ctx)
{
/* Restore the rounding mode if updated. */
if (__glibc_unlikely (ctx->updated_status))
@ -484,7 +457,7 @@ libc_feresetround_ctx (struct rm_ctx *ctx)
}
static __always_inline void
libc_feholdsetround_noex_ctx (struct rm_ctx *ctx, int round)
default_libc_feholdsetround_noex_ctx (struct rm_ctx *ctx, int round)
{
/* Save exception flags and rounding mode, and disable exception
traps. */
@ -496,12 +469,45 @@ libc_feholdsetround_noex_ctx (struct rm_ctx *ctx, int round)
}
static __always_inline void
libc_feresetround_noex_ctx (struct rm_ctx *ctx)
default_libc_feresetround_noex_ctx (struct rm_ctx *ctx)
{
/* Restore exception flags and rounding mode. */
__fesetenv (&ctx->env);
}
#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_feholdsetround_noex_ctx
# define libc_feholdsetround_noex_ctx libc_feholdsetround_ctx
# endif
# ifndef libc_feholdsetround_noexf_ctx
# define libc_feholdsetround_noexf_ctx libc_feholdsetroundf_ctx
# endif
# ifndef libc_feholdsetround_noexl_ctx
# define libc_feholdsetround_noexl_ctx libc_feholdsetroundl_ctx
# endif
# 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
#else
# define libc_feholdsetround_ctx default_libc_feholdsetround_ctx
# define libc_feresetround_ctx default_libc_feresetround_ctx
# define libc_feholdsetround_noex_ctx default_libc_feholdsetround_noex_ctx
# define libc_feresetround_noex_ctx default_libc_feresetround_noex_ctx
# define libc_feholdsetroundf_ctx libc_feholdsetround_ctx
# define libc_feholdsetroundl_ctx libc_feholdsetround_ctx
# define libc_feresetroundf_ctx libc_feresetround_ctx

8
sysdeps/i386/Makefile

@ -5,6 +5,14 @@ asm-CPPFLAGS += -DGAS_SYNTAX
# The i386 `long double' is a distinct type we support.
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)
sysdep_routines += cacheinfo
endif

18
sysdeps/i386/fpu/fenv_private.h

@ -460,11 +460,19 @@ libc_feupdateenv_387_ctx (struct rm_ctx *ctx)
#endif /* __SSE_MATH__ */
#ifdef __SSE2_MATH__
# define libc_feholdexcept_setround_ctx libc_feholdexcept_setround_sse_ctx
# define libc_fesetenv_ctx libc_fesetenv_sse_ctx
# define libc_feupdateenv_ctx libc_feupdateenv_sse_ctx
# define libc_feholdsetround_ctx libc_feholdsetround_sse_ctx
# define libc_feresetround_ctx libc_feresetround_sse_ctx
# if defined (__x86_64__) || !defined (MATH_SET_BOTH_ROUNDING_MODES)
# define libc_feholdexcept_setround_ctx libc_feholdexcept_setround_sse_ctx
# define libc_fesetenv_ctx libc_fesetenv_sse_ctx
# define libc_feupdateenv_ctx libc_feupdateenv_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
# define libc_feholdexcept_setround_ctx libc_feholdexcept_setround_387_ctx
# define libc_feupdateenv_ctx libc_feupdateenv_387_ctx

Loading…
Cancel
Save