On 27/09/2018 23:13, Richard Henderson wrote: > Most of the v8 extensions are self-contained within the ISAR > registers and are not implied by other feature bits, which > makes them the easiest to convert.
Lovely! > Signed-off-by: Richard Henderson <richard.hender...@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <phi...@redhat.com> > --- > target/arm/cpu.h | 123 +++++++++++++++++++++++++++++++++---- > target/arm/translate-a64.h | 20 ++++++ > target/arm/translate.h | 16 +++++ > linux-user/elfload.c | 46 ++++++++------ > target/arm/cpu.c | 18 +++--- > target/arm/cpu64.c | 41 +++++++------ > target/arm/translate-a64.c | 100 +++++++++++++++--------------- > target/arm/translate.c | 35 +++++------ > 8 files changed, 272 insertions(+), 127 deletions(-) > > diff --git a/target/arm/cpu.h b/target/arm/cpu.h > index e1b9270b8c..1e3c4650ce 100644 > --- a/target/arm/cpu.h > +++ b/target/arm/cpu.h > @@ -1550,30 +1550,18 @@ enum arm_features { > ARM_FEATURE_LPAE, /* has Large Physical Address Extension */ > ARM_FEATURE_V8, > ARM_FEATURE_AARCH64, /* supports 64 bit mode */ > - ARM_FEATURE_V8_AES, /* implements AES part of v8 Crypto Extensions */ > ARM_FEATURE_CBAR, /* has cp15 CBAR */ > ARM_FEATURE_CRC, /* ARMv8 CRC instructions */ > ARM_FEATURE_CBAR_RO, /* has cp15 CBAR and it is read-only */ > ARM_FEATURE_EL2, /* has EL2 Virtualization support */ > ARM_FEATURE_EL3, /* has EL3 Secure monitor support */ > - ARM_FEATURE_V8_SHA1, /* implements SHA1 part of v8 Crypto Extensions */ > - ARM_FEATURE_V8_SHA256, /* implements SHA256 part of v8 Crypto Extensions > */ > - ARM_FEATURE_V8_PMULL, /* implements PMULL part of v8 Crypto Extensions */ > ARM_FEATURE_THUMB_DSP, /* DSP insns supported in the Thumb encodings */ > ARM_FEATURE_PMU, /* has PMU support */ > ARM_FEATURE_VBAR, /* has cp15 VBAR */ > ARM_FEATURE_M_SECURITY, /* M profile Security Extension */ > ARM_FEATURE_JAZELLE, /* has (trivial) Jazelle implementation */ > ARM_FEATURE_SVE, /* has Scalable Vector Extension */ > - ARM_FEATURE_V8_SHA512, /* implements SHA512 part of v8 Crypto Extensions > */ > - ARM_FEATURE_V8_SHA3, /* implements SHA3 part of v8 Crypto Extensions */ > - ARM_FEATURE_V8_SM3, /* implements SM3 part of v8 Crypto Extensions */ > - ARM_FEATURE_V8_SM4, /* implements SM4 part of v8 Crypto Extensions */ > - ARM_FEATURE_V8_ATOMICS, /* ARMv8.1-Atomics feature */ > - ARM_FEATURE_V8_RDM, /* implements v8.1 simd round multiply */ > - ARM_FEATURE_V8_DOTPROD, /* implements v8.2 simd dot product */ > ARM_FEATURE_V8_FP16, /* implements v8.2 half-precision float */ > - ARM_FEATURE_V8_FCMA, /* has complex number part of v8.3 extensions. */ > ARM_FEATURE_M_MAIN, /* M profile Main Extension */ > }; > > @@ -3120,4 +3108,115 @@ static inline uint64_t *aa64_vfp_qreg(CPUARMState > *env, unsigned regno) > /* Shared between translate-sve.c and sve_helper.c. */ > extern const uint64_t pred_esz_masks[4]; > > +/* > + * 32-bit feature tests via id registers. > + */ > +static inline bool aa32_feature_aes(ARMCPU *cpu) > +{ > + return FIELD_EX32(cpu->id_isar5, ID_ISAR5, AES) != 0; > +} > + > +static inline bool aa32_feature_pmull(ARMCPU *cpu) > +{ > + return FIELD_EX32(cpu->id_isar5, ID_ISAR5, AES) > 1; > +} > + > +static inline bool aa32_feature_sha1(ARMCPU *cpu) > +{ > + return FIELD_EX32(cpu->id_isar5, ID_ISAR5, SHA1) != 0; > +} > + > +static inline bool aa32_feature_sha2(ARMCPU *cpu) > +{ > + return FIELD_EX32(cpu->id_isar5, ID_ISAR5, SHA2) != 0; > +} > + > +static inline bool aa32_feature_crc32(ARMCPU *cpu) > +{ > + return FIELD_EX32(cpu->id_isar5, ID_ISAR5, CRC32) != 0; > +} > + > +static inline bool aa32_feature_rdm(ARMCPU *cpu) > +{ > + return FIELD_EX32(cpu->id_isar5, ID_ISAR5, RDM) != 0; > +} > + > +static inline bool aa32_feature_vcma(ARMCPU *cpu) > +{ > + return FIELD_EX32(cpu->id_isar5, ID_ISAR5, VCMA) != 0; > +} > + > +static inline bool aa32_feature_dp(ARMCPU *cpu) > +{ > + return FIELD_EX32(cpu->id_isar6, ID_ISAR6, DP) != 0; > +} > + > +/* > + * 64-bit feature tests via id registers. > + */ > +static inline bool aa64_feature_aes(ARMCPU *cpu) > +{ > + return FIELD_EX64(cpu->id_aa64isar0, ID_AA64ISAR0, AES) != 0; > +} > + > +static inline bool aa64_feature_pmull(ARMCPU *cpu) > +{ > + return FIELD_EX64(cpu->id_aa64isar0, ID_AA64ISAR0, AES) > 1; > +} > + > +static inline bool aa64_feature_sha1(ARMCPU *cpu) > +{ > + return FIELD_EX64(cpu->id_aa64isar0, ID_AA64ISAR0, SHA1) != 0; > +} > + > +static inline bool aa64_feature_sha256(ARMCPU *cpu) > +{ > + return FIELD_EX64(cpu->id_aa64isar0, ID_AA64ISAR0, SHA2) != 0; > +} > + > +static inline bool aa64_feature_sha512(ARMCPU *cpu) > +{ > + return FIELD_EX64(cpu->id_aa64isar0, ID_AA64ISAR0, SHA2) > 1; > +} > + > +static inline bool aa64_feature_crc32(ARMCPU *cpu) > +{ > + return FIELD_EX64(cpu->id_aa64isar0, ID_AA64ISAR0, CRC32) != 0; > +} > + > +static inline bool aa64_feature_atomics(ARMCPU *cpu) > +{ > + return FIELD_EX64(cpu->id_aa64isar0, ID_AA64ISAR0, ATOMIC) != 0; > +} > + > +static inline bool aa64_feature_rdm(ARMCPU *cpu) > +{ > + return FIELD_EX64(cpu->id_aa64isar0, ID_AA64ISAR0, RDM) != 0; > +} > + > +static inline bool aa64_feature_sha3(ARMCPU *cpu) > +{ > + return FIELD_EX64(cpu->id_aa64isar0, ID_AA64ISAR0, SHA3) != 0; > +} > + > +static inline bool aa64_feature_sm3(ARMCPU *cpu) > +{ > + return FIELD_EX64(cpu->id_aa64isar0, ID_AA64ISAR0, SM3) != 0; > +} > + > +static inline bool aa64_feature_sm4(ARMCPU *cpu) > +{ > + return FIELD_EX64(cpu->id_aa64isar0, ID_AA64ISAR0, SM4) != 0; > +} > + > +static inline bool aa64_feature_dp(ARMCPU *cpu) > +{ > + return FIELD_EX64(cpu->id_aa64isar0, ID_AA64ISAR0, DP) != 0; > +} > + > +static inline bool aa64_feature_fcma(ARMCPU *cpu) > +{ > + return FIELD_EX64(cpu->id_aa64isar1, ID_AA64ISAR1, FCMA) != 0; > +} > + > #endif > diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h > index 63d958cf50..b4ef9eb024 100644 > --- a/target/arm/translate-a64.h > +++ b/target/arm/translate-a64.h > @@ -123,4 +123,24 @@ typedef void GVecGen2iFn(unsigned, uint32_t, uint32_t, > int64_t, > typedef void GVecGen3Fn(unsigned, uint32_t, uint32_t, > uint32_t, uint32_t, uint32_t); > > +#define FORWARD_FEATURE(NAME) \ > + static inline bool aa64_dc_feature_##NAME(DisasContext *dc) \ > + { return aa64_feature_##NAME(dc->cpu); } > + > +FORWARD_FEATURE(aes) > +FORWARD_FEATURE(pmull) > +FORWARD_FEATURE(sha1) > +FORWARD_FEATURE(sha256) > +FORWARD_FEATURE(sha512) > +FORWARD_FEATURE(crc32) > +FORWARD_FEATURE(atomics) > +FORWARD_FEATURE(rdm) > +FORWARD_FEATURE(sha3) > +FORWARD_FEATURE(sm3) > +FORWARD_FEATURE(sm4) > +FORWARD_FEATURE(dp) > +FORWARD_FEATURE(fcma) > + > +#undef FORWARD_FEATURE > + > #endif /* TARGET_ARM_TRANSLATE_A64_H */ > diff --git a/target/arm/translate.h b/target/arm/translate.h > index 45f04244be..baacfd7e6b 100644 > --- a/target/arm/translate.h > +++ b/target/arm/translate.h > @@ -7,6 +7,7 @@ > /* internal defines */ > typedef struct DisasContext { > DisasContextBase base; > + ARMCPU *cpu; /* for access to the id_* registers */ > > target_ulong pc; > target_ulong page_start; > @@ -189,4 +190,19 @@ static inline TCGv_i32 get_ahp_flag(void) > return ret; > } > > +#define FORWARD_FEATURE(NAME) \ > + static inline bool aa32_dc_feature_##NAME(DisasContext *dc) \ > + { return aa32_feature_##NAME(dc->cpu); } > + > +FORWARD_FEATURE(aes) > +FORWARD_FEATURE(pmull) > +FORWARD_FEATURE(sha1) > +FORWARD_FEATURE(sha2) > +FORWARD_FEATURE(crc32) > +FORWARD_FEATURE(rdm) > +FORWARD_FEATURE(vcma) > +FORWARD_FEATURE(dp) > + > +#undef FORWARD_FEATURE > + > #endif /* TARGET_ARM_TRANSLATE_H */ > diff --git a/linux-user/elfload.c b/linux-user/elfload.c > index e97c4cde49..408bf67206 100644 > --- a/linux-user/elfload.c > +++ b/linux-user/elfload.c > @@ -458,6 +458,10 @@ static uint32_t get_elf_hwcap(void) > /* probe for the extra features */ > #define GET_FEATURE(feat, hwcap) \ > do { if (arm_feature(&cpu->env, feat)) { hwcaps |= hwcap; } } while (0) > + > +#define GET_FEATURE_ID(feat, hwcap) \ > + do { if (aa32_feature_##feat(cpu)) { hwcaps |= hwcap; } } while (0) > + > /* EDSP is in v5TE and above, but all our v5 CPUs are v5TE */ > GET_FEATURE(ARM_FEATURE_V5, ARM_HWCAP_ARM_EDSP); > GET_FEATURE(ARM_FEATURE_VFP, ARM_HWCAP_ARM_VFP); > @@ -485,15 +489,16 @@ static uint32_t get_elf_hwcap2(void) > ARMCPU *cpu = ARM_CPU(thread_cpu); > uint32_t hwcaps = 0; > > - GET_FEATURE(ARM_FEATURE_V8_AES, ARM_HWCAP2_ARM_AES); > - GET_FEATURE(ARM_FEATURE_V8_PMULL, ARM_HWCAP2_ARM_PMULL); > - GET_FEATURE(ARM_FEATURE_V8_SHA1, ARM_HWCAP2_ARM_SHA1); > - GET_FEATURE(ARM_FEATURE_V8_SHA256, ARM_HWCAP2_ARM_SHA2); > - GET_FEATURE(ARM_FEATURE_CRC, ARM_HWCAP2_ARM_CRC32); > + GET_FEATURE_ID(aes, ARM_HWCAP2_ARM_AES); > + GET_FEATURE_ID(pmull, ARM_HWCAP2_ARM_PMULL); > + GET_FEATURE_ID(sha1, ARM_HWCAP2_ARM_SHA1); > + GET_FEATURE_ID(sha2, ARM_HWCAP2_ARM_SHA2); > + GET_FEATURE_ID(crc32, ARM_HWCAP2_ARM_CRC32); > return hwcaps; > } > > #undef GET_FEATURE > +#undef GET_FEATURE_ID > > #else > /* 64 bit ARM definitions */ > @@ -570,23 +575,28 @@ static uint32_t get_elf_hwcap(void) > /* probe for the extra features */ > #define GET_FEATURE(feat, hwcap) \ > do { if (arm_feature(&cpu->env, feat)) { hwcaps |= hwcap; } } while (0) > - GET_FEATURE(ARM_FEATURE_V8_AES, ARM_HWCAP_A64_AES); > - GET_FEATURE(ARM_FEATURE_V8_PMULL, ARM_HWCAP_A64_PMULL); > - GET_FEATURE(ARM_FEATURE_V8_SHA1, ARM_HWCAP_A64_SHA1); > - GET_FEATURE(ARM_FEATURE_V8_SHA256, ARM_HWCAP_A64_SHA2); > - GET_FEATURE(ARM_FEATURE_CRC, ARM_HWCAP_A64_CRC32); > - GET_FEATURE(ARM_FEATURE_V8_SHA3, ARM_HWCAP_A64_SHA3); > - GET_FEATURE(ARM_FEATURE_V8_SM3, ARM_HWCAP_A64_SM3); > - GET_FEATURE(ARM_FEATURE_V8_SM4, ARM_HWCAP_A64_SM4); > - GET_FEATURE(ARM_FEATURE_V8_SHA512, ARM_HWCAP_A64_SHA512); > +#define GET_FEATURE_ID(feat, hwcap) \ > + do { if (aa64_feature_##feat(cpu)) { hwcaps |= hwcap; } } while (0) > + > + GET_FEATURE_ID(aes, ARM_HWCAP_A64_AES); > + GET_FEATURE_ID(pmull, ARM_HWCAP_A64_PMULL); > + GET_FEATURE_ID(sha1, ARM_HWCAP_A64_SHA1); > + GET_FEATURE_ID(sha256, ARM_HWCAP_A64_SHA2); > + GET_FEATURE_ID(sha512, ARM_HWCAP_A64_SHA512); > + GET_FEATURE_ID(crc32, ARM_HWCAP_A64_CRC32); > + GET_FEATURE_ID(sha3, ARM_HWCAP_A64_SHA3); > + GET_FEATURE_ID(sm3, ARM_HWCAP_A64_SM3); > + GET_FEATURE_ID(sm4, ARM_HWCAP_A64_SM4); > GET_FEATURE(ARM_FEATURE_V8_FP16, > ARM_HWCAP_A64_FPHP | ARM_HWCAP_A64_ASIMDHP); > - GET_FEATURE(ARM_FEATURE_V8_ATOMICS, ARM_HWCAP_A64_ATOMICS); > - GET_FEATURE(ARM_FEATURE_V8_RDM, ARM_HWCAP_A64_ASIMDRDM); > - GET_FEATURE(ARM_FEATURE_V8_DOTPROD, ARM_HWCAP_A64_ASIMDDP); > - GET_FEATURE(ARM_FEATURE_V8_FCMA, ARM_HWCAP_A64_FCMA); > + GET_FEATURE_ID(atomics, ARM_HWCAP_A64_ATOMICS); > + GET_FEATURE_ID(rdm, ARM_HWCAP_A64_ASIMDRDM); > + GET_FEATURE_ID(dp, ARM_HWCAP_A64_ASIMDDP); > + GET_FEATURE_ID(fcma, ARM_HWCAP_A64_FCMA); > GET_FEATURE(ARM_FEATURE_SVE, ARM_HWCAP_A64_SVE); > + > #undef GET_FEATURE > +#undef GET_FEATURE_ID > > return hwcaps; > } > diff --git a/target/arm/cpu.c b/target/arm/cpu.c > index b5e61cc177..17c9c43f41 100644 > --- a/target/arm/cpu.c > +++ b/target/arm/cpu.c > @@ -1827,17 +1827,17 @@ static void arm_max_initfn(Object *obj) > cortex_a15_initfn(obj); > #ifdef CONFIG_USER_ONLY > /* We don't set these in system emulation mode for the moment, > - * since we don't correctly set the ID registers to advertise them, > + * since we don't correctly set (all of) the ID registers to > + * advertise them. > */ > set_feature(&cpu->env, ARM_FEATURE_V8); > - set_feature(&cpu->env, ARM_FEATURE_V8_AES); > - set_feature(&cpu->env, ARM_FEATURE_V8_SHA1); > - set_feature(&cpu->env, ARM_FEATURE_V8_SHA256); > - set_feature(&cpu->env, ARM_FEATURE_V8_PMULL); > - set_feature(&cpu->env, ARM_FEATURE_CRC); > - set_feature(&cpu->env, ARM_FEATURE_V8_RDM); > - set_feature(&cpu->env, ARM_FEATURE_V8_DOTPROD); > - set_feature(&cpu->env, ARM_FEATURE_V8_FCMA); > + FIELD_DP32(cpu->id_isar5, ID_ISAR5, AES, 2); /* AES + PMULL */ > + FIELD_DP32(cpu->id_isar5, ID_ISAR5, SHA1, 1); > + FIELD_DP32(cpu->id_isar5, ID_ISAR5, SHA2, 1); > + FIELD_DP32(cpu->id_isar5, ID_ISAR5, CRC32, 1); > + FIELD_DP32(cpu->id_isar5, ID_ISAR5, RDM, 1); > + FIELD_DP32(cpu->id_isar5, ID_ISAR5, VCMA, 1); > + FIELD_DP32(cpu->id_isar6, ID_ISAR6, DP, 1); > #endif > } > } > diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c > index 800bff780e..f9830b67f3 100644 > --- a/target/arm/cpu64.c > +++ b/target/arm/cpu64.c > @@ -109,11 +109,6 @@ static void aarch64_a57_initfn(Object *obj) > set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER); > set_feature(&cpu->env, ARM_FEATURE_AARCH64); > set_feature(&cpu->env, ARM_FEATURE_CBAR_RO); > - set_feature(&cpu->env, ARM_FEATURE_V8_AES); > - set_feature(&cpu->env, ARM_FEATURE_V8_SHA1); > - set_feature(&cpu->env, ARM_FEATURE_V8_SHA256); > - set_feature(&cpu->env, ARM_FEATURE_V8_PMULL); > - set_feature(&cpu->env, ARM_FEATURE_CRC); > set_feature(&cpu->env, ARM_FEATURE_EL2); > set_feature(&cpu->env, ARM_FEATURE_EL3); > set_feature(&cpu->env, ARM_FEATURE_PMU); > @@ -170,11 +165,6 @@ static void aarch64_a53_initfn(Object *obj) > set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER); > set_feature(&cpu->env, ARM_FEATURE_AARCH64); > set_feature(&cpu->env, ARM_FEATURE_CBAR_RO); > - set_feature(&cpu->env, ARM_FEATURE_V8_AES); > - set_feature(&cpu->env, ARM_FEATURE_V8_SHA1); > - set_feature(&cpu->env, ARM_FEATURE_V8_SHA256); > - set_feature(&cpu->env, ARM_FEATURE_V8_PMULL); > - set_feature(&cpu->env, ARM_FEATURE_CRC); > set_feature(&cpu->env, ARM_FEATURE_EL2); > set_feature(&cpu->env, ARM_FEATURE_EL3); > set_feature(&cpu->env, ARM_FEATURE_PMU); > @@ -254,6 +244,29 @@ static void aarch64_max_initfn(Object *obj) > kvm_arm_set_cpu_features_from_host(cpu); > } else { > aarch64_a57_initfn(obj); > + > + FIELD_DP64(cpu->id_aa64isar0, ID_AA64ISAR0, AES, 2); /* AES + PMULL > */ > + FIELD_DP64(cpu->id_aa64isar0, ID_AA64ISAR0, SHA1, 1); > + FIELD_DP64(cpu->id_aa64isar0, ID_AA64ISAR0, SHA2, 2); /* SHA512 */ > + FIELD_DP64(cpu->id_aa64isar0, ID_AA64ISAR0, CRC32, 1); > + FIELD_DP64(cpu->id_aa64isar0, ID_AA64ISAR0, ATOMIC, 2); > + FIELD_DP64(cpu->id_aa64isar0, ID_AA64ISAR0, RDM, 1); > + FIELD_DP64(cpu->id_aa64isar0, ID_AA64ISAR0, SHA3, 1); > + FIELD_DP64(cpu->id_aa64isar0, ID_AA64ISAR0, SM3, 1); > + FIELD_DP64(cpu->id_aa64isar0, ID_AA64ISAR0, SM4, 1); > + FIELD_DP64(cpu->id_aa64isar0, ID_AA64ISAR0, DP, 1); > + > + FIELD_DP64(cpu->id_aa64isar1, ID_AA64ISAR1, FCMA, 1); > + > + /* Replicate the same data to the 32-bit id registers. */ > + FIELD_DP32(cpu->id_isar5, ID_ISAR5, AES, 2); /* AES + PMULL */ > + FIELD_DP32(cpu->id_isar5, ID_ISAR5, SHA1, 1); > + FIELD_DP32(cpu->id_isar5, ID_ISAR5, SHA2, 1); > + FIELD_DP32(cpu->id_isar5, ID_ISAR5, CRC32, 1); > + FIELD_DP32(cpu->id_isar5, ID_ISAR5, RDM, 1); > + FIELD_DP32(cpu->id_isar5, ID_ISAR5, VCMA, 1); > + FIELD_DP32(cpu->id_isar6, ID_ISAR6, DP, 1); > + > #ifdef CONFIG_USER_ONLY > /* We don't set these in system emulation mode for the moment, > * since we don't correctly set the ID registers to advertise them, > @@ -261,15 +274,7 @@ static void aarch64_max_initfn(Object *obj) > * whereas the architecture requires them to be present in both if > * present in either. > */ > - set_feature(&cpu->env, ARM_FEATURE_V8_SHA512); > - set_feature(&cpu->env, ARM_FEATURE_V8_SHA3); > - set_feature(&cpu->env, ARM_FEATURE_V8_SM3); > - set_feature(&cpu->env, ARM_FEATURE_V8_SM4); > - set_feature(&cpu->env, ARM_FEATURE_V8_ATOMICS); > - set_feature(&cpu->env, ARM_FEATURE_V8_RDM); > - set_feature(&cpu->env, ARM_FEATURE_V8_DOTPROD); > set_feature(&cpu->env, ARM_FEATURE_V8_FP16); > - set_feature(&cpu->env, ARM_FEATURE_V8_FCMA); > set_feature(&cpu->env, ARM_FEATURE_SVE); > /* For usermode -cpu max we can use a larger and more efficient DCZ > * blocksize since we don't have to follow what the hardware does. > diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c > index 8ca3876707..40575485aa 100644 > --- a/target/arm/translate-a64.c > +++ b/target/arm/translate-a64.c > @@ -2318,7 +2318,7 @@ static void disas_ldst_excl(DisasContext *s, uint32_t > insn) > } > if (rt2 == 31 > && ((rt | rs) & 1) == 0 > - && arm_dc_feature(s, ARM_FEATURE_V8_ATOMICS)) { > + && aa64_dc_feature_atomics(s)) { > /* CASP / CASPL */ > gen_compare_and_swap_pair(s, rs, rt, rn, size | 2); > return; > @@ -2340,7 +2340,7 @@ static void disas_ldst_excl(DisasContext *s, uint32_t > insn) > } > if (rt2 == 31 > && ((rt | rs) & 1) == 0 > - && arm_dc_feature(s, ARM_FEATURE_V8_ATOMICS)) { > + && aa64_dc_feature_atomics(s)) { > /* CASPA / CASPAL */ > gen_compare_and_swap_pair(s, rs, rt, rn, size | 2); > return; > @@ -2351,7 +2351,7 @@ static void disas_ldst_excl(DisasContext *s, uint32_t > insn) > case 0xb: /* CASL */ > case 0xe: /* CASA */ > case 0xf: /* CASAL */ > - if (rt2 == 31 && arm_dc_feature(s, ARM_FEATURE_V8_ATOMICS)) { > + if (rt2 == 31 && aa64_dc_feature_atomics(s)) { > gen_compare_and_swap(s, rs, rt, rn, size); > return; > } > @@ -2890,11 +2890,10 @@ static void disas_ldst_atomic(DisasContext *s, > uint32_t insn, > int rs = extract32(insn, 16, 5); > int rn = extract32(insn, 5, 5); > int o3_opc = extract32(insn, 12, 4); > - int feature = ARM_FEATURE_V8_ATOMICS; > TCGv_i64 tcg_rn, tcg_rs; > AtomicThreeOpFn *fn; > > - if (is_vector) { > + if (is_vector || !aa64_dc_feature_atomics(s)) { > unallocated_encoding(s); > return; > } > @@ -2930,10 +2929,6 @@ static void disas_ldst_atomic(DisasContext *s, > uint32_t insn, > unallocated_encoding(s); > return; > } > - if (!arm_dc_feature(s, feature)) { > - unallocated_encoding(s); > - return; > - } > > if (rn == 31) { > gen_check_sp_alignment(s); > @@ -4564,7 +4559,7 @@ static void handle_crc32(DisasContext *s, > TCGv_i64 tcg_acc, tcg_val; > TCGv_i32 tcg_bytes; > > - if (!arm_dc_feature(s, ARM_FEATURE_CRC) > + if (!aa64_dc_feature_crc32(s) > || (sf == 1 && sz != 3) > || (sf == 0 && sz == 3)) { > unallocated_encoding(s); > @@ -8608,7 +8603,7 @@ static void > disas_simd_scalar_three_reg_same_extra(DisasContext *s, > bool u = extract32(insn, 29, 1); > TCGv_i32 ele1, ele2, ele3; > TCGv_i64 res; > - int feature; > + bool feature; > > switch (u * 16 + opcode) { > case 0x10: /* SQRDMLAH (vector) */ > @@ -8617,13 +8612,13 @@ static void > disas_simd_scalar_three_reg_same_extra(DisasContext *s, > unallocated_encoding(s); > return; > } > - feature = ARM_FEATURE_V8_RDM; > + feature = aa64_dc_feature_rdm(s); > break; > default: > unallocated_encoding(s); > return; > } > - if (!arm_dc_feature(s, feature)) { > + if (!feature) { > unallocated_encoding(s); > return; > } > @@ -10352,7 +10347,7 @@ static void disas_simd_three_reg_diff(DisasContext > *s, uint32_t insn) > return; > } > if (size == 3) { > - if (!arm_dc_feature(s, ARM_FEATURE_V8_PMULL)) { > + if (!aa64_dc_feature_pmull(s)) { > unallocated_encoding(s); > return; > } > @@ -11404,7 +11399,8 @@ static void > disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn) > int size = extract32(insn, 22, 2); > bool u = extract32(insn, 29, 1); > bool is_q = extract32(insn, 30, 1); > - int feature, rot; > + bool feature; > + int rot; > > switch (u * 16 + opcode) { > case 0x10: /* SQRDMLAH (vector) */ > @@ -11413,7 +11409,7 @@ static void > disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn) > unallocated_encoding(s); > return; > } > - feature = ARM_FEATURE_V8_RDM; > + feature = aa64_dc_feature_rdm(s); > break; > case 0x02: /* SDOT (vector) */ > case 0x12: /* UDOT (vector) */ > @@ -11421,7 +11417,7 @@ static void > disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn) > unallocated_encoding(s); > return; > } > - feature = ARM_FEATURE_V8_DOTPROD; > + feature = aa64_dc_feature_dp(s); > break; > case 0x18: /* FCMLA, #0 */ > case 0x19: /* FCMLA, #90 */ > @@ -11435,13 +11431,13 @@ static void > disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn) > unallocated_encoding(s); > return; > } > - feature = ARM_FEATURE_V8_FCMA; > + feature = aa64_dc_feature_fcma(s); > break; > default: > unallocated_encoding(s); > return; > } > - if (!arm_dc_feature(s, feature)) { > + if (!feature) { > unallocated_encoding(s); > return; > } > @@ -12655,14 +12651,14 @@ static void disas_simd_indexed(DisasContext *s, > uint32_t insn) > break; > case 0x1d: /* SQRDMLAH */ > case 0x1f: /* SQRDMLSH */ > - if (!arm_dc_feature(s, ARM_FEATURE_V8_RDM)) { > + if (!aa64_dc_feature_rdm(s)) { > unallocated_encoding(s); > return; > } > break; > case 0x0e: /* SDOT */ > case 0x1e: /* UDOT */ > - if (size != MO_32 || !arm_dc_feature(s, ARM_FEATURE_V8_DOTPROD)) { > + if (size != MO_32 || !aa64_dc_feature_dp(s)) { > unallocated_encoding(s); > return; > } > @@ -12671,7 +12667,7 @@ static void disas_simd_indexed(DisasContext *s, > uint32_t insn) > case 0x13: /* FCMLA #90 */ > case 0x15: /* FCMLA #180 */ > case 0x17: /* FCMLA #270 */ > - if (!arm_dc_feature(s, ARM_FEATURE_V8_FCMA)) { > + if (!aa64_dc_feature_fcma(s)) { > unallocated_encoding(s); > return; > } > @@ -13198,8 +13194,7 @@ static void disas_crypto_aes(DisasContext *s, > uint32_t insn) > TCGv_i32 tcg_decrypt; > CryptoThreeOpIntFn *genfn; > > - if (!arm_dc_feature(s, ARM_FEATURE_V8_AES) > - || size != 0) { > + if (!aa64_dc_feature_aes(s) || size != 0) { > unallocated_encoding(s); > return; > } > @@ -13256,7 +13251,7 @@ static void disas_crypto_three_reg_sha(DisasContext > *s, uint32_t insn) > int rd = extract32(insn, 0, 5); > CryptoThreeOpFn *genfn; > TCGv_ptr tcg_rd_ptr, tcg_rn_ptr, tcg_rm_ptr; > - int feature = ARM_FEATURE_V8_SHA256; > + bool feature; > > if (size != 0) { > unallocated_encoding(s); > @@ -13269,23 +13264,26 @@ static void disas_crypto_three_reg_sha(DisasContext > *s, uint32_t insn) > case 2: /* SHA1M */ > case 3: /* SHA1SU0 */ > genfn = NULL; > - feature = ARM_FEATURE_V8_SHA1; > + feature = aa64_dc_feature_sha1(s); > break; > case 4: /* SHA256H */ > genfn = gen_helper_crypto_sha256h; > + feature = aa64_dc_feature_sha256(s); > break; > case 5: /* SHA256H2 */ > genfn = gen_helper_crypto_sha256h2; > + feature = aa64_dc_feature_sha256(s); > break; > case 6: /* SHA256SU1 */ > genfn = gen_helper_crypto_sha256su1; > + feature = aa64_dc_feature_sha256(s); > break; > default: > unallocated_encoding(s); > return; > } > > - if (!arm_dc_feature(s, feature)) { > + if (!feature) { > unallocated_encoding(s); > return; > } > @@ -13326,7 +13324,7 @@ static void disas_crypto_two_reg_sha(DisasContext *s, > uint32_t insn) > int rn = extract32(insn, 5, 5); > int rd = extract32(insn, 0, 5); > CryptoTwoOpFn *genfn; > - int feature; > + bool feature; > TCGv_ptr tcg_rd_ptr, tcg_rn_ptr; > > if (size != 0) { > @@ -13336,15 +13334,15 @@ static void disas_crypto_two_reg_sha(DisasContext > *s, uint32_t insn) > > switch (opcode) { > case 0: /* SHA1H */ > - feature = ARM_FEATURE_V8_SHA1; > + feature = aa64_dc_feature_sha1(s); > genfn = gen_helper_crypto_sha1h; > break; > case 1: /* SHA1SU1 */ > - feature = ARM_FEATURE_V8_SHA1; > + feature = aa64_dc_feature_sha1(s); > genfn = gen_helper_crypto_sha1su1; > break; > case 2: /* SHA256SU0 */ > - feature = ARM_FEATURE_V8_SHA256; > + feature = aa64_dc_feature_sha256(s); > genfn = gen_helper_crypto_sha256su0; > break; > default: > @@ -13352,7 +13350,7 @@ static void disas_crypto_two_reg_sha(DisasContext *s, > uint32_t insn) > return; > } > > - if (!arm_dc_feature(s, feature)) { > + if (!feature) { > unallocated_encoding(s); > return; > } > @@ -13383,40 +13381,40 @@ static void > disas_crypto_three_reg_sha512(DisasContext *s, uint32_t insn) > int rm = extract32(insn, 16, 5); > int rn = extract32(insn, 5, 5); > int rd = extract32(insn, 0, 5); > - int feature; > + bool feature; > CryptoThreeOpFn *genfn; > > if (o == 0) { > switch (opcode) { > case 0: /* SHA512H */ > - feature = ARM_FEATURE_V8_SHA512; > + feature = aa64_dc_feature_sha512(s); > genfn = gen_helper_crypto_sha512h; > break; > case 1: /* SHA512H2 */ > - feature = ARM_FEATURE_V8_SHA512; > + feature = aa64_dc_feature_sha512(s); > genfn = gen_helper_crypto_sha512h2; > break; > case 2: /* SHA512SU1 */ > - feature = ARM_FEATURE_V8_SHA512; > + feature = aa64_dc_feature_sha512(s); > genfn = gen_helper_crypto_sha512su1; > break; > case 3: /* RAX1 */ > - feature = ARM_FEATURE_V8_SHA3; > + feature = aa64_dc_feature_sha3(s); > genfn = NULL; > break; > } > } else { > switch (opcode) { > case 0: /* SM3PARTW1 */ > - feature = ARM_FEATURE_V8_SM3; > + feature = aa64_dc_feature_sm3(s); > genfn = gen_helper_crypto_sm3partw1; > break; > case 1: /* SM3PARTW2 */ > - feature = ARM_FEATURE_V8_SM3; > + feature = aa64_dc_feature_sm3(s); > genfn = gen_helper_crypto_sm3partw2; > break; > case 2: /* SM4EKEY */ > - feature = ARM_FEATURE_V8_SM4; > + feature = aa64_dc_feature_sm4(s); > genfn = gen_helper_crypto_sm4ekey; > break; > default: > @@ -13425,7 +13423,7 @@ static void > disas_crypto_three_reg_sha512(DisasContext *s, uint32_t insn) > } > } > > - if (!arm_dc_feature(s, feature)) { > + if (!feature) { > unallocated_encoding(s); > return; > } > @@ -13484,16 +13482,16 @@ static void > disas_crypto_two_reg_sha512(DisasContext *s, uint32_t insn) > int rn = extract32(insn, 5, 5); > int rd = extract32(insn, 0, 5); > TCGv_ptr tcg_rd_ptr, tcg_rn_ptr; > - int feature; > + bool feature; > CryptoTwoOpFn *genfn; > > switch (opcode) { > case 0: /* SHA512SU0 */ > - feature = ARM_FEATURE_V8_SHA512; > + feature = aa64_dc_feature_sha512(s); > genfn = gen_helper_crypto_sha512su0; > break; > case 1: /* SM4E */ > - feature = ARM_FEATURE_V8_SM4; > + feature = aa64_dc_feature_sm4(s); > genfn = gen_helper_crypto_sm4e; > break; > default: > @@ -13501,7 +13499,7 @@ static void disas_crypto_two_reg_sha512(DisasContext > *s, uint32_t insn) > return; > } > > - if (!arm_dc_feature(s, feature)) { > + if (!feature) { > unallocated_encoding(s); > return; > } > @@ -13532,22 +13530,22 @@ static void disas_crypto_four_reg(DisasContext *s, > uint32_t insn) > int ra = extract32(insn, 10, 5); > int rn = extract32(insn, 5, 5); > int rd = extract32(insn, 0, 5); > - int feature; > + bool feature; > > switch (op0) { > case 0: /* EOR3 */ > case 1: /* BCAX */ > - feature = ARM_FEATURE_V8_SHA3; > + feature = aa64_dc_feature_sha3(s); > break; > case 2: /* SM3SS1 */ > - feature = ARM_FEATURE_V8_SM3; > + feature = aa64_dc_feature_sm3(s); > break; > default: > unallocated_encoding(s); > return; > } > > - if (!arm_dc_feature(s, feature)) { > + if (!feature) { > unallocated_encoding(s); > return; > } > @@ -13634,7 +13632,7 @@ static void disas_crypto_xar(DisasContext *s, > uint32_t insn) > TCGv_i64 tcg_op1, tcg_op2, tcg_res[2]; > int pass; > > - if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA3)) { > + if (!aa64_dc_feature_sha3(s)) { > unallocated_encoding(s); > return; > } > @@ -13680,7 +13678,7 @@ static void disas_crypto_three_reg_imm2(DisasContext > *s, uint32_t insn) > TCGv_ptr tcg_rd_ptr, tcg_rn_ptr, tcg_rm_ptr; > TCGv_i32 tcg_imm2, tcg_opcode; > > - if (!arm_dc_feature(s, ARM_FEATURE_V8_SM3)) { > + if (!aa64_dc_feature_sm3(s)) { > unallocated_encoding(s); > return; > } > diff --git a/target/arm/translate.c b/target/arm/translate.c > index c6a5d2ac44..06d61b1e0d 100644 > --- a/target/arm/translate.c > +++ b/target/arm/translate.c > @@ -5660,7 +5660,7 @@ static const uint8_t neon_2rm_sizes[] = { > static int do_v81_helper(DisasContext *s, gen_helper_gvec_3_ptr *fn, > int q, int rd, int rn, int rm) > { > - if (arm_dc_feature(s, ARM_FEATURE_V8_RDM)) { > + if (aa32_dc_feature_rdm(s)) { > int opr_sz = (1 + q) * 8; > tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), > vfp_reg_offset(1, rn), > @@ -5734,7 +5734,7 @@ static int disas_neon_data_insn(DisasContext *s, > uint32_t insn) > return 1; > } > if (!u) { /* SHA-1 */ > - if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) { > + if (!aa32_dc_feature_sha1(s)) { > return 1; > } > ptr1 = vfp_reg_ptr(true, rd); > @@ -5744,7 +5744,7 @@ static int disas_neon_data_insn(DisasContext *s, > uint32_t insn) > gen_helper_crypto_sha1_3reg(ptr1, ptr2, ptr3, tmp4); > tcg_temp_free_i32(tmp4); > } else { /* SHA-256 */ > - if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256) || size == 3) { > + if (!aa32_dc_feature_sha2(s) || size == 3) { > return 1; > } > ptr1 = vfp_reg_ptr(true, rd); > @@ -6739,7 +6739,7 @@ static int disas_neon_data_insn(DisasContext *s, > uint32_t insn) > if (op == 14 && size == 2) { > TCGv_i64 tcg_rn, tcg_rm, tcg_rd; > > - if (!arm_dc_feature(s, ARM_FEATURE_V8_PMULL)) { > + if (!aa32_dc_feature_pmull(s)) { > return 1; > } > tcg_rn = tcg_temp_new_i64(); > @@ -7056,7 +7056,7 @@ static int disas_neon_data_insn(DisasContext *s, > uint32_t insn) > { > NeonGenThreeOpEnvFn *fn; > > - if (!arm_dc_feature(s, ARM_FEATURE_V8_RDM)) { > + if (!aa32_dc_feature_rdm(s)) { > return 1; > } > if (u && ((rd | rn) & 1)) { > @@ -7330,8 +7330,7 @@ static int disas_neon_data_insn(DisasContext *s, > uint32_t insn) > break; > } > case NEON_2RM_AESE: case NEON_2RM_AESMC: > - if (!arm_dc_feature(s, ARM_FEATURE_V8_AES) > - || ((rm | rd) & 1)) { > + if (!aa32_dc_feature_aes(s) || ((rm | rd) & 1)) { > return 1; > } > ptr1 = vfp_reg_ptr(true, rd); > @@ -7352,8 +7351,7 @@ static int disas_neon_data_insn(DisasContext *s, > uint32_t insn) > tcg_temp_free_i32(tmp3); > break; > case NEON_2RM_SHA1H: > - if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1) > - || ((rm | rd) & 1)) { > + if (!aa32_dc_feature_sha1(s) || ((rm | rd) & 1)) { > return 1; > } > ptr1 = vfp_reg_ptr(true, rd); > @@ -7370,10 +7368,10 @@ static int disas_neon_data_insn(DisasContext *s, > uint32_t insn) > } > /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */ > if (q) { > - if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256)) { > + if (!aa32_dc_feature_sha2(s)) { > return 1; > } > - } else if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) { > + } else if (!aa32_dc_feature_sha1(s)) { > return 1; > } > ptr1 = vfp_reg_ptr(true, rd); > @@ -7784,7 +7782,7 @@ static int disas_neon_insn_3same_ext(DisasContext *s, > uint32_t insn) > /* VCMLA -- 1111 110R R.1S .... .... 1000 ...0 .... */ > int size = extract32(insn, 20, 1); > data = extract32(insn, 23, 2); /* rot */ > - if (!arm_dc_feature(s, ARM_FEATURE_V8_FCMA) > + if (!aa32_dc_feature_vcma(s) > || (!size && !arm_dc_feature(s, ARM_FEATURE_V8_FP16))) { > return 1; > } > @@ -7793,7 +7791,7 @@ static int disas_neon_insn_3same_ext(DisasContext *s, > uint32_t insn) > /* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */ > int size = extract32(insn, 20, 1); > data = extract32(insn, 24, 1); /* rot */ > - if (!arm_dc_feature(s, ARM_FEATURE_V8_FCMA) > + if (!aa32_dc_feature_vcma(s) > || (!size && !arm_dc_feature(s, ARM_FEATURE_V8_FP16))) { > return 1; > } > @@ -7801,7 +7799,7 @@ static int disas_neon_insn_3same_ext(DisasContext *s, > uint32_t insn) > } else if ((insn & 0xfeb00f00) == 0xfc200d00) { > /* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */ > bool u = extract32(insn, 4, 1); > - if (!arm_dc_feature(s, ARM_FEATURE_V8_DOTPROD)) { > + if (!aa32_dc_feature_dp(s)) { > return 1; > } > fn_gvec = u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b; > @@ -7863,7 +7861,7 @@ static int disas_neon_insn_2reg_scalar_ext(DisasContext > *s, uint32_t insn) > int size = extract32(insn, 23, 1); > int index; > > - if (!arm_dc_feature(s, ARM_FEATURE_V8_FCMA)) { > + if (!aa32_dc_feature_vcma(s)) { > return 1; > } > if (size == 0) { > @@ -7884,7 +7882,7 @@ static int disas_neon_insn_2reg_scalar_ext(DisasContext > *s, uint32_t insn) > } else if ((insn & 0xffb00f00) == 0xfe200d00) { > /* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */ > int u = extract32(insn, 4, 1); > - if (!arm_dc_feature(s, ARM_FEATURE_V8_DOTPROD)) { > + if (!aa32_dc_feature_dp(s)) { > return 1; > } > fn_gvec = u ? gen_helper_gvec_udot_idx_b : > gen_helper_gvec_sdot_idx_b; > @@ -8860,8 +8858,7 @@ static void disas_arm_insn(DisasContext *s, unsigned > int insn) > * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED. > * Bits 8, 10 and 11 should be zero. > */ > - if (!arm_dc_feature(s, ARM_FEATURE_CRC) || op1 == 0x3 || > - (c & 0xd) != 0) { > + if (!aa32_dc_feature_crc32(s) || op1 == 0x3 || (c & 0xd) != 0) { > goto illegal_op; > } > > @@ -10706,7 +10703,7 @@ static void disas_thumb2_insn(DisasContext *s, > uint32_t insn) > case 0x28: > case 0x29: > case 0x2a: > - if (!arm_dc_feature(s, ARM_FEATURE_CRC)) { > + if (!aa32_dc_feature_crc32(s)) { > goto illegal_op; > } > break; >