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.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/runtime/mppa_k1c/i64_udivmod.c b/runtime/mppa_k1c/i64_udivmod.c
new file mode 100644
index 00000000..20d8c976
--- /dev/null
+++ b/runtime/mppa_k1c/i64_udivmod.c
@@ -0,0 +1,58 @@
+#ifdef __K1_TINYK1__
+unsigned long long
+udivmoddi4(unsigned long long num, unsigned long long den, int modwanted)
+{
+ unsigned long long bit = 1;
+ unsigned long long res = 0;
+
+ while (den < num && bit && !(den & (1L<<31)))
+ {
+ den <<=1;
+ bit <<=1;
+ }
+ while (bit)
+ {
+ if (num >= den)
+ {
+ num -= den;
+ res |= bit;
+ }
+ bit >>=1;
+ den >>=1;
+ }
+ if (modwanted) return num;
+ return res;
+}
+
+#else
+
+/* THIS IS THE PREVIOUS VERSION, USED ON BOSTAN AND ANDEY */
+unsigned long long
+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);
+ den = den << k;
+ if(r >= den) {
+ r = r - den;
+ q = 1LL << k;
+ }
+ if(k != 0) {
+ unsigned i = k;
+ den = den >> 1;
+ do {
+ r = __builtin_k1_stsud (den, r);
+ i--;
+ } while (i!= 0);
+ q = q + r;
+ r = r >> k;
+ q = q - (r << k);
+ }
+ }
+
+ return modwanted ? r : q;
+}
+#endif /* __K1_TINYK1__ */
+