diff options
-rw-r--r-- | gcc/doc/md.texi | 75 | ||||
-rw-r--r-- | gcc/genattr.c | 2 | ||||
-rw-r--r-- | gcc/genattrtab.c | 2 | ||||
-rw-r--r-- | gcc/gencodes.c | 2 | ||||
-rw-r--r-- | gcc/genconfig.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/genopinit.c | 2 | ||||
-rw-r--r-- | gcc/genoutput.c | 2 | ||||
-rw-r--r-- | gcc/genpeep.c | 2 | ||||
-rw-r--r-- | gcc/genrecog.c | 2 | ||||
-rw-r--r-- | gcc/gensupport.c | 243 | ||||
-rw-r--r-- | gcc/gensupport.h | 1 | ||||
-rw-r--r-- | gcc/rtl.def | 5 |
15 files changed, 334 insertions, 12 deletions
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi index 0d9bf91..f8ecb2a 100644 --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -38,6 +38,7 @@ See the next chapter for information on the C header file. * Expander Definitions::Generating a sequence of several RTL insns for a standard operation. * Insn Splitting:: Splitting Instructions into Multiple Instructions. +* Including Patterns:: Including Patterns in Machine Descriptions. * Peephole Definitions::Defining machine-specific peephole optimizations. * Insn Attributes:: Specifying the value of attributes for generated insns. * Conditional Execution::Generating @code{define_insn} patterns for @@ -3910,6 +3911,80 @@ functionality as two separate @code{define_insn} and @code{define_split} patterns. It exists for compactness, and as a maintenance tool to prevent having to ensure the two patterns' templates match. +@node Including Patterns +@section Including Patterns in Machine Descriptions. +@cindex insn includes + +@findex include +The @code{include} pattern tells the compiler tools where to +look for patterns that are in files other than in the file +@file{.md}. This is used only at build time and there is no preprocessing allowed. + +It looks like: + +@smallexample + +(include + @var{pathname}) +@end smallexample + +For example: + +@smallexample + +(include "filestuff") + +@end smallexample + +Where @var{pathname} is a string that specifies the the location of the file, +specifies the include file to be in @file{gcc/config/target/filestuff}. The +directory @file{gcc/config/target} is regarded as the default directory. + + +Machine descriptions may be split up into smaller more manageable subsections +and placed into subdirectories. + +By specifying: + +@smallexample + +(include "BOGUS/filestuff") + +@end smallexample + +the include file is specified to be in @file{gcc/config/@var{target}/BOGUS/filestuff}. + +Specifying an absolute path for the include file such as; +@smallexample + +(include "/u2/BOGUS/filestuff") + +@end smallexample +is permitted but is not encouraged. + +@subsection RTL Generation Tool Options for Directory Search +@cindex directory options .md +@cindex options, directory search +@cindex search options + +The @option{-I@var{dir}} option specifies directories to search for machine descriptions. +For example: + +@smallexample + +genrecog -I/p1/abc/proc1 -I/p2/abcd/pro2 target.md + +@end smallexample + + +Add the directory @var{dir} to the head of the list of directories to be +searched for header files. This can be used to override a system machine definition +file, substituting your own version, since these directories are +searched before the default machine description file directories. If you use more than +one @option{-I} option, the directories are scanned in left-to-right +order; the standard default directory come after. + + @node Peephole Definitions @section Machine-Specific Peephole Optimizers @cindex peephole optimizer definitions diff --git a/gcc/genattr.c b/gcc/genattr.c index be86ca6..4f9c712 100644 --- a/gcc/genattr.c +++ b/gcc/genattr.c @@ -210,7 +210,7 @@ main (argc, argv) if (argc <= 1) fatal ("No input file name."); - if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE) + if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE) return (FATAL_EXIT_CODE); puts ("/* Generated automatically by the program `genattr'"); diff --git a/gcc/genattrtab.c b/gcc/genattrtab.c index e3748a2..8b65fc8 100644 --- a/gcc/genattrtab.c +++ b/gcc/genattrtab.c @@ -6075,7 +6075,7 @@ main (argc, argv) if (argc <= 1) fatal ("No input file name."); - if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE) + if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE) return (FATAL_EXIT_CODE); obstack_init (hash_obstack); diff --git a/gcc/gencodes.c b/gcc/gencodes.c index 735570a..89d4b75 100644 --- a/gcc/gencodes.c +++ b/gcc/gencodes.c @@ -56,7 +56,7 @@ main (argc, argv) if (argc <= 1) fatal ("No input file name."); - if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE) + if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE) return (FATAL_EXIT_CODE); puts ("\ diff --git a/gcc/genconfig.c b/gcc/genconfig.c index 27000be..01107ff 100644 --- a/gcc/genconfig.c +++ b/gcc/genconfig.c @@ -277,7 +277,7 @@ main (argc, argv) if (argc <= 1) fatal ("No input file name."); - if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE) + if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE) return (FATAL_EXIT_CODE); puts ("/* Generated automatically by the program `genconfig'"); diff --git a/gcc/genemit.c b/gcc/genemit.c index 34d6711..7510719 100644 --- a/gcc/genemit.c +++ b/gcc/genemit.c @@ -789,7 +789,7 @@ main (argc, argv) if (argc <= 1) fatal ("No input file name."); - if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE) + if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE) 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 80602d7..7c11136 100644 --- a/gcc/genextract.c +++ b/gcc/genextract.c @@ -362,7 +362,7 @@ main (argc, argv) if (argc <= 1) fatal ("No input file name."); - if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE) + if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE) return (FATAL_EXIT_CODE); /* Assign sequential codes to all entries in the machine description diff --git a/gcc/genflags.c b/gcc/genflags.c index cd30af1..4bf0511 100644 --- a/gcc/genflags.c +++ b/gcc/genflags.c @@ -230,7 +230,7 @@ main (argc, argv) if (argc <= 1) fatal ("No input file name."); - if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE) + if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE) return (FATAL_EXIT_CODE); puts ("/* Generated automatically by the program `genflags'"); diff --git a/gcc/genopinit.c b/gcc/genopinit.c index 3907b20..85fa643 100644 --- a/gcc/genopinit.c +++ b/gcc/genopinit.c @@ -316,7 +316,7 @@ main (argc, argv) if (argc <= 1) fatal ("No input file name."); - if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE) + if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE) return (FATAL_EXIT_CODE); printf ("/* Generated automatically by the program `genopinit'\n\ diff --git a/gcc/genoutput.c b/gcc/genoutput.c index 00b2903..73911ae 100644 --- a/gcc/genoutput.c +++ b/gcc/genoutput.c @@ -953,7 +953,7 @@ main (argc, argv) if (argc <= 1) fatal ("No input file name."); - if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE) + if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE) return (FATAL_EXIT_CODE); output_prologue (); diff --git a/gcc/genpeep.c b/gcc/genpeep.c index 4f0861f..05c156a 100644 --- a/gcc/genpeep.c +++ b/gcc/genpeep.c @@ -385,7 +385,7 @@ main (argc, argv) if (argc <= 1) fatal ("No input file name."); - if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE) + if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE) return (FATAL_EXIT_CODE); printf ("/* Generated automatically by the program `genpeep'\n\ diff --git a/gcc/genrecog.c b/gcc/genrecog.c index f2e6b28..0e7356b 100644 --- a/gcc/genrecog.c +++ b/gcc/genrecog.c @@ -2689,7 +2689,7 @@ main (argc, argv) if (argc <= 1) fatal ("No input file name."); - if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE) + if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE) return (FATAL_EXIT_CODE); next_insn_code = 0; diff --git a/gcc/gensupport.c b/gcc/gensupport.c index 83be3c7..3660378 100644 --- a/gcc/gensupport.c +++ b/gcc/gensupport.c @@ -42,6 +42,8 @@ static int predicable_default; static const char *predicable_true; static const char *predicable_false; +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. */ @@ -62,6 +64,23 @@ static struct queue_elem *other_queue; static struct queue_elem **other_tail = &other_queue; static void queue_pattern PARAMS ((rtx, struct queue_elem ***, 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 *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_include = 0; /* Last in chain */ + static void remove_constraints PARAMS ((rtx)); static void process_rtx PARAMS ((rtx, int)); @@ -78,6 +97,9 @@ static const char *alter_output_for_insn PARAMS ((struct queue_elem *, int, int)); static void process_one_cond_exec PARAMS ((struct queue_elem *)); static void process_define_cond_exec PARAMS ((void)); +static int process_include PARAMS ((rtx, int)); +static char *save_string PARAMS ((const char *, int)); +static int init_include_reader PARAMS ((FILE *)); void message_with_line VPARAMS ((int lineno, const char *msg, ...)) @@ -157,6 +179,142 @@ remove_constraints (part) } } +/* The entry point for initializing the reader. */ + +static int +init_include_reader (inf) + FILE *inf; +{ + int c; + + errors = 0; + + /* Read the entire file. */ + while (1) + { + rtx desc; + int lineno; + + c = read_skip_spaces (inf); + if (c == EOF) + break; + + ungetc (c, inf); + lineno = read_rtx_lineno; + desc = read_rtx (inf); + process_rtx (desc, lineno); + } + fclose (inf); + + /* Process define_cond_exec patterns. */ + if (define_cond_exec_queue != NULL) + process_define_cond_exec (); + + return errors ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE; +} + +/* Process an include file assuming that it lives in gcc/config/{target}/ + if the include looks line (include "file" ) */ +static int +process_include (desc, lineno) + rtx desc; + int lineno; +{ + const char *filename = XSTR (desc, 0); + char *pathname = NULL; + FILE *input_file; + char *fname; + struct file_name_list *stackp; + int flen; + + stackp = include; + + /* If specified file name is absolute, just open it. */ + if (IS_ABSOLUTE_PATHNAME (filename) || !stackp) + { + if (base_dir) + { + pathname = xmalloc (strlen (base_dir) + strlen (filename) + 1); + pathname = strcpy (pathname, base_dir); + strcat (pathname, filename); + strcat (pathname, "\0"); + } + else + { + pathname = xstrdup (filename); + } + read_rtx_filename = pathname; + input_file = fopen (pathname, "r"); + + if (input_file == 0) + { + perror (pathname); + return FATAL_EXIT_CODE; + } + } + else if (stackp) + { + + flen = strlen (filename); + + fname = (char *) alloca (max_include_len + flen + 2); + + /* + 2 above for slash and terminating null. */ + + /* Search directory path, trying to open the file. + Copy each filename tried into FNAME. */ + + for (; stackp; stackp = stackp->next) + { + if (stackp->fname) + { + strcpy (fname, stackp->fname); + strcat (fname, "/"); + fname[strlen (fname) + flen] = 0; + } + else + { + fname[0] = 0; + } + strncat (fname, (const char *) filename, flen); + read_rtx_filename = fname; + input_file = fopen (fname, "r"); + if (input_file != NULL) + break; + } + if (stackp == NULL) + { + if (strchr (fname, '/') == NULL || strchr (fname, '\\' ) || base_dir) + { + if (base_dir) + { + pathname = + xmalloc (strlen (base_dir) + strlen (filename) + 1); + pathname = strcpy (pathname, base_dir); + strcat (pathname, filename); + strcat (pathname, "\0"); + } + else + pathname = xstrdup (filename); + } + read_rtx_filename = pathname; + input_file = fopen (pathname, "r"); + + if (input_file == 0) + { + perror (filename); + return FATAL_EXIT_CODE; + } + } + + } + + if (init_include_reader (input_file) == FATAL_EXIT_CODE) + message_with_line (lineno, "read errors found in include file %s\n", pathname); + + return SUCCESS_EXIT_CODE; +} + /* Process a top level rtx in some way, queueing as appropriate. */ static void @@ -164,6 +322,8 @@ process_rtx (desc, lineno) rtx desc; int lineno; { + const char *filename = XSTR (desc, 0); + switch (GET_CODE (desc)) { case DEFINE_INSN: @@ -178,6 +338,11 @@ process_rtx (desc, lineno) queue_pattern (desc, &define_attr_tail, lineno); break; + case INCLUDE: + if (process_include (desc, lineno) == FATAL_EXIT_CODE) + message_with_line (lineno, "include file at %s not found\n", filename); + break; + case DEFINE_INSN_AND_SPLIT: { const char *split_cond; @@ -767,6 +932,74 @@ process_define_cond_exec () for (elem = define_cond_exec_queue; elem ; elem = elem->next) process_one_cond_exec (elem); } + +static char * +save_string (s, len) + const char *s; + int len; +{ + register char *result = xmalloc (len + 1); + + memcpy (result, s, len); + result[len] = 0; + return result; +} + + +/* The entry point for initializing the reader. */ + +int +init_md_reader_args (argc, argv) + int argc; + char **argv; +{ + int i; + const char *in_fname; + + max_include_len = 0; + in_fname = NULL; + for (i = 1; i < argc; i++) + { + if (argv[i][0] != '-') + { + if (in_fname == NULL) + 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 = (struct file_name_list *) + xmalloc (sizeof (struct file_name_list)); + dirtmp->next = 0; /* New one goes on the end */ + if (include == 0) + include = dirtmp; + else + last_include->next = dirtmp; + last_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: + fatal ("Invalid option `%s'", argv[i]); + + } + } + } + return init_md_reader (in_fname); +} /* The entry point for initializing the reader. */ @@ -776,6 +1009,14 @@ init_md_reader (filename) { FILE *input_file; int c; + char *lastsl; + + if (!IS_ABSOLUTE_PATHNAME (filename)) + { + lastsl = strrchr (filename, '/'); + if (lastsl != NULL) + base_dir = save_string (filename, lastsl - filename + 1 ); + } read_rtx_filename = filename; input_file = fopen (filename, "r"); @@ -797,7 +1038,7 @@ init_md_reader (filename) c = read_skip_spaces (input_file); if (c == EOF) - break; + break; ungetc (c, input_file); lineno = read_rtx_lineno; diff --git a/gcc/gensupport.h b/gcc/gensupport.h index 13a9253..96c8c87 100644 --- a/gcc/gensupport.h +++ b/gcc/gensupport.h @@ -21,6 +21,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA struct obstack; extern struct obstack *rtl_obstack; +extern int init_md_reader_args PARAMS ((int, char **)); extern int init_md_reader PARAMS ((const char *)); extern rtx read_md_rtx PARAMS ((int *, int *)); diff --git a/gcc/rtl.def b/gcc/rtl.def index d85fb14..6c887bc 100644 --- a/gcc/rtl.def +++ b/gcc/rtl.def @@ -73,6 +73,11 @@ DEF_RTL_EXPR(UNKNOWN, "UnKnown", "*", 'x') DEF_RTL_EXPR(NIL, "nil", "*", 'x') + +/* include a file */ + +DEF_RTL_EXPR(INCLUDE, "include", "s", 'x') + /* --------------------------------------------------------------------- Expressions used in constructing lists. --------------------------------------------------------------------- */ |