mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2024-12-23 00:25:27 +00:00
tcg: Pass tb and index to tcg_gen_exit_tb separately
Do the cast to uintptr_t within the helper, so that the compiler can type check the pointer argument. We can also do some more sanity checking of the index argument. Backports commit 07ea28b41830f946de3841b0ac61a3413679feb9 from qemu
This commit is contained in:
parent
330bb60809
commit
10e2b13650
|
@ -50,7 +50,7 @@ static inline void gen_tb_start(TCGContext *tcg_ctx, TranslationBlock *tb)
|
|||
static inline void gen_tb_end(TCGContext *tcg_ctx, TranslationBlock *tb, int num_insns)
|
||||
{
|
||||
gen_set_label(tcg_ctx, tcg_ctx->exitreq_label);
|
||||
tcg_gen_exit_tb(tcg_ctx, (uintptr_t)tb + TB_EXIT_REQUESTED);
|
||||
tcg_gen_exit_tb(tcg_ctx, tb, TB_EXIT_REQUESTED);
|
||||
|
||||
#if 0
|
||||
if (tb->cflags & CF_USE_ICOUNT) {
|
||||
|
|
|
@ -404,7 +404,7 @@ static inline void gen_goto_tb(DisasContext *s, int n, uint64_t dest)
|
|||
if (use_goto_tb(s, n, dest)) {
|
||||
tcg_gen_goto_tb(tcg_ctx, n);
|
||||
gen_a64_set_pc_im(s, dest);
|
||||
tcg_gen_exit_tb(tcg_ctx, (intptr_t)tb + n);
|
||||
tcg_gen_exit_tb(tcg_ctx, tb, n);
|
||||
s->base.is_jmp = DISAS_NORETURN;
|
||||
} else {
|
||||
gen_a64_set_pc_im(s, dest);
|
||||
|
@ -14070,7 +14070,7 @@ static void aarch64_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
|
|||
gen_a64_set_pc_im(dc, dc->pc);
|
||||
/* fall through */
|
||||
case DISAS_EXIT:
|
||||
tcg_gen_exit_tb(tcg_ctx, 0);
|
||||
tcg_gen_exit_tb(tcg_ctx, NULL, 0);
|
||||
break;
|
||||
case DISAS_JUMP:
|
||||
tcg_gen_lookup_and_goto_ptr(tcg_ctx);
|
||||
|
@ -14099,7 +14099,7 @@ static void aarch64_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
|
|||
/* The helper doesn't necessarily throw an exception, but we
|
||||
* must go back to the main loop to check for interrupts anyway.
|
||||
*/
|
||||
tcg_gen_exit_tb(tcg_ctx, 0);
|
||||
tcg_gen_exit_tb(tcg_ctx, NULL, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1028,7 +1028,7 @@ static inline void gen_bx_excret_final_code(DisasContext *s)
|
|||
if (is_singlestepping(s)) {
|
||||
gen_singlestep_exception(s);
|
||||
} else {
|
||||
tcg_gen_exit_tb(tcg_ctx, 0);
|
||||
tcg_gen_exit_tb(tcg_ctx, NULL, 0);
|
||||
}
|
||||
gen_set_label(tcg_ctx, excret_label);
|
||||
/* Yes: this is an exception return.
|
||||
|
@ -4376,7 +4376,7 @@ static void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
|
|||
if (use_goto_tb(s, dest)) {
|
||||
tcg_gen_goto_tb(tcg_ctx, n);
|
||||
gen_set_pc_im(s, dest);
|
||||
tcg_gen_exit_tb(tcg_ctx, (uintptr_t)s->base.tb + n);
|
||||
tcg_gen_exit_tb(tcg_ctx, s->base.tb, n);
|
||||
} else {
|
||||
gen_set_pc_im(s, dest);
|
||||
gen_goto_ptr(s);
|
||||
|
@ -12907,7 +12907,7 @@ static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
|
|||
/* fall through */
|
||||
default:
|
||||
/* indicate that the hash table must be used to find the next TB */
|
||||
tcg_gen_exit_tb(tcg_ctx, 0);
|
||||
tcg_gen_exit_tb(tcg_ctx, NULL, 0);
|
||||
break;
|
||||
case DISAS_NORETURN:
|
||||
/* nothing more to generate */
|
||||
|
@ -12922,7 +12922,7 @@ static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
|
|||
/* The helper doesn't necessarily throw an exception, but we
|
||||
* must go back to the main loop to check for interrupts anyway.
|
||||
*/
|
||||
tcg_gen_exit_tb(tcg_ctx, 0);
|
||||
tcg_gen_exit_tb(tcg_ctx, NULL, 0);
|
||||
break;
|
||||
}
|
||||
case DISAS_WFE:
|
||||
|
|
|
@ -2464,7 +2464,7 @@ static inline void gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip)
|
|||
/* jump to same page: we can use a direct jump */
|
||||
tcg_gen_goto_tb(tcg_ctx, tb_num);
|
||||
gen_jmp_im(s, eip);
|
||||
tcg_gen_exit_tb(tcg_ctx, (uintptr_t)s->base.tb + tb_num);
|
||||
tcg_gen_exit_tb(tcg_ctx, s->base.tb, tb_num);
|
||||
s->base.is_jmp = DISAS_NORETURN;
|
||||
} else {
|
||||
/* jump to another page */
|
||||
|
@ -2904,13 +2904,13 @@ do_gen_eob_worker(DisasContext *s, bool inhibit, bool recheck_tf, bool jr)
|
|||
gen_helper_debug(tcg_ctx, tcg_ctx->cpu_env);
|
||||
} else if (recheck_tf) {
|
||||
gen_helper_rechecking_single_step(tcg_ctx, tcg_ctx->cpu_env);
|
||||
tcg_gen_exit_tb(tcg_ctx, 0);
|
||||
tcg_gen_exit_tb(tcg_ctx, NULL, 0);
|
||||
} else if (s->tf) {
|
||||
gen_helper_single_step(tcg_ctx, tcg_ctx->cpu_env);
|
||||
} else if (jr) {
|
||||
tcg_gen_lookup_and_goto_ptr(tcg_ctx);
|
||||
} else {
|
||||
tcg_gen_exit_tb(tcg_ctx, 0);
|
||||
tcg_gen_exit_tb(tcg_ctx, NULL, 0);
|
||||
}
|
||||
s->base.is_jmp = DISAS_NORETURN;
|
||||
}
|
||||
|
@ -8030,7 +8030,7 @@ case 0x101:
|
|||
gen_helper_vmrun(tcg_ctx, cpu_env,
|
||||
tcg_const_i32(tcg_ctx, s->aflag - 1),
|
||||
tcg_const_i32(tcg_ctx, s->pc - pc_start));
|
||||
tcg_gen_exit_tb(tcg_ctx, 0);
|
||||
tcg_gen_exit_tb(tcg_ctx, NULL, 0);
|
||||
s->base.is_jmp = DISAS_NORETURN;
|
||||
break;
|
||||
|
||||
|
|
|
@ -1528,10 +1528,10 @@ static void gen_jmp_tb(DisasContext *s, int n, uint32_t dest)
|
|||
} else if (use_goto_tb(s, dest)) {
|
||||
tcg_gen_goto_tb(tcg_ctx, n);
|
||||
tcg_gen_movi_i32(tcg_ctx, tcg_ctx->QREG_PC, dest);
|
||||
tcg_gen_exit_tb(tcg_ctx, (uintptr_t)s->tb + n);
|
||||
tcg_gen_exit_tb(tcg_ctx, s->tb, n);
|
||||
} else {
|
||||
gen_jmp_im(s, dest);
|
||||
tcg_gen_exit_tb(tcg_ctx, 0);
|
||||
tcg_gen_exit_tb(tcg_ctx, NULL, 0);
|
||||
}
|
||||
s->is_jmp = DISAS_TB_JUMP;
|
||||
}
|
||||
|
@ -6416,7 +6416,7 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb)
|
|||
case DISAS_UPDATE:
|
||||
update_cc_op(dc);
|
||||
/* indicate that the hash table must be used to find the next TB */
|
||||
tcg_gen_exit_tb(tcg_ctx, 0);
|
||||
tcg_gen_exit_tb(tcg_ctx, NULL, 0);
|
||||
break;
|
||||
case DISAS_TB_JUMP:
|
||||
/* nothing more to generate */
|
||||
|
|
|
@ -4350,7 +4350,7 @@ static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
|
|||
if (use_goto_tb(ctx, dest)) {
|
||||
tcg_gen_goto_tb(tcg_ctx, n);
|
||||
gen_save_pc(ctx, dest);
|
||||
tcg_gen_exit_tb(tcg_ctx, (uintptr_t)ctx->base.tb + n);
|
||||
tcg_gen_exit_tb(tcg_ctx, ctx->base.tb, n);
|
||||
} else {
|
||||
gen_save_pc(ctx, dest);
|
||||
if (ctx->base.singlestep_enabled) {
|
||||
|
@ -20534,7 +20534,7 @@ static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
|
|||
gen_goto_tb(ctx, 0, ctx->base.pc_next);
|
||||
break;
|
||||
case DISAS_EXIT:
|
||||
tcg_gen_exit_tb(tcg_ctx, 0);
|
||||
tcg_gen_exit_tb(tcg_ctx, NULL, 0);
|
||||
break;
|
||||
case DISAS_NORETURN:
|
||||
break;
|
||||
|
|
|
@ -359,12 +359,12 @@ static inline void gen_goto_tb(DisasContext *s, int tb_num,
|
|||
tcg_gen_goto_tb(tcg_ctx, tb_num);
|
||||
tcg_gen_movi_tl(tcg_ctx, tcg_ctx->sparc_cpu_pc, pc);
|
||||
tcg_gen_movi_tl(tcg_ctx, tcg_ctx->cpu_npc, npc);
|
||||
tcg_gen_exit_tb(tcg_ctx, (uintptr_t)s->base.tb + tb_num);
|
||||
tcg_gen_exit_tb(tcg_ctx, s->base.tb, tb_num);
|
||||
} else {
|
||||
/* jump to another page: currently not optimized */
|
||||
tcg_gen_movi_tl(tcg_ctx, tcg_ctx->sparc_cpu_pc, pc);
|
||||
tcg_gen_movi_tl(tcg_ctx, tcg_ctx->cpu_npc, npc);
|
||||
tcg_gen_exit_tb(tcg_ctx, 0);
|
||||
tcg_gen_exit_tb(tcg_ctx, NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4510,7 +4510,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn, bool hook_ins
|
|||
/* End TB to notice changed ASI. */
|
||||
save_state(dc);
|
||||
gen_op_next_insn(dc);
|
||||
tcg_gen_exit_tb(tcg_ctx, 0);
|
||||
tcg_gen_exit_tb(tcg_ctx, NULL, 0);
|
||||
dc->base.is_jmp = DISAS_NORETURN;
|
||||
break;
|
||||
case 0x6: /* V9 wrfprs */
|
||||
|
@ -4519,7 +4519,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn, bool hook_ins
|
|||
dc->fprs_dirty = 0;
|
||||
save_state(dc);
|
||||
gen_op_next_insn(dc);
|
||||
tcg_gen_exit_tb(tcg_ctx, 0);
|
||||
tcg_gen_exit_tb(tcg_ctx, NULL, 0);
|
||||
dc->base.is_jmp = DISAS_NORETURN;
|
||||
break;
|
||||
case 0xf: /* V9 sir, nop if user */
|
||||
|
@ -4647,7 +4647,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn, bool hook_ins
|
|||
dc->cc_op = CC_OP_FLAGS;
|
||||
save_state(dc);
|
||||
gen_op_next_insn(dc);
|
||||
tcg_gen_exit_tb(tcg_ctx, 0);
|
||||
tcg_gen_exit_tb(tcg_ctx, NULL, 0);
|
||||
dc->base.is_jmp = DISAS_NORETURN;
|
||||
#endif
|
||||
}
|
||||
|
@ -4803,7 +4803,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn, bool hook_ins
|
|||
hpstate));
|
||||
save_state(dc);
|
||||
gen_op_next_insn(dc);
|
||||
tcg_gen_exit_tb(tcg_ctx, 0);
|
||||
tcg_gen_exit_tb(tcg_ctx, NULL, 0);
|
||||
dc->base.is_jmp = DISAS_NORETURN;
|
||||
break;
|
||||
case 1: // htstate
|
||||
|
@ -5979,7 +5979,7 @@ static bool sparc_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
|
|||
save_state(dc);
|
||||
}
|
||||
gen_helper_debug(tcg_ctx, tcg_ctx->cpu_env);
|
||||
tcg_gen_exit_tb(tcg_ctx, 0);
|
||||
tcg_gen_exit_tb(tcg_ctx, NULL, 0);
|
||||
dc->base.is_jmp = DISAS_NORETURN;
|
||||
/* update pc_next so that the current instruction is included in tb->size */
|
||||
dc->base.pc_next += 4;
|
||||
|
@ -6026,7 +6026,7 @@ static void sparc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
|
|||
tcg_gen_movi_tl(tcg_ctx, tcg_ctx->sparc_cpu_pc, dc->pc);
|
||||
}
|
||||
save_npc(dc);
|
||||
tcg_gen_exit_tb(tcg_ctx, 0);
|
||||
tcg_gen_exit_tb(tcg_ctx, NULL, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2588,10 +2588,30 @@ void tcg_gen_extr32_i64(TCGContext *s, TCGv_i64 lo, TCGv_i64 hi, TCGv_i64 arg)
|
|||
|
||||
/* QEMU specific operations. */
|
||||
|
||||
void tcg_gen_exit_tb(TCGContext *s, TranslationBlock *tb, unsigned idx)
|
||||
{
|
||||
uintptr_t val = (uintptr_t)tb + idx;
|
||||
|
||||
if (tb == NULL) {
|
||||
tcg_debug_assert(idx == 0);
|
||||
} else if (idx <= TB_EXIT_IDXMAX) {
|
||||
#ifdef CONFIG_DEBUG_TCG
|
||||
/* This is an exit following a goto_tb. Verify that we have
|
||||
seen this numbered exit before, via tcg_gen_goto_tb. */
|
||||
tcg_debug_assert(tcg_ctx->goto_tb_issue_mask & (1 << idx));
|
||||
#endif
|
||||
} else {
|
||||
/* This is an exit via the exitreq label. */
|
||||
tcg_debug_assert(idx == TB_EXIT_REQUESTED);
|
||||
}
|
||||
|
||||
tcg_gen_op1i(s, INDEX_op_exit_tb, val);
|
||||
}
|
||||
|
||||
void tcg_gen_goto_tb(TCGContext *s, unsigned idx)
|
||||
{
|
||||
/* We only support two chained exits. */
|
||||
tcg_debug_assert(idx <= 1);
|
||||
tcg_debug_assert(idx <= TB_EXIT_IDXMAX);
|
||||
#ifdef CONFIG_DEBUG_TCG
|
||||
/* Verify that we havn't seen this numbered exit before. */
|
||||
tcg_debug_assert((s->goto_tb_issue_mask & (1 << idx)) == 0);
|
||||
|
@ -2608,7 +2628,7 @@ void tcg_gen_lookup_and_goto_ptr(TCGContext *s)
|
|||
tcg_gen_op1i(s, INDEX_op_goto_ptr, tcgv_ptr_arg(s, ptr));
|
||||
tcg_temp_free_ptr(s, ptr);
|
||||
} else {
|
||||
tcg_gen_exit_tb(s, 0);
|
||||
tcg_gen_exit_tb(s, NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -789,10 +789,19 @@ static inline void tcg_gen_insn_start(TCGContext *tcg_ctx, target_ulong pc, targ
|
|||
# error "Unhandled number of operands to insn_start"
|
||||
#endif
|
||||
|
||||
static inline void tcg_gen_exit_tb(TCGContext *s, uintptr_t val)
|
||||
{
|
||||
tcg_gen_op1i(s, INDEX_op_exit_tb, val);
|
||||
}
|
||||
/**
|
||||
* tcg_gen_exit_tb() - output exit_tb TCG operation
|
||||
* @tb: The TranslationBlock from which we are exiting
|
||||
* @idx: Direct jump slot index, or exit request
|
||||
*
|
||||
* See tcg/README for more info about this TCG operation.
|
||||
* See also tcg.h and the block comment above TB_EXIT_MASK.
|
||||
*
|
||||
* For a normal exit from the TB, back to the main loop, @tb should
|
||||
* be NULL and @idx should be 0. Otherwise, @tb should be valid and
|
||||
* @idx should be one of the TB_EXIT_ values.
|
||||
*/
|
||||
void tcg_gen_exit_tb(TCGContext *s, TranslationBlock *tb, unsigned idx);
|
||||
|
||||
/**
|
||||
* tcg_gen_goto_tb() - output goto_tb TCG operation
|
||||
|
|
|
@ -1376,6 +1376,7 @@ static inline unsigned get_mmuidx(TCGMemOpIdx oi)
|
|||
#define TB_EXIT_MASK 3
|
||||
#define TB_EXIT_IDX0 0
|
||||
#define TB_EXIT_IDX1 1
|
||||
#define TB_EXIT_IDXMAX 1
|
||||
#define TB_EXIT_ICOUNT_EXPIRED 2
|
||||
#define TB_EXIT_REQUESTED 3
|
||||
|
||||
|
|
Loading…
Reference in a new issue