diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h index 30302d6c5b..7bf24c506b 100644 --- a/target/arm/cpu-features.h +++ b/target/arm/cpu-features.h @@ -802,6 +802,11 @@ static inline bool isar_feature_aa64_hcx(const ARMISARegisters *id) return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, HCX) != 0; } +static inline bool isar_feature_aa64_afp(const ARMISARegisters *id) +{ + return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, AFP) != 0; +} + static inline bool isar_feature_aa64_tidcp1(const ARMISARegisters *id) { return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, TIDCP1) != 0; diff --git a/target/arm/cpu.h b/target/arm/cpu.h index c2d2d99b46..1c91b1f50f 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -1714,6 +1714,9 @@ void vfp_set_fpscr(CPUARMState *env, uint32_t val); */ /* FPCR bits */ +#define FPCR_FIZ (1 << 0) /* Flush Inputs to Zero (FEAT_AFP) */ +#define FPCR_AH (1 << 1) /* Alternate Handling (FEAT_AFP) */ +#define FPCR_NEP (1 << 2) /* SIMD scalar ops preserve elts (FEAT_AFP) */ #define FPCR_IOE (1 << 8) /* Invalid Operation exception trap enable */ #define FPCR_DZE (1 << 9) /* Divide by Zero exception trap enable */ #define FPCR_OFE (1 << 10) /* Overflow exception trap enable */ diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c index 3c8f3e6588..8c79ab4fc8 100644 --- a/target/arm/vfp_helper.c +++ b/target/arm/vfp_helper.c @@ -242,6 +242,9 @@ static void vfp_set_fpcr_masked(CPUARMState *env, uint32_t val, uint32_t mask) if (!cpu_isar_feature(any_fp16, cpu)) { val &= ~FPCR_FZ16; } + if (!cpu_isar_feature(aa64_afp, cpu)) { + val &= ~(FPCR_FIZ | FPCR_AH | FPCR_NEP); + } if (!cpu_isar_feature(aa64_ebf16, cpu)) { val &= ~FPCR_EBF; @@ -271,12 +274,14 @@ static void vfp_set_fpcr_masked(CPUARMState *env, uint32_t val, uint32_t mask) * We don't implement trapped exception handling, so the * trap enable bits, IDE|IXE|UFE|OFE|DZE|IOE are all RAZ/WI (not RES0!) * - * The FPCR bits we keep in vfp.fpcr are AHP, DN, FZ, RMode, EBF - * and FZ16. Len, Stride and LTPSIZE we just handled. Store those bits + * The FPCR bits we keep in vfp.fpcr are AHP, DN, FZ, RMode, EBF, FZ16, + * FIZ, AH, and NEP. + * Len, Stride and LTPSIZE we just handled. Store those bits * there, and zero any of the other FPCR bits and the RES0 and RAZ/WI * bits. */ - val &= FPCR_AHP | FPCR_DN | FPCR_FZ | FPCR_RMODE_MASK | FPCR_FZ16 | FPCR_EBF; + val &= FPCR_AHP | FPCR_DN | FPCR_FZ | FPCR_RMODE_MASK | FPCR_FZ16 | + FPCR_EBF | FPCR_FIZ | FPCR_AH | FPCR_NEP; env->vfp.fpcr &= ~mask; env->vfp.fpcr |= val; }