diff options
Diffstat (limited to 'sysdeps/x86_64/fpu/bits/mathinline.h')
-rw-r--r-- | sysdeps/x86_64/fpu/bits/mathinline.h | 89 |
1 files changed, 79 insertions, 10 deletions
diff --git a/sysdeps/x86_64/fpu/bits/mathinline.h b/sysdeps/x86_64/fpu/bits/mathinline.h index 5bdf47ecbf..c3e03e8ca1 100644 --- a/sysdeps/x86_64/fpu/bits/mathinline.h +++ b/sysdeps/x86_64/fpu/bits/mathinline.h @@ -30,32 +30,34 @@ #endif -#if defined __USE_ISOC99 && defined __GNUC__ && __GNUC__ >= 2 +#if defined __GNUC__ && __GNUC__ >= 2 +# ifdef __USE_ISOC99 +__BEGIN_NAMESPACE_C99 /* Test for negative number. Used in the signbit() macro. */ __MATH_INLINE int __NTH (__signbitf (float __x)) { -# if __WORDSIZE == 32 +# if __WORDSIZE == 32 __extension__ union { float __f; int __i; } __u = { __f: __x }; return __u.__i < 0; -# else +# else int __m; __asm ("pmovmskb %1, %0" : "=r" (__m) : "x" (__x)); return __m & 0x8; -# endif +# endif } __MATH_INLINE int __NTH (__signbit (double __x)) { -# if __WORDSIZE == 32 +# if __WORDSIZE == 32 __extension__ union { double __d; int __i[2]; } __u = { __d: __x }; return __u.__i[1] < 0; -# else +# else int __m; __asm ("pmovmskb %1, %0" : "=r" (__m) : "x" (__x)); return __m & 0x80; -# endif +# endif } __MATH_INLINE int __NTH (__signbitl (long double __x)) @@ -64,9 +66,6 @@ __NTH (__signbitl (long double __x)) return (__u.__i[2] & 0x8000) != 0; } -#ifdef __USE_ISOC99 -__BEGIN_NAMESPACE_C99 - /* Round to nearest integer. */ # if __WORDSIZE == 64 || defined __SSE_MATH__ __MATH_INLINE long int @@ -101,10 +100,14 @@ __NTH (llrint (double __x)) __asm ("cvtsd2si %1, %0" : "=r" (__res) : "xm" (__x)); return __res; } + +__END_NAMESPACE_C99 # endif # if defined __FINITE_MATH_ONLY__ && __FINITE_MATH_ONLY__ > 0 \ && (__WORDSIZE == 64 || defined __SSE2_MATH__) +__BEGIN_NAMESPACE_C99 + /* Determine maximum of two values. */ __MATH_INLINE float __NTH (fmaxf (float __x, float __y)) @@ -137,4 +140,70 @@ __NTH (fmin (double __x, double __y)) __END_NAMESPACE_C99 # endif +# if defined __SSE4_1__ && (__WORDSIZE == 64 || defined __SSE2_MATH__) +# if defined __USE_MISC || defined __USE_XOPEN_EXTENDED || defined __USE_ISOC99 +__BEGIN_NAMESPACE_C99 + +/* Round to nearest integer. */ +__MATH_INLINE double +__NTH (rint (double __x)) +{ + double __res; + __asm ("roundsd $4, %1, %0" : "=x" (__res) : "x" (__x)); + return __res; +} +__MATH_INLINE float +__NTH (rintf (float __x)) +{ + float __res; + __asm ("roundss $4, %1, %0" : "=x" (__res) : "x" (__x)); + return __res; +} + +__END_NAMESPACE_C99 +# endif + +__BEGIN_NAMESPACE_STD +/* Smallest integral value not less than X. */ +__MATH_INLINE double +__NTH (ceil (double __x)) +{ + double __res; + __asm ("roundsd $2, %1, %0" : "=x" (__res) : "x" (__x)); + return __res; +} +__END_NAMESPACE_STD + +__BEGIN_NAMESPACE_C99 +__MATH_INLINE float +__NTH (ceilf (float __x)) +{ + float __res; + __asm ("roundss $2, %1, %0" : "=x" (__res) : "x" (__x)); + return __res; +} +__END_NAMESPACE_C99 + +__BEGIN_NAMESPACE_STD +/* Largest integer not greater than X. */ +__MATH_INLINE double +__NTH (ceil (double __x)) +{ + double __res; + __asm ("roundsd $1, %1, %0" : "=x" (__res) : "x" (__x)); + return __res; +} +__END_NAMESPACE_STD + +__BEGIN_NAMESPACE_C99 +__MATH_INLINE float +__NTH (ceilf (float __x)) +{ + float __res; + __asm ("roundss $1, %1, %0" : "=x" (__res) : "x" (__x)); + return __res; +} +__END_NAMESPACE_C99 +# endif + #endif |