qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

vec.h (3837B)


      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 
     17 typedef 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 #if !HOST_BIG_ENDIAN
     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 
     51 static 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 
     57 static 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 
     63 static 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 
     69 static 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 
     75 static 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 
     92 static 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 
     99 static 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 
    106 static 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 
    113 static 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 
    120 static 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 */