1  /* { dg-do compile } */
       2  /* { dg-options "-O3 -mzarch -march=z13 -mzvector --save-temps" } */
       3  /* { dg-do run { target { s390_z13_hw } } } */
       4  
       5  /*
       6   * The vector intrinsic vec_permi(a, b, c) chooses one of the two eight-byte
       7   * vector elements in each of a and b, depending on the value of c. The valid
       8   * values for c differ from the encoding for the M4 field in assembly and in the
       9   * binary instruction.
      10   *
      11   * selection | c | encoding in assembly
      12   * a[0] b[0] | 0 | 0          -> vmrhg
      13   * a[0] b[1] | 1 | 1
      14   * a[1] b[0] | 2 | 4
      15   * a[1] b[1] | 3 | 5          -> vmrlg
      16   *
      17   * (i.e., indices a[i] b[j] are encoded for c as (i<<1) | j, yet for the
      18   * M4 field as (i<<2) | j.
      19   */
      20  
      21  /* { dg-final { scan-assembler-times "\tvmrhg\t" 3 } } */
      22  /* { dg-final { scan-assembler-times "\tvmrlg\t" 3 } } */
      23  /* { dg-final { scan-assembler-times "\tvpdi\t" 6 } } */
      24  
      25  #include "vec-types.h"
      26  #include <vecintrin.h>
      27  
      28  #define GEN_PERMI_BITS(VEC_TYPE, BITS)			\
      29    VEC_TYPE __attribute__((noinline))			\
      30    permi_##BITS##_##VEC_TYPE(VEC_TYPE a, VEC_TYPE b) {	\
      31      return vec_permi (a, b, (BITS)); }
      32  
      33  #define GEN_PERMI(VEC_TYPE)			\
      34    GEN_PERMI_BITS(VEC_TYPE, 0);			\
      35    GEN_PERMI_BITS(VEC_TYPE, 1);			\
      36    GEN_PERMI_BITS(VEC_TYPE, 2);			\
      37    GEN_PERMI_BITS(VEC_TYPE, 3);
      38  
      39  GEN_PERMI(v2di)
      40  GEN_PERMI(uv2di)
      41  GEN_PERMI(v2df)
      42  
      43  
      44  #define CHECK_PERMI_BITS(VEC_TYPE, BITS)		\
      45    VEC_TYPE r##BITS = permi_##BITS##_##VEC_TYPE (a, b);	\
      46    if (r##BITS[0] != ((BITS) & 2) >> 1			\
      47        || r##BITS[1] != ((BITS) & 1) + 2)		\
      48      __builtin_abort();
      49  
      50  #define CHECK_PERMI(VEC_TYPE)			\
      51    {						\
      52      VEC_TYPE a = GEN_SEQ_VEC (VEC_TYPE, 0);	\
      53      VEC_TYPE b = GEN_SEQ_VEC (VEC_TYPE, 2);	\
      54      CHECK_PERMI_BITS (VEC_TYPE, 0);		\
      55      CHECK_PERMI_BITS (VEC_TYPE, 1);		\
      56      CHECK_PERMI_BITS (VEC_TYPE, 2);		\
      57      CHECK_PERMI_BITS (VEC_TYPE, 3);		\
      58    }
      59  
      60  int
      61  main ()
      62  {
      63    CHECK_PERMI (v2di);
      64    CHECK_PERMI (uv2di);
      65    CHECK_PERMI (v2df);
      66  }