/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */ /* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ /* { dg-require-effective-target powerpc_vsx_ok } */ /* { dg-options "-mvsx -O2" } */ /* This will run, and someday we should add the support to test whether we are running on VSX hardware. */ #include #include #ifdef DEBUG #include static int errors = 0; #endif union args { double scalar[2]; vector double vect; }; union largs { unsigned long scalar[2]; vector bool long vect; }; static void do_test (union args *expected, union args *got, const char *name) { if (expected->scalar[0] != got->scalar[0] || expected->scalar[1] != got->scalar[1]) { #ifdef DEBUG printf ("%s failed!\n", name); errors++; #else abort (); #endif } } static void do_ltest (union largs *expected, union largs *got, const char *name) { if (expected->scalar[0] != got->scalar[0] || expected->scalar[1] != got->scalar[1]) { #ifdef DEBUG printf ("%s failed!\n", name); errors++; #else abort (); #endif } } /* Vec functions taking a single argument. */ static vector double vabs (vector double arg) { return vec_abs (arg); } static vector double vceil (vector double arg) { return vec_ceil (arg); } static vector double vfloor (vector double arg) { return vec_floor (arg); } static vector double vnearbyint (vector double arg) { return vec_nearbyint (arg); } static vector double vrint (vector double arg) { return vec_rint (arg); } static vector double vsqrt (vector double arg) { return vec_sqrt (arg); } /* Single argument tests. */ static struct { union args result; union args input; vector double (*func) (vector double); const char *name; } arg1_tests[] = { /* result input function name */ { { 1.0, 2.0 }, { -1.0, 2.0 }, vabs, "vabs" }, { { 1.0, 2.0 }, { 1.0, -2.0 }, vabs, "vabs" }, { { 2.0, 2.0 }, { 1.1, 1.7 }, vceil, "vceil" }, { { -1.0, -1.0 }, { -1.1, -1.7 }, vceil, "vceil" }, { { -1.0, 2.0 }, { -1.5, 1.5 }, vceil, "vceil" }, { { 1.0, 1.0 }, { 1.1, 1.7 }, vfloor, "vfloor" }, { { -2.0, -2.0 }, { -1.1, -1.7 }, vfloor, "vfloor" }, { { -2.0, 1.0 }, { -1.5, 1.5 }, vfloor, "vfloor" }, { { 1.0, 2.0 }, { 1.1, 1.7 }, vnearbyint, "vnearbyint" }, { { -1.0, -2.0 }, { -1.1, -1.7 }, vnearbyint, "vnearbyint" }, { { -2.0, 2.0 }, { -1.5, 1.5 }, vnearbyint, "vnearbyint" }, { { 1.0, 2.0 }, { 1.1, 1.7 }, vrint, "vrint" }, { { -1.0, -2.0 }, { -1.1, -1.7 }, vrint, "vrint" }, { { -2.0, 2.0 }, { -1.5, 1.5 }, vrint, "vrint" }, { { 2.0, 4.0 }, { 4.0, 16.0 }, vsqrt, "vsqrt" }, }; static void test_arg1 (void) { unsigned i; #ifdef DEBUG printf ("Single argument tests:\n"); #endif for (i = 0; i < sizeof (arg1_tests) / sizeof (arg1_tests[0]); i++) { union args u; u.vect = arg1_tests[i].func (arg1_tests[i].input.vect); #ifdef DEBUG printf ("test %-16s: expected { %4g, %4g }, got { %4g, %4g }, input { %4g, %4g }\n", arg1_tests[i].name, arg1_tests[i].result.scalar[0], arg1_tests[i].result.scalar[1], u.scalar[0], u.scalar[1], arg1_tests[i].input.scalar[0], arg1_tests[i].input.scalar[1]); #endif do_test (&arg1_tests[i].result, &u, arg1_tests[i].name); } return; } /* Vect functions taking 2 arguments. */ static vector double vadd (vector double arg1, vector double arg2) { return vec_add (arg1, arg2); } static vector double vadd2 (vector double arg1, vector double arg2) { return arg1 + arg2; } static vector double vsub (vector double arg1, vector double arg2) { return vec_sub (arg1, arg2); } static vector double vsub2 (vector double arg1, vector double arg2) { return arg1 - arg2; } static vector double vmul (vector double arg1, vector double arg2) { return vec_mul (arg1, arg2); } static vector double vmul2 (vector double arg1, vector double arg2) { return arg1 * arg2; } static vector double vdiv (vector double arg1, vector double arg2) { return vec_div (arg1, arg2); } static vector double vdiv2 (vector double arg1, vector double arg2) { return arg1 / arg2; } static vector double vmax (vector double arg1, vector double arg2) { return vec_max (arg1, arg2); } static vector double vmin (vector double arg1, vector double arg2) { return vec_min (arg1, arg2); } /* 2 argument tests. */ static struct { union args result; union args input[2]; vector double (*func) (vector double, vector double); const char *name; } arg2_tests[] = { /* result */ { { 4.0, 6.0 }, { { 1.0, 2.0 }, { 3.0, 4.0 } }, vadd, "vadd" }, { { 4.0, -6.0 }, { { 1.0, -2.0 }, { 3.0, -4.0 } }, vadd, "vadd" }, { { 4.0, 6.0 }, { { 1.0, 2.0 }, { 3.0, 4.0 } }, vadd2, "vadd2" }, { { 4.0, -6.0 }, { { 1.0, -2.0 }, { 3.0, -4.0 } }, vadd2, "vadd2" }, { { -2.0, -2.0 }, { { 1.0, 2.0 }, { 3.0, 4.0 } }, vsub, "vsub" }, { { -2.0, 2.0 }, { { 1.0, -2.0 }, { 3.0, -4.0 } }, vsub, "vsub" }, { { -2.0, -2.0 }, { { 1.0, 2.0 }, { 3.0, 4.0 } }, vsub2, "vsub2" }, { { -2.0, 2.0 }, { { 1.0, -2.0 }, { 3.0, -4.0 } }, vsub2, "vsub2" }, { { 6.0, 4.0 }, { { 2.0, 8.0 }, { 3.0, 0.5 } }, vmul, "vmul" }, { { 6.0, 4.0 }, { { 2.0, 8.0 }, { 3.0, 0.5 } }, vmul2, "vmul2" }, { { 2.0, 0.5 }, { { 6.0, 4.0 }, { 3.0, 8.0 } }, vdiv, "vdiv" }, { { 2.0, 0.5 }, { { 6.0, 4.0 }, { 3.0, 8.0 } }, vdiv2, "vdiv2" }, { { 3.0, 4.0 }, { { 1.0, 2.0 }, { 3.0, 4.0 } }, vmax, "vmax" }, { { 1.0, 4.0 }, { { 1.0, -2.0 }, { -3.0, 4.0 } }, vmax, "vmax" }, { { 1.0, 2.0 }, { { 1.0, 2.0 }, { 3.0, 4.0 } }, vmin, "vmin" }, { { -3.0, -2.0 }, { { 1.0, -2.0 }, { -3.0, 4.0 } }, vmin, "vmin" }, }; static void test_arg2 (void) { unsigned i; #ifdef DEBUG printf ("\nTwo argument tests:\n"); #endif for (i = 0; i < sizeof (arg2_tests) / sizeof (arg2_tests[0]); i++) { union args u; u.vect = arg2_tests[i].func (arg2_tests[i].input[0].vect, arg2_tests[i].input[1].vect); #ifdef DEBUG printf ("test %-16s: expected { %4g, %4g }, got { %4g, %4g }, input { %4g, %4g }, { %4g, %4g }\n", arg2_tests[i].name, arg2_tests[i].result.scalar[0], arg2_tests[i].result.scalar[1], u.scalar[0], u.scalar[1], arg2_tests[i].input[0].scalar[0], arg2_tests[i].input[0].scalar[1], arg2_tests[i].input[1].scalar[0], arg2_tests[i].input[1].scalar[1]); #endif do_test (&arg2_tests[i].result, &u, arg2_tests[i].name); } return; } /* Comparisons, returnning a boolean vector. */ static vector bool long vcmpeq (vector double arg1, vector double arg2) { return vec_cmpeq (arg1, arg2); } static vector bool long vcmplt (vector double arg1, vector double arg2) { return vec_cmplt (arg1, arg2); } static vector bool long vcmple (vector double arg1, vector double arg2) { return vec_cmple (arg1, arg2); } static vector bool long vcmpgt (vector double arg1, vector double arg2) { return vec_cmpgt (arg1, arg2); } static vector bool long vcmpge (vector double arg1, vector double arg2) { return vec_cmpge (arg1, arg2); } #define ONE 0xffffffffffffffffUL #define ZERO 0x0000000000000000UL /* comparison tests. */ static struct { union largs result; union args input[2]; vector bool long (*func) (vector double, vector double); const char *name; } argcmp_tests[] = { { { ONE, ZERO }, { { 1.0, 2.0 }, { 1.0, -2.0 } }, vcmpeq, "vcmpeq" }, { { ZERO, ONE }, { { -1.0, 2.0 }, { 1.0, 2.0 } }, vcmpeq, "vcmpeq" }, { { ONE, ONE }, { { 1.0, -2.0 }, { 1.0, -2.0 } }, vcmple, "vcmple" }, { { ONE, ONE }, { { 1.0, -2.0 }, { 2.0, -1.0 } }, vcmple, "vcmple" }, { { ZERO, ZERO }, { { 2.0, -1.0 }, { 1.0, -2.0 } }, vcmple, "vcmple" }, { { ZERO, ZERO }, { { 1.0, -2.0 }, { 1.0, -2.0 } }, vcmplt, "vcmplt" }, { { ONE, ONE }, { { 1.0, -2.0 }, { 2.0, -1.0 } }, vcmplt, "vcmplt" }, { { ZERO, ZERO }, { { 2.0, -1.0 }, { 1.0, -2.0 } }, vcmplt, "vcmplt" }, { { ZERO, ZERO }, { { 1.0, -2.0 }, { 1.0, -2.0 } }, vcmpgt, "vcmpgt" }, { { ZERO, ZERO }, { { 1.0, -2.0 }, { 2.0, -1.0 } }, vcmpgt, "vcmpgt" }, { { ONE, ONE }, { { 2.0, -1.0 }, { 1.0, -2.0 } }, vcmpgt, "vcmpgt" }, { { ONE, ONE }, { { 1.0, -2.0 }, { 1.0, -2.0 } }, vcmpge, "vcmpge" }, { { ZERO, ZERO }, { { 1.0, -2.0 }, { 2.0, -1.0 } }, vcmpge, "vcmpge" }, { { ONE, ONE }, { { 2.0, -1.0 }, { 1.0, -2.0 } }, vcmpge, "vcmpge" }, }; static void test_argcmp (void) { unsigned i; #ifdef DEBUG printf ("\nComparison tests:\n"); #endif for (i = 0; i < sizeof (argcmp_tests) / sizeof (argcmp_tests[0]); i++) { union largs u; u.vect = argcmp_tests[i].func (argcmp_tests[i].input[0].vect, argcmp_tests[i].input[1].vect); #ifdef DEBUG printf ("test %-16s: expected { 0x%016lx, 0x%016lx }, got { 0x%016lx, 0x%016lx }, input { %4g, %4g }, { %4g, %4g }\n", argcmp_tests[i].name, argcmp_tests[i].result.scalar[0], argcmp_tests[i].result.scalar[1], u.scalar[0], u.scalar[1], argcmp_tests[i].input[0].scalar[0], argcmp_tests[i].input[0].scalar[1], argcmp_tests[i].input[1].scalar[0], argcmp_tests[i].input[1].scalar[1]); #endif do_ltest (&argcmp_tests[i].result, &u, argcmp_tests[i].name); } return; } int main (int argc, char *argv[]) { test_arg1 (); test_arg2 (); test_argcmp (); #ifdef DEBUG if (errors) { printf ("There were %d error(s)\n", errors); return errors; } else printf ("There were no errors\n"); #endif return 0; }