From: Richard Henderson <[email protected]> Zero operands produce a zero high and low product. One operands produce a copy of the other operand and a zero or sign extension in the high half.
Fold those cases during TCG optimization so wide-multiply idioms used by target translators can collapse before code generation. Signed-off-by: Richard Henderson <[email protected]> Signed-off-by: James Hilliard <[email protected]> Signed-off-by: Philippe Mathieu-Daudé <[email protected]> --- tcg/optimize.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/tcg/optimize.c b/tcg/optimize.c index ef5eb2cf175..fcdef25beed 100644 --- a/tcg/optimize.c +++ b/tcg/optimize.c @@ -2212,6 +2212,34 @@ static bool fold_multiply2(OptContext *ctx, TCGOp *op) tcg_opt_gen_movi(ctx, op2, rh, h); return true; } + + if (b == 0) { + op2 = opt_insert_before(ctx, op, 0, 2); + tcg_opt_gen_movi(ctx, op2, rl, 0); + tcg_opt_gen_movi(ctx, op, rh, 0); + return true; + } + if (b == 1) { + op2 = opt_insert_before(ctx, op, 0, 2); + tcg_opt_gen_mov(ctx, op2, rl, op->args[2]); + + switch (op->opc) { + case INDEX_op_mulu2: + tcg_opt_gen_movi(ctx, op, rh, 0); + break; + case INDEX_op_muls2: + op->opc = INDEX_op_sar; + op->args[0] = rh; + op->args[1] = rl; + op->args[2] = + arg_new_constant(ctx, tcg_type_size(ctx->type) * 8 - 1); + break; + default: + g_assert_not_reached(); + } + + return true; + } } return finish_folding(ctx, op); } -- 2.53.0
