aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorSegher Boessenkool <segher@kernel.crashing.org>2014-12-10 19:36:18 +0100
committerSegher Boessenkool <segher@gcc.gnu.org>2014-12-10 19:36:18 +0100
commit969ce0b0a60ac986c6b4f31cbc7c262b7be9f80b (patch)
tree0508be077c18d6897c83e1f441be0e385af574b9 /gcc
parent46121d60c508a382e89bd7c4c403e981da09ee4a (diff)
downloadgcc-969ce0b0a60ac986c6b4f31cbc7c262b7be9f80b.zip
gcc-969ce0b0a60ac986c6b4f31cbc7c262b7be9f80b.tar.gz
gcc-969ce0b0a60ac986c6b4f31cbc7c262b7be9f80b.tar.bz2
re PR target/64180 (PowerPC carry bit improvements)
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog22
-rw-r--r--gcc/config/rs6000/predicates.md6
-rw-r--r--gcc/config/rs6000/rs6000.md200
3 files changed, 228 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 8ed3e8c..f70d816 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,6 +1,28 @@
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
* config/rs6000/rs6000.md (*add<mode>3_internal1): Rename to
"*add<mode>3".
(*add<mode>3_internal2, *add<mode>3_internal3, and (their splitters):
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 @@
|| 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 6712443..733cc39 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -1634,6 +1634,115 @@
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" "")))]
@@ -1772,6 +1881,97 @@
[(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" "")))]