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.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/arm/translate.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 1792bb7abd..09636aab4e 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -9752,6 +9752,10 @@ static bool op_stm(DisasContext *s, arg_ldst_block *a, int min_n)
if (n < min_n) {
return false;
}
+ /* Using PC as the base register is UNPREDICTABLE. */
+ if (a->rn == 15) {
+ return false;
+ }
addr = op_addr_block_pre(s, a, n);
mem_idx = get_mem_index(s);
@@ -9828,6 +9832,10 @@ static bool do_ldm(DisasContext *s, arg_ldst_block *a, int min_n)
if (n < min_n) {
return false;
}
+ /* Using PC as the base register is UNPREDICTABLE. */
+ if (a->rn == 15) {
+ return false;
+ }
addr = op_addr_block_pre(s, a, n);
mem_idx = get_mem_index(s);
@@ -9864,6 +9872,7 @@ static bool do_ldm(DisasContext *s, arg_ldst_block *a, int min_n)
op_addr_block_post(s, a, addr, n);
if (loaded_base) {
+ /* Note that we reject base == pc above. */
store_reg(s, a->rn, loaded_var);
}
--
2.17.1