genoutput.c (process_template): Process '*' in '@' alternatives.

* genoutput.c (process_template): Process '*' in '@' alternatives.
	* doc/md.texi (node Output Statement): Provide example for the above.

From-SVN: r192457
This commit is contained in:
J"orn Rennecke 2012-10-15 12:44:40 +00:00 committed by Joern Rennecke
parent c3dc2ac8f4
commit 94c765ab35
3 changed files with 79 additions and 8 deletions

View file

@ -1,3 +1,8 @@
2012-10-15 J"orn Rennecke <joern.rennecke@arc.com>
* genoutput.c (process_template): Process '*' in '@' alternatives.
* doc/md.texi (node Output Statement): Provide example for the above.
2012-10-15 Richard Guenther <rguenther@suse.de>
PR tree-optimization/54920

View file

@ -665,6 +665,22 @@ as follows, having the output control string start with a @samp{@@}:
@end group
@end smallexample
If you just need a little bit of C code in one (or a few) alternatives,
you can use @samp{*} inside of a @samp{@@} multi-alternative template:
@smallexample
@group
(define_insn ""
[(set (match_operand:SI 0 "general_operand" "=r,<,m")
(const_int 0))]
""
"@@
clrreg %0
* return stack_mem_p (operands[0]) ? \"push 0\" : \"clrmem %0\";
clrmem %0")
@end group
@end smallexample
@node Predicates
@section Predicates
@cindex predicates

View file

@ -1,6 +1,6 @@
/* Generate code from to output assembler insns as recognized from rtl.
Copyright (C) 1987, 1988, 1992, 1994, 1995, 1997, 1998, 1999, 2000, 2002,
2003, 2004, 2005, 2007, 2008, 2009, 2010, 2012
2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011, 2012
Free Software Foundation, Inc.
This file is part of GCC.
@ -662,19 +662,55 @@ process_template (struct data *d, const char *template_code)
list of assembler code templates, one for each alternative. */
else if (template_code[0] == '@')
{
d->template_code = 0;
d->output_format = INSN_OUTPUT_FORMAT_MULTI;
int found_star = 0;
printf ("\nstatic const char * const output_%d[] = {\n", d->code_number);
for (cp = &template_code[1]; *cp; )
{
while (ISSPACE (*cp))
cp++;
if (*cp == '*')
found_star = 1;
while (!IS_VSPACE (*cp) && *cp != '\0')
++cp;
}
d->template_code = 0;
if (found_star)
{
d->output_format = INSN_OUTPUT_FORMAT_FUNCTION;
puts ("\nstatic const char *");
printf ("output_%d (rtx *operands ATTRIBUTE_UNUSED, "
"rtx insn ATTRIBUTE_UNUSED)\n", d->code_number);
puts ("{");
puts (" switch (which_alternative)\n {");
}
else
{
d->output_format = INSN_OUTPUT_FORMAT_MULTI;
printf ("\nstatic const char * const output_%d[] = {\n",
d->code_number);
}
for (i = 0, cp = &template_code[1]; *cp; )
{
const char *ep, *sp;
const char *ep, *sp, *bp;
while (ISSPACE (*cp))
cp++;
printf (" \"");
bp = cp;
if (found_star)
{
printf (" case %d:", i);
if (*cp == '*')
{
printf ("\n ");
cp++;
}
else
printf (" return \"");
}
else
printf (" \"");
for (ep = sp = cp; !IS_VSPACE (*ep) && *ep != '\0'; ++ep)
if (!ISSPACE (*ep))
@ -690,7 +726,18 @@ process_template (struct data *d, const char *template_code)
cp++;
}
printf ("\",\n");
if (!found_star)
puts ("\",");
else if (*bp != '*')
puts ("\";");
else
{
/* The usual action will end with a return.
If there is neither break or return at the end, this is
assumed to be intentional; this allows to have multiple
consecutive alternatives share some code. */
puts ("");
}
i++;
}
if (i == 1)
@ -700,7 +747,10 @@ process_template (struct data *d, const char *template_code)
error_with_line (d->lineno,
"wrong number of alternatives in the output template");
printf ("};\n");
if (found_star)
puts (" default: gcc_unreachable ();\n }\n}");
else
printf ("};\n");
}
else
{