Makefile.in (build/genmddeps.o): Depend on $(READ_MD_H).
gcc/ * 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. From-SVN: r160577
This commit is contained in:
parent
7f7c467fed
commit
600ab3fcfa
|
@ -1,3 +1,72 @@
|
|||
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'.
|
||||
|
|
|
@ -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) \
|
||||
|
|
|
@ -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'");
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 ("\
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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'");
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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'");
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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\
|
||||
|
|
|
@ -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 ();
|
||||
|
|
|
@ -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\
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
264
gcc/gensupport.c
264
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. */
|
||||
|
|
|
@ -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 */
|
||||
|
|
291
gcc/read-md.c
291
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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
211
gcc/read-rtl.c
211
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;
|
||||
}
|
||||
|
||||
*x = XEXP (queue_next, 0);
|
||||
*lineno = queue_lineno;
|
||||
queue_next = XEXP (queue_next, 1);
|
||||
mode_maps = 0;
|
||||
XEXP (queue_head, 0) = read_rtx_code (rtx_name, &mode_maps);
|
||||
XEXP (queue_head, 1) = 0;
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -1121,17 +1069,41 @@ read_rtx_1 (struct map_value **mode_maps)
|
|||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue