Merge to HEAD at tree-cleanup-merge-20041024 .
[official-gcc.git] / gcc / testsuite / gcc.dg / ppc64-abi-1.c
blobfa196595f382fd3324cb4a8c9db9b8fe24905159
1 /* { dg-do run { target powerpc64-*-* } } */
2 /* { dg-options "-O2" } */
3 #include <stdarg.h>
4 #include <signal.h>
5 #include <stdio.h>
7 /* Testcase to check for ABI compliance of parameter passing
8 for the PowerPC64 ABI.
9 Parameter passing of integral and floating point is tested. */
11 extern void abort (void);
13 typedef struct
15 unsigned long gprs[8];
16 double fprs[13];
17 } reg_parms_t;
19 reg_parms_t gparms;
22 /* Testcase could break on future gcc's, if parameter regs
23 are changed before this asm. */
25 #ifndef __MACH__
26 #define save_parms(lparms) \
27 asm volatile ("ld 11,gparms@got(2)\n\t" \
28 "std 3,0(11)\n\t" \
29 "std 4,8(11)\n\t" \
30 "std 5,16(11)\n\t" \
31 "std 6,24(11)\n\t" \
32 "std 7,32(11)\n\t" \
33 "std 8,40(11)\n\t" \
34 "std 9,48(11)\n\t" \
35 "std 10,56(11)\n\t" \
36 "stfd 1,64(11)\n\t" \
37 "stfd 2,72(11)\n\t" \
38 "stfd 3,80(11)\n\t" \
39 "stfd 4,88(11)\n\t" \
40 "stfd 5,96(11)\n\t" \
41 "stfd 6,104(11)\n\t" \
42 "stfd 7,112(11)\n\t" \
43 "stfd 8,120(11)\n\t" \
44 "stfd 9,128(11)\n\t" \
45 "stfd 10,136(11)\n\t" \
46 "stfd 11,144(11)\n\t" \
47 "stfd 12,152(11)\n\t" \
48 "stfd 13,160(11)\n\t":::"11", "memory"); \
49 lparms = gparms;
50 #else
51 #define save_parms(lparms) \
52 asm volatile ("ld r11,gparms@got(r2)\n\t" \
53 "std r3,0(r11)\n\t" \
54 "std r4,8(r11)\n\t" \
55 "std r5,16(r11)\n\t" \
56 "std r6,24(r11)\n\t" \
57 "std r7,32(r11)\n\t" \
58 "std r8,40(r11)\n\t" \
59 "std r9,48(r11)\n\t" \
60 "std r10,56(r11)\n\t" \
61 "stfd f1,64(r11)\n\t" \
62 "stfd f2,72(r11)\n\t" \
63 "stfd f3,80(r11)\n\t" \
64 "stfd f4,88(r11)\n\t" \
65 "stfd f5,96(r11)\n\t" \
66 "stfd f6,104(r11)\n\t" \
67 "stfd f7,112(r11)\n\t" \
68 "stfd f8,120(r11)\n\t" \
69 "stfd f9,128(r11)\n\t" \
70 "stfd f10,136(r11)\n\t" \
71 "stfd f11,144(r11)\n\t" \
72 "stfd f12,152(r11)\n\t" \
73 "stfd f13,160(r11)\n\t":::"r11", "memory"); \
74 lparms = gparms;
75 #endif
77 /* Stackframe structure relevant for parameter passing. */
78 typedef union
80 double d;
81 unsigned long l;
82 unsigned int i[2];
83 } parm_t;
85 typedef struct sf
87 struct sf *backchain;
88 long a1;
89 long a2;
90 long a3;
91 long a4;
92 long a5;
93 parm_t slot[100];
94 } stack_frame_t;
97 /* Paramter passing.
98 s : gpr 3
99 l : gpr 4
100 d : fpr 1
102 void __attribute__ ((noinline)) fcld (char *s, long l, double d)
104 reg_parms_t lparms;
105 save_parms (lparms);
107 if (s != (char *) lparms.gprs[0])
108 abort ();
110 if (l != lparms.gprs[1])
111 abort ();
113 if (d != lparms.fprs[0])
114 abort ();
117 /* Paramter passing.
118 s : gpr 3
119 l : gpr 4
120 d : fpr 2
121 i : gpr 5
123 void __attribute__ ((noinline))
124 fcldi (char *s, long l, double d, signed int i)
126 reg_parms_t lparms;
127 save_parms (lparms);
129 if (s != (char *) lparms.gprs[0])
130 abort ();
132 if (l != lparms.gprs[1])
133 abort ();
135 if (d != lparms.fprs[0])
136 abort ();
138 if ((signed long) i != lparms.gprs[3])
139 abort ();
142 /* Paramter passing.
143 s : gpr 3
144 l : gpr 4
145 d : fpr 2
146 i : gpr 5
148 void __attribute__ ((noinline))
149 fcldu (char *s, long l, float d, unsigned int i)
151 reg_parms_t lparms;
152 save_parms (lparms);
154 if (s != (char *) lparms.gprs[0])
155 abort ();
157 if (l != lparms.gprs[1])
158 abort ();
160 if ((double) d != lparms.fprs[0])
161 abort ();
163 if ((unsigned long) i != lparms.gprs[3])
164 abort ();
167 /* Paramter passing.
168 s : gpr 3
169 l : slot 1
170 d : slot 2
173 void __attribute__ ((noinline)) fceld (char *s, ...)
175 stack_frame_t *sp;
176 reg_parms_t lparms;
177 va_list arg;
178 double d;
179 long l;
180 save_parms (lparms);
182 va_start (arg, s);
184 if (s != (char *) lparms.gprs[0])
185 abort ();
187 l = va_arg (arg, long);
188 d = va_arg (arg, double);
190 /* Go back one frame. */
191 sp = __builtin_frame_address (0);
192 sp = sp->backchain;
194 if (sp->slot[1].l != l)
195 abort ();
197 if (sp->slot[2].d != d)
198 abort ();
201 /* Paramter passing.
202 s : gpr 3
203 i : gpr 4
204 j : gpr 5
205 d : slot 3
206 l : slot 4
208 void __attribute__ ((noinline)) fciiedl (char *s, int i, int j, ...)
210 stack_frame_t *sp;
211 reg_parms_t lparms;
212 va_list arg;
213 double d;
214 long l;
215 save_parms (lparms);
217 va_start (arg, j);
219 if (s != (char *) lparms.gprs[0])
220 abort ();
222 if ((long) i != lparms.gprs[1])
223 abort ();
225 if ((long) j != lparms.gprs[2])
226 abort ();
228 d = va_arg (arg, double);
229 l = va_arg (arg, long);
231 sp = __builtin_frame_address (0);
232 sp = sp->backchain;
234 if (sp->slot[3].d != d)
235 abort ();
237 if (sp->slot[4].l != l)
238 abort ();
242 Parameter Register Offset in parameter save area
243 c r3 0-7 (not stored in parameter save area)
244 ff f1 8-15 (not stored)
245 d r5 16-23 (not stored)
246 ld f2 24-31 (not stored)
247 f r7 32-39 (not stored)
248 s r8,r9 40-55 (not stored)
249 gg f3 56-63 (not stored)
250 t (none) 64-79 (stored in parameter save area)
251 e (none) 80-87 (stored)
252 hh f4 88-95 (stored)
256 typedef struct
258 int a;
259 double dd;
260 } sparm;
262 typedef union
264 int i[2];
265 long l;
266 double d;
267 } double_t;
269 /* Example from ABI documentation with slight changes.
270 Paramter passing.
271 c : gpr 3
272 ff : fpr 1
273 d : gpr 5
274 ld : fpr 2
275 f : gpr 7
276 s : gpr 8 - 9
277 gg : fpr 3
278 t : save area offset 64 - 79
279 e : save area offset 80 - 88
280 hh : fpr 4
283 void __attribute__ ((noinline))
284 fididisdsid (int c, double ff, int d, double ld, int f,
285 sparm s, double gg, sparm t, int e, double hh)
287 stack_frame_t *sp;
288 reg_parms_t lparms;
289 double_t dx, dy;
291 save_parms (lparms);
293 /* Parm 0: int. */
294 if ((long) c != lparms.gprs[0])
295 abort ();
297 /* Parm 1: double. */
298 if (ff != lparms.fprs[0])
299 abort ();
301 /* Parm 2: int. */
302 if ((long) d != lparms.gprs[2])
303 abort ();
305 /* Parm 3: double. */
306 if (ld != lparms.fprs[1])
307 abort ();
309 /* Parm 4: int. */
310 if ((long) f != lparms.gprs[4])
311 abort ();
313 /* Parm 5: struct sparm. */
314 dx.l = lparms.gprs[5];
315 dy.l = lparms.gprs[6];
317 if (s.a != dx.i[0])
318 abort ();
319 if (s.dd != dy.d)
320 abort ();
322 /* Parm 6: double. */
323 if (gg != lparms.fprs[2])
324 abort ();
326 sp = __builtin_frame_address (0);
327 sp = sp->backchain;
329 /* Parm 7: struct sparm. */
330 dx.l = sp->slot[8].l;
331 dy.l = sp->slot[9].l;
332 if (t.a != dx.i[0])
333 abort ();
334 if (t.dd != dy.d)
335 abort ();
337 /* Parm 8: int. */
338 if (e != sp->slot[10].l)
339 abort ();
341 /* Parm 9: double. */
343 if (hh != lparms.fprs[3])
344 abort ();
348 main ()
350 char *s = "ii";
352 fcld (s, 1, 1.0);
353 fcldi (s, 1, 1.0, -2);
354 fcldu (s, 1, 1.0, 2);
355 fceld (s, 1, 1.0);
356 fciiedl (s, 1, 2, 1.0, 3);
357 fididisdsid (1, 1.0, 2, 2.0, -1, (sparm)
359 3, 3.0}, 4.0, (sparm)
361 5, 5.0}, 6, 7.0);
362 return 0;