comparison libquadmath/math/sincosq_kernel.c @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents 04ced10e8804
children
comparison
equal deleted inserted replaced
131:84e7813d76e9 145:1830386684a0
1 /* Quad-precision floating point sine and cosine on <-pi/4,pi/4>. 1 /* Quad-precision floating point sine and cosine on <-pi/4,pi/4>.
2 Copyright (C) 1999-2017 Free Software Foundation, Inc. 2 Copyright (C) 1999-2018 Free Software Foundation, Inc.
3 This file is part of the GNU C Library. 3 This file is part of the GNU C Library.
4 Contributed by Jakub Jelinek <jj@ultra.linux.cz> 4 Contributed by Jakub Jelinek <jj@ultra.linux.cz>
5 5
6 The GNU C Library is free software; you can redistribute it and/or 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 7 modify it under the terms of the GNU Lesser General Public
12 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details. 14 Lesser General Public License for more details.
15 15
16 You should have received a copy of the GNU Lesser General Public 16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, write to the Free 17 License along with the GNU C Library; if not, see
18 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 18 <http://www.gnu.org/licenses/>. */
19 02111-1307 USA. */
20 19
21 #include "quadmath-imp.h" 20 #include "quadmath-imp.h"
22 21
23 static const __float128 c[] = { 22 static const __float128 c[] = {
24 #define ONE c[0] 23 #define ONE c[0]
87 1.60590438367608957516841576404938118e-10Q, /* 3fde6124613a811480538a9a41957115 */ 86 1.60590438367608957516841576404938118e-10Q, /* 3fde6124613a811480538a9a41957115 */
88 -7.64716343504264506714019494041582610e-13Q, /* bfd6ae7f3d5aef30c7bc660b060ef365 */ 87 -7.64716343504264506714019494041582610e-13Q, /* bfd6ae7f3d5aef30c7bc660b060ef365 */
89 2.81068754939739570236322404393398135e-15Q, /* 3fce9510115aabf87aceb2022a9a9180 */ 88 2.81068754939739570236322404393398135e-15Q, /* 3fce9510115aabf87aceb2022a9a9180 */
90 }; 89 };
91 90
92 #define SINCOSQ_COS_HI 0 91 #define SINCOSL_COS_HI 0
93 #define SINCOSQ_COS_LO 1 92 #define SINCOSL_COS_LO 1
94 #define SINCOSQ_SIN_HI 2 93 #define SINCOSL_SIN_HI 2
95 #define SINCOSQ_SIN_LO 3 94 #define SINCOSL_SIN_LO 3
96 extern const __float128 __sincosq_table[]; 95 extern const __float128 __sincosq_table[];
97 96
98 void 97 void
99 __quadmath_kernel_sincosq(__float128 x, __float128 y, __float128 *sinx, 98 __quadmath_kernel_sincosq(__float128 x, __float128 y, __float128 *sinx, __float128 *cosx, int iy)
100 __float128 *cosx, int iy)
101 { 99 {
102 __float128 h, l, z, sin_l, cos_l_m1; 100 __float128 h, l, z, sin_l, cos_l_m1;
103 int64_t ix; 101 int64_t ix;
104 uint32_t tix, hix, index; 102 uint32_t tix, hix, index;
105 GET_FLT128_MSW64 (ix, x); 103 GET_FLT128_MSW64 (ix, x);
126 z*(COS5+z*(COS6+z*(COS7+z*COS8)))))))); 124 z*(COS5+z*(COS6+z*(COS7+z*COS8))))))));
127 } 125 }
128 else 126 else
129 { 127 {
130 /* So that we don't have to use too large polynomial, we find 128 /* So that we don't have to use too large polynomial, we find
131 l and h such that x = l + h, where fabsl(l) <= 1.0/256 with 83 129 l and h such that x = l + h, where fabsq(l) <= 1.0/256 with 83
132 possible values for h. We look up cosq(h) and sinq(h) in 130 possible values for h. We look up cosq(h) and sinq(h) in
133 pre-computed tables, compute cosq(l) and sinq(l) using a 131 pre-computed tables, compute cosq(l) and sinq(l) using a
134 Chebyshev polynomial of degree 10(11) and compute 132 Chebyshev polynomial of degree 10(11) and compute
135 sinq(h+l) = sinq(h)cosq(l) + cosq(h)sinq(l) and 133 sinq(h+l) = sinq(h)cosq(l) + cosq(h)sinq(l) and
136 cosq(h+l) = cosq(h)cosq(l) - sinq(h)sinq(l). */ 134 cosq(h+l) = cosq(h)cosq(l) - sinq(h)sinq(l). */
137 index = 0x3ffe - (tix >> 16); 135 index = 0x3ffe - (tix >> 16);
138 hix = (tix + (0x200 << index)) & (0xfffffc00 << index); 136 hix = (tix + (0x200 << index)) & (0xfffffc00 << index);
139 if (signbitq (x)) 137 if (signbitq (x))
140 { 138 {
141 x = -x; 139 x = -x;
142 y = -y; 140 y = -y;
143 } 141 }
144 switch (index) 142 switch (index)
145 { 143 {
146 case 0: index = ((45 << 10) + hix - 0x3ffe0000) >> 8; break; 144 case 0: index = ((45 << 10) + hix - 0x3ffe0000) >> 8; break;
147 case 1: index = ((13 << 11) + hix - 0x3ffd0000) >> 9; break; 145 case 1: index = ((13 << 11) + hix - 0x3ffd0000) >> 9; break;
148 default: 146 default:
155 else 153 else
156 l = x - h; 154 l = x - h;
157 z = l * l; 155 z = l * l;
158 sin_l = l*(ONE+z*(SSIN1+z*(SSIN2+z*(SSIN3+z*(SSIN4+z*SSIN5))))); 156 sin_l = l*(ONE+z*(SSIN1+z*(SSIN2+z*(SSIN3+z*(SSIN4+z*SSIN5)))));
159 cos_l_m1 = z*(SCOS1+z*(SCOS2+z*(SCOS3+z*(SCOS4+z*SCOS5)))); 157 cos_l_m1 = z*(SCOS1+z*(SCOS2+z*(SCOS3+z*(SCOS4+z*SCOS5))));
160 z = __sincosq_table [index + SINCOSQ_SIN_HI] 158 z = __sincosq_table [index + SINCOSL_SIN_HI]
161 + (__sincosq_table [index + SINCOSQ_SIN_LO] 159 + (__sincosq_table [index + SINCOSL_SIN_LO]
162 + (__sincosq_table [index + SINCOSQ_SIN_HI] * cos_l_m1) 160 + (__sincosq_table [index + SINCOSL_SIN_HI] * cos_l_m1)
163 + (__sincosq_table [index + SINCOSQ_COS_HI] * sin_l)); 161 + (__sincosq_table [index + SINCOSL_COS_HI] * sin_l));
164 *sinx = (ix < 0) ? -z : z; 162 *sinx = (ix < 0) ? -z : z;
165 *cosx = __sincosq_table [index + SINCOSQ_COS_HI] 163 *cosx = __sincosq_table [index + SINCOSL_COS_HI]
166 + (__sincosq_table [index + SINCOSQ_COS_LO] 164 + (__sincosq_table [index + SINCOSL_COS_LO]
167 - (__sincosq_table [index + SINCOSQ_SIN_HI] * sin_l 165 - (__sincosq_table [index + SINCOSL_SIN_HI] * sin_l
168 - __sincosq_table [index + SINCOSQ_COS_HI] * cos_l_m1)); 166 - __sincosq_table [index + SINCOSL_COS_HI] * cos_l_m1));
169 } 167 }
170 } 168 }