diff options
| author | Richard Henderson <richard.henderson@linaro.org> | 2022-04-21 08:17:28 -0700 |
|---|---|---|
| committer | Richard Henderson <richard.henderson@linaro.org> | 2022-04-26 08:17:05 -0700 |
| commit | e84f1768449330a5b4c62a8aaa68f102ba6ec573 (patch) | |
| tree | af6ca0b49c5612a35ac77da507974dba9ee71713 /target/nios2/helper.c | |
| parent | a25c4eff32ba6192cff648ccaf0316bd829c80af (diff) | |
| download | focaccia-qemu-e84f1768449330a5b4c62a8aaa68f102ba6ec573.tar.gz focaccia-qemu-e84f1768449330a5b4c62a8aaa68f102ba6ec573.zip | |
target/nios2: Advance pc when raising exceptions
The exception return address for nios2 is the instruction after the one that was executing at the time of the exception. We have so far implemented this by advancing the pc during the process of raising the exception. It is perhaps a little less confusing to do this advance in the translator (and helpers) when raising the exception in the first place, so that we may more closely match kernel sources. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Message-Id: <20220421151735.31996-58-richard.henderson@linaro.org>
Diffstat (limited to 'target/nios2/helper.c')
| -rw-r--r-- | target/nios2/helper.c | 13 |
1 files changed, 7 insertions, 6 deletions
diff --git a/target/nios2/helper.c b/target/nios2/helper.c index e256d1528e..bb3b09e5a7 100644 --- a/target/nios2/helper.c +++ b/target/nios2/helper.c @@ -49,7 +49,7 @@ static void do_exception(Nios2CPU *cpu, uint32_t exception_addr, cr_es = CR_BSTATUS; } env->ctrl[cr_es] = old_status; - env->regs[r_ea] = env->pc + 4; + env->regs[r_ea] = env->pc; if (cpu->mmu_present) { new_status |= CR_STATUS_EH; @@ -113,7 +113,7 @@ static void do_eic_irq(Nios2CPU *cpu) } env->shadow_regs[new_rs][R_SSTATUS] = old_status; } - env->shadow_regs[new_rs][R_EA] = env->pc + 4; + env->shadow_regs[new_rs][R_EA] = env->pc; } env->ctrl[CR_STATUS] = new_status; @@ -187,6 +187,8 @@ void nios2_cpu_do_interrupt(CPUState *cs) switch (cs->exception_index) { case EXCP_IRQ: + /* Note that PC is advanced for interrupts as well. */ + env->pc += 4; if (cpu->eic_present) { do_eic_irq(cpu); } else { @@ -249,7 +251,6 @@ void nios2_cpu_do_interrupt(CPUState *cs) break; case EXCP_SEMIHOST: - env->pc += 4; do_nios2_semihosting(env); break; @@ -291,7 +292,7 @@ void nios2_cpu_do_unaligned_access(CPUState *cs, vaddr addr, env->ctrl[CR_BADADDR] = addr; cs->exception_index = EXCP_UNALIGN; - cpu_loop_exit_restore(cs, retaddr); + nios2_cpu_loop_exit_advance(env, retaddr); } bool nios2_cpu_tlb_fill(CPUState *cs, vaddr address, int size, @@ -330,7 +331,7 @@ bool nios2_cpu_tlb_fill(CPUState *cs, vaddr address, int size, cs->exception_index = (access_type == MMU_INST_FETCH ? EXCP_SUPERA_X : EXCP_SUPERA_D); env->ctrl[CR_BADADDR] = address; - cpu_loop_exit_restore(cs, retaddr); + nios2_cpu_loop_exit_advance(env, retaddr); } } @@ -367,5 +368,5 @@ bool nios2_cpu_tlb_fill(CPUState *cs, vaddr address, int size, cs->exception_index = excp; env->ctrl[CR_BADADDR] = address; - cpu_loop_exit_restore(cs, retaddr); + nios2_cpu_loop_exit_advance(env, retaddr); } |