1/* Check calling convention with variable argument lists in the vector
2   ABI.  */
3
4/* { dg-do run { target { s390*-*-* } } } */
5/* { dg-require-effective-target vector } */
6/* { dg-options "-O3 -mzarch -march=z13 --save-temps" } */
7
8/* Make sure arguments are fetched from the argument overflow area.  */
9/* { dg-final { scan-assembler "vl\t%v\[0-9\]*,352\\(%r15\\)" { target lp64 } } } */
10/* { dg-final { scan-assembler "ld\t%v\[0-9\]*,368\\(%r15\\)" { target lp64 } } } */
11/* { dg-final { scan-assembler "vl\t%v\[0-9\]*,376\\(%r15\\)" { target lp64 } } } */
12/* { dg-final { scan-assembler "ld\t%v\[0-9\]*,392\\(%r15\\)" { target lp64 } } } */
13
14/* { dg-final { scan-assembler "vl\t%v\[0-9\]*,208\\(%r15\\)" { target ilp32 } } } */
15/* { dg-final { scan-assembler "ld\t%v\[0-9\]*,224\\(%r15\\)" { target ilp32 } } } */
16/* { dg-final { scan-assembler "vl\t%v\[0-9\]*,232\\(%r15\\)" { target ilp32 } } } */
17/* { dg-final { scan-assembler "ld\t%v\[0-9\]*,248\\(%r15\\)" { target ilp32 } } } */
18
19/* { dg-final { cleanup-saved-temps } } */
20
21#include <stdarg.h>
22
23extern void abort (void);
24
25typedef long long v2di __attribute__((vector_size(16)));
26typedef int v2si __attribute__((vector_size(8)));
27
28v2di __attribute__((noinline))
29add (int a, ...)
30{
31  int i;
32  va_list va;
33  v2di di_result = { 0, 0 };
34  v2si si_result = (v2si){ 0, 0 };
35
36  va_start (va, a);
37
38  di_result += va_arg (va, v2di);
39  si_result += va_arg (va, v2si);
40  di_result += va_arg (va, v2di);
41  si_result += va_arg (va, v2si);
42
43  va_end (va);
44
45  di_result[0] += si_result[0];
46  di_result[1] += si_result[1];
47
48  return di_result;
49}
50
51int
52main ()
53{
54  v2di r = add (4, (v2di){ 11, 21 }, (v2si){ 12, 22 }, (v2di){ 13, 23 }, (v2si){ 14, 24 });
55
56  if (r[0] != 50 || r[1] != 90)
57    abort ();
58
59  return 0;
60}
61