On Wed, Sep 19, 2012 at 3:51 AM, Joern Rennecke <amyl...@spamcop.net> wrote: > I am about to submit the ARCompact target port; this port needs a few > patches to target-independent code. > > There is a move pattern with 20 alternatives; a few of them need a simple > function call to decide which output pattern to use. With the '@'-syntax > for multi-alternative templates, each alternative is still a one-liner. > Requiring to transform this into some switch statement would make the thing > several times as big, and very hard to take in; besides, it is generally > a maintenance issue if you have to completely rewrite a multi-alternative > template if you just change one alternative from a constant to some C-code, > or vice versa for the last non-literal alternative. > > The attached patch makes the '*' syntax for C code fragments available for > individual alternatives of an '@' multi-alternative output template. > It does this by translating the input into a switch statement in the > generated file, so in a way this is just syntactic sugar, but it's syntactic > sugar that makes some machine descriptions easier to write and change. > > Bootstrapped in revision 191429 for i686-pc-linux-gnu. > > I've been wondering if it'd make sense to also support for '{' / '}' , > but at least in the ARCompact context, I think the use of that syntax > inside a multi-alternative template would reduce rather than improve > legibility, so, having no application for the '{' / '}' in that place, > there seems to be no use in adding support for that at this point in time.
I think that needs to be documented somewhere in the internals manual, possibly with an example. Richard. > 2008-11-19 J"orn Rennecke <joern.renne...@arc.com> > > * genoutput.c (process_template): Process '*' in '@' alternatives. > > Index: genoutput.c > =================================================================== > --- genoutput.c (revision 191429) > +++ genoutput.c (working copy) > @@ -662,19 +662,55 @@ process_template (struct data *d, const > 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 > 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 > 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 > { >