]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/genextract.c
Update copyright years.
[thirdparty/gcc.git] / gcc / genextract.c
index 2995ef8efe96520361bb7c5a285ef534b44427e6..63911e72d338df7b1b39f8d590eb3516d0885d3b 100644 (file)
@@ -1,5 +1,5 @@
 /* Generate code from machine description to extract operands from insn as rtl.
-   Copyright (C) 1987-2014 Free Software Foundation, Inc.
+   Copyright (C) 1987-2020 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -26,7 +26,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "errors.h"
 #include "read-md.h"
 #include "gensupport.h"
-#include "vec.h"
 
 /* This structure contains all the information needed to describe one
    set of extractions methods.  Each method may be used by more than
@@ -34,9 +33,10 @@ along with GCC; see the file COPYING3.  If not see
 
    The string for each operand describes that path to the operand and
    contains `0' through `9' when going into an expression and `a' through
-   `z' when going into a vector.  We assume here that only the first operand
-   of an rtl expression is a vector.  genrecog.c makes the same assumption
-   (and uses the same representation) and it is currently true.  */
+   `z' then 'A' through to 'Z' when going into a vector.  We assume here that
+   only the first operand of an rtl expression is a vector.  genrecog.c makes
+   the same assumption (and uses the same representation) and it is currently
+   true.  */
 
 typedef char *locstr;
 
@@ -68,48 +68,62 @@ static struct code_ptr *peepholes;
    data that will be used to produce an extractions structure.  */
 
 
-struct accum_extract
+class accum_extract
 {
-  vec<locstr> oplocs;
-  vec<locstr> duplocs;
-  vec<int> dupnums;
-  vec<char> pathstr;
-};
+public:
+  accum_extract () : oplocs (10), duplocs (10), dupnums (10), pathstr (20) {}
 
-int line_no;
+  auto_vec<locstr> oplocs;
+  auto_vec<locstr> duplocs;
+  auto_vec<int> dupnums;
+  auto_vec<char> pathstr;
+};
 
 /* Forward declarations.  */
-static void walk_rtx (rtx, struct accum_extract *);
+static void walk_rtx (md_rtx_info *, rtx, class accum_extract *);
+
+#define UPPER_OFFSET ('A' - ('z' - 'a' + 1))
 
+/* Convert integer OPERAND into a character - either into [a-zA-Z] for vector
+   operands or [0-9] for integer operands - and push onto the end of the path
+   in ACC.  */
 static void
-gen_insn (rtx insn, int insn_code_number)
+push_pathstr_operand (int operand, bool is_vector,
+                    class accum_extract *acc)
+{
+  if (is_vector && 'a' + operand > 'z')
+    acc->pathstr.safe_push (operand + UPPER_OFFSET);
+  else if (is_vector)
+    acc->pathstr.safe_push (operand + 'a');
+  else
+    acc->pathstr.safe_push (operand + '0');
+}
+
+static void
+gen_insn (md_rtx_info *info)
 {
   int i;
   unsigned int op_count, dup_count, j;
   struct extraction *p;
   struct code_ptr *link;
-  struct accum_extract acc;
-
-  acc.oplocs.create (10);
-  acc.duplocs.create (10);
-  acc.dupnums.create (10);
-  acc.pathstr.create (20);
+  class accum_extract acc;
 
   /* Walk the insn's pattern, remembering at all times the path
      down to the walking point.  */
 
+  rtx insn = info->def;
   if (XVECLEN (insn, 1) == 1)
-    walk_rtx (XVECEXP (insn, 1, 0), &acc);
+    walk_rtx (info, XVECEXP (insn, 1, 0), &acc);
   else
     for (i = XVECLEN (insn, 1) - 1; i >= 0; i--)
       {
-       acc.pathstr.safe_push ('a' + i);
-       walk_rtx (XVECEXP (insn, 1, i), &acc);
+       push_pathstr_operand (i, true, &acc);
+       walk_rtx (info, XVECEXP (insn, 1, i), &acc);
        acc.pathstr.pop ();
       }
 
   link = XNEW (struct code_ptr);
-  link->insn_code = insn_code_number;
+  link->insn_code = info->index;
 
   /* See if we find something that already had this extraction method.  */
 
@@ -144,7 +158,7 @@ gen_insn (rtx insn, int insn_code_number)
       /* This extraction is the same as ours.  Just link us in.  */
       link->next = p->insns;
       p->insns = link;
-      goto done;
+      return;
     }
 
   /* Otherwise, make a new extraction method.  We stash the arrays
@@ -168,26 +182,22 @@ gen_insn (rtx insn, int insn_code_number)
   memcpy (p->oplocs, acc.oplocs.address (), op_count * sizeof (locstr));
   memcpy (p->duplocs, acc.duplocs.address (), dup_count * sizeof (locstr));
   memcpy (p->dupnums, acc.dupnums.address (), dup_count * sizeof (int));
-
- done:
-  acc.oplocs.release ();
-  acc.duplocs.release ();
-  acc.dupnums.release ();
-  acc.pathstr.release ();
 }
 \f
 /* Helper subroutine of walk_rtx: given a vec<locstr>, an index, and a
    string, insert the string at the index, which should either already
    exist and be NULL, or not yet exist within the vector.  In the latter
-   case the vector is enlarged as appropriate.  */
+   case the vector is enlarged as appropriate.  INFO describes the
+   containing define_* expression.  */
 static void
-VEC_safe_set_locstr (vec<locstr> *vp, unsigned int ix, char *str)
+VEC_safe_set_locstr (md_rtx_info *info, vec<locstr> *vp,
+                    unsigned int ix, char *str)
 {
   if (ix < (*vp).length ())
     {
       if ((*vp)[ix])
        {
-         message_with_line (line_no, "repeated operand number %d", ix);
+         message_at (info->loc, "repeated operand number %d", ix);
          have_error = 1;
        }
       else
@@ -214,10 +224,10 @@ VEC_char_to_string (vec<char> v)
 }
 
 static void
-walk_rtx (rtx x, struct accum_extract *acc)
+walk_rtx (md_rtx_info *info, rtx x, class accum_extract *acc)
 {
   RTX_CODE code;
-  int i, len, base;
+  int i, len;
   const char *fmt;
 
   if (x == 0)
@@ -234,20 +244,19 @@ walk_rtx (rtx x, struct accum_extract *acc)
 
     case MATCH_OPERAND:
     case MATCH_SCRATCH:
-      VEC_safe_set_locstr (&acc->oplocs, XINT (x, 0),
+      VEC_safe_set_locstr (info, &acc->oplocs, XINT (x, 0),
                           VEC_char_to_string (acc->pathstr));
       break;
 
     case MATCH_OPERATOR:
     case MATCH_PARALLEL:
-      VEC_safe_set_locstr (&acc->oplocs, XINT (x, 0),
+      VEC_safe_set_locstr (info, &acc->oplocs, XINT (x, 0),
                           VEC_char_to_string (acc->pathstr));
 
-      base = (code == MATCH_OPERATOR ? '0' : 'a');
       for (i = XVECLEN (x, 2) - 1; i >= 0; i--)
        {
-         acc->pathstr.safe_push (base + i);
-         walk_rtx (XVECEXP (x, 2, i), acc);
+         push_pathstr_operand (i, code != MATCH_OPERATOR, acc);
+         walk_rtx (info, XVECEXP (x, 2, i), acc);
          acc->pathstr.pop ();
         }
       return;
@@ -261,11 +270,10 @@ walk_rtx (rtx x, struct accum_extract *acc)
       if (code == MATCH_DUP)
        break;
 
-      base = (code == MATCH_OP_DUP ? '0' : 'a');
       for (i = XVECLEN (x, 1) - 1; i >= 0; i--)
         {
-         acc->pathstr.safe_push (base + i);
-         walk_rtx (XVECEXP (x, 1, i), acc);
+         push_pathstr_operand (i, code != MATCH_OP_DUP, acc);
+         walk_rtx (info, XVECEXP (x, 1, i), acc);
          acc->pathstr.pop ();
         }
       return;
@@ -280,8 +288,8 @@ walk_rtx (rtx x, struct accum_extract *acc)
     {
       if (fmt[i] == 'e' || fmt[i] == 'u')
        {
-         acc->pathstr.safe_push ('0' + i);
-         walk_rtx (XEXP (x, i), acc);
+         push_pathstr_operand (i, false, acc);
+         walk_rtx (info, XEXP (x, i), acc);
          acc->pathstr.pop ();
        }
       else if (fmt[i] == 'E')
@@ -289,8 +297,8 @@ walk_rtx (rtx x, struct accum_extract *acc)
          int j;
          for (j = XVECLEN (x, i) - 1; j >= 0; j--)
            {
-             acc->pathstr.safe_push ('a' + j);
-             walk_rtx (XVECEXP (x, i, j), acc);
+             push_pathstr_operand (j, true, acc);
+             walk_rtx (info, XVECEXP (x, i, j), acc);
              acc->pathstr.pop ();
            }
        }
@@ -320,7 +328,7 @@ print_path (const char *path)
 
   for (i = len - 1; i >= 0 ; i--)
     {
-      if (ISLOWER (path[i]))
+      if (ISLOWER (path[i]) || ISUPPER (path[i]))
        fputs ("XVECEXP (", stdout);
       else if (ISDIGIT (path[i]))
        fputs ("XEXP (", stdout);
@@ -332,7 +340,9 @@ print_path (const char *path)
 
   for (i = 0; i < len; i++)
     {
-      if (ISLOWER (path[i]))
+      if (ISUPPER (path[i]))
+       printf (", 0, %d)", path[i] - UPPER_OFFSET);
+      else if (ISLOWER (path[i]))
        printf (", 0, %d)", path[i] - 'a');
       else if (ISDIGIT (path[i]))
        printf (", %d)", path[i] - '0');
@@ -352,6 +362,7 @@ print_header (void)
 /* Generated automatically by the program `genextract'\n\
    from the machine description file `md'.  */\n\
 \n\
+#define IN_TARGET_CODE 1\n\
 #include \"config.h\"\n\
 #include \"system.h\"\n\
 #include \"coretypes.h\"\n\
@@ -373,10 +384,11 @@ insn_extract (rtx_insn *insn)\n{\n\
   rtx pat = PATTERN (insn);\n\
   int i ATTRIBUTE_UNUSED; /* only for peepholes */\n\
 \n\
-#ifdef ENABLE_CHECKING\n\
-  memset (ro, 0xab, sizeof (*ro) * MAX_RECOG_OPERANDS);\n\
-  memset (ro_loc, 0xab, sizeof (*ro_loc) * MAX_RECOG_OPERANDS);\n\
-#endif\n");
+  if (flag_checking)\n\
+    {\n\
+      memset (ro, 0xab, sizeof (*ro) * MAX_RECOG_OPERANDS);\n\
+      memset (ro_loc, 0xab, sizeof (*ro_loc) * MAX_RECOG_OPERANDS);\n\
+    }\n");
 
   puts ("\
   switch (INSN_CODE (insn))\n\
@@ -393,14 +405,12 @@ insn_extract (rtx_insn *insn)\n{\n\
 }
 
 int
-main (int argc, char **argv)
+main (int argc, const char **argv)
 {
-  rtx desc;
   unsigned int i;
   struct extraction *p;
   struct code_ptr *link;
   const char *name;
-  int insn_code_number;
 
   progname = "genextract";
 
@@ -409,19 +419,26 @@ main (int argc, char **argv)
 
   /* Read the machine description.  */
 
-  while ((desc = read_md_rtx (&line_no, &insn_code_number)) != NULL)
-    {
-       if (GET_CODE (desc) == DEFINE_INSN)
-        gen_insn (desc, insn_code_number);
+  md_rtx_info info;
+  while (read_md_rtx (&info))
+    switch (GET_CODE (info.def))
+      {
+      case DEFINE_INSN:
+       gen_insn (&info);
+       break;
 
-      else if (GET_CODE (desc) == DEFINE_PEEPHOLE)
+      case DEFINE_PEEPHOLE:
        {
          struct code_ptr *link = XNEW (struct code_ptr);
 
-         link->insn_code = insn_code_number;
+         link->insn_code = info.index;
          link->next = peepholes;
          peepholes = link;
        }
+       break;
+
+      default:
+       break;
     }
 
   if (have_error)