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,16,4) [] = { 0x19, 0x19, 0x19, 0x19 };
       7  VECT_VAR_DECL(expected,int,32,2) [] = { 0x4, 0x4 };
       8  VECT_VAR_DECL(expected,int,16,8) [] = { 0x10, 0x10, 0x10, 0x10,
       9  					0x10, 0x10, 0x10, 0x10 };
      10  VECT_VAR_DECL(expected,int,32,4) [] = { 0xa, 0xa, 0xa, 0xa };
      11  
      12  /* Expected results when saturation occurs.  */
      13  VECT_VAR_DECL(expected2,int,16,4) [] = { 0x7fff, 0x7fff, 0x7fff, 0x7fff };
      14  VECT_VAR_DECL(expected2,int,32,2) [] = { 0x7fffffff, 0x7fffffff };
      15  VECT_VAR_DECL(expected2,int,16,8) [] = { 0x7fff, 0x7fff, 0x7fff, 0x7fff,
      16  					 0x7fff, 0x7fff, 0x7fff, 0x7fff };
      17  VECT_VAR_DECL(expected2,int,32,4) [] = { 0x7fffffff, 0x7fffffff,
      18  					 0x7fffffff, 0x7fffffff };
      19  
      20  #define INSN_NAME vqdmulh
      21  #define TEST_MSG "VQDMULH_N"
      22  #define FNNAME1(NAME) exec_ ## NAME ## _n
      23  #define FNNAME(NAME) FNNAME1(NAME)
      24  
      25  void FNNAME (INSN_NAME) (void)
      26  {
      27    int i;
      28  
      29    /* vector_res = vqdmulh_n(vector,val), then store the result.  */
      30  #define TEST_VQDMULH_N2(INSN, Q, T1, T2, W, N, L, CMT) \
      31    Set_Neon_Cumulative_Sat(0, VECT_VAR(vector_res, T1, W, N));	\
      32    VECT_VAR(vector_res, T1, W, N) =				\
      33      INSN##Q##_n_##T2##W(VECT_VAR(vector, T1, W, N),		\
      34  			L);					\
      35    vst1##Q##_##T2##W(VECT_VAR(result, T1, W, N),			\
      36  		    VECT_VAR(vector_res, T1, W, N))
      37  
      38    /* Two auxliary macros are necessary to expand INSN.  */
      39  #define TEST_VQDMULH_N1(INSN, Q, T1, T2, W, N, L, CMT) \
      40    TEST_VQDMULH_N2(INSN, Q, T1, T2, W, N, L, CMT)
      41  
      42  #define TEST_VQDMULH_N(Q, T1, T2, W, N, L, CMT)	\
      43    TEST_VQDMULH_N1(INSN_NAME, Q, T1, T2, W, N, L, CMT)
      44  
      45    DECL_VARIABLE(vector, int, 16, 4);
      46    DECL_VARIABLE(vector, int, 32, 2);
      47    DECL_VARIABLE(vector, int, 16, 8);
      48    DECL_VARIABLE(vector, int, 32, 4);
      49  
      50    DECL_VARIABLE(vector_res, int, 16, 4);
      51    DECL_VARIABLE(vector_res, int, 32, 2);
      52    DECL_VARIABLE(vector_res, int, 16, 8);
      53    DECL_VARIABLE(vector_res, int, 32, 4);
      54  
      55    clean_results ();
      56  
      57    /* Initialize vector.  */
      58    VDUP(vector, , int, s, 16, 4, 0x1000);
      59    VDUP(vector, , int, s, 32, 2, 0x100023);
      60    VDUP(vector, q, int, s, 16, 8, 0x1000);
      61    VDUP(vector, q, int, s, 32, 4, 0x100045);
      62  
      63    /* Choose multiplier arbitrarily.  */
      64    TEST_VQDMULH_N(, int, s, 16, 4, 0xCF, "");
      65    TEST_VQDMULH_N(, int, s, 32, 2, 0x2344, "");
      66    TEST_VQDMULH_N(q, int, s, 16, 8, 0x80, "");
      67    TEST_VQDMULH_N(q, int, s, 32, 4, 0x5422, "");
      68  
      69    CHECK (TEST_MSG, int, 16, 4, PRIx16, expected, "");
      70    CHECK (TEST_MSG, int, 32, 2, PRIx32, expected, "");
      71    CHECK (TEST_MSG, int, 16, 8, PRIx16, expected, "");
      72    CHECK (TEST_MSG, int, 32, 4, PRIx32, expected, "");
      73  
      74    /* Choose input values to trigger saturation.  */
      75    VDUP(vector, , int, s, 16, 4, 0x8000);
      76    VDUP(vector, , int, s, 32, 2, 0x80000000);
      77    VDUP(vector, q, int, s, 16, 8, 0x8000);
      78    VDUP(vector, q, int, s, 32, 4, 0x80000000);
      79  
      80  #define TEST_MSG2 " (check mul cumulative saturation)"
      81    TEST_VQDMULH_N(, int, s, 16, 4, 0x8000, TEST_MSG2);
      82    TEST_VQDMULH_N(, int, s, 32, 2, 0x80000000, TEST_MSG2);
      83    TEST_VQDMULH_N(q, int, s, 16, 8, 0x8000, TEST_MSG2);
      84    TEST_VQDMULH_N(q, int, s, 32, 4, 0x80000000, TEST_MSG2);
      85  
      86    CHECK (TEST_MSG, int, 16, 4, PRIx16, expected2, TEST_MSG2);
      87    CHECK (TEST_MSG, int, 32, 2, PRIx32, expected2, TEST_MSG2);
      88    CHECK (TEST_MSG, int, 16, 8, PRIx16, expected2, TEST_MSG2);
      89    CHECK (TEST_MSG, int, 32, 4, PRIx32, expected2, TEST_MSG2);
      90  }
      91  
      92  int main (void)
      93  {
      94    FNNAME (INSN_NAME) ();
      95    return 0;
      96  }