aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJ"orn Rennecke <joern.rennecke@arc.com>2012-10-15 12:44:40 +0000
committerJoern Rennecke <amylaar@gcc.gnu.org>2012-10-15 13:44:40 +0100
commit94c765ab35ed0b6739e88ce01834309a862cc789 (patch)
tree4deb78426b9c9cb2f9d67c7e7b56ac4f7299338e /gcc
parentc3dc2ac8f43fe6870a2fee7c301645699db1ff56 (diff)
downloadgcc-94c765ab35ed0b6739e88ce01834309a862cc789.zip
gcc-94c765ab35ed0b6739e88ce01834309a862cc789.tar.gz
gcc-94c765ab35ed0b6739e88ce01834309a862cc789.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/doc/md.texi16
-rw-r--r--gcc/genoutput.c66
3 files changed, 79 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7447694..37d9b00 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index f17d55e..6a1db6a 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -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
diff --git a/gcc/genoutput.c b/gcc/genoutput.c
index 2c6104c..d736d2c0 100644
--- a/gcc/genoutput.c
+++ b/gcc/genoutput.c
@@ -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
{