1 /* { dg-do run { target int128 } } */
2 /* { dg-require-effective-target vsx_hw } */
3 /* { dg-options "-mvsx -O2" } */
4 
5 /* This test should run the same on any target that supports vsx
6    instructions.  Intentionally not specifying cpu in order to test
7    all code generation paths.  */
8 
9 #include <stdlib.h>
10 #include <stddef.h>
11 #include <altivec.h>
12 
13 #include <stdio.h>
14 
15 static vector unsigned __int128
deoptimize_uint128(vector unsigned __int128 a)16 deoptimize_uint128 (vector unsigned __int128  a)
17 {
18   __asm__ (" # %x0" : "+v" (a));
19   return a;
20 }
21 
22 static vector unsigned long long int
deoptimize_ulong(vector unsigned long long int a)23 deoptimize_ulong (vector unsigned long long int a)
24 {
25   __asm__ (" # %x0" : "+v" (a));
26   return a;
27 }
28 
29 static vector unsigned int
deoptimize_uint(vector unsigned int a)30 deoptimize_uint (vector unsigned int a)
31 {
32   __asm__ (" # %x0" : "+v" (a));
33   return a;
34 }
35 
36 static vector unsigned char
deoptimize_uchar(vector unsigned char a)37 deoptimize_uchar (vector unsigned char a)
38 {
39   __asm__ (" # %x0" : "+v" (a));
40   return a;
41 }
42 
43 static vector unsigned short
deoptimize_ushort(vector unsigned short a)44 deoptimize_ushort (vector unsigned short a)
45 {
46   __asm__ (" # %x0" : "+v" (a));
47   return a;
48 }
49 
50 __attribute ((noinline))
51 vector unsigned __int128
set_auto_n_uint128(vector unsigned __int128 a,int n,unsigned __int128 x)52 set_auto_n_uint128 (vector unsigned __int128 a, int n, unsigned __int128 x)
53 {
54   return vec_insert (x, a, n);
55 }
56 
57 __attribute ((noinline))
58 vector unsigned long long int
set_auto_n_ulong(vector unsigned long long int a,int n,unsigned long long int x)59 set_auto_n_ulong (vector unsigned long long int a, int n,
60 		  unsigned long long int x)
61 {
62   return vec_insert (x, a, n);
63 }
64 
65 __attribute ((noinline))
66 vector unsigned int
set_auto_n_uint(vector unsigned int a,int n,unsigned int x)67 set_auto_n_uint (vector unsigned int a, int n, unsigned int x)
68 {
69   return vec_insert (x, a, n);
70 }
71 
72 __attribute ((noinline))
73 vector unsigned char
set_auto_n_uchar(vector unsigned char a,int n,unsigned char x)74 set_auto_n_uchar (vector unsigned char a, int n, unsigned char x)
75 {
76   return vec_insert (x, a, n);
77 }
78 
79 __attribute ((noinline))
80 vector unsigned short
set_auto_n_ushort(vector unsigned short a,int n,unsigned short x)81 set_auto_n_ushort (vector unsigned short a, int n, unsigned short x)
82 {
83   return vec_insert (x, a, n);
84 }
85 
86 __attribute ((noinline))
87 unsigned __int128
get_auto_n_uint128(vector unsigned __int128 a,int n)88 get_auto_n_uint128 (vector unsigned __int128 a, int n)
89 {
90   return vec_extract (a, n);
91 }
92 
93 __attribute ((noinline))
94 unsigned long long int
get_auto_n_ulong(vector unsigned long long int a,int n)95 get_auto_n_ulong (vector unsigned long long int a, int n)
96 {
97   return vec_extract (a, n);
98 }
99 
100 __attribute ((noinline))
101 unsigned int
get_auto_n_uint(vector unsigned int a,int n)102 get_auto_n_uint (vector unsigned int a, int n)
103 {
104   return vec_extract (a, n);
105 }
106 
107 __attribute ((noinline))
108 unsigned char
get_auto_n_uchar(vector unsigned char a,int n)109 get_auto_n_uchar (vector unsigned char a, int n)
110 {
111   return vec_extract (a, n);
112 }
113 
114 __attribute ((noinline))
115 unsigned short
get_auto_n_ushort(vector unsigned short a,int n)116 get_auto_n_ushort (vector unsigned short a, int n)
117 {
118   return vec_extract (a, n);
119 }
120 
check_uint128_element(int i,unsigned __int128 entry)121 int check_uint128_element (int i, unsigned __int128 entry)
122 {
123   printf ("checking uint128 entry at index %d\n", i);
124 
125   return (entry == ((((unsigned __int128) 0xffeeddccbbaa9988ULL) << 64)
126 		    | 0x0706050403020100ULL));
127 }
128 
get_uint128_element(int i)129 unsigned __int128 get_uint128_element (int i)
130 {
131   return ((((unsigned __int128) 0xffeeddccbbaa9988ULL) << 64)
132 	  | 0x0706050403020100ULL);
133 }
134 
check_ulong_element(int i,unsigned long long int entry)135 int check_ulong_element (int i, unsigned long long int entry)
136 {
137   printf ("checking ulong entry 0x%llx at index %d\n", entry, i);
138 
139   switch (i % 2)
140     {
141       case 0: return (entry == 0x9999901010ULL);
142       case 1: return (entry == 0x7777733333ULL);
143       default:
144 	return 0;
145     }
146 }
147 
get_ulong_element(int i)148 unsigned long long int get_ulong_element (int i)
149 {
150   switch (i % 2)
151     {
152     case 0: return 0x9999901010ULL;
153     case 1: return 0x7777733333ULL;
154     }
155 }
156 
check_uint_element(int i,unsigned int entry)157 int check_uint_element (int i, unsigned int entry)
158 {
159   printf ("checking uint entry 0x%x at index %d\n", entry, i);
160 
161   switch (i % 4)
162     {
163     case 0: return (entry == 0x99999);
164     case 1: return (entry == 0x01010);
165     case 2: return (entry == 0x77777);
166     case 3: return (entry == 0x33333);
167     default:
168       return 0;
169     }
170 }
171 
get_uint_element(int i)172 unsigned int get_uint_element (int i)
173 {
174   switch (i % 4)
175     {
176     case 0: return 0x99999;
177     case 1: return 0x01010;
178     case 2: return 0x77777;
179     case 3: return 0x33333;
180     }
181 }
182 
check_uchar_element(int i,unsigned char entry)183 int check_uchar_element (int i, unsigned char entry)
184 {
185   printf ("checking uchar entry 0x%x at index %d\n", entry, i);
186   switch (i % 16)
187     {
188     case 0: return (entry == 0x90);
189     case 1: return (entry == 0x80);
190     case 2: return (entry == 0x70);
191     case 3: return (entry == 0x60);
192     case 4: return (entry == 0x50);
193     case 5: return (entry == 0x40);
194     case 6: return (entry == 0x30);
195     case 7: return (entry == 0x20);
196     case 8: return (entry == 0x10);
197     case 9: return (entry == 0xf0);
198     case 10: return (entry == 0xe0);
199     case 11: return (entry == 0xd0);
200     case 12: return (entry == 0xc0);
201     case 13: return (entry == 0xb0);
202     case 14: return (entry == 0xa0);
203     case 15: return (entry == 0xff);
204     default:
205       return 0;
206     }
207 }
208 
get_uchar_element(int i)209 unsigned char get_uchar_element (int i)
210 {
211   switch (i % 16)
212     {
213     case 0: return 0x90;
214     case 1: return 0x80;
215     case 2: return 0x70;
216     case 3: return 0x60;
217     case 4: return 0x50;
218     case 5: return 0x40;
219     case 6: return 0x30;
220     case 7: return 0x20;
221     case 8: return 0x10;
222     case 9: return 0xf0;
223     case 10: return 0xe0;
224     case 11: return 0xd0;
225     case 12: return 0xc0;
226     case 13: return 0xb0;
227     case 14: return 0xa0;
228     case 15: return 0xff;
229     }
230 }
231 
check_ushort_element(int i,unsigned short entry)232 int check_ushort_element (int i, unsigned short entry)
233 {
234   printf ("checking ushort entry 0x%x at index %d\n", entry, i);
235   switch (i % 8)
236     {
237     case 0: return (entry == 0x9988);
238     case 1: return (entry == 0x8877);
239     case 2: return (entry == 0x7766);
240     case 3: return (entry == 0x6655);
241     case 4: return (entry == 0x5544);
242     case 5: return (entry == 0x4433);
243     case 6: return (entry == 0x3322);
244     case 7: return (entry == 0x2211);
245     default:
246       return 0;
247     }
248 }
249 
get_ushort_element(int i)250 unsigned short get_ushort_element (int i)
251 {
252   switch (i % 8)
253     {
254     case 0: return 0x9988;
255     case 1: return 0x8877;
256     case 2: return 0x7766;
257     case 3: return 0x6655;
258     case 4: return 0x5544;
259     case 5: return 0x4433;
260     case 6: return 0x3322;
261     case 7: return 0x2211;
262     }
263 }
264 
265 vector unsigned __int128
init_auto_uint128(vector unsigned __int128 a)266 init_auto_uint128 (vector unsigned __int128 a)
267 {
268   int i;
269   for (i = 0; i < 32; i += 3)
270     a = set_auto_n_uint128 (a, i, get_uint128_element (i));
271   return a;
272 }
273 
do_auto_uint128(vector unsigned __int128 a)274 void do_auto_uint128 (vector unsigned __int128 a)
275 {
276   int i;
277   unsigned __int128 c;
278   for (i = 0; i < 32; i += 3)
279     {
280       c = get_auto_n_uint128 (a, i);
281       if (!check_uint128_element (i, c)) abort ();
282     }
283 }
284 
285 vector unsigned long long int
init_auto_ulong(vector unsigned long long int a)286 init_auto_ulong (vector unsigned long long int a)
287 {
288   int i;
289   for (i = 0; i < 32; i += 3)
290     a = set_auto_n_ulong (a, i, get_ulong_element (i));
291   return a;
292 }
293 
do_auto_ulong(vector unsigned long long int a)294 void do_auto_ulong (vector unsigned long long int a)
295 {
296   int i;
297   unsigned long long int c;
298   for (i = 0; i < 32; i += 3)
299     {
300       c = get_auto_n_ulong (a, i);
301       if (!check_ulong_element (i, c)) abort ();
302     }
303  }
304 
init_auto_uint(vector unsigned int a)305 vector unsigned int init_auto_uint (vector unsigned int a)
306 {
307   int i;
308   for (i = 0; i < 32; i += 3)
309     a = set_auto_n_uint (a, i, get_uint_element (i));
310   return a;
311 }
312 
do_auto_uint(vector unsigned int a)313 void do_auto_uint (vector unsigned int a)
314 {
315   int i;
316   unsigned int c;
317   for (i = 0; i < 32; i += 3)
318     {
319       c = get_auto_n_uint (a, i);
320       if (!check_uint_element (i, c)) abort ();
321     }
322  }
323 
init_auto_ushort(vector unsigned short a)324 vector unsigned short init_auto_ushort ( vector unsigned short a )
325 {
326   int i;
327   for (i = 0; i < 32; i += 3)
328     a = set_auto_n_ushort (a, i, get_ushort_element (i));
329   return a;
330 }
331 
do_auto_ushort(vector unsigned short a)332 void do_auto_ushort (vector unsigned short a)
333 {
334   int i;
335   unsigned short c;
336   for (i = 0; i < 32; i += 3)
337     {
338       c = get_auto_n_ushort (a, i);
339       if (!check_ushort_element (i, c)) abort ();
340     }
341 }
342 
init_auto_uchar(vector unsigned char a)343 vector unsigned char init_auto_uchar (vector unsigned char a)
344 {
345   int i;
346   for (i = 0; i < 32; i += 3)
347     a = set_auto_n_uchar (a, i, get_uchar_element (i));
348   return a;
349 }
350 
do_auto_uchar(vector unsigned char a)351 void do_auto_uchar (vector unsigned char a)
352 {
353   int i;
354   unsigned char c;
355   for (i = 0; i < 32; i += 3)
356     {
357       c = get_auto_n_uchar (a, i);
358       if (!check_uchar_element (i, c)) abort ();
359     }
360 }
361 
362 int
main(void)363 main (void)
364 {
365   size_t i;
366 
367   vector unsigned __int128 u = { 0 };
368   vector unsigned __int128 du;
369 
370   vector unsigned long long int v = { 0, 0 };
371   vector unsigned long long int dv;
372 
373   vector unsigned int x = { 0, 0, 0, 0 };
374   vector unsigned int dx;
375 
376   vector unsigned char y = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
377   vector unsigned char dy;
378 
379   vector unsigned short z = { 0, 0, 0, 0, 0, 0, 0, 0 };
380   vector unsigned short dz;
381 
382   du = init_auto_uint128 (u);
383   dv = init_auto_ulong (v);
384   dx = init_auto_uint (x);
385   dy = init_auto_uchar (y);
386   dz = init_auto_ushort (z);
387 
388   du = deoptimize_uint128 (du);
389   dv = deoptimize_ulong (dv);
390   dx = deoptimize_uint (dx);
391   dy = deoptimize_uchar (dy);
392   dz = deoptimize_ushort (dz);
393 
394   do_auto_uint128 (du);
395   do_auto_ulong (dv);
396   do_auto_uint (dx);
397   do_auto_uchar (dy);
398   do_auto_ushort (dz);
399   return 0;
400 }
401