aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorTorbjorn Granlund <tege@gnu.org>1992-07-07 19:58:52 +0000
committerTorbjorn Granlund <tege@gnu.org>1992-07-07 19:58:52 +0000
commit431b1ee0e00345dda0bf4b8d2b60ea7d5e6feeab (patch)
tree2714ddc20da697d1d08c5c1bd09396268ed7d9f9 /gcc
parentab49538861468caa8bb7d1cd6df050e614ffab1c (diff)
downloadgcc-431b1ee0e00345dda0bf4b8d2b60ea7d5e6feeab.zip
gcc-431b1ee0e00345dda0bf4b8d2b60ea7d5e6feeab.tar.gz
gcc-431b1ee0e00345dda0bf4b8d2b60ea7d5e6feeab.tar.bz2
*** empty log message ***
From-SVN: r1504
Diffstat (limited to 'gcc')
-rw-r--r--gcc/libgcc2.c102
1 files changed, 101 insertions, 1 deletions
diff --git a/gcc/libgcc2.c b/gcc/libgcc2.c
index 8e9ed05..8c70133 100644
--- a/gcc/libgcc2.c
+++ b/gcc/libgcc2.c
@@ -92,7 +92,7 @@ typedef union
DItype ll;
} DIunion;
-#if defined (L_udivmoddi4) || defined (L_muldi3)
+#if defined (L_udivmoddi4) || defined (L_muldi3) || defined (L_udiv_using_sdiv)
#include "longlong.h"
@@ -269,6 +269,106 @@ __muldi3 (u, v)
}
#endif
+#ifdef L_udiv_using_sdiv
+USItype
+__udiv_using_sdiv (rp, a1, a0, d)
+ USItype *rp, a1, a0, d;
+{
+ USItype q, r;
+ USItype c0, c1, b1;
+
+ if ((SItype) d >= 0)
+ {
+ if (a1 < d - a1 - (a0 >> 31))
+ {
+ /* dividend, divisor, and quotient are nonnegative */
+ sdiv_qrnnd (q, r, a1, a0, d);
+ }
+ else
+ {
+ /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
+ sub_ddmmss (c1, c0, a1, a0, d >> 1, d << 31);
+ /* Divide (c1*2^32 + c0) by d */
+ sdiv_qrnnd (q, r, c1, c0, d);
+ /* Add 2^31 to quotient */
+ q += 1 << 31;
+ }
+ }
+ else
+ {
+ b1 = d >> 1; /* d/2, between 2^30 and 2^31 - 1 */
+ c1 = a1 >> 1; /* A/2 */
+ c0 = (a1 << 31) + (a0 >> 1);
+
+ if (a1 < b1) /* A < 2^32*b1, so A/2 < 2^31*b1 */
+ {
+ sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
+
+ r = 2*r + (a0 & 1); /* Remainder from A/(2*b1) */
+ if ((d & 1) != 0)
+ {
+ if (r >= q)
+ r = r - q;
+ else if (q - r <= d)
+ {
+ r = r - q + d;
+ q--;
+ }
+ else
+ {
+ r = r - q + 2*d;
+ q -= 2;
+ }
+ }
+ }
+ else if (c1 < b1) /* So 2^31 <= (A/2)/b1 < 2^32 */
+ {
+ c1 = (b1 - 1) - c1;
+ c0 = ~c0; /* logical NOT */
+
+ sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
+
+ q = ~q; /* (A/2)/b1 */
+ r = (b1 - 1) - r;
+
+ r = 2*r + (a0 & 1); /* A/(2*b1) */
+
+ if ((d & 1) != 0)
+ {
+ if (r >= q)
+ r = r - q;
+ else if (q - r <= d)
+ {
+ r = r - q + d;
+ q--;
+ }
+ else
+ {
+ r = r - q + 2*d;
+ q -= 2;
+ }
+ }
+ }
+ else /* Implies c1 = b1 */
+ { /* Hence a1 = d - 1 = 2*b1 - 1 */
+ if (a0 >= -d)
+ {
+ q = -1;
+ r = a0 + d;
+ }
+ else
+ {
+ q = -2;
+ r = a0 + 2*d;
+ }
+ }
+ }
+
+ *rp = r;
+ return q;
+}
+#endif
+
#ifdef L_udivmoddi4
static const UQItype __clz_tab[] =
{