* [Qemu-devel] [PATCH v3 01/10] target/arm: Fix aarch64_sve_change_el wrt EL0
2018-10-08 21:21 [Qemu-devel] [PATCH v3 00/10] target/arm: Rely on id regs instead of features Richard Henderson
@ 2018-10-08 21:21 ` Richard Henderson
2018-10-16 10:38 ` Peter Maydell
2018-10-08 21:21 ` [Qemu-devel] [PATCH v3 02/10] target/arm: Define fields of ISAR registers Richard Henderson
` (9 subsequent siblings)
10 siblings, 1 reply; 17+ messages in thread
From: Richard Henderson @ 2018-10-08 21:21 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell
At present we assert:
arm_el_is_aa64: Assertion `el >= 1 && el <= 3' failed.
The comment in arm_el_is_aa64 explains why asking about EL0 without
extra information is impossible. Add an extra argument to provide
it from the surrounding context.
Fixes: 0ab5953b00b3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/arm/cpu.h | 7 +++++--
target/arm/helper.c | 16 ++++++++++++----
target/arm/op_helper.c | 6 +++++-
3 files changed, 22 insertions(+), 7 deletions(-)
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 3a2aff1192..54362ddce8 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -911,10 +911,13 @@ int arm_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
int aarch64_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
int aarch64_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
void aarch64_sve_narrow_vq(CPUARMState *env, unsigned vq);
-void aarch64_sve_change_el(CPUARMState *env, int old_el, int new_el);
+void aarch64_sve_change_el(CPUARMState *env, int old_el,
+ int new_el, bool el0_a64);
#else
static inline void aarch64_sve_narrow_vq(CPUARMState *env, unsigned vq) { }
-static inline void aarch64_sve_change_el(CPUARMState *env, int o, int n) { }
+static inline void aarch64_sve_change_el(CPUARMState *env, int o,
+ int n, bool a)
+{ }
#endif
target_ulong do_arm_semihosting(CPUARMState *env);
diff --git a/target/arm/helper.c b/target/arm/helper.c
index c83f7c1109..0efbb5c76c 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -8374,7 +8374,11 @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
unsigned int new_mode = aarch64_pstate_mode(new_el, true);
unsigned int cur_el = arm_current_el(env);
- aarch64_sve_change_el(env, cur_el, new_el);
+ /*
+ * Note that new_el can never be 0. If cur_el is 0, then
+ * el0_a64 is is_a64(), else el0_a64 is ignored.
+ */
+ aarch64_sve_change_el(env, cur_el, new_el, is_a64(env));
if (cur_el < new_el) {
/* Entry vector offset depends on whether the implemented EL
@@ -12791,9 +12795,11 @@ void aarch64_sve_narrow_vq(CPUARMState *env, unsigned vq)
/*
* Notice a change in SVE vector size when changing EL.
*/
-void aarch64_sve_change_el(CPUARMState *env, int old_el, int new_el)
+void aarch64_sve_change_el(CPUARMState *env, int old_el,
+ int new_el, bool el0_a64)
{
int old_len, new_len;
+ bool old_a64, new_a64;
/* Nothing to do if no SVE. */
if (!arm_feature(env, ARM_FEATURE_SVE)) {
@@ -12817,9 +12823,11 @@ void aarch64_sve_change_el(CPUARMState *env, int old_el, int new_el)
* we already have the correct register contents when encountering the
* vq0->vq0 transition between EL0->EL1.
*/
- old_len = (arm_el_is_aa64(env, old_el) && !sve_exception_el(env, old_el)
+ old_a64 = old_el ? arm_el_is_aa64(env, old_el) : el0_a64;
+ old_len = (old_a64 && !sve_exception_el(env, old_el)
? sve_zcr_len_for_el(env, old_el) : 0);
- new_len = (arm_el_is_aa64(env, new_el) && !sve_exception_el(env, new_el)
+ new_a64 = new_el ? arm_el_is_aa64(env, new_el) : el0_a64;
+ new_len = (new_a64 && !sve_exception_el(env, new_el)
? sve_zcr_len_for_el(env, new_el) : 0);
/* When changing vector length, clear inaccessible state. */
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
index fb15a13e6c..d915579712 100644
--- a/target/arm/op_helper.c
+++ b/target/arm/op_helper.c
@@ -1101,7 +1101,11 @@ void HELPER(exception_return)(CPUARMState *env)
"AArch64 EL%d PC 0x%" PRIx64 "\n",
cur_el, new_el, env->pc);
}
- aarch64_sve_change_el(env, cur_el, new_el);
+ /*
+ * Note that cur_el can never be 0. If new_el is 0, then
+ * el0_a64 is return_to_aa64, else el0_a64 is ignored.
+ */
+ aarch64_sve_change_el(env, cur_el, new_el, return_to_aa64);
qemu_mutex_lock_iothread();
arm_call_el_change_hook(arm_env_get_cpu(env));
--
2.17.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH v3 02/10] target/arm: Define fields of ISAR registers
2018-10-08 21:21 [Qemu-devel] [PATCH v3 00/10] target/arm: Rely on id regs instead of features Richard Henderson
2018-10-08 21:21 ` [Qemu-devel] [PATCH v3 01/10] target/arm: Fix aarch64_sve_change_el wrt EL0 Richard Henderson
@ 2018-10-08 21:21 ` Richard Henderson
2018-10-08 21:21 ` [Qemu-devel] [PATCH v3 03/10] target/arm: Convert v8 extensions from feature bits to isar tests Richard Henderson
` (8 subsequent siblings)
10 siblings, 0 replies; 17+ messages in thread
From: Richard Henderson @ 2018-10-08 21:21 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/arm/cpu.h | 88 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 88 insertions(+)
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 54362ddce8..f00c0444c4 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1443,6 +1443,94 @@ FIELD(V7M_CSSELR, LEVEL, 1, 3)
*/
FIELD(V7M_CSSELR, INDEX, 0, 4)
+/*
+ * System register ID fields.
+ */
+FIELD(ID_ISAR0, SWAP, 0, 4)
+FIELD(ID_ISAR0, BITCOUNT, 4, 4)
+FIELD(ID_ISAR0, BITFIELD, 8, 4)
+FIELD(ID_ISAR0, CMPBRANCH, 12, 4)
+FIELD(ID_ISAR0, COPROC, 16, 4)
+FIELD(ID_ISAR0, DEBUG, 20, 4)
+FIELD(ID_ISAR0, DIVIDE, 24, 4)
+
+FIELD(ID_ISAR1, ENDIAN, 0, 4)
+FIELD(ID_ISAR1, EXCEPT, 4, 4)
+FIELD(ID_ISAR1, EXCEPT_AR, 8, 4)
+FIELD(ID_ISAR1, EXTEND, 12, 4)
+FIELD(ID_ISAR1, IFTHEN, 16, 4)
+FIELD(ID_ISAR1, IMMEDIATE, 20, 4)
+FIELD(ID_ISAR1, INTERWORK, 24, 4)
+FIELD(ID_ISAR1, JAZELLE, 28, 4)
+
+FIELD(ID_ISAR2, LOADSTORE, 0, 4)
+FIELD(ID_ISAR2, MEMHINT, 4, 4)
+FIELD(ID_ISAR2, MULTIACCESSINT, 8, 4)
+FIELD(ID_ISAR2, MULT, 12, 4)
+FIELD(ID_ISAR2, MULTS, 16, 4)
+FIELD(ID_ISAR2, MULTU, 20, 4)
+FIELD(ID_ISAR2, PSR_AR, 24, 4)
+FIELD(ID_ISAR2, REVERSAL, 28, 4)
+
+FIELD(ID_ISAR3, SATURATE, 0, 4)
+FIELD(ID_ISAR3, SIMD, 4, 4)
+FIELD(ID_ISAR3, SVC, 8, 4)
+FIELD(ID_ISAR3, SYNCHPRIM, 12, 4)
+FIELD(ID_ISAR3, TABBRANCH, 16, 4)
+FIELD(ID_ISAR3, T32COPY, 20, 4)
+FIELD(ID_ISAR3, TRUENOP, 24, 4)
+FIELD(ID_ISAR3, T32EE, 28, 4)
+
+FIELD(ID_ISAR4, UNPRIV, 0, 4)
+FIELD(ID_ISAR4, WITHSHIFTS, 4, 4)
+FIELD(ID_ISAR4, WRITEBACK, 8, 4)
+FIELD(ID_ISAR4, SMC, 12, 4)
+FIELD(ID_ISAR4, BARRIER, 16, 4)
+FIELD(ID_ISAR4, SYNCHPRIM_FRAC, 20, 4)
+FIELD(ID_ISAR4, PSR_M, 24, 4)
+FIELD(ID_ISAR4, SWP_FRAC, 28, 4)
+
+FIELD(ID_ISAR5, SEVL, 0, 4)
+FIELD(ID_ISAR5, AES, 4, 4)
+FIELD(ID_ISAR5, SHA1, 8, 4)
+FIELD(ID_ISAR5, SHA2, 12, 4)
+FIELD(ID_ISAR5, CRC32, 16, 4)
+FIELD(ID_ISAR5, RDM, 24, 4)
+FIELD(ID_ISAR5, VCMA, 28, 4)
+
+FIELD(ID_ISAR6, JSCVT, 0, 4)
+FIELD(ID_ISAR6, DP, 4, 4)
+FIELD(ID_ISAR6, FHM, 8, 4)
+FIELD(ID_ISAR6, SB, 12, 4)
+FIELD(ID_ISAR6, SPECRES, 16, 4)
+
+FIELD(ID_AA64ISAR0, AES, 4, 4)
+FIELD(ID_AA64ISAR0, SHA1, 8, 4)
+FIELD(ID_AA64ISAR0, SHA2, 12, 4)
+FIELD(ID_AA64ISAR0, CRC32, 16, 4)
+FIELD(ID_AA64ISAR0, ATOMIC, 20, 4)
+FIELD(ID_AA64ISAR0, RDM, 28, 4)
+FIELD(ID_AA64ISAR0, SHA3, 32, 4)
+FIELD(ID_AA64ISAR0, SM3, 36, 4)
+FIELD(ID_AA64ISAR0, SM4, 40, 4)
+FIELD(ID_AA64ISAR0, DP, 44, 4)
+FIELD(ID_AA64ISAR0, FHM, 48, 4)
+FIELD(ID_AA64ISAR0, TS, 52, 4)
+FIELD(ID_AA64ISAR0, TLB, 56, 4)
+FIELD(ID_AA64ISAR0, RNDR, 60, 4)
+
+FIELD(ID_AA64ISAR1, DPB, 0, 4)
+FIELD(ID_AA64ISAR1, APA, 4, 4)
+FIELD(ID_AA64ISAR1, API, 8, 4)
+FIELD(ID_AA64ISAR1, JSCVT, 12, 4)
+FIELD(ID_AA64ISAR1, FCMA, 16, 4)
+FIELD(ID_AA64ISAR1, LRCPC, 20, 4)
+FIELD(ID_AA64ISAR1, GPA, 24, 4)
+FIELD(ID_AA64ISAR1, GPI, 28, 4)
+FIELD(ID_AA64ISAR1, FRINTTS, 32, 4)
+FIELD(ID_AA64ISAR1, SB, 36, 4)
+FIELD(ID_AA64ISAR1, SPECRES, 40, 4)
+
QEMU_BUILD_BUG_ON(ARRAY_SIZE(((ARMCPU *)0)->ccsidr) <= R_V7M_CSSELR_INDEX_MASK);
/* If adding a feature bit which corresponds to a Linux ELF
--
2.17.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH v3 03/10] target/arm: Convert v8 extensions from feature bits to isar tests
2018-10-08 21:21 [Qemu-devel] [PATCH v3 00/10] target/arm: Rely on id regs instead of features Richard Henderson
2018-10-08 21:21 ` [Qemu-devel] [PATCH v3 01/10] target/arm: Fix aarch64_sve_change_el wrt EL0 Richard Henderson
2018-10-08 21:21 ` [Qemu-devel] [PATCH v3 02/10] target/arm: Define fields of ISAR registers Richard Henderson
@ 2018-10-08 21:21 ` Richard Henderson
2018-10-16 10:40 ` Peter Maydell
2018-10-08 21:21 ` [Qemu-devel] [PATCH v3 04/10] target/arm: Align cortex-r5 id_isar0 Richard Henderson
` (7 subsequent siblings)
10 siblings, 1 reply; 17+ messages in thread
From: Richard Henderson @ 2018-10-08 21:21 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell
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.
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
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 | 27 +++++---
target/arm/cpu64.c | 52 ++++++++++------
target/arm/translate-a64.c | 101 +++++++++++++++---------------
target/arm/translate.c | 36 +++++------
8 files changed, 294 insertions(+), 127 deletions(-)
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index f00c0444c4..66eaa40ed9 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1573,30 +1573,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 */
};
@@ -3148,4 +3136,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 c1b65f3efb..1d60569583 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;
@@ -190,4 +191,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 10bca65b99..571beca8fd 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..b7d9942aa3 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1827,17 +1827,26 @@ 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);
+ {
+ uint32_t t;
+
+ t = cpu->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->id_isar5 = t;
+
+ t = cpu->id_isar6;
+ t = FIELD_DP32(t, ID_ISAR6, DP, 1);
+ cpu->id_isar6 = t;
+ }
#endif
}
}
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index db71504cb5..a0cc29d356 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);
@@ -253,7 +243,41 @@ static void aarch64_max_initfn(Object *obj)
if (kvm_enabled()) {
kvm_arm_set_cpu_features_from_host(cpu);
} else {
+ uint64_t t;
+ uint32_t u;
aarch64_a57_initfn(obj);
+
+ t = cpu->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->id_aa64isar0 = t;
+
+ t = cpu->id_aa64isar1;
+ t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 1);
+ cpu->id_aa64isar1 = t;
+
+ /* Replicate the same data to the 32-bit id registers. */
+ u = cpu->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->id_isar5 = u;
+
+ u = cpu->id_isar6;
+ u = FIELD_DP32(u, ID_ISAR6, DP, 1);
+ cpu->id_isar6 = u;
+
#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 +285,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 8a24278d79..55a050dc50 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -2322,7 +2322,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;
@@ -2344,7 +2344,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;
@@ -2355,7 +2355,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;
}
@@ -2894,11 +2894,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;
}
@@ -2934,10 +2933,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);
@@ -4568,7 +4563,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);
@@ -8612,7 +8607,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) */
@@ -8621,13 +8616,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;
}
@@ -10356,7 +10351,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;
}
@@ -11408,7 +11403,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) */
@@ -11417,7 +11413,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) */
@@ -11425,7 +11421,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 */
@@ -11439,13 +11435,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;
}
@@ -12659,14 +12655,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;
}
@@ -12675,7 +12671,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;
}
@@ -13202,8 +13198,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;
}
@@ -13260,7 +13255,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);
@@ -13273,23 +13268,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;
}
@@ -13330,7 +13328,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) {
@@ -13340,15 +13338,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:
@@ -13356,7 +13354,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;
}
@@ -13387,40 +13385,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:
@@ -13429,7 +13427,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;
}
@@ -13488,16 +13486,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:
@@ -13505,7 +13503,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;
}
@@ -13536,22 +13534,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;
}
@@ -13638,7 +13636,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;
}
@@ -13684,7 +13682,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;
}
@@ -13833,6 +13831,7 @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
ARMCPU *arm_cpu = arm_env_get_cpu(env);
int bound;
+ dc->cpu = arm_cpu;
dc->pc = dc->base.pc_first;
dc->condjmp = 0;
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 1b4bacb522..ea8545c43b 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -5689,7 +5689,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),
@@ -5763,7 +5763,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);
@@ -5773,7 +5773,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);
@@ -6768,7 +6768,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();
@@ -7085,7 +7085,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)) {
@@ -7359,8 +7359,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);
@@ -7381,8 +7380,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);
@@ -7399,10 +7397,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);
@@ -7813,7 +7811,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;
}
@@ -7822,7 +7820,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;
}
@@ -7830,7 +7828,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;
@@ -7892,7 +7890,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) {
@@ -7913,7 +7911,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;
@@ -8889,8 +8887,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;
}
@@ -10785,7 +10782,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;
@@ -12586,6 +12583,7 @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
CPUARMState *env = cs->env_ptr;
ARMCPU *cpu = arm_env_get_cpu(env);
+ dc->cpu = cpu;
dc->pc = dc->base.pc_first;
dc->condjmp = 0;
--
2.17.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] [PATCH v3 03/10] target/arm: Convert v8 extensions from feature bits to isar tests
2018-10-08 21:21 ` [Qemu-devel] [PATCH v3 03/10] target/arm: Convert v8 extensions from feature bits to isar tests Richard Henderson
@ 2018-10-16 10:40 ` Peter Maydell
2018-10-16 16:06 ` Richard Henderson
0 siblings, 1 reply; 17+ messages in thread
From: Peter Maydell @ 2018-10-16 10:40 UTC (permalink / raw)
To: Richard Henderson; +Cc: QEMU Developers
On 8 October 2018 at 22:21, Richard Henderson
<richard.henderson@linaro.org> 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.
>
> Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> diff --git a/target/arm/translate.h b/target/arm/translate.h
> index c1b65f3efb..1d60569583 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 */
The translate code is not supposed to have access to either ARMCPU
or the ARMCPUState env pointer. Putting a pointer to cpu into the
DisasContext defeats this. This is why aarch64_tr_init_disas_context()
and the 32-bit equivalent extract all the info they need from
arm_cpu and env and put it into DisasContext fields.
thanks
-- PMM
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] [PATCH v3 03/10] target/arm: Convert v8 extensions from feature bits to isar tests
2018-10-16 10:40 ` Peter Maydell
@ 2018-10-16 16:06 ` Richard Henderson
0 siblings, 0 replies; 17+ messages in thread
From: Richard Henderson @ 2018-10-16 16:06 UTC (permalink / raw)
To: Peter Maydell; +Cc: QEMU Developers
On 10/16/18 3:40 AM, Peter Maydell wrote:
> On 8 October 2018 at 22:21, Richard Henderson
> <richard.henderson@linaro.org> 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.
>>
>> Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
>> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
>
>> diff --git a/target/arm/translate.h b/target/arm/translate.h
>> index c1b65f3efb..1d60569583 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 */
>
> The translate code is not supposed to have access to either ARMCPU
> or the ARMCPUState env pointer. Putting a pointer to cpu into the
> DisasContext defeats this. This is why aarch64_tr_init_disas_context()
> and the 32-bit equivalent extract all the info they need from
> arm_cpu and env and put it into DisasContext fields.
I know that.
I also know that if we don't do it this way, then we need to duplicate all of
the routines that query the ID registers. I think this way is cleaner.
We simply have to be vigilant about how ctx->cpu is used otherwise.
r~
^ permalink raw reply [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH v3 04/10] target/arm: Align cortex-r5 id_isar0
2018-10-08 21:21 [Qemu-devel] [PATCH v3 00/10] target/arm: Rely on id regs instead of features Richard Henderson
` (2 preceding siblings ...)
2018-10-08 21:21 ` [Qemu-devel] [PATCH v3 03/10] target/arm: Convert v8 extensions from feature bits to isar tests Richard Henderson
@ 2018-10-08 21:21 ` Richard Henderson
2018-10-08 21:22 ` [Qemu-devel] [PATCH v3 05/10] target/arm: Fix cortex-a7 id_isar0 Richard Henderson
` (6 subsequent siblings)
10 siblings, 0 replies; 17+ messages in thread
From: Richard Henderson @ 2018-10-08 21:21 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell
The missing nibble made it more difficult to read.
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/arm/cpu.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index b7d9942aa3..ac46641541 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1397,7 +1397,7 @@ static void cortex_r5_initfn(Object *obj)
cpu->id_mmfr1 = 0x00000000;
cpu->id_mmfr2 = 0x01200000;
cpu->id_mmfr3 = 0x0211;
- cpu->id_isar0 = 0x2101111;
+ cpu->id_isar0 = 0x02101111;
cpu->id_isar1 = 0x13112111;
cpu->id_isar2 = 0x21232141;
cpu->id_isar3 = 0x01112131;
--
2.17.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH v3 05/10] target/arm: Fix cortex-a7 id_isar0
2018-10-08 21:21 [Qemu-devel] [PATCH v3 00/10] target/arm: Rely on id regs instead of features Richard Henderson
` (3 preceding siblings ...)
2018-10-08 21:21 ` [Qemu-devel] [PATCH v3 04/10] target/arm: Align cortex-r5 id_isar0 Richard Henderson
@ 2018-10-08 21:22 ` Richard Henderson
2018-10-08 21:22 ` [Qemu-devel] [PATCH v3 06/10] target/arm: Convert division from feature bits to isar0 tests Richard Henderson
` (5 subsequent siblings)
10 siblings, 0 replies; 17+ messages in thread
From: Richard Henderson @ 2018-10-08 21:22 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell
The incorrect value advertised only thumb2 div without arm div.
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/arm/cpu.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index ac46641541..83a6cb535f 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1587,7 +1587,10 @@ static void cortex_a7_initfn(Object *obj)
cpu->id_mmfr1 = 0x40000000;
cpu->id_mmfr2 = 0x01240000;
cpu->id_mmfr3 = 0x02102211;
- cpu->id_isar0 = 0x01101110;
+ /* a7_mpcore_r0p5_trm, page 4-4 gives 0x01101110; but
+ * table 4-41 gives 0x02101110, which includes the arm div insns.
+ */
+ cpu->id_isar0 = 0x02101110;
cpu->id_isar1 = 0x13112111;
cpu->id_isar2 = 0x21232041;
cpu->id_isar3 = 0x11112131;
--
2.17.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH v3 06/10] target/arm: Convert division from feature bits to isar0 tests
2018-10-08 21:21 [Qemu-devel] [PATCH v3 00/10] target/arm: Rely on id regs instead of features Richard Henderson
` (4 preceding siblings ...)
2018-10-08 21:22 ` [Qemu-devel] [PATCH v3 05/10] target/arm: Fix cortex-a7 id_isar0 Richard Henderson
@ 2018-10-08 21:22 ` Richard Henderson
2018-10-08 21:22 ` [Qemu-devel] [PATCH v3 07/10] target/arm: Convert jazelle from feature bit to isar1 test Richard Henderson
` (4 subsequent siblings)
10 siblings, 0 replies; 17+ messages in thread
From: Richard Henderson @ 2018-10-08 21:22 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell
Both arm and thumb2 division are controlled by the same ISAR field,
which takes care of the arm implies thumb case. Having M imply
thumb2 division was wrong for cortex-m0, which is v6m and does not
have thumb2 at all, much less thumb2 division.
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/arm/cpu.h | 12 ++++++++++--
target/arm/translate.h | 2 ++
linux-user/elfload.c | 4 ++--
target/arm/cpu.c | 10 +---------
target/arm/translate.c | 4 ++--
5 files changed, 17 insertions(+), 15 deletions(-)
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 66eaa40ed9..2af971e823 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1550,7 +1550,6 @@ enum arm_features {
ARM_FEATURE_VFP3,
ARM_FEATURE_VFP_FP16,
ARM_FEATURE_NEON,
- ARM_FEATURE_THUMB_DIV, /* divide supported in Thumb encoding */
ARM_FEATURE_M, /* Microcontroller profile. */
ARM_FEATURE_OMAPCP, /* OMAP specific CP15 ops handling. */
ARM_FEATURE_THUMB2EE,
@@ -1560,7 +1559,6 @@ enum arm_features {
ARM_FEATURE_V5,
ARM_FEATURE_STRONGARM,
ARM_FEATURE_VAPA, /* cp15 VA to PA lookups */
- ARM_FEATURE_ARM_DIV, /* divide supported in ARM encoding */
ARM_FEATURE_VFP4, /* VFPv4 (implies that NEON is v2) */
ARM_FEATURE_GENERIC_TIMER,
ARM_FEATURE_MVFR, /* Media and VFP Feature Registers 0 and 1 */
@@ -3139,6 +3137,16 @@ extern const uint64_t pred_esz_masks[4];
/*
* 32-bit feature tests via id registers.
*/
+static inline bool aa32_feature_thumb_div(ARMCPU *cpu)
+{
+ return FIELD_EX32(cpu->id_isar0, ID_ISAR0, DIVIDE) != 0;
+}
+
+static inline bool aa32_feature_arm_div(ARMCPU *cpu)
+{
+ return FIELD_EX32(cpu->id_isar0, ID_ISAR0, DIVIDE) > 1;
+}
+
static inline bool aa32_feature_aes(ARMCPU *cpu)
{
return FIELD_EX32(cpu->id_isar5, ID_ISAR5, AES) != 0;
diff --git a/target/arm/translate.h b/target/arm/translate.h
index 1d60569583..8279465d1d 100644
--- a/target/arm/translate.h
+++ b/target/arm/translate.h
@@ -195,6 +195,8 @@ static inline TCGv_i32 get_ahp_flag(void)
static inline bool aa32_dc_feature_##NAME(DisasContext *dc) \
{ return aa32_feature_##NAME(dc->cpu); }
+FORWARD_FEATURE(thumb_div)
+FORWARD_FEATURE(arm_div)
FORWARD_FEATURE(aes)
FORWARD_FEATURE(pmull)
FORWARD_FEATURE(sha1)
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 571beca8fd..9b00e977d8 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -471,8 +471,8 @@ static uint32_t get_elf_hwcap(void)
GET_FEATURE(ARM_FEATURE_VFP3, ARM_HWCAP_ARM_VFPv3);
GET_FEATURE(ARM_FEATURE_V6K, ARM_HWCAP_ARM_TLS);
GET_FEATURE(ARM_FEATURE_VFP4, ARM_HWCAP_ARM_VFPv4);
- GET_FEATURE(ARM_FEATURE_ARM_DIV, ARM_HWCAP_ARM_IDIVA);
- GET_FEATURE(ARM_FEATURE_THUMB_DIV, ARM_HWCAP_ARM_IDIVT);
+ GET_FEATURE_ID(arm_div, ARM_HWCAP_ARM_IDIVA);
+ GET_FEATURE_ID(thumb_div, ARM_HWCAP_ARM_IDIVT);
/* All QEMU's VFPv3 CPUs have 32 registers, see VFP_DREG in translate.c.
* Note that the ARM_HWCAP_ARM_VFPv3D16 bit is always the inverse of
* ARM_HWCAP_ARM_VFPD32 (and so always clear for QEMU); it is unrelated
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 83a6cb535f..f068b4c476 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -825,7 +825,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
* Presence of EL2 itself is ARM_FEATURE_EL2, and of the
* Security Extensions is ARM_FEATURE_EL3.
*/
- set_feature(env, ARM_FEATURE_ARM_DIV);
+ assert(aa32_feature_arm_div(cpu));
set_feature(env, ARM_FEATURE_LPAE);
set_feature(env, ARM_FEATURE_V7);
}
@@ -858,12 +858,6 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
if (arm_feature(env, ARM_FEATURE_V5)) {
set_feature(env, ARM_FEATURE_V4T);
}
- if (arm_feature(env, ARM_FEATURE_M)) {
- set_feature(env, ARM_FEATURE_THUMB_DIV);
- }
- if (arm_feature(env, ARM_FEATURE_ARM_DIV)) {
- set_feature(env, ARM_FEATURE_THUMB_DIV);
- }
if (arm_feature(env, ARM_FEATURE_VFP4)) {
set_feature(env, ARM_FEATURE_VFP3);
set_feature(env, ARM_FEATURE_VFP_FP16);
@@ -1384,8 +1378,6 @@ static void cortex_r5_initfn(Object *obj)
ARMCPU *cpu = ARM_CPU(obj);
set_feature(&cpu->env, ARM_FEATURE_V7);
- set_feature(&cpu->env, ARM_FEATURE_THUMB_DIV);
- set_feature(&cpu->env, ARM_FEATURE_ARM_DIV);
set_feature(&cpu->env, ARM_FEATURE_V7MP);
set_feature(&cpu->env, ARM_FEATURE_PMSA);
cpu->midr = 0x411fc153; /* r1p3 */
diff --git a/target/arm/translate.c b/target/arm/translate.c
index ea8545c43b..b1ee6533cc 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -9755,7 +9755,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
case 1:
case 3:
/* SDIV, UDIV */
- if (!arm_dc_feature(s, ARM_FEATURE_ARM_DIV)) {
+ if (!aa32_dc_feature_arm_div(s)) {
goto illegal_op;
}
if (((insn >> 5) & 7) || (rd != 15)) {
@@ -10963,7 +10963,7 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
tmp2 = load_reg(s, rm);
if ((op & 0x50) == 0x10) {
/* sdiv, udiv */
- if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DIV)) {
+ if (!aa32_dc_feature_thumb_div(s)) {
goto illegal_op;
}
if (op & 0x20)
--
2.17.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH v3 07/10] target/arm: Convert jazelle from feature bit to isar1 test
2018-10-08 21:21 [Qemu-devel] [PATCH v3 00/10] target/arm: Rely on id regs instead of features Richard Henderson
` (5 preceding siblings ...)
2018-10-08 21:22 ` [Qemu-devel] [PATCH v3 06/10] target/arm: Convert division from feature bits to isar0 tests Richard Henderson
@ 2018-10-08 21:22 ` Richard Henderson
2018-10-08 21:22 ` [Qemu-devel] [PATCH v3 08/10] target/arm: Convert t32ee from feature bit to isar3 test Richard Henderson
` (3 subsequent siblings)
10 siblings, 0 replies; 17+ messages in thread
From: Richard Henderson @ 2018-10-08 21:22 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell
Having V6 alone imply jazelle was wrong for cortex-m0.
Change to an assertion for V6 & !M.
This was harmless, because the only place we tested ARM_FEATURE_JAZELLE
was for 'bxj' in disas_arm(), which is unreachable for M-profile cores.
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/arm/cpu.h | 6 +++++-
target/arm/translate.h | 1 +
target/arm/cpu.c | 17 ++++++++++++++---
target/arm/translate.c | 2 +-
4 files changed, 21 insertions(+), 5 deletions(-)
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 2af971e823..557ef8daf9 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1580,7 +1580,6 @@ enum arm_features {
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_FP16, /* implements v8.2 half-precision float */
ARM_FEATURE_M_MAIN, /* M profile Main Extension */
@@ -3147,6 +3146,11 @@ static inline bool aa32_feature_arm_div(ARMCPU *cpu)
return FIELD_EX32(cpu->id_isar0, ID_ISAR0, DIVIDE) > 1;
}
+static inline bool aa32_feature_jazelle(ARMCPU *cpu)
+{
+ return FIELD_EX32(cpu->id_isar1, ID_ISAR1, JAZELLE) != 0;
+}
+
static inline bool aa32_feature_aes(ARMCPU *cpu)
{
return FIELD_EX32(cpu->id_isar5, ID_ISAR5, AES) != 0;
diff --git a/target/arm/translate.h b/target/arm/translate.h
index 8279465d1d..bd394bdf69 100644
--- a/target/arm/translate.h
+++ b/target/arm/translate.h
@@ -197,6 +197,7 @@ static inline TCGv_i32 get_ahp_flag(void)
FORWARD_FEATURE(thumb_div)
FORWARD_FEATURE(arm_div)
+FORWARD_FEATURE(jazelle)
FORWARD_FEATURE(aes)
FORWARD_FEATURE(pmull)
FORWARD_FEATURE(sha1)
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index f068b4c476..4e2609aa7e 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -850,8 +850,8 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
}
if (arm_feature(env, ARM_FEATURE_V6)) {
set_feature(env, ARM_FEATURE_V5);
- set_feature(env, ARM_FEATURE_JAZELLE);
if (!arm_feature(env, ARM_FEATURE_M)) {
+ assert(aa32_feature_jazelle(cpu));
set_feature(env, ARM_FEATURE_AUXCR);
}
}
@@ -1078,11 +1078,16 @@ static void arm926_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_VFP);
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
set_feature(&cpu->env, ARM_FEATURE_CACHE_TEST_CLEAN);
- set_feature(&cpu->env, ARM_FEATURE_JAZELLE);
cpu->midr = 0x41069265;
cpu->reset_fpsid = 0x41011090;
cpu->ctr = 0x1dd20d2;
cpu->reset_sctlr = 0x00090078;
+
+ /*
+ * ARMv5 does not have the ID_ISAR registers, but we can still
+ * set the field to indicate Jazelle support within QEMU.
+ */
+ cpu->id_isar1 = FIELD_DP32(cpu->id_isar1, ID_ISAR1, JAZELLE, 1);
}
static void arm946_initfn(Object *obj)
@@ -1108,12 +1113,18 @@ static void arm1026_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_AUXCR);
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
set_feature(&cpu->env, ARM_FEATURE_CACHE_TEST_CLEAN);
- set_feature(&cpu->env, ARM_FEATURE_JAZELLE);
cpu->midr = 0x4106a262;
cpu->reset_fpsid = 0x410110a0;
cpu->ctr = 0x1dd20d2;
cpu->reset_sctlr = 0x00090078;
cpu->reset_auxcr = 1;
+
+ /*
+ * ARMv5 does not have the ID_ISAR registers, but we can still
+ * set the field to indicate Jazelle support within QEMU.
+ */
+ cpu->id_isar1 = FIELD_DP32(cpu->id_isar1, ID_ISAR1, JAZELLE, 1);
+
{
/* The 1026 had an IFAR at c6,c0,0,1 rather than the ARMv6 c6,c0,0,2 */
ARMCPRegInfo ifar = {
diff --git a/target/arm/translate.c b/target/arm/translate.c
index b1ee6533cc..54ecf369cb 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -42,7 +42,7 @@
#define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5)
/* currently all emulated v5 cores are also v5TE, so don't bother */
#define ENABLE_ARCH_5TE arm_dc_feature(s, ARM_FEATURE_V5)
-#define ENABLE_ARCH_5J arm_dc_feature(s, ARM_FEATURE_JAZELLE)
+#define ENABLE_ARCH_5J aa32_dc_feature_jazelle(s)
#define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6)
#define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K)
#define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2)
--
2.17.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH v3 08/10] target/arm: Convert t32ee from feature bit to isar3 test
2018-10-08 21:21 [Qemu-devel] [PATCH v3 00/10] target/arm: Rely on id regs instead of features Richard Henderson
` (6 preceding siblings ...)
2018-10-08 21:22 ` [Qemu-devel] [PATCH v3 07/10] target/arm: Convert jazelle from feature bit to isar1 test Richard Henderson
@ 2018-10-08 21:22 ` Richard Henderson
2018-10-08 21:22 ` [Qemu-devel] [PATCH v3 09/10] target/arm: Convert sve from feature bit to aa64pfr0 test Richard Henderson
` (2 subsequent siblings)
10 siblings, 0 replies; 17+ messages in thread
From: Richard Henderson @ 2018-10-08 21:22 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/arm/cpu.h | 6 +++++-
linux-user/elfload.c | 2 +-
target/arm/cpu.c | 4 ----
target/arm/helper.c | 2 +-
target/arm/machine.c | 3 +--
5 files changed, 8 insertions(+), 9 deletions(-)
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 557ef8daf9..d8cb9633d2 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1552,7 +1552,6 @@ enum arm_features {
ARM_FEATURE_NEON,
ARM_FEATURE_M, /* Microcontroller profile. */
ARM_FEATURE_OMAPCP, /* OMAP specific CP15 ops handling. */
- ARM_FEATURE_THUMB2EE,
ARM_FEATURE_V7MP, /* v7 Multiprocessing Extensions */
ARM_FEATURE_V7VE, /* v7 Virtualization Extensions (non-EL2 parts) */
ARM_FEATURE_V4T,
@@ -3151,6 +3150,11 @@ static inline bool aa32_feature_jazelle(ARMCPU *cpu)
return FIELD_EX32(cpu->id_isar1, ID_ISAR1, JAZELLE) != 0;
}
+static inline bool aa32_feature_t32ee(ARMCPU *cpu)
+{
+ return FIELD_EX32(cpu->id_isar3, ID_ISAR3, T32EE) != 0;
+}
+
static inline bool aa32_feature_aes(ARMCPU *cpu)
{
return FIELD_EX32(cpu->id_isar5, ID_ISAR5, AES) != 0;
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 9b00e977d8..3061d703b2 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -466,7 +466,7 @@ static uint32_t get_elf_hwcap(void)
GET_FEATURE(ARM_FEATURE_V5, ARM_HWCAP_ARM_EDSP);
GET_FEATURE(ARM_FEATURE_VFP, ARM_HWCAP_ARM_VFP);
GET_FEATURE(ARM_FEATURE_IWMMXT, ARM_HWCAP_ARM_IWMMXT);
- GET_FEATURE(ARM_FEATURE_THUMB2EE, ARM_HWCAP_ARM_THUMBEE);
+ GET_FEATURE_ID(t32ee, ARM_HWCAP_ARM_THUMBEE);
GET_FEATURE(ARM_FEATURE_NEON, ARM_HWCAP_ARM_NEON);
GET_FEATURE(ARM_FEATURE_VFP3, ARM_HWCAP_ARM_VFPv3);
GET_FEATURE(ARM_FEATURE_V6K, ARM_HWCAP_ARM_TLS);
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 4e2609aa7e..f8faea7933 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1436,7 +1436,6 @@ static void cortex_a8_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_V7);
set_feature(&cpu->env, ARM_FEATURE_VFP3);
set_feature(&cpu->env, ARM_FEATURE_NEON);
- set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
set_feature(&cpu->env, ARM_FEATURE_EL3);
cpu->midr = 0x410fc080;
@@ -1505,7 +1504,6 @@ static void cortex_a9_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_VFP3);
set_feature(&cpu->env, ARM_FEATURE_VFP_FP16);
set_feature(&cpu->env, ARM_FEATURE_NEON);
- set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
set_feature(&cpu->env, ARM_FEATURE_EL3);
/* Note that A9 supports the MP extensions even for
* A9UP and single-core A9MP (which are both different
@@ -1568,7 +1566,6 @@ static void cortex_a7_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_V7VE);
set_feature(&cpu->env, ARM_FEATURE_VFP4);
set_feature(&cpu->env, ARM_FEATURE_NEON);
- set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
@@ -1614,7 +1611,6 @@ static void cortex_a15_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_V7VE);
set_feature(&cpu->env, ARM_FEATURE_VFP4);
set_feature(&cpu->env, ARM_FEATURE_NEON);
- set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 0efbb5c76c..0da13175be 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -5356,7 +5356,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
define_arm_cp_regs(cpu, vmsa_pmsa_cp_reginfo);
define_arm_cp_regs(cpu, vmsa_cp_reginfo);
}
- if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
+ if (aa32_feature_t32ee(cpu)) {
define_arm_cp_regs(cpu, t2ee_cp_reginfo);
}
if (arm_feature(env, ARM_FEATURE_GENERIC_TIMER)) {
diff --git a/target/arm/machine.c b/target/arm/machine.c
index ff4ec22bf7..d44e891533 100644
--- a/target/arm/machine.c
+++ b/target/arm/machine.c
@@ -301,9 +301,8 @@ static const VMStateDescription vmstate_m = {
static bool thumb2ee_needed(void *opaque)
{
ARMCPU *cpu = opaque;
- CPUARMState *env = &cpu->env;
- return arm_feature(env, ARM_FEATURE_THUMB2EE);
+ return aa32_feature_t32ee(cpu);
}
static const VMStateDescription vmstate_thumb2ee = {
--
2.17.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH v3 09/10] target/arm: Convert sve from feature bit to aa64pfr0 test
2018-10-08 21:21 [Qemu-devel] [PATCH v3 00/10] target/arm: Rely on id regs instead of features Richard Henderson
` (7 preceding siblings ...)
2018-10-08 21:22 ` [Qemu-devel] [PATCH v3 08/10] target/arm: Convert t32ee from feature bit to isar3 test Richard Henderson
@ 2018-10-08 21:22 ` Richard Henderson
2018-10-08 21:22 ` [Qemu-devel] [PATCH v3 10/10] target/arm: Convert v8.2-fp16 " Richard Henderson
2018-10-16 10:48 ` [Qemu-devel] [PATCH v3 00/10] target/arm: Rely on id regs instead of features Peter Maydell
10 siblings, 0 replies; 17+ messages in thread
From: Richard Henderson @ 2018-10-08 21:22 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/arm/cpu.h | 16 +++++++++++++++-
target/arm/translate-a64.h | 1 +
linux-user/aarch64/signal.c | 4 ++--
linux-user/elfload.c | 2 +-
linux-user/syscall.c | 10 ++++++----
target/arm/cpu64.c | 5 ++++-
target/arm/helper.c | 9 ++++++---
target/arm/machine.c | 3 +--
target/arm/translate-a64.c | 4 ++--
9 files changed, 38 insertions(+), 16 deletions(-)
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index d8cb9633d2..a97b471fff 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1531,6 +1531,16 @@ FIELD(ID_AA64ISAR1, FRINTTS, 32, 4)
FIELD(ID_AA64ISAR1, SB, 36, 4)
FIELD(ID_AA64ISAR1, SPECRES, 40, 4)
+FIELD(ID_AA64PFR0, EL0, 0, 4)
+FIELD(ID_AA64PFR0, EL1, 4, 4)
+FIELD(ID_AA64PFR0, EL2, 8, 4)
+FIELD(ID_AA64PFR0, EL3, 12, 4)
+FIELD(ID_AA64PFR0, FP, 16, 4)
+FIELD(ID_AA64PFR0, ADVSIMD, 20, 4)
+FIELD(ID_AA64PFR0, GIC, 24, 4)
+FIELD(ID_AA64PFR0, RAS, 28, 4)
+FIELD(ID_AA64PFR0, SVE, 32, 4)
+
QEMU_BUILD_BUG_ON(ARRAY_SIZE(((ARMCPU *)0)->ccsidr) <= R_V7M_CSSELR_INDEX_MASK);
/* If adding a feature bit which corresponds to a Linux ELF
@@ -1579,7 +1589,6 @@ enum arm_features {
ARM_FEATURE_PMU, /* has PMU support */
ARM_FEATURE_VBAR, /* has cp15 VBAR */
ARM_FEATURE_M_SECURITY, /* M profile Security Extension */
- ARM_FEATURE_SVE, /* has Scalable Vector Extension */
ARM_FEATURE_V8_FP16, /* implements v8.2 half-precision float */
ARM_FEATURE_M_MAIN, /* M profile Main Extension */
};
@@ -3263,4 +3272,9 @@ static inline bool aa64_feature_fcma(ARMCPU *cpu)
return FIELD_EX64(cpu->id_aa64isar1, ID_AA64ISAR1, FCMA) != 0;
}
+static inline bool aa64_feature_sve(ARMCPU *cpu)
+{
+ return FIELD_EX64(cpu->id_aa64pfr0, ID_AA64PFR0, SVE) != 0;
+}
+
#endif
diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
index b4ef9eb024..636f3fded3 100644
--- a/target/arm/translate-a64.h
+++ b/target/arm/translate-a64.h
@@ -140,6 +140,7 @@ FORWARD_FEATURE(sm3)
FORWARD_FEATURE(sm4)
FORWARD_FEATURE(dp)
FORWARD_FEATURE(fcma)
+FORWARD_FEATURE(sve)
#undef FORWARD_FEATURE
diff --git a/linux-user/aarch64/signal.c b/linux-user/aarch64/signal.c
index 07fedfc33c..65272fb7a9 100644
--- a/linux-user/aarch64/signal.c
+++ b/linux-user/aarch64/signal.c
@@ -314,7 +314,7 @@ static int target_restore_sigframe(CPUARMState *env,
break;
case TARGET_SVE_MAGIC:
- if (arm_feature(env, ARM_FEATURE_SVE)) {
+ if (aa64_feature_sve(arm_env_get_cpu(env))) {
vq = (env->vfp.zcr_el[1] & 0xf) + 1;
sve_size = QEMU_ALIGN_UP(TARGET_SVE_SIG_CONTEXT_SIZE(vq), 16);
if (!sve && size == sve_size) {
@@ -433,7 +433,7 @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
&layout);
/* SVE state needs saving only if it exists. */
- if (arm_feature(env, ARM_FEATURE_SVE)) {
+ if (aa64_feature_sve(arm_env_get_cpu(env))) {
vq = (env->vfp.zcr_el[1] & 0xf) + 1;
sve_size = QEMU_ALIGN_UP(TARGET_SVE_SIG_CONTEXT_SIZE(vq), 16);
sve_ofs = alloc_sigframe_space(sve_size, &layout);
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 3061d703b2..e3585f4cb6 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -593,7 +593,7 @@ static uint32_t get_elf_hwcap(void)
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);
+ GET_FEATURE_ID(sve, ARM_HWCAP_A64_SVE);
#undef GET_FEATURE
#undef GET_FEATURE_ID
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index ae3c0dfef7..37f315ad4a 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -9356,7 +9356,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
* even though the current architectural maximum is VQ=16.
*/
ret = -TARGET_EINVAL;
- if (arm_feature(cpu_env, ARM_FEATURE_SVE)
+ if (aa64_feature_sve(arm_env_get_cpu(cpu_env))
&& arg2 >= 0 && arg2 <= 512 * 16 && !(arg2 & 15)) {
CPUARMState *env = cpu_env;
ARMCPU *cpu = arm_env_get_cpu(env);
@@ -9375,9 +9375,11 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
return ret;
case TARGET_PR_SVE_GET_VL:
ret = -TARGET_EINVAL;
- if (arm_feature(cpu_env, ARM_FEATURE_SVE)) {
- CPUARMState *env = cpu_env;
- ret = ((env->vfp.zcr_el[1] & 0xf) + 1) * 16;
+ {
+ ARMCPU *cpu = arm_env_get_cpu(cpu_env);
+ if (aa64_feature_sve(cpu)) {
+ ret = ((cpu->env.vfp.zcr_el[1] & 0xf) + 1) * 16;
+ }
}
return ret;
#endif /* AARCH64 */
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index a0cc29d356..ee2c04a627 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -264,6 +264,10 @@ static void aarch64_max_initfn(Object *obj)
t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 1);
cpu->id_aa64isar1 = t;
+ t = cpu->id_aa64pfr0;
+ t = FIELD_DP64(t, ID_AA64PFR0, SVE, 1);
+ cpu->id_aa64pfr0 = t;
+
/* Replicate the same data to the 32-bit id registers. */
u = cpu->id_isar5;
u = FIELD_DP32(u, ID_ISAR5, AES, 2); /* AES + PMULL */
@@ -286,7 +290,6 @@ static void aarch64_max_initfn(Object *obj)
* present in either.
*/
set_feature(&cpu->env, ARM_FEATURE_V8_FP16);
- 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/helper.c b/target/arm/helper.c
index 0da13175be..2b981a09e4 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -5615,7 +5615,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
define_one_arm_cp_reg(cpu, &sctlr);
}
- if (arm_feature(env, ARM_FEATURE_SVE)) {
+ if (aa64_feature_sve(cpu)) {
define_one_arm_cp_reg(cpu, &zcr_el1_reginfo);
if (arm_feature(env, ARM_FEATURE_EL2)) {
define_one_arm_cp_reg(cpu, &zcr_el2_reginfo);
@@ -12668,13 +12668,15 @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
uint32_t flags;
if (is_a64(env)) {
+ ARMCPU *cpu = arm_env_get_cpu(env);
+
*pc = env->pc;
flags = ARM_TBFLAG_AARCH64_STATE_MASK;
/* Get control bits for tagged addresses */
flags |= (arm_regime_tbi0(env, mmu_idx) << ARM_TBFLAG_TBI0_SHIFT);
flags |= (arm_regime_tbi1(env, mmu_idx) << ARM_TBFLAG_TBI1_SHIFT);
- if (arm_feature(env, ARM_FEATURE_SVE)) {
+ if (aa64_feature_sve(cpu)) {
int sve_el = sve_exception_el(env, current_el);
uint32_t zcr_len;
@@ -12798,11 +12800,12 @@ void aarch64_sve_narrow_vq(CPUARMState *env, unsigned vq)
void aarch64_sve_change_el(CPUARMState *env, int old_el,
int new_el, bool el0_a64)
{
+ ARMCPU *cpu = arm_env_get_cpu(env);
int old_len, new_len;
bool old_a64, new_a64;
/* Nothing to do if no SVE. */
- if (!arm_feature(env, ARM_FEATURE_SVE)) {
+ if (!aa64_feature_sve(cpu)) {
return;
}
diff --git a/target/arm/machine.c b/target/arm/machine.c
index d44e891533..8b3ba96889 100644
--- a/target/arm/machine.c
+++ b/target/arm/machine.c
@@ -131,9 +131,8 @@ static const VMStateDescription vmstate_iwmmxt = {
static bool sve_needed(void *opaque)
{
ARMCPU *cpu = opaque;
- CPUARMState *env = &cpu->env;
- return arm_feature(env, ARM_FEATURE_SVE);
+ return aa64_feature_sve(cpu);
}
/* The first two words of each Zreg is stored in VFP state. */
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 55a050dc50..448723fbe4 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -173,7 +173,7 @@ void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
cpu_fprintf(f, " FPCR=%08x FPSR=%08x\n",
vfp_get_fpcr(env), vfp_get_fpsr(env));
- if (arm_feature(env, ARM_FEATURE_SVE) && sve_exception_el(env, el) == 0) {
+ if (aa64_feature_sve(cpu) && sve_exception_el(env, el) == 0) {
int j, zcr_len = sve_zcr_len_for_el(env, el);
for (i = 0; i <= FFR_PRED_NUM; i++) {
@@ -13790,7 +13790,7 @@ static void disas_a64_insn(CPUARMState *env, DisasContext *s)
unallocated_encoding(s);
break;
case 0x2:
- if (!arm_dc_feature(s, ARM_FEATURE_SVE) || !disas_sve(s, insn)) {
+ if (!aa64_dc_feature_sve(s) || !disas_sve(s, insn)) {
unallocated_encoding(s);
}
break;
--
2.17.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH v3 10/10] target/arm: Convert v8.2-fp16 from feature bit to aa64pfr0 test
2018-10-08 21:21 [Qemu-devel] [PATCH v3 00/10] target/arm: Rely on id regs instead of features Richard Henderson
` (8 preceding siblings ...)
2018-10-08 21:22 ` [Qemu-devel] [PATCH v3 09/10] target/arm: Convert sve from feature bit to aa64pfr0 test Richard Henderson
@ 2018-10-08 21:22 ` Richard Henderson
2018-10-16 10:36 ` Peter Maydell
2018-10-16 10:48 ` [Qemu-devel] [PATCH v3 00/10] target/arm: Rely on id regs instead of features Peter Maydell
10 siblings, 1 reply; 17+ messages in thread
From: Richard Henderson @ 2018-10-08 21:22 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/arm/cpu.h | 17 +++++++++++++++-
target/arm/translate-a64.h | 1 +
target/arm/translate.h | 1 +
linux-user/elfload.c | 6 +-----
target/arm/cpu64.c | 9 ++-------
target/arm/helper.c | 2 +-
target/arm/translate-a64.c | 40 +++++++++++++++++++-------------------
target/arm/translate.c | 6 +++---
8 files changed, 45 insertions(+), 37 deletions(-)
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index a97b471fff..1c880b0c29 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1589,7 +1589,6 @@ enum arm_features {
ARM_FEATURE_PMU, /* has PMU support */
ARM_FEATURE_VBAR, /* has cp15 VBAR */
ARM_FEATURE_M_SECURITY, /* M profile Security Extension */
- ARM_FEATURE_V8_FP16, /* implements v8.2 half-precision float */
ARM_FEATURE_M_MAIN, /* M profile Main Extension */
};
@@ -3204,6 +3203,16 @@ static inline bool aa32_feature_dp(ARMCPU *cpu)
return FIELD_EX32(cpu->id_isar6, ID_ISAR6, DP) != 0;
}
+static inline bool aa32_feature_fp16_arith(ARMCPU *cpu)
+{
+ /*
+ * This is a placeholder for use by VCMA until the rest of
+ * the ARMv8.2-FP16 extension is implemented for aa32 mode.
+ * At which point we can properly set and check MVFR1.FPHP.
+ */
+ return FIELD_EX64(cpu->id_aa64pfr0, ID_AA64PFR0, FP) == 1;
+}
+
/*
* 64-bit feature tests via id registers.
*/
@@ -3272,6 +3281,12 @@ static inline bool aa64_feature_fcma(ARMCPU *cpu)
return FIELD_EX64(cpu->id_aa64isar1, ID_AA64ISAR1, FCMA) != 0;
}
+static inline bool aa64_feature_fp16(ARMCPU *cpu)
+{
+ /* We always set the AdvSIMD and FP fields identically wrt FP16. */
+ return FIELD_EX64(cpu->id_aa64pfr0, ID_AA64PFR0, FP) == 1;
+}
+
static inline bool aa64_feature_sve(ARMCPU *cpu)
{
return FIELD_EX64(cpu->id_aa64pfr0, ID_AA64PFR0, SVE) != 0;
diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
index 636f3fded3..e122cef242 100644
--- a/target/arm/translate-a64.h
+++ b/target/arm/translate-a64.h
@@ -140,6 +140,7 @@ FORWARD_FEATURE(sm3)
FORWARD_FEATURE(sm4)
FORWARD_FEATURE(dp)
FORWARD_FEATURE(fcma)
+FORWARD_FEATURE(fp16)
FORWARD_FEATURE(sve)
#undef FORWARD_FEATURE
diff --git a/target/arm/translate.h b/target/arm/translate.h
index bd394bdf69..ad911de98c 100644
--- a/target/arm/translate.h
+++ b/target/arm/translate.h
@@ -206,6 +206,7 @@ FORWARD_FEATURE(crc32)
FORWARD_FEATURE(rdm)
FORWARD_FEATURE(vcma)
FORWARD_FEATURE(dp)
+FORWARD_FEATURE(fp16_arith)
#undef FORWARD_FEATURE
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index e3585f4cb6..d041ef9d49 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -573,8 +573,6 @@ static uint32_t get_elf_hwcap(void)
hwcaps |= ARM_HWCAP_A64_ASIMD;
/* 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 (aa64_feature_##feat(cpu)) { hwcaps |= hwcap; } } while (0)
@@ -587,15 +585,13 @@ static uint32_t get_elf_hwcap(void)
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_ID(fp16, ARM_HWCAP_A64_FPHP | ARM_HWCAP_A64_ASIMDHP);
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_ID(sve, ARM_HWCAP_A64_SVE);
-#undef GET_FEATURE
#undef GET_FEATURE_ID
return hwcaps;
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index ee2c04a627..38e9afef3b 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -266,6 +266,8 @@ static void aarch64_max_initfn(Object *obj)
t = cpu->id_aa64pfr0;
t = FIELD_DP64(t, ID_AA64PFR0, SVE, 1);
+ t = FIELD_DP64(t, ID_AA64PFR0, FP, 1);
+ t = FIELD_DP64(t, ID_AA64PFR0, ADVSIMD, 1);
cpu->id_aa64pfr0 = t;
/* Replicate the same data to the 32-bit id registers. */
@@ -283,13 +285,6 @@ static void aarch64_max_initfn(Object *obj)
cpu->id_isar6 = u;
#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,
- * and in some cases they're only available in AArch64 and not AArch32,
- * whereas the architecture requires them to be present in both if
- * present in either.
- */
- set_feature(&cpu->env, ARM_FEATURE_V8_FP16);
/* 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/helper.c b/target/arm/helper.c
index 2b981a09e4..834382575e 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -11609,7 +11609,7 @@ void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val)
uint32_t changed;
/* When ARMv8.2-FP16 is not supported, FZ16 is RES0. */
- if (!arm_feature(env, ARM_FEATURE_V8_FP16)) {
+ if (!aa64_feature_fp16(arm_env_get_cpu(env))) {
val &= ~FPCR_FZ16;
}
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 448723fbe4..c403b12eb9 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -4805,7 +4805,7 @@ static void disas_fp_compare(DisasContext *s, uint32_t insn)
break;
case 3:
size = MO_16;
- if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
+ if (aa64_dc_feature_fp16(s)) {
break;
}
/* fallthru */
@@ -4856,7 +4856,7 @@ static void disas_fp_ccomp(DisasContext *s, uint32_t insn)
break;
case 3:
size = MO_16;
- if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
+ if (aa64_dc_feature_fp16(s)) {
break;
}
/* fallthru */
@@ -4922,7 +4922,7 @@ static void disas_fp_csel(DisasContext *s, uint32_t insn)
break;
case 3:
sz = MO_16;
- if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
+ if (aa64_dc_feature_fp16(s)) {
break;
}
/* fallthru */
@@ -5255,7 +5255,7 @@ static void disas_fp_1src(DisasContext *s, uint32_t insn)
handle_fp_1src_double(s, opcode, rd, rn);
break;
case 3:
- if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
+ if (!aa64_dc_feature_fp16(s)) {
unallocated_encoding(s);
return;
}
@@ -5470,7 +5470,7 @@ static void disas_fp_2src(DisasContext *s, uint32_t insn)
handle_fp_2src_double(s, opcode, rd, rn, rm);
break;
case 3:
- if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
+ if (!aa64_dc_feature_fp16(s)) {
unallocated_encoding(s);
return;
}
@@ -5628,7 +5628,7 @@ static void disas_fp_3src(DisasContext *s, uint32_t insn)
handle_fp_3src_double(s, o0, o1, rd, rn, rm, ra);
break;
case 3:
- if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
+ if (!aa64_dc_feature_fp16(s)) {
unallocated_encoding(s);
return;
}
@@ -5698,7 +5698,7 @@ static void disas_fp_imm(DisasContext *s, uint32_t insn)
break;
case 3:
sz = MO_16;
- if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
+ if (aa64_dc_feature_fp16(s)) {
break;
}
/* fallthru */
@@ -5923,7 +5923,7 @@ static void disas_fp_fixed_conv(DisasContext *s, uint32_t insn)
case 1: /* float64 */
break;
case 3: /* float16 */
- if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
+ if (aa64_dc_feature_fp16(s)) {
break;
}
/* fallthru */
@@ -6053,7 +6053,7 @@ static void disas_fp_int_conv(DisasContext *s, uint32_t insn)
break;
case 0x6: /* 16-bit float, 32-bit int */
case 0xe: /* 16-bit float, 64-bit int */
- if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
+ if (aa64_dc_feature_fp16(s)) {
break;
}
/* fallthru */
@@ -6080,7 +6080,7 @@ static void disas_fp_int_conv(DisasContext *s, uint32_t insn)
case 1: /* float64 */
break;
case 3: /* float16 */
- if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
+ if (aa64_dc_feature_fp16(s)) {
break;
}
/* fallthru */
@@ -6517,7 +6517,7 @@ static void disas_simd_across_lanes(DisasContext *s, uint32_t insn)
*/
is_min = extract32(size, 1, 1);
is_fp = true;
- if (!is_u && arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
+ if (!is_u && aa64_dc_feature_fp16(s)) {
size = 1;
} else if (!is_u || !is_q || extract32(size, 0, 1)) {
unallocated_encoding(s);
@@ -6913,7 +6913,7 @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
if (o2 != 0 || ((cmode == 0xf) && is_neg && !is_q)) {
/* Check for FMOV (vector, immediate) - half-precision */
- if (!(arm_dc_feature(s, ARM_FEATURE_V8_FP16) && o2 && cmode == 0xf)) {
+ if (!(aa64_dc_feature_fp16(s) && o2 && cmode == 0xf)) {
unallocated_encoding(s);
return;
}
@@ -7080,7 +7080,7 @@ static void disas_simd_scalar_pairwise(DisasContext *s, uint32_t insn)
case 0x2f: /* FMINP */
/* FP op, size[0] is 32 or 64 bit*/
if (!u) {
- if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
+ if (!aa64_dc_feature_fp16(s)) {
unallocated_encoding(s);
return;
} else {
@@ -7725,7 +7725,7 @@ static void handle_simd_shift_intfp_conv(DisasContext *s, bool is_scalar,
size = MO_32;
} else if (immh & 2) {
size = MO_16;
- if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
+ if (!aa64_dc_feature_fp16(s)) {
unallocated_encoding(s);
return;
}
@@ -7770,7 +7770,7 @@ static void handle_simd_shift_fpint_conv(DisasContext *s, bool is_scalar,
size = MO_32;
} else if (immh & 0x2) {
size = MO_16;
- if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
+ if (!aa64_dc_feature_fp16(s)) {
unallocated_encoding(s);
return;
}
@@ -8534,7 +8534,7 @@ static void disas_simd_scalar_three_reg_same_fp16(DisasContext *s,
return;
}
- if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
+ if (!aa64_dc_feature_fp16(s)) {
unallocated_encoding(s);
}
@@ -11215,7 +11215,7 @@ static void disas_simd_three_reg_same_fp16(DisasContext *s, uint32_t insn)
TCGv_ptr fpst;
bool pairwise = false;
- if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
+ if (!aa64_dc_feature_fp16(s)) {
unallocated_encoding(s);
return;
}
@@ -11430,7 +11430,7 @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
case 0x1c: /* FCADD, #90 */
case 0x1e: /* FCADD, #270 */
if (size == 0
- || (size == 1 && !arm_dc_feature(s, ARM_FEATURE_V8_FP16))
+ || (size == 1 && !aa64_dc_feature_fp16(s))
|| (size == 3 && !is_q)) {
unallocated_encoding(s);
return;
@@ -12310,7 +12310,7 @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
bool need_fpst = true;
int rmode;
- if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
+ if (!aa64_dc_feature_fp16(s)) {
unallocated_encoding(s);
return;
}
@@ -12727,7 +12727,7 @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
}
break;
}
- if (is_fp16 && !arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
+ if (is_fp16 && !aa64_dc_feature_fp16(s)) {
unallocated_encoding(s);
return;
}
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 54ecf369cb..426db7828a 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -7812,7 +7812,7 @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
int size = extract32(insn, 20, 1);
data = extract32(insn, 23, 2); /* rot */
if (!aa32_dc_feature_vcma(s)
- || (!size && !arm_dc_feature(s, ARM_FEATURE_V8_FP16))) {
+ || (!size && !aa32_dc_feature_fp16_arith(s))) {
return 1;
}
fn_gvec_ptr = size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah;
@@ -7821,7 +7821,7 @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
int size = extract32(insn, 20, 1);
data = extract32(insn, 24, 1); /* rot */
if (!aa32_dc_feature_vcma(s)
- || (!size && !arm_dc_feature(s, ARM_FEATURE_V8_FP16))) {
+ || (!size && !aa32_dc_feature_fp16_arith(s))) {
return 1;
}
fn_gvec_ptr = size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh;
@@ -7894,7 +7894,7 @@ static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
return 1;
}
if (size == 0) {
- if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
+ if (!aa32_dc_feature_fp16_arith(s)) {
return 1;
}
/* For fp16, rm is just Vm, and index is M. */
--
2.17.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] [PATCH v3 10/10] target/arm: Convert v8.2-fp16 from feature bit to aa64pfr0 test
2018-10-08 21:22 ` [Qemu-devel] [PATCH v3 10/10] target/arm: Convert v8.2-fp16 " Richard Henderson
@ 2018-10-16 10:36 ` Peter Maydell
2018-10-16 16:12 ` Richard Henderson
0 siblings, 1 reply; 17+ messages in thread
From: Peter Maydell @ 2018-10-16 10:36 UTC (permalink / raw)
To: Richard Henderson; +Cc: QEMU Developers
On 8 October 2018 at 22:22, Richard Henderson
<richard.henderson@linaro.org> wrote:
> Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> target/arm/cpu.h | 17 +++++++++++++++-
> target/arm/translate-a64.h | 1 +
> target/arm/translate.h | 1 +
> linux-user/elfload.c | 6 +-----
> target/arm/cpu64.c | 9 ++-------
> target/arm/helper.c | 2 +-
> target/arm/translate-a64.c | 40 +++++++++++++++++++-------------------
> target/arm/translate.c | 6 +++---
> 8 files changed, 45 insertions(+), 37 deletions(-)
> diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
> index ee2c04a627..38e9afef3b 100644
> --- a/target/arm/cpu64.c
> +++ b/target/arm/cpu64.c
> @@ -266,6 +266,8 @@ static void aarch64_max_initfn(Object *obj)
>
> t = cpu->id_aa64pfr0;
> t = FIELD_DP64(t, ID_AA64PFR0, SVE, 1);
> + t = FIELD_DP64(t, ID_AA64PFR0, FP, 1);
> + t = FIELD_DP64(t, ID_AA64PFR0, ADVSIMD, 1);
> cpu->id_aa64pfr0 = t;
>
> /* Replicate the same data to the 32-bit id registers. */
> @@ -283,13 +285,6 @@ static void aarch64_max_initfn(Object *obj)
> cpu->id_isar6 = u;
>
> #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,
> - * and in some cases they're only available in AArch64 and not AArch32,
> - * whereas the architecture requires them to be present in both if
> - * present in either.
> - */
> - set_feature(&cpu->env, ARM_FEATURE_V8_FP16);
FP16 is the feature that this comment refers to about not having the
AArch32 support present yet. So previously we only set that feature
bit in the user-only mode. Doesn't that mean we need to only
set the equivalent PFR0 bits in the ID register in user-only mode now?
thanks
-- PMM
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] [PATCH v3 10/10] target/arm: Convert v8.2-fp16 from feature bit to aa64pfr0 test
2018-10-16 10:36 ` Peter Maydell
@ 2018-10-16 16:12 ` Richard Henderson
0 siblings, 0 replies; 17+ messages in thread
From: Richard Henderson @ 2018-10-16 16:12 UTC (permalink / raw)
To: Peter Maydell; +Cc: QEMU Developers
On 10/16/18 3:36 AM, Peter Maydell wrote:
> On 8 October 2018 at 22:22, Richard Henderson
> <richard.henderson@linaro.org> wrote:
>> Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
>> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
>> ---
>> target/arm/cpu.h | 17 +++++++++++++++-
>> target/arm/translate-a64.h | 1 +
>> target/arm/translate.h | 1 +
>> linux-user/elfload.c | 6 +-----
>> target/arm/cpu64.c | 9 ++-------
>> target/arm/helper.c | 2 +-
>> target/arm/translate-a64.c | 40 +++++++++++++++++++-------------------
>> target/arm/translate.c | 6 +++---
>> 8 files changed, 45 insertions(+), 37 deletions(-)
>> diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
>> index ee2c04a627..38e9afef3b 100644
>> --- a/target/arm/cpu64.c
>> +++ b/target/arm/cpu64.c
>> @@ -266,6 +266,8 @@ static void aarch64_max_initfn(Object *obj)
>>
>> t = cpu->id_aa64pfr0;
>> t = FIELD_DP64(t, ID_AA64PFR0, SVE, 1);
>> + t = FIELD_DP64(t, ID_AA64PFR0, FP, 1);
>> + t = FIELD_DP64(t, ID_AA64PFR0, ADVSIMD, 1);
>> cpu->id_aa64pfr0 = t;
>>
>> /* Replicate the same data to the 32-bit id registers. */
>> @@ -283,13 +285,6 @@ static void aarch64_max_initfn(Object *obj)
>> cpu->id_isar6 = u;
>>
>> #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,
>> - * and in some cases they're only available in AArch64 and not AArch32,
>> - * whereas the architecture requires them to be present in both if
>> - * present in either.
>> - */
>> - set_feature(&cpu->env, ARM_FEATURE_V8_FP16);
>
> FP16 is the feature that this comment refers to about not having the
> AArch32 support present yet. So previously we only set that feature
> bit in the user-only mode. Doesn't that mean we need to only
> set the equivalent PFR0 bits in the ID register in user-only mode now?
If we do that, then we violate the SVE rule that FP16 must be present. I think
it's more valuable to have SVE available in system mode than the more obscure
AArch64 <-> AArch32 feature correspondence.
r~
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] [PATCH v3 00/10] target/arm: Rely on id regs instead of features
2018-10-08 21:21 [Qemu-devel] [PATCH v3 00/10] target/arm: Rely on id regs instead of features Richard Henderson
` (9 preceding siblings ...)
2018-10-08 21:22 ` [Qemu-devel] [PATCH v3 10/10] target/arm: Convert v8.2-fp16 " Richard Henderson
@ 2018-10-16 10:48 ` Peter Maydell
10 siblings, 0 replies; 17+ messages in thread
From: Peter Maydell @ 2018-10-16 10:48 UTC (permalink / raw)
To: Richard Henderson; +Cc: QEMU Developers
On 8 October 2018 at 22:21, Richard Henderson
<richard.henderson@linaro.org> wrote:
> This edition fixes a number of conflicts with master, and adds
> a few field definitions from ARMv8.5, courtesy of Philippe.
>
> It also fixes a big think-o in a last-minute change to the
> sve system mode patch set that was applied to master today.
> That would be patch 1. Sorry for not testing the original
> more thoroughly.
>
>
> r~
>
>
> Richard Henderson (10):
> target/arm: Fix aarch64_sve_change_el wrt EL0
> target/arm: Define fields of ISAR registers
> target/arm: Align cortex-r5 id_isar0
> target/arm: Fix cortex-a7 id_isar0
I'm applying these patches (1,2,4,5) to target-arm.next.
thanks
-- PMM
^ permalink raw reply [flat|nested] 17+ messages in thread