diff mbox

[06/10] rs6000: New add/subf carry insns

Message ID 20141210140030.GA15905@gate.crashing.org
State New
Headers show

Commit Message

Segher Boessenkool Dec. 10, 2014, 2 p.m. UTC
On Mon, Dec 08, 2014 at 10:53:21AM -0500, David Edelsohn wrote:
> As we both noticed, there are a few problems with this patch, so I'll
> wait for a revised version.

Here it is.  It took a bit longer because of a latent problem in combine
(ugh!) that caused mysterious failures in guality (double ugh).

For the carry_in patterns I now have an expander that expands to the
_0 and _m1 cases directly.

Okay for mainline?

Cheers,


Segher



2014-12-10  Segher Boessenkool  <segher@kernel.crashing.org>

gcc/
	PR target/64180
	* config/rs6000/predicates.md (adde_operand): New.
	* config/rs6000/rs6000.md (add<mode>3_carry): New.
	(*add<mode>3_imm_carry_pos): New.
	(*add<mode>3_imm_carry_0): New.
	(*add<mode>3_imm_carry_m1): New.
	(*add<mode>3_imm_carry_neg): New.
	(add<mode>3_carry_in): New.
	(*add<mode>3_carry_in): New.
	(add<mode>3_carry_in_0): New.
	(add<mode>3_carry_in_m1): New.
	(subf<mode>3_carry): New.
	(*subf<mode>3_imm_carry_0): New.
	(*subf<mode>3_imm_carry_m1): New.
	(subf<mode>3_carry_in): New.
	(*subf<mode>3_carry_in): New.
	(subf<mode>3_carry_in_0): New.
	(subf<mode>3_carry_in_m1): New.
	(subf<mode>3_carry_in_xx): New.

---
 gcc/config/rs6000/predicates.md |   6 ++
 gcc/config/rs6000/rs6000.md     | 200 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 206 insertions(+)

Comments

David Edelsohn Dec. 10, 2014, 2:39 p.m. UTC | #1
On Wed, Dec 10, 2014 at 9:00 AM, Segher Boessenkool
<segher@kernel.crashing.org> wrote:
> On Mon, Dec 08, 2014 at 10:53:21AM -0500, David Edelsohn wrote:
>> As we both noticed, there are a few problems with this patch, so I'll
>> wait for a revised version.
>
> Here it is.  It took a bit longer because of a latent problem in combine
> (ugh!) that caused mysterious failures in guality (double ugh).
>
> For the carry_in patterns I now have an expander that expands to the
> _0 and _m1 cases directly.
>
> Okay for mainline?
>
> Cheers,
>
>
> Segher
>
>
>
> 2014-12-10  Segher Boessenkool  <segher@kernel.crashing.org>
>
> gcc/
>         PR target/64180
>         * config/rs6000/predicates.md (adde_operand): New.
>         * config/rs6000/rs6000.md (add<mode>3_carry): New.
>         (*add<mode>3_imm_carry_pos): New.
>         (*add<mode>3_imm_carry_0): New.
>         (*add<mode>3_imm_carry_m1): New.
>         (*add<mode>3_imm_carry_neg): New.
>         (add<mode>3_carry_in): New.
>         (*add<mode>3_carry_in): New.

Please name this *add<mode>3_carry_in_internal

>         (add<mode>3_carry_in_0): New.
>         (add<mode>3_carry_in_m1): New.
>         (subf<mode>3_carry): New.
>         (*subf<mode>3_imm_carry_0): New.
>         (*subf<mode>3_imm_carry_m1): New.
>         (subf<mode>3_carry_in): New.
>         (*subf<mode>3_carry_in): New.

Please name this *subf<mode>3_carry_in_internal

>         (subf<mode>3_carry_in_0): New.
>         (subf<mode>3_carry_in_m1): New.
>         (subf<mode>3_carry_in_xx): New.

Okay with those changes.

Thanks for all of the great improvements!

- David
diff mbox

Patch

diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index ea230a5..a19cb2f 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -788,6 +788,12 @@  (define_predicate "add_operand"
 		 || satisfies_constraint_L (op)")
     (match_operand 0 "gpc_reg_operand")))
 
+;; Return 1 if the operand is either a non-special register, or 0, or -1.
+(define_predicate "adde_operand"
+  (if_then_else (match_code "const_int")
+    (match_test "INTVAL (op) == 0 || INTVAL (op) == -1")
+    (match_operand 0 "gpc_reg_operand")))
+
 ;; Return 1 if OP is a constant but not a valid add_operand.
 (define_predicate "non_add_cint_operand"
   (and (match_code "const_int")
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index dcdb7c1..63ca3c2 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -1634,6 +1634,115 @@  (define_split
     FAIL;
 })
 
+
+(define_insn "add<mode>3_carry"
+  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
+	(plus:P (match_operand:P 1 "gpc_reg_operand" "r")
+		(match_operand:P 2 "reg_or_short_operand" "rI")))
+   (set (reg:P CA_REGNO)
+	(ltu:P (plus:P (match_dup 1)
+		       (match_dup 2))
+	       (match_dup 1)))]
+  ""
+  "add%I2c %0,%1,%2"
+  [(set_attr "type" "add")])
+
+(define_insn "*add<mode>3_imm_carry_pos"
+  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
+	(plus:P (match_operand:P 1 "gpc_reg_operand" "r")
+		(match_operand:P 2 "short_cint_operand" "n")))
+   (set (reg:P CA_REGNO)
+	(geu:P (match_dup 1)
+	       (match_operand:P 3 "const_int_operand" "n")))]
+  "INTVAL (operands[2]) > 0
+   && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
+  "addic %0,%1,%2"
+  [(set_attr "type" "add")])
+
+(define_insn "*add<mode>3_imm_carry_0"
+  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
+	(match_operand:P 1 "gpc_reg_operand" "r"))
+   (set (reg:P CA_REGNO)
+	(const_int 0))]
+  ""
+  "addic %0,%1,0"
+  [(set_attr "type" "add")])
+
+(define_insn "*add<mode>3_imm_carry_m1"
+  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
+	(plus:P (match_operand:P 1 "gpc_reg_operand" "r")
+		(const_int -1)))
+   (set (reg:P CA_REGNO)
+	(ne:P (match_dup 1)
+	      (const_int 0)))]
+  ""
+  "addic %0,%1,-1"
+  [(set_attr "type" "add")])
+
+(define_insn "*add<mode>3_imm_carry_neg"
+  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
+	(plus:P (match_operand:P 1 "gpc_reg_operand" "r")
+		(match_operand:P 2 "short_cint_operand" "n")))
+   (set (reg:P CA_REGNO)
+	(gtu:P (match_dup 1)
+	       (match_operand:P 3 "const_int_operand" "n")))]
+  "INTVAL (operands[2]) < 0
+   && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
+  "addic %0,%1,%2"
+  [(set_attr "type" "add")])
+
+
+(define_expand "add<mode>3_carry_in"
+  [(parallel [
+     (set (match_operand:GPR 0 "gpc_reg_operand")
+	  (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
+			      (match_operand:GPR 2 "adde_operand"))
+		    (reg:GPR CA_REGNO)))
+     (clobber (reg:GPR CA_REGNO))])]
+  ""
+{
+  if (operands[2] == const0_rtx)
+    {
+      emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
+      DONE;
+    }
+  if (operands[2] == constm1_rtx)
+    {
+      emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
+      DONE;
+    }
+})
+
+(define_insn "*add<mode>3_carry_in"
+  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
+	(plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
+			    (match_operand:GPR 2 "gpc_reg_operand" "r"))
+		  (reg:GPR CA_REGNO)))
+   (clobber (reg:GPR CA_REGNO))]
+  ""
+  "adde %0,%1,%2"
+  [(set_attr "type" "add")])
+
+(define_insn "add<mode>3_carry_in_0"
+  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
+	(plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
+		  (reg:GPR CA_REGNO)))
+   (clobber (reg:GPR CA_REGNO))]
+  ""
+  "addze %0,%1"
+  [(set_attr "type" "add")])
+
+(define_insn "add<mode>3_carry_in_m1"
+  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
+	(plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
+			    (reg:GPR CA_REGNO))
+		  (const_int -1)))
+   (clobber (reg:GPR CA_REGNO))]
+  ""
+  "addme %0,%1"
+  [(set_attr "type" "add")])
+
+
 (define_expand "one_cmpl<mode>2"
   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
 	(not:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))]
@@ -1772,6 +1881,97 @@  (define_insn "subf<mode>3_imm"
   [(set_attr "type" "add")])
 
 
+(define_insn "subf<mode>3_carry"
+  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
+	(minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
+		 (match_operand:P 1 "gpc_reg_operand" "r")))
+   (set (reg:P CA_REGNO)
+	(leu:P (match_dup 1)
+	       (match_dup 2)))]
+  ""
+  "subf%I2c %0,%1,%2"
+  [(set_attr "type" "add")])
+
+(define_insn "*subf<mode>3_imm_carry_0"
+  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
+	(neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
+   (set (reg:P CA_REGNO)
+	(eq:P (match_dup 1)
+	      (const_int 0)))]
+  ""
+  "subfic %0,%1,0"
+  [(set_attr "type" "add")])
+
+(define_insn "*subf<mode>3_imm_carry_m1"
+  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
+	(not:P (match_operand:P 1 "gpc_reg_operand" "r")))
+   (set (reg:P CA_REGNO)
+	(const_int 1))]
+  ""
+  "subfic %0,%1,-1"
+  [(set_attr "type" "add")])
+
+
+(define_expand "subf<mode>3_carry_in"
+  [(parallel [
+     (set (match_operand:GPR 0 "gpc_reg_operand")
+	  (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
+			      (reg:GPR CA_REGNO))
+		    (match_operand:GPR 2 "adde_operand")))
+     (clobber (reg:GPR CA_REGNO))])]
+  ""
+{
+  if (operands[2] == const0_rtx)
+    {
+      emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
+      DONE;
+    }
+  if (operands[2] == constm1_rtx)
+    {
+      emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
+      DONE;
+    }
+})
+
+(define_insn "*subf<mode>3_carry_in"
+  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
+	(plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
+			    (reg:GPR CA_REGNO))
+		  (match_operand:GPR 2 "gpc_reg_operand" "r")))
+   (clobber (reg:GPR CA_REGNO))]
+  ""
+  "subfe %0,%1,%2"
+  [(set_attr "type" "add")])
+
+(define_insn "subf<mode>3_carry_in_0"
+  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
+	(plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
+		  (reg:GPR CA_REGNO)))
+   (clobber (reg:GPR CA_REGNO))]
+  ""
+  "subfze %0,%1"
+  [(set_attr "type" "add")])
+
+(define_insn "subf<mode>3_carry_in_m1"
+  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
+	(plus:GPR (minus:GPR (reg:GPR CA_REGNO)
+			     (match_operand:GPR 1 "gpc_reg_operand" "r"))
+		  (const_int -2)))
+   (clobber (reg:GPR CA_REGNO))]
+  ""
+  "subfme %0,%1"
+  [(set_attr "type" "add")])
+
+(define_insn "subf<mode>3_carry_in_xx"
+  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
+	(plus:GPR (reg:GPR CA_REGNO)
+		  (const_int -1)))
+   (clobber (reg:GPR CA_REGNO))]
+  ""
+  "subfe %0,%0,%0"
+  [(set_attr "type" "add")])
+
+
 (define_expand "neg<mode>2"
   [(set (match_operand:SDI 0 "gpc_reg_operand" "")
 	(neg:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))]