aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--target/arm/helper.c49
1 files changed, 27 insertions, 22 deletions
diff --git a/target/arm/helper.c b/target/arm/helper.c
index d92fd23..cbc873e 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -8509,8 +8509,34 @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
ARMCPRegInfo *r2;
int is64 = (r->type & ARM_CP_64BIT) ? 1 : 0;
int ns = (secstate & ARM_CP_SECSTATE_NS) ? 1 : 0;
+ int cp = r->cp;
size_t name_len;
+ switch (state) {
+ case ARM_CP_STATE_AA32:
+ /* We assume it is a cp15 register if the .cp field is left unset. */
+ if (cp == 0 && r->state == ARM_CP_STATE_BOTH) {
+ cp = 15;
+ }
+ key = ENCODE_CP_REG(cp, is64, ns, r->crn, crm, opc1, opc2);
+ break;
+ case ARM_CP_STATE_AA64:
+ /*
+ * To allow abbreviation of ARMCPRegInfo definitions, we treat
+ * cp == 0 as equivalent to the value for "standard guest-visible
+ * sysreg". STATE_BOTH definitions are also always "standard sysreg"
+ * in their AArch64 view (the .cp value may be non-zero for the
+ * benefit of the AArch32 view).
+ */
+ if (cp == 0 || r->state == ARM_CP_STATE_BOTH) {
+ cp = CP_REG_ARM64_SYSREG_CP;
+ }
+ key = ENCODE_AA64_CP_REG(cp, r->crn, crm, r->opc0, opc1, opc2);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+
/* Combine cpreg and name into one allocation. */
name_len = strlen(name) + 1;
r2 = g_malloc(sizeof(*r2) + name_len);
@@ -8554,12 +8580,6 @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
}
if (r->state == ARM_CP_STATE_BOTH) {
- /* We assume it is a cp15 register if the .cp field is left unset.
- */
- if (r2->cp == 0) {
- r2->cp = 15;
- }
-
#if HOST_BIG_ENDIAN
if (r2->fieldoffset) {
r2->fieldoffset += sizeof(uint32_t);
@@ -8567,22 +8587,6 @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
#endif
}
}
- if (state == ARM_CP_STATE_AA64) {
- /* To allow abbreviation of ARMCPRegInfo
- * definitions, we treat cp == 0 as equivalent to
- * the value for "standard guest-visible sysreg".
- * STATE_BOTH definitions are also always "standard
- * sysreg" in their AArch64 view (the .cp value may
- * be non-zero for the benefit of the AArch32 view).
- */
- if (r->cp == 0 || r->state == ARM_CP_STATE_BOTH) {
- r2->cp = CP_REG_ARM64_SYSREG_CP;
- }
- key = ENCODE_AA64_CP_REG(r2->cp, r2->crn, crm,
- r2->opc0, opc1, opc2);
- } else {
- key = ENCODE_CP_REG(r2->cp, is64, ns, r2->crn, crm, opc1, opc2);
- }
if (opaque) {
r2->opaque = opaque;
}
@@ -8593,6 +8597,7 @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
/* Make sure reginfo passed to helpers for wildcarded regs
* has the correct crm/opc1/opc2 for this reg, not CP_ANY:
*/
+ r2->cp = cp;
r2->crm = crm;
r2->opc1 = opc1;
r2->opc2 = opc2;