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 avr


AVR is a cc0 target, so it requires a bit more care to synthesize tst
instructions properly.

The only differences I am getting are some replacements of a "sbrc/sbrs 7"
and "rjmp" pair with "tst" and "brge/brlt", which I think is good.

Paolo

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

	* config/avr/avr-protos.h (out_tstsi, out_tsthi): Adjust prototype.
	* config/avr/avr.c (out_tstsi, out_tsthi): Get the tested operand
	as an argument.
	(adjust_insn_length): Adjust calls.
	(avr_reorg): Handle (compare (foo) (const_int 0)).
	* config/avr/avr.md (tstqi, tsthi, tstsi): Remove.
	(*negated_tstqi, *negated_tsthi, *negated_tstsi): Unmacroize.
	(*reversed_tsthi, *reversed_tstsi): Add a scratch for simplicity.
	(cmpqi, cmphi, cmpsi): Prepend asterisk, fuse tst[qhs]i here.
	(bCC): Remove.
	(cbranchqi4, cbranchhi4, cbranchsi4): New.
	(cpse peephole): Match (compare (foo) (const_int 0)).

Index: gcc/config/avr/avr-protos.h
===================================================================
--- gcc/config/avr/avr-protos.h	(branch cond-optab)
+++ gcc/config/avr/avr-protos.h	(working copy)
@@ -70,8 +70,8 @@ extern const char *out_movhi_mr_r (rtx i
 extern const char *out_movsi_r_mr (rtx insn, rtx op[], int *l);
 extern const char *out_movsi_mr_r (rtx insn, rtx op[], int *l);
 extern const char *output_movsisf (rtx insn, rtx operands[], int *l);
-extern const char *out_tstsi (rtx insn, int *l);
-extern const char *out_tsthi (rtx insn, int *l);
+extern const char *out_tstsi (rtx insn, rtx src, int *l);
+extern const char *out_tsthi (rtx insn, rtx src, int *l);
 extern const char *ret_cond_branch (rtx x, int len, int reverse);
 
 extern const char *ashlqi3_out (rtx insn, rtx operands[], int *len);
Index: gcc/config/avr/avr.c
===================================================================
--- gcc/config/avr/avr.c	(branch cond-optab)
+++ gcc/config/avr/avr.c	(working copy)
@@ -2899,21 +2899,21 @@ compare_eq_p (rtx insn)
 /* Output test instruction for HImode.  */
 
 const char *
-out_tsthi (rtx insn, int *l)
+out_tsthi (rtx insn, rtx op, int *l)
 {
   if (compare_sign_p (insn))
     {
       if (l) *l = 1;
       return AS1 (tst,%B0);
     }
-  if (reg_unused_after (insn, SET_SRC (PATTERN (insn)))
+  if (reg_unused_after (insn, op)
       && compare_eq_p (insn))
     {
       /* Faster than sbiw if we can clobber the operand.  */
       if (l) *l = 1;
       return AS2 (or,%A0,%B0);
     }
-  if (test_hard_reg_class (ADDW_REGS, SET_SRC (PATTERN (insn))))
+  if (test_hard_reg_class (ADDW_REGS, op))
     {
       if (l) *l = 1;
       return AS2 (sbiw,%0,0);
@@ -2927,14 +2927,14 @@ out_tsthi (rtx insn, int *l)
 /* Output test instruction for SImode.  */
 
 const char *
-out_tstsi (rtx insn, int *l)
+out_tstsi (rtx insn, rtx op, int *l)
 {
   if (compare_sign_p (insn))
     {
       if (l) *l = 1;
       return AS1 (tst,%D0);
     }
-  if (test_hard_reg_class (ADDW_REGS, SET_SRC (PATTERN (insn))))
+  if (test_hard_reg_class (ADDW_REGS, op))
     {
       if (l) *l = 3;
       return (AS2 (sbiw,%A0,0) CR_TAB
@@ -4351,8 +4351,8 @@ adjust_insn_length (rtx insn, int len)
 	{
 	  switch (GET_MODE (op[1]))
 	    {
-	    case HImode: out_tsthi (insn,&len); break;
-	    case SImode: out_tstsi (insn,&len); break;
+	    case HImode: out_tsthi (insn, op[1], &len); break;
+	    case SImode: out_tstsi (insn, op[1], &len); break;
 	    default: break;
 	    }
 	}
@@ -5711,6 +5711,21 @@ avr_reorg (void)
 		  XEXP (pattern,1) = x;
 		  INSN_CODE (next) = -1;
 		}
+	      else if (true_regnum (XEXP (pattern, 0)) >= 0
+		       && XEXP (pattern, 1) == const0_rtx)
+	        {
+	          /* This is a tst insn, we can reverse it.  */
+	          rtx next = next_real_insn (insn);
+	          rtx pat = PATTERN (next);
+	          rtx src = SET_SRC (pat);
+	          rtx t = XEXP (src,0);
+    
+	          PUT_CODE (t, swap_condition (GET_CODE (t)));
+	          XEXP (pattern, 1) = XEXP (pattern, 0);
+	          XEXP (pattern, 0) = const0_rtx;
+	          INSN_CODE (next) = -1;
+	          INSN_CODE (insn) = -1;
+	        }
 	      else if (true_regnum (XEXP (pattern,0)) >= 0
 		       && GET_CODE (XEXP (pattern,1)) == CONST_INT)
 		{
@@ -5730,20 +5745,6 @@ avr_reorg (void)
 		    }
 		}
 	    }
-	  else if (true_regnum (SET_SRC (pattern)) >= 0)
-	    {
-	      /* This is a tst insn */
-	      rtx next = next_real_insn (insn);
-	      rtx pat = PATTERN (next);
-	      rtx src = SET_SRC (pat);
-	      rtx t = XEXP (src,0);
-
-	      PUT_CODE (t, swap_condition (GET_CODE (t)));
-	      SET_SRC (pattern) = gen_rtx_COMPARE (GET_MODE (SET_SRC (pattern)), const0_rtx,
-					       SET_SRC (pattern));
-	      INSN_CODE (next) = -1;
-	      INSN_CODE (insn) = -1;
-	    }
 	}
     }
 }
Index: gcc/config/avr/avr.md
===================================================================
--- gcc/config/avr/avr.md	(branch cond-optab)
+++ gcc/config/avr/avr.md	(working copy)
@@ -2165,53 +2165,65 @@
 ;;<=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=>
 ;; compare
 
-(define_insn "tstqi"
+; Optimize negated tests into reverse compare if overflow is undefined.
+(define_insn "*negated_tstqi"
   [(set (cc0)
-        (match_operand:QI 0 "register_operand" "r"))]
-  ""
-  "tst %0"
+        (compare (neg:QI (match_operand:QI 0 "register_operand" "r"))
+		 (const_int 0)))]
+  "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
+  "cp __zero_reg__,%0"
   [(set_attr "cc" "compare")
    (set_attr "length" "1")])
 
 (define_insn "*reversed_tstqi"
   [(set (cc0)
-        (compare (const_int 0)  
+        (compare (const_int 0)
 		 (match_operand:QI 0 "register_operand" "r")))]
   ""
   "cp __zero_reg__,%0"
-  [(set_attr "cc" "compare")
-   (set_attr "length" "1")])
+[(set_attr "cc" "compare")
+ (set_attr "length" "2")])
 
-(define_insn "tsthi"
+(define_insn "*negated_tsthi"
   [(set (cc0)
-        (match_operand:HI 0 "register_operand" "!w,r"))]
-  ""
-  "* return out_tsthi (insn,NULL);"
-[(set_attr "cc" "compare,compare")
- (set_attr "length" "1,2")])
+        (compare (neg:HI (match_operand:HI 0 "register_operand" "r"))
+		 (const_int 0)))]
+  "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
+  "cp __zero_reg__,%A0
+	cpc __zero_reg__,%B0"
+[(set_attr "cc" "compare")
+ (set_attr "length" "2")])
 
+;; Leave here the clobber used by the cmphi pattern for simplicity, even
+;; though it is unused, because this pattern is synthesized by avr_reorg.
 (define_insn "*reversed_tsthi"
   [(set (cc0)
         (compare (const_int 0)
-		 (match_operand:HI 0 "register_operand" "r")))]
+		 (match_operand:HI 0 "register_operand" "r")))
+   (clobber (match_scratch:QI 1 "=X"))]
   ""
   "cp __zero_reg__,%A0
 	cpc __zero_reg__,%B0"
 [(set_attr "cc" "compare")
  (set_attr "length" "2")])
 
-(define_insn "tstsi"
+(define_insn "*negated_tstsi"
   [(set (cc0)
-        (match_operand:SI 0 "register_operand" "r"))]
-  ""
-  "* return out_tstsi (insn,NULL);"
+        (compare (neg:SI (match_operand:SI 0 "register_operand" "r"))
+		 (const_int 0)))]
+  "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
+  "cp __zero_reg__,%A0
+	cpc __zero_reg__,%B0
+	cpc __zero_reg__,%C0
+	cpc __zero_reg__,%D0"
   [(set_attr "cc" "compare")
    (set_attr "length" "4")])
 
 (define_insn "*reversed_tstsi"
   [(set (cc0)
-        (compare (const_int 0)  
-		 (match_operand:SI 0 "register_operand" "r")))]
+        (compare (const_int 0)
+		 (match_operand:SI 0 "register_operand" "r")))
+   (clobber (match_scratch:QI 1 "=X"))]
   ""
   "cp __zero_reg__,%A0
 	cpc __zero_reg__,%B0
@@ -2221,16 +2233,17 @@
    (set_attr "length" "4")])
 
 
-(define_insn "cmpqi"
+(define_insn "*cmpqi"
   [(set (cc0)
-        (compare (match_operand:QI 0 "register_operand"  "r,d")
-		 (match_operand:QI 1 "nonmemory_operand" "r,i")))]
+        (compare (match_operand:QI 0 "register_operand"  "r,r,d")
+		 (match_operand:QI 1 "nonmemory_operand" "L,r,i")))]
   ""
   "@
+	tst %0
 	cp %0,%1
 	cpi %0,lo8(%1)"
-  [(set_attr "cc" "compare,compare")
-   (set_attr "length" "1,1")])
+  [(set_attr "cc" "compare,compare,compare")
+   (set_attr "length" "1,1,1")])
 
 (define_insn "*cmpqi_sign_extend"
   [(set (cc0)
@@ -2242,19 +2255,22 @@
   [(set_attr "cc" "compare")
    (set_attr "length" "1")])
 
-(define_insn "cmphi"
+(define_insn "*cmphi"
   [(set (cc0)
-	(compare (match_operand:HI 0 "register_operand"  "r,d,d,r,r")
-		 (match_operand:HI 1 "nonmemory_operand" "r,M,i,M,i")))
-   (clobber (match_scratch:QI 2 "=X,X,&d,&d,&d"))]
+	(compare (match_operand:HI 0 "register_operand"  "!w,r,r,d,d,r,r")
+		 (match_operand:HI 1 "nonmemory_operand" "L,L,r,M,i,M,i")))
+   (clobber (match_scratch:QI 2 "=X,X,X,X,&d,&d,&d"))]
   ""
   "*{
   switch (which_alternative)
     {
-    case 0:
+    case 0: case 1:
+      return out_tsthi (insn, operands[0], NULL);
+
+    case 2:
       return (AS2 (cp,%A0,%A1) CR_TAB
               AS2 (cpc,%B0,%B1));
-    case 1:
+    case 3:
       if (reg_unused_after (insn, operands[0])
           && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 63
           && test_hard_reg_class (ADDW_REGS, operands[0]))
@@ -2262,7 +2278,7 @@
        else
         return (AS2 (cpi,%0,%1) CR_TAB
                 AS2 (cpc,%B0,__zero_reg__));
-    case 2:
+    case 4:
       if (reg_unused_after (insn, operands[0]))
         return (AS2 (subi,%0,lo8(%1))  CR_TAB
                 AS2 (sbci,%B0,hi8(%1)));
@@ -2270,12 +2286,12 @@
         return (AS2 (ldi, %2,hi8(%1))  CR_TAB
 	        AS2 (cpi, %A0,lo8(%1)) CR_TAB
 	        AS2 (cpc, %B0,%2));
-   case 3:
+   case 5:
       return (AS2 (ldi, %2,lo8(%1))  CR_TAB
 	      AS2 (cp, %A0,%2) CR_TAB
 	      AS2 (cpc, %B0,__zero_reg__));
 
-   case 4:
+   case 6:
       return (AS2 (ldi, %2,lo8(%1))  CR_TAB
               AS2 (cp, %A0,%2)       CR_TAB
               AS2 (ldi, %2,hi8(%1)) CR_TAB
@@ -2283,25 +2299,28 @@
     }
   return \"bug\";
 }" 
-  [(set_attr "cc" "compare,compare,compare,compare,compare")
-   (set_attr "length" "2,2,3,3,4")])
+  [(set_attr "cc" "compare,compare,compare,compare,compare,compare,compare")
+   (set_attr "length" "1,2,2,2,3,3,4")])
 
 
-(define_insn "cmpsi"
+(define_insn "*cmpsi"
   [(set (cc0)
-	(compare (match_operand:SI 0 "register_operand"  "r,d,d,r,r")
-		 (match_operand:SI 1 "nonmemory_operand" "r,M,i,M,i")))
-   (clobber (match_scratch:QI 2 "=X,X,&d,&d,&d"))]
+	(compare (match_operand:SI 0 "register_operand"  "r,r,d,d,r,r")
+		 (match_operand:SI 1 "nonmemory_operand" "L,r,M,i,M,i")))
+   (clobber (match_scratch:QI 2 "=X,X,X,&d,&d,&d"))]
   ""
   "*{
   switch (which_alternative)
     {
     case 0:
+      return out_tstsi (insn, operands[0], NULL);
+
+    case 1:
       return (AS2 (cp,%A0,%A1) CR_TAB
               AS2 (cpc,%B0,%B1) CR_TAB
 	      AS2 (cpc,%C0,%C1) CR_TAB
 	      AS2 (cpc,%D0,%D1));
-    case 1:
+    case 2:
       if (reg_unused_after (insn, operands[0])
           && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 63
           && test_hard_reg_class (ADDW_REGS, operands[0]))
@@ -2313,7 +2332,7 @@
                 AS2 (cpc,%B0,__zero_reg__) CR_TAB
                 AS2 (cpc,%C0,__zero_reg__) CR_TAB
                 AS2 (cpc,%D0,__zero_reg__));
-    case 2:
+    case 3:
       if (reg_unused_after (insn, operands[0]))
         return (AS2 (subi,%A0,lo8(%1))  CR_TAB
                 AS2 (sbci,%B0,hi8(%1))  CR_TAB
@@ -2327,13 +2346,13 @@
 	       AS2 (cpc, %C0,%2)       CR_TAB
 	       AS2 (ldi, %2,hhi8(%1)) CR_TAB
 	       AS2 (cpc, %D0,%2));
-    case 3:
+    case 4:
         return (AS2 (ldi,%2,lo8(%1))        CR_TAB
                 AS2 (cp,%A0,%2)            CR_TAB
                 AS2 (cpc,%B0,__zero_reg__) CR_TAB
                 AS2 (cpc,%C0,__zero_reg__) CR_TAB
                 AS2 (cpc,%D0,__zero_reg__));
-    case 4:
+    case 5:
        return (AS2 (ldi, %2,lo8(%1))   CR_TAB
                AS2 (cp, %A0,%2)        CR_TAB
 	       AS2 (ldi, %2,hi8(%1))  CR_TAB
@@ -2345,113 +2364,53 @@
     }
   return \"bug\";
 }"
-  [(set_attr "cc" "compare,compare,compare,compare,compare")
-   (set_attr "length" "4,4,7,5,8")])
-
-; Optimize negated tests into reverse compare if overflow is undefined.
-(define_insn_and_split "negated_tst<mode>"
- [(set (cc0)
-        (neg:QISI (match_operand:QISI 0 "register_operand")))]
+  [(set_attr "cc" "compare,compare,compare,compare,compare,compare")
+   (set_attr "length" "4,4,4,7,5,8")])
 
-  "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
-  "#"
-  ""
-  [(set (cc0)
-        (compare (const_int 0)  
-		 (match_dup 0)))]
-  "")
 
 ;; ----------------------------------------------------------------------
 ;; JUMP INSTRUCTIONS
 ;; ----------------------------------------------------------------------
 ;; Conditional jump instructions
 
-(define_expand "beq"
-  [(set (pc)
-        (if_then_else (eq (cc0) (const_int 0))
-                      (label_ref (match_operand 0 "" ""))
-                      (pc)))]
-  ""
-  "")
-
-(define_expand "bne"
-  [(set (pc)
-        (if_then_else (ne (cc0) (const_int 0))
-                      (label_ref (match_operand 0 "" ""))
-                      (pc)))]
-  ""
-  "")
-
-(define_expand "bge"
-  [(set (pc)
-        (if_then_else (ge (cc0) (const_int 0))
-                      (label_ref (match_operand 0 "" ""))
-                      (pc)))]
-  ""
-  "")
-
-(define_expand "bgeu"
-  [(set (pc)
-        (if_then_else (geu (cc0) (const_int 0))
-                      (label_ref (match_operand 0 "" ""))
-                      (pc)))]
-  ""
-  "")
-
-(define_expand "blt"
-  [(set (pc)
-        (if_then_else (lt (cc0) (const_int 0))
-                      (label_ref (match_operand 0 "" ""))
-                      (pc)))]
-  ""
-  "")
-
-(define_expand "bltu"
-  [(set (pc)
-        (if_then_else (ltu (cc0) (const_int 0))
-                      (label_ref (match_operand 0 "" ""))
-                      (pc)))]
-  ""
-  "")
-
-
-
-/****************************************************************
- AVR not have following conditional jumps: LE,LEU,GT,GTU.
- Convert them all to proper jumps.
-*****************************************************************/
-
-(define_expand "ble"
-  [(set (pc)
-        (if_then_else (le (cc0) (const_int 0))
-                      (label_ref (match_operand 0 "" ""))
-                      (pc)))]
-  ""
-  "")
-
-(define_expand "bleu"
-  [(set (pc)
-        (if_then_else (leu (cc0) (const_int 0))
-                      (label_ref (match_operand 0 "" ""))
-                      (pc)))]
-  ""
-  "")
+(define_expand "cbranchsi4"
+  [(parallel [(set (cc0)
+	           (compare (match_operand:SI 1 "register_operand" "")
+	                    (match_operand:SI 2 "nonmemory_operand" "")))
+	      (clobber (match_scratch:QI 4 ""))])
+   (set (pc)
+        (if_then_else
+              (match_operator 0 "ordered_comparison_operator" [(cc0)
+                                                               (const_int 0)])
+              (label_ref (match_operand 3 "" ""))
+              (pc)))]
+ "")
+
+(define_expand "cbranchhi4"
+  [(parallel [(set (cc0)
+	           (compare (match_operand:HI 1 "register_operand" "")
+	                    (match_operand:HI 2 "nonmemory_operand" "")))
+	      (clobber (match_scratch:QI 4 ""))])
+   (set (pc)
+        (if_then_else
+              (match_operator 0 "ordered_comparison_operator" [(cc0)
+                                                               (const_int 0)])
+              (label_ref (match_operand 3 "" ""))
+              (pc)))]
+ "")
 
-(define_expand "bgt"
-  [(set (pc)
-        (if_then_else (gt (cc0) (const_int 0))
-                      (label_ref (match_operand 0 "" ""))
-                      (pc)))]
-  ""
-  "")
+(define_expand "cbranchqi4"
+  [(set (cc0)
+        (compare (match_operand:QI 1 "register_operand" "")
+                 (match_operand:QI 2 "nonmemory_operand" "")))
+   (set (pc)
+        (if_then_else
+              (match_operator 0 "ordered_comparison_operator" [(cc0)
+                                                               (const_int 0)])
+              (label_ref (match_operand 3 "" ""))
+              (pc)))]
+ "")
 
-(define_expand "bgtu"
-  [(set (pc)
-        (if_then_else (gtu (cc0) (const_int 0))
-                      (label_ref (match_operand 0 "" ""))
-                      (pc)))]
-  ""
-  "")
 
 ;; Test a single bit in a QI/HI/SImode register.
 (define_insn "*sbrx_branch"
@@ -2613,6 +2572,11 @@
   [(set_attr "type" "branch")
    (set_attr "cc" "clobber")])
 
+;; ****************************************************************
+;; AVR does not have following conditional jumps: LE,LEU,GT,GTU.
+;; Convert them all to proper jumps.
+;; ****************************************************************/
+
 (define_insn "difficult_branch"
   [(set (pc)
         (if_then_else (match_operator 1 "difficult_comparison_operator"
@@ -3113,7 +3077,9 @@
 }")
 
 (define_peephole
-  [(set (cc0) (match_operand:QI 0 "register_operand" ""))
+  [(set (cc0)
+	(compare (match_operand:QI 0 "register_operand" "")
+		 (const_int 0)))
    (set (pc)
 	(if_then_else (eq (cc0) (const_int 0))
 		      (label_ref (match_operand 1 "" ""))


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