diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2022-12-09 14:58:16 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2022-12-10 03:06:17 -0500 |
| commit | 02b221051a180a252bb3a092b1cc054469c6fa15 (patch) | |
| tree | 5105489a81f50526e6cbff3232541769dcf949b6 | |
| parent | b483c796c66e3a415a7590bfe62f316fa8fa70e6 (diff) | |
| download | zig-02b221051a180a252bb3a092b1cc054469c6fa15.tar.gz zig-02b221051a180a252bb3a092b1cc054469c6fa15.zip | |
fix aarch64-windows-gnu libc
We were missing some math functions. After this enhancement I verified
that I was able to cross-compile ninja.exe for aarch64-windows and
produce a viable binary.
32 files changed, 780 insertions, 5 deletions
diff --git a/lib/libc/mingw/math/arm-common/acosh.c b/lib/libc/mingw/math/arm-common/acosh.c new file mode 100644 index 0000000000..a26840d862 --- /dev/null +++ b/lib/libc/mingw/math/arm-common/acosh.c @@ -0,0 +1,16 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#include <math.h> + +double acosh(double x) +{ + if (x < 1.0) + return NAN; + if (isinf(x*x)) + return log(2) + log(x); + return log(x + sqrt(x*x - 1)); +} diff --git a/lib/libc/mingw/math/arm-common/acoshf.c b/lib/libc/mingw/math/arm-common/acoshf.c new file mode 100644 index 0000000000..d02e94da62 --- /dev/null +++ b/lib/libc/mingw/math/arm-common/acoshf.c @@ -0,0 +1,16 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#include <math.h> + +float acoshf(float x) +{ + if (x < 1.0) + return NAN; + if (isinf(x*x)) + return logf(2) + logf(x); + return logf(x + sqrtf(x*x - 1)); +} diff --git a/lib/libc/mingw/math/arm-common/acoshl.c b/lib/libc/mingw/math/arm-common/acoshl.c new file mode 100644 index 0000000000..c2157bebc9 --- /dev/null +++ b/lib/libc/mingw/math/arm-common/acoshl.c @@ -0,0 +1,16 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#include <math.h> + +long double acoshl(long double x) +{ +#if defined(__arm__) || defined(_ARM_) || defined(__aarch64__) || defined(_ARM64_) + return acosh(x); +#else +#error Not supported on your platform yet +#endif +} diff --git a/lib/libc/mingw/math/arm-common/asinh.c b/lib/libc/mingw/math/arm-common/asinh.c new file mode 100644 index 0000000000..a5a8da7ba5 --- /dev/null +++ b/lib/libc/mingw/math/arm-common/asinh.c @@ -0,0 +1,18 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#include <math.h> + +double asinh(double x) +{ + if (isinf(x*x + 1)) { + if (x > 0) + return log(2) + log(x); + else + return -log(2) - log(-x); + } + return log(x + sqrt(x*x + 1)); +} diff --git a/lib/libc/mingw/math/arm-common/asinhf.c b/lib/libc/mingw/math/arm-common/asinhf.c new file mode 100644 index 0000000000..f1ccea2030 --- /dev/null +++ b/lib/libc/mingw/math/arm-common/asinhf.c @@ -0,0 +1,18 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#include <math.h> + +float asinhf(float x) +{ + if (isinf(x*x + 1)) { + if (x > 0) + return logf(2) + logf(x); + else + return -logf(2) - logf(-x); + } + return logf(x + sqrtf(x*x + 1)); +} diff --git a/lib/libc/mingw/math/arm-common/asinhl.c b/lib/libc/mingw/math/arm-common/asinhl.c new file mode 100644 index 0000000000..556b3c4f51 --- /dev/null +++ b/lib/libc/mingw/math/arm-common/asinhl.c @@ -0,0 +1,16 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#include <math.h> + +long double asinhl(long double x) +{ +#if defined(__arm__) || defined(_ARM_) || defined(__aarch64__) || defined(_ARM64_) + return asinh(x); +#else +#error Not supported on your platform yet +#endif +} diff --git a/lib/libc/mingw/math/arm-common/atanh.c b/lib/libc/mingw/math/arm-common/atanh.c new file mode 100644 index 0000000000..08302c0e2e --- /dev/null +++ b/lib/libc/mingw/math/arm-common/atanh.c @@ -0,0 +1,17 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#include <math.h> + +double atanh(double x) +{ + if (x > 1 || x < -1) + return NAN; + if (-1e-6 < x && x < 1e-6) + return x + x*x*x/3; + else + return (log(1 + x) - log(1 - x)) / 2; +} diff --git a/lib/libc/mingw/math/arm-common/atanhf.c b/lib/libc/mingw/math/arm-common/atanhf.c new file mode 100644 index 0000000000..a29492305e --- /dev/null +++ b/lib/libc/mingw/math/arm-common/atanhf.c @@ -0,0 +1,17 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#include <math.h> + +float atanhf(float x) +{ + if (x > 1 || x < -1) + return NAN; + if (-1e-6 < x && x < 1e-6) + return x + x*x*x/3; + else + return (logf(1 + x) - logf(1 - x)) / 2; +} diff --git a/lib/libc/mingw/math/arm-common/atanhl.c b/lib/libc/mingw/math/arm-common/atanhl.c new file mode 100644 index 0000000000..c4d124b9f4 --- /dev/null +++ b/lib/libc/mingw/math/arm-common/atanhl.c @@ -0,0 +1,16 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#include <math.h> + +long double atanhl(long double x) +{ +#if defined(__arm__) || defined(_ARM_) || defined(__aarch64__) || defined(_ARM64_) + return atanh(x); +#else +#error Not supported on your platform yet +#endif +} diff --git a/lib/libc/mingw/math/arm-common/copysignl.c b/lib/libc/mingw/math/arm-common/copysignl.c new file mode 100644 index 0000000000..ea66215f2d --- /dev/null +++ b/lib/libc/mingw/math/arm-common/copysignl.c @@ -0,0 +1,11 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ +#include <math.h> + +long double copysignl(long double x, long double y) +{ + return copysign(x, y); +} diff --git a/lib/libc/mingw/math/arm-common/expm1.c b/lib/libc/mingw/math/arm-common/expm1.c new file mode 100644 index 0000000000..578bb446aa --- /dev/null +++ b/lib/libc/mingw/math/arm-common/expm1.c @@ -0,0 +1,12 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#include <math.h> + +double expm1(double x) +{ + return exp(x) - 1.0; +} diff --git a/lib/libc/mingw/math/arm-common/expm1f.c b/lib/libc/mingw/math/arm-common/expm1f.c new file mode 100644 index 0000000000..a810b71862 --- /dev/null +++ b/lib/libc/mingw/math/arm-common/expm1f.c @@ -0,0 +1,15 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#include <math.h> + +float expm1f(float x) +{ + // Intentionally using double version of exp() here in the float version of + // expm1, to preserve as much accuracy as possible in the intermediate + // result. + return exp(x) - 1.0; +} diff --git a/lib/libc/mingw/math/arm-common/expm1l.c b/lib/libc/mingw/math/arm-common/expm1l.c new file mode 100644 index 0000000000..baf4da23af --- /dev/null +++ b/lib/libc/mingw/math/arm-common/expm1l.c @@ -0,0 +1,16 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#include <math.h> + +long double expm1l(long double x) +{ +#if defined(__arm__) || defined(_ARM_) || defined(__aarch64__) || defined(_ARM64_) + return expm1(x); +#else +#error Not supported on your platform yet +#endif +} diff --git a/lib/libc/mingw/math/arm-common/ilogb.c b/lib/libc/mingw/math/arm-common/ilogb.c new file mode 100644 index 0000000000..546db42437 --- /dev/null +++ b/lib/libc/mingw/math/arm-common/ilogb.c @@ -0,0 +1,19 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#include <math.h> +#include <limits.h> + +int ilogb(double x) +{ + if (x == 0.0) + return FP_ILOGB0; + if (isinf(x)) + return INT_MAX; + if (isnan(x)) + return FP_ILOGBNAN; + return (int) logb(x); +} diff --git a/lib/libc/mingw/math/arm-common/ilogbf.c b/lib/libc/mingw/math/arm-common/ilogbf.c new file mode 100644 index 0000000000..3df38411ec --- /dev/null +++ b/lib/libc/mingw/math/arm-common/ilogbf.c @@ -0,0 +1,19 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#include <math.h> +#include <limits.h> + +int ilogbf(float x) +{ + if (x == 0.0) + return FP_ILOGB0; + if (isinf(x)) + return INT_MAX; + if (isnan(x)) + return FP_ILOGBNAN; + return (int) logbf(x); +} diff --git a/lib/libc/mingw/math/arm-common/ilogbl.c b/lib/libc/mingw/math/arm-common/ilogbl.c new file mode 100644 index 0000000000..1a6865d46e --- /dev/null +++ b/lib/libc/mingw/math/arm-common/ilogbl.c @@ -0,0 +1,16 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#include <math.h> + +int ilogbl(long double x) +{ +#if defined(__arm__) || defined(_ARM_) || defined(__aarch64__) || defined(_ARM64_) + return ilogb(x); +#else +#error Not supported on your platform yet +#endif +} diff --git a/lib/libc/mingw/math/arm-common/ldexpl.c b/lib/libc/mingw/math/arm-common/ldexpl.c new file mode 100644 index 0000000000..2c2a9e51a7 --- /dev/null +++ b/lib/libc/mingw/math/arm-common/ldexpl.c @@ -0,0 +1,16 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#include <math.h> + +long double ldexpl(long double x, int n) +{ +#if defined(__arm__) || defined(_ARM_) || defined(__aarch64__) || defined(_ARM64_) + return ldexp(x, n); +#else +#error Not supported on your platform yet +#endif +} diff --git a/lib/libc/mingw/math/arm-common/log1p.c b/lib/libc/mingw/math/arm-common/log1p.c new file mode 100644 index 0000000000..ea75d75b5d --- /dev/null +++ b/lib/libc/mingw/math/arm-common/log1p.c @@ -0,0 +1,12 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#include <math.h> + +double log1p(double x) +{ + return log(x + 1.0); +} diff --git a/lib/libc/mingw/math/arm-common/log1pf.c b/lib/libc/mingw/math/arm-common/log1pf.c new file mode 100644 index 0000000000..e947131260 --- /dev/null +++ b/lib/libc/mingw/math/arm-common/log1pf.c @@ -0,0 +1,15 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#include <math.h> + +float log1pf(float x) +{ + // Intentionally using double version of log() here in the float version of + // log1p, to preserve as much accuracy as possible in the intermediate + // parameter. + return log(x + 1.0); +} diff --git a/lib/libc/mingw/math/arm-common/log1pl.c b/lib/libc/mingw/math/arm-common/log1pl.c new file mode 100644 index 0000000000..c2b321a26d --- /dev/null +++ b/lib/libc/mingw/math/arm-common/log1pl.c @@ -0,0 +1,16 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#include <math.h> + +long double log1pl(long double x) +{ +#if defined(__arm__) || defined(_ARM_) || defined(__aarch64__) || defined(_ARM64_) + return log1p(x); +#else +#error Not supported on your platform yet +#endif +} diff --git a/lib/libc/mingw/math/arm-common/logb.c b/lib/libc/mingw/math/arm-common/logb.c new file mode 100644 index 0000000000..105a44c09f --- /dev/null +++ b/lib/libc/mingw/math/arm-common/logb.c @@ -0,0 +1,17 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#include <math.h> +#include <limits.h> + +extern double (* __MINGW_IMP_SYMBOL(_logb))(double); + +double logb(double x) +{ + if (isinf(x)) + return INFINITY; + return __MINGW_IMP_SYMBOL(_logb)(x); +} diff --git a/lib/libc/mingw/math/arm-common/logbf.c b/lib/libc/mingw/math/arm-common/logbf.c new file mode 100644 index 0000000000..565b66aebb --- /dev/null +++ b/lib/libc/mingw/math/arm-common/logbf.c @@ -0,0 +1,17 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#include <math.h> +#include <limits.h> + +extern float (* __MINGW_IMP_SYMBOL(_logbf))(float); + +float logbf(float x) +{ + if (isinf(x)) + return INFINITY; + return __MINGW_IMP_SYMBOL(_logbf)(x); +} diff --git a/lib/libc/mingw/math/arm-common/logbl.c b/lib/libc/mingw/math/arm-common/logbl.c new file mode 100644 index 0000000000..fca06754df --- /dev/null +++ b/lib/libc/mingw/math/arm-common/logbl.c @@ -0,0 +1,16 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#include <math.h> + +long double logbl(long double x) +{ +#if defined(__arm__) || defined(_ARM_) || defined(__aarch64__) || defined(_ARM64_) + return logb(x); +#else +#error Not supported on your platform yet +#endif +} diff --git a/lib/libc/mingw/math/arm-common/powf.c b/lib/libc/mingw/math/arm-common/powf.c new file mode 100644 index 0000000000..4d518fe9bb --- /dev/null +++ b/lib/libc/mingw/math/arm-common/powf.c @@ -0,0 +1,21 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#include <math.h> +#include <limits.h> + +extern float (* __MINGW_IMP_SYMBOL(powf))(float, float); + +float powf(float x, float y) +{ + if (x == 1.0f) + return 1.0f; + if (y == 0.0f) + return 1.0f; + if (x == -1.0f && isinf(y)) + return 1.0f; + return __MINGW_IMP_SYMBOL(powf)(x, y); +} diff --git a/lib/libc/mingw/math/arm-common/powl.c b/lib/libc/mingw/math/arm-common/powl.c new file mode 100644 index 0000000000..46e6b2d459 --- /dev/null +++ b/lib/libc/mingw/math/arm-common/powl.c @@ -0,0 +1,16 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#include <math.h> + +long double powl(long double x, long double y) +{ +#if defined(__arm__) || defined(_ARM_) || defined(__aarch64__) || defined(_ARM64_) + return pow(x, y); +#else +#error Not supported on your platform yet +#endif +} diff --git a/lib/libc/mingw/math/arm-common/remainder.c b/lib/libc/mingw/math/arm-common/remainder.c new file mode 100644 index 0000000000..b97ccf1339 --- /dev/null +++ b/lib/libc/mingw/math/arm-common/remainder.c @@ -0,0 +1,14 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#include <math.h> +#include <errno.h> + +double remainder(double x, double y) +{ + int iret; + return remquo(x, y, &iret); +} diff --git a/lib/libc/mingw/math/arm-common/remainderf.c b/lib/libc/mingw/math/arm-common/remainderf.c new file mode 100644 index 0000000000..1e2946c8b3 --- /dev/null +++ b/lib/libc/mingw/math/arm-common/remainderf.c @@ -0,0 +1,14 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#include <math.h> +#include <errno.h> + +float remainderf(float x, float y) +{ + int iret; + return remquof(x, y, &iret); +} diff --git a/lib/libc/mingw/math/arm-common/remainderl.c b/lib/libc/mingw/math/arm-common/remainderl.c new file mode 100644 index 0000000000..16fef94651 --- /dev/null +++ b/lib/libc/mingw/math/arm-common/remainderl.c @@ -0,0 +1,17 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#include <math.h> +#include <errno.h> + +long double remainderl(long double x, long double y) +{ +#if defined(__arm__) || defined(_ARM_) || defined(__aarch64__) || defined(_ARM64_) + return remainder(x, y); +#else +#error Not supported on your platform yet +#endif +} diff --git a/lib/libc/mingw/math/arm-common/remquol.c b/lib/libc/mingw/math/arm-common/remquol.c new file mode 100644 index 0000000000..c9fb1cbb53 --- /dev/null +++ b/lib/libc/mingw/math/arm-common/remquol.c @@ -0,0 +1,17 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#include <math.h> +#include <errno.h> + +long double remquol(long double x, long double y, int *quo) +{ +#if defined(__arm__) || defined(_ARM_) || defined(__aarch64__) || defined(_ARM64_) + return remquo(x, y, quo); +#else +#error Not supported on your platform yet +#endif +} diff --git a/lib/libc/mingw/math/arm-common/s_remquo.c b/lib/libc/mingw/math/arm-common/s_remquo.c new file mode 100644 index 0000000000..48b73177a4 --- /dev/null +++ b/lib/libc/mingw/math/arm-common/s_remquo.c @@ -0,0 +1,154 @@ +/* @(#)e_fmod.c 1.3 95/01/18 */ +/*- + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include <sys/cdefs.h> + +#include <float.h> + +#include <math.h> +#include "../bsd_private_base.h" + +static const double Zero[] = {0.0, -0.0,}; + +/* + * Return the IEEE remainder and set *quo to the last n bits of the + * quotient, rounded to the nearest integer. We choose n=31 because + * we wind up computing all the integer bits of the quotient anyway as + * a side-effect of computing the remainder by the shift and subtract + * method. In practice, this is far more bits than are needed to use + * remquo in reduction algorithms. + */ +double +remquo(double x, double y, int *quo) +{ + int32_t n,hx,hy,hz,ix,iy,sx,i; + u_int32_t lx,ly,lz,q,sxy; + + EXTRACT_WORDS(hx,lx,x); + EXTRACT_WORDS(hy,ly,y); + sxy = (hx ^ hy) & 0x80000000; + sx = hx&0x80000000; /* sign of x */ + hx ^=sx; /* |x| */ + hy &= 0x7fffffff; /* |y| */ + + /* purge off exception values */ + if((hy|ly)==0||(hx>=0x7ff00000)|| /* y=0,or x not finite */ + ((hy|((ly|-ly)>>31))>0x7ff00000)) /* or y is NaN */ + return nan_mix_op(x, y, *)/nan_mix_op(x, y, *); + if(hx<=hy) { + if((hx<hy)||(lx<ly)) { + q = 0; + goto fixup; /* |x|<|y| return x or x-y */ + } + if(lx==ly) { + *quo = (sxy ? -1 : 1); + return Zero[(u_int32_t)sx>>31]; /* |x|=|y| return x*0*/ + } + } + + /* determine ix = ilogb(x) */ + if(hx<0x00100000) { /* subnormal x */ + if(hx==0) { + for (ix = -1043, i=lx; i>0; i<<=1) ix -=1; + } else { + for (ix = -1022,i=(hx<<11); i>0; i<<=1) ix -=1; + } + } else ix = (hx>>20)-1023; + + /* determine iy = ilogb(y) */ + if(hy<0x00100000) { /* subnormal y */ + if(hy==0) { + for (iy = -1043, i=ly; i>0; i<<=1) iy -=1; + } else { + for (iy = -1022,i=(hy<<11); i>0; i<<=1) iy -=1; + } + } else iy = (hy>>20)-1023; + + /* set up {hx,lx}, {hy,ly} and align y to x */ + if(ix >= -1022) + hx = 0x00100000|(0x000fffff&hx); + else { /* subnormal x, shift x to normal */ + n = -1022-ix; + if(n<=31) { + hx = (hx<<n)|(lx>>(32-n)); + lx <<= n; + } else { + hx = lx<<(n-32); + lx = 0; + } + } + if(iy >= -1022) + hy = 0x00100000|(0x000fffff&hy); + else { /* subnormal y, shift y to normal */ + n = -1022-iy; + if(n<=31) { + hy = (hy<<n)|(ly>>(32-n)); + ly <<= n; + } else { + hy = ly<<(n-32); + ly = 0; + } + } + + /* fix point fmod */ + n = ix - iy; + q = 0; + while(n--) { + hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1; + if(hz<0){hx = hx+hx+(lx>>31); lx = lx+lx;} + else {hx = hz+hz+(lz>>31); lx = lz+lz; q++;} + q <<= 1; + } + hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1; + if(hz>=0) {hx=hz;lx=lz;q++;} + + /* convert back to floating value and restore the sign */ + if((hx|lx)==0) { /* return sign(x)*0 */ + q &= 0x7fffffff; + *quo = (sxy ? -q : q); + return Zero[(u_int32_t)sx>>31]; + } + while(hx<0x00100000) { /* normalize x */ + hx = hx+hx+(lx>>31); lx = lx+lx; + iy -= 1; + } + if(iy>= -1022) { /* normalize output */ + hx = ((hx-0x00100000)|((iy+1023)<<20)); + } else { /* subnormal output */ + n = -1022 - iy; + if(n<=20) { + lx = (lx>>n)|((u_int32_t)hx<<(32-n)); + hx >>= n; + } else if (n<=31) { + lx = (hx<<(32-n))|(lx>>n); hx = 0; + } else { + lx = hx>>(n-32); hx = 0; + } + } +fixup: + INSERT_WORDS(x,hx,lx); + y = fabs(y); + if (y < 0x1p-1021) { + if (x+x>y || (x+x==y && (q & 1))) { + q++; + x-=y; + } + } else if (x>0.5*y || (x==0.5*y && (q & 1))) { + q++; + x-=y; + } + GET_HIGH_WORD(hx,x); + SET_HIGH_WORD(x,hx^sx); + q &= 0x7fffffff; + *quo = (sxy ? -q : q); + return x; +} diff --git a/lib/libc/mingw/math/arm-common/s_remquof.c b/lib/libc/mingw/math/arm-common/s_remquof.c new file mode 100644 index 0000000000..f2a4e0d081 --- /dev/null +++ b/lib/libc/mingw/math/arm-common/s_remquof.c @@ -0,0 +1,121 @@ +/* @(#)e_fmod.c 1.3 95/01/18 */ +/*- + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include <sys/cdefs.h> + +#include <math.h> +#include "../bsd_private_base.h" + +static const float Zero[] = {0.0, -0.0,}; + +/* + * Return the IEEE remainder and set *quo to the last n bits of the + * quotient, rounded to the nearest integer. We choose n=31 because + * we wind up computing all the integer bits of the quotient anyway as + * a side-effect of computing the remainder by the shift and subtract + * method. In practice, this is far more bits than are needed to use + * remquo in reduction algorithms. + */ +float +remquof(float x, float y, int *quo) +{ + int32_t n,hx,hy,hz,ix,iy,sx,i; + u_int32_t q,sxy; + + GET_FLOAT_WORD(hx,x); + GET_FLOAT_WORD(hy,y); + sxy = (hx ^ hy) & 0x80000000; + sx = hx&0x80000000; /* sign of x */ + hx ^=sx; /* |x| */ + hy &= 0x7fffffff; /* |y| */ + + /* purge off exception values */ + if(hy==0||hx>=0x7f800000||hy>0x7f800000) /* y=0,NaN;or x not finite */ + return nan_mix_op(x, y, *)/nan_mix_op(x, y, *); + if(hx<hy) { + q = 0; + goto fixup; /* |x|<|y| return x or x-y */ + } else if(hx==hy) { + *quo = (sxy ? -1 : 1); + return Zero[(u_int32_t)sx>>31]; /* |x|=|y| return x*0*/ + } + + /* determine ix = ilogb(x) */ + if(hx<0x00800000) { /* subnormal x */ + for (ix = -126,i=(hx<<8); i>0; i<<=1) ix -=1; + } else ix = (hx>>23)-127; + + /* determine iy = ilogb(y) */ + if(hy<0x00800000) { /* subnormal y */ + for (iy = -126,i=(hy<<8); i>0; i<<=1) iy -=1; + } else iy = (hy>>23)-127; + + /* set up {hx,lx}, {hy,ly} and align y to x */ + if(ix >= -126) + hx = 0x00800000|(0x007fffff&hx); + else { /* subnormal x, shift x to normal */ + n = -126-ix; + hx <<= n; + } + if(iy >= -126) + hy = 0x00800000|(0x007fffff&hy); + else { /* subnormal y, shift y to normal */ + n = -126-iy; + hy <<= n; + } + + /* fix point fmod */ + n = ix - iy; + q = 0; + while(n--) { + hz=hx-hy; + if(hz<0) hx = hx << 1; + else {hx = hz << 1; q++;} + q <<= 1; + } + hz=hx-hy; + if(hz>=0) {hx=hz;q++;} + + /* convert back to floating value and restore the sign */ + if(hx==0) { /* return sign(x)*0 */ + q &= 0x7fffffff; + *quo = (sxy ? -q : q); + return Zero[(u_int32_t)sx>>31]; + } + while(hx<0x00800000) { /* normalize x */ + hx <<= 1; + iy -= 1; + } + if(iy>= -126) { /* normalize output */ + hx = ((hx-0x00800000)|((iy+127)<<23)); + } else { /* subnormal output */ + n = -126 - iy; + hx >>= n; + } +fixup: + SET_FLOAT_WORD(x,hx); + y = fabsf(y); + if (y < 0x1p-125f) { + if (x+x>y || (x+x==y && (q & 1))) { + q++; + x-=y; + } + } else if (x>0.5f*y || (x==0.5f*y && (q & 1))) { + q++; + x-=y; + } + GET_FLOAT_WORD(hx,x); + SET_FLOAT_WORD(x,hx^sx); + q &= 0x7fffffff; + *quo = (sxy ? -q : q); + return x; +} diff --git a/src/mingw.zig b/src/mingw.zig index 79c4327c4c..a4f2f0cf91 100644 --- a/src/mingw.zig +++ b/src/mingw.zig @@ -1018,7 +1018,44 @@ const mingwex_x86_src = [_][]const u8{ "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "trunc.S", }; -const mingwex_arm32_src = [_][]const u8{ +const arm_common = [_][]const u8{ + "math" ++ path.sep_str ++ "arm-common" ++ path.sep_str ++ "acosh.c", + "math" ++ path.sep_str ++ "arm-common" ++ path.sep_str ++ "acoshf.c", + "math" ++ path.sep_str ++ "arm-common" ++ path.sep_str ++ "acoshl.c", + "math" ++ path.sep_str ++ "arm-common" ++ path.sep_str ++ "asinh.c", + "math" ++ path.sep_str ++ "arm-common" ++ path.sep_str ++ "asinhf.c", + "math" ++ path.sep_str ++ "arm-common" ++ path.sep_str ++ "asinhl.c", + "math" ++ path.sep_str ++ "arm-common" ++ path.sep_str ++ "atanh.c", + "math" ++ path.sep_str ++ "arm-common" ++ path.sep_str ++ "atanhf.c", + "math" ++ path.sep_str ++ "arm-common" ++ path.sep_str ++ "atanhl.c", + "math" ++ path.sep_str ++ "arm-common" ++ path.sep_str ++ "copysignl.c", + "math" ++ path.sep_str ++ "arm-common" ++ path.sep_str ++ "expm1.c", + "math" ++ path.sep_str ++ "arm-common" ++ path.sep_str ++ "expm1f.c", + "math" ++ path.sep_str ++ "arm-common" ++ path.sep_str ++ "expm1l.c", + "math" ++ path.sep_str ++ "arm-common" ++ path.sep_str ++ "ilogb.c", + "math" ++ path.sep_str ++ "arm-common" ++ path.sep_str ++ "ilogbf.c", + "math" ++ path.sep_str ++ "arm-common" ++ path.sep_str ++ "ilogbl.c", + "math" ++ path.sep_str ++ "arm-common" ++ path.sep_str ++ "ldexpl.c", + "math" ++ path.sep_str ++ "arm-common" ++ path.sep_str ++ "log1p.c", + "math" ++ path.sep_str ++ "arm-common" ++ path.sep_str ++ "log1pf.c", + "math" ++ path.sep_str ++ "arm-common" ++ path.sep_str ++ "log1pl.c", + "math" ++ path.sep_str ++ "arm-common" ++ path.sep_str ++ "log2.c", + "math" ++ path.sep_str ++ "arm-common" ++ path.sep_str ++ "logb.c", + "math" ++ path.sep_str ++ "arm-common" ++ path.sep_str ++ "logbf.c", + "math" ++ path.sep_str ++ "arm-common" ++ path.sep_str ++ "logbl.c", + "math" ++ path.sep_str ++ "arm-common" ++ path.sep_str ++ "pow.c", + "math" ++ path.sep_str ++ "arm-common" ++ path.sep_str ++ "powf.c", + "math" ++ path.sep_str ++ "arm-common" ++ path.sep_str ++ "powl.c", + "math" ++ path.sep_str ++ "arm-common" ++ path.sep_str ++ "remainder.c", + "math" ++ path.sep_str ++ "arm-common" ++ path.sep_str ++ "remainderf.c", + "math" ++ path.sep_str ++ "arm-common" ++ path.sep_str ++ "remainderl.c", + "math" ++ path.sep_str ++ "arm-common" ++ path.sep_str ++ "remquol.c", + "math" ++ path.sep_str ++ "arm-common" ++ path.sep_str ++ "s_remquo.c", + "math" ++ path.sep_str ++ "arm-common" ++ path.sep_str ++ "s_remquof.c", + "math" ++ path.sep_str ++ "arm-common" ++ path.sep_str ++ "scalbn.c", +}; + +const mingwex_arm32_src = arm_common ++ [_][]const u8{ "math" ++ path.sep_str ++ "arm" ++ path.sep_str ++ "_chgsignl.S", "math" ++ path.sep_str ++ "arm" ++ path.sep_str ++ "s_rint.c", "math" ++ path.sep_str ++ "arm" ++ path.sep_str ++ "s_rintf.c", @@ -1033,11 +1070,8 @@ const mingwex_arm32_src = [_][]const u8{ "math" ++ path.sep_str ++ "arm" ++ path.sep_str ++ "s_truncf.c", }; -const mingwex_arm64_src = [_][]const u8{ +const mingwex_arm64_src = arm_common ++ [_][]const u8{ "misc" ++ path.sep_str ++ "initenv.c", - "math" ++ path.sep_str ++ "arm-common" ++ path.sep_str ++ "log2.c", - "math" ++ path.sep_str ++ "arm-common" ++ path.sep_str ++ "pow.c", - "math" ++ path.sep_str ++ "arm-common" ++ path.sep_str ++ "scalbn.c", "math" ++ path.sep_str ++ "arm64" ++ path.sep_str ++ "_chgsignl.S", "math" ++ path.sep_str ++ "arm64" ++ path.sep_str ++ "rint.c", "math" ++ path.sep_str ++ "arm64" ++ path.sep_str ++ "rintf.c", |
