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]

[cond-optab] Convert mcore


mcore's main simplification stems from consolidating the generation of
the compare instruction into a single routine, instead of having separate
functions for 1) legitimizing a comparison 2) synthesizing the CC register
for the comparison.

Paolo

2009-03-24  Paolo Bonzini  <bonzini@gnu.org>

	* config/mcore/mcore-protos.h (arch_compare_op0, arch_compare_op1,
	mcore_modify_comparison, mcore_gen_compare_reg): Remove.
	(mcore_gen_compare): New.
	* config/mcore/mcore.c (arch_compare_op0, arch_compare_op1): Delete.
	(mcore_modify_comparison, mcore_gen_compare_reg): Fold into...
	(mcore_gen_compare): ... this.
	* config/mcore/mcore.md (cmpsi, bCC, sCC): Remove.
	(cbranchsi4, cstoresi4): New, using mcore_gen_compare.
	(stack probe pattern): Use cbranchsi4.

Index: gcc/config/mcore/mcore-protos.h
===================================================================
--- gcc/config/mcore/mcore-protos.h	(branch cond-optab)
+++ gcc/config/mcore/mcore-protos.h	(working copy)
@@ -46,21 +46,17 @@ extern rtx          mcore_function_value
 
 #ifdef RTX_CODE
 
-extern GTY(()) rtx arch_compare_op0;
-extern GTY(()) rtx arch_compare_op1;
-
 extern const char * mcore_output_bclri         		(rtx, int);
 extern const char * mcore_output_bseti         		(rtx, int);
 extern const char * mcore_output_cmov          		(rtx *, int, const char *);
 extern char *       mcore_output_call          		(rtx *, int);
 extern int          mcore_is_dead                	(rtx, rtx);
 extern int          mcore_expand_insv            	(rtx *);
-extern int          mcore_modify_comparison      	(RTX_CODE);
 extern bool         mcore_expand_block_move      	(rtx *);
 extern const char * mcore_output_andn          		(rtx, rtx *);
 extern void         mcore_print_operand_address  	(FILE *, rtx);
 extern void         mcore_print_operand          	(FILE *, rtx, int);
-extern rtx          mcore_gen_compare_reg        	(RTX_CODE);
+extern bool         mcore_gen_compare	        	(RTX_CODE, rtx, rtx);
 extern int          mcore_symbolic_address_p     	(rtx);
 extern bool         mcore_r15_operand_p			(rtx);
 extern enum reg_class mcore_secondary_reload_class	(enum reg_class, enum machine_mode, rtx);
Index: gcc/config/mcore/mcore.c
===================================================================
--- gcc/config/mcore/mcore.c	(branch cond-optab)
+++ gcc/config/mcore/mcore.c	(working copy)
@@ -57,11 +57,6 @@ long   mcore_current_compilation_timesta
 
 /* Global variables for machine-dependent things.  */
 
-/* Saved operands from the last compare to use when we generate an scc
-  or bcc insn.  */
-rtx arch_compare_op0;
-rtx arch_compare_op1;
-
 /* Provides the class number of the smallest class containing
    reg number.  */
 const int regno_reg_class[FIRST_PSEUDO_REGISTER] =
@@ -519,26 +514,36 @@ mcore_rtx_costs (rtx x, int code, int ou
     }
 }
 
-/* Check to see if a comparison against a constant can be made more efficient
-   by incrementing/decrementing the constant to get one that is more efficient
-   to load.  */
+/* Prepare the operands for a comparison.  Return whether the branch/setcc
+   should reverse the operands.  */
 
-int
-mcore_modify_comparison (enum rtx_code code)
+bool
+mcore_gen_compare (enum rtx_code code, rtx op0, rtx op1)
 {
-  rtx op1 = arch_compare_op1;
-  
+  rtx cc_reg = gen_rtx_REG (CCmode, CC_REG);
+  bool invert;
+
   if (GET_CODE (op1) == CONST_INT)
     {
       HOST_WIDE_INT val = INTVAL (op1);
       
       switch (code)
 	{
+	case GTU:
+	  /* Unsigned > 0 is the same as != 0; everything else is converted
+	     below to LEU (reversed cmphs).  */
+	  if (val == 0)
+	    code = NE;
+	  break;
+
+        /* Check whether (LE A imm) can become (LT A imm + 1),
+	   or (GT A imm) can become (GE A imm + 1).  */
+	case GT:
 	case LE:
 	  if (CONST_OK_FOR_J (val + 1))
 	    {
-	      arch_compare_op1 = GEN_INT (val + 1);
-	      return 1;
+	      op1 = GEN_INT (val + 1);
+	      code = code == LE ? LT : GE;
 	    }
 	  break;
 	  
@@ -546,28 +551,18 @@ mcore_modify_comparison (enum rtx_code c
 	  break;
 	}
     }
-  
-  return 0;
-}
-
-/* Prepare the operands for a comparison.  */
-
-rtx
-mcore_gen_compare_reg (enum rtx_code code)
-{
-  rtx op0 = arch_compare_op0;
-  rtx op1 = arch_compare_op1;
-  rtx cc_reg = gen_rtx_REG (CCmode, CC_REG);
-
+ 
   if (CONSTANT_P (op1) && GET_CODE (op1) != CONST_INT)
     op1 = force_reg (SImode, op1);
 
   /* cmpnei: 0-31 (K immediate)
      cmplti: 1-32 (J immediate, 0 using btsti x,31).  */
+  invert = false;
   switch (code)
     {
     case EQ:	/* Use inverted condition, cmpne.  */
       code = NE;
+      invert = true;
       /* Drop through.  */
       
     case NE:	/* Use normal condition, cmpne.  */
@@ -577,6 +572,7 @@ mcore_gen_compare_reg (enum rtx_code cod
 
     case LE:	/* Use inverted condition, reversed cmplt.  */
       code = GT;
+      invert = true;
       /* Drop through.  */
       
     case GT:	/* Use normal condition, reversed cmplt.  */
@@ -586,6 +582,7 @@ mcore_gen_compare_reg (enum rtx_code cod
 
     case GE:	/* Use inverted condition, cmplt.  */
       code = LT;
+      invert = true;
       /* Drop through.  */
       
     case LT:	/* Use normal condition, cmplt.  */
@@ -597,13 +594,10 @@ mcore_gen_compare_reg (enum rtx_code cod
       break;
 
     case GTU:	/* Use inverted condition, cmple.  */
-      /* Unsigned > 0 is the same as != 0, but we need to invert the
-	 condition, so we want to set code = EQ.  This cannot be done
-	 however, as the mcore does not support such a test.  Instead
-	 we cope with this case in the "bgtu" pattern itself so we
-	 should never reach this point.  */
+      /* We coped with unsigned > 0 above.  */
       gcc_assert (GET_CODE (op1) != CONST_INT || INTVAL (op1) != 0);
       code = LEU;
+      invert = true;
       /* Drop through.  */
       
     case LEU:	/* Use normal condition, reversed cmphs.  */
@@ -613,6 +607,7 @@ mcore_gen_compare_reg (enum rtx_code cod
 
     case LTU:	/* Use inverted condition, cmphs.  */
       code = GEU;
+      invert = true;
       /* Drop through.  */
       
     case GEU:	/* Use normal condition, cmphs.  */
@@ -624,9 +619,10 @@ mcore_gen_compare_reg (enum rtx_code cod
       break;
     }
 
-  emit_insn (gen_rtx_SET (VOIDmode, cc_reg, gen_rtx_fmt_ee (code, CCmode, op0, op1)));
-  
-  return cc_reg;
+  emit_insn (gen_rtx_SET (VOIDmode,
+			  cc_reg,
+			  gen_rtx_fmt_ee (code, CCmode, op0, op1)));
+  return invert;
 }
 
 int
Index: gcc/config/mcore/mcore.md
===================================================================
--- gcc/config/mcore/mcore.md	(branch cond-optab)
+++ gcc/config/mcore/mcore.md	(working copy)
@@ -303,22 +303,6 @@
   ""
   "cmphs	%1,%0")
 
-;; We save the compare operands in the cmpxx patterns and use them when
-;; we generate the branch.
-
-;; We accept constants here, in case we can modify them to ones which
-;; are more efficient to load.  E.g. change 'x <= 62' to 'x < 63'.
-
-(define_expand "cmpsi"
-  [(set (reg:CC 17) (compare:CC (match_operand:SI 0 "mcore_compare_operand" "")
-				(match_operand:SI 1 "nonmemory_operand" "")))]
-  ""
-  "
-{ arch_compare_op0 = operands[0];
-  arch_compare_op1 = operands[1];
-  DONE;
-}")
-
 ;; -------------------------------------------------------------------------
 ;; Logical operations
 ;; -------------------------------------------------------------------------
@@ -1479,6 +1463,10 @@
 ;; Define the real conditional branch instructions.
 ;; ------------------------------------------------------------------------
 
+;; At top-level, condition test are eq/ne, because we
+;; are comparing against the condition register (which
+;; has the result of the true relational test
+
 (define_insn "branch_true"
   [(set (pc) (if_then_else (ne (reg:CC 17) (const_int 0))
 			   (label_ref (match_operand 0 "" ""))
@@ -1513,189 +1501,28 @@
 
 ;; Conditional branch insns
 
-;; At top-level, condition test are eq/ne, because we
-;; are comparing against the condition register (which
-;; has the result of the true relational test
-
-; There is no beq compare, so we reverse the branch arms.
-
-(define_expand "beq"
-  [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
-			   (pc)
-			   (label_ref (match_operand 0 "" ""))))]
-  ""
-  "
-{
-  operands[1] = mcore_gen_compare_reg (EQ);
-}")
-
-(define_expand "bne"
-  [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
-			   (label_ref (match_operand 0 "" ""))
-			   (pc)))]
-  ""
-  "
-{
-  operands[1] = mcore_gen_compare_reg (NE);
-}")
-
-; check whether (GT A imm) can become (LE A imm) with the branch reversed.  
-; if so, emit a (LT A imm + 1) in place of the (LE A imm).  BRC
-
-(define_expand "bgt"
-  [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
-			   (label_ref (match_operand 0 "" ""))
-			   (pc)))]
-  ""
-  "
-{
-  if (mcore_modify_comparison (LE))
-    {
-      emit_jump_insn (gen_reverse_blt (operands[0]));
-      DONE;
-    }
-  operands[1] = mcore_gen_compare_reg (GT);
-}")
-
-; There is no ble compare, so we reverse the branch arms.
-; reversed the condition and branch arms for ble -- the check_dbra_loop()
-; transformation assumes that ble uses a branch-true with the label as
-; as the target. BRC
-
-; check whether (LE A imm) can become (LT A imm + 1).
-
-(define_expand "ble"
-  [(set (pc) (if_then_else (eq (match_dup 1) (const_int 0))
-			   (label_ref (match_operand 0 "" ""))
-                           (pc)))]
-  ""
-  "
-{
-  if (mcore_modify_comparison (LE))
-    {
-      emit_jump_insn (gen_blt (operands[0]));
-      DONE;
-    }
-  operands[1] = mcore_gen_compare_reg (LE);
-}")
-
-; make generating a reversed blt simple
-(define_expand "reverse_blt"
-  [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
-                           (pc)
-                           (label_ref (match_operand 0 "" ""))))]
-  ""
-  "
-{
-  operands[1] = mcore_gen_compare_reg (LT);
-}")
-
-(define_expand "blt"
-  [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
-			   (label_ref (match_operand 0 "" ""))
-			   (pc)))]
-  ""
-  "
-{
-  operands[1] = mcore_gen_compare_reg (LT);
-}")
-
-; There is no bge compare, so we reverse the branch arms.
-
-(define_expand "bge"
-  [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
-			   (pc)
-			   (label_ref (match_operand 0 "" ""))))]
-  ""
-  "
-{
-  operands[1] = mcore_gen_compare_reg (GE);
-}")
-
-; There is no gtu compare, so we reverse the branch arms
-
-;(define_expand "bgtu"
-;  [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
-;			   (pc)
-;			   (label_ref (match_operand 0 "" ""))))]
-;  ""
-;  "
-;{
-;  if (GET_CODE (arch_compare_op1) == CONST_INT
-;      && INTVAL (arch_compare_op1) == 0)
-;    operands[1] = mcore_gen_compare_reg (NE);
-;  else 
-;    { if (mcore_modify_comparison (GTU))
-;	{
-;	  emit_jump_insn (gen_bgeu (operands[0]));
-;	  DONE;
-;	}
-;      operands[1] = mcore_gen_compare_reg (LEU);
-;    }
-;}")
-
-(define_expand "bgtu"
-  [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
-			   (pc)
-			   (label_ref (match_operand 0 "" ""))))]
-  ""
-  "
-{
-  if (GET_CODE (arch_compare_op1) == CONST_INT
-      && INTVAL (arch_compare_op1) == 0)
-    {
-      /* The inverse of '> 0' for an unsigned test is
-	 '== 0' but we do not have such an instruction available.
-	 Instead we must reverse the branch (back to the normal
-	 ordering) and test '!= 0'.  */
-	 
-      operands[1] = mcore_gen_compare_reg (NE);
-      
-      emit_jump_insn (gen_rtx_SET (VOIDmode,
-	pc_rtx,
-	gen_rtx_IF_THEN_ELSE (VOIDmode,
-	gen_rtx_NE (VOIDmode,
-	operands[1],
-	const0_rtx),
-	gen_rtx_LABEL_REF (VOIDmode,operands[0]),
-	pc_rtx)));
-      DONE;	      
-    }
-  operands[1] = mcore_gen_compare_reg (GTU);
-}")
-
-
-(define_expand "bleu"
-  [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
-			   (label_ref (match_operand 0 "" ""))
-			   (pc)))]
+(define_expand "cbranchsi4"
+  [(set (pc)
+	(if_then_else (match_operator:SI 0 "ordered_comparison_operator"
+		       [(match_operand:SI 1 "mcore_compare_operand")
+			(match_operand:SI 2 "nonmemory_operand")])
+		      (label_ref (match_operand 3 ""))
+		      (pc)))]
   ""
   "
 {
-  operands[1] = mcore_gen_compare_reg (LEU);
-}")
+  bool invert;
+  invert = mcore_gen_compare (GET_CODE (operands[0]),
+			      operands[1], operands[2]);
 
-; There is no bltu compare, so we reverse the branch arms
-(define_expand "bltu"
-  [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
-			   (pc)
-			   (label_ref (match_operand 0 "" ""))))]
-  ""
-  "
-{
-  operands[1] = mcore_gen_compare_reg (LTU);
+  if (invert)
+    emit_jump_insn (gen_branch_false (operands[3]));
+  else
+    emit_jump_insn (gen_branch_true (operands[3]));
+  DONE;
 }")
 
-(define_expand "bgeu"
-  [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
-			   (label_ref (match_operand 0 "" ""))
-			   (pc)))]
-  ""
-  "
-{
 
-  operands[1] = mcore_gen_compare_reg (GEU);
-}")
 
 ;; ------------------------------------------------------------------------
 ;; Jump and linkage insns
@@ -1853,118 +1680,23 @@
    (set (match_dup 0) (eq:SI (reg:CC 17) (const_int 0)))])
      
 
-(define_expand "seq"
-  [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
-	(eq:SI (match_dup 1) (const_int 0)))]
-  ""
-  "
-{
-  operands[1] = mcore_gen_compare_reg (NE);
-}")
-
-(define_expand "sne"
-  [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
-	(ne:SI (match_dup 1) (const_int 0)))]
-  ""
-  "
-{
-  operands[1] = mcore_gen_compare_reg (NE);
-}")
-
-(define_expand "slt"
-  [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
-	(ne:SI (match_dup 1) (const_int 0)))]
-  ""
-  "
-{
-  operands[1] = mcore_gen_compare_reg (LT);
-}")
-
-; make generating a LT with the comparison reversed easy.  BRC
-(define_expand "reverse_slt"
+(define_expand "cstoresi4"
   [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
-        (eq:SI (match_dup 1) (const_int 0)))]
+	(match_operator:SI 1 "ordered_comparison_operator"
+	 [(match_operand:SI 2 "mcore_compare_operand" "")
+	  (match_operand:SI 3 "nonmemory_operand" "")]))]
   ""
   "
 {
-  operands[1] = mcore_gen_compare_reg (LT);
-}")
-
-(define_expand "sge"
-  [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
-	(eq:SI (match_dup 1) (const_int 0)))]
-  ""
-  "
-{
-  operands[1] = mcore_gen_compare_reg (LT);
-}")
-
-; check whether (GT A imm) can become (LE A imm) with the comparison
-; reversed.  if so, emit a (LT A imm + 1) in place of the (LE A imm).  BRC
+  bool invert;
+  invert = mcore_gen_compare (GET_CODE (operands[1]),
+			      operands[2], operands[3]);
 
-(define_expand "sgt"
-  [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
-	(ne:SI (match_dup 1) (const_int 0)))]
-  ""
-  "
-{
-  if (mcore_modify_comparison (LE))
-    {
-      emit_insn (gen_reverse_slt (operands[0]));
-      DONE;
-    }
-  
-  operands[1] = mcore_gen_compare_reg (GT);
-}")
-
-(define_expand "sle"
-  [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
-	(eq:SI (match_dup 1) (const_int 0)))]
-  ""
-  "
-{
-  if (mcore_modify_comparison (LE))
-    {
-      emit_insn (gen_slt (operands[0]));
-      DONE;
-    }
-  operands[1] = mcore_gen_compare_reg (GT);
-}")
-
-(define_expand "sltu"
-  [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
-	(eq:SI (match_dup 1) (const_int 0)))]
-  ""
-  "
-{
-  operands[1] = mcore_gen_compare_reg (GEU);
-}")
-
-(define_expand "sgeu"
-  [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
-	(ne:SI (match_dup 1) (const_int 0)))]
-  ""
-  "
-{
-  operands[1] = mcore_gen_compare_reg (GEU);
-}")
-
-(define_expand "sgtu"
-  [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
-	(eq:SI (match_dup 1) (const_int 0)))]
-  ""
-  "
-{
-  operands[1] = mcore_gen_compare_reg (LEU);
-}")
-
-(define_expand "sleu"
-  [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
-	(ne:SI (match_dup 1) (const_int 0)))]
-  ""
-  "
-{
-  operands[1] = mcore_gen_compare_reg (LEU);
+  if (invert)
+    emit_insn (gen_mvcv (operands[0]));
+  else
+    emit_insn (gen_mvc (operands[0]));
+  DONE;
 }")
 
 (define_insn "incscc"
@@ -3308,7 +3040,7 @@
       rtx loop_label = gen_label_rtx ();
       rtx step = gen_reg_rtx (Pmode);
       rtx tmp = gen_reg_rtx (Pmode);
-      rtx memref;
+      rtx test, memref;
 
 #if 1
       emit_insn (gen_movsi (tmp, operands[1]));
@@ -3317,8 +3049,8 @@
       if (GET_CODE (operands[1]) != CONST_INT)
 	{
 	  out_label = gen_label_rtx ();
-	  emit_insn (gen_cmpsi (step, tmp));		/* quick out */
-	  emit_jump_insn (gen_bgeu (out_label));
+	  test = gen_rtx_GEU (VOIDmode, step, tmp);		/* quick out */
+	  emit_jump_insn (gen_cbranchsi4 (test, step, tmp, out_label));
 	}
 
       /* Run a loop that steps it incrementally.  */
@@ -3332,8 +3064,8 @@
       emit_insn(gen_subsi3(tmp, tmp, step));
 
       /* Loop condition -- going back up.  */
-      emit_insn (gen_cmpsi (step, tmp));
-      emit_jump_insn (gen_bltu (loop_label));
+      test = gen_rtx_LTU (VOIDmode, step, tmp);
+      emit_jump_insn (gen_cbranchsi4 (test, step, tmp, loop_label));
 
       if (out_label)
 	emit_label (out_label);


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