aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/x86_64
diff options
context:
space:
mode:
authorRichard Henderson <rth@twiddle.net>2012-03-18 15:58:00 -0700
committerRichard Henderson <rth@twiddle.net>2012-03-19 06:51:39 -0700
commitbd37f2ee314147c69a39817d590149cf1181ef47 (patch)
tree453f01145f7e526a6f5fdd5f3a6c1dde93f59ce8 /sysdeps/x86_64
parentd0adc9223031b606c3c7781b4ec41462796ab313 (diff)
downloadglibc-bd37f2ee314147c69a39817d590149cf1181ef47.tar
glibc-bd37f2ee314147c69a39817d590149cf1181ef47.tar.gz
glibc-bd37f2ee314147c69a39817d590149cf1181ef47.tar.bz2
glibc-bd37f2ee314147c69a39817d590149cf1181ef47.zip
Optimize private 387 fenv access; share code between i386 and x86_64.
Diffstat (limited to 'sysdeps/x86_64')
-rw-r--r--sysdeps/x86_64/fpu/math_private.h120
1 files changed, 1 insertions, 119 deletions
diff --git a/sysdeps/x86_64/fpu/math_private.h b/sysdeps/x86_64/fpu/math_private.h
index aa208b2e18..67c5f6a324 100644
--- a/sysdeps/x86_64/fpu/math_private.h
+++ b/sysdeps/x86_64/fpu/math_private.h
@@ -1,33 +1,12 @@
#ifndef X86_64_MATH_PRIVATE_H
#define X86_64_MATH_PRIVATE_H 1
-#include <fenv.h>
-
-#define math_opt_barrier(x) \
- ({ __typeof(x) __x; \
- if (sizeof (x) <= sizeof (double)) \
- __asm ("" : "=x" (__x) : "0" (x)); \
- else \
- __asm ("" : "=t" (__x) : "0" (x)); \
- __x; })
-#define math_force_eval(x) \
- do { \
- if (sizeof (x) <= sizeof (double)) \
- __asm __volatile ("" : : "x" (x)); \
- else \
- __asm __volatile ("" : : "f" (x)); \
- } while (0)
-
/* We can do a few things better on x86-64. */
#if defined __AVX__ || defined SSE2AVX
# define MOVD "vmovd"
-# define STMXCSR "vstmxcsr"
-# define LDMXCSR "vldmxcsr"
#else
# define MOVD "movd"
-# define STMXCSR "stmxcsr"
-# define LDMXCSR "ldmxcsr"
#endif
/* Direct movement of float into integer register. */
@@ -64,104 +43,7 @@
f = f__; \
} 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 int
-libc_feupdateenv_test (fenv_t *e, int ex)
-{
- unsigned int mxcsr, old_mxcsr, cur_ex;
- asm volatile (STMXCSR " %0" : "=m" (*&mxcsr));
- cur_ex = mxcsr & FE_ALL_EXCEPT;
-
- /* Merge current exceptions with the old environment. */
- old_mxcsr = e->__mxcsr;
- mxcsr = old_mxcsr | cur_ex;
- asm volatile (LDMXCSR " %0" : : "m" (*&mxcsr));
-
- /* Raise SIGFPE for any new exceptions since the hold. Expect that
- the normal environment has all exceptions masked. */
- if (__builtin_expect ((old_mxcsr >> 7) & cur_ex, 0))
- __feraiseexcept (cur_ex);
-
- /* Test for exceptions raised since the hold. */
- return cur_ex & ex;
-}
-#define libc_feupdateenv_test libc_feupdateenv_test
-#define libc_feupdateenv_testf libc_feupdateenv_test
-
-static __always_inline void
-libc_feupdateenv (fenv_t *e)
-{
- libc_feupdateenv_test (e, 0);
-}
-#define libc_feupdateenv libc_feupdateenv
-#define libc_feupdateenvf libc_feupdateenv
-
-static __always_inline void
-libc_feholdsetround (fenv_t *e, int r)
-{
- unsigned int mxcsr;
- asm (STMXCSR " %0" : "=m" (*&mxcsr));
- e->__mxcsr = mxcsr;
- mxcsr = (mxcsr & ~0x6000) | (r << 3);
- asm volatile (LDMXCSR " %0" : : "m" (*&mxcsr));
-}
-#define libc_feholdsetround libc_feholdsetround
-#define libc_feholdsetroundf libc_feholdsetround
-
-static __always_inline void
-libc_feresetround (fenv_t *e)
-{
- unsigned int mxcsr;
- asm (STMXCSR " %0" : "=m" (*&mxcsr));
- mxcsr = (mxcsr & ~0x6000) | (e->__mxcsr & 0x6000);
- asm volatile (LDMXCSR " %0" : : "m" (*&mxcsr));
-}
-#define libc_feresetround libc_feresetround
-#define libc_feresetroundf libc_feresetround
-
+#include <sysdeps/i386/fpu/fenv_private.h>
#include_next <math_private.h>
extern __always_inline double