aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2011-10-06 10:12:44 -0700
committerRichard Henderson <rth@gcc.gnu.org>2011-10-06 10:12:44 -0700
commit810cfbebfad8981bd8e4aea6a247ad4ee1c24ec0 (patch)
treeacb91c58f47e36a30c602e7af385b23e00d7c86f
parent44167383a18a5e2af75ccccaf2c1ea7b6c334695 (diff)
downloadgcc-810cfbebfad8981bd8e4aea6a247ad4ee1c24ec0.zip
gcc-810cfbebfad8981bd8e4aea6a247ad4ee1c24ec0.tar.gz
gcc-810cfbebfad8981bd8e4aea6a247ad4ee1c24ec0.tar.bz2
i386: Use the proper mode for blend in vshuffle.
From-SVN: r179625
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/i386/i386.c28
2 files changed, 27 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 89905f5..19516c0 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -7,6 +7,12 @@
(vshuffle<mode>): Use it.
(avx_vec_concat<V_256>): Rename from *vec_concat<V_256>_avx.
+ * config/i386/i386.c (ix86_expand_sse_movcc): Use correct mode
+ for vector_all_ones_operand.
+ (ix86_expand_int_vcond): Distinguish between comparison mode
+ and data mode. Allow them to differ.
+ (ix86_expand_vshuffle): Don't force data mode to match maskmode.
+
2001-10-06 Richard Henderson <rth@redhat.com>
* optabs.c (expand_vec_shuffle_expr): Use the proper mode for the
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 9960fd2..2fdf540 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -18941,7 +18941,7 @@ ix86_expand_sse_movcc (rtx dest, rtx cmp, rtx op_true, rtx op_false)
enum machine_mode mode = GET_MODE (dest);
rtx t2, t3, x;
- if (vector_all_ones_operand (op_true, GET_MODE (op_true))
+ if (vector_all_ones_operand (op_true, mode)
&& rtx_equal_p (op_false, CONST0_RTX (mode)))
{
emit_insn (gen_rtx_SET (VOIDmode, dest, cmp));
@@ -19170,7 +19170,8 @@ ix86_expand_fp_vcond (rtx operands[])
bool
ix86_expand_int_vcond (rtx operands[])
{
- enum machine_mode mode = GET_MODE (operands[0]);
+ enum machine_mode data_mode = GET_MODE (operands[0]);
+ enum machine_mode mode = GET_MODE (operands[4]);
enum rtx_code code = GET_CODE (operands[3]);
bool negate = false;
rtx x, cop0, cop1;
@@ -19297,8 +19298,21 @@ ix86_expand_int_vcond (rtx operands[])
}
}
- x = ix86_expand_sse_cmp (operands[0], code, cop0, cop1,
- operands[1+negate], operands[2-negate]);
+ /* Allow the comparison to be done in one mode, but the movcc to
+ happen in another mode. */
+ if (data_mode == mode)
+ {
+ x = ix86_expand_sse_cmp (operands[0], code, cop0, cop1,
+ operands[1+negate], operands[2-negate]);
+ }
+ else
+ {
+ gcc_assert (GET_MODE_SIZE (data_mode) == GET_MODE_SIZE (mode));
+ x = ix86_expand_sse_cmp (gen_lowpart (mode, operands[0]),
+ code, cop0, cop1,
+ operands[1+negate], operands[2-negate]);
+ x = gen_lowpart (data_mode, x);
+ }
ix86_expand_sse_movcc (operands[0], x, operands[1+negate],
operands[2-negate]);
@@ -19533,9 +19547,9 @@ ix86_expand_vshuffle (rtx operands[])
mask = expand_simple_binop (maskmode, AND, mask, vt,
NULL_RTX, 0, OPTAB_DIRECT);
- xops[0] = gen_lowpart (maskmode, operands[0]);
- xops[1] = gen_lowpart (maskmode, t2);
- xops[2] = gen_lowpart (maskmode, t1);
+ xops[0] = operands[0];
+ xops[1] = gen_lowpart (mode, t2);
+ xops[2] = gen_lowpart (mode, t1);
xops[3] = gen_rtx_EQ (maskmode, mask, vt);
xops[4] = mask;
xops[5] = vt;