]> git.proxmox.com Git - mirror_qemu.git/commitdiff
target/xtensa: don't require opcode table sorting
authorMax Filippov <jcmvbkbc@gmail.com>
Sun, 10 Feb 2019 07:21:44 +0000 (23:21 -0800)
committerMax Filippov <jcmvbkbc@gmail.com>
Tue, 19 Feb 2019 05:29:08 +0000 (21:29 -0800)
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>
target/xtensa/cpu.h
target/xtensa/helper.c
target/xtensa/translate.c

index 47d80a59e2f562746523256c8d251c2c0d3c8b1d..2765665ceca6689dec2408936b8f38a33f5b7918 100644 (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)
index 321ca42955216d5333061e95c68be9c76a11a46b..57709fc20cafab343508a5cf576d91b806c041f8 100644 (file)
 #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;
index 62283cd1ccc8c525939aaa5afd5ab19bc449a263..26342aaa1f82766959866f852c457eba7a8b69f8 100644 (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[])
 {