aboutsummaryrefslogtreecommitdiff
path: root/source/math.c
diff options
context:
space:
mode:
authorToni Uhlig <matzeton@googlemail.com>2020-05-24 16:48:22 +0200
committerToni Uhlig <matzeton@googlemail.com>2020-05-25 21:57:14 +0200
commit31c69b6ca1b91e7fd9fd8e14082fd2584c5f538c (patch)
tree16e789c7d68608831b498f41f54d9482b82a711a /source/math.c
first public release
Signed-off-by: Toni Uhlig <matzeton@googlemail.com>
Diffstat (limited to 'source/math.c')
-rw-r--r--source/math.c135
1 files changed, 135 insertions, 0 deletions
diff --git a/source/math.c b/source/math.c
new file mode 100644
index 0000000..c8eafee
--- /dev/null
+++ b/source/math.c
@@ -0,0 +1,135 @@
+#include "compat.h"
+#include "math.h"
+
+
+uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t * rem_p)
+{
+ uint64_t quot = 0, qbit = 1;
+
+ if (den == 0) {
+ asm volatile ("int $0");
+ return 0; /* If trap returns... */
+ }
+
+ /* Left-justify denominator and count shift */
+ while ((int64_t) den >= 0) {
+ den <<= 1;
+ qbit <<= 1;
+ }
+
+ while (qbit) {
+ if (den <= num) {
+ num -= den;
+ quot += qbit;
+ }
+ den >>= 1;
+ qbit >>= 1;
+ }
+
+ if (rem_p)
+ *rem_p = num;
+
+ return quot;
+}
+
+/* slightly modified version from
+ * https://code.google.com/p/embox/source/browse/trunk/embox/src/lib/gcc
+ * _thx_
+ */
+
+UINT64 __udivdi3(UINT64 num, UINT64 den)
+{
+ UINT64 result = 0;
+ int steps;
+
+ if (den == 0)
+ {
+ return 0;
+ }
+
+ steps = 0;
+ result = 0;
+
+ while (!(den & 0x8000000000000000))
+ {
+ den <<= 1;
+ ++steps;
+ }
+
+ do
+ {
+ result <<= 1;
+ if (num >= den)
+ {
+ result |= 1;
+ num -= den;
+ }
+ den >>= 1;
+ }
+ while (steps--);
+
+ return result;
+}
+
+INT64 __divdi3(INT64 num, INT64 den)
+{
+ INT64 quot;
+ int neg;
+
+ num = num < 0 ? (neg = 1, -num) : (neg = 0, num);
+ den = den < 0 ? (neg ^= 1, -den) : den;
+
+ quot = __udivdi3(num, den);
+
+ return neg ? -quot : quot;
+}
+
+INT64 __moddi3(INT64 num, INT64 den)
+{
+ INT64 rem;
+ int neg;
+
+ num = num < 0 ? (neg = 1, -num) : (neg = 0, num);
+ den = den < 0 ? (neg ^= 1, -den) : den;
+
+ rem = __umoddi3(num, den);
+
+ return neg ? -rem : rem;
+}
+
+UINT64 __umoddi3(UINT64 num, UINT64 den)
+{
+ int steps;
+
+ if (den == 0)
+ {
+ return 0;
+ }
+
+ steps = 0;
+
+ while (!(den & 0x8000000000000000))
+ {
+ den <<= 1;
+ ++steps;
+ }
+
+ do
+ {
+ if (num >= den)
+ {
+ num -= den;
+ }
+ den >>= 1;
+ }
+ while (steps--);
+
+ return num;
+}
+
+size_t __pow(size_t x, size_t n)
+{
+ if (n > 0) {
+ return x*__pow(x, n-1);
+ } else return 1;
+}