target/alpha: Convert to DisasContextBase

Signed-off-by: Richard Henderson <rth@twiddle.net>
This commit is contained in:
Richard Henderson 2017-07-14 13:32:08 -10:00 committed by Richard Henderson
parent 3de811c6fd
commit c5f806579f

View File

@ -43,8 +43,8 @@
typedef struct DisasContext DisasContext; typedef struct DisasContext DisasContext;
struct DisasContext { struct DisasContext {
struct TranslationBlock *tb; DisasContextBase base;
uint64_t pc;
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY
uint64_t palbr; uint64_t palbr;
#endif #endif
@ -68,8 +68,6 @@ struct DisasContext {
TCGv sink; TCGv sink;
/* Temporary for immediate constants. */ /* Temporary for immediate constants. */
TCGv lit; TCGv lit;
bool singlestep_enabled;
}; };
/* Target-specific return values from translate_one, indicating the /* Target-specific return values from translate_one, indicating the
@ -282,7 +280,7 @@ static void gen_excp_1(int exception, int error_code)
static DisasJumpType gen_excp(DisasContext *ctx, int exception, int error_code) static DisasJumpType gen_excp(DisasContext *ctx, int exception, int error_code)
{ {
tcg_gen_movi_i64(cpu_pc, ctx->pc); tcg_gen_movi_i64(cpu_pc, ctx->base.pc_next);
gen_excp_1(exception, error_code); gen_excp_1(exception, error_code);
return DISAS_NORETURN; return DISAS_NORETURN;
} }
@ -463,8 +461,8 @@ static bool in_superpage(DisasContext *ctx, int64_t addr)
static bool use_exit_tb(DisasContext *ctx) static bool use_exit_tb(DisasContext *ctx)
{ {
return ((ctx->tb->cflags & CF_LAST_IO) return ((ctx->base.tb->cflags & CF_LAST_IO)
|| ctx->singlestep_enabled || ctx->base.singlestep_enabled
|| singlestep); || singlestep);
} }
@ -480,7 +478,7 @@ static bool use_goto_tb(DisasContext *ctx, uint64_t dest)
return true; return true;
} }
/* Check for the dest on the same page as the start of the TB. */ /* Check for the dest on the same page as the start of the TB. */
return ((ctx->tb->pc ^ dest) & TARGET_PAGE_MASK) == 0; return ((ctx->base.tb->pc ^ dest) & TARGET_PAGE_MASK) == 0;
#else #else
return true; return true;
#endif #endif
@ -488,10 +486,10 @@ static bool use_goto_tb(DisasContext *ctx, uint64_t dest)
static DisasJumpType gen_bdirect(DisasContext *ctx, int ra, int32_t disp) static DisasJumpType gen_bdirect(DisasContext *ctx, int ra, int32_t disp)
{ {
uint64_t dest = ctx->pc + (disp << 2); uint64_t dest = ctx->base.pc_next + (disp << 2);
if (ra != 31) { if (ra != 31) {
tcg_gen_movi_i64(ctx->ir[ra], ctx->pc); tcg_gen_movi_i64(ctx->ir[ra], ctx->base.pc_next);
} }
/* Notice branch-to-next; used to initialize RA with the PC. */ /* Notice branch-to-next; used to initialize RA with the PC. */
@ -500,7 +498,7 @@ static DisasJumpType gen_bdirect(DisasContext *ctx, int ra, int32_t disp)
} else if (use_goto_tb(ctx, dest)) { } else if (use_goto_tb(ctx, dest)) {
tcg_gen_goto_tb(0); tcg_gen_goto_tb(0);
tcg_gen_movi_i64(cpu_pc, dest); tcg_gen_movi_i64(cpu_pc, dest);
tcg_gen_exit_tb((uintptr_t)ctx->tb); tcg_gen_exit_tb((uintptr_t)ctx->base.tb);
return DISAS_NORETURN; return DISAS_NORETURN;
} else { } else {
tcg_gen_movi_i64(cpu_pc, dest); tcg_gen_movi_i64(cpu_pc, dest);
@ -511,26 +509,26 @@ static DisasJumpType gen_bdirect(DisasContext *ctx, int ra, int32_t disp)
static DisasJumpType gen_bcond_internal(DisasContext *ctx, TCGCond cond, static DisasJumpType gen_bcond_internal(DisasContext *ctx, TCGCond cond,
TCGv cmp, int32_t disp) TCGv cmp, int32_t disp)
{ {
uint64_t dest = ctx->pc + (disp << 2); uint64_t dest = ctx->base.pc_next + (disp << 2);
TCGLabel *lab_true = gen_new_label(); TCGLabel *lab_true = gen_new_label();
if (use_goto_tb(ctx, dest)) { if (use_goto_tb(ctx, dest)) {
tcg_gen_brcondi_i64(cond, cmp, 0, lab_true); tcg_gen_brcondi_i64(cond, cmp, 0, lab_true);
tcg_gen_goto_tb(0); tcg_gen_goto_tb(0);
tcg_gen_movi_i64(cpu_pc, ctx->pc); tcg_gen_movi_i64(cpu_pc, ctx->base.pc_next);
tcg_gen_exit_tb((uintptr_t)ctx->tb); tcg_gen_exit_tb((uintptr_t)ctx->base.tb);
gen_set_label(lab_true); gen_set_label(lab_true);
tcg_gen_goto_tb(1); tcg_gen_goto_tb(1);
tcg_gen_movi_i64(cpu_pc, dest); tcg_gen_movi_i64(cpu_pc, dest);
tcg_gen_exit_tb((uintptr_t)ctx->tb + 1); tcg_gen_exit_tb((uintptr_t)ctx->base.tb + 1);
return DISAS_NORETURN; return DISAS_NORETURN;
} else { } else {
TCGv_i64 z = tcg_const_i64(0); TCGv_i64 z = tcg_const_i64(0);
TCGv_i64 d = tcg_const_i64(dest); TCGv_i64 d = tcg_const_i64(dest);
TCGv_i64 p = tcg_const_i64(ctx->pc); TCGv_i64 p = tcg_const_i64(ctx->base.pc_next);
tcg_gen_movcond_i64(cond, cpu_pc, cmp, z, d, p); tcg_gen_movcond_i64(cond, cpu_pc, cmp, z, d, p);
@ -1210,7 +1208,7 @@ static DisasJumpType gen_call_pal(DisasContext *ctx, int palcode)
} }
/* Allow interrupts to be recognized right away. */ /* Allow interrupts to be recognized right away. */
tcg_gen_movi_i64(cpu_pc, ctx->pc); tcg_gen_movi_i64(cpu_pc, ctx->base.pc_next);
return DISAS_PC_UPDATED_NOCHAIN; return DISAS_PC_UPDATED_NOCHAIN;
case 0x36: case 0x36:
@ -1260,7 +1258,7 @@ static DisasJumpType gen_call_pal(DisasContext *ctx, int palcode)
#else #else
{ {
TCGv tmp = tcg_temp_new(); TCGv tmp = tcg_temp_new();
uint64_t exc_addr = ctx->pc; uint64_t exc_addr = ctx->base.pc_next;
uint64_t entry = ctx->palbr; uint64_t entry = ctx->palbr;
if (ctx->tbflags & ENV_FLAG_PAL_MODE) { if (ctx->tbflags & ENV_FLAG_PAL_MODE) {
@ -1285,7 +1283,7 @@ static DisasJumpType gen_call_pal(DisasContext *ctx, int palcode)
if (!use_exit_tb(ctx)) { if (!use_exit_tb(ctx)) {
tcg_gen_goto_tb(0); tcg_gen_goto_tb(0);
tcg_gen_movi_i64(cpu_pc, entry); tcg_gen_movi_i64(cpu_pc, entry);
tcg_gen_exit_tb((uintptr_t)ctx->tb); tcg_gen_exit_tb((uintptr_t)ctx->base.tb);
return DISAS_NORETURN; return DISAS_NORETURN;
} else { } else {
tcg_gen_movi_i64(cpu_pc, entry); tcg_gen_movi_i64(cpu_pc, entry);
@ -2407,7 +2405,7 @@ static DisasJumpType translate_one(DisasContext *ctx, uint32_t insn)
case 0xC000: case 0xC000:
/* RPCC */ /* RPCC */
va = dest_gpr(ctx, ra); va = dest_gpr(ctx, ra);
if (ctx->tb->cflags & CF_USE_ICOUNT) { if (ctx->base.tb->cflags & CF_USE_ICOUNT) {
gen_io_start(); gen_io_start();
gen_helper_load_pcc(va, cpu_env); gen_helper_load_pcc(va, cpu_env);
gen_io_end(); gen_io_end();
@ -2457,7 +2455,7 @@ static DisasJumpType translate_one(DisasContext *ctx, uint32_t insn)
vb = load_gpr(ctx, rb); vb = load_gpr(ctx, rb);
tcg_gen_andi_i64(cpu_pc, vb, ~3); tcg_gen_andi_i64(cpu_pc, vb, ~3);
if (ra != 31) { if (ra != 31) {
tcg_gen_movi_i64(ctx->ir[ra], ctx->pc); tcg_gen_movi_i64(ctx->ir[ra], ctx->base.pc_next);
} }
ret = DISAS_PC_UPDATED; ret = DISAS_PC_UPDATED;
break; break;
@ -2944,13 +2942,14 @@ void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
pc_start = tb->pc; pc_start = tb->pc;
ctx.tb = tb; ctx.base.tb = tb;
ctx.pc = pc_start; ctx.base.pc_next = pc_start;
ctx.base.singlestep_enabled = cs->singlestep_enabled;
ctx.tbflags = tb->flags; ctx.tbflags = tb->flags;
ctx.mem_idx = cpu_mmu_index(env, false); ctx.mem_idx = cpu_mmu_index(env, false);
ctx.implver = env->implver; ctx.implver = env->implver;
ctx.amask = env->amask; ctx.amask = env->amask;
ctx.singlestep_enabled = cs->singlestep_enabled;
#ifdef CONFIG_USER_ONLY #ifdef CONFIG_USER_ONLY
ctx.ir = cpu_std_ir; ctx.ir = cpu_std_ir;
@ -2992,39 +2991,40 @@ void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
tcg_clear_temp_count(); tcg_clear_temp_count();
do { do {
tcg_gen_insn_start(ctx.pc); tcg_gen_insn_start(ctx.base.pc_next);
num_insns++; num_insns++;
if (unlikely(cpu_breakpoint_test(cs, ctx.pc, BP_ANY))) { if (unlikely(cpu_breakpoint_test(cs, ctx.base.pc_next, BP_ANY))) {
ret = gen_excp(&ctx, EXCP_DEBUG, 0); ret = gen_excp(&ctx, EXCP_DEBUG, 0);
/* The address covered by the breakpoint must be included in /* The address covered by the breakpoint must be included in
[tb->pc, tb->pc + tb->size) in order to for it to be [tb->pc, tb->pc + tb->size) in order to for it to be
properly cleared -- thus we increment the PC here so that properly cleared -- thus we increment the PC here so that
the logic setting tb->size below does the right thing. */ the logic setting tb->size below does the right thing. */
ctx.pc += 4; ctx.base.pc_next += 4;
break; break;
} }
if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) { if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
gen_io_start(); gen_io_start();
} }
insn = cpu_ldl_code(env, ctx.pc); insn = cpu_ldl_code(env, ctx.base.pc_next);
ctx.pc += 4; ctx.base.pc_next += 4;
ret = translate_one(ctxp, insn); ret = translate_one(ctxp, insn);
free_context_temps(ctxp); free_context_temps(ctxp);
if (tcg_check_temp_count()) { if (tcg_check_temp_count()) {
qemu_log("TCG temporary leak before "TARGET_FMT_lx"\n", ctx.pc); qemu_log("TCG temporary leak before "TARGET_FMT_lx"\n",
ctx.base.pc_next);
} }
/* If we reach a page boundary, are single stepping, /* If we reach a page boundary, are single stepping,
or exhaust instruction count, stop generation. */ or exhaust instruction count, stop generation. */
if (ret == DISAS_NEXT if (ret == DISAS_NEXT
&& ((ctx.pc & pc_mask) == 0 && ((ctx.base.pc_next & pc_mask) == 0
|| tcg_op_buf_full() || tcg_op_buf_full()
|| num_insns >= max_insns || num_insns >= max_insns
|| singlestep || singlestep
|| ctx.singlestep_enabled)) { || ctx.base.singlestep_enabled)) {
ret = DISAS_TOO_MANY; ret = DISAS_TOO_MANY;
} }
} while (ret == DISAS_NEXT); } while (ret == DISAS_NEXT);
@ -3037,14 +3037,14 @@ void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
case DISAS_NORETURN: case DISAS_NORETURN:
break; break;
case DISAS_TOO_MANY: case DISAS_TOO_MANY:
if (use_goto_tb(&ctx, ctx.pc)) { if (use_goto_tb(&ctx, ctx.base.pc_next)) {
tcg_gen_goto_tb(0); tcg_gen_goto_tb(0);
tcg_gen_movi_i64(cpu_pc, ctx.pc); tcg_gen_movi_i64(cpu_pc, ctx.base.pc_next);
tcg_gen_exit_tb((uintptr_t)ctx.tb); tcg_gen_exit_tb((uintptr_t)ctx.base.tb);
} }
/* FALLTHRU */ /* FALLTHRU */
case DISAS_PC_STALE: case DISAS_PC_STALE:
tcg_gen_movi_i64(cpu_pc, ctx.pc); tcg_gen_movi_i64(cpu_pc, ctx.base.pc_next);
/* FALLTHRU */ /* FALLTHRU */
case DISAS_PC_UPDATED: case DISAS_PC_UPDATED:
if (!use_exit_tb(&ctx)) { if (!use_exit_tb(&ctx)) {
@ -3053,7 +3053,7 @@ void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
} }
/* FALLTHRU */ /* FALLTHRU */
case DISAS_PC_UPDATED_NOCHAIN: case DISAS_PC_UPDATED_NOCHAIN:
if (ctx.singlestep_enabled) { if (ctx.base.singlestep_enabled) {
gen_excp_1(EXCP_DEBUG, 0); gen_excp_1(EXCP_DEBUG, 0);
} else { } else {
tcg_gen_exit_tb(0); tcg_gen_exit_tb(0);
@ -3065,7 +3065,7 @@ void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
gen_tb_end(tb, num_insns); gen_tb_end(tb, num_insns);
tb->size = ctx.pc - pc_start; tb->size = ctx.base.pc_next - pc_start;
tb->icount = num_insns; tb->icount = num_insns;
#ifdef DEBUG_DISAS #ifdef DEBUG_DISAS
@ -3073,7 +3073,7 @@ void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
&& qemu_log_in_addr_range(pc_start)) { && qemu_log_in_addr_range(pc_start)) {
qemu_log_lock(); qemu_log_lock();
qemu_log("IN: %s\n", lookup_symbol(pc_start)); qemu_log("IN: %s\n", lookup_symbol(pc_start));
log_target_disas(cs, pc_start, ctx.pc - pc_start, 1); log_target_disas(cs, pc_start, ctx.base.pc_next - pc_start, 1);
qemu_log("\n"); qemu_log("\n");
qemu_log_unlock(); qemu_log_unlock();
} }