diff --git a/.gitignore b/.gitignore index 3a77629..0d362c8 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,4 @@ /valgrind-3.16.0.RC2.tar.bz2 /valgrind-3.16.0.tar.bz2 /valgrind-3.16.1.tar.bz2 +/valgrind-3.17.0.RC1.tar.bz2 diff --git a/sources b/sources index 0d18846..eec672d 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (valgrind-3.16.1.tar.bz2) = 2a4173efe1b6facdd2f5c5ee8ed006704168eba1813736fccc8191d60363afd96197512cf42037e65f18d4ddd49adc74a54c47210df216fba3c46bf68ef0f950 +SHA512 (valgrind-3.17.0.RC1.tar.bz2) = ef71f3fca24466e78bd8a137666722f06cc5744cda5ae608b96d69390a72839e4d7499293872eb797e1c9edbe13ca6cf6147b6eb2491bb455d6696180f9864b7 diff --git a/valgrind-3.16.0-pkglibexecdir.patch b/valgrind-3.16.0-pkglibexecdir.patch deleted file mode 100644 index cd52729..0000000 --- a/valgrind-3.16.0-pkglibexecdir.patch +++ /dev/null @@ -1,117 +0,0 @@ -diff --git a/Makefile.all.am b/Makefile.all.am -index 3786e34..1befef5 100644 ---- a/Makefile.all.am -+++ b/Makefile.all.am -@@ -50,20 +50,20 @@ inplace-noinst_DSYMS: build-noinst_DSYMS - done - - # This is used by coregrind/Makefile.am and by /Makefile.am for doing --# "make install". It copies $(noinst_PROGRAMS) into $prefix/lib/valgrind/. -+# "make install". It copies $(noinst_PROGRAMS) into $prefix/libexec/valgrind/. - # It needs to be depended on by an 'install-exec-local' rule. - install-noinst_PROGRAMS: $(noinst_PROGRAMS) -- $(mkinstalldirs) $(DESTDIR)$(pkglibdir); \ -+ $(mkinstalldirs) $(DESTDIR)$(pkglibexecdir); \ - for f in $(noinst_PROGRAMS); do \ -- $(INSTALL_PROGRAM) $$f $(DESTDIR)$(pkglibdir); \ -+ $(INSTALL_PROGRAM) $$f $(DESTDIR)$(pkglibexecdir); \ - done - - # This is used by coregrind/Makefile.am and by /Makefile.am for doing --# "make uninstall". It removes $(noinst_PROGRAMS) from $prefix/lib/valgrind/. -+# "make uninstall". It removes $(noinst_PROGRAMS) from $prefix/libexec/valgrind/. - # It needs to be depended on by an 'uninstall-local' rule. - uninstall-noinst_PROGRAMS: - for f in $(noinst_PROGRAMS); do \ -- rm -f $(DESTDIR)$(pkglibdir)/$$f; \ -+ rm -f $(DESTDIR)$(pkglibexecdir)/$$f; \ - done - - # Similar to install-noinst_PROGRAMS. -@@ -71,15 +71,15 @@ uninstall-noinst_PROGRAMS: - # directories. XXX: not sure whether the resulting permissions will be - # correct when using 'cp -R'... - install-noinst_DSYMS: build-noinst_DSYMS -- $(mkinstalldirs) $(DESTDIR)$(pkglibdir); \ -+ $(mkinstalldirs) $(DESTDIR)$(pkglibexecdir); \ - for f in $(noinst_DSYMS); do \ -- cp -R $$f.dSYM $(DESTDIR)$(pkglibdir); \ -+ cp -R $$f.dSYM $(DESTDIR)$(pkglibexecdir); \ - done - - # Similar to uninstall-noinst_PROGRAMS. - uninstall-noinst_DSYMS: - for f in $(noinst_DSYMS); do \ -- rm -f $(DESTDIR)$(pkglibdir)/$$f.dSYM; \ -+ rm -f $(DESTDIR)$(pkglibexecdir)/$$f.dSYM; \ - done - - # This needs to be depended on by a 'clean-local' rule. -diff --git a/Makefile.am b/Makefile.am -index 242b38a..3b7c806 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -58,7 +58,7 @@ DEFAULT_SUPP_FILES = @DEFAULT_SUPP@ - # default.supp, as it is built from the base .supp files at compile-time. - dist_noinst_DATA = $(SUPP_FILES) - --vglibdir = $(pkglibdir) -+vglibdir = $(pkglibexecdir) - vglib_DATA = default.supp - - pkgconfigdir = $(libdir)/pkgconfig -diff --git a/coregrind/Makefile.am b/coregrind/Makefile.am -index 94030fd..f09763a 100644 ---- a/coregrind/Makefile.am -+++ b/coregrind/Makefile.am -@@ -11,12 +11,12 @@ include $(top_srcdir)/Makefile.all.am - - AM_CPPFLAGS_@VGCONF_PLATFORM_PRI_CAPS@ += \ - -I$(top_srcdir)/coregrind \ -- -DVG_LIBDIR="\"$(pkglibdir)"\" \ -+ -DVG_LIBDIR="\"$(pkglibexecdir)"\" \ - -DVG_PLATFORM="\"@VGCONF_ARCH_PRI@-@VGCONF_OS@\"" - if VGCONF_HAVE_PLATFORM_SEC - AM_CPPFLAGS_@VGCONF_PLATFORM_SEC_CAPS@ += \ - -I$(top_srcdir)/coregrind \ -- -DVG_LIBDIR="\"$(pkglibdir)"\" \ -+ -DVG_LIBDIR="\"$(pkglibexecdir)"\" \ - -DVG_PLATFORM="\"@VGCONF_ARCH_SEC@-@VGCONF_OS@\"" - endif - -@@ -714,7 +714,7 @@ GDBSERVER_XML_FILES = \ - m_gdbserver/mips64-fpu.xml - - # so as to make sure these get copied into the install tree --vglibdir = $(pkglibdir) -+vglibdir = $(pkglibexecdir) - vglib_DATA = $(GDBSERVER_XML_FILES) - - # so as to make sure these get copied into the tarball -diff --git a/mpi/Makefile.am b/mpi/Makefile.am -index 7ad9a25..471fee0 100644 ---- a/mpi/Makefile.am -+++ b/mpi/Makefile.am -@@ -18,16 +18,18 @@ EXTRA_DIST = \ - # libmpiwrap-.so - #---------------------------------------------------------------------------- - --noinst_PROGRAMS = -+# These are really real libraries, so they should go to libdir, not libexec. -+mpidir = $(pkglibdir) -+mpi_PROGRAMS = - if BUILD_MPIWRAP_PRI --noinst_PROGRAMS += libmpiwrap-@VGCONF_ARCH_PRI@-@VGCONF_OS@.so -+mpi_PROGRAMS += libmpiwrap-@VGCONF_ARCH_PRI@-@VGCONF_OS@.so - endif - if BUILD_MPIWRAP_SEC --noinst_PROGRAMS += libmpiwrap-@VGCONF_ARCH_SEC@-@VGCONF_OS@.so -+mpi_PROGRAMS += libmpiwrap-@VGCONF_ARCH_SEC@-@VGCONF_OS@.so - endif - - if VGCONF_OS_IS_DARWIN --noinst_DSYMS = $(noinst_PROGRAMS) -+mpi_DSYMS = $(mpi_PROGRAMS) - endif - - diff --git a/valgrind-3.16.0-shmctl.patch b/valgrind-3.16.0-shmctl.patch deleted file mode 100644 index 16d9d7c..0000000 --- a/valgrind-3.16.0-shmctl.patch +++ /dev/null @@ -1,111 +0,0 @@ -commit 232893d9b3c7d79d018db7f303aee219161a86d0 -Author: Anssi Hannula -Date: Thu Jul 2 14:49:17 2020 +0300 - - Fix shmat() on Linux nanomips and x86 - - On Linux, there are two variants of the direct shmctl syscall: - - sys_shmctl: always uses shmid64_ds, does not accept IPC_64 - - sys_old_shmctl: uses shmid_ds or shmid64_ds depending on IPC_64 - - The following Linux ABIs have the sys_old_shmctl variant: - alpha, arm, microblaze, mips n32/n64, xtensa - - Other ABIs (and future ABIs) have the sys_shmctl variant, including ABIs - that only got sys_shmctl in Linux 5.1 (such as x86, mips o32, ppc, - s390x). - - We incorrectly assume the sys_old_shmctl variant on nanomips and x86, - causing shmat() calls under valgrind to fail with EINVAL. - - On x86, the issue was previously masked by the non-existence of - __NR_shmctl until a9fc7bceeb0b0 ("Update Linux x86 system call number - definitions") in 2019. - - On mips o32, ppc, and s390x this issue is not visible as our headers do - not have __NR_shmctl for those ABIs (396 since Linux 5.1). - - Fix the issue by correcting the preprocessor check in get_shm_size() to - only assume the old Linux sys_old_shmctl behavior on the specific - affected platforms. - - Also, exclude the use of direct shmctl entirely on Linux x86, ppc, - mips o32, s390x in order to keep compatibility with pre-5.1 kernel - versions that did not yet have direct shmctl for those ABIs. - This currently only has actual effect on x86 as only it has __NR_shmctl - in our headers. - - Fixes tests mremap4, mremap5, mremap6. - - https://bugs.kde.org/show_bug.cgi?id=410743 - -diff --git a/coregrind/m_syswrap/syswrap-generic.c b/coregrind/m_syswrap/syswrap-generic.c -index badb8c778..7d4b385a3 100644 ---- a/coregrind/m_syswrap/syswrap-generic.c -+++ b/coregrind/m_syswrap/syswrap-generic.c -@@ -1960,11 +1960,27 @@ ML_(generic_POST_sys_semctl) ( ThreadId tid, - static - SizeT get_shm_size ( Int shmid ) - { --#if defined(__NR_shmctl) -+ /* -+ * The excluded platforms below gained direct shmctl in Linux 5.1. Keep -+ * using ipc-multiplexed shmctl to keep compatibility with older kernel -+ * versions. -+ */ -+#if defined(__NR_shmctl) && \ -+ !defined(VGP_x86_linux) && !defined(VGP_mips32_linux) && \ -+ !defined(VGP_ppc32_linux) && !defined(VGP_ppc64be_linux) && \ -+ !defined(VGP_ppc64le_linux) && !defined(VGP_s390x_linux) - # ifdef VKI_IPC_64 - struct vki_shmid64_ds buf; --# if defined(VGP_amd64_linux) || defined(VGP_arm64_linux) -- /* See bug 222545 comment 7 */ -+ /* -+ * On Linux, the following ABIs use old shmid_ds by default with direct -+ * shmctl and require IPC_64 for shmid64_ds (i.e. the direct syscall is -+ * mapped to sys_old_shmctl): -+ * alpha, arm, microblaze, mips n32/n64, xtensa -+ * Other Linux ABIs use shmid64_ds by default and do not recognize IPC_64 -+ * with the direct shmctl syscall (but still recognize it for the -+ * ipc-multiplexed version if that exists for the ABI). -+ */ -+# if defined(VGO_linux) && !defined(VGP_arm_linux) && !defined(VGP_mips64_linux) - SysRes __res = VG_(do_syscall3)(__NR_shmctl, shmid, - VKI_IPC_STAT, (UWord)&buf); - # else -commit 620dba22be67dea2ada9fa825b2ed4d61774af82 -Author: Mark Wielaard -Date: Wed Feb 3 16:56:14 2021 +0100 - - syswrap-linux.c: Pass implicit VKI_IPC_64 for shmctl also on arm64. - - The shmctl syscall on amd64, arm64 and riscv (but we don't have a port - for that last one) always use IPC_64. Explicitly pass it to the generic - PRE/POST handlers so they select the correct (64bit) data structures on - those architectures. - - https://bugzilla.redhat.com/show_bug.cgi?id=1909548 - -diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c -index 328e02a98..52074149d 100644 ---- a/coregrind/m_syswrap/syswrap-linux.c -+++ b/coregrind/m_syswrap/syswrap-linux.c -@@ -5127,7 +5127,7 @@ PRE(sys_shmctl) - PRINT("sys_shmctl ( %ld, %ld, %#" FMT_REGWORD "x )", SARG1, SARG2, ARG3); - PRE_REG_READ3(long, "shmctl", - int, shmid, int, cmd, struct shmid_ds *, buf); --#ifdef VGP_amd64_linux -+#if defined(VGP_amd64_linux) || defined(VGP_arm64_linux) - ML_(generic_PRE_sys_shmctl)(tid, ARG1,ARG2|VKI_IPC_64,ARG3); - #else - ML_(generic_PRE_sys_shmctl)(tid, ARG1,ARG2,ARG3); -@@ -5136,7 +5136,7 @@ PRE(sys_shmctl) - - POST(sys_shmctl) - { --#ifdef VGP_amd64_linux -+#if defined(VGP_amd64_linux) || defined(VGP_arm64_linux) - ML_(generic_POST_sys_shmctl)(tid, RES,ARG1,ARG2|VKI_IPC_64,ARG3); - #else - ML_(generic_POST_sys_shmctl)(tid, RES,ARG1,ARG2,ARG3); diff --git a/valgrind-3.16.0-some-stack-protector.patch b/valgrind-3.16.0-some-stack-protector.patch index bde2aa5..324c7d3 100644 --- a/valgrind-3.16.0-some-stack-protector.patch +++ b/valgrind-3.16.0-some-stack-protector.patch @@ -52,8 +52,8 @@ diff --git a/configure.ac b/configure.ac index f8c798b..ccc8f52 100755 --- a/configure.ac +++ b/configure.ac -@@ -2188,24 +2188,24 @@ AC_LANG(C) - AC_SUBST(FLAG_FALIGNED_NEW) +@@ -2352,24 +2352,24 @@ + AM_CONDITIONAL([HAVE_ALIGNED_CXX_ALLOC], [test x$ac_have_aligned_cxx_alloc = xyes]) # does this compiler support -fno-stack-protector ? -AC_MSG_CHECKING([if gcc accepts -fno-stack-protector]) diff --git a/valgrind-3.16.1-PPC64BE-lsw.patch b/valgrind-3.16.1-PPC64BE-lsw.patch deleted file mode 100644 index 2a1e9c3..0000000 --- a/valgrind-3.16.1-PPC64BE-lsw.patch +++ /dev/null @@ -1,34 +0,0 @@ -diff --git a/none/tests/ppc64/ldst_multiple.vgtest b/none/tests/ppc64/ldst_multiple.vgtest -index 87e668e09..22dd46c99 100644 ---- a/none/tests/ppc64/ldst_multiple.vgtest -+++ b/none/tests/ppc64/ldst_multiple.vgtest -@@ -1 +1,2 @@ -+prereq: ../../../tests/is_ppc64_BE - prog: ldst_multiple ---- valgrind-3.16.1/none/tests/ppc64/Makefile.am.orig 2020-10-18 20:43:34.579699246 +0200 -+++ valgrind-3.16.1/none/tests/ppc64/Makefile.am 2020-10-18 20:44:52.950198040 +0200 -@@ -54,17 +54,22 @@ - - check_PROGRAMS = \ - allexec \ -- lsw jm-insns round \ -+ jm-insns round \ - test_isa_2_06_part1 test_isa_2_06_part2 test_isa_2_06_part3 \ - test_dfp1 test_dfp2 test_dfp3 test_dfp4 test_dfp5 \ - test_isa_2_07_part1 test_isa_2_07_part2 \ - test_isa_3_0 \ - subnormal_test \ -- test_tm test_touch_tm ldst_multiple data-cache-instructions \ -+ test_tm test_touch_tm data-cache-instructions \ - power6_mf_gpr std_reg_imm \ - twi_tdi tw_td power6_bcmp - - -+# lsw and ldst_multiple compile (and run) only on big endian. -+if VGCONF_PLATFORMS_INCLUDE_PPC64BE_LINUX -+check_PROGRAMS += lsw ldst_multiple -+endif -+ - AM_CFLAGS += @FLAG_M64@ - AM_CXXFLAGS += @FLAG_M64@ - AM_CCASFLAGS += @FLAG_M64@ diff --git a/valgrind-3.16.1-REX-prefix-JMP.patch b/valgrind-3.16.1-REX-prefix-JMP.patch deleted file mode 100644 index f780fb1..0000000 --- a/valgrind-3.16.1-REX-prefix-JMP.patch +++ /dev/null @@ -1,38 +0,0 @@ -commit e2dec0ff9b1e071779bee2c4e6fc82f8194b1c1d -Author: Mark Wielaard -Date: Sun Jul 26 21:17:23 2020 +0200 - - Handle REX prefixed JMP instruction. - - The NET Core runtime might generate a JMP with a REX prefix. - For Jv (32bit offset) and Jb (8bit offset) this is valid. - Prefixes that change operand size are ignored for such JMPs. - So remove the check for sz == 4 and force sz = 4 for Jv. - - https://bugs.kde.org/show_bug.cgi?id=422174 - -diff --git a/VEX/priv/guest_amd64_toIR.c b/VEX/priv/guest_amd64_toIR.c -index fadf47d41..7888132eb 100644 ---- a/VEX/priv/guest_amd64_toIR.c -+++ b/VEX/priv/guest_amd64_toIR.c -@@ -21392,8 +21392,8 @@ Long dis_ESC_NONE ( - - case 0xE9: /* Jv (jump, 16/32 offset) */ - if (haveF3(pfx)) goto decode_failure; -- if (sz != 4) -- goto decode_failure; /* JRS added 2004 July 11 */ -+ sz = 4; /* Prefixes that change operand size are ignored for this -+ instruction. Operand size is forced to 32bit. */ - if (haveF2(pfx)) DIP("bnd ; "); /* MPX bnd prefix. */ - d64 = (guest_RIP_bbstart+delta+sz) + getSDisp(sz,delta); - delta += sz; -@@ -21404,8 +21404,7 @@ Long dis_ESC_NONE ( - - case 0xEB: /* Jb (jump, byte offset) */ - if (haveF3(pfx)) goto decode_failure; -- if (sz != 4) -- goto decode_failure; /* JRS added 2004 July 11 */ -+ /* Prefixes that change operand size are ignored for this instruction. */ - if (haveF2(pfx)) DIP("bnd ; "); /* MPX bnd prefix. */ - d64 = (guest_RIP_bbstart+delta+1) + getSDisp8(delta); - delta++; diff --git a/valgrind-3.16.1-arm64-expensive-cmp.patch b/valgrind-3.16.1-arm64-expensive-cmp.patch deleted file mode 100644 index b2f8b50..0000000 --- a/valgrind-3.16.1-arm64-expensive-cmp.patch +++ /dev/null @@ -1,19 +0,0 @@ -commit 359b98828ced9cfff8c1badfed75c7ef999cfee5 -Author: Julian Seward -Date: Sun Nov 15 18:28:09 2020 +0100 - - memcheck: on arm64, use expensive instrumentation for Cmp{EQ,NE}64 by default. - -diff --git a/memcheck/mc_translate.c b/memcheck/mc_translate.c -index b32c9c9c5..e91d51094 100644 ---- a/memcheck/mc_translate.c -+++ b/memcheck/mc_translate.c -@@ -8485,6 +8485,8 @@ IRSB* MC_(instrument) ( VgCallbackClosure* closure, - # elif defined(VGA_ppc64le) - // Needed by (at least) set_AV_CR6() in the front end. - mce.dlbo.dl_CmpEQ64_CmpNE64 = DLexpensive; -+# elif defined(VGA_arm64) -+ mce.dlbo.dl_CmpEQ64_CmpNE64 = DLexpensive; - # endif - - /* preInstrumentationAnalysis() will allocate &mce.tmpHowUsed and then diff --git a/valgrind-3.16.1-arm64-fma.patch b/valgrind-3.16.1-arm64-fma.patch deleted file mode 100644 index c8ef17a..0000000 --- a/valgrind-3.16.1-arm64-fma.patch +++ /dev/null @@ -1,729 +0,0 @@ -From 04cdc29b007594a0e58ffef0c9dd87df3ea595ea Mon Sep 17 00:00:00 2001 -From: Mark Wielaard -Date: Wed, 14 Oct 2020 06:11:34 -0400 -Subject: [PATCH] arm64 VEX frontend and backend support for - Iop_M{Add,Sub}F{32,64} - -The arm64 frontend used to implement the scalar fmadd, fmsub, fnmadd -and fnmsub iinstructions into separate addition/substraction and -multiplication instructions, which caused rounding issues. - -This patch turns them into Iop_M{Add,Sub}F{32,64} instructions -(with some arguments negated). And the backend now emits fmadd or fmsub -instructions. - -Alexandra Hajkova added tests and fixed up the -implementation to make sure rounding (and sign) are correct now. - -https://bugs.kde.org/show_bug.cgi?id=426014 ---- - VEX/priv/guest_arm64_toIR.c | 58 ++++++++--- - VEX/priv/host_arm64_defs.c | 136 +++++++++++++++++++++++++- - VEX/priv/host_arm64_defs.h | 30 ++++++ - VEX/priv/host_arm64_isel.c | 39 ++++++++ - none/tests/arm64/Makefile.am | 6 +- - none/tests/arm64/fmadd_sub.c | 98 +++++++++++++++++++ - none/tests/arm64/fmadd_sub.stderr.exp | 0 - none/tests/arm64/fmadd_sub.stdout.exp | 125 +++++++++++++++++++++++ - none/tests/arm64/fmadd_sub.vgtest | 3 + - 9 files changed, 479 insertions(+), 16 deletions(-) - create mode 100644 none/tests/arm64/fmadd_sub.c - create mode 100644 none/tests/arm64/fmadd_sub.stderr.exp - create mode 100644 none/tests/arm64/fmadd_sub.stdout.exp - create mode 100644 none/tests/arm64/fmadd_sub.vgtest - -diff --git a/VEX/priv/guest_arm64_toIR.c b/VEX/priv/guest_arm64_toIR.c -index 556b85a6a..d242d43c0 100644 ---- a/VEX/priv/guest_arm64_toIR.c -+++ b/VEX/priv/guest_arm64_toIR.c -@@ -286,6 +286,12 @@ static IRExpr* triop ( IROp op, IRExpr* a1, IRExpr* a2, IRExpr* a3 ) - return IRExpr_Triop(op, a1, a2, a3); - } - -+static IRExpr* qop ( IROp op, IRExpr* a1, IRExpr* a2, -+ IRExpr* a3, IRExpr* a4 ) -+{ -+ return IRExpr_Qop(op, a1, a2, a3, a4); -+} -+ - static IRExpr* loadLE ( IRType ty, IRExpr* addr ) - { - return IRExpr_Load(Iend_LE, ty, addr); -@@ -532,6 +538,22 @@ static IROp mkADDF ( IRType ty ) { - } - } - -+static IROp mkFMADDF ( IRType ty ) { -+ switch (ty) { -+ case Ity_F32: return Iop_MAddF32; -+ case Ity_F64: return Iop_MAddF64; -+ default: vpanic("mkFMADDF"); -+ } -+} -+ -+static IROp mkFMSUBF ( IRType ty ) { -+ switch (ty) { -+ case Ity_F32: return Iop_MSubF32; -+ case Ity_F64: return Iop_MSubF64; -+ default: vpanic("mkFMSUBF"); -+ } -+} -+ - static IROp mkSUBF ( IRType ty ) { - switch (ty) { - case Ity_F32: return Iop_SubF32; -@@ -14368,30 +14390,40 @@ Bool dis_AdvSIMD_fp_data_proc_3_source(/*MB_OUT*/DisResult* dres, UInt insn) - where Fx=Dx when sz=1, Fx=Sx when sz=0 - - -----SPEC------ ----IMPL---- -- fmadd a + n * m a + n * m -- fmsub a + (-n) * m a - n * m -- fnmadd (-a) + (-n) * m -(a + n * m) -- fnmsub (-a) + n * m -(a - n * m) -+ fmadd a + n * m fmadd (a, n, m) -+ fmsub a + (-n) * m fmsub (a, n, m) -+ fnmadd (-a) + (-n) * m fmadd (-a, -n, m) -+ fnmsub (-a) + n * m fmadd (-a, n, m) -+ -+ Note Iop_MAdd/SubF32/64 take arguments in the order: rm, N, M, A - */ - Bool isD = (ty & 1) == 1; - UInt ix = (bitO1 << 1) | bitO0; - IRType ity = isD ? Ity_F64 : Ity_F32; -- IROp opADD = mkADDF(ity); -- IROp opSUB = mkSUBF(ity); -- IROp opMUL = mkMULF(ity); -+ IROp opFMADD = mkFMADDF(ity); -+ IROp opFMSUB = mkFMSUBF(ity); - IROp opNEG = mkNEGF(ity); - IRTemp res = newTemp(ity); - IRExpr* eA = getQRegLO(aa, ity); - IRExpr* eN = getQRegLO(nn, ity); - IRExpr* eM = getQRegLO(mm, ity); - IRExpr* rm = mkexpr(mk_get_IR_rounding_mode()); -- IRExpr* eNxM = triop(opMUL, rm, eN, eM); - switch (ix) { -- case 0: assign(res, triop(opADD, rm, eA, eNxM)); break; -- case 1: assign(res, triop(opSUB, rm, eA, eNxM)); break; -- case 2: assign(res, unop(opNEG, triop(opADD, rm, eA, eNxM))); break; -- case 3: assign(res, unop(opNEG, triop(opSUB, rm, eA, eNxM))); break; -- default: vassert(0); -+ case 0: /* FMADD */ -+ assign(res, qop(opFMADD, rm, eN, eM, eA)); -+ break; -+ case 1: /* FMSUB */ -+ assign(res, qop(opFMSUB, rm, eN, eM, eA)); -+ break; -+ case 2: /* FNMADD */ -+ assign(res, qop(opFMADD, rm, unop(opNEG, eN), eM, -+ unop(opNEG,eA))); -+ break; -+ case 3: /* FNMSUB */ -+ assign(res, qop(opFMADD, rm, eN, eM, unop(opNEG, eA))); -+ break; -+ default: -+ vassert(0); - } - putQReg128(dd, mkV128(0x0000)); - putQRegLO(dd, mkexpr(res)); -diff --git a/VEX/priv/host_arm64_defs.c b/VEX/priv/host_arm64_defs.c -index e4ef56986..13b497f60 100644 ---- a/VEX/priv/host_arm64_defs.c -+++ b/VEX/priv/host_arm64_defs.c -@@ -546,6 +546,14 @@ static const HChar* showARM64FpBinOp ( ARM64FpBinOp op ) { - } - } - -+static const HChar* showARM64FpTriOp ( ARM64FpTriOp op ) { -+ switch (op) { -+ case ARM64fpt_FMADD: return "fmadd"; -+ case ARM64fpt_FMSUB: return "fmsub"; -+ default: vpanic("showARM64FpTriOp"); -+ } -+} -+ - static const HChar* showARM64FpUnaryOp ( ARM64FpUnaryOp op ) { - switch (op) { - case ARM64fpu_NEG: return "neg "; -@@ -1154,6 +1162,28 @@ ARM64Instr* ARM64Instr_VBinS ( ARM64FpBinOp op, - i->ARM64in.VBinS.argR = argR; - return i; - } -+ARM64Instr* ARM64Instr_VTriD ( ARM64FpTriOp op, -+ HReg dst, HReg arg1, HReg arg2, HReg arg3 ) { -+ ARM64Instr* i = LibVEX_Alloc_inline(sizeof(ARM64Instr)); -+ i->tag = ARM64in_VTriD; -+ i->ARM64in.VTriD.op = op; -+ i->ARM64in.VTriD.dst = dst; -+ i->ARM64in.VTriD.arg1 = arg1; -+ i->ARM64in.VTriD.arg2 = arg2; -+ i->ARM64in.VTriD.arg3 = arg3; -+ return i; -+} -+ARM64Instr* ARM64Instr_VTriS ( ARM64FpTriOp op, -+ HReg dst, HReg arg1, HReg arg2, HReg arg3 ) { -+ ARM64Instr* i = LibVEX_Alloc_inline(sizeof(ARM64Instr)); -+ i->tag = ARM64in_VTriS; -+ i->ARM64in.VTriS.op = op; -+ i->ARM64in.VTriS.dst = dst; -+ i->ARM64in.VTriS.arg1 = arg1; -+ i->ARM64in.VTriS.arg2 = arg2; -+ i->ARM64in.VTriS.arg3 = arg3; -+ return i; -+} - ARM64Instr* ARM64Instr_VCmpD ( HReg argL, HReg argR ) { - ARM64Instr* i = LibVEX_Alloc_inline(sizeof(ARM64Instr)); - i->tag = ARM64in_VCmpD; -@@ -1756,6 +1786,26 @@ void ppARM64Instr ( const ARM64Instr* i ) { - vex_printf(", "); - ppHRegARM64asSreg(i->ARM64in.VBinS.argR); - return; -+ case ARM64in_VTriD: -+ vex_printf("f%s ", showARM64FpTriOp(i->ARM64in.VTriD.op)); -+ ppHRegARM64(i->ARM64in.VTriD.dst); -+ vex_printf(", "); -+ ppHRegARM64(i->ARM64in.VTriD.arg1); -+ vex_printf(", "); -+ ppHRegARM64(i->ARM64in.VTriD.arg2); -+ vex_printf(", "); -+ ppHRegARM64(i->ARM64in.VTriD.arg3); -+ return; -+ case ARM64in_VTriS: -+ vex_printf("f%s ", showARM64FpTriOp(i->ARM64in.VTriS.op)); -+ ppHRegARM64asSreg(i->ARM64in.VTriS.dst); -+ vex_printf(", "); -+ ppHRegARM64asSreg(i->ARM64in.VTriS.arg1); -+ vex_printf(", "); -+ ppHRegARM64asSreg(i->ARM64in.VTriS.arg2); -+ vex_printf(", "); -+ ppHRegARM64asSreg(i->ARM64in.VTriS.arg3); -+ return; - case ARM64in_VCmpD: - vex_printf("fcmp "); - ppHRegARM64(i->ARM64in.VCmpD.argL); -@@ -2197,6 +2247,18 @@ void getRegUsage_ARM64Instr ( HRegUsage* u, const ARM64Instr* i, Bool mode64 ) - addHRegUse(u, HRmRead, i->ARM64in.VBinS.argL); - addHRegUse(u, HRmRead, i->ARM64in.VBinS.argR); - return; -+ case ARM64in_VTriD: -+ addHRegUse(u, HRmWrite, i->ARM64in.VTriD.dst); -+ addHRegUse(u, HRmRead, i->ARM64in.VTriD.arg1); -+ addHRegUse(u, HRmRead, i->ARM64in.VTriD.arg2); -+ addHRegUse(u, HRmRead, i->ARM64in.VTriD.arg3); -+ return; -+ case ARM64in_VTriS: -+ addHRegUse(u, HRmWrite, i->ARM64in.VTriS.dst); -+ addHRegUse(u, HRmRead, i->ARM64in.VTriS.arg1); -+ addHRegUse(u, HRmRead, i->ARM64in.VTriS.arg2); -+ addHRegUse(u, HRmRead, i->ARM64in.VTriS.arg3); -+ return; - case ARM64in_VCmpD: - addHRegUse(u, HRmRead, i->ARM64in.VCmpD.argL); - addHRegUse(u, HRmRead, i->ARM64in.VCmpD.argR); -@@ -2454,6 +2516,18 @@ void mapRegs_ARM64Instr ( HRegRemap* m, ARM64Instr* i, Bool mode64 ) - i->ARM64in.VBinS.argL = lookupHRegRemap(m, i->ARM64in.VBinS.argL); - i->ARM64in.VBinS.argR = lookupHRegRemap(m, i->ARM64in.VBinS.argR); - return; -+ case ARM64in_VTriD: -+ i->ARM64in.VTriD.dst = lookupHRegRemap(m, i->ARM64in.VTriD.dst); -+ i->ARM64in.VTriD.arg1 = lookupHRegRemap(m, i->ARM64in.VTriD.arg1); -+ i->ARM64in.VTriD.arg2 = lookupHRegRemap(m, i->ARM64in.VTriD.arg2); -+ i->ARM64in.VTriD.arg3 = lookupHRegRemap(m, i->ARM64in.VTriD.arg3); -+ return; -+ case ARM64in_VTriS: -+ i->ARM64in.VTriS.dst = lookupHRegRemap(m, i->ARM64in.VTriS.dst); -+ i->ARM64in.VTriS.arg1 = lookupHRegRemap(m, i->ARM64in.VTriS.arg1); -+ i->ARM64in.VTriS.arg2 = lookupHRegRemap(m, i->ARM64in.VTriS.arg2); -+ i->ARM64in.VTriS.arg3 = lookupHRegRemap(m, i->ARM64in.VTriS.arg3); -+ return; - case ARM64in_VCmpD: - i->ARM64in.VCmpD.argL = lookupHRegRemap(m, i->ARM64in.VCmpD.argL); - i->ARM64in.VCmpD.argR = lookupHRegRemap(m, i->ARM64in.VCmpD.argR); -@@ -2812,7 +2886,8 @@ static inline UInt qregEnc ( HReg r ) - #define X11110011 BITS8(1,1,1,1,0,0,1,1) - #define X11110101 BITS8(1,1,1,1,0,1,0,1) - #define X11110111 BITS8(1,1,1,1,0,1,1,1) -- -+#define X11111000 BITS8(1,1,1,1,1,0,0,0) -+#define X11111010 BITS8(1,1,1,1,1,0,1,0) - - /* --- 4 fields --- */ - -@@ -2972,6 +3047,27 @@ static inline UInt X_3_6_1_6_6_5_5 ( UInt f1, UInt f2, UInt f3, - } - - -+static inline UInt X_3_8_5_1_5_5_5 ( UInt f1, UInt f2, UInt f3, UInt f4, -+ UInt f5, UInt f6, UInt f7 ) { -+ vassert(3+8+5+1+5+5+5 == 32); -+ vassert(f1 < (1<<3)); -+ vassert(f2 < (1<<8)); -+ vassert(f3 < (1<<5)); -+ vassert(f4 < (1<<1)); -+ vassert(f5 < (1<<5)); -+ vassert(f6 < (1<<5)); -+ vassert(f7 < (1<<5)); -+ UInt w = 0; -+ w = (w << 3) | f1; -+ w = (w << 8) | f2; -+ w = (w << 5) | f3; -+ w = (w << 1) | f4; -+ w = (w << 5) | f5; -+ w = (w << 5) | f6; -+ w = (w << 5) | f7; -+ return w; -+} -+ - //ZZ #define X0000 BITS4(0,0,0,0) - //ZZ #define X0001 BITS4(0,0,0,1) - //ZZ #define X0010 BITS4(0,0,1,0) -@@ -4339,6 +4435,44 @@ Int emit_ARM64Instr ( /*MB_MOD*/Bool* is_profInc, - = X_3_8_5_6_5_5(X000, X11110001, sM, (b1512 << 2) | X10, sN, sD); - goto done; - } -+ case ARM64in_VTriD: { -+ /* 31 20 15 14 9 4 -+ 000 11111 010 m 0 a n d FMADD Dd,Dn,Dm,Da -+ ---------------- 1 ------ FMSUB ----------- -+ */ -+ UInt dD = dregEnc(i->ARM64in.VTriD.dst); -+ UInt dN = dregEnc(i->ARM64in.VTriD.arg1); -+ UInt dM = dregEnc(i->ARM64in.VTriD.arg2); -+ UInt dA = dregEnc(i->ARM64in.VTriD.arg3); -+ UInt b15 = 2; /* impossible */ -+ switch (i->ARM64in.VTriD.op) { -+ case ARM64fpt_FMADD: b15 = 0; break; -+ case ARM64fpt_FMSUB: b15 = 1; break; -+ default: goto bad; -+ } -+ vassert(b15 < 2); -+ *p++ = X_3_8_5_1_5_5_5(X000, X11111010, dM, b15, dA, dN, dD); -+ goto done; -+ } -+ case ARM64in_VTriS: { -+ /* 31 20 15 14 9 4 -+ 000 11111 000 m 0 a n d FMADD Dd,Dn,Dm,Da -+ ---------------- 1 ------ FMSUB ----------- -+ */ -+ UInt dD = dregEnc(i->ARM64in.VTriD.dst); -+ UInt dN = dregEnc(i->ARM64in.VTriD.arg1); -+ UInt dM = dregEnc(i->ARM64in.VTriD.arg2); -+ UInt dA = dregEnc(i->ARM64in.VTriD.arg3); -+ UInt b15 = 2; /* impossible */ -+ switch (i->ARM64in.VTriD.op) { -+ case ARM64fpt_FMADD: b15 = 0; break; -+ case ARM64fpt_FMSUB: b15 = 1; break; -+ default: goto bad; -+ } -+ vassert(b15 < 2); -+ *p++ = X_3_8_5_1_5_5_5(X000, X11111000, dM, b15, dA, dN, dD); -+ goto done; -+ } - case ARM64in_VCmpD: { - /* 000 11110 01 1 m 00 1000 n 00 000 FCMP Dn, Dm */ - UInt dN = dregEnc(i->ARM64in.VCmpD.argL); -diff --git a/VEX/priv/host_arm64_defs.h b/VEX/priv/host_arm64_defs.h -index 05dba7ab8..5a82564ce 100644 ---- a/VEX/priv/host_arm64_defs.h -+++ b/VEX/priv/host_arm64_defs.h -@@ -289,6 +289,14 @@ typedef - } - ARM64FpBinOp; - -+typedef -+ enum { -+ ARM64fpt_FMADD=105, -+ ARM64fpt_FMSUB, -+ ARM64fpt_INVALID -+ } -+ ARM64FpTriOp; -+ - typedef - enum { - ARM64fpu_NEG=110, -@@ -498,6 +506,8 @@ typedef - ARM64in_VUnaryS, - ARM64in_VBinD, - ARM64in_VBinS, -+ ARM64in_VTriD, -+ ARM64in_VTriS, - ARM64in_VCmpD, - ARM64in_VCmpS, - ARM64in_VFCSel, -@@ -799,6 +809,22 @@ typedef - HReg argL; - HReg argR; - } VBinS; -+ /* 64-bit FP ternary arithmetic */ -+ struct { -+ ARM64FpTriOp op; -+ HReg dst; -+ HReg arg1; -+ HReg arg2; -+ HReg arg3; -+ } VTriD; -+ /* 32-bit FP ternary arithmetic */ -+ struct { -+ ARM64FpTriOp op; -+ HReg dst; -+ HReg arg1; -+ HReg arg2; -+ HReg arg3; -+ } VTriS; - /* 64-bit FP compare */ - struct { - HReg argL; -@@ -970,6 +996,10 @@ extern ARM64Instr* ARM64Instr_VUnaryD ( ARM64FpUnaryOp op, HReg dst, HReg src ); - extern ARM64Instr* ARM64Instr_VUnaryS ( ARM64FpUnaryOp op, HReg dst, HReg src ); - extern ARM64Instr* ARM64Instr_VBinD ( ARM64FpBinOp op, HReg, HReg, HReg ); - extern ARM64Instr* ARM64Instr_VBinS ( ARM64FpBinOp op, HReg, HReg, HReg ); -+extern ARM64Instr* ARM64Instr_VTriD ( ARM64FpTriOp op, HReg dst, -+ HReg, HReg, HReg ); -+extern ARM64Instr* ARM64Instr_VTriS ( ARM64FpTriOp op, HReg dst, -+ HReg, HReg, HReg ); - extern ARM64Instr* ARM64Instr_VCmpD ( HReg argL, HReg argR ); - extern ARM64Instr* ARM64Instr_VCmpS ( HReg argL, HReg argR ); - extern ARM64Instr* ARM64Instr_VFCSel ( HReg dst, HReg argL, HReg argR, -diff --git a/VEX/priv/host_arm64_isel.c b/VEX/priv/host_arm64_isel.c -index 2f19eab81..da1218715 100644 ---- a/VEX/priv/host_arm64_isel.c -+++ b/VEX/priv/host_arm64_isel.c -@@ -3255,6 +3255,25 @@ static HReg iselDblExpr_wrk ( ISelEnv* env, IRExpr* e ) - } - } - -+ if (e->tag == Iex_Qop) { -+ IRQop* qop = e->Iex.Qop.details; -+ ARM64FpTriOp triop = ARM64fpt_INVALID; -+ switch (qop->op) { -+ case Iop_MAddF64: triop = ARM64fpt_FMADD; break; -+ case Iop_MSubF64: triop = ARM64fpt_FMSUB; break; -+ default: break; -+ } -+ if (triop != ARM64fpt_INVALID) { -+ HReg N = iselDblExpr(env, qop->arg2); -+ HReg M = iselDblExpr(env, qop->arg3); -+ HReg A = iselDblExpr(env, qop->arg4); -+ HReg dst = newVRegD(env); -+ set_FPCR_rounding_mode(env, qop->arg1); -+ addInstr(env, ARM64Instr_VTriD(triop, dst, N, M, A)); -+ return dst; -+ } -+ } -+ - if (e->tag == Iex_ITE) { - /* ITE(ccexpr, iftrue, iffalse) */ - ARM64CondCode cc; -@@ -3450,6 +3469,26 @@ static HReg iselFltExpr_wrk ( ISelEnv* env, IRExpr* e ) - return dst; - } - -+ if (e->tag == Iex_Qop) { -+ IRQop* qop = e->Iex.Qop.details; -+ ARM64FpTriOp triop = ARM64fpt_INVALID; -+ switch (qop->op) { -+ case Iop_MAddF32: triop = ARM64fpt_FMADD; break; -+ case Iop_MSubF32: triop = ARM64fpt_FMSUB; break; -+ default: break; -+ } -+ -+ if (triop != ARM64fpt_INVALID) { -+ HReg N = iselFltExpr(env, qop->arg2); -+ HReg M = iselFltExpr(env, qop->arg3); -+ HReg A = iselFltExpr(env, qop->arg4); -+ HReg dst = newVRegD(env); -+ set_FPCR_rounding_mode(env, qop->arg1); -+ addInstr(env, ARM64Instr_VTriS(triop, dst, N, M, A)); -+ return dst; -+ } -+ } -+ - ppIRExpr(e); - vpanic("iselFltExpr_wrk"); - } -diff --git a/none/tests/arm64/Makefile.am b/none/tests/arm64/Makefile.am -index 7b3ebbdca..4ecab36ad 100644 ---- a/none/tests/arm64/Makefile.am -+++ b/none/tests/arm64/Makefile.am -@@ -10,14 +10,16 @@ EXTRA_DIST = \ - integer.stdout.exp integer.stderr.exp integer.vgtest \ - memory.stdout.exp memory.stderr.exp memory.vgtest \ - atomics_v81.stdout.exp atomics_v81.stderr.exp atomics_v81.vgtest \ -- simd_v81.stdout.exp simd_v81.stderr.exp simd_v81.vgtest -+ simd_v81.stdout.exp simd_v81.stderr.exp simd_v81.vgtest \ -+ fmadd_sub.stdout.exp fmadd_sub.stderr.exp fmadd_sub.vgtest - - check_PROGRAMS = \ - allexec \ - cvtf_imm \ - fp_and_simd \ - integer \ -- memory -+ memory \ -+ fmadd_sub - - if BUILD_ARMV8_CRC_TESTS - check_PROGRAMS += crc32 -diff --git a/none/tests/arm64/fmadd_sub.c b/none/tests/arm64/fmadd_sub.c -new file mode 100644 -index 000000000..dcab22d1b ---- /dev/null -+++ b/none/tests/arm64/fmadd_sub.c -@@ -0,0 +1,98 @@ -+#include -+#include -+#include -+#include -+ -+#define COUNT 5 -+ -+static void -+print_float(const char *ident, float x) -+{ -+ union -+ { -+ float f; -+ uint32_t i; -+ } u; -+ -+ u.f = x; -+ printf("%s = %08x = %.17g\n", ident, u.i, x); -+} -+ -+static void -+print_double(const char *ident, double x) -+{ -+ union -+ { -+ double f; -+ uint64_t i; -+ } u; -+ -+ u.f = x; -+ printf("%s = %016lx = %.17g\n", ident, u.i, x); -+} -+ -+int -+main(int argc, char **argv) -+{ -+ float x[] = { 55, 0.98076171874999996, 0, 1, 0xFFFFFFFF } ; -+ float y[] = { 0.69314718055994529, 1.015625, 0, 1, 0xFFFFFFFF }; -+ float z[] = { 38.123094930796988, 1, 0, 1, 0xFFFFFFFF }; -+ float dst = -5; -+ -+ double dx[] = { 55, 0.98076171874999996, 0, 1, 0xFFFFFFFF } ; -+ double dy[] = { 0.69314718055994529, 1.015625, 0, 1, 0xFFFFFFFF }; -+ double dz[] = { 38.123094930796988, 1, 0, 1, 0xFFFFFFFF }; -+ double ddst= -5; -+ -+ int i; -+ -+ for (i = 0; i < COUNT; i++) { -+ //32bit variant -+ asm("fmadd %s0, %s1, %s2, %s3\n;" : "=w"(dst) : "w"(x[i]), "w"(y[i]), "w"(z[i])); -+ printf("FMADD 32bit: dst = z + x * y\n"); -+ printf("%f = %f + %f * %f\n", dst, z[i], x[i], y[i]); -+ print_float("dst", dst); -+ -+ // Floating-point negated fused multiply-add -+ asm("fnmadd %s0, %s1, %s2, %s3\n;" : "=w"(dst) : "w"(x[i]), "w"(y[i]), "w"(z[i])); -+ printf("FNMADD 32bit: dst = -z + (-x) * y\n"); -+ printf("%f = -%f + (-%f) * %f\n", dst, z[i], x[i], y[i]); -+ print_float("dst", dst); -+ -+ asm("fmsub %s0, %s1, %s2, %s3\n;" : "=w"(dst) : "w"(x[i]), "w"(y[i]), "w"(z[i])); -+ printf("FMSUB 32bit: dst = z + (-x) * y\n"); -+ printf("%f = %f + (-%f) * %f\n", dst, z[i], x[i], y[i]); -+ print_float("dst", dst); -+ -+ asm("fnmsub %s0, %s1, %s2, %s3\n;" : "=w"(dst) : "w"(x[i]), "w"(y[i]), "w"(z[i])); -+ printf("FNMSUB 32bit: dst = -z + x * y\n"); -+ printf("%f = -%f + %f * %f\n", dst, z[i], x[i], y[i]); -+ print_float("dst", dst); -+ -+ //64bit variant -+ asm("fmadd %d0, %d1, %d2, %d3\n;" : "=w"(ddst) : "w"(dx[i]), "w"(dy[i]), "w"(dz[i])); -+ printf("FMADD 64bit: dst = z + x * y\n"); -+ printf("%f = %f + %f * %f\n", ddst, dz[i], dx[i], dy[i]); -+ print_double("dst", ddst); -+ -+ asm("fnmadd %d0, %d1, %d2, %d3\n;" : "=w"(ddst) : "w"(dx[i]), "w"(dy[i]), "w"(dz[i])); -+ printf("FNMADD 64bit: dst = -z + (-x) * y\n"); -+ printf("%f = -%f - %f * %f\n", ddst, dz[i], dx[i], dy[i]); -+ print_double("dst", ddst); -+ -+ asm("fmsub %d0, %d1, %d2, %d3\n;" : "=w"(ddst) : "w"(dx[i]), "w"(dy[i]), "w"(dz[i])); -+ printf("FMSUB 64bit: dst = z + (-x) * y\n"); -+ printf("%f = %f + (-%f) * %f\n", ddst, dz[i], dx[i], dy[i]); -+ print_double("dst", ddst); -+ -+ asm("fnmsub %d0, %d1, %d2, %d3\n;" : "=w"(ddst) : "w"(dx[i]), "w"(dy[i]), "w"(dz[i])); -+ printf("FNMSUB 64bit: dst = -z + x * y\n"); -+ printf("%f = -%f + %f * %f\n", ddst, dz[i], dx[i], dy[i]); -+ print_double("dst", ddst); -+ -+ printf("\n"); -+ } -+ -+ return 0; -+} -+ -diff --git a/none/tests/arm64/fmadd_sub.stderr.exp b/none/tests/arm64/fmadd_sub.stderr.exp -new file mode 100644 -index 000000000..e69de29bb -diff --git a/none/tests/arm64/fmadd_sub.stdout.exp b/none/tests/arm64/fmadd_sub.stdout.exp -new file mode 100644 -index 000000000..f1824b12b ---- /dev/null -+++ b/none/tests/arm64/fmadd_sub.stdout.exp -@@ -0,0 +1,125 @@ -+FMADD 32bit: dst = z + x * y -+76.246193 = 38.123096 + 55.000000 * 0.693147 -+dst = 42987e0d = 76.246192932128906 -+FNMADD 32bit: dst = -z + (-x) * y -+-76.246193 = -38.123096 + (-55.000000) * 0.693147 -+dst = c2987e0d = -76.246192932128906 -+FMSUB 32bit: dst = z + (-x) * y -+0.000001 = 38.123096 + (-55.000000) * 0.693147 -+dst = 35c00000 = 1.430511474609375e-06 -+FNMSUB 32bit: dst = -z + x * y -+-0.000001 = -38.123096 + 55.000000 * 0.693147 -+dst = b5c00000 = -1.430511474609375e-06 -+FMADD 64bit: dst = z + x * y -+76.246190 = 38.123095 + 55.000000 * 0.693147 -+dst = 40530fc1931f09c9 = 76.246189861593976 -+FNMADD 64bit: dst = -z + (-x) * y -+-76.246190 = -38.123095 - 55.000000 * 0.693147 -+dst = c0530fc1931f09c9 = -76.246189861593976 -+FMSUB 64bit: dst = z + (-x) * y -+-0.000000 = 38.123095 + (-55.000000) * 0.693147 -+dst = bce9000000000000 = -2.7755575615628914e-15 -+FNMSUB 64bit: dst = -z + x * y -+0.000000 = -38.123095 + 55.000000 * 0.693147 -+dst = 3ce9000000000000 = 2.7755575615628914e-15 -+ -+FMADD 32bit: dst = z + x * y -+1.996086 = 1.000000 + 0.980762 * 1.015625 -+dst = 3fff7fc0 = 1.9960861206054688 -+FNMADD 32bit: dst = -z + (-x) * y -+-1.996086 = -1.000000 + (-0.980762) * 1.015625 -+dst = bfff7fc0 = -1.9960861206054688 -+FMSUB 32bit: dst = z + (-x) * y -+0.003914 = 1.000000 + (-0.980762) * 1.015625 -+dst = 3b80401a = 0.00391389150172472 -+FNMSUB 32bit: dst = -z + x * y -+-0.003914 = -1.000000 + 0.980762 * 1.015625 -+dst = bb80401a = -0.00391389150172472 -+FMADD 64bit: dst = z + x * y -+1.996086 = 1.000000 + 0.980762 * 1.015625 -+dst = 3fffeff800000000 = 1.9960861206054688 -+FNMADD 64bit: dst = -z + (-x) * y -+-1.996086 = -1.000000 - 0.980762 * 1.015625 -+dst = bfffeff800000000 = -1.9960861206054688 -+FMSUB 64bit: dst = z + (-x) * y -+0.003914 = 1.000000 + (-0.980762) * 1.015625 -+dst = 3f70080000000034 = 0.0039138793945312951 -+FNMSUB 64bit: dst = -z + x * y -+-0.003914 = -1.000000 + 0.980762 * 1.015625 -+dst = bf70080000000034 = -0.0039138793945312951 -+ -+FMADD 32bit: dst = z + x * y -+0.000000 = 0.000000 + 0.000000 * 0.000000 -+dst = 00000000 = 0 -+FNMADD 32bit: dst = -z + (-x) * y -+-0.000000 = -0.000000 + (-0.000000) * 0.000000 -+dst = 80000000 = -0 -+FMSUB 32bit: dst = z + (-x) * y -+0.000000 = 0.000000 + (-0.000000) * 0.000000 -+dst = 00000000 = 0 -+FNMSUB 32bit: dst = -z + x * y -+0.000000 = -0.000000 + 0.000000 * 0.000000 -+dst = 00000000 = 0 -+FMADD 64bit: dst = z + x * y -+0.000000 = 0.000000 + 0.000000 * 0.000000 -+dst = 0000000000000000 = 0 -+FNMADD 64bit: dst = -z + (-x) * y -+-0.000000 = -0.000000 - 0.000000 * 0.000000 -+dst = 8000000000000000 = -0 -+FMSUB 64bit: dst = z + (-x) * y -+0.000000 = 0.000000 + (-0.000000) * 0.000000 -+dst = 0000000000000000 = 0 -+FNMSUB 64bit: dst = -z + x * y -+0.000000 = -0.000000 + 0.000000 * 0.000000 -+dst = 0000000000000000 = 0 -+ -+FMADD 32bit: dst = z + x * y -+2.000000 = 1.000000 + 1.000000 * 1.000000 -+dst = 40000000 = 2 -+FNMADD 32bit: dst = -z + (-x) * y -+-2.000000 = -1.000000 + (-1.000000) * 1.000000 -+dst = c0000000 = -2 -+FMSUB 32bit: dst = z + (-x) * y -+0.000000 = 1.000000 + (-1.000000) * 1.000000 -+dst = 00000000 = 0 -+FNMSUB 32bit: dst = -z + x * y -+0.000000 = -1.000000 + 1.000000 * 1.000000 -+dst = 00000000 = 0 -+FMADD 64bit: dst = z + x * y -+2.000000 = 1.000000 + 1.000000 * 1.000000 -+dst = 4000000000000000 = 2 -+FNMADD 64bit: dst = -z + (-x) * y -+-2.000000 = -1.000000 - 1.000000 * 1.000000 -+dst = c000000000000000 = -2 -+FMSUB 64bit: dst = z + (-x) * y -+0.000000 = 1.000000 + (-1.000000) * 1.000000 -+dst = 0000000000000000 = 0 -+FNMSUB 64bit: dst = -z + x * y -+0.000000 = -1.000000 + 1.000000 * 1.000000 -+dst = 0000000000000000 = 0 -+ -+FMADD 32bit: dst = z + x * y -+18446744073709551616.000000 = 4294967296.000000 + 4294967296.000000 * 4294967296.000000 -+dst = 5f800000 = 1.8446744073709552e+19 -+FNMADD 32bit: dst = -z + (-x) * y -+-18446744073709551616.000000 = -4294967296.000000 + (-4294967296.000000) * 4294967296.000000 -+dst = df800000 = -1.8446744073709552e+19 -+FMSUB 32bit: dst = z + (-x) * y -+-18446744073709551616.000000 = 4294967296.000000 + (-4294967296.000000) * 4294967296.000000 -+dst = df800000 = -1.8446744073709552e+19 -+FNMSUB 32bit: dst = -z + x * y -+18446744073709551616.000000 = -4294967296.000000 + 4294967296.000000 * 4294967296.000000 -+dst = 5f800000 = 1.8446744073709552e+19 -+FMADD 64bit: dst = z + x * y -+18446744069414584320.000000 = 4294967295.000000 + 4294967295.000000 * 4294967295.000000 -+dst = 43efffffffe00000 = 1.8446744069414584e+19 -+FNMADD 64bit: dst = -z + (-x) * y -+-18446744069414584320.000000 = -4294967295.000000 - 4294967295.000000 * 4294967295.000000 -+dst = c3efffffffe00000 = -1.8446744069414584e+19 -+FMSUB 64bit: dst = z + (-x) * y -+-18446744060824649728.000000 = 4294967295.000000 + (-4294967295.000000) * 4294967295.000000 -+dst = c3efffffffa00000 = -1.844674406082465e+19 -+FNMSUB 64bit: dst = -z + x * y -+18446744060824649728.000000 = -4294967295.000000 + 4294967295.000000 * 4294967295.000000 -+dst = 43efffffffa00000 = 1.844674406082465e+19 -+ -diff --git a/none/tests/arm64/fmadd_sub.vgtest b/none/tests/arm64/fmadd_sub.vgtest -new file mode 100644 -index 000000000..b4c53eea4 ---- /dev/null -+++ b/none/tests/arm64/fmadd_sub.vgtest -@@ -0,0 +1,3 @@ -+prog: fmadd_sub -+prereq: test -x fmadd_sub -+vgopts: -q --- -2.18.4 - -diff --git a/VEX/priv/guest_generic_bb_to_IR.c b/VEX/priv/guest_generic_bb_to_IR.c -index 0cee970e4..1e72ddacd 100644 ---- a/VEX/priv/guest_generic_bb_to_IR.c -+++ b/VEX/priv/guest_generic_bb_to_IR.c -@@ -422,6 +422,8 @@ static Bool expr_is_guardable ( const IRExpr* e ) - return !primopMightTrap(e->Iex.Binop.op); - case Iex_Triop: - return !primopMightTrap(e->Iex.Triop.details->op); -+ case Iex_Qop: -+ return !primopMightTrap(e->Iex.Qop.details->op); - case Iex_ITE: - case Iex_CCall: - case Iex_Get: diff --git a/valgrind-3.16.1-arm64_sp_lr_fp_DwReg.patch b/valgrind-3.16.1-arm64_sp_lr_fp_DwReg.patch deleted file mode 100644 index 14b45d4..0000000 --- a/valgrind-3.16.1-arm64_sp_lr_fp_DwReg.patch +++ /dev/null @@ -1,72 +0,0 @@ -diff --git a/coregrind/m_debuginfo/d3basics.c b/coregrind/m_debuginfo/d3basics.c -index e1127ffe2..1bc5f8f05 100644 ---- a/coregrind/m_debuginfo/d3basics.c -+++ b/coregrind/m_debuginfo/d3basics.c -@@ -523,6 +523,7 @@ static Bool get_Dwarf_Reg( /*OUT*/Addr* a, Word regno, const RegSummary* regs ) - if (regno == 30) { *a = regs->fp; return True; } - # elif defined(VGP_arm64_linux) - if (regno == 31) { *a = regs->sp; return True; } -+ if (regno == 29) { *a = regs->fp; return True; } - # else - # error "Unknown platform" - # endif -diff --git a/coregrind/m_debuginfo/debuginfo.c b/coregrind/m_debuginfo/debuginfo.c -index c4a5ea593..bc2578b37 100644 ---- a/coregrind/m_debuginfo/debuginfo.c -+++ b/coregrind/m_debuginfo/debuginfo.c -@@ -2874,7 +2874,9 @@ UWord evalCfiExpr ( const XArray* exprs, Int ix, - # elif defined(VGA_ppc32) || defined(VGA_ppc64be) \ - || defined(VGA_ppc64le) - # elif defined(VGP_arm64_linux) -+ case Creg_ARM64_SP: return eec->uregs->sp; - case Creg_ARM64_X30: return eec->uregs->x30; -+ case Creg_ARM64_X29: return eec->uregs->x29; - # else - # error "Unsupported arch" - # endif -diff --git a/coregrind/m_debuginfo/priv_storage.h b/coregrind/m_debuginfo/priv_storage.h -index 39456eccb..ae44ca34e 100644 ---- a/coregrind/m_debuginfo/priv_storage.h -+++ b/coregrind/m_debuginfo/priv_storage.h -@@ -415,7 +415,9 @@ typedef - Creg_ARM_R15, - Creg_ARM_R14, - Creg_ARM_R7, -+ Creg_ARM64_SP, - Creg_ARM64_X30, -+ Creg_ARM64_X29, - Creg_S390_IA, - Creg_S390_SP, - Creg_S390_FP, -diff --git a/coregrind/m_debuginfo/readdwarf.c b/coregrind/m_debuginfo/readdwarf.c -index 3996623ed..bcacca4cb 100644 ---- a/coregrind/m_debuginfo/readdwarf.c -+++ b/coregrind/m_debuginfo/readdwarf.c -@@ -2816,7 +2816,12 @@ static Int copy_convert_CfiExpr_tree ( XArray* dstxa, - if (dwreg == srcuc->ra_reg) - return ML_(CfiExpr_CfiReg)( dstxa, Creg_IA_IP ); - # elif defined(VGA_arm64) -- I_die_here; -+ if (dwreg == SP_REG) -+ return ML_(CfiExpr_CfiReg)( dstxa, Creg_ARM64_SP ); -+ if (dwreg == FP_REG) -+ return ML_(CfiExpr_CfiReg)( dstxa, Creg_ARM64_X29 ); -+ if (dwreg == srcuc->ra_reg) -+ return ML_(CfiExpr_CfiReg)( dstxa, Creg_ARM64_X30 ); - # elif defined(VGA_ppc32) || defined(VGA_ppc64be) \ - || defined(VGA_ppc64le) - # else -diff --git a/coregrind/m_debuginfo/storage.c b/coregrind/m_debuginfo/storage.c -index 8667d123f..48a92b402 100644 ---- a/coregrind/m_debuginfo/storage.c -+++ b/coregrind/m_debuginfo/storage.c -@@ -1002,7 +1002,9 @@ static void ppCfiReg ( CfiReg reg ) - case Creg_ARM_R15: VG_(printf)("R15"); break; - case Creg_ARM_R14: VG_(printf)("R14"); break; - case Creg_ARM_R7: VG_(printf)("R7"); break; -+ case Creg_ARM64_SP: VG_(printf)("SP"); break; - case Creg_ARM64_X30: VG_(printf)("X30"); break; -+ case Creg_ARM64_X29: VG_(printf)("X29"); break; - case Creg_MIPS_RA: VG_(printf)("RA"); break; - case Creg_S390_IA: VG_(printf)("IA"); break; - case Creg_S390_SP: VG_(printf)("SP"); break; diff --git a/valgrind-3.16.1-dl_runtime_resolve.patch b/valgrind-3.16.1-dl_runtime_resolve.patch deleted file mode 100644 index 0a34759..0000000 --- a/valgrind-3.16.1-dl_runtime_resolve.patch +++ /dev/null @@ -1,206 +0,0 @@ -commit f4abcc05fdba3f25890a9b30b71d511ccc906d46 -Author: Mark Wielaard -Date: Mon Jul 27 22:43:28 2020 +0200 - - Incorrect call-graph tracking due to new _dl_runtime_resolve_xsave* - - Newer glibc have alternate ld.so _ld_runtime_resolve functions. - Namely _dl_runtime_resolve_xsave and _dl_runtime_resolve_xsave'2 - - This patch recognizes the xsave, xsvec and fxsave variants and - changes callgrind so that any variant counts as _dl_runtime_resolve. - - Original patch by paulo.cesar.pereira.de.andrade@gmail.com - https://bugs.kde.org/show_bug.cgi?id=415293 - -diff --git a/callgrind/fn.c b/callgrind/fn.c -index e9d8dd214..7cce1a0c7 100644 ---- a/callgrind/fn.c -+++ b/callgrind/fn.c -@@ -30,8 +30,11 @@ - - static fn_array current_fn_active; - --static Addr runtime_resolve_addr = 0; --static int runtime_resolve_length = 0; -+/* x86_64 defines 4 variants. */ -+#define MAX_RESOLVE_ADDRS 4 -+static int runtime_resolve_addrs = 0; -+static Addr runtime_resolve_addr[MAX_RESOLVE_ADDRS]; -+static int runtime_resolve_length[MAX_RESOLVE_ADDRS]; - - // a code pattern is a list of tuples (start offset, length) - struct chunk_t { int start, len; }; -@@ -56,6 +59,9 @@ static Bool check_code(obj_node* obj, - /* first chunk of pattern should always start at offset 0 and - * have at least 3 bytes */ - CLG_ASSERT((pat->chunk[0].start == 0) && (pat->chunk[0].len >2)); -+ -+ /* and we cannot be called more than MAX_RESOLVE_ADDRS times */ -+ CLG_ASSERT(runtime_resolve_addrs < MAX_RESOLVE_ADDRS); - - CLG_DEBUG(1, "check_code: %s, pattern %s, check %d bytes of [%x %x %x...]\n", - obj->name, pat->name, pat->chunk[0].len, code[0], code[1], code[2]); -@@ -93,8 +99,9 @@ static Bool check_code(obj_node* obj, - pat->name, obj->name + obj->last_slash_pos, - addr - obj->start, addr, pat->len); - -- runtime_resolve_addr = addr; -- runtime_resolve_length = pat->len; -+ runtime_resolve_addr[runtime_resolve_addrs] = addr; -+ runtime_resolve_length[runtime_resolve_addrs] = pat->len; -+ runtime_resolve_addrs++; - return True; - } - } -@@ -138,8 +145,9 @@ static Bool search_runtime_resolve(obj_node* obj) - "x86-glibc2.8", 30, {{ 0,12 }, { 16,14 }, { 30,0}} }; - - if (VG_(strncmp)(obj->name, "/lib/ld", 7) != 0) return False; -- if (check_code(obj, code, &pat)) return True; -- if (check_code(obj, code_28, &pat_28)) return True; -+ Bool pat_p = check_code(obj, code, &pat); -+ Bool pat_28_p = check_code(obj, code_28, &pat_28); -+ if (pat_p || pat_28_p) return True; - return False; - #endif - -@@ -186,9 +194,98 @@ static Bool search_runtime_resolve(obj_node* obj) - static struct pattern pat = { - "amd64-def", 110, {{ 0,62 }, { 66,44 }, { 110,0 }} }; - -+ static UChar code_xsavec[] = { -+ /* 0*/ 0x53, 0x48, 0x89, 0xe3, 0x48, 0x83, 0xe4, 0xc0, -+ /* 8*/ 0x48, 0x2b, 0x25, 0x00, 0x00, 0x00, 0x00, /* sub (%rip),%rsp */ -+ /*15*/ 0x48, -+ /*16*/ 0x89, 0x04, 0x24, 0x48, 0x89, 0x4c, 0x24, 0x08, -+ /*24*/ 0x48, 0x89, 0x54, 0x24, 0x10, 0x48, 0x89, 0x74, -+ /*32*/ 0x24, 0x18, 0x48, 0x89, 0x7c, 0x24, 0x20, 0x4c, -+ /*40*/ 0x89, 0x44, 0x24, 0x28, 0x4c, 0x89, 0x4c, 0x24, -+ /*48*/ 0x30, 0xb8, 0xee, 0x00, 0x00, 0x00, 0x31, 0xd2, -+ /*56*/ 0x48, 0x89, 0x94, 0x24, 0x50, 0x02, 0x00, 0x00, -+ /*64*/ 0x48, 0x89, 0x94, 0x24, 0x58, 0x02, 0x00, 0x00, -+ /*72*/ 0x48, 0x89, 0x94, 0x24, 0x60, 0x02, 0x00, 0x00, -+ /*80*/ 0x48, 0x89, 0x94, 0x24, 0x68, 0x02, 0x00, 0x00, -+ /*88*/ 0x48, 0x89, 0x94, 0x24, 0x70, 0x02, 0x00, 0x00, -+ /*96*/ 0x48, 0x89, 0x94, 0x24, 0x78, 0x02, 0x00, 0x00, -+ /*04*/ 0x0f, 0xc7, 0x64, 0x24, 0x40, 0x48, 0x8b, 0x73, -+ /*112*/0x10, 0x48, 0x8b, 0x7b, 0x08, -+ /*117*/0xe8, 0x00, 0x00, 0x00, 0x00, /* callq <_dl_fixup> */ -+ /*122*/0x49, 0x89, 0xc3, 0xb8, 0xee, 0x00, -+ /*128*/0x00, 0x00, 0x31, 0xd2, 0x0f, 0xae, 0x6c, 0x24, -+ /*136*/0x40, 0x4c, 0x8b, 0x4c, 0x24, 0x30, 0x4c, 0x8b, -+ /*144*/0x44, 0x24, 0x28, 0x48, 0x8b, 0x7c, 0x24, 0x20, -+ /*152*/0x48, 0x8b, 0x74, 0x24, 0x18, 0x48, 0x8b, 0x54, -+ /*160*/0x24, 0x10, 0x48, 0x8b, 0x4c, 0x24, 0x08, 0x48, -+ /*168*/0x8b, 0x04, 0x24, 0x48, 0x89, 0xdc, 0x48, 0x8b, -+ /*176*/0x1c, 0x24, 0x48, 0x83, 0xc4, 0x18, 0xf2, 0x41, -+ /*184*/0xff, 0xe3 }; -+ static struct pattern pat_xsavec = { -+ "amd64-xsavec", 186, {{ 0,11 }, { 15,103 }, {122,64}, { 186,0 }} }; -+ -+ static UChar code_xsave[] = { -+ /* 0*/ 0x53, 0x48, 0x89, 0xe3, 0x48, 0x83, 0xe4, 0xc0, -+ /* 8*/ 0x48, 0x2b, 0x25, 0x00, 0x00, 0x00, 0x00, /* sub (%rip),%rsp */ -+ /*15*/ 0x48, -+ /*16*/ 0x89, 0x04, 0x24, 0x48, 0x89, 0x4c, 0x24, 0x08, -+ /*24*/ 0x48, 0x89, 0x54, 0x24, 0x10, 0x48, 0x89, 0x74, -+ /*32*/ 0x24, 0x18, 0x48, 0x89, 0x7c, 0x24, 0x20, 0x4c, -+ /*40*/ 0x89, 0x44, 0x24, 0x28, 0x4c, 0x89, 0x4c, 0x24, -+ /*48*/ 0x30, 0xb8, 0xee, 0x00, 0x00, 0x00, 0x31, 0xd2, -+ /*56*/ 0x48, 0x89, 0x94, 0x24, 0x40, 0x02, 0x00, 0x00, -+ /*64*/ 0x48, 0x89, 0x94, 0x24, 0x48, 0x02, 0x00, 0x00, -+ /*72*/ 0x48, 0x89, 0x94, 0x24, 0x50, 0x02, 0x00, 0x00, -+ /*80*/ 0x48, 0x89, 0x94, 0x24, 0x58, 0x02, 0x00, 0x00, -+ /*88*/ 0x48, 0x89, 0x94, 0x24, 0x60, 0x02, 0x00, 0x00, -+ /*96*/ 0x48, 0x89, 0x94, 0x24, 0x68, 0x02, 0x00, 0x00, -+ /*104*/0x48, 0x89, 0x94, 0x24, 0x70, 0x02, 0x00, 0x00, -+ /*112*/0x48, 0x89, 0x94, 0x24, 0x78, 0x02, 0x00, 0x00, -+ /*120*/0x0f, 0xae, 0x64, 0x24, 0x40, 0x48, 0x8b, 0x73, -+ /*128*/0x10, 0x48, 0x8b, 0x7b, 0x08, -+ /*133*/0xe8, 0x00, 0x00, 0x00, 0x00, /* callq <_dl_fixup> */ -+ /*138*/0x49, 0x89, 0xc3, 0xb8, 0xee, 0x00, -+ /*144*/0x00, 0x00, 0x31, 0xd2, 0x0f, 0xae, 0x6c, 0x24, -+ /*152*/0x40, 0x4c, 0x8b, 0x4c, 0x24, 0x30, 0x4c, 0x8b, -+ /*160*/0x44, 0x24, 0x28, 0x48, 0x8b, 0x7c, 0x24, 0x20, -+ /*168*/0x48, 0x8b, 0x74, 0x24, 0x18, 0x48, 0x8b, 0x54, -+ /*176*/0x24, 0x10, 0x48, 0x8b, 0x4c, 0x24, 0x08, 0x48, -+ /*184*/0x8b, 0x04, 0x24, 0x48, 0x89, 0xdc, 0x48, 0x8b, -+ /*192*/0x1c, 0x24, 0x48, 0x83, 0xc4, 0x18, 0xf2, 0x41, -+ /*200*/0xff, 0xe3 }; -+ static struct pattern pat_xsave = { -+ "amd64-xsave", 202, {{ 0,11 }, { 15,119 }, {138,64}, { 202,0 }} }; -+ -+ static UChar code_fxsave[] = { -+ /* 0*/ 0x53, 0x48, 0x89, 0xe3, 0x48, 0x83, 0xe4, 0xf0, -+ /* 8*/ 0x48, 0x81, 0xec, 0x40, 0x02, 0x00, 0x00, 0x48, -+ /*16*/ 0x89, 0x04, 0x24, 0x48, 0x89, 0x4c, 0x24, 0x08, -+ /*24*/ 0x48, 0x89, 0x54, 0x24, 0x10, 0x48, 0x89, 0x74, -+ /*32*/ 0x24, 0x18, 0x48, 0x89, 0x7c, 0x24, 0x20, 0x4c, -+ /*40*/ 0x89, 0x44, 0x24, 0x28, 0x4c, 0x89, 0x4c, 0x24, -+ /*48*/ 0x30, 0x0f, 0xae, 0x44, 0x24, 0x40, 0x48, 0x8b, -+ /*56*/ 0x73, 0x10, 0x48, 0x8b, 0x7b, 0x08, -+ /*62*/ 0xe8, 0x00, 0x00, 0x00, 0x00, /* callq <_dl_fixup> */ -+ /*67*/ 0x49, 0x89, 0xc3, 0x0f, 0xae, -+ /*72*/ 0x4c, 0x24, 0x40, 0x4c, 0x8b, 0x4c, 0x24, 0x30, -+ /*80*/ 0x4c, 0x8b, 0x44, 0x24, 0x28, 0x48, 0x8b, 0x7c, -+ /*88*/ 0x24, 0x20, 0x48, 0x8b, 0x74, 0x24, 0x18, 0x48, -+ /*96*/ 0x8b, 0x54, 0x24, 0x10, 0x48, 0x8b, 0x4c, 0x24, -+ /*104*/0x08, 0x48, 0x8b, 0x04, 0x24, 0x48, 0x89, 0xdc, -+ /*112*/0x48, 0x8b, 0x1c, 0x24, 0x48, 0x83, 0xc4, 0x18, -+ /*120*/0xf2, 0x41, 0xff, 0xe3 }; -+ static struct pattern pat_fxsave = { -+ "amd64-fxsave", 124, {{ 0,63 }, { 67,57 }, { 124,0 }} }; -+ - if ((VG_(strncmp)(obj->name, "/lib/ld", 7) != 0) && -- (VG_(strncmp)(obj->name, "/lib64/ld", 9) != 0)) return False; -- return check_code(obj, code, &pat); -+ (VG_(strncmp)(obj->name, "/lib64/ld", 9) != 0) && -+ (VG_(strncmp)(obj->name, "/usr/lib/ld", 11) != 0) && -+ (VG_(strncmp)(obj->name, "/usr/lib64/ld", 13) != 0)) return False; -+ Bool pat_p = check_code(obj, code, &pat); -+ Bool pat_xsavec_p = check_code(obj, code_xsavec, &pat_xsavec); -+ Bool pat_xsave_p = check_code(obj, code_xsave, &pat_xsave); -+ Bool pat_fxsave_p = check_code(obj, code_fxsave, &pat_fxsave); -+ if (pat_p || pat_xsavec_p || pat_xsave_p || pat_fxsave_p) return True; - #endif - - /* For other platforms, no patterns known */ -@@ -254,7 +351,7 @@ obj_node* new_obj_node(DebugInfo* di, obj_node* next) - i++; - } - -- if (runtime_resolve_addr == 0) search_runtime_resolve(obj); -+ if (runtime_resolve_addrs == 0) search_runtime_resolve(obj); - - return obj; - } -@@ -490,6 +587,7 @@ fn_node* CLG_(get_fn_node)(BB* bb) - DebugInfo* di; - UInt line_num; - fn_node* fn; -+ Int i; - - /* fn from debug info is idempotent for a BB */ - if (bb->fn) return bb->fn; -@@ -538,12 +636,14 @@ fn_node* CLG_(get_fn_node)(BB* bb) - } - if (0 == VG_(strcmp)(fnname, "_exit") && !exit_bb) - exit_bb = bb; -- -- if (runtime_resolve_addr && -- (bb_addr(bb) >= runtime_resolve_addr) && -- (bb_addr(bb) < runtime_resolve_addr + runtime_resolve_length)) { -- /* BB in runtime_resolve found by code check; use this name */ -- fnname = "_dl_runtime_resolve"; -+ -+ for (i = 0; i < runtime_resolve_addrs; i++) { -+ if ((bb_addr(bb) >= runtime_resolve_addr[i]) && -+ (bb_addr(bb) < runtime_resolve_addr[i] + runtime_resolve_length[i])) { -+ /* BB in runtime_resolve found by code check; use this name */ -+ fnname = "_dl_runtime_resolve"; -+ break; -+ } - } - - /* get fn_node struct for this function */ diff --git a/valgrind-3.16.1-dwarf5.patch b/valgrind-3.16.1-dwarf5.patch deleted file mode 100644 index 24388cb..0000000 --- a/valgrind-3.16.1-dwarf5.patch +++ /dev/null @@ -1,2410 +0,0 @@ -From 256a67e6a5a07e37997d3a5ef64204a99b8e5a50 Mon Sep 17 00:00:00 2001 -From: Mark Wielaard -Date: Mon, 25 Jan 2021 15:33:34 +0100 -Subject: [PATCH] DWARF5 - ---- - coregrind/m_debuginfo/d3basics.c | 99 ++++ - coregrind/m_debuginfo/priv_d3basics.h | 195 +++++- - coregrind/m_debuginfo/priv_readdwarf.h | 3 +- - coregrind/m_debuginfo/priv_readdwarf3.h | 3 +- - coregrind/m_debuginfo/readdwarf.c | 465 ++++++++++++--- - coregrind/m_debuginfo/readdwarf3.c | 748 +++++++++++++++++++----- - coregrind/m_debuginfo/readelf.c | 33 +- - coregrind/m_debuginfo/readmacho.c | 14 +- - 8 files changed, 1304 insertions(+), 256 deletions(-) - -diff --git a/coregrind/m_debuginfo/d3basics.c b/coregrind/m_debuginfo/d3basics.c -index b6d13c118..e1127ffe2 100644 ---- a/coregrind/m_debuginfo/d3basics.c -+++ b/coregrind/m_debuginfo/d3basics.c -@@ -128,6 +128,16 @@ const HChar* ML_(pp_DW_TAG) ( DW_TAG tag ) - case DW_TAG_type_unit: return "DW_TAG_type_unit"; - case DW_TAG_rvalue_reference_type: return "DW_TAG_rvalue_reference_type"; - case DW_TAG_template_alias: return "DW_TAG_template_alias"; -+ /* DWARF 5. */ -+ case DW_TAG_coarray_type: return "DW_TAG_coarray_type"; -+ case DW_TAG_generic_subrange: return "DW_TAG_generic_subrange"; -+ case DW_TAG_dynamic_type: return "DW_TAG_dynamic_type"; -+ case DW_TAG_atomic_type: return "DW_TAG_atomic_type"; -+ case DW_TAG_call_site: return "DW_TAG_call_site"; -+ case DW_TAG_call_site_parameter: -+ return "DW_TAG_call_site_parameter"; -+ case DW_TAG_skeleton_unit: return "DW_TAG_skeleton_unit"; -+ case DW_TAG_immutable_type: return "DW_TAG_immutable_type"; - /* SGI/MIPS Extensions. */ - case DW_TAG_MIPS_loop: return "DW_TAG_MIPS_loop"; - /* HP extensions. See: -@@ -140,6 +150,16 @@ const HChar* ML_(pp_DW_TAG) ( DW_TAG tag ) - case DW_TAG_class_template: return "DW_TAG_class_template"; - case DW_TAG_GNU_BINCL: return "DW_TAG_GNU_BINCL"; - case DW_TAG_GNU_EINCL: return "DW_TAG_GNU_EINCL"; -+ case DW_TAG_GNU_template_template_param: -+ return "DW_TAG_GNU_template_template_param"; -+ case DW_TAG_GNU_template_parameter_pack: -+ return"DW_TAG_GNU_template_parameter_pack"; -+ case DW_TAG_GNU_formal_parameter_pack: -+ return "DW_TAG_GNU_formal_parameter_pack"; -+ case DW_TAG_GNU_call_site: -+ return "DW_TAG_GNU_call_site"; -+ case DW_TAG_GNU_call_site_parameter: -+ return "DW_TAG_GNU_call_site_parameter"; - /* Extensions for UPC. See: http://upc.gwu.edu/~upc. */ - case DW_TAG_upc_shared_type: return "DW_TAG_upc_shared_type"; - case DW_TAG_upc_strict_type: return "DW_TAG_upc_strict_type"; -@@ -180,6 +200,27 @@ const HChar* ML_(pp_DW_FORM) ( DW_FORM form ) - case DW_FORM_exprloc: return "DW_FORM_exprloc"; - case DW_FORM_flag_present:return "DW_FORM_flag_present"; - case DW_FORM_ref_sig8: return "DW_FORM_ref_sig8"; -+ case DW_FORM_strx: return "DW_FORM_strx"; -+ case DW_FORM_addrx: return "DW_FORM_addrx"; -+ case DW_FORM_ref_sup4: return "DW_FORM_ref_sup4"; -+ case DW_FORM_strp_sup: return "DW_FORM_strp_sup"; -+ case DW_FORM_data16: return "DW_FORM_data16"; -+ case DW_FORM_line_strp: return "DW_FORM_line_strp"; -+ case DW_FORM_implicit_const:return "DW_FORM_implicit_const"; -+ case DW_FORM_loclistx: return "DW_FORM_loclistx"; -+ case DW_FORM_rnglistx: return "DW_FORM_rnglistx"; -+ case DW_FORM_ref_sup8: return "DW_FORM_ref_sup8"; -+ case DW_FORM_strx1: return "DW_FORM_strx1"; -+ case DW_FORM_strx2: return "DW_FORM_strx2"; -+ case DW_FORM_strx3: return "DW_FORM_strx3"; -+ case DW_FORM_strx4: return "DW_FORM_strx4"; -+ case DW_FORM_addrx1: return "DW_FORM_addrx1"; -+ case DW_FORM_addrx2: return "DW_FORM_addrx2"; -+ case DW_FORM_addrx3: return "DW_FORM_addrx3"; -+ case DW_FORM_addrx4: return "DW_FORM_addrx4"; -+ /* GNU Debug Fission extensions. */ -+ case DW_FORM_GNU_addr_index:return "DW_FORM_GNU_addr_index"; -+ case DW_FORM_GNU_str_index:return "DW_FORM_GNU_str_index"; - case DW_FORM_GNU_ref_alt:return "DW_FORM_GNU_ref_alt"; - case DW_FORM_GNU_strp_alt:return "DW_FORM_GNU_strp_alt"; - } -@@ -286,6 +327,36 @@ const HChar* ML_(pp_DW_AT) ( DW_AT attr ) - case DW_AT_const_expr: return "DW_AT_const_expr"; - case DW_AT_enum_class: return "DW_AT_enum_class"; - case DW_AT_linkage_name: return "DW_AT_linkage_name"; -+ /* DWARF 5 values. */ -+ case DW_AT_string_length_bit_size: return "DW_AT_string_length_bit_size"; -+ case DW_AT_string_length_byte_size: return "DW_AT_string_length_byte_size"; -+ case DW_AT_rank: return "DW_AT_rank"; -+ case DW_AT_str_offsets_base: return "DW_AT_str_offsets_base"; -+ case DW_AT_addr_base: return "DW_AT_addr_base"; -+ case DW_AT_rnglists_base: return "DW_AT_rnglists_base"; -+ case DW_AT_dwo_name: return "DW_AT_dwo_name"; -+ case DW_AT_reference: return "DW_AT_reference"; -+ case DW_AT_rvalue_reference: return "DW_AT_rvalue_reference"; -+ case DW_AT_macros: return "DW_AT_macros"; -+ case DW_AT_call_all_calls: return "DW_AT_call_all_calls"; -+ case DW_AT_call_all_source_calls: return "DW_AT_call_all_source_calls"; -+ case DW_AT_call_all_tail_calls: return "DW_AT_call_all_tail_calls"; -+ case DW_AT_call_return_pc: return "DW_AT_call_return_pc"; -+ case DW_AT_call_value: return "DW_AT_call_value"; -+ case DW_AT_call_origin: return "DW_AT_call_origin"; -+ case DW_AT_call_parameter: return "DW_AT_call_parameter"; -+ case DW_AT_call_pc: return "DW_AT_call_pc"; -+ case DW_AT_call_tail_call: return "DW_AT_call_tail_call"; -+ case DW_AT_call_target: return "DW_AT_call_target"; -+ case DW_AT_call_target_clobbered: return "DW_AT_call_target_clobbered"; -+ case DW_AT_call_data_location: return "DW_AT_call_data_location"; -+ case DW_AT_call_data_value: return "DW_AT_call_data_value"; -+ case DW_AT_noreturn: return "DW_AT_noreturn"; -+ case DW_AT_alignment: return "DW_AT_alignment"; -+ case DW_AT_export_symbols: return "DW_AT_export_symbols"; -+ case DW_AT_deleted: return "DW_AT_deleted"; -+ case DW_AT_defaulted: return "DW_AT_defaulted"; -+ case DW_AT_loclists_base: return "DW_AT_loclists_base"; - /* SGI/MIPS extensions. */ - /* case DW_AT_MIPS_fde: return "DW_AT_MIPS_fde"; */ - /* DW_AT_MIPS_fde == DW_AT_HP_unmodifiable */ -@@ -322,8 +393,36 @@ const HChar* ML_(pp_DW_AT) ( DW_AT attr ) - case DW_AT_body_begin: return "DW_AT_body_begin"; - case DW_AT_body_end: return "DW_AT_body_end"; - case DW_AT_GNU_vector: return "DW_AT_GNU_vector"; -+ case DW_AT_GNU_guarded_by: return "DW_AT_GNU_guarded_by"; -+ case DW_AT_GNU_pt_guarded_by: return "DW_AT_GNU_pt_guarded_by"; -+ case DW_AT_GNU_guarded: return "DW_AT_GNU_guarded"; -+ case DW_AT_GNU_pt_guarded: return "DW_AT_GNU_pt_guarded"; -+ case DW_AT_GNU_locks_excluded: return "DW_AT_GNU_locks_excluded"; -+ case DW_AT_GNU_exclusive_locks_required: return "DW_AT_GNU_exclusive_locks_required"; -+ case DW_AT_GNU_shared_locks_required: return "DW_AT_GNU_shared_locks_required"; -+ case DW_AT_GNU_odr_signature: return "DW_AT_GNU_odr_signature"; -+ case DW_AT_GNU_template_name: return "DW_AT_GNU_template_name"; -+ case DW_AT_GNU_call_site_value: return "DW_AT_GNU_call_site_value"; -+ case DW_AT_GNU_call_site_data_value: return "DW_AT_GNU_call_site_data_value"; -+ case DW_AT_GNU_call_site_target: return "DW_AT_GNU_call_site_target"; -+ case DW_AT_GNU_call_site_target_clobbered: return "DW_AT_GNU_call_site_target_clobbered"; -+ case DW_AT_GNU_tail_call: return "DW_AT_GNU_tail_call"; - case DW_AT_GNU_all_tail_call_sites: return "DW_AT_GNU_all_tail_call_sites"; - case DW_AT_GNU_all_call_sites: return "DW_AT_GNU_all_call_sites"; -+ case DW_AT_GNU_all_source_call_sites: return "DW_AT_GNU_all_source_call_sites"; -+ case DW_AT_GNU_locviews: return "DW_AT_GNU_locviews"; -+ case DW_AT_GNU_entry_view: return "DW_AT_GNU_entry_view"; -+ case DW_AT_GNU_macros: return "DW_AT_GNU_macros"; -+ case DW_AT_GNU_deleted: return "DW_AT_GNU_deleted"; -+ case DW_AT_GNU_dwo_name: return "DW_AT_GNU_dwo_name"; -+ case DW_AT_GNU_dwo_id: return "DW_AT_GNU_dwo_id"; -+ case DW_AT_GNU_ranges_base: return "DW_AT_GNU_ranges_base"; -+ case DW_AT_GNU_addr_base: return "DW_AT_GNU_addr_base"; -+ case DW_AT_GNU_pubnames: return "DW_AT_GNU_pubnames"; -+ case DW_AT_GNU_pubtypes: return "DW_AT_GNU_pubtypes"; -+ case DW_AT_GNU_numerator: return "DW_AT_GNU_numerator"; -+ case DW_AT_GNU_denominator: return "DW_AT_GNU_denominator"; -+ case DW_AT_GNU_bias: return "DW_AT_GNU_bias"; - /* VMS extensions. */ - case DW_AT_VMS_rtnbeg_pd_address: return "DW_AT_VMS_rtnbeg_pd_address"; - /* UPC extension. */ -diff --git a/coregrind/m_debuginfo/priv_d3basics.h b/coregrind/m_debuginfo/priv_d3basics.h -index b60e3e8eb..9d825e39e 100644 ---- a/coregrind/m_debuginfo/priv_d3basics.h -+++ b/coregrind/m_debuginfo/priv_d3basics.h -@@ -108,6 +108,15 @@ typedef enum - DW_TAG_type_unit = 0x41, - DW_TAG_rvalue_reference_type = 0x42, - DW_TAG_template_alias = 0x43, -+ /* DWARF 5. */ -+ DW_TAG_coarray_type = 0x44, -+ DW_TAG_generic_subrange = 0x45, -+ DW_TAG_dynamic_type = 0x46, -+ DW_TAG_atomic_type = 0x47, -+ DW_TAG_call_site = 0x48, -+ DW_TAG_call_site_parameter = 0x49, -+ DW_TAG_skeleton_unit = 0x4a, -+ DW_TAG_immutable_type = 0x4b, - /* SGI/MIPS Extensions. */ - DW_TAG_MIPS_loop = 0x4081, - /* HP extensions. See: ftp://ftp.hp.com/pub/lang/tools/WDB/wdb-4.0.tar.gz . */ -@@ -118,6 +127,11 @@ typedef enum - DW_TAG_class_template = 0x4103, /* For C++. */ - DW_TAG_GNU_BINCL = 0x4104, - DW_TAG_GNU_EINCL = 0x4105, -+ DW_TAG_GNU_template_template_param = 0x4106, -+ DW_TAG_GNU_template_parameter_pack = 0x4107, -+ DW_TAG_GNU_formal_parameter_pack = 0x4108, -+ DW_TAG_GNU_call_site = 0x4109, -+ DW_TAG_GNU_call_site_parameter = 0x410a, - /* Extensions for UPC. See: http://upc.gwu.edu/~upc. */ - DW_TAG_upc_shared_type = 0x8765, - DW_TAG_upc_strict_type = 0x8766, -@@ -164,13 +178,23 @@ typedef enum dwarf_source_language - DW_LANG_D = 0x0013, - /* DWARF 4. */ - DW_LANG_Python = 0x0014, -- /* DWARF 5-pre. Only what GCC already outputs. */ -+ /* DWARF 5. */ - DW_LANG_Go = 0x0016, -+ DW_LANG_Modula3 = 0x0017, -+ DW_LANG_Haskell = 0x0018, -+ DW_LANG_C_plus_plus_03 = 0x0019, - DW_LANG_C_plus_plus_11 = 0x001a, -+ DW_LANG_OCaml = 0x001b, -+ DW_LANG_Rust = 0x001c, - DW_LANG_C11 = 0x001d, -+ DW_LANG_Swift = 0x001e, -+ DW_LANG_Julia = 0x001f, -+ DW_LANG_Dylan = 0x0020, - DW_LANG_C_plus_plus_14 = 0x0021, - DW_LANG_Fortran03 = 0x0022, - DW_LANG_Fortran08 = 0x0023, -+ DW_LANG_RenderScript = 0x0024, -+ DW_LANG_BLISS = 0x0025, - /* MIPS. */ - DW_LANG_Mips_Assembler = 0x8001, - /* UPC. */ -@@ -207,6 +231,28 @@ typedef enum - DW_FORM_exprloc = 0x18, - DW_FORM_flag_present = 0x19, - DW_FORM_ref_sig8 = 0x20, -+ /* DWARF 5 values. */ -+ DW_FORM_strx = 0x1a, -+ DW_FORM_addrx = 0x1b, -+ DW_FORM_ref_sup4 = 0x1c, -+ DW_FORM_strp_sup = 0x1d, -+ DW_FORM_data16 = 0x1e, -+ DW_FORM_line_strp = 0x1f, -+ DW_FORM_implicit_const = 0x21, -+ DW_FORM_loclistx = 0x22, -+ DW_FORM_rnglistx = 0x23, -+ DW_FORM_ref_sup8 = 0x24, -+ DW_FORM_strx1 = 0x25, -+ DW_FORM_strx2 = 0x26, -+ DW_FORM_strx3 = 0x27, -+ DW_FORM_strx4 = 0x28, -+ DW_FORM_addrx1 = 0x29, -+ DW_FORM_addrx2 = 0x2a, -+ DW_FORM_addrx3 = 0x2b, -+ DW_FORM_addrx4 = 0x2c, -+ /* GNU Debug Fission extensions. */ -+ DW_FORM_GNU_addr_index = 0x1f01, -+ DW_FORM_GNU_str_index = 0x1f02, - /* Extensions for DWZ multifile. - See http://www.dwarfstd.org/ShowIssue.php?issue=120604.1&type=open . */ - DW_FORM_GNU_ref_alt = 0x1f20, -@@ -314,6 +360,36 @@ typedef enum - DW_AT_const_expr = 0x6c, - DW_AT_enum_class = 0x6d, - DW_AT_linkage_name = 0x6e, -+ DW_AT_string_length_bit_size = 0x6f, -+ DW_AT_string_length_byte_size = 0x70, -+ DW_AT_rank = 0x71, -+ DW_AT_str_offsets_base = 0x72, -+ DW_AT_addr_base = 0x73, -+ DW_AT_rnglists_base = 0x74, -+ /* 0x75 reserved. */ -+ DW_AT_dwo_name = 0x76, -+ DW_AT_reference = 0x77, -+ DW_AT_rvalue_reference = 0x78, -+ DW_AT_macros = 0x79, -+ DW_AT_call_all_calls = 0x7a, -+ DW_AT_call_all_source_calls = 0x7b, -+ DW_AT_call_all_tail_calls = 0x7c, -+ DW_AT_call_return_pc = 0x7d, -+ DW_AT_call_value = 0x7e, -+ DW_AT_call_origin = 0x7f, -+ DW_AT_call_parameter = 0x80, -+ DW_AT_call_pc = 0x81, -+ DW_AT_call_tail_call = 0x82, -+ DW_AT_call_target = 0x83, -+ DW_AT_call_target_clobbered = 0x84, -+ DW_AT_call_data_location = 0x85, -+ DW_AT_call_data_value = 0x86, -+ DW_AT_noreturn = 0x87, -+ DW_AT_alignment = 0x88, -+ DW_AT_export_symbols = 0x89, -+ DW_AT_deleted = 0x8a, -+ DW_AT_defaulted = 0x8b, -+ DW_AT_loclists_base = 0x8c, - /* SGI/MIPS extensions. */ - DW_AT_MIPS_fde = 0x2001, - DW_AT_MIPS_loop_begin = 0x2002, -@@ -349,8 +425,39 @@ typedef enum - DW_AT_body_begin = 0x2105, - DW_AT_body_end = 0x2106, - DW_AT_GNU_vector = 0x2107, -+ DW_AT_GNU_guarded_by = 0x2108, -+ DW_AT_GNU_pt_guarded_by = 0x2109, -+ DW_AT_GNU_guarded = 0x210a, -+ DW_AT_GNU_pt_guarded = 0x210b, -+ DW_AT_GNU_locks_excluded = 0x210c, -+ DW_AT_GNU_exclusive_locks_required = 0x210d, -+ DW_AT_GNU_shared_locks_required = 0x210e, -+ DW_AT_GNU_odr_signature = 0x210f, -+ DW_AT_GNU_template_name = 0x2110, -+ DW_AT_GNU_call_site_value = 0x2111, -+ DW_AT_GNU_call_site_data_value = 0x2112, -+ DW_AT_GNU_call_site_target = 0x2113, -+ DW_AT_GNU_call_site_target_clobbered = 0x2114, -+ DW_AT_GNU_tail_call = 0x2115, - DW_AT_GNU_all_tail_call_sites = 0x2116, - DW_AT_GNU_all_call_sites = 0x2117, -+ DW_AT_GNU_all_source_call_sites = 0x2118, -+ DW_AT_GNU_locviews = 0x2137, -+ DW_AT_GNU_entry_view = 0x2138, -+ DW_AT_GNU_macros = 0x2119, -+ DW_AT_GNU_deleted = 0x211a, -+ /* GNU Debug Fission extensions. */ -+ DW_AT_GNU_dwo_name = 0x2130, -+ DW_AT_GNU_dwo_id = 0x2131, -+ DW_AT_GNU_ranges_base = 0x2132, -+ DW_AT_GNU_addr_base = 0x2133, -+ DW_AT_GNU_pubnames = 0x2134, -+ DW_AT_GNU_pubtypes = 0x2135, -+ /* https://gcc.gnu.org/wiki/DW_AT_GNU_numerator_denominator */ -+ DW_AT_GNU_numerator = 0x2303, -+ DW_AT_GNU_denominator = 0x2304, -+ /* https://gcc.gnu.org/wiki/DW_AT_GNU_bias */ -+ DW_AT_GNU_bias = 0x2305, - /* VMS extensions. */ - DW_AT_VMS_rtnbeg_pd_address = 0x2201, - /* UPC extension. */ -@@ -387,6 +494,9 @@ typedef enum - DW_ATE_decimal_float = 0xf, - /* DWARF 4. */ - DW_ATE_UTF = 0x10, -+ /* DWARF 5. */ -+ DW_ATE_UCS = 0x11, -+ DW_ATE_ASCII = 0x12, - /* HP extensions. */ - DW_ATE_HP_float80 = 0x80, /* Floating-point (80 bit). */ - DW_ATE_HP_complex_float80 = 0x81, /* Complex floating-point (80 bit). */ -@@ -558,8 +668,35 @@ typedef enum - /* DWARF 4 extensions. */ - DW_OP_implicit_value = 0x9e, - DW_OP_stack_value = 0x9f, -+ /* DWARF 5 extensions. */ -+ DW_OP_implicit_pointer = 0xa0, -+ DW_OP_addrx = 0xa1, -+ DW_OP_constx = 0xa2, -+ DW_OP_entry_value = 0xa3, -+ DW_OP_const_type = 0xa4, -+ DW_OP_regval_type = 0xa5, -+ DW_OP_deref_type = 0xa6, -+ DW_OP_xderef_type = 0xa7, -+ DW_OP_convert = 0xa8, -+ DW_OP_reinterpret = 0xa9, - /* GNU extensions. */ - DW_OP_GNU_push_tls_address = 0xe0, -+ DW_OP_GNU_uninit = 0xf0, -+ DW_OP_GNU_encoded_addr = 0xf1, -+ DW_OP_GNU_implicit_pointer = 0xf2, -+ DW_OP_GNU_entry_value = 0xf3, -+ DW_OP_GNU_const_type = 0xf4, -+ DW_OP_GNU_regval_type = 0xf5, -+ DW_OP_GNU_deref_type = 0xf6, -+ DW_OP_GNU_convert = 0xf7, -+ DW_OP_GNU_reinterpret = 0xf9, -+ DW_OP_GNU_parameter_ref = 0xfa, -+ /* GNU Debug Fission extensions. */ -+ DW_OP_GNU_addr_index = 0xfb, -+ DW_OP_GNU_const_index = 0xfc, -+ /* The GNU variable value extension. -+ See http://dwarfstd.org/ShowIssue.php?issue=161109.2 . */ -+ DW_OP_GNU_variable_value = 0xfd, - /* HP extensions. */ - DW_OP_HP_unknown = 0xe0, /* Ouch, the same as GNU_push_tls_address. */ - DW_OP_HP_is_value = 0xe1, -@@ -571,6 +708,62 @@ typedef enum - } - DW_OP; - -+typedef enum -+ { -+ DW_UT_compile = 0x01, -+ DW_UT_type = 0x02, -+ DW_UT_partial = 0x03, -+ DW_UT_skeleton = 0x04, -+ DW_UT_split_compile = 0x05, -+ DW_UT_split_type = 0x06, -+ -+ DW_UT_lo_user = 0x80, -+ DW_UT_hi_user = 0xff -+ } -+ DW_UT; -+ -+typedef enum -+ { -+ DW_LNCT_path = 0x1, -+ DW_LNCT_directory_index = 0x2, -+ DW_LNCT_timestamp = 0x3, -+ DW_LNCT_size = 0x4, -+ DW_LNCT_MD5 = 0x5, -+ -+ DW_LNCT_lo_user = 0x2000, -+ DW_LNCT_hi_user = 0x3fff -+ } -+ DW_LNCT; -+ -+typedef enum -+ { -+ DW_RLE_end_of_list = 0x00, -+ DW_RLE_base_addressx = 0x01, -+ DW_RLE_startx_endx = 0x02, -+ DW_RLE_startx_length = 0x03, -+ DW_RLE_offset_pair = 0x04, -+ DW_RLE_base_address = 0x05, -+ DW_RLE_start_end = 0x06, -+ DW_RLE_start_length = 0x07 -+ } -+ DW_RLE; -+ -+typedef enum -+ { -+ DW_LLE_end_of_list = 0x00, -+ DW_LLE_base_addressx = 0x01, -+ DW_LLE_startx_endx = 0x02, -+ DW_LLE_startx_length = 0x03, -+ DW_LLE_offset_pair = 0x04, -+ DW_LLE_default_location = 0x05, -+ DW_LLE_base_address = 0x06, -+ DW_LLE_start_end = 0x07, -+ DW_LLE_start_length = 0x08, -+ -+ DW_LLE_GNU_view_pair = 0x09 -+ } -+ DW_LLE; -+ - const HChar* ML_(pp_DW_children) ( DW_children hashch ); - const HChar* ML_(pp_DW_TAG) ( DW_TAG tag ); - const HChar* ML_(pp_DW_FORM) ( DW_FORM form ); -diff --git a/coregrind/m_debuginfo/priv_readdwarf.h b/coregrind/m_debuginfo/priv_readdwarf.h -index 1e3f24c2a..302266924 100644 ---- a/coregrind/m_debuginfo/priv_readdwarf.h -+++ b/coregrind/m_debuginfo/priv_readdwarf.h -@@ -50,7 +50,8 @@ void ML_(read_debuginfo_dwarf3) - DiSlice escn_debug_abbv, /* .debug_abbrev */ - DiSlice escn_debug_line, /* .debug_line */ - DiSlice escn_debug_str, /* .debug_str */ -- DiSlice escn_debug_str_alt ); /* .debug_str */ -+ DiSlice escn_debug_str_alt, /* .debug_str */ -+ DiSlice escn_debug_line_str );/* .debug_line_str */ - - /* -------------------- - DWARF1 reader -diff --git a/coregrind/m_debuginfo/priv_readdwarf3.h b/coregrind/m_debuginfo/priv_readdwarf3.h -index 1a5bd61c3..f6d1dd1ee 100644 ---- a/coregrind/m_debuginfo/priv_readdwarf3.h -+++ b/coregrind/m_debuginfo/priv_readdwarf3.h -@@ -45,9 +45,10 @@ ML_(new_dwarf3_reader) ( - DiSlice escn_debug_info, DiSlice escn_debug_types, - DiSlice escn_debug_abbv, DiSlice escn_debug_line, - DiSlice escn_debug_str, DiSlice escn_debug_ranges, -+ DiSlice escn_debug_rnglists, DiSlice escn_debug_loclists, - DiSlice escn_debug_loc, DiSlice escn_debug_info_alt, - DiSlice escn_debug_abbv_alt, DiSlice escn_debug_line_alt, -- DiSlice escn_debug_str_alt -+ DiSlice escn_debug_str_alt, DiSlice escn_debug_line_str - ); - - #endif /* ndef __PRIV_READDWARF3_H */ -diff --git a/coregrind/m_debuginfo/readdwarf.c b/coregrind/m_debuginfo/readdwarf.c -index 5701c504b..88d5d99f1 100644 ---- a/coregrind/m_debuginfo/readdwarf.c -+++ b/coregrind/m_debuginfo/readdwarf.c -@@ -322,6 +322,123 @@ void process_extended_line_op( struct _DebugInfo* di, - //////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////// - -+static -+HChar * get_line_str (struct _DebugInfo* di, const UnitInfo* ui, -+ DiCursor *data, const UInt form, -+ DiCursor debugstr_img, DiCursor debuglinestr_img) -+{ -+ HChar *str = NULL; -+ switch (form) { -+ case DW_FORM_string: -+ str = ML_(cur_step_strdup)(data, "di.gls.string"); -+ break; -+ case DW_FORM_strp: -+ if (!ui->dw64) -+ str = ML_(cur_read_strdup)(ML_(cur_plus)(debugstr_img, -+ ML_(cur_step_UInt)(data)), -+ "di.gls.strp.dw32"); -+ else -+ str = ML_(cur_read_strdup)(ML_(cur_plus)(debugstr_img, -+ ML_(cur_step_ULong)(data)), -+ "di.gls.strp.dw64"); -+ break; -+ case DW_FORM_line_strp: -+ if (!ui->dw64) -+ str = ML_(cur_read_strdup)(ML_(cur_plus)(debuglinestr_img, -+ ML_(cur_step_UInt)(data)), -+ "di.gls.line_strp.dw32"); -+ else -+ str = ML_(cur_read_strdup)(ML_(cur_plus)(debuglinestr_img, -+ ML_(cur_step_ULong)(data)), -+ "di.gls.line_strp.dw64"); -+ break; -+ default: -+ ML_(symerr)(di, True, -+ "Unknown path string FORM in .debug_line"); -+ break; -+ } -+ return str; -+} -+ -+static -+Int get_line_ndx (struct _DebugInfo* di, -+ DiCursor *data, const UInt form) -+{ -+ Int res = 0; -+ switch (form) { -+ case DW_FORM_data1: -+ res = ML_(cur_step_UChar)(data); -+ break; -+ case DW_FORM_data2: -+ res = ML_(cur_step_UShort)(data); -+ break; -+ case DW_FORM_udata: -+ res = step_leb128U(data); -+ break; -+ default: -+ ML_(symerr)(di, True, -+ "Unknown directory_index value FORM in .debug_line"); -+ break; -+ } -+ return res; -+} -+ -+static -+DiCursor skip_line_form (struct _DebugInfo* di, const UnitInfo* ui, -+ DiCursor d, const UInt form) -+{ -+ switch (form) { -+ case DW_FORM_block: { -+ ULong len = step_leb128U(&d); -+ d = ML_(cur_plus)(d, len); -+ break; -+ } -+ case DW_FORM_block1: -+ d = ML_(cur_plus)(d, ML_(cur_read_UChar)(d) + 1); -+ break; -+ case DW_FORM_block2: -+ d = ML_(cur_plus)(d, ML_(cur_read_UShort)(d) + 2); -+ break; -+ case DW_FORM_block4: -+ d = ML_(cur_plus)(d, ML_(cur_read_UInt)(d) + 4); -+ break; -+ case DW_FORM_flag: -+ case DW_FORM_data1: -+ d = ML_(cur_plus)(d, 1); -+ break; -+ case DW_FORM_data2: -+ d = ML_(cur_plus)(d, 2); -+ break; -+ case DW_FORM_data4: -+ d = ML_(cur_plus)(d, 4); -+ break; -+ case DW_FORM_data8: -+ d = ML_(cur_plus)(d, 8); -+ break; -+ case DW_FORM_data16: -+ d = ML_(cur_plus)(d, 16); -+ break; -+ case DW_FORM_string: -+ d = ML_(cur_plus)(d, ML_(cur_strlen)(d) + 1); -+ break; -+ case DW_FORM_strp: -+ case DW_FORM_line_strp: -+ case DW_FORM_sec_offset: -+ d = ML_(cur_plus)(d, ui->dw64 ? 8 : 4); -+ break; -+ case DW_FORM_udata: -+ (void)step_leb128U(&d); -+ break; -+ case DW_FORM_sdata: -+ (void)step_leb128S(&d); -+ break; -+ default: -+ ML_(symerr)(di, True, "Unknown FORM in .debug_line"); -+ break; -+ } -+ return d; -+} -+ - /* read a .debug_line section block for a compilation unit - * - * Input: - theBlock must point to the start of the block -@@ -335,7 +452,9 @@ static - void read_dwarf2_lineblock ( struct _DebugInfo* di, - const UnitInfo* ui, - DiCursor theBlock, /* IMAGE */ -- Int noLargerThan ) -+ Int noLargerThan, -+ DiCursor debugstr_img, -+ DiCursor debuglinestr_img) - { - Int i; - DebugLineInfo info; -@@ -348,6 +467,9 @@ void read_dwarf2_lineblock ( struct _DebugInfo* di, - DiCursor external = theBlock; - DiCursor data = theBlock; - -+ UChar p_ndx = 0, d_ndx = 0; /* DWARF5 path and dir index. */ -+ UInt forms[256]; /* DWARF5 forms. */ -+ - /* fndn_ix_xa is an xarray of fndn_ix (indexes in di->fndnpool) which - are build from file names harvested from the DWARF2 - info. Entry [0] is the "null" pool index and is never referred to -@@ -372,17 +494,6 @@ void read_dwarf2_lineblock ( struct _DebugInfo* di, - fndn_ix_xa = VG_(newXA) (ML_(dinfo_zalloc), "di.rd2l.2", ML_(dinfo_free), - sizeof(UInt) ); - -- /* DWARF2 starts numbering filename entries at 1, so we need to -- add a dummy zeroth entry to the table. */ -- fndn_ix = 0; // 0 is the "null" index in a fixed pool. -- VG_(addToXA) (fndn_ix_xa, &fndn_ix); -- -- if (ML_(cur_is_valid)(ui->compdir)) -- dirname = ML_(addStrFromCursor)(di, ui->compdir); -- else -- dirname = ML_(addStr)(di, ".", -1); -- VG_(addToXA) (dirname_xa, &dirname); -- - info.li_length = step_initial_length_field( &external, &is64 ); - if (di->ddump_line) - VG_(printf)(" Length: %llu\n", -@@ -402,13 +513,19 @@ void read_dwarf2_lineblock ( struct _DebugInfo* di, - VG_(printf)(" DWARF Version: %d\n", - (Int)info.li_version); - -- if (info.li_version != 2 && info.li_version != 3 && info.li_version != 4) { -+ if (info.li_version != 2 && info.li_version != 3 && info.li_version != 4 -+ && info.li_version != 5) { - ML_(symerr)(di, True, -- "Only DWARF version 2, 3 and 4 line info " -+ "Only DWARF version 2, 3, 4 and 5 line info " - "is currently supported."); - goto out; - } - -+ if (info.li_version >= 5) { -+ /* UChar addr_size = */ ML_(cur_step_UChar)(&external); -+ /* UChar seg_size = */ ML_(cur_step_UChar)(&external); -+ } -+ - info.li_header_length = is64 ? ML_(cur_step_ULong)(&external) - : (ULong)(ML_(cur_step_UInt)(&external)); - if (di->ddump_line) -@@ -485,60 +602,141 @@ void read_dwarf2_lineblock ( struct _DebugInfo* di, - /* skip over "standard_opcode_lengths" */ - data = ML_(cur_plus)(standard_opcodes, info.li_opcode_base - 1); - -- /* Read the contents of the Directory table. */ -- if (di->ddump_line) -- VG_(printf)(" The Directory Table%s\n", -- ML_(cur_read_UChar)(data) == 0 ? " is empty." : ":" ); -- -- while (ML_(cur_read_UChar)(data) != 0) { -+ if (ML_(cur_is_valid)(ui->compdir)) -+ dirname = ML_(addStrFromCursor)(di, ui->compdir); -+ else -+ dirname = ML_(addStr)(di, ".", -1); - -- HChar* data_str = ML_(cur_read_strdup)(data, "di.rd2l.1"); -+ if (info.li_version < 5) { -+ /* Read the contents of the Directory table. */ - if (di->ddump_line) -- VG_(printf)(" %s\n", data_str); -- -- /* If data[0] is '/', then 'data' is an absolute path and we -- don't mess with it. Otherwise, construct the -- path 'ui->compdir' ++ "/" ++ 'data'. */ -- -- if (data_str[0] != '/' -- /* not an absolute path */ -- && ML_(cur_is_valid)(ui->compdir) -- /* actually got something sensible for compdir */ -- && ML_(cur_strlen)(ui->compdir)) -- { -- HChar* compdir_str = ML_(cur_read_strdup)(ui->compdir, "di.rd2l.1b"); -- SizeT len = VG_(strlen)(compdir_str) + 1 + VG_(strlen)(data_str); -- HChar *buf = ML_(dinfo_zalloc)("di.rd2l.1c", len + 1); -- -- VG_(strcpy)(buf, compdir_str); -- VG_(strcat)(buf, "/"); -- VG_(strcat)(buf, data_str); -- -- dirname = ML_(addStr)(di, buf, len); -- VG_(addToXA) (dirname_xa, &dirname); -- if (0) VG_(printf)("rel path %s\n", buf); -- ML_(dinfo_free)(compdir_str); -- ML_(dinfo_free)(buf); -- } else { -- /* just use 'data'. */ -- dirname = ML_(addStr)(di,data_str,-1); -- VG_(addToXA) (dirname_xa, &dirname); -- if (0) VG_(printf)("abs path %s\n", data_str); -+ VG_(printf)("The Directory Table%s\n", -+ ML_(cur_read_UChar)(data) == 0 ? " is empty." : ":" ); -+ -+ /* DWARF2 starts numbering filename entries at 1, so we need to -+ add a dummy zeroth entry to the table. */ -+ fndn_ix = 0; // 0 is the "null" index in a fixed pool. -+ VG_(addToXA) (fndn_ix_xa, &fndn_ix); -+ VG_(addToXA) (dirname_xa, &dirname); -+ -+ while (ML_(cur_read_UChar)(data) != 0) { -+ -+ HChar* data_str = ML_(cur_read_strdup)(data, "di.rd2l.1"); -+ if (di->ddump_line) -+ VG_(printf)(" %s\n", data_str); -+ -+ /* If data[0] is '/', then 'data' is an absolute path and we -+ don't mess with it. Otherwise, construct the -+ path 'ui->compdir' ++ "/" ++ 'data'. */ -+ -+ if (data_str[0] != '/' -+ /* not an absolute path */ -+ && ML_(cur_is_valid)(ui->compdir) -+ /* actually got something sensible for compdir */ -+ && ML_(cur_strlen)(ui->compdir)) -+ { -+ HChar* compdir_str = ML_(cur_read_strdup)(ui->compdir, -+ "di.rd2l.1b"); -+ SizeT len = VG_(strlen)(compdir_str) + 1 + VG_(strlen)(data_str); -+ HChar *buf = ML_(dinfo_zalloc)("di.rd2l.1c", len + 1); -+ -+ VG_(strcpy)(buf, compdir_str); -+ VG_(strcat)(buf, "/"); -+ VG_(strcat)(buf, data_str); -+ -+ dirname = ML_(addStr)(di, buf, len); -+ VG_(addToXA) (dirname_xa, &dirname); -+ if (0) VG_(printf)("rel path %s\n", buf); -+ ML_(dinfo_free)(compdir_str); -+ ML_(dinfo_free)(buf); -+ } else { -+ /* just use 'data'. */ -+ dirname = ML_(addStr)(di,data_str,-1); -+ VG_(addToXA) (dirname_xa, &dirname); -+ if (0) VG_(printf)("abs path %s\n", data_str); -+ } -+ -+ data = ML_(cur_plus)(data, VG_(strlen)(data_str) + 1); -+ ML_(dinfo_free)(data_str); - } - -- data = ML_(cur_plus)(data, VG_(strlen)(data_str) + 1); -- ML_(dinfo_free)(data_str); -- } -+ if (di->ddump_line) -+ VG_(printf)("\n"); - -- if (di->ddump_line) -- VG_(printf)("\n"); -+ if (ML_(cur_read_UChar)(data) != 0) { -+ ML_(symerr)(di, True, -+ "can't find NUL at end of DWARF2 directory table"); -+ goto out; -+ } -+ data = ML_(cur_plus)(data, 1); -+ } else { -+ UInt directories_count; -+ UChar directory_entry_format_count = ML_(cur_step_UChar)(&data); -+ UInt n; -+ for (n = 0; n < directory_entry_format_count; n++) { -+ UInt lnct = step_leb128U(&data); -+ UInt form = step_leb128U(&data); -+ if (lnct == DW_LNCT_path) -+ p_ndx = n; -+ forms[n] = form; -+ } -+ directories_count = step_leb128U(&data); -+ /* Read the contents of the Directory table. */ -+ if (di->ddump_line) -+ VG_(printf)(" dwarf The Directory Table%s\n", -+ directories_count == 0 ? " is empty." : ":" ); -+ -+ for (n = 0; n < directories_count; n++) { -+ UInt f; -+ for (f = 0; f < directory_entry_format_count; f++) { -+ UInt form = forms[f]; -+ if (f == p_ndx) { -+ HChar *data_str = get_line_str (di, ui, &data, form, -+ debugstr_img, -+ debuglinestr_img); -+ if (di->ddump_line) -+ VG_(printf)(" %s\n", data_str); -+ -+ /* If data[0] is '/', then 'data' is an absolute path and we -+ don't mess with it. Otherwise, construct the -+ path 'ui->compdir' ++ "/" ++ 'data'. */ -+ -+ if (data_str[0] != '/' -+ /* not an absolute path */ -+ && ML_(cur_is_valid)(ui->compdir) -+ /* actually got something sensible for compdir */ -+ && ML_(cur_strlen)(ui->compdir)) -+ { -+ HChar* compdir_str = ML_(cur_read_strdup)(ui->compdir, -+ "di.rd2l.1b"); -+ SizeT len = VG_(strlen)(compdir_str) + 1 -+ + VG_(strlen)(data_str); -+ HChar *buf = ML_(dinfo_zalloc)("di.rd2l.1c", len + 1); -+ -+ VG_(strcpy)(buf, compdir_str); -+ VG_(strcat)(buf, "/"); -+ VG_(strcat)(buf, data_str); -+ -+ dirname = ML_(addStr)(di, buf, len); -+ VG_(addToXA) (dirname_xa, &dirname); -+ if (0) VG_(printf)("rel path %s\n", buf); -+ ML_(dinfo_free)(compdir_str); -+ ML_(dinfo_free)(buf); -+ } else { -+ /* just use 'data'. */ -+ dirname = ML_(addStr)(di,data_str,-1); -+ VG_(addToXA) (dirname_xa, &dirname); -+ if (0) VG_(printf)("abs path %s\n", data_str); -+ } - -- if (ML_(cur_read_UChar)(data) != 0) { -- ML_(symerr)(di, True, -- "can't find NUL at end of DWARF2 directory table"); -- goto out; -+ ML_(dinfo_free)(data_str); -+ -+ } else { -+ data = skip_line_form (di, ui, data, form); -+ } -+ } -+ } - } -- data = ML_(cur_plus)(data, 1); - - /* Read the contents of the File Name table. This produces a bunch - of fndn_ix in fndn_ix_xa. */ -@@ -547,33 +745,76 @@ void read_dwarf2_lineblock ( struct _DebugInfo* di, - VG_(printf)(" Entry Dir Time Size Name\n"); - } - -- i = 1; -- while (ML_(cur_read_UChar)(data) != 0) { -- HChar* name = ML_(cur_step_strdup)(&data, "di.rd2l.2"); -- Int diridx = step_leb128U(&data); -- Int uu_time = step_leb128U(&data); /* unused */ -- Int uu_size = step_leb128U(&data); /* unused */ -+ if (info.li_version < 5) { -+ i = 1; -+ while (ML_(cur_read_UChar)(data) != 0) { -+ HChar* name = ML_(cur_step_strdup)(&data, "di.rd2l.2"); -+ Int diridx = step_leb128U(&data); -+ Int uu_time = step_leb128U(&data); /* unused */ -+ Int uu_size = step_leb128U(&data); /* unused */ -+ -+ dirname = safe_dirname_ix( dirname_xa, diridx ); -+ fndn_ix = ML_(addFnDn) (di, name, dirname); -+ VG_(addToXA) (fndn_ix_xa, &fndn_ix); -+ if (0) VG_(printf)("file %s diridx %d\n", name, diridx ); -+ if (di->ddump_line) -+ VG_(printf)(" %d\t%d\t%d\t%d\t%s\n", -+ i, diridx, uu_time, uu_size, name); -+ i++; -+ ML_(dinfo_free)(name); -+ } - -- dirname = safe_dirname_ix( dirname_xa, diridx ); -- fndn_ix = ML_(addFnDn) (di, name, dirname); -- VG_(addToXA) (fndn_ix_xa, &fndn_ix); -- if (0) VG_(printf)("file %s diridx %d\n", name, diridx ); - if (di->ddump_line) -- VG_(printf)(" %d\t%d\t%d\t%d\t%s\n", -- i, diridx, uu_time, uu_size, name); -- i++; -- ML_(dinfo_free)(name); -- } -+ VG_(printf)("\n"); - -- if (di->ddump_line) -- VG_(printf)("\n"); -+ if (ML_(cur_read_UChar)(data) != 0) { -+ ML_(symerr)(di, True, -+ "can't find NUL at end of DWARF2 file name table"); -+ goto out; -+ } -+ data = ML_(cur_plus)(data, 1); -+ } else { -+ UInt file_names_count; -+ UChar file_names_entry_format_count = ML_(cur_step_UChar)(&data); -+ UInt n; -+ for (n = 0; n < file_names_entry_format_count; n++) { -+ UInt lnct = step_leb128U(&data); -+ UInt form = step_leb128U(&data); -+ if (lnct == DW_LNCT_path) -+ p_ndx = n; -+ if (lnct == DW_LNCT_directory_index) -+ d_ndx = n; -+ forms[n] = form; -+ } -+ file_names_count = step_leb128U(&data); -+ for (n = 0; n < file_names_count; n++) { -+ UInt f; -+ HChar* name = NULL; -+ Int diridx = 0; -+ for (f = 0; f < file_names_entry_format_count; f++) { -+ UInt form = forms[f]; -+ if (f == p_ndx) -+ name = get_line_str (di, ui, &data, form, -+ debugstr_img, debuglinestr_img); -+ else if (n == d_ndx) -+ diridx = get_line_ndx (di, &data, form); -+ else -+ data = skip_line_form (di, ui, data, form); -+ } - -- if (ML_(cur_read_UChar)(data) != 0) { -- ML_(symerr)(di, True, -- "can't find NUL at end of DWARF2 file name table"); -- goto out; -+ dirname = safe_dirname_ix( dirname_xa, diridx ); -+ fndn_ix = ML_(addFnDn) (di, name, dirname); -+ VG_(addToXA) (fndn_ix_xa, &fndn_ix); -+ if (0) VG_(printf)("file %s diridx %d\n", name, diridx ); -+ if (di->ddump_line) -+ VG_(printf)(" %u\t%d\t%d\t%d\t%s\n", -+ n, diridx, 0, 0, name); -+ ML_(dinfo_free)(name); -+ } -+ -+ if (di->ddump_line) -+ VG_(printf)("\n"); - } -- data = ML_(cur_plus)(data, 1); - - if (di->ddump_line) - VG_(printf)(" Line Number Statements:\n"); -@@ -772,9 +1013,12 @@ static DiCursor lookup_abbrev( DiCursor p, ULong acode ) - (void)step_leb128U(&p); /* skip tag */ - p = ML_(cur_plus)(p,1); /* skip has_children flag */ - ULong name; -+ ULong form; - do { - name = step_leb128U(&p); /* name */ -- (void)step_leb128U(&p); /* form */ -+ form = step_leb128U(&p); /* form */ -+ if (form == 0x21) /* DW_FORM_implicit_const */ -+ step_leb128S(&p); - } - while (name != 0); /* until name == form == 0 */ - } -@@ -804,13 +1048,14 @@ void read_unitinfo_dwarf2( /*OUT*/UnitInfo* ui, - DiCursor unitblock_img, - DiCursor debugabbrev_img, - DiCursor debugstr_img, -- DiCursor debugstr_alt_img ) -+ DiCursor debugstr_alt_img, -+ DiCursor debuglinestr_img) - { - UInt acode, abcode; - ULong atoffs, blklen; - UShort ver; - -- UChar addr_size; -+ UChar addr_size = 0; - DiCursor p = unitblock_img; - DiCursor end_img; - DiCursor abbrev_img; -@@ -823,16 +1068,25 @@ void read_unitinfo_dwarf2( /*OUT*/UnitInfo* ui, - /* This block length */ - blklen = step_initial_length_field( &p, &ui->dw64 ); - -- /* version should be 2, 3 or 4 */ -+ /* version should be 2, 3, 4 or 5 */ - ver = ML_(cur_step_UShort)(&p); - -- /* get offset in abbrev */ -- atoffs = ui->dw64 ? ML_(cur_step_ULong)(&p) -- : (ULong)(ML_(cur_step_UInt)(&p)); -+ if (ver >= 5) -+ /* unit_type for DWARF5 */ -+ /* unit_type = */ ML_(cur_step_UChar)(&p); -+ else -+ /* get offset in abbrev */ -+ atoffs = ui->dw64 ? ML_(cur_step_ULong)(&p) -+ : (ULong)(ML_(cur_step_UInt)(&p)); - - /* Address size */ - addr_size = ML_(cur_step_UChar)(&p); - -+ if (ver >= 5) -+ /* get offset in abbrev */ -+ atoffs = ui->dw64 ? ML_(cur_step_ULong)(&p) -+ : (ULong)(ML_(cur_step_UInt)(&p)); -+ - /* End of this block */ - end_img = ML_(cur_plus)(unitblock_img, blklen + (ui->dw64 ? 12 : 4)); - -@@ -909,6 +1163,17 @@ void read_unitinfo_dwarf2( /*OUT*/UnitInfo* ui, - sval = ML_(cur_plus)(debugstr_img, ML_(cur_read_ULong)(p)); - p = ML_(cur_plus)(p, ui->dw64 ? 8 : 4); - break; -+ case 0x1f: /* FORM_line_strp */ /* pointer in .debug_line_str */ -+ /* 2006-01-01: only generate a value if a debug_str -+ section was found) */ -+ if (ML_(cur_is_valid)(debuglinestr_img) && !ui->dw64) -+ sval = ML_(cur_plus)(debuglinestr_img, -+ ML_(cur_read_UInt)(p)); -+ if (ML_(cur_is_valid)(debuglinestr_img) && ui->dw64) -+ sval = ML_(cur_plus)(debuglinestr_img, -+ ML_(cur_read_ULong)(p)); -+ p = ML_(cur_plus)(p, ui->dw64 ? 8 : 4); -+ break; - case 0x08: /* FORM_string */ - sval = p; - p = ML_(cur_plus)(p, ML_(cur_strlen)(p) + 1); -@@ -928,7 +1193,13 @@ void read_unitinfo_dwarf2( /*OUT*/UnitInfo* ui, - p = ML_(cur_plus)(p, 8); - /* perhaps should assign unconditionally to cval? */ - break; -+ case 0x21: /* FORM_implicit_const */ -+ cval = step_leb128S (&abbrev_img); -+ break; - /* TODO : Following ones just skip data - implement if you need */ -+ case 0x1e: /* FORM_data16 */ -+ p = ML_(cur_plus)(p, 16); -+ break; - case 0x01: /* FORM_addr */ - p = ML_(cur_plus)(p, addr_size); - break; -@@ -1028,7 +1299,8 @@ void ML_(read_debuginfo_dwarf3) - DiSlice escn_debug_abbv, /* .debug_abbrev */ - DiSlice escn_debug_line, /* .debug_line */ - DiSlice escn_debug_str, /* .debug_str */ -- DiSlice escn_debug_str_alt ) /* .debug_str */ -+ DiSlice escn_debug_str_alt, /* .debug_str */ -+ DiSlice escn_debug_line_str) /* .debug_line_str */ - { - UnitInfo ui; - UShort ver; -@@ -1067,9 +1339,9 @@ void ML_(read_debuginfo_dwarf3) - - /* version should be 2 */ - ver = ML_(cur_read_UShort)( ML_(cur_plus)(block_img, blklen_len) ); -- if ( ver != 2 && ver != 3 && ver != 4 ) { -+ if ( ver != 2 && ver != 3 && ver != 4 && ver != 5) { - ML_(symerr)( di, True, -- "Ignoring non-Dwarf2/3/4 block in .debug_info" ); -+ "Ignoring non-Dwarf2/3/4/5 block in .debug_info" ); - continue; - } - -@@ -1082,7 +1354,8 @@ void ML_(read_debuginfo_dwarf3) - read_unitinfo_dwarf2( &ui, block_img, - ML_(cur_from_sli)(escn_debug_abbv), - ML_(cur_from_sli)(escn_debug_str), -- ML_(cur_from_sli)(escn_debug_str_alt) ); -+ ML_(cur_from_sli)(escn_debug_str_alt), -+ ML_(cur_from_sli)(escn_debug_line_str)); - if (0) { - HChar* str_name = ML_(cur_read_strdup)(ui.name, "di.rdd3.1"); - HChar* str_compdir = ML_(cur_read_strdup)(ui.compdir, "di.rdd3.2"); -@@ -1107,7 +1380,9 @@ void ML_(read_debuginfo_dwarf3) - read_dwarf2_lineblock( - di, &ui, - ML_(cur_plus)(ML_(cur_from_sli)(escn_debug_line), ui.stmt_list), -- escn_debug_line.szB - ui.stmt_list -+ escn_debug_line.szB - ui.stmt_list, -+ ML_(cur_from_sli)(escn_debug_str), -+ ML_(cur_from_sli)(escn_debug_line_str) - ); - } - } -diff --git a/coregrind/m_debuginfo/readdwarf3.c b/coregrind/m_debuginfo/readdwarf3.c -index c4d529bc6..82bc8f241 100644 ---- a/coregrind/m_debuginfo/readdwarf3.c -+++ b/coregrind/m_debuginfo/readdwarf3.c -@@ -384,6 +384,7 @@ typedef - struct _name_form { - ULong at_name; // Dwarf Attribute name - ULong at_form; // Dwarf Attribute form -+ Long at_val; // Dwarf Attribute value (for implicit_const) - UInt skip_szB; // Nr of bytes skippable from here ... - UInt next_nf; // ... to reach this attr/form index in the g_abbv.nf - } name_form; -@@ -423,7 +424,7 @@ typedef - void (*barf)( const HChar* ) __attribute__((noreturn)); - /* Is this 64-bit DWARF ? */ - Bool is_dw64; -- /* Which DWARF version ? (2, 3 or 4) */ -+ /* Which DWARF version ? (2, 3, 4 or 5) */ - UShort version; - /* Length of this Compilation Unit, as stated in the - .unit_length :: InitialLength field of the CU Header. -@@ -452,12 +453,15 @@ typedef - /* Image information for various sections. */ - DiSlice escn_debug_str; - DiSlice escn_debug_ranges; -+ DiSlice escn_debug_rnglists; -+ DiSlice escn_debug_loclists; - DiSlice escn_debug_loc; - DiSlice escn_debug_line; - DiSlice escn_debug_info; - DiSlice escn_debug_types; - DiSlice escn_debug_info_alt; - DiSlice escn_debug_str_alt; -+ DiSlice escn_debug_line_str; - /* How much to add to .debug_types resp. alternate .debug_info offsets - in cook_die*. */ - UWord types_cuOff_bias; -@@ -651,25 +655,35 @@ static GExpr* make_singleton_GX ( DiCursor block, ULong nbytes ) - __attribute__((noinline)) - static GExpr* make_general_GX ( const CUConst* cc, - Bool td3, -- ULong debug_loc_offset, -+ ULong offset, - Addr svma_of_referencing_CU ) - { -+ Bool done; - Addr base; - Cursor loc; - XArray* xa; /* XArray of UChar */ - GExpr* gx; - Word nbytes; -+ Bool addBase = cc->version < 5; - - vg_assert(sizeof(UWord) == sizeof(Addr)); -- if (!ML_(sli_is_valid)(cc->escn_debug_loc) || cc->escn_debug_loc.szB == 0) -+ if (cc->version < 5 && (!ML_(sli_is_valid)(cc->escn_debug_loc) -+ || cc->escn_debug_loc.szB == 0)) - cc->barf("make_general_GX: .debug_loc is empty/missing"); -+ if (cc->version >= 5 && (!ML_(sli_is_valid)(cc->escn_debug_loclists) -+ || cc->escn_debug_loclists.szB == 0)) -+ cc->barf("make_general_GX: .debug_loclists is empty/missing"); - -- init_Cursor( &loc, cc->escn_debug_loc, 0, cc->barf, -- "Overrun whilst reading .debug_loc section(2)" ); -- set_position_of_Cursor( &loc, debug_loc_offset ); -+ if (cc->version < 5) -+ init_Cursor( &loc, cc->escn_debug_loc, 0, cc->barf, -+ "Overrun whilst reading .debug_loc section(2)" ); -+ else -+ init_Cursor( &loc, cc->escn_debug_loclists, 0, cc->barf, -+ "Overrun whilst reading .debug_loclists section(2)" ); -+ set_position_of_Cursor( &loc, offset ); - -- TRACE_D3("make_general_GX (.debug_loc_offset = %llu, ioff = %llu) {\n", -- debug_loc_offset, get_DiCursor_from_Cursor(&loc).ioff ); -+ TRACE_D3("make_general_GX (offset = %llu, ioff = %llu) {\n", -+ offset, get_DiCursor_from_Cursor(&loc).ioff ); - - /* Who frees this xa? It is freed before this fn exits. */ - xa = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.mgGX.1", -@@ -679,40 +693,86 @@ static GExpr* make_general_GX ( const CUConst* cc, - { UChar c = 1; /*biasMe*/ VG_(addBytesToXA)( xa, &c, sizeof(c) ); } - - base = 0; -- while (True) { -+ done = False; -+ while (!done) { - Bool acquire; - UWord len; -- /* Read a (host-)word pair. This is something of a hack since -- the word size to read is really dictated by the ELF file; -- however, we assume we're reading a file with the same -- word-sizeness as the host. Reasonably enough. */ -- UWord w1 = get_UWord( &loc ); -- UWord w2 = get_UWord( &loc ); -- -- TRACE_D3(" %08lx %08lx\n", w1, w2); -- if (w1 == 0 && w2 == 0) -- break; /* end of list */ -- -- if (w1 == -1UL) { -- /* new value for 'base' */ -- base = w2; -- continue; -+ UWord w1; -+ UWord w2; -+ if (cc->version < 5) { -+ /* Read a (host-)word pair. This is something of a hack since -+ the word size to read is really dictated by the ELF file; -+ however, we assume we're reading a file with the same -+ word-sizeness as the host. Reasonably enough. */ -+ w1 = get_UWord( &loc ); -+ w2 = get_UWord( &loc ); -+ -+ TRACE_D3(" %08lx %08lx\n", w1, w2); -+ if (w1 == 0 && w2 == 0) { -+ done = True; -+ break; /* end of list */ -+ } -+ -+ if (w1 == -1UL) { -+ /* new value for 'base' */ -+ base = w2; -+ continue; -+ } -+ /* else a location expression follows */ -+ len = (UWord)get_UShort( &loc ); -+ } else { -+ w1 = 0; -+ w2 = 0; -+ len = 0; -+ DW_LLE r = get_UChar( &loc ); -+ switch (r) { -+ case DW_LLE_end_of_list: -+ done = True; -+ break; -+ case DW_LLE_base_address: -+ base = get_UWord( &loc ); -+ break; -+ case DW_LLE_start_length: -+ w1 = get_UWord( &loc ); -+ w2 = w1 + get_ULEB128( &loc ); -+ len = get_ULEB128( &loc ); -+ break; -+ case DW_LLE_offset_pair: -+ w1 = base + get_ULEB128( &loc ); -+ w2 = base + get_ULEB128( &loc ); -+ len = get_ULEB128( &loc ); -+ break; -+ case DW_LLE_start_end: -+ w1 = get_UWord ( &loc ); -+ w2 = get_UWord ( &loc ); -+ len = get_ULEB128( &loc ); -+ break; -+ case DW_LLE_GNU_view_pair: -+ get_ULEB128( &loc ); -+ get_ULEB128( &loc ); -+ break; -+ case DW_LLE_base_addressx: -+ case DW_LLE_startx_endx: -+ case DW_LLE_startx_length: -+ case DW_LLE_default_location: -+ default: -+ cc->barf( "Unhandled or unknown loclists entry" ); -+ done = True; -+ } - } - -- /* else a location expression follows */ - /* else enumerate [w1+base, w2+base) */ - /* w2 is 1 past end of range, as per D3 defn for "DW_AT_high_pc" - (sec 2.17.2) */ - if (w1 > w2) { - TRACE_D3("negative range is for .debug_loc expr at " - "file offset %llu\n", -- debug_loc_offset); -+ offset); - cc->barf( "negative range in .debug_loc section" ); - } - - /* ignore zero length ranges */ - acquire = w1 < w2; -- len = (UWord)get_UShort( &loc ); - - if (acquire) { - UWord w; -@@ -720,9 +780,9 @@ static GExpr* make_general_GX ( const CUConst* cc, - UChar c; - c = 0; /* !isEnd*/ - VG_(addBytesToXA)( xa, &c, sizeof(c) ); -- w = w1 + base + svma_of_referencing_CU; -+ w = w1 + (addBase ? base : 0) + svma_of_referencing_CU; - VG_(addBytesToXA)( xa, &w, sizeof(w) ); -- w = w2 -1 + base + svma_of_referencing_CU; -+ w = w2 -1 + (addBase ? base : 0) + svma_of_referencing_CU; - VG_(addBytesToXA)( xa, &w, sizeof(w) ); - s = (UShort)len; - VG_(addBytesToXA)( xa, &s, sizeof(s) ); -@@ -839,45 +899,96 @@ get_range_list ( const CUConst* cc, - XArray* xa; /* XArray of AddrRange */ - AddrRange pair; - -- if (!ML_(sli_is_valid)(cc->escn_debug_ranges) -- || cc->escn_debug_ranges.szB == 0) -+ if (cc->version < 5 && (!ML_(sli_is_valid)(cc->escn_debug_ranges) -+ || cc->escn_debug_ranges.szB == 0)) - cc->barf("get_range_list: .debug_ranges is empty/missing"); -+ if (cc->version >= 5 && (!ML_(sli_is_valid)(cc->escn_debug_rnglists) -+ || cc->escn_debug_rnglists.szB == 0)) -+ cc->barf("get_range_list: .debug_rnglists is empty/missing"); -+ -+ if (cc->version < 5) -+ init_Cursor( &ranges, cc->escn_debug_ranges, 0, cc->barf, -+ "Overrun whilst reading .debug_ranges section(2)" ); -+ else -+ init_Cursor( &ranges, cc->escn_debug_rnglists, 0, cc->barf, -+ "Overrun whilst reading .debug_rnglists section(2)" ); - -- init_Cursor( &ranges, cc->escn_debug_ranges, 0, cc->barf, -- "Overrun whilst reading .debug_ranges section(2)" ); - set_position_of_Cursor( &ranges, debug_ranges_offset ); - - /* Who frees this xa? varstack_preen() does. */ - xa = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.grl.1", ML_(dinfo_free), - sizeof(AddrRange) ); - base = 0; -- while (True) { -- /* Read a (host-)word pair. This is something of a hack since -- the word size to read is really dictated by the ELF file; -- however, we assume we're reading a file with the same -- word-sizeness as the host. Reasonably enough. */ -- UWord w1 = get_UWord( &ranges ); -- UWord w2 = get_UWord( &ranges ); -- -- if (w1 == 0 && w2 == 0) -- break; /* end of list. */ -- -- if (w1 == -1UL) { -- /* new value for 'base' */ -- base = w2; -- continue; -- } -+ if (cc->version < 5) { -+ while (True) { -+ /* Read a (host-)word pair. This is something of a hack since -+ the word size to read is really dictated by the ELF file; -+ however, we assume we're reading a file with the same -+ word-sizeness as the host. Reasonably enough. */ -+ UWord w1 = get_UWord( &ranges ); -+ UWord w2 = get_UWord( &ranges ); - -- /* else enumerate [w1+base, w2+base) */ -- /* w2 is 1 past end of range, as per D3 defn for "DW_AT_high_pc" -- (sec 2.17.2) */ -- if (w1 > w2) -- cc->barf( "negative range in .debug_ranges section" ); -- if (w1 < w2) { -- pair.aMin = w1 + base + svma_of_referencing_CU; -- pair.aMax = w2 - 1 + base + svma_of_referencing_CU; -- vg_assert(pair.aMin <= pair.aMax); -- VG_(addToXA)( xa, &pair ); -+ if (w1 == 0 && w2 == 0) -+ break; /* end of list. */ -+ -+ if (w1 == -1UL) { -+ /* new value for 'base' */ -+ base = w2; -+ continue; -+ } -+ -+ /* else enumerate [w1+base, w2+base) */ -+ /* w2 is 1 past end of range, as per D3 defn for "DW_AT_high_pc" -+ (sec 2.17.2) */ -+ if (w1 > w2) -+ cc->barf( "negative range in .debug_ranges section" ); -+ if (w1 < w2) { -+ pair.aMin = w1 + base + svma_of_referencing_CU; -+ pair.aMax = w2 - 1 + base + svma_of_referencing_CU; -+ vg_assert(pair.aMin <= pair.aMax); -+ VG_(addToXA)( xa, &pair ); -+ } -+ } -+ } else { -+ Bool done = False; -+ while (!done) { -+ UWord w1 = 0; -+ UWord w2 = 0; -+ DW_RLE r = get_UChar( &ranges ); -+ switch (r) { -+ case DW_RLE_end_of_list: -+ done = True; -+ break; -+ case DW_RLE_base_address: -+ base = get_UWord( &ranges ); -+ break; -+ case DW_RLE_start_length: -+ w1 = get_UWord( &ranges ); -+ w2 = w1 + get_ULEB128( &ranges ); -+ break; -+ case DW_RLE_offset_pair: -+ w1 = base + get_ULEB128( &ranges ); -+ w2 = base + get_ULEB128( &ranges ); -+ break; -+ case DW_RLE_start_end: -+ w1 = get_UWord ( &ranges ); -+ w2 = get_UWord ( &ranges ); -+ break; -+ case DW_RLE_base_addressx: -+ case DW_RLE_startx_endx: -+ case DW_RLE_startx_length: -+ default: -+ cc->barf( "Unhandled or unknown range list entry" ); -+ done = True; -+ } -+ if (w1 > w2) -+ cc->barf( "negative range in .debug_rnglists section" ); -+ if (w1 < w2) { -+ pair.aMin = w1 + svma_of_referencing_CU; -+ pair.aMax = w2 - 1 + svma_of_referencing_CU; -+ vg_assert(pair.aMin <= pair.aMax); -+ VG_(addToXA)( xa, &pair ); -+ } - } - } - return xa; -@@ -930,6 +1041,8 @@ static void init_ht_abbvs (CUConst* cc, - } - ta->nf[ta_nf_n].at_name = get_ULEB128( &c ); - ta->nf[ta_nf_n].at_form = get_ULEB128( &c ); -+ if (ta->nf[ta_nf_n].at_form == DW_FORM_implicit_const) -+ ta->nf[ta_nf_n].at_val = get_SLEB128( &c ); - if (ta->nf[ta_nf_n].at_name == 0 && ta->nf[ta_nf_n].at_form == 0) { - ta_nf_n++; - break; -@@ -1005,7 +1118,7 @@ void parse_CU_Header ( /*OUT*/CUConst* cc, - Bool type_unit, - Bool alt_info ) - { -- UChar address_size; -+ UChar address_size, unit_type; - ULong debug_abbrev_offset; - - VG_(memset)(cc, 0, sizeof(*cc)); -@@ -1021,10 +1134,21 @@ void parse_CU_Header ( /*OUT*/CUConst* cc, - - /* version */ - cc->version = get_UShort( c ); -- if (cc->version != 2 && cc->version != 3 && cc->version != 4) -- cc->barf( "parse_CU_Header: is neither DWARF2 nor DWARF3 nor DWARF4" ); -+ if (cc->version != 2 && cc->version != 3 && cc->version != 4 -+ && cc->version != 5) -+ cc->barf( "parse_CU_Header: " -+ "is neither DWARF2 nor DWARF3 nor DWARF4 nor DWARF5" ); - TRACE_D3(" Version: %d\n", (Int)cc->version ); - -+ /* unit type */ -+ if (cc->version >= 5) { -+ unit_type = get_UChar( c ); -+ address_size = get_UChar( c ); -+ } else { -+ unit_type = type_unit ? DW_UT_type : DW_UT_compile; -+ address_size = 0; /* Will be read later. */ -+ } -+ - /* debug_abbrev_offset */ - debug_abbrev_offset = get_Dwarfish_UWord( c, cc->is_dw64 ); - if (debug_abbrev_offset >= escn_debug_abbv.szB) -@@ -1035,7 +1159,9 @@ void parse_CU_Header ( /*OUT*/CUConst* cc, - give up. This makes it safe to assume elsewhere that - DW_FORM_addr and DW_FORM_ref_addr can be treated as a host - word. */ -- address_size = get_UChar( c ); -+ if (cc->version < 5) -+ address_size = get_UChar( c ); -+ - if (address_size != sizeof(void*)) - cc->barf( "parse_CU_Header: invalid address_size" ); - TRACE_D3(" Pointer Size: %d\n", (Int)address_size ); -@@ -1043,7 +1169,7 @@ void parse_CU_Header ( /*OUT*/CUConst* cc, - cc->is_type_unit = type_unit; - cc->is_alt_info = alt_info; - -- if (type_unit) { -+ if (type_unit || (cc->version >= 5 && unit_type == DW_UT_type)) { - cc->type_signature = get_ULong( c ); - cc->type_offset = get_Dwarfish_UWord( c, cc->is_dw64 ); - } -@@ -1130,8 +1256,9 @@ typedef - static - void get_Form_contents ( /*OUT*/FormContents* cts, - const CUConst* cc, Cursor* c, -- Bool td3, DW_FORM form ) -+ Bool td3, const name_form *abbv ) - { -+ DW_FORM form = abbv->at_form; - VG_(bzero_inline)(cts, sizeof(*cts)); - // !!! keep switch in sync with get_Form_szB. The nr of characters read below - // must be computed similarly in get_Form_szB. -@@ -1157,6 +1284,19 @@ void get_Form_contents ( /*OUT*/FormContents* cts, - cts->szB = 8; - TRACE_D3("%llu", cts->u.val); - break; -+ case DW_FORM_data16: { -+ /* This is more like a block than an integral value. */ -+ ULong u64b; -+ DiCursor data16 = get_DiCursor_from_Cursor(c); -+ TRACE_D3("data16: "); -+ for (u64b = 16; u64b > 0; u64b--) { -+ UChar u8 = get_UChar(c); -+ TRACE_D3("%x ", (UInt)u8); -+ } -+ cts->u.cur = data16; -+ cts->szB = - (Long)16; -+ break; -+ } - case DW_FORM_sec_offset: - cts->u.val = (ULong)get_Dwarfish_UWord( c, cc->is_dw64 ); - cts->szB = cc->is_dw64 ? 8 : 4; -@@ -1242,6 +1382,26 @@ void get_Form_contents ( /*OUT*/FormContents* cts, - cts->szB = - (Long)(1 + (ULong)ML_(cur_strlen)(str)); - break; - } -+ case DW_FORM_line_strp: { -+ /* this is an offset into .debug_line_str */ -+ UWord uw = (UWord)get_Dwarfish_UWord( c, cc->is_dw64 ); -+ if (!ML_(sli_is_valid)(cc->escn_debug_line_str) -+ || uw >= cc->escn_debug_line_str.szB) -+ cc->barf("get_Form_contents: DW_FORM_line_strp " -+ "points outside .debug_line_str"); -+ /* FIXME: check the entire string lies inside debug_line_str, -+ not just the first byte of it. */ -+ DiCursor line_str -+ = ML_(cur_plus)( ML_(cur_from_sli)(cc->escn_debug_line_str), uw ); -+ if (TD3) { -+ HChar* tmp = ML_(cur_read_strdup)(line_str, "di.getFC.1.5"); -+ TRACE_D3("(indirect line string, offset: 0x%lx): %s", uw, tmp); -+ ML_(dinfo_free)(tmp); -+ } -+ cts->u.cur = line_str; -+ cts->szB = - (Long)(1 + (ULong)ML_(cur_strlen)(line_str)); -+ break; -+ } - case DW_FORM_string: { - DiCursor str = get_AsciiZ(c); - if (TD3) { -@@ -1307,6 +1467,11 @@ void get_Form_contents ( /*OUT*/FormContents* cts, - cts->u.val = 1; - cts->szB = 1; - break; -+ case DW_FORM_implicit_const: -+ cts->u.val = (ULong)abbv->at_val; -+ cts->szB = 8; -+ TRACE_D3("%llu", cts->u.val); -+ break; - case DW_FORM_block1: { - ULong u64b; - ULong u64 = (ULong)get_UChar(c); -@@ -1396,9 +1561,14 @@ void get_Form_contents ( /*OUT*/FormContents* cts, - cts->szB = sizeof(UWord); - break; - } -- case DW_FORM_indirect: -- get_Form_contents (cts, cc, c, td3, (DW_FORM)get_ULEB128(c)); -+ case DW_FORM_indirect: { -+ /* Urgh, this is ugly and somewhat unclear how it works -+ with DW_FORM_implicit_const. HACK. */ -+ name_form nfi = *abbv; -+ nfi.at_form = (DW_FORM)get_ULEB128(c); -+ get_Form_contents (cts, cc, c, td3, &nfi); - return; -+ } - - case DW_FORM_GNU_ref_alt: - cts->u.val = get_Dwarfish_UWord(c, cc->is_dw64); -@@ -1471,6 +1641,7 @@ UInt get_Form_szB (const CUConst* cc, DW_FORM form ) - case DW_FORM_data2: return 2; - case DW_FORM_data4: return 4; - case DW_FORM_data8: return 8; -+ case DW_FORM_data16: return 16; - case DW_FORM_sec_offset: - if (cc->is_dw64) - return 8; -@@ -1488,6 +1659,7 @@ UInt get_Form_szB (const CUConst* cc, DW_FORM form ) - else - return sizeof_Dwarfish_UWord (cc->is_dw64); - case DW_FORM_strp: -+ case DW_FORM_line_strp: - return sizeof_Dwarfish_UWord (cc->is_dw64); - case DW_FORM_string: - return VARSZ_FORM; -@@ -1522,6 +1694,8 @@ UInt get_Form_szB (const CUConst* cc, DW_FORM form ) - return sizeof_Dwarfish_UWord(cc->is_dw64); - case DW_FORM_GNU_strp_alt: - return sizeof_Dwarfish_UWord(cc->is_dw64); -+ case DW_FORM_implicit_const: -+ return 0; /* Value inside abbrev. */ - default: - VG_(printf)( - "get_Form_szB: unhandled %u (%s)\n", -@@ -1544,13 +1718,13 @@ void skip_DIE (UWord *sibling, - while (True) { - if (abbv->nf[nf_i].at_name == DW_AT_sibling) { - get_Form_contents( &cts, cc, c_die, False /*td3*/, -- (DW_FORM)abbv->nf[nf_i].at_form ); -+ &abbv->nf[nf_i] ); - if ( cts.szB > 0 ) - *sibling = cts.u.val; - nf_i++; - } else if (abbv->nf[nf_i].skip_szB == VARSZ_FORM) { - get_Form_contents( &cts, cc, c_die, False /*td3*/, -- (DW_FORM)abbv->nf[nf_i].at_form ); -+ &abbv->nf[nf_i] ); - nf_i++; - } else { - advance_position_of_Cursor (c_die, (ULong)abbv->nf[nf_i].skip_szB); -@@ -1778,6 +1952,124 @@ static GExpr* get_GX ( const CUConst* cc, Bool td3, const FormContents* cts ) - return gexpr; - } - -+static -+HChar * get_line_str (struct _DebugInfo* di, Bool is_dw64, -+ Cursor *data, const UInt form, -+ DiSlice debugstr_img, DiSlice debuglinestr_img) -+{ -+ HChar *str = NULL; -+ switch (form) { -+ case DW_FORM_string: { -+ DiCursor distr = get_AsciiZ(data); -+ str = ML_(cur_step_strdup)(&distr, "di.gls.string"); -+ break; -+ } -+ case DW_FORM_strp: { -+ UWord uw = (UWord)get_Dwarfish_UWord( data, is_dw64 ); -+ DiCursor distr -+ = ML_(cur_plus)( ML_(cur_from_sli)(debugstr_img), uw ); -+ str = ML_(cur_read_strdup)(distr, "di.gls.strp"); -+ break; -+ } -+ case DW_FORM_line_strp: { -+ UWord uw = (UWord)get_Dwarfish_UWord( data, is_dw64 ); -+ DiCursor distr -+ = ML_(cur_plus)( ML_(cur_from_sli)(debuglinestr_img), uw ); -+ str = ML_(cur_read_strdup)(distr, "di.gls.line_strp"); -+ break; -+ } -+ default: -+ ML_(symerr)(di, True, -+ "Unknown path string FORM in .debug_line"); -+ break; -+ } -+ return str; -+} -+ -+static -+Int get_line_ndx (struct _DebugInfo* di, -+ Cursor *data, const UInt form) -+{ -+ Int res = 0; -+ switch (form) { -+ case DW_FORM_data1: -+ res = get_UChar(data); -+ break; -+ case DW_FORM_data2: -+ res = get_UShort(data); -+ break; -+ case DW_FORM_udata: -+ res = get_ULEB128(data); -+ break; -+ default: -+ ML_(symerr)(di, True, -+ "Unknown directory_index value FORM in .debug_line"); -+ break; -+ } -+ return res; -+} -+ -+static -+void skip_line_form (struct _DebugInfo* di, Bool is_dw64, -+ Cursor *d, const UInt form) -+{ -+ switch (form) { -+ case DW_FORM_block: { -+ ULong len = get_ULEB128(d); -+ advance_position_of_Cursor (d, len); -+ break; -+ } -+ case DW_FORM_block1: { -+ UChar len = get_UChar(d); -+ advance_position_of_Cursor (d, len); -+ break; -+ } -+ case DW_FORM_block2: { -+ UShort len = get_UShort(d); -+ advance_position_of_Cursor (d, len); -+ break; -+ } -+ case DW_FORM_block4: { -+ UInt len = get_UInt(d); -+ advance_position_of_Cursor (d, len); -+ break; -+ } -+ case DW_FORM_flag: -+ case DW_FORM_data1: -+ advance_position_of_Cursor (d, 1); -+ break; -+ case DW_FORM_data2: -+ advance_position_of_Cursor (d, 2); -+ break; -+ case DW_FORM_data4: -+ advance_position_of_Cursor (d, 4); -+ break; -+ case DW_FORM_data8: -+ advance_position_of_Cursor (d, 8); -+ break; -+ case DW_FORM_data16: -+ advance_position_of_Cursor (d, 16); -+ break; -+ case DW_FORM_string: -+ (void)get_AsciiZ (d); -+ break; -+ case DW_FORM_strp: -+ case DW_FORM_line_strp: -+ case DW_FORM_sec_offset: -+ advance_position_of_Cursor (d, is_dw64 ? 8 : 4); -+ break; -+ case DW_FORM_udata: -+ (void)get_ULEB128(d); -+ break; -+ case DW_FORM_sdata: -+ (void)get_SLEB128(d); -+ break; -+ default: -+ ML_(symerr)(di, True, "Unknown FORM in .debug_line"); -+ break; -+ } -+} -+ - /* Returns an xarray* of directory names (indexed by the dwarf dirname - integer). - If 'compdir' is NULL, entry [0] will be set to "." -@@ -1786,8 +2078,8 @@ static GExpr* get_GX ( const CUConst* cc, Bool td3, const FormContents* cts ) - whatever that means, according to the DWARF3 spec. - FIXME??? readdwarf3.c/readdwarf.c have a lot of duplicated code */ - static --XArray* read_dirname_xa (DebugInfo* di, const HChar *compdir, -- Cursor *c, -+XArray* read_dirname_xa (DebugInfo* di, UShort version, const HChar *compdir, -+ Cursor *c, const CUConst *cc, - Bool td3 ) - { - XArray* dirname_xa; /* xarray of HChar* dirname */ -@@ -1804,51 +2096,121 @@ XArray* read_dirname_xa (DebugInfo* di, const HChar *compdir, - dirname = compdir; - compdir_len = VG_(strlen)(compdir); - } -- VG_(addToXA) (dirname_xa, &dirname); -- -- TRACE_D3(" The Directory Table%s\n", -- peek_UChar(c) == 0 ? " is empty." : ":" ); -- -- while (peek_UChar(c) != 0) { -- -- DiCursor cur = get_AsciiZ(c); -- HChar* data_str = ML_(cur_read_strdup)( cur, "dirname_xa.1" ); -- TRACE_D3(" %s\n", data_str); -- -- /* If data_str[0] is '/', then 'data' is an absolute path and we -- don't mess with it. Otherwise, construct the -- path 'compdir' ++ "/" ++ 'data'. */ -- -- if (data_str[0] != '/' -- /* not an absolute path */ -- && compdir -- /* actually got something sensible for compdir */ -- && compdir_len) -- { -- SizeT len = compdir_len + 1 + VG_(strlen)(data_str); -- HChar *buf = ML_(dinfo_zalloc)("dirname_xa.2", len + 1); -- -- VG_(strcpy)(buf, compdir); -- VG_(strcat)(buf, "/"); -- VG_(strcat)(buf, data_str); -- -- dirname = ML_(addStr)(di, buf, len); -- VG_(addToXA) (dirname_xa, &dirname); -- if (0) VG_(printf)("rel path %s\n", buf); -- ML_(dinfo_free)(buf); -- } else { -- /* just use 'data'. */ -- dirname = ML_(addStr)(di,data_str,-1); -- VG_(addToXA) (dirname_xa, &dirname); -- if (0) VG_(printf)("abs path %s\n", data_str); -+ -+ /* For version 5, the compdir is the first (zero) entry. */ -+ if (version < 5) -+ VG_(addToXA) (dirname_xa, &dirname); -+ -+ if (version < 5) { -+ TRACE_D3("The Directory Table%s\n", -+ peek_UChar(c) == 0 ? " is empty." : ":" ); -+ -+ while (peek_UChar(c) != 0) { -+ -+ DiCursor cur = get_AsciiZ(c); -+ HChar* data_str = ML_(cur_read_strdup)( cur, "dirname_xa.1" ); -+ TRACE_D3(" %s\n", data_str); -+ -+ /* If data_str[0] is '/', then 'data' is an absolute path and we -+ don't mess with it. Otherwise, construct the -+ path 'compdir' ++ "/" ++ 'data'. */ -+ -+ if (data_str[0] != '/' -+ /* not an absolute path */ -+ && compdir -+ /* actually got something sensible for compdir */ -+ && compdir_len) -+ { -+ SizeT len = compdir_len + 1 + VG_(strlen)(data_str); -+ HChar *buf = ML_(dinfo_zalloc)("dirname_xa.2", len + 1); -+ -+ VG_(strcpy)(buf, compdir); -+ VG_(strcat)(buf, "/"); -+ VG_(strcat)(buf, data_str); -+ -+ dirname = ML_(addStr)(di, buf, len); -+ VG_(addToXA) (dirname_xa, &dirname); -+ if (0) VG_(printf)("rel path %s\n", buf); -+ ML_(dinfo_free)(buf); -+ } else { -+ /* just use 'data'. */ -+ dirname = ML_(addStr)(di,data_str,-1); -+ VG_(addToXA) (dirname_xa, &dirname); -+ if (0) VG_(printf)("abs path %s\n", data_str); -+ } -+ -+ ML_(dinfo_free)(data_str); -+ } -+ } else { -+ UChar forms[256]; -+ UChar p_ndx = 0; -+ UInt directories_count; -+ UChar directory_entry_format_count; -+ UInt n; -+ DiSlice debugstr_img = cc->escn_debug_str; -+ DiSlice debuglinestr_img = cc->escn_debug_line_str; -+ -+ directory_entry_format_count = get_UChar(c); -+ for (n = 0; n < directory_entry_format_count; n++) { -+ UInt lnct = get_ULEB128(c); -+ UInt form = get_ULEB128(c); -+ if (lnct == DW_LNCT_path) -+ p_ndx = n; -+ forms[n] = form; - } -+ directories_count = get_ULEB128(c); -+ TRACE_D3("The Directory Table%s\n", -+ directories_count == 0 ? " is empty." : ":" ); -+ -+ for (n = 0; n < directories_count; n++) { -+ UInt f; -+ for (f = 0; f < directory_entry_format_count; f++) { -+ UInt form = forms[f]; -+ if (f == p_ndx) { -+ HChar *data_str = get_line_str (di, cc->is_dw64, c, form, -+ debugstr_img, -+ debuglinestr_img); -+ TRACE_D3(" %s\n", data_str); -+ -+ /* If data_str[0] is '/', then 'data' is an absolute path and we -+ don't mess with it. Otherwise, construct the -+ path 'compdir' ++ "/" ++ 'data'. */ -+ -+ if (data_str[0] != '/' -+ /* not an absolute path */ -+ && compdir -+ /* actually got something sensible for compdir */ -+ && compdir_len) -+ { -+ SizeT len = compdir_len + 1 + VG_(strlen)(data_str); -+ HChar *buf = ML_(dinfo_zalloc)("dirname_xa.2", len + 1); -+ -+ VG_(strcpy)(buf, compdir); -+ VG_(strcat)(buf, "/"); -+ VG_(strcat)(buf, data_str); -+ -+ dirname = ML_(addStr)(di, buf, len); -+ VG_(addToXA) (dirname_xa, &dirname); -+ if (0) VG_(printf)("rel path %s\n", buf); -+ ML_(dinfo_free)(buf); -+ } else { -+ /* just use 'data'. */ -+ dirname = ML_(addStr)(di,data_str,-1); -+ VG_(addToXA) (dirname_xa, &dirname); -+ if (0) VG_(printf)("abs path %s\n", data_str); -+ } - -- ML_(dinfo_free)(data_str); -+ ML_(dinfo_free)(data_str); -+ } else { -+ skip_line_form (di, cc->is_dw64, c, form); -+ } -+ } -+ } - } - - TRACE_D3 ("\n"); - -- if (get_UChar (c) != 0) { -+ if (version < 5 && get_UChar (c) != 0) { - ML_(symerr)(NULL, True, - "could not get NUL at end of DWARF directory table"); - VG_(deleteXA)(dirname_xa); -@@ -1888,9 +2250,13 @@ void read_filename_table( /*MOD*/XArray* /* of UInt* */ fndn_ix_Table, - get_Initial_Length( &is_dw64, &c, - "read_filename_table: invalid initial-length field" ); - version = get_UShort( &c ); -- if (version != 2 && version != 3 && version != 4) -- cc->barf("read_filename_table: Only DWARF version 2, 3 and 4 line info " -- "is currently supported."); -+ if (version != 2 && version != 3 && version != 4 && version != 5) -+ cc->barf("read_filename_table: Only DWARF version 2, 3, 4 and 5 " -+ "line info is currently supported."); -+ if (version >= 5) { -+ /* addrs_size = */ get_UChar( &c ); -+ /* seg_size = */ get_UChar( &c ); -+ } - /*header_length = (ULong)*/ get_Dwarfish_UWord( &c, is_dw64 ); - /*minimum_instruction_length = */ get_UChar( &c ); - if (version >= 4) -@@ -1903,30 +2269,77 @@ void read_filename_table( /*MOD*/XArray* /* of UInt* */ fndn_ix_Table, - for (i = 1; i < (Word)opcode_base; i++) - (void)get_UChar( &c ); - -- dirname_xa = read_dirname_xa(cc->di, compdir, &c, td3); -+ dirname_xa = read_dirname_xa(cc->di, version, compdir, &c, cc, td3); - - /* Read and record the file names table */ - vg_assert( VG_(sizeXA)( fndn_ix_Table ) == 0 ); -- /* Add a dummy index-zero entry. DWARF3 numbers its files -- from 1, for some reason. */ -- fndn_ix = ML_(addFnDn) ( cc->di, "", NULL ); -- VG_(addToXA)( fndn_ix_Table, &fndn_ix ); -- while (peek_UChar(&c) != 0) { -- DiCursor cur = get_AsciiZ(&c); -- str = ML_(addStrFromCursor)( cc->di, cur ); -- dir_xa_ix = get_ULEB128( &c ); -- if (dirname_xa != NULL -- && dir_xa_ix >= 0 && dir_xa_ix < VG_(sizeXA) (dirname_xa)) -- dirname = *(HChar**)VG_(indexXA) ( dirname_xa, dir_xa_ix ); -- else -- dirname = NULL; -- fndn_ix = ML_(addFnDn)( cc->di, str, dirname); -- TRACE_D3(" read_filename_table: %ld fndn_ix %u %s %s\n", -- VG_(sizeXA)(fndn_ix_Table), fndn_ix, -- dirname, str); -+ if (version < 5) { -+ /* Add a dummy index-zero entry. DWARF3 numbers its files -+ from 1, for some reason. */ -+ fndn_ix = ML_(addFnDn) ( cc->di, "", NULL ); - VG_(addToXA)( fndn_ix_Table, &fndn_ix ); -- (void)get_ULEB128( &c ); /* skip last mod time */ -- (void)get_ULEB128( &c ); /* file size */ -+ while (peek_UChar(&c) != 0) { -+ DiCursor cur = get_AsciiZ(&c); -+ str = ML_(addStrFromCursor)( cc->di, cur ); -+ dir_xa_ix = get_ULEB128( &c ); -+ if (dirname_xa != NULL -+ && dir_xa_ix >= 0 && dir_xa_ix < VG_(sizeXA) (dirname_xa)) -+ dirname = *(HChar**)VG_(indexXA) ( dirname_xa, dir_xa_ix ); -+ else -+ dirname = NULL; -+ fndn_ix = ML_(addFnDn)( cc->di, str, dirname); -+ TRACE_D3(" read_filename_table: %ld fndn_ix %u %s %s\n", -+ VG_(sizeXA)(fndn_ix_Table), fndn_ix, -+ dirname, str); -+ VG_(addToXA)( fndn_ix_Table, &fndn_ix ); -+ (void)get_ULEB128( &c ); /* skip last mod time */ -+ (void)get_ULEB128( &c ); /* file size */ -+ } -+ } else { -+ UChar forms[256]; -+ UChar p_ndx = 0, d_ndx = 0; -+ UInt file_names_count; -+ UChar file_names_entry_format_count; -+ UInt n; -+ DiSlice debugstr_img = cc->escn_debug_str; -+ DiSlice debuglinestr_img = cc->escn_debug_line_str; -+ file_names_entry_format_count = get_UChar( &c ); -+ for (n = 0; n < file_names_entry_format_count; n++) { -+ UInt lnct = get_ULEB128( &c ); -+ UInt form = get_ULEB128( &c ); -+ if (lnct == DW_LNCT_path) -+ p_ndx = n; -+ if (lnct == DW_LNCT_directory_index) -+ d_ndx = n; -+ forms[n] = form; -+ } -+ file_names_count = get_ULEB128( &c ); -+ for (n = 0; n < file_names_count; n++) { -+ UInt f; -+ dir_xa_ix = 0; -+ str = NULL; -+ for (f = 0; f < file_names_entry_format_count; f++) { -+ UInt form = forms[f]; -+ if (f == p_ndx) -+ str = get_line_str (cc->di, cc->is_dw64, &c, form, -+ debugstr_img, debuglinestr_img); -+ else if (n == d_ndx) -+ dir_xa_ix = get_line_ndx (cc->di, &c, form); -+ else -+ skip_line_form (cc->di, cc->is_dw64, &c, form); -+ } -+ -+ if (dirname_xa != NULL -+ && dir_xa_ix >= 0 && dir_xa_ix < VG_(sizeXA) (dirname_xa)) -+ dirname = *(HChar**)VG_(indexXA) ( dirname_xa, dir_xa_ix ); -+ else -+ dirname = NULL; -+ fndn_ix = ML_(addFnDn)( cc->di, str, dirname); -+ TRACE_D3(" read_filename_table: %ld fndn_ix %u %s %s\n", -+ VG_(sizeXA)(fndn_ix_Table), fndn_ix, -+ dirname, str); -+ VG_(addToXA)( fndn_ix_Table, &fndn_ix ); -+ } - } - /* We're done! The rest of it is not interesting. */ - if (dirname_xa != NULL) -@@ -2011,11 +2424,12 @@ static void trace_DIE( - while (True) { - DW_AT attr = (DW_AT) abbv->nf[nf_i].at_name; - DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form; -+ const name_form *nf = &abbv->nf[nf_i]; - nf_i++; - if (attr == 0 && form == 0) break; - VG_(printf)(" %-18s: ", ML_(pp_DW_AT)(attr)); - /* Get the form contents, so as to print them */ -- get_Form_contents( &cts, cc, &c, True, form ); -+ get_Form_contents( &cts, cc, &c, True, nf ); - if (attr == DW_AT_sibling && cts.szB > 0) { - sibling = cts.u.val; - } -@@ -2094,9 +2508,10 @@ static void parse_var_DIE ( - while (True) { - DW_AT attr = (DW_AT) abbv->nf[nf_i].at_name; - DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form; -+ const name_form *nf = &abbv->nf[nf_i]; - nf_i++; - if (attr == 0 && form == 0) break; -- get_Form_contents( &cts, cc, c_die, False/*td3*/, form ); -+ get_Form_contents( &cts, cc, c_die, False/*td3*/, nf ); - if (attr == DW_AT_low_pc && cts.szB > 0) { - ip_lo = cts.u.val; - have_lo = True; -@@ -2196,9 +2611,10 @@ static void parse_var_DIE ( - while (True) { - DW_AT attr = (DW_AT) abbv->nf[nf_i].at_name; - DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form; -+ const name_form *nf = &abbv->nf[nf_i]; - nf_i++; - if (attr == 0 && form == 0) break; -- get_Form_contents( &cts, cc, c_die, False/*td3*/, form ); -+ get_Form_contents( &cts, cc, c_die, False/*td3*/, nf ); - if (attr == DW_AT_low_pc && cts.szB > 0) { - ip_lo = cts.u.val; - have_lo = True; -@@ -2282,9 +2698,10 @@ static void parse_var_DIE ( - while (True) { - DW_AT attr = (DW_AT) abbv->nf[nf_i].at_name; - DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form; -+ const name_form *nf = &abbv->nf[nf_i]; - nf_i++; - if (attr == 0 && form == 0) break; -- get_Form_contents( &cts, cc, c_die, False/*td3*/, form ); -+ get_Form_contents( &cts, cc, c_die, False/*td3*/, nf ); - n_attrs++; - if (attr == DW_AT_name && cts.szB < 0) { - name = ML_(addStrFromCursor)( cc->di, cts.u.cur ); -@@ -2646,9 +3063,10 @@ static const HChar* get_inlFnName (Int absori, const CUConst* cc, Bool td3) - while (True) { - DW_AT attr = (DW_AT) abbv->nf[nf_i].at_name; - DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form; -+ const name_form *nf = &abbv->nf[nf_i]; - nf_i++; - if (attr == 0 && form == 0) break; -- get_Form_contents( &cts, cc, &c, False/*td3*/, form ); -+ get_Form_contents( &cts, cc, &c, False/*td3*/, nf ); - if (attr == DW_AT_name) { - HChar *fnname; - if (cts.szB >= 0) -@@ -2720,9 +3138,10 @@ static Bool parse_inl_DIE ( - while (True) { - DW_AT attr = (DW_AT) abbv->nf[nf_i].at_name; - DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form; -+ const name_form *nf = &abbv->nf[nf_i]; - nf_i++; - if (attr == 0 && form == 0) break; -- get_Form_contents( &cts, cc, c_die, False/*td3*/, form ); -+ get_Form_contents( &cts, cc, c_die, False/*td3*/, nf ); - if (attr == DW_AT_low_pc && cts.szB > 0) { - ip_lo = cts.u.val; - have_lo = True; -@@ -2764,9 +3183,10 @@ static Bool parse_inl_DIE ( - while (True) { - DW_AT attr = (DW_AT) abbv->nf[nf_i].at_name; - DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form; -+ const name_form *nf = &abbv->nf[nf_i]; - nf_i++; - if (attr == 0 && form == 0) break; -- get_Form_contents( &cts, cc, c_die, False/*td3*/, form ); -+ get_Form_contents( &cts, cc, c_die, False/*td3*/, nf ); - if (attr == DW_AT_call_file && cts.szB > 0) { - Int ftabIx = (Int)cts.u.val; - if (ftabIx >= 1 -@@ -3090,9 +3510,10 @@ static void parse_type_DIE ( /*MOD*/XArray* /* of TyEnt */ tyents, - while (True) { - DW_AT attr = (DW_AT) abbv->nf[nf_i].at_name; - DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form; -+ const name_form *nf = &abbv->nf[nf_i]; - nf_i++; - if (attr == 0 && form == 0) break; -- get_Form_contents( &cts, cc, c_die, False/*td3*/, form ); -+ get_Form_contents( &cts, cc, c_die, False/*td3*/, nf ); - if (attr != DW_AT_language) - continue; - if (cts.szB <= 0) -@@ -3132,9 +3553,10 @@ static void parse_type_DIE ( /*MOD*/XArray* /* of TyEnt */ tyents, - while (True) { - DW_AT attr = (DW_AT) abbv->nf[nf_i].at_name; - DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form; -+ const name_form *nf = &abbv->nf[nf_i]; - nf_i++; - if (attr == 0 && form == 0) break; -- get_Form_contents( &cts, cc, c_die, False/*td3*/, form ); -+ get_Form_contents( &cts, cc, c_die, False/*td3*/, nf ); - if (attr == DW_AT_name && cts.szB < 0) { - typeE.Te.TyBase.name - = ML_(cur_read_strdup)( cts.u.cur, -@@ -3243,9 +3665,10 @@ static void parse_type_DIE ( /*MOD*/XArray* /* of TyEnt */ tyents, - while (True) { - DW_AT attr = (DW_AT) abbv->nf[nf_i].at_name; - DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form; -+ const name_form *nf = &abbv->nf[nf_i]; - nf_i++; - if (attr == 0 && form == 0) break; -- get_Form_contents( &cts, cc, c_die, False/*td3*/, form ); -+ get_Form_contents( &cts, cc, c_die, False/*td3*/, nf ); - if (attr == DW_AT_byte_size && cts.szB > 0) { - typeE.Te.TyPorR.szB = cts.u.val; - } -@@ -3275,9 +3698,10 @@ static void parse_type_DIE ( /*MOD*/XArray* /* of TyEnt */ tyents, - while (True) { - DW_AT attr = (DW_AT) abbv->nf[nf_i].at_name; - DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form; -+ const name_form *nf = &abbv->nf[nf_i]; - nf_i++; - if (attr == 0 && form == 0) break; -- get_Form_contents( &cts, cc, c_die, False/*td3*/, form ); -+ get_Form_contents( &cts, cc, c_die, False/*td3*/, nf ); - if (attr == DW_AT_name && cts.szB < 0) { - typeE.Te.TyEnum.name - = ML_(cur_read_strdup)( cts.u.cur, -@@ -3356,9 +3780,10 @@ static void parse_type_DIE ( /*MOD*/XArray* /* of TyEnt */ tyents, - while (True) { - DW_AT attr = (DW_AT) abbv->nf[nf_i].at_name; - DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form; -+ const name_form *nf = &abbv->nf[nf_i]; - nf_i++; - if (attr == 0 && form == 0) break; -- get_Form_contents( &cts, cc, c_die, False/*td3*/, form ); -+ get_Form_contents( &cts, cc, c_die, False/*td3*/, nf ); - if (attr == DW_AT_name && cts.szB < 0) { - atomE.Te.Atom.name - = ML_(cur_read_strdup)( cts.u.cur, -@@ -3411,9 +3836,10 @@ static void parse_type_DIE ( /*MOD*/XArray* /* of TyEnt */ tyents, - while (True) { - DW_AT attr = (DW_AT) abbv->nf[nf_i].at_name; - DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form; -+ const name_form *nf = &abbv->nf[nf_i]; - nf_i++; - if (attr == 0 && form == 0) break; -- get_Form_contents( &cts, cc, c_die, False/*td3*/, form ); -+ get_Form_contents( &cts, cc, c_die, False/*td3*/, nf ); - if (attr == DW_AT_name && cts.szB < 0) { - typeE.Te.TyStOrUn.name - = ML_(cur_read_strdup)( cts.u.cur, -@@ -3498,9 +3924,10 @@ static void parse_type_DIE ( /*MOD*/XArray* /* of TyEnt */ tyents, - while (True) { - DW_AT attr = (DW_AT) abbv->nf[nf_i].at_name; - DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form; -+ const name_form *nf = &abbv->nf[nf_i]; - nf_i++; - if (attr == 0 && form == 0) break; -- get_Form_contents( &cts, cc, c_die, False/*td3*/, form ); -+ get_Form_contents( &cts, cc, c_die, False/*td3*/, nf ); - if (attr == DW_AT_name && cts.szB < 0) { - fieldE.Te.Field.name - = ML_(cur_read_strdup)( cts.u.cur, -@@ -3585,9 +4012,10 @@ static void parse_type_DIE ( /*MOD*/XArray* /* of TyEnt */ tyents, - while (True) { - DW_AT attr = (DW_AT) abbv->nf[nf_i].at_name; - DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form; -+ const name_form *nf = &abbv->nf[nf_i]; - nf_i++; - if (attr == 0 && form == 0) break; -- get_Form_contents( &cts, cc, c_die, False/*td3*/, form ); -+ get_Form_contents( &cts, cc, c_die, False/*td3*/, nf ); - if (attr == DW_AT_type && cts.szB > 0) { - typeE.Te.TyArray.typeR - = cook_die_using_form( cc, (UWord)cts.u.val, form ); -@@ -3626,9 +4054,10 @@ static void parse_type_DIE ( /*MOD*/XArray* /* of TyEnt */ tyents, - while (True) { - DW_AT attr = (DW_AT) abbv->nf[nf_i].at_name; - DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form; -+ const name_form *nf = &abbv->nf[nf_i]; - nf_i++; - if (attr == 0 && form == 0) break; -- get_Form_contents( &cts, cc, c_die, False/*td3*/, form ); -+ get_Form_contents( &cts, cc, c_die, False/*td3*/, nf ); - if (attr == DW_AT_lower_bound && cts.szB > 0 - && form_expected_for_bound (form)) { - lower = (Long)cts.u.val; -@@ -3714,9 +4143,10 @@ static void parse_type_DIE ( /*MOD*/XArray* /* of TyEnt */ tyents, - while (True) { - DW_AT attr = (DW_AT) abbv->nf[nf_i].at_name; - DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form; -+ const name_form *nf = &abbv->nf[nf_i]; - nf_i++; - if (attr == 0 && form == 0) break; -- get_Form_contents( &cts, cc, c_die, False/*td3*/, form ); -+ get_Form_contents( &cts, cc, c_die, False/*td3*/, nf ); - if (attr == DW_AT_name && cts.szB < 0) { - typeE.Te.TyTyDef.name - = ML_(cur_read_strdup)( cts.u.cur, -@@ -3764,9 +4194,10 @@ static void parse_type_DIE ( /*MOD*/XArray* /* of TyEnt */ tyents, - while (True) { - DW_AT attr = (DW_AT) abbv->nf[nf_i].at_name; - DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form; -+ const name_form *nf = &abbv->nf[nf_i]; - nf_i++; - if (attr == 0 && form == 0) break; -- get_Form_contents( &cts, cc, c_die, False/*td3*/, form ); -+ get_Form_contents( &cts, cc, c_die, False/*td3*/, nf ); - if (attr == DW_AT_type && cts.szB > 0) { - typeE.Te.TyQual.typeR - = cook_die_using_form( cc, (UWord)cts.u.val, form ); -@@ -4486,6 +4917,9 @@ static void trace_debug_abbrev (const DebugInfo* di, - while (True) { - ULong at_name = get_ULEB128( &abbv ); - ULong at_form = get_ULEB128( &abbv ); -+ if (at_form == DW_FORM_implicit_const) { -+ /* Long at_val = */ get_SLEB128 ( &abbv ); -+ } - if (at_name == 0 && at_form == 0) break; - TRACE_D3(" %-18s %s\n", - ML_(pp_DW_AT)(at_name), ML_(pp_DW_FORM)(at_form)); -@@ -4502,9 +4936,10 @@ void new_dwarf3_reader_wrk ( - DiSlice escn_debug_info, DiSlice escn_debug_types, - DiSlice escn_debug_abbv, DiSlice escn_debug_line, - DiSlice escn_debug_str, DiSlice escn_debug_ranges, -+ DiSlice escn_debug_rnglists, DiSlice escn_debug_loclists, - DiSlice escn_debug_loc, DiSlice escn_debug_info_alt, - DiSlice escn_debug_abbv_alt, DiSlice escn_debug_line_alt, -- DiSlice escn_debug_str_alt -+ DiSlice escn_debug_str_alt, DiSlice escn_debug_line_str - ) - { - XArray* /* of TyEnt */ tyents = NULL; -@@ -4738,6 +5173,8 @@ void new_dwarf3_reader_wrk ( - cc.escn_debug_str = pass == 0 ? escn_debug_str_alt - : escn_debug_str; - cc.escn_debug_ranges = escn_debug_ranges; -+ cc.escn_debug_rnglists = escn_debug_rnglists; -+ cc.escn_debug_loclists = escn_debug_loclists; - cc.escn_debug_loc = escn_debug_loc; - cc.escn_debug_line = pass == 0 ? escn_debug_line_alt - : escn_debug_line; -@@ -4746,6 +5183,7 @@ void new_dwarf3_reader_wrk ( - cc.escn_debug_types = escn_debug_types; - cc.escn_debug_info_alt = escn_debug_info_alt; - cc.escn_debug_str_alt = escn_debug_str_alt; -+ cc.escn_debug_line_str = escn_debug_line_str; - cc.types_cuOff_bias = escn_debug_info.szB; - cc.alt_cuOff_bias = escn_debug_info.szB + escn_debug_types.szB; - cc.cu_start_offset = cu_start_offset; -@@ -5216,9 +5654,10 @@ ML_(new_dwarf3_reader) ( - DiSlice escn_debug_info, DiSlice escn_debug_types, - DiSlice escn_debug_abbv, DiSlice escn_debug_line, - DiSlice escn_debug_str, DiSlice escn_debug_ranges, -+ DiSlice escn_debug_rnglists, DiSlice escn_debug_loclists, - DiSlice escn_debug_loc, DiSlice escn_debug_info_alt, - DiSlice escn_debug_abbv_alt, DiSlice escn_debug_line_alt, -- DiSlice escn_debug_str_alt -+ DiSlice escn_debug_str_alt, DiSlice escn_debug_line_str - ) - { - volatile Int jumped; -@@ -5239,9 +5678,10 @@ ML_(new_dwarf3_reader) ( - escn_debug_info, escn_debug_types, - escn_debug_abbv, escn_debug_line, - escn_debug_str, escn_debug_ranges, -+ escn_debug_rnglists, escn_debug_loclists, - escn_debug_loc, escn_debug_info_alt, - escn_debug_abbv_alt, escn_debug_line_alt, -- escn_debug_str_alt ); -+ escn_debug_str_alt, escn_debug_line_str ); - d3rd_jmpbuf_valid = False; - TRACE_D3("\n------ .debug_info reading was successful ------\n"); - } else { -diff --git a/coregrind/m_debuginfo/readelf.c b/coregrind/m_debuginfo/readelf.c -index bc5a732d7..404034df0 100644 ---- a/coregrind/m_debuginfo/readelf.c -+++ b/coregrind/m_debuginfo/readelf.c -@@ -2577,7 +2577,10 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) - DiSlice debug_types_escn = DiSlice_INVALID; // .debug_types (dwarf4) - DiSlice debug_abbv_escn = DiSlice_INVALID; // .debug_abbrev (dwarf2) - DiSlice debug_str_escn = DiSlice_INVALID; // .debug_str (dwarf2) -+ DiSlice debug_line_str_escn = DiSlice_INVALID; // .debug_line_str(dwarf5) - DiSlice debug_ranges_escn = DiSlice_INVALID; // .debug_ranges (dwarf2) -+ DiSlice debug_rnglists_escn = DiSlice_INVALID; // .debug_rnglists(dwarf5) -+ DiSlice debug_loclists_escn = DiSlice_INVALID; // .debug_loclists(dwarf5) - DiSlice debug_loc_escn = DiSlice_INVALID; // .debug_loc (dwarf2) - DiSlice debug_frame_escn = DiSlice_INVALID; // .debug_frame (dwarf2) - DiSlice debug_line_alt_escn = DiSlice_INVALID; // .debug_line (alt) -@@ -2683,10 +2686,22 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) - if (!ML_(sli_is_valid)(debug_str_escn)) - FIND(".zdebug_str", debug_str_escn) - -+ FIND( ".debug_line_str", debug_line_str_escn) -+ if (!ML_(sli_is_valid)(debug_line_str_escn)) -+ FIND(".zdebug_str", debug_line_str_escn) -+ - FIND( ".debug_ranges", debug_ranges_escn) - if (!ML_(sli_is_valid)(debug_ranges_escn)) - FIND(".zdebug_ranges", debug_ranges_escn) - -+ FIND( ".debug_rnglists", debug_rnglists_escn) -+ if (!ML_(sli_is_valid)(debug_rnglists_escn)) -+ FIND(".zdebug_rnglists", debug_rnglists_escn) -+ -+ FIND( ".debug_loclists", debug_loclists_escn) -+ if (!ML_(sli_is_valid)(debug_loclists_escn)) -+ FIND(".zdebug_loclists", debug_loclists_escn) -+ - FIND( ".debug_loc", debug_loc_escn) - if (!ML_(sli_is_valid)(debug_loc_escn)) - FIND(".zdebug_loc", debug_loc_escn) -@@ -2994,10 +3009,22 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) - if (!ML_(sli_is_valid)(debug_str_escn)) - FIND(need_dwarf2, ".zdebug_str", debug_str_escn) - -+ FIND( need_dwarf2, ".debug_line_str", debug_line_str_escn) -+ if (!ML_(sli_is_valid)(debug_line_str_escn)) -+ FIND(need_dwarf2, ".zdebug_line_str", debug_line_str_escn) -+ - FIND( need_dwarf2, ".debug_ranges", debug_ranges_escn) - if (!ML_(sli_is_valid)(debug_ranges_escn)) - FIND(need_dwarf2, ".zdebug_ranges", debug_ranges_escn) - -+ FIND( need_dwarf2, ".debug_rnglists", debug_rnglists_escn) -+ if (!ML_(sli_is_valid)(debug_rnglists_escn)) -+ FIND(need_dwarf2, ".zdebug_rnglists", debug_rnglists_escn) -+ -+ FIND( need_dwarf2, ".debug_loclists", debug_loclists_escn) -+ if (!ML_(sli_is_valid)(debug_loclists_escn)) -+ FIND(need_dwarf2, ".zdebug_loclists", debug_loclists_escn) -+ - FIND( need_dwarf2, ".debug_loc", debug_loc_escn) - if (!ML_(sli_is_valid)(debug_loc_escn)) - FIND(need_dwarf2, ".zdebug_loc", debug_loc_escn) -@@ -3231,7 +3258,8 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) - debug_abbv_escn, - debug_line_escn, - debug_str_escn, -- debug_str_alt_escn ); -+ debug_str_alt_escn, -+ debug_line_str_escn); - /* The new reader: read the DIEs in .debug_info to acquire - information on variable types and locations or inline info. - But only if the tool asks for it, or the user requests it on -@@ -3242,9 +3270,10 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di ) - di, debug_info_escn, debug_types_escn, - debug_abbv_escn, debug_line_escn, - debug_str_escn, debug_ranges_escn, -+ debug_rnglists_escn, debug_loclists_escn, - debug_loc_escn, debug_info_alt_escn, - debug_abbv_alt_escn, debug_line_alt_escn, -- debug_str_alt_escn -+ debug_str_alt_escn, debug_line_str_escn - ); - } - } -diff --git a/coregrind/m_debuginfo/readmacho.c b/coregrind/m_debuginfo/readmacho.c -index f39ee006f..9153a74ca 100644 ---- a/coregrind/m_debuginfo/readmacho.c -+++ b/coregrind/m_debuginfo/readmacho.c -@@ -1103,8 +1103,14 @@ Bool ML_(read_macho_debug_info)( struct _DebugInfo* di ) - = getsectdata(dsli, "__DWARF", "__debug_line", NULL); - DiSlice debug_str_mscn - = getsectdata(dsli, "__DWARF", "__debug_str", NULL); -+ DiSlice debug_line_str_mscn -+ = getsectdata(dsli, "__DWARF", "__debug_line_str", NULL); - DiSlice debug_ranges_mscn - = getsectdata(dsli, "__DWARF", "__debug_ranges", NULL); -+ DiSlice debug_rnglists_mscn -+ = getsectdata(dsli, "__DWARF", "__debug_rnglists", NULL); -+ DiSlice debug_loclists_mscn -+ = getsectdata(dsli, "__DWARF", "__debug_loclists", NULL); - DiSlice debug_loc_mscn - = getsectdata(dsli, "__DWARF", "__debug_loc", NULL); - -@@ -1145,7 +1151,8 @@ Bool ML_(read_macho_debug_info)( struct _DebugInfo* di ) - debug_abbv_mscn, - debug_line_mscn, - debug_str_mscn, -- DiSlice_INVALID /* ALT .debug_str */ ); -+ DiSlice_INVALID, /* ALT .debug_str */ -+ debug_line_str ); - - /* The new reader: read the DIEs in .debug_info to acquire - information on variable types and locations or inline info. -@@ -1160,11 +1167,14 @@ Bool ML_(read_macho_debug_info)( struct _DebugInfo* di ) - debug_line_mscn, - debug_str_mscn, - debug_ranges_mscn, -+ debug_rnglists_mscn, -+ debug_loclists_mscn, - debug_loc_mscn, - DiSlice_INVALID, /* ALT .debug_info */ - DiSlice_INVALID, /* ALT .debug_abbv */ - DiSlice_INVALID, /* ALT .debug_line */ -- DiSlice_INVALID /* ALT .debug_str */ -+ DiSlice_INVALID, /* ALT .debug_str */ -+ debug_line_str_mscn /* .debug_line_str */ - ); - } - } --- -2.18.4 - diff --git a/valgrind-3.16.1-epoll.patch b/valgrind-3.16.1-epoll.patch deleted file mode 100644 index c6a0411..0000000 --- a/valgrind-3.16.1-epoll.patch +++ /dev/null @@ -1,117 +0,0 @@ -commit f326d68d762edf4b0e9604daa446b6f8ca25725a -Author: Mark Wielaard -Date: Sun Jul 26 22:40:22 2020 +0200 - - epoll_ctl warns for uninitialized padding on non-amd64 64bit arches - - struct vki_epoll_event is packed on x86_64, but not on other 64bit - arches. This means that on 64bit arches there can be padding in the - epoll_event struct. Seperately the data field is only used by user - space (which might not set the data field if it doesn't need to). - - Only check the events field on epoll_ctl. But assume both events - and data are both written to by epoll_[p]wait (exclude padding). - - https://bugs.kde.org/show_bug.cgi?id=422623 - -diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c -index 5b5b7eee6..929a4d9af 100644 ---- a/coregrind/m_syswrap/syswrap-linux.c -+++ b/coregrind/m_syswrap/syswrap-linux.c -@@ -2099,8 +2099,29 @@ PRE(sys_epoll_ctl) - SARG1, ( ARG2<3 ? epoll_ctl_s[ARG2] : "?" ), SARG3, ARG4); - PRE_REG_READ4(long, "epoll_ctl", - int, epfd, int, op, int, fd, struct vki_epoll_event *, event); -- if (ARG2 != VKI_EPOLL_CTL_DEL) -- PRE_MEM_READ( "epoll_ctl(event)", ARG4, sizeof(struct vki_epoll_event) ); -+ if (ARG2 != VKI_EPOLL_CTL_DEL) { -+ /* Just check the events field, the data field is for user space and -+ unused by the kernel. */ -+ struct vki_epoll_event *event = (struct vki_epoll_event *) ARG4; -+ PRE_MEM_READ( "epoll_ctl(event)", (Addr) &event->events, -+ sizeof(__vki_u32) ); -+ } -+} -+ -+/* RES event records have been written (exclude padding). */ -+static void epoll_post_helper ( ThreadId tid, SyscallArgs* arrghs, -+ SyscallStatus* status ) -+{ -+ vg_assert(SUCCESS); -+ if (RES > 0) { -+ Int i; -+ struct vki_epoll_event **events = (struct vki_epoll_event**)(Addr)ARG2; -+ for (i = 0; i < RES; i++) { -+ /* Assume both events and data are set (data is user space only). */ -+ POST_FIELD_WRITE(events[i]->events); -+ POST_FIELD_WRITE(events[i]->data); -+ } -+ } - } - - PRE(sys_epoll_wait) -@@ -2111,13 +2132,12 @@ PRE(sys_epoll_wait) - PRE_REG_READ4(long, "epoll_wait", - int, epfd, struct vki_epoll_event *, events, - int, maxevents, int, timeout); -+ /* Assume all (maxevents) events records should be (fully) writable. */ - PRE_MEM_WRITE( "epoll_wait(events)", ARG2, sizeof(struct vki_epoll_event)*ARG3); - } - POST(sys_epoll_wait) - { -- vg_assert(SUCCESS); -- if (RES > 0) -- POST_MEM_WRITE( ARG2, sizeof(struct vki_epoll_event)*RES ) ; -+ epoll_post_helper (tid, arrghs, status); - } - - PRE(sys_epoll_pwait) -@@ -2130,15 +2150,14 @@ PRE(sys_epoll_pwait) - int, epfd, struct vki_epoll_event *, events, - int, maxevents, int, timeout, vki_sigset_t *, sigmask, - vki_size_t, sigsetsize); -+ /* Assume all (maxevents) events records should be (fully) writable. */ - PRE_MEM_WRITE( "epoll_pwait(events)", ARG2, sizeof(struct vki_epoll_event)*ARG3); - if (ARG5) - PRE_MEM_READ( "epoll_pwait(sigmask)", ARG5, sizeof(vki_sigset_t) ); - } - POST(sys_epoll_pwait) - { -- vg_assert(SUCCESS); -- if (RES > 0) -- POST_MEM_WRITE( ARG2, sizeof(struct vki_epoll_event)*RES ) ; -+ epoll_post_helper (tid, arrghs, status); - } - - PRE(sys_eventfd) -commit b74f9f23c8758c77367f18368ea95baa858544cb -Author: Mark Wielaard -Date: Tue Aug 18 23:58:55 2020 +0200 - - Fix epoll_ctl setting of array event and data fields. - - Fix for https://bugs.kde.org/show_bug.cgi?id=422623 in commit ecf5ba119 - epoll_ctl warns for uninitialized padding on non-amd64 64bit arches - contained a bug. A pointer to an array is not a pointer to a pointer to - an array. Found by a Fedora user: - https://bugzilla.redhat.com/show_bug.cgi?id=1844778#c10 - -diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c -index 0850487e9..3f488795a 100644 ---- a/coregrind/m_syswrap/syswrap-linux.c -+++ b/coregrind/m_syswrap/syswrap-linux.c -@@ -2115,11 +2115,11 @@ static void epoll_post_helper ( ThreadId tid, SyscallArgs* arrghs, - vg_assert(SUCCESS); - if (RES > 0) { - Int i; -- struct vki_epoll_event **events = (struct vki_epoll_event**)(Addr)ARG2; -+ struct vki_epoll_event *events = (struct vki_epoll_event*)(Addr)ARG2; - for (i = 0; i < RES; i++) { - /* Assume both events and data are set (data is user space only). */ -- POST_FIELD_WRITE(events[i]->events); -- POST_FIELD_WRITE(events[i]->data); -+ POST_FIELD_WRITE(events[i].events); -+ POST_FIELD_WRITE(events[i].data); - } - } - } diff --git a/valgrind-3.16.1-faccessat2.patch b/valgrind-3.16.1-faccessat2.patch deleted file mode 100644 index 9751f45..0000000 --- a/valgrind-3.16.1-faccessat2.patch +++ /dev/null @@ -1,201 +0,0 @@ -From fe4b349df3d5edc1c849e9890cbc6b191386a03c Mon Sep 17 00:00:00 2001 -From: Mark Wielaard -Date: Fri, 16 Oct 2020 02:55:06 +0200 -Subject: [PATCH] Support new faccessat2 linux syscall (439) - -faccessat2 is a new syscall in linux 5.8 and will be used by glibc 2.33. -faccessat2 is simply faccessat with a new flag argument. It has -a common number across all linux arches. - -https://bugs.kde.org/427787 ---- - NEWS | 1 + - coregrind/m_syswrap/priv_syswrap-linux.h | 1 + - coregrind/m_syswrap/syswrap-amd64-linux.c | 2 ++ - coregrind/m_syswrap/syswrap-arm-linux.c | 2 ++ - coregrind/m_syswrap/syswrap-arm64-linux.c | 2 ++ - coregrind/m_syswrap/syswrap-linux.c | 9 +++++++++ - coregrind/m_syswrap/syswrap-mips32-linux.c | 2 ++ - coregrind/m_syswrap/syswrap-mips64-linux.c | 1 + - coregrind/m_syswrap/syswrap-nanomips-linux.c | 1 + - coregrind/m_syswrap/syswrap-ppc32-linux.c | 2 ++ - coregrind/m_syswrap/syswrap-ppc64-linux.c | 2 ++ - coregrind/m_syswrap/syswrap-s390x-linux.c | 2 ++ - coregrind/m_syswrap/syswrap-x86-linux.c | 2 ++ - include/vki/vki-scnums-shared-linux.h | 2 ++ - 14 files changed, 31 insertions(+) - -diff --git a/coregrind/m_syswrap/priv_syswrap-linux.h b/coregrind/m_syswrap/priv_syswrap-linux.h -index eb0b320ca..110f7c832 100644 ---- a/coregrind/m_syswrap/priv_syswrap-linux.h -+++ b/coregrind/m_syswrap/priv_syswrap-linux.h -@@ -180,6 +180,7 @@ DECL_TEMPLATE(linux, sys_symlinkat); - DECL_TEMPLATE(linux, sys_readlinkat); - DECL_TEMPLATE(linux, sys_fchmodat); - DECL_TEMPLATE(linux, sys_faccessat); -+DECL_TEMPLATE(linux, sys_faccessat2); - DECL_TEMPLATE(linux, sys_utimensat); - DECL_TEMPLATE(linux, sys_name_to_handle_at); - DECL_TEMPLATE(linux, sys_open_by_handle_at); -diff --git a/coregrind/m_syswrap/syswrap-amd64-linux.c b/coregrind/m_syswrap/syswrap-amd64-linux.c -index d6f3eb910..45e1f3d1b 100644 ---- a/coregrind/m_syswrap/syswrap-amd64-linux.c -+++ b/coregrind/m_syswrap/syswrap-amd64-linux.c -@@ -873,6 +873,8 @@ static SyscallTableEntry syscall_table[] = { - LINXY(__NR_io_uring_setup, sys_io_uring_setup), // 425 - LINXY(__NR_io_uring_enter, sys_io_uring_enter), // 426 - LINXY(__NR_io_uring_register, sys_io_uring_register), // 427 -+ -+ LINX_(__NR_faccessat2, sys_faccessat2), // 439 - }; - - SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno ) -diff --git a/coregrind/m_syswrap/syswrap-arm-linux.c b/coregrind/m_syswrap/syswrap-arm-linux.c -index 70700e53f..978aedbe6 100644 ---- a/coregrind/m_syswrap/syswrap-arm-linux.c -+++ b/coregrind/m_syswrap/syswrap-arm-linux.c -@@ -1046,6 +1046,8 @@ static SyscallTableEntry syscall_main_table[] = { - LINXY(__NR_futex_time64, sys_futex_time64), // 422 - LINXY(__NR_sched_rr_get_interval_time64, - sys_sched_rr_get_interval_time64), // 423 -+ -+ LINX_(__NR_faccessat2, sys_faccessat2), // 439 - }; - - -diff --git a/coregrind/m_syswrap/syswrap-arm64-linux.c b/coregrind/m_syswrap/syswrap-arm64-linux.c -index acca02442..051d84989 100644 ---- a/coregrind/m_syswrap/syswrap-arm64-linux.c -+++ b/coregrind/m_syswrap/syswrap-arm64-linux.c -@@ -825,6 +825,8 @@ static SyscallTableEntry syscall_main_table[] = { - // (__NR_pkey_free, sys_ni_syscall), // 290 - - LINXY(__NR_statx, sys_statx), // 397 -+ -+ LINX_(__NR_faccessat2, sys_faccessat2), // 439 - }; - - -diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c -index 3f488795a..41849873e 100644 ---- a/coregrind/m_syswrap/syswrap-linux.c -+++ b/coregrind/m_syswrap/syswrap-linux.c -@@ -5988,6 +5988,15 @@ PRE(sys_faccessat) - PRE_MEM_RASCIIZ( "faccessat(pathname)", ARG2 ); - } - -+PRE(sys_faccessat2) -+{ -+ PRINT("sys_faccessat2 ( %ld, %#" FMT_REGWORD "x(%s), %ld, %ld )", -+ SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3, SARG4); -+ PRE_REG_READ4(long, "faccessat2", -+ int, dfd, const char *, pathname, int, mode, int, flags); -+ PRE_MEM_RASCIIZ( "faccessat2(pathname)", ARG2 ); -+} -+ - PRE(sys_name_to_handle_at) - { - PRINT("sys_name_to_handle_at ( %ld, %#" FMT_REGWORD "x(%s), %#" -diff --git a/coregrind/m_syswrap/syswrap-mips32-linux.c b/coregrind/m_syswrap/syswrap-mips32-linux.c -index 5face576b..f35fb8bbb 100644 ---- a/coregrind/m_syswrap/syswrap-mips32-linux.c -+++ b/coregrind/m_syswrap/syswrap-mips32-linux.c -@@ -1131,6 +1131,8 @@ static SyscallTableEntry syscall_main_table[] = { - LINXY(__NR_futex_time64, sys_futex_time64), // 422 - LINXY(__NR_sched_rr_get_interval_time64, - sys_sched_rr_get_interval_time64), // 423 -+ -+ LINX_ (__NR_faccessat2, sys_faccessat2), // 439 - }; - - SyscallTableEntry* ML_(get_linux_syscall_entry) (UInt sysno) -diff --git a/coregrind/m_syswrap/syswrap-mips64-linux.c b/coregrind/m_syswrap/syswrap-mips64-linux.c -index c64911a50..bd260679c 100644 ---- a/coregrind/m_syswrap/syswrap-mips64-linux.c -+++ b/coregrind/m_syswrap/syswrap-mips64-linux.c -@@ -812,6 +812,7 @@ static SyscallTableEntry syscall_main_table[] = { - LINX_ (__NR_syncfs, sys_syncfs), - LINXY (__NR_statx, sys_statx), - LINX_ (__NR_setns, sys_setns), -+ LINX_ (__NR_faccessat2, sys_faccessat2), - }; - - SyscallTableEntry * ML_(get_linux_syscall_entry) ( UInt sysno ) -diff --git a/coregrind/m_syswrap/syswrap-nanomips-linux.c b/coregrind/m_syswrap/syswrap-nanomips-linux.c -index 7ceecb6da..a904745ab 100644 ---- a/coregrind/m_syswrap/syswrap-nanomips-linux.c -+++ b/coregrind/m_syswrap/syswrap-nanomips-linux.c -@@ -821,6 +821,7 @@ static SyscallTableEntry syscall_main_table[] = { - // (__NR_pkey_mprotect, sys_ni_syscall), - // (__NR_pkey_alloc, sys_ni_syscall), - // (__NR_pkey_free, sys_ni_syscall), -+ LINX_ (__NR_faccessat2, sys_faccessat2), - }; - - SyscallTableEntry* ML_(get_linux_syscall_entry) (UInt sysno) -diff --git a/coregrind/m_syswrap/syswrap-ppc32-linux.c b/coregrind/m_syswrap/syswrap-ppc32-linux.c -index c19cb9e0e..6ddd482d9 100644 ---- a/coregrind/m_syswrap/syswrap-ppc32-linux.c -+++ b/coregrind/m_syswrap/syswrap-ppc32-linux.c -@@ -1049,6 +1049,8 @@ static SyscallTableEntry syscall_table[] = { - LINXY(__NR_futex_time64, sys_futex_time64), // 422 - LINXY(__NR_sched_rr_get_interval_time64, - sys_sched_rr_get_interval_time64), // 423 -+ -+ LINX_(__NR_faccessat2, sys_faccessat2), // 439 - }; - - SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno ) -diff --git a/coregrind/m_syswrap/syswrap-ppc64-linux.c b/coregrind/m_syswrap/syswrap-ppc64-linux.c -index b6422a765..7026e4ac6 100644 ---- a/coregrind/m_syswrap/syswrap-ppc64-linux.c -+++ b/coregrind/m_syswrap/syswrap-ppc64-linux.c -@@ -1014,6 +1014,8 @@ static SyscallTableEntry syscall_table[] = { - LINX_(__NR_pwritev2, sys_pwritev2), // 381 - - LINXY(__NR_statx, sys_statx), // 383 -+ -+ LINX_(__NR_faccessat2, sys_faccessat2), // 439 - }; - - SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno ) -diff --git a/coregrind/m_syswrap/syswrap-s390x-linux.c b/coregrind/m_syswrap/syswrap-s390x-linux.c -index 3427fee16..c5e4bb957 100644 ---- a/coregrind/m_syswrap/syswrap-s390x-linux.c -+++ b/coregrind/m_syswrap/syswrap-s390x-linux.c -@@ -859,6 +859,8 @@ static SyscallTableEntry syscall_table[] = { - LINX_(__NR_pwritev2, sys_pwritev2), // 377 - - LINXY(__NR_statx, sys_statx), // 379 -+ -+ LINX_(__NR_faccessat2, sys_faccessat2), // 439 - }; - - SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno ) -diff --git a/coregrind/m_syswrap/syswrap-x86-linux.c b/coregrind/m_syswrap/syswrap-x86-linux.c -index b59d96f37..67d866497 100644 ---- a/coregrind/m_syswrap/syswrap-x86-linux.c -+++ b/coregrind/m_syswrap/syswrap-x86-linux.c -@@ -1644,6 +1644,8 @@ static SyscallTableEntry syscall_table[] = { - LINXY(__NR_io_uring_setup, sys_io_uring_setup), // 425 - LINXY(__NR_io_uring_enter, sys_io_uring_enter), // 426 - LINXY(__NR_io_uring_register, sys_io_uring_register),// 427 -+ -+ LINX_(__NR_faccessat2, sys_faccessat2), // 439 - }; - - SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno ) -diff --git a/include/vki/vki-scnums-shared-linux.h b/include/vki/vki-scnums-shared-linux.h -index 6221d5a81..c8bc31b4b 100644 ---- a/include/vki/vki-scnums-shared-linux.h -+++ b/include/vki/vki-scnums-shared-linux.h -@@ -39,4 +39,6 @@ - #define __NR_fsmount 432 - #define __NR_fspick 433 - -+#define __NR_faccessat2 439 -+ - #endif --- -2.20.1 - diff --git a/valgrind-3.16.1-ficlone.patch b/valgrind-3.16.1-ficlone.patch deleted file mode 100644 index 83b00a3..0000000 --- a/valgrind-3.16.1-ficlone.patch +++ /dev/null @@ -1,43 +0,0 @@ -commit 1c49351424f04ee29a5efc054cb08ab3ad22b978 -Author: Laurent Bonnans -Date: Fri Nov 16 15:22:18 2018 +0100 - - Fix 397605 - Add support for Linux FICLONE ioctl - -diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c -index 41849873e..328e02a98 100644 ---- a/coregrind/m_syswrap/syswrap-linux.c -+++ b/coregrind/m_syswrap/syswrap-linux.c -@@ -7961,6 +7961,11 @@ PRE(sys_ioctl) - case VKI_FIBMAP: - PRE_MEM_READ( "ioctl(FIBMAP)", ARG3, sizeof(int)); - break; -+ case VKI_FICLONE: -+ /* The direction of FICLONE (W) is incorrectly specified -+ * as it expects a file descriptor and not a pointer to -+ * user data */ -+ break; - - case VKI_FBIOGET_VSCREENINFO: /* 0x4600 */ - PRE_MEM_WRITE( "ioctl(FBIOGET_VSCREENINFO)", ARG3, -@@ -10898,6 +10903,8 @@ POST(sys_ioctl) - case VKI_FIBMAP: - POST_MEM_WRITE(ARG3, sizeof(int)); - break; -+ case VKI_FICLONE: -+ break; - - case VKI_FBIOGET_VSCREENINFO: //0x4600 - POST_MEM_WRITE(ARG3, sizeof(struct vki_fb_var_screeninfo)); -diff --git a/include/vki/vki-linux.h b/include/vki/vki-linux.h -index ef93b9258..3b9dc3779 100644 ---- a/include/vki/vki-linux.h -+++ b/include/vki/vki-linux.h -@@ -1888,6 +1888,7 @@ struct vki_ppdev_frob_struct { - - #define VKI_FIBMAP _VKI_IO(0x00,1) /* bmap access */ - #define VKI_FIGETBSZ _VKI_IO(0x00,2) /* get the block size used for bmap */ -+#define VKI_FICLONE _VKI_IOW(0x94, 9, int) - - //---------------------------------------------------------------------- - // From linux-2.6.8.1/include/scsi/sg.h diff --git a/valgrind-3.16.1-gdbserver_nlcontrolc.patch b/valgrind-3.16.1-gdbserver_nlcontrolc.patch deleted file mode 100644 index fbc7854..0000000 --- a/valgrind-3.16.1-gdbserver_nlcontrolc.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/gdbserver_tests/nlcontrolc.vgtest b/gdbserver_tests/nlcontrolc.vgtest -index bb5308403..4eb479595 100644 ---- a/gdbserver_tests/nlcontrolc.vgtest -+++ b/gdbserver_tests/nlcontrolc.vgtest -@@ -13,7 +13,7 @@ args: 1000000000 1000000000 1000000000 BSBSBSBS 1 - vgopts: --tool=none --vgdb=yes --vgdb-error=0 --vgdb-prefix=./vgdb-prefix-nlcontrolc - stderr_filter: filter_stderr - # Bug 338633 nlcontrol hangs on arm64 currently. --prereq: test -e gdb -a -f vgdb.invoker && ! ../tests/arch_test arm64 && ! ../tests/os_test solaris -+prereq: false && test -e gdb -a -f vgdb.invoker && ! ../tests/arch_test arm64 && ! ../tests/os_test solaris - progB: gdb - argsB: --quiet -l 60 --nx ./sleepers - stdinB: nlcontrolc.stdinB.gdb diff --git a/valgrind-3.16.1-open-proc-self-exe.patch b/valgrind-3.16.1-open-proc-self-exe.patch deleted file mode 100644 index 343f759..0000000 --- a/valgrind-3.16.1-open-proc-self-exe.patch +++ /dev/null @@ -1,98 +0,0 @@ -diff --git a/coregrind/m_syswrap/priv_syswrap-generic.h b/coregrind/m_syswrap/priv_syswrap-generic.h -index 4717abac6..c50b31399 100644 ---- a/coregrind/m_syswrap/priv_syswrap-generic.h -+++ b/coregrind/m_syswrap/priv_syswrap-generic.h -@@ -106,6 +106,10 @@ extern Bool - ML_(handle_auxv_open)(SyscallStatus *status, const HChar *filename, - int flags); - -+extern Bool -+ML_(handle_self_exe_open)(SyscallStatus *status, const HChar *filename, -+ int flags); -+ - /* Helper function for generic mprotect and linux pkey_mprotect. */ - extern void handle_sys_mprotect (ThreadId tid, SyscallStatus *status, - Addr *addr, SizeT *len, Int *prot); -diff --git a/coregrind/m_syswrap/syswrap-generic.c b/coregrind/m_syswrap/syswrap-generic.c -index 7d4b385a3..3810f7474 100644 ---- a/coregrind/m_syswrap/syswrap-generic.c -+++ b/coregrind/m_syswrap/syswrap-generic.c -@@ -4078,6 +4078,38 @@ Bool ML_(handle_auxv_open)(SyscallStatus *status, const HChar *filename, - } - #endif // defined(VGO_linux) || defined(VGO_solaris) - -+#if defined(VGO_linux) -+Bool ML_(handle_self_exe_open)(SyscallStatus *status, const HChar *filename, -+ int flags) -+{ -+ HChar name[30]; // large enough for /proc//exe -+ -+ if (!ML_(safe_to_deref)((const void *) filename, 1)) -+ return False; -+ -+ /* Opening /proc//exe or /proc/self/exe? */ -+ VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)()); -+ if (!VG_STREQ(filename, name) && !VG_STREQ(filename, "/proc/self/exe")) -+ return False; -+ -+ /* Allow to open the file only for reading. */ -+ if (flags & (VKI_O_WRONLY | VKI_O_RDWR)) { -+ SET_STATUS_Failure(VKI_EACCES); -+ return True; -+ } -+ -+ SysRes sres = VG_(dup)(VG_(cl_exec_fd)); -+ SET_STATUS_from_SysRes(sres); -+ if (!sr_isError(sres)) { -+ OffT off = VG_(lseek)(sr_Res(sres), 0, VKI_SEEK_SET); -+ if (off < 0) -+ SET_STATUS_Failure(VKI_EMFILE); -+ } -+ -+ return True; -+} -+#endif // defined(VGO_linux) -+ - PRE(sys_open) - { - if (ARG2 & VKI_O_CREAT) { -@@ -4119,8 +4151,10 @@ PRE(sys_open) - } - } - -- /* Handle also the case of /proc/self/auxv or /proc//auxv. */ -- if (ML_(handle_auxv_open)(status, (const HChar *)(Addr)ARG1, ARG2)) -+ /* Handle also the case of /proc/self/auxv or /proc//auxv -+ or /proc/self/exe or /proc//exe. */ -+ if (ML_(handle_auxv_open)(status, (const HChar *)(Addr)ARG1, ARG2) -+ || ML_(handle_self_exe_open)(status, (const HChar *)(Addr)ARG1, ARG2)) - return; - #endif // defined(VGO_linux) - -diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c -index 52074149d..fcc534454 100644 ---- a/coregrind/m_syswrap/syswrap-linux.c -+++ b/coregrind/m_syswrap/syswrap-linux.c -@@ -5745,6 +5745,22 @@ PRE(sys_openat) - return; - } - -+ /* And for /proc/self/exe or /proc//exe case. */ -+ -+ VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)()); -+ if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 ) -+ && (VG_(strcmp)((HChar *)(Addr)ARG2, name) == 0 -+ || VG_(strcmp)((HChar *)(Addr)ARG2, "/proc/self/exe") == 0)) { -+ sres = VG_(dup)( VG_(cl_exec_fd) ); -+ SET_STATUS_from_SysRes( sres ); -+ if (!sr_isError(sres)) { -+ OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET ); -+ if (off < 0) -+ SET_STATUS_Failure( VKI_EMFILE ); -+ } -+ return; -+ } -+ - /* Otherwise handle normally */ - *flags |= SfMayBlock; - } diff --git a/valgrind-3.16.1-ppc64-scv-hwcap.patch b/valgrind-3.16.1-ppc64-scv-hwcap.patch deleted file mode 100644 index ef88bef..0000000 --- a/valgrind-3.16.1-ppc64-scv-hwcap.patch +++ /dev/null @@ -1,57 +0,0 @@ -From a88c168b4dd607bca47d3a1ec08573d3e5fa889b Mon Sep 17 00:00:00 2001 -From: Florian Weimer -Date: Fri, 8 Jan 2021 15:08:50 +0100 -Subject: [PATCH] ppc64: Mask unrecognized AT_HWCAP2 values - -Also suppress printing a log message for scv instructions in the -instruction stream. - -These changes are required for running glibc 2.33 on kernels with scv -support under valgrind. ---- - VEX/priv/guest_ppc_toIR.c | 5 +++-- - coregrind/m_initimg/initimg-linux.c | 6 ++++++ - 2 files changed, 9 insertions(+), 2 deletions(-) - -diff --git a/VEX/priv/guest_ppc_toIR.c b/VEX/priv/guest_ppc_toIR.c -index e7b576fa2..99e96a577 100644 ---- a/VEX/priv/guest_ppc_toIR.c -+++ b/VEX/priv/guest_ppc_toIR.c -@@ -8739,8 +8739,9 @@ - { - IRType ty = mode64 ? Ity_I64 : Ity_I32; - -- if (theInstr != 0x44000002) { -- vex_printf("dis_syslink(ppc)(theInstr)\n"); -+ if (theInstr != 0x44000002) { // sc -+ if (theInstr != 0x44000001) // scv -+ vex_printf("dis_syslink(ppc)(theInstr)\n"); - return False; - } - -diff --git a/coregrind/m_initimg/initimg-linux.c b/coregrind/m_initimg/initimg-linux.c -index ba84fa6e9..fb68ae00b 100644 ---- a/coregrind/m_initimg/initimg-linux.c -+++ b/coregrind/m_initimg/initimg-linux.c -@@ -750,6 +750,7 @@ Addr setup_client_stack( void* init_sp, - PPC_FEATURE2_HAS_ISEL 0x08000000 - PPC_FEATURE2_HAS_TAR 0x04000000 - PPC_FEATURE2_HAS_VCRYPTO 0x02000000 -+ PPC_FEATURE2_HAS_IEEE128 0x00400000 - */ - auxv_2_07 = (auxv->u.a_val & 0x80000000ULL) == 0x80000000ULL; - hw_caps_2_07 = (vex_archinfo->hwcaps & VEX_HWCAPS_PPC64_ISA2_07) -@@ -757,6 +757,11 @@ - * matches the setting in VEX HWCAPS. - */ - vg_assert(auxv_2_07 == hw_caps_2_07); -+ -+ /* Mask unrecognized HWCAP bits. Only keep the bits that have -+ * been mentioned above. -+ */ -+ auxv->u.a_val &= 0xfec00000ULL; - } - - break; ---- valgrind-3.16.1/VEX/priv/guest_ppc_toIR.c 2021-01-08 16:43:45.947122866 +0100 -+++ guest_ppc_toIR.c.new 2021-01-08 16:43:40.238166866 +0100 diff --git a/valgrind-3.16.1-pthread-intercept.patch b/valgrind-3.16.1-pthread-intercept.patch deleted file mode 100644 index 8234314..0000000 --- a/valgrind-3.16.1-pthread-intercept.patch +++ /dev/null @@ -1,222 +0,0 @@ -commit 15330adf7c2471fbaa6a0818db07078d81dbff97 -Author: Bart Van Assche -Date: Sat Sep 19 08:08:59 2020 -0700 - - drd: Port to Fedora 33 - - Apparently on Fedora 33 the POSIX thread functions exist in both libc and - libpthread. Hence this patch that intercepts the pthread functions in - libc. See also https://bugs.kde.org/show_bug.cgi?id=426144 . - -diff --git a/drd/drd_pthread_intercepts.c b/drd/drd_pthread_intercepts.c -index 58c45aaec..c2882e5ab 100644 ---- a/drd/drd_pthread_intercepts.c -+++ b/drd/drd_pthread_intercepts.c -@@ -174,7 +174,16 @@ static int never_true; - ret_ty VG_WRAP_FUNCTION_ZZ(VG_Z_LIBC_SONAME,zf) argl_decl \ - { return implf argl; } - #else -+/* -+ * On Linux, intercept both the libc and the libpthread functions. At -+ * least glibc 2.32.9000 (Fedora 34) has an implementation of all pthread -+ * functions in both libc and libpthread. Older glibc versions only have an -+ * implementation of the pthread functions in libpthread. -+ */ - #define PTH_FUNC(ret_ty, zf, implf, argl_decl, argl) \ -+ ret_ty VG_WRAP_FUNCTION_ZZ(VG_Z_LIBC_SONAME,zf) argl_decl; \ -+ ret_ty VG_WRAP_FUNCTION_ZZ(VG_Z_LIBC_SONAME,zf) argl_decl \ -+ { return implf argl; } \ - ret_ty VG_WRAP_FUNCTION_ZZ(VG_Z_LIBPTHREAD_SONAME,zf) argl_decl; \ - ret_ty VG_WRAP_FUNCTION_ZZ(VG_Z_LIBPTHREAD_SONAME,zf) argl_decl \ - { return implf argl; } - -commit 3073d03e4b6e76797828b3f466863dbdda76cc7a -Author: Bart Van Assche -Date: Tue Oct 20 19:40:19 2020 -0700 - - drd: Unbreak the musl build - - See also https://bugs.kde.org/show_bug.cgi?id=428035. - - Reported-by: Stacy - Fixes: 15330adf7c24 ("drd: Port to Fedora 33") - -diff --git a/drd/drd_pthread_intercepts.c b/drd/drd_pthread_intercepts.c -index 62c466f50..585aafe22 100644 ---- a/drd/drd_pthread_intercepts.c -+++ b/drd/drd_pthread_intercepts.c -@@ -174,6 +174,13 @@ static int never_true; - ret_ty VG_WRAP_FUNCTION_ZZ(VG_Z_LIBC_SONAME,zf) argl_decl \ - { return implf argl; } - #else -+#ifdef MUSL_LIBC -+/* musl provides a single library that includes pthreads functions. */ -+#define PTH_FUNC(ret_ty, zf, implf, argl_decl, argl) \ -+ ret_ty VG_WRAP_FUNCTION_ZZ(VG_Z_LIBPTHREAD_SONAME,zf) argl_decl; \ -+ ret_ty VG_WRAP_FUNCTION_ZZ(VG_Z_LIBPTHREAD_SONAME,zf) argl_decl \ -+ { return implf argl; } -+#else - /* - * On Linux, intercept both the libc and the libpthread functions. At - * least glibc 2.32.9000 (Fedora 34) has an implementation of all pthread -@@ -188,6 +195,7 @@ static int never_true; - ret_ty VG_WRAP_FUNCTION_ZZ(VG_Z_LIBPTHREAD_SONAME,zf) argl_decl \ - { return implf argl; } - #endif -+#endif - - /** - * Macro for generating three Valgrind interception functions: one with the -diff --git a/drd/drd_pthread_intercepts.c b/drd/drd_pthread_intercepts.c - -index 585aafe22..3d1f90d3b 100644 ---- a/drd/drd_pthread_intercepts.c -+++ b/drd/drd_pthread_intercepts.c -@@ -151,7 +151,7 @@ static drd_rtld_guard_fn DRD_(rtld_bind_clear) = NULL; - * @param[in] arg_decl Argument declaration list enclosed in parentheses. - * @param[in] argl Argument list enclosed in parentheses. - */ --#ifdef VGO_darwin -+#if defined(VGO_darwin) - static int never_true; - #define PTH_FUNC(ret_ty, zf, implf, argl_decl, argl) \ - ret_ty VG_WRAP_FUNCTION_ZZ(VG_Z_LIBPTHREAD_SONAME,zf) argl_decl; \ -@@ -164,29 +164,12 @@ static int never_true; - fflush(stdout); \ - return pth_func_result; \ - } --#elif defined(VGO_solaris) --/* On Solaris, libpthread is just a filter library on top of libc. -- * Threading and synchronization functions in runtime linker are not -- * intercepted. -- */ -+#elif defined(VG_WRAP_THREAD_FUNCTION_LIBC_ONLY) - #define PTH_FUNC(ret_ty, zf, implf, argl_decl, argl) \ - ret_ty VG_WRAP_FUNCTION_ZZ(VG_Z_LIBC_SONAME,zf) argl_decl; \ - ret_ty VG_WRAP_FUNCTION_ZZ(VG_Z_LIBC_SONAME,zf) argl_decl \ - { return implf argl; } --#else --#ifdef MUSL_LIBC --/* musl provides a single library that includes pthreads functions. */ --#define PTH_FUNC(ret_ty, zf, implf, argl_decl, argl) \ -- ret_ty VG_WRAP_FUNCTION_ZZ(VG_Z_LIBPTHREAD_SONAME,zf) argl_decl; \ -- ret_ty VG_WRAP_FUNCTION_ZZ(VG_Z_LIBPTHREAD_SONAME,zf) argl_decl \ -- { return implf argl; } --#else --/* -- * On Linux, intercept both the libc and the libpthread functions. At -- * least glibc 2.32.9000 (Fedora 34) has an implementation of all pthread -- * functions in both libc and libpthread. Older glibc versions only have an -- * implementation of the pthread functions in libpthread. -- */ -+#elif defined(VG_WRAP_THREAD_FUNCTION_LIBC_AND_LIBPTHREAD) - #define PTH_FUNC(ret_ty, zf, implf, argl_decl, argl) \ - ret_ty VG_WRAP_FUNCTION_ZZ(VG_Z_LIBC_SONAME,zf) argl_decl; \ - ret_ty VG_WRAP_FUNCTION_ZZ(VG_Z_LIBC_SONAME,zf) argl_decl \ -@@ -194,7 +177,8 @@ static int never_true; - ret_ty VG_WRAP_FUNCTION_ZZ(VG_Z_LIBPTHREAD_SONAME,zf) argl_decl; \ - ret_ty VG_WRAP_FUNCTION_ZZ(VG_Z_LIBPTHREAD_SONAME,zf) argl_decl \ - { return implf argl; } --#endif -+#else -+# error "Unknown platform/thread wrapping" - #endif - - /** -diff --git a/helgrind/hg_intercepts.c b/helgrind/hg_intercepts.c -index a10c3a4a3..2bc89f8a0 100644 ---- a/helgrind/hg_intercepts.c -+++ b/helgrind/hg_intercepts.c -@@ -78,26 +78,37 @@ - /*----------------------------------------------------------------*/ - - #if defined(VGO_solaris) --/* On Solaris, libpthread is just a filter library on top of libc. -- * Threading and synchronization functions in runtime linker are not -- * intercepted. -- */ --#define PTH_FUNC(ret_ty, f, args...) \ -- ret_ty I_WRAP_SONAME_FNNAME_ZZ(VG_Z_LIBC_SONAME,f)(args); \ -- ret_ty I_WRAP_SONAME_FNNAME_ZZ(VG_Z_LIBC_SONAME,f)(args) -- - /* pthread_t is typedef'd to 'unsigned int' but in DO_CREQ_* macros - sizeof(Word) is expected. */ - #define CREQ_PTHREAD_T Word - #define SEM_ERROR ret - #else --#define PTH_FUNC(ret_ty, f, args...) \ -- ret_ty I_WRAP_SONAME_FNNAME_ZZ(VG_Z_LIBPTHREAD_SONAME,f)(args); \ -- ret_ty I_WRAP_SONAME_FNNAME_ZZ(VG_Z_LIBPTHREAD_SONAME,f)(args) - #define CREQ_PTHREAD_T pthread_t - #define SEM_ERROR errno - #endif /* VGO_solaris */ - -+#define HG_EXPAND(tok) #tok -+#define HG_STR(tok) HG_EXPAND(tok) -+#define HG_WEAK_ALIAS(name, aliasname) \ -+ extern __typeof (name) aliasname __attribute__ ((weak, alias(HG_STR(name)))) -+ -+#if defined(VG_WRAP_THREAD_FUNCTION_LIBPTHREAD_ONLY) -+#define PTH_FUNC(ret_ty, f, args...) \ -+ ret_ty I_WRAP_SONAME_FNNAME_ZZ(VG_Z_LIBPTHREAD_SONAME,f)(args); \ -+ ret_ty I_WRAP_SONAME_FNNAME_ZZ(VG_Z_LIBPTHREAD_SONAME,f)(args) -+#elif defined(VG_WRAP_THREAD_FUNCTION_LIBC_AND_LIBPTHREAD) -+#define PTH_FUNC(ret_ty, f, args...) \ -+ ret_ty I_WRAP_SONAME_FNNAME_ZZ(VG_Z_LIBPTHREAD_SONAME,f)(args); \ -+ HG_WEAK_ALIAS(I_WRAP_SONAME_FNNAME_ZZ(VG_Z_LIBPTHREAD_SONAME,f), I_WRAP_SONAME_FNNAME_ZZ(VG_Z_LIBC_SONAME,f)); \ -+ ret_ty I_WRAP_SONAME_FNNAME_ZZ(VG_Z_LIBPTHREAD_SONAME,f)(args) -+#elif defined(VG_WRAP_THREAD_FUNCTION_LIBC_ONLY) -+#define PTH_FUNC(ret_ty, f, args...) \ -+ ret_ty I_WRAP_SONAME_FNNAME_ZZ(VG_Z_LIBC_SONAME,f)(args); \ -+ ret_ty I_WRAP_SONAME_FNNAME_ZZ(VG_Z_LIBC_SONAME,f)(args) -+#else -+# error "Unknown platform/thread wrapping" -+#endif -+ - // Do a client request. These are macros rather than a functions so - // as to avoid having an extra frame in stack traces. - -diff --git a/include/pub_tool_redir.h b/include/pub_tool_redir.h -index bd65a44b4..d665afd98 100644 ---- a/include/pub_tool_redir.h -+++ b/include/pub_tool_redir.h -@@ -277,11 +277,7 @@ - /* --- Soname of the pthreads library. --- */ - - #if defined(VGO_linux) --# if defined(MUSL_LIBC) --# define VG_Z_LIBPTHREAD_SONAME libcZdZa // libc.* --#else - # define VG_Z_LIBPTHREAD_SONAME libpthreadZdsoZd0 // libpthread.so.0 --#endif - #elif defined(VGO_darwin) - # define VG_Z_LIBPTHREAD_SONAME libSystemZdZaZddylib // libSystem.*.dylib - #elif defined(VGO_solaris) -@@ -364,6 +360,27 @@ - - Bool VG_(is_soname_ld_so) (const HChar *soname); - -+// Some macros to help decide which libraries (libc or libpthread -+// or some platform-specific variation of these) should be used -+// for wrapping pthread/semaphore functions with DRD and Helgrind -+// The possibilities are a) only in libpthread -+// b) mabye in both libpthread and libc or c) only in libc -+// Linux GNU libc is moving from a) to c) (starting with Fedora 33) -+// Linux MUSL libc is c) -+// Darwin is a) -+// Solaris is c) -+// FreeBSD is b) -+ -+#if defined(VGO_darwin) -+#define VG_WRAP_THREAD_FUNCTION_LIBPTHREAD_ONLY -+#elif defined(VGO_solaris) || (defined(VGO_linux) && defined(MUSL_LIBC)) -+#define VG_WRAP_THREAD_FUNCTION_LIBC_ONLY -+#elif defined(VGO_linux) -+#define VG_WRAP_THREAD_FUNCTION_LIBC_AND_LIBPTHREAD -+#else -+# error "Unknown platform" -+#endif -+ - #endif // __PUB_TOOL_REDIR_H - - /*--------------------------------------------------------------------*/ diff --git a/valgrind-3.16.1-readdwarf-line.patch b/valgrind-3.16.1-readdwarf-line.patch deleted file mode 100644 index cfe34a8..0000000 --- a/valgrind-3.16.1-readdwarf-line.patch +++ /dev/null @@ -1,53 +0,0 @@ -commit 67363912e9cdba83869a72ff8c4084e7a7e4ab85 -Author: Mark Wielaard -Date: Sun Feb 21 22:45:51 2021 +0100 - - Fix typo in DWARF 5 line table readers - - This typo meant the directory entry was most often zero, which - happened to be sometimes correct anyway (since zero is the compdir). - So for simple testcases it looked correct. But it would be wrong for - compilation units not in the current compdir. Like files compiled with - a relative of absolute path. - - The same typo was in both readdwarf.c (read_dwarf2_lineblock) and - readdwarf3.c (read_filename_table). read_dwarf2_lineblock also had - an extra "dwarf" string in the debug-line output. - - https://bugzilla.redhat.com/show_bug.cgi?id=1927153 - -diff --git a/coregrind/m_debuginfo/readdwarf.c b/coregrind/m_debuginfo/readdwarf.c -index 88d5d99f1..3996623ed 100644 ---- a/coregrind/m_debuginfo/readdwarf.c -+++ b/coregrind/m_debuginfo/readdwarf.c -@@ -683,7 +683,7 @@ void read_dwarf2_lineblock ( struct _DebugInfo* di, - directories_count = step_leb128U(&data); - /* Read the contents of the Directory table. */ - if (di->ddump_line) -- VG_(printf)(" dwarf The Directory Table%s\n", -+ VG_(printf)(" The Directory Table%s\n", - directories_count == 0 ? " is empty." : ":" ); - - for (n = 0; n < directories_count; n++) { -@@ -796,7 +796,7 @@ void read_dwarf2_lineblock ( struct _DebugInfo* di, - if (f == p_ndx) - name = get_line_str (di, ui, &data, form, - debugstr_img, debuglinestr_img); -- else if (n == d_ndx) -+ else if (f == d_ndx) - diridx = get_line_ndx (di, &data, form); - else - data = skip_line_form (di, ui, data, form); -diff --git a/coregrind/m_debuginfo/readdwarf3.c b/coregrind/m_debuginfo/readdwarf3.c -index 82bc8f241..60fc40244 100644 ---- a/coregrind/m_debuginfo/readdwarf3.c -+++ b/coregrind/m_debuginfo/readdwarf3.c -@@ -2323,7 +2323,7 @@ void read_filename_table( /*MOD*/XArray* /* of UInt* */ fndn_ix_Table, - if (f == p_ndx) - str = get_line_str (cc->di, cc->is_dw64, &c, form, - debugstr_img, debuglinestr_img); -- else if (n == d_ndx) -+ else if (f == d_ndx) - dir_xa_ix = get_line_ndx (cc->di, &c, form); - else - skip_line_form (cc->di, cc->is_dw64, &c, form); diff --git a/valgrind-3.16.1-s390_emit_load_mem.patch b/valgrind-3.16.1-s390_emit_load_mem.patch deleted file mode 100644 index 95da59f..0000000 --- a/valgrind-3.16.1-s390_emit_load_mem.patch +++ /dev/null @@ -1,27 +0,0 @@ -commit ba73f8d2ebe4b5fe8163ee5ab806f0e50961ebdf -Author: Andreas Arnez -Date: Tue Nov 3 18:17:30 2020 +0100 - - Bug 428648 - s390x: Force 12-bit amode for vector loads in isel - - Similar to Bug 417452, where the instruction selector sometimes attempted - to generate vector stores with a 20-bit displacement, the same problem has - now been reported with vector loads. - - The problem is caused in s390_isel_vec_expr_wrk(), where the addressing - mode is generated with s390_isel_amode() instead of - s390_isel_amode_short(). This is fixed. - -diff --git a/VEX/priv/host_s390_isel.c b/VEX/priv/host_s390_isel.c -index 2f80dd850..134f3eb6f 100644 ---- a/VEX/priv/host_s390_isel.c -+++ b/VEX/priv/host_s390_isel.c -@@ -3741,7 +3741,7 @@ s390_isel_vec_expr_wrk(ISelEnv *env, IRExpr *expr) - /* --------- LOAD --------- */ - case Iex_Load: { - HReg dst = newVRegV(env); -- s390_amode *am = s390_isel_amode(env, expr->Iex.Load.addr); -+ s390_amode *am = s390_isel_amode_short(env, expr->Iex.Load.addr); - - if (expr->Iex.Load.end != Iend_BE) - goto irreducible; diff --git a/valgrind-3.16.1-s390x-z14-vector.patch b/valgrind-3.16.1-s390x-z14-vector.patch deleted file mode 100644 index 747c8a8..0000000 --- a/valgrind-3.16.1-s390x-z14-vector.patch +++ /dev/null @@ -1,2977 +0,0 @@ -diff --git a/VEX/priv/guest_s390_defs.h b/VEX/priv/guest_s390_defs.h -index 9f93cff19..905429015 100644 ---- a/VEX/priv/guest_s390_defs.h -+++ b/VEX/priv/guest_s390_defs.h -@@ -8,7 +8,7 @@ - This file is part of Valgrind, a dynamic binary instrumentation - framework. - -- Copyright IBM Corp. 2010-2017 -+ Copyright IBM Corp. 2010-2020 - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as -@@ -263,26 +263,27 @@ extern ULong last_execute_target; - before S390_VEC_OP_LAST. */ - typedef enum { - 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_VFCE = 16, -- S390_VEC_OP_VFCH = 17, -- S390_VEC_OP_VFCHE = 18, -- S390_VEC_OP_VFTCI = 19, -- S390_VEC_OP_LAST = 20 // supposed to be the last element in enum -+ S390_VEC_OP_VPKS, -+ S390_VEC_OP_VPKLS, -+ S390_VEC_OP_VFAE, -+ S390_VEC_OP_VFEE, -+ S390_VEC_OP_VFENE, -+ S390_VEC_OP_VISTR, -+ S390_VEC_OP_VSTRC, -+ S390_VEC_OP_VCEQ, -+ S390_VEC_OP_VTM, -+ S390_VEC_OP_VGFM, -+ S390_VEC_OP_VGFMA, -+ S390_VEC_OP_VMAH, -+ S390_VEC_OP_VMALH, -+ S390_VEC_OP_VCH, -+ S390_VEC_OP_VCHL, -+ S390_VEC_OP_VFTCI, -+ S390_VEC_OP_VFMIN, -+ S390_VEC_OP_VFMAX, -+ S390_VEC_OP_VBPERM, -+ S390_VEC_OP_VMSL, -+ S390_VEC_OP_LAST // supposed to be the last element in enum - } s390x_vec_op_t; - - /* Arguments of s390x_dirtyhelper_vec_op(...) which are packed into one -diff --git a/VEX/priv/guest_s390_helpers.c b/VEX/priv/guest_s390_helpers.c -index a470d9f8d..b71b621ae 100644 ---- a/VEX/priv/guest_s390_helpers.c -+++ b/VEX/priv/guest_s390_helpers.c -@@ -8,7 +8,7 @@ - This file is part of Valgrind, a dynamic binary instrumentation - framework. - -- Copyright IBM Corp. 2010-2017 -+ Copyright IBM Corp. 2010-2020 - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as -@@ -314,20 +314,11 @@ ULong s390x_dirtyhelper_STCKE(ULong *addr) {return 3;} - /*--- Dirty helper for Store Facility instruction ---*/ - /*------------------------------------------------------------*/ - #if defined(VGA_s390x) --static void --s390_set_facility_bit(ULong *addr, UInt bitno, UInt value) --{ -- addr += bitno / 64; -- bitno = bitno % 64; -- -- ULong mask = 1; -- mask <<= (63 - bitno); - -- if (value == 1) { -- *addr |= mask; // set -- } else { -- *addr &= ~mask; // clear -- } -+static ULong -+s390_stfle_range(UInt lo, UInt hi) -+{ -+ return ((1UL << (hi + 1 - lo)) - 1) << (63 - (hi % 64)); - } - - ULong -@@ -336,6 +327,77 @@ s390x_dirtyhelper_STFLE(VexGuestS390XState *guest_state, ULong *addr) - ULong hoststfle[S390_NUM_FACILITY_DW], cc, num_dw, i; - register ULong reg0 asm("0") = guest_state->guest_r0 & 0xF; /* r0[56:63] */ - -+ /* Restrict to facilities that we know about and that we assume to be -+ compatible with Valgrind. Of course, in this way we may reject features -+ that Valgrind is not really involved in (and thus would be compatible -+ with), but quering for such features doesn't seem like a typical use -+ case. */ -+ ULong accepted_facility[S390_NUM_FACILITY_DW] = { -+ /* === 0 .. 63 === */ -+ (s390_stfle_range(0, 16) -+ /* 17: message-security-assist, not supported */ -+ | s390_stfle_range(18, 19) -+ /* 20: HFP-multiply-and-add/subtract, not supported */ -+ | s390_stfle_range(21, 22) -+ /* 23: HFP-unnormalized-extension, not supported */ -+ | s390_stfle_range(24, 25) -+ /* 26: parsing-enhancement, not supported */ -+ | s390_stfle_range(27, 28) -+ /* 29: unassigned */ -+ | s390_stfle_range(30, 30) -+ /* 31: extract-CPU-time, not supported */ -+ | s390_stfle_range(32, 41) -+ /* 42-43: DFP, not fully supported */ -+ /* 44: PFPO, not fully supported */ -+ | s390_stfle_range(45, 47) -+ /* 48: DFP zoned-conversion, not supported */ -+ /* 49: includes PPA, not supported */ -+ /* 50: constrained transactional-execution, not supported */ -+ | s390_stfle_range(51, 55) -+ /* 56: unassigned */ -+ /* 57: MSA5, not supported */ -+ | s390_stfle_range(58, 60) -+ /* 61: miscellaneous-instruction 3, not supported */ -+ | s390_stfle_range(62, 63)), -+ -+ /* === 64 .. 127 === */ -+ (s390_stfle_range(64, 72) -+ /* 73: transactional-execution, not supported */ -+ | s390_stfle_range(74, 75) -+ /* 76: MSA3, not supported */ -+ /* 77: MSA4, not supported */ -+ | s390_stfle_range(78, 78) -+ /* 80: DFP packed-conversion, not supported */ -+ /* 81: PPA-in-order, not supported */ -+ | s390_stfle_range(82, 82) -+ /* 83-127: unassigned */ ), -+ -+ /* === 128 .. 191 === */ -+ (s390_stfle_range(128, 131) -+ /* 132: unassigned */ -+ /* 133: guarded-storage, not supported */ -+ /* 134: vector packed decimal, not supported */ -+ | s390_stfle_range(135, 135) -+ /* 136: unassigned */ -+ /* 137: unassigned */ -+ | s390_stfle_range(138, 142) -+ /* 143: unassigned */ -+ | s390_stfle_range(144, 145) -+ /* 146: MSA8, not supported */ -+ | s390_stfle_range(147, 147) -+ /* 148: vector-enhancements 2, not supported */ -+ | s390_stfle_range(149, 149) -+ /* 150: unassigned */ -+ /* 151: DEFLATE-conversion, not supported */ -+ /* 153: unassigned */ -+ /* 154: unassigned */ -+ /* 155: MSA9, not supported */ -+ | s390_stfle_range(156, 156) -+ /* 157-167: unassigned */ -+ | s390_stfle_range(168, 168) -+ /* 168-191: unassigned */ ), -+ }; -+ - /* We cannot store more than S390_NUM_FACILITY_DW - (and it makes not much sense to do so anyhow) */ - if (reg0 > S390_NUM_FACILITY_DW - 1) -@@ -351,35 +413,9 @@ s390x_dirtyhelper_STFLE(VexGuestS390XState *guest_state, ULong *addr) - /* Update guest register 0 with what STFLE set r0 to */ - guest_state->guest_r0 = reg0; - -- /* Set default: VM facilities = host facilities */ -+ /* VM facilities = host facilities, filtered by acceptance */ - for (i = 0; i < num_dw; ++i) -- addr[i] = hoststfle[i]; -- -- /* Now adjust the VM facilities according to what the VM supports */ -- s390_set_facility_bit(addr, S390_FAC_LDISP, 1); -- s390_set_facility_bit(addr, S390_FAC_EIMM, 1); -- s390_set_facility_bit(addr, S390_FAC_ETF2, 1); -- s390_set_facility_bit(addr, S390_FAC_ETF3, 1); -- s390_set_facility_bit(addr, S390_FAC_GIE, 1); -- s390_set_facility_bit(addr, S390_FAC_EXEXT, 1); -- s390_set_facility_bit(addr, S390_FAC_HIGHW, 1); -- s390_set_facility_bit(addr, S390_FAC_LSC2, 1); -- -- s390_set_facility_bit(addr, S390_FAC_HFPMAS, 0); -- s390_set_facility_bit(addr, S390_FAC_HFPUNX, 0); -- s390_set_facility_bit(addr, S390_FAC_XCPUT, 0); -- s390_set_facility_bit(addr, S390_FAC_MSA, 0); -- s390_set_facility_bit(addr, S390_FAC_PENH, 0); -- s390_set_facility_bit(addr, S390_FAC_DFP, 0); -- s390_set_facility_bit(addr, S390_FAC_PFPO, 0); -- s390_set_facility_bit(addr, S390_FAC_DFPZC, 0); -- s390_set_facility_bit(addr, S390_FAC_MISC, 0); -- s390_set_facility_bit(addr, S390_FAC_CTREXE, 0); -- s390_set_facility_bit(addr, S390_FAC_TREXE, 0); -- s390_set_facility_bit(addr, S390_FAC_MSA4, 0); -- s390_set_facility_bit(addr, S390_FAC_VXE, 0); -- s390_set_facility_bit(addr, S390_FAC_VXE2, 0); -- s390_set_facility_bit(addr, S390_FAC_DFLT, 0); -+ addr[i] = hoststfle[i] & accepted_facility[i]; - - return cc; - } -@@ -2500,25 +2536,26 @@ s390x_dirtyhelper_vec_op(VexGuestS390XState *guest_state, - 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 */ -- {0xe7, 0xe8}, /* VFCE */ -- {0xe7, 0xeb}, /* VFCH */ -- {0xe7, 0xea}, /* VFCHE */ -- {0xe7, 0x4a} /* VFTCI */ -+ [S390_VEC_OP_VPKS] = {0xe7, 0x97}, -+ [S390_VEC_OP_VPKLS] = {0xe7, 0x95}, -+ [S390_VEC_OP_VFAE] = {0xe7, 0x82}, -+ [S390_VEC_OP_VFEE] = {0xe7, 0x80}, -+ [S390_VEC_OP_VFENE] = {0xe7, 0x81}, -+ [S390_VEC_OP_VISTR] = {0xe7, 0x5c}, -+ [S390_VEC_OP_VSTRC] = {0xe7, 0x8a}, -+ [S390_VEC_OP_VCEQ] = {0xe7, 0xf8}, -+ [S390_VEC_OP_VTM] = {0xe7, 0xd8}, -+ [S390_VEC_OP_VGFM] = {0xe7, 0xb4}, -+ [S390_VEC_OP_VGFMA] = {0xe7, 0xbc}, -+ [S390_VEC_OP_VMAH] = {0xe7, 0xab}, -+ [S390_VEC_OP_VMALH] = {0xe7, 0xa9}, -+ [S390_VEC_OP_VCH] = {0xe7, 0xfb}, -+ [S390_VEC_OP_VCHL] = {0xe7, 0xf9}, -+ [S390_VEC_OP_VFTCI] = {0xe7, 0x4a}, -+ [S390_VEC_OP_VFMIN] = {0xe7, 0xee}, -+ [S390_VEC_OP_VFMAX] = {0xe7, 0xef}, -+ [S390_VEC_OP_VBPERM]= {0xe7, 0x85}, -+ [S390_VEC_OP_VMSL] = {0xe7, 0xb8}, - }; - - union { -@@ -2612,6 +2649,7 @@ s390x_dirtyhelper_vec_op(VexGuestS390XState *guest_state, - case S390_VEC_OP_VGFMA: - case S390_VEC_OP_VMAH: - case S390_VEC_OP_VMALH: -+ case S390_VEC_OP_VMSL: - the_insn.VRRd.v1 = 1; - the_insn.VRRd.v2 = 2; - the_insn.VRRd.v3 = 3; -@@ -2621,9 +2659,9 @@ s390x_dirtyhelper_vec_op(VexGuestS390XState *guest_state, - the_insn.VRRd.m6 = d->m5; - break; - -- case S390_VEC_OP_VFCE: -- case S390_VEC_OP_VFCH: -- case S390_VEC_OP_VFCHE: -+ case S390_VEC_OP_VFMIN: -+ case S390_VEC_OP_VFMAX: -+ case S390_VEC_OP_VBPERM: - the_insn.VRRc.v1 = 1; - the_insn.VRRc.v2 = 2; - the_insn.VRRc.v3 = 3; -diff --git a/VEX/priv/guest_s390_toIR.c b/VEX/priv/guest_s390_toIR.c -index c27a8d3fe..5f2c5ce98 100644 ---- a/VEX/priv/guest_s390_toIR.c -+++ b/VEX/priv/guest_s390_toIR.c -@@ -8,7 +8,7 @@ - This file is part of Valgrind, a dynamic binary instrumentation - framework. - -- Copyright IBM Corp. 2010-2017 -+ Copyright IBM Corp. 2010-2020 - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as -@@ -248,6 +248,13 @@ typedef enum { - #define VRS_d2(insn) (((insn) >> 32) & 0xfff) - #define VRS_m4(insn) (((insn) >> 28) & 0xf) - #define VRS_rxb(insn) (((insn) >> 24) & 0xf) -+#define VRSd_v1(insn) (((insn) >> 28) & 0xf) -+#define VRSd_r3(insn) (((insn) >> 48) & 0xf) -+#define VSI_i3(insn) (((insn) >> 48) & 0xff) -+#define VSI_b2(insn) (((insn) >> 44) & 0xf) -+#define VSI_d2(insn) (((insn) >> 32) & 0xfff) -+#define VSI_v1(insn) (((insn) >> 28) & 0xf) -+#define VSI_rxb(insn) (((insn) >> 24) & 0xf) - - - /*------------------------------------------------------------*/ -@@ -1934,6 +1941,26 @@ s390_vr_get_type(const UChar m) - return results[m]; - } - -+/* Determine IRType from instruction's floating-point format field */ -+static IRType -+s390_vr_get_ftype(const UChar m) -+{ -+ static const IRType results[] = {Ity_F32, Ity_F64, Ity_F128}; -+ if (m >= 2 && m <= 4) -+ return results[m - 2]; -+ return Ity_INVALID; -+} -+ -+/* Determine number of elements from instruction's floating-point format -+ field */ -+static UChar -+s390_vr_get_n_elem(const UChar m) -+{ -+ if (m >= 2 && m <= 4) -+ return 1 << (4 - m); -+ return 0; -+} -+ - /* Determine if Condition Code Set (CS) flag is set in m field */ - #define s390_vr_is_cs_set(m) (((m) & 0x1) != 0) - -@@ -2188,12 +2215,15 @@ s390_vr_offset_by_index(UInt archreg,IRType type, UChar index) - goto invalidIndex; - } - return vr_offset(archreg) + sizeof(ULong) * index; -+ - case Ity_V128: -+ case Ity_F128: - if(index == 0) { - return vr_qw_offset(archreg); - } else { - goto invalidIndex; - } -+ - default: - vpanic("s390_vr_offset_by_index: unknown type"); - } -@@ -2211,7 +2241,14 @@ put_vr(UInt archreg, IRType type, UChar index, IRExpr *expr) - UInt offset = s390_vr_offset_by_index(archreg, type, index); - vassert(typeOfIRExpr(irsb->tyenv, expr) == type); - -- stmt(IRStmt_Put(offset, expr)); -+ if (type == Ity_F128) { -+ IRTemp val = newTemp(Ity_F128); -+ assign(val, expr); -+ stmt(IRStmt_Put(offset, unop(Iop_F128HItoF64, mkexpr(val)))); -+ stmt(IRStmt_Put(offset + 8, unop(Iop_F128LOtoF64, mkexpr(val)))); -+ } else { -+ stmt(IRStmt_Put(offset, expr)); -+ } - } - - /* Read type sized part specified by index of a vr register. */ -@@ -2219,6 +2256,11 @@ static IRExpr * - get_vr(UInt archreg, IRType type, UChar index) - { - UInt offset = s390_vr_offset_by_index(archreg, type, index); -+ if (type == Ity_F128) { -+ return binop(Iop_F64HLtoF128, -+ IRExpr_Get(offset, Ity_F64), -+ IRExpr_Get(offset + 8, Ity_F64)); -+ } - return IRExpr_Get(offset, type); - } - -@@ -2294,11 +2336,11 @@ s390_getCountToBlockBoundary(IRTemp op2addr, UChar m) - return mkexpr(output); - } - --/* Load bytes into v1. -- maxIndex specifies max index to load and must be Ity_I32. -- 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) -+/* Starting from addr, load at most maxIndex + 1 bytes into v1. Fill the -+ leftmost or rightmost bytes of v1, depending on whether `rightmost' is set. -+ If maxIndex >= 15, load all 16 bytes; otherwise clear the remaining bytes. */ -+static void -+s390_vr_loadWithLength(UChar v1, IRTemp addr, IRExpr *maxIndex, Bool rightmost) - { - IRTemp maxIdx = newTemp(Ity_I32); - IRTemp cappedMax = newTemp(Ity_I64); -@@ -2311,8 +2353,8 @@ static void s390_vr_loadWithLength(UChar v1, IRTemp addr, IRExpr *maxIndex) - 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. */ -+ from the unaligned address. Then shift the loaded data left- or -+ right-aligned into the target vector register. */ - - assign(maxIdx, maxIndex); - assign(cappedMax, mkite(binop(Iop_CmpLT32U, mkexpr(maxIdx), mkU32(15)), -@@ -2325,20 +2367,60 @@ static void s390_vr_loadWithLength(UChar v1, IRTemp addr, IRExpr *maxIndex) - 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)); -+ IRExpr* chunk = load(Ity_V128, binop(Iop_Sub64, mkexpr(addr), mkexpr(back))); -+ -+ /* Shift the loaded 16-byte vector to the right, then to the left, or vice -+ versa, where each shift amount ranges from 0 to 120. */ -+ IRExpr* shift1; -+ IRExpr* shift2 = unop(Iop_64to8, binop(Iop_Shl64, mkexpr(zeroed), mkU8(3))); -+ -+ if (rightmost) { -+ shift1 = unop(Iop_64to8, binop(Iop_Shl64, mkexpr(back), mkU8(3))); -+ put_vr_qw(v1, binop(Iop_ShrV128, -+ binop(Iop_ShlV128, chunk, shift1), -+ shift2)); -+ } else { -+ shift1 = unop(Iop_64to8, -+ binop(Iop_Shl64, -+ binop(Iop_Sub64, mkexpr(zeroed), mkexpr(back)), -+ mkU8(3))); -+ put_vr_qw(v1, binop(Iop_ShlV128, -+ binop(Iop_ShrV128, chunk, shift1), -+ shift2)); -+ } -+} -+ -+/* Store at most maxIndex + 1 bytes from v1 to addr. Store the leftmost or -+ rightmost bytes of v1, depending on whether `rightmost' is set. If maxIndex -+ >= 15, store all 16 bytes. */ -+static void -+s390_vr_storeWithLength(UChar v1, IRTemp addr, IRExpr *maxIndex, Bool rightmost) -+{ -+ IRTemp maxIdx = newTemp(Ity_I32); -+ IRTemp cappedMax = newTemp(Ity_I64); -+ IRTemp counter = newTemp(Ity_I64); -+ IRExpr* offset; -+ -+ assign(maxIdx, maxIndex); -+ assign(cappedMax, mkite(binop(Iop_CmpLT32U, mkexpr(maxIdx), mkU32(15)), -+ unop(Iop_32Uto64, mkexpr(maxIdx)), mkU64(15))); -+ -+ assign(counter, get_counter_dw0()); -+ -+ if (rightmost) -+ offset = binop(Iop_Add64, -+ binop(Iop_Sub64, mkU64(15), mkexpr(cappedMax)), -+ mkexpr(counter)); -+ else -+ offset = mkexpr(counter); -+ -+ store(binop(Iop_Add64, mkexpr(addr), mkexpr(counter)), -+ binop(Iop_GetElem8x16, get_vr_qw(v1), unop(Iop_64to8, offset))); - -- 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))); -+ /* Check for end of field */ -+ put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1))); -+ iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(cappedMax))); -+ put_counter_dw0(mkU64(0)); - } - - /* Bitwise vCond ? v1 : v2 -@@ -3749,6 +3831,28 @@ s390_format_VRS_RRDVM(const HChar *(*irgen)(UChar r1, IRTemp op2addr, UChar v3, - s390_disasm(ENC5(MNM, GPR, UDXB, VR, UINT), mnm, r1, d2, 0, b2, v3, m4); - } - -+static void -+s390_format_VRS_RRDV(const HChar *(*irgen)(UChar v1, UChar r3, IRTemp op2addr), -+ UChar v1, UChar r3, UChar b2, UShort d2, 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, 4, rxb); -+ mnm = irgen(v1, r3, op2addr); -+ -+ if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) -+ s390_disasm(ENC4(MNM, VR, GPR, UDXB), mnm, v1, r3, d2, 0, b2); -+} -+ - - static void - s390_format_VRS_VRDVM(const HChar *(*irgen)(UChar v1, IRTemp op2addr, UChar v3, -@@ -4081,6 +4185,29 @@ s390_format_VRRa_VVVMMM(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3, - mnm, v1, v2, v3, m4, m5, m6); - } - -+static void -+s390_format_VSI_URDV(const HChar *(*irgen)(UChar v1, IRTemp op2addr, UChar i3), -+ UChar v1, UChar b2, UChar d2, UChar i3, UChar rxb) -+{ -+ const HChar *mnm; -+ IRTemp op2addr = newTemp(Ity_I64); -+ -+ if (!s390_host_has_vx) { -+ emulation_failure(EmFail_S390X_vx); -+ return; -+ } -+ -+ v1 = s390_vr_getVRindex(v1, 4, rxb); -+ -+ assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) : -+ mkU64(0))); -+ -+ mnm = irgen(v1, op2addr, i3); -+ -+ if (vex_traceflags & VEX_TRACE_FE) -+ s390_disasm(ENC4(MNM, VR, UDXB, UINT), mnm, v1, d2, 0, b2, i3); -+} -+ - /*------------------------------------------------------------*/ - /*--- Build IR for opcodes ---*/ - /*------------------------------------------------------------*/ -@@ -16186,7 +16313,9 @@ s390_irgen_VGM(UChar v1, UShort i2, UChar m3) - static const HChar * - s390_irgen_VLLEZ(UChar v1, IRTemp op2addr, UChar m3) - { -- IRType type = s390_vr_get_type(m3); -+ s390_insn_assert("vllez", m3 <= 3 || m3 == 6); -+ -+ IRType type = s390_vr_get_type(m3 & 3); - IRExpr* op2 = load(type, mkexpr(op2addr)); - IRExpr* op2as64bit; - switch (type) { -@@ -16206,7 +16335,13 @@ s390_irgen_VLLEZ(UChar v1, IRTemp op2addr, UChar m3) - vpanic("s390_irgen_VLLEZ: unknown type"); - } - -- put_vr_dw0(v1, op2as64bit); -+ if (m3 == 6) { -+ /* left-aligned */ -+ put_vr_dw0(v1, binop(Iop_Shl64, op2as64bit, mkU8(32))); -+ } else { -+ /* right-aligned */ -+ put_vr_dw0(v1, op2as64bit); -+ } - put_vr_dw1(v1, mkU64(0)); - return "vllez"; - } -@@ -16615,7 +16750,7 @@ s390_irgen_VLBB(UChar v1, IRTemp addr, UChar m3) - s390_getCountToBlockBoundary(addr, m3), - mkU32(1)); - -- s390_vr_loadWithLength(v1, addr, maxIndex); -+ s390_vr_loadWithLength(v1, addr, maxIndex, False); - - return "vlbb"; - } -@@ -16623,41 +16758,50 @@ s390_irgen_VLBB(UChar v1, IRTemp addr, UChar m3) - static const HChar * - s390_irgen_VLL(UChar v1, IRTemp addr, UChar r3) - { -- s390_vr_loadWithLength(v1, addr, get_gpr_w1(r3)); -+ s390_vr_loadWithLength(v1, addr, get_gpr_w1(r3), False); - - return "vll"; - } - - static const HChar * --s390_irgen_VSTL(UChar v1, IRTemp addr, UChar r3) -+s390_irgen_VLRL(UChar v1, IRTemp addr, UChar i3) - { -- IRTemp counter = newTemp(Ity_I64); -- IRTemp maxIndexToStore = newTemp(Ity_I64); -- IRTemp gpr3 = newTemp(Ity_I64); -- -- assign(gpr3, unop(Iop_32Uto64, get_gpr_w1(r3))); -- assign(maxIndexToStore, mkite(binop(Iop_CmpLE64U, -- mkexpr(gpr3), -- mkU64(16) -- ), -- mkexpr(gpr3), -- mkU64(16) -- ) -- ); -+ s390_insn_assert("vlrl", (i3 & 0xf0) == 0); -+ s390_vr_loadWithLength(v1, addr, mkU32((UInt) i3), True); - -- assign(counter, get_counter_dw0()); -+ return "vlrl"; -+} - -- store(binop(Iop_Add64, mkexpr(addr), mkexpr(counter)), -- binop(Iop_GetElem8x16, get_vr_qw(v1), unop(Iop_64to8, mkexpr(counter)))); -+static const HChar * -+s390_irgen_VLRLR(UChar v1, UChar r3, IRTemp addr) -+{ -+ s390_vr_loadWithLength(v1, addr, get_gpr_w1(r3), True); - -- /* Check for end of field */ -- put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1))); -- iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(maxIndexToStore))); -- put_counter_dw0(mkU64(0)); -+ return "vlrlr"; -+} - -+static const HChar * -+s390_irgen_VSTL(UChar v1, IRTemp addr, UChar r3) -+{ -+ s390_vr_storeWithLength(v1, addr, get_gpr_w1(r3), False); - return "vstl"; - } - -+static const HChar * -+s390_irgen_VSTRL(UChar v1, IRTemp addr, UChar i3) -+{ -+ s390_insn_assert("vstrl", (i3 & 0xf0) == 0); -+ s390_vr_storeWithLength(v1, addr, mkU32((UInt) i3), True); -+ return "vstrl"; -+} -+ -+static const HChar * -+s390_irgen_VSTRLR(UChar v1, UChar r3, IRTemp addr) -+{ -+ s390_vr_storeWithLength(v1, addr, get_gpr_w1(r3), True); -+ return "vstrlr"; -+} -+ - static const HChar * - s390_irgen_VX(UChar v1, UChar v2, UChar v3) - { -@@ -16682,6 +16826,24 @@ s390_irgen_VO(UChar v1, UChar v2, UChar v3) - return "vo"; - } - -+static const HChar * -+s390_irgen_VOC(UChar v1, UChar v2, UChar v3) -+{ -+ put_vr_qw(v1, binop(Iop_OrV128, get_vr_qw(v2), -+ unop(Iop_NotV128, get_vr_qw(v3)))); -+ -+ return "voc"; -+} -+ -+static const HChar * -+s390_irgen_VNN(UChar v1, UChar v2, UChar v3) -+{ -+ put_vr_qw(v1, unop(Iop_NotV128, -+ binop(Iop_AndV128, get_vr_qw(v2), get_vr_qw(v3)))); -+ -+ return "vnn"; -+} -+ - static const HChar * - s390_irgen_VNO(UChar v1, UChar v2, UChar v3) - { -@@ -16691,6 +16853,15 @@ s390_irgen_VNO(UChar v1, UChar v2, UChar v3) - return "vno"; - } - -+static const HChar * -+s390_irgen_VNX(UChar v1, UChar v2, UChar v3) -+{ -+ put_vr_qw(v1, unop(Iop_NotV128, -+ binop(Iop_XorV128, get_vr_qw(v2), get_vr_qw(v3)))); -+ -+ return "vnx"; -+} -+ - static const HChar * - s390_irgen_LZRF(UChar r1, IRTemp op2addr) - { -@@ -17499,9 +17670,19 @@ s390_irgen_VCTZ(UChar v1, UChar v2, UChar m3) - static const HChar * - s390_irgen_VPOPCT(UChar v1, UChar v2, UChar m3) - { -- vassert(m3 == 0); -+ s390_insn_assert("vpopct", m3 <= 3); -+ -+ IRExpr* cnt = unop(Iop_Cnt8x16, get_vr_qw(v2)); - -- put_vr_qw(v1, unop(Iop_Cnt8x16, get_vr_qw(v2))); -+ if (m3 >= 1) { -+ cnt = unop(Iop_PwAddL8Ux16, cnt); -+ if (m3 >= 2) { -+ cnt = unop(Iop_PwAddL16Ux8, cnt); -+ if (m3 == 3) -+ cnt = unop(Iop_PwAddL32Ux4, cnt); -+ } -+ } -+ put_vr_qw(v1, cnt); - - return "vpopct"; - } -@@ -18335,12 +18516,53 @@ s390_irgen_VMALH(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5) - return "vmalh"; - } - -+static const HChar * -+s390_irgen_VMSL(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5, UChar m6) -+{ -+ s390_insn_assert("vmsl", m5 == 3 && (m6 & 3) == 0); -+ -+ IRDirty* d; -+ IRTemp cc = newTemp(Ity_I64); -+ -+ s390x_vec_op_details_t details = { .serialized = 0ULL }; -+ details.op = S390_VEC_OP_VMSL; -+ details.v1 = v1; -+ details.v2 = v2; -+ details.v3 = v3; -+ details.v4 = v4; -+ details.m4 = m5; -+ details.m5 = m6; -+ -+ d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op", -+ &s390x_dirtyhelper_vec_op, -+ mkIRExprVec_2(IRExpr_GSPTR(), -+ mkU64(details.serialized))); -+ -+ d->nFxState = 4; -+ 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); -+ d->fxState[0].size = sizeof(V128); -+ 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_Read; -+ d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v4 * sizeof(V128); -+ d->fxState[2].size = sizeof(V128); -+ d->fxState[3].fx = Ifx_Write; -+ d->fxState[3].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128); -+ d->fxState[3].size = sizeof(V128); -+ -+ stmt(IRStmt_Dirty(d)); -+ -+ return "vmsl"; -+} -+ - static void --s390_vector_fp_convert(IROp op, IRType fromType, IRType toType, -+s390_vector_fp_convert(IROp op, IRType fromType, IRType toType, Bool rounding, - UChar v1, UChar v2, UChar m3, UChar m4, UChar m5) - { - Bool isSingleElementOp = s390_vr_is_single_element_control_set(m4); -- UChar maxIndex = isSingleElementOp ? 0 : 1; - - /* For Iop_F32toF64 we do this: - f32[0] -> f64[0] -@@ -18353,14 +18575,21 @@ s390_vector_fp_convert(IROp op, IRType fromType, IRType toType, - The magic below with scaling factors is used to achieve the logic - described above. - */ -- const UChar sourceIndexScaleFactor = (op == Iop_F32toF64) ? 2 : 1; -- const UChar destinationIndexScaleFactor = (op == Iop_F64toF32) ? 2 : 1; -- -- const Bool isUnary = (op == Iop_F32toF64); -- for (UChar i = 0; i <= maxIndex; i++) { -+ Int size_diff = sizeofIRType(toType) - sizeofIRType(fromType); -+ const UChar sourceIndexScaleFactor = size_diff > 0 ? 2 : 1; -+ const UChar destinationIndexScaleFactor = size_diff < 0 ? 2 : 1; -+ UChar n_elem = (isSingleElementOp ? 1 : -+ 16 / (size_diff > 0 ? -+ sizeofIRType(toType) : sizeofIRType(fromType))); -+ -+ for (UChar i = 0; i < n_elem; i++) { - IRExpr* argument = get_vr(v2, fromType, i * sourceIndexScaleFactor); - IRExpr* result; -- if (!isUnary) { -+ if (rounding) { -+ if (!s390_host_has_fpext && m5 != S390_BFP_ROUND_PER_FPC) { -+ emulation_warning(EmWarn_S390X_fpext_rounding); -+ m5 = S390_BFP_ROUND_PER_FPC; -+ } - result = binop(op, - mkexpr(encode_bfp_rounding_mode(m5)), - argument); -@@ -18369,10 +18598,6 @@ s390_vector_fp_convert(IROp op, IRType fromType, IRType toType, - } - put_vr(v1, toType, i * destinationIndexScaleFactor, result); - } -- -- if (isSingleElementOp) { -- put_vr_dw1(v1, mkU64(0)); -- } - } - - static const HChar * -@@ -18380,12 +18605,8 @@ s390_irgen_VCDG(UChar v1, UChar v2, UChar m3, UChar m4, UChar m5) - { - s390_insn_assert("vcdg", m3 == 3); - -- if (!s390_host_has_fpext && m5 != S390_BFP_ROUND_PER_FPC) { -- emulation_warning(EmWarn_S390X_fpext_rounding); -- m5 = S390_BFP_ROUND_PER_FPC; -- } -- -- s390_vector_fp_convert(Iop_I64StoF64, Ity_I64, Ity_F64, v1, v2, m3, m4, m5); -+ s390_vector_fp_convert(Iop_I64StoF64, Ity_I64, Ity_F64, True, -+ v1, v2, m3, m4, m5); - - return "vcdg"; - } -@@ -18395,12 +18616,8 @@ s390_irgen_VCDLG(UChar v1, UChar v2, UChar m3, UChar m4, UChar m5) - { - s390_insn_assert("vcdlg", m3 == 3); - -- if (!s390_host_has_fpext && m5 != S390_BFP_ROUND_PER_FPC) { -- emulation_warning(EmWarn_S390X_fpext_rounding); -- m5 = S390_BFP_ROUND_PER_FPC; -- } -- -- s390_vector_fp_convert(Iop_I64UtoF64, Ity_I64, Ity_F64, v1, v2, m3, m4, m5); -+ s390_vector_fp_convert(Iop_I64UtoF64, Ity_I64, Ity_F64, True, -+ v1, v2, m3, m4, m5); - - return "vcdlg"; - } -@@ -18410,12 +18627,8 @@ s390_irgen_VCGD(UChar v1, UChar v2, UChar m3, UChar m4, UChar m5) - { - s390_insn_assert("vcgd", m3 == 3); - -- if (!s390_host_has_fpext && m5 != S390_BFP_ROUND_PER_FPC) { -- emulation_warning(EmWarn_S390X_fpext_rounding); -- m5 = S390_BFP_ROUND_PER_FPC; -- } -- -- s390_vector_fp_convert(Iop_F64toI64S, Ity_F64, Ity_I64, v1, v2, m3, m4, m5); -+ s390_vector_fp_convert(Iop_F64toI64S, Ity_F64, Ity_I64, True, -+ v1, v2, m3, m4, m5); - - return "vcgd"; - } -@@ -18425,12 +18638,8 @@ s390_irgen_VCLGD(UChar v1, UChar v2, UChar m3, UChar m4, UChar m5) - { - s390_insn_assert("vclgd", m3 == 3); - -- if (!s390_host_has_fpext && m5 != S390_BFP_ROUND_PER_FPC) { -- emulation_warning(EmWarn_S390X_fpext_rounding); -- m5 = S390_BFP_ROUND_PER_FPC; -- } -- -- s390_vector_fp_convert(Iop_F64toI64U, Ity_F64, Ity_I64, v1, v2, m3, m4, m5); -+ s390_vector_fp_convert(Iop_F64toI64U, Ity_F64, Ity_I64, True, -+ v1, v2, m3, m4, m5); - - return "vclgd"; - } -@@ -18438,246 +18647,262 @@ s390_irgen_VCLGD(UChar v1, UChar v2, UChar m3, UChar m4, UChar m5) - static const HChar * - s390_irgen_VFI(UChar v1, UChar v2, UChar m3, UChar m4, UChar m5) - { -- s390_insn_assert("vfi", m3 == 3); -+ s390_insn_assert("vfi", -+ (m3 == 3 || (s390_host_has_vxe && m3 >= 2 && m3 <= 4))); - -- if (!s390_host_has_fpext && m5 != S390_BFP_ROUND_PER_FPC) { -- emulation_warning(EmWarn_S390X_fpext_rounding); -- m5 = S390_BFP_ROUND_PER_FPC; -+ switch (m3) { -+ case 2: s390_vector_fp_convert(Iop_RoundF32toInt, Ity_F32, Ity_F32, True, -+ v1, v2, m3, m4, m5); break; -+ case 3: s390_vector_fp_convert(Iop_RoundF64toInt, Ity_F64, Ity_F64, True, -+ v1, v2, m3, m4, m5); break; -+ case 4: s390_vector_fp_convert(Iop_RoundF128toInt, Ity_F128, Ity_F128, True, -+ v1, v2, m3, m4, m5); break; - } - -- s390_vector_fp_convert(Iop_RoundF64toInt, Ity_F64, Ity_F64, -- v1, v2, m3, m4, m5); -- -- return "vcgld"; -+ return "vfi"; - } - - static const HChar * --s390_irgen_VLDE(UChar v1, UChar v2, UChar m3, UChar m4, UChar m5) -+s390_irgen_VFLL(UChar v1, UChar v2, UChar m3, UChar m4, UChar m5) - { -- s390_insn_assert("vlde", m3 == 2); -+ s390_insn_assert("vfll", m3 == 2 || (s390_host_has_vxe && m3 == 3)); - -- s390_vector_fp_convert(Iop_F32toF64, Ity_F32, Ity_F64, v1, v2, m3, m4, m5); -+ if (m3 == 2) -+ s390_vector_fp_convert(Iop_F32toF64, Ity_F32, Ity_F64, False, -+ v1, v2, m3, m4, m5); -+ else -+ s390_vector_fp_convert(Iop_F64toF128, Ity_F64, Ity_F128, False, -+ v1, v2, m3, m4, m5); - -- return "vlde"; -+ return "vfll"; - } - - static const HChar * --s390_irgen_VLED(UChar v1, UChar v2, UChar m3, UChar m4, UChar m5) -+s390_irgen_VFLR(UChar v1, UChar v2, UChar m3, UChar m4, UChar m5) - { -- s390_insn_assert("vled", m3 == 3); -- -- if (!s390_host_has_fpext && m5 != S390_BFP_ROUND_PER_FPC) { -- m5 = S390_BFP_ROUND_PER_FPC; -- } -+ s390_insn_assert("vflr", m3 == 3 || (s390_host_has_vxe && m3 == 2)); - -- s390_vector_fp_convert(Iop_F64toF32, Ity_F64, Ity_F32, v1, v2, m3, m4, m5); -+ if (m3 == 3) -+ s390_vector_fp_convert(Iop_F64toF32, Ity_F64, Ity_F32, True, -+ v1, v2, m3, m4, m5); -+ else -+ s390_vector_fp_convert(Iop_F128toF64, Ity_F128, Ity_F64, True, -+ v1, v2, m3, m4, m5); - -- return "vled"; -+ return "vflr"; - } - - static const HChar * - s390_irgen_VFPSO(UChar v1, UChar v2, UChar m3, UChar m4, UChar m5) - { -- s390_insn_assert("vfpso", m3 == 3); -- -- IRExpr* result; -- switch (m5) { -- case 0: { -- /* Invert sign */ -- if (!s390_vr_is_single_element_control_set(m4)) { -- result = unop(Iop_Neg64Fx2, get_vr_qw(v2)); -- } -- else { -- result = binop(Iop_64HLtoV128, -- unop(Iop_ReinterpF64asI64, -- unop(Iop_NegF64, get_vr(v2, Ity_F64, 0))), -- mkU64(0)); -- } -- break; -- } -+ s390_insn_assert("vfpso", m5 <= 2 && -+ (m3 == 3 || (s390_host_has_vxe && m3 >= 2 && m3 <= 4))); - -- case 1: { -- /* Set sign to negative */ -- IRExpr* highHalf = mkU64(0x8000000000000000ULL); -- if (!s390_vr_is_single_element_control_set(m4)) { -- IRExpr* lowHalf = highHalf; -- IRExpr* mask = binop(Iop_64HLtoV128, highHalf, lowHalf); -- result = binop(Iop_OrV128, get_vr_qw(v2), mask); -- } -- else { -- result = binop(Iop_64HLtoV128, -- binop(Iop_Or64, get_vr_dw0(v2), highHalf), -- mkU64(0ULL)); -- } -+ Bool single = s390_vr_is_single_element_control_set(m4) || m3 == 4; -+ IRType type = single ? s390_vr_get_ftype(m3) : Ity_V128; -+ int idx = 2 * (m3 - 2) + (single ? 0 : 1); - -- break; -- } -- -- case 2: { -- /* Set sign to positive */ -- if (!s390_vr_is_single_element_control_set(m4)) { -- result = unop(Iop_Abs64Fx2, get_vr_qw(v2)); -- } -- else { -- result = binop(Iop_64HLtoV128, -- unop(Iop_ReinterpF64asI64, -- unop(Iop_AbsF64, get_vr(v2, Ity_F64, 0))), -- mkU64(0)); -- } -- -- break; -- } -- -- default: -- vpanic("s390_irgen_VFPSO: Invalid m5 value"); -- } -+ static const IROp negate_ops[] = { -+ Iop_NegF32, Iop_Neg32Fx4, -+ Iop_NegF64, Iop_Neg64Fx2, -+ Iop_NegF128 -+ }; -+ static const IROp abs_ops[] = { -+ Iop_AbsF32, Iop_Abs32Fx4, -+ Iop_AbsF64, Iop_Abs64Fx2, -+ Iop_AbsF128 -+ }; - -- put_vr_qw(v1, result); -- if (s390_vr_is_single_element_control_set(m4)) { -- put_vr_dw1(v1, mkU64(0ULL)); -+ if (m5 == 1) { -+ /* Set sign to negative */ -+ put_vr(v1, type, 0, -+ unop(negate_ops[idx], -+ unop(abs_ops[idx], get_vr(v2, type, 0)))); -+ } else { -+ /* m5 == 0: invert sign; m5 == 2: set sign to positive */ -+ const IROp *ops = m5 == 2 ? abs_ops : negate_ops; -+ put_vr(v1, type, 0, unop(ops[idx], get_vr(v2, type, 0))); - } - - return "vfpso"; - } - --static void s390x_vec_fp_binary_op(IROp generalOp, IROp singleElementOp, -- UChar v1, UChar v2, UChar v3, UChar m4, -- UChar m5) -+static const HChar * -+s390x_vec_fp_binary_op(const HChar* mnm, const IROp ops[], -+ UChar v1, UChar v2, UChar v3, -+ UChar m4, UChar m5) - { -- IRExpr* result; -- if (!s390_vr_is_single_element_control_set(m5)) { -- result = triop(generalOp, get_bfp_rounding_mode_from_fpc(), -- get_vr_qw(v2), get_vr_qw(v3)); -+ s390_insn_assert(mnm, (m5 & 7) == 0 && -+ (m4 == 3 || (s390_host_has_vxe && m4 >= 2 && m4 <= 4))); -+ -+ int idx = 2 * (m4 - 2); -+ -+ if (m4 == 4 || s390_vr_is_single_element_control_set(m5)) { -+ IRType type = s390_vr_get_ftype(m4); -+ put_vr(v1, type, 0, -+ triop(ops[idx], get_bfp_rounding_mode_from_fpc(), -+ get_vr(v2, type, 0), get_vr(v3, type, 0))); - } else { -- IRExpr* highHalf = triop(singleElementOp, -- get_bfp_rounding_mode_from_fpc(), -- get_vr(v2, Ity_F64, 0), -- get_vr(v3, Ity_F64, 0)); -- result = binop(Iop_64HLtoV128, unop(Iop_ReinterpF64asI64, highHalf), -- mkU64(0ULL)); -+ put_vr_qw(v1, triop(ops[idx + 1], get_bfp_rounding_mode_from_fpc(), -+ get_vr_qw(v2), get_vr_qw(v3))); - } - -- put_vr_qw(v1, result); -+ return mnm; - } - --static void s390x_vec_fp_unary_op(IROp generalOp, IROp singleElementOp, -- UChar v1, UChar v2, UChar m3, UChar m4) -+static const HChar * -+s390x_vec_fp_unary_op(const HChar* mnm, const IROp ops[], -+ UChar v1, UChar v2, UChar m3, UChar m4) - { -- IRExpr* result; -- if (!s390_vr_is_single_element_control_set(m4)) { -- result = binop(generalOp, get_bfp_rounding_mode_from_fpc(), -- get_vr_qw(v2)); -+ s390_insn_assert(mnm, (m4 & 7) == 0 && -+ (m3 == 3 || (s390_host_has_vxe && m3 >= 2 && m3 <= 4))); -+ -+ int idx = 2 * (m3 - 2); -+ -+ if (m3 == 4 || s390_vr_is_single_element_control_set(m4)) { -+ IRType type = s390_vr_get_ftype(m3); -+ put_vr(v1, type, 0, -+ binop(ops[idx], get_bfp_rounding_mode_from_fpc(), -+ get_vr(v2, type, 0))); - } - else { -- IRExpr* highHalf = binop(singleElementOp, -- get_bfp_rounding_mode_from_fpc(), -- get_vr(v2, Ity_F64, 0)); -- result = binop(Iop_64HLtoV128, unop(Iop_ReinterpF64asI64, highHalf), -- mkU64(0ULL)); -+ put_vr_qw(v1, binop(ops[idx + 1], get_bfp_rounding_mode_from_fpc(), -+ get_vr_qw(v2))); - } - -- put_vr_qw(v1, result); -+ return mnm; - } - - --static void --s390_vector_fp_mulAddOrSub(IROp singleElementOp, -- UChar v1, UChar v2, UChar v3, UChar v4, -- UChar m5, UChar m6) -+static const HChar * -+s390_vector_fp_mulAddOrSub(UChar v1, UChar v2, UChar v3, UChar v4, -+ UChar m5, UChar m6, -+ const HChar* mnm, const IROp single_ops[], -+ Bool negate) - { -- Bool isSingleElementOp = s390_vr_is_single_element_control_set(m5); -+ s390_insn_assert(mnm, m6 == 3 || (s390_host_has_vxe && m6 >= 2 && m6 <= 4)); -+ -+ static const IROp negate_ops[] = { Iop_NegF32, Iop_NegF64, Iop_NegF128 }; -+ IRType type = s390_vr_get_ftype(m6); -+ Bool single = s390_vr_is_single_element_control_set(m5) || m6 == 4; -+ UChar n_elem = single ? 1 : s390_vr_get_n_elem(m6); - IRTemp irrm_temp = newTemp(Ity_I32); - assign(irrm_temp, get_bfp_rounding_mode_from_fpc()); - IRExpr* irrm = mkexpr(irrm_temp); -- IRExpr* result; -- IRExpr* highHalf = qop(singleElementOp, -- irrm, -- get_vr(v2, Ity_F64, 0), -- get_vr(v3, Ity_F64, 0), -- get_vr(v4, Ity_F64, 0)); -- -- if (isSingleElementOp) { -- result = binop(Iop_64HLtoV128, unop(Iop_ReinterpF64asI64, highHalf), -- mkU64(0ULL)); -- } else { -- IRExpr* lowHalf = qop(singleElementOp, -- irrm, -- get_vr(v2, Ity_F64, 1), -- get_vr(v3, Ity_F64, 1), -- get_vr(v4, Ity_F64, 1)); -- result = binop(Iop_64HLtoV128, unop(Iop_ReinterpF64asI64, highHalf), -- unop(Iop_ReinterpF64asI64, lowHalf)); -- } - -- put_vr_qw(v1, result); -+ for (UChar idx = 0; idx < n_elem; idx++) { -+ IRExpr* result = qop(single_ops[m6 - 2], -+ irrm, -+ get_vr(v2, type, idx), -+ get_vr(v3, type, idx), -+ get_vr(v4, type, idx)); -+ put_vr(v1, type, idx, negate ? unop(negate_ops[m6 - 2], result) : result); -+ } -+ return mnm; - } - - static const HChar * - s390_irgen_VFA(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5) - { -- s390_insn_assert("vfa", m4 == 3); -- s390x_vec_fp_binary_op(Iop_Add64Fx2, Iop_AddF64, v1, v2, v3, m4, m5); -- return "vfa"; -+ static const IROp vfa_ops[] = { -+ Iop_AddF32, Iop_Add32Fx4, -+ Iop_AddF64, Iop_Add64Fx2, -+ Iop_AddF128, -+ }; -+ return s390x_vec_fp_binary_op("vfa", vfa_ops, v1, v2, v3, m4, m5); - } - - static const HChar * - s390_irgen_VFS(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5) - { -- s390_insn_assert("vfs", m4 == 3); -- s390x_vec_fp_binary_op(Iop_Sub64Fx2, Iop_SubF64, v1, v2, v3, m4, m5); -- return "vfs"; -+ static const IROp vfs_ops[] = { -+ Iop_SubF32, Iop_Sub32Fx4, -+ Iop_SubF64, Iop_Sub64Fx2, -+ Iop_SubF128, -+ }; -+ return s390x_vec_fp_binary_op("vfs", vfs_ops, v1, v2, v3, m4, m5); - } - - static const HChar * - s390_irgen_VFM(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5) - { -- s390_insn_assert("vfm", m4 == 3); -- s390x_vec_fp_binary_op(Iop_Mul64Fx2, Iop_MulF64, v1, v2, v3, m4, m5); -- return "vfm"; -+ static const IROp vfm_ops[] = { -+ Iop_MulF32, Iop_Mul32Fx4, -+ Iop_MulF64, Iop_Mul64Fx2, -+ Iop_MulF128, -+ }; -+ return s390x_vec_fp_binary_op("vfm", vfm_ops, v1, v2, v3, m4, m5); - } - - static const HChar * - s390_irgen_VFD(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5) - { -- s390_insn_assert("vfd", m4 == 3); -- s390x_vec_fp_binary_op(Iop_Div64Fx2, Iop_DivF64, v1, v2, v3, m4, m5); -- return "vfd"; -+ static const IROp vfd_ops[] = { -+ Iop_DivF32, Iop_Div32Fx4, -+ Iop_DivF64, Iop_Div64Fx2, -+ Iop_DivF128, -+ }; -+ return s390x_vec_fp_binary_op("vfd", vfd_ops, v1, v2, v3, m4, m5); - } - - static const HChar * - s390_irgen_VFSQ(UChar v1, UChar v2, UChar m3, UChar m4) - { -- s390_insn_assert("vfsq", m3 == 3); -- s390x_vec_fp_unary_op(Iop_Sqrt64Fx2, Iop_SqrtF64, v1, v2, m3, m4); -- -- return "vfsq"; -+ static const IROp vfsq_ops[] = { -+ Iop_SqrtF32, Iop_Sqrt32Fx4, -+ Iop_SqrtF64, Iop_Sqrt64Fx2, -+ Iop_SqrtF128 -+ }; -+ return s390x_vec_fp_unary_op("vfsq", vfsq_ops, v1, v2, m3, m4); - } - -+static const IROp FMA_single_ops[] = { -+ Iop_MAddF32, Iop_MAddF64, Iop_MAddF128 -+}; -+ - static const HChar * - s390_irgen_VFMA(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5, UChar m6) - { -- s390_insn_assert("vfma", m6 == 3); -- s390_vector_fp_mulAddOrSub(Iop_MAddF64, v1, v2, v3, v4, m5, m6); -- return "vfma"; -+ return s390_vector_fp_mulAddOrSub(v1, v2, v3, v4, m5, m6, -+ "vfma", FMA_single_ops, False); - } - -+static const HChar * -+s390_irgen_VFNMA(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5, UChar m6) -+{ -+ return s390_vector_fp_mulAddOrSub(v1, v2, v3, v4, m5, m6, -+ "vfnma", FMA_single_ops, True); -+} -+ -+static const IROp FMS_single_ops[] = { -+ Iop_MSubF32, Iop_MSubF64, Iop_MSubF128 -+}; -+ - static const HChar * - s390_irgen_VFMS(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5, UChar m6) - { -- s390_insn_assert("vfms", m6 == 3); -- s390_vector_fp_mulAddOrSub(Iop_MSubF64, v1, v2, v3, v4, m5, m6); -- return "vfms"; -+ return s390_vector_fp_mulAddOrSub(v1, v2, v3, v4, m5, m6, -+ "vfms", FMS_single_ops, False); -+} -+ -+static const HChar * -+s390_irgen_VFNMS(UChar v1, UChar v2, UChar v3, UChar v4, UChar m5, UChar m6) -+{ -+ return s390_vector_fp_mulAddOrSub(v1, v2, v3, v4, m5, m6, -+ "vfnms", FMS_single_ops, True); - } - - static const HChar * - s390_irgen_WFC(UChar v1, UChar v2, UChar m3, UChar m4) - { -- s390_insn_assert("wfc", m3 == 3); -- s390_insn_assert("wfc", m4 == 0); -+ s390_insn_assert("wfc", m4 == 0 && -+ (m3 == 3 || (s390_host_has_vxe && m3 >= 2 && m3 <= 4))); -+ -+ static const IROp ops[] = { Iop_CmpF32, Iop_CmpF64, Iop_CmpF128 }; -+ IRType type = s390_vr_get_ftype(m3); - - IRTemp cc_vex = newTemp(Ity_I32); -- assign(cc_vex, binop(Iop_CmpF64, -- get_vr(v1, Ity_F64, 0), get_vr(v2, Ity_F64, 0))); -+ assign(cc_vex, binop(ops[m3 - 2], get_vr(v1, type, 0), get_vr(v2, type, 0))); - - IRTemp cc_s390 = newTemp(Ity_I32); - assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex)); -@@ -18695,213 +18920,253 @@ s390_irgen_WFK(UChar v1, UChar v2, UChar m3, UChar m4) - } - - static const HChar * --s390_irgen_VFCE(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5, UChar m6) -+s390_irgen_VFCx(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5, UChar m6, -+ const HChar *mnem, IRCmpFResult cmp, Bool equal_ok, -+ IROp cmp32, IROp cmp64) - { -- s390_insn_assert("vfce", m4 == 3); -+ s390_insn_assert(mnem, (m5 & 3) == 0 && (m6 & 14) == 0 && -+ (m4 == 3 || (s390_host_has_vxe && m4 >= 2 && m4 <= 4))); - -- Bool isSingleElementOp = s390_vr_is_single_element_control_set(m5); -- if (!s390_vr_is_cs_set(m6)) { -- if (!isSingleElementOp) { -- put_vr_qw(v1, binop(Iop_CmpEQ64Fx2, get_vr_qw(v2), get_vr_qw(v3))); -+ Bool single = s390_vr_is_single_element_control_set(m5) || m4 == 4; -+ -+ if (single) { -+ static const IROp ops[] = { Iop_CmpF32, Iop_CmpF64, Iop_CmpF128 }; -+ IRType type = s390_vr_get_ftype(m4); -+ IRTemp result = newTemp(Ity_I32); -+ IRTemp cond = newTemp(Ity_I1); -+ -+ assign(result, binop(ops[m4 - 2], -+ get_vr(v2, type, 0), get_vr(v3, type, 0))); -+ if (equal_ok) { -+ assign(cond, -+ binop(Iop_Or1, -+ binop(Iop_CmpEQ32, mkexpr(result), mkU32(cmp)), -+ binop(Iop_CmpEQ32, mkexpr(result), mkU32(Ircr_EQ)))); - } else { -- IRExpr* comparisonResult = binop(Iop_CmpF64, get_vr(v2, Ity_F64, 0), -- get_vr(v3, Ity_F64, 0)); -- IRExpr* result = mkite(binop(Iop_CmpEQ32, comparisonResult, -- mkU32(Ircr_EQ)), -- mkU64(0xffffffffffffffffULL), -- mkU64(0ULL)); -- put_vr_qw(v1, binop(Iop_64HLtoV128, result, mkU64(0ULL))); -+ assign(cond, binop(Iop_CmpEQ32, mkexpr(result), mkU32(cmp))); -+ } -+ put_vr_qw(v1, mkite(mkexpr(cond), -+ IRExpr_Const(IRConst_V128(0xffff)), -+ IRExpr_Const(IRConst_V128(0)))); -+ if (s390_vr_is_cs_set(m6)) { -+ IRTemp cc = newTemp(Ity_I64); -+ assign(cc, mkite(mkexpr(cond), mkU64(0), mkU64(3))); -+ s390_cc_set(cc); - } - } else { -- IRDirty* d; -- IRTemp cc = newTemp(Ity_I64); -- -- s390x_vec_op_details_t details = { .serialized = 0ULL }; -- details.op = S390_VEC_OP_VFCE; -- details.v1 = v1; -- details.v2 = v2; -- details.v3 = v3; -- details.m4 = m4; -- details.m5 = m5; -- details.m6 = m6; -+ IRTemp result = newTemp(Ity_V128); -+ -+ assign(result, binop(m4 == 2 ? cmp32 : cmp64, -+ get_vr_qw(v2), get_vr_qw(v3))); -+ put_vr_qw(v1, mkexpr(result)); -+ if (s390_vr_is_cs_set(m6)) { -+ IRTemp cc = newTemp(Ity_I64); -+ assign(cc, -+ mkite(binop(Iop_CmpEQ64, -+ binop(Iop_And64, -+ unop(Iop_V128to64, mkexpr(result)), -+ unop(Iop_V128HIto64, mkexpr(result))), -+ mkU64(-1ULL)), -+ mkU64(0), /* all comparison results are true */ -+ mkite(binop(Iop_CmpEQ64, -+ binop(Iop_Or64, -+ unop(Iop_V128to64, mkexpr(result)), -+ unop(Iop_V128HIto64, mkexpr(result))), -+ mkU64(0)), -+ mkU64(3), /* all false */ -+ mkU64(1)))); /* mixed true/false */ -+ s390_cc_set(cc); -+ } -+ } - -- d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op", -- &s390x_dirtyhelper_vec_op, -- mkIRExprVec_2(IRExpr_GSPTR(), -- mkU64(details.serialized))); -+ return mnem; -+} - -- const UChar elementSize = isSingleElementOp ? sizeof(ULong) : sizeof(V128); -- 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); -- d->fxState[0].size = elementSize; -- d->fxState[1].fx = Ifx_Read; -- d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128); -- d->fxState[1].size = elementSize; -- d->fxState[2].fx = Ifx_Write; -- d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128); -- d->fxState[2].size = sizeof(V128); -+static const HChar * -+s390_irgen_VFCE(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5, UChar m6) -+{ -+ return s390_irgen_VFCx(v1, v2, v3, m4, m5, m6, "vfce", Ircr_EQ, -+ False, Iop_CmpEQ32Fx4, Iop_CmpEQ64Fx2); -+} - -- stmt(IRStmt_Dirty(d)); -- s390_cc_set(cc); -- } -+static const HChar * -+s390_irgen_VFCH(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5, UChar m6) -+{ -+ /* Swap arguments and compare "low" instead. */ -+ return s390_irgen_VFCx(v1, v3, v2, m4, m5, m6, "vfch", Ircr_LT, -+ False, Iop_CmpLT32Fx4, Iop_CmpLT64Fx2); -+} - -- return "vfce"; -+static const HChar * -+s390_irgen_VFCHE(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5, UChar m6) -+{ -+ /* Swap arguments and compare "low or equal" instead. */ -+ return s390_irgen_VFCx(v1, v3, v2, m4, m5, m6, "vfche", Ircr_LT, -+ True, Iop_CmpLE32Fx4, Iop_CmpLE64Fx2); - } - - static const HChar * --s390_irgen_VFCH(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5, UChar m6) -+s390_irgen_VFTCI(UChar v1, UChar v2, UShort i3, UChar m4, UChar m5) - { -- vassert(m4 == 3); -+ s390_insn_assert("vftci", -+ (m4 == 3 || (s390_host_has_vxe && m4 >= 2 && m4 <= 4))); - - Bool isSingleElementOp = s390_vr_is_single_element_control_set(m5); -- if (!s390_vr_is_cs_set(m6)) { -- if (!isSingleElementOp) { -- put_vr_qw(v1, binop(Iop_CmpLE64Fx2, get_vr_qw(v3), get_vr_qw(v2))); -- } else { -- IRExpr* comparisonResult = binop(Iop_CmpF64, get_vr(v2, Ity_F64, 0), -- get_vr(v3, Ity_F64, 0)); -- IRExpr* result = mkite(binop(Iop_CmpEQ32, comparisonResult, -- mkU32(Ircr_GT)), -- mkU64(0xffffffffffffffffULL), -- mkU64(0ULL)); -- put_vr_qw(v1, binop(Iop_64HLtoV128, result, mkU64(0ULL))); -- } -- } -- else { -- IRDirty* d; -- IRTemp cc = newTemp(Ity_I64); - -- s390x_vec_op_details_t details = { .serialized = 0ULL }; -- details.op = S390_VEC_OP_VFCH; -- details.v1 = v1; -- details.v2 = v2; -- details.v3 = v3; -- details.m4 = m4; -- details.m5 = m5; -- details.m6 = m6; -+ IRDirty* d; -+ IRTemp cc = newTemp(Ity_I64); - -- d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op", -- &s390x_dirtyhelper_vec_op, -- mkIRExprVec_2(IRExpr_GSPTR(), -- mkU64(details.serialized))); -+ s390x_vec_op_details_t details = { .serialized = 0ULL }; -+ details.op = S390_VEC_OP_VFTCI; -+ details.v1 = v1; -+ details.v2 = v2; -+ details.i3 = i3; -+ details.m4 = m4; -+ details.m5 = m5; - -- const UChar elementSize = isSingleElementOp ? sizeof(ULong) : sizeof(V128); -- 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); -- d->fxState[0].size = elementSize; -- d->fxState[1].fx = Ifx_Read; -- d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128); -- d->fxState[1].size = elementSize; -- d->fxState[2].fx = Ifx_Write; -- d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128); -- d->fxState[2].size = sizeof(V128); -+ d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op", -+ &s390x_dirtyhelper_vec_op, -+ mkIRExprVec_2(IRExpr_GSPTR(), -+ mkU64(details.serialized))); - -- stmt(IRStmt_Dirty(d)); -- s390_cc_set(cc); -- } -+ const UChar elementSize = isSingleElementOp ? -+ sizeofIRType(s390_vr_get_ftype(m4)) : sizeof(V128); -+ d->nFxState = 2; -+ 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); -+ d->fxState[0].size = elementSize; -+ d->fxState[1].fx = Ifx_Write; -+ d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128); -+ d->fxState[1].size = sizeof(V128); -+ -+ stmt(IRStmt_Dirty(d)); -+ s390_cc_set(cc); - -- return "vfch"; -+ return "vftci"; - } - - static const HChar * --s390_irgen_VFCHE(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5, UChar m6) -+s390_irgen_VFMIN(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5, UChar m6) - { -- s390_insn_assert("vfche", m4 == 3); -+ s390_insn_assert("vfmin", -+ (m4 == 3 || (s390_host_has_vxe && m4 >= 2 && m4 <= 4))); - - Bool isSingleElementOp = s390_vr_is_single_element_control_set(m5); -- if (!s390_vr_is_cs_set(m6)) { -- if (!isSingleElementOp) { -- put_vr_qw(v1, binop(Iop_CmpLT64Fx2, get_vr_qw(v3), get_vr_qw(v2))); -- } -- else { -- IRExpr* comparisonResult = binop(Iop_CmpF64, get_vr(v3, Ity_F64, 0), -- get_vr(v2, Ity_F64, 0)); -- IRExpr* result = mkite(binop(Iop_CmpEQ32, comparisonResult, -- mkU32(Ircr_LT)), -- mkU64(0xffffffffffffffffULL), -- mkU64(0ULL)); -- put_vr_qw(v1, binop(Iop_64HLtoV128, result, mkU64(0ULL))); -- } -- } -- else { -- IRDirty* d; -- IRTemp cc = newTemp(Ity_I64); -- -- s390x_vec_op_details_t details = { .serialized = 0ULL }; -- details.op = S390_VEC_OP_VFCHE; -- details.v1 = v1; -- details.v2 = v2; -- details.v3 = v3; -- details.m4 = m4; -- details.m5 = m5; -- details.m6 = m6; -+ IRDirty* d; -+ IRTemp cc = newTemp(Ity_I64); - -- d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op", -- &s390x_dirtyhelper_vec_op, -- mkIRExprVec_2(IRExpr_GSPTR(), -- mkU64(details.serialized))); -+ s390x_vec_op_details_t details = { .serialized = 0ULL }; -+ details.op = S390_VEC_OP_VFMIN; -+ details.v1 = v1; -+ details.v2 = v2; -+ details.v3 = v3; -+ details.m4 = m4; -+ details.m5 = m5; -+ details.m6 = m6; - -- const UChar elementSize = isSingleElementOp ? sizeof(ULong) : sizeof(V128); -- 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); -- d->fxState[0].size = elementSize; -- d->fxState[1].fx = Ifx_Read; -- d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128); -- d->fxState[1].size = elementSize; -- d->fxState[2].fx = Ifx_Write; -- d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128); -- d->fxState[2].size = sizeof(V128); -+ d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op", -+ &s390x_dirtyhelper_vec_op, -+ mkIRExprVec_2(IRExpr_GSPTR(), -+ mkU64(details.serialized))); - -- stmt(IRStmt_Dirty(d)); -- s390_cc_set(cc); -- } -+ const UChar elementSize = isSingleElementOp ? -+ sizeofIRType(s390_vr_get_ftype(m4)) : sizeof(V128); -+ 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); -+ d->fxState[0].size = elementSize; -+ d->fxState[1].fx = Ifx_Read; -+ d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128); -+ d->fxState[1].size = elementSize; -+ d->fxState[2].fx = Ifx_Write; -+ d->fxState[2].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128); -+ d->fxState[2].size = sizeof(V128); - -- return "vfche"; -+ stmt(IRStmt_Dirty(d)); -+ s390_cc_set(cc); -+ return "vfmin"; - } - - static const HChar * --s390_irgen_VFTCI(UChar v1, UChar v2, UShort i3, UChar m4, UChar m5) -+s390_irgen_VFMAX(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5, UChar m6) - { -- s390_insn_assert("vftci", m4 == 3); -+ s390_insn_assert("vfmax", -+ (m4 == 3 || (s390_host_has_vxe && m4 >= 2 && m4 <= 4))); - - Bool isSingleElementOp = s390_vr_is_single_element_control_set(m5); -- - IRDirty* d; - IRTemp cc = newTemp(Ity_I64); - - s390x_vec_op_details_t details = { .serialized = 0ULL }; -- details.op = S390_VEC_OP_VFTCI; -+ details.op = S390_VEC_OP_VFMAX; - details.v1 = v1; - details.v2 = v2; -- details.i3 = i3; -+ details.v3 = v3; - details.m4 = m4; - details.m5 = m5; -+ details.m6 = m6; - - d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op", - &s390x_dirtyhelper_vec_op, - mkIRExprVec_2(IRExpr_GSPTR(), - mkU64(details.serialized))); - -- const UChar elementSize = isSingleElementOp ? sizeof(ULong) : sizeof(V128); -- d->nFxState = 2; -+ const UChar elementSize = isSingleElementOp ? -+ sizeofIRType(s390_vr_get_ftype(m4)) : sizeof(V128); -+ 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); - d->fxState[0].size = elementSize; -- d->fxState[1].fx = Ifx_Write; -- d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128); -- d->fxState[1].size = sizeof(V128); -+ d->fxState[1].fx = Ifx_Read; -+ d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v3 * sizeof(V128); -+ d->fxState[1].size = elementSize; -+ 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_set(cc); -+ return "vfmax"; -+} - -- return "vftci"; -+static const HChar * -+s390_irgen_VBPERM(UChar v1, UChar v2, UChar v3) -+{ -+ IRDirty* d; -+ IRTemp cc = newTemp(Ity_I64); -+ -+ s390x_vec_op_details_t details = { .serialized = 0ULL }; -+ details.op = S390_VEC_OP_VBPERM; -+ details.v1 = v1; -+ details.v2 = v2; -+ details.v3 = v3; -+ details.m4 = 0; -+ details.m5 = 0; -+ details.m6 = 0; -+ -+ 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); -+ d->fxState[0].size = sizeof(V128); -+ 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_set(cc); -+ return "vbperm"; - } - - /* New insns are added here. -@@ -20489,11 +20754,23 @@ s390_decode_6byte_and_irgen(const UChar *bytes) - RXY_dl2(ovl), - RXY_dh2(ovl)); goto ok; - case 0xe60000000034ULL: /* VPKZ */ goto unimplemented; -- case 0xe60000000035ULL: /* VLRL */ goto unimplemented; -- case 0xe60000000037ULL: /* VLRLR */ goto unimplemented; -+ case 0xe60000000035ULL: s390_format_VSI_URDV(s390_irgen_VLRL, VSI_v1(ovl), -+ VSI_b2(ovl), VSI_d2(ovl), -+ VSI_i3(ovl), -+ VSI_rxb(ovl)); goto ok; -+ case 0xe60000000037ULL: s390_format_VRS_RRDV(s390_irgen_VLRLR, VRSd_v1(ovl), -+ VRSd_r3(ovl), VRS_b2(ovl), -+ VRS_d2(ovl), -+ VRS_rxb(ovl)); goto ok; - case 0xe6000000003cULL: /* VUPKZ */ goto unimplemented; -- case 0xe6000000003dULL: /* VSTRL */ goto unimplemented; -- case 0xe6000000003fULL: /* VSTRLR */ goto unimplemented; -+ case 0xe6000000003dULL: s390_format_VSI_URDV(s390_irgen_VSTRL, VSI_v1(ovl), -+ VSI_b2(ovl), VSI_d2(ovl), -+ VSI_i3(ovl), -+ VSI_rxb(ovl)); goto ok; -+ case 0xe6000000003fULL: s390_format_VRS_RRDV(s390_irgen_VSTRLR, VRSd_v1(ovl), -+ VRSd_r3(ovl), VRS_b2(ovl), -+ VRS_d2(ovl), -+ VRS_rxb(ovl)); goto ok; - case 0xe60000000049ULL: /* VLIP */ goto unimplemented; - case 0xe60000000050ULL: /* VCVB */ goto unimplemented; - case 0xe60000000052ULL: /* VCVBG */ goto unimplemented; -@@ -20691,12 +20968,18 @@ s390_decode_6byte_and_irgen(const UChar *bytes) - case 0xe7000000006bULL: s390_format_VRR_VVV(s390_irgen_VNO, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), - VRR_rxb(ovl)); goto ok; -- case 0xe7000000006cULL: /* VNX */ goto unimplemented; -+ case 0xe7000000006cULL: s390_format_VRR_VVV(s390_irgen_VNX, VRR_v1(ovl), -+ VRR_v2(ovl), VRR_r3(ovl), -+ VRR_rxb(ovl)); goto ok; - case 0xe7000000006dULL: s390_format_VRR_VVV(s390_irgen_VX, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), - VRR_rxb(ovl)); goto ok; -- case 0xe7000000006eULL: /* VNN */ goto unimplemented; -- case 0xe7000000006fULL: /* VOC */ goto unimplemented; -+ case 0xe7000000006eULL: s390_format_VRR_VVV(s390_irgen_VNN, VRR_v1(ovl), -+ VRR_v2(ovl), VRR_r3(ovl), -+ VRR_rxb(ovl)); goto ok; -+ case 0xe7000000006fULL: s390_format_VRR_VVV(s390_irgen_VOC, VRR_v1(ovl), -+ VRR_v2(ovl), VRR_r3(ovl), -+ VRR_rxb(ovl)); goto ok; - case 0xe70000000070ULL: s390_format_VRR_VVVM(s390_irgen_VESLV, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), - VRR_m4(ovl), VRR_rxb(ovl)); goto ok; -@@ -20749,7 +21032,9 @@ s390_decode_6byte_and_irgen(const UChar *bytes) - case 0xe70000000084ULL: s390_format_VRR_VVVM(s390_irgen_VPDI, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), - VRR_m4(ovl), VRR_rxb(ovl)); goto ok; -- case 0xe70000000085ULL: /* VBPERM */ goto unimplemented; -+ case 0xe70000000085ULL: s390_format_VRR_VVV(s390_irgen_VBPERM, VRR_v1(ovl), -+ VRR_v2(ovl), VRR_r3(ovl), -+ VRR_rxb(ovl)); goto ok; - case 0xe7000000008aULL: s390_format_VRR_VVVVMM(s390_irgen_VSTRC, VRRd_v1(ovl), - VRRd_v2(ovl), VRRd_v3(ovl), - VRRd_v4(ovl), VRRd_m5(ovl), -@@ -20780,8 +21065,16 @@ s390_decode_6byte_and_irgen(const UChar *bytes) - case 0xe70000000097ULL: s390_format_VRR_VVVMM(s390_irgen_VPKS, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), - VRR_m4(ovl), VRR_m5(ovl), VRR_rxb(ovl)); goto ok; -- case 0xe7000000009eULL: /* VFNMS */ goto unimplemented; -- case 0xe7000000009fULL: /* VFNMA */ goto unimplemented; -+ case 0xe7000000009eULL: s390_format_VRR_VVVVMM(s390_irgen_VFNMS, VRRe_v1(ovl), -+ VRRe_v2(ovl), VRRe_v3(ovl), -+ VRRe_v4(ovl), VRRe_m5(ovl), -+ VRRe_m6(ovl), -+ VRRe_rxb(ovl)); goto ok; -+ case 0xe7000000009fULL: s390_format_VRR_VVVVMM(s390_irgen_VFNMA, VRRe_v1(ovl), -+ VRRe_v2(ovl), VRRe_v3(ovl), -+ VRRe_v4(ovl), VRRe_m5(ovl), -+ VRRe_m6(ovl), -+ VRRe_rxb(ovl)); goto ok; - case 0xe700000000a1ULL: s390_format_VRR_VVVM(s390_irgen_VMLH, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), - VRR_m4(ovl), VRR_rxb(ovl)); goto ok; -@@ -20834,7 +21127,11 @@ s390_decode_6byte_and_irgen(const UChar *bytes) - case 0xe700000000b4ULL: s390_format_VRR_VVVM(s390_irgen_VGFM, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), - VRR_m4(ovl), VRR_rxb(ovl)); goto ok; -- case 0xe700000000b8ULL: /* VMSL */ goto unimplemented; -+ case 0xe700000000b8ULL: s390_format_VRR_VVVVMM(s390_irgen_VMSL, VRRd_v1(ovl), -+ VRRd_v2(ovl), VRRd_v3(ovl), -+ VRRd_v4(ovl), VRRd_m5(ovl), -+ VRRd_m6(ovl), -+ VRRd_rxb(ovl)); goto ok; - case 0xe700000000b9ULL: s390_format_VRRd_VVVVM(s390_irgen_VACCC, VRRd_v1(ovl), - VRRd_v2(ovl), VRRd_v3(ovl), - VRRd_v4(ovl), VRRd_m5(ovl), -@@ -20871,11 +21168,11 @@ s390_decode_6byte_and_irgen(const UChar *bytes) - VRRa_v2(ovl), VRRa_m3(ovl), - VRRa_m4(ovl), VRRa_m5(ovl), - VRRa_rxb(ovl)); goto ok; -- case 0xe700000000c4ULL: s390_format_VRRa_VVMMM(s390_irgen_VLDE, VRRa_v1(ovl), -+ case 0xe700000000c4ULL: s390_format_VRRa_VVMMM(s390_irgen_VFLL, VRRa_v1(ovl), - VRRa_v2(ovl), VRRa_m3(ovl), - VRRa_m4(ovl), VRRa_m5(ovl), - VRRa_rxb(ovl)); goto ok; -- case 0xe700000000c5ULL: s390_format_VRRa_VVMMM(s390_irgen_VLED, VRRa_v1(ovl), -+ case 0xe700000000c5ULL: s390_format_VRRa_VVMMM(s390_irgen_VFLR, VRRa_v1(ovl), - VRRa_v2(ovl), VRRa_m3(ovl), - VRRa_m4(ovl), VRRa_m5(ovl), - VRRa_rxb(ovl)); goto ok; -@@ -20956,8 +21253,16 @@ s390_decode_6byte_and_irgen(const UChar *bytes) - VRRa_m3(ovl), VRRa_m4(ovl), - VRRa_m5(ovl), - VRRa_rxb(ovl)); goto ok; -- case 0xe700000000eeULL: /* VFMIN */ goto unimplemented; -- case 0xe700000000efULL: /* VFMAX */ goto unimplemented; -+ case 0xe700000000eeULL: s390_format_VRRa_VVVMMM(s390_irgen_VFMIN, VRRa_v1(ovl), -+ VRRa_v2(ovl), VRRa_v3(ovl), -+ VRRa_m3(ovl), VRRa_m4(ovl), -+ VRRa_m5(ovl), -+ VRRa_rxb(ovl)); goto ok; -+ case 0xe700000000efULL: s390_format_VRRa_VVVMMM(s390_irgen_VFMAX, VRRa_v1(ovl), -+ VRRa_v2(ovl), VRRa_v3(ovl), -+ VRRa_m3(ovl), VRRa_m4(ovl), -+ VRRa_m5(ovl), -+ VRRa_rxb(ovl)); goto ok; - case 0xe700000000f0ULL: s390_format_VRR_VVVM(s390_irgen_VAVGL, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), - VRR_m4(ovl), VRR_rxb(ovl)); goto ok; -diff --git a/VEX/priv/host_s390_defs.c b/VEX/priv/host_s390_defs.c -index 3b6121fec..8762975b2 100644 ---- a/VEX/priv/host_s390_defs.c -+++ b/VEX/priv/host_s390_defs.c -@@ -8,7 +8,7 @@ - This file is part of Valgrind, a dynamic binary instrumentation - framework. - -- Copyright IBM Corp. 2010-2017 -+ Copyright IBM Corp. 2010-2020 - Copyright (C) 2012-2017 Florian Krohm (britzel@acm.org) - - This program is free software; you can redistribute it and/or -@@ -684,6 +684,8 @@ s390_insn* genMove_S390(HReg from, HReg to, Bool mode64) - switch (hregClass(from)) { - case HRcInt64: - return s390_insn_move(sizeofIRType(Ity_I64), to, from); -+ case HRcFlt64: -+ return s390_insn_move(sizeofIRType(Ity_F64), to, from); - case HRcVec128: - return s390_insn_move(sizeofIRType(Ity_V128), to, from); - default: -@@ -7870,6 +7872,10 @@ s390_insn_as_string(const s390_insn *insn) - op = "v-vfloatabs"; - break; - -+ case S390_VEC_FLOAT_NABS: -+ op = "v-vfloatnabs"; -+ break; -+ - default: - goto fail; - } -@@ -9439,21 +9445,28 @@ s390_insn_unop_emit(UChar *buf, const s390_insn *insn) - - case S390_VEC_FLOAT_NEG: { - vassert(insn->variant.unop.src.tag == S390_OPND_REG); -- vassert(insn->size == 8); -+ vassert(insn->size >= 4); - UChar v1 = hregNumber(insn->variant.unop.dst); - UChar v2 = hregNumber(insn->variant.unop.src.variant.reg); - return s390_emit_VFPSO(buf, v1, v2, s390_getM_from_size(insn->size), 0, 0); - } - case S390_VEC_FLOAT_ABS: { - vassert(insn->variant.unop.src.tag == S390_OPND_REG); -- vassert(insn->size == 8); -+ vassert(insn->size >= 4); - UChar v1 = hregNumber(insn->variant.unop.dst); - UChar v2 = hregNumber(insn->variant.unop.src.variant.reg); - return s390_emit_VFPSO(buf, v1, v2, s390_getM_from_size(insn->size), 0, 2); - } -+ case S390_VEC_FLOAT_NABS: { -+ vassert(insn->variant.unop.src.tag == S390_OPND_REG); -+ vassert(insn->size >= 4); -+ UChar v1 = hregNumber(insn->variant.unop.dst); -+ UChar v2 = hregNumber(insn->variant.unop.src.variant.reg); -+ return s390_emit_VFPSO(buf, v1, v2, s390_getM_from_size(insn->size), 0, 1); -+ } - case S390_VEC_FLOAT_SQRT: { - vassert(insn->variant.unop.src.tag == S390_OPND_REG); -- vassert(insn->size == 8); -+ vassert(insn->size >= 4); - UChar v1 = hregNumber(insn->variant.unop.dst); - UChar v2 = hregNumber(insn->variant.unop.src.variant.reg); - return s390_emit_VFSQ(buf, v1, v2, s390_getM_from_size(insn->size), 0); -diff --git a/VEX/priv/host_s390_defs.h b/VEX/priv/host_s390_defs.h -index 3f6473e10..9b69f4d38 100644 ---- a/VEX/priv/host_s390_defs.h -+++ b/VEX/priv/host_s390_defs.h -@@ -8,7 +8,7 @@ - This file is part of Valgrind, a dynamic binary instrumentation - framework. - -- Copyright IBM Corp. 2010-2017 -+ Copyright IBM Corp. 2010-2020 - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as -@@ -205,6 +205,7 @@ typedef enum { - S390_VEC_COUNT_ONES, - S390_VEC_FLOAT_NEG, - S390_VEC_FLOAT_ABS, -+ S390_VEC_FLOAT_NABS, - S390_VEC_FLOAT_SQRT, - S390_UNOP_T_INVALID - } s390_unop_t; -@@ -931,6 +932,8 @@ extern UInt s390_host_hwcaps; - (s390_host_hwcaps & (VEX_HWCAPS_S390X_MSA5)) - #define s390_host_has_lsc2 \ - (s390_host_hwcaps & (VEX_HWCAPS_S390X_LSC2)) -+#define s390_host_has_vxe \ -+ (s390_host_hwcaps & (VEX_HWCAPS_S390X_VXE)) - #endif /* ndef __VEX_HOST_S390_DEFS_H */ - - /*---------------------------------------------------------------*/ -diff --git a/VEX/priv/host_s390_isel.c b/VEX/priv/host_s390_isel.c -index 134f3eb6f..2f9854038 100644 ---- a/VEX/priv/host_s390_isel.c -+++ b/VEX/priv/host_s390_isel.c -@@ -8,7 +8,7 @@ - This file is part of Valgrind, a dynamic binary instrumentation - framework. - -- Copyright IBM Corp. 2010-2017 -+ Copyright IBM Corp. 2010-2020 - Copyright (C) 2012-2017 Florian Krohm (britzel@acm.org) - - This program is free software; you can redistribute it and/or -@@ -2362,9 +2362,10 @@ s390_isel_float128_expr_wrk(HReg *dst_hi, HReg *dst_lo, ISelEnv *env, - case Iop_NegF128: - if (left->tag == Iex_Unop && - (left->Iex.Unop.op == Iop_AbsF32 || -- left->Iex.Unop.op == Iop_AbsF64)) -+ left->Iex.Unop.op == Iop_AbsF64)) { - bfpop = S390_BFP_NABS; -- else -+ left = left->Iex.Unop.arg; -+ } else - bfpop = S390_BFP_NEG; - goto float128_opnd; - case Iop_AbsF128: bfpop = S390_BFP_ABS; goto float128_opnd; -@@ -2726,9 +2727,10 @@ s390_isel_float_expr_wrk(ISelEnv *env, IRExpr *expr) - case Iop_NegF64: - if (left->tag == Iex_Unop && - (left->Iex.Unop.op == Iop_AbsF32 || -- left->Iex.Unop.op == Iop_AbsF64)) -+ left->Iex.Unop.op == Iop_AbsF64)) { - bfpop = S390_BFP_NABS; -- else -+ left = left->Iex.Unop.arg; -+ } else - bfpop = S390_BFP_NEG; - break; - -@@ -3944,11 +3946,27 @@ s390_isel_vec_expr_wrk(ISelEnv *env, IRExpr *expr) - vec_unop = S390_VEC_COUNT_ONES; - goto Iop_V_wrk; - -+ case Iop_Neg32Fx4: -+ size = 4; -+ vec_unop = S390_VEC_FLOAT_NEG; -+ if (arg->tag == Iex_Unop && arg->Iex.Unop.op == Iop_Abs32Fx4) { -+ vec_unop = S390_VEC_FLOAT_NABS; -+ arg = arg->Iex.Unop.arg; -+ } -+ goto Iop_V_wrk; - case Iop_Neg64Fx2: - size = 8; - vec_unop = S390_VEC_FLOAT_NEG; -+ if (arg->tag == Iex_Unop && arg->Iex.Unop.op == Iop_Abs64Fx2) { -+ vec_unop = S390_VEC_FLOAT_NABS; -+ arg = arg->Iex.Unop.arg; -+ } - goto Iop_V_wrk; - -+ case Iop_Abs32Fx4: -+ size = 4; -+ vec_unop = S390_VEC_FLOAT_ABS; -+ goto Iop_V_wrk; - case Iop_Abs64Fx2: - size = 8; - vec_unop = S390_VEC_FLOAT_ABS; -@@ -4474,17 +4492,29 @@ s390_isel_vec_expr_wrk(ISelEnv *env, IRExpr *expr) - vec_binop = S390_VEC_ELEM_ROLL_V; - goto Iop_VV_wrk; - -+ case Iop_CmpEQ32Fx4: -+ size = 4; -+ vec_binop = S390_VEC_FLOAT_COMPARE_EQUAL; -+ goto Iop_VV_wrk; - case Iop_CmpEQ64Fx2: - size = 8; - vec_binop = S390_VEC_FLOAT_COMPARE_EQUAL; - goto Iop_VV_wrk; - -+ case Iop_CmpLE32Fx4: -+ size = 4; -+ vec_binop = S390_VEC_FLOAT_COMPARE_LESS_OR_EQUAL; -+ goto Iop_VV_wrk; - case Iop_CmpLE64Fx2: { - size = 8; - vec_binop = S390_VEC_FLOAT_COMPARE_LESS_OR_EQUAL; - goto Iop_VV_wrk; - } - -+ case Iop_CmpLT32Fx4: -+ size = 4; -+ vec_binop = S390_VEC_FLOAT_COMPARE_LESS; -+ goto Iop_VV_wrk; - case Iop_CmpLT64Fx2: { - size = 8; - vec_binop = S390_VEC_FLOAT_COMPARE_LESS; -@@ -4671,20 +4701,41 @@ s390_isel_vec_expr_wrk(ISelEnv *env, IRExpr *expr) - dst, reg1, reg2, reg3)); - return dst; - -+ case Iop_Add32Fx4: -+ size = 4; -+ vec_binop = S390_VEC_FLOAT_ADD; -+ goto Iop_irrm_VV_wrk; -+ - case Iop_Add64Fx2: - size = 8; - vec_binop = S390_VEC_FLOAT_ADD; - goto Iop_irrm_VV_wrk; - -+ case Iop_Sub32Fx4: -+ size = 4; -+ vec_binop = S390_VEC_FLOAT_SUB; -+ goto Iop_irrm_VV_wrk; -+ - case Iop_Sub64Fx2: - size = 8; - vec_binop = S390_VEC_FLOAT_SUB; - goto Iop_irrm_VV_wrk; - -+ case Iop_Mul32Fx4: -+ size = 4; -+ vec_binop = S390_VEC_FLOAT_MUL; -+ goto Iop_irrm_VV_wrk; -+ - case Iop_Mul64Fx2: - size = 8; - vec_binop = S390_VEC_FLOAT_MUL; - goto Iop_irrm_VV_wrk; -+ -+ case Iop_Div32Fx4: -+ size = 4; -+ vec_binop = S390_VEC_FLOAT_DIV; -+ goto Iop_irrm_VV_wrk; -+ - case Iop_Div64Fx2: - size = 8; - vec_binop = S390_VEC_FLOAT_DIV; -diff --git a/VEX/priv/main_main.c b/VEX/priv/main_main.c -index 72f419988..12f521d8c 100644 ---- a/VEX/priv/main_main.c -+++ b/VEX/priv/main_main.c -@@ -1795,6 +1795,7 @@ static const HChar* show_hwcaps_s390x ( UInt hwcaps ) - { VEX_HWCAPS_S390X_MSA5, "msa5" }, - { VEX_HWCAPS_S390X_MI2, "mi2" }, - { VEX_HWCAPS_S390X_LSC2, "lsc2" }, -+ { VEX_HWCAPS_S390X_LSC2, "vxe" }, - }; - /* Allocate a large enough buffer */ - static HChar buf[sizeof prefix + -diff --git a/VEX/pub/libvex.h b/VEX/pub/libvex.h -index 53e3705da..2ffed0ad0 100644 ---- a/VEX/pub/libvex.h -+++ b/VEX/pub/libvex.h -@@ -171,7 +171,7 @@ typedef - #define VEX_HWCAPS_S390X_MSA5 (1<<19) /* message security assistance facility */ - #define VEX_HWCAPS_S390X_MI2 (1<<20) /* miscellaneous-instruction-extensions facility 2 */ - #define VEX_HWCAPS_S390X_LSC2 (1<<21) /* Conditional load/store facility2 */ -- -+#define VEX_HWCAPS_S390X_VXE (1<<22) /* Vector-enhancements facility */ - - /* Special value representing all available s390x hwcaps */ - #define VEX_HWCAPS_S390X_ALL (VEX_HWCAPS_S390X_LDISP | \ -@@ -189,7 +189,8 @@ typedef - VEX_HWCAPS_S390X_VX | \ - VEX_HWCAPS_S390X_MSA5 | \ - VEX_HWCAPS_S390X_MI2 | \ -- VEX_HWCAPS_S390X_LSC2) -+ VEX_HWCAPS_S390X_LSC2 | \ -+ VEX_HWCAPS_S390X_VXE) - - #define VEX_HWCAPS_S390X(x) ((x) & ~VEX_S390X_MODEL_MASK) - #define VEX_S390X_MODEL(x) ((x) & VEX_S390X_MODEL_MASK) -diff --git a/VEX/pub/libvex_emnote.h b/VEX/pub/libvex_emnote.h -index be033b4da..77880a270 100644 ---- a/VEX/pub/libvex_emnote.h -+++ b/VEX/pub/libvex_emnote.h -@@ -124,6 +124,10 @@ typedef - /* ppno insn is not supported on this host */ - EmFail_S390X_ppno, - -+ /* insn needs vector-enhancements facility which is not available on this -+ host */ -+ EmFail_S390X_vxe, -+ - EmNote_NUMBER - } - VexEmNote; -diff --git a/coregrind/m_initimg/initimg-linux.c b/coregrind/m_initimg/initimg-linux.c -index 365942c4f..ba84fa6e9 100644 ---- a/coregrind/m_initimg/initimg-linux.c -+++ b/coregrind/m_initimg/initimg-linux.c -@@ -697,9 +697,13 @@ Addr setup_client_stack( void* init_sp, - } - # elif defined(VGP_s390x_linux) - { -- /* Advertise hardware features "below" TE and VXRS. TE itself -- and anything above VXRS is not supported by Valgrind. */ -- auxv->u.a_val &= (VKI_HWCAP_S390_TE - 1) | VKI_HWCAP_S390_VXRS; -+ /* Out of the hardware features available on the platform, -+ advertise those "below" TE, as well as the ones explicitly -+ ORed in the expression below. Anything else, such as TE -+ itself, is not supported by Valgrind. */ -+ auxv->u.a_val &= ((VKI_HWCAP_S390_TE - 1) -+ | VKI_HWCAP_S390_VXRS -+ | VKI_HWCAP_S390_VXRS_EXT); - } - # elif defined(VGP_arm64_linux) - { -diff --git a/coregrind/m_machine.c b/coregrind/m_machine.c -index e7877e636..228ae2554 100644 ---- a/coregrind/m_machine.c -+++ b/coregrind/m_machine.c -@@ -1555,6 +1555,7 @@ Bool VG_(machine_get_hwcaps)( void ) - { False, S390_FAC_MSA5, VEX_HWCAPS_S390X_MSA5, "MSA5" }, - { False, S390_FAC_MI2, VEX_HWCAPS_S390X_MI2, "MI2" }, - { False, S390_FAC_LSC2, VEX_HWCAPS_S390X_LSC2, "LSC2" }, -+ { False, S390_FAC_VXE, VEX_HWCAPS_S390X_VXE, "VXE" }, - }; - - /* Set hwcaps according to the detected facilities */ -diff --git a/include/vki/vki-s390x-linux.h b/include/vki/vki-s390x-linux.h -index 7b863a324..4ab2d3334 100644 ---- a/include/vki/vki-s390x-linux.h -+++ b/include/vki/vki-s390x-linux.h -@@ -806,6 +806,7 @@ typedef vki_s390_regs vki_elf_gregset_t; - - #define VKI_HWCAP_S390_TE 1024 - #define VKI_HWCAP_S390_VXRS 2048 -+#define VKI_HWCAP_S390_VXRS_EXT 8192 - - - //---------------------------------------------------------------------- -diff --git a/none/tests/s390x/vector.h b/none/tests/s390x/vector.h -index de2391480..632c2cb9c 100644 ---- a/none/tests/s390x/vector.h -+++ b/none/tests/s390x/vector.h -@@ -86,6 +86,13 @@ void print_hex(const V128 value) { - printf("%016lx | %016lx\n", value.u64[0], value.u64[1]); - } - -+void print_hex64(const V128 value, int zero_only) { -+ if (zero_only) -+ printf("%016lx | --\n", value.u64[0]); -+ else -+ printf("%016lx | %016lx\n", value.u64[0], value.u64[1]); -+} -+ - void print_f32(const V128 value, int even_only, int zero_only) { - if (zero_only) - printf("%a | -- | -- | --\n", value.f32[0]); -@@ -222,8 +229,10 @@ static void test_##insn##_selective(const s390x_test_usageInfo info) \ - {printf(" v_arg2 = "); print_hex(v_arg2);} \ - if (info & V128_V_ARG3_AS_INT) \ - {printf(" v_arg3 = "); print_hex(v_arg3);} \ -- if (info & V128_V_RES_AS_INT) \ -- {printf(" v_result = "); print_hex(v_result);} \ -+ if (info & V128_V_RES_AS_INT) { \ -+ printf(" v_result = "); \ -+ print_hex64(v_result, info & V128_V_RES_ZERO_ONLY); \ -+ } \ - \ - if (info & V128_V_ARG1_AS_FLOAT64) \ - {printf(" v_arg1 = "); print_f64(v_arg1, 0);} \ -diff --git a/none/tests/s390x/vector_float.c b/none/tests/s390x/vector_float.c -index 52f3a296f..20853f381 100644 ---- a/none/tests/s390x/vector_float.c -+++ b/none/tests/s390x/vector_float.c -@@ -114,50 +114,59 @@ int main() - test_with_selective_printing(vldeb, (V128_V_RES_AS_FLOAT64 | - V128_V_ARG1_AS_FLOAT64)); - test_with_selective_printing(wldeb, (V128_V_RES_AS_FLOAT64 | -- V128_V_ARG1_AS_FLOAT64)); -+ V128_V_ARG1_AS_FLOAT64 | -+ V128_V_RES_ZERO_ONLY)); - - test_with_selective_printing(vflcdb, (V128_V_RES_AS_FLOAT64 | - V128_V_ARG1_AS_FLOAT64)); - test_with_selective_printing(wflcdb, (V128_V_RES_AS_FLOAT64 | -- V128_V_ARG1_AS_FLOAT64)); -+ V128_V_ARG1_AS_FLOAT64 | -+ V128_V_RES_ZERO_ONLY)); - test_with_selective_printing(vflndb, (V128_V_RES_AS_FLOAT64 | - V128_V_ARG1_AS_FLOAT64)); - test_with_selective_printing(wflndb, (V128_V_RES_AS_FLOAT64 | -- V128_V_ARG1_AS_FLOAT64)); -+ V128_V_ARG1_AS_FLOAT64 | -+ V128_V_RES_ZERO_ONLY)); - test_with_selective_printing(vflpdb, (V128_V_RES_AS_FLOAT64 | - V128_V_ARG1_AS_FLOAT64)); - test_with_selective_printing(wflpdb, (V128_V_RES_AS_FLOAT64 | -- V128_V_ARG1_AS_FLOAT64)); -+ V128_V_ARG1_AS_FLOAT64 | -+ V128_V_RES_ZERO_ONLY)); - - test_with_selective_printing(vfadb, (V128_V_RES_AS_FLOAT64 | - V128_V_ARG1_AS_FLOAT64 | - V128_V_ARG2_AS_FLOAT64)); - test_with_selective_printing(wfadb, (V128_V_RES_AS_FLOAT64 | - V128_V_ARG1_AS_FLOAT64 | -- V128_V_ARG2_AS_FLOAT64)); -+ V128_V_ARG2_AS_FLOAT64 | -+ V128_V_RES_ZERO_ONLY)); - test_with_selective_printing(vfsdb, (V128_V_RES_AS_FLOAT64 | - V128_V_ARG1_AS_FLOAT64 | - V128_V_ARG2_AS_FLOAT64)); - test_with_selective_printing(wfsdb, (V128_V_RES_AS_FLOAT64 | - V128_V_ARG1_AS_FLOAT64 | -- V128_V_ARG2_AS_FLOAT64)); -+ V128_V_ARG2_AS_FLOAT64 | -+ V128_V_RES_ZERO_ONLY)); - test_with_selective_printing(vfmdb, (V128_V_RES_AS_FLOAT64 | - V128_V_ARG1_AS_FLOAT64 | - V128_V_ARG2_AS_FLOAT64)); - test_with_selective_printing(wfmdb, (V128_V_RES_AS_FLOAT64 | - V128_V_ARG1_AS_FLOAT64 | -- V128_V_ARG2_AS_FLOAT64)); -+ V128_V_ARG2_AS_FLOAT64 | -+ V128_V_RES_ZERO_ONLY)); - test_with_selective_printing(vfddb, (V128_V_RES_AS_FLOAT64 | - V128_V_ARG1_AS_FLOAT64 | - V128_V_ARG2_AS_FLOAT64)); - test_with_selective_printing(wfddb, (V128_V_RES_AS_FLOAT64 | - V128_V_ARG1_AS_FLOAT64 | -- V128_V_ARG2_AS_FLOAT64)); -+ V128_V_ARG2_AS_FLOAT64 | -+ V128_V_RES_ZERO_ONLY)); - - test_with_selective_printing(vfsqdb, (V128_V_RES_AS_FLOAT64 | - V128_V_ARG1_AS_FLOAT64)); - test_with_selective_printing(wfsqdb, (V128_V_RES_AS_FLOAT64 | -- V128_V_ARG1_AS_FLOAT64)); -+ V128_V_ARG1_AS_FLOAT64 | -+ V128_V_RES_ZERO_ONLY)); - - test_with_selective_printing(vfmadb, (V128_V_RES_AS_FLOAT64 | - V128_V_ARG1_AS_FLOAT64 | -@@ -166,7 +175,8 @@ int main() - test_with_selective_printing(wfmadb, (V128_V_RES_AS_FLOAT64 | - V128_V_ARG1_AS_FLOAT64 | - V128_V_ARG2_AS_FLOAT64 | -- V128_V_ARG3_AS_FLOAT64)); -+ V128_V_ARG3_AS_FLOAT64 | -+ V128_V_RES_ZERO_ONLY)); - test_with_selective_printing(vfmsdb, (V128_V_RES_AS_FLOAT64 | - V128_V_ARG1_AS_FLOAT64 | - V128_V_ARG2_AS_FLOAT64 | -@@ -174,21 +184,25 @@ int main() - test_with_selective_printing(wfmsdb, (V128_V_RES_AS_FLOAT64 | - V128_V_ARG1_AS_FLOAT64 | - V128_V_ARG2_AS_FLOAT64 | -- V128_V_ARG3_AS_FLOAT64)); -+ V128_V_ARG3_AS_FLOAT64 | -+ V128_V_RES_ZERO_ONLY)); - - test_with_selective_printing(wfcdb, (V128_V_ARG1_AS_FLOAT64 | - V128_V_ARG2_AS_FLOAT64 | -- V128_R_RES)); -+ V128_R_RES | -+ V128_V_RES_ZERO_ONLY)); - test_with_selective_printing(wfkdb, (V128_V_ARG1_AS_FLOAT64 | - V128_V_ARG2_AS_FLOAT64 | -- V128_R_RES)); -+ V128_R_RES | -+ V128_V_RES_ZERO_ONLY)); - - test_with_selective_printing(vfcedb, (V128_V_RES_AS_INT | - V128_V_ARG1_AS_FLOAT64 | - V128_V_ARG2_AS_FLOAT64)); - test_with_selective_printing(wfcedb, (V128_V_RES_AS_INT | - V128_V_ARG1_AS_FLOAT64 | -- V128_V_ARG2_AS_FLOAT64)); -+ V128_V_ARG2_AS_FLOAT64 | -+ V128_V_RES_ZERO_ONLY)); - test_with_selective_printing(vfcedbs, (V128_V_RES_AS_INT | - V128_V_ARG1_AS_FLOAT64 | - V128_V_ARG2_AS_FLOAT64 | -@@ -196,14 +210,16 @@ int main() - test_with_selective_printing(wfcedbs, (V128_V_RES_AS_INT | - V128_V_ARG1_AS_FLOAT64 | - V128_V_ARG2_AS_FLOAT64 | -- V128_R_RES)); -+ V128_R_RES | -+ V128_V_RES_ZERO_ONLY)); - - test_with_selective_printing(vfchdb, (V128_V_RES_AS_INT | - V128_V_ARG1_AS_FLOAT64 | - V128_V_ARG2_AS_FLOAT64)); - test_with_selective_printing(wfchdb, (V128_V_RES_AS_INT | - V128_V_ARG1_AS_FLOAT64 | -- V128_V_ARG2_AS_FLOAT64)); -+ V128_V_ARG2_AS_FLOAT64 | -+ V128_V_RES_ZERO_ONLY)); - test_with_selective_printing(vfchdbs, (V128_V_RES_AS_INT | - V128_V_ARG1_AS_FLOAT64 | - V128_V_ARG2_AS_FLOAT64 | -@@ -211,14 +227,16 @@ int main() - test_with_selective_printing(wfchdbs, (V128_V_RES_AS_INT | - V128_V_ARG1_AS_FLOAT64 | - V128_V_ARG2_AS_FLOAT64 | -- V128_R_RES)); -+ V128_R_RES | -+ V128_V_RES_ZERO_ONLY)); - - test_with_selective_printing(vfchedb, (V128_V_RES_AS_INT | - V128_V_ARG1_AS_FLOAT64 | - V128_V_ARG2_AS_FLOAT64)); - test_with_selective_printing(wfchedb, (V128_V_RES_AS_INT | - V128_V_ARG1_AS_FLOAT64 | -- V128_V_ARG2_AS_FLOAT64)); -+ V128_V_ARG2_AS_FLOAT64 | -+ V128_V_RES_ZERO_ONLY)); - test_with_selective_printing(vfchedbs, (V128_V_RES_AS_INT | - V128_V_ARG1_AS_FLOAT64 | - V128_V_ARG2_AS_FLOAT64 | -@@ -226,7 +244,8 @@ int main() - test_with_selective_printing(wfchedbs, (V128_V_RES_AS_INT | - V128_V_ARG1_AS_FLOAT64 | - V128_V_ARG2_AS_FLOAT64 | -- V128_R_RES)); -+ V128_R_RES | -+ V128_V_RES_ZERO_ONLY)); - - test_with_selective_printing(vftcidb0, (V128_V_RES_AS_INT | - V128_V_ARG1_AS_FLOAT64 | -diff --git a/none/tests/s390x/vector_float.stdout.exp b/none/tests/s390x/vector_float.stdout.exp -index eac525041..a330ac832 100644 ---- a/none/tests/s390x/vector_float.stdout.exp -+++ b/none/tests/s390x/vector_float.stdout.exp -@@ -419,88 +419,88 @@ insn vcgdb07: - v_result = 7fffffffffffffff | 7fffffffffffffff - v_arg1 = 0x1.fed2f087c21p+341 | 0x1.180e4c1d87fc4p+682 - insn wcgdb00: -- v_result = 7fffffffffffffff | 0000000000000000 -+ v_result = 7fffffffffffffff | -- - v_arg1 = 0x1.d7fd9222e8b86p+670 | 0x1.c272612672a3p+798 - insn wcgdb00: -- v_result = 0000000000000000 | 0000000000000000 -+ v_result = 0000000000000000 | -- - v_arg1 = 0x1.745cd360987e5p-496 | -0x1.f3b404919f358p-321 - insn wcgdb00: -- v_result = 8000000000000000 | 0000000000000000 -+ v_result = 8000000000000000 | -- - v_arg1 = -0x1.9523565cd92d5p+643 | 0x1.253677d6d3be2p-556 - insn wcgdb00: -- v_result = 7fffffffffffffff | 0000000000000000 -+ v_result = 7fffffffffffffff | -- - v_arg1 = 0x1.b6eb576ec3e6ap+845 | -0x1.c7e102c503d91p+266 - insn wcgdb01: -- v_result = 0000000000000000 | 0000000000000000 -+ v_result = 0000000000000000 | -- - v_arg1 = -0x1.3d4319841f4d6p-1011 | -0x1.2feabf7dfc506p-680 - insn wcgdb01: -- v_result = 0000000000000000 | 0000000000000000 -+ v_result = 0000000000000000 | -- - v_arg1 = -0x1.6fb8d1cd8b32cp-843 | -0x1.50f6a6922f97ep+33 - insn wcgdb01: -- v_result = 0000000000000000 | 0000000000000000 -+ v_result = 0000000000000000 | -- - v_arg1 = -0x1.64a673daccf1ap-566 | -0x1.69ef9b1d01499p+824 - insn wcgdb01: -- v_result = 8000000000000000 | 0000000000000000 -+ v_result = 8000000000000000 | -- - v_arg1 = -0x1.3e2ddd862b4adp+1005 | -0x1.312466410271p+184 - insn wcgdb03: -- v_result = 0000000000000001 | 0000000000000000 -+ v_result = 0000000000000001 | -- - v_arg1 = 0x1.d594c3412a11p-953 | -0x1.a07393d34d77cp-224 - insn wcgdb03: -- v_result = 8000000000000000 | 0000000000000000 -+ v_result = 8000000000000000 | -- - v_arg1 = -0x1.f7a0dbcfd6e4cp+104 | -0x1.40f7cde7f2214p-702 - insn wcgdb03: -- v_result = 8000000000000000 | 0000000000000000 -+ v_result = 8000000000000000 | -- - v_arg1 = -0x1.40739c1574808p+560 | -0x1.970328ddf1b6ep-374 - insn wcgdb03: -- v_result = 0000000000000001 | 0000000000000000 -+ v_result = 0000000000000001 | -- - v_arg1 = 0x1.477653afd7048p-38 | 0x1.1eac2f8b2a93cp-384 - insn wcgdb04: -- v_result = ffffffffe9479a7d | 0000000000000000 -+ v_result = ffffffffe9479a7d | -- - v_arg1 = -0x1.6b865833eff3p+28 | 0x1.06e8cf1834d0ep-722 - insn wcgdb04: -- v_result = 0000000000000000 | 0000000000000000 -+ v_result = 0000000000000000 | -- - v_arg1 = 0x1.eef0b2294a5cp-544 | -0x1.8e8b133ccda15p+752 - insn wcgdb04: -- v_result = 0000000000000000 | 0000000000000000 -+ v_result = 0000000000000000 | -- - v_arg1 = -0x1.f34e77e6b6698p-894 | -0x1.9f7ce1cb53bddp-896 - insn wcgdb04: -- v_result = 7fffffffffffffff | 0000000000000000 -+ v_result = 7fffffffffffffff | -- - v_arg1 = 0x1.95707a6d75db5p+1018 | -0x1.3b0c072d23011p-224 - insn wcgdb05: -- v_result = 0000000000000000 | 0000000000000000 -+ v_result = 0000000000000000 | -- - v_arg1 = -0x1.a9fb71160793p-968 | 0x1.05f601fe8123ap-986 - insn wcgdb05: -- v_result = 8000000000000000 | 0000000000000000 -+ v_result = 8000000000000000 | -- - v_arg1 = -0x1.0864159b94305p+451 | -0x1.d4647f5a78b7ep-599 - insn wcgdb05: -- v_result = 7fffffffffffffff | 0000000000000000 -+ v_result = 7fffffffffffffff | -- - v_arg1 = 0x1.37eadff8397c8p+432 | -0x1.15d896b6f6063p+464 - insn wcgdb05: -- v_result = 0000000000000000 | 0000000000000000 -+ v_result = 0000000000000000 | -- - v_arg1 = 0x1.eb0812b0d677p-781 | 0x1.3117c5e0e288cp-202 - insn wcgdb06: -- v_result = 0000000000000001 | 0000000000000000 -+ v_result = 0000000000000001 | -- - v_arg1 = 0x1.6b88069167c0fp-662 | -0x1.70571d27e1279p+254 - insn wcgdb06: -- v_result = 7fffffffffffffff | 0000000000000000 -+ v_result = 7fffffffffffffff | -- - v_arg1 = 0x1.f6a6d6e883596p+260 | 0x1.0d578afaaa34ap+604 - insn wcgdb06: -- v_result = 0000000000000001 | 0000000000000000 -+ v_result = 0000000000000001 | -- - v_arg1 = 0x1.d91c7d13c4694p-475 | -0x1.ecf1f8529767bp+830 - insn wcgdb06: -- v_result = 0000000000000001 | 0000000000000000 -+ v_result = 0000000000000001 | -- - v_arg1 = 0x1.fac8dd3bb7af6p-101 | 0x1.fb8324a00fba8p+959 - insn wcgdb07: -- v_result = 7fffffffffffffff | 0000000000000000 -+ v_result = 7fffffffffffffff | -- - v_arg1 = 0x1.4b0fa18fa73c7p+111 | -0x1.08e7b17633a49p+61 - insn wcgdb07: -- v_result = e636b693e39a1100 | 0000000000000000 -+ v_result = e636b693e39a1100 | -- - v_arg1 = -0x1.9c9496c1c65efp+60 | 0x1.c4182ee728d76p-572 - insn wcgdb07: -- v_result = ffffffffffffffff | 0000000000000000 -+ v_result = ffffffffffffffff | -- - v_arg1 = -0x1.819718032dff7p-303 | 0x1.a784c77ff6aa2p-622 - insn wcgdb07: -- v_result = 7fffffffffffffff | 0000000000000000 -+ v_result = 7fffffffffffffff | -- - v_arg1 = 0x1.978e8abfd83c2p+152 | 0x1.2531ebf451762p+315 - insn vclgdb00: - v_result = 0000000000000000 | 0000000000000000 -@@ -587,88 +587,88 @@ insn vclgdb07: - v_result = 0000000000000000 | 0000000000000000 - v_arg1 = -0x1.137bbb51f08bdp+306 | 0x1.18d2a1063356p-795 - insn wclgdb00: -- v_result = 0000000000000000 | 0000000000000000 -+ v_result = 0000000000000000 | -- - v_arg1 = -0x1.e66f55dcc2639p-1013 | -0x1.733ee56929f3bp-304 - insn wclgdb00: -- v_result = 0000000000000000 | 0000000000000000 -+ v_result = 0000000000000000 | -- - v_arg1 = 0x1.8802fd9ab740cp-986 | -0x1.64d4d2c7c145fp-1015 - insn wclgdb00: -- v_result = 0000000000000000 | 0000000000000000 -+ v_result = 0000000000000000 | -- - v_arg1 = 0x1.a67209b8c407bp-645 | -0x1.6410ff9b1c801p+487 - insn wclgdb00: -- v_result = 0000000000000000 | 0000000000000000 -+ v_result = 0000000000000000 | -- - v_arg1 = -0x1.cb2febaefeb2dp+49 | 0x1.dee368b2ec375p-502 - insn wclgdb01: -- v_result = 0000000000000000 | 0000000000000000 -+ v_result = 0000000000000000 | -- - v_arg1 = 0x1.5703db3c1b0e2p-728 | 0x1.068c4d51ea4ebp+617 - insn wclgdb01: -- v_result = 0000000000000000 | 0000000000000000 -+ v_result = 0000000000000000 | -- - v_arg1 = -0x1.ae350291e5b3ep+291 | 0x1.1b87bb09b6032p+376 - insn wclgdb01: -- v_result = ffffffffffffffff | 0000000000000000 -+ v_result = ffffffffffffffff | -- - v_arg1 = 0x1.c4666a710127ep+424 | -0x1.19e969b6c0076p+491 - insn wclgdb01: -- v_result = ffffffffffffffff | 0000000000000000 -+ v_result = ffffffffffffffff | -- - v_arg1 = 0x1.c892c5a4d103fp+105 | -0x1.d4f937cc76704p+749 - insn wclgdb03: -- v_result = 0000000000000001 | 0000000000000000 -+ v_result = 0000000000000001 | -- - v_arg1 = 0x1.81090d8fc663dp-111 | 0x1.337ec5e0f0904p+1 - insn wclgdb03: -- v_result = 0000000000000000 | 0000000000000000 -+ v_result = 0000000000000000 | -- - v_arg1 = -0x1.e787adc70b91p-593 | 0x1.db8d83196b53cp-762 - insn wclgdb03: -- v_result = ffffffffffffffff | 0000000000000000 -+ v_result = ffffffffffffffff | -- - v_arg1 = 0x1.6529307e907efp+389 | -0x1.3ea0d8d5b4dd2p+589 - insn wclgdb03: -- v_result = 0000000000000000 | 0000000000000000 -+ v_result = 0000000000000000 | -- - v_arg1 = -0x1.be701a158637p-385 | 0x1.c5a7f70cb8a09p+107 - insn wclgdb04: -- v_result = 0000000000000000 | 0000000000000000 -+ v_result = 0000000000000000 | -- - v_arg1 = -0x1.2f328571ab445p+21 | -0x1.dcc21fc82ba01p-930 - insn wclgdb04: -- v_result = 0000000000000000 | 0000000000000000 -+ v_result = 0000000000000000 | -- - v_arg1 = -0x1.06b69fcbb7bffp-415 | 0x1.6f9a13a0a827ap+915 - insn wclgdb04: -- v_result = 0000000000000000 | 0000000000000000 -+ v_result = 0000000000000000 | -- - v_arg1 = -0x1.738e549b38bcdp+479 | 0x1.a522edb999c9p-45 - insn wclgdb04: -- v_result = 0000000000000000 | 0000000000000000 -+ v_result = 0000000000000000 | -- - v_arg1 = 0x1.7f9399d2bcf3bp-215 | -0x1.7bc35f2d69a7fp+818 - insn wclgdb05: -- v_result = ffffffffffffffff | 0000000000000000 -+ v_result = ffffffffffffffff | -- - v_arg1 = 0x1.fc542bdb707f6p+880 | -0x1.8521ebc93a25fp-969 - insn wclgdb05: -- v_result = 1ce8d9951b8c8600 | 0000000000000000 -+ v_result = 1ce8d9951b8c8600 | -- - v_arg1 = 0x1.ce8d9951b8c86p+60 | 0x1.92712589230e7p+475 - insn wclgdb05: -- v_result = 0000000000000000 | 0000000000000000 -+ v_result = 0000000000000000 | -- - v_arg1 = -0x1.8a297f60a0811p-156 | 0x1.102b79043d82cp-204 - insn wclgdb05: -- v_result = 0000000000000000 | 0000000000000000 -+ v_result = 0000000000000000 | -- - v_arg1 = 0x1.beb9057e1401dp-196 | -0x1.820f18f830262p+15 - insn wclgdb06: -- v_result = 0000000000000001 | 0000000000000000 -+ v_result = 0000000000000001 | -- - v_arg1 = 0x1.c321a966ecb4dp-430 | -0x1.2f6a1a95ead99p-943 - insn wclgdb06: -- v_result = 0000000000000000 | 0000000000000000 -+ v_result = 0000000000000000 | -- - v_arg1 = -0x1.f1a86b4aed821p-56 | -0x1.1ee6717cc2d7fp-899 - insn wclgdb06: -- v_result = 0000000000000000 | 0000000000000000 -+ v_result = 0000000000000000 | -- - v_arg1 = -0x1.73ce49d89ecb9p-302 | 0x1.52663b975ed23p-716 - insn wclgdb06: -- v_result = 0000000000000000 | 0000000000000000 -+ v_result = 0000000000000000 | -- - v_arg1 = -0x1.3e9c2de97a292p+879 | 0x1.d34eed36f2eafp+960 - insn wclgdb07: -- v_result = 0000000000000000 | 0000000000000000 -+ v_result = 0000000000000000 | -- - v_arg1 = -0x1.4e6ec6ddc6a45p-632 | -0x1.6e564d0fec72bp+369 - insn wclgdb07: -- v_result = ffffffffffffffff | 0000000000000000 -+ v_result = ffffffffffffffff | -- - v_arg1 = 0x1.42e2c658e4c4dp+459 | -0x1.9f9dc0252e44p+85 - insn wclgdb07: -- v_result = 0000000000000000 | 0000000000000000 -+ v_result = 0000000000000000 | -- - v_arg1 = -0x1.fb40ac8cda3c1p-762 | 0x1.0e9ed614bc8f1p-342 - insn wclgdb07: -- v_result = 0000000000000000 | 0000000000000000 -+ v_result = 0000000000000000 | -- - v_arg1 = -0x1.c1f8b3c68e214p+118 | -0x1.1a26a49368b61p+756 - insn vfidb00: - v_arg1 = -0x1.38df4cf9d52dbp-545 | -0x1.049253d90dd92p+94 -@@ -1020,16 +1020,16 @@ insn vldeb: - v_result = -0x1.6f5fb2p+70 | -0x1.0d2df6p-107 - insn wldeb: - v_arg1 = -0x1.d26169729db2ap-435 | 0x1.d6fd080793e8cp+767 -- v_result = -0x1.9a4c2cp-54 | 0x0p+0 -+ v_result = -0x1.9a4c2cp-54 | -- - insn wldeb: - v_arg1 = -0x1.f4b59107fce61p-930 | 0x1.cdf2816e253f4p-168 -- v_result = -0x1.be96b2p-116 | 0x0p+0 -+ v_result = -0x1.be96b2p-116 | -- - insn wldeb: - v_arg1 = -0x1.9603a2997928cp-441 | -0x1.aada85e355a11p-767 -- v_result = -0x1.d2c074p-55 | 0x0p+0 -+ v_result = -0x1.d2c074p-55 | -- - insn wldeb: - v_arg1 = 0x1.25ccf5bd0e83p+620 | 0x1.e1635864ebb17p-88 -- v_result = 0x1.64b99ep+78 | 0x0p+0 -+ v_result = 0x1.64b99ep+78 | -- - insn vflcdb: - v_arg1 = 0x1.0ae6d82f76afp-166 | -0x1.e8fb1e03a7415p-191 - v_result = -0x1.0ae6d82f76afp-166 | 0x1.e8fb1e03a7415p-191 -@@ -1044,16 +1044,16 @@ insn vflcdb: - v_result = -0x1.19520153d35b4p-301 | -0x1.ac5325cd23253p+396 - insn wflcdb: - v_arg1 = 0x1.ffd3eecfd54d7p-831 | -0x1.97854fa523a77p+146 -- v_result = -0x1.ffd3eecfd54d7p-831 | 0x0p+0 -+ v_result = -0x1.ffd3eecfd54d7p-831 | -- - insn wflcdb: - v_arg1 = -0x1.508ea45606447p-442 | 0x1.ae7f0e6cf9d2bp+583 -- v_result = 0x1.508ea45606447p-442 | 0x0p+0 -+ v_result = 0x1.508ea45606447p-442 | -- - insn wflcdb: - v_arg1 = 0x1.da8ab2188c21ap+94 | 0x1.78a9c152aa074p-808 -- v_result = -0x1.da8ab2188c21ap+94 | 0x0p+0 -+ v_result = -0x1.da8ab2188c21ap+94 | -- - insn wflcdb: - v_arg1 = -0x1.086882645e0c5p-1001 | -0x1.54e2de5af5a74p-262 -- v_result = 0x1.086882645e0c5p-1001 | 0x0p+0 -+ v_result = 0x1.086882645e0c5p-1001 | -- - insn vflndb: - v_arg1 = -0x1.5bec561d407dcp+819 | -0x1.a5773dadb7a2dp+935 - v_result = -0x1.5bec561d407dcp+819 | -0x1.a5773dadb7a2dp+935 -@@ -1068,16 +1068,16 @@ insn vflndb: - v_result = -0x1.c5bc39a06d4e2p-259 | -0x1.c5e61ad849e77p-833 - insn wflndb: - v_arg1 = -0x1.e9f3e6d1beffap-117 | -0x1.d58cc8bf123b3p-714 -- v_result = -0x1.e9f3e6d1beffap-117 | 0x0p+0 -+ v_result = -0x1.e9f3e6d1beffap-117 | -- - insn wflndb: - v_arg1 = -0x1.3fc4ef2e7485ep-691 | 0x1.eb328986081efp-775 -- v_result = -0x1.3fc4ef2e7485ep-691 | 0x0p+0 -+ v_result = -0x1.3fc4ef2e7485ep-691 | -- - insn wflndb: - v_arg1 = -0x1.7146c5afdec16p+23 | -0x1.597fcfa1fab2p-708 -- v_result = -0x1.7146c5afdec16p+23 | 0x0p+0 -+ v_result = -0x1.7146c5afdec16p+23 | -- - insn wflndb: - v_arg1 = 0x1.03f8d7e9afe84p-947 | 0x1.9a10c3feb6b57p-118 -- v_result = -0x1.03f8d7e9afe84p-947 | 0x0p+0 -+ v_result = -0x1.03f8d7e9afe84p-947 | -- - insn vflpdb: - v_arg1 = 0x1.64ae59b6c762ep-407 | -0x1.fa7191ab21e86p+533 - v_result = 0x1.64ae59b6c762ep-407 | 0x1.fa7191ab21e86p+533 -@@ -1092,16 +1092,16 @@ insn vflpdb: - v_result = 0x1.85fa2de1d492ap+170 | 0x1.ac36828822c11p-968 - insn wflpdb: - v_arg1 = 0x1.a6cf677640a73p-871 | 0x1.b6f1792385922p-278 -- v_result = 0x1.a6cf677640a73p-871 | 0x0p+0 -+ v_result = 0x1.a6cf677640a73p-871 | -- - insn wflpdb: - v_arg1 = -0x1.b886774f6d888p-191 | -0x1.6a2b08d735d22p-643 -- v_result = 0x1.b886774f6d888p-191 | 0x0p+0 -+ v_result = 0x1.b886774f6d888p-191 | -- - insn wflpdb: - v_arg1 = 0x1.5045d37d46f5fp+943 | -0x1.333a86ef2dcf6p-1013 -- v_result = 0x1.5045d37d46f5fp+943 | 0x0p+0 -+ v_result = 0x1.5045d37d46f5fp+943 | -- - insn wflpdb: - v_arg1 = 0x1.1e7bec6ada14dp+252 | 0x1.a70b3f3e24dap-153 -- v_result = 0x1.1e7bec6ada14dp+252 | 0x0p+0 -+ v_result = 0x1.1e7bec6ada14dp+252 | -- - insn vfadb: - v_arg1 = 0x1.5b1ad8e9f17c6p-294 | -0x1.ddd8300a0bf02p+122 - v_arg2 = -0x1.9b49c31ca8ac6p+926 | 0x1.fdbc992926268p+677 -@@ -1121,19 +1121,19 @@ insn vfadb: - insn wfadb: - v_arg1 = 0x1.3c5466cb80722p+489 | -0x1.11e1770053ca2p+924 - v_arg2 = 0x1.d876cd721a726p-946 | 0x1.5c04ceb79c9bcp+1001 -- v_result = 0x1.3c5466cb80722p+489 | 0x0p+0 -+ v_result = 0x1.3c5466cb80722p+489 | -- - insn wfadb: - v_arg1 = 0x1.b0b142d6b76a3p+577 | 0x1.3146824e993a2p+432 - v_arg2 = -0x1.f7f3b7582925fp-684 | -0x1.9700143c2b935p-837 -- v_result = 0x1.b0b142d6b76a2p+577 | 0x0p+0 -+ v_result = 0x1.b0b142d6b76a2p+577 | -- - insn wfadb: - v_arg1 = -0x1.8d65e15edabd6p+244 | 0x1.3be7fd08492d6p-141 - v_arg2 = -0x1.5eef86490fb0ap+481 | 0x1.7b26c897cb6dfp+810 -- v_result = -0x1.5eef86490fb0ap+481 | 0x0p+0 -+ v_result = -0x1.5eef86490fb0ap+481 | -- - insn wfadb: - v_arg1 = -0x1.2dffa5b5f29p+34 | 0x1.71a026274602fp-881 - v_arg2 = 0x1.4dad707287289p+756 | -0x1.1500d55807247p-616 -- v_result = 0x1.4dad707287288p+756 | 0x0p+0 -+ v_result = 0x1.4dad707287288p+756 | -- - insn vfsdb: - v_arg1 = 0x1.054fd9c4d4883p+644 | 0x1.45c90ed85bd7fp-780 - v_arg2 = 0x1.f3bc7a611dadap+494 | -0x1.7c9e1e858ba5bp-301 -@@ -1153,19 +1153,19 @@ insn vfsdb: - insn wfsdb: - v_arg1 = 0x1.9090dabf846e7p-648 | 0x1.1c4ab843a2d15p+329 - v_arg2 = -0x1.a7ceb293690dep+316 | 0x1.22245954a20cp+42 -- v_result = 0x1.a7ceb293690dep+316 | 0x0p+0 -+ v_result = 0x1.a7ceb293690dep+316 | -- - insn wfsdb: - v_arg1 = 0x1.4e5347c27819p-933 | -0x1.56a30bda28351p-64 - v_arg2 = -0x1.dedb9f3935b56p-155 | 0x1.8c5b6ed76816cp-522 -- v_result = 0x1.dedb9f3935b56p-155 | 0x0p+0 -+ v_result = 0x1.dedb9f3935b56p-155 | -- - insn wfsdb: - v_arg1 = 0x1.0ec4e562a015bp-491 | 0x1.3996381b52d9fp-686 - v_arg2 = 0x1.1dcce4e81819p+960 | -0x1.32fa425e8fc08p-263 -- v_result = -0x1.1dcce4e81818fp+960 | 0x0p+0 -+ v_result = -0x1.1dcce4e81818fp+960 | -- - insn wfsdb: - v_arg1 = -0x1.587229f90f77dp-19 | 0x1.100d8eb8105e4p-784 - v_arg2 = -0x1.afb4cce4c43ddp+530 | -0x1.6da7f05e7f512p-869 -- v_result = 0x1.afb4cce4c43dcp+530 | 0x0p+0 -+ v_result = 0x1.afb4cce4c43dcp+530 | -- - insn vfmdb: - v_arg1 = 0x1.892b425556c47p-124 | 0x1.38222404079dfp-656 - v_arg2 = 0x1.af612ed2c342dp-267 | -0x1.1f735fd6ce768p-877 -@@ -1185,19 +1185,19 @@ insn vfmdb: - insn wfmdb: - v_arg1 = -0x1.b992d950126a1p-683 | -0x1.9c1b22eb58c59p-497 - v_arg2 = 0x1.b557a7d8e32c3p-25 | -0x1.f746b2ddafccep+227 -- v_result = -0x1.792f6fb13894ap-707 | 0x0p+0 -+ v_result = -0x1.792f6fb13894ap-707 | -- - insn wfmdb: - v_arg1 = -0x1.677a8c20a5a2fp+876 | 0x1.c03e7b97e8c0dp-645 - v_arg2 = 0x1.dab44be430937p-1011 | -0x1.3f51352c67be9p-916 -- v_result = -0x1.4d4b0a1827064p-134 | 0x0p+0 -+ v_result = -0x1.4d4b0a1827064p-134 | -- - insn wfmdb: - v_arg1 = -0x1.da60f596ad0cep+254 | 0x1.52332e0650e33p+966 - v_arg2 = 0x1.a042c52ed993cp+215 | 0x1.8f380c84aa133p+204 -- v_result = -0x1.81aca4bbcbd24p+470 | 0x0p+0 -+ v_result = -0x1.81aca4bbcbd24p+470 | -- - insn wfmdb: - v_arg1 = -0x1.83d17f11f6aa3p-469 | -0x1.98117efe89b9ep-361 - v_arg2 = 0x1.8c445fd46d214p-701 | -0x1.f98118821821cp+596 -- v_result = -0x0p+0 | 0x0p+0 -+ v_result = -0x0p+0 | -- - insn vfddb: - v_arg1 = -0x1.ecbb48899e0f1p+969 | 0x1.caf175ab352p-20 - v_arg2 = -0x1.9455d67f9f79dp+208 | 0x1.bc4a431b04a6fp+482 -@@ -1217,19 +1217,19 @@ insn vfddb: - insn wfddb: - v_arg1 = 0x1.bd48489b60731p-114 | 0x1.a760dcf57b74fp-51 - v_arg2 = -0x1.171f83409eeb6p-402 | -0x1.e159d1409bdc6p-972 -- v_result = -0x1.9864f1511f8cp+288 | 0x0p+0 -+ v_result = -0x1.9864f1511f8cp+288 | -- - insn wfddb: - v_arg1 = -0x1.120505ef4606p-637 | -0x1.83f6f775c0eb7p+272 - v_arg2 = -0x1.d18ba3872fde1p+298 | 0x1.c60f8d191068cp-454 -- v_result = 0x1.2d5cdb15a686cp-936 | 0x0p+0 -+ v_result = 0x1.2d5cdb15a686cp-936 | -- - insn wfddb: - v_arg1 = 0x1.f637f7f8c790fp-97 | -0x1.7bdce4d74947p+189 - v_arg2 = -0x1.1c8f2d1b3a2edp-218 | -0x1.55fdfd1840241p-350 -- v_result = -0x1.c3d0799c1420fp+121 | 0x0p+0 -+ v_result = -0x1.c3d0799c1420fp+121 | -- - insn wfddb: - v_arg1 = -0x1.c63b7b2eee253p+250 | 0x1.dfd9dcd8b823fp-125 - v_arg2 = 0x1.094a1f1f87e0cp+629 | 0x1.eeaa23c0d7843p-814 -- v_result = -0x1.b653a10ebdeccp-379 | 0x0p+0 -+ v_result = -0x1.b653a10ebdeccp-379 | -- - insn vfsqdb: - v_arg1 = 0x1.f60db25f7066p-703 | -0x1.d43509abca8c3p+631 - v_result = 0x1.fb009ab25ec11p-352 | nan -@@ -1244,16 +1244,16 @@ insn vfsqdb: - v_result = 0x1.833dba0954bccp+249 | nan - insn wfsqdb: - v_arg1 = 0x1.71af4e7f64978p+481 | -0x1.3429dc60011d7p-879 -- v_result = 0x1.b30fc65551133p+240 | 0x0p+0 -+ v_result = 0x1.b30fc65551133p+240 | -- - insn wfsqdb: - v_arg1 = 0x1.5410db1c5f403p+173 | 0x1.97fa6581e692fp+108 -- v_result = 0x1.a144f43a592c1p+86 | 0x0p+0 -+ v_result = 0x1.a144f43a592c1p+86 | -- - insn wfsqdb: - v_arg1 = -0x1.5838027725afep+6 | 0x1.ac61529c11f38p+565 -- v_result = nan | 0x0p+0 -+ v_result = nan | -- - insn wfsqdb: - v_arg1 = -0x1.159e341dcc06ep-439 | 0x1.ed54ce5481ba5p-574 -- v_result = nan | 0x0p+0 -+ v_result = nan | -- - insn vfmadb: - v_arg1 = -0x1.eb00a5c503d75p+538 | 0x1.89fae603ddc07p+767 - v_arg2 = -0x1.71c72712c3957p+715 | 0x1.1bd5773442feap+762 -@@ -1278,22 +1278,22 @@ insn wfmadb: - v_arg1 = 0x1.1cc5b10a14d54p+668 | -0x1.686407390f7d1p+616 - v_arg2 = -0x1.bf34549e73246p+676 | -0x1.dc5a34cc470f3p+595 - v_arg3 = -0x1.95e0fdcf13974p-811 | -0x1.79c7cc1a8ec83p-558 -- v_result = -0x1.fffffffffffffp+1023 | 0x0p+0 -+ v_result = -0x1.fffffffffffffp+1023 | -- - insn wfmadb: - v_arg1 = 0x1.138bc1a5d75f8p+713 | -0x1.e226ebba2fe54p+381 - v_arg2 = -0x1.081ebb7cc3414p-772 | 0x1.369d99e174fc3p+922 - v_arg3 = -0x1.0671c682a5d0cp-1016 | 0x1.03c9530dd0377p+378 -- v_result = -0x1.1c4933e117d95p-59 | 0x0p+0 -+ v_result = -0x1.1c4933e117d95p-59 | -- - insn wfmadb: - v_arg1 = -0x1.166f0b1fad67bp+64 | -0x1.e9ee8d32e1069p-452 - v_arg2 = -0x1.4a235bdd109e2p-65 | 0x1.bacaa96fc7e81p-403 - v_arg3 = -0x1.d2e19acf7c4bdp+99 | 0x1.f901130f685adp-963 -- v_result = -0x1.d2e19acf7c4bcp+99 | 0x0p+0 -+ v_result = -0x1.d2e19acf7c4bcp+99 | -- - insn wfmadb: - v_arg1 = -0x1.77d7bfec863d2p-988 | -0x1.b68029700c6b1p-206 - v_arg2 = -0x1.aca05ad00aec1p+737 | 0x1.ac746bd7e216bp+51 - v_arg3 = 0x1.17342292078b4p+188 | -0x1.49efaf9392301p+555 -- v_result = 0x1.17342292078b4p+188 | 0x0p+0 -+ v_result = 0x1.17342292078b4p+188 | -- - insn vfmsdb: - v_arg1 = -0x1.a1b218e84e61p+34 | 0x1.b220f0d144daep-111 - v_arg2 = 0x1.564fcc2527961p-265 | 0x1.ea85a4154721ep+733 -@@ -1318,22 +1318,22 @@ insn wfmsdb: - v_arg1 = -0x1.7499a639673a6p-100 | -0x1.2a0d737e6cb1cp-207 - v_arg2 = -0x1.01ad4670a7aa3p-911 | 0x1.f94385e1021e8p+317 - v_arg3 = 0x1.aa42b2bb17af9p+982 | 0x1.c550e471711p+786 -- v_result = -0x1.aa42b2bb17af8p+982 | 0x0p+0 -+ v_result = -0x1.aa42b2bb17af8p+982 | -- - insn wfmsdb: - v_arg1 = 0x1.76840f99b431ep+500 | -0x1.989a500c92c08p+594 - v_arg2 = 0x1.33c657cb8385cp-84 | -0x1.2c795ad92ce17p+807 - v_arg3 = -0x1.ee58a39f02d54p-351 | -0x1.18695ed9a280ap+48 -- v_result = 0x1.c242894a0068p+416 | 0x0p+0 -+ v_result = 0x1.c242894a0068p+416 | -- - insn wfmsdb: - v_arg1 = -0x1.16db07e054a65p-469 | -0x1.3a627ab99c6e4p+689 - v_arg2 = 0x1.17872eae826e5p-538 | 0x1.44ed513fb5873p-929 - v_arg3 = 0x1.5ca912008e077p-217 | -0x1.982a6f7359876p-23 -- v_result = -0x1.5ca912008e077p-217 | 0x0p+0 -+ v_result = -0x1.5ca912008e077p-217 | -- - insn wfmsdb: - v_arg1 = -0x1.d315f4a932c6p+122 | 0x1.616a04493e143p+513 - v_arg2 = -0x1.cf1cd3516f23fp+552 | 0x1.7121749c3932cp-750 - v_arg3 = 0x1.dc26d92304d7fp-192 | -0x1.1fc3cca9ec20ep+371 -- v_result = 0x1.a67ca6ba395bcp+675 | 0x0p+0 -+ v_result = 0x1.a67ca6ba395bcp+675 | -- - insn wfcdb: - v_arg1 = 0x1.302001b736011p-633 | -0x1.72d5300225c97p-468 - v_arg2 = -0x1.8c007c5aba108p-17 | -0x1.bb3f9ae136acdp+569 -@@ -1383,19 +1383,19 @@ insn vfcedb: - v_arg1 = 0x1.d8e5c9930c19dp+623 | -0x1.cf1facff4e194p-605 - v_arg2 = -0x1.ed6ba02646d0dp+441 | -0x1.2d677e710620bp+810 - insn wfcedb: -- v_result = 0000000000000000 | 0000000000000000 -+ v_result = 0000000000000000 | -- - v_arg1 = -0x1.a252009e1a12cp-442 | 0x1.4dc608268bb29p-513 - v_arg2 = -0x1.81020aa1a36e6p-687 | -0x1.300e64ce414f1p-899 - insn wfcedb: -- v_result = 0000000000000000 | 0000000000000000 -+ v_result = 0000000000000000 | -- - v_arg1 = 0x1.cec439a8d4781p-175 | -0x1.d20e3b281d599p+893 - v_arg2 = 0x1.ca17cf16cf0aap-879 | 0x1.61506f8596092p+545 - insn wfcedb: -- v_result = 0000000000000000 | 0000000000000000 -+ v_result = 0000000000000000 | -- - v_arg1 = 0x1.0659f5f24a004p+877 | 0x1.fc46867ed0338p-680 - v_arg2 = -0x1.1d6849587155ep-1010 | -0x1.f68171edc235fp+575 - insn wfcedb: -- v_result = 0000000000000000 | 0000000000000000 -+ v_result = 0000000000000000 | -- - v_arg1 = 0x1.dc88a0d46ad79p-816 | 0x1.245140dcaed79p+851 - v_arg2 = 0x1.b33e977c7b3ep-818 | -0x1.04319d7c69367p+787 - insn vfcedbs: -@@ -1419,22 +1419,22 @@ insn vfcedbs: - v_arg2 = 0x1.ae2c06ea88ff4p+332 | -0x1.f668ce4f8ef9ap+821 - r_result = 0000000000000003 - insn wfcedbs: -- v_result = 0000000000000000 | 0000000000000000 -+ v_result = 0000000000000000 | -- - v_arg1 = 0x1.645261bf86b1fp-996 | 0x1.abd13c95397aap+992 - v_arg2 = -0x1.ba09e8fc66a8cp+113 | 0x1.75dbfe92c16c4p-786 - r_result = 0000000000000003 - insn wfcedbs: -- v_result = 0000000000000000 | 0000000000000000 -+ v_result = 0000000000000000 | -- - v_arg1 = -0x1.d02831d003e7dp+415 | -0x1.611a9dfd10f36p-80 - v_arg2 = -0x1.10bda62f4647p+723 | 0x1.cc47af6653378p-614 - r_result = 0000000000000003 - insn wfcedbs: -- v_result = 0000000000000000 | 0000000000000000 -+ v_result = 0000000000000000 | -- - v_arg1 = 0x1.f168f32f84178p-321 | -0x1.79a2a0b9549d1p-136 - v_arg2 = 0x1.41e19d1cfa692p+11 | -0x1.2a0ed6e7fd517p-453 - r_result = 0000000000000003 - insn wfcedbs: -- v_result = 0000000000000000 | 0000000000000000 -+ v_result = 0000000000000000 | -- - v_arg1 = -0x1.76a9144ee26c5p+188 | -0x1.386aaea2d9cddp-542 - v_arg2 = 0x1.810fcf222efc4p-999 | -0x1.ce90a9a43e2a1p+80 - r_result = 0000000000000003 -@@ -1455,19 +1455,19 @@ insn vfchdb: - v_arg1 = 0x1.82be31fb88a2dp+946 | -0x1.7ca9e9ff31953p-931 - v_arg2 = 0x1.fe75a1052beccp+490 | 0x1.179d18543d678p-255 - insn wfchdb: -- v_result = ffffffffffffffff | 0000000000000000 -+ v_result = ffffffffffffffff | -- - v_arg1 = 0x1.0af85d8d8d609p-464 | -0x1.9f639a686e0fep+203 - v_arg2 = -0x1.3142b77b55761p-673 | 0x1.ca9c474339da1p+472 - insn wfchdb: -- v_result = ffffffffffffffff | 0000000000000000 -+ v_result = ffffffffffffffff | -- - v_arg1 = -0x1.6cf16959a022bp+213 | 0x1.445606e4363e1p+942 - v_arg2 = -0x1.8c343201bbd2p+939 | -0x1.e5095ad0c37a4p-434 - insn wfchdb: -- v_result = ffffffffffffffff | 0000000000000000 -+ v_result = ffffffffffffffff | -- - v_arg1 = 0x1.36b4fc9cf5bdap-52 | -0x1.f1fd95cbcd533p+540 - v_arg2 = 0x1.5a2362891c9edp-175 | -0x1.e1f68c319e5d2p+58 - insn wfchdb: -- v_result = ffffffffffffffff | 0000000000000000 -+ v_result = ffffffffffffffff | -- - v_arg1 = 0x1.11c6489f544bbp+811 | 0x1.262a740ec3d47p+456 - v_arg2 = -0x1.d9394d354e989p-154 | 0x1.cc21b3094391ap-972 - insn vfchdbs: -@@ -1491,22 +1491,22 @@ insn vfchdbs: - v_arg2 = 0x1.e426748435a76p+370 | 0x1.8702527d17783p-871 - r_result = 0000000000000003 - insn wfchdbs: -- v_result = ffffffffffffffff | 0000000000000000 -+ v_result = ffffffffffffffff | -- - v_arg1 = 0x1.6c51b9f6442c8p+639 | 0x1.1e6b37adff703p+702 - v_arg2 = 0x1.0cba9c1c75e43p+520 | -0x1.145d44ed90967p+346 - r_result = 0000000000000000 - insn wfchdbs: -- v_result = ffffffffffffffff | 0000000000000000 -+ v_result = ffffffffffffffff | -- - v_arg1 = 0x1.7b3dd643bf36bp+816 | -0x1.61ce7bfb9307ap-683 - v_arg2 = -0x1.f2c998dc15c9ap-776 | 0x1.e16397f2dcdf5p+571 - r_result = 0000000000000000 - insn wfchdbs: -- v_result = ffffffffffffffff | 0000000000000000 -+ v_result = ffffffffffffffff | -- - v_arg1 = 0x1.cc3be81884e0ap-865 | -0x1.8b353bd41064p+820 - v_arg2 = -0x1.2c1bafaafdd4ep-34 | -0x1.24666808ab16ep-435 - r_result = 0000000000000000 - insn wfchdbs: -- v_result = ffffffffffffffff | 0000000000000000 -+ v_result = ffffffffffffffff | -- - v_arg1 = 0x1.c3de33d3b673ap+554 | 0x1.d39ed71e53096p-798 - v_arg2 = -0x1.c1e8f7b3c001p-828 | 0x1.22e2cf797fabp-787 - r_result = 0000000000000000 -@@ -1527,19 +1527,19 @@ insn vfchedb: - v_arg1 = -0x1.6c5599e7ba923p+829 | -0x1.5d1a1191ed6eap-994 - v_arg2 = -0x1.555c8775bc4d2p-478 | -0x1.4aa6a2c82319cp+493 - insn wfchedb: -- v_result = ffffffffffffffff | 0000000000000000 -+ v_result = ffffffffffffffff | -- - v_arg1 = 0x1.ae6cad07b0f3ep-232 | -0x1.2ed61a43f3b99p-74 - v_arg2 = -0x1.226f7cddbde13p-902 | -0x1.790d1d6febbf8p+336 - insn wfchedb: -- v_result = ffffffffffffffff | 0000000000000000 -+ v_result = ffffffffffffffff | -- - v_arg1 = 0x1.20eb8eac3711dp-385 | 0x1.ef71d3312d7e1p+739 - v_arg2 = 0x1.7a3ba08c5a0bdp-823 | -0x1.a7845ccaa544dp-129 - insn wfchedb: -- v_result = 0000000000000000 | 0000000000000000 -+ v_result = 0000000000000000 | -- - v_arg1 = -0x1.97ebdbc057be8p+824 | 0x1.2b7798b063cd6p+237 - v_arg2 = 0x1.cdb87a6074294p-81 | -0x1.074c902b19bccp-416 - insn wfchedb: -- v_result = 0000000000000000 | 0000000000000000 -+ v_result = 0000000000000000 | -- - v_arg1 = -0x1.82deebf9ff023p+937 | 0x1.56c5adcf9d4abp-672 - v_arg2 = -0x1.311ce49bc9439p+561 | 0x1.c8e1c512d8544p+103 - insn vfchedbs: -@@ -1563,22 +1563,22 @@ insn vfchedbs: - v_arg2 = -0x1.47f5dfc7a5bcp-569 | 0x1.5877ef33664a3p-758 - r_result = 0000000000000003 - insn wfchedbs: -- v_result = 0000000000000000 | 0000000000000000 -+ v_result = 0000000000000000 | -- - v_arg1 = -0x1.a7370ccfd9e49p+505 | 0x1.c6b2385850ca2p-591 - v_arg2 = 0x1.984f4fcd338b1p+675 | -0x1.feb996c821232p-39 - r_result = 0000000000000003 - insn wfchedbs: -- v_result = ffffffffffffffff | 0000000000000000 -+ v_result = ffffffffffffffff | -- - v_arg1 = 0x1.641878612dd2p+207 | 0x1.b35e3292db7f6p+567 - v_arg2 = -0x1.18a87f209e96bp+299 | -0x1.3d598f3612d8ap+1016 - r_result = 0000000000000000 - insn wfchedbs: -- v_result = ffffffffffffffff | 0000000000000000 -+ v_result = ffffffffffffffff | -- - v_arg1 = 0x1.cfc2cda244153p+404 | 0x1.d8b2b28e9d8d7p+276 - v_arg2 = 0x1.3517b8c7a59a1p-828 | 0x1.6096fab7003ccp-415 - r_result = 0000000000000000 - insn wfchedbs: -- v_result = 0000000000000000 | 0000000000000000 -+ v_result = 0000000000000000 | -- - v_arg1 = -0x1.54d656f033e56p-603 | -0x1.95ad0e2088967p+254 - v_arg2 = 0x1.4cb319db206e4p-614 | 0x1.b41cd9e3739b6p-862 - r_result = 0000000000000003 diff --git a/valgrind-3.16.1-sched_getsetattr.patch b/valgrind-3.16.1-sched_getsetattr.patch deleted file mode 100644 index b95267d..0000000 --- a/valgrind-3.16.1-sched_getsetattr.patch +++ /dev/null @@ -1,201 +0,0 @@ -commit a53adb79711ccfc76a4ee32b20253045cdab55c7 -Author: Mark Wielaard -Date: Mon Jul 27 16:36:17 2020 +0200 - - Handle linux syscalls sched_getattr and sched_setattr - - The only "special" thing about these syscalls is that the given - struct sched_attr determines its own size for future expansion. - - Original fix by "ISHIKAWA,chiaki" - - https://bugs.kde.org/show_bug.cgi?id=369029 - -diff --git a/coregrind/m_syswrap/priv_syswrap-linux.h b/coregrind/m_syswrap/priv_syswrap-linux.h -index cdc73c1e6..eb0b320ca 100644 ---- a/coregrind/m_syswrap/priv_syswrap-linux.h -+++ b/coregrind/m_syswrap/priv_syswrap-linux.h -@@ -227,6 +227,8 @@ DECL_TEMPLATE(linux, sys_fremovexattr); - // syscalls. - DECL_TEMPLATE(linux, sys_sched_setparam); - DECL_TEMPLATE(linux, sys_sched_getparam); -+DECL_TEMPLATE(linux, sys_sched_setattr); -+DECL_TEMPLATE(linux, sys_sched_getattr); - DECL_TEMPLATE(linux, sys_sched_setscheduler); - DECL_TEMPLATE(linux, sys_sched_getscheduler); - DECL_TEMPLATE(linux, sys_sched_yield); -diff --git a/coregrind/m_syswrap/syswrap-amd64-linux.c b/coregrind/m_syswrap/syswrap-amd64-linux.c -index 28d90135a..d6f3eb910 100644 ---- a/coregrind/m_syswrap/syswrap-amd64-linux.c -+++ b/coregrind/m_syswrap/syswrap-amd64-linux.c -@@ -846,9 +846,8 @@ static SyscallTableEntry syscall_table[] = { - LINX_(__NR_process_vm_writev, sys_process_vm_writev),// 311 - LINX_(__NR_kcmp, sys_kcmp), // 312 - LINX_(__NR_finit_module, sys_finit_module), // 313 --// LIN__(__NR_sched_setattr, sys_ni_syscall), // 314 -- --// LIN__(__NR_sched_getattr, sys_ni_syscall), // 315 -+ LINX_(__NR_sched_setattr, sys_sched_setattr), // 314 -+ LINXY(__NR_sched_getattr, sys_sched_getattr), // 315 - LINX_(__NR_renameat2, sys_renameat2), // 316 - // LIN__(__NR_seccomp, sys_ni_syscall), // 317 - LINXY(__NR_getrandom, sys_getrandom), // 318 -diff --git a/coregrind/m_syswrap/syswrap-arm-linux.c b/coregrind/m_syswrap/syswrap-arm-linux.c -index 579542785..70700e53f 100644 ---- a/coregrind/m_syswrap/syswrap-arm-linux.c -+++ b/coregrind/m_syswrap/syswrap-arm-linux.c -@@ -1009,6 +1009,8 @@ static SyscallTableEntry syscall_main_table[] = { - LINXY(__NR_process_vm_readv, sys_process_vm_readv), // 376 - LINX_(__NR_process_vm_writev, sys_process_vm_writev),// 377 - -+ LINX_(__NR_sched_setattr, sys_sched_setattr), // 380 -+ LINXY(__NR_sched_getattr, sys_sched_getattr), // 381 - LINX_(__NR_renameat2, sys_renameat2), // 382 - - LINXY(__NR_getrandom, sys_getrandom), // 384 -diff --git a/coregrind/m_syswrap/syswrap-arm64-linux.c b/coregrind/m_syswrap/syswrap-arm64-linux.c -index 81e01456f..acca02442 100644 ---- a/coregrind/m_syswrap/syswrap-arm64-linux.c -+++ b/coregrind/m_syswrap/syswrap-arm64-linux.c -@@ -806,8 +806,8 @@ static SyscallTableEntry syscall_main_table[] = { - LINX_(__NR_process_vm_writev, sys_process_vm_writev), // 271 - LINX_(__NR_kcmp, sys_kcmp), // 272 - LINX_(__NR_finit_module, sys_finit_module), // 273 -- // (__NR_sched_setattr, sys_ni_syscall), // 274 -- // (__NR_sched_getattr, sys_ni_syscall), // 275 -+ LINX_(__NR_sched_setattr, sys_sched_setattr), // 274 -+ LINXY(__NR_sched_getattr, sys_sched_getattr), // 275 - LINX_(__NR_renameat2, sys_renameat2), // 276 - // (__NR_seccomp, sys_ni_syscall), // 277 - LINXY(__NR_getrandom, sys_getrandom), // 278 -diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c -index 5b5b7eee6..56be3032d 100644 ---- a/coregrind/m_syswrap/syswrap-linux.c -+++ b/coregrind/m_syswrap/syswrap-linux.c -@@ -3677,6 +3677,41 @@ POST(sys_sched_getparam) - POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) ); - } - -+PRE(sys_sched_setattr) -+{ -+ struct vki_sched_attr *attr; -+ PRINT("sched_setattr ( %ld, %#" FMT_REGWORD "x, %#" -+ FMT_REGWORD "x )", SARG1, ARG2, ARG3 ); -+ PRE_REG_READ3(long, "sched_setattr", -+ vki_pid_t, pid, struct sched_attr *, p, unsigned int, flags); -+ /* We need to be able to read at least the size field. */ -+ PRE_MEM_READ( "sched_setattr(attr->size)", ARG2, sizeof(vki_uint32_t) ); -+ attr = (struct vki_sched_attr *)(Addr)ARG2; -+ if (ML_(safe_to_deref)(attr,sizeof(vki_uint32_t))) -+ PRE_MEM_READ( "sched_setattr(attr)", (Addr)attr, attr->size); -+} -+ -+PRE(sys_sched_getattr) -+{ -+ struct vki_sched_attr *attr; -+ PRINT("sched_getattr ( %ld, %#" FMT_REGWORD "x, %ld, %#" -+ FMT_REGWORD "x )", SARG1, ARG2, ARG3, ARG4 ); -+ PRE_REG_READ4(long, "sched_getattr", -+ vki_pid_t, pid, struct sched_attr *, p, -+ unsigned int, size, unsigned int, flags); -+ /* We need to be able to read at least the size field. */ -+ PRE_MEM_READ( "sched_setattr(attr->size)", ARG2, sizeof(vki_uint32_t) ); -+ /* And the kernel needs to be able to write to the whole struct size. */ -+ attr = (struct vki_sched_attr *)(Addr)ARG2; -+ if (ML_(safe_to_deref)(attr,sizeof(vki_uint32_t))) -+ PRE_MEM_WRITE( "sched_setattr(attr)", (Addr)attr, attr->size); -+} -+POST(sys_sched_getattr) -+{ -+ struct vki_sched_attr *attr = (struct vki_sched_attr *)(Addr)ARG2; -+ POST_MEM_WRITE( (Addr)attr, attr->size ); -+} -+ - PRE(sys_sched_getscheduler) - { - PRINT("sys_sched_getscheduler ( %ld )", SARG1); -diff --git a/coregrind/m_syswrap/syswrap-ppc32-linux.c b/coregrind/m_syswrap/syswrap-ppc32-linux.c -index eed12a1bc..c19cb9e0e 100644 ---- a/coregrind/m_syswrap/syswrap-ppc32-linux.c -+++ b/coregrind/m_syswrap/syswrap-ppc32-linux.c -@@ -1016,6 +1016,9 @@ static SyscallTableEntry syscall_table[] = { - LINXY(__NR_process_vm_readv, sys_process_vm_readv), // 351 - LINX_(__NR_process_vm_writev, sys_process_vm_writev),// 352 - -+ LINX_(__NR_sched_setattr, sys_sched_setattr), // 355 -+ LINXY(__NR_sched_getattr, sys_sched_getattr), // 356 -+ - LINXY(__NR_getrandom, sys_getrandom), // 359 - LINXY(__NR_memfd_create, sys_memfd_create), // 360 - -diff --git a/coregrind/m_syswrap/syswrap-ppc64-linux.c b/coregrind/m_syswrap/syswrap-ppc64-linux.c -index d58200b49..b6422a765 100644 ---- a/coregrind/m_syswrap/syswrap-ppc64-linux.c -+++ b/coregrind/m_syswrap/syswrap-ppc64-linux.c -@@ -998,6 +998,8 @@ static SyscallTableEntry syscall_table[] = { - LINXY(__NR_process_vm_readv, sys_process_vm_readv), // 351 - LINX_(__NR_process_vm_writev, sys_process_vm_writev),// 352 - -+ LINX_(__NR_sched_setattr, sys_sched_setattr), // 355 -+ LINXY(__NR_sched_getattr, sys_sched_getattr), // 356 - LINX_(__NR_renameat2, sys_renameat2), // 357 - - LINXY(__NR_getrandom, sys_getrandom), // 359 -diff --git a/coregrind/m_syswrap/syswrap-s390x-linux.c b/coregrind/m_syswrap/syswrap-s390x-linux.c -index a0a330aa2..3427fee16 100644 ---- a/coregrind/m_syswrap/syswrap-s390x-linux.c -+++ b/coregrind/m_syswrap/syswrap-s390x-linux.c -@@ -825,8 +825,8 @@ static SyscallTableEntry syscall_table[] = { - LINX_(__NR_kcmp, sys_kcmp), // 343 - // ?????(__NR_finit_module, ), // 344 - --// ?????(__NR_sched_setattr, ), // 345 --// ?????(__NR_sched_getattr, ), // 346 -+ LINX_(__NR_sched_setattr, sys_sched_setattr), // 345 -+ LINXY(__NR_sched_getattr, sys_sched_getattr), // 346 - LINX_(__NR_renameat2, sys_renameat2), // 347 - // ?????(__NR_seccomp, ), // 348 - LINXY(__NR_getrandom, sys_getrandom), // 349 -diff --git a/coregrind/m_syswrap/syswrap-x86-linux.c b/coregrind/m_syswrap/syswrap-x86-linux.c -index 332ed0bf2..b59d96f37 100644 ---- a/coregrind/m_syswrap/syswrap-x86-linux.c -+++ b/coregrind/m_syswrap/syswrap-x86-linux.c -@@ -1580,8 +1580,8 @@ static SyscallTableEntry syscall_table[] = { - LINX_(__NR_kcmp, sys_kcmp), // 349 - - // LIN__(__NR_finit_module, sys_ni_syscall), // 350 --// LIN__(__NR_sched_setattr, sys_ni_syscall), // 351 --// LIN__(__NR_sched_getattr, sys_ni_syscall), // 352 -+ LINX_(__NR_sched_setattr, sys_sched_setattr), // 351 -+ LINXY(__NR_sched_getattr, sys_sched_getattr), // 352 - LINX_(__NR_renameat2, sys_renameat2), // 353 - // LIN__(__NR_seccomp, sys_ni_syscall), // 354 - -diff --git a/include/vki/vki-linux.h b/include/vki/vki-linux.h -index 75b583165..ef93b9258 100644 ---- a/include/vki/vki-linux.h -+++ b/include/vki/vki-linux.h -@@ -410,6 +410,23 @@ struct vki_sched_param { - int sched_priority; - }; - -+struct vki_sched_attr { -+ vki_uint32_t size; -+ vki_uint32_t sched_policy; -+ vki_uint64_t sched_flags; -+ -+ /* SCHED_NORMAL, SCHED_BATCH */ -+ vki_int32_t sched_nice; -+ -+ /* SCHED_FIFO, SCHED_RR */ -+ vki_uint32_t sched_priority; -+ -+ /* SCHED_DEADLINE */ -+ vki_uint64_t sched_runtime; -+ vki_uint64_t sched_deadline; -+ vki_uint64_t sched_period; -+}; -+ - #define VKI_TASK_COMM_LEN 16 - - //---------------------------------------------------------------------- diff --git a/valgrind-3.16.1-stxsibx-stxsihx.patch b/valgrind-3.16.1-stxsibx-stxsihx.patch deleted file mode 100644 index c94ad91..0000000 --- a/valgrind-3.16.1-stxsibx-stxsihx.patch +++ /dev/null @@ -1,63 +0,0 @@ -diff --git a/VEX/priv/guest_ppc_toIR.c b/VEX/priv/guest_ppc_toIR.c -index c9c058a7a..d726d63de 100644 ---- a/VEX/priv/guest_ppc_toIR.c -+++ b/VEX/priv/guest_ppc_toIR.c -@@ -25671,49 +25671,29 @@ dis_vx_store ( UInt prefix, UInt theInstr ) - - case 0x38D: // stxsibx - { -- IRExpr *stored_word; -- IRTemp byte_to_store = newTemp( Ity_I64 ); -+ IRTemp byte_to_store = newTemp( Ity_I8 ); - - DIP("stxsibx %u,r%u,r%u\n", (UInt)XS, rA_addr, rB_addr); - -- /* Can't store just a byte, need to fetch the word at EA merge data -- * and store. -- */ -- stored_word = load( Ity_I64, mkexpr( EA ) ); -- assign( byte_to_store, binop( Iop_And64, -+ assign( byte_to_store, unop( Iop_64to8, - unop( Iop_V128HIto64, -- mkexpr( vS ) ), -- mkU64( 0xFF ) ) ); -+ mkexpr( vS ) ) ) ); - -- store( mkexpr( EA ), binop( Iop_Or64, -- binop( Iop_And64, -- stored_word, -- mkU64( 0xFFFFFFFFFFFFFF00 ) ), -- mkexpr( byte_to_store ) ) ); -+ store( mkexpr( EA ), mkexpr( byte_to_store ) ); - break; - } - - case 0x3AD: // stxsihx - { -- IRExpr *stored_word; -- IRTemp byte_to_store = newTemp( Ity_I64 ); -+ IRTemp hword_to_store = newTemp( Ity_I16 ); - - DIP("stxsihx %u,r%u,r%u\n", (UInt)XS, rA_addr, rB_addr); - -- /* Can't store just a halfword, need to fetch the word at EA merge data -- * and store. -- */ -- stored_word = load( Ity_I64, mkexpr( EA ) ); -- assign( byte_to_store, binop( Iop_And64, -- unop( Iop_V128HIto64, -- mkexpr( vS ) ), -- mkU64( 0xFFFF ) ) ); -+ assign( hword_to_store, unop( Iop_64to16, -+ unop( Iop_V128HIto64, -+ mkexpr( vS ) ) ) ); - -- store( mkexpr( EA ), binop( Iop_Or64, -- binop( Iop_And64, -- stored_word, -- mkU64( 0xFFFFFFFFFFFF0000 ) ), -- mkexpr( byte_to_store ) ) ); -+ store( mkexpr( EA ), mkexpr( hword_to_store ) ); - break; - } - diff --git a/valgrind.spec b/valgrind.spec index b53b7ac..ae44977 100644 --- a/valgrind.spec +++ b/valgrind.spec @@ -2,8 +2,8 @@ Summary: Tool for finding memory management bugs in programs Name: %{?scl_prefix}valgrind -Version: 3.16.1 -Release: 20%{?dist} +Version: 3.17.0 +Release: 0.1.RC1%{?dist} Epoch: 1 License: GPLv2+ URL: http://www.valgrind.org/ @@ -71,7 +71,7 @@ URL: http://www.valgrind.org/ # So those will already have their full symbol table. %undefine _include_minidebuginfo -Source0: ftp://sourceware.org/pub/valgrind/valgrind-%{version}.tar.bz2 +Source0: ftp://sourceware.org/pub/valgrind/valgrind-%{version}.RC1.tar.bz2 # Needs investigation and pushing upstream Patch1: valgrind-3.9.0-cachegrind-improvements.patch @@ -82,81 +82,11 @@ Patch2: valgrind-3.9.0-helgrind-race-supp.patch # Make ld.so supressions slightly less specific. Patch3: valgrind-3.9.0-ldso-supp.patch -# We want all executables and libraries in libexec instead of lib -# so they are only available for valgrind usage itself and so the -# same directory is used independent of arch. -Patch4: valgrind-3.16.0-pkglibexecdir.patch - # Add some stack-protector -Patch5: valgrind-3.16.0-some-stack-protector.patch +Patch4: valgrind-3.16.0-some-stack-protector.patch # Add some -Wl,z,now. -Patch6: valgrind-3.16.0-some-Wl-z-now.patch - -# KDE#422174 unhandled instruction bytes: 0x48 0xE9 (REX prefix JMP instr) -Patch7: valgrind-3.16.1-REX-prefix-JMP.patch - -# KDE#422623 epoll_ctl warns for uninit padding on non-amd64 64bit arches -Patch8: valgrind-3.16.1-epoll.patch - -# KDE#369029 handle linux syscalls sched_getattr and sched_setattr -Patch9: valgrind-3.16.1-sched_getsetattr.patch - -# KDE#415293 Incorrect call-graph tracking due to new _dl_runtime_resolve* -Patch10: valgrind-3.16.1-dl_runtime_resolve.patch - -# KDE#427787 Support new faccessat2 linux syscall (439) -Patch11: valgrind-3.16.1-faccessat2.patch - -# KDE#427931 gdbserver_tests/nlcontrolc.vgtest hangs on fedora rawhide -Patch12: valgrind-3.16.1-gdbserver_nlcontrolc.patch - -# KDE#427870 lmw, lswi and related PowerPC insns aren't allowed on ppc64le -Patch13: valgrind-3.16.1-PPC64BE-lsw.patch - -# KDE#428909 helgrind: need to intercept duplicate libc definitions -Patch14: valgrind-3.16.1-pthread-intercept.patch - -# KDE#428648 s390_emit_load_mem panics due to 20-bit offset for vector load -Patch15: valgrind-3.16.1-s390_emit_load_mem.patch - -# KDE#133812 s390x: z14 vector instructions not implemented -Patch16: valgrind-3.16.1-s390x-z14-vector.patch - -# KDE#430354 ppc stxsibx and stxsihx instructions write too much data -Patch17: valgrind-3.16.1-stxsibx-stxsihx.patch - -# KDE#426014 arm64: implement fmadd and fmsub as Iop_MAdd/Sub -# KDE#430485 expr_is_guardable doesn't handle Iex_Qop -Patch18: valgrind-3.16.1-arm64-fma.patch - -# KDE#397605 Add support for Linux FICLONE ioctl -Patch19: valgrind-3.16.1-ficlone.patch - -# rhbz#1909415 valgrind makes false complaint about strcmp() on aarch64 -# upstream git commit 359b98828 -Patch20: valgrind-3.16.1-arm64-expensive-cmp.patch - -# KDE#431157 PPC_FEATURE2_SCV needs to be masked in AT_HWCAP2 -Patch21: valgrind-3.16.1-ppc64-scv-hwcap.patch - -# KDE#432102 Support DWARF5 -Patch22: valgrind-3.16.1-dwarf5.patch - -# KDE#410743 shmat() calls for 32-bit programs fail when running in 64-bit -# RHBZ#1909548 shmctl(IPC_STAT) doesn't set shm_nattch on aarch64 -Patch23: valgrind-3.16.0-shmctl.patch - -# KDE#140178 open("/proc/self/exe", ...); doesn't quite work -# RHBZ#1925786 valgrind appears to only interject readlink on /proc/self/exe -Patch24: valgrind-3.16.1-open-proc-self-exe.patch - -# RHBZ#1927153 -flto makes valgrind report non-existing paths to source files -Patch25: valgrind-3.16.1-readdwarf-line.patch - -# RHBZ#433898 netresolve: FTBFS in Fedora rawhide/f34 because arm64 valgrind -# KDE#433898 arm64: Handle sp, lr, fp as DwReg in CfiExpr -Patch26: valgrind-3.16.1-arm64_sp_lr_fp_DwReg.patch +Patch5: valgrind-3.16.0-some-Wl-z-now.patch BuildRequires: make BuildRequires: glibc-devel @@ -191,6 +121,11 @@ BuildRequires: docbook-dtds # configure might use which BuildRequires: which +# For testing the debuginfod +%if 0%{?fedora} > 29 || 0%{?rhel} > 7 +BuildRequires: elfutils-debuginfod +%endif + %{?scl:Requires:%scl_runtime} # We need to fixup selinux file context when doing a scl build. @@ -280,40 +215,18 @@ Valgrind User Manual for details. %endif %prep -%setup -q -n %{?scl:%{pkg_name}}%{!?scl:%{name}}-%{version} +%setup -q -n %{?scl:%{pkg_name}}%{!?scl:%{name}}-%{version}.RC1 %patch1 -p1 %patch2 -p1 %patch3 -p1 -%patch4 -p1 # Old rhel gcc doesn't have -fstack-protector-strong. %if 0%{?fedora} || 0%{?rhel} >= 7 +%patch4 -p1 %patch5 -p1 -%patch6 -p1 %endif -%patch7 -p1 -%patch8 -p1 -%patch9 -p1 -%patch10 -p1 -%patch11 -p1 -%patch12 -p1 -%patch13 -p1 -%patch14 -p1 -%patch15 -p1 -%patch16 -p1 -%patch17 -p1 -%patch18 -p1 -%patch19 -p1 -%patch20 -p1 -%patch21 -p1 -%patch22 -p1 -%patch23 -p1 -%patch24 -p1 -%patch25 -p1 -%patch26 -p1 - %build # LTO triggers undefined symbols in valgrind. Valgrind has a --enable-lto # configure time option, but that doesn't seem to help. @@ -505,6 +418,7 @@ echo ===============END TESTING=============== %{_includedir}/valgrind/drd.h %{_includedir}/valgrind/helgrind.h %{_includedir}/valgrind/memcheck.h +%{_includedir}/valgrind/dhat.h %{_libdir}/pkgconfig/valgrind.pc %if %{build_tools_devel} @@ -537,6 +451,10 @@ fi %endif %changelog +* Mon Mar 15 2021 Mark Wielaard - 3.17.0-0.1.RC1 +- Update to upstream 3.17.0-RC1 +- Drop all upstreamed patches + * Wed Mar 3 2021 Mark Wielaard - 3.16.1-20 - Add valgrind-3.16.1-arm64_sp_lr_fp_DwReg.patch