OSDN Git Service

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