1 /* { dg-do run { target lp64 } } */
2 /* { dg-skip-if "" { powerpc*-*-darwin* } } */
3 /* { dg-require-effective-target powerpc_vsx_ok } */
4 /* { dg-options "-mvsx -O2" } */
5
6 /* This will run, and someday we should add the support to test whether we are
7 running on VSX hardware. */
8
9 #include <altivec.h>
10 #include <stdlib.h>
11
12 #ifdef DEBUG
13 #include <stdio.h>
14
15 static int errors = 0;
16 #endif
17
18 union args_d {
19 double scalar[2];
20 vector double vect;
21 };
22
23 union args_f {
24 float scalar[4];
25 vector float vect;
26 };
27
28 union largs {
29 unsigned long scalar[2];
30 vector bool long vect;
31 };
32
33 static void
34 do_test_d (union args_d *expected, union args_d *got, const char *name)
35 {
36 if (expected->scalar[0] != got->scalar[0]
37 || expected->scalar[1] != got->scalar[1])
38 {
39 #ifdef DEBUG
40 printf ("%s failed!\n", name);
41 errors++;
42 #else
43 abort ();
44 #endif
45 }
46 }
47
48 static void
49 do_test_f (union args_f *expected, union args_f *got, const char *name)
50 {
51 if (expected->scalar[0] != got->scalar[0]
52 || expected->scalar[1] != got->scalar[1]
53 || expected->scalar[2] != got->scalar[2]
54 || expected->scalar[3] != got->scalar[3])
55 {
56 #ifdef DEBUG
57 printf ("%s failed!\n", name);
58 errors++;
59 #else
60 abort ();
61 #endif
62 }
63 }
64
65 static void
66 do_ltest (union largs *expected, union largs *got, const char *name)
67 {
68 if (expected->scalar[0] != got->scalar[0]
69 || expected->scalar[1] != got->scalar[1])
70 {
71 #ifdef DEBUG
72 printf ("%s failed!\n", name);
73 errors++;
74 #else
75 abort ();
76 #endif
77 }
78 }
79
80
81 /* Vec functions taking a single argument. */
82 static vector double
83 vabs (vector double arg)
84 {
85 return vec_abs (arg);
86 }
87
88 static vector double
89 vceil_d (vector double arg)
90 {
91 return vec_ceil (arg);
92 }
93
94 static vector float
95 vceil_f (vector float arg)
96 {
97 return vec_ceil (arg);
98 }
99
100 static vector double
101 vfloor_d (vector double arg)
102 {
103 return vec_floor (arg);
104 }
105
106 static vector float
107 vfloor_f (vector float arg)
108 {
109 return vec_floor (arg);
110 }
111
112 static vector double
113 vnearbyint_d (vector double arg)
114 {
115 return vec_nearbyint (arg);
116 }
117
118 static vector float
119 vnearbyint_f (vector float arg)
120 {
121 return vec_nearbyint (arg);
122 }
123
124 static vector float
125 vrint_f (vector float arg)
126 {
127 return vec_rint (arg);
128 }
129
130 static vector double
131 vrint_d (vector double arg)
132 {
133 return vec_rint (arg);
134 }
135
136 static vector float
137 vsqrt_f (vector float arg)
138 {
139 return vec_sqrt (arg);
140 }
141
142 static vector double
143 vsqrt_d (vector double arg)
144 {
145 return vec_sqrt (arg);
146 }
147
148 /* Single argument tests with double args */
149 static struct
150 {
151 union args_d result;
152 union args_d input;
153 vector double (*func) (vector double);
154 const char *name;
155 } arg1_tests_d[] = {
156 /* result input function name */
157 { { 1.0, 2.0 }, { -1.0, 2.0 }, vabs, "vabs" },
158 { { 1.0, 2.0 }, { 1.0, -2.0 }, vabs, "vabs" },
159 { { 2.0, 2.0 }, { 1.1, 1.7 }, vceil_d, "vceil_d" },
160 { { -1.0, -1.0 }, { -1.1, -1.7 }, vceil_d, "vceil_d" },
161 { { -1.0, 2.0 }, { -1.5, 1.5 }, vceil_d, "vceil_d" },
162 { { 1.0, 1.0 }, { 1.1, 1.7 }, vfloor_d, "vfloor_d" },
163 { { -2.0, -2.0 }, { -1.1, -1.7 }, vfloor_d, "vfloor_d" },
164 { { -2.0, 1.0 }, { -1.5, 1.5 }, vfloor_d, "vfloor_d" },
165 { { 1.0, 2.0 }, { 1.1, 1.7 }, vnearbyint_d, "vnearbyint_d" },
166 { { -1.0, -2.0 }, { -1.1, -1.7 }, vnearbyint_d, "vnearbyint_d" },
167 { { -2.0, 2.0 }, { -1.5, 1.5 }, vnearbyint_d, "vnearbyint_d" },
168 { { 1.0, 2.0 }, { 1.1, 1.7 }, vrint_d, "vrint_d" },
169 { { -1.0, -2.0 }, { -1.1, -1.7 }, vrint_d, "vrint_d" },
170 { { -2.0, 2.0 }, { -1.5, 1.5 }, vrint_d, "vrint_d" },
171
172 { { 2.0, 4.0 }, { 4.0, 16.0 }, vsqrt_d, "vsqrt_d" },
173 };
174
175 static void
176 test_arg1_d (void)
177 {
178 unsigned i;
179
180 #ifdef DEBUG
181 printf ("\nSingle argument tests with double args:\n");
182 #endif
183
184 for (i = 0; i < sizeof (arg1_tests_d) / sizeof (arg1_tests_d[0]); i++)
185 {
186 union args_d u;
187 u.vect = arg1_tests_d[i].func (arg1_tests_d[i].input.vect);
188
189 #ifdef DEBUG
190 printf ("test %-16s: expected { %4g, %4g }, got { %4g, %4g }, input { %4g, %4g }\n",
191 arg1_tests_d[i].name,
192 arg1_tests_d[i].result.scalar[0],
193 arg1_tests_d[i].result.scalar[1],
194 u.scalar[0],
195 u.scalar[1],
196 arg1_tests_d[i].input.scalar[0],
197 arg1_tests_d[i].input.scalar[1]);
198 #endif
199
200 do_test_d (&arg1_tests_d[i].result, &u, arg1_tests_d[i].name);
201 }
202
203 return;
204 }
205
206 /* Single argument tests with float args. */
207 static struct
208 {
209 union args_f result;
210 union args_f input;
211 vector float (*func) (vector float);
212 const char *name;
213 } arg1_tests_f[] = {
214 /* result input function name */
215 { { 2.0, 2.0, 3.0, 3.0 }, { 1.05, 1.1, 2.2, 2.3 }, vceil_f, "vceil_f" },
216 { { -1.0, -1.0, -2.0, -2.0 }, { -1.1, -1.7, -2.1, -2.4 }, vceil_f, "vceil_f" },
217 { { 1.0, 1.0, 2.0, 2.0 }, { 1.05, 1.1, 2.2, 2.3 }, vfloor_f, "vfloor_f" },
218 { { -2.0, -2.0, -3.0, -3.0 }, { -1.1, -1.7, -2.1, -2.4 }, vfloor_f, "vfloor_f" },
219 { { 1.0, 2.0, -3.0, 3.0 }, { 1.1, 1.7, -3.1, 3.1 }, vnearbyint_f, "vnearbyint_f" },
220 { { -1.0, -2.0, -3.0, 3.0 }, { -1.1, -1.7, -2.9, 2.9 }, vnearbyint_f, "vnearbyint_f" },
221 { { -2.0, 2.0, -3.0, 3.0 }, { -1.5, 1.5, -2.55, 3.49 }, vnearbyint_f, "vnearbyint_f" },
222 { { 10.0, 18.0, 30.0, 40.0 }, { 10.1, 17.7, 30.0, 40.01 }, vrint_f, "vrint_f" },
223 { { -11.0, -18.0, -30.0, -40.0 }, { -11.1, -17.7, -30.0, -40.01 }, vrint_f, "vrint_f" },
224
225 { { 2.0, 4.0 }, { 4.0, 16.0 }, vsqrt_f, "vsqrt_f" },
226 };
227
228 static void
229 test_arg1_f (void)
230 {
231 unsigned i;
232
233 #ifdef DEBUG
234 printf ("\nSingle argument tests with float args:\n");
235 #endif
236
237 for (i = 0; i < sizeof (arg1_tests_f) / sizeof (arg1_tests_f[0]); i++)
238 {
239 union args_f u;
240 u.vect = arg1_tests_f[i].func (arg1_tests_f[i].input.vect);
241
242 #ifdef DEBUG
243 printf ("test %-16s: expected { %4g, %4g, %4g, %4g }, got { %4g, %4g, %4g, %4g }, input { %4g, %4g, %4g, %4g }\n",
244 arg1_tests_f[i].name,
245 arg1_tests_f[i].result.scalar[0],
246 arg1_tests_f[i].result.scalar[1],
247 arg1_tests_f[i].result.scalar[2],
248 arg1_tests_f[i].result.scalar[3],
249 u.scalar[0],
250 u.scalar[1],
251 u.scalar[2],
252 u.scalar[3],
253 arg1_tests_f[i].input.scalar[0],
254 arg1_tests_f[i].input.scalar[1],
255 arg1_tests_f[i].input.scalar[2],
256 arg1_tests_f[i].input.scalar[3]);
257 #endif
258
259 do_test_f (&arg1_tests_f[i].result, &u, arg1_tests_f[i].name);
260 }
261
262 return;
263 }
264
265
266 /* Vect functions taking 2 arguments. */
267 static vector double
268 vadd (vector double arg1, vector double arg2)
269 {
270 return vec_add (arg1, arg2);
271 }
272
273 static vector double
274 vadd2 (vector double arg1, vector double arg2)
275 {
276 return arg1 + arg2;
277 }
278
279 static vector double
280 vsub (vector double arg1, vector double arg2)
281 {
282 return vec_sub (arg1, arg2);
283 }
284
285 static vector double
286 vsub2 (vector double arg1, vector double arg2)
287 {
288 return arg1 - arg2;
289 }
290
291 static vector double
292 vmul (vector double arg1, vector double arg2)
293 {
294 return vec_mul (arg1, arg2);
295 }
296
297 static vector double
298 vmul2 (vector double arg1, vector double arg2)
299 {
300 return arg1 * arg2;
301 }
302
303 static vector double
304 vdiv (vector double arg1, vector double arg2)
305 {
306 return vec_div (arg1, arg2);
307 }
308
309 static vector double
310 vdiv2 (vector double arg1, vector double arg2)
311 {
312 return arg1 / arg2;
313 }
314
315 static vector double
316 vmax (vector double arg1, vector double arg2)
317 {
318 return vec_max (arg1, arg2);
319 }
320
321 static vector double
322 vmin (vector double arg1, vector double arg2)
323 {
324 return vec_min (arg1, arg2);
325 }
326
327 /* 2 argument tests. */
328 static struct
329 {
330 union args_d result;
331 union args_d input[2];
332 vector double (*func) (vector double, vector double);
333 const char *name;
334 } arg2_tests[] = {
335 /* result */
336 { { 4.0, 6.0 }, { { 1.0, 2.0 }, { 3.0, 4.0 } }, vadd, "vadd" },
337 { { 4.0, -6.0 }, { { 1.0, -2.0 }, { 3.0, -4.0 } }, vadd, "vadd" },
338 { { 4.0, 6.0 }, { { 1.0, 2.0 }, { 3.0, 4.0 } }, vadd2, "vadd2" },
339 { { 4.0, -6.0 }, { { 1.0, -2.0 }, { 3.0, -4.0 } }, vadd2, "vadd2" },
340 { { -2.0, -2.0 }, { { 1.0, 2.0 }, { 3.0, 4.0 } }, vsub, "vsub" },
341 { { -2.0, 2.0 }, { { 1.0, -2.0 }, { 3.0, -4.0 } }, vsub, "vsub" },
342 { { -2.0, -2.0 }, { { 1.0, 2.0 }, { 3.0, 4.0 } }, vsub2, "vsub2" },
343 { { -2.0, 2.0 }, { { 1.0, -2.0 }, { 3.0, -4.0 } }, vsub2, "vsub2" },
344 { { 6.0, 4.0 }, { { 2.0, 8.0 }, { 3.0, 0.5 } }, vmul, "vmul" },
345 { { 6.0, 4.0 }, { { 2.0, 8.0 }, { 3.0, 0.5 } }, vmul2, "vmul2" },
346 { { 2.0, 0.5 }, { { 6.0, 4.0 }, { 3.0, 8.0 } }, vdiv, "vdiv" },
347 { { 2.0, 0.5 }, { { 6.0, 4.0 }, { 3.0, 8.0 } }, vdiv2, "vdiv2" },
348 { { 3.0, 4.0 }, { { 1.0, 2.0 }, { 3.0, 4.0 } }, vmax, "vmax" },
349 { { 1.0, 4.0 }, { { 1.0, -2.0 }, { -3.0, 4.0 } }, vmax, "vmax" },
350 { { 1.0, 2.0 }, { { 1.0, 2.0 }, { 3.0, 4.0 } }, vmin, "vmin" },
351 { { -3.0, -2.0 }, { { 1.0, -2.0 }, { -3.0, 4.0 } }, vmin, "vmin" },
352 };
353
354 static void
355 test_arg2 (void)
356 {
357 unsigned i;
358
359 #ifdef DEBUG
360 printf ("\nTwo argument tests:\n");
361 #endif
362
363 for (i = 0; i < sizeof (arg2_tests) / sizeof (arg2_tests[0]); i++)
364 {
365 union args_d u;
366 u.vect = arg2_tests[i].func (arg2_tests[i].input[0].vect,
367 arg2_tests[i].input[1].vect);
368
369 #ifdef DEBUG
370 printf ("test %-16s: expected { %4g, %4g }, got { %4g, %4g }, input { %4g, %4g }, { %4g, %4g }\n",
371 arg2_tests[i].name,
372 arg2_tests[i].result.scalar[0],
373 arg2_tests[i].result.scalar[1],
374 u.scalar[0],
375 u.scalar[1],
376 arg2_tests[i].input[0].scalar[0],
377 arg2_tests[i].input[0].scalar[1],
378 arg2_tests[i].input[1].scalar[0],
379 arg2_tests[i].input[1].scalar[1]);
380 #endif
381
382 do_test_d (&arg2_tests[i].result, &u, arg2_tests[i].name);
383 }
384
385 return;
386 }
387
388
389 /* Comparisons, returnning a boolean vector. */
390 static vector bool long
391 vcmpeq (vector double arg1, vector double arg2)
392 {
393 return vec_cmpeq (arg1, arg2);
394 }
395
396 static vector bool long
397 vcmplt (vector double arg1, vector double arg2)
398 {
399 return vec_cmplt (arg1, arg2);
400 }
401
402 static vector bool long
403 vcmple (vector double arg1, vector double arg2)
404 {
405 return vec_cmple (arg1, arg2);
406 }
407
408 static vector bool long
409 vcmpgt (vector double arg1, vector double arg2)
410 {
411 return vec_cmpgt (arg1, arg2);
412 }
413
414 static vector bool long
415 vcmpge (vector double arg1, vector double arg2)
416 {
417 return vec_cmpge (arg1, arg2);
418 }
419
420 #define ONE 0xffffffffffffffffUL
421 #define ZERO 0x0000000000000000UL
422
423 /* comparison tests. */
424 static struct
425 {
426 union largs result;
427 union args_d input[2];
428 vector bool long (*func) (vector double, vector double);
429 const char *name;
430 } argcmp_tests[] = {
431 { { ONE, ZERO }, { { 1.0, 2.0 }, { 1.0, -2.0 } }, vcmpeq, "vcmpeq" },
432 { { ZERO, ONE }, { { -1.0, 2.0 }, { 1.0, 2.0 } }, vcmpeq, "vcmpeq" },
433
434 { { ONE, ONE }, { { 1.0, -2.0 }, { 1.0, -2.0 } }, vcmple, "vcmple" },
435 { { ONE, ONE }, { { 1.0, -2.0 }, { 2.0, -1.0 } }, vcmple, "vcmple" },
436 { { ZERO, ZERO }, { { 2.0, -1.0 }, { 1.0, -2.0 } }, vcmple, "vcmple" },
437
438 { { ZERO, ZERO }, { { 1.0, -2.0 }, { 1.0, -2.0 } }, vcmplt, "vcmplt" },
439 { { ONE, ONE }, { { 1.0, -2.0 }, { 2.0, -1.0 } }, vcmplt, "vcmplt" },
440 { { ZERO, ZERO }, { { 2.0, -1.0 }, { 1.0, -2.0 } }, vcmplt, "vcmplt" },
441
442 { { ZERO, ZERO }, { { 1.0, -2.0 }, { 1.0, -2.0 } }, vcmpgt, "vcmpgt" },
443 { { ZERO, ZERO }, { { 1.0, -2.0 }, { 2.0, -1.0 } }, vcmpgt, "vcmpgt" },
444 { { ONE, ONE }, { { 2.0, -1.0 }, { 1.0, -2.0 } }, vcmpgt, "vcmpgt" },
445
446 { { ONE, ONE }, { { 1.0, -2.0 }, { 1.0, -2.0 } }, vcmpge, "vcmpge" },
447 { { ZERO, ZERO }, { { 1.0, -2.0 }, { 2.0, -1.0 } }, vcmpge, "vcmpge" },
448 { { ONE, ONE }, { { 2.0, -1.0 }, { 1.0, -2.0 } }, vcmpge, "vcmpge" },
449 };
450
451 static void
452 test_argcmp (void)
453 {
454 unsigned i;
455
456 #ifdef DEBUG
457 printf ("\nComparison tests:\n");
458 #endif
459
460 for (i = 0; i < sizeof (argcmp_tests) / sizeof (argcmp_tests[0]); i++)
461 {
462 union largs u;
463 u.vect = argcmp_tests[i].func (argcmp_tests[i].input[0].vect,
464 argcmp_tests[i].input[1].vect);
465
466 #ifdef DEBUG
467 printf ("test %-16s: expected { 0x%016lx, 0x%016lx }, got { 0x%016lx, 0x%016lx }, input { %4g, %4g }, { %4g, %4g }\n",
468 argcmp_tests[i].name,
469 argcmp_tests[i].result.scalar[0],
470 argcmp_tests[i].result.scalar[1],
471 u.scalar[0],
472 u.scalar[1],
473 argcmp_tests[i].input[0].scalar[0],
474 argcmp_tests[i].input[0].scalar[1],
475 argcmp_tests[i].input[1].scalar[0],
476 argcmp_tests[i].input[1].scalar[1]);
477 #endif
478
479 do_ltest (&argcmp_tests[i].result, &u, argcmp_tests[i].name);
480 }
481
482 return;
483 }
484
485
486 int
487 main (int argc, char *argv[])
488 {
489 test_arg1_f ();
490 test_arg1_d ();
491 test_arg2 ();
492 test_argcmp ();
493
494 #ifdef DEBUG
495 if (errors)
496 {
497 printf ("There were %d error(s)\n", errors);
498 return errors;
499 }
500 else
501 printf ("There were no errors\n");
502 #endif
503
504 return 0;
505 }