target/nios2: Update helper_eret for shadow registers
When CRS = 0, we restore from estatus; otherwise from sstatus. Update for the new CRS. Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20220421151735.31996-56-richard.henderson@linaro.org>
This commit is contained in:
parent
3a03087019
commit
6bcc59cafa
|
@ -82,6 +82,7 @@ enum {
|
||||||
R_FP = 28,
|
R_FP = 28,
|
||||||
R_EA = 29,
|
R_EA = 29,
|
||||||
R_BA = 30,
|
R_BA = 30,
|
||||||
|
R_SSTATUS = 30,
|
||||||
R_RA = 31,
|
R_RA = 31,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -73,14 +73,18 @@ 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.
|
* do not allow reserved fields in status to be set.
|
||||||
* TODO: more than this is required for shadow registers.
|
* When shadow registers are enabled, eret *does* restore CRS.
|
||||||
|
* Rather than testing eic_present to decide, mask CRS out of
|
||||||
|
* the set of readonly fields.
|
||||||
*/
|
*/
|
||||||
new_status &= cpu->cr_state[CR_STATUS].writable;
|
new_status &= cpu->cr_state[CR_STATUS].writable |
|
||||||
|
(cpu->cr_state[CR_STATUS].readonly & R_CR_STATUS_CRS_MASK);
|
||||||
|
|
||||||
env->ctrl[CR_STATUS] = new_status;
|
env->ctrl[CR_STATUS] = new_status;
|
||||||
env->pc = new_pc;
|
env->pc = new_pc;
|
||||||
|
nios2_update_crs(env);
|
||||||
cpu_loop_exit(cs);
|
cpu_loop_exit(cs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -496,11 +496,14 @@ static void eret(DisasContext *dc, uint32_t code, uint32_t flags)
|
||||||
#ifdef CONFIG_USER_ONLY
|
#ifdef CONFIG_USER_ONLY
|
||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
#else
|
#else
|
||||||
TCGv tmp = tcg_temp_new();
|
if (FIELD_EX32(dc->tb_flags, TBFLAGS, CRS0)) {
|
||||||
tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPUNios2State, ctrl[CR_ESTATUS]));
|
TCGv tmp = tcg_temp_new();
|
||||||
gen_helper_eret(cpu_env, tmp, load_gpr(dc, R_EA));
|
tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPUNios2State, ctrl[CR_ESTATUS]));
|
||||||
tcg_temp_free(tmp);
|
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;
|
dc->base.is_jmp = DISAS_NORETURN;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue