1 /* { dg-do run } */
2 /* { dg-require-effective-target s390_vxe } */
3 /* { dg-options "-O3 -mzarch -march=z14 -mzvector --save-temps -Wno-attributes" } */
4 
5 #include <string.h>
6 #include <vecintrin.h>
7 
8 typedef vector signed char v16qi;
9 typedef vector unsigned char uv16qi;
10 typedef vector bool char bv16qi;
11 
12 typedef vector signed short int v8hi;
13 typedef vector unsigned short int uv8hi;
14 typedef vector bool short int bv8hi;
15 
16 typedef vector signed int v4si;
17 typedef vector unsigned int uv4si;
18 typedef vector bool int bv4si;
19 
20 typedef vector signed long long v2di;
21 typedef vector unsigned long long uv2di;
22 typedef vector bool long long bv2di;
23 
24 typedef vector float v4sf;
25 typedef vector double v2df;
26 
27 #define NUM_CONSTS 8
28 
29 const v16qi v16qi_vals[NUM_CONSTS] =
30   { (v16qi){ 1 },
31     (v16qi){ 2 },
32     (v16qi){ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 },
33     (v16qi){ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2 },
34     (v16qi){ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 },
35     (v16qi){ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
36     (v16qi){ 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 },
37     (v16qi){ 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1 }
38   };
39 
40 const v8hi v8hi_vals[NUM_CONSTS] =
41   { (v8hi){ 1 },
42     (v8hi){ 2 },
43     (v8hi){ 1,1,1,1,1,1,1,1 },
44     (v8hi){ 2,2,2,2,2,2,2,2 },
45     (v8hi){ -1,-1,-1,-1,-1,-1,-1,-1 },
46     (v8hi){ 0,0,0,0,0,0,0,0 },
47     (v8hi){ 1,2,3,4,5,6,7,8 },
48     (v8hi){ 8,7,6,5,4,3,2,1 }
49   };
50 
51 const v4si v4si_vals[NUM_CONSTS] =
52   { (v4si){ 1 },
53     (v4si){ 2 },
54     (v4si){ 1,1,1,1 },
55     (v4si){ 2,2,2,2 },
56     (v4si){ -1,-1,-1,-1 },
57     (v4si){ 0,0,0,0 },
58     (v4si){ 1,2,3,4 },
59     (v4si){ 4,3,2,1 }
60   };
61 
62 const v2di v2di_vals[NUM_CONSTS] =
63   { (v2di){ 1 },
64     (v2di){ 2 },
65     (v2di){ 1,1 },
66     (v2di){ 2,2 },
67     (v2di){ -1,-1 },
68     (v2di){ 0,0 },
69     (v2di){ 1,2 },
70     (v2di){ 2,1 }
71   };
72 
73 const v4sf v4sf_vals[NUM_CONSTS] =
74   { (v4sf){ 1.0f },
75     (v4sf){ 2.0f },
76     (v4sf){ 1.0f,1.0f,1.0f,1.0f },
77     (v4sf){ 2.0f,2.0f,2.0f,2.0f },
78     (v4sf){ -1.0f,-1.0f,-1.0f,-1.0f },
79     (v4sf){ 0.0f,0.0f,0.0f,0.0f },
80     (v4sf){ 1.1f,2.1f,3.1f,4.1f },
81     (v4sf){ 4.1f,3.1f,2.1f,1.1f }
82   };
83 
84 const v2df v2df_vals[NUM_CONSTS] =
85   { (v2df){ 1.0 },
86     (v2df){ 2.0 },
87     (v2df){ 1.0,1.0 },
88     (v2df){ 2.0,2.0 },
89     (v2df){ -1.0,-1.0 },
90     (v2df){ 0.0,0.0 },
91     (v2df){ 1.1,2.1 },
92     (v2df){ 2.1,1.1 }
93   };
94 
95 /* Each bit of the result vector has the value of the corresponding
96    bit of A if the corresponding bit of C is 0, or the value of the
97    corresponding bit of B otherwise.  */
98 void __attribute__((noinline, noclone, target ("arch=zEC12")))
emul(unsigned char * result,unsigned char * a,unsigned char * b,unsigned char * c)99 emul (unsigned char *result, unsigned char *a,
100       unsigned char *b, unsigned char *c)
101 {
102   for (int i = 0; i < 16; i++)
103     result[i] = (a[i] & ~c[i]) | (b[i] & c[i]);
104 }
105 
106 #define GENFUNC(NAME, T1, T2)						\
107   T1 __attribute__((noinline, noclone))					\
108   NAME##_reg (T1 a, T1 b, T2 c) { return vec_sel (a, b, c); }		\
109   void __attribute__((noinline, noclone))				\
110   NAME##_mem (T1 *a, T1 *b, T2 *c, T1 *out) { *out = vec_sel (*a, *b, *c); } \
111   T1 __attribute__((always_inline))					\
112   NAME##_const (T1 a, T1 b, T2 c) { return vec_sel (a, b, c); }
113 
GENFUNC(vec_sel_b8_a,bv16qi,uv16qi)114 GENFUNC (vec_sel_b8_a, bv16qi, uv16qi)
115 GENFUNC (vec_sel_b8_b, bv16qi, bv16qi)
116 GENFUNC (vec_sel_s8_a,  v16qi, uv16qi)
117 GENFUNC (vec_sel_s8_b,  v16qi, bv16qi)
118 GENFUNC (vec_sel_u8_a, uv16qi, uv16qi)
119 GENFUNC (vec_sel_u8_b, uv16qi, bv16qi)
120 
121 GENFUNC (vec_sel_b16_a, bv8hi, uv8hi)
122 GENFUNC (vec_sel_b16_b, bv8hi, bv8hi)
123 GENFUNC (vec_sel_s16_a,  v8hi, uv8hi)
124 GENFUNC (vec_sel_s16_b,  v8hi, bv8hi)
125 GENFUNC (vec_sel_u16_a, uv8hi, uv8hi)
126 GENFUNC (vec_sel_u16_b, uv8hi, bv8hi)
127 
128 GENFUNC (vec_sel_b32_a, bv4si, uv4si)
129 GENFUNC (vec_sel_b32_b, bv4si, bv4si)
130 GENFUNC (vec_sel_s32_a,  v4si, uv4si)
131 GENFUNC (vec_sel_s32_b,  v4si, bv4si)
132 GENFUNC (vec_sel_u32_a, uv4si, uv4si)
133 GENFUNC (vec_sel_u32_b, uv4si, bv4si)
134 
135 GENFUNC (vec_sel_b64_a, bv2di, uv2di)
136 GENFUNC (vec_sel_b64_b, bv2di, bv2di)
137 GENFUNC (vec_sel_s64_a,  v2di, uv2di)
138 GENFUNC (vec_sel_s64_b,  v2di, bv2di)
139 GENFUNC (vec_sel_u64_a, uv2di, uv2di)
140 GENFUNC (vec_sel_u64_b, uv2di, bv2di)
141 
142 GENFUNC (vec_sel_flt_a,  v4sf, uv4si)
143 GENFUNC (vec_sel_flt_b,  v4sf, bv4si)
144 
145 GENFUNC (vec_sel_dbl_a,  v2df, uv2di)
146 GENFUNC (vec_sel_dbl_b,  v2df, bv2di)
147 
148 #define TESTFUNC(NAME, T1, T2, VAL_TYPE)				\
149   for (int i = 0; i < NUM_CONSTS; i++)					\
150     for (int j = 0; j < NUM_CONSTS; j++)				\
151       for (int k = 0; k < NUM_CONSTS; k++)				\
152 	{								\
153 	  unsigned char result[16];					\
154 	  T1 in1 = (T1)VAL_TYPE##_vals[i];				\
155 	  T1 in2 = (T1)VAL_TYPE##_vals[j];				\
156 	  T2 in3 = (T2)VAL_TYPE##_vals[k];				\
157 	  emul (result, (char*)&in1, (char*)&in2, (char*)&in3);		\
158 									\
159 	  T1 reg = NAME##_reg (in1, in2, in3);				\
160 	  if (memcmp ((char*)&reg, result, 16) != 0)			\
161 	    __builtin_abort ();						\
162 									\
163 	  T1 mem;							\
164 	  NAME##_mem (&in1, &in2, &in3, &mem);				\
165 	  if (memcmp ((char*)&mem, result, 16) != 0)			\
166 	    __builtin_abort ();						\
167 									\
168 	  T1 cons = NAME##_const (in1, in2, in3);			\
169 	  if (memcmp ((char*)&cons, result, 16) != 0)			\
170 	    __builtin_abort ();						\
171 	}
172 
173 int
174 main ()
175 {
176   TESTFUNC (vec_sel_b8_a, bv16qi, uv16qi, v16qi);
177   TESTFUNC (vec_sel_b8_b, bv16qi, bv16qi, v16qi);
178   TESTFUNC (vec_sel_s8_a,  v16qi, uv16qi, v16qi);
179   TESTFUNC (vec_sel_s8_b,  v16qi, bv16qi, v16qi);
180   TESTFUNC (vec_sel_u8_a, uv16qi, uv16qi, v16qi);
181   TESTFUNC (vec_sel_u8_b, uv16qi, bv16qi, v16qi);
182 
183   TESTFUNC (vec_sel_b16_a, bv8hi, uv8hi, v8hi);
184   TESTFUNC (vec_sel_b16_b, bv8hi, bv8hi, v8hi);
185   TESTFUNC (vec_sel_s16_a,  v8hi, uv8hi, v8hi);
186   TESTFUNC (vec_sel_s16_b,  v8hi, bv8hi, v8hi);
187   TESTFUNC (vec_sel_u16_a, uv8hi, uv8hi, v8hi);
188   TESTFUNC (vec_sel_u16_b, uv8hi, bv8hi, v8hi);
189 
190   TESTFUNC (vec_sel_b32_a, bv4si, uv4si, v4si);
191   TESTFUNC (vec_sel_b32_b, bv4si, bv4si, v4si);
192   TESTFUNC (vec_sel_s32_a,  v4si, uv4si, v4si);
193   TESTFUNC (vec_sel_s32_b,  v4si, bv4si, v4si);
194   TESTFUNC (vec_sel_u32_a, uv4si, uv4si, v4si);
195   TESTFUNC (vec_sel_u32_b, uv4si, bv4si, v4si);
196 
197   TESTFUNC (vec_sel_b64_a, bv2di, uv2di, v2di);
198   TESTFUNC (vec_sel_b64_b, bv2di, bv2di, v2di);
199   TESTFUNC (vec_sel_s64_a,  v2di, uv2di, v2di);
200   TESTFUNC (vec_sel_s64_b,  v2di, bv2di, v2di);
201   TESTFUNC (vec_sel_u64_a, uv2di, uv2di, v2di);
202   TESTFUNC (vec_sel_u64_b, uv2di, bv2di, v2di);
203 
204   TESTFUNC (vec_sel_flt_a,  v4sf, uv4si, v4sf);
205   TESTFUNC (vec_sel_flt_b,  v4sf, bv4si, v4sf);
206 
207   TESTFUNC (vec_sel_dbl_a,  v2df, uv2di, v2df);
208   TESTFUNC (vec_sel_dbl_b,  v2df, bv2di, v2df);
209 }
210 
211 /* { dg-final { scan-assembler {\n\tvsel\t} } } */
212