aboutsummaryrefslogtreecommitdiff
path: root/target/nios2/op_helper.c
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2022-04-21 08:17:28 -0700
committerRichard Henderson <richard.henderson@linaro.org>2022-04-26 08:17:05 -0700
commite84f1768449330a5b4c62a8aaa68f102ba6ec573 (patch)
treeaf6ca0b49c5612a35ac77da507974dba9ee71713 /target/nios2/op_helper.c
parenta25c4eff32ba6192cff648ccaf0316bd829c80af (diff)
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/op_helper.c')
-rw-r--r--target/nios2/op_helper.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/target/nios2/op_helper.c b/target/nios2/op_helper.c
index 94040102f4..2e30d0a908 100644
--- a/target/nios2/op_helper.c
+++ b/target/nios2/op_helper.c
@@ -31,6 +31,20 @@ void helper_raise_exception(CPUNios2State *env, uint32_t index)
cpu_loop_exit(cs);
}
+void nios2_cpu_loop_exit_advance(CPUNios2State *env, uintptr_t retaddr)
+{
+ CPUState *cs = env_cpu(env);
+
+ /*
+ * Note that PC is advanced for all hardware exceptions.
+ * Do this here, rather than in restore_state_to_opc(),
+ * lest we affect QEMU internal exceptions, like EXCP_DEBUG.
+ */
+ cpu_restore_state(cs, retaddr, true);
+ env->pc += 4;
+ cpu_loop_exit(cs);
+}
+
static void maybe_raise_div(CPUNios2State *env, uintptr_t ra)
{
Nios2CPU *cpu = env_archcpu(env);
@@ -38,7 +52,7 @@ static void maybe_raise_div(CPUNios2State *env, uintptr_t ra)
if (cpu->diverr_present) {
cs->exception_index = EXCP_DIV;
- cpu_loop_exit_restore(cs, ra);
+ nios2_cpu_loop_exit_advance(env, ra);
}
}
@@ -69,7 +83,7 @@ void helper_eret(CPUNios2State *env, uint32_t new_status, uint32_t new_pc)
if (unlikely(new_pc & 3)) {
env->ctrl[CR_BADADDR] = new_pc;
cs->exception_index = EXCP_UNALIGND;
- cpu_loop_exit_restore(cs, GETPC());
+ nios2_cpu_loop_exit_advance(env, GETPC());
}
/*