From: Andreas Arnez Date: Mon, 22 May 2023 16:57:35 +0000 (+0200) Subject: Bug 470132 - s390x: Fix the wrap-around case in VGM X-Git-Tag: VALGRIND_3_22_0~137 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6635fc58345ba2c36589f0bef4d326166e947023;p=thirdparty%2Fvalgrind.git Bug 470132 - s390x: Fix the wrap-around case in VGM Valgrind's implementation of VGM is incomplete: * It doesn't support generating a wrap-around bit mask. Such a mask should result when the ending bit position is smaller than the starting bit position. Valgrind runs into an assertion failure instead. * It doesn't ignore unused bits in the I2 and I3 fields of the instruction, as it should. Fix this by re-implementing the main logic in s390_irgen_VGM(). --- diff --git a/NEWS b/NEWS index a4e7533115..783612fbb9 100644 --- a/NEWS +++ b/NEWS @@ -38,6 +38,7 @@ are not entered into bugzilla tend to get forgotten about or ignored. 469146 massif --ignore-fn does not ignore inlined functions 469768 Make it possible to install gdb scripts in a different location 470121 Can't run callgrind_control with valgrind 3.21.0 because of perl errors +470132 s390x: Assertion failure on VGM instruction 470520 Multiple realloc zero errors crash in MC_(eq_Error) 470713 Failure on the Yosys project: valgrind: m_libcfile.c:1802 (Bool vgPlain_realpath(const HChar *, HChar *)): diff --git a/VEX/priv/guest_s390_toIR.c b/VEX/priv/guest_s390_toIR.c index 11dda41ef5..d9d746c38a 100644 --- a/VEX/priv/guest_s390_toIR.c +++ b/VEX/priv/guest_s390_toIR.c @@ -16388,50 +16388,37 @@ s390_irgen_VGBM(UChar v1, UShort i2, UChar m3 __attribute__((unused))) static const HChar * s390_irgen_VGM(UChar v1, UShort i2, UChar m3) { - UChar from = (i2 & 0xff00) >> 8; - UChar to = (i2 & 0x00ff); - ULong value = 0UL; - IRType type = s390_vr_get_type(m3); - vassert(from <= to); - - UChar maxIndex = 0; - switch (type) { - case Ity_I8: - maxIndex = 7; - break; - case Ity_I16: - maxIndex = 15; - break; - case Ity_I32: - maxIndex = 31; - break; - case Ity_I64: - maxIndex = 63; - break; - default: - vpanic("s390_irgen_VGM: unknown type"); - } - - for(UChar index = from; index <= to; index++) { - value |= (1ULL << (maxIndex - index)); - } - - IRExpr *fillValue; - switch (type) { - case Ity_I8: + s390_insn_assert("vgm", m3 <= 3); + + UChar max_idx = (8 << m3) - 1; + UChar from = max_idx & (i2 >> 8); + UChar to = max_idx & i2; + ULong all_one = (1ULL << max_idx << 1) - 1; + ULong value = (all_one >> from) ^ (all_one >> to >> 1); + + /* In case of wrap-around we now have a value that needs inverting: + to from + V V + 00000111111111110000000000000000 */ + if (to < from) + value ^= all_one; + + IRExpr* fillValue; + switch (m3) { + case 0: fillValue = mkU8(value); break; - case Ity_I16: + case 1: fillValue = mkU16(value); break; - case Ity_I32: + case 2: fillValue = mkU32(value); break; - case Ity_I64: + case 3: fillValue = mkU64(value); break; default: - vpanic("s390_irgen_VGM: unknown type"); + vpanic("s390_irgen_VGM: unknown element size"); } s390_vr_fill(v1, fillValue);