Make Alpha and PowerPC targets use shared helpers
authorj_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162>
Sun, 28 Oct 2007 12:54:53 +0000 (12:54 +0000)
committerj_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162>
Sun, 28 Oct 2007 12:54:53 +0000 (12:54 +0000)
 for clz, clo, ctz, cto and ctpop.

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3466 c046a42c-6fe2-441c-8c8c-71466251a162

target-alpha/op_helper.c
target-ppc/op.c
target-ppc/op_helper.c
target-ppc/op_helper.h

index f9390c8..ae8470b 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include "exec.h"
+#include "host-utils.h"
 #include "softfloat.h"
 
 #include "op_helper.h"
@@ -211,87 +212,17 @@ void helper_mulqv ()
 
 void helper_ctpop (void)
 {
-    int n;
-
-    for (n = 0; T0 != 0; n++)
-        T0 = T0 ^ (T0 - 1);
-    T0 = n;
+    T0 = ctpop64(T0);
 }
 
 void helper_ctlz (void)
 {
-    uint32_t op32;
-    int n;
-
-    n = 0;
-    if (!(T0 & 0xFFFFFFFF00000000ULL)) {
-        n += 32;
-        T0 <<= 32;
-    }
-    /* Make it easier for 32 bits hosts */
-    op32 = T0 >> 32;
-    if (!(op32 & 0xFFFF0000UL)) {
-        n += 16;
-        op32 <<= 16;
-    }
-    if (!(op32 & 0xFF000000UL)) {
-        n += 8;
-        op32 <<= 8;
-    }
-    if (!(op32 & 0xF0000000UL)) {
-        n += 4;
-        op32 <<= 4;
-    }
-    if (!(op32 & 0xC0000000UL)) {
-        n += 2;
-        op32 <<= 2;
-    }
-    if (!(op32 & 0x80000000UL)) {
-        n++;
-        op32 <<= 1;
-    }
-    if (!(op32 & 0x80000000UL)) {
-        n++;
-    }
-    T0 = n;
+    T0 = clz64(T0);
 }
 
 void helper_cttz (void)
 {
-    uint32_t op32;
-    int n;
-
-    n = 0;
-    if (!(T0 & 0x00000000FFFFFFFFULL)) {
-        n += 32;
-        T0 >>= 32;
-    }
-    /* Make it easier for 32 bits hosts */
-    op32 = T0;
-    if (!(op32 & 0x0000FFFFUL)) {
-        n += 16;
-        op32 >>= 16;
-    }
-    if (!(op32 & 0x000000FFUL)) {
-        n += 8;
-        op32 >>= 8;
-    }
-    if (!(op32 & 0x0000000FUL)) {
-        n += 4;
-        op32 >>= 4;
-    }
-    if (!(op32 & 0x00000003UL)) {
-        n += 2;
-        op32 >>= 2;
-    }
-    if (!(op32 & 0x00000001UL)) {
-        n++;
-        op32 >>= 1;
-    }
-    if (!(op32 & 0x00000001UL)) {
-        n++;
-    }
-    T0 = n;
+    T0 = ctz64(T0);
 }
 
 static always_inline uint64_t byte_zap (uint64_t op, uint8_t mskb)
index 0146d33..4c170d8 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "config.h"
 #include "exec.h"
+#include "host-utils.h"
 #include "helper_regs.h"
 #include "op_helper.h"
 
@@ -1508,14 +1509,14 @@ void OPPROTO op_andi_T1_64 (void)
 /* count leading zero */
 void OPPROTO op_cntlzw (void)
 {
-    T0 = _do_cntlzw(T0);
+    do_cntlzw();
     RETURN();
 }
 
 #if defined(TARGET_PPC64)
 void OPPROTO op_cntlzd (void)
 {
-    T0 = _do_cntlzd(T0);
+    do_cntlzd();
     RETURN();
 }
 #endif
index 61075c0..751bd72 100644 (file)
@@ -18,6 +18,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 #include "exec.h"
+#include "host-utils.h"
 
 #include "helper_regs.h"
 #include "op_helper.h"
@@ -381,6 +382,18 @@ void do_subfzeo_64 (void)
 }
 #endif
 
+void do_cntlzw (void)
+{
+    T0 = clz32(T0);
+}
+
+#if defined(TARGET_PPC64)
+void do_cntlzd (void)
+{
+    T0 = clz64(T0);
+}
+#endif
+
 /* shift right arithmetic helper */
 void do_sraw (void)
 {
@@ -438,16 +451,6 @@ void do_srad (void)
 }
 #endif
 
-static always_inline int popcnt (uint32_t val)
-{
-    int i;
-
-    for (i = 0; val != 0;)
-        val = val ^ (val - 1);
-
-    return i;
-}
-
 void do_popcntb (void)
 {
     uint32_t ret;
@@ -455,7 +458,7 @@ void do_popcntb (void)
 
     ret = 0;
     for (i = 0; i < 32; i += 8)
-        ret |= popcnt((T0 >> i) & 0xFF) << i;
+        ret |= ctpop8((T0 >> i) & 0xFF) << i;
     T0 = ret;
 }
 
@@ -467,7 +470,7 @@ void do_popcntb_64 (void)
 
     ret = 0;
     for (i = 0; i < 64; i += 8)
-        ret |= popcnt((T0 >> i) & 0xFF) << i;
+        ret |= ctpop8((T0 >> i) & 0xFF) << i;
     T0 = ret;
 }
 #endif
@@ -1924,14 +1927,14 @@ static always_inline uint32_t _do_eaddw (uint32_t op1, uint32_t op2)
 static always_inline int _do_ecntlsw (uint32_t val)
 {
     if (val & 0x80000000)
-        return _do_cntlzw(~val);
+        return clz32(~val);
     else
-        return _do_cntlzw(val);
+        return clz32(val);
 }
 
 static always_inline int _do_ecntlzw (uint32_t val)
 {
-    return _do_cntlzw(val);
+    return clz32(val);
 }
 
 static always_inline uint32_t _do_eneg (uint32_t val)
index 6597b3c..915b32a 100644 (file)
@@ -75,6 +75,10 @@ void do_nego (void);
 void do_subfe (void);
 void do_subfmeo (void);
 void do_subfzeo (void);
+void do_cntlzw (void);
+#if defined(TARGET_PPC64)
+void do_cntlzd (void);
+#endif
 void do_sraw (void);
 #if defined(TARGET_PPC64)
 void do_adde_64 (void);
@@ -285,78 +289,6 @@ void do_evfsctsiz (void);
 void do_evfsctuiz (void);
 #endif /* defined(TARGET_PPCEMB) */
 
-/* Inlined helpers: used in micro-operation as well as helpers */
-/* Generic fixed-point helpers */
-static always_inline int _do_cntlzw (uint32_t val)
-{
-    int cnt = 0;
-    if (!(val & 0xFFFF0000UL)) {
-        cnt += 16;
-        val <<= 16;
-    }
-    if (!(val & 0xFF000000UL)) {
-        cnt += 8;
-        val <<= 8;
-    }
-    if (!(val & 0xF0000000UL)) {
-        cnt += 4;
-        val <<= 4;
-    }
-    if (!(val & 0xC0000000UL)) {
-        cnt += 2;
-        val <<= 2;
-    }
-    if (!(val & 0x80000000UL)) {
-        cnt++;
-        val <<= 1;
-    }
-    if (!(val & 0x80000000UL)) {
-        cnt++;
-    }
-    return cnt;
-}
-
-static always_inline int _do_cntlzd (uint64_t val)
-{
-    int cnt = 0;
-#if HOST_LONG_BITS == 64
-    if (!(val & 0xFFFFFFFF00000000ULL)) {
-        cnt += 32;
-        val <<= 32;
-    }
-    if (!(val & 0xFFFF000000000000ULL)) {
-        cnt += 16;
-        val <<= 16;
-    }
-    if (!(val & 0xFF00000000000000ULL)) {
-        cnt += 8;
-        val <<= 8;
-    }
-    if (!(val & 0xF000000000000000ULL)) {
-        cnt += 4;
-        val <<= 4;
-    }
-    if (!(val & 0xC000000000000000ULL)) {
-        cnt += 2;
-        val <<= 2;
-    }
-    if (!(val & 0x8000000000000000ULL)) {
-        cnt++;
-        val <<= 1;
-    }
-    if (!(val & 0x8000000000000000ULL)) {
-        cnt++;
-    }
-#else
-    /* Make it easier on 32 bits host machines */
-    if (!(val >> 32))
-        cnt = _do_cntlzw(val) + 32;
-    else
-        cnt = _do_cntlzw(val >> 32);
-#endif
-    return cnt;
-}
-
 #if defined(TARGET_PPCEMB)
 /* SPE extension */
 /* Single precision floating-point helpers */