diff --git a/qemu/target/arm/translate-a64.c b/qemu/target/arm/translate-a64.c index cc083ea7..0be41a79 100644 --- a/qemu/target/arm/translate-a64.c +++ b/qemu/target/arm/translate-a64.c @@ -396,7 +396,7 @@ static void gen_exception_internal(DisasContext *s, int excp) static void gen_exception_internal_insn(DisasContext *s, int offset, int excp) { - gen_a64_set_pc_im(s, s->pc - offset); + gen_a64_set_pc_im(s, s->base.pc_next - offset); gen_exception_internal(s, excp); s->base.is_jmp = DISAS_NORETURN; } @@ -404,7 +404,7 @@ static void gen_exception_internal_insn(DisasContext *s, int offset, int excp) static void gen_exception_insn(DisasContext *s, int offset, int excp, uint32_t syndrome, uint32_t target_el) { - gen_a64_set_pc_im(s, s->pc - offset); + gen_a64_set_pc_im(s, s->base.pc_next - offset); gen_exception(s, excp, syndrome, target_el); s->base.is_jmp = DISAS_NORETURN; } @@ -415,7 +415,7 @@ static void gen_exception_bkpt_insn(DisasContext *s, int offset, TCGContext *tcg_ctx = s->uc->tcg_ctx; TCGv_i32 tcg_syn; - gen_a64_set_pc_im(s, s->pc - offset); + gen_a64_set_pc_im(s, s->base.pc_next - offset); tcg_syn = tcg_const_i32(tcg_ctx, syndrome); gen_helper_exception_bkpt_insn(tcg_ctx, tcg_ctx->cpu_env, tcg_syn); tcg_temp_free_i32(tcg_ctx, tcg_syn); @@ -1429,7 +1429,7 @@ static void disas_uncond_b_imm(DisasContext *s, uint32_t insn) if (insn & (1U << 31)) { /* BL Branch with link */ - tcg_gen_movi_i64(tcg_ctx, cpu_reg(s, 30), s->pc); + tcg_gen_movi_i64(tcg_ctx, cpu_reg(s, 30), s->base.pc_next); } /* B Branch / BL Branch with link */ @@ -1463,7 +1463,7 @@ static void disas_comp_b_imm(DisasContext *s, uint32_t insn) tcg_gen_brcondi_i64(tcg_ctx, 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(tcg_ctx, label_match); gen_goto_tb(s, 1, addr); } @@ -1495,7 +1495,7 @@ static void disas_test_b_imm(DisasContext *s, uint32_t insn) tcg_gen_brcondi_i64(tcg_ctx, op ? TCG_COND_NE : TCG_COND_EQ, tcg_cmp, 0, label_match); tcg_temp_free_i64(tcg_ctx, tcg_cmp); - gen_goto_tb(s, 0, s->pc); + gen_goto_tb(s, 0, s->base.pc_next); gen_set_label(tcg_ctx, label_match); gen_goto_tb(s, 1, addr); } @@ -1524,7 +1524,7 @@ static void disas_cond_b_imm(DisasContext *s, uint32_t insn) /* genuinely conditional branches */ TCGLabel *label_match = gen_new_label(tcg_ctx); arm_gen_test_cc(s, cond, label_match); - gen_goto_tb(s, 0, s->pc); + gen_goto_tb(s, 0, s->base.pc_next); gen_set_label(tcg_ctx, label_match); gen_goto_tb(s, 1, addr); } else { @@ -1683,7 +1683,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 */ @@ -1695,7 +1695,7 @@ static void handle_sync(DisasContext *s, uint32_t insn, * MB and end the TB instead. */ tcg_gen_mb(tcg_ctx, TCG_MO_ALL | TCG_BAR_SC); - gen_goto_tb(s, 0, s->pc); + gen_goto_tb(s, 0, s->base.pc_next); return; default: @@ -2218,7 +2218,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(tcg_ctx, cpu_reg(s, 30), s->pc); + tcg_gen_movi_i64(tcg_ctx, cpu_reg(s, 30), s->base.pc_next); } break; @@ -2245,7 +2245,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(tcg_ctx, cpu_reg(s, 30), s->pc); + tcg_gen_movi_i64(tcg_ctx, cpu_reg(s, 30), s->base.pc_next); } break; @@ -14357,20 +14357,20 @@ static void disas_a64_insn(CPUARMState *env, DisasContext *s) TCGContext *tcg_ctx = env->uc->tcg_ctx; // Unicorn: end address tells us to stop emulation - if (s->pc == s->uc->addr_end) { + if (s->base.pc_next == s->uc->addr_end) { // imitate WFI instruction to halt emulation s->base.is_jmp = DISAS_WFI; return; } - 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; // Unicorn: trace this instruction on request - if (HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_CODE, s->pc - 4)) { - gen_uc_tracecode(tcg_ctx, 4, UC_HOOK_CODE_IDX, env->uc, s->pc - 4); + if (HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_CODE, s->pc_curr)) { + gen_uc_tracecode(tcg_ctx, 4, UC_HOOK_CODE_IDX, env->uc, s->pc_curr); // the callback might want to stop emulation immediately check_exit_request(tcg_ctx); } @@ -14473,7 +14473,6 @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase, dc->uc = env->uc; dc->isar = &arm_cpu->isar; - dc->pc = dc->base.pc_first; dc->condjmp = 0; dc->aarch64 = 1; @@ -14547,7 +14546,7 @@ static void aarch64_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu) DisasContext *dc = container_of(dcbase, DisasContext, base); TCGContext *tcg_ctx = cpu->uc->tcg_ctx; - tcg_gen_insn_start(tcg_ctx, dc->pc, 0, 0); + tcg_gen_insn_start(tcg_ctx, dc->base.pc_next, 0, 0); dc->insn_start = tcg_last_op(tcg_ctx); } @@ -14558,7 +14557,7 @@ static bool aarch64_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu, TCGContext *tcg_ctx = cpu->uc->tcg_ctx; if (bp->flags & BP_CPU) { - gen_a64_set_pc_im(dc, dc->pc); + gen_a64_set_pc_im(dc, dc->base.pc_next); gen_helper_check_breakpoints(tcg_ctx, tcg_ctx->cpu_env); /* End the TB early; it likely won't be executed */ dc->base.is_jmp = DISAS_TOO_MANY; @@ -14569,7 +14568,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; } @@ -14599,7 +14598,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); } @@ -14616,7 +14614,7 @@ static void aarch64_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) */ switch (dc->base.is_jmp) { default: - gen_a64_set_pc_im(dc, dc->pc); + gen_a64_set_pc_im(dc, dc->base.pc_next); /* fall through */ case DISAS_EXIT: case DISAS_JUMP: @@ -14633,11 +14631,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, dc->pc); + gen_a64_set_pc_im(dc, dc->base.pc_next); /* fall through */ case DISAS_EXIT: tcg_gen_exit_tb(tcg_ctx, NULL, 0); @@ -14649,11 +14647,11 @@ static void aarch64_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) case DISAS_SWI: break; case DISAS_WFE: - gen_a64_set_pc_im(dc, dc->pc); + gen_a64_set_pc_im(dc, dc->base.pc_next); gen_helper_wfe(tcg_ctx, tcg_ctx->cpu_env); break; case DISAS_YIELD: - gen_a64_set_pc_im(dc, dc->pc); + gen_a64_set_pc_im(dc, dc->base.pc_next); gen_helper_yield(tcg_ctx, tcg_ctx->cpu_env); break; case DISAS_WFI: @@ -14663,7 +14661,7 @@ static void aarch64_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) */ TCGv_i32 tmp = tcg_const_i32(tcg_ctx, 4); - gen_a64_set_pc_im(dc, dc->pc); + gen_a64_set_pc_im(dc, dc->base.pc_next); gen_helper_wfi(tcg_ctx, tcg_ctx->cpu_env, tmp); tcg_temp_free_i32(tcg_ctx, tmp); /* The helper doesn't necessarily throw an exception, but we @@ -14674,9 +14672,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, diff --git a/qemu/target/arm/translate.c b/qemu/target/arm/translate.c index 82c9370c..61f49d8f 100644 --- a/qemu/target/arm/translate.c +++ b/qemu/target/arm/translate.c @@ -1101,7 +1101,7 @@ static inline void gen_blxns(DisasContext *s, int rm) * We do however need to set the PC, because the blxns helper reads it. * The blxns helper may throw an exception. */ - gen_set_pc_im(s, s->pc); + gen_set_pc_im(s, s->base.pc_next); gen_helper_v7m_blxns(tcg_ctx, tcg_ctx->cpu_env, var); tcg_temp_free_i32(tcg_ctx, var); s->base.is_jmp = DISAS_EXIT; @@ -1295,7 +1295,7 @@ static inline void gen_hvc(DisasContext *s, int imm16) * for single stepping.) */ s->svc_imm = imm16; - gen_set_pc_im(s, s->pc); + gen_set_pc_im(s, s->base.pc_next); s->base.is_jmp = DISAS_HVC; } @@ -1311,14 +1311,14 @@ static inline void gen_smc(DisasContext *s) 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); - gen_set_pc_im(s, s->pc); + gen_set_pc_im(s, s->base.pc_next); s->base.is_jmp = DISAS_SMC; } static void gen_exception_internal_insn(DisasContext *s, int offset, int excp) { gen_set_condexec(s); - gen_set_pc_im(s, s->pc - offset); + gen_set_pc_im(s, s->base.pc_next - offset); gen_exception_internal(s, excp); s->base.is_jmp = DISAS_NORETURN; } @@ -1327,7 +1327,7 @@ static void gen_exception_insn(DisasContext *s, int offset, int excp, int syn, uint32_t target_el) { gen_set_condexec(s); - gen_set_pc_im(s, s->pc - offset); + gen_set_pc_im(s, s->base.pc_next - offset); gen_exception(s, excp, syn, target_el); s->base.is_jmp = DISAS_NORETURN; } @@ -1338,7 +1338,7 @@ static void gen_exception_bkpt_insn(DisasContext *s, int offset, uint32_t syn) TCGv_i32 tcg_syn; gen_set_condexec(s); - gen_set_pc_im(s, s->pc - offset); + gen_set_pc_im(s, s->base.pc_next - offset); tcg_syn = tcg_const_i32(tcg_ctx, syn); gen_helper_exception_bkpt_insn(tcg_ctx, tcg_ctx->cpu_env, tcg_syn); tcg_temp_free_i32(tcg_ctx, tcg_syn); @@ -1349,7 +1349,7 @@ static void gen_exception_bkpt_insn(DisasContext *s, int offset, uint32_t syn) static inline void gen_lookup_tb(DisasContext *s) { TCGContext *tcg_ctx = s->uc->tcg_ctx; - tcg_gen_movi_i32(tcg_ctx, tcg_ctx->cpu_R[15], s->pc); + tcg_gen_movi_i32(tcg_ctx, tcg_ctx->cpu_R[15], s->base.pc_next); s->base.is_jmp = DISAS_EXIT; } @@ -3020,7 +3020,7 @@ static inline bool use_goto_tb(DisasContext *s, target_ulong dest) { #ifndef CONFIG_USER_ONLY return (s->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) || - ((s->pc - 1) & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK); + ((s->base.pc_next - 1) & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK); #else return true; #endif @@ -3414,17 +3414,17 @@ static void gen_nop_hint(DisasContext *s, int val) */ case 1: /* yield */ if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) { - gen_set_pc_im(s, s->pc); + gen_set_pc_im(s, s->base.pc_next); s->base.is_jmp = DISAS_YIELD; } break; case 3: /* wfi */ - gen_set_pc_im(s, s->pc); + gen_set_pc_im(s, s->base.pc_next); s->base.is_jmp = DISAS_WFI; break; case 2: /* wfe */ if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) { - gen_set_pc_im(s, s->pc); + gen_set_pc_im(s, s->base.pc_next); s->base.is_jmp = DISAS_WFE; } break; @@ -7401,7 +7401,7 @@ static int disas_coproc_insn(DisasContext *s, uint32_t insn) if (isread) { return 1; } - gen_set_pc_im(s, s->pc); + gen_set_pc_im(s, s->base.pc_next); s->base.is_jmp = DISAS_WFI; return 0; default: @@ -7895,8 +7895,8 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn) } // Unicorn: trace this instruction on request - if (HOOK_EXISTS_BOUNDED(s->uc, UC_HOOK_CODE, s->pc - 4)) { - gen_uc_tracecode(tcg_ctx, 4, UC_HOOK_CODE_IDX, s->uc, s->pc - 4); + if (HOOK_EXISTS_BOUNDED(s->uc, UC_HOOK_CODE, s->pc_curr)) { + gen_uc_tracecode(tcg_ctx, 4, UC_HOOK_CODE_IDX, s->uc, s->pc_curr); // the callback might want to stop emulation immediately check_exit_request(tcg_ctx); } @@ -7988,7 +7988,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn) * self-modifying code correctly and also to take * any pending interrupts immediately. */ - gen_goto_tb(s, 0, s->pc); + gen_goto_tb(s, 0, s->base.pc_next); return; case 7: /* sb */ if ((insn & 0xf) || !dc_isar_feature(aa32_sb, s)) { @@ -7999,7 +7999,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn) * for TCG; MB and end the TB instead. */ tcg_gen_mb(tcg_ctx, TCG_MO_ALL | TCG_BAR_SC); - gen_goto_tb(s, 0, s->pc); + gen_goto_tb(s, 0, s->base.pc_next); return; default: goto illegal_op; @@ -8055,7 +8055,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn) int32_t offset; tmp = tcg_temp_new_i32(tcg_ctx); - tcg_gen_movi_i32(tcg_ctx, tmp, s->pc); + tcg_gen_movi_i32(tcg_ctx, tmp, s->base.pc_next); store_reg(s, 14, tmp); /* Sign-extend the 24-bit offset */ offset = (((int32_t)insn) << 8) >> 8; @@ -8240,7 +8240,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn) /* branch link/exchange thumb (blx) */ tmp = load_reg(s, rm); tmp2 = tcg_temp_new_i32(tcg_ctx); - tcg_gen_movi_i32(tcg_ctx, tmp2, s->pc); + tcg_gen_movi_i32(tcg_ctx, tmp2, s->base.pc_next); store_reg(s, 14, tmp2); gen_bx(s, tmp); break; @@ -9400,7 +9400,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn) /* branch (and link) */ if (insn & (1 << 24)) { tmp = tcg_temp_new_i32(tcg_ctx); - tcg_gen_movi_i32(tcg_ctx, tmp, s->pc); + tcg_gen_movi_i32(tcg_ctx, tmp, s->base.pc_next); store_reg(s, 14, tmp); } offset = sextract32(insn << 2, 0, 26); @@ -9422,7 +9422,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn) break; case 0xf: /* swi */ - gen_set_pc_im(s, s->pc); + gen_set_pc_im(s, s->base.pc_next); s->svc_imm = extract32(insn, 0, 24); s->base.is_jmp = DISAS_SWI; break; @@ -10506,7 +10506,7 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn) if (insn & (1 << 14)) { /* Branch and link. */ - tcg_gen_movi_i32(tcg_ctx, tcg_ctx->cpu_R[14], s->pc | 1); + tcg_gen_movi_i32(tcg_ctx, tcg_ctx->cpu_R[14], s->base.pc_next | 1); } offset += read_pc(s); @@ -10629,7 +10629,7 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn) * and also to take any pending interrupts * immediately. */ - gen_goto_tb(s, 0, s->pc); + gen_goto_tb(s, 0, s->base.pc_next); break; case 7: /* sb */ if ((insn & 0xf) || !dc_isar_feature(aa32_sb, s)) { @@ -10640,7 +10640,7 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn) * for TCG; MB and end the TB instead. */ tcg_gen_mb(tcg_ctx, TCG_MO_ALL | TCG_BAR_SC); - gen_goto_tb(s, 0, s->pc); + gen_goto_tb(s, 0, s->base.pc_next); break; default: goto illegal_op; @@ -11302,7 +11302,7 @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn) /* BLX/BX */ tmp = load_reg(s, rm); if (link) { - val = (uint32_t)s->pc | 1; + val = (uint32_t)s->base.pc_next | 1; tmp2 = tcg_temp_new_i32(tcg_ctx); tcg_gen_movi_i32(tcg_ctx, tmp2, val); store_reg(s, 14, tmp2); @@ -11876,7 +11876,7 @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn) if (cond == 0xf) { /* swi */ - gen_set_pc_im(s, s->pc); + gen_set_pc_im(s, s->base.pc_next); s->svc_imm = extract32(insn, 0, 8); s->base.is_jmp = DISAS_SWI; break; @@ -11905,7 +11905,7 @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn) tcg_gen_andi_i32(tcg_ctx, tmp, tmp, 0xfffffffc); tmp2 = tcg_temp_new_i32(tcg_ctx); - tcg_gen_movi_i32(tcg_ctx, tmp2, s->pc | 1); + tcg_gen_movi_i32(tcg_ctx, tmp2, s->base.pc_next | 1); store_reg(s, 14, tmp2); gen_bx(s, tmp); break; @@ -11930,7 +11930,7 @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn) tcg_gen_addi_i32(tcg_ctx, tmp, tmp, offset); tmp2 = tcg_temp_new_i32(tcg_ctx); - tcg_gen_movi_i32(tcg_ctx, tmp2, s->pc | 1); + tcg_gen_movi_i32(tcg_ctx, tmp2, s->base.pc_next | 1); store_reg(s, 14, tmp2); gen_bx(s, tmp); } else { @@ -11950,16 +11950,16 @@ undef: static bool insn_crosses_page(CPUARMState *env, DisasContext *s) { - /* Return true if the insn at dc->pc might cross a page boundary. + /* Return true if the insn at dc->base.pc_next might cross a page boundary. * (False positives are OK, false negatives are not.) * We know this is a Thumb insn, and our caller ensures we are - * only called if dc->pc is less than 4 bytes from the page + * only called if dc->base.pc_next is less than 4 bytes from the page * boundary, so we cross the page if the first 16 bits indicate * that this is a 32 bit insn. */ - uint16_t insn = arm_lduw_code(env, s->pc, s->sctlr_b); + uint16_t insn = arm_lduw_code(env, s->base.pc_next, s->sctlr_b); - return !thumb_insn_is_16bit(s, s->pc, insn); + return !thumb_insn_is_16bit(s, s->base.pc_next, insn); } static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) @@ -11973,7 +11973,6 @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) dc->uc = cs->uc; dc->isar = &cpu->isar; - dc->pc = dc->base.pc_first; dc->condjmp = 0; dc->aarch64 = 0; @@ -12107,7 +12106,7 @@ static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu) DisasContext *dc = container_of(dcbase, DisasContext, base); TCGContext *tcg_ctx = cpu->uc->tcg_ctx; - tcg_gen_insn_start(tcg_ctx, dc->pc, + tcg_gen_insn_start(tcg_ctx, dc->base.pc_next, (dc->condexec_cond << 4) | (dc->condexec_mask >> 1), 0); dc->insn_start = tcg_last_op(tcg_ctx); @@ -12121,7 +12120,7 @@ static bool arm_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu, if (bp->flags & BP_CPU) { gen_set_condexec(dc); - gen_set_pc_im(dc, dc->pc); + gen_set_pc_im(dc, dc->base.pc_next); gen_helper_check_breakpoints(tcg_ctx, tcg_ctx->cpu_env); /* End the TB early; it's likely not going to be executed */ dc->base.is_jmp = DISAS_TOO_MANY; @@ -12134,7 +12133,7 @@ static bool arm_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu, tb->size below does the right thing. */ /* TODO: Advance PC by correct instruction length to * avoid disassembler error messages */ - dc->pc += 2; + dc->base.pc_next += 2; dc->base.is_jmp = DISAS_NORETURN; } @@ -12145,7 +12144,7 @@ static bool arm_pre_translate_insn(DisasContext *dc) { #ifdef CONFIG_USER_ONLY /* Intercept jump to the magic kernel page. */ - if (dc->pc >= 0xffff0000) { + if (dc->base.pc_next >= 0xffff0000) { /* We always get here via a jump, so know we are not in a conditional execution block. */ gen_exception_internal(dc, EXCP_KERNEL_TRAP); @@ -12155,7 +12154,7 @@ static bool arm_pre_translate_insn(DisasContext *dc) #endif // Unicorn: end address tells us to stop emulation - if (dc->pc == dc->uc->addr_end) { + if (dc->base.pc_next == dc->uc->addr_end) { // imitate WFI instruction to halt emulation dc->base.is_jmp = DISAS_WFI; return true; @@ -12188,7 +12187,6 @@ static void arm_post_translate_insn(DisasContext *dc) gen_set_label(tcg_ctx, dc->condlabel); dc->condjmp = 0; } - dc->base.pc_next = dc->pc; translator_loop_temp_check(&dc->base); } @@ -12202,10 +12200,10 @@ 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->pc_curr = dc->base.pc_next; + insn = arm_ldl_code(env, dc->base.pc_next, dc->sctlr_b); dc->insn = insn; - dc->pc += 4; + dc->base.pc_next += 4; disas_arm_insn(dc, insn); arm_post_translate_insn(dc); @@ -12272,15 +12270,15 @@ 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; + dc->pc_curr = dc->base.pc_next; + insn = arm_lduw_code(env, dc->base.pc_next, dc->sctlr_b); + is_16bit = thumb_insn_is_16bit(dc, dc->base.pc_next, insn); + dc->base.pc_next += 2; if (!is_16bit) { - uint32_t insn2 = arm_lduw_code(env, dc->pc, dc->sctlr_b); + uint32_t insn2 = arm_lduw_code(env, dc->base.pc_next, dc->sctlr_b); insn = insn << 16 | insn2; - dc->pc += 2; + dc->base.pc_next += 2; } dc->insn = insn; @@ -12298,8 +12296,8 @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) // Unicorn: trace this instruction on request const uint32_t insn_size = is_16bit ? 2 : 4; - if (HOOK_EXISTS_BOUNDED(dc->uc, UC_HOOK_CODE, dc->pc - insn_size)) { - gen_uc_tracecode(tcg_ctx, insn_size, UC_HOOK_CODE_IDX, dc->uc, dc->pc - insn_size); + if (HOOK_EXISTS_BOUNDED(dc->uc, UC_HOOK_CODE, dc->base.pc_next - insn_size)) { + gen_uc_tracecode(tcg_ctx, insn_size, UC_HOOK_CODE_IDX, dc->uc, dc->base.pc_next - insn_size); // the callback might want to stop emulation immediately check_exit_request(tcg_ctx); } @@ -12336,8 +12334,8 @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) * but isn't very efficient). */ if (dc->base.is_jmp == DISAS_NEXT - && (dc->pc - dc->page_start >= TARGET_PAGE_SIZE - || (dc->pc - dc->page_start >= TARGET_PAGE_SIZE - 3 + && (dc->base.pc_next - dc->page_start >= TARGET_PAGE_SIZE + || (dc->base.pc_next - dc->page_start >= TARGET_PAGE_SIZE - 3 && insn_crosses_page(env, dc)))) { dc->base.is_jmp = DISAS_TOO_MANY; } @@ -12383,7 +12381,7 @@ static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) case DISAS_NEXT: case DISAS_TOO_MANY: case DISAS_UPDATE: - gen_set_pc_im(dc, dc->pc); + gen_set_pc_im(dc, dc->base.pc_next); /* fall through */ default: /* FIXME: Single stepping a WFI insn will not halt the CPU. */ @@ -12404,13 +12402,13 @@ static void arm_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; case DISAS_JUMP: gen_goto_ptr(dc); break; case DISAS_UPDATE: - gen_set_pc_im(dc, dc->pc); + gen_set_pc_im(dc, dc->base.pc_next); /* fall through */ default: /* indicate that the hash table must be used to find the next TB */ @@ -12456,15 +12454,12 @@ static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) gen_set_label(tcg_ctx, dc->condlabel); gen_set_condexec(dc); if (unlikely(is_singlestepping(dc))) { - gen_set_pc_im(dc, dc->pc); + gen_set_pc_im(dc, dc->base.pc_next); gen_singlestep_exception(dc); } else { - gen_goto_tb(dc, 1, dc->pc); + gen_goto_tb(dc, 1, dc->base.pc_next); } } - - /* Functions above can change dc->pc, so re-align db->pc_next */ - dc->base.pc_next = dc->pc; } static void arm_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu) diff --git a/qemu/target/arm/translate.h b/qemu/target/arm/translate.h index f513b89e..cd1c8941 100644 --- a/qemu/target/arm/translate.h +++ b/qemu/target/arm/translate.h @@ -9,7 +9,6 @@ typedef struct DisasContext { DisasContextBase base; const ARMISARegisters *isar; - target_ulong pc; /* The address of the current instruction being translated. */ target_ulong pc_curr; target_ulong page_start;