target/riscv: Enable PC-relative translation

Add a base pc_save for PC-relative translation(CF_PCREL).
Diable the directly sync pc from tb by riscv_cpu_synchronize_from_tb.
Use gen_pc_plus_diff to get the pc-relative address.
Enable CF_PCREL in System mode.

Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-Id: <20230526072124.298466-7-liweiwei@iscas.ac.cn>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
This commit is contained in:
Weiwei Li 2023-05-26 15:21:23 +08:00 committed by Alistair Francis
parent 227fb82f99
commit 356c13f94d
4 changed files with 74 additions and 20 deletions

View file

@ -721,16 +721,18 @@ static vaddr riscv_cpu_get_pc(CPUState *cs)
static void riscv_cpu_synchronize_from_tb(CPUState *cs,
const TranslationBlock *tb)
{
RISCVCPU *cpu = RISCV_CPU(cs);
CPURISCVState *env = &cpu->env;
RISCVMXL xl = FIELD_EX32(tb->flags, TB_FLAGS, XL);
if (!(tb_cflags(tb) & CF_PCREL)) {
RISCVCPU *cpu = RISCV_CPU(cs);
CPURISCVState *env = &cpu->env;
RISCVMXL xl = FIELD_EX32(tb->flags, TB_FLAGS, XL);
tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL));
tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL));
if (xl == MXL_RV32) {
env->pc = (int32_t) tb->pc;
} else {
env->pc = tb->pc;
if (xl == MXL_RV32) {
env->pc = (int32_t) tb->pc;
} else {
env->pc = tb->pc;
}
}
}
@ -756,11 +758,18 @@ static void riscv_restore_state_to_opc(CPUState *cs,
RISCVCPU *cpu = RISCV_CPU(cs);
CPURISCVState *env = &cpu->env;
RISCVMXL xl = FIELD_EX32(tb->flags, TB_FLAGS, XL);
target_ulong pc;
if (tb_cflags(tb) & CF_PCREL) {
pc = (env->pc & TARGET_PAGE_MASK) | data[0];
} else {
pc = data[0];
}
if (xl == MXL_RV32) {
env->pc = (int32_t)data[0];
env->pc = (int32_t)pc;
} else {
env->pc = data[0];
env->pc = pc;
}
env->bins = data[1];
}
@ -1343,6 +1352,8 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
}
#ifndef CONFIG_USER_ONLY
cs->tcg_cflags |= CF_PCREL;
if (cpu->cfg.ext_sstc) {
riscv_timer_init(cpu);
}