diff options
author | Clinton Popetz <cpopetz@cygnus.com> | 2000-05-03 17:45:26 +0000 |
---|---|---|
committer | Clinton Popetz <cpopetz@gcc.gnu.org> | 2000-05-03 13:45:26 -0400 |
commit | c88c0d42a1ac718915fcd7c79ebe517baa624348 (patch) | |
tree | 51d16ed3ff5a009c7dd29449525fd4e9a6dc37c1 /gcc | |
parent | 18ca529b1976bfdc7f84b96f93d0ac3f483bf7f8 (diff) | |
download | gcc-c88c0d42a1ac718915fcd7c79ebe517baa624348.zip gcc-c88c0d42a1ac718915fcd7c79ebe517baa624348.tar.gz gcc-c88c0d42a1ac718915fcd7c79ebe517baa624348.tar.bz2 |
gensupport.c: New file.
* gensupport.c: New file.
* gensupport.h: New file.
* Makefile.in (HOST_RTL): Depend on gensupport.
(gensupport.o) New rule.
* genattr.c: Use gensupport for reading .md files.
* genattrtab.c: Ditto.
* gencodes.c: Ditto.
* genconfig.c: Ditto.
* genemit.c: Ditto.
* genextract.c: Ditto.
* genflags.c: Ditto.
* genopinit.c: Ditto.
* genoutput.c: Ditto.
* genpeep.c: Ditto.
* genrecog.c: Ditto.
* rtl.def (define_insn_and_split): New DEF_RTL_EXPR.
* md.texi (Insn Splitting): Document define_insn_and_split.
From-SVN: r33633
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 20 | ||||
-rw-r--r-- | gcc/Makefile.in | 5 | ||||
-rw-r--r-- | gcc/genattr.c | 20 | ||||
-rw-r--r-- | gcc/genattrtab.c | 86 | ||||
-rw-r--r-- | gcc/gencodes.c | 31 | ||||
-rw-r--r-- | gcc/genconfig.c | 61 | ||||
-rw-r--r-- | gcc/genemit.c | 64 | ||||
-rw-r--r-- | gcc/genextract.c | 30 | ||||
-rw-r--r-- | gcc/genflags.c | 23 | ||||
-rw-r--r-- | gcc/genopinit.c | 20 | ||||
-rw-r--r-- | gcc/genoutput.c | 28 | ||||
-rw-r--r-- | gcc/genpeep.c | 22 | ||||
-rw-r--r-- | gcc/genrecog.c | 21 | ||||
-rw-r--r-- | gcc/gensupport.c | 191 | ||||
-rw-r--r-- | gcc/gensupport.h | 24 | ||||
-rw-r--r-- | gcc/md.texi | 50 | ||||
-rw-r--r-- | gcc/rtl.def | 27 |
17 files changed, 477 insertions, 246 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 267ce89..2241bad 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,23 @@ +Wed May 3 12:40:53 2000 Clinton Popetz <cpopetz@cygnus.com> + + * gensupport.c: New file. + * gensupport.h: New file. + * Makefile.in (HOST_RTL): Depend on gensupport. + (gensupport.o) New rule. + * genattr.c: Use gensupport for reading .md files. + * genattrtab.c: Ditto. + * gencodes.c: Ditto. + * genconfig.c: Ditto. + * genemit.c: Ditto. + * genextract.c: Ditto. + * genflags.c: Ditto. + * genopinit.c: Ditto. + * genoutput.c: Ditto. + * genpeep.c: Ditto. + * genrecog.c: Ditto. + * rtl.def (define_insn_and_split): New DEF_RTL_EXPR. + * md.texi (Insn Splitting): Document define_insn_and_split. + Tue May 2 00:20:30 2000 Jason Eckhardt <jle@cygnus.com> * flow.c (verify_flow_info): Added two more sanity checks. The diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 197cc7f..5bd8cc9 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -586,7 +586,9 @@ HOST_LIBS = $(USE_HOST_OBSTACK) $(USE_HOST_ALLOCA) $(USE_HOST_MALLOC) \ $(HOST_INTLLIBS) $(USE_HOST_VFPRINTF) $(USE_HOST_DOPRINT) \ $(HOST_CLIB) -HOST_RTL = $(HOST_PREFIX)rtl.o $(HOST_PREFIX)bitmap.o $(HOST_PREFIX)ggc-none.o +HOST_RTL = $(HOST_PREFIX)rtl.o $(HOST_PREFIX)bitmap.o \ + $(HOST_PREFIX)ggc-none.o $(HOST_PREFIX)gensupport.o + HOST_PRINT = $(HOST_PREFIX)print-rtl.o HOST_ERRORS = $(HOST_PREFIX)errors.o @@ -1514,6 +1516,7 @@ toplev.o : toplev.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) function.h \ -c `echo $(srcdir)/toplev.c | sed 's,^\./,,'` rtl.o : rtl.c $(CONFIG_H) system.h $(RTL_H) bitmap.h $(GGC_H) toplev.h +gensupport.o : gensupport.c $(CONFIG_H) system.h $(RTL_H) print-rtl.o : print-rtl.c $(CONFIG_H) system.h $(RTL_H) $(BASIC_BLOCK_H) rtlanal.o : rtlanal.c $(CONFIG_H) system.h $(RTL_H) diff --git a/gcc/genattr.c b/gcc/genattr.c index 30160a4..36a37b1 100644 --- a/gcc/genattr.c +++ b/gcc/genattr.c @@ -25,6 +25,7 @@ Boston, MA 02111-1307, USA. */ #include "rtl.h" #include "obstack.h" #include "errors.h" +#include "gensupport.h" static struct obstack obstack; struct obstack *rtl_obstack = &obstack; @@ -222,8 +223,6 @@ main (argc, argv) char **argv; { rtx desc; - FILE *infile; - register int c; int have_delay = 0; int have_annul_true = 0; int have_annul_false = 0; @@ -245,13 +244,8 @@ main (argc, argv) if (argc <= 1) fatal ("No input file name."); - infile = fopen (argv[1], "r"); - if (infile == 0) - { - perror (argv[1]); - return (FATAL_EXIT_CODE); - } - read_rtx_filename = argv[1]; + if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE) + return (FATAL_EXIT_CODE); printf ("/* Generated automatically by the program `genattr'\n\ from the machine description file `md'. */\n\n"); @@ -266,12 +260,12 @@ from the machine description file `md'. */\n\n"); while (1) { - c = read_skip_spaces (infile); - if (c == EOF) + int line_no, insn_code_number; + + desc = read_md_rtx (&line_no, &insn_code_number); + if (desc == NULL) break; - ungetc (c, infile); - desc = read_rtx (infile); if (GET_CODE (desc) == DEFINE_ATTR) gen_attr (desc); diff --git a/gcc/genattrtab.c b/gcc/genattrtab.c index 2dab1b6..b1be9a0 100644 --- a/gcc/genattrtab.c +++ b/gcc/genattrtab.c @@ -100,6 +100,7 @@ Boston, MA 02111-1307, USA. */ #include "system.h" #include "rtl.h" #include "ggc.h" +#include "gensupport.h" #ifdef HAVE_SYS_RESOURCE_H # include <sys/resource.h> @@ -4304,8 +4305,8 @@ gen_insn (exp) switch (GET_CODE (exp)) { case DEFINE_INSN: - id->insn_code = insn_code_number++; - id->insn_index = insn_index_number++; + id->insn_code = insn_code_number; + id->insn_index = insn_index_number; id->num_alternatives = count_alternatives (exp); if (id->num_alternatives == 0) id->num_alternatives = 1; @@ -4313,8 +4314,8 @@ gen_insn (exp) break; case DEFINE_PEEPHOLE: - id->insn_code = insn_code_number++; - id->insn_index = insn_index_number++; + id->insn_code = insn_code_number; + id->insn_index = insn_index_number; id->num_alternatives = count_alternatives (exp); if (id->num_alternatives == 0) id->num_alternatives = 1; @@ -5967,8 +5968,6 @@ main (argc, argv) char **argv; { rtx desc; - FILE *infile; - register int c; struct attr_desc *attr; struct insn_def *id; rtx tem; @@ -5976,6 +5975,12 @@ main (argc, argv) progname = "genattrtab"; + if (argc <= 1) + fatal ("No input file name."); + + if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE) + return (FATAL_EXIT_CODE); + #if defined (RLIMIT_STACK) && defined (HAVE_GETRLIMIT) && defined (HAVE_SETRLIMIT) /* Get rid of any avoidable limit on stack size. */ { @@ -5993,17 +5998,6 @@ main (argc, argv) obstack_init (hash_obstack); obstack_init (temp_obstack); - if (argc <= 1) - fatal ("No input file name."); - - infile = fopen (argv[1], "r"); - if (infile == 0) - { - perror (argv[1]); - return (FATAL_EXIT_CODE); - } - read_rtx_filename = argv[1]; - /* Set up true and false rtx's */ true_rtx = rtx_alloc (CONST_INT); XWINT (true_rtx, 0) = 1; @@ -6021,45 +6015,41 @@ from the machine description file `md'. */\n\n"); while (1) { - c = read_skip_spaces (infile); - if (c == EOF) - break; - ungetc (c, infile); - - desc = read_rtx (infile); - if (GET_CODE (desc) == DEFINE_INSN - || GET_CODE (desc) == DEFINE_PEEPHOLE - || GET_CODE (desc) == DEFINE_ASM_ATTRIBUTES) - gen_insn (desc); - - else if (GET_CODE (desc) == DEFINE_EXPAND) - insn_code_number++, insn_index_number++; + int line_no; - else if (GET_CODE (desc) == DEFINE_SPLIT) - insn_code_number++, insn_index_number++; - - else if (GET_CODE (desc) == DEFINE_PEEPHOLE2) - insn_code_number++, insn_index_number++; + desc = read_md_rtx (&line_no, &insn_code_number); + if (desc == NULL) + break; - else if (GET_CODE (desc) == DEFINE_ATTR) + switch (GET_CODE (desc)) { - gen_attr (desc); - insn_index_number++; - } + case DEFINE_INSN: + case DEFINE_PEEPHOLE: + case DEFINE_ASM_ATTRIBUTES: + gen_insn(desc); + break; + + case DEFINE_ATTR: + gen_attr (desc); + break; - else if (GET_CODE (desc) == DEFINE_DELAY) - { - gen_delay (desc); - insn_index_number++; - } + case DEFINE_DELAY: + gen_delay (desc); + break; - else if (GET_CODE (desc) == DEFINE_FUNCTION_UNIT) - { - gen_unit (desc); - insn_index_number++; + case DEFINE_FUNCTION_UNIT: + gen_unit (desc); + break; + + default: + break; } + if (GET_CODE (desc) != DEFINE_ASM_ATTRIBUTES) + insn_index_number++; } + insn_code_number++; + /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */ if (! got_define_asm_attributes) { diff --git a/gcc/gencodes.c b/gcc/gencodes.c index 39db391..750839b 100644 --- a/gcc/gencodes.c +++ b/gcc/gencodes.c @@ -27,6 +27,7 @@ Boston, MA 02111-1307, USA. */ #include "rtl.h" #include "obstack.h" #include "errors.h" +#include "gensupport.h" static struct obstack obstack; struct obstack *rtl_obstack = &obstack; @@ -84,8 +85,6 @@ main (argc, argv) char **argv; { rtx desc; - FILE *infile; - register int c; progname = "gencodes"; obstack_init (rtl_obstack); @@ -93,13 +92,8 @@ main (argc, argv) if (argc <= 1) fatal ("No input file name."); - infile = fopen (argv[1], "r"); - if (infile == 0) - { - perror (argv[1]); - return (FATAL_EXIT_CODE); - } - read_rtx_filename = argv[1]; + if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE) + return (FATAL_EXIT_CODE); printf ("/* Generated automatically by the program `gencodes'\n\ from the machine description file `md'. */\n\n"); @@ -113,23 +107,14 @@ from the machine description file `md'. */\n\n"); while (1) { - c = read_skip_spaces (infile); - if (c == EOF) + int line_no; + + desc = read_md_rtx (&line_no, &insn_code_number); + if (desc == NULL) break; - ungetc (c, infile); - desc = read_rtx (infile); if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND) - { - gen_insn (desc); - insn_code_number++; - } - if (GET_CODE (desc) == DEFINE_PEEPHOLE - || GET_CODE (desc) == DEFINE_PEEPHOLE2 - || GET_CODE (desc) == DEFINE_SPLIT) - { - insn_code_number++; - } + gen_insn (desc); } printf (" CODE_FOR_nothing };\n"); diff --git a/gcc/genconfig.c b/gcc/genconfig.c index d78af03..0772162 100644 --- a/gcc/genconfig.c +++ b/gcc/genconfig.c @@ -26,6 +26,7 @@ Boston, MA 02111-1307, USA. */ #include "rtl.h" #include "obstack.h" #include "errors.h" +#include "gensupport.h" static struct obstack obstack; struct obstack *rtl_obstack = &obstack; @@ -279,8 +280,6 @@ main (argc, argv) char **argv; { rtx desc; - FILE *infile; - register int c; progname = "genconfig"; obstack_init (rtl_obstack); @@ -288,13 +287,8 @@ main (argc, argv) if (argc <= 1) fatal ("No input file name."); - infile = fopen (argv[1], "r"); - if (infile == 0) - { - perror (argv[1]); - return (FATAL_EXIT_CODE); - } - read_rtx_filename = argv[1]; + if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE) + return (FATAL_EXIT_CODE); printf ("/* Generated automatically by the program `genconfig'\n\ from the machine description file `md'. */\n\n"); @@ -307,27 +301,38 @@ from the machine description file `md'. */\n\n"); while (1) { - c = read_skip_spaces (infile); - if (c == EOF) + int line_no, insn_code_number = 0; + + desc = read_md_rtx (&line_no, &insn_code_number); + if (desc == NULL) break; - ungetc (c, infile); - - desc = read_rtx (infile); - if (GET_CODE (desc) == DEFINE_INSN) - gen_insn (desc); - if (GET_CODE (desc) == DEFINE_EXPAND) - gen_expand (desc); - if (GET_CODE (desc) == DEFINE_SPLIT) - gen_split (desc); - if (GET_CODE (desc) == DEFINE_PEEPHOLE2) - { - have_peephole2_flag = 1; - gen_split (desc); - } - if (GET_CODE (desc) == DEFINE_PEEPHOLE) + + switch (GET_CODE (desc)) { - have_peephole_flag = 1; - gen_peephole (desc); + case DEFINE_INSN: + gen_insn (desc); + break; + + case DEFINE_EXPAND: + gen_expand (desc); + break; + + case DEFINE_SPLIT: + gen_split (desc); + break; + + case DEFINE_PEEPHOLE2: + have_peephole2_flag = 1; + gen_split (desc); + break; + + case DEFINE_PEEPHOLE: + have_peephole_flag = 1; + gen_peephole (desc); + break; + + default: + break; } } diff --git a/gcc/genemit.c b/gcc/genemit.c index f2bac16..6fc604d 100644 --- a/gcc/genemit.c +++ b/gcc/genemit.c @@ -25,6 +25,7 @@ Boston, MA 02111-1307, USA. */ #include "rtl.h" #include "obstack.h" #include "errors.h" +#include "gensupport.h" static struct obstack obstack; struct obstack *rtl_obstack = &obstack; @@ -779,8 +780,6 @@ main (argc, argv) char **argv; { rtx desc; - FILE *infile; - register int c; progname = "genemit"; obstack_init (rtl_obstack); @@ -788,13 +787,8 @@ main (argc, argv) if (argc <= 1) fatal ("No input file name."); - infile = fopen (argv[1], "r"); - if (infile == 0) - { - perror (argv[1]); - return (FATAL_EXIT_CODE); - } - read_rtx_filename = argv[1]; + if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE) + return (FATAL_EXIT_CODE); /* Assign sequential codes to all entries in the machine description in parallel with the tables in insn-output.c. */ @@ -828,37 +822,33 @@ from the machine description file `md'. */\n\n"); while (1) { - c = read_skip_spaces (infile); - if (c == EOF) - break; - ungetc (c, infile); + int line_no; - desc = read_rtx (infile); + desc = read_md_rtx (&line_no, &insn_code_number); + if (desc == NULL) + break; - if (GET_CODE (desc) == DEFINE_INSN) + switch (GET_CODE (desc)) { - gen_insn (desc); - ++insn_code_number; - } - if (GET_CODE (desc) == DEFINE_EXPAND) - { - gen_expand (desc); - ++insn_code_number; - } - if (GET_CODE (desc) == DEFINE_SPLIT) - { - gen_split (desc); - ++insn_code_number; - } - if (GET_CODE (desc) == DEFINE_PEEPHOLE2) - { - gen_split (desc); - ++insn_code_number; - } - if (GET_CODE (desc) == DEFINE_PEEPHOLE) - { - ++insn_code_number; - } + case DEFINE_INSN: + gen_insn (desc); + break; + + case DEFINE_EXPAND: + gen_expand (desc); + break; + + case DEFINE_SPLIT: + gen_split (desc); + break; + + case DEFINE_PEEPHOLE2: + gen_split (desc); + break; + + default: + break; + } ++insn_index_number; } diff --git a/gcc/genextract.c b/gcc/genextract.c index 9e291c9..fea0492 100644 --- a/gcc/genextract.c +++ b/gcc/genextract.c @@ -26,6 +26,7 @@ Boston, MA 02111-1307, USA. */ #include "obstack.h" #include "errors.h" #include "insn-config.h" +#include "gensupport.h" static struct obstack obstack; struct obstack *rtl_obstack = &obstack; @@ -389,8 +390,7 @@ main (argc, argv) char **argv; { rtx desc; - FILE *infile; - int c, i; + int i; struct extraction *p; struct code_ptr *link; const char *name; @@ -401,13 +401,8 @@ main (argc, argv) if (argc <= 1) fatal ("No input file name."); - infile = fopen (argv[1], "r"); - if (infile == 0) - { - perror (argv[1]); - return (FATAL_EXIT_CODE); - } - read_rtx_filename = argv[1]; + if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE) + return (FATAL_EXIT_CODE); /* Assign sequential codes to all entries in the machine description in parallel with the tables in insn-output.c. */ @@ -446,17 +441,16 @@ from the machine description file `md'. */\n\n"); while (1) { - c = read_skip_spaces (infile); - if (c == EOF) + int line_no; + + desc = read_md_rtx (&line_no, &insn_code_number); + if (desc == NULL) break; - ungetc (c, infile); - desc = read_rtx (infile); - if (GET_CODE (desc) == DEFINE_INSN) + if (GET_CODE (desc) == DEFINE_INSN) { record_insn_name (insn_code_number, XSTR (desc, 0)); gen_insn (desc); - ++insn_code_number; } else if (GET_CODE (desc) == DEFINE_PEEPHOLE) @@ -467,13 +461,7 @@ from the machine description file `md'. */\n\n"); link->insn_code = insn_code_number; link->next = peepholes; peepholes = link; - ++insn_code_number; } - - else if (GET_CODE (desc) == DEFINE_EXPAND - || GET_CODE (desc) == DEFINE_PEEPHOLE2 - || GET_CODE (desc) == DEFINE_SPLIT) - ++insn_code_number; } /* Write out code to handle peepholes and the insn_codes that it should diff --git a/gcc/genflags.c b/gcc/genflags.c index 39b5354..f679dd2 100644 --- a/gcc/genflags.c +++ b/gcc/genflags.c @@ -27,6 +27,7 @@ Boston, MA 02111-1307, USA. */ #include "rtl.h" #include "obstack.h" #include "errors.h" +#include "gensupport.h" static struct obstack obstack; struct obstack *rtl_obstack = &obstack; @@ -227,8 +228,6 @@ main (argc, argv) rtx *call_insns; rtx *normal_insns; rtx *insn_ptr; - FILE *infile; - register int c; progname = "genflags"; obstack_init (rtl_obstack); @@ -238,14 +237,9 @@ main (argc, argv) if (argc <= 1) fatal ("No input file name."); - infile = fopen (argv[1], "r"); - if (infile == 0) - { - perror (argv[1]); - return (FATAL_EXIT_CODE); - } - read_rtx_filename = argv[1]; - + if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE) + return (FATAL_EXIT_CODE); + printf ("/* Generated automatically by the program `genflags'\n\ from the machine description file `md'. */\n\n"); @@ -253,12 +247,11 @@ from the machine description file `md'. */\n\n"); while (1) { - c = read_skip_spaces (infile); - if (c == EOF) - break; - ungetc (c, infile); + int line_no, insn_code_number = 0; - desc = read_rtx (infile); + desc = read_md_rtx (&line_no, &insn_code_number); + if (desc == NULL) + break; if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND) gen_insn (desc); } diff --git a/gcc/genopinit.c b/gcc/genopinit.c index ac5debb..2cd5d8e 100644 --- a/gcc/genopinit.c +++ b/gcc/genopinit.c @@ -25,6 +25,7 @@ Boston, MA 02111-1307, USA. */ #include "rtl.h" #include "obstack.h" #include "errors.h" +#include "gensupport.h" static struct obstack obstack; struct obstack *rtl_obstack = &obstack; @@ -313,8 +314,6 @@ main (argc, argv) char **argv; { rtx desc; - FILE *infile; - register int c; progname = "genopinit"; obstack_init (rtl_obstack); @@ -322,13 +321,8 @@ main (argc, argv) if (argc <= 1) fatal ("No input file name."); - infile = fopen (argv[1], "r"); - if (infile == 0) - { - perror (argv[1]); - return (FATAL_EXIT_CODE); - } - read_rtx_filename = argv[1]; + if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE) + return (FATAL_EXIT_CODE); printf ("/* Generated automatically by the program `genopinit'\n\ from the machine description file `md'. */\n\n"); @@ -350,12 +344,12 @@ from the machine description file `md'. */\n\n"); while (1) { - c = read_skip_spaces (infile); - if (c == EOF) + int line_no, insn_code_number = 0; + + desc = read_md_rtx (&line_no, &insn_code_number); + if (desc == NULL) break; - ungetc (c, infile); - desc = read_rtx (infile); if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND) gen_insn (desc); } diff --git a/gcc/genoutput.c b/gcc/genoutput.c index d581da2..922359db 100644 --- a/gcc/genoutput.c +++ b/gcc/genoutput.c @@ -90,6 +90,7 @@ Boston, MA 02111-1307, USA. */ #include "rtl.h" #include "obstack.h" #include "errors.h" +#include "gensupport.h" /* No instruction can have more operands than this. Sorry for this arbitrary limit, but what machine will have an instruction with @@ -720,7 +721,7 @@ gen_insn (insn) register struct data *d = (struct data *) xmalloc (sizeof (struct data)); register int i; - d->code_number = next_code_number++; + d->code_number = next_code_number; d->index_number = next_index_number; if (XSTR (insn, 0)[0]) d->name = XSTR (insn, 0); @@ -759,7 +760,7 @@ gen_peephole (peep) register struct data *d = (struct data *) xmalloc (sizeof (struct data)); register int i; - d->code_number = next_code_number++; + d->code_number = next_code_number; d->index_number = next_index_number; d->name = 0; @@ -797,7 +798,7 @@ gen_expand (insn) register struct data *d = (struct data *) xmalloc (sizeof (struct data)); register int i; - d->code_number = next_code_number++; + d->code_number = next_code_number; d->index_number = next_index_number; if (XSTR (insn, 0)[0]) d->name = XSTR (insn, 0); @@ -840,7 +841,7 @@ gen_split (split) register struct data *d = (struct data *) xmalloc (sizeof (struct data)); register int i; - d->code_number = next_code_number++; + d->code_number = next_code_number; d->index_number = next_index_number; d->name = 0; @@ -903,8 +904,6 @@ main (argc, argv) char **argv; { rtx desc; - FILE *infile; - register int c; progname = "genoutput"; obstack_init (rtl_obstack); @@ -912,13 +911,8 @@ main (argc, argv) if (argc <= 1) fatal ("No input file name."); - infile = fopen (argv[1], "r"); - if (infile == 0) - { - perror (argv[1]); - return (FATAL_EXIT_CODE); - } - read_rtx_filename = argv[1]; + if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE) + return (FATAL_EXIT_CODE); output_prologue (); next_code_number = 0; @@ -928,12 +922,12 @@ main (argc, argv) while (1) { - c = read_skip_spaces (infile); - if (c == EOF) + int line_no; + + desc = read_md_rtx (&line_no, &next_code_number); + if (desc == NULL) break; - ungetc (c, infile); - desc = read_rtx (infile); if (GET_CODE (desc) == DEFINE_INSN) gen_insn (desc); if (GET_CODE (desc) == DEFINE_PEEPHOLE) diff --git a/gcc/genpeep.c b/gcc/genpeep.c index fd1357d..b8ef9aa 100644 --- a/gcc/genpeep.c +++ b/gcc/genpeep.c @@ -25,6 +25,7 @@ Boston, MA 02111-1307, USA. */ #include "rtl.h" #include "obstack.h" #include "errors.h" +#include "gensupport.h" static struct obstack obstack; struct obstack *rtl_obstack = &obstack; @@ -408,8 +409,6 @@ main (argc, argv) char **argv; { rtx desc; - FILE *infile; - register int c; max_opno = -1; @@ -419,13 +418,8 @@ main (argc, argv) if (argc <= 1) fatal ("No input file name."); - infile = fopen (argv[1], "r"); - if (infile == 0) - { - perror (argv[1]); - return (FATAL_EXIT_CODE); - } - read_rtx_filename = argv[1]; + if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE) + return (FATAL_EXIT_CODE); printf ("/* Generated automatically by the program `genpeep'\n\ from the machine description file `md'. */\n\n"); @@ -458,13 +452,13 @@ from the machine description file `md'. */\n\n"); while (1) { - c = read_skip_spaces (infile); - if (c == EOF) + int line_no, rtx_number = 0; + + desc = read_md_rtx (&line_no, &rtx_number); + if (desc == NULL) break; - ungetc (c, infile); - desc = read_rtx (infile); - if (GET_CODE (desc) == DEFINE_PEEPHOLE) + if (GET_CODE (desc) == DEFINE_PEEPHOLE) { gen_peephole (desc); insn_code_number++; diff --git a/gcc/genrecog.c b/gcc/genrecog.c index 3acf5b1..1f0c331 100644 --- a/gcc/genrecog.c +++ b/gcc/genrecog.c @@ -55,6 +55,7 @@ #include "rtl.h" #include "obstack.h" #include "errors.h" +#include "gensupport.h" #define OUTPUT_LABEL(INDENT_STRING, LABEL_NUMBER) \ printf("%sL%d: ATTRIBUTE_UNUSED_LABEL\n", (INDENT_STRING), (LABEL_NUMBER)) @@ -2461,7 +2462,6 @@ make_insn_sequence (insn, type) next_insn_code); break; } - next_insn_code++; return head; } @@ -2518,13 +2518,8 @@ main (argc, argv) if (argc <= 1) fatal ("No input file name."); - infile = fopen (argv[1], "r"); - if (infile == 0) - { - perror (argv[1]); - return FATAL_EXIT_CODE; - } - read_rtx_filename = argv[1]; + if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE) + return (FATAL_EXIT_CODE); next_insn_code = 0; next_index = 0; @@ -2535,13 +2530,10 @@ main (argc, argv) while (1) { - c = read_skip_spaces (infile); - if (c == EOF) + desc = read_md_rtx (&pattern_lineno, &next_insn_code); + if (desc == NULL) break; - ungetc (c, infile); - pattern_lineno = read_rtx_lineno; - desc = read_rtx (infile); if (GET_CODE (desc) == DEFINE_INSN) { h = make_insn_sequence (desc, RECOG); @@ -2558,9 +2550,6 @@ main (argc, argv) merge_trees (&peephole2_tree, &h); } - if (GET_CODE (desc) == DEFINE_PEEPHOLE - || GET_CODE (desc) == DEFINE_EXPAND) - next_insn_code++; next_index++; } diff --git a/gcc/gensupport.c b/gcc/gensupport.c new file mode 100644 index 0000000..aff9d84 --- /dev/null +++ b/gcc/gensupport.c @@ -0,0 +1,191 @@ +/* Read machine descriptions, return top level rtx for use by the + various generation passes. + + Copyright (C) 2000 Free Software Foundation, Inc. + + This file is part of GNU CC. + + GNU CC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU CC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU CC; see the file COPYING. If not, write to + the Free Software Foundation, 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "hconfig.h" +#include "system.h" +#include "rtl.h" +#include "errors.h" +#include "gensupport.h" + +static FILE *input_file; + +static int sequence_num; + +struct queue_elem { + rtx data; + struct queue_elem *next; +}; + +static struct queue_elem *rtx_ready_queue; + +/* Recursively remove constraints from an rtx. */ + +static void +remove_constraints (part) + rtx part; +{ + register int i, j; + register const char *format_ptr; + + if (part == 0) + return; + + if (GET_CODE (part) == MATCH_OPERAND) + XSTR (part, 2) = ""; + else if (GET_CODE (part) == MATCH_SCRATCH) + XSTR (part, 1) = ""; + + format_ptr = GET_RTX_FORMAT (GET_CODE (part)); + + for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++) + switch (*format_ptr++) + { + case 'e': + case 'u': + remove_constraints (XEXP (part, i)); + break; + case 'E': + if (XVEC (part, i) != NULL) + for (j = 0; j < XVECLEN (part, i); j++) + remove_constraints (XVECEXP (part, i, j)); + break; + } +} + +/* Handle any synthetic top level rtx, i.e. anything except: + DEFINE_INSN + DEFINE_EXPAND + DEFINE_SPLIT + DEFINE_PEEPHOLE + DEFINE_PEEPHOLE2 + DEFINE_ATTRIBUTE + DEFINE_FUNCTION_UNIT + DEFINE_ASM_ATTRIBUTES */ + +static void +process_rtx (desc) + rtx* desc; +{ + if (GET_CODE (*desc) == DEFINE_INSN_AND_SPLIT) + { + struct queue_elem* elem = xmalloc (sizeof (struct queue_elem)); + const char *split_cond; + + /* Create a split with values from the insn_and_split. */ + rtx split = rtx_alloc (DEFINE_SPLIT); + XVEC (split, 0) = copy_rtx (XVEC (*desc, 1)); + remove_constraints (XVEC (split, 0)); + split_cond = XSTR (split, 1) = XSTR (*desc, 4); + + /* If the split condition starts with "&&", append it to the + insn condition to create the new split condition. */ + if (split_cond[0] == '&' && split_cond[1] == '&') + { + const char *insn_cond = XSTR (*desc, 2); + char *combined = + xmalloc (strlen (insn_cond) + strlen (split_cond) + 1); + strcpy (combined, insn_cond); + strcat (combined, split_cond); + XSTR (split, 1) = combined; + } + + XVEC (split, 2) = XVEC (*desc, 5); + XSTR (split, 3) = XSTR (*desc, 6); + + /* Fix up the DEFINE_INSN. */ + PUT_CODE (*desc, DEFINE_INSN); + XVEC (*desc, 4) = XSTR (*desc, 7); + + /* Return the DEFINE_INSN part, and put the DEFINE_SPLIT + in the queue. */ + elem->next = rtx_ready_queue; + elem->data = split; + rtx_ready_queue = elem; + } +} + +/* The entry point for initializing the reader. */ + +int +init_md_reader (filename) + const char *filename; +{ + + input_file = fopen (filename, "r"); + + if (input_file == 0) + { + perror (filename); + return FATAL_EXIT_CODE; + } + + read_rtx_filename = filename; + sequence_num = 0; + rtx_ready_queue = NULL; + + return SUCCESS_EXIT_CODE; +} + + +/* The entry point for reading a single rtx from an md file. */ + +rtx +read_md_rtx (lineno, seqnr) + int *lineno; + int *seqnr; +{ + rtx desc; + + if (rtx_ready_queue != NULL) + { + desc = rtx_ready_queue->data; + rtx_ready_queue = rtx_ready_queue->next; + } + else + { + int c; + c = read_skip_spaces (input_file); + if (c == EOF) + return NULL; + + ungetc (c, input_file); + desc = read_rtx (input_file); + process_rtx (&desc); + } + *lineno = read_rtx_lineno; + *seqnr = sequence_num; + switch (GET_CODE (desc)) + { + case DEFINE_INSN: + case DEFINE_EXPAND: + case DEFINE_SPLIT: + case DEFINE_PEEPHOLE: + case DEFINE_PEEPHOLE2: + sequence_num++; + break; + + default: + break; + } + + return desc; +} diff --git a/gcc/gensupport.h b/gcc/gensupport.h new file mode 100644 index 0000000..3dbec6b --- /dev/null +++ b/gcc/gensupport.h @@ -0,0 +1,24 @@ +/* Declarations for rtx-reader support for gen* routines. + Copyright (C) 2000 Free Software Foundation, Inc. + +This file is part of GNU CC. + +GNU CC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU CC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU CC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +extern int init_md_reader PARAMS ((const char *)); +extern rtx read_md_rtx PARAMS ((int *, int *)); + + diff --git a/gcc/md.texi b/gcc/md.texi index 0b46d81..083a228 100644 --- a/gcc/md.texi +++ b/gcc/md.texi @@ -3431,6 +3431,56 @@ insns that don't. Instead, write two separate @code{define_split} definitions, one for the insns that are valid and one for the insns that are not valid. +For the common case where the pattern of a define_split exactly matches the +pattern of a define_insn, use @code{define_insn_and_split}. It looks like +this: + +@smallexample +(define_insn_and_split + [@var{insn-pattern}] + "@var{condition}" + "@var{output-template}" + "@var{split-condition}" + [@var{new-insn-pattern-1} + @var{new-insn-pattern-2} + @dots{}] + "@var{preparation statements}" + [@var{insn-attributes}]) + +@end smallexample + +@var{insn-pattern}, @var{condition}, @var{output-template}, and +@var{insn-attributes} are used as in @code{define_insn}. The +@var{new-insn-pattern} vector and the @var{preparation-statements} are used as +in a @code{define_split}. The @var{split-condition} is also used as in +@code{define_split}, with the additional behavior that if the condition starts +with @samp{&&}, the condition used for the split will be the constructed as a +logical "and" of the split condition with the insn condition. For example, +from i386.md: + +@smallexample +(define_insn_and_split "zero_extendhisi2_and" + [(set (match_operand:SI 0 "register_operand" "=r") + (zero_extend:SI (match_operand:HI 1 "register_operand" "0"))) + (clobber (reg:CC 17))] + "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size" + "#" + "&& reload_completed" + [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535))) + (clobber (reg:CC 17))])] + "" + [(set_attr "type" "alu1")]) + +@end smallexample + +In this case, the actual split condition will be +"TARGET_ZERO_EXTEND_WITH_AND && !optimize_size && reload_completed." + +The @code{define_insn_and_split} construction provides exactly the same +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 Peephole Definitions @section Machine-Specific Peephole Optimizers @cindex peephole optimizer definitions diff --git a/gcc/rtl.def b/gcc/rtl.def index 30c5518..29cb5ee 100644 --- a/gcc/rtl.def +++ b/gcc/rtl.def @@ -203,6 +203,33 @@ DEF_RTL_EXPR(DEFINE_PEEPHOLE, "define_peephole", "EssV", 'x') (`operands' is an alias here for `recog_operand'). */ DEF_RTL_EXPR(DEFINE_SPLIT, "define_split", "EsES", 'x') +/* Definition of an insn and associated split. + This is the concatenation, with a few modifications, of a define_insn + and a define_split which share the same pattern. + Operand: + 0: names this instruction. + If the name is the null string, the instruction is in the + machine description just to be recognized, and will never be emitted by + the tree to rtl expander. + 1: is the pattern. + 2: is a string which is a C expression + giving an additional condition for recognizing this pattern. + A null string means no extra condition. + 3: is the action to execute if this pattern is matched. + If this assembler code template starts with a * then it is a fragment of + C code to run to decide on a template to use. Otherwise, it is the + template to use. + 4: C expression that must be true for split. This may start with "&&" + in which case the split condition is the logical and of the insn + condition and what follows the "&&" of this operand. + 5: vector of insn patterns to place into a SEQUENCE + 6: optionally, some C code to execute before generating the + insns. This might, for example, create some RTX's and store them in + elements of `recog_operand' for use by the vector of insn-patterns. + (`operands' is an alias here for `recog_operand'). + 7: optionally, a vector of attributes for this insn. */ +DEF_RTL_EXPR(DEFINE_INSN_AND_SPLIT, "define_insn_and_split", "sEsssESV", 'x') + /* Definition of an RTL peephole operation. Follows the same arguments as define_split. */ DEF_RTL_EXPR(DEFINE_PEEPHOLE2, "define_peephole2", "EsES", 'x') |