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