qemu/target/s390x/tcg/vec.h
<<
>>
Prefs
   1/*
   2 * QEMU TCG support -- s390x vector utilitites
   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#ifndef S390X_VEC_H
  13#define S390X_VEC_H
  14
  15#include "tcg/tcg.h"
  16
  17typedef union S390Vector {
  18    uint64_t doubleword[2];
  19    uint32_t word[4];
  20    uint16_t halfword[8];
  21    uint8_t byte[16];
  22} S390Vector;
  23
  24/*
  25 * Each vector is stored as two 64bit host values. So when talking about
  26 * byte/halfword/word numbers, we have to take care of proper translation
  27 * between element numbers.
  28 *
  29 * Big Endian (target/possible host)
  30 * B:  [ 0][ 1][ 2][ 3][ 4][ 5][ 6][ 7] - [ 8][ 9][10][11][12][13][14][15]
  31 * HW: [     0][     1][     2][     3] - [     4][     5][     6][     7]
  32 * W:  [             0][             1] - [             2][             3]
  33 * DW: [                             0] - [                             1]
  34 *
  35 * Little Endian (possible host)
  36 * B:  [ 7][ 6][ 5][ 4][ 3][ 2][ 1][ 0] - [15][14][13][12][11][10][ 9][ 8]
  37 * HW: [     3][     2][     1][     0] - [     7][     6][     5][     4]
  38 * W:  [             1][             0] - [             3][             2]
  39 * DW: [                             0] - [                             1]
  40 */
  41#ifndef HOST_WORDS_BIGENDIAN
  42#define H1(x)  ((x) ^ 7)
  43#define H2(x)  ((x) ^ 3)
  44#define H4(x)  ((x) ^ 1)
  45#else
  46#define H1(x)  (x)
  47#define H2(x)  (x)
  48#define H4(x)  (x)
  49#endif
  50
  51static inline uint8_t s390_vec_read_element8(const S390Vector *v, uint8_t enr)
  52{
  53    g_assert(enr < 16);
  54    return v->byte[H1(enr)];
  55}
  56
  57static inline uint16_t s390_vec_read_element16(const S390Vector *v, uint8_t enr)
  58{
  59    g_assert(enr < 8);
  60    return v->halfword[H2(enr)];
  61}
  62
  63static inline uint32_t s390_vec_read_element32(const S390Vector *v, uint8_t enr)
  64{
  65    g_assert(enr < 4);
  66    return v->word[H4(enr)];
  67}
  68
  69static inline uint64_t s390_vec_read_element64(const S390Vector *v, uint8_t enr)
  70{
  71    g_assert(enr < 2);
  72    return v->doubleword[enr];
  73}
  74
  75static inline uint64_t s390_vec_read_element(const S390Vector *v, uint8_t enr,
  76                                             uint8_t es)
  77{
  78    switch (es) {
  79    case MO_8:
  80        return s390_vec_read_element8(v, enr);
  81    case MO_16:
  82        return s390_vec_read_element16(v, enr);
  83    case MO_32:
  84        return s390_vec_read_element32(v, enr);
  85    case MO_64:
  86        return s390_vec_read_element64(v, enr);
  87    default:
  88        g_assert_not_reached();
  89    }
  90}
  91
  92static inline void s390_vec_write_element8(S390Vector *v, uint8_t enr,
  93                                           uint8_t data)
  94{
  95    g_assert(enr < 16);
  96    v->byte[H1(enr)] = data;
  97}
  98
  99static inline void s390_vec_write_element16(S390Vector *v, uint8_t enr,
 100                                            uint16_t data)
 101{
 102    g_assert(enr < 8);
 103    v->halfword[H2(enr)] = data;
 104}
 105
 106static inline void s390_vec_write_element32(S390Vector *v, uint8_t enr,
 107                                            uint32_t data)
 108{
 109    g_assert(enr < 4);
 110    v->word[H4(enr)] = data;
 111}
 112
 113static inline void s390_vec_write_element64(S390Vector *v, uint8_t enr,
 114                                            uint64_t data)
 115{
 116    g_assert(enr < 2);
 117    v->doubleword[enr] = data;
 118}
 119
 120static inline void s390_vec_write_element(S390Vector *v, uint8_t enr,
 121                                          uint8_t es, uint64_t data)
 122{
 123    switch (es) {
 124    case MO_8:
 125        s390_vec_write_element8(v, enr, data);
 126        break;
 127    case MO_16:
 128        s390_vec_write_element16(v, enr, data);
 129        break;
 130    case MO_32:
 131        s390_vec_write_element32(v, enr, data);
 132        break;
 133    case MO_64:
 134        s390_vec_write_element64(v, enr, data);
 135        break;
 136    default:
 137        g_assert_not_reached();
 138    }
 139}
 140
 141#endif /* S390X_VEC_H */
 142