aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2022-03-03 11:37:40 +0000
committerPeter Maydell <peter.maydell@linaro.org>2022-03-07 13:16:49 +0000
commitc64ee036ac215f970a76e8c51cb1cfaaef70feb5 (patch)
treeccbd97927981efa838f980d5e0b3724398d1d3d4
parent5df022cf2e5e24910a7d579d5780ae78bc24f247 (diff)
downloadqemu-c64ee036ac215f970a76e8c51cb1cfaaef70feb5.zip
qemu-c64ee036ac215f970a76e8c51cb1cfaaef70feb5.tar.gz
qemu-c64ee036ac215f970a76e8c51cb1cfaaef70feb5.tar.bz2
target/arm/translate-neon: UNDEF if VLD1/VST1 stride bits are non-zero
For VLD1/VST1 (single element to one lane) we are only accessing one register, and so the 'stride' is meaningless. The bits that would specify stride (insn bit [4] for size=1, bit [6] for size=2) are specified to be zero in the encoding (which would correspond to a stride of 1 for VLD2/VLD3/VLD4 etc), and we must UNDEF if they are not. We failed to make this check, which meant that we would incorrectly handle some instruction patterns as loads or stores instead of UNDEFing them. Enforce that stride == 1 for the nregs == 1 case. Resolves: https://gitlab.com/qemu-project/qemu/-/issues/890 Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Tested-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20220303113741.2156877-2-peter.maydell@linaro.org
-rw-r--r--target/arm/translate-neon.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c
index 3854dd3..072fdc1 100644
--- a/target/arm/translate-neon.c
+++ b/target/arm/translate-neon.c
@@ -657,6 +657,9 @@ static bool trans_VLDST_single(DisasContext *s, arg_VLDST_single *a)
/* Catch the UNDEF cases. This is unavoidably a bit messy. */
switch (nregs) {
case 1:
+ if (a->stride != 1) {
+ return false;
+ }
if (((a->align & (1 << a->size)) != 0) ||
(a->size == 2 && (a->align == 1 || a->align == 2))) {
return false;