This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RFA: Process '*' in '@'-output-template alternatives


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.
2008-11-19  J"orn Rennecke  <joern.rennecke@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
     {

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]