Skip to content

Commit

Permalink
target/arm: Diagnose too few registers in list for LDM/STM
Browse files Browse the repository at this point in the history
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.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20190904193059.26202-31-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
rth7680 authored and pm215 committed Sep 5, 2019
1 parent 3949f46 commit 4b22254
Showing 1 changed file with 18 additions and 8 deletions.
26 changes: 18 additions & 8 deletions target/arm/translate.c
Expand Up @@ -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;
Expand All @@ -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);
Expand Down Expand Up @@ -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)
Expand All @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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)
Expand All @@ -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);
}

/*
Expand Down

0 comments on commit 4b22254

Please sign in to comment.