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:
parent
8d63d4055e
commit
c5af628dbe
3 changed files with 59 additions and 77 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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); }"
|
||||
|
|
Loading…
Add table
Reference in a new issue