(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.target/
x86_64/
abi/
test_passing_unions.c
       1  /* This tests passing of structs.  */
       2  
       3  #include "defines.h"
       4  #include "args.h"
       5  
       6  struct IntegerRegisters iregs;
       7  struct FloatRegisters fregs;
       8  unsigned int num_iregs, num_fregs;
       9  
      10  struct int_struct
      11  {
      12    int i;
      13  };
      14  
      15  struct long_struct
      16  {
      17    long l;
      18  };
      19  
      20  union un1
      21  {
      22    char c;
      23    int i;
      24  };
      25  
      26  union un2
      27  {
      28    char c1;
      29    long l;
      30    char c2;
      31  };
      32  
      33  union un3
      34  {
      35    struct int_struct is;
      36    struct long_struct ls;
      37    union un1 un;
      38  };
      39  
      40  
      41  void
      42  check_union_passing1(union un1 u ATTRIBUTE_UNUSED)
      43  {
      44    check_int_arguments;
      45  }
      46  
      47  void
      48  check_union_passing2(union un2 u1 ATTRIBUTE_UNUSED)
      49  {
      50    check_int_arguments;
      51  }
      52  
      53  void
      54  check_union_passing3(union un3 u ATTRIBUTE_UNUSED)
      55  {
      56    check_int_arguments;
      57  }
      58  
      59  #define check_union_passing1 WRAP_CALL(check_union_passing1)
      60  #define check_union_passing2 WRAP_CALL(check_union_passing2)
      61  #define check_union_passing3 WRAP_CALL(check_union_passing3)
      62  
      63  #ifdef CHECK_M64_M128
      64  union un4
      65  {
      66    __m128 x;
      67    float f;
      68  };
      69  
      70  union un5
      71  {
      72    __m128 x;
      73    long i;
      74  };
      75  
      76  void
      77  check_union_passing4(union un4 u1 ATTRIBUTE_UNUSED,
      78  		     union un4 u2 ATTRIBUTE_UNUSED,
      79  		     union un4 u3 ATTRIBUTE_UNUSED,
      80  		     union un4 u4 ATTRIBUTE_UNUSED,
      81  		     union un4 u5 ATTRIBUTE_UNUSED,
      82  		     union un4 u6 ATTRIBUTE_UNUSED,
      83  		     union un4 u7 ATTRIBUTE_UNUSED,
      84  		     union un4 u8 ATTRIBUTE_UNUSED)
      85  {
      86    check_m128_arguments;
      87  }
      88  
      89  void
      90  check_union_passing5(union un5 u ATTRIBUTE_UNUSED)
      91  {
      92    check_int_arguments;
      93    check_vector_arguments(m128, 8);
      94  }
      95  
      96  #define check_union_passing4 WRAP_CALL(check_union_passing4)
      97  #define check_union_passing5 WRAP_CALL(check_union_passing5)
      98  #endif
      99  
     100  union un6
     101  {
     102    long double ld;
     103    int i;
     104  };
     105  
     106  
     107  void
     108  check_union_passing6(union un6 u ATTRIBUTE_UNUSED)
     109  {
     110    /* Check the passing on the stack by comparing the address of the
     111       stack elements to the expected place on the stack.  */
     112    assert ((unsigned long)&u.ld == rsp+8);
     113    assert ((unsigned long)&u.i == rsp+8);
     114  }
     115  
     116  #define check_union_passing6 WRAP_CALL(check_union_passing6)
     117  
     118  int
     119  main (void)
     120  {
     121    union un1 u1;
     122  #ifdef CHECK_LARGER_UNION_PASSING
     123    union un2 u2;
     124    union un3 u3;
     125    struct int_struct is;
     126    struct long_struct ls;
     127  #endif /* CHECK_LARGER_UNION_PASSING */
     128  #ifdef CHECK_M64_M128
     129    union un4 u4[8];
     130    union un5 u5 = { { 48.394, 39.3, -397.9, 3484.9 } };
     131    int i;
     132  #endif
     133    union un6 u6;
     134  
     135    /* Check a union with char, int.  */
     136    clear_struct_registers;
     137    u1.i = 0;  /* clear the struct to not have high bits left */
     138    u1.c = 32;
     139    iregs.I0 = 32;
     140    num_iregs = 1;
     141    clear_int_hardware_registers;
     142    check_union_passing1(u1);
     143    u1.i = 0;  /* clear the struct to not have high bits left */
     144    u1.i = 33;
     145    iregs.I0 = 33;
     146    num_iregs = 1;
     147    clear_int_hardware_registers;
     148    check_union_passing1(u1);
     149  
     150    /* Check a union with char, long, char.  */
     151  #ifdef CHECK_LARGER_UNION_PASSING
     152    clear_struct_registers;
     153    u2.l = 0;  /* clear the struct to not have high bits left */
     154    u2.c1 = 34;
     155    iregs.I0 = 34;
     156    num_iregs = 1;
     157    clear_int_hardware_registers;
     158    check_union_passing2(u2);
     159    u2.l = 0;  /* clear the struct to not have high bits left */
     160    u2.l = 35;
     161    iregs.I0 = 35;
     162    num_iregs = 1;
     163    clear_int_hardware_registers;
     164    check_union_passing2(u2);
     165    u2.l = 0;  /* clear the struct to not have high bits left */
     166    u2.c2 = 36;
     167    iregs.I0 = 36;
     168    num_iregs = 1;
     169    clear_int_hardware_registers;
     170    check_union_passing2(u2);
     171  
     172    /* check a union containing two structs and a union.  */
     173    clear_struct_registers;
     174    is.i = 37;
     175    u3.ls.l = 0;  /* clear the struct to not have high bits left */
     176    u3.is = is;
     177    iregs.I0 = 37;
     178    num_iregs = 1;
     179    clear_int_hardware_registers;
     180    check_union_passing3(u3);
     181    ls.l = 38;
     182    u3.ls.l = 0;  /* clear the struct to not have high bits left */
     183    u3.ls = ls;
     184    iregs.I0 = 38;
     185    num_iregs = 1;
     186    clear_int_hardware_registers;
     187    check_union_passing3(u3);
     188    u1.c = 39;
     189    u3.ls.l = 0;  /* clear the struct to not have high bits left */
     190    u3.un = u1;
     191    iregs.I0 = 39;
     192    num_iregs = 1;
     193    clear_int_hardware_registers;
     194    check_union_passing3(u3);
     195    u1.i = 40;
     196    u3.ls.l = 0;  /* clear the struct to not have high bits left */
     197    u3.un = u1;
     198    iregs.I0 = 40;
     199    num_iregs = 1;
     200    clear_int_hardware_registers;
     201    check_union_passing3(u3);
     202  #endif /* CHECK_LARGER_UNION_PASSING */
     203  
     204  #ifdef CHECK_M64_M128
     205    clear_struct_registers;
     206    for (i = 0; i < 8; i++)
     207      {
     208        u4[i].x = (__m128){32+i, 0, i, 0};
     209        (&fregs.xmm0)[i]._m128[0] = u4[i].x;
     210      }
     211    num_fregs = 8;
     212    clear_float_hardware_registers;
     213    check_union_passing4(u4[0], u4[1], u4[2], u4[3],
     214  		       u4[4], u4[5], u4[6], u4[7]);
     215  
     216    clear_struct_registers;
     217    fregs.xmm0._m128[0] = u5.x;
     218    num_fregs = 1;
     219    num_iregs = 1;
     220    iregs.I0 = u5.i;
     221    clear_float_hardware_registers;
     222    check_union_passing5(u5);
     223  #endif
     224  
     225    u6.i = 2;
     226    check_union_passing6(u6);
     227  
     228    return 0;
     229  }