mirror of https://gitee.com/openkylin/qemu.git
target-arm: Pull "add one cpreg to hashtable" into its own function
define_one_arm_cp_reg_with_opaque() has a set of nested loops which insert a cpreg entry into the hashtable for each of the possible opc/crn/crm values allowed by wildcard specifications. We're about to add an extra loop to this nesting, so pull the core of the loop (which adds a single entry to the hashtable) out into its own function for clarity. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <rth@twiddle.net>
This commit is contained in:
parent
ce5458e82e
commit
6e6efd612f
|
@ -1937,6 +1937,57 @@ CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
|
|||
return cpu_list;
|
||||
}
|
||||
|
||||
static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
|
||||
void *opaque, int crm, int opc1, int opc2)
|
||||
{
|
||||
/* Private utility function for define_one_arm_cp_reg_with_opaque():
|
||||
* add a single reginfo struct to the hash table.
|
||||
*/
|
||||
uint32_t *key = g_new(uint32_t, 1);
|
||||
ARMCPRegInfo *r2 = g_memdup(r, sizeof(ARMCPRegInfo));
|
||||
int is64 = (r->type & ARM_CP_64BIT) ? 1 : 0;
|
||||
*key = ENCODE_CP_REG(r->cp, is64, r->crn, crm, opc1, opc2);
|
||||
if (opaque) {
|
||||
r2->opaque = opaque;
|
||||
}
|
||||
/* Make sure reginfo passed to helpers for wildcarded regs
|
||||
* has the correct crm/opc1/opc2 for this reg, not CP_ANY:
|
||||
*/
|
||||
r2->crm = crm;
|
||||
r2->opc1 = opc1;
|
||||
r2->opc2 = opc2;
|
||||
/* By convention, for wildcarded registers only the first
|
||||
* entry is used for migration; the others are marked as
|
||||
* NO_MIGRATE so we don't try to transfer the register
|
||||
* multiple times. Special registers (ie NOP/WFI) are
|
||||
* never migratable.
|
||||
*/
|
||||
if ((r->type & ARM_CP_SPECIAL) ||
|
||||
((r->crm == CP_ANY) && crm != 0) ||
|
||||
((r->opc1 == CP_ANY) && opc1 != 0) ||
|
||||
((r->opc2 == CP_ANY) && opc2 != 0)) {
|
||||
r2->type |= ARM_CP_NO_MIGRATE;
|
||||
}
|
||||
|
||||
/* Overriding of an existing definition must be explicitly
|
||||
* requested.
|
||||
*/
|
||||
if (!(r->type & ARM_CP_OVERRIDE)) {
|
||||
ARMCPRegInfo *oldreg;
|
||||
oldreg = g_hash_table_lookup(cpu->cp_regs, key);
|
||||
if (oldreg && !(oldreg->type & ARM_CP_OVERRIDE)) {
|
||||
fprintf(stderr, "Register redefined: cp=%d %d bit "
|
||||
"crn=%d crm=%d opc1=%d opc2=%d, "
|
||||
"was %s, now %s\n", r2->cp, 32 + 32 * is64,
|
||||
r2->crn, r2->crm, r2->opc1, r2->opc2,
|
||||
oldreg->name, r2->name);
|
||||
g_assert_not_reached();
|
||||
}
|
||||
}
|
||||
g_hash_table_insert(cpu->cp_regs, key, r2);
|
||||
}
|
||||
|
||||
|
||||
void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
|
||||
const ARMCPRegInfo *r, void *opaque)
|
||||
{
|
||||
|
@ -1977,48 +2028,7 @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
|
|||
for (crm = crmmin; crm <= crmmax; crm++) {
|
||||
for (opc1 = opc1min; opc1 <= opc1max; opc1++) {
|
||||
for (opc2 = opc2min; opc2 <= opc2max; opc2++) {
|
||||
uint32_t *key = g_new(uint32_t, 1);
|
||||
ARMCPRegInfo *r2 = g_memdup(r, sizeof(ARMCPRegInfo));
|
||||
int is64 = (r->type & ARM_CP_64BIT) ? 1 : 0;
|
||||
*key = ENCODE_CP_REG(r->cp, is64, r->crn, crm, opc1, opc2);
|
||||
if (opaque) {
|
||||
r2->opaque = opaque;
|
||||
}
|
||||
/* Make sure reginfo passed to helpers for wildcarded regs
|
||||
* has the correct crm/opc1/opc2 for this reg, not CP_ANY:
|
||||
*/
|
||||
r2->crm = crm;
|
||||
r2->opc1 = opc1;
|
||||
r2->opc2 = opc2;
|
||||
/* By convention, for wildcarded registers only the first
|
||||
* entry is used for migration; the others are marked as
|
||||
* NO_MIGRATE so we don't try to transfer the register
|
||||
* multiple times. Special registers (ie NOP/WFI) are
|
||||
* never migratable.
|
||||
*/
|
||||
if ((r->type & ARM_CP_SPECIAL) ||
|
||||
((r->crm == CP_ANY) && crm != 0) ||
|
||||
((r->opc1 == CP_ANY) && opc1 != 0) ||
|
||||
((r->opc2 == CP_ANY) && opc2 != 0)) {
|
||||
r2->type |= ARM_CP_NO_MIGRATE;
|
||||
}
|
||||
|
||||
/* Overriding of an existing definition must be explicitly
|
||||
* requested.
|
||||
*/
|
||||
if (!(r->type & ARM_CP_OVERRIDE)) {
|
||||
ARMCPRegInfo *oldreg;
|
||||
oldreg = g_hash_table_lookup(cpu->cp_regs, key);
|
||||
if (oldreg && !(oldreg->type & ARM_CP_OVERRIDE)) {
|
||||
fprintf(stderr, "Register redefined: cp=%d %d bit "
|
||||
"crn=%d crm=%d opc1=%d opc2=%d, "
|
||||
"was %s, now %s\n", r2->cp, 32 + 32 * is64,
|
||||
r2->crn, r2->crm, r2->opc1, r2->opc2,
|
||||
oldreg->name, r2->name);
|
||||
g_assert_not_reached();
|
||||
}
|
||||
}
|
||||
g_hash_table_insert(cpu->cp_regs, key, r2);
|
||||
add_cpreg_to_hashtable(cpu, r, opaque, crm, opc1, opc2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue