Use conditional internal functions in if-conversion
[official-gcc.git] / gcc / testsuite / gcc.target / powerpc / ppc64-abi-1.c
blob921c46862e27767e10bd4e53cf82b2a157c92da0
1 /* { dg-do run { target { powerpc*-*-* && lp64 } } } */
2 /* { dg-skip-if "" { *-*-darwin* } } */
3 /* { dg-options "-O2" } */
5 typedef __builtin_va_list va_list;
6 #define va_start(ap, arg) __builtin_va_start (ap, arg)
7 #define va_arg(ap, type) __builtin_va_arg (ap, type)
9 /* Testcase to check for ABI compliance of parameter passing
10 for the PowerPC64 ABI.
11 Parameter passing of integral and floating point is tested. */
13 extern void abort (void);
15 typedef struct
17 unsigned long gprs[8];
18 double fprs[13];
19 } reg_parms_t;
21 volatile reg_parms_t gparms;
24 /* Testcase could break on future gcc's, if parameter regs are changed
25 before this asm. To minimize the risk of that happening the test
26 consists of two sets of functions wih identical signatures:
27 foo, which does nothing except save function argument registers
28 to prevent them from getting clobbered (see PR65109),
29 foo_check, which verifies that the values of function registers
30 saved by foo match those passed to foo_check by the caller. */
32 #ifndef __MACH__
33 #define save_parms() \
34 asm volatile ("ld 11,gparms@got(2)\n\t" \
35 "std 3,0(11)\n\t" \
36 "std 4,8(11)\n\t" \
37 "std 5,16(11)\n\t" \
38 "std 6,24(11)\n\t" \
39 "std 7,32(11)\n\t" \
40 "std 8,40(11)\n\t" \
41 "std 9,48(11)\n\t" \
42 "std 10,56(11)\n\t" \
43 "stfd 1,64(11)\n\t" \
44 "stfd 2,72(11)\n\t" \
45 "stfd 3,80(11)\n\t" \
46 "stfd 4,88(11)\n\t" \
47 "stfd 5,96(11)\n\t" \
48 "stfd 6,104(11)\n\t" \
49 "stfd 7,112(11)\n\t" \
50 "stfd 8,120(11)\n\t" \
51 "stfd 9,128(11)\n\t" \
52 "stfd 10,136(11)\n\t" \
53 "stfd 11,144(11)\n\t" \
54 "stfd 12,152(11)\n\t" \
55 "stfd 13,160(11)\n\t":::"11", "memory")
56 #else
57 #define save_parms() \
58 asm volatile ("ld r11,gparms@got(r2)\n\t" \
59 "std r3,0(r11)\n\t" \
60 "std r4,8(r11)\n\t" \
61 "std r5,16(r11)\n\t" \
62 "std r6,24(r11)\n\t" \
63 "std r7,32(r11)\n\t" \
64 "std r8,40(r11)\n\t" \
65 "std r9,48(r11)\n\t" \
66 "std r10,56(r11)\n\t" \
67 "stfd f1,64(r11)\n\t" \
68 "stfd f2,72(r11)\n\t" \
69 "stfd f3,80(r11)\n\t" \
70 "stfd f4,88(r11)\n\t" \
71 "stfd f5,96(r11)\n\t" \
72 "stfd f6,104(r11)\n\t" \
73 "stfd f7,112(r11)\n\t" \
74 "stfd f8,120(r11)\n\t" \
75 "stfd f9,128(r11)\n\t" \
76 "stfd f10,136(r11)\n\t" \
77 "stfd f11,144(r11)\n\t" \
78 "stfd f12,152(r11)\n\t" \
79 "stfd f13,160(r11)\n\t":::"r11", "memory")
80 #endif
83 /* Stackframe structure relevant for parameter passing. */
84 typedef union
86 double d;
87 unsigned long l;
88 unsigned int i[2];
89 } parm_t;
91 typedef struct sf
93 struct sf *backchain;
94 long a1;
95 long a2;
96 long a3;
97 #if _CALL_ELF != 2
98 long a4;
99 long a5;
100 #endif
101 parm_t slot[100];
102 } stack_frame_t;
105 /* Paramter passing.
106 s : gpr 3
107 l : gpr 4
108 d : fpr 1
110 void __attribute__ ((noinline)) fcld (char *s, long l, double d)
112 save_parms ();
115 void __attribute__ ((noinline)) fcld_check (char *s, long l, double d)
117 if (s != (char *) gparms.gprs[0])
118 abort ();
120 if (l != gparms.gprs[1])
121 abort ();
123 if (d != gparms.fprs[0])
124 abort ();
127 /* Paramter passing.
128 s : gpr 3
129 l : gpr 4
130 d : fpr 2
131 i : gpr 5
133 void __attribute__ ((noinline))
134 fcldi (char *s, long l, double d, signed int i)
136 save_parms ();
139 void __attribute__ ((noinline))
140 fcldi_check (char *s, long l, double d, signed int i)
142 if (s != (char *) gparms.gprs[0])
143 abort ();
145 if (l != gparms.gprs[1])
146 abort ();
148 if (d != gparms.fprs[0])
149 abort ();
151 if ((signed long) i != gparms.gprs[3])
152 abort ();
155 /* Paramter passing.
156 s : gpr 3
157 l : gpr 4
158 d : fpr 2
159 i : gpr 5
161 void __attribute__ ((noinline))
162 fcldu (char *s, long l, float d, unsigned int i)
164 save_parms ();
167 void __attribute__ ((noinline))
168 fcldu_check (char *s, long l, float d, unsigned int i)
170 if (s != (char *) gparms.gprs[0])
171 abort ();
173 if (l != gparms.gprs[1])
174 abort ();
176 if ((double) d != gparms.fprs[0])
177 abort ();
179 if ((unsigned long) i != gparms.gprs[3])
180 abort ();
183 /* Paramter passing.
184 s : gpr 3
185 l : slot 1
186 d : slot 2
188 void __attribute__ ((noinline)) fceld (char *s, ...)
190 save_parms ();
193 void __attribute__ ((noinline)) fceld_check (char *s, ...)
195 stack_frame_t *sp;
196 va_list arg;
197 double d;
198 long l;
200 va_start (arg, s);
202 if (s != (char *) gparms.gprs[0])
203 abort ();
205 l = va_arg (arg, long);
206 d = va_arg (arg, double);
208 /* Go back one frame. */
209 sp = __builtin_frame_address (0);
210 sp = sp->backchain;
212 if (sp->slot[1].l != l)
213 abort ();
215 if (sp->slot[2].d != d)
216 abort ();
219 /* Paramter passing.
220 s : gpr 3
221 i : gpr 4
222 j : gpr 5
223 d : slot 3
224 l : slot 4
226 void __attribute__ ((noinline)) fciiedl (char *s, int i, int j, ...)
228 save_parms ();
231 void __attribute__ ((noinline)) fciiedl_check (char *s, int i, int j, ...)
233 stack_frame_t *sp;
234 va_list arg;
235 double d;
236 long l;
238 va_start (arg, j);
240 if (s != (char *) gparms.gprs[0])
241 abort ();
243 if ((long) i != gparms.gprs[1])
244 abort ();
246 if ((long) j != gparms.gprs[2])
247 abort ();
249 d = va_arg (arg, double);
250 l = va_arg (arg, long);
252 sp = __builtin_frame_address (0);
253 sp = sp->backchain;
255 if (sp->slot[3].d != d)
256 abort ();
258 if (sp->slot[4].l != l)
259 abort ();
263 Parameter Register Offset in parameter save area
264 c r3 0-7 (not stored in parameter save area)
265 ff f1 8-15 (not stored)
266 d r5 16-23 (not stored)
267 ld f2 24-31 (not stored)
268 f r7 32-39 (not stored)
269 s r8,r9 40-55 (not stored)
270 gg f3 56-63 (not stored)
271 t (none) 64-79 (stored in parameter save area)
272 e (none) 80-87 (stored)
273 hh f4 88-95 (stored)
277 typedef struct
279 int a;
280 double dd;
281 } sparm;
283 typedef union
285 int i[2];
286 long l;
287 double d;
288 } double_t;
290 /* Example from ABI documentation with slight changes.
291 Paramter passing.
292 c : gpr 3
293 ff : fpr 1
294 d : gpr 5
295 ld : fpr 2
296 f : gpr 7
297 s : gpr 8 - 9
298 gg : fpr 3
299 t : save area offset 64 - 79
300 e : save area offset 80 - 88
301 hh : fpr 4
304 void __attribute__ ((noinline))
305 fididisdsid (int c, double ff, int d, double ld, int f,
306 sparm s, double gg, sparm t, int e, double hh)
308 save_parms ();
311 void
312 fididisdsid_check (int c, double ff, int d, double ld, int f,
313 sparm s, double gg, sparm t, int e, double hh)
315 stack_frame_t *sp;
316 double_t dx, dy;
318 /* Parm 0: int. */
319 if ((long) c != gparms.gprs[0])
320 abort ();
322 /* Parm 1: double. */
323 if (ff != gparms.fprs[0])
324 abort ();
326 /* Parm 2: int. */
327 if ((long) d != gparms.gprs[2])
328 abort ();
330 /* Parm 3: double. */
331 if (ld != gparms.fprs[1])
332 abort ();
334 /* Parm 4: int. */
335 if ((long) f != gparms.gprs[4])
336 abort ();
338 /* Parm 5: struct sparm. */
339 dx.l = gparms.gprs[5];
340 dy.l = gparms.gprs[6];
342 if (s.a != dx.i[0])
343 abort ();
344 if (s.dd != dy.d)
345 abort ();
347 /* Parm 6: double. */
348 if (gg != gparms.fprs[2])
349 abort ();
351 sp = ((stack_frame_t*)__builtin_frame_address (0))->backchain;
353 /* Parm 7: struct sparm. */
354 dx.l = sp->slot[8].l;
355 dy.l = sp->slot[9].l;
356 if (t.a != dx.i[0])
357 abort ();
358 if (t.dd != dy.d)
359 abort ();
361 /* Parm 8: int. */
362 if (e != sp->slot[10].l)
363 abort ();
365 /* Parm 9: double. */
367 if (hh != gparms.fprs[3])
368 abort ();
372 main ()
374 char *s = "ii";
376 #define ABI_CHECK(func, args) \
377 func args, func ## _check args
379 ABI_CHECK (fcld, (s, 1, 1.0));
380 ABI_CHECK (fcldi, (s, 1, 1.0, -2));
381 ABI_CHECK (fcldu, (s, 1, 1.0, 2));
382 ABI_CHECK (fceld, (s, 1, 1.0));
383 ABI_CHECK (fciiedl, (s, 1, 2, 1.0, 3));
384 ABI_CHECK (fididisdsid, (1, 1.0, 2, 2.0, -1,
385 (sparm){3, 3.0}, 4.0, (sparm){5, 5.0},
386 6, 7.0));
388 return 0;