aboutsummaryrefslogtreecommitdiff
path: root/target/arm/translate-sve.c
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2018-10-08 14:55:03 +0100
committerPeter Maydell <peter.maydell@linaro.org>2018-10-08 14:55:03 +0100
commit2a99ab2b3545133961de034df27e24f4c22e3707 (patch)
treed96c8650632b711d3043e7d398d9d93fda72ed3c /target/arm/translate-sve.c
parentced3155141755ba244c988c72c4bde32cc819670 (diff)
downloadqemu-2a99ab2b3545133961de034df27e24f4c22e3707.zip
qemu-2a99ab2b3545133961de034df27e24f4c22e3707.tar.gz
qemu-2a99ab2b3545133961de034df27e24f4c22e3707.tar.bz2
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. Tested-by: Laurent Desnogues <laurent.desnogues@gmail.com> Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20181005175350.30752-7-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target/arm/translate-sve.c')
-rw-r--r--target/arm/translate-sve.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 6678795..4ee3bbc 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -4765,12 +4765,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(simd_desc(16, 16, zt));
+
+ 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();
+#ifdef HOST_WORDS_BIGENDIAN
+ poff += 6;
+#endif
+ tcg_gen_ld16u_i64(tmp, cpu_env, poff);
+
+ poff = offsetof(CPUARMState, vfp.preg_tmp);
+ tcg_gen_st_i64(tmp, cpu_env, poff);
+ tcg_temp_free_i64(tmp);
+ }
+
t_pg = tcg_temp_new_ptr();
+ tcg_gen_addi_ptr(t_pg, cpu_env, poff);
- tcg_gen_addi_ptr(t_pg, cpu_env, pred_full_reg_offset(s, pg));
fns[msz](cpu_env, t_pg, addr, desc);
tcg_temp_free_ptr(t_pg);