On 16 May 2018 at 23:30, Richard Henderson <richard.henderson@linaro.org> wrote:
> Rearrange the arithmetic so that we are agnostic about the total size
> of the vector and the size of the element. This will allow us to index
> up to the 32nd byte and with 16-byte elements.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> target/arm/translate-a64.h | 14 +++++++-------
> 1 file changed, 7 insertions(+), 7 deletions(-)
>
> diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
> index dd9c09f89b..5a97ae2b59 100644
> --- a/target/arm/translate-a64.h
> +++ b/target/arm/translate-a64.h
> @@ -67,18 +67,18 @@ static inline void assert_fp_access_checked(DisasContext *s)
> static inline int vec_reg_offset(DisasContext *s, int regno,
> int element, TCGMemOp size)
> {
> - int offs = 0;
> + int element_size = 1 << size;
> + int offs = element * element_size;
> #ifdef HOST_WORDS_BIGENDIAN
> /* This is complicated slightly because vfp.zregs[n].d[0] is
> * still the low half and vfp.zregs[n].d[1] the high half
> * of the 128 bit vector, even on big endian systems.
> - * Calculate the offset assuming a fully bigendian 128 bits,
> - * then XOR to account for the order of the two 64 bit halves.
> + * Calculate the offset assuming a fully little-endian 128 bits,
> + * then XOR to account for the order of the 64 bit units.
> */
> - offs += (16 - ((element + 1) * (1 << size)));
> - offs ^= 8;
> -#else
> - offs += element * (1 << size);
> + if (element_size < 8) {
> + offs ^= 8 - element_size;
> + }
> #endif
> offs += offsetof(CPUARMState, vfp.zregs[regno]);
> assert_fp_access_checked(s);
This looks right for element sizes up to 8, but I don't understand
how it handles 16 byte elements as the commit message says -- the
d[0] and d[1] are the wrong way round and don't form a single
16-byte big-endian value, so they must need special casing somewhere
else ?
thanks
-- PMM