aboutsummaryrefslogtreecommitdiff
path: root/target-ppc/int_helper.c
diff options
context:
space:
mode:
authorNikunj A Dadhania <nikunj@linux.vnet.ibm.com>2016-07-26 17:28:34 +0530
committerDavid Gibson <david@gibson.dropbear.id.au>2016-09-07 09:52:14 +1000
commit082ce33005d81ff45b929e826ac48a5696059efc (patch)
tree5a878f045addc781c844003ef21ee0bd63e451eb /target-ppc/int_helper.c
parentb35344e4a0968fd1341ec1c1ed2e6b5c0d851542 (diff)
target-ppc: add cmpeqb instruction
Search a byte in the stream of 8bytes provided in the register Suggested-by: Richard Henderson <rth@twiddle.net> Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com> Reviewed-by: Richard Henderson <rth@twiddle.net> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Diffstat (limited to 'target-ppc/int_helper.c')
-rw-r--r--target-ppc/int_helper.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c
index 02b6df3b66..15947ad925 100644
--- a/target-ppc/int_helper.c
+++ b/target-ppc/int_helper.c
@@ -151,6 +151,28 @@ target_ulong helper_cnttzw(target_ulong t)
}
#if defined(TARGET_PPC64)
+/* if x = 0xab, returns 0xababababababababa */
+#define pattern(x) (((x) & 0xff) * (~(target_ulong)0 / 0xff))
+
+/* substract 1 from each byte, and with inverse, check if MSB is set at each
+ * byte.
+ * i.e. ((0x00 - 0x01) & ~(0x00)) & 0x80
+ * (0xFF & 0xFF) & 0x80 = 0x80 (zero found)
+ */
+#define haszero(v) (((v) - pattern(0x01)) & ~(v) & pattern(0x80))
+
+/* When you XOR the pattern and there is a match, that byte will be zero */
+#define hasvalue(x, n) (haszero((x) ^ pattern(n)))
+
+uint32_t helper_cmpeqb(target_ulong ra, target_ulong rb)
+{
+ return hasvalue(rb, ra) ? 1 << CRF_GT : 0;
+}
+
+#undef pattern
+#undef haszero
+#undef hasvalue
+
target_ulong helper_cntlzd(target_ulong t)
{
return clz64(t);