return 0;
}
+/* Helpers for folding PopCount32/64.
+ https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan
+ As many iterations as 1-bits present.
+*/
+static UInt fold_PopCount64 ( ULong value )
+{
+ UInt count;
+
+ for (count = 0; value != 0; ++count) {
+ value &= value - 1; // clear the least significant 1-bit
+ }
+ return count;
+}
+
+static UInt fold_PopCount32 ( UInt value )
+{
+ UInt count;
+
+ for (count = 0; value != 0; ++count) {
+ value &= value - 1; // clear the least significant 1-bit
+ }
+ return count;
+}
+
+
/* V64 holds 8 summary-constant bits in V128/V256 style. Convert to
the corresponding real constant. */
//XXX re-check this before use
(0xFF & e->Iex.Unop.arg->Iex.Const.con->Ico.U8)
)));
break;
+ case Iop_CmpNEZ16:
+ e2 = IRExpr_Const(IRConst_U1(toBool(
+ 0 !=
+ (0xFFFF & e->Iex.Unop.arg->Iex.Const.con->Ico.U16)
+ )));
+ break;
case Iop_CmpNEZ32:
e2 = IRExpr_Const(IRConst_U1(toBool(
0 !=
break;
}
+ case Iop_PopCount32: {
+ UInt u32 = e->Iex.Unop.arg->Iex.Const.con->Ico.U32;
+ e2 = IRExpr_Const(IRConst_U32(fold_PopCount32(u32)));
+ break;
+ }
+ case Iop_PopCount64: {
+ ULong u64 = e->Iex.Unop.arg->Iex.Const.con->Ico.U64;
+ e2 = IRExpr_Const(IRConst_U64(fold_PopCount64(u64)));
+ break;
+ }
+
/* For these vector ones, can't fold all cases, but at least
do the most obvious one. Could do better here using
summarise/desummarise of vector constants, but too
// { OPNAME(128HIto64), Ity_I64, 1, Ity_I128, }, // 128 bit
{ OPNAME(CmpNEZ8), Ity_I1, 1, Ity_I8 },
-// { OPNAME(CmpNEZ16), Ity_I1, 1, Ity_I16 }, // no folding yet
+ { OPNAME(CmpNEZ16), Ity_I1, 1, Ity_I16 },
{ OPNAME(CmpNEZ32), Ity_I1, 1, Ity_I32 },
{ OPNAME(CmpNEZ64), Ity_I1, 1, Ity_I64 },
// { OPNAME(CtzNat32), Ity_I32, 1, Ity_I32 }, // no folding yet
// { OPNAME(CtzNat64), Ity_I64, 1, Ity_I64 }, // no folding yet
-// { OPNAME(PopCount32), Ity_I32, 1, Ity_I32 }, // no folding yet
-// { OPNAME(PopCount64), Ity_I64, 1, Ity_I64 }, // no folding yet
+ { OPNAME(PopCount32), Ity_I32, 1, Ity_I32 },
+ { OPNAME(PopCount64), Ity_I64, 1, Ity_I64 },
static void check_result(const irop_t *, const test_data_t *);
static void run_tests(const irop_t *, test_data_t *, unsigned, uint64_t *);
static uint64_t left(uint64_t, unsigned);
+static uint32_t popcount(uint64_t);
void
case Iop_64HIto32: expected = opnd >> 32; break;
case Iop_CmpNEZ8:
-// case Iop_CmpNEZ16:
+ case Iop_CmpNEZ16:
case Iop_CmpNEZ32:
case Iop_CmpNEZ64:
expected = opnd != 0;
case Iop_Left32: expected = left(opnd, 32); break;
case Iop_Left64: expected = left(opnd, 64); break;
+ case Iop_PopCount32:
+ case Iop_PopCount64:
+ expected = popcount(opnd);
+ break;
+
default:
panic("%s: operator %s not handled\n", __func__, op->name);
}
panic(__func__);
}
}
+
+
+/* Naive implementation of counting 1-bits */
+static uint32_t
+popcount(uint64_t value)
+{
+ uint32_t count;
+
+ for (count = 0; value != 0; value >>= 1) {
+ count += value & 1;
+ }
+ return count;
+}