1 /* { dg-do run } */
2 /* { dg-require-effective-target s390_vxe2 } */
3 /* { dg-options "-O3 -mzarch -march=arch13 -mzvector --save-temps" } */
4 
5 #include <string.h>
6 #include <vecintrin.h>
7 
8 typedef vector unsigned char uv16qi;
9 
10 uv16qi test_vec = (uv16qi){ 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 };
11 
12 #define NUM_TEST_LENGTHS 3
13 
14 unsigned int test_len[NUM_TEST_LENGTHS] = { 0, 12, 18 };
15 
16 
17 /* Proceeding from left to right, the specified number (LEN+1) of
18    rightmost bytes from SOURCE are stored in TARGET.  */
19 void __attribute__((noinline, noclone, target ("arch=zEC12")))
emul(unsigned char * source,unsigned char * target,unsigned int len)20 emul (unsigned char *source, unsigned char *target, unsigned int len)
21 {
22   int start = 15 - len;
23   if (start < 0)
24     start = 0;
25   for (int s = start, t = 0; s < 16; s++, t++)
26     target[t] = source[s];
27 }
28 
29 void __attribute__((noinline, noclone))
vec_store_len_r_reg(uv16qi s,unsigned char * t,unsigned int len)30 vec_store_len_r_reg (uv16qi s, unsigned char *t, unsigned int len)
31 {
32   vec_store_len_r (s, t, len);
33 }
34 
35 void __attribute__((noinline, noclone))
vec_store_len_r_mem(uv16qi * s,unsigned char * t,unsigned int * len)36 vec_store_len_r_mem (uv16qi *s, unsigned char *t, unsigned int *len)
37 {
38   vec_store_len_r (*s, t, *len);
39 }
40 
41 #define GEN_CONST_FUNC(CONST)					\
42   static void inline						\
43   vec_store_len_r_const##CONST (uv16qi s, unsigned char *t)	\
44   {								\
45     vec_store_len_r (s, t, CONST);				\
46   }
47 
48 #define GEN_CONST_TEST(CONST)					\
49   memset (exp_result, 0, 16);					\
50   emul ((unsigned char*)&test_vec, exp_result, CONST);		\
51   memset (result, 0, 16);					\
52   vec_store_len_r_const##CONST (test_vec, result);		\
53   if (memcmp (result, exp_result, 16) != 0)			\
54     __builtin_abort ();
55 
56 GEN_CONST_FUNC(0)
57 GEN_CONST_FUNC(12)
58 GEN_CONST_FUNC(18)
59 
60 int
main()61 main ()
62 {
63   unsigned char exp_result[16];
64   unsigned char result[16];
65 
66   for (int i = 0; i < NUM_TEST_LENGTHS; i++)
67     {
68       memset (exp_result, 0, 16);
69 
70       emul ((unsigned char*)&test_vec, exp_result, test_len[i]);
71 
72       memset (result, 0, 16);
73       vec_store_len_r_reg (test_vec, result, test_len[i]);
74       if (memcmp (result, exp_result, 16) != 0)
75 	__builtin_abort ();
76 
77       memset (result, 0, 16);
78       vec_store_len_r_mem (&test_vec, result, &test_len[i]);
79       if (memcmp (result, exp_result, 16) != 0)
80 	__builtin_abort ();
81     }
82 
83   GEN_CONST_TEST(0)
84   GEN_CONST_TEST(12)
85   GEN_CONST_TEST(18)
86 
87   return 0;
88 }
89 
90 /* vec_store_len_r_reg and vec_store_len_r_mem */
91 /* { dg-final { scan-assembler-times "vstrlr\t" 2 } } */
92 
93 /* For the 2 constants.  The 3. should be implemented with vst.  */
94 /* { dg-final { scan-assembler-times "vstrl\t" 2 } } */
95