summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorzack <zack@138bc75d-0d04-0410-961f-82ee72b054a4>2006-01-23 15:15:05 +0000
committerzack <zack@138bc75d-0d04-0410-961f-82ee72b054a4>2006-01-23 15:15:05 +0000
commitaf908c02d4c893024a3ccfa73244b96a10caeb2f (patch)
tree4239faf09e39683b3cf8286950be3b1832fd451b /gcc
parent0a1039d0a6d67e2b6c303ceb4079deead1e6b108 (diff)
downloadgcc-af908c02d4c893024a3ccfa73244b96a10caeb2f.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@110119 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog37
-rw-r--r--gcc/Makefile.in74
-rw-r--r--gcc/dummy-conditions.c42
-rw-r--r--gcc/genconditions.c68
-rw-r--r--gcc/gensupport.c220
-rw-r--r--gcc/gensupport.h16
-rw-r--r--gcc/read-rtl.c74
7 files changed, 343 insertions, 188 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 8f01cd23c13..6b723cc965b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,42 @@
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.
Declare vectors of int, char, and locstr.
(locstr): New typedef.
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 68bbb698f3c..c6eec9832c1 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -198,7 +198,7 @@ GCC_WARN_CFLAGS = $(LOOSE_WARN) $($(@D)-warn) $(NOCOMMON_FLAG) $($@-warn)
# These files are to have -Werror bypassed in stage2:
# These are very hard to completely clean due to target complexities.
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
build/gengtype-yacc.o-warn = -Wno-error
# flex output may yield harmless "no previous prototype" warnings
@@ -840,9 +840,7 @@ BUILD_LIBS = $(BUILD_LIBIBERTY)
BUILD_RTL = build/rtl.o build/read-rtl.o build/ggc-none.o \
build/min-insn-modes.o
-BUILD_SUPPORT = build/gensupport.o build/insn-conditions.o
-BUILD_EARLY_SUPPORT = build/gensupport.o build/dummy-conditions.o
-
+BUILD_SUPPORT = build/gensupport.o
BUILD_PRINT = build/print-rtl.o
BUILD_ERRORS = build/errors.o
BUILD_VARRAY = build/varray.o
@@ -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-attr.h insn-attrtab.c insn-opinit.c insn-preds.c insn-constants.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
# 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 \
# The "; @true" construct forces Make to recheck the timestamp on the
# target file.
-simple_generated_h = insn-attr.h insn-codes.h insn-config.h \
- insn-constants.h insn-flags.h
+simple_generated_h = insn-attr.h insn-codes.h insn-config.h insn-flags.h
-simple_generated_c = insn-attrtab.c insn-conditions.c insn-emit.c \
- insn-extract.c insn-opinit.c insn-output.c \
- insn-peep.c insn-recog.c
+simple_generated_c = insn-attrtab.c insn-emit.c insn-extract.c \
+ insn-opinit.c insn-output.c insn-peep.c \
+ insn-recog.c
$(simple_generated_h): insn-%.h: s-%; @true
-$(simple_generated_h:insn-%.h=s-%): s-%: $(MD_DEPS) build/gen%$(build_exeext)
- $(RUN_GEN) build/gen$*$(build_exeext) $(md_file) > tmp-$*.h
+$(simple_generated_h:insn-%.h=s-%): s-%: build/gen%$(build_exeext) \
+ $(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
$(STAMP) s-$*
$(simple_generated_c): insn-%.c: s-%; @true
-$(simple_generated_c:insn-%.c=s-%): s-%: $(MD_DEPS) build/gen%$(build_exeext)
- $(RUN_GEN) build/gen$*$(build_exeext) $(md_file) > tmp-$*.c
+$(simple_generated_c:insn-%.c=s-%): s-%: build/gen%$(build_exeext) \
+ $(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
$(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
# doesn't use the insn-* convention.
tree-check.h: s-check ; @true
@@ -2706,6 +2716,20 @@ s-check : build/gencheck$(build_exeext)
$(SHELL) $(srcdir)/../move-if-change tmp-check.h tree-check.h
$(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
# once with different options, so they have custom rules. The
# stampfile idiom is the same.
@@ -2859,7 +2883,6 @@ build/%.o : # dependencies provided by explicit rule later
# Header dependencies for the programs that generate source code.
# These are library modules...
-build/dummy-conditions.o : dummy-conditions.c
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) \
@@ -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 \
$(GTM_H) $(RTL_BASE_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) \
$(RTL_H) real.h $(GGC_H) errors.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
build/vec.o : vec.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) coretypes.h vec.h \
$(GGC_H) toplev.h
-build/insn-conditions.o : insn-conditions.c $(CONFIG_H) $(SYSTEM_H) \
- $(GTM_H) $(RTL_H) $(TM_P_H) $(REGS_H) $(FUNCTION_H) $(RECOG_H) real.h \
- output.h $(FLAGS_H) hard-reg-set.h $(RESOURCE_H) toplev.h reload.h \
+build/gencondmd.o : build/gencondmd.c $(CONFIG_H) $(SYSTEM_H) $(GTM_H) \
+ $(RTL_H) $(TM_P_H) $(REGS_H) $(FUNCTION_H) $(RECOG_H) real.h output.h \
+ $(FLAGS_H) hard-reg-set.h $(RESOURCE_H) toplev.h reload.h \
gensupport.h insn-constants.h coretypes.h
# ...these are the programs themselves.
@@ -2942,15 +2965,16 @@ build/gen%$(build_exeext): build/gen%.o $(BUILD_LIBDEPS)
$(filter-out $(BUILD_LIBDEPS), $^) $(BUILD_LIBS)
# 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) \
$(BUILD_PRINT) $(BUILD_ERRORS)
-# And all of these, but it's a different set.
-genprogearly = mddeps constants conditions preds
-$(genprogearly:%=build/gen%$(build_exeext)): $(BUILD_RTL) $(BUILD_ERRORS) \
- $(BUILD_EARLY_SUPPORT)
-build/genpreds$(build_exeext) : $(BUILD_PRINT)
+# These don't have the glue to link with print-rtl.o.
+genprognoprint = mddeps constants conditions
+$(genprognoprint:%=build/gen%$(build_exeext)): $(BUILD_RTL) $(BUILD_SUPPORT) \
+ $(BUILD_ERRORS)
+
build/gengenrtl$(build_exeext) : $(BUILD_ERRORS)
build/genmodes$(build_exeext) : $(BUILD_ERRORS)
diff --git a/gcc/dummy-conditions.c b/gcc/dummy-conditions.c
deleted file mode 100644
index 14a28b628e7..00000000000
--- a/gcc/dummy-conditions.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/* 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;
diff --git a/gcc/genconditions.c b/gcc/genconditions.c
index bdb3d30e27a..10dfc5896b4 100644
--- a/gcc/genconditions.c
+++ b/gcc/genconditions.c
@@ -38,31 +38,10 @@
/* so we can include except.h in the generated file. */
static int saw_eh_return;
-static htab_t condition_table;
-
-static void add_condition (const char *);
static void write_header (void);
static void write_conditions (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. */
static void
@@ -86,13 +65,6 @@ write_header (void)
puts ("\
#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 \"tm.h\"\n\
#include \"rtl.h\"\n\
@@ -172,15 +144,35 @@ write_conditions (void)
Each condition is mapped to its truth value (0 or 1), or -1 if that\n\
cannot be calculated at compile time. */\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",
- (unsigned long) htab_elements (condition_table));
- puts ("const int insn_elision_unavailable = 0;\n#endif");
+/* Emit code which will convert the C-format table to a
+ (define_conditions) form, which the MD reader can understand.
+ 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
@@ -195,10 +187,7 @@ main (int argc, char **argv)
if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
return (FATAL_EXIT_CODE);
- condition_table = htab_create (1000, hash_c_test, cmp_c_test, NULL);
-
/* Read the machine description. */
-
while (1)
{
desc = read_md_rtx (&pattern_lineno, &code);
@@ -214,7 +203,7 @@ main (int argc, char **argv)
case DEFINE_INSN:
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
pattern in the machine description. */
if (!strcmp (XSTR (desc, 0), "eh_return"))
@@ -224,13 +213,14 @@ main (int argc, char **argv)
case DEFINE_SPLIT:
case DEFINE_PEEPHOLE:
case DEFINE_PEEPHOLE2:
- add_condition (XSTR (desc, 1));
+ add_c_test (XSTR (desc, 1), -1);
break;
}
}
write_header ();
write_conditions ();
+ write_writer ();
fflush (stdout);
return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
diff --git a/gcc/gensupport.c b/gcc/gensupport.c
index 644b3b920a3..94d27aca975 100644
--- a/gcc/gensupport.c
+++ b/gcc/gensupport.c
@@ -901,93 +901,148 @@ int
init_md_reader_args_cb (int argc, char **argv, bool (*parse_opt)(const char *))
{
FILE *input_file;
- int i, lineno;
- size_t ix;
+ int c, i, lineno;
char *lastsl;
rtx desc;
+ bool no_more_options;
+ bool already_read_stdin;
/* Unlock the stdio streams. */
unlock_std_streams ();
+ /* First we loop over all the options. */
for (i = 1; i < argc; i++)
{
if (argv[i][0] != '-')
+ continue;
+
+ c = argv[i][1];
+ switch (c)
{
- if (in_fname)
- fatal ("too many input files");
+ 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;
- in_fname = argv[i];
- }
- else
- {
- 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]);
- }
- }
- }
+ case '\0':
+ /* An argument consisting of exactly one dash is a request to
+ read stdin. This will be handled in the second loop. */
+ continue;
- if (!in_fname)
- fatal ("no input file name");
+ case '-':
+ /* 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, '/');
- if (lastsl != NULL)
- base_dir = save_string (in_fname, lastsl - in_fname + 1 );
+ default:
+ /* The program may have provided a callback so it can
+ accept its own options. */
+ if (parse_opt && parse_opt (argv[i]))
+ break;
- read_rtx_filename = in_fname;
- input_file = fopen (in_fname, "r");
- if (input_file == 0)
- {
- perror (in_fname);
- return FATAL_EXIT_CODE;
+ fatal ("invalid option `%s'", argv[i]);
+ }
}
- /* Initialize the table of insn conditions. */
- 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];
+ stop_parsing_options:
+ /* Prepare to read input. */
+ condition_table = htab_create (500, hash_c_test, cmp_c_test, NULL);
init_predicate_table ();
-
obstack_init (rtl_obstack);
errors = 0;
sequence_num = 0;
+ no_more_options = false;
+ already_read_stdin = false;
- /* Read the entire file. */
- while (read_rtx (input_file, &desc, &lineno))
- process_rtx (desc, lineno);
- fclose (input_file);
+
+ /* Now loop over all input files. */
+ for (i = 1; i < argc; i++)
+ {
+ 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. */
if (define_cond_exec_queue != NULL)
@@ -1119,16 +1174,41 @@ maybe_eval_c_test (const char *expr)
if (expr[0] == 0)
return 1;
- if (insn_elision_unavailable)
- return -1;
-
dummy.expr = expr;
test = (const struct c_test *)htab_find (condition_table, &dummy);
- gcc_assert (test);
-
+ if (!test)
+ return -1;
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.
Return 0 for the null string. */
int
diff --git a/gcc/gensupport.h b/gcc/gensupport.h
index 51f37b7bc7c..53cbdc23b6e 100644
--- a/gcc/gensupport.h
+++ b/gcc/gensupport.h
@@ -37,31 +37,27 @@ extern void message_with_line (int, const char *, ...)
Must be set before calling init_md_reader. */
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
time, return its truth value; else return -1. The test must have
appeared somewhere in the machine description when genconditions
was run. */
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
{
const char *expr;
int value;
};
-extern const struct c_test insn_conditions[];
-extern const size_t n_insn_conditions;
-
#ifdef __HASHTAB_H__
extern hashval_t hash_c_test (const void *);
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 *);
diff --git a/gcc/read-rtl.c b/gcc/read-rtl.c
index 79f40508d3b..b4b105108eb 100644
--- a/gcc/read-rtl.c
+++ b/gcc/read-rtl.c
@@ -31,6 +31,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
#include "rtl.h"
#include "obstack.h"
#include "hashtab.h"
+#include "gensupport.h"
static htab_t md_constants;
@@ -138,6 +139,7 @@ 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);
+static void read_conditions (FILE *infile, char *tmp_char);
static void validate_const_int (FILE *, const char *);
static int find_macro (struct macro_group *, const char *, FILE *);
static struct mapping *read_mapping (struct macro_group *, htab_t, FILE *);
@@ -1205,6 +1207,58 @@ traverse_md_constants (htab_trav callback, void *info)
if (md_constants)
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
validate_const_int (FILE *infile, const char *string)
@@ -1354,16 +1408,23 @@ read_rtx (FILE *infile, rtx *x, int *lineno)
{
struct map_value *mode_maps;
struct macro_traverse_data mtd;
+ rtx from_file;
c = read_skip_spaces (infile);
if (c == EOF)
return false;
ungetc (c, infile);
- queue_next = queue_head;
queue_lineno = read_rtx_lineno;
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;
mtd.queue = queue_next;
@@ -1412,6 +1473,10 @@ read_rtx_1 (FILE *infile, struct map_value **mode_maps)
again:
c = read_skip_spaces (infile); /* Should be open paren. */
+
+ if (c == EOF)
+ return 0;
+
if (c != '(')
fatal_expected_char (infile, '(', c);
@@ -1429,6 +1494,11 @@ read_rtx_1 (FILE *infile, struct map_value **mode_maps)
read_constants (infile, tmp_char);
goto again;
}
+ if (strcmp (tmp_char, "define_conditions") == 0)
+ {
+ read_conditions (infile, tmp_char);
+ goto again;
+ }
if (strcmp (tmp_char, "define_mode_attr") == 0)
{
read_mapping (&modes, modes.attrs, infile);