393 lines
9.5 KiB
C
393 lines
9.5 KiB
C
/* { 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 <altivec.h>
|
||
#include <stdlib.h>
|
||
|
||
#ifdef DEBUG
|
||
#include <stdio.h>
|
||
|
||
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;
|
||
}
|