Commit d53c3e911c for qemu.org
commit d53c3e911c97c007995b79562ed695e5db0d8c29
Author: Richard Henderson <richard.henderson@linaro.org>
Date: Thu Jul 30 15:36:35 2026 -0700
tcg/optimize: Handle revbit{8,32,64}
These are nearly identical to bswap, so reuse fold_bswap.
Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
diff --git a/tcg/optimize.c b/tcg/optimize.c
index d12babad88..facf4c1e0f 100644
--- a/tcg/optimize.c
+++ b/tcg/optimize.c
@@ -534,6 +534,20 @@ static uint64_t do_constant_folding_2(TCGOpcode op, TCGType type,
case INDEX_op_bswap64:
return bswap64(x);
+ case INDEX_op_revbit8:
+ /* Note the host-utils.h revbit8 operates on uint8_t. */
+ if (type == TCG_TYPE_I32) {
+ return bswap32(revbit32(x));
+ }
+ return bswap64(revbit64(x));
+
+ case INDEX_op_revbit32:
+ x = revbit32(x);
+ return y & TCG_BSWAP_OS ? (int32_t)x : x;
+
+ case INDEX_op_revbit64:
+ return revbit64(x);
+
case INDEX_op_ext_i32_i64:
return (int32_t)x;
@@ -1483,49 +1497,45 @@ static bool fold_bswap(OptContext *ctx, TCGOp *op)
{
uint64_t z_mask, o_mask, s_mask;
TempOptInfo *t1 = arg_info(op->args[1]);
- int flags = op->args[2];
-
- if (ti_is_const(t1)) {
- return tcg_opt_gen_movi(ctx, op, op->args[0],
- do_constant_folding(op->opc, ctx->type,
- ti_const_val(t1), flags));
- }
-
- z_mask = t1->z_mask;
- o_mask = t1->o_mask;
- s_mask = 0;
+ int flags = 0;
switch (op->opc) {
case INDEX_op_bswap16:
- z_mask = bswap16(z_mask);
- o_mask = bswap16(o_mask);
- if (flags & TCG_BSWAP_OS) {
- z_mask = (int16_t)z_mask;
- o_mask = (int16_t)o_mask;
- s_mask = INT16_MIN;
- } else if (!(flags & TCG_BSWAP_OZ)) {
- z_mask |= MAKE_64BIT_MASK(16, 48);
- }
+ flags = op->args[2];
+ s_mask = INT16_MIN;
break;
case INDEX_op_bswap32:
- z_mask = bswap32(z_mask);
- o_mask = bswap32(o_mask);
- if (flags & TCG_BSWAP_OS) {
- z_mask = (int32_t)z_mask;
- o_mask = (int32_t)o_mask;
- s_mask = INT32_MIN;
- } else if (!(flags & TCG_BSWAP_OZ)) {
- z_mask |= MAKE_64BIT_MASK(32, 32);
- }
+ case INDEX_op_revbit32:
+ flags = op->args[2];
+ s_mask = INT32_MIN;
break;
case INDEX_op_bswap64:
- z_mask = bswap64(z_mask);
- o_mask = bswap64(o_mask);
+ case INDEX_op_revbit8:
+ case INDEX_op_revbit64:
+ s_mask = 0;
break;
default:
g_assert_not_reached();
}
+ if (ti_is_const(t1)) {
+ return tcg_opt_gen_movi(ctx, op, op->args[0],
+ do_constant_folding(op->opc, ctx->type,
+ ti_const_val(t1), flags));
+ }
+
+ z_mask = do_constant_folding(op->opc, ctx->type, t1->z_mask, flags);
+ o_mask = do_constant_folding(op->opc, ctx->type, t1->o_mask, flags);
+
+ if (flags & TCG_BSWAP_OS) {
+ /* s_mask set */
+ } else {
+ if (!(flags & TCG_BSWAP_OZ)) {
+ z_mask |= s_mask << 1;
+ }
+ s_mask = 0;
+ }
+
return fold_masks_zos(ctx, op, z_mask, o_mask, s_mask);
}
@@ -3104,6 +3114,9 @@ void tcg_optimize(TCGContext *s)
case INDEX_op_bswap16:
case INDEX_op_bswap32:
case INDEX_op_bswap64:
+ case INDEX_op_revbit8:
+ case INDEX_op_revbit32:
+ case INDEX_op_revbit64:
done = fold_bswap(&ctx, op);
break;
case INDEX_op_clz: