diff options
Diffstat (limited to 'target/nios2/translate.c')
| -rw-r--r-- | target/nios2/translate.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/target/nios2/translate.c b/target/nios2/translate.c index a3e87beba4..794b763d8a 100644 --- a/target/nios2/translate.c +++ b/target/nios2/translate.c @@ -197,11 +197,24 @@ 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)); + TCGLabel *l = gen_new_label(); + TCGv test = tcg_temp_new(); + TCGv dest = load_gpr(dc, regno); + + tcg_gen_andi_tl(test, dest, 3); + tcg_gen_brcondi_tl(TCG_COND_NE, test, 0, l); + tcg_temp_free(test); + + tcg_gen_mov_tl(cpu_pc, dest); if (is_call) { tcg_gen_movi_tl(dest_gpr(dc, R_RA), dc->base.pc_next); } tcg_gen_lookup_and_goto_ptr(); + + gen_set_label(l); + tcg_gen_st_tl(dest, cpu_env, offsetof(CPUNios2State, ctrl[CR_BADADDR])); + t_gen_helper_raise_exception(dc, EXCP_UNALIGND); + dc->base.is_jmp = DISAS_NORETURN; } |