1  /* This tests passing of structs.  */
       2  
       3  #include "defines.h"
       4  #include "args.h"
       5  
       6  struct IntegerRegisters iregbits = { ~0, ~0, ~0, ~0, ~0, ~0 };
       7  struct IntegerRegisters iregs;
       8  unsigned int num_iregs;
       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  union un4
      64  {
      65    int i;
      66    float f;
      67  };
      68  
      69  union un5
      70  {
      71    long long ll;
      72    double d;
      73  };
      74  
      75  void
      76  check_union_passing4(union un4 u1 ATTRIBUTE_UNUSED,
      77  		     union un4 u2 ATTRIBUTE_UNUSED,
      78  		     union un4 u3 ATTRIBUTE_UNUSED,
      79  		     union un4 u4 ATTRIBUTE_UNUSED,
      80  		     union un4 u5 ATTRIBUTE_UNUSED,
      81  		     union un4 u6 ATTRIBUTE_UNUSED,
      82  		     union un4 u7 ATTRIBUTE_UNUSED,
      83  		     union un4 u8 ATTRIBUTE_UNUSED)
      84  {
      85    check_int_arguments;
      86  }
      87  
      88  void
      89  check_union_passing5(union un5 u ATTRIBUTE_UNUSED)
      90  {
      91    check_int_arguments;
      92  }
      93  
      94  #define check_union_passing4 WRAP_CALL(check_union_passing4)
      95  #define check_union_passing5 WRAP_CALL(check_union_passing5)
      96  
      97  #ifdef CHECK_FLOAT128
      98  union un6
      99  {
     100    __float128 f128;
     101    int i;
     102  };
     103  
     104  
     105  void
     106  check_union_passing6(union un6 u ATTRIBUTE_UNUSED)
     107  {
     108    /* Check the passing on the stack by comparing the address of the
     109       stack elements to the expected place on the stack.  */
     110    assert ((unsigned long)&u.f128 == esp+4);
     111    assert ((unsigned long)&u.i == esp+4);
     112  }
     113  
     114  #define check_union_passing6 WRAP_CALL(check_union_passing6)
     115  #endif
     116  
     117  int
     118  main (void)
     119  {
     120    union un1 u1;
     121  #ifdef CHECK_LARGER_UNION_PASSING
     122    union un2 u2;
     123    union un3 u3;
     124    struct int_struct is;
     125    struct long_struct ls;
     126  #endif /* CHECK_LARGER_UNION_PASSING */
     127    union un4 u4[8];
     128    union un5 u5;
     129    int i;
     130  #ifdef CHECK_FLOAT128
     131    union un6 u6;
     132  #endif
     133  
     134    /* Check a union with char, int.  */
     135    clear_struct_registers;
     136    u1.i = 0;  /* clear the struct to not have high bits left */
     137    u1.c = 32;
     138    iregs.I0 = 32;
     139    num_iregs = 1;
     140    clear_int_hardware_registers;
     141    check_union_passing1(u1);
     142    u1.i = 0;  /* clear the struct to not have high bits left */
     143    u1.i = 33;
     144    iregs.I0 = 33;
     145    num_iregs = 1;
     146    clear_int_hardware_registers;
     147    check_union_passing1(u1);
     148  
     149    /* Check a union with char, long, char.  */
     150  #ifdef CHECK_LARGER_UNION_PASSING
     151    clear_struct_registers;
     152    u2.l = 0;  /* clear the struct to not have high bits left */
     153    u2.c1 = 34;
     154    iregs.I0 = 34;
     155    num_iregs = 1;
     156    clear_int_hardware_registers;
     157    check_union_passing2(u2);
     158    u2.l = 0;  /* clear the struct to not have high bits left */
     159    u2.l = 35;
     160    iregs.I0 = 35;
     161    num_iregs = 1;
     162    clear_int_hardware_registers;
     163    check_union_passing2(u2);
     164    u2.l = 0;  /* clear the struct to not have high bits left */
     165    u2.c2 = 36;
     166    iregs.I0 = 36;
     167    num_iregs = 1;
     168    clear_int_hardware_registers;
     169    check_union_passing2(u2);
     170  
     171    /* check a union containing two structs and a union.  */
     172    clear_struct_registers;
     173    is.i = 37;
     174    u3.ls.l = 0;  /* clear the struct to not have high bits left */
     175    u3.is = is;
     176    iregs.I0 = 37;
     177    num_iregs = 1;
     178    clear_int_hardware_registers;
     179    check_union_passing3(u3);
     180    ls.l = 38;
     181    u3.ls.l = 0;  /* clear the struct to not have high bits left */
     182    u3.ls = ls;
     183    iregs.I0 = 38;
     184    num_iregs = 1;
     185    clear_int_hardware_registers;
     186    check_union_passing3(u3);
     187    u1.c = 39;
     188    u3.ls.l = 0;  /* clear the struct to not have high bits left */
     189    u3.un = u1;
     190    iregs.I0 = 39;
     191    num_iregs = 1;
     192    clear_int_hardware_registers;
     193    check_union_passing3(u3);
     194    u1.i = 40;
     195    u3.ls.l = 0;  /* clear the struct to not have high bits left */
     196    u3.un = u1;
     197    iregs.I0 = 40;
     198    num_iregs = 1;
     199    clear_int_hardware_registers;
     200    check_union_passing3(u3);
     201  #endif /* CHECK_LARGER_UNION_PASSING */
     202  
     203    clear_struct_registers;
     204    for (i = 0; i < 8; i++)
     205      u4[i].f = 32 + i;
     206    iregs.I0 = u4[0].i;
     207    iregs.I1 = u4[1].i;
     208    iregs.I2 = u4[2].i;
     209    num_iregs = 3;
     210    clear_int_hardware_registers;
     211    check_union_passing4(u4[0], u4[1], u4[2], u4[3],
     212  		       u4[4], u4[5], u4[6], u4[7]);
     213  
     214    clear_struct_registers;
     215    u5.d = 48.394;
     216    iregs.I0 = u5.ll & 0xffffffff;
     217    iregs.I1 = (u5.ll >> 32) & 0xffffffff;
     218    num_iregs = 2;
     219    clear_int_hardware_registers;
     220    check_union_passing5(u5);
     221  
     222  #ifdef CHECK_FLOAT128
     223    u6.i = 2;
     224    check_union_passing6(u6);
     225  #endif
     226  
     227    return 0;
     228  }