This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RFC: midlevel RTL


Hi,
this patch is attempt to start work on midrtl implementation.  It does not
bootstrap at the moment, but has good testsuite score.  There appears to be
some reload interference I can't find right now. (basically the insns are
lowered but for instance reload invents the new insn and puts it code 0 -
generic move that fails as generic move is now refusing everything.  It really
looks like reload bug).

Basically the patch adds new file midrtl.md describing very simple
architecture.  I am slowly bypassing the current code generation to use that
architecture and do splitting to generate lowlevel RTL before CSE2 pass (so
majority of existing optimizations are done on midrtl).

I hope this to be way how to gradually move compiler to midRTL w/o breaking it
too much.  There are dificult issues to solve - for instance how to represent
and emit libcalls I would like to discuss.

Once I will get code bootstrapping (if ever :) I will install it to the cfg
branch as it is more flexible than current mainline source for such change.

Honza

Sun Jan 20 17:19:45 CET 2002  Jan Hubicka  <jh@suse.cz>
	* Makefile.in (md_file): Add dependancy on midrtl.md.
	* emit-rtl.c (try_split): Avoid recursive splitting in
	RTL lowering process; avoid abort on badly updated probability
	notes for now.
	* function.c (prepare_function_start): RTL form is initiallly
	RTL_FORM_MID.
	* function.h (struct function): Add rtl_form.
	* genrecog.c (pred_table): Add generic operands.
	* gensupport.c (init_md_reader): Implicitly inlucde midrtl.md
	file.
	* optabs.c (prepare_generic_operand): New function.
	(expand_binop, expand_unop, emit_cmp_and_jump_insns):
	Generate midlevel RTL.
	* recog.c (generic_address, generic_src_operand, generic_dest_operand):
	New functions.
	* recog.h (generic_address, generic_src_operand, generic_dest_operand):
	Declare.
	* toplev.c (rest_of_compilation): Do RTL lowering.
	* i386.c (ix86_expand_int_movcc): Do not crash on DImode comparisons.
	* midrtl.md: New file.

Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/egcs/gcc/Makefile.in,v
retrieving revision 1.775.2.19
diff -c -3 -p -r1.775.2.19 Makefile.in
*** Makefile.in	2002/01/18 23:23:53	1.775.2.19
--- Makefile.in	2002/01/20 17:11:50
*************** xmake_file=@dep_host_xmake_file@
*** 252,258 ****
  tmake_file=@dep_tmake_file@
  out_file=$(srcdir)/config/@out_file@
  out_object_file=@out_object_file@
! md_file=$(srcdir)/config/@md_file@
  tm_p_file_list=@tm_p_file_list@
  tm_p_file=@tm_p_file@
  build_xm_file_list=@build_xm_file_list@
--- 252,258 ----
  tmake_file=@dep_tmake_file@
  out_file=$(srcdir)/config/@out_file@
  out_object_file=@out_object_file@
! md_file=$(srcdir)/config/@md_file@ $(srcdir)/midrtl.md
  tm_p_file_list=@tm_p_file_list@
  tm_p_file=@tm_p_file@
  build_xm_file_list=@build_xm_file_list@
Index: emit-rtl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/emit-rtl.c,v
retrieving revision 1.223.2.8
diff -c -3 -p -r1.223.2.8 emit-rtl.c
*** emit-rtl.c	2002/01/17 14:34:00	1.223.2.8
--- emit-rtl.c	2002/01/20 17:11:51
*************** try_split (pat, trial, last)
*** 3003,3011 ****
  		    /* We can preserve the REG_BR_PROB notes only if exactly
  		       one jump is created, otherwise the machine description
  		       is responsible for this step using
! 		       split_branch_probability variable.  */
  		    if (njumps != 1)
  		      abort ();
  		    REG_NOTES (insn)
  		      = gen_rtx_EXPR_LIST (REG_BR_PROB,
  					   GEN_INT (probability),
--- 3003,3017 ----
  		    /* We can preserve the REG_BR_PROB notes only if exactly
  		       one jump is created, otherwise the machine description
  		       is responsible for this step using
! 		       split_branch_probability variable. 
! 		    
! 		       MIDlevel RTL lowering process create this from time to time.
! 		       Lets give up this condition for now.
! 		     */
! #if 0
  		    if (njumps != 1)
  		      abort ();
+ #endif
  		    REG_NOTES (insn)
  		      = gen_rtx_EXPR_LIST (REG_BR_PROB,
  					   GEN_INT (probability),
*************** try_split (pat, trial, last)
*** 3089,3106 ****
  	     set LAST and continue from the insn after the one returned.
  	     We can't use next_active_insn here since AFTER may be a note.
  	     Ignore deleted insns, which can be occur if not optimizing.  */
! 	  for (tem = NEXT_INSN (before); tem != after; tem = NEXT_INSN (tem))
! 	    if (! INSN_DELETED_P (tem) && INSN_P (tem))
! 	      tem = try_split (PATTERN (tem), tem, 1);
  	}
        /* Avoid infinite loop if the result matches the original pattern.  */
        else if (rtx_equal_p (seq, pat))
  	return trial;
!       else
  	{
  	  PATTERN (trial) = seq;
  	  INSN_CODE (trial) = -1;
! 	  try_split (seq, trial, last);
  	}
  
        /* Return either the first or the last insn, depending on which was
--- 3095,3115 ----
  	     set LAST and continue from the insn after the one returned.
  	     We can't use next_active_insn here since AFTER may be a note.
  	     Ignore deleted insns, which can be occur if not optimizing.  */
! 	  if (cfun->rtl_form != RTL_FORM_MIDLOW)
! 	    for (tem = NEXT_INSN (before); tem != after; tem = NEXT_INSN (tem))
! 	      if (! INSN_DELETED_P (tem) && INSN_P (tem))
! 		tem = try_split (PATTERN (tem), tem, 1);
  	}
        /* Avoid infinite loop if the result matches the original pattern.  */
        else if (rtx_equal_p (seq, pat))
  	return trial;
!       else 
  	{
  	  PATTERN (trial) = seq;
  	  INSN_CODE (trial) = -1;
!           /* Avoid recursive splitting during RTL lowering process.  */
! 	  if (cfun->rtl_form != RTL_FORM_MIDLOW)
! 	    try_split (seq, trial, last);
  	}
  
        /* Return either the first or the last insn, depending on which was
Index: function.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/function.c,v
retrieving revision 1.322.2.6
diff -c -3 -p -r1.322.2.6 function.c
*** function.c	2002/01/07 14:50:47	1.322.2.6
--- function.c	2002/01/20 17:11:53
*************** prepare_function_start ()
*** 6133,6138 ****
--- 6133,6140 ----
    cfun->stack_alignment_needed = STACK_BOUNDARY;
    cfun->preferred_stack_boundary = STACK_BOUNDARY;
  
+   cfun->rtl_form = RTL_FORM_MID;
+ 
    /* Set if a call to setjmp is seen.  */
    current_function_calls_setjmp = 0;
  
Index: function.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/function.h,v
retrieving revision 1.71.2.4
diff -c -3 -p -r1.71.2.4 function.h
*** function.h	2002/01/07 14:50:47	1.71.2.4
--- function.h	2002/01/20 17:11:54
*************** struct function
*** 487,492 ****
--- 487,505 ----
      FUNCTION_FREQUENCY_HOT,
      FUNCTION_FREQUENCY_UNLIKELY_EXECUTED
    } function_frequency;
+ 
+   /* Record current form of RTL during at current compilation phase.
+      The order is reverse of how lowering happens, so comparisons works.  */
+   enum rtl_form {
+     /* The lowlevel RTL form - each insn corresponds to pattern in machine
+        description.  */
+     RTL_FORM_LOW,
+     /* Code lowering is in the progress - the generic patterns are being split
+        to lowlevel instructions.  */
+     RTL_FORM_MIDLOW,
+     /* Majority of insns are well formed generic patterns.  */
+     RTL_FORM_MID
+   } rtl_form;
  };
  
  /* The function currently being compiled.  */
Index: genconstants.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/genconstants.c,v
retrieving revision 1.2.8.1
diff -c -3 -p -r1.2.8.1 genconstants.c
*** genconstants.c	2001/12/14 23:08:15	1.2.8.1
--- genconstants.c	2002/01/20 17:11:55
*************** main (argc, argv)
*** 63,69 ****
    if (argc <= 1)
      fatal ("no input file name");
  
!   if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    /* Scan and discard the entire file.  This has the side effect
--- 63,69 ----
    if (argc <= 1)
      fatal ("no input file name");
  
!   if (init_md_reader (argv[1], argv[2]) != SUCCESS_EXIT_CODE)
      return (FATAL_EXIT_CODE);
  
    /* Scan and discard the entire file.  This has the side effect
Index: genrecog.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/genrecog.c,v
retrieving revision 1.111.2.4
diff -c -3 -p -r1.111.2.4 genrecog.c
*** genrecog.c	2002/01/07 14:50:51	1.111.2.4
--- genrecog.c	2002/01/20 17:11:56
*************** static const struct pred_table
*** 186,191 ****
--- 186,199 ----
    const char *const name;
    const RTX_CODE codes[NUM_RTX_CODE];
  } preds[] = {
+   {"generic_src_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,
+ 			   VEC_CONST, LABEL_REF, SUBREG, REG, MEM}},
+   {"generic_dest_operand", {SUBREG, REG, MEM}},
+   {"generic_unary_operator", {NEG, NOT, ABS, SQRT, FFS}},
+   {"generic_binary_operator", {SS_PLUS, SS_MINUS, US_PLUS, US_MINUS,
+ 			      PLUS, MINUS, DIV, MOD, UDIV, UMOD, ASHIFT,
+ 			      ASHIFTRT, LSHIFTRT, MULT, AND, IOR, XOR,
+ 			      SMIN, SMAX, UMIN, UMAX}},
    {"general_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,
  		       LABEL_REF, SUBREG, REG, MEM}},
  #ifdef PREDICATE_CODES
*************** static const char *const special_mode_pr
*** 220,226 ****
  #ifdef SPECIAL_MODE_PREDICATES
    SPECIAL_MODE_PREDICATES
  #endif
!   "pmode_register_operand"
  };
  
  #define NUM_SPECIAL_MODE_PREDS ARRAY_SIZE (special_mode_pred_table)
--- 228,236 ----
  #ifdef SPECIAL_MODE_PREDICATES
    SPECIAL_MODE_PREDICATES
  #endif
!   "pmode_register_operand",
!   "generic_src_operand",
!   "generic_dest_operand"
  };
  
  #define NUM_SPECIAL_MODE_PREDS ARRAY_SIZE (special_mode_pred_table)
Index: gensupport.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/gensupport.c,v
retrieving revision 1.23.2.2
diff -c -3 -p -r1.23.2.2 gensupport.c
*** gensupport.c	2001/12/14 23:08:18	1.23.2.2
--- gensupport.c	2002/01/20 17:11:56
*************** init_md_reader_args (argc, argv)
*** 958,973 ****
       char **argv;
  {
    int i;
!   const char *in_fname;
  
    max_include_len = 0;
    in_fname = NULL;
    for (i = 1; i < argc; i++)
      {
        if (argv[i][0] != '-')
  	{
  	  if (in_fname == NULL)
  	    in_fname = argv[i];
  	}
        else
  	{
--- 958,976 ----
       char **argv;
  {
    int i;
!   const char *in_fname, *mid_fname;
  
    max_include_len = 0;
    in_fname = NULL;
+   mid_fname = NULL;
    for (i = 1; i < argc; i++)
      {
        if (argv[i][0] != '-')
  	{
  	  if (in_fname == NULL)
  	    in_fname = argv[i];
+ 	  else if (mid_fname == NULL)
+ 	    mid_fname = argv[i];
  	}
        else
  	{
*************** init_md_reader_args (argc, argv)
*** 1002,1015 ****
  	    }
  	}
      }
!     return init_md_reader (in_fname);
  }
  
  /* The entry point for initializing the reader.  */
  
  int
! init_md_reader (filename)
!      const char *filename;
  {
    FILE *input_file;
    int c;
--- 1005,1018 ----
  	    }
  	}
      }
!     return init_md_reader (in_fname, mid_fname);
  }
  
  /* The entry point for initializing the reader.  */
  
  int
! init_md_reader (filename, midfilename)
!      const char *filename, *midfilename;
  {
    FILE *input_file;
    int c;
*************** init_md_reader (filename)
*** 1033,1038 ****
--- 1036,1045 ----
    obstack_init (rtl_obstack);
    errors = 0;
    sequence_num = 0;
+ 
+   /* Read the midlevel RTL description first.  */
+   if (init_include_reader (fopen (midfilename, "r")) == FATAL_EXIT_CODE)
+     errors = 1;
  
    /* Read the entire file.  */
    while (1)
Index: gensupport.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/gensupport.h,v
retrieving revision 1.3.8.1
diff -c -3 -p -r1.3.8.1 gensupport.h
*** gensupport.h	2001/11/22 16:04:38	1.3.8.1
--- gensupport.h	2002/01/20 17:11:56
*************** struct obstack;
*** 22,28 ****
  extern struct obstack *rtl_obstack;
  
  extern int init_md_reader_args	PARAMS ((int, char **));
! extern int init_md_reader	PARAMS ((const char *));
  extern rtx read_md_rtx		PARAMS ((int *, int *));
  
  extern void message_with_line	PARAMS ((int, const char *, ...))
--- 22,28 ----
  extern struct obstack *rtl_obstack;
  
  extern int init_md_reader_args	PARAMS ((int, char **));
! extern int init_md_reader	PARAMS ((const char *, const char *));
  extern rtx read_md_rtx		PARAMS ((int *, int *));
  
  extern void message_with_line	PARAMS ((int, const char *, ...))
Index: midrtl.md
===================================================================
RCS file: midrtl.md
diff -N midrtl.md
*** /dev/null	Tue May  5 13:32:27 1998
--- midrtl.md	Sun Jan 20 09:11:56 2002
***************
*** 0 ****
--- 1,114 ----
+ ;; GCC midlevel RTL description
+ ;; Copyright (C) 2002 Free Software Foundation, Inc.
+ ;; Contributed by Jan Hubicka
+ ;;
+ ;; 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.
+ 
+ (define_insn_and_split "_generic_move"
+   [(set (match_operand 0 "generic_dest_operand" "")
+         (match_operand 1 "generic_src_operand" ""))]
+   "cfun->rtl_form >= RTL_FORM_MID"
+   "#"
+   "cfun->rtl_form == RTL_FORM_MIDLOW"
+   [(const_int 0)]
+ {
+   emit_move_insn (operands[0], operands[1]);
+   DONE;
+ })
+ 
+ (define_insn_and_split "generic_unary_operation"
+   [(set (match_operand 0 "generic_dest_operand" "")
+ 	(match_operator 2 "generic_unary_operator"
+ 	   [(match_operand 1 "generic_src_operand" "")]))]
+   "cfun->rtl_form >= RTL_FORM_MID"
+   "#"
+   "cfun->rtl_form == RTL_FORM_MIDLOW"
+   [(const_int 0)]
+ {
+   rtx res;
+   res = expand_simple_unop (GET_MODE (operands[0]), GET_CODE (operands[2]),
+ 			    operands[1], operands[0], 1);
+   if (!res)
+     abort ();
+   if (res != operands[0])
+     emit_move_insn (operands[0], res);
+   DONE;
+ })
+ 
+ (define_insn_and_split "_generic_binary_operation"
+   [(set (match_operand 0 "generic_dest_operand" "")
+ 	(match_operator 3 "generic_binary_operator"
+ 	   [(match_operand 1 "generic_src_operand" "")
+ 	    (match_operand 2 "generic_src_operand" "")]))]
+   "cfun->rtl_form >= RTL_FORM_MID"
+   "#"
+   "cfun->rtl_form == RTL_FORM_MIDLOW"
+   [(const_int 0)]
+ {
+   rtx res;
+   res = expand_simple_binop (GET_MODE (operands[0]), GET_CODE (operands[3]),
+ 			     operands[1], operands[2], operands[0],
+ 			     1, OPTAB_LIB_WIDEN);
+   if (!res)
+     abort ();
+   if (res != operands[0])
+     emit_move_insn (operands[0], res);
+   DONE;
+ })
+ 
+ (define_insn_and_split "_generic_simplejump"
+   [(set (pc) (label_ref (match_operand 0 "" "")))]
+   "cfun->rtl_form >= RTL_FORM_MID"
+   "#"
+   "cfun->rtl_form == RTL_FORM_MIDLOW"
+   [(const_int 0)]
+ {
+   emit_insn (gen_jump (operands[0]));
+   DONE;
+ })
+ 
+ (define_insn_and_split "_generic_indirectjump"
+   [(set (pc) (match_operand 0 "generic_src_operand" ""))]
+   "cfun->rtl_form >= RTL_FORM_MID"
+   "#"
+   "cfun->rtl_form == RTL_FORM_MIDLOW"
+   [(const_int 0)]
+ {
+   emit_insn (gen_indirect_jump (operands[0]));
+   DONE;
+ })
+ 
+ (define_insn_and_split "_generic_condjump"
+   [(set (pc)
+ 	(if_then_else (match_operator 3 "comparison_operator"
+ 			 [(match_operand 0 "generic_src_operand" "")
+ 			  (match_operand 1 "generic_src_operand" "")])
+ 		      (label_ref (match_operand 2 "" ""))
+ 		      (pc)))]
+   "cfun->rtl_form >= RTL_FORM_MID && GET_MODE (operands[0]) != VOIDmode"
+   "#"
+   "cfun->rtl_form == RTL_FORM_MIDLOW"
+   [(const_int 0)]
+ {
+   emit_cmp_and_jump_insns (operands[0], operands[1], GET_CODE (operands[3]),
+ 			   NULL_RTX, GET_MODE (operands[0]),
+ 			   unsigned_condition (GET_CODE (operands[3]))
+ 			   == GET_CODE (operands[3]),
+ 			   operands[2]);
+   DONE;
+ })
Index: optabs.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/optabs.c,v
retrieving revision 1.116.2.5
diff -c -3 -p -r1.116.2.5 optabs.c
*** optabs.c	2002/01/14 21:18:01	1.116.2.5
--- optabs.c	2002/01/20 17:11:57
*************** static void emit_cmp_and_jump_insn_1 PAR
*** 118,123 ****
--- 118,124 ----
  					    enum rtx_code, int, rtx));
  static void prepare_float_lib_cmp PARAMS ((rtx *, rtx *, enum rtx_code *,
  					 enum machine_mode *, int *));
+ static rtx prepare_generic_operand PARAMS ((rtx, enum machine_mode, int));
  
  /* Add a REG_EQUAL note to the last insn in SEQ.  TARGET is being set to
     the result of operation CODE applied to OP0 (and OP1 if it is a binary
*************** expand_binop (mode, binoptab, op0, op1, 
*** 717,722 ****
--- 718,737 ----
  	}
      }
  
+   if (cfun->rtl_form >= RTL_FORM_MID && binoptab->code != UNKNOWN
+       && binoptab->code != SMIN && binoptab->code != SMAX
+       && binoptab->code != UMIN && binoptab->code != UMAX)
+     {
+       if (!target)
+ 	target = gen_reg_rtx (mode);
+       op0 = prepare_generic_operand (op0, mode, 1);
+       op1 = prepare_generic_operand (op1, shift_op ? QImode : mode, 1);
+       emit_insn (gen_rtx_SET (VOIDmode, target,
+ 			      gen_rtx_fmt_ee (binoptab->code, mode,
+ 					      op0, op1)));
+       return target;
+     }
+ 
    /* If we can do it with a three-operand insn, do so.  */
  
    if (methods != OPTAB_MUST_WIDEN
*************** expand_unop (mode, unoptab, op0, target,
*** 2090,2095 ****
--- 2105,2121 ----
    if (target)
      target = protect_from_queue (target, 1);
  
+   if (cfun->rtl_form >= RTL_FORM_MID && unoptab->code != UNKNOWN
+       && unoptab->code != ABS)
+     {
+       if (!target)
+ 	target = gen_reg_rtx (mode);
+       op0 = prepare_generic_operand (op0, mode, 1);
+       emit_insn (gen_rtx_SET (VOIDmode, target,
+ 			      gen_rtx_fmt_e (unoptab->code, mode, op0)));
+       return target;
+     }
+ 
    if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
      {
        int icode = (int) unoptab->handlers[(int) mode].insn_code;
*************** prepare_operand (icode, x, opnum, mode, 
*** 3243,3248 ****
--- 3269,3289 ----
    return x;
  }
  
+ static rtx
+ prepare_generic_operand (x, mode, unsignedp)
+      rtx x;
+      enum machine_mode mode;
+      int unsignedp;
+ {
+   x = protect_from_queue (x, 0);
+   x = force_not_mem (x);
+ 
+   if (GET_MODE (x) != VOIDmode && GET_MODE (x) != mode)
+     x = convert_modes (mode, GET_MODE (x), x, unsignedp);
+ 
+   return x;
+ }
+ 
  /* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
     we can do the comparison.
     The arguments are the same as for emit_cmp_and_jump_insns; but LABEL may
*************** emit_cmp_and_jump_insns (x, y, compariso
*** 3365,3370 ****
--- 3406,3426 ----
    emit_queue ();
    if (unsignedp)
      comparison = unsigned_condition (comparison);
+ 
+   if (cfun->rtl_form >= RTL_FORM_MID && mode != BLKmode && label)
+     {
+       op0 = prepare_generic_operand (op0, mode, unsignedp);
+       op1 = prepare_generic_operand (op1, mode, unsignedp);
+       if (GET_MODE (op0) == VOIDmode && GET_MODE (op1) == VOIDmode)
+ 	op0 = force_reg (mode, op0);
+       emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
+ 				   gen_rtx_IF_THEN_ELSE (VOIDmode,
+ 				     gen_rtx_fmt_ee (comparison, VOIDmode,
+ 						     op0, op1),
+ 				     gen_rtx_LABEL_REF (VOIDmode, label),
+ 				     pc_rtx)));
+       return;
+     }
  
    prepare_cmp_insn (&op0, &op1, &comparison, size, &mode, &unsignedp,
  		    ccp_jump);
Index: recog.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/recog.c,v
retrieving revision 1.133.2.3
diff -c -3 -p -r1.133.2.3 recog.c
*** recog.c	2002/01/16 18:19:59	1.133.2.3
--- recog.c	2002/01/20 17:11:58
*************** peephole2_optimize (dump_file)
*** 3220,3222 ****
--- 3220,3424 ----
  #endif
  }
  #endif /* HAVE_peephole2 */
+ 
+ int
+ generic_address (op)
+      rtx op;
+ {
+ #if 0
+   rtx offset = NULL, base = NULL, index = NULL, mult = NULL;
+ 
+   switch (GET_CODE (op))
+     {
+     case REG:
+       base = op;
+       break;
+     case PLUS:
+       if (CONSTANT_P (XEXP (op, 1)))
+ 	{
+ 	  offset = XEXP (op, 1);
+ 	  op = XEXP (op, 0);
+ 	  if (GET_CODE (op) == MULT)
+ 	    goto mult;
+ 	  base = op;
+ 	}
+       else
+ 	{
+ 	  base = XEXP (op, 1);
+ 	  op = XEXP (op, 0);
+ 	  if (REG_P (op))
+ 	    index = op;
+ 	  else if (GET_CODE (op) == MULT)
+ 	    goto mult;
+ 	  else
+ 	    return 0;
+ 	}
+       break;
+     case MULT:
+     mult:
+       index = XEXP (mult, 0);
+       mult = XEXP (mult, 1);
+       break;
+     default:
+       offset = op;
+     }
+   if (offset)
+     switch (GET_CODE (offset))
+       {
+       case CONST:
+       case LABEL_REF:
+       case SYMBOL_REF:
+       case CONST_INT:
+       case CONST_DOUBLE:
+ 	break;
+       default:
+ 	return 0;
+       }
+   if (base && (!REG_P (base) || GET_MODE (base) != Pmode))
+     return 0;
+   if (index && (!REG_P (index) || GET_MODE (index) != Pmode))
+     return 0;
+   if (mult && GET_CODE (mult) != CONST_INT)
+     return 0;
+   return 1;
+ #endif
+   return address_operand (op, VOIDmode);
+ }
+ 
+ int
+ generic_src_operand (op, mode)
+      rtx op;
+      enum machine_mode mode;
+ {
+   enum machine_mode op_mode = GET_MODE (op);
+   enum rtx_code code = GET_CODE (op);
+ 
+   if (mode != VOIDmode && op_mode != VOIDmode && mode != op_mode)
+     return 0;
+   if (mode == VOIDmode && op_mode != VOIDmode)
+     switch (GET_MODE_CLASS (op_mode))
+       {
+ 	case MODE_INT:
+ 	case MODE_FLOAT:
+ 	case MODE_COMPLEX_INT:
+ 	case MODE_COMPLEX_FLOAT:
+ 	case MODE_VECTOR_INT:
+ 	case MODE_VECTOR_FLOAT:
+ 	  break;
+ 	default:
+ 	  return 0;
+       }
+   switch (code)
+     {
+ 	/* Accept constants.  */
+       case LABEL_REF:
+       case SYMBOL_REF:
+       case CONST_INT:
+       case CONST_DOUBLE:
+       case CONST:
+       case CONSTANT_P_RTX:
+       case VEC_CONST:
+ 	/* Accept registers.  */
+       case REG:
+ 	return 1;
+ 	/* Accept memory.  */
+       case MEM:
+ 	return generic_address (XEXP (op, 0));
+ 	/* Accept subreg of register.  */
+       case SUBREG:
+ 	return (REG_P (SUBREG_REG (op)));
+       default:
+ 	return 0;
+     }
+ }
+ int
+ generic_dest_operand (op, mode)
+      rtx op;
+      enum machine_mode mode;
+ {
+   enum machine_mode op_mode = GET_MODE (op);
+   enum rtx_code code = GET_CODE (op);
+ 
+   if (mode != VOIDmode && op_mode != VOIDmode && mode != op_mode)
+     return 0;
+   if (mode == VOIDmode && op_mode != VOIDmode)
+     switch (GET_MODE_CLASS (op_mode))
+       {
+       case MODE_INT:
+       case MODE_FLOAT:
+       case MODE_COMPLEX_INT:
+       case MODE_COMPLEX_FLOAT:
+       case MODE_VECTOR_INT:
+       case MODE_VECTOR_FLOAT:
+ 	break;
+       default:
+ 	return 0;
+       }
+   switch (code)
+     {
+       /* Accept registers.  */
+     case REG:
+       return 1;
+       /* Accept memory.  */
+     case MEM:
+       return generic_address (XEXP (op, 0));
+       /* Accept subreg of register.  */
+     case SUBREG:
+       return (REG_P (SUBREG_REG (op)));
+     default:
+       return 0;
+     }
+ }
+ 
+ int
+ generic_unary_operator (op, mode)
+      rtx op;
+      enum machine_mode mode ATTRIBUTE_UNUSED;
+ {
+   switch (GET_CODE (op))
+     {
+       case NEG:
+       case NOT:
+       case ABS:
+       case SQRT:
+       case FFS:
+ 	return 1;
+       default:
+ 	return 0;
+     }
+   return 0;
+ }
+ 
+ int
+ generic_binary_operator (op, mode)
+      rtx op;
+      enum machine_mode mode ATTRIBUTE_UNUSED;
+ {
+   switch (GET_CODE (op))
+     {
+       case SS_PLUS:
+       case SS_MINUS:
+       case US_PLUS:
+       case US_MINUS:
+       case PLUS:
+       case MINUS:
+       case DIV:
+       case MOD:
+       case UDIV:
+       case UMOD:
+       case ASHIFT:
+       case ASHIFTRT:
+       case LSHIFTRT:
+       case MULT:
+       case AND:
+       case IOR:
+       case XOR:
+       case SMIN:
+       case SMAX:
+       case UMIN:
+       case UMAX:
+ 	return 1;
+       default:
+ 	return 0;
+     }
+ }
Index: recog.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/recog.h,v
retrieving revision 1.41
diff -c -3 -p -r1.41 recog.h
*** recog.h	2001/10/07 16:50:52	1.41
--- recog.h	2002/01/20 17:11:58
*************** extern int reg_fits_class_p		PARAMS ((rt
*** 96,101 ****
--- 96,105 ----
  					       enum machine_mode));
  extern rtx *find_single_use		PARAMS ((rtx, rtx, rtx *));
  
+ extern int generic_address		PARAMS ((rtx));
+ 
+ extern int generic_src_operand		PARAMS ((rtx, enum machine_mode));
+ extern int generic_dest_operand		PARAMS ((rtx, enum machine_mode));
  extern int general_operand		PARAMS ((rtx, enum machine_mode));
  extern int address_operand		PARAMS ((rtx, enum machine_mode));
  extern int register_operand		PARAMS ((rtx, enum machine_mode));
Index: toplev.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/toplev.c,v
retrieving revision 1.537.2.35
diff -c -3 -p -r1.537.2.35 toplev.c
*** toplev.c	2002/01/19 20:53:44	1.537.2.35
--- toplev.c	2002/01/20 17:11:59
*************** rest_of_compilation (decl)
*** 3080,3085 ****
--- 3080,3101 ----
       }
  #endif
  
+   /* Lower into lowlevel RTL now.  */
+   cfun->rtl_form = RTL_FORM_MIDLOW;
+   {
+     rtx insn;
+     int old_defer = flag_defer_pop;
+ 
+     flag_defer_pop = 0;
+     split_all_insns (0);
+     flag_defer_pop = old_defer;
+     for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+       if (INSN_P (insn))
+ 	INSN_CODE (insn) = -1;
+   }
+   reg_scan (insns, max_reg_num (), 0);
+   cfun->rtl_form = RTL_FORM_LOW;
+ 
    if (optimize > 0)
      {
        timevar_push (TV_CSE2);
Index: config/i386/i386.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/i386/i386.c,v
retrieving revision 1.353.2.2
diff -c -3 -p -r1.353.2.2 i386.c
*** i386.c	2002/01/14 21:18:22	1.353.2.2
--- i386.c	2002/01/20 17:12:02
*************** ix86_expand_int_movcc (operands)
*** 8030,8035 ****
--- 8030,8037 ----
  
  	  out = emit_store_flag (out, code, ix86_compare_op0,
  				 ix86_compare_op1, VOIDmode, 0, 1);
+ 	  if (!out)
+ 	    return 0;
  
  	  nops = 0;
  	  /* On x86_64 the lea instruction operates on Pmode, so we need to get arithmetics
*************** ix86_expand_int_movcc (operands)
*** 8119,8124 ****
--- 8121,8128 ----
  
  	  out = emit_store_flag (out, code, ix86_compare_op0,
  				 ix86_compare_op1, VOIDmode, 0, 1);
+ 	  if (!out)
+ 	    return 0;
  
  	  out = expand_simple_binop (mode, PLUS,
  				     out, constm1_rtx,


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]