target/xtensa: use libisa for instruction decoding

Replace manual opcode analysis with libisa-based code. This makes it
possible to support variable-encoding instructions of the core ISA, like
const16, and will allow to support advanced Xtensa features, like FLIX
and TIE.

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
This commit is contained in:
Max Filippov 2017-11-03 19:44:46 -07:00
parent 502d0f361b
commit 33071f6888
3 changed files with 128 additions and 2148 deletions

View File

@ -392,6 +392,9 @@ struct XtensaConfig {
uint32_t configid[2];
void *isa_internal;
xtensa_isa isa;
XtensaOpcodeOps **opcode_ops;
const XtensaOpcodeTranslators **opcode_translators;
uint32_t clock_freq_khz;

View File

@ -52,10 +52,47 @@ static void xtensa_core_class_init(ObjectClass *oc, void *data)
cc->gdb_num_core_regs = config->gdb_regmap.num_regs;
}
static void init_libisa(XtensaConfig *config)
{
unsigned i, j;
unsigned opcodes;
config->isa = xtensa_isa_init(config->isa_internal, NULL, NULL);
assert(xtensa_isa_maxlength(config->isa) <= MAX_INSN_LENGTH);
opcodes = xtensa_isa_num_opcodes(config->isa);
config->opcode_ops = g_new(XtensaOpcodeOps *, opcodes);
for (i = 0; i < opcodes; ++i) {
const char *opc_name = xtensa_opcode_name(config->isa, i);
XtensaOpcodeOps *ops = NULL;
assert(xtensa_opcode_num_operands(config->isa, i) <= MAX_OPCODE_ARGS);
if (!config->opcode_translators) {
ops = xtensa_find_opcode_ops(&xtensa_core_opcodes, opc_name);
} else {
for (j = 0; !ops && config->opcode_translators[j]; ++j) {
ops = xtensa_find_opcode_ops(config->opcode_translators[j],
opc_name);
}
}
#ifdef DEBUG
if (ops == NULL) {
fprintf(stderr,
"opcode translator not found for %s's opcode '%s'\n",
config->name, opc_name);
}
#endif
config->opcode_ops[i] = ops;
}
}
void xtensa_finalize_config(XtensaConfig *config)
{
unsigned i, n = 0;
if (config->isa_internal) {
init_libisa(config);
}
if (config->gdb_regmap.num_regs) {
return;
}

File diff suppressed because it is too large Load Diff