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.
Signed-off-by: Richard Henderson
---
target/arm/translate.c | 24
1 file changed, 16 insertions(+), 8 deletions(-)
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 29e2eae441..1792bb7abd 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -9733,7 +9733,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;
@@ -9749,7 +9749,9 @@ 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) {
+return false;
+}
addr = op_addr_block_pre(s, a, n);
mem_idx = get_mem_index(s);
@@ -9782,7 +9784,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)
@@ -9791,10 +9794,11 @@ static bool trans_STM_t32(DisasContext *s,
arg_ldst_block *a)
if (a->w && (a->list & (1 << a->rn))) {
return false;
}
-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;
@@ -9821,7 +9825,9 @@ 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) {
+return false;
+}
addr = op_addr_block_pre(s, a, n);
mem_idx = get_mem_index(s);
@@ -9888,7 +9894,8 @@ static bool trans_LDM_a32(DisasContext *s, arg_ldst_block
*a)
if (ENABLE_ARCH_7 && a->w && (a->list & (1 << a->rn))) {
return false;
}
-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)
@@ -9897,7 +9904,8 @@ static bool trans_LDM_t32(DisasContext *s, arg_ldst_block
*a)
if (a->w && (a->list & (1 << a->rn))) {
return false;
}
-return do_ldm(s, a);
+/* BitCount(list) < 2 is UNPREDICTABLE */
+return do_ldm(s, a, 2);
}
/*
--
2.17.1