/* RTL reader for GNU C Compiler.
- Copyright (C) 1987, 1988, 1991, 1994, 1997, 1998, 1999, 2000, 2001
+ Copyright (C) 1987, 1988, 1991, 1994, 1997, 1998, 1999, 2000, 2001, 2002
Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+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 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 unsigned def_hash PARAMS ((const void *));
+static void read_escape PARAMS ((struct obstack *, FILE *));
+static hashval_t 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 validate_const_int PARAMS ((FILE *, const char *));
/* Subroutines of read_rtx. */
static void
fatal_with_file_and_line VPARAMS ((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_START (ap, msg);
-
-#ifndef ANSI_PROTOTYPES
- infile = va_arg (ap, FILE *);
- msg = va_arg (ap, const char *);
-#endif
+ VA_OPEN (ap, msg);
+ VA_FIXEDARG (ap, FILE *, infile);
+ VA_FIXEDARG (ap, const char *, 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)
fprintf (stderr, "%s:%d: following context is `%s'\n",
read_rtx_filename, read_rtx_lineno, context);
- va_end (ap);
+ VA_CLOSE (ap);
exit (1);
}
read_skip_spaces (infile)
FILE *infile;
{
- register int c;
+ int c;
+
while (1)
{
c = getc (infile);
case '/':
{
- register int prevc;
+ int prevc;
c = getc (infile);
if (c != '*')
fatal_expected_char (infile, '*', c);
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)
{
- if (c == ' ' || c == '\n' || c == '\t' || c == '\f')
+ if (c == ' ' || c == '\n' || c == '\t' || c == '\f' || c == '\r')
break;
if (c == ':' || c == ')' || c == ']' || c == '"' || c == '/'
|| c == '(' || c == '[')
}
}
+/* 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;
+{
+ int c = getc (infile);
+
+ switch (c)
+ {
+ /* Backslash-newline is replaced by nothing, as in C. */
+ case '\n':
+ read_rtx_lineno++;
+ return;
+
+ /* \" \' \\ are replaced by the second character. */
+ case '\\':
+ case '"':
+ case '\'':
+ break;
+
+ /* Standard C string escapes:
+ \a \b \f \n \r \t \v
+ \[0-7] \x
+ all are passed through to the output string unmolested.
+ In normal use these wind up in a string constant processed
+ by the C compiler, which will translate them appropriately.
+ We do not bother checking that \[0-7] are followed by up to
+ two octal digits, or that \x is followed by N hex digits.
+ \? \u \U are left out because they are not in traditional C. */
+ case 'a': case 'b': case 'f': case 'n': case 'r': case 't': case 'v':
+ case '0': case '1': case '2': case '3': case '4': case '5': case '6':
+ case '7': case 'x':
+ obstack_1grow (ob, '\\');
+ break;
+
+ /* \; makes stuff for a C string constant containing
+ newline and tab. */
+ case ';':
+ obstack_grow (ob, "\\n\\t", 4);
+ return;
+
+ /* pass anything else through, but issue a warning. */
+ default:
+ fprintf (stderr, "%s:%d: warning: unrecognized escape \\%c\n",
+ read_rtx_filename, read_rtx_lineno, c);
+ obstack_1grow (ob, '\\');
+ break;
+ }
+
+ obstack_1grow (ob, c);
+}
+
+
/* Read a double-quoted string onto the obstack. Caller has scanned
the leading quote. */
static char *
FILE *infile;
{
int c;
+
while (1)
{
c = getc (infile); /* Read the string */
read_rtx_lineno++;
else if (c == '\\')
{
- c = getc (infile); /* Read the string */
- /* \; makes stuff for a C string constant containing
- newline and tab. */
- if (c == ';')
- {
- obstack_grow (ob, "\\n\\t", 4);
- continue;
- }
- else if (c == '\n')
- /* \-newline: delete the backslash and update our idea of
- the line number. */
- read_rtx_lineno++;
- else if (c == '\\' || c == '"')
- ; /* \", \\ are a literal quote and backslash. */
- else
- /* Backslash escapes we do not recognize are left unmolested.
- They may be handled by the C compiler (e.g. \n, \t) */
- {
- ungetc (c, infile); /* put it back */
- c = '\\';
- }
+ read_escape (ob, infile);
+ continue;
}
else if (c == '"')
break;
brace_depth--;
else if (c == '\\')
{
- c = getc (infile); /* Read the string */
- /* \; makes stuff for a C string constant containing
- newline and tab. */
- if (c == ';')
- {
- obstack_grow (ob, "\\n\\t", 4);
- continue;
- }
- else if (c == '\n')
- /* \-newline: delete the backslash and update our idea of
- the line number. */
- read_rtx_lineno++;
- else if (c == '\\')
- ; /* \\ is a literal backslash */
- else
- /* Backslash escapes we do not recognize are left unmolested.
- They may be handled by the C compiler (e.g. \n, \t) */
- {
- ungetc (c, infile); /* put it back */
- c = '\\';
- }
+ read_escape (ob, infile);
+ continue;
}
obstack_1grow (ob, c);
}
-
+
obstack_1grow (ob, 0);
return obstack_finish (ob);
}
}
else
fatal_with_file_and_line (infile, "expected `\"' or `{', found `%c'", c);
-
+
if (saw_paren)
{
c = read_skip_spaces (infile);
/* 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 PARAMS ((const char *));
+
HOST_WIDE_INT
-atoll(p)
+atoll (p)
const char *p;
{
int neg = 0;
HOST_WIDE_INT tmp_wide;
- while (ISSPACE(*p))
+ while (ISSPACE (*p))
p++;
if (*p == '-')
neg = 1, 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;
#endif
/* Given a constant definition, return a hash code for its name. */
-static unsigned
+static hashval_t
def_hash (def)
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));
def_name_eq_p (def1, def2)
const void *def1, *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
htab_traverse (md_constants, callback, info);
}
+static void
+validate_const_int (infile, string)
+ 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
read_rtx (infile)
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;
{
XVEC (return_rtx, i) = 0;
break;
- }
+ }
/* Now process the vector. */
case 'E':
break;
}
+ case 'T':
case 's':
{
char *stringbuf;
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 =
- ((i == 3 && (GET_CODE (return_rtx) == DEFINE_INSN
- || GET_CODE (return_rtx) == DEFINE_INSN_AND_SPLIT))
- || (i == 2 && GET_CODE (return_rtx) == DEFINE_PEEPHOLE));
-
+ int 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
stringbuf = (char *) obstack_finish (&rtl_obstack);
}
- XSTR (return_rtx, i) = stringbuf;
+ if (star_if_braced)
+ XTMPL (return_rtx, i) = stringbuf;
+ else
+ XSTR (return_rtx, i) = stringbuf;
}
break;
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
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;