(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.target/
x86_64/
abi/
avx512fp16/
test_passing_unions.c
       1  /* This tests passing of structs.  */
       2  
       3  #include "avx512fp16-xmm-check.h"
       4  #include "defines.h"
       5  #include "args.h"
       6  
       7  struct IntegerRegisters iregs;
       8  struct FloatRegisters fregs;
       9  unsigned int num_iregs, num_fregs;
      10  
      11  struct int_struct
      12  {
      13    int i;
      14  };
      15  
      16  struct long_struct
      17  {
      18    long l;
      19  };
      20  
      21  union un1
      22  {
      23    char c;
      24    int i;
      25  };
      26  
      27  union un2
      28  {
      29    char c1;
      30    long l;
      31    char c2;
      32  };
      33  
      34  union un3
      35  {
      36    struct int_struct is;
      37    struct long_struct ls;
      38    union un1 un;
      39  };
      40  
      41  
      42  void
      43  check_union_passing1(union un1 u ATTRIBUTE_UNUSED)
      44  {
      45    check_int_arguments;
      46  }
      47  
      48  void
      49  check_union_passing2(union un2 u1 ATTRIBUTE_UNUSED)
      50  {
      51    check_int_arguments;
      52  }
      53  
      54  void
      55  check_union_passing3(union un3 u ATTRIBUTE_UNUSED)
      56  {
      57    check_int_arguments;
      58  }
      59  
      60  #define check_union_passing1 WRAP_CALL(check_union_passing1)
      61  #define check_union_passing2 WRAP_CALL(check_union_passing2)
      62  #define check_union_passing3 WRAP_CALL(check_union_passing3)
      63  
      64  #ifdef CHECK_M64_M128
      65  union un4
      66  {
      67    __m128 x;
      68    float f;
      69  };
      70  
      71  union un5
      72  {
      73    __m128 x;
      74    long i;
      75  };
      76  
      77  void
      78  check_union_passing4(union un4 u1 ATTRIBUTE_UNUSED,
      79  		     union un4 u2 ATTRIBUTE_UNUSED,
      80  		     union un4 u3 ATTRIBUTE_UNUSED,
      81  		     union un4 u4 ATTRIBUTE_UNUSED,
      82  		     union un4 u5 ATTRIBUTE_UNUSED,
      83  		     union un4 u6 ATTRIBUTE_UNUSED,
      84  		     union un4 u7 ATTRIBUTE_UNUSED,
      85  		     union un4 u8 ATTRIBUTE_UNUSED)
      86  {
      87    check_m128_arguments;
      88  }
      89  
      90  void
      91  check_union_passing5(union un5 u ATTRIBUTE_UNUSED)
      92  {
      93    check_int_arguments;
      94    check_vector_arguments(m128, 8);
      95  }
      96  
      97  union un4a
      98  {
      99    __m128 x;
     100    _Float16 f;
     101  };
     102  
     103  void
     104  check_union_passing4a(union un4a u1 ATTRIBUTE_UNUSED,
     105  		      union un4a u2 ATTRIBUTE_UNUSED,
     106  		      union un4a u3 ATTRIBUTE_UNUSED,
     107  		      union un4a u4 ATTRIBUTE_UNUSED,
     108  		      union un4a u5 ATTRIBUTE_UNUSED,
     109  		      union un4a u6 ATTRIBUTE_UNUSED,
     110  		      union un4a u7 ATTRIBUTE_UNUSED,
     111  		      union un4a u8 ATTRIBUTE_UNUSED)
     112  {
     113    check_m128_arguments;
     114  }
     115  
     116  union un4b
     117  {
     118    __m128h x;
     119    _Float16 f;
     120  };
     121  
     122  void
     123  check_union_passing4b(union un4b u1 ATTRIBUTE_UNUSED,
     124  		      union un4b u2 ATTRIBUTE_UNUSED,
     125  		      union un4b u3 ATTRIBUTE_UNUSED,
     126  		      union un4b u4 ATTRIBUTE_UNUSED,
     127  		      union un4b u5 ATTRIBUTE_UNUSED,
     128  		      union un4b u6 ATTRIBUTE_UNUSED,
     129  		      union un4b u7 ATTRIBUTE_UNUSED,
     130  		      union un4b u8 ATTRIBUTE_UNUSED)
     131  {
     132    check_m128_arguments;
     133  }
     134  
     135  #define check_union_passing4 WRAP_CALL(check_union_passing4)
     136  #define check_union_passing4a WRAP_CALL(check_union_passing4a)
     137  #define check_union_passing4b WRAP_CALL(check_union_passing4b)
     138  #define check_union_passing5 WRAP_CALL(check_union_passing5)
     139  #endif
     140  
     141  union un6
     142  {
     143    long double ld;
     144    int i;
     145  };
     146  
     147  
     148  void
     149  check_union_passing6(union un6 u ATTRIBUTE_UNUSED)
     150  {
     151    /* Check the passing on the stack by comparing the address of the
     152       stack elements to the expected place on the stack.  */
     153    assert ((unsigned long)&u.ld == rsp+8);
     154    assert ((unsigned long)&u.i == rsp+8);
     155  }
     156  
     157  #define check_union_passing6 WRAP_CALL(check_union_passing6)
     158  
     159  union un7
     160  {
     161    long double ld;
     162    _Float16 f;
     163  };
     164  
     165  void
     166  check_union_passing7(union un7 u ATTRIBUTE_UNUSED)
     167  {
     168    /* Check the passing on the stack by comparing the address of the
     169       stack elements to the expected place on the stack.  */
     170    assert ((unsigned long)&u.ld == rsp+8);
     171    assert ((unsigned long)&u.f == rsp+8);
     172  }
     173  
     174  #define check_union_passing7 WRAP_CALL(check_union_passing7)
     175  
     176  union un8
     177  {
     178    _Float16 f;
     179    int i;
     180  };
     181  
     182  void
     183  check_union_passing8(union un8 u ATTRIBUTE_UNUSED)
     184  {
     185    check_int_arguments;
     186  }
     187  
     188  #define check_union_passing8 WRAP_CALL(check_union_passing8)
     189  
     190  static void
     191  do_test (void)
     192  {
     193    union un1 u1;
     194  #ifdef CHECK_LARGER_UNION_PASSING
     195    union un2 u2;
     196    union un3 u3;
     197    struct int_struct is;
     198    struct long_struct ls;
     199  #endif /* CHECK_LARGER_UNION_PASSING */
     200  #ifdef CHECK_M64_M128
     201    union un4 u4[8];
     202    union un4a u4a[8];
     203    union un4b u4b[8];
     204    union un5 u5 = { { 48.394, 39.3, -397.9, 3484.9 } };
     205    int i;
     206  #endif
     207    union un6 u6;
     208    union un7 u7;
     209    union un8 u8;
     210  
     211    /* Check a union with char, int.  */
     212    clear_struct_registers;
     213    u1.i = 0;  /* clear the struct to not have high bits left */
     214    u1.c = 32;
     215    iregs.I0 = 32;
     216    num_iregs = 1;
     217    clear_int_hardware_registers;
     218    check_union_passing1(u1);
     219    u1.i = 0;  /* clear the struct to not have high bits left */
     220    u1.i = 33;
     221    iregs.I0 = 33;
     222    num_iregs = 1;
     223    clear_int_hardware_registers;
     224    check_union_passing1(u1);
     225  
     226    /* Check a union with char, long, char.  */
     227  #ifdef CHECK_LARGER_UNION_PASSING
     228    clear_struct_registers;
     229    u2.l = 0;  /* clear the struct to not have high bits left */
     230    u2.c1 = 34;
     231    iregs.I0 = 34;
     232    num_iregs = 1;
     233    clear_int_hardware_registers;
     234    check_union_passing2(u2);
     235    u2.l = 0;  /* clear the struct to not have high bits left */
     236    u2.l = 35;
     237    iregs.I0 = 35;
     238    num_iregs = 1;
     239    clear_int_hardware_registers;
     240    check_union_passing2(u2);
     241    u2.l = 0;  /* clear the struct to not have high bits left */
     242    u2.c2 = 36;
     243    iregs.I0 = 36;
     244    num_iregs = 1;
     245    clear_int_hardware_registers;
     246    check_union_passing2(u2);
     247  
     248    /* check a union containing two structs and a union.  */
     249    clear_struct_registers;
     250    is.i = 37;
     251    u3.ls.l = 0;  /* clear the struct to not have high bits left */
     252    u3.is = is;
     253    iregs.I0 = 37;
     254    num_iregs = 1;
     255    clear_int_hardware_registers;
     256    check_union_passing3(u3);
     257    ls.l = 38;
     258    u3.ls.l = 0;  /* clear the struct to not have high bits left */
     259    u3.ls = ls;
     260    iregs.I0 = 38;
     261    num_iregs = 1;
     262    clear_int_hardware_registers;
     263    check_union_passing3(u3);
     264    u1.c = 39;
     265    u3.ls.l = 0;  /* clear the struct to not have high bits left */
     266    u3.un = u1;
     267    iregs.I0 = 39;
     268    num_iregs = 1;
     269    clear_int_hardware_registers;
     270    check_union_passing3(u3);
     271    u1.i = 40;
     272    u3.ls.l = 0;  /* clear the struct to not have high bits left */
     273    u3.un = u1;
     274    iregs.I0 = 40;
     275    num_iregs = 1;
     276    clear_int_hardware_registers;
     277    check_union_passing3(u3);
     278  #endif /* CHECK_LARGER_UNION_PASSING */
     279  
     280  #ifdef CHECK_M64_M128
     281    clear_struct_registers;
     282    for (i = 0; i < 8; i++)
     283      {
     284        u4[i].x = (__m128){32+i, 0, i, 0};
     285        (&fregs.xmm0)[i]._m128[0] = u4[i].x;
     286      }
     287    num_fregs = 8;
     288    clear_float_hardware_registers;
     289    check_union_passing4(u4[0], u4[1], u4[2], u4[3],
     290  		       u4[4], u4[5], u4[6], u4[7]);
     291  
     292    clear_struct_registers;
     293    for (i = 0; i < 8; i++)
     294      {
     295        u4a[i].x = (__m128){32+i, 0, i, 0};
     296        (&fregs.xmm0)[i]._m128[0] = u4[i].x;
     297      }
     298    num_fregs = 8;
     299    clear_float_hardware_registers;
     300    check_union_passing4a(u4a[0], u4a[1], u4a[2], u4a[3],
     301  		       u4a[4], u4a[5], u4a[6], u4a[7]);
     302  
     303    clear_struct_registers;
     304    for (i = 0; i < 8; i++)
     305      {
     306        u4b[i].x = (__m128h){33+i, 0, i, 0, -i, 1, 2 * i, i + 8};
     307        (&fregs.xmm0)[i]._m128h[0] = u4b[i].x;
     308      }
     309    num_fregs = 8;
     310    clear_float_hardware_registers;
     311    check_union_passing4b(u4b[0], u4b[1], u4b[2], u4b[3],
     312  		        u4b[4], u4b[5], u4b[6], u4b[7]);
     313  
     314    clear_struct_registers;
     315    fregs.xmm0._m128[0] = u5.x;
     316    num_fregs = 1;
     317    num_iregs = 1;
     318    iregs.I0 = u5.i;
     319    clear_float_hardware_registers;
     320    check_union_passing5(u5);
     321  #endif
     322  
     323    u6.i = 2;
     324    check_union_passing6(u6);
     325  
     326    u7.f = 2.0f16;
     327    check_union_passing7(u7);
     328  
     329    clear_struct_registers;
     330    u8.i = 8;
     331    num_iregs = 1;
     332    iregs.I0 = u8.i;
     333    clear_int_hardware_registers;
     334    check_union_passing8(u8);
     335  }