Lines Matching refs:op
374 static bool tcg_opt_gen_mov(OptContext *ctx, TCGOp *op, TCGArg dst, TCGArg src) in tcg_opt_gen_mov() argument
383 tcg_op_remove(ctx->tcg, op); in tcg_opt_gen_mov()
407 op->opc = new_op; in tcg_opt_gen_mov()
408 op->args[0] = dst; in tcg_opt_gen_mov()
409 op->args[1] = src; in tcg_opt_gen_mov()
432 static bool tcg_opt_gen_movi(OptContext *ctx, TCGOp *op, in tcg_opt_gen_movi() argument
436 return tcg_opt_gen_mov(ctx, op, dst, arg_new_constant(ctx, val)); in tcg_opt_gen_movi()
439 static uint64_t do_constant_folding_2(TCGOpcode op, uint64_t x, uint64_t y) in do_constant_folding_2() argument
443 switch (op) { in do_constant_folding_2()
602 static uint64_t do_constant_folding(TCGOpcode op, TCGType type, in do_constant_folding() argument
605 uint64_t res = do_constant_folding_2(op, x, y); in do_constant_folding()
792 static int do_constant_folding_cond1(OptContext *ctx, TCGOp *op, TCGArg dest, in do_constant_folding_cond1() argument
835 TCGOp *op2 = tcg_op_insert_before(ctx->tcg, op, and_opc, 3); in do_constant_folding_cond1()
849 static int do_constant_folding_cond2(OptContext *ctx, TCGOp *op, TCGArg *args) in do_constant_folding_cond2() argument
928 TCGOp *op1 = tcg_op_insert_before(ctx->tcg, op, INDEX_op_and_i32, 3); in do_constant_folding_cond2()
929 TCGOp *op2 = tcg_op_insert_before(ctx->tcg, op, INDEX_op_and_i32, 3); in do_constant_folding_cond2()
948 static void init_arguments(OptContext *ctx, TCGOp *op, int nb_args) in init_arguments() argument
951 TCGTemp *ts = arg_temp(op->args[i]); in init_arguments()
956 static void copy_propagate(OptContext *ctx, TCGOp *op, in copy_propagate() argument
960 TCGTemp *ts = arg_temp(op->args[i]); in copy_propagate()
962 op->args[i] = temp_arg(find_better_copy(ts)); in copy_propagate()
967 static void finish_folding(OptContext *ctx, TCGOp *op) in finish_folding() argument
969 const TCGOpDef *def = &tcg_op_defs[op->opc]; in finish_folding()
987 TCGTemp *ts = arg_temp(op->args[i]); in finish_folding()
1011 static bool fold_const1(OptContext *ctx, TCGOp *op) in fold_const1() argument
1013 if (arg_is_const(op->args[1])) { in fold_const1()
1016 t = arg_info(op->args[1])->val; in fold_const1()
1017 t = do_constant_folding(op->opc, ctx->type, t, 0); in fold_const1()
1018 return tcg_opt_gen_movi(ctx, op, op->args[0], t); in fold_const1()
1023 static bool fold_const2(OptContext *ctx, TCGOp *op) in fold_const2() argument
1025 if (arg_is_const(op->args[1]) && arg_is_const(op->args[2])) { in fold_const2()
1026 uint64_t t1 = arg_info(op->args[1])->val; in fold_const2()
1027 uint64_t t2 = arg_info(op->args[2])->val; in fold_const2()
1029 t1 = do_constant_folding(op->opc, ctx->type, t1, t2); in fold_const2()
1030 return tcg_opt_gen_movi(ctx, op, op->args[0], t1); in fold_const2()
1035 static bool fold_commutative(OptContext *ctx, TCGOp *op) in fold_commutative() argument
1037 swap_commutative(op->args[0], &op->args[1], &op->args[2]); in fold_commutative()
1041 static bool fold_const2_commutative(OptContext *ctx, TCGOp *op) in fold_const2_commutative() argument
1043 swap_commutative(op->args[0], &op->args[1], &op->args[2]); in fold_const2_commutative()
1044 return fold_const2(ctx, op); in fold_const2_commutative()
1047 static bool fold_masks(OptContext *ctx, TCGOp *op) in fold_masks() argument
1069 return tcg_opt_gen_movi(ctx, op, op->args[0], 0); in fold_masks()
1072 return tcg_opt_gen_mov(ctx, op, op->args[0], op->args[1]); in fold_masks()
1082 static bool fold_not(OptContext *ctx, TCGOp *op);
1083 static bool fold_to_not(OptContext *ctx, TCGOp *op, int idx) in fold_to_not() argument
1107 op->opc = not_op; in fold_to_not()
1108 op->args[1] = op->args[idx]; in fold_to_not()
1109 return fold_not(ctx, op); in fold_to_not()
1115 static bool fold_ix_to_i(OptContext *ctx, TCGOp *op, uint64_t i) in fold_ix_to_i() argument
1117 if (arg_is_const_val(op->args[1], i)) { in fold_ix_to_i()
1118 return tcg_opt_gen_movi(ctx, op, op->args[0], i); in fold_ix_to_i()
1124 static bool fold_ix_to_not(OptContext *ctx, TCGOp *op, uint64_t i) in fold_ix_to_not() argument
1126 if (arg_is_const_val(op->args[1], i)) { in fold_ix_to_not()
1127 return fold_to_not(ctx, op, 2); in fold_ix_to_not()
1133 static bool fold_xi_to_i(OptContext *ctx, TCGOp *op, uint64_t i) in fold_xi_to_i() argument
1135 if (arg_is_const_val(op->args[2], i)) { in fold_xi_to_i()
1136 return tcg_opt_gen_movi(ctx, op, op->args[0], i); in fold_xi_to_i()
1142 static bool fold_xi_to_x(OptContext *ctx, TCGOp *op, uint64_t i) in fold_xi_to_x() argument
1144 if (arg_is_const_val(op->args[2], i)) { in fold_xi_to_x()
1145 return tcg_opt_gen_mov(ctx, op, op->args[0], op->args[1]); in fold_xi_to_x()
1151 static bool fold_xi_to_not(OptContext *ctx, TCGOp *op, uint64_t i) in fold_xi_to_not() argument
1153 if (arg_is_const_val(op->args[2], i)) { in fold_xi_to_not()
1154 return fold_to_not(ctx, op, 1); in fold_xi_to_not()
1160 static bool fold_xx_to_i(OptContext *ctx, TCGOp *op, uint64_t i) in fold_xx_to_i() argument
1162 if (args_are_copies(op->args[1], op->args[2])) { in fold_xx_to_i()
1163 return tcg_opt_gen_movi(ctx, op, op->args[0], i); in fold_xx_to_i()
1169 static bool fold_xx_to_x(OptContext *ctx, TCGOp *op) in fold_xx_to_x() argument
1171 if (args_are_copies(op->args[1], op->args[2])) { in fold_xx_to_x()
1172 return tcg_opt_gen_mov(ctx, op, op->args[0], op->args[1]); in fold_xx_to_x()
1186 static bool fold_add(OptContext *ctx, TCGOp *op) in fold_add() argument
1188 if (fold_const2_commutative(ctx, op) || in fold_add()
1189 fold_xi_to_x(ctx, op, 0)) { in fold_add()
1196 static bool fold_add_vec(OptContext *ctx, TCGOp *op) in fold_add_vec() argument
1198 if (fold_commutative(ctx, op) || in fold_add_vec()
1199 fold_xi_to_x(ctx, op, 0)) { in fold_add_vec()
1205 static bool fold_addsub2(OptContext *ctx, TCGOp *op, bool add) in fold_addsub2() argument
1207 bool a_const = arg_is_const(op->args[2]) && arg_is_const(op->args[3]); in fold_addsub2()
1208 bool b_const = arg_is_const(op->args[4]) && arg_is_const(op->args[5]); in fold_addsub2()
1211 uint64_t al = arg_info(op->args[2])->val; in fold_addsub2()
1212 uint64_t ah = arg_info(op->args[3])->val; in fold_addsub2()
1213 uint64_t bl = arg_info(op->args[4])->val; in fold_addsub2()
1214 uint64_t bh = arg_info(op->args[5])->val; in fold_addsub2()
1244 rl = op->args[0]; in fold_addsub2()
1245 rh = op->args[1]; in fold_addsub2()
1248 op2 = tcg_op_insert_before(ctx->tcg, op, 0, 2); in fold_addsub2()
1250 tcg_opt_gen_movi(ctx, op, rl, al); in fold_addsub2()
1257 uint64_t bl = arg_info(op->args[4])->val; in fold_addsub2()
1258 uint64_t bh = arg_info(op->args[5])->val; in fold_addsub2()
1264 op->opc = (ctx->type == TCG_TYPE_I32 in fold_addsub2()
1266 op->args[4] = arg_new_constant(ctx, bl); in fold_addsub2()
1267 op->args[5] = arg_new_constant(ctx, bh); in fold_addsub2()
1272 static bool fold_add2(OptContext *ctx, TCGOp *op) in fold_add2() argument
1275 swap_commutative(op->args[0], &op->args[2], &op->args[4]); in fold_add2()
1276 swap_commutative(op->args[1], &op->args[3], &op->args[5]); in fold_add2()
1278 return fold_addsub2(ctx, op, true); in fold_add2()
1281 static bool fold_and(OptContext *ctx, TCGOp *op) in fold_and() argument
1285 if (fold_const2_commutative(ctx, op) || in fold_and()
1286 fold_xi_to_i(ctx, op, 0) || in fold_and()
1287 fold_xi_to_x(ctx, op, -1) || in fold_and()
1288 fold_xx_to_x(ctx, op)) { in fold_and()
1292 z1 = arg_info(op->args[1])->z_mask; in fold_and()
1293 z2 = arg_info(op->args[2])->z_mask; in fold_and()
1300 ctx->s_mask = arg_info(op->args[1])->s_mask in fold_and()
1301 & arg_info(op->args[2])->s_mask; in fold_and()
1307 if (arg_is_const(op->args[2])) { in fold_and()
1311 return fold_masks(ctx, op); in fold_and()
1314 static bool fold_andc(OptContext *ctx, TCGOp *op) in fold_andc() argument
1318 if (fold_const2(ctx, op) || in fold_andc()
1319 fold_xx_to_i(ctx, op, 0) || in fold_andc()
1320 fold_xi_to_x(ctx, op, 0) || in fold_andc()
1321 fold_ix_to_not(ctx, op, -1)) { in fold_andc()
1325 z1 = arg_info(op->args[1])->z_mask; in fold_andc()
1331 if (arg_is_const(op->args[2])) { in fold_andc()
1332 uint64_t z2 = ~arg_info(op->args[2])->z_mask; in fold_andc()
1338 ctx->s_mask = arg_info(op->args[1])->s_mask in fold_andc()
1339 & arg_info(op->args[2])->s_mask; in fold_andc()
1340 return fold_masks(ctx, op); in fold_andc()
1343 static bool fold_brcond(OptContext *ctx, TCGOp *op) in fold_brcond() argument
1345 int i = do_constant_folding_cond1(ctx, op, NO_DEST, &op->args[0], in fold_brcond()
1346 &op->args[1], &op->args[2]); in fold_brcond()
1348 tcg_op_remove(ctx->tcg, op); in fold_brcond()
1352 op->opc = INDEX_op_br; in fold_brcond()
1353 op->args[0] = op->args[3]; in fold_brcond()
1358 static bool fold_brcond2(OptContext *ctx, TCGOp *op) in fold_brcond2() argument
1364 i = do_constant_folding_cond2(ctx, op, &op->args[0]); in fold_brcond2()
1365 cond = op->args[4]; in fold_brcond2()
1366 label = op->args[5]; in fold_brcond2()
1378 if (arg_is_const_val(op->args[2], 0) && in fold_brcond2()
1379 arg_is_const_val(op->args[3], 0)) { in fold_brcond2()
1392 i = do_constant_folding_cond(TCG_TYPE_I32, op->args[0], in fold_brcond2()
1393 op->args[2], cond); in fold_brcond2()
1401 i = do_constant_folding_cond(TCG_TYPE_I32, op->args[1], in fold_brcond2()
1402 op->args[3], cond); in fold_brcond2()
1413 if (arg_is_const_val(op->args[2], 0)) { in fold_brcond2()
1416 if (arg_is_const_val(op->args[3], 0)) { in fold_brcond2()
1425 op->opc = INDEX_op_brcond_i32; in fold_brcond2()
1426 op->args[1] = op->args[2]; in fold_brcond2()
1427 op->args[2] = cond; in fold_brcond2()
1428 op->args[3] = label; in fold_brcond2()
1429 return fold_brcond(ctx, op); in fold_brcond2()
1432 op->opc = INDEX_op_brcond_i32; in fold_brcond2()
1433 op->args[0] = op->args[1]; in fold_brcond2()
1434 op->args[1] = op->args[3]; in fold_brcond2()
1435 op->args[2] = cond; in fold_brcond2()
1436 op->args[3] = label; in fold_brcond2()
1437 return fold_brcond(ctx, op); in fold_brcond2()
1441 tcg_op_remove(ctx->tcg, op); in fold_brcond2()
1444 op->opc = INDEX_op_br; in fold_brcond2()
1445 op->args[0] = label; in fold_brcond2()
1451 static bool fold_bswap(OptContext *ctx, TCGOp *op) in fold_bswap() argument
1455 if (arg_is_const(op->args[1])) { in fold_bswap()
1456 uint64_t t = arg_info(op->args[1])->val; in fold_bswap()
1458 t = do_constant_folding(op->opc, ctx->type, t, op->args[2]); in fold_bswap()
1459 return tcg_opt_gen_movi(ctx, op, op->args[0], t); in fold_bswap()
1462 z_mask = arg_info(op->args[1])->z_mask; in fold_bswap()
1464 switch (op->opc) { in fold_bswap()
1484 switch (op->args[2] & (TCG_BSWAP_OZ | TCG_BSWAP_OS)) { in fold_bswap()
1503 return fold_masks(ctx, op); in fold_bswap()
1506 static bool fold_call(OptContext *ctx, TCGOp *op) in fold_call() argument
1509 int nb_oargs = TCGOP_CALLO(op); in fold_call()
1510 int nb_iargs = TCGOP_CALLI(op); in fold_call()
1513 init_arguments(ctx, op, nb_oargs + nb_iargs); in fold_call()
1514 copy_propagate(ctx, op, nb_oargs, nb_iargs); in fold_call()
1517 flags = tcg_call_flags(op); in fold_call()
1535 reset_temp(ctx, op->args[i]); in fold_call()
1543 static bool fold_count_zeros(OptContext *ctx, TCGOp *op) in fold_count_zeros() argument
1547 if (arg_is_const(op->args[1])) { in fold_count_zeros()
1548 uint64_t t = arg_info(op->args[1])->val; in fold_count_zeros()
1551 t = do_constant_folding(op->opc, ctx->type, t, 0); in fold_count_zeros()
1552 return tcg_opt_gen_movi(ctx, op, op->args[0], t); in fold_count_zeros()
1554 return tcg_opt_gen_mov(ctx, op, op->args[0], op->args[2]); in fold_count_zeros()
1567 ctx->z_mask = arg_info(op->args[2])->z_mask | z_mask; in fold_count_zeros()
1572 static bool fold_ctpop(OptContext *ctx, TCGOp *op) in fold_ctpop() argument
1574 if (fold_const1(ctx, op)) { in fold_ctpop()
1592 static bool fold_deposit(OptContext *ctx, TCGOp *op) in fold_deposit() argument
1596 if (arg_is_const(op->args[1]) && arg_is_const(op->args[2])) { in fold_deposit()
1597 uint64_t t1 = arg_info(op->args[1])->val; in fold_deposit()
1598 uint64_t t2 = arg_info(op->args[2])->val; in fold_deposit()
1600 t1 = deposit64(t1, op->args[3], op->args[4], t2); in fold_deposit()
1601 return tcg_opt_gen_movi(ctx, op, op->args[0], t1); in fold_deposit()
1616 if (arg_is_const_val(op->args[1], 0) && op->args[3] == 0) { in fold_deposit()
1617 uint64_t mask = MAKE_64BIT_MASK(0, op->args[4]); in fold_deposit()
1619 op->opc = and_opc; in fold_deposit()
1620 op->args[1] = op->args[2]; in fold_deposit()
1621 op->args[2] = arg_new_constant(ctx, mask); in fold_deposit()
1622 ctx->z_mask = mask & arg_info(op->args[1])->z_mask; in fold_deposit()
1627 if (arg_is_const_val(op->args[2], 0)) { in fold_deposit()
1628 uint64_t mask = deposit64(-1, op->args[3], op->args[4], 0); in fold_deposit()
1630 op->opc = and_opc; in fold_deposit()
1631 op->args[2] = arg_new_constant(ctx, mask); in fold_deposit()
1632 ctx->z_mask = mask & arg_info(op->args[1])->z_mask; in fold_deposit()
1636 ctx->z_mask = deposit64(arg_info(op->args[1])->z_mask, in fold_deposit()
1637 op->args[3], op->args[4], in fold_deposit()
1638 arg_info(op->args[2])->z_mask); in fold_deposit()
1642 static bool fold_divide(OptContext *ctx, TCGOp *op) in fold_divide() argument
1644 if (fold_const2(ctx, op) || in fold_divide()
1645 fold_xi_to_x(ctx, op, 1)) { in fold_divide()
1651 static bool fold_dup(OptContext *ctx, TCGOp *op) in fold_dup() argument
1653 if (arg_is_const(op->args[1])) { in fold_dup()
1654 uint64_t t = arg_info(op->args[1])->val; in fold_dup()
1655 t = dup_const(TCGOP_VECE(op), t); in fold_dup()
1656 return tcg_opt_gen_movi(ctx, op, op->args[0], t); in fold_dup()
1661 static bool fold_dup2(OptContext *ctx, TCGOp *op) in fold_dup2() argument
1663 if (arg_is_const(op->args[1]) && arg_is_const(op->args[2])) { in fold_dup2()
1664 uint64_t t = deposit64(arg_info(op->args[1])->val, 32, 32, in fold_dup2()
1665 arg_info(op->args[2])->val); in fold_dup2()
1666 return tcg_opt_gen_movi(ctx, op, op->args[0], t); in fold_dup2()
1669 if (args_are_copies(op->args[1], op->args[2])) { in fold_dup2()
1670 op->opc = INDEX_op_dup_vec; in fold_dup2()
1671 TCGOP_VECE(op) = MO_32; in fold_dup2()
1676 static bool fold_eqv(OptContext *ctx, TCGOp *op) in fold_eqv() argument
1678 if (fold_const2_commutative(ctx, op) || in fold_eqv()
1679 fold_xi_to_x(ctx, op, -1) || in fold_eqv()
1680 fold_xi_to_not(ctx, op, 0)) { in fold_eqv()
1684 ctx->s_mask = arg_info(op->args[1])->s_mask in fold_eqv()
1685 & arg_info(op->args[2])->s_mask; in fold_eqv()
1689 static bool fold_extract(OptContext *ctx, TCGOp *op) in fold_extract() argument
1692 int pos = op->args[2]; in fold_extract()
1693 int len = op->args[3]; in fold_extract()
1695 if (arg_is_const(op->args[1])) { in fold_extract()
1698 t = arg_info(op->args[1])->val; in fold_extract()
1700 return tcg_opt_gen_movi(ctx, op, op->args[0], t); in fold_extract()
1703 z_mask_old = arg_info(op->args[1])->z_mask; in fold_extract()
1711 return fold_masks(ctx, op); in fold_extract()
1714 static bool fold_extract2(OptContext *ctx, TCGOp *op) in fold_extract2() argument
1716 if (arg_is_const(op->args[1]) && arg_is_const(op->args[2])) { in fold_extract2()
1717 uint64_t v1 = arg_info(op->args[1])->val; in fold_extract2()
1718 uint64_t v2 = arg_info(op->args[2])->val; in fold_extract2()
1719 int shr = op->args[3]; in fold_extract2()
1721 if (op->opc == INDEX_op_extract2_i64) { in fold_extract2()
1728 return tcg_opt_gen_movi(ctx, op, op->args[0], v1 | v2); in fold_extract2()
1733 static bool fold_exts(OptContext *ctx, TCGOp *op) in fold_exts() argument
1738 if (fold_const1(ctx, op)) { in fold_exts()
1742 z_mask = arg_info(op->args[1])->z_mask; in fold_exts()
1743 s_mask = arg_info(op->args[1])->s_mask; in fold_exts()
1746 switch (op->opc) { in fold_exts()
1777 return fold_masks(ctx, op); in fold_exts()
1780 static bool fold_extu(OptContext *ctx, TCGOp *op) in fold_extu() argument
1785 if (fold_const1(ctx, op)) { in fold_extu()
1789 z_mask_old = z_mask = arg_info(op->args[1])->z_mask; in fold_extu()
1791 switch (op->opc) { in fold_extu()
1818 return fold_masks(ctx, op); in fold_extu()
1821 static bool fold_mb(OptContext *ctx, TCGOp *op) in fold_mb() argument
1837 ctx->prev_mb->args[0] |= op->args[0]; in fold_mb()
1838 tcg_op_remove(ctx->tcg, op); in fold_mb()
1840 ctx->prev_mb = op; in fold_mb()
1845 static bool fold_mov(OptContext *ctx, TCGOp *op) in fold_mov() argument
1847 return tcg_opt_gen_mov(ctx, op, op->args[0], op->args[1]); in fold_mov()
1850 static bool fold_movcond(OptContext *ctx, TCGOp *op) in fold_movcond() argument
1855 if (args_are_copies(op->args[3], op->args[4])) { in fold_movcond()
1856 return tcg_opt_gen_mov(ctx, op, op->args[0], op->args[3]); in fold_movcond()
1863 if (swap_commutative(op->args[0], &op->args[4], &op->args[3])) { in fold_movcond()
1864 op->args[5] = tcg_invert_cond(op->args[5]); in fold_movcond()
1867 i = do_constant_folding_cond1(ctx, op, NO_DEST, &op->args[1], in fold_movcond()
1868 &op->args[2], &op->args[5]); in fold_movcond()
1870 return tcg_opt_gen_mov(ctx, op, op->args[0], op->args[4 - i]); in fold_movcond()
1873 ctx->z_mask = arg_info(op->args[3])->z_mask in fold_movcond()
1874 | arg_info(op->args[4])->z_mask; in fold_movcond()
1875 ctx->s_mask = arg_info(op->args[3])->s_mask in fold_movcond()
1876 & arg_info(op->args[4])->s_mask; in fold_movcond()
1878 if (arg_is_const(op->args[3]) && arg_is_const(op->args[4])) { in fold_movcond()
1879 uint64_t tv = arg_info(op->args[3])->val; in fold_movcond()
1880 uint64_t fv = arg_info(op->args[4])->val; in fold_movcond()
1882 TCGCond cond = op->args[5]; in fold_movcond()
1904 op->opc = opc; in fold_movcond()
1905 op->args[3] = cond; in fold_movcond()
1907 op->opc = opc; in fold_movcond()
1908 op->args[3] = tcg_invert_cond(cond); in fold_movcond()
1911 op->opc = negopc; in fold_movcond()
1912 op->args[3] = cond; in fold_movcond()
1914 op->opc = negopc; in fold_movcond()
1915 op->args[3] = tcg_invert_cond(cond); in fold_movcond()
1922 static bool fold_mul(OptContext *ctx, TCGOp *op) in fold_mul() argument
1924 if (fold_const2(ctx, op) || in fold_mul()
1925 fold_xi_to_i(ctx, op, 0) || in fold_mul()
1926 fold_xi_to_x(ctx, op, 1)) { in fold_mul()
1932 static bool fold_mul_highpart(OptContext *ctx, TCGOp *op) in fold_mul_highpart() argument
1934 if (fold_const2_commutative(ctx, op) || in fold_mul_highpart()
1935 fold_xi_to_i(ctx, op, 0)) { in fold_mul_highpart()
1941 static bool fold_multiply2(OptContext *ctx, TCGOp *op) in fold_multiply2() argument
1943 swap_commutative(op->args[0], &op->args[2], &op->args[3]); in fold_multiply2()
1945 if (arg_is_const(op->args[2]) && arg_is_const(op->args[3])) { in fold_multiply2()
1946 uint64_t a = arg_info(op->args[2])->val; in fold_multiply2()
1947 uint64_t b = arg_info(op->args[3])->val; in fold_multiply2()
1952 switch (op->opc) { in fold_multiply2()
1973 rl = op->args[0]; in fold_multiply2()
1974 rh = op->args[1]; in fold_multiply2()
1977 op2 = tcg_op_insert_before(ctx->tcg, op, 0, 2); in fold_multiply2()
1979 tcg_opt_gen_movi(ctx, op, rl, l); in fold_multiply2()
1986 static bool fold_nand(OptContext *ctx, TCGOp *op) in fold_nand() argument
1988 if (fold_const2_commutative(ctx, op) || in fold_nand()
1989 fold_xi_to_not(ctx, op, -1)) { in fold_nand()
1993 ctx->s_mask = arg_info(op->args[1])->s_mask in fold_nand()
1994 & arg_info(op->args[2])->s_mask; in fold_nand()
1998 static bool fold_neg_no_const(OptContext *ctx, TCGOp *op) in fold_neg_no_const() argument
2001 uint64_t z_mask = arg_info(op->args[1])->z_mask; in fold_neg_no_const()
2008 finish_folding(ctx, op); in fold_neg_no_const()
2012 static bool fold_neg(OptContext *ctx, TCGOp *op) in fold_neg() argument
2014 return fold_const1(ctx, op) || fold_neg_no_const(ctx, op); in fold_neg()
2017 static bool fold_nor(OptContext *ctx, TCGOp *op) in fold_nor() argument
2019 if (fold_const2_commutative(ctx, op) || in fold_nor()
2020 fold_xi_to_not(ctx, op, 0)) { in fold_nor()
2024 ctx->s_mask = arg_info(op->args[1])->s_mask in fold_nor()
2025 & arg_info(op->args[2])->s_mask; in fold_nor()
2029 static bool fold_not(OptContext *ctx, TCGOp *op) in fold_not() argument
2031 if (fold_const1(ctx, op)) { in fold_not()
2035 ctx->s_mask = arg_info(op->args[1])->s_mask; in fold_not()
2038 finish_folding(ctx, op); in fold_not()
2042 static bool fold_or(OptContext *ctx, TCGOp *op) in fold_or() argument
2044 if (fold_const2_commutative(ctx, op) || in fold_or()
2045 fold_xi_to_x(ctx, op, 0) || in fold_or()
2046 fold_xx_to_x(ctx, op)) { in fold_or()
2050 ctx->z_mask = arg_info(op->args[1])->z_mask in fold_or()
2051 | arg_info(op->args[2])->z_mask; in fold_or()
2052 ctx->s_mask = arg_info(op->args[1])->s_mask in fold_or()
2053 & arg_info(op->args[2])->s_mask; in fold_or()
2054 return fold_masks(ctx, op); in fold_or()
2057 static bool fold_orc(OptContext *ctx, TCGOp *op) in fold_orc() argument
2059 if (fold_const2(ctx, op) || in fold_orc()
2060 fold_xx_to_i(ctx, op, -1) || in fold_orc()
2061 fold_xi_to_x(ctx, op, -1) || in fold_orc()
2062 fold_ix_to_not(ctx, op, 0)) { in fold_orc()
2066 ctx->s_mask = arg_info(op->args[1])->s_mask in fold_orc()
2067 & arg_info(op->args[2])->s_mask; in fold_orc()
2071 static bool fold_qemu_ld(OptContext *ctx, TCGOp *op) in fold_qemu_ld() argument
2073 const TCGOpDef *def = &tcg_op_defs[op->opc]; in fold_qemu_ld()
2074 MemOpIdx oi = op->args[def->nb_oargs + def->nb_iargs]; in fold_qemu_ld()
2091 static bool fold_qemu_st(OptContext *ctx, TCGOp *op) in fold_qemu_st() argument
2098 static bool fold_remainder(OptContext *ctx, TCGOp *op) in fold_remainder() argument
2100 if (fold_const2(ctx, op) || in fold_remainder()
2101 fold_xx_to_i(ctx, op, 0)) { in fold_remainder()
2107 static bool fold_setcond_zmask(OptContext *ctx, TCGOp *op, bool neg) in fold_setcond_zmask() argument
2112 if (!arg_is_const(op->args[2])) { in fold_setcond_zmask()
2116 a_zmask = arg_info(op->args[1])->z_mask; in fold_setcond_zmask()
2117 b_val = arg_info(op->args[2])->val; in fold_setcond_zmask()
2118 cond = op->args[3]; in fold_setcond_zmask()
2140 return tcg_opt_gen_movi(ctx, op, op->args[0], neg ? -inv : inv); in fold_setcond_zmask()
2175 return tcg_opt_gen_mov(ctx, op, op->args[0], op->args[1]); in fold_setcond_zmask()
2194 op->opc = neg_opc; in fold_setcond_zmask()
2196 op->opc = add_opc; in fold_setcond_zmask()
2197 op->args[2] = arg_new_constant(ctx, -1); in fold_setcond_zmask()
2199 op->opc = xor_opc; in fold_setcond_zmask()
2200 op->args[2] = arg_new_constant(ctx, 1); in fold_setcond_zmask()
2209 static void fold_setcond_tst_pow2(OptContext *ctx, TCGOp *op, bool neg) in fold_setcond_tst_pow2() argument
2213 TCGCond cond = op->args[3]; in fold_setcond_tst_pow2()
2220 if (!is_tst_cond(cond) || !arg_is_const(op->args[2])) { in fold_setcond_tst_pow2()
2224 src2 = op->args[2]; in fold_setcond_tst_pow2()
2258 ret = op->args[0]; in fold_setcond_tst_pow2()
2259 src1 = op->args[1]; in fold_setcond_tst_pow2()
2263 op->opc = sext_opc; in fold_setcond_tst_pow2()
2264 op->args[1] = src1; in fold_setcond_tst_pow2()
2265 op->args[2] = sh; in fold_setcond_tst_pow2()
2266 op->args[3] = 1; in fold_setcond_tst_pow2()
2269 op->opc = uext_opc; in fold_setcond_tst_pow2()
2270 op->args[1] = src1; in fold_setcond_tst_pow2()
2271 op->args[2] = sh; in fold_setcond_tst_pow2()
2272 op->args[3] = 1; in fold_setcond_tst_pow2()
2275 op2 = tcg_op_insert_before(ctx->tcg, op, shr_opc, 3); in fold_setcond_tst_pow2()
2281 op->opc = and_opc; in fold_setcond_tst_pow2()
2282 op->args[1] = src1; in fold_setcond_tst_pow2()
2283 op->args[2] = arg_new_constant(ctx, 1); in fold_setcond_tst_pow2()
2287 op2 = tcg_op_insert_after(ctx->tcg, op, sub_opc, 3); in fold_setcond_tst_pow2()
2292 op2 = tcg_op_insert_after(ctx->tcg, op, xor_opc, 3); in fold_setcond_tst_pow2()
2297 op2 = tcg_op_insert_after(ctx->tcg, op, neg_opc, 2); in fold_setcond_tst_pow2()
2303 static bool fold_setcond(OptContext *ctx, TCGOp *op) in fold_setcond() argument
2305 int i = do_constant_folding_cond1(ctx, op, op->args[0], &op->args[1], in fold_setcond()
2306 &op->args[2], &op->args[3]); in fold_setcond()
2308 return tcg_opt_gen_movi(ctx, op, op->args[0], i); in fold_setcond()
2311 if (fold_setcond_zmask(ctx, op, false)) { in fold_setcond()
2314 fold_setcond_tst_pow2(ctx, op, false); in fold_setcond()
2321 static bool fold_negsetcond(OptContext *ctx, TCGOp *op) in fold_negsetcond() argument
2323 int i = do_constant_folding_cond1(ctx, op, op->args[0], &op->args[1], in fold_negsetcond()
2324 &op->args[2], &op->args[3]); in fold_negsetcond()
2326 return tcg_opt_gen_movi(ctx, op, op->args[0], -i); in fold_negsetcond()
2329 if (fold_setcond_zmask(ctx, op, true)) { in fold_negsetcond()
2332 fold_setcond_tst_pow2(ctx, op, true); in fold_negsetcond()
2339 static bool fold_setcond2(OptContext *ctx, TCGOp *op) in fold_setcond2() argument
2344 i = do_constant_folding_cond2(ctx, op, &op->args[1]); in fold_setcond2()
2345 cond = op->args[5]; in fold_setcond2()
2357 if (arg_is_const_val(op->args[3], 0) && in fold_setcond2()
2358 arg_is_const_val(op->args[4], 0)) { in fold_setcond2()
2371 i = do_constant_folding_cond(TCG_TYPE_I32, op->args[1], in fold_setcond2()
2372 op->args[3], cond); in fold_setcond2()
2380 i = do_constant_folding_cond(TCG_TYPE_I32, op->args[2], in fold_setcond2()
2381 op->args[4], cond); in fold_setcond2()
2392 if (arg_is_const_val(op->args[3], 0)) { in fold_setcond2()
2395 if (arg_is_const_val(op->args[4], 0)) { in fold_setcond2()
2404 op->args[2] = op->args[3]; in fold_setcond2()
2405 op->args[3] = cond; in fold_setcond2()
2406 op->opc = INDEX_op_setcond_i32; in fold_setcond2()
2407 return fold_setcond(ctx, op); in fold_setcond2()
2410 op->args[1] = op->args[2]; in fold_setcond2()
2411 op->args[2] = op->args[4]; in fold_setcond2()
2412 op->args[3] = cond; in fold_setcond2()
2413 op->opc = INDEX_op_setcond_i32; in fold_setcond2()
2414 return fold_setcond(ctx, op); in fold_setcond2()
2422 return tcg_opt_gen_movi(ctx, op, op->args[0], i); in fold_setcond2()
2425 static bool fold_cmp_vec(OptContext *ctx, TCGOp *op) in fold_cmp_vec() argument
2428 if (swap_commutative(NO_DEST, &op->args[1], &op->args[2])) { in fold_cmp_vec()
2429 op->args[3] = tcg_swap_cond(op->args[3]); in fold_cmp_vec()
2434 static bool fold_cmpsel_vec(OptContext *ctx, TCGOp *op) in fold_cmpsel_vec() argument
2437 if (args_are_copies(op->args[3], op->args[4])) { in fold_cmpsel_vec()
2438 return tcg_opt_gen_mov(ctx, op, op->args[0], op->args[3]); in fold_cmpsel_vec()
2442 if (swap_commutative(NO_DEST, &op->args[1], &op->args[2])) { in fold_cmpsel_vec()
2443 op->args[5] = tcg_swap_cond(op->args[5]); in fold_cmpsel_vec()
2449 if (swap_commutative(op->args[0], &op->args[4], &op->args[3])) { in fold_cmpsel_vec()
2450 op->args[5] = tcg_invert_cond(op->args[5]); in fold_cmpsel_vec()
2455 static bool fold_sextract(OptContext *ctx, TCGOp *op) in fold_sextract() argument
2458 int pos = op->args[2]; in fold_sextract()
2459 int len = op->args[3]; in fold_sextract()
2461 if (arg_is_const(op->args[1])) { in fold_sextract()
2464 t = arg_info(op->args[1])->val; in fold_sextract()
2466 return tcg_opt_gen_movi(ctx, op, op->args[0], t); in fold_sextract()
2469 z_mask = arg_info(op->args[1])->z_mask; in fold_sextract()
2473 s_mask_old = arg_info(op->args[1])->s_mask; in fold_sextract()
2482 return fold_masks(ctx, op); in fold_sextract()
2485 static bool fold_shift(OptContext *ctx, TCGOp *op) in fold_shift() argument
2489 if (fold_const2(ctx, op) || in fold_shift()
2490 fold_ix_to_i(ctx, op, 0) || in fold_shift()
2491 fold_xi_to_x(ctx, op, 0)) { in fold_shift()
2495 s_mask = arg_info(op->args[1])->s_mask; in fold_shift()
2496 z_mask = arg_info(op->args[1])->z_mask; in fold_shift()
2498 if (arg_is_const(op->args[2])) { in fold_shift()
2499 int sh = arg_info(op->args[2])->val; in fold_shift()
2501 ctx->z_mask = do_constant_folding(op->opc, ctx->type, z_mask, sh); in fold_shift()
2503 s_mask = do_constant_folding(op->opc, ctx->type, s_mask, sh); in fold_shift()
2506 return fold_masks(ctx, op); in fold_shift()
2509 switch (op->opc) { in fold_shift()
2534 static bool fold_sub_to_neg(OptContext *ctx, TCGOp *op) in fold_sub_to_neg() argument
2539 if (!arg_is_const(op->args[1]) || arg_info(op->args[1])->val != 0) { in fold_sub_to_neg()
2557 tcg_can_emit_vec_op(neg_op, ctx->type, TCGOP_VECE(op)) > 0); in fold_sub_to_neg()
2563 op->opc = neg_op; in fold_sub_to_neg()
2564 op->args[1] = op->args[2]; in fold_sub_to_neg()
2565 return fold_neg_no_const(ctx, op); in fold_sub_to_neg()
2571 static bool fold_sub_vec(OptContext *ctx, TCGOp *op) in fold_sub_vec() argument
2573 if (fold_xx_to_i(ctx, op, 0) || in fold_sub_vec()
2574 fold_xi_to_x(ctx, op, 0) || in fold_sub_vec()
2575 fold_sub_to_neg(ctx, op)) { in fold_sub_vec()
2581 static bool fold_sub(OptContext *ctx, TCGOp *op) in fold_sub() argument
2583 if (fold_const2(ctx, op) || fold_sub_vec(ctx, op)) { in fold_sub()
2588 if (arg_is_const(op->args[2])) { in fold_sub()
2589 uint64_t val = arg_info(op->args[2])->val; in fold_sub()
2591 op->opc = (ctx->type == TCG_TYPE_I32 in fold_sub()
2593 op->args[2] = arg_new_constant(ctx, -val); in fold_sub()
2598 static bool fold_sub2(OptContext *ctx, TCGOp *op) in fold_sub2() argument
2600 return fold_addsub2(ctx, op, false); in fold_sub2()
2603 static bool fold_tcg_ld(OptContext *ctx, TCGOp *op) in fold_tcg_ld() argument
2606 switch (op->opc) { in fold_tcg_ld()
2634 static bool fold_tcg_ld_memcopy(OptContext *ctx, TCGOp *op) in fold_tcg_ld_memcopy() argument
2640 if (op->args[1] != tcgv_ptr_arg(tcg_env)) { in fold_tcg_ld_memcopy()
2645 ofs = op->args[2]; in fold_tcg_ld_memcopy()
2646 dst = arg_temp(op->args[0]); in fold_tcg_ld_memcopy()
2649 return tcg_opt_gen_mov(ctx, op, temp_arg(dst), temp_arg(src)); in fold_tcg_ld_memcopy()
2657 static bool fold_tcg_st(OptContext *ctx, TCGOp *op) in fold_tcg_st() argument
2659 intptr_t ofs = op->args[2]; in fold_tcg_st()
2662 if (op->args[1] != tcgv_ptr_arg(tcg_env)) { in fold_tcg_st()
2667 switch (op->opc) { in fold_tcg_st()
2691 static bool fold_tcg_st_memcopy(OptContext *ctx, TCGOp *op) in fold_tcg_st_memcopy() argument
2697 if (op->args[1] != tcgv_ptr_arg(tcg_env)) { in fold_tcg_st_memcopy()
2698 fold_tcg_st(ctx, op); in fold_tcg_st_memcopy()
2702 src = arg_temp(op->args[0]); in fold_tcg_st_memcopy()
2703 ofs = op->args[2]; in fold_tcg_st_memcopy()
2713 tcg_op_remove(ctx->tcg, op); in fold_tcg_st_memcopy()
2724 static bool fold_xor(OptContext *ctx, TCGOp *op) in fold_xor() argument
2726 if (fold_const2_commutative(ctx, op) || in fold_xor()
2727 fold_xx_to_i(ctx, op, 0) || in fold_xor()
2728 fold_xi_to_x(ctx, op, 0) || in fold_xor()
2729 fold_xi_to_not(ctx, op, -1)) { in fold_xor()
2733 ctx->z_mask = arg_info(op->args[1])->z_mask in fold_xor()
2734 | arg_info(op->args[2])->z_mask; in fold_xor()
2735 ctx->s_mask = arg_info(op->args[1])->s_mask in fold_xor()
2736 & arg_info(op->args[2])->s_mask; in fold_xor()
2737 return fold_masks(ctx, op); in fold_xor()
2740 static bool fold_bitsel_vec(OptContext *ctx, TCGOp *op) in fold_bitsel_vec() argument
2743 if (args_are_copies(op->args[2], op->args[3])) { in fold_bitsel_vec()
2744 return tcg_opt_gen_mov(ctx, op, op->args[0], op->args[2]); in fold_bitsel_vec()
2747 if (arg_is_const(op->args[2]) && arg_is_const(op->args[3])) { in fold_bitsel_vec()
2748 uint64_t tv = arg_info(op->args[2])->val; in fold_bitsel_vec()
2749 uint64_t fv = arg_info(op->args[3])->val; in fold_bitsel_vec()
2752 return tcg_opt_gen_mov(ctx, op, op->args[0], op->args[1]); in fold_bitsel_vec()
2756 op->opc = INDEX_op_not_vec; in fold_bitsel_vec()
2757 return fold_not(ctx, op); in fold_bitsel_vec()
2759 op->opc = INDEX_op_xor_vec; in fold_bitsel_vec()
2760 op->args[2] = arg_new_constant(ctx, -1); in fold_bitsel_vec()
2761 return fold_xor(ctx, op); in fold_bitsel_vec()
2765 if (arg_is_const(op->args[2])) { in fold_bitsel_vec()
2766 uint64_t tv = arg_info(op->args[2])->val; in fold_bitsel_vec()
2768 op->opc = INDEX_op_or_vec; in fold_bitsel_vec()
2769 op->args[2] = op->args[3]; in fold_bitsel_vec()
2770 return fold_or(ctx, op); in fold_bitsel_vec()
2773 op->opc = INDEX_op_andc_vec; in fold_bitsel_vec()
2774 op->args[2] = op->args[1]; in fold_bitsel_vec()
2775 op->args[1] = op->args[3]; in fold_bitsel_vec()
2776 return fold_andc(ctx, op); in fold_bitsel_vec()
2779 if (arg_is_const(op->args[3])) { in fold_bitsel_vec()
2780 uint64_t fv = arg_info(op->args[3])->val; in fold_bitsel_vec()
2782 op->opc = INDEX_op_and_vec; in fold_bitsel_vec()
2783 return fold_and(ctx, op); in fold_bitsel_vec()
2786 op->opc = INDEX_op_orc_vec; in fold_bitsel_vec()
2787 op->args[2] = op->args[1]; in fold_bitsel_vec()
2788 op->args[1] = op->args[3]; in fold_bitsel_vec()
2789 return fold_orc(ctx, op); in fold_bitsel_vec()
2799 TCGOp *op, *op_next; in tcg_optimize() local
2814 QTAILQ_FOREACH_SAFE(op, &s->ops, link, op_next) { in tcg_optimize()
2815 TCGOpcode opc = op->opc; in tcg_optimize()
2821 fold_call(&ctx, op); in tcg_optimize()
2826 init_arguments(&ctx, op, def->nb_oargs + def->nb_iargs); in tcg_optimize()
2827 copy_propagate(&ctx, op, def->nb_oargs, def->nb_iargs); in tcg_optimize()
2831 ctx.type = TCG_TYPE_V64 + TCGOP_VECL(op); in tcg_optimize()
2849 done = fold_add(&ctx, op); in tcg_optimize()
2852 done = fold_add_vec(&ctx, op); in tcg_optimize()
2855 done = fold_add2(&ctx, op); in tcg_optimize()
2858 done = fold_and(&ctx, op); in tcg_optimize()
2861 done = fold_andc(&ctx, op); in tcg_optimize()
2864 done = fold_brcond(&ctx, op); in tcg_optimize()
2867 done = fold_brcond2(&ctx, op); in tcg_optimize()
2872 done = fold_bswap(&ctx, op); in tcg_optimize()
2876 done = fold_count_zeros(&ctx, op); in tcg_optimize()
2879 done = fold_ctpop(&ctx, op); in tcg_optimize()
2882 done = fold_deposit(&ctx, op); in tcg_optimize()
2886 done = fold_divide(&ctx, op); in tcg_optimize()
2889 done = fold_dup(&ctx, op); in tcg_optimize()
2892 done = fold_dup2(&ctx, op); in tcg_optimize()
2895 done = fold_eqv(&ctx, op); in tcg_optimize()
2898 done = fold_extract(&ctx, op); in tcg_optimize()
2901 done = fold_extract2(&ctx, op); in tcg_optimize()
2907 done = fold_exts(&ctx, op); in tcg_optimize()
2915 done = fold_extu(&ctx, op); in tcg_optimize()
2923 done = fold_tcg_ld(&ctx, op); in tcg_optimize()
2928 done = fold_tcg_ld_memcopy(&ctx, op); in tcg_optimize()
2933 done = fold_tcg_st(&ctx, op); in tcg_optimize()
2938 done = fold_tcg_st_memcopy(&ctx, op); in tcg_optimize()
2941 done = fold_mb(&ctx, op); in tcg_optimize()
2944 done = fold_mov(&ctx, op); in tcg_optimize()
2947 done = fold_movcond(&ctx, op); in tcg_optimize()
2950 done = fold_mul(&ctx, op); in tcg_optimize()
2954 done = fold_mul_highpart(&ctx, op); in tcg_optimize()
2958 done = fold_multiply2(&ctx, op); in tcg_optimize()
2961 done = fold_nand(&ctx, op); in tcg_optimize()
2964 done = fold_neg(&ctx, op); in tcg_optimize()
2967 done = fold_nor(&ctx, op); in tcg_optimize()
2970 done = fold_not(&ctx, op); in tcg_optimize()
2973 done = fold_or(&ctx, op); in tcg_optimize()
2976 done = fold_orc(&ctx, op); in tcg_optimize()
2984 done = fold_qemu_ld(&ctx, op); in tcg_optimize()
2994 done = fold_qemu_st(&ctx, op); in tcg_optimize()
2998 done = fold_remainder(&ctx, op); in tcg_optimize()
3005 done = fold_shift(&ctx, op); in tcg_optimize()
3008 done = fold_setcond(&ctx, op); in tcg_optimize()
3011 done = fold_negsetcond(&ctx, op); in tcg_optimize()
3014 done = fold_setcond2(&ctx, op); in tcg_optimize()
3017 done = fold_cmp_vec(&ctx, op); in tcg_optimize()
3020 done = fold_cmpsel_vec(&ctx, op); in tcg_optimize()
3023 done = fold_bitsel_vec(&ctx, op); in tcg_optimize()
3026 done = fold_sextract(&ctx, op); in tcg_optimize()
3029 done = fold_sub(&ctx, op); in tcg_optimize()
3032 done = fold_sub_vec(&ctx, op); in tcg_optimize()
3035 done = fold_sub2(&ctx, op); in tcg_optimize()
3038 done = fold_xor(&ctx, op); in tcg_optimize()
3045 finish_folding(&ctx, op); in tcg_optimize()