read-rtl.c: split out read_rtx_operand from read_rtx_code
authorDavid Malcolm <dmalcolm@redhat.com>
Mon, 26 Sep 2016 16:39:15 +0000 (16:39 +0000)
committerDavid Malcolm <dmalcolm@gcc.gnu.org>
Mon, 26 Sep 2016 16:39:15 +0000 (16:39 +0000)
gcc/ChangeLog:
* read-rtl.c (read_rtx_code): Rename local "i" to "idx", and use
"c" instead when parsing characters.  Move operand parsing into...
(read_rtx_operand): ...this new function, renaming "i" to "idx",
and tightening the scope of various locals.

From-SVN: r240502

gcc/ChangeLog
gcc/read-rtl.c

index 289a9759a2a727b6a74e7e42581c954729529213..e88c6641d55065d2734ccebc786b84f543a8c3a7 100644 (file)
@@ -1,3 +1,10 @@
+2016-09-26  David Malcolm  <dmalcolm@redhat.com>
+
+       * read-rtl.c (read_rtx_code): Rename local "i" to "idx", and use
+       "c" instead when parsing characters.  Move operand parsing into...
+       (read_rtx_operand): ...this new function, renaming "i" to "idx",
+       and tightening the scope of various locals.
+
 2016-09-26  LH Mouse  <lh_mouse@126.com>
 
        * config/i386/cygming.h (ASM_OUTPUT_DWARF_OFFSET): Fix typo.
index eda938265c588a253e7baa1b93f5165bc2295c3e..925ea451c9d0591a1b01079ccda752f2a5286a71 100644 (file)
@@ -107,6 +107,7 @@ const char *current_iterator_name;
 
 static void validate_const_int (const char *);
 static rtx read_rtx_code (const char *);
+static void read_rtx_operand (rtx, int);
 static rtx read_nested_rtx (void);
 static rtx read_rtx_variadic (rtx);
 
@@ -1089,17 +1090,12 @@ read_rtx (const char *rtx_name, vec<rtx> *rtxen)
 static rtx
 read_rtx_code (const char *code_name)
 {
-  int i;
   RTX_CODE code;
-  struct mapping *iterator, *m;
+  struct mapping *iterator;
   const char *format_ptr;
   struct md_name name;
   rtx return_rtx;
   int c;
-  HOST_WIDE_INT tmp_wide;
-  char *str;
-  char *start, *end, *ptr;
-  char tmpstr[256];
 
   /* Linked list structure for making RTXs: */
   struct rtx_list
@@ -1128,199 +1124,17 @@ read_rtx_code (const char *code_name)
   /* If what follows is `: mode ', read it and
      store the mode in the rtx.  */
 
-  i = read_skip_spaces ();
-  if (i == ':')
+  c = read_skip_spaces ();
+  if (c == ':')
     {
       read_name (&name);
       record_potential_iterator_use (&modes, return_rtx, name.string);
     }
   else
-    unread_char (i);
-
-  for (i = 0; format_ptr[i] != 0; i++)
-    switch (format_ptr[i])
-      {
-       /* 0 means a field for internal use only.
-          Don't expect it to be present in the input.  */
-      case '0':
-       if (code == REG)
-         ORIGINAL_REGNO (return_rtx) = REGNO (return_rtx);
-       break;
-
-      case 'e':
-      case 'u':
-       XEXP (return_rtx, i) = read_nested_rtx ();
-       break;
-
-      case 'V':
-       /* 'V' is an optional vector: if a closeparen follows,
-          just store NULL for this element.  */
-       c = read_skip_spaces ();
-       unread_char (c);
-       if (c == ')')
-         {
-           XVEC (return_rtx, i) = 0;
-           break;
-         }
-       /* Now process the vector.  */
-       /* FALLTHRU */
-
-      case 'E':
-       {
-         /* Obstack to store scratch vector in.  */
-         struct obstack vector_stack;
-         int list_counter = 0;
-         rtvec return_vec = NULL_RTVEC;
-
-         require_char_ws ('[');
-
-         /* Add expressions to a list, while keeping a count.  */
-         obstack_init (&vector_stack);
-         while ((c = read_skip_spaces ()) && c != ']')
-           {
-             if (c == EOF)
-               fatal_expected_char (']', c);
-             unread_char (c);
-             list_counter++;
-             obstack_ptr_grow (&vector_stack, read_nested_rtx ());
-           }
-         if (list_counter > 0)
-           {
-             return_vec = rtvec_alloc (list_counter);
-             memcpy (&return_vec->elem[0], obstack_finish (&vector_stack),
-                     list_counter * sizeof (rtx));
-           }
-         else if (format_ptr[i] == 'E')
-           fatal_with_file_and_line ("vector must have at least one element");
-         XVEC (return_rtx, i) = return_vec;
-         obstack_free (&vector_stack, NULL);
-         /* close bracket gotten */
-       }
-       break;
-
-      case 'S':
-      case 'T':
-      case 's':
-       {
-         char *stringbuf;
-         int star_if_braced;
-
-         c = read_skip_spaces ();
-         unread_char (c);
-         if (c == ')')
-           {
-             /* 'S' fields are optional and should be NULL if no string
-                was given.  Also allow normal 's' and 'T' strings to be
-                omitted, treating them in the same way as empty strings.  */
-             XSTR (return_rtx, i) = (format_ptr[i] == 'S' ? NULL : "");
-             break;
-           }
-
-         /* The output template slot of a DEFINE_INSN,
-            DEFINE_INSN_AND_SPLIT, or DEFINE_PEEPHOLE automatically
-            gets a star inserted as its first character, if it is
-            written with a brace block instead of a string constant.  */
-         star_if_braced = (format_ptr[i] == 'T');
-
-         stringbuf = read_string (star_if_braced);
-
-         /* For insn patterns, we want to provide a default name
-            based on the file and line, like "*foo.md:12", if the
-            given name is blank.  These are only for define_insn and
-            define_insn_and_split, to aid debugging.  */
-         if (*stringbuf == '\0'
-             && i == 0
-             && (GET_CODE (return_rtx) == DEFINE_INSN
-                 || GET_CODE (return_rtx) == DEFINE_INSN_AND_SPLIT))
-           {
-             char line_name[20];
-             const char *read_md_filename = rtx_reader_ptr->get_filename ();
-             const char *fn = (read_md_filename ? read_md_filename : "rtx");
-             const char *slash;
-             for (slash = fn; *slash; slash ++)
-               if (*slash == '/' || *slash == '\\' || *slash == ':')
-                 fn = slash + 1;
-             obstack_1grow (&string_obstack, '*');
-             obstack_grow (&string_obstack, fn, strlen (fn));
-             sprintf (line_name, ":%d", rtx_reader_ptr->get_lineno ());
-             obstack_grow (&string_obstack, line_name, strlen (line_name)+1);
-             stringbuf = XOBFINISH (&string_obstack, char *);
-           }
-
-         /* Find attr-names in the string.  */
-         ptr = &tmpstr[0];
-         end = stringbuf;
-         while ((start = strchr (end, '<')) && (end  = strchr (start, '>')))
-           {
-             if ((end - start - 1 > 0)
-                 && (end - start - 1 < (int)sizeof (tmpstr)))
-               {
-                 strncpy (tmpstr, start+1, end-start-1);
-                 tmpstr[end-start-1] = 0;
-                 end++;
-               }
-             else
-               break;
-             m = (struct mapping *) htab_find (substs.attrs, &ptr);
-             if (m != 0)
-               {
-                 /* Here we should find linked subst-iter.  */
-                 str = find_subst_iter_by_attr (ptr);
-                 if (str)
-                   m = (struct mapping *) htab_find (substs.iterators, &str);
-                 else
-                   m = 0;
-               }
-             if (m != 0)
-               record_iterator_use (m, return_rtx);
-           }
-
-         if (star_if_braced)
-           XTMPL (return_rtx, i) = stringbuf;
-         else
-           XSTR (return_rtx, i) = stringbuf;
-       }
-       break;
+    unread_char (c);
 
-      case 'w':
-       read_name (&name);
-       validate_const_int (name.string);
-#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
-       tmp_wide = atoi (name.string);
-#else
-#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
-       tmp_wide = atol (name.string);
-#else
-       /* Prefer atoll over atoq, since the former is in the ISO C99 standard.
-          But prefer not to use our hand-rolled function above either.  */
-#if HAVE_DECL_ATOLL || !defined(HAVE_ATOQ)
-       tmp_wide = atoll (name.string);
-#else
-       tmp_wide = atoq (name.string);
-#endif
-#endif
-#endif
-       XWINT (return_rtx, i) = tmp_wide;
-       break;
-
-      case 'i':
-      case 'n':
-       /* Can be an iterator or an integer constant.  */
-       read_name (&name);
-       record_potential_iterator_use (&ints, &XINT (return_rtx, i),
-                                      name.string);
-       break;
-
-      case 'r':
-       read_name (&name);
-       validate_const_int (name.string);
-       set_regno_raw (return_rtx, atoi (name.string), 1);
-       REG_ATTRS (return_rtx) = NULL;
-       break;
-
-      default:
-       gcc_unreachable ();
-      }
+  for (int idx = 0; format_ptr[idx] != 0; idx++)
+    read_rtx_operand (return_rtx, idx);
 
   if (CONST_WIDE_INT_P (return_rtx))
     {
@@ -1382,6 +1196,210 @@ read_rtx_code (const char *code_name)
   return return_rtx;
 }
 
+/* Subroutine of read_rtx_code.  Parse operand IDX within RETURN_RTX,
+   based on the corresponding format character within GET_RTX_FORMAT
+   for the GET_CODE (RETURN_RTX).  */
+
+static void
+read_rtx_operand (rtx return_rtx, int idx)
+{
+  RTX_CODE code = GET_CODE (return_rtx);
+  const char *format_ptr = GET_RTX_FORMAT (code);
+  int c;
+  struct md_name name;
+
+  switch (format_ptr[idx])
+    {
+      /* 0 means a field for internal use only.
+        Don't expect it to be present in the input.  */
+    case '0':
+      if (code == REG)
+       ORIGINAL_REGNO (return_rtx) = REGNO (return_rtx);
+      break;
+
+    case 'e':
+    case 'u':
+      XEXP (return_rtx, idx) = read_nested_rtx ();
+      break;
+
+    case 'V':
+      /* 'V' is an optional vector: if a closeparen follows,
+        just store NULL for this element.  */
+      c = read_skip_spaces ();
+      unread_char (c);
+      if (c == ')')
+       {
+         XVEC (return_rtx, idx) = 0;
+         break;
+       }
+      /* Now process the vector.  */
+      /* FALLTHRU */
+
+    case 'E':
+      {
+       /* Obstack to store scratch vector in.  */
+       struct obstack vector_stack;
+       int list_counter = 0;
+       rtvec return_vec = NULL_RTVEC;
+
+       require_char_ws ('[');
+
+       /* Add expressions to a list, while keeping a count.  */
+       obstack_init (&vector_stack);
+       while ((c = read_skip_spaces ()) && c != ']')
+         {
+           if (c == EOF)
+             fatal_expected_char (']', c);
+           unread_char (c);
+           list_counter++;
+           obstack_ptr_grow (&vector_stack, read_nested_rtx ());
+         }
+       if (list_counter > 0)
+         {
+           return_vec = rtvec_alloc (list_counter);
+           memcpy (&return_vec->elem[0], obstack_finish (&vector_stack),
+                   list_counter * sizeof (rtx));
+         }
+       else if (format_ptr[idx] == 'E')
+         fatal_with_file_and_line ("vector must have at least one element");
+       XVEC (return_rtx, idx) = return_vec;
+       obstack_free (&vector_stack, NULL);
+       /* close bracket gotten */
+      }
+      break;
+
+    case 'S':
+    case 'T':
+    case 's':
+      {
+       char *stringbuf;
+       int star_if_braced;
+
+       c = read_skip_spaces ();
+       unread_char (c);
+       if (c == ')')
+         {
+           /* 'S' fields are optional and should be NULL if no string
+              was given.  Also allow normal 's' and 'T' strings to be
+              omitted, treating them in the same way as empty strings.  */
+           XSTR (return_rtx, idx) = (format_ptr[idx] == 'S' ? NULL : "");
+           break;
+         }
+
+       /* The output template slot of a DEFINE_INSN,
+          DEFINE_INSN_AND_SPLIT, or DEFINE_PEEPHOLE automatically
+          gets a star inserted as its first character, if it is
+          written with a brace block instead of a string constant.  */
+       star_if_braced = (format_ptr[idx] == 'T');
+
+       stringbuf = read_string (star_if_braced);
+
+       /* For insn patterns, we want to provide a default name
+          based on the file and line, like "*foo.md:12", if the
+          given name is blank.  These are only for define_insn and
+          define_insn_and_split, to aid debugging.  */
+       if (*stringbuf == '\0'
+           && idx == 0
+           && (GET_CODE (return_rtx) == DEFINE_INSN
+               || GET_CODE (return_rtx) == DEFINE_INSN_AND_SPLIT))
+         {
+           char line_name[20];
+           const char *read_md_filename = rtx_reader_ptr->get_filename ();
+           const char *fn = (read_md_filename ? read_md_filename : "rtx");
+           const char *slash;
+           for (slash = fn; *slash; slash ++)
+             if (*slash == '/' || *slash == '\\' || *slash == ':')
+               fn = slash + 1;
+           obstack_1grow (&string_obstack, '*');
+           obstack_grow (&string_obstack, fn, strlen (fn));
+           sprintf (line_name, ":%d", rtx_reader_ptr->get_lineno ());
+           obstack_grow (&string_obstack, line_name, strlen (line_name)+1);
+           stringbuf = XOBFINISH (&string_obstack, char *);
+         }
+
+       /* Find attr-names in the string.  */
+       char *str;
+       char *start, *end, *ptr;
+       char tmpstr[256];
+       ptr = &tmpstr[0];
+       end = stringbuf;
+       while ((start = strchr (end, '<')) && (end  = strchr (start, '>')))
+         {
+           if ((end - start - 1 > 0)
+               && (end - start - 1 < (int)sizeof (tmpstr)))
+             {
+               strncpy (tmpstr, start+1, end-start-1);
+               tmpstr[end-start-1] = 0;
+               end++;
+             }
+           else
+             break;
+           struct mapping *m
+             = (struct mapping *) htab_find (substs.attrs, &ptr);
+           if (m != 0)
+             {
+               /* Here we should find linked subst-iter.  */
+               str = find_subst_iter_by_attr (ptr);
+               if (str)
+                 m = (struct mapping *) htab_find (substs.iterators, &str);
+               else
+                 m = 0;
+             }
+           if (m != 0)
+             record_iterator_use (m, return_rtx);
+         }
+
+       if (star_if_braced)
+         XTMPL (return_rtx, idx) = stringbuf;
+       else
+         XSTR (return_rtx, idx) = stringbuf;
+      }
+      break;
+
+    case 'w':
+      {
+       HOST_WIDE_INT tmp_wide;
+       read_name (&name);
+       validate_const_int (name.string);
+#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
+       tmp_wide = atoi (name.string);
+#else
+#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
+       tmp_wide = atol (name.string);
+#else
+       /* Prefer atoll over atoq, since the former is in the ISO C99 standard.
+          But prefer not to use our hand-rolled function above either.  */
+#if HAVE_DECL_ATOLL || !defined(HAVE_ATOQ)
+       tmp_wide = atoll (name.string);
+#else
+       tmp_wide = atoq (name.string);
+#endif
+#endif
+#endif
+       XWINT (return_rtx, idx) = tmp_wide;
+      }
+      break;
+
+    case 'i':
+    case 'n':
+      /* Can be an iterator or an integer constant.  */
+      read_name (&name);
+      record_potential_iterator_use (&ints, &XINT (return_rtx, idx),
+                                    name.string);
+      break;
+
+    case 'r':
+      read_name (&name);
+      validate_const_int (name.string);
+      set_regno_raw (return_rtx, atoi (name.string), 1);
+      REG_ATTRS (return_rtx) = NULL;
+      break;
+
+    default:
+      gcc_unreachable ();
+    }
+}
+
 /* Read a nested rtx construct from the MD file and return it.  */
 
 static rtx