diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2022-04-21 08:17:19 -0700 |
---|---|---|
committer | Richard Henderson <richard.henderson@linaro.org> | 2022-04-26 08:17:05 -0700 |
commit | bd9154aa2b7b66e542e243a460912b25c94799de (patch) | |
tree | 78e432a1813c1e86876689266934d77a77449cc6 /target/nios2 | |
parent | 0706ac0f860896a73299cb4d2de50a9216e2f5bb (diff) |
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>
Diffstat (limited to 'target/nios2')
-rw-r--r-- | target/nios2/translate.c | 27 |
1 files changed, 13 insertions, 14 deletions
diff --git a/target/nios2/translate.c b/target/nios2/translate.c index e2742a8556..8616813365 100644 --- a/target/nios2/translate.c +++ b/target/nios2/translate.c @@ -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; |