mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-05 00:33:55 -06:00
target/arm: Enforce alignment for aa64 vector LDn/STn (multiple)
Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20210419202257.161730-30-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
a9e89e539e
commit
c8f638d99a
1 changed files with 11 additions and 4 deletions
|
@ -3635,7 +3635,7 @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
|
||||||
bool is_postidx = extract32(insn, 23, 1);
|
bool is_postidx = extract32(insn, 23, 1);
|
||||||
bool is_q = extract32(insn, 30, 1);
|
bool is_q = extract32(insn, 30, 1);
|
||||||
TCGv_i64 clean_addr, tcg_rn, tcg_ebytes;
|
TCGv_i64 clean_addr, tcg_rn, tcg_ebytes;
|
||||||
MemOp endian = s->be_data;
|
MemOp endian, align, mop;
|
||||||
|
|
||||||
int total; /* total bytes */
|
int total; /* total bytes */
|
||||||
int elements; /* elements per vector */
|
int elements; /* elements per vector */
|
||||||
|
@ -3703,6 +3703,7 @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For our purposes, bytes are always little-endian. */
|
/* For our purposes, bytes are always little-endian. */
|
||||||
|
endian = s->be_data;
|
||||||
if (size == 0) {
|
if (size == 0) {
|
||||||
endian = MO_LE;
|
endian = MO_LE;
|
||||||
}
|
}
|
||||||
|
@ -3721,11 +3722,17 @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
|
||||||
* Consecutive little-endian elements from a single register
|
* Consecutive little-endian elements from a single register
|
||||||
* can be promoted to a larger little-endian operation.
|
* can be promoted to a larger little-endian operation.
|
||||||
*/
|
*/
|
||||||
|
align = MO_ALIGN;
|
||||||
if (selem == 1 && endian == MO_LE) {
|
if (selem == 1 && endian == MO_LE) {
|
||||||
|
align = pow2_align(size);
|
||||||
size = 3;
|
size = 3;
|
||||||
}
|
}
|
||||||
elements = (is_q ? 16 : 8) >> size;
|
if (!s->align_mem) {
|
||||||
|
align = 0;
|
||||||
|
}
|
||||||
|
mop = endian | size | align;
|
||||||
|
|
||||||
|
elements = (is_q ? 16 : 8) >> size;
|
||||||
tcg_ebytes = tcg_const_i64(1 << size);
|
tcg_ebytes = tcg_const_i64(1 << size);
|
||||||
for (r = 0; r < rpt; r++) {
|
for (r = 0; r < rpt; r++) {
|
||||||
int e;
|
int e;
|
||||||
|
@ -3734,9 +3741,9 @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
|
||||||
for (xs = 0; xs < selem; xs++) {
|
for (xs = 0; xs < selem; xs++) {
|
||||||
int tt = (rt + r + xs) % 32;
|
int tt = (rt + r + xs) % 32;
|
||||||
if (is_store) {
|
if (is_store) {
|
||||||
do_vec_st(s, tt, e, clean_addr, size | endian);
|
do_vec_st(s, tt, e, clean_addr, mop);
|
||||||
} else {
|
} else {
|
||||||
do_vec_ld(s, tt, e, clean_addr, size | endian);
|
do_vec_ld(s, tt, e, clean_addr, mop);
|
||||||
}
|
}
|
||||||
tcg_gen_add_i64(clean_addr, clean_addr, tcg_ebytes);
|
tcg_gen_add_i64(clean_addr, clean_addr, tcg_ebytes);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue