toilscript 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +94 -0
  3. package/README.md +114 -0
  4. package/bin/asc.js +35 -0
  5. package/bin/asinit.js +468 -0
  6. package/dist/asc.d.ts +4 -0
  7. package/dist/toilscript.d.ts +4 -0
  8. package/dist/transform.cjs +1 -0
  9. package/dist/transform.d.ts +1 -0
  10. package/dist/transform.js +1 -0
  11. package/lib/binaryen.d.ts +2 -0
  12. package/lib/binaryen.js +2 -0
  13. package/package.json +114 -0
  14. package/std/README.md +6 -0
  15. package/std/assembly/array.ts +550 -0
  16. package/std/assembly/arraybuffer.ts +77 -0
  17. package/std/assembly/atomics.ts +127 -0
  18. package/std/assembly/bindings/asyncify.ts +16 -0
  19. package/std/assembly/bindings/dom.ts +291 -0
  20. package/std/assembly/bindings/node.ts +6 -0
  21. package/std/assembly/bitflags.ts +53 -0
  22. package/std/assembly/builtins.ts +2650 -0
  23. package/std/assembly/byteslice.ts +177 -0
  24. package/std/assembly/compat.ts +2 -0
  25. package/std/assembly/console.ts +42 -0
  26. package/std/assembly/crypto.ts +9 -0
  27. package/std/assembly/dataview.ts +181 -0
  28. package/std/assembly/date.ts +375 -0
  29. package/std/assembly/diagnostics.ts +11 -0
  30. package/std/assembly/encoding.ts +151 -0
  31. package/std/assembly/endian.ts +45 -0
  32. package/std/assembly/error.ts +44 -0
  33. package/std/assembly/fixedarray.ts +173 -0
  34. package/std/assembly/fixedmap.ts +326 -0
  35. package/std/assembly/fixedset.ts +275 -0
  36. package/std/assembly/function.ts +42 -0
  37. package/std/assembly/index.d.ts +2891 -0
  38. package/std/assembly/iterator.ts +35 -0
  39. package/std/assembly/map.ts +269 -0
  40. package/std/assembly/math.ts +3289 -0
  41. package/std/assembly/memory.ts +123 -0
  42. package/std/assembly/number.ts +388 -0
  43. package/std/assembly/object.ts +36 -0
  44. package/std/assembly/performance.ts +9 -0
  45. package/std/assembly/pointer.ts +80 -0
  46. package/std/assembly/polyfills.ts +27 -0
  47. package/std/assembly/process.ts +50 -0
  48. package/std/assembly/reference.ts +48 -0
  49. package/std/assembly/regexp.ts +12 -0
  50. package/std/assembly/rt/README.md +83 -0
  51. package/std/assembly/rt/common.ts +81 -0
  52. package/std/assembly/rt/index-incremental.ts +2 -0
  53. package/std/assembly/rt/index-memory.ts +1 -0
  54. package/std/assembly/rt/index-minimal.ts +2 -0
  55. package/std/assembly/rt/index-stub.ts +1 -0
  56. package/std/assembly/rt/index.d.ts +37 -0
  57. package/std/assembly/rt/itcms.ts +419 -0
  58. package/std/assembly/rt/memory-runtime.ts +94 -0
  59. package/std/assembly/rt/rtrace.ts +15 -0
  60. package/std/assembly/rt/stub.ts +133 -0
  61. package/std/assembly/rt/tcms.ts +254 -0
  62. package/std/assembly/rt/tlsf.ts +592 -0
  63. package/std/assembly/rt.ts +90 -0
  64. package/std/assembly/set.ts +225 -0
  65. package/std/assembly/shared/feature.ts +68 -0
  66. package/std/assembly/shared/runtime.ts +13 -0
  67. package/std/assembly/shared/target.ts +11 -0
  68. package/std/assembly/shared/tsconfig.json +11 -0
  69. package/std/assembly/shared/typeinfo.ts +72 -0
  70. package/std/assembly/staticarray.ts +423 -0
  71. package/std/assembly/string.ts +850 -0
  72. package/std/assembly/symbol.ts +114 -0
  73. package/std/assembly/table.ts +16 -0
  74. package/std/assembly/tsconfig.json +6 -0
  75. package/std/assembly/typedarray.ts +1954 -0
  76. package/std/assembly/uri.ts +17 -0
  77. package/std/assembly/util/bytes.ts +107 -0
  78. package/std/assembly/util/casemap.ts +497 -0
  79. package/std/assembly/util/error.ts +58 -0
  80. package/std/assembly/util/hash.ts +117 -0
  81. package/std/assembly/util/math.ts +1922 -0
  82. package/std/assembly/util/memory.ts +290 -0
  83. package/std/assembly/util/number.ts +873 -0
  84. package/std/assembly/util/sort.ts +313 -0
  85. package/std/assembly/util/string.ts +1202 -0
  86. package/std/assembly/util/uri.ts +275 -0
  87. package/std/assembly/vector.ts +4 -0
  88. package/std/assembly.json +16 -0
  89. package/std/portable/index.d.ts +461 -0
  90. package/std/portable/index.js +416 -0
  91. package/std/portable.json +11 -0
  92. package/std/types/assembly/index.d.ts +1 -0
  93. package/std/types/assembly/package.json +3 -0
  94. package/std/types/portable/index.d.ts +1 -0
  95. package/std/types/portable/package.json +3 -0
  96. package/tsconfig-base.json +13 -0
  97. package/util/README.md +23 -0
  98. package/util/browser/fs.js +1 -0
  99. package/util/browser/module.js +5 -0
  100. package/util/browser/path.js +520 -0
  101. package/util/browser/process.js +59 -0
  102. package/util/browser/url.js +23 -0
  103. package/util/cpu.d.ts +9 -0
  104. package/util/cpu.js +42 -0
  105. package/util/find.d.ts +6 -0
  106. package/util/find.js +20 -0
  107. package/util/node.d.ts +21 -0
  108. package/util/node.js +34 -0
  109. package/util/options.d.ts +70 -0
  110. package/util/options.js +262 -0
  111. package/util/terminal.d.ts +52 -0
  112. package/util/terminal.js +35 -0
  113. package/util/text.d.ts +26 -0
  114. package/util/text.js +114 -0
  115. package/util/tsconfig.json +9 -0
  116. package/util/web.d.ts +11 -0
  117. package/util/web.js +33 -0
@@ -0,0 +1,3289 @@
1
+ import { Math as JSMath } from "./bindings/dom";
2
+ export { JSMath };
3
+
4
+ import {
5
+ pow_lut, exp_lut, exp2_lut, log_lut, log2_lut,
6
+ powf_lut, expf_lut, exp2f_lut, logf_lut, log2f_lut
7
+ } from "./util/math";
8
+
9
+ import {
10
+ abs as builtin_abs,
11
+ ceil as builtin_ceil,
12
+ clz as builtin_clz,
13
+ copysign as builtin_copysign,
14
+ floor as builtin_floor,
15
+ max as builtin_max,
16
+ min as builtin_min,
17
+ sqrt as builtin_sqrt,
18
+ trunc as builtin_trunc
19
+ } from "./builtins";
20
+
21
+ // SUN COPYRIGHT NOTICE
22
+ //
23
+ // Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
24
+ // Developed at SunPro, a Sun Microsystems, Inc. business.
25
+ // Permission to use, copy, modify, and distribute this software
26
+ // is freely granted, provided that this notice is preserved.
27
+ //
28
+ // Applies to all functions marked with a comment referring here.
29
+
30
+ /** @internal */
31
+ // @ts-ignore: decorator
32
+ @lazy let rempio2_y0: f64, rempio2_y1: f64, res128_hi: u64;
33
+
34
+ /** @internal */
35
+ // @ts-ignore: decorator
36
+ @lazy @inline const PIO2_TABLE = memory.data<u64>([
37
+ 0x00000000A2F9836E, 0x4E441529FC2757D1, 0xF534DDC0DB629599, 0x3C439041FE5163AB,
38
+ 0xDEBBC561B7246E3A, 0x424DD2E006492EEA, 0x09D1921CFE1DEB1C, 0xB129A73EE88235F5,
39
+ 0x2EBB4484E99C7026, 0xB45F7E413991D639, 0x835339F49C845F8B, 0xBDF9283B1FF897FF,
40
+ 0xDE05980FEF2F118B, 0x5A0A6D1F6D367ECF, 0x27CB09B74F463F66, 0x9E5FEA2D7527BAC7,
41
+ 0xEBE5F17B3D0739F7, 0x8A5292EA6BFB5FB1, 0x1F8D5D0856033046, 0xFC7B6BABF0CFBC20,
42
+ 0x9AF4361DA9E39161, 0x5EE61B086599855F, 0x14A068408DFFD880, 0x4D73273106061557
43
+ ]);
44
+
45
+ /** @internal */
46
+ function R(z: f64): f64 { // Rational approximation of (asin(x)-x)/x^3
47
+ const // see: musl/src/math/asin.c and SUN COPYRIGHT NOTICE above
48
+ pS0 = reinterpret<f64>(0x3FC5555555555555), // 1.66666666666666657415e-01
49
+ pS1 = reinterpret<f64>(0xBFD4D61203EB6F7D), // -3.25565818622400915405e-01
50
+ pS2 = reinterpret<f64>(0x3FC9C1550E884455), // 2.01212532134862925881e-01
51
+ pS3 = reinterpret<f64>(0xBFA48228B5688F3B), // -4.00555345006794114027e-02
52
+ pS4 = reinterpret<f64>(0x3F49EFE07501B288), // 7.91534994289814532176e-04
53
+ pS5 = reinterpret<f64>(0x3F023DE10DFDF709), // 3.47933107596021167570e-05
54
+ qS1 = reinterpret<f64>(0xC0033A271C8A2D4B), // -2.40339491173441421878e+00
55
+ qS2 = reinterpret<f64>(0x40002AE59C598AC8), // 2.02094576023350569471e+00
56
+ qS3 = reinterpret<f64>(0xBFE6066C1B8D0159), // -6.88283971605453293030e-01
57
+ qS4 = reinterpret<f64>(0x3FB3B8C5B12E9282); // 7.70381505559019352791e-02
58
+
59
+ let p = z * (pS0 + z * (pS1 + z * (pS2 + z * (pS3 + z * (pS4 + z * pS5)))));
60
+ let q = 1.0 + z * (qS1 + z * (qS2 + z * (qS3 + z * qS4)));
61
+ return p / q;
62
+ }
63
+
64
+ /** @internal */
65
+ // @ts-ignore: decorator
66
+ @inline
67
+ function expo2(x: f64, sign: f64): f64 { // exp(x)/2 for x >= log(DBL_MAX)
68
+ const // see: musl/src/math/__expo2.c
69
+ k = <u32>2043,
70
+ kln2 = reinterpret<f64>(0x40962066151ADD8B); // 0x1.62066151add8bp+10
71
+ let scale = reinterpret<f64>(<u64>((<u32>0x3FF + k / 2) << 20) << 32);
72
+ // in directed rounding correct sign before rounding or overflow is important
73
+ return NativeMath.exp(x - kln2) * (sign * scale) * scale;
74
+ }
75
+
76
+ /** @internal */
77
+ /* Helper function to eventually get bits of π/2 * |x|
78
+ *
79
+ * y = π/4 * (frac << clz(frac) >> 11)
80
+ * return clz(frac)
81
+ *
82
+ * Right shift 11 bits to make upper half fit in `double`
83
+ */
84
+ // @ts-ignore: decorator
85
+ @inline
86
+ function pio2_right(q0: u64, q1: u64): u64 { // see: jdh8/metallic/blob/master/src/math/double/rem_pio2.c
87
+ // Bits of π/4
88
+ const p0: u64 = 0xC4C6628B80DC1CD1;
89
+ const p1: u64 = 0xC90FDAA22168C234;
90
+
91
+ const Ox1p_64 = reinterpret<f64>(0x3BF0000000000000); // 0x1p-64
92
+ const Ox1p_75 = reinterpret<f64>(0x3B40000000000000); // 0x1p-75
93
+
94
+ let shift = clz(q1);
95
+
96
+ q1 = q1 << shift | q0 >> (64 - shift);
97
+ q0 <<= shift;
98
+
99
+ let lo = umuldi(p1, q1);
100
+ let hi = res128_hi;
101
+
102
+ let ahi = hi >> 11;
103
+ let alo = lo >> 11 | hi << 53;
104
+ let blo = <u64>(Ox1p_75 * <f64>p0 * <f64>q1 + Ox1p_75 * <f64>p1 * <f64>q0);
105
+
106
+ rempio2_y0 = <f64>(ahi + u64(lo < blo));
107
+ rempio2_y1 = Ox1p_64 * <f64>(alo + blo);
108
+
109
+ return shift;
110
+ }
111
+
112
+ /** @internal */
113
+ // @ts-ignore: decorator
114
+ @inline
115
+ function umuldi(u: u64, v: u64): u64 {
116
+ let u1: u64 , v1: u64, w0: u64, w1: u64, t: u64;
117
+
118
+ u1 = u & 0xFFFFFFFF;
119
+ v1 = v & 0xFFFFFFFF;
120
+
121
+ u >>= 32;
122
+ v >>= 32;
123
+
124
+ t = u1 * v1;
125
+ w0 = t & 0xFFFFFFFF;
126
+ t = u * v1 + (t >> 32);
127
+ w1 = t >> 32;
128
+ t = u1 * v + (t & 0xFFFFFFFF);
129
+
130
+ res128_hi = u * v + w1 + (t >> 32);
131
+ return (t << 32) + w0;
132
+ }
133
+
134
+ /** @internal */
135
+ function pio2_large_quot(x: f64, u: i64): i32 { // see: jdh8/metallic/blob/master/src/math/double/rem_pio2.c
136
+ let magnitude = u & 0x7FFFFFFFFFFFFFFF;
137
+ let offset = (magnitude >> 52) - 1045;
138
+ let shift = offset & 63;
139
+ let tblPtr = PIO2_TABLE + (<i32>(offset >> 6) << 3);
140
+ let s0: u64, s1: u64, s2: u64;
141
+
142
+ let b0 = load<u64>(tblPtr, 0 << 3);
143
+ let b1 = load<u64>(tblPtr, 1 << 3);
144
+ let b2 = load<u64>(tblPtr, 2 << 3);
145
+
146
+ // Get 192 bits of 0x1p-31 / π with `offset` bits skipped
147
+ if (shift) {
148
+ let rshift = 64 - shift;
149
+ let b3 = load<u64>(tblPtr, 3 << 3);
150
+ s0 = b1 >> rshift | b0 << shift;
151
+ s1 = b2 >> rshift | b1 << shift;
152
+ s2 = b3 >> rshift | b2 << shift;
153
+ } else {
154
+ s0 = b0;
155
+ s1 = b1;
156
+ s2 = b2;
157
+ }
158
+
159
+ let significand = (u & 0x000FFFFFFFFFFFFF) | 0x0010000000000000;
160
+
161
+ // First 128 bits of fractional part of x/(2π)
162
+ let blo = umuldi(s1, significand);
163
+ let bhi = res128_hi;
164
+
165
+ let ahi = s0 * significand;
166
+ let clo = (s2 >> 32) * (significand >> 32);
167
+ let plo = blo + clo;
168
+ let phi = ahi + bhi + u64(plo < clo);
169
+
170
+ // r: u128 = p << 2
171
+ let rlo = plo << 2;
172
+ let rhi = phi << 2 | plo >> 62;
173
+
174
+ // s: i128 = r >> 127
175
+ let slo = <i64>rhi >> 63;
176
+ let shi = slo >> 1;
177
+ let q = (<i64>phi >> 62) - slo;
178
+
179
+ let shifter = 0x3CB0000000000000 - (pio2_right(rlo ^ slo, rhi ^ shi) << 52);
180
+ let signbit = (u ^ rhi) & 0x8000000000000000;
181
+ let coeff = reinterpret<f64>(shifter | signbit);
182
+
183
+ rempio2_y0 *= coeff;
184
+ rempio2_y1 *= coeff;
185
+
186
+ return <i32>q;
187
+ }
188
+
189
+ /** @internal */
190
+ // @ts-ignore: decorator
191
+ @inline
192
+ function rempio2(x: f64, u: u64, sign: i32): i32 {
193
+ const
194
+ pio2_1 = reinterpret<f64>(0x3FF921FB54400000), // 1.57079632673412561417e+00
195
+ pio2_1t = reinterpret<f64>(0x3DD0B4611A626331), // 6.07710050650619224932e-11
196
+ pio2_2 = reinterpret<f64>(0x3DD0B4611A600000), // 6.07710050630396597660e-11
197
+ pio2_2t = reinterpret<f64>(0x3BA3198A2E037073), // 2.02226624879595063154e-21
198
+ pio2_3 = reinterpret<f64>(0x3BA3198A2E000000), // 2.02226624871116645580e-21
199
+ pio2_3t = reinterpret<f64>(0x397B839A252049C1), // 8.47842766036889956997e-32
200
+ invpio2 = reinterpret<f64>(0x3FE45F306DC9C883); // 0.63661977236758134308
201
+
202
+ let ix = <u32>(u >> 32) & 0x7FFFFFFF;
203
+
204
+ if (ASC_SHRINK_LEVEL < 1) {
205
+ if (ix < 0x4002D97C) { // |x| < 3pi/4, special case with n=+-1
206
+ let q = 1, z: f64, y0: f64, y1: f64;
207
+ if (!sign) {
208
+ z = x - pio2_1;
209
+ if (ix != 0x3FF921FB) { // 33+53 bit pi is good enough
210
+ y0 = z - pio2_1t;
211
+ y1 = (z - y0) - pio2_1t;
212
+ } else { // near pi/2, use 33+33+53 bit pi
213
+ z -= pio2_2;
214
+ y0 = z - pio2_2t;
215
+ y1 = (z - y0) - pio2_2t;
216
+ }
217
+ } else { // negative x
218
+ z = x + pio2_1;
219
+ if (ix != 0x3FF921FB) { // 33+53 bit pi is good enough
220
+ y0 = z + pio2_1t;
221
+ y1 = (z - y0) + pio2_1t;
222
+ } else { // near pi/2, use 33+33+53 bit pi
223
+ z += pio2_2;
224
+ y0 = z + pio2_2t;
225
+ y1 = (z - y0) + pio2_2t;
226
+ }
227
+ q = -1;
228
+ }
229
+ rempio2_y0 = y0;
230
+ rempio2_y1 = y1;
231
+ return q;
232
+ }
233
+ }
234
+
235
+ if (ix < 0x413921FB) { // |x| ~< 2^20*pi/2 (1647099)
236
+ // Use precise Cody Waite scheme
237
+ let q = nearest(x * invpio2);
238
+ let r = x - q * pio2_1;
239
+ let w = q * pio2_1t; // 1st round good to 85 bit
240
+ let j = ix >> 20;
241
+ let y0 = r - w;
242
+ let hi = <u32>(reinterpret<u64>(y0) >> 32);
243
+ let i = j - ((hi >> 20) & 0x7FF);
244
+
245
+ if (i > 16) { // 2nd iteration needed, good to 118
246
+ let t = r;
247
+ w = q * pio2_2;
248
+ r = t - w;
249
+ w = q * pio2_2t - ((t - r) - w);
250
+ y0 = r - w;
251
+ hi = <u32>(reinterpret<u64>(y0) >> 32);
252
+ i = j - ((hi >> 20) & 0x7FF);
253
+ if (i > 49) { // 3rd iteration need, 151 bits acc
254
+ let t = r;
255
+ w = q * pio2_3;
256
+ r = t - w;
257
+ w = q * pio2_3t - ((t - r) - w);
258
+ y0 = r - w;
259
+ }
260
+ }
261
+ let y1 = (r - y0) - w;
262
+ rempio2_y0 = y0;
263
+ rempio2_y1 = y1;
264
+ return <i32>q;
265
+ }
266
+ let q = pio2_large_quot(x, u);
267
+ return select(-q, q, sign);
268
+ }
269
+
270
+ /** @internal */
271
+ // @ts-ignore: decorator
272
+ @inline
273
+ function sin_kern(x: f64, y: f64, iy: i32): f64 { // see: musl/tree/src/math/__sin.c
274
+ const
275
+ S1 = reinterpret<f64>(0xBFC5555555555549), // -1.66666666666666324348e-01
276
+ S2 = reinterpret<f64>(0x3F8111111110F8A6), // 8.33333333332248946124e-03
277
+ S3 = reinterpret<f64>(0xBF2A01A019C161D5), // -1.98412698298579493134e-04
278
+ S4 = reinterpret<f64>(0x3EC71DE357B1FE7D), // 2.75573137070700676789e-06
279
+ S5 = reinterpret<f64>(0xBE5AE5E68A2B9CEB), // -2.50507602534068634195e-08
280
+ S6 = reinterpret<f64>(0x3DE5D93A5ACFD57C); // 1.58969099521155010221e-10
281
+
282
+ let z = x * x;
283
+ let w = z * z;
284
+ let r = S2 + z * (S3 + z * S4) + z * w * (S5 + z * S6);
285
+ let v = z * x;
286
+ if (!iy) {
287
+ return x + v * (S1 + z * r);
288
+ } else {
289
+ return x - ((z * (0.5 * y - v * r) - y) - v * S1);
290
+ }
291
+ }
292
+
293
+ /** @internal */
294
+ // @ts-ignore: decorator
295
+ @inline
296
+ function cos_kern(x: f64, y: f64): f64 { // see: musl/tree/src/math/__cos.c
297
+ const
298
+ C1 = reinterpret<f64>(0x3FA555555555554C), // 4.16666666666666019037e-02
299
+ C2 = reinterpret<f64>(0xBF56C16C16C15177), // -1.38888888888741095749e-03
300
+ C3 = reinterpret<f64>(0x3EFA01A019CB1590), // 2.48015872894767294178e-05
301
+ C4 = reinterpret<f64>(0xBE927E4F809C52AD), // -2.75573143513906633035e-07
302
+ C5 = reinterpret<f64>(0x3E21EE9EBDB4B1C4), // 2.08757232129817482790e-09
303
+ C6 = reinterpret<f64>(0xBDA8FAE9BE8838D4); // -1.13596475577881948265e-11
304
+
305
+ let z = x * x;
306
+ let w = z * z;
307
+ let r = z * (C1 + z * (C2 + z * C3)) + w * w * (C4 + z * (C5 + z * C6));
308
+ let hz = 0.5 * z;
309
+ w = 1.0 - hz;
310
+ return w + (((1.0 - w) - hz) + (z * r - x * y));
311
+ }
312
+
313
+ /** @internal */
314
+ function tan_kern(x: f64, y: f64, iy: i32): f64 { // see: src/lib/msun/src/k_tan.c
315
+ const
316
+ T0 = reinterpret<f64>(0x3FD5555555555563), // 3.33333333333334091986e-01
317
+ T1 = reinterpret<f64>(0x3FC111111110FE7A), // 1.33333333333201242699e-01
318
+ T2 = reinterpret<f64>(0x3FABA1BA1BB341FE), // 5.39682539762260521377e-02
319
+ T3 = reinterpret<f64>(0x3F9664F48406D637), // 2.18694882948595424599e-02
320
+ T4 = reinterpret<f64>(0x3F8226E3E96E8493), // 8.86323982359930005737e-03
321
+ T5 = reinterpret<f64>(0x3F6D6D22C9560328), // 3.59207910759131235356e-03
322
+ T6 = reinterpret<f64>(0x3F57DBC8FEE08315), // 1.45620945432529025516e-03
323
+ T7 = reinterpret<f64>(0x3F4344D8F2F26501), // 5.88041240820264096874e-04
324
+ T8 = reinterpret<f64>(0x3F3026F71A8D1068), // 2.46463134818469906812e-04
325
+ T9 = reinterpret<f64>(0x3F147E88A03792A6), // 7.81794442939557092300e-05
326
+ T10 = reinterpret<f64>(0x3F12B80F32F0A7E9), // 7.14072491382608190305e-05
327
+ T11 = reinterpret<f64>(0xBEF375CBDB605373), // -1.85586374855275456654e-05
328
+ T12 = reinterpret<f64>(0x3EFB2A7074BF7AD4); // 2.59073051863633712884e-05
329
+
330
+ const
331
+ one = reinterpret<f64>(0x3FF0000000000000), // 1.00000000000000000000e+00
332
+ pio4 = reinterpret<f64>(0x3FE921FB54442D18), // 7.85398163397448278999e-01
333
+ pio4lo = reinterpret<f64>(0x3C81A62633145C07); // 3.06161699786838301793e-17
334
+
335
+ let z: f64, r: f64, v: f64, w: f64, s: f64;
336
+ let hx = <i32>(reinterpret<u64>(x) >> 32); // high word of x
337
+ let ix = hx & 0x7FFFFFFF; // high word of |x|
338
+ let big = ix >= 0x3FE59428;
339
+ if (big) { // |x| >= 0.6744
340
+ if (hx < 0) { x = -x, y = -y; }
341
+ z = pio4 - x;
342
+ w = pio4lo - y;
343
+ x = z + w;
344
+ y = 0.0;
345
+ }
346
+ z = x * x;
347
+ w = z * z;
348
+ r = T1 + w * (T3 + w * (T5 + w * (T7 + w * (T9 + w * T11))));
349
+ v = z * (T2 + w * (T4 + w * (T6 + w * (T8 + w * (T10 + w * T12)))));
350
+ s = z * x;
351
+ r = y + z * (s * (r + v) + y);
352
+ r += T0 * s;
353
+ w = x + r;
354
+ if (big) {
355
+ v = iy;
356
+ return (1 - ((hx >> 30) & 2)) * (v - 2.0 * (x - (w * w / (w + v) - r)));
357
+ }
358
+ if (iy == 1) return w;
359
+ let a: f64, t: f64;
360
+ z = w;
361
+ z = reinterpret<f64>(reinterpret<u64>(z) & 0xFFFFFFFF00000000);
362
+ v = r - (z - x); // z + v = r + x
363
+ t = a = -one / w; // a = -1.0 / w
364
+ t = reinterpret<f64>(reinterpret<u64>(t) & 0xFFFFFFFF00000000);
365
+ s = one + t * z;
366
+ return t + a * (s + t * v);
367
+ }
368
+
369
+ /** @internal */
370
+ function dtoi32(x: f64): i32 {
371
+ if (ASC_SHRINK_LEVEL > 0) {
372
+ const inv32 = 1.0 / 4294967296;
373
+ return <i32><i64>(x - 4294967296 * floor(x * inv32));
374
+ } else {
375
+ let result = 0;
376
+ let u = reinterpret<u64>(x);
377
+ let e = (u >> 52) & 0x7FF;
378
+ if (e <= 1023 + 30) {
379
+ result = <i32>x;
380
+ } else if (e <= 1023 + 30 + 53) {
381
+ let v = (u & ((<u64>1 << 52) - 1)) | (<u64>1 << 52);
382
+ v = v << e - 1023 - 52 + 32;
383
+ result = <i32>(v >> 32);
384
+ result = select<i32>(-result, result, <i64>u < 0);
385
+ }
386
+ return result;
387
+ }
388
+ }
389
+
390
+ // @ts-ignore: decorator
391
+ @lazy let random_seeded = false;
392
+
393
+ // @ts-ignore: decorator
394
+ @lazy let random_state0_64: u64, random_state1_64: u64;
395
+
396
+ // @ts-ignore: decorator
397
+ @lazy let random_state0_32: u32, random_state1_32: u32;
398
+
399
+ function murmurHash3(h: u64): u64 { // Force all bits of a hash block to avalanche
400
+ h ^= h >> 33; // see: https://github.com/aappleby/smhasher
401
+ h *= 0xFF51AFD7ED558CCD;
402
+ h ^= h >> 33;
403
+ h *= 0xC4CEB9FE1A85EC53;
404
+ h ^= h >> 33;
405
+ return h;
406
+ }
407
+
408
+ function splitMix32(h: u32): u32 {
409
+ h += 0x6D2B79F5;
410
+ h = (h ^ (h >> 15)) * (h | 1);
411
+ h ^= h + (h ^ (h >> 7)) * (h | 61);
412
+ return h ^ (h >> 14);
413
+ }
414
+
415
+ export namespace NativeMath {
416
+
417
+ // @ts-ignore: decorator
418
+ @lazy
419
+ export const E = reinterpret<f64>(0x4005BF0A8B145769); // 2.7182818284590452354
420
+
421
+ // @ts-ignore: decorator
422
+ @lazy
423
+ export const LN2 = reinterpret<f64>(0x3FE62E42FEFA39EF); // 0.69314718055994530942
424
+
425
+ // @ts-ignore: decorator
426
+ @lazy
427
+ export const LN10 = reinterpret<f64>(0x40026BB1BBB55516); // 2.30258509299404568402
428
+
429
+ // @ts-ignore: decorator
430
+ @lazy
431
+ export const LOG2E = reinterpret<f64>(0x3FF71547652B82FE); // 1.4426950408889634074
432
+
433
+ // @ts-ignore: decorator
434
+ @lazy
435
+ export const LOG10E = reinterpret<f64>(0x3FDBCB7B1526E50E); // 0.43429448190325182765
436
+
437
+ // @ts-ignore: decorator
438
+ @lazy
439
+ export const PI = reinterpret<f64>(0x400921FB54442D18); // 3.14159265358979323846
440
+
441
+ // @ts-ignore: decorator
442
+ @lazy
443
+ export const SQRT1_2 = reinterpret<f64>(0x3FE6A09E667F3BCD); // 0.70710678118654752440
444
+
445
+ // @ts-ignore: decorator
446
+ @lazy
447
+ export const SQRT2 = reinterpret<f64>(0x3FF6A09E667F3BCD); // 1.41421356237309504880
448
+
449
+ // @ts-ignore: decorator
450
+ @lazy
451
+ export let sincos_sin: f64 = 0;
452
+
453
+ // @ts-ignore: decorator
454
+ @lazy
455
+ export let sincos_cos: f64 = 0;
456
+
457
+ // @ts-ignore: decorator
458
+ @inline export function abs(x: f64): f64 {
459
+ return builtin_abs<f64>(x);
460
+ }
461
+
462
+ export function acos(x: f64): f64 { // see: musl/src/math/acos.c and SUN COPYRIGHT NOTICE above
463
+ const
464
+ pio2_hi = reinterpret<f64>(0x3FF921FB54442D18), // 1.57079632679489655800e+00
465
+ pio2_lo = reinterpret<f64>(0x3C91A62633145C07), // 6.12323399573676603587e-17
466
+ Ox1p_120f = reinterpret<f32>(0x03800000);
467
+
468
+ let hx = <u32>(reinterpret<u64>(x) >> 32);
469
+ let ix = hx & 0x7FFFFFFF;
470
+ if (ix >= 0x3FF00000) {
471
+ let lx = <u32>reinterpret<u64>(x);
472
+ if ((ix - 0x3FF00000 | lx) == 0) {
473
+ if (<i32>hx < 0) return 2 * pio2_hi + Ox1p_120f;
474
+ return 0;
475
+ }
476
+ return 0 / (x - x);
477
+ }
478
+ if (ix < 0x3FE00000) {
479
+ if (ix <= 0x3C600000) return pio2_hi + Ox1p_120f;
480
+ return pio2_hi - (x - (pio2_lo - x * R(x * x)));
481
+ }
482
+ let s: f64, w: f64, z: f64;
483
+ if (<i32>hx < 0) {
484
+ // z = (1.0 + x) * 0.5;
485
+ z = 0.5 + x * 0.5;
486
+ s = builtin_sqrt<f64>(z);
487
+ w = R(z) * s - pio2_lo;
488
+ return 2 * (pio2_hi - (s + w));
489
+ }
490
+ // z = (1.0 - x) * 0.5;
491
+ z = 0.5 - x * 0.5;
492
+ s = builtin_sqrt<f64>(z);
493
+ let df = reinterpret<f64>(reinterpret<u64>(s) & 0xFFFFFFFF00000000);
494
+ let c = (z - df * df) / (s + df);
495
+ w = R(z) * s + c;
496
+ return 2 * (df + w);
497
+ }
498
+
499
+ export function acosh(x: f64): f64 { // see: musl/src/math/acosh.c
500
+ const s = reinterpret<f64>(0x3FE62E42FEFA39EF);
501
+ let u = reinterpret<u64>(x);
502
+ // Prevent propagation for all input values less than 1.0.
503
+ // Note musl lib didn't fix this yet.
504
+ if (<i64>u < 0x3FF0000000000000) return (x - x) / 0.0;
505
+ let e = u >> 52 & 0x7FF;
506
+ if (e < 0x3FF + 1) return log1p(x - 1 + builtin_sqrt<f64>((x - 1) * (x - 1) + 2 * (x - 1)));
507
+ if (e < 0x3FF + 26) return log(2 * x - 1 / (x + builtin_sqrt<f64>(x * x - 1)));
508
+ return log(x) + s;
509
+ }
510
+
511
+ export function asin(x: f64): f64 { // see: musl/src/math/asin.c and SUN COPYRIGHT NOTICE above
512
+ const
513
+ pio2_hi = reinterpret<f64>(0x3FF921FB54442D18), // 1.57079632679489655800e+00
514
+ pio2_lo = reinterpret<f64>(0x3C91A62633145C07), // 6.12323399573676603587e-17
515
+ Ox1p_120f = reinterpret<f32>(0x03800000);
516
+
517
+ let hx = <u32>(reinterpret<u64>(x) >> 32);
518
+ let ix = hx & 0x7FFFFFFF;
519
+ if (ix >= 0x3FF00000) {
520
+ let lx = <u32>reinterpret<u64>(x);
521
+ if ((ix - 0x3FF00000 | lx) == 0) return x * pio2_hi + Ox1p_120f;
522
+ return 0 / (x - x);
523
+ }
524
+ if (ix < 0x3FE00000) {
525
+ if (ix < 0x3E500000 && ix >= 0x00100000) return x;
526
+ return x + x * R(x * x);
527
+ }
528
+ // let z = (1.0 - builtin_abs<f64>(x)) * 0.5;
529
+ let z = 0.5 - builtin_abs<f64>(x) * 0.5;
530
+ let s = builtin_sqrt<f64>(z);
531
+ let r = R(z);
532
+ if (ix >= 0x3FEF3333) x = pio2_hi - (2 * (s + s * r) - pio2_lo);
533
+ else {
534
+ let f = reinterpret<f64>(reinterpret<u64>(s) & 0xFFFFFFFF00000000);
535
+ let c = (z - f * f) / (s + f);
536
+ x = 0.5 * pio2_hi - (2 * s * r - (pio2_lo - 2 * c) - (0.5 * pio2_hi - 2 * f));
537
+ }
538
+ return select(-x, x, <i32>hx < 0);
539
+ }
540
+
541
+ export function asinh(x: f64): f64 { // see: musl/src/math/asinh.c
542
+ const c = reinterpret<f64>(0x3FE62E42FEFA39EF); // 0.693147180559945309417232121458176568
543
+ let u = reinterpret<u64>(x);
544
+ let e = u >> 52 & 0x7FF;
545
+ let y = reinterpret<f64>(u & 0x7FFFFFFFFFFFFFFF);
546
+ if (e >= 0x3FF + 26) y = log(y) + c;
547
+ else if (e >= 0x3FF + 1) y = log(2 * y + 1 / (builtin_sqrt<f64>(y * y + 1) + y));
548
+ else if (e >= 0x3FF - 26) y = log1p(y + y * y / (builtin_sqrt<f64>(y * y + 1) + 1));
549
+ return builtin_copysign(y, x);
550
+ }
551
+
552
+ export function atan(x: f64): f64 { // see musl/src/math/atan.c and SUN COPYRIGHT NOTICE above
553
+ const
554
+ atanhi0 = reinterpret<f64>(0x3FDDAC670561BB4F), // 4.63647609000806093515e-01
555
+ atanhi1 = reinterpret<f64>(0x3FE921FB54442D18), // 7.85398163397448278999e-01
556
+ atanhi2 = reinterpret<f64>(0x3FEF730BD281F69B), // 9.82793723247329054082e-01
557
+ atanhi3 = reinterpret<f64>(0x3FF921FB54442D18), // 1.57079632679489655800e+00
558
+ atanlo0 = reinterpret<f64>(0x3C7A2B7F222F65E2), // 2.26987774529616870924e-17
559
+ atanlo1 = reinterpret<f64>(0x3C81A62633145C07), // 3.06161699786838301793e-17
560
+ atanlo2 = reinterpret<f64>(0x3C7007887AF0CBBD), // 1.39033110312309984516e-17
561
+ atanlo3 = reinterpret<f64>(0x3C91A62633145C07), // 6.12323399573676603587e-17
562
+ aT0 = reinterpret<f64>(0x3FD555555555550D), // 3.33333333333329318027e-01
563
+ aT1 = reinterpret<f64>(0xBFC999999998EBC4), // -1.99999999998764832476e-01
564
+ aT2 = reinterpret<f64>(0x3FC24924920083FF), // 1.42857142725034663711e-01
565
+ aT3 = reinterpret<f64>(0xBFBC71C6FE231671), // -1.11111104054623557880e-01,
566
+ aT4 = reinterpret<f64>(0x3FB745CDC54C206E), // 9.09088713343650656196e-02
567
+ aT5 = reinterpret<f64>(0xBFB3B0F2AF749A6D), // -7.69187620504482999495e-02
568
+ aT6 = reinterpret<f64>(0x3FB10D66A0D03D51), // 6.66107313738753120669e-02
569
+ aT7 = reinterpret<f64>(0xBFADDE2D52DEFD9A), // -5.83357013379057348645e-02
570
+ aT8 = reinterpret<f64>(0x3FA97B4B24760DEB), // 4.97687799461593236017e-02
571
+ aT9 = reinterpret<f64>(0xBFA2B4442C6A6C2F), // -3.65315727442169155270e-02
572
+ aT10 = reinterpret<f64>(0x3F90AD3AE322DA11), // 1.62858201153657823623e-02
573
+ Ox1p_120f = reinterpret<f32>(0x03800000);
574
+
575
+ let ix = <u32>(reinterpret<u64>(x) >> 32);
576
+ let sx = x;
577
+ ix &= 0x7FFFFFFF;
578
+ let z: f64;
579
+ if (ix >= 0x44100000) {
580
+ if (isNaN(x)) return x;
581
+ z = atanhi3 + Ox1p_120f;
582
+ return builtin_copysign<f64>(z, sx);
583
+ }
584
+ let id: i32;
585
+ if (ix < 0x3FDC0000) {
586
+ if (ix < 0x3E400000) return x;
587
+ id = -1;
588
+ } else {
589
+ x = builtin_abs<f64>(x);
590
+ if (ix < 0x3FF30000) {
591
+ if (ix < 0x3FE60000) {
592
+ id = 0;
593
+ x = (2.0 * x - 1.0) / (2.0 + x);
594
+ } else {
595
+ id = 1;
596
+ x = (x - 1.0) / (x + 1.0);
597
+ }
598
+ } else {
599
+ if (ix < 0x40038000) {
600
+ id = 2;
601
+ x = (x - 1.5) / (1.0 + 1.5 * x);
602
+ } else {
603
+ id = 3;
604
+ x = -1.0 / x;
605
+ }
606
+ }
607
+ }
608
+ z = x * x;
609
+ let w = z * z;
610
+ let s1 = z * (aT0 + w * (aT2 + w * (aT4 + w * (aT6 + w * (aT8 + w * aT10)))));
611
+ let s2 = w * (aT1 + w * (aT3 + w * (aT5 + w * (aT7 + w * aT9))));
612
+ let s3 = x * (s1 + s2);
613
+ if (id < 0) return x - s3;
614
+ switch (id) {
615
+ case 0: { z = atanhi0 - ((s3 - atanlo0) - x); break; }
616
+ case 1: { z = atanhi1 - ((s3 - atanlo1) - x); break; }
617
+ case 2: { z = atanhi2 - ((s3 - atanlo2) - x); break; }
618
+ case 3: { z = atanhi3 - ((s3 - atanlo3) - x); break; }
619
+ default: unreachable();
620
+ }
621
+ return builtin_copysign<f64>(z, sx);
622
+ }
623
+
624
+ export function atanh(x: f64): f64 { // see: musl/src/math/atanh.c
625
+ let u = reinterpret<u64>(x);
626
+ let e = u >> 52 & 0x7FF;
627
+ let y = builtin_abs(x);
628
+ if (e < 0x3FF - 1) {
629
+ if (e >= 0x3FF - 32) y = 0.5 * log1p(2 * y + 2 * y * y / (1 - y));
630
+ } else {
631
+ y = 0.5 * log1p(2 * (y / (1 - y)));
632
+ }
633
+ return builtin_copysign<f64>(y, x);
634
+ }
635
+
636
+ export function atan2(y: f64, x: f64): f64 { // see: musl/src/math/atan2.c and SUN COPYRIGHT NOTICE above
637
+ const pi_lo = reinterpret<f64>(0x3CA1A62633145C07); // 1.2246467991473531772E-16
638
+ if (isNaN(x) || isNaN(y)) return x + y;
639
+ let u = reinterpret<u64>(x);
640
+ let ix = <u32>(u >> 32);
641
+ let lx = <u32>u;
642
+ u = reinterpret<u64>(y);
643
+ let iy = <u32>(u >> 32);
644
+ let ly = <u32>u;
645
+ if ((ix - 0x3FF00000 | lx) == 0) return atan(y);
646
+ let m = ((iy >> 31) & 1) | ((ix >> 30) & 2);
647
+ ix = ix & 0x7FFFFFFF;
648
+ iy = iy & 0x7FFFFFFF;
649
+ if ((iy | ly) == 0) {
650
+ switch (m) {
651
+ case 0:
652
+ case 1: return y;
653
+ case 2: return PI;
654
+ case 3: return -PI;
655
+ }
656
+ }
657
+ if ((ix | lx) == 0) return m & 1 ? -PI / 2 : PI / 2;
658
+ if (ix == 0x7FF00000) {
659
+ if (iy == 0x7FF00000) {
660
+ let t = m & 2 ? 3 * PI / 4 : PI / 4;
661
+ return m & 1 ? -t : t;
662
+ } else {
663
+ let t = m & 2 ? PI : 0;
664
+ return m & 1 ? -t : t;
665
+ }
666
+ }
667
+ let z: f64;
668
+ if (ix + (64 << 20) < iy || iy == 0x7FF00000) return m & 1 ? -PI / 2 : PI / 2;
669
+ if ((m & 2) && iy + (64 << 20) < ix) z = 0;
670
+ else z = atan(builtin_abs<f64>(y / x));
671
+ switch (m) {
672
+ case 0: return z;
673
+ case 1: return -z;
674
+ case 2: return PI - (z - pi_lo);
675
+ case 3: return (z - pi_lo) - PI;
676
+ }
677
+ unreachable();
678
+ return 0;
679
+ }
680
+
681
+ export function cbrt(x: f64): f64 { // see: musl/src/math/cbrt.c and SUN COPYRIGHT NOTICE above
682
+ const
683
+ B1 = <u32>715094163,
684
+ B2 = <u32>696219795,
685
+ P0 = reinterpret<f64>(0x3FFE03E60F61E692), // 1.87595182427177009643
686
+ P1 = reinterpret<f64>(0xBFFE28E092F02420), // -1.88497979543377169875
687
+ P2 = reinterpret<f64>(0x3FF9F1604A49D6C2), // 1.621429720105354466140
688
+ P3 = reinterpret<f64>(0xBFE844CBBEE751D9), // -0.758397934778766047437
689
+ P4 = reinterpret<f64>(0x3FC2B000D4E4EDD7), // 0.145996192886612446982
690
+ Ox1p54 = reinterpret<f64>(0x4350000000000000); // 0x1p54
691
+
692
+ let u = reinterpret<u64>(x);
693
+ let hx = <u32>(u >> 32) & 0x7FFFFFFF;
694
+ if (hx >= 0x7FF00000) return x + x;
695
+ if (hx < 0x00100000) {
696
+ u = reinterpret<u64>(x * Ox1p54);
697
+ hx = <u32>(u >> 32) & 0x7FFFFFFF;
698
+ if (hx == 0) return x;
699
+ hx = hx / 3 + B2;
700
+ } else {
701
+ hx = hx / 3 + B1;
702
+ }
703
+ u &= 1 << 63;
704
+ u |= <u64>hx << 32;
705
+ let t = reinterpret<f64>(u);
706
+ let r = (t * t) * (t / x);
707
+ t = t * ((P0 + r * (P1 + r * P2)) + ((r * r) * r) * (P3 + r * P4));
708
+ t = reinterpret<f64>((reinterpret<u64>(t) + 0x80000000) & 0xFFFFFFFFC0000000);
709
+ let s = t * t;
710
+ r = x / s;
711
+ r = (r - t) / (2 * t + r);
712
+ t = t + t * r;
713
+ return t;
714
+ }
715
+
716
+ // @ts-ignore: decorator
717
+ @inline
718
+ export function ceil(x: f64): f64 {
719
+ return builtin_ceil<f64>(x);
720
+ }
721
+
722
+ export function clz32(x: f64): f64 {
723
+ if (!isFinite(x)) return 32;
724
+ /*
725
+ * Wasm (MVP) and JS have different approaches for double->int conversions.
726
+ *
727
+ * For emulate JS conversion behavior and avoid trapping from wasm we should modulate by MAX_INT
728
+ * our float-point arguments before actual convertion to integers.
729
+ */
730
+ return builtin_clz(dtoi32(x));
731
+ }
732
+
733
+ export function cos(x: f64): f64 { // see: musl/src/math/cos.c
734
+ let u = reinterpret<u64>(x);
735
+ let ux = u32(u >> 32);
736
+ let sign = ux >> 31;
737
+
738
+ ux &= 0x7FFFFFFF;
739
+
740
+ // |x| ~< pi/4
741
+ if (ux <= 0x3FE921FB) {
742
+ if (ux < 0x3E46A09E) { // |x| < 2**-27 * sqrt(2)
743
+ return 1.0;
744
+ }
745
+ return cos_kern(x, 0);
746
+ }
747
+
748
+ // sin(Inf or NaN) is NaN
749
+ if (ux >= 0x7FF00000) return x - x;
750
+
751
+ // argument reduction needed
752
+ let n = rempio2(x, u, sign);
753
+ let y0 = rempio2_y0;
754
+ let y1 = rempio2_y1;
755
+
756
+ x = n & 1 ? sin_kern(y0, y1, 1) : cos_kern(y0, y1);
757
+ return (n + 1) & 2 ? -x : x;
758
+ }
759
+
760
+ export function cosh(x: f64): f64 { // see: musl/src/math/cosh.c
761
+ let u = reinterpret<u64>(x);
762
+ u &= 0x7FFFFFFFFFFFFFFF;
763
+ x = reinterpret<f64>(u);
764
+ let w = <u32>(u >> 32);
765
+ let t: f64;
766
+ if (w < 0x3FE62E42) {
767
+ if (w < 0x3FF00000 - (26 << 20)) return 1;
768
+ t = expm1(x);
769
+ // return 1 + t * t / (2 * (1 + t));
770
+ return 1 + t * t / (2 + 2 * t);
771
+ }
772
+ if (w < 0x40862E42) {
773
+ t = exp(x);
774
+ return 0.5 * (t + 1 / t);
775
+ }
776
+ t = expo2(x, 1);
777
+ return t;
778
+ }
779
+
780
+ export function exp(x: f64): f64 { // see: musl/src/math/exp.c and SUN COPYRIGHT NOTICE above
781
+ if (ASC_SHRINK_LEVEL < 1) {
782
+ return exp_lut(x);
783
+ } else {
784
+ const
785
+ ln2hi = reinterpret<f64>(0x3FE62E42FEE00000), // 6.93147180369123816490e-01
786
+ ln2lo = reinterpret<f64>(0x3DEA39EF35793C76), // 1.90821492927058770002e-10
787
+ invln2 = reinterpret<f64>(0x3FF71547652B82FE), // 1.44269504088896338700e+00
788
+ P1 = reinterpret<f64>(0x3FC555555555553E), // 1.66666666666666019037e-01
789
+ P2 = reinterpret<f64>(0xBF66C16C16BEBD93), // -2.77777777770155933842e-03
790
+ P3 = reinterpret<f64>(0x3F11566AAF25DE2C), // 6.61375632143793436117e-05
791
+ P4 = reinterpret<f64>(0xBEBBBD41C5D26BF1), // -1.65339022054652515390e-06
792
+ P5 = reinterpret<f64>(0x3E66376972BEA4D0), // 4.13813679705723846039e-08
793
+ overflow = reinterpret<f64>(0x40862E42FEFA39EF), // 709.782712893383973096
794
+ underflow = reinterpret<f64>(0xC0874910D52D3051), // -745.13321910194110842
795
+ Ox1p1023 = reinterpret<f64>(0x7FE0000000000000); // 0x1p1023
796
+
797
+ let hx = u32(reinterpret<u64>(x) >> 32);
798
+ let sign = hx >> 31;
799
+ hx &= 0x7FFFFFFF;
800
+ if (hx >= 0x4086232B) {
801
+ if (isNaN(x)) return x;
802
+ if (x > overflow) return x * Ox1p1023;
803
+ if (x < underflow) return 0;
804
+ }
805
+ let hi: f64, lo: f64 = 0;
806
+ let k = 0;
807
+ if (hx > 0x3FD62E42) {
808
+ if (hx >= 0x3FF0A2B2) {
809
+ k = i32(invln2 * x + builtin_copysign<f64>(0.5, x));
810
+ } else {
811
+ k = 1 - (sign << 1);
812
+ }
813
+ hi = x - k * ln2hi;
814
+ lo = k * ln2lo;
815
+ x = hi - lo;
816
+ } else if (hx > 0x3E300000) {
817
+ hi = x;
818
+ } else return 1.0 + x;
819
+ let xs = x * x;
820
+ // let c = x - xp2 * (P1 + xp2 * (P2 + xp2 * (P3 + xp2 * (P4 + xp2 * P5))));
821
+ let xq = xs * xs;
822
+ let c = x - (xs * P1 + xq * ((P2 + xs * P3) + xq * (P4 + xs * P5)));
823
+ let y = 1.0 + (x * c / (2 - c) - lo + hi);
824
+ return k == 0 ? y : scalbn(y, k);
825
+ }
826
+ }
827
+
828
+ export function exp2(x: f64): f64 {
829
+ return exp2_lut(x);
830
+ }
831
+
832
+ export function expm1(x: f64): f64 { // see: musl/src/math/expm1.c and SUN COPYRIGHT NOTICE above
833
+ const
834
+ o_threshold = reinterpret<f64>(0x40862E42FEFA39EF), // 7.09782712893383973096e+02
835
+ ln2_hi = reinterpret<f64>(0x3FE62E42FEE00000), // 6.93147180369123816490e-01
836
+ ln2_lo = reinterpret<f64>(0x3DEA39EF35793C76), // 1.90821492927058770002e-10
837
+ invln2 = reinterpret<f64>(0x3FF71547652B82FE), // 1.44269504088896338700e+00
838
+ Q1 = reinterpret<f64>(0xBFA11111111110F4), // -3.33333333333331316428e-02
839
+ Q2 = reinterpret<f64>(0x3F5A01A019FE5585), // 1.58730158725481460165e-03
840
+ Q3 = reinterpret<f64>(0xBF14CE199EAADBB7), // -7.93650757867487942473e-05
841
+ Q4 = reinterpret<f64>(0x3ED0CFCA86E65239), // 4.00821782732936239552e-06
842
+ Q5 = reinterpret<f64>(0xBE8AFDB76E09C32D), // -2.01099218183624371326e-07
843
+ Ox1p1023 = reinterpret<f64>(0x7FE0000000000000); // 0x1p1023
844
+
845
+ let u = reinterpret<u64>(x);
846
+ let hx = u32(u >> 32) & 0x7FFFFFFF;
847
+ let sign = u32(u >> 63);
848
+ let k = 0;
849
+ if (hx >= 0x4043687A) {
850
+ if (isNaN(x)) return x;
851
+ if (sign) return -1;
852
+ if (x > o_threshold) return x * Ox1p1023;
853
+ }
854
+ let c = 0.0, t: f64;
855
+ if (hx > 0x3FD62E42) {
856
+ k = select<i32>(
857
+ 1 - (sign << 1),
858
+ i32(invln2 * x + builtin_copysign<f64>(0.5, x)),
859
+ hx < 0x3FF0A2B2
860
+ );
861
+ t = <f64>k;
862
+ let hi = x - t * ln2_hi;
863
+ let lo = t * ln2_lo;
864
+ x = hi - lo;
865
+ c = (hi - x) - lo;
866
+ } else if (hx < 0x3C900000) return x;
867
+ let hfx = 0.5 * x;
868
+ let hxs = x * hfx;
869
+ // let r1 = 1.0 + hxs * (Q1 + hxs * (Q2 + hxs * (Q3 + hxs * (Q4 + hxs * Q5))));
870
+ let hxq = hxs * hxs;
871
+ let r1 = (1.0 + hxs * Q1) + hxq * ((Q2 + hxs * Q3) + hxq * (Q4 + hxs * Q5));
872
+ t = 3.0 - r1 * hfx;
873
+ let e = hxs * ((r1 - t) / (6.0 - x * t));
874
+ if (k == 0) return x - (x * e - hxs);
875
+ e = x * (e - c) - c;
876
+ e -= hxs;
877
+ if (k == -1) return 0.5 * (x - e) - 0.5;
878
+ if (k == 1) {
879
+ if (x < -0.25) return -2.0 * (e - (x + 0.5));
880
+ return 1.0 + 2.0 * (x - e);
881
+ }
882
+ u = (0x3FF + k) << 52;
883
+ let twopk = reinterpret<f64>(u);
884
+ let y: f64;
885
+ if (k < 0 || k > 56) {
886
+ y = x - e + 1.0;
887
+ if (k == 1024) y = y * 2.0 * Ox1p1023;
888
+ else y = y * twopk;
889
+ return y - 1.0;
890
+ }
891
+ u = (0x3FF - k) << 52;
892
+ y = reinterpret<f64>(u);
893
+ if (k < 20) y = (1 - y) - e;
894
+ else y = 1 - (e + y);
895
+ return (x + y) * twopk;
896
+ }
897
+
898
+ // @ts-ignore: decorator
899
+ @inline
900
+ export function floor(x: f64): f64 {
901
+ return builtin_floor<f64>(x);
902
+ }
903
+
904
+ // @ts-ignore: decorator
905
+ @inline
906
+ export function fround(x: f64): f64 {
907
+ return <f32>x;
908
+ }
909
+
910
+ export function hypot(x: f64, y: f64): f64 { // see: musl/src/math/hypot.c
911
+ const
912
+ SPLIT = reinterpret<f64>(0x41A0000000000000) + 1, // 0x1p27 + 1
913
+ Ox1p700 = reinterpret<f64>(0x6BB0000000000000),
914
+ Ox1p_700 = reinterpret<f64>(0x1430000000000000);
915
+
916
+ let ux = reinterpret<u64>(x);
917
+ let uy = reinterpret<u64>(y);
918
+ ux &= 0x7FFFFFFFFFFFFFFF;
919
+ uy &= 0x7FFFFFFFFFFFFFFF;
920
+ if (ux < uy) {
921
+ let ut = ux;
922
+ ux = uy;
923
+ uy = ut;
924
+ }
925
+ let ex = i32(ux >> 52);
926
+ let ey = i32(uy >> 52);
927
+ y = reinterpret<f64>(uy);
928
+ if (ey == 0x7FF) return y;
929
+ x = reinterpret<f64>(ux);
930
+ if (ex == 0x7FF || uy == 0) return x;
931
+ if (ex - ey > 64) return x + y;
932
+ let z = 1.0;
933
+ if (ex > 0x3FF + 510) {
934
+ z = Ox1p700;
935
+ x *= Ox1p_700;
936
+ y *= Ox1p_700;
937
+ } else if (ey < 0x3FF - 450) {
938
+ z = Ox1p_700;
939
+ x *= Ox1p700;
940
+ y *= Ox1p700;
941
+ }
942
+ let c = x * SPLIT;
943
+ let h = x - c + c;
944
+ let l = x - h;
945
+ let hx = x * x;
946
+ let lx = h * h - hx + (2 * h + l) * l;
947
+ c = y * SPLIT;
948
+ h = y - c + c;
949
+ l = y - h;
950
+ let hy = y * y;
951
+ let ly = h * h - hy + (2 * h + l) * l;
952
+ return z * builtin_sqrt(ly + lx + hy + hx);
953
+ }
954
+
955
+ export function imul(x: f64, y: f64): f64 {
956
+ /*
957
+ * Wasm (MVP) and JS have different approaches for double->int conversions.
958
+ *
959
+ * For emulate JS conversion behavior and avoid trapping from wasm we should modulate by MAX_INT
960
+ * our float-point arguments before actual convertion to integers.
961
+ */
962
+ if (!isFinite(x + y)) return 0;
963
+ return dtoi32(x) * dtoi32(y);
964
+ }
965
+
966
+ export function log(x: f64): f64 { // see: musl/src/math/log.c and SUN COPYRIGHT NOTICE above
967
+ if (ASC_SHRINK_LEVEL < 1) {
968
+ return log_lut(x);
969
+ } else {
970
+ const
971
+ ln2_hi = reinterpret<f64>(0x3FE62E42FEE00000), // 6.93147180369123816490e-01
972
+ ln2_lo = reinterpret<f64>(0x3DEA39EF35793C76), // 1.90821492927058770002e-10
973
+ Lg1 = reinterpret<f64>(0x3FE5555555555593), // 6.666666666666735130e-01
974
+ Lg2 = reinterpret<f64>(0x3FD999999997FA04), // 3.999999999940941908e-01
975
+ Lg3 = reinterpret<f64>(0x3FD2492494229359), // 2.857142874366239149e-01
976
+ Lg4 = reinterpret<f64>(0x3FCC71C51D8E78AF), // 2.222219843214978396e-01
977
+ Lg5 = reinterpret<f64>(0x3FC7466496CB03DE), // 1.818357216161805012e-01
978
+ Lg6 = reinterpret<f64>(0x3FC39A09D078C69F), // 1.531383769920937332e-01
979
+ Lg7 = reinterpret<f64>(0x3FC2F112DF3E5244), // 1.479819860511658591e-01
980
+ Ox1p54 = reinterpret<f64>(0x4350000000000000); // 0x1p54
981
+
982
+ let u = reinterpret<u64>(x);
983
+ let hx = u32(u >> 32);
984
+ let k = 0;
985
+ let sign = hx >> 31;
986
+ if (sign || hx < 0x00100000) {
987
+ if (u << 1 == 0) return -1 / (x * x);
988
+ if (sign) return (x - x) / 0.0;
989
+ k -= 54;
990
+ x *= Ox1p54;
991
+ u = reinterpret<u64>(x);
992
+ hx = u32(u >> 32);
993
+ } else if (hx >= 0x7FF00000) {
994
+ return x;
995
+ } else if (hx == 0x3FF00000 && u << 32 == 0) {
996
+ return 0;
997
+ }
998
+ hx += 0x3FF00000 - 0x3FE6A09E;
999
+ k += (<i32>hx >> 20) - 0x3FF;
1000
+ hx = (hx & 0x000FFFFF) + 0x3FE6A09E;
1001
+ u = <u64>hx << 32 | (u & 0xFFFFFFFF);
1002
+ x = reinterpret<f64>(u);
1003
+ let f = x - 1.0;
1004
+ let hfsq = 0.5 * f * f;
1005
+ let s = f / (2.0 + f);
1006
+ let z = s * s;
1007
+ let w = z * z;
1008
+ let t1 = w * (Lg2 + w * (Lg4 + w * Lg6));
1009
+ let t2 = z * (Lg1 + w * (Lg3 + w * (Lg5 + w * Lg7)));
1010
+ let r = t2 + t1;
1011
+ let dk = <f64>k;
1012
+ return s * (hfsq + r) + dk * ln2_lo - hfsq + f + dk * ln2_hi;
1013
+ }
1014
+ }
1015
+
1016
+ export function log10(x: f64): f64 { // see: musl/src/math/log10.c and SUN COPYRIGHT NOTICE above
1017
+ const
1018
+ ivln10hi = reinterpret<f64>(0x3FDBCB7B15200000), // 4.34294481878168880939e-01
1019
+ ivln10lo = reinterpret<f64>(0x3DBB9438CA9AADD5), // 2.50829467116452752298e-11
1020
+ log10_2hi = reinterpret<f64>(0x3FD34413509F6000), // 3.01029995663611771306e-01
1021
+ log10_2lo = reinterpret<f64>(0x3D59FEF311F12B36), // 3.69423907715893078616e-13
1022
+ Lg1 = reinterpret<f64>(0x3FE5555555555593), // 6.666666666666735130e-01
1023
+ Lg2 = reinterpret<f64>(0x3FD999999997FA04), // 3.999999999940941908e-01
1024
+ Lg3 = reinterpret<f64>(0x3FD2492494229359), // 2.857142874366239149e-01
1025
+ Lg4 = reinterpret<f64>(0x3FCC71C51D8E78AF), // 2.222219843214978396e-01
1026
+ Lg5 = reinterpret<f64>(0x3FC7466496CB03DE), // 1.818357216161805012e-01
1027
+ Lg6 = reinterpret<f64>(0x3FC39A09D078C69F), // 1.531383769920937332e-01
1028
+ Lg7 = reinterpret<f64>(0x3FC2F112DF3E5244), // 1.479819860511658591e-01
1029
+ Ox1p54 = reinterpret<f64>(0x4350000000000000); // 0x1p54
1030
+
1031
+ let u = reinterpret<u64>(x);
1032
+ let hx = u32(u >> 32);
1033
+ let k = 0;
1034
+ let sign = hx >> 31;
1035
+ if (sign || hx < 0x00100000) {
1036
+ if (u << 1 == 0) return -1 / (x * x);
1037
+ if (sign) return (x - x) / 0.0;
1038
+ k -= 54;
1039
+ x *= Ox1p54;
1040
+ u = reinterpret<u64>(x);
1041
+ hx = u32(u >> 32);
1042
+ } else if (hx >= 0x7FF00000) {
1043
+ return x;
1044
+ } else if (hx == 0x3FF00000 && u << 32 == 0) {
1045
+ return 0;
1046
+ }
1047
+ hx += 0x3FF00000 - 0x3FE6A09E;
1048
+ k += i32(hx >> 20) - 0x3FF;
1049
+ hx = (hx & 0x000FFFFF) + 0x3FE6A09E;
1050
+ u = <u64>hx << 32 | (u & 0xFFFFFFFF);
1051
+ x = reinterpret<f64>(u);
1052
+ let f = x - 1.0;
1053
+ let hfsq = 0.5 * f * f;
1054
+ let s = f / (2.0 + f);
1055
+ let z = s * s;
1056
+ let w = z * z;
1057
+ let t1 = w * (Lg2 + w * (Lg4 + w * Lg6));
1058
+ let t2 = z * (Lg1 + w * (Lg3 + w * (Lg5 + w * Lg7)));
1059
+ let r = t2 + t1;
1060
+ let hi = f - hfsq;
1061
+ u = reinterpret<u64>(hi);
1062
+ u &= 0xFFFFFFFF00000000;
1063
+ hi = reinterpret<f64>(u);
1064
+ let lo = f - hi - hfsq + s * (hfsq + r);
1065
+ let val_hi = hi * ivln10hi;
1066
+ let dk = <f64>k;
1067
+ let y = dk * log10_2hi;
1068
+ let val_lo = dk * log10_2lo + (lo + hi) * ivln10lo + lo * ivln10hi;
1069
+ w = y + val_hi;
1070
+ val_lo += (y - w) + val_hi;
1071
+ return val_lo + w;
1072
+ }
1073
+
1074
+ export function log1p(x: f64): f64 { // see: musl/src/math/log1p.c and SUN COPYRIGHT NOTICE above
1075
+ const
1076
+ ln2_hi = reinterpret<f64>(0x3FE62E42FEE00000), // 6.93147180369123816490e-01
1077
+ ln2_lo = reinterpret<f64>(0x3DEA39EF35793C76), // 1.90821492927058770002e-10
1078
+ Lg1 = reinterpret<f64>(0x3FE5555555555593), // 6.666666666666735130e-01
1079
+ Lg2 = reinterpret<f64>(0x3FD999999997FA04), // 3.999999999940941908e-01
1080
+ Lg3 = reinterpret<f64>(0x3FD2492494229359), // 2.857142874366239149e-01
1081
+ Lg4 = reinterpret<f64>(0x3FCC71C51D8E78AF), // 2.222219843214978396e-01
1082
+ Lg5 = reinterpret<f64>(0x3FC7466496CB03DE), // 1.818357216161805012e-01
1083
+ Lg6 = reinterpret<f64>(0x3FC39A09D078C69F), // 1.531383769920937332e-01
1084
+ Lg7 = reinterpret<f64>(0x3FC2F112DF3E5244); // 1.479819860511658591e-01
1085
+
1086
+ let u = reinterpret<u64>(x);
1087
+ let hx = u32(u >> 32);
1088
+ let k = 1;
1089
+ let c = 0.0, f = 0.0;
1090
+ if (hx < 0x3FDA827A || bool(hx >> 31)) {
1091
+ if (hx >= 0xBFF00000) {
1092
+ if (x == -1) return x / 0.0;
1093
+ return (x - x) / 0.0;
1094
+ }
1095
+ if (hx << 1 < 0x3CA00000 << 1) return x;
1096
+ if (hx <= 0xBFD2BEC4) {
1097
+ k = 0;
1098
+ c = 0;
1099
+ f = x;
1100
+ }
1101
+ } else if (hx >= 0x7FF00000) return x;
1102
+ if (k) {
1103
+ u = reinterpret<u64>(1 + x);
1104
+ let hu = u32(u >> 32);
1105
+ hu += 0x3FF00000 - 0x3FE6A09E;
1106
+ k = i32(hu >> 20) - 0x3FF;
1107
+ if (k < 54) {
1108
+ let uf = reinterpret<f64>(u);
1109
+ c = k >= 2 ? 1 - (uf - x) : x - (uf - 1);
1110
+ c /= uf;
1111
+ } else c = 0;
1112
+ hu = (hu & 0x000FFFFF) + 0x3FE6A09E;
1113
+ u = <u64>hu << 32 | (u & 0xFFFFFFFF);
1114
+ f = reinterpret<f64>(u) - 1;
1115
+ }
1116
+ let hfsq = 0.5 * f * f;
1117
+ let s = f / (2.0 + f);
1118
+ let z = s * s;
1119
+ let w = z * z;
1120
+ let t1 = w * (Lg2 + w * (Lg4 + w * Lg6));
1121
+ let t2 = z * (Lg1 + w * (Lg3 + w * (Lg5 + w * Lg7)));
1122
+ let r = t2 + t1;
1123
+ let dk = <f64>k;
1124
+ return s * (hfsq + r) + (dk * ln2_lo + c) - hfsq + f + dk * ln2_hi;
1125
+ }
1126
+
1127
+ export function log2(x: f64): f64 { // see: musl/src/math/log2.c and SUN COPYRIGHT NOTICE above
1128
+ if (ASC_SHRINK_LEVEL < 1) {
1129
+ return log2_lut(x);
1130
+ } else {
1131
+ const
1132
+ ivln2hi = reinterpret<f64>(0x3FF7154765200000), // 1.44269504072144627571e+00
1133
+ ivln2lo = reinterpret<f64>(0x3DE705FC2EEFA200), // 1.67517131648865118353e-10
1134
+ Lg1 = reinterpret<f64>(0x3FE5555555555593), // 6.666666666666735130e-01
1135
+ Lg2 = reinterpret<f64>(0x3FD999999997FA04), // 3.999999999940941908e-01
1136
+ Lg3 = reinterpret<f64>(0x3FD2492494229359), // 2.857142874366239149e-01
1137
+ Lg4 = reinterpret<f64>(0x3FCC71C51D8E78AF), // 2.222219843214978396e-01
1138
+ Lg5 = reinterpret<f64>(0x3FC7466496CB03DE), // 1.818357216161805012e-01
1139
+ Lg6 = reinterpret<f64>(0x3FC39A09D078C69F), // 1.531383769920937332e-01
1140
+ Lg7 = reinterpret<f64>(0x3FC2F112DF3E5244), // 1.479819860511658591e-01
1141
+ Ox1p54 = reinterpret<f64>(0x4350000000000000); // 1p54
1142
+
1143
+ let u = reinterpret<u64>(x);
1144
+ let hx = u32(u >> 32);
1145
+ let k = 0;
1146
+ let sign = hx >> 31;
1147
+ if (sign || hx < 0x00100000) {
1148
+ if (u << 1 == 0) return -1 / (x * x);
1149
+ if (sign) return (x - x) / 0.0;
1150
+ k -= 54;
1151
+ x *= Ox1p54;
1152
+ u = reinterpret<u64>(x);
1153
+ hx = u32(u >> 32);
1154
+ } else if (hx >= 0x7FF00000) {
1155
+ return x;
1156
+ } else if (hx == 0x3FF00000 && u << 32 == 0) {
1157
+ return 0;
1158
+ }
1159
+ hx += 0x3FF00000 - 0x3FE6A09E;
1160
+ k += i32(hx >> 20) - 0x3FF;
1161
+ hx = (hx & 0x000FFFFF) + 0x3FE6A09E;
1162
+ u = <u64>hx << 32 | (u & 0xFFFFFFFF);
1163
+ x = reinterpret<f64>(u);
1164
+ let f = x - 1.0;
1165
+ let hfsq = 0.5 * f * f;
1166
+ let s = f / (2.0 + f);
1167
+ let z = s * s;
1168
+ let w = z * z;
1169
+ let t1 = w * (Lg2 + w * (Lg4 + w * Lg6));
1170
+ let t2 = z * (Lg1 + w * (Lg3 + w * (Lg5 + w * Lg7)));
1171
+ let r = t2 + t1;
1172
+ let hi = f - hfsq;
1173
+ u = reinterpret<u64>(hi);
1174
+ u &= 0xFFFFFFFF00000000;
1175
+ hi = reinterpret<f64>(u);
1176
+ let lo = f - hi - hfsq + s * (hfsq + r);
1177
+ let val_hi = hi * ivln2hi;
1178
+ let val_lo = (lo + hi) * ivln2lo + lo * ivln2hi;
1179
+ let y = <f64>k;
1180
+ w = y + val_hi;
1181
+ val_lo += (y - w) + val_hi;
1182
+ val_hi = w;
1183
+ return val_lo + val_hi;
1184
+ }
1185
+ }
1186
+
1187
+ // @ts-ignore: decorator
1188
+ @inline
1189
+ export function max(value1: f64, value2: f64): f64 {
1190
+ return builtin_max<f64>(value1, value2);
1191
+ }
1192
+
1193
+ // @ts-ignore: decorator
1194
+ @inline
1195
+ export function min(value1: f64, value2: f64): f64 {
1196
+ return builtin_min<f64>(value1, value2);
1197
+ }
1198
+
1199
+ export function pow(x: f64, y: f64): f64 { // see: musl/src/math/pow.c and SUN COPYRIGHT NOTICE above
1200
+ // TODO: remove this fast pathes after introduced own mid-end IR with "stdlib call simplify" transforms
1201
+ if (builtin_abs<f64>(y) <= 2) {
1202
+ if (y == 2.0) return x * x;
1203
+ if (y == 0.5) {
1204
+ return select<f64>(
1205
+ builtin_abs<f64>(builtin_sqrt<f64>(x)),
1206
+ Infinity,
1207
+ x != -Infinity
1208
+ );
1209
+ }
1210
+ if (y == -1.0) return 1 / x;
1211
+ if (y == 1.0) return x;
1212
+ if (y == 0.0) return 1.0;
1213
+ }
1214
+ if (ASC_SHRINK_LEVEL < 1) {
1215
+ return pow_lut(x, y);
1216
+ } else {
1217
+ const
1218
+ dp_h1 = reinterpret<f64>(0x3FE2B80340000000), // 5.84962487220764160156e-01
1219
+ dp_l1 = reinterpret<f64>(0x3E4CFDEB43CFD006), // 1.35003920212974897128e-08
1220
+ two53 = reinterpret<f64>(0x4340000000000000), // 9007199254740992.0
1221
+ huge = reinterpret<f64>(0x7E37E43C8800759C), // 1e+300
1222
+ tiny = reinterpret<f64>(0x01A56E1FC2F8F359), // 1e-300
1223
+ L1 = reinterpret<f64>(0x3FE3333333333303), // 5.99999999999994648725e-01
1224
+ L2 = reinterpret<f64>(0x3FDB6DB6DB6FABFF), // 4.28571428578550184252e-01
1225
+ L3 = reinterpret<f64>(0x3FD55555518F264D), // 3.33333329818377432918e-01
1226
+ L4 = reinterpret<f64>(0x3FD17460A91D4101), // 2.72728123808534006489e-01
1227
+ L5 = reinterpret<f64>(0x3FCD864A93C9DB65), // 2.30660745775561754067e-01
1228
+ L6 = reinterpret<f64>(0x3FCA7E284A454EEF), // 2.06975017800338417784e-01
1229
+ P1 = reinterpret<f64>(0x3FC555555555553E), // 1.66666666666666019037e-01
1230
+ P2 = reinterpret<f64>(0xBF66C16C16BEBD93), // -2.77777777770155933842e-03
1231
+ P3 = reinterpret<f64>(0x3F11566AAF25DE2C), // 6.61375632143793436117e-05
1232
+ P4 = reinterpret<f64>(0xBEBBBD41C5D26BF1), // -1.65339022054652515390e-06
1233
+ P5 = reinterpret<f64>(0x3E66376972BEA4D0), // 4.13813679705723846039e-08
1234
+ lg2 = reinterpret<f64>(0x3FE62E42FEFA39EF), // 6.93147180559945286227e-01
1235
+ lg2_h = reinterpret<f64>(0x3FE62E4300000000), // 6.93147182464599609375e-01
1236
+ lg2_l = reinterpret<f64>(0xBE205C610CA86C39), // -1.90465429995776804525e-09
1237
+ ovt = reinterpret<f64>(0x3C971547652B82FE), // 8.0085662595372944372e-017
1238
+ cp = reinterpret<f64>(0x3FEEC709DC3A03FD), // 9.61796693925975554329e-01
1239
+ cp_h = reinterpret<f64>(0x3FEEC709E0000000), // 9.61796700954437255859e-01
1240
+ cp_l = reinterpret<f64>(0xBE3E2FE0145B01F5), // -7.02846165095275826516e-09
1241
+ ivln2 = reinterpret<f64>(0x3FF71547652B82FE), // 1.44269504088896338700e+00
1242
+ ivln2_h = reinterpret<f64>(0x3FF7154760000000), // 1.44269502162933349609e+00
1243
+ ivln2_l = reinterpret<f64>(0x3E54AE0BF85DDF44), // 1.92596299112661746887e-08
1244
+ inv3 = reinterpret<f64>(0x3FD5555555555555); // 0.3333333333333333333333
1245
+
1246
+ let u_ = reinterpret<u64>(x);
1247
+ let hx = i32(u_ >> 32);
1248
+ let lx = <u32>u_;
1249
+ u_ = reinterpret<u64>(y);
1250
+ let hy = i32(u_ >> 32);
1251
+ let ly = <u32>u_;
1252
+ let ix = hx & 0x7FFFFFFF;
1253
+ let iy = hy & 0x7FFFFFFF;
1254
+ if ((iy | ly) == 0) return 1.0; // x**0 = 1, even if x is NaN
1255
+ // if (hx == 0x3FF00000 && lx == 0) return 1.0; // C: 1**y = 1, even if y is NaN, JS: NaN
1256
+ if ( // NaN if either arg is NaN
1257
+ ix > 0x7FF00000 || (ix == 0x7FF00000 && lx != 0) ||
1258
+ iy > 0x7FF00000 || (iy == 0x7FF00000 && ly != 0)
1259
+ ) return x + y;
1260
+ let yisint = 0, k: i32;
1261
+ if (hx < 0) {
1262
+ if (iy >= 0x43400000) yisint = 2;
1263
+ else if (iy >= 0x3FF00000) {
1264
+ k = (iy >> 20) - 0x3FF;
1265
+ let offset = select<u32>(52, 20, k > 20) - k;
1266
+ let Ly = select<u32>(ly, iy, k > 20);
1267
+ let jj = Ly >> offset;
1268
+ if ((jj << offset) == Ly) yisint = 2 - (jj & 1);
1269
+ }
1270
+ }
1271
+ if (ly == 0) {
1272
+ if (iy == 0x7FF00000) { // y is +-inf
1273
+ if (((ix - 0x3FF00000) | lx) == 0) return NaN; // C: (-1)**+-inf is 1, JS: NaN
1274
+ else if (ix >= 0x3FF00000) return hy >= 0 ? y : 0.0; // (|x|>1)**+-inf = inf,0
1275
+ else return hy >= 0 ? 0.0 : -y; // (|x|<1)**+-inf = 0,inf
1276
+ }
1277
+ if (iy == 0x3FF00000) {
1278
+ if (hy >= 0) return x;
1279
+ return 1 / x;
1280
+ }
1281
+ if (hy == 0x40000000) return x * x;
1282
+ if (hy == 0x3FE00000) {
1283
+ if (hx >= 0) return builtin_sqrt(x);
1284
+ }
1285
+ }
1286
+ let ax = builtin_abs<f64>(x), z: f64;
1287
+ if (lx == 0) {
1288
+ if (ix == 0 || ix == 0x7FF00000 || ix == 0x3FF00000) {
1289
+ z = ax;
1290
+ if (hy < 0) z = 1.0 / z;
1291
+ if (hx < 0) {
1292
+ if (((ix - 0x3FF00000) | yisint) == 0) {
1293
+ let d = z - z;
1294
+ z = d / d;
1295
+ } else if (yisint == 1) z = -z;
1296
+ }
1297
+ return z;
1298
+ }
1299
+ }
1300
+ let s = 1.0;
1301
+ if (hx < 0) {
1302
+ if (yisint == 0) {
1303
+ let d = x - x;
1304
+ return d / d;
1305
+ }
1306
+ if (yisint == 1) s = -1.0;
1307
+ }
1308
+ let t1: f64, t2: f64, p_h: f64, p_l: f64, r: f64, t: f64, u: f64, v: f64, w: f64;
1309
+ let j: i32, n: i32;
1310
+ if (iy > 0x41E00000) {
1311
+ if (iy > 0x43F00000) {
1312
+ if (ix <= 0x3FEFFFFF) return hy < 0 ? huge * huge : tiny * tiny;
1313
+ if (ix >= 0x3FF00000) return hy > 0 ? huge * huge : tiny * tiny;
1314
+ }
1315
+ if (ix < 0x3FEFFFFF) return hy < 0 ? s * huge * huge : s * tiny * tiny;
1316
+ if (ix > 0x3FF00000) return hy > 0 ? s * huge * huge : s * tiny * tiny;
1317
+ t = ax - 1.0;
1318
+ w = (t * t) * (0.5 - t * (inv3 - t * 0.25));
1319
+ u = ivln2_h * t;
1320
+ v = t * ivln2_l - w * ivln2;
1321
+ t1 = u + v;
1322
+ t1 = reinterpret<f64>(reinterpret<u64>(t1) & 0xFFFFFFFF00000000);
1323
+ t2 = v - (t1 - u);
1324
+ } else {
1325
+ let ss: f64, s2: f64, s_h: f64, s_l: f64, t_h: f64, t_l: f64;
1326
+ n = 0;
1327
+ if (ix < 0x00100000) {
1328
+ ax *= two53;
1329
+ n -= 53;
1330
+ ix = <u32>(reinterpret<u64>(ax) >> 32);
1331
+ }
1332
+ n += (ix >> 20) - 0x3FF;
1333
+ j = ix & 0x000FFFFF;
1334
+ ix = j | 0x3FF00000;
1335
+ if (j <= 0x3988E) k = 0;
1336
+ else if (j < 0xBB67A) k = 1;
1337
+ else {
1338
+ k = 0;
1339
+ n += 1;
1340
+ ix -= 0x00100000;
1341
+ }
1342
+ ax = reinterpret<f64>(reinterpret<u64>(ax) & 0xFFFFFFFF | (<u64>ix << 32));
1343
+ let bp = select<f64>(1.5, 1.0, k); // k ? 1.5 : 1.0
1344
+ u = ax - bp;
1345
+ v = 1.0 / (ax + bp);
1346
+ ss = u * v;
1347
+ s_h = ss;
1348
+ s_h = reinterpret<f64>(reinterpret<u64>(s_h) & 0xFFFFFFFF00000000);
1349
+ t_h = reinterpret<f64>(u64(((ix >> 1) | 0x20000000) + 0x00080000 + (k << 18)) << 32);
1350
+ t_l = ax - (t_h - bp);
1351
+ s_l = v * ((u - s_h * t_h) - s_h * t_l);
1352
+ s2 = ss * ss;
1353
+ r = s2 * s2 * (L1 + s2 * (L2 + s2 * (L3 + s2 * (L4 + s2 * (L5 + s2 * L6)))));
1354
+ r += s_l * (s_h + ss);
1355
+ s2 = s_h * s_h;
1356
+ t_h = 3.0 + s2 + r;
1357
+ t_h = reinterpret<f64>(reinterpret<u64>(t_h) & 0xFFFFFFFF00000000);
1358
+ t_l = r - ((t_h - 3.0) - s2);
1359
+ u = s_h * t_h;
1360
+ v = s_l * t_h + t_l * ss;
1361
+ p_h = u + v;
1362
+ p_h = reinterpret<f64>(reinterpret<u64>(p_h) & 0xFFFFFFFF00000000);
1363
+ p_l = v - (p_h - u);
1364
+ let z_h = cp_h * p_h;
1365
+ let dp_l = select<f64>(dp_l1, 0.0, k);
1366
+ let z_l = cp_l * p_h + p_l * cp + dp_l;
1367
+ t = <f64>n;
1368
+ let dp_h = select<f64>(dp_h1, 0.0, k);
1369
+ t1 = ((z_h + z_l) + dp_h) + t;
1370
+ t1 = reinterpret<f64>(reinterpret<u64>(t1) & 0xFFFFFFFF00000000);
1371
+ t2 = z_l - (((t1 - t) - dp_h) - z_h);
1372
+ }
1373
+ let y1 = y;
1374
+ y1 = reinterpret<f64>(reinterpret<u64>(y1) & 0xFFFFFFFF00000000);
1375
+ p_l = (y - y1) * t1 + y * t2;
1376
+ p_h = y1 * t1;
1377
+ z = p_l + p_h;
1378
+ u_ = reinterpret<u64>(z);
1379
+ j = u32(u_ >> 32);
1380
+ let i = <i32>u_;
1381
+ if (j >= 0x40900000) {
1382
+ if (((j - 0x40900000) | i) != 0) return s * huge * huge;
1383
+ if (p_l + ovt > z - p_h) return s * huge * huge;
1384
+ } else if ((j & 0x7FFFFFFF) >= 0x4090CC00) {
1385
+ if (((j - 0xC090CC00) | i) != 0) return s * tiny * tiny;
1386
+ if (p_l <= z - p_h) return s * tiny * tiny;
1387
+ }
1388
+ i = j & 0x7FFFFFFF;
1389
+ k = (i >> 20) - 0x3FF;
1390
+ n = 0;
1391
+ if (i > 0x3FE00000) {
1392
+ n = j + (0x00100000 >> (k + 1));
1393
+ k = ((n & 0x7FFFFFFF) >> 20) - 0x3FF;
1394
+ t = 0.0;
1395
+ t = reinterpret<f64>(u64(n & ~(0x000FFFFF >> k)) << 32);
1396
+ n = ((n & 0x000FFFFF) | 0x00100000) >> (20 - k);
1397
+ if (j < 0) n = -n;
1398
+ p_h -= t;
1399
+ }
1400
+ t = p_l + p_h;
1401
+ t = reinterpret<f64>(reinterpret<u64>(t) & 0xFFFFFFFF00000000);
1402
+ u = t * lg2_h;
1403
+ v = (p_l - (t - p_h)) * lg2 + t * lg2_l;
1404
+ z = u + v;
1405
+ w = v - (z - u);
1406
+ t = z * z;
1407
+ t1 = z - t * (P1 + t * (P2 + t * (P3 + t * (P4 + t * P5))));
1408
+ r = (z * t1) / (t1 - 2.0) - (w + z * w);
1409
+ z = 1.0 - (r - z);
1410
+ j = u32(reinterpret<u64>(z) >> 32);
1411
+ j += n << 20;
1412
+ if ((j >> 20) <= 0) z = scalbn(z, n);
1413
+ else z = reinterpret<f64>(reinterpret<u64>(z) & 0xFFFFFFFF | (<u64>j << 32));
1414
+ return s * z;
1415
+ }
1416
+ }
1417
+
1418
+ export function seedRandom(value: i64): void {
1419
+ // Instead zero seed use golden ratio:
1420
+ // phi = (1 + sqrt(5)) / 2
1421
+ // trunc(2^64 / phi) = 0x9e3779b97f4a7c15
1422
+ if (value == 0) value = 0x9e3779b97f4a7c15;
1423
+ random_state0_64 = murmurHash3(value);
1424
+ random_state1_64 = murmurHash3(~random_state0_64);
1425
+ random_state0_32 = splitMix32(<u32>value);
1426
+ random_state1_32 = splitMix32(random_state0_32);
1427
+ random_seeded = true;
1428
+ }
1429
+
1430
+ export function random(): f64 { // see: v8/src/base/utils/random-number-generator.cc
1431
+ if (!random_seeded) seedRandom(reinterpret<i64>(seed()));
1432
+ let s1 = random_state0_64;
1433
+ let s0 = random_state1_64;
1434
+ random_state0_64 = s0;
1435
+ s1 ^= s1 << 23;
1436
+ s1 ^= s1 >> 17;
1437
+ s1 ^= s0;
1438
+ s1 ^= s0 >> 26;
1439
+ random_state1_64 = s1;
1440
+ let r = (s0 >> 12) | 0x3FF0000000000000;
1441
+ return reinterpret<f64>(r) - 1;
1442
+ }
1443
+
1444
+ export function round(x: f64): f64 {
1445
+ if (ASC_SHRINK_LEVEL > 0) {
1446
+ return builtin_ceil<f64>(x) - f64(builtin_ceil<f64>(x) - 0.5 > x);
1447
+ } else {
1448
+ let roundUp = builtin_ceil<f64>(x);
1449
+ return select<f64>(roundUp, roundUp - 1.0, roundUp - 0.5 <= x);
1450
+ }
1451
+ }
1452
+
1453
+ export function sign(x: f64): f64 {
1454
+ if (ASC_SHRINK_LEVEL > 0) {
1455
+ return select<f64>(builtin_copysign<f64>(1, x), x, builtin_abs(x) > 0);
1456
+ } else {
1457
+ return select<f64>(1, select<f64>(-1, x, x < 0), x > 0);
1458
+ }
1459
+ }
1460
+
1461
+ // @ts-ignore: decorator
1462
+ @inline
1463
+ export function signbit(x: f64): bool {
1464
+ return bool(reinterpret<u64>(x) >>> 63);
1465
+ }
1466
+
1467
+ export function sin(x: f64): f64 { // see: musl/src/math/sin.c
1468
+ let u = reinterpret<u64>(x);
1469
+ let ux = u32(u >> 32);
1470
+ let sign = ux >> 31;
1471
+
1472
+ ux &= 0x7FFFFFFF;
1473
+
1474
+ // |x| ~< pi/4
1475
+ if (ux <= 0x3FE921FB) {
1476
+ if (ux < 0x3E500000) { // |x| < 2**-26
1477
+ return x;
1478
+ }
1479
+ return sin_kern(x, 0.0, 0);
1480
+ }
1481
+
1482
+ // sin(Inf or NaN) is NaN
1483
+ if (ux >= 0x7FF00000) return x - x;
1484
+
1485
+ // argument reduction needed
1486
+ let n = rempio2(x, u, sign);
1487
+ let y0 = rempio2_y0;
1488
+ let y1 = rempio2_y1;
1489
+
1490
+ x = n & 1 ? cos_kern(y0, y1) : sin_kern(y0, y1, 1);
1491
+ return n & 2 ? -x : x;
1492
+ }
1493
+
1494
+ export function sinh(x: f64): f64 { // see: musl/src/math/sinh.c
1495
+ let u = reinterpret<u64>(x) & 0x7FFFFFFFFFFFFFFF;
1496
+ let a = reinterpret<f64>(u);
1497
+ let w = u32(u >> 32);
1498
+ let h = builtin_copysign(0.5, x);
1499
+ if (w < 0x40862E42) {
1500
+ let t = expm1(a);
1501
+ if (w < 0x3FF00000) {
1502
+ if (w < 0x3FF00000 - (26 << 20)) return x;
1503
+ return h * (2 * t - t * t / (t + 1));
1504
+ }
1505
+ return h * (t + t / (t + 1));
1506
+ }
1507
+ return expo2(a, 2 * h);
1508
+ }
1509
+
1510
+ // @ts-ignore: decorator
1511
+ @inline
1512
+ export function sqrt(x: f64): f64 {
1513
+ return builtin_sqrt<f64>(x);
1514
+ }
1515
+
1516
+ export function tan(x: f64): f64 { // see: musl/src/math/tan.c
1517
+ let u = reinterpret<u64>(x);
1518
+ let ux = u32(u >> 32);
1519
+ let sign = ux >>> 31;
1520
+
1521
+ ux &= 0x7FFFFFFF;
1522
+
1523
+ // |x| ~< pi/4
1524
+ if (ux <= 0x3FE921FB) {
1525
+ if (ux < 0x3E400000) { // |x| < 2**-27
1526
+ return x;
1527
+ }
1528
+ return tan_kern(x, 0.0, 1);
1529
+ }
1530
+
1531
+ // tan(Inf or NaN) is NaN
1532
+ if (ux >= 0x7FF00000) return x - x;
1533
+
1534
+ let n = rempio2(x, u, sign);
1535
+ return tan_kern(rempio2_y0, rempio2_y1, 1 - ((n & 1) << 1));
1536
+ }
1537
+
1538
+ export function tanh(x: f64): f64 { // see: musl/src/math/tanh.c
1539
+ let u = reinterpret<u64>(x);
1540
+ u &= 0x7FFFFFFFFFFFFFFF;
1541
+ let y = reinterpret<f64>(u);
1542
+ let w = u32(u >> 32);
1543
+ let t: f64;
1544
+ if (w > 0x3FE193EA) {
1545
+ if (w > 0x40340000) {
1546
+ t = 1 - 0 / y;
1547
+ } else {
1548
+ t = expm1(2 * y);
1549
+ t = 1 - 2 / (t + 2);
1550
+ }
1551
+ } else if (w > 0x3FD058AE) {
1552
+ t = expm1(2 * y);
1553
+ t = t / (t + 2);
1554
+ } else if (w >= 0x00100000) {
1555
+ t = expm1(-2 * y);
1556
+ t = -t / (t + 2);
1557
+ } else t = y;
1558
+ return builtin_copysign<f64>(t, x);
1559
+ }
1560
+
1561
+ // @ts-ignore: decorator
1562
+ @inline
1563
+ export function trunc(x: f64): f64 {
1564
+ return builtin_trunc<f64>(x);
1565
+ }
1566
+
1567
+ export function scalbn(x: f64, n: i32): f64 { // see: https://git.musl-libc.org/cgit/musl/tree/src/math/scalbn.c
1568
+ const
1569
+ Ox1p53 = reinterpret<f64>(0x4340000000000000),
1570
+ Ox1p1023 = reinterpret<f64>(0x7FE0000000000000),
1571
+ Ox1p_1022 = reinterpret<f64>(0x0010000000000000);
1572
+
1573
+ let y = x;
1574
+ if (n > 1023) {
1575
+ y *= Ox1p1023;
1576
+ n -= 1023;
1577
+ if (n > 1023) {
1578
+ y *= Ox1p1023;
1579
+ n = builtin_min<i32>(n - 1023, 1023);
1580
+ }
1581
+ } else if (n < -1022) {
1582
+ // make sure final n < -53 to avoid double
1583
+ // rounding in the subnormal range
1584
+ y *= Ox1p_1022 * Ox1p53;
1585
+ n += 1022 - 53;
1586
+ if (n < -1022) {
1587
+ y *= Ox1p_1022 * Ox1p53;
1588
+ n = builtin_max<i32>(n + 1022 - 53, -1022);
1589
+ }
1590
+ }
1591
+ return y * reinterpret<f64>(<u64>(0x3FF + n) << 52);
1592
+ }
1593
+
1594
+ export function mod(x: f64, y: f64): f64 { // see: musl/src/math/fmod.c
1595
+ if (builtin_abs<f64>(y) == 1.0) {
1596
+ // x % 1, x % -1 ==> sign(x) * abs(x - 1.0 * trunc(x / 1.0))
1597
+ // TODO: move this rule to compiler's optimization pass.
1598
+ // It could be apply for any x % C_pot, where "C_pot" is pow of two const.
1599
+ return builtin_copysign<f64>(x - builtin_trunc<f64>(x), x);
1600
+ }
1601
+ let ux = reinterpret<u64>(x);
1602
+ let uy = reinterpret<u64>(y);
1603
+ let ex = i64(ux >> 52 & 0x7FF);
1604
+ let ey = i64(uy >> 52 & 0x7FF);
1605
+ let sx = ux >> 63;
1606
+ let uy1 = uy << 1;
1607
+ if (uy1 == 0 || ex == 0x7FF || isNaN<f64>(y)) {
1608
+ let m = x * y;
1609
+ return m / m;
1610
+ }
1611
+ let ux1 = ux << 1;
1612
+ if (ux1 <= uy1) {
1613
+ return x * f64(ux1 != uy1);
1614
+ }
1615
+ if (!ex) {
1616
+ ex -= builtin_clz<i64>(ux << 12);
1617
+ ux <<= 1 - ex;
1618
+ } else {
1619
+ ux &= u64(-1) >> 12;
1620
+ ux |= 1 << 52;
1621
+ }
1622
+ if (!ey) {
1623
+ ey -= builtin_clz<i64>(uy << 12);
1624
+ uy <<= 1 - ey;
1625
+ } else {
1626
+ uy &= u64(-1) >> 12;
1627
+ uy |= 1 << 52;
1628
+ }
1629
+ while (ex > ey) {
1630
+ if (ux >= uy) {
1631
+ if (ux == uy) return 0 * x;
1632
+ ux -= uy;
1633
+ }
1634
+ ux <<= 1;
1635
+ --ex;
1636
+ }
1637
+ if (ux >= uy) {
1638
+ if (ux == uy) return 0 * x;
1639
+ ux -= uy;
1640
+ }
1641
+ // for (; !(ux >> 52); ux <<= 1) --ex;
1642
+ let shift = builtin_clz<i64>(ux << 11);
1643
+ ex -= shift;
1644
+ ux <<= shift;
1645
+ if (ex > 0) {
1646
+ ux -= 1 << 52;
1647
+ ux |= ex << 52;
1648
+ } else {
1649
+ ux >>= -ex + 1;
1650
+ }
1651
+ return reinterpret<f64>(ux | (sx << 63));
1652
+ }
1653
+
1654
+ export function rem(x: f64, y: f64): f64 { // see: musl/src/math/remquo.c
1655
+ let ux = reinterpret<u64>(x);
1656
+ let uy = reinterpret<u64>(y);
1657
+ let ex = i64(ux >> 52 & 0x7FF);
1658
+ let ey = i64(uy >> 52 & 0x7FF);
1659
+ if (uy << 1 == 0 || ex == 0x7FF || isNaN(y)) {
1660
+ let m = x * y;
1661
+ return m / m;
1662
+ }
1663
+ if (ux << 1 == 0) return x;
1664
+ let uxi = ux;
1665
+ if (!ex) {
1666
+ ex -= builtin_clz<i64>(uxi << 12);
1667
+ uxi <<= 1 - ex;
1668
+ } else {
1669
+ uxi &= u64(-1) >> 12;
1670
+ uxi |= 1 << 52;
1671
+ }
1672
+ if (!ey) {
1673
+ ey -= builtin_clz<i64>(uy << 12);
1674
+ uy <<= 1 - ey;
1675
+ } else {
1676
+ uy &= u64(-1) >> 12;
1677
+ uy |= 1 << 52;
1678
+ }
1679
+ let q: u32 = 0;
1680
+ do {
1681
+ if (ex < ey) {
1682
+ if (ex + 1 == ey) break; // goto end
1683
+ return x;
1684
+ }
1685
+ while (ex > ey) {
1686
+ if (uxi >= uy) {
1687
+ uxi -= uy;
1688
+ ++q;
1689
+ }
1690
+ uxi <<= 1;
1691
+ q <<= 1;
1692
+ --ex;
1693
+ }
1694
+ if (uxi >= uy) {
1695
+ uxi -= uy;
1696
+ ++q;
1697
+ }
1698
+ if (uxi == 0) ex = -60;
1699
+ else {
1700
+ let shift = builtin_clz<i64>(uxi << 11);
1701
+ ex -= shift;
1702
+ uxi <<= shift;
1703
+ }
1704
+ break;
1705
+ } while (false);
1706
+ // end:
1707
+ if (ex > 0) {
1708
+ uxi -= 1 << 52;
1709
+ uxi |= ex << 52;
1710
+ } else {
1711
+ uxi >>= -ex + 1;
1712
+ }
1713
+ x = reinterpret<f64>(uxi);
1714
+ y = builtin_abs<f64>(y);
1715
+ let x2 = x + x;
1716
+ if (ex == ey || (ex + 1 == ey && (x2 > y || (x2 == y && <bool>(q & 1))))) {
1717
+ x -= y;
1718
+ // ++q;
1719
+ }
1720
+ return <i64>ux < 0 ? -x : x;
1721
+ }
1722
+
1723
+ export function sincos(x: f64): void { // see: musl/tree/src/math/sincos.c
1724
+ let u = reinterpret<u64>(x);
1725
+ let ux = u32(u >> 32);
1726
+ let sign = ux >> 31;
1727
+ ux &= 0x7FFFFFFF;
1728
+
1729
+ if (ux <= 0x3FE921FB) { // |x| ~<= π/4
1730
+ if (ux < 0x3E46A09E) { // if |x| < 2**-27 * sqrt(2)
1731
+ sincos_sin = x;
1732
+ sincos_cos = 1;
1733
+ return;
1734
+ }
1735
+ sincos_sin = sin_kern(x, 0, 0);
1736
+ sincos_cos = cos_kern(x, 0);
1737
+ return;
1738
+ }
1739
+ // sin(Inf or NaN) is NaN
1740
+ if (ux >= 0x7F800000) {
1741
+ let xx = x - x;
1742
+ sincos_sin = xx;
1743
+ sincos_cos = xx;
1744
+ return;
1745
+ }
1746
+ // general argument reduction needed
1747
+ let n = rempio2(x, u, sign);
1748
+ let y0 = rempio2_y0;
1749
+ let y1 = rempio2_y1;
1750
+ let s = sin_kern(y0, y1, 1);
1751
+ let c = cos_kern(y0, y1);
1752
+ let sin = s, cos = c;
1753
+ if (n & 1) {
1754
+ sin = c;
1755
+ cos = -s;
1756
+ }
1757
+ if (n & 2) {
1758
+ sin = -sin;
1759
+ cos = -cos;
1760
+ }
1761
+ sincos_sin = sin;
1762
+ sincos_cos = cos;
1763
+ }
1764
+ }
1765
+
1766
+ // @ts-ignore: decorator
1767
+ @lazy let rempio2f_y: f64;
1768
+
1769
+ // @ts-ignore: decorator
1770
+ @lazy @inline const PIO2F_TABLE = memory.data<u64>([
1771
+ 0xA2F9836E4E441529,
1772
+ 0xFC2757D1F534DDC0,
1773
+ 0xDB6295993C439041,
1774
+ 0xFE5163ABDEBBC561
1775
+ ]);
1776
+
1777
+ function Rf(z: f32): f32 { // Rational approximation of (asin(x)-x)/x^3
1778
+ const // see: musl/src/math/asinf.c and SUN COPYRIGHT NOTICE above
1779
+ pS0 = reinterpret<f32>(0x3E2AAA75), // 1.6666586697e-01f
1780
+ pS1 = reinterpret<f32>(0xBD2F13BA), // -4.2743422091e-02f
1781
+ pS2 = reinterpret<f32>(0xBC0DD36B), // -8.6563630030e-03f
1782
+ qS1 = reinterpret<f32>(0xBF34E5AE); // -7.0662963390e-01f
1783
+
1784
+ let p = z * (pS0 + z * (pS1 + z * pS2));
1785
+ let q: f32 = 1 + z * qS1;
1786
+ return p / q;
1787
+ }
1788
+
1789
+ // @ts-ignore: decorator
1790
+ @inline
1791
+ function expo2f(x: f32, sign: f32): f32 { // exp(x)/2 for x >= log(DBL_MAX)
1792
+ const // see: musl/src/math/__expo2f.c
1793
+ k = <u32>235,
1794
+ kln2 = reinterpret<f32>(0x4322E3BC); // 0x1.45c778p+7f
1795
+ let scale = reinterpret<f32>(u32(0x7F + (k >> 1)) << 23);
1796
+ // in directed rounding correct sign before rounding or overflow is important
1797
+ return NativeMathf.exp(x - kln2) * (sign * scale) * scale;
1798
+ }
1799
+
1800
+ // @ts-ignore: decorator
1801
+ @inline
1802
+ function pio2f_large_quot(x: f32, u: i32): i32 { // see: jdh8/metallic/blob/master/src/math/float/rem_pio2f.c
1803
+ const coeff = reinterpret<f64>(0x3BF921FB54442D18); // π * 0x1p-65 = 8.51530395021638647334e-20
1804
+
1805
+ let offset = (u >> 23) - 152;
1806
+ let shift = u64(offset & 63);
1807
+ let tblPtr = PIO2F_TABLE + (offset >> 6 << 3);
1808
+
1809
+ let b0 = load<u64>(tblPtr, 0 << 3);
1810
+ let b1 = load<u64>(tblPtr, 1 << 3);
1811
+ let lo: u64;
1812
+
1813
+ if (shift > 32) {
1814
+ let b2 = load<u64>(tblPtr, 2 << 3);
1815
+ lo = b2 >> (96 - shift);
1816
+ lo |= b1 << (shift - 32);
1817
+ } else {
1818
+ lo = b1 >> (32 - shift);
1819
+ }
1820
+
1821
+ let hi = (b1 >> (64 - shift)) | (b0 << shift);
1822
+ let mantissa: u64 = (u & 0x007FFFFF) | 0x00800000;
1823
+ let product = mantissa * hi + (mantissa * lo >> 32);
1824
+ let r: i64 = product << 2;
1825
+ let q = i32((product >> 62) + (r >>> 63));
1826
+ rempio2f_y = copysign<f64>(coeff, x) * <f64>r;
1827
+ return q;
1828
+ }
1829
+
1830
+ // @ts-ignore: decorator
1831
+ @inline
1832
+ function rempio2f(x: f32, u: u32, sign: i32): i32 { // see: jdh8/metallic/blob/master/src/math/float/rem_pio2f.c
1833
+ const
1834
+ pi2hi = reinterpret<f64>(0x3FF921FB50000000), // 1.57079631090164184570
1835
+ pi2lo = reinterpret<f64>(0x3E5110B4611A6263), // 1.58932547735281966916e-8
1836
+ _2_pi = reinterpret<f64>(0x3FE45F306DC9C883); // 0.63661977236758134308
1837
+
1838
+ if (u < 0x4DC90FDB) { // π * 0x1p28
1839
+ let q = nearest(x * _2_pi);
1840
+ rempio2f_y = x - q * pi2hi - q * pi2lo;
1841
+ return <i32>q;
1842
+ }
1843
+
1844
+ let q = pio2f_large_quot(x, u);
1845
+ return select(-q, q, sign);
1846
+ }
1847
+
1848
+ // |sin(x)/x - s(x)| < 2**-37.5 (~[-4.89e-12, 4.824e-12]).
1849
+ // @ts-ignore: decorator
1850
+ @inline
1851
+ function sin_kernf(x: f64): f32 { // see: musl/tree/src/math/__sindf.c
1852
+ const
1853
+ S1 = reinterpret<f64>(0xBFC5555554CBAC77), // -0x15555554cbac77.0p-55
1854
+ S2 = reinterpret<f64>(0x3F811110896EFBB2), // 0x111110896efbb2.0p-59
1855
+ S3 = reinterpret<f64>(0xBF2A00F9E2CAE774), // -0x1a00f9e2cae774.0p-65
1856
+ S4 = reinterpret<f64>(0x3EC6CD878C3B46A7); // 0x16cd878c3b46a7.0p-71
1857
+
1858
+ let z = x * x;
1859
+ let w = z * z;
1860
+ let r = S3 + z * S4;
1861
+ let s = z * x;
1862
+ return f32((x + s * (S1 + z * S2)) + s * w * r);
1863
+ }
1864
+
1865
+ // |cos(x) - c(x)| < 2**-34.1 (~[-5.37e-11, 5.295e-11]).
1866
+ // @ts-ignore: decorator
1867
+ @inline
1868
+ function cos_kernf(x: f64): f32 { // see: musl/tree/src/math/__cosdf.c
1869
+ const
1870
+ C0 = reinterpret<f64>(0xBFDFFFFFFD0C5E81), // -0x1ffffffd0c5e81.0p-54
1871
+ C1 = reinterpret<f64>(0x3FA55553E1053A42), // 0x155553e1053a42.0p-57
1872
+ C2 = reinterpret<f64>(0xBF56C087E80F1E27), // -0x16c087e80f1e27.0p-62
1873
+ C3 = reinterpret<f64>(0x3EF99342E0EE5069); // 0x199342e0ee5069.0p-68
1874
+
1875
+ let z = x * x;
1876
+ let w = z * z;
1877
+ let r = C2 + z * C3;
1878
+ return f32(((1 + z * C0) + w * C1) + (w * z) * r);
1879
+ }
1880
+
1881
+ // |tan(x)/x - t(x)| < 2**-25.5 (~[-2e-08, 2e-08]).
1882
+ // @ts-ignore: decorator
1883
+ @inline
1884
+ function tan_kernf(x: f64, odd: i32): f32 { // see: musl/tree/src/math/__tandf.c
1885
+ const
1886
+ T0 = reinterpret<f64>(0x3FD5554D3418C99F), // 0x15554d3418c99f.0p-54
1887
+ T1 = reinterpret<f64>(0x3FC112FD38999F72), // 0x1112fd38999f72.0p-55
1888
+ T2 = reinterpret<f64>(0x3FAB54C91D865AFE), // 0x1b54c91d865afe.0p-57
1889
+ T3 = reinterpret<f64>(0x3F991DF3908C33CE), // 0x191df3908c33ce.0p-58
1890
+ T4 = reinterpret<f64>(0x3F685DADFCECF44E), // 0x185dadfcecf44e.0p-61
1891
+ T5 = reinterpret<f64>(0x3F8362B9BF971BCD); // 0x1362b9bf971bcd.0p-59
1892
+
1893
+ let z = x * x;
1894
+ let r = T4 + z * T5;
1895
+ let t = T2 + z * T3;
1896
+ let w = z * z;
1897
+ let s = z * x;
1898
+ let u = T0 + z * T1;
1899
+
1900
+ r = (x + s * u) + (s * w) * (t + w * r);
1901
+ return f32(odd ? -1 / r : r);
1902
+ }
1903
+
1904
+ // See: jdh8/metallic/src/math/float/log2f.c and jdh8/metallic/src/math/float/kernel/atanh.h
1905
+ // @ts-ignore: decorator
1906
+ @inline
1907
+ function log2f(x: f64): f64 {
1908
+ const
1909
+ log2e = reinterpret<f64>(0x3FF71547652B82FE), // 1.44269504088896340736
1910
+ c0 = reinterpret<f64>(0x3FD555554FD9CAEF), // 0.33333332822728226129
1911
+ c1 = reinterpret<f64>(0x3FC999A7A8AF4132), // 0.20000167595436263505
1912
+ c2 = reinterpret<f64>(0x3FC2438D79437030), // 0.14268654271188685375
1913
+ c3 = reinterpret<f64>(0x3FBE2F663B001C97); // 0.11791075649681414150
1914
+
1915
+ let i = reinterpret<i64>(x);
1916
+ let exponent = (i - 0x3FE6A09E667F3BCD) >> 52;
1917
+ x = reinterpret<f64>(i - (exponent << 52));
1918
+ x = (x - 1) / (x + 1);
1919
+ let xx = x * x;
1920
+ let y = x + x * xx * (c0 + c1 * xx + (c2 + c3 * xx) * (xx * xx));
1921
+ return (2 * log2e) * y + <f64>exponent;
1922
+ }
1923
+
1924
+ // See: jdh8/metallic/src/math/float/exp2f.h and jdh8/metallic/blob/master/src/math/float/kernel/exp2f.h
1925
+ // @ts-ignore: decorator
1926
+ @inline
1927
+ function exp2f(x: f64): f64 {
1928
+ const
1929
+ c0 = reinterpret<f64>(0x3FE62E4302FCC24A), // 6.931471880289532425e-1
1930
+ c1 = reinterpret<f64>(0x3FCEBFBE07D97B91), // 2.402265108421173406e-1
1931
+ c2 = reinterpret<f64>(0x3FAC6AF6CCFC1A65), // 5.550357105498874537e-2
1932
+ c3 = reinterpret<f64>(0x3F83B29E3CE9AEF6), // 9.618030771171497658e-3
1933
+ c4 = reinterpret<f64>(0x3F55F0896145A89F), // 1.339086685300950937e-3
1934
+ c5 = reinterpret<f64>(0x3F2446C81E384864); // 1.546973499989028719e-4
1935
+
1936
+ if (x < -1022) return 0;
1937
+ if (x >= 1024) return Infinity;
1938
+
1939
+ let n = nearest(x);
1940
+ x -= n;
1941
+ let xx = x * x;
1942
+ let y = 1 + x * (c0 + c1 * x + (c2 + c3 * x) * xx + (c4 + c5 * x) * (xx * xx));
1943
+ return reinterpret<f64>(reinterpret<i64>(y) + (<i64>n << 52));
1944
+ }
1945
+
1946
+ export namespace NativeMathf {
1947
+
1948
+ // @ts-ignore: decorator
1949
+ @lazy
1950
+ export const E = <f32>NativeMath.E;
1951
+
1952
+ // @ts-ignore: decorator
1953
+ @lazy
1954
+ export const LN2 = <f32>NativeMath.LN2;
1955
+
1956
+ // @ts-ignore: decorator
1957
+ @lazy
1958
+ export const LN10 = <f32>NativeMath.LN10;
1959
+
1960
+ // @ts-ignore: decorator
1961
+ @lazy
1962
+ export const LOG2E = <f32>NativeMath.LOG2E;
1963
+
1964
+ // @ts-ignore: decorator
1965
+ @lazy
1966
+ export const LOG10E = <f32>NativeMath.LOG10E;
1967
+
1968
+ // @ts-ignore: decorator
1969
+ @lazy
1970
+ export const PI = <f32>NativeMath.PI;
1971
+
1972
+ // @ts-ignore: decorator
1973
+ @lazy
1974
+ export const SQRT1_2 = <f32>NativeMath.SQRT1_2;
1975
+
1976
+ // @ts-ignore: decorator
1977
+ @lazy
1978
+ export const SQRT2 = <f32>NativeMath.SQRT2;
1979
+
1980
+ // @ts-ignore: decorator
1981
+ @lazy
1982
+ export let sincos_sin: f32 = 0;
1983
+
1984
+ // @ts-ignore: decorator
1985
+ @lazy
1986
+ export let sincos_cos: f32 = 0;
1987
+
1988
+ // @ts-ignore: decorator
1989
+ @inline
1990
+ export function abs(x: f32): f32 {
1991
+ return builtin_abs<f32>(x);
1992
+ }
1993
+
1994
+ export function acos(x: f32): f32 { // see: musl/src/math/acosf.c and SUN COPYRIGHT NOTICE above
1995
+ const
1996
+ pio2_hi = reinterpret<f32>(0x3FC90FDA), // 1.5707962513e+00f
1997
+ pio2_lo = reinterpret<f32>(0x33A22168), // 7.5497894159e-08f
1998
+ Ox1p_120f = reinterpret<f32>(0x03800000); // 0x1p-120f
1999
+
2000
+ let hx = reinterpret<u32>(x);
2001
+ let ix = hx & 0x7FFFFFFF;
2002
+ if (ix >= 0x3F800000) {
2003
+ if (ix == 0x3F800000) {
2004
+ return select<f32>(2 * pio2_hi + Ox1p_120f, 0, <i32>hx < 0);
2005
+ }
2006
+ return 0 / (x - x);
2007
+ }
2008
+ if (ix < 0x3F000000) {
2009
+ if (ix <= 0x32800000) return pio2_hi + Ox1p_120f;
2010
+ return pio2_hi - (x - (pio2_lo - x * Rf(x * x)));
2011
+ }
2012
+ let z: f32, w: f32, s: f32;
2013
+ if (<i32>hx < 0) {
2014
+ // z = (1 + x) * 0.5;
2015
+ z = 0.5 + x * 0.5;
2016
+ s = builtin_sqrt<f32>(z);
2017
+ w = Rf(z) * s - pio2_lo;
2018
+ return 2 * (pio2_hi - (s + w));
2019
+ }
2020
+ // z = (1 - x) * 0.5;
2021
+ z = 0.5 - x * 0.5;
2022
+ s = builtin_sqrt<f32>(z);
2023
+ hx = reinterpret<u32>(s);
2024
+ let df = reinterpret<f32>(hx & 0xFFFFF000);
2025
+ let c = (z - df * df) / (s + df);
2026
+ w = Rf(z) * s + c;
2027
+ return 2 * (df + w);
2028
+ }
2029
+
2030
+ export function acosh(x: f32): f32 { // see: musl/src/math/acoshf.c
2031
+ const s = reinterpret<f32>(0x3F317218); // 0.693147180559945309417232121458176568f
2032
+ let u = reinterpret<u32>(x);
2033
+ let a = u & 0x7FFFFFFF;
2034
+ if (a < 0x3F800000 + (1 << 23)) { // |x| < 2, invalid if x < 1
2035
+ let xm1 = x - 1;
2036
+ return log1p(xm1 + builtin_sqrt(xm1 * (xm1 + 2)));
2037
+ }
2038
+ if (u < 0x3F800000 + (12 << 23)) { // 2 <= x < 0x1p12
2039
+ return log(2 * x - 1 / (x + builtin_sqrt<f32>(x * x - 1)));
2040
+ }
2041
+ // x >= 0x1p12 or x <= -2 or NaN
2042
+ return log(x) + s;
2043
+ }
2044
+
2045
+ export function asin(x: f32): f32 { // see: musl/src/math/asinf.c and SUN COPYRIGHT NOTICE above
2046
+ const
2047
+ pio2 = reinterpret<f32>(0x3FC90FDB), // 1.570796326794896558e+00f
2048
+ Ox1p_120f = reinterpret<f32>(0x03800000); // 0x1p-120f
2049
+
2050
+ let sx = x;
2051
+ let hx = reinterpret<u32>(x) & 0x7FFFFFFF;
2052
+ if (hx >= 0x3F800000) {
2053
+ if (hx == 0x3F800000) return x * pio2 + Ox1p_120f;
2054
+ return 0 / (x - x);
2055
+ }
2056
+ if (hx < 0x3F000000) {
2057
+ if (hx < 0x39800000 && hx >= 0x00800000) return x;
2058
+ return x + x * Rf(x * x);
2059
+ }
2060
+ // let z: f32 = (1 - builtin_abs<f32>(x)) * 0.5;
2061
+ let z: f32 = 0.5 - builtin_abs<f32>(x) * 0.5;
2062
+ let s = builtin_sqrt<f64>(z); // sic
2063
+ x = f32(pio2 - 2 * (s + s * Rf(z)));
2064
+ return builtin_copysign(x, sx);
2065
+ }
2066
+
2067
+ export function asinh(x: f32): f32 { // see: musl/src/math/asinhf.c
2068
+ const c = reinterpret<f32>(0x3F317218); // 0.693147180559945309417232121458176568f
2069
+ let u = reinterpret<u32>(x) & 0x7FFFFFFF;
2070
+ let y = reinterpret<f32>(u);
2071
+ if (u >= 0x3F800000 + (12 << 23)) y = log(y) + c;
2072
+ else if (u >= 0x3F800000 + (1 << 23)) y = log(2 * y + 1 / (builtin_sqrt<f32>(y * y + 1) + y));
2073
+ else if (u >= 0x3F800000 - (12 << 23)) y = log1p(y + y * y / (builtin_sqrt<f32>(y * y + 1) + 1));
2074
+ return builtin_copysign(y, x);
2075
+ }
2076
+
2077
+ export function atan(x: f32): f32 { // see: musl/src/math/atanf.c and SUN COPYRIGHT NOTICE above
2078
+ const
2079
+ atanhi0 = reinterpret<f32>(0x3EED6338), // 4.6364760399e-01f
2080
+ atanhi1 = reinterpret<f32>(0x3F490FDA), // 7.8539812565e-01f
2081
+ atanhi2 = reinterpret<f32>(0x3F7B985E), // 9.8279368877e-01f
2082
+ atanhi3 = reinterpret<f32>(0x3FC90FDA), // 1.5707962513e+00f
2083
+ atanlo0 = reinterpret<f32>(0x31AC3769), // 5.0121582440e-09f
2084
+ atanlo1 = reinterpret<f32>(0x33222168), // 3.7748947079e-08f
2085
+ atanlo2 = reinterpret<f32>(0x33140FB4), // 3.4473217170e-08f
2086
+ atanlo3 = reinterpret<f32>(0x33A22168), // 7.5497894159e-08f
2087
+ aT0 = reinterpret<f32>(0x3EAAAAA9), // 3.3333328366e-01f
2088
+ aT1 = reinterpret<f32>(0xBE4CCA98), // -1.9999158382e-01f
2089
+ aT2 = reinterpret<f32>(0x3E11F50D), // 1.4253635705e-01f
2090
+ aT3 = reinterpret<f32>(0xBDDA1247), // -1.0648017377e-01f
2091
+ aT4 = reinterpret<f32>(0x3D7CAC25), // 6.1687607318e-02f
2092
+ Ox1p_120f = reinterpret<f32>(0x03800000); // 0x1p-120f
2093
+
2094
+ let ix = reinterpret<u32>(x);
2095
+ let sx = x;
2096
+ ix &= 0x7FFFFFFF;
2097
+ let z: f32;
2098
+ if (ix >= 0x4C800000) {
2099
+ if (isNaN(x)) return x;
2100
+ z = atanhi3 + Ox1p_120f;
2101
+ return builtin_copysign(z, sx);
2102
+ }
2103
+ let id: i32;
2104
+ if (ix < 0x3EE00000) {
2105
+ if (ix < 0x39800000) return x;
2106
+ id = -1;
2107
+ } else {
2108
+ x = builtin_abs<f32>(x);
2109
+ if (ix < 0x3F980000) {
2110
+ if (ix < 0x3F300000) {
2111
+ id = 0;
2112
+ x = (2.0 * x - 1.0) / (2.0 + x);
2113
+ } else {
2114
+ id = 1;
2115
+ x = (x - 1.0) / (x + 1.0);
2116
+ }
2117
+ } else {
2118
+ if (ix < 0x401C0000) {
2119
+ id = 2;
2120
+ x = (x - 1.5) / (1.0 + 1.5 * x);
2121
+ } else {
2122
+ id = 3;
2123
+ x = -1.0 / x;
2124
+ }
2125
+ }
2126
+ }
2127
+ z = x * x;
2128
+ let w = z * z;
2129
+ let s1 = z * (aT0 + w * (aT2 + w * aT4));
2130
+ let s2 = w * (aT1 + w * aT3);
2131
+ let s3 = x * (s1 + s2);
2132
+ if (id < 0) return x - s3;
2133
+ switch (id) {
2134
+ case 0: { z = atanhi0 - ((s3 - atanlo0) - x); break; }
2135
+ case 1: { z = atanhi1 - ((s3 - atanlo1) - x); break; }
2136
+ case 2: { z = atanhi2 - ((s3 - atanlo2) - x); break; }
2137
+ case 3: { z = atanhi3 - ((s3 - atanlo3) - x); break; }
2138
+ default: unreachable();
2139
+ }
2140
+ return builtin_copysign(z, sx);
2141
+ }
2142
+
2143
+ export function atanh(x: f32): f32 { // see: musl/src/math/atanhf.c
2144
+ let u = reinterpret<u32>(x);
2145
+ let y = builtin_abs(x);
2146
+ if (u < 0x3F800000 - (1 << 23)) {
2147
+ if (u >= 0x3F800000 - (32 << 23)) y = 0.5 * log1p(2 * y * (1.0 + y / (1 - y)));
2148
+ } else y = 0.5 * log1p(2 * (y / (1 - y)));
2149
+ return builtin_copysign(y, x);
2150
+ }
2151
+
2152
+ export function atan2(y: f32, x: f32): f32 { // see: musl/src/math/atan2f.c and SUN COPYRIGHT NOTICE above
2153
+ const
2154
+ pi = reinterpret<f32>(0x40490FDB), // 3.1415927410e+00f
2155
+ pi_lo = reinterpret<f32>(0xB3BBBD2E); // -8.7422776573e-08f
2156
+
2157
+ if (isNaN(x) || isNaN(y)) return x + y;
2158
+ let ix = reinterpret<u32>(x);
2159
+ let iy = reinterpret<u32>(y);
2160
+ if (ix == 0x3F800000) return atan(y);
2161
+ let m = u32(((iy >> 31) & 1) | ((ix >> 30) & 2));
2162
+ ix &= 0x7FFFFFFF;
2163
+ iy &= 0x7FFFFFFF;
2164
+ if (iy == 0) {
2165
+ switch (m) {
2166
+ case 0:
2167
+ case 1: return y;
2168
+ case 2: return pi;
2169
+ case 3: return -pi;
2170
+ }
2171
+ }
2172
+ if (ix == 0) return m & 1 ? -pi / 2 : pi / 2;
2173
+ if (ix == 0x7F800000) {
2174
+ if (iy == 0x7F800000) {
2175
+ let t: f32 = m & 2 ? 3 * pi / 4 : pi / 4;
2176
+ return m & 1 ? -t : t;
2177
+ } else {
2178
+ let t: f32 = m & 2 ? pi : 0.0;
2179
+ return m & 1 ? -t : t;
2180
+ }
2181
+ }
2182
+ if (ix + (26 << 23) < iy || iy == 0x7F800000) return m & 1 ? -pi / 2 : pi / 2;
2183
+ let z: f32;
2184
+ if ((m & 2) && iy + (26 << 23) < ix) z = 0.0;
2185
+ else z = atan(builtin_abs<f32>(y / x));
2186
+ switch (m) {
2187
+ case 0: return z;
2188
+ case 1: return -z;
2189
+ case 2: return pi - (z - pi_lo);
2190
+ case 3: return (z - pi_lo) - pi;
2191
+ }
2192
+ unreachable();
2193
+ return 0;
2194
+ }
2195
+
2196
+ export function cbrt(x: f32): f32 { // see: musl/src/math/cbrtf.c and SUN COPYRIGHT NOTICE above
2197
+ const
2198
+ B1 = <u32>709958130,
2199
+ B2 = <u32>642849266,
2200
+ Ox1p24f = reinterpret<f32>(0x4B800000);
2201
+
2202
+ let u = reinterpret<u32>(x);
2203
+ let hx = u & 0x7FFFFFFF;
2204
+ if (hx >= 0x7F800000) return x + x;
2205
+ if (hx < 0x00800000) {
2206
+ if (hx == 0) return x;
2207
+ u = reinterpret<u32>(x * Ox1p24f);
2208
+ hx = u & 0x7FFFFFFF;
2209
+ hx = hx / 3 + B2;
2210
+ } else {
2211
+ hx = hx / 3 + B1;
2212
+ }
2213
+ u &= 0x80000000;
2214
+ u |= hx;
2215
+ let t = <f64>reinterpret<f32>(u);
2216
+ let r = t * t * t;
2217
+ t = t * (<f64>x + x + r) / (x + r + r);
2218
+ r = t * t * t;
2219
+ t = t * (<f64>x + x + r) / (x + r + r);
2220
+ return <f32>t;
2221
+ }
2222
+
2223
+ // @ts-ignore: decorator
2224
+ @inline
2225
+ export function ceil(x: f32): f32 {
2226
+ return builtin_ceil<f32>(x);
2227
+ }
2228
+
2229
+ export function clz32(x: f32): f32 {
2230
+ if (!isFinite(x)) return 32;
2231
+ return <f32>builtin_clz(dtoi32(x));
2232
+ }
2233
+
2234
+ export function cos(x: f32): f32 { // see: musl/src/math/cosf.c
2235
+ const
2236
+ c1pio2 = reinterpret<f64>(0x3FF921FB54442D18), // M_PI_2 * 1
2237
+ c2pio2 = reinterpret<f64>(0x400921FB54442D18), // M_PI_2 * 2
2238
+ c3pio2 = reinterpret<f64>(0x4012D97C7F3321D2), // M_PI_2 * 3
2239
+ c4pio2 = reinterpret<f64>(0x401921FB54442D18); // M_PI_2 * 4
2240
+
2241
+ let ux = reinterpret<u32>(x);
2242
+ let sign = ux >> 31;
2243
+ ux &= 0x7FFFFFFF;
2244
+
2245
+ if (ux <= 0x3F490FDA) { // |x| ~<= π/4
2246
+ if (ux < 0x39800000) { // |x| < 2**-12
2247
+ // raise inexact if x != 0
2248
+ return 1;
2249
+ }
2250
+ return cos_kernf(x);
2251
+ }
2252
+
2253
+ if (ASC_SHRINK_LEVEL < 1) {
2254
+ if (ux <= 0x407B53D1) { // |x| ~<= 5π/4
2255
+ if (ux > 0x4016CBE3) { // |x| ~> 3π/4
2256
+ return -cos_kernf(sign ? x + c2pio2 : x - c2pio2);
2257
+ } else {
2258
+ return sign ? sin_kernf(x + c1pio2) : sin_kernf(c1pio2 - x);
2259
+ }
2260
+ }
2261
+ if (ux <= 0x40E231D5) { // |x| ~<= 9π/4
2262
+ if (ux > 0x40AFEDDF) { // |x| ~> 7π/4
2263
+ return cos_kernf(sign ? x + c4pio2 : x - c4pio2);
2264
+ } else {
2265
+ return sign ? sin_kernf(-x - c3pio2) : sin_kernf(x - c3pio2);
2266
+ }
2267
+ }
2268
+ }
2269
+
2270
+ // cos(Inf or NaN) is NaN
2271
+ if (ux >= 0x7F800000) return x - x;
2272
+
2273
+ // general argument reduction needed
2274
+ let n = rempio2f(x, ux, sign);
2275
+ let y = rempio2f_y;
2276
+
2277
+ let t = n & 1 ? sin_kernf(y) : cos_kernf(y);
2278
+ return (n + 1) & 2 ? -t : t;
2279
+ }
2280
+
2281
+ export function cosh(x: f32): f32 { // see: musl/src/math/coshf.c
2282
+ let u = reinterpret<u32>(x);
2283
+ u &= 0x7FFFFFFF;
2284
+ x = reinterpret<f32>(u);
2285
+ if (u < 0x3F317217) {
2286
+ if (u < 0x3F800000 - (12 << 23)) return 1;
2287
+ let t = expm1(x);
2288
+ // return 1 + t * t / (2 * (1 + t));
2289
+ return 1 + t * t / (2 + 2 * t);
2290
+ }
2291
+ if (u < 0x42B17217) {
2292
+ let t = exp(x);
2293
+ // return 0.5 * (t + 1 / t);
2294
+ return 0.5 * t + 0.5 / t;
2295
+ }
2296
+ return expo2f(x, 1);
2297
+ }
2298
+
2299
+ // @ts-ignore: decorator
2300
+ @inline
2301
+ export function floor(x: f32): f32 {
2302
+ return builtin_floor<f32>(x);
2303
+ }
2304
+
2305
+ export function exp(x: f32): f32 { // see: musl/src/math/expf.c and SUN COPYRIGHT NOTICE above
2306
+ if (ASC_SHRINK_LEVEL < 1) {
2307
+ return expf_lut(x);
2308
+ } else {
2309
+ const
2310
+ ln2hi = reinterpret<f32>(0x3F317200), // 6.9314575195e-1f
2311
+ ln2lo = reinterpret<f32>(0x35BFBE8E), // 1.4286067653e-6f
2312
+ invln2 = reinterpret<f32>(0x3FB8AA3B), // 1.4426950216e+0f
2313
+ P1 = reinterpret<f32>(0x3E2AAA8F), // 1.6666625440e-1f
2314
+ P2 = reinterpret<f32>(0xBB355215), // -2.7667332906e-3f
2315
+ Ox1p127f = reinterpret<f32>(0x7F000000); // 0x1p+127f
2316
+
2317
+ let hx = reinterpret<u32>(x);
2318
+ let sign = hx >> 31;
2319
+ hx &= 0x7FFFFFFF;
2320
+ if (hx >= 0x42AEAC50) {
2321
+ if (hx > 0x7F800000) return x; // NaN
2322
+ if (hx >= 0x42B17218) {
2323
+ if (!sign) return x * Ox1p127f;
2324
+ else if (hx >= 0x42CFF1B5) return 0;
2325
+ }
2326
+ }
2327
+ let hi: f32, lo: f32;
2328
+ let k: i32;
2329
+ if (hx > 0x3EB17218) {
2330
+ if (hx > 0x3F851592) {
2331
+ k = i32(invln2 * x + builtin_copysign<f32>(0.5, x));
2332
+ } else {
2333
+ k = 1 - (sign << 1);
2334
+ }
2335
+ hi = x - <f32>k * ln2hi;
2336
+ lo = <f32>k * ln2lo;
2337
+ x = hi - lo;
2338
+ } else if (hx > 0x39000000) {
2339
+ k = 0;
2340
+ hi = x;
2341
+ lo = 0;
2342
+ } else {
2343
+ return 1 + x;
2344
+ }
2345
+ let xx = x * x;
2346
+ let c = x - xx * (P1 + xx * P2);
2347
+ let y: f32 = 1 + (x * c / (2 - c) - lo + hi);
2348
+ return k == 0 ? y : scalbn(y, k);
2349
+ }
2350
+ }
2351
+
2352
+ export function exp2(x: f32): f32 {
2353
+ return exp2f_lut(x);
2354
+ }
2355
+
2356
+ export function expm1(x: f32): f32 { // see: musl/src/math/expm1f.c and SUN COPYRIGHT NOTICE above
2357
+ const
2358
+ ln2_hi = reinterpret<f32>(0x3F317180), // 6.9313812256e-01f
2359
+ ln2_lo = reinterpret<f32>(0x3717F7D1), // 9.0580006145e-06f
2360
+ invln2 = reinterpret<f32>(0x3FB8AA3B), // 1.4426950216e+00f
2361
+ Q1 = reinterpret<f32>(0xBD088868), // -3.3333212137e-02f
2362
+ Q2 = reinterpret<f32>(0x3ACF3010), // 1.5807170421e-03f
2363
+ Ox1p127f = reinterpret<f32>(0x7F000000); // 0x1p+127f
2364
+
2365
+ let u = reinterpret<u32>(x);
2366
+ let hx = u & 0x7FFFFFFF;
2367
+ let sign = u >> 31;
2368
+ if (hx >= 0x4195B844) {
2369
+ if (hx > 0x7F800000) return x;
2370
+ if (sign) return -1;
2371
+ if (hx > 0x42B17217) { // x > log(FLT_MAX)
2372
+ x *= Ox1p127f;
2373
+ return x;
2374
+ }
2375
+ }
2376
+ let c: f32 = 0.0, t: f32, k: i32;
2377
+ if (hx > 0x3EB17218) {
2378
+ k = select<i32>(
2379
+ 1 - (sign << 1),
2380
+ i32(invln2 * x + builtin_copysign<f32>(0.5, x)),
2381
+ hx < 0x3F851592
2382
+ );
2383
+ t = <f32>k;
2384
+ let hi = x - t * ln2_hi;
2385
+ let lo = t * ln2_lo;
2386
+ x = hi - lo;
2387
+ c = (hi - x) - lo;
2388
+ } else if (hx < 0x33000000) {
2389
+ return x;
2390
+ } else k = 0;
2391
+ let hfx: f32 = 0.5 * x;
2392
+ let hxs: f32 = x * hfx;
2393
+ let r1: f32 = 1.0 + hxs * (Q1 + hxs * Q2);
2394
+ t = 3.0 - r1 * hfx;
2395
+ let e = hxs * ((r1 - t) / (6.0 - x * t));
2396
+ if (k == 0) return x - (x * e - hxs);
2397
+ e = x * (e - c) - c;
2398
+ e -= hxs;
2399
+ if (k == -1) return 0.5 * (x - e) - 0.5;
2400
+ if (k == 1) {
2401
+ if (x < -0.25) return -2.0 * (e - (x + 0.5));
2402
+ return 1.0 + 2.0 * (x - e);
2403
+ }
2404
+ u = (0x7F + k) << 23;
2405
+ let twopk = reinterpret<f32>(u);
2406
+ let y: f32;
2407
+ if (k < 0 || k > 56) {
2408
+ y = x - e + 1.0;
2409
+ if (k == 128) y = y * 2.0 * Ox1p127f;
2410
+ else y = y * twopk;
2411
+ return y - 1.0;
2412
+ }
2413
+ u = (0x7F - k) << 23;
2414
+ y = reinterpret<f32>(u);
2415
+ if (k < 20) y = (1 - y) - e;
2416
+ else y = 1 - (e + y);
2417
+ return (x + y) * twopk;
2418
+ }
2419
+
2420
+ // @ts-ignore: decorator
2421
+ @inline
2422
+ export function fround(x: f32): f32 {
2423
+ return x;
2424
+ }
2425
+
2426
+ export function hypot(x: f32, y: f32): f32 { // see: musl/src/math/hypotf.c
2427
+ const
2428
+ Ox1p90f = reinterpret<f32>(0x6C800000),
2429
+ Ox1p_90f = reinterpret<f32>(0x12800000);
2430
+
2431
+ let ux = reinterpret<u32>(x);
2432
+ let uy = reinterpret<u32>(y);
2433
+ ux &= 0x7FFFFFFF;
2434
+ uy &= 0x7FFFFFFF;
2435
+ if (ux < uy) {
2436
+ let ut = ux;
2437
+ ux = uy;
2438
+ uy = ut;
2439
+ }
2440
+ x = reinterpret<f32>(ux);
2441
+ y = reinterpret<f32>(uy);
2442
+ if (uy == 0xFF << 23) return y;
2443
+ if (ux >= 0xFF << 23 || uy == 0 || ux - uy >= 25 << 23) return x + y;
2444
+ let z: f32 = 1;
2445
+ if (ux >= (0x7F + 60) << 23) {
2446
+ z = Ox1p90f;
2447
+ x *= Ox1p_90f;
2448
+ y *= Ox1p_90f;
2449
+ } else if (uy < (0x7F - 60) << 23) {
2450
+ z = Ox1p_90f;
2451
+ x *= Ox1p90f;
2452
+ y *= Ox1p90f;
2453
+ }
2454
+ return z * builtin_sqrt<f32>(f32(<f64>x * x + <f64>y * y));
2455
+ }
2456
+
2457
+ // @ts-ignore: decorator
2458
+ @inline
2459
+ export function imul(x: f32, y: f32): f32 {
2460
+ /*
2461
+ * Wasm (MVP) and JS have different approaches for double->int conversions.
2462
+ *
2463
+ * For emulate JS conversion behavior and avoid trapping from wasm we should modulate by MAX_INT
2464
+ * our float-point arguments before actual convertion to integers.
2465
+ */
2466
+ if (!isFinite(x + y)) return 0;
2467
+ return <f32>(dtoi32(x) * dtoi32(y));
2468
+ }
2469
+
2470
+ export function log(x: f32): f32 { // see: musl/src/math/logf.c and SUN COPYRIGHT NOTICE above
2471
+ if (ASC_SHRINK_LEVEL < 1) {
2472
+ return logf_lut(x);
2473
+ } else {
2474
+ const
2475
+ ln2_hi = reinterpret<f32>(0x3F317180), // 6.9313812256e-01f
2476
+ ln2_lo = reinterpret<f32>(0x3717F7D1), // 9.0580006145e-06f
2477
+ Lg1 = reinterpret<f32>(0x3F2AAAAA), // 0xaaaaaa.0p-24f
2478
+ Lg2 = reinterpret<f32>(0x3ECCCE13), // 0xccce13.0p-25f
2479
+ Lg3 = reinterpret<f32>(0x3E91E9EE), // 0x91e9ee.0p-25f
2480
+ Lg4 = reinterpret<f32>(0x3E789E26), // 0xf89e26.0p-26f
2481
+ Ox1p25f = reinterpret<f32>(0x4C000000);
2482
+
2483
+ let u = reinterpret<u32>(x);
2484
+ let k = 0;
2485
+ let sign = u >> 31;
2486
+ if (sign || u < 0x00800000) {
2487
+ if (u << 1 == 0) return -1 / (x * x);
2488
+ if (sign) return (x - x) / 0;
2489
+ k -= 25;
2490
+ x *= Ox1p25f;
2491
+ u = reinterpret<u32>(x);
2492
+ } else if (u >= 0x7F800000) {
2493
+ return x;
2494
+ } else if (u == 0x3F800000) {
2495
+ return 0;
2496
+ }
2497
+ u += 0x3F800000 - 0x3F3504F3;
2498
+ k += i32(u >> 23) - 0x7F;
2499
+ u = (u & 0x007FFFFF) + 0x3F3504F3;
2500
+ x = reinterpret<f32>(u);
2501
+ let f = x - 1.0;
2502
+ let s = f / (2.0 + f);
2503
+ let z = s * s;
2504
+ let w = z * z;
2505
+ let t1 = w * (Lg2 + w * Lg4);
2506
+ let t2 = z * (Lg1 + w * Lg3);
2507
+ let r = t2 + t1;
2508
+ let hfsq = <f32>0.5 * f * f;
2509
+ let dk = <f32>k;
2510
+ return s * (hfsq + r) + dk * ln2_lo - hfsq + f + dk * ln2_hi;
2511
+ }
2512
+ }
2513
+
2514
+ export function log10(x: f32): f32 { // see: musl/src/math/log10f.c and SUN COPYRIGHT NOTICE above
2515
+ const
2516
+ ivln10hi = reinterpret<f32>(0x3EDE6000), // 4.3432617188e-01f
2517
+ ivln10lo = reinterpret<f32>(0xB804EAD9), // -3.1689971365e-05f
2518
+ log10_2hi = reinterpret<f32>(0x3E9A2080), // 3.0102920532e-01f
2519
+ log10_2lo = reinterpret<f32>(0x355427DB), // 7.9034151668e-07f
2520
+ Lg1 = reinterpret<f32>(0x3F2AAAAA), // 0xaaaaaa.0p-24f, 0.66666662693f
2521
+ Lg2 = reinterpret<f32>(0x3ECCCE13), // 0xccce13.0p-25f, 0.40000972152f
2522
+ Lg3 = reinterpret<f32>(0x3E91E9EE), // 0x91e9ee.0p-25f, 0.28498786688f
2523
+ Lg4 = reinterpret<f32>(0x3E789E26), // 0xf89e26.0p-26f, 0.24279078841f
2524
+ Ox1p25f = reinterpret<f32>(0x4C000000); // 0x1p25f
2525
+
2526
+ let ux = reinterpret<u32>(x);
2527
+ let k = 0;
2528
+ let sign = ux >> 31;
2529
+ if (sign || ux < 0x00800000) {
2530
+ if (ux << 1 == 0) return -1 / (x * x);
2531
+ if (sign) return (x - x) / 0.0;
2532
+ k -= 25;
2533
+ x *= Ox1p25f;
2534
+ ux = reinterpret<u32>(x);
2535
+ } else if (ux >= 0x7F800000) {
2536
+ return x;
2537
+ } else if (ux == 0x3F800000) {
2538
+ return 0;
2539
+ }
2540
+ ux += 0x3F800000 - 0x3F3504F3;
2541
+ k += i32(ux >> 23) - 0x7F;
2542
+ ux = (ux & 0x007FFFFF) + 0x3F3504F3;
2543
+ x = reinterpret<f32>(ux);
2544
+ let f = x - 1.0;
2545
+ let s = f / (2.0 + f);
2546
+ let z = s * s;
2547
+ let w = z * z;
2548
+ let t1 = w * (Lg2 + w * Lg4);
2549
+ let t2 = z * (Lg1 + w * Lg3);
2550
+ let r = t2 + t1;
2551
+ let hfsq: f32 = 0.5 * f * f;
2552
+ let hi = f - hfsq;
2553
+ ux = reinterpret<u32>(hi);
2554
+ ux &= 0xFFFFF000;
2555
+ hi = reinterpret<f32>(ux);
2556
+ let lo = f - hi - hfsq + s * (hfsq + r);
2557
+ let dk = <f32>k;
2558
+ return dk * log10_2lo + (lo + hi) * ivln10lo + lo * ivln10hi + hi * ivln10hi + dk * log10_2hi;
2559
+ }
2560
+
2561
+ export function log1p(x: f32): f32 { // see: musl/src/math/log1pf.c and SUN COPYRIGHT NOTICE above
2562
+ const
2563
+ ln2_hi = reinterpret<f32>(0x3F317180), // 6.9313812256e-01
2564
+ ln2_lo = reinterpret<f32>(0x3717F7D1), // 9.0580006145e-06
2565
+ Lg1 = reinterpret<f32>(0x3F2AAAAA), // 0xaaaaaa.0p-24f, 0.66666662693f
2566
+ Lg2 = reinterpret<f32>(0x3ECCCE13), // 0xccce13.0p-25f, 0.40000972152f
2567
+ Lg3 = reinterpret<f32>(0x3E91E9EE), // 0x91e9ee.0p-25f, 0.28498786688f
2568
+ Lg4 = reinterpret<f32>(0x3E789E26); // 0xf89e26.0p-26f, 0.24279078841f
2569
+
2570
+ let ix = reinterpret<u32>(x);
2571
+ let c: f32 = 0;
2572
+ let f: f32 = 0;
2573
+ let k = 1;
2574
+ if (ix < 0x3ED413D0 || bool(ix >> 31)) {
2575
+ if (ix >= 0xBF800000) {
2576
+ if (x == -1) return x / 0.0;
2577
+ return (x - x) / 0.0;
2578
+ }
2579
+ if (ix << 1 < 0x33800000 << 1) return x;
2580
+ if (ix <= 0xBE95F619) {
2581
+ k = 0;
2582
+ c = 0;
2583
+ f = x;
2584
+ }
2585
+ } else if (ix >= 0x7F800000) return x;
2586
+ if (k) {
2587
+ let uf: f32 = 1 + x;
2588
+ let iu = reinterpret<u32>(uf);
2589
+ iu += 0x3F800000 - 0x3F3504F3;
2590
+ k = i32(iu >> 23) - 0x7F;
2591
+ if (k < 25) {
2592
+ c = k >= 2 ? 1 - (uf - x) : x - (uf - 1);
2593
+ c /= uf;
2594
+ } else c = 0;
2595
+ iu = (iu & 0x007FFFFF) + 0x3F3504F3;
2596
+ f = reinterpret<f32>(iu) - 1;
2597
+ }
2598
+ let s = f / (2.0 + f);
2599
+ let z = s * s;
2600
+ let w = z * z;
2601
+ let t1 = w * (Lg2 + w * Lg4);
2602
+ let t2 = z * (Lg1 + w * Lg3);
2603
+ let r = t2 + t1;
2604
+ let hfsq: f32 = 0.5 * f * f;
2605
+ let dk = <f32>k;
2606
+ return s * (hfsq + r) + (dk * ln2_lo + c) - hfsq + f + dk * ln2_hi;
2607
+ }
2608
+
2609
+ export function log2(x: f32): f32 { // see: musl/src/math/log2f.c and SUN COPYRIGHT NOTICE above
2610
+ if (ASC_SHRINK_LEVEL < 1) {
2611
+ return log2f_lut(x);
2612
+ } else {
2613
+ const
2614
+ ivln2hi = reinterpret<f32>(0x3FB8B000), // 1.4428710938e+00f
2615
+ ivln2lo = reinterpret<f32>(0xB9389AD4), // -1.7605285393e-04
2616
+ Lg1 = reinterpret<f32>(0x3F2AAAAA), // 0xaaaaaa.0p-24f, 0.66666662693f
2617
+ Lg2 = reinterpret<f32>(0x3ECCCE13), // 0xccce13.0p-25f, 0.40000972152f
2618
+ Lg3 = reinterpret<f32>(0x3E91E9EE), // 0x91e9ee.0p-25f, 0.28498786688f
2619
+ Lg4 = reinterpret<f32>(0x3E789E26), // 0xf89e26.0p-26f, 0.24279078841f
2620
+ Ox1p25f = reinterpret<f32>(0x4C000000); // 0x1p25f
2621
+
2622
+ let ux = reinterpret<u32>(x);
2623
+ let k = 0;
2624
+ let sign = ux >> 31;
2625
+ if (sign || ux < 0x00800000) {
2626
+ if (ux << 1 == 0) return -1 / (x * x);
2627
+ if (sign) return (x - x) / 0.0;
2628
+ k -= 25;
2629
+ x *= Ox1p25f;
2630
+ ux = reinterpret<u32>(x);
2631
+ } else if (ux >= 0x7F800000) {
2632
+ return x;
2633
+ } else if (ux == 0x3F800000) {
2634
+ return 0;
2635
+ }
2636
+ ux += 0x3F800000 - 0x3F3504F3;
2637
+ k += i32(ux >> 23) - 0x7F;
2638
+ ux = (ux & 0x007FFFFF) + 0x3F3504F3;
2639
+ x = reinterpret<f32>(ux);
2640
+ let f = x - 1.0;
2641
+ let s = f / (2.0 + f);
2642
+ let z = s * s;
2643
+ let w = z * z;
2644
+ let t1 = w * (Lg2 + w * Lg4);
2645
+ let t2 = z * (Lg1 + w * Lg3);
2646
+ let r = t2 + t1;
2647
+ let hfsq: f32 = 0.5 * f * f;
2648
+ let hi = f - hfsq;
2649
+ let u = reinterpret<u32>(hi);
2650
+ u &= 0xFFFFF000;
2651
+ hi = reinterpret<f32>(u);
2652
+ let lo: f32 = f - hi - hfsq + s * (hfsq + r);
2653
+ let dk = <f32>k;
2654
+ return (lo + hi) * ivln2lo + lo * ivln2hi + hi * ivln2hi + dk;
2655
+ }
2656
+ }
2657
+
2658
+ // @ts-ignore: decorator
2659
+ @inline
2660
+ export function max(value1: f32, value2: f32): f32 {
2661
+ return builtin_max<f32>(value1, value2);
2662
+ }
2663
+
2664
+ // @ts-ignore: decorator
2665
+ @inline
2666
+ export function min(value1: f32, value2: f32): f32 {
2667
+ return builtin_min<f32>(value1, value2);
2668
+ }
2669
+
2670
+ export function pow(x: f32, y: f32): f32 {
2671
+ // TODO: remove this fast pathes after introduced own mid-end IR with "stdlib call simplify" transforms
2672
+ if (builtin_abs<f32>(y) <= 2) {
2673
+ if (y == 2.0) return x * x;
2674
+ if (y == 0.5) {
2675
+ return select<f32>(
2676
+ builtin_abs<f32>(builtin_sqrt<f32>(x)),
2677
+ Infinity,
2678
+ x != -Infinity
2679
+ );
2680
+ }
2681
+ if (y == -1.0) return 1 / x;
2682
+ if (y == 1.0) return x;
2683
+ if (y == 0.0) return 1.0;
2684
+ }
2685
+ if (ASC_SHRINK_LEVEL < 1) {
2686
+ // see: musl/src/math/powf.c
2687
+ return powf_lut(x, y);
2688
+ } else {
2689
+ // based on: jdh8/metallic/src/math/float/powf.c
2690
+ if (y == 0) return 1;
2691
+ // @ts-ignore: cast
2692
+ if (isNaN(x) | isNaN(y)) {
2693
+ return NaN;
2694
+ }
2695
+ let sign: u32 = 0;
2696
+ let uy = reinterpret<u32>(y);
2697
+ let ux = reinterpret<u32>(x);
2698
+ let sx = ux >> 31;
2699
+ ux &= 0x7FFFFFFF;
2700
+ if (sx && nearest(y) == y) {
2701
+ x = -x;
2702
+ sx = 0;
2703
+ sign = u32(nearest(y * 0.5) != y * 0.5) << 31;
2704
+ }
2705
+ let m: u32;
2706
+ if (ux == 0x3F800000) { // x == 1
2707
+ m = sx | u32((uy & 0x7FFFFFFF) == 0x7F800000) ? 0x7FC00000 : 0x3F800000;
2708
+ } else if (ux == 0) {
2709
+ m = <i32>uy < 0 ? 0x7F800000 : 0;
2710
+ } else if (ux == 0x7F800000) {
2711
+ m = <i32>uy < 0 ? 0 : 0x7F800000;
2712
+ } else if (sx) {
2713
+ m = 0x7FC00000;
2714
+ } else {
2715
+ m = reinterpret<u32>(<f32>exp2f(<f64>y * log2f(x)));
2716
+ }
2717
+ return reinterpret<f32>(m | sign);
2718
+ }
2719
+ }
2720
+
2721
+ // @ts-ignore: decorator
2722
+ @inline
2723
+ export function seedRandom(value: i64): void {
2724
+ NativeMath.seedRandom(value);
2725
+ }
2726
+
2727
+ // Using xoroshiro64starstar from http://xoshiro.di.unimi.it/xoroshiro64starstar.c
2728
+ export function random(): f32 {
2729
+ if (!random_seeded) seedRandom(reinterpret<i64>(seed()));
2730
+
2731
+ let s0 = random_state0_32;
2732
+ let s1 = random_state1_32;
2733
+ let r = rotl<u32>(s0 * 0x9E3779BB, 5) * 5;
2734
+
2735
+ s1 ^= s0;
2736
+ random_state0_32 = rotl<u32>(s0, 26) ^ s1 ^ (s1 << 9);
2737
+ random_state1_32 = rotl<u32>(s1, 13);
2738
+
2739
+ return reinterpret<f32>((r >> 9) | (127 << 23)) - 1.0;
2740
+ }
2741
+
2742
+ export function round(x: f32): f32 {
2743
+ if (ASC_SHRINK_LEVEL > 0) {
2744
+ return builtin_ceil<f32>(x) - f32(builtin_ceil<f32>(x) - 0.5 > x);
2745
+ } else {
2746
+ let roundUp = builtin_ceil<f32>(x);
2747
+ return select<f32>(roundUp, roundUp - 1.0, roundUp - 0.5 <= x);
2748
+ }
2749
+ }
2750
+
2751
+ export function sign(x: f32): f32 {
2752
+ if (ASC_SHRINK_LEVEL > 0) {
2753
+ return select<f32>(builtin_copysign<f32>(1, x), x, builtin_abs(x) > 0);
2754
+ } else {
2755
+ return select<f32>(1, select<f32>(-1, x, x < 0), x > 0);
2756
+ }
2757
+ }
2758
+
2759
+ // @ts-ignore: decorator
2760
+ @inline
2761
+ export function signbit(x: f32): bool {
2762
+ return <bool>(reinterpret<u32>(x) >>> 31);
2763
+ }
2764
+
2765
+ export function sin(x: f32): f32 { // see: musl/src/math/sinf.c
2766
+ const
2767
+ s1pio2 = reinterpret<f64>(0x3FF921FB54442D18), // M_PI_2 * 1
2768
+ s2pio2 = reinterpret<f64>(0x400921FB54442D18), // M_PI_2 * 2
2769
+ s3pio2 = reinterpret<f64>(0x4012D97C7F3321D2), // M_PI_2 * 3
2770
+ s4pio2 = reinterpret<f64>(0x401921FB54442D18); // M_PI_2 * 4
2771
+
2772
+ let ux = reinterpret<u32>(x);
2773
+ let sign = ux >> 31;
2774
+ ux &= 0x7FFFFFFF;
2775
+
2776
+ if (ux <= 0x3F490FDA) { // |x| ~<= π/4
2777
+ if (ux < 0x39800000) { // |x| < 2**-12
2778
+ return x;
2779
+ }
2780
+ return sin_kernf(x);
2781
+ }
2782
+
2783
+ if (ASC_SHRINK_LEVEL < 1) {
2784
+ if (ux <= 0x407B53D1) { // |x| ~<= 5π/4
2785
+ if (ux <= 0x4016CBE3) { // |x| ~<= 3π/4
2786
+ return sign ? -cos_kernf(x + s1pio2) : cos_kernf(x - s1pio2);
2787
+ }
2788
+ return sin_kernf(-(sign ? x + s2pio2 : x - s2pio2));
2789
+ }
2790
+
2791
+ if (ux <= 0x40E231D5) { // |x| ~<= 9π/4
2792
+ if (ux <= 0x40AFEDDF) { // |x| ~<= 7π/4
2793
+ return sign ? cos_kernf(x + s3pio2) : -cos_kernf(x - s3pio2);
2794
+ }
2795
+ return sin_kernf(sign ? x + s4pio2 : x - s4pio2);
2796
+ }
2797
+ }
2798
+
2799
+ // sin(Inf or NaN) is NaN
2800
+ if (ux >= 0x7F800000) return x - x;
2801
+
2802
+ let n = rempio2f(x, ux, sign);
2803
+ let y = rempio2f_y;
2804
+
2805
+ let t = n & 1 ? cos_kernf(y) : sin_kernf(y);
2806
+ return n & 2 ? -t : t;
2807
+ }
2808
+
2809
+ export function sinh(x: f32): f32 { // see: musl/src/math/sinhf.c
2810
+ let u = reinterpret<u32>(x) & 0x7FFFFFFF;
2811
+ let a = reinterpret<f32>(u);
2812
+ let h = builtin_copysign<f32>(0.5, x);
2813
+ if (u < 0x42B17217) {
2814
+ let t = expm1(a);
2815
+ if (u < 0x3F800000) {
2816
+ if (u < 0x3F800000 - (12 << 23)) return x;
2817
+ return h * (2 * t - t * t / (t + 1));
2818
+ }
2819
+ return h * (t + t / (t + 1));
2820
+ }
2821
+ return expo2f(a, 2 * h);
2822
+ }
2823
+
2824
+ // @ts-ignore: decorator
2825
+ @inline
2826
+ export function sqrt(x: f32): f32 {
2827
+ return builtin_sqrt<f32>(x);
2828
+ }
2829
+
2830
+ export function tan(x: f32): f32 { // see: musl/src/math/tanf.c
2831
+ const
2832
+ t1pio2 = reinterpret<f64>(0x3FF921FB54442D18), // 1 * M_PI_2
2833
+ t2pio2 = reinterpret<f64>(0x400921FB54442D18), // 2 * M_PI_2
2834
+ t3pio2 = reinterpret<f64>(0x4012D97C7F3321D2), // 3 * M_PI_2
2835
+ t4pio2 = reinterpret<f64>(0x401921FB54442D18); // 4 * M_PI_2
2836
+
2837
+ let ux = reinterpret<u32>(x);
2838
+ let sign = ux >> 31;
2839
+ ux &= 0x7FFFFFFF;
2840
+
2841
+ if (ux <= 0x3F490FDA) { // |x| ~<= π/4
2842
+ if (ux < 0x39800000) { // |x| < 2**-12
2843
+ return x;
2844
+ }
2845
+ return tan_kernf(x, 0);
2846
+ }
2847
+
2848
+ if (ASC_SHRINK_LEVEL < 1) {
2849
+ if (ux <= 0x407B53D1) { // |x| ~<= 5π/4
2850
+ if (ux <= 0x4016CBE3) { // |x| ~<= 3π/4
2851
+ return tan_kernf((sign ? x + t1pio2 : x - t1pio2), 1);
2852
+ } else {
2853
+ return tan_kernf((sign ? x + t2pio2 : x - t2pio2), 0);
2854
+ }
2855
+ }
2856
+ if (ux <= 0x40E231D5) { // |x| ~<= 9π/4
2857
+ if (ux <= 0x40AFEDDF) { // |x| ~<= 7π/4
2858
+ return tan_kernf((sign ? x + t3pio2 : x - t3pio2), 1);
2859
+ } else {
2860
+ return tan_kernf((sign ? x + t4pio2 : x - t4pio2), 0);
2861
+ }
2862
+ }
2863
+ }
2864
+
2865
+ // tan(Inf or NaN) is NaN
2866
+ if (ux >= 0x7F800000) return x - x;
2867
+
2868
+ // argument reduction
2869
+ let n = rempio2f(x, ux, sign);
2870
+ let y = rempio2f_y;
2871
+ return tan_kernf(y, n & 1);
2872
+ }
2873
+
2874
+ export function tanh(x: f32): f32 { // see: musl/src/math/tanhf.c
2875
+ let u = reinterpret<u32>(x);
2876
+ u &= 0x7FFFFFFF;
2877
+ let y = reinterpret<f32>(u);
2878
+ let t: f32;
2879
+ if (u > 0x3F0C9F54) {
2880
+ if (u > 0x41200000) t = 1 + 0 / y;
2881
+ else {
2882
+ t = expm1(2 * y);
2883
+ t = 1 - 2 / (t + 2);
2884
+ }
2885
+ } else if (u > 0x3E82C578) {
2886
+ t = expm1(2 * y);
2887
+ t = t / (t + 2);
2888
+ } else if (u >= 0x00800000) {
2889
+ t = expm1(-2 * y);
2890
+ t = -t / (t + 2);
2891
+ } else t = y;
2892
+ return builtin_copysign<f32>(t, x);
2893
+ }
2894
+
2895
+ // @ts-ignore: decorator
2896
+ @inline
2897
+ export function trunc(x: f32): f32 {
2898
+ return builtin_trunc<f32>(x);
2899
+ }
2900
+
2901
+ export function scalbn(x: f32, n: i32): f32 { // see: https://git.musl-libc.org/cgit/musl/tree/src/math/scalbnf.c
2902
+ const
2903
+ Ox1p24f = reinterpret<f32>(0x4B800000),
2904
+ Ox1p127f = reinterpret<f32>(0x7F000000),
2905
+ Ox1p_126f = reinterpret<f32>(0x00800000);
2906
+
2907
+ let y = x;
2908
+ if (n > 127) {
2909
+ y *= Ox1p127f;
2910
+ n -= 127;
2911
+ if (n > 127) {
2912
+ y *= Ox1p127f;
2913
+ n = builtin_min<i32>(n - 127, 127);
2914
+ }
2915
+ } else if (n < -126) {
2916
+ y *= Ox1p_126f * Ox1p24f;
2917
+ n += 126 - 24;
2918
+ if (n < -126) {
2919
+ y *= Ox1p_126f * Ox1p24f;
2920
+ n = builtin_max<i32>(n + 126 - 24, -126);
2921
+ }
2922
+ }
2923
+ return y * reinterpret<f32>(<u32>(0x7F + n) << 23);
2924
+ }
2925
+
2926
+ export function mod(x: f32, y: f32): f32 { // see: musl/src/math/fmodf.c
2927
+ if (builtin_abs<f32>(y) == 1.0) {
2928
+ // x % 1, x % -1 ==> sign(x) * abs(x - 1.0 * trunc(x / 1.0))
2929
+ // TODO: move this rule to compiler's optimization pass.
2930
+ // It could be apply for any x % C_pot, where "C_pot" is pow of two const.
2931
+ return builtin_copysign<f32>(x - builtin_trunc<f32>(x), x);
2932
+ }
2933
+ let ux = reinterpret<u32>(x);
2934
+ let uy = reinterpret<u32>(y);
2935
+ let ex = i32(ux >> 23 & 0xFF);
2936
+ let ey = i32(uy >> 23 & 0xFF);
2937
+ let sm = ux & 0x80000000;
2938
+ let uy1 = uy << 1;
2939
+ if (uy1 == 0 || ex == 0xFF || isNaN<f32>(y)) {
2940
+ let m = x * y;
2941
+ return m / m;
2942
+ }
2943
+ let ux1 = ux << 1;
2944
+ if (ux1 <= uy1) {
2945
+ return x * f32(ux1 != uy1);
2946
+ }
2947
+ if (!ex) {
2948
+ ex -= builtin_clz<u32>(ux << 9);
2949
+ ux <<= 1 - ex;
2950
+ } else {
2951
+ ux &= <u32>-1 >> 9;
2952
+ ux |= 1 << 23;
2953
+ }
2954
+ if (!ey) {
2955
+ ey -= builtin_clz<u32>(uy << 9);
2956
+ uy <<= 1 - ey;
2957
+ } else {
2958
+ uy &= u32(-1) >> 9;
2959
+ uy |= 1 << 23;
2960
+ }
2961
+ while (ex > ey) {
2962
+ if (ux >= uy) {
2963
+ if (ux == uy) return 0 * x;
2964
+ ux -= uy;
2965
+ }
2966
+ ux <<= 1;
2967
+ --ex;
2968
+ }
2969
+ if (ux >= uy) {
2970
+ if (ux == uy) return 0 * x;
2971
+ ux -= uy;
2972
+ }
2973
+ // for (; !(ux >> 23); ux <<= 1) --ex;
2974
+ let shift = <i32>builtin_clz<u32>(ux << 8);
2975
+ ex -= shift;
2976
+ ux <<= shift;
2977
+ if (ex > 0) {
2978
+ ux -= 1 << 23;
2979
+ ux |= <u32>ex << 23;
2980
+ } else {
2981
+ ux >>= -ex + 1;
2982
+ }
2983
+ return reinterpret<f32>(ux | sm);
2984
+ }
2985
+
2986
+ export function rem(x: f32, y: f32): f32 { // see: musl/src/math/remquof.c
2987
+ let ux = reinterpret<u32>(x);
2988
+ let uy = reinterpret<u32>(y);
2989
+ let ex = i32(ux >> 23 & 0xFF);
2990
+ let ey = i32(uy >> 23 & 0xFF);
2991
+ let uxi = ux;
2992
+ if (uy << 1 == 0 || ex == 0xFF || isNaN(y)) return (x * y) / (x * y);
2993
+ if (ux << 1 == 0) return x;
2994
+ if (!ex) {
2995
+ ex -= builtin_clz<u32>(uxi << 9);
2996
+ uxi <<= 1 - ex;
2997
+ } else {
2998
+ uxi &= u32(-1) >> 9;
2999
+ uxi |= 1 << 23;
3000
+ }
3001
+ if (!ey) {
3002
+ ey -= builtin_clz<u32>(uy << 9);
3003
+ uy <<= 1 - ey;
3004
+ } else {
3005
+ uy &= u32(-1) >> 9;
3006
+ uy |= 1 << 23;
3007
+ }
3008
+ let q = 0;
3009
+ do {
3010
+ if (ex < ey) {
3011
+ if (ex + 1 == ey) break; // goto end
3012
+ return x;
3013
+ }
3014
+ while (ex > ey) {
3015
+ if (uxi >= uy) {
3016
+ uxi -= uy;
3017
+ ++q;
3018
+ }
3019
+ uxi <<= 1;
3020
+ q <<= 1;
3021
+ --ex;
3022
+ }
3023
+ if (uxi >= uy) {
3024
+ uxi -= uy;
3025
+ ++q;
3026
+ }
3027
+ if (uxi == 0) ex = -30;
3028
+ else {
3029
+ let shift = builtin_clz<i32>(uxi << 8);
3030
+ ex -= shift;
3031
+ uxi <<= shift;
3032
+ }
3033
+ break;
3034
+ } while (false);
3035
+ // end:
3036
+ if (ex > 0) {
3037
+ uxi -= 1 << 23;
3038
+ uxi |= <u32>ex << 23;
3039
+ } else {
3040
+ uxi >>= -ex + 1;
3041
+ }
3042
+ x = reinterpret<f32>(uxi);
3043
+ y = builtin_abs<f32>(y);
3044
+ let x2 = x + x;
3045
+ if (ex == ey || (ex + 1 == ey && (<f32>x2 > y || (<f32>x2 == y && bool(q & 1))))) {
3046
+ x -= y;
3047
+ // q++;
3048
+ }
3049
+ return <i32>ux < 0 ? -x : x;
3050
+ }
3051
+
3052
+ export function sincos(x: f32): void { // see: musl/tree/src/math/sincosf.c
3053
+ const
3054
+ s1pio2 = reinterpret<f64>(0x3FF921FB54442D18), // 1 * M_PI_2
3055
+ s2pio2 = reinterpret<f64>(0x400921FB54442D18), // 2 * M_PI_2
3056
+ s3pio2 = reinterpret<f64>(0x4012D97C7F3321D2), // 3 * M_PI_2
3057
+ s4pio2 = reinterpret<f64>(0x401921FB54442D18); // 4 * M_PI_2
3058
+
3059
+ let ux = reinterpret<u32>(x);
3060
+ let sign = ux >> 31;
3061
+ ux &= 0x7FFFFFFF;
3062
+
3063
+ if (ux <= 0x3F490FDA) { // |x| ~<= π/4
3064
+ if (ux < 0x39800000) { // |x| < 2**-12
3065
+ sincos_sin = x;
3066
+ sincos_cos = 1;
3067
+ return;
3068
+ }
3069
+ sincos_sin = sin_kernf(x);
3070
+ sincos_cos = cos_kernf(x);
3071
+ return;
3072
+ }
3073
+ if (ASC_SHRINK_LEVEL < 1) {
3074
+ if (ux <= 0x407B53D1) { // |x| ~<= 5π/4
3075
+ if (ux <= 0x4016CBE3) { // |x| ~<= 3π/4
3076
+ if (sign) {
3077
+ sincos_sin = -cos_kernf(x + s1pio2);
3078
+ sincos_cos = sin_kernf(x + s1pio2);
3079
+ } else {
3080
+ sincos_sin = cos_kernf(s1pio2 - x);
3081
+ sincos_cos = sin_kernf(s1pio2 - x);
3082
+ }
3083
+ return;
3084
+ }
3085
+ // -sin(x + c) is not correct if x+c could be 0: -0 vs +0
3086
+ sincos_sin = -sin_kernf(sign ? x + s2pio2 : x - s2pio2);
3087
+ sincos_cos = -cos_kernf(sign ? x + s2pio2 : x - s2pio2);
3088
+ return;
3089
+ }
3090
+ if (ux <= 0x40E231D5) { // |x| ~<= 9π/4
3091
+ if (ux <= 0x40AFEDDF) { // |x| ~<= 7π/4
3092
+ if (sign) {
3093
+ sincos_sin = cos_kernf(x + s3pio2);
3094
+ sincos_cos = -sin_kernf(x + s3pio2);
3095
+ } else {
3096
+ sincos_sin = -cos_kernf(x - s3pio2);
3097
+ sincos_cos = sin_kernf(x - s3pio2);
3098
+ }
3099
+ return;
3100
+ }
3101
+ sincos_sin = sin_kernf(sign ? x + s4pio2 : x - s4pio2);
3102
+ sincos_cos = cos_kernf(sign ? x + s4pio2 : x - s4pio2);
3103
+ return;
3104
+ }
3105
+ }
3106
+ // sin(Inf or NaN) is NaN
3107
+ if (ux >= 0x7F800000) {
3108
+ let xx = x - x;
3109
+ sincos_sin = xx;
3110
+ sincos_cos = xx;
3111
+ return;
3112
+ }
3113
+ // general argument reduction needed
3114
+ let n = rempio2f(x, ux, sign);
3115
+ let y = rempio2f_y;
3116
+ let s = sin_kernf(y);
3117
+ let c = cos_kernf(y);
3118
+ let sin = s, cos = c;
3119
+ if (n & 1) {
3120
+ sin = c;
3121
+ cos = -s;
3122
+ }
3123
+ if (n & 2) {
3124
+ sin = -sin;
3125
+ cos = -cos;
3126
+ }
3127
+ sincos_sin = sin;
3128
+ sincos_cos = cos;
3129
+ }
3130
+ }
3131
+
3132
+ export function ipow32(x: i32, e: i32): i32 {
3133
+ let out = 1;
3134
+ if (ASC_SHRINK_LEVEL < 1) {
3135
+ if (x == 2) {
3136
+ return select<i32>(1 << e, 0, <u32>e < 32);
3137
+ }
3138
+ if (e <= 0) {
3139
+ if (x == -1) return select<i32>(-1, 1, e & 1);
3140
+ return i32(e == 0) | i32(x == 1);
3141
+ }
3142
+ else if (e == 1) return x;
3143
+ else if (e == 2) return x * x;
3144
+ else if (e < 32) {
3145
+ let log = 32 - clz(e);
3146
+ // 32 = 2 ^ 5, so need only five cases.
3147
+ // But some extra cases needs for properly overflowing
3148
+ switch (log) {
3149
+ case 5: {
3150
+ if (e & 1) out *= x;
3151
+ e >>>= 1;
3152
+ x *= x;
3153
+ }
3154
+ case 4: {
3155
+ if (e & 1) out *= x;
3156
+ e >>>= 1;
3157
+ x *= x;
3158
+ }
3159
+ case 3: {
3160
+ if (e & 1) out *= x;
3161
+ e >>>= 1;
3162
+ x *= x;
3163
+ }
3164
+ case 2: {
3165
+ if (e & 1) out *= x;
3166
+ e >>>= 1;
3167
+ x *= x;
3168
+ }
3169
+ case 1: {
3170
+ if (e & 1) out *= x;
3171
+ }
3172
+ }
3173
+ return out;
3174
+ }
3175
+ }
3176
+ while (e) {
3177
+ if (e & 1) out *= x;
3178
+ e >>>= 1;
3179
+ x *= x;
3180
+ }
3181
+ return out;
3182
+ }
3183
+
3184
+ export function ipow64(x: i64, e: i64): i64 {
3185
+ let out: i64 = 1;
3186
+ if (ASC_SHRINK_LEVEL < 1) {
3187
+ if (x == 2) {
3188
+ return select<i64>(1 << e, 0, <u64>e < 64);
3189
+ }
3190
+ if (e <= 0) {
3191
+ if (x == -1) return select<i64>(-1, 1, e & 1);
3192
+ return i64(e == 0) | i64(x == 1);
3193
+ }
3194
+ else if (e == 1) return x;
3195
+ else if (e == 2) return x * x;
3196
+ else if (e < 64) {
3197
+ let log = 64 - <i32>clz(e);
3198
+ // 64 = 2 ^ 6, so need only six cases.
3199
+ // But some extra cases needs for properly overflowing
3200
+ switch (log) {
3201
+ case 6: {
3202
+ if (e & 1) out *= x;
3203
+ e >>>= 1;
3204
+ x *= x;
3205
+ }
3206
+ case 5: {
3207
+ if (e & 1) out *= x;
3208
+ e >>>= 1;
3209
+ x *= x;
3210
+ }
3211
+ case 4: {
3212
+ if (e & 1) out *= x;
3213
+ e >>>= 1;
3214
+ x *= x;
3215
+ }
3216
+ case 3: {
3217
+ if (e & 1) out *= x;
3218
+ e >>>= 1;
3219
+ x *= x;
3220
+ }
3221
+ case 2: {
3222
+ if (e & 1) out *= x;
3223
+ e >>>= 1;
3224
+ x *= x;
3225
+ }
3226
+ case 1: {
3227
+ if (e & 1) out *= x;
3228
+ }
3229
+ }
3230
+ return out;
3231
+ }
3232
+ }
3233
+ while (e) {
3234
+ if (e & 1) out *= x;
3235
+ e >>>= 1;
3236
+ x *= x;
3237
+ }
3238
+ return out;
3239
+ }
3240
+
3241
+ /*
3242
+ TODO:
3243
+ In compile time if only exponent is constant we could replace ipow32/ipow64 by shortest addition chains
3244
+ which usually faster than exponentiation by squaring
3245
+
3246
+ for ipow32 and e < 32:
3247
+
3248
+ let b: i32, c: i32, d: i32, h: i32, k: i32, g: i32;
3249
+ switch (e) {
3250
+ case 1: return x;
3251
+ case 2: return x * x;
3252
+ case 3: return x * x * x;
3253
+ case 4: return (b = x * x) * b;
3254
+ case 5: return (b = x * x) * b * x;
3255
+ case 6: return (b = x * x) * b * b;
3256
+ case 7: return (b = x * x) * b * b * x;
3257
+ case 8: return (d = (b = x * x) * b) * d;
3258
+ case 9: return (c = x * x * x) * c * c;
3259
+ case 10: return (d = (b = x * x) * b) * d * b;
3260
+ case 11: return (d = (b = x * x) * b) * d * b * x;
3261
+ case 12: return (d = (b = x * x) * b) * d * d;
3262
+ case 13: return (d = (b = x * x) * b) * d * d * x;
3263
+ case 14: return (d = (b = x * x) * b) * d * d * b;
3264
+ case 15: return (k = (b = x * x) * b * x) * k * k;
3265
+ case 16: return (h = (d = (b = x * x) * b) * d) * h;
3266
+ case 17: return (h = (d = (b = x * x) * b) * d) * h * x;
3267
+ case 18: return (h = (d = (b = x * x) * b) * d * x) * h;
3268
+ case 19: return (h = (d = (b = x * x) * b) * d * x) * h * x;
3269
+ case 20: return (h = (k = (b = x * x) * b * x) * k) * h;
3270
+ case 21: return (h = (k = (b = x * x) * b * x) * k) * h * x;
3271
+ case 22: return (g = (h = (k = (b = x * x) * b * x) * k) * x) * g;
3272
+ case 23: return (h = (d = (c = (b = x * x) * x) * b) * d) * h * c;
3273
+ case 24: return (h = (d = (c = x * x * x) * c) * d) * h;
3274
+ case 25: return (h = (d = (c = x * x * x) * c) * d) * h * x;
3275
+ case 26: return (g = (h = (d = (c = x * x * x) * c) * d) * x) * g;
3276
+ case 27: return (h = (d = (c = x * x * x) * c) * d) * h * c;
3277
+ case 28: return (h = (d = (c = x * x * x) * c * x) * d) * h;
3278
+ case 29: return (h = (d = (c = x * x * x) * c * x) * d) * h * x;
3279
+ case 30: return (h = (d = (c = x * x * x) * c) * d * c) * h;
3280
+ case 31: return (h = (d = (c = x * x * x) * c) * d * c) * h * x;
3281
+ }
3282
+
3283
+ for ipow64: TODO
3284
+ switch (e) {
3285
+ case 32:
3286
+ ...
3287
+ case 63:
3288
+ }
3289
+ */