aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorClinton Popetz <cpopetz@cygnus.com>2000-05-03 17:45:26 +0000
committerClinton Popetz <cpopetz@gcc.gnu.org>2000-05-03 13:45:26 -0400
commitc88c0d42a1ac718915fcd7c79ebe517baa624348 (patch)
tree51d16ed3ff5a009c7dd29449525fd4e9a6dc37c1 /gcc
parent18ca529b1976bfdc7f84b96f93d0ac3f483bf7f8 (diff)
downloadgcc-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/ChangeLog20
-rw-r--r--gcc/Makefile.in5
-rw-r--r--gcc/genattr.c20
-rw-r--r--gcc/genattrtab.c86
-rw-r--r--gcc/gencodes.c31
-rw-r--r--gcc/genconfig.c61
-rw-r--r--gcc/genemit.c64
-rw-r--r--gcc/genextract.c30
-rw-r--r--gcc/genflags.c23
-rw-r--r--gcc/genopinit.c20
-rw-r--r--gcc/genoutput.c28
-rw-r--r--gcc/genpeep.c22
-rw-r--r--gcc/genrecog.c21
-rw-r--r--gcc/gensupport.c191
-rw-r--r--gcc/gensupport.h24
-rw-r--r--gcc/md.texi50
-rw-r--r--gcc/rtl.def27
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')