summaryrefslogtreecommitdiff
path: root/target-alpha
diff options
context:
space:
mode:
authorRichard Henderson <rth@twiddle.net>2013-07-26 14:05:08 -1000
committerRichard Henderson <rth@twiddle.net>2013-08-16 11:17:23 -0700
commitb114b68adf12a5333bb95b252aed6309cf0c0e5f (patch)
tree1065e0813e045cc61d1b829a41566430f0e3c007 /target-alpha
parenta9ead832617195a9b0727557c94dda776f8e8074 (diff)
downloadqemu-b114b68adf12a5333bb95b252aed6309cf0c0e5f.tar.gz
target-alpha: Consider the superpage when threading and ending TBs
This allows significantly more threading, and occasionally larger TBs, when processing code for the kernel and PALcode. Signed-off-by: Richard Henderson <rth@twiddle.net>
Diffstat (limited to 'target-alpha')
-rw-r--r--target-alpha/translate.c37
1 files changed, 29 insertions, 8 deletions
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index f172670098..309dea6ff0 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -379,13 +379,26 @@ static ExitStatus gen_store_conditional(DisasContext *ctx, int ra, int rb,
#endif
}
-static int use_goto_tb(DisasContext *ctx, uint64_t dest)
+static bool in_superpage(DisasContext *ctx, int64_t addr)
{
- /* Check for the dest on the same page as the start of the TB. We
- also want to suppress goto_tb in the case of single-steping and IO. */
- return (((ctx->tb->pc ^ dest) & TARGET_PAGE_MASK) == 0
- && !ctx->singlestep_enabled
- && !(ctx->tb->cflags & CF_LAST_IO));
+ return ((ctx->tb->flags & TB_FLAGS_USER_MODE) == 0
+ && addr < 0
+ && ((addr >> 41) & 3) == 2
+ && addr >> TARGET_VIRT_ADDR_SPACE_BITS == addr >> 63);
+}
+
+static bool use_goto_tb(DisasContext *ctx, uint64_t dest)
+{
+ /* Suppress goto_tb in the case of single-steping and IO. */
+ if (ctx->singlestep_enabled || (ctx->tb->cflags & CF_LAST_IO)) {
+ return false;
+ }
+ /* If the destination is in the superpage, the page perms can't change. */
+ if (in_superpage(ctx, dest)) {
+ return true;
+ }
+ /* Check for the dest on the same page as the start of the TB. */
+ return ((ctx->tb->pc ^ dest) & TARGET_PAGE_MASK) == 0;
}
static ExitStatus gen_bdirect(DisasContext *ctx, int ra, int32_t disp)
@@ -3431,6 +3444,7 @@ static inline void gen_intermediate_code_internal(AlphaCPU *cpu,
CPUAlphaState *env = &cpu->env;
DisasContext ctx, *ctxp = &ctx;
target_ulong pc_start;
+ target_ulong pc_mask;
uint32_t insn;
uint16_t *gen_opc_end;
CPUBreakpoint *bp;
@@ -3460,8 +3474,15 @@ static inline void gen_intermediate_code_internal(AlphaCPU *cpu,
num_insns = 0;
max_insns = tb->cflags & CF_COUNT_MASK;
- if (max_insns == 0)
+ if (max_insns == 0) {
max_insns = CF_COUNT_MASK;
+ }
+
+ if (in_superpage(&ctx, pc_start)) {
+ pc_mask = (1ULL << 41) - 1;
+ } else {
+ pc_mask = ~TARGET_PAGE_MASK;
+ }
gen_tb_start();
do {
@@ -3499,7 +3520,7 @@ static inline void gen_intermediate_code_internal(AlphaCPU *cpu,
/* If we reach a page boundary, are single stepping,
or exhaust instruction count, stop generation. */
if (ret == NO_EXIT
- && ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0
+ && ((ctx.pc & pc_mask) == 0
|| tcg_ctx.gen_opc_ptr >= gen_opc_end
|| num_insns >= max_insns
|| singlestep