===================================================================
@@ -11381,4 +11381,13 @@ name and same types of iterator. For ex
would produce a single set of functions that handles both
@code{INTEGER_MODES} and @code{FLOAT_MODES}.
+It is also possible for these @samp{@@} patterns to have different
+numbers of operands from each other. For example, patterns with
+a binary rtl code might take three operands (one output and two inputs)
+while patterns with a ternary rtl code might take four operands (one
+output and three inputs). This combination would produce separate
+@samp{maybe_gen_@var{name}} and @samp{gen_@var{name}} functions for
+each operand count, but it would still produce a single
+@samp{maybe_code_for_@var{name}} and a single @samp{code_for_@var{name}}.
+
@end ifset
===================================================================
@@ -811,42 +811,45 @@ handle_overloaded_code_for (overloaded_n
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");
+ /* 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");
+ /* 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");
+ }
}
int
===================================================================
@@ -134,31 +134,43 @@ handle_overloaded_code_for (FILE *file,
static void
handle_overloaded_gen (FILE *file, overloaded_name *oname)
{
- pattern_stats stats;
- get_pattern_stats (&stats, XVEC (oname->first_instance->insn, 1));
+ unsigned HOST_WIDE_INT seen = 0;
+ for (overloaded_instance *instance = oname->first_instance->next;
+ instance; instance = instance->next)
+ {
+ 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;
- fprintf (file, "\nextern rtx maybe_gen_%s (", oname->name);
- for (unsigned int i = 0; i < oname->arg_types.length (); ++i)
- fprintf (file, "%s%s", i == 0 ? "" : ", ", oname->arg_types[i]);
- for (int i = 0; i < stats.num_generator_args; ++i)
- fprintf (file, ", rtx");
- fprintf (file, ");\n");
+ seen |= mask;
- fprintf (file, "inline rtx\ngen_%s (", oname->name);
- for (unsigned int i = 0; i < oname->arg_types.length (); ++i)
- fprintf (file, "%s%s arg%d", i == 0 ? "" : ", ", oname->arg_types[i], i);
- for (int i = 0; i < stats.num_generator_args; ++i)
- fprintf (file, ", rtx x%d", i);
- fprintf (file, ")\n{\n rtx res = maybe_gen_%s (", oname->name);
- for (unsigned int i = 0; i < oname->arg_types.length (); ++i)
- fprintf (file, "%sarg%d", i == 0 ? "" : ", ", i);
- for (int i = 0; i < stats.num_generator_args; ++i)
- fprintf (file, ", x%d", i);
- fprintf (file,
- ");\n"
- " gcc_assert (res);\n"
- " return res;\n"
- "}\n");
+ fprintf (file, "\nextern rtx maybe_gen_%s (", oname->name);
+ for (unsigned int i = 0; i < oname->arg_types.length (); ++i)
+ fprintf (file, "%s%s", i == 0 ? "" : ", ", oname->arg_types[i]);
+ for (int i = 0; i < stats.num_generator_args; ++i)
+ fprintf (file, ", rtx");
+ fprintf (file, ");\n");
+
+ fprintf (file, "inline rtx\ngen_%s (", oname->name);
+ for (unsigned int i = 0; i < oname->arg_types.length (); ++i)
+ fprintf (file, "%s%s arg%d", i == 0 ? "" : ", ",
+ oname->arg_types[i], i);
+ for (int i = 0; i < stats.num_generator_args; ++i)
+ fprintf (file, ", rtx x%d", i);
+ fprintf (file, ")\n{\n rtx res = maybe_gen_%s (", oname->name);
+ for (unsigned int i = 0; i < oname->arg_types.length (); ++i)
+ fprintf (file, "%sarg%d", i == 0 ? "" : ", ", i);
+ for (int i = 0; i < stats.num_generator_args; ++i)
+ fprintf (file, ", x%d", i);
+ fprintf (file,
+ ");\n"
+ " gcc_assert (res);\n"
+ " return res;\n"
+ "}\n");
+ }
}
int
===================================================================
@@ -500,12 +500,14 @@ replace_operands_with_dups (rtx x)
{
newx = rtx_alloc (MATCH_DUP);
XINT (newx, 0) = XINT (x, 0);
+ x = newx;
}
else if (GET_CODE (x) == MATCH_OPERATOR)
{
newx = rtx_alloc (MATCH_OP_DUP);
XINT (newx, 0) = XINT (x, 0);
XVEC (newx, 1) = XVEC (x, 2);
+ x = newx;
}
else
newx = shallow_copy_rtx (x);