1 #include <altivec.h>
2 
3 /* Test various ways of creating vectors with 2 double words and accessing the
4    elements.  This include files supports:
5 
6 	 testing double
7 	 testing long on 64-bit systems
8 	 testing long long on 32-bit systems.
9 
10    The endian support is:
11 
12 	big endian
13 	little endian.  */
14 
15 #ifdef DEBUG
16 #include <stdio.h>
17 #define DEBUG0(STR)		fputs (STR, stdout)
18 #define DEBUG2(STR,A,B)		printf (STR, A, B)
19 
20 static int errors = 0;
21 
22 #else
23 #include <stdlib.h>
24 #define DEBUG0(STR)
25 #define DEBUG2(STR,A,B)
26 #endif
27 
28 #if defined(DO_DOUBLE)
29 #define TYPE	double
30 #define STYPE	"double"
31 #define ZERO	0.0
32 #define ONE	1.0
33 #define TWO	2.0
34 #define THREE	3.0
35 #define FOUR	4.0
36 #define FIVE	5.0
37 #define SIX	6.0
38 #define FMT	"g"
39 
40 #elif defined(_ARCH_PPC64)
41 #define TYPE	long
42 #define STYPE	"long"
43 #define ZERO	0L
44 #define ONE	1L
45 #define TWO	2L
46 #define THREE	3L
47 #define FOUR	4L
48 #define FIVE	5L
49 #define SIX	6L
50 #define FMT	"ld"
51 
52 #else
53 #define TYPE	long long
54 #define STYPE	"long long"
55 #define ZERO	0LL
56 #define ONE	1LL
57 #define TWO	2LL
58 #define THREE	3LL
59 #define FOUR	4LL
60 #define FIVE	5LL
61 #define SIX	6LL
62 #define FMT	"lld"
63 #endif
64 
65 /* Macros to order the left/right values correctly.  */
66 
67 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
68 #define INIT_ORDER(A, B)	(TYPE) A, (TYPE) B
69 #define ELEMENT_ORDER(A, B)	(TYPE) A, (TYPE) B
70 #define ENDIAN			"-mbig"
71 #else
72 #define INIT_ORDER(A, B)	(TYPE) B, (TYPE) A
73 #define ELEMENT_ORDER(A, B)	(TYPE) B, (TYPE) A
74 #define ENDIAN			"-mlittle"
75 #endif
76 
77 static volatile TYPE		five	= FIVE;
78 static volatile TYPE		six	= SIX;
79 static volatile vector TYPE	s_v12 = { ONE,   TWO };
80 static volatile vector TYPE	g_v34 = { THREE, FOUR };
81 
82 
83 __attribute__((__noinline__))
84 static void
vector_check(vector TYPE v,TYPE expect_hi,TYPE expect_lo)85 vector_check (vector TYPE v, TYPE expect_hi, TYPE expect_lo)
86 {
87   TYPE actual_hi, actual_lo;
88 #ifdef DEBUG
89   const char *pass_fail;
90 #endif
91 
92   __asm__ ("xxlor %x0,%x1,%x1"		: "=&wa" (actual_hi) : "wa" (v));
93   __asm__ ("xxpermdi %x0,%x1,%x1,3"	: "=&wa" (actual_lo) : "wa" (v));
94 
95 #ifdef DEBUG
96   if ((actual_hi == expect_hi) && (actual_lo == expect_lo))
97     pass_fail = ", pass";
98   else
99     {
100       pass_fail = ", fail";
101       errors++;
102     }
103 
104   printf ("Expected %" FMT ", %" FMT ", got %" FMT ", %" FMT "%s\n",
105 	  expect_hi, expect_lo,
106 	  actual_hi, actual_lo,
107 	  pass_fail);
108 #else
109   if ((actual_hi != expect_hi) || (actual_lo != expect_lo))
110     abort ();
111 #endif
112 }
113 
114 __attribute__((__noinline__))
115 static vector TYPE
combine(TYPE op0,TYPE op1)116 combine (TYPE op0, TYPE op1)
117 {
118   return (vector TYPE) { op0, op1 };
119 }
120 
121 __attribute__((__noinline__))
122 static vector TYPE
combine_insert(TYPE op0,TYPE op1)123 combine_insert (TYPE op0, TYPE op1)
124 {
125   vector TYPE ret = (vector TYPE) { ZERO, ZERO };
126   ret = vec_insert (op0, ret, 0);
127   ret = vec_insert (op1, ret, 1);
128   return ret;
129 }
130 
131 __attribute__((__noinline__))
132 static vector TYPE
concat_extract_00(vector TYPE a,vector TYPE b)133 concat_extract_00 (vector TYPE a, vector TYPE b)
134 {
135   return (vector TYPE) { vec_extract (a, 0), vec_extract (b, 0) };
136 }
137 
138 __attribute__((__noinline__))
139 static vector TYPE
concat_extract_01(vector TYPE a,vector TYPE b)140 concat_extract_01 (vector TYPE a, vector TYPE b)
141 {
142   return (vector TYPE) { vec_extract (a, 0), vec_extract (b, 1) };
143 }
144 
145 __attribute__((__noinline__))
146 static vector TYPE
concat_extract_10(vector TYPE a,vector TYPE b)147 concat_extract_10 (vector TYPE a, vector TYPE b)
148 {
149   return (vector TYPE) { vec_extract (a, 1), vec_extract (b, 0) };
150 }
151 
152 __attribute__((__noinline__))
153 static vector TYPE
concat_extract_11(vector TYPE a,vector TYPE b)154 concat_extract_11 (vector TYPE a, vector TYPE b)
155 {
156   return (vector TYPE) { vec_extract (a, 1), vec_extract (b, 1) };
157 }
158 
159 __attribute__((__noinline__))
160 static vector TYPE
concat_extract2_0s(vector TYPE a,TYPE b)161 concat_extract2_0s (vector TYPE a, TYPE b)
162 {
163   return (vector TYPE) { vec_extract (a, 0), b };
164 }
165 
166 __attribute__((__noinline__))
167 static vector TYPE
concat_extract2_1s(vector TYPE a,TYPE b)168 concat_extract2_1s (vector TYPE a, TYPE b)
169 {
170   return (vector TYPE) { vec_extract (a, 1), b };
171 }
172 
173 __attribute__((__noinline__))
174 static vector TYPE
concat_extract2_s0(TYPE a,vector TYPE b)175 concat_extract2_s0 (TYPE a, vector TYPE b)
176 {
177   return (vector TYPE) { a, vec_extract (b, 0) };
178 }
179 
180 __attribute__((__noinline__))
181 static vector TYPE
concat_extract2_s1(TYPE a,vector TYPE b)182 concat_extract2_s1 (TYPE a, vector TYPE b)
183 {
184   return (vector TYPE) { a, vec_extract (b, 1) };
185 }
186 
187 __attribute__((__noinline__))
188 static vector TYPE
concat_extract_nn(vector TYPE a,vector TYPE b,size_t i,size_t j)189 concat_extract_nn (vector TYPE a, vector TYPE b, size_t i, size_t j)
190 {
191   return (vector TYPE) { vec_extract (a, i), vec_extract (b, j) };
192 }
193 
194 __attribute__((__noinline__))
195 static vector TYPE
array_0(vector TYPE v,TYPE a)196 array_0 (vector TYPE v, TYPE a)
197 {
198   v[0] = a;
199   return v;
200 }
201 
202 __attribute__((__noinline__))
203 static vector TYPE
array_1(vector TYPE v,TYPE a)204 array_1 (vector TYPE v, TYPE a)
205 {
206   v[1] = a;
207   return v;
208 }
209 
210 __attribute__((__noinline__))
211 static vector TYPE
array_01(vector TYPE v,TYPE a,TYPE b)212 array_01 (vector TYPE v, TYPE a, TYPE b)
213 {
214   v[0] = a;
215   v[1] = b;
216   return v;
217 }
218 
219 __attribute__((__noinline__))
220 static vector TYPE
array_01b(TYPE a,TYPE b)221 array_01b (TYPE a, TYPE b)
222 {
223   vector TYPE v = (vector TYPE) { 0, 0 };
224   v[0] = a;
225   v[1] = b;
226   return v;
227 }
228 
229 int
main(void)230 main (void)
231 {
232   vector TYPE a = (vector TYPE) { ONE,   TWO  };
233   vector TYPE b = (vector TYPE) { THREE, FOUR };
234   size_t i, j;
235 
236   vector TYPE z = (vector TYPE) { ZERO,  ZERO };
237 
238   DEBUG2 ("Endian: %s, type: %s\n", ENDIAN, STYPE);
239   DEBUG0 ("\nStatic/global initialization\n");
240   vector_check (s_v12, INIT_ORDER (1, 2));
241   vector_check (g_v34, INIT_ORDER (3, 4));
242 
243   DEBUG0 ("\nVector via constant runtime intiialization\n");
244   vector_check (a, INIT_ORDER (1, 2));
245   vector_check (b, INIT_ORDER (3, 4));
246 
247   DEBUG0 ("\nCombine scalars using vector initialization\n");
248   vector_check (combine (1, 2), INIT_ORDER (1, 2));
249   vector_check (combine (3, 4), INIT_ORDER (3, 4));
250 
251   DEBUG0 ("\nSetup with vec_insert\n");
252   a = combine_insert (1, 2);
253   b = combine_insert (3, 4);
254   vector_check (a, ELEMENT_ORDER (1, 2));
255   vector_check (b, ELEMENT_ORDER (3, 4));
256 
257   DEBUG0 ("\nTesting array syntax\n");
258   vector_check (array_0   (a, FIVE),      ELEMENT_ORDER (5, 2));
259   vector_check (array_1   (b, SIX),       ELEMENT_ORDER (3, 6));
260   vector_check (array_01  (z, FIVE, SIX), ELEMENT_ORDER (5, 6));
261   vector_check (array_01b (FIVE, SIX),    ELEMENT_ORDER (5, 6));
262 
263   vector_check (array_0   (a, five),      ELEMENT_ORDER (5, 2));
264   vector_check (array_1   (b, six),       ELEMENT_ORDER (3, 6));
265   vector_check (array_01  (z, five, six), ELEMENT_ORDER (5, 6));
266   vector_check (array_01b (five, six),    ELEMENT_ORDER (5, 6));
267 
268   DEBUG0 ("\nTesting concat and extract\n");
269   vector_check (concat_extract_00 (a, b), INIT_ORDER (1, 3));
270   vector_check (concat_extract_01 (a, b), INIT_ORDER (1, 4));
271   vector_check (concat_extract_10 (a, b), INIT_ORDER (2, 3));
272   vector_check (concat_extract_11 (a, b), INIT_ORDER (2, 4));
273 
274   DEBUG0 ("\nTesting concat and extract #2\n");
275   vector_check (concat_extract2_0s (a, FIVE), INIT_ORDER (1, 5));
276   vector_check (concat_extract2_1s (a, FIVE), INIT_ORDER (2, 5));
277   vector_check (concat_extract2_s0 (SIX, a),  INIT_ORDER (6, 1));
278   vector_check (concat_extract2_s1 (SIX, a),  INIT_ORDER (6, 2));
279 
280   DEBUG0 ("\nTesting variable concat and extract\n");
281   for (i = 0; i < 2; i++)
282     {
283       for (j = 0; j < 2; j++)
284 	{
285 	  static struct {
286 	    TYPE hi;
287 	    TYPE lo;
288 	  } hilo[2][2] =
289 	      { { { ONE, THREE }, { ONE, FOUR } },
290 		{ { TWO, THREE }, { TWO, FOUR } } };
291 
292 	  vector_check (concat_extract_nn (a, b, i, j),
293 			INIT_ORDER (hilo[i][j].hi, hilo[i][j].lo));
294 	}
295     }
296 
297   DEBUG0 ("\nTesting separate function\n");
298   vector_check (combine (vec_extract (a, 0), vec_extract (b, 0)),
299 		INIT_ORDER (1, 3));
300 
301   vector_check (combine (vec_extract (a, 0), vec_extract (b, 1)),
302 		INIT_ORDER (1, 4));
303 
304   vector_check (combine (vec_extract (a, 1), vec_extract (b, 0)),
305 		INIT_ORDER (2, 3));
306 
307   vector_check (combine (vec_extract (a, 1), vec_extract (b, 1)),
308 		INIT_ORDER (2, 4));
309 
310   vector_check (combine_insert (vec_extract (a, 0), vec_extract (b, 0)),
311 		ELEMENT_ORDER (1, 3));
312 
313   vector_check (combine_insert (vec_extract (a, 0), vec_extract (b, 1)),
314 		ELEMENT_ORDER (1, 4));
315 
316   vector_check (combine_insert (vec_extract (a, 1), vec_extract (b, 0)),
317 		ELEMENT_ORDER (2, 3));
318 
319   vector_check (combine_insert (vec_extract (a, 1), vec_extract (b, 1)),
320 		ELEMENT_ORDER (2, 4));
321 
322 
323 #if defined(DO_DOUBLE)
324   DEBUG0 ("\nTesting explicit 2df concat\n");
325   vector_check (__builtin_vsx_concat_2df (FIVE, SIX), INIT_ORDER (5, 6));
326   vector_check (__builtin_vsx_concat_2df (five, six), INIT_ORDER (5, 6));
327 
328 #elif defined(_ARCH_PPC64)
329   DEBUG0 ("\nTesting explicit 2di concat\n");
330   vector_check (__builtin_vsx_concat_2di (FIVE, SIX), INIT_ORDER (5, 6));
331   vector_check (__builtin_vsx_concat_2di (five, six), INIT_ORDER (5, 6));
332 
333 #else
334   DEBUG0 ("\nSkip explicit 2di concat on 32-bit\n");
335 #endif
336 
337 #ifdef DEBUG
338   if (errors)
339     printf ("\n%d error%s were found", errors, (errors == 1) ? "" : "s");
340   else
341     printf ("\nNo errors were found.\n");
342 
343   return errors;
344 
345 #else
346   return 0;
347 #endif
348 }
349