1/* Check calling convention in the vector ABI regarding vector like structs.  */
2
3/* { dg-do compile { target { s390*-*-* } } } */
4/* { dg-options "-O3 -mzarch -march=z13" } */
5
6/* addA */
7/* { dg-final { scan-assembler-times "vfadb\t%v24,%v24,%v26" 1 } } */
8
9/* addB and addE*/
10/* { dg-final { scan-assembler-times "vah\t%v24,%v\[0-9\]*,%v\[0-9\]*" 2 } } */
11
12/* addC */
13/* { dg-final { scan-assembler-times "vag\t%v24,%v\[0-9\]*,%v\[0-9\]*" 1 } } */
14
15/* addB and addC are expected to read the arguments via pointers in r2 and r3 */
16/* { dg-final { scan-assembler-times "vl\t%v\[0-9\]*,0\\(%r2\\)" 2 } } */
17/* { dg-final { scan-assembler-times "vl\t%v\[0-9\]*,0\\(%r3\\)" 2 } } */
18
19/* addD */
20/* { dg-final { scan-assembler-times "vaf\t%v24,%v24,%v26" 1 } } */
21
22/* addE */
23/* { dg-final { scan-assembler-times "vah\t%v24,%v24,%v26" 1 } } */
24
25/* addF */
26/* { dg-final { scan-assembler-times "vab\t%v24,%v\[0-9\]*,%v\[0-9\]*" 1 } } */
27/* { dg-final { scan-assembler-times "srlg\t%r\[0-9\]*,%r2,32" 1 { target lp64 } } } */
28/* { dg-final { scan-assembler-times "srlg\t%r\[0-9\]*,%r3,32" 1 { target lp64 } } } */
29/* { dg-final { scan-assembler-times "llgfr\t%.*,%r2" 1 { target { ! lp64 } } } } */
30/* { dg-final { scan-assembler-times "llgfr\t%.*,%r4" 1 { target { ! lp64 } } } } */
31
32
33typedef double v2df __attribute__((vector_size(16)));
34typedef long long v2di __attribute__((vector_size(16)));
35typedef int v4si __attribute__((vector_size(16)));
36typedef short v8hi __attribute__((vector_size(16)));
37
38typedef short v2hi __attribute__((vector_size(4)));
39typedef char v4qi __attribute__((vector_size(4)));
40
41/* Vector like structs are passed in VRs.  */
42struct A { v2df a; };
43
44v2df
45addA (struct A a, struct A b)
46{
47  return a.a + b.a;
48}
49
50/* Only single element vectors qualify as vector type parms.  This one
51   is passed as a struct. Since it is bigger than 8 bytes it is passed
52   on the stack with the reference being put into r2/r3.  */
53struct B { v8hi a; char b;};
54
55v8hi
56addB (struct B a, struct B b)
57{
58  return a.a + b.a;
59}
60
61/* The resulting struct is bigger than 16 bytes and therefore passed
62   on the stack with the references residing in r2/r3.  */
63struct C { v2di __attribute__((aligned(32))) a; };
64
65v2di
66addC (struct C a, struct C b)
67{
68  return a.a + b.a;
69}
70
71/* The attribute here does not have any effect. So this struct stays
72   vector like and hence is passed in a VR.  */
73struct D { v4si __attribute__((aligned(16))) a; };
74
75v4si
76addD (struct D a, struct D b)
77{
78  return a.a + b.a;
79}
80
81
82/* Smaller vectors are passed in vector registers. This also applies
83   for vector like structs.  */
84struct E { v2hi a; };
85
86v2hi
87addE (struct E a, struct E b)
88{
89  return a.a + b.a;
90}
91
92/* This struct is not passed in VRs because of padding.  But since it
93   fits in a GPR and has a power of two size. It is passed in
94   GPRs.  */
95struct F { v4qi __attribute__((aligned(8))) a; };
96
97v4qi
98addF (struct F a, struct F b)
99{
100  return a.a + b.a;
101}
102