diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c index f9390c84d5..ae8470b595 100644 --- a/target-alpha/op_helper.c +++ b/target-alpha/op_helper.c @@ -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) diff --git a/target-ppc/op.c b/target-ppc/op.c index 0146d33c3d..4c170d84b6 100644 --- a/target-ppc/op.c +++ b/target-ppc/op.c @@ -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 diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c index 61075c0866..751bd7212c 100644 --- a/target-ppc/op_helper.c +++ b/target-ppc/op_helper.c @@ -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) diff --git a/target-ppc/op_helper.h b/target-ppc/op_helper.h index 6597b3ca58..915b32a28e 100644 --- a/target-ppc/op_helper.h +++ b/target-ppc/op_helper.h @@ -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 */