1/* { dg-do run } */
2/* { dg-options "-O2 -mmmx" } */
3
4#include "mmx-check.h"
5
6#include <mmintrin.h>
7#include <string.h>
8
9#define SHIFT (4)
10
11typedef union {
12  __m64 v;
13  unsigned char c[8];
14  unsigned short int s[4];
15  unsigned long long t;
16  unsigned int u[2];
17}vecInWord;
18
19void mmx_tests (void) __attribute__((noinline));
20void dump64_16 (char *, char *, vecInWord);
21void dump64_32 (char *, char *, vecInWord);
22void dump64_64 (char *, char *, vecInWord);
23int check (const char *, const char *[]);
24
25char buf[8000];
26char comparison[8000];
27static int errors = 0;
28
29vecInWord a64, b64, c64, d64, e64;
30__m64 m64_16, s64, m64_32, m64_64;
31
32const char *reference_mmx[] = {
33  "_mm_srai_pi16 0012 0012 0012 0012 \n",
34  "_mm_sra_pi16 0012 0012 0012 0012 \n",
35  "_mm_srai_pi32 00123456 00123456 \n",
36  "_mm_sra_pi32 00123456 00123456 \n",
37  "_mm_srli_pi16 0012 0012 0012 0012 \n",
38  "_mm_srl_pi16 0012 0012 0012 0012 \n",
39  "_mm_srli_pi32 00123456 00123456 \n",
40  "_mm_srl_pi32 00123456 00123456 \n",
41  "_mm_srli_si64 00123456789abcde\n",
42  "_mm_srl_si64 00123456789abcde\n",
43  "_mm_slli_pi16 1230 1230 1230 1230 \n",
44  "_mm_sll_pi16 1230 1230 1230 1230 \n",
45  "_mm_slli_pi32 12345670 12345670 \n",
46  "_mm_sll_pi32 12345670 12345670 \n",
47  "_mm_slli_si64 123456789abcdef0\n",
48  "_mm_sll_si64 123456789abcdef0\n",
49  ""
50};
51
52
53static void
54mmx_test (void)
55{
56  d64.u[0]  = 0x01234567;
57  d64.u[1]  = 0x01234567;
58
59  m64_32 = d64.v;
60
61  e64.t  = 0x0123456789abcdefULL;
62
63  m64_64 = e64.v;
64
65  a64.s[0] = 0x0123;
66  a64.s[1] = 0x0123;
67  a64.s[2] = 0x0123;
68  a64.s[3] = 0x0123;
69
70  m64_16 = a64.v;
71
72  b64.s[0] = SHIFT;
73  b64.s[1] = 0;
74  b64.s[2] = 0;
75  b64.s[3] = 0;
76
77  s64 = b64.v;
78
79  mmx_tests();
80  check (buf, reference_mmx);
81#ifdef DEBUG
82  printf ("mmx testing:\n");
83  printf (buf);
84  printf ("\ncomparison:\n");
85  printf (comparison);
86#endif
87  buf[0] = '\0';
88
89  if (errors != 0)
90    abort ();
91}
92
93void __attribute__((noinline))
94mmx_tests (void)
95{
96  /* psraw */
97  c64.v = _mm_srai_pi16 (m64_16, SHIFT);
98  dump64_16 (buf, "_mm_srai_pi16", c64);
99  c64.v  = _mm_sra_pi16 (m64_16, s64);
100  dump64_16 (buf, "_mm_sra_pi16", c64);
101
102  /* psrad */
103  c64.v  = _mm_srai_pi32 (m64_32, SHIFT);
104  dump64_32 (buf, "_mm_srai_pi32", c64);
105  c64.v = _mm_sra_pi32 (m64_32, s64);
106  dump64_32 (buf, "_mm_sra_pi32", c64);
107
108  /* psrlw */
109  c64.v = _mm_srli_pi16 (m64_16, SHIFT);
110  dump64_16 (buf, "_mm_srli_pi16", c64);
111  c64.v = _mm_srl_pi16 (m64_16, s64);
112  dump64_16 (buf, "_mm_srl_pi16", c64);
113
114  /* psrld */
115  c64.v = _mm_srli_pi32 (m64_32, SHIFT);
116  dump64_32 (buf, "_mm_srli_pi32", c64);
117  c64.v = _mm_srl_pi32 (m64_32, s64);
118  dump64_32 (buf, "_mm_srl_pi32", c64);
119
120  /* psrlq */
121  c64.v = _mm_srli_si64 (m64_64, SHIFT);
122  dump64_64 (buf, "_mm_srli_si64", c64);
123  c64.v = _mm_srl_si64 (m64_64, s64);
124  dump64_64 (buf, "_mm_srl_si64", c64);
125
126  /* psllw */
127  c64.v = _mm_slli_pi16 (m64_16, SHIFT);
128  dump64_16 (buf, "_mm_slli_pi16", c64);
129  c64.v = _mm_sll_pi16 (m64_16, s64);
130  dump64_16 (buf, "_mm_sll_pi16", c64);
131
132  /* pslld */
133  c64.v = _mm_slli_pi32 (m64_32, SHIFT);
134  dump64_32 (buf, "_mm_slli_pi32", c64);
135  c64.v = _mm_sll_pi32 (m64_32, s64);
136  dump64_32 (buf, "_mm_sll_pi32", c64);
137
138  /* psllq */
139  c64.v = _mm_slli_si64 (m64_64, SHIFT);
140  dump64_64 (buf, "_mm_slli_si64", c64);
141  c64.v = _mm_sll_si64 (m64_64, s64);
142  dump64_64 (buf, "_mm_sll_si64", c64);
143}
144
145void
146dump64_16 (char *buf, char *name, vecInWord x)
147{
148  int i;
149  char *p = buf + strlen (buf);
150
151  sprintf (p, "%s ", name);
152  p += strlen (p);
153
154  for (i=0; i<4; i++)
155    {
156      sprintf (p, "%4.4x ", x.s[i]);
157      p += strlen (p);
158    }
159  strcat (p, "\n");
160}
161
162void
163dump64_32 (char *buf, char *name, vecInWord x)
164{
165  int i;
166  char *p = buf + strlen (buf);
167
168  sprintf (p, "%s ", name);
169  p += strlen (p);
170
171  for (i=0; i<2; i++)
172    {
173      sprintf (p, "%8.8x ", x.u[i]);
174      p += strlen (p);
175    }
176  strcat (p, "\n");
177}
178
179void
180dump64_64 (char *buf, char *name, vecInWord x)
181{
182  char *p = buf + strlen (buf);
183
184  sprintf (p, "%s ", name);
185  p += strlen (p);
186
187#if defined(_WIN32) && !defined(__CYGWIN__)
188  sprintf (p, "%16.16I64x\n", x.t);
189#else
190  sprintf (p, "%16.16llx\n", x.t);
191#endif
192}
193
194int
195check (const char *input, const char *reference[])
196{
197  int broken, i, j, len;
198  const char *p_input;
199  char *p_comparison;
200  int new_errors = 0;
201
202  p_comparison = &comparison[0];
203  p_input = input;
204
205  for (i = 0; *reference[i] != '\0'; i++)
206    {
207      broken = 0;
208      len = strlen (reference[i]);
209      for (j = 0; j < len; j++)
210	{
211	  /* Ignore the terminating NUL characters at the end of every string in 'reference[]'.  */
212	  if (!broken && *p_input != reference[i][j])
213	    {
214	      *p_comparison = '\0';
215	      strcat (p_comparison, " >>> ");
216	      p_comparison += strlen (p_comparison);
217	      new_errors++;
218	      broken = 1;
219	    }
220	  *p_comparison = *p_input;
221	  p_comparison++;
222	  p_input++;
223	}
224      if (broken)
225	{
226	  *p_comparison = '\0';
227	  strcat (p_comparison, "expected:\n");
228	  strcat (p_comparison, reference[i]);
229	  p_comparison += strlen (p_comparison);
230	}
231    }
232  *p_comparison = '\0';
233  strcat (p_comparison, new_errors ? "failure\n\n" : "O.K.\n\n") ;
234  errors += new_errors;
235  return 0;
236}
237