This patch adds support for branch instructions that act on registers rather than immediates (jmp, call, ret).
Signed-off-by: Alexander Graf <ag...@suse.de> --- target-arm/translate-a64.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index 267fd4d..f4694b4 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -185,6 +185,29 @@ static void handle_b(DisasContext *s, uint32_t insn) s->is_jmp = DISAS_TB_JUMP; } +static void handle_br(DisasContext *s, uint32_t insn) +{ + int branch_type = get_bits(insn, 21, 2); + int source = get_bits(insn, 5, 5); + + switch (branch_type) { + case 0: /* JMP */ + break; + case 1: /* CALL */ + tcg_gen_movi_i64(cpu_reg(30), s->pc); + break; + case 2: /* RET */ + source = 30; + break; + case 3: + unallocated_encoding(s); + return; + } + + tcg_gen_mov_i64(cpu_pc, cpu_reg(source)); + s->is_jmp = DISAS_JUMP; +} + void disas_a64_insn(CPUARMState *env, DisasContext *s) { uint32_t insn; @@ -199,6 +222,12 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s) case 0x5: handle_b(s, insn); goto insn_done; + case 0x35: + if ((insn & 0xff9ffc1f) == 0xd61f0000) { + handle_br(s, insn); + goto insn_done; + } + break; } switch ((insn >> 24) & 0x1f) { -- 1.7.12.4