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 const unsigned char test_vec[16] = { 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 bytes from SOURCE are stored right-justified in TARGET. */
19 void __attribute__((noinline, noclone, target ("arch=zEC12")))
emul(const unsigned char * source,unsigned char * target,unsigned int len)20 emul (const 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 = 0, t = start; t < 16; s++, t++)
26 target[t] = source[s];
27 }
28
29 uv16qi __attribute__((noinline, noclone))
vec_load_len_r_reg(const unsigned char * s,unsigned int len)30 vec_load_len_r_reg (const unsigned char *s, unsigned int len)
31 {
32 return vec_load_len_r (s, len);
33 }
34
35 void __attribute__((noinline, noclone))
vec_load_len_r_mem(const unsigned char * s,uv16qi * t,unsigned int * len)36 vec_load_len_r_mem (const unsigned char *s, uv16qi *t, unsigned int *len)
37 {
38 *t = vec_load_len_r (s, *len);
39 }
40
41 #define GEN_CONST_FUNC(CONST) \
42 static uv16qi inline \
43 vec_load_len_r_const##CONST (const unsigned char *s) \
44 { \
45 return vec_load_len_r (s, CONST); \
46 }
47
48 #define GEN_CONST_TEST(CONST) \
49 memset (exp_result, 0, 16); \
50 emul (test_vec, exp_result, CONST); \
51 result = (uv16qi) { 0 }; \
52 result = vec_load_len_r_const##CONST (test_vec); \
53 if (memcmp ((char*)&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 uv16qi result;
65
66 for (int i = 0; i < NUM_TEST_LENGTHS; i++)
67 {
68 memset (exp_result, 0, 16);
69
70 emul (test_vec, exp_result, test_len[i]);
71
72 result = (uv16qi) { 0 };
73 result = vec_load_len_r_reg (test_vec, test_len[i]);
74 if (memcmp ((char*)&result, exp_result, 16) != 0)
75 __builtin_abort ();
76
77 result = (uv16qi) { 0 };
78 vec_load_len_r_mem (test_vec, &result, &test_len[i]);
79 if (memcmp ((char*)&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_load_len_r_reg and vec_load_len_r_mem */
91 /* { dg-final { scan-assembler-times "vlrlr\t" 2 } } */
92
93 /* For the 2 constants. The 3. should be implemented with vl. */
94 /* { dg-final { scan-assembler-times "vlrl\t" 2 } } */
95