return nb_tbs;
}
+static gboolean tcg_region_tree_traverse(gpointer k, gpointer v, gpointer data)
+{
+ TranslationBlock *tb = v;
+
+ tb_destroy(tb);
+ return FALSE;
+}
+
static void tcg_region_tree_reset_all(void)
{
size_t i;
for (i = 0; i < region.n; i++) {
struct tcg_region_tree *rt = region_trees + i * tree_size;
+ g_tree_foreach(rt->tree, tcg_region_tree_traverse, NULL);
/* Increment the refcount first so that destroy acts as a reset */
g_tree_ref(rt->tree);
g_tree_destroy(rt->tree);
return have_vec && TCG_TARGET_HAS_shv_vec;
case INDEX_op_rotli_vec:
return have_vec && TCG_TARGET_HAS_roti_vec;
+ case INDEX_op_rotls_vec:
+ return have_vec && TCG_TARGET_HAS_rots_vec;
+ case INDEX_op_rotlv_vec:
+ case INDEX_op_rotrv_vec:
+ return have_vec && TCG_TARGET_HAS_rotv_vec;
case INDEX_op_ssadd_vec:
case INDEX_op_usadd_vec:
case INDEX_op_sssub_vec:
}
/* Outputs become available. */
- for (i = 0; i < nb_oargs; i++) {
- arg_ts = arg_temp(op->args[i]);
+ if (opc == INDEX_op_mov_i32 || opc == INDEX_op_mov_i64) {
+ arg_ts = arg_temp(op->args[0]);
dir_ts = arg_ts->state_ptr;
- if (!dir_ts) {
- continue;
+ if (dir_ts) {
+ op->args[0] = temp_arg(dir_ts);
+ changes = true;
+
+ /* The output is now live and modified. */
+ arg_ts->state = 0;
+
+ if (NEED_SYNC_ARG(0)) {
+ TCGOpcode sopc = (arg_ts->type == TCG_TYPE_I32
+ ? INDEX_op_st_i32
+ : INDEX_op_st_i64);
+ TCGOp *sop = tcg_op_insert_after(s, op, sopc);
+ TCGTemp *out_ts = dir_ts;
+
+ if (IS_DEAD_ARG(0)) {
+ out_ts = arg_temp(op->args[1]);
+ arg_ts->state = TS_DEAD;
+ tcg_op_remove(s, op);
+ } else {
+ arg_ts->state = TS_MEM;
+ }
+
+ sop->args[0] = temp_arg(out_ts);
+ sop->args[1] = temp_arg(arg_ts->mem_base);
+ sop->args[2] = arg_ts->mem_offset;
+ } else {
+ tcg_debug_assert(!IS_DEAD_ARG(0));
+ }
}
- op->args[i] = temp_arg(dir_ts);
- changes = true;
+ } else {
+ for (i = 0; i < nb_oargs; i++) {
+ arg_ts = arg_temp(op->args[i]);
+ dir_ts = arg_ts->state_ptr;
+ if (!dir_ts) {
+ continue;
+ }
+ op->args[i] = temp_arg(dir_ts);
+ changes = true;
- /* The output is now live and modified. */
- arg_ts->state = 0;
+ /* The output is now live and modified. */
+ arg_ts->state = 0;
- /* Sync outputs upon their last write. */
- if (NEED_SYNC_ARG(i)) {
- TCGOpcode sopc = (arg_ts->type == TCG_TYPE_I32
- ? INDEX_op_st_i32
- : INDEX_op_st_i64);
- TCGOp *sop = tcg_op_insert_after(s, op, sopc);
+ /* Sync outputs upon their last write. */
+ if (NEED_SYNC_ARG(i)) {
+ TCGOpcode sopc = (arg_ts->type == TCG_TYPE_I32
+ ? INDEX_op_st_i32
+ : INDEX_op_st_i64);
+ TCGOp *sop = tcg_op_insert_after(s, op, sopc);
- sop->args[0] = temp_arg(dir_ts);
- sop->args[1] = temp_arg(arg_ts->mem_base);
- sop->args[2] = arg_ts->mem_offset;
+ sop->args[0] = temp_arg(dir_ts);
+ sop->args[1] = temp_arg(arg_ts->mem_base);
+ sop->args[2] = arg_ts->mem_offset;
- arg_ts->state = TS_MEM;
- }
- /* Drop outputs that are dead. */
- if (IS_DEAD_ARG(i)) {
- arg_ts->state = TS_DEAD;
+ arg_ts->state = TS_MEM;
+ }
+ /* Drop outputs that are dead. */
+ if (IS_DEAD_ARG(i)) {
+ arg_ts->state = TS_DEAD;
+ }
}
}
}