Use __builtin_fma more in dbl-64 code.
[glibc.git] / sysdeps / ieee754 / dbl-64 / s_sincos.c
blobc389226b0425d35ca202f720a8ee4006306eaad4
1 /* Compute sine and cosine of argument.
2 Copyright (C) 1997-2016 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, see
18 <http://www.gnu.org/licenses/>. */
20 #include <errno.h>
21 #include <math.h>
23 #include <math_private.h>
25 #define __sin __sin_local
26 #define __cos __cos_local
27 #define IN_SINCOS 1
28 #include "s_sin.c"
30 /* Consolidated version of reduce_and_compute in s_sin.c that does range
31 reduction only once and computes sin and cos together. */
32 static inline void
33 __always_inline
34 reduce_and_compute_sincos (double x, double *sinx, double *cosx)
36 double a, da;
37 unsigned int n = __branred (x, &a, &da);
39 n = n & 3;
41 if (n == 1 || n == 2)
43 a = -a;
44 da = -da;
47 if (n & 1)
49 double *temp = cosx;
50 cosx = sinx;
51 sinx = temp;
54 if (a * a < 0.01588)
55 *sinx = bsloww (a, da, x, n);
56 else
57 *sinx = bsloww1 (a, da, x, n);
58 *cosx = bsloww2 (a, da, x, n);
61 void
62 __sincos (double x, double *sinx, double *cosx)
64 mynumber u;
65 int k;
67 SET_RESTORE_ROUND_53BIT (FE_TONEAREST);
69 u.x = x;
70 k = 0x7fffffff & u.i[HIGH_HALF];
72 if (k < 0x400368fd)
74 *sinx = __sin_local (x);
75 *cosx = __cos_local (x);
76 return;
78 if (k < 0x419921FB)
80 double a, da;
81 int4 n = reduce_sincos_1 (x, &a, &da);
83 *sinx = do_sincos_1 (a, da, x, n, 0);
84 *cosx = do_sincos_1 (a, da, x, n, 1);
86 return;
88 if (k < 0x42F00000)
90 double a, da;
91 int4 n = reduce_sincos_2 (x, &a, &da);
93 *sinx = do_sincos_2 (a, da, x, n, 0);
94 *cosx = do_sincos_2 (a, da, x, n, 1);
96 return;
98 if (k < 0x7ff00000)
100 reduce_and_compute_sincos (x, sinx, cosx);
101 return;
104 if (isinf (x))
105 __set_errno (EDOM);
107 *sinx = *cosx = x / x;
109 weak_alias (__sincos, sincos)
110 #ifdef NO_LONG_DOUBLE
111 strong_alias (__sincos, __sincosl)
112 weak_alias (__sincos, sincosl)
113 #endif