mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-01-18 17:47:18 +00:00
tcg: Hoist max_insns computation to tb_gen_code
In order to handle TB's that translate to too much code, we need to place the control of the length of the translation in the hands of the code gen master loop. Backports commit 8b86d6d25807e13a63ab6ea879f976b9f18cc45a from qemu
This commit is contained in:
parent
2479bbd3b2
commit
bca82cde84
|
@ -1325,16 +1325,26 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
|
||||||
TranslationBlock *tb;
|
TranslationBlock *tb;
|
||||||
tb_page_addr_t phys_pc, phys_page2;
|
tb_page_addr_t phys_pc, phys_page2;
|
||||||
tcg_insn_unit *gen_code_buf;
|
tcg_insn_unit *gen_code_buf;
|
||||||
int gen_code_size, search_size;
|
int gen_code_size, search_size, max_insns;
|
||||||
#ifdef CONFIG_PROFILER
|
#ifdef CONFIG_PROFILER
|
||||||
int64_t ti;
|
int64_t ti;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
phys_pc = get_page_addr_code(env, pc);
|
phys_pc = get_page_addr_code(env, pc);
|
||||||
/* UNICORN: Commented out
|
|
||||||
if (use_icount) {
|
/* Instruction counting */
|
||||||
cflags |= CF_USE_ICOUNT;
|
max_insns = cflags & CF_COUNT_MASK;
|
||||||
}*/
|
if (max_insns == 0) {
|
||||||
|
max_insns = CF_COUNT_MASK;
|
||||||
|
}
|
||||||
|
if (max_insns > TCG_MAX_INSNS) {
|
||||||
|
max_insns = TCG_MAX_INSNS;
|
||||||
|
}
|
||||||
|
// Unicorn: commented out
|
||||||
|
if (cpu->singlestep_enabled /*|| singlestep*/) {
|
||||||
|
max_insns = 1;
|
||||||
|
}
|
||||||
|
|
||||||
tb = tb_alloc(env->uc, pc);
|
tb = tb_alloc(env->uc, pc);
|
||||||
if (unlikely(!tb)) {
|
if (unlikely(!tb)) {
|
||||||
buffer_overflow:
|
buffer_overflow:
|
||||||
|
@ -1360,7 +1370,7 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
|
||||||
tcg_func_start(tcg_ctx);
|
tcg_func_start(tcg_ctx);
|
||||||
|
|
||||||
tcg_ctx->cpu = ENV_GET_CPU(env);
|
tcg_ctx->cpu = ENV_GET_CPU(env);
|
||||||
gen_intermediate_code(cpu, tb);
|
gen_intermediate_code(cpu, tb, max_insns);
|
||||||
tcg_ctx->cpu = NULL;
|
tcg_ctx->cpu = NULL;
|
||||||
|
|
||||||
// Unicorn: FIXME: Needs to be amended to work with new TCG
|
// Unicorn: FIXME: Needs to be amended to work with new TCG
|
||||||
|
|
|
@ -30,7 +30,7 @@ void translator_loop_temp_check(DisasContextBase *db)
|
||||||
}
|
}
|
||||||
|
|
||||||
void translator_loop(const TranslatorOps *ops, DisasContextBase *db,
|
void translator_loop(const TranslatorOps *ops, DisasContextBase *db,
|
||||||
CPUState *cpu, TranslationBlock *tb)
|
CPUState *cpu, TranslationBlock *tb, int max_insns)
|
||||||
{
|
{
|
||||||
int bp_insn = 0;
|
int bp_insn = 0;
|
||||||
TCGContext *tcg_ctx = cpu->uc->tcg_ctx;
|
TCGContext *tcg_ctx = cpu->uc->tcg_ctx;
|
||||||
|
@ -41,24 +41,12 @@ void translator_loop(const TranslatorOps *ops, DisasContextBase *db,
|
||||||
db->pc_next = db->pc_first;
|
db->pc_next = db->pc_first;
|
||||||
db->is_jmp = DISAS_NEXT;
|
db->is_jmp = DISAS_NEXT;
|
||||||
db->num_insns = 0;
|
db->num_insns = 0;
|
||||||
|
db->max_insns = max_insns;
|
||||||
db->singlestep_enabled = cpu->singlestep_enabled;
|
db->singlestep_enabled = cpu->singlestep_enabled;
|
||||||
db->uc = cpu->uc;
|
db->uc = cpu->uc;
|
||||||
|
|
||||||
db->uc->block_full = false;
|
db->uc->block_full = false;
|
||||||
|
|
||||||
/* Instruction counting */
|
|
||||||
db->max_insns = tb_cflags(db->tb) & CF_COUNT_MASK;
|
|
||||||
if (db->max_insns == 0) {
|
|
||||||
db->max_insns = CF_COUNT_MASK;
|
|
||||||
}
|
|
||||||
if (db->max_insns > TCG_MAX_INSNS) {
|
|
||||||
db->max_insns = TCG_MAX_INSNS;
|
|
||||||
}
|
|
||||||
// Unicorn: commented out
|
|
||||||
if (db->singlestep_enabled /*|| singlestep*/) {
|
|
||||||
db->max_insns = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ops->init_disas_context(db, cpu);
|
ops->init_disas_context(db, cpu);
|
||||||
tcg_debug_assert(db->is_jmp == DISAS_NEXT); /* no early exit */
|
tcg_debug_assert(db->is_jmp == DISAS_NEXT); /* no early exit */
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ typedef ram_addr_t tb_page_addr_t;
|
||||||
|
|
||||||
#include "qemu/log.h"
|
#include "qemu/log.h"
|
||||||
|
|
||||||
void gen_intermediate_code(CPUState *cpu, struct TranslationBlock *tb);
|
void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns);
|
||||||
void restore_state_to_opc(CPUArchState *env, struct TranslationBlock *tb,
|
void restore_state_to_opc(CPUArchState *env, struct TranslationBlock *tb,
|
||||||
target_ulong *data);
|
target_ulong *data);
|
||||||
|
|
||||||
|
|
|
@ -126,6 +126,7 @@ typedef struct TranslatorOps {
|
||||||
* @db: Disassembly context.
|
* @db: Disassembly context.
|
||||||
* @cpu: Target vCPU.
|
* @cpu: Target vCPU.
|
||||||
* @tb: Translation block.
|
* @tb: Translation block.
|
||||||
|
* @max_insns: Maximum number of insns to translate.
|
||||||
*
|
*
|
||||||
* Generic translator loop.
|
* Generic translator loop.
|
||||||
*
|
*
|
||||||
|
@ -140,7 +141,7 @@ typedef struct TranslatorOps {
|
||||||
* - When too many instructions have been translated.
|
* - When too many instructions have been translated.
|
||||||
*/
|
*/
|
||||||
void translator_loop(const TranslatorOps *ops, DisasContextBase *db,
|
void translator_loop(const TranslatorOps *ops, DisasContextBase *db,
|
||||||
CPUState *cpu, TranslationBlock *tb);
|
CPUState *cpu, TranslationBlock *tb, int max_insns);
|
||||||
|
|
||||||
void translator_loop_temp_check(DisasContextBase *db);
|
void translator_loop_temp_check(DisasContextBase *db);
|
||||||
|
|
||||||
|
|
|
@ -13959,7 +13959,7 @@ static const TranslatorOps thumb_translator_ops = {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* generate intermediate code for basic block 'tb'. */
|
/* generate intermediate code for basic block 'tb'. */
|
||||||
void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
|
void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
|
||||||
{
|
{
|
||||||
DisasContext dc;
|
DisasContext dc;
|
||||||
const TranslatorOps *ops = &arm_translator_ops;
|
const TranslatorOps *ops = &arm_translator_ops;
|
||||||
|
@ -13973,7 +13973,7 @@ void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
translator_loop(ops, &dc.base, cpu, tb);
|
translator_loop(ops, &dc.base, cpu, tb, max_insns);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
|
|
@ -9241,11 +9241,11 @@ static const TranslatorOps i386_tr_ops = {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* generate intermediate code for basic block 'tb'. */
|
/* generate intermediate code for basic block 'tb'. */
|
||||||
void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
|
void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
|
||||||
{
|
{
|
||||||
DisasContext dc;
|
DisasContext dc;
|
||||||
|
|
||||||
translator_loop(&i386_tr_ops, &dc.base, cpu, tb);
|
translator_loop(&i386_tr_ops, &dc.base, cpu, tb, max_insns);
|
||||||
}
|
}
|
||||||
|
|
||||||
void restore_state_to_opc(CPUX86State *env, TranslationBlock *tb,
|
void restore_state_to_opc(CPUX86State *env, TranslationBlock *tb,
|
||||||
|
|
|
@ -6424,10 +6424,10 @@ static const TranslatorOps m68k_tr_ops = {
|
||||||
m68k_tr_disas_log,
|
m68k_tr_disas_log,
|
||||||
};
|
};
|
||||||
|
|
||||||
void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
|
void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
|
||||||
{
|
{
|
||||||
DisasContext dc;
|
DisasContext dc;
|
||||||
translator_loop(&m68k_tr_ops, &dc.base, cpu, tb);
|
translator_loop(&m68k_tr_ops, &dc.base, cpu, tb, max_insns);
|
||||||
}
|
}
|
||||||
|
|
||||||
void restore_state_to_opc(CPUM68KState *env, TranslationBlock *tb,
|
void restore_state_to_opc(CPUM68KState *env, TranslationBlock *tb,
|
||||||
|
|
|
@ -29920,11 +29920,11 @@ static const TranslatorOps mips_tr_ops = {
|
||||||
mips_tr_disas_log,
|
mips_tr_disas_log,
|
||||||
};
|
};
|
||||||
|
|
||||||
void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
|
void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb, int max_insns)
|
||||||
{
|
{
|
||||||
DisasContext ctx;
|
DisasContext ctx;
|
||||||
|
|
||||||
translator_loop(&mips_tr_ops, &ctx.base, cs, tb);
|
translator_loop(&mips_tr_ops, &ctx.base, cs, tb, max_insns);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
|
|
@ -822,11 +822,11 @@ static const TranslatorOps riscv_tr_ops = {
|
||||||
.disas_log = riscv_tr_disas_log,
|
.disas_log = riscv_tr_disas_log,
|
||||||
};
|
};
|
||||||
|
|
||||||
void gen_intermediate_code(CPUState *cs, TranslationBlock *tb)
|
void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
|
||||||
{
|
{
|
||||||
DisasContext ctx;
|
DisasContext ctx;
|
||||||
|
|
||||||
translator_loop(&riscv_tr_ops, &ctx.base, cs, tb);
|
translator_loop(&riscv_tr_ops, &ctx.base, cs, tb, max_insns);
|
||||||
}
|
}
|
||||||
|
|
||||||
void riscv_translate_init(struct uc_struct *uc)
|
void riscv_translate_init(struct uc_struct *uc)
|
||||||
|
|
|
@ -6048,11 +6048,11 @@ static const TranslatorOps sparc_tr_ops = {
|
||||||
sparc_tr_disas_log,
|
sparc_tr_disas_log,
|
||||||
};
|
};
|
||||||
|
|
||||||
void gen_intermediate_code(CPUState *cs, TranslationBlock *tb)
|
void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
|
||||||
{
|
{
|
||||||
DisasContext dc = {{0}};
|
DisasContext dc = {{0}};
|
||||||
|
|
||||||
translator_loop(&sparc_tr_ops, &dc.base, cs, tb);
|
translator_loop(&sparc_tr_ops, &dc.base, cs, tb, max_insns);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sparc_tcg_init(struct uc_struct *uc)
|
void sparc_tcg_init(struct uc_struct *uc)
|
||||||
|
|
Loading…
Reference in a new issue