1  /* { dg-do run } */
       2  /* { dg-skip-if "" { arm*-*-* } } */
       3  
       4  #include <arm_neon.h>
       5  #include "arm-neon-ref.h"
       6  #include "compute-ref-data.h"
       7  
       8  /* Expected results with negative input.  */
       9  VECT_VAR_DECL(expected_neg,uint,8,16) [] = { 0xfe, 0xfe, 0xfe, 0xfe,
      10  					     0xfe, 0xfe, 0xfe, 0xfe,
      11  					     0x0, 0x0, 0x0, 0x0,
      12  					     0x0, 0x0, 0x0, 0x0 };
      13  VECT_VAR_DECL(expected_neg,uint,16,8) [] = { 0xfffd, 0xfffd, 0xfffd, 0xfffd,
      14  					     0x0, 0x0, 0x0, 0x0 };
      15  VECT_VAR_DECL(expected_neg,uint,32,4) [] = { 0xfffffffc, 0xfffffffc, 0x0, 0x0 };
      16  
      17  /* Expected results with max input value shifted by 1.  */
      18  VECT_VAR_DECL(expected_max_sh1,uint,8,16) [] = { 0x7f, 0x7f, 0x7f, 0x7f,
      19  						 0x7f, 0x7f, 0x7f, 0x7f,
      20  						 0xff, 0xff, 0xff, 0xff,
      21  						 0xff, 0xff, 0xff, 0xff };
      22  VECT_VAR_DECL(expected_max_sh1,uint,16,8) [] = { 0x7fff, 0x7fff, 0x7fff, 0x7fff,
      23  						 0xffff, 0xffff, 0xffff, 0xffff };
      24  VECT_VAR_DECL(expected_max_sh1,uint,32,4) [] = { 0x7fffffff, 0x7fffffff,
      25  						 0xffffffff, 0xffffffff };
      26  
      27  /* Expected results with max input value shifted by max amount.  */
      28  VECT_VAR_DECL(expected_max_shmax,uint,8,16) [] = { 0x7f, 0x7f, 0x7f, 0x7f,
      29  						   0x7f, 0x7f, 0x7f, 0x7f,
      30  						   0x80, 0x80, 0x80, 0x80,
      31  						   0x80, 0x80, 0x80, 0x80 };
      32  VECT_VAR_DECL(expected_max_shmax,uint,16,8) [] = { 0x7fff, 0x7fff, 0x7fff, 0x7fff,
      33  						   0x8000, 0x8000, 0x8000, 0x8000 };
      34  VECT_VAR_DECL(expected_max_shmax,uint,32,4) [] = { 0x7fffffff, 0x7fffffff,
      35  						   0x80000000, 0x80000000 };
      36  
      37  /* Expected results with min input value shifted by max amount.  */
      38  VECT_VAR_DECL(expected_min_shmax,uint,8,16) [] = { 0x80, 0x80, 0x80, 0x80,
      39  						   0x80, 0x80, 0x80, 0x80,
      40  						   0x0, 0x0, 0x0, 0x0,
      41  						   0x0, 0x0, 0x0, 0x0 };
      42  VECT_VAR_DECL(expected_min_shmax,uint,16,8) [] = { 0x8000, 0x8000, 0x8000, 0x8000,
      43  						   0x0, 0x0, 0x0, 0x0 };
      44  VECT_VAR_DECL(expected_min_shmax,uint,32,4) [] = { 0x80000000, 0x80000000,
      45  						   0x0, 0x0 };
      46  
      47  /* Expected results with inputs in usual range.  */
      48  VECT_VAR_DECL(expected,uint,8,16) [] = { 0x12, 0x12, 0x12, 0x12,
      49  					 0x12, 0x12, 0x12, 0x12,
      50  					 0x49, 0x49, 0x49, 0x49,
      51  					 0x49, 0x49, 0x49, 0x49 };
      52  VECT_VAR_DECL(expected,uint,16,8) [] = { 0x4321, 0x4321, 0x4321, 0x4321,
      53  					 0x0, 0x0, 0x0, 0x0 };
      54  VECT_VAR_DECL(expected,uint,32,4) [] = { 0xdeadbeef, 0xdeadbeef,
      55  					 0xdeadbf, 0xdeadbf };
      56  
      57  #define INSN vqrshrun_high_n
      58  #define TEST_MSG "VQRSHRUN_HIGH_N"
      59  
      60  #define FNNAME1(NAME) void exec_ ## NAME (void)
      61  #define FNNAME(NAME) FNNAME1(NAME)
      62  
      63  FNNAME (INSN)
      64  {
      65    /* Basic test: y=vqrshrun_high_n(x,v), then store the result.  */
      66  #define TEST_VQRSHRUN_HIGH_N2(INSN, T1, T2, W, W2, N, N2, V) \
      67    VECT_VAR(vector_res, uint, W2, N2) =			     \
      68      INSN##_##T2##W(VECT_VAR(vector1, uint, W2, N),	     \
      69  		   VECT_VAR(vector2, T1, W, N), V);	     \
      70    vst1q_u##W2(VECT_VAR(result, uint, W2, N2),		     \
      71  	      VECT_VAR(vector_res, uint, W2, N2));	     \
      72  
      73    /* Two auxliary macros are necessary to expand INSN */
      74  #define TEST_VQRSHRUN_HIGH_N1(INSN, T1, T2, W, W2, N, N2, V) \
      75    TEST_VQRSHRUN_HIGH_N2(INSN, T1, T2, W, W2, N, N2, V)
      76  
      77  #define TEST_VQRSHRUN_HIGH_N(T1, T2, W, W2, N, N2, V) \
      78    TEST_VQRSHRUN_HIGH_N1(INSN, T1, T2, W, W2, N, N2, V)
      79  
      80  
      81    DECL_VARIABLE(vector1, uint, 8, 8);
      82    DECL_VARIABLE(vector1, uint, 16, 4);
      83    DECL_VARIABLE(vector1, uint, 32, 2);
      84  
      85    /* vector is twice as large as vector_res.  */
      86    DECL_VARIABLE(vector2, int, 16, 8);
      87    DECL_VARIABLE(vector2, int, 32, 4);
      88    DECL_VARIABLE(vector2, int, 64, 2);
      89  
      90    DECL_VARIABLE(vector_res, uint, 8, 16);
      91    DECL_VARIABLE(vector_res, uint, 16, 8);
      92    DECL_VARIABLE(vector_res, uint, 32, 4);
      93  
      94    clean_results ();
      95  
      96    /* Fill input vector with negative values, to check saturation on
      97       limits.  */
      98    VDUP(vector1, , uint, u, 8, 8, -2);
      99    VDUP(vector1, , uint, u, 16, 4, -3);
     100    VDUP(vector1, , uint, u, 32, 2, -4);
     101  
     102    VDUP(vector2, q, int, s, 16, 8, -2);
     103    VDUP(vector2, q, int, s, 32, 4, -3);
     104    VDUP(vector2, q, int, s, 64, 2, -4);
     105  
     106    /* Choose shift amount arbitrarily.   */
     107  #define CMT " (negative input)"
     108    TEST_VQRSHRUN_HIGH_N(int, s, 16, 8, 8, 16, 3);
     109    TEST_VQRSHRUN_HIGH_N(int, s, 32, 16, 4, 8, 4);
     110    TEST_VQRSHRUN_HIGH_N(int, s, 64, 32, 2, 4, 2);
     111  
     112    CHECK(TEST_MSG, uint, 8, 16, PRIx8, expected_neg, CMT);
     113    CHECK(TEST_MSG, uint, 16, 8, PRIx16, expected_neg, CMT);
     114    CHECK(TEST_MSG, uint, 32, 4, PRIx32, expected_neg, CMT);
     115  
     116  
     117    /* Fill input vector with max value, to check saturation on
     118       limits.  */
     119    VDUP(vector1, , uint, u, 8, 8, 0x7F);
     120    VDUP(vector1, , uint, u, 16, 4, 0x7FFF);
     121    VDUP(vector1, , uint, u, 32, 2, 0x7FFFFFFFLL);
     122  
     123    VDUP(vector2, q, int, s, 16, 8, 0x7FFF);
     124    VDUP(vector2, q, int, s, 32, 4, 0x7FFFFFFF);
     125    VDUP(vector2, q, int, s, 64, 2, 0x7FFFFFFFFFFFFFFFLL);
     126  
     127    /* shift by 1.  */
     128  #undef CMT
     129  #define CMT " (check cumulative saturation: shift by 1)"
     130    TEST_VQRSHRUN_HIGH_N(int, s, 16, 8, 8, 16, 1);
     131    TEST_VQRSHRUN_HIGH_N(int, s, 32, 16, 4, 8, 1);
     132    TEST_VQRSHRUN_HIGH_N(int, s, 64, 32, 2, 4, 1);
     133  
     134    CHECK(TEST_MSG, uint, 8, 16, PRIx8, expected_max_sh1, CMT);
     135    CHECK(TEST_MSG, uint, 16, 8, PRIx16, expected_max_sh1, CMT);
     136    CHECK(TEST_MSG, uint, 32, 4, PRIx32, expected_max_sh1, CMT);
     137  
     138  
     139    /* shift by max.  */
     140  #undef CMT
     141  #define CMT " (check cumulative saturation: shift by max, positive input)"
     142    TEST_VQRSHRUN_HIGH_N(int, s, 16, 8, 8, 16, 8);
     143    TEST_VQRSHRUN_HIGH_N(int, s, 32, 16, 4, 8, 16);
     144    TEST_VQRSHRUN_HIGH_N(int, s, 64, 32, 2, 4, 32);
     145  
     146    CHECK(TEST_MSG, uint, 8, 16, PRIx8, expected_max_shmax, CMT);
     147    CHECK(TEST_MSG, uint, 16, 8, PRIx16, expected_max_shmax, CMT);
     148    CHECK(TEST_MSG, uint, 32, 4, PRIx32, expected_max_shmax, CMT);
     149  
     150  
     151    /* Fill input vector with min value, to check saturation on limits.  */
     152    VDUP(vector1, , uint, u, 8, 8, 0x80);
     153    VDUP(vector1, , uint, u, 16, 4, 0x8000);
     154    VDUP(vector1, , uint, u, 32, 2, 0x80000000LL);
     155  
     156    VDUP(vector2, q, int, s, 16, 8, 0x8000);
     157    VDUP(vector2, q, int, s, 32, 4, 0x80000000);
     158    VDUP(vector2, q, int, s, 64, 2, 0x8000000000000000LL);
     159  
     160    /* shift by max  */
     161  #undef CMT
     162  #define CMT " (check cumulative saturation: shift by max, negative input)"
     163    TEST_VQRSHRUN_HIGH_N(int, s, 16, 8, 8, 16, 8);
     164    TEST_VQRSHRUN_HIGH_N(int, s, 32, 16, 4, 8, 16);
     165    TEST_VQRSHRUN_HIGH_N(int, s, 64, 32, 2, 4, 32);
     166  
     167    CHECK(TEST_MSG, uint, 8, 16, PRIx8, expected_min_shmax, CMT);
     168    CHECK(TEST_MSG, uint, 16, 8, PRIx16, expected_min_shmax, CMT);
     169    CHECK(TEST_MSG, uint, 32, 4, PRIx32, expected_min_shmax, CMT);
     170  
     171  
     172    /* Fill input vector with positive values, to check normal case.  */
     173    VDUP(vector1, , uint, u, 8, 8, 0x12);
     174    VDUP(vector1, , uint, u, 16, 4, 0x4321);
     175    VDUP(vector1, , uint, u, 32, 2, 0xDEADBEEF);
     176  
     177    VDUP(vector2, q, int, s, 16, 8, 0x1234);
     178    VDUP(vector2, q, int, s, 32, 4, 0x87654321);
     179    VDUP(vector2, q, int, s, 64, 2, 0xDEADBEEF);
     180  
     181    /* shift arbitrary amount.  */
     182  #undef CMT
     183  #define CMT ""
     184    TEST_VQRSHRUN_HIGH_N(int, s, 16, 8, 8, 16, 6);
     185    TEST_VQRSHRUN_HIGH_N(int, s, 32, 16, 4, 8, 7);
     186    TEST_VQRSHRUN_HIGH_N(int, s, 64, 32, 2, 4, 8);
     187  
     188    CHECK(TEST_MSG, uint, 8, 16, PRIx8, expected, CMT);
     189    CHECK(TEST_MSG, uint, 16, 8, PRIx16, expected, CMT);
     190    CHECK(TEST_MSG, uint, 32, 4, PRIx32, expected, CMT);
     191  }
     192  
     193  int main (void)
     194  {
     195    exec_vqrshrun_high_n ();
     196    return 0;
     197  }