OSDN Git Service

f07a8cbc99bbb886e4ea1bfee763d5260aae0989
[pf3gnuchains/gcc-fork.git] / gcc / testsuite / gcc.target / i386 / sse-6.c
1 /* { dg-do run } */
2 /* { dg-options "-O2 -msse2" } */
3
4 #include "sse2-check.h"
5
6 #include <emmintrin.h>
7 #include <string.h>
8
9 #define SHIFT (4)
10
11 typedef union {
12   __m128i v;
13   unsigned int s[4];
14   unsigned short int t[8];
15   unsigned long long u[2];
16   unsigned char c[16];
17 }vecInLong;
18
19 void sse2_tests (void) __attribute__((noinline));
20 void dump128_16 (char *, char *, vecInLong);
21 void dump128_32 (char *, char *, vecInLong);
22 void dump128_64 (char *, char *, vecInLong);
23 void dump128_128 (char *, char *, vecInLong);
24 int check (const char *, const char *[]);
25
26 char buf[8000];
27 char comparison[8000];
28 static int errors = 0;
29
30 vecInLong a128, b128, c128, d128, e128, f128;
31 __m128i m128_16, m128_32, s128, m128_64, m128_128;
32 __m64 m64_16, s64, m64_32, m64_64;
33
34 const char *reference_sse2[] = {
35   "_mm_srai_epi16 0012 0012 0012 0012 0012 0012 0012 0012 \n",
36   "_mm_sra_epi16 0012 0012 0012 0012 0012 0012 0012 0012 \n",
37   "_mm_srai_epi32 00123456 00123456 00123456 00123456 \n",
38   "_mm_sra_epi32 00123456 00123456 00123456 00123456 \n",
39   "_mm_srli_epi16 0012 0012 0012 0012 0012 0012 0012 0012 \n",
40   "_mm_srl_epi16 0012 0012 0012 0012 0012 0012 0012 0012 \n",
41   "_mm_srli_epi32 00123456 00123456 00123456 00123456 \n",
42   "_mm_srl_epi32 00123456 00123456 00123456 00123456 \n",
43   "_mm_srli_epi64 00123456789abcde 00123456789abcde \n",
44   "_mm_srl_epi64 00123456789abcde 00123456789abcde \n",
45   "_mm_srli_si128 (byte shift)  00000000ffeeddccbbaa998877665544\n",
46   "_mm_slli_epi16 1230 1230 1230 1230 1230 1230 1230 1230 \n",
47   "_mm_sll_epi16 1230 1230 1230 1230 1230 1230 1230 1230 \n",
48   "_mm_slli_epi32 12345670 12345670 12345670 12345670 \n",
49   "_mm_sll_epi32 12345670 12345670 12345670 12345670 \n",
50   "_mm_slli_epi64 123456789abcdef0 123456789abcdef0 \n",
51   "_mm_sll_epi64 123456789abcdef0 123456789abcdef0 \n",
52   "_mm_sll_si128 (byte shift) bbaa9988776655443322110000000000\n",
53   "_mm_shuffle_epi32 ffeeddcc bbaa9988 77665544 33221100 \n",
54   "_mm_shuffelo_epi16 7766 5544 3322 1100 9988 bbaa ddcc ffee \n",
55   "_mm_shuffehi_epi16 1100 3322 5544 7766 ffee ddcc bbaa 9988 \n",
56   ""
57 };
58
59 static void
60 sse2_test (void)
61 {
62   a128.s[0] = 0x01234567;
63   a128.s[1] = 0x01234567;
64   a128.s[2] = 0x01234567;
65   a128.s[3] = 0x01234567;
66
67   m128_32 = a128.v;
68
69   d128.u[0] = 0x0123456789abcdefULL;
70   d128.u[1] = 0x0123456789abcdefULL;
71
72   m128_64 = d128.v;
73
74   /* This is the 128-bit constant 0x00112233445566778899aabbccddeeff,
75      expressed as two little-endian 64-bit words.  */
76   e128.u[0] = 0x7766554433221100ULL;
77   e128.u[1] = 0xffeeddccbbaa9988ULL;
78
79   f128.t[0] = 0x0123;
80   f128.t[1] = 0x0123;
81   f128.t[2] = 0x0123;
82   f128.t[3] = 0x0123;
83   f128.t[4] = 0x0123;
84   f128.t[5] = 0x0123;
85   f128.t[6] = 0x0123;
86   f128.t[7] = 0x0123;
87
88   m128_16 = f128.v;
89
90   m128_128 = e128.v;
91
92   b128.s[0] = SHIFT;
93   b128.s[1] = 0;
94   b128.s[2] = 0;
95   b128.s[3] = 0;
96
97   s128 = b128.v;
98
99   sse2_tests();
100   check (buf, reference_sse2);
101 #ifdef DEBUG
102   printf ("sse2 testing:\n");
103   printf (buf);
104   printf ("\ncomparison:\n");
105   printf (comparison);
106 #endif
107   buf[0] = '\0';
108
109   if (errors != 0)
110     abort ();
111 }
112
113 void __attribute__((noinline))
114 sse2_tests (void)
115 {
116   /* psraw */
117   c128.v = _mm_srai_epi16 (m128_16, SHIFT);
118   dump128_16 (buf, "_mm_srai_epi16", c128);
119   c128.v = _mm_sra_epi16 (m128_16, s128);
120   dump128_16 (buf, "_mm_sra_epi16", c128);
121
122   /* psrad */
123   c128.v = _mm_srai_epi32 (m128_32, SHIFT);
124   dump128_32 (buf, "_mm_srai_epi32", c128);
125   c128.v = _mm_sra_epi32 (m128_32, s128);
126   dump128_32 (buf, "_mm_sra_epi32", c128);
127
128   /* psrlw */
129   c128.v = _mm_srli_epi16 (m128_16, SHIFT);
130   dump128_16 (buf, "_mm_srli_epi16", c128);
131   c128.v = _mm_srl_epi16 (m128_16, s128);
132   dump128_16 (buf, "_mm_srl_epi16", c128);
133
134   /* psrld */
135   c128.v = _mm_srli_epi32 (m128_32, SHIFT);
136   dump128_32 (buf, "_mm_srli_epi32", c128);
137   c128.v = _mm_srl_epi32 (m128_32, s128);
138   dump128_32 (buf, "_mm_srl_epi32", c128);
139
140   /* psrlq */
141   c128.v = _mm_srli_epi64 (m128_64, SHIFT);
142   dump128_64 (buf, "_mm_srli_epi64", c128);
143   c128.v = _mm_srl_epi64 (m128_64, s128);
144   dump128_64 (buf, "_mm_srl_epi64", c128);
145
146   /* psrldq */
147   c128.v = _mm_srli_si128 (m128_128, SHIFT);
148   dump128_128 (buf, "_mm_srli_si128 (byte shift) ", c128);
149
150   /* psllw */
151   c128.v = _mm_slli_epi16 (m128_16, SHIFT);
152   dump128_16 (buf, "_mm_slli_epi16", c128);
153   c128.v = _mm_sll_epi16 (m128_16, s128);
154   dump128_16 (buf, "_mm_sll_epi16", c128);
155
156   /* pslld */
157   c128.v = _mm_slli_epi32 (m128_32, SHIFT);
158   dump128_32 (buf, "_mm_slli_epi32", c128);
159   c128.v = _mm_sll_epi32 (m128_32, s128);
160   dump128_32 (buf, "_mm_sll_epi32", c128);
161
162   /* psllq */
163   c128.v = _mm_slli_epi64 (m128_64, SHIFT);
164   dump128_64 (buf, "_mm_slli_epi64", c128);
165   c128.v = _mm_sll_epi64 (m128_64, s128);
166   dump128_64 (buf, "_mm_sll_epi64", c128);
167
168   /* pslldq */
169   c128.v = _mm_slli_si128 (m128_128, SHIFT);
170   dump128_128 (buf, "_mm_sll_si128 (byte shift)", c128);
171
172   /* Shuffle constant 0x1b == 0b_00_01_10_11, e.g. swap words: ABCD => DCBA.  */
173
174   /* pshufd */
175   c128.v = _mm_shuffle_epi32 (m128_128, 0x1b);
176   dump128_32 (buf, "_mm_shuffle_epi32", c128);
177
178   /* pshuflw */
179   c128.v = _mm_shufflelo_epi16 (m128_128, 0x1b);
180   dump128_16 (buf, "_mm_shuffelo_epi16", c128);
181
182   /* pshufhw */
183   c128.v = _mm_shufflehi_epi16 (m128_128, 0x1b);
184   dump128_16 (buf, "_mm_shuffehi_epi16", c128);
185 }
186
187 void
188 dump128_16 (char *buf, char *name, vecInLong x)
189 {
190   int i;
191   char *p = buf + strlen (buf);
192
193   sprintf (p, "%s ", name);
194   p += strlen (p);
195
196   for (i=0; i<8; i++)
197     {
198       sprintf (p, "%4.4x ", x.t[i]);
199       p += strlen (p);
200     }
201   strcat (p, "\n");
202 }
203
204 void
205 dump128_32 (char *buf, char *name, vecInLong x)
206 {
207   int i;
208   char *p = buf + strlen (buf);
209
210   sprintf (p, "%s ", name);
211   p += strlen (p);
212
213   for (i=0; i<4; i++)
214     {
215       sprintf (p, "%8.8x ", x.s[i]);
216       p += strlen (p);
217     }
218   strcat (p, "\n");
219 }
220
221 void
222 dump128_64 (char *buf, char *name, vecInLong x)
223 {
224   int i;
225   char *p = buf + strlen (buf);
226
227   sprintf (p, "%s ", name);
228   p += strlen (p);
229
230   for (i=0; i<2; i++)
231     {
232       sprintf (p, "%16.16llx ", x.u[i]);
233       p += strlen (p);
234     }
235   strcat (p, "\n");
236 }
237
238 void
239 dump128_128 (char *buf, char *name, vecInLong x)
240 {
241   int i;
242   char *p = buf + strlen (buf);
243
244   sprintf (p, "%s ", name);
245   p += strlen (p);
246
247   for (i=15; i>=0; i--)
248     {
249       /* This is cheating; we don't have a 128-bit int format code.
250          Running the loop backwards to compensate for the
251          little-endian layout. */
252       sprintf (p, "%2.2x", x.c[i]);
253       p += strlen (p);
254     }
255   strcat (p, "\n");
256 }
257
258 int
259 check (const char *input, const char *reference[])
260 {
261   int broken, i, j, len;
262   const char *p_input;
263   char *p_comparison;
264   int new_errors = 0;
265
266   p_comparison = &comparison[0];
267   p_input = input;
268
269   for (i = 0; *reference[i] != '\0'; i++)
270     {
271       broken = 0;
272       len = strlen (reference[i]);
273       for (j = 0; j < len; j++)
274         {
275           /* Ignore the terminating NUL characters at the end of every string in 'reference[]'.  */
276           if (!broken && *p_input != reference[i][j])
277             {
278               *p_comparison = '\0';
279               strcat (p_comparison, " >>> ");
280               p_comparison += strlen (p_comparison);
281               new_errors++;
282               broken = 1;
283             }
284           *p_comparison = *p_input;
285           p_comparison++;
286           p_input++;
287         }
288       if (broken)
289         {
290           *p_comparison = '\0';
291           strcat (p_comparison, "expected:\n");
292           strcat (p_comparison, reference[i]);
293           p_comparison += strlen (p_comparison);
294         }
295     }
296   *p_comparison = '\0';
297   strcat (p_comparison, new_errors ? "failure\n\n" : "O.K.\n\n") ;
298   errors += new_errors;
299   return 0;
300 }