Merge from mainline (gomp-merge-2005-02-26).
[official-gcc.git] / gcc / testsuite / gcc.dg / ppc64-abi-2.c
blobe6baa25f4a384d7c2b8a642f0399df78726ef6d7
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 void fnp_cvvvv();
307 int __attribute__((no_instrument_function, noinline))
308 main1()
310 char *s = "vv";
311 vector int v = {1, 2, 3, 4};
312 vector int w = {5, 6, 7, 8};
314 fcvi (s, v, 2);
315 fcvv (s, v, w);
316 fnp_cvvvv (s, v, w, v, w);
317 fcivv (s, 1, v, w);
318 fcevv (s, v, w);
319 fciievv (s, 1, 2, v, w);
320 fcvevv (s, v, v, w);
321 return 0;
324 int __attribute__((no_instrument_function))
325 main()
327 /* Exit on systems without altivec. */
328 signal (SIGILL, sig_ill_handler);
329 /* Altivec instruction, 'vor %v0,%v0,%v0'. */
330 asm volatile (".long 0x10000484");
331 signal (SIGILL, SIG_DFL);
333 return main1 ();
336 /* Paramter passing.
337 Function called with no prototype.
338 s : gpr 3
339 v : vpr 2 gpr 5-6
340 w : vpr 3 gpr 7-8
341 x : vpr 4 gpr 9-10
342 y : vpr 5 slot 8-9
344 void
345 fnp_cvvvv (char *s, vector int v, vector int w,
346 vector int x, vector int y)
348 vector int a, c = {12, 16, 20, 24};
349 reg_parms_t lparms = gparms;
350 stack_frame_t *sp;
351 vector_int_t v0, v1, v2, v3;
353 if (s != (char *) lparms.gprs[0])
354 abort();
356 if (!vec_all_eq (v, lparms.vrs[0]))
357 abort ();
359 if (!vec_all_eq (w, lparms.vrs[1]))
360 abort ();
362 if (!vec_all_eq (x, lparms.vrs[2]))
363 abort ();
365 if (!vec_all_eq (y, lparms.vrs[3]))
366 abort ();
368 a = vec_add (v,w);
369 a = vec_add (a,x);
370 a = vec_add (a,y);
372 if (!vec_all_eq (a, c))
373 abort ();
375 v0.v = lparms.vrs[0];
376 v1.v = lparms.vrs[1];
377 v2.v = lparms.vrs[2];
378 v3.v = lparms.vrs[3];
380 if (v0.l[0] != lparms.gprs[2])
381 abort ();
383 if (v0.l[1] != lparms.gprs[3])
384 abort ();
386 if (v1.l[0] != lparms.gprs[4])
387 abort ();
389 if (v1.l[1] != lparms.gprs[5])
390 abort ();
392 if (v2.l[0] != lparms.gprs[6])
393 abort ();
395 if (v2.l[1] != lparms.gprs[7])
396 abort ();
398 sp = __builtin_frame_address(0);
399 sp = sp->backchain;
401 if (sp->slot[8].l != v3.l[0])
402 abort ();
404 if (sp->slot[9].l != v3.l[1])
405 abort ();