All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v6 00/22] Support UXL filed in xstatus
@ 2022-01-13 11:39 ` LIU Zhiwei
  0 siblings, 0 replies; 60+ messages in thread
From: LIU Zhiwei @ 2022-01-13 11:39 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: guoren, bin.meng, richard.henderson, palmer, Alistair.Francis,
	LIU Zhiwei

In this patch set, we process the pc reigsters writes,
gdb reads and writes, and address calculation under
different UXLEN settings.

The patch set v6 has been tested by running rv64 Linux with 
rv32 rootfs in compat mode. You can almost follow the test [1]
given by GuoRen, except using the branch riscv-upstream-uxl-v6
on my QEMU repo [2].

[1] https://lore.kernel.org/linux-arm-kernel/20211228143958.3409187-17-guoren@kernel.org/t/
[2] https://github.com/romanheros/qemu.git 

Patch 3, 5, 20, 22, have not been reviewed. Others have been reviewed or acked.

v6:
  Pass boot 32bit rootfs on compat Linux
  Pass test cases on compat OpenTee
  Fix csr write mask 
  Fix WARL for uxl
  Fix sstatus read for uxl
  Relax UXL field for debugging
  Don't bump machine state version for xl
  Rename cpu_get_xl to cpu_recompute_xl
  Rebase to vector v1.0
  Rebase to 128 bit cpu

v5:
  Add xl field in env to clear up redundant riscv_cpu_xl
  Adjust pmpcfg access with mxl
  Select gdb core xml according to mxl 

v4:
  Support SSTATUS64_UXL write
  Bump vmstate version for vill split

v3:
  Merge gen_pm_adjust_address into a canonical address function
  Adjust address for RVA with XLEN
  Split pm_enabled into pm_mask_enabled and pm_base_enabled
  Replace array of pm tcg globals with one scalar tcg global
  Split and change patch sequence

v2:
  Split out vill from vtype
  Remove context switch when xlen changes at exception
  Use XL instead of OL in many places
  Use pointer masking and XLEN for vector address
  Define an common fuction to calculate address for ld


LIU Zhiwei (22):
  target/riscv: Adjust pmpcfg access with mxl
  target/riscv: Don't save pc when exception return
  target/riscv: Sign extend link reg for jal and jalr
  target/riscv: Sign extend pc for different XLEN
  target/riscv: Create xl field in env
  target/riscv: Ignore the pc bits above XLEN
  target/riscv: Extend pc for runtime pc write
  target/riscv: Use gdb xml according to max mxlen
  target/riscv: Relax debug check for pm write
  target/riscv: Adjust csr write mask with XLEN
  target/riscv: Create current pm fields in env
  target/riscv: Alloc tcg global for cur_pm[mask|base]
  target/riscv: Calculate address according to XLEN
  target/riscv: Split pm_enabled into mask and base
  target/riscv: Split out the vill from vtype
  target/riscv: Adjust vsetvl according to XLEN
  target/riscv: Remove VILL field in VTYPE
  target/riscv: Fix check range for first fault only
  target/riscv: Adjust vector address with mask
  target/riscv: Adjust scalar reg in vector with XLEN
  target/riscv: Enable uxl field write
  target/riscv: Relax UXL field for debugging

 target/riscv/cpu.c                            | 32 +++++--
 target/riscv/cpu.h                            | 45 ++++++++-
 target/riscv/cpu_helper.c                     | 94 +++++++++----------
 target/riscv/csr.c                            | 74 +++++++++++++--
 target/riscv/gdbstub.c                        | 71 ++++++++++----
 target/riscv/helper.h                         |  4 +-
 .../riscv/insn_trans/trans_privileged.c.inc   |  9 +-
 target/riscv/insn_trans/trans_rva.c.inc       |  9 +-
 target/riscv/insn_trans/trans_rvd.c.inc       | 19 +---
 target/riscv/insn_trans/trans_rvf.c.inc       | 19 +---
 target/riscv/insn_trans/trans_rvi.c.inc       | 39 +++-----
 target/riscv/insn_trans/trans_rvv.c.inc       |  6 +-
 target/riscv/machine.c                        | 16 +++-
 target/riscv/op_helper.c                      |  7 +-
 target/riscv/pmp.c                            | 12 +--
 target/riscv/translate.c                      | 90 +++++++++---------
 target/riscv/vector_helper.c                  | 39 +++++---
 17 files changed, 355 insertions(+), 230 deletions(-)

-- 
2.25.1



^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v6 00/22] Support UXL filed in xstatus
@ 2022-01-13 11:39 ` LIU Zhiwei
  0 siblings, 0 replies; 60+ messages in thread
From: LIU Zhiwei @ 2022-01-13 11:39 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: Alistair.Francis, palmer, bin.meng, richard.henderson, guoren,
	LIU Zhiwei

In this patch set, we process the pc reigsters writes,
gdb reads and writes, and address calculation under
different UXLEN settings.

The patch set v6 has been tested by running rv64 Linux with 
rv32 rootfs in compat mode. You can almost follow the test [1]
given by GuoRen, except using the branch riscv-upstream-uxl-v6
on my QEMU repo [2].

[1] https://lore.kernel.org/linux-arm-kernel/20211228143958.3409187-17-guoren@kernel.org/t/
[2] https://github.com/romanheros/qemu.git 

Patch 3, 5, 20, 22, have not been reviewed. Others have been reviewed or acked.

v6:
  Pass boot 32bit rootfs on compat Linux
  Pass test cases on compat OpenTee
  Fix csr write mask 
  Fix WARL for uxl
  Fix sstatus read for uxl
  Relax UXL field for debugging
  Don't bump machine state version for xl
  Rename cpu_get_xl to cpu_recompute_xl
  Rebase to vector v1.0
  Rebase to 128 bit cpu

v5:
  Add xl field in env to clear up redundant riscv_cpu_xl
  Adjust pmpcfg access with mxl
  Select gdb core xml according to mxl 

v4:
  Support SSTATUS64_UXL write
  Bump vmstate version for vill split

v3:
  Merge gen_pm_adjust_address into a canonical address function
  Adjust address for RVA with XLEN
  Split pm_enabled into pm_mask_enabled and pm_base_enabled
  Replace array of pm tcg globals with one scalar tcg global
  Split and change patch sequence

v2:
  Split out vill from vtype
  Remove context switch when xlen changes at exception
  Use XL instead of OL in many places
  Use pointer masking and XLEN for vector address
  Define an common fuction to calculate address for ld


LIU Zhiwei (22):
  target/riscv: Adjust pmpcfg access with mxl
  target/riscv: Don't save pc when exception return
  target/riscv: Sign extend link reg for jal and jalr
  target/riscv: Sign extend pc for different XLEN
  target/riscv: Create xl field in env
  target/riscv: Ignore the pc bits above XLEN
  target/riscv: Extend pc for runtime pc write
  target/riscv: Use gdb xml according to max mxlen
  target/riscv: Relax debug check for pm write
  target/riscv: Adjust csr write mask with XLEN
  target/riscv: Create current pm fields in env
  target/riscv: Alloc tcg global for cur_pm[mask|base]
  target/riscv: Calculate address according to XLEN
  target/riscv: Split pm_enabled into mask and base
  target/riscv: Split out the vill from vtype
  target/riscv: Adjust vsetvl according to XLEN
  target/riscv: Remove VILL field in VTYPE
  target/riscv: Fix check range for first fault only
  target/riscv: Adjust vector address with mask
  target/riscv: Adjust scalar reg in vector with XLEN
  target/riscv: Enable uxl field write
  target/riscv: Relax UXL field for debugging

 target/riscv/cpu.c                            | 32 +++++--
 target/riscv/cpu.h                            | 45 ++++++++-
 target/riscv/cpu_helper.c                     | 94 +++++++++----------
 target/riscv/csr.c                            | 74 +++++++++++++--
 target/riscv/gdbstub.c                        | 71 ++++++++++----
 target/riscv/helper.h                         |  4 +-
 .../riscv/insn_trans/trans_privileged.c.inc   |  9 +-
 target/riscv/insn_trans/trans_rva.c.inc       |  9 +-
 target/riscv/insn_trans/trans_rvd.c.inc       | 19 +---
 target/riscv/insn_trans/trans_rvf.c.inc       | 19 +---
 target/riscv/insn_trans/trans_rvi.c.inc       | 39 +++-----
 target/riscv/insn_trans/trans_rvv.c.inc       |  6 +-
 target/riscv/machine.c                        | 16 +++-
 target/riscv/op_helper.c                      |  7 +-
 target/riscv/pmp.c                            | 12 +--
 target/riscv/translate.c                      | 90 +++++++++---------
 target/riscv/vector_helper.c                  | 39 +++++---
 17 files changed, 355 insertions(+), 230 deletions(-)

-- 
2.25.1



^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH v6 01/22] target/riscv: Adjust pmpcfg access with mxl
  2022-01-13 11:39 ` LIU Zhiwei
@ 2022-01-13 11:39   ` LIU Zhiwei
  -1 siblings, 0 replies; 60+ messages in thread
From: LIU Zhiwei @ 2022-01-13 11:39 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: guoren, bin.meng, richard.henderson, palmer, Alistair.Francis,
	LIU Zhiwei

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/riscv/csr.c | 19 +++++++++++++++++++
 target/riscv/pmp.c | 12 ++++--------
 2 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index adb3d4381d..e7578f3e0f 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1493,9 +1493,23 @@ static RISCVException write_mseccfg(CPURISCVState *env, int csrno,
     return RISCV_EXCP_NONE;
 }
 
+static bool check_pmp_reg_index(CPURISCVState *env, uint32_t reg_index)
+{
+    /* TODO: RV128 restriction check */
+    if ((reg_index & 1) && (riscv_cpu_mxl(env) == MXL_RV64)) {
+        return false;
+    }
+    return true;
+}
+
 static RISCVException read_pmpcfg(CPURISCVState *env, int csrno,
                                   target_ulong *val)
 {
+    uint32_t reg_index = csrno - CSR_PMPCFG0;
+
+    if (!check_pmp_reg_index(env, reg_index)) {
+        return RISCV_EXCP_ILLEGAL_INST;
+    }
     *val = pmpcfg_csr_read(env, csrno - CSR_PMPCFG0);
     return RISCV_EXCP_NONE;
 }
@@ -1503,6 +1517,11 @@ static RISCVException read_pmpcfg(CPURISCVState *env, int csrno,
 static RISCVException write_pmpcfg(CPURISCVState *env, int csrno,
                                    target_ulong val)
 {
+    uint32_t reg_index = csrno - CSR_PMPCFG0;
+
+    if (!check_pmp_reg_index(env, reg_index)) {
+        return RISCV_EXCP_ILLEGAL_INST;
+    }
     pmpcfg_csr_write(env, csrno - CSR_PMPCFG0, val);
     return RISCV_EXCP_NONE;
 }
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
index 54abf42583..81b61bb65c 100644
--- a/target/riscv/pmp.c
+++ b/target/riscv/pmp.c
@@ -463,16 +463,11 @@ void pmpcfg_csr_write(CPURISCVState *env, uint32_t reg_index,
 {
     int i;
     uint8_t cfg_val;
+    int pmpcfg_nums = 2 << riscv_cpu_mxl(env);
 
     trace_pmpcfg_csr_write(env->mhartid, reg_index, val);
 
-    if ((reg_index & 1) && (sizeof(target_ulong) == 8)) {
-        qemu_log_mask(LOG_GUEST_ERROR,
-                      "ignoring pmpcfg write - incorrect address\n");
-        return;
-    }
-
-    for (i = 0; i < sizeof(target_ulong); i++) {
+    for (i = 0; i < pmpcfg_nums; i++) {
         cfg_val = (val >> 8 * i)  & 0xff;
         pmp_write_cfg(env, (reg_index * 4) + i, cfg_val);
     }
@@ -490,8 +485,9 @@ target_ulong pmpcfg_csr_read(CPURISCVState *env, uint32_t reg_index)
     int i;
     target_ulong cfg_val = 0;
     target_ulong val = 0;
+    int pmpcfg_nums = 2 << riscv_cpu_mxl(env);
 
-    for (i = 0; i < sizeof(target_ulong); i++) {
+    for (i = 0; i < pmpcfg_nums; i++) {
         val = pmp_read_cfg(env, (reg_index * 4) + i);
         cfg_val |= (val << (i * 8));
     }
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v6 01/22] target/riscv: Adjust pmpcfg access with mxl
@ 2022-01-13 11:39   ` LIU Zhiwei
  0 siblings, 0 replies; 60+ messages in thread
From: LIU Zhiwei @ 2022-01-13 11:39 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: Alistair.Francis, palmer, bin.meng, richard.henderson, guoren,
	LIU Zhiwei

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/riscv/csr.c | 19 +++++++++++++++++++
 target/riscv/pmp.c | 12 ++++--------
 2 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index adb3d4381d..e7578f3e0f 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1493,9 +1493,23 @@ static RISCVException write_mseccfg(CPURISCVState *env, int csrno,
     return RISCV_EXCP_NONE;
 }
 
+static bool check_pmp_reg_index(CPURISCVState *env, uint32_t reg_index)
+{
+    /* TODO: RV128 restriction check */
+    if ((reg_index & 1) && (riscv_cpu_mxl(env) == MXL_RV64)) {
+        return false;
+    }
+    return true;
+}
+
 static RISCVException read_pmpcfg(CPURISCVState *env, int csrno,
                                   target_ulong *val)
 {
+    uint32_t reg_index = csrno - CSR_PMPCFG0;
+
+    if (!check_pmp_reg_index(env, reg_index)) {
+        return RISCV_EXCP_ILLEGAL_INST;
+    }
     *val = pmpcfg_csr_read(env, csrno - CSR_PMPCFG0);
     return RISCV_EXCP_NONE;
 }
@@ -1503,6 +1517,11 @@ static RISCVException read_pmpcfg(CPURISCVState *env, int csrno,
 static RISCVException write_pmpcfg(CPURISCVState *env, int csrno,
                                    target_ulong val)
 {
+    uint32_t reg_index = csrno - CSR_PMPCFG0;
+
+    if (!check_pmp_reg_index(env, reg_index)) {
+        return RISCV_EXCP_ILLEGAL_INST;
+    }
     pmpcfg_csr_write(env, csrno - CSR_PMPCFG0, val);
     return RISCV_EXCP_NONE;
 }
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
index 54abf42583..81b61bb65c 100644
--- a/target/riscv/pmp.c
+++ b/target/riscv/pmp.c
@@ -463,16 +463,11 @@ void pmpcfg_csr_write(CPURISCVState *env, uint32_t reg_index,
 {
     int i;
     uint8_t cfg_val;
+    int pmpcfg_nums = 2 << riscv_cpu_mxl(env);
 
     trace_pmpcfg_csr_write(env->mhartid, reg_index, val);
 
-    if ((reg_index & 1) && (sizeof(target_ulong) == 8)) {
-        qemu_log_mask(LOG_GUEST_ERROR,
-                      "ignoring pmpcfg write - incorrect address\n");
-        return;
-    }
-
-    for (i = 0; i < sizeof(target_ulong); i++) {
+    for (i = 0; i < pmpcfg_nums; i++) {
         cfg_val = (val >> 8 * i)  & 0xff;
         pmp_write_cfg(env, (reg_index * 4) + i, cfg_val);
     }
@@ -490,8 +485,9 @@ target_ulong pmpcfg_csr_read(CPURISCVState *env, uint32_t reg_index)
     int i;
     target_ulong cfg_val = 0;
     target_ulong val = 0;
+    int pmpcfg_nums = 2 << riscv_cpu_mxl(env);
 
-    for (i = 0; i < sizeof(target_ulong); i++) {
+    for (i = 0; i < pmpcfg_nums; i++) {
         val = pmp_read_cfg(env, (reg_index * 4) + i);
         cfg_val |= (val << (i * 8));
     }
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v6 02/22] target/riscv: Don't save pc when exception return
  2022-01-13 11:39 ` LIU Zhiwei
@ 2022-01-13 11:39   ` LIU Zhiwei
  -1 siblings, 0 replies; 60+ messages in thread
From: LIU Zhiwei @ 2022-01-13 11:39 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: guoren, bin.meng, richard.henderson, palmer, Alistair Francis,
	LIU Zhiwei

As pc will be written by the xepc in exception return, just ignore
pc in translation.

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
 target/riscv/helper.h                          | 4 ++--
 target/riscv/insn_trans/trans_privileged.c.inc | 7 ++-----
 target/riscv/op_helper.c                       | 4 ++--
 3 files changed, 6 insertions(+), 9 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 6cf6d6ce98..72cc2582f4 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -100,8 +100,8 @@ DEF_HELPER_2(csrr_i128, tl, env, int)
 DEF_HELPER_4(csrw_i128, void, env, int, tl, tl)
 DEF_HELPER_6(csrrw_i128, tl, env, int, tl, tl, tl, tl)
 #ifndef CONFIG_USER_ONLY
-DEF_HELPER_2(sret, tl, env, tl)
-DEF_HELPER_2(mret, tl, env, tl)
+DEF_HELPER_1(sret, tl, env)
+DEF_HELPER_1(mret, tl, env)
 DEF_HELPER_1(wfi, void, env)
 DEF_HELPER_1(tlb_flush, void, env)
 #endif
diff --git a/target/riscv/insn_trans/trans_privileged.c.inc b/target/riscv/insn_trans/trans_privileged.c.inc
index 75c6ef80a6..6077bbbf11 100644
--- a/target/riscv/insn_trans/trans_privileged.c.inc
+++ b/target/riscv/insn_trans/trans_privileged.c.inc
@@ -74,10 +74,8 @@ static bool trans_uret(DisasContext *ctx, arg_uret *a)
 static bool trans_sret(DisasContext *ctx, arg_sret *a)
 {
 #ifndef CONFIG_USER_ONLY
-    tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
-
     if (has_ext(ctx, RVS)) {
-        gen_helper_sret(cpu_pc, cpu_env, cpu_pc);
+        gen_helper_sret(cpu_pc, cpu_env);
         tcg_gen_exit_tb(NULL, 0); /* no chaining */
         ctx->base.is_jmp = DISAS_NORETURN;
     } else {
@@ -92,8 +90,7 @@ static bool trans_sret(DisasContext *ctx, arg_sret *a)
 static bool trans_mret(DisasContext *ctx, arg_mret *a)
 {
 #ifndef CONFIG_USER_ONLY
-    tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
-    gen_helper_mret(cpu_pc, cpu_env, cpu_pc);
+    gen_helper_mret(cpu_pc, cpu_env);
     tcg_gen_exit_tb(NULL, 0); /* no chaining */
     ctx->base.is_jmp = DISAS_NORETURN;
     return true;
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index 6f040f2fb9..67693cb42b 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -115,7 +115,7 @@ target_ulong helper_csrrw_i128(CPURISCVState *env, int csr,
 
 #ifndef CONFIG_USER_ONLY
 
-target_ulong helper_sret(CPURISCVState *env, target_ulong cpu_pc_deb)
+target_ulong helper_sret(CPURISCVState *env)
 {
     uint64_t mstatus;
     target_ulong prev_priv, prev_virt;
@@ -176,7 +176,7 @@ target_ulong helper_sret(CPURISCVState *env, target_ulong cpu_pc_deb)
     return retpc;
 }
 
-target_ulong helper_mret(CPURISCVState *env, target_ulong cpu_pc_deb)
+target_ulong helper_mret(CPURISCVState *env)
 {
     if (!(env->priv >= PRV_M)) {
         riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v6 02/22] target/riscv: Don't save pc when exception return
@ 2022-01-13 11:39   ` LIU Zhiwei
  0 siblings, 0 replies; 60+ messages in thread
From: LIU Zhiwei @ 2022-01-13 11:39 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: Alistair.Francis, palmer, bin.meng, richard.henderson, guoren,
	LIU Zhiwei, Alistair Francis

As pc will be written by the xepc in exception return, just ignore
pc in translation.

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
 target/riscv/helper.h                          | 4 ++--
 target/riscv/insn_trans/trans_privileged.c.inc | 7 ++-----
 target/riscv/op_helper.c                       | 4 ++--
 3 files changed, 6 insertions(+), 9 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 6cf6d6ce98..72cc2582f4 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -100,8 +100,8 @@ DEF_HELPER_2(csrr_i128, tl, env, int)
 DEF_HELPER_4(csrw_i128, void, env, int, tl, tl)
 DEF_HELPER_6(csrrw_i128, tl, env, int, tl, tl, tl, tl)
 #ifndef CONFIG_USER_ONLY
-DEF_HELPER_2(sret, tl, env, tl)
-DEF_HELPER_2(mret, tl, env, tl)
+DEF_HELPER_1(sret, tl, env)
+DEF_HELPER_1(mret, tl, env)
 DEF_HELPER_1(wfi, void, env)
 DEF_HELPER_1(tlb_flush, void, env)
 #endif
diff --git a/target/riscv/insn_trans/trans_privileged.c.inc b/target/riscv/insn_trans/trans_privileged.c.inc
index 75c6ef80a6..6077bbbf11 100644
--- a/target/riscv/insn_trans/trans_privileged.c.inc
+++ b/target/riscv/insn_trans/trans_privileged.c.inc
@@ -74,10 +74,8 @@ static bool trans_uret(DisasContext *ctx, arg_uret *a)
 static bool trans_sret(DisasContext *ctx, arg_sret *a)
 {
 #ifndef CONFIG_USER_ONLY
-    tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
-
     if (has_ext(ctx, RVS)) {
-        gen_helper_sret(cpu_pc, cpu_env, cpu_pc);
+        gen_helper_sret(cpu_pc, cpu_env);
         tcg_gen_exit_tb(NULL, 0); /* no chaining */
         ctx->base.is_jmp = DISAS_NORETURN;
     } else {
@@ -92,8 +90,7 @@ static bool trans_sret(DisasContext *ctx, arg_sret *a)
 static bool trans_mret(DisasContext *ctx, arg_mret *a)
 {
 #ifndef CONFIG_USER_ONLY
-    tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
-    gen_helper_mret(cpu_pc, cpu_env, cpu_pc);
+    gen_helper_mret(cpu_pc, cpu_env);
     tcg_gen_exit_tb(NULL, 0); /* no chaining */
     ctx->base.is_jmp = DISAS_NORETURN;
     return true;
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index 6f040f2fb9..67693cb42b 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -115,7 +115,7 @@ target_ulong helper_csrrw_i128(CPURISCVState *env, int csr,
 
 #ifndef CONFIG_USER_ONLY
 
-target_ulong helper_sret(CPURISCVState *env, target_ulong cpu_pc_deb)
+target_ulong helper_sret(CPURISCVState *env)
 {
     uint64_t mstatus;
     target_ulong prev_priv, prev_virt;
@@ -176,7 +176,7 @@ target_ulong helper_sret(CPURISCVState *env, target_ulong cpu_pc_deb)
     return retpc;
 }
 
-target_ulong helper_mret(CPURISCVState *env, target_ulong cpu_pc_deb)
+target_ulong helper_mret(CPURISCVState *env)
 {
     if (!(env->priv >= PRV_M)) {
         riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v6 03/22] target/riscv: Sign extend link reg for jal and jalr
  2022-01-13 11:39 ` LIU Zhiwei
@ 2022-01-13 11:39   ` LIU Zhiwei
  -1 siblings, 0 replies; 60+ messages in thread
From: LIU Zhiwei @ 2022-01-13 11:39 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: guoren, bin.meng, richard.henderson, palmer, Alistair.Francis,
	LIU Zhiwei

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
---
 target/riscv/insn_trans/trans_rvi.c.inc | 4 +---
 target/riscv/translate.c                | 4 +---
 2 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
index 3a0ae28fef..b9ba57f266 100644
--- a/target/riscv/insn_trans/trans_rvi.c.inc
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
@@ -68,9 +68,7 @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
         tcg_temp_free(t0);
     }
 
-    if (a->rd != 0) {
-        tcg_gen_movi_tl(cpu_gpr[a->rd], ctx->pc_succ_insn);
-    }
+    gen_set_gpri(ctx, a->rd, ctx->pc_succ_insn);
     tcg_gen_lookup_and_goto_ptr();
 
     if (misaligned) {
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 615048ec87..b47b308920 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -367,10 +367,8 @@ static void gen_jal(DisasContext *ctx, int rd, target_ulong imm)
             return;
         }
     }
-    if (rd != 0) {
-        tcg_gen_movi_tl(cpu_gpr[rd], ctx->pc_succ_insn);
-    }
 
+    gen_set_gpri(ctx, rd, ctx->pc_succ_insn);
     gen_goto_tb(ctx, 0, ctx->base.pc_next + imm); /* must use this for safety */
     ctx->base.is_jmp = DISAS_NORETURN;
 }
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v6 03/22] target/riscv: Sign extend link reg for jal and jalr
@ 2022-01-13 11:39   ` LIU Zhiwei
  0 siblings, 0 replies; 60+ messages in thread
From: LIU Zhiwei @ 2022-01-13 11:39 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: Alistair.Francis, palmer, bin.meng, richard.henderson, guoren,
	LIU Zhiwei

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
---
 target/riscv/insn_trans/trans_rvi.c.inc | 4 +---
 target/riscv/translate.c                | 4 +---
 2 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
index 3a0ae28fef..b9ba57f266 100644
--- a/target/riscv/insn_trans/trans_rvi.c.inc
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
@@ -68,9 +68,7 @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
         tcg_temp_free(t0);
     }
 
-    if (a->rd != 0) {
-        tcg_gen_movi_tl(cpu_gpr[a->rd], ctx->pc_succ_insn);
-    }
+    gen_set_gpri(ctx, a->rd, ctx->pc_succ_insn);
     tcg_gen_lookup_and_goto_ptr();
 
     if (misaligned) {
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 615048ec87..b47b308920 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -367,10 +367,8 @@ static void gen_jal(DisasContext *ctx, int rd, target_ulong imm)
             return;
         }
     }
-    if (rd != 0) {
-        tcg_gen_movi_tl(cpu_gpr[rd], ctx->pc_succ_insn);
-    }
 
+    gen_set_gpri(ctx, rd, ctx->pc_succ_insn);
     gen_goto_tb(ctx, 0, ctx->base.pc_next + imm); /* must use this for safety */
     ctx->base.is_jmp = DISAS_NORETURN;
 }
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v6 04/22] target/riscv: Sign extend pc for different XLEN
  2022-01-13 11:39 ` LIU Zhiwei
@ 2022-01-13 11:39   ` LIU Zhiwei
  -1 siblings, 0 replies; 60+ messages in thread
From: LIU Zhiwei @ 2022-01-13 11:39 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: guoren, bin.meng, richard.henderson, palmer, Alistair Francis,
	LIU Zhiwei

When pc is written, it is sign-extended to fill the widest supported XLEN.

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
 .../riscv/insn_trans/trans_privileged.c.inc   |  2 +-
 target/riscv/insn_trans/trans_rvi.c.inc       |  5 ++--
 target/riscv/insn_trans/trans_rvv.c.inc       |  4 +--
 target/riscv/translate.c                      | 25 ++++++++++++++++---
 4 files changed, 27 insertions(+), 9 deletions(-)

diff --git a/target/riscv/insn_trans/trans_privileged.c.inc b/target/riscv/insn_trans/trans_privileged.c.inc
index 6077bbbf11..53613682e8 100644
--- a/target/riscv/insn_trans/trans_privileged.c.inc
+++ b/target/riscv/insn_trans/trans_privileged.c.inc
@@ -102,7 +102,7 @@ static bool trans_mret(DisasContext *ctx, arg_mret *a)
 static bool trans_wfi(DisasContext *ctx, arg_wfi *a)
 {
 #ifndef CONFIG_USER_ONLY
-    tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
+    gen_set_pc_imm(ctx, ctx->pc_succ_insn);
     gen_helper_wfi(cpu_env);
     return true;
 #else
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
index b9ba57f266..04d3ea237f 100644
--- a/target/riscv/insn_trans/trans_rvi.c.inc
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
@@ -59,6 +59,7 @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
     tcg_gen_addi_tl(cpu_pc, get_gpr(ctx, a->rs1, EXT_NONE), a->imm);
     tcg_gen_andi_tl(cpu_pc, cpu_pc, (target_ulong)-2);
 
+    gen_set_pc(ctx, cpu_pc);
     if (!has_ext(ctx, RVC)) {
         TCGv t0 = tcg_temp_new();
 
@@ -827,7 +828,7 @@ static bool trans_fence_i(DisasContext *ctx, arg_fence_i *a)
      * FENCE_I is a no-op in QEMU,
      * however we need to end the translation block
      */
-    tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
+    gen_set_pc_imm(ctx, ctx->pc_succ_insn);
     tcg_gen_exit_tb(NULL, 0);
     ctx->base.is_jmp = DISAS_NORETURN;
     return true;
@@ -836,7 +837,7 @@ static bool trans_fence_i(DisasContext *ctx, arg_fence_i *a)
 static bool do_csr_post(DisasContext *ctx)
 {
     /* We may have changed important cpu state -- exit to main loop. */
-    tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
+    gen_set_pc_imm(ctx, ctx->pc_succ_insn);
     tcg_gen_exit_tb(NULL, 0);
     ctx->base.is_jmp = DISAS_NORETURN;
     return true;
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
index 6c285c958b..1c8086d3a6 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -149,7 +149,7 @@ static bool do_vsetvl(DisasContext *s, int rd, int rs1, TCGv s2)
     gen_set_gpr(s, rd, dst);
     mark_vs_dirty(s);
 
-    tcg_gen_movi_tl(cpu_pc, s->pc_succ_insn);
+    gen_set_pc_imm(s, s->pc_succ_insn);
     tcg_gen_lookup_and_goto_ptr();
     s->base.is_jmp = DISAS_NORETURN;
 
@@ -173,7 +173,7 @@ static bool do_vsetivli(DisasContext *s, int rd, TCGv s1, TCGv s2)
     gen_helper_vsetvl(dst, cpu_env, s1, s2);
     gen_set_gpr(s, rd, dst);
     mark_vs_dirty(s);
-    tcg_gen_movi_tl(cpu_pc, s->pc_succ_insn);
+    gen_set_pc_imm(s, s->pc_succ_insn);
     tcg_gen_lookup_and_goto_ptr();
     s->base.is_jmp = DISAS_NORETURN;
 
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index b47b308920..d8b7c48600 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -191,16 +191,33 @@ static void gen_check_nanbox_s(TCGv_i64 out, TCGv_i64 in)
     tcg_gen_movcond_i64(TCG_COND_GEU, out, in, t_max, in, t_nan);
 }
 
+static void gen_set_pc_imm(DisasContext *ctx, target_ulong dest)
+{
+    if (get_xl(ctx) == MXL_RV32) {
+        dest = (int32_t)dest;
+    }
+    tcg_gen_movi_tl(cpu_pc, dest);
+}
+
+static void gen_set_pc(DisasContext *ctx, TCGv dest)
+{
+    if (get_xl(ctx) == MXL_RV32) {
+        tcg_gen_ext32s_tl(cpu_pc, dest);
+    } else {
+        tcg_gen_mov_tl(cpu_pc, dest);
+    }
+}
+
 static void generate_exception(DisasContext *ctx, int excp)
 {
-    tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
+    gen_set_pc_imm(ctx, ctx->base.pc_next);
     gen_helper_raise_exception(cpu_env, tcg_constant_i32(excp));
     ctx->base.is_jmp = DISAS_NORETURN;
 }
 
 static void generate_exception_mtval(DisasContext *ctx, int excp)
 {
-    tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
+    gen_set_pc_imm(ctx, ctx->base.pc_next);
     tcg_gen_st_tl(cpu_pc, cpu_env, offsetof(CPURISCVState, badaddr));
     gen_helper_raise_exception(cpu_env, tcg_constant_i32(excp));
     ctx->base.is_jmp = DISAS_NORETURN;
@@ -223,10 +240,10 @@ static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
 {
     if (translator_use_goto_tb(&ctx->base, dest)) {
         tcg_gen_goto_tb(n);
-        tcg_gen_movi_tl(cpu_pc, dest);
+        gen_set_pc_imm(ctx, dest);
         tcg_gen_exit_tb(ctx->base.tb, n);
     } else {
-        tcg_gen_movi_tl(cpu_pc, dest);
+        gen_set_pc_imm(ctx, dest);
         tcg_gen_lookup_and_goto_ptr();
     }
 }
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v6 04/22] target/riscv: Sign extend pc for different XLEN
@ 2022-01-13 11:39   ` LIU Zhiwei
  0 siblings, 0 replies; 60+ messages in thread
From: LIU Zhiwei @ 2022-01-13 11:39 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: Alistair.Francis, palmer, bin.meng, richard.henderson, guoren,
	LIU Zhiwei, Alistair Francis

When pc is written, it is sign-extended to fill the widest supported XLEN.

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
 .../riscv/insn_trans/trans_privileged.c.inc   |  2 +-
 target/riscv/insn_trans/trans_rvi.c.inc       |  5 ++--
 target/riscv/insn_trans/trans_rvv.c.inc       |  4 +--
 target/riscv/translate.c                      | 25 ++++++++++++++++---
 4 files changed, 27 insertions(+), 9 deletions(-)

diff --git a/target/riscv/insn_trans/trans_privileged.c.inc b/target/riscv/insn_trans/trans_privileged.c.inc
index 6077bbbf11..53613682e8 100644
--- a/target/riscv/insn_trans/trans_privileged.c.inc
+++ b/target/riscv/insn_trans/trans_privileged.c.inc
@@ -102,7 +102,7 @@ static bool trans_mret(DisasContext *ctx, arg_mret *a)
 static bool trans_wfi(DisasContext *ctx, arg_wfi *a)
 {
 #ifndef CONFIG_USER_ONLY
-    tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
+    gen_set_pc_imm(ctx, ctx->pc_succ_insn);
     gen_helper_wfi(cpu_env);
     return true;
 #else
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
index b9ba57f266..04d3ea237f 100644
--- a/target/riscv/insn_trans/trans_rvi.c.inc
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
@@ -59,6 +59,7 @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
     tcg_gen_addi_tl(cpu_pc, get_gpr(ctx, a->rs1, EXT_NONE), a->imm);
     tcg_gen_andi_tl(cpu_pc, cpu_pc, (target_ulong)-2);
 
+    gen_set_pc(ctx, cpu_pc);
     if (!has_ext(ctx, RVC)) {
         TCGv t0 = tcg_temp_new();
 
@@ -827,7 +828,7 @@ static bool trans_fence_i(DisasContext *ctx, arg_fence_i *a)
      * FENCE_I is a no-op in QEMU,
      * however we need to end the translation block
      */
-    tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
+    gen_set_pc_imm(ctx, ctx->pc_succ_insn);
     tcg_gen_exit_tb(NULL, 0);
     ctx->base.is_jmp = DISAS_NORETURN;
     return true;
@@ -836,7 +837,7 @@ static bool trans_fence_i(DisasContext *ctx, arg_fence_i *a)
 static bool do_csr_post(DisasContext *ctx)
 {
     /* We may have changed important cpu state -- exit to main loop. */
-    tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
+    gen_set_pc_imm(ctx, ctx->pc_succ_insn);
     tcg_gen_exit_tb(NULL, 0);
     ctx->base.is_jmp = DISAS_NORETURN;
     return true;
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
index 6c285c958b..1c8086d3a6 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -149,7 +149,7 @@ static bool do_vsetvl(DisasContext *s, int rd, int rs1, TCGv s2)
     gen_set_gpr(s, rd, dst);
     mark_vs_dirty(s);
 
-    tcg_gen_movi_tl(cpu_pc, s->pc_succ_insn);
+    gen_set_pc_imm(s, s->pc_succ_insn);
     tcg_gen_lookup_and_goto_ptr();
     s->base.is_jmp = DISAS_NORETURN;
 
@@ -173,7 +173,7 @@ static bool do_vsetivli(DisasContext *s, int rd, TCGv s1, TCGv s2)
     gen_helper_vsetvl(dst, cpu_env, s1, s2);
     gen_set_gpr(s, rd, dst);
     mark_vs_dirty(s);
-    tcg_gen_movi_tl(cpu_pc, s->pc_succ_insn);
+    gen_set_pc_imm(s, s->pc_succ_insn);
     tcg_gen_lookup_and_goto_ptr();
     s->base.is_jmp = DISAS_NORETURN;
 
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index b47b308920..d8b7c48600 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -191,16 +191,33 @@ static void gen_check_nanbox_s(TCGv_i64 out, TCGv_i64 in)
     tcg_gen_movcond_i64(TCG_COND_GEU, out, in, t_max, in, t_nan);
 }
 
+static void gen_set_pc_imm(DisasContext *ctx, target_ulong dest)
+{
+    if (get_xl(ctx) == MXL_RV32) {
+        dest = (int32_t)dest;
+    }
+    tcg_gen_movi_tl(cpu_pc, dest);
+}
+
+static void gen_set_pc(DisasContext *ctx, TCGv dest)
+{
+    if (get_xl(ctx) == MXL_RV32) {
+        tcg_gen_ext32s_tl(cpu_pc, dest);
+    } else {
+        tcg_gen_mov_tl(cpu_pc, dest);
+    }
+}
+
 static void generate_exception(DisasContext *ctx, int excp)
 {
-    tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
+    gen_set_pc_imm(ctx, ctx->base.pc_next);
     gen_helper_raise_exception(cpu_env, tcg_constant_i32(excp));
     ctx->base.is_jmp = DISAS_NORETURN;
 }
 
 static void generate_exception_mtval(DisasContext *ctx, int excp)
 {
-    tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
+    gen_set_pc_imm(ctx, ctx->base.pc_next);
     tcg_gen_st_tl(cpu_pc, cpu_env, offsetof(CPURISCVState, badaddr));
     gen_helper_raise_exception(cpu_env, tcg_constant_i32(excp));
     ctx->base.is_jmp = DISAS_NORETURN;
@@ -223,10 +240,10 @@ static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
 {
     if (translator_use_goto_tb(&ctx->base, dest)) {
         tcg_gen_goto_tb(n);
-        tcg_gen_movi_tl(cpu_pc, dest);
+        gen_set_pc_imm(ctx, dest);
         tcg_gen_exit_tb(ctx->base.tb, n);
     } else {
-        tcg_gen_movi_tl(cpu_pc, dest);
+        gen_set_pc_imm(ctx, dest);
         tcg_gen_lookup_and_goto_ptr();
     }
 }
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v6 05/22] target/riscv: Create xl field in env
  2022-01-13 11:39 ` LIU Zhiwei
@ 2022-01-13 11:39   ` LIU Zhiwei
  -1 siblings, 0 replies; 60+ messages in thread
From: LIU Zhiwei @ 2022-01-13 11:39 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: guoren, bin.meng, richard.henderson, palmer, Alistair.Francis,
	LIU Zhiwei

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
---
 target/riscv/cpu.c        |  1 +
 target/riscv/cpu.h        | 31 +++++++++++++++++++++++++++++++
 target/riscv/cpu_helper.c | 34 ++--------------------------------
 target/riscv/csr.c        |  2 ++
 target/riscv/machine.c    | 10 ++++++++++
 5 files changed, 46 insertions(+), 32 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 9bc25d3055..54c1cf8ec5 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -399,6 +399,7 @@ static void riscv_cpu_reset(DeviceState *dev)
     /* mmte is supposed to have pm.current hardwired to 1 */
     env->mmte |= (PM_EXT_INITIAL | MMTE_M_PM_CURRENT);
 #endif
+    env->xl = riscv_cpu_mxl(env);
     cs->exception_index = RISCV_EXCP_NONE;
     env->load_res = -1;
     set_default_nan_mode(1, &env->fp_status);
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 4d63086765..65fd849bef 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -145,6 +145,7 @@ struct CPURISCVState {
     uint32_t misa_mxl_max;  /* max mxl for this cpu */
     uint32_t misa_ext;      /* current extensions */
     uint32_t misa_ext_mask; /* max ext for this cpu */
+    uint32_t xl;            /* current xlen */
 
     /* 128-bit helpers upper part return value */
     target_ulong retxh;
@@ -443,6 +444,36 @@ static inline RISCVMXL riscv_cpu_mxl(CPURISCVState *env)
 }
 #endif
 
+#if defined(TARGET_RISCV32)
+#define cpu_recompute_xl(env)  ((void)(env), MXL_RV32)
+#else
+static inline RISCVMXL cpu_recompute_xl(CPURISCVState *env)
+{
+    RISCVMXL xl = env->misa_mxl;
+#if !defined(CONFIG_USER_ONLY)
+    /*
+     * When emulating a 32-bit-only cpu, use RV32.
+     * When emulating a 64-bit cpu, and MXL has been reduced to RV32,
+     * MSTATUSH doesn't have UXL/SXL, therefore XLEN cannot be widened
+     * back to RV64 for lower privs.
+     */
+    if (xl != MXL_RV32) {
+        switch (env->priv) {
+        case PRV_M:
+            break;
+        case PRV_U:
+            xl = get_field(env->mstatus, MSTATUS64_UXL);
+            break;
+        default: /* PRV_S | PRV_H */
+            xl = get_field(env->mstatus, MSTATUS64_SXL);
+            break;
+        }
+    }
+#endif
+    return xl;
+}
+#endif
+
 /*
  * Encode LMUL to lmul as follows:
  *     LMUL    vlmul    lmul
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 434a83e66a..32ea066ef0 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -35,37 +35,6 @@ int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
 #endif
 }
 
-static RISCVMXL cpu_get_xl(CPURISCVState *env)
-{
-#if defined(TARGET_RISCV32)
-    return MXL_RV32;
-#elif defined(CONFIG_USER_ONLY)
-    return MXL_RV64;
-#else
-    RISCVMXL xl = riscv_cpu_mxl(env);
-
-    /*
-     * When emulating a 32-bit-only cpu, use RV32.
-     * When emulating a 64-bit cpu, and MXL has been reduced to RV32,
-     * MSTATUSH doesn't have UXL/SXL, therefore XLEN cannot be widened
-     * back to RV64 for lower privs.
-     */
-    if (xl != MXL_RV32) {
-        switch (env->priv) {
-        case PRV_M:
-            break;
-        case PRV_U:
-            xl = get_field(env->mstatus, MSTATUS64_UXL);
-            break;
-        default: /* PRV_S | PRV_H */
-            xl = get_field(env->mstatus, MSTATUS64_SXL);
-            break;
-        }
-    }
-    return xl;
-#endif
-}
-
 void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
                           target_ulong *cs_base, uint32_t *pflags)
 {
@@ -145,7 +114,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
     }
 #endif
 
-    flags = FIELD_DP32(flags, TB_FLAGS, XL, cpu_get_xl(env));
+    flags = FIELD_DP32(flags, TB_FLAGS, XL, env->xl);
 
     *pflags = flags;
 }
@@ -361,6 +330,7 @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv)
     }
     /* tlb_flush is unnecessary as mode is contained in mmu_idx */
     env->priv = newpriv;
+    env->xl = cpu_recompute_xl(env);
 
     /*
      * Clear the load reservation - otherwise a reservation placed in one
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index e7578f3e0f..b282a642f5 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -585,6 +585,7 @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno,
         mstatus = set_field(mstatus, MSTATUS64_UXL, xl);
     }
     env->mstatus = mstatus;
+    env->xl = cpu_recompute_xl(env);
 
     return RISCV_EXCP_NONE;
 }
@@ -700,6 +701,7 @@ static RISCVException write_misa(CPURISCVState *env, int csrno,
     /* flush translation cache */
     tb_flush(env_cpu(env));
     env->misa_ext = val;
+    env->xl = riscv_cpu_mxl(env);
     return RISCV_EXCP_NONE;
 }
 
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
index 13b9ab375b..e1d1029e88 100644
--- a/target/riscv/machine.c
+++ b/target/riscv/machine.c
@@ -185,10 +185,20 @@ static const VMStateDescription vmstate_rv128 = {
     }
 };
 
+static int riscv_cpu_post_load(void *opaque, int version_id)
+{
+    RISCVCPU *cpu = opaque;
+    CPURISCVState *env = &cpu->env;
+
+    env->xl = cpu_recompute_xl(env);
+    return 0;
+}
+
 const VMStateDescription vmstate_riscv_cpu = {
     .name = "cpu",
     .version_id = 3,
     .minimum_version_id = 3,
+    .post_load = riscv_cpu_post_load,
     .fields = (VMStateField[]) {
         VMSTATE_UINTTL_ARRAY(env.gpr, RISCVCPU, 32),
         VMSTATE_UINT64_ARRAY(env.fpr, RISCVCPU, 32),
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v6 05/22] target/riscv: Create xl field in env
@ 2022-01-13 11:39   ` LIU Zhiwei
  0 siblings, 0 replies; 60+ messages in thread
From: LIU Zhiwei @ 2022-01-13 11:39 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: Alistair.Francis, palmer, bin.meng, richard.henderson, guoren,
	LIU Zhiwei

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
---
 target/riscv/cpu.c        |  1 +
 target/riscv/cpu.h        | 31 +++++++++++++++++++++++++++++++
 target/riscv/cpu_helper.c | 34 ++--------------------------------
 target/riscv/csr.c        |  2 ++
 target/riscv/machine.c    | 10 ++++++++++
 5 files changed, 46 insertions(+), 32 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 9bc25d3055..54c1cf8ec5 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -399,6 +399,7 @@ static void riscv_cpu_reset(DeviceState *dev)
     /* mmte is supposed to have pm.current hardwired to 1 */
     env->mmte |= (PM_EXT_INITIAL | MMTE_M_PM_CURRENT);
 #endif
+    env->xl = riscv_cpu_mxl(env);
     cs->exception_index = RISCV_EXCP_NONE;
     env->load_res = -1;
     set_default_nan_mode(1, &env->fp_status);
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 4d63086765..65fd849bef 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -145,6 +145,7 @@ struct CPURISCVState {
     uint32_t misa_mxl_max;  /* max mxl for this cpu */
     uint32_t misa_ext;      /* current extensions */
     uint32_t misa_ext_mask; /* max ext for this cpu */
+    uint32_t xl;            /* current xlen */
 
     /* 128-bit helpers upper part return value */
     target_ulong retxh;
@@ -443,6 +444,36 @@ static inline RISCVMXL riscv_cpu_mxl(CPURISCVState *env)
 }
 #endif
 
+#if defined(TARGET_RISCV32)
+#define cpu_recompute_xl(env)  ((void)(env), MXL_RV32)
+#else
+static inline RISCVMXL cpu_recompute_xl(CPURISCVState *env)
+{
+    RISCVMXL xl = env->misa_mxl;
+#if !defined(CONFIG_USER_ONLY)
+    /*
+     * When emulating a 32-bit-only cpu, use RV32.
+     * When emulating a 64-bit cpu, and MXL has been reduced to RV32,
+     * MSTATUSH doesn't have UXL/SXL, therefore XLEN cannot be widened
+     * back to RV64 for lower privs.
+     */
+    if (xl != MXL_RV32) {
+        switch (env->priv) {
+        case PRV_M:
+            break;
+        case PRV_U:
+            xl = get_field(env->mstatus, MSTATUS64_UXL);
+            break;
+        default: /* PRV_S | PRV_H */
+            xl = get_field(env->mstatus, MSTATUS64_SXL);
+            break;
+        }
+    }
+#endif
+    return xl;
+}
+#endif
+
 /*
  * Encode LMUL to lmul as follows:
  *     LMUL    vlmul    lmul
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 434a83e66a..32ea066ef0 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -35,37 +35,6 @@ int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
 #endif
 }
 
-static RISCVMXL cpu_get_xl(CPURISCVState *env)
-{
-#if defined(TARGET_RISCV32)
-    return MXL_RV32;
-#elif defined(CONFIG_USER_ONLY)
-    return MXL_RV64;
-#else
-    RISCVMXL xl = riscv_cpu_mxl(env);
-
-    /*
-     * When emulating a 32-bit-only cpu, use RV32.
-     * When emulating a 64-bit cpu, and MXL has been reduced to RV32,
-     * MSTATUSH doesn't have UXL/SXL, therefore XLEN cannot be widened
-     * back to RV64 for lower privs.
-     */
-    if (xl != MXL_RV32) {
-        switch (env->priv) {
-        case PRV_M:
-            break;
-        case PRV_U:
-            xl = get_field(env->mstatus, MSTATUS64_UXL);
-            break;
-        default: /* PRV_S | PRV_H */
-            xl = get_field(env->mstatus, MSTATUS64_SXL);
-            break;
-        }
-    }
-    return xl;
-#endif
-}
-
 void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
                           target_ulong *cs_base, uint32_t *pflags)
 {
@@ -145,7 +114,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
     }
 #endif
 
-    flags = FIELD_DP32(flags, TB_FLAGS, XL, cpu_get_xl(env));
+    flags = FIELD_DP32(flags, TB_FLAGS, XL, env->xl);
 
     *pflags = flags;
 }
@@ -361,6 +330,7 @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv)
     }
     /* tlb_flush is unnecessary as mode is contained in mmu_idx */
     env->priv = newpriv;
+    env->xl = cpu_recompute_xl(env);
 
     /*
      * Clear the load reservation - otherwise a reservation placed in one
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index e7578f3e0f..b282a642f5 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -585,6 +585,7 @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno,
         mstatus = set_field(mstatus, MSTATUS64_UXL, xl);
     }
     env->mstatus = mstatus;
+    env->xl = cpu_recompute_xl(env);
 
     return RISCV_EXCP_NONE;
 }
@@ -700,6 +701,7 @@ static RISCVException write_misa(CPURISCVState *env, int csrno,
     /* flush translation cache */
     tb_flush(env_cpu(env));
     env->misa_ext = val;
+    env->xl = riscv_cpu_mxl(env);
     return RISCV_EXCP_NONE;
 }
 
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
index 13b9ab375b..e1d1029e88 100644
--- a/target/riscv/machine.c
+++ b/target/riscv/machine.c
@@ -185,10 +185,20 @@ static const VMStateDescription vmstate_rv128 = {
     }
 };
 
+static int riscv_cpu_post_load(void *opaque, int version_id)
+{
+    RISCVCPU *cpu = opaque;
+    CPURISCVState *env = &cpu->env;
+
+    env->xl = cpu_recompute_xl(env);
+    return 0;
+}
+
 const VMStateDescription vmstate_riscv_cpu = {
     .name = "cpu",
     .version_id = 3,
     .minimum_version_id = 3,
+    .post_load = riscv_cpu_post_load,
     .fields = (VMStateField[]) {
         VMSTATE_UINTTL_ARRAY(env.gpr, RISCVCPU, 32),
         VMSTATE_UINT64_ARRAY(env.fpr, RISCVCPU, 32),
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v6 06/22] target/riscv: Ignore the pc bits above XLEN
  2022-01-13 11:39 ` LIU Zhiwei
@ 2022-01-13 11:39   ` LIU Zhiwei
  -1 siblings, 0 replies; 60+ messages in thread
From: LIU Zhiwei @ 2022-01-13 11:39 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: guoren, bin.meng, richard.henderson, palmer, Alistair Francis,
	LIU Zhiwei

The read from PC for translation is in cpu_get_tb_cpu_state, before translation.

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
 target/riscv/cpu_helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 32ea066ef0..2c83eb1f05 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -40,7 +40,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
 {
     uint32_t flags = 0;
 
-    *pc = env->pc;
+    *pc = env->xl == MXL_RV32 ? env->pc & UINT32_MAX : env->pc;
     *cs_base = 0;
 
     if (riscv_has_ext(env, RVV)) {
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v6 06/22] target/riscv: Ignore the pc bits above XLEN
@ 2022-01-13 11:39   ` LIU Zhiwei
  0 siblings, 0 replies; 60+ messages in thread
From: LIU Zhiwei @ 2022-01-13 11:39 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: Alistair.Francis, palmer, bin.meng, richard.henderson, guoren,
	LIU Zhiwei, Alistair Francis

The read from PC for translation is in cpu_get_tb_cpu_state, before translation.

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
 target/riscv/cpu_helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 32ea066ef0..2c83eb1f05 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -40,7 +40,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
 {
     uint32_t flags = 0;
 
-    *pc = env->pc;
+    *pc = env->xl == MXL_RV32 ? env->pc & UINT32_MAX : env->pc;
     *cs_base = 0;
 
     if (riscv_has_ext(env, RVV)) {
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v6 07/22] target/riscv: Extend pc for runtime pc write
  2022-01-13 11:39 ` LIU Zhiwei
@ 2022-01-13 11:39   ` LIU Zhiwei
  -1 siblings, 0 replies; 60+ messages in thread
From: LIU Zhiwei @ 2022-01-13 11:39 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: guoren, bin.meng, richard.henderson, palmer, Alistair Francis,
	LIU Zhiwei

In some cases, we must restore the guest PC to the address of the start of
the TB, such as when the instruction counter hits zero. So extend pc register
according to current xlen for these cases.

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
 target/riscv/cpu.c | 22 +++++++++++++++++++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 54c1cf8ec5..db16aaf7c9 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -341,7 +341,12 @@ static void riscv_cpu_set_pc(CPUState *cs, vaddr value)
 {
     RISCVCPU *cpu = RISCV_CPU(cs);
     CPURISCVState *env = &cpu->env;
-    env->pc = value;
+
+    if (env->xl == MXL_RV32) {
+        env->pc = (int32_t)value;
+    } else {
+        env->pc = value;
+    }
 }
 
 static void riscv_cpu_synchronize_from_tb(CPUState *cs,
@@ -349,7 +354,13 @@ static void riscv_cpu_synchronize_from_tb(CPUState *cs,
 {
     RISCVCPU *cpu = RISCV_CPU(cs);
     CPURISCVState *env = &cpu->env;
-    env->pc = tb->pc;
+    RISCVMXL xl = FIELD_EX32(tb->flags, TB_FLAGS, XL);
+
+    if (xl == MXL_RV32) {
+        env->pc = (int32_t)tb->pc;
+    } else {
+        env->pc = tb->pc;
+    }
 }
 
 static bool riscv_cpu_has_work(CPUState *cs)
@@ -370,7 +381,12 @@ static bool riscv_cpu_has_work(CPUState *cs)
 void restore_state_to_opc(CPURISCVState *env, TranslationBlock *tb,
                           target_ulong *data)
 {
-    env->pc = data[0];
+    RISCVMXL xl = FIELD_EX32(tb->flags, TB_FLAGS, XL);
+    if (xl == MXL_RV32) {
+        env->pc = (int32_t)data[0];
+    } else {
+        env->pc = data[0];
+    }
 }
 
 static void riscv_cpu_reset(DeviceState *dev)
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v6 07/22] target/riscv: Extend pc for runtime pc write
@ 2022-01-13 11:39   ` LIU Zhiwei
  0 siblings, 0 replies; 60+ messages in thread
From: LIU Zhiwei @ 2022-01-13 11:39 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: Alistair.Francis, palmer, bin.meng, richard.henderson, guoren,
	LIU Zhiwei, Alistair Francis

In some cases, we must restore the guest PC to the address of the start of
the TB, such as when the instruction counter hits zero. So extend pc register
according to current xlen for these cases.

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
 target/riscv/cpu.c | 22 +++++++++++++++++++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 54c1cf8ec5..db16aaf7c9 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -341,7 +341,12 @@ static void riscv_cpu_set_pc(CPUState *cs, vaddr value)
 {
     RISCVCPU *cpu = RISCV_CPU(cs);
     CPURISCVState *env = &cpu->env;
-    env->pc = value;
+
+    if (env->xl == MXL_RV32) {
+        env->pc = (int32_t)value;
+    } else {
+        env->pc = value;
+    }
 }
 
 static void riscv_cpu_synchronize_from_tb(CPUState *cs,
@@ -349,7 +354,13 @@ static void riscv_cpu_synchronize_from_tb(CPUState *cs,
 {
     RISCVCPU *cpu = RISCV_CPU(cs);
     CPURISCVState *env = &cpu->env;
-    env->pc = tb->pc;
+    RISCVMXL xl = FIELD_EX32(tb->flags, TB_FLAGS, XL);
+
+    if (xl == MXL_RV32) {
+        env->pc = (int32_t)tb->pc;
+    } else {
+        env->pc = tb->pc;
+    }
 }
 
 static bool riscv_cpu_has_work(CPUState *cs)
@@ -370,7 +381,12 @@ static bool riscv_cpu_has_work(CPUState *cs)
 void restore_state_to_opc(CPURISCVState *env, TranslationBlock *tb,
                           target_ulong *data)
 {
-    env->pc = data[0];
+    RISCVMXL xl = FIELD_EX32(tb->flags, TB_FLAGS, XL);
+    if (xl == MXL_RV32) {
+        env->pc = (int32_t)data[0];
+    } else {
+        env->pc = data[0];
+    }
 }
 
 static void riscv_cpu_reset(DeviceState *dev)
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v6 08/22] target/riscv: Use gdb xml according to max mxlen
  2022-01-13 11:39 ` LIU Zhiwei
@ 2022-01-13 11:39   ` LIU Zhiwei
  -1 siblings, 0 replies; 60+ messages in thread
From: LIU Zhiwei @ 2022-01-13 11:39 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: guoren, bin.meng, richard.henderson, palmer, Alistair Francis,
	LIU Zhiwei

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
 target/riscv/cpu.c     |  8 ++---
 target/riscv/gdbstub.c | 71 +++++++++++++++++++++++++++++++-----------
 2 files changed, 55 insertions(+), 24 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index db16aaf7c9..a21287253a 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -446,6 +446,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
     RISCVCPU *cpu = RISCV_CPU(dev);
     CPURISCVState *env = &cpu->env;
     RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev);
+    CPUClass *cc = CPU_CLASS(mcc);
     int priv_version = 0;
     Error *local_err = NULL;
 
@@ -496,11 +497,13 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
     switch (env->misa_mxl_max) {
 #ifdef TARGET_RISCV64
     case MXL_RV64:
+        cc->gdb_core_xml_file = "riscv-64bit-cpu.xml";
         break;
     case MXL_RV128:
         break;
 #endif
     case MXL_RV32:
+        cc->gdb_core_xml_file = "riscv-32bit-cpu.xml";
         break;
     default:
         g_assert_not_reached();
@@ -772,11 +775,6 @@ static void riscv_cpu_class_init(ObjectClass *c, void *data)
     cc->gdb_read_register = riscv_cpu_gdb_read_register;
     cc->gdb_write_register = riscv_cpu_gdb_write_register;
     cc->gdb_num_core_regs = 33;
-#if defined(TARGET_RISCV32)
-    cc->gdb_core_xml_file = "riscv-32bit-cpu.xml";
-#elif defined(TARGET_RISCV64)
-    cc->gdb_core_xml_file = "riscv-64bit-cpu.xml";
-#endif
     cc->gdb_stop_before_watchpoint = true;
     cc->disas_set_info = riscv_cpu_disas_set_info;
 #ifndef CONFIG_USER_ONLY
diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
index a5429b92d4..f531a74c2f 100644
--- a/target/riscv/gdbstub.c
+++ b/target/riscv/gdbstub.c
@@ -50,11 +50,23 @@ int riscv_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
 {
     RISCVCPU *cpu = RISCV_CPU(cs);
     CPURISCVState *env = &cpu->env;
+    target_ulong tmp;
 
     if (n < 32) {
-        return gdb_get_regl(mem_buf, env->gpr[n]);
+        tmp = env->gpr[n];
     } else if (n == 32) {
-        return gdb_get_regl(mem_buf, env->pc);
+        tmp = env->pc;
+    } else {
+        return 0;
+    }
+
+    switch (env->misa_mxl_max) {
+    case MXL_RV32:
+        return gdb_get_reg32(mem_buf, tmp);
+    case MXL_RV64:
+        return gdb_get_reg64(mem_buf, tmp);
+    default:
+        g_assert_not_reached();
     }
     return 0;
 }
@@ -63,18 +75,32 @@ int riscv_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
 {
     RISCVCPU *cpu = RISCV_CPU(cs);
     CPURISCVState *env = &cpu->env;
-
-    if (n == 0) {
-        /* discard writes to x0 */
-        return sizeof(target_ulong);
-    } else if (n < 32) {
-        env->gpr[n] = ldtul_p(mem_buf);
-        return sizeof(target_ulong);
+    int length = 0;
+    target_ulong tmp;
+
+    switch (env->misa_mxl_max) {
+    case MXL_RV32:
+        tmp = (int32_t)ldl_p(mem_buf);
+        length = 4;
+        break;
+    case MXL_RV64:
+        if (env->xl < MXL_RV64) {
+            tmp = (int32_t)ldq_p(mem_buf);
+        } else {
+            tmp = ldq_p(mem_buf);
+        }
+        length = 8;
+        break;
+    default:
+        g_assert_not_reached();
+    }
+    if (n > 0 && n < 32) {
+        env->gpr[n] = tmp;
     } else if (n == 32) {
-        env->pc = ldtul_p(mem_buf);
-        return sizeof(target_ulong);
+        env->pc = tmp;
     }
-    return 0;
+
+    return length;
 }
 
 static int riscv_gdb_get_fpu(CPURISCVState *env, GByteArray *buf, int n)
@@ -387,13 +413,20 @@ void riscv_cpu_register_gdb_regs_for_features(CPUState *cs)
                                                               cs->gdb_num_regs),
                                  "riscv-vector.xml", 0);
     }
-#if defined(TARGET_RISCV32)
-    gdb_register_coprocessor(cs, riscv_gdb_get_virtual, riscv_gdb_set_virtual,
-                             1, "riscv-32bit-virtual.xml", 0);
-#elif defined(TARGET_RISCV64)
-    gdb_register_coprocessor(cs, riscv_gdb_get_virtual, riscv_gdb_set_virtual,
-                             1, "riscv-64bit-virtual.xml", 0);
-#endif
+    switch (env->misa_mxl_max) {
+    case MXL_RV32:
+        gdb_register_coprocessor(cs, riscv_gdb_get_virtual,
+                                 riscv_gdb_set_virtual,
+                                 1, "riscv-32bit-virtual.xml", 0);
+        break;
+    case MXL_RV64:
+        gdb_register_coprocessor(cs, riscv_gdb_get_virtual,
+                                 riscv_gdb_set_virtual,
+                                 1, "riscv-64bit-virtual.xml", 0);
+        break;
+    default:
+        g_assert_not_reached();
+    }
 
     gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr,
                              riscv_gen_dynamic_csr_xml(cs, cs->gdb_num_regs),
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v6 08/22] target/riscv: Use gdb xml according to max mxlen
@ 2022-01-13 11:39   ` LIU Zhiwei
  0 siblings, 0 replies; 60+ messages in thread
From: LIU Zhiwei @ 2022-01-13 11:39 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: Alistair.Francis, palmer, bin.meng, richard.henderson, guoren,
	LIU Zhiwei, Alistair Francis

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
 target/riscv/cpu.c     |  8 ++---
 target/riscv/gdbstub.c | 71 +++++++++++++++++++++++++++++++-----------
 2 files changed, 55 insertions(+), 24 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index db16aaf7c9..a21287253a 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -446,6 +446,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
     RISCVCPU *cpu = RISCV_CPU(dev);
     CPURISCVState *env = &cpu->env;
     RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev);
+    CPUClass *cc = CPU_CLASS(mcc);
     int priv_version = 0;
     Error *local_err = NULL;
 
@@ -496,11 +497,13 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
     switch (env->misa_mxl_max) {
 #ifdef TARGET_RISCV64
     case MXL_RV64:
+        cc->gdb_core_xml_file = "riscv-64bit-cpu.xml";
         break;
     case MXL_RV128:
         break;
 #endif
     case MXL_RV32:
+        cc->gdb_core_xml_file = "riscv-32bit-cpu.xml";
         break;
     default:
         g_assert_not_reached();
@@ -772,11 +775,6 @@ static void riscv_cpu_class_init(ObjectClass *c, void *data)
     cc->gdb_read_register = riscv_cpu_gdb_read_register;
     cc->gdb_write_register = riscv_cpu_gdb_write_register;
     cc->gdb_num_core_regs = 33;
-#if defined(TARGET_RISCV32)
-    cc->gdb_core_xml_file = "riscv-32bit-cpu.xml";
-#elif defined(TARGET_RISCV64)
-    cc->gdb_core_xml_file = "riscv-64bit-cpu.xml";
-#endif
     cc->gdb_stop_before_watchpoint = true;
     cc->disas_set_info = riscv_cpu_disas_set_info;
 #ifndef CONFIG_USER_ONLY
diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
index a5429b92d4..f531a74c2f 100644
--- a/target/riscv/gdbstub.c
+++ b/target/riscv/gdbstub.c
@@ -50,11 +50,23 @@ int riscv_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
 {
     RISCVCPU *cpu = RISCV_CPU(cs);
     CPURISCVState *env = &cpu->env;
+    target_ulong tmp;
 
     if (n < 32) {
-        return gdb_get_regl(mem_buf, env->gpr[n]);
+        tmp = env->gpr[n];
     } else if (n == 32) {
-        return gdb_get_regl(mem_buf, env->pc);
+        tmp = env->pc;
+    } else {
+        return 0;
+    }
+
+    switch (env->misa_mxl_max) {
+    case MXL_RV32:
+        return gdb_get_reg32(mem_buf, tmp);
+    case MXL_RV64:
+        return gdb_get_reg64(mem_buf, tmp);
+    default:
+        g_assert_not_reached();
     }
     return 0;
 }
@@ -63,18 +75,32 @@ int riscv_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
 {
     RISCVCPU *cpu = RISCV_CPU(cs);
     CPURISCVState *env = &cpu->env;
-
-    if (n == 0) {
-        /* discard writes to x0 */
-        return sizeof(target_ulong);
-    } else if (n < 32) {
-        env->gpr[n] = ldtul_p(mem_buf);
-        return sizeof(target_ulong);
+    int length = 0;
+    target_ulong tmp;
+
+    switch (env->misa_mxl_max) {
+    case MXL_RV32:
+        tmp = (int32_t)ldl_p(mem_buf);
+        length = 4;
+        break;
+    case MXL_RV64:
+        if (env->xl < MXL_RV64) {
+            tmp = (int32_t)ldq_p(mem_buf);
+        } else {
+            tmp = ldq_p(mem_buf);
+        }
+        length = 8;
+        break;
+    default:
+        g_assert_not_reached();
+    }
+    if (n > 0 && n < 32) {
+        env->gpr[n] = tmp;
     } else if (n == 32) {
-        env->pc = ldtul_p(mem_buf);
-        return sizeof(target_ulong);
+        env->pc = tmp;
     }
-    return 0;
+
+    return length;
 }
 
 static int riscv_gdb_get_fpu(CPURISCVState *env, GByteArray *buf, int n)
@@ -387,13 +413,20 @@ void riscv_cpu_register_gdb_regs_for_features(CPUState *cs)
                                                               cs->gdb_num_regs),
                                  "riscv-vector.xml", 0);
     }
-#if defined(TARGET_RISCV32)
-    gdb_register_coprocessor(cs, riscv_gdb_get_virtual, riscv_gdb_set_virtual,
-                             1, "riscv-32bit-virtual.xml", 0);
-#elif defined(TARGET_RISCV64)
-    gdb_register_coprocessor(cs, riscv_gdb_get_virtual, riscv_gdb_set_virtual,
-                             1, "riscv-64bit-virtual.xml", 0);
-#endif
+    switch (env->misa_mxl_max) {
+    case MXL_RV32:
+        gdb_register_coprocessor(cs, riscv_gdb_get_virtual,
+                                 riscv_gdb_set_virtual,
+                                 1, "riscv-32bit-virtual.xml", 0);
+        break;
+    case MXL_RV64:
+        gdb_register_coprocessor(cs, riscv_gdb_get_virtual,
+                                 riscv_gdb_set_virtual,
+                                 1, "riscv-64bit-virtual.xml", 0);
+        break;
+    default:
+        g_assert_not_reached();
+    }
 
     gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr,
                              riscv_gen_dynamic_csr_xml(cs, cs->gdb_num_regs),
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v6 09/22] target/riscv: Relax debug check for pm write
  2022-01-13 11:39 ` LIU Zhiwei
@ 2022-01-13 11:39   ` LIU Zhiwei
  -1 siblings, 0 replies; 60+ messages in thread
From: LIU Zhiwei @ 2022-01-13 11:39 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: guoren, bin.meng, richard.henderson, palmer, Alistair Francis,
	LIU Zhiwei

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
 target/riscv/csr.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index b282a642f5..3f3afbed21 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1552,6 +1552,9 @@ static bool check_pm_current_disabled(CPURISCVState *env, int csrno)
     int csr_priv = get_field(csrno, 0x300);
     int pm_current;
 
+    if (env->debugger) {
+        return false;
+    }
     /*
      * If priv lvls differ that means we're accessing csr from higher priv lvl,
      * so allow the access
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v6 09/22] target/riscv: Relax debug check for pm write
@ 2022-01-13 11:39   ` LIU Zhiwei
  0 siblings, 0 replies; 60+ messages in thread
From: LIU Zhiwei @ 2022-01-13 11:39 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: Alistair.Francis, palmer, bin.meng, richard.henderson, guoren,
	LIU Zhiwei, Alistair Francis

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
 target/riscv/csr.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index b282a642f5..3f3afbed21 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1552,6 +1552,9 @@ static bool check_pm_current_disabled(CPURISCVState *env, int csrno)
     int csr_priv = get_field(csrno, 0x300);
     int pm_current;
 
+    if (env->debugger) {
+        return false;
+    }
     /*
      * If priv lvls differ that means we're accessing csr from higher priv lvl,
      * so allow the access
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v6 10/22] target/riscv: Adjust csr write mask with XLEN
  2022-01-13 11:39 ` LIU Zhiwei
@ 2022-01-13 11:39   ` LIU Zhiwei
  -1 siblings, 0 replies; 60+ messages in thread
From: LIU Zhiwei @ 2022-01-13 11:39 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: guoren, bin.meng, richard.henderson, palmer, Alistair Francis,
	LIU Zhiwei

Write mask is representing the bits we care about.

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
 target/riscv/insn_trans/trans_rvi.c.inc | 12 ++++++++----
 target/riscv/op_helper.c                |  3 ++-
 2 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
index 04d3ea237f..631bc1f09e 100644
--- a/target/riscv/insn_trans/trans_rvi.c.inc
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
@@ -924,7 +924,8 @@ static bool do_csrrw_i128(DisasContext *ctx, int rd, int rc,
 
 static bool trans_csrrw(DisasContext *ctx, arg_csrrw *a)
 {
-    if (get_xl(ctx) < MXL_RV128) {
+    RISCVMXL xl = get_xl(ctx);
+    if (xl < MXL_RV128) {
         TCGv src = get_gpr(ctx, a->rs1, EXT_NONE);
 
         /*
@@ -935,7 +936,8 @@ static bool trans_csrrw(DisasContext *ctx, arg_csrrw *a)
             return do_csrw(ctx, a->csr, src);
         }
 
-        TCGv mask = tcg_constant_tl(-1);
+        TCGv mask = tcg_constant_tl(xl == MXL_RV32 ? UINT32_MAX :
+                                                     (target_ulong)-1);
         return do_csrrw(ctx, a->rd, a->csr, src, mask);
     } else {
         TCGv srcl = get_gpr(ctx, a->rs1, EXT_NONE);
@@ -1013,7 +1015,8 @@ static bool trans_csrrc(DisasContext *ctx, arg_csrrc *a)
 
 static bool trans_csrrwi(DisasContext *ctx, arg_csrrwi *a)
 {
-    if (get_xl(ctx) < MXL_RV128) {
+    RISCVMXL xl = get_xl(ctx);
+    if (xl < MXL_RV128) {
         TCGv src = tcg_constant_tl(a->rs1);
 
         /*
@@ -1024,7 +1027,8 @@ static bool trans_csrrwi(DisasContext *ctx, arg_csrrwi *a)
             return do_csrw(ctx, a->csr, src);
         }
 
-        TCGv mask = tcg_constant_tl(-1);
+        TCGv mask = tcg_constant_tl(xl == MXL_RV32 ? UINT32_MAX :
+                                                     (target_ulong)-1);
         return do_csrrw(ctx, a->rd, a->csr, src, mask);
     } else {
         TCGv src = tcg_constant_tl(a->rs1);
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index 67693cb42b..1a75ba11e6 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -50,7 +50,8 @@ target_ulong helper_csrr(CPURISCVState *env, int csr)
 
 void helper_csrw(CPURISCVState *env, int csr, target_ulong src)
 {
-    RISCVException ret = riscv_csrrw(env, csr, NULL, src, -1);
+    target_ulong mask = env->xl == MXL_RV32 ? UINT32_MAX : (target_ulong)-1;
+    RISCVException ret = riscv_csrrw(env, csr, NULL, src, mask);
 
     if (ret != RISCV_EXCP_NONE) {
         riscv_raise_exception(env, ret, GETPC());
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v6 10/22] target/riscv: Adjust csr write mask with XLEN
@ 2022-01-13 11:39   ` LIU Zhiwei
  0 siblings, 0 replies; 60+ messages in thread
From: LIU Zhiwei @ 2022-01-13 11:39 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: Alistair.Francis, palmer, bin.meng, richard.henderson, guoren,
	LIU Zhiwei, Alistair Francis

Write mask is representing the bits we care about.

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
 target/riscv/insn_trans/trans_rvi.c.inc | 12 ++++++++----
 target/riscv/op_helper.c                |  3 ++-
 2 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
index 04d3ea237f..631bc1f09e 100644
--- a/target/riscv/insn_trans/trans_rvi.c.inc
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
@@ -924,7 +924,8 @@ static bool do_csrrw_i128(DisasContext *ctx, int rd, int rc,
 
 static bool trans_csrrw(DisasContext *ctx, arg_csrrw *a)
 {
-    if (get_xl(ctx) < MXL_RV128) {
+    RISCVMXL xl = get_xl(ctx);
+    if (xl < MXL_RV128) {
         TCGv src = get_gpr(ctx, a->rs1, EXT_NONE);
 
         /*
@@ -935,7 +936,8 @@ static bool trans_csrrw(DisasContext *ctx, arg_csrrw *a)
             return do_csrw(ctx, a->csr, src);
         }
 
-        TCGv mask = tcg_constant_tl(-1);
+        TCGv mask = tcg_constant_tl(xl == MXL_RV32 ? UINT32_MAX :
+                                                     (target_ulong)-1);
         return do_csrrw(ctx, a->rd, a->csr, src, mask);
     } else {
         TCGv srcl = get_gpr(ctx, a->rs1, EXT_NONE);
@@ -1013,7 +1015,8 @@ static bool trans_csrrc(DisasContext *ctx, arg_csrrc *a)
 
 static bool trans_csrrwi(DisasContext *ctx, arg_csrrwi *a)
 {
-    if (get_xl(ctx) < MXL_RV128) {
+    RISCVMXL xl = get_xl(ctx);
+    if (xl < MXL_RV128) {
         TCGv src = tcg_constant_tl(a->rs1);
 
         /*
@@ -1024,7 +1027,8 @@ static bool trans_csrrwi(DisasContext *ctx, arg_csrrwi *a)
             return do_csrw(ctx, a->csr, src);
         }
 
-        TCGv mask = tcg_constant_tl(-1);
+        TCGv mask = tcg_constant_tl(xl == MXL_RV32 ? UINT32_MAX :
+                                                     (target_ulong)-1);
         return do_csrrw(ctx, a->rd, a->csr, src, mask);
     } else {
         TCGv src = tcg_constant_tl(a->rs1);
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index 67693cb42b..1a75ba11e6 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -50,7 +50,8 @@ target_ulong helper_csrr(CPURISCVState *env, int csr)
 
 void helper_csrw(CPURISCVState *env, int csr, target_ulong src)
 {
-    RISCVException ret = riscv_csrrw(env, csr, NULL, src, -1);
+    target_ulong mask = env->xl == MXL_RV32 ? UINT32_MAX : (target_ulong)-1;
+    RISCVException ret = riscv_csrrw(env, csr, NULL, src, mask);
 
     if (ret != RISCV_EXCP_NONE) {
         riscv_raise_exception(env, ret, GETPC());
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v6 11/22] target/riscv: Create current pm fields in env
  2022-01-13 11:39 ` LIU Zhiwei
@ 2022-01-13 11:39   ` LIU Zhiwei
  -1 siblings, 0 replies; 60+ messages in thread
From: LIU Zhiwei @ 2022-01-13 11:39 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: guoren, bin.meng, richard.henderson, palmer, Alistair Francis,
	LIU Zhiwei

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/riscv/cpu.c        |  1 +
 target/riscv/cpu.h        |  4 ++++
 target/riscv/cpu_helper.c | 43 +++++++++++++++++++++++++++++++++++++++
 target/riscv/csr.c        | 19 +++++++++++++++++
 target/riscv/machine.c    |  1 +
 5 files changed, 68 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index a21287253a..a4b9ab0d9c 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -416,6 +416,7 @@ static void riscv_cpu_reset(DeviceState *dev)
     env->mmte |= (PM_EXT_INITIAL | MMTE_M_PM_CURRENT);
 #endif
     env->xl = riscv_cpu_mxl(env);
+    riscv_cpu_update_mask(env);
     cs->exception_index = RISCV_EXCP_NONE;
     env->load_res = -1;
     set_default_nan_mode(1, &env->fp_status);
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 65fd849bef..adb455cf09 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -265,6 +265,8 @@ struct CPURISCVState {
     target_ulong upmmask;
     target_ulong upmbase;
 #endif
+    target_ulong cur_pmmask;
+    target_ulong cur_pmbase;
 
     float_status fp_status;
 
@@ -502,6 +504,8 @@ static inline uint32_t vext_get_vlmax(RISCVCPU *cpu, target_ulong vtype)
 void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
                           target_ulong *cs_base, uint32_t *pflags);
 
+void riscv_cpu_update_mask(CPURISCVState *env);
+
 RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
                            target_ulong *ret_value,
                            target_ulong new_value, target_ulong write_mask);
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 2c83eb1f05..e6c95edb18 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -119,6 +119,48 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
     *pflags = flags;
 }
 
+void riscv_cpu_update_mask(CPURISCVState *env)
+{
+    target_ulong mask = -1, base = 0;
+    /*
+     * TODO: Current RVJ spec does not specify
+     * how the extension interacts with XLEN.
+     */
+#ifndef CONFIG_USER_ONLY
+    if (riscv_has_ext(env, RVJ)) {
+        switch (env->priv) {
+        case PRV_M:
+            if (env->mmte & M_PM_ENABLE) {
+                mask = env->mpmmask;
+                base = env->mpmbase;
+            }
+            break;
+        case PRV_S:
+            if (env->mmte & S_PM_ENABLE) {
+                mask = env->spmmask;
+                base = env->spmbase;
+            }
+            break;
+        case PRV_U:
+            if (env->mmte & U_PM_ENABLE) {
+                mask = env->upmmask;
+                base = env->upmbase;
+            }
+            break;
+        default:
+            g_assert_not_reached();
+        }
+    }
+#endif
+    if (env->xl == MXL_RV32) {
+        env->cur_pmmask = mask & UINT32_MAX;
+        env->cur_pmbase = base & UINT32_MAX;
+    } else {
+        env->cur_pmmask = mask;
+        env->cur_pmbase = base;
+    }
+}
+
 #ifndef CONFIG_USER_ONLY
 static int riscv_cpu_local_irq_pending(CPURISCVState *env)
 {
@@ -331,6 +373,7 @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv)
     /* tlb_flush is unnecessary as mode is contained in mmu_idx */
     env->priv = newpriv;
     env->xl = cpu_recompute_xl(env);
+    riscv_cpu_update_mask(env);
 
     /*
      * Clear the load reservation - otherwise a reservation placed in one
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 3f3afbed21..6e4b8cd56d 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1603,6 +1603,7 @@ static RISCVException write_mmte(CPURISCVState *env, int csrno,
     /* 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);
 
     /* Set XS and SD bits, since PM CSRs are dirty */
     mstatus = env->mstatus | MSTATUS_XS;
@@ -1678,6 +1679,9 @@ static RISCVException write_mpmmask(CPURISCVState *env, int csrno,
     uint64_t mstatus;
 
     env->mpmmask = val;
+    if ((env->priv == PRV_M) && (env->mmte & M_PM_ENABLE)) {
+        env->cur_pmmask = val;
+    }
     env->mmte |= PM_EXT_DIRTY;
 
     /* Set XS and SD bits, since PM CSRs are dirty */
@@ -1703,6 +1707,9 @@ static RISCVException write_spmmask(CPURISCVState *env, int csrno,
         return RISCV_EXCP_NONE;
     }
     env->spmmask = val;
+    if ((env->priv == PRV_S) && (env->mmte & S_PM_ENABLE)) {
+        env->cur_pmmask = val;
+    }
     env->mmte |= PM_EXT_DIRTY;
 
     /* Set XS and SD bits, since PM CSRs are dirty */
@@ -1728,6 +1735,9 @@ static RISCVException write_upmmask(CPURISCVState *env, int csrno,
         return RISCV_EXCP_NONE;
     }
     env->upmmask = val;
+    if ((env->priv == PRV_U) && (env->mmte & U_PM_ENABLE)) {
+        env->cur_pmmask = val;
+    }
     env->mmte |= PM_EXT_DIRTY;
 
     /* Set XS and SD bits, since PM CSRs are dirty */
@@ -1749,6 +1759,9 @@ static RISCVException write_mpmbase(CPURISCVState *env, int csrno,
     uint64_t mstatus;
 
     env->mpmbase = val;
+    if ((env->priv == PRV_M) && (env->mmte & M_PM_ENABLE)) {
+        env->cur_pmbase = val;
+    }
     env->mmte |= PM_EXT_DIRTY;
 
     /* Set XS and SD bits, since PM CSRs are dirty */
@@ -1774,6 +1787,9 @@ static RISCVException write_spmbase(CPURISCVState *env, int csrno,
         return RISCV_EXCP_NONE;
     }
     env->spmbase = val;
+    if ((env->priv == PRV_S) && (env->mmte & S_PM_ENABLE)) {
+        env->cur_pmbase = val;
+    }
     env->mmte |= PM_EXT_DIRTY;
 
     /* Set XS and SD bits, since PM CSRs are dirty */
@@ -1799,6 +1815,9 @@ static RISCVException write_upmbase(CPURISCVState *env, int csrno,
         return RISCV_EXCP_NONE;
     }
     env->upmbase = val;
+    if ((env->priv == PRV_U) && (env->mmte & U_PM_ENABLE)) {
+        env->cur_pmbase = val;
+    }
     env->mmte |= PM_EXT_DIRTY;
 
     /* Set XS and SD bits, since PM CSRs are dirty */
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
index e1d1029e88..58dd7c2fad 100644
--- a/target/riscv/machine.c
+++ b/target/riscv/machine.c
@@ -191,6 +191,7 @@ static int riscv_cpu_post_load(void *opaque, int version_id)
     CPURISCVState *env = &cpu->env;
 
     env->xl = cpu_recompute_xl(env);
+    riscv_cpu_update_mask(env);
     return 0;
 }
 
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v6 11/22] target/riscv: Create current pm fields in env
@ 2022-01-13 11:39   ` LIU Zhiwei
  0 siblings, 0 replies; 60+ messages in thread
From: LIU Zhiwei @ 2022-01-13 11:39 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: Alistair.Francis, palmer, bin.meng, richard.henderson, guoren,
	LIU Zhiwei, Alistair Francis

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/riscv/cpu.c        |  1 +
 target/riscv/cpu.h        |  4 ++++
 target/riscv/cpu_helper.c | 43 +++++++++++++++++++++++++++++++++++++++
 target/riscv/csr.c        | 19 +++++++++++++++++
 target/riscv/machine.c    |  1 +
 5 files changed, 68 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index a21287253a..a4b9ab0d9c 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -416,6 +416,7 @@ static void riscv_cpu_reset(DeviceState *dev)
     env->mmte |= (PM_EXT_INITIAL | MMTE_M_PM_CURRENT);
 #endif
     env->xl = riscv_cpu_mxl(env);
+    riscv_cpu_update_mask(env);
     cs->exception_index = RISCV_EXCP_NONE;
     env->load_res = -1;
     set_default_nan_mode(1, &env->fp_status);
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 65fd849bef..adb455cf09 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -265,6 +265,8 @@ struct CPURISCVState {
     target_ulong upmmask;
     target_ulong upmbase;
 #endif
+    target_ulong cur_pmmask;
+    target_ulong cur_pmbase;
 
     float_status fp_status;
 
@@ -502,6 +504,8 @@ static inline uint32_t vext_get_vlmax(RISCVCPU *cpu, target_ulong vtype)
 void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
                           target_ulong *cs_base, uint32_t *pflags);
 
+void riscv_cpu_update_mask(CPURISCVState *env);
+
 RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
                            target_ulong *ret_value,
                            target_ulong new_value, target_ulong write_mask);
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 2c83eb1f05..e6c95edb18 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -119,6 +119,48 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
     *pflags = flags;
 }
 
+void riscv_cpu_update_mask(CPURISCVState *env)
+{
+    target_ulong mask = -1, base = 0;
+    /*
+     * TODO: Current RVJ spec does not specify
+     * how the extension interacts with XLEN.
+     */
+#ifndef CONFIG_USER_ONLY
+    if (riscv_has_ext(env, RVJ)) {
+        switch (env->priv) {
+        case PRV_M:
+            if (env->mmte & M_PM_ENABLE) {
+                mask = env->mpmmask;
+                base = env->mpmbase;
+            }
+            break;
+        case PRV_S:
+            if (env->mmte & S_PM_ENABLE) {
+                mask = env->spmmask;
+                base = env->spmbase;
+            }
+            break;
+        case PRV_U:
+            if (env->mmte & U_PM_ENABLE) {
+                mask = env->upmmask;
+                base = env->upmbase;
+            }
+            break;
+        default:
+            g_assert_not_reached();
+        }
+    }
+#endif
+    if (env->xl == MXL_RV32) {
+        env->cur_pmmask = mask & UINT32_MAX;
+        env->cur_pmbase = base & UINT32_MAX;
+    } else {
+        env->cur_pmmask = mask;
+        env->cur_pmbase = base;
+    }
+}
+
 #ifndef CONFIG_USER_ONLY
 static int riscv_cpu_local_irq_pending(CPURISCVState *env)
 {
@@ -331,6 +373,7 @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv)
     /* tlb_flush is unnecessary as mode is contained in mmu_idx */
     env->priv = newpriv;
     env->xl = cpu_recompute_xl(env);
+    riscv_cpu_update_mask(env);
 
     /*
      * Clear the load reservation - otherwise a reservation placed in one
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 3f3afbed21..6e4b8cd56d 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1603,6 +1603,7 @@ static RISCVException write_mmte(CPURISCVState *env, int csrno,
     /* 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);
 
     /* Set XS and SD bits, since PM CSRs are dirty */
     mstatus = env->mstatus | MSTATUS_XS;
@@ -1678,6 +1679,9 @@ static RISCVException write_mpmmask(CPURISCVState *env, int csrno,
     uint64_t mstatus;
 
     env->mpmmask = val;
+    if ((env->priv == PRV_M) && (env->mmte & M_PM_ENABLE)) {
+        env->cur_pmmask = val;
+    }
     env->mmte |= PM_EXT_DIRTY;
 
     /* Set XS and SD bits, since PM CSRs are dirty */
@@ -1703,6 +1707,9 @@ static RISCVException write_spmmask(CPURISCVState *env, int csrno,
         return RISCV_EXCP_NONE;
     }
     env->spmmask = val;
+    if ((env->priv == PRV_S) && (env->mmte & S_PM_ENABLE)) {
+        env->cur_pmmask = val;
+    }
     env->mmte |= PM_EXT_DIRTY;
 
     /* Set XS and SD bits, since PM CSRs are dirty */
@@ -1728,6 +1735,9 @@ static RISCVException write_upmmask(CPURISCVState *env, int csrno,
         return RISCV_EXCP_NONE;
     }
     env->upmmask = val;
+    if ((env->priv == PRV_U) && (env->mmte & U_PM_ENABLE)) {
+        env->cur_pmmask = val;
+    }
     env->mmte |= PM_EXT_DIRTY;
 
     /* Set XS and SD bits, since PM CSRs are dirty */
@@ -1749,6 +1759,9 @@ static RISCVException write_mpmbase(CPURISCVState *env, int csrno,
     uint64_t mstatus;
 
     env->mpmbase = val;
+    if ((env->priv == PRV_M) && (env->mmte & M_PM_ENABLE)) {
+        env->cur_pmbase = val;
+    }
     env->mmte |= PM_EXT_DIRTY;
 
     /* Set XS and SD bits, since PM CSRs are dirty */
@@ -1774,6 +1787,9 @@ static RISCVException write_spmbase(CPURISCVState *env, int csrno,
         return RISCV_EXCP_NONE;
     }
     env->spmbase = val;
+    if ((env->priv == PRV_S) && (env->mmte & S_PM_ENABLE)) {
+        env->cur_pmbase = val;
+    }
     env->mmte |= PM_EXT_DIRTY;
 
     /* Set XS and SD bits, since PM CSRs are dirty */
@@ -1799,6 +1815,9 @@ static RISCVException write_upmbase(CPURISCVState *env, int csrno,
         return RISCV_EXCP_NONE;
     }
     env->upmbase = val;
+    if ((env->priv == PRV_U) && (env->mmte & U_PM_ENABLE)) {
+        env->cur_pmbase = val;
+    }
     env->mmte |= PM_EXT_DIRTY;
 
     /* Set XS and SD bits, since PM CSRs are dirty */
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
index e1d1029e88..58dd7c2fad 100644
--- a/target/riscv/machine.c
+++ b/target/riscv/machine.c
@@ -191,6 +191,7 @@ static int riscv_cpu_post_load(void *opaque, int version_id)
     CPURISCVState *env = &cpu->env;
 
     env->xl = cpu_recompute_xl(env);
+    riscv_cpu_update_mask(env);
     return 0;
 }
 
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v6 12/22] target/riscv: Alloc tcg global for cur_pm[mask|base]
  2022-01-13 11:39 ` LIU Zhiwei
@ 2022-01-13 11:39   ` LIU Zhiwei
  -1 siblings, 0 replies; 60+ messages in thread
From: LIU Zhiwei @ 2022-01-13 11:39 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: guoren, bin.meng, richard.henderson, palmer, Alistair Francis,
	LIU Zhiwei

Replace the array of pm_mask/pm_base with scalar variables.
Remove the cached array value in DisasContext.

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
 target/riscv/translate.c | 32 ++++++++------------------------
 1 file changed, 8 insertions(+), 24 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index d8b7c48600..4a8b091790 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -38,8 +38,8 @@ static TCGv_i64 cpu_fpr[32]; /* assume F and D extensions */
 static TCGv load_res;
 static TCGv load_val;
 /* globals for PM CSRs */
-static TCGv pm_mask[4];
-static TCGv pm_base[4];
+static TCGv pm_mask;
+static TCGv pm_base;
 
 #include "exec/gen-icount.h"
 
@@ -107,8 +107,6 @@ typedef struct DisasContext {
     TCGv temp[4];
     /* PointerMasking extension */
     bool pm_enabled;
-    TCGv pm_mask;
-    TCGv pm_base;
 } DisasContext;
 
 static inline bool has_ext(DisasContext *ctx, uint32_t ext)
@@ -401,8 +399,8 @@ static TCGv gen_pm_adjust_address(DisasContext *s, TCGv src)
         return src;
     } else {
         temp = temp_new(s);
-        tcg_gen_andc_tl(temp, src, s->pm_mask);
-        tcg_gen_or_tl(temp, temp, s->pm_base);
+        tcg_gen_andc_tl(temp, src, pm_mask);
+        tcg_gen_or_tl(temp, temp, pm_base);
         return temp;
     }
 }
@@ -925,10 +923,6 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
     ctx->ntemp = 0;
     memset(ctx->temp, 0, sizeof(ctx->temp));
     ctx->pm_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_ENABLED);
-    int priv = tb_flags & TB_FLAGS_PRIV_MMU_MASK;
-    ctx->pm_mask = pm_mask[priv];
-    ctx->pm_base = pm_base[priv];
-
     ctx->zero = tcg_constant_tl(0);
 }
 
@@ -1046,19 +1040,9 @@ void riscv_translate_init(void)
                              "load_res");
     load_val = tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, load_val),
                              "load_val");
-#ifndef CONFIG_USER_ONLY
     /* Assign PM CSRs to tcg globals */
-    pm_mask[PRV_U] =
-      tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, upmmask), "upmmask");
-    pm_base[PRV_U] =
-      tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, upmbase), "upmbase");
-    pm_mask[PRV_S] =
-      tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, spmmask), "spmmask");
-    pm_base[PRV_S] =
-      tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, spmbase), "spmbase");
-    pm_mask[PRV_M] =
-      tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, mpmmask), "mpmmask");
-    pm_base[PRV_M] =
-      tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, mpmbase), "mpmbase");
-#endif
+    pm_mask = tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, cur_pmmask),
+                                 "pmmask");
+    pm_base = tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, cur_pmbase),
+                                 "pmbase");
 }
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v6 12/22] target/riscv: Alloc tcg global for cur_pm[mask|base]
@ 2022-01-13 11:39   ` LIU Zhiwei
  0 siblings, 0 replies; 60+ messages in thread
From: LIU Zhiwei @ 2022-01-13 11:39 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: Alistair.Francis, palmer, bin.meng, richard.henderson, guoren,
	LIU Zhiwei, Alistair Francis

Replace the array of pm_mask/pm_base with scalar variables.
Remove the cached array value in DisasContext.

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
 target/riscv/translate.c | 32 ++++++++------------------------
 1 file changed, 8 insertions(+), 24 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index d8b7c48600..4a8b091790 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -38,8 +38,8 @@ static TCGv_i64 cpu_fpr[32]; /* assume F and D extensions */
 static TCGv load_res;
 static TCGv load_val;
 /* globals for PM CSRs */
-static TCGv pm_mask[4];
-static TCGv pm_base[4];
+static TCGv pm_mask;
+static TCGv pm_base;
 
 #include "exec/gen-icount.h"
 
@@ -107,8 +107,6 @@ typedef struct DisasContext {
     TCGv temp[4];
     /* PointerMasking extension */
     bool pm_enabled;
-    TCGv pm_mask;
-    TCGv pm_base;
 } DisasContext;
 
 static inline bool has_ext(DisasContext *ctx, uint32_t ext)
@@ -401,8 +399,8 @@ static TCGv gen_pm_adjust_address(DisasContext *s, TCGv src)
         return src;
     } else {
         temp = temp_new(s);
-        tcg_gen_andc_tl(temp, src, s->pm_mask);
-        tcg_gen_or_tl(temp, temp, s->pm_base);
+        tcg_gen_andc_tl(temp, src, pm_mask);
+        tcg_gen_or_tl(temp, temp, pm_base);
         return temp;
     }
 }
@@ -925,10 +923,6 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
     ctx->ntemp = 0;
     memset(ctx->temp, 0, sizeof(ctx->temp));
     ctx->pm_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_ENABLED);
-    int priv = tb_flags & TB_FLAGS_PRIV_MMU_MASK;
-    ctx->pm_mask = pm_mask[priv];
-    ctx->pm_base = pm_base[priv];
-
     ctx->zero = tcg_constant_tl(0);
 }
 
@@ -1046,19 +1040,9 @@ void riscv_translate_init(void)
                              "load_res");
     load_val = tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, load_val),
                              "load_val");
-#ifndef CONFIG_USER_ONLY
     /* Assign PM CSRs to tcg globals */
-    pm_mask[PRV_U] =
-      tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, upmmask), "upmmask");
-    pm_base[PRV_U] =
-      tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, upmbase), "upmbase");
-    pm_mask[PRV_S] =
-      tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, spmmask), "spmmask");
-    pm_base[PRV_S] =
-      tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, spmbase), "spmbase");
-    pm_mask[PRV_M] =
-      tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, mpmmask), "mpmmask");
-    pm_base[PRV_M] =
-      tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, mpmbase), "mpmbase");
-#endif
+    pm_mask = tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, cur_pmmask),
+                                 "pmmask");
+    pm_base = tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, cur_pmbase),
+                                 "pmbase");
 }
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v6 13/22] target/riscv: Calculate address according to XLEN
  2022-01-13 11:39 ` LIU Zhiwei
@ 2022-01-13 11:39   ` LIU Zhiwei
  -1 siblings, 0 replies; 60+ messages in thread
From: LIU Zhiwei @ 2022-01-13 11:39 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: guoren, bin.meng, richard.henderson, palmer, Alistair Francis,
	LIU Zhiwei

Define one common function to compute a canonical address from a register
plus offset. Merge gen_pm_adjust_address into this function.

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
 target/riscv/insn_trans/trans_rva.c.inc |  9 +++------
 target/riscv/insn_trans/trans_rvd.c.inc | 19 ++-----------------
 target/riscv/insn_trans/trans_rvf.c.inc | 19 ++-----------------
 target/riscv/insn_trans/trans_rvi.c.inc | 18 ++----------------
 target/riscv/translate.c                | 25 ++++++++++++-------------
 5 files changed, 21 insertions(+), 69 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rva.c.inc b/target/riscv/insn_trans/trans_rva.c.inc
index 86032fa9a7..45db82c9be 100644
--- a/target/riscv/insn_trans/trans_rva.c.inc
+++ b/target/riscv/insn_trans/trans_rva.c.inc
@@ -20,12 +20,11 @@
 
 static bool gen_lr(DisasContext *ctx, arg_atomic *a, MemOp mop)
 {
-    TCGv src1 = get_gpr(ctx, a->rs1, EXT_ZERO);
+    TCGv src1 = get_address(ctx, a->rs1, 0);
 
     if (a->rl) {
         tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
     }
-    src1 = gen_pm_adjust_address(ctx, src1);
     tcg_gen_qemu_ld_tl(load_val, src1, ctx->mem_idx, mop);
     if (a->aq) {
         tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
@@ -44,8 +43,7 @@ static bool gen_sc(DisasContext *ctx, arg_atomic *a, MemOp mop)
     TCGLabel *l1 = gen_new_label();
     TCGLabel *l2 = gen_new_label();
 
-    src1 = get_gpr(ctx, a->rs1, EXT_ZERO);
-    src1 = gen_pm_adjust_address(ctx, src1);
+    src1 = get_address(ctx, a->rs1, 0);
     tcg_gen_brcond_tl(TCG_COND_NE, load_res, src1, l1);
 
     /*
@@ -83,10 +81,9 @@ static bool gen_amo(DisasContext *ctx, arg_atomic *a,
                     MemOp mop)
 {
     TCGv dest = dest_gpr(ctx, a->rd);
-    TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
+    TCGv src1 = get_address(ctx, a->rs1, 0);
     TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE);
 
-    src1 = gen_pm_adjust_address(ctx, src1);
     func(dest, src1, src2, ctx->mem_idx, mop);
 
     gen_set_gpr(ctx, a->rd, dest);
diff --git a/target/riscv/insn_trans/trans_rvd.c.inc b/target/riscv/insn_trans/trans_rvd.c.inc
index ed444b042a..091ed3a8ad 100644
--- a/target/riscv/insn_trans/trans_rvd.c.inc
+++ b/target/riscv/insn_trans/trans_rvd.c.inc
@@ -25,14 +25,7 @@ static bool trans_fld(DisasContext *ctx, arg_fld *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVD);
 
-    addr = get_gpr(ctx, a->rs1, EXT_NONE);
-    if (a->imm) {
-        TCGv temp = temp_new(ctx);
-        tcg_gen_addi_tl(temp, addr, a->imm);
-        addr = temp;
-    }
-    addr = gen_pm_adjust_address(ctx, addr);
-
+    addr = get_address(ctx, a->rs1, a->imm);
     tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], addr, ctx->mem_idx, MO_TEUQ);
 
     mark_fs_dirty(ctx);
@@ -46,16 +39,8 @@ static bool trans_fsd(DisasContext *ctx, arg_fsd *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVD);
 
-    addr = get_gpr(ctx, a->rs1, EXT_NONE);
-    if (a->imm) {
-        TCGv temp = temp_new(ctx);
-        tcg_gen_addi_tl(temp, addr, a->imm);
-        addr = temp;
-    }
-    addr = gen_pm_adjust_address(ctx, addr);
-
+    addr = get_address(ctx, a->rs1, a->imm);
     tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], addr, ctx->mem_idx, MO_TEUQ);
-
     return true;
 }
 
diff --git a/target/riscv/insn_trans/trans_rvf.c.inc b/target/riscv/insn_trans/trans_rvf.c.inc
index b5459249c4..0aac87f7db 100644
--- a/target/riscv/insn_trans/trans_rvf.c.inc
+++ b/target/riscv/insn_trans/trans_rvf.c.inc
@@ -31,14 +31,7 @@ static bool trans_flw(DisasContext *ctx, arg_flw *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVF);
 
-    addr = get_gpr(ctx, a->rs1, EXT_NONE);
-    if (a->imm) {
-        TCGv temp = temp_new(ctx);
-        tcg_gen_addi_tl(temp, addr, a->imm);
-        addr = temp;
-    }
-    addr = gen_pm_adjust_address(ctx, addr);
-
+    addr = get_address(ctx, a->rs1, a->imm);
     dest = cpu_fpr[a->rd];
     tcg_gen_qemu_ld_i64(dest, addr, ctx->mem_idx, MO_TEUL);
     gen_nanbox_s(dest, dest);
@@ -54,16 +47,8 @@ static bool trans_fsw(DisasContext *ctx, arg_fsw *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVF);
 
-    addr = get_gpr(ctx, a->rs1, EXT_NONE);
-    if (a->imm) {
-        TCGv temp = tcg_temp_new();
-        tcg_gen_addi_tl(temp, addr, a->imm);
-        addr = temp;
-    }
-    addr = gen_pm_adjust_address(ctx, addr);
-
+    addr = get_address(ctx, a->rs1, a->imm);
     tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], addr, ctx->mem_idx, MO_TEUL);
-
     return true;
 }
 
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
index 631bc1f09e..3cd1b3f877 100644
--- a/target/riscv/insn_trans/trans_rvi.c.inc
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
@@ -226,14 +226,7 @@ static bool trans_bgeu(DisasContext *ctx, arg_bgeu *a)
 static bool gen_load_tl(DisasContext *ctx, arg_lb *a, MemOp memop)
 {
     TCGv dest = dest_gpr(ctx, a->rd);
-    TCGv addr = get_gpr(ctx, a->rs1, EXT_NONE);
-
-    if (a->imm) {
-        TCGv temp = temp_new(ctx);
-        tcg_gen_addi_tl(temp, addr, a->imm);
-        addr = temp;
-    }
-    addr = gen_pm_adjust_address(ctx, addr);
+    TCGv addr = get_address(ctx, a->rs1, a->imm);
 
     tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, memop);
     gen_set_gpr(ctx, a->rd, dest);
@@ -330,16 +323,9 @@ static bool trans_ldu(DisasContext *ctx, arg_ldu *a)
 
 static bool gen_store_tl(DisasContext *ctx, arg_sb *a, MemOp memop)
 {
-    TCGv addr = get_gpr(ctx, a->rs1, EXT_NONE);
+    TCGv addr = get_address(ctx, a->rs1, a->imm);
     TCGv data = get_gpr(ctx, a->rs2, EXT_NONE);
 
-    if (a->imm) {
-        TCGv temp = temp_new(ctx);
-        tcg_gen_addi_tl(temp, addr, a->imm);
-        addr = temp;
-    }
-    addr = gen_pm_adjust_address(ctx, addr);
-
     tcg_gen_qemu_st_tl(data, addr, ctx->mem_idx, memop);
     return true;
 }
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 4a8b091790..a1d1018b1b 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -388,21 +388,20 @@ static void gen_jal(DisasContext *ctx, int rd, target_ulong imm)
     ctx->base.is_jmp = DISAS_NORETURN;
 }
 
-/*
- * Generates address adjustment for PointerMasking
- */
-static TCGv gen_pm_adjust_address(DisasContext *s, TCGv src)
+/* Compute a canonical address from a register plus offset. */
+static TCGv get_address(DisasContext *ctx, int rs1, int imm)
 {
-    TCGv temp;
-    if (!s->pm_enabled) {
-        /* Load unmodified address */
-        return src;
-    } else {
-        temp = temp_new(s);
-        tcg_gen_andc_tl(temp, src, pm_mask);
-        tcg_gen_or_tl(temp, temp, pm_base);
-        return temp;
+    TCGv addr = temp_new(ctx);
+    TCGv src1 = get_gpr(ctx, rs1, EXT_NONE);
+
+    tcg_gen_addi_tl(addr, src1, imm);
+    if (ctx->pm_enabled) {
+        tcg_gen_and_tl(addr, addr, pm_mask);
+        tcg_gen_or_tl(addr, addr, pm_base);
+    } else if (get_xl(ctx) == MXL_RV32) {
+        tcg_gen_ext32u_tl(addr, addr);
     }
+    return addr;
 }
 
 #ifndef CONFIG_USER_ONLY
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v6 13/22] target/riscv: Calculate address according to XLEN
@ 2022-01-13 11:39   ` LIU Zhiwei
  0 siblings, 0 replies; 60+ messages in thread
From: LIU Zhiwei @ 2022-01-13 11:39 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: Alistair.Francis, palmer, bin.meng, richard.henderson, guoren,
	LIU Zhiwei, Alistair Francis

Define one common function to compute a canonical address from a register
plus offset. Merge gen_pm_adjust_address into this function.

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
 target/riscv/insn_trans/trans_rva.c.inc |  9 +++------
 target/riscv/insn_trans/trans_rvd.c.inc | 19 ++-----------------
 target/riscv/insn_trans/trans_rvf.c.inc | 19 ++-----------------
 target/riscv/insn_trans/trans_rvi.c.inc | 18 ++----------------
 target/riscv/translate.c                | 25 ++++++++++++-------------
 5 files changed, 21 insertions(+), 69 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rva.c.inc b/target/riscv/insn_trans/trans_rva.c.inc
index 86032fa9a7..45db82c9be 100644
--- a/target/riscv/insn_trans/trans_rva.c.inc
+++ b/target/riscv/insn_trans/trans_rva.c.inc
@@ -20,12 +20,11 @@
 
 static bool gen_lr(DisasContext *ctx, arg_atomic *a, MemOp mop)
 {
-    TCGv src1 = get_gpr(ctx, a->rs1, EXT_ZERO);
+    TCGv src1 = get_address(ctx, a->rs1, 0);
 
     if (a->rl) {
         tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
     }
-    src1 = gen_pm_adjust_address(ctx, src1);
     tcg_gen_qemu_ld_tl(load_val, src1, ctx->mem_idx, mop);
     if (a->aq) {
         tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
@@ -44,8 +43,7 @@ static bool gen_sc(DisasContext *ctx, arg_atomic *a, MemOp mop)
     TCGLabel *l1 = gen_new_label();
     TCGLabel *l2 = gen_new_label();
 
-    src1 = get_gpr(ctx, a->rs1, EXT_ZERO);
-    src1 = gen_pm_adjust_address(ctx, src1);
+    src1 = get_address(ctx, a->rs1, 0);
     tcg_gen_brcond_tl(TCG_COND_NE, load_res, src1, l1);
 
     /*
@@ -83,10 +81,9 @@ static bool gen_amo(DisasContext *ctx, arg_atomic *a,
                     MemOp mop)
 {
     TCGv dest = dest_gpr(ctx, a->rd);
-    TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
+    TCGv src1 = get_address(ctx, a->rs1, 0);
     TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE);
 
-    src1 = gen_pm_adjust_address(ctx, src1);
     func(dest, src1, src2, ctx->mem_idx, mop);
 
     gen_set_gpr(ctx, a->rd, dest);
diff --git a/target/riscv/insn_trans/trans_rvd.c.inc b/target/riscv/insn_trans/trans_rvd.c.inc
index ed444b042a..091ed3a8ad 100644
--- a/target/riscv/insn_trans/trans_rvd.c.inc
+++ b/target/riscv/insn_trans/trans_rvd.c.inc
@@ -25,14 +25,7 @@ static bool trans_fld(DisasContext *ctx, arg_fld *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVD);
 
-    addr = get_gpr(ctx, a->rs1, EXT_NONE);
-    if (a->imm) {
-        TCGv temp = temp_new(ctx);
-        tcg_gen_addi_tl(temp, addr, a->imm);
-        addr = temp;
-    }
-    addr = gen_pm_adjust_address(ctx, addr);
-
+    addr = get_address(ctx, a->rs1, a->imm);
     tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], addr, ctx->mem_idx, MO_TEUQ);
 
     mark_fs_dirty(ctx);
@@ -46,16 +39,8 @@ static bool trans_fsd(DisasContext *ctx, arg_fsd *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVD);
 
-    addr = get_gpr(ctx, a->rs1, EXT_NONE);
-    if (a->imm) {
-        TCGv temp = temp_new(ctx);
-        tcg_gen_addi_tl(temp, addr, a->imm);
-        addr = temp;
-    }
-    addr = gen_pm_adjust_address(ctx, addr);
-
+    addr = get_address(ctx, a->rs1, a->imm);
     tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], addr, ctx->mem_idx, MO_TEUQ);
-
     return true;
 }
 
diff --git a/target/riscv/insn_trans/trans_rvf.c.inc b/target/riscv/insn_trans/trans_rvf.c.inc
index b5459249c4..0aac87f7db 100644
--- a/target/riscv/insn_trans/trans_rvf.c.inc
+++ b/target/riscv/insn_trans/trans_rvf.c.inc
@@ -31,14 +31,7 @@ static bool trans_flw(DisasContext *ctx, arg_flw *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVF);
 
-    addr = get_gpr(ctx, a->rs1, EXT_NONE);
-    if (a->imm) {
-        TCGv temp = temp_new(ctx);
-        tcg_gen_addi_tl(temp, addr, a->imm);
-        addr = temp;
-    }
-    addr = gen_pm_adjust_address(ctx, addr);
-
+    addr = get_address(ctx, a->rs1, a->imm);
     dest = cpu_fpr[a->rd];
     tcg_gen_qemu_ld_i64(dest, addr, ctx->mem_idx, MO_TEUL);
     gen_nanbox_s(dest, dest);
@@ -54,16 +47,8 @@ static bool trans_fsw(DisasContext *ctx, arg_fsw *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVF);
 
-    addr = get_gpr(ctx, a->rs1, EXT_NONE);
-    if (a->imm) {
-        TCGv temp = tcg_temp_new();
-        tcg_gen_addi_tl(temp, addr, a->imm);
-        addr = temp;
-    }
-    addr = gen_pm_adjust_address(ctx, addr);
-
+    addr = get_address(ctx, a->rs1, a->imm);
     tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], addr, ctx->mem_idx, MO_TEUL);
-
     return true;
 }
 
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
index 631bc1f09e..3cd1b3f877 100644
--- a/target/riscv/insn_trans/trans_rvi.c.inc
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
@@ -226,14 +226,7 @@ static bool trans_bgeu(DisasContext *ctx, arg_bgeu *a)
 static bool gen_load_tl(DisasContext *ctx, arg_lb *a, MemOp memop)
 {
     TCGv dest = dest_gpr(ctx, a->rd);
-    TCGv addr = get_gpr(ctx, a->rs1, EXT_NONE);
-
-    if (a->imm) {
-        TCGv temp = temp_new(ctx);
-        tcg_gen_addi_tl(temp, addr, a->imm);
-        addr = temp;
-    }
-    addr = gen_pm_adjust_address(ctx, addr);
+    TCGv addr = get_address(ctx, a->rs1, a->imm);
 
     tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, memop);
     gen_set_gpr(ctx, a->rd, dest);
@@ -330,16 +323,9 @@ static bool trans_ldu(DisasContext *ctx, arg_ldu *a)
 
 static bool gen_store_tl(DisasContext *ctx, arg_sb *a, MemOp memop)
 {
-    TCGv addr = get_gpr(ctx, a->rs1, EXT_NONE);
+    TCGv addr = get_address(ctx, a->rs1, a->imm);
     TCGv data = get_gpr(ctx, a->rs2, EXT_NONE);
 
-    if (a->imm) {
-        TCGv temp = temp_new(ctx);
-        tcg_gen_addi_tl(temp, addr, a->imm);
-        addr = temp;
-    }
-    addr = gen_pm_adjust_address(ctx, addr);
-
     tcg_gen_qemu_st_tl(data, addr, ctx->mem_idx, memop);
     return true;
 }
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 4a8b091790..a1d1018b1b 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -388,21 +388,20 @@ static void gen_jal(DisasContext *ctx, int rd, target_ulong imm)
     ctx->base.is_jmp = DISAS_NORETURN;
 }
 
-/*
- * Generates address adjustment for PointerMasking
- */
-static TCGv gen_pm_adjust_address(DisasContext *s, TCGv src)
+/* Compute a canonical address from a register plus offset. */
+static TCGv get_address(DisasContext *ctx, int rs1, int imm)
 {
-    TCGv temp;
-    if (!s->pm_enabled) {
-        /* Load unmodified address */
-        return src;
-    } else {
-        temp = temp_new(s);
-        tcg_gen_andc_tl(temp, src, pm_mask);
-        tcg_gen_or_tl(temp, temp, pm_base);
-        return temp;
+    TCGv addr = temp_new(ctx);
+    TCGv src1 = get_gpr(ctx, rs1, EXT_NONE);
+
+    tcg_gen_addi_tl(addr, src1, imm);
+    if (ctx->pm_enabled) {
+        tcg_gen_and_tl(addr, addr, pm_mask);
+        tcg_gen_or_tl(addr, addr, pm_base);
+    } else if (get_xl(ctx) == MXL_RV32) {
+        tcg_gen_ext32u_tl(addr, addr);
     }
+    return addr;
 }
 
 #ifndef CONFIG_USER_ONLY
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v6 14/22] target/riscv: Split pm_enabled into mask and base
  2022-01-13 11:39 ` LIU Zhiwei
@ 2022-01-13 11:39   ` LIU Zhiwei
  -1 siblings, 0 replies; 60+ messages in thread
From: LIU Zhiwei @ 2022-01-13 11:39 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: guoren, bin.meng, richard.henderson, palmer, Alistair Francis,
	LIU Zhiwei

Use cached cur_pmmask and cur_pmbase to infer the
current PM mode.

This may decrease the TCG IR by one when pm_enabled
is true and pm_base_enabled is false.

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
 target/riscv/cpu.h        |  3 ++-
 target/riscv/cpu_helper.c | 24 ++++++------------------
 target/riscv/translate.c  | 12 ++++++++----
 3 files changed, 16 insertions(+), 23 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index adb455cf09..41dcf9775a 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -435,7 +435,8 @@ FIELD(TB_FLAGS, MSTATUS_HS_VS, 18, 2)
 /* The combination of MXL/SXL/UXL that applies to the current cpu mode. */
 FIELD(TB_FLAGS, XL, 20, 2)
 /* If PointerMasking should be applied */
-FIELD(TB_FLAGS, PM_ENABLED, 22, 1)
+FIELD(TB_FLAGS, PM_MASK_ENABLED, 22, 1)
+FIELD(TB_FLAGS, PM_BASE_ENABLED, 23, 1)
 
 #ifdef TARGET_RISCV32
 #define riscv_cpu_mxl(env)  ((void)(env), MXL_RV32)
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index e6c95edb18..b781e96657 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -94,27 +94,15 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
         flags = FIELD_DP32(flags, TB_FLAGS, MSTATUS_HS_VS,
                            get_field(env->mstatus_hs, MSTATUS_VS));
     }
-    if (riscv_has_ext(env, RVJ)) {
-        int priv = flags & TB_FLAGS_PRIV_MMU_MASK;
-        bool pm_enabled = false;
-        switch (priv) {
-        case PRV_U:
-            pm_enabled = env->mmte & U_PM_ENABLE;
-            break;
-        case PRV_S:
-            pm_enabled = env->mmte & S_PM_ENABLE;
-            break;
-        case PRV_M:
-            pm_enabled = env->mmte & M_PM_ENABLE;
-            break;
-        default:
-            g_assert_not_reached();
-        }
-        flags = FIELD_DP32(flags, TB_FLAGS, PM_ENABLED, pm_enabled);
-    }
 #endif
 
     flags = FIELD_DP32(flags, TB_FLAGS, XL, env->xl);
+    if (env->cur_pmmask < (env->xl == MXL_RV32 ? UINT32_MAX : UINT64_MAX)) {
+        flags = FIELD_DP32(flags, TB_FLAGS, PM_MASK_ENABLED, 1);
+    }
+    if (env->cur_pmbase != 0) {
+        flags = FIELD_DP32(flags, TB_FLAGS, PM_BASE_ENABLED, 1);
+    }
 
     *pflags = flags;
 }
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index a1d1018b1b..a0caf306c9 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -106,7 +106,8 @@ typedef struct DisasContext {
     /* Space for 3 operands plus 1 extra for address computation. */
     TCGv temp[4];
     /* PointerMasking extension */
-    bool pm_enabled;
+    bool pm_mask_enabled;
+    bool pm_base_enabled;
 } DisasContext;
 
 static inline bool has_ext(DisasContext *ctx, uint32_t ext)
@@ -395,12 +396,14 @@ static TCGv get_address(DisasContext *ctx, int rs1, int imm)
     TCGv src1 = get_gpr(ctx, rs1, EXT_NONE);
 
     tcg_gen_addi_tl(addr, src1, imm);
-    if (ctx->pm_enabled) {
+    if (ctx->pm_mask_enabled) {
         tcg_gen_and_tl(addr, addr, pm_mask);
-        tcg_gen_or_tl(addr, addr, pm_base);
     } else if (get_xl(ctx) == MXL_RV32) {
         tcg_gen_ext32u_tl(addr, addr);
     }
+    if (ctx->pm_base_enabled) {
+        tcg_gen_or_tl(addr, addr, pm_base);
+    }
     return addr;
 }
 
@@ -921,7 +924,8 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
     ctx->cs = cs;
     ctx->ntemp = 0;
     memset(ctx->temp, 0, sizeof(ctx->temp));
-    ctx->pm_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_ENABLED);
+    ctx->pm_mask_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_MASK_ENABLED);
+    ctx->pm_base_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_BASE_ENABLED);
     ctx->zero = tcg_constant_tl(0);
 }
 
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v6 14/22] target/riscv: Split pm_enabled into mask and base
@ 2022-01-13 11:39   ` LIU Zhiwei
  0 siblings, 0 replies; 60+ messages in thread
From: LIU Zhiwei @ 2022-01-13 11:39 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: Alistair.Francis, palmer, bin.meng, richard.henderson, guoren,
	LIU Zhiwei, Alistair Francis

Use cached cur_pmmask and cur_pmbase to infer the
current PM mode.

This may decrease the TCG IR by one when pm_enabled
is true and pm_base_enabled is false.

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
 target/riscv/cpu.h        |  3 ++-
 target/riscv/cpu_helper.c | 24 ++++++------------------
 target/riscv/translate.c  | 12 ++++++++----
 3 files changed, 16 insertions(+), 23 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index adb455cf09..41dcf9775a 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -435,7 +435,8 @@ FIELD(TB_FLAGS, MSTATUS_HS_VS, 18, 2)
 /* The combination of MXL/SXL/UXL that applies to the current cpu mode. */
 FIELD(TB_FLAGS, XL, 20, 2)
 /* If PointerMasking should be applied */
-FIELD(TB_FLAGS, PM_ENABLED, 22, 1)
+FIELD(TB_FLAGS, PM_MASK_ENABLED, 22, 1)
+FIELD(TB_FLAGS, PM_BASE_ENABLED, 23, 1)
 
 #ifdef TARGET_RISCV32
 #define riscv_cpu_mxl(env)  ((void)(env), MXL_RV32)
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index e6c95edb18..b781e96657 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -94,27 +94,15 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
         flags = FIELD_DP32(flags, TB_FLAGS, MSTATUS_HS_VS,
                            get_field(env->mstatus_hs, MSTATUS_VS));
     }
-    if (riscv_has_ext(env, RVJ)) {
-        int priv = flags & TB_FLAGS_PRIV_MMU_MASK;
-        bool pm_enabled = false;
-        switch (priv) {
-        case PRV_U:
-            pm_enabled = env->mmte & U_PM_ENABLE;
-            break;
-        case PRV_S:
-            pm_enabled = env->mmte & S_PM_ENABLE;
-            break;
-        case PRV_M:
-            pm_enabled = env->mmte & M_PM_ENABLE;
-            break;
-        default:
-            g_assert_not_reached();
-        }
-        flags = FIELD_DP32(flags, TB_FLAGS, PM_ENABLED, pm_enabled);
-    }
 #endif
 
     flags = FIELD_DP32(flags, TB_FLAGS, XL, env->xl);
+    if (env->cur_pmmask < (env->xl == MXL_RV32 ? UINT32_MAX : UINT64_MAX)) {
+        flags = FIELD_DP32(flags, TB_FLAGS, PM_MASK_ENABLED, 1);
+    }
+    if (env->cur_pmbase != 0) {
+        flags = FIELD_DP32(flags, TB_FLAGS, PM_BASE_ENABLED, 1);
+    }
 
     *pflags = flags;
 }
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index a1d1018b1b..a0caf306c9 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -106,7 +106,8 @@ typedef struct DisasContext {
     /* Space for 3 operands plus 1 extra for address computation. */
     TCGv temp[4];
     /* PointerMasking extension */
-    bool pm_enabled;
+    bool pm_mask_enabled;
+    bool pm_base_enabled;
 } DisasContext;
 
 static inline bool has_ext(DisasContext *ctx, uint32_t ext)
@@ -395,12 +396,14 @@ static TCGv get_address(DisasContext *ctx, int rs1, int imm)
     TCGv src1 = get_gpr(ctx, rs1, EXT_NONE);
 
     tcg_gen_addi_tl(addr, src1, imm);
-    if (ctx->pm_enabled) {
+    if (ctx->pm_mask_enabled) {
         tcg_gen_and_tl(addr, addr, pm_mask);
-        tcg_gen_or_tl(addr, addr, pm_base);
     } else if (get_xl(ctx) == MXL_RV32) {
         tcg_gen_ext32u_tl(addr, addr);
     }
+    if (ctx->pm_base_enabled) {
+        tcg_gen_or_tl(addr, addr, pm_base);
+    }
     return addr;
 }
 
@@ -921,7 +924,8 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
     ctx->cs = cs;
     ctx->ntemp = 0;
     memset(ctx->temp, 0, sizeof(ctx->temp));
-    ctx->pm_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_ENABLED);
+    ctx->pm_mask_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_MASK_ENABLED);
+    ctx->pm_base_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_BASE_ENABLED);
     ctx->zero = tcg_constant_tl(0);
 }
 
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v6 15/22] target/riscv: Split out the vill from vtype
  2022-01-13 11:39 ` LIU Zhiwei
@ 2022-01-13 11:39   ` LIU Zhiwei
  -1 siblings, 0 replies; 60+ messages in thread
From: LIU Zhiwei @ 2022-01-13 11:39 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: guoren, bin.meng, richard.henderson, palmer, Alistair Francis,
	LIU Zhiwei

We need not specially process vtype when XLEN changes.

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
 target/riscv/cpu.h           |  1 +
 target/riscv/cpu_helper.c    |  3 +--
 target/riscv/csr.c           | 13 ++++++++++++-
 target/riscv/machine.c       |  5 +++--
 target/riscv/vector_helper.c |  3 ++-
 5 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 41dcf9775a..abf217e34f 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -124,6 +124,7 @@ struct CPURISCVState {
     target_ulong vl;
     target_ulong vstart;
     target_ulong vtype;
+    bool vill;
 
     target_ulong pc;
     target_ulong load_res;
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index b781e96657..bebcfcd009 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -57,8 +57,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
         uint32_t maxsz = vlmax << sew;
         bool vl_eq_vlmax = (env->vstart == 0) && (vlmax == env->vl) &&
                            (maxsz >= 8);
-        flags = FIELD_DP32(flags, TB_FLAGS, VILL,
-                    FIELD_EX64(env->vtype, VTYPE, VILL));
+        flags = FIELD_DP32(flags, TB_FLAGS, VILL, env->vill);
         flags = FIELD_DP32(flags, TB_FLAGS, SEW, sew);
         flags = FIELD_DP32(flags, TB_FLAGS, LMUL,
                     FIELD_EX64(env->vtype, VTYPE, VLMUL));
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 6e4b8cd56d..8e67ff7c54 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -279,7 +279,18 @@ static RISCVException write_fcsr(CPURISCVState *env, int csrno,
 static RISCVException read_vtype(CPURISCVState *env, int csrno,
                                  target_ulong *val)
 {
-    *val = env->vtype;
+    uint64_t vill;
+    switch (env->xl) {
+    case MXL_RV32:
+        vill = (uint32_t)env->vill << 31;
+        break;
+    case MXL_RV64:
+        vill = (uint64_t)env->vill << 63;
+        break;
+    default:
+        g_assert_not_reached();
+    }
+    *val = (target_ulong)vill | env->vtype;
     return RISCV_EXCP_NONE;
 }
 
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
index 58dd7c2fad..8cea167bca 100644
--- a/target/riscv/machine.c
+++ b/target/riscv/machine.c
@@ -124,8 +124,8 @@ static bool vector_needed(void *opaque)
 
 static const VMStateDescription vmstate_vector = {
     .name = "cpu/vector",
-    .version_id = 1,
-    .minimum_version_id = 1,
+    .version_id = 2,
+    .minimum_version_id = 2,
     .needed = vector_needed,
     .fields = (VMStateField[]) {
             VMSTATE_UINT64_ARRAY(env.vreg, RISCVCPU, 32 * RV_VLEN_MAX / 64),
@@ -134,6 +134,7 @@ static const VMStateDescription vmstate_vector = {
             VMSTATE_UINTTL(env.vl, RISCVCPU),
             VMSTATE_UINTTL(env.vstart, RISCVCPU),
             VMSTATE_UINTTL(env.vtype, RISCVCPU),
+            VMSTATE_BOOL(env.vill, RISCVCPU),
             VMSTATE_END_OF_LIST()
         }
 };
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index ad505ec9b2..a9484c22ea 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -52,7 +52,8 @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
         || (ediv != 0)
         || (reserved != 0)) {
         /* only set vill bit. */
-        env->vtype = FIELD_DP64(0, VTYPE, VILL, 1);
+        env->vill = 1;
+        env->vtype = 0;
         env->vl = 0;
         env->vstart = 0;
         return 0;
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v6 15/22] target/riscv: Split out the vill from vtype
@ 2022-01-13 11:39   ` LIU Zhiwei
  0 siblings, 0 replies; 60+ messages in thread
From: LIU Zhiwei @ 2022-01-13 11:39 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: Alistair.Francis, palmer, bin.meng, richard.henderson, guoren,
	LIU Zhiwei, Alistair Francis

We need not specially process vtype when XLEN changes.

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
 target/riscv/cpu.h           |  1 +
 target/riscv/cpu_helper.c    |  3 +--
 target/riscv/csr.c           | 13 ++++++++++++-
 target/riscv/machine.c       |  5 +++--
 target/riscv/vector_helper.c |  3 ++-
 5 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 41dcf9775a..abf217e34f 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -124,6 +124,7 @@ struct CPURISCVState {
     target_ulong vl;
     target_ulong vstart;
     target_ulong vtype;
+    bool vill;
 
     target_ulong pc;
     target_ulong load_res;
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index b781e96657..bebcfcd009 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -57,8 +57,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
         uint32_t maxsz = vlmax << sew;
         bool vl_eq_vlmax = (env->vstart == 0) && (vlmax == env->vl) &&
                            (maxsz >= 8);
-        flags = FIELD_DP32(flags, TB_FLAGS, VILL,
-                    FIELD_EX64(env->vtype, VTYPE, VILL));
+        flags = FIELD_DP32(flags, TB_FLAGS, VILL, env->vill);
         flags = FIELD_DP32(flags, TB_FLAGS, SEW, sew);
         flags = FIELD_DP32(flags, TB_FLAGS, LMUL,
                     FIELD_EX64(env->vtype, VTYPE, VLMUL));
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 6e4b8cd56d..8e67ff7c54 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -279,7 +279,18 @@ static RISCVException write_fcsr(CPURISCVState *env, int csrno,
 static RISCVException read_vtype(CPURISCVState *env, int csrno,
                                  target_ulong *val)
 {
-    *val = env->vtype;
+    uint64_t vill;
+    switch (env->xl) {
+    case MXL_RV32:
+        vill = (uint32_t)env->vill << 31;
+        break;
+    case MXL_RV64:
+        vill = (uint64_t)env->vill << 63;
+        break;
+    default:
+        g_assert_not_reached();
+    }
+    *val = (target_ulong)vill | env->vtype;
     return RISCV_EXCP_NONE;
 }
 
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
index 58dd7c2fad..8cea167bca 100644
--- a/target/riscv/machine.c
+++ b/target/riscv/machine.c
@@ -124,8 +124,8 @@ static bool vector_needed(void *opaque)
 
 static const VMStateDescription vmstate_vector = {
     .name = "cpu/vector",
-    .version_id = 1,
-    .minimum_version_id = 1,
+    .version_id = 2,
+    .minimum_version_id = 2,
     .needed = vector_needed,
     .fields = (VMStateField[]) {
             VMSTATE_UINT64_ARRAY(env.vreg, RISCVCPU, 32 * RV_VLEN_MAX / 64),
@@ -134,6 +134,7 @@ static const VMStateDescription vmstate_vector = {
             VMSTATE_UINTTL(env.vl, RISCVCPU),
             VMSTATE_UINTTL(env.vstart, RISCVCPU),
             VMSTATE_UINTTL(env.vtype, RISCVCPU),
+            VMSTATE_BOOL(env.vill, RISCVCPU),
             VMSTATE_END_OF_LIST()
         }
 };
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index ad505ec9b2..a9484c22ea 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -52,7 +52,8 @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
         || (ediv != 0)
         || (reserved != 0)) {
         /* only set vill bit. */
-        env->vtype = FIELD_DP64(0, VTYPE, VILL, 1);
+        env->vill = 1;
+        env->vtype = 0;
         env->vl = 0;
         env->vstart = 0;
         return 0;
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v6 16/22] target/riscv: Adjust vsetvl according to XLEN
  2022-01-13 11:39 ` LIU Zhiwei
@ 2022-01-13 11:39   ` LIU Zhiwei
  -1 siblings, 0 replies; 60+ messages in thread
From: LIU Zhiwei @ 2022-01-13 11:39 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: guoren, bin.meng, richard.henderson, palmer, Alistair Francis,
	LIU Zhiwei

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
 target/riscv/cpu.h           | 5 +++++
 target/riscv/vector_helper.c | 7 +++++--
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index abf217e34f..645a1b3f6c 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -478,6 +478,11 @@ static inline RISCVMXL cpu_recompute_xl(CPURISCVState *env)
 }
 #endif
 
+static inline int riscv_cpu_xlen(CPURISCVState *env)
+{
+    return 16 << env->xl;
+}
+
 /*
  * Encode LMUL to lmul as follows:
  *     LMUL    vlmul    lmul
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index a9484c22ea..8b7c9ec890 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -36,8 +36,11 @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
     uint64_t lmul = FIELD_EX64(s2, VTYPE, VLMUL);
     uint16_t sew = 8 << FIELD_EX64(s2, VTYPE, VSEW);
     uint8_t ediv = FIELD_EX64(s2, VTYPE, VEDIV);
-    bool vill = FIELD_EX64(s2, VTYPE, VILL);
-    target_ulong reserved = FIELD_EX64(s2, VTYPE, RESERVED);
+    int xlen = riscv_cpu_xlen(env);
+    bool vill = (s2 >> (xlen - 1)) & 0x1;
+    target_ulong reserved = s2 &
+                            MAKE_64BIT_MASK(R_VTYPE_RESERVED_SHIFT,
+                                            xlen - 1 - R_VTYPE_RESERVED_SHIFT);
 
     if (lmul & 4) {
         /* Fractional LMUL. */
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v6 16/22] target/riscv: Adjust vsetvl according to XLEN
@ 2022-01-13 11:39   ` LIU Zhiwei
  0 siblings, 0 replies; 60+ messages in thread
From: LIU Zhiwei @ 2022-01-13 11:39 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: Alistair.Francis, palmer, bin.meng, richard.henderson, guoren,
	LIU Zhiwei, Alistair Francis

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
 target/riscv/cpu.h           | 5 +++++
 target/riscv/vector_helper.c | 7 +++++--
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index abf217e34f..645a1b3f6c 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -478,6 +478,11 @@ static inline RISCVMXL cpu_recompute_xl(CPURISCVState *env)
 }
 #endif
 
+static inline int riscv_cpu_xlen(CPURISCVState *env)
+{
+    return 16 << env->xl;
+}
+
 /*
  * Encode LMUL to lmul as follows:
  *     LMUL    vlmul    lmul
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index a9484c22ea..8b7c9ec890 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -36,8 +36,11 @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
     uint64_t lmul = FIELD_EX64(s2, VTYPE, VLMUL);
     uint16_t sew = 8 << FIELD_EX64(s2, VTYPE, VSEW);
     uint8_t ediv = FIELD_EX64(s2, VTYPE, VEDIV);
-    bool vill = FIELD_EX64(s2, VTYPE, VILL);
-    target_ulong reserved = FIELD_EX64(s2, VTYPE, RESERVED);
+    int xlen = riscv_cpu_xlen(env);
+    bool vill = (s2 >> (xlen - 1)) & 0x1;
+    target_ulong reserved = s2 &
+                            MAKE_64BIT_MASK(R_VTYPE_RESERVED_SHIFT,
+                                            xlen - 1 - R_VTYPE_RESERVED_SHIFT);
 
     if (lmul & 4) {
         /* Fractional LMUL. */
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v6 17/22] target/riscv: Remove VILL field in VTYPE
  2022-01-13 11:39 ` LIU Zhiwei
@ 2022-01-13 11:39   ` LIU Zhiwei
  -1 siblings, 0 replies; 60+ messages in thread
From: LIU Zhiwei @ 2022-01-13 11:39 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: guoren, bin.meng, richard.henderson, palmer, Alistair Francis,
	LIU Zhiwei

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
Acked-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
 target/riscv/cpu.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 645a1b3f6c..85eb5c63cf 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -110,7 +110,6 @@ FIELD(VTYPE, VTA, 6, 1)
 FIELD(VTYPE, VMA, 7, 1)
 FIELD(VTYPE, VEDIV, 8, 2)
 FIELD(VTYPE, RESERVED, 10, sizeof(target_ulong) * 8 - 11)
-FIELD(VTYPE, VILL, sizeof(target_ulong) * 8 - 1, 1)
 
 struct CPURISCVState {
     target_ulong gpr[32];
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v6 17/22] target/riscv: Remove VILL field in VTYPE
@ 2022-01-13 11:39   ` LIU Zhiwei
  0 siblings, 0 replies; 60+ messages in thread
From: LIU Zhiwei @ 2022-01-13 11:39 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: Alistair.Francis, palmer, bin.meng, richard.henderson, guoren,
	LIU Zhiwei, Alistair Francis

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
Acked-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
 target/riscv/cpu.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 645a1b3f6c..85eb5c63cf 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -110,7 +110,6 @@ FIELD(VTYPE, VTA, 6, 1)
 FIELD(VTYPE, VMA, 7, 1)
 FIELD(VTYPE, VEDIV, 8, 2)
 FIELD(VTYPE, RESERVED, 10, sizeof(target_ulong) * 8 - 11)
-FIELD(VTYPE, VILL, sizeof(target_ulong) * 8 - 1, 1)
 
 struct CPURISCVState {
     target_ulong gpr[32];
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v6 18/22] target/riscv: Fix check range for first fault only
  2022-01-13 11:39 ` LIU Zhiwei
@ 2022-01-13 11:40   ` LIU Zhiwei
  -1 siblings, 0 replies; 60+ messages in thread
From: LIU Zhiwei @ 2022-01-13 11:40 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: guoren, bin.meng, richard.henderson, palmer, Alistair Francis,
	LIU Zhiwei

Only check the range that has passed the address translation.

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
 target/riscv/vector_helper.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 8b7c9ec890..efb3129532 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -500,12 +500,12 @@ vext_ldff(void *vd, void *v0, target_ulong base,
                                          cpu_mmu_index(env, false));
                 if (host) {
 #ifdef CONFIG_USER_ONLY
-                    if (page_check_range(addr, nf << esz, PAGE_READ) < 0) {
+                    if (page_check_range(addr, offset, PAGE_READ) < 0) {
                         vl = i;
                         goto ProbeSuccess;
                     }
 #else
-                    probe_pages(env, addr, nf << esz, ra, MMU_DATA_LOAD);
+                    probe_pages(env, addr, offset, ra, MMU_DATA_LOAD);
 #endif
                 } else {
                     vl = i;
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v6 18/22] target/riscv: Fix check range for first fault only
@ 2022-01-13 11:40   ` LIU Zhiwei
  0 siblings, 0 replies; 60+ messages in thread
From: LIU Zhiwei @ 2022-01-13 11:40 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: Alistair.Francis, palmer, bin.meng, richard.henderson, guoren,
	LIU Zhiwei, Alistair Francis

Only check the range that has passed the address translation.

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
 target/riscv/vector_helper.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 8b7c9ec890..efb3129532 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -500,12 +500,12 @@ vext_ldff(void *vd, void *v0, target_ulong base,
                                          cpu_mmu_index(env, false));
                 if (host) {
 #ifdef CONFIG_USER_ONLY
-                    if (page_check_range(addr, nf << esz, PAGE_READ) < 0) {
+                    if (page_check_range(addr, offset, PAGE_READ) < 0) {
                         vl = i;
                         goto ProbeSuccess;
                     }
 #else
-                    probe_pages(env, addr, nf << esz, ra, MMU_DATA_LOAD);
+                    probe_pages(env, addr, offset, ra, MMU_DATA_LOAD);
 #endif
                 } else {
                     vl = i;
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v6 19/22] target/riscv: Adjust vector address with mask
  2022-01-13 11:39 ` LIU Zhiwei
@ 2022-01-13 11:40   ` LIU Zhiwei
  -1 siblings, 0 replies; 60+ messages in thread
From: LIU Zhiwei @ 2022-01-13 11:40 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: guoren, bin.meng, richard.henderson, palmer, Alistair Francis,
	LIU Zhiwei

The mask comes from the pointer masking extension, or the max value
corresponding to XLEN bits.

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/riscv/vector_helper.c | 25 +++++++++++++++----------
 1 file changed, 15 insertions(+), 10 deletions(-)

diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index efb3129532..020d2e841f 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -139,6 +139,11 @@ static inline uint32_t vext_max_elems(uint32_t desc, uint32_t esz)
     return scale < 0 ? vlenb >> -scale : vlenb << scale;
 }
 
+static inline target_ulong adjust_addr(CPURISCVState *env, target_ulong addr)
+{
+    return (addr & env->cur_pmmask) | env->cur_pmbase;
+}
+
 /*
  * This function checks watchpoint before real load operation.
  *
@@ -156,12 +161,12 @@ static void probe_pages(CPURISCVState *env, target_ulong addr,
     target_ulong pagelen = -(addr | TARGET_PAGE_MASK);
     target_ulong curlen = MIN(pagelen, len);
 
-    probe_access(env, addr, curlen, access_type,
+    probe_access(env, adjust_addr(env, addr), curlen, access_type,
                  cpu_mmu_index(env, false), ra);
     if (len > curlen) {
         addr += curlen;
         curlen = len - curlen;
-        probe_access(env, addr, curlen, access_type,
+        probe_access(env, adjust_addr(env, addr), curlen, access_type,
                      cpu_mmu_index(env, false), ra);
     }
 }
@@ -239,7 +244,7 @@ vext_ldst_stride(void *vd, void *v0, target_ulong base,
         k = 0;
         while (k < nf) {
             target_ulong addr = base + stride * i + (k << esz);
-            ldst_elem(env, addr, i + k * max_elems, vd, ra);
+            ldst_elem(env, adjust_addr(env, addr), i + k * max_elems, vd, ra);
             k++;
         }
     }
@@ -295,7 +300,7 @@ vext_ldst_us(void *vd, target_ulong base, CPURISCVState *env, uint32_t desc,
         k = 0;
         while (k < nf) {
             target_ulong addr = base + ((i * nf + k) << esz);
-            ldst_elem(env, addr, i + k * max_elems, vd, ra);
+            ldst_elem(env, adjust_addr(env, addr), i + k * max_elems, vd, ra);
             k++;
         }
     }
@@ -409,7 +414,7 @@ vext_ldst_index(void *vd, void *v0, target_ulong base,
         k = 0;
         while (k < nf) {
             abi_ptr addr = get_index_addr(base, i, vs2) + (k << esz);
-            ldst_elem(env, addr, i + k * max_elems, vd, ra);
+            ldst_elem(env, adjust_addr(env, addr), i + k * max_elems, vd, ra);
             k++;
         }
     }
@@ -488,7 +493,7 @@ vext_ldff(void *vd, void *v0, target_ulong base,
         if (!vm && !vext_elem_mask(v0, i)) {
             continue;
         }
-        addr = base + i * (nf << esz);
+        addr = adjust_addr(env, base + i * (nf << esz));
         if (i == 0) {
             probe_pages(env, addr, nf << esz, ra, MMU_DATA_LOAD);
         } else {
@@ -515,7 +520,7 @@ vext_ldff(void *vd, void *v0, target_ulong base,
                     break;
                 }
                 remain -= offset;
-                addr += offset;
+                addr = adjust_addr(env, addr + offset);
             }
         }
     }
@@ -531,7 +536,7 @@ ProbeSuccess:
         }
         while (k < nf) {
             target_ulong addr = base + ((i * nf + k) << esz);
-            ldst_elem(env, addr, i + k * max_elems, vd, ra);
+            ldst_elem(env, adjust_addr(env, addr), i + k * max_elems, vd, ra);
             k++;
         }
     }
@@ -585,7 +590,7 @@ vext_ldst_whole(void *vd, target_ulong base, CPURISCVState *env, uint32_t desc,
         /* load/store rest of elements of current segment pointed by vstart */
         for (pos = off; pos < max_elems; pos++, env->vstart++) {
             target_ulong addr = base + ((pos + k * max_elems) << esz);
-            ldst_elem(env, addr, pos + k * max_elems, vd, ra);
+            ldst_elem(env, adjust_addr(env, addr), pos + k * max_elems, vd, ra);
         }
         k++;
     }
@@ -594,7 +599,7 @@ vext_ldst_whole(void *vd, target_ulong base, CPURISCVState *env, uint32_t desc,
     for (; k < nf; k++) {
         for (i = 0; i < max_elems; i++, env->vstart++) {
             target_ulong addr = base + ((i + k * max_elems) << esz);
-            ldst_elem(env, addr, i + k * max_elems, vd, ra);
+            ldst_elem(env, adjust_addr(env, addr), i + k * max_elems, vd, ra);
         }
     }
 
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v6 19/22] target/riscv: Adjust vector address with mask
@ 2022-01-13 11:40   ` LIU Zhiwei
  0 siblings, 0 replies; 60+ messages in thread
From: LIU Zhiwei @ 2022-01-13 11:40 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: Alistair.Francis, palmer, bin.meng, richard.henderson, guoren,
	LIU Zhiwei, Alistair Francis

The mask comes from the pointer masking extension, or the max value
corresponding to XLEN bits.

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/riscv/vector_helper.c | 25 +++++++++++++++----------
 1 file changed, 15 insertions(+), 10 deletions(-)

diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index efb3129532..020d2e841f 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -139,6 +139,11 @@ static inline uint32_t vext_max_elems(uint32_t desc, uint32_t esz)
     return scale < 0 ? vlenb >> -scale : vlenb << scale;
 }
 
+static inline target_ulong adjust_addr(CPURISCVState *env, target_ulong addr)
+{
+    return (addr & env->cur_pmmask) | env->cur_pmbase;
+}
+
 /*
  * This function checks watchpoint before real load operation.
  *
@@ -156,12 +161,12 @@ static void probe_pages(CPURISCVState *env, target_ulong addr,
     target_ulong pagelen = -(addr | TARGET_PAGE_MASK);
     target_ulong curlen = MIN(pagelen, len);
 
-    probe_access(env, addr, curlen, access_type,
+    probe_access(env, adjust_addr(env, addr), curlen, access_type,
                  cpu_mmu_index(env, false), ra);
     if (len > curlen) {
         addr += curlen;
         curlen = len - curlen;
-        probe_access(env, addr, curlen, access_type,
+        probe_access(env, adjust_addr(env, addr), curlen, access_type,
                      cpu_mmu_index(env, false), ra);
     }
 }
@@ -239,7 +244,7 @@ vext_ldst_stride(void *vd, void *v0, target_ulong base,
         k = 0;
         while (k < nf) {
             target_ulong addr = base + stride * i + (k << esz);
-            ldst_elem(env, addr, i + k * max_elems, vd, ra);
+            ldst_elem(env, adjust_addr(env, addr), i + k * max_elems, vd, ra);
             k++;
         }
     }
@@ -295,7 +300,7 @@ vext_ldst_us(void *vd, target_ulong base, CPURISCVState *env, uint32_t desc,
         k = 0;
         while (k < nf) {
             target_ulong addr = base + ((i * nf + k) << esz);
-            ldst_elem(env, addr, i + k * max_elems, vd, ra);
+            ldst_elem(env, adjust_addr(env, addr), i + k * max_elems, vd, ra);
             k++;
         }
     }
@@ -409,7 +414,7 @@ vext_ldst_index(void *vd, void *v0, target_ulong base,
         k = 0;
         while (k < nf) {
             abi_ptr addr = get_index_addr(base, i, vs2) + (k << esz);
-            ldst_elem(env, addr, i + k * max_elems, vd, ra);
+            ldst_elem(env, adjust_addr(env, addr), i + k * max_elems, vd, ra);
             k++;
         }
     }
@@ -488,7 +493,7 @@ vext_ldff(void *vd, void *v0, target_ulong base,
         if (!vm && !vext_elem_mask(v0, i)) {
             continue;
         }
-        addr = base + i * (nf << esz);
+        addr = adjust_addr(env, base + i * (nf << esz));
         if (i == 0) {
             probe_pages(env, addr, nf << esz, ra, MMU_DATA_LOAD);
         } else {
@@ -515,7 +520,7 @@ vext_ldff(void *vd, void *v0, target_ulong base,
                     break;
                 }
                 remain -= offset;
-                addr += offset;
+                addr = adjust_addr(env, addr + offset);
             }
         }
     }
@@ -531,7 +536,7 @@ ProbeSuccess:
         }
         while (k < nf) {
             target_ulong addr = base + ((i * nf + k) << esz);
-            ldst_elem(env, addr, i + k * max_elems, vd, ra);
+            ldst_elem(env, adjust_addr(env, addr), i + k * max_elems, vd, ra);
             k++;
         }
     }
@@ -585,7 +590,7 @@ vext_ldst_whole(void *vd, target_ulong base, CPURISCVState *env, uint32_t desc,
         /* load/store rest of elements of current segment pointed by vstart */
         for (pos = off; pos < max_elems; pos++, env->vstart++) {
             target_ulong addr = base + ((pos + k * max_elems) << esz);
-            ldst_elem(env, addr, pos + k * max_elems, vd, ra);
+            ldst_elem(env, adjust_addr(env, addr), pos + k * max_elems, vd, ra);
         }
         k++;
     }
@@ -594,7 +599,7 @@ vext_ldst_whole(void *vd, target_ulong base, CPURISCVState *env, uint32_t desc,
     for (; k < nf; k++) {
         for (i = 0; i < max_elems; i++, env->vstart++) {
             target_ulong addr = base + ((i + k * max_elems) << esz);
-            ldst_elem(env, addr, i + k * max_elems, vd, ra);
+            ldst_elem(env, adjust_addr(env, addr), i + k * max_elems, vd, ra);
         }
     }
 
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v6 20/22] target/riscv: Adjust scalar reg in vector with XLEN
  2022-01-13 11:39 ` LIU Zhiwei
@ 2022-01-13 11:40   ` LIU Zhiwei
  -1 siblings, 0 replies; 60+ messages in thread
From: LIU Zhiwei @ 2022-01-13 11:40 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: guoren, bin.meng, richard.henderson, palmer, Alistair.Francis,
	LIU Zhiwei

When sew <= 32bits, not need to extend scalar reg.
When sew > 32bits, if xlen is less that sew, we should sign extend
the scalar register, except explicitly specified by the spec.

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
---
 target/riscv/insn_trans/trans_rvv.c.inc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
index 1c8086d3a6..b6502cdc7c 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -1201,7 +1201,7 @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, uint32_t vm,
     dest = tcg_temp_new_ptr();
     mask = tcg_temp_new_ptr();
     src2 = tcg_temp_new_ptr();
-    src1 = get_gpr(s, rs1, EXT_NONE);
+    src1 = get_gpr(s, rs1, EXT_SIGN);
 
     data = FIELD_DP32(data, VDATA, VM, vm);
     data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v6 20/22] target/riscv: Adjust scalar reg in vector with XLEN
@ 2022-01-13 11:40   ` LIU Zhiwei
  0 siblings, 0 replies; 60+ messages in thread
From: LIU Zhiwei @ 2022-01-13 11:40 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: Alistair.Francis, palmer, bin.meng, richard.henderson, guoren,
	LIU Zhiwei

When sew <= 32bits, not need to extend scalar reg.
When sew > 32bits, if xlen is less that sew, we should sign extend
the scalar register, except explicitly specified by the spec.

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
---
 target/riscv/insn_trans/trans_rvv.c.inc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
index 1c8086d3a6..b6502cdc7c 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -1201,7 +1201,7 @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, uint32_t vm,
     dest = tcg_temp_new_ptr();
     mask = tcg_temp_new_ptr();
     src2 = tcg_temp_new_ptr();
-    src1 = get_gpr(s, rs1, EXT_NONE);
+    src1 = get_gpr(s, rs1, EXT_SIGN);
 
     data = FIELD_DP32(data, VDATA, VM, vm);
     data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v6 21/22] target/riscv: Enable uxl field write
  2022-01-13 11:39 ` LIU Zhiwei
@ 2022-01-13 11:40   ` LIU Zhiwei
  -1 siblings, 0 replies; 60+ messages in thread
From: LIU Zhiwei @ 2022-01-13 11:40 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: guoren, bin.meng, richard.henderson, palmer, Alistair Francis,
	LIU Zhiwei

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
 target/riscv/csr.c | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 8e67ff7c54..d944ee9caf 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -568,6 +568,7 @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno,
 {
     uint64_t mstatus = env->mstatus;
     uint64_t mask = 0;
+    RISCVMXL xl = riscv_cpu_mxl(env);
 
     /* flush tlb on mstatus fields that affect VM */
     if ((val ^ mstatus) & (MSTATUS_MXR | MSTATUS_MPP | MSTATUS_MPV |
@@ -579,21 +580,22 @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno,
         MSTATUS_MPP | MSTATUS_MXR | MSTATUS_TVM | MSTATUS_TSR |
         MSTATUS_TW | MSTATUS_VS;
 
-    if (riscv_cpu_mxl(env) != MXL_RV32) {
+    if (xl != MXL_RV32) {
         /*
          * RV32: MPV and GVA are not in mstatus. The current plan is to
          * add them to mstatush. For now, we just don't support it.
          */
         mask |= MSTATUS_MPV | MSTATUS_GVA;
+        if ((val & MSTATUS64_UXL) != 0) {
+            mask |= MSTATUS64_UXL;
+        }
     }
 
     mstatus = (mstatus & ~mask) | (val & mask);
 
-    RISCVMXL xl = riscv_cpu_mxl(env);
     if (xl > MXL_RV32) {
-        /* SXL and UXL fields are for now read only */
+        /* SXL field is for now read only */
         mstatus = set_field(mstatus, MSTATUS64_SXL, xl);
-        mstatus = set_field(mstatus, MSTATUS64_UXL, xl);
     }
     env->mstatus = mstatus;
     env->xl = cpu_recompute_xl(env);
@@ -903,7 +905,9 @@ static RISCVException read_sstatus(CPURISCVState *env, int csrno,
                                    target_ulong *val)
 {
     target_ulong mask = (sstatus_v1_10_mask);
-
+    if (env->xl != MXL_RV32) {
+        mask |= SSTATUS64_UXL;
+    }
     /* TODO: Use SXL not MXL. */
     *val = add_status_sd(riscv_cpu_mxl(env), env->mstatus & mask);
     return RISCV_EXCP_NONE;
@@ -913,6 +917,9 @@ static RISCVException write_sstatus(CPURISCVState *env, int csrno,
                                     target_ulong val)
 {
     target_ulong mask = (sstatus_v1_10_mask);
+    if (env->xl != MXL_RV32) {
+        mask |= SSTATUS64_UXL;
+    }
     target_ulong newval = (env->mstatus & ~mask) | (val & mask);
     return write_mstatus(env, CSR_MSTATUS, newval);
 }
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v6 21/22] target/riscv: Enable uxl field write
@ 2022-01-13 11:40   ` LIU Zhiwei
  0 siblings, 0 replies; 60+ messages in thread
From: LIU Zhiwei @ 2022-01-13 11:40 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: Alistair.Francis, palmer, bin.meng, richard.henderson, guoren,
	LIU Zhiwei, Alistair Francis

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
 target/riscv/csr.c | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 8e67ff7c54..d944ee9caf 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -568,6 +568,7 @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno,
 {
     uint64_t mstatus = env->mstatus;
     uint64_t mask = 0;
+    RISCVMXL xl = riscv_cpu_mxl(env);
 
     /* flush tlb on mstatus fields that affect VM */
     if ((val ^ mstatus) & (MSTATUS_MXR | MSTATUS_MPP | MSTATUS_MPV |
@@ -579,21 +580,22 @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno,
         MSTATUS_MPP | MSTATUS_MXR | MSTATUS_TVM | MSTATUS_TSR |
         MSTATUS_TW | MSTATUS_VS;
 
-    if (riscv_cpu_mxl(env) != MXL_RV32) {
+    if (xl != MXL_RV32) {
         /*
          * RV32: MPV and GVA are not in mstatus. The current plan is to
          * add them to mstatush. For now, we just don't support it.
          */
         mask |= MSTATUS_MPV | MSTATUS_GVA;
+        if ((val & MSTATUS64_UXL) != 0) {
+            mask |= MSTATUS64_UXL;
+        }
     }
 
     mstatus = (mstatus & ~mask) | (val & mask);
 
-    RISCVMXL xl = riscv_cpu_mxl(env);
     if (xl > MXL_RV32) {
-        /* SXL and UXL fields are for now read only */
+        /* SXL field is for now read only */
         mstatus = set_field(mstatus, MSTATUS64_SXL, xl);
-        mstatus = set_field(mstatus, MSTATUS64_UXL, xl);
     }
     env->mstatus = mstatus;
     env->xl = cpu_recompute_xl(env);
@@ -903,7 +905,9 @@ static RISCVException read_sstatus(CPURISCVState *env, int csrno,
                                    target_ulong *val)
 {
     target_ulong mask = (sstatus_v1_10_mask);
-
+    if (env->xl != MXL_RV32) {
+        mask |= SSTATUS64_UXL;
+    }
     /* TODO: Use SXL not MXL. */
     *val = add_status_sd(riscv_cpu_mxl(env), env->mstatus & mask);
     return RISCV_EXCP_NONE;
@@ -913,6 +917,9 @@ static RISCVException write_sstatus(CPURISCVState *env, int csrno,
                                     target_ulong val)
 {
     target_ulong mask = (sstatus_v1_10_mask);
+    if (env->xl != MXL_RV32) {
+        mask |= SSTATUS64_UXL;
+    }
     target_ulong newval = (env->mstatus & ~mask) | (val & mask);
     return write_mstatus(env, CSR_MSTATUS, newval);
 }
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v6 22/22] target/riscv: Relax UXL field for debugging
  2022-01-13 11:39 ` LIU Zhiwei
@ 2022-01-13 11:40   ` LIU Zhiwei
  -1 siblings, 0 replies; 60+ messages in thread
From: LIU Zhiwei @ 2022-01-13 11:40 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: guoren, bin.meng, richard.henderson, palmer, Alistair.Francis,
	LIU Zhiwei

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
---
 target/riscv/csr.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index d944ee9caf..1037c6b15d 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -580,7 +580,7 @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno,
         MSTATUS_MPP | MSTATUS_MXR | MSTATUS_TVM | MSTATUS_TSR |
         MSTATUS_TW | MSTATUS_VS;
 
-    if (xl != MXL_RV32) {
+    if (xl != MXL_RV32 || env->debugger) {
         /*
          * RV32: MPV and GVA are not in mstatus. The current plan is to
          * add them to mstatush. For now, we just don't support it.
@@ -905,7 +905,7 @@ static RISCVException read_sstatus(CPURISCVState *env, int csrno,
                                    target_ulong *val)
 {
     target_ulong mask = (sstatus_v1_10_mask);
-    if (env->xl != MXL_RV32) {
+    if (env->xl != MXL_RV32 || env->debugger) {
         mask |= SSTATUS64_UXL;
     }
     /* TODO: Use SXL not MXL. */
@@ -917,7 +917,8 @@ static RISCVException write_sstatus(CPURISCVState *env, int csrno,
                                     target_ulong val)
 {
     target_ulong mask = (sstatus_v1_10_mask);
-    if (env->xl != MXL_RV32) {
+
+    if (env->xl != MXL_RV32 || env->debugger) {
         mask |= SSTATUS64_UXL;
     }
     target_ulong newval = (env->mstatus & ~mask) | (val & mask);
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* [PATCH v6 22/22] target/riscv: Relax UXL field for debugging
@ 2022-01-13 11:40   ` LIU Zhiwei
  0 siblings, 0 replies; 60+ messages in thread
From: LIU Zhiwei @ 2022-01-13 11:40 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: Alistair.Francis, palmer, bin.meng, richard.henderson, guoren,
	LIU Zhiwei

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
---
 target/riscv/csr.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index d944ee9caf..1037c6b15d 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -580,7 +580,7 @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno,
         MSTATUS_MPP | MSTATUS_MXR | MSTATUS_TVM | MSTATUS_TSR |
         MSTATUS_TW | MSTATUS_VS;
 
-    if (xl != MXL_RV32) {
+    if (xl != MXL_RV32 || env->debugger) {
         /*
          * RV32: MPV and GVA are not in mstatus. The current plan is to
          * add them to mstatush. For now, we just don't support it.
@@ -905,7 +905,7 @@ static RISCVException read_sstatus(CPURISCVState *env, int csrno,
                                    target_ulong *val)
 {
     target_ulong mask = (sstatus_v1_10_mask);
-    if (env->xl != MXL_RV32) {
+    if (env->xl != MXL_RV32 || env->debugger) {
         mask |= SSTATUS64_UXL;
     }
     /* TODO: Use SXL not MXL. */
@@ -917,7 +917,8 @@ static RISCVException write_sstatus(CPURISCVState *env, int csrno,
                                     target_ulong val)
 {
     target_ulong mask = (sstatus_v1_10_mask);
-    if (env->xl != MXL_RV32) {
+
+    if (env->xl != MXL_RV32 || env->debugger) {
         mask |= SSTATUS64_UXL;
     }
     target_ulong newval = (env->mstatus & ~mask) | (val & mask);
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 60+ messages in thread

* Re: [PATCH v6 01/22] target/riscv: Adjust pmpcfg access with mxl
  2022-01-13 11:39   ` LIU Zhiwei
@ 2022-01-19  3:20     ` Alistair Francis
  -1 siblings, 0 replies; 60+ messages in thread
From: Alistair Francis @ 2022-01-19  3:20 UTC (permalink / raw)
  To: LIU Zhiwei
  Cc: guoren, open list:RISC-V, Bin Meng, Richard Henderson,
	qemu-devel@nongnu.org Developers, Palmer Dabbelt,
	Alistair Francis

On Thu, Jan 13, 2022 at 9:41 PM LIU Zhiwei <zhiwei_liu@c-sky.com> wrote:
>
> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  target/riscv/csr.c | 19 +++++++++++++++++++
>  target/riscv/pmp.c | 12 ++++--------
>  2 files changed, 23 insertions(+), 8 deletions(-)
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index adb3d4381d..e7578f3e0f 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -1493,9 +1493,23 @@ static RISCVException write_mseccfg(CPURISCVState *env, int csrno,
>      return RISCV_EXCP_NONE;
>  }
>
> +static bool check_pmp_reg_index(CPURISCVState *env, uint32_t reg_index)
> +{
> +    /* TODO: RV128 restriction check */
> +    if ((reg_index & 1) && (riscv_cpu_mxl(env) == MXL_RV64)) {
> +        return false;
> +    }
> +    return true;
> +}
> +
>  static RISCVException read_pmpcfg(CPURISCVState *env, int csrno,
>                                    target_ulong *val)
>  {
> +    uint32_t reg_index = csrno - CSR_PMPCFG0;
> +
> +    if (!check_pmp_reg_index(env, reg_index)) {
> +        return RISCV_EXCP_ILLEGAL_INST;
> +    }
>      *val = pmpcfg_csr_read(env, csrno - CSR_PMPCFG0);
>      return RISCV_EXCP_NONE;
>  }
> @@ -1503,6 +1517,11 @@ static RISCVException read_pmpcfg(CPURISCVState *env, int csrno,
>  static RISCVException write_pmpcfg(CPURISCVState *env, int csrno,
>                                     target_ulong val)
>  {
> +    uint32_t reg_index = csrno - CSR_PMPCFG0;
> +
> +    if (!check_pmp_reg_index(env, reg_index)) {
> +        return RISCV_EXCP_ILLEGAL_INST;
> +    }
>      pmpcfg_csr_write(env, csrno - CSR_PMPCFG0, val);
>      return RISCV_EXCP_NONE;
>  }
> diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
> index 54abf42583..81b61bb65c 100644
> --- a/target/riscv/pmp.c
> +++ b/target/riscv/pmp.c
> @@ -463,16 +463,11 @@ void pmpcfg_csr_write(CPURISCVState *env, uint32_t reg_index,
>  {
>      int i;
>      uint8_t cfg_val;
> +    int pmpcfg_nums = 2 << riscv_cpu_mxl(env);
>
>      trace_pmpcfg_csr_write(env->mhartid, reg_index, val);
>
> -    if ((reg_index & 1) && (sizeof(target_ulong) == 8)) {
> -        qemu_log_mask(LOG_GUEST_ERROR,
> -                      "ignoring pmpcfg write - incorrect address\n");
> -        return;
> -    }
> -
> -    for (i = 0; i < sizeof(target_ulong); i++) {
> +    for (i = 0; i < pmpcfg_nums; i++) {
>          cfg_val = (val >> 8 * i)  & 0xff;
>          pmp_write_cfg(env, (reg_index * 4) + i, cfg_val);
>      }
> @@ -490,8 +485,9 @@ target_ulong pmpcfg_csr_read(CPURISCVState *env, uint32_t reg_index)
>      int i;
>      target_ulong cfg_val = 0;
>      target_ulong val = 0;
> +    int pmpcfg_nums = 2 << riscv_cpu_mxl(env);
>
> -    for (i = 0; i < sizeof(target_ulong); i++) {
> +    for (i = 0; i < pmpcfg_nums; i++) {
>          val = pmp_read_cfg(env, (reg_index * 4) + i);
>          cfg_val |= (val << (i * 8));
>      }
> --
> 2.25.1
>
>


^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v6 01/22] target/riscv: Adjust pmpcfg access with mxl
@ 2022-01-19  3:20     ` Alistair Francis
  0 siblings, 0 replies; 60+ messages in thread
From: Alistair Francis @ 2022-01-19  3:20 UTC (permalink / raw)
  To: LIU Zhiwei
  Cc: qemu-devel@nongnu.org Developers, open list:RISC-V, guoren,
	Bin Meng, Richard Henderson, Palmer Dabbelt, Alistair Francis

On Thu, Jan 13, 2022 at 9:41 PM LIU Zhiwei <zhiwei_liu@c-sky.com> wrote:
>
> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  target/riscv/csr.c | 19 +++++++++++++++++++
>  target/riscv/pmp.c | 12 ++++--------
>  2 files changed, 23 insertions(+), 8 deletions(-)
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index adb3d4381d..e7578f3e0f 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -1493,9 +1493,23 @@ static RISCVException write_mseccfg(CPURISCVState *env, int csrno,
>      return RISCV_EXCP_NONE;
>  }
>
> +static bool check_pmp_reg_index(CPURISCVState *env, uint32_t reg_index)
> +{
> +    /* TODO: RV128 restriction check */
> +    if ((reg_index & 1) && (riscv_cpu_mxl(env) == MXL_RV64)) {
> +        return false;
> +    }
> +    return true;
> +}
> +
>  static RISCVException read_pmpcfg(CPURISCVState *env, int csrno,
>                                    target_ulong *val)
>  {
> +    uint32_t reg_index = csrno - CSR_PMPCFG0;
> +
> +    if (!check_pmp_reg_index(env, reg_index)) {
> +        return RISCV_EXCP_ILLEGAL_INST;
> +    }
>      *val = pmpcfg_csr_read(env, csrno - CSR_PMPCFG0);
>      return RISCV_EXCP_NONE;
>  }
> @@ -1503,6 +1517,11 @@ static RISCVException read_pmpcfg(CPURISCVState *env, int csrno,
>  static RISCVException write_pmpcfg(CPURISCVState *env, int csrno,
>                                     target_ulong val)
>  {
> +    uint32_t reg_index = csrno - CSR_PMPCFG0;
> +
> +    if (!check_pmp_reg_index(env, reg_index)) {
> +        return RISCV_EXCP_ILLEGAL_INST;
> +    }
>      pmpcfg_csr_write(env, csrno - CSR_PMPCFG0, val);
>      return RISCV_EXCP_NONE;
>  }
> diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
> index 54abf42583..81b61bb65c 100644
> --- a/target/riscv/pmp.c
> +++ b/target/riscv/pmp.c
> @@ -463,16 +463,11 @@ void pmpcfg_csr_write(CPURISCVState *env, uint32_t reg_index,
>  {
>      int i;
>      uint8_t cfg_val;
> +    int pmpcfg_nums = 2 << riscv_cpu_mxl(env);
>
>      trace_pmpcfg_csr_write(env->mhartid, reg_index, val);
>
> -    if ((reg_index & 1) && (sizeof(target_ulong) == 8)) {
> -        qemu_log_mask(LOG_GUEST_ERROR,
> -                      "ignoring pmpcfg write - incorrect address\n");
> -        return;
> -    }
> -
> -    for (i = 0; i < sizeof(target_ulong); i++) {
> +    for (i = 0; i < pmpcfg_nums; i++) {
>          cfg_val = (val >> 8 * i)  & 0xff;
>          pmp_write_cfg(env, (reg_index * 4) + i, cfg_val);
>      }
> @@ -490,8 +485,9 @@ target_ulong pmpcfg_csr_read(CPURISCVState *env, uint32_t reg_index)
>      int i;
>      target_ulong cfg_val = 0;
>      target_ulong val = 0;
> +    int pmpcfg_nums = 2 << riscv_cpu_mxl(env);
>
> -    for (i = 0; i < sizeof(target_ulong); i++) {
> +    for (i = 0; i < pmpcfg_nums; i++) {
>          val = pmp_read_cfg(env, (reg_index * 4) + i);
>          cfg_val |= (val << (i * 8));
>      }
> --
> 2.25.1
>
>


^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v6 03/22] target/riscv: Sign extend link reg for jal and jalr
  2022-01-13 11:39   ` LIU Zhiwei
@ 2022-01-19  3:21     ` Alistair Francis
  -1 siblings, 0 replies; 60+ messages in thread
From: Alistair Francis @ 2022-01-19  3:21 UTC (permalink / raw)
  To: LIU Zhiwei
  Cc: guoren, open list:RISC-V, Bin Meng, Richard Henderson,
	qemu-devel@nongnu.org Developers, Palmer Dabbelt,
	Alistair Francis

On Thu, Jan 13, 2022 at 9:45 PM LIU Zhiwei <zhiwei_liu@c-sky.com> wrote:
>
> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  target/riscv/insn_trans/trans_rvi.c.inc | 4 +---
>  target/riscv/translate.c                | 4 +---
>  2 files changed, 2 insertions(+), 6 deletions(-)
>
> diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
> index 3a0ae28fef..b9ba57f266 100644
> --- a/target/riscv/insn_trans/trans_rvi.c.inc
> +++ b/target/riscv/insn_trans/trans_rvi.c.inc
> @@ -68,9 +68,7 @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
>          tcg_temp_free(t0);
>      }
>
> -    if (a->rd != 0) {
> -        tcg_gen_movi_tl(cpu_gpr[a->rd], ctx->pc_succ_insn);
> -    }
> +    gen_set_gpri(ctx, a->rd, ctx->pc_succ_insn);
>      tcg_gen_lookup_and_goto_ptr();
>
>      if (misaligned) {
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index 615048ec87..b47b308920 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -367,10 +367,8 @@ static void gen_jal(DisasContext *ctx, int rd, target_ulong imm)
>              return;
>          }
>      }
> -    if (rd != 0) {
> -        tcg_gen_movi_tl(cpu_gpr[rd], ctx->pc_succ_insn);
> -    }
>
> +    gen_set_gpri(ctx, rd, ctx->pc_succ_insn);
>      gen_goto_tb(ctx, 0, ctx->base.pc_next + imm); /* must use this for safety */
>      ctx->base.is_jmp = DISAS_NORETURN;
>  }
> --
> 2.25.1
>
>


^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v6 03/22] target/riscv: Sign extend link reg for jal and jalr
@ 2022-01-19  3:21     ` Alistair Francis
  0 siblings, 0 replies; 60+ messages in thread
From: Alistair Francis @ 2022-01-19  3:21 UTC (permalink / raw)
  To: LIU Zhiwei
  Cc: qemu-devel@nongnu.org Developers, open list:RISC-V, guoren,
	Bin Meng, Richard Henderson, Palmer Dabbelt, Alistair Francis

On Thu, Jan 13, 2022 at 9:45 PM LIU Zhiwei <zhiwei_liu@c-sky.com> wrote:
>
> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  target/riscv/insn_trans/trans_rvi.c.inc | 4 +---
>  target/riscv/translate.c                | 4 +---
>  2 files changed, 2 insertions(+), 6 deletions(-)
>
> diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
> index 3a0ae28fef..b9ba57f266 100644
> --- a/target/riscv/insn_trans/trans_rvi.c.inc
> +++ b/target/riscv/insn_trans/trans_rvi.c.inc
> @@ -68,9 +68,7 @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
>          tcg_temp_free(t0);
>      }
>
> -    if (a->rd != 0) {
> -        tcg_gen_movi_tl(cpu_gpr[a->rd], ctx->pc_succ_insn);
> -    }
> +    gen_set_gpri(ctx, a->rd, ctx->pc_succ_insn);
>      tcg_gen_lookup_and_goto_ptr();
>
>      if (misaligned) {
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index 615048ec87..b47b308920 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -367,10 +367,8 @@ static void gen_jal(DisasContext *ctx, int rd, target_ulong imm)
>              return;
>          }
>      }
> -    if (rd != 0) {
> -        tcg_gen_movi_tl(cpu_gpr[rd], ctx->pc_succ_insn);
> -    }
>
> +    gen_set_gpri(ctx, rd, ctx->pc_succ_insn);
>      gen_goto_tb(ctx, 0, ctx->base.pc_next + imm); /* must use this for safety */
>      ctx->base.is_jmp = DISAS_NORETURN;
>  }
> --
> 2.25.1
>
>


^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v6 05/22] target/riscv: Create xl field in env
  2022-01-13 11:39   ` LIU Zhiwei
@ 2022-01-19  3:24     ` Alistair Francis
  -1 siblings, 0 replies; 60+ messages in thread
From: Alistair Francis @ 2022-01-19  3:24 UTC (permalink / raw)
  To: LIU Zhiwei
  Cc: guoren, open list:RISC-V, Bin Meng, Richard Henderson,
	qemu-devel@nongnu.org Developers, Palmer Dabbelt,
	Alistair Francis

On Thu, Jan 13, 2022 at 9:50 PM LIU Zhiwei <zhiwei_liu@c-sky.com> wrote:
>
> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>

I'm not clear on why this is better?

Alistair

> ---
>  target/riscv/cpu.c        |  1 +
>  target/riscv/cpu.h        | 31 +++++++++++++++++++++++++++++++
>  target/riscv/cpu_helper.c | 34 ++--------------------------------
>  target/riscv/csr.c        |  2 ++
>  target/riscv/machine.c    | 10 ++++++++++
>  5 files changed, 46 insertions(+), 32 deletions(-)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 9bc25d3055..54c1cf8ec5 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -399,6 +399,7 @@ static void riscv_cpu_reset(DeviceState *dev)
>      /* mmte is supposed to have pm.current hardwired to 1 */
>      env->mmte |= (PM_EXT_INITIAL | MMTE_M_PM_CURRENT);
>  #endif
> +    env->xl = riscv_cpu_mxl(env);
>      cs->exception_index = RISCV_EXCP_NONE;
>      env->load_res = -1;
>      set_default_nan_mode(1, &env->fp_status);
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 4d63086765..65fd849bef 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -145,6 +145,7 @@ struct CPURISCVState {
>      uint32_t misa_mxl_max;  /* max mxl for this cpu */
>      uint32_t misa_ext;      /* current extensions */
>      uint32_t misa_ext_mask; /* max ext for this cpu */
> +    uint32_t xl;            /* current xlen */
>
>      /* 128-bit helpers upper part return value */
>      target_ulong retxh;
> @@ -443,6 +444,36 @@ static inline RISCVMXL riscv_cpu_mxl(CPURISCVState *env)
>  }
>  #endif
>
> +#if defined(TARGET_RISCV32)
> +#define cpu_recompute_xl(env)  ((void)(env), MXL_RV32)
> +#else
> +static inline RISCVMXL cpu_recompute_xl(CPURISCVState *env)
> +{
> +    RISCVMXL xl = env->misa_mxl;
> +#if !defined(CONFIG_USER_ONLY)
> +    /*
> +     * When emulating a 32-bit-only cpu, use RV32.
> +     * When emulating a 64-bit cpu, and MXL has been reduced to RV32,
> +     * MSTATUSH doesn't have UXL/SXL, therefore XLEN cannot be widened
> +     * back to RV64 for lower privs.
> +     */
> +    if (xl != MXL_RV32) {
> +        switch (env->priv) {
> +        case PRV_M:
> +            break;
> +        case PRV_U:
> +            xl = get_field(env->mstatus, MSTATUS64_UXL);
> +            break;
> +        default: /* PRV_S | PRV_H */
> +            xl = get_field(env->mstatus, MSTATUS64_SXL);
> +            break;
> +        }
> +    }
> +#endif
> +    return xl;
> +}
> +#endif
> +
>  /*
>   * Encode LMUL to lmul as follows:
>   *     LMUL    vlmul    lmul
> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> index 434a83e66a..32ea066ef0 100644
> --- a/target/riscv/cpu_helper.c
> +++ b/target/riscv/cpu_helper.c
> @@ -35,37 +35,6 @@ int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
>  #endif
>  }
>
> -static RISCVMXL cpu_get_xl(CPURISCVState *env)
> -{
> -#if defined(TARGET_RISCV32)
> -    return MXL_RV32;
> -#elif defined(CONFIG_USER_ONLY)
> -    return MXL_RV64;
> -#else
> -    RISCVMXL xl = riscv_cpu_mxl(env);
> -
> -    /*
> -     * When emulating a 32-bit-only cpu, use RV32.
> -     * When emulating a 64-bit cpu, and MXL has been reduced to RV32,
> -     * MSTATUSH doesn't have UXL/SXL, therefore XLEN cannot be widened
> -     * back to RV64 for lower privs.
> -     */
> -    if (xl != MXL_RV32) {
> -        switch (env->priv) {
> -        case PRV_M:
> -            break;
> -        case PRV_U:
> -            xl = get_field(env->mstatus, MSTATUS64_UXL);
> -            break;
> -        default: /* PRV_S | PRV_H */
> -            xl = get_field(env->mstatus, MSTATUS64_SXL);
> -            break;
> -        }
> -    }
> -    return xl;
> -#endif
> -}
> -
>  void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
>                            target_ulong *cs_base, uint32_t *pflags)
>  {
> @@ -145,7 +114,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
>      }
>  #endif
>
> -    flags = FIELD_DP32(flags, TB_FLAGS, XL, cpu_get_xl(env));
> +    flags = FIELD_DP32(flags, TB_FLAGS, XL, env->xl);
>
>      *pflags = flags;
>  }
> @@ -361,6 +330,7 @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv)
>      }
>      /* tlb_flush is unnecessary as mode is contained in mmu_idx */
>      env->priv = newpriv;
> +    env->xl = cpu_recompute_xl(env);
>
>      /*
>       * Clear the load reservation - otherwise a reservation placed in one
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index e7578f3e0f..b282a642f5 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -585,6 +585,7 @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno,
>          mstatus = set_field(mstatus, MSTATUS64_UXL, xl);
>      }
>      env->mstatus = mstatus;
> +    env->xl = cpu_recompute_xl(env);
>
>      return RISCV_EXCP_NONE;
>  }
> @@ -700,6 +701,7 @@ static RISCVException write_misa(CPURISCVState *env, int csrno,
>      /* flush translation cache */
>      tb_flush(env_cpu(env));
>      env->misa_ext = val;
> +    env->xl = riscv_cpu_mxl(env);
>      return RISCV_EXCP_NONE;
>  }
>
> diff --git a/target/riscv/machine.c b/target/riscv/machine.c
> index 13b9ab375b..e1d1029e88 100644
> --- a/target/riscv/machine.c
> +++ b/target/riscv/machine.c
> @@ -185,10 +185,20 @@ static const VMStateDescription vmstate_rv128 = {
>      }
>  };
>
> +static int riscv_cpu_post_load(void *opaque, int version_id)
> +{
> +    RISCVCPU *cpu = opaque;
> +    CPURISCVState *env = &cpu->env;
> +
> +    env->xl = cpu_recompute_xl(env);
> +    return 0;
> +}
> +
>  const VMStateDescription vmstate_riscv_cpu = {
>      .name = "cpu",
>      .version_id = 3,
>      .minimum_version_id = 3,
> +    .post_load = riscv_cpu_post_load,
>      .fields = (VMStateField[]) {
>          VMSTATE_UINTTL_ARRAY(env.gpr, RISCVCPU, 32),
>          VMSTATE_UINT64_ARRAY(env.fpr, RISCVCPU, 32),
> --
> 2.25.1
>
>


^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v6 05/22] target/riscv: Create xl field in env
@ 2022-01-19  3:24     ` Alistair Francis
  0 siblings, 0 replies; 60+ messages in thread
From: Alistair Francis @ 2022-01-19  3:24 UTC (permalink / raw)
  To: LIU Zhiwei
  Cc: qemu-devel@nongnu.org Developers, open list:RISC-V, guoren,
	Bin Meng, Richard Henderson, Palmer Dabbelt, Alistair Francis

On Thu, Jan 13, 2022 at 9:50 PM LIU Zhiwei <zhiwei_liu@c-sky.com> wrote:
>
> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>

I'm not clear on why this is better?

Alistair

> ---
>  target/riscv/cpu.c        |  1 +
>  target/riscv/cpu.h        | 31 +++++++++++++++++++++++++++++++
>  target/riscv/cpu_helper.c | 34 ++--------------------------------
>  target/riscv/csr.c        |  2 ++
>  target/riscv/machine.c    | 10 ++++++++++
>  5 files changed, 46 insertions(+), 32 deletions(-)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 9bc25d3055..54c1cf8ec5 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -399,6 +399,7 @@ static void riscv_cpu_reset(DeviceState *dev)
>      /* mmte is supposed to have pm.current hardwired to 1 */
>      env->mmte |= (PM_EXT_INITIAL | MMTE_M_PM_CURRENT);
>  #endif
> +    env->xl = riscv_cpu_mxl(env);
>      cs->exception_index = RISCV_EXCP_NONE;
>      env->load_res = -1;
>      set_default_nan_mode(1, &env->fp_status);
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 4d63086765..65fd849bef 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -145,6 +145,7 @@ struct CPURISCVState {
>      uint32_t misa_mxl_max;  /* max mxl for this cpu */
>      uint32_t misa_ext;      /* current extensions */
>      uint32_t misa_ext_mask; /* max ext for this cpu */
> +    uint32_t xl;            /* current xlen */
>
>      /* 128-bit helpers upper part return value */
>      target_ulong retxh;
> @@ -443,6 +444,36 @@ static inline RISCVMXL riscv_cpu_mxl(CPURISCVState *env)
>  }
>  #endif
>
> +#if defined(TARGET_RISCV32)
> +#define cpu_recompute_xl(env)  ((void)(env), MXL_RV32)
> +#else
> +static inline RISCVMXL cpu_recompute_xl(CPURISCVState *env)
> +{
> +    RISCVMXL xl = env->misa_mxl;
> +#if !defined(CONFIG_USER_ONLY)
> +    /*
> +     * When emulating a 32-bit-only cpu, use RV32.
> +     * When emulating a 64-bit cpu, and MXL has been reduced to RV32,
> +     * MSTATUSH doesn't have UXL/SXL, therefore XLEN cannot be widened
> +     * back to RV64 for lower privs.
> +     */
> +    if (xl != MXL_RV32) {
> +        switch (env->priv) {
> +        case PRV_M:
> +            break;
> +        case PRV_U:
> +            xl = get_field(env->mstatus, MSTATUS64_UXL);
> +            break;
> +        default: /* PRV_S | PRV_H */
> +            xl = get_field(env->mstatus, MSTATUS64_SXL);
> +            break;
> +        }
> +    }
> +#endif
> +    return xl;
> +}
> +#endif
> +
>  /*
>   * Encode LMUL to lmul as follows:
>   *     LMUL    vlmul    lmul
> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> index 434a83e66a..32ea066ef0 100644
> --- a/target/riscv/cpu_helper.c
> +++ b/target/riscv/cpu_helper.c
> @@ -35,37 +35,6 @@ int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
>  #endif
>  }
>
> -static RISCVMXL cpu_get_xl(CPURISCVState *env)
> -{
> -#if defined(TARGET_RISCV32)
> -    return MXL_RV32;
> -#elif defined(CONFIG_USER_ONLY)
> -    return MXL_RV64;
> -#else
> -    RISCVMXL xl = riscv_cpu_mxl(env);
> -
> -    /*
> -     * When emulating a 32-bit-only cpu, use RV32.
> -     * When emulating a 64-bit cpu, and MXL has been reduced to RV32,
> -     * MSTATUSH doesn't have UXL/SXL, therefore XLEN cannot be widened
> -     * back to RV64 for lower privs.
> -     */
> -    if (xl != MXL_RV32) {
> -        switch (env->priv) {
> -        case PRV_M:
> -            break;
> -        case PRV_U:
> -            xl = get_field(env->mstatus, MSTATUS64_UXL);
> -            break;
> -        default: /* PRV_S | PRV_H */
> -            xl = get_field(env->mstatus, MSTATUS64_SXL);
> -            break;
> -        }
> -    }
> -    return xl;
> -#endif
> -}
> -
>  void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
>                            target_ulong *cs_base, uint32_t *pflags)
>  {
> @@ -145,7 +114,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
>      }
>  #endif
>
> -    flags = FIELD_DP32(flags, TB_FLAGS, XL, cpu_get_xl(env));
> +    flags = FIELD_DP32(flags, TB_FLAGS, XL, env->xl);
>
>      *pflags = flags;
>  }
> @@ -361,6 +330,7 @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv)
>      }
>      /* tlb_flush is unnecessary as mode is contained in mmu_idx */
>      env->priv = newpriv;
> +    env->xl = cpu_recompute_xl(env);
>
>      /*
>       * Clear the load reservation - otherwise a reservation placed in one
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index e7578f3e0f..b282a642f5 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -585,6 +585,7 @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno,
>          mstatus = set_field(mstatus, MSTATUS64_UXL, xl);
>      }
>      env->mstatus = mstatus;
> +    env->xl = cpu_recompute_xl(env);
>
>      return RISCV_EXCP_NONE;
>  }
> @@ -700,6 +701,7 @@ static RISCVException write_misa(CPURISCVState *env, int csrno,
>      /* flush translation cache */
>      tb_flush(env_cpu(env));
>      env->misa_ext = val;
> +    env->xl = riscv_cpu_mxl(env);
>      return RISCV_EXCP_NONE;
>  }
>
> diff --git a/target/riscv/machine.c b/target/riscv/machine.c
> index 13b9ab375b..e1d1029e88 100644
> --- a/target/riscv/machine.c
> +++ b/target/riscv/machine.c
> @@ -185,10 +185,20 @@ static const VMStateDescription vmstate_rv128 = {
>      }
>  };
>
> +static int riscv_cpu_post_load(void *opaque, int version_id)
> +{
> +    RISCVCPU *cpu = opaque;
> +    CPURISCVState *env = &cpu->env;
> +
> +    env->xl = cpu_recompute_xl(env);
> +    return 0;
> +}
> +
>  const VMStateDescription vmstate_riscv_cpu = {
>      .name = "cpu",
>      .version_id = 3,
>      .minimum_version_id = 3,
> +    .post_load = riscv_cpu_post_load,
>      .fields = (VMStateField[]) {
>          VMSTATE_UINTTL_ARRAY(env.gpr, RISCVCPU, 32),
>          VMSTATE_UINT64_ARRAY(env.fpr, RISCVCPU, 32),
> --
> 2.25.1
>
>


^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v6 20/22] target/riscv: Adjust scalar reg in vector with XLEN
  2022-01-13 11:40   ` LIU Zhiwei
@ 2022-01-19  3:30     ` Alistair Francis
  -1 siblings, 0 replies; 60+ messages in thread
From: Alistair Francis @ 2022-01-19  3:30 UTC (permalink / raw)
  To: LIU Zhiwei
  Cc: guoren, open list:RISC-V, Bin Meng, Richard Henderson,
	qemu-devel@nongnu.org Developers, Palmer Dabbelt,
	Alistair Francis

On Thu, Jan 13, 2022 at 10:20 PM LIU Zhiwei <zhiwei_liu@c-sky.com> wrote:
>
> When sew <= 32bits, not need to extend scalar reg.
> When sew > 32bits, if xlen is less that sew, we should sign extend
> the scalar register, except explicitly specified by the spec.
>
> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  target/riscv/insn_trans/trans_rvv.c.inc | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
> index 1c8086d3a6..b6502cdc7c 100644
> --- a/target/riscv/insn_trans/trans_rvv.c.inc
> +++ b/target/riscv/insn_trans/trans_rvv.c.inc
> @@ -1201,7 +1201,7 @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, uint32_t vm,
>      dest = tcg_temp_new_ptr();
>      mask = tcg_temp_new_ptr();
>      src2 = tcg_temp_new_ptr();
> -    src1 = get_gpr(s, rs1, EXT_NONE);
> +    src1 = get_gpr(s, rs1, EXT_SIGN);
>
>      data = FIELD_DP32(data, VDATA, VM, vm);
>      data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
> --
> 2.25.1
>
>


^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v6 20/22] target/riscv: Adjust scalar reg in vector with XLEN
@ 2022-01-19  3:30     ` Alistair Francis
  0 siblings, 0 replies; 60+ messages in thread
From: Alistair Francis @ 2022-01-19  3:30 UTC (permalink / raw)
  To: LIU Zhiwei
  Cc: qemu-devel@nongnu.org Developers, open list:RISC-V, guoren,
	Bin Meng, Richard Henderson, Palmer Dabbelt, Alistair Francis

On Thu, Jan 13, 2022 at 10:20 PM LIU Zhiwei <zhiwei_liu@c-sky.com> wrote:
>
> When sew <= 32bits, not need to extend scalar reg.
> When sew > 32bits, if xlen is less that sew, we should sign extend
> the scalar register, except explicitly specified by the spec.
>
> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  target/riscv/insn_trans/trans_rvv.c.inc | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
> index 1c8086d3a6..b6502cdc7c 100644
> --- a/target/riscv/insn_trans/trans_rvv.c.inc
> +++ b/target/riscv/insn_trans/trans_rvv.c.inc
> @@ -1201,7 +1201,7 @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, uint32_t vm,
>      dest = tcg_temp_new_ptr();
>      mask = tcg_temp_new_ptr();
>      src2 = tcg_temp_new_ptr();
> -    src1 = get_gpr(s, rs1, EXT_NONE);
> +    src1 = get_gpr(s, rs1, EXT_SIGN);
>
>      data = FIELD_DP32(data, VDATA, VM, vm);
>      data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
> --
> 2.25.1
>
>


^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v6 22/22] target/riscv: Relax UXL field for debugging
  2022-01-13 11:40   ` LIU Zhiwei
@ 2022-01-19  3:34     ` Alistair Francis
  -1 siblings, 0 replies; 60+ messages in thread
From: Alistair Francis @ 2022-01-19  3:34 UTC (permalink / raw)
  To: LIU Zhiwei
  Cc: guoren, open list:RISC-V, Bin Meng, Richard Henderson,
	qemu-devel@nongnu.org Developers, Palmer Dabbelt,
	Alistair Francis

On Thu, Jan 13, 2022 at 10:23 PM LIU Zhiwei <zhiwei_liu@c-sky.com> wrote:
>
> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  target/riscv/csr.c | 7 ++++---
>  1 file changed, 4 insertions(+), 3 deletions(-)
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index d944ee9caf..1037c6b15d 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -580,7 +580,7 @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno,
>          MSTATUS_MPP | MSTATUS_MXR | MSTATUS_TVM | MSTATUS_TSR |
>          MSTATUS_TW | MSTATUS_VS;
>
> -    if (xl != MXL_RV32) {
> +    if (xl != MXL_RV32 || env->debugger) {
>          /*
>           * RV32: MPV and GVA are not in mstatus. The current plan is to
>           * add them to mstatush. For now, we just don't support it.
> @@ -905,7 +905,7 @@ static RISCVException read_sstatus(CPURISCVState *env, int csrno,
>                                     target_ulong *val)
>  {
>      target_ulong mask = (sstatus_v1_10_mask);
> -    if (env->xl != MXL_RV32) {
> +    if (env->xl != MXL_RV32 || env->debugger) {
>          mask |= SSTATUS64_UXL;
>      }
>      /* TODO: Use SXL not MXL. */
> @@ -917,7 +917,8 @@ static RISCVException write_sstatus(CPURISCVState *env, int csrno,
>                                      target_ulong val)
>  {
>      target_ulong mask = (sstatus_v1_10_mask);
> -    if (env->xl != MXL_RV32) {
> +
> +    if (env->xl != MXL_RV32 || env->debugger) {
>          mask |= SSTATUS64_UXL;
>      }
>      target_ulong newval = (env->mstatus & ~mask) | (val & mask);
> --
> 2.25.1
>
>


^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v6 22/22] target/riscv: Relax UXL field for debugging
@ 2022-01-19  3:34     ` Alistair Francis
  0 siblings, 0 replies; 60+ messages in thread
From: Alistair Francis @ 2022-01-19  3:34 UTC (permalink / raw)
  To: LIU Zhiwei
  Cc: qemu-devel@nongnu.org Developers, open list:RISC-V, guoren,
	Bin Meng, Richard Henderson, Palmer Dabbelt, Alistair Francis

On Thu, Jan 13, 2022 at 10:23 PM LIU Zhiwei <zhiwei_liu@c-sky.com> wrote:
>
> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  target/riscv/csr.c | 7 ++++---
>  1 file changed, 4 insertions(+), 3 deletions(-)
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index d944ee9caf..1037c6b15d 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -580,7 +580,7 @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno,
>          MSTATUS_MPP | MSTATUS_MXR | MSTATUS_TVM | MSTATUS_TSR |
>          MSTATUS_TW | MSTATUS_VS;
>
> -    if (xl != MXL_RV32) {
> +    if (xl != MXL_RV32 || env->debugger) {
>          /*
>           * RV32: MPV and GVA are not in mstatus. The current plan is to
>           * add them to mstatush. For now, we just don't support it.
> @@ -905,7 +905,7 @@ static RISCVException read_sstatus(CPURISCVState *env, int csrno,
>                                     target_ulong *val)
>  {
>      target_ulong mask = (sstatus_v1_10_mask);
> -    if (env->xl != MXL_RV32) {
> +    if (env->xl != MXL_RV32 || env->debugger) {
>          mask |= SSTATUS64_UXL;
>      }
>      /* TODO: Use SXL not MXL. */
> @@ -917,7 +917,8 @@ static RISCVException write_sstatus(CPURISCVState *env, int csrno,
>                                      target_ulong val)
>  {
>      target_ulong mask = (sstatus_v1_10_mask);
> -    if (env->xl != MXL_RV32) {
> +
> +    if (env->xl != MXL_RV32 || env->debugger) {
>          mask |= SSTATUS64_UXL;
>      }
>      target_ulong newval = (env->mstatus & ~mask) | (val & mask);
> --
> 2.25.1
>
>


^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v6 05/22] target/riscv: Create xl field in env
  2022-01-19  3:24     ` Alistair Francis
@ 2022-01-19  3:36       ` LIU Zhiwei
  -1 siblings, 0 replies; 60+ messages in thread
From: LIU Zhiwei @ 2022-01-19  3:36 UTC (permalink / raw)
  To: Alistair Francis
  Cc: guoren, open list:RISC-V, Bin Meng, Richard Henderson,
	qemu-devel@nongnu.org Developers, Palmer Dabbelt,
	Alistair Francis


On 2022/1/19 上午11:24, Alistair Francis wrote:
> On Thu, Jan 13, 2022 at 9:50 PM LIU Zhiwei <zhiwei_liu@c-sky.com> wrote:
>> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
> I'm not clear on why this is better?

Current xlen has been used in helper functions and many other places.  
The computation of current xlen  is not so trivial, so that we should 
recompute it as little as possible.
Fortunately, xlen only changes in very seldom cases, such as exception, 
misa write,  mstatus write, cpu reset, migration load.
So that we can only recompute XLEN in this places and cache it into 
CPURISCVState.

Thanks
Zhiwei

>
> Alistair
>
>> ---
>>   target/riscv/cpu.c        |  1 +
>>   target/riscv/cpu.h        | 31 +++++++++++++++++++++++++++++++
>>   target/riscv/cpu_helper.c | 34 ++--------------------------------
>>   target/riscv/csr.c        |  2 ++
>>   target/riscv/machine.c    | 10 ++++++++++
>>   5 files changed, 46 insertions(+), 32 deletions(-)
>>
>> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
>> index 9bc25d3055..54c1cf8ec5 100644
>> --- a/target/riscv/cpu.c
>> +++ b/target/riscv/cpu.c
>> @@ -399,6 +399,7 @@ static void riscv_cpu_reset(DeviceState *dev)
>>       /* mmte is supposed to have pm.current hardwired to 1 */
>>       env->mmte |= (PM_EXT_INITIAL | MMTE_M_PM_CURRENT);
>>   #endif
>> +    env->xl = riscv_cpu_mxl(env);
>>       cs->exception_index = RISCV_EXCP_NONE;
>>       env->load_res = -1;
>>       set_default_nan_mode(1, &env->fp_status);
>> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
>> index 4d63086765..65fd849bef 100644
>> --- a/target/riscv/cpu.h
>> +++ b/target/riscv/cpu.h
>> @@ -145,6 +145,7 @@ struct CPURISCVState {
>>       uint32_t misa_mxl_max;  /* max mxl for this cpu */
>>       uint32_t misa_ext;      /* current extensions */
>>       uint32_t misa_ext_mask; /* max ext for this cpu */
>> +    uint32_t xl;            /* current xlen */
>>
>>       /* 128-bit helpers upper part return value */
>>       target_ulong retxh;
>> @@ -443,6 +444,36 @@ static inline RISCVMXL riscv_cpu_mxl(CPURISCVState *env)
>>   }
>>   #endif
>>
>> +#if defined(TARGET_RISCV32)
>> +#define cpu_recompute_xl(env)  ((void)(env), MXL_RV32)
>> +#else
>> +static inline RISCVMXL cpu_recompute_xl(CPURISCVState *env)
>> +{
>> +    RISCVMXL xl = env->misa_mxl;
>> +#if !defined(CONFIG_USER_ONLY)
>> +    /*
>> +     * When emulating a 32-bit-only cpu, use RV32.
>> +     * When emulating a 64-bit cpu, and MXL has been reduced to RV32,
>> +     * MSTATUSH doesn't have UXL/SXL, therefore XLEN cannot be widened
>> +     * back to RV64 for lower privs.
>> +     */
>> +    if (xl != MXL_RV32) {
>> +        switch (env->priv) {
>> +        case PRV_M:
>> +            break;
>> +        case PRV_U:
>> +            xl = get_field(env->mstatus, MSTATUS64_UXL);
>> +            break;
>> +        default: /* PRV_S | PRV_H */
>> +            xl = get_field(env->mstatus, MSTATUS64_SXL);
>> +            break;
>> +        }
>> +    }
>> +#endif
>> +    return xl;
>> +}
>> +#endif
>> +
>>   /*
>>    * Encode LMUL to lmul as follows:
>>    *     LMUL    vlmul    lmul
>> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
>> index 434a83e66a..32ea066ef0 100644
>> --- a/target/riscv/cpu_helper.c
>> +++ b/target/riscv/cpu_helper.c
>> @@ -35,37 +35,6 @@ int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
>>   #endif
>>   }
>>
>> -static RISCVMXL cpu_get_xl(CPURISCVState *env)
>> -{
>> -#if defined(TARGET_RISCV32)
>> -    return MXL_RV32;
>> -#elif defined(CONFIG_USER_ONLY)
>> -    return MXL_RV64;
>> -#else
>> -    RISCVMXL xl = riscv_cpu_mxl(env);
>> -
>> -    /*
>> -     * When emulating a 32-bit-only cpu, use RV32.
>> -     * When emulating a 64-bit cpu, and MXL has been reduced to RV32,
>> -     * MSTATUSH doesn't have UXL/SXL, therefore XLEN cannot be widened
>> -     * back to RV64 for lower privs.
>> -     */
>> -    if (xl != MXL_RV32) {
>> -        switch (env->priv) {
>> -        case PRV_M:
>> -            break;
>> -        case PRV_U:
>> -            xl = get_field(env->mstatus, MSTATUS64_UXL);
>> -            break;
>> -        default: /* PRV_S | PRV_H */
>> -            xl = get_field(env->mstatus, MSTATUS64_SXL);
>> -            break;
>> -        }
>> -    }
>> -    return xl;
>> -#endif
>> -}
>> -
>>   void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
>>                             target_ulong *cs_base, uint32_t *pflags)
>>   {
>> @@ -145,7 +114,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
>>       }
>>   #endif
>>
>> -    flags = FIELD_DP32(flags, TB_FLAGS, XL, cpu_get_xl(env));
>> +    flags = FIELD_DP32(flags, TB_FLAGS, XL, env->xl);
>>
>>       *pflags = flags;
>>   }
>> @@ -361,6 +330,7 @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv)
>>       }
>>       /* tlb_flush is unnecessary as mode is contained in mmu_idx */
>>       env->priv = newpriv;
>> +    env->xl = cpu_recompute_xl(env);
>>
>>       /*
>>        * Clear the load reservation - otherwise a reservation placed in one
>> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
>> index e7578f3e0f..b282a642f5 100644
>> --- a/target/riscv/csr.c
>> +++ b/target/riscv/csr.c
>> @@ -585,6 +585,7 @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno,
>>           mstatus = set_field(mstatus, MSTATUS64_UXL, xl);
>>       }
>>       env->mstatus = mstatus;
>> +    env->xl = cpu_recompute_xl(env);
>>
>>       return RISCV_EXCP_NONE;
>>   }
>> @@ -700,6 +701,7 @@ static RISCVException write_misa(CPURISCVState *env, int csrno,
>>       /* flush translation cache */
>>       tb_flush(env_cpu(env));
>>       env->misa_ext = val;
>> +    env->xl = riscv_cpu_mxl(env);
>>       return RISCV_EXCP_NONE;
>>   }
>>
>> diff --git a/target/riscv/machine.c b/target/riscv/machine.c
>> index 13b9ab375b..e1d1029e88 100644
>> --- a/target/riscv/machine.c
>> +++ b/target/riscv/machine.c
>> @@ -185,10 +185,20 @@ static const VMStateDescription vmstate_rv128 = {
>>       }
>>   };
>>
>> +static int riscv_cpu_post_load(void *opaque, int version_id)
>> +{
>> +    RISCVCPU *cpu = opaque;
>> +    CPURISCVState *env = &cpu->env;
>> +
>> +    env->xl = cpu_recompute_xl(env);
>> +    return 0;
>> +}
>> +
>>   const VMStateDescription vmstate_riscv_cpu = {
>>       .name = "cpu",
>>       .version_id = 3,
>>       .minimum_version_id = 3,
>> +    .post_load = riscv_cpu_post_load,
>>       .fields = (VMStateField[]) {
>>           VMSTATE_UINTTL_ARRAY(env.gpr, RISCVCPU, 32),
>>           VMSTATE_UINT64_ARRAY(env.fpr, RISCVCPU, 32),
>> --
>> 2.25.1
>>
>>


^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v6 05/22] target/riscv: Create xl field in env
@ 2022-01-19  3:36       ` LIU Zhiwei
  0 siblings, 0 replies; 60+ messages in thread
From: LIU Zhiwei @ 2022-01-19  3:36 UTC (permalink / raw)
  To: Alistair Francis
  Cc: qemu-devel@nongnu.org Developers, open list:RISC-V, guoren,
	Bin Meng, Richard Henderson, Palmer Dabbelt, Alistair Francis


On 2022/1/19 上午11:24, Alistair Francis wrote:
> On Thu, Jan 13, 2022 at 9:50 PM LIU Zhiwei <zhiwei_liu@c-sky.com> wrote:
>> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
> I'm not clear on why this is better?

Current xlen has been used in helper functions and many other places.  
The computation of current xlen  is not so trivial, so that we should 
recompute it as little as possible.
Fortunately, xlen only changes in very seldom cases, such as exception, 
misa write,  mstatus write, cpu reset, migration load.
So that we can only recompute XLEN in this places and cache it into 
CPURISCVState.

Thanks
Zhiwei

>
> Alistair
>
>> ---
>>   target/riscv/cpu.c        |  1 +
>>   target/riscv/cpu.h        | 31 +++++++++++++++++++++++++++++++
>>   target/riscv/cpu_helper.c | 34 ++--------------------------------
>>   target/riscv/csr.c        |  2 ++
>>   target/riscv/machine.c    | 10 ++++++++++
>>   5 files changed, 46 insertions(+), 32 deletions(-)
>>
>> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
>> index 9bc25d3055..54c1cf8ec5 100644
>> --- a/target/riscv/cpu.c
>> +++ b/target/riscv/cpu.c
>> @@ -399,6 +399,7 @@ static void riscv_cpu_reset(DeviceState *dev)
>>       /* mmte is supposed to have pm.current hardwired to 1 */
>>       env->mmte |= (PM_EXT_INITIAL | MMTE_M_PM_CURRENT);
>>   #endif
>> +    env->xl = riscv_cpu_mxl(env);
>>       cs->exception_index = RISCV_EXCP_NONE;
>>       env->load_res = -1;
>>       set_default_nan_mode(1, &env->fp_status);
>> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
>> index 4d63086765..65fd849bef 100644
>> --- a/target/riscv/cpu.h
>> +++ b/target/riscv/cpu.h
>> @@ -145,6 +145,7 @@ struct CPURISCVState {
>>       uint32_t misa_mxl_max;  /* max mxl for this cpu */
>>       uint32_t misa_ext;      /* current extensions */
>>       uint32_t misa_ext_mask; /* max ext for this cpu */
>> +    uint32_t xl;            /* current xlen */
>>
>>       /* 128-bit helpers upper part return value */
>>       target_ulong retxh;
>> @@ -443,6 +444,36 @@ static inline RISCVMXL riscv_cpu_mxl(CPURISCVState *env)
>>   }
>>   #endif
>>
>> +#if defined(TARGET_RISCV32)
>> +#define cpu_recompute_xl(env)  ((void)(env), MXL_RV32)
>> +#else
>> +static inline RISCVMXL cpu_recompute_xl(CPURISCVState *env)
>> +{
>> +    RISCVMXL xl = env->misa_mxl;
>> +#if !defined(CONFIG_USER_ONLY)
>> +    /*
>> +     * When emulating a 32-bit-only cpu, use RV32.
>> +     * When emulating a 64-bit cpu, and MXL has been reduced to RV32,
>> +     * MSTATUSH doesn't have UXL/SXL, therefore XLEN cannot be widened
>> +     * back to RV64 for lower privs.
>> +     */
>> +    if (xl != MXL_RV32) {
>> +        switch (env->priv) {
>> +        case PRV_M:
>> +            break;
>> +        case PRV_U:
>> +            xl = get_field(env->mstatus, MSTATUS64_UXL);
>> +            break;
>> +        default: /* PRV_S | PRV_H */
>> +            xl = get_field(env->mstatus, MSTATUS64_SXL);
>> +            break;
>> +        }
>> +    }
>> +#endif
>> +    return xl;
>> +}
>> +#endif
>> +
>>   /*
>>    * Encode LMUL to lmul as follows:
>>    *     LMUL    vlmul    lmul
>> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
>> index 434a83e66a..32ea066ef0 100644
>> --- a/target/riscv/cpu_helper.c
>> +++ b/target/riscv/cpu_helper.c
>> @@ -35,37 +35,6 @@ int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
>>   #endif
>>   }
>>
>> -static RISCVMXL cpu_get_xl(CPURISCVState *env)
>> -{
>> -#if defined(TARGET_RISCV32)
>> -    return MXL_RV32;
>> -#elif defined(CONFIG_USER_ONLY)
>> -    return MXL_RV64;
>> -#else
>> -    RISCVMXL xl = riscv_cpu_mxl(env);
>> -
>> -    /*
>> -     * When emulating a 32-bit-only cpu, use RV32.
>> -     * When emulating a 64-bit cpu, and MXL has been reduced to RV32,
>> -     * MSTATUSH doesn't have UXL/SXL, therefore XLEN cannot be widened
>> -     * back to RV64 for lower privs.
>> -     */
>> -    if (xl != MXL_RV32) {
>> -        switch (env->priv) {
>> -        case PRV_M:
>> -            break;
>> -        case PRV_U:
>> -            xl = get_field(env->mstatus, MSTATUS64_UXL);
>> -            break;
>> -        default: /* PRV_S | PRV_H */
>> -            xl = get_field(env->mstatus, MSTATUS64_SXL);
>> -            break;
>> -        }
>> -    }
>> -    return xl;
>> -#endif
>> -}
>> -
>>   void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
>>                             target_ulong *cs_base, uint32_t *pflags)
>>   {
>> @@ -145,7 +114,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
>>       }
>>   #endif
>>
>> -    flags = FIELD_DP32(flags, TB_FLAGS, XL, cpu_get_xl(env));
>> +    flags = FIELD_DP32(flags, TB_FLAGS, XL, env->xl);
>>
>>       *pflags = flags;
>>   }
>> @@ -361,6 +330,7 @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv)
>>       }
>>       /* tlb_flush is unnecessary as mode is contained in mmu_idx */
>>       env->priv = newpriv;
>> +    env->xl = cpu_recompute_xl(env);
>>
>>       /*
>>        * Clear the load reservation - otherwise a reservation placed in one
>> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
>> index e7578f3e0f..b282a642f5 100644
>> --- a/target/riscv/csr.c
>> +++ b/target/riscv/csr.c
>> @@ -585,6 +585,7 @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno,
>>           mstatus = set_field(mstatus, MSTATUS64_UXL, xl);
>>       }
>>       env->mstatus = mstatus;
>> +    env->xl = cpu_recompute_xl(env);
>>
>>       return RISCV_EXCP_NONE;
>>   }
>> @@ -700,6 +701,7 @@ static RISCVException write_misa(CPURISCVState *env, int csrno,
>>       /* flush translation cache */
>>       tb_flush(env_cpu(env));
>>       env->misa_ext = val;
>> +    env->xl = riscv_cpu_mxl(env);
>>       return RISCV_EXCP_NONE;
>>   }
>>
>> diff --git a/target/riscv/machine.c b/target/riscv/machine.c
>> index 13b9ab375b..e1d1029e88 100644
>> --- a/target/riscv/machine.c
>> +++ b/target/riscv/machine.c
>> @@ -185,10 +185,20 @@ static const VMStateDescription vmstate_rv128 = {
>>       }
>>   };
>>
>> +static int riscv_cpu_post_load(void *opaque, int version_id)
>> +{
>> +    RISCVCPU *cpu = opaque;
>> +    CPURISCVState *env = &cpu->env;
>> +
>> +    env->xl = cpu_recompute_xl(env);
>> +    return 0;
>> +}
>> +
>>   const VMStateDescription vmstate_riscv_cpu = {
>>       .name = "cpu",
>>       .version_id = 3,
>>       .minimum_version_id = 3,
>> +    .post_load = riscv_cpu_post_load,
>>       .fields = (VMStateField[]) {
>>           VMSTATE_UINTTL_ARRAY(env.gpr, RISCVCPU, 32),
>>           VMSTATE_UINT64_ARRAY(env.fpr, RISCVCPU, 32),
>> --
>> 2.25.1
>>
>>


^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v6 05/22] target/riscv: Create xl field in env
  2022-01-19  3:36       ` LIU Zhiwei
@ 2022-01-19  3:43         ` Alistair Francis
  -1 siblings, 0 replies; 60+ messages in thread
From: Alistair Francis @ 2022-01-19  3:43 UTC (permalink / raw)
  To: LIU Zhiwei
  Cc: guoren, open list:RISC-V, Bin Meng, Richard Henderson,
	qemu-devel@nongnu.org Developers, Palmer Dabbelt,
	Alistair Francis

On Wed, Jan 19, 2022 at 1:36 PM LIU Zhiwei <zhiwei_liu@c-sky.com> wrote:
>
>
> On 2022/1/19 上午11:24, Alistair Francis wrote:
> > On Thu, Jan 13, 2022 at 9:50 PM LIU Zhiwei <zhiwei_liu@c-sky.com> wrote:
> >> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
> > I'm not clear on why this is better?
>
> Current xlen has been used in helper functions and many other places.
> The computation of current xlen  is not so trivial, so that we should
> recompute it as little as possible.
> Fortunately, xlen only changes in very seldom cases, such as exception,
> misa write,  mstatus write, cpu reset, migration load.
> So that we can only recompute XLEN in this places and cache it into
> CPURISCVState.

Sounds good! Do you mind adding that to the commit message

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

>
> Thanks
> Zhiwei
>
> >
> > Alistair
> >
> >> ---
> >>   target/riscv/cpu.c        |  1 +
> >>   target/riscv/cpu.h        | 31 +++++++++++++++++++++++++++++++
> >>   target/riscv/cpu_helper.c | 34 ++--------------------------------
> >>   target/riscv/csr.c        |  2 ++
> >>   target/riscv/machine.c    | 10 ++++++++++
> >>   5 files changed, 46 insertions(+), 32 deletions(-)
> >>
> >> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> >> index 9bc25d3055..54c1cf8ec5 100644
> >> --- a/target/riscv/cpu.c
> >> +++ b/target/riscv/cpu.c
> >> @@ -399,6 +399,7 @@ static void riscv_cpu_reset(DeviceState *dev)
> >>       /* mmte is supposed to have pm.current hardwired to 1 */
> >>       env->mmte |= (PM_EXT_INITIAL | MMTE_M_PM_CURRENT);
> >>   #endif
> >> +    env->xl = riscv_cpu_mxl(env);
> >>       cs->exception_index = RISCV_EXCP_NONE;
> >>       env->load_res = -1;
> >>       set_default_nan_mode(1, &env->fp_status);
> >> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> >> index 4d63086765..65fd849bef 100644
> >> --- a/target/riscv/cpu.h
> >> +++ b/target/riscv/cpu.h
> >> @@ -145,6 +145,7 @@ struct CPURISCVState {
> >>       uint32_t misa_mxl_max;  /* max mxl for this cpu */
> >>       uint32_t misa_ext;      /* current extensions */
> >>       uint32_t misa_ext_mask; /* max ext for this cpu */
> >> +    uint32_t xl;            /* current xlen */
> >>
> >>       /* 128-bit helpers upper part return value */
> >>       target_ulong retxh;
> >> @@ -443,6 +444,36 @@ static inline RISCVMXL riscv_cpu_mxl(CPURISCVState *env)
> >>   }
> >>   #endif
> >>
> >> +#if defined(TARGET_RISCV32)
> >> +#define cpu_recompute_xl(env)  ((void)(env), MXL_RV32)
> >> +#else
> >> +static inline RISCVMXL cpu_recompute_xl(CPURISCVState *env)
> >> +{
> >> +    RISCVMXL xl = env->misa_mxl;
> >> +#if !defined(CONFIG_USER_ONLY)
> >> +    /*
> >> +     * When emulating a 32-bit-only cpu, use RV32.
> >> +     * When emulating a 64-bit cpu, and MXL has been reduced to RV32,
> >> +     * MSTATUSH doesn't have UXL/SXL, therefore XLEN cannot be widened
> >> +     * back to RV64 for lower privs.
> >> +     */
> >> +    if (xl != MXL_RV32) {
> >> +        switch (env->priv) {
> >> +        case PRV_M:
> >> +            break;
> >> +        case PRV_U:
> >> +            xl = get_field(env->mstatus, MSTATUS64_UXL);
> >> +            break;
> >> +        default: /* PRV_S | PRV_H */
> >> +            xl = get_field(env->mstatus, MSTATUS64_SXL);
> >> +            break;
> >> +        }
> >> +    }
> >> +#endif
> >> +    return xl;
> >> +}
> >> +#endif
> >> +
> >>   /*
> >>    * Encode LMUL to lmul as follows:
> >>    *     LMUL    vlmul    lmul
> >> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> >> index 434a83e66a..32ea066ef0 100644
> >> --- a/target/riscv/cpu_helper.c
> >> +++ b/target/riscv/cpu_helper.c
> >> @@ -35,37 +35,6 @@ int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
> >>   #endif
> >>   }
> >>
> >> -static RISCVMXL cpu_get_xl(CPURISCVState *env)
> >> -{
> >> -#if defined(TARGET_RISCV32)
> >> -    return MXL_RV32;
> >> -#elif defined(CONFIG_USER_ONLY)
> >> -    return MXL_RV64;
> >> -#else
> >> -    RISCVMXL xl = riscv_cpu_mxl(env);
> >> -
> >> -    /*
> >> -     * When emulating a 32-bit-only cpu, use RV32.
> >> -     * When emulating a 64-bit cpu, and MXL has been reduced to RV32,
> >> -     * MSTATUSH doesn't have UXL/SXL, therefore XLEN cannot be widened
> >> -     * back to RV64 for lower privs.
> >> -     */
> >> -    if (xl != MXL_RV32) {
> >> -        switch (env->priv) {
> >> -        case PRV_M:
> >> -            break;
> >> -        case PRV_U:
> >> -            xl = get_field(env->mstatus, MSTATUS64_UXL);
> >> -            break;
> >> -        default: /* PRV_S | PRV_H */
> >> -            xl = get_field(env->mstatus, MSTATUS64_SXL);
> >> -            break;
> >> -        }
> >> -    }
> >> -    return xl;
> >> -#endif
> >> -}
> >> -
> >>   void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
> >>                             target_ulong *cs_base, uint32_t *pflags)
> >>   {
> >> @@ -145,7 +114,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
> >>       }
> >>   #endif
> >>
> >> -    flags = FIELD_DP32(flags, TB_FLAGS, XL, cpu_get_xl(env));
> >> +    flags = FIELD_DP32(flags, TB_FLAGS, XL, env->xl);
> >>
> >>       *pflags = flags;
> >>   }
> >> @@ -361,6 +330,7 @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv)
> >>       }
> >>       /* tlb_flush is unnecessary as mode is contained in mmu_idx */
> >>       env->priv = newpriv;
> >> +    env->xl = cpu_recompute_xl(env);
> >>
> >>       /*
> >>        * Clear the load reservation - otherwise a reservation placed in one
> >> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> >> index e7578f3e0f..b282a642f5 100644
> >> --- a/target/riscv/csr.c
> >> +++ b/target/riscv/csr.c
> >> @@ -585,6 +585,7 @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno,
> >>           mstatus = set_field(mstatus, MSTATUS64_UXL, xl);
> >>       }
> >>       env->mstatus = mstatus;
> >> +    env->xl = cpu_recompute_xl(env);
> >>
> >>       return RISCV_EXCP_NONE;
> >>   }
> >> @@ -700,6 +701,7 @@ static RISCVException write_misa(CPURISCVState *env, int csrno,
> >>       /* flush translation cache */
> >>       tb_flush(env_cpu(env));
> >>       env->misa_ext = val;
> >> +    env->xl = riscv_cpu_mxl(env);
> >>       return RISCV_EXCP_NONE;
> >>   }
> >>
> >> diff --git a/target/riscv/machine.c b/target/riscv/machine.c
> >> index 13b9ab375b..e1d1029e88 100644
> >> --- a/target/riscv/machine.c
> >> +++ b/target/riscv/machine.c
> >> @@ -185,10 +185,20 @@ static const VMStateDescription vmstate_rv128 = {
> >>       }
> >>   };
> >>
> >> +static int riscv_cpu_post_load(void *opaque, int version_id)
> >> +{
> >> +    RISCVCPU *cpu = opaque;
> >> +    CPURISCVState *env = &cpu->env;
> >> +
> >> +    env->xl = cpu_recompute_xl(env);
> >> +    return 0;
> >> +}
> >> +
> >>   const VMStateDescription vmstate_riscv_cpu = {
> >>       .name = "cpu",
> >>       .version_id = 3,
> >>       .minimum_version_id = 3,
> >> +    .post_load = riscv_cpu_post_load,
> >>       .fields = (VMStateField[]) {
> >>           VMSTATE_UINTTL_ARRAY(env.gpr, RISCVCPU, 32),
> >>           VMSTATE_UINT64_ARRAY(env.fpr, RISCVCPU, 32),
> >> --
> >> 2.25.1
> >>
> >>


^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH v6 05/22] target/riscv: Create xl field in env
@ 2022-01-19  3:43         ` Alistair Francis
  0 siblings, 0 replies; 60+ messages in thread
From: Alistair Francis @ 2022-01-19  3:43 UTC (permalink / raw)
  To: LIU Zhiwei
  Cc: qemu-devel@nongnu.org Developers, open list:RISC-V, guoren,
	Bin Meng, Richard Henderson, Palmer Dabbelt, Alistair Francis

On Wed, Jan 19, 2022 at 1:36 PM LIU Zhiwei <zhiwei_liu@c-sky.com> wrote:
>
>
> On 2022/1/19 上午11:24, Alistair Francis wrote:
> > On Thu, Jan 13, 2022 at 9:50 PM LIU Zhiwei <zhiwei_liu@c-sky.com> wrote:
> >> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
> > I'm not clear on why this is better?
>
> Current xlen has been used in helper functions and many other places.
> The computation of current xlen  is not so trivial, so that we should
> recompute it as little as possible.
> Fortunately, xlen only changes in very seldom cases, such as exception,
> misa write,  mstatus write, cpu reset, migration load.
> So that we can only recompute XLEN in this places and cache it into
> CPURISCVState.

Sounds good! Do you mind adding that to the commit message

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

>
> Thanks
> Zhiwei
>
> >
> > Alistair
> >
> >> ---
> >>   target/riscv/cpu.c        |  1 +
> >>   target/riscv/cpu.h        | 31 +++++++++++++++++++++++++++++++
> >>   target/riscv/cpu_helper.c | 34 ++--------------------------------
> >>   target/riscv/csr.c        |  2 ++
> >>   target/riscv/machine.c    | 10 ++++++++++
> >>   5 files changed, 46 insertions(+), 32 deletions(-)
> >>
> >> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> >> index 9bc25d3055..54c1cf8ec5 100644
> >> --- a/target/riscv/cpu.c
> >> +++ b/target/riscv/cpu.c
> >> @@ -399,6 +399,7 @@ static void riscv_cpu_reset(DeviceState *dev)
> >>       /* mmte is supposed to have pm.current hardwired to 1 */
> >>       env->mmte |= (PM_EXT_INITIAL | MMTE_M_PM_CURRENT);
> >>   #endif
> >> +    env->xl = riscv_cpu_mxl(env);
> >>       cs->exception_index = RISCV_EXCP_NONE;
> >>       env->load_res = -1;
> >>       set_default_nan_mode(1, &env->fp_status);
> >> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> >> index 4d63086765..65fd849bef 100644
> >> --- a/target/riscv/cpu.h
> >> +++ b/target/riscv/cpu.h
> >> @@ -145,6 +145,7 @@ struct CPURISCVState {
> >>       uint32_t misa_mxl_max;  /* max mxl for this cpu */
> >>       uint32_t misa_ext;      /* current extensions */
> >>       uint32_t misa_ext_mask; /* max ext for this cpu */
> >> +    uint32_t xl;            /* current xlen */
> >>
> >>       /* 128-bit helpers upper part return value */
> >>       target_ulong retxh;
> >> @@ -443,6 +444,36 @@ static inline RISCVMXL riscv_cpu_mxl(CPURISCVState *env)
> >>   }
> >>   #endif
> >>
> >> +#if defined(TARGET_RISCV32)
> >> +#define cpu_recompute_xl(env)  ((void)(env), MXL_RV32)
> >> +#else
> >> +static inline RISCVMXL cpu_recompute_xl(CPURISCVState *env)
> >> +{
> >> +    RISCVMXL xl = env->misa_mxl;
> >> +#if !defined(CONFIG_USER_ONLY)
> >> +    /*
> >> +     * When emulating a 32-bit-only cpu, use RV32.
> >> +     * When emulating a 64-bit cpu, and MXL has been reduced to RV32,
> >> +     * MSTATUSH doesn't have UXL/SXL, therefore XLEN cannot be widened
> >> +     * back to RV64 for lower privs.
> >> +     */
> >> +    if (xl != MXL_RV32) {
> >> +        switch (env->priv) {
> >> +        case PRV_M:
> >> +            break;
> >> +        case PRV_U:
> >> +            xl = get_field(env->mstatus, MSTATUS64_UXL);
> >> +            break;
> >> +        default: /* PRV_S | PRV_H */
> >> +            xl = get_field(env->mstatus, MSTATUS64_SXL);
> >> +            break;
> >> +        }
> >> +    }
> >> +#endif
> >> +    return xl;
> >> +}
> >> +#endif
> >> +
> >>   /*
> >>    * Encode LMUL to lmul as follows:
> >>    *     LMUL    vlmul    lmul
> >> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> >> index 434a83e66a..32ea066ef0 100644
> >> --- a/target/riscv/cpu_helper.c
> >> +++ b/target/riscv/cpu_helper.c
> >> @@ -35,37 +35,6 @@ int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
> >>   #endif
> >>   }
> >>
> >> -static RISCVMXL cpu_get_xl(CPURISCVState *env)
> >> -{
> >> -#if defined(TARGET_RISCV32)
> >> -    return MXL_RV32;
> >> -#elif defined(CONFIG_USER_ONLY)
> >> -    return MXL_RV64;
> >> -#else
> >> -    RISCVMXL xl = riscv_cpu_mxl(env);
> >> -
> >> -    /*
> >> -     * When emulating a 32-bit-only cpu, use RV32.
> >> -     * When emulating a 64-bit cpu, and MXL has been reduced to RV32,
> >> -     * MSTATUSH doesn't have UXL/SXL, therefore XLEN cannot be widened
> >> -     * back to RV64 for lower privs.
> >> -     */
> >> -    if (xl != MXL_RV32) {
> >> -        switch (env->priv) {
> >> -        case PRV_M:
> >> -            break;
> >> -        case PRV_U:
> >> -            xl = get_field(env->mstatus, MSTATUS64_UXL);
> >> -            break;
> >> -        default: /* PRV_S | PRV_H */
> >> -            xl = get_field(env->mstatus, MSTATUS64_SXL);
> >> -            break;
> >> -        }
> >> -    }
> >> -    return xl;
> >> -#endif
> >> -}
> >> -
> >>   void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
> >>                             target_ulong *cs_base, uint32_t *pflags)
> >>   {
> >> @@ -145,7 +114,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
> >>       }
> >>   #endif
> >>
> >> -    flags = FIELD_DP32(flags, TB_FLAGS, XL, cpu_get_xl(env));
> >> +    flags = FIELD_DP32(flags, TB_FLAGS, XL, env->xl);
> >>
> >>       *pflags = flags;
> >>   }
> >> @@ -361,6 +330,7 @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv)
> >>       }
> >>       /* tlb_flush is unnecessary as mode is contained in mmu_idx */
> >>       env->priv = newpriv;
> >> +    env->xl = cpu_recompute_xl(env);
> >>
> >>       /*
> >>        * Clear the load reservation - otherwise a reservation placed in one
> >> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> >> index e7578f3e0f..b282a642f5 100644
> >> --- a/target/riscv/csr.c
> >> +++ b/target/riscv/csr.c
> >> @@ -585,6 +585,7 @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno,
> >>           mstatus = set_field(mstatus, MSTATUS64_UXL, xl);
> >>       }
> >>       env->mstatus = mstatus;
> >> +    env->xl = cpu_recompute_xl(env);
> >>
> >>       return RISCV_EXCP_NONE;
> >>   }
> >> @@ -700,6 +701,7 @@ static RISCVException write_misa(CPURISCVState *env, int csrno,
> >>       /* flush translation cache */
> >>       tb_flush(env_cpu(env));
> >>       env->misa_ext = val;
> >> +    env->xl = riscv_cpu_mxl(env);
> >>       return RISCV_EXCP_NONE;
> >>   }
> >>
> >> diff --git a/target/riscv/machine.c b/target/riscv/machine.c
> >> index 13b9ab375b..e1d1029e88 100644
> >> --- a/target/riscv/machine.c
> >> +++ b/target/riscv/machine.c
> >> @@ -185,10 +185,20 @@ static const VMStateDescription vmstate_rv128 = {
> >>       }
> >>   };
> >>
> >> +static int riscv_cpu_post_load(void *opaque, int version_id)
> >> +{
> >> +    RISCVCPU *cpu = opaque;
> >> +    CPURISCVState *env = &cpu->env;
> >> +
> >> +    env->xl = cpu_recompute_xl(env);
> >> +    return 0;
> >> +}
> >> +
> >>   const VMStateDescription vmstate_riscv_cpu = {
> >>       .name = "cpu",
> >>       .version_id = 3,
> >>       .minimum_version_id = 3,
> >> +    .post_load = riscv_cpu_post_load,
> >>       .fields = (VMStateField[]) {
> >>           VMSTATE_UINTTL_ARRAY(env.gpr, RISCVCPU, 32),
> >>           VMSTATE_UINT64_ARRAY(env.fpr, RISCVCPU, 32),
> >> --
> >> 2.25.1
> >>
> >>


^ permalink raw reply	[flat|nested] 60+ messages in thread

end of thread, other threads:[~2022-01-19  3:46 UTC | newest]

Thread overview: 60+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-13 11:39 [PATCH v6 00/22] Support UXL filed in xstatus LIU Zhiwei
2022-01-13 11:39 ` LIU Zhiwei
2022-01-13 11:39 ` [PATCH v6 01/22] target/riscv: Adjust pmpcfg access with mxl LIU Zhiwei
2022-01-13 11:39   ` LIU Zhiwei
2022-01-19  3:20   ` Alistair Francis
2022-01-19  3:20     ` Alistair Francis
2022-01-13 11:39 ` [PATCH v6 02/22] target/riscv: Don't save pc when exception return LIU Zhiwei
2022-01-13 11:39   ` LIU Zhiwei
2022-01-13 11:39 ` [PATCH v6 03/22] target/riscv: Sign extend link reg for jal and jalr LIU Zhiwei
2022-01-13 11:39   ` LIU Zhiwei
2022-01-19  3:21   ` Alistair Francis
2022-01-19  3:21     ` Alistair Francis
2022-01-13 11:39 ` [PATCH v6 04/22] target/riscv: Sign extend pc for different XLEN LIU Zhiwei
2022-01-13 11:39   ` LIU Zhiwei
2022-01-13 11:39 ` [PATCH v6 05/22] target/riscv: Create xl field in env LIU Zhiwei
2022-01-13 11:39   ` LIU Zhiwei
2022-01-19  3:24   ` Alistair Francis
2022-01-19  3:24     ` Alistair Francis
2022-01-19  3:36     ` LIU Zhiwei
2022-01-19  3:36       ` LIU Zhiwei
2022-01-19  3:43       ` Alistair Francis
2022-01-19  3:43         ` Alistair Francis
2022-01-13 11:39 ` [PATCH v6 06/22] target/riscv: Ignore the pc bits above XLEN LIU Zhiwei
2022-01-13 11:39   ` LIU Zhiwei
2022-01-13 11:39 ` [PATCH v6 07/22] target/riscv: Extend pc for runtime pc write LIU Zhiwei
2022-01-13 11:39   ` LIU Zhiwei
2022-01-13 11:39 ` [PATCH v6 08/22] target/riscv: Use gdb xml according to max mxlen LIU Zhiwei
2022-01-13 11:39   ` LIU Zhiwei
2022-01-13 11:39 ` [PATCH v6 09/22] target/riscv: Relax debug check for pm write LIU Zhiwei
2022-01-13 11:39   ` LIU Zhiwei
2022-01-13 11:39 ` [PATCH v6 10/22] target/riscv: Adjust csr write mask with XLEN LIU Zhiwei
2022-01-13 11:39   ` LIU Zhiwei
2022-01-13 11:39 ` [PATCH v6 11/22] target/riscv: Create current pm fields in env LIU Zhiwei
2022-01-13 11:39   ` LIU Zhiwei
2022-01-13 11:39 ` [PATCH v6 12/22] target/riscv: Alloc tcg global for cur_pm[mask|base] LIU Zhiwei
2022-01-13 11:39   ` LIU Zhiwei
2022-01-13 11:39 ` [PATCH v6 13/22] target/riscv: Calculate address according to XLEN LIU Zhiwei
2022-01-13 11:39   ` LIU Zhiwei
2022-01-13 11:39 ` [PATCH v6 14/22] target/riscv: Split pm_enabled into mask and base LIU Zhiwei
2022-01-13 11:39   ` LIU Zhiwei
2022-01-13 11:39 ` [PATCH v6 15/22] target/riscv: Split out the vill from vtype LIU Zhiwei
2022-01-13 11:39   ` LIU Zhiwei
2022-01-13 11:39 ` [PATCH v6 16/22] target/riscv: Adjust vsetvl according to XLEN LIU Zhiwei
2022-01-13 11:39   ` LIU Zhiwei
2022-01-13 11:39 ` [PATCH v6 17/22] target/riscv: Remove VILL field in VTYPE LIU Zhiwei
2022-01-13 11:39   ` LIU Zhiwei
2022-01-13 11:40 ` [PATCH v6 18/22] target/riscv: Fix check range for first fault only LIU Zhiwei
2022-01-13 11:40   ` LIU Zhiwei
2022-01-13 11:40 ` [PATCH v6 19/22] target/riscv: Adjust vector address with mask LIU Zhiwei
2022-01-13 11:40   ` LIU Zhiwei
2022-01-13 11:40 ` [PATCH v6 20/22] target/riscv: Adjust scalar reg in vector with XLEN LIU Zhiwei
2022-01-13 11:40   ` LIU Zhiwei
2022-01-19  3:30   ` Alistair Francis
2022-01-19  3:30     ` Alistair Francis
2022-01-13 11:40 ` [PATCH v6 21/22] target/riscv: Enable uxl field write LIU Zhiwei
2022-01-13 11:40   ` LIU Zhiwei
2022-01-13 11:40 ` [PATCH v6 22/22] target/riscv: Relax UXL field for debugging LIU Zhiwei
2022-01-13 11:40   ` LIU Zhiwei
2022-01-19  3:34   ` Alistair Francis
2022-01-19  3:34     ` Alistair Francis

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.