Lines Matching refs:op

356 static bool tcg_opt_gen_mov(OptContext *ctx, TCGOp *op, TCGArg dst, TCGArg src)  in tcg_opt_gen_mov()  argument
365 tcg_op_remove(ctx->tcg, op); in tcg_opt_gen_mov()
389 op->opc = new_op; in tcg_opt_gen_mov()
390 op->args[0] = dst; in tcg_opt_gen_mov()
391 op->args[1] = src; in tcg_opt_gen_mov()
414 static bool tcg_opt_gen_movi(OptContext *ctx, TCGOp *op, in tcg_opt_gen_movi() argument
418 return tcg_opt_gen_mov(ctx, op, dst, arg_new_constant(ctx, val)); in tcg_opt_gen_movi()
421 static uint64_t do_constant_folding_2(TCGOpcode op, uint64_t x, uint64_t y) in do_constant_folding_2() argument
425 switch (op) { in do_constant_folding_2()
584 static uint64_t do_constant_folding(TCGOpcode op, TCGType type, in do_constant_folding() argument
587 uint64_t res = do_constant_folding_2(op, x, y); in do_constant_folding()
788 static void init_arguments(OptContext *ctx, TCGOp *op, int nb_args) in init_arguments() argument
791 TCGTemp *ts = arg_temp(op->args[i]); in init_arguments()
796 static void copy_propagate(OptContext *ctx, TCGOp *op, in copy_propagate() argument
800 TCGTemp *ts = arg_temp(op->args[i]); in copy_propagate()
802 op->args[i] = temp_arg(find_better_copy(ts)); in copy_propagate()
807 static void finish_folding(OptContext *ctx, TCGOp *op) in finish_folding() argument
809 const TCGOpDef *def = &tcg_op_defs[op->opc]; in finish_folding()
827 TCGTemp *ts = arg_temp(op->args[i]); in finish_folding()
851 static bool fold_const1(OptContext *ctx, TCGOp *op) in fold_const1() argument
853 if (arg_is_const(op->args[1])) { in fold_const1()
856 t = arg_info(op->args[1])->val; in fold_const1()
857 t = do_constant_folding(op->opc, ctx->type, t, 0); in fold_const1()
858 return tcg_opt_gen_movi(ctx, op, op->args[0], t); in fold_const1()
863 static bool fold_const2(OptContext *ctx, TCGOp *op) in fold_const2() argument
865 if (arg_is_const(op->args[1]) && arg_is_const(op->args[2])) { in fold_const2()
866 uint64_t t1 = arg_info(op->args[1])->val; in fold_const2()
867 uint64_t t2 = arg_info(op->args[2])->val; in fold_const2()
869 t1 = do_constant_folding(op->opc, ctx->type, t1, t2); in fold_const2()
870 return tcg_opt_gen_movi(ctx, op, op->args[0], t1); in fold_const2()
875 static bool fold_commutative(OptContext *ctx, TCGOp *op) in fold_commutative() argument
877 swap_commutative(op->args[0], &op->args[1], &op->args[2]); in fold_commutative()
881 static bool fold_const2_commutative(OptContext *ctx, TCGOp *op) in fold_const2_commutative() argument
883 swap_commutative(op->args[0], &op->args[1], &op->args[2]); in fold_const2_commutative()
884 return fold_const2(ctx, op); in fold_const2_commutative()
887 static bool fold_masks(OptContext *ctx, TCGOp *op) in fold_masks() argument
909 return tcg_opt_gen_movi(ctx, op, op->args[0], 0); in fold_masks()
912 return tcg_opt_gen_mov(ctx, op, op->args[0], op->args[1]); in fold_masks()
922 static bool fold_not(OptContext *ctx, TCGOp *op);
923 static bool fold_to_not(OptContext *ctx, TCGOp *op, int idx) in fold_to_not() argument
947 op->opc = not_op; in fold_to_not()
948 op->args[1] = op->args[idx]; in fold_to_not()
949 return fold_not(ctx, op); in fold_to_not()
955 static bool fold_ix_to_i(OptContext *ctx, TCGOp *op, uint64_t i) in fold_ix_to_i() argument
957 if (arg_is_const(op->args[1]) && arg_info(op->args[1])->val == i) { in fold_ix_to_i()
958 return tcg_opt_gen_movi(ctx, op, op->args[0], i); in fold_ix_to_i()
964 static bool fold_ix_to_not(OptContext *ctx, TCGOp *op, uint64_t i) in fold_ix_to_not() argument
966 if (arg_is_const(op->args[1]) && arg_info(op->args[1])->val == i) { in fold_ix_to_not()
967 return fold_to_not(ctx, op, 2); in fold_ix_to_not()
973 static bool fold_xi_to_i(OptContext *ctx, TCGOp *op, uint64_t i) in fold_xi_to_i() argument
975 if (arg_is_const(op->args[2]) && arg_info(op->args[2])->val == i) { in fold_xi_to_i()
976 return tcg_opt_gen_movi(ctx, op, op->args[0], i); in fold_xi_to_i()
982 static bool fold_xi_to_x(OptContext *ctx, TCGOp *op, uint64_t i) in fold_xi_to_x() argument
984 if (arg_is_const(op->args[2]) && arg_info(op->args[2])->val == i) { in fold_xi_to_x()
985 return tcg_opt_gen_mov(ctx, op, op->args[0], op->args[1]); in fold_xi_to_x()
991 static bool fold_xi_to_not(OptContext *ctx, TCGOp *op, uint64_t i) in fold_xi_to_not() argument
993 if (arg_is_const(op->args[2]) && arg_info(op->args[2])->val == i) { in fold_xi_to_not()
994 return fold_to_not(ctx, op, 1); in fold_xi_to_not()
1000 static bool fold_xx_to_i(OptContext *ctx, TCGOp *op, uint64_t i) in fold_xx_to_i() argument
1002 if (args_are_copies(op->args[1], op->args[2])) { in fold_xx_to_i()
1003 return tcg_opt_gen_movi(ctx, op, op->args[0], i); in fold_xx_to_i()
1009 static bool fold_xx_to_x(OptContext *ctx, TCGOp *op) in fold_xx_to_x() argument
1011 if (args_are_copies(op->args[1], op->args[2])) { in fold_xx_to_x()
1012 return tcg_opt_gen_mov(ctx, op, op->args[0], op->args[1]); in fold_xx_to_x()
1026 static bool fold_add(OptContext *ctx, TCGOp *op) in fold_add() argument
1028 if (fold_const2_commutative(ctx, op) || in fold_add()
1029 fold_xi_to_x(ctx, op, 0)) { in fold_add()
1036 static bool fold_add_vec(OptContext *ctx, TCGOp *op) in fold_add_vec() argument
1038 if (fold_commutative(ctx, op) || in fold_add_vec()
1039 fold_xi_to_x(ctx, op, 0)) { in fold_add_vec()
1045 static bool fold_addsub2(OptContext *ctx, TCGOp *op, bool add) in fold_addsub2() argument
1047 bool a_const = arg_is_const(op->args[2]) && arg_is_const(op->args[3]); in fold_addsub2()
1048 bool b_const = arg_is_const(op->args[4]) && arg_is_const(op->args[5]); in fold_addsub2()
1051 uint64_t al = arg_info(op->args[2])->val; in fold_addsub2()
1052 uint64_t ah = arg_info(op->args[3])->val; in fold_addsub2()
1053 uint64_t bl = arg_info(op->args[4])->val; in fold_addsub2()
1054 uint64_t bh = arg_info(op->args[5])->val; in fold_addsub2()
1084 rl = op->args[0]; in fold_addsub2()
1085 rh = op->args[1]; in fold_addsub2()
1088 op2 = tcg_op_insert_before(ctx->tcg, op, 0, 2); in fold_addsub2()
1090 tcg_opt_gen_movi(ctx, op, rl, al); in fold_addsub2()
1097 uint64_t bl = arg_info(op->args[4])->val; in fold_addsub2()
1098 uint64_t bh = arg_info(op->args[5])->val; in fold_addsub2()
1104 op->opc = (ctx->type == TCG_TYPE_I32 in fold_addsub2()
1106 op->args[4] = arg_new_constant(ctx, bl); in fold_addsub2()
1107 op->args[5] = arg_new_constant(ctx, bh); in fold_addsub2()
1112 static bool fold_add2(OptContext *ctx, TCGOp *op) in fold_add2() argument
1115 swap_commutative(op->args[0], &op->args[2], &op->args[4]); in fold_add2()
1116 swap_commutative(op->args[1], &op->args[3], &op->args[5]); in fold_add2()
1118 return fold_addsub2(ctx, op, true); in fold_add2()
1121 static bool fold_and(OptContext *ctx, TCGOp *op) in fold_and() argument
1125 if (fold_const2_commutative(ctx, op) || in fold_and()
1126 fold_xi_to_i(ctx, op, 0) || in fold_and()
1127 fold_xi_to_x(ctx, op, -1) || in fold_and()
1128 fold_xx_to_x(ctx, op)) { in fold_and()
1132 z1 = arg_info(op->args[1])->z_mask; in fold_and()
1133 z2 = arg_info(op->args[2])->z_mask; in fold_and()
1140 ctx->s_mask = arg_info(op->args[1])->s_mask in fold_and()
1141 & arg_info(op->args[2])->s_mask; in fold_and()
1147 if (arg_is_const(op->args[2])) { in fold_and()
1151 return fold_masks(ctx, op); in fold_and()
1154 static bool fold_andc(OptContext *ctx, TCGOp *op) in fold_andc() argument
1158 if (fold_const2(ctx, op) || in fold_andc()
1159 fold_xx_to_i(ctx, op, 0) || in fold_andc()
1160 fold_xi_to_x(ctx, op, 0) || in fold_andc()
1161 fold_ix_to_not(ctx, op, -1)) { in fold_andc()
1165 z1 = arg_info(op->args[1])->z_mask; in fold_andc()
1171 if (arg_is_const(op->args[2])) { in fold_andc()
1172 uint64_t z2 = ~arg_info(op->args[2])->z_mask; in fold_andc()
1178 ctx->s_mask = arg_info(op->args[1])->s_mask in fold_andc()
1179 & arg_info(op->args[2])->s_mask; in fold_andc()
1180 return fold_masks(ctx, op); in fold_andc()
1183 static bool fold_brcond(OptContext *ctx, TCGOp *op) in fold_brcond() argument
1185 TCGCond cond = op->args[2]; in fold_brcond()
1188 if (swap_commutative(NO_DEST, &op->args[0], &op->args[1])) { in fold_brcond()
1189 op->args[2] = cond = tcg_swap_cond(cond); in fold_brcond()
1192 i = do_constant_folding_cond(ctx->type, op->args[0], op->args[1], cond); in fold_brcond()
1194 tcg_op_remove(ctx->tcg, op); in fold_brcond()
1198 op->opc = INDEX_op_br; in fold_brcond()
1199 op->args[0] = op->args[3]; in fold_brcond()
1204 static bool fold_brcond2(OptContext *ctx, TCGOp *op) in fold_brcond2() argument
1206 TCGCond cond = op->args[4]; in fold_brcond2()
1207 TCGArg label = op->args[5]; in fold_brcond2()
1210 if (swap_commutative2(&op->args[0], &op->args[2])) { in fold_brcond2()
1211 op->args[4] = cond = tcg_swap_cond(cond); in fold_brcond2()
1214 i = do_constant_folding_cond2(&op->args[0], &op->args[2], cond); in fold_brcond2()
1226 if (arg_is_const(op->args[2]) && arg_info(op->args[2])->val == 0 && in fold_brcond2()
1227 arg_is_const(op->args[3]) && arg_info(op->args[3])->val == 0) { in fold_brcond2()
1240 i = do_constant_folding_cond(TCG_TYPE_I32, op->args[0], in fold_brcond2()
1241 op->args[2], cond); in fold_brcond2()
1249 i = do_constant_folding_cond(TCG_TYPE_I32, op->args[1], in fold_brcond2()
1250 op->args[3], cond); in fold_brcond2()
1255 op->opc = INDEX_op_brcond_i32; in fold_brcond2()
1256 op->args[1] = op->args[2]; in fold_brcond2()
1257 op->args[2] = cond; in fold_brcond2()
1258 op->args[3] = label; in fold_brcond2()
1267 op->opc = INDEX_op_brcond_i32; in fold_brcond2()
1268 op->args[0] = op->args[1]; in fold_brcond2()
1269 op->args[1] = op->args[3]; in fold_brcond2()
1270 op->args[2] = cond; in fold_brcond2()
1271 op->args[3] = label; in fold_brcond2()
1276 tcg_op_remove(ctx->tcg, op); in fold_brcond2()
1279 op->opc = INDEX_op_br; in fold_brcond2()
1280 op->args[0] = label; in fold_brcond2()
1286 static bool fold_bswap(OptContext *ctx, TCGOp *op) in fold_bswap() argument
1290 if (arg_is_const(op->args[1])) { in fold_bswap()
1291 uint64_t t = arg_info(op->args[1])->val; in fold_bswap()
1293 t = do_constant_folding(op->opc, ctx->type, t, op->args[2]); in fold_bswap()
1294 return tcg_opt_gen_movi(ctx, op, op->args[0], t); in fold_bswap()
1297 z_mask = arg_info(op->args[1])->z_mask; in fold_bswap()
1299 switch (op->opc) { in fold_bswap()
1319 switch (op->args[2] & (TCG_BSWAP_OZ | TCG_BSWAP_OS)) { in fold_bswap()
1338 return fold_masks(ctx, op); in fold_bswap()
1341 static bool fold_call(OptContext *ctx, TCGOp *op) in fold_call() argument
1344 int nb_oargs = TCGOP_CALLO(op); in fold_call()
1345 int nb_iargs = TCGOP_CALLI(op); in fold_call()
1348 init_arguments(ctx, op, nb_oargs + nb_iargs); in fold_call()
1349 copy_propagate(ctx, op, nb_oargs, nb_iargs); in fold_call()
1352 flags = tcg_call_flags(op); in fold_call()
1370 reset_temp(ctx, op->args[i]); in fold_call()
1378 static bool fold_count_zeros(OptContext *ctx, TCGOp *op) in fold_count_zeros() argument
1382 if (arg_is_const(op->args[1])) { in fold_count_zeros()
1383 uint64_t t = arg_info(op->args[1])->val; in fold_count_zeros()
1386 t = do_constant_folding(op->opc, ctx->type, t, 0); in fold_count_zeros()
1387 return tcg_opt_gen_movi(ctx, op, op->args[0], t); in fold_count_zeros()
1389 return tcg_opt_gen_mov(ctx, op, op->args[0], op->args[2]); in fold_count_zeros()
1402 ctx->z_mask = arg_info(op->args[2])->z_mask | z_mask; in fold_count_zeros()
1407 static bool fold_ctpop(OptContext *ctx, TCGOp *op) in fold_ctpop() argument
1409 if (fold_const1(ctx, op)) { in fold_ctpop()
1427 static bool fold_deposit(OptContext *ctx, TCGOp *op) in fold_deposit() argument
1431 if (arg_is_const(op->args[1]) && arg_is_const(op->args[2])) { in fold_deposit()
1432 uint64_t t1 = arg_info(op->args[1])->val; in fold_deposit()
1433 uint64_t t2 = arg_info(op->args[2])->val; in fold_deposit()
1435 t1 = deposit64(t1, op->args[3], op->args[4], t2); in fold_deposit()
1436 return tcg_opt_gen_movi(ctx, op, op->args[0], t1); in fold_deposit()
1451 if (arg_is_const(op->args[1]) in fold_deposit()
1452 && arg_info(op->args[1])->val == 0 in fold_deposit()
1453 && op->args[3] == 0) { in fold_deposit()
1454 uint64_t mask = MAKE_64BIT_MASK(0, op->args[4]); in fold_deposit()
1456 op->opc = and_opc; in fold_deposit()
1457 op->args[1] = op->args[2]; in fold_deposit()
1458 op->args[2] = arg_new_constant(ctx, mask); in fold_deposit()
1459 ctx->z_mask = mask & arg_info(op->args[1])->z_mask; in fold_deposit()
1464 if (arg_is_const(op->args[2]) in fold_deposit()
1465 && arg_info(op->args[2])->val == 0) { in fold_deposit()
1466 uint64_t mask = deposit64(-1, op->args[3], op->args[4], 0); in fold_deposit()
1468 op->opc = and_opc; in fold_deposit()
1469 op->args[2] = arg_new_constant(ctx, mask); in fold_deposit()
1470 ctx->z_mask = mask & arg_info(op->args[1])->z_mask; in fold_deposit()
1474 ctx->z_mask = deposit64(arg_info(op->args[1])->z_mask, in fold_deposit()
1475 op->args[3], op->args[4], in fold_deposit()
1476 arg_info(op->args[2])->z_mask); in fold_deposit()
1480 static bool fold_divide(OptContext *ctx, TCGOp *op) in fold_divide() argument
1482 if (fold_const2(ctx, op) || in fold_divide()
1483 fold_xi_to_x(ctx, op, 1)) { in fold_divide()
1489 static bool fold_dup(OptContext *ctx, TCGOp *op) in fold_dup() argument
1491 if (arg_is_const(op->args[1])) { in fold_dup()
1492 uint64_t t = arg_info(op->args[1])->val; in fold_dup()
1493 t = dup_const(TCGOP_VECE(op), t); in fold_dup()
1494 return tcg_opt_gen_movi(ctx, op, op->args[0], t); in fold_dup()
1499 static bool fold_dup2(OptContext *ctx, TCGOp *op) in fold_dup2() argument
1501 if (arg_is_const(op->args[1]) && arg_is_const(op->args[2])) { in fold_dup2()
1502 uint64_t t = deposit64(arg_info(op->args[1])->val, 32, 32, in fold_dup2()
1503 arg_info(op->args[2])->val); in fold_dup2()
1504 return tcg_opt_gen_movi(ctx, op, op->args[0], t); in fold_dup2()
1507 if (args_are_copies(op->args[1], op->args[2])) { in fold_dup2()
1508 op->opc = INDEX_op_dup_vec; in fold_dup2()
1509 TCGOP_VECE(op) = MO_32; in fold_dup2()
1514 static bool fold_eqv(OptContext *ctx, TCGOp *op) in fold_eqv() argument
1516 if (fold_const2_commutative(ctx, op) || in fold_eqv()
1517 fold_xi_to_x(ctx, op, -1) || in fold_eqv()
1518 fold_xi_to_not(ctx, op, 0)) { in fold_eqv()
1522 ctx->s_mask = arg_info(op->args[1])->s_mask in fold_eqv()
1523 & arg_info(op->args[2])->s_mask; in fold_eqv()
1527 static bool fold_extract(OptContext *ctx, TCGOp *op) in fold_extract() argument
1530 int pos = op->args[2]; in fold_extract()
1531 int len = op->args[3]; in fold_extract()
1533 if (arg_is_const(op->args[1])) { in fold_extract()
1536 t = arg_info(op->args[1])->val; in fold_extract()
1538 return tcg_opt_gen_movi(ctx, op, op->args[0], t); in fold_extract()
1541 z_mask_old = arg_info(op->args[1])->z_mask; in fold_extract()
1549 return fold_masks(ctx, op); in fold_extract()
1552 static bool fold_extract2(OptContext *ctx, TCGOp *op) in fold_extract2() argument
1554 if (arg_is_const(op->args[1]) && arg_is_const(op->args[2])) { in fold_extract2()
1555 uint64_t v1 = arg_info(op->args[1])->val; in fold_extract2()
1556 uint64_t v2 = arg_info(op->args[2])->val; in fold_extract2()
1557 int shr = op->args[3]; in fold_extract2()
1559 if (op->opc == INDEX_op_extract2_i64) { in fold_extract2()
1566 return tcg_opt_gen_movi(ctx, op, op->args[0], v1 | v2); in fold_extract2()
1571 static bool fold_exts(OptContext *ctx, TCGOp *op) in fold_exts() argument
1576 if (fold_const1(ctx, op)) { in fold_exts()
1580 z_mask = arg_info(op->args[1])->z_mask; in fold_exts()
1581 s_mask = arg_info(op->args[1])->s_mask; in fold_exts()
1584 switch (op->opc) { in fold_exts()
1615 return fold_masks(ctx, op); in fold_exts()
1618 static bool fold_extu(OptContext *ctx, TCGOp *op) in fold_extu() argument
1623 if (fold_const1(ctx, op)) { in fold_extu()
1627 z_mask_old = z_mask = arg_info(op->args[1])->z_mask; in fold_extu()
1629 switch (op->opc) { in fold_extu()
1656 return fold_masks(ctx, op); in fold_extu()
1659 static bool fold_mb(OptContext *ctx, TCGOp *op) in fold_mb() argument
1675 ctx->prev_mb->args[0] |= op->args[0]; in fold_mb()
1676 tcg_op_remove(ctx->tcg, op); in fold_mb()
1678 ctx->prev_mb = op; in fold_mb()
1683 static bool fold_mov(OptContext *ctx, TCGOp *op) in fold_mov() argument
1685 return tcg_opt_gen_mov(ctx, op, op->args[0], op->args[1]); in fold_mov()
1688 static bool fold_movcond(OptContext *ctx, TCGOp *op) in fold_movcond() argument
1690 TCGCond cond = op->args[5]; in fold_movcond()
1693 if (swap_commutative(NO_DEST, &op->args[1], &op->args[2])) { in fold_movcond()
1694 op->args[5] = cond = tcg_swap_cond(cond); in fold_movcond()
1700 if (swap_commutative(op->args[0], &op->args[4], &op->args[3])) { in fold_movcond()
1701 op->args[5] = cond = tcg_invert_cond(cond); in fold_movcond()
1704 i = do_constant_folding_cond(ctx->type, op->args[1], op->args[2], cond); in fold_movcond()
1706 return tcg_opt_gen_mov(ctx, op, op->args[0], op->args[4 - i]); in fold_movcond()
1709 ctx->z_mask = arg_info(op->args[3])->z_mask in fold_movcond()
1710 | arg_info(op->args[4])->z_mask; in fold_movcond()
1711 ctx->s_mask = arg_info(op->args[3])->s_mask in fold_movcond()
1712 & arg_info(op->args[4])->s_mask; in fold_movcond()
1714 if (arg_is_const(op->args[3]) && arg_is_const(op->args[4])) { in fold_movcond()
1715 uint64_t tv = arg_info(op->args[3])->val; in fold_movcond()
1716 uint64_t fv = arg_info(op->args[4])->val; in fold_movcond()
1739 op->opc = opc; in fold_movcond()
1740 op->args[3] = cond; in fold_movcond()
1742 op->opc = opc; in fold_movcond()
1743 op->args[3] = tcg_invert_cond(cond); in fold_movcond()
1746 op->opc = negopc; in fold_movcond()
1747 op->args[3] = cond; in fold_movcond()
1749 op->opc = negopc; in fold_movcond()
1750 op->args[3] = tcg_invert_cond(cond); in fold_movcond()
1757 static bool fold_mul(OptContext *ctx, TCGOp *op) in fold_mul() argument
1759 if (fold_const2(ctx, op) || in fold_mul()
1760 fold_xi_to_i(ctx, op, 0) || in fold_mul()
1761 fold_xi_to_x(ctx, op, 1)) { in fold_mul()
1767 static bool fold_mul_highpart(OptContext *ctx, TCGOp *op) in fold_mul_highpart() argument
1769 if (fold_const2_commutative(ctx, op) || in fold_mul_highpart()
1770 fold_xi_to_i(ctx, op, 0)) { in fold_mul_highpart()
1776 static bool fold_multiply2(OptContext *ctx, TCGOp *op) in fold_multiply2() argument
1778 swap_commutative(op->args[0], &op->args[2], &op->args[3]); in fold_multiply2()
1780 if (arg_is_const(op->args[2]) && arg_is_const(op->args[3])) { in fold_multiply2()
1781 uint64_t a = arg_info(op->args[2])->val; in fold_multiply2()
1782 uint64_t b = arg_info(op->args[3])->val; in fold_multiply2()
1787 switch (op->opc) { in fold_multiply2()
1808 rl = op->args[0]; in fold_multiply2()
1809 rh = op->args[1]; in fold_multiply2()
1812 op2 = tcg_op_insert_before(ctx->tcg, op, 0, 2); in fold_multiply2()
1814 tcg_opt_gen_movi(ctx, op, rl, l); in fold_multiply2()
1821 static bool fold_nand(OptContext *ctx, TCGOp *op) in fold_nand() argument
1823 if (fold_const2_commutative(ctx, op) || in fold_nand()
1824 fold_xi_to_not(ctx, op, -1)) { in fold_nand()
1828 ctx->s_mask = arg_info(op->args[1])->s_mask in fold_nand()
1829 & arg_info(op->args[2])->s_mask; in fold_nand()
1833 static bool fold_neg(OptContext *ctx, TCGOp *op) in fold_neg() argument
1837 if (fold_const1(ctx, op)) { in fold_neg()
1842 z_mask = arg_info(op->args[1])->z_mask; in fold_neg()
1849 finish_folding(ctx, op); in fold_neg()
1853 static bool fold_nor(OptContext *ctx, TCGOp *op) in fold_nor() argument
1855 if (fold_const2_commutative(ctx, op) || in fold_nor()
1856 fold_xi_to_not(ctx, op, 0)) { in fold_nor()
1860 ctx->s_mask = arg_info(op->args[1])->s_mask in fold_nor()
1861 & arg_info(op->args[2])->s_mask; in fold_nor()
1865 static bool fold_not(OptContext *ctx, TCGOp *op) in fold_not() argument
1867 if (fold_const1(ctx, op)) { in fold_not()
1871 ctx->s_mask = arg_info(op->args[1])->s_mask; in fold_not()
1874 finish_folding(ctx, op); in fold_not()
1878 static bool fold_or(OptContext *ctx, TCGOp *op) in fold_or() argument
1880 if (fold_const2_commutative(ctx, op) || in fold_or()
1881 fold_xi_to_x(ctx, op, 0) || in fold_or()
1882 fold_xx_to_x(ctx, op)) { in fold_or()
1886 ctx->z_mask = arg_info(op->args[1])->z_mask in fold_or()
1887 | arg_info(op->args[2])->z_mask; in fold_or()
1888 ctx->s_mask = arg_info(op->args[1])->s_mask in fold_or()
1889 & arg_info(op->args[2])->s_mask; in fold_or()
1890 return fold_masks(ctx, op); in fold_or()
1893 static bool fold_orc(OptContext *ctx, TCGOp *op) in fold_orc() argument
1895 if (fold_const2(ctx, op) || in fold_orc()
1896 fold_xx_to_i(ctx, op, -1) || in fold_orc()
1897 fold_xi_to_x(ctx, op, -1) || in fold_orc()
1898 fold_ix_to_not(ctx, op, 0)) { in fold_orc()
1902 ctx->s_mask = arg_info(op->args[1])->s_mask in fold_orc()
1903 & arg_info(op->args[2])->s_mask; in fold_orc()
1907 static bool fold_qemu_ld(OptContext *ctx, TCGOp *op) in fold_qemu_ld() argument
1909 const TCGOpDef *def = &tcg_op_defs[op->opc]; in fold_qemu_ld()
1910 MemOpIdx oi = op->args[def->nb_oargs + def->nb_iargs]; in fold_qemu_ld()
1927 static bool fold_qemu_st(OptContext *ctx, TCGOp *op) in fold_qemu_st() argument
1934 static bool fold_remainder(OptContext *ctx, TCGOp *op) in fold_remainder() argument
1936 if (fold_const2(ctx, op) || in fold_remainder()
1937 fold_xx_to_i(ctx, op, 0)) { in fold_remainder()
1943 static bool fold_setcond(OptContext *ctx, TCGOp *op) in fold_setcond() argument
1945 TCGCond cond = op->args[3]; in fold_setcond()
1948 if (swap_commutative(op->args[0], &op->args[1], &op->args[2])) { in fold_setcond()
1949 op->args[3] = cond = tcg_swap_cond(cond); in fold_setcond()
1952 i = do_constant_folding_cond(ctx->type, op->args[1], op->args[2], cond); in fold_setcond()
1954 return tcg_opt_gen_movi(ctx, op, op->args[0], i); in fold_setcond()
1962 static bool fold_negsetcond(OptContext *ctx, TCGOp *op) in fold_negsetcond() argument
1964 TCGCond cond = op->args[3]; in fold_negsetcond()
1967 if (swap_commutative(op->args[0], &op->args[1], &op->args[2])) { in fold_negsetcond()
1968 op->args[3] = cond = tcg_swap_cond(cond); in fold_negsetcond()
1971 i = do_constant_folding_cond(ctx->type, op->args[1], op->args[2], cond); in fold_negsetcond()
1973 return tcg_opt_gen_movi(ctx, op, op->args[0], -i); in fold_negsetcond()
1982 static bool fold_setcond2(OptContext *ctx, TCGOp *op) in fold_setcond2() argument
1984 TCGCond cond = op->args[5]; in fold_setcond2()
1987 if (swap_commutative2(&op->args[1], &op->args[3])) { in fold_setcond2()
1988 op->args[5] = cond = tcg_swap_cond(cond); in fold_setcond2()
1991 i = do_constant_folding_cond2(&op->args[1], &op->args[3], cond); in fold_setcond2()
2003 if (arg_is_const(op->args[3]) && arg_info(op->args[3])->val == 0 && in fold_setcond2()
2004 arg_is_const(op->args[4]) && arg_info(op->args[4])->val == 0) { in fold_setcond2()
2017 i = do_constant_folding_cond(TCG_TYPE_I32, op->args[1], in fold_setcond2()
2018 op->args[3], cond); in fold_setcond2()
2026 i = do_constant_folding_cond(TCG_TYPE_I32, op->args[2], in fold_setcond2()
2027 op->args[4], cond); in fold_setcond2()
2032 op->args[2] = op->args[3]; in fold_setcond2()
2033 op->args[3] = cond; in fold_setcond2()
2034 op->opc = INDEX_op_setcond_i32; in fold_setcond2()
2043 op->args[1] = op->args[2]; in fold_setcond2()
2044 op->args[2] = op->args[4]; in fold_setcond2()
2045 op->args[3] = cond; in fold_setcond2()
2046 op->opc = INDEX_op_setcond_i32; in fold_setcond2()
2055 return tcg_opt_gen_movi(ctx, op, op->args[0], i); in fold_setcond2()
2058 static bool fold_sextract(OptContext *ctx, TCGOp *op) in fold_sextract() argument
2061 int pos = op->args[2]; in fold_sextract()
2062 int len = op->args[3]; in fold_sextract()
2064 if (arg_is_const(op->args[1])) { in fold_sextract()
2067 t = arg_info(op->args[1])->val; in fold_sextract()
2069 return tcg_opt_gen_movi(ctx, op, op->args[0], t); in fold_sextract()
2072 z_mask = arg_info(op->args[1])->z_mask; in fold_sextract()
2076 s_mask_old = arg_info(op->args[1])->s_mask; in fold_sextract()
2085 return fold_masks(ctx, op); in fold_sextract()
2088 static bool fold_shift(OptContext *ctx, TCGOp *op) in fold_shift() argument
2092 if (fold_const2(ctx, op) || in fold_shift()
2093 fold_ix_to_i(ctx, op, 0) || in fold_shift()
2094 fold_xi_to_x(ctx, op, 0)) { in fold_shift()
2098 s_mask = arg_info(op->args[1])->s_mask; in fold_shift()
2099 z_mask = arg_info(op->args[1])->z_mask; in fold_shift()
2101 if (arg_is_const(op->args[2])) { in fold_shift()
2102 int sh = arg_info(op->args[2])->val; in fold_shift()
2104 ctx->z_mask = do_constant_folding(op->opc, ctx->type, z_mask, sh); in fold_shift()
2106 s_mask = do_constant_folding(op->opc, ctx->type, s_mask, sh); in fold_shift()
2109 return fold_masks(ctx, op); in fold_shift()
2112 switch (op->opc) { in fold_shift()
2137 static bool fold_sub_to_neg(OptContext *ctx, TCGOp *op) in fold_sub_to_neg() argument
2142 if (!arg_is_const(op->args[1]) || arg_info(op->args[1])->val != 0) { in fold_sub_to_neg()
2160 tcg_can_emit_vec_op(neg_op, ctx->type, TCGOP_VECE(op)) > 0); in fold_sub_to_neg()
2166 op->opc = neg_op; in fold_sub_to_neg()
2167 op->args[1] = op->args[2]; in fold_sub_to_neg()
2168 return fold_neg(ctx, op); in fold_sub_to_neg()
2174 static bool fold_sub_vec(OptContext *ctx, TCGOp *op) in fold_sub_vec() argument
2176 if (fold_xx_to_i(ctx, op, 0) || in fold_sub_vec()
2177 fold_xi_to_x(ctx, op, 0) || in fold_sub_vec()
2178 fold_sub_to_neg(ctx, op)) { in fold_sub_vec()
2184 static bool fold_sub(OptContext *ctx, TCGOp *op) in fold_sub() argument
2186 if (fold_const2(ctx, op) || fold_sub_vec(ctx, op)) { in fold_sub()
2191 if (arg_is_const(op->args[2])) { in fold_sub()
2192 uint64_t val = arg_info(op->args[2])->val; in fold_sub()
2194 op->opc = (ctx->type == TCG_TYPE_I32 in fold_sub()
2196 op->args[2] = arg_new_constant(ctx, -val); in fold_sub()
2201 static bool fold_sub2(OptContext *ctx, TCGOp *op) in fold_sub2() argument
2203 return fold_addsub2(ctx, op, false); in fold_sub2()
2206 static bool fold_tcg_ld(OptContext *ctx, TCGOp *op) in fold_tcg_ld() argument
2209 switch (op->opc) { in fold_tcg_ld()
2237 static bool fold_tcg_ld_memcopy(OptContext *ctx, TCGOp *op) in fold_tcg_ld_memcopy() argument
2243 if (op->args[1] != tcgv_ptr_arg(tcg_env)) { in fold_tcg_ld_memcopy()
2248 ofs = op->args[2]; in fold_tcg_ld_memcopy()
2249 dst = arg_temp(op->args[0]); in fold_tcg_ld_memcopy()
2252 return tcg_opt_gen_mov(ctx, op, temp_arg(dst), temp_arg(src)); in fold_tcg_ld_memcopy()
2260 static bool fold_tcg_st(OptContext *ctx, TCGOp *op) in fold_tcg_st() argument
2262 intptr_t ofs = op->args[2]; in fold_tcg_st()
2265 if (op->args[1] != tcgv_ptr_arg(tcg_env)) { in fold_tcg_st()
2270 switch (op->opc) { in fold_tcg_st()
2294 static bool fold_tcg_st_memcopy(OptContext *ctx, TCGOp *op) in fold_tcg_st_memcopy() argument
2300 if (op->args[1] != tcgv_ptr_arg(tcg_env)) { in fold_tcg_st_memcopy()
2301 fold_tcg_st(ctx, op); in fold_tcg_st_memcopy()
2305 src = arg_temp(op->args[0]); in fold_tcg_st_memcopy()
2306 ofs = op->args[2]; in fold_tcg_st_memcopy()
2316 tcg_op_remove(ctx->tcg, op); in fold_tcg_st_memcopy()
2327 static bool fold_xor(OptContext *ctx, TCGOp *op) in fold_xor() argument
2329 if (fold_const2_commutative(ctx, op) || in fold_xor()
2330 fold_xx_to_i(ctx, op, 0) || in fold_xor()
2331 fold_xi_to_x(ctx, op, 0) || in fold_xor()
2332 fold_xi_to_not(ctx, op, -1)) { in fold_xor()
2336 ctx->z_mask = arg_info(op->args[1])->z_mask in fold_xor()
2337 | arg_info(op->args[2])->z_mask; in fold_xor()
2338 ctx->s_mask = arg_info(op->args[1])->s_mask in fold_xor()
2339 & arg_info(op->args[2])->s_mask; in fold_xor()
2340 return fold_masks(ctx, op); in fold_xor()
2347 TCGOp *op, *op_next; in tcg_optimize() local
2362 QTAILQ_FOREACH_SAFE(op, &s->ops, link, op_next) { in tcg_optimize()
2363 TCGOpcode opc = op->opc; in tcg_optimize()
2369 fold_call(&ctx, op); in tcg_optimize()
2374 init_arguments(&ctx, op, def->nb_oargs + def->nb_iargs); in tcg_optimize()
2375 copy_propagate(&ctx, op, def->nb_oargs, def->nb_iargs); in tcg_optimize()
2379 ctx.type = TCG_TYPE_V64 + TCGOP_VECL(op); in tcg_optimize()
2397 done = fold_add(&ctx, op); in tcg_optimize()
2400 done = fold_add_vec(&ctx, op); in tcg_optimize()
2403 done = fold_add2(&ctx, op); in tcg_optimize()
2406 done = fold_and(&ctx, op); in tcg_optimize()
2409 done = fold_andc(&ctx, op); in tcg_optimize()
2412 done = fold_brcond(&ctx, op); in tcg_optimize()
2415 done = fold_brcond2(&ctx, op); in tcg_optimize()
2420 done = fold_bswap(&ctx, op); in tcg_optimize()
2424 done = fold_count_zeros(&ctx, op); in tcg_optimize()
2427 done = fold_ctpop(&ctx, op); in tcg_optimize()
2430 done = fold_deposit(&ctx, op); in tcg_optimize()
2434 done = fold_divide(&ctx, op); in tcg_optimize()
2437 done = fold_dup(&ctx, op); in tcg_optimize()
2440 done = fold_dup2(&ctx, op); in tcg_optimize()
2443 done = fold_eqv(&ctx, op); in tcg_optimize()
2446 done = fold_extract(&ctx, op); in tcg_optimize()
2449 done = fold_extract2(&ctx, op); in tcg_optimize()
2455 done = fold_exts(&ctx, op); in tcg_optimize()
2463 done = fold_extu(&ctx, op); in tcg_optimize()
2471 done = fold_tcg_ld(&ctx, op); in tcg_optimize()
2476 done = fold_tcg_ld_memcopy(&ctx, op); in tcg_optimize()
2481 done = fold_tcg_st(&ctx, op); in tcg_optimize()
2486 done = fold_tcg_st_memcopy(&ctx, op); in tcg_optimize()
2489 done = fold_mb(&ctx, op); in tcg_optimize()
2492 done = fold_mov(&ctx, op); in tcg_optimize()
2495 done = fold_movcond(&ctx, op); in tcg_optimize()
2498 done = fold_mul(&ctx, op); in tcg_optimize()
2502 done = fold_mul_highpart(&ctx, op); in tcg_optimize()
2506 done = fold_multiply2(&ctx, op); in tcg_optimize()
2509 done = fold_nand(&ctx, op); in tcg_optimize()
2512 done = fold_neg(&ctx, op); in tcg_optimize()
2515 done = fold_nor(&ctx, op); in tcg_optimize()
2518 done = fold_not(&ctx, op); in tcg_optimize()
2521 done = fold_or(&ctx, op); in tcg_optimize()
2524 done = fold_orc(&ctx, op); in tcg_optimize()
2532 done = fold_qemu_ld(&ctx, op); in tcg_optimize()
2542 done = fold_qemu_st(&ctx, op); in tcg_optimize()
2546 done = fold_remainder(&ctx, op); in tcg_optimize()
2553 done = fold_shift(&ctx, op); in tcg_optimize()
2556 done = fold_setcond(&ctx, op); in tcg_optimize()
2559 done = fold_negsetcond(&ctx, op); in tcg_optimize()
2562 done = fold_setcond2(&ctx, op); in tcg_optimize()
2565 done = fold_sextract(&ctx, op); in tcg_optimize()
2568 done = fold_sub(&ctx, op); in tcg_optimize()
2571 done = fold_sub_vec(&ctx, op); in tcg_optimize()
2574 done = fold_sub2(&ctx, op); in tcg_optimize()
2577 done = fold_xor(&ctx, op); in tcg_optimize()
2584 finish_folding(&ctx, op); in tcg_optimize()