From: Andreas Arnez Date: Thu, 19 Mar 2020 16:35:55 +0000 (+0100) Subject: Bug 418997 - s390x: Support Iex_ITE for float and vector expressions X-Git-Tag: VALGRIND_3_16_0~67 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=abe7f083fdebb40c6f4a5adbdd2b64f5c329969a;p=thirdparty%2Fvalgrind.git Bug 418997 - s390x: Support Iex_ITE for float and vector expressions The s390x backend supports Iex_ITE expressions for integer types I8, I16, I32, and I64 only. But "grail" can now generate such expressions for guarding any kind of Ist_Put statements; see add_guarded_stmt_to_end_of() in "guest_generic_bb_to_IR.c". On s390x this means that F64 and V128 can occur as well, in which case a crash would result. And such crashes are actually seen when running the test suite with "grail" enabled. Extend Iex_ITE support to the floating-point types F32 and F64 and to the vector type V128. Do this by extending S390_INSN_COND_MOVE as needed. --- diff --git a/NEWS b/NEWS index 4b4dad0086..7c497c15fa 100644 --- a/NEWS +++ b/NEWS @@ -134,6 +134,7 @@ n-i-bz Add support for the Linux io_uring system calls n-i-bz sys_statx: don't complain if both |filename| and |buf| are NULL. n-i-bz Fix non-glibc build of test suite with s390x_features 418004 Grail code additions break ppc64. +418997 s390x: Support Iex_ITE for float and vector types Release 3.15.0 (12 April 2019) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/VEX/priv/host_s390_defs.c b/VEX/priv/host_s390_defs.c index b61cd41a50..308b6ff409 100644 --- a/VEX/priv/host_s390_defs.c +++ b/VEX/priv/host_s390_defs.c @@ -6465,7 +6465,7 @@ s390_insn_cond_move(UChar size, s390_cc_t cond, HReg dst, s390_opnd_RMI src) insn->variant.cond_move.src = src; insn->variant.cond_move.dst = dst; - vassert(size == 1 || size == 2 || size == 4 || size == 8); + vassert(size == 1 || size == 2 || size == 4 || size == 8 || size == 16); return insn; } @@ -10189,7 +10189,7 @@ s390_insn_cond_move_emit(UChar *buf, const s390_insn *insn) p = buf; - if (s390_host_has_lsc) { + if (s390_host_has_lsc && hregClass(dst) == HRcInt64) { /* LOCx is not the preferred way to implement an unconditional load. */ if (cond == S390_CC_ALWAYS) goto use_branch_insn; @@ -10257,14 +10257,32 @@ use_branch_insn: switch (src.tag) { case S390_OPND_REG: - p = s390_emit_LGR(p, hregNumber(dst), hregNumber(src.variant.reg)); + switch (hregClass(dst)) { + case HRcInt64: + p = s390_emit_LGR(p, hregNumber(dst), hregNumber(src.variant.reg)); + break; + case HRcFlt64: + p = s390_emit_LDR(p, hregNumber(dst), hregNumber(src.variant.reg)); + break; + case HRcVec128: + p = s390_emit_VLR(p, hregNumber(dst), hregNumber(src.variant.reg)); + break; + default: + goto fail; + } break; case S390_OPND_AMODE: + if (hregClass(dst) != HRcInt64) + goto fail; + p = s390_emit_load_mem(p, insn->size, hregNumber(dst), src.variant.am); break; case S390_OPND_IMMEDIATE: { + if (hregClass(dst) != HRcInt64) + goto fail; + ULong value = src.variant.imm; UInt r = hregNumber(dst); diff --git a/VEX/priv/host_s390_isel.c b/VEX/priv/host_s390_isel.c index b374024c8c..e96c7209f1 100644 --- a/VEX/priv/host_s390_isel.c +++ b/VEX/priv/host_s390_isel.c @@ -2770,6 +2770,25 @@ s390_isel_float_expr_wrk(ISelEnv *env, IRExpr *expr) return dst; } + /* --------- MULTIPLEX --------- */ + case Iex_ITE: { + IRExpr *cond_expr = expr->Iex.ITE.cond; + HReg dst, r0, r1; + + vassert(typeOfIRExpr(env->type_env, cond_expr) == Ity_I1); + + dst = newVRegF(env); + r0 = s390_isel_float_expr(env, expr->Iex.ITE.iffalse); + r1 = s390_isel_float_expr(env, expr->Iex.ITE.iftrue); + size = sizeofIRType(typeOfIRExpr(env->type_env, expr->Iex.ITE.iftrue)); + + s390_cc_t cc = s390_isel_cc(env, cond_expr); + + addInstr(env, s390_insn_move(size, dst, r0)); + addInstr(env, s390_insn_cond_move(size, cc, dst, s390_opnd_reg(r1))); + return dst; + } + default: goto irreducible; } @@ -4694,6 +4713,25 @@ s390_isel_vec_expr_wrk(ISelEnv *env, IRExpr *expr) } } + /* --------- MULTIPLEX --------- */ + case Iex_ITE: { + IRExpr *cond_expr = expr->Iex.ITE.cond; + HReg dst, r0, r1; + + vassert(typeOfIRExpr(env->type_env, cond_expr) == Ity_I1); + + dst = newVRegV(env); + r0 = s390_isel_vec_expr(env, expr->Iex.ITE.iffalse); + r1 = s390_isel_vec_expr(env, expr->Iex.ITE.iftrue); + size = sizeofIRType(typeOfIRExpr(env->type_env, expr->Iex.ITE.iftrue)); + + s390_cc_t cc = s390_isel_cc(env, cond_expr); + + addInstr(env, s390_insn_move(size, dst, r0)); + addInstr(env, s390_insn_cond_move(size, cc, dst, s390_opnd_reg(r1))); + return dst; + } + default: goto irreducible; }