@@ -82,6 +82,7 @@ enum {
R_FP = 28,
R_EA = 29,
R_BA = 30,
+ R_SSTATUS = 30,
R_RA = 31,
};
@@ -73,7 +73,7 @@ void helper_eret(CPUNios2State *env, uint32_t new_status, uint32_t new_pc)
}
/*
- * Both estatus and bstatus have no constraints on write;
+ * None of estatus, bstatus, or sstatus have constraints on write;
* do not allow reserved fields in status to be set.
*/
new_status &= (cpu->cr_state[CR_STATUS].writable |
@@ -81,6 +81,7 @@ void helper_eret(CPUNios2State *env, uint32_t new_status, uint32_t new_pc)
env->ctrl[CR_STATUS] = new_status;
env->pc = new_pc;
+ nios2_update_crs(env);
cpu_loop_exit(cs);
}
@@ -435,11 +435,14 @@ static void eret(DisasContext *dc, uint32_t code, uint32_t flags)
#ifdef CONFIG_USER_ONLY
g_assert_not_reached();
#else
- TCGv tmp = tcg_temp_new();
- tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPUNios2State, ctrl[CR_ESTATUS]));
- gen_helper_eret(cpu_env, tmp, load_gpr(dc, R_EA));
- tcg_temp_free(tmp);
-
+ if (dc->crs0) {
+ TCGv tmp = tcg_temp_new();
+ tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPUNios2State, ctrl[CR_ESTATUS]));
+ gen_helper_eret(cpu_env, tmp, load_gpr(dc, R_EA));
+ tcg_temp_free(tmp);
+ } else {
+ gen_helper_eret(cpu_env, load_gpr(dc, R_SSTATUS), load_gpr(dc, R_EA));
+ }
dc->base.is_jmp = DISAS_NORETURN;
#endif
}
When CRS = 0, we restore from estatus; otherwise from sstatus. Update for the new CRS. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- target/nios2/cpu.h | 1 + target/nios2/op_helper.c | 3 ++- target/nios2/translate.c | 13 ++++++++----- 3 files changed, 11 insertions(+), 6 deletions(-)