target/arm: Clear unused predicate bits for LD1RQ

The 16-byte load only uses 16 predicate bits. But while
reusing the other load infrastructure, we find other bits
that are set and trigger an assert. To avoid this and
retain the assert, zero-extend the predicate that we pass
to the LD1 helper.

Backports commit 2a99ab2b3545133961de034df27e24f4c22e3707 from qemu
This commit is contained in:
Richard Henderson 2018-10-08 11:30:35 -04:00 committed by Lioncash
parent a37f24aa11
commit 935eb43b5e
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7

View file

@ -4936,12 +4936,33 @@ static void do_ldrq(DisasContext *s, int zt, int pg, TCGv_i64 addr, int msz)
unsigned vsz = vec_full_reg_size(s);
TCGv_ptr t_pg;
TCGv_i32 desc;
int poff;
/* Load the first quadword using the normal predicated load helpers. */
desc = tcg_const_i32(tcg_ctx, simd_desc(16, 16, zt));
t_pg = tcg_temp_new_ptr(tcg_ctx);
tcg_gen_addi_ptr(tcg_ctx, t_pg, tcg_ctx->cpu_env, pred_full_reg_offset(s, pg));
poff = pred_full_reg_offset(s, pg);
if (vsz > 16) {
/*
* Zero-extend the first 16 bits of the predicate into a temporary.
* This avoids triggering an assert making sure we don't have bits
* set within a predicate beyond VQ, but we have lowered VQ to 1
* for this load operation.
*/
TCGv_i64 tmp = tcg_temp_new_i64(tcg_ctx);
#ifdef HOST_WORDS_BIGENDIAN
poff += 6;
#endif
tcg_gen_ld16u_i64(tcg_ctx, tmp, tcg_ctx->cpu_env, poff);
poff = offsetof(CPUARMState, vfp.preg_tmp);
tcg_gen_st_i64(tcg_ctx, tmp, tcg_ctx->cpu_env, poff);
tcg_temp_free_i64(tcg_ctx, tmp);
}
t_pg = tcg_temp_new_ptr(tcg_ctx);
tcg_gen_addi_ptr(tcg_ctx, t_pg, tcg_ctx->cpu_env, poff);
fns[msz](tcg_ctx, tcg_ctx->cpu_env, t_pg, addr, desc);
tcg_temp_free_ptr(tcg_ctx, t_pg);