|
@@ -1277,6 +1277,9 @@ static Property arm_cpu_cfgend_property =
|
|
|
static Property arm_cpu_has_vfp_property =
|
|
|
DEFINE_PROP_BOOL("vfp", ARMCPU, has_vfp, true);
|
|
|
|
|
|
+static Property arm_cpu_has_vfp_d32_property =
|
|
|
+ DEFINE_PROP_BOOL("vfp-d32", ARMCPU, has_vfp_d32, true);
|
|
|
+
|
|
|
static Property arm_cpu_has_neon_property =
|
|
|
DEFINE_PROP_BOOL("neon", ARMCPU, has_neon, true);
|
|
|
|
|
@@ -1408,6 +1411,22 @@ void arm_cpu_post_init(Object *obj)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ if (cpu->has_vfp && cpu_isar_feature(aa32_simd_r32, cpu)) {
|
|
|
+ cpu->has_vfp_d32 = true;
|
|
|
+ if (!kvm_enabled()) {
|
|
|
+ /*
|
|
|
+ * The permitted values of the SIMDReg bits [3:0] on
|
|
|
+ * Armv8-A are either 0b0000 and 0b0010. On such CPUs,
|
|
|
+ * make sure that has_vfp_d32 can not be set to false.
|
|
|
+ */
|
|
|
+ if (!(arm_feature(&cpu->env, ARM_FEATURE_V8) &&
|
|
|
+ !arm_feature(&cpu->env, ARM_FEATURE_M))) {
|
|
|
+ qdev_property_add_static(DEVICE(obj),
|
|
|
+ &arm_cpu_has_vfp_d32_property);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
if (arm_feature(&cpu->env, ARM_FEATURE_NEON)) {
|
|
|
cpu->has_neon = true;
|
|
|
if (!kvm_enabled()) {
|
|
@@ -1674,6 +1693,19 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
+ if (cpu->has_vfp_d32 != cpu->has_neon) {
|
|
|
+ error_setg(errp, "ARM CPUs must have both VFP-D32 and Neon or neither");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!cpu->has_vfp_d32) {
|
|
|
+ uint32_t u;
|
|
|
+
|
|
|
+ u = cpu->isar.mvfr0;
|
|
|
+ u = FIELD_DP32(u, MVFR0, SIMDREG, 1); /* 16 registers */
|
|
|
+ cpu->isar.mvfr0 = u;
|
|
|
+ }
|
|
|
+
|
|
|
if (!cpu->has_vfp) {
|
|
|
uint64_t t;
|
|
|
uint32_t u;
|