target-alpha: Use goto_tb in call_pal

With appropriate flushing when the PALBR changes, the target of
a CALL_PAL is so predictable we can chain to it.

Signed-off-by: Richard Henderson <rth@twiddle.net>
This commit is contained in:
Richard Henderson 2013-07-26 12:00:32 -10:00
parent ba96394e20
commit a9ead83261
3 changed files with 26 additions and 0 deletions

View File

@ -112,6 +112,7 @@ DEF_HELPER_3(stq_c_phys, i64, env, i64, i64)
DEF_HELPER_FLAGS_1(tbia, TCG_CALL_NO_RWG, void, env)
DEF_HELPER_FLAGS_2(tbis, TCG_CALL_NO_RWG, void, env, i64)
DEF_HELPER_FLAGS_1(tb_flush, TCG_CALL_NO_RWG, void, env)
DEF_HELPER_1(halt, void, i64);

View File

@ -72,6 +72,11 @@ void helper_tbis(CPUAlphaState *env, uint64_t p)
tlb_flush_page(env, p);
}
void helper_tb_flush(CPUAlphaState *env)
{
tb_flush(env);
}
void helper_halt(uint64_t restart)
{
if (restart) {

View File

@ -1609,6 +1609,17 @@ static ExitStatus gen_call_pal(DisasContext *ctx, int palcode)
tcg_temp_free(entry);
tcg_temp_free(pc);
/* Since the destination is running in PALmode, we don't really
need the page permissions check. We'll see the existance of
the page when we create the TB, and we'll flush all TBs if
we change the PAL base register. */
if (!ctx->singlestep_enabled && !(ctx->tb->cflags & CF_LAST_IO)) {
tcg_gen_goto_tb(0);
tcg_gen_exit_tb((tcg_target_long)ctx->tb);
return EXIT_GOTO_TB;
}
return EXIT_PC_UPDATED;
}
#endif
@ -1727,6 +1738,15 @@ static ExitStatus gen_mtpr(DisasContext *ctx, int rb, int regno)
gen_helper_set_alarm(cpu_env, tmp);
break;
case 7:
/* PALBR */
tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUAlphaState, palbr));
/* Changing the PAL base register implies un-chaining all of the TBs
that ended with a CALL_PAL. Since the base register usually only
changes during boot, flushing everything works well. */
gen_helper_tb_flush(cpu_env);
return EXIT_PC_STALE;
default:
/* The basic registers are data only, and unknown registers
are read-zero, write-ignore. */