diff options
author | Richard Henderson <rth@twiddle.net> | 2013-07-26 12:00:32 -1000 |
---|---|---|
committer | Richard Henderson <rth@twiddle.net> | 2013-08-16 11:17:23 -0700 |
commit | a9ead832617195a9b0727557c94dda776f8e8074 (patch) | |
tree | a881b774fa9c2ebc058abf78d20a6fae1cc6b2f4 /target-alpha/translate.c | |
parent | ba96394e20ad033a10eb790fdf2377e2a8892feb (diff) |
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>
Diffstat (limited to 'target-alpha/translate.c')
-rw-r--r-- | target-alpha/translate.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/target-alpha/translate.c b/target-alpha/translate.c index 59389a2ea0..f172670098 100644 --- a/target-alpha/translate.c +++ b/target-alpha/translate.c @@ -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. */ |