diff --git a/qemu/target/arm/cpu.c b/qemu/target/arm/cpu.c index 6fe0943a..995d8247 100644 --- a/qemu/target/arm/cpu.c +++ b/qemu/target/arm/cpu.c @@ -283,7 +283,7 @@ static void arm_cpu_reset(CPUState *s) env->v7m.ccr[M_REG_S] |= R_V7M_CCR_UNALIGN_TRP_MASK; } - if (arm_feature(env, ARM_FEATURE_VFP)) { + if (cpu_isar_feature(aa32_vfp_simd, cpu)) { env->v7m.fpccr[M_REG_NS] = R_V7M_FPCCR_ASPEN_MASK; env->v7m.fpccr[M_REG_S] = R_V7M_FPCCR_ASPEN_MASK | R_V7M_FPCCR_LSPEN_MASK | R_V7M_FPCCR_S_MASK; diff --git a/qemu/target/arm/cpu.h b/qemu/target/arm/cpu.h index 9a066b59..4a551372 100644 --- a/qemu/target/arm/cpu.h +++ b/qemu/target/arm/cpu.h @@ -3323,6 +3323,15 @@ static inline bool isar_feature_aa32_fp16_arith(const ARMISARegisters *id) return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, FP) == 1; } +static inline bool isar_feature_aa32_vfp_simd(const ARMISARegisters *id) +{ + /* + * Return true if either VFP or SIMD is implemented. + * In this case, a minimum of VFP w/ D0-D15. + */ + return FIELD_EX32(id->mvfr0, MVFR0, SIMDREG) > 0; +} + static inline bool isar_feature_aa32_simd_r32(const ARMISARegisters *id) { /* Return true if D16-D31 are implemented */ diff --git a/qemu/target/arm/helper.c b/qemu/target/arm/helper.c index c61e31b0..373a9424 100644 --- a/qemu/target/arm/helper.c +++ b/qemu/target/arm/helper.c @@ -748,7 +748,7 @@ static void cpacr_write(CPUARMState *env, const ARMCPRegInfo *ri, * ASEDIS [31] and D32DIS [30] are both UNK/SBZP without VFP. * TRCDIS [28] is RAZ/WI since we do not implement a trace macrocell. */ - if (arm_feature(env, ARM_FEATURE_VFP)) { + if (cpu_isar_feature(aa32_vfp_simd, env_archcpu(env))) { /* VFP coprocessor: cp10 & cp11 [23:20] */ mask |= (1 << 31) | (1 << 30) | (0xf << 20); diff --git a/qemu/target/arm/m_helper.c b/qemu/target/arm/m_helper.c index 4340e317..763267fb 100644 --- a/qemu/target/arm/m_helper.c +++ b/qemu/target/arm/m_helper.c @@ -662,7 +662,8 @@ static uint32_t v7m_integrity_sig(CPUARMState *env, uint32_t lr) */ uint32_t sig = 0xfefa125a; - if (!arm_feature(env, ARM_FEATURE_VFP) || (lr & R_V7M_EXCRET_FTYPE_MASK)) { + if (!cpu_isar_feature(aa32_vfp_simd, env_archcpu(env)) + || (lr & R_V7M_EXCRET_FTYPE_MASK)) { sig |= 1; } return sig; @@ -764,7 +765,7 @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain, if (dotailchain) { /* Sanitize LR FType and PREFIX bits */ - if (!arm_feature(env, ARM_FEATURE_VFP)) { + if (!cpu_isar_feature(aa32_vfp_simd, cpu)) { lr |= R_V7M_EXCRET_FTYPE_MASK; } lr = deposit32(lr, 24, 8, 0xff); @@ -1296,7 +1297,7 @@ static void do_v7m_exception_exit(ARMCPU *cpu) ftype = excret & R_V7M_EXCRET_FTYPE_MASK; - if (!arm_feature(env, ARM_FEATURE_VFP) && !ftype) { + if (!ftype && !cpu_isar_feature(aa32_vfp_simd, cpu)) { qemu_log_mask(LOG_GUEST_ERROR, "M profile: zero FTYPE in exception " "exit PC value 0x%" PRIx32 " is UNPREDICTABLE " "if FPU not present\n",