diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2023-08-13 11:03:05 -0700 |
---|---|---|
committer | Richard Henderson <richard.henderson@linaro.org> | 2023-08-24 11:22:42 -0700 |
commit | 8f7a840d7df92ecbf78802e54eee52e82aa55383 (patch) | |
tree | 5cf72a98b657466ea77c383ff3cd0c4fb44eb52c /tcg | |
parent | 36df88c0405aafa747d3ee04c3d96f81827841f7 (diff) | |
download | qemu-8f7a840d7df92ecbf78802e54eee52e82aa55383.zip qemu-8f7a840d7df92ecbf78802e54eee52e82aa55383.tar.gz qemu-8f7a840d7df92ecbf78802e54eee52e82aa55383.tar.bz2 |
tcg: Fold deposit with zero to and
Inserting a zero into a value, or inserting a value
into zero at offset 0 may be implemented with AND.
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'tcg')
-rw-r--r-- | tcg/optimize.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/tcg/optimize.c b/tcg/optimize.c index d215636..bbd9bb6 100644 --- a/tcg/optimize.c +++ b/tcg/optimize.c @@ -1279,6 +1279,8 @@ static bool fold_ctpop(OptContext *ctx, TCGOp *op) static bool fold_deposit(OptContext *ctx, TCGOp *op) { + TCGOpcode and_opc; + if (arg_is_const(op->args[1]) && arg_is_const(op->args[2])) { uint64_t t1 = arg_info(op->args[1])->val; uint64_t t2 = arg_info(op->args[2])->val; @@ -1287,6 +1289,41 @@ static bool fold_deposit(OptContext *ctx, TCGOp *op) return tcg_opt_gen_movi(ctx, op, op->args[0], t1); } + switch (ctx->type) { + case TCG_TYPE_I32: + and_opc = INDEX_op_and_i32; + break; + case TCG_TYPE_I64: + and_opc = INDEX_op_and_i64; + break; + default: + g_assert_not_reached(); + } + + /* Inserting a value into zero at offset 0. */ + if (arg_is_const(op->args[1]) + && arg_info(op->args[1])->val == 0 + && op->args[3] == 0) { + uint64_t mask = MAKE_64BIT_MASK(0, op->args[4]); + + op->opc = and_opc; + op->args[1] = op->args[2]; + op->args[2] = temp_arg(tcg_constant_internal(ctx->type, mask)); + ctx->z_mask = mask & arg_info(op->args[1])->z_mask; + return false; + } + + /* Inserting zero into a value. */ + if (arg_is_const(op->args[2]) + && arg_info(op->args[2])->val == 0) { + uint64_t mask = deposit64(-1, op->args[3], op->args[4], 0); + + op->opc = and_opc; + op->args[2] = temp_arg(tcg_constant_internal(ctx->type, mask)); + ctx->z_mask = mask & arg_info(op->args[1])->z_mask; + return false; + } + ctx->z_mask = deposit64(arg_info(op->args[1])->z_mask, op->args[3], op->args[4], arg_info(op->args[2])->z_mask); |