1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-07-29 11:41:21 +03:00

Convert libc_feholdexcept et al from macros to inline functions.

This commit is contained in:
Richard Henderson
2012-03-09 12:51:27 -08:00
parent 4851a949b4
commit b4dabbb47a
3 changed files with 153 additions and 78 deletions

View File

@ -1,5 +1,23 @@
2012-03-19 Richard Henderson <rth@twiddle.net> 2012-03-19 Richard Henderson <rth@twiddle.net>
* sysdeps/generic/math_private.h: Include <fenv.h>.
(default_libc_feholdexcept): New.
(default_libc_feholdexcept_setround): New.
(default_libc_fesetenv, default_libc_feupdateenv): New.
(libc_feholdexcept): Only define if undefined.
(libc_feholdexceptf, libc_feholdexceptl): Likewise.
(libc_feholdexcept_setround, libc_feholdexcept_setroundf): Likewise.
(libc_feholdexcept_setroundl): Likewise.
(libc_feholdexcept_setround_53bit): Likewise.
(libc_fetestexcept, libc_fetestexceptf, libc_fetestexceptl): Likewise.
(libc_fesetenv, libc_fesetenvf, libc_fesetenvl): Likewise.
(libc_feupdateenv, libc_feupdateenvf, libc_feupdateenvl): Likewise.
(libc_feupdateenv_53bit): Likewise.
* sysdeps/x86_64/fpu/math_private.h: Include <fenv.h>.
(libc_feholdexcept): Convert from macro to inline function.
(libc_feholdexcept_setround, libc_fetestexcept): Likewise.
(libc_fesetenv, libc_feupdateenv): Likewise.
* sysdeps/generic/math_private.h (GET_HIGH_WORD): Define only if * sysdeps/generic/math_private.h (GET_HIGH_WORD): Define only if
not previously defined. not previously defined.
(GET_LOW_WORD, EXTRACT_WORDS64, INSERT_WORDS): Likewise. (GET_LOW_WORD, EXTRACT_WORDS64, INSERT_WORDS): Likewise.

View File

@ -19,6 +19,7 @@
#include <endian.h> #include <endian.h>
#include <stdint.h> #include <stdint.h>
#include <sys/types.h> #include <sys/types.h>
#include <fenv.h>
/* The original fdlibm code used statements like: /* The original fdlibm code used statements like:
n0 = ((*(int*)&one)>>29)^1; * index of high word * n0 = ((*(int*)&one)>>29)^1; * index of high word *
@ -372,33 +373,89 @@ extern void __docos (double __x, double __dx, double __v[]);
know what operations are going to be performed. Therefore we know what operations are going to be performed. Therefore we
define additional interfaces. By default they refer to the normal define additional interfaces. By default they refer to the normal
interfaces. */ interfaces. */
#define libc_feholdexcept(e) (void) feholdexcept (e)
#define libc_feholdexceptf(e) (void) feholdexcept (e)
#define libc_feholdexceptl(e) (void) feholdexcept (e)
#define libc_feholdexcept_setround(e, r) \ static __always_inline void
do { feholdexcept (e); fesetround (r); } while (0) default_libc_feholdexcept (fenv_t *e)
#define libc_feholdexcept_setroundf(e, r) \ {
do { feholdexcept (e); fesetround (r); } while (0) (void) feholdexcept (e);
#define libc_feholdexcept_setroundl(e, r) \ }
do { feholdexcept (e); fesetround (r); } while (0)
#define libc_feholdexcept_setround_53bit(e, r) \ #ifndef libc_feholdexcept
libc_feholdexcept_setround (e, r) # define libc_feholdexcept default_libc_feholdexcept
#endif
#ifndef libc_feholdexceptf
# define libc_feholdexceptf default_libc_feholdexcept
#endif
#ifndef libc_feholdexceptl
# define libc_feholdexceptl default_libc_feholdexcept
#endif
#define libc_fetestexcept(e) fetestexcept (e) static __always_inline void
#define libc_fetestexceptf(e) fetestexcept (e) default_libc_feholdexcept_setround (fenv_t *e, int r)
#define libc_fetestexceptl(e) fetestexcept (e) {
feholdexcept (e);
fesetround (r);
}
#define libc_fesetenv(e) (void) fesetenv (e) #ifndef libc_feholdexcept_setround
#define libc_fesetenvf(e) (void) fesetenv (e) # define libc_feholdexcept_setround default_libc_feholdexcept_setround
#define libc_fesetenvl(e) (void) fesetenv (e) #endif
#ifndef libc_feholdexcept_setroundf
# define libc_feholdexcept_setroundf default_libc_feholdexcept_setround
#endif
#ifndef libc_feholdexcept_setroundl
# define libc_feholdexcept_setroundl default_libc_feholdexcept_setround
#endif
#define libc_feupdateenv(e) (void) feupdateenv (e) #ifndef libc_feholdexcept_setround_53bit
#define libc_feupdateenvf(e) (void) feupdateenv (e) # define libc_feholdexcept_setround_53bit libc_feholdexcept_setround
#define libc_feupdateenvl(e) (void) feupdateenv (e) #endif
#define libc_feupdateenv_53bit(e) libc_feupdateenv (e) #ifndef libc_fetestexcept
# define libc_fetestexcept fetestexcept
#endif
#ifndef libc_fetestexceptf
# define libc_fetestexceptf fetestexcept
#endif
#ifndef libc_fetestexceptl
# define libc_fetestexceptl fetestexcept
#endif
static __always_inline void
default_libc_fesetenv (fenv_t *e)
{
(void) fesetenv (e);
}
#ifndef libc_fesetenv
# define libc_fesetenv default_libc_fesetenv
#endif
#ifndef libc_fesetenvf
# define libc_fesetenvf default_libc_fesetenv
#endif
#ifndef libc_fesetenvl
# define libc_fesetenvl default_libc_fesetenv
#endif
static __always_inline void
default_libc_feupdateenv (fenv_t *e)
{
(void) feupdateenv (e);
}
#ifndef libc_feupdateenv
# define libc_feupdateenv default_libc_feupdateenv
#endif
#ifndef libc_feupdateenvf
# define libc_feupdateenvf default_libc_feupdateenv
#endif
#ifndef libc_feupdateenvl
# define libc_feupdateenvl default_libc_feupdateenv
#endif
#ifndef libc_feupdateenv_53bit
# define libc_feupdateenv_53bit libc_feupdateenv
#endif
#define __nan(str) \ #define __nan(str) \
(__builtin_constant_p (str) && str[0] == '\0' ? NAN : __nan (str)) (__builtin_constant_p (str) && str[0] == '\0' ? NAN : __nan (str))

View File

@ -1,6 +1,8 @@
#ifndef X86_64_MATH_PRIVATE_H #ifndef X86_64_MATH_PRIVATE_H
#define X86_64_MATH_PRIVATE_H 1 #define X86_64_MATH_PRIVATE_H 1
#include <fenv.h>
#define math_opt_barrier(x) \ #define math_opt_barrier(x) \
({ __typeof(x) __x; \ ({ __typeof(x) __x; \
if (sizeof (x) <= sizeof (double)) \ if (sizeof (x) <= sizeof (double)) \
@ -62,6 +64,61 @@
f = f__; \ f = f__; \
} while (0) } while (0)
/* Specialized variants of the <fenv.h> interfaces which only handle
either the FPU or the SSE unit. */
static __always_inline void
libc_feholdexcept (fenv_t *e)
{
unsigned int mxcsr;
asm (STMXCSR " %0" : "=m" (*&mxcsr));
e->__mxcsr = mxcsr;
mxcsr = (mxcsr | 0x1f80) & ~0x3f;
asm volatile (LDMXCSR " %0" : : "m" (*&mxcsr));
}
#define libc_feholdexcept libc_feholdexcept
#define libc_feholdexceptf libc_feholdexcept
static __always_inline void
libc_feholdexcept_setround (fenv_t *e, int r)
{
unsigned int mxcsr;
asm (STMXCSR " %0" : "=m" (*&mxcsr));
e->__mxcsr = mxcsr;
mxcsr = ((mxcsr | 0x1f80) & ~0x603f) | (r << 3);
asm volatile (LDMXCSR " %0" : : "m" (*&mxcsr));
}
#define libc_feholdexcept_setround libc_feholdexcept_setround
#define libc_feholdexcept_setroundf libc_feholdexcept_setround
static __always_inline int
libc_fetestexcept (int e)
{
unsigned int mxcsr;
asm volatile (STMXCSR " %0" : "=m" (*&mxcsr));
return mxcsr & e & FE_ALL_EXCEPT;
}
#define libc_fetestexcept libc_fetestexcept
#define libc_fetestexceptf libc_fetestexcept
static __always_inline void
libc_fesetenv (fenv_t *e)
{
asm volatile (LDMXCSR " %0" : : "m" (e->__mxcsr));
}
#define libc_fesetenv libc_fesetenv
#define libc_fesetenvf libc_fesetenv
static __always_inline void
libc_feupdateenv (fenv_t *e)
{
unsigned int mxcsr;
asm volatile (STMXCSR " %0" : "=m" (*&mxcsr));
asm volatile (LDMXCSR " %0" : : "m" ((e)->__mxcsr));
__feraiseexcept (mxcsr & FE_ALL_EXCEPT);
}
#define libc_feupdateenv libc_feupdateenv
#define libc_feupdateenvf libc_feupdateenv
#include_next <math_private.h> #include_next <math_private.h>
extern __always_inline double extern __always_inline double
@ -146,61 +203,4 @@ __floorf (float d)
} }
#endif /* __SSE4_1__ */ #endif /* __SSE4_1__ */
/* Specialized variants of the <fenv.h> interfaces which only handle
either the FPU or the SSE unit. */
#undef libc_feholdexcept
#define libc_feholdexcept(e) \
do { \
unsigned int mxcsr; \
asm (STMXCSR " %0" : "=m" (*&mxcsr)); \
(e)->__mxcsr = mxcsr; \
mxcsr = (mxcsr | 0x1f80) & ~0x3f; \
asm volatile (LDMXCSR " %0" : : "m" (*&mxcsr)); \
} while (0)
#undef libc_feholdexceptf
#define libc_feholdexceptf(e) libc_feholdexcept (e)
// #define libc_feholdexceptl(e) (void) feholdexcept (e)
#undef libc_feholdexcept_setround
#define libc_feholdexcept_setround(e, r) \
do { \
unsigned int mxcsr; \
asm (STMXCSR " %0" : "=m" (*&mxcsr)); \
(e)->__mxcsr = mxcsr; \
mxcsr = ((mxcsr | 0x1f80) & ~0x603f) | ((r) << 3); \
asm volatile (LDMXCSR " %0" : : "m" (*&mxcsr)); \
} while (0)
#undef libc_feholdexcept_setroundf
#define libc_feholdexcept_setroundf(e, r) libc_feholdexcept_setround (e, r)
// #define libc_feholdexcept_setroundl(e, r) ...
#undef libc_fetestexcept
#define libc_fetestexcept(e) \
({ unsigned int mxcsr; \
asm volatile (STMXCSR " %0" : "=m" (*&mxcsr)); \
mxcsr & (e) & FE_ALL_EXCEPT; })
#undef libc_fetestexceptf
#define libc_fetestexceptf(e) libc_fetestexcept (e)
// #define libc_fetestexceptl(e) fetestexcept (e)
#undef libc_fesetenv
#define libc_fesetenv(e) \
asm volatile (LDMXCSR " %0" : : "m" ((e)->__mxcsr))
#undef libc_fesetenvf
#define libc_fesetenvf(e) libc_fesetenv (e)
// #define libc_fesetenvl(e) (void) fesetenv (e)
#undef libc_feupdateenv
#define libc_feupdateenv(e) \
do { \
unsigned int mxcsr; \
asm volatile (STMXCSR " %0" : "=m" (*&mxcsr)); \
asm volatile (LDMXCSR " %0" : : "m" ((e)->__mxcsr)); \
__feraiseexcept (mxcsr & FE_ALL_EXCEPT); \
} while (0)
#undef libc_feupdateenvf
#define libc_feupdateenvf(e) libc_feupdateenv (e)
// #define libc_feupdateenvl(e) (void) feupdateenv (e)
#endif /* X86_64_MATH_PRIVATE_H */ #endif /* X86_64_MATH_PRIVATE_H */