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>
Richard Henderson committed
Jul 30, 2026 at 15:36 UTC
d53c3e911c97c007995b79562ed695e5db0d8c29
1 file changed
+44
-31
tcg/optimize.c
+44
-31
@@ -534,6 +534,20 @@ static uint64_t do_constant_folding_2(TCGOpcode op, TCGType type,
534
case INDEX_op_bswap64:
535
return bswap64(x);
536
537
+ case INDEX_op_revbit8:
538
+ /* Note the host-utils.h revbit8 operates on uint8_t. */
539
+ if (type == TCG_TYPE_I32) {
540
+ return bswap32(revbit32(x));
541
+ }
542
+ return bswap64(revbit64(x));
543
+
544
+ case INDEX_op_revbit32:
545
+ x = revbit32(x);
546
+ return y & TCG_BSWAP_OS ? (int32_t)x : x;
547
+
548
+ case INDEX_op_revbit64:
549
+ return revbit64(x);
550
+
551
case INDEX_op_ext_i32_i64:
552
return (int32_t)x;
553
@@ -1483,49 +1497,45 @@ static bool fold_bswap(OptContext *ctx, TCGOp *op)
1497
{
1498
uint64_t z_mask, o_mask, s_mask;
1499
TempOptInfo *t1 = arg_info(op->args[1]);
1486
- int flags = op->args[2];
1487
-
1488
- if (ti_is_const(t1)) {
1489
- return tcg_opt_gen_movi(ctx, op, op->args[0],
1490
- do_constant_folding(op->opc, ctx->type,
1491
- ti_const_val(t1), flags));
1492
- }
1493
-
1494
- z_mask = t1->z_mask;
1495
- o_mask = t1->o_mask;
1496
- s_mask = 0;
1500
+ int flags = 0;
1501
1502
switch (op->opc) {
1503
case INDEX_op_bswap16:
1500
- z_mask = bswap16(z_mask);
1501
- o_mask = bswap16(o_mask);
1502
- if (flags & TCG_BSWAP_OS) {
1503
- z_mask = (int16_t)z_mask;
1504
- o_mask = (int16_t)o_mask;
1505
- s_mask = INT16_MIN;
1506
- } else if (!(flags & TCG_BSWAP_OZ)) {
1507
- z_mask |= MAKE_64BIT_MASK(16, 48);
1508
- }
1504
+ flags = op->args[2];
1505
+ s_mask = INT16_MIN;
1506
break;
1507
case INDEX_op_bswap32:
1511
- z_mask = bswap32(z_mask);
1512
- o_mask = bswap32(o_mask);
1513
- if (flags & TCG_BSWAP_OS) {
1514
- z_mask = (int32_t)z_mask;
1515
- o_mask = (int32_t)o_mask;
1516
- s_mask = INT32_MIN;
1517
- } else if (!(flags & TCG_BSWAP_OZ)) {
1518
- z_mask |= MAKE_64BIT_MASK(32, 32);
1519
- }
1508
+ case INDEX_op_revbit32:
1509
+ flags = op->args[2];
1510
+ s_mask = INT32_MIN;
1511
break;
1512
case INDEX_op_bswap64:
1522
- z_mask = bswap64(z_mask);
1523
- o_mask = bswap64(o_mask);
1513
+ case INDEX_op_revbit8:
1514
+ case INDEX_op_revbit64:
1515
+ s_mask = 0;
1516
break;
1517
default:
1518
g_assert_not_reached();
1519
}
1520
1521
+ if (ti_is_const(t1)) {
1522
+ return tcg_opt_gen_movi(ctx, op, op->args[0],
1523
+ do_constant_folding(op->opc, ctx->type,
1524
+ ti_const_val(t1), flags));
1525
+ }
1526
+
1527
+ z_mask = do_constant_folding(op->opc, ctx->type, t1->z_mask, flags);
1528
+ o_mask = do_constant_folding(op->opc, ctx->type, t1->o_mask, flags);
1529
+
1530
+ if (flags & TCG_BSWAP_OS) {
1531
+ /* s_mask set */
1532
+ } else {
1533
+ if (!(flags & TCG_BSWAP_OZ)) {
1534
+ z_mask |= s_mask << 1;
1535
+ }
1536
+ s_mask = 0;
1537
+ }
1538
+
1539
return fold_masks_zos(ctx, op, z_mask, o_mask, s_mask);
1540
}
1541
@@ -3104,6 +3114,9 @@ void tcg_optimize(TCGContext *s)
3114
case INDEX_op_bswap16:
3115
case INDEX_op_bswap32:
3116
case INDEX_op_bswap64:
3117
+ case INDEX_op_revbit8:
3118
+ case INDEX_op_revbit32:
3119
+ case INDEX_op_revbit64:
3120
done = fold_bswap(&ctx, op);
3121
break;
3122
case INDEX_op_clz: