1 /* Darwin 64-bit ABI testing */
2 /* { dg-do run { target { powerpc*-*-darwin* && lp64 } } } */
3 /* { dg-options "-std=c99 -maltivec" } */
5 /* Set this if 8-byte structs are being passed as integers. */
6 /* #define STRUCT8INT */
13 extern void abort (void);
15 struct s3c
{ char ch
[3]; };
16 struct ssc
{ short sh
; char ch
; };
17 struct sif
{ int i
; float f
; };
18 struct sfi
{ float f
; int i
; };
19 struct sfii
{ float f
; int i
; int j
; };
20 struct sfil
{ float f
; int i
; long l
; };
21 struct sfif
{ float f
; int i
; float g
; };
22 struct sfill
{ float f
; int i
; long l
, m
; };
23 struct sfl
{ float f
; long l
; };
24 struct sfldl
{ float f
; long l1
; double d
; long l2
; };
25 struct sfpp
{ float f
; char *p1
; char *p2
; };
28 struct sff
{ float f1
, f2
; };
29 struct sfff
{ float f1
, f2
, f3
; };
30 struct sffff
{ float f1
, f2
, f3
, f4
; };
32 struct sfD
{ float f
; long double D
; };
34 struct sidi
{ int i1
; double d
; int i2
; };
36 struct sdd
{ double d1
, d2
; };
37 struct sddd
{ double d1
, d2
, d3
; };
38 struct sdddd
{ double d1
, d2
, d3
, d4
; };
39 struct s3d
{ double d
[3]; };
41 struct vr
{ union { int ielts
[4]; float felts
[4]; } elts
; };
45 unsigned long gprs
[32];
48 unsigned char stack
[1000];
53 #define TESTFN(RET,NAME,PARAMS) \
55 RET dummy_ ## NAME PARAMS \
57 __asm__("b end_" #NAME "\n_" # NAME ":\n\t" SAVE_STATE "b _dummy_" # NAME "\n\tend_" #NAME ":\n\n" ); \
97 #define SAVE_GPR(N) "std r" #N "," #N "*8(r25)\n\t"
98 #define SAVE_FPR(N) "stfd f" #N "," #N "*8+256(r25)\n\t"
99 #define SAVE_VR(N) "li r26," #N "*16+512\n\tstvx v" #N ",r25,r26\n\t"
100 #define SAVE_STACK(N) "ld r26," #N "(r1)\n\tstd r26," #N "+1024(r25)\n\t"
102 #define SAVE_GPR(N) "stw r" #N "," #N "*4(r25)\n\t"
103 #define SAVE_FPR(N) "stfd f" #N "," #N "*8+128(r25)\n\t"
105 #define SAVE_STACK(N)
108 TESTFN(void, fffi
, (float x
, float y
, int z
))
121 "fsub f0,f0,f0\n\t" \
122 "fsub f1,f1,f1\n\t" \
123 "fsub f2,f2,f2\n\t" \
124 "fsub f3,f3,f3\n\t" \
125 "fsub f4,f4,f4\n\t" \
126 "fsub f5,f5,f5\n\t" \
127 "fsub f6,f6,f6\n\t" \
128 "fsub f7,f7,f7\n\t" \
129 "vsubuwm v0,v0,v0\n\t" \
130 "vsubuwm v1,v1,v1\n\t" \
131 "vsubuwm v2,v2,v2\n\t" \
132 "vsubuwm v3,v3,v3\n\t" \
133 "vsubuwm v4,v4,v4\n\t" \
134 : : : "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \
135 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
136 "v0", "v1", "v2", "v3", "v4" );
138 TESTFN(void, fii
, (int a
, int b
))
139 TESTFN(void, fid
, (int i
, double d
))
140 TESTFN(void, fc
, (complex float z
))
141 TESTFN(void, fffff
, (float f1
, float f2
, float f3
, float f4
))
142 TESTFN(void, fdddd
, (double d1
, double d2
, double d3
, double d4
))
143 TESTFN(void, f_s3c_ssc
, (struct s3c s1
, struct ssc s2
))
144 TESTFN(void, f_sff
, (struct sff s
))
145 TESTFN(void, f_sfff
, (struct sfff s
))
146 TESTFN(void, f_sffff
, (struct sffff s
))
147 TESTFN(void, f_sdd
, (struct sdd s
))
148 TESTFN(void, f_sddd
, (struct sddd s
))
149 TESTFN(void, f_sdddd
, (struct sdddd s
))
150 TESTFN(void, f_s3d
, (struct s3d s
))
151 TESTFN(void, f_sif
, (int i
, struct sif s
))
152 TESTFN(void, fi_sif
, (int i
, struct sif s
))
153 TESTFN(void, fi_sif_i
, (int i
, struct sif s
, int j
))
154 TESTFN(void, f_sfi
, (int i
, struct sfi s
))
155 TESTFN(void, fi_sfi
, (int i
, struct sfi s
))
156 TESTFN(void, fi_sfi_if
, (int i
, struct sfi s
, int j
, float f
))
157 TESTFN(void, fi_sfill
, (int i
, struct sfill s
))
158 TESTFN(void, fi_sfill_i
, (int i
, struct sfill s
, int j
))
159 TESTFN(void, f_sfl
, (struct sfl s
))
160 TESTFN(void, f_sfl_sfl_sfl_sfl_sfl
, (struct sfl s1
, struct sfl s2
, struct sfl s3
, struct sfl s4
, struct sfl s5
))
161 TESTFN(void, fi_sff
, (int i
, struct sff s
))
162 TESTFN(void, f_sfpp_p
, (struct sfpp s
, char *p
))
163 TESTFN(void, f_sfldl
, (struct sfldl s
))
164 TESTFN(void, fi_sff_i
, (int i
, struct sff s
, int j
))
165 TESTFN(void, f_sfD_sfD_sfD_sfD_sfD
, (struct sfD s1
, struct sfD s2
, struct sfD s3
, struct sfD s4
, struct sfD s5
))
166 TESTFN(void, fi_sidi
, (int i
, struct sidi s
))
167 TESTFN(void, fifvf_sfi_dots
, (int i
, float f
, vector
float vf
, struct sfi s
, ...))
168 TESTFN(void, fifvf_sfii_dots
, (int i
, float f
, vector
float vf
, struct sfii s
, ...))
173 static __attribute__ ((noinline
)) void
174 check_gpr (int line
, int reg
, long expected
)
176 if (gparms
.gprs
[reg
] != expected
)
178 printf("%d: r%d is 0x%lx, expected 0x%lx\n",
179 line
, reg
, gparms
.gprs
[reg
], expected
);
184 static __attribute__ ((noinline
)) void
185 check_gpr_double (int line
, int reg
, double expected
)
187 double tmp
= *((double *) &(gparms
.gprs
[reg
]));
190 printf("%d: r%d is %f (0x%llx), expected %f (0x%llx)\n",
192 tmp
, *((long long *) &tmp
),
193 expected
, *((long long *) &expected
));
198 static __attribute__ ((noinline
)) void
199 check_gpr_float_pair (int line
, int reg
, float exp1
, float exp2
)
201 float tmp1
= *((float *) &(gparms
.gprs
[reg
]));
202 float tmp2
= *(((float *) &(gparms
.gprs
[reg
])) + 1);
204 if (tmp1
!= exp1
|| tmp2
!= exp2
)
206 printf("%d: r%d is %f / %f (0x%llx), expected %f (0x%x) / %f (0x%x)\n",
208 tmp1
, tmp2
, *((long long *) &(gparms
.gprs
[reg
])),
209 exp1
, *((int *) &exp1
),
210 exp2
, *((int *) &exp2
));
215 static __attribute__ ((noinline
)) void
216 check_fpr (int line
, int reg
, double expected
)
218 if (gparms
.fprs
[reg
] != expected
)
220 printf("%d: f%d is %f (0x%llx), expected %f (0x%llx)\n",
222 gparms
.fprs
[reg
], *((long long *) &(gparms
.fprs
[reg
])),
223 expected
, *((long long *) &expected
));
228 static __attribute__ ((noinline
)) void
229 check_vr_int (int reg
, int n1
, int n2
, int n3
, int n4
)
231 if (gparms
.vrs
[reg
].elts
.ielts
[0] != n1
232 || gparms
.vrs
[reg
].elts
.ielts
[1] != n2
233 || gparms
.vrs
[reg
].elts
.ielts
[2] != n3
234 || gparms
.vrs
[reg
].elts
.ielts
[3] != n4
)
236 printf("v%d is (%d,%d,%d,%d) (0x%x,0x%x,0x%x,0x%x),\n"
237 " expected (%d,%d,%d,%d) (0x%x,0x%x,0x%x,0x%x)\n",
239 gparms
.vrs
[reg
].elts
.ielts
[0],
240 gparms
.vrs
[reg
].elts
.ielts
[1],
241 gparms
.vrs
[reg
].elts
.ielts
[2],
242 gparms
.vrs
[reg
].elts
.ielts
[3],
243 gparms
.vrs
[reg
].elts
.ielts
[0],
244 gparms
.vrs
[reg
].elts
.ielts
[1],
245 gparms
.vrs
[reg
].elts
.ielts
[2],
246 gparms
.vrs
[reg
].elts
.ielts
[3],
254 static __attribute__ ((noinline
)) void
255 check_vr_float (int reg
, float f1
, float f2
, float f3
, float f4
)
257 if (gparms
.vrs
[reg
].elts
.felts
[0] != f1
258 || gparms
.vrs
[reg
].elts
.felts
[1] != f2
259 || gparms
.vrs
[reg
].elts
.felts
[2] != f3
260 || gparms
.vrs
[reg
].elts
.felts
[3] != f4
)
262 printf("v%d is (%f,%f,%f,%f) (0x%x,0x%x,0x%x,0x%x),\n"
263 " expected (%f,%f,%f,%f) (0x%x,0x%x,0x%x,0x%x)\n",
265 gparms
.vrs
[reg
].elts
.felts
[0],
266 gparms
.vrs
[reg
].elts
.felts
[1],
267 gparms
.vrs
[reg
].elts
.felts
[2],
268 gparms
.vrs
[reg
].elts
.felts
[3],
269 gparms
.vrs
[reg
].elts
.ielts
[0],
270 gparms
.vrs
[reg
].elts
.ielts
[1],
271 gparms
.vrs
[reg
].elts
.ielts
[2],
272 gparms
.vrs
[reg
].elts
.ielts
[3],
274 *((int *) &f1
), *((int *) &f2
), *((int *) &f3
), *((int *) &f4
)
283 complex float cpx
= 4.45f
+ I
* 4.92f
;
287 struct sfi sfi_loc2
= { 6.3f
, 0x1108 };
288 struct sfii sfii_loc
;
289 struct sfii sfii_loc2
= { 6.9f
, 0x1110, 0x6372 };
290 vector
float vf_loc
= (vector
float) { 7.1f
, 7.2f
, 7.3f
, 7.4f
};
291 vector
int vi_loc
= (vector
int) { 0xabc, 0xdef, 0xfed, 0xcba };
293 __asm__ ("mr r25,%0" : : "b" (&gparms
) );
297 check_gpr (__LINE__
, 3, 1);
298 check_gpr (__LINE__
, 4, 2);
302 check_gpr (__LINE__
, 3, 45);
303 check_fpr (__LINE__
, 1, 4.5);
306 fffi(1.2f
, 3.4f
, 456);
307 check_fpr(__LINE__
, 1, 1.2f
);
311 /* Two floats are packed into r3 */
312 check_gpr_float_pair (__LINE__
, 3, 4.45f
, 4.92f
);
315 fffff (4.1f
, 4.2f
, 4.3f
, 4.4f
);
316 check_fpr (__LINE__
, 1, 4.1f
);
317 check_fpr (__LINE__
, 4, 4.4f
);
320 fdddd (4.1, 4.2, 4.3, 4.4);
321 check_fpr (__LINE__
, 1, 4.1);
322 check_fpr (__LINE__
, 4, 4.4);
325 struct sff sff_loc
= { 2.1f
, 2.2f
};
329 check_gpr_float_pair (__LINE__
, 3, 2.1f
, 2.2f
);
331 check_fpr(__LINE__
, 1, 2.1f
);
332 check_fpr(__LINE__
, 2, 2.2f
);
335 fi_sff_i(65, sff_loc
, 66);
336 check_gpr(__LINE__
, 3, 65);
338 check_gpr_float_pair (__LINE__
, 4, 2.1f
, 2.2f
);
340 check_fpr(__LINE__
, 1, 2.1f
);
341 check_fpr(__LINE__
, 2, 2.2f
);
343 check_gpr(__LINE__
, 5, 66);
347 struct sfff sfff_loc
= { 3.1f
, 3.2f
, 3.3f
};
350 check_fpr(__LINE__
, 1, 3.1f
);
351 check_fpr(__LINE__
, 2, 3.2f
);
352 check_fpr(__LINE__
, 3, 3.3f
);
355 check_fpr(__LINE__
, 1, 3.1f
);
356 check_fpr(__LINE__
, 2, 3.2f
);
357 check_fpr(__LINE__
, 3, 3.3f
);
361 struct sffff sffff_loc
= { 4.1f
, 4.2f
, 4.3f
, 4.4f
};
364 check_gpr_float_pair(__LINE__
, 3, 4.1f
, 4.2f
);
365 check_gpr_float_pair(__LINE__
, 4, 4.3f
, 4.4f
);
369 struct sdd sdd_loc
= { 2.1, 2.2 };
372 /* 16-byte struct is passed in two GPRs. */
373 check_gpr_double(__LINE__
, 3, 2.1);
374 check_gpr_double(__LINE__
, 4, 2.2);
378 struct sddd sddd_loc
= { 3.1, 3.2, 3.3 };
381 check_fpr(__LINE__
, 1, 3.1);
382 check_fpr(__LINE__
, 2, 3.2);
383 check_fpr(__LINE__
, 3, 3.3);
387 struct sdddd sdddd_loc
= { 4.1, 4.2, 4.3, 4.4 };
390 check_fpr(__LINE__
, 1, 4.1);
391 check_fpr(__LINE__
, 2, 4.2);
392 check_fpr(__LINE__
, 3, 4.3);
393 check_fpr(__LINE__
, 4, 4.4);
397 struct s3d s3d_loc
= { 89.92, 4.89, 90.9 };
400 check_gpr_double (__LINE__
, 3, 89.92);
401 check_gpr_double (__LINE__
, 4, 4.89);
402 check_gpr_double (__LINE__
, 5, 90.9);
412 f_s3c_ssc(s3c_loc
, ssc_loc
);
416 struct sif sif_loc_n
= { 334, 4.3f
};
418 floatcast
= *((int *) &(sif_loc_n
.f
));
420 fi_sif(29, sif_loc_n
);
421 check_gpr (__LINE__
, 3, 29);
422 check_gpr (__LINE__
, 4, 334LL << 32 | floatcast
);
425 check_fpr (__LINE__
, 1, 4.3f
);
428 fi_sif_i(31, sif_loc_n
, 33);
429 check_gpr (__LINE__
, 3, 31);
430 check_gpr (__LINE__
, 4, 334LL << 32 | floatcast
);
433 check_fpr (__LINE__
, 1, 4.3f
);
435 check_gpr (__LINE__
, 5, 33);
439 struct sfi sfi_loc_n
= { 4.145f
, 335 };
441 fi_sfi(29, sfi_loc_n
);
442 check_gpr (__LINE__
, 3, 29);
444 check_gpr (__LINE__
, 4, 0x4084a3d70000014fLL
);
446 check_fpr (__LINE__
, 1, 4.145f
);
447 check_gpr (__LINE__
, 4, 335);
452 struct sfi sfi_loc_n
= { 4.145f
, 335 };
454 fi_sfi_if (29, sfi_loc_n
, 65, 9.8f
);
455 check_gpr (__LINE__
, 3, 29);
457 check_gpr (__LINE__
, 4, 0x4084a3d70000014fLL
);
459 check_fpr (__LINE__
, 1, 4.145f
);
460 check_gpr (__LINE__
, 4, 335);
462 check_gpr (__LINE__
, 5, 65);
463 check_gpr (__LINE__
, 6, 0x666);
465 check_fpr (__LINE__
, 1, 9.8f
);
467 check_fpr (__LINE__
, 2, 9.8f
);
469 check_gpr (__LINE__
, 7, 0x777);
473 struct sfill sfill_loc_n
= { 4.145f
, 335, 10000000000LL, 20000000000LL };
475 fi_sfill(29, sfill_loc_n
);
476 check_gpr (__LINE__
, 3, 29);
477 check_fpr (__LINE__
, 1, 4.145f
);
478 check_gpr (__LINE__
, 4, 335);
479 check_gpr (__LINE__
, 5, 10000000000LL);
480 check_gpr (__LINE__
, 6, 20000000000LL);
484 struct sfl sfl_loc_n
= { 4.145f
, 335 };
487 check_gpr_float_pair (__LINE__
, 3, 4.145f
, 0.0f
);
488 check_gpr (__LINE__
, 4, 335);
489 check_gpr (__LINE__
, 5, 0x555);
491 f_sfl_sfl_sfl_sfl_sfl (sfl_loc_n
, sfl_loc_n
, sfl_loc_n
, sfl_loc_n
, sfl_loc_n
);
492 check_gpr_float_pair (__LINE__
, 3, 4.145f
, 0.0f
);
493 check_gpr (__LINE__
, 4, 335);
494 check_gpr (__LINE__
, 6, 335);
495 check_gpr (__LINE__
, 8, 335);
496 check_gpr (__LINE__
, 10, 335);
500 struct sfldl sfldl_loc_n
= { 4.145f
, 335, 3.3, 336 };
502 f_sfldl (sfldl_loc_n
);
503 check_fpr (__LINE__
, 1, 4.145f
);
504 check_gpr (__LINE__
, 4, 335);
505 check_fpr (__LINE__
, 2, 3.3);
506 check_gpr (__LINE__
, 6, 336);
513 struct sfpp sfpp_loc_n
= { 4.145f
, p1
, p2
};
515 f_sfpp_p(sfpp_loc_n
, p3
);
516 check_fpr (__LINE__
, 1, 4.145f
);
517 check_gpr (__LINE__
, 4, (long) p1
);
518 check_gpr (__LINE__
, 5, (long) p2
);
519 check_gpr (__LINE__
, 6, (long) p3
);
523 struct sff sff_loc_n
= { 4.145f
, 335.3f
};
525 fi_sff(29, sff_loc_n
);
526 check_gpr (__LINE__
, 3, 29);
528 check_gpr_float_pair (__LINE__
, 4, 4.145f
, 335.3f
);
530 check_fpr (__LINE__
, 1, 4.145f
);
531 check_fpr (__LINE__
, 2, 335.3f
);
536 struct sfD sfD_loc_n
= { 4.145f
, 335.335 };
538 f_sfD_sfD_sfD_sfD_sfD (sfD_loc_n
, sfD_loc_n
, sfD_loc_n
, sfD_loc_n
, sfD_loc_n
);
539 check_fpr (__LINE__
, 1, 4.145f
);
540 check_fpr (__LINE__
, 2, 335.335);
541 check_fpr (__LINE__
, 4, 4.145f
);
542 check_fpr (__LINE__
, 5, 335.335);
543 check_fpr (__LINE__
, 7, 4.145f
);
544 check_fpr (__LINE__
, 10, 4.145f
);
545 check_fpr (__LINE__
, 13, 4.145f
);
549 struct sidi sidi_loc_n
= { 257, 4.14515, 258 };
551 fi_sidi(16, sidi_loc_n
);
552 check_gpr (__LINE__
, 3, 16);
553 check_fpr (__LINE__
, 1, 4.14515);
554 check_gpr (__LINE__
, 4, 257LL << 32);
555 check_gpr (__LINE__
, 5, 0x555);
556 check_gpr (__LINE__
, 6, 258LL << 32);
562 fifvf_sfi_dots(41, 4.3f
, vf_loc
, sfi_loc
, 4.63f
, vi_loc
, sfi_loc2
);
564 check_gpr (__LINE__
, 3, 41);
565 check_fpr (__LINE__
, 1, 4.3f
); /* float skips r4 */
566 check_vr_float(2, 7.1f
, 7.2f
, 7.3f
, 7.4f
); /* vector skips r5/r6 */
568 check_gpr (__LINE__
, 7, 0x40a6666600000062);
570 check_fpr (__LINE__
, 2, sfi_loc
.f
);
571 check_gpr (__LINE__
, 7, sfi_loc
.i
);
573 /* start of varying parameters */
575 check_fpr (__LINE__
, 2, 4.63f
);
577 check_fpr (__LINE__
, 3, 4.63f
);
579 check_gpr_double (__LINE__
, 8, 4.63f
);
580 /* vector takes up r9/r10 */
581 /* sfi_loc2 on stack */
588 fifvf_sfii_dots(41, 4.3f
, vf_loc
, sfii_loc
, 4.63f
, vi_loc
, sfii_loc2
);
590 check_gpr (__LINE__
, 3, 41);
591 check_fpr (__LINE__
, 1, 4.3f
); /* float skips r4 */
592 check_vr_float(2, 7.1f
, 7.2f
, 7.3f
, 7.4f
); /* vector skips r5/r6 */
593 check_fpr (__LINE__
, 2, sfii_loc
.f
);
594 check_gpr (__LINE__
, 7, sfii_loc
.i
);
595 check_gpr (__LINE__
, 8, ((long)sfii_loc
.j
) << 32);
596 /* start of varying parameters */
597 check_fpr (__LINE__
, 3, 4.63f
);
598 check_gpr_double (__LINE__
, 9, 4.63f
);
599 /* vector takes up r10/stack (?) */
600 /* sfii_loc2 on stack */
612 for (i
= 3; i
<= 10; ++i
)
614 printf("r%d=0x%16.16lx ", i
, gparms
.gprs
[i
]);
616 printf("r%d=0x%8.8x ", i
, gparms
.gprs
[i
]);
619 for (i
= 1; i
<= 13; ++i
)
620 printf("f%d=%8.8f ", i
, gparms
.fprs
[i
]);
622 for (i
= 0; i
<= 4; ++i
)
623 printf("v%d=(%x,%x,%x,%x) ", i
,
624 gparms
.vrs
[i
].elts
.ielts
[0], gparms
.vrs
[i
].elts
.ielts
[1],
625 gparms
.vrs
[i
].elts
.ielts
[2], gparms
.vrs
[i
].elts
.ielts
[3]);
627 for (i
= 112; i
< 152; ++i
)
629 if (i
> 112 && i
% 8 == 0)
631 printf("%02x", gparms
.stack
[i
]);