diff options
author | Segher Boessenkool <segher@kernel.crashing.org> | 2014-12-10 19:36:18 +0100 |
---|---|---|
committer | Segher Boessenkool <segher@gcc.gnu.org> | 2014-12-10 19:36:18 +0100 |
commit | 969ce0b0a60ac986c6b4f31cbc7c262b7be9f80b (patch) | |
tree | 0508be077c18d6897c83e1f441be0e385af574b9 /gcc | |
parent | 46121d60c508a382e89bd7c4c403e981da09ee4a (diff) | |
download | gcc-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/ChangeLog | 22 | ||||
-rw-r--r-- | gcc/config/rs6000/predicates.md | 6 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.md | 200 |
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" "")))] |