summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSegher Boessenkool <segher@kernel.crashing.org>2015-05-06 17:55:10 +0200
committerSegher Boessenkool <segher@gcc.gnu.org>2015-05-06 17:55:10 +0200
commit29e597d0e6c853b1487ee86357df704a5e0ab618 (patch)
treef9babee25f5605f87d2df60a8e17cafe17462c8d
parent93e956161e843aecdd9ad07574132efb3616d549 (diff)
downloadgcc-29e597d0e6c853b1487ee86357df704a5e0ab618.tar.gz
rs6000.md (cstore<mode>4_signed_imm): New expander.
* config/rs6000/rs6000.md (cstore<mode>4_signed_imm): New expander. (cstore<mode>4_unsigned_imm): New expander. (cstore<mode>4): Remove empty constraint strings. Use the new expanders. From-SVN: r222855
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/config/rs6000/rs6000.md113
2 files changed, 113 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f7188b26496..3b267c8d3a3 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2015-05-06 Segher Boessenkool <segher@kernel.crashing.org>
+
+ * config/rs6000/rs6000.md (cstore<mode>4_signed_imm): New expander.
+ (cstore<mode>4_unsigned_imm): New expander.
+ (cstore<mode>4): Remove empty constraint strings. Use the new
+ expanders.
+
2015-05-06 Yvan Roux <yvan.roux@linaro.org>
PR target/64208
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 2d15d71cc88..7fc2bb1b4ad 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -11787,10 +11787,102 @@
DONE;
})
+(define_expand "cstore<mode>4_signed_imm"
+ [(use (match_operator 1 "signed_comparison_operator"
+ [(match_operand:GPR 2 "gpc_reg_operand")
+ (match_operand:GPR 3 "immediate_operand")]))
+ (clobber (match_operand:GPR 0 "register_operand"))]
+ ""
+{
+ bool invert = false;
+
+ enum rtx_code cond_code = GET_CODE (operands[1]);
+
+ rtx op0 = operands[0];
+ rtx op1 = operands[2];
+ HOST_WIDE_INT val = INTVAL (operands[3]);
+
+ if (cond_code == GE || cond_code == GT)
+ {
+ cond_code = reverse_condition (cond_code);
+ invert = true;
+ }
+
+ if (cond_code == LE)
+ val++;
+
+ rtx tmp = gen_reg_rtx (<MODE>mode);
+ emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
+ rtx x = gen_reg_rtx (<MODE>mode);
+ if (val < 0)
+ emit_insn (gen_and<mode>3 (x, op1, tmp));
+ else
+ emit_insn (gen_ior<mode>3 (x, op1, tmp));
+
+ if (invert)
+ {
+ rtx tmp = gen_reg_rtx (<MODE>mode);
+ emit_insn (gen_one_cmpl<mode>2 (tmp, x));
+ x = tmp;
+ }
+
+ int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
+ emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
+
+ DONE;
+})
+
+(define_expand "cstore<mode>4_unsigned_imm"
+ [(use (match_operator 1 "unsigned_comparison_operator"
+ [(match_operand:GPR 2 "gpc_reg_operand")
+ (match_operand:GPR 3 "immediate_operand")]))
+ (clobber (match_operand:GPR 0 "register_operand"))]
+ ""
+{
+ bool invert = false;
+
+ enum rtx_code cond_code = GET_CODE (operands[1]);
+
+ rtx op0 = operands[0];
+ rtx op1 = operands[2];
+ HOST_WIDE_INT val = INTVAL (operands[3]);
+
+ if (cond_code == GEU || cond_code == GTU)
+ {
+ cond_code = reverse_condition (cond_code);
+ invert = true;
+ }
+
+ if (cond_code == LEU)
+ val++;
+
+ rtx tmp = gen_reg_rtx (<MODE>mode);
+ rtx tmp2 = gen_reg_rtx (<MODE>mode);
+ emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
+ emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
+ rtx x = gen_reg_rtx (<MODE>mode);
+ if (val < 0)
+ emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
+ else
+ emit_insn (gen_and<mode>3 (x, tmp, tmp2));
+
+ if (invert)
+ {
+ rtx tmp = gen_reg_rtx (<MODE>mode);
+ emit_insn (gen_one_cmpl<mode>2 (tmp, x));
+ x = tmp;
+ }
+
+ int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
+ emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
+
+ DONE;
+})
+
(define_expand "cstore<mode>4"
[(use (match_operator 1 "rs6000_cbranch_operator"
- [(match_operand:GPR 2 "gpc_reg_operand" "")
- (match_operand:GPR 3 "reg_or_short_operand" "")]))
+ [(match_operand:GPR 2 "gpc_reg_operand")
+ (match_operand:GPR 3 "reg_or_short_operand")]))
(clobber (match_operand:GPR 0 "register_operand"))]
""
{
@@ -11819,11 +11911,18 @@
emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
operands[2], operands[3]));
- /* The generic code knows tricks to compute signed comparisons against
- zero. Let it do its thing. */
- else if (operands[3] == const0_rtx
- && signed_comparison_operator (operands[1], VOIDmode))
- FAIL;
+ /* For signed comparisons against a constant, we can do some simple
+ bit-twiddling. */
+ else if (signed_comparison_operator (operands[1], VOIDmode)
+ && CONST_INT_P (operands[3]))
+ emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
+ operands[2], operands[3]));
+
+ /* And similarly for unsigned comparisons. */
+ else if (unsigned_comparison_operator (operands[1], VOIDmode)
+ && CONST_INT_P (operands[3]))
+ emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
+ operands[2], operands[3]));
/* Everything else, use the mfcr brute force. */
else