diff options
Diffstat (limited to 'target-arm/translate-a64.c')
-rw-r--r-- | target-arm/translate-a64.c | 40 |
1 files changed, 22 insertions, 18 deletions
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index 19f9d8d2c8..14e8131b05 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -126,6 +126,8 @@ void aarch64_cpu_dump_state(CPUState *cs, FILE *f, CPUARMState *env = &cpu->env; uint32_t psr = pstate_read(env); int i; + int el = arm_current_el(env); + const char *ns_status; cpu_fprintf(f, "PC=%016"PRIx64" SP=%016"PRIx64"\n", env->pc, env->xregs[31]); @@ -137,13 +139,22 @@ void aarch64_cpu_dump_state(CPUState *cs, FILE *f, cpu_fprintf(f, " "); } } - cpu_fprintf(f, "PSTATE=%08x (flags %c%c%c%c)\n", + + if (arm_feature(env, ARM_FEATURE_EL3) && el != 3) { + ns_status = env->cp15.scr_el3 & SCR_NS ? "NS " : "S "; + } else { + ns_status = ""; + } + + cpu_fprintf(f, "\nPSTATE=%08x %c%c%c%c %sEL%d%c\n", psr, psr & PSTATE_N ? 'N' : '-', psr & PSTATE_Z ? 'Z' : '-', psr & PSTATE_C ? 'C' : '-', - psr & PSTATE_V ? 'V' : '-'); - cpu_fprintf(f, "\n"); + psr & PSTATE_V ? 'V' : '-', + ns_status, + el, + psr & PSTATE_SP ? 'h' : 't'); if (flags & CPU_DUMP_FPU) { int numvfpregs = 32; @@ -1805,9 +1816,6 @@ static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2, * o2: 0 -> exclusive, 1 -> not * o1: 0 -> single register, 1 -> register pair * o0: 1 -> load-acquire/store-release, 0 -> not - * - * o0 == 0 AND o2 == 1 is un-allocated - * o1 == 1 is un-allocated except for 32 and 64 bit sizes */ static void disas_ldst_excl(DisasContext *s, uint32_t insn) { @@ -1822,7 +1830,8 @@ static void disas_ldst_excl(DisasContext *s, uint32_t insn) int size = extract32(insn, 30, 2); TCGv_i64 tcg_addr; - if ((!is_excl && !is_lasr) || + if ((!is_excl && !is_pair && !is_lasr) || + (!is_excl && is_pair) || (is_pair && size < 2)) { unallocated_encoding(s); return; @@ -1851,15 +1860,6 @@ static void disas_ldst_excl(DisasContext *s, uint32_t insn) } else { do_gpr_ld(s, tcg_rt, tcg_addr, size, false, false); } - if (is_pair) { - TCGv_i64 tcg_rt2 = cpu_reg(s, rt); - tcg_gen_addi_i64(tcg_addr, tcg_addr, 1 << size); - if (is_store) { - do_gpr_st(s, tcg_rt2, tcg_addr, size); - } else { - do_gpr_ld(s, tcg_rt2, tcg_addr, size, false, false); - } - } } } @@ -11091,13 +11091,17 @@ void gen_intermediate_code_a64(ARMCPU *cpu, TranslationBlock *tb) QTAILQ_FOREACH(bp, &cs->breakpoints, entry) { if (bp->pc == dc->pc) { if (bp->flags & BP_CPU) { + gen_a64_set_pc_im(dc->pc); gen_helper_check_breakpoints(cpu_env); /* End the TB early; it likely won't be executed */ dc->is_jmp = DISAS_UPDATE; } else { gen_exception_internal_insn(dc, 0, EXCP_DEBUG); - /* Advance PC so that clearing the breakpoint will - invalidate this TB. */ + /* The address covered by the breakpoint must be + included in [tb->pc, tb->pc + tb->size) in order + 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; goto done_generating; } |