From: Andreas Arnez Date: Thu, 10 Apr 2025 15:27:30 +0000 (+0200) Subject: s390x: Implement VTM without dirty helper X-Git-Tag: VALGRIND_3_25_0~50 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6efb1ef86b1ec547ac4dddecc529dbbfeae409cf;p=thirdparty%2Fvalgrind.git s390x: Implement VTM without dirty helper The VTM instruction is currently translated to a dirty helper call, which comes with the usual drawbacks. Replace its implementation and remove the dirty helper. --- diff --git a/VEX/priv/guest_s390_defs.h b/VEX/priv/guest_s390_defs.h index 0ec242a99..29efa0131 100644 --- a/VEX/priv/guest_s390_defs.h +++ b/VEX/priv/guest_s390_defs.h @@ -268,7 +268,6 @@ typedef enum { S390_VEC_OP_VPKS, S390_VEC_OP_VPKLS, S390_VEC_OP_VCEQ, - S390_VEC_OP_VTM, S390_VEC_OP_VGFM, S390_VEC_OP_VGFMA, S390_VEC_OP_VMAH, diff --git a/VEX/priv/guest_s390_helpers.c b/VEX/priv/guest_s390_helpers.c index b99d71a5a..6e0321fea 100644 --- a/VEX/priv/guest_s390_helpers.c +++ b/VEX/priv/guest_s390_helpers.c @@ -2453,7 +2453,6 @@ s390x_dirtyhelper_vec_op(VexGuestS390XState *guest_state, [S390_VEC_OP_VPKS] = {0xe7, 0x97}, [S390_VEC_OP_VPKLS] = {0xe7, 0x95}, [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}, @@ -2538,12 +2537,6 @@ s390x_dirtyhelper_vec_op(VexGuestS390XState *guest_state, the_insn.VRR.op2 = opcodes[d->op][1]; switch(d->op) { - case S390_VEC_OP_VTM: - the_insn.VRR.v1 = 2; - the_insn.VRR.v2 = 3; - the_insn.VRR.rxb = 0b1100; - break; - case S390_VEC_OP_VPKS: case S390_VEC_OP_VPKLS: case S390_VEC_OP_VCEQ: diff --git a/VEX/priv/guest_s390_toIR.c b/VEX/priv/guest_s390_toIR.c index f2ef19376..63dc360b0 100644 --- a/VEX/priv/guest_s390_toIR.c +++ b/VEX/priv/guest_s390_toIR.c @@ -19087,32 +19087,29 @@ s390_irgen_VSUMQ(UChar v1, UChar v2, UChar v3, UChar m4) static const HChar * s390_irgen_VTM(UChar v1, UChar v2) { - IRDirty* d; - IRTemp cc = newTemp(Ity_I64); - - s390x_vec_op_details_t details = { .serialized = 0ULL }; - details.op = S390_VEC_OP_VTM; - details.v2 = v1; - details.v3 = v2; - details.read_only = 1; - - d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_vec_op", - &s390x_dirtyhelper_vec_op, - mkIRExprVec_2(IRExpr_GSPTR(), - mkU64(details.serialized))); - - 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) + v1 * sizeof(V128); - d->fxState[0].size = sizeof(V128); - d->fxState[1].fx = Ifx_Read; - d->fxState[1].offset = S390X_GUEST_OFFSET(guest_v0) + v2 * sizeof(V128); - d->fxState[1].size = sizeof(V128); + IRTemp op1 = newTemp(Ity_V128); + IRTemp op2 = newTemp(Ity_V128); + IRTemp masked = newTemp(Ity_V128); + IRTemp diff = newTemp(Ity_V128); + IRTemp cc = newTemp(Ity_I64); + IRExpr* masked_is_zero; + IRExpr* diff_is_zero; - stmt(IRStmt_Dirty(d)); + assign(op1, get_vr_qw(v1)); + assign(op2, get_vr_qw(v2)); + assign(masked, binop(Iop_AndV128, mkexpr(op1), mkexpr(op2))); + assign(diff, binop(Iop_XorV128, mkexpr(op2), mkexpr(masked))); + masked_is_zero = binop(Iop_CmpEQ64, + binop(Iop_Or64, unop(Iop_V128to64, mkexpr(masked)), + unop(Iop_V128HIto64, mkexpr(masked))), + mkU64(0)); + diff_is_zero = binop(Iop_CmpEQ64, + binop(Iop_Or64, unop(Iop_V128to64, mkexpr(diff)), + unop(Iop_V128HIto64, mkexpr(diff))), + mkU64(0)); + assign(cc, mkite(masked_is_zero, mkU64(0), + mkite(diff_is_zero, mkU64(3), mkU64(1)))); s390_cc_set(cc); - return "vtm"; }