mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-07-06 02:00:34 +00:00
tcg: Propagate TCGOp down to allocators
Backports commit dd186292017641d5b31fc13225a420677e1d20d3 from qemu
This commit is contained in:
parent
f1e2ea6847
commit
c8f0f6901e
|
@ -2412,25 +2412,24 @@ static void tcg_reg_alloc_do_movi(TCGContext *s, TCGTemp *ots,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tcg_reg_alloc_movi(TCGContext *s, const TCGArg *args,
|
static void tcg_reg_alloc_movi(TCGContext *s, const TCGOp *op)
|
||||||
TCGLifeData arg_life)
|
|
||||||
{
|
{
|
||||||
TCGTemp *ots = &s->temps[args[0]];
|
TCGTemp *ots = &s->temps[op->args[0]];
|
||||||
tcg_target_ulong val = args[1];
|
tcg_target_ulong val = op->args[1];
|
||||||
|
|
||||||
tcg_reg_alloc_do_movi(s, ots, val, arg_life);
|
tcg_reg_alloc_do_movi(s, ots, val, op->life);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
|
static void tcg_reg_alloc_mov(TCGContext *s, const TCGOp *op)
|
||||||
const TCGArg *args, TCGLifeData arg_life)
|
|
||||||
{
|
{
|
||||||
|
const TCGLifeData arg_life = op->life;
|
||||||
TCGRegSet allocated_regs;
|
TCGRegSet allocated_regs;
|
||||||
TCGTemp *ts, *ots;
|
TCGTemp *ts, *ots;
|
||||||
TCGType otype, itype;
|
TCGType otype, itype;
|
||||||
|
|
||||||
allocated_regs = s->reserved_regs;
|
allocated_regs = s->reserved_regs;
|
||||||
ots = &s->temps[args[0]];
|
ots = &s->temps[op->args[0]];
|
||||||
ts = &s->temps[args[1]];
|
ts = &s->temps[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;
|
||||||
|
@ -2460,7 +2459,7 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
|
||||||
liveness analysis disabled). */
|
liveness analysis disabled). */
|
||||||
tcg_debug_assert(NEED_SYNC_ARG(0));
|
tcg_debug_assert(NEED_SYNC_ARG(0));
|
||||||
if (!ots->mem_allocated) {
|
if (!ots->mem_allocated) {
|
||||||
temp_allocate_frame(s, args[0]);
|
temp_allocate_frame(s, op->args[0]);
|
||||||
}
|
}
|
||||||
tcg_out_st(s, otype, ts->reg, ots->mem_base->reg, ots->mem_offset);
|
tcg_out_st(s, otype, ts->reg, ots->mem_base->reg, ots->mem_offset);
|
||||||
if (IS_DEAD_ARG(1)) {
|
if (IS_DEAD_ARG(1)) {
|
||||||
|
@ -2494,10 +2493,10 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tcg_reg_alloc_op(TCGContext *s,
|
static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
|
||||||
const TCGOpDef *def, TCGOpcode opc,
|
|
||||||
const TCGArg *args, TCGLifeData arg_life)
|
|
||||||
{
|
{
|
||||||
|
const TCGLifeData arg_life = op->life;
|
||||||
|
const TCGOpDef * const def = &s->tcg_op_defs[op->opc];
|
||||||
TCGRegSet i_allocated_regs;
|
TCGRegSet i_allocated_regs;
|
||||||
TCGRegSet o_allocated_regs;
|
TCGRegSet o_allocated_regs;
|
||||||
int i, k, nb_iargs, nb_oargs;
|
int i, k, nb_iargs, nb_oargs;
|
||||||
|
@ -2513,16 +2512,16 @@ static void tcg_reg_alloc_op(TCGContext *s,
|
||||||
|
|
||||||
/* copy constants */
|
/* copy constants */
|
||||||
memcpy(new_args + nb_oargs + nb_iargs,
|
memcpy(new_args + nb_oargs + nb_iargs,
|
||||||
args + nb_oargs + nb_iargs,
|
op->args + nb_oargs + nb_iargs,
|
||||||
sizeof(TCGArg) * def->nb_cargs);
|
sizeof(TCGArg) * def->nb_cargs);
|
||||||
|
|
||||||
i_allocated_regs = s->reserved_regs;
|
i_allocated_regs = s->reserved_regs;
|
||||||
o_allocated_regs = s->reserved_regs;
|
o_allocated_regs = s->reserved_regs;
|
||||||
|
|
||||||
/* satisfy input constraints */
|
/* satisfy input constraints */
|
||||||
for(k = 0; k < nb_iargs; k++) {
|
for (k = 0; k < nb_iargs; k++) {
|
||||||
i = def->sorted_args[nb_oargs + k];
|
i = def->sorted_args[nb_oargs + k];
|
||||||
arg = args[i];
|
arg = op->args[i];
|
||||||
arg_ct = &def->args_ct[i];
|
arg_ct = &def->args_ct[i];
|
||||||
ts = &s->temps[arg];
|
ts = &s->temps[arg];
|
||||||
|
|
||||||
|
@ -2540,7 +2539,7 @@ static void tcg_reg_alloc_op(TCGContext *s,
|
||||||
if (ts->fixed_reg) {
|
if (ts->fixed_reg) {
|
||||||
/* if fixed register, we must allocate a new register
|
/* if fixed register, we must allocate a new register
|
||||||
if the alias is not the same register */
|
if the alias is not the same register */
|
||||||
if (arg != args[arg_ct->alias_index])
|
if (arg != op->args[arg_ct->alias_index])
|
||||||
goto allocate_in_reg;
|
goto allocate_in_reg;
|
||||||
} else {
|
} else {
|
||||||
/* if the input is aliased to an output and if it is
|
/* if the input is aliased to an output and if it is
|
||||||
|
@ -2581,7 +2580,7 @@ static void tcg_reg_alloc_op(TCGContext *s,
|
||||||
/* 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[args[i]]);
|
temp_dead(s, &s->temps[op->args[i]]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2605,7 +2604,7 @@ static void tcg_reg_alloc_op(TCGContext *s,
|
||||||
/* satisfy the output constraints */
|
/* satisfy the output constraints */
|
||||||
for(k = 0; k < nb_oargs; k++) {
|
for(k = 0; k < nb_oargs; k++) {
|
||||||
i = def->sorted_args[k];
|
i = def->sorted_args[k];
|
||||||
arg = args[i];
|
arg = op->args[i];
|
||||||
arg_ct = &def->args_ct[i];
|
arg_ct = &def->args_ct[i];
|
||||||
ts = &s->temps[arg];
|
ts = &s->temps[arg];
|
||||||
if ((arg_ct->ct & TCG_CT_ALIAS)
|
if ((arg_ct->ct & TCG_CT_ALIAS)
|
||||||
|
@ -2644,11 +2643,11 @@ static void tcg_reg_alloc_op(TCGContext *s,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* emit instruction */
|
/* emit instruction */
|
||||||
tcg_out_op(s, opc, new_args, const_args);
|
tcg_out_op(s, op->opc, new_args, const_args);
|
||||||
|
|
||||||
/* 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[args[i]];
|
ts = &s->temps[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);
|
||||||
|
@ -2667,9 +2666,11 @@ static void tcg_reg_alloc_op(TCGContext *s,
|
||||||
#define STACK_DIR(x) (x)
|
#define STACK_DIR(x) (x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void tcg_reg_alloc_call(TCGContext *s, int nb_oargs, int nb_iargs,
|
static void tcg_reg_alloc_call(TCGContext *s, TCGOp *op)
|
||||||
const TCGArg * const args, TCGLifeData arg_life)
|
|
||||||
{
|
{
|
||||||
|
const int nb_oargs = op->callo;
|
||||||
|
const int nb_iargs = op->calli;
|
||||||
|
const TCGLifeData arg_life = op->life;
|
||||||
int flags, nb_regs, i;
|
int flags, nb_regs, i;
|
||||||
TCGReg reg;
|
TCGReg reg;
|
||||||
TCGArg arg;
|
TCGArg arg;
|
||||||
|
@ -2680,8 +2681,8 @@ static void tcg_reg_alloc_call(TCGContext *s, int nb_oargs, int nb_iargs,
|
||||||
int allocate_args;
|
int allocate_args;
|
||||||
TCGRegSet allocated_regs;
|
TCGRegSet allocated_regs;
|
||||||
|
|
||||||
func_addr = (tcg_insn_unit *)(intptr_t)args[nb_oargs + nb_iargs];
|
func_addr = (tcg_insn_unit *)(intptr_t)op->args[nb_oargs + nb_iargs];
|
||||||
flags = args[nb_oargs + nb_iargs + 1];
|
flags = op->args[nb_oargs + nb_iargs + 1];
|
||||||
|
|
||||||
nb_regs = ARRAY_SIZE(tcg_target_call_iarg_regs);
|
nb_regs = ARRAY_SIZE(tcg_target_call_iarg_regs);
|
||||||
#if TCG_TARGET_REG_BITS == 32
|
#if TCG_TARGET_REG_BITS == 32
|
||||||
|
@ -2704,8 +2705,8 @@ static void tcg_reg_alloc_call(TCGContext *s, int nb_oargs, int nb_iargs,
|
||||||
}
|
}
|
||||||
|
|
||||||
stack_offset = TCG_TARGET_CALL_STACK_OFFSET;
|
stack_offset = TCG_TARGET_CALL_STACK_OFFSET;
|
||||||
for(i = nb_regs; i < nb_iargs; i++) {
|
for (i = nb_regs; i < nb_iargs; i++) {
|
||||||
arg = args[nb_oargs + i];
|
arg = op->args[nb_oargs + i];
|
||||||
#ifdef TCG_TARGET_STACK_GROWSUP
|
#ifdef TCG_TARGET_STACK_GROWSUP
|
||||||
stack_offset -= sizeof(tcg_target_long);
|
stack_offset -= sizeof(tcg_target_long);
|
||||||
#endif
|
#endif
|
||||||
|
@ -2722,8 +2723,8 @@ static void tcg_reg_alloc_call(TCGContext *s, int nb_oargs, int nb_iargs,
|
||||||
|
|
||||||
/* assign input registers */
|
/* assign input registers */
|
||||||
allocated_regs = s->reserved_regs;
|
allocated_regs = s->reserved_regs;
|
||||||
for(i = 0; i < nb_regs; i++) {
|
for (i = 0; i < nb_regs; i++) {
|
||||||
arg = 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 = &s->temps[arg];
|
||||||
reg = tcg_target_call_iarg_regs[i];
|
reg = tcg_target_call_iarg_regs[i];
|
||||||
|
@ -2745,9 +2746,9 @@ static void tcg_reg_alloc_call(TCGContext *s, int nb_oargs, int nb_iargs,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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[args[i]]);
|
temp_dead(s, &s->temps[op->args[i]]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2772,7 +2773,7 @@ static void tcg_reg_alloc_call(TCGContext *s, int nb_oargs, int nb_iargs,
|
||||||
|
|
||||||
/* 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 = args[i];
|
arg = op->args[i];
|
||||||
ts = &s->temps[arg];
|
ts = &s->temps[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);
|
||||||
|
@ -2906,8 +2907,6 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
|
||||||
for (oi = s->gen_op_buf[0].next; oi != 0; oi = oi_next) {
|
for (oi = s->gen_op_buf[0].next; oi != 0; oi = oi_next) {
|
||||||
TCGOp * const op = &s->gen_op_buf[oi];
|
TCGOp * const op = &s->gen_op_buf[oi];
|
||||||
TCGOpcode opc = op->opc;
|
TCGOpcode opc = op->opc;
|
||||||
const TCGOpDef *def = &s->tcg_op_defs[opc];
|
|
||||||
TCGLifeData arg_life = op->life;
|
|
||||||
|
|
||||||
oi_next = op->next;
|
oi_next = op->next;
|
||||||
#ifdef CONFIG_PROFILER
|
#ifdef CONFIG_PROFILER
|
||||||
|
@ -2916,11 +2915,11 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
|
||||||
switch (opc) {
|
switch (opc) {
|
||||||
case INDEX_op_mov_i32:
|
case INDEX_op_mov_i32:
|
||||||
case INDEX_op_mov_i64:
|
case INDEX_op_mov_i64:
|
||||||
tcg_reg_alloc_mov(s, def, op->args, arg_life);
|
tcg_reg_alloc_mov(s, op);
|
||||||
break;
|
break;
|
||||||
case INDEX_op_movi_i32:
|
case INDEX_op_movi_i32:
|
||||||
case INDEX_op_movi_i64:
|
case INDEX_op_movi_i64:
|
||||||
tcg_reg_alloc_movi(s, op->args, arg_life);
|
tcg_reg_alloc_movi(s, op);
|
||||||
break;
|
break;
|
||||||
case INDEX_op_insn_start:
|
case INDEX_op_insn_start:
|
||||||
if (num_insns >= 0) {
|
if (num_insns >= 0) {
|
||||||
|
@ -2945,7 +2944,7 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
|
||||||
tcg_out_label(s, arg_label(s, op->args[0]), s->code_ptr);
|
tcg_out_label(s, arg_label(s, op->args[0]), s->code_ptr);
|
||||||
break;
|
break;
|
||||||
case INDEX_op_call:
|
case INDEX_op_call:
|
||||||
tcg_reg_alloc_call(s, op->callo, op->calli, op->args, arg_life);
|
tcg_reg_alloc_call(s, op);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* Sanity check that we've not introduced any unhandled opcodes. */
|
/* Sanity check that we've not introduced any unhandled opcodes. */
|
||||||
|
@ -2953,7 +2952,7 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
|
||||||
/* Note: in order to speed up the code, it would be much
|
/* Note: in order to speed up the code, it would be much
|
||||||
faster to have specialized register allocator functions for
|
faster to have specialized register allocator functions for
|
||||||
some common argument patterns */
|
some common argument patterns */
|
||||||
tcg_reg_alloc_op(s, def, opc, op->args, arg_life);
|
tcg_reg_alloc_op(s, op);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#ifdef CONFIG_DEBUG_TCG
|
#ifdef CONFIG_DEBUG_TCG
|
||||||
|
|
Loading…
Reference in a new issue