From: Florian Krohm Date: Wed, 17 Feb 2016 20:00:59 +0000 (+0000) Subject: s390: Fix BZ #359289, adding support for popcnt insn. X-Git-Tag: svn/VALGRIND_3_12_0~231 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a696c9e44a79ab1a65074f5746e7e57015be000d;p=thirdparty%2Fvalgrind.git s390: Fix BZ #359289, adding support for popcnt insn. Companion patch is VEX r3210. Patch by Andreas Arnez (arnez@linux.vnet.ibm.com). git-svn-id: svn://svn.valgrind.org/valgrind/trunk@15792 --- diff --git a/NEWS b/NEWS index 3ea35da430..542d62466e 100644 --- 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 diff --git a/docs/internals/s390-opcodes.csv b/docs/internals/s390-opcodes.csv index c0757eec1b..6ffd499d67 100644 --- a/docs/internals/s390-opcodes.csv +++ b/docs/internals/s390-opcodes.csv @@ -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, diff --git a/none/tests/s390x/Makefile.am b/none/tests/s390x/Makefile.am index 6545117e32..67f4739344 100644 --- a/none/tests/s390x/Makefile.am +++ b/none/tests/s390x/Makefile.am @@ -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 \ diff --git a/none/tests/s390x/opcodes.h b/none/tests/s390x/opcodes.h index f8a55e2158..0c5b737aaa 100644 --- a/none/tests/s390x/opcodes.h +++ b/none/tests/s390x/opcodes.h @@ -324,6 +324,7 @@ #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 index 0000000000..d9bc466dd9 --- /dev/null +++ b/none/tests/s390x/popcnt.c @@ -0,0 +1,30 @@ +#include +#include + + +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 index 0000000000..139597f9cb --- /dev/null +++ b/none/tests/s390x/popcnt.stderr.exp @@ -0,0 +1,2 @@ + + diff --git a/none/tests/s390x/popcnt.stdout.exp b/none/tests/s390x/popcnt.stdout.exp new file mode 100644 index 0000000000..0bb7afefce --- /dev/null +++ b/none/tests/s390x/popcnt.stdout.exp @@ -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 index 0000000000..78ad70425b --- /dev/null +++ b/none/tests/s390x/popcnt.vgtest @@ -0,0 +1 @@ +prog: popcnt diff --git a/tests/s390x_features.c b/tests/s390x_features.c index bc671c6779..179b40ebfb 100644 --- a/tests/s390x_features.c +++ b/tests/s390x_features.c @@ -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. }