mirror of https://github.com/xqemu/xqemu.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,46 +1937,12 @@ CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
|
|||
return cpu_list;
|
||||
}
|
||||
|
||||
void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
|
||||
const ARMCPRegInfo *r, void *opaque)
|
||||
static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
|
||||
void *opaque, int crm, int opc1, int opc2)
|
||||
{
|
||||
/* Define implementations of coprocessor registers.
|
||||
* We store these in a hashtable because typically
|
||||
* there are less than 150 registers in a space which
|
||||
* is 16*16*16*8*8 = 262144 in size.
|
||||
* Wildcarding is supported for the crm, opc1 and opc2 fields.
|
||||
* If a register is defined twice then the second definition is
|
||||
* used, so this can be used to define some generic registers and
|
||||
* then override them with implementation specific variations.
|
||||
* At least one of the original and the second definition should
|
||||
* include ARM_CP_OVERRIDE in its type bits -- this is just a guard
|
||||
* against accidental use.
|
||||
/* Private utility function for define_one_arm_cp_reg_with_opaque():
|
||||
* add a single reginfo struct to the hash table.
|
||||
*/
|
||||
int crm, opc1, opc2;
|
||||
int crmmin = (r->crm == CP_ANY) ? 0 : r->crm;
|
||||
int crmmax = (r->crm == CP_ANY) ? 15 : r->crm;
|
||||
int opc1min = (r->opc1 == CP_ANY) ? 0 : r->opc1;
|
||||
int opc1max = (r->opc1 == CP_ANY) ? 7 : r->opc1;
|
||||
int opc2min = (r->opc2 == CP_ANY) ? 0 : r->opc2;
|
||||
int opc2max = (r->opc2 == CP_ANY) ? 7 : r->opc2;
|
||||
/* 64 bit registers have only CRm and Opc1 fields */
|
||||
assert(!((r->type & ARM_CP_64BIT) && (r->opc2 || r->crn)));
|
||||
/* Check that the register definition has enough info to handle
|
||||
* reads and writes if they are permitted.
|
||||
*/
|
||||
if (!(r->type & (ARM_CP_SPECIAL|ARM_CP_CONST))) {
|
||||
if (r->access & PL3_R) {
|
||||
assert(r->fieldoffset || r->readfn);
|
||||
}
|
||||
if (r->access & PL3_W) {
|
||||
assert(r->fieldoffset || r->writefn);
|
||||
}
|
||||
}
|
||||
/* Bad type field probably means missing sentinel at end of reg list */
|
||||
assert(cptype_valid(r->type));
|
||||
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;
|
||||
|
@ -2019,6 +1985,50 @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
|
|||
}
|
||||
}
|
||||
g_hash_table_insert(cpu->cp_regs, key, r2);
|
||||
}
|
||||
|
||||
|
||||
void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
|
||||
const ARMCPRegInfo *r, void *opaque)
|
||||
{
|
||||
/* Define implementations of coprocessor registers.
|
||||
* We store these in a hashtable because typically
|
||||
* there are less than 150 registers in a space which
|
||||
* is 16*16*16*8*8 = 262144 in size.
|
||||
* Wildcarding is supported for the crm, opc1 and opc2 fields.
|
||||
* If a register is defined twice then the second definition is
|
||||
* used, so this can be used to define some generic registers and
|
||||
* then override them with implementation specific variations.
|
||||
* At least one of the original and the second definition should
|
||||
* include ARM_CP_OVERRIDE in its type bits -- this is just a guard
|
||||
* against accidental use.
|
||||
*/
|
||||
int crm, opc1, opc2;
|
||||
int crmmin = (r->crm == CP_ANY) ? 0 : r->crm;
|
||||
int crmmax = (r->crm == CP_ANY) ? 15 : r->crm;
|
||||
int opc1min = (r->opc1 == CP_ANY) ? 0 : r->opc1;
|
||||
int opc1max = (r->opc1 == CP_ANY) ? 7 : r->opc1;
|
||||
int opc2min = (r->opc2 == CP_ANY) ? 0 : r->opc2;
|
||||
int opc2max = (r->opc2 == CP_ANY) ? 7 : r->opc2;
|
||||
/* 64 bit registers have only CRm and Opc1 fields */
|
||||
assert(!((r->type & ARM_CP_64BIT) && (r->opc2 || r->crn)));
|
||||
/* Check that the register definition has enough info to handle
|
||||
* reads and writes if they are permitted.
|
||||
*/
|
||||
if (!(r->type & (ARM_CP_SPECIAL|ARM_CP_CONST))) {
|
||||
if (r->access & PL3_R) {
|
||||
assert(r->fieldoffset || r->readfn);
|
||||
}
|
||||
if (r->access & PL3_W) {
|
||||
assert(r->fieldoffset || r->writefn);
|
||||
}
|
||||
}
|
||||
/* Bad type field probably means missing sentinel at end of reg list */
|
||||
assert(cptype_valid(r->type));
|
||||
for (crm = crmmin; crm <= crmmax; crm++) {
|
||||
for (opc1 = opc1min; opc1 <= opc1max; opc1++) {
|
||||
for (opc2 = opc2min; opc2 <= opc2max; opc2++) {
|
||||
add_cpreg_to_hashtable(cpu, r, opaque, crm, opc1, opc2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue