crt: arm: Add implementations of remainder and remquo for msvcrt Signed-off-by: Martin Storsjö <martin@martin.st>
diff --git a/mingw-w64-crt/Makefile.am b/mingw-w64-crt/Makefile.am index 3fea74e..64d627e 100644 --- a/mingw-w64-crt/Makefile.am +++ b/mingw-w64-crt/Makefile.am
@@ -259,6 +259,12 @@ math/arm/truncf.S \ math/arm-common/copysignl.c \ math/arm-common/log2.c \ + math/arm-common/remainder.c \ + math/arm-common/remainderf.c \ + math/arm-common/remainderl.c \ + math/arm-common/remquo.c \ + math/arm-common/remquof.c \ + math/arm-common/remquol.c \ math/arm-common/scalbn.c endif @@ -266,6 +272,12 @@ $(src_msvcrt) \ math/arm-common/copysignl.c \ math/arm-common/log2.c \ + math/arm-common/remainder.c \ + math/arm-common/remainderf.c \ + math/arm-common/remainderl.c \ + math/arm-common/remquo.c \ + math/arm-common/remquof.c \ + math/arm-common/remquol.c \ math/arm-common/scalbn.c \ math/arm64/exp2.S \ math/arm64/exp2f.S \
diff --git a/mingw-w64-crt/math/arm-common/remainder.c b/mingw-w64-crt/math/arm-common/remainder.c new file mode 100644 index 0000000..b97ccf1 --- /dev/null +++ b/mingw-w64-crt/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/mingw-w64-crt/math/arm-common/remainderf.c b/mingw-w64-crt/math/arm-common/remainderf.c new file mode 100644 index 0000000..1e2946c --- /dev/null +++ b/mingw-w64-crt/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/mingw-w64-crt/math/arm-common/remainderl.c b/mingw-w64-crt/math/arm-common/remainderl.c new file mode 100644 index 0000000..16fef94 --- /dev/null +++ b/mingw-w64-crt/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/mingw-w64-crt/math/arm-common/remquo.c b/mingw-w64-crt/math/arm-common/remquo.c new file mode 100644 index 0000000..6a97ade --- /dev/null +++ b/mingw-w64-crt/math/arm-common/remquo.c
@@ -0,0 +1,31 @@ +/** + * 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 remquo(double x, double y, int *quo) +{ + if (isinf(x) || y == 0) + return NAN; + double div = x/y; + double integral; + double frac = modf(div, &integral); + int iintegral = (int)integral; + if (frac == 0.5) { + if (iintegral & 1) + *quo = iintegral + 1; + else + *quo = iintegral; + } else if (frac == -0.5) { + if (iintegral & 1) + *quo = iintegral - 1; + else + *quo = iintegral; + } else + *quo = round(div); + return x - *quo * y; +}
diff --git a/mingw-w64-crt/math/arm-common/remquof.c b/mingw-w64-crt/math/arm-common/remquof.c new file mode 100644 index 0000000..c395b2b --- /dev/null +++ b/mingw-w64-crt/math/arm-common/remquof.c
@@ -0,0 +1,31 @@ +/** + * 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 remquof(float x, float y, int *quo) +{ + if (isinf(x) || y == 0) + return NAN; + float div = x/y; + float integral; + float frac = modff(div, &integral); + int iintegral = (int)integral; + if (frac == 0.5) { + if (iintegral & 1) + *quo = iintegral + 1; + else + *quo = iintegral; + } else if (frac == -0.5) { + if (iintegral & 1) + *quo = iintegral - 1; + else + *quo = iintegral; + } else + *quo = roundf(div); + return x - *quo * y; +}
diff --git a/mingw-w64-crt/math/arm-common/remquol.c b/mingw-w64-crt/math/arm-common/remquol.c new file mode 100644 index 0000000..c9fb1cb --- /dev/null +++ b/mingw-w64-crt/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 +}