Merge to HEAD at tree-cleanup-merge-20041024 .
[official-gcc.git] / gcc / testsuite / gcc.dg / ppc64-abi-2.c
blob93c121c463df5bb930b69abff8367f3c16c36234
1 /* { dg-do run { target powerpc64-*-linux* } } */
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 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 register to gparms.
32 Note that _mcount need to restore lr to original value,
33 therefor use ctr to return.
36 void __attribute__((no_instrument_function))
37 my_mcount()
39 asm volatile (".type _mcount,@function\n\t"
40 ".globl _mcount\n\t"
41 "_mcount:\n\t"
42 "mflr 0\n\t"
43 "mtctr 0\n\t"
44 "ld 0,16(1)\n\t"
45 "mtlr 0\n\t"
46 "ld 11,gparms@got(2)\n\t"
47 "std 3,0(11)\n\t"
48 "std 4,8(11)\n\t"
49 "std 5,16(11)\n\t"
50 "std 6,24(11)\n\t"
51 "std 7,32(11)\n\t"
52 "std 8,40(11)\n\t"
53 "std 9,48(11)\n\t"
54 "std 10,56(11)\n\t"
55 "stfd 1,64(11)\n\t"
56 "stfd 2,72(11)\n\t"
57 "stfd 3,80(11)\n\t"
58 "stfd 4,88(11)\n\t"
59 "stfd 5,96(11)\n\t"
60 "stfd 6,104(11)\n\t"
61 "stfd 7,112(11)\n\t"
62 "stfd 8,120(11)\n\t"
63 "stfd 9,128(11)\n\t"
64 "stfd 10,136(11)\n\t"
65 "stfd 11,144(11)\n\t"
66 "stfd 12,152(11)\n\t"
67 "stfd 13,160(11)\n\t"
68 "li 3,176\n\t"
69 "stvx 2,3,11\n\t"
70 "addi 3,3,16\n\t"
71 "stvx 3,3,11\n\t"
72 "addi 3,3,16\n\t"
73 "stvx 4,3,11\n\t"
74 "addi 3,3,16\n\t"
75 "stvx 5,3,11\n\t"
76 "addi 3,3,16\n\t"
77 "stvx 6,3,11\n\t"
78 "addi 3,3,16\n\t"
79 "stvx 7,3,11\n\t"
80 "addi 3,3,16\n\t"
81 "stvx 8,3,11\n\t"
82 "addi 3,3,16\n\t"
83 "stvx 9,3,11\n\t"
84 "addi 3,3,16\n\t"
85 "stvx 10,3,11\n\t"
86 "addi 3,3,16\n\t"
87 "stvx 11,3,11\n\t"
88 "addi 3,3,16\n\t"
89 "stvx 12,3,11\n\t"
90 "addi 3,3,16\n\t"
91 "stvx 13,3,11\n\t"
92 "ld 3,0(11)\n\t"
93 "bctr");
96 /* Stackframe structure relevant for parameter passing. */
97 typedef union
99 double d;
100 unsigned long l;
101 unsigned int i[2];
102 } parm_t;
104 typedef struct sf
106 struct sf *backchain;
107 long a1;
108 long a2;
109 long a3;
110 long a4;
111 long a5;
112 parm_t slot[100];
113 } stack_frame_t;
115 typedef union
117 unsigned int i[4];
118 unsigned long l[2];
119 vector int v;
120 } vector_int_t;
122 /* Paramter passing.
123 s : gpr 3
124 v : vpr 2
125 i : gpr 7
127 void __attribute__ ((noinline))
128 fcvi (char *s, vector int v, int i)
130 reg_parms_t lparms = gparms;
132 if (s != (char *) lparms.gprs[0])
133 abort();
135 if (!vec_all_eq (v, lparms.vrs[0]))
136 abort ();
138 if ((long) i != lparms.gprs[4])
139 abort();
141 /* Paramter passing.
142 s : gpr 3
143 v : vpr 2
144 w : vpr 3
147 void __attribute__ ((noinline))
148 fcvv (char *s, vector int v, vector int w)
150 vector int a, c = {6, 8, 10, 12};
151 reg_parms_t lparms = gparms;
153 if (s != (char *) lparms.gprs[0])
154 abort();
156 if (!vec_all_eq (v, lparms.vrs[0]))
157 abort ();
159 if (!vec_all_eq (w, lparms.vrs[1]))
160 abort ();
162 a = vec_add (v,w);
164 if (!vec_all_eq (a, c))
165 abort ();
168 /* Paramter passing.
169 s : gpr 3
170 i : gpr 4
171 v : vpr 2
172 w : vpr 3
174 void __attribute__ ((noinline))
175 fcivv (char *s, int i, vector int v, vector int w)
177 vector int a, c = {6, 8, 10, 12};
178 reg_parms_t lparms = gparms;
180 if (s != (char *) lparms.gprs[0])
181 abort();
183 if ((long) i != lparms.gprs[1])
184 abort();
186 if (!vec_all_eq (v, lparms.vrs[0]))
187 abort ();
189 if (!vec_all_eq (w, lparms.vrs[1]))
190 abort ();
192 a = vec_add (v,w);
194 if (!vec_all_eq (a, c))
195 abort ();
198 /* Paramter passing.
199 s : gpr 3
200 v : slot 2-3
201 w : slot 4-5
204 void __attribute__ ((noinline))
205 fcevv (char *s, ...)
207 vector int a, c = {6, 8, 10, 12};
208 vector int v,w;
209 stack_frame_t *sp;
210 reg_parms_t lparms = gparms;
211 va_list arg;
213 va_start (arg, s);
215 if (s != (char *) lparms.gprs[0])
216 abort();
218 v = va_arg(arg, vector int);
219 w = va_arg(arg, vector int);
220 a = vec_add (v,w);
222 if (!vec_all_eq (a, c))
223 abort ();
225 /* Go back one frame. */
226 sp = __builtin_frame_address(0);
227 sp = sp->backchain;
229 if (sp->slot[2].l != 0x100000002ULL
230 || sp->slot[4].l != 0x500000006ULL)
231 abort();
234 /* Paramter passing.
235 s : gpr 3
236 i : gpr 4
237 j : gpr 5
238 v : slot 4-5
239 w : slot 6-7
241 void __attribute__ ((noinline))
242 fciievv (char *s, int i, int j, ...)
244 vector int a, c = {6, 8, 10, 12};
245 vector int v,w;
246 stack_frame_t *sp;
247 reg_parms_t lparms = gparms;
248 va_list arg;
250 va_start (arg, j);
252 if (s != (char *) lparms.gprs[0])
253 abort();
255 if ((long) i != lparms.gprs[1])
256 abort();
258 if ((long) j != lparms.gprs[2])
259 abort();
261 v = va_arg(arg, vector int);
262 w = va_arg(arg, vector int);
263 a = vec_add (v,w);
265 if (!vec_all_eq (a, c))
266 abort ();
268 sp = __builtin_frame_address(0);
269 sp = sp->backchain;
271 if (sp->slot[4].l != 0x100000002ULL
272 || sp->slot[6].l != 0x500000006ULL)
273 abort();
276 void __attribute__ ((noinline))
277 fcvevv (char *s, vector int x, ...)
279 vector int a, c = {7, 10, 13, 16};
280 vector int v,w;
281 stack_frame_t *sp;
282 reg_parms_t lparms = gparms;
283 va_list arg;
285 va_start (arg, x);
287 v = va_arg(arg, vector int);
288 w = va_arg(arg, vector int);
290 a = vec_add (v,w);
291 a = vec_add (a, x);
293 if (!vec_all_eq (a, c))
294 abort ();
296 sp = __builtin_frame_address(0);
297 sp = sp->backchain;
299 if (sp->slot[4].l != 0x100000002ULL
300 || sp->slot[6].l != 0x500000006ULL)
301 abort();
304 void fnp_cvvvv();
306 int __attribute__((no_instrument_function, noinline))
307 main1()
309 char *s = "vv";
310 vector int v = {1, 2, 3, 4};
311 vector int w = {5, 6, 7, 8};
313 fcvi (s, v, 2);
314 fcvv (s, v, w);
315 fnp_cvvvv (s, v, w, v, w);
316 fcivv (s, 1, v, w);
317 fcevv (s, v, w);
318 fciievv (s, 1, 2, v, w);
319 fcvevv (s, v, v, w);
320 return 0;
323 int __attribute__((no_instrument_function))
324 main()
326 /* Exit on systems without altivec. */
327 signal (SIGILL, sig_ill_handler);
328 /* Altivec instruction, 'vor %v0,%v0,%v0'. */
329 asm volatile (".long 0x10000484");
330 signal (SIGILL, SIG_DFL);
332 return main1 ();
335 /* Paramter passing.
336 Function called with no prototype.
337 s : gpr 3
338 v : vpr 2 gpr 5-6
339 w : vpr 3 gpr 7-8
340 x : vpr 4 gpr 9-10
341 y : vpr 5 slot 8-9
343 void
344 fnp_cvvvv (char *s, vector int v, vector int w,
345 vector int x, vector int y)
347 vector int a, c = {12, 16, 20, 24};
348 reg_parms_t lparms = gparms;
349 stack_frame_t *sp;
350 vector_int_t v0, v1, v2, v3;
352 if (s != (char *) lparms.gprs[0])
353 abort();
355 if (!vec_all_eq (v, lparms.vrs[0]))
356 abort ();
358 if (!vec_all_eq (w, lparms.vrs[1]))
359 abort ();
361 if (!vec_all_eq (x, lparms.vrs[2]))
362 abort ();
364 if (!vec_all_eq (y, lparms.vrs[3]))
365 abort ();
367 a = vec_add (v,w);
368 a = vec_add (a,x);
369 a = vec_add (a,y);
371 if (!vec_all_eq (a, c))
372 abort ();
374 v0.v = lparms.vrs[0];
375 v1.v = lparms.vrs[1];
376 v2.v = lparms.vrs[2];
377 v3.v = lparms.vrs[3];
379 if (v0.l[0] != lparms.gprs[2])
380 abort ();
382 if (v0.l[1] != lparms.gprs[3])
383 abort ();
385 if (v1.l[0] != lparms.gprs[4])
386 abort ();
388 if (v1.l[1] != lparms.gprs[5])
389 abort ();
391 if (v2.l[0] != lparms.gprs[6])
392 abort ();
394 if (v2.l[1] != lparms.gprs[7])
395 abort ();
397 sp = __builtin_frame_address(0);
398 sp = sp->backchain;
400 if (sp->slot[8].l != v3.l[0])
401 abort ();
403 if (sp->slot[9].l != v3.l[1])
404 abort ();