Skip to content

Commit

Permalink
target/arm: Replace s->pc with s->base.pc_next
Browse files Browse the repository at this point in the history
We must update s->base.pc_next when we return from the translate_insn
hook to the main translator loop.  By incrementing s->base.pc_next
immediately after reading the insn word, "pc_next" contains the address
of the next instruction throughout translation.

All remaining uses of s->pc are referencing the address of the next insn,
so this is now a simple global replacement.  Remove the "s->pc" field.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-id: 20190807045335.1361-7-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
rth7680 authored and pm215 committed Aug 16, 2019
1 parent 4818c37 commit a041591
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 83 deletions.
51 changes: 23 additions & 28 deletions target/arm/translate-a64.c
Expand Up @@ -255,15 +255,15 @@ static void gen_exception_internal(int excp)

static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
{
gen_a64_set_pc_im(s->pc - offset);
gen_a64_set_pc_im(s->base.pc_next - offset);
gen_exception_internal(excp);
s->base.is_jmp = DISAS_NORETURN;
}

static void gen_exception_insn(DisasContext *s, int offset, int excp,
uint32_t syndrome, uint32_t target_el)
{
gen_a64_set_pc_im(s->pc - offset);
gen_a64_set_pc_im(s->base.pc_next - offset);
gen_exception(excp, syndrome, target_el);
s->base.is_jmp = DISAS_NORETURN;
}
Expand All @@ -273,7 +273,7 @@ static void gen_exception_bkpt_insn(DisasContext *s, int offset,
{
TCGv_i32 tcg_syn;

gen_a64_set_pc_im(s->pc - offset);
gen_a64_set_pc_im(s->base.pc_next - offset);
tcg_syn = tcg_const_i32(syndrome);
gen_helper_exception_bkpt_insn(cpu_env, tcg_syn);
tcg_temp_free_i32(tcg_syn);
Expand Down Expand Up @@ -1238,7 +1238,7 @@ static void disas_uncond_b_imm(DisasContext *s, uint32_t insn)

if (insn & (1U << 31)) {
/* BL Branch with link */
tcg_gen_movi_i64(cpu_reg(s, 30), s->pc);
tcg_gen_movi_i64(cpu_reg(s, 30), s->base.pc_next);
}

/* B Branch / BL Branch with link */
Expand Down Expand Up @@ -1271,7 +1271,7 @@ static void disas_comp_b_imm(DisasContext *s, uint32_t insn)
tcg_gen_brcondi_i64(op ? TCG_COND_NE : TCG_COND_EQ,
tcg_cmp, 0, label_match);

gen_goto_tb(s, 0, s->pc);
gen_goto_tb(s, 0, s->base.pc_next);
gen_set_label(label_match);
gen_goto_tb(s, 1, addr);
}
Expand Down Expand Up @@ -1302,7 +1302,7 @@ static void disas_test_b_imm(DisasContext *s, uint32_t insn)
tcg_gen_brcondi_i64(op ? TCG_COND_NE : TCG_COND_EQ,
tcg_cmp, 0, label_match);
tcg_temp_free_i64(tcg_cmp);
gen_goto_tb(s, 0, s->pc);
gen_goto_tb(s, 0, s->base.pc_next);
gen_set_label(label_match);
gen_goto_tb(s, 1, addr);
}
Expand Down Expand Up @@ -1330,7 +1330,7 @@ static void disas_cond_b_imm(DisasContext *s, uint32_t insn)
/* genuinely conditional branches */
TCGLabel *label_match = gen_new_label();
arm_gen_test_cc(cond, label_match);
gen_goto_tb(s, 0, s->pc);
gen_goto_tb(s, 0, s->base.pc_next);
gen_set_label(label_match);
gen_goto_tb(s, 1, addr);
} else {
Expand Down Expand Up @@ -1491,7 +1491,7 @@ static void handle_sync(DisasContext *s, uint32_t insn,
* any pending interrupts immediately.
*/
reset_btype(s);
gen_goto_tb(s, 0, s->pc);
gen_goto_tb(s, 0, s->base.pc_next);
return;

case 7: /* SB */
Expand All @@ -1503,7 +1503,7 @@ static void handle_sync(DisasContext *s, uint32_t insn,
* MB and end the TB instead.
*/
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
gen_goto_tb(s, 0, s->pc);
gen_goto_tb(s, 0, s->base.pc_next);
return;

default:
Expand Down Expand Up @@ -2015,7 +2015,7 @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
gen_a64_set_pc(s, dst);
/* BLR also needs to load return address */
if (opc == 1) {
tcg_gen_movi_i64(cpu_reg(s, 30), s->pc);
tcg_gen_movi_i64(cpu_reg(s, 30), s->base.pc_next);
}
break;

Expand All @@ -2042,7 +2042,7 @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
gen_a64_set_pc(s, dst);
/* BLRAA also needs to load return address */
if (opc == 9) {
tcg_gen_movi_i64(cpu_reg(s, 30), s->pc);
tcg_gen_movi_i64(cpu_reg(s, 30), s->base.pc_next);
}
break;

Expand Down Expand Up @@ -14030,10 +14030,10 @@ static void disas_a64_insn(CPUARMState *env, DisasContext *s)
{
uint32_t insn;

s->pc_curr = s->pc;
insn = arm_ldl_code(env, s->pc, s->sctlr_b);
s->pc_curr = s->base.pc_next;
insn = arm_ldl_code(env, s->base.pc_next, s->sctlr_b);
s->insn = insn;
s->pc += 4;
s->base.pc_next += 4;

s->fp_access_checked = false;

Expand Down Expand Up @@ -14130,7 +14130,6 @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
int bound, core_mmu_idx;

dc->isar = &arm_cpu->isar;
dc->pc = dc->base.pc_first;
dc->condjmp = 0;

dc->aarch64 = 1;
Expand Down Expand Up @@ -14203,7 +14202,7 @@ static void aarch64_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
{
DisasContext *dc = container_of(dcbase, DisasContext, base);

tcg_gen_insn_start(dc->pc, 0, 0);
tcg_gen_insn_start(dc->base.pc_next, 0, 0);
dc->insn_start = tcg_last_op();
}

Expand All @@ -14213,7 +14212,7 @@ static bool aarch64_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
DisasContext *dc = container_of(dcbase, DisasContext, base);

if (bp->flags & BP_CPU) {
gen_a64_set_pc_im(dc->pc);
gen_a64_set_pc_im(dc->base.pc_next);
gen_helper_check_breakpoints(cpu_env);
/* End the TB early; it likely won't be executed */
dc->base.is_jmp = DISAS_TOO_MANY;
Expand All @@ -14224,7 +14223,7 @@ static bool aarch64_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
to for it to be properly cleared -- thus we
increment the PC here so that the logic setting
tb->size below does the right thing. */
dc->pc += 4;
dc->base.pc_next += 4;
dc->base.is_jmp = DISAS_NORETURN;
}

Expand Down Expand Up @@ -14254,7 +14253,6 @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
disas_a64_insn(env, dc);
}

dc->base.pc_next = dc->pc;
translator_loop_temp_check(&dc->base);
}

Expand All @@ -14270,7 +14268,7 @@ static void aarch64_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
*/
switch (dc->base.is_jmp) {
default:
gen_a64_set_pc_im(dc->pc);
gen_a64_set_pc_im(dc->base.pc_next);
/* fall through */
case DISAS_EXIT:
case DISAS_JUMP:
Expand All @@ -14287,11 +14285,11 @@ static void aarch64_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
switch (dc->base.is_jmp) {
case DISAS_NEXT:
case DISAS_TOO_MANY:
gen_goto_tb(dc, 1, dc->pc);
gen_goto_tb(dc, 1, dc->base.pc_next);
break;
default:
case DISAS_UPDATE:
gen_a64_set_pc_im(dc->pc);
gen_a64_set_pc_im(dc->base.pc_next);
/* fall through */
case DISAS_EXIT:
tcg_gen_exit_tb(NULL, 0);
Expand All @@ -14303,11 +14301,11 @@ static void aarch64_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
case DISAS_SWI:
break;
case DISAS_WFE:
gen_a64_set_pc_im(dc->pc);
gen_a64_set_pc_im(dc->base.pc_next);
gen_helper_wfe(cpu_env);
break;
case DISAS_YIELD:
gen_a64_set_pc_im(dc->pc);
gen_a64_set_pc_im(dc->base.pc_next);
gen_helper_yield(cpu_env);
break;
case DISAS_WFI:
Expand All @@ -14317,7 +14315,7 @@ static void aarch64_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
*/
TCGv_i32 tmp = tcg_const_i32(4);

gen_a64_set_pc_im(dc->pc);
gen_a64_set_pc_im(dc->base.pc_next);
gen_helper_wfi(cpu_env, tmp);
tcg_temp_free_i32(tmp);
/* The helper doesn't necessarily throw an exception, but we
Expand All @@ -14328,9 +14326,6 @@ static void aarch64_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
}
}
}

/* Functions above can change dc->pc, so re-align db->pc_next */
dc->base.pc_next = dc->pc;
}

static void aarch64_tr_disas_log(const DisasContextBase *dcbase,
Expand Down

0 comments on commit a041591

Please sign in to comment.