Viewing file: vec-abi-3.c (2.86 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/* Check calling convention in the vector ABI regarding vector like structs. */
/* { dg-do compile { target { s390*-*-* } } } */ /* { dg-options "-O3 -mzarch -march=z13" } */
/* addA */ /* { dg-final { scan-assembler-times "vfadb\t%v24,%v24,%v26" 1 } } */
/* addB and addE*/ /* { dg-final { scan-assembler-times "vah\t%v24,%v\[0-9\]*,%v\[0-9\]*" 2 } } */
/* addC */ /* { dg-final { scan-assembler-times "vag\t%v24,%v\[0-9\]*,%v\[0-9\]*" 1 } } */
/* addB and addC are expected to read the arguments via pointers in r2 and r3 */ /* { dg-final { scan-assembler-times "vl\t%v\[0-9\]*,0\\(%r2\\)" 2 } } */ /* { dg-final { scan-assembler-times "vl\t%v\[0-9\]*,0\\(%r3\\)" 2 } } */
/* addD */ /* { dg-final { scan-assembler-times "vaf\t%v24,%v24,%v26" 1 } } */
/* addE */ /* { dg-final { scan-assembler-times "vah\t%v24,%v24,%v26" 1 } } */
/* addF */ /* { dg-final { scan-assembler-times "vab\t%v24,%v\[0-9\]*,%v\[0-9\]*" 1 } } */ /* { dg-final { scan-assembler-times "srlg\t%r\[0-9\]*,%r2,32" 1 { target lp64 } } } */ /* { dg-final { scan-assembler-times "srlg\t%r\[0-9\]*,%r3,32" 1 { target lp64 } } } */ /* { dg-final { scan-assembler-times "llgfr\t%.*,%r2" 1 { target { ! lp64 } } } } */ /* { dg-final { scan-assembler-times "llgfr\t%.*,%r4" 1 { target { ! lp64 } } } } */
typedef double v2df __attribute__((vector_size(16))); typedef long long v2di __attribute__((vector_size(16))); typedef int v4si __attribute__((vector_size(16))); typedef short v8hi __attribute__((vector_size(16)));
typedef short v2hi __attribute__((vector_size(4))); typedef char v4qi __attribute__((vector_size(4)));
/* Vector like structs are passed in VRs. */ struct A { v2df a; };
v2df addA (struct A a, struct A b) { return a.a + b.a; }
/* Only single element vectors qualify as vector type parms. This one is passed as a struct. Since it is bigger than 8 bytes it is passed on the stack with the reference being put into r2/r3. */ struct B { v8hi a; char b;};
v8hi addB (struct B a, struct B b) { return a.a + b.a; }
/* The resulting struct is bigger than 16 bytes and therefore passed on the stack with the references residing in r2/r3. */ struct C { v2di __attribute__((aligned(32))) a; };
v2di addC (struct C a, struct C b) { return a.a + b.a; }
/* The attribute here does not have any effect. So this struct stays vector like and hence is passed in a VR. */ struct D { v4si __attribute__((aligned(16))) a; };
v4si addD (struct D a, struct D b) { return a.a + b.a; }
/* Smaller vectors are passed in vector registers. This also applies for vector like structs. */ struct E { v2hi a; };
v2hi addE (struct E a, struct E b) { return a.a + b.a; }
/* This struct is not passed in VRs because of padding. But since it fits in a GPR and has a power of two size. It is passed in GPRs. */ struct F { v4qi __attribute__((aligned(8))) a; };
v4qi addF (struct F a, struct F b) { return a.a + b.a; }
|