This has been a TODO item for quite a while. The minimum bit count for A32 and T16 is 1, and for T32 is 2.
Reviewed-by: Peter Maydell <peter.mayd...@linaro.org> Signed-off-by: Richard Henderson <richard.hender...@linaro.org> --- target/arm/translate.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/target/arm/translate.c b/target/arm/translate.c index b67e7389d3..b623dbcd48 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -9846,7 +9846,7 @@ static void op_addr_block_post(DisasContext *s, arg_ldst_block *a, } } -static bool op_stm(DisasContext *s, arg_ldst_block *a) +static bool op_stm(DisasContext *s, arg_ldst_block *a, int min_n) { int i, j, n, list, mem_idx; bool user = a->u; @@ -9863,7 +9863,10 @@ static bool op_stm(DisasContext *s, arg_ldst_block *a) list = a->list; n = ctpop16(list); - /* TODO: test invalid n == 0 case */ + if (n < min_n) { + unallocated_encoding(s); + return true; + } addr = op_addr_block_pre(s, a, n); mem_idx = get_mem_index(s); @@ -9896,7 +9899,8 @@ static bool op_stm(DisasContext *s, arg_ldst_block *a) static bool trans_STM(DisasContext *s, arg_ldst_block *a) { - return op_stm(s, a); + /* BitCount(list) < 1 is UNPREDICTABLE */ + return op_stm(s, a, 1); } static bool trans_STM_t32(DisasContext *s, arg_ldst_block *a) @@ -9906,10 +9910,11 @@ static bool trans_STM_t32(DisasContext *s, arg_ldst_block *a) unallocated_encoding(s); return true; } - return op_stm(s, a); + /* BitCount(list) < 2 is UNPREDICTABLE */ + return op_stm(s, a, 2); } -static bool do_ldm(DisasContext *s, arg_ldst_block *a) +static bool do_ldm(DisasContext *s, arg_ldst_block *a, int min_n) { int i, j, n, list, mem_idx; bool loaded_base; @@ -9938,7 +9943,10 @@ static bool do_ldm(DisasContext *s, arg_ldst_block *a) list = a->list; n = ctpop16(list); - /* TODO: test invalid n == 0 case */ + if (n < min_n) { + unallocated_encoding(s); + return true; + } addr = op_addr_block_pre(s, a, n); mem_idx = get_mem_index(s); @@ -10006,7 +10014,8 @@ static bool trans_LDM_a32(DisasContext *s, arg_ldst_block *a) unallocated_encoding(s); return true; } - return do_ldm(s, a); + /* BitCount(list) < 1 is UNPREDICTABLE */ + return do_ldm(s, a, 1); } static bool trans_LDM_t32(DisasContext *s, arg_ldst_block *a) @@ -10016,7 +10025,8 @@ static bool trans_LDM_t32(DisasContext *s, arg_ldst_block *a) unallocated_encoding(s); return true; } - return do_ldm(s, a); + /* BitCount(list) < 2 is UNPREDICTABLE */ + return do_ldm(s, a, 2); } /* -- 2.17.1