target/arm/translate-neon: UNDEF if VLD1/VST1 stride bits are non-zero
authorPeter Maydell <peter.maydell@linaro.org>
Thu, 3 Mar 2022 11:37:40 +0000 (11:37 +0000)
committerPeter Maydell <peter.maydell@linaro.org>
Mon, 7 Mar 2022 13:16:49 +0000 (13:16 +0000)
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

target/arm/translate-neon.c

index 3854dd3516329ab719d0c2fa1f3c46d7c990e5f4..072fdc1e6ee4b5e2690fe9f803d9ecd4d40a9bb4 100644 (file)
@@ -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;