/* { dg-do run { target lp64 } } */ /* { dg-skip-if "" { powerpc*-*-darwin* } } */ /* { dg-require-effective-target vsx_hw } */ /* { dg-options "-mvsx -O2" } */ #include #include #ifdef DEBUG #include static int errors = 0; #endif union args_d { double scalar[2]; vector double vect; }; union args_f { float scalar[4]; vector float vect; }; union largs { unsigned long scalar[2]; vector bool long vect; }; static void do_test_d (union args_d *expected, union args_d *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_test_f (union args_f *expected, union args_f *got, const char *name) { if (expected->scalar[0] != got->scalar[0] || expected->scalar[1] != got->scalar[1] || expected->scalar[2] != got->scalar[2] || expected->scalar[3] != got->scalar[3]) { #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_d (vector double arg) { return vec_ceil (arg); } static vector float vceil_f (vector float arg) { return vec_ceil (arg); } static vector double vfloor_d (vector double arg) { return vec_floor (arg); } static vector float vfloor_f (vector float arg) { return vec_floor (arg); } static vector double vnearbyint_d (vector double arg) { return vec_nearbyint (arg); } static vector float vnearbyint_f (vector float arg) { return vec_nearbyint (arg); } static vector float vrint_f (vector float arg) { return vec_rint (arg); } static vector double vrint_d (vector double arg) { return vec_rint (arg); } static vector float vsqrt_f (vector float arg) { return vec_sqrt (arg); } static vector double vsqrt_d (vector double arg) { return vec_sqrt (arg); } /* Single argument tests with double args */ static struct { union args_d result; union args_d input; vector double (*func) (vector double); const char *name; } arg1_tests_d[] = { /* 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_d, "vceil_d" }, { { -1.0, -1.0 }, { -1.1, -1.7 }, vceil_d, "vceil_d" }, { { -1.0, 2.0 }, { -1.5, 1.5 }, vceil_d, "vceil_d" }, { { 1.0, 1.0 }, { 1.1, 1.7 }, vfloor_d, "vfloor_d" }, { { -2.0, -2.0 }, { -1.1, -1.7 }, vfloor_d, "vfloor_d" }, { { -2.0, 1.0 }, { -1.5, 1.5 }, vfloor_d, "vfloor_d" }, { { 1.0, 2.0 }, { 1.1, 1.7 }, vnearbyint_d, "vnearbyint_d" }, { { -1.0, -2.0 }, { -1.1, -1.7 }, vnearbyint_d, "vnearbyint_d" }, { { -2.0, 2.0 }, { -1.5, 1.5 }, vnearbyint_d, "vnearbyint_d" }, { { 1.0, 2.0 }, { 1.1, 1.7 }, vrint_d, "vrint_d" }, { { -1.0, -2.0 }, { -1.1, -1.7 }, vrint_d, "vrint_d" }, { { -2.0, 2.0 }, { -1.5, 1.5 }, vrint_d, "vrint_d" }, { { 2.0, 4.0 }, { 4.0, 16.0 }, vsqrt_d, "vsqrt_d" }, }; static void test_arg1_d (void) { unsigned i; #ifdef DEBUG printf ("\nSingle argument tests with double args:\n"); #endif for (i = 0; i < sizeof (arg1_tests_d) / sizeof (arg1_tests_d[0]); i++) { union args_d u; u.vect = arg1_tests_d[i].func (arg1_tests_d[i].input.vect); #ifdef DEBUG printf ("test %-16s: expected { %4g, %4g }, got { %4g, %4g }, input { %4g, %4g }\n", arg1_tests_d[i].name, arg1_tests_d[i].result.scalar[0], arg1_tests_d[i].result.scalar[1], u.scalar[0], u.scalar[1], arg1_tests_d[i].input.scalar[0], arg1_tests_d[i].input.scalar[1]); #endif do_test_d (&arg1_tests_d[i].result, &u, arg1_tests_d[i].name); } return; } /* Single argument tests with float args. */ static struct { union args_f result; union args_f input; vector float (*func) (vector float); const char *name; } arg1_tests_f[] = { /* result input function name */ { { 2.0, 2.0, 3.0, 3.0 }, { 1.05, 1.1, 2.2, 2.3 }, vceil_f, "vceil_f" }, { { -1.0, -1.0, -2.0, -2.0 }, { -1.1, -1.7, -2.1, -2.4 }, vceil_f, "vceil_f" }, { { 1.0, 1.0, 2.0, 2.0 }, { 1.05, 1.1, 2.2, 2.3 }, vfloor_f, "vfloor_f" }, { { -2.0, -2.0, -3.0, -3.0 }, { -1.1, -1.7, -2.1, -2.4 }, vfloor_f, "vfloor_f" }, { { 1.0, 2.0, -3.0, 3.0 }, { 1.1, 1.7, -3.1, 3.1 }, vnearbyint_f, "vnearbyint_f" }, { { -1.0, -2.0, -3.0, 3.0 }, { -1.1, -1.7, -2.9, 2.9 }, vnearbyint_f, "vnearbyint_f" }, { { -2.0, 2.0, -3.0, 3.0 }, { -1.5, 1.5, -2.55, 3.49 }, vnearbyint_f, "vnearbyint_f" }, { { 10.0, 18.0, 30.0, 40.0 }, { 10.1, 17.7, 30.0, 40.01 }, vrint_f, "vrint_f" }, { { -11.0, -18.0, -30.0, -40.0 }, { -11.1, -17.7, -30.0, -40.01 }, vrint_f, "vrint_f" }, { { 2.0, 4.0 }, { 4.0, 16.0 }, vsqrt_f, "vsqrt_f" }, }; static void test_arg1_f (void) { unsigned i; #ifdef DEBUG printf ("\nSingle argument tests with float args:\n"); #endif for (i = 0; i < sizeof (arg1_tests_f) / sizeof (arg1_tests_f[0]); i++) { union args_f u; u.vect = arg1_tests_f[i].func (arg1_tests_f[i].input.vect); #ifdef DEBUG printf ("test %-16s: expected { %4g, %4g, %4g, %4g }, got { %4g, %4g, %4g, %4g }, input { %4g, %4g, %4g, %4g }\n", arg1_tests_f[i].name, arg1_tests_f[i].result.scalar[0], arg1_tests_f[i].result.scalar[1], arg1_tests_f[i].result.scalar[2], arg1_tests_f[i].result.scalar[3], u.scalar[0], u.scalar[1], u.scalar[2], u.scalar[3], arg1_tests_f[i].input.scalar[0], arg1_tests_f[i].input.scalar[1], arg1_tests_f[i].input.scalar[2], arg1_tests_f[i].input.scalar[3]); #endif do_test_f (&arg1_tests_f[i].result, &u, arg1_tests_f[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_d result; union args_d 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_d 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_d (&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_d 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_f (); test_arg1_d (); 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; }