From: Andreas Arnez Date: Wed, 5 Feb 2020 18:28:53 +0000 (+0100) Subject: s390x: Exploit LOCGHI for converting from CC to Int1 X-Git-Tag: VALGRIND_3_16_0~94 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=75878add525a00d14be360c3bb1bc9e27596d43a;p=thirdparty%2Fvalgrind.git s390x: Exploit LOCGHI for converting from CC to Int1 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. --- diff --git a/VEX/priv/host_s390_defs.c b/VEX/priv/host_s390_defs.c index 47928cbe1c..43b89c9253 100644 --- a/VEX/priv/host_s390_defs.c +++ b/VEX/priv/host_s390_defs.c @@ -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); diff --git a/VEX/priv/host_s390_defs.h b/VEX/priv/host_s390_defs.h index e79b990e47..bbafa4fb08 100644 --- a/VEX/priv/host_s390_defs.h +++ b/VEX/priv/host_s390_defs.h @@ -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 */ /*---------------------------------------------------------------*/ diff --git a/VEX/priv/main_main.c b/VEX/priv/main_main.c index 5acab9ebaf..82155305c7 100644 --- a/VEX/priv/main_main.c +++ b/VEX/priv/main_main.c @@ -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 + diff --git a/VEX/pub/libvex.h b/VEX/pub/libvex.h index 5d3733db0b..359d10809c 100644 --- a/VEX/pub/libvex.h +++ b/VEX/pub/libvex.h @@ -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) diff --git a/coregrind/m_machine.c b/coregrind/m_machine.c index 32c242a8ea..672a02124a 100644 --- a/coregrind/m_machine.c +++ b/coregrind/m_machine.c @@ -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 */