aboutsummaryrefslogtreecommitdiff
path: root/target/arm/cpu.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2020-10-19 16:12:59 +0100
committerPeter Maydell <peter.maydell@linaro.org>2020-10-20 16:12:01 +0100
commit532a3af5fbd348bca371b4a56b45f8f97c7c5519 (patch)
treed4dd8f99b461632a132129d2e7a9ff8109aa21b3 /target/arm/cpu.c
parentb7226369721896ab9ef71544e4fe95b40710e05a (diff)
target/arm: Fix has_vfp/has_neon ID reg squashing for M-profile
In arm_cpu_realizefn(), if the CPU has VFP or Neon disabled then we squash the ID register fields so that we don't advertise it to the guest. This code was written for A-profile and needs some tweaks to work correctly on M-profile: * A-profile only fields should not be zeroed on M-profile: - MVFR0.FPSHVEC,FPTRAP - MVFR1.SIMDLS,SIMDINT,SIMDSP,SIMDHP - MVFR2.SIMDMISC * M-profile only fields should be zeroed on M-profile: - MVFR1.FP16 In particular, because MVFR1.SIMDHP on A-profile is the same field as MVFR1.FP16 on M-profile this code was incorrectly disabling FP16 support on an M-profile CPU (where has_neon is always false). This isn't a visible bug yet because we don't have any M-profile CPUs with FP16 support, but the change is necessary before we introduce any. Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Message-id: 20201019151301.2046-9-peter.maydell@linaro.org
Diffstat (limited to 'target/arm/cpu.c')
-rw-r--r--target/arm/cpu.c31
1 files changed, 19 insertions, 12 deletions
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 056319859f..186ee621a6 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1429,17 +1429,22 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
u = cpu->isar.mvfr0;
u = FIELD_DP32(u, MVFR0, FPSP, 0);
u = FIELD_DP32(u, MVFR0, FPDP, 0);
- u = FIELD_DP32(u, MVFR0, FPTRAP, 0);
u = FIELD_DP32(u, MVFR0, FPDIVIDE, 0);
u = FIELD_DP32(u, MVFR0, FPSQRT, 0);
- u = FIELD_DP32(u, MVFR0, FPSHVEC, 0);
u = FIELD_DP32(u, MVFR0, FPROUND, 0);
+ if (!arm_feature(env, ARM_FEATURE_M)) {
+ u = FIELD_DP32(u, MVFR0, FPTRAP, 0);
+ u = FIELD_DP32(u, MVFR0, FPSHVEC, 0);
+ }
cpu->isar.mvfr0 = u;
u = cpu->isar.mvfr1;
u = FIELD_DP32(u, MVFR1, FPFTZ, 0);
u = FIELD_DP32(u, MVFR1, FPDNAN, 0);
u = FIELD_DP32(u, MVFR1, FPHP, 0);
+ if (arm_feature(env, ARM_FEATURE_M)) {
+ u = FIELD_DP32(u, MVFR1, FP16, 0);
+ }
cpu->isar.mvfr1 = u;
u = cpu->isar.mvfr2;
@@ -1475,16 +1480,18 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
u = FIELD_DP32(u, ID_ISAR6, FHM, 0);
cpu->isar.id_isar6 = u;
- u = cpu->isar.mvfr1;
- u = FIELD_DP32(u, MVFR1, SIMDLS, 0);
- u = FIELD_DP32(u, MVFR1, SIMDINT, 0);
- u = FIELD_DP32(u, MVFR1, SIMDSP, 0);
- u = FIELD_DP32(u, MVFR1, SIMDHP, 0);
- cpu->isar.mvfr1 = u;
-
- u = cpu->isar.mvfr2;
- u = FIELD_DP32(u, MVFR2, SIMDMISC, 0);
- cpu->isar.mvfr2 = u;
+ if (!arm_feature(env, ARM_FEATURE_M)) {
+ u = cpu->isar.mvfr1;
+ u = FIELD_DP32(u, MVFR1, SIMDLS, 0);
+ u = FIELD_DP32(u, MVFR1, SIMDINT, 0);
+ u = FIELD_DP32(u, MVFR1, SIMDSP, 0);
+ u = FIELD_DP32(u, MVFR1, SIMDHP, 0);
+ cpu->isar.mvfr1 = u;
+
+ u = cpu->isar.mvfr2;
+ u = FIELD_DP32(u, MVFR2, SIMDMISC, 0);
+ cpu->isar.mvfr2 = u;
+ }
}
if (!cpu->has_neon && !cpu->has_vfp) {