Merge reload-branch up to revision 101000
[official-gcc.git] / gcc / testsuite / gcc.dg / ppc64-abi-2.c
blob93ce7195d0cda180dc3ae1004d8382b1152c6825
1 /* { dg-do run { target powerpc64-*-linux* } } */
2 /* { dg-require-effective-target lp64 } */
3 /* { dg-options "-O2 -fprofile -mprofile-kernel -maltivec -mabi=altivec" } */
4 #include <stdarg.h>
5 #include <signal.h>
6 #include <altivec.h>
7 #include <stdlib.h>
9 /* Testcase to check for ABI compliance of parameter passing
10 for the PowerPC64 ABI. */
12 void __attribute__((no_instrument_function))
13 sig_ill_handler (int sig)
15 exit(0);
18 extern void abort (void);
20 typedef struct
22 unsigned long gprs[8];
23 double fprs[13];
24 long pad;
25 vector int vrs[12];
26 } reg_parms_t;
28 reg_parms_t gparms;
30 /* _mcount call is done on Linux ppc64 early in the prologue.
31 my_mcount will provide a entry point _mcount,
32 which will save all register to gparms.
33 Note that _mcount need to restore lr to original value,
34 therefor use ctr to return.
37 void __attribute__((no_instrument_function))
38 my_mcount()
40 asm volatile (".type _mcount,@function\n\t"
41 ".globl _mcount\n\t"
42 "_mcount:\n\t"
43 "mflr 0\n\t"
44 "mtctr 0\n\t"
45 "ld 0,16(1)\n\t"
46 "mtlr 0\n\t"
47 "ld 11,gparms@got(2)\n\t"
48 "std 3,0(11)\n\t"
49 "std 4,8(11)\n\t"
50 "std 5,16(11)\n\t"
51 "std 6,24(11)\n\t"
52 "std 7,32(11)\n\t"
53 "std 8,40(11)\n\t"
54 "std 9,48(11)\n\t"
55 "std 10,56(11)\n\t"
56 "stfd 1,64(11)\n\t"
57 "stfd 2,72(11)\n\t"
58 "stfd 3,80(11)\n\t"
59 "stfd 4,88(11)\n\t"
60 "stfd 5,96(11)\n\t"
61 "stfd 6,104(11)\n\t"
62 "stfd 7,112(11)\n\t"
63 "stfd 8,120(11)\n\t"
64 "stfd 9,128(11)\n\t"
65 "stfd 10,136(11)\n\t"
66 "stfd 11,144(11)\n\t"
67 "stfd 12,152(11)\n\t"
68 "stfd 13,160(11)\n\t"
69 "li 3,176\n\t"
70 "stvx 2,3,11\n\t"
71 "addi 3,3,16\n\t"
72 "stvx 3,3,11\n\t"
73 "addi 3,3,16\n\t"
74 "stvx 4,3,11\n\t"
75 "addi 3,3,16\n\t"
76 "stvx 5,3,11\n\t"
77 "addi 3,3,16\n\t"
78 "stvx 6,3,11\n\t"
79 "addi 3,3,16\n\t"
80 "stvx 7,3,11\n\t"
81 "addi 3,3,16\n\t"
82 "stvx 8,3,11\n\t"
83 "addi 3,3,16\n\t"
84 "stvx 9,3,11\n\t"
85 "addi 3,3,16\n\t"
86 "stvx 10,3,11\n\t"
87 "addi 3,3,16\n\t"
88 "stvx 11,3,11\n\t"
89 "addi 3,3,16\n\t"
90 "stvx 12,3,11\n\t"
91 "addi 3,3,16\n\t"
92 "stvx 13,3,11\n\t"
93 "ld 3,0(11)\n\t"
94 "bctr");
97 /* Stackframe structure relevant for parameter passing. */
98 typedef union
100 double d;
101 unsigned long l;
102 unsigned int i[2];
103 } parm_t;
105 typedef struct sf
107 struct sf *backchain;
108 long a1;
109 long a2;
110 long a3;
111 long a4;
112 long a5;
113 parm_t slot[100];
114 } stack_frame_t;
116 typedef union
118 unsigned int i[4];
119 unsigned long l[2];
120 vector int v;
121 } vector_int_t;
123 /* Paramter passing.
124 s : gpr 3
125 v : vpr 2
126 i : gpr 7
128 void __attribute__ ((noinline))
129 fcvi (char *s, vector int v, int i)
131 reg_parms_t lparms = gparms;
133 if (s != (char *) lparms.gprs[0])
134 abort();
136 if (!vec_all_eq (v, lparms.vrs[0]))
137 abort ();
139 if ((long) i != lparms.gprs[4])
140 abort();
142 /* Paramter passing.
143 s : gpr 3
144 v : vpr 2
145 w : vpr 3
148 void __attribute__ ((noinline))
149 fcvv (char *s, vector int v, vector int w)
151 vector int a, c = {6, 8, 10, 12};
152 reg_parms_t lparms = gparms;
154 if (s != (char *) lparms.gprs[0])
155 abort();
157 if (!vec_all_eq (v, lparms.vrs[0]))
158 abort ();
160 if (!vec_all_eq (w, lparms.vrs[1]))
161 abort ();
163 a = vec_add (v,w);
165 if (!vec_all_eq (a, c))
166 abort ();
169 /* Paramter passing.
170 s : gpr 3
171 i : gpr 4
172 v : vpr 2
173 w : vpr 3
175 void __attribute__ ((noinline))
176 fcivv (char *s, int i, vector int v, vector int w)
178 vector int a, c = {6, 8, 10, 12};
179 reg_parms_t lparms = gparms;
181 if (s != (char *) lparms.gprs[0])
182 abort();
184 if ((long) i != lparms.gprs[1])
185 abort();
187 if (!vec_all_eq (v, lparms.vrs[0]))
188 abort ();
190 if (!vec_all_eq (w, lparms.vrs[1]))
191 abort ();
193 a = vec_add (v,w);
195 if (!vec_all_eq (a, c))
196 abort ();
199 /* Paramter passing.
200 s : gpr 3
201 v : slot 2-3
202 w : slot 4-5
205 void __attribute__ ((noinline))
206 fcevv (char *s, ...)
208 vector int a, c = {6, 8, 10, 12};
209 vector int v,w;
210 stack_frame_t *sp;
211 reg_parms_t lparms = gparms;
212 va_list arg;
214 va_start (arg, s);
216 if (s != (char *) lparms.gprs[0])
217 abort();
219 v = va_arg(arg, vector int);
220 w = va_arg(arg, vector int);
221 a = vec_add (v,w);
223 if (!vec_all_eq (a, c))
224 abort ();
226 /* Go back one frame. */
227 sp = __builtin_frame_address(0);
228 sp = sp->backchain;
230 if (sp->slot[2].l != 0x100000002ULL
231 || sp->slot[4].l != 0x500000006ULL)
232 abort();
235 /* Paramter passing.
236 s : gpr 3
237 i : gpr 4
238 j : gpr 5
239 v : slot 4-5
240 w : slot 6-7
242 void __attribute__ ((noinline))
243 fciievv (char *s, int i, int j, ...)
245 vector int a, c = {6, 8, 10, 12};
246 vector int v,w;
247 stack_frame_t *sp;
248 reg_parms_t lparms = gparms;
249 va_list arg;
251 va_start (arg, j);
253 if (s != (char *) lparms.gprs[0])
254 abort();
256 if ((long) i != lparms.gprs[1])
257 abort();
259 if ((long) j != lparms.gprs[2])
260 abort();
262 v = va_arg(arg, vector int);
263 w = va_arg(arg, vector int);
264 a = vec_add (v,w);
266 if (!vec_all_eq (a, c))
267 abort ();
269 sp = __builtin_frame_address(0);
270 sp = sp->backchain;
272 if (sp->slot[4].l != 0x100000002ULL
273 || sp->slot[6].l != 0x500000006ULL)
274 abort();
277 void __attribute__ ((noinline))
278 fcvevv (char *s, vector int x, ...)
280 vector int a, c = {7, 10, 13, 16};
281 vector int v,w;
282 stack_frame_t *sp;
283 reg_parms_t lparms = gparms;
284 va_list arg;
286 va_start (arg, x);
288 v = va_arg(arg, vector int);
289 w = va_arg(arg, vector int);
291 a = vec_add (v,w);
292 a = vec_add (a, x);
294 if (!vec_all_eq (a, c))
295 abort ();
297 sp = __builtin_frame_address(0);
298 sp = sp->backchain;
300 if (sp->slot[4].l != 0x100000002ULL
301 || sp->slot[6].l != 0x500000006ULL)
302 abort();
305 int __attribute__((no_instrument_function, noinline))
306 main1()
308 char *s = "vv";
309 vector int v = {1, 2, 3, 4};
310 vector int w = {5, 6, 7, 8};
312 fcvi (s, v, 2);
313 fcvv (s, v, w);
314 fcivv (s, 1, v, w);
315 fcevv (s, v, w);
316 fciievv (s, 1, 2, v, w);
317 fcvevv (s, v, v, w);
318 return 0;
321 int __attribute__((no_instrument_function))
322 main()
324 /* Exit on systems without altivec. */
325 signal (SIGILL, sig_ill_handler);
326 /* Altivec instruction, 'vor %v0,%v0,%v0'. */
327 asm volatile (".long 0x10000484");
328 signal (SIGILL, SIG_DFL);
330 return main1 ();
333 /* Paramter passing.
334 Function called with no prototype.
335 s : gpr 3
336 v : vpr 2 gpr 5-6
337 w : vpr 3 gpr 7-8
338 x : vpr 4 gpr 9-10
339 y : vpr 5 slot 8-9
341 void
342 fnp_cvvvv (char *s, vector int v, vector int w,
343 vector int x, vector int y)
345 vector int a, c = {12, 16, 20, 24};
346 reg_parms_t lparms = gparms;
347 stack_frame_t *sp;
348 vector_int_t v0, v1, v2, v3;
350 if (s != (char *) lparms.gprs[0])
351 abort();
353 if (!vec_all_eq (v, lparms.vrs[0]))
354 abort ();
356 if (!vec_all_eq (w, lparms.vrs[1]))
357 abort ();
359 if (!vec_all_eq (x, lparms.vrs[2]))
360 abort ();
362 if (!vec_all_eq (y, lparms.vrs[3]))
363 abort ();
365 a = vec_add (v,w);
366 a = vec_add (a,x);
367 a = vec_add (a,y);
369 if (!vec_all_eq (a, c))
370 abort ();
372 v0.v = lparms.vrs[0];
373 v1.v = lparms.vrs[1];
374 v2.v = lparms.vrs[2];
375 v3.v = lparms.vrs[3];
377 if (v0.l[0] != lparms.gprs[2])
378 abort ();
380 if (v0.l[1] != lparms.gprs[3])
381 abort ();
383 if (v1.l[0] != lparms.gprs[4])
384 abort ();
386 if (v1.l[1] != lparms.gprs[5])
387 abort ();
389 if (v2.l[0] != lparms.gprs[6])
390 abort ();
392 if (v2.l[1] != lparms.gprs[7])
393 abort ();
395 sp = __builtin_frame_address(0);
396 sp = sp->backchain;
398 if (sp->slot[8].l != v3.l[0])
399 abort ();
401 if (sp->slot[9].l != v3.l[1])
402 abort ();