Makefile.in (READ_MD_H): New variable.

gcc/
	* Makefile.in (READ_MD_H): New variable.
	(BUILD_RTL): Add build/read-md.o.
	(lto-wrapper.o): Depend on coretypes.h instead of defaults.h.
	(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.
	* lto-wrapper.c: Include coretypes.h instead of defaults.h.
	* 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.

From-SVN: r160570
This commit is contained in:
Richard Sandiford 2010-06-10 20:21:23 +00:00 committed by Richard Sandiford
parent f14b9067c9
commit 1069247787
21 changed files with 641 additions and 526 deletions

View File

@ -1,3 +1,47 @@
2010-06-10 Richard Sandiford <rdsandiford@googlemail.com>
* Makefile.in (READ_MD_H): New variable.
(BUILD_RTL): Add build/read-md.o.
(lto-wrapper.o): Depend on coretypes.h instead of defaults.h.
(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.
* lto-wrapper.c: Include coretypes.h instead of defaults.h.
* 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.
2010-06-10 Anatoly Sokolov <aesok@post.ru>
* config/moxie/moxie.h (FUNCTION_VALUE, FUNCTION_OUTGOING_VALUE,

View File

@ -871,6 +871,7 @@ RTL_BASE_H = rtl.h rtl.def $(MACHMODE_H) reg-notes.def insn-notes.def \
$(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 vecir.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-family/c-common.def \
@ -1036,8 +1037,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.
@ -2059,7 +2061,7 @@ lto-wrapper$(exeext): lto-wrapper.o intl.o $(LIBDEPS)
$(COMPILER) $(ALL_COMPILERFLAGS) $(LDFLAGS) -o T$@ lto-wrapper.o intl.o $(LIBS)
mv -f T$@ $@
lto-wrapper.o: lto-wrapper.c $(CONFIG_H) $(SYSTEM_H) defaults.h intl.h \
lto-wrapper.o: lto-wrapper.c $(CONFIG_H) $(SYSTEM_H) coretypes.h intl.h \
$(OBSTACK_H)
# Files used by all variants of C.
@ -3765,15 +3767,18 @@ build/%.o : # dependencies provided by explicit rule later
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) $(GGC_H) errors.h
build/vec.o : vec.c $(BCONFIG_H) $(SYSTEM_H) coretypes.h $(VEC_H) \
@ -3791,10 +3796,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
@ -3804,17 +3809,19 @@ build/genchecksum.o : genchecksum.c $(BCONFIG_H) $(SYSTEM_H) $(MD5_H)
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) \
@ -3828,13 +3835,13 @@ build/genmodes.o : genmodes.c $(BCONFIG_H) $(SYSTEM_H) errors.h \
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,

View File

@ -113,6 +113,15 @@ typedef const struct edge_def *const_edge;
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_;

View File

@ -32,14 +32,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#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. */

View File

@ -26,6 +26,7 @@ along with GCC; see the file COPYING3. If not see
#include "tm.h"
#include "rtl.h"
#include "errors.h"
#include "read-md.h"
#include "gensupport.h"

View File

@ -109,9 +109,10 @@ along with GCC; see the file COPYING3. If not see
#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

View File

@ -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. */

View File

@ -25,6 +25,7 @@ along with GCC; see the file COPYING3. If not see
#include "tm.h"
#include "rtl.h"
#include "errors.h"
#include "read-md.h"
#include "gensupport.h"

View File

@ -26,6 +26,7 @@ along with GCC; see the file COPYING3. If not see
#include "tm.h"
#include "rtl.h"
#include "errors.h"
#include "read-md.h"
#include "gensupport.h"
#include "vec.h"
#include "vecprim.h"

View File

@ -28,6 +28,7 @@ along with GCC; see the file COPYING3. If not see
#include "rtl.h"
#include "obstack.h"
#include "errors.h"
#include "read-md.h"
#include "gensupport.h"
/* Obstack to remember insns with. */

View File

@ -88,6 +88,7 @@ along with GCC; see the file COPYING3. If not see
#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

View File

@ -28,6 +28,7 @@ along with GCC; see the file COPYING3. If not see
#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,

View File

@ -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) \

View File

@ -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 *, int);
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, void *info)
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. */

View File

@ -29,9 +29,6 @@ extern int init_md_reader_args_cb (int, char **, bool (*)(const char *));
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 *, const void *);
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

View File

@ -39,12 +39,12 @@ along with GCC; see the file COPYING3. If not see
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include <errno.h>
#include <signal.h>
#if ! defined( SIGCHLD ) && defined( SIGCLD )
# define SIGCHLD SIGCLD
#endif
#include "defaults.h"
#include "intl.h"
#include "libiberty.h"
#include "obstack.h"

View File

@ -29,9 +29,6 @@ along with GCC; see the file COPYING3. If not see
#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))

512
gcc/read-md.c Normal file
View File

@ -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);
}

41
gcc/read-md.h Normal file
View File

@ -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);

View File

@ -30,6 +30,7 @@ along with GCC; see the file COPYING3. If not see
#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 (struct 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 struct iterator_group modes, codes;
/* 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 *lineno)
/* 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)

View File

@ -2361,14 +2361,7 @@ extern void traverse_md_constants (int (*) (void **, void *), void *);
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);