xref: /qemu/target/s390x/tcg/vec.h (revision 5b5d2090de187937baf15674aca20299f2ea8e89)
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 typedef union S390Vector {
16     uint64_t doubleword[2];
17     uint32_t word[4];
18     uint16_t halfword[8];
19     uint8_t byte[16];
20 } S390Vector;
21 
22 /*
23  * Each vector is stored as two 64bit host values. So when talking about
24  * byte/halfword/word numbers, we have to take care of proper translation
25  * between element numbers.
26  *
27  * Big Endian (target/possible host)
28  * B:  [ 0][ 1][ 2][ 3][ 4][ 5][ 6][ 7] - [ 8][ 9][10][11][12][13][14][15]
29  * HW: [     0][     1][     2][     3] - [     4][     5][     6][     7]
30  * W:  [             0][             1] - [             2][             3]
31  * DW: [                             0] - [                             1]
32  *
33  * Little Endian (possible host)
34  * B:  [ 7][ 6][ 5][ 4][ 3][ 2][ 1][ 0] - [15][14][13][12][11][10][ 9][ 8]
35  * HW: [     3][     2][     1][     0] - [     7][     6][     5][     4]
36  * W:  [             1][             0] - [             3][             2]
37  * DW: [                             0] - [                             1]
38  */
39 #ifndef HOST_WORDS_BIGENDIAN
40 #define H1(x)  ((x) ^ 7)
41 #define H2(x)  ((x) ^ 3)
42 #define H4(x)  ((x) ^ 1)
43 #else
44 #define H1(x)  (x)
45 #define H2(x)  (x)
46 #define H4(x)  (x)
47 #endif
48 
49 static inline uint8_t s390_vec_read_element8(const S390Vector *v, uint8_t enr)
50 {
51     g_assert(enr < 16);
52     return v->byte[H1(enr)];
53 }
54 
55 static inline uint16_t s390_vec_read_element16(const S390Vector *v, uint8_t enr)
56 {
57     g_assert(enr < 8);
58     return v->halfword[H2(enr)];
59 }
60 
61 static inline uint32_t s390_vec_read_element32(const S390Vector *v, uint8_t enr)
62 {
63     g_assert(enr < 4);
64     return v->word[H4(enr)];
65 }
66 
67 static inline uint64_t s390_vec_read_element64(const S390Vector *v, uint8_t enr)
68 {
69     g_assert(enr < 2);
70     return v->doubleword[enr];
71 }
72 
73 static inline void s390_vec_write_element8(S390Vector *v, uint8_t enr,
74                                            uint8_t data)
75 {
76     g_assert(enr < 16);
77     v->byte[H1(enr)] = data;
78 }
79 
80 static inline void s390_vec_write_element16(S390Vector *v, uint8_t enr,
81                                             uint16_t data)
82 {
83     g_assert(enr < 8);
84     v->halfword[H2(enr)] = data;
85 }
86 
87 static inline void s390_vec_write_element32(S390Vector *v, uint8_t enr,
88                                             uint32_t data)
89 {
90     g_assert(enr < 4);
91     v->word[H4(enr)] = data;
92 }
93 
94 static inline void s390_vec_write_element64(S390Vector *v, uint8_t enr,
95                                             uint64_t data)
96 {
97     g_assert(enr < 2);
98     v->doubleword[enr] = data;
99 }
100 
101 #endif /* S390X_VEC_H */
102