(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.target/
powerpc/
vsx-vector-5.c
       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  }