summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AK/StdLibExtras.cpp28
1 files changed, 25 insertions, 3 deletions
diff --git a/AK/StdLibExtras.cpp b/AK/StdLibExtras.cpp
index 31b3b9221c..164c2b5ee8 100644
--- a/AK/StdLibExtras.cpp
+++ b/AK/StdLibExtras.cpp
@@ -99,7 +99,7 @@ static int32_t signed_modulo64(int64_t n, int64_t d)
int64_t __divdi3(int64_t n, int64_t d)
{
- return signed_divide64 (n, d);
+ return signed_divide64(n, d);
}
int64_t __moddi3(int64_t n, int64_t d)
@@ -119,8 +119,30 @@ uint64_t __umoddi3(uint64_t n, uint64_t d)
uint64_t __udivmoddi4(uint64_t n, uint64_t d, uint64_t* r)
{
- *r = unsigned_modulo64(n, d);
- return unsigned_divide64(n, d);
+ uint64_t q = 0;
+ uint64_t qbit = 1;
+
+ if (!d)
+ return 1 / ((unsigned)d);
+
+ while ((int64_t)d >= 0) {
+ d <<= 1;
+ qbit <<= 1;
+ }
+
+ while (qbit) {
+ if (d <= n) {
+ n -= d;
+ q += qbit;
+ }
+ d >>= 1;
+ qbit >>= 1;
+ }
+
+ if (r)
+ *r = n;
+
+ return q;
}
}