diff mbox series

[09/11] target/arm: Enforce alignment for VLDn/VSTn (multiple)

Message ID 20201125040642.2339476-10-richard.henderson@linaro.org (mailing list archive)
State New, archived
Headers show
Series target/arm: enforce alignment | expand

Commit Message

Richard Henderson Nov. 25, 2020, 4:06 a.m. UTC
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/translate-neon.c.inc | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)
diff mbox series

Patch

diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
index 32e47331a5..c4be019d9c 100644
--- a/target/arm/translate-neon.c.inc
+++ b/target/arm/translate-neon.c.inc
@@ -427,9 +427,12 @@  static void gen_neon_ldst_base_update(DisasContext *s, int rm, int rn,
 
 static bool trans_VLDST_multiple(DisasContext *s, arg_VLDST_multiple *a)
 {
+    static const MemOp mop_align[4] = {
+        0, MO_ALIGN_8, MO_ALIGN_16, MO_ALIGN_32
+    };
     /* Neon load/store multiple structures */
     int nregs, interleave, spacing, reg, n;
-    MemOp endian = s->be_data;
+    MemOp mop, endian = s->be_data;
     int mmu_idx = get_mem_index(s);
     int size = a->size;
     TCGv_i64 tmp64;
@@ -487,6 +490,10 @@  static bool trans_VLDST_multiple(DisasContext *s, arg_VLDST_multiple *a)
     addr = tcg_temp_new_i32();
     tmp = tcg_const_i32(1 << size);
     load_reg_var(s, addr, a->rn);
+
+    /* Enforce the requested alignment for the first memory operation. */
+    mop = endian | size | mop_align[a->align];
+
     for (reg = 0; reg < nregs; reg++) {
         for (n = 0; n < 8 >> size; n++) {
             int xs;
@@ -494,13 +501,16 @@  static bool trans_VLDST_multiple(DisasContext *s, arg_VLDST_multiple *a)
                 int tt = a->vd + reg + spacing * xs;
 
                 if (a->l) {
-                    gen_aa32_ld_i64(s, tmp64, addr, mmu_idx, endian | size);
+                    gen_aa32_ld_i64(s, tmp64, addr, mmu_idx, mop);
                     neon_store_element64(tt, n, size, tmp64);
                 } else {
                     neon_load_element64(tmp64, tt, n, size);
-                    gen_aa32_st_i64(s, tmp64, addr, mmu_idx, endian | size);
+                    gen_aa32_st_i64(s, tmp64, addr, mmu_idx, mop);
                 }
                 tcg_gen_add_i32(addr, addr, tmp);
+
+                /* Subsequent memory operations inherit alignment */
+                mop &= ~MO_AMASK;
             }
         }
     }