target/arm: Add FPCR.NEP to TBFLAGS
For FEAT_AFP, we want to emit different code when FPCR.NEP is set, so that instead of zeroing the high elements of a vector register when we write the output of a scalar operation to it, we instead merge in those elements from one of the source registers. Since this affects the generated code, we need to put FPCR.NEP into the TBFLAGS. FPCR.NEP is treated as 0 when in streaming SVE mode and FEAT_SME_FA64 is not implemented or not enabled; we can implement this logic in rebuild_hflags_a64(). Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
8a5a2b943e
commit
7025fa996f
@ -3214,6 +3214,7 @@ FIELD(TBFLAG_A64, NV2_MEM_E20, 35, 1)
|
|||||||
/* Set if FEAT_NV2 RAM accesses are big-endian */
|
/* Set if FEAT_NV2 RAM accesses are big-endian */
|
||||||
FIELD(TBFLAG_A64, NV2_MEM_BE, 36, 1)
|
FIELD(TBFLAG_A64, NV2_MEM_BE, 36, 1)
|
||||||
FIELD(TBFLAG_A64, AH, 37, 1) /* FPCR.AH */
|
FIELD(TBFLAG_A64, AH, 37, 1) /* FPCR.AH */
|
||||||
|
FIELD(TBFLAG_A64, NEP, 38, 1) /* FPCR.NEP */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Helpers for using the above. Note that only the A64 accessors use
|
* Helpers for using the above. Note that only the A64 accessors use
|
||||||
|
@ -407,6 +407,15 @@ static CPUARMTBFlags rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
|
|||||||
if (env->vfp.fpcr & FPCR_AH) {
|
if (env->vfp.fpcr & FPCR_AH) {
|
||||||
DP_TBFLAG_A64(flags, AH, 1);
|
DP_TBFLAG_A64(flags, AH, 1);
|
||||||
}
|
}
|
||||||
|
if (env->vfp.fpcr & FPCR_NEP) {
|
||||||
|
/*
|
||||||
|
* In streaming-SVE without FA64, NEP behaves as if zero;
|
||||||
|
* compare pseudocode IsMerging()
|
||||||
|
*/
|
||||||
|
if (!(EX_TBFLAG_A64(flags, PSTATE_SM) && !sme_fa64(env, el))) {
|
||||||
|
DP_TBFLAG_A64(flags, NEP, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return rebuild_hflags_common(env, fp_el, mmu_idx, flags);
|
return rebuild_hflags_common(env, fp_el, mmu_idx, flags);
|
||||||
}
|
}
|
||||||
|
@ -9742,6 +9742,7 @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
|
|||||||
dc->nv2_mem_e20 = EX_TBFLAG_A64(tb_flags, NV2_MEM_E20);
|
dc->nv2_mem_e20 = EX_TBFLAG_A64(tb_flags, NV2_MEM_E20);
|
||||||
dc->nv2_mem_be = EX_TBFLAG_A64(tb_flags, NV2_MEM_BE);
|
dc->nv2_mem_be = EX_TBFLAG_A64(tb_flags, NV2_MEM_BE);
|
||||||
dc->fpcr_ah = EX_TBFLAG_A64(tb_flags, AH);
|
dc->fpcr_ah = EX_TBFLAG_A64(tb_flags, AH);
|
||||||
|
dc->fpcr_nep = EX_TBFLAG_A64(tb_flags, NEP);
|
||||||
dc->vec_len = 0;
|
dc->vec_len = 0;
|
||||||
dc->vec_stride = 0;
|
dc->vec_stride = 0;
|
||||||
dc->cp_regs = arm_cpu->cp_regs;
|
dc->cp_regs = arm_cpu->cp_regs;
|
||||||
|
@ -157,6 +157,8 @@ typedef struct DisasContext {
|
|||||||
bool nv2_mem_be;
|
bool nv2_mem_be;
|
||||||
/* True if FPCR.AH is 1 (alternate floating point handling) */
|
/* True if FPCR.AH is 1 (alternate floating point handling) */
|
||||||
bool fpcr_ah;
|
bool fpcr_ah;
|
||||||
|
/* True if FPCR.NEP is 1 (FEAT_AFP scalar upper-element result handling) */
|
||||||
|
bool fpcr_nep;
|
||||||
/*
|
/*
|
||||||
* >= 0, a copy of PSTATE.BTYPE, which will be 0 without v8.5-BTI.
|
* >= 0, a copy of PSTATE.BTYPE, which will be 0 without v8.5-BTI.
|
||||||
* < 0, set by the current instruction.
|
* < 0, set by the current instruction.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user