1  #include <arm_neon.h>
       2  #include "arm-neon-ref.h"
       3  #include "compute-ref-data.h"
       4  
       5  
       6  /* Expected results with negative input.  */
       7  VECT_VAR_DECL(expected_neg,uint,8,8) [] = { 0x0, 0x0, 0x0, 0x0,
       8  					    0x0, 0x0, 0x0, 0x0 };
       9  VECT_VAR_DECL(expected_neg,uint,16,4) [] = { 0x0, 0x0, 0x0, 0x0 };
      10  VECT_VAR_DECL(expected_neg,uint,32,2) [] = { 0x0, 0x0 };
      11  
      12  /* Expected results with max input value shifted by 1.  */
      13  VECT_VAR_DECL(expected_max_sh1,uint,8,8) [] = { 0xff, 0xff, 0xff, 0xff,
      14  						0xff, 0xff, 0xff, 0xff };
      15  VECT_VAR_DECL(expected_max_sh1,uint,16,4) [] = { 0xffff, 0xffff,
      16  						 0xffff, 0xffff };
      17  VECT_VAR_DECL(expected_max_sh1,uint,32,2) [] = { 0xffffffff, 0xffffffff };
      18  VECT_VAR_DECL(expected_max_sh1,uint,64,1) [] = { 0x3333333333333333 };
      19  
      20  /* Expected results.  */
      21  VECT_VAR_DECL(expected,uint,8,8) [] = { 0x48, 0x48, 0x48, 0x48,
      22  					0x48, 0x48, 0x48, 0x48 };
      23  VECT_VAR_DECL(expected,uint,16,4) [] = { 0x0, 0x0, 0x0, 0x0 };
      24  VECT_VAR_DECL(expected,uint,32,2) [] = { 0xdeadbe, 0xdeadbe };
      25  
      26  
      27  #define INSN vqshrun_n
      28  #define TEST_MSG "VQSHRUN_N"
      29  
      30  #define FNNAME1(NAME) void exec_ ## NAME (void)
      31  #define FNNAME(NAME) FNNAME1(NAME)
      32  
      33  FNNAME (INSN)
      34  {
      35    /* Basic test: y=vqshrun_n(x,v), then store the result.  */
      36  #define TEST_VQSHRUN_N2(INSN, T1, T2, W, W2, N, V, CMT) \
      37    Set_Neon_Cumulative_Sat(0, VECT_VAR(vector_res, uint, W2, N));	\
      38    VECT_VAR(vector_res, uint, W2, N) =					\
      39      INSN##_##T2##W(VECT_VAR(vector, T1, W, N),				\
      40  		   V);							\
      41    vst1_u##W2(VECT_VAR(result, uint, W2, N),				\
      42  	     VECT_VAR(vector_res, uint, W2, N));
      43  
      44    /* Two auxliary macros are necessary to expand INSN */
      45  #define TEST_VQSHRUN_N1(INSN, T1, T2, W, W2, N, V, CMT) \
      46    TEST_VQSHRUN_N2(INSN, T1, T2, W, W2, N, V, CMT)
      47  
      48  #define TEST_VQSHRUN_N(T1, T2, W, W2, N, V, CMT) \
      49    TEST_VQSHRUN_N1(INSN, T1, T2, W, W2, N, V, CMT)
      50  
      51  
      52    /* vector is twice as large as vector_res.  */
      53    DECL_VARIABLE(vector, int, 16, 8);
      54    DECL_VARIABLE(vector, int, 32, 4);
      55    DECL_VARIABLE(vector, int, 64, 2);
      56  
      57    DECL_VARIABLE(vector_res, uint, 8, 8);
      58    DECL_VARIABLE(vector_res, uint, 16, 4);
      59    DECL_VARIABLE(vector_res, uint, 32, 2);
      60  
      61    clean_results ();
      62  
      63    /* Fill input vector with negative values, to check saturation on
      64       limits.  */
      65    VDUP(vector, q, int, s, 16, 8, -2);
      66    VDUP(vector, q, int, s, 32, 4, -3);
      67    VDUP(vector, q, int, s, 64, 2, -4);
      68  
      69    /* Choose shift amount arbitrarily.  */
      70  #define CMT " (negative input)"
      71    TEST_VQSHRUN_N(int, s, 16, 8, 8, 3, CMT);
      72    TEST_VQSHRUN_N(int, s, 32, 16, 4, 4, CMT);
      73    TEST_VQSHRUN_N(int, s, 64, 32, 2, 2, CMT);
      74  
      75    CHECK(TEST_MSG, uint, 8, 8, PRIx8, expected_neg, CMT);
      76    CHECK(TEST_MSG, uint, 16, 4, PRIx16, expected_neg, CMT);
      77    CHECK(TEST_MSG, uint, 32, 2, PRIx32, expected_neg, CMT);
      78  
      79    
      80    /* Fill input vector with max value, to check saturation on
      81       limits.  */
      82    VDUP(vector, q, int, s, 16, 8, 0x7FFF);
      83    VDUP(vector, q, int, s, 32, 4, 0x7FFFFFFF);
      84    VDUP(vector, q, int, s, 64, 2, 0x7FFFFFFFFFFFFFFFLL);
      85  
      86  #undef CMT
      87  #define CMT " (check cumulative saturation)"
      88    TEST_VQSHRUN_N(int, s, 16, 8, 8, 1, CMT);
      89    TEST_VQSHRUN_N(int, s, 32, 16, 4, 1, CMT);
      90    TEST_VQSHRUN_N(int, s, 64, 32, 2, 1, CMT);
      91  
      92    CHECK(TEST_MSG, uint, 8, 8, PRIx8, expected_max_sh1, CMT);
      93    CHECK(TEST_MSG, uint, 16, 4, PRIx16, expected_max_sh1, CMT);
      94    CHECK(TEST_MSG, uint, 32, 2, PRIx32, expected_max_sh1, CMT);
      95  
      96    
      97    /* Fill input vector with positive values, to check normal case.  */
      98    VDUP(vector, q, int, s, 16, 8, 0x1234);
      99    VDUP(vector, q, int, s, 32, 4, 0x87654321);
     100    VDUP(vector, q, int, s, 64, 2, 0xDEADBEEF);
     101  
     102  #undef CMT
     103  #define CMT ""
     104    TEST_VQSHRUN_N(int, s, 16, 8, 8, 6, CMT);
     105    TEST_VQSHRUN_N(int, s, 32, 16, 4, 7, CMT);
     106    TEST_VQSHRUN_N(int, s, 64, 32, 2, 8, CMT);
     107  
     108    CHECK(TEST_MSG, uint, 8, 8, PRIx8, expected, CMT);
     109    CHECK(TEST_MSG, uint, 16, 4, PRIx16, expected, CMT);
     110    CHECK(TEST_MSG, uint, 32, 2, PRIx32, expected, CMT);
     111  }
     112  
     113  int main (void)
     114  {
     115    exec_vqshrun_n ();
     116    return 0;
     117  }