Skip to content

Commit

Permalink
target/arm: Introduce pc_curr
Browse files Browse the repository at this point in the history
Add a new field to retain the address of the instruction currently
being translated.  The 32-bit uses are all within subroutines used
by a32 and t32.  This will become less obvious when t16 support is
merged with a32+t32, and having a clear definition will help.

Convert aarch64 as well for consistency.  Note that there is one
instance of a pre-assert fprintf that used the wrong value for the
address of the current instruction.

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-3-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 331b1ca commit 43722a6
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 17 deletions.
21 changes: 11 additions & 10 deletions target/arm/translate-a64.c
Expand Up @@ -1234,7 +1234,7 @@ static inline AArch64DecodeFn *lookup_disas_fn(const AArch64DecodeTable *table,
*/
static void disas_uncond_b_imm(DisasContext *s, uint32_t insn)
{
uint64_t addr = s->pc + sextract32(insn, 0, 26) * 4 - 4;
uint64_t addr = s->pc_curr + sextract32(insn, 0, 26) * 4;

if (insn & (1U << 31)) {
/* BL Branch with link */
Expand Down Expand Up @@ -1262,7 +1262,7 @@ static void disas_comp_b_imm(DisasContext *s, uint32_t insn)
sf = extract32(insn, 31, 1);
op = extract32(insn, 24, 1); /* 0: CBZ; 1: CBNZ */
rt = extract32(insn, 0, 5);
addr = s->pc + sextract32(insn, 5, 19) * 4 - 4;
addr = s->pc_curr + sextract32(insn, 5, 19) * 4;

tcg_cmp = read_cpu_reg(s, rt, sf);
label_match = gen_new_label();
Expand Down Expand Up @@ -1291,7 +1291,7 @@ static void disas_test_b_imm(DisasContext *s, uint32_t insn)

bit_pos = (extract32(insn, 31, 1) << 5) | extract32(insn, 19, 5);
op = extract32(insn, 24, 1); /* 0: TBZ; 1: TBNZ */
addr = s->pc + sextract32(insn, 5, 14) * 4 - 4;
addr = s->pc_curr + sextract32(insn, 5, 14) * 4;
rt = extract32(insn, 0, 5);

tcg_cmp = tcg_temp_new_i64();
Expand Down Expand Up @@ -1322,7 +1322,7 @@ static void disas_cond_b_imm(DisasContext *s, uint32_t insn)
unallocated_encoding(s);
return;
}
addr = s->pc + sextract32(insn, 5, 19) * 4 - 4;
addr = s->pc_curr + sextract32(insn, 5, 19) * 4;
cond = extract32(insn, 0, 4);

reset_btype(s);
Expand Down Expand Up @@ -1706,7 +1706,7 @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
TCGv_i32 tcg_syn, tcg_isread;
uint32_t syndrome;

gen_a64_set_pc_im(s->pc - 4);
gen_a64_set_pc_im(s->pc_curr);
tmpptr = tcg_const_ptr(ri);
syndrome = syn_aa64_sysregtrap(op0, op1, op2, crn, crm, rt, isread);
tcg_syn = tcg_const_i32(syndrome);
Expand Down Expand Up @@ -1870,7 +1870,7 @@ static void disas_exc(DisasContext *s, uint32_t insn)
/* The pre HVC helper handles cases when HVC gets trapped
* as an undefined insn by runtime configuration.
*/
gen_a64_set_pc_im(s->pc - 4);
gen_a64_set_pc_im(s->pc_curr);
gen_helper_pre_hvc(cpu_env);
gen_ss_advance(s);
gen_exception_insn(s, 0, EXCP_HVC, syn_aa64_hvc(imm16), 2);
Expand All @@ -1880,7 +1880,7 @@ static void disas_exc(DisasContext *s, uint32_t insn)
unallocated_encoding(s);
break;
}
gen_a64_set_pc_im(s->pc - 4);
gen_a64_set_pc_im(s->pc_curr);
tmp = tcg_const_i32(syn_aa64_smc(imm16));
gen_helper_pre_smc(cpu_env, tmp);
tcg_temp_free_i32(tmp);
Expand Down Expand Up @@ -2601,7 +2601,7 @@ static void disas_ld_lit(DisasContext *s, uint32_t insn)

tcg_rt = cpu_reg(s, rt);

clean_addr = tcg_const_i64((s->pc - 4) + imm);
clean_addr = tcg_const_i64(s->pc_curr + imm);
if (is_vector) {
do_fp_ld(s, rt, clean_addr, size);
} else {
Expand Down Expand Up @@ -3580,7 +3580,7 @@ static void disas_pc_rel_adr(DisasContext *s, uint32_t insn)
offset = sextract64(insn, 5, 19);
offset = offset << 2 | extract32(insn, 29, 2);
rd = extract32(insn, 0, 5);
base = s->pc - 4;
base = s->pc_curr;

if (page) {
/* ADRP (page based) */
Expand Down Expand Up @@ -11519,7 +11519,7 @@ static void disas_simd_three_reg_same_fp16(DisasContext *s, uint32_t insn)
break;
default:
fprintf(stderr, "%s: insn %#04x, fpop %#2x @ %#" PRIx64 "\n",
__func__, insn, fpopcode, s->pc);
__func__, insn, fpopcode, s->pc_curr);
g_assert_not_reached();
}

Expand Down Expand Up @@ -14030,6 +14030,7 @@ 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->insn = insn;
s->pc += 4;
Expand Down
2 changes: 1 addition & 1 deletion target/arm/translate-a64.h
Expand Up @@ -25,7 +25,7 @@ void unallocated_encoding(DisasContext *s);
qemu_log_mask(LOG_UNIMP, \
"%s:%d: unsupported instruction encoding 0x%08x " \
"at pc=%016" PRIx64 "\n", \
__FILE__, __LINE__, insn, s->pc - 4); \
__FILE__, __LINE__, insn, s->pc_curr); \
unallocated_encoding(s); \
} while (0)

Expand Down
14 changes: 8 additions & 6 deletions target/arm/translate.c
Expand Up @@ -1197,7 +1197,7 @@ static inline void gen_hvc(DisasContext *s, int imm16)
* as an undefined insn by runtime configuration (ie before
* the insn really executes).
*/
gen_set_pc_im(s, s->pc - 4);
gen_set_pc_im(s, s->pc_curr);
gen_helper_pre_hvc(cpu_env);
/* Otherwise we will treat this as a real exception which
* happens after execution of the insn. (The distinction matters
Expand All @@ -1216,7 +1216,7 @@ static inline void gen_smc(DisasContext *s)
*/
TCGv_i32 tmp;

gen_set_pc_im(s, s->pc - 4);
gen_set_pc_im(s, s->pc_curr);
tmp = tcg_const_i32(syn_aa32_smc());
gen_helper_pre_smc(cpu_env, tmp);
tcg_temp_free_i32(tmp);
Expand Down Expand Up @@ -3175,7 +3175,7 @@ static void gen_msr_banked(DisasContext *s, int r, int sysm, int rn)

/* Sync state because msr_banked() can raise exceptions */
gen_set_condexec(s);
gen_set_pc_im(s, s->pc - 4);
gen_set_pc_im(s, s->pc_curr);
tcg_reg = load_reg(s, rn);
tcg_tgtmode = tcg_const_i32(tgtmode);
tcg_regno = tcg_const_i32(regno);
Expand All @@ -3197,7 +3197,7 @@ static void gen_mrs_banked(DisasContext *s, int r, int sysm, int rn)

/* Sync state because mrs_banked() can raise exceptions */
gen_set_condexec(s);
gen_set_pc_im(s, s->pc - 4);
gen_set_pc_im(s, s->pc_curr);
tcg_reg = tcg_temp_new_i32();
tcg_tgtmode = tcg_const_i32(tgtmode);
tcg_regno = tcg_const_i32(regno);
Expand Down Expand Up @@ -7204,7 +7204,7 @@ static int disas_coproc_insn(DisasContext *s, uint32_t insn)
}

gen_set_condexec(s);
gen_set_pc_im(s, s->pc - 4);
gen_set_pc_im(s, s->pc_curr);
tmpptr = tcg_const_ptr(ri);
tcg_syn = tcg_const_i32(syndrome);
tcg_isread = tcg_const_i32(isread);
Expand Down Expand Up @@ -7614,7 +7614,7 @@ static void gen_srs(DisasContext *s,
tmp = tcg_const_i32(mode);
/* get_r13_banked() will raise an exception if called from System mode */
gen_set_condexec(s);
gen_set_pc_im(s, s->pc - 4);
gen_set_pc_im(s, s->pc_curr);
gen_helper_get_r13_banked(addr, cpu_env, tmp);
tcg_temp_free_i32(tmp);
switch (amode) {
Expand Down Expand Up @@ -12039,6 +12039,7 @@ static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
return;
}

dc->pc_curr = dc->pc;
insn = arm_ldl_code(env, dc->pc, dc->sctlr_b);
dc->insn = insn;
dc->pc += 4;
Expand Down Expand Up @@ -12107,6 +12108,7 @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
return;
}

dc->pc_curr = dc->pc;
insn = arm_lduw_code(env, dc->pc, dc->sctlr_b);
is_16bit = thumb_insn_is_16bit(dc, dc->pc, insn);
dc->pc += 2;
Expand Down
2 changes: 2 additions & 0 deletions target/arm/translate.h
Expand Up @@ -11,6 +11,8 @@ typedef struct DisasContext {
const ARMISARegisters *isar;

target_ulong pc;
/* The address of the current instruction being translated. */
target_ulong pc_curr;
target_ulong page_start;
uint32_t insn;
/* Nonzero if this instruction has been conditionally skipped. */
Expand Down

0 comments on commit 43722a6

Please sign in to comment.