1/* { dg-do run } */
2/* { dg-require-effective-target xop } */
3/* { dg-options "-O2 -mxop" } */
4
5#include "xop-check.h"
6
7#include <x86intrin.h>
8#include <string.h>
9
10#define NUM 10
11
12union
13{
14  __m128i x[NUM];
15  signed char ssi[NUM * 16];
16  short si[NUM * 8];
17  int li[NUM * 4];
18  long long lli[NUM * 2];
19} dst, res, src1;
20
21static void
22init_sbyte ()
23{
24  int i;
25  for (i=0; i < NUM * 16; i++)
26    src1.ssi[i] = i;
27}
28
29static void
30init_sword ()
31{
32  int i;
33  for (i=0; i < NUM * 8; i++)
34    src1.si[i] = i;
35}
36
37
38static void
39init_sdword ()
40{
41  int i;
42  for (i=0; i < NUM * 4; i++)
43    src1.li[i] = i;
44}
45
46static int
47check_sbyte2word ()
48{
49  int i, j, s, t, check_fails = 0;
50  for (i = 0; i < NUM * 16; i = i + 16)
51    {
52      for (j = 0; j < 8; j++)
53	{
54	  t = i + (2 * j);
55	  s = (i / 2) + j;
56	  res.si[s] = src1.ssi[t] - src1.ssi[t + 1] ;
57	  if (res.si[s] != dst.si[s])
58	    check_fails++;
59	}
60    }
61}
62
63static int
64check_sword2dword ()
65{
66  int i, j, s, t, check_fails = 0;
67  for (i = 0; i < (NUM * 8); i = i + 8)
68    {
69      for (j = 0; j < 4; j++)
70	{
71	  t = i + (2 * j);
72	  s = (i / 2) + j;
73	  res.li[s] = src1.si[t] - src1.si[t + 1] ;
74	  if (res.li[s] != dst.li[s])
75	    check_fails++;
76	}
77    }
78}
79
80static int
81check_dword2qword ()
82{
83  int i, j, s, t, check_fails = 0;
84  for (i = 0; i < (NUM * 4); i = i + 4)
85    {
86      for (j = 0; j < 2; j++)
87	{
88	  t = i + (2 * j);
89	  s = (i / 2) + j;
90	  res.lli[s] = src1.li[t] - src1.li[t + 1] ;
91	  if (res.lli[s] != dst.lli[s])
92	    check_fails++;
93	}
94    }
95}
96
97static void
98xop_test (void)
99{
100  int i;
101
102  /* Check hsubbw */
103  init_sbyte ();
104
105  for (i = 0; i < NUM; i++)
106    dst.x[i] = _mm_hsubw_epi8 (src1.x[i]);
107
108  if (check_sbyte2word())
109  abort ();
110
111
112  /* Check hsubwd */
113  init_sword ();
114
115  for (i = 0; i < (NUM ); i++)
116    dst.x[i] = _mm_hsubd_epi16 (src1.x[i]);
117
118  if (check_sword2dword())
119    abort ();
120
121   /* Check hsubdq */
122  init_sdword ();
123    for (i = 0; i < NUM; i++)
124    dst.x[i] = _mm_hsubq_epi32 (src1.x[i]);
125
126  if (check_dword2qword())
127    abort ();
128}
129