mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-03-24 22:15:07 +00:00
target-arm: UNDEF in the UNPREDICTABLE SRS-from-System case
Make get_r13_banked() raise an exception at runtime for the corner case of SRS from System mode, so that we can UNDEF it; this brings us in to line with the ARM ARM's set of permitted CONSTRAINED UNPREDICTABLE choices. Backports commit f01377f591fe15c652f947646c4a69a7d4a71ad9 from qemu
This commit is contained in:
parent
88d21504e4
commit
57a9474cc7
|
@ -468,6 +468,14 @@ void HELPER(set_r13_banked)(CPUARMState *env, uint32_t mode, uint32_t val)
|
||||||
|
|
||||||
uint32_t HELPER(get_r13_banked)(CPUARMState *env, uint32_t mode)
|
uint32_t HELPER(get_r13_banked)(CPUARMState *env, uint32_t mode)
|
||||||
{
|
{
|
||||||
|
if ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_SYS) {
|
||||||
|
/* SRS instruction is UNPREDICTABLE from System mode; we UNDEF.
|
||||||
|
* Other UNPREDICTABLE and UNDEF cases were caught at translate time.
|
||||||
|
*/
|
||||||
|
raise_exception(env, EXCP_UDEF, syn_uncategorized(),
|
||||||
|
exception_target_el(env));
|
||||||
|
}
|
||||||
|
|
||||||
if ((env->uncached_cpsr & CPSR_M) == mode) {
|
if ((env->uncached_cpsr & CPSR_M) == mode) {
|
||||||
return env->regs[13];
|
return env->regs[13];
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -7720,10 +7720,7 @@ static void gen_srs(DisasContext *s,
|
||||||
* -- not a valid mode number
|
* -- not a valid mode number
|
||||||
* -- a mode that's at a higher exception level
|
* -- a mode that's at a higher exception level
|
||||||
* -- Monitor, if we are Non-secure
|
* -- Monitor, if we are Non-secure
|
||||||
* For the UNPREDICTABLE cases we choose to UNDEF, except that for
|
* For the UNPREDICTABLE cases we choose to UNDEF.
|
||||||
* "current mode is System" we will write a garbage SPSR.
|
|
||||||
* (This is because we don't have access to our current mode here
|
|
||||||
* and would have to do a runtime check to UNDEF for System.)
|
|
||||||
*/
|
*/
|
||||||
if (s->current_el == 1 && !s->ns) {
|
if (s->current_el == 1 && !s->ns) {
|
||||||
gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), 3);
|
gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), 3);
|
||||||
|
@ -7769,6 +7766,9 @@ static void gen_srs(DisasContext *s,
|
||||||
|
|
||||||
addr = tcg_temp_new_i32(tcg_ctx);
|
addr = tcg_temp_new_i32(tcg_ctx);
|
||||||
tmp = tcg_const_i32(tcg_ctx, mode);
|
tmp = tcg_const_i32(tcg_ctx, mode);
|
||||||
|
/* get_r13_banked() will raise an exception if called from System mode */
|
||||||
|
gen_set_condexec(s);
|
||||||
|
gen_set_pc_im(s, s->pc - 4);
|
||||||
gen_helper_get_r13_banked(tcg_ctx, addr, tcg_ctx->cpu_env, tmp);
|
gen_helper_get_r13_banked(tcg_ctx, addr, tcg_ctx->cpu_env, tmp);
|
||||||
tcg_temp_free_i32(tcg_ctx, tmp);
|
tcg_temp_free_i32(tcg_ctx, tmp);
|
||||||
switch (amode) {
|
switch (amode) {
|
||||||
|
@ -7818,6 +7818,7 @@ static void gen_srs(DisasContext *s,
|
||||||
tcg_temp_free_i32(tcg_ctx, tmp);
|
tcg_temp_free_i32(tcg_ctx, tmp);
|
||||||
}
|
}
|
||||||
tcg_temp_free_i32(tcg_ctx, addr);
|
tcg_temp_free_i32(tcg_ctx, addr);
|
||||||
|
s->is_jmp = DISAS_UPDATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void disas_arm_insn(DisasContext *s, unsigned int insn) // qq
|
static void disas_arm_insn(DisasContext *s, unsigned int insn) // qq
|
||||||
|
|
Loading…
Reference in a new issue