History

win32 libm: Final optimizations and added nan*() function.

Tyge Løvset committed 5 years ago

Commit 2f78f541 parent 3709f8d1 file · +52 −41Browse files

Unified · Split

win32/include/tcc/tcc_libm.h+52−41
@@ -46,7 +46,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. · 45 unmodified lines
46/* fpclassify */46/* fpclassify */
47 47
48__CRT_INLINE int __cdecl __fpclassify (double x) {48__CRT_INLINE int __cdecl __fpclassify (double x) {
49 union {double f; uint64_t i;} u = {x};49 union {double f; uint64_t i;} u = {.f = x};
50 int e = u.i>>52 & 0x7ff;50 int e = u.i>>52 & 0x7ff;
51 if (!e) return u.i<<1 ? FP_SUBNORMAL : FP_ZERO;51 if (!e) return u.i<<1 ? FP_SUBNORMAL : FP_ZERO;
52 if (e==0x7ff) return u.i<<12 ? FP_NAN : FP_INFINITE;52 if (e==0x7ff) return u.i<<12 ? FP_NAN : FP_INFINITE;
@@ -54,7 +54,7 @@ __CRT_INLINE int __cdecl __fpclassify (double x) { · 1 unmodified line
54}54}
55 55
56__CRT_INLINE int __cdecl __fpclassifyf (float x) {56__CRT_INLINE int __cdecl __fpclassifyf (float x) {
57 union {float f; uint32_t i;} u = {x};57 union {float f; uint32_t i;} u = {.f = x};
58 int e = u.i>>23 & 0xff;58 int e = u.i>>23 & 0xff;
59 if (!e) return u.i<<1 ? FP_SUBNORMAL : FP_ZERO;59 if (!e) return u.i<<1 ? FP_SUBNORMAL : FP_ZERO;
60 if (e==0xff) return u.i<<9 ? FP_NAN : FP_INFINITE;60 if (e==0xff) return u.i<<9 ? FP_NAN : FP_INFINITE;
@@ -69,13 +69,13 @@ __CRT_INLINE int __cdecl __fpclassifyl (long double x) { · 8 unmodified lines
69/* signbit */69/* signbit */
70 70
71__CRT_INLINE int __cdecl __signbit (double x) {71__CRT_INLINE int __cdecl __signbit (double x) {
72 union {double d; uint64_t i;} y = { x };72 union {double f; uint64_t i;} u = {.f = x};
73 return y.i>>63;73 return u.i>>63;
74}74}
75 75
76__CRT_INLINE int __cdecl __signbitf (float x) {76__CRT_INLINE int __cdecl __signbitf (float x) {
77 union {float f; uint32_t i; } y = { x };77 union {float f; uint32_t i; } u = {.f = x};
78 return y.i>>31;78 return u.i>>31;
79}79}
80 80
81__CRT_INLINE int __cdecl __signbitl (long double x) {81__CRT_INLINE int __cdecl __signbitl (long double x) {
@@ -128,7 +128,7 @@ __CRT_INLINE long double __cdecl fmaxl (long double x, long double y) { · 46 unmodified lines
128} while(0)128} while(0)
129 129
130__CRT_INLINE double __cdecl round (double x) {130__CRT_INLINE double __cdecl round (double x) {
131 union {double f; uint64_t i;} u = {x};131 union {double f; uint64_t i;} u = {.f = x};
132 int e = u.i >> 52 & 0x7ff;132 int e = u.i >> 52 & 0x7ff;
133 double y;133 double y;
134 134
@@ -182,26 +182,26 @@ __CRT_INLINE long long __cdecl llroundl (long double x) { · 47 unmodified lines
182/* MUSL asinh, acosh, atanh */182/* MUSL asinh, acosh, atanh */
183 183
184__CRT_INLINE double __cdecl asinh(double x) {184__CRT_INLINE double __cdecl asinh(double x) {
185 union {double f; uint64_t i;} u = {x};185 union {double f; uint64_t i;} u = {.f = x};
186 unsigned e = u.i >> 52 & 0x7ff, s = u.i >> 63;186 unsigned e = u.i >> 52 & 0x7ff, s = u.i >> 63;
187 u.i &= -1ull / 2, x = u.f;187 u.i &= -1ull / 2, x = u.f;
188 if (e >= 0x3ff + 26) x = log(x) + 0.69314718055994530941723212145818;188 if (e >= 0x3ff + 26) x = log(x) + 0.693147180559945309;
189 else if (e >= 0x3ff + 1) x = log(2*x + 1 / (sqrt(x*x + 1) + x));189 else if (e >= 0x3ff + 1) x = log(2*x + 1 / (sqrt(x*x + 1) + x)); /* |x|>=2 */
190 else if (e >= 0x3ff - 26) x = log1p(x + x*x / (sqrt(x*x + 1) + 1));190 else if (e >= 0x3ff - 26) x = log1p(x + x*x / (sqrt(x*x + 1) + 1));
191 else TCCFP_FORCE_EVAL(x + 0x1p120f);191 else TCCFP_FORCE_EVAL(x + 0x1p120f);
192 return s ? -x : x;192 return s ? -x : x;
193}193}
194 194
195__CRT_INLINE double __cdecl acosh(double x) {195__CRT_INLINE double __cdecl acosh(double x) {
196 union {double f; uint64_t i;} u = {x};196 union {double f; uint64_t i;} u = {.f = x};
197 unsigned e = u.i >> 52 & 0x7ff;197 unsigned e = u.i >> 52 & 0x7ff;
198 if (e < 0x3ff + 1) return log1p(x - 1 + sqrt((x - 1)*(x - 1) + 2*(x - 1)));198 if (e < 0x3ff + 1) return --x, log1p(x + sqrt(x*x + 2*x)); /* |x|<2 */
199 if (e < 0x3ff + 26) return log(2*x - 1 / (x + sqrt(x*x - 1)));199 if (e < 0x3ff + 26) return log(2*x - 1 / (x + sqrt(x*x - 1)));
200 return log(x) + 0.69314718055994530941723212145818;200 return log(x) + 0.693147180559945309;
201}201}
202 202
203__CRT_INLINE double __cdecl atanh(double x) {203__CRT_INLINE double __cdecl atanh(double x) {
204 union {double f; uint64_t i;} u = {x};204 union {double f; uint64_t i;} u = {.f = x};
205 unsigned e = u.i >> 52 & 0x7ff, s = u.i >> 63;205 unsigned e = u.i >> 52 & 0x7ff, s = u.i >> 63;
206 u.i &= -1ull / 2, x = u.f;206 u.i &= -1ull / 2, x = u.f;
207 if (e < 0x3ff - 1) {207 if (e < 0x3ff - 1) {
@@ -232,6 +232,18 @@ __CRT_INLINE double __cdecl scalbn(double x, int n) { · 24 unmodified lines
232 return x * u.f;232 return x * u.f;
233}233}
234 234
235/* MUSL nan */
236
237__CRT_INLINE double __cdecl nan(const char* s) {
238 return NAN;
239}
240__CRT_INLINE float __cdecl nanf(const char* s) {
241 return NAN;
242}
243__CRT_INLINE long double __cdecl nanl(const char* s) {
244 return NAN;
245}
246
235 247
236/*******************************************************************************248/*******************************************************************************
237 End of code based on MUSL249 End of code based on MUSL
@@ -240,7 +252,7 @@ __CRT_INLINE double __cdecl scalbn(double x, int n) { · 2 unmodified lines
240 252
241/* Following are math functions missing from msvcrt.dll, and not defined253/* Following are math functions missing from msvcrt.dll, and not defined
242 * in math.h or above. Functions still remaining:254 * in math.h or above. Functions still remaining:
243 * remquo(), remainder(), fma(), nan(), erf(), erfc(), nearbyint().255 * remquo(), remainder(), fma(), erf(), erfc(), nearbyint().
244 * In <stdlib.h>: lldiv().256 * In <stdlib.h>: lldiv().
245 */257 */
246 258
@@ -381,12 +393,12 @@ __CRT_INLINE long double __cdecl nexttowardl(long double x, long double to) { · 134 unmodified lines
381 393
382 394
383__CRT_INLINE float __cdecl fabsf (float x) {395__CRT_INLINE float __cdecl fabsf (float x) {
384 union {float f; uint32_t i;} u = {x};396 union {float f; uint32_t i;} u = {.f = x};
385 u.i &= 0x7fffffff;397 u.i &= 0x7fffffff; return u.f;
386 return u.f;
387}398}
388__CRT_INLINE long double __cdecl fabsl (long double x) {399__CRT_INLINE long double __cdecl fabsl (long double x) {
389 return fabs(x);400 union {double f; uint64_t i;} u = {.f = x};
401 u.i &= 0x7fffffffffffffff; return u.f;
390}402}
391 403
392 404
@@ -456,14 +468,12 @@ __CRT_INLINE long double __cdecl log1pl(long double x) { · 63 unmodified lines
456 468
457 469
458__CRT_INLINE double __cdecl expm1(double x) {470__CRT_INLINE double __cdecl expm1(double x) {
459 if (fabs(x) > 0.0024) return exp(x) - 1.0;471 if (x > 0.0024 || x < -0.0024) return exp(x) - 1.0;
460 double u, v = x*x, t = x + 0.5*v + 0.1666666666666666667*(u = v*x);472 return x*(1.0 + 0.5*x*(1.0 + (1/3.0)*x*(1.0 + 0.25*x*(1.0 + 0.2*x))));
461 return t + 0.04166666666666666667*u*x;
462}473}
463__CRT_INLINE float __cdecl expm1f(float x) {474__CRT_INLINE float __cdecl expm1f(float x) {
464 if (fabsf(x) > 0.085f) return expf(x) - 1.0f;475 if (x > 0.085f || x < -0.085f) return expf(x) - 1.0f;
465 float u, v = x*x, t = x + 0.5f*v + 0.1666666666666666667f*(u = v*x);476 return x*(1.0f + 0.5f*x*(1.0f + (1/3.0f)*x*(1.0f + 0.25f*x)));
466 return t + 0.04166666666666666667f*u*x;
467}477}
468__CRT_INLINE long double __cdecl expm1l(long double x) {478__CRT_INLINE long double __cdecl expm1l(long double x) {
469 return expm1(x);479 return expm1(x);
@@ -471,35 +481,35 @@ __CRT_INLINE long double __cdecl expm1l(long double x) { · 1 unmodified line
471 481
472 482
473__CRT_INLINE double __cdecl cbrt(double x) {483__CRT_INLINE double __cdecl cbrt(double x) {
474 return copysign(pow(fabs(x), 1/3.0), x);484 return x < 0.0 ? -pow(-x, 1/3.0) : pow(x, 1/3.0);
475}485}
476__CRT_INLINE float __cdecl cbrtf(float x) {486__CRT_INLINE float __cdecl cbrtf(float x) {
477 return copysignf(pow(fabs(x), 1/3.0), x);487 return x < 0.0f ? -pow(-x, 1/3.0) : pow(x, 1/3.0);
478}488}
479__CRT_INLINE long double __cdecl cbrtl(long double x) {489__CRT_INLINE long double __cdecl cbrtl(long double x) {
480 return copysign(pow(fabs(x), 1/3.0), x);490 return cbrt(x);
481}491}
482 492
483 493
484__CRT_INLINE double __cdecl log2(double x) {494__CRT_INLINE double __cdecl log2(double x) {
485 return log(x) * 1.4426950408889634073599246810019;495 return log(x) * 1.442695040888963407;
486}496}
487__CRT_INLINE float __cdecl log2f(float x) {497__CRT_INLINE float __cdecl log2f(float x) {
488 return log(x) * 1.4426950408889634073599246810019;498 return log(x) * 1.442695040888963407;
489}499}
490__CRT_INLINE long double __cdecl log2l(long double x) {500__CRT_INLINE long double __cdecl log2l(long double x) {
491 return log(x) * 1.4426950408889634073599246810019;501 return log(x) * 1.442695040888963407;
492}502}
493 503
494 504
495__CRT_INLINE double __cdecl exp2(double x) {505__CRT_INLINE double __cdecl exp2(double x) {
496 return exp(x * 0.69314718055994530941723212145818);506 return exp(x * 0.693147180559945309);
497}507}
498__CRT_INLINE float __cdecl exp2f(float x) {508__CRT_INLINE float __cdecl exp2f(float x) {
499 return exp(x * 0.69314718055994530941723212145818);509 return exp(x * 0.693147180559945309);
500}510}
501__CRT_INLINE long double __cdecl exp2l(long double x) {511__CRT_INLINE long double __cdecl exp2l(long double x) {
502 return exp(x * 0.69314718055994530941723212145818);512 return exp(x * 0.693147180559945309);
503}513}
504 514
505 515
@@ -535,11 +545,10 @@ __CRT_INLINE long double __cdecl fdiml(long double x, long double y) { · 29 unmodified lines
535 545
536__CRT_INLINE double __cdecl tgamma(double x) {546__CRT_INLINE double __cdecl tgamma(double x) {
537 double m = 1.0, t = 3.14159265358979323;547 double m = 1.0, t = 3.14159265358979323;
538 if (x > 172.0)
539 return INFINITY;
540 if (x == floor(x)) {548 if (x == floor(x)) {
541 for (int k = 2; k < x; ++k) m *= k;549 if (x == 0) return INFINITY;
542 return x > 0.0 ? m : (x == 0.0 ? INFINITY : NAN);550 if (x < 0) return NAN;
551 if (x < 26) { for (double k = 2; k < x; ++k) m *= k; return m; }
543 }552 }
544 if (x < 0.5)553 if (x < 0.5)
545 return t / (sin(t*x)*tgamma(1.0 - x));554 return t / (sin(t*x)*tgamma(1.0 - x));
@@ -557,9 +566,11 @@ __CRT_INLINE double __cdecl tgamma(double x) { · 11 unmodified lines
557 566
558 567
559__CRT_INLINE double __cdecl lgamma(double x) {568__CRT_INLINE double __cdecl lgamma(double x) {
560 if (x < 12.0)569 if (x < 12.0) {
561 return x > 0.0 || x != floor(x) ? log(fabs(tgamma(x))) : INFINITY;570 if (x <= 0.0 && x == floor(x)) return INFINITY;
562 571 x = tgamma(x);
572 return log(x < 0.0 ? -x : x);
573 }
563 static const double c[7] = {1.0/12.0, -1.0/360.0, 1.0/1260.0, -1.0/1680.0,574 static const double c[7] = {1.0/12.0, -1.0/360.0, 1.0/1260.0, -1.0/1680.0,
564 1.0/1188.0, -691.0/360360.0, 1.0/156.0};575 1.0/1188.0, -691.0/360360.0, 1.0/156.0};
565 double m = -3617.0/122400.0, t = 1.0 / (x*x);576 double m = -3617.0/122400.0, t = 1.0 / (x*x);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t