rs6000: Implement cstore for signed Pmode register compares

This implements cstore for the last case we do not yet handle, using
the superopt algo from the venerable CWG.  The only integer cases we
do still not handle after this are for -m32 -mpowerpc64.


	* (cstore<mode>4_signed): New expander.
	(cstore<mode>4): Call it.

From-SVN: r231284
This commit is contained in:
Segher Boessenkool 2015-12-04 18:21:49 +01:00 committed by Segher Boessenkool
parent 5c24689633
commit 2f74c72b13
2 changed files with 52 additions and 0 deletions

View File

@ -1,3 +1,8 @@
2015-12-04 Segher Boessenkool <segher&kernel.crashing.org>
* (cstore<mode>4_signed): New expander.
(cstore<mode>4): Call it.
2015-12-04 Jakub Jelinek <jakub@redhat.com>
* tree-tailcall.c (find_tail_calls): Ignore GIMPLE_NOPs.

View File

@ -10525,6 +10525,47 @@
DONE;
}")
(define_expand "cstore<mode>4_signed"
[(use (match_operator 1 "signed_comparison_operator"
[(match_operand:P 2 "gpc_reg_operand")
(match_operand:P 3 "gpc_reg_operand")]))
(clobber (match_operand:P 0 "gpc_reg_operand"))]
""
{
enum rtx_code cond_code = GET_CODE (operands[1]);
rtx op0 = operands[0];
rtx op1 = operands[2];
rtx op2 = operands[3];
if (cond_code == GE || cond_code == LT)
{
cond_code = swap_condition (cond_code);
std::swap (op1, op2);
}
rtx tmp1 = gen_reg_rtx (<MODE>mode);
rtx tmp2 = gen_reg_rtx (<MODE>mode);
rtx tmp3 = gen_reg_rtx (<MODE>mode);
int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
if (cond_code == LE)
emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
else
{
rtx tmp4 = gen_reg_rtx (<MODE>mode);
emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
}
DONE;
})
(define_expand "cstore<mode>4_unsigned"
[(use (match_operator 1 "unsigned_comparison_operator"
[(match_operand:P 2 "gpc_reg_operand" "")
@ -10751,6 +10792,12 @@
emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
operands[2], operands[3]));
/* We also do not want to use mfcr for signed comparisons. */
else if (<MODE>mode == Pmode
&& signed_comparison_operator (operands[1], VOIDmode))
emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
operands[2], operands[3]));
/* Everything else, use the mfcr brute force. */
else
rs6000_emit_sCOND (<MODE>mode, operands);