aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH.J. Lu <hongjiu.lu@intel.com>2008-05-21 02:56:10 +0000
committerH.J. Lu <hongjiu.lu@intel.com>2008-05-21 02:56:10 +0000
commit8c42455a696b9870edeb077c43aa53e83df205a3 (patch)
tree50cdde70b0a64faebd689e9583f08fec9266034f
parent7184322bc1be91424477ea3b842a490189b5c2dc (diff)
2008-05-20 H.J. Lu <hongjiu.lu@intel.com>
* config/i386/i386.c (ix86_expand_vector_init_duplicate): Add support for V16HImode and V32QImode. (ix86_expand_vector_init_one_nonzero): Call ix86_expand_vector_set for 256bit AVX modes. (ix86_expand_vector_set): Support 256bit AVX modes. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/ix86/avx@135704 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog.avx8
-rw-r--r--gcc/config/i386/i386.c106
2 files changed, 107 insertions, 7 deletions
diff --git a/gcc/ChangeLog.avx b/gcc/ChangeLog.avx
index 46782f0a10e..272b92abf8c 100644
--- a/gcc/ChangeLog.avx
+++ b/gcc/ChangeLog.avx
@@ -1,5 +1,13 @@
2008-05-20 H.J. Lu <hongjiu.lu@intel.com>
+ * config/i386/i386.c (ix86_expand_vector_init_duplicate): Add
+ support for V16HImode and V32QImode.
+ (ix86_expand_vector_init_one_nonzero): Call ix86_expand_vector_set
+ for 256bit AVX modes.
+ (ix86_expand_vector_set): Support 256bit AVX modes.
+
+2008-05-20 H.J. Lu <hongjiu.lu@intel.com>
+
* tree-vectorizer.c (get_vectype_for_scalar_type): Fix typo.
2008-05-20 Xuepeng Guo <xuepeng.guo@intel.com>
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index e0d1bdac1ff..9b3a1204676 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -24837,14 +24837,16 @@ ix86_expand_vector_init_duplicate (bool mmx_ok, enum machine_mode mode,
case V8SImode:
hmode = V4SImode;
goto half;
+ case V16HImode:
+ hmode = V8HImode;
+ goto half;
+ case V32QImode:
+ hmode = V16QImode;
+ goto half;
half:
{
- rtx tmp;
-
- val = force_reg (GET_MODE_INNER (mode), val);
- x = gen_rtx_VEC_DUPLICATE (hmode, val);
- tmp = gen_reg_rtx (hmode);
- emit_insn (gen_rtx_SET (VOIDmode, tmp, x));
+ rtx tmp = gen_reg_rtx (hmode);
+ ix86_expand_vector_init_duplicate (mmx_ok, hmode, tmp, val);
emit_insn (gen_rtx_SET (VOIDmode, target,
gen_rtx_VEC_CONCAT (mode, tmp, tmp)));
}
@@ -24883,6 +24885,15 @@ ix86_expand_vector_init_one_nonzero (bool mmx_ok, enum machine_mode mode,
break;
case V4HImode:
use_vector_set = TARGET_SSE || TARGET_3DNOW_A;
+ break;
+ case V32QImode:
+ case V16HImode:
+ case V8SImode:
+ case V8SFmode:
+ case V4DImode:
+ case V4DFmode:
+ use_vector_set = TARGET_AVX;
+ break;
default:
break;
}
@@ -25526,8 +25537,12 @@ ix86_expand_vector_set (bool mmx_ok, rtx target, rtx val, int elt)
{
enum machine_mode mode = GET_MODE (target);
enum machine_mode inner_mode = GET_MODE_INNER (mode);
+ enum machine_mode half_mode;
bool use_vec_merge = false;
- rtx tmp;
+ rtx tmp, op0, op1;
+ rtx (*gen_extract) (rtx, rtx);
+ rtx (*gen_insert) (rtx, rtx, rtx);
+ int i, n;
switch (mode)
{
@@ -25675,6 +25690,83 @@ ix86_expand_vector_set (bool mmx_ok, rtx target, rtx val, int elt)
break;
case V8QImode:
+ break;
+
+ case V32QImode:
+ half_mode = V16QImode;
+ n = 16;
+ goto half;
+
+ case V16HImode:
+ half_mode = V8HImode;
+ n = 8;
+ goto half;
+
+ case V8SImode:
+ half_mode = V4SImode;
+ n = 4;
+ goto half;
+
+ case V8SFmode:
+ half_mode = V4SFmode;
+ n = 4;
+ goto half;
+
+ case V4DImode:
+ half_mode = V2DImode;
+ n = 2;
+ goto half;
+
+ case V4DFmode:
+ half_mode = V2DFmode;
+ n = 2;
+ goto half;
+
+half:
+ /* Compute offset. */
+ i = elt / n;
+ elt %= n;
+
+ switch (i)
+ {
+ case 0:
+ gen_extract = gen_avx_vextractf128_pd256_0;
+ gen_insert = gen_avx_vinsertf128_pd256_0;
+ break;
+ case 1:
+ gen_extract = gen_avx_vextractf128_pd256_1;
+ gen_insert = gen_avx_vinsertf128_pd256_1;
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+ /* Cast to V4DFmode. */
+ tmp = gen_reg_rtx (V4DFmode);
+ emit_move_insn (tmp, gen_lowpart (V4DFmode, target));
+
+ /* Extract the half. */
+ op0 = gen_reg_rtx (V2DFmode);
+ emit_insn ((*gen_extract) (op0, tmp));
+
+ /* Cast to half mode. */
+ op1 = gen_reg_rtx (half_mode);
+ emit_move_insn (op1, gen_lowpart (half_mode, op0));
+
+ /* Put val in op1 at elt. */
+ ix86_expand_vector_set (false, op1, val, elt);
+
+ /* Cast to V2DFmode. */
+ op0 = gen_reg_rtx (V2DFmode);
+ emit_move_insn (op0, gen_lowpart (V2DFmode, op1));
+
+ /* Put it back. */
+ emit_insn ((*gen_insert) (tmp, tmp, op0));
+
+ /* Cast to original mode and store in target. */
+ emit_move_insn (target, gen_lowpart (mode, tmp));
+ return;
+
default:
break;
}