target/riscv: Sign extend pc for different XLEN
When pc is written, it is sign-extended to fill the widest supported XLEN. Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-id: 20220120122050.41546-5-zhiwei_liu@c-sky.com Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
This commit is contained in:
parent
a14db52f7f
commit
40f0c2046c
@ -102,7 +102,7 @@ static bool trans_mret(DisasContext *ctx, arg_mret *a)
|
||||
static bool trans_wfi(DisasContext *ctx, arg_wfi *a)
|
||||
{
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
|
||||
gen_set_pc_imm(ctx, ctx->pc_succ_insn);
|
||||
gen_helper_wfi(cpu_env);
|
||||
return true;
|
||||
#else
|
||||
|
@ -59,6 +59,7 @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
|
||||
tcg_gen_addi_tl(cpu_pc, get_gpr(ctx, a->rs1, EXT_NONE), a->imm);
|
||||
tcg_gen_andi_tl(cpu_pc, cpu_pc, (target_ulong)-2);
|
||||
|
||||
gen_set_pc(ctx, cpu_pc);
|
||||
if (!has_ext(ctx, RVC)) {
|
||||
TCGv t0 = tcg_temp_new();
|
||||
|
||||
@ -827,7 +828,7 @@ static bool trans_fence_i(DisasContext *ctx, arg_fence_i *a)
|
||||
* FENCE_I is a no-op in QEMU,
|
||||
* however we need to end the translation block
|
||||
*/
|
||||
tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
|
||||
gen_set_pc_imm(ctx, ctx->pc_succ_insn);
|
||||
tcg_gen_exit_tb(NULL, 0);
|
||||
ctx->base.is_jmp = DISAS_NORETURN;
|
||||
return true;
|
||||
@ -836,7 +837,7 @@ static bool trans_fence_i(DisasContext *ctx, arg_fence_i *a)
|
||||
static bool do_csr_post(DisasContext *ctx)
|
||||
{
|
||||
/* We may have changed important cpu state -- exit to main loop. */
|
||||
tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
|
||||
gen_set_pc_imm(ctx, ctx->pc_succ_insn);
|
||||
tcg_gen_exit_tb(NULL, 0);
|
||||
ctx->base.is_jmp = DISAS_NORETURN;
|
||||
return true;
|
||||
|
@ -194,7 +194,7 @@ static bool do_vsetvl(DisasContext *s, int rd, int rs1, TCGv s2)
|
||||
gen_set_gpr(s, rd, dst);
|
||||
mark_vs_dirty(s);
|
||||
|
||||
tcg_gen_movi_tl(cpu_pc, s->pc_succ_insn);
|
||||
gen_set_pc_imm(s, s->pc_succ_insn);
|
||||
tcg_gen_lookup_and_goto_ptr();
|
||||
s->base.is_jmp = DISAS_NORETURN;
|
||||
|
||||
@ -219,7 +219,7 @@ static bool do_vsetivli(DisasContext *s, int rd, TCGv s1, TCGv s2)
|
||||
gen_helper_vsetvl(dst, cpu_env, s1, s2);
|
||||
gen_set_gpr(s, rd, dst);
|
||||
mark_vs_dirty(s);
|
||||
tcg_gen_movi_tl(cpu_pc, s->pc_succ_insn);
|
||||
gen_set_pc_imm(s, s->pc_succ_insn);
|
||||
tcg_gen_lookup_and_goto_ptr();
|
||||
s->base.is_jmp = DISAS_NORETURN;
|
||||
|
||||
|
@ -193,16 +193,33 @@ static void gen_check_nanbox_s(TCGv_i64 out, TCGv_i64 in)
|
||||
tcg_gen_movcond_i64(TCG_COND_GEU, out, in, t_max, in, t_nan);
|
||||
}
|
||||
|
||||
static void gen_set_pc_imm(DisasContext *ctx, target_ulong dest)
|
||||
{
|
||||
if (get_xl(ctx) == MXL_RV32) {
|
||||
dest = (int32_t)dest;
|
||||
}
|
||||
tcg_gen_movi_tl(cpu_pc, dest);
|
||||
}
|
||||
|
||||
static void gen_set_pc(DisasContext *ctx, TCGv dest)
|
||||
{
|
||||
if (get_xl(ctx) == MXL_RV32) {
|
||||
tcg_gen_ext32s_tl(cpu_pc, dest);
|
||||
} else {
|
||||
tcg_gen_mov_tl(cpu_pc, dest);
|
||||
}
|
||||
}
|
||||
|
||||
static void generate_exception(DisasContext *ctx, int excp)
|
||||
{
|
||||
tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
|
||||
gen_set_pc_imm(ctx, ctx->base.pc_next);
|
||||
gen_helper_raise_exception(cpu_env, tcg_constant_i32(excp));
|
||||
ctx->base.is_jmp = DISAS_NORETURN;
|
||||
}
|
||||
|
||||
static void generate_exception_mtval(DisasContext *ctx, int excp)
|
||||
{
|
||||
tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
|
||||
gen_set_pc_imm(ctx, ctx->base.pc_next);
|
||||
tcg_gen_st_tl(cpu_pc, cpu_env, offsetof(CPURISCVState, badaddr));
|
||||
gen_helper_raise_exception(cpu_env, tcg_constant_i32(excp));
|
||||
ctx->base.is_jmp = DISAS_NORETURN;
|
||||
@ -225,10 +242,10 @@ static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
|
||||
{
|
||||
if (translator_use_goto_tb(&ctx->base, dest)) {
|
||||
tcg_gen_goto_tb(n);
|
||||
tcg_gen_movi_tl(cpu_pc, dest);
|
||||
gen_set_pc_imm(ctx, dest);
|
||||
tcg_gen_exit_tb(ctx->base.tb, n);
|
||||
} else {
|
||||
tcg_gen_movi_tl(cpu_pc, dest);
|
||||
gen_set_pc_imm(ctx, dest);
|
||||
tcg_gen_lookup_and_goto_ptr();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user