summaryrefslogtreecommitdiff
path: root/gcc/genoutput.c
diff options
context:
space:
mode:
authoramylaar <amylaar@138bc75d-0d04-0410-961f-82ee72b054a4>2012-10-15 12:44:40 +0000
committeramylaar <amylaar@138bc75d-0d04-0410-961f-82ee72b054a4>2012-10-15 12:44:40 +0000
commit66799bd7e24563598c908c5c4670372e84410e2d (patch)
tree4deb78426b9c9cb2f9d67c7e7b56ac4f7299338e /gcc/genoutput.c
parent45767e715e28c262df3dc7fe18d5ca0ff18d4e17 (diff)
downloadgcc-66799bd7e24563598c908c5c4670372e84410e2d.tar.gz
* genoutput.c (process_template): Process '*' in '@' alternatives.
* doc/md.texi (node Output Statement): Provide example for the above. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@192457 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/genoutput.c')
-rw-r--r--gcc/genoutput.c66
1 files changed, 58 insertions, 8 deletions
diff --git a/gcc/genoutput.c b/gcc/genoutput.c
index 2c6104cb25a..d736d2c027f 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
{