]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Bug 434296 - s390x: Rework IR conversion of VISTR
authorAndreas Arnez <arnez@linux.ibm.com>
Tue, 27 Apr 2021 18:13:26 +0000 (20:13 +0200)
committerAndreas Arnez <arnez@linux.ibm.com>
Wed, 5 May 2021 15:32:21 +0000 (17:32 +0200)
The z/Architecture instruction VISTR is currently transformed to a dirty
helper that executes the instruction.  This can cause false positives with
memcheck if the input string contains undefined characters after the
string terminator.  Implement without a dirty helper and emulate the
instruction instead.

VEX/priv/guest_s390_defs.h
VEX/priv/guest_s390_helpers.c
VEX/priv/guest_s390_toIR.c

index caec3108e48e44a250642f266bd33488ce690dc2..24f3798c1ac03ff9d0e3556bf476ebfb5d71b4d6 100644 (file)
@@ -265,7 +265,6 @@ typedef enum {
    S390_VEC_OP_INVALID = 0,
    S390_VEC_OP_VPKS,
    S390_VEC_OP_VPKLS,
-   S390_VEC_OP_VISTR,
    S390_VEC_OP_VCEQ,
    S390_VEC_OP_VTM,
    S390_VEC_OP_VGFM,
index 2188ce5c10c639b2dea322b1388cce69204e41d9..1e04f601a88cae1af5027c2afb698e27142a1291 100644 (file)
@@ -2538,7 +2538,6 @@ s390x_dirtyhelper_vec_op(VexGuestS390XState *guest_state,
       {0x00, 0x00}, /* invalid */
       [S390_VEC_OP_VPKS]  = {0xe7, 0x97},
       [S390_VEC_OP_VPKLS] = {0xe7, 0x95},
-      [S390_VEC_OP_VISTR] = {0xe7, 0x5c},
       [S390_VEC_OP_VCEQ]  = {0xe7, 0xf8},
       [S390_VEC_OP_VTM]   = {0xe7, 0xd8},
       [S390_VEC_OP_VGFM]  = {0xe7, 0xb4},
@@ -2610,14 +2609,6 @@ s390x_dirtyhelper_vec_op(VexGuestS390XState *guest_state,
    the_insn.VRR.op2 = opcodes[d->op][1];
 
    switch(d->op) {
-   case S390_VEC_OP_VISTR:
-      the_insn.VRR.v1 = 1;
-      the_insn.VRR.v2 = 2;
-      the_insn.VRR.rxb = 0b1100;
-      the_insn.VRR.m4 = d->m4;
-      the_insn.VRR.m5 = d->m5;
-      break;
-
    case S390_VEC_OP_VTM:
       the_insn.VRR.v1 = 2;
       the_insn.VRR.v2 = 3;
index c8dc3ec18337edcf1378bb25c459dcdaea2120cb..dfea542591105ffef7e8d80d39cdcf6b0f7a667e 100644 (file)
@@ -17447,40 +17447,34 @@ s390_irgen_VFENE(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5)
 static const HChar *
 s390_irgen_VISTR(UChar v1, UChar v2, UChar m3, UChar m5)
 {
-   IRDirty* d;
-   IRTemp cc = newTemp(Ity_I64);
-
-   /* Check for specification exception */
-   vassert(m3 < 3);
-   vassert((m5 & 0b1110) == 0);
+   s390_insn_assert("vistr", m3 < 3 && m5 == (m5 & 1));
 
-   s390x_vec_op_details_t details = { .serialized = 0ULL };
-   details.op = S390_VEC_OP_VISTR;
-   details.v1 = v1;
-   details.v2 = v2;
-   details.m4 = m3;
-   details.m5 = m5;
-
-   d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op",
-                         &s390x_dirtyhelper_vec_op,
-                         mkIRExprVec_2(IRExpr_GSPTR(),
-                                       mkU64(details.serialized)));
+   static const IROp compare_op[3] = {
+      Iop_CmpEQ8x16, Iop_CmpEQ16x8, Iop_CmpEQ32x4
+   };
+   IRExpr* t;
+   IRTemp op2 = newTemp(Ity_V128);
+   IRTemp op2term = newTemp(Ity_V128);
+   IRTemp mask = newTemp(Ity_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   = sizeof(V128);
-   d->fxState[1].fx     = Ifx_Write;
-   d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v1 * sizeof(V128);
-   d->fxState[1].size   = sizeof(V128);
+   assign(op2, get_vr_qw(v2));
+   assign(op2term, binop(compare_op[m3], mkexpr(op2), mkV128(0)));
+   t = mkexpr(op2term);
 
-   stmt(IRStmt_Dirty(d));
+   for (UChar i = m3; i < 4; i++) {
+      IRTemp s = newTemp(Ity_V128);
+      assign(s, binop(Iop_OrV128, t, binop(Iop_ShrV128, t, mkU8(8 << i))));
+      t = mkexpr(s);
+   }
+   assign(mask, unop(Iop_NotV128, t));
+   put_vr_qw(v1, binop(Iop_AndV128, mkexpr(op2), mkexpr(mask)));
 
    if (s390_vr_is_cs_set(m5)) {
+      IRTemp cc = newTemp(Ity_I64);
+      assign(cc, binop(Iop_And64, mkU64(3), unop(Iop_V128to64, mkexpr(mask))));
       s390_cc_set(cc);
    }
-
+   dis_res->hint = Dis_HintVerbose;
    return "vistr";
 }