]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
recog.h (INSN_OUTPUT_FORMAT_*): New.
authorRichard Henderson <rth@cygnus.com>
Tue, 14 Sep 1999 04:19:34 +0000 (21:19 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Tue, 14 Sep 1999 04:19:34 +0000 (21:19 -0700)
        * recog.h (INSN_OUTPUT_FORMAT_*): New.
        (struct insn_data): Merge `template' and `outfun' into `output'.
        Add `output_format'.
        * genoutput.c (INSN_OUTPUT_FORMAT_*): New.
        (struct data): Remove `outfun'; add `output_format'.
        (name_for_index): Remove declaration.
        (output_insn_data): Handle output formats.
        (process_template): Emit the bare array for @.
        (gen_expand, gen_split): Set output_format to NONE.
        * output.h (get_insn_template): Declare.
        * final.c (get_insn_template): New.
        (final_scan_insn): Use it.
        * toplev.c (compile_file): Likewise.

        * c4x/c4x.c (c4x_process_after_reload): Likewise.
        * i860/i860.c (output_delayed_branch): Likewise.
        (output_delay_insn): Likewise.

From-SVN: r29389

gcc/ChangeLog
gcc/config/c4x/c4x.c
gcc/config/i860/i860.c
gcc/final.c
gcc/genoutput.c
gcc/output.h
gcc/recog.h
gcc/toplev.c

index 6d2aae3881aa92a3052ddfe834fe00c5d069c2a4..b694c997ab008e519cb266402215ba73d15e11ce 100644 (file)
@@ -1,3 +1,23 @@
+Mon Sep 13 21:06:01 1999  Richard Henderson  <rth@cygnus.com>
+
+       * recog.h (INSN_OUTPUT_FORMAT_*): New.
+       (struct insn_data): Merge `template' and `outfun' into `output'.
+       Add `output_format'.
+       * genoutput.c (INSN_OUTPUT_FORMAT_*): New.
+       (struct data): Remove `outfun'; add `output_format'.
+       (name_for_index): Remove declaration.
+       (output_insn_data): Handle output formats.
+       (process_template): Emit the bare array for @.
+       (gen_expand, gen_split): Set output_format to NONE.
+       * output.h (get_insn_template): Declare.
+       * final.c (get_insn_template): New.
+       (final_scan_insn): Use it.
+       * toplev.c (compile_file): Likewise.
+
+       * c4x/c4x.c (c4x_process_after_reload): Likewise.
+       * i860/i860.c (output_delayed_branch): Likewise.
+       (output_delay_insn): Likewise.
+
 1999-09-13  Alexandre Oliva  <oliva@lsd.ic.unicamp.br>
 
        * rtl.c (obstack_alloc_rtx): Removed.
index b3f5a54345eda6609e16c7b174f3f036b913ee08..517ba0f189b79d346c1951da23bb5a042c01d214 100644 (file)
@@ -2196,7 +2196,7 @@ c4x_process_after_reload (first)
            {
              const char *template;
 
-             template = insn_data[insn_code_number].template;
+             template = get_insn_template (insn_code_number, insn);
              if (template && template[0] == '#' && template[1] == '\0')
                {
                  rtx new = try_split (PATTERN(insn), insn, 0);
index a6e9458a8b928046bddaf49c56bd1db4694c9e70..bdbccfb1f8167f627a36cebb7d3342b57051dfb0 100644 (file)
@@ -1456,10 +1456,7 @@ output_delayed_branch (template, operands, insn)
       if (! constrain_operands (1))
        fatal_insn_not_found (delay_insn);
 
-      template = insn_data[insn_code_number].template;
-      if (template == 0)
-       template = ((*insn_data[insn_code_number].outfun)
-                   (recog_data.operand, delay_insn));
+      template = get_insn_template (insn_code_number, delay_insn);
       output_asm_insn (template, recog_data.operand);
     }
   CC_STATUS_INIT;
@@ -1513,10 +1510,7 @@ output_delay_insn (delay_insn)
   /* Now get the template for what this insn would
      have been, without the branch.  */
 
-  template = insn_data[insn_code_number].template;
-  if (template == 0)
-    template = ((*insn_data[insn_code_number].outfun)
-               (recog_data.operand, delay_insn));
+  template = get_insn_template (insn_code_number, delay_insn);
   output_asm_insn (template, recog_data.operand);
   return "";
 }
index e81895bd3bcc9a244dbf918799da85b5557236dc..7046344e36dbb7abd867bf4c20ac1932aa9c0330 100644 (file)
@@ -2034,6 +2034,27 @@ final (first, file, optimize, prescan)
   free_insn_eh_region ();
 }
 \f
+const char *
+get_insn_template (code, insn)
+     int code;
+     rtx insn;
+{
+  const void *output = insn_data[code].output;
+  switch (insn_data[code].output_format)
+    {
+    case INSN_OUTPUT_FORMAT_SINGLE:
+      return (const char *) output;
+    case INSN_OUTPUT_FORMAT_MULTI:
+      return ((const char * const *) output)[which_alternative];
+    case INSN_OUTPUT_FORMAT_FUNCTION:
+      if (insn == NULL)
+       abort ();
+      return (* (insn_output_fn) output) (recog_data.operand, insn);
+
+    default:
+      abort ();
+    }
+}
 /* The final scan for one insn, INSN.
    Args are same as in `final', except that INSN
    is the insn being scanned.
@@ -2895,25 +2916,18 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
          dwarf2out_frame_debug (insn);
 #endif
 
-       /* If the proper template needs to be chosen by some C code,
-          run that code and get the real template.  */
+       /* Find the proper template for this insn.  */
+       template = get_insn_template (insn_code_number, insn);
 
-       template = insn_data[insn_code_number].template;
+       /* If the C code returns 0, it means that it is a jump insn
+          which follows a deleted test insn, and that test insn
+          needs to be reinserted.  */
        if (template == 0)
          {
-           template = ((*insn_data[insn_code_number].outfun)
-                       (recog_data.operand, insn));
-
-           /* If the C code returns 0, it means that it is a jump insn
-              which follows a deleted test insn, and that test insn
-              needs to be reinserted.  */
-           if (template == 0)
-             {
-               if (prev_nonnote_insn (insn) != last_ignored_compare)
-                 abort ();
-               new_block = 0;
-               return prev_nonnote_insn (insn);
-             }
+           if (prev_nonnote_insn (insn) != last_ignored_compare)
+             abort ();
+           new_block = 0;
+           return prev_nonnote_insn (insn);
          }
 
        /* If the template is the string "#", it means that this insn must
index 9c44d7e6475cfe7061a07c7bac33a9d7488c8f80..d40433f294280dfccd94dd85d21e7d04d275f635 100644 (file)
@@ -29,27 +29,24 @@ Boston, MA 02111-1307, USA.  */
      a. `name' is the name for that pattern.  Nameless patterns are
      given a name.
 
-     b. `template' is the template for output of that insn,
-
-     c. `outfun' is the function that returns a template to use for output of
-     that insn.  This is used only in the cases where the template is not
-     constant.  These cases are specified by a * or @ at the beginning of the
-     template string in the machine description.  They are identified for the
-     sake of other parts of the compiler by a zero element in `template'.
-  
-     d. `genfun' is the function to generate a body for that pattern,
+     b. `output' hold either the output template, an array of output
+     templates, or an output function.
+
+     c. `genfun' is the function to generate a body for that pattern,
      given operands as arguments.
 
-     e. `n_operands' is the number of distinct operands in the pattern
+     d. `n_operands' is the number of distinct operands in the pattern
      for that insn,
 
-     f. `n_dups' is the number of match_dup's that appear in the insn's
+     e. `n_dups' is the number of match_dup's that appear in the insn's
      pattern.  This says how many elements of `recog_data.dup_loc' are
      significant after an insn has been recognized.
 
-     g. `n_alternatives' is the number of alternatives in the constraints
+     f. `n_alternatives' is the number of alternatives in the constraints
      of each pattern.
 
+     g. `output_format' tells what type of thing `output' is.
+
      h. `operand' is the base of an array of operand data for the insn.
 
    2. An array of `struct insn_operand data', used by `operand' above.
@@ -144,6 +141,13 @@ static struct operand_data null_operand =
 static struct operand_data *odata = &null_operand;
 static struct operand_data **odata_end = &null_operand.next;
 
+/* Must match the constants in recog.h.  */
+
+#define INSN_OUTPUT_FORMAT_NONE         0       /* abort */
+#define INSN_OUTPUT_FORMAT_SINGLE       1       /* const char * */
+#define INSN_OUTPUT_FORMAT_MULTI        2       /* const char * const * */
+#define INSN_OUTPUT_FORMAT_FUNCTION     3       /* const char * (*)(...) */
+
 /* Record in this chain all information that we will output,
    associated with the code number of the insn.  */
 
@@ -151,14 +155,14 @@ struct data
 {
   struct data *next;
   char *name;
-  char *template;              /* string such as "movl %1,%0" */
+  char *template;
   int code_number;
   int index_number;
   int n_operands;              /* Number of operands this insn recognizes */
   int n_dups;                  /* Number times match_dup appears in pattern */
   int n_alternatives;          /* Number of alternatives in each constraint */
-  char outfun;                 /* Nonzero means this has an output function */
   int operand_number;          /* Operand index in the big array.  */
+  int output_format;           /* INSN_OUTPUT_FORMAT_*.  */
   struct operand_data operand[MAX_MAX_OPERANDS];
 };
 
@@ -172,7 +176,6 @@ static struct data *idata, **idata_end = &idata;
 static int have_constraints;
 
 \f
-static char * name_for_index PROTO((int));
 static void output_prologue PROTO((void));
 static void output_predicate_decls PROTO((void));
 static void output_operand_data PROTO((void));
@@ -353,15 +356,21 @@ output_insn_data ()
            printf ("    \"%s+%d\",\n", last_name, name_offset);
        }
 
-      if (d->template)
-       printf ("    \"%s\",\n", d->template);
-      else
-       printf ("    0,\n");
-
-      if (d->outfun)
-       printf ("    output_%d,\n", d->code_number);
-      else
-       printf ("    0,\n");
+      switch (d->output_format)
+       {
+       case INSN_OUTPUT_FORMAT_NONE:
+         printf ("    0,\n");
+         break;
+       case INSN_OUTPUT_FORMAT_SINGLE:
+         printf ("    \"%s\",\n", d->template);
+         break;
+       case INSN_OUTPUT_FORMAT_MULTI:
+       case INSN_OUTPUT_FORMAT_FUNCTION:
+         printf ("    output_%d,\n", d->code_number);
+         break;
+       default:
+         abort ();
+       }
 
       if (d->name && d->name[0] != '*')
        printf ("    gen_%s,\n", d->name);
@@ -371,7 +380,8 @@ output_insn_data ()
       printf ("    &operand_data[%d],\n", d->operand_number);
       printf ("    %d,\n", d->n_operands);
       printf ("    %d,\n", d->n_dups);
-      printf ("    %d\n", d->n_alternatives);
+      printf ("    %d,\n", d->n_alternatives);
+      printf ("    %d\n", d->output_format);
 
       printf("  },\n");
     }
@@ -637,44 +647,39 @@ process_template (d, template)
   register char *cp;
   register int i;
 
-  /* We need to consider only the instructions whose assembler code template
-     starts with a * or @.  These are the ones where C code is run to decide
-     on a template to use.  So for all others just return now.  */
-
-  if (template[0] != '*' && template[0] != '@')
+  /* Templates starting with * contain straight code to be run.  */
+  if (template[0] == '*')
     {
-      d->template = template;
-      d->outfun = 0;
-      return;
-    }
+      d->template = 0;
+      d->output_format = INSN_OUTPUT_FORMAT_FUNCTION;
 
-  d->template = 0;
-  d->outfun = 1;
-
-  printf ("\nstatic const char *output_%d PROTO ((rtx *, rtx));\n",
-         d->code_number);
-  printf ("\nstatic const char *\n");
-  printf ("output_%d (operands, insn)\n", d->code_number);
-  printf ("     rtx *operands ATTRIBUTE_UNUSED;\n");
-  printf ("     rtx insn ATTRIBUTE_UNUSED;\n");
-  printf ("{\n");
+      printf ("\nstatic const char *output_%d PROTO ((rtx *, rtx));\n",
+             d->code_number);
+      puts ("\nstatic const char *");
+      printf ("output_%d (operands, insn)\n", d->code_number);
+      puts ("     rtx *operands ATTRIBUTE_UNUSED;");
+      puts ("     rtx insn ATTRIBUTE_UNUSED;");
+      puts ("{");
+
+      puts (template + 1);
+      puts ("}");
+    }
 
   /* If the assembler code template starts with a @ it is a newline-separated
-     list of assembler code templates, one for each alternative.  So produce
-     a routine to select the correct one.  */
-
-  if (template[0] == '@')
+     list of assembler code templates, one for each alternative.  */
+  else if (template[0] == '@')
     {
+      d->template = 0;
+      d->output_format = INSN_OUTPUT_FORMAT_MULTI;
 
-      printf ("  static const char *const strings_%d[] = {\n",
-             d->code_number);
+      printf ("\nstatic const char * const output_%d[] = {\n", d->code_number);
 
       for (i = 0, cp = &template[1]; *cp; )
        {
          while (*cp == '\n' || *cp == ' ' || *cp== '\t')
            cp++;
 
-         printf ("    \"");
+         printf ("  \"");
          while (*cp != '\n' && *cp != '\0')
            {
              putchar (*cp);
@@ -685,29 +690,13 @@ process_template (d, template)
          i++;
        }
 
-      printf ("  };\n");
-      printf ("  return strings_%d[which_alternative];\n", d->code_number);
-
-      if (i != d->n_alternatives)
-       fatal ("Insn pattern %d has %d alternatives but %d assembler choices",
-              d->index_number, d->n_alternatives, i);
-
+      printf ("};\n");
     }
   else
     {
-      /* The following is done in a funny way to get around problems in
-        VAX-11 "C" on VMS.  It is the equivalent of:
-        printf ("%s\n", &template[1])); */
-      cp = &template[1];
-      while (*cp)
-       {
-         putchar (*cp);
-         cp++;
-       }
-      putchar ('\n');
+      d->template = template;
+      d->output_format = INSN_OUTPUT_FORMAT_SINGLE;
     }
-
-  printf ("}\n");
 }
 \f
 /* Check insn D for consistency in number of constraint alternatives.  */
@@ -849,7 +838,7 @@ gen_expand (insn)
   d->n_operands = max_opno + 1;
   d->n_dups = num_dups;
   d->template = 0;
-  d->outfun = 0;
+  d->output_format = INSN_OUTPUT_FORMAT_NONE;
 
   validate_insn_alternatives (d);
   place_operands (d);
@@ -889,7 +878,7 @@ gen_split (split)
   d->n_dups = 0;
   d->n_alternatives = 0;
   d->template = 0;
-  d->outfun = 0;
+  d->output_format = INSN_OUTPUT_FORMAT_NONE;
 
   place_operands (d);
 }
index 97794d1f78139c56ba8ab51f325a22a91127a853..db94ddfd120263660733b6c6a9d8a728b4553e68 100644 (file)
@@ -123,6 +123,9 @@ extern int only_leaf_regs_used      PROTO((void));
    available in leaf functions.  */
 extern void leaf_renumber_regs_insn PROTO((rtx));
 
+/* Locate the proper template for the given insn-code.  */
+extern const char *get_insn_template PROTO((int, rtx));
+
 /* Functions in flow.c */
 extern void allocate_for_life_analysis PROTO((void));
 extern int regno_uninitialized         PROTO((int));
index 0d4cc977cf57e0ab6dc681f01ab327caece9650f..e5875d59293b45e293cbfa53c833abaaf53e0ad7 100644 (file)
@@ -211,17 +211,24 @@ struct insn_operand_data
   char strict_low;
 };
 
+/* Legal values for insn_data.output_format.  Indicate what type of data
+   is stored in insn_data.output.  */
+#define INSN_OUTPUT_FORMAT_NONE                0       /* abort */
+#define INSN_OUTPUT_FORMAT_SINGLE      1       /* const char * */
+#define INSN_OUTPUT_FORMAT_MULTI       2       /* const char * const * */
+#define INSN_OUTPUT_FORMAT_FUNCTION    3       /* const char * (*)(...) */
+
 struct insn_data
 {
   const char *name;
-  const char *template;
-  insn_output_fn outfun;
+  const PTR output;
   insn_gen_fn genfun;
   const struct insn_operand_data *operand;
 
   unsigned char n_operands;
   unsigned char n_dups;
   unsigned char n_alternatives;
+  unsigned char output_format;
 };
 
 extern const struct insn_data insn_data[];
index b1b3b8fa318cfa87d81b9ffb7d621e9c7569d394..0be8824e753008d01fb15421bad47a16c6c8e307 100644 (file)
@@ -3172,7 +3172,7 @@ compile_file (name)
       /* It's best if we can write a nop here since some
         assemblers don't tolerate zeros in the text section.  */
       if (insn_data[CODE_FOR_nop].template != 0)
-       output_asm_insn (insn_data[CODE_FOR_nop].template, NULL_PTR);
+       output_asm_insn (get_insn_template (CODE_FOR_nop, NULL), NULL_PTR);
       else
        assemble_zeros (UNITS_PER_WORD);
     }