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
This commit is contained in:
parent
b722636972
commit
532a3af5fb
@ -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;
|
||||
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;
|
||||
u = cpu->isar.mvfr2;
|
||||
u = FIELD_DP32(u, MVFR2, SIMDMISC, 0);
|
||||
cpu->isar.mvfr2 = u;
|
||||
}
|
||||
}
|
||||
|
||||
if (!cpu->has_neon && !cpu->has_vfp) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user