OSDN Git Service

* gcc.target/i386/builtin-apply-mmx.c: Do not XFAIL on Darwin.
[pf3gnuchains/gcc-fork.git] / gcc / testsuite / gcc.target / i386 / mmx-4.c
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
11 typedef 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
19 void mmx_tests (void) __attribute__((noinline));
20 void dump64_16 (char *, char *, vecInWord);
21 void dump64_32 (char *, char *, vecInWord);
22 void dump64_64 (char *, char *, vecInWord);
23 int check (const char *, const char *[]);
24
25 char buf[8000];
26 char comparison[8000];
27 static int errors = 0;
28
29 vecInWord a64, b64, c64, d64, e64;
30 __m64 m64_16, s64, m64_32, m64_64;
31
32 const 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
53 static void
54 mmx_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
93 void __attribute__((noinline))
94 mmx_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
145 void
146 dump64_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
162 void
163 dump64_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
179 void
180 dump64_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
194 int
195 check (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 }