This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[1/13] .md-file enumerations: move a lot of lexing code


This first patch just moves a bunch of data structures, variables and
functions from read-rtl.c and gensupport.c to a new file called read-md.c.
The key point is that the stuff in read-md.c doesn't depend on rtl.h or tm.h.

One further move was needed to make this possible: read-md.c depends on
obstack definitions that are currently in defaults.h, which is included
via tm.h.  The patch moves them to coretypes.h instead.

The pieces are moved verbatim, so there should be no behavioural changes.
Further patches clean up various aspects (such as the naming).

The Makefile.in rule for genconditions.o was missing $(HASHTAB_H) and
gensupport.h, so I added them.  I also rearranged the includes in
genattrtab.c to match the Makefile.in rules (and for consistency
with other files).

Richard


gcc/
	* Makefile.in (READ_MD_H): New variable.
	(BUILD_RTL): Add build/read-md.o.
	(build/gensupport.o, build/read-rtl.o, build/genattr.o)
	(build/genattrtab.o, build/genconditions.o build/genemit.o)
	(build/genextract.o, build/genflags.o, build/genoutput.o)
	(build/genpreds.o, build/genrecog.o): Depend on $(READ_MD_H).
	(build/read-md.o): New rule.
	* defaults.h (obstack_chunk_alloc, obstack_chunk_free)
	(OBSTACK_CHUNK_SIZE, gcc_obstack_init): Move to...
	* coretypes.h: ...here.
	* pretty-print.c (obstack_chunk_alloc, obstack_chunk_free): Delete.
	* genattr.c: Include read-md.h.
	* genattrtab.c: Likewise.
	* genconditions.c: Likewise.
	* genemit.c: Likewise.
	* genextract.c: Likewise.
	* genflags.c: Likewise.
	* genoutput.c: Likewise.
	* genpreds.c: Likewise.
	* genrecog.c: Likewise.
	* rtl.h (read_skip_spaces, copy_rtx_ptr_loc, print_rtx_ptr_loc)
	(join_c_conditions, print_c_condition, read_rtx_filename)
	(read_rtx_lineno): Move to read-md.h.
	* read-rtl.c: Include read-md.h.
	(ptr_loc, string_obstack, ptr_locs, ptr_loc_obstack)
	(joined_conditions, joined_conditions_obstack, read_rtx_lineno)
	(read_rtx_filename, fatal_with_file_and_line, fatal_expected_char)
	(leading_ptr_hash, leading_ptr_eq_p, set_rtx_ptr_loc, get_rtx_ptr_loc)
	(copy_rtx_ptr_loc, print_rtx_ptr_loc, join_c_conditions)
	(print_c_condition, read_skip_spaces, read_escape, read_quoted_string)
	(read_braced_string, read_string): Move to read-md.c.
	(read_rtx): Move some initialization to init_md_reader and call
	init_md_reader here.
	* gensupport.h (message_with_line, n_comma_elts, scan_comma_elt):
	Move to read-md.h.
	* gensupport.c: Include read-md.h.
	(message_with_line, n_comma_elts, scan_comma_elt): Move to
	read-md.c.
	* read-md.h, read-md.c: New files.

Index: gcc/Makefile.in
===================================================================
--- gcc/Makefile.in	2010-05-15 16:50:31.000000000 +0100
+++ gcc/Makefile.in	2010-05-15 16:51:24.000000000 +0100
@@ -870,6 +870,7 @@ RTL_BASE_H = rtl.h rtl.def $(MACHMODE_H)
   $(INPUT_H) $(REAL_H) statistics.h vec.h $(FIXED_VALUE_H) alias.h
 FIXED_VALUE_H = fixed-value.h $(MACHMODE_H) double-int.h
 RTL_H = $(RTL_BASE_H) genrtl.h
+READ_MD_H = $(OBSTACK_H) read-md.h
 PARAMS_H = params.h params.def
 BUILTINS_DEF = builtins.def sync-builtins.def omp-builtins.def
 TREE_H = tree.h all-tree.def tree.def c-common.def $(lang_tree_files) \
@@ -1028,8 +1029,9 @@ LDEXP_LIB = @LDEXP_LIB@
 # even if we are cross-building GCC.
 BUILD_LIBS = $(BUILD_LIBIBERTY)
 
-BUILD_RTL = build/rtl.o build/read-rtl.o build/ggc-none.o build/vec.o \
-	    build/min-insn-modes.o build/gensupport.o build/print-rtl.o
+BUILD_RTL = build/read-md.o build/rtl.o build/read-rtl.o build/ggc-none.o \
+	    build/vec.o build/min-insn-modes.o build/gensupport.o \
+	    build/print-rtl.o
 BUILD_ERRORS = build/errors.o
 
 # Specify the directories to be searched for header files.
@@ -3675,15 +3677,18 @@ build/%.o :  # dependencies provided by
 build/errors.o : errors.c $(BCONFIG_H) $(SYSTEM_H) errors.h
 build/gensupport.o: gensupport.c $(BCONFIG_H) $(SYSTEM_H) coretypes.h	\
   $(GTM_H) $(RTL_BASE_H) $(OBSTACK_H) errors.h $(HASHTAB_H)		\
-  gensupport.h
+  $(READ_MD_H) gensupport.h
 build/ggc-none.o : ggc-none.c $(BCONFIG_H) $(SYSTEM_H) coretypes.h 	\
   $(GGC_H)
 build/min-insn-modes.o : min-insn-modes.c $(BCONFIG_H) $(SYSTEM_H)	\
   $(MACHMODE_H)
 build/print-rtl.o: print-rtl.c $(BCONFIG_H) $(SYSTEM_H) coretypes.h	\
   $(GTM_H) $(RTL_BASE_H)
+build/read-md.o: read-md.c $(BCONFIG_H) $(SYSTEM_H) coretypes.h		\
+  $(HASHTAB_H) $(READ_MD_H)
 build/read-rtl.o: read-rtl.c $(BCONFIG_H) $(SYSTEM_H) coretypes.h	\
-  $(GTM_H) $(RTL_BASE_H) $(OBSTACK_H) $(HASHTAB_H) gensupport.h
+  $(GTM_H) $(RTL_BASE_H) $(OBSTACK_H) $(HASHTAB_H) $(READ_MD_H)		\
+  gensupport.h
 build/rtl.o: rtl.c $(BCONFIG_H) coretypes.h $(GTM_H) $(SYSTEM_H)	\
   $(RTL_H) $(REAL_H) $(GGC_H) errors.h
 build/vec.o : vec.c $(BCONFIG_H) $(SYSTEM_H) coretypes.h vec.h \
@@ -3700,10 +3705,10 @@ build/gencondmd.o : \
 
 # ...these are the programs themselves.
 build/genattr.o : genattr.c $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H)	\
-  coretypes.h $(GTM_H) errors.h gensupport.h
+  coretypes.h $(GTM_H) errors.h $(READ_MD_H) gensupport.h
 build/genattrtab.o : genattrtab.c $(RTL_BASE_H) $(OBSTACK_H)		\
   $(BCONFIG_H) $(SYSTEM_H) coretypes.h $(GTM_H) errors.h $(GGC_H)	\
-  gensupport.h
+  $(READ_MD_H) gensupport.h
 build/genautomata.o : genautomata.c $(RTL_BASE_H) $(OBSTACK_H)		\
   $(BCONFIG_H) $(SYSTEM_H) coretypes.h $(GTM_H) errors.h vec.h		\
   $(HASHTAB_H) gensupport.h
@@ -3713,17 +3718,19 @@ build/genchecksum.o : genchecksum.c $(BC
 build/gencodes.o : gencodes.c $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H)	\
   coretypes.h $(GTM_H) errors.h gensupport.h
 build/genconditions.o : genconditions.c $(RTL_BASE_H) $(BCONFIG_H)	\
-  $(SYSTEM_H) coretypes.h $(GTM_H) errors.h
+  $(SYSTEM_H) coretypes.h $(GTM_H) errors.h $(HASHTAB_H) $(READ_MD_H)	\
+  gensupport.h
 build/genconfig.o : genconfig.c $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H)	\
   coretypes.h $(GTM_H) errors.h gensupport.h
 build/genconstants.o : genconstants.c $(RTL_BASE_H) $(BCONFIG_H)	\
   $(SYSTEM_H) coretypes.h $(GTM_H) errors.h
 build/genemit.o : genemit.c $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H)	\
-  coretypes.h $(GTM_H) errors.h gensupport.h
+  coretypes.h $(GTM_H) errors.h $(READ_MD_H) gensupport.h
 build/genextract.o : genextract.c $(RTL_BASE_H) $(BCONFIG_H)		\
-  $(SYSTEM_H) coretypes.h $(GTM_H) errors.h gensupport.h vecprim.h
+  $(SYSTEM_H) coretypes.h $(GTM_H) errors.h $(READ_MD_H) gensupport.h	\
+  vecprim.h
 build/genflags.o : genflags.c $(RTL_BASE_H) $(OBSTACK_H) $(BCONFIG_H)	\
-  $(SYSTEM_H) coretypes.h $(GTM_H) errors.h gensupport.h
+  $(SYSTEM_H) coretypes.h $(GTM_H) errors.h $(READ_MD_H) gensupport.h
 build/gengenrtl.o : gengenrtl.c $(BCONFIG_H) $(SYSTEM_H) rtl.def
 build/gengtype-lex.o : gengtype-lex.c gengtype.h $(BCONFIG_H) $(SYSTEM_H)
 build/gengtype-parse.o : gengtype-parse.c gengtype.h $(BCONFIG_H)	\
@@ -3737,13 +3744,13 @@ build/genmodes.o : genmodes.c $(BCONFIG_
 build/genopinit.o : genopinit.c $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H)	\
   coretypes.h $(GTM_H) errors.h gensupport.h
 build/genoutput.o : genoutput.c $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H)	\
-  coretypes.h $(GTM_H) errors.h gensupport.h
+  coretypes.h $(GTM_H) errors.h $(READ_MD_H) gensupport.h
 build/genpeep.o : genpeep.c $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H)	\
   coretypes.h $(GTM_H) errors.h gensupport.h $(TOPLEV_H)
 build/genpreds.o : genpreds.c $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H)	\
-  coretypes.h $(GTM_H) errors.h gensupport.h $(OBSTACK_H)
+  coretypes.h $(GTM_H) errors.h $(READ_MD_H) gensupport.h $(OBSTACK_H)
 build/genrecog.o : genrecog.c $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H)	\
-  coretypes.h $(GTM_H) errors.h gensupport.h
+  coretypes.h $(GTM_H) errors.h $(READ_MD_H) gensupport.h
 
 # Compile the programs that generate insn-* from the machine description.
 # They are compiled with $(COMPILER_FOR_BUILD), and associated libraries,
Index: gcc/defaults.h
===================================================================
--- gcc/defaults.h	2010-05-15 16:50:31.000000000 +0100
+++ gcc/defaults.h	2010-05-15 16:50:38.000000000 +0100
@@ -32,14 +32,6 @@ #define GCC_DEFAULTS_H
 #define GET_ENVIRONMENT(VALUE, NAME) do { (VALUE) = getenv (NAME); } while (0)
 #endif
 
-#define obstack_chunk_alloc	((void *(*) (long)) xmalloc)
-#define obstack_chunk_free	((void (*) (void *)) free)
-#define OBSTACK_CHUNK_SIZE	0
-#define gcc_obstack_init(OBSTACK)			\
-  _obstack_begin ((OBSTACK), OBSTACK_CHUNK_SIZE, 0,	\
-		  obstack_chunk_alloc,			\
-		  obstack_chunk_free)
-
 /* Store in OUTPUT a string (made with alloca) containing an
    assembler-name for a local static variable or function named NAME.
    LABELNO is an integer which is different for each call.  */
Index: gcc/coretypes.h
===================================================================
--- gcc/coretypes.h	2010-05-15 16:50:31.000000000 +0100
+++ gcc/coretypes.h	2010-05-15 16:50:38.000000000 +0100
@@ -110,6 +110,15 @@ typedef const struct edge_def *const_edg
 struct basic_block_def;
 typedef struct basic_block_def *basic_block;
 typedef const struct basic_block_def *const_basic_block;
+
+#define obstack_chunk_alloc	((void *(*) (long)) xmalloc)
+#define obstack_chunk_free	((void (*) (void *)) free)
+#define OBSTACK_CHUNK_SIZE	0
+#define gcc_obstack_init(OBSTACK)			\
+  _obstack_begin ((OBSTACK), OBSTACK_CHUNK_SIZE, 0,	\
+		  obstack_chunk_alloc,			\
+		  obstack_chunk_free)
+
 #else
 
 struct _dont_use_rtx_here_;
Index: gcc/pretty-print.c
===================================================================
--- gcc/pretty-print.c	2010-05-15 16:50:31.000000000 +0100
+++ gcc/pretty-print.c	2010-05-15 16:50:38.000000000 +0100
@@ -32,9 +32,6 @@ Software Foundation; either version 3, o
 #include <iconv.h>
 #endif
 
-#define obstack_chunk_alloc xmalloc
-#define obstack_chunk_free  free
-
 /* A pointer to the formatted diagnostic message.  */
 #define pp_formatted_text_data(PP) \
    ((const char *) obstack_base (pp_base (PP)->buffer->obstack))
Index: gcc/genattr.c
===================================================================
--- gcc/genattr.c	2010-05-15 16:50:31.000000000 +0100
+++ gcc/genattr.c	2010-05-15 16:50:38.000000000 +0100
@@ -26,6 +26,7 @@ Software Foundation; either version 3, o
 #include "tm.h"
 #include "rtl.h"
 #include "errors.h"
+#include "read-md.h"
 #include "gensupport.h"
 
 
Index: gcc/genattrtab.c
===================================================================
--- gcc/genattrtab.c	2010-05-15 16:50:31.000000000 +0100
+++ gcc/genattrtab.c	2010-05-15 16:50:38.000000000 +0100
@@ -109,9 +109,10 @@ #define strcmp_check(S1, S2) ((S1) != (S
 #include "coretypes.h"
 #include "tm.h"
 #include "rtl.h"
-#include "gensupport.h"
 #include "obstack.h"
 #include "errors.h"
+#include "read-md.h"
+#include "gensupport.h"
 
 /* Flags for make_internal_attr's `special' parameter.  */
 #define ATTR_NONE		0
Index: gcc/genconditions.c
===================================================================
--- gcc/genconditions.c	2010-05-15 16:50:31.000000000 +0100
+++ gcc/genconditions.c	2010-05-15 16:50:38.000000000 +0100
@@ -33,6 +33,7 @@
 #include "rtl.h"
 #include "errors.h"
 #include "hashtab.h"
+#include "read-md.h"
 #include "gensupport.h"
 
 /* so we can include except.h in the generated file.  */
Index: gcc/genemit.c
===================================================================
--- gcc/genemit.c	2010-05-15 16:50:31.000000000 +0100
+++ gcc/genemit.c	2010-05-15 16:50:38.000000000 +0100
@@ -25,6 +25,7 @@ Software Foundation; either version 3, o
 #include "tm.h"
 #include "rtl.h"
 #include "errors.h"
+#include "read-md.h"
 #include "gensupport.h"
 
 
Index: gcc/genextract.c
===================================================================
--- gcc/genextract.c	2010-05-15 16:50:31.000000000 +0100
+++ gcc/genextract.c	2010-05-15 16:50:38.000000000 +0100
@@ -26,6 +26,7 @@ Software Foundation; either version 3, o
 #include "tm.h"
 #include "rtl.h"
 #include "errors.h"
+#include "read-md.h"
 #include "gensupport.h"
 #include "vec.h"
 #include "vecprim.h"
Index: gcc/genflags.c
===================================================================
--- gcc/genflags.c	2010-05-15 16:50:31.000000000 +0100
+++ gcc/genflags.c	2010-05-15 16:50:38.000000000 +0100
@@ -28,6 +28,7 @@ Software Foundation; either version 3, o
 #include "rtl.h"
 #include "obstack.h"
 #include "errors.h"
+#include "read-md.h"
 #include "gensupport.h"
 
 /* Obstack to remember insns with.  */
Index: gcc/genoutput.c
===================================================================
--- gcc/genoutput.c	2010-05-15 16:50:31.000000000 +0100
+++ gcc/genoutput.c	2010-05-15 16:50:38.000000000 +0100
@@ -88,6 +88,7 @@ Software Foundation; either version 3, o
 #include "tm.h"
 #include "rtl.h"
 #include "errors.h"
+#include "read-md.h"
 #include "gensupport.h"
 
 /* No instruction can have more operands than this.  Sorry for this
Index: gcc/genpreds.c
===================================================================
--- gcc/genpreds.c	2010-05-15 16:50:31.000000000 +0100
+++ gcc/genpreds.c	2010-05-15 16:50:38.000000000 +0100
@@ -28,6 +28,7 @@ the Free Software Foundation; either ver
 #include "rtl.h"
 #include "errors.h"
 #include "obstack.h"
+#include "read-md.h"
 #include "gensupport.h"
 
 /* Given a predicate expression EXP, from form NAME at line LINENO,
Index: gcc/genrecog.c
===================================================================
--- gcc/genrecog.c	2010-05-15 16:50:31.000000000 +0100
+++ gcc/genrecog.c	2010-05-15 16:50:38.000000000 +0100
@@ -56,6 +56,7 @@
 #include "tm.h"
 #include "rtl.h"
 #include "errors.h"
+#include "read-md.h"
 #include "gensupport.h"
 
 #define OUTPUT_LABEL(INDENT_STRING, LABEL_NUMBER) \
Index: gcc/rtl.h
===================================================================
--- gcc/rtl.h	2010-05-15 16:50:31.000000000 +0100
+++ gcc/rtl.h	2010-05-15 16:50:38.000000000 +0100
@@ -2389,14 +2389,7 @@ extern void traverse_md_constants (int (
 struct md_constant { char *name, *value; };
 
 /* In read-rtl.c */
-extern int read_skip_spaces (FILE *);
 extern bool read_rtx (FILE *, rtx *, int *);
-extern void copy_rtx_ptr_loc (const void *, const void *);
-extern void print_rtx_ptr_loc (const void *);
-extern const char *join_c_conditions (const char *, const char *);
-extern void print_c_condition (const char *);
-extern const char *read_rtx_filename;
-extern int read_rtx_lineno;
 
 /* In alias.c */
 extern rtx canon_rtx (rtx);
Index: gcc/read-rtl.c
===================================================================
--- gcc/read-rtl.c	2010-05-15 16:50:31.000000000 +0100
+++ gcc/read-rtl.c	2010-05-15 16:50:38.000000000 +0100
@@ -30,6 +30,7 @@ Software Foundation; either version 3, o
 #include "rtl.h"
 #include "obstack.h"
 #include "hashtab.h"
+#include "read-md.h"
 #include "gensupport.h"
 
 static htab_t md_constants;
@@ -79,14 +80,6 @@ struct iterator_group {
   void (*apply_iterator) (rtx, int);
 };
 
-/* Associates PTR (which can be a string, etc.) with the file location
-   specified by FILENAME and LINENO.  */
-struct ptr_loc {
-  const void *ptr;
-  const char *filename;
-  int lineno;
-};
-
 /* A structure used to pass data from read_rtx to apply_iterator_traverse
    via htab_traverse.  */
 struct iterator_traverse_data {
@@ -105,9 +98,6 @@ struct iterator_traverse_data {
 #define BELLWETHER_CODE(CODE) \
   ((CODE) < NUM_RTX_CODE ? CODE : bellwether_codes[CODE - NUM_RTX_CODE])
 
-static void fatal_with_file_and_line (FILE *, const char *, ...)
-  ATTRIBUTE_PRINTF_2 ATTRIBUTE_NORETURN;
-static void fatal_expected_char (FILE *, int, int) ATTRIBUTE_NORETURN;
 static int find_mode (const char *, FILE *);
 static bool uses_mode_iterator_p (rtx, int);
 static void apply_mode_iterator (rtx, int);
@@ -127,14 +117,6 @@ static struct map_value **add_map_value
 					 int, const char *);
 static void initialize_iterators (void);
 static void read_name (char *, FILE *);
-static hashval_t leading_ptr_hash (const void *);
-static int leading_ptr_eq_p (const void *, const void *);
-static void set_rtx_ptr_loc (const void *, const char *, int);
-static const struct ptr_loc *get_rtx_ptr_loc (const void *);
-static char *read_string (FILE *, int);
-static char *read_quoted_string (FILE *);
-static char *read_braced_string (FILE *);
-static void read_escape (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);
@@ -152,80 +134,6 @@ static rtx read_rtx_variadic (FILE *, st
 /* Index I is the value of BELLWETHER_CODE (I + NUM_RTX_CODE).  */
 static enum rtx_code *bellwether_codes;
 
-/* Obstack used for allocating RTL strings.  */
-static struct obstack string_obstack;
-
-/* A table of ptr_locs, hashed on the PTR field.  */
-static htab_t ptr_locs;
-
-/* An obstack for the above.  Plain xmalloc is a bit heavyweight for a
-   small structure like ptr_loc.  */
-static struct obstack ptr_loc_obstack;
-
-/* A hash table of triples (A, B, C), where each of A, B and C is a condition
-   and A is equivalent to "B && C".  This is used to keep track of the source
-   of conditions that are made up of separate rtx strings (such as the split
-   condition of a define_insn_and_split).  */
-static htab_t joined_conditions;
-
-/* An obstack for allocating joined_conditions entries.  */
-static struct obstack joined_conditions_obstack;
-
-/* Subroutines of read_rtx.  */
-
-/* The current line number for the file.  */
-int read_rtx_lineno = 1;
-
-/* The filename for error reporting.  */
-const char *read_rtx_filename = "<unknown>";
-
-static void
-fatal_with_file_and_line (FILE *infile, const char *msg, ...)
-{
-  char context[64];
-  size_t i;
-  int c;
-  va_list ap;
-
-  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)
-    {
-      c = getc (infile);
-      if (c == EOF)
-	break;
-      if (c == '\r' || c == '\n')
-	break;
-      context[i] = c;
-    }
-  context[i] = '\0';
-
-  fprintf (stderr, "%s:%d: following context is `%s'\n",
-	   read_rtx_filename, read_rtx_lineno, context);
-
-  va_end (ap);
-  exit (1);
-}
-
-/* Dump code after printing a message.  Used when read_rtx finds
-   invalid data.  */
-
-static void
-fatal_expected_char (FILE *infile, int expected_c, int actual_c)
-{
-  if (actual_c == EOF)
-    fatal_with_file_and_line (infile, "expected character `%c', found EOF",
-			      expected_c);
-  else
-    fatal_with_file_and_line (infile, "expected character `%c', found `%c'",
-			      expected_c, actual_c);
-}
-
 /* Implementations of the iterator_group callbacks for modes.  */
 
 static int
@@ -711,173 +619,6 @@ initialize_iterators (void)
     }
 }
 
-/* Return a hash value for the pointer pointed to by DEF.  */
-
-static hashval_t
-leading_ptr_hash (const void *def)
-{
-  return htab_hash_pointer (*(const void *const *) def);
-}
-
-/* Return true if DEF1 and DEF2 are pointers to the same pointer.  */
-
-static int
-leading_ptr_eq_p (const void *def1, const void *def2)
-{
-  return *(const void *const *) def1 == *(const void *const *) def2;
-}
-
-/* Associate PTR with the file position given by FILENAME and LINENO.  */
-
-static void
-set_rtx_ptr_loc (const void *ptr, const char *filename, int lineno)
-{
-  struct ptr_loc *loc;
-
-  loc = (struct ptr_loc *) obstack_alloc (&ptr_loc_obstack,
-					  sizeof (struct ptr_loc));
-  loc->ptr = ptr;
-  loc->filename = filename;
-  loc->lineno = lineno;
-  *htab_find_slot (ptr_locs, loc, INSERT) = loc;
-}
-
-/* Return the position associated with pointer PTR.  Return null if no
-   position was set.  */
-
-static const struct ptr_loc *
-get_rtx_ptr_loc (const void *ptr)
-{
-  return (const struct ptr_loc *) htab_find (ptr_locs, &ptr);
-}
-
-/* Associate NEW_PTR with the same file position as OLD_PTR.  */
-
-void
-copy_rtx_ptr_loc (const void *new_ptr, const void *old_ptr)
-{
-  const struct ptr_loc *loc = get_rtx_ptr_loc (old_ptr);
-  if (loc != 0)
-    set_rtx_ptr_loc (new_ptr, loc->filename, loc->lineno);
-}
-
-/* If PTR is associated with a known file position, print a #line
-   directive for it.  */
-
-void
-print_rtx_ptr_loc (const void *ptr)
-{
-  const struct ptr_loc *loc = get_rtx_ptr_loc (ptr);
-  if (loc != 0)
-    printf ("#line %d \"%s\"\n", loc->lineno, loc->filename);
-}
-
-/* Return a condition that satisfies both COND1 and COND2.  Either string
-   may be null or empty.  */
-
-const char *
-join_c_conditions (const char *cond1, const char *cond2)
-{
-  char *result;
-  const void **entry;
-
-  if (cond1 == 0 || cond1[0] == 0)
-    return cond2;
-
-  if (cond2 == 0 || cond2[0] == 0)
-    return cond1;
-
-  if (strcmp (cond1, cond2) == 0)
-    return cond1;
-
-  result = concat ("(", cond1, ") && (", cond2, ")", NULL);
-  obstack_ptr_grow (&joined_conditions_obstack, result);
-  obstack_ptr_grow (&joined_conditions_obstack, cond1);
-  obstack_ptr_grow (&joined_conditions_obstack, cond2);
-  entry = XOBFINISH (&joined_conditions_obstack, const void **);
-  *htab_find_slot (joined_conditions, entry, INSERT) = entry;
-  return result;
-}
-
-/* Print condition COND, wrapped in brackets.  If COND was created by
-   join_c_conditions, recursively invoke this function for the original
-   conditions and join the result with "&&".  Otherwise print a #line
-   directive for COND if its original file position is known.  */
-
-void
-print_c_condition (const char *cond)
-{
-  const char **halves = (const char **) htab_find (joined_conditions, &cond);
-  if (halves != 0)
-    {
-      printf ("(");
-      print_c_condition (halves[1]);
-      printf (" && ");
-      print_c_condition (halves[2]);
-      printf (")");
-    }
-  else
-    {
-      putc ('\n', stdout);
-      print_rtx_ptr_loc (cond);
-      printf ("(%s)", cond);
-    }
-}
-
-/* Read chars from INFILE until a non-whitespace char
-   and return that.  Comments, both Lisp style and C style,
-   are treated as whitespace.
-   Tools such as genflags use this function.  */
-
-int
-read_skip_spaces (FILE *infile)
-{
-  int c;
-
-  while (1)
-    {
-      c = getc (infile);
-      switch (c)
-	{
-	case '\n':
-	  read_rtx_lineno++;
-	  break;
-
-	case ' ': case '\t': case '\f': case '\r':
-	  break;
-
-	case ';':
-	  do
-	    c = getc (infile);
-	  while (c != '\n' && c != EOF);
-	  read_rtx_lineno++;
-	  break;
-
-	case '/':
-	  {
-	    int prevc;
-	    c = getc (infile);
-	    if (c != '*')
-	      fatal_expected_char (infile, '*', c);
-
-	    prevc = 0;
-	    while ((c = getc (infile)) && c != EOF)
-	      {
-		if (c == '\n')
-		   read_rtx_lineno++;
-	        else if (prevc == '*' && c == '/')
-		  break;
-	        prevc = c;
-	      }
-	  }
-	  break;
-
-	default:
-	  return c;
-	}
-    }
-}
-
 /* Read an rtx code name into the buffer STR[].
    It is terminated by any of the punctuation chars of rtx printed syntax.  */
 
@@ -929,165 +670,6 @@ read_name (char *str, FILE *infile)
 	strcpy (str, p);
     }
 }
-
-/* Subroutine of the string readers.  Handles backslash escapes.
-   Caller has read the backslash, but not placed it into the obstack.  */
-static void
-read_escape (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 (&string_obstack, '\\');
-      break;
-
-      /* \; makes stuff for a C string constant containing
-	 newline and tab.  */
-    case ';':
-      obstack_grow (&string_obstack, "\\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 (&string_obstack, '\\');
-      break;
-    }
-
-  obstack_1grow (&string_obstack, c);
-}
-
-
-/* Read a double-quoted string onto the obstack.  Caller has scanned
-   the leading quote.  */
-static char *
-read_quoted_string (FILE *infile)
-{
-  int c;
-
-  while (1)
-    {
-      c = getc (infile); /* Read the string  */
-      if (c == '\n')
-	read_rtx_lineno++;
-      else if (c == '\\')
-	{
-	  read_escape (infile);
-	  continue;
-	}
-      else if (c == '"' || c == EOF)
-	break;
-
-      obstack_1grow (&string_obstack, c);
-    }
-
-  obstack_1grow (&string_obstack, 0);
-  return XOBFINISH (&string_obstack, char *);
-}
-
-/* Read a braced string (a la Tcl) onto the string obstack.  Caller
-   has scanned the leading brace.  Note that unlike quoted strings,
-   the outermost braces _are_ included in the string constant.  */
-static char *
-read_braced_string (FILE *infile)
-{
-  int c;
-  int brace_depth = 1;  /* caller-processed */
-  unsigned long starting_read_rtx_lineno = read_rtx_lineno;
-
-  obstack_1grow (&string_obstack, '{');
-  while (brace_depth)
-    {
-      c = getc (infile); /* Read the string  */
-
-      if (c == '\n')
-	read_rtx_lineno++;
-      else if (c == '{')
-	brace_depth++;
-      else if (c == '}')
-	brace_depth--;
-      else if (c == '\\')
-	{
-	  read_escape (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 (&string_obstack, c);
-    }
-
-  obstack_1grow (&string_obstack, 0);
-  return XOBFINISH (&string_obstack, char *);
-}
-
-/* Read some kind of string constant.  This is the high-level routine
-   used by read_rtx.  It handles surrounding parentheses, leading star,
-   and dispatch to the appropriate string constant reader.  */
-
-static char *
-read_string (FILE *infile, int star_if_braced)
-{
-  char *stringbuf;
-  int saw_paren = 0;
-  int c, old_lineno;
-
-  c = read_skip_spaces (infile);
-  if (c == '(')
-    {
-      saw_paren = 1;
-      c = read_skip_spaces (infile);
-    }
-
-  old_lineno = read_rtx_lineno;
-  if (c == '"')
-    stringbuf = read_quoted_string (infile);
-  else if (c == '{')
-    {
-      if (star_if_braced)
-	obstack_1grow (&string_obstack, '*');
-      stringbuf = read_braced_string (infile);
-    }
-  else
-    fatal_with_file_and_line (infile, "expected `\"' or `{', found `%c'", c);
-
-  if (saw_paren)
-    {
-      c = read_skip_spaces (infile);
-      if (c != ')')
-	fatal_expected_char (infile, ')', c);
-    }
-
-  set_rtx_ptr_loc (stringbuf, read_rtx_filename, old_lineno);
-  return stringbuf;
-}
 
 /* Provide a version of a function to read a long long if the system does
    not provide one.  */
@@ -1401,14 +983,9 @@ read_rtx (FILE *infile, rtx *x, int *lin
   /* Do one-time initialization.  */
   if (queue_head == 0)
     {
+      init_md_reader ();
       initialize_iterators ();
-      obstack_init (&string_obstack);
       queue_head = rtx_alloc (EXPR_LIST);
-      ptr_locs = htab_create (161, leading_ptr_hash, leading_ptr_eq_p, 0);
-      obstack_init (&ptr_loc_obstack);
-      joined_conditions = htab_create (161, leading_ptr_hash,
-				       leading_ptr_eq_p, 0);
-      obstack_init (&joined_conditions_obstack);
     }
 
   if (queue_next == 0)
Index: gcc/gensupport.h
===================================================================
--- gcc/gensupport.h	2010-05-15 16:50:31.000000000 +0100
+++ gcc/gensupport.h	2010-05-15 16:50:38.000000000 +0100
@@ -29,9 +29,6 @@ extern int init_md_reader_args_cb (int,
 extern int init_md_reader_args (int, char **);
 extern rtx read_md_rtx (int *, int *);
 
-extern void message_with_line (int, const char *, ...)
-     ATTRIBUTE_PRINTF_2;
-
 /* Set this to 0 to disable automatic elision of insn patterns which
    can never be used in this configuration.  See genconditions.c.
    Must be set before calling init_md_reader.  */
@@ -60,9 +57,6 @@ extern int cmp_c_test (const void *, con
 extern void traverse_c_tests (htab_trav, void *);
 #endif
 
-extern int n_comma_elts	(const char *);
-extern const char *scan_comma_elt (const char **);
-
 /* Predicate handling: helper functions and data structures.  */
 
 struct pred_data
Index: gcc/gensupport.c
===================================================================
--- gcc/gensupport.c	2010-05-15 16:50:31.000000000 +0100
+++ gcc/gensupport.c	2010-05-15 16:50:38.000000000 +0100
@@ -26,6 +26,7 @@
 #include "obstack.h"
 #include "errors.h"
 #include "hashtab.h"
+#include "read-md.h"
 #include "gensupport.h"
 
 
@@ -119,20 +120,6 @@ static char *save_string (const char *,
 static void init_predicate_table (void);
 static void record_insn_name (int, const char *);
 
-void
-message_with_line (int lineno, const char *msg, ...)
-{
-  va_list ap;
-
-  va_start (ap, msg);
-
-  fprintf (stderr, "%s:%d: ", read_rtx_filename, lineno);
-  vfprintf (stderr, msg, ap);
-  fputc ('\n', stderr);
-
-  va_end (ap);
-}
-
 /* Make a version of gen_rtx_CONST_INT so that GEN_INT can be used in
    the gensupport programs.  */
 
@@ -1227,53 +1214,6 @@ traverse_c_tests (htab_trav callback, vo
     htab_traverse (condition_table, callback, info);
 }
 
-
-/* Given a string, return the number of comma-separated elements in it.
-   Return 0 for the null string.  */
-int
-n_comma_elts (const char *s)
-{
-  int n;
-
-  if (*s == '\0')
-    return 0;
-
-  for (n = 1; *s; s++)
-    if (*s == ',')
-      n++;
-
-  return n;
-}
-
-/* Given a pointer to a (char *), return a pointer to the beginning of the
-   next comma-separated element in the string.  Advance the pointer given
-   to the end of that element.  Return NULL if at end of string.  Caller
-   is responsible for copying the string if necessary.  White space between
-   a comma and an element is ignored.  */
-
-const char *
-scan_comma_elt (const char **pstr)
-{
-  const char *start;
-  const char *p = *pstr;
-
-  if (*p == ',')
-    p++;
-  while (ISSPACE(*p))
-    p++;
-
-  if (*p == '\0')
-    return NULL;
-
-  start = p;
-
-  while (*p != ',' && *p != '\0')
-    p++;
-
-  *pstr = p;
-  return start;
-}
-
 /* Helper functions for define_predicate and define_special_predicate
    processing.  Shared between genrecog.c and genpreds.c.  */
 
Index: gcc/read-md.h
===================================================================
--- /dev/null	2010-05-15 09:53:34.287207398 +0100
+++ gcc/read-md.h	2010-05-15 16:50:38.000000000 +0100
@@ -0,0 +1,41 @@
+/* MD reader definitions.
+   Copyright (C) 1987, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010
+   Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+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 3, or (at your option) any later
+version.
+
+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 GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#include "obstack.h"
+
+extern int read_rtx_lineno;
+extern const char *read_rtx_filename;
+extern struct obstack string_obstack;
+
+extern void copy_rtx_ptr_loc (const void *, const void *);
+extern void print_rtx_ptr_loc (const void *);
+extern const char *join_c_conditions (const char *, const char *);
+extern void print_c_condition (const char *);
+extern void message_with_line (int, const char *, ...) ATTRIBUTE_PRINTF_2;
+extern void fatal_with_file_and_line (FILE *, const char *, ...)
+  ATTRIBUTE_PRINTF_2 ATTRIBUTE_NORETURN;
+extern void fatal_expected_char (FILE *, int, int) ATTRIBUTE_NORETURN;
+extern int read_skip_spaces (FILE *);
+extern char *read_quoted_string (FILE *);
+extern char *read_string (FILE *, int);
+extern int n_comma_elts (const char *);
+extern const char *scan_comma_elt (const char **);
+extern void init_md_reader (void);
Index: gcc/read-md.c
===================================================================
--- /dev/null	2010-05-15 09:53:34.287207398 +0100
+++ gcc/read-md.c	2010-05-15 16:50:38.000000000 +0100
@@ -0,0 +1,512 @@
+/* MD reader for GCC.
+   Copyright (C) 1987, 1988, 1991, 1994, 1997, 1998, 1999, 2000, 2001, 2002,
+   2003, 2004, 2005, 2006, 2007, 2008, 2010
+   Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+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 3, or (at your option) any later
+version.
+
+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 GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#include "bconfig.h"
+#include "system.h"
+#include "coretypes.h"
+#include "hashtab.h"
+#include "read-md.h"
+
+/* Associates PTR (which can be a string, etc.) with the file location
+   specified by FILENAME and LINENO.  */
+struct ptr_loc {
+  const void *ptr;
+  const char *filename;
+  int lineno;
+};
+
+/* Obstack used for allocating RTL strings.  */
+struct obstack string_obstack;
+
+/* A table of ptr_locs, hashed on the PTR field.  */
+static htab_t ptr_locs;
+
+/* An obstack for the above.  Plain xmalloc is a bit heavyweight for a
+   small structure like ptr_loc.  */
+static struct obstack ptr_loc_obstack;
+
+/* A hash table of triples (A, B, C), where each of A, B and C is a condition
+   and A is equivalent to "B && C".  This is used to keep track of the source
+   of conditions that are made up of separate rtx strings (such as the split
+   condition of a define_insn_and_split).  */
+static htab_t joined_conditions;
+
+/* An obstack for allocating joined_conditions entries.  */
+static struct obstack joined_conditions_obstack;
+
+/* The current line number for the file.  */
+int read_rtx_lineno = 1;
+
+/* The filename for error reporting.  */
+const char *read_rtx_filename = "<unknown>";
+
+/* Return a hash value for the pointer pointed to by DEF.  */
+
+static hashval_t
+leading_ptr_hash (const void *def)
+{
+  return htab_hash_pointer (*(const void *const *) def);
+}
+
+/* Return true if DEF1 and DEF2 are pointers to the same pointer.  */
+
+static int
+leading_ptr_eq_p (const void *def1, const void *def2)
+{
+  return *(const void *const *) def1 == *(const void *const *) def2;
+}
+
+/* Associate PTR with the file position given by FILENAME and LINENO.  */
+
+static void
+set_rtx_ptr_loc (const void *ptr, const char *filename, int lineno)
+{
+  struct ptr_loc *loc;
+
+  loc = (struct ptr_loc *) obstack_alloc (&ptr_loc_obstack,
+					  sizeof (struct ptr_loc));
+  loc->ptr = ptr;
+  loc->filename = filename;
+  loc->lineno = lineno;
+  *htab_find_slot (ptr_locs, loc, INSERT) = loc;
+}
+
+/* Return the position associated with pointer PTR.  Return null if no
+   position was set.  */
+
+static const struct ptr_loc *
+get_rtx_ptr_loc (const void *ptr)
+{
+  return (const struct ptr_loc *) htab_find (ptr_locs, &ptr);
+}
+
+/* Associate NEW_PTR with the same file position as OLD_PTR.  */
+
+void
+copy_rtx_ptr_loc (const void *new_ptr, const void *old_ptr)
+{
+  const struct ptr_loc *loc = get_rtx_ptr_loc (old_ptr);
+  if (loc != 0)
+    set_rtx_ptr_loc (new_ptr, loc->filename, loc->lineno);
+}
+
+/* If PTR is associated with a known file position, print a #line
+   directive for it.  */
+
+void
+print_rtx_ptr_loc (const void *ptr)
+{
+  const struct ptr_loc *loc = get_rtx_ptr_loc (ptr);
+  if (loc != 0)
+    printf ("#line %d \"%s\"\n", loc->lineno, loc->filename);
+}
+
+/* Return a condition that satisfies both COND1 and COND2.  Either string
+   may be null or empty.  */
+
+const char *
+join_c_conditions (const char *cond1, const char *cond2)
+{
+  char *result;
+  const void **entry;
+
+  if (cond1 == 0 || cond1[0] == 0)
+    return cond2;
+
+  if (cond2 == 0 || cond2[0] == 0)
+    return cond1;
+
+  if (strcmp (cond1, cond2) == 0)
+    return cond1;
+
+  result = concat ("(", cond1, ") && (", cond2, ")", NULL);
+  obstack_ptr_grow (&joined_conditions_obstack, result);
+  obstack_ptr_grow (&joined_conditions_obstack, cond1);
+  obstack_ptr_grow (&joined_conditions_obstack, cond2);
+  entry = XOBFINISH (&joined_conditions_obstack, const void **);
+  *htab_find_slot (joined_conditions, entry, INSERT) = entry;
+  return result;
+}
+
+/* Print condition COND, wrapped in brackets.  If COND was created by
+   join_c_conditions, recursively invoke this function for the original
+   conditions and join the result with "&&".  Otherwise print a #line
+   directive for COND if its original file position is known.  */
+
+void
+print_c_condition (const char *cond)
+{
+  const char **halves = (const char **) htab_find (joined_conditions, &cond);
+  if (halves != 0)
+    {
+      printf ("(");
+      print_c_condition (halves[1]);
+      printf (" && ");
+      print_c_condition (halves[2]);
+      printf (")");
+    }
+  else
+    {
+      putc ('\n', stdout);
+      print_rtx_ptr_loc (cond);
+      printf ("(%s)", cond);
+    }
+}
+
+/* A printf-like function for reporting an error against line LINENO
+   in the current MD file.  */
+
+void
+message_with_line (int lineno, const char *msg, ...)
+{
+  va_list ap;
+
+  va_start (ap, msg);
+
+  fprintf (stderr, "%s:%d: ", read_rtx_filename, lineno);
+  vfprintf (stderr, msg, ap);
+  fputc ('\n', stderr);
+
+  va_end (ap);
+}
+
+/* A printf-like function for reporting an error against the current
+   position in the MD file, which is associated with INFILE.  */
+
+void
+fatal_with_file_and_line (FILE *infile, const char *msg, ...)
+{
+  char context[64];
+  size_t i;
+  int c;
+  va_list ap;
+
+  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)
+    {
+      c = getc (infile);
+      if (c == EOF)
+	break;
+      if (c == '\r' || c == '\n')
+	break;
+      context[i] = c;
+    }
+  context[i] = '\0';
+
+  fprintf (stderr, "%s:%d: following context is `%s'\n",
+	   read_rtx_filename, read_rtx_lineno, context);
+
+  va_end (ap);
+  exit (1);
+}
+
+/* Report that we found character ACTUAL when we expected to find
+   character EXPECTED.  INFILE is the file handle associated
+   with the current file.  */
+
+void
+fatal_expected_char (FILE *infile, int expected, int actual)
+{
+  if (actual == EOF)
+    fatal_with_file_and_line (infile, "expected character `%c', found EOF",
+			      expected);
+  else
+    fatal_with_file_and_line (infile, "expected character `%c', found `%c'",
+			      expected, actual);
+}
+
+/* Read chars from INFILE until a non-whitespace char and return that.
+   Comments, both Lisp style and C style, are treated as whitespace.  */
+
+int
+read_skip_spaces (FILE *infile)
+{
+  int c;
+
+  while (1)
+    {
+      c = getc (infile);
+      switch (c)
+	{
+	case '\n':
+	  read_rtx_lineno++;
+	  break;
+
+	case ' ': case '\t': case '\f': case '\r':
+	  break;
+
+	case ';':
+	  do
+	    c = getc (infile);
+	  while (c != '\n' && c != EOF);
+	  read_rtx_lineno++;
+	  break;
+
+	case '/':
+	  {
+	    int prevc;
+	    c = getc (infile);
+	    if (c != '*')
+	      fatal_expected_char (infile, '*', c);
+
+	    prevc = 0;
+	    while ((c = getc (infile)) && c != EOF)
+	      {
+		if (c == '\n')
+		   read_rtx_lineno++;
+	        else if (prevc == '*' && c == '/')
+		  break;
+	        prevc = c;
+	      }
+	  }
+	  break;
+
+	default:
+	  return 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 (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 (&string_obstack, '\\');
+      break;
+
+      /* \; makes stuff for a C string constant containing
+	 newline and tab.  */
+    case ';':
+      obstack_grow (&string_obstack, "\\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 (&string_obstack, '\\');
+      break;
+    }
+
+  obstack_1grow (&string_obstack, c);
+}
+
+/* Read a double-quoted string onto the obstack.  Caller has scanned
+   the leading quote.  */
+
+char *
+read_quoted_string (FILE *infile)
+{
+  int c;
+
+  while (1)
+    {
+      c = getc (infile); /* Read the string  */
+      if (c == '\n')
+	read_rtx_lineno++;
+      else if (c == '\\')
+	{
+	  read_escape (infile);
+	  continue;
+	}
+      else if (c == '"' || c == EOF)
+	break;
+
+      obstack_1grow (&string_obstack, c);
+    }
+
+  obstack_1grow (&string_obstack, 0);
+  return XOBFINISH (&string_obstack, char *);
+}
+
+/* Read a braced string (a la Tcl) onto the string obstack.  Caller
+   has scanned the leading brace.  Note that unlike quoted strings,
+   the outermost braces _are_ included in the string constant.  */
+
+static char *
+read_braced_string (FILE *infile)
+{
+  int c;
+  int brace_depth = 1;  /* caller-processed */
+  unsigned long starting_read_rtx_lineno = read_rtx_lineno;
+
+  obstack_1grow (&string_obstack, '{');
+  while (brace_depth)
+    {
+      c = getc (infile); /* Read the string  */
+
+      if (c == '\n')
+	read_rtx_lineno++;
+      else if (c == '{')
+	brace_depth++;
+      else if (c == '}')
+	brace_depth--;
+      else if (c == '\\')
+	{
+	  read_escape (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 (&string_obstack, c);
+    }
+
+  obstack_1grow (&string_obstack, 0);
+  return XOBFINISH (&string_obstack, char *);
+}
+
+/* Read some kind of string constant.  This is the high-level routine
+   used by read_rtx.  It handles surrounding parentheses, leading star,
+   and dispatch to the appropriate string constant reader.  */
+
+char *
+read_string (FILE *infile, int star_if_braced)
+{
+  char *stringbuf;
+  int saw_paren = 0;
+  int c, old_lineno;
+
+  c = read_skip_spaces (infile);
+  if (c == '(')
+    {
+      saw_paren = 1;
+      c = read_skip_spaces (infile);
+    }
+
+  old_lineno = read_rtx_lineno;
+  if (c == '"')
+    stringbuf = read_quoted_string (infile);
+  else if (c == '{')
+    {
+      if (star_if_braced)
+	obstack_1grow (&string_obstack, '*');
+      stringbuf = read_braced_string (infile);
+    }
+  else
+    fatal_with_file_and_line (infile, "expected `\"' or `{', found `%c'", c);
+
+  if (saw_paren)
+    {
+      c = read_skip_spaces (infile);
+      if (c != ')')
+	fatal_expected_char (infile, ')', c);
+    }
+
+  set_rtx_ptr_loc (stringbuf, read_rtx_filename, old_lineno);
+  return stringbuf;
+}
+
+/* Given a string, return the number of comma-separated elements in it.
+   Return 0 for the null string.  */
+
+int
+n_comma_elts (const char *s)
+{
+  int n;
+
+  if (*s == '\0')
+    return 0;
+
+  for (n = 1; *s; s++)
+    if (*s == ',')
+      n++;
+
+  return n;
+}
+
+/* Given a pointer to a (char *), return a pointer to the beginning of the
+   next comma-separated element in the string.  Advance the pointer given
+   to the end of that element.  Return NULL if at end of string.  Caller
+   is responsible for copying the string if necessary.  White space between
+   a comma and an element is ignored.  */
+
+const char *
+scan_comma_elt (const char **pstr)
+{
+  const char *start;
+  const char *p = *pstr;
+
+  if (*p == ',')
+    p++;
+  while (ISSPACE(*p))
+    p++;
+
+  if (*p == '\0')
+    return NULL;
+
+  start = p;
+
+  while (*p != ',' && *p != '\0')
+    p++;
+
+  *pstr = p;
+  return start;
+}
+
+/* Initialize this file's static data.  */
+
+void
+init_md_reader (void)
+{
+  obstack_init (&string_obstack);
+  ptr_locs = htab_create (161, leading_ptr_hash, leading_ptr_eq_p, 0);
+  obstack_init (&ptr_loc_obstack);
+  joined_conditions = htab_create (161, leading_ptr_hash, leading_ptr_eq_p, 0);
+  obstack_init (&joined_conditions_obstack);
+}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]