From: Richard Henderson <richard.henderson@linaro.org>
Hoist the computation of key into the caller, where
state is a known constant.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
[PMM: added comment about CRN key field increment]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/helper.c | 40 ++++++++++++++++++++--------------------
1 file changed, 20 insertions(+), 20 deletions(-)
diff --git a/target/arm/helper.c b/target/arm/helper.c
index ade16138e75..8a8fa8c40e9 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -7369,26 +7369,13 @@ void register_cp_regs_for_features(ARMCPU *cpu)
static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
CPState state, CPSecureState secstate,
int cp, int crm, int opc1, int opc2,
- const char *name)
+ const char *name, uint32_t key)
{
CPUARMState *env = &cpu->env;
- uint32_t key;
ARMCPRegInfo *r2;
- bool is64 = r->type & ARM_CP_64BIT;
bool ns = secstate & ARM_CP_SECSTATE_NS;
size_t name_len;
- switch (state) {
- case ARM_CP_STATE_AA32:
- key = ENCODE_CP_REG(cp, is64, ns, r->crn, crm, opc1, opc2);
- break;
- case ARM_CP_STATE_AA64:
- key = ENCODE_AA64_CP_REG(r->opc0, opc1, r->crn, crm, opc2);
- break;
- default:
- g_assert_not_reached();
- }
-
/* Overriding of an existing definition must be explicitly requested. */
if (!(r->type & ARM_CP_OVERRIDE)) {
const ARMCPRegInfo *oldreg = get_arm_cp_reginfo(cpu->cp_regs, key);
@@ -7493,22 +7480,28 @@ static void add_cpreg_to_hashtable_aa32(ARMCPU *cpu, const ARMCPRegInfo *r,
* (same for secure and non-secure world) or banked.
*/
char *name;
+ bool is64 = r->type & ARM_CP_64BIT;
+ uint32_t key = ENCODE_CP_REG(cp, is64, 0, r->crn, crm, opc1, opc2);
assert(!(r->type & ARM_CP_ADD_TLBI_NXS)); /* aa64 only */
switch (r->secure) {
- case ARM_CP_SECSTATE_S:
case ARM_CP_SECSTATE_NS:
+ key |= CP_REG_AA32_NS_MASK;
+ /* fall through */
+ case ARM_CP_SECSTATE_S:
add_cpreg_to_hashtable(cpu, r, ARM_CP_STATE_AA32, r->secure,
- cp, crm, opc1, opc2, r->name);
+ cp, crm, opc1, opc2, r->name, key);
break;
case ARM_CP_SECSTATE_BOTH:
name = g_strdup_printf("%s_S", r->name);
add_cpreg_to_hashtable(cpu, r, ARM_CP_STATE_AA32, ARM_CP_SECSTATE_S,
- cp, crm, opc1, opc2, name);
+ cp, crm, opc1, opc2, name, key);
g_free(name);
+
+ key |= CP_REG_AA32_NS_MASK;
add_cpreg_to_hashtable(cpu, r, ARM_CP_STATE_AA32, ARM_CP_SECSTATE_NS,
- cp, crm, opc1, opc2, r->name);
+ cp, crm, opc1, opc2, r->name, key);
break;
default:
g_assert_not_reached();
@@ -7518,6 +7511,8 @@ static void add_cpreg_to_hashtable_aa32(ARMCPU *cpu, const ARMCPRegInfo *r,
static void add_cpreg_to_hashtable_aa64(ARMCPU *cpu, const ARMCPRegInfo *r,
int crm, int opc1, int opc2)
{
+ uint32_t key = ENCODE_AA64_CP_REG(r->opc0, opc1, r->crn, crm, opc2);
+
if ((r->type & ARM_CP_ADD_TLBI_NXS) &&
cpu_isar_feature(aa64_xs, cpu)) {
/*
@@ -7532,18 +7527,23 @@ static void add_cpreg_to_hashtable_aa64(ARMCPU *cpu, const ARMCPRegInfo *r,
*/
ARMCPRegInfo nxs_ri = *r;
g_autofree char *name = g_strdup_printf("%sNXS", r->name);
+ uint32_t nxs_key;
assert(nxs_ri.crn < 0xf);
nxs_ri.crn++;
+ /* Also increment the CRN field inside the key value */
+ nxs_key = key + (1 << CP_REG_ARM64_SYSREG_CRN_SHIFT);
if (nxs_ri.fgt) {
nxs_ri.fgt |= R_FGT_NXS_MASK;
}
+
add_cpreg_to_hashtable(cpu, &nxs_ri, ARM_CP_STATE_AA64,
- ARM_CP_SECSTATE_NS, 0, crm, opc1, opc2, name);
+ ARM_CP_SECSTATE_NS, 0, crm, opc1, opc2,
+ name, nxs_key);
}
add_cpreg_to_hashtable(cpu, r, ARM_CP_STATE_AA64, ARM_CP_SECSTATE_NS,
- 0, crm, opc1, opc2, r->name);
+ 0, crm, opc1, opc2, r->name, key);
}
void define_one_arm_cp_reg(ARMCPU *cpu, const ARMCPRegInfo *r)
--
2.43.0