提交 7f11636d 编写于 作者: E Emilio G. Cota 提交者: Richard Henderson

tcg: remove addr argument from lookup_tb_ptr

It is unlikely that we will ever want to call this helper passing
an argument other than the current PC. So just remove the argument,
and use the pc we already get from cpu_get_tb_cpu_state.

This change paves the way to having a common "tb_lookup" function.
Reviewed-by: NRichard Henderson <rth@twiddle.net>
Signed-off-by: NEmilio G. Cota <cota@braap.org>
Signed-off-by: NRichard Henderson <richard.henderson@linaro.org>
上级 d453ec78
...@@ -144,33 +144,33 @@ uint64_t HELPER(ctpop_i64)(uint64_t arg) ...@@ -144,33 +144,33 @@ uint64_t HELPER(ctpop_i64)(uint64_t arg)
return ctpop64(arg); return ctpop64(arg);
} }
void *HELPER(lookup_tb_ptr)(CPUArchState *env, target_ulong addr) void *HELPER(lookup_tb_ptr)(CPUArchState *env)
{ {
CPUState *cpu = ENV_GET_CPU(env); CPUState *cpu = ENV_GET_CPU(env);
TranslationBlock *tb; TranslationBlock *tb;
target_ulong cs_base, pc; target_ulong cs_base, pc;
uint32_t flags, addr_hash; uint32_t flags, hash;
addr_hash = tb_jmp_cache_hash_func(addr);
tb = atomic_rcu_read(&cpu->tb_jmp_cache[addr_hash]);
cpu_get_tb_cpu_state(env, &pc, &cs_base, &flags); cpu_get_tb_cpu_state(env, &pc, &cs_base, &flags);
hash = tb_jmp_cache_hash_func(pc);
tb = atomic_rcu_read(&cpu->tb_jmp_cache[hash]);
if (unlikely(!(tb if (unlikely(!(tb
&& tb->pc == addr && tb->pc == pc
&& tb->cs_base == cs_base && tb->cs_base == cs_base
&& tb->flags == flags && tb->flags == flags
&& tb->trace_vcpu_dstate == *cpu->trace_dstate))) { && tb->trace_vcpu_dstate == *cpu->trace_dstate))) {
tb = tb_htable_lookup(cpu, addr, cs_base, flags); tb = tb_htable_lookup(cpu, pc, cs_base, flags);
if (!tb) { if (!tb) {
return tcg_ctx.code_gen_epilogue; return tcg_ctx.code_gen_epilogue;
} }
atomic_set(&cpu->tb_jmp_cache[addr_hash], tb); atomic_set(&cpu->tb_jmp_cache[hash], tb);
} }
qemu_log_mask_and_addr(CPU_LOG_EXEC, addr, qemu_log_mask_and_addr(CPU_LOG_EXEC, pc,
"Chain %p [%d: " TARGET_FMT_lx "] %s\n", "Chain %p [%d: " TARGET_FMT_lx "] %s\n",
tb->tc_ptr, cpu->cpu_index, addr, tb->tc_ptr, cpu->cpu_index, pc,
lookup_symbol(addr)); lookup_symbol(pc));
return tb->tc_ptr; return tb->tc_ptr;
} }
......
...@@ -24,7 +24,7 @@ DEF_HELPER_FLAGS_1(clrsb_i64, TCG_CALL_NO_RWG_SE, i64, i64) ...@@ -24,7 +24,7 @@ DEF_HELPER_FLAGS_1(clrsb_i64, TCG_CALL_NO_RWG_SE, i64, i64)
DEF_HELPER_FLAGS_1(ctpop_i32, TCG_CALL_NO_RWG_SE, i32, i32) DEF_HELPER_FLAGS_1(ctpop_i32, TCG_CALL_NO_RWG_SE, i32, i32)
DEF_HELPER_FLAGS_1(ctpop_i64, TCG_CALL_NO_RWG_SE, i64, i64) DEF_HELPER_FLAGS_1(ctpop_i64, TCG_CALL_NO_RWG_SE, i64, i64)
DEF_HELPER_FLAGS_2(lookup_tb_ptr, TCG_CALL_NO_WG_SE, ptr, env, tl) DEF_HELPER_FLAGS_1(lookup_tb_ptr, TCG_CALL_NO_WG_SE, ptr, env)
DEF_HELPER_FLAGS_1(exit_atomic, TCG_CALL_NO_WG, noreturn, env) DEF_HELPER_FLAGS_1(exit_atomic, TCG_CALL_NO_WG, noreturn, env)
......
...@@ -3029,7 +3029,7 @@ static void alpha_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) ...@@ -3029,7 +3029,7 @@ static void alpha_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
/* FALLTHRU */ /* FALLTHRU */
case DISAS_PC_UPDATED: case DISAS_PC_UPDATED:
if (!use_exit_tb(ctx)) { if (!use_exit_tb(ctx)) {
tcg_gen_lookup_and_goto_ptr(cpu_pc); tcg_gen_lookup_and_goto_ptr();
break; break;
} }
/* FALLTHRU */ /* FALLTHRU */
......
...@@ -379,7 +379,7 @@ static inline void gen_goto_tb(DisasContext *s, int n, uint64_t dest) ...@@ -379,7 +379,7 @@ static inline void gen_goto_tb(DisasContext *s, int n, uint64_t dest)
} else if (s->base.singlestep_enabled) { } else if (s->base.singlestep_enabled) {
gen_exception_internal(EXCP_DEBUG); gen_exception_internal(EXCP_DEBUG);
} else { } else {
tcg_gen_lookup_and_goto_ptr(cpu_pc); tcg_gen_lookup_and_goto_ptr();
s->base.is_jmp = DISAS_NORETURN; s->base.is_jmp = DISAS_NORETURN;
} }
} }
...@@ -11363,7 +11363,7 @@ static void aarch64_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) ...@@ -11363,7 +11363,7 @@ static void aarch64_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
gen_a64_set_pc_im(dc->pc); gen_a64_set_pc_im(dc->pc);
/* fall through */ /* fall through */
case DISAS_JUMP: case DISAS_JUMP:
tcg_gen_lookup_and_goto_ptr(cpu_pc); tcg_gen_lookup_and_goto_ptr();
break; break;
case DISAS_EXIT: case DISAS_EXIT:
tcg_gen_exit_tb(0); tcg_gen_exit_tb(0);
......
...@@ -4173,10 +4173,7 @@ static inline bool use_goto_tb(DisasContext *s, target_ulong dest) ...@@ -4173,10 +4173,7 @@ static inline bool use_goto_tb(DisasContext *s, target_ulong dest)
static void gen_goto_ptr(void) static void gen_goto_ptr(void)
{ {
TCGv addr = tcg_temp_new(); tcg_gen_lookup_and_goto_ptr();
tcg_gen_extu_i32_tl(addr, cpu_R[15]);
tcg_gen_lookup_and_goto_ptr(addr);
tcg_temp_free(addr);
} }
/* This will end the TB but doesn't guarantee we'll return to /* This will end the TB but doesn't guarantee we'll return to
......
...@@ -505,7 +505,7 @@ static void gen_goto_tb(DisasContext *ctx, int which, ...@@ -505,7 +505,7 @@ static void gen_goto_tb(DisasContext *ctx, int which,
if (ctx->base.singlestep_enabled) { if (ctx->base.singlestep_enabled) {
gen_excp_1(EXCP_DEBUG); gen_excp_1(EXCP_DEBUG);
} else { } else {
tcg_gen_lookup_and_goto_ptr(cpu_iaoq_f); tcg_gen_lookup_and_goto_ptr();
} }
} }
} }
...@@ -1515,7 +1515,7 @@ static DisasJumpType do_ibranch(DisasContext *ctx, TCGv dest, ...@@ -1515,7 +1515,7 @@ static DisasJumpType do_ibranch(DisasContext *ctx, TCGv dest,
if (link != 0) { if (link != 0) {
tcg_gen_movi_tl(cpu_gr[link], ctx->iaoq_n); tcg_gen_movi_tl(cpu_gr[link], ctx->iaoq_n);
} }
tcg_gen_lookup_and_goto_ptr(cpu_iaoq_f); tcg_gen_lookup_and_goto_ptr();
return nullify_end(ctx, DISAS_NEXT); return nullify_end(ctx, DISAS_NEXT);
} else { } else {
cond_prep(&ctx->null_cond); cond_prep(&ctx->null_cond);
...@@ -3873,7 +3873,7 @@ static void hppa_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs) ...@@ -3873,7 +3873,7 @@ static void hppa_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
if (ctx->base.singlestep_enabled) { if (ctx->base.singlestep_enabled) {
gen_excp_1(EXCP_DEBUG); gen_excp_1(EXCP_DEBUG);
} else { } else {
tcg_gen_lookup_and_goto_ptr(cpu_iaoq_f); tcg_gen_lookup_and_goto_ptr();
} }
break; break;
default: default:
......
...@@ -2511,7 +2511,7 @@ static void gen_bnd_jmp(DisasContext *s) ...@@ -2511,7 +2511,7 @@ static void gen_bnd_jmp(DisasContext *s)
If RECHECK_TF, emit a rechecking helper for #DB, ignoring the state of If RECHECK_TF, emit a rechecking helper for #DB, ignoring the state of
S->TF. This is used by the syscall/sysret insns. */ S->TF. This is used by the syscall/sysret insns. */
static void static void
do_gen_eob_worker(DisasContext *s, bool inhibit, bool recheck_tf, TCGv jr) do_gen_eob_worker(DisasContext *s, bool inhibit, bool recheck_tf, bool jr)
{ {
gen_update_cc_op(s); gen_update_cc_op(s);
...@@ -2532,12 +2532,8 @@ do_gen_eob_worker(DisasContext *s, bool inhibit, bool recheck_tf, TCGv jr) ...@@ -2532,12 +2532,8 @@ do_gen_eob_worker(DisasContext *s, bool inhibit, bool recheck_tf, TCGv jr)
tcg_gen_exit_tb(0); tcg_gen_exit_tb(0);
} else if (s->tf) { } else if (s->tf) {
gen_helper_single_step(cpu_env); gen_helper_single_step(cpu_env);
} else if (!TCGV_IS_UNUSED(jr)) { } else if (jr) {
TCGv vaddr = tcg_temp_new(); tcg_gen_lookup_and_goto_ptr();
tcg_gen_add_tl(vaddr, jr, cpu_seg_base[R_CS]);
tcg_gen_lookup_and_goto_ptr(vaddr);
tcg_temp_free(vaddr);
} else { } else {
tcg_gen_exit_tb(0); tcg_gen_exit_tb(0);
} }
...@@ -2547,10 +2543,7 @@ do_gen_eob_worker(DisasContext *s, bool inhibit, bool recheck_tf, TCGv jr) ...@@ -2547,10 +2543,7 @@ do_gen_eob_worker(DisasContext *s, bool inhibit, bool recheck_tf, TCGv jr)
static inline void static inline void
gen_eob_worker(DisasContext *s, bool inhibit, bool recheck_tf) gen_eob_worker(DisasContext *s, bool inhibit, bool recheck_tf)
{ {
TCGv unused; do_gen_eob_worker(s, inhibit, recheck_tf, false);
TCGV_UNUSED(unused);
do_gen_eob_worker(s, inhibit, recheck_tf, unused);
} }
/* End of block. /* End of block.
...@@ -2569,7 +2562,7 @@ static void gen_eob(DisasContext *s) ...@@ -2569,7 +2562,7 @@ static void gen_eob(DisasContext *s)
/* Jump to register */ /* Jump to register */
static void gen_jr(DisasContext *s, TCGv dest) static void gen_jr(DisasContext *s, TCGv dest)
{ {
do_gen_eob_worker(s, false, false, dest); do_gen_eob_worker(s, false, false, true);
} }
/* generate a jump to eip. No segment change must happen before as a /* generate a jump to eip. No segment change must happen before as a
......
...@@ -4303,7 +4303,7 @@ static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) ...@@ -4303,7 +4303,7 @@ static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
save_cpu_state(ctx, 0); save_cpu_state(ctx, 0);
gen_helper_raise_exception_debug(cpu_env); gen_helper_raise_exception_debug(cpu_env);
} }
tcg_gen_lookup_and_goto_ptr(cpu_PC); tcg_gen_lookup_and_goto_ptr();
} }
} }
...@@ -10883,7 +10883,7 @@ static void gen_branch(DisasContext *ctx, int insn_bytes) ...@@ -10883,7 +10883,7 @@ static void gen_branch(DisasContext *ctx, int insn_bytes)
save_cpu_state(ctx, 0); save_cpu_state(ctx, 0);
gen_helper_raise_exception_debug(cpu_env); gen_helper_raise_exception_debug(cpu_env);
} }
tcg_gen_lookup_and_goto_ptr(cpu_PC); tcg_gen_lookup_and_goto_ptr();
break; break;
default: default:
fprintf(stderr, "unknown branch 0x%x\n", proc_hflags); fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
......
...@@ -5949,7 +5949,7 @@ void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb) ...@@ -5949,7 +5949,7 @@ void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
} else if (use_exit_tb(&dc) || status == EXIT_PC_STALE_NOCHAIN) { } else if (use_exit_tb(&dc) || status == EXIT_PC_STALE_NOCHAIN) {
tcg_gen_exit_tb(0); tcg_gen_exit_tb(0);
} else { } else {
tcg_gen_lookup_and_goto_ptr(psw_addr); tcg_gen_lookup_and_goto_ptr();
} }
break; break;
default: default:
......
...@@ -261,7 +261,7 @@ static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) ...@@ -261,7 +261,7 @@ static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
} else if (use_exit_tb(ctx)) { } else if (use_exit_tb(ctx)) {
tcg_gen_exit_tb(0); tcg_gen_exit_tb(0);
} else { } else {
tcg_gen_lookup_and_goto_ptr(cpu_pc); tcg_gen_lookup_and_goto_ptr();
} }
} }
} }
...@@ -278,7 +278,7 @@ static void gen_jump(DisasContext * ctx) ...@@ -278,7 +278,7 @@ static void gen_jump(DisasContext * ctx)
} else if (use_exit_tb(ctx)) { } else if (use_exit_tb(ctx)) {
tcg_gen_exit_tb(0); tcg_gen_exit_tb(0);
} else { } else {
tcg_gen_lookup_and_goto_ptr(cpu_pc); tcg_gen_lookup_and_goto_ptr();
} }
} else { } else {
gen_goto_tb(ctx, 0, ctx->delayed_pc); gen_goto_tb(ctx, 0, ctx->delayed_pc);
......
...@@ -2588,11 +2588,11 @@ void tcg_gen_goto_tb(unsigned idx) ...@@ -2588,11 +2588,11 @@ void tcg_gen_goto_tb(unsigned idx)
tcg_gen_op1i(INDEX_op_goto_tb, idx); tcg_gen_op1i(INDEX_op_goto_tb, idx);
} }
void tcg_gen_lookup_and_goto_ptr(TCGv addr) void tcg_gen_lookup_and_goto_ptr(void)
{ {
if (TCG_TARGET_HAS_goto_ptr && !qemu_loglevel_mask(CPU_LOG_TB_NOCHAIN)) { if (TCG_TARGET_HAS_goto_ptr && !qemu_loglevel_mask(CPU_LOG_TB_NOCHAIN)) {
TCGv_ptr ptr = tcg_temp_new_ptr(); TCGv_ptr ptr = tcg_temp_new_ptr();
gen_helper_lookup_tb_ptr(ptr, tcg_ctx.tcg_env, addr); gen_helper_lookup_tb_ptr(ptr, tcg_ctx.tcg_env);
tcg_gen_op1i(INDEX_op_goto_ptr, GET_TCGV_PTR(ptr)); tcg_gen_op1i(INDEX_op_goto_ptr, GET_TCGV_PTR(ptr));
tcg_temp_free_ptr(ptr); tcg_temp_free_ptr(ptr);
} else { } else {
......
...@@ -797,7 +797,7 @@ static inline void tcg_gen_exit_tb(uintptr_t val) ...@@ -797,7 +797,7 @@ static inline void tcg_gen_exit_tb(uintptr_t val)
void tcg_gen_goto_tb(unsigned idx); void tcg_gen_goto_tb(unsigned idx);
/** /**
* tcg_gen_lookup_and_goto_ptr() - look up a TB and jump to it if valid * tcg_gen_lookup_and_goto_ptr() - look up the current TB, jump to it if valid
* @addr: Guest address of the target TB * @addr: Guest address of the target TB
* *
* If the TB is not valid, jump to the epilogue. * If the TB is not valid, jump to the epilogue.
...@@ -805,7 +805,7 @@ void tcg_gen_goto_tb(unsigned idx); ...@@ -805,7 +805,7 @@ void tcg_gen_goto_tb(unsigned idx);
* This operation is optional. If the TCG backend does not implement goto_ptr, * This operation is optional. If the TCG backend does not implement goto_ptr,
* this op is equivalent to calling tcg_gen_exit_tb() with 0 as the argument. * this op is equivalent to calling tcg_gen_exit_tb() with 0 as the argument.
*/ */
void tcg_gen_lookup_and_goto_ptr(TCGv addr); void tcg_gen_lookup_and_goto_ptr(void);
#if TARGET_LONG_BITS == 32 #if TARGET_LONG_BITS == 32
#define tcg_temp_new() tcg_temp_new_i32() #define tcg_temp_new() tcg_temp_new_i32()
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册