*/
#include "exec.h"
+#include "host-utils.h"
#include "softfloat.h"
#include "op_helper.h"
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)
#include "config.h"
#include "exec.h"
+#include "host-utils.h"
#include "helper_regs.h"
#include "op_helper.h"
/* 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
* 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"
}
#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)
{
}
#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;
ret = 0;
for (i = 0; i < 32; i += 8)
- ret |= popcnt((T0 >> i) & 0xFF) << i;
+ ret |= ctpop8((T0 >> i) & 0xFF) << i;
T0 = ret;
}
ret = 0;
for (i = 0; i < 64; i += 8)
- ret |= popcnt((T0 >> i) & 0xFF) << i;
+ ret |= ctpop8((T0 >> i) & 0xFF) << i;
T0 = ret;
}
#endif
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)
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);
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 */