mirror of
git://sourceware.org/git/glibc.git
synced 2024-11-21 01:12:26 +08:00
b1c347e2cd
The tile version of math_private.h defines some inline functions for fenv.h functions, to optimize away internal calls to these functions that do nothing given no support for floating-point exceptions and rounding modes. (Some functions may have error cases for invalid arguments, but those aren't applicable to the internal calls from within glibc.) Other configurations lacking support for exceptions and rounding modes lack such inline functions. This patch moves them to the generic math_private.h, appropriately conditioned, so that all such configurations can benefit from the. include/fenv.h is made to check whether there are any non-default rounding modes; that needs to be done there, rather than later, because get-rounding-mode.h defines values for otherwise unsupported FE_* rounding modes. It also gives an error for FE_TONEAREST undefined, a case that already did not work for building the glibc testsuite; the convention has by now been established that all architectures need to provide a version of bits/fenv.h that at least defines FE_TONEAREST. Tested with build-many-glibcs.py. As expected, installed stripped shared libraries are unchanged for tile and for architectures supporting exceptions and rounding modes, but changed for non-tile architectures not supporting exceptions and rounding modes that previously lacked this optimization (e.g. Nios II libm.so is about 1kB smaller). The optimization is not in fact complete (does not cover feholdexcept / __feholdexcept, so a few calls to those remain unnecessarily within libm even after this patch), but that can be dealt with separately. * include/fenv.h [!_ISOMAC && !FE_TONEAREST]: Give #error. [!_ISOMAC] (FE_HAVE_ROUNDING_MODES): New macro. * sysdeps/generic/math_private.h [!FE_HAVE_ROUNDING_MODES && FE_ALL_EXCEPT == 0] (fegetenv): New inline function. [!FE_HAVE_ROUNDING_MODES && FE_ALL_EXCEPT == 0] (__fegetenv): Likewise. [!FE_HAVE_ROUNDING_MODES && FE_ALL_EXCEPT == 0] (fesetenv): Likewise. [!FE_HAVE_ROUNDING_MODES && FE_ALL_EXCEPT == 0] (__fesetenv): Likewise. [!FE_HAVE_ROUNDING_MODES && FE_ALL_EXCEPT == 0] (feupdateenv): Likewise. [!FE_HAVE_ROUNDING_MODES && FE_ALL_EXCEPT == 0] (__feupdateenv): Likewise. [!FE_HAVE_ROUNDING_MODES] (fegetround): Likewise. [!FE_HAVE_ROUNDING_MODES] (__fegetround): Likewise. [!FE_HAVE_ROUNDING_MODES] (fesetround): Likewise. [!FE_HAVE_ROUNDING_MODES] (__fesetround): Likewise. * sysdeps/tile/math_private.h (fegetenv): Remove inline function. (__fegetenv): Likewise. (fesetenv): Likewise. (__fesetenv): Likewise. (feupdateenv): Likewise. (__feupdateenv): Likewise. (fegetround): Likewise. (__fegetround): Likewise. (fesetround): Likewise. (__fesetround): Likewise.
63 lines
1.9 KiB
C
63 lines
1.9 KiB
C
#ifndef _FENV_H
|
|
#include <math/fenv.h>
|
|
|
|
#ifndef _ISOMAC
|
|
# include <stdbool.h>
|
|
/* Now define the internal interfaces. */
|
|
|
|
extern int __feclearexcept (int __excepts);
|
|
extern int __fegetexcept (void);
|
|
extern int __fegetexceptflag (fexcept_t *__flagp, int __excepts);
|
|
extern int __feraiseexcept (int __excepts);
|
|
extern int __fesetexceptflag (const fexcept_t *__flagp, int __excepts);
|
|
extern int __fegetenv (fenv_t *__envp);
|
|
extern int __fesetenv (const fenv_t *__envp);
|
|
extern int __feupdateenv (const fenv_t *__envp);
|
|
extern __typeof (fegetround) __fegetround __attribute_pure__;
|
|
extern __typeof (feholdexcept) __feholdexcept;
|
|
extern __typeof (fesetround) __fesetround;
|
|
|
|
libm_hidden_proto (feraiseexcept)
|
|
libm_hidden_proto (__feraiseexcept)
|
|
libm_hidden_proto (fegetenv)
|
|
libm_hidden_proto (__fegetenv)
|
|
libm_hidden_proto (fegetround)
|
|
libm_hidden_proto (__fegetround)
|
|
libm_hidden_proto (fesetenv)
|
|
libm_hidden_proto (__fesetenv)
|
|
libm_hidden_proto (fesetround)
|
|
libm_hidden_proto (__fesetround)
|
|
libm_hidden_proto (feholdexcept)
|
|
libm_hidden_proto (__feholdexcept)
|
|
libm_hidden_proto (feupdateenv)
|
|
libm_hidden_proto (__feupdateenv)
|
|
libm_hidden_proto (fetestexcept)
|
|
libm_hidden_proto (feclearexcept)
|
|
|
|
/* Rounding mode context. This allows functions to set/restore rounding mode
|
|
only when the desired rounding mode is different from the current rounding
|
|
mode. */
|
|
struct rm_ctx
|
|
{
|
|
fenv_t env;
|
|
bool updated_status;
|
|
};
|
|
|
|
/* Track whether rounding mode macros were defined, since
|
|
get-rounding-mode.h may define default versions if they weren't.
|
|
FE_TONEAREST must always be defined (even if no changes of rounding
|
|
mode are supported, glibc requires it to be defined to represent
|
|
the default rounding mode). */
|
|
# ifndef FE_TONEAREST
|
|
# error "FE_TONEAREST not defined"
|
|
# endif
|
|
# if defined FE_DOWNWARD || defined FE_TOWARDZERO || defined FE_UPWARD
|
|
# define FE_HAVE_ROUNDING_MODES 1
|
|
# else
|
|
# define FE_HAVE_ROUNDING_MODES 0
|
|
# endif
|
|
|
|
#endif
|
|
|
|
#endif
|