]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
s390x: Exploit LOCGHI for converting from CC to Int1
authorAndreas Arnez <arnez@linux.ibm.com>
Wed, 5 Feb 2020 18:28:53 +0000 (19:28 +0100)
committerAndreas Arnez <arnez@linux.ibm.com>
Tue, 25 Feb 2020 15:45:34 +0000 (16:45 +0100)
Whenever converting a condition code to a Boolean value, the current
implementation in s390_insn_cc2bool_emit() generates six instructions
including "insert program mask" (IPM).  On systems with the
load/store-on-condition facility 2, this can be done in two instructions
instead, using "load halfword immediate on condition" (LOCGHI).

Add the new hardware capability VEX_HWCAPS_S390X_LSC2 and the respective
macro s390_host_has_lsc2.  In s390_insn_cc2bool_emit(), check for the
facility and exploit it if available.

A conditional move from an immediate value can be slightly improved with
LOCGHI as well, so do that in s390_insn_cond_move_emit() if possible.

VEX/priv/host_s390_defs.c
VEX/priv/host_s390_defs.h
VEX/priv/main_main.c
VEX/pub/libvex.h
coregrind/m_machine.c

index 47928cbe1c9d56a4a35463e8cea2e27ccbd8a66a..43b89c9253414f52d9cc326652ac322a662136b2 100644 (file)
@@ -1413,6 +1413,19 @@ emit_RIL(UChar *p, ULong op, UChar r1, UInt i2)
 }
 
 
+static UChar *
+emit_RIE(UChar *p, ULong op, UChar r1, UShort i2, UChar m3)
+{
+   ULong the_insn = op;
+
+   the_insn |= ((ULong)r1) << 36;
+   the_insn |= ((ULong)m3) << 32;
+   the_insn |= ((ULong)i2) << 16;
+
+   return emit_6bytes(p, the_insn);
+}
+
+
 static UChar *
 emit_RR(UChar *p, UInt op, UChar r1, UChar r2)
 {
@@ -5131,6 +5144,15 @@ s390_emit_LOCG(UChar *p, UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2)
    return emit_RSY(p, 0xeb00000000e2ULL, r1, m3, b2, dl2, dh2);
 }
 
+static UChar *
+s390_emit_LOCGHI(UChar *p, UChar r1, UShort i2, UChar m3)
+{
+   if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
+      s390_disasm(ENC4(MNM, GPR, INT, UINT), "locghi", r1, (Int)(Short)i2, m3);
+
+   return emit_RIE(p, 0xec0000000046ULL, r1, i2, m3);
+}
+
 
 /* Provide a symbolic name for register "R0" */
 #define R0 0
@@ -9354,6 +9376,15 @@ s390_insn_cc2bool_emit(UChar *buf, const s390_insn *insn)
    if (cond == S390_CC_ALWAYS)
       return s390_emit_LGHI(buf, r1, 1);  /* r1 = 1 */
 
+   /* If LOCGHI is available, use it. */
+   if (s390_host_has_lsc2) {
+      /* Clear r1, then load immediate 1 on condition. */
+      buf = s390_emit_LGHI(buf, r1, 0);
+      if (cond != S390_CC_NEVER)
+         buf = s390_emit_LOCGHI(buf, r1, 1, cond);
+      return buf;
+   }
+
    buf = s390_emit_load_cc(buf, r1);                 /* r1 = cc */
    buf = s390_emit_LGHI(buf, R0, cond);              /* r0 = mask */
    buf = s390_emit_SLLG(buf, r1, R0, r1, DISP20(0)); /* r1 = mask << cc */
@@ -10069,6 +10100,11 @@ s390_insn_cond_move_emit(UChar *buf, const s390_insn *insn)
       case S390_OPND_IMMEDIATE: {
          ULong value = src.variant.imm;
 
+         /* If LOCGHI is available, use it. */
+         if (s390_host_has_lsc2 && ulong_fits_signed_16bit(value)) {
+            return s390_emit_LOCGHI(p, hregNumber(dst), value, cond);
+         }
+
          /* Load value into R0, then use LOCGR */
          if (insn->size <= 4) {
             p = s390_emit_load_32imm(p, R0, value);
index e79b990e479184fc77db8ba39006ff331129bbaa..bbafa4fb08bf423358f1a67c53333c6b7a078bdf 100644 (file)
@@ -926,6 +926,8 @@ extern UInt s390_host_hwcaps;
                       (s390_host_hwcaps & (VEX_HWCAPS_S390X_VX))
 #define s390_host_has_msa5 \
                       (s390_host_hwcaps & (VEX_HWCAPS_S390X_MSA5))
+#define s390_host_has_lsc2 \
+                      (s390_host_hwcaps & (VEX_HWCAPS_S390X_LSC2))
 #endif /* ndef __VEX_HOST_S390_DEFS_H */
 
 /*---------------------------------------------------------------*/
index 5acab9ebafbf71c7995127ea404bf4d9cab2a279..82155305c7d6497fe06805e4610c24698bfd8288 100644 (file)
@@ -1791,6 +1791,7 @@ static const HChar* show_hwcaps_s390x ( UInt hwcaps )
       { VEX_HWCAPS_S390X_VX,    "vx" },
       { VEX_HWCAPS_S390X_MSA5,  "msa5" },
       { VEX_HWCAPS_S390X_MI2,   "mi2" },
+      { VEX_HWCAPS_S390X_LSC2,  "lsc2" },
    };
    /* Allocate a large enough buffer */
    static HChar buf[sizeof prefix + 
index 5d3733db0b8dbd8bbe3f5f82d017b3a6a4ae2a3c..359d10809cbcbdd229c8611c56ef15d049f4f953 100644 (file)
@@ -165,6 +165,7 @@ typedef
 #define VEX_HWCAPS_S390X_VX    (1<<18)  /* Vector facility */
 #define VEX_HWCAPS_S390X_MSA5  (1<<19)  /* message security assistance facility */
 #define VEX_HWCAPS_S390X_MI2   (1<<20)  /* miscellaneous-instruction-extensions facility 2 */
+#define VEX_HWCAPS_S390X_LSC2  (1<<21)  /* Conditional load/store facility2 */
 
 
 /* Special value representing all available s390x hwcaps */
@@ -182,7 +183,8 @@ typedef
                                 VEX_HWCAPS_S390X_PFPO  | \
                                 VEX_HWCAPS_S390X_VX    | \
                                 VEX_HWCAPS_S390X_MSA5  | \
-                                VEX_HWCAPS_S390X_MI2)
+                                VEX_HWCAPS_S390X_MI2   | \
+                                VEX_HWCAPS_S390X_LSC2)
 
 #define VEX_HWCAPS_S390X(x)  ((x) & ~VEX_S390X_MODEL_MASK)
 #define VEX_S390X_MODEL(x)   ((x) &  VEX_S390X_MODEL_MASK)
index 32c242a8ea51e6d421aad60a3fe990685cda517f..672a02124a70bdd78e9335b2a268f230e0407c6e 100644 (file)
@@ -1537,6 +1537,7 @@ Bool VG_(machine_get_hwcaps)( void )
         { False, S390_FAC_VX,    VEX_HWCAPS_S390X_VX,    "VX"    },
         { False, S390_FAC_MSA5,  VEX_HWCAPS_S390X_MSA5,  "MSA5"  },
         { False, S390_FAC_MI2,   VEX_HWCAPS_S390X_MI2,   "MI2"   },
+        { False, S390_FAC_LSC2,  VEX_HWCAPS_S390X_LSC2,  "LSC2"  },
      };
 
      /* Set hwcaps according to the detected facilities */