aboutsummaryrefslogtreecommitdiff
path: root/target-arm/translate-a64.c
diff options
context:
space:
mode:
Diffstat (limited to 'target-arm/translate-a64.c')
-rw-r--r--target-arm/translate-a64.c40
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;
}