diff options
author | Richard Sandiford <richard.sandiford@arm.com> | 2015-08-24 17:59:51 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2015-08-24 17:59:51 +0000 |
commit | 58d745ec901a3707c1e6487ce8c0eca387ec5f42 (patch) | |
tree | c3042a200d6b63e1964f926ac1b634a9c69f950d /gcc/gentarget-def.c | |
parent | 651159e5d652ae1dcc48f8107fa5e5b272767d5b (diff) | |
download | gcc-58d745ec901a3707c1e6487ce8c0eca387ec5f42.tar.gz |
genflags.c (gen_macro): Delete.
gcc/
* genflags.c (gen_macro): Delete.
(gen_proto): Don't create GEN.*CALL.* macros.
* gensupport.h (get_file_location): Declare.
* gensupport.c (rtx_locs): New variable.
(read_md_rtx): Record rtx locations.
(get_file_location): New function.
* target-insns.def (call, call_pop, call_value, call_value_pop)
(sibcall, sibcall_value): New patterns.
* gentarget-def.c (parse_argument): New function.
(def_target_insn): Use it. Handle optional operands. Raise an
error if an .md pattern has the wrong number of operands for the
pattern name. Remove the names of unused operands from the prototype.
* builtins.c (expand_builtin_apply): Use targetm functions
instead of HAVE_call_value and GEN_CALL_VALUE.
* calls.c (emit_call_1): Likewise. Remove support for sibcall_pop
and sibcall_value_pop.
* config/aarch64/aarch64.md (untyped_call): Use gen_call instead
of GEN_CALL.
* config/alpha/alpha.md (untyped_call): Likewise.
* config/iq2000/iq2000.md (untyped_call): Likewise.
* config/m68k/m68k.md (untyped_call): Likewise.
* config/mips/mips.md (untyped_call): Likewise.
* config/pa/pa.md (untyped_call): Likewise.
* config/rs6000/rs6000.md (untyped_call): Likewise.
* config/sparc/sparc.md (untyped_call): Likewise.
* config/tilegx/tilegx.md (untyped_call): Likewise.
* config/tilepro/tilepro.md (untyped_call): Likewise.
* config/visium/visium.md (untyped_call): Likewise.
* config/alpha/alpha.c (alpha_emit_xfloating_libcall): Use
gen_call_value instead of GEN_CALL_VALUE.
* config/arm/arm.md (untyped_call): Likewise.
* config/cr16/cr16.c (cr16_function_arg): Remove reference to
GEN_CALL.
From-SVN: r227143
Diffstat (limited to 'gcc/gentarget-def.c')
-rw-r--r-- | gcc/gentarget-def.c | 106 |
1 files changed, 84 insertions, 22 deletions
diff --git a/gcc/gentarget-def.c b/gcc/gentarget-def.c index e5e291ecfd7..9c8a2503ee2 100644 --- a/gcc/gentarget-def.c +++ b/gcc/gentarget-def.c @@ -60,6 +60,43 @@ static hash_table <nofree_string_hash> *stubs; from the C condition to the function name. */ static hash_map <nofree_string_hash, const char *> *have_funcs; +/* Return true if the part of the prototype at P is for an argument + name. If so, point *END_OUT to the first character after the name. + If OPNO_OUT is nonnull, set *OPNO_OUT to the number of the associated + operand. If REQUIRED_OUT is nonnull, set *REQUIRED_OUT to whether the + .md pattern is required to match the operand. */ + +static bool +parse_argument (const char *p, const char **end_out, + unsigned int *opno_out = 0, + bool *required_out = 0) +{ + while (ISSPACE (*p)) + p++; + if (p[0] == 'x' && ISDIGIT (p[1])) + { + p += 1; + if (required_out) + *required_out = true; + } + else if (p[0] == 'o' && p[1] == 'p' && p[2] == 't' && ISDIGIT (p[3])) + { + p += 3; + if (required_out) + *required_out = false; + } + else + return false; + + char *endptr; + unsigned int opno = strtol (p, &endptr, 10); + if (opno_out) + *opno_out = opno; + *end_out = endptr; + return true; +} + + /* Output hook definitions for pattern NAME, which has target-insns.def prototype PROTOTYPE. */ @@ -78,21 +115,27 @@ def_target_insn (const char *name, const char *prototype) char *suffix = XALLOCAVEC (char, strlen (prototype) + 1); i = 0; unsigned int opno = 0; + unsigned int required_ops = 0; + unsigned int this_opno; + bool required_p; for (const char *p = prototype; *p; ++p) - if (*p == 'x' && ISDIGIT (p[1])) + if (parse_argument (p, &p, &this_opno, &required_p)) { - /* This should be a parameter name of the form "x<OPNO>". - That doesn't contribute to the suffix, so skip ahead and - process the following character. */ - char *endptr; - if ((unsigned int) strtol (p + 1, &endptr, 10) != opno - || (*endptr != ',' && *endptr != ')')) + if (this_opno != opno || (*p != ',' && *p != ')')) { error ("invalid prototype for '%s'", name); exit (FATAL_EXIT_CODE); } + if (required_p && required_ops < opno) + { + error ("prototype for '%s' has required operands after" + " optional operands", name); + exit (FATAL_EXIT_CODE); + } opno += 1; - p = endptr; + if (required_p) + required_ops = opno; + /* Skip over ')'s. */ if (*p == ',') suffix[i++] = '_'; } @@ -117,6 +160,22 @@ def_target_insn (const char *name, const char *prototype) const char *have_name = name; if (rtx insn = insns->find_with_hash (name, hash)) { + pattern_stats stats; + get_pattern_stats (&stats, XVEC (insn, 1)); + unsigned int actual_ops = stats.num_generator_args; + if (opno == required_ops && opno != actual_ops) + error_at (get_file_location (insn), + "'%s' must have %d operands (excluding match_dups)", + name, required_ops); + else if (actual_ops < required_ops) + error_at (get_file_location (insn), + "'%s' must have at least %d operands (excluding match_dups)", + name, required_ops); + else if (actual_ops > opno) + error_at (get_file_location (insn), + "'%s' must have no more than %d operands" + " (excluding match_dups)", name, opno); + const char *test = XSTR (insn, 2); truth = maybe_eval_c_test (test); gcc_assert (truth != 0); @@ -139,13 +198,23 @@ def_target_insn (const char *name, const char *prototype) have_name = entry; } printf ("\nstatic rtx_insn *\n"); - printf ("target_gen_%s %s\n", name, prototype); - printf ("{\n"); + printf ("target_gen_%s ", name); + /* Print the prototype with the argument names after ACTUAL_OPS + removed. */ + const char *p = prototype, *end; + while (*p) + if (parse_argument (p, &end, &this_opno) && this_opno >= actual_ops) + p = end; + else + fputc (*p++, stdout); + + printf ("\n{\n"); if (truth < 0) printf (" gcc_checking_assert (targetm.have_%s ());\n", name); printf (" return insnify (gen_%s (", name); - for (i = 0; i < opno; ++i) - printf ("%sx%d", i == 0 ? "" : ", ", i); + for (i = 0; i < actual_ops; ++i) + printf ("%s%s%d", i == 0 ? "" : ", ", + i < required_ops ? "x" : "opt", i); printf ("));\n"); printf ("}\n"); } @@ -157,18 +226,11 @@ def_target_insn (const char *name, const char *prototype) *slot = xstrdup (suffix); printf ("\nstatic rtx_insn *\n"); printf ("invalid_%s ", suffix); + /* Print the prototype with the argument names removed. */ const char *p = prototype; while (*p) - { - if (p[0] == 'x' && ISDIGIT (p[1])) - { - char *endptr; - strtol (p + 1, &endptr, 10); - p = endptr; - } - else - fputc (*p++, stdout); - } + if (!parse_argument (p, &p)) + fputc (*p++, stdout); printf ("\n{\n"); printf (" gcc_unreachable ();\n"); printf ("}\n"); |