diff options
author | Richard Henderson <rth@twiddle.net> | 2016-11-18 09:31:40 +0100 |
---|---|---|
committer | Richard Henderson <rth@twiddle.net> | 2017-01-10 08:06:11 -0800 |
commit | f69d277ece43c42c7ab0144c2ff05ba740f6706b (patch) | |
tree | 630e59106af7a68dbb6f2587e5e286f6d9ff4b4c /tcg/tcg.c | |
parent | 82790a870992bd87d5fd9e607f40859dcf4f82ac (diff) | |
download | qemu-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.c | 86 |
1 files changed, 28 insertions, 58 deletions
@@ -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) |