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  <seg...@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(+)

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" "")))]
-- 
1.8.1.4

Reply via email to