Generalize movcond to support pre-computed conditions, and the same set of arguments at all times. This will be assumed by a following patch, which needs to reuse tgen_movcond_int.
Signed-off-by: Richard Henderson <richard.hender...@linaro.org> --- tcg/s390x/tcg-target-con-set.h | 3 +- tcg/s390x/tcg-target.c.inc | 78 ++++++++++++++++++++++++++-------- 2 files changed, 61 insertions(+), 20 deletions(-) diff --git a/tcg/s390x/tcg-target-con-set.h b/tcg/s390x/tcg-target-con-set.h index dc271a6d11..86cdc248f2 100644 --- a/tcg/s390x/tcg-target-con-set.h +++ b/tcg/s390x/tcg-target-con-set.h @@ -29,8 +29,7 @@ C_O1_I2(r, rZ, r) C_O1_I2(v, v, r) C_O1_I2(v, v, v) C_O1_I3(v, v, v, v) -C_O1_I4(r, r, ri, r, 0) -C_O1_I4(r, r, ri, rI, 0) +C_O1_I4(r, r, ri, rI, r) C_O2_I2(o, m, 0, r) C_O2_I2(o, m, r, r) C_O2_I3(o, m, 0, 1, r) diff --git a/tcg/s390x/tcg-target.c.inc b/tcg/s390x/tcg-target.c.inc index fad86f01f3..b2adbbe7de 100644 --- a/tcg/s390x/tcg-target.c.inc +++ b/tcg/s390x/tcg-target.c.inc @@ -1461,25 +1461,69 @@ static void tgen_setcond(TCGContext *s, TCGType type, TCGCond cond, } } +static void tgen_movcond_int(TCGContext *s, TCGType type, TCGReg dest, + TCGArg v3, int v3const, TCGReg v4, + int cc, int inv_cc) +{ + TCGReg src; + + /* If dest != v4, LGR+LOCGHI is larger than LGHI+{LOCGR,SELGR}. */ + if (HAVE_FACILITY(LOAD_ON_COND2) && v3const && dest == v4) { + /* Emit: if (cc) dest = v3. */ + tcg_out_insn(s, RIEg, LOCGHI, dest, v3, cc); + return; + } + + if (HAVE_FACILITY(LOAD_ON_COND)) { + if (dest == v4) { + if (v3const) { + tcg_out_insn(s, RI, LGHI, TCG_TMP0, v3); + src = TCG_TMP0; + } else { + src = v3; + } + } else { + if (v3const) { + tcg_out_insn(s, RI, LGHI, dest, v3); + } else { + tcg_out_mov(s, type, dest, v3); + } + cc = inv_cc; + src = v4; + } + /* Emit: if (cc) dest = src. */ + tcg_out_insn(s, RRFc, LOCGR, dest, src, cc); + return; + } + + if (v3const) { + tcg_out_mov(s, type, dest, v4); + /* Emit: if (!cc) goto over; dest = r3; over: */ + tcg_out_insn(s, RI, BRC, inv_cc, (4 + 4) >> 1); + tcg_out_insn(s, RI, LGHI, dest, v3); + return; + } + + if (dest == v4) { + src = v3; + } else { + tcg_out_mov(s, type, dest, v3); + inv_cc = cc; + src = v4; + } + /* Emit: if (!cc) goto over; dest = src; over: */ + tcg_out_insn(s, RI, BRC, inv_cc, (4 + 4) >> 1); + tcg_out_insn(s, RRE, LGR, dest, src); +} + static void tgen_movcond(TCGContext *s, TCGType type, TCGCond c, TCGReg dest, TCGReg c1, TCGArg c2, int c2const, - TCGArg v3, int v3const) + TCGArg v3, int v3const, TCGReg v4) { int cc, inv_cc; cc = tgen_cmp2(s, type, c, c1, c2, c2const, false, &inv_cc); - - if (HAVE_FACILITY(LOAD_ON_COND)) { - if (v3const) { - tcg_out_insn(s, RIEg, LOCGHI, dest, v3, cc); - } else { - tcg_out_insn(s, RRFc, LOCGR, dest, v3, cc); - } - } else { - /* Emit: if (cc) goto over; dest = r3; over: */ - tcg_out_insn(s, RI, BRC, inv_cc, (4 + 4) >> 1); - tcg_out_insn(s, RRE, LGR, dest, v3); - } + tgen_movcond_int(s, type, dest, v3, v3const, v4, cc, inv_cc); } static void tgen_clz(TCGContext *s, TCGReg dest, TCGReg a1, @@ -2352,7 +2396,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, break; case INDEX_op_movcond_i32: tgen_movcond(s, TCG_TYPE_I32, args[5], args[0], args[1], - args[2], const_args[2], args[3], const_args[3]); + args[2], const_args[2], args[3], const_args[3], args[4]); break; case INDEX_op_qemu_ld_i32: @@ -2644,7 +2688,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, break; case INDEX_op_movcond_i64: tgen_movcond(s, TCG_TYPE_I64, args[5], args[0], args[1], - args[2], const_args[2], args[3], const_args[3]); + args[2], const_args[2], args[3], const_args[3], args[4]); break; OP_32_64(deposit): @@ -3256,9 +3300,7 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op) case INDEX_op_movcond_i32: case INDEX_op_movcond_i64: - return (HAVE_FACILITY(LOAD_ON_COND2) - ? C_O1_I4(r, r, ri, rI, 0) - : C_O1_I4(r, r, ri, r, 0)); + return C_O1_I4(r, r, ri, rI, r); case INDEX_op_div2_i32: case INDEX_op_div2_i64: -- 2.34.1