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.hender...@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