]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tm.texi.in (TARGET_HAS_NO_HW_DIVIDE): Define.
authorKugan Vivekanandarajah <kuganv@linaro.org>
Wed, 27 Nov 2013 12:17:05 +0000 (12:17 +0000)
committerChristophe Lyon <clyon@gcc.gnu.org>
Wed, 27 Nov 2013 12:17:05 +0000 (13:17 +0100)
2013-11-27  Kugan Vivekanandarajah  <kuganv@linaro.org>

gcc/
* doc/tm.texi.in (TARGET_HAS_NO_HW_DIVIDE): Define.
* doc/tm.texi (TARGET_HAS_NO_HW_DIVIDE): Regenerate.

libgcc/
* libgcc2.c (__udivmoddi4): Define new implementation when
TARGET_HAS_NO_HW_DIVIDE is defined, for processors without any
divide instructions.

From-SVN: r205444

gcc/ChangeLog
gcc/doc/tm.texi
gcc/doc/tm.texi.in
libgcc/ChangeLog
libgcc/libgcc2.c

index 31e9670fa8928e689c673d2898cc32c4fc3abefe..15ce5e698f26dc3eb2e1318805650f503bdf7cc5 100644 (file)
@@ -1,3 +1,8 @@
+2013-11-27  Kugan Vivekanandarajah  <kuganv@linaro.org>
+
+       * doc/tm.texi.in (TARGET_HAS_NO_HW_DIVIDE): Define.
+       * doc/tm.texi (TARGET_HAS_NO_HW_DIVIDE): Regenerate.
+
 2013-11-27  Marek Polacek  <polacek@redhat.com>
 
        PR sanitizer/59306
index 966576fe721ba22371697339f2d2f40bbd265a56..68b59b9975b0bed4288cb014176f38db0ef1376f 100644 (file)
@@ -5365,6 +5365,14 @@ If this macro evaluates to @code{false} the comparison functions return
 in @file{libgcc.a}, you do not need to define this macro.
 @end defmac
 
+@defmac TARGET_HAS_NO_HW_DIVIDE
+This macro should be defined if the target has no hardware divide
+instructions.  If this macro is defined, GCC will use an algorithm which
+make use of simple logical and arithmetic operations for 64-bit
+division.  If the macro is not defined, GCC will use an algorithm which
+make use of a 64-bit by 32-bit divide primitive.
+@end defmac
+
 @cindex @code{EDOM}, implicit usage
 @findex matherr
 @defmac TARGET_EDOM
index 63f4edb3a4324f77877fe94bdb22f5d87c8f1eea..1bb3806c5df4499a22c4be0154e568778425bf61 100644 (file)
@@ -4205,6 +4205,14 @@ If this macro evaluates to @code{false} the comparison functions return
 in @file{libgcc.a}, you do not need to define this macro.
 @end defmac
 
+@defmac TARGET_HAS_NO_HW_DIVIDE
+This macro should be defined if the target has no hardware divide
+instructions.  If this macro is defined, GCC will use an algorithm which
+make use of simple logical and arithmetic operations for 64-bit
+division.  If the macro is not defined, GCC will use an algorithm which
+make use of a 64-bit by 32-bit divide primitive.
+@end defmac
+
 @cindex @code{EDOM}, implicit usage
 @findex matherr
 @defmac TARGET_EDOM
index a1f84555826a9bdfef4a44b04d63cd918eca6c65..7e7aa4a40d1a84fd2620d23a685a799191fb79ad 100644 (file)
@@ -1,3 +1,9 @@
+2013-11-27  Kugan Vivekanandarajah  <kuganv@linaro.org>
+
+       * libgcc2.c (__udivmoddi4): Define new implementation when
+       TARGET_HAS_NO_HW_DIVIDE is defined, for processors without any
+       divide instructions.
+
 2013-11-25  Oleg Endo  <olegendo@gcc.gnu.org>
 
        * config/sh/crt1.S (start): Don't do VBR_SETUP for SH2E.
index bec411be0b53e418c67c3ecae993a66c29890094..8c4cc6a316c7d1e95a113d6b5da5e6eaf73b053b 100644 (file)
@@ -934,6 +934,74 @@ __parityDI2 (UDWtype x)
 #endif
 
 #ifdef L_udivmoddi4
+#ifdef TARGET_HAS_NO_HW_DIVIDE
+
+#if (defined (L_udivdi3) || defined (L_divdi3) || \
+     defined (L_umoddi3) || defined (L_moddi3))
+static inline __attribute__ ((__always_inline__))
+#endif
+UDWtype
+__udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
+{
+  UDWtype q = 0, r = n, y = d;
+  UWtype lz1, lz2, i, k;
+
+  /* Implements align divisor shift dividend method. This algorithm
+     aligns the divisor under the dividend and then perform number of
+     test-subtract iterations which shift the dividend left. Number of
+     iterations is k + 1 where k is the number of bit positions the
+     divisor must be shifted left  to align it under the dividend.
+     quotient bits can be saved in the rightmost positions of the dividend
+     as it shifts left on each test-subtract iteration. */
+
+  if (y <= r)
+    {
+      lz1 = __builtin_clzll (d);
+      lz2 = __builtin_clzll (n);
+
+      k = lz1 - lz2;
+      y = (y << k);
+
+      /* Dividend can exceed 2 ^ (width − 1) − 1 but still be less than the
+        aligned divisor. Normal iteration can drops the high order bit
+        of the dividend. Therefore, first test-subtract iteration is a
+        special case, saving its quotient bit in a separate location and
+        not shifting the dividend. */
+      if (r >= y)
+       {
+         r = r - y;
+         q =  (1ULL << k);
+       }
+
+      if (k > 0)
+       {
+         y = y >> 1;
+
+         /* k additional iterations where k regular test subtract shift
+           dividend iterations are done.  */
+         i = k;
+         do
+           {
+             if (r >= y)
+               r = ((r - y) << 1) + 1;
+             else
+               r =  (r << 1);
+             i = i - 1;
+           } while (i != 0);
+
+         /* First quotient bit is combined with the quotient bits resulting
+            from the k regular iterations.  */
+         q = q + r;
+         r = r >> k;
+         q = q - (r << k);
+       }
+    }
+
+  if (rp)
+    *rp = r;
+  return q;
+}
+#else
 
 #if (defined (L_udivdi3) || defined (L_divdi3) || \
      defined (L_umoddi3) || defined (L_moddi3))
@@ -1152,6 +1220,7 @@ __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
   return ww.ll;
 }
 #endif
+#endif
 
 #ifdef L_divdi3
 DWtype