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]

Midlevel RTL part 1


Hi
I've bootstrapped and installed teh attached patch to cfg-branch.

	* 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/21 19:09:37
*************** 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: caller-save.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/caller-save.c,v
retrieving revision 1.47.2.2
diff -c -3 -p -r1.47.2.2 caller-save.c
*** caller-save.c	2002/01/07 14:50:18	1.47.2.2
--- caller-save.c	2002/01/21 19:09:37
*************** init_caller_save ()
*** 115,121 ****
--- 115,124 ----
    rtx address;
    int i, j;
    enum machine_mode mode;
+   enum rtl_form old = cfun->rtl_form;
  
+   cfun->rtl_form = RTL_FORM_LOW;
+ 
    /* First find all the registers that we need to deal with and all
       the modes that they can have.  If we can't find a mode to use,
       we can't have the register live over calls.  */
*************** init_caller_save ()
*** 234,239 ****
--- 237,243 ----
  	}
  
    end_sequence ();
+   cfun->rtl_form = old;
  }
  
  /* Initialize save areas by showing that we haven't allocated any yet.  */
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/21 19:09:38
*************** 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/21 19:09:40
*************** 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/21 19:09:40
*************** 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/21 19:09:42
*************** 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/21 19:09:43
*************** 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/21 19:09:43
*************** 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/21 19:09:43
*************** 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	Mon Jan 21 11:09:43 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_generic_binop (GET_CODE (operands[3]), operands[1],
+ 			      operands[2], operands[0]);
+   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/21 19:09:44
*************** 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_simple_binop (mode, code, op0, op
*** 621,626 ****
--- 622,665 ----
  
    return expand_binop (mode, binop, op0, op1, target, unsignedp, methods);
  }
+ 
+ rtx
+ expand_generic_binop (code, op0, op1, target)
+      enum rtx_code code;
+      rtx op0, op1;
+      rtx target;
+ {
+   enum machine_mode mode = GET_MODE (target);
+   switch (code)
+     {
+     case MULT:
+       return expand_mult (mode, op0, op1, target, 1);
+       break;
+     case DIV:
+       if (!INTEGRAL_MODE_P (mode))
+ 	return expand_simple_binop (mode, code, op0, op1, target,
+ 				    1, OPTAB_LIB_WIDEN);
+       else
+ 	return expand_divmod (0,
+ 			      FLOAT_MODE_P (mode)
+ 			      ? RDIV_EXPR : TRUNC_DIV_EXPR, mode,
+ 			      op0, op1, target, 0);
+       break;
+     case MOD:
+       return expand_divmod (1, TRUNC_MOD_EXPR, mode, op0, op1, target, 0);
+       break;
+     case UDIV:
+       return expand_divmod (0, TRUNC_DIV_EXPR, mode, op0, op1, target, 1);
+       break;
+     case UMOD:
+       return expand_divmod (1, TRUNC_MOD_EXPR, mode, op0, op1, target, 1);
+       break;
+     default:
+       return expand_simple_binop (mode, code, op0, op1, target,
+ 				  1, OPTAB_LIB_WIDEN);
+       break;
+     }
+ }
  
  /* Generate code to perform an operation specified by BINOPTAB
     on operands OP0 and OP1, with result having machine-mode MODE.
*************** expand_binop (mode, binoptab, op0, op1, 
*** 717,722 ****
--- 756,777 ----
  	}
      }
  
+   if (cfun->rtl_form >= RTL_FORM_MID && binoptab->code != UNKNOWN
+       && !COMPLEX_MODE_P (GET_MODE_CLASS (mode))
+       && binoptab->code != ROTATE && binoptab->code != ROTATERT
+       && 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 ****
--- 2145,2162 ----
    if (target)
      target = protect_from_queue (target, 1);
  
+   if (cfun->rtl_form >= RTL_FORM_MID && unoptab->code != UNKNOWN
+       && !COMPLEX_MODE_P (GET_MODE_CLASS (mode))
+       && 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 ****
--- 3310,3330 ----
    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 ****
--- 3447,3468 ----
    emit_queue ();
    if (unsignedp)
      comparison = unsigned_condition (comparison);
+ 
+   if (cfun->rtl_form >= RTL_FORM_MID && mode != BLKmode && label
+       && !COMPLEX_MODE_P (GET_MODE_CLASS (mode)))
+     {
+       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/21 19:09:45
*************** peephole2_optimize (dump_file)
*** 3220,3222 ****
--- 3220,3431 ----
  #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:
+       /* Does not work yet due to partial lowering done by codegen.  */
+ #if 0
+ 	case MODE_COMPLEX_INT:
+ 	case MODE_COMPLEX_FLOAT:
+ #endif
+ 	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 ADDRESSOF:
+       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:
+       /* Does not work yet due to partial lowering done by codegen.  */
+ #if 0
+       case MODE_COMPLEX_INT:
+       case MODE_COMPLEX_FLOAT:
+ #endif
+       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/21 19:09:45
*************** 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/21 19:09:47
*************** 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);
*************** lang_independent_init ()
*** 5154,5159 ****
--- 5170,5176 ----
  {
    decl_printable_name = decl_name;
    lang_expand_expr = (lang_expand_expr_t) do_abort;
+ 
  
    /* Set the language-dependent identifier size.  */
    tree_code_length[(int) IDENTIFIER_NODE]
Index: unroll.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/unroll.c,v
retrieving revision 1.144.2.7
diff -c -3 -p -r1.144.2.7 unroll.c
*** unroll.c	2002/01/14 21:18:05	1.144.2.7
--- unroll.c	2002/01/21 19:09:49
*************** unroll_loop (loop, insn_count, strength_
*** 930,935 ****
--- 930,946 ----
  
  	  start_sequence ();
  
+ 	  /* Final value may have form of (PLUS val1 const1_rtx).  We need
+ 	     to convert it into general operand, so compute the real value.  */
+ 
+ 	  if (GET_CODE (final_value) == PLUS)
+ 	    {
+ 	      final_value = expand_simple_binop (mode, PLUS,
+ 						 copy_rtx (XEXP (final_value, 0)),
+ 						 copy_rtx (XEXP (final_value, 1)),
+ 						 NULL_RTX, 0, OPTAB_LIB_WIDEN);
+ 	    }
+ 
  	  /* Calculate the difference between the final and initial values.
  	     Final value may be a (plus (reg x) (const_int 1)) rtx.
  	     Let the following cse pass simplify this if initial value is
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/21 19:09:54
*************** ix86_expand_int_movcc (operands)
*** 7871,7876 ****
--- 7871,7879 ----
        ix86_compare_op1 = GEN_INT (INTVAL (ix86_compare_op1) + 1);
      }
  
+   if (GET_MODE (ix86_compare_op0) == DImode && !TARGET_64BIT)
+     return 0;
+ 
    start_sequence ();
    compare_op = ix86_expand_compare (code, &second_test, &bypass_test);
    compare_seq = gen_sequence ();
*************** ix86_expand_int_movcc (operands)
*** 8030,8035 ****
--- 8033,8040 ----
  
  	  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 ****
--- 8124,8131 ----
  
  	  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,
*************** ix86_expand_fp_movcc (operands)
*** 8344,8349 ****
--- 8351,8360 ----
        return 1;
      }
  
+   /* We can't easilly compare DImode operands.  */
+   if (GET_MODE (ix86_compare_op0) == DImode && !TARGET_64BIT)
+     return 0;
+ 
    /* The floating point conditional move instructions don't directly
       support conditions resulting from a signed integer comparison.  */
  
*************** x86_initialize_trampoline (tramp, fnaddr
*** 10662,10670 ****
    if (!TARGET_64BIT)
      {
        /* Compute offset from the end of the jmp to the target function.  */
!       rtx disp = expand_binop (SImode, sub_optab, fnaddr,
! 			       plus_constant (tramp, 10),
  			       NULL_RTX, 1, OPTAB_DIRECT);
        emit_move_insn (gen_rtx_MEM (QImode, tramp),
  		      GEN_INT (trunc_int_for_mode (0xb9, QImode)));
        emit_move_insn (gen_rtx_MEM (SImode, plus_constant (tramp, 1)), cxt);
--- 10673,10683 ----
    if (!TARGET_64BIT)
      {
        /* Compute offset from the end of the jmp to the target function.  */
!       rtx disp = expand_binop (SImode, add_optab, tramp, GEN_INT (10),
  			       NULL_RTX, 1, OPTAB_DIRECT);
+       disp = expand_binop (SImode, sub_optab, fnaddr,
+ 			   disp,
+ 			   NULL_RTX, 1, OPTAB_DIRECT);
        emit_move_insn (gen_rtx_MEM (QImode, tramp),
  		      GEN_INT (trunc_int_for_mode (0xb9, QImode)));
        emit_move_insn (gen_rtx_MEM (SImode, plus_constant (tramp, 1)), cxt);


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