(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.target/
x86_64/
abi/
test_passing_structs.c
       1  /* This tests passing of structs. */
       2  
       3  #include "defines.h"
       4  #include "args.h"
       5  #include <complex.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  struct long2_struct
      22  {
      23    long l1, l2;
      24  };
      25  
      26  struct long3_struct
      27  {
      28    long l1, l2, l3;
      29  };
      30  
      31  
      32  /* Check that the struct is passed as the individual members in iregs.  */
      33  void
      34  check_struct_passing1 (struct int_struct is ATTRIBUTE_UNUSED)
      35  {
      36    check_int_arguments;
      37  }
      38  
      39  void
      40  check_struct_passing2 (struct long_struct ls ATTRIBUTE_UNUSED)
      41  {
      42    check_int_arguments;
      43  }
      44  
      45  void
      46  check_struct_passing3 (struct long2_struct ls ATTRIBUTE_UNUSED)
      47  {
      48    check_int_arguments;
      49  }
      50  
      51  void
      52  check_struct_passing4 (struct long3_struct ls ATTRIBUTE_UNUSED)
      53  {
      54    /* Check the passing on the stack by comparing the address of the
      55       stack elements to the expected place on the stack.  */
      56    assert ((unsigned long)&ls.l1 == rsp+8);
      57    assert ((unsigned long)&ls.l2 == rsp+16);
      58    assert ((unsigned long)&ls.l3 == rsp+24);
      59  }
      60  
      61  #ifdef CHECK_M64_M128
      62  struct m128_struct
      63  {
      64    __m128 x;
      65  };
      66  
      67  struct m128_2_struct
      68  {
      69    __m128 x1, x2;
      70  };
      71  
      72  /* Check that the struct is passed as the individual members in fregs.  */
      73  void
      74  check_struct_passing5 (struct m128_struct ms1 ATTRIBUTE_UNUSED,
      75  		       struct m128_struct ms2 ATTRIBUTE_UNUSED,
      76  		       struct m128_struct ms3 ATTRIBUTE_UNUSED,
      77  		       struct m128_struct ms4 ATTRIBUTE_UNUSED,
      78  		       struct m128_struct ms5 ATTRIBUTE_UNUSED,
      79  		       struct m128_struct ms6 ATTRIBUTE_UNUSED,
      80  		       struct m128_struct ms7 ATTRIBUTE_UNUSED,
      81  		       struct m128_struct ms8 ATTRIBUTE_UNUSED)
      82  {
      83    check_m128_arguments;
      84  }
      85  
      86  void
      87  check_struct_passing6 (struct m128_2_struct ms 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)&ms.x1 == rsp+8);
      92    assert ((unsigned long)&ms.x2 == rsp+24);
      93  }
      94  #endif
      95  
      96  struct flex1_struct
      97  {
      98    long i;
      99    long flex[];
     100  };
     101  
     102  struct flex2_struct
     103  {
     104    long i;
     105    long flex[0];
     106  };
     107  
     108  void
     109  check_struct_passing7 (struct flex1_struct is ATTRIBUTE_UNUSED)
     110  {
     111    check_int_arguments;
     112  }
     113  
     114  void
     115  check_struct_passing8 (struct flex2_struct is ATTRIBUTE_UNUSED)
     116  {
     117    check_int_arguments;
     118  }
     119  
     120  struct complex1_struct
     121  {
     122    int c;
     123    __complex__ float x;
     124  };
     125  
     126  struct complex1a_struct
     127  {
     128    long l;
     129    float f;
     130  };
     131  
     132  struct complex2_struct
     133  {
     134    int c;
     135    __complex__ float x;
     136    float y;
     137  };
     138  
     139  struct complex2a_struct
     140  {
     141    long l;
     142    double d;
     143  };
     144  
     145  void
     146  check_struct_passing9 (struct complex1_struct is ATTRIBUTE_UNUSED)
     147  {
     148    check_int_arguments;
     149    check_float_arguments;
     150  }
     151  
     152  void
     153  check_struct_passing10 (struct complex2_struct is ATTRIBUTE_UNUSED)
     154  {
     155    check_int_arguments;
     156    check_double_arguments;
     157  }
     158  
     159  static struct flex1_struct f1s = { 60, { } };
     160  static struct flex2_struct f2s = { 61, { } };
     161  
     162  int
     163  main (void)
     164  {
     165    struct int_struct is = { 48 };
     166    struct long_struct ls = { 49 };
     167  #ifdef CHECK_LARGER_STRUCTS
     168    struct long2_struct l2s = { 50, 51 };
     169    struct long3_struct l3s = { 52, 53, 54 };
     170  #endif
     171  #ifdef CHECK_M64_M128
     172    struct m128_struct m128s[8];
     173    struct m128_2_struct m128_2s = { 
     174        { 48.394, 39.3, -397.9, 3484.9 },
     175        { -8.394, -93.3, 7.9, 84.94 }
     176    };
     177    int i;
     178  #endif
     179    struct complex1_struct c1s = { 4, ( -13.4 + 3.5*I ) };
     180    union
     181      {
     182        struct complex1_struct c;
     183        struct complex1a_struct u;
     184      } c1u;
     185    struct complex2_struct c2s = { 4, ( -13.4 + 3.5*I ), -34.5 };
     186    union
     187      {
     188        struct complex2_struct c;
     189        struct complex2a_struct u;
     190      } c2u;
     191  
     192    clear_struct_registers;
     193    iregs.I0 = is.i;
     194    num_iregs = 1;
     195    clear_int_hardware_registers;
     196    WRAP_CALL (check_struct_passing1)(is);
     197  
     198    clear_struct_registers;
     199    iregs.I0 = ls.l;
     200    num_iregs = 1;
     201    clear_int_hardware_registers;
     202    WRAP_CALL (check_struct_passing2)(ls);
     203  
     204  #ifdef CHECK_LARGER_STRUCTS
     205    clear_struct_registers;
     206    iregs.I0 = l2s.l1;
     207    iregs.I1 = l2s.l2;
     208    num_iregs = 2;
     209    clear_int_hardware_registers;
     210    WRAP_CALL (check_struct_passing3)(l2s);
     211    WRAP_CALL (check_struct_passing4)(l3s);
     212  #endif
     213  
     214  #ifdef CHECK_M64_M128
     215    clear_struct_registers;
     216    for (i = 0; i < 8; i++)
     217      {
     218        m128s[i].x = (__m128){32+i, 0, i, 0};
     219        (&fregs.xmm0)[i]._m128[0] = m128s[i].x;
     220      }
     221    num_fregs = 8;
     222    clear_float_hardware_registers;
     223    WRAP_CALL (check_struct_passing5)(m128s[0], m128s[1], m128s[2], m128s[3],
     224  				    m128s[4], m128s[5], m128s[6], m128s[7]);
     225    WRAP_CALL (check_struct_passing6)(m128_2s);
     226  #endif
     227  
     228    clear_struct_registers;
     229    iregs.I0 = f1s.i;
     230    num_iregs = 1;
     231    clear_int_hardware_registers;
     232    WRAP_CALL (check_struct_passing7)(f1s);
     233  
     234    clear_struct_registers;
     235    iregs.I0 = f2s.i;
     236    num_iregs = 1;
     237    clear_int_hardware_registers;
     238    WRAP_CALL (check_struct_passing8)(f2s);
     239  
     240    clear_struct_registers;
     241    c1u.c = c1s;
     242    iregs.I0 = c1u.u.l;
     243    num_iregs = 1;
     244    fregs.xmm0._float [0] = c1u.u.f;
     245    num_fregs = 1;
     246    clear_int_hardware_registers;
     247    clear_float_hardware_registers;
     248    WRAP_CALL (check_struct_passing9)(c1s);
     249  
     250    clear_struct_registers;
     251    c2u.c = c2s;
     252    iregs.I0 = c2u.u.l;
     253    num_iregs = 1;
     254    fregs.xmm0._double[0] = c2u.u.d;
     255    num_fregs = 1;
     256    clear_int_hardware_registers;
     257    clear_float_hardware_registers;
     258    WRAP_CALL (check_struct_passing10)(c2s);
     259  
     260    return 0;
     261  }