1  /* { dg-do run } */
       2  /* { dg-require-effective-target arm_v8_2a_fp16_scalar_hw } */
       3  /* { dg-add-options arm_v8_2a_fp16_neon } */
       4  /* { dg-skip-if "" { arm*-*-* } } */
       5  
       6  #include <arm_neon.h>
       7  #include "arm-neon-ref.h"
       8  #include "compute-ref-data.h"
       9  
      10  #define FP16_C(a) ((__fp16) a)
      11  #define A0 FP16_C (123.4)
      12  #define B0 FP16_C (-5.8)
      13  #define C0 FP16_C (-3.8)
      14  #define D0 FP16_C (10)
      15  
      16  #define A1 FP16_C (12.4)
      17  #define B1 FP16_C (-5.8)
      18  #define C1 FP16_C (90.8)
      19  #define D1 FP16_C (24)
      20  
      21  #define A2 FP16_C (23.4)
      22  #define B2 FP16_C (-5.8)
      23  #define C2 FP16_C (8.9)
      24  #define D2 FP16_C (4)
      25  
      26  #define E0 FP16_C (3.4)
      27  #define F0 FP16_C (-55.8)
      28  #define G0 FP16_C (-31.8)
      29  #define H0 FP16_C (2)
      30  
      31  #define E1 FP16_C (123.4)
      32  #define F1 FP16_C (-5.8)
      33  #define G1 FP16_C (-3.8)
      34  #define H1 FP16_C (102)
      35  
      36  #define E2 FP16_C (4.9)
      37  #define F2 FP16_C (-15.8)
      38  #define G2 FP16_C (39.8)
      39  #define H2 FP16_C (49)
      40  
      41  extern void abort ();
      42  
      43  float16_t src1[8] = { A0, B0, C0, D0, E0, F0, G0, H0 };
      44  float16_t src2[8] = { A1, B1, C1, D1, E1, F1, G1, H1 };
      45  VECT_VAR_DECL (src3, float, 16, 4) [] = { A2, B2, C2, D2 };
      46  VECT_VAR_DECL (src3, float, 16, 8) [] = { A2, B2, C2, D2, E2, F2, G2, H2 };
      47  
      48  /* Expected results for vfmah_lane_f16.  */
      49  uint16_t expected[4] = { 0x5E76 /* A0 + A1 * A2.  */,
      50  			 0x4EF6 /* B0 + B1 * B2.  */,
      51  			 0x6249 /* C0 + C1 * C2.  */,
      52  			 0x56A0 /* D0 + D1 * D2.  */ };
      53  
      54  /* Expected results for vfmah_laneq_f16.  */
      55  uint16_t expected_laneq[8] = { 0x5E76 /* A0 + A1 * A2.  */,
      56  			       0x4EF6 /* B0 + B1 * B2.  */,
      57  			       0x6249 /* C0 + C1 * C2.  */,
      58  			       0x56A0 /* D0 + D1 * D2.  */,
      59  			       0x60BF /* E0 + E1 * E2.  */,
      60  			       0x507A /* F0 + F1 * F2.  */,
      61  			       0xD9B9 /* G0 + G1 * G2.  */,
      62  			       0x6CE2 /* H0 + H1 * H2.  */ };
      63  
      64  /* Expected results for vfmsh_lane_f16.  */
      65  uint16_t expected_fms[4] = { 0xD937 /* A0 + -A1 * A2.  */,
      66  			     0xD0EE /* B0 + -B1 * B2.  */,
      67  			     0xE258 /* C0 + -C1 * C2.  */,
      68  			     0xD560 /* D0 + -D1 * D2.  */ };
      69  
      70  /* Expected results for vfmsh_laneq_f16.  */
      71  uint16_t expected_fms_laneq[8] = { 0xD937 /* A0 + -A1 * A2.  */,
      72  				   0xD0EE /* B0 + -B1 * B2.  */,
      73  				   0xE258 /* C0 + -C1 * C2.  */,
      74  				   0xD560 /* D0 + -D1 * D2.  */,
      75  				   0xE0B2 /* E0 + -E1 * E2.  */,
      76  				   0xD89C /* F0 + -F1 * F2.  */,
      77  				   0x5778 /* G0 + -G1 * G2.  */,
      78  				   0xECE1 /* H0 + -H1 * H2.  */ };
      79  
      80  void exec_vfmash_lane_f16 (void)
      81  {
      82  #define CHECK_LANE(N) \
      83    ret = vfmah_lane_f16 (src1[N], src2[N], VECT_VAR (vsrc3, float, 16, 4), N);\
      84    if (*(uint16_t *) &ret != expected[N])\
      85      abort ();
      86  
      87    DECL_VARIABLE(vsrc3, float, 16, 4);
      88    VLOAD (vsrc3, src3, , float, f, 16, 4);
      89    float16_t ret;
      90    CHECK_LANE(0)
      91    CHECK_LANE(1)
      92    CHECK_LANE(2)
      93    CHECK_LANE(3)
      94  
      95  #undef CHECK_LANE
      96  #define CHECK_LANE(N) \
      97    ret = vfmah_laneq_f16 (src1[N], src2[N], VECT_VAR (vsrc3, float, 16, 8), N);\
      98    if (*(uint16_t *) &ret != expected_laneq[N]) \
      99  	  abort ();
     100  
     101    DECL_VARIABLE(vsrc3, float, 16, 8);
     102    VLOAD (vsrc3, src3, q, float, f, 16, 8);
     103    CHECK_LANE(0)
     104    CHECK_LANE(1)
     105    CHECK_LANE(2)
     106    CHECK_LANE(3)
     107    CHECK_LANE(4)
     108    CHECK_LANE(5)
     109    CHECK_LANE(6)
     110    CHECK_LANE(7)
     111  
     112  #undef CHECK_LANE
     113  #define CHECK_LANE(N) \
     114    ret = vfmsh_lane_f16 (src1[N], src2[N], VECT_VAR (vsrc3, float, 16, 4), N);\
     115    if (*(uint16_t *) &ret != expected_fms[N])\
     116      abort ();
     117  
     118    CHECK_LANE(0)
     119    CHECK_LANE(1)
     120    CHECK_LANE(2)
     121  
     122  #undef CHECK_LANE
     123  #define CHECK_LANE(N) \
     124    ret = vfmsh_laneq_f16 (src1[N], src2[N], VECT_VAR (vsrc3, float, 16, 8), N);\
     125    if (*(uint16_t *) &ret != expected_fms_laneq[N]) \
     126  	  abort ();
     127  
     128    CHECK_LANE(0)
     129    CHECK_LANE(1)
     130    CHECK_LANE(2)
     131    CHECK_LANE(3)
     132    CHECK_LANE(4)
     133    CHECK_LANE(5)
     134    CHECK_LANE(6)
     135    CHECK_LANE(7)
     136  }
     137  
     138  int
     139  main (void)
     140  {
     141    exec_vfmash_lane_f16 ();
     142    return 0;
     143  }