Merge from mainline (gomp-merge-2005-02-26).
[official-gcc.git] / gcc / testsuite / gcc.dg / ppc64-abi-1.c
blobd0cb9cd6c90ee38d0b5fae6e5d1737dd7b97bbc9
1 /* { dg-do run { target powerpc64-*-* } } */
2 /* { dg-require-effective-target lp64 } */
3 /* { dg-options "-O2" } */
4 #include <stdarg.h>
5 #include <signal.h>
6 #include <stdio.h>
8 /* Testcase to check for ABI compliance of parameter passing
9 for the PowerPC64 ABI.
10 Parameter passing of integral and floating point is tested. */
12 extern void abort (void);
14 typedef struct
16 unsigned long gprs[8];
17 double fprs[13];
18 } reg_parms_t;
20 reg_parms_t gparms;
23 /* Testcase could break on future gcc's, if parameter regs
24 are changed before this asm. */
26 #ifndef __MACH__
27 #define save_parms(lparms) \
28 asm volatile ("ld 11,gparms@got(2)\n\t" \
29 "std 3,0(11)\n\t" \
30 "std 4,8(11)\n\t" \
31 "std 5,16(11)\n\t" \
32 "std 6,24(11)\n\t" \
33 "std 7,32(11)\n\t" \
34 "std 8,40(11)\n\t" \
35 "std 9,48(11)\n\t" \
36 "std 10,56(11)\n\t" \
37 "stfd 1,64(11)\n\t" \
38 "stfd 2,72(11)\n\t" \
39 "stfd 3,80(11)\n\t" \
40 "stfd 4,88(11)\n\t" \
41 "stfd 5,96(11)\n\t" \
42 "stfd 6,104(11)\n\t" \
43 "stfd 7,112(11)\n\t" \
44 "stfd 8,120(11)\n\t" \
45 "stfd 9,128(11)\n\t" \
46 "stfd 10,136(11)\n\t" \
47 "stfd 11,144(11)\n\t" \
48 "stfd 12,152(11)\n\t" \
49 "stfd 13,160(11)\n\t":::"11", "memory"); \
50 lparms = gparms;
51 #else
52 #define save_parms(lparms) \
53 asm volatile ("ld r11,gparms@got(r2)\n\t" \
54 "std r3,0(r11)\n\t" \
55 "std r4,8(r11)\n\t" \
56 "std r5,16(r11)\n\t" \
57 "std r6,24(r11)\n\t" \
58 "std r7,32(r11)\n\t" \
59 "std r8,40(r11)\n\t" \
60 "std r9,48(r11)\n\t" \
61 "std r10,56(r11)\n\t" \
62 "stfd f1,64(r11)\n\t" \
63 "stfd f2,72(r11)\n\t" \
64 "stfd f3,80(r11)\n\t" \
65 "stfd f4,88(r11)\n\t" \
66 "stfd f5,96(r11)\n\t" \
67 "stfd f6,104(r11)\n\t" \
68 "stfd f7,112(r11)\n\t" \
69 "stfd f8,120(r11)\n\t" \
70 "stfd f9,128(r11)\n\t" \
71 "stfd f10,136(r11)\n\t" \
72 "stfd f11,144(r11)\n\t" \
73 "stfd f12,152(r11)\n\t" \
74 "stfd f13,160(r11)\n\t":::"r11", "memory"); \
75 lparms = gparms;
76 #endif
78 /* Stackframe structure relevant for parameter passing. */
79 typedef union
81 double d;
82 unsigned long l;
83 unsigned int i[2];
84 } parm_t;
86 typedef struct sf
88 struct sf *backchain;
89 long a1;
90 long a2;
91 long a3;
92 long a4;
93 long a5;
94 parm_t slot[100];
95 } stack_frame_t;
98 /* Paramter passing.
99 s : gpr 3
100 l : gpr 4
101 d : fpr 1
103 void __attribute__ ((noinline)) fcld (char *s, long l, double d)
105 reg_parms_t lparms;
106 save_parms (lparms);
108 if (s != (char *) lparms.gprs[0])
109 abort ();
111 if (l != lparms.gprs[1])
112 abort ();
114 if (d != lparms.fprs[0])
115 abort ();
118 /* Paramter passing.
119 s : gpr 3
120 l : gpr 4
121 d : fpr 2
122 i : gpr 5
124 void __attribute__ ((noinline))
125 fcldi (char *s, long l, double d, signed int i)
127 reg_parms_t lparms;
128 save_parms (lparms);
130 if (s != (char *) lparms.gprs[0])
131 abort ();
133 if (l != lparms.gprs[1])
134 abort ();
136 if (d != lparms.fprs[0])
137 abort ();
139 if ((signed long) i != lparms.gprs[3])
140 abort ();
143 /* Paramter passing.
144 s : gpr 3
145 l : gpr 4
146 d : fpr 2
147 i : gpr 5
149 void __attribute__ ((noinline))
150 fcldu (char *s, long l, float d, unsigned int i)
152 reg_parms_t lparms;
153 save_parms (lparms);
155 if (s != (char *) lparms.gprs[0])
156 abort ();
158 if (l != lparms.gprs[1])
159 abort ();
161 if ((double) d != lparms.fprs[0])
162 abort ();
164 if ((unsigned long) i != lparms.gprs[3])
165 abort ();
168 /* Paramter passing.
169 s : gpr 3
170 l : slot 1
171 d : slot 2
174 void __attribute__ ((noinline)) fceld (char *s, ...)
176 stack_frame_t *sp;
177 reg_parms_t lparms;
178 va_list arg;
179 double d;
180 long l;
181 save_parms (lparms);
183 va_start (arg, s);
185 if (s != (char *) lparms.gprs[0])
186 abort ();
188 l = va_arg (arg, long);
189 d = va_arg (arg, double);
191 /* Go back one frame. */
192 sp = __builtin_frame_address (0);
193 sp = sp->backchain;
195 if (sp->slot[1].l != l)
196 abort ();
198 if (sp->slot[2].d != d)
199 abort ();
202 /* Paramter passing.
203 s : gpr 3
204 i : gpr 4
205 j : gpr 5
206 d : slot 3
207 l : slot 4
209 void __attribute__ ((noinline)) fciiedl (char *s, int i, int j, ...)
211 stack_frame_t *sp;
212 reg_parms_t lparms;
213 va_list arg;
214 double d;
215 long l;
216 save_parms (lparms);
218 va_start (arg, j);
220 if (s != (char *) lparms.gprs[0])
221 abort ();
223 if ((long) i != lparms.gprs[1])
224 abort ();
226 if ((long) j != lparms.gprs[2])
227 abort ();
229 d = va_arg (arg, double);
230 l = va_arg (arg, long);
232 sp = __builtin_frame_address (0);
233 sp = sp->backchain;
235 if (sp->slot[3].d != d)
236 abort ();
238 if (sp->slot[4].l != l)
239 abort ();
243 Parameter Register Offset in parameter save area
244 c r3 0-7 (not stored in parameter save area)
245 ff f1 8-15 (not stored)
246 d r5 16-23 (not stored)
247 ld f2 24-31 (not stored)
248 f r7 32-39 (not stored)
249 s r8,r9 40-55 (not stored)
250 gg f3 56-63 (not stored)
251 t (none) 64-79 (stored in parameter save area)
252 e (none) 80-87 (stored)
253 hh f4 88-95 (stored)
257 typedef struct
259 int a;
260 double dd;
261 } sparm;
263 typedef union
265 int i[2];
266 long l;
267 double d;
268 } double_t;
270 /* Example from ABI documentation with slight changes.
271 Paramter passing.
272 c : gpr 3
273 ff : fpr 1
274 d : gpr 5
275 ld : fpr 2
276 f : gpr 7
277 s : gpr 8 - 9
278 gg : fpr 3
279 t : save area offset 64 - 79
280 e : save area offset 80 - 88
281 hh : fpr 4
284 void __attribute__ ((noinline))
285 fididisdsid (int c, double ff, int d, double ld, int f,
286 sparm s, double gg, sparm t, int e, double hh)
288 stack_frame_t *sp;
289 reg_parms_t lparms;
290 double_t dx, dy;
292 save_parms (lparms);
294 /* Parm 0: int. */
295 if ((long) c != lparms.gprs[0])
296 abort ();
298 /* Parm 1: double. */
299 if (ff != lparms.fprs[0])
300 abort ();
302 /* Parm 2: int. */
303 if ((long) d != lparms.gprs[2])
304 abort ();
306 /* Parm 3: double. */
307 if (ld != lparms.fprs[1])
308 abort ();
310 /* Parm 4: int. */
311 if ((long) f != lparms.gprs[4])
312 abort ();
314 /* Parm 5: struct sparm. */
315 dx.l = lparms.gprs[5];
316 dy.l = lparms.gprs[6];
318 if (s.a != dx.i[0])
319 abort ();
320 if (s.dd != dy.d)
321 abort ();
323 /* Parm 6: double. */
324 if (gg != lparms.fprs[2])
325 abort ();
327 sp = __builtin_frame_address (0);
328 sp = sp->backchain;
330 /* Parm 7: struct sparm. */
331 dx.l = sp->slot[8].l;
332 dy.l = sp->slot[9].l;
333 if (t.a != dx.i[0])
334 abort ();
335 if (t.dd != dy.d)
336 abort ();
338 /* Parm 8: int. */
339 if (e != sp->slot[10].l)
340 abort ();
342 /* Parm 9: double. */
344 if (hh != lparms.fprs[3])
345 abort ();
349 main ()
351 char *s = "ii";
353 fcld (s, 1, 1.0);
354 fcldi (s, 1, 1.0, -2);
355 fcldu (s, 1, 1.0, 2);
356 fceld (s, 1, 1.0);
357 fciiedl (s, 1, 2, 1.0, 3);
358 fididisdsid (1, 1.0, 2, 2.0, -1, (sparm)
360 3, 3.0}, 4.0, (sparm)
362 5, 5.0}, 6, 7.0);
363 return 0;