You can subscribe to this list here.
| 2002 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
(122) |
Nov
(152) |
Dec
(69) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2003 |
Jan
(6) |
Feb
(25) |
Mar
(73) |
Apr
(82) |
May
(24) |
Jun
(25) |
Jul
(10) |
Aug
(11) |
Sep
(10) |
Oct
(54) |
Nov
(203) |
Dec
(182) |
| 2004 |
Jan
(307) |
Feb
(305) |
Mar
(430) |
Apr
(312) |
May
(187) |
Jun
(342) |
Jul
(487) |
Aug
(637) |
Sep
(336) |
Oct
(373) |
Nov
(441) |
Dec
(210) |
| 2005 |
Jan
(385) |
Feb
(480) |
Mar
(636) |
Apr
(544) |
May
(679) |
Jun
(625) |
Jul
(810) |
Aug
(838) |
Sep
(634) |
Oct
(521) |
Nov
(965) |
Dec
(543) |
| 2006 |
Jan
(494) |
Feb
(431) |
Mar
(546) |
Apr
(411) |
May
(406) |
Jun
(322) |
Jul
(256) |
Aug
(401) |
Sep
(345) |
Oct
(542) |
Nov
(308) |
Dec
(481) |
| 2007 |
Jan
(427) |
Feb
(326) |
Mar
(367) |
Apr
(255) |
May
(244) |
Jun
(204) |
Jul
(223) |
Aug
(231) |
Sep
(354) |
Oct
(374) |
Nov
(497) |
Dec
(362) |
| 2008 |
Jan
(322) |
Feb
(482) |
Mar
(658) |
Apr
(422) |
May
(476) |
Jun
(396) |
Jul
(455) |
Aug
(267) |
Sep
(280) |
Oct
(253) |
Nov
(232) |
Dec
(304) |
| 2009 |
Jan
(486) |
Feb
(470) |
Mar
(458) |
Apr
(423) |
May
(696) |
Jun
(461) |
Jul
(551) |
Aug
(575) |
Sep
(134) |
Oct
(110) |
Nov
(157) |
Dec
(102) |
| 2010 |
Jan
(226) |
Feb
(86) |
Mar
(147) |
Apr
(117) |
May
(107) |
Jun
(203) |
Jul
(193) |
Aug
(238) |
Sep
(300) |
Oct
(246) |
Nov
(23) |
Dec
(75) |
| 2011 |
Jan
(133) |
Feb
(195) |
Mar
(315) |
Apr
(200) |
May
(267) |
Jun
(293) |
Jul
(353) |
Aug
(237) |
Sep
(278) |
Oct
(611) |
Nov
(274) |
Dec
(260) |
| 2012 |
Jan
(303) |
Feb
(391) |
Mar
(417) |
Apr
(441) |
May
(488) |
Jun
(655) |
Jul
(590) |
Aug
(610) |
Sep
(526) |
Oct
(478) |
Nov
(359) |
Dec
(372) |
| 2013 |
Jan
(467) |
Feb
(226) |
Mar
(391) |
Apr
(281) |
May
(299) |
Jun
(252) |
Jul
(311) |
Aug
(352) |
Sep
(481) |
Oct
(571) |
Nov
(222) |
Dec
(231) |
| 2014 |
Jan
(185) |
Feb
(329) |
Mar
(245) |
Apr
(238) |
May
(281) |
Jun
(399) |
Jul
(382) |
Aug
(500) |
Sep
(579) |
Oct
(435) |
Nov
(487) |
Dec
(256) |
| 2015 |
Jan
(338) |
Feb
(357) |
Mar
(330) |
Apr
(294) |
May
(191) |
Jun
(108) |
Jul
(142) |
Aug
(261) |
Sep
(190) |
Oct
(54) |
Nov
(83) |
Dec
(22) |
| 2016 |
Jan
(49) |
Feb
(89) |
Mar
(33) |
Apr
(50) |
May
(27) |
Jun
(34) |
Jul
(53) |
Aug
(53) |
Sep
(98) |
Oct
(206) |
Nov
(93) |
Dec
(53) |
| 2017 |
Jan
(65) |
Feb
(82) |
Mar
(102) |
Apr
(86) |
May
(187) |
Jun
(67) |
Jul
(23) |
Aug
(93) |
Sep
(65) |
Oct
(45) |
Nov
(35) |
Dec
(17) |
| 2018 |
Jan
(26) |
Feb
(35) |
Mar
(38) |
Apr
(32) |
May
(8) |
Jun
(43) |
Jul
(27) |
Aug
(30) |
Sep
(43) |
Oct
(42) |
Nov
(38) |
Dec
(67) |
| 2019 |
Jan
(32) |
Feb
(37) |
Mar
(53) |
Apr
(64) |
May
(49) |
Jun
(18) |
Jul
(14) |
Aug
(53) |
Sep
(25) |
Oct
(30) |
Nov
(49) |
Dec
(31) |
| 2020 |
Jan
(87) |
Feb
(45) |
Mar
(37) |
Apr
(51) |
May
(99) |
Jun
(36) |
Jul
(11) |
Aug
(14) |
Sep
(20) |
Oct
(24) |
Nov
(40) |
Dec
(23) |
| 2021 |
Jan
(14) |
Feb
(53) |
Mar
(85) |
Apr
(15) |
May
(19) |
Jun
(3) |
Jul
(14) |
Aug
(1) |
Sep
(57) |
Oct
(73) |
Nov
(56) |
Dec
(22) |
| 2022 |
Jan
(3) |
Feb
(22) |
Mar
(6) |
Apr
(55) |
May
(46) |
Jun
(39) |
Jul
(15) |
Aug
(9) |
Sep
(11) |
Oct
(34) |
Nov
(20) |
Dec
(36) |
| 2023 |
Jan
(79) |
Feb
(41) |
Mar
(99) |
Apr
(169) |
May
(48) |
Jun
(16) |
Jul
(16) |
Aug
(57) |
Sep
(19) |
Oct
|
Nov
|
Dec
|
| S | M | T | W | T | F | S |
|---|---|---|---|---|---|---|
|
|
|
|
|
|
|
1
(2) |
|
2
(2) |
3
(3) |
4
(3) |
5
|
6
|
7
|
8
|
|
9
|
10
(1) |
11
|
12
|
13
(2) |
14
(6) |
15
(4) |
|
16
|
17
(2) |
18
(8) |
19
(1) |
20
|
21
|
22
(2) |
|
23
|
24
(1) |
25
|
26
(3) |
27
(1) |
28
|
29
|
|
30
(2) |
|
|
|
|
|
|
|
From: Andreas A. <ar...@so...> - 2018-09-26 17:32:31
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=0a1d523a87d839edcdd798cc98d19933eb5bd933 commit 0a1d523a87d839edcdd798cc98d19933eb5bd933 Author: Andreas Arnez <ar...@li...> Date: Mon Sep 24 19:08:01 2018 +0200 s390x: Vector integer and string insn support -- tests This adds test cases and some internal stuff to the z/Architecture vector integer and string instruction support. Contributed by Vadim Barkov <vb...@gm...>. Diff: --- .gitignore | 3 + auxprogs/s390-check-opcodes.pl | 7 +- docs/internals/s390-opcodes.csv | 590 +-- none/tests/s390x/Makefile.am | 6 +- none/tests/s390x/vector.c | 29 + none/tests/s390x/vector.h | 7 + none/tests/s390x/vector.stdout.exp | 9 + none/tests/s390x/vector_integer.c | 540 ++ none/tests/s390x/vector_integer.stderr.exp | 2 + none/tests/s390x/vector_integer.stdout.exp | 7317 ++++++++++++++++++++++++++++ none/tests/s390x/vector_integer.vgtest | 2 + none/tests/s390x/vector_string.c | 334 ++ none/tests/s390x/vector_string.stderr.exp | 2 + none/tests/s390x/vector_string.stdout.exp | 5436 +++++++++++++++++++++ none/tests/s390x/vector_string.vgtest | 2 + 15 files changed, 13988 insertions(+), 298 deletions(-) diff --git a/.gitignore b/.gitignore index 7b93983..7ae8ec4 100644 --- a/.gitignore +++ b/.gitignore @@ -1879,6 +1879,9 @@ /none/tests/s390x/lsc2 /none/tests/s390x/ppno /none/tests/s390x/traps +/none/tests/s390x/vector_string +/none/tests/s390x/vector_integer +/none/tests/s390x/high-word # /none/tests/scripts/ /none/tests/scripts/*.dSYM diff --git a/auxprogs/s390-check-opcodes.pl b/auxprogs/s390-check-opcodes.pl index 67687d2..c02e157 100755 --- a/auxprogs/s390-check-opcodes.pl +++ b/auxprogs/s390-check-opcodes.pl @@ -84,8 +84,11 @@ my @extended_mnemonics = ( "vlp[bhfg]", "vlrep[bhfg]", "vlvg[bhfg]", - "vmal*[eolh][bhfg]", - "vml*[eolh][bhf]", + "vmal?[eoh][bhfg]", + "vmal(b|hw|f)", + "vml(b|hw|f)", + "vml?(o|e)[bhf]", + "vml?h[bhf]", "vm[nx]l*[bhfg]", "vmr[lh][bhfg]", "vmslg", diff --git a/docs/internals/s390-opcodes.csv b/docs/internals/s390-opcodes.csv index fe84a7c..0dfce68 100644 --- a/docs/internals/s390-opcodes.csv +++ b/docs/internals/s390-opcodes.csv @@ -981,521 +981,521 @@ cxzt,"convert from zoned extended","not implemented",zEC12, czdt,"convert to zoned long","not implemented",zEC12, czxt,"convert to zoned extended","not implemented",zEC12, vfsdb,"vector fp subtract long","not implemented",z13 -vlpf,"vector load positive word","not implemented",z13 -verllh,"vector element rotate left logical mem halfword","not implemented",z13 +vlpf,"vector load positive word",implemented,z13 +verllh,"vector element rotate left logical mem halfword",implemented,z13 vzero,"vector set to zero","not implemented",z13 -vmalof,"vector multiply and add logical odd word","not implemented",z13 +vmalof,"vector multiply and add logical odd word",implemented,z13 vleif,"vector load word element immediate",implemented,z13 -vlpb,"vector load positive byte","not implemented",z13 -vmxlh,"vector maximum logical halfword","not implemented",z13 +vlpb,"vector load positive byte",implemented,z13 +vmxlh,"vector maximum logical halfword",implemented,z13 vpksfs,"vector pack saturate word","not implemented",z13 -vfenezh,"vector find element not equal halfword","not implemented",z13 -vecl,"vector element compare logical","not implemented",z13 -verimb,"vector element rotate and insert under mask byte","not implemented",z13 -vaccq,"vector add compute carry quadword","not implemented",z13 +vfenezh,"vector find element not equal halfword","implemented",z13 +vecl,"vector element compare logical",implemented,z13 +verimb,"vector element rotate and insert under mask byte",implemented,z13 +vaccq,"vector add compute carry quadword",implemented,z13 vleh,"vector load halfword element","implemented",z13 vst,"vector store","implemented",z13 vsteg,"vector store double word element","implemented",z13 -vmnf,"vector minimum word","not implemented",z13 -vavgl,"vector average logical","not implemented",z13 +vmnf,"vector minimum word",implemented,z13 +vavgl,"vector average logical",implemented,z13 vfpsodb,"vector fp perform sign operation","not implemented",z13 llzrgf,"load logical and zero rightmost bytes 32->64","not implemented",z13 vledb,"vector fp load rounded","not implemented",z13 vldeb,"vector fp load lengthened","not implemented",z13 -vclzg,"vector count leading zeros doubleword","not implemented",z13 -vecg,"vector element compare double word","not implemented",z13 +vclzg,"vector count leading zeros doubleword",implemented,z13 +vecg,"vector element compare double word",implemented,z13 vpksgs,"vector pack saturate double word","not implemented",z13 vsel,"vector select","implemented",z13 vllezb,"vector load logical byte element and zero","implemented",z13 -vfaezh,"vector find any element equal","not implemented",z13 +vfaezh,"vector find any element equal","implemented",z13 vftci,"vector fp test data class immediate","not implemented",z13 -veclb,"vector element compare logical byte","not implemented",z13 +veclb,"vector element compare logical byte",implemented,z13 vuplhw,"vector unpack low halfword","not implemented",z13 -veslvb,"vector element shift left reg byte","not implemented",z13 +veslvb,"vector element shift left reg byte",implemented,z13 vuplh,"vector unpack logical high","implemented",z13 vlde,"vector fp load lengthened","not implemented",z13 -vmoh,"vector multiply odd halfword","not implemented",z13 -vfaehs,"vector find any element equal","not implemented",z13 +vmoh,"vector multiply odd halfword",implemented,z13 +vfaehs,"vector find any element equal","implemented",z13 vftcidb,"vector fp test data class immediate","not implemented",z13 -vaq,"vector add quad word","not implemented",z13 +vaq,"vector add quad word",implemented,z13 vlgvh,"vector load gr from vr halfword element","implemented",z13 -vchlg,"vector compare high logical double word","not implemented",z13 +vchlg,"vector compare high logical double word",implemented,z13 vlvgp,"vector load VR from GRs disjoint","implemented",z13 -vceqg,"vector compare equal double word","not implemented",z13 -vfeezh,"vector find element equal halfword","not implemented",z13 +vceqg,"vector compare equal double word",implemented,z13 +vfeezh,"vector find element equal halfword","implemented",z13 vlvgf,"vector load VR word element from GR","implemented",z13 vsteb,"vector store byte element","implemented",z13 vgmb,"vector generate mask byte","implemented",z13 vpklsf,"vector pack logical saturate word","implemented",z13 -vmao,"vector multiply and add odd","not implemented",z13 -vchf,"vector compare high word","not implemented",z13 -vesraf,"vector element shift right arithmetic mem word","not implemented",z13 -vsbiq,"vector subtract with borrow indication quadword","not implemented",z13 +vmao,"vector multiply and add odd",implemented,z13 +vchf,"vector compare high word",implemented,z13 +vesraf,"vector element shift right arithmetic mem word",implemented,z13 +vsbiq,"vector subtract with borrow indication quadword",implemented,z13 vuphb,"vector unpack high byte","implemented",z13 -vgfmb,"vector galois field multiply sum byte","not implemented",z13 +vgfmb,"vector galois field multiply sum byte",implemented,z13 vrepih,"vector replicate immediate halfword","implemented",z13 vcdlg,"vector fp convert from logical 64 bit","not implemented",z13 cxpt,"convert from packed to extended dfp","not implemented",z13 -vceqb,"vector compare equal byte","not implemented",z13 -vstrczfs,"vector string range compare word","not implemented",z13 +vceqb,"vector compare equal byte",implemented,z13 +vstrczfs,"vector string range compare word",implemented,z13 vpklshs,"vector pack logical saturate halfword","not implemented",z13 vlvgb,"vector load VR byte element from GR","implemented",z13 lcbb,"load count to block boundary","not implemented",z13 -vlcf,"vector load complement word","not implemented",z13 +vlcf,"vector load complement word",implemented,z13 vlvg,"vector load VR element from GR","implemented",z13 -vmalef,"vector multiply and add logical even word","not implemented",z13 +vmalef,"vector multiply and add logical even word",implemented,z13 vn,"vector and","implemented",z13 -vmae,"vector multiply and add even","not implemented",z13 -vstrc,"vector string range compare","not implemented",z13 +vmae,"vector multiply and add even",implemented,z13 +vstrc,"vector string range compare",implemented,z13 vfcedb,"vector fp compare equal","not implemented",z13 -vgfm,"vector galois field multiply sum","not implemented",z13 +vgfm,"vector galois field multiply sum",implemented,z13 vlrepb,"vector load and replicate byte elements","implemented",z13 -vgfmag,"vector galois field multiply sum and accumulate doubleword","not implemented",z13 +vgfmag,"vector galois field multiply sum and accumulate doubleword",implemented,z13 vflndb,"vector fp perform sign operation","not implemented",z13 -vmaeb,"vector multiply and add even byte","not implemented",z13 +vmaeb,"vector multiply and add even byte",implemented,z13 vpkg,"vector pack double word","not implemented",z13 -vsb,"vector subtract byte","not implemented",z13 -vchl,"vector compare high logical","not implemented",z13 +vsb,"vector subtract byte",implemented,z13 +vchl,"vector compare high logical",implemented,z13 vlvgh,"vector load VR halfword element from GR","implemented",z13 locghi,"load halfword immediate on condition into 64 bit gpr","not implemented",z13 -vmalb,"vector multiply and add low byte","not implemented",z13 +vmalb,"vector multiply and add low byte",implemented,z13 vchlgs,"vector compare high logical double word","not implemented",z13 vstef,"vector store word element","implemented",z13 lzrf,"load and zero rightmost byte 32->32","not implemented",z13 vmrlh,"vector merge low halfword","implemented",z13 vchbs,"vector compare high byte","not implemented",z13 -vesrlf,"vector element shift right logical mem word","not implemented",z13 -vmxf,"vector maximum word","not implemented",z13 +vesrlf,"vector element shift right logical mem word",implemented,z13 +vmxf,"vector maximum word",implemented,z13 vgmh,"vector generate mask halfword","implemented",z13 -vfenezb,"vector find element not equal byte","not implemented",z13 +vfenezb,"vector find element not equal byte","implemented",z13 vpklsgs,"vector pack logical saturate double word","not implemented",z13 vpksg,"vector pack saturate double word","implemented",z13 -vfaeh,"vector find any element equal halfword","not implemented",z13 -vmlof,"vector multiply logical odd word","not implemented",z13 -vmahh,"vector multiply and add high halfword","not implemented",z13 +vfaeh,"vector find any element equal halfword","implemented",z13 +vmlof,"vector multiply logical odd word",implemented,z13 +vmahh,"vector multiply and add high halfword",implemented,z13 vx,"vector exclusive or","implemented",z13 vchlfs,"vector compare high logical word","not implemented",z13 -vacccq,"vector add with carry compute carry quadword","not implemented",z13 -vchb,"vector compare high byte","not implemented",z13 -vmaloh,"vector multiply and add logical odd halfword","not implemented",z13 -vmleh,"vector multiply logical even halfword","not implemented",z13 -verimh,"vector element rotate and insert under mask halfword","not implemented",z13 +vacccq,"vector add with carry compute carry quadword",implemented,z13 +vchb,"vector compare high byte",implemented,z13 +vmaloh,"vector multiply and add logical odd halfword",implemented,z13 +vmleh,"vector multiply logical even halfword",implemented,z13 +verimh,"vector element rotate and insert under mask halfword",implemented,z13 vlrepf,"vector load and replicate word elements","implemented",z13 -vgfmg,"vector galois field multiply sum doubleword","not implemented",z13 +vgfmg,"vector galois field multiply sum doubleword",implemented,z13 vpklsg,"vector pack logical saturate double word","implemented",z13 -vesrlvf,"vector element shift right logical reg word","not implemented",z13 +vesrlvf,"vector element shift right logical reg word",implemented,z13 vrepg,"vector replicate double word","implemented",z13 -vmalob,"vector multiply and add logical odd byte","not implemented",z13 -vmxb,"vector maximum byte","not implemented",z13 -vmnl,"vector minimum logical","not implemented",z13 -vmng,"vector minimum doubleword","not implemented",z13 -vchlb,"vector compare high logical byte","not implemented",z13 +vmalob,"vector multiply and add logical odd byte",implemented,z13 +vmxb,"vector maximum byte",implemented,z13 +vmnl,"vector minimum logical",implemented,z13 +vmng,"vector minimum doubleword",implemented,z13 +vchlb,"vector compare high logical byte",implemented,z13 wfadb,"vector fp add","not implemented",z13 vmrl,"vector merge low","implemented",z13 wfk,"vector fp compare and signal scalar","not implemented",z13 vno,"vector nor","implemented",z13 -vstrcf,"vector string range compare word","not implemented",z13 +vstrcf,"vector string range compare word",implemented,z13 vfmsdb,"vector fp multiply and subtract","not implemented",z13 -vavgh,"vector average half word","not implemented",z13 +vavgh,"vector average half word",implemented,z13 vchlhs,"vector compare high logical half word","not implemented",z13 -vah,"vector add halfword","not implemented",z13 -vmalhh,"vector multiply and add logical high halfword","not implemented",z13 +vah,"vector add halfword",implemented,z13 +vmalhh,"vector multiply and add logical high halfword",implemented,z13 wldeb,"vector fp load lengthened","not implemented",z13 vmrh,"vector merge high","implemented",z13 vclgdb,"vector fp convert to logical 64 bit","not implemented",z13 wfsqdb,"vector fp square root","not implemented",z13 -vpopct,"vector population count","not implemented",z13 +vpopct,"vector population count",implemented,z13 vfenef,"vector find element not equal word","not implemented",z13 -vgfmf,"vector galois field multiply sum word","not implemented",z13 +vgfmf,"vector galois field multiply sum word",implemented,z13 vgmf,"vector generate mask word","implemented",z13 vleg,"vector load double word element","implemented",z13 -vmn,"vector minimum","not implemented",z13 +vmn,"vector minimum",implemented,z13 vrepi,"vector replicate immediate","implemented",z13 vsegb,"vector sign extend byte to double word","implemented",z13 cpxt,"convert from extended dfp to packed","not implemented",z13 wftcidb,"vector fp test data class immediate","not implemented",z13 wfchedbs,"vector fp compare high or equal","not implemented",z13 vpks,"vector pack saturate","implemented",z13 -veslg,"vector element shift left mem doubleword","not implemented",z13 +veslg,"vector element shift left mem doubleword",implemented,z13 vupllb,"vector unpack logical low byte","implemented",z13 -vscbig,"vector subtract compute borrow indication doubleword","not implemented",z13 +vscbig,"vector subtract compute borrow indication doubleword",implemented,z13 vsegh,"vector sign extend halfword to double word","implemented",z13 -vsumb,"vector sum across word - byte elements","not implemented",z13 +vsumb,"vector sum across word - byte elements",implemented,z13 vgeg,"vector gather element 8 byte elements","implemented",z13 vcgd,"vector fp convert to fixed 64 bit","not implemented",z13 vuplhb,"vector unpack logical high byte","implemented",z13 -verllv,"vector element rotate left logical reg","not implemented",z13 -vavgb,"vector average byte","not implemented",z13 -veclh,"vector element compare logical half word","not implemented",z13 +verllv,"vector element rotate left logical reg",implemented,z13 +vavgb,"vector average byte",implemented,z13 +veclh,"vector element compare logical half word",implemented,z13 vfmadb,"vector fp multiply and add","not implemented",z13 -vesravb,"vector element shift right arithmetic reg byte","not implemented",z13 -vmaleb,"vector multiply and add logical even byte","not implemented",z13 +vesravb,"vector element shift right arithmetic reg byte",implemented,z13 +vmaleb,"vector multiply and add logical even byte",implemented,z13 vuplf,"vector unpack low word","not implemented",z13 -vsbi,"vector subtract with borrow indication","not implemented",z13 +vsbi,"vector subtract with borrow indication",implemented,z13 vupll,"vector unpack logical low","implemented",z13 vmrhh,"vector merge high halfword","not implemented",z13 -vfenezbs,"vector find element not equal byte","not implemented",z13 -vmhb,"vector multiply high byte","not implemented",z13 +vfenezbs,"vector find element not equal byte",implemented,z13 +vmhb,"vector multiply high byte",implemented,z13 vfmdb,"vector fp multiply","not implemented",z13 -vesrlg,"vector element shift right logical mem doubleword","not implemented",z13 -vmahb,"vector multiply and add high byte","not implemented",z13 -vstrczf,"vector string range compare word","not implemented",z13 +vesrlg,"vector element shift right logical mem doubleword",implemented,z13 +vmahb,"vector multiply and add high byte",implemented,z13 +vstrczf,"vector string range compare word",implemented,z13 wfcedb,"vector fp compare equal","not implemented",z13 -vscbih,"vector subtract compute borrow indication halfword","not implemented",z13 -vlch,"vector load complement halfword","not implemented",z13 -vfenebs,"vector find element not equal byte","not implemented",z13 +vscbih,"vector subtract compute borrow indication halfword",implemented,z13 +vlch,"vector load complement halfword",implemented,z13 +vfenebs,"vector find element not equal byte",implemented,z13 vpklsh,"vector pack logical saturate halfword","implemented",z13 vlgv,"vector load gr from vr element","implemented",z13 vchfs,"vector compare high word","not implemented",z13 -vctzb,"vector count trailing zeros byte","not implemented",z13 -vfaef,"vector find any element equal word","not implemented",z13 -vstrch,"vector string range compare halfword","not implemented",z13 +vctzb,"vector count trailing zeros byte",implemented,z13 +vfaef,"vector find any element equal word",implemented,z13 +vstrch,"vector string range compare halfword",implemented,z13 wfidb,"vector load fp integer","not implemented",z13 vmrhb,"vector merge high byte","not implemented",z13 vuph,"vector unpack high","implemented",z13 vperm,"vector permute","implemented",z13 vrep,"vector replicate","implemented",z13 -vmalhb,"vector multiply and add logical high byte","not implemented",z13 +vmalhb,"vector multiply and add logical high byte",implemented,z13 vleib,"vector load byte element immediate","implemented",z13 -vavg,"vector average","not implemented",z13 +vavg,"vector average",implemented,z13 vfenefs,"vector find element not equal word","not implemented",z13 -vsumh,"vector sum across word - halfword elements","not implemented",z13 -vchh,"vector compare high half word","not implemented",z13 +vsumh,"vector sum across word - halfword elements",implemented,z13 +vchh,"vector compare high half word",implemented,z13 wcdgb,"vector fp convert from fixed 64 bit","not implemented",z13 -verllvb,"vector element rotate left logical reg byte","not implemented",z13 -vec,"vector element compare","not implemented",z13 +verllvb,"vector element rotate left logical reg byte",implemented,z13 +vec,"vector element compare",implemented,z13 vpdi,"vector permute double word immediate",implemented,z13 vfchedb,"vector fp compare high or equal long","not implemented",z13 -vchlh,"vector compare high logical half word","not implemented",z13 -vmaleh,"vector multiply and add logical even halfword","not implemented",z13 -vstrcb,"vector string range compare byte","not implemented",z13 -vsumqg,"vector sum across quadword - doubleword elements","not implemented",z13 -vlc,"vector load complement","not implemented",z13 +vchlh,"vector compare high logical half word",implemented,z13 +vmaleh,"vector multiply and add logical even halfword",implemented,z13 +vstrcb,"vector string range compare byte",implemented,z13 +vsumqg,"vector sum across quadword - doubleword elements",implemented,z13 +vlc,"vector load complement",implemented,z13 vlreph,"vector load and replicate halfword elements",implemented,z13 -vistrb,"vector isolate string byte","not implemented",z13 -vmo,"vector multiply odd","not implemented",z13 -vmxg,"vector maximum doubleword","not implemented",z13 -vsrab,"vector shift right arithmetic by byte","not implemented",z13 -vsbcbiq,"vector subtract with borrow compute borrow indication quadword","not implemented",z13 +vistrb,"vector isolate string byte",implemented,z13 +vmo,"vector multiply odd",implemented,z13 +vmxg,"vector maximum doubleword",implemented,z13 +vsrab,"vector shift right arithmetic by byte",implemented,z13 +vsbcbiq,"vector subtract with borrow compute borrow indication quadword",implemented,z13 wfchdb,"vector fp compare high long","not implemented",z13 -vmlhf,"vector multiply logical high word","not implemented",z13 -vesra,"vector element shift right arithmetic mem","not implemented",z13 -vmnh,"vector minimum halfword","not implemented",z13 +vmlhf,"vector multiply logical high word",implemented,z13 +vesra,"vector element shift right arithmetic mem",implemented,z13 +vmnh,"vector minimum halfword",implemented,z13 vled,"vector fp load rounded","not implemented",z13 -vstrczbs,"vector string range compare byte","not implemented",z13 -vaccb,"vector add compute carry byte","not implemented",z13 -vmahf,"vector multiply and add high word","not implemented",z13 +vstrczbs,"vector string range compare byte",implemented,z13 +vaccb,"vector add compute carry byte",implemented,z13 +vmahf,"vector multiply and add high word",implemented,z13 wfcedbs,"vector fp compare equal long","not implemented",z13 -vmeh,"vector multiply even halfword","not implemented",z13 -vclzb,"vector count leading zeros byte","not implemented",z13 -vmh,"vector multiply high","not implemented",z13 +vmeh,"vector multiply even halfword",implemented,z13 +vclzb,"vector count leading zeros byte",implemented,z13 +vmh,"vector multiply high",implemented,z13 vllez,"vector load logical element and zero",implemented,z13 -vnc,"vector and with complement","not implemented",z13 -vesrlvg,"vector element shift right logical reg doubleword","not implemented",z13 +vnc,"vector and with complement",implemented,z13 +vesrlvg,"vector element shift right logical reg doubleword",implemented,z13 vrepif,"vector replicate immediate word",implemented,z13 vfd,"vector fp divide","not implemented",z13 -vesrlb,"vector element shift right logical mem byte","not implemented",z13 -vavglg,"vector average logical double word","not implemented",z13 +vesrlb,"vector element shift right logical mem byte",implemented,z13 +vavglg,"vector average logical double word",implemented,z13 vpksh,"vector pack saturate halfword",implemented,z13 -veslv,"vector element shift left reg","not implemented",z13 +veslv,"vector element shift left reg",implemented,z13 vone,"vector set to ones","not implemented",z13 -vsrl,"vector shift right logical","not implemented",z13 +vsrl,"vector shift right logical",implemented,z13 vcdg,"vector fp convert from fixed 64 bit","not implemented",z13 -vmlhw,"vector multiply low halfword","not implemented",z13 -vscbib,"vector subtract compute borrow indication byte","not implemented",z13 +vmlhw,"vector multiply low halfword",implemented,z13 +vscbib,"vector subtract compute borrow indication byte",implemented,z13 vrepib,"vector replicate immediate byte",implemented,z13 vpk,"vector pack",implemented,z13 -vmhh,"vector multiply high halfword","not implemented",z13 -vfaezhs,"vector find any element equal","not implemented",z13 -vaf,"vector add word","not implemented",z13 -vmalh,"vector multiply and add logical high","not implemented",z13 +vmhh,"vector multiply high halfword",implemented,z13 +vfaezhs,"vector find any element equal",implemented,z13 +vaf,"vector add word",implemented,z13 +vmalh,"vector multiply and add logical high",implemented,z13 vgmg,"vector generate mask double word",implemented,z13 -vstrczh,"vector string range compare halfword","not implemented",z13 -vag,"vector add double word","not implemented",z13 +vstrczh,"vector string range compare halfword",implemented,z13 +vag,"vector add double word",implemented,z13 vllezf,"vector load logical word element and zero",implemented,z13 -vistrbs,"vector isolate string byte","not implemented",z13 +vistrbs,"vector isolate string byte",implemented,z13 vstm,"vector store multiple",implemented,z13 -vgfmh,"vector galois field multiply sum halfword","not implemented",z13 -verllvf,"vector element rotate left logical reg word","not implemented",z13 -vsra,"vector shift right arithmetic","not implemented",z13 -vslb,"vector shift left by byte","not implemented",z13 -vesravf,"vector element shift right arithmetic reg word","not implemented",z13 +vgfmh,"vector galois field multiply sum halfword",implemented,z13 +verllvf,"vector element rotate left logical reg word",implemented,z13 +vsra,"vector shift right arithmetic",implemented,z13 +vslb,"vector shift left by byte",implemented,z13 +vesravf,"vector element shift right arithmetic reg word",implemented,z13 vfcedbs,"vector fp compare equal long","not implemented",z13 vceqbs,"vector compare equal byte","not implemented",z13 -vsbcbi,"vector subtract with borrow compute borrow indication","not implemented",z13 -vmle,"vector multiply logical even","not implemented",z13 -vfaezfs,"vector find any element equal","not implemented",z13 -vsumg,"vector sum across doubleword","not implemented",z13 -vfaeb,"vector find any element equal byte","not implemented",z13 +vsbcbi,"vector subtract with borrow compute borrow indication",implemented,z13 +vmle,"vector multiply logical even",implemented,z13 +vfaezfs,"vector find any element equal",implemented,z13 +vsumg,"vector sum across doubleword",implemented,z13 +vfaeb,"vector find any element equal byte","implemented",z13 vleih,"vector load halfword element immediate",implemented,z13 -vmlob,"vector multiply logical odd byte","not implemented",z13 +vmlob,"vector multiply logical odd byte",implemented,z13 vllezh,"vector load logical halfword element and zero",implemented,z13 -vmalo,"vector multiply and add logical odd","not implemented",z13 -vclzh,"vector count leading zeros halfword","not implemented",z13 -vesravh,"vector element shift right arithmetic reg halfword","not implemented",z13 +vmalo,"vector multiply and add logical odd",implemented,z13 +vclzh,"vector count leading zeros halfword",implemented,z13 +vesravh,"vector element shift right arithmetic reg halfword",implemented,z13 vceqfs,"vector compare equal word","not implemented",z13 -vlp,"vector load positive","not implemented",z13 +vlp,"vector load positive",implemented,z13 wfmsdb,"vector fp multiply and subtract long","not implemented",z13 -vstrcbs,"vector string range compare byte","not implemented",z13 -vaccg,"vector add compute carry doubleword","not implemented",z13 +vstrcbs,"vector string range compare byte",implemented,z13 +vaccg,"vector add compute carry doubleword",implemented,z13 wfsdb,"vector fp subtract long","not implemented",z13 -vfee,"vector find element equal","not implemented",z13 -vmxh,"vector maximum halfword","not implemented",z13 -vtm,"vector test under mask","not implemented",z13 -vctzf,"vector count trailing zeros word","not implemented",z13 +vfee,"vector find element equal","implemented",z13 +vmxh,"vector maximum halfword",implemented,z13 +vtm,"vector test under mask",implemented,z13 +vctzf,"vector count trailing zeros word",implemented,z13 vfms,"vector fp multiply and subtract","not implemented",z13 -vavgg,"vector average double word","not implemented",z13 -vistr,"vector isolate string","not implemented",z13 -vesrlvb,"vector element shift right logical reg byte","not implemented",z13 -vesrl,"vector element shift right logical mem","not implemented",z13 -vmah,"vector multiply and add high","not implemented",z13 -vesrlvh,"vector element shift right logical reg halfword","not implemented",z13 -vesrah,"vector element shift right arithmetic mem halfword","not implemented",z13 +vavgg,"vector average double word",implemented,z13 +vistr,"vector isolate string",implemented,z13 +vesrlvb,"vector element shift right logical reg byte",implemented,z13 +vesrl,"vector element shift right logical mem",implemented,z13 +vmah,"vector multiply and add high",implemented,z13 +vesrlvh,"vector element shift right logical reg halfword",implemented,z13 +vesrah,"vector element shift right arithmetic mem halfword",implemented,z13 vrepig,"vector replicate immediate double word",implemented,z13 wfddb,"vector fp divide long","not implemented",z13 -vmhf,"vector multiply high word","not implemented",z13 +vmhf,"vector multiply high word",implemented,z13 vupllf,"vector unpack logical low word",implemented,z13 -veslf,"vector element shift left mem word","not implemented",z13 +veslf,"vector element shift left mem word",implemented,z13 wflpdb,"vector fp perform sign operation long","not implemented",z13 -vscbi,"vector subtract compute borrow indication","not implemented",z13 -vmnlb,"vector minimum logical byte","not implemented",z13 -veslh,"vector element shift left mem halfword","not implemented",z13 -vfaebs,"vector find any element equal","not implemented",z13 +vscbi,"vector subtract compute borrow indication",implemented,z13 +vmnlb,"vector minimum logical byte",implemented,z13 +veslh,"vector element shift left mem halfword",implemented,z13 +vfaebs,"vector find any element equal","implemented",z13 vleb,"vector load byte element",implemented,z13 -vfaezb,"vector find any element equal","not implemented",z13 +vfaezb,"vector find any element equal","implemented",z13 vlbb,"vector load to block boundary",implemented,z13 vflcdb,"vector fp perform sign operation long","not implemented",z13 -vmlo,"vector multiply logical odd","not implemented",z13 +vmlo,"vector multiply logical odd",implemented,z13 vlgvf,"vector load gr from vr word element",implemented,z13 -vavgf,"vector average word","not implemented",z13 -veslvh,"vector element shift left reg halfword","not implemented",z13 -vacch,"vector add compute carry halfword","not implemented",z13 -vsumgh,"vector sum across doubleword - halfword","not implemented",z13 -vmaeh,"vector multiply and add even halfword","not implemented",z13 -vmnlh,"vector minimum logical halfword","not implemented",z13 +vavgf,"vector average word",implemented,z13 +veslvh,"vector element shift left reg halfword",implemented,z13 +vacch,"vector add compute carry halfword",implemented,z13 +vsumgh,"vector sum across doubleword - halfword",implemented,z13 +vmaeh,"vector multiply and add even halfword",implemented,z13 +vmnlh,"vector minimum logical halfword",implemented,z13 vstl,"vector store with length",implemented,z13 wfmadb,"vector fp multiply and add long","not implemented",z13 -vme,"vector multiply even","not implemented",z13 +vme,"vector multiply even",implemented,z13 wfmdb,"vector fp multiply long","not implemented",z13 wflcdb,"vector fp perform sign operation long","not implemented",z13 vreph,"vector replicate halfword",implemented,z13 vclgd,"vector fp convert to logical 64 bit","not implemented",z13 vpkls,"vector pack logical saturate",implemented,z13 -vsf,"vector subtract word","not implemented",z13 +vsf,"vector subtract word",implemented,z13 vflpdb,"vector fp perform sign operation long","not implemented",z13 -vesrlv,"vector element shift right logical reg","not implemented",z13 +vesrlv,"vector element shift right logical reg",implemented,z13 vpklsfs,"vector pack logical saturate word","not implemented",z13 vcdgb,"vector fp convert from fixed 64 bit","not implemented",z13 -verll,"vector element rotate left logical mem","not implemented",z13 -vfeezf,"vector find element equal word","not implemented",z13 +verll,"vector element rotate left logical mem",implemented,z13 +vfeezf,"vector find element equal word","implemented",z13 wclgdb,"vector fp convert to logical 64 bit","not implemented",z13 -vgfma,"vector galois field multiply sum and accumulate","not implemented",z13 -vmob,"vector multiply odd byte","not implemented",z13 -vfeneb,"vector find element not equal byte","not implemented",z13 -vfene,"vector find element not equal","not implemented",z13 -vfenezfs,"vector find element not equal word","not implemented",z13 -vmal,"vector multiply and add low","not implemented",z13 +vgfma,"vector galois field multiply sum and accumulate",implemented,z13 +vmob,"vector multiply odd byte",implemented,z13 +vfeneb,"vector find element not equal byte","implemented",z13 +vfene,"vector find element not equal","implemented",z13 +vfenezfs,"vector find element not equal word","implemented",z13 +vmal,"vector multiply and add low",implemented,z13 vfchdb,"vector fp compare high long","not implemented",z13 -vfeezb,"vector find element equal byte","not implemented",z13 -vfae,"vector find any element equal","not implemented",z13 +vfeezb,"vector find element equal byte","implemented",z13 +vfae,"vector find any element equal","implemented",z13 vfchdbs,"vector fp compare high long","not implemented long",z13 vsceg,"vector scatter element 8 byte",implemented,z13 -vfeezfs,"vector find element equal word","not implemented",z13 -vsumgf,"vector sum across doubleword - word","not implemented",z13 -vmnb,"vector minimum byte","not implemented",z13 +vfeezfs,"vector find element equal word","implemented",z13 +vsumgf,"vector sum across doubleword - word",implemented,z13 +vmnb,"vector minimum byte",implemented,z13 vlef,"vector load word element",implemented,z13 vceqgs,"vector compare equal double word","not implemented",z13 -vech,"vector element compare half word","not implemented",z13 -vctz,"vector count trailing zeros","not implemented",z13 -vmloh,"vector multiply logical odd halfword","not implemented",z13 -vaccc,"vector add with carry compute carry","not implemented",z13 -vmale,"vector multiply and add logical even","not implemented",z13 +vech,"vector element compare half word",implemented,z13 +vctz,"vector count trailing zeros",implemented,z13 +vmloh,"vector multiply logical odd halfword",implemented,z13 +vaccc,"vector add with carry compute carry",implemented,z13 +vmale,"vector multiply and add logical even",implemented,z13 vsteh,"vector store halfword element",implemented,z13 -vceq,"vector compare equal","not implemented",z13 +vceq,"vector compare equal",implemented,z13 vfchedbs,"vector fp compare high or equal long","not implemented",z13 -vesl,"vector element shift left mem","not implemented",z13 -vesrav,"vector element shift right arithmetic reg","not implemented",z13 +vesl,"vector element shift left mem",implemented,z13 +vesrav,"vector element shift right arithmetic reg",implemented,z13 vfma,"vector fp multiply and add","not implemented",z13 -vmnlg,"vector minimum logical doubleword","not implemented",z13 -vclz,"vector count leading zeros","not implemented",z13 +vmnlg,"vector minimum logical doubleword",implemented,z13 +vclz,"vector count leading zeros",implemented,z13 vmrlf,"vector merge low word",implemented,z13 -vistrh,"vector isolate string halfword","not implemented",z13 -vmxlb,"vector maximum logical byte","not implemented",z13 +vistrh,"vector isolate string halfword",implemented,z13 +vmxlb,"vector maximum logical byte",implemented,z13 vfs,"vector fp subtract","not implemented",z13 vfm,"vector fp multiply","not implemented",z13 vll,"vector load with length",implemented,z13 vleig,"vector load double word element immediate",implemented,z13 -vfaezbs,"vector find any element equal","not implemented",z13 -veslvg,"vector element shift left reg doubleword","not implemented",z13 +vfaezbs,"vector find any element equal","implemented",z13 +veslvg,"vector element shift left reg doubleword",implemented,z13 locfh,"load high on condition from memory","not implemented",z13 -vfeeb,"vector find element equal byte","not implemented",z13 -vsumq,"vector sum across quadword","not implemented",z13 -vmleb,"vector multiply logical even byte","not implemented",z13 -vesrag,"vector element shift right arithmetic mem doubleword","not implemented",z13 -vceqh,"vector compare equal half word","not implemented",z13 -vmalf,"vector multiply and add low word","not implemented",z13 -vstrchs,"vector string range compare halfword","not implemented",z13 +vfeeb,"vector find element equal byte","implemented",z13 +vsumq,"vector sum across quadword",implemented,z13 +vmleb,"vector multiply logical even byte",implemented,z13 +vesrag,"vector element shift right arithmetic mem doubleword",implemented,z13 +vceqh,"vector compare equal half word",implemented,z13 +vmalf,"vector multiply and add low word",implemented,z13 +vstrchs,"vector string range compare halfword",implemented,z13 vcgdb,"vector fp convert to fixed 64 bit","not implemented",z13 -vsq,"vector subtract quadword","not implemented",z13 +vsq,"vector subtract quadword",implemented,z13 vnot,"vector not","not implemented",z13 vfch,"vector fp compare high","not implemented",z13 lochi,"load halfword immediate on condition into 32 bit gpr","not implemented",z13 -verllvh,"vector element rotate left logical reg halfword","not implemented",z13 +verllvh,"vector element rotate left logical reg halfword",implemented,z13 cpdt,"convert from long dfp to packed","not implemented",z13 vrepb,"vector replicate byte","implemented",z13 ppno,"perform pseudorandom number operation","not implemented",z13 -vfeef,"vector find element equal word","not implemented",z13 -vac,"vector add with carry","not implemented",z13 -verimf,"vector element rotate and insert under mask word","not implemented",z13 +vfeef,"vector find element equal word","implemented",z13 +vac,"vector add with carry",implemented,z13 +verimf,"vector element rotate and insert under mask word",implemented,z13 vfi,"vector load fp integer","not implemented",z13 -vistrfs,"vector isolate string word","not implemented",z13 -vecf,"vector element compare word","not implemented",z13 -vfeezbs,"vector find element equal byte","not implemented",z13 +vistrfs,"vector isolate string word",implemented,z13 +vecf,"vector element compare word",implemented,z13 +vfeezbs,"vector find element equal byte","implemented",z13 wflndb,"vector fp perform sign operation long","not implemented",z13 -vscbif,"vector subtract compute borrow indication word","not implemented",z13 +vscbif,"vector subtract compute borrow indication word",implemented,z13 vchhs,"vector compare high half word","not implemented",z13 -vmlb,"vector multiply low byte","not implemented",z13 -veslvf,"vector element shift left reg word","not implemented",z13 -vfaefs,"vector find any element equal","not implemented",z13 +vmlb,"vector multiply low byte",implemented,z13 +veslvf,"vector element shift left reg word",implemented,z13 +vfaefs,"vector find any element equal","implemented",z13 vlrep,"vector load and replicate",implemented,z13 -vaccf,"vector add compute carry word","not implemented",z13 +vaccf,"vector add compute carry word",implemented,z13 vpksf,"vector pack saturate word",implemented,z13 -vavglf,"vector average logical word","not implemented",z13 -vmef,"vector multiply even word","not implemented",z13 +vavglf,"vector average logical word",implemented,z13 +vmef,"vector multiply even word",implemented,z13 vuplhh,"vector unpack logical high halfword",implemented,z13 -vmxl,"vector maximum logical","not implemented",z13 -vgfmah,"vector galois field multiply sum and accumulate halfword","not implemented",z13 -vmalhf,"vector multiply and add logical high word","not implemented",z13 -vsh,"vector subtract halfword","not implemented",z13 +vmxl,"vector maximum logical",implemented,z13 +vgfmah,"vector galois field multiply sum and accumulate halfword",implemented,z13 +vmalhf,"vector multiply and add logical high word",implemented,z13 +vsh,"vector subtract halfword",implemented,z13 vuplb,"vector unpack low byte",implemented,z13 vsegf,"vector sign extend word to double word",implemented,z13 -vmxlf,"vector maximum logical word","not implemented",z13 +vmxlf,"vector maximum logical word",implemented,z13 wcdlgb,"vector fp convert from logical 64 bit","not implemented",z13 -vstrczb,"vector string range compare byte","not implemented",z13 -vsldb,"vector shift left double by byte","not implemented",z13 -vesrlh,"vector element shift right logical mem halfword","not implemented",z13 +vstrczb,"vector string range compare byte",implemented,z13 +vsldb,"vector shift left double by byte",implemented,z13 +vesrlh,"vector element shift right logical mem halfword",implemented,z13 cdpt,"convert from packed to long dfp","not implemented",z13 -vlcb,"vector load complement byte","not implemented",z13 +vlcb,"vector load complement byte",implemented,z13 wfpsodb,"vector fp perform sign operation long","not implemented",z13 -vsum,"vector sum across word","not implemented",z13 -vfeehs,"vector find element equal halfword","not implemented",z13 -vml,"vector multiply low","not implemented",z13 +vsum,"vector sum across word",implemented,z13 +vfeehs,"vector find element equal halfword",implemented,z13 +vml,"vector multiply low",implemented,z13 vuphh,"vector unpack high halfword",implemented,z13 -vavglb,"vector average logical byte","not implemented",z13 -vmlf,"vector multiply low word","not implemented",z13 +vavglb,"vector average logical byte",implemented,z13 +vmlf,"vector multiply low word",implemented,z13 wledb,"vector fp load rounded long to short","not implemented",z13 -vstrcfs,"vector string range compare word","not implemented",z13 +vstrcfs,"vector string range compare word",implemented,z13 wcgdb,"vector fp convert to fixed 64 bit","not implemented",z13 -vlph,"vector load positive halfword","not implemented",z13 -vfenezf,"vector find element not equal word","not implemented",z13 +vlph,"vector load positive halfword",implemented,z13 +vfenezf,"vector find element not equal word",implemented,z13 vseg,"vector sign extend to double word",implemented,z13 -vcksm,"vector checksum","not implemented",z13 -vsrlb,"vector shift right logical by byte","not implemented",z13 -verimg,"vector element rotate and insert under mask doubleword","not implemented",z13 -vesravg,"vector element shift right arithmetic reg doubleword","not implemented",z13 -vmlhh,"vector multiply logical high halfword","not implemented",z13 -vfaezf,"vector find any element equal","not implemented",z13 -vfenehs,"vector find element not equal halfword","not implemented",z13 +vcksm,"vector checksum",implemented,z13 +vsrlb,"vector shift right logical by byte",implemented,z13 +verimg,"vector element rotate and insert under mask doubleword",implemented,z13 +vesravg,"vector element shift right arithmetic reg doubleword",implemented,z13 +vmlhh,"vector multiply logical high halfword",implemented,z13 +vfaezf,"vector find any element equal",implemented,z13 +vfenehs,"vector find element not equal halfword",implemented,z13 vlr,"vector register load","implemented",z13 vgbm,"vector generate byte mask","implemented",z13 -vmnlf,"vector minimum logical word","not implemented",z13 +vmnlf,"vector minimum logical word",implemented,z13 vlm,"vector load multiple","implemented",z13 vmrlb,"vector merge low byte","implemented",z13 -vavglh,"vector average logical half word","not implemented",z13 +vavglh,"vector average logical half word",implemented,z13 wfkdb,"vector fp compare and signal scalar","not implemented",z13 -veslb,"vector element shift left mem byte","not implemented",z13 +veslb,"vector element shift left mem byte",implemented,z13 wfchedb,"vector fp compare high or equal","not implemented",z13 vllezg,"vector load logical double word element and zero","implemented",z13 -vmaob,"vector multiply and add odd byte","not implemented",z13 +vmaob,"vector multiply and add odd byte",implemented,z13 vmrhf,"vector merge high word","not implemented",z13 -vchg,"vector compare high double word","not implemented",z13 +vchg,"vector compare high double word",implemented,z13 locfhr,"load high on condition from gpr","not implemented",z13 -vlpg,"vector load positive doubleword","not implemented",z13 +vlpg,"vector load positive doubleword",implemented,z13 vcdlgb,"vector fp convert from logical 64 bit","not implemented",z13 -vstrczhs,"vector string range compare halfword","not implemented",z13 -vecb,"vector element compare byte","not implemented",z13 -vmxlg,"vector maximum logical doubleword","not implemented",z13 +vstrczhs,"vector string range compare halfword",implemented,z13 +vecb,"vector element compare byte",implemented,z13 +vmxlg,"vector maximum logical doubleword",implemented,z13 vfpso,"vector fp perform sign operation","not implemented",z13 -verim,"vector element rotate and insert under mask","not implemented",z13 -vsumqf,"vector sum across quadword - word elements","not implemented",z13 -vfeefs,"vector find element equal word","not implemented",z13 +verim,"vector element rotate and insert under mask",implemented,z13 +vsumqf,"vector sum across quadword - word elements",implemented,z13 +vfeefs,"vector find element equal word","implemented",z13 vfche,"vector fp compare high or equal","not implemented",z13 -vistrhs,"vector isolate string halfword","not implemented",z13 -vsl,"vector shift left","not implemented",z13 -vfenezhs,"vector find element not equal halfword","not implemented",z13 -vsg,"vector subtract doubleword","not implemented",z13 -vclzf,"vector count leading zeros word","not implemented",z13 +vistrhs,"vector isolate string halfword",implemented,z13 +vsl,"vector shift left",implemented,z13 +vfenezhs,"vector find element not equal halfword",implemented,z13 +vsg,"vector subtract doubleword",implemented,z13 +vclzf,"vector count leading zeros word",implemented,z13 wfcdb,"vector fp compare scalar long","not implemented",z13 -vmaoh,"vector multiply and add odd halfword","not implemented",z13 +vmaoh,"vector multiply and add odd halfword",implemented,z13 vchgs,"vector compare high double word","not implemented",z13 -vchlf,"vector compare high logical word","not implemented",z13 -va,"vector add","not implemented",z13 +vchlf,"vector compare high logical word",implemented,z13 +va,"vector add",implemented,z13 vmrlg,"vector merge low double word",implemented,z13 -vlcg,"vector load complement doubleword","not implemented",z13 -vceqf,"vector compare equal word","not implemented",z13 -vacq,"vector add with carry quadword","not implemented",z13 -vmaof,"vector multiply and add odd word","not implemented",z13 +vlcg,"vector load complement doubleword",implemented,z13 +vceqf,"vector compare equal word",implemented,z13 +vacq,"vector add with carry quadword",implemented,z13 +vmaof,"vector multiply and add odd word",implemented,z13 vfadb,"vector fp add long","not implemented",z13 -vmlef,"vector multiply logical even word","not implemented",z13 +vmlef,"vector multiply logical even word",implemented,z13 wfc,"vector fp compare scalar","not implemented",z13 -vmx,"vector maximum","not implemented",z13 -vmlh,"vector multiply logical high","not implemented",z13 -vmeb,"vector multiply even byte","not implemented",z13 +vmx,"vector maximum",implemented,z13 +vmlh,"vector multiply logical high",implemented,z13 +vmeb,"vector multiply even byte",implemented,z13 vfddb,"vector fp divide long","not implemented",z13 vpkshs,"vector pack saturate halfword","not implemented",z13 vpkf,"vector pack word","not implemented",z13 vlrepg,"vector load and replicate double word elements",implemented,z13 -vmaef,"vector multiply and add even word","not implemented",z13 -vfeneh,"vector find element not equal halfword","not implemented",z13 -vgfmaf,"vector galois field multiply sum and accumulate word","not implemented",z13 -vctzg,"vector count trailing zeros doubleword","not implemented",z13 +vmaef,"vector multiply and add even word",implemented,z13 +vfeneh,"vector find element not equal halfword","implemented",z13 +vgfmaf,"vector galois field multiply sum and accumulate word",implemented,z13 +vctzg,"vector count trailing zeros doubleword",implemented,z13 lzrg,"load and zero rightmost byte 64->64","not implemented",z13 -vmof,"vector multiply odd word","not implemented",z13 +vmof,"vector multiply odd word",implemented,z13 vfsqdb,"vector fp square root long","not implemented",z13 vlgvg,"vector load gr from vr double word element",implemented,z13 -verllf,"vector element rotate left logical mem word","not implemented",z13 -verllg,"vector element rotate left logical mem doubleword","not implemented",z13 +verllf,"vector element rotate left logical mem word",implemented,z13 +verllg,"vector element rotate left logical mem doubleword",implemented,z13 vrepf,"vector replicate word",implemented,z13 -vfeezhs,"vector find element equal halfword","not implemented",z13 +vfeezhs,"vector find element equal halfword","implemented",z13 wfchdbs,"vector fp compare high long","not implemented",z13 lochhi,"load halfword high immediate on condition","not implemented",z13 vmalhw,"vector multiply and add low halfword","not implemented",z13 -vmlhb,"vector multiply logical high byte","not implemented",z13 -vfeeh,"vector find element equal halfword","not implemented",z13 +vmlhb,"vector multiply logical high byte",implemented,z13 +vfeeh,"vector find element equal halfword",implemented,z13 vgm,"vector generate mask",implemented,z13 -vgfmab,"vector galois field multiply sum and accumulate byte","not implemented",z13 +vgfmab,"vector galois field multiply sum and accumulate byte",implemented,z13 vmrhg,"vector merge high double word","not implemented",z13 -veclg,"vector element compare logical double word","not implemented",z13 +veclg,"vector element compare logical double word",implemented,z13 vl,"vector memory load",implemented,z13 -vctzh,"vector count trailing zeros halfword","not implemented",z13 +vctzh,"vector count trailing zeros halfword",implemented,z13 vuplhf,"vector unpack logical high word",implemented,z13 -verllvg,"vector element rotate left logical reg doubleword","not implemented",z13 +verllvg,"vector element rotate left logical reg doubleword",implemented,z13 vupl,"vector unpack low",implemented,z13 vlgvb,"vector load gr from vr byte element",implemented,z13 -vab,"vector add byte","not implemented",z13 -vch,"vector compare high","not implemented",z13 -veclf,"vector element compare logical word","not implemented",z13 +vab,"vector add byte",implemented,z13 +vch,"vector compare high",implemented,z13 +veclf,"vector element compare logical word",implemented,z13 vgef,"vector gather element 4 byte elements",implemented,z13 -vscbiq,"vector subtract compute borrow indication quadword","not implemented",z13 +vscbiq,"vector subtract compute borrow indication quadword",implemented,z13 cdgtr,"convert from fixed long dfp","not implemented",z13 -vesrab,"vector element shift right arithmetic mem byte","not implemented",z13 +vesrab,"vector element shift right arithmetic mem byte",implemented,z13 vfsq,"vector fp square root","not implemented",z13 vscef,"vector scatter element 4 byte",implemented,z13 vpkh,"vector pack halfword","not implemented",z13 vfa,"vector fp add","not implemented",z13 vo,"vector or",implemented,z13 -verllb,"vector element rotate left logical mem byte","not implemented",z13 +verllb,"vector element rotate left logical mem byte",implemented,z13 stocfh,"store high on condition","not implemented",z13 vchlbs,"vector compare high logical byte","not implemented",z13 vuphf,"vector unpack high word",implemented,z13 -vacc,"vector add compute carry","not implemented",z13 -vistrf,"vector isolate string word","not implemented",z13 +vacc,"vector add compute carry",implemented,z13 +vistrf,"vector isolate string word",implemented,z13 vceqhs,"vector compare equal half word","not implemented",z13 vfidb,"vector load fp integer long","not implemented",z13 vupllh,"vector unpack logical low halfword",implemented,z13 vfce,"vector fp compare equal","not implemented",z13 -vs,"vector subtract","not implemented",z13 -vfeebs,"vector find element equal byte","not implemented",z13 +vs,"vector subtract",implemented,z13 +vfeebs,"vector find element equal byte",implemented,z13 vlvgg,"vector load VR double word element from GR",implemented,z13 vbperm,"vector bit permute","not implemented",arch12 vllezlf,"vector load logical word element and zero - left aligned","not implemented","arch12" @@ -1504,7 +1504,7 @@ vmslg,"vector multiply sum logical double word","not implemented","arch12" vnx,"vector not exclusive or","not implemented","arch12" vnn,"vector nand","not implemented","arch12" voc,"vector or with complement","not implemented","arch12" -vpopctb,"vector population count byte","not implemented","arch12" +vpopctb,"vector population count byte",implemented,"arch12" vpopcth,"vector population count halfword","not implemented","arch12" vpopctf,"vector population count word","not implemented","arch12" vpopctg,"vector population count double word","not implemented","arch12" diff --git a/none/tests/s390x/Makefile.am b/none/tests/s390x/Makefile.am index ff9c291..77c00ba 100644 --- a/none/tests/s390x/Makefile.am +++ b/none/tests/s390x/Makefile.am @@ -18,7 +18,8 @@ INSN_TESTS = clc clcle cvb cvd icm lpr tcxb lam_stam xc mvst add sub mul \ spechelper-cr spechelper-clr \ spechelper-ltr spechelper-or \ spechelper-icm-1 spechelper-icm-2 spechelper-tmll \ - spechelper-tm laa vector lsc2 ppno + spechelper-tm laa vector lsc2 ppno vector_string vector_integer + if BUILD_DFP_TESTS INSN_TESTS += dfp-1 dfp-2 dfp-3 dfp-4 dfptest dfpext dfpconv srnmt pfpo endif @@ -68,3 +69,6 @@ fpext_CFLAGS = $(AM_CFLAGS) @FLAG_MLONG_DOUBLE_128@ ex_clone_LDADD = -lpthread vector_CFLAGS = $(AM_CFLAGS) -march=z13 lsc2_CFLAGS = -march=z13 -DS390_TESTS_NOCOLOR +vector_string_CFLAGS = $(AM_CFLAGS) -march=z13 -DS390_TEST_COUNT=5 +vector_integer_CFLAGS = $(AM_CFLAGS) -march=z13 -DS390_TEST_COUNT=4 + diff --git a/none/tests/s390x/vector.c b/none/tests/s390x/vector.c index 90671b0..5f4f9ab 100644 --- a/none/tests/s390x/vector.c +++ b/none/tests/s390x/vector.c @@ -148,6 +148,33 @@ s390_test_generate(vll_vstl, "vll %%v5, %[r_arg1], %[v_arg1]\n" \ s390_test_generate(vlbb, "vlbb %%v5, 60(%[r_memory_pool]), 0") +/* Test the correctness of work with VR's > 16. + VSEL is choosed just because it have four arguments. + + The algorithm (the tested VR's are %%v21 - %%v24): + - save tested VR's to temporary location + - copy compile-time known values to tested VR's + - perform VSEL on tested VR's + - copy tested VR's to printed results + - restore saved VR's from temporary location + */ +s390_test_generate(test_upper16_registers, \ + "vstm %%v21, %%v24, %[m_memory_pool]\n" \ + \ + "vlr %%v21, %%v1\n" \ + "vlr %%v22, %%v2\n" \ + "vlr %%v23, %%v3\n" \ + "vlr %%v24, %%v5\n" \ + \ + "vsel %%v24, %%v21, %%v22, %%v23\n" \ + \ + "vlr %%v1, %%v21\n" \ + "vlr %%v2, %%v22\n" \ + "vlr %%v3, %%v23\n" \ + "vlr %%v5, %%v24\n" \ + \ + "vlm %%v21, %%v24, %[m_memory_pool]\n") + int main() { size_t iteration = 0; randomize_memory_pool(); @@ -240,5 +267,7 @@ int main() { test(vscef, (randomize_memory_pool())); test(vsceg, (randomize_memory_pool())); + test_once(test_upper16_registers); + return 0; } diff --git a/none/tests/s390x/vector.h b/none/tests/s390x/vector.h index a6538b4..adefbcd 100644 --- a/none/tests/s390x/vector.h +++ b/none/tests/s390x/vector.h @@ -7,7 +7,9 @@ #include "string.h" /* How many times should every test be executed? */ +#ifndef S390_TEST_COUNT #define S390_TEST_COUNT 10 +#endif /* Test the instruction exactly one time. */ #define test_once(insn) test_##insn() @@ -170,4 +172,9 @@ static void test_##insn() \ printf(" r_result = "); print_uint64_t(r_result); \ } +/* Stores CC to %[r_result]. + Usefull when testing instructions which modify condition code. +*/ +#define S390_TEST_PUT_CC_TO_RESULT "ipm %[r_result] \n srl %[r_result], 28 \n" + #endif diff --git a/none/tests/s390x/vector.stdout.exp b/none/tests/s390x/vector.stdout.exp index f4e3fcb..ce08430 100644 --- a/none/tests/s390x/vector.stdout.exp +++ b/none/tests/s390x/vector.stdout.exp @@ -5353,3 +5353,12 @@ insn vsceg: r_arg2 = 05dd1429c4463510 r_arg3 = 2e4c1152e7cc3db9 r_result = 0000000000000000 +insn test_upper16_registers: + v_arg1 = afe87dd05d791ba9 | 92f27e2eeb6290af + v_arg2 = a0af1b8becffa34d | d20d9caf434fff72 + v_arg3 = a70b4021bc3fa7ad | e574fee9c86ab2ea + v_result = a7ac5b8a5cf903e9 | 92797e2ecb67ddba + r_arg1 = 59a6ee2c2a34fa3c + r_arg2 = 9dee771d02ee8535 + r_arg3 = c1ed05a482742c27 + r_result = 0000000000000000 diff --git a/none/tests/s390x/vector_integer.c b/none/tests/s390x/vector_integer.c new file mode 100644 index 0000000..f5d1830 --- /dev/null +++ b/none/tests/s390x/vector_integer.c @@ -0,0 +1,540 @@ +#include "vector.h" + +s390_test_generate(vab, "vab %%v5, %%v1, %%v2") +s390_test_generate(vah, "vah %%v5, %%v1, %%v2") +s390_test_generate(vaf, "vaf %%v5, %%v1, %%v2") +s390_test_generate(vag, "vag %%v5, %%v1, %%v2") +s390_test_generate(vaq, "vaq %%v5, %%v1, %%v2") + +s390_test_generate(vsb, "vsb %%v5, %%v1, %%v2") +s390_test_generate(vsh, "vsh %%v5, %%v1, %%v2") +s390_test_generate(vsf, "vsf %%v5, %%v1, %%v2") +s390_test_generate(vsg, "vsg %%v5, %%v1, %%v2") +s390_test_generate(vsq, "vsq %%v5, %%v1, %%v2") + +s390_test_generate(vn, "vn %%v5, %%v1, %%v2") +s390_test_generate(vnc, "vnc %%v5, %%v1, %%v2") +s390_test_generate(vx, "vx %%v5, %%v1, %%v2") +s390_test_generate(vo, "vo %%v5, %%v1, %%v2") +s390_test_generate(vno, "vno %%v5, %%v1, %%v2") + +s390_test_generate(vavgb, "vavgb %%v5, %%v1, %%v2") +s390_test_generate(vavgh, "vavgh %%v5, %%v1, %%v2") +s390_test_generate(vavgf, "vavgf %%v5, %%v1, %%v2") +s390_test_generate(vavgg, "vavgg %%v5, %%v1, %%v2") +s390_test_generate(vavglb, "vavglb %%v5, %%v1, %%v2") +s390_test_generate(vavglh, "vavglh %%v5, %%v1, %%v2") +s390_test_generate(vavglf, "vavglf %%v5, %%v1, %%v2") +s390_test_generate(vavglg, "vavglg %%v5, %%v1, %%v2") + +s390_test_generate(vmxb, "vmxb %%v5, %%v1, %%v2") +s390_test_generate(vmxh, "vmxh %%v5, %%v1, %%v2") +s390_test_generate(vmxf, "vmxf %%v5, %%v1, %%v2") +s390_test_generate(vmxg, "vmxg %%v5, %%v1, %%v2") +s390_test_generate(vmxlb, "vmxlb %%v5, %%v1, %%v2") +s390_test_generate(vmxlh, "vmxlh %%v5, %%v1, %%v2") +s390_test_generate(vmxlf, "vmxlf %%v5, %%v1, %%v2") +s390_test_generate(vmxlg, "vmxlg %%v5, %%v1, %%v2") + +s390_test_generate(vmnb, "vmnb %%v5, %%v1, %%v2") +s390_test_generate(vmnh, "vmnh %%v5, %%v1, %%v2") +s390_test_generate(vmnf, "vmnf %%v5, %%v1, %%v2") +s390_test_generate(vmng, "vmng %%v5, %%v1, %%v2") +s390_test_generate(vmnlb, "vmnlb %%v5, %%v1, %%v2") +s390_test_generate(vmnlh, "vmnlh %%v5, %%v1, %%v2") +s390_test_generate(vmnlf, "vmnlf %%v5, %%v1, %%v2") +s390_test_generate(vmnlg, "vmnlg %%v5, %%v1, %%v2") + +s390_test_generate(vlcb, "vlcb %%v5, %%v1") +s390_test_generate(vlch, "vlch %%v5, %%v1") +s390_test_generate(vlcf, "vlcf %%v5, %%v1") +s390_test_generate(vlcg, "vlcg %%v5, %%v1") + +s390_test_generate(vlpb, "vlpb %%v5, %%v1") +s390_test_generate(vlph, "vlph %%v5, %%v1") +s390_test_generate(vlpf, "vlpf %%v5, %%v1") +s390_test_generate(vlpg, "vlpg %%v5, %%v1") + +s390_test_generate(vchb, "vchb %%v5, %%v1, %%v2") +s390_test_generate(vchbs, "vchbs %%v5, %%v1, %%v2\n" \ + S390_TEST_PUT_CC_TO_RESULT) +s390_test_generate(vchh, "vchh %%v5, %%v1, %%v2") +s390_test_generate(vchhs, "vchhs %%v5, %%v1, %%v2\n" \ + S390_TEST_PUT_CC_TO_RESULT) +s390_test_generate(vchf, "vchf %%v5, %%v1, %%v2") +s390_test_generate(vchfs, "vchfs %%v5, %%v1, %%v2\n" \ + S390_TEST_PUT_CC_TO_RESULT) +s390_test_generate(vchg, "vchg %%v5, %%v1, %%v2") +s390_test_generate(vchgs, "vchgs %%v5, %%v1, %%v2\n" \ + S390_TEST_PUT_CC_TO_RESULT) +s390_test_generate(vchlb, "vchlb %%v5, %%v1, %%v2") +s390_test_generate(vchlbs, "vchlbs %%v5, %%v1, %%v2\n" \ + S390_TEST_PUT_CC_TO_RESULT) +s390_test_generate(vchlh, "vchlh %%v5, %%v1, %%v2") +s390_test_generate(vchlhs, "vchlhs %%v5, %%v1, %%v2\n" \ + S390_TEST_PUT_CC_TO_RESULT) +s390_test_generate(vchlf, "vchlf %%v5, %%v1, %%v2") +s390_test_generate(vchlfs, "vchlfs %%v5, %%v1, %%v2\n" \ + S390_TEST_PUT_CC_TO_... [truncated message content] |
|
From: Andreas A. <ar...@so...> - 2018-09-26 17:32:26
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=1cc1d564f4e9b33daa381c598dfc464c83080c15 commit 1cc1d564f4e9b33daa381c598dfc464c83080c15 Author: Andreas Arnez <ar...@li...> Date: Mon Sep 24 18:56:07 2018 +0200 s390x: Vector integer and string instruction support This adds z/Architecture vector integer and string instruction support. The main author of this patch is Vadim Barkov <vb...@gm...>. Some fixes were provided by Andreas Arnez <ar...@li...>. Diff: --- NEWS | 2 + VEX/priv/guest_s390_defs.h | 68 +- VEX/priv/guest_s390_helpers.c | 185 ++- VEX/priv/guest_s390_toIR.c | 2879 ++++++++++++++++++++++++++++++------- VEX/priv/host_s390_defs.c | 504 ++++++- VEX/priv/host_s390_defs.h | 44 +- VEX/priv/host_s390_isel.c | 636 +++++++- VEX/priv/ir_defs.c | 27 +- VEX/priv/s390_disasm.c | 4 +- VEX/priv/s390_disasm.h | 4 + VEX/pub/libvex_ir.h | 17 +- VEX/useful/test_main.c | 21 + docs/internals/3_13_BUGSTATUS.txt | 8 - memcheck/mc_main.c | 11 +- memcheck/mc_translate.c | 30 + memcheck/tests/vbit-test/irops.c | 9 + 16 files changed, 3809 insertions(+), 640 deletions(-) diff --git a/NEWS b/NEWS index 384cc9d..def0b4d 100644 --- a/NEWS +++ b/NEWS @@ -121,6 +121,8 @@ where XXXXXX is the bug number as listed below. == 387045 Valgrind crashing on High Sierra when testing any newly [..] 385334 PPC64, fix vpermr, xxperm, xxpermr mask value. 385408 s390x: z13 vector "support" instructions not implemented +385409 s390x: z13 vector integer instructions not implemented +385410 s390x: z13 vector string instructions not implemented 385412 s390x: new non-vector z13 instructions not implemented 385868 glibc ld.so _dl_runtime_resolve_avx_slow conditional jump warning. 385912 none/tests/rlimit_nofile fails on newer glibc/kernel. diff --git a/VEX/priv/guest_s390_defs.h b/VEX/priv/guest_s390_defs.h index 4f9e962..3bfecbe 100644 --- a/VEX/priv/guest_s390_defs.h +++ b/VEX/priv/guest_s390_defs.h @@ -80,8 +80,8 @@ ULong s390x_dirtyhelper_STCKF(ULong *addr); ULong s390x_dirtyhelper_STCKE(ULong *addr); ULong s390x_dirtyhelper_STFLE(VexGuestS390XState *guest_state, ULong *addr); void s390x_dirtyhelper_CUxy(UChar *addr, ULong data, ULong num_bytes); -ULong s390x_dirtyhelper_vec_binop(VexGuestS390XState *guest_state, ULong opcode, - ULong v1, ULong v2); +ULong s390x_dirtyhelper_vec_op(VexGuestS390XState *guest_state, + ULong details); ULong s390_do_cu12_cu14_helper1(UInt byte1, UInt etf3_and_m3_is_1); ULong s390_do_cu12_helper2(UInt byte1, UInt byte2, UInt byte3, UInt byte4, ULong stuff); @@ -261,25 +261,52 @@ extern ULong last_execute_target; /*--- Vector helpers. ---*/ /*------------------------------------------------------------*/ -/* Vector operatons which can change condition code */ +/* Vector operatons passed to s390x_dirtyhelper_vec_op(...) helper. + Please don't change ordering of elements and append new items + before S390_VEC_OP_LAST. */ enum { - S390_CC_VEC_INVALID = 0, - S390_CC_VEC_VPKS = 1, - S390_CC_VEC_VPKLS = 2, - S390_CC_VEC_LAST = 3 // supposed to be the last element in enum -} s390x_cc_vec_binop; - -/* Create an "object" which contain information about vector operation - and it's element size. Used for passing data to dirtyhelper with one argument. -*/ -#define s390x_cc_vec_opcode(op, elem_size) ( ((op) << 3) | ((elem_size) & 0x07)) - -/* Extract operation from opcode created with "s390x_cc_vec_opcode" macro */ -#define s390x_cc_vec_get_op(opcode) ((opcode) >> 3) - -/* Extract operation from opcode created with "s390x_cc_vec_opcode" macro */ -#define s390x_cc_vec_get_elem_size(opcode) ((opcode) & 0x07) - + S390_VEC_OP_INVALID = 0, + S390_VEC_OP_VPKS = 1, + S390_VEC_OP_VPKLS = 2, + S390_VEC_OP_VFAE = 3, + S390_VEC_OP_VFEE = 4, + S390_VEC_OP_VFENE = 5, + S390_VEC_OP_VISTR = 6, + S390_VEC_OP_VSTRC = 7, + S390_VEC_OP_VCEQ = 8, + S390_VEC_OP_VTM = 9, + S390_VEC_OP_VGFM = 10, + S390_VEC_OP_VGFMA = 11, + S390_VEC_OP_VMAH = 12, + S390_VEC_OP_VMALH = 13, + S390_VEC_OP_VCH = 14, + S390_VEC_OP_VCHL = 15, + S390_VEC_OP_LAST = 16 // supposed to be the last element in enum +} s390x_vec_op_t; + +/* Arguments of s390x_dirtyhelper_vec_op(...) which are packed into one + ULong variable. + */ +typedef union { + struct { + unsigned int op : 8; // should be an element of s390x_vec_op_t + unsigned int v1 : 5; // result of operation + unsigned int v2 : 5; // argument one of operation + unsigned int v3 : 5; // argument two of operation or + // zero for unary operations + + unsigned int v4 : 5; // argument two of operation or + // zero for unary and binary operations + + unsigned int m4 : 4; // field m4 of insn or zero if it's missing + unsigned int m5 : 4; // field m5 of insn or zero if it's missing + unsigned int read_only: 1; // don't write result to Guest State + unsigned int reserved : 27; // reserved for future + }; + ULong serialized; +} s390x_vec_op_details_t; + +STATIC_ASSERT(sizeof(s390x_vec_op_details_t) == sizeof(ULong)); /* Macro definitions for opcodes that are not generally available. @@ -293,6 +320,7 @@ enum { ".short 0x" #op1 #v1 #v2 "\n\t .int 0x" #v3 "0" #m5 "0" #m4 #rxb #op2 "\n\t" #define VL(v1, x2, b2, d2, rxb) VRX_VXBD(e7, v1, x2, b2, d2, rxb, 06) +#define VST(v1, x2, b2, d2, rxb) VRX_VXBD(e7, v1, x2, b2, d2, rxb, 0e) #define VPKS(v1, v2, v3, m4, m5, rxb) VRR_VVVMM(e7, v1, v2, v3, m5, m4, rxb, 97) #define VPKLS(v1, v2, v3, m4, m5, rxb) VRR_VVVMM(e7, v1, v2, v3, m5, m4, rxb, 95) diff --git a/VEX/priv/guest_s390_helpers.c b/VEX/priv/guest_s390_helpers.c index aeda677..3aec1f8 100644 --- a/VEX/priv/guest_s390_helpers.c +++ b/VEX/priv/guest_s390_helpers.c @@ -1210,23 +1210,6 @@ decode_bfp_rounding_mode(UInt irrm) psw >> 28; /* cc */ \ }) -/* This macro believes that arguments' addresses are in GPR1 and GPR2. - We use %%v16, %%v17 and %%v18 to avoid side effects in FPRs. -*/ -#define S390_CC_FOR_V128_BINOP(insn) \ -({ \ - /* VL(v1, x2, b2, d2, rxb) */ \ - __asm__ volatile ( \ - VL(1, 0, 1, 000, 8) \ - VL(2, 0, 2, 000, 8) \ - insn \ - "ipm %[psw]\n\t" \ - : [psw] "=d"(psw) \ - : "d"(arg1), "d"(arg2) \ - : "cc", "v16", "v17", "v18"); \ - psw >> 28; /* cc */ \ -}) - /* Convert an IRRoundingMode value to s390_dfp_round_t */ #if defined(VGA_s390x) static s390_dfp_round_t @@ -2488,48 +2471,156 @@ missed: #if defined(VGA_s390x) ULong -s390x_dirtyhelper_vec_binop(VexGuestS390XState *guest_state, ULong opcode, - ULong v1, ULong v2) +s390x_dirtyhelper_vec_op(VexGuestS390XState *guest_state, + const ULong serialized) { UInt psw; - UInt elem_size = s390x_cc_vec_get_elem_size(opcode); - UInt op = s390x_cc_vec_get_op(opcode); - /* S390_CC_FOR_V128_BINOP relies on exatly this GPRs numbers and names. */ - register ULong arg1 asm("1") = (ULong) &((&guest_state->guest_v0)[v1]); - register ULong arg2 asm("2") = (ULong) &((&guest_state->guest_v0)[v2]); - - switch(op) { - case S390_CC_VEC_VPKS: - /* VPKS(v1, v2, v3, m4, m5, rxb) */ - switch(elem_size) { - case 1: return S390_CC_FOR_V128_BINOP(VPKS(3, 1, 2, 1, 1, e)); - case 2: return S390_CC_FOR_V128_BINOP(VPKS(3, 1, 2, 2, 1, e)); - case 3: return S390_CC_FOR_V128_BINOP(VPKS(3, 1, 2, 3, 1, e)); - default: vassert(0); - } + s390x_vec_op_details_t details; + const s390x_vec_op_details_t* d = (const s390x_vec_op_details_t*) &details; + + details.serialized = serialized; + + vassert(d->op > S390_VEC_OP_INVALID && d->op < S390_VEC_OP_LAST); + static const UChar opcodes[][2] = { + {0x00, 0x00}, /* invalid */ + {0xe7, 0x97}, /* VPKS */ + {0xe7, 0x95}, /* VPKLS */ + {0xe7, 0x82}, /* VFAE */ + {0xe7, 0x80}, /* VFEE */ + {0xe7, 0x81}, /* VFENE */ + {0xe7, 0x5c}, /* VISTR */ + {0xe7, 0x8a}, /* VSTRC */ + {0xe7, 0xf8}, /* VCEQ */ + {0xe7, 0xd8}, /* VTM */ + {0xe7, 0xb4}, /* VGFM */ + {0xe7, 0xbc}, /* VGFMA */ + {0xe7, 0xab}, /* VMAH */ + {0xe7, 0xa9}, /* VMALH */ + {0xe7, 0xfb}, /* VCH */ + {0xe7, 0xf9}, /* VCHL */ + }; + + union { + struct { + unsigned int op1 : 8; + unsigned int v1 : 4; + unsigned int v2 : 4; + unsigned int v3 : 4; + unsigned int : 4; + unsigned int m5 : 4; + unsigned int : 4; + unsigned int m4 : 4; + unsigned int rxb : 4; + unsigned int op2 : 8; + } VRR; + struct { + unsigned int op1 : 8; + unsigned int v1 : 4; + unsigned int v2 : 4; + unsigned int v3 : 4; + unsigned int m5 : 4; + unsigned int m6 : 4; + unsigned int : 4; + unsigned int v4 : 4; + unsigned int rxb : 4; + unsigned int op2 : 8; + } VRRd; + UChar bytes[6]; + } the_insn; + + the_insn.VRR.op1 = opcodes[d->op][0]; + the_insn.bytes[1] = the_insn.bytes[2] + = the_insn.bytes[3] = the_insn.bytes[4] = 0; + the_insn.VRR.op2 = opcodes[d->op][1]; + + switch(d->op) { + case S390_VEC_OP_VISTR: + the_insn.VRR.v1 = 1; + the_insn.VRR.v2 = 2; + the_insn.VRR.rxb = 0b1100; + the_insn.VRR.m4 = d->m4; + the_insn.VRR.m5 = d->m5; + break; - case S390_CC_VEC_VPKLS: - /* VPKLS(v1, v2, v3, m4, m5, rxb) */ - switch(elem_size) { - case 1: return S390_CC_FOR_V128_BINOP(VPKLS(3, 1, 2, 1, 1, e)); - case 2: return S390_CC_FOR_V128_BINOP(VPKLS(3, 1, 2, 2, 1, e)); - case 3: return S390_CC_FOR_V128_BINOP(VPKLS(3, 1, 2, 3, 1, e)); - default: vassert(0); - } + case S390_VEC_OP_VTM: + the_insn.VRR.v1 = 2; + the_insn.VRR.v2 = 3; + the_insn.VRR.rxb = 0b1100; + break; + + case S390_VEC_OP_VPKS: + case S390_VEC_OP_VPKLS: + case S390_VEC_OP_VFAE: + case S390_VEC_OP_VFEE: + case S390_VEC_OP_VFENE: + case S390_VEC_OP_VCEQ: + case S390_VEC_OP_VGFM: + case S390_VEC_OP_VCH: + case S390_VEC_OP_VCHL: + the_insn.VRR.v1 = 1; + the_insn.VRR.v2 = 2; + the_insn.VRR.v3 = 3; + the_insn.VRR.rxb = 0b1110; + the_insn.VRR.m4 = d->m4; + the_insn.VRR.m5 = d->m5; + break; + + case S390_VEC_OP_VSTRC: + case S390_VEC_OP_VGFMA: + case S390_VEC_OP_VMAH: + case S390_VEC_OP_VMALH: + the_insn.VRRd.v1 = 1; + the_insn.VRRd.v2 = 2; + the_insn.VRRd.v3 = 3; + the_insn.VRRd.v4 = 4; + the_insn.VRRd.rxb = 0b1111; + the_insn.VRRd.m5 = d->m4; + the_insn.VRRd.m6 = d->m5; + break; default: - vex_printf("operation = %d\n", op); - vpanic("s390x_dirtyhelper_vec_binop: unknown operation"); + vex_printf("operation = %d\n", d->op); + vpanic("s390x_dirtyhelper_vec_op: unknown operation"); } - return 0; + const V128* guest_v = &(guest_state->guest_v0); + __asm__ volatile ( + "lgr %%r10, %[arg1]\n" + VL(2, 0, a, 000, 8) + "lgr %%r10, %[arg2]\n" + VL(3, 0, a, 000, 8) + "lgr %%r10, %[arg3]\n" + VL(4, 0, a, 000, 8) + "ex %[zero], %[insn]\n" + + "cijne %[read_only], 0, return_cc\n" + "lgr %%r10, %[res]\n" + VST(1, 0, a, 000, 8) + + "return_cc: " + "ipm %[psw]\n\t" + : [psw] "=d" (psw) + + : [res] "r" (&guest_v[d->v1]), + [arg1] "r" (&guest_v[d->v2]), + [arg2] "r" (&guest_v[d->v3]), + [arg3] "r" (&guest_v[d->v4]), + + [zero] "r" (0ULL), + [insn] "m" (the_insn), + [read_only] "r" (d->read_only) + + : "cc", "r10", "v16", "v17", "v18", "v19" + ); + + return psw >> 28; /* cc */ } #else ULong -s390x_dirtyhelper_vec_binop(VexGuestS390XState *guest_state, ULong opcode, - ULong v1, ULong v2) +s390x_dirtyhelper_vec_op(VexGuestS390XState *guest_state, ULong opcode, + ULong v1, ULong v2) { return 0; } #endif diff --git a/VEX/priv/guest_s390_toIR.c b/VEX/priv/guest_s390_toIR.c index 8f3fb6d..c594ad5 100644 --- a/VEX/priv/guest_s390_toIR.c +++ b/VEX/priv/guest_s390_toIR.c @@ -748,12 +748,18 @@ s390_cc_thunk_put1d128Z(UInt opc, IRTemp d1, IRTemp nd) s390_cc_thunk_fill(op, hi, lox, ndep); } +static void +s390_cc_set(IRTemp cc) +{ + vassert(typeOfIRTemp(irsb->tyenv, cc) == Ity_I64); + + s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkexpr(cc), mkU64(0), mkU64(0)); +} static void -s390_cc_set(UInt val) +s390_cc_set_val(UInt val) { - s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), - mkU64(val), mkU64(0), mkU64(0)); + s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkU64(val), mkU64(0), mkU64(0)); } /* Build IR to calculate the condition code from flags thunk. @@ -1536,7 +1542,7 @@ get_fpc_w0(void) /* Return the guest state offset of a vr register. */ static UInt -vr_offset(UInt archreg) +vr_offset(const UInt archreg) { static const UInt offset[32] = { S390X_GUEST_OFFSET(guest_v0), @@ -1580,14 +1586,14 @@ vr_offset(UInt archreg) /* Return the guest state offset of quadword of a vr register. */ static UInt -vr_qw_offset(UInt archreg) +vr_qw_offset(const UInt archreg) { return vr_offset(archreg) + 0; } /* Write quadword of a vr to the guest state. */ static void -put_vr_qw(UInt archreg, IRExpr *expr) +put_vr_qw(const UInt archreg, IRExpr *expr) { vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_V128); @@ -1596,7 +1602,7 @@ put_vr_qw(UInt archreg, IRExpr *expr) /* Read quadword of a vr register. */ static IRExpr * -get_vr_qw(UInt archreg) +get_vr_qw(const UInt archreg) { return IRExpr_Get(vr_qw_offset(archreg), Ity_V128); } @@ -1661,6 +1667,13 @@ vr_w3_offset(UInt archreg) return vr_offset(archreg) + 12; } +/* Read word #0 of a vr register. */ +static IRExpr * +get_vr_w0(UInt archreg) +{ + return IRExpr_Get(vr_dw0_offset(archreg), Ity_I32); +} + /* Read word #1 of a vr register. */ static IRExpr * get_vr_w1(UInt archreg) @@ -1668,6 +1681,13 @@ get_vr_w1(UInt archreg) return IRExpr_Get(vr_w1_offset(archreg), Ity_I32); } +/* Read word #2 of a vr register. */ +static IRExpr * +get_vr_w2(UInt archreg) +{ + return IRExpr_Get(vr_dw1_offset(archreg), Ity_I32); +} + /* Read word #3 of a vr register. */ static IRExpr * get_vr_w3(UInt archreg) @@ -1744,6 +1764,223 @@ s390_vr_get_type(const UChar m) return results[m]; } +/* Determine if Condition Code Set (CS) flag is set in m field */ +#define s390_vr_is_cs_set(m) (((m) & 0x1) != 0) + +/* Determine if Zero Search (ZS) flag is set in m field */ +#define s390_vr_is_zs_set(m) (((m) & 0b0010) != 0) + +/* Generates arg1 < arg2 (or arg1 <= arg2 if allow_equal == True) expression. + Arguments must have V128 type and are treated as unsigned 128-bit numbers. +*/ +static IRExpr* +s390_V128_compareLT128x1(IRExpr* arg1, IRExpr* arg2, Bool allow_equal) +{ + /* If high halves are equal + then we compare lower ones + otherwise we compare high halves. + */ + IRExpr* result; + result = mkite(binop(Iop_CmpEQ64, + unop(Iop_V128HIto64, arg1), + unop(Iop_V128HIto64, arg2) + ), + unop(Iop_1Uto64, + binop(allow_equal ? Iop_CmpLE64U : Iop_CmpLT64U, + unop(Iop_V128to64, arg1), + unop(Iop_V128to64, arg2) + ) + ), + unop(Iop_1Uto64, + binop(Iop_CmpLT64U, + unop(Iop_V128HIto64, arg1), + unop(Iop_V128HIto64, arg2) + ) + ) + ); + + return result; +} + +/* Generates arg1 == 0 expression. + Argument must have V128 type and is treated as unsigned 128-bit number. +*/ +static IRExpr* +s390_V128_isZero(IRExpr* arg) +{ + IRExpr* high_or_low = binop(Iop_Or64, + unop(Iop_V128to64, arg), + unop(Iop_V128HIto64, arg) + ); + + return unop(Iop_1Uto64, binop(Iop_CmpEQ64, high_or_low, mkU64(0ULL))); +} + +/* Generate the two's complement for arg. + Arg should be V128. +*/ +static IRExpr* +s390_V128_get_complement(IRExpr* arg, IRType type) +{ + IRExpr* notArg = unop(Iop_NotV128, arg); + IRExpr* ones; + IRExpr* result; + switch(type) { + case Ity_I8: + ones = unop(Iop_Dup8x16, mkU8(0x01)); + result = binop(Iop_Add8x16, notArg, ones); + break; + case Ity_I16: + ones = unop(Iop_Dup16x8, mkU16(0x0001)); + result = binop(Iop_Add16x8, notArg, ones); + break; + case Ity_I32: + ones = unop(Iop_Dup32x4, mkU32(0x00000001)); + result = binop(Iop_Add32x4, notArg, ones); + break; + case Ity_I64: + ones = binop(Iop_64HLtoV128, mkU64(0x1ULL), mkU64(0x1ULL)); + result = binop(Iop_Add64x2, notArg, ones); + break; + case Ity_V128: + ones = binop(Iop_64HLtoV128, mkU64(0x0ULL), mkU64(0x1ULL)); + result = binop(Iop_Add128x1, notArg, ones); + break; + default: + vpanic("s390_V128_get_complement: unknown type"); + } + + return result; +} + +/* # Elements are treated as 128-bit unsigned integers + For i = 0; i < elemCount; i++ do: + sum = arg1[i] + arg2[i] + result[i] = carry_out_bit(sum) + end + return result + */ +static IRExpr* +s390_V128_calculate_carry_out(IRExpr* arg1, IRExpr* arg2, IRType type, + Bool allow_equal) +{ + IRTemp sum = newTemp(Ity_V128); + IRExpr* mask; + IRExpr* comparison; + IRExpr* result; + switch(type){ + case Ity_I8: + assign(sum, binop(Iop_Add8x16, arg1, arg2)); + mask = unop(Iop_Dup8x16, mkU8(0x1)); + comparison = binop(Iop_CmpGT8Ux16, arg1, mkexpr(sum)); + if(allow_equal) { + comparison = binop(Iop_OrV128, binop(Iop_CmpEQ8x16, arg1, mkexpr(sum)), + comparison); + } + result = binop(Iop_AndV128, comparison, mask); + break; + case Ity_I16: + assign(sum, binop(Iop_Add16x8, arg1, arg2)); + mask = unop(Iop_Dup16x8, mkU16(0x1)); + comparison = binop(Iop_CmpGT16Ux8, arg1, mkexpr(sum)); + if(allow_equal) { + comparison = binop(Iop_OrV128, binop(Iop_CmpEQ16x8, arg1, mkexpr(sum)), + comparison); + } + result = binop(Iop_AndV128, comparison, mask); + break; + case Ity_I32: + assign(sum, binop(Iop_Add32x4, arg1, arg2)); + mask = unop(Iop_Dup32x4, mkU32(0x1)); + comparison = binop(Iop_CmpGT32Ux4, arg1, mkexpr(sum)); + if(allow_equal) { + comparison = binop(Iop_OrV128, binop(Iop_CmpEQ32x4, arg1, mkexpr(sum)), + comparison); + } + result = binop(Iop_AndV128, comparison, mask); + break; + case Ity_I64: + assign(sum, binop(Iop_Add64x2, arg1, arg2)); + mask = binop(Iop_64HLtoV128, mkU64(0x1), mkU64(0x1)); + comparison = binop(Iop_CmpGT64Ux2, arg1, mkexpr(sum)); + if(allow_equal) { + comparison = binop(Iop_OrV128, binop(Iop_CmpEQ64x2, arg1, mkexpr(sum)), + comparison); + } + result = binop(Iop_AndV128, comparison, mask); + break; + case Ity_V128: + assign(sum, binop(Iop_Add128x1, arg1, arg2)); + comparison = s390_V128_compareLT128x1(mkexpr(sum), arg1, allow_equal); + result = binop(Iop_64HLtoV128, mkU64(0x0), comparison); + break; + default: + ppIRType(type); + vpanic("s390_V128_calculate_carry_out: unknown type"); + } + + return result; +} + +/* # elemCount = 1 for now (elements are 128-bit unsigned integers) + For i = 0; i < elemCount; i++ do: + sum = arg1[i] + arg2[i] + arg3[i] & 0x1 + result[i] = carry_out_bit(sum) + end + return result + */ +static IRExpr* +s390_V128_calculate_carry_out_with_carry(IRExpr* arg1, IRExpr* arg2, IRExpr* arg3) +{ + IRTemp sum = newTemp(Ity_V128); + assign(sum, binop(Iop_Add128x1, arg1, arg2)); + + IRTemp overflow_before = newTemp(Ity_I64); + assign(overflow_before, s390_V128_compareLT128x1(mkexpr(sum), arg1, False)); + + IRExpr* mask = binop(Iop_64HLtoV128, mkU64(0), mkU64(1)); + IRTemp carry_in = newTemp(Ity_V128); + assign(carry_in, binop(Iop_AndV128, arg3, mask)); + + IRExpr* carry_is_not_zero = unop(Iop_1Uto64, + binop(Iop_CmpNE64, + unop(Iop_V128to64, mkexpr(carry_in)), + mkU64(0ULL) + ) + ); + + IRTemp sum_plus_carry = newTemp(Ity_V128); + assign(sum_plus_carry, binop(Iop_Add128x1, mkexpr(sum), mkexpr(carry_in))); + + IRExpr* overflow_after = binop(Iop_And64, + carry_is_not_zero, + s390_V128_isZero(mkexpr(sum_plus_carry)) + ); + + IRExpr* result = binop(Iop_Or64, mkexpr(overflow_before), overflow_after); + result = binop(Iop_64HLtoV128, mkU64(0Ull), result); + return result; +} + +/* Performs "arg1 + arg2 + carry_out_bit(arg1 + arg2)". + Arguments and result are Ity_I32. +*/ +static IRTemp +s390_checksum_add(IRExpr* arg1, IRExpr* arg2) +{ + IRTemp sum = newTemp(Ity_I32); + IRTemp res = newTemp(Ity_I32); + + assign(sum, binop(Iop_Add32, arg1, arg2)); + assign(res, + mkite(binop(Iop_CmpLT32U, mkexpr(sum), arg1), + binop(Iop_Add32, mkexpr(sum), mkU32(1)), + mkexpr(sum)) + ); + + return res; +} + /* Return the guest state offset of element with type's size and given index of a vr register. */ @@ -1816,7 +2053,7 @@ s390_vr_getVRindex(UChar v,UChar argNumber, UChar rxb) { vassert(argNumber > 0 && argNumber <= 4); vassert(rxb < 16); - return v | (((rxb) << (++argNumber)) & 0b00010000); + return v | (((rxb) << argNumber) & 0b00010000); } static void @@ -1834,8 +2071,7 @@ s390_vr_fill(UChar v1, IRExpr *o2) put_vr_qw(v1, unop(Iop_Dup32x4, o2)); break; case Ity_I64: - put_vr_dw0(v1, o2); - put_vr_dw1(v1, o2); + put_vr_qw(v1, binop(Iop_64HLtoV128, o2, o2)); break; default: ppIRType(o2type); @@ -1881,43 +2117,65 @@ s390_getCountToBlockBoundary(IRTemp op2addr, UChar m) return mkexpr(output); } -/* Helper macro for s390_vr_loadWithLength */ -#define s390_vr_loadWithLength_process(elem) \ - put_vr_qw(v1, triop(Iop_SetElem8x16,\ - get_vr_qw(v1), mkU8(elem),\ - mkite(binop(Iop_CmpLE32U, mkU32(elem), mkexpr(maxIndexToLoad)),\ - load(Ity_I8, binop(Iop_Add64, mkexpr(addr), mkU64(elem))),\ - mkU8(0x00)\ - )\ - )\ - ) - /* Load bytes into v1. maxIndex specifies max index to load and must be Ity_I32. - If maxIndex > 16, all 16 bytes are loaded. + If maxIndex >= 15, all 16 bytes are loaded. All bytes after maxIndex are zeroed. */ static void s390_vr_loadWithLength(UChar v1, IRTemp addr, IRExpr *maxIndex) { - IRTemp maxIndexToLoad = newTemp(Ity_I32); - - assign(maxIndexToLoad, maxIndex); - - s390_vr_loadWithLength_process(0); - s390_vr_loadWithLength_process(1); - s390_vr_loadWithLength_process(2); - s390_vr_loadWithLength_process(3); - s390_vr_loadWithLength_process(4); - s390_vr_loadWithLength_process(5); - s390_vr_loadWithLength_process(6); - s390_vr_loadWithLength_process(7); - s390_vr_loadWithLength_process(8); - s390_vr_loadWithLength_process(9); - s390_vr_loadWithLength_process(10); - s390_vr_loadWithLength_process(11); - s390_vr_loadWithLength_process(12); - s390_vr_loadWithLength_process(13); - s390_vr_loadWithLength_process(14); - s390_vr_loadWithLength_process(15); + IRTemp maxIdx = newTemp(Ity_I32); + IRTemp cappedMax = newTemp(Ity_I64); + IRTemp offset = newTemp(Ity_I64); + IRTemp zeroed = newTemp(Ity_I64); + IRTemp back = newTemp(Ity_I64); + + /* Implement the insn with a single 16-byte load, to allow memcheck's + "partial-loads-OK" heuristic to apply. Ensure that a page boundary is + crossed if and only if the real insn would have crossed it as well. + Thus, if the bytes to load are fully contained in an aligned 16-byte + chunk, load the whole 16-byte aligned chunk, and otherwise load 16 bytes + from the unaligned address. Then shift the loaded data left-aligned + into the target vector register. */ + + assign(maxIdx, maxIndex); + assign(cappedMax, mkite(binop(Iop_CmpLT32U, mkexpr(maxIdx), mkU32(15)), + unop(Iop_32Uto64, mkexpr(maxIdx)), mkU64(15))); + /* 'offset': addr's offset from last 16-byte aligned address + 'zeroed': number of bytes to be zeroed in the target vector + 'back': how much to subtract from addr before loading 16 bytes */ + assign(offset, binop(Iop_And64, mkexpr(addr), mkU64(15))); + assign(zeroed, binop(Iop_Sub64, mkU64(15), mkexpr(cappedMax))); + assign(back, mkite(binop(Iop_CmpLE64U, mkexpr(offset), mkexpr(zeroed)), + mkexpr(offset), mkU64(0))); + + /* How much to shift the loaded 16-byte vector to the right, and then to + the left. Since both 'zeroed' and 'back' range from 0 to 15, the shift + amounts range from 0 to 120. */ + IRExpr *shrAmount = binop(Iop_Shl64, + binop(Iop_Sub64, mkexpr(zeroed), mkexpr(back)), + mkU8(3)); + IRExpr *shlAmount = binop(Iop_Shl64, mkexpr(zeroed), mkU8(3)); + + put_vr_qw(v1, binop(Iop_ShlV128, + binop(Iop_ShrV128, + load(Ity_V128, + binop(Iop_Sub64, mkexpr(addr), mkexpr(back))), + unop(Iop_64to8, shrAmount)), + unop(Iop_64to8, shlAmount))); +} + +/* Bitwise vCond ? v1 : v2 + All args are V128. + */ +static IRExpr* +s390_V128_bitwiseITE(IRExpr* vCond, IRExpr* v1, IRExpr* v2) +{ + IRTemp vc = newTemp(Ity_V128); + assign(vc, vCond); + /* result = (v1 & vCond) | (v2 & ~vCond) */ + return binop(Iop_OrV128, + binop(Iop_AndV128, v1, mkexpr(vc)), + binop(Iop_AndV128, v2, unop(Iop_NotV128, mkexpr(vc)))); } /*------------------------------------------------------------*/ @@ -3292,6 +3550,31 @@ s390_format_VRS_RRDVM(const HChar *(*irgen)(UChar r1, IRTemp op2addr, UChar v3, static void +s390_format_VRS_VRDVM(const HChar *(*irgen)(UChar v1, IRTemp op2addr, UChar v3, + UChar m4), UChar v1, UChar b2, UShort d2, UChar v3, + UChar m4, UChar rxb) +{ + const HChar *mnm; + IRTemp op2addr = newTemp(Ity_I64); + + if (! s390_host_has_vx) { + emulation_failure(EmFail_S390X_vx); + return; + } + + assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) : + mkU64(0))); + + v1 = s390_vr_getVRindex(v1, 1, rxb); + v3 = s390_vr_getVRindex(v3, 2, rxb); + mnm = irgen(v1, op2addr, v3, m4); + + if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) + s390_disasm(ENC5(MNM, VR, UDXB, VR, UINT), mnm, v1, d2, 0, b2, v3, m4); +} + + +static void s390_format_VRS_VRDV(const HChar *(*irgen)(UChar v1, IRTemp op2addr, UChar v3), UChar v1, UChar b2, UShort d2, UChar v3, UChar rxb) { @@ -3396,6 +3679,121 @@ s390_format_VRV_VVRDMT(const HChar *(*irgen)(UChar v1, IRTemp op2addr, UChar m3) } +static void +s390_format_VRRd_VVVVMM(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3, + UChar v4, UChar m5, UChar m6), + UChar v1, UChar v2, UChar v3, UChar v4, UChar m5, + UChar m6, UChar rxb) +{ + const HChar *mnm; + + if (! s390_host_has_vx) { + emulation_failure(EmFail_S390X_vx); + return; + } + + v1 = s390_vr_getVRindex(v1, 1, rxb); + v2 = s390_vr_getVRindex(v2, 2, rxb); + v3 = s390_vr_getVRindex(v3, 3, rxb); + v4 = s390_vr_getVRindex(v4, 4, rxb); + mnm = irgen(v1, v2, v3, v4, m5, m6); + + if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) + s390_disasm(ENC7(MNM, VR, VR, VR, VR, UINT, UINT), + mnm, v1, v2, v3, v4, m5, m6); +} + + +static void +s390_format_VRR_VVMM(const HChar *(*irgen)(UChar v1, UChar v2, UChar m3, + UChar m5), + UChar v1, UChar v2, UChar m3, UChar m5, UChar rxb) +{ + const HChar *mnm; + + if (! s390_host_has_vx) { + emulation_failure(EmFail_S390X_vx); + return; + } + + v1 = s390_vr_getVRindex(v1, 1, rxb); + v2 = s390_vr_getVRindex(v2, 2, rxb); + mnm = irgen(v1, v2, m3, m5); + + if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) + s390_disasm(ENC5(MNM, VR, VR, UINT, UINT), mnm, v1, v2, m3, m5); +} + + +static void +s390_format_VRId_VVVIM(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3, + UChar i4, UChar m5), + UChar v1, UChar v2, UChar v3, UChar i4, UChar m5, + UChar rxb) +{ + const HChar *mnm; + + if (! s390_host_has_vx) { + emulation_failure(EmFail_S390X_vx); + return; + } + + v1 = s390_vr_getVRindex(v1, 1, rxb); + v2 = s390_vr_getVRindex(v2, 2, rxb); + v3 = s390_vr_getVRindex(v3, 3, rxb); + mnm = irgen(v1, v2, v3, i4, m5); + + if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) + s390_disasm(ENC6(MNM, VR, VR, VR, UINT, UINT), mnm, v1, v2, v3, i4, m5); +} + + +static void +s390_format_VRId_VVVI(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3, + UChar i4), + UChar v1, UChar v2, UChar v3, UChar i4, UChar rxb) +{ + const HChar *mnm; + + if (! s390_host_has_vx) { + emulation_failure(EmFail_S390X_vx); + return; + } + + v1 = s390_vr_getVRindex(v1, 1, rxb); + v2 = s390_vr_getVRindex(v2, 2, rxb); + v3 = s390_vr_getVRindex(v3, 3, rxb); + mnm = irgen(v1, v2, v3, i4); + + if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) + s390_disasm(ENC5(MNM, VR, VR, VR, UINT), mnm, v1, v2, v3, i4); +} + + +static void +s390_format_VRRd_VVVVM(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3, + UChar v4, UChar m5), + UChar v1, UChar v2, UChar v3, UChar v4, UChar m5, + UChar rxb) +{ + const HChar *mnm; + + if (! s390_host_has_vx) { + emulation_failure(EmFail_S390X_vx); + return; + } + + v1 = s390_vr_getVRindex(v1, 1, rxb); + v2 = s390_vr_getVRindex(v2, 2, rxb); + v3 = s390_vr_getVRindex(v3, 3, rxb); + v4 = s390_vr_getVRindex(v4, 4, rxb); + mnm = irgen(v1, v2, v3, v4, m5); + + if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) + s390_disasm(ENC6(MNM, VR, VR, VR, VR, UINT), mnm, v1, v2, v3, v4, m5); +} + + /*------------------------------------------------------------*/ /*--- Build IR for opcodes ---*/ /*------------------------------------------------------------*/ @@ -11817,7 +12215,7 @@ s390_irgen_CLCL(UChar r1, UChar r2) assign(pad, get_gpr_b4(r2 + 1)); /* len1 == 0 and len2 == 0? Exit */ - s390_cc_set(0); + s390_cc_set_val(0); next_insn_if(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(len1), mkexpr(len2)), mkU32(0))); @@ -11893,7 +12291,7 @@ s390_irgen_CLCLE(UChar r1, UChar r3, IRTemp pad2) assign(len3, get_gpr_dw0(r3 + 1)); /* len1 == 0 and len3 == 0? Exit */ - s390_cc_set(0); + s390_cc_set_val(0); next_insn_if(binop(Iop_CmpEQ64,binop(Iop_Or64, mkexpr(len1), mkexpr(len3)), mkU64(0))); @@ -12255,7 +12653,7 @@ s390_irgen_SRST(UChar r1, UChar r2) put_counter_dw0(mkU64(0)); // start = next? CC=2 and out r1 and r2 unchanged - s390_cc_set(2); + s390_cc_set_val(2); put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address), mkexpr(counter))); next_insn_if(binop(Iop_CmpEQ64, mkexpr(address), mkexpr(next))); @@ -12263,7 +12661,7 @@ s390_irgen_SRST(UChar r1, UChar r2) assign(delim, get_gpr_b7(0)); // byte = delim? CC=1, R1=address - s390_cc_set(1); + s390_cc_set_val(1); put_gpr_dw0(r1, mkexpr(address)); next_insn_if(binop(Iop_CmpEQ8, mkexpr(delim), mkexpr(byte))); @@ -12296,7 +12694,7 @@ s390_irgen_CLST(UChar r1, UChar r2) assign(byte2, load(Ity_I8, mkexpr(address2))); // end in both? all equal, reset r1 and r2 to start values - s390_cc_set(0); + s390_cc_set_val(0); put_gpr_dw0(r1, binop(Iop_Sub64, mkexpr(address1), mkexpr(counter))); put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address2), mkexpr(counter))); next_insn_if(binop(Iop_CmpEQ8, mkU8(0), @@ -12308,20 +12706,20 @@ s390_irgen_CLST(UChar r1, UChar r2) put_gpr_dw0(r2, mkexpr(address2)); // End found in string1 - s390_cc_set(1); + s390_cc_set_val(1); next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte1))); // End found in string2 - s390_cc_set(2); + s390_cc_set_val(2); next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte2))); // string1 < string2 - s390_cc_set(1); + s390_cc_set_val(1); next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte1)), unop(Iop_8Uto32, mkexpr(byte2)))); // string2 < string1 - s390_cc_set(2); + s390_cc_set_val(2); next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte2)), unop(Iop_8Uto32, mkexpr(byte1)))); @@ -12647,7 +13045,7 @@ s390_irgen_MVCL(UChar r1, UChar r2) /* Check for destructive overlap: addr1 > addr2 && addr2 + len1 > addr1 && (addr2 + len2) > addr1 */ - s390_cc_set(3); + s390_cc_set_val(3); IRTemp cond1 = newTemp(Ity_I32); assign(cond1, unop(Iop_1Uto32, binop(Iop_CmpLT64U, mkexpr(addr2), mkexpr(addr1)))); @@ -12777,7 +13175,7 @@ s390_irgen_MVST(UChar r1, UChar r2) iterate_if(binop(Iop_CmpNE8, mkexpr(end), mkexpr(byte))); // and always set cc=1 at the end + update r1 - s390_cc_set(1); + s390_cc_set_val(1); put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(counter))); put_counter_dw0(mkU64(0)); @@ -14132,8 +14530,7 @@ s390_irgen_STCK(IRTemp op2addr) d->mAddr = mkexpr(op2addr); d->mSize = 8; stmt(IRStmt_Dirty(d)); - s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), - mkexpr(cc), mkU64(0), mkU64(0)); + s390_cc_set(cc); return "stck"; } @@ -14152,8 +14549,7 @@ s390_irgen_STCKF(IRTemp op2addr) d->mAddr = mkexpr(op2addr); d->mSize = 8; stmt(IRStmt_Dirty(d)); - s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), - mkexpr(cc), mkU64(0), mkU64(0)); + s390_cc_set(cc); } return "stckf"; } @@ -14171,8 +14567,7 @@ s390_irgen_STCKE(IRTemp op2addr) d->mAddr = mkexpr(op2addr); d->mSize = 16; stmt(IRStmt_Dirty(d)); - s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), - mkexpr(cc), mkU64(0), mkU64(0)); + s390_cc_set(cc); return "stcke"; } @@ -14206,7 +14601,7 @@ s390_irgen_STFLE(IRTemp op2addr) stmt(IRStmt_Dirty(d)); - s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkexpr(cc), mkU64(0), mkU64(0)); + s390_cc_set(cc); return "stfle"; } @@ -14229,7 +14624,7 @@ s390_irgen_CKSM(UChar r1,UChar r2) assign(len, get_gpr_dw0(r2+1)); /* Condition code is always zero. */ - s390_cc_set(0); + s390_cc_set_val(0); /* If length is zero, there is no need to calculate the checksum */ next_insn_if(binop(Iop_CmpEQ64, mkexpr(len), mkU64(0))); @@ -14296,7 +14691,7 @@ s390_irgen_TROO(UChar m3, UChar r1, UChar r2) IRTemp result = newTemp(Ity_I64); /* End of source string? We're done; proceed to next insn */ - s390_cc_set(0); + s390_cc_set_val(0); next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0))); /* Load character from source string, index translation table and @@ -14308,7 +14703,7 @@ s390_irgen_TROO(UChar m3, UChar r1, UChar r2) assign(op1, load(Ity_I8, mkexpr(result))); if (! s390_host_has_etf2 || (m3 & 0x1) == 0) { - s390_cc_set(1); + s390_cc_set_val(1); next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte))); } store(get_gpr_dw0(r1), mkexpr(op1)); @@ -14343,7 +14738,7 @@ s390_irgen_TRTO(UChar m3, UChar r1, UChar r2) IRTemp result = newTemp(Ity_I64); /* End of source string? We're done; proceed to next insn */ - s390_cc_set(0); + s390_cc_set_val(0); next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0))); /* Load character from source string, index translation table and @@ -14356,7 +14751,7 @@ s390_irgen_TRTO(UChar m3, UChar r1, UChar r2) assign(op1, load(Ity_I8, mkexpr(result))); if (! s390_host_has_etf2 || (m3 & 0x1) == 0) { - s390_cc_set(1); + s390_cc_set_val(1); next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte))); } store(get_gpr_dw0(r1), mkexpr(op1)); @@ -14391,7 +14786,7 @@ s390_irgen_TROT(UChar m3, UChar r1, UChar r2) IRTemp result = newTemp(Ity_I64); /* End of source string? We're done; proceed to next insn */ - s390_cc_set(0); + s390_cc_set_val(0); next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0))); /* Load character from source string, index translation table and @@ -14403,7 +14798,7 @@ s390_irgen_TROT(UChar m3, UChar r1, UChar r2) assign(op1, load(Ity_I16, mkexpr(result))); if (! s390_host_has_etf2 || (m3 & 0x1) == 0) { - s390_cc_set(1); + s390_cc_set_val(1); next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte))); } store(get_gpr_dw0(r1), mkexpr(op1)); @@ -14438,7 +14833,7 @@ s390_irgen_TRTT(UChar m3, UChar r1, UChar r2) IRTemp result = newTemp(Ity_I64); /* End of source string? We're done; proceed to next insn */ - s390_cc_set(0); + s390_cc_set_val(0); next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0))); /* Load character from source string, index translation table and @@ -14450,7 +14845,7 @@ s390_irgen_TRTT(UChar m3, UChar r1, UChar r2) assign(op1, load(Ity_I16, mkexpr(result))); if (! s390_host_has_etf2 || (m3 & 0x1) == 0) { - s390_cc_set(1); + s390_cc_set_val(1); next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte))); } @@ -14495,13 +14890,13 @@ s390_irgen_TRE(UChar r1,UChar r2) IRTemp result = newTemp(Ity_I64); /* End of source string? We're done; proceed to next insn */ - s390_cc_set(0); + s390_cc_set_val(0); next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0))); /* Load character from source string and compare with test byte */ assign(op, load(Ity_I8, mkexpr(src_addr))); - s390_cc_set(1); + s390_cc_set_val(1); next_insn_if(binop(Iop_CmpEQ8, mkexpr(op), mkexpr(test_byte))); assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)), @@ -14548,7 +14943,7 @@ s390_irgen_CU21(UChar m3, UChar r1, UChar r2) /* We're processing the 2nd operand 2 bytes at a time. Therefore, if there are less than 2 bytes left, then the 2nd operand is exhausted and we're done here. cc = 0 */ - s390_cc_set(0); + s390_cc_set_val(0); next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2))); /* There are at least two bytes there. Read them. */ @@ -14594,7 +14989,7 @@ s390_irgen_CU21(UChar m3, UChar r1, UChar r2) IRExpr *invalid_low_surrogate = binop(Iop_And64, mkexpr(retval), mkU64(0xff)); - s390_cc_set(2); + s390_cc_set_val(2); next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1))); } @@ -14603,7 +14998,7 @@ s390_irgen_CU21(UChar m3, UChar r1, UChar r2) assign(num_bytes, binop(Iop_And64, binop(Iop_Shr64, mkexpr(retval), mkU8(8)), mkU64(0xff))); - s390_cc_set(1); + s390_cc_set_val(1); next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes))); /* Extract the bytes to be stored at addr1 */ @@ -14675,7 +15070,7 @@ s390_irgen_CU24(UChar m3, UChar r1, UChar r2) /* We're processing the 2nd operand 2 bytes at a time. Therefore, if there are less than 2 bytes left, then the 2nd operand is exhausted and we're done here. cc = 0 */ - s390_cc_set(0); + s390_cc_set_val(0); next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2))); /* There are at least two bytes there. Read them. */ @@ -14722,12 +15117,12 @@ s390_irgen_CU24(UChar m3, UChar r1, UChar r2) IRExpr *invalid_low_surrogate = binop(Iop_And64, mkexpr(retval), mkU64(0xff)); - s390_cc_set(2); + s390_cc_set_val(2); next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1))); } /* Now test whether the 1st operand is exhausted */ - s390_cc_set(1); + s390_cc_set_val(1); next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkU64(4))); /* Extract the bytes to be stored at addr1 */ @@ -14782,7 +15177,7 @@ s390_irgen_CU42(UChar r1, UChar r2) /* We're processing the 2nd operand 4 bytes at a time. Therefore, if there are less than 4 bytes left, then the 2nd operand is exhausted and we're done here. cc = 0 */ - s390_cc_set(0); + s390_cc_set_val(0); next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4))); /* Read the 2nd operand. */ @@ -14797,7 +15192,7 @@ s390_irgen_CU42(UChar r1, UChar r2) cc=2 outranks cc=1 (1st operand exhausted) */ IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff)); - s390_cc_set(2); + s390_cc_set_val(2); next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1))); /* Now test whether the 1st operand is exhausted */ @@ -14805,7 +15200,7 @@ s390_irgen_CU42(UChar r1, UChar r2) assign(num_bytes, binop(Iop_And64, binop(Iop_Shr64, mkexpr(retval), mkU8(8)), mkU64(0xff))); - s390_cc_set(1); + s390_cc_set_val(1); next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes))); /* Extract the bytes to be stored at addr1 */ @@ -14876,7 +15271,7 @@ s390_irgen_CU41(UChar r1, UChar r2) /* We're processing the 2nd operand 4 bytes at a time. Therefore, if there are less than 4 bytes left, then the 2nd operand is exhausted and we're done here. cc = 0 */ - s390_cc_set(0); + s390_cc_set_val(0); next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4))); /* Read the 2nd operand. */ @@ -14891,7 +15286,7 @@ s390_irgen_CU41(UChar r1, UChar r2) cc=2 outranks cc=1 (1st operand exhausted) */ IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff)); - s390_cc_set(2); + s390_cc_set_val(2); next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1))); /* Now test whether the 1st operand is exhausted */ @@ -14899,7 +15294,7 @@ s390_irgen_CU41(UChar r1, UChar r2) assign(num_bytes, binop(Iop_And64, binop(Iop_Shr64, mkexpr(retval), mkU8(8)), mkU64(0xff))); - s390_cc_set(1); + s390_cc_set_val(1); next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes))); /* Extract the bytes to be stored at addr1 */ @@ -14999,7 +15394,7 @@ s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12) /* We're processing the 2nd operand 1 byte at a time. Therefore, if there is less than 1 byte left, then the 2nd operand is exhausted and we're done here. cc = 0 */ - s390_cc_set(0); + s390_cc_set_val(0); next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(1))); /* There is at least one byte there. Read it. */ @@ -15013,7 +15408,7 @@ s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12) /* Check for invalid 1st byte */ IRExpr *is_invalid = unop(Iop_64to1, mkexpr(retval1)); - s390_cc_set(2); + s390_cc_set_val(2); next_insn_if(is_invalid); /* How many bytes do we have to read? */ @@ -15021,7 +15416,7 @@ s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12) assign(num_src_bytes, binop(Iop_Shr64, mkexpr(retval1), mkU8(8))); /* Now test whether the 2nd operand is exhausted */ - s390_cc_set(0); + s390_cc_set_val(0); next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkexpr(num_src_bytes))); /* Read the remaining bytes */ @@ -15054,7 +15449,7 @@ s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12) } /* Check for invalid character */ - s390_cc_set(2); + s390_cc_set_val(2); is_invalid = unop(Iop_64to1, mkexpr(retval2)); next_insn_if(is_invalid); @@ -15063,7 +15458,7 @@ s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12) assign(num_bytes, binop(Iop_And64, binop(Iop_Shr64, mkexpr(retval2), mkU8(8)), mkU64(0xff))); - s390_cc_set(1); + s390_cc_set_val(1); next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes))); /* Extract the bytes to be stored at addr1 */ @@ -15409,8 +15804,7 @@ s390_irgen_VLM(UChar v1, IRTemp op2addr, UChar v3) static const HChar * s390_irgen_VLVGP(UChar v1, UChar r2, UChar r3) { - put_vr_dw0(v1, get_gpr_dw0(r2)); - put_vr_dw1(v1, get_gpr_dw0(r3)); + put_vr_qw(v1, binop(Iop_64HLtoV128, get_gpr_dw0(r2), get_gpr_dw0(r3))); return "vlvgp"; } @@ -15449,28 +15843,10 @@ s390_irgen_VLVG(UChar v1, IRTemp op2addr, UChar r3, UChar m4) static const HChar * s390_irgen_VMRH(UChar v1, UChar v2, UChar v3, UChar m4) { - IRType type = s390_vr_get_type(m4); - switch (type) { - case Ity_I8: - put_vr_qw(v1, binop(Iop_InterleaveLO8x16, get_vr_qw(v2), get_vr_qw(v3))); - break; - - case Ity_I16: - put_vr_qw(v1, binop(Iop_InterleaveLO16x8, get_vr_qw(v2), get_vr_qw(v3))); - break; - - case Ity_I32: - put_vr_qw(v1, binop(Iop_InterleaveLO32x4, get_vr_qw(v2), get_vr_qw(v3))); - break; - - case Ity_I64: - put_vr_qw(v1, binop(Iop_InterleaveLO64x2, get_vr_qw(v2), get_vr_qw(v3))); - break; - - default: - ppIRType(type); - vpanic("s390_irgen_VMRH: unknown type"); - } + const IROp ops[] = { Iop_InterleaveHI8x16, Iop_InterleaveHI16x8, + Iop_InterleaveHI32x4, Iop_InterleaveHI64x2 }; + vassert(m4 < sizeof(ops) / sizeof(ops[0])); + put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3))); return "vmrh"; } @@ -15478,28 +15854,10 @@ s390_irgen_VMRH(UChar v1, UChar v2, UChar v3, UChar m4) static const HChar * s390_irgen_VMRL(UChar v1, UChar v2, UChar v3, UChar m4) { - IRType type = s390_vr_get_type(m4); - switch (type) { - case Ity_I8: - put_vr_qw(v1, binop(Iop_InterleaveHI8x16, get_vr_qw(v2), get_vr_qw(v3))); - break; - - case Ity_I16: - put_vr_qw(v1, binop(Iop_InterleaveHI16x8, get_vr_qw(v2), get_vr_qw(v3))); - break; - - case Ity_I32: - put_vr_qw(v1, binop(Iop_InterleaveHI32x4, get_vr_qw(v2), get_vr_qw(v3))); - break; - - case Ity_I64: - put_vr_qw(v1, binop(Iop_InterleaveHI64x2, get_vr_qw(v2), get_vr_qw(v3))); - break; - - default: - ppIRType(type); - vpanic("s390_irgen_VMRL: unknown type"); - } + const IROp ops[] = { Iop_InterleaveLO8x16, Iop_InterleaveLO16x8, + Iop_InterleaveLO32x4, Iop_InterleaveLO64x2 }; + vassert(m4 < sizeof(ops) / sizeof(ops[0])); + put_vr_qw(v1, binop(ops[m4], get_vr_qw(v2), get_vr_qw(v3))); return "vmrl"; } @@ -15507,25 +15865,11 @@ s390_irgen_VMRL(UChar v1, UChar v2, UChar v3, UChar m4) static const HChar * s390_irgen_VPK(UChar v1, UChar v2, UChar v3, UChar m4) { - IRType type = s390_vr_get_type(m4); - IRExpr* result = NULL; - switch(type) { - case Ity_I16: - result = binop(Iop_NarrowBin16to8x16, get_vr_qw(v2), get_vr_qw(v3)); - break; - case Ity_I32: - result = binop(Iop_NarrowBin32to16x8, get_vr_qw(v2), get_vr_qw(v3)); - break; - case Ity_I64: - result = binop(Iop_NarrowBin64to32x4, get_vr_qw(v2), get_vr_qw(v3)); - break; - default: - ppIRType(type); - vpanic("s390_irgen_VPK: unknown type"); - } - - put_vr_qw(v1, result); - + const IROp ops[] = { Iop_NarrowBin16to8x16, Iop_NarrowBin32to16x8, + Iop_NarrowBin64to32x4 }; + Char index = m4 - 1; + vassert((index >= 0) && (index < sizeof(ops) / sizeof(ops[0]))); + put_vr_qw(v1, binop(ops[index], get_vr_qw(v2), get_vr_qw(v3))); return "vpk"; } @@ -15648,21 +15992,9 @@ s390_irgen_VSTM(UChar v1, IRTemp op2addr, UChar v3) static const HChar * s390_irgen_VUPH(UChar v1, UChar v2, UChar m3) { - IRType type = s390_vr_get_type(m3); - switch (type) { - case Ity_I8: - put_vr_qw(v1, unop(Iop_Widen8Sto16x8, get_vr_dw0(v2))); - break; - case Ity_I16: - put_vr_qw(v1, unop(Iop_Widen16Sto32x4, get_vr_dw0(v2))); - break; - case Ity_I32: - put_vr_qw(v1, unop(Iop_Widen32Sto64x2, get_vr_dw0(v2))); - break; - default: - ppIRType(type); - vpanic("s390_irgen_VUPH: unknown type"); - } + const IROp ops[] = { Iop_Widen8Sto16x8, Iop_Widen16Sto32x4, Iop_Widen32Sto64x2 }; + vassert(m3 < sizeof(ops) / sizeof(ops[0])); + put_vr_qw(v1, unop(ops[m3], get_vr_dw0(v2))); return "vuph"; } @@ -15670,43 +16002,18 @@ s390_irgen_VUPH(UChar v1, UChar v2, UChar m3) static const HChar * s390_irgen_VUPLH(UChar v1, UChar v2, UChar m3) { - IRType type = s390_vr_get_type(m3); - switch (type) { - case Ity_I8: - put_vr_qw(v1, unop(Iop_Widen8Uto16x8, get_vr_dw0(v2))); - break; - case Ity_I16: - put_vr_qw(v1, unop(Iop_Widen16Uto32x4, get_vr_dw0(v2))); - break; - case Ity_I32: - put_vr_qw(v1, unop(Iop_Widen32Uto64x2, get_vr_dw0(v2))); - break; - default: - ppIRType(type); - vpanic("s390_irgen_VUPLH: unknown type"); - } - + const IROp ops[] = { Iop_Widen8Uto16x8, Iop_Widen16Uto32x4, Iop_Widen32Uto64x2 }; + vassert(m3 < sizeof(ops) / sizeof(ops[0])); + put_vr_qw(v1, unop(ops[m3], get_vr_dw0(v2))); return "vuplh"; } static const HChar * s390_irgen_VUPL(UChar v1, UChar v2, UChar m3) { - IRType type = s390_vr_get_type(m3); - switch (type) { - case Ity_I8: - put_vr_qw(v1, unop(Iop_Widen8Sto16x8, get_vr_dw1(v2))); - break; - case Ity_I16: - put_vr_qw(v1, unop(Iop_Widen16Sto32x4, get_vr_dw1(v2))); - break; - case Ity_I32: - put_vr_qw(v1, unop(Iop_Widen32Sto64x2, get_vr_dw1(v2))); - break; - default: - ppIRType(type); - vpanic("s390_irgen_VUPL: unknown type"); - } + const IROp ops[] = { Iop_Widen8Sto16x8, Iop_Widen16Sto32x4, Iop_Widen32Sto64x2 }; + vassert(m3 < sizeof(ops) / sizeof(ops[0])); + put_vr_qw(v1, unop(ops[m3], get_vr_dw1(v2))); return "vupl"; } @@ -15714,21 +16021,9 @@ s390_irgen_VUPL(UChar v1, UChar v2, UChar m3) static const HChar * s390_irgen_VUPLL(UChar v1, UChar v2, UChar m3) { - IRType type = s390_vr_get_type(m3); - switch (type) { - case Ity_I8: - put_vr_qw(v1, unop(Iop_Widen8Uto16x8, get_vr_dw1(v2))); - break; - case Ity_I16: - put_vr_qw(v1, unop(Iop_Widen16Uto32x4, get_vr_dw1(v2))); - break; - case Ity_I32: - put_vr_qw(v1, unop(Iop_Widen32Uto64x2, get_vr_dw1(v2))); - break; - default: - ppIRType(type); - vpanic("s390_irgen_VUPLL: unknown type"); - } + const IROp ops[] = { Iop_Widen8Uto16x8, Iop_Widen16Uto32x4, Iop_Widen32Uto64x2 }; + vassert(m3 < sizeof(ops) / sizeof(ops[0])); + put_vr_qw(v1, unop(ops[m3], get_vr_dw1(v2))); return "vupll"; } @@ -15773,33 +16068,31 @@ s390_irgen_VREPI(UChar v1, UShort i2, UChar m3) static const HChar * s390_irgen_VPKS(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5) { - IRType type = s390_vr_get_type(m4); - IRExpr* result = NULL; - - switch(type) { - case Ity_I16: - result = binop(Iop_QNarrowBin16Sto8Sx16, get_vr_qw(v2), get_vr_qw(v3)); - break; - case Ity_I32: - result = binop(Iop_QNarrowBin32Sto16Sx8, get_vr_qw(v2), get_vr_qw(v3)); - break; - case Ity_I64: - result = binop(Iop_QNarrowBin64Sto32Sx4, get_vr_qw(v2), get_vr_qw(v3)); - break; - default: - ppIRType(type); - vpanic("s390_irgen_VPKS: unknown type"); - } + if (!s390_vr_is_cs_set(m5)) { + const IROp ops[] = { Iop_QNarrowBin16Sto8Sx16, Iop_QNarrowBin32Sto16Sx8, + Iop_QNarrowBin64Sto32Sx4 }; + Char index = m4 - 1; + vassert((index >= 0) && (index < sizeof(ops) / sizeof(ops[0]))); + put_vr_qw(v1, binop(ops[index], get_vr_qw(v2), get_vr_qw(v3))); - if((m5 & 0x1) != 0) { + } else { IRDirty* d; IRTemp cc = newTemp(Ity_I64); - ULong opcode = s390x_cc_vec_opcode(S390_CC_VEC_VPKS, m4); - d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_binop", - &s390x_dirtyhelper_vec_binop, - mkIRExprVec_4(IRExpr_GSPTR(), mkU64(opcode), - mkU64(v2), mkU64(v3))); - d->nFxState = 2; + + s390x_vec_op_details_t details = { .serialized = 0ULL }; + details.op = S390_VEC_OP_VPKS; + details.v1 = v1; + details.v2 = v2; + details.v3 = v3; + details.m4 = m4; + details.m5 = m5; + + d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op", + &s390x_dirtyhelper_vec_op, + mkIRExprVec_2(IRExpr_GSPTR(), + mkU64(details.serialized))); + + d->nFxState = 3; vex_bzero(&d->fxState, sizeof(d->fxState)); d->fxState[0].fx = Ifx_Read; d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128); @@ -15807,45 +16100,45 @@ s390_irgen_VPKS(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5) d->fxState[1].fx = Ifx_Read; d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128); d->fxState[1].size = sizeof(V128); + d->fxState[2].fx = Ifx_Write; + d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128); + d->fxState[2].size = sizeof(V128); stmt(IRStmt_Dirty(d)); - s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), - mkexpr(cc), mkU64(0), mkU64(0)); + s390_cc_set(cc); } - put_vr_qw(v1, result); return "vpks"; } static const HChar * s390_irgen_VPKLS(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5) { - IRType type = s390_vr_get_type(m4); - IRExpr* result = NULL; - switch(type) { - case Ity_I16: - result = binop(Iop_QNarrowBin16Uto8Ux16, get_vr_qw(v2), get_vr_qw(v3)); - break; - case Ity_I32: - result = binop(Iop_QNarrowBin32Uto16Ux8, get_vr_qw(v2), get_vr_qw(v3)); - break; - case Ity_I64: - result = binop(Iop_QNarrowBin64Uto32Ux4, get_vr_qw(v2), get_vr_qw(v3)); - break; - default: - ppIRType(type); - vpanic("s390_irgen_VPKLS: unknown type"); - } + if (!s390_vr_is_cs_set(m5)) { + const IROp ops[] = { Iop_QNarrowBin16Uto8Ux16, Iop_QNarrowBin32Uto16Ux8, + Iop_QNarrowBin64Uto32Ux4 }; + Char index = m4 - 1; + vassert((index >= 0) && (index < sizeof(ops) / sizeof(ops[0]))); + put_vr_qw(v1, binop(ops[index], get_vr_qw(v2), get_vr_qw(v3))); - if((m5 & 0x1) != 0) { + } else { IRDirty* d; IRTemp cc = newTemp(Ity_I64); - ULong opcode = s390x_cc_vec_opcode(S390_CC_VEC_VPKLS, m4); - d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_binop", - &s390x_dirtyhelper_vec_binop, - mkIRExprVec_4(IRExpr_GSPTR(), mkU64(opcode), - mkU64(v2), mkU64(v3))); - d->nFxState = 2; + + s390x_vec_op_details_t details = { .serialized = 0ULL }; + details.op = S390_VEC_OP_VPKLS; + details.v1 = v1; + details.v2 = v2; + details.v3 = v3; + details.m4 = m4; + details.m5 = m5; + + d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op", + &s390x_dirtyhelper_vec_op, + mkIRExprVec_2(IRExpr_GSPTR(), + mkU64(details.serialized))); + + d->nFxState = 3; vex_bzero(&d->fxState, sizeof(d->fxState)); d->fxState[0].fx = Ifx_Read; d->fxState[0].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128); @@ -15853,30 +16146,25 @@ s390_irgen_VPKLS(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5) d->fxState[1].fx = Ifx_Read; d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128); d->fxState[1].size = sizeof(V128); + d->fxState[2].fx = Ifx_Write; + d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128); + d->fxState[2].size = sizeof(V128); stmt(IRStmt_Dirty(d)); - s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), - mkexpr(cc), mkU64(0), mkU64(0)); + s390_cc_set(cc); } - put_vr_qw(v1, result); return "vpkls"; } static const HChar * s390_irgen_VSEL(UChar v1, UChar v2, UChar v3, UChar v4) { - IRExpr* vA = get_vr_qw(v3); - IRExpr* vB = get_vr_qw(v2); - IRExpr* vC = get_vr_qw(v4); - - /* result = (vA & ~vC) | (vB & vC) */ - put_vr_qw(v1, - binop(Iop_OrV128, - binop(Iop_AndV128, vA, unop(Iop_NotV128, vC)), - binop(Iop_AndV128, vB, vC) - ) - ); + IRExpr* vIfTrue = get_vr_qw(v2); + IRExpr* vIfFalse = get_vr_qw(v3); + IRExpr* vCond = get_vr_qw(v4); + + put_vr_qw(v1, s390_V128_bitwiseITE(vCond, vIfTrue, vIfFalse)); return "vsel"; } @@ -16021,229 +16309,1595 @@ s390_irgen_LOCHHI(UChar r1, UChar m3, UShort i2, UChar unused) next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0))); put_gpr_w0(r1, mkU32(i2)); - return "lochhi"; + return "lochhi"; +} + +static const HChar * +s390_irgen_LOCHI(UChar r1, UChar m3, UShort i2, UChar unused) +{ + next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0))); + put_gpr_w1(r1, mkU32(i2)); + + return "lochi"; +} + +static const HChar * +s390_irgen_LOCGHI(UChar r1, UChar m3, UShort i2, UChar unused) +{ + next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0))); + put_gpr_dw0(r1, mkU64(i2)); + + return "locghi"; +} + +static const HChar * +s390_irgen_STOCFH(UChar r1, IRTemp op2addr) +{ + /* condition is checked in format handler */ + store(mkexpr(op2addr), get_gpr_w1(r1)); + + return "stocfh"; +} + +static const HChar * +s390_irgen_LCBB(UChar r1, IRTemp op2addr, UChar m3) +{ + IRTemp op2 = newTemp(Ity_I32); + assign(op2, s390_getCountToBlockBoundary(op2addr, m3)); + put_gpr_w1(r1, mkexpr(op2)); + + IRExpr* cc = mkite(binop(Iop_CmpEQ32, mkexpr(op2), mkU32(16)), mkU64(0), mkU64(3)); + s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), cc, mkU64(0), mkU64(0)); + + return "lcbb"; +} + +/* Regarding the use of + // Dummy helper which is used to signal VEX library that memory was loaded + sha512_loadparam + = unsafeIRDirty_0_N(0, "s390x_dirtyhelper_PPNO_sha512_load_param_block", + &s390x_dirtyhelper_PPNO_sha512_load_param_block, + mkIRExprVec_0()); + + in the following function (s390_irgen_PPNO). This is a workaround to get + around the fact that IRDirty annotations cannot indicate two memory side + effects, which are unfortunately necessary here. It will possibly lead to + losing undefinedness (undefinedness in some inputs might not be propagated + to the outputs as it shouod, in Memcheck). The correct fix would be to + extend IRDirty to represent two memory side effects, but that's quite a bit + of work. + + Here's a summary of what this insn does. + + // getReg(RegisterNumber n) returns the value of GPR number 'n' + + //... [truncated message content] |
|
From: Philippe W. <phi...@so...> - 2018-09-26 16:06:14
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=9dd4af5c78c2b8094fcb5015b0992c6cb54980c8 commit 9dd4af5c78c2b8094fcb5015b0992c6cb54980c8 Author: Philippe Waroquiers <phi...@sk...> Date: Wed Sep 26 18:04:43 2018 +0200 Fix 398028 Assertion `cfsi_fits` failing in simple C program At least with libopenblas, we can have several rx mappings with some holes between mappings. Change the invariant (2) checking so that such holes are ok, as long as no cfsi refers to such an hole. Diff: --- NEWS | 1 + coregrind/m_debuginfo/debuginfo.c | 56 +++++++++++++++++++++++++++--------- coregrind/m_debuginfo/priv_storage.h | 9 ++++-- 3 files changed, 50 insertions(+), 16 deletions(-) diff --git a/NEWS b/NEWS index ad188da..384cc9d 100644 --- a/NEWS +++ b/NEWS @@ -167,6 +167,7 @@ where XXXXXX is the bug number as listed below. 397089 amd64: Incorrect decoding of three-register vmovss/vmovsd opcode 11h 397354 utimensat should ignore timespec tv_sec if tv_nsec is UTIME_NOW/OMIT 397424 glibc 2.27 and gdb_server tests +398028 Assertion `cfsi_fits` failing in simple C program 398066 s390x: cgijl dep1, 0 reports false unitialised values warning n-i-bz Fix missing workq_ops operations (macOS) diff --git a/coregrind/m_debuginfo/debuginfo.c b/coregrind/m_debuginfo/debuginfo.c index 0fc54bf..1aa4314 100644 --- a/coregrind/m_debuginfo/debuginfo.c +++ b/coregrind/m_debuginfo/debuginfo.c @@ -660,6 +660,8 @@ static void check_CFSI_related_invariants ( const DebugInfo* di ) DebugInfo* di2 = NULL; Bool has_nonempty_rx = False; Word i, j; + const Bool debug = VG_(debugLog_getLevel)() >= 3; + vg_assert(di); /* This fn isn't called until after debuginfo for this object has been successfully read. And that shouldn't happen until we have @@ -676,7 +678,7 @@ static void check_CFSI_related_invariants ( const DebugInfo* di ) if (map->size == 0) continue; has_nonempty_rx = True; - + /* normal case: r-x section is nonempty */ /* invariant (0) */ vg_assert(map->size > 0); @@ -689,8 +691,9 @@ static void check_CFSI_related_invariants ( const DebugInfo* di ) const DebugInfoMapping* map2 = VG_(indexXA)(di2->fsm.maps, j); if (!map2->rx || map2->size == 0) continue; - vg_assert(!ranges_overlap(map->avma, map->size, - map2->avma, map2->size)); + vg_assert2(!ranges_overlap(map->avma, map->size, + map2->avma, map2->size), + "DiCfsi invariant (1) verification failed"); } } di2 = NULL; @@ -723,17 +726,44 @@ static void check_CFSI_related_invariants ( const DebugInfo* di ) if (map->size > 0) VG_(bindRangeMap)(rm, map->avma, map->avma + map->size - 1, 0); } - /* If the map isn't now empty, it means the cfsi range isn't covered - entirely by the rx mappings. */ - Bool cfsi_fits = VG_(sizeRangeMap)(rm) == 1; - if (cfsi_fits) { - // Sanity-check the range-map operation + /* Typically, the range map contains one single range with value 0, + meaning that the cfsi range is entirely covered by the rx mappings. + However, in some cases, there are holes in the rx mappings + (see BZ #398028). + In such a case, check that no cfsi refers to these holes. */ + Bool cfsi_fits = VG_(sizeRangeMap)(rm) >= 1; + // Check the ranges in the map. + for (Word ix = 0; ix < VG_(sizeRangeMap)(rm); ix++) { UWord key_min = 0x55, key_max = 0x56, val = 0x57; - /* We can look up any address at all since we expect only one range */ - VG_(lookupRangeMap)(&key_min, &key_max, &val, rm, 0x1234); - vg_assert(key_min == (UWord)0); - vg_assert(key_max == ~(UWord)0); - vg_assert(val == 0); + VG_(indexRangeMap)(&key_min, &key_max, &val, rm, ix); + if (debug) + VG_(dmsg)("cfsi range rx-mappings coverage check: %s %#lx-%#lx\n", + val == 1 ? "Uncovered" : "Covered", + key_min, key_max); + { + // Sanity-check the range-map operation + UWord check_key_min = 0x55, check_key_max = 0x56, check_val = 0x57; + VG_(lookupRangeMap)(&check_key_min, &check_key_max, &check_val, rm, + key_min + (key_max - key_min) / 2); + if (ix == 0) + vg_assert(key_min == (UWord)0); + if (ix == VG_(sizeRangeMap)(rm) - 1) + vg_assert(key_max == ~(UWord)0); + vg_assert(key_min == check_key_min); + vg_assert(key_max == check_key_max); + vg_assert(val == 0 || val == 1); + vg_assert(val == check_val); + } + if (val == 1) { + /* This is a part of cfsi_minavma .. cfsi_maxavma not covered. + Check no cfsi overlaps with this range. */ + for (i = 0; i < di->cfsi_used; i++) { + DiCfSI* cfsi = &di->cfsi_rd[i]; + vg_assert2(cfsi->base > key_max + || cfsi->base + cfsi->len - 1 < key_min, + "DiCfsi invariant (2) verification failed"); + } + } } vg_assert(cfsi_fits); diff --git a/coregrind/m_debuginfo/priv_storage.h b/coregrind/m_debuginfo/priv_storage.h index 713acbe..98e7156 100644 --- a/coregrind/m_debuginfo/priv_storage.h +++ b/coregrind/m_debuginfo/priv_storage.h @@ -670,9 +670,12 @@ struct _DebugInfo { (0) size of at least one rx mapping > 0 (1) no two non-archived DebugInfos with some rx mapping of size > 0 have overlapping rx mappings - (2) [cfsi_minavma,cfsi_maxavma] does not extend beyond - [avma,+size) of one rx mapping; that is, the former - is a subrange or equal to the latter. + (2) Each address in [cfsi_minavma,cfsi_maxavma] is in an rx mapping + or else no cfsi can cover this address. + The typical case is a single rx mapping covering the full range. + In some cases, the union of several rx mappings covers the range, + with possibly some holes between the rx mappings, and no cfsi fall + within such an hole. (3) all DiCfSI in the cfsi array all have ranges that fall within [avma,+size) of that rx mapping. (4) all DiCfSI in the cfsi array are non-overlapping |