summaryrefslogtreecommitdiff
path: root/newlib/libc/machine/w65/divsi3.c
diff options
context:
space:
mode:
Diffstat (limited to 'newlib/libc/machine/w65/divsi3.c')
-rw-r--r--newlib/libc/machine/w65/divsi3.c134
1 files changed, 134 insertions, 0 deletions
diff --git a/newlib/libc/machine/w65/divsi3.c b/newlib/libc/machine/w65/divsi3.c
new file mode 100644
index 00000000000..bf749923ca5
--- /dev/null
+++ b/newlib/libc/machine/w65/divsi3.c
@@ -0,0 +1,134 @@
+
+#define divnorm(num, den, sign) \
+{ \
+ if (num < 0) \
+ { \
+ num = -num; \
+ sign = 1; \
+ } \
+ else \
+ { \
+ sign = 0; \
+ } \
+ \
+ if (den < 0) \
+ { \
+ den = - den; \
+ sign = 1 - sign; \
+ } \
+}
+
+
+
+
+
+static unsigned long
+divmodsi4(int modwanted, unsigned long num, unsigned long den)
+{
+ long int bit = 1;
+ long int res = 0;
+ long prevden;
+ 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;
+}
+
+
+#define exitdiv(sign, res) if (sign) { res = - res;} return res;
+
+long
+__modsi3 (long numerator, long denominator)
+{
+ int sign = 0;
+ long dividend;
+ long modul;
+
+
+ if (numerator < 0)
+ {
+ numerator = -numerator;
+ sign = 1;
+ }
+ if (denominator < 0)
+ {
+ denominator = -denominator;
+ }
+
+ modul = divmodsi4 (1, numerator, denominator);
+ if (sign)
+ return - modul;
+ return modul;
+}
+
+
+long
+__divsi3 (long numerator, long denominator)
+{
+ int sign;
+ long dividend;
+ long modul;
+ divnorm (numerator, denominator, sign);
+
+ dividend = divmodsi4 (0, numerator, denominator);
+ exitdiv (sign, dividend);
+}
+
+long
+__umodsi3 (unsigned long numerator, unsigned long denominator)
+{
+ long dividend;
+ long modul;
+
+modul= divmodsi4 (1, numerator, denominator);
+ return modul;
+}
+
+long
+__udivsi3 (unsigned long numerator, unsigned long denominator)
+{
+ int sign;
+ long dividend;
+ long modul;
+ dividend = divmodsi4 (0, numerator, denominator);
+ return dividend;
+}
+
+
+
+
+
+
+#ifdef TEST
+
+
+
+main ()
+{
+ long int i, j, k, m;
+ for (i = -10000; i < 10000; i += 8)
+ {
+ for (j = -10000; j < 10000; j += 11)
+ {
+ k = i / j;
+ m = __divsi3 (i, j);
+ if (k != m)
+ printf ("fail %d %d %d %d\n", i, j, k, m);
+ }
+ }
+}
+
+#endif