*** empty log message ***
authorTorbjorn Granlund <tege@gnu.org>
Tue, 7 Jul 1992 19:58:52 +0000 (19:58 +0000)
committerTorbjorn Granlund <tege@gnu.org>
Tue, 7 Jul 1992 19:58:52 +0000 (19:58 +0000)
From-SVN: r1504

gcc/libgcc2.c

index 8e9ed05875bf00883bff879e8d8582b7ca017496..8c70133dd895e69fadaa2d72cac6daa227255612 100644 (file)
@@ -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
 \f
+#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
+\f
 #ifdef L_udivmoddi4
 static const UQItype __clz_tab[] =
 {