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]

[committed] Consolidating various H8 patterns


Another round.

This merges the movmd/movsd related patterns.  Their primary difference
was normal vs advanced mode, so we can just use the P mode iterator and
significantly reduce duplication here.

This also merges two of the btst patterns and fixes the pattern's
condition.  This also allows the btst to be used more aggressively on
the H8/SX where we see minor improvements in the generated code.

The tstXX patterns get merged.  Sadly the way we use output modifiers to
print different registers is painful -- the more natural way would be to
define the modifier to print a register in the size of the operand.
Instead we have a distinct modifier for each size.  The port exploits
the sub-word addressibility in various places.  As a result we can't
combine the output templates as much as I'd like.  I'm pondering
cleaning that up as well.

There's a bit of merging of arithmetic patterns.  What probably gets in
the way most of the time is differing constraints or pattern conditions.
 The former are always a blocker.  The latter we can sometimes work
around (or as in the case of btst point to a minor goof).


Some of the length computations are table driven and were getting in the
way of merging patterns.  So rather than have a separate attributes for
addb, addw, addl length computation, we have a single attribute and
select the right table based on the size of the operand.


That's it until tonight...


Jeff
	* config/h8300/h8300.c (h8300_insn_length_from_table): Consolidate
	ADDB, ADDW and ADDL into a single ADD attribute which selects the
	right table based on the size of the operand.
	* config/h8300/h8300.md (length_table): Corresponding changes. All
	references to "addb", "addw" and "addl" changed to "add".
	(btst patterns): Merge two variants into a single pattern.
	(tstqi, tsthi): Likewise.
	(addhi3_incdec, addsi3_incdec): Likewise.
	(subhi3_h8300hs, subsi3_h8300hs): Likewise.
	(mulhi3, mulsi3): Likewise.
	(udivhi3, udivsi3): Likewise.
	(divhi3, divsi3): Likewise.
	(andorqi3, andorhi3, andorsi3): Likewise.

diff --git a/gcc/config/h8300/h8300.c b/gcc/config/h8300/h8300.c
index 697041e..01c765d 100644
--- a/gcc/config/h8300/h8300.c
+++ b/gcc/config/h8300/h8300.c
@@ -2551,14 +2551,14 @@ h8300_insn_length_from_table (rtx_insn *insn, rtx * operands)
     case LENGTH_TABLE_NONE:
       gcc_unreachable ();
 
-    case LENGTH_TABLE_ADDB:
-      return h8300_binary_length (insn, &addb_length_table);
-
-    case LENGTH_TABLE_ADDW:
-      return h8300_binary_length (insn, &addw_length_table);
-
-    case LENGTH_TABLE_ADDL:
-      return h8300_binary_length (insn, &addl_length_table);
+    case LENGTH_TABLE_ADD:
+      if (GET_MODE (operands[0]) == QImode)
+        return h8300_binary_length (insn, &addb_length_table);
+      else if (GET_MODE (operands[0]) == HImode)
+        return h8300_binary_length (insn, &addw_length_table);
+      else if (GET_MODE (operands[0]) == SImode)
+        return h8300_binary_length (insn, &addl_length_table);
+      gcc_unreachable ();
 
     case LENGTH_TABLE_LOGICB:
       return h8300_binary_length (insn, &logicb_length_table);
diff --git a/gcc/config/h8300/h8300.md b/gcc/config/h8300/h8300.md
index 6084240..e654784 100644
--- a/gcc/config/h8300/h8300.md
+++ b/gcc/config/h8300/h8300.md
@@ -77,7 +77,7 @@
 (define_attr "type" "branch,arith,bitbranch,call"
   (const_string "arith"))
 
-(define_attr "length_table" "none,addb,addw,addl,logicb,movb,movw,movl,mova_zero,mova,unary,mov_imm4,short_immediate,bitfield,bitbranch"
+(define_attr "length_table" "none,add,logicb,movb,movw,movl,mova_zero,mova,unary,mov_imm4,short_immediate,bitfield,bitbranch"
   (const_string "none"))
 
 ;; The size of instructions in bytes.
@@ -752,17 +752,6 @@
   [(set_attr "length" "2,4")
    (set_attr "cc" "set_zn,set_zn")])
 
-(define_insn ""
-  [(set (cc0)
-	(compare (zero_extract:HI (match_operand:HI 0 "register_operand" "r")
-				  (const_int 1)
-				  (match_operand 1 "const_int_operand" "n"))
-		 (const_int 0)))]
-  "TARGET_H8300"
-  "btst	%Z1,%Y0"
-  [(set_attr "length" "2")
-   (set_attr "cc" "set_zn")])
-
 (define_insn_and_split "*tst_extzv_1_n"
   [(set (cc0)
 	(compare (zero_extract:SI (match_operand:QI 0 "general_operand_src" "r,U,mn>")
@@ -790,11 +779,11 @@
 
 (define_insn ""
   [(set (cc0)
-	(compare (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
-				  (const_int 1)
-				  (match_operand 1 "const_int_operand" "n"))
+	(compare (zero_extract:HSI (match_operand:HSI 0 "register_operand" "r")
+				   (const_int 1)
+				   (match_operand 1 "const_int_operand" "n"))
 		 (const_int 0)))]
-  "(TARGET_H8300H || TARGET_H8300S)
+  "(TARGET_H8300 || TARGET_H8300H || TARGET_H8300S)
     && INTVAL (operands[1]) <= 15"
   "btst	%Z1,%Y0"
   [(set_attr "length" "2")
@@ -865,21 +854,18 @@
   [(set_attr "length" "2,8,10")
    (set_attr "cc" "set_zn,set_zn,set_zn")])
 
-(define_insn "*tstqi"
-  [(set (cc0)
-	(compare (match_operand:QI 0 "register_operand" "r")
-		 (const_int 0)))]
-  ""
-  "mov.b	%X0,%X0"
-  [(set_attr "length" "2")
-   (set_attr "cc" "set_znv")])
-
-(define_insn "*tsthi"
+(define_insn "*tst<mode>"
   [(set (cc0)
-	(compare (match_operand:HI 0 "register_operand" "r")
+	(compare (match_operand:QHI 0 "register_operand" "r")
 		 (const_int 0)))]
   ""
-  "mov.w	%T0,%T0"
+  {
+    if (<MODE>mode == QImode)
+      return "mov.b	%X0,%X0";
+    else if (<MODE>mode == HImode)
+      return "mov.w	%T0,%T0";
+    gcc_unreachable ();
+  }
   [(set_attr "length" "2")
    (set_attr "cc" "set_znv")])
 
@@ -918,7 +904,7 @@
 		 (match_operand:QI 1 "h8300_src_operand" "rQi")))]
   ""
   "cmp.b	%X1,%X0"
-  [(set_attr "length_table" "addb")
+  [(set_attr "length_table" "add")
    (set_attr "cc" "compare")])
 
 (define_insn "*cmphi_h8300_znvc"
@@ -949,7 +935,7 @@
       gcc_unreachable ();
       }
 }
-  [(set_attr "length_table" "short_immediate,addw")
+  [(set_attr "length_table" "short_immediate,add")
    (set_attr "cc" "compare,compare")])
 
 (define_insn "cmpsi"
@@ -972,7 +958,7 @@
     }
 }
   [(set_attr "length" "2,*")
-   (set_attr "length_table" "*,addl")
+   (set_attr "length_table" "*,add")
    (set_attr "cc" "compare,compare")])
 
 ;; ----------------------------------------------------------------------
@@ -992,7 +978,7 @@
 		 (match_operand:QI 2 "h8300_src_operand" "rQi")))]
   "h8300_operands_match_p (operands)"
   "add.b	%X2,%X0"
-  [(set_attr "length_table" "addb")
+  [(set_attr "length_table" "add")
    (set_attr "cc" "set_zn")])
 
 (define_insn "*addhi3_h8300"
@@ -1055,15 +1041,19 @@
   [(set_attr "length" "2,2,2,4,2")
    (set_attr "cc" "none_0hit,none_0hit,clobber,set_zn,set_zn")])
 
-(define_insn "*addhi3_incdec"
-  [(set (match_operand:HI 0 "register_operand" "=r,r")
-	(unspec:HI [(match_operand:HI 1 "register_operand" "0,0")
-		    (match_operand:HI 2 "incdec_operand" "M,O")]
-		   UNSPEC_INCDEC))]
+(define_insn "*add<mode>3_incdec"
+  [(set (match_operand:HSI 0 "register_operand" "=r,r")
+	(unspec:HSI [(match_operand:HSI 1 "register_operand" "0,0")
+		     (match_operand:HSI 2 "incdec_operand" "M,O")]
+		    UNSPEC_INCDEC))]
   "TARGET_H8300H || TARGET_H8300S"
-  "@
-   inc.w	%2,%T0
-   dec.w	%G2,%T0"
+  {
+    if (which_alternative == 0)
+      return <MODE>mode == HImode ? "inc.w\t%2,%T0" : "inc.l\t%2,%S0";
+    else if (which_alternative == 1)
+      return <MODE>mode == HImode ? "dec.w\t%G2,%T0" : "dec.l\t%G2,%S0";
+    gcc_unreachable ();
+   }
   [(set_attr "length" "2,2")
    (set_attr "cc" "set_zn,set_zn")])
 
@@ -1077,7 +1067,7 @@
    sub.w	%G2:3,%T0
    add.b	%t2,%t0
    add.w	%T2,%T0"
-  [(set_attr "length_table" "short_immediate,short_immediate,*,addw")
+  [(set_attr "length_table" "short_immediate,short_immediate,*,add")
    (set_attr "length" "*,*,2,*")
    (set_attr "cc" "set_zn")])
 
@@ -1119,18 +1109,6 @@
    (set (attr "cc")
 	(symbol_ref "compute_plussi_cc (operands)"))])
 
-(define_insn "*addsi3_incdec"
-  [(set (match_operand:SI 0 "register_operand" "=r,r")
-	(unspec:SI [(match_operand:SI 1 "register_operand" "0,0")
-		    (match_operand:SI 2 "incdec_operand" "M,O")]
-		   UNSPEC_INCDEC))]
-  "TARGET_H8300H || TARGET_H8300S"
-  "@
-   inc.l	%2,%S0
-   dec.l	%G2,%S0"
-  [(set_attr "length" "2,2")
-   (set_attr "cc" "set_zn,set_zn")])
-
 (define_split
   [(set (match_operand:SI 0 "register_operand" "")
 	(plus:SI (match_dup 0)
@@ -1162,7 +1140,7 @@
 		  (match_operand:QI 2 "h8300_dst_operand" "rQ")))]
   "h8300_operands_match_p (operands)"
   "sub.b	%X2,%X0"
-  [(set_attr "length_table" "addb")
+  [(set_attr "length_table" "add")
    (set_attr "cc" "set_zn")])
 
 (define_insn "*subhi3_h8300"
@@ -1176,15 +1154,19 @@
   [(set_attr "length" "2,4")
    (set_attr "cc" "set_zn,clobber")])
 
-(define_insn "*subhi3_h8300hs"
-  [(set (match_operand:HI 0 "h8300_dst_operand" "=rQ,rQ")
-	(minus:HI (match_operand:HI 1 "h8300_dst_operand" "0,0")
-		  (match_operand:HI 2 "h8300_src_operand" "rQ,i")))]
+(define_insn "*sub<mode>3_h8300hs"
+  [(set (match_operand:HSI 0 "h8300_dst_operand" "=rQ,rQ")
+	(minus:HSI (match_operand:HSI 1 "h8300_dst_operand" "0,0")
+		   (match_operand:HSI 2 "h8300_src_operand" "rQ,i")))]
   "(TARGET_H8300H || TARGET_H8300S) && h8300_operands_match_p (operands)"
-  "@
-   sub.w	%T2,%T0
-   sub.w	%T2,%T0"
-  [(set_attr "length_table" "addw")
+  { 
+    if (<MODE>mode == HImode)
+      return "sub.w	%T2,%T0";
+    else if (<MODE>mode == SImode)
+      return "sub.l	%S2,%S0";
+    gcc_unreachable ();
+  }
+  [(set_attr "length_table" "add")
    (set_attr "cc" "set_zn")])
 
 (define_insn "*subsi3_h8300"
@@ -1195,16 +1177,6 @@
   "sub.w	%f2,%f0\;subx	%y2,%y0\;subx	%z2,%z0"
   [(set_attr "length" "6")])
 
-(define_insn "*subsi3_h8300hs"
-  [(set (match_operand:SI 0 "h8300_dst_operand" "=rQ,rQ")
-	(minus:SI (match_operand:SI 1 "h8300_dst_operand" "0,0")
-		  (match_operand:SI 2 "h8300_src_operand" "rQ,i")))]
-  "(TARGET_H8300H || TARGET_H8300S) && h8300_operands_match_p (operands)"
-  "@
-   sub.l	%S2,%S0
-   sub.l	%S2,%S0"
-  [(set_attr "length_table" "addl")
-   (set_attr "cc" "set_zn")])
 
 ;; ----------------------------------------------------------------------
 ;; MULTIPLY INSTRUCTIONS
@@ -1332,21 +1304,12 @@
 ;; on a H8SX with a multiplier, whereas muls.w seems to be available
 ;; on all H8SX variants.
 
-(define_insn "mulhi3"
-  [(set (match_operand:HI 0 "register_operand" "=r")
-        (mult:HI (match_operand:HI 1 "register_operand" "%0")
-		 (match_operand:HI 2 "reg_or_nibble_operand" "r IP4>X")))]
+(define_insn "mul<mode>3"
+  [(set (match_operand:HSI 0 "register_operand" "=r")
+        (mult:HSI (match_operand:HSI 1 "register_operand" "%0")
+		  (match_operand:HSI 2 "reg_or_nibble_operand" "r IP4>X")))]
   "TARGET_H8300SX"
-  "muls.w\\t%T2,%T0"
-  [(set_attr "length" "2")
-   (set_attr "cc" "set_zn")])
-
-(define_insn "mulsi3"
-  [(set (match_operand:SI 0 "register_operand" "=r")
-        (mult:SI (match_operand:SI 1 "register_operand" "%0")
-		 (match_operand:SI 2 "reg_or_nibble_operand" "r IP4>X")))]
-  "TARGET_H8300SX"
-  "muls.l\\t%S2,%S0"
+  { return <MODE>mode == HImode ? "muls.w\\t%T2,%T0" : "muls.l\\t%S2,%S0"; }
   [(set_attr "length" "2")
    (set_attr "cc" "set_zn")])
 
@@ -1413,36 +1376,20 @@
 ;; DIVIDE/MOD INSTRUCTIONS
 ;; ----------------------------------------------------------------------
 
-(define_insn "udivhi3"
-  [(set (match_operand:HI 0 "register_operand" "=r")
-	(udiv:HI (match_operand:HI 1 "register_operand" "0")
-		 (match_operand:HI 2 "reg_or_nibble_operand" "r IP4>X")))]
+(define_insn "udiv<mode>3"
+  [(set (match_operand:HSI 0 "register_operand" "=r")
+	(udiv:HSI (match_operand:HSI 1 "register_operand" "0")
+		  (match_operand:HSI 2 "reg_or_nibble_operand" "r IP4>X")))]
   "TARGET_H8300SX"
-  "divu.w\\t%T2,%T0"
+  { return <MODE>mode == HImode ? "divu.w\\t%T2,%T0" : "divu.l\\t%S2,%S0"; }
   [(set_attr "length" "2")])
 
-(define_insn "divhi3"
-  [(set (match_operand:HI 0 "register_operand" "=r")
-	(div:HI (match_operand:HI 1 "register_operand" "0")
-		(match_operand:HI 2 "reg_or_nibble_operand" "r IP4>X")))]
+(define_insn "div<mode>3"
+  [(set (match_operand:HSI 0 "register_operand" "=r")
+	(div:HSI (match_operand:HSI 1 "register_operand" "0")
+		 (match_operand:HSI 2 "reg_or_nibble_operand" "r IP4>X")))]
   "TARGET_H8300SX"
-  "divs.w\\t%T2,%T0"
-  [(set_attr "length" "2")])
-
-(define_insn "udivsi3"
-  [(set (match_operand:SI 0 "register_operand" "=r")
-	(udiv:SI (match_operand:SI 1 "register_operand" "0")
-		 (match_operand:SI 2 "reg_or_nibble_operand" "r IP4>X")))]
-  "TARGET_H8300SX"
-  "divu.l\\t%S2,%S0"
-  [(set_attr "length" "2")])
-
-(define_insn "divsi3"
-  [(set (match_operand:SI 0 "register_operand" "=r")
-	(div:SI (match_operand:SI 1 "register_operand" "0")
-		(match_operand:SI 2 "reg_or_nibble_operand" "r IP4>X")))]
-  "TARGET_H8300SX"
-  "divs.l\\t%S2,%S0"
+  { return <MODE>mode == HImode ? "divs.w\\t%T2,%T0" : "divs.l\\t%S2,%S0"; }
   [(set_attr "length" "2")])
 
 (define_insn "udivmodqi4"
@@ -1599,47 +1546,44 @@
   ""
   "")
 
-(define_insn "*andorqi3"
-  [(set (match_operand:QI 0 "register_operand" "=r")
-	(ior:QI (and:QI (match_operand:QI 2 "register_operand" "r")
-			(match_operand:QI 3 "single_one_operand" "n"))
-		(match_operand:QI 1 "register_operand" "0")))]
-  ""
-  "bld\\t%V3,%X2\;bor\\t%V3,%X0\;bst\\t%V3,%X0"
-  [(set_attr "length" "6")])
+(define_insn "*andor<mode>3"
+  [(set (match_operand:QHSI 0 "register_operand" "=r")
+	(ior:QHSI (and:QHSI (match_operand:QHSI 2 "register_operand" "r")
+			    (match_operand:QHSI 3 "single_one_operand" "n"))
+		  (match_operand:QHSI 1 "register_operand" "0")))]
+  "(<MODE>mode == QImode
+    || <MODE>mode == HImode
+    || (<MODE>mode == SImode
+	&& (INTVAL (operands[3]) & 0xffff) != 0))"
+  {
+    if (<MODE>mode == QImode)
+      return "bld\\t%V3,%X2\;bor\\t%V3,%X0\;bst\\t%V3,%X0";
 
-(define_insn "*andorhi3"
-  [(set (match_operand:HI 0 "register_operand" "=r")
-	(ior:HI (and:HI (match_operand:HI 2 "register_operand" "r")
-			(match_operand:HI 3 "single_one_operand" "n"))
-		(match_operand:HI 1 "register_operand" "0")))]
-  ""
-{
-  operands[3] = GEN_INT (INTVAL (operands[3]) & 0xffff);
-  if (INTVAL (operands[3]) > 128)
-    {
-      operands[3] = GEN_INT (INTVAL (operands[3]) >> 8);
-      return "bld\\t%V3,%t2\;bor\\t%V3,%t0\;bst\\t%V3,%t0";
-    }
-  return "bld\\t%V3,%s2\;bor\\t%V3,%s0\;bst\\t%V3,%s0";
-}
-  [(set_attr "length" "6")])
+    if (<MODE>mode == HImode)
+      {
+	operands[3] = GEN_INT (INTVAL (operands[3]) & 0xffff);
+	if (INTVAL (operands[3]) > 128)
+	  {
+	    operands[3] = GEN_INT (INTVAL (operands[3]) >> 8);
+	    return "bld\\t%V3,%t2\;bor\\t%V3,%t0\;bst\\t%V3,%t0";
+	  }
+	return "bld\\t%V3,%s2\;bor\\t%V3,%s0\;bst\\t%V3,%s0";
+      }
 
-(define_insn "*andorsi3"
-  [(set (match_operand:SI 0 "register_operand" "=r")
-	(ior:SI (and:SI (match_operand:SI 2 "register_operand" "r")
-			(match_operand:SI 3 "single_one_operand" "n"))
-		(match_operand:SI 1 "register_operand" "0")))]
-  "(INTVAL (operands[3]) & 0xffff) != 0"
-{
-  operands[3] = GEN_INT (INTVAL (operands[3]) & 0xffff);
-  if (INTVAL (operands[3]) > 128)
-    {
-      operands[3] = GEN_INT (INTVAL (operands[3]) >> 8);
-      return "bld\\t%V3,%x2\;bor\\t%V3,%x0\;bst\\t%V3,%x0";
-    }
-  return "bld\\t%V3,%w2\;bor\\t%V3,%w0\;bst\\t%V3,%w0";
-}
+    if (<MODE>mode == SImode)
+      {
+	operands[3] = GEN_INT (INTVAL (operands[3]) & 0xffff);
+	if (INTVAL (operands[3]) > 128)
+	  {
+	    operands[3] = GEN_INT (INTVAL (operands[3]) >> 8);
+	    return "bld\\t%V3,%x2\;bor\\t%V3,%x0\;bst\\t%V3,%x0";
+	  }
+	return "bld\\t%V3,%w2\;bor\\t%V3,%w0\;bst\\t%V3,%w0";
+      }
+
+    gcc_unreachable ();
+	
+  }
   [(set_attr "length" "6")])
 
 (define_insn "*andorsi3_shift_8"

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