1  #include "avx-check.h"
       2  #include "args.h"
       3  
       4  struct IntegerRegisters iregs;
       5  struct FloatRegisters fregs;
       6  unsigned int num_iregs, num_fregs;
       7  
       8  union un1
       9  {
      10    __m256 x;
      11    float f;
      12  };
      13  
      14  union un2
      15  {
      16    __m256 x;
      17    double d;
      18  };
      19  
      20  union un3
      21  {
      22    __m256 x;
      23    __m128 v;
      24  };
      25  
      26  union un4
      27  {
      28    __m256 x;
      29    long double ld;
      30  };
      31  
      32  union un5
      33  {
      34    __m256 x;
      35    int i;
      36  };
      37  
      38  void
      39  check_union_passing1(union un1 u1 ATTRIBUTE_UNUSED,
      40  		     union un1 u2 ATTRIBUTE_UNUSED,
      41  		     union un1 u3 ATTRIBUTE_UNUSED,
      42  		     union un1 u4 ATTRIBUTE_UNUSED,
      43  		     union un1 u5 ATTRIBUTE_UNUSED,
      44  		     union un1 u6 ATTRIBUTE_UNUSED,
      45  		     union un1 u7 ATTRIBUTE_UNUSED,
      46  		     union un1 u8 ATTRIBUTE_UNUSED)
      47  {
      48    check_m256_arguments;
      49  }
      50  
      51  void
      52  check_union_passing2(union un2 u1 ATTRIBUTE_UNUSED,
      53  		     union un2 u2 ATTRIBUTE_UNUSED,
      54  		     union un2 u3 ATTRIBUTE_UNUSED,
      55  		     union un2 u4 ATTRIBUTE_UNUSED,
      56  		     union un2 u5 ATTRIBUTE_UNUSED,
      57  		     union un2 u6 ATTRIBUTE_UNUSED,
      58  		     union un2 u7 ATTRIBUTE_UNUSED,
      59  		     union un2 u8 ATTRIBUTE_UNUSED)
      60  {
      61    check_m256_arguments;
      62  }
      63  
      64  void
      65  check_union_passing3(union un3 u1 ATTRIBUTE_UNUSED,
      66  		     union un3 u2 ATTRIBUTE_UNUSED,
      67  		     union un3 u3 ATTRIBUTE_UNUSED,
      68  		     union un3 u4 ATTRIBUTE_UNUSED,
      69  		     union un3 u5 ATTRIBUTE_UNUSED,
      70  		     union un3 u6 ATTRIBUTE_UNUSED,
      71  		     union un3 u7 ATTRIBUTE_UNUSED,
      72  		     union un3 u8 ATTRIBUTE_UNUSED)
      73  {
      74    check_m256_arguments;
      75  }
      76  
      77  void
      78  check_union_passing4(union un4 u ATTRIBUTE_UNUSED)
      79  {
      80     /* Check the passing on the stack by comparing the address of the
      81        stack elements to the expected place on the stack.  */
      82    assert ((unsigned long)&u.x == rsp+8);
      83    assert ((unsigned long)&u.ld == rsp+8);
      84  }
      85  
      86  void
      87  check_union_passing5(union un5 u ATTRIBUTE_UNUSED)
      88  {
      89     /* Check the passing on the stack by comparing the address of the
      90        stack elements to the expected place on the stack.  */
      91    assert ((unsigned long)&u.x == rsp+8);
      92    assert ((unsigned long)&u.i == rsp+8);
      93  }
      94  
      95  #define check_union_passing1 WRAP_CALL(check_union_passing1)
      96  #define check_union_passing2 WRAP_CALL(check_union_passing2)
      97  #define check_union_passing3 WRAP_CALL(check_union_passing3)
      98  #define check_union_passing4 WRAP_CALL(check_union_passing4)
      99  #define check_union_passing5 WRAP_CALL(check_union_passing5)
     100  
     101  static void
     102  avx_test (void)
     103  {
     104    union un1 u1[8];
     105    union un2 u2[8];
     106    union un3 u3[8];
     107    union un4 u4;
     108    union un5 u5;
     109    int i;
     110  
     111    for (i = 0; i < 8; i++)
     112      u1[i].x = (__m256){32+i, 0, i, 0, -i, 0, i - 12, i + 8};
     113  
     114    clear_struct_registers;
     115    for (i = 0; i < 8; i++)
     116      (&fregs.ymm0)[i]._m256[0] = u1[i].x;
     117    num_fregs = 8;
     118    check_union_passing1(u1[0], u1[1], u1[2], u1[3],
     119  		       u1[4], u1[5], u1[6], u1[7]);
     120  
     121    clear_struct_registers;
     122    for (i = 0; i < 8; i++)
     123      {
     124        u2[i].x = u1[i].x;
     125        (&fregs.ymm0)[i]._m256[0] = u2[i].x;
     126      }
     127    num_fregs = 8;
     128    check_union_passing2(u2[0], u2[1], u2[2], u2[3],
     129  		       u2[4], u2[5], u2[6], u2[7]);
     130  
     131    clear_struct_registers;
     132    for (i = 0; i < 8; i++)
     133      {
     134        u3[i].x = u1[i].x;
     135        (&fregs.ymm0)[i]._m256[0] = u3[i].x;
     136      }
     137    num_fregs = 8;
     138    check_union_passing3(u3[0], u3[1], u3[2], u3[3],
     139  		       u3[4], u3[5], u3[6], u3[7]);
     140  
     141    check_union_passing4(u4);
     142    check_union_passing5(u5);
     143  }