1/* { dg-do compile { target { powerpc*-*-* && 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 15static int errors = 0; 16#endif 17 18union args { 19 double scalar[2]; 20 vector double vect; 21}; 22 23union largs { 24 unsigned long scalar[2]; 25 vector bool long vect; 26}; 27 28static void 29do_test (union args *expected, union args *got, const char *name) 30{ 31 if (expected->scalar[0] != got->scalar[0] 32 || expected->scalar[1] != got->scalar[1]) 33 { 34#ifdef DEBUG 35 printf ("%s failed!\n", name); 36 errors++; 37#else 38 abort (); 39#endif 40 } 41} 42 43static void 44do_ltest (union largs *expected, union largs *got, const char *name) 45{ 46 if (expected->scalar[0] != got->scalar[0] 47 || expected->scalar[1] != got->scalar[1]) 48 { 49#ifdef DEBUG 50 printf ("%s failed!\n", name); 51 errors++; 52#else 53 abort (); 54#endif 55 } 56} 57 58 59/* Vec functions taking a single argument. */ 60static vector double 61vabs (vector double arg) 62{ 63 return vec_abs (arg); 64} 65 66static vector double 67vceil (vector double arg) 68{ 69 return vec_ceil (arg); 70} 71 72static vector double 73vfloor (vector double arg) 74{ 75 return vec_floor (arg); 76} 77 78static vector double 79vnearbyint (vector double arg) 80{ 81 return vec_nearbyint (arg); 82} 83 84static vector double 85vrint (vector double arg) 86{ 87 return vec_rint (arg); 88} 89 90static vector double 91vsqrt (vector double arg) 92{ 93 return vec_sqrt (arg); 94} 95 96/* Single argument tests. */ 97static struct 98{ 99 union args result; 100 union args input; 101 vector double (*func) (vector double); 102 const char *name; 103} arg1_tests[] = { 104 /* result input function name */ 105 { { 1.0, 2.0 }, { -1.0, 2.0 }, vabs, "vabs" }, 106 { { 1.0, 2.0 }, { 1.0, -2.0 }, vabs, "vabs" }, 107 { { 2.0, 2.0 }, { 1.1, 1.7 }, vceil, "vceil" }, 108 { { -1.0, -1.0 }, { -1.1, -1.7 }, vceil, "vceil" }, 109 { { -1.0, 2.0 }, { -1.5, 1.5 }, vceil, "vceil" }, 110 { { 1.0, 1.0 }, { 1.1, 1.7 }, vfloor, "vfloor" }, 111 { { -2.0, -2.0 }, { -1.1, -1.7 }, vfloor, "vfloor" }, 112 { { -2.0, 1.0 }, { -1.5, 1.5 }, vfloor, "vfloor" }, 113 { { 1.0, 2.0 }, { 1.1, 1.7 }, vnearbyint, "vnearbyint" }, 114 { { -1.0, -2.0 }, { -1.1, -1.7 }, vnearbyint, "vnearbyint" }, 115 { { -2.0, 2.0 }, { -1.5, 1.5 }, vnearbyint, "vnearbyint" }, 116 { { 1.0, 2.0 }, { 1.1, 1.7 }, vrint, "vrint" }, 117 { { -1.0, -2.0 }, { -1.1, -1.7 }, vrint, "vrint" }, 118 { { -2.0, 2.0 }, { -1.5, 1.5 }, vrint, "vrint" }, 119 { { 2.0, 4.0 }, { 4.0, 16.0 }, vsqrt, "vsqrt" }, 120}; 121 122static void 123test_arg1 (void) 124{ 125 unsigned i; 126 127#ifdef DEBUG 128 printf ("Single argument tests:\n"); 129#endif 130 131 for (i = 0; i < sizeof (arg1_tests) / sizeof (arg1_tests[0]); i++) 132 { 133 union args u; 134 u.vect = arg1_tests[i].func (arg1_tests[i].input.vect); 135 136#ifdef DEBUG 137 printf ("test %-16s: expected { %4g, %4g }, got { %4g, %4g }, input { %4g, %4g }\n", 138 arg1_tests[i].name, 139 arg1_tests[i].result.scalar[0], 140 arg1_tests[i].result.scalar[1], 141 u.scalar[0], 142 u.scalar[1], 143 arg1_tests[i].input.scalar[0], 144 arg1_tests[i].input.scalar[1]); 145#endif 146 147 do_test (&arg1_tests[i].result, &u, arg1_tests[i].name); 148 } 149 150 return; 151} 152 153 154/* Vect functions taking 2 arguments. */ 155static vector double 156vadd (vector double arg1, vector double arg2) 157{ 158 return vec_add (arg1, arg2); 159} 160 161static vector double 162vadd2 (vector double arg1, vector double arg2) 163{ 164 return arg1 + arg2; 165} 166 167static vector double 168vsub (vector double arg1, vector double arg2) 169{ 170 return vec_sub (arg1, arg2); 171} 172 173static vector double 174vsub2 (vector double arg1, vector double arg2) 175{ 176 return arg1 - arg2; 177} 178 179static vector double 180vmul (vector double arg1, vector double arg2) 181{ 182 return vec_mul (arg1, arg2); 183} 184 185static vector double 186vmul2 (vector double arg1, vector double arg2) 187{ 188 return arg1 * arg2; 189} 190 191static vector double 192vdiv (vector double arg1, vector double arg2) 193{ 194 return vec_div (arg1, arg2); 195} 196 197static vector double 198vdiv2 (vector double arg1, vector double arg2) 199{ 200 return arg1 / arg2; 201} 202 203static vector double 204vmax (vector double arg1, vector double arg2) 205{ 206 return vec_max (arg1, arg2); 207} 208 209static vector double 210vmin (vector double arg1, vector double arg2) 211{ 212 return vec_min (arg1, arg2); 213} 214 215/* 2 argument tests. */ 216static struct 217{ 218 union args result; 219 union args input[2]; 220 vector double (*func) (vector double, vector double); 221 const char *name; 222} arg2_tests[] = { 223 /* result */ 224 { { 4.0, 6.0 }, { { 1.0, 2.0 }, { 3.0, 4.0 } }, vadd, "vadd" }, 225 { { 4.0, -6.0 }, { { 1.0, -2.0 }, { 3.0, -4.0 } }, vadd, "vadd" }, 226 { { 4.0, 6.0 }, { { 1.0, 2.0 }, { 3.0, 4.0 } }, vadd2, "vadd2" }, 227 { { 4.0, -6.0 }, { { 1.0, -2.0 }, { 3.0, -4.0 } }, vadd2, "vadd2" }, 228 { { -2.0, -2.0 }, { { 1.0, 2.0 }, { 3.0, 4.0 } }, vsub, "vsub" }, 229 { { -2.0, 2.0 }, { { 1.0, -2.0 }, { 3.0, -4.0 } }, vsub, "vsub" }, 230 { { -2.0, -2.0 }, { { 1.0, 2.0 }, { 3.0, 4.0 } }, vsub2, "vsub2" }, 231 { { -2.0, 2.0 }, { { 1.0, -2.0 }, { 3.0, -4.0 } }, vsub2, "vsub2" }, 232 { { 6.0, 4.0 }, { { 2.0, 8.0 }, { 3.0, 0.5 } }, vmul, "vmul" }, 233 { { 6.0, 4.0 }, { { 2.0, 8.0 }, { 3.0, 0.5 } }, vmul2, "vmul2" }, 234 { { 2.0, 0.5 }, { { 6.0, 4.0 }, { 3.0, 8.0 } }, vdiv, "vdiv" }, 235 { { 2.0, 0.5 }, { { 6.0, 4.0 }, { 3.0, 8.0 } }, vdiv2, "vdiv2" }, 236 { { 3.0, 4.0 }, { { 1.0, 2.0 }, { 3.0, 4.0 } }, vmax, "vmax" }, 237 { { 1.0, 4.0 }, { { 1.0, -2.0 }, { -3.0, 4.0 } }, vmax, "vmax" }, 238 { { 1.0, 2.0 }, { { 1.0, 2.0 }, { 3.0, 4.0 } }, vmin, "vmin" }, 239 { { -3.0, -2.0 }, { { 1.0, -2.0 }, { -3.0, 4.0 } }, vmin, "vmin" }, 240}; 241 242static void 243test_arg2 (void) 244{ 245 unsigned i; 246 247#ifdef DEBUG 248 printf ("\nTwo argument tests:\n"); 249#endif 250 251 for (i = 0; i < sizeof (arg2_tests) / sizeof (arg2_tests[0]); i++) 252 { 253 union args u; 254 u.vect = arg2_tests[i].func (arg2_tests[i].input[0].vect, 255 arg2_tests[i].input[1].vect); 256 257#ifdef DEBUG 258 printf ("test %-16s: expected { %4g, %4g }, got { %4g, %4g }, input { %4g, %4g }, { %4g, %4g }\n", 259 arg2_tests[i].name, 260 arg2_tests[i].result.scalar[0], 261 arg2_tests[i].result.scalar[1], 262 u.scalar[0], 263 u.scalar[1], 264 arg2_tests[i].input[0].scalar[0], 265 arg2_tests[i].input[0].scalar[1], 266 arg2_tests[i].input[1].scalar[0], 267 arg2_tests[i].input[1].scalar[1]); 268#endif 269 270 do_test (&arg2_tests[i].result, &u, arg2_tests[i].name); 271 } 272 273 return; 274} 275 276 277/* Comparisons, returnning a boolean vector. */ 278static vector bool long 279vcmpeq (vector double arg1, vector double arg2) 280{ 281 return vec_cmpeq (arg1, arg2); 282} 283 284static vector bool long 285vcmplt (vector double arg1, vector double arg2) 286{ 287 return vec_cmplt (arg1, arg2); 288} 289 290static vector bool long 291vcmple (vector double arg1, vector double arg2) 292{ 293 return vec_cmple (arg1, arg2); 294} 295 296static vector bool long 297vcmpgt (vector double arg1, vector double arg2) 298{ 299 return vec_cmpgt (arg1, arg2); 300} 301 302static vector bool long 303vcmpge (vector double arg1, vector double arg2) 304{ 305 return vec_cmpge (arg1, arg2); 306} 307 308#define ONE 0xffffffffffffffffUL 309#define ZERO 0x0000000000000000UL 310 311/* comparison tests. */ 312static struct 313{ 314 union largs result; 315 union args input[2]; 316 vector bool long (*func) (vector double, vector double); 317 const char *name; 318} argcmp_tests[] = { 319 { { ONE, ZERO }, { { 1.0, 2.0 }, { 1.0, -2.0 } }, vcmpeq, "vcmpeq" }, 320 { { ZERO, ONE }, { { -1.0, 2.0 }, { 1.0, 2.0 } }, vcmpeq, "vcmpeq" }, 321 322 { { ONE, ONE }, { { 1.0, -2.0 }, { 1.0, -2.0 } }, vcmple, "vcmple" }, 323 { { ONE, ONE }, { { 1.0, -2.0 }, { 2.0, -1.0 } }, vcmple, "vcmple" }, 324 { { ZERO, ZERO }, { { 2.0, -1.0 }, { 1.0, -2.0 } }, vcmple, "vcmple" }, 325 326 { { ZERO, ZERO }, { { 1.0, -2.0 }, { 1.0, -2.0 } }, vcmplt, "vcmplt" }, 327 { { ONE, ONE }, { { 1.0, -2.0 }, { 2.0, -1.0 } }, vcmplt, "vcmplt" }, 328 { { ZERO, ZERO }, { { 2.0, -1.0 }, { 1.0, -2.0 } }, vcmplt, "vcmplt" }, 329 330 { { ZERO, ZERO }, { { 1.0, -2.0 }, { 1.0, -2.0 } }, vcmpgt, "vcmpgt" }, 331 { { ZERO, ZERO }, { { 1.0, -2.0 }, { 2.0, -1.0 } }, vcmpgt, "vcmpgt" }, 332 { { ONE, ONE }, { { 2.0, -1.0 }, { 1.0, -2.0 } }, vcmpgt, "vcmpgt" }, 333 334 { { ONE, ONE }, { { 1.0, -2.0 }, { 1.0, -2.0 } }, vcmpge, "vcmpge" }, 335 { { ZERO, ZERO }, { { 1.0, -2.0 }, { 2.0, -1.0 } }, vcmpge, "vcmpge" }, 336 { { ONE, ONE }, { { 2.0, -1.0 }, { 1.0, -2.0 } }, vcmpge, "vcmpge" }, 337}; 338 339static void 340test_argcmp (void) 341{ 342 unsigned i; 343 344#ifdef DEBUG 345 printf ("\nComparison tests:\n"); 346#endif 347 348 for (i = 0; i < sizeof (argcmp_tests) / sizeof (argcmp_tests[0]); i++) 349 { 350 union largs u; 351 u.vect = argcmp_tests[i].func (argcmp_tests[i].input[0].vect, 352 argcmp_tests[i].input[1].vect); 353 354#ifdef DEBUG 355 printf ("test %-16s: expected { 0x%016lx, 0x%016lx }, got { 0x%016lx, 0x%016lx }, input { %4g, %4g }, { %4g, %4g }\n", 356 argcmp_tests[i].name, 357 argcmp_tests[i].result.scalar[0], 358 argcmp_tests[i].result.scalar[1], 359 u.scalar[0], 360 u.scalar[1], 361 argcmp_tests[i].input[0].scalar[0], 362 argcmp_tests[i].input[0].scalar[1], 363 argcmp_tests[i].input[1].scalar[0], 364 argcmp_tests[i].input[1].scalar[1]); 365#endif 366 367 do_ltest (&argcmp_tests[i].result, &u, argcmp_tests[i].name); 368 } 369 370 return; 371} 372 373 374int 375main (int argc, char *argv[]) 376{ 377 test_arg1 (); 378 test_arg2 (); 379 test_argcmp (); 380 381#ifdef DEBUG 382 if (errors) 383 { 384 printf ("There were %d error(s)\n", errors); 385 return errors; 386 } 387 else 388 printf ("There were no errors\n"); 389#endif 390 391 return 0; 392} 393