blob: cc5dbc2f9793255229003e44911859ae876ae131 [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// The following is adapted from fdlibm (http://www.netlib.org/fdlibm).
2//
3// ====================================================
4// Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5//
6// Developed at SunSoft, a Sun Microsystems, Inc. business.
7// Permission to use, copy, modify, and distribute this
8// software is freely granted, provided that this notice
9// is preserved.
10// ====================================================
11//
12// The original source code covered by the above license above has been
13// modified significantly by Google Inc.
14// Copyright 2014 the V8 project authors. All rights reserved.
15
16#include "src/v8.h"
17
18#include "src/double.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040019#include "src/third_party/fdlibm/fdlibm.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000020
21
22namespace v8 {
23namespace fdlibm {
24
25#ifdef _MSC_VER
26inline double scalbn(double x, int y) { return _scalb(x, y); }
27#endif // _MSC_VER
28
29const double MathConstants::constants[] = {
Emily Bernierd0a1eb72015-03-24 16:35:39 -040030 6.36619772367581382433e-01, // invpio2 0
31 1.57079632673412561417e+00, // pio2_1 1
32 6.07710050650619224932e-11, // pio2_1t 2
33 6.07710050630396597660e-11, // pio2_2 3
34 2.02226624879595063154e-21, // pio2_2t 4
35 2.02226624871116645580e-21, // pio2_3 5
36 8.47842766036889956997e-32, // pio2_3t 6
37 -1.66666666666666324348e-01, // S1 7 coefficients for sin
38 8.33333333332248946124e-03, // 8
39 -1.98412698298579493134e-04, // 9
40 2.75573137070700676789e-06, // 10
41 -2.50507602534068634195e-08, // 11
42 1.58969099521155010221e-10, // S6 12
43 4.16666666666666019037e-02, // C1 13 coefficients for cos
44 -1.38888888888741095749e-03, // 14
45 2.48015872894767294178e-05, // 15
46 -2.75573143513906633035e-07, // 16
47 2.08757232129817482790e-09, // 17
48 -1.13596475577881948265e-11, // C6 18
49 3.33333333333334091986e-01, // T0 19 coefficients for tan
50 1.33333333333201242699e-01, // 20
51 5.39682539762260521377e-02, // 21
52 2.18694882948595424599e-02, // 22
53 8.86323982359930005737e-03, // 23
54 3.59207910759131235356e-03, // 24
55 1.45620945432529025516e-03, // 25
56 5.88041240820264096874e-04, // 26
57 2.46463134818469906812e-04, // 27
58 7.81794442939557092300e-05, // 28
59 7.14072491382608190305e-05, // 29
60 -1.85586374855275456654e-05, // 30
61 2.59073051863633712884e-05, // T12 31
62 7.85398163397448278999e-01, // pio4 32
63 3.06161699786838301793e-17, // pio4lo 33
64 6.93147180369123816490e-01, // ln2_hi 34
65 1.90821492927058770002e-10, // ln2_lo 35
66 6.666666666666666666e-01, // 2/3 36
67 6.666666666666735130e-01, // LP1 37 coefficients for log1p
68 3.999999999940941908e-01, // 38
69 2.857142874366239149e-01, // 39
70 2.222219843214978396e-01, // 40
71 1.818357216161805012e-01, // 41
72 1.531383769920937332e-01, // 42
73 1.479819860511658591e-01, // LP7 43
74 7.09782712893383973096e+02, // 44 overflow threshold for expm1
75 1.44269504088896338700e+00, // 1/ln2 45
76 -3.33333333333331316428e-02, // Q1 46 coefficients for expm1
77 1.58730158725481460165e-03, // 47
78 -7.93650757867487942473e-05, // 48
79 4.00821782732936239552e-06, // 49
80 -2.01099218183624371326e-07, // Q5 50
81 710.4758600739439, // 51 overflow threshold sinh, cosh
82 4.34294481903251816668e-01, // ivln10 52 coefficients for log10
83 3.01029995663611771306e-01, // log10_2hi 53
84 3.69423907715893078616e-13, // log10_2lo 54
85 5.99999999999994648725e-01, // L1 55 coefficients for log2
86 4.28571428578550184252e-01, // 56
87 3.33333329818377432918e-01, // 57
88 2.72728123808534006489e-01, // 58
89 2.30660745775561754067e-01, // 59
90 2.06975017800338417784e-01, // L6 60
91 9.61796693925975554329e-01, // cp 61 2/(3*ln(2))
92 9.61796700954437255859e-01, // cp_h 62
93 -7.02846165095275826516e-09, // cp_l 63
94 5.84962487220764160156e-01, // dp_h 64
95 1.35003920212974897128e-08 // dp_l 65
Ben Murdochb8a8cc12014-11-26 15:28:44 +000096};
97
98
99// Table of constants for 2/pi, 396 Hex digits (476 decimal) of 2/pi
100static const int two_over_pi[] = {
101 0xA2F983, 0x6E4E44, 0x1529FC, 0x2757D1, 0xF534DD, 0xC0DB62, 0x95993C,
102 0x439041, 0xFE5163, 0xABDEBB, 0xC561B7, 0x246E3A, 0x424DD2, 0xE00649,
103 0x2EEA09, 0xD1921C, 0xFE1DEB, 0x1CB129, 0xA73EE8, 0x8235F5, 0x2EBB44,
104 0x84E99C, 0x7026B4, 0x5F7E41, 0x3991D6, 0x398353, 0x39F49C, 0x845F8B,
105 0xBDF928, 0x3B1FF8, 0x97FFDE, 0x05980F, 0xEF2F11, 0x8B5A0A, 0x6D1F6D,
106 0x367ECF, 0x27CB09, 0xB74F46, 0x3F669E, 0x5FEA2D, 0x7527BA, 0xC7EBE5,
107 0xF17B3D, 0x0739F7, 0x8A5292, 0xEA6BFB, 0x5FB11F, 0x8D5D08, 0x560330,
108 0x46FC7B, 0x6BABF0, 0xCFBC20, 0x9AF436, 0x1DA9E3, 0x91615E, 0xE61B08,
109 0x659985, 0x5F14A0, 0x68408D, 0xFFD880, 0x4D7327, 0x310606, 0x1556CA,
110 0x73A8C9, 0x60E27B, 0xC08C6B};
111
112static const double zero = 0.0;
113static const double two24 = 1.6777216e+07;
114static const double one = 1.0;
115static const double twon24 = 5.9604644775390625e-08;
116
117static const double PIo2[] = {
118 1.57079625129699707031e+00, // 0x3FF921FB, 0x40000000
119 7.54978941586159635335e-08, // 0x3E74442D, 0x00000000
120 5.39030252995776476554e-15, // 0x3CF84698, 0x80000000
121 3.28200341580791294123e-22, // 0x3B78CC51, 0x60000000
122 1.27065575308067607349e-29, // 0x39F01B83, 0x80000000
123 1.22933308981111328932e-36, // 0x387A2520, 0x40000000
124 2.73370053816464559624e-44, // 0x36E38222, 0x80000000
125 2.16741683877804819444e-51 // 0x3569F31D, 0x00000000
126};
127
128
129int __kernel_rem_pio2(double* x, double* y, int e0, int nx) {
130 static const int32_t jk = 3;
131 double fw;
132 int32_t jx = nx - 1;
133 int32_t jv = (e0 - 3) / 24;
134 if (jv < 0) jv = 0;
135 int32_t q0 = e0 - 24 * (jv + 1);
136 int32_t m = jx + jk;
137
138 double f[10];
139 for (int i = 0, j = jv - jx; i <= m; i++, j++) {
140 f[i] = (j < 0) ? zero : static_cast<double>(two_over_pi[j]);
141 }
142
143 double q[10];
144 for (int i = 0; i <= jk; i++) {
145 fw = 0.0;
146 for (int j = 0; j <= jx; j++) fw += x[j] * f[jx + i - j];
147 q[i] = fw;
148 }
149
150 int32_t jz = jk;
151
152recompute:
153
154 int32_t iq[10];
155 double z = q[jz];
156 for (int i = 0, j = jz; j > 0; i++, j--) {
157 fw = static_cast<double>(static_cast<int32_t>(twon24 * z));
158 iq[i] = static_cast<int32_t>(z - two24 * fw);
159 z = q[j - 1] + fw;
160 }
161
162 z = scalbn(z, q0);
163 z -= 8.0 * std::floor(z * 0.125);
164 int32_t n = static_cast<int32_t>(z);
165 z -= static_cast<double>(n);
166 int32_t ih = 0;
167 if (q0 > 0) {
168 int32_t i = (iq[jz - 1] >> (24 - q0));
169 n += i;
170 iq[jz - 1] -= i << (24 - q0);
171 ih = iq[jz - 1] >> (23 - q0);
172 } else if (q0 == 0) {
173 ih = iq[jz - 1] >> 23;
174 } else if (z >= 0.5) {
175 ih = 2;
176 }
177
178 if (ih > 0) {
179 n += 1;
180 int32_t carry = 0;
181 for (int i = 0; i < jz; i++) {
182 int32_t j = iq[i];
183 if (carry == 0) {
184 if (j != 0) {
185 carry = 1;
186 iq[i] = 0x1000000 - j;
187 }
188 } else {
189 iq[i] = 0xffffff - j;
190 }
191 }
192 if (q0 == 1) {
193 iq[jz - 1] &= 0x7fffff;
194 } else if (q0 == 2) {
195 iq[jz - 1] &= 0x3fffff;
196 }
197 if (ih == 2) {
198 z = one - z;
199 if (carry != 0) z -= scalbn(one, q0);
200 }
201 }
202
203 if (z == zero) {
204 int32_t j = 0;
205 for (int i = jz - 1; i >= jk; i--) j |= iq[i];
206 if (j == 0) {
207 int32_t k = 1;
208 while (iq[jk - k] == 0) k++;
209 for (int i = jz + 1; i <= jz + k; i++) {
210 f[jx + i] = static_cast<double>(two_over_pi[jv + i]);
211 for (j = 0, fw = 0.0; j <= jx; j++) fw += x[j] * f[jx + i - j];
212 q[i] = fw;
213 }
214 jz += k;
215 goto recompute;
216 }
217 }
218
219 if (z == 0.0) {
220 jz -= 1;
221 q0 -= 24;
222 while (iq[jz] == 0) {
223 jz--;
224 q0 -= 24;
225 }
226 } else {
227 z = scalbn(z, -q0);
228 if (z >= two24) {
229 fw = static_cast<double>(static_cast<int32_t>(twon24 * z));
230 iq[jz] = static_cast<int32_t>(z - two24 * fw);
231 jz += 1;
232 q0 += 24;
233 iq[jz] = static_cast<int32_t>(fw);
234 } else {
235 iq[jz] = static_cast<int32_t>(z);
236 }
237 }
238
239 fw = scalbn(one, q0);
240 for (int i = jz; i >= 0; i--) {
241 q[i] = fw * static_cast<double>(iq[i]);
242 fw *= twon24;
243 }
244
245 double fq[10];
246 for (int i = jz; i >= 0; i--) {
247 fw = 0.0;
248 for (int k = 0; k <= jk && k <= jz - i; k++) fw += PIo2[k] * q[i + k];
249 fq[jz - i] = fw;
250 }
251
252 fw = 0.0;
253 for (int i = jz; i >= 0; i--) fw += fq[i];
254 y[0] = (ih == 0) ? fw : -fw;
255 fw = fq[0] - fw;
256 for (int i = 1; i <= jz; i++) fw += fq[i];
257 y[1] = (ih == 0) ? fw : -fw;
258 return n & 7;
259}
260
261
262int rempio2(double x, double* y) {
263 int32_t hx = static_cast<int32_t>(internal::double_to_uint64(x) >> 32);
264 int32_t ix = hx & 0x7fffffff;
265
266 if (ix >= 0x7ff00000) {
267 *y = base::OS::nan_value();
268 return 0;
269 }
270
271 int32_t e0 = (ix >> 20) - 1046;
272 uint64_t zi = internal::double_to_uint64(x) & 0xFFFFFFFFu;
273 zi |= static_cast<uint64_t>(ix - (e0 << 20)) << 32;
274 double z = internal::uint64_to_double(zi);
275
276 double tx[3];
277 for (int i = 0; i < 2; i++) {
278 tx[i] = static_cast<double>(static_cast<int32_t>(z));
279 z = (z - tx[i]) * two24;
280 }
281 tx[2] = z;
282
283 int nx = 3;
284 while (tx[nx - 1] == zero) nx--;
285 int n = __kernel_rem_pio2(tx, y, e0, nx);
286 if (hx < 0) {
287 y[0] = -y[0];
288 y[1] = -y[1];
289 return -n;
290 }
291 return n;
292}
293}
294} // namespace v8::internal