aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2011-10-13 20:20:37 -0700
committerRichard Henderson <rth@gcc.gnu.org>2011-10-13 20:20:37 -0700
commit0772d476effe546701564ee9281fddfd189586f1 (patch)
tree705eec7815466c67d53b2837ca3cd560759f373e /gcc
parentf6293442ba64f9225c4643438bb385eb0c34087a (diff)
downloadgcc-0772d476effe546701564ee9281fddfd189586f1.zip
gcc-0772d476effe546701564ee9281fddfd189586f1.tar.gz
gcc-0772d476effe546701564ee9281fddfd189586f1.tar.bz2
i386: Implement vec_perm_const<mode>.
From-SVN: r179955
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/config/i386/i386-protos.h1
-rw-r--r--gcc/config/i386/i386.c61
-rw-r--r--gcc/config/i386/sse.md21
4 files changed, 88 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9e34eca..81d4f99 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -4,6 +4,11 @@
* config/rs6000/spu.md (vec_permv16qi): New pattern.
+ * config/i386/i386.c (ix86_expand_vec_perm_const): New.
+ * config/i386/i386-protos.h: Update.
+ * config/i386/sse.md (VEC_PERM_CONST): New mode iterator.
+ (vec_perm_const<VEC_PERM_CONST>): New expander.
+
2011-10-13 Jakub Jelinek <jakub@redhat.com>
* config/i386/sse.md (vec_set<mode>): Change V_128 iterator mode
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index eea038e..bdac6ff 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -124,6 +124,7 @@ extern bool ix86_expand_fp_movcc (rtx[]);
extern bool ix86_expand_fp_vcond (rtx[]);
extern bool ix86_expand_int_vcond (rtx[]);
extern void ix86_expand_vec_perm (rtx[]);
+extern bool ix86_expand_vec_perm_const (rtx[]);
extern void ix86_expand_sse_unpack (rtx[], bool, bool);
extern bool ix86_expand_int_addcc (rtx[]);
extern rtx ix86_expand_call (rtx, rtx, rtx, rtx, rtx, bool);
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index a81292b..df6267b 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -36132,6 +36132,67 @@ ix86_expand_vec_perm_builtin (tree exp)
return CONST0_RTX (d.vmode);
}
+bool
+ix86_expand_vec_perm_const (rtx operands[4])
+{
+ struct expand_vec_perm_d d;
+ int i, nelt, which;
+ rtx sel;
+
+ d.target = operands[0];
+ d.op0 = operands[1];
+ d.op1 = operands[2];
+ sel = operands[3];
+
+ d.vmode = GET_MODE (d.target);
+ gcc_assert (VECTOR_MODE_P (d.vmode));
+ d.nelt = nelt = GET_MODE_NUNITS (d.vmode);
+ d.testing_p = false;
+
+ gcc_assert (GET_CODE (sel) == CONST_VECTOR);
+ gcc_assert (XVECLEN (sel, 0) == nelt);
+
+ for (i = which = 0; i < nelt; ++i)
+ {
+ rtx e = XVECEXP (sel, 0, i);
+ int ei = INTVAL (e) & (2 * nelt - 1);
+
+ which |= (ei < nelt ? 1 : 2);
+ d.perm[i] = ei;
+ }
+
+ switch (which)
+ {
+ default:
+ gcc_unreachable();
+
+ case 3:
+ if (!rtx_equal_p (d.op0, d.op1))
+ break;
+
+ /* The elements of PERM do not suggest that only the first operand
+ is used, but both operands are identical. Allow easier matching
+ of the permutation by folding the permutation into the single
+ input vector. */
+ for (i = 0; i < nelt; ++i)
+ if (d.perm[i] >= nelt)
+ d.perm[i] -= nelt;
+ /* FALLTHRU */
+
+ case 1:
+ d.op1 = d.op0;
+ break;
+
+ case 2:
+ for (i = 0; i < nelt; ++i)
+ d.perm[i] -= nelt;
+ d.op0 = d.op1;
+ break;
+ }
+
+ return ix86_expand_vec_perm_builtin_1 (&d);
+}
+
/* Implement targetm.vectorize.builtin_vec_perm_ok. */
static bool
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index 5bf30a8..d5e2de5 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -6236,6 +6236,27 @@
DONE;
})
+(define_mode_iterator VEC_PERM_CONST
+ [(V4SF "TARGET_SSE") (V4SI "TARGET_SSE")
+ (V2DF "TARGET_SSE") (V2DI "TARGET_SSE")
+ (V16QI "TARGET_SSE2") (V8HI "TARGET_SSE2")
+ (V8SF "TARGET_AVX") (V4DF "TARGET_AVX")
+ (V8SI "TARGET_AVX") (V4DI "TARGET_AVX")
+ (V32QI "TARGET_AVX2") (V16HI "TARGET_AVX2")])
+
+(define_expand "vec_perm_const<mode>"
+ [(match_operand:VEC_PERM_CONST 0 "register_operand" "")
+ (match_operand:VEC_PERM_CONST 1 "register_operand" "")
+ (match_operand:VEC_PERM_CONST 2 "register_operand" "")
+ (match_operand:<sseintvecmode> 3 "" "")]
+ ""
+{
+ if (ix86_expand_vec_perm_const (operands))
+ DONE;
+ else
+ FAIL;
+})
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Parallel bitwise logical operations