re PR target/64180 (PowerPC carry bit improvements)
authorSegher Boessenkool <segher@kernel.crashing.org>
Wed, 10 Dec 2014 18:36:18 +0000 (19:36 +0100)
committerSegher Boessenkool <segher@gcc.gnu.org>
Wed, 10 Dec 2014 18:36:18 +0000 (19:36 +0100)
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_internal): 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_internal): New.
(subf<mode>3_carry_in_0): New.
(subf<mode>3_carry_in_m1): New.
(subf<mode>3_carry_in_xx): New.

From-SVN: r218594

gcc/ChangeLog
gcc/config/rs6000/predicates.md
gcc/config/rs6000/rs6000.md

index 8ed3e8c9f3807d893f99f9b6424d785eff53d245..f70d81646ed9e7b40fea37ca1c09bf6834053f01 100644 (file)
@@ -1,3 +1,25 @@
+2014-12-10  Segher Boessenkool  <segher@kernel.crashing.org>
+
+       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_internal): 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_internal): New.
+       (subf<mode>3_carry_in_0): New.
+       (subf<mode>3_carry_in_m1): New.
+       (subf<mode>3_carry_in_xx): New.
+
 2014-12-10  Segher Boessenkool  <segher@kernel.crashing.org>
 
        PR target/64180
index ea230a5b29a672839c51f86963269c9b0fd3f115..a19cb2fd39e468b37cf02ec10bc8880c92510a1b 100644 (file)
                 || 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")
index 6712443e051a2ea00a70ba4655cea1212b6a3fed..733cc390f299b7b70a8506a8595d1e23c0de8f8d 100644 (file)
     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_internal"
+  [(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" "")))]
   [(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_internal"
+  [(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" "")))]