target/arm: Diagnose base == pc for LDM/STM

We have been using store_reg and not store_reg_for_load when writing
back a loaded value into the base register. At first glance this is
incorrect when base == pc, however that case is UNPREDICTABLE.

Backports commit b0e382b8cf365fed8b8c43482029ac7655961a85 from qemu
This commit is contained in:
Richard Henderson 2019-11-20 11:25:43 -05:00 committed by Lioncash
parent 1a0986ee25
commit ed9b8ad2ea
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7

View file

@ -10196,7 +10196,7 @@ static bool op_stm(DisasContext *s, arg_ldst_block *a, int min_n)
list = a->list; list = a->list;
n = ctpop16(list); n = ctpop16(list);
if (n < min_n) { if (n < min_n || a->rn == 15) {
unallocated_encoding(s); unallocated_encoding(s);
return true; return true;
} }
@ -10277,7 +10277,7 @@ static bool do_ldm(DisasContext *s, arg_ldst_block *a, int min_n)
list = a->list; list = a->list;
n = ctpop16(list); n = ctpop16(list);
if (n < min_n) { if (n < min_n || a->rn == 15) {
unallocated_encoding(s); unallocated_encoding(s);
return true; return true;
} }
@ -10317,6 +10317,7 @@ static bool do_ldm(DisasContext *s, arg_ldst_block *a, int min_n)
op_addr_block_post(s, a, addr, n); op_addr_block_post(s, a, addr, n);
if (loaded_base) { if (loaded_base) {
/* Note that we reject base == pc above. */
store_reg(s, a->rn, loaded_var); store_reg(s, a->rn, loaded_var);
} }