+ /* Statistical Profiling extension. */
+ if ((reg->value == CPENC (3, 0, C9, C10, 0)
+ || reg->value == CPENC (3, 0, C9, C10, 1)
+ || reg->value == CPENC (3, 0, C9, C10, 3)
+ || reg->value == CPENC (3, 0, C9, C10, 7)
+ || reg->value == CPENC (3, 0, C9, C9, 0)
+ || reg->value == CPENC (3, 0, C9, C9, 2)
+ || reg->value == CPENC (3, 0, C9, C9, 3)
+ || reg->value == CPENC (3, 0, C9, C9, 4)
+ || reg->value == CPENC (3, 0, C9, C9, 5)
+ || reg->value == CPENC (3, 0, C9, C9, 6)
+ || reg->value == CPENC (3, 0, C9, C9, 7)
+ || reg->value == CPENC (3, 4, C9, C9, 0)
+ || reg->value == CPENC (3, 5, C9, C9, 0))
+ && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_PROFILE))
+ return FALSE;
+
+ /* ARMv8.3 Pointer authentication keys. */
+ if ((reg->value == CPENC (3, 0, C2, C1, 0)
+ || reg->value == CPENC (3, 0, C2, C1, 1)
+ || reg->value == CPENC (3, 0, C2, C1, 2)
+ || reg->value == CPENC (3, 0, C2, C1, 3)
+ || reg->value == CPENC (3, 0, C2, C2, 0)
+ || reg->value == CPENC (3, 0, C2, C2, 1)
+ || reg->value == CPENC (3, 0, C2, C2, 2)
+ || reg->value == CPENC (3, 0, C2, C2, 3)
+ || reg->value == CPENC (3, 0, C2, C3, 0)
+ || reg->value == CPENC (3, 0, C2, C3, 1))
+ && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_3))
+ return FALSE;
+
+ /* SVE. */
+ if ((reg->value == CPENC (3, 0, C0, C4, 4)
+ || reg->value == CPENC (3, 0, C1, C2, 0)
+ || reg->value == CPENC (3, 4, C1, C2, 0)
+ || reg->value == CPENC (3, 6, C1, C2, 0)
+ || reg->value == CPENC (3, 5, C1, C2, 0)
+ || reg->value == CPENC (3, 0, C0, C0, 7))
+ && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_SVE))
+ return FALSE;
+
+ /* ARMv8.4 features. */
+
+ /* PSTATE.DIT. */
+ if (reg->value == CPEN_ (3, C2, 5)
+ && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_4))
+ return FALSE;
+
+ /* Virtualization extensions. */
+ if ((reg->value == CPENC(3, 4, C2, C6, 2)
+ || reg->value == CPENC(3, 4, C2, C6, 0)
+ || reg->value == CPENC(3, 4, C14, C4, 0)
+ || reg->value == CPENC(3, 4, C14, C4, 2)
+ || reg->value == CPENC(3, 4, C14, C4, 1)
+ || reg->value == CPENC(3, 4, C14, C5, 0)
+ || reg->value == CPENC(3, 4, C14, C5, 2)
+ || reg->value == CPENC(3, 4, C14, C5, 1)
+ || reg->value == CPENC(3, 4, C1, C3, 1)
+ || reg->value == CPENC(3, 4, C2, C2, 0))
+ && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_4))
+ return FALSE;
+
+ /* ARMv8.4 TLB instructions. */
+ if ((reg->value == CPENS (0, C8, C1, 0)
+ || reg->value == CPENS (0, C8, C1, 1)
+ || reg->value == CPENS (0, C8, C1, 2)
+ || reg->value == CPENS (0, C8, C1, 3)
+ || reg->value == CPENS (0, C8, C1, 5)
+ || reg->value == CPENS (0, C8, C1, 7)
+ || reg->value == CPENS (4, C8, C4, 0)
+ || reg->value == CPENS (4, C8, C4, 4)
+ || reg->value == CPENS (4, C8, C1, 1)
+ || reg->value == CPENS (4, C8, C1, 5)
+ || reg->value == CPENS (4, C8, C1, 6)
+ || reg->value == CPENS (6, C8, C1, 1)
+ || reg->value == CPENS (6, C8, C1, 5)
+ || reg->value == CPENS (4, C8, C1, 0)
+ || reg->value == CPENS (4, C8, C1, 4)
+ || reg->value == CPENS (6, C8, C1, 0)
+ || reg->value == CPENS (0, C8, C6, 1)
+ || reg->value == CPENS (0, C8, C6, 3)
+ || reg->value == CPENS (0, C8, C6, 5)
+ || reg->value == CPENS (0, C8, C6, 7)
+ || reg->value == CPENS (0, C8, C2, 1)
+ || reg->value == CPENS (0, C8, C2, 3)
+ || reg->value == CPENS (0, C8, C2, 5)
+ || reg->value == CPENS (0, C8, C2, 7)
+ || reg->value == CPENS (0, C8, C5, 1)
+ || reg->value == CPENS (0, C8, C5, 3)
+ || reg->value == CPENS (0, C8, C5, 5)
+ || reg->value == CPENS (0, C8, C5, 7)
+ || reg->value == CPENS (4, C8, C0, 2)
+ || reg->value == CPENS (4, C8, C0, 6)
+ || reg->value == CPENS (4, C8, C4, 2)
+ || reg->value == CPENS (4, C8, C4, 6)
+ || reg->value == CPENS (4, C8, C4, 3)
+ || reg->value == CPENS (4, C8, C4, 7)
+ || reg->value == CPENS (4, C8, C6, 1)
+ || reg->value == CPENS (4, C8, C6, 5)
+ || reg->value == CPENS (4, C8, C2, 1)
+ || reg->value == CPENS (4, C8, C2, 5)
+ || reg->value == CPENS (4, C8, C5, 1)
+ || reg->value == CPENS (4, C8, C5, 5)
+ || reg->value == CPENS (6, C8, C6, 1)
+ || reg->value == CPENS (6, C8, C6, 5)
+ || reg->value == CPENS (6, C8, C2, 1)
+ || reg->value == CPENS (6, C8, C2, 5)
+ || reg->value == CPENS (6, C8, C5, 1)
+ || reg->value == CPENS (6, C8, C5, 5))
+ && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_4))
+ return FALSE;
+
+ /* Random Number Instructions. For now they are available
+ (and optional) only with ARMv8.5-A. */
+ if ((reg->value == CPENC (3, 3, C2, C4, 0)
+ || reg->value == CPENC (3, 3, C2, C4, 1))
+ && !(AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_RNG)
+ && AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_5)))
+ return FALSE;
+
+ /* System Registers in ARMv8.5-A with AARCH64_FEATURE_MEMTAG. */
+ if ((reg->value == CPENC (3, 3, C4, C2, 7)
+ || reg->value == CPENC (3, 0, C5, C6, 1)
+ || reg->value == CPENC (3, 0, C5, C6, 0)
+ || reg->value == CPENC (3, 4, C5, C6, 0)
+ || reg->value == CPENC (3, 6, C5, C6, 0)
+ || reg->value == CPENC (3, 5, C5, C6, 0)
+ || reg->value == CPENC (3, 0, C1, C0, 5)
+ || reg->value == CPENC (3, 0, C1, C0, 6)
+ || reg->value == CPENC (3, 1, C0, C0, 4))
+ && !(AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_MEMTAG)))
+ return FALSE;
+