diff mbox series

[1/4] rs6000: New insns setbc and setbcr

Message ID b55a0c9b577853a9f5d0e6d493c150f2964cce6c.1588796541.git.wschmidt@linux.ibm.com
State New
Headers show
Series rs6000: setbnc and friends [pu] | expand

Commit Message

Bill Schmidt May 6, 2020, 8:31 p.m. UTC
New instructions setbc and setbcr.  setbc sets a GPR to 1 if some
condition register bit is set, and 0 otherwise; setbcr does it the
other way around.

2020-05-06  Segher Boessenkool  <segher@kernel.crashing.org>

	* config/rs6000/rs6000.md (setbc_<un>signed_<GPR:mode>): New
	define_insn.
	(*setbcr_<un>signed_<GPR:mode>): Likewise.
	(cstore<mode>4): Use setbc[r] if available.
	(<code><GPR:mode><GPR2:mode>2_isel): Avoid for TARGET_FUTURE.
	(eq<mode>3): Use setbc for TARGET_FUTURE.
	(*eq<mode>3): Avoid for TARGET_FUTURE.
	(ne<mode>3): Replace :P with :GPR; use setbc for TARGET_FUTURE;
	else for non-Pmode, use gen_eq and gen_xor.
	(*ne<mode>3): Avoid for TARGET_FUTURE.
	(*eqsi3_ext<mode>): Avoid for TARGET_FUTURE; fix missing && 1.
---
 gcc/config/rs6000/rs6000.md | 73 +++++++++++++++++++++++++++++++------
 1 file changed, 62 insertions(+), 11 deletions(-)

Comments

Segher Boessenkool May 6, 2020, 11:38 p.m. UTC | #1
Hi!

On Wed, May 06, 2020 at 03:31:08PM -0500, Bill Schmidt wrote:
> 	(ne<mode>3): Replace :P with :GPR; use setbc for TARGET_FUTURE;
> 	else for non-Pmode, use gen_eq and gen_xor.

Before this patch, there was only ne:P, which results in the same thing
(done by generic code).  I should have done this part as a separate
patch, it looks much more involved than it actually is now.


Segher
diff mbox series

Patch

diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 6173994797c..e8dc576779a 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -5138,6 +5138,25 @@  (define_insn "*isel_reversed_<un>signed_<GPR:mode>"
 }
   [(set_attr "type" "isel")])
 
+; Set Boolean Condition (Reverse)
+(define_insn "setbc_<un>signed_<GPR:mode>"
+  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
+	(match_operator:GPR 1 "scc_comparison_operator"
+			[(match_operand:CCEITHER 2 "cc_reg_operand" "y")
+			 (const_int 0)]))]
+  "TARGET_FUTURE"
+  "setbc %0,%j1"
+  [(set_attr "type" "isel")])
+
+(define_insn "*setbcr_<un>signed_<GPR:mode>"
+  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
+	(match_operator:GPR 1 "scc_rev_comparison_operator"
+			[(match_operand:CCEITHER 2 "cc_reg_operand" "y")
+			 (const_int 0)]))]
+  "TARGET_FUTURE"
+  "setbcr %0,%j1"
+  [(set_attr "type" "isel")])
+
 ;; Floating point conditional move
 (define_expand "mov<mode>cc"
    [(set (match_operand:SFDF 0 "gpc_reg_operand")
@@ -11425,6 +11444,10 @@  (define_expand "cstore<mode>4"
    (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
   ""
 {
+  /* Everything is best done with setbc[r] if available.  */
+  if (TARGET_FUTURE)
+    rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
+
   /* Expanding EQ and NE directly to some machine instructions does not help
      but does hurt combine.  So don't.  */
   if (GET_CODE (operands[1]) == EQ)
@@ -11837,7 +11860,7 @@  (define_insn_and_split "<code><GPR:mode><GPR2:mode>2_isel"
    (clobber (match_scratch:GPR 3 "=r"))
    (clobber (match_scratch:GPR 4 "=r"))
    (clobber (match_scratch:<UNS> 5 "=y"))]
-  "TARGET_ISEL
+  "!TARGET_FUTURE && TARGET_ISEL
    && !(<CODE> == EQ && operands[2] == const0_rtx)
    && !(<CODE> == NE && operands[2] == const0_rtx
 	&& <GPR:MODE>mode == Pmode && <GPR2:MODE>mode == Pmode)"
@@ -11917,6 +11940,16 @@  (define_expand "eq<mode>3"
      (clobber (match_scratch:GPR 4 "=r"))])]
   ""
 {
+  if (TARGET_FUTURE)
+    {
+      rtx cc = gen_reg_rtx (CCmode);
+      rtx compare = gen_rtx_COMPARE (CCmode, operands[1], operands[2]);
+      emit_insn (gen_rtx_SET (cc, compare));
+      rtx eq = gen_rtx_fmt_ee (EQ, <MODE>mode, cc, const0_rtx);
+      emit_insn (gen_setbc_signed_<mode> (operands[0], eq, cc));
+      DONE;
+    }
+
   if (TARGET_ISEL && operands[2] != const0_rtx)
     {
       emit_insn (gen_eq<mode><mode>2_isel (operands[0], operands[1],
@@ -11931,7 +11964,7 @@  (define_insn_and_split "*eq<mode>3"
 		(match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
    (clobber (match_scratch:GPR 3 "=r"))
    (clobber (match_scratch:GPR 4 "=r"))]
-  "!(TARGET_ISEL && operands[2] != const0_rtx)"
+  "!TARGET_FUTURE && !(TARGET_ISEL && operands[2] != const0_rtx)"
   "#"
   "&& 1"
   [(set (match_dup 4)
@@ -11955,14 +11988,32 @@  (define_insn_and_split "*eq<mode>3"
 
 (define_expand "ne<mode>3"
   [(parallel [
-     (set (match_operand:P 0 "gpc_reg_operand" "=r")
-	  (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
-		(match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
-     (clobber (match_scratch:P 3 "=r"))
-     (clobber (match_scratch:P 4 "=r"))
-     (clobber (reg:P CA_REGNO))])]
+     (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
+	  (ne:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
+		(match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
+     (clobber (match_scratch:GPR 3 "=r"))
+     (clobber (match_scratch:GPR 4 "=r"))
+     (clobber (reg:GPR CA_REGNO))])]
   ""
 {
+  if (TARGET_FUTURE)
+    {
+      rtx cc = gen_reg_rtx (CCmode);
+      rtx compare = gen_rtx_COMPARE (CCmode, operands[1], operands[2]);
+      emit_insn (gen_rtx_SET (cc, compare));
+      rtx ne = gen_rtx_fmt_ee (NE, <MODE>mode, cc, const0_rtx);
+      emit_insn (gen_setbc_signed_<mode> (operands[0], ne, cc));
+      DONE;
+    }
+
+  if (<MODE>mode != Pmode)
+    {
+      rtx x = gen_reg_rtx (<MODE>mode);
+      emit_insn (gen_eq<mode>3 (x, operands[1], operands[2]));
+      emit_insn (gen_xor<mode>3 (operands[0], x, const1_rtx));
+      DONE;
+    }
+
   if (TARGET_ISEL && operands[2] != const0_rtx)
     {
       emit_insn (gen_ne<mode><mode>2_isel (operands[0], operands[1],
@@ -11978,7 +12029,7 @@  (define_insn_and_split "*ne<mode>3"
    (clobber (match_scratch:P 3 "=r"))
    (clobber (match_scratch:P 4 "=r"))
    (clobber (reg:P CA_REGNO))]
-  "!(TARGET_ISEL && operands[2] != const0_rtx)"
+  "!TARGET_FUTURE && !(TARGET_ISEL && operands[2] != const0_rtx)"
   "#"
   "&& 1"
   [(parallel [(set (match_dup 4)
@@ -12205,9 +12256,9 @@  (define_insn_and_split "*eqsi3_ext<mode>"
 		  (match_operand:SI 2 "scc_eq_operand" "rKLI")))
    (clobber (match_scratch:SI 3 "=r"))
    (clobber (match_scratch:SI 4 "=r"))]
-  ""
+  "!TARGET_FUTURE"
   "#"
-  ""
+  "&& 1"
   [(set (match_dup 4)
 	(clz:SI (match_dup 3)))
    (set (match_dup 0)