mirror of
				https://github.com/yuzu-emu/unicorn.git
				synced 2025-11-04 10:54:56 +00:00 
			
		
		
		
	tcg: Introduce arg_temp
Backports commit 434391390ba99996af1591b427a73b3f5c05065e from qemu
This commit is contained in:
		
							parent
							
								
									c8f0f6901e
								
							
						
					
					
						commit
						a9c46ad7a0
					
				| 
						 | 
					@ -133,7 +133,7 @@ static TCGArg find_better_copy(TCGContext *s, TCGArg temp)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* If it is a temp, search for a temp local. */
 | 
					    /* If it is a temp, search for a temp local. */
 | 
				
			||||||
    if (!s->temps[temp].temp_local) {
 | 
					    if (!arg_temp(s, temp)->temp_local) {
 | 
				
			||||||
        for (i = temps[temp].next_copy ; i != temp ; i = temps[i].next_copy) {
 | 
					        for (i = temps[temp].next_copy ; i != temp ; i = temps[i].next_copy) {
 | 
				
			||||||
            if (s->temps[i].temp_local) {
 | 
					            if (s->temps[i].temp_local) {
 | 
				
			||||||
                return i;
 | 
					                return i;
 | 
				
			||||||
| 
						 | 
					@ -211,7 +211,7 @@ static void tcg_opt_gen_mov(TCGContext *s, TCGOp *op, TCGArg dst, TCGArg src)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    temps[dst].mask = mask;
 | 
					    temps[dst].mask = mask;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (s->temps[src].type == s->temps[dst].type) {
 | 
					    if (arg_temp(s, src)->type == arg_temp(s, dst)->type) {
 | 
				
			||||||
        temps[dst].next_copy = temps[src].next_copy;
 | 
					        temps[dst].next_copy = temps[src].next_copy;
 | 
				
			||||||
        temps[dst].prev_copy = src;
 | 
					        temps[dst].prev_copy = src;
 | 
				
			||||||
        temps[temps[dst].next_copy].prev_copy = dst;
 | 
					        temps[temps[dst].next_copy].prev_copy = dst;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1190,11 +1190,10 @@ static char *tcg_get_arg_str_ptr(TCGContext *s, char *buf, int buf_size,
 | 
				
			||||||
    return buf;
 | 
					    return buf;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static char *tcg_get_arg_str_idx(TCGContext *s, char *buf,
 | 
					static char *tcg_get_arg_str(TCGContext *s, char *buf,
 | 
				
			||||||
                                 int buf_size, int idx)
 | 
					                             int buf_size, TCGArg arg)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    tcg_debug_assert(idx >= 0 && idx < s->nb_temps);
 | 
					    return tcg_get_arg_str_ptr(s, buf, buf_size, arg_temp(s, arg));
 | 
				
			||||||
    return tcg_get_arg_str_ptr(s, buf, buf_size, &s->temps[idx]);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Find helper name.  */
 | 
					/* Find helper name.  */
 | 
				
			||||||
| 
						 | 
					@ -1354,14 +1353,14 @@ void tcg_dump_ops(TCGContext *s)
 | 
				
			||||||
                            tcg_find_helper(s, op->args[nb_oargs + nb_iargs]),
 | 
					                            tcg_find_helper(s, op->args[nb_oargs + nb_iargs]),
 | 
				
			||||||
                            op->args[nb_oargs + nb_iargs + 1], nb_oargs);
 | 
					                            op->args[nb_oargs + nb_iargs + 1], nb_oargs);
 | 
				
			||||||
            for (i = 0; i < nb_oargs; i++) {
 | 
					            for (i = 0; i < nb_oargs; i++) {
 | 
				
			||||||
                col += qemu_log(",%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
 | 
					                col += qemu_log(",%s", tcg_get_arg_str(s, buf, sizeof(buf),
 | 
				
			||||||
                                                       op->args[i]));
 | 
					                                                       op->args[i]));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            for (i = 0; i < nb_iargs; i++) {
 | 
					            for (i = 0; i < nb_iargs; i++) {
 | 
				
			||||||
                TCGArg arg = op->args[nb_oargs + i];
 | 
					                TCGArg arg = op->args[nb_oargs + i];
 | 
				
			||||||
                const char *t = "<dummy>";
 | 
					                const char *t = "<dummy>";
 | 
				
			||||||
                if (arg != TCG_CALL_DUMMY_ARG) {
 | 
					                if (arg != TCG_CALL_DUMMY_ARG) {
 | 
				
			||||||
                    t = tcg_get_arg_str_idx(s, buf, sizeof(buf), arg);
 | 
					                    t = tcg_get_arg_str(s, buf, sizeof(buf), arg);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                col += qemu_log(",%s", t);
 | 
					                col += qemu_log(",%s", t);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
| 
						 | 
					@ -1377,14 +1376,14 @@ void tcg_dump_ops(TCGContext *s)
 | 
				
			||||||
                if (k != 0) {
 | 
					                if (k != 0) {
 | 
				
			||||||
                    col += qemu_log(",");
 | 
					                    col += qemu_log(",");
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                col += qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
 | 
					                col += qemu_log("%s", tcg_get_arg_str(s, buf, sizeof(buf),
 | 
				
			||||||
                                                      op->args[k++]));
 | 
					                                                      op->args[k++]));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            for (i = 0; i < nb_iargs; i++) {
 | 
					            for (i = 0; i < nb_iargs; i++) {
 | 
				
			||||||
                if (k != 0) {
 | 
					                if (k != 0) {
 | 
				
			||||||
                    col += qemu_log(",");
 | 
					                    col += qemu_log(",");
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                col += qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf),
 | 
					                col += qemu_log("%s", tcg_get_arg_str(s, buf, sizeof(buf),
 | 
				
			||||||
                                                      op->args[k++]));
 | 
					                                                      op->args[k++]));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            switch (c) {
 | 
					            switch (c) {
 | 
				
			||||||
| 
						 | 
					@ -2009,7 +2008,7 @@ static bool liveness_pass_2(TCGContext *s, uint8_t *temp_state)
 | 
				
			||||||
            if (arg < nb_globals) {
 | 
					            if (arg < nb_globals) {
 | 
				
			||||||
                dir = dir_temps[arg];
 | 
					                dir = dir_temps[arg];
 | 
				
			||||||
                if (dir != 0 && temp_state[arg] == TS_DEAD) {
 | 
					                if (dir != 0 && temp_state[arg] == TS_DEAD) {
 | 
				
			||||||
                    TCGTemp *its = &s->temps[arg];
 | 
					                    TCGTemp *its = arg_temp(s, arg);
 | 
				
			||||||
                    TCGOpcode lopc = (its->type == TCG_TYPE_I32
 | 
					                    TCGOpcode lopc = (its->type == TCG_TYPE_I32
 | 
				
			||||||
                                      ? INDEX_op_ld_i32
 | 
					                                      ? INDEX_op_ld_i32
 | 
				
			||||||
                                      : INDEX_op_ld_i64);
 | 
					                                      : INDEX_op_ld_i64);
 | 
				
			||||||
| 
						 | 
					@ -2080,7 +2079,7 @@ static bool liveness_pass_2(TCGContext *s, uint8_t *temp_state)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            /* Sync outputs upon their last write.  */
 | 
					            /* Sync outputs upon their last write.  */
 | 
				
			||||||
            if (NEED_SYNC_ARG(i)) {
 | 
					            if (NEED_SYNC_ARG(i)) {
 | 
				
			||||||
                TCGTemp *its = &s->temps[arg];
 | 
					                TCGTemp *its = arg_temp(s, arg);
 | 
				
			||||||
                TCGOpcode sopc = (its->type == TCG_TYPE_I32
 | 
					                TCGOpcode sopc = (its->type == TCG_TYPE_I32
 | 
				
			||||||
                                  ? INDEX_op_st_i32
 | 
					                                  ? INDEX_op_st_i32
 | 
				
			||||||
                                  : INDEX_op_st_i64);
 | 
					                                  : INDEX_op_st_i64);
 | 
				
			||||||
| 
						 | 
					@ -2111,7 +2110,7 @@ static void dump_regs(TCGContext *s)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for(i = 0; i < s->nb_temps; i++) {
 | 
					    for(i = 0; i < s->nb_temps; i++) {
 | 
				
			||||||
        ts = &s->temps[i];
 | 
					        ts = &s->temps[i];
 | 
				
			||||||
        printf("  %10s: ", tcg_get_arg_str_idx(s, buf, sizeof(buf), i));
 | 
					        printf("  %10s: ", tcg_get_arg_str_ptr(s, buf, sizeof(buf), ts));
 | 
				
			||||||
        switch(ts->val_type) {
 | 
					        switch(ts->val_type) {
 | 
				
			||||||
        case TEMP_VAL_REG:
 | 
					        case TEMP_VAL_REG:
 | 
				
			||||||
            printf("%s", tcg_target_reg_names[ts->reg]);
 | 
					            printf("%s", tcg_target_reg_names[ts->reg]);
 | 
				
			||||||
| 
						 | 
					@ -2414,7 +2413,7 @@ static void tcg_reg_alloc_do_movi(TCGContext *s, TCGTemp *ots,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void tcg_reg_alloc_movi(TCGContext *s, const TCGOp *op)
 | 
					static void tcg_reg_alloc_movi(TCGContext *s, const TCGOp *op)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    TCGTemp *ots = &s->temps[op->args[0]];
 | 
					    TCGTemp *ots = arg_temp(s, op->args[0]);
 | 
				
			||||||
    tcg_target_ulong val = op->args[1];
 | 
					    tcg_target_ulong val = op->args[1];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    tcg_reg_alloc_do_movi(s, ots, val, op->life);
 | 
					    tcg_reg_alloc_do_movi(s, ots, val, op->life);
 | 
				
			||||||
| 
						 | 
					@ -2428,8 +2427,8 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOp *op)
 | 
				
			||||||
    TCGType otype, itype;
 | 
					    TCGType otype, itype;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    allocated_regs = s->reserved_regs;
 | 
					    allocated_regs = s->reserved_regs;
 | 
				
			||||||
    ots = &s->temps[op->args[0]];
 | 
					    ots = arg_temp(s, op->args[0]);
 | 
				
			||||||
    ts = &s->temps[op->args[1]];
 | 
					    ts = arg_temp(s, op->args[1]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Note that otype != itype for no-op truncation.  */
 | 
					    /* Note that otype != itype for no-op truncation.  */
 | 
				
			||||||
    otype = ots->type;
 | 
					    otype = ots->type;
 | 
				
			||||||
| 
						 | 
					@ -2523,7 +2522,7 @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
 | 
				
			||||||
        i = def->sorted_args[nb_oargs + k];
 | 
					        i = def->sorted_args[nb_oargs + k];
 | 
				
			||||||
        arg = op->args[i];
 | 
					        arg = op->args[i];
 | 
				
			||||||
        arg_ct = &def->args_ct[i];
 | 
					        arg_ct = &def->args_ct[i];
 | 
				
			||||||
        ts = &s->temps[arg];
 | 
					        ts = arg_temp(s, arg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (ts->val_type == TEMP_VAL_CONST
 | 
					        if (ts->val_type == TEMP_VAL_CONST
 | 
				
			||||||
            && tcg_target_const_match(ts->val, ts->type, arg_ct)) {
 | 
					            && tcg_target_const_match(ts->val, ts->type, arg_ct)) {
 | 
				
			||||||
| 
						 | 
					@ -2580,7 +2579,7 @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
 | 
				
			||||||
    /* mark dead temporaries and free the associated registers */
 | 
					    /* mark dead temporaries and free the associated registers */
 | 
				
			||||||
    for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
 | 
					    for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
 | 
				
			||||||
        if (IS_DEAD_ARG(i)) {
 | 
					        if (IS_DEAD_ARG(i)) {
 | 
				
			||||||
            temp_dead(s, &s->temps[op->args[i]]);
 | 
					            temp_dead(s, arg_temp(s, op->args[i]));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2606,7 +2605,7 @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
 | 
				
			||||||
            i = def->sorted_args[k];
 | 
					            i = def->sorted_args[k];
 | 
				
			||||||
            arg = op->args[i];
 | 
					            arg = op->args[i];
 | 
				
			||||||
            arg_ct = &def->args_ct[i];
 | 
					            arg_ct = &def->args_ct[i];
 | 
				
			||||||
            ts = &s->temps[arg];
 | 
					            ts = arg_temp(s, arg);
 | 
				
			||||||
            if ((arg_ct->ct & TCG_CT_ALIAS)
 | 
					            if ((arg_ct->ct & TCG_CT_ALIAS)
 | 
				
			||||||
                && !const_args[arg_ct->alias_index]) {
 | 
					                && !const_args[arg_ct->alias_index]) {
 | 
				
			||||||
                reg = new_args[arg_ct->alias_index];
 | 
					                reg = new_args[arg_ct->alias_index];
 | 
				
			||||||
| 
						 | 
					@ -2647,7 +2646,7 @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* move the outputs in the correct register if needed */
 | 
					    /* move the outputs in the correct register if needed */
 | 
				
			||||||
    for(i = 0; i < nb_oargs; i++) {
 | 
					    for(i = 0; i < nb_oargs; i++) {
 | 
				
			||||||
        ts = &s->temps[op->args[i]];
 | 
					        ts = arg_temp(s, op->args[i]);
 | 
				
			||||||
        reg = new_args[i];
 | 
					        reg = new_args[i];
 | 
				
			||||||
        if (ts->fixed_reg && ts->reg != reg) {
 | 
					        if (ts->fixed_reg && ts->reg != reg) {
 | 
				
			||||||
            tcg_out_mov(s, ts->type, ts->reg, reg);
 | 
					            tcg_out_mov(s, ts->type, ts->reg, reg);
 | 
				
			||||||
| 
						 | 
					@ -2711,7 +2710,7 @@ static void tcg_reg_alloc_call(TCGContext *s, TCGOp *op)
 | 
				
			||||||
        stack_offset -= sizeof(tcg_target_long);
 | 
					        stack_offset -= sizeof(tcg_target_long);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
        if (arg != TCG_CALL_DUMMY_ARG) {
 | 
					        if (arg != TCG_CALL_DUMMY_ARG) {
 | 
				
			||||||
            ts = &s->temps[arg];
 | 
					            ts = arg_temp(s, arg);
 | 
				
			||||||
            temp_load(s, ts, s->tcg_target_available_regs[ts->type],
 | 
					            temp_load(s, ts, s->tcg_target_available_regs[ts->type],
 | 
				
			||||||
                      s->reserved_regs);
 | 
					                      s->reserved_regs);
 | 
				
			||||||
            tcg_out_st(s, ts->type, ts->reg, TCG_REG_CALL_STACK, stack_offset);
 | 
					            tcg_out_st(s, ts->type, ts->reg, TCG_REG_CALL_STACK, stack_offset);
 | 
				
			||||||
| 
						 | 
					@ -2726,7 +2725,7 @@ static void tcg_reg_alloc_call(TCGContext *s, TCGOp *op)
 | 
				
			||||||
    for (i = 0; i < nb_regs; i++) {
 | 
					    for (i = 0; i < nb_regs; i++) {
 | 
				
			||||||
        arg = op->args[nb_oargs + i];
 | 
					        arg = op->args[nb_oargs + i];
 | 
				
			||||||
        if (arg != TCG_CALL_DUMMY_ARG) {
 | 
					        if (arg != TCG_CALL_DUMMY_ARG) {
 | 
				
			||||||
            ts = &s->temps[arg];
 | 
					            ts = arg_temp(s, arg);
 | 
				
			||||||
            reg = tcg_target_call_iarg_regs[i];
 | 
					            reg = tcg_target_call_iarg_regs[i];
 | 
				
			||||||
            tcg_reg_free(s, reg, allocated_regs);
 | 
					            tcg_reg_free(s, reg, allocated_regs);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2748,7 +2747,7 @@ static void tcg_reg_alloc_call(TCGContext *s, TCGOp *op)
 | 
				
			||||||
    /* mark dead temporaries and free the associated registers */
 | 
					    /* mark dead temporaries and free the associated registers */
 | 
				
			||||||
    for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
 | 
					    for (i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
 | 
				
			||||||
        if (IS_DEAD_ARG(i)) {
 | 
					        if (IS_DEAD_ARG(i)) {
 | 
				
			||||||
            temp_dead(s, &s->temps[op->args[i]]);
 | 
					            temp_dead(s, arg_temp(s, op->args[i]));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2774,7 +2773,7 @@ static void tcg_reg_alloc_call(TCGContext *s, TCGOp *op)
 | 
				
			||||||
    /* assign output registers and emit moves if needed */
 | 
					    /* assign output registers and emit moves if needed */
 | 
				
			||||||
    for(i = 0; i < nb_oargs; i++) {
 | 
					    for(i = 0; i < nb_oargs; i++) {
 | 
				
			||||||
        arg = op->args[i];
 | 
					        arg = op->args[i];
 | 
				
			||||||
        ts = &s->temps[arg];
 | 
					        ts = arg_temp(s, arg);
 | 
				
			||||||
        reg = tcg_target_call_oarg_regs[i];
 | 
					        reg = tcg_target_call_oarg_regs[i];
 | 
				
			||||||
        tcg_debug_assert(s->reg_to_temp[reg] == NULL);
 | 
					        tcg_debug_assert(s->reg_to_temp[reg] == NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2937,7 +2936,7 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        case INDEX_op_discard:
 | 
					        case INDEX_op_discard:
 | 
				
			||||||
            temp_dead(s, &s->temps[op->args[0]]);
 | 
					            temp_dead(s, arg_temp(s, op->args[0]));
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        case INDEX_op_set_label:
 | 
					        case INDEX_op_set_label:
 | 
				
			||||||
            tcg_reg_alloc_bb_end(s, s->reserved_regs);
 | 
					            tcg_reg_alloc_bb_end(s, s->reserved_regs);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -983,6 +983,11 @@ struct TCGContext {
 | 
				
			||||||
    TCGLabel *exitreq_label;  // gen_tb_start()
 | 
					    TCGLabel *exitreq_label;  // gen_tb_start()
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline TCGTemp *arg_temp(TCGContext *tcg_ctx, TCGArg a)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return &tcg_ctx->temps[a];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void tcg_set_insn_param(TCGContext *tcg_ctx, int op_idx, int arg, TCGArg v)
 | 
					static inline void tcg_set_insn_param(TCGContext *tcg_ctx, int op_idx, int arg, TCGArg v)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    tcg_ctx->gen_op_buf[op_idx].args[arg] = v;
 | 
					    tcg_ctx->gen_op_buf[op_idx].args[arg] = v;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue