These are nearly identical to bswap, so reuse fold_bswap.
Reviewed-by: Philippe Mathieu-Daudé <[email protected]>
Signed-off-by: Richard Henderson <[email protected]>
---
tcg/optimize.c | 77 +++++++++++++++++++++++++++++---------------------
1 file changed, 45 insertions(+), 32 deletions(-)
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,7 +1497,26 @@ 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];
+ int flags = 0;
+
+ switch (op->opc) {
+ case INDEX_op_bswap16:
+ flags = op->args[2];
+ s_mask = INT16_MIN;
+ break;
+ case INDEX_op_bswap32:
+ case INDEX_op_revbit32:
+ flags = op->args[2];
+ s_mask = INT32_MIN;
+ break;
+ case INDEX_op_bswap64:
+ 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],
@@ -1491,39 +1524,16 @@ static bool fold_bswap(OptContext *ctx, TCGOp *op)
ti_const_val(t1), flags));
}
- z_mask = t1->z_mask;
- o_mask = t1->o_mask;
- s_mask = 0;
+ 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);
- 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);
+ if (flags & TCG_BSWAP_OS) {
+ /* s_mask set */
+ } else {
+ if (!(flags & TCG_BSWAP_OZ)) {
+ z_mask |= s_mask << 1;
}
- 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);
- }
- break;
- case INDEX_op_bswap64:
- z_mask = bswap64(z_mask);
- o_mask = bswap64(o_mask);
- break;
- default:
- g_assert_not_reached();
+ 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:
--
2.43.0