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
+}