aboutsummaryrefslogtreecommitdiff
path: root/tcg/tcg.c
diff options
context:
space:
mode:
authorRichard Henderson <rth@twiddle.net>2016-11-18 09:31:40 +0100
committerRichard Henderson <rth@twiddle.net>2017-01-10 08:06:11 -0800
commitf69d277ece43c42c7ab0144c2ff05ba740f6706b (patch)
tree630e59106af7a68dbb6f2587e5e286f6d9ff4b4c /tcg/tcg.c
parent82790a870992bd87d5fd9e607f40859dcf4f82ac (diff)
downloadqemu-f69d277ece43c42c7ab0144c2ff05ba740f6706b.zip
qemu-f69d277ece43c42c7ab0144c2ff05ba740f6706b.tar.gz
qemu-f69d277ece43c42c7ab0144c2ff05ba740f6706b.tar.bz2
tcg: Transition flat op_defs array to a target callback
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>
Diffstat (limited to 'tcg/tcg.c')
-rw-r--r--tcg/tcg.c86
1 files changed, 28 insertions, 58 deletions
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 27913f0..5792c1e 100644
--- 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)