diff options
-rw-r--r-- | gcc/ChangeLog | 69 | ||||
-rw-r--r-- | gcc/Makefile.in | 2 | ||||
-rw-r--r-- | gcc/genattr.c | 2 | ||||
-rw-r--r-- | gcc/genattrtab.c | 2 | ||||
-rw-r--r-- | gcc/genautomata.c | 2 | ||||
-rw-r--r-- | gcc/gencodes.c | 2 | ||||
-rw-r--r-- | gcc/genconditions.c | 2 | ||||
-rw-r--r-- | gcc/genconfig.c | 2 | ||||
-rw-r--r-- | gcc/genconstants.c | 2 | ||||
-rw-r--r-- | gcc/genemit.c | 2 | ||||
-rw-r--r-- | gcc/genextract.c | 2 | ||||
-rw-r--r-- | gcc/genflags.c | 2 | ||||
-rw-r--r-- | gcc/genmddeps.c | 5 | ||||
-rw-r--r-- | gcc/genopinit.c | 2 | ||||
-rw-r--r-- | gcc/genoutput.c | 2 | ||||
-rw-r--r-- | gcc/genpeep.c | 2 | ||||
-rw-r--r-- | gcc/genpreds.c | 2 | ||||
-rw-r--r-- | gcc/genrecog.c | 2 | ||||
-rw-r--r-- | gcc/gensupport.c | 264 | ||||
-rw-r--r-- | gcc/gensupport.h | 9 | ||||
-rw-r--r-- | gcc/read-md.c | 291 | ||||
-rw-r--r-- | gcc/read-md.h | 12 | ||||
-rw-r--r-- | gcc/read-rtl.c | 211 | ||||
-rw-r--r-- | gcc/rtl.def | 3 | ||||
-rw-r--r-- | gcc/rtl.h | 2 |
25 files changed, 490 insertions, 408 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index aeb277f8aef..e697a529387 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,74 @@ 2010-06-10 Richard Sandiford <rdsandiford@googlemail.com> + * Makefile.in (build/genmddeps.o): Depend on $(READ_MD_H). + * genmddeps.c: Include read-md.h. + (main): Call init_rtx_reader_args instead of init_md_reader_args. + * genattr.c (main): Likewise. + * genattrtab.c (main): Likewise. + * genautomata.c (main): Likewise. + * gencodes.c (main): Likewise. + * genconditions.c (main): Likewise. + * genconfig.c (main): Likewise. + * genconstants.c (main): Likewise. + * genemit.c (main): Likewise. + * genextract.c (main): Likewise. + * genflags.c (main): Likewise. + * genopinit.c (main): Likewise. + * genoutput.c (main): Likewise. + * genpeep.c (main): Likewise. + * genrecog.c (main): Likewise. + * genpreds.c (main): Likewise. + * gensupport.h (in_fname): Move to read-md.h. + (init_md_reader_args_cb): Rename to... + (init_rtx_reader_args_cb): ...this and return a bool. + (init_md_reader_args): Rename to... + (init_rtx_reader_args): ...this and return a bool. + (include_callback): Move to read-md.h. + * gensupport.c (in_fname, include_callback, base_dir, max_include_len) + (file_name_list, first_dir_md_include): Move to read-md.c + (first_bracket_include): Delete unused variable. + (last_dir_md_include): Move to read-md.c. + (process_include): Delete, moving code to read-md.c:handle_include. + (process_rtx): Don't handle INCLUDE. + (save_string): Delete. + (rtx_handle_directive): New function. + (init_md_reader_args_cb): Rename to... + (init_rtx_reader_args_cb): ...this and return a boolean success value. + Use read_md_args. + (init_md_reader_args): Rename to... + (init_rtx_reader_args): ...this and return a boolean success value. + * rtl.def (INCLUDE): Delete. + * rtl.h (read_rtx): Remove "int *" argument. Add "const char *" + argument. + * read-rtl.c (read_conditions): Don't gobble ')' here. + (read_mapping): Likewise. + (read_rtx): Remove LINENO argument. Add RTX_NAME argument. + Handle top-level non-rtx constructs here rather than in read_rtx_1. + Store the whole queue in *X. Remove call to init_md_reader. + (read_rtx_1): Rename to... + (read_rtx_code): ...this. Call read_nested_rtx to read subrtxes. + Don't handle top-level non-rtx constructs here. Don't handle (nil) + here. + (read_nested_rtx): New function. Handle (nil) here rather than + in read_rtx_code. + (read_rtx_variadic): Call read_nested_rtx to read subrtxes. Don't + gobble ')' here. + * read-md.h (directive_handler_t): New type. + (in_fname, include_callback): Moved from read-md.h. + (read_constants, init_md_reader): Delete. + (read_md_files): Declare. + * read-md.c (file_name_list, in_fname, base_dir, first_dir_md_include) + (last_dir_md_include_ptr, include_callback, max_include_len): Moved + from gensupport.c. + (read_constants): Rename to... + (handle_constants): ...this. Don't gobble ')' here. + (handle_include, handle_file, handle_toplevel_file) + (parse_include): New functions, mostly taken from gensupport.c. + (init_md_reader): Subsume into... + (read_md_files): ...this new function. + +2010-06-10 Richard Sandiford <rdsandiford@googlemail.com> + * read-md.h (read_char): Increment read_md_lineno after reading '\n'. (unread_char): Decrement read_md_lineno after putting back '\n'. * read-md.c (fatal_with_file_and_line): Push back any characters diff --git a/gcc/Makefile.in b/gcc/Makefile.in index b8379d082b1..84f332ff597 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -3829,7 +3829,7 @@ build/gengtype-parse.o : gengtype-parse.c gengtype.h $(BCONFIG_H) \ build/gengtype.o : gengtype.c $(BCONFIG_H) $(SYSTEM_H) gengtype.h \ rtl.def insn-notes.def errors.h double-int.h $(HASHTAB_H) build/genmddeps.o: genmddeps.c $(BCONFIG_H) $(SYSTEM_H) coretypes.h \ - $(GTM_H) $(RTL_BASE_H) errors.h gensupport.h + $(GTM_H) $(RTL_BASE_H) errors.h $(READ_MD_H) gensupport.h build/genmodes.o : genmodes.c $(BCONFIG_H) $(SYSTEM_H) errors.h \ $(HASHTAB_H) machmode.def $(extra_modes_file) build/genopinit.o : genopinit.c $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H) \ diff --git a/gcc/genattr.c b/gcc/genattr.c index 78c510d3b13..84399b8a677 100644 --- a/gcc/genattr.c +++ b/gcc/genattr.c @@ -98,7 +98,7 @@ main (int argc, char **argv) progname = "genattr"; - if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE) + if (!init_rtx_reader_args (argc, argv)) return (FATAL_EXIT_CODE); puts ("/* Generated automatically by the program `genattr'"); diff --git a/gcc/genattrtab.c b/gcc/genattrtab.c index 545cd8ebce0..ac5c75e45d0 100644 --- a/gcc/genattrtab.c +++ b/gcc/genattrtab.c @@ -4417,7 +4417,7 @@ main (int argc, char **argv) progname = "genattrtab"; - if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE) + if (!init_rtx_reader_args (argc, argv)) return (FATAL_EXIT_CODE); obstack_init (hash_obstack); diff --git a/gcc/genautomata.c b/gcc/genautomata.c index f7493c7071d..a268aa053da 100644 --- a/gcc/genautomata.c +++ b/gcc/genautomata.c @@ -9467,7 +9467,7 @@ main (int argc, char **argv) progname = "genautomata"; - if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE) + if (!init_rtx_reader_args (argc, argv)) return (FATAL_EXIT_CODE); initiate_automaton_gen (argc, argv); diff --git a/gcc/gencodes.c b/gcc/gencodes.c index 5a6014cb1c3..4c59f8392b5 100644 --- a/gcc/gencodes.c +++ b/gcc/gencodes.c @@ -58,7 +58,7 @@ main (int argc, char **argv) direct references to CODE_FOR_xxx in C code. */ insn_elision = 0; - if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE) + if (!init_rtx_reader_args (argc, argv)) return (FATAL_EXIT_CODE); puts ("\ diff --git a/gcc/genconditions.c b/gcc/genconditions.c index 9ac7e83fd09..2d93c3470d6 100644 --- a/gcc/genconditions.c +++ b/gcc/genconditions.c @@ -214,7 +214,7 @@ main (int argc, char **argv) progname = "genconditions"; - if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE) + if (!init_rtx_reader_args (argc, argv)) return (FATAL_EXIT_CODE); /* Read the machine description. */ diff --git a/gcc/genconfig.c b/gcc/genconfig.c index a0a023dce47..027c92e50dc 100644 --- a/gcc/genconfig.c +++ b/gcc/genconfig.c @@ -264,7 +264,7 @@ main (int argc, char **argv) progname = "genconfig"; - if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE) + if (!init_rtx_reader_args (argc, argv)) return (FATAL_EXIT_CODE); puts ("/* Generated automatically by the program `genconfig'"); diff --git a/gcc/genconstants.c b/gcc/genconstants.c index 1a0182c7a59..e5f083a36fd 100644 --- a/gcc/genconstants.c +++ b/gcc/genconstants.c @@ -52,7 +52,7 @@ main (int argc, char **argv) { progname = "genconstants"; - if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE) + if (!init_rtx_reader_args (argc, argv)) return (FATAL_EXIT_CODE); /* Initializing the MD reader has the side effect of loading up diff --git a/gcc/genemit.c b/gcc/genemit.c index 69a3a7d9258..98ec42fe0c3 100644 --- a/gcc/genemit.c +++ b/gcc/genemit.c @@ -833,7 +833,7 @@ main (int argc, char **argv) progname = "genemit"; - if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE) + if (!init_rtx_reader_args (argc, argv)) return (FATAL_EXIT_CODE); /* Assign sequential codes to all entries in the machine description diff --git a/gcc/genextract.c b/gcc/genextract.c index 289bc093235..2bf9779f381 100644 --- a/gcc/genextract.c +++ b/gcc/genextract.c @@ -410,7 +410,7 @@ main (int argc, char **argv) progname = "genextract"; - if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE) + if (!init_rtx_reader_args (argc, argv)) return (FATAL_EXIT_CODE); /* Read the machine description. */ diff --git a/gcc/genflags.c b/gcc/genflags.c index 6f0fdf1f941..f3cffe8746d 100644 --- a/gcc/genflags.c +++ b/gcc/genflags.c @@ -262,7 +262,7 @@ main (int argc, char **argv) direct calls to their generators in C code. */ insn_elision = 0; - if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE) + if (!init_rtx_reader_args (argc, argv)) return (FATAL_EXIT_CODE); puts ("/* Generated automatically by the program `genflags'"); diff --git a/gcc/genmddeps.c b/gcc/genmddeps.c index fb5c3113e54..f9fdacb4a95 100644 --- a/gcc/genmddeps.c +++ b/gcc/genmddeps.c @@ -20,8 +20,9 @@ #include "coretypes.h" #include "tm.h" #include "rtl.h" -#include "gensupport.h" #include "errors.h" +#include "read-md.h" +#include "gensupport.h" struct filedep @@ -49,7 +50,7 @@ main (int argc, char **argv) progname = "genmddeps"; include_callback = add_filedep; - if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE) + if (!init_rtx_reader_args (argc, argv)) return (FATAL_EXIT_CODE); *last = NULL; diff --git a/gcc/genopinit.c b/gcc/genopinit.c index d28baabba7f..d0ec274842a 100644 --- a/gcc/genopinit.c +++ b/gcc/genopinit.c @@ -472,7 +472,7 @@ main (int argc, char **argv) progname = "genopinit"; - if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE) + if (!init_rtx_reader_args (argc, argv)) return (FATAL_EXIT_CODE); printf ("/* Generated automatically by the program `genopinit'\n\ diff --git a/gcc/genoutput.c b/gcc/genoutput.c index c3ce33db65b..a8ab275bff9 100644 --- a/gcc/genoutput.c +++ b/gcc/genoutput.c @@ -1002,7 +1002,7 @@ main (int argc, char **argv) progname = "genoutput"; - if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE) + if (!init_rtx_reader_args (argc, argv)) return (FATAL_EXIT_CODE); output_prologue (); diff --git a/gcc/genpeep.c b/gcc/genpeep.c index 0fec59f317c..b129f94b020 100644 --- a/gcc/genpeep.c +++ b/gcc/genpeep.c @@ -358,7 +358,7 @@ main (int argc, char **argv) progname = "genpeep"; - if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE) + if (!init_rtx_reader_args (argc, argv)) return (FATAL_EXIT_CODE); printf ("/* Generated automatically by the program `genpeep'\n\ diff --git a/gcc/genpreds.c b/gcc/genpreds.c index cd538457353..c69647042c7 100644 --- a/gcc/genpreds.c +++ b/gcc/genpreds.c @@ -1393,7 +1393,7 @@ main (int argc, char **argv) progname = argv[0]; if (argc <= 1) fatal ("no input file name"); - if (init_md_reader_args_cb (argc, argv, parse_option) != SUCCESS_EXIT_CODE) + if (!init_rtx_reader_args_cb (argc, argv, parse_option)) return FATAL_EXIT_CODE; while ((defn = read_md_rtx (&pattern_lineno, &next_insn_code)) != 0) diff --git a/gcc/genrecog.c b/gcc/genrecog.c index a5e069f2dac..26c2a95bbc5 100644 --- a/gcc/genrecog.c +++ b/gcc/genrecog.c @@ -2708,7 +2708,7 @@ main (int argc, char **argv) memset (&split_tree, 0, sizeof split_tree); memset (&peephole2_tree, 0, sizeof peephole2_tree); - if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE) + if (!init_rtx_reader_args (argc, argv)) return (FATAL_EXIT_CODE); next_insn_code = 0; diff --git a/gcc/gensupport.c b/gcc/gensupport.c index df0ad5f352b..1389658609c 100644 --- a/gcc/gensupport.c +++ b/gcc/gensupport.c @@ -35,12 +35,6 @@ int target_flags; int insn_elision = 1; -const char *in_fname; - -/* This callback will be invoked whenever an rtl include directive is - processed. To be used for creation of the dependency file. */ -void (*include_callback) (const char *); - static struct obstack obstack; struct obstack *rtl_obstack = &obstack; @@ -52,8 +46,6 @@ static const char *predicable_false; static htab_t condition_table; -static char *base_dir = NULL; - /* We initially queue all patterns, process the define_insn and define_cond_exec patterns, then return them one at a time. */ @@ -82,22 +74,6 @@ static struct queue_elem **other_tail = &other_queue; static struct queue_elem *queue_pattern (rtx, struct queue_elem ***, const char *, int); -/* Current maximum length of directory names in the search path - for include files. (Altered as we get more of them.) */ - -size_t max_include_len; - -struct file_name_list - { - struct file_name_list *next; - const char *fname; - }; - -struct file_name_list *first_dir_md_include = 0; /* First dir to search */ - /* First dir to search for <file> */ -struct file_name_list *first_bracket_include = 0; -struct file_name_list *last_dir_md_include = 0; /* Last in chain */ - static void remove_constraints (rtx); static void process_rtx (rtx, int); @@ -114,8 +90,6 @@ static const char *alter_output_for_insn (struct queue_elem *, int, int); static void process_one_cond_exec (struct queue_elem *); static void process_define_cond_exec (void); -static void process_include (rtx, int); -static char *save_string (const char *, int); static void init_predicate_table (void); static void record_insn_name (int, const char *); @@ -183,76 +157,6 @@ remove_constraints (rtx part) } } -/* Process an include file assuming that it lives in gcc/config/{target}/ - if the include looks like (include "file"). */ - -static void -process_include (rtx desc, int lineno) -{ - const char *filename = XSTR (desc, 0); - const char *old_filename; - int old_lineno; - char *pathname; - FILE *input_file, *old_file; - - /* If specified file name is absolute, skip the include stack. */ - if (! IS_ABSOLUTE_PATH (filename)) - { - struct file_name_list *stackp; - - /* Search directory path, trying to open the file. */ - for (stackp = first_dir_md_include; stackp; stackp = stackp->next) - { - static const char sep[2] = { DIR_SEPARATOR, '\0' }; - - pathname = concat (stackp->fname, sep, filename, NULL); - input_file = fopen (pathname, "r"); - if (input_file != NULL) - goto success; - free (pathname); - } - } - - if (base_dir) - pathname = concat (base_dir, filename, NULL); - else - pathname = xstrdup (filename); - input_file = fopen (pathname, "r"); - if (input_file == NULL) - { - free (pathname); - error_with_line (lineno, "include file `%s' not found", filename); - return; - } - success: - - /* Save old cursor; setup new for the new file. Note that "lineno" the - argument to this function is the beginning of the include statement, - while read_md_lineno has already been advanced. */ - old_file = read_md_file; - old_filename = read_md_filename; - old_lineno = read_md_lineno; - read_md_file = input_file; - read_md_filename = pathname; - read_md_lineno = 1; - - if (include_callback) - include_callback (pathname); - - /* Read the entire file. */ - while (read_rtx (&desc, &lineno)) - process_rtx (desc, lineno); - - /* Do not free pathname. It is attached to the various rtx queue - elements. */ - - read_md_file = old_file; - read_md_filename = old_filename; - read_md_lineno = old_lineno; - - fclose (input_file); -} - /* Process a top level rtx in some way, queuing as appropriate. */ static void @@ -281,10 +185,6 @@ process_rtx (rtx desc, int lineno) queue_pattern (desc, &define_pred_tail, read_md_filename, lineno); break; - case INCLUDE: - process_include (desc, lineno); - break; - case DEFINE_INSN_AND_SPLIT: { const char *split_cond; @@ -868,178 +768,46 @@ process_define_cond_exec (void) for (elem = define_cond_exec_queue; elem ; elem = elem->next) process_one_cond_exec (elem); } + +/* A read_md_files callback for reading an rtx. */ -static char * -save_string (const char *s, int len) +static void +rtx_handle_directive (int lineno, const char *rtx_name) { - char *result = XNEWVEC (char, len + 1); + rtx queue, x; - memcpy (result, s, len); - result[len] = 0; - return result; + if (read_rtx (rtx_name, &queue)) + for (x = queue; x; x = XEXP (x, 1)) + process_rtx (XEXP (x, 0), lineno); } - /* The entry point for initializing the reader. */ -int -init_md_reader_args_cb (int argc, char **argv, bool (*parse_opt)(const char *)) +bool +init_rtx_reader_args_cb (int argc, char **argv, + bool (*parse_opt) (const char *)) { - 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) - { - 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; - - case '\0': - /* An argument consisting of exactly one dash is a request to - read stdin. This will be handled in the second loop. */ - continue; - - 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]); - } - } - - 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); sequence_num = 0; - no_more_options = false; - already_read_stdin = false; - - /* 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_md_file = stdin; - read_md_filename = in_fname = "<stdin>"; - read_md_lineno = 1; - already_read_stdin = true; - - while (read_rtx (&desc, &lineno)) - process_rtx (desc, lineno); - fclose (read_md_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_md_file = fopen (in_fname, "r"); - if (read_md_file == 0) - { - perror (in_fname); - return FATAL_EXIT_CODE; - } - read_md_filename = in_fname; - read_md_lineno = 1; - - while (read_rtx (&desc, &lineno)) - process_rtx (desc, lineno); - fclose (read_md_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_md_file = stdin; - read_md_filename = in_fname = "<stdin>"; - read_md_lineno = 1; - - while (read_rtx (&desc, &lineno)) - process_rtx (desc, lineno); - fclose (read_md_file); - } + read_md_files (argc, argv, parse_opt, rtx_handle_directive); /* Process define_cond_exec patterns. */ if (define_cond_exec_queue != NULL) process_define_cond_exec (); - return have_error ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE; + return !have_error; } /* Programs that don't have their own options can use this entry point instead. */ -int -init_md_reader_args (int argc, char **argv) +bool +init_rtx_reader_args (int argc, char **argv) { - return init_md_reader_args_cb (argc, argv, 0); + return init_rtx_reader_args_cb (argc, argv, 0); } /* The entry point for reading a single rtx from an md file. */ diff --git a/gcc/gensupport.h b/gcc/gensupport.h index 3e916bef99f..f2fcce56ea3 100644 --- a/gcc/gensupport.h +++ b/gcc/gensupport.h @@ -23,10 +23,9 @@ along with GCC; see the file COPYING3. If not see struct obstack; extern struct obstack *rtl_obstack; -extern const char *in_fname; -extern int init_md_reader_args_cb (int, char **, bool (*)(const char *)); -extern int init_md_reader_args (int, char **); +extern bool init_rtx_reader_args_cb (int, char **, bool (*)(const char *)); +extern bool init_rtx_reader_args (int, char **); extern rtx read_md_rtx (int *, int *); /* Set this to 0 to disable automatic elision of insn patterns which @@ -84,8 +83,4 @@ extern void add_predicate (struct pred_data *); #define FOR_ALL_PREDICATES(p) for (p = first_predicate; p; p = p->next) -/* This callback will be invoked whenever an rtl include directive is - processed. To be used for creation of the dependency file. */ -extern void (*include_callback) (const char *); - #endif /* GCC_GENSUPPORT_H */ diff --git a/gcc/read-md.c b/gcc/read-md.c index 140292189fb..0071e28b471 100644 --- a/gcc/read-md.c +++ b/gcc/read-md.c @@ -34,6 +34,12 @@ struct ptr_loc { int lineno; }; +/* A singly-linked list of filenames. */ +struct file_name_list { + struct file_name_list *next; + const char *fname; +}; + /* Obstack used for allocating MD strings. */ struct obstack string_obstack; @@ -62,10 +68,32 @@ const char *read_md_filename; /* The current line number in READ_MD_FILE. */ int read_md_lineno; +/* The name of the toplevel file that indirectly included READ_MD_FILE. */ +const char *in_fname; + +/* The directory part of IN_FNAME. NULL if IN_FNAME is a bare filename. */ +static char *base_dir; + +/* The first directory to search. */ +static struct file_name_list *first_dir_md_include; + +/* A pointer to the null terminator of the md include chain. */ +static struct file_name_list **last_dir_md_include_ptr = &first_dir_md_include; + +/* This callback will be invoked whenever an md include directive is + processed. To be used for creation of the dependency file. */ +void (*include_callback) (const char *); + +/* The current maximum length of directory names in the search path + for include files. (Altered as we get more of them.) */ +static size_t max_include_len; + /* A table of md_constant structures, hashed by name. Null if no constant expansion should occur. */ static htab_t md_constants; +static void handle_file (directive_handler_t); + /* Given an object that starts with a char * name field, return a hash code for its name. */ @@ -597,8 +625,8 @@ scan_comma_elt (const char **pstr) /* Process a define_constants directive, starting with the optional space after the "define_constants". */ -void -read_constants (void) +static void +handle_constants (void) { int c; htab_t defs; @@ -648,9 +676,6 @@ read_constants (void) fatal_expected_char (')', c); } md_constants = defs; - c = read_skip_spaces (); - if (c != ')') - fatal_expected_char (')', c); } /* For every constant definition, call CALLBACK with two arguments: @@ -664,14 +689,264 @@ traverse_md_constants (htab_trav callback, void *info) htab_traverse (md_constants, callback, info); } -/* Initialize this file's static data. */ +/* Process an "include" directive, starting with the optional space + after the "include". Read in the file and use HANDLE_DIRECTIVE + to process each unknown directive. LINENO is the line number on + which the "include" occured. */ -void -init_md_reader (void) +static void +handle_include (int lineno, directive_handler_t handle_directive) { + const char *filename; + const char *old_filename; + int old_lineno; + char *pathname; + FILE *input_file, *old_file; + + filename = read_string (false); + input_file = NULL; + + /* If the specified file name is absolute, skip the include stack. */ + if (!IS_ABSOLUTE_PATH (filename)) + { + struct file_name_list *stackp; + + /* Search the directory path, trying to open the file. */ + for (stackp = first_dir_md_include; stackp; stackp = stackp->next) + { + static const char sep[2] = { DIR_SEPARATOR, '\0' }; + + pathname = concat (stackp->fname, sep, filename, NULL); + input_file = fopen (pathname, "r"); + if (input_file != NULL) + break; + free (pathname); + } + } + + /* If we haven't managed to open the file yet, try combining the + filename with BASE_DIR. */ + if (input_file == NULL) + { + if (base_dir) + pathname = concat (base_dir, filename, NULL); + else + pathname = xstrdup (filename); + input_file = fopen (pathname, "r"); + } + + if (input_file == NULL) + { + free (pathname); + error_with_line (lineno, "include file `%s' not found", filename); + return; + } + + /* Save the old cursor. Note that the LINENO argument to this + function is the beginning of the include statement, while + read_md_lineno has already been advanced. */ + old_file = read_md_file; + old_filename = read_md_filename; + old_lineno = read_md_lineno; + + if (include_callback) + include_callback (pathname); + + read_md_file = input_file; + read_md_filename = pathname; + handle_file (handle_directive); + + /* Restore the old cursor. */ + read_md_file = old_file; + read_md_filename = old_filename; + read_md_lineno = old_lineno; + + /* Do not free the pathname. It is attached to the various rtx + queue elements. */ +} + +/* Process the current file, assuming that read_md_file and + read_md_filename are valid. Use HANDLE_DIRECTIVE to handle + unknown directives. */ + +static void +handle_file (directive_handler_t handle_directive) +{ + struct md_name directive; + int c, lineno; + + read_md_lineno = 1; + while ((c = read_skip_spaces ()) != EOF) + { + lineno = read_md_lineno; + if (c != '(') + fatal_expected_char ('(', c); + + read_name (&directive); + if (strcmp (directive.string, "define_constants") == 0) + handle_constants (); + else if (strcmp (directive.string, "include") == 0) + handle_include (lineno, handle_directive); + else + handle_directive (lineno, directive.string); + + c = read_skip_spaces (); + if (c != ')') + fatal_expected_char (')', c); + } + fclose (read_md_file); +} + +/* Like handle_file, but for top-level files. Set up in_fname and + base_dir accordingly. */ + +static void +handle_toplevel_file (directive_handler_t handle_directive) +{ + char *lastsl; + + in_fname = read_md_filename; + lastsl = strrchr (in_fname, '/'); + if (lastsl != NULL) + base_dir = xstrndup (in_fname, lastsl - in_fname + 1); + else + base_dir = NULL; + + handle_file (handle_directive); +} + +/* Parse a -I option with argument ARG. */ + +static void +parse_include (const char *arg) +{ + struct file_name_list *dirtmp; + + dirtmp = XNEW (struct file_name_list); + dirtmp->next = 0; + dirtmp->fname = arg; + *last_dir_md_include_ptr = dirtmp; + last_dir_md_include_ptr = &dirtmp->next; + if (strlen (dirtmp->fname) > max_include_len) + max_include_len = strlen (dirtmp->fname); +} + +/* The main routine for reading .md files. Try to process all the .md + files specified on the command line and return true if no error occured. + + ARGC and ARGV are the arguments to main. + + PARSE_OPT, if nonnull, is passed all unknown command-line arguments. + It should return true if it recognizes the argument or false if a + generic error should be reported. + + The parser calls HANDLE_DIRECTIVE for each unknown directive. + See the comment above the directive_handler_t definition for + details about the callback's interface. */ + +bool +read_md_files (int argc, char **argv, bool (*parse_opt) (const char *), + directive_handler_t handle_directive) +{ + int i; + bool no_more_options; + bool already_read_stdin; + int num_files; + + /* Initialize global data. */ obstack_init (&string_obstack); ptr_locs = htab_create (161, leading_ptr_hash, leading_ptr_eq_p, 0); obstack_init (&ptr_loc_obstack); joined_conditions = htab_create (161, leading_ptr_hash, leading_ptr_eq_p, 0); obstack_init (&joined_conditions_obstack); + + /* Unlock the stdio streams. */ + unlock_std_streams (); + + /* First we loop over all the options. */ + for (i = 1; i < argc; i++) + if (argv[i][0] == '-') + { + /* An argument consisting of exactly one dash is a request to + read stdin. This will be handled in the second loop. */ + if (argv[i][1] == '\0') + continue; + + /* An argument consisting of just two dashes causes option + parsing to cease. */ + if (argv[i][1] == '-' && argv[i][2] == '\0') + break; + + if (argv[i][1] == 'I') + { + if (argv[i][2] != '\0') + parse_include (argv[i] + 2); + else if (++i < argc) + parse_include (argv[i]); + else + fatal ("directory name missing after -I option"); + continue; + } + + /* The program may have provided a callback so it can + accept its own options. */ + if (parse_opt && parse_opt (argv[i])) + continue; + + fatal ("invalid option `%s'", argv[i]); + } + + /* Now loop over all input files. */ + num_files = 0; + no_more_options = false; + already_read_stdin = false; + 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"); + + read_md_file = stdin; + read_md_filename = "<stdin>"; + handle_toplevel_file (handle_directive); + already_read_stdin = true; + 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. */ + read_md_filename = argv[i]; + read_md_file = fopen (read_md_filename, "r"); + if (read_md_file == 0) + { + perror (read_md_filename); + return false; + } + handle_toplevel_file (handle_directive); + num_files++; + } + + /* If we get to this point without having seen any files to process, + read the standard input now. */ + if (num_files == 0 && !already_read_stdin) + { + read_md_file = stdin; + read_md_filename = "<stdin>"; + handle_toplevel_file (handle_directive); + } + + return !have_error; } diff --git a/gcc/read-md.h b/gcc/read-md.h index 0ebebde057d..bb83468f537 100644 --- a/gcc/read-md.h +++ b/gcc/read-md.h @@ -41,10 +41,18 @@ struct md_constant { char *value; }; +/* A callback that handles a single .md-file directive, up to but not + including the closing ')'. It takes two arguments: the line number on + which the directive started, and the name of the directive. The next + unread character is the optional space after the directive name. */ +typedef void (*directive_handler_t) (int, const char *); + +extern const char *in_fname; extern FILE *read_md_file; extern int read_md_lineno; extern const char *read_md_filename; extern struct obstack string_obstack; +extern void (*include_callback) (const char *); /* Read the next character from the MD file. */ @@ -86,6 +94,6 @@ extern char *read_quoted_string (void); extern char *read_string (int); extern int n_comma_elts (const char *); extern const char *scan_comma_elt (const char **); -extern void read_constants (void); extern void traverse_md_constants (htab_trav, void *); -extern void init_md_reader (void); +extern bool read_md_files (int, char **, bool (*) (const char *), + directive_handler_t); diff --git a/gcc/read-rtl.c b/gcc/read-rtl.c index a3a9b61753c..d49cbdabf7a 100644 --- a/gcc/read-rtl.c +++ b/gcc/read-rtl.c @@ -117,7 +117,8 @@ static void validate_const_int (const char *); static int find_iterator (struct iterator_group *, const char *); static struct mapping *read_mapping (struct iterator_group *, htab_t); static void check_code_iterator (struct mapping *); -static rtx read_rtx_1 (struct map_value **); +static rtx read_rtx_code (const char *, struct map_value **); +static rtx read_nested_rtx (struct map_value **); static rtx read_rtx_variadic (struct map_value **, rtx); /* The mode and code iterator structures. */ @@ -691,9 +692,6 @@ read_conditions (void) add_c_test (expr, value); } - c = read_skip_spaces (); - if (c != ')') - fatal_expected_char (')', c); } static void @@ -785,10 +783,6 @@ read_mapping (struct iterator_group *group, htab_t table) } while (c != ']'); - c = read_skip_spaces (); - if (c != ')') - fatal_expected_char (')', c); - return m; } @@ -812,74 +806,76 @@ check_code_iterator (struct mapping *iterator) bellwether_codes[iterator->index] = bellwether; } -/* Read an rtx in printed representation from the MD file and store - its core representation in *X. Also store the line number of the - opening '(' in *LINENO. Return true on success or false if the - end of file has been reached. - - read_rtx is not used in the compiler proper, but rather in - the utilities gen*.c that construct C code from machine descriptions. */ +/* Read an rtx-related declaration from the MD file, given that it + starts with directive name RTX_NAME. Return true if it expands to + one or more rtxes (as defined by rtx.def). When returning true, + store the list of rtxes as an EXPR_LIST in *X. */ bool -read_rtx (rtx *x, int *lineno) +read_rtx (const char *rtx_name, rtx *x) { - static rtx queue_head, queue_next; - static int queue_lineno; - int c; + static rtx queue_head; + struct map_value *mode_maps; + struct iterator_traverse_data mtd; /* Do one-time initialization. */ if (queue_head == 0) { - init_md_reader (); initialize_iterators (); queue_head = rtx_alloc (EXPR_LIST); } - if (queue_next == 0) + /* Handle various rtx-related declarations that aren't themselves + encoded as rtxes. */ + if (strcmp (rtx_name, "define_conditions") == 0) { - struct map_value *mode_maps; - struct iterator_traverse_data mtd; - rtx from_file; - - c = read_skip_spaces (); - if (c == EOF) - return false; - unread_char (c); - - queue_lineno = read_md_lineno; - mode_maps = 0; - from_file = read_rtx_1 (&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; - mtd.mode_maps = mode_maps; - mtd.unknown_mode_attr = mode_maps ? mode_maps->string : NULL; - htab_traverse (modes.iterators, apply_iterator_traverse, &mtd); - htab_traverse (codes.iterators, apply_iterator_traverse, &mtd); - if (mtd.unknown_mode_attr) - fatal_with_file_and_line ("undefined attribute '%s' used for mode", - mtd.unknown_mode_attr); + read_conditions (); + return false; } + if (strcmp (rtx_name, "define_mode_attr") == 0) + { + read_mapping (&modes, modes.attrs); + return false; + } + if (strcmp (rtx_name, "define_mode_iterator") == 0) + { + read_mapping (&modes, modes.iterators); + return false; + } + if (strcmp (rtx_name, "define_code_attr") == 0) + { + read_mapping (&codes, codes.attrs); + return false; + } + if (strcmp (rtx_name, "define_code_iterator") == 0) + { + check_code_iterator (read_mapping (&codes, codes.iterators)); + return false; + } + + mode_maps = 0; + XEXP (queue_head, 0) = read_rtx_code (rtx_name, &mode_maps); + XEXP (queue_head, 1) = 0; - *x = XEXP (queue_next, 0); - *lineno = queue_lineno; - queue_next = XEXP (queue_next, 1); + mtd.queue = queue_head; + mtd.mode_maps = mode_maps; + mtd.unknown_mode_attr = mode_maps ? mode_maps->string : NULL; + htab_traverse (modes.iterators, apply_iterator_traverse, &mtd); + htab_traverse (codes.iterators, apply_iterator_traverse, &mtd); + if (mtd.unknown_mode_attr) + fatal_with_file_and_line ("undefined attribute '%s' used for mode", + mtd.unknown_mode_attr); + *x = queue_head; return true; } -/* Subroutine of read_rtx that reads one construct from the MD file but - doesn't apply any iterators. */ +/* Subroutine of read_rtx and read_nested_rtx. CODE_NAME is the name of + either an rtx code or a code iterator. Parse the rest of the rtx and + return it. MODE_MAPS is as for iterator_traverse_data. */ static rtx -read_rtx_1 (struct map_value **mode_maps) +read_rtx_code (const char *code_name, struct map_value **mode_maps) { int i; RTX_CODE real_code, bellwether_code; @@ -897,55 +893,7 @@ read_rtx_1 (struct map_value **mode_maps) rtx value; /* Value of this node. */ }; - again: - c = read_skip_spaces (); /* Should be open paren. */ - - if (c == EOF) - return 0; - - if (c != '(') - fatal_expected_char ('(', c); - - read_name (&name); - if (strcmp (name.string, "nil") == 0) - { - /* (nil) stands for an expression that isn't there. */ - c = read_skip_spaces (); - if (c != ')') - fatal_expected_char (')', c); - return 0; - } - if (strcmp (name.string, "define_constants") == 0) - { - read_constants (); - goto again; - } - if (strcmp (name.string, "define_conditions") == 0) - { - read_conditions (); - goto again; - } - if (strcmp (name.string, "define_mode_attr") == 0) - { - read_mapping (&modes, modes.attrs); - goto again; - } - if (strcmp (name.string, "define_mode_iterator") == 0) - { - read_mapping (&modes, modes.iterators); - goto again; - } - if (strcmp (name.string, "define_code_attr") == 0) - { - read_mapping (&codes, codes.attrs); - goto again; - } - if (strcmp (name.string, "define_code_iterator") == 0) - { - check_code_iterator (read_mapping (&codes, codes.iterators)); - goto again; - } - real_code = (enum rtx_code) find_iterator (&codes, name.string); + real_code = (enum rtx_code) find_iterator (&codes, code_name); bellwether_code = BELLWETHER_CODE (real_code); /* If we end up with an insn expression then we free this space below. */ @@ -983,7 +931,7 @@ read_rtx_1 (struct map_value **mode_maps) case 'e': case 'u': - XEXP (return_rtx, i) = read_rtx_1 (mode_maps); + XEXP (return_rtx, i) = read_nested_rtx (mode_maps); break; case 'V': @@ -1017,7 +965,7 @@ read_rtx_1 (struct map_value **mode_maps) fatal_expected_char (']', c); unread_char (c); list_counter++; - obstack_ptr_grow (&vector_stack, read_rtx_1 (mode_maps)); + obstack_ptr_grow (&vector_stack, read_nested_rtx (mode_maps)); } if (list_counter > 0) { @@ -1122,16 +1070,40 @@ read_rtx_1 (struct map_value **mode_maps) } c = read_skip_spaces (); + /* Syntactic sugar for AND and IOR, allowing Lisp-like + arbitrary number of arguments for them. */ + if (c == '(' + && (GET_CODE (return_rtx) == AND + || GET_CODE (return_rtx) == IOR)) + return read_rtx_variadic (mode_maps, return_rtx); + + unread_char (c); + return return_rtx; +} + +/* Read a nested rtx construct from the MD file and return it. + MODE_MAPS is as for iterator_traverse_data. */ + +static rtx +read_nested_rtx (struct map_value **mode_maps) +{ + struct md_name name; + int c; + rtx return_rtx; + + c = read_skip_spaces (); + if (c != '(') + fatal_expected_char ('(', c); + + read_name (&name); + if (strcmp (name.string, "nil") == 0) + return_rtx = NULL; + else + return_rtx = read_rtx_code (name.string, mode_maps); + + c = read_skip_spaces (); if (c != ')') - { - /* Syntactic sugar for AND and IOR, allowing Lisp-like - arbitrary number of arguments for them. */ - if (c == '(' && (GET_CODE (return_rtx) == AND - || GET_CODE (return_rtx) == IOR)) - return read_rtx_variadic (mode_maps, return_rtx); - else - fatal_expected_char (')', c); - } + fatal_expected_char (')', c); return return_rtx; } @@ -1156,16 +1128,13 @@ read_rtx_variadic (struct map_value **mode_maps, rtx form) PUT_MODE (q, GET_MODE (p)); XEXP (q, 0) = XEXP (p, 1); - XEXP (q, 1) = read_rtx_1 (mode_maps); + XEXP (q, 1) = read_nested_rtx (mode_maps); XEXP (p, 1) = q; p = q; c = read_skip_spaces (); } while (c == '('); - - if (c != ')') - fatal_expected_char (')', c); - + unread_char (c); return form; } diff --git a/gcc/rtl.def b/gcc/rtl.def index c9ef1af001a..8464d32e7f9 100644 --- a/gcc/rtl.def +++ b/gcc/rtl.def @@ -715,9 +715,6 @@ DEF_RTL_EXPR(VAR_LOCATION, "var_location", "tei", RTX_EXTRA) descriptions. */ #ifdef GENERATOR_FILE -/* Include a secondary machine-description file at this point. */ -DEF_RTL_EXPR(INCLUDE, "include", "s", RTX_EXTRA) - /* Pattern-matching operators: */ /* Use the function named by the second arg (the string) diff --git a/gcc/rtl.h b/gcc/rtl.h index 5826496fd89..6be88d16ed3 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -2357,7 +2357,7 @@ extern void init_varasm_once (void); extern rtx make_debug_expr_from_rtl (const_rtx); /* In read-rtl.c */ -extern bool read_rtx (rtx *, int *); +extern bool read_rtx (const char *, rtx *); /* In alias.c */ extern rtx canon_rtx (rtx); |