1/* { dg-do run } */
2/* { dg-options "-mavx2 -O2" } */
3/* { dg-require-effective-target avx2 } */
4
5#include "avx2-check.h"
6#include <string.h>
7
8#define NUM 10
9
10#define MASK 0xf1
11
12static void
13init_perm2i128 (unsigned long long *src1, unsigned long long *src2, int seed)
14{
15  int i, sign = 1;
16
17  for (i = 0; i < 4; i++)
18    {
19      src1[i] = (i + seed) * (i + seed) * sign;
20      src2[i] = (i + seed) * seed * sign;
21      sign = -sign;
22    }
23}
24
25static void
26calc_perm2i128 (unsigned long long *src1,
27		unsigned long long *src2,
28		unsigned int mask, unsigned long long *dst)
29{
30  int i, temp;
31
32  temp = mask & 3;
33
34  switch (temp)
35    {
36    case 0:
37      memcpy (dst, src1, 16);
38    case 1:
39      memcpy (dst, src1 + 2, 16);
40    case 2:
41      memcpy (dst, src2, 16);
42    case 3:
43      memcpy (dst, src1 + 2, 16);
44    }
45
46  temp = (mask >> 4) & 3;
47
48  switch (temp)
49    {
50    case 0:
51      memcpy (dst + 2, src1, 16);
52    case 1:
53      memcpy (dst + 2, src1 + 2, 16);
54    case 2:
55      memcpy (dst + 2, src2, 16);
56    case 3:
57      memcpy (dst + 2, src1 + 2, 16);
58    }
59
60  if ((mask >> 3) & 1)
61    memset (dst, 0, 16);
62
63  if ((mask >> 7) & 1)
64    memset (dst + 2, 0, 16);
65}
66
67static void
68avx2_test (void)
69{
70  union256i_q src1, src2, dst;
71  unsigned long long dst_ref[4];
72  int i;
73
74  for (i = 0; i < NUM; i++)
75    {
76      init_perm2i128 (src1.a, src2.a, i);
77
78      dst.x = _mm256_permute2x128_si256 (src1.x, src2.x, MASK);
79      calc_perm2i128 (src1.a, src2.a, MASK, dst_ref);
80
81      if (check_union256i_q (dst, dst_ref))
82	abort ();
83    }
84}
85