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 arc (take 2)


This is the arc patch with a little tweaks I've made after testing.

We're getting a little more if-conversion here than on trunk.
The reason is that emit_conditional_move gets a condition of (le
(reg) (const_int -1)), which is not canonical, instead of (lt (reg)
(const_int 0)).  Then, at if-conversion time, on trunk compare_from_rtx
calls simplify_relational_operation which gets back to the LT form.

Because of this:

      if (GET_CODE (comparison) != code)
        return NULL_RTX;

then on trunk emit_conditional_move fails.  The branch is a little
more permissive because compare_from_rtx disappeared altogether,
so it goes on creating correct RTL:

    9 r67:SI=0xa
    6 cc:CC=cmp(r0:SI,0x0)
   33 r71:SI=[`x']
   34 r67:SI={(cc:CC<0x0)?r71:SI:r67:SI}

Paolo

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

	* config/arc/arc.c (gen_compare_reg): Do not emit cmp.
	* config/arc/arc.h (movsicc, movsfcc): Use it.
	(movdicc, *movdicc_insn, movdfcc, *movdfcc_insn): Remove.
	(cbranchsi4, cstoresi4): New.
	(cmpsi, bCC and sCC expanders): Remove.


Index: gcc/config/arc/arc.md
===================================================================
--- gcc/config/arc/arc.md	(branch cond-optab)
+++ gcc/config/arc/arc.md	(working copy)
@@ -585,29 +585,11 @@
   "
 {
   enum rtx_code code = GET_CODE (operands[1]);
-  rtx ccreg
-    = gen_rtx_REG (SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1),
-		   61);
-
-  operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
+  rtx cc_reg = gen_compare_reg (code, XEXP (operands[1], 0),
+				XEXP (operands[1], 1));
+  operands[1] = gen_rtx_fmt_ee (code, VOIDmode, cc_reg, const0_rtx);
 }")
 
-;(define_expand "movdicc"
-;  [(set (match_operand:DI 0 "register_operand" "")
-;	(if_then_else:DI (match_operand 1 "comparison_operator" "")
-;			 (match_operand:DI 2 "nonmemory_operand" "")
-;			 (match_operand:DI 3 "register_operand" "")))]
-;  "0 /* ??? this would work better if we had cmpdi */"
-;  "
-;{
-;  enum rtx_code code = GET_CODE (operands[1]);
-;  rtx ccreg
-;   = gen_rtx_REG (SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1),
-;		   61);
-;
-;  operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
-;}")
-
 (define_expand "movsfcc"
   [(set (match_operand:SF 0 "register_operand" "")
 	(if_then_else:SF (match_operand 1 "comparison_operator" "")
@@ -617,29 +599,11 @@
   "
 {
   enum rtx_code code = GET_CODE (operands[1]);
-  rtx ccreg
-    = gen_rtx_REG (SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1),
-		   61);
-
-  operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
+  rtx cc_reg = gen_compare_reg (code, XEXP (operands[1], 0),
+				XEXP (operands[1], 1));
+  operands[1] = gen_rtx_fmt_ee (code, VOIDmode, cc_reg, const0_rtx);
 }")
 
-;(define_expand "movdfcc"
-;  [(set (match_operand:DF 0 "register_operand" "")
-;	(if_then_else:DF (match_operand 1 "comparison_operator" "")
-;			 (match_operand:DF 2 "nonmemory_operand" "")
-;			 (match_operand:DF 3 "register_operand" "")))]
-;  "0 /* ??? can generate less efficient code if constants involved */"
-;  "
-;{
-; enum rtx_code code = GET_CODE (operands[1]);
-; rtx ccreg
-;   = gen_rtx_REG (SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1),
-;		   61);
-;
-;  operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
-;}")
-
 (define_insn "*movsicc_insn"
   [(set (match_operand:SI 0 "register_operand" "=r")
 	(if_then_else:SI (match_operand 1 "comparison_operator" "")
@@ -649,32 +613,6 @@
   "mov.%d1 %0,%S2"
   [(set_attr "type" "cmove")])
 
-; ??? This doesn't properly handle constants.
-;(define_insn "*movdicc_insn"
-;  [(set (match_operand:DI 0 "register_operand" "=r,r")
-;	(if_then_else:DI (match_operand 1 "comparison_operator" "")
-;			 (match_operand:DI 2 "nonmemory_operand" "r,Ji")
-;			 (match_operand:DI 3 "register_operand" "0,0")))]
-;  "0"
-;  "*
-;{
-;  switch (which_alternative)
-;    {
-;    case 0 :
-;      /* We normally copy the low-numbered register first.  However, if
-;	 the first register operand 0 is the same as the second register of
-;	 operand 1, we must copy in the opposite order.  */
-;      if (REGNO (operands[0]) == REGNO (operands[2]) + 1)
-;	return \"mov.%d1 %R0,%R2\;mov.%d1 %0,%2\";
-;      else
-;	return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\";
-;    case 1 :
-;      return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\";
-;    }
-;}"
-;  [(set_attr "type" "cmove,cmove")
-;   (set_attr "length" "2,4")])
-
 (define_insn "*movsfcc_insn"
   [(set (match_operand:SF 0 "register_operand" "=r,r")
 	(if_then_else:SF (match_operand 1 "comparison_operator" "")
@@ -686,30 +624,6 @@
    mov.%d1 %0,%2 ; %A2"
   [(set_attr "type" "cmove,cmove")])
 
-;(define_insn "*movdfcc_insn"
-;  [(set (match_operand:DF 0 "register_operand" "=r,r")
-;	(if_then_else:DF (match_operand 1 "comparison_operator" "")
-;			 (match_operand:DF 2 "nonmemory_operand" "r,E")
-;			 (match_operand:DF 3 "register_operand" "0,0")))]
-;  "0"
-;  "*
-;{
-;  switch (which_alternative)
-;    {
-;    case 0 :
-;      /* We normally copy the low-numbered register first.  However, if
-;	 the first register operand 0 is the same as the second register of
-;	 operand 1, we must copy in the opposite order.  */
-;      if (REGNO (operands[0]) == REGNO (operands[2]) + 1)
-;	return \"mov.%d1 %R0,%R2\;mov.%d1 %0,%2\";
-;      else
-;	return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\";
-;    case 1 :
-;      return \"mov.%d1 %0,%L2\;mov.%d1 %R0,%H2 ; %A2\";
-;    }
-;}"
-;  [(set_attr "type" "cmove,cmove")
-;   (set_attr "length" "2,4")])
 
 ;; Zero extension instructions.
 ;; ??? We don't support volatile memrefs here, but I'm not sure why.
@@ -1156,22 +1070,6 @@
 ;; Compare instructions.
 ;; This controls RTL generation and register allocation.
 
-;; We generate RTL for comparisons and branches by having the cmpxx 
-;; patterns store away the operands.  Then, the scc and bcc patterns
-;; emit RTL for both the compare and the branch.
-
-(define_expand "cmpsi"
-  [(set (reg:CC 61)
-	(compare:CC (match_operand:SI 0 "register_operand" "")
-		    (match_operand:SI 1 "nonmemory_operand" "")))]
-  ""
-  "
-{
-  arc_compare_op0 = operands[0];
-  arc_compare_op1 = operands[1];
-  DONE;
-}")
-
 ;; ??? We may be able to relax this a bit by adding a new constant 'K' for 0.
 ;; This assumes sub.f 0,symbol,0 is a valid insn.
 ;; Note that "sub.f 0,r0,1" is an 8 byte insn.  To avoid unnecessarily
@@ -1211,96 +1109,25 @@
    sub.f 0,%0,%1"
   [(set_attr "type" "compare,compare,compare")])
 
-;; Next come the scc insns.
-
-(define_expand "seq"
-  [(set (match_operand:SI 0 "register_operand" "=r")
-	(eq:SI (match_dup 1) (const_int 0)))]
-  ""
-  "
-{
-  operands[1] = gen_compare_reg (EQ, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "sne"
-  [(set (match_operand:SI 0 "register_operand" "=r")
-	(ne:SI (match_dup 1) (const_int 0)))]
-  ""
-  "
-{
-  operands[1] = gen_compare_reg (NE, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "sgt"
-  [(set (match_operand:SI 0 "register_operand" "=r")
-	(gt:SI (match_dup 1) (const_int 0)))]
-  ""
-  "
-{
-  operands[1] = gen_compare_reg (GT, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "sle"
-  [(set (match_operand:SI 0 "register_operand" "=r")
-	(le:SI (match_dup 1) (const_int 0)))]
-  ""
-  "
-{
-  operands[1] = gen_compare_reg (LE, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "sge"
-  [(set (match_operand:SI 0 "register_operand" "=r")
-	(ge:SI (match_dup 1) (const_int 0)))]
-  ""
-  "
-{
-  operands[1] = gen_compare_reg (GE, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "slt"
-  [(set (match_operand:SI 0 "register_operand" "=r")
-	(lt:SI (match_dup 1) (const_int 0)))]
-  ""
-  "
-{
-  operands[1] = gen_compare_reg (LT, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "sgtu"
-  [(set (match_operand:SI 0 "register_operand" "=r")
-	(gtu:SI (match_dup 1) (const_int 0)))]
-  ""
-  "
-{
-  operands[1] = gen_compare_reg (GTU, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "sleu"
-  [(set (match_operand:SI 0 "register_operand" "=r")
-	(leu:SI (match_dup 1) (const_int 0)))]
-  ""
-  "
-{
-  operands[1] = gen_compare_reg (LEU, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "sgeu"
-  [(set (match_operand:SI 0 "register_operand" "=r")
-	(geu:SI (match_dup 1) (const_int 0)))]
-  ""
-  "
-{
-  operands[1] = gen_compare_reg (GEU, arc_compare_op0, arc_compare_op1);
-}")
+;; Next come the scc insn and its expander.
 
-(define_expand "sltu"
-  [(set (match_operand:SI 0 "register_operand" "=r")
-	(ltu:SI (match_dup 1) (const_int 0)))]
+(define_expand "cstoresi4"
+  [(set (match_dup 4)
+        (match_op_dup 5
+         [(match_operand:SI 2 "register_operand" "")
+          (match_operand:SI 3 "nonmemory_operand" "")]))
+   (set (match_operand:SI 0 "register_operand")
+        (match_operator:SI 1 "ordered_comparison_operator"
+	 [(match_dup 4)
+	  (const_int 0)]))]
   ""
   "
 {
-  operands[1] = gen_compare_reg (LTU, arc_compare_op0, arc_compare_op1);
+  operands[4] = gen_compare_reg (GET_CODE (operands[1]),
+				 operands[2], operands[3]);
+  operands[5] = gen_rtx_fmt_ee (COMPARE,
+				GET_MODE (operands[4]),
+				operands[2], operands[3]);
 }")
 
 (define_insn "*scc_insn"
@@ -1332,114 +1159,26 @@
 
 ;; These control RTL generation for conditional jump insns
 
-(define_expand "beq"
-  [(set (pc)
-	(if_then_else (eq (match_dup 1) (const_int 0))
-		      (label_ref (match_operand 0 "" ""))
-		      (pc)))]
-  ""
-  "
-{
-  operands[1] = gen_compare_reg (EQ, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "bne"
-  [(set (pc)
-	(if_then_else (ne (match_dup 1) (const_int 0))
-		      (label_ref (match_operand 0 "" ""))
-		      (pc)))]
-  ""
-  "
-{
-  operands[1] = gen_compare_reg (NE, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "bgt"
-  [(set (pc)
-	(if_then_else (gt (match_dup 1) (const_int 0))
-		      (label_ref (match_operand 0 "" ""))
-		      (pc)))]
-  ""
-  "
-{
-  operands[1] = gen_compare_reg (GT, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "ble"
-  [(set (pc)
-	(if_then_else (le (match_dup 1) (const_int 0))
-		      (label_ref (match_operand 0 "" ""))
-		      (pc)))]
-  ""
-  "
-{
-  operands[1] = gen_compare_reg (LE, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "bge"
-  [(set (pc)
-	(if_then_else (ge (match_dup 1) (const_int 0))
-		      (label_ref (match_operand 0 "" ""))
-		      (pc)))]
-  ""
-  "
-{
-  operands[1] = gen_compare_reg (GE, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "blt"
-  [(set (pc)
-	(if_then_else (lt (match_dup 1) (const_int 0))
-		      (label_ref (match_operand 0 "" ""))
-		      (pc)))]
-  ""
-  "
-{
-  operands[1] = gen_compare_reg (LT, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "bgtu"
-  [(set (pc)
-	(if_then_else (gtu (match_dup 1) (const_int 0))
-		      (label_ref (match_operand 0 "" ""))
-		      (pc)))]
-  ""
-  "
-{
-  operands[1] = gen_compare_reg (GTU, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "bleu"
-  [(set (pc)
-	(if_then_else (leu (match_dup 1) (const_int 0))
-		      (label_ref (match_operand 0 "" ""))
-		      (pc)))]
-  ""
-  "
-{
-  operands[1] = gen_compare_reg (LEU, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "bgeu"
-  [(set (pc)
-	(if_then_else (geu (match_dup 1) (const_int 0))
-		      (label_ref (match_operand 0 "" ""))
-		      (pc)))]
-  ""
-  "
-{
-  operands[1] = gen_compare_reg (GEU, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "bltu"
-  [(set (pc)
-	(if_then_else (ltu (match_dup 1) (const_int 0))
-		      (label_ref (match_operand 0 "" ""))
-		      (pc)))]
+(define_expand "cbranchsi4"
+  [(set (match_dup 4)
+        (match_op_dup 5
+	 [(match_operand:SI 1 "register_operand" "")
+          (match_operand:SI 2 "nonmemory_operand" "")]))
+   (set (pc)
+        (if_then_else
+              (match_operator 0 "ordered_comparison_operator"
+	       [(match_dup 4)
+		(const_int 0)])
+              (label_ref (match_operand 3 "" ""))
+              (pc)))]
   ""
   "
 {
-  operands[1] = gen_compare_reg (LTU, arc_compare_op0, arc_compare_op1);
+  operands[4] = gen_compare_reg (GET_CODE (operands[0]),
+				 operands[1], operands[2]);
+  operands[5] = gen_rtx_fmt_ee (COMPARE,
+				GET_MODE (operands[4]),
+				operands[1], operands[2]);
 }")
 
 ;; Now match both normal and inverted jump.
Index: gcc/config/arc/arc.c
===================================================================
--- gcc/config/arc/arc.c	(branch cond-optab)
+++ gcc/config/arc/arc.c	(working copy)
@@ -49,10 +49,6 @@ int arc_cpu_type;
    cpu (or NULL).  */
 const char *arc_mangle_cpu;
 
-/* Save the operands last given to a compare for use when we
-   generate a scc or bcc insn.  */
-rtx arc_compare_op0, arc_compare_op1;
-
 /* Name of text, data, and rodata sections used in varasm.c.  */
 const char *arc_text_section;
 const char *arc_data_section;
@@ -729,21 +725,14 @@ proper_comparison_operator (rtx op, enum
 
 /* Misc. utilities.  */
 
-/* X and Y are two things to compare using CODE.  Emit the compare insn and
-   return the rtx for the cc reg in the proper mode.  */
+/* X and Y are two things to compare using CODE.  Return the rtx
+   for the cc reg in the proper mode.  */
 
 rtx
 gen_compare_reg (enum rtx_code code, rtx x, rtx y)
 {
   enum machine_mode mode = SELECT_CC_MODE (code, x, y);
-  rtx cc_reg;
-
-  cc_reg = gen_rtx_REG (mode, 61);
-
-  emit_insn (gen_rtx_SET (VOIDmode, cc_reg,
-			  gen_rtx_COMPARE (mode, x, y)));
-
-  return cc_reg;
+  return gen_rtx_REG (mode, 61);
 }
 
 /* Return 1 if VALUE, a const_double, will fit in a limm (4 byte number).
Index: gcc/config/arc/arc.h
===================================================================
--- gcc/config/arc/arc.h	(branch cond-optab)
+++ gcc/config/arc/arc.h	(working copy)
@@ -1071,11 +1071,6 @@ do { if ((LOG) != 0) fprintf (FILE, "\t.
 /* ??? Not defined in tm.texi.  */
 #define SETJMP_VIA_SAVE_AREA
 
-/* Define the information needed to generate branch and scc insns.  This is
-   stored from the compare operation.  Note that we can't use "rtx" here
-   since it hasn't been defined!  */
-extern struct rtx_def *arc_compare_op0, *arc_compare_op1;
-
 /* ARC function types.  */
 enum arc_function_type {
   ARC_FUNCTION_UNKNOWN, ARC_FUNCTION_NORMAL,


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