OSDN Git Service

* longlong.h (umul_ppmm): Add ColdFire support.
[pf3gnuchains/gcc-fork.git] / gcc / longlong.h
index a593150..2fb68e7 100644 (file)
@@ -66,7 +66,7 @@
    is rounded towards 0.
 
    5) count_leading_zeros(count, x) counts the number of zero-bits from the
-   msb to the first non-zero bit in the UWtype X.  This is the number of
+   msb to the first nonzero bit in the UWtype X.  This is the number of
    steps X needs to be shifted left to set the msb.  Undefined for X == 0,
    unless the symbol COUNT_LEADING_ZEROS_0 is defined to some value.
 
 #define umul_ppmm(ph, pl, m0, m1) \
   do {                                                                 \
     UDItype __m0 = (m0), __m1 = (m1);                                  \
-    __asm__ ("umulh %r1,%2,%0"                                         \
-            : "=r" ((UDItype) ph)                                      \
-            : "%rJ" (__m0),                                            \
-              "rI" (__m1));                                            \
+    (ph) = __builtin_alpha_umulh (__m0, __m1);                         \
     (pl) = __m0 * __m1;                                                        \
   } while (0)
 #define UMUL_TIME 46
     (q) = __udiv_qrnnd (&__r, (n1), (n0), (d));                                \
     (r) = __r;                                                         \
   } while (0)
-extern UDItype __udiv_qrnnd PARAMS ((UDItype *, UDItype, UDItype, UDItype));
+extern UDItype __udiv_qrnnd (UDItype *, UDItype, UDItype, UDItype);
 #define UDIV_TIME 220
 #endif /* LONGLONG_STANDALONE */
 #ifdef __alpha_cix__
-#define count_leading_zeros(COUNT,X) \
-  __asm__("ctlz %1,%0" : "=r"(COUNT) : "r"(X))
-#define count_trailing_zeros(COUNT,X) \
-  __asm__("cttz %1,%0" : "=r"(COUNT) : "r"(X))
+#define count_leading_zeros(COUNT,X)   ((COUNT) = __builtin_clzl (X))
+#define count_trailing_zeros(COUNT,X)  ((COUNT) = __builtin_ctzl (X))
 #define COUNT_LEADING_ZEROS_0 64
 #else
-extern const UQItype __clz_tab[];
+extern const UQItype __clz_tab[] ATTRIBUTE_HIDDEN;
 #define count_leading_zeros(COUNT,X) \
   do {                                                                 \
     UDItype __xr = (X), __t, __a;                                      \
-    __asm__("cmpbge $31,%1,%0" : "=r"(__t) : "r"(__xr));               \
+    __t = __builtin_alpha_cmpbge (0, __xr);                            \
     __a = __clz_tab[__t ^ 0xff] - 1;                                   \
-    __asm__("extbl %1,%2,%0" : "=r"(__t) : "r"(__xr), "r"(__a));       \
+    __t = __builtin_alpha_extbl (__xr, __a);                           \
     (COUNT) = 64 - (__clz_tab[__t] + __a*8);                           \
   } while (0)
 #define count_trailing_zeros(COUNT,X) \
   do {                                                                 \
     UDItype __xr = (X), __t, __a;                                      \
-    __asm__("cmpbge $31,%1,%0" : "=r"(__t) : "r"(__xr));               \
+    __t = __builtin_alpha_cmpbge (0, __xr);                            \
     __t = ~__t & -~__t;                                                        \
     __a = ((__t & 0xCC) != 0) * 2;                                     \
     __a += ((__t & 0xF0) != 0) * 4;                                    \
     __a += ((__t & 0xAA) != 0);                                                \
-    __asm__("extbl %1,%2,%0" : "=r"(__t) : "r"(__xr), "r"(__a));       \
+    __t = __builtin_alpha_extbl (__xr, __a);                           \
     __a <<= 3;                                                         \
     __t &= -__t;                                                       \
     __a += ((__t & 0xCC) != 0) * 2;                                    \
@@ -292,44 +287,27 @@ UDItype __umulsidi3 (USItype, USItype);
   } while (0)
 #endif
 
-#if (defined (__i370__) || defined (__mvs__)) && W_TYPE_SIZE == 32
-#define umul_ppmm(xh, xl, m0, m1) \
-  do {                                                                 \
-    union {UDItype __ll;                                               \
-          struct {USItype __h, __l;} __i;                              \
-         } __xx;                                                       \
-    USItype __m0 = (m0), __m1 = (m1);                                  \
-    __asm__ ("mr %0,%3"                                                        \
-            : "=r" (__xx.__i.__h),                                     \
-              "=r" (__xx.__i.__l)                                      \
-            : "%1" (__m0),                                             \
-              "r" (__m1));                                             \
-    (xh) = __xx.__i.__h; (xl) = __xx.__i.__l;                          \
-    (xh) += ((((SItype) __m0 >> 31) & __m1)                            \
-            + (((SItype) __m1 >> 31) & __m0));                         \
-  } while (0)
+#if (defined (__i370__) || defined (__s390__) || defined (__mvs__)) && W_TYPE_SIZE == 32
 #define smul_ppmm(xh, xl, m0, m1) \
   do {                                                                 \
     union {DItype __ll;                                                        \
           struct {USItype __h, __l;} __i;                              \
-         } __xx;                                                       \
-    __asm__ ("mr %0,%3"                                                        \
-            : "=r" (__xx.__i.__h),                                     \
-              "=r" (__xx.__i.__l)                                      \
-            : "%1" (m0),                                               \
-              "r" (m1));                                               \
-    (xh) = __xx.__i.__h; (xl) = __xx.__i.__l;                          \
+         } __x;                                                        \
+    __asm__ ("lr %N0,%1\n\tmr %0,%2"                                   \
+            : "=&r" (__x.__ll)                                         \
+            : "r" (m0), "r" (m1));                                     \
+    (xh) = __x.__i.__h; (xl) = __x.__i.__l;                            \
   } while (0)
 #define sdiv_qrnnd(q, r, n1, n0, d) \
   do {                                                                 \
     union {DItype __ll;                                                        \
           struct {USItype __h, __l;} __i;                              \
-         } __xx;                                                       \
-    __xx.__i.__h = n1; __xx.__i.__l = n0;                              \
+         } __x                                                       \
+    __x.__i.__h = n1; __x.__i.__l = n0;                                        \
     __asm__ ("dr %0,%2"                                                        \
-            : "=r" (__xx.__ll)                                         \
-            : "0" (__xx.__ll), "r" (d));                               \
-    (q) = __xx.__i.__l; (r) = __xx.__i.__h;                            \
+            : "=r" (__x.__ll)                                          \
+            : "0" (__x.__ll), "r" (d));                                \
+    (q) = __x.__i.__l; (r) = __x.__i.__h;                              \
   } while (0)
 #endif
 
@@ -465,7 +443,42 @@ UDItype __umulsidi3 (USItype, USItype);
             "dmi" ((USItype) (d)))
 
 #else /* not mc68020 */
-#if !defined(__mcf5200__)
+#if defined(__mcoldfire__)
+#define umul_ppmm(xh, xl, a, b) \
+  __asm__ ("| Inlined umul_ppmm\n"                                     \
+          "    move%.l %2,%/d0\n"                                      \
+          "    move%.l %3,%/d1\n"                                      \
+          "    move%.l %/d0,%/d2\n"                                    \
+          "    swap    %/d0\n"                                         \
+          "    move%.l %/d1,%/d3\n"                                    \
+          "    swap    %/d1\n"                                         \
+          "    move%.w %/d2,%/d4\n"                                    \
+          "    mulu    %/d3,%/d4\n"                                    \
+          "    mulu    %/d1,%/d2\n"                                    \
+          "    mulu    %/d0,%/d3\n"                                    \
+          "    mulu    %/d0,%/d1\n"                                    \
+          "    move%.l %/d4,%/d0\n"                                    \
+          "    clr%.w  %/d0\n"                                         \
+          "    swap    %/d0\n"                                         \
+          "    add%.l  %/d0,%/d2\n"                                    \
+          "    add%.l  %/d3,%/d2\n"                                    \
+          "    jcc     1f\n"                                           \
+          "    add%.l  %#65536,%/d1\n"                                 \
+          "1:  swap    %/d2\n"                                         \
+          "    moveq   %#0,%/d0\n"                                     \
+          "    move%.w %/d2,%/d0\n"                                    \
+          "    move%.w %/d4,%/d2\n"                                    \
+          "    move%.l %/d2,%1\n"                                      \
+          "    add%.l  %/d1,%/d0\n"                                    \
+          "    move%.l %/d0,%0"                                        \
+          : "=g" ((USItype) (xh)),                                     \
+            "=g" ((USItype) (xl))                                      \
+          : "g" ((USItype) (a)),                                       \
+            "g" ((USItype) (b))                                        \
+          : "d0", "d1", "d2", "d3", "d4")
+#define UMUL_TIME 100
+#define UDIV_TIME 400
+#else /* not ColdFire */
 /* %/ inserts REGISTER_PREFIX, %# inserts IMMEDIATE_PREFIX.  */
 #define umul_ppmm(xh, xl, a, b) \
   __asm__ ("| Inlined umul_ppmm\n"                                     \
@@ -501,14 +514,16 @@ UDItype __umulsidi3 (USItype, USItype);
           : "d0", "d1", "d2", "d3", "d4")
 #define UMUL_TIME 100
 #define UDIV_TIME 400
-#endif /* not mcf5200 */
+#endif /* not ColdFire */
 #endif /* not mc68020 */
 
-/* The '020, '030, '040 and '060 have bitfield insns.  */
-#if defined (__mc68020__) || defined(mc68020) \
-       || defined(__mc68030__) || defined(mc68030) \
-       || defined(__mc68040__) || defined(mc68040) \
-       || defined(__mc68060__) || defined(mc68060)
+/* The '020, '030, '040 and '060 have bitfield insns.
+   cpu32 disguises as a 68020, but lacks them.  */
+#if ( defined (__mc68020__) || defined(mc68020) \
+               || defined(__mc68030__) || defined(mc68030) \
+               || defined(__mc68040__) || defined(mc68040) \
+               || defined(__mc68060__) || defined(mc68060) ) \
+       && !defined(__mcpu32__)
 #define count_leading_zeros(count, x) \
   __asm__ ("bfffo %1{%b2:%b2},%0"                                      \
           : "=d" ((USItype) (count))                                   \
@@ -669,7 +684,7 @@ UDItype __umulsidi3 (USItype, USItype);
   __asm__ ("{cntlz|cntlzw} %0,%1" : "=r" (count) : "r" (x))
 #define COUNT_LEADING_ZEROS_0 32
 #if defined (_ARCH_PPC) || defined (__powerpc__) || defined (__POWERPC__) \
-  || defined (__ppc__) || defined (PPC) || defined (__vxworks__)
+  || defined (__ppc__) || defined (PPC)
 #define umul_ppmm(ph, pl, m0, m1) \
   do {                                                                 \
     USItype __m0 = (m0), __m1 = (m1);                                  \
@@ -1201,6 +1216,20 @@ UDItype __umulsidi3 (USItype, USItype);
   } while (0)
 #endif
 
+/* If we lack umul_ppmm but have smul_ppmm, define umul_ppmm in terms of
+   smul_ppmm.  */
+#if !defined (umul_ppmm) && defined (smul_ppmm)
+#define umul_ppmm(w1, w0, u, v)                                                \
+  do {                                                                 \
+    UWtype __w1;                                                       \
+    UWtype __xm0 = (u), __xm1 = (v);                                   \
+    smul_ppmm (__w1, w0, __xm0, __xm1);                                        \
+    (w1) = __w1 + (-(__xm0 >> (W_TYPE_SIZE - 1)) & __xm1)              \
+               + (-(__xm1 >> (W_TYPE_SIZE - 1)) & __xm0);              \
+  } while (0)
+#endif
+
+/* If we still don't have umul_ppmm, define it using plain C.  */
 #if !defined (umul_ppmm)
 #define umul_ppmm(w1, w0, u, v)                                                \
   do {                                                                 \
@@ -1290,7 +1319,7 @@ UDItype __umulsidi3 (USItype, USItype);
 #endif
 
 #if !defined (count_leading_zeros)
-extern const UQItype __clz_tab[];
+extern const UQItype __clz_tab[] ATTRIBUTE_HIDDEN;
 #define count_leading_zeros(count, x) \
   do {                                                                 \
     UWtype __xr = (x);                                                 \