On 07/03/2019 13.15, David Hildenbrand wrote: > We'll have to read/write vector elements quite frequently from helpers. > The tricky bit is properly taking care of endianess. Handle it similar > to aarch64. > > Signed-off-by: David Hildenbrand <da...@redhat.com> > --- > target/s390x/vec.h | 101 +++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 101 insertions(+) > create mode 100644 target/s390x/vec.h > > diff --git a/target/s390x/vec.h b/target/s390x/vec.h > new file mode 100644 > index 0000000000..3313fb43ee > --- /dev/null > +++ b/target/s390x/vec.h > @@ -0,0 +1,101 @@ > +/* > + * QEMU TCG support -- s390x vector utilitites > + * > + * Copyright (C) 2019 Red Hat Inc > + * > + * Authors: > + * David Hildenbrand <da...@redhat.com> > + * > + * This work is licensed under the terms of the GNU GPL, version 2 or later. > + * See the COPYING file in the top-level directory. > + */ > +#ifndef S390X_VEC_H > +#define S390X_VEC_H > + > +typedef union S390Vector { > + uint64_t doubleword[2]; > + uint32_t word[4]; > + uint16_t halfword[8]; > + uint8_t byte[16]; > +} S390Vector; > + > +/* > + * Each vector is stored as two 64bit host values. So when talking about > + * byte/halfword/word numbers, we have to take care of proper translation > + * between element numbers. > + * > + * Big Endian (target/possible host) > + * B: [ 0][ 1][ 2][ 3][ 4][ 5][ 6][ 7] - [ 8][ 9][10][11][12][13][14][15] > + * HW: [ 0][ 1][ 2][ 3] - [ 4][ 5][ 6][ 7] > + * W: [ 0][ 1] - [ 2][ 3] > + * DW: [ 0] - [ 1] > + * > + * Little Endian (possible host) > + * B: [ 7][ 6][ 5][ 4][ 3][ 2][ 1][ 0] - [15][14][13][12][11][10][ 9][ 8] > + * HW: [ 3][ 2][ 1][ 0] - [ 7][ 6][ 5][ 4] > + * W: [ 1][ 0] - [ 3][ 2] > + * DW: [ 0] - [ 1] > + */ > +#ifndef HOST_WORDS_BIGENDIAN > +#define H1(x) ((x) ^ 7) > +#define H2(x) ((x) ^ 3) > +#define H4(x) ((x) ^ 1) > +#else > +#define H1(x) (x) > +#define H2(x) (x) > +#define H4(x) (x) > +#endif > + > +static inline uint8_t s390_vec_read_element8(const S390Vector *v, uint8_t > enr) > +{ > + g_assert(enr < 16); > + return v->byte[H1(enr)]; > +} > + > +static inline uint16_t s390_vec_read_element16(const S390Vector *v, uint8_t > enr) > +{ > + g_assert(enr < 8); > + return v->halfword[H2(enr)]; > +} > + > +static inline uint32_t s390_vec_read_element32(const S390Vector *v, uint8_t > enr) > +{ > + g_assert(enr < 4); > + return v->word[H4(enr)]; > +} > + > +static inline uint64_t s390_vec_read_element64(const S390Vector *v, uint8_t > enr) > +{ > + g_assert(enr < 2); > + return v->doubleword[enr]; > +} > + > +static inline void s390_vec_write_element8(S390Vector *v, uint8_t enr, > + uint8_t data) > +{ > + g_assert(enr < 16); > + v->byte[H1(enr)] = data; > +} > + > +static inline void s390_vec_write_element16(S390Vector *v, uint8_t enr, > + uint16_t data) > +{ > + g_assert(enr < 8); > + v->halfword[H2(enr)] = data; > +} > + > +static inline void s390_vec_write_element32(S390Vector *v, uint8_t enr, > + uint32_t data) > +{ > + g_assert(enr < 4); > + v->word[H4(enr)] = data; > +} > + > +static inline void s390_vec_write_element64(S390Vector *v, uint8_t enr, > + uint64_t data) > +{ > + g_assert(enr < 2); > + v->doubleword[enr] = data; > +} > + > +#endif /* S390X_VEC_H */ >
Pretty brain-twisting, but it looks right to me. Reviewed-by: Thomas Huth <th...@redhat.com>