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 <jeffreya...@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 --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)