mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-03-23 06:25:12 +00:00
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:
parent
e5797bb0b7
commit
4221703f18
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in a new issue