aboutsummaryrefslogtreecommitdiff
path: root/target-alpha/translate.c
diff options
context:
space:
mode:
authorRichard Henderson <rth@twiddle.net>2013-07-26 12:00:32 -1000
committerRichard Henderson <rth@twiddle.net>2013-08-16 11:17:23 -0700
commita9ead832617195a9b0727557c94dda776f8e8074 (patch)
treea881b774fa9c2ebc058abf78d20a6fae1cc6b2f4 /target-alpha/translate.c
parentba96394e20ad033a10eb790fdf2377e2a8892feb (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.c20
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. */