]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
s390: Implement popcnt insn. Part of fixing BZ #359289.
authorFlorian Krohm <florian@eich-krohm.de>
Wed, 17 Feb 2016 19:57:01 +0000 (19:57 +0000)
committerFlorian Krohm <florian@eich-krohm.de>
Wed, 17 Feb 2016 19:57:01 +0000 (19:57 +0000)
Patch by Andreas Arnez (arnez@linux.vnet.ibm.com)

git-svn-id: svn://svn.valgrind.org/vex/trunk@3210

VEX/priv/guest_s390_toIR.c

index 116a6062597caa0d7b4b080e2e3d28dd9aa54e01..5e6acd4412e013ffbd8c8f1fdfdd5e83ad5d52fd 100644 (file)
@@ -8,7 +8,7 @@
    This file is part of Valgrind, a dynamic binary instrumentation
    framework.
 
-   Copyright IBM Corp. 2010-2015
+   Copyright IBM Corp. 2010-2016
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
@@ -12937,6 +12937,38 @@ s390_irgen_FLOGR(UChar r1, UChar r2)
    return "flogr";
 }
 
+static const HChar *
+s390_irgen_POPCNT(UChar r1, UChar r2)
+{
+   Int i;
+   IRTemp val = newTemp(Ity_I64);
+   IRTemp mask[3];
+
+   assign(val, get_gpr_dw0(r2));
+   for (i = 0; i < 3; i++) {
+      mask[i] = newTemp(Ity_I64);
+   }
+   assign(mask[0], mkU64(0x5555555555555555ULL));
+   assign(mask[1], mkU64(0x3333333333333333ULL));
+   assign(mask[2], mkU64(0x0F0F0F0F0F0F0F0FULL));
+   for (i = 0; i < 3; i++) {
+      IRTemp tmp = newTemp(Ity_I64);
+
+      assign(tmp,
+             binop(Iop_Add64,
+                   binop(Iop_And64,
+                         mkexpr(val),
+                         mkexpr(mask[i])),
+                   binop(Iop_And64,
+                         binop(Iop_Shr64, mkexpr(val), mkU8(1 << i)),
+                         mkexpr(mask[i]))));
+      val = tmp;
+   }
+   s390_cc_thunk_putZ(S390_CC_OP_BITWISE, val);
+   put_gpr_dw0(r1, mkexpr(val));
+   return "popcnt";
+}
+
 static const HChar *
 s390_irgen_STCK(IRTemp op2addr)
 {
@@ -14999,7 +15031,8 @@ s390_decode_4byte_and_irgen(const UChar *bytes)
                                    ovl.fmt.RRE.r2);  goto ok;
    case 0xb9df: s390_format_RRE_RR(s390_irgen_CLHLR, ovl.fmt.RRE.r1,
                                    ovl.fmt.RRE.r2);  goto ok;
-   case 0xb9e1: /* POPCNT */ goto unimplemented;
+   case 0xb9e1: s390_format_RRE_RR(s390_irgen_POPCNT, ovl.fmt.RRE.r1,
+                                   ovl.fmt.RRE.r2);  goto ok;
    case 0xb9e2: s390_format_RRF_U0RR(s390_irgen_LOCGR, ovl.fmt.RRF3.r3,
                                      ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
                                      S390_XMNM_LOCGR);  goto ok;