* [PATCH v6 0/6] target/riscv: Fix pointer mask related support
@ 2023-04-04 2:06 Weiwei Li
2023-04-04 2:06 ` [PATCH v6 1/6] target/riscv: Fix pointer mask transformation for vector address Weiwei Li
` (5 more replies)
0 siblings, 6 replies; 26+ messages in thread
From: Weiwei Li @ 2023-04-04 2:06 UTC (permalink / raw)
To: qemu-riscv, qemu-devel
Cc: palmer, alistair.francis, bin.meng, dbarboza, zhiwei_liu,
wangjunqiang, lazyparser, Weiwei Li
This patchset tries to fix some problem in current implementation for pointer mask, and add support for pointer mask of instruction fetch.
The port is available here:
https://github.com/plctlab/plct-qemu/tree/plct-pm-fix-v6
v2:
* drop some error patchs
* Add patch 2 and 3 to fix the new problems
* Add patch 4 and 5 to use PC-relative translation for pointer mask for instruction fetch
v3:
* use target_pc temp instead of cpu_pc to store into badaddr in patch 3
* use dest_gpr instead of tcg_temp_new() for succ_pc in patch 4
* enable CF_PCREL for system mode in seperate patch 5
v4:
* Fix wrong pc_save value for conditional jump in patch 4
* Fix tcg_cflags overwrite problem to make CF_PCREL really work in new patch 5
* Fix tb mis-matched problem in new patch 6
v5:
* use gen_get_target_pc to compute target address of auipc and successor address of jalr in patch 4.
* separate tcg related fix patches(5, 6) from this patchset
v6:
* rename gen_get_target_pc as gen_pc_plus_diff in patch 3 and patch 4
* use gen_pc_plus_diff to compute successor address of jal in patch 4
* Mov comments for patch 5 to patch 4
Weiwei Li (6):
target/riscv: Fix pointer mask transformation for vector address
target/riscv: Update cur_pmmask/base when xl changes
target/riscv: Fix target address to update badaddr
target/riscv: Add support for PC-relative translation
target/riscv: Enable PC-relative translation in system mode
target/riscv: Add pointer mask support for instruction fetch
target/riscv/cpu.c | 31 ++++++++----
target/riscv/cpu.h | 1 +
target/riscv/cpu_helper.c | 20 +++++++-
target/riscv/csr.c | 11 ++--
target/riscv/insn_trans/trans_rvi.c.inc | 37 ++++++++++----
target/riscv/translate.c | 67 ++++++++++++++++++-------
target/riscv/vector_helper.c | 2 +-
7 files changed, 126 insertions(+), 43 deletions(-)
--
2.25.1
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH v6 1/6] target/riscv: Fix pointer mask transformation for vector address
2023-04-04 2:06 [PATCH v6 0/6] target/riscv: Fix pointer mask related support Weiwei Li
@ 2023-04-04 2:06 ` Weiwei Li
2023-04-05 4:38 ` Alistair Francis
2023-04-04 2:06 ` [PATCH v6 2/6] target/riscv: Update cur_pmmask/base when xl changes Weiwei Li
` (4 subsequent siblings)
5 siblings, 1 reply; 26+ messages in thread
From: Weiwei Li @ 2023-04-04 2:06 UTC (permalink / raw)
To: qemu-riscv, qemu-devel
Cc: palmer, alistair.francis, bin.meng, dbarboza, zhiwei_liu,
wangjunqiang, lazyparser, Weiwei Li
actual_address = (requested_address & ~mpmmask) | mpmbase.
Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
---
target/riscv/vector_helper.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 2423affe37..a58d82af8c 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -172,7 +172,7 @@ static inline uint32_t vext_get_total_elems(CPURISCVState *env, uint32_t desc,
static inline target_ulong adjust_addr(CPURISCVState *env, target_ulong addr)
{
- return (addr & env->cur_pmmask) | env->cur_pmbase;
+ return (addr & ~env->cur_pmmask) | env->cur_pmbase;
}
/*
--
2.25.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v6 2/6] target/riscv: Update cur_pmmask/base when xl changes
2023-04-04 2:06 [PATCH v6 0/6] target/riscv: Fix pointer mask related support Weiwei Li
2023-04-04 2:06 ` [PATCH v6 1/6] target/riscv: Fix pointer mask transformation for vector address Weiwei Li
@ 2023-04-04 2:06 ` Weiwei Li
2023-04-05 4:38 ` Alistair Francis
2023-04-04 2:06 ` [PATCH v6 3/6] target/riscv: Fix target address to update badaddr Weiwei Li
` (3 subsequent siblings)
5 siblings, 1 reply; 26+ messages in thread
From: Weiwei Li @ 2023-04-04 2:06 UTC (permalink / raw)
To: qemu-riscv, qemu-devel
Cc: palmer, alistair.francis, bin.meng, dbarboza, zhiwei_liu,
wangjunqiang, lazyparser, Weiwei Li
write_mstatus() can only change current xl when in debug mode.
And we need update cur_pmmask/base in this case.
Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
---
target/riscv/csr.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index d522efc0b6..43b9ad4500 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1277,8 +1277,15 @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno,
mstatus = set_field(mstatus, MSTATUS64_SXL, xl);
}
env->mstatus = mstatus;
- env->xl = cpu_recompute_xl(env);
+ /*
+ * Except in debug mode, UXL/SXL can only be modified by higher
+ * privilege mode. So xl will not be changed in normal mode.
+ */
+ if (env->debugger) {
+ env->xl = cpu_recompute_xl(env);
+ riscv_cpu_update_mask(env);
+ }
return RISCV_EXCP_NONE;
}
--
2.25.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v6 3/6] target/riscv: Fix target address to update badaddr
2023-04-04 2:06 [PATCH v6 0/6] target/riscv: Fix pointer mask related support Weiwei Li
2023-04-04 2:06 ` [PATCH v6 1/6] target/riscv: Fix pointer mask transformation for vector address Weiwei Li
2023-04-04 2:06 ` [PATCH v6 2/6] target/riscv: Update cur_pmmask/base when xl changes Weiwei Li
@ 2023-04-04 2:06 ` Weiwei Li
2023-04-04 3:06 ` LIU Zhiwei
2023-04-05 4:41 ` Alistair Francis
2023-04-04 2:06 ` [PATCH v6 4/6] target/riscv: Add support for PC-relative translation Weiwei Li
` (2 subsequent siblings)
5 siblings, 2 replies; 26+ messages in thread
From: Weiwei Li @ 2023-04-04 2:06 UTC (permalink / raw)
To: qemu-riscv, qemu-devel
Cc: palmer, alistair.francis, bin.meng, dbarboza, zhiwei_liu,
wangjunqiang, lazyparser, Weiwei Li, Richard Henderson
Compute the target address before storing it into badaddr
when mis-aligned exception is triggered.
Use a target_pc temp to store the target address to avoid
the confusing operation that udpate target address into
cpu_pc before misalign check, then update it into badaddr
and restore cpu_pc to current pc if exception is triggered.
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>
---
target/riscv/insn_trans/trans_rvi.c.inc | 23 ++++++++++++++++-------
target/riscv/translate.c | 21 ++++++++++-----------
2 files changed, 26 insertions(+), 18 deletions(-)
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
index 4ad54e8a49..cc72864d32 100644
--- a/target/riscv/insn_trans/trans_rvi.c.inc
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
@@ -51,25 +51,30 @@ static bool trans_jal(DisasContext *ctx, arg_jal *a)
static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
{
TCGLabel *misaligned = NULL;
+ TCGv target_pc = tcg_temp_new();
- 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);
+ tcg_gen_addi_tl(target_pc, get_gpr(ctx, a->rs1, EXT_NONE), a->imm);
+ tcg_gen_andi_tl(target_pc, target_pc, (target_ulong)-2);
+
+ if (get_xl(ctx) == MXL_RV32) {
+ tcg_gen_ext32s_tl(target_pc, target_pc);
+ }
- gen_set_pc(ctx, cpu_pc);
if (!has_ext(ctx, RVC)) {
TCGv t0 = tcg_temp_new();
misaligned = gen_new_label();
- tcg_gen_andi_tl(t0, cpu_pc, 0x2);
+ tcg_gen_andi_tl(t0, target_pc, 0x2);
tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0x0, misaligned);
}
gen_set_gpri(ctx, a->rd, ctx->pc_succ_insn);
+ tcg_gen_mov_tl(cpu_pc, target_pc);
lookup_and_goto_ptr(ctx);
if (misaligned) {
gen_set_label(misaligned);
- gen_exception_inst_addr_mis(ctx);
+ gen_exception_inst_addr_mis(ctx, target_pc);
}
ctx->base.is_jmp = DISAS_NORETURN;
@@ -153,6 +158,7 @@ static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond)
TCGLabel *l = gen_new_label();
TCGv src1 = get_gpr(ctx, a->rs1, EXT_SIGN);
TCGv src2 = get_gpr(ctx, a->rs2, EXT_SIGN);
+ target_ulong next_pc;
if (get_xl(ctx) == MXL_RV128) {
TCGv src1h = get_gprh(ctx, a->rs1);
@@ -169,9 +175,12 @@ static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond)
gen_set_label(l); /* branch taken */
- if (!has_ext(ctx, RVC) && ((ctx->base.pc_next + a->imm) & 0x3)) {
+ next_pc = ctx->base.pc_next + a->imm;
+ if (!has_ext(ctx, RVC) && (next_pc & 0x3)) {
/* misaligned */
- gen_exception_inst_addr_mis(ctx);
+ TCGv target_pc = tcg_temp_new();
+ gen_pc_plus_diff(target_pc, ctx, next_pc);
+ gen_exception_inst_addr_mis(ctx, target_pc);
} else {
gen_goto_tb(ctx, 0, ctx->base.pc_next + a->imm);
}
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 0ee8ee147d..d434fedb37 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -222,21 +222,18 @@ static void decode_save_opc(DisasContext *ctx)
ctx->insn_start = NULL;
}
-static void gen_set_pc_imm(DisasContext *ctx, target_ulong dest)
+static void gen_pc_plus_diff(TCGv target, DisasContext *ctx,
+ target_ulong dest)
{
if (get_xl(ctx) == MXL_RV32) {
dest = (int32_t)dest;
}
- tcg_gen_movi_tl(cpu_pc, dest);
+ tcg_gen_movi_tl(target, dest);
}
-static void gen_set_pc(DisasContext *ctx, TCGv dest)
+static void gen_set_pc_imm(DisasContext *ctx, target_ulong dest)
{
- if (get_xl(ctx) == MXL_RV32) {
- tcg_gen_ext32s_tl(cpu_pc, dest);
- } else {
- tcg_gen_mov_tl(cpu_pc, dest);
- }
+ gen_pc_plus_diff(cpu_pc, ctx, dest);
}
static void generate_exception(DisasContext *ctx, int excp)
@@ -257,9 +254,9 @@ static void gen_exception_illegal(DisasContext *ctx)
}
}
-static void gen_exception_inst_addr_mis(DisasContext *ctx)
+static void gen_exception_inst_addr_mis(DisasContext *ctx, TCGv target)
{
- tcg_gen_st_tl(cpu_pc, cpu_env, offsetof(CPURISCVState, badaddr));
+ tcg_gen_st_tl(target, cpu_env, offsetof(CPURISCVState, badaddr));
generate_exception(ctx, RISCV_EXCP_INST_ADDR_MIS);
}
@@ -551,7 +548,9 @@ static void gen_jal(DisasContext *ctx, int rd, target_ulong imm)
next_pc = ctx->base.pc_next + imm;
if (!has_ext(ctx, RVC)) {
if ((next_pc & 0x3) != 0) {
- gen_exception_inst_addr_mis(ctx);
+ TCGv target_pc = tcg_temp_new();
+ gen_pc_plus_diff(target_pc, ctx, next_pc);
+ gen_exception_inst_addr_mis(ctx, target_pc);
return;
}
}
--
2.25.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v6 4/6] target/riscv: Add support for PC-relative translation
2023-04-04 2:06 [PATCH v6 0/6] target/riscv: Fix pointer mask related support Weiwei Li
` (2 preceding siblings ...)
2023-04-04 2:06 ` [PATCH v6 3/6] target/riscv: Fix target address to update badaddr Weiwei Li
@ 2023-04-04 2:06 ` Weiwei Li
2023-04-04 3:12 ` LIU Zhiwei
2023-04-04 13:56 ` Richard Henderson
2023-04-04 2:06 ` [PATCH v6 5/6] target/riscv: Enable PC-relative translation in system mode Weiwei Li
2023-04-04 2:06 ` [PATCH v6 6/6] target/riscv: Add pointer mask support for instruction fetch Weiwei Li
5 siblings, 2 replies; 26+ messages in thread
From: Weiwei Li @ 2023-04-04 2:06 UTC (permalink / raw)
To: qemu-riscv, qemu-devel
Cc: palmer, alistair.francis, bin.meng, dbarboza, zhiwei_liu,
wangjunqiang, lazyparser, Weiwei Li, Richard Henderson
Add a base pc_save for PC-relative translation(CF_PCREL).
Diable the directly sync pc from tb by riscv_cpu_synchronize_from_tb.
We can get pc-relative address from following formula:
real_pc = (old)env->pc + diff, where diff = target_pc - ctx->pc_save.
Use gen_get_target_pc to compute target address of auipc and successor
address of jalr and jal.
The existence of CF_PCREL can improve performance with the guest
kernel's address space randomization. Each guest process maps libc.so
(et al) at a different virtual address, and this allows those
translations to be shared.
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>
---
target/riscv/cpu.c | 29 +++++++++------
target/riscv/insn_trans/trans_rvi.c.inc | 14 ++++++--
target/riscv/translate.c | 48 ++++++++++++++++++++-----
3 files changed, 70 insertions(+), 21 deletions(-)
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 1e97473af2..646fa31a59 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -658,16 +658,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;
+ }
}
}
@@ -693,11 +695,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];
}
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
index cc72864d32..7cbbdac5aa 100644
--- a/target/riscv/insn_trans/trans_rvi.c.inc
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
@@ -38,7 +38,9 @@ static bool trans_lui(DisasContext *ctx, arg_lui *a)
static bool trans_auipc(DisasContext *ctx, arg_auipc *a)
{
- gen_set_gpri(ctx, a->rd, a->imm + ctx->base.pc_next);
+ TCGv target_pc = dest_gpr(ctx, a->rd);
+ gen_pc_plus_diff(target_pc, ctx, a->imm + ctx->base.pc_next);
+ gen_set_gpr(ctx, a->rd, target_pc);
return true;
}
@@ -52,6 +54,7 @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
{
TCGLabel *misaligned = NULL;
TCGv target_pc = tcg_temp_new();
+ TCGv succ_pc = dest_gpr(ctx, a->rd);
tcg_gen_addi_tl(target_pc, get_gpr(ctx, a->rs1, EXT_NONE), a->imm);
tcg_gen_andi_tl(target_pc, target_pc, (target_ulong)-2);
@@ -68,7 +71,9 @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0x0, misaligned);
}
- gen_set_gpri(ctx, a->rd, ctx->pc_succ_insn);
+ gen_pc_plus_diff(succ_pc, ctx, ctx->pc_succ_insn);
+ gen_set_gpr(ctx, a->rd, succ_pc);
+
tcg_gen_mov_tl(cpu_pc, target_pc);
lookup_and_goto_ptr(ctx);
@@ -159,6 +164,7 @@ static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond)
TCGv src1 = get_gpr(ctx, a->rs1, EXT_SIGN);
TCGv src2 = get_gpr(ctx, a->rs2, EXT_SIGN);
target_ulong next_pc;
+ target_ulong orig_pc_save = ctx->pc_save;
if (get_xl(ctx) == MXL_RV128) {
TCGv src1h = get_gprh(ctx, a->rs1);
@@ -175,6 +181,7 @@ static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond)
gen_set_label(l); /* branch taken */
+ ctx->pc_save = orig_pc_save;
next_pc = ctx->base.pc_next + a->imm;
if (!has_ext(ctx, RVC) && (next_pc & 0x3)) {
/* misaligned */
@@ -182,8 +189,9 @@ static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond)
gen_pc_plus_diff(target_pc, ctx, next_pc);
gen_exception_inst_addr_mis(ctx, target_pc);
} else {
- gen_goto_tb(ctx, 0, ctx->base.pc_next + a->imm);
+ gen_goto_tb(ctx, 0, next_pc);
}
+ ctx->pc_save = -1;
ctx->base.is_jmp = DISAS_NORETURN;
return true;
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index d434fedb37..4623749602 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -59,6 +59,7 @@ typedef struct DisasContext {
DisasContextBase base;
/* pc_succ_insn points to the instruction following base.pc_next */
target_ulong pc_succ_insn;
+ target_ulong pc_save;
target_ulong priv_ver;
RISCVMXL misa_mxl_max;
RISCVMXL xl;
@@ -225,15 +226,24 @@ static void decode_save_opc(DisasContext *ctx)
static void gen_pc_plus_diff(TCGv target, DisasContext *ctx,
target_ulong dest)
{
- if (get_xl(ctx) == MXL_RV32) {
- dest = (int32_t)dest;
+ assert(ctx->pc_save != -1);
+ if (tb_cflags(ctx->base.tb) & CF_PCREL) {
+ tcg_gen_addi_tl(target, cpu_pc, dest - ctx->pc_save);
+ if (get_xl(ctx) == MXL_RV32) {
+ tcg_gen_ext32s_tl(target, target);
+ }
+ } else {
+ if (get_xl(ctx) == MXL_RV32) {
+ dest = (int32_t)dest;
+ }
+ tcg_gen_movi_tl(target, dest);
}
- tcg_gen_movi_tl(target, dest);
}
static void gen_set_pc_imm(DisasContext *ctx, target_ulong dest)
{
gen_pc_plus_diff(cpu_pc, ctx, dest);
+ ctx->pc_save = dest;
}
static void generate_exception(DisasContext *ctx, int excp)
@@ -287,8 +297,21 @@ static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
* direct block chain benefits will be small.
*/
if (translator_use_goto_tb(&ctx->base, dest) && !ctx->itrigger) {
- tcg_gen_goto_tb(n);
- gen_set_pc_imm(ctx, dest);
+ /*
+ * For pcrel, the pc must always be up-to-date on entry to
+ * the linked TB, so that it can use simple additions for all
+ * further adjustments. For !pcrel, the linked TB is compiled
+ * to know its full virtual address, so we can delay the
+ * update to pc to the unlinked path. A long chain of links
+ * can thus avoid many updates to the PC.
+ */
+ if (tb_cflags(ctx->base.tb) & CF_PCREL) {
+ gen_set_pc_imm(ctx, dest);
+ tcg_gen_goto_tb(n);
+ } else {
+ tcg_gen_goto_tb(n);
+ gen_set_pc_imm(ctx, dest);
+ }
tcg_gen_exit_tb(ctx->base.tb, n);
} else {
gen_set_pc_imm(ctx, dest);
@@ -543,6 +566,7 @@ static void gen_set_fpr_d(DisasContext *ctx, int reg_num, TCGv_i64 t)
static void gen_jal(DisasContext *ctx, int rd, target_ulong imm)
{
target_ulong next_pc;
+ TCGv succ_pc = dest_gpr(ctx, rd);
/* check misaligned: */
next_pc = ctx->base.pc_next + imm;
@@ -555,8 +579,10 @@ static void gen_jal(DisasContext *ctx, int rd, target_ulong imm)
}
}
- gen_set_gpri(ctx, rd, ctx->pc_succ_insn);
- gen_goto_tb(ctx, 0, ctx->base.pc_next + imm); /* must use this for safety */
+ gen_pc_plus_diff(succ_pc, ctx, ctx->pc_succ_insn);
+ gen_set_gpr(ctx, rd, succ_pc);
+
+ gen_goto_tb(ctx, 0, next_pc); /* must use this for safety */
ctx->base.is_jmp = DISAS_NORETURN;
}
@@ -1150,6 +1176,7 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
RISCVCPU *cpu = RISCV_CPU(cs);
uint32_t tb_flags = ctx->base.tb->flags;
+ ctx->pc_save = ctx->base.pc_first;
ctx->pc_succ_insn = ctx->base.pc_first;
ctx->mem_idx = FIELD_EX32(tb_flags, TB_FLAGS, MEM_IDX);
ctx->mstatus_fs = tb_flags & TB_FLAGS_MSTATUS_FS;
@@ -1195,8 +1222,13 @@ static void riscv_tr_tb_start(DisasContextBase *db, CPUState *cpu)
static void riscv_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
{
DisasContext *ctx = container_of(dcbase, DisasContext, base);
+ target_ulong pc_next = ctx->base.pc_next;
+
+ if (tb_cflags(dcbase->tb) & CF_PCREL) {
+ pc_next &= ~TARGET_PAGE_MASK;
+ }
- tcg_gen_insn_start(ctx->base.pc_next, 0);
+ tcg_gen_insn_start(pc_next, 0);
ctx->insn_start = tcg_last_op();
}
--
2.25.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v6 5/6] target/riscv: Enable PC-relative translation in system mode
2023-04-04 2:06 [PATCH v6 0/6] target/riscv: Fix pointer mask related support Weiwei Li
` (3 preceding siblings ...)
2023-04-04 2:06 ` [PATCH v6 4/6] target/riscv: Add support for PC-relative translation Weiwei Li
@ 2023-04-04 2:06 ` Weiwei Li
2023-04-04 2:06 ` [PATCH v6 6/6] target/riscv: Add pointer mask support for instruction fetch Weiwei Li
5 siblings, 0 replies; 26+ messages in thread
From: Weiwei Li @ 2023-04-04 2:06 UTC (permalink / raw)
To: qemu-riscv, qemu-devel
Cc: palmer, alistair.francis, bin.meng, dbarboza, zhiwei_liu,
wangjunqiang, lazyparser, Weiwei Li, Richard Henderson
Enable PC-relative translation in system mode by setting CF_PCREL
field of tcg_cflags in riscv_cpu_realize().
Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
target/riscv/cpu.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 646fa31a59..3b562d5d9f 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1193,6 +1193,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);
}
--
2.25.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v6 6/6] target/riscv: Add pointer mask support for instruction fetch
2023-04-04 2:06 [PATCH v6 0/6] target/riscv: Fix pointer mask related support Weiwei Li
` (4 preceding siblings ...)
2023-04-04 2:06 ` [PATCH v6 5/6] target/riscv: Enable PC-relative translation in system mode Weiwei Li
@ 2023-04-04 2:06 ` Weiwei Li
2023-04-04 2:52 ` LIU Zhiwei
5 siblings, 1 reply; 26+ messages in thread
From: Weiwei Li @ 2023-04-04 2:06 UTC (permalink / raw)
To: qemu-riscv, qemu-devel
Cc: palmer, alistair.francis, bin.meng, dbarboza, zhiwei_liu,
wangjunqiang, lazyparser, Weiwei Li, Richard Henderson
Transform the fetch address in cpu_get_tb_cpu_state() when pointer
mask for instruction is enabled.
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>
---
target/riscv/cpu.h | 1 +
target/riscv/cpu_helper.c | 20 +++++++++++++++++++-
target/riscv/csr.c | 2 --
3 files changed, 20 insertions(+), 3 deletions(-)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 638e47c75a..57bd9c3279 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -368,6 +368,7 @@ struct CPUArchState {
#endif
target_ulong cur_pmmask;
target_ulong cur_pmbase;
+ bool cur_pminsn;
/* Fields from here on are preserved across CPU reset. */
QEMUTimer *stimer; /* Internal timer for S-mode interrupt */
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index f88c503cf4..b683a770fe 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -40,6 +40,19 @@ int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
#endif
}
+static target_ulong adjust_pc_address(CPURISCVState *env, target_ulong pc)
+{
+ target_ulong adjust_pc = pc;
+
+ if (env->cur_pminsn) {
+ adjust_pc = (adjust_pc & ~env->cur_pmmask) | env->cur_pmbase;
+ } else if (env->xl == MXL_RV32) {
+ adjust_pc &= UINT32_MAX;
+ }
+
+ return adjust_pc;
+}
+
void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
target_ulong *cs_base, uint32_t *pflags)
{
@@ -48,7 +61,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
uint32_t flags = 0;
- *pc = env->xl == MXL_RV32 ? env->pc & UINT32_MAX : env->pc;
+ *pc = adjust_pc_address(env, env->pc);
*cs_base = 0;
if (cpu->cfg.ext_zve32f) {
@@ -124,6 +137,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
void riscv_cpu_update_mask(CPURISCVState *env)
{
target_ulong mask = -1, base = 0;
+ bool insn = false;
/*
* TODO: Current RVJ spec does not specify
* how the extension interacts with XLEN.
@@ -135,18 +149,21 @@ void riscv_cpu_update_mask(CPURISCVState *env)
if (env->mmte & M_PM_ENABLE) {
mask = env->mpmmask;
base = env->mpmbase;
+ insn = env->mmte & MMTE_M_PM_INSN;
}
break;
case PRV_S:
if (env->mmte & S_PM_ENABLE) {
mask = env->spmmask;
base = env->spmbase;
+ insn = env->mmte & MMTE_S_PM_INSN;
}
break;
case PRV_U:
if (env->mmte & U_PM_ENABLE) {
mask = env->upmmask;
base = env->upmbase;
+ insn = env->mmte & MMTE_U_PM_INSN;
}
break;
default:
@@ -161,6 +178,7 @@ void riscv_cpu_update_mask(CPURISCVState *env)
env->cur_pmmask = mask;
env->cur_pmbase = base;
}
+ env->cur_pminsn = insn;
}
#ifndef CONFIG_USER_ONLY
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 43b9ad4500..0902b64129 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -3518,8 +3518,6 @@ static RISCVException write_mmte(CPURISCVState *env, int csrno,
/* for machine mode pm.current is hardwired to 1 */
wpri_val |= MMTE_M_PM_CURRENT;
- /* hardwiring pm.instruction bit to 0, since it's not supported yet */
- wpri_val &= ~(MMTE_M_PM_INSN | MMTE_S_PM_INSN | MMTE_U_PM_INSN);
env->mmte = wpri_val | PM_EXT_DIRTY;
riscv_cpu_update_mask(env);
--
2.25.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [PATCH v6 6/6] target/riscv: Add pointer mask support for instruction fetch
2023-04-04 2:06 ` [PATCH v6 6/6] target/riscv: Add pointer mask support for instruction fetch Weiwei Li
@ 2023-04-04 2:52 ` LIU Zhiwei
0 siblings, 0 replies; 26+ messages in thread
From: LIU Zhiwei @ 2023-04-04 2:52 UTC (permalink / raw)
To: Weiwei Li, qemu-riscv, qemu-devel
Cc: palmer, alistair.francis, bin.meng, dbarboza, wangjunqiang,
lazyparser, Richard Henderson
On 2023/4/4 10:06, Weiwei Li wrote:
> Transform the fetch address in cpu_get_tb_cpu_state() when pointer
> mask for instruction is enabled.
>
> 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>
> ---
> target/riscv/cpu.h | 1 +
> target/riscv/cpu_helper.c | 20 +++++++++++++++++++-
> target/riscv/csr.c | 2 --
> 3 files changed, 20 insertions(+), 3 deletions(-)
>
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 638e47c75a..57bd9c3279 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -368,6 +368,7 @@ struct CPUArchState {
> #endif
> target_ulong cur_pmmask;
> target_ulong cur_pmbase;
> + bool cur_pminsn;
>
> /* Fields from here on are preserved across CPU reset. */
> QEMUTimer *stimer; /* Internal timer for S-mode interrupt */
> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> index f88c503cf4..b683a770fe 100644
> --- a/target/riscv/cpu_helper.c
> +++ b/target/riscv/cpu_helper.c
> @@ -40,6 +40,19 @@ int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
> #endif
> }
>
> +static target_ulong adjust_pc_address(CPURISCVState *env, target_ulong pc)
> +{
> + target_ulong adjust_pc = pc;
> +
> + if (env->cur_pminsn) {
> + adjust_pc = (adjust_pc & ~env->cur_pmmask) | env->cur_pmbase;
> + } else if (env->xl == MXL_RV32) {
> + adjust_pc &= UINT32_MAX;
> + }
> +
> + return adjust_pc;
> +}
> +
> void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
> target_ulong *cs_base, uint32_t *pflags)
> {
> @@ -48,7 +61,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
>
> uint32_t flags = 0;
>
> - *pc = env->xl == MXL_RV32 ? env->pc & UINT32_MAX : env->pc;
> + *pc = adjust_pc_address(env, env->pc);
> *cs_base = 0;
>
> if (cpu->cfg.ext_zve32f) {
> @@ -124,6 +137,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
> void riscv_cpu_update_mask(CPURISCVState *env)
> {
> target_ulong mask = -1, base = 0;
> + bool insn = false;
> /*
> * TODO: Current RVJ spec does not specify
> * how the extension interacts with XLEN.
> @@ -135,18 +149,21 @@ void riscv_cpu_update_mask(CPURISCVState *env)
> if (env->mmte & M_PM_ENABLE) {
> mask = env->mpmmask;
> base = env->mpmbase;
> + insn = env->mmte & MMTE_M_PM_INSN;
> }
> break;
> case PRV_S:
> if (env->mmte & S_PM_ENABLE) {
> mask = env->spmmask;
> base = env->spmbase;
> + insn = env->mmte & MMTE_S_PM_INSN;
> }
> break;
> case PRV_U:
> if (env->mmte & U_PM_ENABLE) {
> mask = env->upmmask;
> base = env->upmbase;
> + insn = env->mmte & MMTE_U_PM_INSN;
> }
> break;
> default:
> @@ -161,6 +178,7 @@ void riscv_cpu_update_mask(CPURISCVState *env)
> env->cur_pmmask = mask;
> env->cur_pmbase = base;
> }
> + env->cur_pminsn = insn;
> }
>
> #ifndef CONFIG_USER_ONLY
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 43b9ad4500..0902b64129 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -3518,8 +3518,6 @@ static RISCVException write_mmte(CPURISCVState *env, int csrno,
> /* for machine mode pm.current is hardwired to 1 */
> wpri_val |= MMTE_M_PM_CURRENT;
>
> - /* hardwiring pm.instruction bit to 0, since it's not supported yet */
> - wpri_val &= ~(MMTE_M_PM_INSN | MMTE_S_PM_INSN | MMTE_U_PM_INSN);
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Zhiwei
> env->mmte = wpri_val | PM_EXT_DIRTY;
> riscv_cpu_update_mask(env);
>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v6 3/6] target/riscv: Fix target address to update badaddr
2023-04-04 2:06 ` [PATCH v6 3/6] target/riscv: Fix target address to update badaddr Weiwei Li
@ 2023-04-04 3:06 ` LIU Zhiwei
2023-04-04 3:37 ` liweiwei
2023-04-05 4:41 ` Alistair Francis
1 sibling, 1 reply; 26+ messages in thread
From: LIU Zhiwei @ 2023-04-04 3:06 UTC (permalink / raw)
To: Weiwei Li, qemu-riscv, qemu-devel
Cc: palmer, alistair.francis, bin.meng, dbarboza, wangjunqiang,
lazyparser, Richard Henderson
On 2023/4/4 10:06, Weiwei Li wrote:
> Compute the target address before storing it into badaddr
> when mis-aligned exception is triggered.
> Use a target_pc temp to store the target address to avoid
> the confusing operation that udpate target address into
> cpu_pc before misalign check, then update it into badaddr
> and restore cpu_pc to current pc if exception is triggered.
>
> 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>
> ---
> target/riscv/insn_trans/trans_rvi.c.inc | 23 ++++++++++++++++-------
> target/riscv/translate.c | 21 ++++++++++-----------
> 2 files changed, 26 insertions(+), 18 deletions(-)
>
> diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
> index 4ad54e8a49..cc72864d32 100644
> --- a/target/riscv/insn_trans/trans_rvi.c.inc
> +++ b/target/riscv/insn_trans/trans_rvi.c.inc
> @@ -51,25 +51,30 @@ static bool trans_jal(DisasContext *ctx, arg_jal *a)
> static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
> {
> TCGLabel *misaligned = NULL;
> + TCGv target_pc = tcg_temp_new();
>
> - 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);
> + tcg_gen_addi_tl(target_pc, get_gpr(ctx, a->rs1, EXT_NONE), a->imm);
> + tcg_gen_andi_tl(target_pc, target_pc, (target_ulong)-2);
> +
> + if (get_xl(ctx) == MXL_RV32) {
> + tcg_gen_ext32s_tl(target_pc, target_pc);
> + }
>
Delete this.
> - gen_set_pc(ctx, cpu_pc);
> if (!has_ext(ctx, RVC)) {
> TCGv t0 = tcg_temp_new();
>
> misaligned = gen_new_label();
> - tcg_gen_andi_tl(t0, cpu_pc, 0x2);
> + tcg_gen_andi_tl(t0, target_pc, 0x2);
> tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0x0, misaligned);
> }
>
> gen_set_gpri(ctx, a->rd, ctx->pc_succ_insn);
> + tcg_gen_mov_tl(cpu_pc, target_pc);
And we can use the gen_set_pc instead.
I think the reason you want to delete gen_set_pc is to make the
gen_set_pc_imm the only API to change the cpu_pc.
This implicitly enhance the correctness, which may constrain the scalable.
Zhiwei
> lookup_and_goto_ptr(ctx);
>
> if (misaligned) {
> gen_set_label(misaligned);
> - gen_exception_inst_addr_mis(ctx);
> + gen_exception_inst_addr_mis(ctx, target_pc);
> }
> ctx->base.is_jmp = DISAS_NORETURN;
>
> @@ -153,6 +158,7 @@ static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond)
> TCGLabel *l = gen_new_label();
> TCGv src1 = get_gpr(ctx, a->rs1, EXT_SIGN);
> TCGv src2 = get_gpr(ctx, a->rs2, EXT_SIGN);
> + target_ulong next_pc;
>
> if (get_xl(ctx) == MXL_RV128) {
> TCGv src1h = get_gprh(ctx, a->rs1);
> @@ -169,9 +175,12 @@ static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond)
>
> gen_set_label(l); /* branch taken */
>
> - if (!has_ext(ctx, RVC) && ((ctx->base.pc_next + a->imm) & 0x3)) {
> + next_pc = ctx->base.pc_next + a->imm;
> + if (!has_ext(ctx, RVC) && (next_pc & 0x3)) {
> /* misaligned */
> - gen_exception_inst_addr_mis(ctx);
> + TCGv target_pc = tcg_temp_new();
> + gen_pc_plus_diff(target_pc, ctx, next_pc);
> + gen_exception_inst_addr_mis(ctx, target_pc);
> } else {
> gen_goto_tb(ctx, 0, ctx->base.pc_next + a->imm);
> }
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index 0ee8ee147d..d434fedb37 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -222,21 +222,18 @@ static void decode_save_opc(DisasContext *ctx)
> ctx->insn_start = NULL;
> }
>
> -static void gen_set_pc_imm(DisasContext *ctx, target_ulong dest)
> +static void gen_pc_plus_diff(TCGv target, DisasContext *ctx,
> + target_ulong dest)
> {
> if (get_xl(ctx) == MXL_RV32) {
> dest = (int32_t)dest;
> }
> - tcg_gen_movi_tl(cpu_pc, dest);
> + tcg_gen_movi_tl(target, dest);
> }
>
> -static void gen_set_pc(DisasContext *ctx, TCGv dest)
> +static void gen_set_pc_imm(DisasContext *ctx, target_ulong dest)
> {
> - if (get_xl(ctx) == MXL_RV32) {
> - tcg_gen_ext32s_tl(cpu_pc, dest);
> - } else {
> - tcg_gen_mov_tl(cpu_pc, dest);
> - }
> + gen_pc_plus_diff(cpu_pc, ctx, dest);
> }
>
> static void generate_exception(DisasContext *ctx, int excp)
> @@ -257,9 +254,9 @@ static void gen_exception_illegal(DisasContext *ctx)
> }
> }
>
> -static void gen_exception_inst_addr_mis(DisasContext *ctx)
> +static void gen_exception_inst_addr_mis(DisasContext *ctx, TCGv target)
> {
> - tcg_gen_st_tl(cpu_pc, cpu_env, offsetof(CPURISCVState, badaddr));
> + tcg_gen_st_tl(target, cpu_env, offsetof(CPURISCVState, badaddr));
> generate_exception(ctx, RISCV_EXCP_INST_ADDR_MIS);
> }
>
> @@ -551,7 +548,9 @@ static void gen_jal(DisasContext *ctx, int rd, target_ulong imm)
> next_pc = ctx->base.pc_next + imm;
> if (!has_ext(ctx, RVC)) {
> if ((next_pc & 0x3) != 0) {
> - gen_exception_inst_addr_mis(ctx);
> + TCGv target_pc = tcg_temp_new();
> + gen_pc_plus_diff(target_pc, ctx, next_pc);
> + gen_exception_inst_addr_mis(ctx, target_pc);
> return;
> }
> }
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v6 4/6] target/riscv: Add support for PC-relative translation
2023-04-04 2:06 ` [PATCH v6 4/6] target/riscv: Add support for PC-relative translation Weiwei Li
@ 2023-04-04 3:12 ` LIU Zhiwei
2023-04-04 3:25 ` LIU Zhiwei
2023-04-04 3:46 ` liweiwei
2023-04-04 13:56 ` Richard Henderson
1 sibling, 2 replies; 26+ messages in thread
From: LIU Zhiwei @ 2023-04-04 3:12 UTC (permalink / raw)
To: Weiwei Li, qemu-riscv, qemu-devel
Cc: palmer, alistair.francis, bin.meng, dbarboza, wangjunqiang,
lazyparser, Richard Henderson
On 2023/4/4 10:06, Weiwei Li wrote:
> Add a base pc_save for PC-relative translation(CF_PCREL).
> Diable the directly sync pc from tb by riscv_cpu_synchronize_from_tb.
> We can get pc-relative address from following formula:
> real_pc = (old)env->pc + diff, where diff = target_pc - ctx->pc_save.
> Use gen_get_target_pc to compute target address of auipc and successor
> address of jalr and jal.
>
> The existence of CF_PCREL can improve performance with the guest
> kernel's address space randomization. Each guest process maps libc.so
> (et al) at a different virtual address, and this allows those
> translations to be shared.
>
> 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>
> ---
> target/riscv/cpu.c | 29 +++++++++------
> target/riscv/insn_trans/trans_rvi.c.inc | 14 ++++++--
Miss the process for trans_ebreak.
I want to construct the PCREL feature on the processing of ctx pc
related fields, which is the reason why we need do specially process.
For example,
static bool trans_auipc(DisasContext *ctx, arg_auipc *a)
{
- gen_set_gpri(ctx, a->rd, a->imm + ctx->base.pc_next);
+ if (tb_cflags(ctx->cflags) & CF_PCREL) {
+ target_ulong pc_rel = ctx->base.pc_next - ctx->base.pc_first +
a->imm;
+ gen_set_gpr_pcrel(ctx, a->rd, cpu_pc, pc_rel);
+ } else {
+ gen_set_gpri(ctx, a->rd, a->imm + ctx->base.pc_next);
+ }
return true;
}
+static void gen_set_gpr_pcrel(DisasContext *ctx, int reg_num, TCGv t,
target_ulong rel)
+{
+ TCGv dest = dest_gpr(ctx, reg_num);
+ tcg_gen_addi_tl(dest, t, rel);
+ gen_set_gpr(ctx, reg_num, dest);
+}
+
But if it is too difficult to reuse the current implementation, your
implementation is also acceptable to me.
Zhiwei
> target/riscv/translate.c | 48 ++++++++++++++++++++-----
> 3 files changed, 70 insertions(+), 21 deletions(-)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 1e97473af2..646fa31a59 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -658,16 +658,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;
> + }
> }
> }
>
> @@ -693,11 +695,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];
> }
> diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
> index cc72864d32..7cbbdac5aa 100644
> --- a/target/riscv/insn_trans/trans_rvi.c.inc
> +++ b/target/riscv/insn_trans/trans_rvi.c.inc
> @@ -38,7 +38,9 @@ static bool trans_lui(DisasContext *ctx, arg_lui *a)
>
> static bool trans_auipc(DisasContext *ctx, arg_auipc *a)
> {
> - gen_set_gpri(ctx, a->rd, a->imm + ctx->base.pc_next);
> + TCGv target_pc = dest_gpr(ctx, a->rd);
> + gen_pc_plus_diff(target_pc, ctx, a->imm + ctx->base.pc_next);
> + gen_set_gpr(ctx, a->rd, target_pc);
> return true;
> }
>
> @@ -52,6 +54,7 @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
> {
> TCGLabel *misaligned = NULL;
> TCGv target_pc = tcg_temp_new();
> + TCGv succ_pc = dest_gpr(ctx, a->rd);
>
> tcg_gen_addi_tl(target_pc, get_gpr(ctx, a->rs1, EXT_NONE), a->imm);
> tcg_gen_andi_tl(target_pc, target_pc, (target_ulong)-2);
> @@ -68,7 +71,9 @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
> tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0x0, misaligned);
> }
>
> - gen_set_gpri(ctx, a->rd, ctx->pc_succ_insn);
> + gen_pc_plus_diff(succ_pc, ctx, ctx->pc_succ_insn);
> + gen_set_gpr(ctx, a->rd, succ_pc);
> +
> tcg_gen_mov_tl(cpu_pc, target_pc);
> lookup_and_goto_ptr(ctx);
>
> @@ -159,6 +164,7 @@ static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond)
> TCGv src1 = get_gpr(ctx, a->rs1, EXT_SIGN);
> TCGv src2 = get_gpr(ctx, a->rs2, EXT_SIGN);
> target_ulong next_pc;
> + target_ulong orig_pc_save = ctx->pc_save;
>
> if (get_xl(ctx) == MXL_RV128) {
> TCGv src1h = get_gprh(ctx, a->rs1);
> @@ -175,6 +181,7 @@ static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond)
>
> gen_set_label(l); /* branch taken */
>
> + ctx->pc_save = orig_pc_save;
> next_pc = ctx->base.pc_next + a->imm;
> if (!has_ext(ctx, RVC) && (next_pc & 0x3)) {
> /* misaligned */
> @@ -182,8 +189,9 @@ static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond)
> gen_pc_plus_diff(target_pc, ctx, next_pc);
> gen_exception_inst_addr_mis(ctx, target_pc);
> } else {
> - gen_goto_tb(ctx, 0, ctx->base.pc_next + a->imm);
> + gen_goto_tb(ctx, 0, next_pc);
> }
> + ctx->pc_save = -1;
> ctx->base.is_jmp = DISAS_NORETURN;
>
> return true;
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index d434fedb37..4623749602 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -59,6 +59,7 @@ typedef struct DisasContext {
> DisasContextBase base;
> /* pc_succ_insn points to the instruction following base.pc_next */
> target_ulong pc_succ_insn;
> + target_ulong pc_save;
> target_ulong priv_ver;
> RISCVMXL misa_mxl_max;
> RISCVMXL xl;
> @@ -225,15 +226,24 @@ static void decode_save_opc(DisasContext *ctx)
> static void gen_pc_plus_diff(TCGv target, DisasContext *ctx,
> target_ulong dest)
> {
> - if (get_xl(ctx) == MXL_RV32) {
> - dest = (int32_t)dest;
> + assert(ctx->pc_save != -1);
> + if (tb_cflags(ctx->base.tb) & CF_PCREL) {
> + tcg_gen_addi_tl(target, cpu_pc, dest - ctx->pc_save);
> + if (get_xl(ctx) == MXL_RV32) {
> + tcg_gen_ext32s_tl(target, target);
> + }
> + } else {
> + if (get_xl(ctx) == MXL_RV32) {
> + dest = (int32_t)dest;
> + }
> + tcg_gen_movi_tl(target, dest);
> }
> - tcg_gen_movi_tl(target, dest);
> }
>
> static void gen_set_pc_imm(DisasContext *ctx, target_ulong dest)
> {
> gen_pc_plus_diff(cpu_pc, ctx, dest);
> + ctx->pc_save = dest;
> }
>
> static void generate_exception(DisasContext *ctx, int excp)
> @@ -287,8 +297,21 @@ static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
> * direct block chain benefits will be small.
> */
> if (translator_use_goto_tb(&ctx->base, dest) && !ctx->itrigger) {
> - tcg_gen_goto_tb(n);
> - gen_set_pc_imm(ctx, dest);
> + /*
> + * For pcrel, the pc must always be up-to-date on entry to
> + * the linked TB, so that it can use simple additions for all
> + * further adjustments. For !pcrel, the linked TB is compiled
> + * to know its full virtual address, so we can delay the
> + * update to pc to the unlinked path. A long chain of links
> + * can thus avoid many updates to the PC.
> + */
> + if (tb_cflags(ctx->base.tb) & CF_PCREL) {
> + gen_set_pc_imm(ctx, dest);
> + tcg_gen_goto_tb(n);
> + } else {
> + tcg_gen_goto_tb(n);
> + gen_set_pc_imm(ctx, dest);
> + }
> tcg_gen_exit_tb(ctx->base.tb, n);
> } else {
> gen_set_pc_imm(ctx, dest);
> @@ -543,6 +566,7 @@ static void gen_set_fpr_d(DisasContext *ctx, int reg_num, TCGv_i64 t)
> static void gen_jal(DisasContext *ctx, int rd, target_ulong imm)
> {
> target_ulong next_pc;
> + TCGv succ_pc = dest_gpr(ctx, rd);
>
> /* check misaligned: */
> next_pc = ctx->base.pc_next + imm;
> @@ -555,8 +579,10 @@ static void gen_jal(DisasContext *ctx, int rd, target_ulong imm)
> }
> }
>
> - gen_set_gpri(ctx, rd, ctx->pc_succ_insn);
> - gen_goto_tb(ctx, 0, ctx->base.pc_next + imm); /* must use this for safety */
> + gen_pc_plus_diff(succ_pc, ctx, ctx->pc_succ_insn);
> + gen_set_gpr(ctx, rd, succ_pc);
> +
> + gen_goto_tb(ctx, 0, next_pc); /* must use this for safety */
> ctx->base.is_jmp = DISAS_NORETURN;
> }
>
> @@ -1150,6 +1176,7 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
> RISCVCPU *cpu = RISCV_CPU(cs);
> uint32_t tb_flags = ctx->base.tb->flags;
>
> + ctx->pc_save = ctx->base.pc_first;
> ctx->pc_succ_insn = ctx->base.pc_first;
> ctx->mem_idx = FIELD_EX32(tb_flags, TB_FLAGS, MEM_IDX);
> ctx->mstatus_fs = tb_flags & TB_FLAGS_MSTATUS_FS;
> @@ -1195,8 +1222,13 @@ static void riscv_tr_tb_start(DisasContextBase *db, CPUState *cpu)
> static void riscv_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
> {
> DisasContext *ctx = container_of(dcbase, DisasContext, base);
> + target_ulong pc_next = ctx->base.pc_next;
> +
> + if (tb_cflags(dcbase->tb) & CF_PCREL) {
> + pc_next &= ~TARGET_PAGE_MASK;
> + }
>
> - tcg_gen_insn_start(ctx->base.pc_next, 0);
> + tcg_gen_insn_start(pc_next, 0);
> ctx->insn_start = tcg_last_op();
> }
>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v6 4/6] target/riscv: Add support for PC-relative translation
2023-04-04 3:12 ` LIU Zhiwei
@ 2023-04-04 3:25 ` LIU Zhiwei
2023-04-04 3:46 ` liweiwei
1 sibling, 0 replies; 26+ messages in thread
From: LIU Zhiwei @ 2023-04-04 3:25 UTC (permalink / raw)
To: Weiwei Li, qemu-riscv, qemu-devel
Cc: palmer, alistair.francis, bin.meng, dbarboza, wangjunqiang,
lazyparser, Richard Henderson
On 2023/4/4 11:12, LIU Zhiwei wrote:
>
> On 2023/4/4 10:06, Weiwei Li wrote:
>> Add a base pc_save for PC-relative translation(CF_PCREL).
>> Diable the directly sync pc from tb by riscv_cpu_synchronize_from_tb.
>> We can get pc-relative address from following formula:
>> real_pc = (old)env->pc + diff, where diff = target_pc - ctx->pc_save.
>> Use gen_get_target_pc to compute target address of auipc and successor
>> address of jalr and jal.
>>
>> The existence of CF_PCREL can improve performance with the guest
>> kernel's address space randomization. Each guest process maps libc.so
>> (et al) at a different virtual address, and this allows those
>> translations to be shared.
>>
>> 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>
>> ---
>> target/riscv/cpu.c | 29 +++++++++------
>> target/riscv/insn_trans/trans_rvi.c.inc | 14 ++++++--
>
> Miss the process for trans_ebreak.
Please ignore this sentence comment. It will not influence the codegen.
Zhiwei
>
> I want to construct the PCREL feature on the processing of ctx pc
> related fields, which is the reason why we need do specially process.
> For example,
>
> static bool trans_auipc(DisasContext *ctx, arg_auipc *a)
> {
> - gen_set_gpri(ctx, a->rd, a->imm + ctx->base.pc_next);
> + if (tb_cflags(ctx->cflags) & CF_PCREL) {
> + target_ulong pc_rel = ctx->base.pc_next - ctx->base.pc_first
> + a->imm;
> + gen_set_gpr_pcrel(ctx, a->rd, cpu_pc, pc_rel);
> + } else {
> + gen_set_gpri(ctx, a->rd, a->imm + ctx->base.pc_next);
> + }
> return true;
> }
>
> +static void gen_set_gpr_pcrel(DisasContext *ctx, int reg_num, TCGv t,
> target_ulong rel)
> +{
> + TCGv dest = dest_gpr(ctx, reg_num);
> + tcg_gen_addi_tl(dest, t, rel);
> + gen_set_gpr(ctx, reg_num, dest);
> +}
> +
>
> But if it is too difficult to reuse the current implementation, your
> implementation is also acceptable to me.
>
> Zhiwei
>
>> target/riscv/translate.c | 48 ++++++++++++++++++++-----
>> 3 files changed, 70 insertions(+), 21 deletions(-)
>>
>> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
>> index 1e97473af2..646fa31a59 100644
>> --- a/target/riscv/cpu.c
>> +++ b/target/riscv/cpu.c
>> @@ -658,16 +658,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;
>> + }
>> }
>> }
>> @@ -693,11 +695,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];
>> }
>> diff --git a/target/riscv/insn_trans/trans_rvi.c.inc
>> b/target/riscv/insn_trans/trans_rvi.c.inc
>> index cc72864d32..7cbbdac5aa 100644
>> --- a/target/riscv/insn_trans/trans_rvi.c.inc
>> +++ b/target/riscv/insn_trans/trans_rvi.c.inc
>> @@ -38,7 +38,9 @@ static bool trans_lui(DisasContext *ctx, arg_lui *a)
>> static bool trans_auipc(DisasContext *ctx, arg_auipc *a)
>> {
>> - gen_set_gpri(ctx, a->rd, a->imm + ctx->base.pc_next);
>> + TCGv target_pc = dest_gpr(ctx, a->rd);
>> + gen_pc_plus_diff(target_pc, ctx, a->imm + ctx->base.pc_next);
>> + gen_set_gpr(ctx, a->rd, target_pc);
>> return true;
>> }
>> @@ -52,6 +54,7 @@ static bool trans_jalr(DisasContext *ctx,
>> arg_jalr *a)
>> {
>> TCGLabel *misaligned = NULL;
>> TCGv target_pc = tcg_temp_new();
>> + TCGv succ_pc = dest_gpr(ctx, a->rd);
>> tcg_gen_addi_tl(target_pc, get_gpr(ctx, a->rs1, EXT_NONE),
>> a->imm);
>> tcg_gen_andi_tl(target_pc, target_pc, (target_ulong)-2);
>> @@ -68,7 +71,9 @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
>> tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0x0, misaligned);
>> }
>> - gen_set_gpri(ctx, a->rd, ctx->pc_succ_insn);
>> + gen_pc_plus_diff(succ_pc, ctx, ctx->pc_succ_insn);
>> + gen_set_gpr(ctx, a->rd, succ_pc);
>> +
>> tcg_gen_mov_tl(cpu_pc, target_pc);
>> lookup_and_goto_ptr(ctx);
>> @@ -159,6 +164,7 @@ static bool gen_branch(DisasContext *ctx, arg_b
>> *a, TCGCond cond)
>> TCGv src1 = get_gpr(ctx, a->rs1, EXT_SIGN);
>> TCGv src2 = get_gpr(ctx, a->rs2, EXT_SIGN);
>> target_ulong next_pc;
>> + target_ulong orig_pc_save = ctx->pc_save;
>> if (get_xl(ctx) == MXL_RV128) {
>> TCGv src1h = get_gprh(ctx, a->rs1);
>> @@ -175,6 +181,7 @@ static bool gen_branch(DisasContext *ctx, arg_b
>> *a, TCGCond cond)
>> gen_set_label(l); /* branch taken */
>> + ctx->pc_save = orig_pc_save;
>> next_pc = ctx->base.pc_next + a->imm;
>> if (!has_ext(ctx, RVC) && (next_pc & 0x3)) {
>> /* misaligned */
>> @@ -182,8 +189,9 @@ static bool gen_branch(DisasContext *ctx, arg_b
>> *a, TCGCond cond)
>> gen_pc_plus_diff(target_pc, ctx, next_pc);
>> gen_exception_inst_addr_mis(ctx, target_pc);
>> } else {
>> - gen_goto_tb(ctx, 0, ctx->base.pc_next + a->imm);
>> + gen_goto_tb(ctx, 0, next_pc);
>> }
>> + ctx->pc_save = -1;
>> ctx->base.is_jmp = DISAS_NORETURN;
>> return true;
>> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
>> index d434fedb37..4623749602 100644
>> --- a/target/riscv/translate.c
>> +++ b/target/riscv/translate.c
>> @@ -59,6 +59,7 @@ typedef struct DisasContext {
>> DisasContextBase base;
>> /* pc_succ_insn points to the instruction following
>> base.pc_next */
>> target_ulong pc_succ_insn;
>> + target_ulong pc_save;
>> target_ulong priv_ver;
>> RISCVMXL misa_mxl_max;
>> RISCVMXL xl;
>> @@ -225,15 +226,24 @@ static void decode_save_opc(DisasContext *ctx)
>> static void gen_pc_plus_diff(TCGv target, DisasContext *ctx,
>> target_ulong dest)
>> {
>> - if (get_xl(ctx) == MXL_RV32) {
>> - dest = (int32_t)dest;
>> + assert(ctx->pc_save != -1);
>> + if (tb_cflags(ctx->base.tb) & CF_PCREL) {
>> + tcg_gen_addi_tl(target, cpu_pc, dest - ctx->pc_save);
>> + if (get_xl(ctx) == MXL_RV32) {
>> + tcg_gen_ext32s_tl(target, target);
>> + }
>> + } else {
>> + if (get_xl(ctx) == MXL_RV32) {
>> + dest = (int32_t)dest;
>> + }
>> + tcg_gen_movi_tl(target, dest);
>> }
>> - tcg_gen_movi_tl(target, dest);
>> }
>> static void gen_set_pc_imm(DisasContext *ctx, target_ulong dest)
>> {
>> gen_pc_plus_diff(cpu_pc, ctx, dest);
>> + ctx->pc_save = dest;
>> }
>> static void generate_exception(DisasContext *ctx, int excp)
>> @@ -287,8 +297,21 @@ static void gen_goto_tb(DisasContext *ctx, int
>> n, target_ulong dest)
>> * direct block chain benefits will be small.
>> */
>> if (translator_use_goto_tb(&ctx->base, dest) && !ctx->itrigger) {
>> - tcg_gen_goto_tb(n);
>> - gen_set_pc_imm(ctx, dest);
>> + /*
>> + * For pcrel, the pc must always be up-to-date on entry to
>> + * the linked TB, so that it can use simple additions for all
>> + * further adjustments. For !pcrel, the linked TB is compiled
>> + * to know its full virtual address, so we can delay the
>> + * update to pc to the unlinked path. A long chain of links
>> + * can thus avoid many updates to the PC.
>> + */
>> + if (tb_cflags(ctx->base.tb) & CF_PCREL) {
>> + gen_set_pc_imm(ctx, dest);
>> + tcg_gen_goto_tb(n);
>> + } else {
>> + tcg_gen_goto_tb(n);
>> + gen_set_pc_imm(ctx, dest);
>> + }
>> tcg_gen_exit_tb(ctx->base.tb, n);
>> } else {
>> gen_set_pc_imm(ctx, dest);
>> @@ -543,6 +566,7 @@ static void gen_set_fpr_d(DisasContext *ctx, int
>> reg_num, TCGv_i64 t)
>> static void gen_jal(DisasContext *ctx, int rd, target_ulong imm)
>> {
>> target_ulong next_pc;
>> + TCGv succ_pc = dest_gpr(ctx, rd);
>> /* check misaligned: */
>> next_pc = ctx->base.pc_next + imm;
>> @@ -555,8 +579,10 @@ static void gen_jal(DisasContext *ctx, int rd,
>> target_ulong imm)
>> }
>> }
>> - gen_set_gpri(ctx, rd, ctx->pc_succ_insn);
>> - gen_goto_tb(ctx, 0, ctx->base.pc_next + imm); /* must use this
>> for safety */
>> + gen_pc_plus_diff(succ_pc, ctx, ctx->pc_succ_insn);
>> + gen_set_gpr(ctx, rd, succ_pc);
>> +
>> + gen_goto_tb(ctx, 0, next_pc); /* must use this for safety */
>> ctx->base.is_jmp = DISAS_NORETURN;
>> }
>> @@ -1150,6 +1176,7 @@ static void
>> riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
>> RISCVCPU *cpu = RISCV_CPU(cs);
>> uint32_t tb_flags = ctx->base.tb->flags;
>> + ctx->pc_save = ctx->base.pc_first;
>> ctx->pc_succ_insn = ctx->base.pc_first;
>> ctx->mem_idx = FIELD_EX32(tb_flags, TB_FLAGS, MEM_IDX);
>> ctx->mstatus_fs = tb_flags & TB_FLAGS_MSTATUS_FS;
>> @@ -1195,8 +1222,13 @@ static void riscv_tr_tb_start(DisasContextBase
>> *db, CPUState *cpu)
>> static void riscv_tr_insn_start(DisasContextBase *dcbase, CPUState
>> *cpu)
>> {
>> DisasContext *ctx = container_of(dcbase, DisasContext, base);
>> + target_ulong pc_next = ctx->base.pc_next;
>> +
>> + if (tb_cflags(dcbase->tb) & CF_PCREL) {
>> + pc_next &= ~TARGET_PAGE_MASK;
>> + }
>> - tcg_gen_insn_start(ctx->base.pc_next, 0);
>> + tcg_gen_insn_start(pc_next, 0);
>> ctx->insn_start = tcg_last_op();
>> }
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v6 3/6] target/riscv: Fix target address to update badaddr
2023-04-04 3:06 ` LIU Zhiwei
@ 2023-04-04 3:37 ` liweiwei
0 siblings, 0 replies; 26+ messages in thread
From: liweiwei @ 2023-04-04 3:37 UTC (permalink / raw)
To: LIU Zhiwei, qemu-riscv, qemu-devel
Cc: liweiwei, palmer, alistair.francis, bin.meng, dbarboza,
wangjunqiang, lazyparser, Richard Henderson
On 2023/4/4 11:06, LIU Zhiwei wrote:
>
> On 2023/4/4 10:06, Weiwei Li wrote:
>> Compute the target address before storing it into badaddr
>> when mis-aligned exception is triggered.
>> Use a target_pc temp to store the target address to avoid
>> the confusing operation that udpate target address into
>> cpu_pc before misalign check, then update it into badaddr
>> and restore cpu_pc to current pc if exception is triggered.
>>
>> 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>
>> ---
>> target/riscv/insn_trans/trans_rvi.c.inc | 23 ++++++++++++++++-------
>> target/riscv/translate.c | 21 ++++++++++-----------
>> 2 files changed, 26 insertions(+), 18 deletions(-)
>>
>> diff --git a/target/riscv/insn_trans/trans_rvi.c.inc
>> b/target/riscv/insn_trans/trans_rvi.c.inc
>> index 4ad54e8a49..cc72864d32 100644
>> --- a/target/riscv/insn_trans/trans_rvi.c.inc
>> +++ b/target/riscv/insn_trans/trans_rvi.c.inc
>> @@ -51,25 +51,30 @@ static bool trans_jal(DisasContext *ctx, arg_jal *a)
>> static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
>> {
>> TCGLabel *misaligned = NULL;
>> + TCGv target_pc = tcg_temp_new();
>> - 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);
>> + tcg_gen_addi_tl(target_pc, get_gpr(ctx, a->rs1, EXT_NONE), a->imm);
>> + tcg_gen_andi_tl(target_pc, target_pc, (target_ulong)-2);
>> +
>> + if (get_xl(ctx) == MXL_RV32) {
>> + tcg_gen_ext32s_tl(target_pc, target_pc);
>> + }
> Delete this.
The (signed-extended)target_pc should be used in both updating cpu_pc
and following gen_exception_inst_addr_mis().
So we cannot delete it and just resue the logic in gen_set_pc().
This is also why I use tcg_gen_mov_tl(cpu_pc, target_pc) directly in
following code.
Regards,
Weiwei Li
>> - gen_set_pc(ctx, cpu_pc);
>> if (!has_ext(ctx, RVC)) {
>> TCGv t0 = tcg_temp_new();
>> misaligned = gen_new_label();
>> - tcg_gen_andi_tl(t0, cpu_pc, 0x2);
>> + tcg_gen_andi_tl(t0, target_pc, 0x2);
>> tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0x0, misaligned);
>> }
>> gen_set_gpri(ctx, a->rd, ctx->pc_succ_insn);
>> + tcg_gen_mov_tl(cpu_pc, target_pc);
>
> And we can use the gen_set_pc instead.
>
> I think the reason you want to delete gen_set_pc is to make the
> gen_set_pc_imm the only API to change the cpu_pc.
>
> This implicitly enhance the correctness, which may constrain the
> scalable.
>
> Zhiwei
>
>> lookup_and_goto_ptr(ctx);
>> if (misaligned) {
>> gen_set_label(misaligned);
>> - gen_exception_inst_addr_mis(ctx);
>> + gen_exception_inst_addr_mis(ctx, target_pc);
>> }
>> ctx->base.is_jmp = DISAS_NORETURN;
>> @@ -153,6 +158,7 @@ static bool gen_branch(DisasContext *ctx, arg_b
>> *a, TCGCond cond)
>> TCGLabel *l = gen_new_label();
>> TCGv src1 = get_gpr(ctx, a->rs1, EXT_SIGN);
>> TCGv src2 = get_gpr(ctx, a->rs2, EXT_SIGN);
>> + target_ulong next_pc;
>> if (get_xl(ctx) == MXL_RV128) {
>> TCGv src1h = get_gprh(ctx, a->rs1);
>> @@ -169,9 +175,12 @@ static bool gen_branch(DisasContext *ctx, arg_b
>> *a, TCGCond cond)
>> gen_set_label(l); /* branch taken */
>> - if (!has_ext(ctx, RVC) && ((ctx->base.pc_next + a->imm) & 0x3)) {
>> + next_pc = ctx->base.pc_next + a->imm;
>> + if (!has_ext(ctx, RVC) && (next_pc & 0x3)) {
>> /* misaligned */
>> - gen_exception_inst_addr_mis(ctx);
>> + TCGv target_pc = tcg_temp_new();
>> + gen_pc_plus_diff(target_pc, ctx, next_pc);
>> + gen_exception_inst_addr_mis(ctx, target_pc);
>> } else {
>> gen_goto_tb(ctx, 0, ctx->base.pc_next + a->imm);
>> }
>> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
>> index 0ee8ee147d..d434fedb37 100644
>> --- a/target/riscv/translate.c
>> +++ b/target/riscv/translate.c
>> @@ -222,21 +222,18 @@ static void decode_save_opc(DisasContext *ctx)
>> ctx->insn_start = NULL;
>> }
>> -static void gen_set_pc_imm(DisasContext *ctx, target_ulong dest)
>> +static void gen_pc_plus_diff(TCGv target, DisasContext *ctx,
>> + target_ulong dest)
>> {
>> if (get_xl(ctx) == MXL_RV32) {
>> dest = (int32_t)dest;
>> }
>> - tcg_gen_movi_tl(cpu_pc, dest);
>> + tcg_gen_movi_tl(target, dest);
>> }
>> -static void gen_set_pc(DisasContext *ctx, TCGv dest)
>> +static void gen_set_pc_imm(DisasContext *ctx, target_ulong dest)
>> {
>> - if (get_xl(ctx) == MXL_RV32) {
>> - tcg_gen_ext32s_tl(cpu_pc, dest);
>> - } else {
>> - tcg_gen_mov_tl(cpu_pc, dest);
>> - }
>> + gen_pc_plus_diff(cpu_pc, ctx, dest);
>> }
>> static void generate_exception(DisasContext *ctx, int excp)
>> @@ -257,9 +254,9 @@ static void gen_exception_illegal(DisasContext *ctx)
>> }
>> }
>> -static void gen_exception_inst_addr_mis(DisasContext *ctx)
>> +static void gen_exception_inst_addr_mis(DisasContext *ctx, TCGv target)
>> {
>> - tcg_gen_st_tl(cpu_pc, cpu_env, offsetof(CPURISCVState, badaddr));
>> + tcg_gen_st_tl(target, cpu_env, offsetof(CPURISCVState, badaddr));
>> generate_exception(ctx, RISCV_EXCP_INST_ADDR_MIS);
>> }
>> @@ -551,7 +548,9 @@ static void gen_jal(DisasContext *ctx, int rd,
>> target_ulong imm)
>> next_pc = ctx->base.pc_next + imm;
>> if (!has_ext(ctx, RVC)) {
>> if ((next_pc & 0x3) != 0) {
>> - gen_exception_inst_addr_mis(ctx);
>> + TCGv target_pc = tcg_temp_new();
>> + gen_pc_plus_diff(target_pc, ctx, next_pc);
>> + gen_exception_inst_addr_mis(ctx, target_pc);
>> return;
>> }
>> }
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v6 4/6] target/riscv: Add support for PC-relative translation
2023-04-04 3:12 ` LIU Zhiwei
2023-04-04 3:25 ` LIU Zhiwei
@ 2023-04-04 3:46 ` liweiwei
2023-04-04 7:07 ` LIU Zhiwei
1 sibling, 1 reply; 26+ messages in thread
From: liweiwei @ 2023-04-04 3:46 UTC (permalink / raw)
To: LIU Zhiwei, qemu-riscv, qemu-devel
Cc: liweiwei, palmer, alistair.francis, bin.meng, dbarboza,
wangjunqiang, lazyparser, Richard Henderson
On 2023/4/4 11:12, LIU Zhiwei wrote:
>
> On 2023/4/4 10:06, Weiwei Li wrote:
>> Add a base pc_save for PC-relative translation(CF_PCREL).
>> Diable the directly sync pc from tb by riscv_cpu_synchronize_from_tb.
>> We can get pc-relative address from following formula:
>> real_pc = (old)env->pc + diff, where diff = target_pc - ctx->pc_save.
>> Use gen_get_target_pc to compute target address of auipc and successor
>> address of jalr and jal.
>>
>> The existence of CF_PCREL can improve performance with the guest
>> kernel's address space randomization. Each guest process maps libc.so
>> (et al) at a different virtual address, and this allows those
>> translations to be shared.
>>
>> 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>
>> ---
>> target/riscv/cpu.c | 29 +++++++++------
>> target/riscv/insn_trans/trans_rvi.c.inc | 14 ++++++--
>
> Miss the process for trans_ebreak.
>
> I want to construct the PCREL feature on the processing of ctx pc
> related fields, which is the reason why we need do specially process.
> For example,
>
> static bool trans_auipc(DisasContext *ctx, arg_auipc *a)
> {
> - gen_set_gpri(ctx, a->rd, a->imm + ctx->base.pc_next);
> + if (tb_cflags(ctx->cflags) & CF_PCREL) {
> + target_ulong pc_rel = ctx->base.pc_next - ctx->base.pc_first
> + a->imm;
> + gen_set_gpr_pcrel(ctx, a->rd, cpu_pc, pc_rel);
> + } else {
> + gen_set_gpri(ctx, a->rd, a->imm + ctx->base.pc_next);
> + }
> return true;
> }
>
> +static void gen_set_gpr_pcrel(DisasContext *ctx, int reg_num, TCGv t,
> target_ulong rel)
> +{
> + TCGv dest = dest_gpr(ctx, reg_num);
> + tcg_gen_addi_tl(dest, t, rel);
> + gen_set_gpr(ctx, reg_num, dest);
> +}
> +
>
> But if it is too difficult to reuse the current implementation, your
> implementation is also acceptable to me.
Sorry, I don't get your idea. gen_pc_plus_diff() can do all the above job.
Regards,
Weiwei Li
>
> Zhiwei
>
>> target/riscv/translate.c | 48 ++++++++++++++++++++-----
>> 3 files changed, 70 insertions(+), 21 deletions(-)
>>
>> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
>> index 1e97473af2..646fa31a59 100644
>> --- a/target/riscv/cpu.c
>> +++ b/target/riscv/cpu.c
>> @@ -658,16 +658,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;
>> + }
>> }
>> }
>> @@ -693,11 +695,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];
>> }
>> diff --git a/target/riscv/insn_trans/trans_rvi.c.inc
>> b/target/riscv/insn_trans/trans_rvi.c.inc
>> index cc72864d32..7cbbdac5aa 100644
>> --- a/target/riscv/insn_trans/trans_rvi.c.inc
>> +++ b/target/riscv/insn_trans/trans_rvi.c.inc
>> @@ -38,7 +38,9 @@ static bool trans_lui(DisasContext *ctx, arg_lui *a)
>> static bool trans_auipc(DisasContext *ctx, arg_auipc *a)
>> {
>> - gen_set_gpri(ctx, a->rd, a->imm + ctx->base.pc_next);
>> + TCGv target_pc = dest_gpr(ctx, a->rd);
>> + gen_pc_plus_diff(target_pc, ctx, a->imm + ctx->base.pc_next);
>> + gen_set_gpr(ctx, a->rd, target_pc);
>> return true;
>> }
>> @@ -52,6 +54,7 @@ static bool trans_jalr(DisasContext *ctx,
>> arg_jalr *a)
>> {
>> TCGLabel *misaligned = NULL;
>> TCGv target_pc = tcg_temp_new();
>> + TCGv succ_pc = dest_gpr(ctx, a->rd);
>> tcg_gen_addi_tl(target_pc, get_gpr(ctx, a->rs1, EXT_NONE),
>> a->imm);
>> tcg_gen_andi_tl(target_pc, target_pc, (target_ulong)-2);
>> @@ -68,7 +71,9 @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
>> tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0x0, misaligned);
>> }
>> - gen_set_gpri(ctx, a->rd, ctx->pc_succ_insn);
>> + gen_pc_plus_diff(succ_pc, ctx, ctx->pc_succ_insn);
>> + gen_set_gpr(ctx, a->rd, succ_pc);
>> +
>> tcg_gen_mov_tl(cpu_pc, target_pc);
>> lookup_and_goto_ptr(ctx);
>> @@ -159,6 +164,7 @@ static bool gen_branch(DisasContext *ctx, arg_b
>> *a, TCGCond cond)
>> TCGv src1 = get_gpr(ctx, a->rs1, EXT_SIGN);
>> TCGv src2 = get_gpr(ctx, a->rs2, EXT_SIGN);
>> target_ulong next_pc;
>> + target_ulong orig_pc_save = ctx->pc_save;
>> if (get_xl(ctx) == MXL_RV128) {
>> TCGv src1h = get_gprh(ctx, a->rs1);
>> @@ -175,6 +181,7 @@ static bool gen_branch(DisasContext *ctx, arg_b
>> *a, TCGCond cond)
>> gen_set_label(l); /* branch taken */
>> + ctx->pc_save = orig_pc_save;
>> next_pc = ctx->base.pc_next + a->imm;
>> if (!has_ext(ctx, RVC) && (next_pc & 0x3)) {
>> /* misaligned */
>> @@ -182,8 +189,9 @@ static bool gen_branch(DisasContext *ctx, arg_b
>> *a, TCGCond cond)
>> gen_pc_plus_diff(target_pc, ctx, next_pc);
>> gen_exception_inst_addr_mis(ctx, target_pc);
>> } else {
>> - gen_goto_tb(ctx, 0, ctx->base.pc_next + a->imm);
>> + gen_goto_tb(ctx, 0, next_pc);
>> }
>> + ctx->pc_save = -1;
>> ctx->base.is_jmp = DISAS_NORETURN;
>> return true;
>> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
>> index d434fedb37..4623749602 100644
>> --- a/target/riscv/translate.c
>> +++ b/target/riscv/translate.c
>> @@ -59,6 +59,7 @@ typedef struct DisasContext {
>> DisasContextBase base;
>> /* pc_succ_insn points to the instruction following
>> base.pc_next */
>> target_ulong pc_succ_insn;
>> + target_ulong pc_save;
>> target_ulong priv_ver;
>> RISCVMXL misa_mxl_max;
>> RISCVMXL xl;
>> @@ -225,15 +226,24 @@ static void decode_save_opc(DisasContext *ctx)
>> static void gen_pc_plus_diff(TCGv target, DisasContext *ctx,
>> target_ulong dest)
>> {
>> - if (get_xl(ctx) == MXL_RV32) {
>> - dest = (int32_t)dest;
>> + assert(ctx->pc_save != -1);
>> + if (tb_cflags(ctx->base.tb) & CF_PCREL) {
>> + tcg_gen_addi_tl(target, cpu_pc, dest - ctx->pc_save);
>> + if (get_xl(ctx) == MXL_RV32) {
>> + tcg_gen_ext32s_tl(target, target);
>> + }
>> + } else {
>> + if (get_xl(ctx) == MXL_RV32) {
>> + dest = (int32_t)dest;
>> + }
>> + tcg_gen_movi_tl(target, dest);
>> }
>> - tcg_gen_movi_tl(target, dest);
>> }
>> static void gen_set_pc_imm(DisasContext *ctx, target_ulong dest)
>> {
>> gen_pc_plus_diff(cpu_pc, ctx, dest);
>> + ctx->pc_save = dest;
>> }
>> static void generate_exception(DisasContext *ctx, int excp)
>> @@ -287,8 +297,21 @@ static void gen_goto_tb(DisasContext *ctx, int
>> n, target_ulong dest)
>> * direct block chain benefits will be small.
>> */
>> if (translator_use_goto_tb(&ctx->base, dest) && !ctx->itrigger) {
>> - tcg_gen_goto_tb(n);
>> - gen_set_pc_imm(ctx, dest);
>> + /*
>> + * For pcrel, the pc must always be up-to-date on entry to
>> + * the linked TB, so that it can use simple additions for all
>> + * further adjustments. For !pcrel, the linked TB is compiled
>> + * to know its full virtual address, so we can delay the
>> + * update to pc to the unlinked path. A long chain of links
>> + * can thus avoid many updates to the PC.
>> + */
>> + if (tb_cflags(ctx->base.tb) & CF_PCREL) {
>> + gen_set_pc_imm(ctx, dest);
>> + tcg_gen_goto_tb(n);
>> + } else {
>> + tcg_gen_goto_tb(n);
>> + gen_set_pc_imm(ctx, dest);
>> + }
>> tcg_gen_exit_tb(ctx->base.tb, n);
>> } else {
>> gen_set_pc_imm(ctx, dest);
>> @@ -543,6 +566,7 @@ static void gen_set_fpr_d(DisasContext *ctx, int
>> reg_num, TCGv_i64 t)
>> static void gen_jal(DisasContext *ctx, int rd, target_ulong imm)
>> {
>> target_ulong next_pc;
>> + TCGv succ_pc = dest_gpr(ctx, rd);
>> /* check misaligned: */
>> next_pc = ctx->base.pc_next + imm;
>> @@ -555,8 +579,10 @@ static void gen_jal(DisasContext *ctx, int rd,
>> target_ulong imm)
>> }
>> }
>> - gen_set_gpri(ctx, rd, ctx->pc_succ_insn);
>> - gen_goto_tb(ctx, 0, ctx->base.pc_next + imm); /* must use this
>> for safety */
>> + gen_pc_plus_diff(succ_pc, ctx, ctx->pc_succ_insn);
>> + gen_set_gpr(ctx, rd, succ_pc);
>> +
>> + gen_goto_tb(ctx, 0, next_pc); /* must use this for safety */
>> ctx->base.is_jmp = DISAS_NORETURN;
>> }
>> @@ -1150,6 +1176,7 @@ static void
>> riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
>> RISCVCPU *cpu = RISCV_CPU(cs);
>> uint32_t tb_flags = ctx->base.tb->flags;
>> + ctx->pc_save = ctx->base.pc_first;
>> ctx->pc_succ_insn = ctx->base.pc_first;
>> ctx->mem_idx = FIELD_EX32(tb_flags, TB_FLAGS, MEM_IDX);
>> ctx->mstatus_fs = tb_flags & TB_FLAGS_MSTATUS_FS;
>> @@ -1195,8 +1222,13 @@ static void riscv_tr_tb_start(DisasContextBase
>> *db, CPUState *cpu)
>> static void riscv_tr_insn_start(DisasContextBase *dcbase, CPUState
>> *cpu)
>> {
>> DisasContext *ctx = container_of(dcbase, DisasContext, base);
>> + target_ulong pc_next = ctx->base.pc_next;
>> +
>> + if (tb_cflags(dcbase->tb) & CF_PCREL) {
>> + pc_next &= ~TARGET_PAGE_MASK;
>> + }
>> - tcg_gen_insn_start(ctx->base.pc_next, 0);
>> + tcg_gen_insn_start(pc_next, 0);
>> ctx->insn_start = tcg_last_op();
>> }
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v6 4/6] target/riscv: Add support for PC-relative translation
2023-04-04 3:46 ` liweiwei
@ 2023-04-04 7:07 ` LIU Zhiwei
2023-04-04 8:48 ` liweiwei
2023-04-04 14:05 ` Richard Henderson
0 siblings, 2 replies; 26+ messages in thread
From: LIU Zhiwei @ 2023-04-04 7:07 UTC (permalink / raw)
To: liweiwei, qemu-riscv, qemu-devel
Cc: palmer, alistair.francis, bin.meng, dbarboza, wangjunqiang,
lazyparser, Richard Henderson
On 2023/4/4 11:46, liweiwei wrote:
>
> On 2023/4/4 11:12, LIU Zhiwei wrote:
>>
>> On 2023/4/4 10:06, Weiwei Li wrote:
>>> Add a base pc_save for PC-relative translation(CF_PCREL).
>>> Diable the directly sync pc from tb by riscv_cpu_synchronize_from_tb.
>>> We can get pc-relative address from following formula:
>>> real_pc = (old)env->pc + diff, where diff = target_pc -
>>> ctx->pc_save.
>>> Use gen_get_target_pc to compute target address of auipc and successor
>>> address of jalr and jal.
>>>
>>> The existence of CF_PCREL can improve performance with the guest
>>> kernel's address space randomization. Each guest process maps libc.so
>>> (et al) at a different virtual address, and this allows those
>>> translations to be shared.
>>>
>>> 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>
>>> ---
>>> target/riscv/cpu.c | 29 +++++++++------
>>> target/riscv/insn_trans/trans_rvi.c.inc | 14 ++++++--
>>
>> Miss the process for trans_ebreak.
>>
>> I want to construct the PCREL feature on the processing of ctx pc
>> related fields, which is the reason why we need do specially process.
>> For example,
>>
>> static bool trans_auipc(DisasContext *ctx, arg_auipc *a)
>> {
>> - gen_set_gpri(ctx, a->rd, a->imm + ctx->base.pc_next);
>> + if (tb_cflags(ctx->cflags) & CF_PCREL) {
>> + target_ulong pc_rel = ctx->base.pc_next - ctx->base.pc_first
>> + a->imm;
>> + gen_set_gpr_pcrel(ctx, a->rd, cpu_pc, pc_rel);
>> + } else {
>> + gen_set_gpri(ctx, a->rd, a->imm + ctx->base.pc_next);
>> + }
>> return true;
>> }
>>
>> +static void gen_set_gpr_pcrel(DisasContext *ctx, int reg_num, TCGv
>> t, target_ulong rel)
>> +{
>> + TCGv dest = dest_gpr(ctx, reg_num);
>> + tcg_gen_addi_tl(dest, t, rel);
>> + gen_set_gpr(ctx, reg_num, dest);
>> +}
>> +
>>
>> But if it is too difficult to reuse the current implementation, your
>> implementation is also acceptable to me.
>
> Sorry, I don't get your idea. gen_pc_plus_diff() can do all the above
> job.
Yes, I think so. I just suspect whether it is easy to read and verify
the correctness. And the maintenance for the future.
1) Maybe we should split the PCREL to a split patch set, as it is a new
feature. The point masking can still use this thread.
2) For the new patch set for PCREL, process where we need to modify one
by one. One clue for recognize where to modify is the ctx pc related
fields, such as pc_next/pc_first/succ_insn_pc.
One thing may worth to try is that don't change the code in
insn_trans/trans_X. Just rename the origin API we need to modify to a
new name with _abs suffix. And and a correspond set of API for PCREL
with _pcrel suffix.
For example, in DisasContext, we define
void (*gen_set_gpri)(DisasContext *ctx, int reg_num, target_long imm);
In disas_init_fn,
if (tb_cflags(tb) & CF_PCREL) {
gen_set_gpri = gen_set_gpri_pcrel;
} else {
gen_set_gpri = gen_set_gpri_abs;
}
Thus we can write the code in trans_insn without think about the PCREL.
Thanks,
Zhiwei
>
> Regards,
>
> Weiwei Li
>
>>
>> Zhiwei
>>
>>> target/riscv/translate.c | 48 ++++++++++++++++++++-----
>>> 3 files changed, 70 insertions(+), 21 deletions(-)
>>>
>>> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
>>> index 1e97473af2..646fa31a59 100644
>>> --- a/target/riscv/cpu.c
>>> +++ b/target/riscv/cpu.c
>>> @@ -658,16 +658,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;
>>> + }
>>> }
>>> }
>>> @@ -693,11 +695,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];
>>> }
>>> diff --git a/target/riscv/insn_trans/trans_rvi.c.inc
>>> b/target/riscv/insn_trans/trans_rvi.c.inc
>>> index cc72864d32..7cbbdac5aa 100644
>>> --- a/target/riscv/insn_trans/trans_rvi.c.inc
>>> +++ b/target/riscv/insn_trans/trans_rvi.c.inc
>>> @@ -38,7 +38,9 @@ static bool trans_lui(DisasContext *ctx, arg_lui *a)
>>> static bool trans_auipc(DisasContext *ctx, arg_auipc *a)
>>> {
>>> - gen_set_gpri(ctx, a->rd, a->imm + ctx->base.pc_next);
>>> + TCGv target_pc = dest_gpr(ctx, a->rd);
>>> + gen_pc_plus_diff(target_pc, ctx, a->imm + ctx->base.pc_next);
>>> + gen_set_gpr(ctx, a->rd, target_pc);
>>> return true;
>>> }
>>> @@ -52,6 +54,7 @@ static bool trans_jalr(DisasContext *ctx,
>>> arg_jalr *a)
>>> {
>>> TCGLabel *misaligned = NULL;
>>> TCGv target_pc = tcg_temp_new();
>>> + TCGv succ_pc = dest_gpr(ctx, a->rd);
>>> tcg_gen_addi_tl(target_pc, get_gpr(ctx, a->rs1, EXT_NONE),
>>> a->imm);
>>> tcg_gen_andi_tl(target_pc, target_pc, (target_ulong)-2);
>>> @@ -68,7 +71,9 @@ static bool trans_jalr(DisasContext *ctx, arg_jalr
>>> *a)
>>> tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0x0, misaligned);
>>> }
>>> - gen_set_gpri(ctx, a->rd, ctx->pc_succ_insn);
>>> + gen_pc_plus_diff(succ_pc, ctx, ctx->pc_succ_insn);
>>> + gen_set_gpr(ctx, a->rd, succ_pc);
>>> +
>>> tcg_gen_mov_tl(cpu_pc, target_pc);
>>> lookup_and_goto_ptr(ctx);
>>> @@ -159,6 +164,7 @@ static bool gen_branch(DisasContext *ctx,
>>> arg_b *a, TCGCond cond)
>>> TCGv src1 = get_gpr(ctx, a->rs1, EXT_SIGN);
>>> TCGv src2 = get_gpr(ctx, a->rs2, EXT_SIGN);
>>> target_ulong next_pc;
>>> + target_ulong orig_pc_save = ctx->pc_save;
>>> if (get_xl(ctx) == MXL_RV128) {
>>> TCGv src1h = get_gprh(ctx, a->rs1);
>>> @@ -175,6 +181,7 @@ static bool gen_branch(DisasContext *ctx, arg_b
>>> *a, TCGCond cond)
>>> gen_set_label(l); /* branch taken */
>>> + ctx->pc_save = orig_pc_save;
>>> next_pc = ctx->base.pc_next + a->imm;
>>> if (!has_ext(ctx, RVC) && (next_pc & 0x3)) {
>>> /* misaligned */
>>> @@ -182,8 +189,9 @@ static bool gen_branch(DisasContext *ctx, arg_b
>>> *a, TCGCond cond)
>>> gen_pc_plus_diff(target_pc, ctx, next_pc);
>>> gen_exception_inst_addr_mis(ctx, target_pc);
>>> } else {
>>> - gen_goto_tb(ctx, 0, ctx->base.pc_next + a->imm);
>>> + gen_goto_tb(ctx, 0, next_pc);
>>> }
>>> + ctx->pc_save = -1;
>>> ctx->base.is_jmp = DISAS_NORETURN;
>>> return true;
>>> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
>>> index d434fedb37..4623749602 100644
>>> --- a/target/riscv/translate.c
>>> +++ b/target/riscv/translate.c
>>> @@ -59,6 +59,7 @@ typedef struct DisasContext {
>>> DisasContextBase base;
>>> /* pc_succ_insn points to the instruction following
>>> base.pc_next */
>>> target_ulong pc_succ_insn;
>>> + target_ulong pc_save;
>>> target_ulong priv_ver;
>>> RISCVMXL misa_mxl_max;
>>> RISCVMXL xl;
>>> @@ -225,15 +226,24 @@ static void decode_save_opc(DisasContext *ctx)
>>> static void gen_pc_plus_diff(TCGv target, DisasContext *ctx,
>>> target_ulong dest)
>>> {
>>> - if (get_xl(ctx) == MXL_RV32) {
>>> - dest = (int32_t)dest;
>>> + assert(ctx->pc_save != -1);
>>> + if (tb_cflags(ctx->base.tb) & CF_PCREL) {
>>> + tcg_gen_addi_tl(target, cpu_pc, dest - ctx->pc_save);
>>> + if (get_xl(ctx) == MXL_RV32) {
>>> + tcg_gen_ext32s_tl(target, target);
>>> + }
>>> + } else {
>>> + if (get_xl(ctx) == MXL_RV32) {
>>> + dest = (int32_t)dest;
>>> + }
>>> + tcg_gen_movi_tl(target, dest);
>>> }
>>> - tcg_gen_movi_tl(target, dest);
>>> }
>>> static void gen_set_pc_imm(DisasContext *ctx, target_ulong dest)
>>> {
>>> gen_pc_plus_diff(cpu_pc, ctx, dest);
>>> + ctx->pc_save = dest;
>>> }
>>> static void generate_exception(DisasContext *ctx, int excp)
>>> @@ -287,8 +297,21 @@ static void gen_goto_tb(DisasContext *ctx, int
>>> n, target_ulong dest)
>>> * direct block chain benefits will be small.
>>> */
>>> if (translator_use_goto_tb(&ctx->base, dest) && !ctx->itrigger) {
>>> - tcg_gen_goto_tb(n);
>>> - gen_set_pc_imm(ctx, dest);
>>> + /*
>>> + * For pcrel, the pc must always be up-to-date on entry to
>>> + * the linked TB, so that it can use simple additions for all
>>> + * further adjustments. For !pcrel, the linked TB is compiled
>>> + * to know its full virtual address, so we can delay the
>>> + * update to pc to the unlinked path. A long chain of links
>>> + * can thus avoid many updates to the PC.
>>> + */
>>> + if (tb_cflags(ctx->base.tb) & CF_PCREL) {
>>> + gen_set_pc_imm(ctx, dest);
>>> + tcg_gen_goto_tb(n);
>>> + } else {
>>> + tcg_gen_goto_tb(n);
>>> + gen_set_pc_imm(ctx, dest);
>>> + }
>>> tcg_gen_exit_tb(ctx->base.tb, n);
>>> } else {
>>> gen_set_pc_imm(ctx, dest);
>>> @@ -543,6 +566,7 @@ static void gen_set_fpr_d(DisasContext *ctx, int
>>> reg_num, TCGv_i64 t)
>>> static void gen_jal(DisasContext *ctx, int rd, target_ulong imm)
>>> {
>>> target_ulong next_pc;
>>> + TCGv succ_pc = dest_gpr(ctx, rd);
>>> /* check misaligned: */
>>> next_pc = ctx->base.pc_next + imm;
>>> @@ -555,8 +579,10 @@ static void gen_jal(DisasContext *ctx, int rd,
>>> target_ulong imm)
>>> }
>>> }
>>> - gen_set_gpri(ctx, rd, ctx->pc_succ_insn);
>>> - gen_goto_tb(ctx, 0, ctx->base.pc_next + imm); /* must use this
>>> for safety */
>>> + gen_pc_plus_diff(succ_pc, ctx, ctx->pc_succ_insn);
>>> + gen_set_gpr(ctx, rd, succ_pc);
>>> +
>>> + gen_goto_tb(ctx, 0, next_pc); /* must use this for safety */
>>> ctx->base.is_jmp = DISAS_NORETURN;
>>> }
>>> @@ -1150,6 +1176,7 @@ static void
>>> riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
>>> RISCVCPU *cpu = RISCV_CPU(cs);
>>> uint32_t tb_flags = ctx->base.tb->flags;
>>> + ctx->pc_save = ctx->base.pc_first;
>>> ctx->pc_succ_insn = ctx->base.pc_first;
>>> ctx->mem_idx = FIELD_EX32(tb_flags, TB_FLAGS, MEM_IDX);
>>> ctx->mstatus_fs = tb_flags & TB_FLAGS_MSTATUS_FS;
>>> @@ -1195,8 +1222,13 @@ static void
>>> riscv_tr_tb_start(DisasContextBase *db, CPUState *cpu)
>>> static void riscv_tr_insn_start(DisasContextBase *dcbase, CPUState
>>> *cpu)
>>> {
>>> DisasContext *ctx = container_of(dcbase, DisasContext, base);
>>> + target_ulong pc_next = ctx->base.pc_next;
>>> +
>>> + if (tb_cflags(dcbase->tb) & CF_PCREL) {
>>> + pc_next &= ~TARGET_PAGE_MASK;
>>> + }
>>> - tcg_gen_insn_start(ctx->base.pc_next, 0);
>>> + tcg_gen_insn_start(pc_next, 0);
>>> ctx->insn_start = tcg_last_op();
>>> }
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v6 4/6] target/riscv: Add support for PC-relative translation
2023-04-04 7:07 ` LIU Zhiwei
@ 2023-04-04 8:48 ` liweiwei
2023-04-04 9:23 ` LIU Zhiwei
2023-04-04 14:05 ` Richard Henderson
1 sibling, 1 reply; 26+ messages in thread
From: liweiwei @ 2023-04-04 8:48 UTC (permalink / raw)
To: LIU Zhiwei, qemu-riscv, qemu-devel
Cc: liweiwei, palmer, alistair.francis, bin.meng, dbarboza,
wangjunqiang, lazyparser, Richard Henderson
On 2023/4/4 15:07, LIU Zhiwei wrote:
>
> On 2023/4/4 11:46, liweiwei wrote:
>>
>> On 2023/4/4 11:12, LIU Zhiwei wrote:
>>>
>>> On 2023/4/4 10:06, Weiwei Li wrote:
>>>> Add a base pc_save for PC-relative translation(CF_PCREL).
>>>> Diable the directly sync pc from tb by riscv_cpu_synchronize_from_tb.
>>>> We can get pc-relative address from following formula:
>>>> real_pc = (old)env->pc + diff, where diff = target_pc -
>>>> ctx->pc_save.
>>>> Use gen_get_target_pc to compute target address of auipc and successor
>>>> address of jalr and jal.
>>>>
>>>> The existence of CF_PCREL can improve performance with the guest
>>>> kernel's address space randomization. Each guest process maps libc.so
>>>> (et al) at a different virtual address, and this allows those
>>>> translations to be shared.
>>>>
>>>> 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>
>>>> ---
>>>> target/riscv/cpu.c | 29 +++++++++------
>>>> target/riscv/insn_trans/trans_rvi.c.inc | 14 ++++++--
>>>
>>> Miss the process for trans_ebreak.
>>>
>>> I want to construct the PCREL feature on the processing of ctx pc
>>> related fields, which is the reason why we need do specially
>>> process. For example,
>>>
>>> static bool trans_auipc(DisasContext *ctx, arg_auipc *a)
>>> {
>>> - gen_set_gpri(ctx, a->rd, a->imm + ctx->base.pc_next);
>>> + if (tb_cflags(ctx->cflags) & CF_PCREL) {
>>> + target_ulong pc_rel = ctx->base.pc_next -
>>> ctx->base.pc_first + a->imm;
>>> + gen_set_gpr_pcrel(ctx, a->rd, cpu_pc, pc_rel);
>>> + } else {
>>> + gen_set_gpri(ctx, a->rd, a->imm + ctx->base.pc_next);
>>> + }
>>> return true;
>>> }
>>>
>>> +static void gen_set_gpr_pcrel(DisasContext *ctx, int reg_num, TCGv
>>> t, target_ulong rel)
>>> +{
>>> + TCGv dest = dest_gpr(ctx, reg_num);
>>> + tcg_gen_addi_tl(dest, t, rel);
>>> + gen_set_gpr(ctx, reg_num, dest);
>>> +}
>>> +
>>>
>>> But if it is too difficult to reuse the current implementation, your
>>> implementation is also acceptable to me.
>>
>> Sorry, I don't get your idea. gen_pc_plus_diff() can do all the above
>> job.
>
> Yes, I think so. I just suspect whether it is easy to read and verify
> the correctness. And the maintenance for the future.
>
>
> 1) Maybe we should split the PCREL to a split patch set, as it is a
> new feature. The point masking can still use this thread.
Point mask for instruction relies on PCREL. That's why I introduce PCREL
in this patchset.
Maybe we can divide this patch if needed.
>
>
> 2) For the new patch set for PCREL, process where we need to modify
> one by one. One clue for recognize where to modify is the ctx pc
> related fields, such as pc_next/pc_first/succ_insn_pc.
>
> One thing may worth to try is that don't change the code in
> insn_trans/trans_X. Just rename the origin API we need to modify to a
> new name with _abs suffix. And and a correspond set of API for PCREL
> with _pcrel suffix.
>
I don't find a good way to remain trans_* unchanged to support PCREL.
> For example, in DisasContext, we define
>
> void (*gen_set_gpri)(DisasContext *ctx, int reg_num, target_long imm);
>
> In disas_init_fn,
>
> if (tb_cflags(tb) & CF_PCREL) {
> gen_set_gpri = gen_set_gpri_pcrel;
> } else {
> gen_set_gpri = gen_set_gpri_abs;
> }
> Thus we can write the code in trans_insn without think about the PCREL.
That's what I want. And PCREL also have been avoided in following code
of trans_*.
However, we should't update pc_next/pc_succ_insn related address into
register directly by reusing existed API like gen_set_gpri.
It's a general API to set gpr to any imm. However PC-relative only works
for pc-related imm.
Maybe we can introduce a new API like gen_set_gpr_pci() to set pc
related imm.
However it seems unnecessary, because it's no difference from current
logic by using gen_pc_plus_diff() from the developer hand.
Regards,
Weiwei Li
>
> Thanks,
> Zhiwei
>
>>
>> Regards,
>>
>> Weiwei Li
>>
>>>
>>> Zhiwei
>>>
>>>> target/riscv/translate.c | 48 ++++++++++++++++++++-----
>>>> 3 files changed, 70 insertions(+), 21 deletions(-)
>>>>
>>>> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
>>>> index 1e97473af2..646fa31a59 100644
>>>> --- a/target/riscv/cpu.c
>>>> +++ b/target/riscv/cpu.c
>>>> @@ -658,16 +658,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;
>>>> + }
>>>> }
>>>> }
>>>> @@ -693,11 +695,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];
>>>> }
>>>> diff --git a/target/riscv/insn_trans/trans_rvi.c.inc
>>>> b/target/riscv/insn_trans/trans_rvi.c.inc
>>>> index cc72864d32..7cbbdac5aa 100644
>>>> --- a/target/riscv/insn_trans/trans_rvi.c.inc
>>>> +++ b/target/riscv/insn_trans/trans_rvi.c.inc
>>>> @@ -38,7 +38,9 @@ static bool trans_lui(DisasContext *ctx, arg_lui *a)
>>>> static bool trans_auipc(DisasContext *ctx, arg_auipc *a)
>>>> {
>>>> - gen_set_gpri(ctx, a->rd, a->imm + ctx->base.pc_next);
>>>> + TCGv target_pc = dest_gpr(ctx, a->rd);
>>>> + gen_pc_plus_diff(target_pc, ctx, a->imm + ctx->base.pc_next);
>>>> + gen_set_gpr(ctx, a->rd, target_pc);
>>>> return true;
>>>> }
>>>> @@ -52,6 +54,7 @@ static bool trans_jalr(DisasContext *ctx,
>>>> arg_jalr *a)
>>>> {
>>>> TCGLabel *misaligned = NULL;
>>>> TCGv target_pc = tcg_temp_new();
>>>> + TCGv succ_pc = dest_gpr(ctx, a->rd);
>>>> tcg_gen_addi_tl(target_pc, get_gpr(ctx, a->rs1, EXT_NONE),
>>>> a->imm);
>>>> tcg_gen_andi_tl(target_pc, target_pc, (target_ulong)-2);
>>>> @@ -68,7 +71,9 @@ static bool trans_jalr(DisasContext *ctx,
>>>> arg_jalr *a)
>>>> tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0x0, misaligned);
>>>> }
>>>> - gen_set_gpri(ctx, a->rd, ctx->pc_succ_insn);
>>>> + gen_pc_plus_diff(succ_pc, ctx, ctx->pc_succ_insn);
>>>> + gen_set_gpr(ctx, a->rd, succ_pc);
>>>> +
>>>> tcg_gen_mov_tl(cpu_pc, target_pc);
>>>> lookup_and_goto_ptr(ctx);
>>>> @@ -159,6 +164,7 @@ static bool gen_branch(DisasContext *ctx,
>>>> arg_b *a, TCGCond cond)
>>>> TCGv src1 = get_gpr(ctx, a->rs1, EXT_SIGN);
>>>> TCGv src2 = get_gpr(ctx, a->rs2, EXT_SIGN);
>>>> target_ulong next_pc;
>>>> + target_ulong orig_pc_save = ctx->pc_save;
>>>> if (get_xl(ctx) == MXL_RV128) {
>>>> TCGv src1h = get_gprh(ctx, a->rs1);
>>>> @@ -175,6 +181,7 @@ static bool gen_branch(DisasContext *ctx, arg_b
>>>> *a, TCGCond cond)
>>>> gen_set_label(l); /* branch taken */
>>>> + ctx->pc_save = orig_pc_save;
>>>> next_pc = ctx->base.pc_next + a->imm;
>>>> if (!has_ext(ctx, RVC) && (next_pc & 0x3)) {
>>>> /* misaligned */
>>>> @@ -182,8 +189,9 @@ static bool gen_branch(DisasContext *ctx, arg_b
>>>> *a, TCGCond cond)
>>>> gen_pc_plus_diff(target_pc, ctx, next_pc);
>>>> gen_exception_inst_addr_mis(ctx, target_pc);
>>>> } else {
>>>> - gen_goto_tb(ctx, 0, ctx->base.pc_next + a->imm);
>>>> + gen_goto_tb(ctx, 0, next_pc);
>>>> }
>>>> + ctx->pc_save = -1;
>>>> ctx->base.is_jmp = DISAS_NORETURN;
>>>> return true;
>>>> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
>>>> index d434fedb37..4623749602 100644
>>>> --- a/target/riscv/translate.c
>>>> +++ b/target/riscv/translate.c
>>>> @@ -59,6 +59,7 @@ typedef struct DisasContext {
>>>> DisasContextBase base;
>>>> /* pc_succ_insn points to the instruction following
>>>> base.pc_next */
>>>> target_ulong pc_succ_insn;
>>>> + target_ulong pc_save;
>>>> target_ulong priv_ver;
>>>> RISCVMXL misa_mxl_max;
>>>> RISCVMXL xl;
>>>> @@ -225,15 +226,24 @@ static void decode_save_opc(DisasContext *ctx)
>>>> static void gen_pc_plus_diff(TCGv target, DisasContext *ctx,
>>>> target_ulong dest)
>>>> {
>>>> - if (get_xl(ctx) == MXL_RV32) {
>>>> - dest = (int32_t)dest;
>>>> + assert(ctx->pc_save != -1);
>>>> + if (tb_cflags(ctx->base.tb) & CF_PCREL) {
>>>> + tcg_gen_addi_tl(target, cpu_pc, dest - ctx->pc_save);
>>>> + if (get_xl(ctx) == MXL_RV32) {
>>>> + tcg_gen_ext32s_tl(target, target);
>>>> + }
>>>> + } else {
>>>> + if (get_xl(ctx) == MXL_RV32) {
>>>> + dest = (int32_t)dest;
>>>> + }
>>>> + tcg_gen_movi_tl(target, dest);
>>>> }
>>>> - tcg_gen_movi_tl(target, dest);
>>>> }
>>>> static void gen_set_pc_imm(DisasContext *ctx, target_ulong dest)
>>>> {
>>>> gen_pc_plus_diff(cpu_pc, ctx, dest);
>>>> + ctx->pc_save = dest;
>>>> }
>>>> static void generate_exception(DisasContext *ctx, int excp)
>>>> @@ -287,8 +297,21 @@ static void gen_goto_tb(DisasContext *ctx, int
>>>> n, target_ulong dest)
>>>> * direct block chain benefits will be small.
>>>> */
>>>> if (translator_use_goto_tb(&ctx->base, dest) &&
>>>> !ctx->itrigger) {
>>>> - tcg_gen_goto_tb(n);
>>>> - gen_set_pc_imm(ctx, dest);
>>>> + /*
>>>> + * For pcrel, the pc must always be up-to-date on entry to
>>>> + * the linked TB, so that it can use simple additions for all
>>>> + * further adjustments. For !pcrel, the linked TB is
>>>> compiled
>>>> + * to know its full virtual address, so we can delay the
>>>> + * update to pc to the unlinked path. A long chain of links
>>>> + * can thus avoid many updates to the PC.
>>>> + */
>>>> + if (tb_cflags(ctx->base.tb) & CF_PCREL) {
>>>> + gen_set_pc_imm(ctx, dest);
>>>> + tcg_gen_goto_tb(n);
>>>> + } else {
>>>> + tcg_gen_goto_tb(n);
>>>> + gen_set_pc_imm(ctx, dest);
>>>> + }
>>>> tcg_gen_exit_tb(ctx->base.tb, n);
>>>> } else {
>>>> gen_set_pc_imm(ctx, dest);
>>>> @@ -543,6 +566,7 @@ static void gen_set_fpr_d(DisasContext *ctx,
>>>> int reg_num, TCGv_i64 t)
>>>> static void gen_jal(DisasContext *ctx, int rd, target_ulong imm)
>>>> {
>>>> target_ulong next_pc;
>>>> + TCGv succ_pc = dest_gpr(ctx, rd);
>>>> /* check misaligned: */
>>>> next_pc = ctx->base.pc_next + imm;
>>>> @@ -555,8 +579,10 @@ static void gen_jal(DisasContext *ctx, int rd,
>>>> target_ulong imm)
>>>> }
>>>> }
>>>> - gen_set_gpri(ctx, rd, ctx->pc_succ_insn);
>>>> - gen_goto_tb(ctx, 0, ctx->base.pc_next + imm); /* must use this
>>>> for safety */
>>>> + gen_pc_plus_diff(succ_pc, ctx, ctx->pc_succ_insn);
>>>> + gen_set_gpr(ctx, rd, succ_pc);
>>>> +
>>>> + gen_goto_tb(ctx, 0, next_pc); /* must use this for safety */
>>>> ctx->base.is_jmp = DISAS_NORETURN;
>>>> }
>>>> @@ -1150,6 +1176,7 @@ static void
>>>> riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
>>>> RISCVCPU *cpu = RISCV_CPU(cs);
>>>> uint32_t tb_flags = ctx->base.tb->flags;
>>>> + ctx->pc_save = ctx->base.pc_first;
>>>> ctx->pc_succ_insn = ctx->base.pc_first;
>>>> ctx->mem_idx = FIELD_EX32(tb_flags, TB_FLAGS, MEM_IDX);
>>>> ctx->mstatus_fs = tb_flags & TB_FLAGS_MSTATUS_FS;
>>>> @@ -1195,8 +1222,13 @@ static void
>>>> riscv_tr_tb_start(DisasContextBase *db, CPUState *cpu)
>>>> static void riscv_tr_insn_start(DisasContextBase *dcbase,
>>>> CPUState *cpu)
>>>> {
>>>> DisasContext *ctx = container_of(dcbase, DisasContext, base);
>>>> + target_ulong pc_next = ctx->base.pc_next;
>>>> +
>>>> + if (tb_cflags(dcbase->tb) & CF_PCREL) {
>>>> + pc_next &= ~TARGET_PAGE_MASK;
>>>> + }
>>>> - tcg_gen_insn_start(ctx->base.pc_next, 0);
>>>> + tcg_gen_insn_start(pc_next, 0);
>>>> ctx->insn_start = tcg_last_op();
>>>> }
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v6 4/6] target/riscv: Add support for PC-relative translation
2023-04-04 8:48 ` liweiwei
@ 2023-04-04 9:23 ` LIU Zhiwei
0 siblings, 0 replies; 26+ messages in thread
From: LIU Zhiwei @ 2023-04-04 9:23 UTC (permalink / raw)
To: liweiwei, qemu-riscv, qemu-devel
Cc: palmer, alistair.francis, bin.meng, dbarboza, wangjunqiang,
lazyparser, Richard Henderson
On 2023/4/4 16:48, liweiwei wrote:
>
> On 2023/4/4 15:07, LIU Zhiwei wrote:
>>
>> On 2023/4/4 11:46, liweiwei wrote:
>>>
>>> On 2023/4/4 11:12, LIU Zhiwei wrote:
>>>>
>>>> On 2023/4/4 10:06, Weiwei Li wrote:
>>>>> Add a base pc_save for PC-relative translation(CF_PCREL).
>>>>> Diable the directly sync pc from tb by riscv_cpu_synchronize_from_tb.
>>>>> We can get pc-relative address from following formula:
>>>>> real_pc = (old)env->pc + diff, where diff = target_pc -
>>>>> ctx->pc_save.
>>>>> Use gen_get_target_pc to compute target address of auipc and
>>>>> successor
>>>>> address of jalr and jal.
>>>>>
>>>>> The existence of CF_PCREL can improve performance with the guest
>>>>> kernel's address space randomization. Each guest process maps
>>>>> libc.so
>>>>> (et al) at a different virtual address, and this allows those
>>>>> translations to be shared.
>>>>>
>>>>> 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>
>>>>> ---
>>>>> target/riscv/cpu.c | 29 +++++++++------
>>>>> target/riscv/insn_trans/trans_rvi.c.inc | 14 ++++++--
>>>>
>>>> Miss the process for trans_ebreak.
>>>>
>>>> I want to construct the PCREL feature on the processing of ctx pc
>>>> related fields, which is the reason why we need do specially
>>>> process. For example,
>>>>
>>>> static bool trans_auipc(DisasContext *ctx, arg_auipc *a)
>>>> {
>>>> - gen_set_gpri(ctx, a->rd, a->imm + ctx->base.pc_next);
>>>> + if (tb_cflags(ctx->cflags) & CF_PCREL) {
>>>> + target_ulong pc_rel = ctx->base.pc_next -
>>>> ctx->base.pc_first + a->imm;
>>>> + gen_set_gpr_pcrel(ctx, a->rd, cpu_pc, pc_rel);
>>>> + } else {
>>>> + gen_set_gpri(ctx, a->rd, a->imm + ctx->base.pc_next);
>>>> + }
>>>> return true;
>>>> }
>>>>
>>>> +static void gen_set_gpr_pcrel(DisasContext *ctx, int reg_num, TCGv
>>>> t, target_ulong rel)
>>>> +{
>>>> + TCGv dest = dest_gpr(ctx, reg_num);
>>>> + tcg_gen_addi_tl(dest, t, rel);
>>>> + gen_set_gpr(ctx, reg_num, dest);
>>>> +}
>>>> +
>>>>
>>>> But if it is too difficult to reuse the current implementation,
>>>> your implementation is also acceptable to me.
>>>
>>> Sorry, I don't get your idea. gen_pc_plus_diff() can do all the
>>> above job.
>>
>> Yes, I think so. I just suspect whether it is easy to read and verify
>> the correctness. And the maintenance for the future.
>>
>>
>> 1) Maybe we should split the PCREL to a split patch set, as it is a
>> new feature. The point masking can still use this thread.
>
> Point mask for instruction relies on PCREL. That's why I introduce
> PCREL in this patchset.
>
> Maybe we can divide this patch if needed.
If we won't use another way to rewrite the PCREL, we don't have to split it.
>
>>
>>
>> 2) For the new patch set for PCREL, process where we need to modify
>> one by one. One clue for recognize where to modify is the ctx pc
>> related fields, such as pc_next/pc_first/succ_insn_pc.
>>
>> One thing may worth to try is that don't change the code in
>> insn_trans/trans_X. Just rename the origin API we need to modify to
>> a new name with _abs suffix. And and a correspond set of API for
>> PCREL with _pcrel suffix.
>>
> I don't find a good way to remain trans_* unchanged to support PCREL.
>> For example, in DisasContext, we define
>>
>> void (*gen_set_gpri)(DisasContext *ctx, int reg_num, target_long imm);
>>
>> In disas_init_fn,
>>
>> if (tb_cflags(tb) & CF_PCREL) {
>> gen_set_gpri = gen_set_gpri_pcrel;
>> } else {
>> gen_set_gpri = gen_set_gpri_abs;
>> } Thus we can write the code in trans_insn without think about the
>> PCREL.
>
> That's what I want. And PCREL also have been avoided in following
> code of trans_*.
>
> However, we should't update pc_next/pc_succ_insn related address into
> register directly by reusing existed API like gen_set_gpri.
>
> It's a general API to set gpr to any imm. However PC-relative only
> works for pc-related imm.
>
> Maybe we can introduce a new API like gen_set_gpr_pci() to set pc
> related imm.
Yes, I think so, except _pci is not a good suffix. But I don't insist
on this way.
Zhiwei
>
> However it seems unnecessary, because it's no difference from current
> logic by using gen_pc_plus_diff() from the developer hand.
>
> Regards,
>
> Weiwei Li
>
>>
>> Thanks,
>> Zhiwei
>>
>>>
>>> Regards,
>>>
>>> Weiwei Li
>>>
>>>>
>>>> Zhiwei
>>>>
>>>>> target/riscv/translate.c | 48 ++++++++++++++++++++-----
>>>>> 3 files changed, 70 insertions(+), 21 deletions(-)
>>>>>
>>>>> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
>>>>> index 1e97473af2..646fa31a59 100644
>>>>> --- a/target/riscv/cpu.c
>>>>> +++ b/target/riscv/cpu.c
>>>>> @@ -658,16 +658,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;
>>>>> + }
>>>>> }
>>>>> }
>>>>> @@ -693,11 +695,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];
>>>>> }
>>>>> diff --git a/target/riscv/insn_trans/trans_rvi.c.inc
>>>>> b/target/riscv/insn_trans/trans_rvi.c.inc
>>>>> index cc72864d32..7cbbdac5aa 100644
>>>>> --- a/target/riscv/insn_trans/trans_rvi.c.inc
>>>>> +++ b/target/riscv/insn_trans/trans_rvi.c.inc
>>>>> @@ -38,7 +38,9 @@ static bool trans_lui(DisasContext *ctx, arg_lui
>>>>> *a)
>>>>> static bool trans_auipc(DisasContext *ctx, arg_auipc *a)
>>>>> {
>>>>> - gen_set_gpri(ctx, a->rd, a->imm + ctx->base.pc_next);
>>>>> + TCGv target_pc = dest_gpr(ctx, a->rd);
>>>>> + gen_pc_plus_diff(target_pc, ctx, a->imm + ctx->base.pc_next);
>>>>> + gen_set_gpr(ctx, a->rd, target_pc);
>>>>> return true;
>>>>> }
>>>>> @@ -52,6 +54,7 @@ static bool trans_jalr(DisasContext *ctx,
>>>>> arg_jalr *a)
>>>>> {
>>>>> TCGLabel *misaligned = NULL;
>>>>> TCGv target_pc = tcg_temp_new();
>>>>> + TCGv succ_pc = dest_gpr(ctx, a->rd);
>>>>> tcg_gen_addi_tl(target_pc, get_gpr(ctx, a->rs1, EXT_NONE),
>>>>> a->imm);
>>>>> tcg_gen_andi_tl(target_pc, target_pc, (target_ulong)-2);
>>>>> @@ -68,7 +71,9 @@ static bool trans_jalr(DisasContext *ctx,
>>>>> arg_jalr *a)
>>>>> tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0x0, misaligned);
>>>>> }
>>>>> - gen_set_gpri(ctx, a->rd, ctx->pc_succ_insn);
>>>>> + gen_pc_plus_diff(succ_pc, ctx, ctx->pc_succ_insn);
>>>>> + gen_set_gpr(ctx, a->rd, succ_pc);
>>>>> +
>>>>> tcg_gen_mov_tl(cpu_pc, target_pc);
>>>>> lookup_and_goto_ptr(ctx);
>>>>> @@ -159,6 +164,7 @@ static bool gen_branch(DisasContext *ctx,
>>>>> arg_b *a, TCGCond cond)
>>>>> TCGv src1 = get_gpr(ctx, a->rs1, EXT_SIGN);
>>>>> TCGv src2 = get_gpr(ctx, a->rs2, EXT_SIGN);
>>>>> target_ulong next_pc;
>>>>> + target_ulong orig_pc_save = ctx->pc_save;
>>>>> if (get_xl(ctx) == MXL_RV128) {
>>>>> TCGv src1h = get_gprh(ctx, a->rs1);
>>>>> @@ -175,6 +181,7 @@ static bool gen_branch(DisasContext *ctx,
>>>>> arg_b *a, TCGCond cond)
>>>>> gen_set_label(l); /* branch taken */
>>>>> + ctx->pc_save = orig_pc_save;
>>>>> next_pc = ctx->base.pc_next + a->imm;
>>>>> if (!has_ext(ctx, RVC) && (next_pc & 0x3)) {
>>>>> /* misaligned */
>>>>> @@ -182,8 +189,9 @@ static bool gen_branch(DisasContext *ctx,
>>>>> arg_b *a, TCGCond cond)
>>>>> gen_pc_plus_diff(target_pc, ctx, next_pc);
>>>>> gen_exception_inst_addr_mis(ctx, target_pc);
>>>>> } else {
>>>>> - gen_goto_tb(ctx, 0, ctx->base.pc_next + a->imm);
>>>>> + gen_goto_tb(ctx, 0, next_pc);
>>>>> }
>>>>> + ctx->pc_save = -1;
>>>>> ctx->base.is_jmp = DISAS_NORETURN;
>>>>> return true;
>>>>> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
>>>>> index d434fedb37..4623749602 100644
>>>>> --- a/target/riscv/translate.c
>>>>> +++ b/target/riscv/translate.c
>>>>> @@ -59,6 +59,7 @@ typedef struct DisasContext {
>>>>> DisasContextBase base;
>>>>> /* pc_succ_insn points to the instruction following
>>>>> base.pc_next */
>>>>> target_ulong pc_succ_insn;
>>>>> + target_ulong pc_save;
>>>>> target_ulong priv_ver;
>>>>> RISCVMXL misa_mxl_max;
>>>>> RISCVMXL xl;
>>>>> @@ -225,15 +226,24 @@ static void decode_save_opc(DisasContext *ctx)
>>>>> static void gen_pc_plus_diff(TCGv target, DisasContext *ctx,
>>>>> target_ulong dest)
>>>>> {
>>>>> - if (get_xl(ctx) == MXL_RV32) {
>>>>> - dest = (int32_t)dest;
>>>>> + assert(ctx->pc_save != -1);
>>>>> + if (tb_cflags(ctx->base.tb) & CF_PCREL) {
>>>>> + tcg_gen_addi_tl(target, cpu_pc, dest - ctx->pc_save);
>>>>> + if (get_xl(ctx) == MXL_RV32) {
>>>>> + tcg_gen_ext32s_tl(target, target);
>>>>> + }
>>>>> + } else {
>>>>> + if (get_xl(ctx) == MXL_RV32) {
>>>>> + dest = (int32_t)dest;
>>>>> + }
>>>>> + tcg_gen_movi_tl(target, dest);
>>>>> }
>>>>> - tcg_gen_movi_tl(target, dest);
>>>>> }
>>>>> static void gen_set_pc_imm(DisasContext *ctx, target_ulong dest)
>>>>> {
>>>>> gen_pc_plus_diff(cpu_pc, ctx, dest);
>>>>> + ctx->pc_save = dest;
>>>>> }
>>>>> static void generate_exception(DisasContext *ctx, int excp)
>>>>> @@ -287,8 +297,21 @@ static void gen_goto_tb(DisasContext *ctx,
>>>>> int n, target_ulong dest)
>>>>> * direct block chain benefits will be small.
>>>>> */
>>>>> if (translator_use_goto_tb(&ctx->base, dest) &&
>>>>> !ctx->itrigger) {
>>>>> - tcg_gen_goto_tb(n);
>>>>> - gen_set_pc_imm(ctx, dest);
>>>>> + /*
>>>>> + * For pcrel, the pc must always be up-to-date on entry to
>>>>> + * the linked TB, so that it can use simple additions for
>>>>> all
>>>>> + * further adjustments. For !pcrel, the linked TB is
>>>>> compiled
>>>>> + * to know its full virtual address, so we can delay the
>>>>> + * update to pc to the unlinked path. A long chain of links
>>>>> + * can thus avoid many updates to the PC.
>>>>> + */
>>>>> + if (tb_cflags(ctx->base.tb) & CF_PCREL) {
>>>>> + gen_set_pc_imm(ctx, dest);
>>>>> + tcg_gen_goto_tb(n);
>>>>> + } else {
>>>>> + tcg_gen_goto_tb(n);
>>>>> + gen_set_pc_imm(ctx, dest);
>>>>> + }
>>>>> tcg_gen_exit_tb(ctx->base.tb, n);
>>>>> } else {
>>>>> gen_set_pc_imm(ctx, dest);
>>>>> @@ -543,6 +566,7 @@ static void gen_set_fpr_d(DisasContext *ctx,
>>>>> int reg_num, TCGv_i64 t)
>>>>> static void gen_jal(DisasContext *ctx, int rd, target_ulong imm)
>>>>> {
>>>>> target_ulong next_pc;
>>>>> + TCGv succ_pc = dest_gpr(ctx, rd);
>>>>> /* check misaligned: */
>>>>> next_pc = ctx->base.pc_next + imm;
>>>>> @@ -555,8 +579,10 @@ static void gen_jal(DisasContext *ctx, int
>>>>> rd, target_ulong imm)
>>>>> }
>>>>> }
>>>>> - gen_set_gpri(ctx, rd, ctx->pc_succ_insn);
>>>>> - gen_goto_tb(ctx, 0, ctx->base.pc_next + imm); /* must use
>>>>> this for safety */
>>>>> + gen_pc_plus_diff(succ_pc, ctx, ctx->pc_succ_insn);
>>>>> + gen_set_gpr(ctx, rd, succ_pc);
>>>>> +
>>>>> + gen_goto_tb(ctx, 0, next_pc); /* must use this for safety */
>>>>> ctx->base.is_jmp = DISAS_NORETURN;
>>>>> }
>>>>> @@ -1150,6 +1176,7 @@ static void
>>>>> riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
>>>>> RISCVCPU *cpu = RISCV_CPU(cs);
>>>>> uint32_t tb_flags = ctx->base.tb->flags;
>>>>> + ctx->pc_save = ctx->base.pc_first;
>>>>> ctx->pc_succ_insn = ctx->base.pc_first;
>>>>> ctx->mem_idx = FIELD_EX32(tb_flags, TB_FLAGS, MEM_IDX);
>>>>> ctx->mstatus_fs = tb_flags & TB_FLAGS_MSTATUS_FS;
>>>>> @@ -1195,8 +1222,13 @@ static void
>>>>> riscv_tr_tb_start(DisasContextBase *db, CPUState *cpu)
>>>>> static void riscv_tr_insn_start(DisasContextBase *dcbase,
>>>>> CPUState *cpu)
>>>>> {
>>>>> DisasContext *ctx = container_of(dcbase, DisasContext, base);
>>>>> + target_ulong pc_next = ctx->base.pc_next;
>>>>> +
>>>>> + if (tb_cflags(dcbase->tb) & CF_PCREL) {
>>>>> + pc_next &= ~TARGET_PAGE_MASK;
>>>>> + }
>>>>> - tcg_gen_insn_start(ctx->base.pc_next, 0);
>>>>> + tcg_gen_insn_start(pc_next, 0);
>>>>> ctx->insn_start = tcg_last_op();
>>>>> }
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v6 4/6] target/riscv: Add support for PC-relative translation
2023-04-04 2:06 ` [PATCH v6 4/6] target/riscv: Add support for PC-relative translation Weiwei Li
2023-04-04 3:12 ` LIU Zhiwei
@ 2023-04-04 13:56 ` Richard Henderson
2023-04-04 14:33 ` liweiwei
1 sibling, 1 reply; 26+ messages in thread
From: Richard Henderson @ 2023-04-04 13:56 UTC (permalink / raw)
To: Weiwei Li, qemu-riscv, qemu-devel
Cc: palmer, alistair.francis, bin.meng, dbarboza, zhiwei_liu,
wangjunqiang, lazyparser
On 4/3/23 19:06, Weiwei Li wrote:
> static bool trans_auipc(DisasContext *ctx, arg_auipc *a)
> {
> - gen_set_gpri(ctx, a->rd, a->imm + ctx->base.pc_next);
> + TCGv target_pc = dest_gpr(ctx, a->rd);
> + gen_pc_plus_diff(target_pc, ctx, a->imm + ctx->base.pc_next);
> + gen_set_gpr(ctx, a->rd, target_pc);
> return true;
> }
This is not how I expect a function called "pc plus diff" to work.
It should be simpler:
TCGv rd = dest_gpr(ctx, a->rd);
gen_pc_plus_diff(ctx, rd, a->imm);
gen_set_gpr(ctx, a->rd, rd);
All of the manipulation of cpu_pc, pc_save, and pc_next are all hidden inside the
function. All that "add upper immediate to pc" should do is supply the immediate.
r~
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v6 4/6] target/riscv: Add support for PC-relative translation
2023-04-04 7:07 ` LIU Zhiwei
2023-04-04 8:48 ` liweiwei
@ 2023-04-04 14:05 ` Richard Henderson
1 sibling, 0 replies; 26+ messages in thread
From: Richard Henderson @ 2023-04-04 14:05 UTC (permalink / raw)
To: LIU Zhiwei, liweiwei, qemu-riscv, qemu-devel
Cc: palmer, alistair.francis, bin.meng, dbarboza, wangjunqiang,
lazyparser
On 4/4/23 00:07, LIU Zhiwei wrote:
> Yes, I think so. I just suspect whether it is easy to read and verify the correctness. And
> the maintenance for the future.
>
>
> 1) Maybe we should split the PCREL to a split patch set, as it is a new feature. The point
> masking can still use this thread.
Yes.
> 2) For the new patch set for PCREL, process where we need to modify one by one. One clue
> for recognize where to modify is the ctx pc related fields, such as
> pc_next/pc_first/succ_insn_pc.
>
> One thing may worth to try is that don't change the code in insn_trans/trans_X. Just
> rename the origin API we need to modify to a new name with _abs suffix. And and a
> correspond set of API for PCREL with _pcrel suffix.
>
> For example, in DisasContext, we define
>
> void (*gen_set_gpri)(DisasContext *ctx, int reg_num, target_long imm);
>
> In disas_init_fn,
>
> if (tb_cflags(tb) & CF_PCREL) {
> gen_set_gpri = gen_set_gpri_pcrel;
> } else {
> gen_set_gpri = gen_set_gpri_abs;
> }
>
> Thus we can write the code in trans_insn without think about the PCREL.
No. Please have a look at how the other conversions have progressed. E.g.
https://lore.kernel.org/qemu-devel/20220930220312.135327-1-richard.henderson@linaro.org/
Step by step, each of the internal translation functions is converted from absolute to
relative values. By operating on relative values, all knowledge of "pc" is centralized,
and it simplifies the trans_* functions.
r~
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v6 4/6] target/riscv: Add support for PC-relative translation
2023-04-04 13:56 ` Richard Henderson
@ 2023-04-04 14:33 ` liweiwei
2023-04-04 14:57 ` Richard Henderson
0 siblings, 1 reply; 26+ messages in thread
From: liweiwei @ 2023-04-04 14:33 UTC (permalink / raw)
To: Richard Henderson, qemu-riscv, qemu-devel
Cc: liweiwei, palmer, alistair.francis, bin.meng, dbarboza,
zhiwei_liu, wangjunqiang, lazyparser
[-- Attachment #1: Type: text/plain, Size: 1312 bytes --]
On 2023/4/4 21:56, Richard Henderson wrote:
> On 4/3/23 19:06, Weiwei Li wrote:
>> static bool trans_auipc(DisasContext *ctx, arg_auipc *a)
>> {
>> - gen_set_gpri(ctx, a->rd, a->imm + ctx->base.pc_next);
>> + TCGv target_pc = dest_gpr(ctx, a->rd);
>> + gen_pc_plus_diff(target_pc, ctx, a->imm + ctx->base.pc_next);
>> + gen_set_gpr(ctx, a->rd, target_pc);
>> return true;
>> }
>
> This is not how I expect a function called "pc plus diff" to work.
Yeah, it's different from the similar function in ARM.
However, it's more in line with the original RISC-V logic.
Maybe we can change a name for the function, such as
gen_pc_relative_address().
> It should be simpler:
>
>
> TCGv rd = dest_gpr(ctx, a->rd);
>
> gen_pc_plus_diff(ctx, rd, a->imm);
> gen_set_gpr(ctx, a->rd, rd);
>
> All of the manipulation of cpu_pc, pc_save, and pc_next are all hidden
> inside the function. All that "add upper immediate to pc" should do
> is supply the immediate.
If we want to hide all of them in gen_pc_plus_diff, then we need
calculate the diff for pc_succ_insn or introduce a new API for it, since
we need get the successor pc in many instructions.
And the logic for gen_goto_tb or gen_set_pc_imm also need update.
Regards,
Weiwei Li
>
>
> r~
[-- Attachment #2: Type: text/html, Size: 2494 bytes --]
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v6 4/6] target/riscv: Add support for PC-relative translation
2023-04-04 14:33 ` liweiwei
@ 2023-04-04 14:57 ` Richard Henderson
2023-04-04 15:14 ` liweiwei
0 siblings, 1 reply; 26+ messages in thread
From: Richard Henderson @ 2023-04-04 14:57 UTC (permalink / raw)
To: liweiwei, qemu-riscv, qemu-devel
Cc: palmer, alistair.francis, bin.meng, dbarboza, zhiwei_liu,
wangjunqiang, lazyparser
On 4/4/23 07:33, liweiwei wrote:
> If we want to hide all of them in gen_pc_plus_diff, then we need calculate the diff for
> pc_succ_insn or introduce a new API for it, since we need get the successor pc in many
> instructions.
>
> And the logic for gen_goto_tb or gen_set_pc_imm also need update.
Yes, exactly.
r~
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v6 4/6] target/riscv: Add support for PC-relative translation
2023-04-04 14:57 ` Richard Henderson
@ 2023-04-04 15:14 ` liweiwei
2023-04-04 15:27 ` Richard Henderson
0 siblings, 1 reply; 26+ messages in thread
From: liweiwei @ 2023-04-04 15:14 UTC (permalink / raw)
To: Richard Henderson, qemu-riscv, qemu-devel
Cc: liweiwei, palmer, alistair.francis, bin.meng, dbarboza,
zhiwei_liu, wangjunqiang, lazyparser
On 2023/4/4 22:57, Richard Henderson wrote:
> On 4/4/23 07:33, liweiwei wrote:
>> If we want to hide all of them in gen_pc_plus_diff, then we need
>> calculate the diff for pc_succ_insn or introduce a new API for it,
>> since we need get the successor pc in many instructions.
>>
>> And the logic for gen_goto_tb or gen_set_pc_imm also need update.
>
> Yes, exactly.
>
>
Sorry, I didn't find benefits from this. If we do this, we'll firstly
calculate the diff = pc_succ_insn - pc_next, then we add it with pc_next
- pc_save to get the relative address to env->pc.
This seems make things more complicated.
Regards,
Weiwei Li
> r~
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v6 4/6] target/riscv: Add support for PC-relative translation
2023-04-04 15:14 ` liweiwei
@ 2023-04-04 15:27 ` Richard Henderson
2023-04-04 15:39 ` liweiwei
0 siblings, 1 reply; 26+ messages in thread
From: Richard Henderson @ 2023-04-04 15:27 UTC (permalink / raw)
To: liweiwei, qemu-riscv, qemu-devel
Cc: palmer, alistair.francis, bin.meng, dbarboza, zhiwei_liu,
wangjunqiang, lazyparser
On 4/4/23 08:14, liweiwei wrote:
>
> On 2023/4/4 22:57, Richard Henderson wrote:
>> On 4/4/23 07:33, liweiwei wrote:
>>> If we want to hide all of them in gen_pc_plus_diff, then we need calculate the diff
>>> for pc_succ_insn or introduce a new API for it, since we need get the successor pc in
>>> many instructions.
>>>
>>> And the logic for gen_goto_tb or gen_set_pc_imm also need update.
>>
>> Yes, exactly.
>>
>>
> Sorry, I didn't find benefits from this. If we do this, we'll firstly calculate the diff =
> pc_succ_insn - pc_next, then we add it with pc_next - pc_save to get the relative address
> to env->pc.
It will me simpler because you'll move all of the calculations into a helper function.
The trans_* functions will be supplying a immediate directly:
* for auipc, this is a->imm,
* for jalr, this is 0.
r~
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v6 4/6] target/riscv: Add support for PC-relative translation
2023-04-04 15:27 ` Richard Henderson
@ 2023-04-04 15:39 ` liweiwei
0 siblings, 0 replies; 26+ messages in thread
From: liweiwei @ 2023-04-04 15:39 UTC (permalink / raw)
To: Richard Henderson, qemu-riscv, qemu-devel
Cc: liweiwei, palmer, alistair.francis, bin.meng, dbarboza,
zhiwei_liu, wangjunqiang, lazyparser
On 2023/4/4 23:27, Richard Henderson wrote:
> On 4/4/23 08:14, liweiwei wrote:
>>
>> On 2023/4/4 22:57, Richard Henderson wrote:
>>> On 4/4/23 07:33, liweiwei wrote:
>>>> If we want to hide all of them in gen_pc_plus_diff, then we need
>>>> calculate the diff for pc_succ_insn or introduce a new API for it,
>>>> since we need get the successor pc in many instructions.
>>>>
>>>> And the logic for gen_goto_tb or gen_set_pc_imm also need update.
>>>
>>> Yes, exactly.
>>>
>>>
>> Sorry, I didn't find benefits from this. If we do this, we'll firstly
>> calculate the diff = pc_succ_insn - pc_next, then we add it with
>> pc_next - pc_save to get the relative address to env->pc.
>
> It will me simpler because you'll move all of the calculations into a
> helper function.
helper? Do you mean gen_pc_plus_diff?
>
> The trans_* functions will be supplying a immediate directly:
>
> * for auipc, this is a->imm,
Yeah. this will be simpler in trans_, however the total calculation is
the same. we just move a->imm + pc_next to gen_pc_plus_diff.
> * for jalr, this is 0.
Not 0, but pc_succ_insn - pc_next. This may be the case in many place.
Regards,
Weiwei Li
>
>
> r~
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v6 1/6] target/riscv: Fix pointer mask transformation for vector address
2023-04-04 2:06 ` [PATCH v6 1/6] target/riscv: Fix pointer mask transformation for vector address Weiwei Li
@ 2023-04-05 4:38 ` Alistair Francis
0 siblings, 0 replies; 26+ messages in thread
From: Alistair Francis @ 2023-04-05 4:38 UTC (permalink / raw)
To: Weiwei Li
Cc: qemu-riscv, qemu-devel, palmer, alistair.francis, bin.meng,
dbarboza, zhiwei_liu, wangjunqiang, lazyparser
On Tue, Apr 4, 2023 at 12:09 PM Weiwei Li <liweiwei@iscas.ac.cn> wrote:
>
> actual_address = (requested_address & ~mpmmask) | mpmbase.
>
> Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
> Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
> Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Alistair
> ---
> target/riscv/vector_helper.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
> index 2423affe37..a58d82af8c 100644
> --- a/target/riscv/vector_helper.c
> +++ b/target/riscv/vector_helper.c
> @@ -172,7 +172,7 @@ static inline uint32_t vext_get_total_elems(CPURISCVState *env, uint32_t desc,
>
> static inline target_ulong adjust_addr(CPURISCVState *env, target_ulong addr)
> {
> - return (addr & env->cur_pmmask) | env->cur_pmbase;
> + return (addr & ~env->cur_pmmask) | env->cur_pmbase;
> }
>
> /*
> --
> 2.25.1
>
>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v6 2/6] target/riscv: Update cur_pmmask/base when xl changes
2023-04-04 2:06 ` [PATCH v6 2/6] target/riscv: Update cur_pmmask/base when xl changes Weiwei Li
@ 2023-04-05 4:38 ` Alistair Francis
0 siblings, 0 replies; 26+ messages in thread
From: Alistair Francis @ 2023-04-05 4:38 UTC (permalink / raw)
To: Weiwei Li
Cc: qemu-riscv, qemu-devel, palmer, alistair.francis, bin.meng,
dbarboza, zhiwei_liu, wangjunqiang, lazyparser
On Tue, Apr 4, 2023 at 12:08 PM Weiwei Li <liweiwei@iscas.ac.cn> wrote:
>
> write_mstatus() can only change current xl when in debug mode.
> And we need update cur_pmmask/base in this case.
>
> Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
> Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
> Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Alistair
> ---
> target/riscv/csr.c | 9 ++++++++-
> 1 file changed, 8 insertions(+), 1 deletion(-)
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index d522efc0b6..43b9ad4500 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -1277,8 +1277,15 @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno,
> mstatus = set_field(mstatus, MSTATUS64_SXL, xl);
> }
> env->mstatus = mstatus;
> - env->xl = cpu_recompute_xl(env);
>
> + /*
> + * Except in debug mode, UXL/SXL can only be modified by higher
> + * privilege mode. So xl will not be changed in normal mode.
> + */
> + if (env->debugger) {
> + env->xl = cpu_recompute_xl(env);
> + riscv_cpu_update_mask(env);
> + }
> return RISCV_EXCP_NONE;
> }
>
> --
> 2.25.1
>
>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v6 3/6] target/riscv: Fix target address to update badaddr
2023-04-04 2:06 ` [PATCH v6 3/6] target/riscv: Fix target address to update badaddr Weiwei Li
2023-04-04 3:06 ` LIU Zhiwei
@ 2023-04-05 4:41 ` Alistair Francis
1 sibling, 0 replies; 26+ messages in thread
From: Alistair Francis @ 2023-04-05 4:41 UTC (permalink / raw)
To: Weiwei Li
Cc: qemu-riscv, qemu-devel, palmer, alistair.francis, bin.meng,
dbarboza, zhiwei_liu, wangjunqiang, lazyparser, Richard Henderson
On Tue, Apr 4, 2023 at 12:08 PM Weiwei Li <liweiwei@iscas.ac.cn> wrote:
>
> Compute the target address before storing it into badaddr
> when mis-aligned exception is triggered.
> Use a target_pc temp to store the target address to avoid
> the confusing operation that udpate target address into
> cpu_pc before misalign check, then update it into badaddr
> and restore cpu_pc to current pc if exception is triggered.
>
> 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>
Alistair
> ---
> target/riscv/insn_trans/trans_rvi.c.inc | 23 ++++++++++++++++-------
> target/riscv/translate.c | 21 ++++++++++-----------
> 2 files changed, 26 insertions(+), 18 deletions(-)
>
> diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
> index 4ad54e8a49..cc72864d32 100644
> --- a/target/riscv/insn_trans/trans_rvi.c.inc
> +++ b/target/riscv/insn_trans/trans_rvi.c.inc
> @@ -51,25 +51,30 @@ static bool trans_jal(DisasContext *ctx, arg_jal *a)
> static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
> {
> TCGLabel *misaligned = NULL;
> + TCGv target_pc = tcg_temp_new();
>
> - 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);
> + tcg_gen_addi_tl(target_pc, get_gpr(ctx, a->rs1, EXT_NONE), a->imm);
> + tcg_gen_andi_tl(target_pc, target_pc, (target_ulong)-2);
> +
> + if (get_xl(ctx) == MXL_RV32) {
> + tcg_gen_ext32s_tl(target_pc, target_pc);
> + }
>
> - gen_set_pc(ctx, cpu_pc);
> if (!has_ext(ctx, RVC)) {
> TCGv t0 = tcg_temp_new();
>
> misaligned = gen_new_label();
> - tcg_gen_andi_tl(t0, cpu_pc, 0x2);
> + tcg_gen_andi_tl(t0, target_pc, 0x2);
> tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0x0, misaligned);
> }
>
> gen_set_gpri(ctx, a->rd, ctx->pc_succ_insn);
> + tcg_gen_mov_tl(cpu_pc, target_pc);
> lookup_and_goto_ptr(ctx);
>
> if (misaligned) {
> gen_set_label(misaligned);
> - gen_exception_inst_addr_mis(ctx);
> + gen_exception_inst_addr_mis(ctx, target_pc);
> }
> ctx->base.is_jmp = DISAS_NORETURN;
>
> @@ -153,6 +158,7 @@ static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond)
> TCGLabel *l = gen_new_label();
> TCGv src1 = get_gpr(ctx, a->rs1, EXT_SIGN);
> TCGv src2 = get_gpr(ctx, a->rs2, EXT_SIGN);
> + target_ulong next_pc;
>
> if (get_xl(ctx) == MXL_RV128) {
> TCGv src1h = get_gprh(ctx, a->rs1);
> @@ -169,9 +175,12 @@ static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond)
>
> gen_set_label(l); /* branch taken */
>
> - if (!has_ext(ctx, RVC) && ((ctx->base.pc_next + a->imm) & 0x3)) {
> + next_pc = ctx->base.pc_next + a->imm;
> + if (!has_ext(ctx, RVC) && (next_pc & 0x3)) {
> /* misaligned */
> - gen_exception_inst_addr_mis(ctx);
> + TCGv target_pc = tcg_temp_new();
> + gen_pc_plus_diff(target_pc, ctx, next_pc);
> + gen_exception_inst_addr_mis(ctx, target_pc);
> } else {
> gen_goto_tb(ctx, 0, ctx->base.pc_next + a->imm);
> }
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index 0ee8ee147d..d434fedb37 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -222,21 +222,18 @@ static void decode_save_opc(DisasContext *ctx)
> ctx->insn_start = NULL;
> }
>
> -static void gen_set_pc_imm(DisasContext *ctx, target_ulong dest)
> +static void gen_pc_plus_diff(TCGv target, DisasContext *ctx,
> + target_ulong dest)
> {
> if (get_xl(ctx) == MXL_RV32) {
> dest = (int32_t)dest;
> }
> - tcg_gen_movi_tl(cpu_pc, dest);
> + tcg_gen_movi_tl(target, dest);
> }
>
> -static void gen_set_pc(DisasContext *ctx, TCGv dest)
> +static void gen_set_pc_imm(DisasContext *ctx, target_ulong dest)
> {
> - if (get_xl(ctx) == MXL_RV32) {
> - tcg_gen_ext32s_tl(cpu_pc, dest);
> - } else {
> - tcg_gen_mov_tl(cpu_pc, dest);
> - }
> + gen_pc_plus_diff(cpu_pc, ctx, dest);
> }
>
> static void generate_exception(DisasContext *ctx, int excp)
> @@ -257,9 +254,9 @@ static void gen_exception_illegal(DisasContext *ctx)
> }
> }
>
> -static void gen_exception_inst_addr_mis(DisasContext *ctx)
> +static void gen_exception_inst_addr_mis(DisasContext *ctx, TCGv target)
> {
> - tcg_gen_st_tl(cpu_pc, cpu_env, offsetof(CPURISCVState, badaddr));
> + tcg_gen_st_tl(target, cpu_env, offsetof(CPURISCVState, badaddr));
> generate_exception(ctx, RISCV_EXCP_INST_ADDR_MIS);
> }
>
> @@ -551,7 +548,9 @@ static void gen_jal(DisasContext *ctx, int rd, target_ulong imm)
> next_pc = ctx->base.pc_next + imm;
> if (!has_ext(ctx, RVC)) {
> if ((next_pc & 0x3) != 0) {
> - gen_exception_inst_addr_mis(ctx);
> + TCGv target_pc = tcg_temp_new();
> + gen_pc_plus_diff(target_pc, ctx, next_pc);
> + gen_exception_inst_addr_mis(ctx, target_pc);
> return;
> }
> }
> --
> 2.25.1
>
>
^ permalink raw reply [flat|nested] 26+ messages in thread
end of thread, other threads:[~2023-04-05 4:42 UTC | newest]
Thread overview: 26+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-04-04 2:06 [PATCH v6 0/6] target/riscv: Fix pointer mask related support Weiwei Li
2023-04-04 2:06 ` [PATCH v6 1/6] target/riscv: Fix pointer mask transformation for vector address Weiwei Li
2023-04-05 4:38 ` Alistair Francis
2023-04-04 2:06 ` [PATCH v6 2/6] target/riscv: Update cur_pmmask/base when xl changes Weiwei Li
2023-04-05 4:38 ` Alistair Francis
2023-04-04 2:06 ` [PATCH v6 3/6] target/riscv: Fix target address to update badaddr Weiwei Li
2023-04-04 3:06 ` LIU Zhiwei
2023-04-04 3:37 ` liweiwei
2023-04-05 4:41 ` Alistair Francis
2023-04-04 2:06 ` [PATCH v6 4/6] target/riscv: Add support for PC-relative translation Weiwei Li
2023-04-04 3:12 ` LIU Zhiwei
2023-04-04 3:25 ` LIU Zhiwei
2023-04-04 3:46 ` liweiwei
2023-04-04 7:07 ` LIU Zhiwei
2023-04-04 8:48 ` liweiwei
2023-04-04 9:23 ` LIU Zhiwei
2023-04-04 14:05 ` Richard Henderson
2023-04-04 13:56 ` Richard Henderson
2023-04-04 14:33 ` liweiwei
2023-04-04 14:57 ` Richard Henderson
2023-04-04 15:14 ` liweiwei
2023-04-04 15:27 ` Richard Henderson
2023-04-04 15:39 ` liweiwei
2023-04-04 2:06 ` [PATCH v6 5/6] target/riscv: Enable PC-relative translation in system mode Weiwei Li
2023-04-04 2:06 ` [PATCH v6 6/6] target/riscv: Add pointer mask support for instruction fetch Weiwei Li
2023-04-04 2:52 ` LIU Zhiwei
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).