From bcb1aa8e648e55abc18d30864b109c662d522134 Mon Sep 17 00:00:00 2001 From: Andreas Arnez Date: Fri, 29 Sep 2023 16:11:31 +0200 Subject: [PATCH] s390x: Make z16 machine model known to Valgrind The z16 machine model hasn't been fully introduced to Valgrind yet. Add the missing support: * Add z16 to the list of machine models in each of `libvex.h', `tests/s390x_features.c', and `s390-check-opcodes.pl'. * Starting with z16, the "store facility list extended" (STFLE) instruction can write four instead of three words. Reflect this in the STFLE-helper and in the `stfle' test case. * Pass the new STFLE-bits unchanged, except for the vector-packed-decimal facility, which is unsupported by Valgrind. --- VEX/priv/guest_s390_helpers.c | 36 ++++++++++++++++----------- VEX/pub/libvex.h | 3 ++- VEX/pub/libvex_s390x_common.h | 2 +- auxprogs/s390-check-opcodes.pl | 2 +- coregrind/m_machine.c | 9 ++++--- none/tests/s390x/Makefile.am | 1 + none/tests/s390x/stfle.c | 2 +- none/tests/s390x/stfle.stdout.exp-z16 | 10 ++++++++ tests/s390x_features.c | 2 ++ 9 files changed, 45 insertions(+), 22 deletions(-) create mode 100644 none/tests/s390x/stfle.stdout.exp-z16 diff --git a/VEX/priv/guest_s390_helpers.c b/VEX/priv/guest_s390_helpers.c index 95bb653274..df565ffa7f 100644 --- a/VEX/priv/guest_s390_helpers.c +++ b/VEX/priv/guest_s390_helpers.c @@ -324,8 +324,9 @@ s390_stfle_range(UInt lo, UInt hi) ULong 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] */ + ULong hoststfle[S390_NUM_FACILITY_DW], cc, last_dw, i; + register ULong reg0 asm("0") = guest_state->guest_r0; + last_dw = reg0 & 0xf; /* 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 @@ -393,26 +394,31 @@ s390x_dirtyhelper_STFLE(VexGuestS390XState *guest_state, ULong *addr) /* 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) - reg0 = S390_NUM_FACILITY_DW - 1; - num_dw = reg0 + 1; /* number of double words written */ + /* === 192 .. 255 === */ + /* 192: vector-packed-decimal, not supported */ + (s390_stfle_range(193, 194) + /* 195: unassigned */ + | s390_stfle_range(196, 197)), + }; - asm volatile(" .insn s,0xb2b00000,%0\n" /* stfle */ - "ipm %2\n" - "srl %2,28\n" - : "=m" (hoststfle), "+d"(reg0), "=d"(cc) : : "cc", "memory"); + asm(".insn s,0xb2b00000,%0\n" /* stfle */ + "ipm %2\n" + "srl %2,28\n" + : "=Q"(hoststfle), "+d"(reg0), "=d"(cc) + : + : "cc"); /* Update guest register 0 with what STFLE set r0 to */ guest_state->guest_r0 = reg0; /* VM facilities = host facilities, filtered by acceptance */ - for (i = 0; i < num_dw; ++i) - addr[i] = hoststfle[i] & accepted_facility[i]; + for (i = 0; i <= last_dw; ++i) { + if (i < S390_NUM_FACILITY_DW) + addr[i] = hoststfle[i] & accepted_facility[i]; + else + addr[i] = 0; /* mask out any excess doublewords */ + } return cc; } diff --git a/VEX/pub/libvex.h b/VEX/pub/libvex.h index ec50d52ca9..27bb6e0f46 100644 --- a/VEX/pub/libvex.h +++ b/VEX/pub/libvex.h @@ -154,7 +154,8 @@ typedef #define VEX_S390X_MODEL_Z14 14 #define VEX_S390X_MODEL_Z14_ZR1 15 #define VEX_S390X_MODEL_Z15 16 -#define VEX_S390X_MODEL_UNKNOWN 17 /* always last in list */ +#define VEX_S390X_MODEL_Z16 17 +#define VEX_S390X_MODEL_UNKNOWN 18 /* always last in list */ #define VEX_S390X_MODEL_MASK 0x3F #define VEX_HWCAPS_S390X_LDISP (1<<6) /* Long-displacement facility */ diff --git a/VEX/pub/libvex_s390x_common.h b/VEX/pub/libvex_s390x_common.h index 289421677a..0fbe4145a9 100644 --- a/VEX/pub/libvex_s390x_common.h +++ b/VEX/pub/libvex_s390x_common.h @@ -116,7 +116,7 @@ #define S390_NUM_GPRPARMS 5 /* Number of double words needed to store all facility bits. */ -#define S390_NUM_FACILITY_DW 3 +#define S390_NUM_FACILITY_DW 4 #endif /* __LIBVEX_PUB_S390X_H */ diff --git a/auxprogs/s390-check-opcodes.pl b/auxprogs/s390-check-opcodes.pl index 515ff9a71a..3abb0c8fbb 100755 --- a/auxprogs/s390-check-opcodes.pl +++ b/auxprogs/s390-check-opcodes.pl @@ -28,7 +28,7 @@ my %csv_implemented = (); my %toir_implemented = (); my %toir_decoded = (); my %known_arch = map {($_ => 1)} - qw(g5 z900 z990 z9-109 z9-ec z10 z196 zEC12 z13 arch12 arch13); + qw(g5 z900 z990 z9-109 z9-ec z10 z196 zEC12 z13 arch12 arch13 arch14); # Patterns for identifying certain extended mnemonics that shall be # skipped in "s390-opc.txt" and "s390-opcodes.csv". diff --git a/coregrind/m_machine.c b/coregrind/m_machine.c index 661a3f1074..a4c2218bfb 100644 --- a/coregrind/m_machine.c +++ b/coregrind/m_machine.c @@ -584,6 +584,8 @@ static UInt VG_(get_machine_model)(void) { "3907", VEX_S390X_MODEL_Z14_ZR1 }, { "8561", VEX_S390X_MODEL_Z15 }, { "8562", VEX_S390X_MODEL_Z15 }, + { "3931", VEX_S390X_MODEL_Z16 }, + { "3932", VEX_S390X_MODEL_Z16 }, }; Int model, n, fh; @@ -1541,9 +1543,10 @@ Bool VG_(machine_get_hwcaps)( void ) } else { register ULong reg0 asm("0") = S390_NUM_FACILITY_DW - 1; - __asm__ __volatile__(" .insn s,0xb2b00000,%0\n" /* stfle */ - : "=m" (hoststfle), "+d"(reg0) - : : "cc", "memory"); + __asm__(".insn s,0xb2b00000,%0" /* stfle */ + : "=Q"(hoststfle), "+d"(reg0) + : + : "cc"); } /* Restore signals */ diff --git a/none/tests/s390x/Makefile.am b/none/tests/s390x/Makefile.am index 8bbbbd1e27..88ee52e7a1 100644 --- a/none/tests/s390x/Makefile.am +++ b/none/tests/s390x/Makefile.am @@ -51,6 +51,7 @@ EXTRA_DIST = \ dfpext.stderr.exp dfpext.stdout.exp dfpext.vgtest \ dfpconv.stderr.exp dfpconv.stdout.exp dfpconv.vgtest \ srnmt.stderr.exp srnmt.stdout.exp srnmt.vgtest \ + stfle.stdout.exp-z16 \ pfpo.stderr.exp pfpo.stdout.exp pfpo.vgtest AM_CFLAGS += @FLAG_M64@ diff --git a/none/tests/s390x/stfle.c b/none/tests/s390x/stfle.c index 19f2c61f71..22ddf86635 100644 --- a/none/tests/s390x/stfle.c +++ b/none/tests/s390x/stfle.c @@ -1,7 +1,7 @@ #include /* Number of double words needed to store all facility bits. */ -#define S390_NUM_FACILITY_DW 3 +#define S390_NUM_FACILITY_DW 4 unsigned long long stfle(unsigned long dw, unsigned bit_to_test) diff --git a/none/tests/s390x/stfle.stdout.exp-z16 b/none/tests/s390x/stfle.stdout.exp-z16 new file mode 100644 index 0000000000..b857fae3d7 --- /dev/null +++ b/none/tests/s390x/stfle.stdout.exp-z16 @@ -0,0 +1,10 @@ +the value of cc is 0 and #double words is 4 +the value of cc is 0 and #double words is 4 +The z/Architecture architectural mode is installed and active +the value of cc is 0 and #double words is 4 +STFLE facility is installed +the value of cc is 3 and #double words is 4 +the value of cc is 3 and #double words is 4 +The z/Architecture architectural mode is installed and active +the value of cc is 3 and #double words is 4 +No MSA facility available diff --git a/tests/s390x_features.c b/tests/s390x_features.c index 6a45199c9d..507f3ab2f8 100644 --- a/tests/s390x_features.c +++ b/tests/s390x_features.c @@ -118,6 +118,8 @@ model_info models[] = { { "3907", "z14 ZR1"}, { "8561", "z15" }, { "8562", "z15" }, + { "3931", "z16" }, + { "3932", "z16" }, }; -- 2.43.5