mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2024-12-23 10:45:28 +00:00
target/arm: Rearrange {sve,fp}_check_access assert
We want to ensure that access is checked by the time we ask for a specific fp/vector register. We want to ensure that we do not emit two lots of code to raise an exception. But sometimes it's difficult to cleanly organize the code such that we never pass through sve_check_access exactly once. Allow multiple calls so long as the result is true, that is, no exception to be raised. Backports 8a40fe5f1bf3837ae3f9961efe1d51e7214f2664
This commit is contained in:
parent
64822511dd
commit
f329d428f3
|
@ -1347,28 +1347,33 @@ static void do_vec_ld(DisasContext *s, int destidx, int element,
|
|||
*/
|
||||
static inline bool fp_access_check(DisasContext *s)
|
||||
{
|
||||
if (s->fp_excp_el) {
|
||||
assert(!s->fp_access_checked);
|
||||
s->fp_access_checked = true;
|
||||
|
||||
if (!s->fp_excp_el) {
|
||||
return true;
|
||||
}
|
||||
|
||||
gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
|
||||
syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
|
||||
return false;
|
||||
}
|
||||
|
||||
s->fp_access_checked = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Check that SVE access is enabled. If it is, return true.
|
||||
* If not, emit code to generate an appropriate exception and return false.
|
||||
*/
|
||||
bool sve_access_check(DisasContext *s)
|
||||
{
|
||||
if (s->sve_excp_el) {
|
||||
gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_sve_access_trap(),
|
||||
s->sve_excp_el);
|
||||
assert(!s->sve_access_checked);
|
||||
s->sve_access_checked = true;
|
||||
|
||||
gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
|
||||
syn_sve_access_trap(), s->sve_excp_el);
|
||||
return false;
|
||||
}
|
||||
s->sve_access_checked = true;
|
||||
return fp_access_check(s);
|
||||
}
|
||||
|
||||
|
@ -14858,6 +14863,7 @@ static void disas_a64_insn(CPUARMState *env, DisasContext *s)
|
|||
}
|
||||
|
||||
s->fp_access_checked = false;
|
||||
s->sve_access_checked = false;
|
||||
|
||||
if (dc_isar_feature(aa64_bti, s)) {
|
||||
if (s->base.num_insns == 1) {
|
||||
|
|
|
@ -63,6 +63,7 @@ typedef struct DisasContext {
|
|||
* that it is set at the point where we actually touch the FP regs.
|
||||
*/
|
||||
bool fp_access_checked;
|
||||
bool sve_access_checked;
|
||||
/* ARMv8 single-step state (this is distinct from the QEMU gdbstub
|
||||
* single-step support).
|
||||
*/
|
||||
|
|
Loading…
Reference in a new issue