target/nios2: Create gen_jumpr

Split out a function to perform an indirect branch.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20220421151735.31996-49-richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson 2022-04-21 08:17:19 -07:00
parent 0706ac0f86
commit bd9154aa2b

View file

@ -36,7 +36,6 @@
#include "semihosting/semihost.h"
/* is_jmp field values */
#define DISAS_JUMP DISAS_TARGET_0 /* only pc was modified dynamically */
#define DISAS_UPDATE DISAS_TARGET_1 /* cpu state was modified dynamically */
#define INSTRUCTION_FLG(func, flags) { (func), (flags) }
@ -195,6 +194,16 @@ static void gen_goto_tb(DisasContext *dc, int n, uint32_t dest)
}
}
static void gen_jumpr(DisasContext *dc, int regno, bool is_call)
{
tcg_gen_mov_tl(cpu_pc, load_gpr(dc, regno));
if (is_call) {
tcg_gen_movi_tl(dest_gpr(dc, R_RA), dc->base.pc_next);
}
tcg_gen_exit_tb(NULL, 0);
dc->base.is_jmp = DISAS_NORETURN;
}
static void gen_excp(DisasContext *dc, uint32_t code, uint32_t flags)
{
t_gen_helper_raise_exception(dc, flags);
@ -437,8 +446,7 @@ static void eret(DisasContext *dc, uint32_t code, uint32_t flags)
/* PC <- ra */
static void ret(DisasContext *dc, uint32_t code, uint32_t flags)
{
tcg_gen_mov_tl(cpu_pc, load_gpr(dc, R_RA));
dc->base.is_jmp = DISAS_JUMP;
gen_jumpr(dc, R_RA, false);
}
/*
@ -468,8 +476,7 @@ static void jmp(DisasContext *dc, uint32_t code, uint32_t flags)
{
R_TYPE(instr, code);
tcg_gen_mov_tl(cpu_pc, load_gpr(dc, instr.a));
dc->base.is_jmp = DISAS_JUMP;
gen_jumpr(dc, instr.a, false);
}
/* rC <- PC + 4 */
@ -488,10 +495,7 @@ static void callr(DisasContext *dc, uint32_t code, uint32_t flags)
{
R_TYPE(instr, code);
tcg_gen_mov_tl(cpu_pc, load_gpr(dc, instr.a));
tcg_gen_movi_tl(dest_gpr(dc, R_RA), dc->base.pc_next);
dc->base.is_jmp = DISAS_JUMP;
gen_jumpr(dc, instr.a, true);
}
/* rC <- ctlN */
@ -909,11 +913,6 @@ static void nios2_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
tcg_gen_exit_tb(NULL, 0);
break;
case DISAS_JUMP:
/* The jump will already have updated the PC register */
tcg_gen_exit_tb(NULL, 0);
break;
case DISAS_NORETURN:
/* nothing more to generate */
break;