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