]> git.proxmox.com Git - mirror_qemu.git/blob - target/s390x/tcg/vec_int_helper.c
Merge tag 'pull-request-2022-05-04' of https://gitlab.com/thuth/qemu into staging
[mirror_qemu.git] / target / s390x / tcg / vec_int_helper.c
1 /*
2 * QEMU TCG support -- s390x vector integer instruction support
3 *
4 * Copyright (C) 2019 Red Hat Inc
5 *
6 * Authors:
7 * David Hildenbrand <david@redhat.com>
8 *
9 * This work is licensed under the terms of the GNU GPL, version 2 or later.
10 * See the COPYING file in the top-level directory.
11 */
12 #include "qemu/osdep.h"
13 #include "cpu.h"
14 #include "vec.h"
15 #include "exec/helper-proto.h"
16 #include "tcg/tcg-gvec-desc.h"
17
18 static bool s390_vec_is_zero(const S390Vector *v)
19 {
20 return !v->doubleword[0] && !v->doubleword[1];
21 }
22
23 static void s390_vec_xor(S390Vector *res, const S390Vector *a,
24 const S390Vector *b)
25 {
26 res->doubleword[0] = a->doubleword[0] ^ b->doubleword[0];
27 res->doubleword[1] = a->doubleword[1] ^ b->doubleword[1];
28 }
29
30 static void s390_vec_and(S390Vector *res, const S390Vector *a,
31 const S390Vector *b)
32 {
33 res->doubleword[0] = a->doubleword[0] & b->doubleword[0];
34 res->doubleword[1] = a->doubleword[1] & b->doubleword[1];
35 }
36
37 static bool s390_vec_equal(const S390Vector *a, const S390Vector *b)
38 {
39 return a->doubleword[0] == b->doubleword[0] &&
40 a->doubleword[1] == b->doubleword[1];
41 }
42
43 static void s390_vec_shl(S390Vector *d, const S390Vector *a, uint64_t count)
44 {
45 uint64_t tmp;
46
47 g_assert(count < 128);
48 if (count == 0) {
49 d->doubleword[0] = a->doubleword[0];
50 d->doubleword[1] = a->doubleword[1];
51 } else if (count == 64) {
52 d->doubleword[0] = a->doubleword[1];
53 d->doubleword[1] = 0;
54 } else if (count < 64) {
55 tmp = extract64(a->doubleword[1], 64 - count, count);
56 d->doubleword[1] = a->doubleword[1] << count;
57 d->doubleword[0] = (a->doubleword[0] << count) | tmp;
58 } else {
59 d->doubleword[0] = a->doubleword[1] << (count - 64);
60 d->doubleword[1] = 0;
61 }
62 }
63
64 static void s390_vec_sar(S390Vector *d, const S390Vector *a, uint64_t count)
65 {
66 uint64_t tmp;
67
68 if (count == 0) {
69 d->doubleword[0] = a->doubleword[0];
70 d->doubleword[1] = a->doubleword[1];
71 } else if (count == 64) {
72 tmp = (int64_t)a->doubleword[0] >> 63;
73 d->doubleword[1] = a->doubleword[0];
74 d->doubleword[0] = tmp;
75 } else if (count < 64) {
76 tmp = a->doubleword[1] >> count;
77 d->doubleword[1] = deposit64(tmp, 64 - count, count, a->doubleword[0]);
78 d->doubleword[0] = (int64_t)a->doubleword[0] >> count;
79 } else {
80 tmp = (int64_t)a->doubleword[0] >> 63;
81 d->doubleword[1] = (int64_t)a->doubleword[0] >> (count - 64);
82 d->doubleword[0] = tmp;
83 }
84 }
85
86 static void s390_vec_shr(S390Vector *d, const S390Vector *a, uint64_t count)
87 {
88 uint64_t tmp;
89
90 g_assert(count < 128);
91 if (count == 0) {
92 d->doubleword[0] = a->doubleword[0];
93 d->doubleword[1] = a->doubleword[1];
94 } else if (count == 64) {
95 d->doubleword[1] = a->doubleword[0];
96 d->doubleword[0] = 0;
97 } else if (count < 64) {
98 tmp = a->doubleword[1] >> count;
99 d->doubleword[1] = deposit64(tmp, 64 - count, count, a->doubleword[0]);
100 d->doubleword[0] = a->doubleword[0] >> count;
101 } else {
102 d->doubleword[1] = a->doubleword[0] >> (count - 64);
103 d->doubleword[0] = 0;
104 }
105 }
106 #define DEF_VAVG(BITS) \
107 void HELPER(gvec_vavg##BITS)(void *v1, const void *v2, const void *v3, \
108 uint32_t desc) \
109 { \
110 int i; \
111 \
112 for (i = 0; i < (128 / BITS); i++) { \
113 const int32_t a = (int##BITS##_t)s390_vec_read_element##BITS(v2, i); \
114 const int32_t b = (int##BITS##_t)s390_vec_read_element##BITS(v3, i); \
115 \
116 s390_vec_write_element##BITS(v1, i, (a + b + 1) >> 1); \
117 } \
118 }
119 DEF_VAVG(8)
120 DEF_VAVG(16)
121
122 #define DEF_VAVGL(BITS) \
123 void HELPER(gvec_vavgl##BITS)(void *v1, const void *v2, const void *v3, \
124 uint32_t desc) \
125 { \
126 int i; \
127 \
128 for (i = 0; i < (128 / BITS); i++) { \
129 const uint##BITS##_t a = s390_vec_read_element##BITS(v2, i); \
130 const uint##BITS##_t b = s390_vec_read_element##BITS(v3, i); \
131 \
132 s390_vec_write_element##BITS(v1, i, (a + b + 1) >> 1); \
133 } \
134 }
135 DEF_VAVGL(8)
136 DEF_VAVGL(16)
137
138 #define DEF_VCLZ(BITS) \
139 void HELPER(gvec_vclz##BITS)(void *v1, const void *v2, uint32_t desc) \
140 { \
141 int i; \
142 \
143 for (i = 0; i < (128 / BITS); i++) { \
144 const uint##BITS##_t a = s390_vec_read_element##BITS(v2, i); \
145 \
146 s390_vec_write_element##BITS(v1, i, clz32(a) - 32 + BITS); \
147 } \
148 }
149 DEF_VCLZ(8)
150 DEF_VCLZ(16)
151
152 #define DEF_VCTZ(BITS) \
153 void HELPER(gvec_vctz##BITS)(void *v1, const void *v2, uint32_t desc) \
154 { \
155 int i; \
156 \
157 for (i = 0; i < (128 / BITS); i++) { \
158 const uint##BITS##_t a = s390_vec_read_element##BITS(v2, i); \
159 \
160 s390_vec_write_element##BITS(v1, i, a ? ctz32(a) : BITS); \
161 } \
162 }
163 DEF_VCTZ(8)
164 DEF_VCTZ(16)
165
166 /* like binary multiplication, but XOR instead of addition */
167 #define DEF_GALOIS_MULTIPLY(BITS, TBITS) \
168 static uint##TBITS##_t galois_multiply##BITS(uint##TBITS##_t a, \
169 uint##TBITS##_t b) \
170 { \
171 uint##TBITS##_t res = 0; \
172 \
173 while (b) { \
174 if (b & 0x1) { \
175 res = res ^ a; \
176 } \
177 a = a << 1; \
178 b = b >> 1; \
179 } \
180 return res; \
181 }
182 DEF_GALOIS_MULTIPLY(8, 16)
183 DEF_GALOIS_MULTIPLY(16, 32)
184 DEF_GALOIS_MULTIPLY(32, 64)
185
186 static S390Vector galois_multiply64(uint64_t a, uint64_t b)
187 {
188 S390Vector res = {};
189 S390Vector va = {
190 .doubleword[1] = a,
191 };
192 S390Vector vb = {
193 .doubleword[1] = b,
194 };
195
196 while (!s390_vec_is_zero(&vb)) {
197 if (vb.doubleword[1] & 0x1) {
198 s390_vec_xor(&res, &res, &va);
199 }
200 s390_vec_shl(&va, &va, 1);
201 s390_vec_shr(&vb, &vb, 1);
202 }
203 return res;
204 }
205
206 #define DEF_VGFM(BITS, TBITS) \
207 void HELPER(gvec_vgfm##BITS)(void *v1, const void *v2, const void *v3, \
208 uint32_t desc) \
209 { \
210 int i; \
211 \
212 for (i = 0; i < (128 / TBITS); i++) { \
213 uint##BITS##_t a = s390_vec_read_element##BITS(v2, i * 2); \
214 uint##BITS##_t b = s390_vec_read_element##BITS(v3, i * 2); \
215 uint##TBITS##_t d = galois_multiply##BITS(a, b); \
216 \
217 a = s390_vec_read_element##BITS(v2, i * 2 + 1); \
218 b = s390_vec_read_element##BITS(v3, i * 2 + 1); \
219 d = d ^ galois_multiply32(a, b); \
220 s390_vec_write_element##TBITS(v1, i, d); \
221 } \
222 }
223 DEF_VGFM(8, 16)
224 DEF_VGFM(16, 32)
225 DEF_VGFM(32, 64)
226
227 void HELPER(gvec_vgfm64)(void *v1, const void *v2, const void *v3,
228 uint32_t desc)
229 {
230 S390Vector tmp1, tmp2;
231 uint64_t a, b;
232
233 a = s390_vec_read_element64(v2, 0);
234 b = s390_vec_read_element64(v3, 0);
235 tmp1 = galois_multiply64(a, b);
236 a = s390_vec_read_element64(v2, 1);
237 b = s390_vec_read_element64(v3, 1);
238 tmp2 = galois_multiply64(a, b);
239 s390_vec_xor(v1, &tmp1, &tmp2);
240 }
241
242 #define DEF_VGFMA(BITS, TBITS) \
243 void HELPER(gvec_vgfma##BITS)(void *v1, const void *v2, const void *v3, \
244 const void *v4, uint32_t desc) \
245 { \
246 int i; \
247 \
248 for (i = 0; i < (128 / TBITS); i++) { \
249 uint##BITS##_t a = s390_vec_read_element##BITS(v2, i * 2); \
250 uint##BITS##_t b = s390_vec_read_element##BITS(v3, i * 2); \
251 uint##TBITS##_t d = galois_multiply##BITS(a, b); \
252 \
253 a = s390_vec_read_element##BITS(v2, i * 2 + 1); \
254 b = s390_vec_read_element##BITS(v3, i * 2 + 1); \
255 d = d ^ galois_multiply32(a, b); \
256 d = d ^ s390_vec_read_element##TBITS(v4, i); \
257 s390_vec_write_element##TBITS(v1, i, d); \
258 } \
259 }
260 DEF_VGFMA(8, 16)
261 DEF_VGFMA(16, 32)
262 DEF_VGFMA(32, 64)
263
264 void HELPER(gvec_vgfma64)(void *v1, const void *v2, const void *v3,
265 const void *v4, uint32_t desc)
266 {
267 S390Vector tmp1, tmp2;
268 uint64_t a, b;
269
270 a = s390_vec_read_element64(v2, 0);
271 b = s390_vec_read_element64(v3, 0);
272 tmp1 = galois_multiply64(a, b);
273 a = s390_vec_read_element64(v2, 1);
274 b = s390_vec_read_element64(v3, 1);
275 tmp2 = galois_multiply64(a, b);
276 s390_vec_xor(&tmp1, &tmp1, &tmp2);
277 s390_vec_xor(v1, &tmp1, v4);
278 }
279
280 #define DEF_VMAL(BITS) \
281 void HELPER(gvec_vmal##BITS)(void *v1, const void *v2, const void *v3, \
282 const void *v4, uint32_t desc) \
283 { \
284 int i; \
285 \
286 for (i = 0; i < (128 / BITS); i++) { \
287 const uint##BITS##_t a = s390_vec_read_element##BITS(v2, i); \
288 const uint##BITS##_t b = s390_vec_read_element##BITS(v3, i); \
289 const uint##BITS##_t c = s390_vec_read_element##BITS(v4, i); \
290 \
291 s390_vec_write_element##BITS(v1, i, a * b + c); \
292 } \
293 }
294 DEF_VMAL(8)
295 DEF_VMAL(16)
296
297 #define DEF_VMAH(BITS) \
298 void HELPER(gvec_vmah##BITS)(void *v1, const void *v2, const void *v3, \
299 const void *v4, uint32_t desc) \
300 { \
301 int i; \
302 \
303 for (i = 0; i < (128 / BITS); i++) { \
304 const int32_t a = (int##BITS##_t)s390_vec_read_element##BITS(v2, i); \
305 const int32_t b = (int##BITS##_t)s390_vec_read_element##BITS(v3, i); \
306 const int32_t c = (int##BITS##_t)s390_vec_read_element##BITS(v4, i); \
307 \
308 s390_vec_write_element##BITS(v1, i, (a * b + c) >> BITS); \
309 } \
310 }
311 DEF_VMAH(8)
312 DEF_VMAH(16)
313
314 #define DEF_VMALH(BITS) \
315 void HELPER(gvec_vmalh##BITS)(void *v1, const void *v2, const void *v3, \
316 const void *v4, uint32_t desc) \
317 { \
318 int i; \
319 \
320 for (i = 0; i < (128 / BITS); i++) { \
321 const uint##BITS##_t a = s390_vec_read_element##BITS(v2, i); \
322 const uint##BITS##_t b = s390_vec_read_element##BITS(v3, i); \
323 const uint##BITS##_t c = s390_vec_read_element##BITS(v4, i); \
324 \
325 s390_vec_write_element##BITS(v1, i, (a * b + c) >> BITS); \
326 } \
327 }
328 DEF_VMALH(8)
329 DEF_VMALH(16)
330
331 #define DEF_VMAE(BITS, TBITS) \
332 void HELPER(gvec_vmae##BITS)(void *v1, const void *v2, const void *v3, \
333 const void *v4, uint32_t desc) \
334 { \
335 int i, j; \
336 \
337 for (i = 0, j = 0; i < (128 / TBITS); i++, j += 2) { \
338 int##TBITS##_t a = (int##BITS##_t)s390_vec_read_element##BITS(v2, j); \
339 int##TBITS##_t b = (int##BITS##_t)s390_vec_read_element##BITS(v3, j); \
340 int##TBITS##_t c = s390_vec_read_element##TBITS(v4, i); \
341 \
342 s390_vec_write_element##TBITS(v1, i, a * b + c); \
343 } \
344 }
345 DEF_VMAE(8, 16)
346 DEF_VMAE(16, 32)
347 DEF_VMAE(32, 64)
348
349 #define DEF_VMALE(BITS, TBITS) \
350 void HELPER(gvec_vmale##BITS)(void *v1, const void *v2, const void *v3, \
351 const void *v4, uint32_t desc) \
352 { \
353 int i, j; \
354 \
355 for (i = 0, j = 0; i < (128 / TBITS); i++, j += 2) { \
356 uint##TBITS##_t a = s390_vec_read_element##BITS(v2, j); \
357 uint##TBITS##_t b = s390_vec_read_element##BITS(v3, j); \
358 uint##TBITS##_t c = s390_vec_read_element##TBITS(v4, i); \
359 \
360 s390_vec_write_element##TBITS(v1, i, a * b + c); \
361 } \
362 }
363 DEF_VMALE(8, 16)
364 DEF_VMALE(16, 32)
365 DEF_VMALE(32, 64)
366
367 #define DEF_VMAO(BITS, TBITS) \
368 void HELPER(gvec_vmao##BITS)(void *v1, const void *v2, const void *v3, \
369 const void *v4, uint32_t desc) \
370 { \
371 int i, j; \
372 \
373 for (i = 0, j = 1; i < (128 / TBITS); i++, j += 2) { \
374 int##TBITS##_t a = (int##BITS##_t)s390_vec_read_element##BITS(v2, j); \
375 int##TBITS##_t b = (int##BITS##_t)s390_vec_read_element##BITS(v3, j); \
376 int##TBITS##_t c = s390_vec_read_element##TBITS(v4, i); \
377 \
378 s390_vec_write_element##TBITS(v1, i, a * b + c); \
379 } \
380 }
381 DEF_VMAO(8, 16)
382 DEF_VMAO(16, 32)
383 DEF_VMAO(32, 64)
384
385 #define DEF_VMALO(BITS, TBITS) \
386 void HELPER(gvec_vmalo##BITS)(void *v1, const void *v2, const void *v3, \
387 const void *v4, uint32_t desc) \
388 { \
389 int i, j; \
390 \
391 for (i = 0, j = 1; i < (128 / TBITS); i++, j += 2) { \
392 uint##TBITS##_t a = s390_vec_read_element##BITS(v2, j); \
393 uint##TBITS##_t b = s390_vec_read_element##BITS(v3, j); \
394 uint##TBITS##_t c = s390_vec_read_element##TBITS(v4, i); \
395 \
396 s390_vec_write_element##TBITS(v1, i, a * b + c); \
397 } \
398 }
399 DEF_VMALO(8, 16)
400 DEF_VMALO(16, 32)
401 DEF_VMALO(32, 64)
402
403 #define DEF_VMH(BITS) \
404 void HELPER(gvec_vmh##BITS)(void *v1, const void *v2, const void *v3, \
405 uint32_t desc) \
406 { \
407 int i; \
408 \
409 for (i = 0; i < (128 / BITS); i++) { \
410 const int32_t a = (int##BITS##_t)s390_vec_read_element##BITS(v2, i); \
411 const int32_t b = (int##BITS##_t)s390_vec_read_element##BITS(v3, i); \
412 \
413 s390_vec_write_element##BITS(v1, i, (a * b) >> BITS); \
414 } \
415 }
416 DEF_VMH(8)
417 DEF_VMH(16)
418
419 #define DEF_VMLH(BITS) \
420 void HELPER(gvec_vmlh##BITS)(void *v1, const void *v2, const void *v3, \
421 uint32_t desc) \
422 { \
423 int i; \
424 \
425 for (i = 0; i < (128 / BITS); i++) { \
426 const uint##BITS##_t a = s390_vec_read_element##BITS(v2, i); \
427 const uint##BITS##_t b = s390_vec_read_element##BITS(v3, i); \
428 \
429 s390_vec_write_element##BITS(v1, i, (a * b) >> BITS); \
430 } \
431 }
432 DEF_VMLH(8)
433 DEF_VMLH(16)
434
435 #define DEF_VME(BITS, TBITS) \
436 void HELPER(gvec_vme##BITS)(void *v1, const void *v2, const void *v3, \
437 uint32_t desc) \
438 { \
439 int i, j; \
440 \
441 for (i = 0, j = 0; i < (128 / TBITS); i++, j += 2) { \
442 int##TBITS##_t a = (int##BITS##_t)s390_vec_read_element##BITS(v2, j); \
443 int##TBITS##_t b = (int##BITS##_t)s390_vec_read_element##BITS(v3, j); \
444 \
445 s390_vec_write_element##TBITS(v1, i, a * b); \
446 } \
447 }
448 DEF_VME(8, 16)
449 DEF_VME(16, 32)
450 DEF_VME(32, 64)
451
452 #define DEF_VMLE(BITS, TBITS) \
453 void HELPER(gvec_vmle##BITS)(void *v1, const void *v2, const void *v3, \
454 uint32_t desc) \
455 { \
456 int i, j; \
457 \
458 for (i = 0, j = 0; i < (128 / TBITS); i++, j += 2) { \
459 const uint##TBITS##_t a = s390_vec_read_element##BITS(v2, j); \
460 const uint##TBITS##_t b = s390_vec_read_element##BITS(v3, j); \
461 \
462 s390_vec_write_element##TBITS(v1, i, a * b); \
463 } \
464 }
465 DEF_VMLE(8, 16)
466 DEF_VMLE(16, 32)
467 DEF_VMLE(32, 64)
468
469 #define DEF_VMO(BITS, TBITS) \
470 void HELPER(gvec_vmo##BITS)(void *v1, const void *v2, const void *v3, \
471 uint32_t desc) \
472 { \
473 int i, j; \
474 \
475 for (i = 0, j = 1; i < (128 / TBITS); i++, j += 2) { \
476 int##TBITS##_t a = (int##BITS##_t)s390_vec_read_element##BITS(v2, j); \
477 int##TBITS##_t b = (int##BITS##_t)s390_vec_read_element##BITS(v3, j); \
478 \
479 s390_vec_write_element##TBITS(v1, i, a * b); \
480 } \
481 }
482 DEF_VMO(8, 16)
483 DEF_VMO(16, 32)
484 DEF_VMO(32, 64)
485
486 #define DEF_VMLO(BITS, TBITS) \
487 void HELPER(gvec_vmlo##BITS)(void *v1, const void *v2, const void *v3, \
488 uint32_t desc) \
489 { \
490 int i, j; \
491 \
492 for (i = 0, j = 1; i < (128 / TBITS); i++, j += 2) { \
493 const uint##TBITS##_t a = s390_vec_read_element##BITS(v2, j); \
494 const uint##TBITS##_t b = s390_vec_read_element##BITS(v3, j); \
495 \
496 s390_vec_write_element##TBITS(v1, i, a * b); \
497 } \
498 }
499 DEF_VMLO(8, 16)
500 DEF_VMLO(16, 32)
501 DEF_VMLO(32, 64)
502
503 #define DEF_VPOPCT(BITS) \
504 void HELPER(gvec_vpopct##BITS)(void *v1, const void *v2, uint32_t desc) \
505 { \
506 int i; \
507 \
508 for (i = 0; i < (128 / BITS); i++) { \
509 const uint##BITS##_t a = s390_vec_read_element##BITS(v2, i); \
510 \
511 s390_vec_write_element##BITS(v1, i, ctpop32(a)); \
512 } \
513 }
514 DEF_VPOPCT(8)
515 DEF_VPOPCT(16)
516
517 #define DEF_VERIM(BITS) \
518 void HELPER(gvec_verim##BITS)(void *v1, const void *v2, const void *v3, \
519 uint32_t desc) \
520 { \
521 const uint8_t count = simd_data(desc); \
522 int i; \
523 \
524 for (i = 0; i < (128 / BITS); i++) { \
525 const uint##BITS##_t a = s390_vec_read_element##BITS(v1, i); \
526 const uint##BITS##_t b = s390_vec_read_element##BITS(v2, i); \
527 const uint##BITS##_t mask = s390_vec_read_element##BITS(v3, i); \
528 const uint##BITS##_t d = (a & ~mask) | (rol##BITS(b, count) & mask); \
529 \
530 s390_vec_write_element##BITS(v1, i, d); \
531 } \
532 }
533 DEF_VERIM(8)
534 DEF_VERIM(16)
535
536 void HELPER(gvec_vsl)(void *v1, const void *v2, uint64_t count,
537 uint32_t desc)
538 {
539 s390_vec_shl(v1, v2, count);
540 }
541
542 void HELPER(gvec_vsl_ve2)(void *v1, const void *v2, const void *v3,
543 uint32_t desc)
544 {
545 S390Vector tmp;
546 uint32_t sh, e0, e1 = 0;
547 int i;
548
549 for (i = 15; i >= 0; --i, e1 = e0) {
550 e0 = s390_vec_read_element8(v2, i);
551 sh = s390_vec_read_element8(v3, i) & 7;
552
553 s390_vec_write_element8(&tmp, i, rol32(e0 | (e1 << 24), sh));
554 }
555
556 *(S390Vector *)v1 = tmp;
557 }
558
559 void HELPER(gvec_vsra)(void *v1, const void *v2, uint64_t count,
560 uint32_t desc)
561 {
562 s390_vec_sar(v1, v2, count);
563 }
564
565 void HELPER(gvec_vsra_ve2)(void *v1, const void *v2, const void *v3,
566 uint32_t desc)
567 {
568 S390Vector tmp;
569 uint32_t sh, e0, e1 = 0;
570 int i = 0;
571
572 /* Byte 0 is special only. */
573 e0 = (int32_t)(int8_t)s390_vec_read_element8(v2, i);
574 sh = s390_vec_read_element8(v3, i) & 7;
575 s390_vec_write_element8(&tmp, i, e0 >> sh);
576
577 e1 = e0;
578 for (i = 1; i < 16; ++i, e1 = e0) {
579 e0 = s390_vec_read_element8(v2, i);
580 sh = s390_vec_read_element8(v3, i) & 7;
581 s390_vec_write_element8(&tmp, i, (e0 | e1 << 8) >> sh);
582 }
583
584 *(S390Vector *)v1 = tmp;
585 }
586
587 void HELPER(gvec_vsrl)(void *v1, const void *v2, uint64_t count,
588 uint32_t desc)
589 {
590 s390_vec_shr(v1, v2, count);
591 }
592
593 void HELPER(gvec_vsrl_ve2)(void *v1, const void *v2, const void *v3,
594 uint32_t desc)
595 {
596 S390Vector tmp;
597 uint32_t sh, e0, e1 = 0;
598
599 for (int i = 0; i < 16; ++i, e1 = e0) {
600 e0 = s390_vec_read_element8(v2, i);
601 sh = s390_vec_read_element8(v3, i) & 7;
602
603 s390_vec_write_element8(&tmp, i, (e0 | (e1 << 8)) >> sh);
604 }
605
606 *(S390Vector *)v1 = tmp;
607 }
608
609 #define DEF_VSCBI(BITS) \
610 void HELPER(gvec_vscbi##BITS)(void *v1, const void *v2, const void *v3, \
611 uint32_t desc) \
612 { \
613 int i; \
614 \
615 for (i = 0; i < (128 / BITS); i++) { \
616 const uint##BITS##_t a = s390_vec_read_element##BITS(v2, i); \
617 const uint##BITS##_t b = s390_vec_read_element##BITS(v3, i); \
618 \
619 s390_vec_write_element##BITS(v1, i, a >= b); \
620 } \
621 }
622 DEF_VSCBI(8)
623 DEF_VSCBI(16)
624
625 void HELPER(gvec_vtm)(void *v1, const void *v2, CPUS390XState *env,
626 uint32_t desc)
627 {
628 S390Vector tmp;
629
630 s390_vec_and(&tmp, v1, v2);
631 if (s390_vec_is_zero(&tmp)) {
632 /* Selected bits all zeros; or all mask bits zero */
633 env->cc_op = 0;
634 } else if (s390_vec_equal(&tmp, v2)) {
635 /* Selected bits all ones */
636 env->cc_op = 3;
637 } else {
638 /* Selected bits a mix of zeros and ones */
639 env->cc_op = 1;
640 }
641 }