public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r12-3356] Improve handling of C bit for setcc insns
@ 2021-09-05  4:10 Jeff Law
  0 siblings, 0 replies; only message in thread
From: Jeff Law @ 2021-09-05  4:10 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:b27416a7a91b7e6b6b018411ac85cad556ff9903

commit r12-3356-gb27416a7a91b7e6b6b018411ac85cad556ff9903
Author: Jeff Law <jlaw@localhost.localdomain>
Date:   Sun Sep 5 00:08:34 2021 -0400

    Improve handling of C bit for setcc insns
    
    gcc/
            * config/h8300/h8300.md (QHSI2 mode iterator): New mode iterator.
            * config/h8300/testcompare.md (store_c): Update name, use new
            QHSI2 iterator.
            (store_neg_c, store_shifted_c): New patterns.

Diff:
---
 gcc/config/h8300/h8300.md       |   1 +
 gcc/config/h8300/testcompare.md | 122 +++++++++++++++++++++++++++++++++++++++-
 2 files changed, 120 insertions(+), 3 deletions(-)

diff --git a/gcc/config/h8300/h8300.md b/gcc/config/h8300/h8300.md
index 89bfcf11126..e81e21b103e 100644
--- a/gcc/config/h8300/h8300.md
+++ b/gcc/config/h8300/h8300.md
@@ -223,6 +223,7 @@
 (define_mode_iterator HSI [HI SI])
 
 (define_mode_iterator QHSI [QI HI SI])
+(define_mode_iterator QHSI2 [QI HI SI])
 
 (define_mode_iterator QHSIF [QI HI SI SF])
 
diff --git a/gcc/config/h8300/testcompare.md b/gcc/config/h8300/testcompare.md
index 9ff7a51077e..0ee3e360bea 100644
--- a/gcc/config/h8300/testcompare.md
+++ b/gcc/config/h8300/testcompare.md
@@ -212,11 +212,96 @@
   }
   [(set (attr "length") (symbol_ref "<MODE>mode == SImode ? 6 : 4"))])
 
+;; Similarly, but with a negated result
+(define_insn "*store_neg_c_<mode>"
+  [(set (match_operand:QHSI 0 "register_operand" "=r")
+	(neg:QHSI (ne:QHSI (reg:CCC CC_REG) (const_int 0))))]
+  "reload_completed"
+  {
+    if (<MODE>mode == QImode)
+      return "subx\t%X0,%X0";
+    else if (<MODE>mode == HImode)
+      return "subx\t%X0,%X0\;exts.w\t%T0";
+    else if (<MODE>mode == SImode)
+      return "subx\t%X0,%X0\;exts.w\t%T0\;exts.l\t%S0";
+    gcc_unreachable ();
+  }
+  [(set
+     (attr "length")
+     (symbol_ref "(<MODE>mode == SImode ? 6 : <MODE>mode == HImode ? 4 : 2)"))])
+
+;; Using b[i]st we can store the C bit into any of the low 16 bits of
+;; a destination.  We can also rotate it up into the high bit of a 32 bit
+;; destination.
+(define_insn "*store_shifted_c<mode>"
+  [(set (match_operand:QHSI 0 "register_operand" "=r")
+	(ashift:QHSI (eqne:QHSI (reg:CCC CC_REG) (const_int 0))
+		     (match_operand 1 "immediate_operand" "n")))]
+  "(reload_completed
+    && (INTVAL (operands[1]) == 31 || INTVAL (operands[1]) <= 15))"
+  {
+    if (<CODE> == NE)
+      {
+	if (<MODE>mode == QImode)
+	  return "xor.b\t%X0,%X0\;bst\t%1,%X0";
+	else if (<MODE>mode == HImode && INTVAL (operands[1]) < 8)
+	  return "xor.w\t%T0,%T0\;bst\t%1,%X0";
+	else if (<MODE>mode == HImode)
+	  {
+	    operands[1] = GEN_INT (INTVAL (operands[1]) - 8);
+	    output_asm_insn ("xor.w\t%T0,%T0\;bst\t%1,%t0", operands);
+	    return "";
+	  }
+	else if (<MODE>mode == SImode && INTVAL (operands[1]) == 31)
+	  return "xor.l\t%S0,%S0\;rotxr.l\t%S0";
+	else if (<MODE>mode == SImode && INTVAL (operands[1]) < 8)
+	  return "xor.l\t%S0,%S0\;bst\t%1,%X0";
+	else if (<MODE>mode == SImode)
+	  {
+	    operands[1] = GEN_INT (INTVAL (operands[1]) - 8);
+	    output_asm_insn ("xor.l\t%S0,%S0\;bst\t%1,%t0", operands);
+	    return "";
+	  }
+	gcc_unreachable ();
+      }
+    else if (<CODE> == EQ)
+      {
+	if (<MODE>mode == QImode)
+	  return "xor.b\t%X0,%X0\;bist\t%1,%X0";
+	else if (<MODE>mode == HImode && INTVAL (operands[1]) < 8)
+	  return "xor.w\t%T0,%T0\;bist\t%1,%X0";
+	else if (<MODE>mode == HImode)
+	  {
+	    operands[1] = GEN_INT (INTVAL (operands[1]) - 8);
+	    output_asm_insn ("xor.w\t%T0,%T0\;bist\t%1,%t0", operands);
+	    return "";
+	  }
+	else if (<MODE>mode == SImode && INTVAL (operands[1]) == 31)
+	  return "xor.l\t%S0,%S0\;bixor\t#0,%X0\;rotxr.l\t%S0";
+	else if (<MODE>mode == SImode && INTVAL (operands[1]) < 8)
+	  return "xor.l\t%S0,%S0\;bist\t%1,%X0";
+	else if (<MODE>mode == SImode)
+	  {
+	    operands[1] = GEN_INT (INTVAL (operands[1]) - 8);
+	    output_asm_insn ("xor.l\t%S0,%S0\;bist\t%1,%t0", operands);
+	    return "";
+	  }
+	gcc_unreachable ();
+      }
+    gcc_unreachable ();
+  }
+  [(set
+     (attr "length")
+     (symbol_ref "(<MODE>mode == QImode ? 4
+		   : <MODE>mode == HImode ? 4
+		   : <CODE> == NE ? 6
+		   : INTVAL (operands[1]) == 31 ? 8 : 6)"))])
+
 ;; Recognize this scc and generate code we can match
-(define_insn_and_split "*store_c_i_<mode>"
+(define_insn_and_split "*store_c"
   [(set (match_operand:QHSI 0 "register_operand" "=r")
-	(geultu:QHSI (match_operand:QHSI 1 "register_operand" "r")
-		     (match_operand:QHSI 2 "register_operand" "r")))]
+	(geultu:QHSI (match_operand:QHSI2 1 "register_operand" "r")
+		     (match_operand:QHSI2 2 "register_operand" "r")))]
   ""
   "#"
   "&& reload_completed"
@@ -224,3 +309,34 @@
 	(ltu:CCC (match_dup 1) (match_dup 2)))
    (set (match_dup 0)
 	(<geultu_to_c>:QHSI (reg:CCC CC_REG) (const_int 0)))])
+
+;; We can fold in negation of the result and generate better code than
+;; what the generic bits would do when testing for C == 1
+(define_insn_and_split "*store_neg_c"
+  [(set (match_operand:QHSI 0 "register_operand" "=r")
+	(neg:QHSI
+	  (ltu:QHSI (match_operand:QHSI2 1 "register_operand" "r")
+		    (match_operand:QHSI2 2 "register_operand" "r"))))]
+  ""
+  "#"
+  "&& reload_completed"
+  [(set (reg:CCC CC_REG)
+	(ltu:CCC (match_dup 1) (match_dup 2)))
+   (set (match_dup 0)
+	(neg:QHSI (ne:QHSI (reg:CCC CC_REG) (const_int 0))))])
+
+;; We can use rotates and bst/bist to put the C bit into various places
+;; in the destination.
+(define_insn_and_split "*store_shifted_c"
+  [(set (match_operand:QHSI 0 "register_operand" "=r")
+       (ashift:QHSI (geultu:QHSI (match_operand:QHSI2 1 "register_operand" "r")
+                                 (match_operand:QHSI2 2 "register_operand" "r"))
+		    (match_operand 3 "immediate_operand" "n")))]
+  "INTVAL (operands[3]) == 31 || INTVAL (operands[3]) <= 15"
+  "#"
+  "&& reload_completed"
+  [(set (reg:CCC CC_REG) (ltu:CCC (match_dup 1) (match_dup 2)))
+   (set (match_dup 0)
+	(ashift:QHSI (<geultu_to_c>:QHSI (reg:CCC CC_REG) (const_int 0))
+		     (match_dup 3)))])
+


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

only message in thread, other threads:[~2021-09-05  4:10 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-05  4:10 [gcc r12-3356] Improve handling of C bit for setcc insns 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).