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]

[PATCH]: Optimize tst/cmp instructions for HC11/HC12


Hi!

The following patch optimizes the code for test and compare for 68hc11/hc12.

I've committed this on 3_1 branch and mainline.

	Stephane

2002-03-15  Stephane Carrez  <Stephane.Carrez@worldnet.fr>

	* config/m68hc11/m68hc11.md ("tstqi_1"): Try to use ldab instead of tst.
	("tstqi" split): Avoid using memory for tstqi on address register.
	(splits): Remove constraints.
	("cmphi_1_hc12"): New from "cmphi_1" and tuned for 68HC12.
	("cmpdf", "cmpsf"): Remove since not used.
	("*tbeq", "*tbne", "*tbeq8", "*tbne8"): Also look in cc_status.value2.
	(peephole2): New peepholes to optimize tstqi and pre inc/dec addressing.
Index: config/m68hc11/m68hc11.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/m68hc11/m68hc11.md,v
retrieving revision 1.26
diff -u -p -r1.26 m68hc11.md
--- m68hc11.md	2002/03/15 22:22:56	1.26
+++ m68hc11.md	2002/03/15 22:31:00
@@ -204,28 +204,37 @@
 
 ;;
 ;; Split pattern for (tst:QI) on an address register.
-;; The value is saved in memory and we test the low part only.
 ;;
 (define_split
   [(set (cc0)
-	(match_operand:QI 0 "hard_addr_reg_operand" "xy"))]
+	(match_operand:QI 0 "hard_addr_reg_operand" ""))]
   "z_replacement_completed == 2 && GET_MODE (operands[0]) == QImode"
-  [(set (match_dup 3) (match_dup 2))
-   (set (cc0) (match_dup 4))]
-  "operands[2] = gen_rtx (REG, HImode, REGNO (operands[0]));
-   operands[3] = gen_rtx (REG, HImode, SOFT_TMP_REGNUM);
-   operands[4] = gen_rtx (REG, QImode, SOFT_TMP_REGNUM);")
+  [(parallel [(set (reg:HI D_REGNUM) (match_dup 1))
+	      (set (match_dup 1) (reg:HI D_REGNUM))])
+   (set (cc0) (reg:QI D_REGNUM))
+   (parallel [(set (reg:HI D_REGNUM) (match_dup 1))
+	      (set (match_dup 1) (reg:HI D_REGNUM))])]
+  "operands[1] = gen_rtx (REG, HImode, REGNO (operands[0]));")
 
 (define_insn "tstqi_1"
   [(set (cc0)
 	(match_operand:QI 0 "tst_operand" "m,d,*A,!u"))]
   ""
-  "@
-   tst\\t%0
-   tstb
-   #
-   tst\\t%b0")
+  "*
+{
+  if (A_REG_P (operands[0]))
+    return \"#\";
+
+  else if (D_REG_P (operands[0]))
+    return \"tstb\";
+
+  else if (dead_register_here (insn, d_reg))
+    return \"ldab\\t%b0\";
 
+  else
+    return \"tst\\t%b0\";
+}")
+
 ;;
 ;; tstqi_z_used, cmpqi_z_used and cmphi_z_used are patterns generated 
 ;; during the Z register replacement.  They are used when an operand
@@ -247,8 +256,8 @@
 
 (define_split /* "tstqi_z_used" */
   [(set (cc0)
-	(match_operand:QI 0 "tst_operand" "m"))
-   (use (match_operand:HI 1 "hard_reg_operand" "dxy"))
+	(match_operand:QI 0 "tst_operand" ""))
+   (use (match_operand:HI 1 "hard_reg_operand" ""))
    (use (reg:HI 11))]
   "z_replacement_completed == 2"
   [(set (mem:HI (pre_dec:HI (reg:HI SP_REGNUM))) (match_dup 1))
@@ -288,8 +297,8 @@
 ;;
 (define_split
   [(set (cc0)
-	(compare (match_operand:HI 0 "hard_reg_operand" "dxy")
-		 (match_operand:HI 1 "hard_reg_operand" "Aw")))]
+	(compare (match_operand:HI 0 "hard_reg_operand" "")
+		 (match_operand:HI 1 "hard_reg_operand" "")))]
   "reload_completed"
   [(set (match_dup 2) (match_dup 1))
    (set (cc0)
@@ -311,13 +320,13 @@
   DONE;
 }")
 
-(define_insn "cmphi_1"
+(define_insn "cmphi_1_hc12"
   [(set (cc0)
 	(compare (match_operand:HI 0 "tst_operand" 
-				"x,dy,xyd,?xy,d,m,!u,dxy,dxy")
+				"d,?xy,xyd,?xy,d,m,!u,dxy,dxy")
 		 (match_operand:HI 1 "cmp_operand"
 				"i,i,!u,m,m,dxy,dxy,?*d*A,!*w")))]
-  ""
+  "TARGET_M6812"
   "*
 {
   if (H_REG_P (operands[1]) && !H_REG_P (operands[0]))
@@ -331,6 +340,26 @@
     return \"cp%0\\t%1\";
 }")
 
+(define_insn "cmphi_1_hc11"
+  [(set (cc0)
+	(compare (match_operand:HI 0 "tst_operand" 
+				"dx,y,xyd,?xy,d,m,!u,dxy,dxy")
+		 (match_operand:HI 1 "cmp_operand"
+				"i,i,!u,m,m,dxy,dxy,?*d*A,!*w")))]
+  "TARGET_M6811"
+  "*
+{
+  if (H_REG_P (operands[1]) && !H_REG_P (operands[0]))
+    {
+      cc_status.flags |= CC_REVERSED;
+      return \"cp%1\\t%0\";
+    }
+  else if (H_REG_P (operands[1]))
+    return \"#\";
+  else
+    return \"cp%0\\t%1\";
+}")
+
 (define_insn "cmphi_z_used"
   [(set (cc0)
 	(compare (match_operand:HI 0 "tst_operand" "dxy,m")
@@ -342,9 +371,9 @@
   
 (define_split /* "cmphi_z_used" */
   [(set (cc0)
-	(compare (match_operand:HI 0 "tst_operand" "dxy,m")
-		 (match_operand:HI 1 "cmp_operand" "m,dxy")))
-   (use (match_operand:HI 2 "hard_reg_operand" "dxy,dxy"))
+	(compare (match_operand:HI 0 "tst_operand" "")
+		 (match_operand:HI 1 "cmp_operand" "")))
+   (use (match_operand:HI 2 "hard_reg_operand" ""))
    (use (reg:HI 11))]
   "z_replacement_completed == 2"
   [(set (mem:HI (pre_dec:HI (reg:HI SP_REGNUM))) (match_dup 2))
@@ -361,8 +390,8 @@
 ;;
 (define_split
   [(set (cc0)
-	(compare (match_operand:QI 0 "hard_addr_reg_operand" "xy")
-		 (match_operand:QI 1 "cmp_operand" "uimA")))]
+	(compare (match_operand:QI 0 "hard_addr_reg_operand" "")
+		 (match_operand:QI 1 "cmp_operand" "")))]
   "z_replacement_completed == 2 && GET_MODE (operands[0]) == QImode"
   [(parallel [(set (reg:HI D_REGNUM) (match_dup 3))
               (set (match_dup 3) (reg:HI D_REGNUM))])
@@ -374,8 +403,8 @@
 
 (define_split
   [(set (cc0)
-	(compare (match_operand:QI 0 "hard_reg_operand" "dxy")
-		 (match_operand:QI 1 "hard_reg_operand" "dxy")))]
+	(compare (match_operand:QI 0 "hard_reg_operand" "")
+		 (match_operand:QI 1 "hard_reg_operand" "")))]
   "reload_completed"
   [(set (match_dup 3) (match_dup 4))
    (set (cc0)
@@ -413,8 +442,8 @@
 
 (define_split /* "bitcmpqi" */
   [(set (cc0)
-	(and:QI (match_operand:QI 0 "tst_operand" "d")
-		(match_operand:QI 1 "hard_addr_reg_operand" "xy")))]
+	(and:QI (match_operand:QI 0 "tst_operand" "")
+		(match_operand:QI 1 "hard_addr_reg_operand" "")))]
   "z_replacement_completed == 2 && GET_MODE (operands[0]) == QImode"
   [(set (match_dup 3) (match_dup 2))
    (set (cc0) (and:QI (match_dup 0) (match_dup 4)))]
@@ -433,9 +462,9 @@
   
 (define_split /* "bitcmpqi_z_used" */
   [(set (cc0)
-	(and:QI (match_operand:QI 0 "tst_operand" "d,m")
-		(match_operand:QI 1 "cmp_operand" "m,d")))
-   (use (match_operand:HI 2 "hard_reg_operand" "xy,xy"))
+	(and:QI (match_operand:QI 0 "tst_operand" "")
+		(match_operand:QI 1 "cmp_operand" "")))
+   (use (match_operand:HI 2 "hard_reg_operand" ""))
    (use (reg:HI 11))]
   "z_replacement_completed == 2"
   [(set (mem:HI (pre_dec:HI (reg:HI 3))) (match_dup 2))
@@ -534,30 +563,6 @@
    (set (match_dup 2) (mem:HI (post_inc:HI (reg:HI SP_REGNUM))))]
   "operands[3] = gen_rtx (REG, HImode, SOFT_Z_REGNUM);")
 
-(define_expand "cmpdf"
-  [(set (cc0)
-	(compare (match_operand:DF 0 "general_operand" "")
-		 (match_operand:DF 1 "general_operand" "")))]
-  "0"
-  "
-{
-  m68hc11_compare_op0 = operands[0];
-  m68hc11_compare_op1 = operands[1];
-  DONE;
-}")
-
-(define_expand "cmpsf"
-  [(set (cc0)
-	(compare (match_operand:SF 0 "general_operand" "")
-		 (match_operand:SF 1 "general_operand" "")))]
-  "0"
-  "
-{
-  m68hc11_compare_op0 = operands[0];
-  m68hc11_compare_op1 = operands[1];
-  DONE;
-}")
-
 ;;--------------------------------------------------------------------
 ;;-  Move strict_low_part
 ;;--------------------------------------------------------------------
@@ -5909,7 +5914,8 @@
       smaller and a little bit faster.  This happens quite often due
       to reloading of operands[0].  In that case, flags are set correctly
       due to the load instruction.  */
-  if (cc_status.value1 && rtx_equal_p (cc_status.value1, operands[0]))
+  if ((cc_status.value1 && rtx_equal_p (cc_status.value1, operands[0]))
+      || (cc_status.value2 && rtx_equal_p (cc_status.value2, operands[0])))
     return \"beq\\t%l1\";
   else
     return \"tbeq\\t%0,%l1\";
@@ -5924,7 +5930,8 @@
   "TARGET_M6812"
   "*
 {
-   if (cc_status.value1 && rtx_equal_p (cc_status.value1, operands[0]))
+   if ((cc_status.value1 && rtx_equal_p (cc_status.value1, operands[0]))
+       || (cc_status.value2 && rtx_equal_p (cc_status.value2, operands[0])))
      return \"bne\\t%l1\";
    else
      return \"tbne\\t%0,%l1\";
@@ -5942,7 +5949,8 @@
   "TARGET_M6812"
   "*
 {
-   if (cc_status.value1 && rtx_equal_p (cc_status.value1, operands[0]))
+   if ((cc_status.value1 && rtx_equal_p (cc_status.value1, operands[0]))
+       || (cc_status.value2 && rtx_equal_p (cc_status.value2, operands[0])))
      return \"beq\\t%l1\";
    else
      return \"tbeq\\tb,%l1\";
@@ -5957,7 +5965,8 @@
   "TARGET_M6812"
   "*
 {
-   if (cc_status.value1 && rtx_equal_p (cc_status.value1, operands[0]))
+   if ((cc_status.value1 && rtx_equal_p (cc_status.value1, operands[0]))
+       || (cc_status.value2 && rtx_equal_p (cc_status.value2, operands[0])))
      return \"bne\\t%l1\";
    else
      return \"tbne\\tb,%l1\";
@@ -6424,6 +6433,65 @@
   [(set (match_dup 0) (reg:HI SP_REGNUM))
    (set (match_dup 0) (plus:HI (match_dup 0) (match_dup 1)))]
   "")
+
+;;
+;; Remove a possible move before a compare instruction when that
+;; move will go in a dead register.  Compare with the source then.
+;;
+(define_peephole2
+  [(set (match_operand:HI 0 "hard_reg_operand" "")
+	(match_operand:HI 1 "hard_reg_operand" ""))
+   (set (cc0)
+	(compare (match_dup 0)
+	         (match_operand:HI 2 "cmp_operand" "")))]
+  "(X_REG_P (operands[1]) || Y_REG_P (operands[1]))
+   && peep2_reg_dead_p (2, operands[0])
+   && !reg_mentioned_p (operands[0], operands[2])"
+  [(set (cc0) (compare (match_dup 1) (match_dup 2)))]
+  "")
+
+;;
+;; Optimize an address register increment and a compare to use
+;; a PRE_INC or PRE_DEC addressing mode (disabled on the compare insn
+;; before reload, but can be enabled after).
+;;
+(define_peephole2
+  [(set (match_operand:HI 0 "hard_reg_operand" "")
+	(plus:HI (match_dup 0)
+	         (match_operand:HI 1 "const_int_operand" "")))
+   (set (cc0)
+	(compare (match_operand:QI 2 "hard_reg_operand" "")
+		 (match_operand:QI 3 "memory_operand" "")))]
+  "TARGET_AUTO_INC_DEC
+   && (INTVAL (operands[1]) == -1 || INTVAL (operands[1]) == 1)
+   && reg_mentioned_p (operands[0], operands[3])"
+  [(set (cc0) (compare (match_dup 2) (match_dup 4)))]
+  "if (INTVAL (operands[1]) == 1)
+     operands[4] = gen_rtx (MEM, QImode,
+			    gen_rtx (PRE_INC, HImode, operands[0]));
+   else
+     operands[4] = gen_rtx (MEM, QImode,
+			    gen_rtx (PRE_DEC, HImode, operands[0]));
+  ")
+
+(define_peephole2
+  [(set (match_operand:HI 0 "hard_reg_operand" "")
+	(plus:HI (match_dup 0)
+	         (match_operand:HI 1 "const_int_operand" "")))
+   (set (cc0)
+	(compare (match_operand:QI 2 "memory_operand" "")
+		 (match_operand:QI 3 "hard_reg_operand" "")))]
+  "TARGET_AUTO_INC_DEC
+   && (INTVAL (operands[1]) == -1 || INTVAL (operands[1]) == 1)
+   && reg_mentioned_p (operands[0], operands[2])"
+  [(set (cc0) (compare (match_dup 4) (match_dup 3)))]
+  "if (INTVAL (operands[1]) == 1)
+     operands[4] = gen_rtx (MEM, QImode,
+			    gen_rtx (PRE_INC, HImode, operands[0]));
+   else
+     operands[4] = gen_rtx (MEM, QImode,
+			    gen_rtx (PRE_DEC, HImode, operands[0]));
+  ")
 
 ;;
 ;; This peephole catches the address computations generated by the reload

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