On 27/2/23 06:41, Richard Henderson wrote:
> Here it is not trivial to notice first initialization, so explicitly
> zero the temps. Use an array for the output, rather than separate
> tcg_rd/tcg_rd_hi variables.
>
> Fixes a bug by adding a missing clear_vec_high.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> target/arm/translate-a64.c | 26 +++++++++++++++-----------
> 1 file changed, 15 insertions(+), 11 deletions(-)
>
> diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
> index 16aa71451c..02a61aa8b7 100644
> --- a/target/arm/translate-a64.c
> +++ b/target/arm/translate-a64.c
> @@ -12003,22 +12003,26 @@ static void handle_rev(DisasContext *s, int opcode, bool u,
> int esize = 8 << size;
> int elements = dsize / esize;
> TCGv_i64 tcg_rn = tcg_temp_new_i64();
> - TCGv_i64 tcg_rd = tcg_const_i64(0);
> - TCGv_i64 tcg_rd_hi = tcg_const_i64(0);
> + TCGv_i64 tcg_rd[2];
> +
> + for (i = 0; i < 2; i++) {
> + tcg_rd[i] = tcg_temp_new_i64();
> + tcg_gen_movi_i64(tcg_rd[i], 0);
> + }
>
> for (i = 0; i < elements; i++) {
> int e_rev = (i & 0xf) ^ revmask;
> - int off = e_rev * esize;
> + int w = (e_rev * esize) / 64;
> + int o = (e_rev * esize) % 64;
> +
> read_vec_element(s, tcg_rn, rn, i, size);
> - if (off >= 64) {
> - tcg_gen_deposit_i64(tcg_rd_hi, tcg_rd_hi,
> - tcg_rn, off - 64, esize);
> - } else {
> - tcg_gen_deposit_i64(tcg_rd, tcg_rd, tcg_rn, off, esize);
> - }
> + tcg_gen_deposit_i64(tcg_rd[w], tcg_rd[w], tcg_rn, o, esize);
> }
> - write_vec_element(s, tcg_rd, rd, 0, MO_64);
> - write_vec_element(s, tcg_rd_hi, rd, 1, MO_64);
> +
> + for (i = 0; i < 2; i++) {
> + write_vec_element(s, tcg_rd[i], rd, i, MO_64);
> + }
Preferably splitting the bugfix in a preliminary patch,
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> + clear_vec_high(s, true, rd);
> }
> }
>