target/arm: Factor FP context update code out into helper function
Factor the code in full_vfp_access_check() which updates the ownership of the FP context and creates a new FP context out into its own function. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20210618141019.10671-6-peter.maydell@linaro.org
This commit is contained in:
parent
e494cd0a1a
commit
95aceeeac9
|
@ -132,47 +132,13 @@ void gen_preserve_fp_state(DisasContext *s)
|
|||
}
|
||||
|
||||
/*
|
||||
* Check that VFP access is enabled. If it is, do the necessary
|
||||
* M-profile lazy-FP handling and then return true.
|
||||
* If not, emit code to generate an appropriate exception and
|
||||
* return false.
|
||||
* The ignore_vfp_enabled argument specifies that we should ignore
|
||||
* whether VFP is enabled via FPEXC[EN]: this should be true for FMXR/FMRX
|
||||
* accesses to FPSID, FPEXC, MVFR0, MVFR1, MVFR2, and false for all other insns.
|
||||
* Generate code for M-profile FP context handling: update the
|
||||
* ownership of the FP context, and create a new context if
|
||||
* necessary. This corresponds to the parts of the pseudocode
|
||||
* ExecuteFPCheck() after the inital PreserveFPState() call.
|
||||
*/
|
||||
static bool full_vfp_access_check(DisasContext *s, bool ignore_vfp_enabled)
|
||||
static void gen_update_fp_context(DisasContext *s)
|
||||
{
|
||||
if (s->fp_excp_el) {
|
||||
if (arm_dc_feature(s, ARM_FEATURE_M)) {
|
||||
/*
|
||||
* M-profile mostly catches the "FPU disabled" case early, in
|
||||
* disas_m_nocp(), but a few insns (eg LCTP, WLSTP, DLSTP)
|
||||
* which do coprocessor-checks are outside the large ranges of
|
||||
* the encoding space handled by the patterns in m-nocp.decode,
|
||||
* and for them we may need to raise NOCP here.
|
||||
*/
|
||||
gen_exception_insn(s, s->pc_curr, EXCP_NOCP,
|
||||
syn_uncategorized(), s->fp_excp_el);
|
||||
} else {
|
||||
gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
|
||||
syn_fp_access_trap(1, 0xe, false),
|
||||
s->fp_excp_el);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!s->vfp_enabled && !ignore_vfp_enabled) {
|
||||
assert(!arm_dc_feature(s, ARM_FEATURE_M));
|
||||
unallocated_encoding(s);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (arm_dc_feature(s, ARM_FEATURE_M)) {
|
||||
/* Handle M-profile lazy FP state mechanics */
|
||||
|
||||
/* Trigger lazy-state preservation if necessary */
|
||||
gen_preserve_fp_state(s);
|
||||
|
||||
/* Update ownership of FP context: set FPCCR.S to match current state */
|
||||
if (s->v8m_fpccr_s_wrong) {
|
||||
TCGv_i32 tmp;
|
||||
|
@ -219,6 +185,52 @@ static bool full_vfp_access_check(DisasContext *s, bool ignore_vfp_enabled)
|
|||
/* Don't need to do this for any further FP insns in this TB */
|
||||
s->v7m_new_fp_ctxt_needed = false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that VFP access is enabled. If it is, do the necessary
|
||||
* M-profile lazy-FP handling and then return true.
|
||||
* If not, emit code to generate an appropriate exception and
|
||||
* return false.
|
||||
* The ignore_vfp_enabled argument specifies that we should ignore
|
||||
* whether VFP is enabled via FPEXC[EN]: this should be true for FMXR/FMRX
|
||||
* accesses to FPSID, FPEXC, MVFR0, MVFR1, MVFR2, and false for all other insns.
|
||||
*/
|
||||
static bool full_vfp_access_check(DisasContext *s, bool ignore_vfp_enabled)
|
||||
{
|
||||
if (s->fp_excp_el) {
|
||||
if (arm_dc_feature(s, ARM_FEATURE_M)) {
|
||||
/*
|
||||
* M-profile mostly catches the "FPU disabled" case early, in
|
||||
* disas_m_nocp(), but a few insns (eg LCTP, WLSTP, DLSTP)
|
||||
* which do coprocessor-checks are outside the large ranges of
|
||||
* the encoding space handled by the patterns in m-nocp.decode,
|
||||
* and for them we may need to raise NOCP here.
|
||||
*/
|
||||
gen_exception_insn(s, s->pc_curr, EXCP_NOCP,
|
||||
syn_uncategorized(), s->fp_excp_el);
|
||||
} else {
|
||||
gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
|
||||
syn_fp_access_trap(1, 0xe, false),
|
||||
s->fp_excp_el);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!s->vfp_enabled && !ignore_vfp_enabled) {
|
||||
assert(!arm_dc_feature(s, ARM_FEATURE_M));
|
||||
unallocated_encoding(s);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (arm_dc_feature(s, ARM_FEATURE_M)) {
|
||||
/* Handle M-profile lazy FP state mechanics */
|
||||
|
||||
/* Trigger lazy-state preservation if necessary */
|
||||
gen_preserve_fp_state(s);
|
||||
|
||||
/* Update ownership of FP context and create new FP context if needed */
|
||||
gen_update_fp_context(s);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
Loading…
Reference in a new issue