From: Ilya Leoshkevich Date: Thu, 16 May 2019 10:34:37 +0000 (+0200) Subject: Bug 404406 - s390x: implement z14 miscellaneous instructions X-Git-Tag: VALGRIND_3_16_0~263 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=50b20aa244c1fddd9b9e872526d4daad49ddd7a5;p=thirdparty%2Fvalgrind.git Bug 404406 - s390x: implement z14 miscellaneous instructions (from bug 404406 comment 0): Valgrind on s390x currently lacks support for the miscellaneous instruction extensions facility 2. Signed-off-by: Ilya Leoshkevich --- diff --git a/NEWS b/NEWS index 905a868417..770a231788 100644 --- a/NEWS +++ b/NEWS @@ -54,6 +54,7 @@ where XXXXXX is the bug number as listed below. 407764 drd cond_post_wait gets wrong (?) condition on s390x z13 system 408009 Expose rdrand and f16c even on avx if host cpu supports them 408091 Missing pkey syscalls +404406 s390x: z14 miscellaneous instructions not implemented n-i-bz Fix minor one time leaks in dhat. n-i-bz Add --run-cxx-freeres=no in outer args to avoid inner crashes. diff --git a/VEX/priv/guest_s390_defs.h b/VEX/priv/guest_s390_defs.h index 0185de5fd5..1470558cee 100644 --- a/VEX/priv/guest_s390_defs.h +++ b/VEX/priv/guest_s390_defs.h @@ -158,7 +158,9 @@ enum { S390_CC_OP_DFP_128_TO_INT_64 = 57, S390_CC_OP_PFPO_32 = 58, S390_CC_OP_PFPO_64 = 59, - S390_CC_OP_PFPO_128 = 60 + S390_CC_OP_PFPO_128 = 60, + S390_CC_OP_MUL_32 = 61, + S390_CC_OP_MUL_64 = 62 }; /*------------------------------------------------------------*/ diff --git a/VEX/priv/guest_s390_helpers.c b/VEX/priv/guest_s390_helpers.c index 63ee68b24c..525e7000cf 100644 --- a/VEX/priv/guest_s390_helpers.c +++ b/VEX/priv/guest_s390_helpers.c @@ -990,6 +990,16 @@ decode_bfp_rounding_mode(UInt irrm) psw >> 28; /* cc */ \ }) +#define S390_CC_FOR_TERNARY(opcode,cc_dep1,cc_dep2) \ +({ \ + __asm__ volatile ( \ + opcode ",%[op1],%[op1],%[op2],0\n\t" \ + "ipm %[psw]\n\t" : [psw] "=d"(psw), [op1] "+d"(cc_dep1) \ + : [op2] "d"(cc_dep2) \ + : "cc");\ + psw >> 28; /* cc */ \ +}) + #define S390_CC_FOR_TERNARY_SUBB(opcode,cc_dep1,cc_dep2,cc_ndep) \ ({ \ /* Recover the original DEP2 value. See comment near s390_cc_thunk_put3 \ @@ -1802,6 +1812,12 @@ s390_calculate_cc(ULong cc_op, ULong cc_dep1, ULong cc_dep2, ULong cc_ndep) return psw >> 28; /* cc */ } + case S390_CC_OP_MUL_32: + return S390_CC_FOR_TERNARY(".insn rrf,0xb9fd0000", cc_dep1, cc_dep2); + + case S390_CC_OP_MUL_64: + return S390_CC_FOR_TERNARY(".insn rrf,0xb9ed0000", cc_dep1, cc_dep2); + default: break; } diff --git a/VEX/priv/guest_s390_toIR.c b/VEX/priv/guest_s390_toIR.c index 076a4211fa..06ec27fae0 100644 --- a/VEX/priv/guest_s390_toIR.c +++ b/VEX/priv/guest_s390_toIR.c @@ -49,7 +49,7 @@ static UInt s390_decode_and_irgen(const UChar *, UInt, DisResult *); static void s390_irgen_xonc(IROp, IRTemp, IRTemp, IRTemp); static void s390_irgen_CLC_EX(IRTemp, IRTemp, IRTemp); - +static const HChar *s390_irgen_BIC(UChar r1, IRTemp op2addr); /*------------------------------------------------------------*/ /*--- Globals ---*/ @@ -3314,8 +3314,12 @@ s390_format_RXY_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr), mnm = irgen(r1, op2addr); - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - s390_disasm(ENC3(MNM, GPR, SDXB), mnm, r1, dh2, dl2, x2, b2); + if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) { + if (irgen == s390_irgen_BIC) + s390_disasm(ENC2(XMNM, SDXB), S390_XMNM_BIC, r1, dh2, dl2, x2, b2); + else + s390_disasm(ENC3(MNM, GPR, SDXB), mnm, r1, dh2, dl2, x2, b2); + } } static void @@ -4280,6 +4284,22 @@ s390_irgen_AHIK(UChar r1, UChar r3, UShort i2) return "ahik"; } +static const HChar * +s390_irgen_AGH(UChar r1, IRTemp op2addr) +{ + IRTemp op1 = newTemp(Ity_I64); + IRTemp op2 = newTemp(Ity_I64); + IRTemp result = newTemp(Ity_I64); + + assign(op1, get_gpr_dw0(r1)); + assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr)))); + assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2))); + s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2); + put_gpr_dw0(r1, mkexpr(result)); + + return "agh"; +} + static const HChar * s390_irgen_AGHIK(UChar r1, UChar r3, UShort i2) { @@ -5197,6 +5217,24 @@ s390_irgen_BCTG(UChar r1, IRTemp op2addr) return "bctg"; } +static const HChar * +s390_irgen_BIC(UChar r1, IRTemp op2addr) +{ + IRTemp cond = newTemp(Ity_I32); + + if (r1 == 0) { + /* nothing */ + } else if (r1 == 15) { + always_goto(load(Ity_I64, mkexpr(op2addr))); + } else { + assign(cond, s390_call_calculate_cond(r1)); + if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)), + load(Ity_I64, mkexpr(op2addr))); + } + + return "bic"; +} + static const HChar * s390_irgen_BXH(UChar r1, UChar r3, IRTemp op2addr) { @@ -8333,6 +8371,54 @@ s390_irgen_MFY(UChar r1, IRTemp op2addr) return "mfy"; } +static const HChar * +s390_irgen_MG(UChar r1, IRTemp op2addr) +{ + IRTemp op1 = newTemp(Ity_I64); + IRTemp op2 = newTemp(Ity_I64); + IRTemp result = newTemp(Ity_I128); + + assign(op1, get_gpr_dw0(r1 + 1)); + assign(op2, load(Ity_I64, mkexpr(op2addr))); + assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2))); + put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); + put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); + + return "mg"; +} + +static const HChar * +s390_irgen_MGH(UChar r1, IRTemp op2addr) +{ + IRTemp op1 = newTemp(Ity_I64); + IRTemp op2 = newTemp(Ity_I16); + IRTemp result = newTemp(Ity_I128); + + assign(op1, get_gpr_dw0(r1)); + assign(op2, load(Ity_I16, mkexpr(op2addr))); + assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_16Sto64, mkexpr(op2)) + )); + put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result))); + + return "mgh"; +} + +static const HChar * +s390_irgen_MGRK(UChar r3, UChar r1, UChar r2) +{ + IRTemp op2 = newTemp(Ity_I64); + IRTemp op3 = newTemp(Ity_I64); + IRTemp result = newTemp(Ity_I128); + + assign(op2, get_gpr_dw0(r2)); + assign(op3, get_gpr_dw0(r3)); + assign(result, binop(Iop_MullS64, mkexpr(op2), mkexpr(op3))); + put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); + put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); + + return "mgrk"; +} + static const HChar * s390_irgen_MH(UChar r1, IRTemp op2addr) { @@ -8522,6 +8608,38 @@ s390_irgen_MS(UChar r1, IRTemp op2addr) return "ms"; } +static const HChar * +s390_irgen_MSC(UChar r1, IRTemp op2addr) +{ + IRTemp op1 = newTemp(Ity_I32); + IRTemp op2 = newTemp(Ity_I32); + IRTemp result = newTemp(Ity_I64); + + assign(op1, get_gpr_w1(r1)); + assign(op2, load(Ity_I32, mkexpr(op2addr))); + assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2))); + s390_cc_thunk_putSS(S390_CC_OP_MUL_32, op1, op2); + put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result))); + + return "msc"; +} + +static const HChar * +s390_irgen_MSRKC(UChar r3, UChar r1, UChar r2) +{ + IRTemp op2 = newTemp(Ity_I32); + IRTemp op3 = newTemp(Ity_I32); + IRTemp result = newTemp(Ity_I64); + + assign(op2, get_gpr_w1(r2)); + assign(op3, get_gpr_w1(r3)); + assign(result, binop(Iop_MullS32, mkexpr(op2), mkexpr(op3))); + s390_cc_thunk_putSS(S390_CC_OP_MUL_32, op2, op3); + put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result))); + + return "msrkc"; +} + static const HChar * s390_irgen_MSY(UChar r1, IRTemp op2addr) { @@ -8552,6 +8670,22 @@ s390_irgen_MSG(UChar r1, IRTemp op2addr) return "msg"; } +static const HChar * +s390_irgen_MSGC(UChar r1, IRTemp op2addr) +{ + IRTemp op1 = newTemp(Ity_I64); + IRTemp op2 = newTemp(Ity_I64); + IRTemp result = newTemp(Ity_I128); + + assign(op1, get_gpr_dw0(r1)); + assign(op2, load(Ity_I64, mkexpr(op2addr))); + assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2))); + s390_cc_thunk_putSS(S390_CC_OP_MUL_64, op1, op2); + put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result))); + + return "msgc"; +} + static const HChar * s390_irgen_MSGF(UChar r1, IRTemp op2addr) { @@ -8599,6 +8733,22 @@ s390_irgen_MSGFI(UChar r1, UInt i2) return "msgfi"; } +static const HChar * +s390_irgen_MSGRKC(UChar r3, UChar r1, UChar r2) +{ + IRTemp op2 = newTemp(Ity_I64); + IRTemp op3 = newTemp(Ity_I64); + IRTemp result = newTemp(Ity_I128); + + assign(op2, get_gpr_dw0(r2)); + assign(op3, get_gpr_dw0(r3)); + assign(result, binop(Iop_MullS64, mkexpr(op2), mkexpr(op3))); + s390_cc_thunk_putSS(S390_CC_OP_MUL_64, op2, op3); + put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result))); + + return "msgrkc"; +} + static const HChar * s390_irgen_OR(UChar r1, UChar r2) { @@ -10060,6 +10210,22 @@ s390_irgen_SGF(UChar r1, IRTemp op2addr) return "sgf"; } +static const HChar * +s390_irgen_SGH(UChar r1, IRTemp op2addr) +{ + IRTemp op1 = newTemp(Ity_I64); + IRTemp op2 = newTemp(Ity_I64); + IRTemp result = newTemp(Ity_I64); + + assign(op1, get_gpr_dw0(r1)); + assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr)))); + assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2))); + s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2); + put_gpr_dw0(r1, mkexpr(result)); + + return "sgh"; +} + static const HChar * s390_irgen_SH(UChar r1, IRTemp op2addr) { @@ -19693,8 +19859,12 @@ s390_decode_4byte_and_irgen(const UChar *bytes) case 0xb9eb: s390_format_RRF_R0RR2(s390_irgen_SLGRK, RRF4_r3(ovl), RRF4_r1(ovl), RRF4_r2(ovl)); goto ok; - case 0xb9ec: /* MGRK */ goto unimplemented; - case 0xb9ed: /* MSGRKC */ goto unimplemented; + case 0xb9ec: s390_format_RRF_R0RR2(s390_irgen_MGRK, RRF4_r3(ovl), + RRF4_r1(ovl), RRF4_r2(ovl)); + goto ok; + case 0xb9ed: s390_format_RRF_R0RR2(s390_irgen_MSGRKC, RRF4_r3(ovl), + RRF4_r1(ovl), RRF4_r2(ovl)); + goto ok; case 0xb9f2: s390_format_RRF_U0RR(s390_irgen_LOCR, RRF3_r3(ovl), RRF3_r1(ovl), RRF3_r2(ovl), S390_XMNM_LOCR); goto ok; @@ -19719,7 +19889,9 @@ s390_decode_4byte_and_irgen(const UChar *bytes) case 0xb9fb: s390_format_RRF_R0RR2(s390_irgen_SLRK, RRF4_r3(ovl), RRF4_r1(ovl), RRF4_r2(ovl)); goto ok; - case 0xb9fd: /* MSRKC */ goto unimplemented; + case 0xb9fd: s390_format_RRF_R0RR2(s390_irgen_MSRKC, RRF4_r3(ovl), + RRF4_r1(ovl), RRF4_r2(ovl)); + goto ok; } switch ((ovl & 0xff000000) >> 24) { @@ -20036,8 +20208,14 @@ s390_decode_6byte_and_irgen(const UChar *bytes) RXY_x2(ovl), RXY_b2(ovl), RXY_dl2(ovl), RXY_dh2(ovl)); goto ok; - case 0xe30000000038ULL: /* AGH */ goto unimplemented; - case 0xe30000000039ULL: /* SGH */ goto unimplemented; + case 0xe30000000038ULL: s390_format_RXY_RRRD(s390_irgen_AGH, RXY_r1(ovl), + RXY_x2(ovl), RXY_b2(ovl), + RXY_dl2(ovl), + RXY_dh2(ovl)); goto ok; + case 0xe30000000039ULL: s390_format_RXY_RRRD(s390_irgen_SGH, RXY_r1(ovl), + RXY_x2(ovl), RXY_b2(ovl), + RXY_dl2(ovl), + RXY_dh2(ovl)); goto ok; case 0xe3000000003aULL: s390_format_RXY_RRRD(s390_irgen_LLZRGF, RXY_r1(ovl), RXY_x2(ovl), RXY_b2(ovl), RXY_dl2(ovl), @@ -20046,7 +20224,10 @@ s390_decode_6byte_and_irgen(const UChar *bytes) RXY_x2(ovl), RXY_b2(ovl), RXY_dl2(ovl), RXY_dh2(ovl)); goto ok; - case 0xe3000000003cULL: /* MGH */ goto unimplemented; + case 0xe3000000003cULL: s390_format_RXY_RRRD(s390_irgen_MGH, RXY_r1(ovl), + RXY_x2(ovl), RXY_b2(ovl), + RXY_dl2(ovl), + RXY_dh2(ovl)); goto ok; case 0xe3000000003eULL: s390_format_RXY_RRRD(s390_irgen_STRV, RXY_r1(ovl), RXY_x2(ovl), RXY_b2(ovl), RXY_dl2(ovl), @@ -20059,7 +20240,10 @@ s390_decode_6byte_and_irgen(const UChar *bytes) RXY_x2(ovl), RXY_b2(ovl), RXY_dl2(ovl), RXY_dh2(ovl)); goto ok; - case 0xe30000000047ULL: /* BIC */ goto unimplemented; + case 0xe30000000047ULL: s390_format_RXY_RRRD(s390_irgen_BIC, RXY_r1(ovl), + RXY_x2(ovl), RXY_b2(ovl), + RXY_dl2(ovl), + RXY_dh2(ovl)); goto ok; case 0xe30000000048ULL: /* LLGFSG */ goto unimplemented; case 0xe30000000049ULL: /* STGSC */ goto unimplemented; case 0xe3000000004cULL: /* LGG */ goto unimplemented; @@ -20072,7 +20256,10 @@ s390_decode_6byte_and_irgen(const UChar *bytes) RXY_x2(ovl), RXY_b2(ovl), RXY_dl2(ovl), RXY_dh2(ovl)); goto ok; - case 0xe30000000053ULL: /* MSC */ goto unimplemented; + case 0xe30000000053ULL: s390_format_RXY_RRRD(s390_irgen_MSC, RXY_r1(ovl), + RXY_x2(ovl), RXY_b2(ovl), + RXY_dl2(ovl), + RXY_dh2(ovl)); goto ok; case 0xe30000000054ULL: s390_format_RXY_RRRD(s390_irgen_NY, RXY_r1(ovl), RXY_x2(ovl), RXY_b2(ovl), RXY_dl2(ovl), @@ -20177,8 +20364,14 @@ s390_decode_6byte_and_irgen(const UChar *bytes) RXY_x2(ovl), RXY_b2(ovl), RXY_dl2(ovl), RXY_dh2(ovl)); goto ok; - case 0xe30000000083ULL: /* MSGC */ goto unimplemented; - case 0xe30000000084ULL: /* MG */ goto unimplemented; + case 0xe30000000083ULL: s390_format_RXY_RRRD(s390_irgen_MSGC, RXY_r1(ovl), + RXY_x2(ovl), RXY_b2(ovl), + RXY_dl2(ovl), + RXY_dh2(ovl)); goto ok; + case 0xe30000000084ULL: s390_format_RXY_RRRD(s390_irgen_MG, RXY_r1(ovl), + RXY_x2(ovl), RXY_b2(ovl), + RXY_dl2(ovl), + RXY_dh2(ovl)); goto ok; case 0xe30000000085ULL: s390_format_RXY_RRRD(s390_irgen_LGAT, RXY_r1(ovl), RXY_x2(ovl), RXY_b2(ovl), RXY_dl2(ovl), diff --git a/VEX/priv/host_s390_defs.c b/VEX/priv/host_s390_defs.c index 8aa2ba67f8..162550fd70 100644 --- a/VEX/priv/host_s390_defs.c +++ b/VEX/priv/host_s390_defs.c @@ -3023,6 +3023,26 @@ s390_emit_MFY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) } +static UChar * +s390_emit_MG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2) +{ + if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) + s390_disasm(ENC3(MNM, GPR, SDXB), "mg", r1, dh2, dl2, x2, b2); + + return emit_RXY(p, 0xe30000000084ULL, r1, x2, b2, dl2, dh2); +} + + +static UChar * +s390_emit_MGRK(UChar *p, UChar r3, UChar r1, UChar r2) +{ + if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) + s390_disasm(ENC4(MNM, GPR, GPR, GPR), "mgrk", r1, r2, r3); + + return emit_RRF3(p, 0xb9ec0000, r3, r1, r2); +} + + static UChar * s390_emit_MH(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2) { @@ -9595,7 +9615,7 @@ s390_insn_mul_emit(UChar *buf, const s390_insn *insn) case 8: if (signed_multiply) - vpanic("s390_insn_mul_emit"); + return s390_emit_MGRK(buf, r1 + 1, r1, r2); else return s390_emit_MLGR(buf, r1, r2); @@ -9640,7 +9660,7 @@ s390_insn_mul_emit(UChar *buf, const s390_insn *insn) case 8: if (signed_multiply) - vpanic("s390_insn_mul_emit"); + return s390_emit_MG(buf, r1, x, b, DISP20(d)); else return s390_emit_MLG(buf, r1, x, b, DISP20(d)); @@ -9665,7 +9685,7 @@ s390_insn_mul_emit(UChar *buf, const s390_insn *insn) case 8: buf = s390_emit_load_64imm(buf, R0, value); if (signed_multiply) - vpanic("s390_insn_mul_emit"); + return s390_emit_MGRK(buf, r1 + 1, r1, R0); else return s390_emit_MLGR(buf, r1, R0); diff --git a/VEX/priv/host_s390_isel.c b/VEX/priv/host_s390_isel.c index 9141b7bffd..30e5c7620b 100644 --- a/VEX/priv/host_s390_isel.c +++ b/VEX/priv/host_s390_isel.c @@ -1018,6 +1018,8 @@ s390_isel_int128_expr_wrk(HReg *dst_hi, HReg *dst_lo, ISelEnv *env, goto do_multiply64; case Iop_MullS64: + if (!(env->hwcaps & VEX_HWCAPS_S390X_MI2)) + goto irreducible; is_signed_multiply = True; goto do_multiply64; @@ -1125,7 +1127,10 @@ s390_isel_int128_expr_wrk(HReg *dst_hi, HReg *dst_lo, ISelEnv *env, } } - vpanic("s390_isel_int128_expr"); + /* We get here if no pattern matched. */ + irreducible: + ppIRExpr(expr); + vpanic("s390_isel_int128_expr: cannot reduce tree"); } diff --git a/VEX/priv/main_main.c b/VEX/priv/main_main.c index 97c0bacd67..3cfe8c1cb2 100644 --- a/VEX/priv/main_main.c +++ b/VEX/priv/main_main.c @@ -1721,6 +1721,7 @@ static const HChar* show_hwcaps_s390x ( UInt hwcaps ) { VEX_HWCAPS_S390X_PFPO, "pfpo" }, { VEX_HWCAPS_S390X_VX, "vx" }, { VEX_HWCAPS_S390X_MSA5, "msa5" }, + { VEX_HWCAPS_S390X_MI2, "mi2" }, }; /* Allocate a large enough buffer */ static HChar buf[sizeof prefix + diff --git a/VEX/priv/s390_disasm.c b/VEX/priv/s390_disasm.c index 4d3fec544c..e3fbc11af5 100644 --- a/VEX/priv/s390_disasm.c +++ b/VEX/priv/s390_disasm.c @@ -433,6 +433,16 @@ s390_disasm(UInt command, ...) the integer mask is appended as the final operand */ if (mask == 0 || mask == 15) mask_suffix = mask; break; + case S390_XMNM_BIC: + mask = va_arg(args, UInt); + if (mask == 0) { + /* There is no special opcode when mask == 0. */ + p += vex_sprintf(p, "bic"); + mask_suffix = mask; + } else { + p += vex_sprintf(p, "%s", construct_mnemonic("bi", "", mask)); + } + break; } } continue; diff --git a/VEX/priv/s390_disasm.h b/VEX/priv/s390_disasm.h index 8469f72ab7..eec41f8ac5 100644 --- a/VEX/priv/s390_disasm.h +++ b/VEX/priv/s390_disasm.h @@ -91,7 +91,8 @@ enum { S390_XMNM_LOCFHR = 13, S390_XMNM_LOCHI = 14, S390_XMNM_LOCGHI = 15, - S390_XMNM_LOCHHI = 16 + S390_XMNM_LOCHHI = 16, + S390_XMNM_BIC = 17 }; void s390_disasm(UInt command, ...); diff --git a/VEX/pub/libvex.h b/VEX/pub/libvex.h index 37afd185a7..9337a7c329 100644 --- a/VEX/pub/libvex.h +++ b/VEX/pub/libvex.h @@ -163,6 +163,7 @@ typedef #define VEX_HWCAPS_S390X_PFPO (1<<17) /* Perform floating point ops facility */ #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 */ /* Special value representing all available s390x hwcaps */ @@ -179,7 +180,8 @@ typedef VEX_HWCAPS_S390X_ETF2 | \ VEX_HWCAPS_S390X_PFPO | \ VEX_HWCAPS_S390X_VX | \ - VEX_HWCAPS_S390X_MSA5) + VEX_HWCAPS_S390X_MSA5 | \ + VEX_HWCAPS_S390X_MI2) #define VEX_HWCAPS_S390X(x) ((x) & ~VEX_S390X_MODEL_MASK) #define VEX_S390X_MODEL(x) ((x) & VEX_S390X_MODEL_MASK) diff --git a/VEX/pub/libvex_s390x_common.h b/VEX/pub/libvex_s390x_common.h index c976395fc1..d945a44722 100644 --- a/VEX/pub/libvex_s390x_common.h +++ b/VEX/pub/libvex_s390x_common.h @@ -99,6 +99,7 @@ #define S390_FAC_CTREXE 50 // constrained transactional execution #define S390_FAC_LSC2 53 // load/store on condition 2 and load and zero rightmost byte #define S390_FAC_MSA5 57 // message-security-assist 5 +#define S390_FAC_MI2 58 // miscellaneous-instruction-extensions 2 #define S390_FAC_TREXE 73 // transactional execution #define S390_FAC_MSA4 77 // message-security-assist 4 #define S390_FAC_VX 129 // vector facility diff --git a/coregrind/m_machine.c b/coregrind/m_machine.c index cbb88472da..9eab9000f4 100644 --- a/coregrind/m_machine.c +++ b/coregrind/m_machine.c @@ -1534,7 +1534,8 @@ Bool VG_(machine_get_hwcaps)( void ) { False, S390_FAC_LSC, VEX_HWCAPS_S390X_LSC, "LSC" }, { False, S390_FAC_PFPO, VEX_HWCAPS_S390X_PFPO, "PFPO" }, { False, S390_FAC_VX, VEX_HWCAPS_S390X_VX, "VX" }, - { False, S390_FAC_MSA5, VEX_HWCAPS_S390X_MSA5, "MSA5" } + { False, S390_FAC_MSA5, VEX_HWCAPS_S390X_MSA5, "MSA5" }, + { False, S390_FAC_MI2, VEX_HWCAPS_S390X_MI2, "MI2" }, }; /* Set hwcaps according to the detected facilities */ diff --git a/docs/internals/s390-opcodes.csv b/docs/internals/s390-opcodes.csv index 4281f240f2..67d75490cc 100644 --- a/docs/internals/s390-opcodes.csv +++ b/docs/internals/s390-opcodes.csv @@ -1633,17 +1633,17 @@ wfsxb,"scalar vector fp subtract scalar extended","not implemented","arch12" vftcisb,"vector fp test data class immediate short","not implemented","arch12" wftcisb,"scalar vector fp test data class immediate scalar short","not implemented","arch12" wftcixb,"scalar vector fp test data class immediate scalar extended","not implemented","arch12" -agh,"add halfword to 64 bit value","not implemented","arch12" -bic,"branch indirect on condition","not implemented","arch12" -bi,"unconditional indirect branch","not implemented","arch12" -mgrk,"multiply 64x64reg -> 128","not implemented","arch12" -mg,"multiply 64x64mem -> 128","not implemented","arch12" -mgh,"multiply halfword 64x16mem -> 64","not implemented","arch12" -msrkc,"multiply single 32x32 -> 32","not implemented","arch12" -msgrkc,"multiply single 64x64 -> 64","not implemented","arch12" -msc,"multiply single 32x32mem -> 32","not implemented","arch12" -msgc,"multiply single 64x64mem -> 64","not implemented","arch12" -sgh,"subtract halfword from 64 bit value","not implemented","arch12" +agh,"add halfword to 64 bit value",implemented,"arch12" +bic,"branch indirect on condition",implemented,"arch12" +bi,"unconditional indirect branch",implemented,"arch12" +mgrk,"multiply 64x64reg -> 128",implemented,"arch12" +mg,"multiply 64x64mem -> 128",implemented,"arch12" +mgh,"multiply halfword 64x16mem -> 64",implemented,"arch12" +msrkc,"multiply single 32x32 -> 32",implemented,"arch12" +msgrkc,"multiply single 64x64 -> 64",implemented,"arch12" +msc,"multiply single 32x32mem -> 32",implemented,"arch12" +msgc,"multiply single 64x64mem -> 64",implemented,"arch12" +sgh,"subtract halfword from 64 bit value",implemented,"arch12" vlrlr,"vector load rightmost with length","not implemented","arch12" vlrl,"vector load rightmost with immediate length","not implemented","arch12" vstrlr,"vector store rightmost with length","not implemented","arch12"