Commit 1c7352cd by Zack Weinberg Committed by Zack Weinberg

r110123@banpei: zack | 2006-01-22 14:44:34 -0800

 r110123@banpei:  zack | 2006-01-22 14:44:34 -0800
 	* genconditions.c (condition_table, add_condition): Delete.
 	(write_conditions): Don't emit n_insn_conditions nor
 	insn_elision_unavailable.  Issue the gcc version #ifdef here,
 	inside the table, with no #else clause ...
 	(write_header): ...not here.
 	(write_writer): New function.
 	(main): Don't initialize condition_table.  Use add_c_test.
 	Call write_writer.
 	* gensupport.c (init_md_reader_args_cb): Handle multiple input
 	files on the command line.
 	(maybe_eval_c_test): Don't check insn_elision_unavailable.
 	Return -1 if there is no entry in the table, don't abort.
 	(add_c_test, traverse_c_tests): New functions.
 	* gensupport.h (insn_elision_unavailable, insn_conditions)
 	(n_insn_conditions): Delete declarations.
 	(add_c_test, traverse_c_tests): Declare.
 	* read-rtl.c: Include gensupport.h.
 	(read_conditions): New function.
 	(read_rtx): If read_rtx_1 returns 0, treat as EOF.
 	(read_rtx_1): If we get EOF when we were looking for an initial
 	open paren, return 0.  Call read_conditions when appropriate.
 	* Makefile.in: Kill BUILD_EARLY_SUPPORT and all references to
 	dummy-conditions.o.  Eliminate references to insn-conditions.o,
 	or change them to build/gencondmd.o, as appropriate.  Remove
 	insn-constants.h from $(simple_generated_h) and insn-conditions.c
 	from $(simple_generated_c).  For all files remaining in those
 	two lists, add insn-conditions.md to the generator command line.
 	Give insn-constants.h/s-constants their own rules.  Add rules
 	for build/gencondmd.c, s-conditions, insn-conditions.md, s-condmd.
 	(build/read-rtl.o): Depend on gensupport.h.
 	(genprognormal): Include preds.
 	(genprogearly): Rename genprognoprint; only difference is now that
 	they don't link with $(BUILD_PRINT).
 	* dummy-conditions.c: Delete.

From-SVN: r110119
parent 245fc639
2006-01-22 Zack Weinberg <zackw@panix.com> 2006-01-22 Zack Weinberg <zackw@panix.com>
* genconditions.c (condition_table, add_condition): Delete.
(write_conditions): Don't emit n_insn_conditions nor
insn_elision_unavailable. Issue the gcc version #ifdef here,
inside the table, with no #else clause ...
(write_header): ...not here.
(write_writer): New function.
(main): Don't initialize condition_table. Use add_c_test.
Call write_writer.
* gensupport.c (init_md_reader_args_cb): Handle multiple input
files on the command line.
(maybe_eval_c_test): Don't check insn_elision_unavailable.
Return -1 if there is no entry in the table, don't abort.
(add_c_test, traverse_c_tests): New functions.
* gensupport.h (insn_elision_unavailable, insn_conditions)
(n_insn_conditions): Delete declarations.
(add_c_test, traverse_c_tests): Declare.
* read-rtl.c: Include gensupport.h.
(read_conditions): New function.
(read_rtx): If read_rtx_1 returns 0, treat as EOF.
(read_rtx_1): If we get EOF when we were looking for an initial
open paren, return 0. Call read_conditions when appropriate.
* Makefile.in: Kill BUILD_EARLY_SUPPORT and all references to
dummy-conditions.o. Eliminate references to insn-conditions.o,
or change them to build/gencondmd.o, as appropriate. Remove
insn-constants.h from $(simple_generated_h) and insn-conditions.c
from $(simple_generated_c). For all files remaining in those
two lists, add insn-conditions.md to the generator command line.
Give insn-constants.h/s-constants their own rules. Add rules
for build/gencondmd.c, s-conditions, insn-conditions.md, s-condmd.
(build/read-rtl.o): Depend on gensupport.h.
(genprognormal): Include preds.
(genprogearly): Rename genprognoprint; only difference is now that
they don't link with $(BUILD_PRINT).
* dummy-conditions.c: Delete.
2006-01-22 Zack Weinberg <zackw@panix.com>
* genextract.c: Don't include insn-config.h. Do include vec.h. * genextract.c: Don't include insn-config.h. Do include vec.h.
Declare vectors of int, char, and locstr. Declare vectors of int, char, and locstr.
(locstr): New typedef. (locstr): New typedef.
......
...@@ -198,7 +198,7 @@ GCC_WARN_CFLAGS = $(LOOSE_WARN) $($(@D)-warn) $(NOCOMMON_FLAG) $($@-warn) ...@@ -198,7 +198,7 @@ GCC_WARN_CFLAGS = $(LOOSE_WARN) $($(@D)-warn) $(NOCOMMON_FLAG) $($@-warn)
# These files are to have -Werror bypassed in stage2: # These files are to have -Werror bypassed in stage2:
# These are very hard to completely clean due to target complexities. # These are very hard to completely clean due to target complexities.
gcc.o-warn = -Wno-error gcc.o-warn = -Wno-error
build/insn-conditions.o-warn = -Wno-error build/gencondmd.o-warn = -Wno-error
# Bison-1.75 output often yields (harmless) -Wtraditional warnings # Bison-1.75 output often yields (harmless) -Wtraditional warnings
build/gengtype-yacc.o-warn = -Wno-error build/gengtype-yacc.o-warn = -Wno-error
# flex output may yield harmless "no previous prototype" warnings # flex output may yield harmless "no previous prototype" warnings
...@@ -840,9 +840,7 @@ BUILD_LIBS = $(BUILD_LIBIBERTY) ...@@ -840,9 +840,7 @@ BUILD_LIBS = $(BUILD_LIBIBERTY)
BUILD_RTL = build/rtl.o build/read-rtl.o build/ggc-none.o \ BUILD_RTL = build/rtl.o build/read-rtl.o build/ggc-none.o \
build/min-insn-modes.o build/min-insn-modes.o
BUILD_SUPPORT = build/gensupport.o build/insn-conditions.o BUILD_SUPPORT = build/gensupport.o
BUILD_EARLY_SUPPORT = build/gensupport.o build/dummy-conditions.o
BUILD_PRINT = build/print-rtl.o BUILD_PRINT = build/print-rtl.o
BUILD_ERRORS = build/errors.o BUILD_ERRORS = build/errors.o
BUILD_VARRAY = build/varray.o BUILD_VARRAY = build/varray.o
...@@ -1019,7 +1017,7 @@ STAGECOPYSTUFF = insn-flags.h insn-config.h insn-codes.h \ ...@@ -1019,7 +1017,7 @@ STAGECOPYSTUFF = insn-flags.h insn-config.h insn-codes.h \
insn-output.c insn-recog.c insn-emit.c insn-extract.c insn-peep.c \ insn-output.c insn-recog.c insn-emit.c insn-extract.c insn-peep.c \
insn-attr.h insn-attrtab.c insn-opinit.c insn-preds.c insn-constants.h \ insn-attr.h insn-attrtab.c insn-opinit.c insn-preds.c insn-constants.h \
tm-preds.h \ tm-preds.h \
tree-check.h insn-conditions.c min-insn-modes.c insn-modes.c insn-modes.h \ tree-check.h min-insn-modes.c insn-modes.c insn-modes.h \
genrtl.c genrtl.h gt-*.h gtype-*.h gtype-desc.c gtyp-gen.h genrtl.c genrtl.h gt-*.h gtype-*.h gtype-desc.c gtyp-gen.h
# Files to be moved away after each stage in building. # Files to be moved away after each stage in building.
...@@ -2678,26 +2676,38 @@ insn-recog.o : insn-recog.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ ...@@ -2678,26 +2676,38 @@ insn-recog.o : insn-recog.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
# The "; @true" construct forces Make to recheck the timestamp on the # The "; @true" construct forces Make to recheck the timestamp on the
# target file. # target file.
simple_generated_h = insn-attr.h insn-codes.h insn-config.h \ simple_generated_h = insn-attr.h insn-codes.h insn-config.h insn-flags.h
insn-constants.h insn-flags.h
simple_generated_c = insn-attrtab.c insn-conditions.c insn-emit.c \ simple_generated_c = insn-attrtab.c insn-emit.c insn-extract.c \
insn-extract.c insn-opinit.c insn-output.c \ insn-opinit.c insn-output.c insn-peep.c \
insn-peep.c insn-recog.c insn-recog.c
$(simple_generated_h): insn-%.h: s-%; @true $(simple_generated_h): insn-%.h: s-%; @true
$(simple_generated_h:insn-%.h=s-%): s-%: $(MD_DEPS) build/gen%$(build_exeext) $(simple_generated_h:insn-%.h=s-%): s-%: build/gen%$(build_exeext) \
$(RUN_GEN) build/gen$*$(build_exeext) $(md_file) > tmp-$*.h $(MD_DEPS) insn-conditions.md
$(RUN_GEN) build/gen$*$(build_exeext) $(md_file) \
insn-conditions.md > tmp-$*.h
$(SHELL) $(srcdir)/../move-if-change tmp-$*.h insn-$*.h $(SHELL) $(srcdir)/../move-if-change tmp-$*.h insn-$*.h
$(STAMP) s-$* $(STAMP) s-$*
$(simple_generated_c): insn-%.c: s-%; @true $(simple_generated_c): insn-%.c: s-%; @true
$(simple_generated_c:insn-%.c=s-%): s-%: $(MD_DEPS) build/gen%$(build_exeext) $(simple_generated_c:insn-%.c=s-%): s-%: build/gen%$(build_exeext) \
$(RUN_GEN) build/gen$*$(build_exeext) $(md_file) > tmp-$*.c $(MD_DEPS) insn-conditions.md
$(RUN_GEN) build/gen$*$(build_exeext) $(md_file) \
insn-conditions.md > tmp-$*.c
$(SHELL) $(srcdir)/../move-if-change tmp-$*.c insn-$*.c $(SHELL) $(srcdir)/../move-if-change tmp-$*.c insn-$*.c
$(STAMP) s-$* $(STAMP) s-$*
# genconstants needs to run before insn-conditions.md is available
# (because the constants may be used in the conditions).
insn-constants.h: s-constants; @true
s-constants: build/genconstants$(build_exeext) $(MD_DEPS)
$(RUN_GEN) build/genconstants$(build_exeext) $(md_file) \
> tmp-constants.h
$(SHELL) $(srcdir)/../move-if-change tmp-constants.h insn-constants.h
$(STAMP) s-constants
# gencheck doesn't read the machine description, and the file produced # gencheck doesn't read the machine description, and the file produced
# doesn't use the insn-* convention. # doesn't use the insn-* convention.
tree-check.h: s-check ; @true tree-check.h: s-check ; @true
...@@ -2706,6 +2716,20 @@ s-check : build/gencheck$(build_exeext) ...@@ -2706,6 +2716,20 @@ s-check : build/gencheck$(build_exeext)
$(SHELL) $(srcdir)/../move-if-change tmp-check.h tree-check.h $(SHELL) $(srcdir)/../move-if-change tmp-check.h tree-check.h
$(STAMP) s-check $(STAMP) s-check
# gencondmd doesn't use the standard naming convention.
build/gencondmd.c: s-conditions; @true
s-conditions: $(MD_DEPS) build/genconditions$(build_exeext)
$(RUN_GEN) build/genconditions$(build_exeext) $(md_file) > tmp-condmd.c
$(SHELL) $(srcdir)/../move-if-change tmp-condmd.c build/gencondmd.c
$(STAMP) s-conditions
insn-conditions.md: s-condmd; @true
s-condmd: build/gencondmd$(build_exeext)
$(RUN_GEN) build/gencondmd$(build_exeext) > tmp-cond.md
$(SHELL) $(srcdir)/../move-if-change tmp-cond.md insn-conditions.md
$(STAMP) s-condmd
# These files are generated by running the same generator more than # These files are generated by running the same generator more than
# once with different options, so they have custom rules. The # once with different options, so they have custom rules. The
# stampfile idiom is the same. # stampfile idiom is the same.
...@@ -2859,7 +2883,6 @@ build/%.o : # dependencies provided by explicit rule later ...@@ -2859,7 +2883,6 @@ build/%.o : # dependencies provided by explicit rule later
# Header dependencies for the programs that generate source code. # Header dependencies for the programs that generate source code.
# These are library modules... # These are library modules...
build/dummy-conditions.o : dummy-conditions.c
build/errors.o : errors.c $(BCONFIG_H) $(SYSTEM_H) errors.h build/errors.o : errors.c $(BCONFIG_H) $(SYSTEM_H) errors.h
build/gensupport.o: gensupport.c $(BCONFIG_H) $(SYSTEM_H) coretypes.h \ build/gensupport.o: gensupport.c $(BCONFIG_H) $(SYSTEM_H) coretypes.h \
$(GTM_H) $(RTL_BASE_H) $(OBSTACK_H) errors.h $(HASHTAB_H) \ $(GTM_H) $(RTL_BASE_H) $(OBSTACK_H) errors.h $(HASHTAB_H) \
...@@ -2871,16 +2894,16 @@ build/min-insn-modes.o : min-insn-modes.c $(BCONFIG_H) $(SYSTEM_H) \ ...@@ -2871,16 +2894,16 @@ build/min-insn-modes.o : min-insn-modes.c $(BCONFIG_H) $(SYSTEM_H) \
build/print-rtl.o: print-rtl.c $(BCONFIG_H) $(SYSTEM_H) coretypes.h \ build/print-rtl.o: print-rtl.c $(BCONFIG_H) $(SYSTEM_H) coretypes.h \
$(GTM_H) $(RTL_BASE_H) $(GTM_H) $(RTL_BASE_H)
build/read-rtl.o: read-rtl.c $(BCONFIG_H) $(SYSTEM_H) coretypes.h \ build/read-rtl.o: read-rtl.c $(BCONFIG_H) $(SYSTEM_H) coretypes.h \
$(GTM_H) $(RTL_BASE_H) $(OBSTACK_H) $(HASHTAB_H) $(GTM_H) $(RTL_BASE_H) $(OBSTACK_H) $(HASHTAB_H) gensupport.h
build/rtl.o: rtl.c $(BCONFIG_H) coretypes.h $(GTM_H) $(SYSTEM_H) \ build/rtl.o: rtl.c $(BCONFIG_H) coretypes.h $(GTM_H) $(SYSTEM_H) \
$(RTL_H) real.h $(GGC_H) errors.h $(RTL_H) real.h $(GGC_H) errors.h
build/varray.o: varray.c $(BCONFIG_H) coretypes.h $(GTM_H) $(SYSTEM_H) \ build/varray.o: varray.c $(BCONFIG_H) coretypes.h $(GTM_H) $(SYSTEM_H) \
$(VARRAY_H) $(RTL_BASE_H) $(GGC_H) $(TREE_H) bitmap.h errors.h $(VARRAY_H) $(RTL_BASE_H) $(GGC_H) $(TREE_H) bitmap.h errors.h
build/vec.o : vec.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) coretypes.h vec.h \ build/vec.o : vec.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) coretypes.h vec.h \
$(GGC_H) toplev.h $(GGC_H) toplev.h
build/insn-conditions.o : insn-conditions.c $(CONFIG_H) $(SYSTEM_H) \ build/gencondmd.o : build/gencondmd.c $(CONFIG_H) $(SYSTEM_H) $(GTM_H) \
$(GTM_H) $(RTL_H) $(TM_P_H) $(REGS_H) $(FUNCTION_H) $(RECOG_H) real.h \ $(RTL_H) $(TM_P_H) $(REGS_H) $(FUNCTION_H) $(RECOG_H) real.h output.h \
output.h $(FLAGS_H) hard-reg-set.h $(RESOURCE_H) toplev.h reload.h \ $(FLAGS_H) hard-reg-set.h $(RESOURCE_H) toplev.h reload.h \
gensupport.h insn-constants.h coretypes.h gensupport.h insn-constants.h coretypes.h
# ...these are the programs themselves. # ...these are the programs themselves.
...@@ -2942,15 +2965,16 @@ build/gen%$(build_exeext): build/gen%.o $(BUILD_LIBDEPS) ...@@ -2942,15 +2965,16 @@ build/gen%$(build_exeext): build/gen%.o $(BUILD_LIBDEPS)
$(filter-out $(BUILD_LIBDEPS), $^) $(BUILD_LIBS) $(filter-out $(BUILD_LIBDEPS), $^) $(BUILD_LIBS)
# All these programs have the same additional dependency set. # All these programs have the same additional dependency set.
genprognormal = attr codes config emit extract flags opinit output peep recog genprognormal = attr codes config emit extract flags opinit output peep recog \
preds
$(genprognormal:%=build/gen%$(build_exeext)): $(BUILD_RTL) $(BUILD_SUPPORT) \ $(genprognormal:%=build/gen%$(build_exeext)): $(BUILD_RTL) $(BUILD_SUPPORT) \
$(BUILD_PRINT) $(BUILD_ERRORS) $(BUILD_PRINT) $(BUILD_ERRORS)
# And all of these, but it's a different set. # These don't have the glue to link with print-rtl.o.
genprogearly = mddeps constants conditions preds genprognoprint = mddeps constants conditions
$(genprogearly:%=build/gen%$(build_exeext)): $(BUILD_RTL) $(BUILD_ERRORS) \ $(genprognoprint:%=build/gen%$(build_exeext)): $(BUILD_RTL) $(BUILD_SUPPORT) \
$(BUILD_EARLY_SUPPORT) $(BUILD_ERRORS)
build/genpreds$(build_exeext) : $(BUILD_PRINT)
build/gengenrtl$(build_exeext) : $(BUILD_ERRORS) build/gengenrtl$(build_exeext) : $(BUILD_ERRORS)
build/genmodes$(build_exeext) : $(BUILD_ERRORS) build/genmodes$(build_exeext) : $(BUILD_ERRORS)
......
/* Support for calculating constant conditions.
Copyright (C) 2002, 2004 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 2, 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 COPYING. If not, write to
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA. */
#include <stddef.h> /* for size_t */
/* MD generators that are run before insn-conditions.c exists should
link against this file instead. Currently that is genconditions
and genconstants. */
/* In order to avoid dragging in all the headers that are needed to
declare things that gensupport.h uses, we duplicate the declaration
of struct c_test here. (In particular we do not want to have to
include tm.h nor rtl.h in this file.) */
struct c_test
{
const char *expr;
int value;
};
/* Empty conditions table to prevent link errors. */
const struct c_test insn_conditions[1] = { { 0, 0 } };
const size_t n_insn_conditions = 0;
/* Disable insn elision, since it is currently impossible. */
const int insn_elision_unavailable = 1;
...@@ -38,31 +38,10 @@ ...@@ -38,31 +38,10 @@
/* so we can include except.h in the generated file. */ /* so we can include except.h in the generated file. */
static int saw_eh_return; static int saw_eh_return;
static htab_t condition_table;
static void add_condition (const char *);
static void write_header (void); static void write_header (void);
static void write_conditions (void); static void write_conditions (void);
static int write_one_condition (void **, void *); static int write_one_condition (void **, void *);
/* Record the C test expression EXPR in the condition_table.
Duplicates clobber previous entries, which leaks memory, but
we don't care for this application. */
static void
add_condition (const char *expr)
{
struct c_test *test;
if (expr[0] == 0)
return;
test = XNEW (struct c_test);
test->expr = expr;
*(htab_find_slot (condition_table, test, INSERT)) = test;
}
/* Generate the header for insn-conditions.c. */ /* Generate the header for insn-conditions.c. */
static void static void
...@@ -86,13 +65,6 @@ write_header (void) ...@@ -86,13 +65,6 @@ write_header (void)
puts ("\ puts ("\
#include \"system.h\"\n\ #include \"system.h\"\n\
/* If we don't have __builtin_constant_p, or it's not acceptable in array\n\
initializers, fall back to assuming that all conditions potentially\n\
vary at run time. It works in 3.0.1 and later; 3.0 only when not\n\
optimizing. */\n\
#if GCC_VERSION < 3001\n\
#include \"dummy-conditions.c\"\n\
#else\n\
#include \"coretypes.h\"\n\ #include \"coretypes.h\"\n\
#include \"tm.h\"\n\ #include \"tm.h\"\n\
#include \"rtl.h\"\n\ #include \"rtl.h\"\n\
...@@ -172,15 +144,35 @@ write_conditions (void) ...@@ -172,15 +144,35 @@ write_conditions (void)
Each condition is mapped to its truth value (0 or 1), or -1 if that\n\ Each condition is mapped to its truth value (0 or 1), or -1 if that\n\
cannot be calculated at compile time. */\n\ cannot be calculated at compile time. */\n\
\n\ \n\
const struct c_test insn_conditions[] = {"); static const struct c_test insn_conditions[] = {\n \
/* If we don't have __builtin_constant_p, or it's not acceptable in array\n\
initializers, fall back to assuming that all conditions potentially\n\
vary at run time. It works in 3.0.1 and later; 3.0 only when not\n\
optimizing. */\n\
#if GCC_VERSION >= 3001");
htab_traverse (condition_table, write_one_condition, 0); traverse_c_tests (write_one_condition, 0);
puts ("};\n"); puts ("#endif\n};\n");
}
printf ("const size_t n_insn_conditions = %lu;\n", /* Emit code which will convert the C-format table to a
(unsigned long) htab_elements (condition_table)); (define_conditions) form, which the MD reader can understand.
puts ("const int insn_elision_unavailable = 0;\n#endif"); The result will be added to the set of files scanned by
'downstream' generators. */
static void
write_writer (void)
{
puts ("int\nmain(void)\n{\n\
unsigned int i;\n\
\n\
puts (\"(define_conditions [\");\n\
for (i = 0; i < ARRAY_SIZE (insn_conditions); i++)\n\
printf (\" (%d \\\"%s\\\")\\n\",\n\
insn_conditions[i].value, insn_conditions[i].expr);\n\
puts (\"])\");\n\
fflush (stdout);\n\
return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);\n}");
} }
int int
...@@ -195,10 +187,7 @@ main (int argc, char **argv) ...@@ -195,10 +187,7 @@ main (int argc, char **argv)
if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE) if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
return (FATAL_EXIT_CODE); return (FATAL_EXIT_CODE);
condition_table = htab_create (1000, hash_c_test, cmp_c_test, NULL);
/* Read the machine description. */ /* Read the machine description. */
while (1) while (1)
{ {
desc = read_md_rtx (&pattern_lineno, &code); desc = read_md_rtx (&pattern_lineno, &code);
...@@ -214,7 +203,7 @@ main (int argc, char **argv) ...@@ -214,7 +203,7 @@ main (int argc, char **argv)
case DEFINE_INSN: case DEFINE_INSN:
case DEFINE_EXPAND: case DEFINE_EXPAND:
add_condition (XSTR (desc, 2)); add_c_test (XSTR (desc, 2), -1);
/* except.h needs to know whether there is an eh_return /* except.h needs to know whether there is an eh_return
pattern in the machine description. */ pattern in the machine description. */
if (!strcmp (XSTR (desc, 0), "eh_return")) if (!strcmp (XSTR (desc, 0), "eh_return"))
...@@ -224,13 +213,14 @@ main (int argc, char **argv) ...@@ -224,13 +213,14 @@ main (int argc, char **argv)
case DEFINE_SPLIT: case DEFINE_SPLIT:
case DEFINE_PEEPHOLE: case DEFINE_PEEPHOLE:
case DEFINE_PEEPHOLE2: case DEFINE_PEEPHOLE2:
add_condition (XSTR (desc, 1)); add_c_test (XSTR (desc, 1), -1);
break; break;
} }
} }
write_header (); write_header ();
write_conditions (); write_conditions ();
write_writer ();
fflush (stdout); fflush (stdout);
return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE); return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
......
...@@ -901,93 +901,148 @@ int ...@@ -901,93 +901,148 @@ int
init_md_reader_args_cb (int argc, char **argv, bool (*parse_opt)(const char *)) init_md_reader_args_cb (int argc, char **argv, bool (*parse_opt)(const char *))
{ {
FILE *input_file; FILE *input_file;
int i, lineno; int c, i, lineno;
size_t ix;
char *lastsl; char *lastsl;
rtx desc; rtx desc;
bool no_more_options;
bool already_read_stdin;
/* Unlock the stdio streams. */ /* Unlock the stdio streams. */
unlock_std_streams (); unlock_std_streams ();
/* First we loop over all the options. */
for (i = 1; i < argc; i++) for (i = 1; i < argc; i++)
{ {
if (argv[i][0] != '-') if (argv[i][0] != '-')
continue;
c = argv[i][1];
switch (c)
{ {
if (in_fname) case 'I': /* Add directory to path for includes. */
fatal ("too many input files"); {
struct file_name_list *dirtmp;
dirtmp = XNEW (struct file_name_list);
dirtmp->next = 0; /* New one goes on the end */
if (first_dir_md_include == 0)
first_dir_md_include = dirtmp;
else
last_dir_md_include->next = dirtmp;
last_dir_md_include = dirtmp; /* Tail follows the last one */
if (argv[i][1] == 'I' && argv[i][2] != 0)
dirtmp->fname = argv[i] + 2;
else if (i + 1 == argc)
fatal ("directory name missing after -I option");
else
dirtmp->fname = argv[++i];
if (strlen (dirtmp->fname) > max_include_len)
max_include_len = strlen (dirtmp->fname);
}
break;
in_fname = argv[i]; case '\0':
} /* An argument consisting of exactly one dash is a request to
else read stdin. This will be handled in the second loop. */
{ continue;
int c = argv[i][1];
switch (c)
{
case 'I': /* Add directory to path for includes. */
{
struct file_name_list *dirtmp;
dirtmp = XNEW (struct file_name_list);
dirtmp->next = 0; /* New one goes on the end */
if (first_dir_md_include == 0)
first_dir_md_include = dirtmp;
else
last_dir_md_include->next = dirtmp;
last_dir_md_include = dirtmp; /* Tail follows the last one */
if (argv[i][1] == 'I' && argv[i][2] != 0)
dirtmp->fname = argv[i] + 2;
else if (i + 1 == argc)
fatal ("directory name missing after -I option");
else
dirtmp->fname = argv[++i];
if (strlen (dirtmp->fname) > max_include_len)
max_include_len = strlen (dirtmp->fname);
}
break;
default:
/* The program may have provided a callback so it can
accept its own options. */
if (parse_opt && parse_opt (argv[i]))
break;
fatal ("invalid option `%s'", argv[i]);
}
}
}
if (!in_fname) case '-':
fatal ("no input file name"); /* An argument consisting of just two dashes causes option
parsing to cease. */
if (argv[i][2] == '\0')
goto stop_parsing_options;
lastsl = strrchr (in_fname, '/'); default:
if (lastsl != NULL) /* The program may have provided a callback so it can
base_dir = save_string (in_fname, lastsl - in_fname + 1 ); accept its own options. */
if (parse_opt && parse_opt (argv[i]))
break;
read_rtx_filename = in_fname; fatal ("invalid option `%s'", argv[i]);
input_file = fopen (in_fname, "r"); }
if (input_file == 0)
{
perror (in_fname);
return FATAL_EXIT_CODE;
} }
/* Initialize the table of insn conditions. */ stop_parsing_options:
condition_table = htab_create (n_insn_conditions,
hash_c_test, cmp_c_test, NULL);
for (ix = 0; ix < n_insn_conditions; ix++)
*(htab_find_slot (condition_table, &insn_conditions[ix], INSERT))
= (void *) &insn_conditions[ix];
/* Prepare to read input. */
condition_table = htab_create (500, hash_c_test, cmp_c_test, NULL);
init_predicate_table (); init_predicate_table ();
obstack_init (rtl_obstack); obstack_init (rtl_obstack);
errors = 0; errors = 0;
sequence_num = 0; sequence_num = 0;
no_more_options = false;
already_read_stdin = false;
/* Read the entire file. */
while (read_rtx (input_file, &desc, &lineno)) /* Now loop over all input files. */
process_rtx (desc, lineno); for (i = 1; i < argc; i++)
fclose (input_file); {
if (argv[i][0] == '-')
{
if (argv[i][1] == '\0')
{
/* Read stdin. */
if (already_read_stdin)
fatal ("cannot read standard input twice");
base_dir = NULL;
read_rtx_filename = in_fname = "<stdin>";
read_rtx_lineno = 1;
input_file = stdin;
already_read_stdin = true;
while (read_rtx (input_file, &desc, &lineno))
process_rtx (desc, lineno);
fclose (input_file);
continue;
}
else if (argv[i][1] == '-' && argv[i][2] == '\0')
{
/* No further arguments are to be treated as options. */
no_more_options = true;
continue;
}
else if (!no_more_options)
continue;
}
/* If we get here we are looking at a non-option argument, i.e.
a file to be processed. */
in_fname = argv[i];
lastsl = strrchr (in_fname, '/');
if (lastsl != NULL)
base_dir = save_string (in_fname, lastsl - in_fname + 1 );
else
base_dir = NULL;
read_rtx_filename = in_fname;
read_rtx_lineno = 1;
input_file = fopen (in_fname, "r");
if (input_file == 0)
{
perror (in_fname);
return FATAL_EXIT_CODE;
}
while (read_rtx (input_file, &desc, &lineno))
process_rtx (desc, lineno);
fclose (input_file);
}
/* If we get to this point without having seen any files to process,
read standard input now. */
if (!in_fname)
{
base_dir = NULL;
read_rtx_filename = in_fname = "<stdin>";
read_rtx_lineno = 1;
input_file = stdin;
while (read_rtx (input_file, &desc, &lineno))
process_rtx (desc, lineno);
fclose (input_file);
}
/* Process define_cond_exec patterns. */ /* Process define_cond_exec patterns. */
if (define_cond_exec_queue != NULL) if (define_cond_exec_queue != NULL)
...@@ -1119,16 +1174,41 @@ maybe_eval_c_test (const char *expr) ...@@ -1119,16 +1174,41 @@ maybe_eval_c_test (const char *expr)
if (expr[0] == 0) if (expr[0] == 0)
return 1; return 1;
if (insn_elision_unavailable)
return -1;
dummy.expr = expr; dummy.expr = expr;
test = (const struct c_test *)htab_find (condition_table, &dummy); test = (const struct c_test *)htab_find (condition_table, &dummy);
gcc_assert (test); if (!test)
return -1;
return test->value; return test->value;
} }
/* Record the C test expression EXPR in the condition_table, with
value VAL. Duplicates clobber previous entries. */
void
add_c_test (const char *expr, int value)
{
struct c_test *test;
if (expr[0] == 0)
return;
test = XNEW (struct c_test);
test->expr = expr;
test->value = value;
*(htab_find_slot (condition_table, test, INSERT)) = test;
}
/* For every C test, call CALLBACK with two arguments: a pointer to
the condition structure and INFO. Stops when CALLBACK returns zero. */
void
traverse_c_tests (htab_trav callback, void *info)
{
if (condition_table)
htab_traverse (condition_table, callback, info);
}
/* Given a string, return the number of comma-separated elements in it. /* Given a string, return the number of comma-separated elements in it.
Return 0 for the null string. */ Return 0 for the null string. */
int int
......
...@@ -37,31 +37,27 @@ extern void message_with_line (int, const char *, ...) ...@@ -37,31 +37,27 @@ extern void message_with_line (int, const char *, ...)
Must be set before calling init_md_reader. */ Must be set before calling init_md_reader. */
extern int insn_elision; extern int insn_elision;
/* If this is 1, the insn elision table doesn't even exist yet;
maybe_eval_c_test will always return -1. This is distinct from
insn_elision because genflags and gencodes need to see all the
patterns, but treat elided patterns differently. */
extern const int insn_elision_unavailable;
/* If the C test passed as the argument can be evaluated at compile /* If the C test passed as the argument can be evaluated at compile
time, return its truth value; else return -1. The test must have time, return its truth value; else return -1. The test must have
appeared somewhere in the machine description when genconditions appeared somewhere in the machine description when genconditions
was run. */ was run. */
extern int maybe_eval_c_test (const char *); extern int maybe_eval_c_test (const char *);
/* This table should not be accessed directly; use maybe_eval_c_test. */ /* Add an entry to the table of conditions. Used by genconditions and
by read-rtl.c. */
extern void add_c_test (const char *, int);
/* This structure is used internally by gensupport.c and genconditions.c. */
struct c_test struct c_test
{ {
const char *expr; const char *expr;
int value; int value;
}; };
extern const struct c_test insn_conditions[];
extern const size_t n_insn_conditions;
#ifdef __HASHTAB_H__ #ifdef __HASHTAB_H__
extern hashval_t hash_c_test (const void *); extern hashval_t hash_c_test (const void *);
extern int cmp_c_test (const void *, const void *); extern int cmp_c_test (const void *, const void *);
extern void traverse_c_tests (htab_trav, void *);
#endif #endif
extern int n_comma_elts (const char *); extern int n_comma_elts (const char *);
......
...@@ -31,6 +31,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA ...@@ -31,6 +31,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
#include "rtl.h" #include "rtl.h"
#include "obstack.h" #include "obstack.h"
#include "hashtab.h" #include "hashtab.h"
#include "gensupport.h"
static htab_t md_constants; static htab_t md_constants;
...@@ -138,6 +139,7 @@ static void read_escape (FILE *); ...@@ -138,6 +139,7 @@ static void read_escape (FILE *);
static hashval_t def_hash (const void *); static hashval_t def_hash (const void *);
static int def_name_eq_p (const void *, const void *); static int def_name_eq_p (const void *, const void *);
static void read_constants (FILE *infile, char *tmp_char); static void read_constants (FILE *infile, char *tmp_char);
static void read_conditions (FILE *infile, char *tmp_char);
static void validate_const_int (FILE *, const char *); static void validate_const_int (FILE *, const char *);
static int find_macro (struct macro_group *, const char *, FILE *); static int find_macro (struct macro_group *, const char *, FILE *);
static struct mapping *read_mapping (struct macro_group *, htab_t, FILE *); static struct mapping *read_mapping (struct macro_group *, htab_t, FILE *);
...@@ -1205,6 +1207,58 @@ traverse_md_constants (htab_trav callback, void *info) ...@@ -1205,6 +1207,58 @@ traverse_md_constants (htab_trav callback, void *info)
if (md_constants) if (md_constants)
htab_traverse (md_constants, callback, info); htab_traverse (md_constants, callback, info);
} }
/* INFILE is a FILE pointer to read text from. TMP_CHAR is a buffer
suitable to read a name or number into. Process a
define_conditions directive, starting with the optional space after
the "define_conditions". The directive looks like this:
(define_conditions [
(number "string")
(number "string")
...
])
It's not intended to appear in machine descriptions. It is
generated by (the program generated by) genconditions.c, and
slipped in at the beginning of the sequence of MD files read by
most of the other generators. */
static void
read_conditions (FILE *infile, char *tmp_char)
{
int c;
c = read_skip_spaces (infile);
if (c != '[')
fatal_expected_char (infile, '[', c);
while ( (c = read_skip_spaces (infile)) != ']')
{
char *expr;
int value;
if (c != '(')
fatal_expected_char (infile, '(', c);
read_name (tmp_char, infile);
validate_const_int (infile, tmp_char);
value = atoi (tmp_char);
c = read_skip_spaces (infile);
if (c != '"')
fatal_expected_char (infile, '"', c);
expr = read_quoted_string (infile);
c = read_skip_spaces (infile);
if (c != ')')
fatal_expected_char (infile, ')', c);
add_c_test (expr, value);
}
c = read_skip_spaces (infile);
if (c != ')')
fatal_expected_char (infile, ')', c);
}
static void static void
validate_const_int (FILE *infile, const char *string) validate_const_int (FILE *infile, const char *string)
...@@ -1354,16 +1408,23 @@ read_rtx (FILE *infile, rtx *x, int *lineno) ...@@ -1354,16 +1408,23 @@ read_rtx (FILE *infile, rtx *x, int *lineno)
{ {
struct map_value *mode_maps; struct map_value *mode_maps;
struct macro_traverse_data mtd; struct macro_traverse_data mtd;
rtx from_file;
c = read_skip_spaces (infile); c = read_skip_spaces (infile);
if (c == EOF) if (c == EOF)
return false; return false;
ungetc (c, infile); ungetc (c, infile);
queue_next = queue_head;
queue_lineno = read_rtx_lineno; queue_lineno = read_rtx_lineno;
mode_maps = 0; mode_maps = 0;
XEXP (queue_next, 0) = read_rtx_1 (infile, &mode_maps); from_file = read_rtx_1 (infile, &mode_maps);
if (from_file == 0)
return false; /* This confuses a top level (nil) with end of
file, but a top level (nil) would have
crashed our caller anyway. */
queue_next = queue_head;
XEXP (queue_next, 0) = from_file;
XEXP (queue_next, 1) = 0; XEXP (queue_next, 1) = 0;
mtd.queue = queue_next; mtd.queue = queue_next;
...@@ -1412,6 +1473,10 @@ read_rtx_1 (FILE *infile, struct map_value **mode_maps) ...@@ -1412,6 +1473,10 @@ read_rtx_1 (FILE *infile, struct map_value **mode_maps)
again: again:
c = read_skip_spaces (infile); /* Should be open paren. */ c = read_skip_spaces (infile); /* Should be open paren. */
if (c == EOF)
return 0;
if (c != '(') if (c != '(')
fatal_expected_char (infile, '(', c); fatal_expected_char (infile, '(', c);
...@@ -1429,6 +1494,11 @@ read_rtx_1 (FILE *infile, struct map_value **mode_maps) ...@@ -1429,6 +1494,11 @@ read_rtx_1 (FILE *infile, struct map_value **mode_maps)
read_constants (infile, tmp_char); read_constants (infile, tmp_char);
goto again; goto again;
} }
if (strcmp (tmp_char, "define_conditions") == 0)
{
read_conditions (infile, tmp_char);
goto again;
}
if (strcmp (tmp_char, "define_mode_attr") == 0) if (strcmp (tmp_char, "define_mode_attr") == 0)
{ {
read_mapping (&modes, modes.attrs, infile); read_mapping (&modes, modes.attrs, infile);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment