1  /* { dg-skip-if "can't compile on arm." { arm*-*-* } } */
       2  /* { dg-do run { target { aarch64*-*-* } } } */
       3  /* { dg-additional-options "-O3 -march=armv8.2-a+dotprod" } */
       4  /* { dg-require-effective-target arm_v8_2a_dotprod_neon_hw } */
       5  
       6  #include <arm_neon.h>
       7  
       8  extern void abort();
       9  
      10  #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
      11  # define ORDER(x, y) y
      12  #else
      13  # define ORDER(x, y) x - y
      14  #endif
      15  
      16  #define P(n1,n2) n1,n1,n1,n1,n2,n2,n2,n2
      17  #define ARR(nm, p, ty, ...) ty nm##_##p = { __VA_ARGS__ }
      18  #define TEST(t1, t2, t3, f, r1, r2, n1, n2) \
      19  	ARR(f, x, t1, r1);		    \
      20  	ARR(f, y, t2, r2);		    \
      21  	t3 f##_##r = {0};		    \
      22  	f##_##r = f (f##_##r, f##_##x, f##_##y);  \
      23  	if (f##_##r[0] != n1 || f##_##r[1] != n2)   \
      24  	  abort ();
      25  
      26  #define TEST_LANE(t1, t2, t3, f, r1, r2, n1, n2, n3, n4) \
      27  	ARR(f, x, t1, r1);		    \
      28  	ARR(f, y, t2, r2);		    \
      29  	t3 f##_##rx = {0};		    \
      30  	f##_##rx = f (f##_##rx, f##_##x, f##_##y, ORDER (1, 0));  \
      31  	if (f##_##rx[0] != n1 || f##_##rx[1] != n2)   \
      32  	  abort ();				    \
      33  	t3 f##_##rx1 = {0};			    \
      34  	f##_##rx1 = f (f##_##rx1, f##_##x, f##_##y, ORDER (1, 1));  \
      35  	if (f##_##rx1[0] != n3 || f##_##rx1[1] != n4)   \
      36  	  abort ();
      37  
      38  #define Px(n1,n2,n3,n4) P(n1,n2),P(n3,n4)
      39  #define TEST_LANEQ(t1, t2, t3, f, r1, r2, n1, n2, n3, n4, n5, n6, n7, n8) \
      40  	ARR(f, x, t1, r1);		    \
      41  	ARR(f, y, t2, r2);		    \
      42  	t3 f##_##rx = {0};		    \
      43  	f##_##rx = f (f##_##rx, f##_##x, f##_##y, ORDER (3, 0));  \
      44  	if (f##_##rx[0] != n1 || f##_##rx[1] != n2)   \
      45  	  abort ();				    \
      46  	t3 f##_##rx1 = {0};			    \
      47  	f##_##rx1 = f (f##_##rx1, f##_##x, f##_##y, ORDER (3, 1));  \
      48  	if (f##_##rx1[0] != n3 || f##_##rx1[1] != n4)   \
      49  	  abort (); \
      50  	t3 f##_##rx2 = {0};				    \
      51  	f##_##rx2 = f (f##_##rx2, f##_##x, f##_##y, ORDER (3, 2));  \
      52  	if (f##_##rx2[0] != n5 || f##_##rx2[1] != n6)   \
      53  	  abort ();				    \
      54  	t3 f##_##rx3 = {0};			    \
      55  	f##_##rx3 = f (f##_##rx3, f##_##x, f##_##y, ORDER (3, 3));  \
      56  	if (f##_##rx3[0] != n7 || f##_##rx3[1] != n8)   \
      57  	  abort ();
      58  
      59  int
      60  main()
      61  {
      62    TEST (uint8x8_t, uint8x8_t, uint32x2_t, vdot_u32, P(1,2), P(2,3), 8, 24);
      63    TEST (int8x8_t, int8x8_t, int32x2_t, vdot_s32, P(1,2), P(-2,-3), -8, -24);
      64  
      65    TEST (uint8x16_t, uint8x16_t, uint32x4_t, vdotq_u32, P(1,2), P(2,3), 8, 24);
      66    TEST (int8x16_t, int8x16_t, int32x4_t, vdotq_s32, P(1,2), P(-2,-3), -8, -24);
      67  
      68    TEST_LANE (uint8x8_t, uint8x8_t, uint32x2_t, vdot_lane_u32, P(1,2), P(2,3), 8, 16, 12, 24);
      69    TEST_LANE (int8x8_t, int8x8_t, int32x2_t, vdot_lane_s32, P(1,2), P(-2,-3), -8, -16, -12, -24);
      70  
      71    TEST_LANE (uint8x16_t, uint8x8_t, uint32x4_t, vdotq_lane_u32, P(1,2), P(2,3), 8, 16, 12, 24);
      72    TEST_LANE (int8x16_t, int8x8_t, int32x4_t, vdotq_lane_s32, P(1,2), P(-2,-3), -8, -16, -12, -24);
      73  
      74    TEST_LANEQ (uint8x8_t, uint8x16_t, uint32x2_t, vdot_laneq_u32, P(1,2), Px(2,3,1,4), 8, 16, 12, 24, 4, 8, 16, 32);
      75    TEST_LANEQ (int8x8_t, int8x16_t, int32x2_t, vdot_laneq_s32, P(1,2), Px(-2,-3,-1,-4), -8, -16, -12, -24, -4, -8, -16, -32);
      76  
      77    TEST_LANEQ (uint8x16_t, uint8x16_t, uint32x4_t, vdotq_laneq_u32, Px(1,2,2,1), Px(2,3,1,4), 8, 16, 12, 24, 4, 8, 16, 32);
      78    TEST_LANEQ (int8x16_t, int8x16_t, int32x4_t, vdotq_laneq_s32, Px(1,2,2,1), Px(-2,-3,-1,-4), -8, -16, -12, -24, -4, -8, -16, -32);
      79  
      80    return 0;
      81  }