@samitouri / QOSamiQemu / commits / d53c3e911c

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: