From c5af628dbe90df6244b33bd7c6a89fbd124068b8 Mon Sep 17 00:00:00 2001 From: Nathan Froyd Date: Fri, 16 Jul 2010 15:25:43 +0000 Subject: [PATCH] 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_): Use scc_comparison_operator constraint. Permit 0 for the consequent operand. Permit any GPR for the alternative operand. (isel_unsigned_): Likewise. From-SVN: r162263 --- gcc/ChangeLog | 13 +++++ gcc/config/rs6000/rs6000.c | 103 +++++++++++++----------------------- gcc/config/rs6000/rs6000.md | 20 +++---- 3 files changed, 59 insertions(+), 77 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8fac566e8804..353ccd388f91 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2010-07-16 Nathan Froyd + + * 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_): Use + scc_comparison_operator constraint. Permit 0 for the consequent + operand. Permit any GPR for the alternative operand. + (isel_unsigned_): Likewise. + 2010-07-16 Jakub Jelinek PR target/44942 diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index c6f67d433eab..d96c1d6f32df 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -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) - { - 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 + 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_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 diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 02602a1f661c..09669159c770 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -6091,13 +6091,13 @@ ;; change the mode underneath our feet and then gets confused trying ;; to reload the value. (define_insn "isel_signed_" - [(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" "* { return output_isel (operands); }" @@ -6105,13 +6105,13 @@ (set_attr "length" "4")]) (define_insn "isel_unsigned_" - [(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" "* { return output_isel (operands); }" -- 2.43.5