summaryrefslogtreecommitdiffstats
path: root/target/arm/cpu.h
diff options
context:
space:
mode:
Diffstat (limited to 'target/arm/cpu.h')
-rw-r--r--target/arm/cpu.h88
1 files changed, 80 insertions, 8 deletions
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 65171cb30e..0b84742b66 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -904,7 +904,7 @@ struct ARMCPU {
/* The elements of this array are the CCSIDR values for each cache,
* in the order L1DCache, L1ICache, L2DCache, L2ICache, etc.
*/
- uint32_t ccsidr[16];
+ uint64_t ccsidr[16];
uint64_t reset_cbar;
uint32_t reset_auxcr;
bool reset_hivecs;
@@ -1880,7 +1880,6 @@ QEMU_BUILD_BUG_ON(ARRAY_SIZE(((ARMCPU *)0)->ccsidr) <= R_V7M_CSSELR_INDEX_MASK);
* mapping in linux-user/elfload.c:get_elf_hwcap().
*/
enum arm_features {
- ARM_FEATURE_VFP,
ARM_FEATURE_AUXCR, /* ARM1026 Auxiliary control register. */
ARM_FEATURE_XSCALE, /* Intel XScale extensions. */
ARM_FEATURE_IWMMXT, /* Intel iwMMXt extension. */
@@ -1889,7 +1888,6 @@ enum arm_features {
ARM_FEATURE_V7,
ARM_FEATURE_THUMB2,
ARM_FEATURE_PMSA, /* no MMU; may have Memory Protection Unit */
- ARM_FEATURE_VFP3,
ARM_FEATURE_NEON,
ARM_FEATURE_M, /* Microcontroller profile. */
ARM_FEATURE_OMAPCP, /* OMAP specific CP15 ops handling. */
@@ -1900,7 +1898,6 @@ enum arm_features {
ARM_FEATURE_V5,
ARM_FEATURE_STRONGARM,
ARM_FEATURE_VAPA, /* cp15 VA to PA lookups */
- ARM_FEATURE_VFP4, /* VFPv4 (implies that NEON is v2) */
ARM_FEATURE_GENERIC_TIMER,
ARM_FEATURE_MVFR, /* Media and VFP Feature Registers 0 and 1 */
ARM_FEATURE_DUMMY_C15_REGS, /* RAZ/WI all of cp15 crn=15 */
@@ -3450,6 +3447,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 */
@@ -3461,12 +3467,35 @@ static inline bool isar_feature_aa32_fpshvec(const ARMISARegisters *id)
return FIELD_EX32(id->mvfr0, MVFR0, FPSHVEC) > 0;
}
-static inline bool isar_feature_aa32_fpdp(const ARMISARegisters *id)
+static inline bool isar_feature_aa32_fpsp_v2(const ARMISARegisters *id)
+{
+ /* Return true if CPU supports single precision floating point, VFPv2 */
+ return FIELD_EX32(id->mvfr0, MVFR0, FPSP) > 0;
+}
+
+static inline bool isar_feature_aa32_fpsp_v3(const ARMISARegisters *id)
+{
+ /* Return true if CPU supports single precision floating point, VFPv3 */
+ return FIELD_EX32(id->mvfr0, MVFR0, FPSP) >= 2;
+}
+
+static inline bool isar_feature_aa32_fpdp_v2(const ARMISARegisters *id)
{
- /* Return true if CPU supports double precision floating point */
+ /* Return true if CPU supports double precision floating point, VFPv2 */
return FIELD_EX32(id->mvfr0, MVFR0, FPDP) > 0;
}
+static inline bool isar_feature_aa32_fpdp_v3(const ARMISARegisters *id)
+{
+ /* Return true if CPU supports double precision floating point, VFPv3 */
+ return FIELD_EX32(id->mvfr0, MVFR0, FPDP) >= 2;
+}
+
+static inline bool isar_feature_aa32_vfp(const ARMISARegisters *id)
+{
+ return isar_feature_aa32_fpsp_v2(id) || isar_feature_aa32_fpdp_v2(id);
+}
+
/*
* We always set the FP and SIMD FP16 fields to indicate identical
* levels of support (assuming SIMD is implemented at all), so
@@ -3482,6 +3511,18 @@ static inline bool isar_feature_aa32_fp16_dpconv(const ARMISARegisters *id)
return FIELD_EX32(id->mvfr1, MVFR1, FPHP) > 1;
}
+/*
+ * Note that this ID register field covers both VFP and Neon FMAC,
+ * so should usually be tested in combination with some other
+ * check that confirms the presence of whichever of VFP or Neon is
+ * relevant, to avoid accidentally enabling a Neon feature on
+ * a VFP-no-Neon core or vice-versa.
+ */
+static inline bool isar_feature_aa32_simdfmac(const ARMISARegisters *id)
+{
+ return FIELD_EX32(id->mvfr1, MVFR1, SIMDFMAC) != 0;
+}
+
static inline bool isar_feature_aa32_vsel(const ARMISARegisters *id)
{
return FIELD_EX32(id->mvfr2, MVFR2, FPMISC) >= 1;
@@ -3536,6 +3577,11 @@ static inline bool isar_feature_aa32_ac2(const ARMISARegisters *id)
return FIELD_EX32(id->id_mmfr4, ID_MMFR4, AC2) != 0;
}
+static inline bool isar_feature_aa32_ccidx(const ARMISARegisters *id)
+{
+ return FIELD_EX32(id->id_mmfr4, ID_MMFR4, CCIDX) != 0;
+}
+
/*
* 64-bit feature tests via id registers.
*/
@@ -3669,6 +3715,12 @@ static inline bool isar_feature_aa64_dcpodp(const ARMISARegisters *id)
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, DPB) >= 2;
}
+static inline bool isar_feature_aa64_fp_simd(const ARMISARegisters *id)
+{
+ /* We always set the AdvSIMD and FP fields identically. */
+ return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, FP) != 0xf;
+}
+
static inline bool isar_feature_aa64_fp16(const ARMISARegisters *id)
{
/* We always set the AdvSIMD and FP fields identically wrt FP16. */
@@ -3723,8 +3775,23 @@ static inline bool isar_feature_aa64_pmu_8_1(const ARMISARegisters *id)
static inline bool isar_feature_aa64_pmu_8_4(const ARMISARegisters *id)
{
- return FIELD_EX32(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) >= 5 &&
- FIELD_EX32(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf;
+ return FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) >= 5 &&
+ FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf;
+}
+
+static inline bool isar_feature_aa64_rcpc_8_3(const ARMISARegisters *id)
+{
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, LRCPC) != 0;
+}
+
+static inline bool isar_feature_aa64_rcpc_8_4(const ARMISARegisters *id)
+{
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, LRCPC) >= 2;
+}
+
+static inline bool isar_feature_aa64_ccidx(const ARMISARegisters *id)
+{
+ return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, CCIDX) != 0;
}
/*
@@ -3750,6 +3817,11 @@ static inline bool isar_feature_any_pmu_8_4(const ARMISARegisters *id)
return isar_feature_aa64_pmu_8_4(id) || isar_feature_aa32_pmu_8_4(id);
}
+static inline bool isar_feature_any_ccidx(const ARMISARegisters *id)
+{
+ return isar_feature_aa64_ccidx(id) || isar_feature_aa32_ccidx(id);
+}
+
/*
* Forward to the above feature tests given an ARMCPU pointer.
*/