rtl.def (INCLUDE): Define.
2001-11-05 Alan Matsuoka <alanm@redhat.com> * rtl.def (INCLUDE) : Define. * gensupport.c (init_include_reader, process_include, save_string) : New functions to implement an include facility in .md files. * gensupport.h : Add prototype for init_md_reader_args. * genattr.c genattrtab.c gencodes.c genconfig.c genemit.c genextract.c genflags.c genopinit.c genoutput.c genpeep.c genrecog.c: Change call to init_md_reader to init_md_reader_args. * md.texi: Document (include "path") and -I directives for RTL generation tools. From-SVN: r47020
This commit is contained in:
parent
497786446b
commit
04d8aa70d5
15 changed files with 334 additions and 12 deletions
|
@ -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
|
||||
|
|
|
@ -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'");
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 ("\
|
||||
|
|
|
@ -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'");
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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'");
|
||||
|
|
|
@ -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\
|
||||
|
|
|
@ -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 ();
|
||||
|
|
|
@ -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\
|
||||
|
|
|
@ -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;
|
||||
|
|
243
gcc/gensupport.c
243
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;
|
||||
|
|
|
@ -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 *));
|
||||
|
||||
|
|
|
@ -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.
|
||||
--------------------------------------------------------------------- */
|
||||
|
|
Loading…
Add table
Reference in a new issue