summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--target-ppc/cpu-models.c2
-rw-r--r--target-ppc/cpu-models.h3
-rw-r--r--target-ppc/translate_init.c32
3 files changed, 30 insertions, 7 deletions
diff --git a/target-ppc/cpu-models.c b/target-ppc/cpu-models.c
index 17f56b7504..9bb68c8191 100644
--- a/target-ppc/cpu-models.c
+++ b/target-ppc/cpu-models.c
@@ -1227,7 +1227,7 @@
 /***************************************************************************/
 /* PowerPC CPU aliases                                                     */
 
-const PowerPCCPUAlias ppc_cpu_aliases[] = {
+PowerPCCPUAlias ppc_cpu_aliases[] = {
     { "403", "403GC" },
     { "405", "405D4" },
     { "405CR", "405CRc" },
diff --git a/target-ppc/cpu-models.h b/target-ppc/cpu-models.h
index a94f835121..ae8f7c743e 100644
--- a/target-ppc/cpu-models.h
+++ b/target-ppc/cpu-models.h
@@ -31,9 +31,10 @@
 typedef struct PowerPCCPUAlias {
     const char *alias;
     const char *model;
+    ObjectClass *oc;
 } PowerPCCPUAlias;
 
-extern const PowerPCCPUAlias ppc_cpu_aliases[];
+extern PowerPCCPUAlias ppc_cpu_aliases[];
 
 /*****************************************************************************/
 /* PVR definitions for most known PowerPC                                    */
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index f01e9e7d91..937390a967 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -7934,6 +7934,28 @@ static gint ppc_cpu_compare_class_name(gconstpointer a, gconstpointer b)
 
 #include <ctype.h>
 
+static ObjectClass *ppc_cpu_class_by_name(const char *name);
+
+static ObjectClass *ppc_cpu_class_by_alias(PowerPCCPUAlias *alias)
+{
+    ObjectClass *invalid_class = (void*)ppc_cpu_class_by_alias;
+
+    /* Cache target class lookups in the alias table */
+    if (!alias->oc) {
+        alias->oc = ppc_cpu_class_by_name(alias->model);
+        if (!alias->oc) {
+            /* Fast check for non-existing aliases */
+            alias->oc = invalid_class;
+        }
+    }
+
+    if (alias->oc == invalid_class) {
+        return NULL;
+    } else {
+        return alias->oc;
+    }
+}
+
 static ObjectClass *ppc_cpu_class_by_name(const char *name)
 {
     GSList *list, *item;
@@ -7961,7 +7983,7 @@ static ObjectClass *ppc_cpu_class_by_name(const char *name)
 
     for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
         if (strcmp(ppc_cpu_aliases[i].alias, name) == 0) {
-            return ppc_cpu_class_by_name(ppc_cpu_aliases[i].model);
+            return ppc_cpu_class_by_alias(&ppc_cpu_aliases[i]);
         }
     }
 
@@ -8051,8 +8073,8 @@ static void ppc_cpu_list_entry(gpointer data, gpointer user_data)
     (*s->cpu_fprintf)(s->file, "PowerPC %-16s PVR %08x\n",
                       name, pcc->pvr);
     for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
-        const PowerPCCPUAlias *alias = &ppc_cpu_aliases[i];
-        ObjectClass *alias_oc = ppc_cpu_class_by_name(alias->model);
+        PowerPCCPUAlias *alias = &ppc_cpu_aliases[i];
+        ObjectClass *alias_oc = ppc_cpu_class_by_alias(alias);
 
         if (alias_oc != oc) {
             continue;
@@ -8119,12 +8141,12 @@ CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
     g_slist_free(list);
 
     for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
-        const PowerPCCPUAlias *alias = &ppc_cpu_aliases[i];
+        PowerPCCPUAlias *alias = &ppc_cpu_aliases[i];
         ObjectClass *oc;
         CpuDefinitionInfoList *entry;
         CpuDefinitionInfo *info;
 
-        oc = ppc_cpu_class_by_name(alias->model);
+        oc = ppc_cpu_class_by_alias(alias);
         if (oc == NULL) {
             continue;
         }