diff --git a/qemu/target/arm/translate-a64.c b/qemu/target/arm/translate-a64.c index 06990c26..cc083ea7 100644 --- a/qemu/target/arm/translate-a64.c +++ b/qemu/target/arm/translate-a64.c @@ -1425,7 +1425,7 @@ static inline AArch64DecodeFn *lookup_disas_fn(const AArch64DecodeTable *table, static void disas_uncond_b_imm(DisasContext *s, uint32_t insn) { TCGContext *tcg_ctx = s->uc->tcg_ctx; - 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 */ @@ -1454,7 +1454,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(tcg_ctx); @@ -1484,7 +1484,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(tcg_ctx); @@ -1516,7 +1516,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); @@ -1903,7 +1903,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, s->pc - 4); + gen_a64_set_pc_im(s, s->pc_curr); tmpptr = tcg_const_ptr(tcg_ctx, ri); syndrome = syn_aa64_sysregtrap(op0, op1, op2, crn, crm, rt, isread); tcg_syn = tcg_const_i32(tcg_ctx, syndrome); @@ -2072,7 +2072,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, s->pc - 4); + gen_a64_set_pc_im(s, s->pc_curr); gen_helper_pre_hvc(tcg_ctx, tcg_ctx->cpu_env); gen_ss_advance(s); gen_exception_insn(s, 0, EXCP_HVC, syn_aa64_hvc(imm16), 2); @@ -2082,7 +2082,7 @@ static void disas_exc(DisasContext *s, uint32_t insn) unallocated_encoding(s); break; } - gen_a64_set_pc_im(s, s->pc - 4); + gen_a64_set_pc_im(s, s->pc_curr); tmp = tcg_const_i32(tcg_ctx, syn_aa64_smc(imm16)); gen_helper_pre_smc(tcg_ctx, tcg_ctx->cpu_env, tmp); tcg_temp_free_i32(tcg_ctx, tmp); @@ -2801,7 +2801,7 @@ static void disas_ld_lit(DisasContext *s, uint32_t insn) tcg_rt = cpu_reg(s, rt); - clean_addr = tcg_const_i64(tcg_ctx, (s->pc - 4) + imm); + clean_addr = tcg_const_i64(tcg_ctx, s->pc_curr + imm); if (is_vector) { do_fp_ld(s, rt, clean_addr, size); } else { @@ -3788,7 +3788,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) */ @@ -11828,7 +11828,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(); } @@ -14363,6 +14363,7 @@ static void disas_a64_insn(CPUARMState *env, DisasContext *s) return; } + s->pc_curr = s->pc; insn = arm_ldl_code(env, s->pc, s->sctlr_b); s->insn = insn; s->pc += 4; diff --git a/qemu/target/arm/translate-a64.h b/qemu/target/arm/translate-a64.h index 29dc2f01..fe96d76e 100644 --- a/qemu/target/arm/translate-a64.h +++ b/qemu/target/arm/translate-a64.h @@ -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) diff --git a/qemu/target/arm/translate.c b/qemu/target/arm/translate.c index 59de07e0..495cc4c3 100644 --- a/qemu/target/arm/translate.c +++ b/qemu/target/arm/translate.c @@ -1269,7 +1269,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(tcg_ctx, tcg_ctx->cpu_env); /* Otherwise we will treat this as a real exception which * happens after execution of the insn. (The distinction matters @@ -1289,7 +1289,7 @@ static inline void gen_smc(DisasContext *s) TCGv_i32 tmp; TCGContext *tcg_ctx = s->uc->tcg_ctx; - gen_set_pc_im(s, s->pc - 4); + gen_set_pc_im(s, s->pc_curr); tmp = tcg_const_i32(tcg_ctx, syn_aa32_smc()); gen_helper_pre_smc(tcg_ctx, tcg_ctx->cpu_env, tmp); tcg_temp_free_i32(tcg_ctx, tmp); @@ -3310,7 +3310,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(tcg_ctx, tgtmode); tcg_regno = tcg_const_i32(tcg_ctx, regno); @@ -3333,7 +3333,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_ctx); tcg_tgtmode = tcg_const_i32(tcg_ctx, tgtmode); tcg_regno = tcg_const_i32(tcg_ctx, regno); @@ -7364,7 +7364,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(tcg_ctx, ri); tcg_syn = tcg_const_i32(tcg_ctx, syndrome); tcg_isread = tcg_const_i32(tcg_ctx, isread); @@ -7786,7 +7786,7 @@ static void gen_srs(DisasContext *s, tmp = tcg_const_i32(tcg_ctx, 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(tcg_ctx, addr, tcg_ctx->cpu_env, tmp); tcg_temp_free_i32(tcg_ctx, tmp); switch (amode) { @@ -12232,6 +12232,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; @@ -12301,6 +12302,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; diff --git a/qemu/target/arm/translate.h b/qemu/target/arm/translate.h index deaa95a8..f513b89e 100644 --- a/qemu/target/arm/translate.h +++ b/qemu/target/arm/translate.h @@ -10,6 +10,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. */