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
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
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
30 deoptimize_uint (vector unsigned int a)
31 {
32 __asm__ (" # %x0" : "+v" (a));
33 return a;
34 }
35
36 static vector unsigned char
37 deoptimize_uchar (vector unsigned char a)
38 {
39 __asm__ (" # %x0" : "+v" (a));
40 return a;
41 }
42
43 static vector unsigned short
44 deoptimize_ushort (vector unsigned short a)
45 {
46 __asm__ (" # %x0" : "+v" (a));
47 return a;
48 }
49
50 __attribute ((noinline)) unsigned __int128
51 get_auto_n_uint128 (vector unsigned __int128 a, int n)
52 {
53 return __builtin_vec_extract (a, n);
54 }
55
56 __attribute ((noinline)) unsigned long long int
57 get_auto_n_ulong (vector unsigned long long int a, int n)
58 {
59 return __builtin_vec_extract (a, n);
60 }
61
62 __attribute ((noinline))
63 unsigned int get_auto_n_uint (vector unsigned int a, int n)
64 {
65 return __builtin_vec_extract (a, n);
66 }
67
68 __attribute ((noinline))
69 unsigned char get_auto_n_uchar (vector unsigned char a, int n)
70 {
71 return __builtin_vec_extract (a, n);
72 }
73
74 __attribute ((noinline))
75 unsigned short get_auto_n_ushort (vector unsigned short a, int n)
76 {
77 return __builtin_vec_extract (a, n);
78 }
79
80
81 int check_uint128_element (int i, unsigned __int128 entry)
82 {
83 printf ("checking uint128 entry at index %d\n", i);
84
85 return (entry == ((((unsigned __int128) 0xffeeddccbbaa9988ULL) << 64)
86 | 0x0706050403020100ULL));
87 }
88
89 int check_ulong_element (int i, unsigned long long int entry)
90 {
91 printf ("checking ulong entry 0x%llx at index %d\n", entry, i);
92
93 switch (i % 2)
94 {
95 case 0: return (entry == 0x9999901010ULL);
96 case 1: return (entry == 0x7777733333ULL);
97 default:
98 return 0;
99 }
100 }
101
102 int check_uint_element (int i, unsigned int entry)
103 {
104 printf ("checking uint entry 0x%x at index %d\n", entry, i);
105
106 switch (i % 4)
107 {
108 case 0: return (entry == 0x99999);
109 case 1: return (entry == 0x01010);
110 case 2: return (entry == 0x77777);
111 case 3: return (entry == 0x33333);
112 default:
113 return 0;
114 }
115 }
116
117 int check_uchar_element (int i, unsigned char entry)
118 {
119 printf ("checking uchar entry 0x%x at index %d\n", entry, i);
120 switch (i % 16)
121 {
122 case 0: return (entry == 0x90);
123 case 1: return (entry == 0x80);
124 case 2: return (entry == 0x70);
125 case 3: return (entry == 0x60);
126 case 4: return (entry == 0x50);
127 case 5: return (entry == 0x40);
128 case 6: return (entry == 0x30);
129 case 7: return (entry == 0x20);
130 case 8: return (entry == 0x10);
131 case 9: return (entry == 0xf0);
132 case 10: return (entry == 0xe0);
133 case 11: return (entry == 0xd0);
134 case 12: return (entry == 0xc0);
135 case 13: return (entry == 0xb0);
136 case 14: return (entry == 0xa0);
137 case 15: return (entry == 0xff);
138 default:
139 return 0;
140 }
141 }
142
143 int check_ushort_element (int i, unsigned short entry)
144 {
145 printf ("checking ushort entry 0x%x at index %d\n", entry, i);
146 switch (i % 8)
147 {
148 case 0: return (entry == 0x9988);
149 case 1: return (entry == 0x8877);
150 case 2: return (entry == 0x7766);
151 case 3: return (entry == 0x6655);
152 case 4: return (entry == 0x5544);
153 case 5: return (entry == 0x4433);
154 case 6: return (entry == 0x3322);
155 case 7: return (entry == 0x2211);
156 default:
157 return 0;
158 }
159 }
160
161 void do_auto_uint128 ( vector unsigned __int128 a )
162 {
163 int i;
164 unsigned __int128 c;
165 for (i = 0; i < 32; i += 3)
166 {
167 c = get_auto_n_uint128 (a,i);
168 if (!check_uint128_element (i, c)) abort ();
169 }
170 }
171
172 void do_auto_ulong ( vector unsigned long long int a )
173 {
174 int i;
175 unsigned long long int c;
176 for (i = 0; i < 32; i += 3)
177 {
178 c = get_auto_n_ulong (a,i);
179 if (!check_ulong_element (i, c)) abort ();
180 }
181 }
182
183 void do_auto_uint ( vector unsigned int a )
184 {
185 int i;
186 unsigned int c;
187 for (i = 0; i < 32; i += 3)
188 {
189 c = get_auto_n_uint (a,i);
190 if (!check_uint_element (i, c)) abort ();
191 }
192 }
193
194 void do_auto_ushort ( vector unsigned short a )
195 {
196 int i;
197 unsigned short c;
198 for (i = 0; i < 32; i += 3)
199 {
200 c = get_auto_n_ushort (a,i);
201 if (!check_ushort_element (i, c)) abort ();
202 }
203 }
204
205 void do_auto_uchar ( vector unsigned char a )
206 {
207 int i;
208 unsigned char c;
209 for (i = 0; i < 32; i += 3)
210 {
211 c = get_auto_n_uchar (a,i);
212 if (!check_uchar_element (i, c)) abort ();
213 }
214 }
215
216 int
217 main (void)
218 {
219 size_t i;
220
221 vector unsigned __int128 u = {
222 ((((unsigned __int128) 0xffeeddccbbaa9988ULL) << 64)
223 | 0x0706050403020100ULL) };
224 vector unsigned __int128 du;
225
226 vector unsigned long long int v = { 0x9999901010ULL, 0x7777733333ULL };
227 vector unsigned long long int dv;
228
229 vector unsigned int x = { 0x99999, 0x01010, 0x77777, 0x33333 };
230 vector unsigned int dx;
231
232 vector unsigned char y = { 0x90, 0x80, 0x70, 0x60, 0x50, 0x40, 0x30, 0x20,
233 0x10, 0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0, 0xff };
234 vector unsigned char dy;
235
236 vector unsigned short z = { 0x9988, 0x8877, 0x7766, 0x6655,
237 0x5544, 0x4433, 0x3322, 0x2211 };
238 vector unsigned short dz;
239
240 do_auto_uint128 (u);
241 do_auto_ulong (v);
242 do_auto_uint (x);
243 do_auto_uchar (y);
244 do_auto_ushort (z);
245
246 du = deoptimize_uint128 (u);
247 dv = deoptimize_ulong (v);
248 dx = deoptimize_uint (x);
249 dy = deoptimize_uchar (y);
250 dz = deoptimize_ushort (z);
251
252 do_auto_uint128 (du);
253 do_auto_ulong (dv);
254 do_auto_uint (dx);
255 do_auto_uchar (dy);
256 do_auto_ushort (dz);
257 return 0;
258 }