diff mbox series

[committed] Reinstate branch-on-bit insns for H8

Message ID 9b71ef47-4947-6af7-44ac-57219edc2d98@gmail.com
State New
Headers show
Series [committed] Reinstate branch-on-bit insns for H8 | expand

Commit Message

Jeff Law July 29, 2021, 6:59 p.m. UTC
The branch-on-bit patterns have been disabled since the transition away 
from cc0 on the H8.  This patch reinstates them.  This tends to be a 
fairly nice win since the bit test is 2 or 4 bytes, but the 
and-with-constant approaches is going to be 2-6 bytes or worse if the 
input value doesn't die.

Variable bit handling isn't supported yet.  I can't convince myself the 
old variable bit test patterns were ever used.   But some contemplating 
is useful here as these are crazy expensive, none of my ideas from last 
night looked viable though.


Tested overnight in my tester without regressions.  Committing to the trunk.

Jeff
commit 0c6d21faa426bd6e6fdb3a6b47af530e49944118
Author: Jeff Law <jeffreyalaw@gmail.com>
Date:   Thu Jul 29 14:32:59 2021 -0400

    Reinstate branch-on-bit insns for H8
    
    gcc/
            * config/h8300/h8300-modes.def: Add CCZ, CCV and CCC, drop CCZNV.
            * config/h8300/h8300.md (H8cc mode iterator): Add CCZ.
            (cc mode_attr): Similarly.
            (ccz subst_attr): Similarly.
            * config/h8300/jumpcall.md: Add new patterns for branch-on-bit.
            * config/h8300/testcompare.md: Remove various cc0 based patterns
            that had been commented out.  Add pattern to set CCZ from a bit
            test.
diff mbox series

Patch

diff --git a/gcc/config/h8300/h8300-modes.def b/gcc/config/h8300/h8300-modes.def
index 23b777b2966..6ab52606a9a 100644
--- a/gcc/config/h8300/h8300-modes.def
+++ b/gcc/config/h8300/h8300-modes.def
@@ -18,4 +18,6 @@ 
    <http://www.gnu.org/licenses/>.  */
 
 CC_MODE (CCZN);
-CC_MODE (CCZNV);
+CC_MODE (CCZ);
+CC_MODE (CCV);
+CC_MODE (CCC);
diff --git a/gcc/config/h8300/h8300.md b/gcc/config/h8300/h8300.md
index e596987a6a6..7f49e4284f2 100644
--- a/gcc/config/h8300/h8300.md
+++ b/gcc/config/h8300/h8300.md
@@ -140,11 +140,11 @@ 
 
 ;; The modes we're supporting.  This is used when we want to generate
 ;; multiple patterns where only the mode differs from a single template
-(define_mode_iterator H8cc [CC CCZN])
+(define_mode_iterator H8cc [CC CCZN CCZ])
 
 ;; This is used to generate multiple define_substs from a single
 ;; template for the different variants we might have.
-(define_mode_attr cc [(CC "cc") (CCZN "cczn")])
+(define_mode_attr cc [(CC "cc") (CCZN "cczn") (CCZ "ccz")])
 
 ;; The primary substitution pattern.  <cc> is used to create multiple
 ;; substitutions based on the CC bits that are set.
@@ -165,6 +165,7 @@ 
 ;; apply the subst_cczn or subset_cc define_subst to generate a
 ;; new pattern that compare-elim can use
 (define_subst_attr "cczn" "subst_cczn" "" "_cczn")
+(define_subst_attr "ccz" "subst_ccz" "" "_ccz")
 (define_subst_attr "cc" "subst_cc" "" "_cc")
 
 ;; Type of delay slot.  NONE means the instruction has no delay slot.
diff --git a/gcc/config/h8300/jumpcall.md b/gcc/config/h8300/jumpcall.md
index e1f04183564..3e59fee58bd 100644
--- a/gcc/config/h8300/jumpcall.md
+++ b/gcc/config/h8300/jumpcall.md
@@ -143,6 +143,52 @@ 
   [(set_attr "type" "bitbranch")
    (set_attr "length_table" "bitbranch")])
 
+(define_insn_and_split ""
+  [(set (pc)
+	(if_then_else (match_operator 3 "eqne_operator"
+			[(zero_extract:QHSI (match_operand:QHSI 1 "register_operand" "r")
+					    (const_int 1)
+					    (match_operand 2 "const_int_operand" "n"))
+			 (const_int 0)])
+		      (label_ref (match_operand 0 "" ""))
+		      (pc)))]
+  "INTVAL (operands[2]) < 16"
+  "#"
+  "&& reload_completed"
+  [(set (reg:CCZ CC_REG)
+	(eq (zero_extract:QHSI (match_dup 1) (const_int 1) (match_dup 2))
+	    (const_int 0)))
+   (set (pc)
+	(if_then_else (match_op_dup 3 [(reg:CCZ CC_REG) (const_int 0)])
+		      (label_ref (match_dup 0))
+		      (pc)))])
+
+(define_insn_and_split ""
+  [(set (pc)
+	(if_then_else (match_operator 3 "eqne_operator"
+			[(zero_extract:SI (match_operand:SI 1 "register_operand" "r")
+					  (const_int 1)
+					  (match_operand 2 "const_int_operand" "n"))
+			 (const_int 0)])
+		      (label_ref (match_operand 0 "" ""))
+		      (pc)))
+   (clobber (match_scratch:SI 4 "=&r"))]
+  "INTVAL (operands[2]) >= 16"
+  "#"
+  "&& reload_completed"
+  [(parallel [(set (match_dup 4)
+		   (ior:SI (and:SI (match_dup 4) (const_int -65536))
+			   (lshiftrt:SI (match_dup 1) (const_int 16))))
+	      (clobber (reg:CC CC_REG))])
+   (set (reg:CCZ CC_REG)
+	(eq (zero_extract:SI (match_dup 4) (const_int 1) (match_dup 2))
+	    (const_int 0)))
+   (set (pc)
+	(if_then_else (match_op_dup 3 [(reg:CCZ CC_REG) (const_int 0)])
+		      (label_ref (match_dup 0))
+		      (pc)))]
+  "operands[2] = GEN_INT (INTVAL (operands[2]) - 16);")
+
 ;; Unconditional and other jump instructions.
 
 (define_insn "jump"
diff --git a/gcc/config/h8300/testcompare.md b/gcc/config/h8300/testcompare.md
index e9f6ddcf075..29190532e49 100644
--- a/gcc/config/h8300/testcompare.md
+++ b/gcc/config/h8300/testcompare.md
@@ -26,77 +26,15 @@ 
 ;;  ""
 ;;  [(set_attr "length" "2,8,10")])
 ;;
-;;(define_insn ""
-;;  [(set (cc0)
-;;	(compare (zero_extract:HSI (match_operand:HSI 0 "register_operand" "r")
-;;				   (const_int 1)
-;;				   (match_operand 1 "const_int_operand" "n"))
-;;		 (const_int 0)))]
-;;  "INTVAL (operands[1]) <= 15"
-;;  "btst	%Z1,%Y0"
-;;  [(set_attr "length" "2")])
-;;
-;;(define_insn_and_split "*tstsi_upper_bit"
-;;  [(set (cc0)
-;;	(compare (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
-;;				  (const_int 1)
-;;				  (match_operand 1 "const_int_operand" "n"))
-;;		 (const_int 0)))
-;;   (clobber (match_scratch:SI 2 "=&r"))]
-;;  "INTVAL (operands[1]) >= 16"
-;;  "#"
-;;  "&& reload_completed"
-;;  [(set (match_dup 2)
-;;	(ior:SI (and:SI (match_dup 2)
-;;			(const_int -65536))
-;;		(lshiftrt:SI (match_dup 0)
-;;			     (const_int 16))))
-;;   (set (cc0)
-;;	(compare (zero_extract:SI (match_dup 2)
-;;				  (const_int 1)
-;;				  (match_dup 3))
-;;		 (const_int 0)))]
-;;  {
-;;    operands[3] = GEN_INT (INTVAL (operands[1]) - 16);
-;;  })
-;;
-;;(define_insn "*tstsi_variable_bit"
-;;  [(set (cc0)
-;;	(compare (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
-;;				  (const_int 1)
-;;				  (and:SI (match_operand:SI 1 "register_operand" "r")
-;;					  (const_int 7)))
-;;		 (const_int 0)))]
-;;  ""
-;;  "btst	%w1,%w0"
-;;  [(set_attr "length" "2")])
-;;
-;;(define_insn_and_split "*tstsi_variable_bit_qi"
-;;  [(set (cc0)
-;;	(compare (zero_extract:SI (zero_extend:SI (match_operand:QI 0 "general_operand_src" "r,U,mn>"))
-;;				  (const_int 1)
-;;				  (and:SI (match_operand:SI 1 "register_operand" "r,r,r")
-;;					  (const_int 7)))
-;;		 (const_int 0)))
-;;   (clobber (match_scratch:QI 2 "=X,X,&r"))]
-;;  "!CONSTANT_P (operands[0])"
-;;  "@
-;;   btst\\t%w1,%X0
-;;   btst\\t%w1,%X0
-;;   #"
-;;  "&& reload_completed
-;;   && !satisfies_constraint_U (operands[0])"
-;;  [(set (match_dup 2)
-;;	(match_dup 0))
-;;   (parallel [(set (cc0)
-;;		   (compare (zero_extract:SI (zero_extend:SI (match_dup 2))
-;;					     (const_int 1)
-;;					     (and:SI (match_dup 1)
-;;						     (const_int 7)))
-;;			    (const_int 0)))
-;;	      (clobber (scratch:QI))])]
-;;  ""
-;;  [(set_attr "length" "2,8,10")])
+(define_insn ""
+  [(set (reg:CCZ CC_REG)
+	(eq (zero_extract:HSI (match_operand:HSI 0 "register_operand" "r")
+			      (const_int 1)
+			      (match_operand 1 "const_int_operand" "n"))
+	    (const_int 0)))]
+  "INTVAL (operands[1]) < 16"
+  "btst	%Z1,%Y0"
+  [(set_attr "length" "2")])
 
 (define_insn "*tst<mode>"
   [(set (reg:CCZN CC_REG)