1  #include <arm_neon.h>
       2  #include "arm-neon-ref.h"
       3  #include "compute-ref-data.h"
       4  
       5  /* Expected results.  */
       6  VECT_VAR_DECL(expected,int,32,4) [] = { 0x8000, 0x8000, 0x8000, 0x8000 };
       7  VECT_VAR_DECL(expected,int,64,2) [] = { 0x4000, 0x4000 };
       8  
       9  /* Expected results when saturation occurs.  */
      10  VECT_VAR_DECL(expected2,int,32,4) [] = { 0x7fffffff, 0x7fffffff,
      11  					 0x7fffffff, 0x7fffffff };
      12  VECT_VAR_DECL(expected2,int,64,2) [] = { 0x7fffffffffffffff,
      13  					 0x7fffffffffffffff };
      14  
      15  #define INSN_NAME vqdmull
      16  #define TEST_MSG "VQDMULL_LANE"
      17  
      18  #define FNNAME1(NAME) exec_ ## NAME
      19  #define FNNAME(NAME) FNNAME1(NAME)
      20  
      21  void FNNAME (INSN_NAME) (void)
      22  {
      23    int i;
      24  
      25    /* vector_res = vqdmull_lane(vector,vector2,lane), then store the result.  */
      26  #define TEST_VQDMULL_LANE2(INSN, T1, T2, W, W2, N, L, CMT) \
      27    Set_Neon_Cumulative_Sat(0, VECT_VAR(vector_res, T1, W2, N));		\
      28    VECT_VAR(vector_res, T1, W2, N) =					\
      29      INSN##_lane_##T2##W(VECT_VAR(vector, T1, W, N),			\
      30  			VECT_VAR(vector2, T1, W, N),			\
      31  			L);						\
      32    vst1q_##T2##W2(VECT_VAR(result, T1, W2, N),				\
      33  		 VECT_VAR(vector_res, T1, W2, N))
      34  
      35    /* Two auxliary macros are necessary to expand INSN.  */
      36  #define TEST_VQDMULL_LANE1(INSN, T1, T2, W, W2, N, L, CMT) \
      37    TEST_VQDMULL_LANE2(INSN, T1, T2, W, W2, N, L, CMT)
      38  
      39  #define TEST_VQDMULL_LANE(T1, T2, W, W2, N, L, CMT) \
      40    TEST_VQDMULL_LANE1(INSN_NAME, T1, T2, W, W2, N, L, CMT)
      41  
      42    DECL_VARIABLE(vector, int, 16, 4);
      43    DECL_VARIABLE(vector, int, 32, 2);
      44    DECL_VARIABLE(vector2, int, 16, 4);
      45    DECL_VARIABLE(vector2, int, 32, 2);
      46  
      47    DECL_VARIABLE(vector_res, int, 32, 4);
      48    DECL_VARIABLE(vector_res, int, 64, 2);
      49  
      50    clean_results ();
      51  
      52    /* Initialize vector.  */
      53    VDUP(vector, , int, s, 16, 4, 0x1000);
      54    VDUP(vector, , int, s, 32, 2, 0x1000);
      55  
      56    /* Initialize vector2.  */
      57    VDUP(vector2, , int, s, 16, 4, 0x4);
      58    VDUP(vector2, , int, s, 32, 2, 0x2);
      59  
      60    /* Choose lane arbitrarily.  */
      61    TEST_VQDMULL_LANE(int, s, 16, 32, 4, 2, "");
      62    TEST_VQDMULL_LANE(int, s, 32, 64, 2, 1, "");
      63  
      64    CHECK(TEST_MSG, int, 32, 4, PRIx32, expected, "");
      65    CHECK(TEST_MSG, int, 64, 2, PRIx64, expected, "");
      66  
      67    VDUP(vector, , int, s, 16, 4, 0x8000);
      68    VDUP(vector2, , int, s, 16, 4, 0x8000);
      69    VDUP(vector, , int, s, 32, 2, 0x80000000);
      70    VDUP(vector2, , int, s, 32, 2, 0x80000000);
      71  
      72  #define TEST_MSG2 "with saturation"
      73    TEST_VQDMULL_LANE(int, s, 16, 32, 4, 2, TEST_MSG2);
      74    TEST_VQDMULL_LANE(int, s, 32, 64, 2, 1, TEST_MSG2);
      75  
      76    CHECK(TEST_MSG, int, 32, 4, PRIx32, expected2, TEST_MSG2);
      77    CHECK(TEST_MSG, int, 64, 2, PRIx64, expected2, TEST_MSG2);
      78  }
      79  
      80  int main (void)
      81  {
      82    FNNAME (INSN_NAME) ();
      83    return 0;
      84  }