rs6000.c (rs6000_emit_sISEL): Let rs6000_emit_int_cmove do all the work.

* config/rs6000/rs6000.c (rs6000_emit_sISEL): Let rs6000_emit_int_cmove
	do all the work.
	(rs6000_emit_int_cmove): Use function pointers for insn generation.
	Don't force values into registers unnecessarily.
	(output_isel): Assert that we're not given conditions we can't handle.
	Delete corresponding code.
	* config/rs6000/rs6000.md (isel_signed_<mode>): Use
	scc_comparison_operator constraint.  Permit 0 for the consequent
	operand.  Permit any GPR for the alternative operand.
	(isel_unsigned_<mode>): Likewise.

From-SVN: r162263
This commit is contained in:
Nathan Froyd 2010-07-16 15:25:43 +00:00 committed by Nathan Froyd
parent 8d63d4055e
commit c5af628dbe
3 changed files with 59 additions and 77 deletions

View file

@ -1,3 +1,16 @@
2010-07-16 Nathan Froyd <froydnj@codesourcery.com>
* config/rs6000/rs6000.c (rs6000_emit_sISEL): Let rs6000_emit_int_cmove
do all the work.
(rs6000_emit_int_cmove): Use function pointers for insn generation.
Don't force values into registers unnecessarily.
(output_isel): Assert that we're not given conditions we can't handle.
Delete corresponding code.
* config/rs6000/rs6000.md (isel_signed_<mode>): Use
scc_comparison_operator constraint. Permit 0 for the consequent
operand. Permit any GPR for the alternative operand.
(isel_unsigned_<mode>): Likewise.
2010-07-16 Jakub Jelinek <jakub@redhat.com>
PR target/44942

View file

@ -15997,53 +15997,12 @@ rs6000_generate_compare (rtx cmp, enum machine_mode mode)
}
/* Emit the RTL for an sCOND pattern. */
/* Emit the RTL for an sISEL pattern. */
void
rs6000_emit_sISEL (enum machine_mode mode, rtx operands[])
rs6000_emit_sISEL (enum machine_mode mode ATTRIBUTE_UNUSED, rtx operands[])
{
rtx condition_rtx;
enum machine_mode op_mode;
enum rtx_code cond_code;
rtx result = operands[0];
condition_rtx = rs6000_generate_compare (operands[1], mode);
cond_code = GET_CODE (condition_rtx);
op_mode = GET_MODE (XEXP (operands[1], 0));
if (op_mode == VOIDmode)
op_mode = GET_MODE (XEXP (operands[1], 1));
if (TARGET_POWERPC64 && GET_MODE (result) == DImode)
{
PUT_MODE (condition_rtx, DImode);
if (cond_code == GEU || cond_code == GTU || cond_code == LEU
|| cond_code == LTU)
emit_insn (gen_isel_unsigned_di (result, condition_rtx,
force_reg (DImode, const1_rtx),
force_reg (DImode, const0_rtx),
XEXP (condition_rtx, 0)));
else
emit_insn (gen_isel_signed_di (result, condition_rtx,
force_reg (DImode, const1_rtx),
force_reg (DImode, const0_rtx),
XEXP (condition_rtx, 0)));
}
else
{
PUT_MODE (condition_rtx, SImode);
if (cond_code == GEU || cond_code == GTU || cond_code == LEU
|| cond_code == LTU)
emit_insn (gen_isel_unsigned_si (result, condition_rtx,
force_reg (SImode, const1_rtx),
force_reg (SImode, const0_rtx),
XEXP (condition_rtx, 0)));
else
emit_insn (gen_isel_signed_si (result, condition_rtx,
force_reg (SImode, const1_rtx),
force_reg (SImode, const0_rtx),
XEXP (condition_rtx, 0)));
}
rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
}
void
@ -16710,6 +16669,9 @@ rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
{
rtx condition_rtx, cr;
enum machine_mode mode = GET_MODE (dest);
enum rtx_code cond_code;
rtx (*isel_func) (rtx, rtx, rtx, rtx, rtx);
bool signedp;
if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode))
return 0;
@ -16718,27 +16680,37 @@ rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
compare, it just looks at the CRx bits set by a previous compare
instruction. */
condition_rtx = rs6000_generate_compare (op, mode);
cond_code = GET_CODE (condition_rtx);
cr = XEXP (condition_rtx, 0);
signedp = GET_MODE (cr) == CCmode;
if (mode == SImode)
isel_func = (mode == SImode
? (signedp ? gen_isel_signed_si : gen_isel_unsigned_si)
: (signedp ? gen_isel_signed_di : gen_isel_unsigned_di));
switch (cond_code)
{
if (GET_MODE (cr) == CCmode)
emit_insn (gen_isel_signed_si (dest, condition_rtx,
true_cond, false_cond, cr));
else
emit_insn (gen_isel_unsigned_si (dest, condition_rtx,
true_cond, false_cond, cr));
}
else
{
if (GET_MODE (cr) == CCmode)
emit_insn (gen_isel_signed_di (dest, condition_rtx,
true_cond, false_cond, cr));
else
emit_insn (gen_isel_unsigned_di (dest, condition_rtx,
true_cond, false_cond, cr));
case LT: case GT: case LTU: case GTU: case EQ:
/* isel handles these directly. */
break;
default:
/* We need to swap the sense of the comparison. */
{
rtx t = true_cond;
true_cond = false_cond;
false_cond = t;
PUT_CODE (condition_rtx, reverse_condition (cond_code));
}
break;
}
false_cond = force_reg (mode, false_cond);
if (true_cond != const0_rtx)
true_cond = force_reg (mode, true_cond);
emit_insn (isel_func (dest, condition_rtx, true_cond, false_cond, cr));
return 1;
}
@ -16748,13 +16720,10 @@ output_isel (rtx *operands)
enum rtx_code code;
code = GET_CODE (operands[1]);
if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
{
PUT_CODE (operands[1], reverse_condition (code));
return "isel %0,%3,%2,%j1";
}
else
return "isel %0,%2,%3,%j1";
gcc_assert (!(code == GE || code == GEU || code == LE || code == LEU || code == NE));
return "isel %0,%2,%3,%j1";
}
void

View file

@ -6091,13 +6091,13 @@
;; change the mode underneath our feet and then gets confused trying
;; to reload the value.
(define_insn "isel_signed_<mode>"
[(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
[(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
(if_then_else:GPR
(match_operator 1 "comparison_operator"
[(match_operand:CC 4 "cc_reg_operand" "y")
(match_operator 1 "scc_comparison_operator"
[(match_operand:CC 4 "cc_reg_operand" "y,y")
(const_int 0)])
(match_operand:GPR 2 "gpc_reg_operand" "b")
(match_operand:GPR 3 "gpc_reg_operand" "b")))]
(match_operand:GPR 2 "reg_or_cint_operand" "O,b")
(match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
"TARGET_ISEL<sel>"
"*
{ return output_isel (operands); }"
@ -6105,13 +6105,13 @@
(set_attr "length" "4")])
(define_insn "isel_unsigned_<mode>"
[(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
[(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
(if_then_else:GPR
(match_operator 1 "comparison_operator"
[(match_operand:CCUNS 4 "cc_reg_operand" "y")
(match_operator 1 "scc_comparison_operator"
[(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
(const_int 0)])
(match_operand:GPR 2 "gpc_reg_operand" "b")
(match_operand:GPR 3 "gpc_reg_operand" "b")))]
(match_operand:GPR 2 "reg_or_cint_operand" "O,b")
(match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
"TARGET_ISEL<sel>"
"*
{ return output_isel (operands); }"