OSDN Git Service

* c-typeck.c (common_type): Correct comment.
[pf3gnuchains/gcc-fork.git] / gcc / read-rtl.c
index 959a6f3..d17235f 100644 (file)
@@ -1,5 +1,6 @@
-/* RTL reader for GNU C Compiler.
-   Copyright (C) 1987, 1988, 1991, 1994, 1997, 1998, 1999, 2000, 2001
+/* RTL reader for GCC.
+   Copyright (C) 1987, 1988, 1991, 1994, 1997, 1998, 1999, 2000, 2001, 2002,
+   2003, 2004
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -19,28 +20,28 @@ along with GCC; see the file COPYING.  If not, write to the Free
 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 02111-1307, USA.  */
 
-#include "hconfig.h"
+#include "bconfig.h"
 #include "system.h"
+#include "coretypes.h"
+#include "tm.h"
 #include "rtl.h"
 #include "obstack.h"
 #include "hashtab.h"
 
-#define        obstack_chunk_alloc     xmalloc
-#define        obstack_chunk_free      free
-
 static htab_t md_constants;
 
-static void fatal_with_file_and_line PARAMS ((FILE *, const char *, ...))
+static void fatal_with_file_and_line (FILE *, const char *, ...)
   ATTRIBUTE_PRINTF_2 ATTRIBUTE_NORETURN;
-static void fatal_expected_char PARAMS ((FILE *, int, int)) ATTRIBUTE_NORETURN;
-static void read_name          PARAMS ((char *, FILE *));
-static char *read_string       PARAMS ((struct obstack *, FILE *, int));
-static char *read_quoted_string        PARAMS ((struct obstack *, FILE *));
-static char *read_braced_string        PARAMS ((struct obstack *, FILE *));
-static void read_escape                PARAMS ((struct obstack *, FILE *));
-static unsigned def_hash PARAMS ((const void *));
-static int def_name_eq_p PARAMS ((const void *, const void *));
-static void read_constants PARAMS ((FILE *infile, char *tmp_char));
+static void fatal_expected_char (FILE *, int, int) ATTRIBUTE_NORETURN;
+static void read_name (char *, FILE *);
+static char *read_string (struct obstack *, FILE *, int);
+static char *read_quoted_string (struct obstack *, FILE *);
+static char *read_braced_string (struct obstack *, FILE *);
+static void read_escape (struct obstack *, FILE *);
+static hashval_t def_hash (const void *);
+static int def_name_eq_p (const void *, const void *);
+static void read_constants (FILE *infile, char *tmp_char);
+static void validate_const_int (FILE *, const char *);
 
 /* Subroutines of read_rtx.  */
 
@@ -51,30 +52,21 @@ int read_rtx_lineno = 1;
 const char *read_rtx_filename = "<unknown>";
 
 static void
-fatal_with_file_and_line VPARAMS ((FILE *infile, const char *msg, ...))
+fatal_with_file_and_line (FILE *infile, const char *msg, ...)
 {
-#ifndef ANSI_PROTOTYPES
-  FILE *infile;
-  const char *msg;
-#endif
-  va_list ap;
   char context[64];
   size_t i;
   int c;
+  va_list ap;
 
-  VA_START (ap, msg);
-
-#ifndef ANSI_PROTOTYPES
-  infile = va_arg (ap, FILE *);
-  msg = va_arg (ap, const char *);
-#endif
+  va_start (ap, msg);
 
   fprintf (stderr, "%s:%d: ", read_rtx_filename, read_rtx_lineno);
   vfprintf (stderr, msg, ap);
   putc ('\n', stderr);
 
   /* Gather some following context.  */
-  for (i = 0; i < sizeof(context)-1; ++i)
+  for (i = 0; i < sizeof (context)-1; ++i)
     {
       c = getc (infile);
       if (c == EOF)
@@ -96,9 +88,7 @@ fatal_with_file_and_line VPARAMS ((FILE *infile, const char *msg, ...))
    invalid data.  */
 
 static void
-fatal_expected_char (infile, expected_c, actual_c)
-     FILE *infile;
-     int expected_c, actual_c;
+fatal_expected_char (FILE *infile, int expected_c, int actual_c)
 {
   fatal_with_file_and_line (infile, "expected character `%c', found `%c'",
                            expected_c, actual_c);
@@ -110,10 +100,10 @@ fatal_expected_char (infile, expected_c, actual_c)
    Tools such as genflags use this function.  */
 
 int
-read_skip_spaces (infile)
-     FILE *infile;
+read_skip_spaces (FILE *infile)
 {
-  register int c;
+  int c;
+
   while (1)
     {
       c = getc (infile);
@@ -135,7 +125,7 @@ read_skip_spaces (infile)
 
        case '/':
          {
-           register int prevc;
+           int prevc;
            c = getc (infile);
            if (c != '*')
              fatal_expected_char (infile, '*', c);
@@ -162,14 +152,12 @@ read_skip_spaces (infile)
    It is terminated by any of the punctuation chars of rtx printed syntax.  */
 
 static void
-read_name (str, infile)
-     char *str;
-     FILE *infile;
+read_name (char *str, FILE *infile)
 {
-  register char *p;
-  register int c;
+  char *p;
+  int c;
 
-  c = read_skip_spaces(infile);
+  c = read_skip_spaces (infile);
 
   p = str;
   while (1)
@@ -215,11 +203,10 @@ read_name (str, infile)
 /* Subroutine of the string readers.  Handles backslash escapes.
    Caller has read the backslash, but not placed it into the obstack.  */
 static void
-read_escape (ob, infile)
-     struct obstack *ob;
-     FILE *infile;
+read_escape (struct obstack *ob, FILE *infile)
 {
   int c = getc (infile);
+
   switch (c)
     {
       /* Backslash-newline is replaced by nothing, as in C.  */
@@ -264,16 +251,15 @@ read_escape (ob, infile)
 
   obstack_1grow (ob, c);
 }
-      
+
 
 /* Read a double-quoted string onto the obstack.  Caller has scanned
    the leading quote.  */
 static char *
-read_quoted_string (ob, infile)
-     struct obstack *ob;
-     FILE *infile;
+read_quoted_string (struct obstack *ob, FILE *infile)
 {
   int c;
+
   while (1)
     {
       c = getc (infile); /* Read the string  */
@@ -298,17 +284,17 @@ read_quoted_string (ob, infile)
    scanned the leading brace.  Note that unlike quoted strings,
    the outermost braces _are_ included in the string constant.  */
 static char *
-read_braced_string (ob, infile)
-     struct obstack *ob;
-     FILE *infile;
+read_braced_string (struct obstack *ob, FILE *infile)
 {
   int c;
   int brace_depth = 1;  /* caller-processed */
+  unsigned long starting_read_rtx_lineno = read_rtx_lineno;
 
   obstack_1grow (ob, '{');
   while (brace_depth)
     {
       c = getc (infile); /* Read the string  */
+
       if (c == '\n')
        read_rtx_lineno++;
       else if (c == '{')
@@ -320,10 +306,14 @@ read_braced_string (ob, infile)
          read_escape (ob, infile);
          continue;
        }
+      else if (c == EOF)
+       fatal_with_file_and_line
+         (infile, "missing closing } for opening brace on line %lu",
+          starting_read_rtx_lineno);
 
       obstack_1grow (ob, c);
     }
-      
+
   obstack_1grow (ob, 0);
   return obstack_finish (ob);
 }
@@ -333,10 +323,7 @@ read_braced_string (ob, infile)
    and dispatch to the appropriate string constant reader.  */
 
 static char *
-read_string (ob, infile, star_if_braced)
-     struct obstack *ob;
-     FILE *infile;
-     int star_if_braced;
+read_string (struct obstack *ob, FILE *infile, int star_if_braced)
 {
   char *stringbuf;
   int saw_paren = 0;
@@ -359,7 +346,7 @@ read_string (ob, infile, star_if_braced)
     }
   else
     fatal_with_file_and_line (infile, "expected `\"' or `{', found `%c'", c);
-       
+
   if (saw_paren)
     {
       c = read_skip_spaces (infile);
@@ -373,14 +360,15 @@ read_string (ob, infile, star_if_braced)
 /* Provide a version of a function to read a long long if the system does
    not provide one.  */
 #if HOST_BITS_PER_WIDE_INT > HOST_BITS_PER_LONG && !defined(HAVE_ATOLL) && !defined(HAVE_ATOQ)
+HOST_WIDE_INT atoll (const char *);
+
 HOST_WIDE_INT
-atoll(p)
-    const char *p;
+atoll (const char *p)
 {
   int neg = 0;
   HOST_WIDE_INT tmp_wide;
 
-  while (ISSPACE(*p))
+  while (ISSPACE (*p))
     p++;
   if (*p == '-')
     neg = 1, p++;
@@ -388,13 +376,13 @@ atoll(p)
     p++;
 
   tmp_wide = 0;
-  while (ISDIGIT(*p))
+  while (ISDIGIT (*p))
     {
       HOST_WIDE_INT new_wide = tmp_wide*10 + (*p - '0');
       if (new_wide < tmp_wide)
        {
          /* Return INT_MAX equiv on overflow.  */
-         tmp_wide = (~(unsigned HOST_WIDE_INT)0) >> 1;
+         tmp_wide = (~(unsigned HOST_WIDE_INT) 0) >> 1;
          break;
        }
       tmp_wide = new_wide;
@@ -408,12 +396,11 @@ atoll(p)
 #endif
 
 /* Given a constant definition, return a hash code for its name.  */
-static unsigned
-def_hash (def)
-     const void *def;
+static hashval_t
+def_hash (const void *def)
 {
   unsigned result, i;
-  const char *string = ((const struct md_constant *)def)->name;
+  const char *string = ((const struct md_constant *) def)->name;
 
   for (result = i = 0;*string++ != '\0'; i++)
     result += ((unsigned char) *string << (i % CHAR_BIT));
@@ -422,20 +409,17 @@ def_hash (def)
 
 /* Given two constant definitions, return true if they have the same name.  */
 static int
-def_name_eq_p (def1, def2)
-     const void *def1, *def2;
+def_name_eq_p (const void *def1, const void *def2)
 {
-  return ! strcmp (((const struct md_constant *)def1)->name,
-                  ((const struct md_constant *)def2)->name);
+  return ! strcmp (((const struct md_constant *) def1)->name,
+                  ((const struct md_constant *) def2)->name);
 }
 
 /* INFILE is a FILE pointer to read text from.  TMP_CHAR is a buffer suitable
    to read a name or number into.  Process a define_constants directive,
    starting with the optional space after the "define_constants".  */
 static void
-read_constants (infile, tmp_char)
-     FILE *infile;
-     char *tmp_char;
+read_constants (FILE *infile, char *tmp_char)
 {
   int c;
   htab_t defs;
@@ -491,32 +475,49 @@ read_constants (infile, tmp_char)
    a pointer a pointer to the constant definition and INFO.
    Stops when CALLBACK returns zero.  */
 void
-traverse_md_constants (callback, info)
-     htab_trav callback;
-     void *info;
+traverse_md_constants (htab_trav callback, void *info)
 {
   if (md_constants)
     htab_traverse (md_constants, callback, info);
 }
 
+static void
+validate_const_int (FILE *infile, const char *string)
+{
+  const char *cp;
+  int valid = 1;
+
+  cp = string;
+  while (*cp && ISSPACE (*cp))
+    cp++;
+  if (*cp == '-' || *cp == '+')
+    cp++;
+  if (*cp == 0)
+    valid = 0;
+  for (; *cp; cp++)
+    if (! ISDIGIT (*cp))
+      valid = 0;
+  if (!valid)
+    fatal_with_file_and_line (infile, "invalid decimal constant \"%s\"\n", string);
+}
+
 /* Read an rtx in printed representation from INFILE
    and return an actual rtx in core constructed accordingly.
    read_rtx is not used in the compiler proper, but rather in
    the utilities gen*.c that construct C code from machine descriptions.  */
 
 rtx
-read_rtx (infile)
-     FILE *infile;
+read_rtx (FILE *infile)
 {
-  register int i, j;
+  int i, j;
   RTX_CODE tmp_code;
-  register const char *format_ptr;
+  const char *format_ptr;
   /* tmp_char is a buffer used for reading decimal integers
      and names of rtx types and machine modes.
      Therefore, 256 must be enough.  */
   char tmp_char[256];
   rtx return_rtx;
-  register int c;
+  int c;
   int tmp_int;
   HOST_WIDE_INT tmp_wide;
 
@@ -615,7 +616,7 @@ again:
          {
            XVEC (return_rtx, i) = 0;
            break;
-         }
+         }
        /* Now process the vector.  */
 
       case 'E':
@@ -629,13 +630,13 @@ again:
          if (c != '[')
            fatal_expected_char (infile, '[', c);
 
-         /* add expressions to a list, while keeping a count */
+         /* Add expressions to a list, while keeping a count.  */
          obstack_init (&vector_stack);
          while ((c = read_skip_spaces (infile)) && c != ']')
            {
              ungetc (c, infile);
              list_counter++;
-             obstack_ptr_grow (&vector_stack, (PTR) read_rtx (infile));
+             obstack_ptr_grow (&vector_stack, read_rtx (infile));
            }
          if (list_counter > 0)
            {
@@ -650,27 +651,29 @@ again:
        break;
 
       case 'S':
-       /* 'S' is an optional string: if a closeparen follows,
-          just store NULL for this element.  */
-       c = read_skip_spaces (infile);
-       ungetc (c, infile);
-       if (c == ')')
-         {
-           XSTR (return_rtx, i) = 0;
-           break;
-         }
-
       case 'T':
       case 's':
        {
          char *stringbuf;
+         int star_if_braced;
+
+         c = read_skip_spaces (infile);
+         ungetc (c, infile);
+         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[-1] == '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.  */
-         int star_if_braced = (format_ptr[-1] == 'T');
-           
+         star_if_braced = (format_ptr[-1] == 'T');
+
          stringbuf = read_string (&rtl_obstack, infile, star_if_braced);
 
          /* For insn patterns, we want to provide a default name
@@ -704,6 +707,7 @@ again:
 
       case 'w':
        read_name (tmp_char, infile);
+       validate_const_int (infile, tmp_char);
 #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
        tmp_wide = atoi (tmp_char);
 #else
@@ -725,6 +729,7 @@ again:
       case 'i':
       case 'n':
        read_name (tmp_char, infile);
+       validate_const_int (infile, tmp_char);
        tmp_int = atoi (tmp_char);
        XINT (return_rtx, i) = tmp_int;
        break;