aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Froyd <froydnj@codesourcery.com>2010-07-16 15:25:43 +0000
committerNathan Froyd <froydnj@gcc.gnu.org>2010-07-16 15:25:43 +0000
commitc5af628dbe90df6244b33bd7c6a89fbd124068b8 (patch)
treeb6415535bcf129a547077d04dde2e0785807981c
parent8d63d4055e5e853eb82141ee6bb7823904423f3c (diff)
downloadgcc-c5af628dbe90df6244b33bd7c6a89fbd124068b8.zip
gcc-c5af628dbe90df6244b33bd7c6a89fbd124068b8.tar.gz
gcc-c5af628dbe90df6244b33bd7c6a89fbd124068b8.tar.bz2
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
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/config/rs6000/rs6000.c103
-rw-r--r--gcc/config/rs6000/rs6000.md20
3 files changed, 59 insertions, 77 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 8fac566..353ccd3 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index c6f67d4..d96c1d6 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 02602a1..0966915 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_<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); }"