diff options
author | zack <zack@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-01-23 15:15:05 +0000 |
---|---|---|
committer | zack <zack@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-01-23 15:15:05 +0000 |
commit | af908c02d4c893024a3ccfa73244b96a10caeb2f (patch) | |
tree | 4239faf09e39683b3cf8286950be3b1832fd451b /gcc | |
parent | 0a1039d0a6d67e2b6c303ceb4079deead1e6b108 (diff) | |
download | gcc-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/ChangeLog | 37 | ||||
-rw-r--r-- | gcc/Makefile.in | 74 | ||||
-rw-r--r-- | gcc/dummy-conditions.c | 42 | ||||
-rw-r--r-- | gcc/genconditions.c | 68 | ||||
-rw-r--r-- | gcc/gensupport.c | 220 | ||||
-rw-r--r-- | gcc/gensupport.h | 16 | ||||
-rw-r--r-- | gcc/read-rtl.c | 74 |
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); |