]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
s390x: Implement VTM without dirty helper
authorAndreas Arnez <arnez@linux.ibm.com>
Thu, 10 Apr 2025 15:27:30 +0000 (17:27 +0200)
committerAndreas Arnez <arnez@linux.ibm.com>
Fri, 11 Apr 2025 14:51:09 +0000 (16:51 +0200)
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.

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

index 0ec242a99b44156591a63c0ce33cb6f0992c89b7..29efa01311fd190c613dfc46082f3ee474e5dded 100644 (file)
@@ -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,
index b99d71a5af20aea95a6b4c8f69af8d6b1c202519..6e0321feaab5c7d9bba1426864d822c662343b53 100644 (file)
@@ -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:
index f2ef1937657681567c029c9df98447642f5e1a58..63dc360b0f0e8a26b09eece1a25e65e261ab569f 100644 (file)
@@ -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";
 }