diff options
author | Richard Sandiford <richard.sandiford@arm.com> | 2019-07-12 07:54:23 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2019-07-12 07:54:23 +0000 |
commit | d281492de84960b5885f88fffeeb226650f5141d (patch) | |
tree | 28304a490e6a430efab5d43f9479dbef727543b4 /gcc/genemit.c | |
parent | 1fdd6f0412922eb7438cbbadbb805fce8cc77485 (diff) | |
download | gcc-d281492de84960b5885f88fffeeb226650f5141d.zip gcc-d281492de84960b5885f88fffeeb226650f5141d.tar.gz gcc-d281492de84960b5885f88fffeeb226650f5141d.tar.bz2 |
Support multiple operand counts for .md @ patterns
This patch extends the support for "@..." pattern names so that
the patterns can have different numbers of operands. This allows
things like binary and ternary operations to be handled in a
consistent way, a bit like optabs. The generators assert that
the number of operands passed is correct for the underlying
instruction.
Also, replace_operands_with_dups iterated over the old rtx format
even after having decided to do a replacement, which broke with
match_operator.
2019-07-12 Richard Sandiford <richard.sandiford@arm.com>
gcc/
* doc/md.texi: Document that @ patterns can have different
numbers of operands.
* genemit.c (handle_overloaded_gen): Handle this case.
* genopinit.c (handle_overloaded_gen): Likewise.
* gensupport.c (replace_operands_with_dups): Iterate over
the new rtx's format rather than the old one's.
From-SVN: r273432
Diffstat (limited to 'gcc/genemit.c')
-rw-r--r-- | gcc/genemit.c | 65 |
1 files changed, 34 insertions, 31 deletions
diff --git a/gcc/genemit.c b/gcc/genemit.c index 83f86a3..3ff8197 100644 --- a/gcc/genemit.c +++ b/gcc/genemit.c @@ -811,42 +811,45 @@ handle_overloaded_code_for (overloaded_name *oname) static void handle_overloaded_gen (overloaded_name *oname) { + unsigned HOST_WIDE_INT seen = 0; /* All patterns must have the same number of operands. */ - pattern_stats stats; - get_pattern_stats (&stats, XVEC (oname->first_instance->insn, 1)); for (overloaded_instance *instance = oname->first_instance->next; instance; instance = instance->next) { - pattern_stats stats2; - get_pattern_stats (&stats2, XVEC (instance->insn, 1)); - if (stats.num_generator_args != stats2.num_generator_args) - fatal_at (get_file_location (instance->insn), - "inconsistent number of operands for '%s'; " - "this instance has %d, but previous instances had %d", - oname->name, stats2.num_generator_args, - stats.num_generator_args); + pattern_stats stats; + get_pattern_stats (&stats, XVEC (instance->insn, 1)); + unsigned HOST_WIDE_INT mask + = HOST_WIDE_INT_1U << stats.num_generator_args; + if (seen & mask) + continue; + + seen |= mask; + + /* Print the function prototype. */ + printf ("\nrtx\nmaybe_gen_%s (", oname->name); + print_overload_arguments (oname); + for (int i = 0; i < stats.num_generator_args; ++i) + printf (", rtx x%d", i); + printf (")\n{\n"); + + /* Use maybe_code_for_*, instead of duplicating the selection + logic here. */ + printf (" insn_code code = maybe_code_for_%s (", oname->name); + for (unsigned int i = 0; i < oname->arg_types.length (); ++i) + printf ("%sarg%d", i == 0 ? "" : ", ", i); + printf (");\n" + " if (code != CODE_FOR_nothing)\n" + " {\n" + " gcc_assert (insn_data[code].n_generator_args == %d);\n" + " return GEN_FCN (code) (", stats.num_generator_args); + for (int i = 0; i < stats.num_generator_args; ++i) + printf ("%sx%d", i == 0 ? "" : ", ", i); + printf (");\n" + " }\n" + " else\n" + " return NULL_RTX;\n" + "}\n"); } - - /* Print the function prototype. */ - printf ("\nrtx\nmaybe_gen_%s (", oname->name); - print_overload_arguments (oname); - for (int i = 0; i < stats.num_generator_args; ++i) - printf (", rtx x%d", i); - printf (")\n{\n"); - - /* Use maybe_code_for_*, instead of duplicating the selection logic here. */ - printf (" insn_code code = maybe_code_for_%s (", oname->name); - for (unsigned int i = 0; i < oname->arg_types.length (); ++i) - printf ("%sarg%d", i == 0 ? "" : ", ", i); - printf (");\n" - " if (code != CODE_FOR_nothing)\n" - " return GEN_FCN (code) ("); - for (int i = 0; i < stats.num_generator_args; ++i) - printf ("%sx%d", i == 0 ? "" : ", ", i); - printf (");\n" - " else\n" - " return NULL_RTX;\n" - "}\n"); } int |