]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
s390: Fix BZ #359289, adding support for popcnt insn.
authorFlorian Krohm <florian@eich-krohm.de>
Wed, 17 Feb 2016 20:00:59 +0000 (20:00 +0000)
committerFlorian Krohm <florian@eich-krohm.de>
Wed, 17 Feb 2016 20:00:59 +0000 (20:00 +0000)
Companion patch is VEX r3210.
Patch by Andreas Arnez (arnez@linux.vnet.ibm.com).

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@15792

NEWS
docs/internals/s390-opcodes.csv
none/tests/s390x/Makefile.am
none/tests/s390x/opcodes.h
none/tests/s390x/popcnt.c [new file with mode: 0644]
none/tests/s390x/popcnt.stderr.exp [new file with mode: 0644]
none/tests/s390x/popcnt.stdout.exp [new file with mode: 0644]
none/tests/s390x/popcnt.vgtest [new file with mode: 0644]
tests/s390x_features.c

diff --git a/NEWS b/NEWS
index 3ea35da430ef9f2401e63bf4a362dbd7385f7d59..542d62466e45435fd04d9fcbe7f0faf82f7a14b3 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -71,6 +71,7 @@ where XXXXXX is the bug number as listed below.
 357887  Fix a file handle leak. VG_(fclose) did not close the file
 358030  support direct socket calls on x86 32bit (new in linux 4.3)
 359133  Assertion 'eltSzB <= ddpa->poolSzB' failed
+359289  s390x: popcnt (B9E1) not implemented
 
 n-i-bz Fix incorrect (or infinite loop) unwind on RHEL7 x86 32 bits
 n-i-bz massif --pages-as-heap=yes does not report peak caused by mmap+munmap
index c0757eec1babcf81429a09c942517d1748115a90..6ffd499d67f7818de86f9d40c80b5ef93b853260 100644 (file)
@@ -903,7 +903,7 @@ srk,"subtract 3 operands 32 bit",implemented,
 sgrk,"subtract 3 operands 64 bit",implemented,
 slrk,"subtract logical 3 operands 32 bit",implemented,
 slgrk,"subtract logical 3 operands 64 bit",implemented,
-popcnt,"population count","not implemented",
+popcnt,"population count","implemented",
 rrbm,"reset reference bits multiple",N/A,"privileged instruction"
 cefbra,"convert from 32 bit fixed to short bfp with rounding mode",implemented,
 cdfbra,"convert from 32 bit fixed to long bfp with rounding mode",implemented,
index 6545117e32347929a43b60db5f075596084ec31a..67f47393440e6bc7a578ff1f758da61f1d2b52d4 100644 (file)
@@ -11,7 +11,7 @@ INSN_TESTS = clc clcle cvb cvd icm lpr tcxb lam_stam xc mvst add sub mul \
              ex_sig ex_clone cu14 cu14_1 cu41 fpconv ecag fpext_warn \
              rounding-1 rounding-2 rounding-3 rounding-4 rounding-5 bfp-1 \
              bfp-2 bfp-3 bfp-4 srnm srnmb comp-1 comp-2 exrl tmll tm stmg \
-            ex clst mvc test_fork test_sig rounding-6 rxsbg\
+            ex clst mvc test_fork test_sig rounding-6 rxsbg popcnt \
             spechelper-alr spechelper-algr \
             spechelper-slr spechelper-slgr \
             spechelper-cr  spechelper-clr  \
index f8a55e215811a6d3a716d1b50c5e66060c31749d..0c5b737aaaf17959fb8dfd3207607293e636b89e 100644 (file)
 #define OY(r1,x2,b2,dl2,dh2)            RXY_RRRD(e3,r1,x2,b2,dl2,dh2,56)
 #define PFD(r1,x2,b2,dl2,dh2)           RXY_URRD(e3,r1,x2,b2,dl2,dh2,36)
 #define PFDRL(r1,i2)                    RIL_UP(c6,r1,2,i2)
+#define POPCNT(r1,r2)                   RRE_RR(b9e1,00,r1,r2)
 #define RISBG(r1,r2,i3,i4,i5)           RIE_RRUUU(ec,r1,r2,i3,i4,i5,55)
 #define RNSBG(r1,r2,i3,i4,i5)           RIE_RRUUU(ec,r1,r2,i3,i4,i5,54)
 #define ROSBG(r1,r2,i3,i4,i5)           RIE_RRUUU(ec,r1,r2,i3,i4,i5,56)
diff --git a/none/tests/s390x/popcnt.c b/none/tests/s390x/popcnt.c
new file mode 100644 (file)
index 0000000..d9bc466
--- /dev/null
@@ -0,0 +1,30 @@
+#include <stdio.h>
+#include <stdint.h>
+
+
+static void check_popcnt(uint64_t in, uint64_t expected_result,
+                         int expected_cc)
+{
+   uint64_t out = ~expected_result;
+   int cc = ~expected_cc;
+
+   asm volatile(".insn rre, 0xb9e10000, %[out], %[in]\n\t"
+                "ipm     %[cc]\n\t"
+                "srl     %[cc],28\n\t"
+                : [cc]"=d" (cc), [out]"=d" (out)
+                : [in]"d" (in)
+                : "cc");
+   printf("popcnt %16lx -> %16lx %s  cc=%d %s\n",
+          in, out, (out == expected_result ? "   " : "ERR"),
+          cc, (cc == expected_cc ? "   " : "ERR"));
+}
+
+int main()
+{
+   check_popcnt(0, 0, 0);
+   check_popcnt(1, 1, 1);
+   check_popcnt(0x8000000000000000ULL, 0x0100000000000000ULL, 1);
+   check_popcnt(0xffffffffffffffffULL, 0x0808080808080808ULL, 1);
+   check_popcnt(0xff427e3800556bcdULL, 0x0802060300040505ULL, 1);
+   return 0;
+}
diff --git a/none/tests/s390x/popcnt.stderr.exp b/none/tests/s390x/popcnt.stderr.exp
new file mode 100644 (file)
index 0000000..139597f
--- /dev/null
@@ -0,0 +1,2 @@
+
+
diff --git a/none/tests/s390x/popcnt.stdout.exp b/none/tests/s390x/popcnt.stdout.exp
new file mode 100644 (file)
index 0000000..0bb7afe
--- /dev/null
@@ -0,0 +1,5 @@
+popcnt                0 ->                0      cc=0    
+popcnt                1 ->                1      cc=1    
+popcnt 8000000000000000 ->  100000000000000      cc=1    
+popcnt ffffffffffffffff ->  808080808080808      cc=1    
+popcnt ff427e3800556bcd ->  802060300040505      cc=1    
diff --git a/none/tests/s390x/popcnt.vgtest b/none/tests/s390x/popcnt.vgtest
new file mode 100644 (file)
index 0000000..78ad704
--- /dev/null
@@ -0,0 +1 @@
+prog: popcnt
index bc671c6779773a2c546173126e0f287ee2c88db4..179b40ebfbdaf938fc0796a3fae5c4610cdfc864 100644 (file)
@@ -232,6 +232,8 @@ static int go(char *feature, char *cpu)
       match = facilities & FAC_BIT(42);
    } else if (strcmp(feature, "s390x-pfpo") == 0 ) {
       match = facilities & FAC_BIT(44);
+   } else if (strcmp(feature, "s390x-highw") == 0 ) {
+      match = facilities & FAC_BIT(45);
    } else {
       return 2;          // Unrecognised feature.
    }