OSDN Git Service

7ec58f11a447ac2ea2740dff421a455a17fc8c47
[pf3gnuchains/gcc-fork.git] / gcc / testsuite / gcc.target / i386 / ssse3-palignr.c
1 /* { dg-do run { target i?86-*-* x86_64-*-* } } */
2 /* { dg-require-effective-target ssse3 } */
3 /* { dg-options "-O2 -mssse3" } */
4 #include <tmmintrin.h>
5 #include <string.h>
6 #include <stdlib.h>
7 #include "../../gcc.dg/i386-cpuid.h"
8 #include "ssse3-vals.h"
9
10 static void ssse3_test (void);
11
12 int
13 main ()
14 {
15   unsigned long cpu_facilities;
16  
17   cpu_facilities = i386_cpuid_ecx ();
18
19   /* Run SSSE3 test only if host has SSSE3 support.  */
20   if ((cpu_facilities & bit_SSSE3))
21     ssse3_test ();
22
23   exit (0);
24 }
25
26 /* Test the 64-bit form */
27 static void
28 ssse3_test_palignr (int *i1, int *i2, unsigned int imm, int *r)
29 {
30   __m64 t1 = *(__m64 *) i1;
31   __m64 t2 = *(__m64 *) i2;
32
33   switch (imm)
34     {
35     case 0:
36       *(__m64 *) r = _mm_alignr_pi8 (t1, t2, 0);
37       break;
38     case 1:
39       *(__m64 *) r = _mm_alignr_pi8 (t1, t2, 1);
40       break;
41     case 2:
42       *(__m64 *) r = _mm_alignr_pi8 (t1, t2, 2);
43       break;
44     case 3:
45       *(__m64 *) r = _mm_alignr_pi8 (t1, t2, 3);
46       break;
47     case 4:
48       *(__m64 *) r = _mm_alignr_pi8 (t1, t2, 4);
49       break;
50     case 5:
51       *(__m64 *) r = _mm_alignr_pi8 (t1, t2, 5);
52       break;
53     case 6:
54       *(__m64 *) r = _mm_alignr_pi8 (t1, t2, 6);
55       break;
56     case 7:
57       *(__m64 *) r = _mm_alignr_pi8 (t1, t2, 7);
58       break;
59     case 8:
60       *(__m64 *) r = _mm_alignr_pi8 (t1, t2, 8);
61       break;
62     case 9:
63       *(__m64 *) r = _mm_alignr_pi8 (t1, t2, 9);
64       break;
65     case 10:
66       *(__m64 *) r = _mm_alignr_pi8 (t1, t2, 10);
67       break;
68     case 11:
69       *(__m64 *) r = _mm_alignr_pi8 (t1, t2, 11);
70       break;
71     case 12:
72       *(__m64 *) r = _mm_alignr_pi8 (t1, t2, 12);
73       break;
74     case 13:
75       *(__m64 *) r = _mm_alignr_pi8 (t1, t2, 13);
76       break;
77     case 14:
78       *(__m64 *) r = _mm_alignr_pi8 (t1, t2, 14);
79       break;
80     case 15:
81       *(__m64 *) r = _mm_alignr_pi8 (t1, t2, 15);
82       break;
83     default:
84       *(__m64 *) r = _mm_alignr_pi8 (t1, t2, 16);
85       break;
86     }
87
88    _mm_empty();
89 }
90
91 /* Test the 128-bit form */
92 static void
93 ssse3_test_palignr128 (int *i1, int *i2, unsigned int imm, int *r)
94 {
95   /* Assumes incoming pointers are 16-byte aligned */
96   __m128i t1 = *(__m128i *) i1;
97   __m128i t2 = *(__m128i *) i2;
98
99   switch (imm)
100     {
101     case 0:
102       *(__m128i *) r = _mm_alignr_epi8 (t1, t2, 0);
103       break;
104     case 1:
105       *(__m128i *) r = _mm_alignr_epi8 (t1, t2, 1);
106       break;
107     case 2:
108       *(__m128i *) r = _mm_alignr_epi8 (t1, t2, 2);
109       break;
110     case 3:
111       *(__m128i *) r = _mm_alignr_epi8 (t1, t2, 3);
112       break;
113     case 4:
114       *(__m128i *) r = _mm_alignr_epi8 (t1, t2, 4);
115       break;
116     case 5:
117       *(__m128i *) r = _mm_alignr_epi8 (t1, t2, 5);
118       break;
119     case 6:
120       *(__m128i *) r = _mm_alignr_epi8 (t1, t2, 6);
121       break;
122     case 7:
123       *(__m128i *) r = _mm_alignr_epi8 (t1, t2, 7);
124       break;
125     case 8:
126       *(__m128i *) r = _mm_alignr_epi8 (t1, t2, 8);
127       break;
128     case 9:
129       *(__m128i *) r = _mm_alignr_epi8 (t1, t2, 9);
130       break;
131     case 10:
132       *(__m128i *) r = _mm_alignr_epi8 (t1, t2, 10);
133       break;
134     case 11:
135       *(__m128i *) r = _mm_alignr_epi8 (t1, t2, 11);
136       break;
137     case 12:
138       *(__m128i *) r = _mm_alignr_epi8 (t1, t2, 12);
139       break;
140     case 13:
141       *(__m128i *) r = _mm_alignr_epi8 (t1, t2, 13);
142       break;
143     case 14:
144       *(__m128i *) r = _mm_alignr_epi8 (t1, t2, 14);
145       break;
146     case 15:
147       *(__m128i *) r = _mm_alignr_epi8 (t1, t2, 15);
148       break;
149     case 16:
150       *(__m128i *) r = _mm_alignr_epi8 (t1, t2, 16);
151       break;
152     case 17:
153       *(__m128i *) r = _mm_alignr_epi8 (t1, t2, 17);
154       break;
155     case 18:
156       *(__m128i *) r = _mm_alignr_epi8 (t1, t2, 18);
157       break;
158     case 19:
159       *(__m128i *) r = _mm_alignr_epi8 (t1, t2, 19);
160       break;
161     case 20:
162       *(__m128i *) r = _mm_alignr_epi8 (t1, t2, 20);
163       break;
164     case 21:
165       *(__m128i *) r = _mm_alignr_epi8 (t1, t2, 21);
166       break;
167     case 22:
168       *(__m128i *) r = _mm_alignr_epi8 (t1, t2, 22);
169       break;
170     case 23:
171       *(__m128i *) r = _mm_alignr_epi8 (t1, t2, 23);
172       break;
173     case 24:
174       *(__m128i *) r = _mm_alignr_epi8 (t1, t2, 24);
175       break;
176     case 25:
177       *(__m128i *) r = _mm_alignr_epi8 (t1, t2, 25);
178       break;
179     case 26:
180       *(__m128i *) r = _mm_alignr_epi8 (t1, t2, 26);
181       break;
182     case 27:
183       *(__m128i *) r = _mm_alignr_epi8 (t1, t2, 27);
184       break;
185     case 28:
186       *(__m128i *) r = _mm_alignr_epi8 (t1, t2, 28);
187       break;
188     case 29:
189       *(__m128i *) r = _mm_alignr_epi8 (t1, t2, 29);
190       break;
191     case 30:
192       *(__m128i *) r = _mm_alignr_epi8 (t1, t2, 30);
193       break;
194     case 31:
195       *(__m128i *) r = _mm_alignr_epi8 (t1, t2, 31);
196       break;
197     default:
198       *(__m128i *) r = _mm_alignr_epi8 (t1, t2, 32);
199       break;
200     }
201 }
202
203 /* Routine to manually compute the results */
204 static void
205 compute_correct_result_128 (int *i1, int *i2, unsigned int imm, int *r)
206 {
207   char buf [32];
208   char *bout = (char *) r;
209   int i;
210
211   memcpy (&buf[0], i2, 16);
212   memcpy (&buf[16], i1, 16);
213
214   for (i = 0; i < 16; i++)
215     if (imm >= 32 || imm + i >= 32)
216       bout[i] = 0;
217     else
218       bout[i] = buf[imm + i];
219 }
220
221 static void
222 compute_correct_result_64 (int *i1, int *i2, unsigned int imm, int *r)
223 {
224   char buf [16];
225   char *bout = (char *)r;
226   int i;
227
228   /* Handle the first half */
229   memcpy (&buf[0], i2, 8);
230   memcpy (&buf[8], i1, 8);
231
232   for (i = 0; i < 8; i++)
233     if (imm >= 16 || imm + i >= 16)
234       bout[i] = 0;
235     else
236       bout[i] = buf[imm + i];
237
238   /* Handle the second half */
239   memcpy (&buf[0], &i2[2], 8);
240   memcpy (&buf[8], &i1[2], 8);
241
242   for (i = 0; i < 8; i++)
243     if (imm >= 16 || imm + i >= 16)
244       bout[i + 8] = 0;
245     else
246       bout[i + 8] = buf[imm + i];
247 }
248
249 static void
250 ssse3_test (void)
251 {
252   int i;
253   int r [4] __attribute__ ((aligned(16)));
254   int ck [4];
255   unsigned int imm;
256   int fail = 0;
257
258   for (i = 0; i < 256; i += 8)
259     for (imm = 0; imm < 100; imm++)
260       {
261         /* Manually compute the result */
262         compute_correct_result_64 (&vals[i + 0], &vals[i + 4], imm, ck);
263
264         /* Run the 64-bit tests */
265         ssse3_test_palignr (&vals[i + 0], &vals[i + 4], imm, &r[0]);
266         ssse3_test_palignr (&vals[i + 2], &vals[i + 6], imm, &r[2]);
267         fail += chk_128 (ck, r);
268
269         /* Recompute the results for 128-bits */
270         compute_correct_result_128 (&vals[i + 0], &vals[i + 4], imm, ck);
271
272         /* Run the 128-bit tests */
273         ssse3_test_palignr128 (&vals[i + 0], &vals[i + 4], imm, r);
274         fail += chk_128 (ck, r);
275       }
276
277   if (fail != 0)
278     abort ();
279 }