]> git.proxmox.com Git - mirror_qemu.git/commitdiff
tcg: Transition flat op_defs array to a target callback
authorRichard Henderson <rth@twiddle.net>
Fri, 18 Nov 2016 08:31:40 +0000 (09:31 +0100)
committerRichard Henderson <rth@twiddle.net>
Tue, 10 Jan 2017 16:06:11 +0000 (08:06 -0800)
This will allow the target to tailor the constraints to the
auto-detected ISA extensions.

Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <rth@twiddle.net>
tcg/aarch64/tcg-target.inc.c
tcg/arm/tcg-target.inc.c
tcg/i386/tcg-target.inc.c
tcg/ia64/tcg-target.inc.c
tcg/mips/tcg-target.inc.c
tcg/ppc/tcg-target.inc.c
tcg/s390/tcg-target.inc.c
tcg/sparc/tcg-target.inc.c
tcg/tcg.c
tcg/tcg.h
tcg/tci/tcg-target.inc.c

index c0e9890194508e53528354138ee0219cd91b2c90..416db45b850d18841650e9f3d3a362d868f7e470 100644 (file)
@@ -1812,6 +1812,18 @@ static const TCGTargetOpDef aarch64_op_defs[] = {
     { -1 },
 };
 
+static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
+{
+    int i, n = ARRAY_SIZE(aarch64_op_defs);
+
+    for (i = 0; i < n; ++i) {
+        if (aarch64_op_defs[i].op == op) {
+            return &aarch64_op_defs[i];
+        }
+    }
+    return NULL;
+}
+
 static void tcg_target_init(TCGContext *s)
 {
     tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffffffff);
@@ -1834,8 +1846,6 @@ static void tcg_target_init(TCGContext *s)
     tcg_regset_set_reg(s->reserved_regs, TCG_REG_FP);
     tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP);
     tcg_regset_set_reg(s->reserved_regs, TCG_REG_X18); /* platform register */
-
-    tcg_add_target_add_op_defs(aarch64_op_defs);
 }
 
 /* Saving pairs: (X19, X20) .. (X27, X28), (X29(fp), X30(lr)).  */
index 2d5af0ff8b96652ecb1040ca77cb9025305da81f..eeabcf828f71efaa6f606278d6b8fdf2ef92fda3 100644 (file)
@@ -2008,6 +2008,18 @@ static const TCGTargetOpDef arm_op_defs[] = {
     { -1 },
 };
 
+static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
+{
+    int i, n = ARRAY_SIZE(arm_op_defs);
+
+    for (i = 0; i < n; ++i) {
+        if (arm_op_defs[i].op == op) {
+            return &arm_op_defs[i];
+        }
+    }
+    return NULL;
+}
+
 static void tcg_target_init(TCGContext *s)
 {
     /* Only probe for the platform and capabilities if we havn't already
@@ -2038,8 +2050,6 @@ static void tcg_target_init(TCGContext *s)
     tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
     tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP);
     tcg_regset_set_reg(s->reserved_regs, TCG_REG_PC);
-
-    tcg_add_target_add_op_defs(arm_op_defs);
 }
 
 static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg,
index 39f62bd6c5a08515d6cbbfd4528d99787b2a294b..595c3992e9fe816aaaa2934f54cdeef2f6986f2a 100644 (file)
@@ -2330,6 +2330,18 @@ static const TCGTargetOpDef x86_op_defs[] = {
     { -1 },
 };
 
+static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
+{
+    int i, n = ARRAY_SIZE(x86_op_defs);
+
+    for (i = 0; i < n; ++i) {
+        if (x86_op_defs[i].op == op) {
+            return &x86_op_defs[i];
+        }
+    }
+    return NULL;
+}
+
 static int tcg_target_callee_save_regs[] = {
 #if TCG_TARGET_REG_BITS == 64
     TCG_REG_RBP,
@@ -2471,8 +2483,6 @@ static void tcg_target_init(TCGContext *s)
 
     tcg_regset_clear(s->reserved_regs);
     tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
-
-    tcg_add_target_add_op_defs(x86_op_defs);
 }
 
 typedef struct {
index b04d716c3da3e57d265db7731985a7e2d0969efa..e4d419d3a7a0ea0b36eee872a1ab35afca0547ed 100644 (file)
@@ -2352,6 +2352,18 @@ static const TCGTargetOpDef ia64_op_defs[] = {
     { -1 },
 };
 
+static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
+{
+    int i, n = ARRAY_SIZE(ia64_op_defs);
+
+    for (i = 0; i < n; ++i) {
+        if (ia64_op_defs[i].op == op) {
+            return &ia64_op_defs[i];
+        }
+    }
+    return NULL;
+}
+
 /* Generate global QEMU prologue and epilogue code */
 static void tcg_target_qemu_prologue(TCGContext *s)
 {
@@ -2471,6 +2483,4 @@ static void tcg_target_init(TCGContext *s)
     tcg_regset_set_reg(s->reserved_regs, TCG_REG_R5);
     tcg_regset_set_reg(s->reserved_regs, TCG_REG_R6);
     tcg_regset_set_reg(s->reserved_regs, TCG_REG_R7);
-
-    tcg_add_target_add_op_defs(ia64_op_defs);
 }
index 24c49497a9185d0973a43259722da243379a2c9f..a8f031a5a48882930c8e3ec16c76eea11d658f84 100644 (file)
@@ -2262,6 +2262,18 @@ static const TCGTargetOpDef mips_op_defs[] = {
     { -1 },
 };
 
+static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
+{
+    int i, n = ARRAY_SIZE(mips_op_defs);
+
+    for (i = 0; i < n; ++i) {
+        if (mips_op_defs[i].op == op) {
+            return &mips_op_defs[i];
+        }
+    }
+    return NULL;
+}
+
 static int tcg_target_callee_save_regs[] = {
     TCG_REG_S0,       /* used for the global env (TCG_AREG0) */
     TCG_REG_S1,
@@ -2563,8 +2575,6 @@ static void tcg_target_init(TCGContext *s)
     tcg_regset_set_reg(s->reserved_regs, TCG_REG_RA);   /* return address */
     tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP);   /* stack pointer */
     tcg_regset_set_reg(s->reserved_regs, TCG_REG_GP);   /* global pointer */
-
-    tcg_add_target_add_op_defs(mips_op_defs);
 }
 
 void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr)
index 7ec54a2a60c7d82f7b374010b7fca1a7a2c32fb5..a1b7412a53018be69a65b9a1792bf5092bae5804 100644 (file)
@@ -2634,6 +2634,18 @@ static const TCGTargetOpDef ppc_op_defs[] = {
     { -1 },
 };
 
+static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
+{
+    int i, n = ARRAY_SIZE(ppc_op_defs);
+
+    for (i = 0; i < n; ++i) {
+        if (ppc_op_defs[i].op == op) {
+            return &ppc_op_defs[i];
+        }
+    }
+    return NULL;
+}
+
 static void tcg_target_init(TCGContext *s)
 {
     unsigned long hwcap = qemu_getauxval(AT_HWCAP);
@@ -2670,8 +2682,6 @@ static void tcg_target_init(TCGContext *s)
     if (USE_REG_RA) {
         tcg_regset_set_reg(s->reserved_regs, TCG_REG_RA);  /* return addr */
     }
-
-    tcg_add_target_add_op_defs(ppc_op_defs);
 }
 
 #ifdef __ELF__
index 22e121a1c48d9cc43b13dc360c9a6d599cc846e5..b686f3ae4db3e1a6c6f75d8f5c08b0c784e214e3 100644 (file)
@@ -2326,6 +2326,18 @@ static const TCGTargetOpDef s390_op_defs[] = {
     { -1 },
 };
 
+static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
+{
+    int i, n = ARRAY_SIZE(s390_op_defs);
+
+    for (i = 0; i < n; ++i) {
+        if (s390_op_defs[i].op == op) {
+            return &s390_op_defs[i];
+        }
+    }
+    return NULL;
+}
+
 static void query_s390_facilities(void)
 {
     unsigned long hwcap = qemu_getauxval(AT_HWCAP);
@@ -2368,8 +2380,6 @@ static void tcg_target_init(TCGContext *s)
     /* XXX many insns can't be used with R0, so we better avoid it for now */
     tcg_regset_set_reg(s->reserved_regs, TCG_REG_R0);
     tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
-
-    tcg_add_target_add_op_defs(s390_op_defs);
 }
 
 #define FRAME_SIZE  ((int)(TCG_TARGET_CALL_STACK_OFFSET          \
index 700c43487f42e6d8098c54af9bcc1517d7a04203..f2cbf50cfd7523a977183c5b587600d8bd81d17e 100644 (file)
@@ -1583,6 +1583,18 @@ static const TCGTargetOpDef sparc_op_defs[] = {
     { -1 },
 };
 
+static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
+{
+    int i, n = ARRAY_SIZE(sparc_op_defs);
+
+    for (i = 0; i < n; ++i) {
+        if (sparc_op_defs[i].op == op) {
+            return &sparc_op_defs[i];
+        }
+    }
+    return NULL;
+}
+
 static void tcg_target_init(TCGContext *s)
 {
     /* Only probe for the platform and capabilities if we havn't already
@@ -1622,8 +1634,6 @@ static void tcg_target_init(TCGContext *s)
     tcg_regset_set_reg(s->reserved_regs, TCG_REG_O6); /* stack pointer */
     tcg_regset_set_reg(s->reserved_regs, TCG_REG_T1); /* for internal use */
     tcg_regset_set_reg(s->reserved_regs, TCG_REG_T2); /* for internal use */
-
-    tcg_add_target_add_op_defs(sparc_op_defs);
 }
 
 #if SPARC64
index 27913f0c870b846dd0384acbb6182144b5bb5ae5..5792c1edfc364750db004d657d0eafadd74c52af 100644 (file)
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -62,6 +62,7 @@
 /* Forward declarations for functions declared in tcg-target.inc.c and
    used here. */
 static void tcg_target_init(TCGContext *s);
+static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode);
 static void tcg_target_qemu_prologue(TCGContext *s);
 static void patch_reloc(tcg_insn_unit *code_ptr, int type,
                         intptr_t value, intptr_t addend);
@@ -319,6 +320,7 @@ static const TCGHelperInfo all_helpers[] = {
 };
 
 static int indirect_reg_alloc_order[ARRAY_SIZE(tcg_target_reg_alloc_order)];
+static void process_op_defs(TCGContext *s);
 
 void tcg_context_init(TCGContext *s)
 {
@@ -362,6 +364,7 @@ void tcg_context_init(TCGContext *s)
     }
 
     tcg_target_init(s);
+    process_op_defs(s);
 
     /* Reverse the order of the saved registers, assuming they're all at
        the start of tcg_target_reg_alloc_order.  */
@@ -1221,29 +1224,33 @@ static void sort_constraints(TCGOpDef *def, int start, int n)
     }
 }
 
-void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs)
+static void process_op_defs(TCGContext *s)
 {
     TCGOpcode op;
-    TCGOpDef *def;
-    const char *ct_str;
-    int i, nb_args;
 
-    for(;;) {
-        if (tdefs->op == (TCGOpcode)-1)
-            break;
-        op = tdefs->op;
-        tcg_debug_assert((unsigned)op < NB_OPS);
-        def = &tcg_op_defs[op];
-#if defined(CONFIG_DEBUG_TCG)
-        /* Duplicate entry in op definitions? */
-        tcg_debug_assert(!def->used);
-        def->used = 1;
-#endif
+    for (op = 0; op < NB_OPS; op++) {
+        TCGOpDef *def = &tcg_op_defs[op];
+        const TCGTargetOpDef *tdefs;
+        int i, nb_args, ok;
+
+        if (def->flags & TCG_OPF_NOT_PRESENT) {
+            continue;
+        }
+
         nb_args = def->nb_iargs + def->nb_oargs;
-        for(i = 0; i < nb_args; i++) {
-            ct_str = tdefs->args_ct_str[i];
-            /* Incomplete TCGTargetOpDef entry? */
+        if (nb_args == 0) {
+            continue;
+        }
+
+        tdefs = tcg_target_op_def(op);
+        /* Missing TCGTargetOpDef entry. */
+        tcg_debug_assert(tdefs != NULL);
+
+        for (i = 0; i < nb_args; i++) {
+            const char *ct_str = tdefs->args_ct_str[i];
+            /* Incomplete TCGTargetOpDef entry. */
             tcg_debug_assert(ct_str != NULL);
+
             tcg_regset_clear(def->args_ct[i].u.regs);
             def->args_ct[i].ct = 0;
             if (ct_str[0] >= '0' && ct_str[0] <= '9') {
@@ -1272,11 +1279,9 @@ void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs)
                         ct_str++;
                         break;
                     default:
-                        if (target_parse_constraint(&def->args_ct[i], &ct_str) < 0) {
-                            fprintf(stderr, "Invalid constraint '%s' for arg %d of operation '%s'\n",
-                                    ct_str, i, def->name);
-                            exit(1);
-                        }
+                        ok = target_parse_constraint(&def->args_ct[i], &ct_str);
+                        /* Typo in TCGTargetOpDef constraint. */
+                        tcg_debug_assert(ok == 0);
                     }
                 }
             }
@@ -1288,42 +1293,7 @@ void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs)
         /* sort the constraints (XXX: this is just an heuristic) */
         sort_constraints(def, 0, def->nb_oargs);
         sort_constraints(def, def->nb_oargs, def->nb_iargs);
-
-#if 0
-        {
-            int i;
-
-            printf("%s: sorted=", def->name);
-            for(i = 0; i < def->nb_oargs + def->nb_iargs; i++)
-                printf(" %d", def->sorted_args[i]);
-            printf("\n");
-        }
-#endif
-        tdefs++;
-    }
-
-#if defined(CONFIG_DEBUG_TCG)
-    i = 0;
-    for (op = 0; op < tcg_op_defs_max; op++) {
-        const TCGOpDef *def = &tcg_op_defs[op];
-        if (def->flags & TCG_OPF_NOT_PRESENT) {
-            /* Wrong entry in op definitions? */
-            if (def->used) {
-                fprintf(stderr, "Invalid op definition for %s\n", def->name);
-                i = 1;
-            }
-        } else {
-            /* Missing entry in op definitions? */
-            if (!def->used) {
-                fprintf(stderr, "Missing op definition for %s\n", def->name);
-                i = 1;
-            }
-        }
-    }
-    if (i == 1) {
-        tcg_abort();
     }
-#endif
 }
 
 void tcg_op_remove(TCGContext *s, TCGOp *op)
index ebfcefda7726e1b82cd8dd8df0012263a2a22c6c..144bdabbe087741c02b5fe90fec0b6c4cd40e428 100644 (file)
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -906,8 +906,6 @@ do {\
     abort();\
 } while (0)
 
-void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs);
-
 #if UINTPTR_MAX == UINT32_MAX
 #define TCGV_NAT_TO_PTR(n) MAKE_TCGV_PTR(GET_TCGV_I32(n))
 #define TCGV_PTR_TO_NAT(n) MAKE_TCGV_I32(GET_TCGV_PTR(n))
index 9dbf4d5512577ab8f1f13c3dfeb9c950776eaf60..42d4bd671c29add87fc54ff7daba0eaaa7830c4e 100644 (file)
@@ -259,6 +259,18 @@ static const TCGTargetOpDef tcg_target_op_defs[] = {
     { -1 },
 };
 
+static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
+{
+    int i, n = ARRAY_SIZE(tcg_target_op_defs);
+
+    for (i = 0; i < n; ++i) {
+        if (tcg_target_op_defs[i].op == op) {
+            return &tcg_target_op_defs[i];
+        }
+    }
+    return NULL;
+}
+
 static const int tcg_target_reg_alloc_order[] = {
     TCG_REG_R0,
     TCG_REG_R1,
@@ -875,7 +887,6 @@ static void tcg_target_init(TCGContext *s)
 
     tcg_regset_clear(s->reserved_regs);
     tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
-    tcg_add_target_add_op_defs(tcg_target_op_defs);
 
     /* We use negative offsets from "sp" so that we can distinguish
        stores that might pretend to be call arguments.  */