define_insn_and_split patch

Clinton Popetz cpopetz@cygnus.com
Wed May 3 09:17:00 GMT 2000


> On Fri, Apr 28, 2000 at 02:07:17PM -0700, Richard Henderson wrote:
>
> > Rather than just adjusting each of the N programs to match, what say we
> > create a new gensupport.c that contains the rtx reader function (and
> > other assundry bits that are not currently shared either).  
 

Ok, here's a patch to do this. 

			-Clint


Wed May  3 10:56:21 CDT 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.


 
*** gensupport.c	Wed May  3 11:00:04 2000
--- gensupport.c	Wed May  3 11:16:58 2000
***************
*** 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;
+ }
*** gnesupport.h	Wed May  3 11:00:04 2000
--- gensupport.h	Wed May  3 11:07:11 2000
***************
*** 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 *));
+ 
+ 
Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/egcs/gcc/Makefile.in,v
retrieving revision 1.431
diff -c -2 -p -r1.431 Makefile.in
*** Makefile.in	2000/04/30 17:30:24	1.431
--- Makefile.in	2000/05/03 15:51:55
*************** HOST_LIBS = $(USE_HOST_OBSTACK) $(USE_HO
*** 585,589 ****
  	    $(HOST_CLIB)
  
! HOST_RTL = $(HOST_PREFIX)rtl.o $(HOST_PREFIX)bitmap.o $(HOST_PREFIX)ggc-none.o
  HOST_PRINT = $(HOST_PREFIX)print-rtl.o
  HOST_ERRORS = $(HOST_PREFIX)errors.o
--- 585,591 ----
  	    $(HOST_CLIB)
  
! 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
*************** toplev.o : toplev.c $(CONFIG_H) system.h
*** 1513,1516 ****
--- 1515,1519 ----
  
  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)
Index: genattr.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/genattr.c,v
retrieving revision 1.33
diff -c -2 -p -r1.33 genattr.c
*** genattr.c	2000/03/07 20:39:05	1.33
--- genattr.c	2000/05/03 15:51:55
*************** Boston, MA 02111-1307, USA.  */
*** 26,29 ****
--- 26,30 ----
  #include "obstack.h"
  #include "errors.h"
+ #include "gensupport.h"
  
  static struct obstack obstack;
*************** main (argc, argv)
*** 223,228 ****
  {
    rtx desc;
-   FILE *infile;
-   register int c;
    int have_delay = 0;
    int have_annul_true = 0;
--- 224,227 ----
*************** main (argc, argv)
*** 246,256 ****
      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];
  
    printf ("/* Generated automatically by the program `genattr'\n\
--- 245,250 ----
      fatal ("No input file name.");
  
!   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'. 
*** 267,276 ****
    while (1)
      {
!       c = read_skip_spaces (infile);
!       if (c == EOF)
  	break;
-       ungetc (c, infile);
  
-       desc = read_rtx (infile);
        if (GET_CODE (desc) == DEFINE_ATTR)
  	gen_attr (desc);
--- 261,270 ----
    while (1)
      {
!       int line_no, insn_code_number;
! 
!       desc = read_md_rtx (&line_no, &insn_code_number);
!       if (desc == NULL)
  	break;
  
        if (GET_CODE (desc) == DEFINE_ATTR)
  	gen_attr (desc);
Index: genattrtab.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/genattrtab.c,v
retrieving revision 1.74
diff -c -2 -p -r1.74 genattrtab.c
*** genattrtab.c	2000/04/24 06:45:30	1.74
--- genattrtab.c	2000/05/03 15:51:59
*************** Boston, MA 02111-1307, USA.  */
*** 101,104 ****
--- 101,105 ----
  #include "rtl.h"
  #include "ggc.h"
+ #include "gensupport.h"
  
  #ifdef HAVE_SYS_RESOURCE_H
*************** gen_insn (exp)
*** 4305,4310 ****
      {
      case DEFINE_INSN:
!       id->insn_code = insn_code_number++;
!       id->insn_index = insn_index_number++;
        id->num_alternatives = count_alternatives (exp);
        if (id->num_alternatives == 0)
--- 4306,4311 ----
      {
      case DEFINE_INSN:
!       id->insn_code = insn_code_number;
!       id->insn_index = insn_index_number;
        id->num_alternatives = count_alternatives (exp);
        if (id->num_alternatives == 0)
*************** gen_insn (exp)
*** 4314,4319 ****
  
      case DEFINE_PEEPHOLE:
!       id->insn_code = insn_code_number++;
!       id->insn_index = insn_index_number++;
        id->num_alternatives = count_alternatives (exp);
        if (id->num_alternatives == 0)
--- 4315,4320 ----
  
      case DEFINE_PEEPHOLE:
!       id->insn_code = insn_code_number;
!       id->insn_index = insn_index_number;
        id->num_alternatives = count_alternatives (exp);
        if (id->num_alternatives == 0)
*************** main (argc, argv)
*** 5968,5973 ****
  {
    rtx desc;
-   FILE *infile;
-   register int c;
    struct attr_desc *attr;
    struct insn_def *id;
--- 5969,5972 ----
*************** main (argc, argv)
*** 5977,5980 ****
--- 5976,5986 ----
    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.  */
*************** main (argc, argv)
*** 5994,6007 ****
    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 */
--- 6000,6005 ----
    obstack_init (temp_obstack);
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
        return (FATAL_EXIT_CODE);
  
    /* Set up true and false rtx's */
*************** from the machine description file `md'. 
*** 6022,6063 ****
    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++;
! 
!       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++;
  
!       else if (GET_CODE (desc) == DEFINE_ATTR)
  	{
! 	  gen_attr (desc);
! 	  insn_index_number++;
! 	}
  
!       else if (GET_CODE (desc) == DEFINE_DELAY)
! 	{
! 	  gen_delay (desc);
! 	  insn_index_number++;
! 	}
  
!       else if (GET_CODE (desc) == DEFINE_FUNCTION_UNIT)
! 	{
! 	  gen_unit (desc);
! 	  insn_index_number++;
  	}
      }
  
    /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one.  */
--- 6020,6057 ----
    while (1)
      {
!       int line_no;
  
!       desc = read_md_rtx (&line_no, &insn_code_number);
!       if (desc == NULL)
! 	break;
  
!       switch (GET_CODE (desc))
  	{
! 	  case DEFINE_INSN:
! 	  case DEFINE_PEEPHOLE:
! 	  case DEFINE_ASM_ATTRIBUTES:
! 	      gen_insn(desc);
! 	      break;
! 	  
! 	  case DEFINE_ATTR:
! 	      gen_attr (desc);
! 	      break;
  
! 	  case DEFINE_DELAY:
! 	      gen_delay (desc);
! 	      break;
  
! 	  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.  */
Index: gencodes.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/gencodes.c,v
retrieving revision 1.28
diff -c -2 -p -r1.28 gencodes.c
*** gencodes.c	2000/02/26 13:50:42	1.28
--- gencodes.c	2000/05/03 15:51:59
*************** Boston, MA 02111-1307, USA.  */
*** 28,31 ****
--- 28,32 ----
  #include "obstack.h"
  #include "errors.h"
+ #include "gensupport.h"
  
  static struct obstack obstack;
*************** main (argc, argv)
*** 85,90 ****
  {
    rtx desc;
-   FILE *infile;
-   register int c;
  
    progname = "gencodes";
--- 86,89 ----
*************** main (argc, argv)
*** 94,104 ****
      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];
  
    printf ("/* Generated automatically by the program `gencodes'\n\
--- 93,98 ----
      fatal ("No input file name.");
  
!   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'. 
*** 114,134 ****
    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_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++;
! 	}
      }
  
--- 108,119 ----
    while (1)
      {
!       int line_no;
! 
!       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);
      }
  
Index: genconfig.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/genconfig.c,v
retrieving revision 1.34
diff -c -2 -p -r1.34 genconfig.c
*** genconfig.c	2000/04/27 07:18:08	1.34
--- genconfig.c	2000/05/03 15:51:59
*************** Boston, MA 02111-1307, USA.  */
*** 27,30 ****
--- 27,31 ----
  #include "obstack.h"
  #include "errors.h"
+ #include "gensupport.h"
  
  static struct obstack obstack;
*************** main (argc, argv)
*** 280,285 ****
  {
    rtx desc;
-   FILE *infile;
-   register int c;
  
    progname = "genconfig";
--- 281,284 ----
*************** main (argc, argv)
*** 289,299 ****
      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];
  
    printf ("/* Generated automatically by the program `genconfig'\n\
--- 288,293 ----
      fatal ("No input file name.");
  
!   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'. 
*** 308,332 ****
    while (1)
      {
!       c = read_skip_spaces (infile);
!       if (c == EOF)
! 	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)
  	{
! 	  have_peephole_flag = 1;
! 	  gen_peephole (desc);
  	}
      }
--- 302,337 ----
    while (1)
      {
!       int line_no, insn_code_number = 0;
  
!       desc = read_md_rtx (&line_no, &insn_code_number);
!       if (desc == NULL)
! 	break;
! 	
!       switch (GET_CODE (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;
  	}
      }
Index: genemit.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/genemit.c,v
retrieving revision 1.53
diff -c -2 -p -r1.53 genemit.c
*** genemit.c	2000/02/26 13:50:42	1.53
--- genemit.c	2000/05/03 15:51:59
*************** Boston, MA 02111-1307, USA.  */
*** 26,29 ****
--- 26,30 ----
  #include "obstack.h"
  #include "errors.h"
+ #include "gensupport.h"
  
  static struct obstack obstack;
*************** main (argc, argv)
*** 780,785 ****
  {
    rtx desc;
-   FILE *infile;
-   register int c;
  
    progname = "genemit";
--- 781,784 ----
*************** main (argc, argv)
*** 789,799 ****
      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];
  
    /* Assign sequential codes to all entries in the machine description
--- 788,793 ----
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
!     return (FATAL_EXIT_CODE);
  
    /* Assign sequential codes to all entries in the machine description
*************** from the machine description file `md'. 
*** 829,863 ****
    while (1)
      {
!       c = read_skip_spaces (infile);
!       if (c == EOF)
! 	break;
!       ungetc (c, infile);
  
!       desc = read_rtx (infile);
  
!       if (GET_CODE (desc) == DEFINE_INSN)
  	{
! 	  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;
! 	}
        ++insn_index_number;
      }
--- 823,853 ----
    while (1)
      {
!       int line_no;
  
!       desc = read_md_rtx (&line_no, &insn_code_number);
!       if (desc == NULL)
! 	break;
  
!       switch (GET_CODE (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:
! 	      gen_split (desc);
! 	      break;
! 
! 	  default:
! 	      break;
! 	 }
        ++insn_index_number;
      }
Index: genextract.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/genextract.c,v
retrieving revision 1.40
diff -c -2 -p -r1.40 genextract.c
*** genextract.c	2000/02/26 13:50:42	1.40
--- genextract.c	2000/05/03 15:52:00
*************** Boston, MA 02111-1307, USA.  */
*** 27,30 ****
--- 27,31 ----
  #include "errors.h"
  #include "insn-config.h"
+ #include "gensupport.h"
  
  static struct obstack obstack;
*************** main (argc, argv)
*** 390,395 ****
  {
    rtx desc;
!   FILE *infile;
!   int c, i;
    struct extraction *p;
    struct code_ptr *link;
--- 391,395 ----
  {
    rtx desc;
!   int i;
    struct extraction *p;
    struct code_ptr *link;
*************** main (argc, argv)
*** 402,412 ****
      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];
  
    /* Assign sequential codes to all entries in the machine description
--- 402,407 ----
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
        return (FATAL_EXIT_CODE);
  
    /* Assign sequential codes to all entries in the machine description
*************** from the machine description file `md'. 
*** 447,461 ****
    while (1)
      {
!       c = read_skip_spaces (infile);
!       if (c == EOF)
  	break;
-       ungetc (c, infile);
  
!       desc = read_rtx (infile);
!       if (GET_CODE (desc) == DEFINE_INSN)
  	{
  	  record_insn_name (insn_code_number, XSTR (desc, 0));
  	  gen_insn (desc);
- 	  ++insn_code_number;
  	}
  
--- 442,455 ----
    while (1)
      {
!       int line_no;
! 
!       desc = read_md_rtx (&line_no, &insn_code_number);
!       if (desc == NULL)
  	break;
  
!        if (GET_CODE (desc) == DEFINE_INSN)
  	{
  	  record_insn_name (insn_code_number, XSTR (desc, 0));
  	  gen_insn (desc);
  	}
  
*************** from the machine description file `md'. 
*** 468,478 ****
  	  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;
      }
  
--- 462,466 ----
Index: genflags.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/genflags.c,v
retrieving revision 1.31
diff -c -2 -p -r1.31 genflags.c
*** genflags.c	2000/03/17 22:40:44	1.31
--- genflags.c	2000/05/03 15:52:00
*************** Boston, MA 02111-1307, USA.  */
*** 28,31 ****
--- 28,32 ----
  #include "obstack.h"
  #include "errors.h"
+ #include "gensupport.h"
  
  static struct obstack obstack;
*************** main (argc, argv)
*** 228,233 ****
    rtx *normal_insns;
    rtx *insn_ptr;
-   FILE *infile;
-   register int c;
  
    progname = "genflags";
--- 229,232 ----
*************** main (argc, argv)
*** 239,250 ****
      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];
! 
    printf ("/* Generated automatically by the program `genflags'\n\
  from the machine description file `md'.  */\n\n");
--- 238,244 ----
      fatal ("No input file name.");
  
!   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");
*************** from the machine description file `md'. 
*** 254,263 ****
    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_EXPAND)
  	gen_insn (desc);
--- 248,256 ----
    while (1)
      {
!       int line_no, insn_code_number = 0;
  
!       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);
Index: genopinit.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/genopinit.c,v
retrieving revision 1.37
diff -c -2 -p -r1.37 genopinit.c
*** genopinit.c	2000/03/07 20:39:05	1.37
--- genopinit.c	2000/05/03 15:52:00
*************** Boston, MA 02111-1307, USA.  */
*** 26,29 ****
--- 26,30 ----
  #include "obstack.h"
  #include "errors.h"
+ #include "gensupport.h"
  
  static struct obstack obstack;
*************** main (argc, argv)
*** 314,319 ****
  {
    rtx desc;
-   FILE *infile;
-   register int c;
  
    progname = "genopinit";
--- 315,318 ----
*************** main (argc, argv)
*** 323,333 ****
      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];
  
    printf ("/* Generated automatically by the program `genopinit'\n\
--- 322,327 ----
      fatal ("No input file name.");
  
!   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'. 
*** 351,360 ****
    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_EXPAND)
  	gen_insn (desc);
--- 345,354 ----
    while (1)
      {
!       int line_no, insn_code_number = 0;
! 
!       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);
Index: genoutput.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/genoutput.c,v
retrieving revision 1.50
diff -c -2 -p -r1.50 genoutput.c
*** genoutput.c	2000/03/17 17:31:54	1.50
--- genoutput.c	2000/05/03 15:52:00
*************** Boston, MA 02111-1307, USA.  */
*** 91,94 ****
--- 91,95 ----
  #include "obstack.h"
  #include "errors.h"
+ #include "gensupport.h"
  
  /* No instruction can have more operands than this.  Sorry for this
*************** gen_insn (insn)
*** 721,725 ****
    register int i;
  
!   d->code_number = next_code_number++;
    d->index_number = next_index_number;
    if (XSTR (insn, 0)[0])
--- 722,726 ----
    register int i;
  
!   d->code_number = next_code_number;
    d->index_number = next_index_number;
    if (XSTR (insn, 0)[0])
*************** gen_peephole (peep)
*** 760,764 ****
    register int i;
  
!   d->code_number = next_code_number++;
    d->index_number = next_index_number;
    d->name = 0;
--- 761,765 ----
    register int i;
  
!   d->code_number = next_code_number;
    d->index_number = next_index_number;
    d->name = 0;
*************** gen_expand (insn)
*** 798,802 ****
    register int i;
  
!   d->code_number = next_code_number++;
    d->index_number = next_index_number;
    if (XSTR (insn, 0)[0])
--- 799,803 ----
    register int i;
  
!   d->code_number = next_code_number;
    d->index_number = next_index_number;
    if (XSTR (insn, 0)[0])
*************** gen_split (split)
*** 841,845 ****
    register int i;
  
!   d->code_number = next_code_number++;
    d->index_number = next_index_number;
    d->name = 0;
--- 842,846 ----
    register int i;
  
!   d->code_number = next_code_number;
    d->index_number = next_index_number;
    d->name = 0;
*************** main (argc, argv)
*** 904,909 ****
  {
    rtx desc;
-   FILE *infile;
-   register int c;
  
    progname = "genoutput";
--- 905,908 ----
*************** main (argc, argv)
*** 913,923 ****
      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];
  
    output_prologue ();
--- 912,917 ----
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
        return (FATAL_EXIT_CODE);
  
    output_prologue ();
*************** main (argc, argv)
*** 929,938 ****
    while (1)
      {
!       c = read_skip_spaces (infile);
!       if (c == EOF)
  	break;
-       ungetc (c, infile);
  
-       desc = read_rtx (infile);
        if (GET_CODE (desc) == DEFINE_INSN)
  	gen_insn (desc);
--- 923,932 ----
    while (1)
      {
!       int line_no;
! 
!       desc = read_md_rtx (&line_no, &next_code_number);
!       if (desc == NULL)
  	break;
  
        if (GET_CODE (desc) == DEFINE_INSN)
  	gen_insn (desc);
Index: genpeep.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/genpeep.c,v
retrieving revision 1.41
diff -c -2 -p -r1.41 genpeep.c
*** genpeep.c	2000/02/26 13:50:42	1.41
--- genpeep.c	2000/05/03 15:52:01
*************** Boston, MA 02111-1307, USA.  */
*** 26,29 ****
--- 26,30 ----
  #include "obstack.h"
  #include "errors.h"
+ #include "gensupport.h"
  
  static struct obstack obstack;
*************** main (argc, argv)
*** 409,414 ****
  {
    rtx desc;
-   FILE *infile;
-   register int c;
  
    max_opno = -1;
--- 410,413 ----
*************** main (argc, argv)
*** 420,430 ****
      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];
  
    printf ("/* Generated automatically by the program `genpeep'\n\
--- 419,424 ----
      fatal ("No input file name.");
  
!   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'. 
*** 459,469 ****
    while (1)
      {
!       c = read_skip_spaces (infile);
!       if (c == EOF)
  	break;
-       ungetc (c, infile);
  
!       desc = read_rtx (infile);
!       if (GET_CODE (desc) == DEFINE_PEEPHOLE)
  	{
  	  gen_peephole (desc);
--- 453,463 ----
    while (1)
      {
!       int line_no, rtx_number = 0;
! 
!       desc = read_md_rtx (&line_no, &rtx_number);
!       if (desc == NULL)
  	break;
  
!        if (GET_CODE (desc) == DEFINE_PEEPHOLE)
  	{
  	  gen_peephole (desc);
Index: genrecog.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/genrecog.c,v
retrieving revision 1.78
diff -c -2 -p -r1.78 genrecog.c
*** genrecog.c	2000/04/09 20:26:42	1.78
--- genrecog.c	2000/05/03 15:52:02
***************
*** 56,59 ****
--- 56,60 ----
  #include "obstack.h"
  #include "errors.h"
+ #include "gensupport.h"
  
  #define OUTPUT_LABEL(INDENT_STRING, LABEL_NUMBER) \
*************** make_insn_sequence (insn, type)
*** 2462,2466 ****
        break;
      }
-   next_insn_code++;
  
    return head;
--- 2463,2466 ----
*************** main (argc, argv)
*** 2519,2529 ****
      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];
  
    next_insn_code = 0;
--- 2519,2524 ----
      fatal ("No input file name.");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
!     return (FATAL_EXIT_CODE);
  
    next_insn_code = 0;
*************** main (argc, argv)
*** 2536,2546 ****
    while (1)
      {
!       c = read_skip_spaces (infile);
!       if (c == EOF)
  	break;
-       ungetc (c, infile);
-       pattern_lineno = read_rtx_lineno;
  
-       desc = read_rtx (infile);
        if (GET_CODE (desc) == DEFINE_INSN)
  	{
--- 2531,2538 ----
    while (1)
      {
!       desc = read_md_rtx (&pattern_lineno, &next_insn_code);
!       if (desc == NULL)
  	break;
  
        if (GET_CODE (desc) == DEFINE_INSN)
  	{
*************** main (argc, argv)
*** 2559,2565 ****
  	}
  	
-       if (GET_CODE (desc) == DEFINE_PEEPHOLE
- 	  || GET_CODE (desc) == DEFINE_EXPAND)
- 	next_insn_code++;
        next_index++;
      }
--- 2551,2554 ----
Index: md.texi
===================================================================
RCS file: /cvs/gcc/egcs/gcc/md.texi,v
retrieving revision 1.43
diff -c -2 -p -r1.43 md.texi
*** md.texi	2000/04/05 21:14:53	1.43
--- md.texi	2000/05/03 15:52:08
*************** definitions, one for the insns that are 
*** 3432,3435 ****
--- 3432,3485 ----
  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
Index: rtl.def
===================================================================
RCS file: /cvs/gcc/egcs/gcc/rtl.def,v
retrieving revision 1.34
diff -c -2 -p -r1.34 rtl.def
*** rtl.def	2000/04/21 19:32:09	1.34
--- rtl.def	2000/05/03 15:52:09
*************** DEF_RTL_EXPR(DEFINE_PEEPHOLE, "define_pe
*** 204,207 ****
--- 204,234 ----
  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.  */


More information about the Gcc-patches mailing list