aboutsummaryrefslogtreecommitdiffstats
path: root/runtime/mppa_k1c/i64_udivmod.c
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/mppa_k1c/i64_udivmod.c')
-rw-r--r--runtime/mppa_k1c/i64_udivmod.c25
1 files changed, 23 insertions, 2 deletions
diff --git a/runtime/mppa_k1c/i64_udivmod.c b/runtime/mppa_k1c/i64_udivmod.c
index 20d8c976..d94d3f23 100644
--- a/runtime/mppa_k1c/i64_udivmod.c
+++ b/runtime/mppa_k1c/i64_udivmod.c
@@ -26,6 +26,25 @@ udivmoddi4(unsigned long long num, unsigned long long den, int modwanted)
#else
+/* Number of leading zeroes */
+static int i64_nlzd(unsigned x)
+{
+ if (x == 0) return 64;
+ int n = 0;
+ if (x <= 0x00000000FFFFFFFFl) { n += 32; x <<= 32; }
+ if (x <= 0x0000FFFFFFFFFFFFl) { n += 16; x <<= 16; }
+ if (x <= 0x00FFFFFFFFFFFFFFl) { n += 8; x <<= 8; }
+ if (x <= 0x0FFFFFFFFFFFFFFFl) { n += 4; x <<= 4; }
+ if (x <= 0x3FFFFFFFFFFFFFFFl) { n += 2; x <<= 2; }
+ if (x <= 0x7FFFFFFFFFFFFFFFl) { n += 1; x <<= 1; }
+ return n;
+}
+
+static unsigned long long i64_stsud(unsigned rz, unsigned ry)
+{
+ return ry >= rz ? ry - rz << 1 | 1 : ry << 1;
+}
+
/* THIS IS THE PREVIOUS VERSION, USED ON BOSTAN AND ANDEY */
unsigned long long
udivmoddi4(unsigned long long num, unsigned long long den, int modwanted)
@@ -33,7 +52,8 @@ udivmoddi4(unsigned long long num, unsigned long long den, int modwanted)
unsigned long long r = num, q = 0;
if(den <= r) {
- unsigned k = __builtin_clzll (den) - __builtin_clzll (r);
+ //unsigned k = __builtin_clzll (den) - __builtin_clzll (r);
+ unsigned k = i64_nlzd(den) - i64_nlzd(r);
den = den << k;
if(r >= den) {
r = r - den;
@@ -43,7 +63,8 @@ udivmoddi4(unsigned long long num, unsigned long long den, int modwanted)
unsigned i = k;
den = den >> 1;
do {
- r = __builtin_k1_stsud (den, r);
+ r = i64_stsud(den, r);
+ //r = __builtin_k1_stsud (den, r);
i--;
} while (i!= 0);
q = q + r;