1  /* Test variable number of 128-bit vector arguments passed to functions.  */
       2  
       3  #include <stdio.h>
       4  #include "avx512fp16-xmm-check.h"
       5  #include "defines.h"
       6  #include "macros.h"
       7  #include "args.h"
       8  
       9  struct IntegerRegisters iregs;
      10  struct FloatRegisters fregs;
      11  
      12  /* This struct holds values for argument checking.  */
      13  struct 
      14  {
      15    XMM_T i0, i1, i2, i3, i4, i5, i6, i7, i8, i9;
      16  } values;
      17  
      18  char *pass;
      19  int failed = 0;
      20  
      21  #undef assert
      22  #define assert(c) do { \
      23    if (!(c)) {failed++; printf ("failed %s\n", pass); } \
      24  } while (0)
      25  
      26  #define compare(X1,X2,T) do { \
      27    assert (memcmp (&X1, &X2, sizeof (T)) == 0); \
      28  } while (0)
      29  
      30  void
      31  fun_check_passing_m128_varargs (__m128 i0, __m128 i1, __m128 i2,
      32  				__m128 i3, ...)
      33  {
      34    /* Check argument values.  */
      35    void **fp = __builtin_frame_address (0);
      36    void *ra = __builtin_return_address (0);
      37    __m128 *argp;
      38  
      39    compare (values.i0, i0, __m128);
      40    compare (values.i1, i1, __m128);
      41    compare (values.i2, i2, __m128);
      42    compare (values.i3, i3, __m128);
      43  
      44    /* Get the pointer to the return address on stack.  */
      45    while (*fp != ra)
      46      fp++;
      47  
      48    /* Skip the return address stack slot.  */
      49    argp = (__m128 *) (((char *) fp) + 8);
      50  
      51    /* Check __m128 arguments passed on stack.  */
      52    compare (values.i8, argp[0], __m128);
      53    compare (values.i9, argp[1], __m128);
      54  
      55    /* Check register contents.  */
      56    compare (fregs.xmm0, xmm_regs[0], __m128);
      57    compare (fregs.xmm1, xmm_regs[1], __m128);
      58    compare (fregs.xmm2, xmm_regs[2], __m128);
      59    compare (fregs.xmm3, xmm_regs[3], __m128);
      60    compare (fregs.xmm4, xmm_regs[4], __m128);
      61    compare (fregs.xmm5, xmm_regs[5], __m128);
      62    compare (fregs.xmm6, xmm_regs[6], __m128);
      63    compare (fregs.xmm7, xmm_regs[7], __m128);
      64  }
      65  
      66  void
      67  fun_check_passing_m128h_varargs (__m128h i0, __m128h i1, __m128h i2,
      68  				 __m128h i3, ...)
      69  {
      70    /* Check argument values.  */
      71    void **fp = __builtin_frame_address (0);
      72    void *ra = __builtin_return_address (0);
      73    __m128h *argp;
      74  
      75    compare (values.i0, i0, __m128h);
      76    compare (values.i1, i1, __m128h);
      77    compare (values.i2, i2, __m128h);
      78    compare (values.i3, i3, __m128h);
      79  
      80    /* Get the pointer to the return address on stack.  */
      81    while (*fp != ra)
      82      fp++;
      83  
      84    /* Skip the return address stack slot.  */
      85    argp = (__m128h *) (((char *) fp) + 8);
      86  
      87    /* Check __m128h arguments passed on stack.  */
      88    compare (values.i8, argp[0], __m128h);
      89    compare (values.i9, argp[1], __m128h);
      90  
      91    /* Check register contents.  */
      92    compare (fregs.xmm0, xmm_regs[0], __m128h);
      93    compare (fregs.xmm1, xmm_regs[1], __m128h);
      94    compare (fregs.xmm2, xmm_regs[2], __m128h);
      95    compare (fregs.xmm3, xmm_regs[3], __m128h);
      96    compare (fregs.xmm4, xmm_regs[4], __m128h);
      97    compare (fregs.xmm5, xmm_regs[5], __m128h);
      98    compare (fregs.xmm6, xmm_regs[6], __m128h);
      99    compare (fregs.xmm7, xmm_regs[7], __m128h);
     100  }
     101  
     102  #define def_check_int_passing_varargs(_i0, _i1, _i2, _i3, _i4, _i5, \
     103  				      _i6, _i7, _i8, _i9, \
     104  				      _func, TYPE) \
     105    values.i0.TYPE[0] = _i0; \
     106    values.i1.TYPE[0] = _i1; \
     107    values.i2.TYPE[0] = _i2; \
     108    values.i3.TYPE[0] = _i3; \
     109    values.i4.TYPE[0] = _i4; \
     110    values.i5.TYPE[0] = _i5; \
     111    values.i6.TYPE[0] = _i6; \
     112    values.i7.TYPE[0] = _i7; \
     113    values.i8.TYPE[0] = _i8; \
     114    values.i9.TYPE[0] = _i9; \
     115    clear_float_registers; \
     116    fregs.F0.TYPE[0] = _i0; \
     117    fregs.F1.TYPE[0] = _i1; \
     118    fregs.F2.TYPE[0] = _i2; \
     119    fregs.F3.TYPE[0] = _i3; \
     120    fregs.F4.TYPE[0] = _i4; \
     121    fregs.F5.TYPE[0] = _i5; \
     122    fregs.F6.TYPE[0] = _i6; \
     123    fregs.F7.TYPE[0] = _i7; \
     124    WRAP_CALL(_func) (_i0, _i1, _i2, _i3, _i4, _i5, _i6, _i7, _i8, _i9);
     125  
     126  void
     127  test_m128_varargs (void)
     128  {
     129    __m128 x[10];
     130    int i;
     131    for (i = 0; i < 10; i++)
     132      x[i] = (__m128){32+i, 0, 0, 0};
     133    pass = "m128-varargs";
     134    def_check_int_passing_varargs (x[0], x[1], x[2], x[3], x[4], x[5],
     135  				 x[6], x[7], x[8], x[9],
     136  				 fun_check_passing_m128_varargs,
     137  				 _m128);
     138  }
     139  
     140  void
     141  test_m128h_varargs (void)
     142  {
     143    __m128h x[10];
     144    int i;
     145    for (i = 0; i < 10; i++)
     146      x[i] = (__m128h) {
     147          1.1f16 + i, 2.2f16 + i, 3.3f16 + i, 4.4f16 + i,
     148  	5.5f16 + i, 6.6f16 + i, 7.7f16 + i, 8.8f16 + i
     149      };
     150    pass = "m128h-varargs";
     151    def_check_int_passing_varargs (x[0], x[1], x[2], x[3], x[4], x[5],
     152  				 x[6], x[7], x[8], x[9],
     153  				 fun_check_passing_m128h_varargs,
     154  				 _m128h);
     155  }
     156  
     157  static void
     158  do_test (void)
     159  {
     160    test_m128_varargs ();
     161    test_m128h_varargs ();
     162    if (failed)
     163      abort ();
     164  }