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
4646 /* fpclassify */
4747
4848 __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};
5050 int e = u.i>>52 & 0x7ff;
5151 if (!e) return u.i<<1 ? FP_SUBNORMAL : FP_ZERO;
5252 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
5454 }
5555
5656 __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};
5858 int e = u.i>>23 & 0xff;
5959 if (!e) return u.i<<1 ? FP_SUBNORMAL : FP_ZERO;
6060 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
6969 /* signbit */
7070
7171 __CRT_INLINE int __cdecl __signbit (double x) {
72− union {double d; uint64_t i;} y = { x };
73− return y.i>>63;
72+ union {double f; uint64_t i;} u = {.f = x};
73+ return u.i>>63;
7474 }
7575
7676 __CRT_INLINE int __cdecl __signbitf (float x) {
77− union {float f; uint32_t i; } y = { x };
78− return y.i>>31;
77+ union {float f; uint32_t i; } u = {.f = x};
78+ return u.i>>31;
7979 }
8080
8181 __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
128128 } while(0)
129129
130130 __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};
132132 int e = u.i >> 52 & 0x7ff;
133133 double y;
134134
@@ -182,26 +182,26 @@ __CRT_INLINE long long __cdecl llroundl (long double x) { · 47 unmodified lines
182182 /* MUSL asinh, acosh, atanh */
183183
184184 __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};
186186 unsigned e = u.i >> 52 & 0x7ff, s = u.i >> 63;
187187 u.i &= -1ull / 2, x = u.f;
188− if (e >= 0x3ff + 26) x = log(x) + 0.69314718055994530941723212145818;
189− else if (e >= 0x3ff + 1) x = log(2*x + 1 / (sqrt(x*x + 1) + x));
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)); /* |x|>=2 */
190190 else if (e >= 0x3ff - 26) x = log1p(x + x*x / (sqrt(x*x + 1) + 1));
191191 else TCCFP_FORCE_EVAL(x + 0x1p120f);
192192 return s ? -x : x;
193193 }
194194
195195 __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};
197197 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 */
199199 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;
201201 }
202202
203203 __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};
205205 unsigned e = u.i >> 52 & 0x7ff, s = u.i >> 63;
206206 u.i &= -1ull / 2, x = u.f;
207207 if (e < 0x3ff - 1) {
@@ -232,6 +232,18 @@ __CRT_INLINE double __cdecl scalbn(double x, int n) { · 24 unmodified lines
232232 return x * u.f;
233233 }
234234
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+
235247
236248 /*******************************************************************************
237249 End of code based on MUSL
@@ -240,7 +252,7 @@ __CRT_INLINE double __cdecl scalbn(double x, int n) { · 2 unmodified lines
240252
241253 /* Following are math functions missing from msvcrt.dll, and not defined
242254 * in math.h or above. Functions still remaining:
243− * remquo(), remainder(), fma(), nan(), erf(), erfc(), nearbyint().
255+ * remquo(), remainder(), fma(), erf(), erfc(), nearbyint().
244256 * In <stdlib.h>: lldiv().
245257 */
246258
@@ -381,12 +393,12 @@ __CRT_INLINE long double __cdecl nexttowardl(long double x, long double to) { · 134 unmodified lines
381393
382394
383395 __CRT_INLINE float __cdecl fabsf (float x) {
384− union {float f; uint32_t i;} u = {x};
385− u.i &= 0x7fffffff;
386− return u.f;
396+ union {float f; uint32_t i;} u = {.f = x};
397+ u.i &= 0x7fffffff; return u.f;
387398 }
388399 __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;
390402 }
391403
392404
@@ -456,14 +468,12 @@ __CRT_INLINE long double __cdecl log1pl(long double x) { · 63 unmodified lines
456468
457469
458470 __CRT_INLINE double __cdecl expm1(double x) {
459− if (fabs(x) > 0.0024) return exp(x) - 1.0;
460− double u, v = x*x, t = x + 0.5*v + 0.1666666666666666667*(u = v*x);
461− return t + 0.04166666666666666667*u*x;
471+ if (x > 0.0024 || x < -0.0024) return exp(x) - 1.0;
472+ return x*(1.0 + 0.5*x*(1.0 + (1/3.0)*x*(1.0 + 0.25*x*(1.0 + 0.2*x))));
462473 }
463474 __CRT_INLINE float __cdecl expm1f(float x) {
464− if (fabsf(x) > 0.085f) return expf(x) - 1.0f;
465− float u, v = x*x, t = x + 0.5f*v + 0.1666666666666666667f*(u = v*x);
466− return t + 0.04166666666666666667f*u*x;
475+ if (x > 0.085f || x < -0.085f) return expf(x) - 1.0f;
476+ return x*(1.0f + 0.5f*x*(1.0f + (1/3.0f)*x*(1.0f + 0.25f*x)));
467477 }
468478 __CRT_INLINE long double __cdecl expm1l(long double x) {
469479 return expm1(x);
@@ -471,35 +481,35 @@ __CRT_INLINE long double __cdecl expm1l(long double x) { · 1 unmodified line
471481
472482
473483 __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);
475485 }
476486 __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);
478488 }
479489 __CRT_INLINE long double __cdecl cbrtl(long double x) {
480− return copysign(pow(fabs(x), 1/3.0), x);
490+ return cbrt(x);
481491 }
482492
483493
484494 __CRT_INLINE double __cdecl log2(double x) {
485− return log(x) * 1.4426950408889634073599246810019;
495+ return log(x) * 1.442695040888963407;
486496 }
487497 __CRT_INLINE float __cdecl log2f(float x) {
488− return log(x) * 1.4426950408889634073599246810019;
498+ return log(x) * 1.442695040888963407;
489499 }
490500 __CRT_INLINE long double __cdecl log2l(long double x) {
491− return log(x) * 1.4426950408889634073599246810019;
501+ return log(x) * 1.442695040888963407;
492502 }
493503
494504
495505 __CRT_INLINE double __cdecl exp2(double x) {
496− return exp(x * 0.69314718055994530941723212145818);
506+ return exp(x * 0.693147180559945309);
497507 }
498508 __CRT_INLINE float __cdecl exp2f(float x) {
499− return exp(x * 0.69314718055994530941723212145818);
509+ return exp(x * 0.693147180559945309);
500510 }
501511 __CRT_INLINE long double __cdecl exp2l(long double x) {
502− return exp(x * 0.69314718055994530941723212145818);
512+ return exp(x * 0.693147180559945309);
503513 }
504514
505515
@@ -535,11 +545,10 @@ __CRT_INLINE long double __cdecl fdiml(long double x, long double y) { · 29 unmodified lines
535545
536546 __CRT_INLINE double __cdecl tgamma(double x) {
537547 double m = 1.0, t = 3.14159265358979323;
538− if (x > 172.0)
539− return INFINITY;
540548 if (x == floor(x)) {
541− for (int k = 2; k < x; ++k) m *= k;
542− return x > 0.0 ? m : (x == 0.0 ? INFINITY : NAN);
549+ if (x == 0) return INFINITY;
550+ if (x < 0) return NAN;
551+ if (x < 26) { for (double k = 2; k < x; ++k) m *= k; return m; }
543552 }
544553 if (x < 0.5)
545554 return t / (sin(t*x)*tgamma(1.0 - x));
@@ -557,9 +566,11 @@ __CRT_INLINE double __cdecl tgamma(double x) { · 11 unmodified lines
557566
558567
559568 __CRT_INLINE double __cdecl lgamma(double x) {
560− if (x < 12.0)
561− return x > 0.0 || x != floor(x) ? log(fabs(tgamma(x))) : INFINITY;
562−
569+ if (x < 12.0) {
570+ if (x <= 0.0 && x == floor(x)) return INFINITY;
571+ x = tgamma(x);
572+ return log(x < 0.0 ? -x : x);
573+ }
563574 static const double c[7] = {1.0/12.0, -1.0/360.0, 1.0/1260.0, -1.0/1680.0,
564575 1.0/1188.0, -691.0/360360.0, 1.0/156.0};
565576 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