target/xtensa: don't require opcode table sorting

Requirement for alphabetical opcode sorting in opcode tables is awkward
and does not allow sharing implementation between multiple opcodes.
Use hash tables to find opcodes by name. Move implementation from the
translate.c to the helper.c to its only user and remove declaration from
the cpu.h

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
This commit is contained in:
Max Filippov 2019-02-09 23:21:44 -08:00
parent 0e7c887919
commit 7590397375
3 changed files with 42 additions and 16 deletions

View File

@ -587,8 +587,6 @@ static inline void xtensa_select_static_vectors(CPUXtensaState *env,
env->static_vectors = n;
}
void xtensa_runstall(CPUXtensaState *env, bool runstall);
XtensaOpcodeOps *xtensa_find_opcode_ops(const XtensaOpcodeTranslators *t,
const char *opcode);
#define XTENSA_OPTION_BIT(opt) (((uint64_t)1) << (opt))
#define XTENSA_OPTION_ALL (~(uint64_t)0)

View File

@ -30,10 +30,52 @@
#include "exec/exec-all.h"
#include "exec/gdbstub.h"
#include "exec/helper-proto.h"
#include "qemu/error-report.h"
#include "qemu/host-utils.h"
static struct XtensaConfigList *xtensa_cores;
static void add_translator_to_hash(GHashTable *translator,
const char *name,
const XtensaOpcodeOps *opcode)
{
if (!g_hash_table_insert(translator, (void *)name, (void *)opcode)) {
error_report("Multiple definitions of '%s' opcode in a single table",
name);
}
}
static GHashTable *hash_opcode_translators(const XtensaOpcodeTranslators *t)
{
unsigned i, j;
GHashTable *translator = g_hash_table_new(g_str_hash, g_str_equal);
for (i = 0; i < t->num_opcodes; ++i) {
add_translator_to_hash(translator,
(void *)t->opcode[i].name,
(void *)(t->opcode + i));
}
return translator;
}
static XtensaOpcodeOps *
xtensa_find_opcode_ops(const XtensaOpcodeTranslators *t,
const char *name)
{
static GHashTable *translators;
GHashTable *translator;
if (translators == NULL) {
translators = g_hash_table_new(g_direct_hash, g_direct_equal);
}
translator = g_hash_table_lookup(translators, t);
if (translator == NULL) {
translator = hash_opcode_translators(t);
g_hash_table_insert(translators, (void *)t, translator);
}
return g_hash_table_lookup(translator, name);
}
static void init_libisa(XtensaConfig *config)
{
unsigned i, j;

View File

@ -1274,20 +1274,6 @@ void restore_state_to_opc(CPUXtensaState *env, TranslationBlock *tb,
env->pc = data[0];
}
static int compare_opcode_ops(const void *a, const void *b)
{
return strcmp((const char *)a,
((const XtensaOpcodeOps *)b)->name);
}
XtensaOpcodeOps *
xtensa_find_opcode_ops(const XtensaOpcodeTranslators *t,
const char *name)
{
return bsearch(name, t->opcode, t->num_opcodes,
sizeof(XtensaOpcodeOps), compare_opcode_ops);
}
static void translate_abs(DisasContext *dc, const uint32_t arg[],
const uint32_t par[])
{