mirror of https://gitlab.com/qemu-project/qemu
target/arm: Convert TBZ, TBNZ to decodetree
Convert the test-and-branch-immediate insns TBZ and TBNZ to decodetree. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20230512144106.3608981-16-peter.maydell@linaro.org
This commit is contained in:
parent
f8977d50fc
commit
e505828d30
|
@ -118,3 +118,9 @@ BL 1 00101 .......................... @branch
|
||||||
&cbz rt imm sf nz
|
&cbz rt imm sf nz
|
||||||
|
|
||||||
CBZ sf:1 011010 nz:1 ................... rt:5 &cbz imm=%imm19
|
CBZ sf:1 011010 nz:1 ................... rt:5 &cbz imm=%imm19
|
||||||
|
|
||||||
|
%imm14 5:s14 !function=times_4
|
||||||
|
%imm31_19 31:1 19:5
|
||||||
|
&tbz rt imm nz bitpos
|
||||||
|
|
||||||
|
TBZ . 011011 nz:1 ..... .............. rt:5 &tbz imm=%imm14 bitpos=%imm31_19
|
||||||
|
|
|
@ -1352,35 +1352,23 @@ static bool trans_CBZ(DisasContext *s, arg_cbz *a)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Test and branch (immediate)
|
static bool trans_TBZ(DisasContext *s, arg_tbz *a)
|
||||||
* 31 30 25 24 23 19 18 5 4 0
|
|
||||||
* +----+-------------+----+-------+-------------+------+
|
|
||||||
* | b5 | 0 1 1 0 1 1 | op | b40 | imm14 | Rt |
|
|
||||||
* +----+-------------+----+-------+-------------+------+
|
|
||||||
*/
|
|
||||||
static void disas_test_b_imm(DisasContext *s, uint32_t insn)
|
|
||||||
{
|
{
|
||||||
unsigned int bit_pos, op, rt;
|
|
||||||
int64_t diff;
|
|
||||||
DisasLabel match;
|
DisasLabel match;
|
||||||
TCGv_i64 tcg_cmp;
|
TCGv_i64 tcg_cmp;
|
||||||
|
|
||||||
bit_pos = (extract32(insn, 31, 1) << 5) | extract32(insn, 19, 5);
|
|
||||||
op = extract32(insn, 24, 1); /* 0: TBZ; 1: TBNZ */
|
|
||||||
diff = sextract32(insn, 5, 14) * 4;
|
|
||||||
rt = extract32(insn, 0, 5);
|
|
||||||
|
|
||||||
tcg_cmp = tcg_temp_new_i64();
|
tcg_cmp = tcg_temp_new_i64();
|
||||||
tcg_gen_andi_i64(tcg_cmp, cpu_reg(s, rt), (1ULL << bit_pos));
|
tcg_gen_andi_i64(tcg_cmp, cpu_reg(s, a->rt), 1ULL << a->bitpos);
|
||||||
|
|
||||||
reset_btype(s);
|
reset_btype(s);
|
||||||
|
|
||||||
match = gen_disas_label(s);
|
match = gen_disas_label(s);
|
||||||
tcg_gen_brcondi_i64(op ? TCG_COND_NE : TCG_COND_EQ,
|
tcg_gen_brcondi_i64(a->nz ? TCG_COND_NE : TCG_COND_EQ,
|
||||||
tcg_cmp, 0, match.label);
|
tcg_cmp, 0, match.label);
|
||||||
gen_goto_tb(s, 0, 4);
|
gen_goto_tb(s, 0, 4);
|
||||||
set_disas_label(s, match);
|
set_disas_label(s, match);
|
||||||
gen_goto_tb(s, 1, diff);
|
gen_goto_tb(s, 1, a->imm);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Conditional branch (immediate)
|
/* Conditional branch (immediate)
|
||||||
|
@ -2397,9 +2385,6 @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
|
||||||
static void disas_b_exc_sys(DisasContext *s, uint32_t insn)
|
static void disas_b_exc_sys(DisasContext *s, uint32_t insn)
|
||||||
{
|
{
|
||||||
switch (extract32(insn, 25, 7)) {
|
switch (extract32(insn, 25, 7)) {
|
||||||
case 0x1b: case 0x5b: /* Test & branch (immediate) */
|
|
||||||
disas_test_b_imm(s, insn);
|
|
||||||
break;
|
|
||||||
case 0x2a: /* Conditional branch (immediate) */
|
case 0x2a: /* Conditional branch (immediate) */
|
||||||
disas_cond_b_imm(s, insn);
|
disas_cond_b_imm(s, insn);
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue