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