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);
17 unsigned long gprs
[8];
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. */
33 #define save_parms() \
34 asm volatile ("ld 11,gparms@got(2)\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")
57 #define save_parms() \
58 asm volatile ("ld r11,gparms@got(r2)\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")
83 /* Stackframe structure relevant for parameter passing. */
110 void __attribute__ ((noinline
)) fcld (char *s
, long l
, double d
)
115 void __attribute__ ((noinline
)) fcld_check (char *s
, long l
, double d
)
117 if (s
!= (char *) gparms
.gprs
[0])
120 if (l
!= gparms
.gprs
[1])
123 if (d
!= gparms
.fprs
[0])
133 void __attribute__ ((noinline
))
134 fcldi (char *s
, long l
, double d
, signed int i
)
139 void __attribute__ ((noinline
))
140 fcldi_check (char *s
, long l
, double d
, signed int i
)
142 if (s
!= (char *) gparms
.gprs
[0])
145 if (l
!= gparms
.gprs
[1])
148 if (d
!= gparms
.fprs
[0])
151 if ((signed long) i
!= gparms
.gprs
[3])
161 void __attribute__ ((noinline
))
162 fcldu (char *s
, long l
, float d
, unsigned int i
)
167 void __attribute__ ((noinline
))
168 fcldu_check (char *s
, long l
, float d
, unsigned int i
)
170 if (s
!= (char *) gparms
.gprs
[0])
173 if (l
!= gparms
.gprs
[1])
176 if ((double) d
!= gparms
.fprs
[0])
179 if ((unsigned long) i
!= gparms
.gprs
[3])
188 void __attribute__ ((noinline
)) fceld (char *s
, ...)
193 void __attribute__ ((noinline
)) fceld_check (char *s
, ...)
202 if (s
!= (char *) gparms
.gprs
[0])
205 l
= va_arg (arg
, long);
206 d
= va_arg (arg
, double);
208 /* Go back one frame. */
209 sp
= __builtin_frame_address (0);
212 if (sp
->slot
[1].l
!= l
)
215 if (sp
->slot
[2].d
!= d
)
226 void __attribute__ ((noinline
)) fciiedl (char *s
, int i
, int j
, ...)
231 void __attribute__ ((noinline
)) fciiedl_check (char *s
, int i
, int j
, ...)
240 if (s
!= (char *) gparms
.gprs
[0])
243 if ((long) i
!= gparms
.gprs
[1])
246 if ((long) j
!= gparms
.gprs
[2])
249 d
= va_arg (arg
, double);
250 l
= va_arg (arg
, long);
252 sp
= __builtin_frame_address (0);
255 if (sp
->slot
[3].d
!= d
)
258 if (sp
->slot
[4].l
!= l
)
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)
290 /* Example from ABI documentation with slight changes.
299 t : save area offset 64 - 79
300 e : save area offset 80 - 88
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
)
312 fididisdsid_check (int c
, double ff
, int d
, double ld
, int f
,
313 sparm s
, double gg
, sparm t
, int e
, double hh
)
319 if ((long) c
!= gparms
.gprs
[0])
322 /* Parm 1: double. */
323 if (ff
!= gparms
.fprs
[0])
327 if ((long) d
!= gparms
.gprs
[2])
330 /* Parm 3: double. */
331 if (ld
!= gparms
.fprs
[1])
335 if ((long) f
!= gparms
.gprs
[4])
338 /* Parm 5: struct sparm. */
339 dx
.l
= gparms
.gprs
[5];
340 dy
.l
= gparms
.gprs
[6];
347 /* Parm 6: double. */
348 if (gg
!= gparms
.fprs
[2])
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
;
362 if (e
!= sp
->slot
[10].l
)
365 /* Parm 9: double. */
367 if (hh
!= gparms
.fprs
[3])
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},