Message ID | 20120919112754.aj5o7ugam84gkg8g-nzlynne@webmail.spamcop.net |
---|---|
State | New |
Headers | show |
Joern Rennecke a écrit: > Index: doc/md.texi > =================================================================== > --- doc/md.texi (revision 191429) > +++ doc/md.texi (working copy) > @@ -665,6 +665,22 @@ (define_insn "" > @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\"; ---------------------------------------------------^ Isn't there a backslash missing? > + clrmem %0") > +@end group > +@end smallexample > + > @node Predicates > @section Predicates > @cindex predicates > 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 > {
Quoting Georg-Johann Lay <gjl@gcc.gnu.org>: >> + * return stack_mem_p (operands[0]) ? \"push 0" : \"clrmem %0\"; > ---------------------------------------------------^ > > Isn't there a backslash missing? Oops, yes, there is.
Index: doc/md.texi =================================================================== --- doc/md.texi (revision 191429) +++ doc/md.texi (working copy) @@ -665,6 +665,22 @@ (define_insn "" @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 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 {
Quoting Richard Guenther <richard.guenther@gmail.com>: > Something smaller (but pointless) woudl be nice. I have attached the patch with the example added to the documentation. Again, bootstrapped on i686-pc-linux-gnu. 2011-09-19 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.