2017-08-28 Richard Biener <rguenther@suse.de>
[official-gcc.git] / gcc / testsuite / gcc.target / powerpc / ppc64-abi-2.c
blobeb1df7a2dc97503de9cb27cdbf6c72c9181b0ef9
1 /* { dg-do run { target { { powerpc*-*-linux* && lp64 } && powerpc_altivec_ok } } } */
2 /* { dg-options "-O2 -fprofile -mprofile-kernel -maltivec -mabi=altivec" } */
3 #include <stdarg.h>
4 #include <signal.h>
5 #include <altivec.h>
6 #include <stdlib.h>
8 /* Testcase to check for ABI compliance of parameter passing
9 for the PowerPC64 ABI. */
11 void __attribute__((no_instrument_function))
12 sig_ill_handler (int sig)
14 exit(0);
17 extern void abort (void);
19 typedef struct
21 unsigned long gprs[8];
22 double fprs[13];
23 long pad;
24 vector int vrs[12];
25 } reg_parms_t;
27 volatile reg_parms_t gparms;
29 /* _mcount call is done on Linux ppc64 early in the prologue.
30 my_mcount will provide a entry point _mcount,
31 which will save all parameter registers to gparms.
32 Note that _mcount needs to restore lr to original value,
33 therefore use ctr to return.
36 extern void my_mcount (void) asm ("_mcount");
37 void __attribute__((no_instrument_function, no_split_stack))
38 my_mcount (void)
40 asm volatile ("mflr 12\n\t"
41 "mtctr 12\n\t"
42 "mtlr 0\n\t"
43 "addis 12,2,gparms@got@ha\n\t"
44 "ld 12,gparms@got@l(12)\n\t"
45 "std 3,0(12)\n\t"
46 "std 4,8(12)\n\t"
47 "std 5,16(12)\n\t"
48 "std 6,24(12)\n\t"
49 "std 7,32(12)\n\t"
50 "std 8,40(12)\n\t"
51 "std 9,48(12)\n\t"
52 "std 10,56(12)\n\t"
53 "stfd 1,64(12)\n\t"
54 "stfd 2,72(12)\n\t"
55 "stfd 3,80(12)\n\t"
56 "stfd 4,88(12)\n\t"
57 "stfd 5,96(12)\n\t"
58 "stfd 6,104(12)\n\t"
59 "stfd 7,112(12)\n\t"
60 "stfd 8,120(12)\n\t"
61 "stfd 9,128(12)\n\t"
62 "stfd 10,136(12)\n\t"
63 "stfd 11,144(12)\n\t"
64 "stfd 12,152(12)\n\t"
65 "stfd 13,160(12)\n\t"
66 "li 0,176\n\t"
67 "stvx 2,12,0\n\t"
68 "li 0,192\n\t"
69 "stvx 3,12,0\n\t"
70 "li 0,208\n\t"
71 "stvx 4,12,0\n\t"
72 "li 0,224\n\t"
73 "stvx 5,12,0\n\t"
74 "li 0,240\n\t"
75 "stvx 6,12,0\n\t"
76 "li 0,256\n\t"
77 "stvx 7,12,0\n\t"
78 "li 0,272\n\t"
79 "stvx 8,12,0\n\t"
80 "li 0,288\n\t"
81 "stvx 9,12,0\n\t"
82 "li 0,304\n\t"
83 "stvx 10,12,0\n\t"
84 "li 0,320\n\t"
85 "stvx 11,12,0\n\t"
86 "li 0,336\n\t"
87 "stvx 12,12,0\n\t"
88 "li 0,352\n\t"
89 "stvx 13,12,0\n\t"
90 "bctr");
93 /* Stackframe structure relevant for parameter passing. */
94 typedef union
96 double d;
97 unsigned long l;
98 unsigned int i[2];
99 } parm_t;
101 typedef struct sf
103 struct sf *backchain;
104 long a1;
105 long a2;
106 long a3;
107 #if _CALL_ELF != 2
108 long a4;
109 long a5;
110 #endif
111 parm_t slot[100];
112 } stack_frame_t;
114 typedef union
116 unsigned int i[4];
117 unsigned long l[2];
118 vector int v;
119 } vector_int_t;
121 #ifdef __LITTLE_ENDIAN__
122 #define MAKE_SLOT(x, y) ((long)x | ((long)y << 32))
123 #else
124 #define MAKE_SLOT(x, y) ((long)y | ((long)x << 32))
125 #endif
127 /* Paramter passing.
128 s : gpr 3
129 v : vpr 2
130 i : gpr 7
132 void __attribute__ ((noinline))
133 fcvi (char *s, vector int v, int i)
135 reg_parms_t lparms = gparms;
137 if (s != (char *) lparms.gprs[0])
138 abort();
140 if (!vec_all_eq (v, lparms.vrs[0]))
141 abort ();
143 if ((long) i != lparms.gprs[4])
144 abort();
146 /* Paramter passing.
147 s : gpr 3
148 v : vpr 2
149 w : vpr 3
152 void __attribute__ ((noinline))
153 fcvv (char *s, vector int v, vector int w)
155 vector int a, c = {6, 8, 10, 12};
156 reg_parms_t lparms = gparms;
158 if (s != (char *) lparms.gprs[0])
159 abort();
161 if (!vec_all_eq (v, lparms.vrs[0]))
162 abort ();
164 if (!vec_all_eq (w, lparms.vrs[1]))
165 abort ();
167 a = vec_add (v,w);
169 if (!vec_all_eq (a, c))
170 abort ();
173 /* Paramter passing.
174 s : gpr 3
175 i : gpr 4
176 v : vpr 2
177 w : vpr 3
179 void __attribute__ ((noinline))
180 fcivv (char *s, int i, vector int v, vector int w)
182 vector int a, c = {6, 8, 10, 12};
183 reg_parms_t lparms = gparms;
185 if (s != (char *) lparms.gprs[0])
186 abort();
188 if ((long) i != lparms.gprs[1])
189 abort();
191 if (!vec_all_eq (v, lparms.vrs[0]))
192 abort ();
194 if (!vec_all_eq (w, lparms.vrs[1]))
195 abort ();
197 a = vec_add (v,w);
199 if (!vec_all_eq (a, c))
200 abort ();
203 /* Paramter passing.
204 s : gpr 3
205 v : slot 2-3
206 w : slot 4-5
209 void __attribute__ ((noinline))
210 fcevv (char *s, ...)
212 vector int a, c = {6, 8, 10, 12};
213 vector int v,w;
214 stack_frame_t *sp;
215 reg_parms_t lparms = gparms;
216 va_list arg;
218 va_start (arg, s);
220 if (s != (char *) lparms.gprs[0])
221 abort();
223 v = va_arg(arg, vector int);
224 w = va_arg(arg, vector int);
225 a = vec_add (v,w);
227 if (!vec_all_eq (a, c))
228 abort ();
230 /* Go back one frame. */
231 sp = __builtin_frame_address(0);
232 sp = sp->backchain;
234 if (sp->slot[2].l != MAKE_SLOT (1, 2)
235 || sp->slot[4].l != MAKE_SLOT (5, 6))
236 abort();
239 /* Paramter passing.
240 s : gpr 3
241 i : gpr 4
242 j : gpr 5
243 v : slot 4-5
244 w : slot 6-7
246 void __attribute__ ((noinline))
247 fciievv (char *s, int i, int j, ...)
249 vector int a, c = {6, 8, 10, 12};
250 vector int v,w;
251 stack_frame_t *sp;
252 reg_parms_t lparms = gparms;
253 va_list arg;
255 va_start (arg, j);
257 if (s != (char *) lparms.gprs[0])
258 abort();
260 if ((long) i != lparms.gprs[1])
261 abort();
263 if ((long) j != lparms.gprs[2])
264 abort();
266 v = va_arg(arg, vector int);
267 w = va_arg(arg, vector int);
268 a = vec_add (v,w);
270 if (!vec_all_eq (a, c))
271 abort ();
273 sp = __builtin_frame_address(0);
274 sp = sp->backchain;
276 if (sp->slot[4].l != MAKE_SLOT (1, 2)
277 || sp->slot[6].l != MAKE_SLOT (5, 6))
278 abort();
281 void __attribute__ ((noinline))
282 fcvevv (char *s, vector int x, ...)
284 vector int a, c = {7, 10, 13, 16};
285 vector int v,w;
286 stack_frame_t *sp;
287 reg_parms_t lparms = gparms;
288 va_list arg;
290 va_start (arg, x);
292 v = va_arg(arg, vector int);
293 w = va_arg(arg, vector int);
295 a = vec_add (v,w);
296 a = vec_add (a, x);
298 if (!vec_all_eq (a, c))
299 abort ();
301 sp = __builtin_frame_address(0);
302 sp = sp->backchain;
304 if (sp->slot[4].l != MAKE_SLOT (1, 2)
305 || sp->slot[6].l != MAKE_SLOT (5, 6))
306 abort();
309 int __attribute__((no_instrument_function, noinline))
310 main1()
312 char *s = "vv";
313 vector int v = {1, 2, 3, 4};
314 vector int w = {5, 6, 7, 8};
316 fcvi (s, v, 2);
317 fcvv (s, v, w);
318 fcivv (s, 1, v, w);
319 fcevv (s, v, w);
320 fciievv (s, 1, 2, v, w);
321 fcvevv (s, v, v, w);
322 return 0;
325 int __attribute__((no_instrument_function))
326 main()
328 /* Exit on systems without altivec. */
329 signal (SIGILL, sig_ill_handler);
330 /* Altivec instruction, 'vor %v0,%v0,%v0'. */
331 asm volatile (".long 0x10000484");
332 signal (SIGILL, SIG_DFL);
334 return main1 ();
337 /* Paramter passing.
338 Function called with no prototype.
339 s : gpr 3
340 v : vpr 2 gpr 5-6
341 w : vpr 3 gpr 7-8
342 x : vpr 4 gpr 9-10
343 y : vpr 5 slot 8-9
345 void
346 fnp_cvvvv (char *s, vector int v, vector int w,
347 vector int x, vector int y)
349 vector int a, c = {12, 16, 20, 24};
350 reg_parms_t lparms = gparms;
351 stack_frame_t *sp;
352 vector_int_t v0, v1, v2, v3;
354 if (s != (char *) lparms.gprs[0])
355 abort();
357 if (!vec_all_eq (v, lparms.vrs[0]))
358 abort ();
360 if (!vec_all_eq (w, lparms.vrs[1]))
361 abort ();
363 if (!vec_all_eq (x, lparms.vrs[2]))
364 abort ();
366 if (!vec_all_eq (y, lparms.vrs[3]))
367 abort ();
369 a = vec_add (v,w);
370 a = vec_add (a,x);
371 a = vec_add (a,y);
373 if (!vec_all_eq (a, c))
374 abort ();
376 v0.v = lparms.vrs[0];
377 v1.v = lparms.vrs[1];
378 v2.v = lparms.vrs[2];
379 v3.v = lparms.vrs[3];
381 if (v0.l[0] != lparms.gprs[2])
382 abort ();
384 if (v0.l[1] != lparms.gprs[3])
385 abort ();
387 if (v1.l[0] != lparms.gprs[4])
388 abort ();
390 if (v1.l[1] != lparms.gprs[5])
391 abort ();
393 if (v2.l[0] != lparms.gprs[6])
394 abort ();
396 if (v2.l[1] != lparms.gprs[7])
397 abort ();
399 sp = __builtin_frame_address(0);
400 sp = sp->backchain;
402 if (sp->slot[8].l != v3.l[0])
403 abort ();
405 if (sp->slot[9].l != v3.l[1])
406 abort ();