target/arm: Store cpregs key in the hash table directly

Cast the uint32_t key into a gpointer directly, which
allows us to avoid allocating storage for each key.

Use g_hash_table_lookup when we already have a gpointer
(e.g. for callbacks like count_cpreg), or when using
get_arm_cp_reginfo would require casting away const.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 20220501055028.646596-12-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Richard Henderson 2022-04-30 22:49:53 -07:00 committed by Peter Maydell
parent 9da35a40fd
commit 5860362d25
3 changed files with 21 additions and 26 deletions

View File

@ -1090,8 +1090,8 @@ static void arm_cpu_initfn(Object *obj)
ARMCPU *cpu = ARM_CPU(obj); ARMCPU *cpu = ARM_CPU(obj);
cpu_set_cpustate_pointers(cpu); cpu_set_cpustate_pointers(cpu);
cpu->cp_regs = g_hash_table_new_full(g_int_hash, g_int_equal, cpu->cp_regs = g_hash_table_new_full(g_direct_hash, g_direct_equal,
g_free, cpreg_hashtable_data_destroy); NULL, cpreg_hashtable_data_destroy);
QLIST_INIT(&cpu->pre_el_change_hooks); QLIST_INIT(&cpu->pre_el_change_hooks);
QLIST_INIT(&cpu->el_change_hooks); QLIST_INIT(&cpu->el_change_hooks);

View File

@ -273,7 +273,7 @@ static void arm_gen_one_xml_sysreg_tag(GString *s, DynamicGDBXMLInfo *dyn_xml,
static void arm_register_sysreg_for_xml(gpointer key, gpointer value, static void arm_register_sysreg_for_xml(gpointer key, gpointer value,
gpointer p) gpointer p)
{ {
uint32_t ri_key = *(uint32_t *)key; uint32_t ri_key = (uintptr_t)key;
ARMCPRegInfo *ri = value; ARMCPRegInfo *ri = value;
RegisterSysregXmlParam *param = (RegisterSysregXmlParam *)p; RegisterSysregXmlParam *param = (RegisterSysregXmlParam *)p;
GString *s = param->s; GString *s = param->s;

View File

@ -214,11 +214,8 @@ bool write_list_to_cpustate(ARMCPU *cpu)
static void add_cpreg_to_list(gpointer key, gpointer opaque) static void add_cpreg_to_list(gpointer key, gpointer opaque)
{ {
ARMCPU *cpu = opaque; ARMCPU *cpu = opaque;
uint64_t regidx; uint32_t regidx = (uintptr_t)key;
const ARMCPRegInfo *ri; const ARMCPRegInfo *ri = get_arm_cp_reginfo(cpu->cp_regs, regidx);
regidx = *(uint32_t *)key;
ri = get_arm_cp_reginfo(cpu->cp_regs, regidx);
if (!(ri->type & (ARM_CP_NO_RAW|ARM_CP_ALIAS))) { if (!(ri->type & (ARM_CP_NO_RAW|ARM_CP_ALIAS))) {
cpu->cpreg_indexes[cpu->cpreg_array_len] = cpreg_to_kvm_id(regidx); cpu->cpreg_indexes[cpu->cpreg_array_len] = cpreg_to_kvm_id(regidx);
@ -230,11 +227,9 @@ static void add_cpreg_to_list(gpointer key, gpointer opaque)
static void count_cpreg(gpointer key, gpointer opaque) static void count_cpreg(gpointer key, gpointer opaque)
{ {
ARMCPU *cpu = opaque; ARMCPU *cpu = opaque;
uint64_t regidx;
const ARMCPRegInfo *ri; const ARMCPRegInfo *ri;
regidx = *(uint32_t *)key; ri = g_hash_table_lookup(cpu->cp_regs, key);
ri = get_arm_cp_reginfo(cpu->cp_regs, regidx);
if (!(ri->type & (ARM_CP_NO_RAW|ARM_CP_ALIAS))) { if (!(ri->type & (ARM_CP_NO_RAW|ARM_CP_ALIAS))) {
cpu->cpreg_array_len++; cpu->cpreg_array_len++;
@ -243,8 +238,8 @@ static void count_cpreg(gpointer key, gpointer opaque)
static gint cpreg_key_compare(gconstpointer a, gconstpointer b) static gint cpreg_key_compare(gconstpointer a, gconstpointer b)
{ {
uint64_t aidx = cpreg_to_kvm_id(*(uint32_t *)a); uint64_t aidx = cpreg_to_kvm_id((uintptr_t)a);
uint64_t bidx = cpreg_to_kvm_id(*(uint32_t *)b); uint64_t bidx = cpreg_to_kvm_id((uintptr_t)b);
if (aidx > bidx) { if (aidx > bidx) {
return 1; return 1;
@ -5915,15 +5910,16 @@ static void define_arm_vh_e2h_redirects_aliases(ARMCPU *cpu)
for (i = 0; i < ARRAY_SIZE(aliases); i++) { for (i = 0; i < ARRAY_SIZE(aliases); i++) {
const struct E2HAlias *a = &aliases[i]; const struct E2HAlias *a = &aliases[i];
ARMCPRegInfo *src_reg, *dst_reg, *new_reg; ARMCPRegInfo *src_reg, *dst_reg, *new_reg;
uint32_t *new_key;
bool ok; bool ok;
if (a->feature && !a->feature(&cpu->isar)) { if (a->feature && !a->feature(&cpu->isar)) {
continue; continue;
} }
src_reg = g_hash_table_lookup(cpu->cp_regs, &a->src_key); src_reg = g_hash_table_lookup(cpu->cp_regs,
dst_reg = g_hash_table_lookup(cpu->cp_regs, &a->dst_key); (gpointer)(uintptr_t)a->src_key);
dst_reg = g_hash_table_lookup(cpu->cp_regs,
(gpointer)(uintptr_t)a->dst_key);
g_assert(src_reg != NULL); g_assert(src_reg != NULL);
g_assert(dst_reg != NULL); g_assert(dst_reg != NULL);
@ -5936,14 +5932,14 @@ static void define_arm_vh_e2h_redirects_aliases(ARMCPU *cpu)
/* Create alias before redirection so we dup the right data. */ /* Create alias before redirection so we dup the right data. */
new_reg = g_memdup(src_reg, sizeof(ARMCPRegInfo)); new_reg = g_memdup(src_reg, sizeof(ARMCPRegInfo));
new_key = g_memdup(&a->new_key, sizeof(uint32_t));
new_reg->name = a->new_name; new_reg->name = a->new_name;
new_reg->type |= ARM_CP_ALIAS; new_reg->type |= ARM_CP_ALIAS;
/* Remove PL1/PL0 access, leaving PL2/PL3 R/W in place. */ /* Remove PL1/PL0 access, leaving PL2/PL3 R/W in place. */
new_reg->access &= PL2_RW | PL3_RW; new_reg->access &= PL2_RW | PL3_RW;
ok = g_hash_table_insert(cpu->cp_regs, new_key, new_reg); ok = g_hash_table_insert(cpu->cp_regs,
(gpointer)(uintptr_t)a->new_key, new_reg);
g_assert(ok); g_assert(ok);
src_reg->opaque = dst_reg; src_reg->opaque = dst_reg;
@ -8509,7 +8505,7 @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
/* Private utility function for define_one_arm_cp_reg_with_opaque(): /* Private utility function for define_one_arm_cp_reg_with_opaque():
* add a single reginfo struct to the hash table. * add a single reginfo struct to the hash table.
*/ */
uint32_t *key = g_new(uint32_t, 1); uint32_t key;
ARMCPRegInfo *r2 = g_memdup(r, sizeof(ARMCPRegInfo)); ARMCPRegInfo *r2 = g_memdup(r, sizeof(ARMCPRegInfo));
int is64 = (r->type & ARM_CP_64BIT) ? 1 : 0; int is64 = (r->type & ARM_CP_64BIT) ? 1 : 0;
int ns = (secstate & ARM_CP_SECSTATE_NS) ? 1 : 0; int ns = (secstate & ARM_CP_SECSTATE_NS) ? 1 : 0;
@ -8576,10 +8572,10 @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
if (r->cp == 0 || r->state == ARM_CP_STATE_BOTH) { if (r->cp == 0 || r->state == ARM_CP_STATE_BOTH) {
r2->cp = CP_REG_ARM64_SYSREG_CP; r2->cp = CP_REG_ARM64_SYSREG_CP;
} }
*key = ENCODE_AA64_CP_REG(r2->cp, r2->crn, crm, key = ENCODE_AA64_CP_REG(r2->cp, r2->crn, crm,
r2->opc0, opc1, opc2); r2->opc0, opc1, opc2);
} else { } else {
*key = ENCODE_CP_REG(r2->cp, is64, ns, r2->crn, crm, opc1, opc2); key = ENCODE_CP_REG(r2->cp, is64, ns, r2->crn, crm, opc1, opc2);
} }
if (opaque) { if (opaque) {
r2->opaque = opaque; r2->opaque = opaque;
@ -8621,8 +8617,7 @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
* requested. * requested.
*/ */
if (!(r->type & ARM_CP_OVERRIDE)) { if (!(r->type & ARM_CP_OVERRIDE)) {
ARMCPRegInfo *oldreg; const ARMCPRegInfo *oldreg = get_arm_cp_reginfo(cpu->cp_regs, key);
oldreg = g_hash_table_lookup(cpu->cp_regs, key);
if (oldreg && !(oldreg->type & ARM_CP_OVERRIDE)) { if (oldreg && !(oldreg->type & ARM_CP_OVERRIDE)) {
fprintf(stderr, "Register redefined: cp=%d %d bit " fprintf(stderr, "Register redefined: cp=%d %d bit "
"crn=%d crm=%d opc1=%d opc2=%d, " "crn=%d crm=%d opc1=%d opc2=%d, "
@ -8632,7 +8627,7 @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
g_assert_not_reached(); g_assert_not_reached();
} }
} }
g_hash_table_insert(cpu->cp_regs, key, r2); g_hash_table_insert(cpu->cp_regs, (gpointer)(uintptr_t)key, r2);
} }
@ -8864,7 +8859,7 @@ void modify_arm_cp_regs_with_len(ARMCPRegInfo *regs, size_t regs_len,
const ARMCPRegInfo *get_arm_cp_reginfo(GHashTable *cpregs, uint32_t encoded_cp) const ARMCPRegInfo *get_arm_cp_reginfo(GHashTable *cpregs, uint32_t encoded_cp)
{ {
return g_hash_table_lookup(cpregs, &encoded_cp); return g_hash_table_lookup(cpregs, (gpointer)(uintptr_t)encoded_cp);
} }
void arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri, void arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri,