From: Siddhesh Poyarekar Date: Mon, 21 Dec 2015 05:10:32 +0000 (+0530) Subject: Consolidate range reduction in sincos for x > 281474976710656 X-Git-Tag: upstream/2.24~687 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a045832debe4191bcffed6e539a5470152e9c9e8;p=platform%2Fupstream%2Fglibc.git Consolidate range reduction in sincos for x > 281474976710656 Range reduction needs to be done only once for sin and cos, so copy over all of the relevant functions (__sin, __cos, reduce_and_compute) and consolidate common code. --- diff --git a/ChangeLog b/ChangeLog index 0024c1e..c8281dd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2015-12-21 Siddhesh Poyarekar + + * sysdeps/ieee754/dbl-64/s_sin.c (__sin) [!IN_SINCOS]: Skip + common code for sincos. + (__cos) [!IN_SINCOS]: Likewise. + * sysdeps/ieee754/dbl-64/s_sincos.c (reduce_and_compute_sincos): + New function. + (__sincos): Use it. + 2015-12-20 Aurelien Jarno * sysdeps/i386/fpu/libm-test-ulps: Move to .... diff --git a/sysdeps/ieee754/dbl-64/s_sin.c b/sysdeps/ieee754/dbl-64/s_sin.c index a635a86..b619905 100644 --- a/sysdeps/ieee754/dbl-64/s_sin.c +++ b/sysdeps/ieee754/dbl-64/s_sin.c @@ -497,6 +497,7 @@ __sin (double x) } } /* else if (k < 0x42F00000 ) */ +#ifndef IN_SINCOS /* -----------------281474976710656 <|x| <2^1024----------------------------*/ else if (k < 0x7ff00000) retval = reduce_and_compute (x, 0); @@ -508,6 +509,7 @@ __sin (double x) __set_errno (EDOM); retval = x / x; } +#endif return retval; } @@ -729,6 +731,7 @@ __cos (double x) } } /* else if (k < 0x42F00000 ) */ +#ifndef IN_SINCOS /* 281474976710656 <|x| <2^1024 */ else if (k < 0x7ff00000) retval = reduce_and_compute (x, 1); @@ -739,6 +742,7 @@ __cos (double x) __set_errno (EDOM); retval = x / x; /* |x| > 2^1024 */ } +#endif return retval; } diff --git a/sysdeps/ieee754/dbl-64/s_sincos.c b/sysdeps/ieee754/dbl-64/s_sincos.c index 2a3fc06..f50ffa6 100644 --- a/sysdeps/ieee754/dbl-64/s_sincos.c +++ b/sysdeps/ieee754/dbl-64/s_sincos.c @@ -27,13 +27,64 @@ #define IN_SINCOS 1 #include "s_sin.c" +/* Consolidated version of reduce_and_compute in s_sin.c that does range + reduction only once and computes sin and cos together. */ +static inline void +__always_inline +reduce_and_compute_sincos (double x, double *sinx, double *cosx) +{ + double a, da; + unsigned int n = __branred (x, &a, &da); + + n = n & 3; + + if (n == 1 || n == 2) + { + a = -a; + da = -da; + } + + if (n & 1) + { + double *temp = cosx; + cosx = sinx; + sinx = temp; + } + + if (a * a < 0.01588) + *sinx = bsloww (a, da, x, n); + else + *sinx = bsloww1 (a, da, x, n); + *cosx = bsloww2 (a, da, x, n); +} + void __sincos (double x, double *sinx, double *cosx) { + mynumber u; + int k; + SET_RESTORE_ROUND_53BIT (FE_TONEAREST); - *sinx = __sin (x); - *cosx = __cos (x); + u.x = x; + k = 0x7fffffff & u.i[HIGH_HALF]; + + if (k < 0x42F00000) + { + *sinx = __sin_local (x); + *cosx = __cos_local (x); + return; + } + if (k < 0x7ff00000) + { + reduce_and_compute_sincos (x, sinx, cosx); + return; + } + + if (isinf (x)) + __set_errno (EDOM); + + *sinx = *cosx = x / x; } weak_alias (__sincos, sincos) #ifdef NO_LONG_DOUBLE