@@ -3214,6 +3214,7 @@ FIELD(TBFLAG_A64, NV2_MEM_E20, 35, 1)
/* Set if FEAT_NV2 RAM accesses are big-endian */
FIELD(TBFLAG_A64, NV2_MEM_BE, 36, 1)
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
@@ -157,6 +157,8 @@ typedef struct DisasContext {
bool nv2_mem_be;
/* True if FPCR.AH is 1 (alternate floating point handling) */
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, set by the current instruction.
@@ -407,6 +407,15 @@ static CPUARMTBFlags rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
if (env->vfp.fpcr & FPCR_AH) {
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);
}
@@ -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_be = EX_TBFLAG_A64(tb_flags, NV2_MEM_BE);
dc->fpcr_ah = EX_TBFLAG_A64(tb_flags, AH);
+ dc->fpcr_nep = EX_TBFLAG_A64(tb_flags, NEP);
dc->vec_len = 0;
dc->vec_stride = 0;
dc->cp_regs = arm_cpu->cp_regs;