diff options
Diffstat (limited to 'target-ppc')
-rw-r--r-- | target-ppc/op.c | 5 | ||||
-rw-r--r-- | target-ppc/op_helper.c | 33 | ||||
-rw-r--r-- | target-ppc/op_helper.h | 76 |
3 files changed, 25 insertions, 89 deletions
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 */ |