1 /* { dg-do run { target { powerpc64*-*-* && { p8vector_hw } } } } */
2 /* { dg-require-effective-target powerpc_p8vector_ok } */
3 /* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
4 /* { dg-options "-mcpu=power8 -mpower8-vector -O3" } */
5 
6 /* Test that the vec_cmpne builtin works as expected for long long
7    and double vectors.  */
8 
9 #include "altivec.h"
10 
11 #define N 4096
12 
13 void abort ();
14 
15 #define define_test_functions(VBTYPE, RTYPE, STYPE, NAME) \
16 \
17 RTYPE result_ne_##NAME[N] __attribute__((aligned(16))); \
18 RTYPE result_eq_##NAME[N] __attribute__((aligned(16))); \
19 STYPE operand1_##NAME[N] __attribute__((aligned(16))); \
20 STYPE operand2_##NAME[N] __attribute__((aligned(16))); \
21 RTYPE expected_##NAME[N] __attribute__((aligned(16))); \
22 \
23 __attribute__((noinline)) void vector_tests_##NAME () \
24 { \
25   vector STYPE v1_##NAME, v2_##NAME; \
26   vector bool VBTYPE tmp_##NAME; \
27   int i; \
28   for (i = 0; i < N; i+=16/sizeof (STYPE)) \
29     { \
30       /* result_ne = operand1!=operand2.  */ \
31       v1_##NAME = (vector STYPE) { operand1_##NAME[i], \
32 					 operand1_##NAME[i+1] }; \
33       v2_##NAME = (vector STYPE) { operand2_##NAME[i], \
34 					 operand2_##NAME[i+1] }; \
35 \
36       tmp_##NAME = vec_cmpeq (v1_##NAME, v2_##NAME); \
37       result_eq_##NAME[i] = tmp_##NAME[0]; \
38       result_eq_##NAME[i+1] = tmp_##NAME[1]; \
39 \
40       tmp_##NAME = vec_cmpne (v1_##NAME, v2_##NAME); \
41       result_ne_##NAME[i] = tmp_##NAME[0]; \
42       result_ne_##NAME[i+1] = tmp_##NAME[1]; \
43     } \
44 } \
45 \
46 __attribute__((noinline)) void init_##NAME () \
47 { \
48   int i; \
49   for (i = 0; i < N; ++i) \
50     { \
51       result_ne_##NAME[i] = 7; \
52       result_eq_##NAME[i] = 15; \
53       if (i%3 == 0) \
54 	{ \
55 	  /* op1 < op2.  */ \
56 	  operand1_##NAME[i] = 1; \
57 	  operand2_##NAME[i] = 2; \
58 	} \
59       else if (i%3 == 1) \
60 	{ \
61 	  /* op1 > op2.  */ \
62 	  operand1_##NAME[i] = 2; \
63 	  operand2_##NAME[i] = 1; \
64 	} \
65       else if (i%3 == 2) \
66 	{ \
67 	  /* op1 == op2.  */ \
68 	  operand1_##NAME[i] = 3; \
69 	  operand2_##NAME[i] = 3; \
70 	} \
71       /* For vector comparisons: "For each element of the result_ne, the \
72 	  value of each bit is 1 if the corresponding elements of ARG1 and \
73 	  ARG2 are equal." {or whatever the comparison is} "Otherwise, the \
74 	  value of each bit is 0."  */ \
75     expected_##NAME[i] = -1 * (RTYPE)(operand1_##NAME[i] != operand2_##NAME[i]); \
76   } \
77 } \
78 \
79 __attribute__((noinline)) void verify_results_##NAME () \
80 { \
81   int i; \
82   for (i = 0; i < N; ++i) \
83     { \
84       if ( ((result_ne_##NAME[i] != expected_##NAME[i]) || \
85 	    (result_ne_##NAME[i] == result_eq_##NAME[i]))) \
86 	abort (); \
87     } \
88 }
89 
90 
91 #define execute_test_functions(VBTYPE, RTYPE, STYPE, NAME) \
92 { \
93   init_##NAME (); \
94   vector_tests_##NAME (); \
95   verify_results_##NAME (); \
96 }
97 
98 
99 define_test_functions (long long, signed long long, signed long long, si);
100 define_test_functions (long long, signed long long, double, dd);
101 
main()102 int main ()
103 {
104   execute_test_functions (long long, signed long long, signed long long, si);
105   execute_test_functions (long long, signed long long, double, dd);
106 
107   return 0;
108 }
109 
110 
111