public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r12-1987] Use shift instructions to eliminate redundant compare/test instructions on the H8
@ 2021-07-02 16:03 Jeff Law
  0 siblings, 0 replies; only message in thread
From: Jeff Law @ 2021-07-02 16:03 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:7aa5fb17a30ff0ce9928e5eac35b892d95e7eba5

commit r12-1987-g7aa5fb17a30ff0ce9928e5eac35b892d95e7eba5
Author: Jeff Law <jeffreyalaw@gmail.com>
Date:   Fri Jul 2 11:58:47 2021 -0400

    Use shift instructions to eliminate redundant compare/test instructions on the H8
    
    gcc/ChangeLog
    
            * config/h8300/h8300-protos.h (compute_a_shift_cc): Accept
            additional argument for the code.
            * config/h8300/h8300.c (compute_a_shift_cc): Accept additional
            argument for the code.  Just return if the ZN bits are useful or
            not rather than the old style CC_* enums.
            * config/h8300/shiftrotate.md (shiftqi_noscratch): Move before
            more generic shiftqi patterns.
            (shifthi_noscratch, shiftsi_noscratch): Similarly.
            (shiftqi_noscratch_set_flags): New pattern.
            (shifthi_noscratch_set_flags, shiftsi_noscratch_set_flags): Likewise.

Diff:
---
 gcc/config/h8300/h8300-protos.h |   2 +-
 gcc/config/h8300/h8300.c        |  20 +++---
 gcc/config/h8300/shiftrotate.md | 153 +++++++++++++++++++++++++++-------------
 3 files changed, 116 insertions(+), 59 deletions(-)

diff --git a/gcc/config/h8300/h8300-protos.h b/gcc/config/h8300/h8300-protos.h
index 86bcc3fd324..744337d6667 100644
--- a/gcc/config/h8300/h8300-protos.h
+++ b/gcc/config/h8300/h8300-protos.h
@@ -41,7 +41,7 @@ extern const char *output_logical_op (machine_mode, rtx_code code,
 extern unsigned int compute_logical_op_length (machine_mode, rtx_code,
 					      rtx *, rtx_insn *);
 
-extern int compute_a_shift_cc (rtx, rtx *);
+extern int compute_a_shift_cc (rtx *, rtx_code);
 #ifdef HAVE_ATTR_cc
 extern enum attr_cc compute_plussi_cc (rtx *);
 #endif
diff --git a/gcc/config/h8300/h8300.c b/gcc/config/h8300/h8300.c
index 0fdc68bf65b..d2f6548a265 100644
--- a/gcc/config/h8300/h8300.c
+++ b/gcc/config/h8300/h8300.c
@@ -4297,11 +4297,9 @@ compute_a_shift_length (rtx operands[3], rtx_code code)
 /* Compute which flag bits are valid after a shift insn.  */
 
 int
-compute_a_shift_cc (rtx insn ATTRIBUTE_UNUSED, rtx *operands)
+compute_a_shift_cc (rtx operands[3], rtx_code code)
 {
-  rtx shift = operands[3];
-  machine_mode mode = GET_MODE (shift);
-  enum rtx_code code = GET_CODE (shift);
+  machine_mode mode = GET_MODE (operands[0]);
   enum shift_type shift_type;
   enum shift_mode shift_mode;
   struct shift_info info;
@@ -4358,16 +4356,18 @@ compute_a_shift_cc (rtx insn ATTRIBUTE_UNUSED, rtx *operands)
     {
     case SHIFT_SPECIAL:
       if (info.remainder == 0)
-	return info.cc_special;
+	return (info.cc_special == OLD_CC_SET_ZN
+		|| info.cc_special == OLD_CC_SET_ZNV);
 
       /* Fall through.  */
 
     case SHIFT_INLINE:
-      return info.cc_inline;
+      return (info.cc_inline == OLD_CC_SET_ZN
+	      || info.cc_inline == OLD_CC_SET_ZNV);
       
     case SHIFT_ROT_AND:
       /* This case always ends with an and instruction.  */
-      return OLD_CC_SET_ZNV;
+      return true;
       
     case SHIFT_LOOP:
       /* A loop to shift by a "large" constant value.
@@ -4375,9 +4375,11 @@ compute_a_shift_cc (rtx insn ATTRIBUTE_UNUSED, rtx *operands)
       if (info.shift2 != NULL)
 	{
 	  if (n % 2)
-	    return info.cc_inline;
+	    return (info.cc_inline == OLD_CC_SET_ZN
+		    || info.cc_inline == OLD_CC_SET_ZNV);
+		
 	}
-      return OLD_CC_CLOBBER;
+      return false;
       
     default:
       gcc_unreachable ();
diff --git a/gcc/config/h8300/shiftrotate.md b/gcc/config/h8300/shiftrotate.md
index c5d32cd6271..0476324bf22 100644
--- a/gcc/config/h8300/shiftrotate.md
+++ b/gcc/config/h8300/shiftrotate.md
@@ -150,33 +150,6 @@
 }
   [(set_attr "length" "4")])
 
-(define_insn_and_split "*shiftqi"
-  [(set (match_operand:QI 0 "register_operand" "=r,r")
-	(shifts:QI
-	  (match_operand:QI 1 "register_operand" "0,0")
-	  (match_operand:QI 2 "nonmemory_operand" "R,rn")))
-   (clobber (match_scratch:QI 3 "=X,&r"))]
-  ""
-  "#"
-  "&& reload_completed"
-  [(parallel [(set (match_dup 0) (shifts:QI (match_dup 1) (match_dup 2)))
-	      (clobber (match_dup 3))
-	      (clobber (reg:CC CC_REG))])])
-
-(define_insn "*shiftqi_clobber_flags"
-  [(set (match_operand:QI 0 "register_operand" "=r,r")
-	(shifts:QI
-	  (match_operand:QI 1 "register_operand" "0,0")
-	  (match_operand:QI 2 "nonmemory_operand" "R,rn")))
-   (clobber (match_scratch:QI 3 "=X,&r"))
-   (clobber (reg:CC CC_REG))]
-  ""
-{
-  return output_a_shift (operands, <CODE>);
-}
-  [(set (attr "length")
-	(symbol_ref "compute_a_shift_length (operands, <CODE>)"))])
-
 (define_insn_and_split "*shiftqi_noscratch"
   [(set (match_operand:QI 0 "register_operand" "=r,r")
 	(shifts:QI
@@ -204,24 +177,43 @@
   [(set (attr "length")
 	(symbol_ref "compute_a_shift_length (operands, <CODE>)"))])
 
-(define_insn_and_split "*shifthi"
-  [(set (match_operand:HI 0 "register_operand" "=r,r")
-	(shifts:HI
-	  (match_operand:HI 1 "register_operand" "0,0")
-	  (match_operand:QI 2 "nonmemory_operand" "S,rn")))
+(define_insn "*shiftqi_noscratch_set_flags"
+  [(set (reg:CCZN CC_REG)
+	(compare:CCZN
+	  (shifts:QI
+	    (match_operand:QI 1 "register_operand" "0,0")
+	    (match_operand:QI 2 "nonmemory_operand" "R,rn"))
+	  (const_int 0)))
+   (set (match_operand:QI 0 "register_operand" "=r,r")
+	(shifts:QI (match_dup 1) (match_dup 2)))]
+  "(GET_CODE (operands[2]) == CONST_INT
+    && !h8300_shift_needs_scratch_p (INTVAL (operands[2]), QImode, <CODE>)
+    && compute_a_shift_cc (operands, <CODE>))"
+{
+  return output_a_shift (operands, <CODE>);
+}
+  [(set (attr "length")
+	(symbol_ref "compute_a_shift_length (operands, <CODE>)"))])
+
+
+(define_insn_and_split "*shiftqi"
+  [(set (match_operand:QI 0 "register_operand" "=r,r")
+	(shifts:QI
+	  (match_operand:QI 1 "register_operand" "0,0")
+	  (match_operand:QI 2 "nonmemory_operand" "R,rn")))
    (clobber (match_scratch:QI 3 "=X,&r"))]
   ""
   "#"
   "&& reload_completed"
-  [(parallel [(set (match_dup 0) (shifts:HI (match_dup 1) (match_dup 2)))
+  [(parallel [(set (match_dup 0) (shifts:QI (match_dup 1) (match_dup 2)))
 	      (clobber (match_dup 3))
 	      (clobber (reg:CC CC_REG))])])
 
-(define_insn "*shifthi_clobber_flags"
-  [(set (match_operand:HI 0 "register_operand" "=r,r")
-	(shifts:HI
-	  (match_operand:HI 1 "register_operand" "0,0")
-	  (match_operand:QI 2 "nonmemory_operand" "S,rn")))
+(define_insn "*shiftqi_clobber_flags"
+  [(set (match_operand:QI 0 "register_operand" "=r,r")
+	(shifts:QI
+	  (match_operand:QI 1 "register_operand" "0,0")
+	  (match_operand:QI 2 "nonmemory_operand" "R,rn")))
    (clobber (match_scratch:QI 3 "=X,&r"))
    (clobber (reg:CC CC_REG))]
   ""
@@ -257,24 +249,41 @@
   [(set (attr "length")
 	(symbol_ref "compute_a_shift_length (operands, <CODE>)"))])
 
-(define_insn_and_split "*shiftsi"
-  [(set (match_operand:SI 0 "register_operand" "=r,r")
-	(shifts:SI
-	  (match_operand:SI 1 "register_operand" "0,0")
-	  (match_operand:QI 2 "nonmemory_operand" "T,rn")))
+(define_insn "*shifthi_noscratch_setzn"
+  [(set (reg:CCZN CC_REG)
+	(compare:CCZN
+	  (shifts:HI (match_operand:HI 1 "register_operand" "0,0")
+		     (match_operand:HI 2 "nonmemory_operand" "S,rn"))
+	  (const_int 0)))
+   (set (match_operand:HI 0 "register_operand" "=r,r")
+	(shifts:HI (match_dup 1) (match_dup 2)))]
+  "(GET_CODE (operands[2]) == CONST_INT
+    && !h8300_shift_needs_scratch_p (INTVAL (operands[2]), HImode, <CODE>)
+    && compute_a_shift_cc (operands, <CODE>))"
+{
+  return output_a_shift (operands, <CODE>);
+}
+  [(set (attr "length")
+	(symbol_ref "compute_a_shift_length (operands, <CODE>)"))])
+
+(define_insn_and_split "*shifthi"
+  [(set (match_operand:HI 0 "register_operand" "=r,r")
+	(shifts:HI
+	  (match_operand:HI 1 "register_operand" "0,0")
+	  (match_operand:QI 2 "nonmemory_operand" "S,rn")))
    (clobber (match_scratch:QI 3 "=X,&r"))]
   ""
   "#"
   "&& reload_completed"
-  [(parallel [(set (match_dup 0) (shifts:SI (match_dup 1) (match_dup 2)))
+  [(parallel [(set (match_dup 0) (shifts:HI (match_dup 1) (match_dup 2)))
 	      (clobber (match_dup 3))
 	      (clobber (reg:CC CC_REG))])])
 
-(define_insn "*shiftsi_clobber_flags"
-  [(set (match_operand:SI 0 "register_operand" "=r,r")
-	(shifts:SI
-	  (match_operand:SI 1 "register_operand" "0,0")
-	  (match_operand:QI 2 "nonmemory_operand" "T,rn")))
+(define_insn "*shifthi_clobber_flags"
+  [(set (match_operand:HI 0 "register_operand" "=r,r")
+	(shifts:HI
+	  (match_operand:HI 1 "register_operand" "0,0")
+	  (match_operand:QI 2 "nonmemory_operand" "S,rn")))
    (clobber (match_scratch:QI 3 "=X,&r"))
    (clobber (reg:CC CC_REG))]
   ""
@@ -310,9 +319,55 @@
   [(set (attr "length")
 	(symbol_ref "compute_a_shift_length (operands, <CODE>)"))])
 
+(define_insn "*shiftsi_noscratch_cczn"
+  [(set (reg:CCZN CC_REG)
+	(compare:CCZN
+	  (shifts:SI
+	    (match_operand:SI 1 "register_operand" "0,0")
+	    (match_operand:SI 2 "nonmemory_operand" "T,rn"))
+	  (const_int 0)))
+   (set (match_operand:SI 0 "register_operand" "=r,r")
+	(shifts:SI (match_dup 1) (match_dup 2)))]
+  "(GET_CODE (operands[2]) == CONST_INT
+    && !h8300_shift_needs_scratch_p (INTVAL (operands[2]), SImode, <CODE>)
+    && compute_a_shift_cc (operands, <CODE>))"
+{
+  return output_a_shift (operands, <CODE>);
+}
+  [(set (attr "length")
+	(symbol_ref "compute_a_shift_length (operands, <CODE>)"))])
+
 ;; Split a variable shift into a loop.  If the register containing
 ;; the shift count dies, then we just use that register.
 
+
+(define_insn_and_split "*shiftsi"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+	(shifts:SI
+	  (match_operand:SI 1 "register_operand" "0,0")
+	  (match_operand:QI 2 "nonmemory_operand" "T,rn")))
+   (clobber (match_scratch:QI 3 "=X,&r"))]
+  ""
+  "#"
+  "&& reload_completed"
+  [(parallel [(set (match_dup 0) (shifts:SI (match_dup 1) (match_dup 2)))
+	      (clobber (match_dup 3))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*shiftsi_clobber_flags"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+	(shifts:SI
+	  (match_operand:SI 1 "register_operand" "0,0")
+	  (match_operand:QI 2 "nonmemory_operand" "T,rn")))
+   (clobber (match_scratch:QI 3 "=X,&r"))
+   (clobber (reg:CC CC_REG))]
+  ""
+{
+  return output_a_shift (operands, <CODE>);
+}
+  [(set (attr "length")
+	(symbol_ref "compute_a_shift_length (operands, <CODE>)"))])
+
 (define_split
   [(set (match_operand 0 "register_operand" "")
 	(match_operator 2 "nshift_operator"


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2021-07-02 16:03 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-02 16:03 [gcc r12-1987] Use shift instructions to eliminate redundant compare/test instructions on the H8 Jeff Law

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).