1  /* { dg-do run { target avx512fp16 } } */
       2  /* { dg-options "-O2 -mavx512fp16 -mavx512dq" } */
       3  
       4  #define AVX512FP16
       5  #include "avx512fp16-helper.h"
       6  
       7  #define N_ELEMS (AVX512F_LEN / 16)
       8  
       9  void NOINLINE
      10  EMULATE(c_fmul_pch) (V512 * dest, V512 op1, V512 op2,
      11  		  __mmask16 k, int zero_mask, int c_flag)
      12  {
      13    V512 v1, v2, v3, v4, v5, v6, v7, v8;
      14    int i;
      15    int invert = 1;
      16    if (c_flag == 1)
      17      invert = -1;
      18  
      19    unpack_ph_2twops(op1, &v1, &v2);
      20    unpack_ph_2twops(op2, &v3, &v4);
      21    unpack_ph_2twops(*dest, &v7, &v8);
      22  
      23    for (i = 0; i < 16; i++) {
      24        if (((1 << (i / 2)) & k) == 0) {
      25  	  if (zero_mask) {
      26  	      v5.f32[i] = 0;
      27  	  }
      28  	  else {
      29  	      v5.u32[i] = v7.u32[i];
      30  	  }
      31        }
      32        else {
      33  	  if ((i % 2) == 0) {
      34  	      v5.f32[i] = v1.f32[i] * v3.f32[i]
      35  		- invert * (v1.f32[i+1] * v3.f32[i+1]);
      36  	  }
      37  	  else {
      38  	      v5.f32[i] = v1.f32[i] * v3.f32[i-1]
      39  		+ invert * (v1.f32[i-1] * v3.f32[i]);
      40  
      41  	  }
      42        }
      43        if (((1 << (i / 2 + 8)) & k) == 0) {
      44  	  if (zero_mask) {
      45  	      v6.f32[i] = 0;
      46  	  }
      47  	  else {
      48  	      v6.u32[i] = v8.u32[i];
      49  	  }
      50        }
      51        else {
      52  	  if ((i % 2) == 0) {
      53  	      v6.f32[i] = v2.f32[i] * v4.f32[i]
      54  		- invert * (v2.f32[i+1] * v4.f32[i+1]);
      55  	  }
      56  	  else {
      57  	      v6.f32[i] = v2.f32[i] * v4.f32[i-1]
      58  		+ invert * (v2.f32[i-1] * v4.f32[i]);
      59  	  }
      60  
      61        }
      62     }
      63  
      64    *dest = pack_twops_2ph(v5, v6);
      65  }
      66  
      67  void
      68  TEST (void)
      69  {
      70    V512 res;
      71    V512 exp;
      72  
      73    init_src();
      74  
      75    EMULATE(c_fmul_pch)(&exp, src1, src2, NET_CMASK, 0, 1);
      76    HF(res) = INTRINSIC (_fcmul_pch) (HF(src1), HF(src2));
      77    CHECK_RESULT (&res, &exp, N_ELEMS, _fcmul_pch);
      78  
      79    init_dest(&res, &exp);
      80    EMULATE(c_fmul_pch)(&exp, src1, src2, HALF_MASK, 0, 1);
      81    HF(res) = INTRINSIC (_mask_fcmul_pch) (HF(res) ,HALF_MASK, HF(src1),
      82  					 HF(src2));
      83    CHECK_RESULT (&res, &exp, N_ELEMS, _mask_fcmul_pch);
      84  
      85    EMULATE(c_fmul_pch)(&exp, src1, src2, HALF_MASK, 1, 1);
      86    HF(res) = INTRINSIC (_maskz_fcmul_pch) ( HALF_MASK, HF(src1),
      87  					   HF(src2));
      88    CHECK_RESULT (&res, &exp, N_ELEMS, _maskz_fcmul_pch);
      89  
      90  #if AVX512F_LEN == 512
      91    EMULATE(c_fmul_pch)(&exp, src1, src2, NET_CMASK, 0, 1);
      92    HF(res) = INTRINSIC (_fcmul_round_pch) (HF(src1), HF(src2), _ROUND_NINT);
      93    CHECK_RESULT (&res, &exp, N_ELEMS, _fcmul_round_pch);
      94  
      95    init_dest(&res, &exp);
      96    EMULATE(c_fmul_pch)(&exp, src1, src2, HALF_MASK, 0, 1);
      97    HF(res) = INTRINSIC (_mask_fcmul_round_pch) (HF(res) ,HALF_MASK, HF(src1),
      98  					 HF(src2), _ROUND_NINT);
      99    CHECK_RESULT (&res, &exp, N_ELEMS, _mask_fcmul_round_pch);
     100  
     101    EMULATE(c_fmul_pch)(&exp, src1, src2, HALF_MASK, 1, 1);
     102    HF(res) = INTRINSIC (_maskz_fcmul_round_pch) ( HALF_MASK, HF(src1),
     103  					   HF(src2), _ROUND_NINT);
     104    CHECK_RESULT (&res, &exp, N_ELEMS, _maskz_fcmul_round_pch);
     105  #endif
     106  
     107    if (n_errs != 0) {
     108        abort ();
     109    }
     110  }
     111