1  #include <stdio.h>
       2  #include "defines.h"
       3  #include "macros.h"
       4  #include "args.h"
       5  
       6  struct IntegerRegisters iregs;
       7  struct FloatRegisters fregs;
       8  unsigned int num_iregs, num_fregs;
       9  
      10  /* This struct holds values for argument checking.  */
      11  struct 
      12  {
      13    XMM_T i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15, i16, i17, i18, i19, i20, i21, i22, i23;
      14  } values;
      15  
      16  char *pass;
      17  int failed = 0;
      18  
      19  #undef assert
      20  #define assert(c) do { \
      21    if (!(c)) {failed++; printf ("failed %s\n", pass); } \
      22  } while (0)
      23  
      24  #define compare(X1,X2,T) do { \
      25    assert (memcmp (&X1, &X2, sizeof (T)) == 0); \
      26  } while (0)
      27  
      28  void
      29  fun_check_passing_m64_8_values (__m64 i0 ATTRIBUTE_UNUSED, __m64 i1 ATTRIBUTE_UNUSED, __m64 i2 ATTRIBUTE_UNUSED, __m64 i3 ATTRIBUTE_UNUSED, __m64 i4 ATTRIBUTE_UNUSED, __m64 i5 ATTRIBUTE_UNUSED, __m64 i6 ATTRIBUTE_UNUSED, __m64 i7 ATTRIBUTE_UNUSED)
      30  {
      31    /* Check argument values.  */
      32    compare (values.i0, i0, __m64);
      33    compare (values.i1, i1, __m64);
      34    compare (values.i2, i2, __m64);
      35    compare (values.i3, i3, __m64);
      36    compare (values.i4, i4, __m64);
      37    compare (values.i5, i5, __m64);
      38    compare (values.i6, i6, __m64);
      39    compare (values.i7, i7, __m64);
      40  }
      41  
      42  void
      43  fun_check_passing_m64_8_regs (__m64 i0 ATTRIBUTE_UNUSED, __m64 i1 ATTRIBUTE_UNUSED, __m64 i2 ATTRIBUTE_UNUSED, __m64 i3 ATTRIBUTE_UNUSED, __m64 i4 ATTRIBUTE_UNUSED, __m64 i5 ATTRIBUTE_UNUSED, __m64 i6 ATTRIBUTE_UNUSED, __m64 i7 ATTRIBUTE_UNUSED)
      44  {
      45    /* Check register contents.  */
      46    check_m64_arguments;
      47  }
      48  
      49  void
      50  fun_check_passing_m64_20_values (__m64 i0 ATTRIBUTE_UNUSED, __m64 i1 ATTRIBUTE_UNUSED, __m64 i2 ATTRIBUTE_UNUSED, __m64 i3 ATTRIBUTE_UNUSED, __m64 i4 ATTRIBUTE_UNUSED, __m64 i5 ATTRIBUTE_UNUSED, __m64 i6 ATTRIBUTE_UNUSED, __m64 i7 ATTRIBUTE_UNUSED, __m64 i8 ATTRIBUTE_UNUSED, __m64 i9 ATTRIBUTE_UNUSED, __m64 i10 ATTRIBUTE_UNUSED, __m64 i11 ATTRIBUTE_UNUSED, __m64 i12 ATTRIBUTE_UNUSED, __m64 i13 ATTRIBUTE_UNUSED, __m64 i14 ATTRIBUTE_UNUSED, __m64 i15 ATTRIBUTE_UNUSED, __m64 i16 ATTRIBUTE_UNUSED, __m64 i17 ATTRIBUTE_UNUSED, __m64 i18 ATTRIBUTE_UNUSED, __m64 i19 ATTRIBUTE_UNUSED)
      51  {
      52    /* Check argument values.  */
      53    compare (values.i0 , i0, __m64);
      54    compare (values.i1 , i1, __m64);
      55    compare (values.i2 , i2, __m64);
      56    compare (values.i3 , i3, __m64);
      57    compare (values.i4 , i4, __m64);
      58    compare (values.i5 , i5, __m64);
      59    compare (values.i6 , i6, __m64);
      60    compare (values.i7 , i7, __m64);
      61    compare (values.i8 , i8, __m64);
      62    compare (values.i9 , i9, __m64);
      63    compare (values.i10 , i10, __m64);
      64    compare (values.i11 , i11, __m64);
      65    compare (values.i12 , i12, __m64);
      66    compare (values.i13 , i13, __m64);
      67    compare (values.i14 , i14, __m64);
      68    compare (values.i15 , i15, __m64);
      69    compare (values.i16 , i16, __m64);
      70    compare (values.i17 , i17, __m64);
      71    compare (values.i18 , i18, __m64);
      72    compare (values.i19 , i19, __m64);
      73  }
      74  
      75  void
      76  fun_check_passing_m64_20_regs (__m64 i0 ATTRIBUTE_UNUSED, __m64 i1 ATTRIBUTE_UNUSED, __m64 i2 ATTRIBUTE_UNUSED, __m64 i3 ATTRIBUTE_UNUSED, __m64 i4 ATTRIBUTE_UNUSED, __m64 i5 ATTRIBUTE_UNUSED, __m64 i6 ATTRIBUTE_UNUSED, __m64 i7 ATTRIBUTE_UNUSED, __m64 i8 ATTRIBUTE_UNUSED, __m64 i9 ATTRIBUTE_UNUSED, __m64 i10 ATTRIBUTE_UNUSED, __m64 i11 ATTRIBUTE_UNUSED, __m64 i12 ATTRIBUTE_UNUSED, __m64 i13 ATTRIBUTE_UNUSED, __m64 i14 ATTRIBUTE_UNUSED, __m64 i15 ATTRIBUTE_UNUSED, __m64 i16 ATTRIBUTE_UNUSED, __m64 i17 ATTRIBUTE_UNUSED, __m64 i18 ATTRIBUTE_UNUSED, __m64 i19 ATTRIBUTE_UNUSED)
      77  {
      78    /* Check register contents.  */
      79    check_m64_arguments;
      80  }
      81  
      82  void
      83  fun_check_passing_m128_8_values (__m128 i0 ATTRIBUTE_UNUSED, __m128 i1 ATTRIBUTE_UNUSED, __m128 i2 ATTRIBUTE_UNUSED, __m128 i3 ATTRIBUTE_UNUSED, __m128 i4 ATTRIBUTE_UNUSED, __m128 i5 ATTRIBUTE_UNUSED, __m128 i6 ATTRIBUTE_UNUSED, __m128 i7 ATTRIBUTE_UNUSED)
      84  {
      85    /* Check argument values.  */
      86    compare (values.i0, i0, __m128);
      87    compare (values.i1, i1, __m128);
      88    compare (values.i2, i2, __m128);
      89    compare (values.i3, i3, __m128);
      90    compare (values.i4, i4, __m128);
      91    compare (values.i5, i5, __m128);
      92    compare (values.i6, i6, __m128);
      93    compare (values.i7, i7, __m128);
      94  }
      95  
      96  void
      97  fun_check_passing_m128_8_regs (__m128 i0 ATTRIBUTE_UNUSED, __m128 i1 ATTRIBUTE_UNUSED, __m128 i2 ATTRIBUTE_UNUSED, __m128 i3 ATTRIBUTE_UNUSED, __m128 i4 ATTRIBUTE_UNUSED, __m128 i5 ATTRIBUTE_UNUSED, __m128 i6 ATTRIBUTE_UNUSED, __m128 i7 ATTRIBUTE_UNUSED)
      98  {
      99    /* Check register contents.  */
     100    check_m128_arguments;
     101  }
     102  
     103  void
     104  fun_check_passing_m128_20_values (__m128 i0 ATTRIBUTE_UNUSED, __m128 i1 ATTRIBUTE_UNUSED, __m128 i2 ATTRIBUTE_UNUSED, __m128 i3 ATTRIBUTE_UNUSED, __m128 i4 ATTRIBUTE_UNUSED, __m128 i5 ATTRIBUTE_UNUSED, __m128 i6 ATTRIBUTE_UNUSED, __m128 i7 ATTRIBUTE_UNUSED, __m128 i8 ATTRIBUTE_UNUSED, __m128 i9 ATTRIBUTE_UNUSED, __m128 i10 ATTRIBUTE_UNUSED, __m128 i11 ATTRIBUTE_UNUSED, __m128 i12 ATTRIBUTE_UNUSED, __m128 i13 ATTRIBUTE_UNUSED, __m128 i14 ATTRIBUTE_UNUSED, __m128 i15 ATTRIBUTE_UNUSED, __m128 i16 ATTRIBUTE_UNUSED, __m128 i17 ATTRIBUTE_UNUSED, __m128 i18 ATTRIBUTE_UNUSED, __m128 i19 ATTRIBUTE_UNUSED)
     105  {
     106    /* Check argument values.  */
     107    compare (values.i0 , i0, __m128);
     108    compare (values.i1 , i1, __m128);
     109    compare (values.i2 , i2, __m128);
     110    compare (values.i3 , i3, __m128);
     111    compare (values.i4 , i4, __m128);
     112    compare (values.i5 , i5, __m128);
     113    compare (values.i6 , i6, __m128);
     114    compare (values.i7 , i7, __m128);
     115    compare (values.i8 , i8, __m128);
     116    compare (values.i9 , i9, __m128);
     117    compare (values.i10 , i10, __m128);
     118    compare (values.i11 , i11, __m128);
     119    compare (values.i12 , i12, __m128);
     120    compare (values.i13 , i13, __m128);
     121    compare (values.i14 , i14, __m128);
     122    compare (values.i15 , i15, __m128);
     123    compare (values.i16 , i16, __m128);
     124    compare (values.i17 , i17, __m128);
     125    compare (values.i18 , i18, __m128);
     126    compare (values.i19 , i19, __m128);
     127  }
     128  
     129  void
     130  fun_check_passing_m128_20_regs (__m128 i0 ATTRIBUTE_UNUSED, __m128 i1 ATTRIBUTE_UNUSED, __m128 i2 ATTRIBUTE_UNUSED, __m128 i3 ATTRIBUTE_UNUSED, __m128 i4 ATTRIBUTE_UNUSED, __m128 i5 ATTRIBUTE_UNUSED, __m128 i6 ATTRIBUTE_UNUSED, __m128 i7 ATTRIBUTE_UNUSED, __m128 i8 ATTRIBUTE_UNUSED, __m128 i9 ATTRIBUTE_UNUSED, __m128 i10 ATTRIBUTE_UNUSED, __m128 i11 ATTRIBUTE_UNUSED, __m128 i12 ATTRIBUTE_UNUSED, __m128 i13 ATTRIBUTE_UNUSED, __m128 i14 ATTRIBUTE_UNUSED, __m128 i15 ATTRIBUTE_UNUSED, __m128 i16 ATTRIBUTE_UNUSED, __m128 i17 ATTRIBUTE_UNUSED, __m128 i18 ATTRIBUTE_UNUSED, __m128 i19 ATTRIBUTE_UNUSED)
     131  {
     132    /* Check register contents.  */
     133    check_m128_arguments;
     134  }
     135  
     136  
     137  #define def_check_int_passing8(_i0, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _func1, _func2, TYPE) \
     138    values.i0.TYPE[0] = _i0; \
     139    values.i1.TYPE[0] = _i1; \
     140    values.i2.TYPE[0] = _i2; \
     141    values.i3.TYPE[0] = _i3; \
     142    values.i4.TYPE[0] = _i4; \
     143    values.i5.TYPE[0] = _i5; \
     144    values.i6.TYPE[0] = _i6; \
     145    values.i7.TYPE[0] = _i7; \
     146    WRAP_CALL(_func1) (_i0, _i1, _i2, _i3, _i4, _i5, _i6, _i7); \
     147    \
     148    clear_float_registers; \
     149    fregs.F0.TYPE[0] = _i0; \
     150    fregs.F1.TYPE[0] = _i1; \
     151    fregs.F2.TYPE[0] = _i2; \
     152    fregs.F3.TYPE[0] = _i3; \
     153    fregs.F4.TYPE[0] = _i4; \
     154    fregs.F5.TYPE[0] = _i5; \
     155    fregs.F6.TYPE[0] = _i6; \
     156    fregs.F7.TYPE[0] = _i7; \
     157    num_fregs = 8; \
     158    WRAP_CALL(_func2) (_i0, _i1, _i2, _i3, _i4, _i5, _i6, _i7);
     159  
     160  #define def_check_int_passing20(_i0, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, _i9, _i10, _i11, _i12, _i13, _i14, _i15, _i16, _i17, _i18, _i19, _func1, _func2, TYPE) \
     161    values.i0.TYPE[0] = _i0; \
     162    values.i1.TYPE[0] = _i1; \
     163    values.i2.TYPE[0] = _i2; \
     164    values.i3.TYPE[0] = _i3; \
     165    values.i4.TYPE[0] = _i4; \
     166    values.i5.TYPE[0] = _i5; \
     167    values.i6.TYPE[0] = _i6; \
     168    values.i7.TYPE[0] = _i7; \
     169    values.i8.TYPE[0] = _i8; \
     170    values.i9.TYPE[0] = _i9; \
     171    values.i10.TYPE[0] = _i10; \
     172    values.i11.TYPE[0] = _i11; \
     173    values.i12.TYPE[0] = _i12; \
     174    values.i13.TYPE[0] = _i13; \
     175    values.i14.TYPE[0] = _i14; \
     176    values.i15.TYPE[0] = _i15; \
     177    values.i16.TYPE[0] = _i16; \
     178    values.i17.TYPE[0] = _i17; \
     179    values.i18.TYPE[0] = _i18; \
     180    values.i19.TYPE[0] = _i19; \
     181    WRAP_CALL(_func1) (_i0, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, _i9, _i10, _i11, _i12, _i13, _i14, _i15, _i16, _i17, _i18, _i19); \
     182    \
     183    clear_float_registers; \
     184    fregs.F0.TYPE[0] = _i0; \
     185    fregs.F1.TYPE[0] = _i1; \
     186    fregs.F2.TYPE[0] = _i2; \
     187    fregs.F3.TYPE[0] = _i3; \
     188    fregs.F4.TYPE[0] = _i4; \
     189    fregs.F5.TYPE[0] = _i5; \
     190    fregs.F6.TYPE[0] = _i6; \
     191    fregs.F7.TYPE[0] = _i7; \
     192    num_fregs = 8; \
     193    WRAP_CALL(_func2) (_i0, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, _i9, _i10, _i11, _i12, _i13, _i14, _i15, _i16, _i17, _i18, _i19);
     194  
     195  void
     196  test_m64_on_stack ()
     197  {
     198    __m64 x[8];
     199    int i;
     200    for (i = 0; i < 8; i++)
     201      x[i] = (__m64){32+i, 0};
     202    pass = "m64-8";
     203    def_check_int_passing8(x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], fun_check_passing_m64_8_values, fun_check_passing_m64_8_regs, _m64);
     204  }
     205  
     206  void
     207  test_too_many_m64 ()
     208  {
     209    __m64 x[20];
     210    int i;
     211    for (i = 0; i < 20; i++)
     212      x[i] = (__m64){32+i, 0};
     213    pass = "m64-20";
     214    def_check_int_passing20(x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9], x[10], x[11], x[12], x[13], x[14], x[15], x[16], x[17], x[18], x[19], fun_check_passing_m64_20_values, fun_check_passing_m64_20_regs, _m64);
     215  }
     216  
     217  void
     218  test_m128_on_stack ()
     219  {
     220    __m128 x[8];
     221    int i;
     222    for (i = 0; i < 8; i++)
     223      x[i] = (__m128){32+i, 0, 0, 0};
     224    pass = "m128-8";
     225    def_check_int_passing8(x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], fun_check_passing_m128_8_values, fun_check_passing_m128_8_regs, _m128);
     226  }
     227  
     228  void
     229  test_too_many_m128 ()
     230  {
     231    __m128 x[20];
     232    int i;
     233    for (i = 0; i < 20; i++)
     234      x[i] = (__m128){32+i, 0, 0, 0};
     235    pass = "m128-20";
     236    def_check_int_passing20(x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9], x[10], x[11], x[12], x[13], x[14], x[15], x[16], x[17], x[18], x[19], fun_check_passing_m128_20_values, fun_check_passing_m128_20_regs, _m128);
     237  }
     238  
     239  int
     240  main (void)
     241  {
     242    test_m64_on_stack ();
     243    test_too_many_m64 ();
     244    test_m128_on_stack ();
     245    test_too_many_m128 ();
     246    if (failed)
     247      abort ();
     248    return 0;
     249  }