[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v2 2/9] target/arm: Convert v8 extensions from f
From: |
Philippe Mathieu-Daudé |
Subject: |
Re: [Qemu-devel] [PATCH v2 2/9] target/arm: Convert v8 extensions from feature bits to isar tests |
Date: |
Fri, 28 Sep 2018 16:15:02 +0200 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.0 |
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 <address@hidden>
Reviewed-by: Philippe Mathieu-Daudé <address@hidden>
> ---
> 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;
>
- [Qemu-devel] [PATCH v2 0/9] target/arm: Rely on id regs instead of features, Richard Henderson, 2018/09/27
- [Qemu-devel] [PATCH v2 2/9] target/arm: Convert v8 extensions from feature bits to isar tests, Richard Henderson, 2018/09/27
- Re: [Qemu-devel] [PATCH v2 2/9] target/arm: Convert v8 extensions from feature bits to isar tests,
Philippe Mathieu-Daudé <=
- [Qemu-devel] [PATCH v2 7/9] target/arm: Convert t32ee from feature bit to isar3 test, Richard Henderson, 2018/09/27
- [Qemu-devel] [PATCH v2 6/9] target/arm: Convert jazelle from feature bit to isar1 test, Richard Henderson, 2018/09/27
- [Qemu-devel] [PATCH v2 1/9] target/arm: Define fields of ISAR registers, Richard Henderson, 2018/09/27
- [Qemu-devel] [PATCH v2 9/9] target/arm: Convert v8.2-fp16 from feature bit to pfr0 test, Richard Henderson, 2018/09/27