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
This commit is contained in:
parent
245fc63928
commit
1c7352cde8
|
@ -1,3 +1,40 @@
|
|||
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.
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
|
@ -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);
|
||||
|
|
220
gcc/gensupport.c
220
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
case '\0':
|
||||
/* An argument consisting of exactly one dash is a request to
|
||||
read stdin. This will be handled in the second loop. */
|
||||
continue;
|
||||
|
||||
fatal ("invalid option `%s'", argv[i]);
|
||||
}
|
||||
case '-':
|
||||
/* An argument consisting of just two dashes causes option
|
||||
parsing to cease. */
|
||||
if (argv[i][2] == '\0')
|
||||
goto stop_parsing_options;
|
||||
|
||||
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)
|
||||
fatal ("no input file name");
|
||||
|
||||
lastsl = strrchr (in_fname, '/');
|
||||
if (lastsl != NULL)
|
||||
base_dir = save_string (in_fname, lastsl - in_fname + 1 );
|
||||
|
||||
read_rtx_filename = in_fname;
|
||||
input_file = fopen (in_fname, "r");
|
||||
if (input_file == 0)
|
||||
{
|
||||
perror (in_fname);
|
||||
return FATAL_EXIT_CODE;
|
||||
}
|
||||
|
||||
/* 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
|
||||
|
|
|
@ -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 *);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue