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,46 +1937,12 @@ CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
|
||||||
return cpu_list;
|
return cpu_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
|
static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
|
||||||
const ARMCPRegInfo *r, void *opaque)
|
void *opaque, int crm, int opc1, int opc2)
|
||||||
{
|
{
|
||||||
/* Define implementations of coprocessor registers.
|
/* Private utility function for define_one_arm_cp_reg_with_opaque():
|
||||||
* We store these in a hashtable because typically
|
* add a single reginfo struct to the hash table.
|
||||||
* 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++) {
|
|
||||||
uint32_t *key = g_new(uint32_t, 1);
|
uint32_t *key = g_new(uint32_t, 1);
|
||||||
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;
|
||||||
|
@ -2019,6 +1985,50 @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
g_hash_table_insert(cpu->cp_regs, key, r2);
|
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