target/arm: Convert v8 extensions from feature bits to isar tests

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.

Backports commit 962fcbf2efe57231a9f5df0ae0f40c05e35628ba from qemu
This commit is contained in:
Richard Henderson 2018-11-10 08:17:52 -05:00 committed by Lioncash
parent e5797bb0b7
commit 4221703f18
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7
6 changed files with 245 additions and 115 deletions

View file

@ -1578,19 +1578,28 @@ static void arm_max_initfn(struct uc_struct *uc, Object *obj, void *opaque)
* real-world A15 doesn't implement them.
*/
// Unicorn: We lie and enable them anyway
// Unicorn: We lie and enable them anyway.
/* 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);
{
uint32_t t;
t = cpu->isar.id_isar5;
t = FIELD_DP32(t, ID_ISAR5, AES, 2);
t = FIELD_DP32(t, ID_ISAR5, SHA1, 1);
t = FIELD_DP32(t, ID_ISAR5, SHA2, 1);
t = FIELD_DP32(t, ID_ISAR5, CRC32, 1);
t = FIELD_DP32(t, ID_ISAR5, RDM, 1);
t = FIELD_DP32(t, ID_ISAR5, VCMA, 1);
cpu->isar.id_isar5 = t;
t = cpu->isar.id_isar6;
t = FIELD_DP32(t, ID_ISAR6, DP, 1);
cpu->isar.id_isar6 = t;
}
}
#endif

View file

@ -670,6 +670,8 @@ typedef enum ARMPSCIState {
PSCI_ON_PENDING = 2
} ARMPSCIState;
typedef struct ARMISARegisters ARMISARegisters;
/**
* ARMCPU:
* @env: #CPUARMState
@ -1528,30 +1530,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 */
};
@ -3097,4 +3087,121 @@ 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 isar_feature_aa32_aes(const ARMISARegisters *id)
{
return FIELD_EX32(id->id_isar5, ID_ISAR5, AES) != 0;
}
static inline bool isar_feature_aa32_pmull(const ARMISARegisters *id)
{
return FIELD_EX32(id->id_isar5, ID_ISAR5, AES) > 1;
}
static inline bool isar_feature_aa32_sha1(const ARMISARegisters *id)
{
return FIELD_EX32(id->id_isar5, ID_ISAR5, SHA1) != 0;
}
static inline bool isar_feature_aa32_sha2(const ARMISARegisters *id)
{
return FIELD_EX32(id->id_isar5, ID_ISAR5, SHA2) != 0;
}
static inline bool isar_feature_aa32_crc32(const ARMISARegisters *id)
{
return FIELD_EX32(id->id_isar5, ID_ISAR5, CRC32) != 0;
}
static inline bool isar_feature_aa32_rdm(const ARMISARegisters *id)
{
return FIELD_EX32(id->id_isar5, ID_ISAR5, RDM) != 0;
}
static inline bool isar_feature_aa32_vcma(const ARMISARegisters *id)
{
return FIELD_EX32(id->id_isar5, ID_ISAR5, VCMA) != 0;
}
static inline bool isar_feature_aa32_dp(const ARMISARegisters *id)
{
return FIELD_EX32(id->id_isar6, ID_ISAR6, DP) != 0;
}
/*
* 64-bit feature tests via id registers.
*/
static inline bool isar_feature_aa64_aes(const ARMISARegisters *id)
{
return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, AES) != 0;
}
static inline bool isar_feature_aa64_pmull(const ARMISARegisters *id)
{
return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, AES) > 1;
}
static inline bool isar_feature_aa64_sha1(const ARMISARegisters *id)
{
return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SHA1) != 0;
}
static inline bool isar_feature_aa64_sha256(const ARMISARegisters *id)
{
return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SHA2) != 0;
}
static inline bool isar_feature_aa64_sha512(const ARMISARegisters *id)
{
return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SHA2) > 1;
}
static inline bool isar_feature_aa64_crc32(const ARMISARegisters *id)
{
return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, CRC32) != 0;
}
static inline bool isar_feature_aa64_atomics(const ARMISARegisters *id)
{
return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, ATOMIC) != 0;
}
static inline bool isar_feature_aa64_rdm(const ARMISARegisters *id)
{
return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, RDM) != 0;
}
static inline bool isar_feature_aa64_sha3(const ARMISARegisters *id)
{
return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SHA3) != 0;
}
static inline bool isar_feature_aa64_sm3(const ARMISARegisters *id)
{
return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SM3) != 0;
}
static inline bool isar_feature_aa64_sm4(const ARMISARegisters *id)
{
return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SM4) != 0;
}
static inline bool isar_feature_aa64_dp(const ARMISARegisters *id)
{
return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, DP) != 0;
}
static inline bool isar_feature_aa64_fcma(const ARMISARegisters *id)
{
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, FCMA) != 0;
}
/*
* Forward to the above feature tests given an ARMCPU pointer.
*/
#define cpu_isar_feature(name, cpu) \
({ ARMCPU *cpu_ = (cpu); isar_feature_##name(&cpu_->isar); })
#endif

View file

@ -89,11 +89,6 @@ static void aarch64_a57_initfn(struct uc_struct *uc, Object *obj, void *opaque)
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);
@ -147,11 +142,6 @@ static void aarch64_a53_initfn(struct uc_struct *uc, Object *obj, void *opaque)
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);
@ -203,11 +193,6 @@ static void aarch64_a72_initfn(struct uc_struct *uc, Object *obj, void *opaque)
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);
@ -256,9 +241,42 @@ static void aarch64_a72_initfn(struct uc_struct *uc, Object *obj, void *opaque)
static void aarch64_max_initfn(struct uc_struct *uc, Object *obj, void *opaque)
{
ARMCPU *cpu = ARM_CPU(uc, obj);
uint64_t t;
uint32_t u;
aarch64_a57_initfn(uc, obj, opaque);
t = cpu->isar.id_aa64isar0;
t = FIELD_DP64(t, ID_AA64ISAR0, AES, 2); /* AES + PMULL */
t = FIELD_DP64(t, ID_AA64ISAR0, SHA1, 1);
t = FIELD_DP64(t, ID_AA64ISAR0, SHA2, 2); /* SHA512 */
t = FIELD_DP64(t, ID_AA64ISAR0, CRC32, 1);
t = FIELD_DP64(t, ID_AA64ISAR0, ATOMIC, 2);
t = FIELD_DP64(t, ID_AA64ISAR0, RDM, 1);
t = FIELD_DP64(t, ID_AA64ISAR0, SHA3, 1);
t = FIELD_DP64(t, ID_AA64ISAR0, SM3, 1);
t = FIELD_DP64(t, ID_AA64ISAR0, SM4, 1);
t = FIELD_DP64(t, ID_AA64ISAR0, DP, 1);
cpu->isar.id_aa64isar0 = t;
t = cpu->isar.id_aa64isar1;
t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 1);
cpu->isar.id_aa64isar1 = t;
/* Replicate the same data to the 32-bit id registers. */
u = cpu->isar.id_isar5;
u = FIELD_DP32(u, ID_ISAR5, AES, 2); /* AES + PMULL */
u = FIELD_DP32(u, ID_ISAR5, SHA1, 1);
u = FIELD_DP32(u, ID_ISAR5, SHA2, 1);
u = FIELD_DP32(u, ID_ISAR5, CRC32, 1);
u = FIELD_DP32(u, ID_ISAR5, RDM, 1);
u = FIELD_DP32(u, ID_ISAR5, VCMA, 1);
cpu->isar.id_isar5 = u;
u = cpu->isar.id_isar6;
u = FIELD_DP32(u, ID_ISAR6, DP, 1);
cpu->isar.id_isar6 = u;
// Unicorn: we lie and enable them anyway
/* We don't set these in system emulation mode for the moment,
* since we don't correctly set the ID registers to advertise them,
@ -266,15 +284,7 @@ static void aarch64_max_initfn(struct uc_struct *uc, Object *obj, void *opaque)
* 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.

View file

@ -2390,7 +2390,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)) {
&& dc_isar_feature(aa64_atomics, s)) {
/* CASP / CASPL */
gen_compare_and_swap_pair(s, rs, rt, rn, size | 2);
return;
@ -2412,7 +2412,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)) {
&& dc_isar_feature(aa64_atomics, s)) {
/* CASPA / CASPAL */
gen_compare_and_swap_pair(s, rs, rt, rn, size | 2);
return;
@ -2423,7 +2423,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 && dc_isar_feature(aa64_atomics, s)) {
gen_compare_and_swap(s, rs, rt, rn, size);
return;
}
@ -2968,11 +2968,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 || !dc_isar_feature(aa64_atomics, s)) {
unallocated_encoding(s);
return;
}
@ -3008,10 +3007,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);
@ -4667,7 +4662,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 (!dc_isar_feature(aa64_crc32, s)
|| (sf == 1 && sz != 3)
|| (sf == 0 && sz == 3)) {
unallocated_encoding(s);
@ -8756,7 +8751,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) */
@ -8765,13 +8760,13 @@ static void disas_simd_scalar_three_reg_same_extra(DisasContext *s,
unallocated_encoding(s);
return;
}
feature = ARM_FEATURE_V8_RDM;
feature = dc_isar_feature(aa64_rdm, s);
break;
default:
unallocated_encoding(s);
return;
}
if (!arm_dc_feature(s, feature)) {
if (!feature) {
unallocated_encoding(s);
return;
}
@ -10514,7 +10509,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 (!dc_isar_feature(aa64_pmull, s)) {
unallocated_encoding(s);
return;
}
@ -11571,7 +11566,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) */
@ -11580,7 +11576,7 @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
unallocated_encoding(s);
return;
}
feature = ARM_FEATURE_V8_RDM;
feature = dc_isar_feature(aa64_rdm, s);
break;
case 0x02: /* SDOT (vector) */
case 0x12: /* UDOT (vector) */
@ -11588,7 +11584,7 @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
unallocated_encoding(s);
return;
}
feature = ARM_FEATURE_V8_DOTPROD;
feature = dc_isar_feature(aa64_dp, s);
break;
case 0x18: /* FCMLA, #0 */
case 0x19: /* FCMLA, #90 */
@ -11602,13 +11598,13 @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
unallocated_encoding(s);
return;
}
feature = ARM_FEATURE_V8_FCMA;
feature = dc_isar_feature(aa64_fcma, s);
break;
default:
unallocated_encoding(s);
return;
}
if (!arm_dc_feature(s, feature)) {
if (!feature) {
unallocated_encoding(s);
return;
}
@ -12829,14 +12825,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 (!dc_isar_feature(aa64_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 || !dc_isar_feature(aa64_dp, s)) {
unallocated_encoding(s);
return;
}
@ -12845,7 +12841,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 (!dc_isar_feature(aa64_fcma, s)) {
unallocated_encoding(s);
return;
}
@ -13373,8 +13369,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 (!dc_isar_feature(aa64_aes, s) || size != 0) {
unallocated_encoding(s);
return;
}
@ -13432,7 +13427,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);
@ -13445,23 +13440,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 = dc_isar_feature(aa64_sha1, s);
break;
case 4: /* SHA256H */
genfn = gen_helper_crypto_sha256h;
feature = dc_isar_feature(aa64_sha256, s);
break;
case 5: /* SHA256H2 */
genfn = gen_helper_crypto_sha256h2;
feature = dc_isar_feature(aa64_sha256, s);
break;
case 6: /* SHA256SU1 */
genfn = gen_helper_crypto_sha256su1;
feature = dc_isar_feature(aa64_sha256, s);
break;
default:
unallocated_encoding(s);
return;
}
if (!arm_dc_feature(s, feature)) {
if (!feature) {
unallocated_encoding(s);
return;
}
@ -13503,7 +13501,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) {
@ -13513,15 +13511,15 @@ static void disas_crypto_two_reg_sha(DisasContext *s, uint32_t insn)
switch (opcode) {
case 0: /* SHA1H */
feature = ARM_FEATURE_V8_SHA1;
feature = dc_isar_feature(aa64_sha1, s);
genfn = gen_helper_crypto_sha1h;
break;
case 1: /* SHA1SU1 */
feature = ARM_FEATURE_V8_SHA1;
feature = dc_isar_feature(aa64_sha1, s);
genfn = gen_helper_crypto_sha1su1;
break;
case 2: /* SHA256SU0 */
feature = ARM_FEATURE_V8_SHA256;
feature = dc_isar_feature(aa64_sha256, s);
genfn = gen_helper_crypto_sha256su0;
break;
default:
@ -13529,7 +13527,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;
}
@ -13561,40 +13559,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 = dc_isar_feature(aa64_sha512, s);
genfn = gen_helper_crypto_sha512h;
break;
case 1: /* SHA512H2 */
feature = ARM_FEATURE_V8_SHA512;
feature = dc_isar_feature(aa64_sha512, s);
genfn = gen_helper_crypto_sha512h2;
break;
case 2: /* SHA512SU1 */
feature = ARM_FEATURE_V8_SHA512;
feature = dc_isar_feature(aa64_sha512, s);
genfn = gen_helper_crypto_sha512su1;
break;
case 3: /* RAX1 */
feature = ARM_FEATURE_V8_SHA3;
feature = dc_isar_feature(aa64_sha3, s);
genfn = NULL;
break;
}
} else {
switch (opcode) {
case 0: /* SM3PARTW1 */
feature = ARM_FEATURE_V8_SM3;
feature = dc_isar_feature(aa64_sm3, s);
genfn = gen_helper_crypto_sm3partw1;
break;
case 1: /* SM3PARTW2 */
feature = ARM_FEATURE_V8_SM3;
feature = dc_isar_feature(aa64_sm3, s);
genfn = gen_helper_crypto_sm3partw2;
break;
case 2: /* SM4EKEY */
feature = ARM_FEATURE_V8_SM4;
feature = dc_isar_feature(aa64_sm4, s);
genfn = gen_helper_crypto_sm4ekey;
break;
default:
@ -13603,7 +13601,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;
}
@ -13663,16 +13661,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 = dc_isar_feature(aa64_sha512, s);
genfn = gen_helper_crypto_sha512su0;
break;
case 1: /* SM4E */
feature = ARM_FEATURE_V8_SM4;
feature = dc_isar_feature(aa64_sm4, s);
genfn = gen_helper_crypto_sm4e;
break;
default:
@ -13680,7 +13678,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;
}
@ -13712,22 +13710,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 = dc_isar_feature(aa64_sha3, s);
break;
case 2: /* SM3SS1 */
feature = ARM_FEATURE_V8_SM3;
feature = dc_isar_feature(aa64_sm3, s);
break;
default:
unallocated_encoding(s);
return;
}
if (!arm_dc_feature(s, feature)) {
if (!feature) {
unallocated_encoding(s);
return;
}
@ -13815,7 +13813,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 (!dc_isar_feature(aa64_sha3, s)) {
unallocated_encoding(s);
return;
}
@ -13862,7 +13860,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 (!dc_isar_feature(aa64_sm3, s)) {
unallocated_encoding(s);
return;
}
@ -14029,6 +14027,7 @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
// Unicorn: Store uc context
dc->uc = env->uc;
dc->isar = &arm_cpu->isar;
dc->pc = dc->base.pc_first;
dc->condjmp = 0;

View file

@ -5853,7 +5853,7 @@ static int do_v81_helper(DisasContext *s, gen_helper_gvec_3_ptr *fn,
{
TCGContext *tcg_ctx = s->uc->tcg_ctx;
if (arm_dc_feature(s, ARM_FEATURE_V8_RDM)) {
if (dc_isar_feature(aa32_rdm, s)) {
int opr_sz = (1 + q) * 8;
tcg_gen_gvec_3_ptr(tcg_ctx, vfp_reg_offset(1, rd),
vfp_reg_offset(1, rn),
@ -5928,7 +5928,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 (!dc_isar_feature(aa32_sha1, s)) {
return 1;
}
ptr1 = vfp_reg_ptr(s, true, rd);
@ -5938,7 +5938,7 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
gen_helper_crypto_sha1_3reg(tcg_ctx, ptr1, ptr2, ptr3, tmp4);
tcg_temp_free_i32(tcg_ctx, tmp4);
} else { /* SHA-256 */
if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256) || size == 3) {
if (!dc_isar_feature(aa32_sha2, s) || size == 3) {
return 1;
}
ptr1 = vfp_reg_ptr(s, true, rd);
@ -6933,7 +6933,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 (!dc_isar_feature(aa32_pmull, s)) {
return 1;
}
tcg_rn = tcg_temp_new_i64(tcg_ctx);
@ -7250,7 +7250,7 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
{
NeonGenThreeOpEnvFn *fn;
if (!arm_dc_feature(s, ARM_FEATURE_V8_RDM)) {
if (!dc_isar_feature(aa32_rdm, s)) {
return 1;
}
if (u && ((rd | rn) & 1)) {
@ -7525,8 +7525,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 (!dc_isar_feature(aa32_aes, s) || ((rm | rd) & 1)) {
return 1;
}
ptr1 = vfp_reg_ptr(s, true, rd);
@ -7547,8 +7546,7 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
tcg_temp_free_i32(tcg_ctx, tmp3);
break;
case NEON_2RM_SHA1H:
if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)
|| ((rm | rd) & 1)) {
if (!dc_isar_feature(aa32_sha1, s) || ((rm | rd) & 1)) {
return 1;
}
ptr1 = vfp_reg_ptr(s, true, rd);
@ -7565,10 +7563,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 (!dc_isar_feature(aa32_sha2, s)) {
return 1;
}
} else if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
} else if (!dc_isar_feature(aa32_sha1, s)) {
return 1;
}
ptr1 = vfp_reg_ptr(s, true, rd);
@ -7980,7 +7978,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 (!dc_isar_feature(aa32_vcma, s)
|| (!size && !arm_dc_feature(s, ARM_FEATURE_V8_FP16))) {
return 1;
}
@ -7989,7 +7987,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 (!dc_isar_feature(aa32_vcma, s)
|| (!size && !arm_dc_feature(s, ARM_FEATURE_V8_FP16))) {
return 1;
}
@ -7997,7 +7995,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 (!dc_isar_feature(aa32_dp, s)) {
return 1;
}
fn_gvec = u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b;
@ -8060,7 +8058,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 (!dc_isar_feature(aa32_vcma, s)) {
return 1;
}
if (size == 0) {
@ -8081,7 +8079,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 (!dc_isar_feature(aa32_dp, s)) {
return 1;
}
fn_gvec = u ? gen_helper_gvec_udot_idx_b : gen_helper_gvec_sdot_idx_b;
@ -9081,8 +9079,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 (!dc_isar_feature(aa32_crc32, s) || op1 == 0x3 || (c & 0xd) != 0) {
goto illegal_op;
}
@ -10973,7 +10970,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 (!dc_isar_feature(aa32_crc32, s)) {
goto illegal_op;
}
break;
@ -12803,6 +12800,7 @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
ARMCPU *cpu = arm_env_get_cpu(env);
dc->uc = cs->uc;
dc->isar = &cpu->isar;
dc->pc = dc->base.pc_first;
dc->condjmp = 0;

View file

@ -6,6 +6,7 @@
/* internal defines */
typedef struct DisasContext {
DisasContextBase base;
const ARMISARegisters *isar;
target_ulong pc;
target_ulong page_start;
@ -190,4 +191,10 @@ static inline TCGv_i32 get_ahp_flag(DisasContext *s)
return ret;
}
/*
* Forward to the isar_feature_* tests given a DisasContext pointer.
*/
#define dc_isar_feature(name, ctx) \
({ DisasContext *ctx_ = (ctx); isar_feature_##name(ctx_->isar); })
#endif /* TARGET_ARM_TRANSLATE_H */