(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.target/
s390/
vector/
vec-abi-3.c
       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  
      33  typedef double v2df __attribute__((vector_size(16)));
      34  typedef long long v2di __attribute__((vector_size(16)));
      35  typedef int v4si __attribute__((vector_size(16)));
      36  typedef short v8hi __attribute__((vector_size(16)));
      37  
      38  typedef short v2hi __attribute__((vector_size(4)));
      39  typedef char v4qi __attribute__((vector_size(4)));
      40  
      41  /* Vector like structs are passed in VRs.  */
      42  struct A { v2df a; };
      43  
      44  v2df
      45  addA (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.  */
      53  struct B { v8hi a; char b;};
      54  
      55  v8hi
      56  addB (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.  */
      63  struct C { v2di __attribute__((aligned(32))) a; };
      64  
      65  v2di
      66  addC (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.  */
      73  struct D { v4si __attribute__((aligned(16))) a; };
      74  
      75  v4si
      76  addD (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.  */
      84  struct E { v2hi a; };
      85  
      86  v2hi
      87  addE (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.  */
      95  struct F { v4qi __attribute__((aligned(8))) a; };
      96  
      97  v4qi
      98  addF (struct F a, struct F b)
      99  {
     100    return a.a + b.a;
     101  }