OSDN Git Service

2010-12-02 Richard Guenther <rguenther@suse.de>
[pf3gnuchains/gcc-fork.git] / gcc / longlong.h
index 9bfd322..49daa6e 100644 (file)
@@ -318,6 +318,7 @@ UDItype __umulsidi3 (USItype, USItype);
 #endif
 
 #if (defined (__i370__) || defined (__s390__) || defined (__mvs__)) && W_TYPE_SIZE == 32
+#if !defined (__zarch__)
 #define smul_ppmm(xh, xl, m0, m1) \
   do {                                                                 \
     union {DItype __ll;                                                        \
@@ -339,6 +340,28 @@ UDItype __umulsidi3 (USItype, USItype);
             : "0" (__x.__ll), "r" (d));                                \
     (q) = __x.__i.__l; (r) = __x.__i.__h;                              \
   } while (0)
+#else
+#define smul_ppmm(xh, xl, m0, m1) \
+  do {                                                                  \
+    register SItype r0 __asm__ ("0");                                   \
+    register SItype r1 __asm__ ("1") = m0;                              \
+                                                                        \
+    __asm__ ("mr\t%%r0,%3"                                              \
+             : "=r" (r0), "=r" (r1)                                     \
+             : "r"  (r1),  "r" (m1));                                   \
+    (xh) = r1; (xl) = r0;                                               \
+  } while (0)
+#define sdiv_qrnnd(q, r, n1, n0, d) \
+  do {                                                                 \
+    register SItype r0 __asm__ ("0") = n0;                              \
+    register SItype r1 __asm__ ("1") = n1;                              \
+                                                                        \
+    __asm__ ("dr\t%%r0,%3"                                             \
+            : "=r" (r0), "=r" (r1)                                     \
+            : "r" (r0), "r" (r1), "r" (d));                            \
+    (q) = r0; (r) = r1;                                                \
+  } while (0)
+#endif /* __zarch__ */
 #endif
 
 #if (defined (__i386__) || defined (__i486__)) && W_TYPE_SIZE == 32
@@ -432,6 +455,55 @@ UDItype __umulsidi3 (USItype, USItype);
     __w; })
 #endif /* __i960__ */
 
+#if defined (__ia64) && W_TYPE_SIZE == 64
+/* This form encourages gcc (pre-release 3.4 at least) to emit predicated
+   "sub r=r,r" and "sub r=r,r,1", giving a 2 cycle latency.  The generic
+   code using "al<bl" arithmetically comes out making an actual 0 or 1 in a
+   register, which takes an extra cycle.  */
+#define sub_ddmmss(sh, sl, ah, al, bh, bl)                             \
+  do {                                                                 \
+    UWtype __x;                                                                \
+    __x = (al) - (bl);                                                 \
+    if ((al) < (bl))                                                   \
+      (sh) = (ah) - (bh) - 1;                                          \
+    else                                                               \
+      (sh) = (ah) - (bh);                                              \
+    (sl) = __x;                                                                \
+  } while (0)
+
+/* Do both product parts in assembly, since that gives better code with
+   all gcc versions.  Some callers will just use the upper part, and in
+   that situation we waste an instruction, but not any cycles.  */
+#define umul_ppmm(ph, pl, m0, m1)                                      \
+  __asm__ ("xma.hu %0 = %2, %3, f0\n\txma.l %1 = %2, %3, f0"           \
+          : "=&f" (ph), "=f" (pl)                                      \
+          : "f" (m0), "f" (m1))
+#define count_leading_zeros(count, x)                                  \
+  do {                                                                 \
+    UWtype _x = (x), _y, _a, _c;                                       \
+    __asm__ ("mux1 %0 = %1, @rev" : "=r" (_y) : "r" (_x));             \
+    __asm__ ("czx1.l %0 = %1" : "=r" (_a) : "r" (-_y | _y));           \
+    _c = (_a - 1) << 3;                                                        \
+    _x >>= _c;                                                         \
+    if (_x >= 1 << 4)                                                  \
+      _x >>= 4, _c += 4;                                               \
+    if (_x >= 1 << 2)                                                  \
+      _x >>= 2, _c += 2;                                               \
+    _c += _x >> 1;                                                     \
+    (count) =  W_TYPE_SIZE - 1 - _c;                                   \
+  } while (0)
+/* similar to what gcc does for __builtin_ffs, but 0 based rather than 1
+   based, and we don't need a special case for x==0 here */
+#define count_trailing_zeros(count, x)                                 \
+  do {                                                                 \
+    UWtype __ctz_x = (x);                                              \
+    __asm__ ("popcnt %0 = %1"                                          \
+            : "=r" (count)                                             \
+            : "r" ((__ctz_x-1) & ~__ctz_x));                           \
+  } while (0)
+#define UMUL_TIME 14
+#endif
+
 #if defined (__M32R__) && W_TYPE_SIZE == 32
 #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
   /* The cmp clears the condition bit.  */ \
@@ -933,7 +1005,7 @@ UDItype __umulsidi3 (USItype, USItype);
 "      or r1,%0"                                                       \
        : "=r" (q), "=&z" (r)                                           \
        : "1" (n1), "r" (n0), "rm" (d), "r" (&__udiv_qrnnd_16)          \
-       : "r1", "r2", "r4", "r5", "r6", "pr");                          \
+       : "r1", "r2", "r4", "r5", "r6", "pr", "t");                     \
   } while (0)
 
 #define UDIV_TIME 80
@@ -941,7 +1013,7 @@ UDItype __umulsidi3 (USItype, USItype);
 #define sub_ddmmss(sh, sl, ah, al, bh, bl)                             \
   __asm__ ("clrt;subc %5,%1; subc %4,%0"                               \
           : "=r" (sh), "=r" (sl)                                       \
-          : "0" (ah), "1" (al), "r" (bh), "r" (bl))
+          : "0" (ah), "1" (al), "r" (bh), "r" (bl) : "t")
 
 #endif /* __sh__ */
 
@@ -1275,6 +1347,28 @@ UDItype __umulsidi3 (USItype, USItype);
 #define count_trailing_zeros(COUNT, X) ((COUNT) = __builtin_ctz (X))
 #endif /* __xtensa__ */
 
+#if defined xstormy16
+extern UHItype __stormy16_count_leading_zeros (UHItype);
+#define count_leading_zeros(count, x)                                  \
+  do                                                                   \
+    {                                                                  \
+      UHItype size;                                                    \
+                                                                       \
+      /* We assume that W_TYPE_SIZE is a multiple of 16...  */         \
+      for ((count) = 0, size = W_TYPE_SIZE; size; size -= 16)          \
+       {                                                               \
+         UHItype c;                                                    \
+                                                                       \
+         c = __clzhi2 ((x) >> (size - 16));                            \
+         (count) += c;                                                 \
+         if (c != 16)                                                  \
+           break;                                                      \
+       }                                                               \
+    }                                                                  \
+  while (0)
+#define COUNT_LEADING_ZEROS_0 W_TYPE_SIZE
+#endif
+
 #if defined (__z8000__) && W_TYPE_SIZE == 16
 #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
   __asm__ ("add        %H1,%H5\n\tadc  %H0,%H3"                                \