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
This commit is contained in:
Segher Boessenkool 2015-05-06 17:55:10 +02:00 committed by Segher Boessenkool
parent 93e956161e
commit 29e597d0e6
2 changed files with 113 additions and 7 deletions

View file

@ -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

View file

@ -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