All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/13] Support UXL filed in xstatus.
@ 2021-11-01 10:01 ` LIU Zhiwei
  0 siblings, 0 replies; 88+ messages in thread
From: LIU Zhiwei @ 2021-11-01 10:01 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: palmer, richard.henderson, bin.meng, 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.

LIU Zhiwei (13):
  target/riscv: Sign extend pc for different ol
  target/riscv: Extend pc for runtime pc write
  target/riscv: Ignore the pc bits above XLEN
  target/riscv: Use gdb xml according to max mxlen
  target/riscv: Calculate address according to ol
  target/riscv: Adjust vsetvl according to ol
  target/riscv: Ajdust vector atomic check with ol
  target/riscv: Fix check range for first fault only
  target/riscv: Adjust vector address with ol
  target/riscv: Adjust scalar reg in vector with ol
  target/riscv: Switch context in exception return
  target/riscv: Don't save pc when exception return
  target/riscv: Enable uxl field write

 target/riscv/cpu.c                            | 20 ++++-
 target/riscv/cpu.h                            |  4 +
 target/riscv/cpu_helper.c                     |  4 +-
 target/riscv/csr.c                            |  6 +-
 target/riscv/gdbstub.c                        | 73 ++++++++++++-----
 target/riscv/helper.h                         |  7 +-
 target/riscv/insn_trans/trans_privileged.c.inc|  9 +--
 target/riscv/insn_trans/trans_rvd.c.inc       | 20 ++---
 target/riscv/insn_trans/trans_rvf.c.inc       | 21 ++---
 target/riscv/insn_trans/trans_rvi.c.inc       | 23 +++---
 target/riscv/insn_trans/trans_rvv.c.inc       | 19 +++--
 target/riscv/internals.h                      |  1 +
 target/riscv/op_helper.c                      | 30 ++++++-
 target/riscv/translate.c                      | 23 +++++-
 target/riscv/vector_helper.c                  | 81 +++++++++++++------
 15 files changed, 233 insertions(+), 108 deletions(-)

-- 
2.25.1



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

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

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

LIU Zhiwei (13):
  target/riscv: Sign extend pc for different ol
  target/riscv: Extend pc for runtime pc write
  target/riscv: Ignore the pc bits above XLEN
  target/riscv: Use gdb xml according to max mxlen
  target/riscv: Calculate address according to ol
  target/riscv: Adjust vsetvl according to ol
  target/riscv: Ajdust vector atomic check with ol
  target/riscv: Fix check range for first fault only
  target/riscv: Adjust vector address with ol
  target/riscv: Adjust scalar reg in vector with ol
  target/riscv: Switch context in exception return
  target/riscv: Don't save pc when exception return
  target/riscv: Enable uxl field write

 target/riscv/cpu.c                            | 20 ++++-
 target/riscv/cpu.h                            |  4 +
 target/riscv/cpu_helper.c                     |  4 +-
 target/riscv/csr.c                            |  6 +-
 target/riscv/gdbstub.c                        | 73 ++++++++++++-----
 target/riscv/helper.h                         |  7 +-
 target/riscv/insn_trans/trans_privileged.c.inc|  9 +--
 target/riscv/insn_trans/trans_rvd.c.inc       | 20 ++---
 target/riscv/insn_trans/trans_rvf.c.inc       | 21 ++---
 target/riscv/insn_trans/trans_rvi.c.inc       | 23 +++---
 target/riscv/insn_trans/trans_rvv.c.inc       | 19 +++--
 target/riscv/internals.h                      |  1 +
 target/riscv/op_helper.c                      | 30 ++++++-
 target/riscv/translate.c                      | 23 +++++-
 target/riscv/vector_helper.c                  | 81 +++++++++++++------
 15 files changed, 233 insertions(+), 108 deletions(-)

-- 
2.25.1



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

* [PATCH 01/13] target/riscv: Sign extend pc for different ol
  2021-11-01 10:01 ` LIU Zhiwei
@ 2021-11-01 10:01   ` LIU Zhiwei
  -1 siblings, 0 replies; 88+ messages in thread
From: LIU Zhiwei @ 2021-11-01 10:01 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: palmer, richard.henderson, bin.meng, 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>
---
 target/riscv/translate.c | 23 +++++++++++++++++++----
 1 file changed, 19 insertions(+), 4 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 1d57bc97b5..7d78a3561e 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -150,16 +150,31 @@ 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(DisasContext *ctx, target_ulong dest)
+{
+    TCGv t = tcg_constant_tl(dest);
+    switch (get_ol(ctx)) {
+    case MXL_RV32:
+        tcg_gen_ext32s_tl(cpu_pc, t);
+        break;
+    case MXL_RV64:
+        tcg_gen_mov_tl(cpu_pc, t);
+        break;
+    default:
+        g_assert_not_reached();
+    }
+}
+
 static void generate_exception(DisasContext *ctx, int excp)
 {
-    tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
+    gen_set_pc(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(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;
@@ -179,10 +194,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(ctx, dest);
         tcg_gen_exit_tb(ctx->base.tb, n);
     } else {
-        tcg_gen_movi_tl(cpu_pc, dest);
+        gen_set_pc(ctx, dest);
         tcg_gen_lookup_and_goto_ptr();
     }
 }
-- 
2.25.1



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

* [PATCH 01/13] target/riscv: Sign extend pc for different ol
@ 2021-11-01 10:01   ` LIU Zhiwei
  0 siblings, 0 replies; 88+ messages in thread
From: LIU Zhiwei @ 2021-11-01 10:01 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: Alistair.Francis, palmer, bin.meng, richard.henderson, 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>
---
 target/riscv/translate.c | 23 +++++++++++++++++++----
 1 file changed, 19 insertions(+), 4 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 1d57bc97b5..7d78a3561e 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -150,16 +150,31 @@ 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(DisasContext *ctx, target_ulong dest)
+{
+    TCGv t = tcg_constant_tl(dest);
+    switch (get_ol(ctx)) {
+    case MXL_RV32:
+        tcg_gen_ext32s_tl(cpu_pc, t);
+        break;
+    case MXL_RV64:
+        tcg_gen_mov_tl(cpu_pc, t);
+        break;
+    default:
+        g_assert_not_reached();
+    }
+}
+
 static void generate_exception(DisasContext *ctx, int excp)
 {
-    tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
+    gen_set_pc(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(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;
@@ -179,10 +194,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(ctx, dest);
         tcg_gen_exit_tb(ctx->base.tb, n);
     } else {
-        tcg_gen_movi_tl(cpu_pc, dest);
+        gen_set_pc(ctx, dest);
         tcg_gen_lookup_and_goto_ptr();
     }
 }
-- 
2.25.1



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

* [PATCH 02/13] target/riscv: Extend pc for runtime pc write
  2021-11-01 10:01 ` LIU Zhiwei
@ 2021-11-01 10:01   ` LIU Zhiwei
  -1 siblings, 0 replies; 88+ messages in thread
From: LIU Zhiwei @ 2021-11-01 10:01 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: palmer, richard.henderson, bin.meng, 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 hit zero. So extend pc register
according to current xlen for these cases.

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
---
 target/riscv/cpu.c        | 20 +++++++++++++++++---
 target/riscv/cpu.h        |  2 ++
 target/riscv/cpu_helper.c |  2 +-
 3 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 7d53125dbc..7eefd4f6a6 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -319,7 +319,12 @@ static void riscv_cpu_set_pc(CPUState *cs, vaddr value)
 {
     RISCVCPU *cpu = RISCV_CPU(cs);
     CPURISCVState *env = &cpu->env;
-    env->pc = value;
+
+    if (cpu_get_xl(env) == MXL_RV32) {
+        env->pc = (int32_t)value;
+    } else {
+        env->pc = value;
+    }
 }
 
 static void riscv_cpu_synchronize_from_tb(CPUState *cs,
@@ -327,7 +332,12 @@ static void riscv_cpu_synchronize_from_tb(CPUState *cs,
 {
     RISCVCPU *cpu = RISCV_CPU(cs);
     CPURISCVState *env = &cpu->env;
-    env->pc = tb->pc;
+
+    if (cpu_get_xl(env) == MXL_RV32) {
+        env->pc = (int32_t)tb->pc;
+    } else {
+        env->pc = tb->pc;
+    }
 }
 
 static bool riscv_cpu_has_work(CPUState *cs)
@@ -348,7 +358,11 @@ static bool riscv_cpu_has_work(CPUState *cs)
 void restore_state_to_opc(CPURISCVState *env, TranslationBlock *tb,
                           target_ulong *data)
 {
-    env->pc = data[0];
+   if (cpu_get_xl(env) == MXL_RV32) {
+        env->pc = (int32_t)data[0];
+    } else {
+        env->pc = data[0];
+    }
 }
 
 static void riscv_cpu_reset(DeviceState *dev)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 0760c0af93..8befff0166 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -420,6 +420,8 @@ static inline RISCVMXL riscv_cpu_mxl(CPURISCVState *env)
 }
 #endif
 
+RISCVMXL cpu_get_xl(CPURISCVState *env);
+
 /*
  * A simplification for VLMAX
  * = (1 << LMUL) * VLEN / (8 * (1 << SEW))
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index f30ff672f8..7d0aee6769 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -35,7 +35,7 @@ int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
 #endif
 }
 
-static RISCVMXL cpu_get_xl(CPURISCVState *env)
+RISCVMXL cpu_get_xl(CPURISCVState *env)
 {
 #if defined(TARGET_RISCV32)
     return MXL_RV32;
-- 
2.25.1



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

* [PATCH 02/13] target/riscv: Extend pc for runtime pc write
@ 2021-11-01 10:01   ` LIU Zhiwei
  0 siblings, 0 replies; 88+ messages in thread
From: LIU Zhiwei @ 2021-11-01 10:01 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: Alistair.Francis, palmer, bin.meng, richard.henderson, 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 hit zero. So extend pc register
according to current xlen for these cases.

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
---
 target/riscv/cpu.c        | 20 +++++++++++++++++---
 target/riscv/cpu.h        |  2 ++
 target/riscv/cpu_helper.c |  2 +-
 3 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 7d53125dbc..7eefd4f6a6 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -319,7 +319,12 @@ static void riscv_cpu_set_pc(CPUState *cs, vaddr value)
 {
     RISCVCPU *cpu = RISCV_CPU(cs);
     CPURISCVState *env = &cpu->env;
-    env->pc = value;
+
+    if (cpu_get_xl(env) == MXL_RV32) {
+        env->pc = (int32_t)value;
+    } else {
+        env->pc = value;
+    }
 }
 
 static void riscv_cpu_synchronize_from_tb(CPUState *cs,
@@ -327,7 +332,12 @@ static void riscv_cpu_synchronize_from_tb(CPUState *cs,
 {
     RISCVCPU *cpu = RISCV_CPU(cs);
     CPURISCVState *env = &cpu->env;
-    env->pc = tb->pc;
+
+    if (cpu_get_xl(env) == MXL_RV32) {
+        env->pc = (int32_t)tb->pc;
+    } else {
+        env->pc = tb->pc;
+    }
 }
 
 static bool riscv_cpu_has_work(CPUState *cs)
@@ -348,7 +358,11 @@ static bool riscv_cpu_has_work(CPUState *cs)
 void restore_state_to_opc(CPURISCVState *env, TranslationBlock *tb,
                           target_ulong *data)
 {
-    env->pc = data[0];
+   if (cpu_get_xl(env) == MXL_RV32) {
+        env->pc = (int32_t)data[0];
+    } else {
+        env->pc = data[0];
+    }
 }
 
 static void riscv_cpu_reset(DeviceState *dev)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 0760c0af93..8befff0166 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -420,6 +420,8 @@ static inline RISCVMXL riscv_cpu_mxl(CPURISCVState *env)
 }
 #endif
 
+RISCVMXL cpu_get_xl(CPURISCVState *env);
+
 /*
  * A simplification for VLMAX
  * = (1 << LMUL) * VLEN / (8 * (1 << SEW))
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index f30ff672f8..7d0aee6769 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -35,7 +35,7 @@ int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
 #endif
 }
 
-static RISCVMXL cpu_get_xl(CPURISCVState *env)
+RISCVMXL cpu_get_xl(CPURISCVState *env)
 {
 #if defined(TARGET_RISCV32)
     return MXL_RV32;
-- 
2.25.1



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

* [PATCH 03/13] target/riscv: Ignore the pc bits above XLEN
  2021-11-01 10:01 ` LIU Zhiwei
@ 2021-11-01 10:01   ` LIU Zhiwei
  -1 siblings, 0 replies; 88+ messages in thread
From: LIU Zhiwei @ 2021-11-01 10:01 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: palmer, richard.henderson, bin.meng, 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>
---
 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 7d0aee6769..eb425d74d2 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -71,7 +71,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
 {
     uint32_t flags = 0;
 
-    *pc = env->pc;
+    *pc = cpu_get_xl(env) == 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] 88+ messages in thread

* [PATCH 03/13] target/riscv: Ignore the pc bits above XLEN
@ 2021-11-01 10:01   ` LIU Zhiwei
  0 siblings, 0 replies; 88+ messages in thread
From: LIU Zhiwei @ 2021-11-01 10:01 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: Alistair.Francis, palmer, bin.meng, richard.henderson, 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>
---
 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 7d0aee6769..eb425d74d2 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -71,7 +71,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
 {
     uint32_t flags = 0;
 
-    *pc = env->pc;
+    *pc = cpu_get_xl(env) == 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] 88+ messages in thread

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

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
---
 target/riscv/gdbstub.c | 73 +++++++++++++++++++++++++++++++-----------
 1 file changed, 54 insertions(+), 19 deletions(-)

diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
index 23429179e2..15abbbdb54 100644
--- a/target/riscv/gdbstub.c
+++ b/target/riscv/gdbstub.c
@@ -24,11 +24,25 @@ 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:
+        gdb_get_reg32(mem_buf, tmp);
+        break;
+    case MXL_RV64:
+        gdb_get_reg64(mem_buf, tmp);
+        break;
+    default:
+        g_assert_not_reached();
     }
     return 0;
 }
@@ -37,18 +51,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 = (uint32_t)ldl_p(mem_buf);
+        length = 4;
+        break;
+    case MXL_RV64:
+        if (cpu_get_xl(env) < 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)
@@ -198,13 +226,20 @@ void riscv_cpu_register_gdb_regs_for_features(CPUState *cs)
         gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
                                  36, "riscv-32bit-fpu.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] 88+ messages in thread

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

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
---
 target/riscv/gdbstub.c | 73 +++++++++++++++++++++++++++++++-----------
 1 file changed, 54 insertions(+), 19 deletions(-)

diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
index 23429179e2..15abbbdb54 100644
--- a/target/riscv/gdbstub.c
+++ b/target/riscv/gdbstub.c
@@ -24,11 +24,25 @@ 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:
+        gdb_get_reg32(mem_buf, tmp);
+        break;
+    case MXL_RV64:
+        gdb_get_reg64(mem_buf, tmp);
+        break;
+    default:
+        g_assert_not_reached();
     }
     return 0;
 }
@@ -37,18 +51,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 = (uint32_t)ldl_p(mem_buf);
+        length = 4;
+        break;
+    case MXL_RV64:
+        if (cpu_get_xl(env) < 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)
@@ -198,13 +226,20 @@ void riscv_cpu_register_gdb_regs_for_features(CPUState *cs)
         gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
                                  36, "riscv-32bit-fpu.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] 88+ messages in thread

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

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
---
 target/riscv/insn_trans/trans_rvd.c.inc | 20 ++++++--------------
 target/riscv/insn_trans/trans_rvf.c.inc | 21 ++++++++-------------
 target/riscv/insn_trans/trans_rvi.c.inc | 21 ++++++++++-----------
 3 files changed, 24 insertions(+), 38 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvd.c.inc b/target/riscv/insn_trans/trans_rvd.c.inc
index 64fb0046f7..70317691c9 100644
--- a/target/riscv/insn_trans/trans_rvd.c.inc
+++ b/target/riscv/insn_trans/trans_rvd.c.inc
@@ -20,17 +20,13 @@
 
 static bool trans_fld(DisasContext *ctx, arg_fld *a)
 {
-    TCGv addr;
+    TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
+    TCGv addr = temp_new(ctx);
 
     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;
-    }
+    tcg_gen_addi_tl(addr, src1, a->imm);
     addr = gen_pm_adjust_address(ctx, addr);
 
     tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], addr, ctx->mem_idx, MO_TEQ);
@@ -41,17 +37,13 @@ static bool trans_fld(DisasContext *ctx, arg_fld *a)
 
 static bool trans_fsd(DisasContext *ctx, arg_fsd *a)
 {
-    TCGv addr;
+    TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
+    TCGv addr = temp_new(ctx);
 
     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;
-    }
+    tcg_gen_addi_tl(addr, src1, a->imm);
     addr = gen_pm_adjust_address(ctx, addr);
 
     tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], addr, ctx->mem_idx, MO_TEQ);
diff --git a/target/riscv/insn_trans/trans_rvf.c.inc b/target/riscv/insn_trans/trans_rvf.c.inc
index b5459249c4..08fa83df7e 100644
--- a/target/riscv/insn_trans/trans_rvf.c.inc
+++ b/target/riscv/insn_trans/trans_rvf.c.inc
@@ -26,16 +26,15 @@
 static bool trans_flw(DisasContext *ctx, arg_flw *a)
 {
     TCGv_i64 dest;
-    TCGv addr;
+    TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
+    TCGv addr = temp_new(ctx);
 
     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;
+    tcg_gen_addi_tl(addr, src1, a->imm);
+    if (ctx->ol == MXL_RV32) {
+        tcg_gen_ext32u_tl(addr, addr);
     }
     addr = gen_pm_adjust_address(ctx, addr);
 
@@ -49,17 +48,13 @@ static bool trans_flw(DisasContext *ctx, arg_flw *a)
 
 static bool trans_fsw(DisasContext *ctx, arg_fsw *a)
 {
-    TCGv addr;
+    TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
+    TCGv addr = temp_new(ctx);
 
     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;
-    }
+    tcg_gen_addi_tl(addr, src1, a->imm);
     addr = gen_pm_adjust_address(ctx, addr);
 
     tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], addr, ctx->mem_idx, MO_TEUL);
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
index e51dbc41c5..bd9d50bb94 100644
--- a/target/riscv/insn_trans/trans_rvi.c.inc
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
@@ -137,12 +137,12 @@ static bool trans_bgeu(DisasContext *ctx, arg_bgeu *a)
 static bool gen_load(DisasContext *ctx, arg_lb *a, MemOp memop)
 {
     TCGv dest = dest_gpr(ctx, a->rd);
-    TCGv addr = get_gpr(ctx, a->rs1, EXT_NONE);
+    TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
+    TCGv addr = temp_new(ctx);
 
-    if (a->imm) {
-        TCGv temp = temp_new(ctx);
-        tcg_gen_addi_tl(temp, addr, a->imm);
-        addr = temp;
+    tcg_gen_addi_tl(addr, src1, a->imm);
+    if (ctx->ol == MXL_RV32) {
+        tcg_gen_ext32u_tl(addr, addr);
     }
     addr = gen_pm_adjust_address(ctx, addr);
 
@@ -178,16 +178,15 @@ static bool trans_lhu(DisasContext *ctx, arg_lhu *a)
 
 static bool gen_store(DisasContext *ctx, arg_sb *a, MemOp memop)
 {
-    TCGv addr = get_gpr(ctx, a->rs1, EXT_NONE);
+    TCGv addr = temp_new(ctx);
+    TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
     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;
+    tcg_gen_addi_tl(addr, src1, a->imm);
+    if (ctx->ol == MXL_RV32) {
+        tcg_gen_ext32u_tl(addr, addr);
     }
     addr = gen_pm_adjust_address(ctx, addr);
-
     tcg_gen_qemu_st_tl(data, addr, ctx->mem_idx, memop);
     return true;
 }
-- 
2.25.1



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

* [PATCH 05/13] target/riscv: Calculate address according to ol
@ 2021-11-01 10:01   ` LIU Zhiwei
  0 siblings, 0 replies; 88+ messages in thread
From: LIU Zhiwei @ 2021-11-01 10:01 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: Alistair.Francis, palmer, bin.meng, richard.henderson, LIU Zhiwei

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
---
 target/riscv/insn_trans/trans_rvd.c.inc | 20 ++++++--------------
 target/riscv/insn_trans/trans_rvf.c.inc | 21 ++++++++-------------
 target/riscv/insn_trans/trans_rvi.c.inc | 21 ++++++++++-----------
 3 files changed, 24 insertions(+), 38 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvd.c.inc b/target/riscv/insn_trans/trans_rvd.c.inc
index 64fb0046f7..70317691c9 100644
--- a/target/riscv/insn_trans/trans_rvd.c.inc
+++ b/target/riscv/insn_trans/trans_rvd.c.inc
@@ -20,17 +20,13 @@
 
 static bool trans_fld(DisasContext *ctx, arg_fld *a)
 {
-    TCGv addr;
+    TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
+    TCGv addr = temp_new(ctx);
 
     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;
-    }
+    tcg_gen_addi_tl(addr, src1, a->imm);
     addr = gen_pm_adjust_address(ctx, addr);
 
     tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], addr, ctx->mem_idx, MO_TEQ);
@@ -41,17 +37,13 @@ static bool trans_fld(DisasContext *ctx, arg_fld *a)
 
 static bool trans_fsd(DisasContext *ctx, arg_fsd *a)
 {
-    TCGv addr;
+    TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
+    TCGv addr = temp_new(ctx);
 
     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;
-    }
+    tcg_gen_addi_tl(addr, src1, a->imm);
     addr = gen_pm_adjust_address(ctx, addr);
 
     tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], addr, ctx->mem_idx, MO_TEQ);
diff --git a/target/riscv/insn_trans/trans_rvf.c.inc b/target/riscv/insn_trans/trans_rvf.c.inc
index b5459249c4..08fa83df7e 100644
--- a/target/riscv/insn_trans/trans_rvf.c.inc
+++ b/target/riscv/insn_trans/trans_rvf.c.inc
@@ -26,16 +26,15 @@
 static bool trans_flw(DisasContext *ctx, arg_flw *a)
 {
     TCGv_i64 dest;
-    TCGv addr;
+    TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
+    TCGv addr = temp_new(ctx);
 
     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;
+    tcg_gen_addi_tl(addr, src1, a->imm);
+    if (ctx->ol == MXL_RV32) {
+        tcg_gen_ext32u_tl(addr, addr);
     }
     addr = gen_pm_adjust_address(ctx, addr);
 
@@ -49,17 +48,13 @@ static bool trans_flw(DisasContext *ctx, arg_flw *a)
 
 static bool trans_fsw(DisasContext *ctx, arg_fsw *a)
 {
-    TCGv addr;
+    TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
+    TCGv addr = temp_new(ctx);
 
     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;
-    }
+    tcg_gen_addi_tl(addr, src1, a->imm);
     addr = gen_pm_adjust_address(ctx, addr);
 
     tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], addr, ctx->mem_idx, MO_TEUL);
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
index e51dbc41c5..bd9d50bb94 100644
--- a/target/riscv/insn_trans/trans_rvi.c.inc
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
@@ -137,12 +137,12 @@ static bool trans_bgeu(DisasContext *ctx, arg_bgeu *a)
 static bool gen_load(DisasContext *ctx, arg_lb *a, MemOp memop)
 {
     TCGv dest = dest_gpr(ctx, a->rd);
-    TCGv addr = get_gpr(ctx, a->rs1, EXT_NONE);
+    TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
+    TCGv addr = temp_new(ctx);
 
-    if (a->imm) {
-        TCGv temp = temp_new(ctx);
-        tcg_gen_addi_tl(temp, addr, a->imm);
-        addr = temp;
+    tcg_gen_addi_tl(addr, src1, a->imm);
+    if (ctx->ol == MXL_RV32) {
+        tcg_gen_ext32u_tl(addr, addr);
     }
     addr = gen_pm_adjust_address(ctx, addr);
 
@@ -178,16 +178,15 @@ static bool trans_lhu(DisasContext *ctx, arg_lhu *a)
 
 static bool gen_store(DisasContext *ctx, arg_sb *a, MemOp memop)
 {
-    TCGv addr = get_gpr(ctx, a->rs1, EXT_NONE);
+    TCGv addr = temp_new(ctx);
+    TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
     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;
+    tcg_gen_addi_tl(addr, src1, a->imm);
+    if (ctx->ol == MXL_RV32) {
+        tcg_gen_ext32u_tl(addr, addr);
     }
     addr = gen_pm_adjust_address(ctx, addr);
-
     tcg_gen_qemu_st_tl(data, addr, ctx->mem_idx, memop);
     return true;
 }
-- 
2.25.1



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

* [PATCH 06/13] target/riscv: Adjust vsetvl according to ol
  2021-11-01 10:01 ` LIU Zhiwei
@ 2021-11-01 10:01   ` LIU Zhiwei
  -1 siblings, 0 replies; 88+ messages in thread
From: LIU Zhiwei @ 2021-11-01 10:01 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: palmer, richard.henderson, bin.meng, Alistair.Francis, LIU Zhiwei

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
---
 target/riscv/cpu.h                      |  2 ++
 target/riscv/helper.h                   |  2 +-
 target/riscv/insn_trans/trans_rvv.c.inc |  4 ++--
 target/riscv/vector_helper.c            | 19 +++++++++++++++----
 4 files changed, 20 insertions(+), 7 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 8befff0166..7163ac1f4c 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -107,6 +107,8 @@ FIELD(VTYPE, VSEW, 2, 3)
 FIELD(VTYPE, VEDIV, 5, 2)
 FIELD(VTYPE, RESERVED, 7, sizeof(target_ulong) * 8 - 9)
 FIELD(VTYPE, VILL, sizeof(target_ulong) * 8 - 1, 1)
+FIELD(VTYPE, RESERVED_OLEN32, 7, 23)
+FIELD(VTYPE, VILL_OLEN32, 31, 1)
 
 struct CPURISCVState {
     target_ulong gpr[32];
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index c7a5376227..e198d43981 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -82,7 +82,7 @@ DEF_HELPER_2(hyp_hlvx_wu, tl, env, tl)
 #endif
 
 /* Vector functions */
-DEF_HELPER_3(vsetvl, tl, env, tl, tl)
+DEF_HELPER_4(vsetvl, tl, env, tl, tl, tl)
 DEF_HELPER_5(vlb_v_b, void, ptr, ptr, tl, env, i32)
 DEF_HELPER_5(vlb_v_b_mask, void, ptr, ptr, tl, env, i32)
 DEF_HELPER_5(vlb_v_h, void, ptr, ptr, tl, env, i32)
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
index 17ee3babef..01da065710 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -37,7 +37,7 @@ static bool trans_vsetvl(DisasContext *ctx, arg_vsetvl *a)
     } else {
         s1 = get_gpr(ctx, a->rs1, EXT_ZERO);
     }
-    gen_helper_vsetvl(dst, cpu_env, s1, s2);
+    gen_helper_vsetvl(dst, cpu_env, s1, s2, tcg_constant_tl(get_olen(ctx)));
     gen_set_gpr(ctx, a->rd, dst);
 
     tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
@@ -64,7 +64,7 @@ static bool trans_vsetvli(DisasContext *ctx, arg_vsetvli *a)
     } else {
         s1 = get_gpr(ctx, a->rs1, EXT_ZERO);
     }
-    gen_helper_vsetvl(dst, cpu_env, s1, s2);
+    gen_helper_vsetvl(dst, cpu_env, s1, s2, tcg_constant_tl(get_olen(ctx)));
     gen_set_gpr(ctx, a->rd, dst);
 
     gen_goto_tb(ctx, 0, ctx->pc_succ_insn);
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 12c31aa4b4..09e76229bc 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -27,18 +27,29 @@
 #include <math.h>
 
 target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
-                            target_ulong s2)
+                            target_ulong s2, target_ulong olen)
 {
     int vlmax, vl;
     RISCVCPU *cpu = env_archcpu(env);
     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);
+    bool vill;
+    target_ulong reserved;
 
+    if (olen < TARGET_LONG_BITS) {
+        vill = FIELD_EX64(s2, VTYPE, VILL_OLEN32);
+        reserved = FIELD_EX64(s2, VTYPE, RESERVED_OLEN32);
+    } else {
+        vill = FIELD_EX64(s2, VTYPE, VILL);
+        reserved = FIELD_EX64(s2, VTYPE, RESERVED);
+    }
     if ((sew > cpu->cfg.elen) || vill || (ediv != 0) || (reserved != 0)) {
         /* only set vill bit. */
-        env->vtype = FIELD_DP64(0, VTYPE, VILL, 1);
+        if (olen < TARGET_LONG_BITS) {
+            env->vtype = FIELD_DP64(0, VTYPE, VILL_OLEN32, 1);
+        } else {
+            env->vtype = FIELD_DP64(0, VTYPE, VILL, 1);
+        }
         env->vl = 0;
         env->vstart = 0;
         return 0;
-- 
2.25.1



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

* [PATCH 06/13] target/riscv: Adjust vsetvl according to ol
@ 2021-11-01 10:01   ` LIU Zhiwei
  0 siblings, 0 replies; 88+ messages in thread
From: LIU Zhiwei @ 2021-11-01 10:01 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: Alistair.Francis, palmer, bin.meng, richard.henderson, LIU Zhiwei

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
---
 target/riscv/cpu.h                      |  2 ++
 target/riscv/helper.h                   |  2 +-
 target/riscv/insn_trans/trans_rvv.c.inc |  4 ++--
 target/riscv/vector_helper.c            | 19 +++++++++++++++----
 4 files changed, 20 insertions(+), 7 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 8befff0166..7163ac1f4c 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -107,6 +107,8 @@ FIELD(VTYPE, VSEW, 2, 3)
 FIELD(VTYPE, VEDIV, 5, 2)
 FIELD(VTYPE, RESERVED, 7, sizeof(target_ulong) * 8 - 9)
 FIELD(VTYPE, VILL, sizeof(target_ulong) * 8 - 1, 1)
+FIELD(VTYPE, RESERVED_OLEN32, 7, 23)
+FIELD(VTYPE, VILL_OLEN32, 31, 1)
 
 struct CPURISCVState {
     target_ulong gpr[32];
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index c7a5376227..e198d43981 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -82,7 +82,7 @@ DEF_HELPER_2(hyp_hlvx_wu, tl, env, tl)
 #endif
 
 /* Vector functions */
-DEF_HELPER_3(vsetvl, tl, env, tl, tl)
+DEF_HELPER_4(vsetvl, tl, env, tl, tl, tl)
 DEF_HELPER_5(vlb_v_b, void, ptr, ptr, tl, env, i32)
 DEF_HELPER_5(vlb_v_b_mask, void, ptr, ptr, tl, env, i32)
 DEF_HELPER_5(vlb_v_h, void, ptr, ptr, tl, env, i32)
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
index 17ee3babef..01da065710 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -37,7 +37,7 @@ static bool trans_vsetvl(DisasContext *ctx, arg_vsetvl *a)
     } else {
         s1 = get_gpr(ctx, a->rs1, EXT_ZERO);
     }
-    gen_helper_vsetvl(dst, cpu_env, s1, s2);
+    gen_helper_vsetvl(dst, cpu_env, s1, s2, tcg_constant_tl(get_olen(ctx)));
     gen_set_gpr(ctx, a->rd, dst);
 
     tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
@@ -64,7 +64,7 @@ static bool trans_vsetvli(DisasContext *ctx, arg_vsetvli *a)
     } else {
         s1 = get_gpr(ctx, a->rs1, EXT_ZERO);
     }
-    gen_helper_vsetvl(dst, cpu_env, s1, s2);
+    gen_helper_vsetvl(dst, cpu_env, s1, s2, tcg_constant_tl(get_olen(ctx)));
     gen_set_gpr(ctx, a->rd, dst);
 
     gen_goto_tb(ctx, 0, ctx->pc_succ_insn);
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 12c31aa4b4..09e76229bc 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -27,18 +27,29 @@
 #include <math.h>
 
 target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
-                            target_ulong s2)
+                            target_ulong s2, target_ulong olen)
 {
     int vlmax, vl;
     RISCVCPU *cpu = env_archcpu(env);
     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);
+    bool vill;
+    target_ulong reserved;
 
+    if (olen < TARGET_LONG_BITS) {
+        vill = FIELD_EX64(s2, VTYPE, VILL_OLEN32);
+        reserved = FIELD_EX64(s2, VTYPE, RESERVED_OLEN32);
+    } else {
+        vill = FIELD_EX64(s2, VTYPE, VILL);
+        reserved = FIELD_EX64(s2, VTYPE, RESERVED);
+    }
     if ((sew > cpu->cfg.elen) || vill || (ediv != 0) || (reserved != 0)) {
         /* only set vill bit. */
-        env->vtype = FIELD_DP64(0, VTYPE, VILL, 1);
+        if (olen < TARGET_LONG_BITS) {
+            env->vtype = FIELD_DP64(0, VTYPE, VILL_OLEN32, 1);
+        } else {
+            env->vtype = FIELD_DP64(0, VTYPE, VILL, 1);
+        }
         env->vl = 0;
         env->vstart = 0;
         return 0;
-- 
2.25.1



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

* [PATCH 07/13] target/riscv: Ajdust vector atomic check with ol
  2021-11-01 10:01 ` LIU Zhiwei
@ 2021-11-01 10:01   ` LIU Zhiwei
  -1 siblings, 0 replies; 88+ messages in thread
From: LIU Zhiwei @ 2021-11-01 10:01 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: palmer, richard.henderson, bin.meng, Alistair.Francis, LIU Zhiwei

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 01da065710..ed042f7bb9 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -739,7 +739,7 @@ static bool amo_check(DisasContext *s, arg_rwdvm* a)
             (!a->wd || vext_check_overlap_mask(s, a->rd, a->vm, false)) &&
             vext_check_reg(s, a->rd, false) &&
             vext_check_reg(s, a->rs2, false) &&
-            ((1 << s->sew) <= sizeof(target_ulong)) &&
+            ((1 << s->sew) <= (get_olen(s) / 8)) &&
             ((1 << s->sew) >= 4));
 }
 
-- 
2.25.1



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

* [PATCH 07/13] target/riscv: Ajdust vector atomic check with ol
@ 2021-11-01 10:01   ` LIU Zhiwei
  0 siblings, 0 replies; 88+ messages in thread
From: LIU Zhiwei @ 2021-11-01 10:01 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: Alistair.Francis, palmer, bin.meng, richard.henderson, LIU Zhiwei

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 01da065710..ed042f7bb9 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -739,7 +739,7 @@ static bool amo_check(DisasContext *s, arg_rwdvm* a)
             (!a->wd || vext_check_overlap_mask(s, a->rd, a->vm, false)) &&
             vext_check_reg(s, a->rd, false) &&
             vext_check_reg(s, a->rs2, false) &&
-            ((1 << s->sew) <= sizeof(target_ulong)) &&
+            ((1 << s->sew) <= (get_olen(s) / 8)) &&
             ((1 << s->sew) >= 4));
 }
 
-- 
2.25.1



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

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

Only check the range that has passed the address translation.

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.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 09e76229bc..535420ee66 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -638,12 +638,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 * msz, PAGE_READ) < 0) {
+                    if (page_check_range(addr, offset, PAGE_READ) < 0) {
                         vl = i;
                         goto ProbeSuccess;
                     }
 #else
-                    probe_pages(env, addr, nf * msz, 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] 88+ messages in thread

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

Only check the range that has passed the address translation.

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.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 09e76229bc..535420ee66 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -638,12 +638,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 * msz, PAGE_READ) < 0) {
+                    if (page_check_range(addr, offset, PAGE_READ) < 0) {
                         vl = i;
                         goto ProbeSuccess;
                     }
 #else
-                    probe_pages(env, addr, nf * msz, 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] 88+ messages in thread

* [PATCH 09/13] target/riscv: Adjust vector address with ol
  2021-11-01 10:01 ` LIU Zhiwei
@ 2021-11-01 10:01   ` LIU Zhiwei
  -1 siblings, 0 replies; 88+ messages in thread
From: LIU Zhiwei @ 2021-11-01 10:01 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: palmer, richard.henderson, bin.meng, Alistair.Francis, LIU Zhiwei

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
---
 target/riscv/insn_trans/trans_rvv.c.inc |  8 ++++
 target/riscv/internals.h                |  1 +
 target/riscv/vector_helper.c            | 54 +++++++++++++++++--------
 3 files changed, 46 insertions(+), 17 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
index ed042f7bb9..5cd9b802df 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -233,6 +233,7 @@ static bool ld_us_op(DisasContext *s, arg_r2nfvm *a, uint8_t seq)
     data = FIELD_DP32(data, VDATA, VM, a->vm);
     data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
     data = FIELD_DP32(data, VDATA, NF, a->nf);
+    data = FIELD_DP32(data, VDATA, OL, s->ol);
     return ldst_us_trans(a->rd, a->rs1, data, fn, s);
 }
 
@@ -286,6 +287,7 @@ static bool st_us_op(DisasContext *s, arg_r2nfvm *a, uint8_t seq)
     data = FIELD_DP32(data, VDATA, VM, a->vm);
     data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
     data = FIELD_DP32(data, VDATA, NF, a->nf);
+    data = FIELD_DP32(data, VDATA, OL, s->ol);
     return ldst_us_trans(a->rd, a->rs1, data, fn, s);
 }
 
@@ -365,6 +367,7 @@ static bool ld_stride_op(DisasContext *s, arg_rnfvm *a, uint8_t seq)
     data = FIELD_DP32(data, VDATA, VM, a->vm);
     data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
     data = FIELD_DP32(data, VDATA, NF, a->nf);
+    data = FIELD_DP32(data, VDATA, OL, s->ol);
     return ldst_stride_trans(a->rd, a->rs1, a->rs2, data, fn, s);
 }
 
@@ -404,6 +407,7 @@ static bool st_stride_op(DisasContext *s, arg_rnfvm *a, uint8_t seq)
     data = FIELD_DP32(data, VDATA, VM, a->vm);
     data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
     data = FIELD_DP32(data, VDATA, NF, a->nf);
+    data = FIELD_DP32(data, VDATA, OL, s->ol);
     fn =  fns[seq][s->sew];
     if (fn == NULL) {
         return false;
@@ -490,6 +494,7 @@ static bool ld_index_op(DisasContext *s, arg_rnfvm *a, uint8_t seq)
     data = FIELD_DP32(data, VDATA, VM, a->vm);
     data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
     data = FIELD_DP32(data, VDATA, NF, a->nf);
+    data = FIELD_DP32(data, VDATA, OL, s->ol);
     return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s);
 }
 
@@ -542,6 +547,7 @@ static bool st_index_op(DisasContext *s, arg_rnfvm *a, uint8_t seq)
     data = FIELD_DP32(data, VDATA, VM, a->vm);
     data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
     data = FIELD_DP32(data, VDATA, NF, a->nf);
+    data = FIELD_DP32(data, VDATA, OL, s->ol);
     return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s);
 }
 
@@ -617,6 +623,7 @@ static bool ldff_op(DisasContext *s, arg_r2nfvm *a, uint8_t seq)
     data = FIELD_DP32(data, VDATA, VM, a->vm);
     data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
     data = FIELD_DP32(data, VDATA, NF, a->nf);
+    data = FIELD_DP32(data, VDATA, OL, s->ol);
     return ldff_trans(a->rd, a->rs1, data, fn, s);
 }
 
@@ -724,6 +731,7 @@ static bool amo_op(DisasContext *s, arg_rwdvm *a, uint8_t seq)
     data = FIELD_DP32(data, VDATA, VM, a->vm);
     data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
     data = FIELD_DP32(data, VDATA, WD, a->wd);
+    data = FIELD_DP32(data, VDATA, OL, s->ol);
     return amo_trans(a->rd, a->rs1, a->rs2, data, fn, s);
 }
 /*
diff --git a/target/riscv/internals.h b/target/riscv/internals.h
index b15ad394bb..f74b8291e4 100644
--- a/target/riscv/internals.h
+++ b/target/riscv/internals.h
@@ -27,6 +27,7 @@ FIELD(VDATA, VM, 8, 1)
 FIELD(VDATA, LMUL, 9, 2)
 FIELD(VDATA, NF, 11, 4)
 FIELD(VDATA, WD, 11, 1)
+FIELD(VDATA, OL, 15, 2)
 
 /* float point classify helpers */
 target_ulong fclass_h(uint64_t frs1);
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 535420ee66..451688c328 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -112,6 +112,11 @@ static uint32_t vext_wd(uint32_t desc)
     return (simd_data(desc) >> 11) & 0x1;
 }
 
+static inline uint32_t vext_ol(uint32_t desc)
+{
+    return FIELD_EX32(simd_data(desc), VDATA, OL);
+}
+
 /*
  * Get vector group length in bytes. Its range is [64, 2048].
  *
@@ -123,6 +128,14 @@ static inline uint32_t vext_maxsz(uint32_t desc)
     return simd_maxsz(desc) << vext_lmul(desc);
 }
 
+static inline target_ulong adjust_addr(target_ulong addr, uint32_t olen)
+{
+    if (olen < TARGET_LONG_BITS) {
+        addr &= UINT32_MAX;
+    }
+    return addr;
+}
+
 /*
  * This function checks watchpoint before real load operation.
  *
@@ -135,17 +148,17 @@ static inline uint32_t vext_maxsz(uint32_t desc)
  */
 static void probe_pages(CPURISCVState *env, target_ulong addr,
                         target_ulong len, uintptr_t ra,
-                        MMUAccessType access_type)
+                        MMUAccessType access_type, uint32_t olen)
 {
     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(addr, olen), 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(addr, olen), curlen, access_type,
                      cpu_mmu_index(env, false), ra);
     }
 }
@@ -290,13 +303,14 @@ vext_ldst_stride(void *vd, void *v0, target_ulong base,
     uint32_t nf = vext_nf(desc);
     uint32_t mlen = vext_mlen(desc);
     uint32_t vlmax = vext_maxsz(desc) / esz;
+    uint32_t olen = 16 << vext_ol(desc);
 
     /* probe every access*/
     for (i = 0; i < env->vl; i++) {
         if (!vm && !vext_elem_mask(v0, mlen, i)) {
             continue;
         }
-        probe_pages(env, base + stride * i, nf * msz, ra, access_type);
+        probe_pages(env, base + stride * i, nf * msz, ra, access_type, olen);
     }
     /* do real access */
     for (i = 0; i < env->vl; i++) {
@@ -306,7 +320,7 @@ vext_ldst_stride(void *vd, void *v0, target_ulong base,
         }
         while (k < nf) {
             target_ulong addr = base + stride * i + k * msz;
-            ldst_elem(env, addr, i + k * vlmax, vd, ra);
+            ldst_elem(env, adjust_addr(addr, olen), i + k * vlmax, vd, ra);
             k++;
         }
     }
@@ -391,15 +405,16 @@ vext_ldst_us(void *vd, target_ulong base, CPURISCVState *env, uint32_t desc,
     uint32_t i, k;
     uint32_t nf = vext_nf(desc);
     uint32_t vlmax = vext_maxsz(desc) / esz;
+    uint32_t olen = 16 << vext_ol(desc);
 
     /* probe every access */
-    probe_pages(env, base, env->vl * nf * msz, ra, access_type);
+    probe_pages(env, base, env->vl * nf * msz, ra, access_type, olen);
     /* load bytes from guest memory */
     for (i = 0; i < env->vl; i++) {
         k = 0;
         while (k < nf) {
             target_ulong addr = base + (i * nf + k) * msz;
-            ldst_elem(env, addr, i + k * vlmax, vd, ra);
+            ldst_elem(env, adjust_addr(addr, olen), i + k * vlmax, vd, ra);
             k++;
         }
     }
@@ -519,6 +534,7 @@ vext_ldst_index(void *vd, void *v0, target_ulong base,
     uint32_t vm = vext_vm(desc);
     uint32_t mlen = vext_mlen(desc);
     uint32_t vlmax = vext_maxsz(desc) / esz;
+    uint32_t olen = 16 << vext_ol(desc);
 
     /* probe every access*/
     for (i = 0; i < env->vl; i++) {
@@ -526,7 +542,7 @@ vext_ldst_index(void *vd, void *v0, target_ulong base,
             continue;
         }
         probe_pages(env, get_index_addr(base, i, vs2), nf * msz, ra,
-                    access_type);
+                    access_type, olen);
     }
     /* load bytes from guest memory */
     for (i = 0; i < env->vl; i++) {
@@ -536,7 +552,7 @@ vext_ldst_index(void *vd, void *v0, target_ulong base,
         }
         while (k < nf) {
             abi_ptr addr = get_index_addr(base, i, vs2) + k * msz;
-            ldst_elem(env, addr, i + k * vlmax, vd, ra);
+            ldst_elem(env, adjust_addr(addr, olen), i + k * vlmax, vd, ra);
             k++;
         }
     }
@@ -619,6 +635,7 @@ vext_ldff(void *vd, void *v0, target_ulong base,
     uint32_t nf = vext_nf(desc);
     uint32_t vm = vext_vm(desc);
     uint32_t vlmax = vext_maxsz(desc) / esz;
+    uint32_t olen = 16 << vext_ol(desc);
     target_ulong addr, offset, remain;
 
     /* probe every access*/
@@ -626,9 +643,9 @@ vext_ldff(void *vd, void *v0, target_ulong base,
         if (!vm && !vext_elem_mask(v0, mlen, i)) {
             continue;
         }
-        addr = base + nf * i * msz;
+        addr = adjust_addr(base + nf * i * msz, olen);
         if (i == 0) {
-            probe_pages(env, addr, nf * msz, ra, MMU_DATA_LOAD);
+            probe_pages(env, addr, nf * msz, ra, MMU_DATA_LOAD, olen);
         } else {
             /* if it triggers an exception, no need to check watchpoint */
             remain = nf * msz;
@@ -643,7 +660,7 @@ vext_ldff(void *vd, void *v0, target_ulong base,
                         goto ProbeSuccess;
                     }
 #else
-                    probe_pages(env, addr, offset, ra, MMU_DATA_LOAD);
+                    probe_pages(env, addr, offset, ra, MMU_DATA_LOAD, olen);
 #endif
                 } else {
                     vl = i;
@@ -653,7 +670,7 @@ vext_ldff(void *vd, void *v0, target_ulong base,
                     break;
                 }
                 remain -= offset;
-                addr += offset;
+                addr = adjust_addr(addr + offset, olen);
             }
         }
     }
@@ -669,7 +686,7 @@ ProbeSuccess:
         }
         while (k < nf) {
             target_ulong addr = base + (i * nf + k) * msz;
-            ldst_elem(env, addr, i + k * vlmax, vd, ra);
+            ldst_elem(env, adjust_addr(addr, olen), i + k * vlmax, vd, ra);
             k++;
         }
     }
@@ -795,20 +812,23 @@ vext_amo_noatomic(void *vs3, void *v0, target_ulong base,
     uint32_t vm = vext_vm(desc);
     uint32_t mlen = vext_mlen(desc);
     uint32_t vlmax = vext_maxsz(desc) / esz;
+    uint32_t olen = 16 << vext_ol(desc);
 
     for (i = 0; i < env->vl; i++) {
         if (!vm && !vext_elem_mask(v0, mlen, i)) {
             continue;
         }
-        probe_pages(env, get_index_addr(base, i, vs2), msz, ra, MMU_DATA_LOAD);
-        probe_pages(env, get_index_addr(base, i, vs2), msz, ra, MMU_DATA_STORE);
+        probe_pages(env, get_index_addr(base, i, vs2), msz, ra,
+                    MMU_DATA_LOAD, olen);
+        probe_pages(env, get_index_addr(base, i, vs2), msz, ra,
+                    MMU_DATA_STORE, olen);
     }
     for (i = 0; i < env->vl; i++) {
         if (!vm && !vext_elem_mask(v0, mlen, i)) {
             continue;
         }
         addr = get_index_addr(base, i, vs2);
-        noatomic_op(vs3, addr, wd, i, env, ra);
+        noatomic_op(vs3, adjust_addr(addr, olen), wd, i, env, ra);
     }
     clear_elem(vs3, env->vl, env->vl * esz, vlmax * esz);
 }
-- 
2.25.1



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

* [PATCH 09/13] target/riscv: Adjust vector address with ol
@ 2021-11-01 10:01   ` LIU Zhiwei
  0 siblings, 0 replies; 88+ messages in thread
From: LIU Zhiwei @ 2021-11-01 10:01 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: Alistair.Francis, palmer, bin.meng, richard.henderson, LIU Zhiwei

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
---
 target/riscv/insn_trans/trans_rvv.c.inc |  8 ++++
 target/riscv/internals.h                |  1 +
 target/riscv/vector_helper.c            | 54 +++++++++++++++++--------
 3 files changed, 46 insertions(+), 17 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
index ed042f7bb9..5cd9b802df 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -233,6 +233,7 @@ static bool ld_us_op(DisasContext *s, arg_r2nfvm *a, uint8_t seq)
     data = FIELD_DP32(data, VDATA, VM, a->vm);
     data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
     data = FIELD_DP32(data, VDATA, NF, a->nf);
+    data = FIELD_DP32(data, VDATA, OL, s->ol);
     return ldst_us_trans(a->rd, a->rs1, data, fn, s);
 }
 
@@ -286,6 +287,7 @@ static bool st_us_op(DisasContext *s, arg_r2nfvm *a, uint8_t seq)
     data = FIELD_DP32(data, VDATA, VM, a->vm);
     data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
     data = FIELD_DP32(data, VDATA, NF, a->nf);
+    data = FIELD_DP32(data, VDATA, OL, s->ol);
     return ldst_us_trans(a->rd, a->rs1, data, fn, s);
 }
 
@@ -365,6 +367,7 @@ static bool ld_stride_op(DisasContext *s, arg_rnfvm *a, uint8_t seq)
     data = FIELD_DP32(data, VDATA, VM, a->vm);
     data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
     data = FIELD_DP32(data, VDATA, NF, a->nf);
+    data = FIELD_DP32(data, VDATA, OL, s->ol);
     return ldst_stride_trans(a->rd, a->rs1, a->rs2, data, fn, s);
 }
 
@@ -404,6 +407,7 @@ static bool st_stride_op(DisasContext *s, arg_rnfvm *a, uint8_t seq)
     data = FIELD_DP32(data, VDATA, VM, a->vm);
     data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
     data = FIELD_DP32(data, VDATA, NF, a->nf);
+    data = FIELD_DP32(data, VDATA, OL, s->ol);
     fn =  fns[seq][s->sew];
     if (fn == NULL) {
         return false;
@@ -490,6 +494,7 @@ static bool ld_index_op(DisasContext *s, arg_rnfvm *a, uint8_t seq)
     data = FIELD_DP32(data, VDATA, VM, a->vm);
     data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
     data = FIELD_DP32(data, VDATA, NF, a->nf);
+    data = FIELD_DP32(data, VDATA, OL, s->ol);
     return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s);
 }
 
@@ -542,6 +547,7 @@ static bool st_index_op(DisasContext *s, arg_rnfvm *a, uint8_t seq)
     data = FIELD_DP32(data, VDATA, VM, a->vm);
     data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
     data = FIELD_DP32(data, VDATA, NF, a->nf);
+    data = FIELD_DP32(data, VDATA, OL, s->ol);
     return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s);
 }
 
@@ -617,6 +623,7 @@ static bool ldff_op(DisasContext *s, arg_r2nfvm *a, uint8_t seq)
     data = FIELD_DP32(data, VDATA, VM, a->vm);
     data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
     data = FIELD_DP32(data, VDATA, NF, a->nf);
+    data = FIELD_DP32(data, VDATA, OL, s->ol);
     return ldff_trans(a->rd, a->rs1, data, fn, s);
 }
 
@@ -724,6 +731,7 @@ static bool amo_op(DisasContext *s, arg_rwdvm *a, uint8_t seq)
     data = FIELD_DP32(data, VDATA, VM, a->vm);
     data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
     data = FIELD_DP32(data, VDATA, WD, a->wd);
+    data = FIELD_DP32(data, VDATA, OL, s->ol);
     return amo_trans(a->rd, a->rs1, a->rs2, data, fn, s);
 }
 /*
diff --git a/target/riscv/internals.h b/target/riscv/internals.h
index b15ad394bb..f74b8291e4 100644
--- a/target/riscv/internals.h
+++ b/target/riscv/internals.h
@@ -27,6 +27,7 @@ FIELD(VDATA, VM, 8, 1)
 FIELD(VDATA, LMUL, 9, 2)
 FIELD(VDATA, NF, 11, 4)
 FIELD(VDATA, WD, 11, 1)
+FIELD(VDATA, OL, 15, 2)
 
 /* float point classify helpers */
 target_ulong fclass_h(uint64_t frs1);
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 535420ee66..451688c328 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -112,6 +112,11 @@ static uint32_t vext_wd(uint32_t desc)
     return (simd_data(desc) >> 11) & 0x1;
 }
 
+static inline uint32_t vext_ol(uint32_t desc)
+{
+    return FIELD_EX32(simd_data(desc), VDATA, OL);
+}
+
 /*
  * Get vector group length in bytes. Its range is [64, 2048].
  *
@@ -123,6 +128,14 @@ static inline uint32_t vext_maxsz(uint32_t desc)
     return simd_maxsz(desc) << vext_lmul(desc);
 }
 
+static inline target_ulong adjust_addr(target_ulong addr, uint32_t olen)
+{
+    if (olen < TARGET_LONG_BITS) {
+        addr &= UINT32_MAX;
+    }
+    return addr;
+}
+
 /*
  * This function checks watchpoint before real load operation.
  *
@@ -135,17 +148,17 @@ static inline uint32_t vext_maxsz(uint32_t desc)
  */
 static void probe_pages(CPURISCVState *env, target_ulong addr,
                         target_ulong len, uintptr_t ra,
-                        MMUAccessType access_type)
+                        MMUAccessType access_type, uint32_t olen)
 {
     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(addr, olen), 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(addr, olen), curlen, access_type,
                      cpu_mmu_index(env, false), ra);
     }
 }
@@ -290,13 +303,14 @@ vext_ldst_stride(void *vd, void *v0, target_ulong base,
     uint32_t nf = vext_nf(desc);
     uint32_t mlen = vext_mlen(desc);
     uint32_t vlmax = vext_maxsz(desc) / esz;
+    uint32_t olen = 16 << vext_ol(desc);
 
     /* probe every access*/
     for (i = 0; i < env->vl; i++) {
         if (!vm && !vext_elem_mask(v0, mlen, i)) {
             continue;
         }
-        probe_pages(env, base + stride * i, nf * msz, ra, access_type);
+        probe_pages(env, base + stride * i, nf * msz, ra, access_type, olen);
     }
     /* do real access */
     for (i = 0; i < env->vl; i++) {
@@ -306,7 +320,7 @@ vext_ldst_stride(void *vd, void *v0, target_ulong base,
         }
         while (k < nf) {
             target_ulong addr = base + stride * i + k * msz;
-            ldst_elem(env, addr, i + k * vlmax, vd, ra);
+            ldst_elem(env, adjust_addr(addr, olen), i + k * vlmax, vd, ra);
             k++;
         }
     }
@@ -391,15 +405,16 @@ vext_ldst_us(void *vd, target_ulong base, CPURISCVState *env, uint32_t desc,
     uint32_t i, k;
     uint32_t nf = vext_nf(desc);
     uint32_t vlmax = vext_maxsz(desc) / esz;
+    uint32_t olen = 16 << vext_ol(desc);
 
     /* probe every access */
-    probe_pages(env, base, env->vl * nf * msz, ra, access_type);
+    probe_pages(env, base, env->vl * nf * msz, ra, access_type, olen);
     /* load bytes from guest memory */
     for (i = 0; i < env->vl; i++) {
         k = 0;
         while (k < nf) {
             target_ulong addr = base + (i * nf + k) * msz;
-            ldst_elem(env, addr, i + k * vlmax, vd, ra);
+            ldst_elem(env, adjust_addr(addr, olen), i + k * vlmax, vd, ra);
             k++;
         }
     }
@@ -519,6 +534,7 @@ vext_ldst_index(void *vd, void *v0, target_ulong base,
     uint32_t vm = vext_vm(desc);
     uint32_t mlen = vext_mlen(desc);
     uint32_t vlmax = vext_maxsz(desc) / esz;
+    uint32_t olen = 16 << vext_ol(desc);
 
     /* probe every access*/
     for (i = 0; i < env->vl; i++) {
@@ -526,7 +542,7 @@ vext_ldst_index(void *vd, void *v0, target_ulong base,
             continue;
         }
         probe_pages(env, get_index_addr(base, i, vs2), nf * msz, ra,
-                    access_type);
+                    access_type, olen);
     }
     /* load bytes from guest memory */
     for (i = 0; i < env->vl; i++) {
@@ -536,7 +552,7 @@ vext_ldst_index(void *vd, void *v0, target_ulong base,
         }
         while (k < nf) {
             abi_ptr addr = get_index_addr(base, i, vs2) + k * msz;
-            ldst_elem(env, addr, i + k * vlmax, vd, ra);
+            ldst_elem(env, adjust_addr(addr, olen), i + k * vlmax, vd, ra);
             k++;
         }
     }
@@ -619,6 +635,7 @@ vext_ldff(void *vd, void *v0, target_ulong base,
     uint32_t nf = vext_nf(desc);
     uint32_t vm = vext_vm(desc);
     uint32_t vlmax = vext_maxsz(desc) / esz;
+    uint32_t olen = 16 << vext_ol(desc);
     target_ulong addr, offset, remain;
 
     /* probe every access*/
@@ -626,9 +643,9 @@ vext_ldff(void *vd, void *v0, target_ulong base,
         if (!vm && !vext_elem_mask(v0, mlen, i)) {
             continue;
         }
-        addr = base + nf * i * msz;
+        addr = adjust_addr(base + nf * i * msz, olen);
         if (i == 0) {
-            probe_pages(env, addr, nf * msz, ra, MMU_DATA_LOAD);
+            probe_pages(env, addr, nf * msz, ra, MMU_DATA_LOAD, olen);
         } else {
             /* if it triggers an exception, no need to check watchpoint */
             remain = nf * msz;
@@ -643,7 +660,7 @@ vext_ldff(void *vd, void *v0, target_ulong base,
                         goto ProbeSuccess;
                     }
 #else
-                    probe_pages(env, addr, offset, ra, MMU_DATA_LOAD);
+                    probe_pages(env, addr, offset, ra, MMU_DATA_LOAD, olen);
 #endif
                 } else {
                     vl = i;
@@ -653,7 +670,7 @@ vext_ldff(void *vd, void *v0, target_ulong base,
                     break;
                 }
                 remain -= offset;
-                addr += offset;
+                addr = adjust_addr(addr + offset, olen);
             }
         }
     }
@@ -669,7 +686,7 @@ ProbeSuccess:
         }
         while (k < nf) {
             target_ulong addr = base + (i * nf + k) * msz;
-            ldst_elem(env, addr, i + k * vlmax, vd, ra);
+            ldst_elem(env, adjust_addr(addr, olen), i + k * vlmax, vd, ra);
             k++;
         }
     }
@@ -795,20 +812,23 @@ vext_amo_noatomic(void *vs3, void *v0, target_ulong base,
     uint32_t vm = vext_vm(desc);
     uint32_t mlen = vext_mlen(desc);
     uint32_t vlmax = vext_maxsz(desc) / esz;
+    uint32_t olen = 16 << vext_ol(desc);
 
     for (i = 0; i < env->vl; i++) {
         if (!vm && !vext_elem_mask(v0, mlen, i)) {
             continue;
         }
-        probe_pages(env, get_index_addr(base, i, vs2), msz, ra, MMU_DATA_LOAD);
-        probe_pages(env, get_index_addr(base, i, vs2), msz, ra, MMU_DATA_STORE);
+        probe_pages(env, get_index_addr(base, i, vs2), msz, ra,
+                    MMU_DATA_LOAD, olen);
+        probe_pages(env, get_index_addr(base, i, vs2), msz, ra,
+                    MMU_DATA_STORE, olen);
     }
     for (i = 0; i < env->vl; i++) {
         if (!vm && !vext_elem_mask(v0, mlen, i)) {
             continue;
         }
         addr = get_index_addr(base, i, vs2);
-        noatomic_op(vs3, addr, wd, i, env, ra);
+        noatomic_op(vs3, adjust_addr(addr, olen), wd, i, env, ra);
     }
     clear_elem(vs3, env->vl, env->vl * esz, vlmax * esz);
 }
-- 
2.25.1



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

* [PATCH 10/13] target/riscv: Adjust scalar reg in vector with ol
  2021-11-01 10:01 ` LIU Zhiwei
@ 2021-11-01 10:01   ` LIU Zhiwei
  -1 siblings, 0 replies; 88+ messages in thread
From: LIU Zhiwei @ 2021-11-01 10:01 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: palmer, richard.henderson, bin.meng, 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 | 5 +++--
 target/riscv/vector_helper.c            | 6 ++++--
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
index 5cd9b802df..947a58d7ca 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -853,7 +853,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, MLEN, s->mlen);
     data = FIELD_DP32(data, VDATA, VM, vm);
@@ -2677,6 +2677,7 @@ static bool trans_vmv_s_x(DisasContext *s, arg_vmv_s_x *a)
         /* This instruction ignores LMUL and vector register groups */
         int maxsz = s->vlen >> 3;
         TCGv_i64 t1;
+        TCGv src1 = get_gpr(s, a->rs1, EXT_ZERO);
         TCGLabel *over = gen_new_label();
 
         tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
@@ -2686,7 +2687,7 @@ static bool trans_vmv_s_x(DisasContext *s, arg_vmv_s_x *a)
         }
 
         t1 = tcg_temp_new_i64();
-        tcg_gen_extu_tl_i64(t1, cpu_gpr[a->rs1]);
+        tcg_gen_extu_tl_i64(t1, src1);
         vec_element_storei(s, a->rd, 0, t1);
         tcg_temp_free_i64(t1);
     done:
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 451688c328..5bdbbf7c71 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -4763,6 +4763,7 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2,         \
     uint32_t mlen = vext_mlen(desc);                                      \
     uint32_t vlmax = env_archcpu(env)->cfg.vlen / mlen;                   \
     uint32_t vm = vext_vm(desc);                                          \
+    uint32_t olen = 16 << vext_ol(desc);                                  \
     uint32_t vl = env->vl;                                                \
     uint32_t i;                                                           \
                                                                           \
@@ -4771,7 +4772,7 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2,         \
             continue;                                                     \
         }                                                                 \
         if (i == 0) {                                                     \
-            *((ETYPE *)vd + H(i)) = s1;                                   \
+            *((ETYPE *)vd + H(i)) = adjust_addr(s1, olen);                \
         } else {                                                          \
             *((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(i - 1));           \
         }                                                                 \
@@ -4792,6 +4793,7 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2,         \
     uint32_t mlen = vext_mlen(desc);                                      \
     uint32_t vlmax = env_archcpu(env)->cfg.vlen / mlen;                   \
     uint32_t vm = vext_vm(desc);                                          \
+    uint32_t olen = 16 << vext_ol(desc);                                  \
     uint32_t vl = env->vl;                                                \
     uint32_t i;                                                           \
                                                                           \
@@ -4800,7 +4802,7 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2,         \
             continue;                                                     \
         }                                                                 \
         if (i == vl - 1) {                                                \
-            *((ETYPE *)vd + H(i)) = s1;                                   \
+            *((ETYPE *)vd + H(i)) = adjust_addr(s1, olen);                \
         } else {                                                          \
             *((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(i + 1));           \
         }                                                                 \
-- 
2.25.1



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

* [PATCH 10/13] target/riscv: Adjust scalar reg in vector with ol
@ 2021-11-01 10:01   ` LIU Zhiwei
  0 siblings, 0 replies; 88+ messages in thread
From: LIU Zhiwei @ 2021-11-01 10:01 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: Alistair.Francis, palmer, bin.meng, richard.henderson, 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 | 5 +++--
 target/riscv/vector_helper.c            | 6 ++++--
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
index 5cd9b802df..947a58d7ca 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -853,7 +853,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, MLEN, s->mlen);
     data = FIELD_DP32(data, VDATA, VM, vm);
@@ -2677,6 +2677,7 @@ static bool trans_vmv_s_x(DisasContext *s, arg_vmv_s_x *a)
         /* This instruction ignores LMUL and vector register groups */
         int maxsz = s->vlen >> 3;
         TCGv_i64 t1;
+        TCGv src1 = get_gpr(s, a->rs1, EXT_ZERO);
         TCGLabel *over = gen_new_label();
 
         tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
@@ -2686,7 +2687,7 @@ static bool trans_vmv_s_x(DisasContext *s, arg_vmv_s_x *a)
         }
 
         t1 = tcg_temp_new_i64();
-        tcg_gen_extu_tl_i64(t1, cpu_gpr[a->rs1]);
+        tcg_gen_extu_tl_i64(t1, src1);
         vec_element_storei(s, a->rd, 0, t1);
         tcg_temp_free_i64(t1);
     done:
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 451688c328..5bdbbf7c71 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -4763,6 +4763,7 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2,         \
     uint32_t mlen = vext_mlen(desc);                                      \
     uint32_t vlmax = env_archcpu(env)->cfg.vlen / mlen;                   \
     uint32_t vm = vext_vm(desc);                                          \
+    uint32_t olen = 16 << vext_ol(desc);                                  \
     uint32_t vl = env->vl;                                                \
     uint32_t i;                                                           \
                                                                           \
@@ -4771,7 +4772,7 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2,         \
             continue;                                                     \
         }                                                                 \
         if (i == 0) {                                                     \
-            *((ETYPE *)vd + H(i)) = s1;                                   \
+            *((ETYPE *)vd + H(i)) = adjust_addr(s1, olen);                \
         } else {                                                          \
             *((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(i - 1));           \
         }                                                                 \
@@ -4792,6 +4793,7 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2,         \
     uint32_t mlen = vext_mlen(desc);                                      \
     uint32_t vlmax = env_archcpu(env)->cfg.vlen / mlen;                   \
     uint32_t vm = vext_vm(desc);                                          \
+    uint32_t olen = 16 << vext_ol(desc);                                  \
     uint32_t vl = env->vl;                                                \
     uint32_t i;                                                           \
                                                                           \
@@ -4800,7 +4802,7 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2,         \
             continue;                                                     \
         }                                                                 \
         if (i == vl - 1) {                                                \
-            *((ETYPE *)vd + H(i)) = s1;                                   \
+            *((ETYPE *)vd + H(i)) = adjust_addr(s1, olen);                \
         } else {                                                          \
             *((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(i + 1));           \
         }                                                                 \
-- 
2.25.1



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

* [PATCH 11/13] target/riscv: Switch context in exception return
  2021-11-01 10:01 ` LIU Zhiwei
@ 2021-11-01 10:01   ` LIU Zhiwei
  -1 siblings, 0 replies; 88+ messages in thread
From: LIU Zhiwei @ 2021-11-01 10:01 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: palmer, richard.henderson, bin.meng, Alistair.Francis, LIU Zhiwei

After excpetion return, we should give a xlen view of context in new
priveledge, including the general registers, pc, and CSRs.

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
---
 target/riscv/helper.h                         |  1 +
 .../riscv/insn_trans/trans_privileged.c.inc   |  2 ++
 target/riscv/op_helper.c                      | 26 +++++++++++++++++++
 3 files changed, 29 insertions(+)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index e198d43981..9b379d7232 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -71,6 +71,7 @@ DEF_HELPER_2(sret, tl, env, tl)
 DEF_HELPER_2(mret, tl, env, tl)
 DEF_HELPER_1(wfi, void, env)
 DEF_HELPER_1(tlb_flush, void, env)
+DEF_HELPER_1(switch_context_xl, void, env)
 #endif
 
 /* Hypervisor functions */
diff --git a/target/riscv/insn_trans/trans_privileged.c.inc b/target/riscv/insn_trans/trans_privileged.c.inc
index 75c6ef80a6..6e39632f83 100644
--- a/target/riscv/insn_trans/trans_privileged.c.inc
+++ b/target/riscv/insn_trans/trans_privileged.c.inc
@@ -78,6 +78,7 @@ static bool trans_sret(DisasContext *ctx, arg_sret *a)
 
     if (has_ext(ctx, RVS)) {
         gen_helper_sret(cpu_pc, cpu_env, cpu_pc);
+        gen_helper_switch_context_xl(cpu_env);
         tcg_gen_exit_tb(NULL, 0); /* no chaining */
         ctx->base.is_jmp = DISAS_NORETURN;
     } else {
@@ -94,6 +95,7 @@ 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_switch_context_xl(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 ee7c24efe7..20cf8ad883 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -70,6 +70,32 @@ target_ulong helper_csrrw(CPURISCVState *env, int csr,
 }
 
 #ifndef CONFIG_USER_ONLY
+void helper_switch_context_xl(CPURISCVState *env)
+{
+    RISCVMXL xl = cpu_get_xl(env);
+    if (xl == env->misa_mxl_max) {
+        return;
+    }
+    assert(xl < env->misa_mxl_max);
+    switch (xl) {
+    case MXL_RV32:
+        for (int i = 1; i < 32; i++) {
+            env->gpr[i] = (int32_t)env->gpr[i];
+        }
+        env->pc = (int32_t)env->pc;
+        /*
+         * For the read-only bits of the previous-width CSR, the bits at the
+         * same positions in the temporary register are set to zeros.
+         */
+        if ((env->priv == PRV_U) && (env->misa_ext & RVV)) {
+            env->vl = 0;
+            env->vtype = 0;
+        }
+        break;
+    default:
+        break;
+    }
+}
 
 target_ulong helper_sret(CPURISCVState *env, target_ulong cpu_pc_deb)
 {
-- 
2.25.1



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

* [PATCH 11/13] target/riscv: Switch context in exception return
@ 2021-11-01 10:01   ` LIU Zhiwei
  0 siblings, 0 replies; 88+ messages in thread
From: LIU Zhiwei @ 2021-11-01 10:01 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: Alistair.Francis, palmer, bin.meng, richard.henderson, LIU Zhiwei

After excpetion return, we should give a xlen view of context in new
priveledge, including the general registers, pc, and CSRs.

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
---
 target/riscv/helper.h                         |  1 +
 .../riscv/insn_trans/trans_privileged.c.inc   |  2 ++
 target/riscv/op_helper.c                      | 26 +++++++++++++++++++
 3 files changed, 29 insertions(+)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index e198d43981..9b379d7232 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -71,6 +71,7 @@ DEF_HELPER_2(sret, tl, env, tl)
 DEF_HELPER_2(mret, tl, env, tl)
 DEF_HELPER_1(wfi, void, env)
 DEF_HELPER_1(tlb_flush, void, env)
+DEF_HELPER_1(switch_context_xl, void, env)
 #endif
 
 /* Hypervisor functions */
diff --git a/target/riscv/insn_trans/trans_privileged.c.inc b/target/riscv/insn_trans/trans_privileged.c.inc
index 75c6ef80a6..6e39632f83 100644
--- a/target/riscv/insn_trans/trans_privileged.c.inc
+++ b/target/riscv/insn_trans/trans_privileged.c.inc
@@ -78,6 +78,7 @@ static bool trans_sret(DisasContext *ctx, arg_sret *a)
 
     if (has_ext(ctx, RVS)) {
         gen_helper_sret(cpu_pc, cpu_env, cpu_pc);
+        gen_helper_switch_context_xl(cpu_env);
         tcg_gen_exit_tb(NULL, 0); /* no chaining */
         ctx->base.is_jmp = DISAS_NORETURN;
     } else {
@@ -94,6 +95,7 @@ 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_switch_context_xl(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 ee7c24efe7..20cf8ad883 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -70,6 +70,32 @@ target_ulong helper_csrrw(CPURISCVState *env, int csr,
 }
 
 #ifndef CONFIG_USER_ONLY
+void helper_switch_context_xl(CPURISCVState *env)
+{
+    RISCVMXL xl = cpu_get_xl(env);
+    if (xl == env->misa_mxl_max) {
+        return;
+    }
+    assert(xl < env->misa_mxl_max);
+    switch (xl) {
+    case MXL_RV32:
+        for (int i = 1; i < 32; i++) {
+            env->gpr[i] = (int32_t)env->gpr[i];
+        }
+        env->pc = (int32_t)env->pc;
+        /*
+         * For the read-only bits of the previous-width CSR, the bits at the
+         * same positions in the temporary register are set to zeros.
+         */
+        if ((env->priv == PRV_U) && (env->misa_ext & RVV)) {
+            env->vl = 0;
+            env->vtype = 0;
+        }
+        break;
+    default:
+        break;
+    }
+}
 
 target_ulong helper_sret(CPURISCVState *env, target_ulong cpu_pc_deb)
 {
-- 
2.25.1



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

* [PATCH 12/13] target/riscv: Don't save pc when exception return
  2021-11-01 10:01 ` LIU Zhiwei
@ 2021-11-01 10:01   ` LIU Zhiwei
  -1 siblings, 0 replies; 88+ messages in thread
From: LIU Zhiwei @ 2021-11-01 10:01 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: palmer, richard.henderson, bin.meng, 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>
---
 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 9b379d7232..34c57a6083 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -67,8 +67,8 @@ DEF_HELPER_2(csrr, tl, env, int)
 DEF_HELPER_3(csrw, void, env, int, tl)
 DEF_HELPER_4(csrrw, tl, env, int, 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)
 DEF_HELPER_1(switch_context_xl, void, env)
diff --git a/target/riscv/insn_trans/trans_privileged.c.inc b/target/riscv/insn_trans/trans_privileged.c.inc
index 6e39632f83..cf6dc98888 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);
         gen_helper_switch_context_xl(cpu_env);
         tcg_gen_exit_tb(NULL, 0); /* no chaining */
         ctx->base.is_jmp = DISAS_NORETURN;
@@ -93,8 +91,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);
     gen_helper_switch_context_xl(cpu_env);
     tcg_gen_exit_tb(NULL, 0); /* no chaining */
     ctx->base.is_jmp = DISAS_NORETURN;
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index 20cf8ad883..3ce2767ccf 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -97,7 +97,7 @@ void helper_switch_context_xl(CPURISCVState *env)
     }
 }
 
-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;
@@ -158,7 +158,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] 88+ messages in thread

* [PATCH 12/13] target/riscv: Don't save pc when exception return
@ 2021-11-01 10:01   ` LIU Zhiwei
  0 siblings, 0 replies; 88+ messages in thread
From: LIU Zhiwei @ 2021-11-01 10:01 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: Alistair.Francis, palmer, bin.meng, richard.henderson, 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>
---
 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 9b379d7232..34c57a6083 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -67,8 +67,8 @@ DEF_HELPER_2(csrr, tl, env, int)
 DEF_HELPER_3(csrw, void, env, int, tl)
 DEF_HELPER_4(csrrw, tl, env, int, 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)
 DEF_HELPER_1(switch_context_xl, void, env)
diff --git a/target/riscv/insn_trans/trans_privileged.c.inc b/target/riscv/insn_trans/trans_privileged.c.inc
index 6e39632f83..cf6dc98888 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);
         gen_helper_switch_context_xl(cpu_env);
         tcg_gen_exit_tb(NULL, 0); /* no chaining */
         ctx->base.is_jmp = DISAS_NORETURN;
@@ -93,8 +91,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);
     gen_helper_switch_context_xl(cpu_env);
     tcg_gen_exit_tb(NULL, 0); /* no chaining */
     ctx->base.is_jmp = DISAS_NORETURN;
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index 20cf8ad883..3ce2767ccf 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -97,7 +97,7 @@ void helper_switch_context_xl(CPURISCVState *env)
     }
 }
 
-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;
@@ -158,7 +158,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] 88+ messages in thread

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

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

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 9f41954894..471c10acf6 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -543,14 +543,16 @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno,
          * add them to mstatush. For now, we just don't support it.
          */
         mask |= MSTATUS_MPV | MSTATUS_GVA;
+        if ((val ^ mstatus) & MSTATUS64_UXL) {
+            mask |= MSTATUS64_UXL;
+        }
     }
 
     mstatus = (mstatus & ~mask) | (val & mask);
 
     if (riscv_cpu_mxl(env) == MXL_RV64) {
-        /* SXL and UXL fields are for now read only */
+        /* SXL fields are for now read only */
         mstatus = set_field(mstatus, MSTATUS64_SXL, MXL_RV64);
-        mstatus = set_field(mstatus, MSTATUS64_UXL, MXL_RV64);
     }
     env->mstatus = mstatus;
 
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
index bd9d50bb94..880026f13d 100644
--- a/target/riscv/insn_trans/trans_rvi.c.inc
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
@@ -475,7 +475,7 @@ static bool do_csrrw(DisasContext *ctx, int rd, int rc, TCGv src, TCGv mask)
 
 static bool trans_csrrw(DisasContext *ctx, arg_csrrw *a)
 {
-    TCGv src = get_gpr(ctx, a->rs1, EXT_NONE);
+    TCGv src = get_gpr(ctx, a->rs1, EXT_ZERO);
 
     /*
      * If rd == 0, the insn shall not read the csr, nor cause any of the
-- 
2.25.1



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

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

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

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 9f41954894..471c10acf6 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -543,14 +543,16 @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno,
          * add them to mstatush. For now, we just don't support it.
          */
         mask |= MSTATUS_MPV | MSTATUS_GVA;
+        if ((val ^ mstatus) & MSTATUS64_UXL) {
+            mask |= MSTATUS64_UXL;
+        }
     }
 
     mstatus = (mstatus & ~mask) | (val & mask);
 
     if (riscv_cpu_mxl(env) == MXL_RV64) {
-        /* SXL and UXL fields are for now read only */
+        /* SXL fields are for now read only */
         mstatus = set_field(mstatus, MSTATUS64_SXL, MXL_RV64);
-        mstatus = set_field(mstatus, MSTATUS64_UXL, MXL_RV64);
     }
     env->mstatus = mstatus;
 
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
index bd9d50bb94..880026f13d 100644
--- a/target/riscv/insn_trans/trans_rvi.c.inc
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
@@ -475,7 +475,7 @@ static bool do_csrrw(DisasContext *ctx, int rd, int rc, TCGv src, TCGv mask)
 
 static bool trans_csrrw(DisasContext *ctx, arg_csrrw *a)
 {
-    TCGv src = get_gpr(ctx, a->rs1, EXT_NONE);
+    TCGv src = get_gpr(ctx, a->rs1, EXT_ZERO);
 
     /*
      * If rd == 0, the insn shall not read the csr, nor cause any of the
-- 
2.25.1



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

* Re: [PATCH 01/13] target/riscv: Sign extend pc for different ol
  2021-11-01 10:01   ` LIU Zhiwei
@ 2021-11-01 10:29     ` Richard Henderson
  -1 siblings, 0 replies; 88+ messages in thread
From: Richard Henderson @ 2021-11-01 10:29 UTC (permalink / raw)
  To: LIU Zhiwei, qemu-devel, qemu-riscv; +Cc: palmer, bin.meng, Alistair.Francis

On 11/1/21 6:01 AM, LIU Zhiwei wrote:
> +static void gen_set_pc(DisasContext *ctx, target_ulong dest)
> +{
> +    TCGv t = tcg_constant_tl(dest);
> +    switch (get_ol(ctx)) {
> +    case MXL_RV32:
> +        tcg_gen_ext32s_tl(cpu_pc, t);

Don't compute with tcg to do what you can in C.  Dest is constant.
And I think that XL is more appropriate than OL (which *should* be the same, but still 
looks weird).

     if (get_xl(ctx) == MXL_RV32) {
         dest = (int32_t)dest;
     }
     tcg_gen_movi_tl(cpu_pc, dest);


r~


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

* Re: [PATCH 01/13] target/riscv: Sign extend pc for different ol
@ 2021-11-01 10:29     ` Richard Henderson
  0 siblings, 0 replies; 88+ messages in thread
From: Richard Henderson @ 2021-11-01 10:29 UTC (permalink / raw)
  To: LIU Zhiwei, qemu-devel, qemu-riscv; +Cc: Alistair.Francis, palmer, bin.meng

On 11/1/21 6:01 AM, LIU Zhiwei wrote:
> +static void gen_set_pc(DisasContext *ctx, target_ulong dest)
> +{
> +    TCGv t = tcg_constant_tl(dest);
> +    switch (get_ol(ctx)) {
> +    case MXL_RV32:
> +        tcg_gen_ext32s_tl(cpu_pc, t);

Don't compute with tcg to do what you can in C.  Dest is constant.
And I think that XL is more appropriate than OL (which *should* be the same, but still 
looks weird).

     if (get_xl(ctx) == MXL_RV32) {
         dest = (int32_t)dest;
     }
     tcg_gen_movi_tl(cpu_pc, dest);


r~


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

* Re: [PATCH 02/13] target/riscv: Extend pc for runtime pc write
  2021-11-01 10:01   ` LIU Zhiwei
@ 2021-11-01 10:33     ` Richard Henderson
  -1 siblings, 0 replies; 88+ messages in thread
From: Richard Henderson @ 2021-11-01 10:33 UTC (permalink / raw)
  To: LIU Zhiwei, qemu-devel, qemu-riscv; +Cc: palmer, bin.meng, Alistair.Francis

On 11/1/21 6:01 AM, LIU Zhiwei wrote:
> In some cases, we must restore the guest PC to the address of the start of
> the TB, such as when the instruction counter hit zero. So extend pc register
> according to current xlen for these cases.
> 
> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
> ---
>   target/riscv/cpu.c        | 20 +++++++++++++++++---
>   target/riscv/cpu.h        |  2 ++
>   target/riscv/cpu_helper.c |  2 +-
>   3 files changed, 20 insertions(+), 4 deletions(-)
> 
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 7d53125dbc..7eefd4f6a6 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -319,7 +319,12 @@ static void riscv_cpu_set_pc(CPUState *cs, vaddr value)
>   {
>       RISCVCPU *cpu = RISCV_CPU(cs);
>       CPURISCVState *env = &cpu->env;
> -    env->pc = value;
> +
> +    if (cpu_get_xl(env) == MXL_RV32) {
> +        env->pc = (int32_t)value;
> +    } else {
> +        env->pc = value;
> +    }
>   }
>   

Good.

>   static void riscv_cpu_synchronize_from_tb(CPUState *cs,
> @@ -327,7 +332,12 @@ static void riscv_cpu_synchronize_from_tb(CPUState *cs,
>   {
>       RISCVCPU *cpu = RISCV_CPU(cs);
>       CPURISCVState *env = &cpu->env;
> -    env->pc = tb->pc;
> +
> +    if (cpu_get_xl(env) == MXL_RV32) {
> +        env->pc = (int32_t)tb->pc;
> +    } else {
> +        env->pc = tb->pc;
> +    }

Bad, since TB->PC should be extended properly.
Though this waits on a change to cpu_get_tb_cpu_state.

> @@ -348,7 +358,11 @@ static bool riscv_cpu_has_work(CPUState *cs)
>   void restore_state_to_opc(CPURISCVState *env, TranslationBlock *tb,
>                             target_ulong *data)
>   {
> -    env->pc = data[0];
> +   if (cpu_get_xl(env) == MXL_RV32) {
> +        env->pc = (int32_t)data[0];
> +    } else {
> +        env->pc = data[0];
> +    }

Likewise.


r~


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

* Re: [PATCH 02/13] target/riscv: Extend pc for runtime pc write
@ 2021-11-01 10:33     ` Richard Henderson
  0 siblings, 0 replies; 88+ messages in thread
From: Richard Henderson @ 2021-11-01 10:33 UTC (permalink / raw)
  To: LIU Zhiwei, qemu-devel, qemu-riscv; +Cc: Alistair.Francis, palmer, bin.meng

On 11/1/21 6:01 AM, LIU Zhiwei wrote:
> In some cases, we must restore the guest PC to the address of the start of
> the TB, such as when the instruction counter hit zero. So extend pc register
> according to current xlen for these cases.
> 
> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
> ---
>   target/riscv/cpu.c        | 20 +++++++++++++++++---
>   target/riscv/cpu.h        |  2 ++
>   target/riscv/cpu_helper.c |  2 +-
>   3 files changed, 20 insertions(+), 4 deletions(-)
> 
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 7d53125dbc..7eefd4f6a6 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -319,7 +319,12 @@ static void riscv_cpu_set_pc(CPUState *cs, vaddr value)
>   {
>       RISCVCPU *cpu = RISCV_CPU(cs);
>       CPURISCVState *env = &cpu->env;
> -    env->pc = value;
> +
> +    if (cpu_get_xl(env) == MXL_RV32) {
> +        env->pc = (int32_t)value;
> +    } else {
> +        env->pc = value;
> +    }
>   }
>   

Good.

>   static void riscv_cpu_synchronize_from_tb(CPUState *cs,
> @@ -327,7 +332,12 @@ static void riscv_cpu_synchronize_from_tb(CPUState *cs,
>   {
>       RISCVCPU *cpu = RISCV_CPU(cs);
>       CPURISCVState *env = &cpu->env;
> -    env->pc = tb->pc;
> +
> +    if (cpu_get_xl(env) == MXL_RV32) {
> +        env->pc = (int32_t)tb->pc;
> +    } else {
> +        env->pc = tb->pc;
> +    }

Bad, since TB->PC should be extended properly.
Though this waits on a change to cpu_get_tb_cpu_state.

> @@ -348,7 +358,11 @@ static bool riscv_cpu_has_work(CPUState *cs)
>   void restore_state_to_opc(CPURISCVState *env, TranslationBlock *tb,
>                             target_ulong *data)
>   {
> -    env->pc = data[0];
> +   if (cpu_get_xl(env) == MXL_RV32) {
> +        env->pc = (int32_t)data[0];
> +    } else {
> +        env->pc = data[0];
> +    }

Likewise.


r~


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

* Re: [PATCH 03/13] target/riscv: Ignore the pc bits above XLEN
  2021-11-01 10:01   ` LIU Zhiwei
@ 2021-11-01 10:35     ` Richard Henderson
  -1 siblings, 0 replies; 88+ messages in thread
From: Richard Henderson @ 2021-11-01 10:35 UTC (permalink / raw)
  To: LIU Zhiwei, qemu-devel, qemu-riscv; +Cc: palmer, bin.meng, Alistair.Francis

On 11/1/21 6:01 AM, LIU Zhiwei wrote:
> 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>
> ---
>   target/riscv/cpu_helper.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

Could perhaps be sorted to patch 2, then riscv_cpu_synchronize_from_tb and 
restore_state_to_opc could assert that the pc is properly extended.


r~


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

* Re: [PATCH 03/13] target/riscv: Ignore the pc bits above XLEN
@ 2021-11-01 10:35     ` Richard Henderson
  0 siblings, 0 replies; 88+ messages in thread
From: Richard Henderson @ 2021-11-01 10:35 UTC (permalink / raw)
  To: LIU Zhiwei, qemu-devel, qemu-riscv; +Cc: Alistair.Francis, palmer, bin.meng

On 11/1/21 6:01 AM, LIU Zhiwei wrote:
> 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>
> ---
>   target/riscv/cpu_helper.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

Could perhaps be sorted to patch 2, then riscv_cpu_synchronize_from_tb and 
restore_state_to_opc could assert that the pc is properly extended.


r~


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

* Re: [PATCH 04/13] target/riscv: Use gdb xml according to max mxlen
  2021-11-01 10:01   ` LIU Zhiwei
@ 2021-11-01 10:40     ` Richard Henderson
  -1 siblings, 0 replies; 88+ messages in thread
From: Richard Henderson @ 2021-11-01 10:40 UTC (permalink / raw)
  To: LIU Zhiwei, qemu-devel, qemu-riscv; +Cc: palmer, bin.meng, Alistair.Francis

On 11/1/21 6:01 AM, LIU Zhiwei wrote:
> +    switch (env->misa_mxl_max) {
> +    case MXL_RV32:
> +        tmp = (uint32_t)ldl_p(mem_buf);

Signed int32_t.

Otherwise,
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~


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

* Re: [PATCH 04/13] target/riscv: Use gdb xml according to max mxlen
@ 2021-11-01 10:40     ` Richard Henderson
  0 siblings, 0 replies; 88+ messages in thread
From: Richard Henderson @ 2021-11-01 10:40 UTC (permalink / raw)
  To: LIU Zhiwei, qemu-devel, qemu-riscv; +Cc: Alistair.Francis, palmer, bin.meng

On 11/1/21 6:01 AM, LIU Zhiwei wrote:
> +    switch (env->misa_mxl_max) {
> +    case MXL_RV32:
> +        tmp = (uint32_t)ldl_p(mem_buf);

Signed int32_t.

Otherwise,
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~


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

* Re: [PATCH 05/13] target/riscv: Calculate address according to ol
  2021-11-01 10:01   ` LIU Zhiwei
@ 2021-11-01 10:46     ` Richard Henderson
  -1 siblings, 0 replies; 88+ messages in thread
From: Richard Henderson @ 2021-11-01 10:46 UTC (permalink / raw)
  To: LIU Zhiwei, qemu-devel, qemu-riscv; +Cc: palmer, bin.meng, Alistair.Francis

On 11/1/21 6:01 AM, LIU Zhiwei wrote:
>   static bool trans_fld(DisasContext *ctx, arg_fld *a)
>   {
> -    TCGv addr;
> +    TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
> +    TCGv addr = temp_new(ctx);
>   
>       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;
> -    }
> +    tcg_gen_addi_tl(addr, src1, a->imm);
>       addr = gen_pm_adjust_address(ctx, addr);

No change here,

>   static bool trans_fsd(DisasContext *ctx, arg_fsd *a)
>   {
> -    TCGv addr;
> +    TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
> +    TCGv addr = temp_new(ctx);
>   
>       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;
> -    }
> +    tcg_gen_addi_tl(addr, src1, a->imm);
>       addr = gen_pm_adjust_address(ctx, addr);

Or here.

>   static bool trans_flw(DisasContext *ctx, arg_flw *a)
>   {
>       TCGv_i64 dest;
> -    TCGv addr;
> +    TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
> +    TCGv addr = temp_new(ctx);
>   
>       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;
> +    tcg_gen_addi_tl(addr, src1, a->imm);
> +    if (ctx->ol == MXL_RV32) {
> +        tcg_gen_ext32u_tl(addr, addr);
>       }
>       addr = gen_pm_adjust_address(ctx, addr);

But you did here.

(1) OL is wrong, use XL.
(2) The address adjustment should be done in some common routine.
     Probably rename gen_pm_adjust_address to make it more generic,
     then add the XL truncation there.


r~


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

* Re: [PATCH 05/13] target/riscv: Calculate address according to ol
@ 2021-11-01 10:46     ` Richard Henderson
  0 siblings, 0 replies; 88+ messages in thread
From: Richard Henderson @ 2021-11-01 10:46 UTC (permalink / raw)
  To: LIU Zhiwei, qemu-devel, qemu-riscv; +Cc: Alistair.Francis, palmer, bin.meng

On 11/1/21 6:01 AM, LIU Zhiwei wrote:
>   static bool trans_fld(DisasContext *ctx, arg_fld *a)
>   {
> -    TCGv addr;
> +    TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
> +    TCGv addr = temp_new(ctx);
>   
>       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;
> -    }
> +    tcg_gen_addi_tl(addr, src1, a->imm);
>       addr = gen_pm_adjust_address(ctx, addr);

No change here,

>   static bool trans_fsd(DisasContext *ctx, arg_fsd *a)
>   {
> -    TCGv addr;
> +    TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
> +    TCGv addr = temp_new(ctx);
>   
>       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;
> -    }
> +    tcg_gen_addi_tl(addr, src1, a->imm);
>       addr = gen_pm_adjust_address(ctx, addr);

Or here.

>   static bool trans_flw(DisasContext *ctx, arg_flw *a)
>   {
>       TCGv_i64 dest;
> -    TCGv addr;
> +    TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
> +    TCGv addr = temp_new(ctx);
>   
>       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;
> +    tcg_gen_addi_tl(addr, src1, a->imm);
> +    if (ctx->ol == MXL_RV32) {
> +        tcg_gen_ext32u_tl(addr, addr);
>       }
>       addr = gen_pm_adjust_address(ctx, addr);

But you did here.

(1) OL is wrong, use XL.
(2) The address adjustment should be done in some common routine.
     Probably rename gen_pm_adjust_address to make it more generic,
     then add the XL truncation there.


r~


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

* Re: [PATCH 06/13] target/riscv: Adjust vsetvl according to ol
  2021-11-01 10:01   ` LIU Zhiwei
@ 2021-11-01 10:53     ` Richard Henderson
  -1 siblings, 0 replies; 88+ messages in thread
From: Richard Henderson @ 2021-11-01 10:53 UTC (permalink / raw)
  To: LIU Zhiwei, qemu-devel, qemu-riscv; +Cc: palmer, bin.meng, Alistair.Francis

On 11/1/21 6:01 AM, LIU Zhiwei wrote:
> --- a/target/riscv/insn_trans/trans_rvv.c.inc
> +++ b/target/riscv/insn_trans/trans_rvv.c.inc
> @@ -37,7 +37,7 @@ static bool trans_vsetvl(DisasContext *ctx, arg_vsetvl *a)
>       } else {
>           s1 = get_gpr(ctx, a->rs1, EXT_ZERO);
>       }
> -    gen_helper_vsetvl(dst, cpu_env, s1, s2);
> +    gen_helper_vsetvl(dst, cpu_env, s1, s2, tcg_constant_tl(get_olen(ctx)));

XLEN not OLEN.

> +        if (olen < TARGET_LONG_BITS) {
> +            env->vtype = FIELD_DP64(0, VTYPE, VILL_OLEN32, 1);
> +        } else {
> +            env->vtype = FIELD_DP64(0, VTYPE, VILL, 1);
> +        }

This looks like an excellent reason to split VILL out of VTYPE and create a separate 
env->vill field.  Re-assemble it when reading the CSR, much like we do for misa.mxl.  That 
would want to be a separate patch, of course.


r~


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

* Re: [PATCH 06/13] target/riscv: Adjust vsetvl according to ol
@ 2021-11-01 10:53     ` Richard Henderson
  0 siblings, 0 replies; 88+ messages in thread
From: Richard Henderson @ 2021-11-01 10:53 UTC (permalink / raw)
  To: LIU Zhiwei, qemu-devel, qemu-riscv; +Cc: Alistair.Francis, palmer, bin.meng

On 11/1/21 6:01 AM, LIU Zhiwei wrote:
> --- a/target/riscv/insn_trans/trans_rvv.c.inc
> +++ b/target/riscv/insn_trans/trans_rvv.c.inc
> @@ -37,7 +37,7 @@ static bool trans_vsetvl(DisasContext *ctx, arg_vsetvl *a)
>       } else {
>           s1 = get_gpr(ctx, a->rs1, EXT_ZERO);
>       }
> -    gen_helper_vsetvl(dst, cpu_env, s1, s2);
> +    gen_helper_vsetvl(dst, cpu_env, s1, s2, tcg_constant_tl(get_olen(ctx)));

XLEN not OLEN.

> +        if (olen < TARGET_LONG_BITS) {
> +            env->vtype = FIELD_DP64(0, VTYPE, VILL_OLEN32, 1);
> +        } else {
> +            env->vtype = FIELD_DP64(0, VTYPE, VILL, 1);
> +        }

This looks like an excellent reason to split VILL out of VTYPE and create a separate 
env->vill field.  Re-assemble it when reading the CSR, much like we do for misa.mxl.  That 
would want to be a separate patch, of course.


r~


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

* Re: [PATCH 07/13] target/riscv: Ajdust vector atomic check with ol
  2021-11-01 10:01   ` LIU Zhiwei
@ 2021-11-01 10:55     ` Richard Henderson
  -1 siblings, 0 replies; 88+ messages in thread
From: Richard Henderson @ 2021-11-01 10:55 UTC (permalink / raw)
  To: LIU Zhiwei, qemu-devel, qemu-riscv; +Cc: palmer, bin.meng, Alistair.Francis

On 11/1/21 6:01 AM, LIU Zhiwei wrote:
> -            ((1 << s->sew) <= sizeof(target_ulong)) &&
> +            ((1 << s->sew) <= (get_olen(s) / 8)) &&

XLEN not OLEN.

But this will also clash with rv128, since we still won't have 128-bit atomics.  So I 
think you need to be more reserved in this change:

     /* TODO: RV128 could allow 128-bit atomics */
     (get_xl(s) == MXL_RV32 ? 4 : 8)


r~


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

* Re: [PATCH 07/13] target/riscv: Ajdust vector atomic check with ol
@ 2021-11-01 10:55     ` Richard Henderson
  0 siblings, 0 replies; 88+ messages in thread
From: Richard Henderson @ 2021-11-01 10:55 UTC (permalink / raw)
  To: LIU Zhiwei, qemu-devel, qemu-riscv; +Cc: Alistair.Francis, palmer, bin.meng

On 11/1/21 6:01 AM, LIU Zhiwei wrote:
> -            ((1 << s->sew) <= sizeof(target_ulong)) &&
> +            ((1 << s->sew) <= (get_olen(s) / 8)) &&

XLEN not OLEN.

But this will also clash with rv128, since we still won't have 128-bit atomics.  So I 
think you need to be more reserved in this change:

     /* TODO: RV128 could allow 128-bit atomics */
     (get_xl(s) == MXL_RV32 ? 4 : 8)


r~


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

* Re: [PATCH 09/13] target/riscv: Adjust vector address with ol
  2021-11-01 10:01   ` LIU Zhiwei
@ 2021-11-01 11:35     ` Richard Henderson
  -1 siblings, 0 replies; 88+ messages in thread
From: Richard Henderson @ 2021-11-01 11:35 UTC (permalink / raw)
  To: LIU Zhiwei, qemu-devel, qemu-riscv, Alexey Baturo
  Cc: palmer, bin.meng, Alistair.Francis

On 11/1/21 6:01 AM, LIU Zhiwei wrote:
> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
> ---
>   target/riscv/insn_trans/trans_rvv.c.inc |  8 ++++
>   target/riscv/internals.h                |  1 +
>   target/riscv/vector_helper.c            | 54 +++++++++++++++++--------
>   3 files changed, 46 insertions(+), 17 deletions(-)
> 
> diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
> index ed042f7bb9..5cd9b802df 100644
> --- a/target/riscv/insn_trans/trans_rvv.c.inc
> +++ b/target/riscv/insn_trans/trans_rvv.c.inc
> @@ -233,6 +233,7 @@ static bool ld_us_op(DisasContext *s, arg_r2nfvm *a, uint8_t seq)
>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>       data = FIELD_DP32(data, VDATA, NF, a->nf);
> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>       return ldst_us_trans(a->rd, a->rs1, data, fn, s);
>   }
>   
> @@ -286,6 +287,7 @@ static bool st_us_op(DisasContext *s, arg_r2nfvm *a, uint8_t seq)
>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>       data = FIELD_DP32(data, VDATA, NF, a->nf);
> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>       return ldst_us_trans(a->rd, a->rs1, data, fn, s);
>   }
>   
> @@ -365,6 +367,7 @@ static bool ld_stride_op(DisasContext *s, arg_rnfvm *a, uint8_t seq)
>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>       data = FIELD_DP32(data, VDATA, NF, a->nf);
> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>       return ldst_stride_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>   }
>   
> @@ -404,6 +407,7 @@ static bool st_stride_op(DisasContext *s, arg_rnfvm *a, uint8_t seq)
>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>       data = FIELD_DP32(data, VDATA, NF, a->nf);
> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>       fn =  fns[seq][s->sew];
>       if (fn == NULL) {
>           return false;
> @@ -490,6 +494,7 @@ static bool ld_index_op(DisasContext *s, arg_rnfvm *a, uint8_t seq)
>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>       data = FIELD_DP32(data, VDATA, NF, a->nf);
> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>       return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>   }
>   
> @@ -542,6 +547,7 @@ static bool st_index_op(DisasContext *s, arg_rnfvm *a, uint8_t seq)
>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>       data = FIELD_DP32(data, VDATA, NF, a->nf);
> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>       return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>   }
>   
> @@ -617,6 +623,7 @@ static bool ldff_op(DisasContext *s, arg_r2nfvm *a, uint8_t seq)
>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>       data = FIELD_DP32(data, VDATA, NF, a->nf);
> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>       return ldff_trans(a->rd, a->rs1, data, fn, s);
>   }
>   
> @@ -724,6 +731,7 @@ static bool amo_op(DisasContext *s, arg_rwdvm *a, uint8_t seq)
>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>       data = FIELD_DP32(data, VDATA, WD, a->wd);
> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>       return amo_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>   }
>   /*
> diff --git a/target/riscv/internals.h b/target/riscv/internals.h
> index b15ad394bb..f74b8291e4 100644
> --- a/target/riscv/internals.h
> +++ b/target/riscv/internals.h
> @@ -27,6 +27,7 @@ FIELD(VDATA, VM, 8, 1)
>   FIELD(VDATA, LMUL, 9, 2)
>   FIELD(VDATA, NF, 11, 4)
>   FIELD(VDATA, WD, 11, 1)
> +FIELD(VDATA, OL, 15, 2)
>   
>   /* float point classify helpers */
>   target_ulong fclass_h(uint64_t frs1);
> diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
> index 535420ee66..451688c328 100644
> --- a/target/riscv/vector_helper.c
> +++ b/target/riscv/vector_helper.c
> @@ -112,6 +112,11 @@ static uint32_t vext_wd(uint32_t desc)
>       return (simd_data(desc) >> 11) & 0x1;
>   }
>   
> +static inline uint32_t vext_ol(uint32_t desc)
> +{
> +    return FIELD_EX32(simd_data(desc), VDATA, OL);
> +}

XLEN not OLEN.

> @@ -123,6 +128,14 @@ static inline uint32_t vext_maxsz(uint32_t desc)
>       return simd_maxsz(desc) << vext_lmul(desc);
>   }
>   
> +static inline target_ulong adjust_addr(target_ulong addr, uint32_t olen)
> +{
> +    if (olen < TARGET_LONG_BITS) {
> +        addr &= UINT32_MAX;
> +    }
> +    return addr;
> +}

Here's where I'm unsure.  This looks a lot like the changes that are required to support 
pointer-masking in vectors, which Alexey said he was going to look at.

(1) Do we need to pass anything in VEXT at all?
     We do have CPURISCVState, so we could just use cpu_get_ml,
     which we would also need for env->mmte etc for pointer masking.

(2) Do we try to streamline the "normal" case with a simple bit in VEXT
     that indicates if the address needs modification at all?  I.e. the
     bit is set if UXLEN < TARGET_LONG_BITS or if PM_ENABLED?

(3) Do we try to streamline the computation by passing down composite
     mask and base parameters.  This way we don't need to do complex
     examination of ENV to determine execution mode, and instead always
     compute

        addr = (addr & mask) | base;

     where mask = -1, base = 0 for "normal" addressing, and when
     UXLEN == 32, mask <= UINT32_MAX.

(4) Do we in fact want to pre-compute these into known slots on ENV,
     so that we don't have to pass these around as separate parameters?
     We would adjust these values during PM CSR changes and when
     changing privilege levels.


r~


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

* Re: [PATCH 09/13] target/riscv: Adjust vector address with ol
@ 2021-11-01 11:35     ` Richard Henderson
  0 siblings, 0 replies; 88+ messages in thread
From: Richard Henderson @ 2021-11-01 11:35 UTC (permalink / raw)
  To: LIU Zhiwei, qemu-devel, qemu-riscv, Alexey Baturo
  Cc: Alistair.Francis, palmer, bin.meng

On 11/1/21 6:01 AM, LIU Zhiwei wrote:
> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
> ---
>   target/riscv/insn_trans/trans_rvv.c.inc |  8 ++++
>   target/riscv/internals.h                |  1 +
>   target/riscv/vector_helper.c            | 54 +++++++++++++++++--------
>   3 files changed, 46 insertions(+), 17 deletions(-)
> 
> diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
> index ed042f7bb9..5cd9b802df 100644
> --- a/target/riscv/insn_trans/trans_rvv.c.inc
> +++ b/target/riscv/insn_trans/trans_rvv.c.inc
> @@ -233,6 +233,7 @@ static bool ld_us_op(DisasContext *s, arg_r2nfvm *a, uint8_t seq)
>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>       data = FIELD_DP32(data, VDATA, NF, a->nf);
> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>       return ldst_us_trans(a->rd, a->rs1, data, fn, s);
>   }
>   
> @@ -286,6 +287,7 @@ static bool st_us_op(DisasContext *s, arg_r2nfvm *a, uint8_t seq)
>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>       data = FIELD_DP32(data, VDATA, NF, a->nf);
> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>       return ldst_us_trans(a->rd, a->rs1, data, fn, s);
>   }
>   
> @@ -365,6 +367,7 @@ static bool ld_stride_op(DisasContext *s, arg_rnfvm *a, uint8_t seq)
>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>       data = FIELD_DP32(data, VDATA, NF, a->nf);
> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>       return ldst_stride_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>   }
>   
> @@ -404,6 +407,7 @@ static bool st_stride_op(DisasContext *s, arg_rnfvm *a, uint8_t seq)
>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>       data = FIELD_DP32(data, VDATA, NF, a->nf);
> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>       fn =  fns[seq][s->sew];
>       if (fn == NULL) {
>           return false;
> @@ -490,6 +494,7 @@ static bool ld_index_op(DisasContext *s, arg_rnfvm *a, uint8_t seq)
>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>       data = FIELD_DP32(data, VDATA, NF, a->nf);
> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>       return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>   }
>   
> @@ -542,6 +547,7 @@ static bool st_index_op(DisasContext *s, arg_rnfvm *a, uint8_t seq)
>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>       data = FIELD_DP32(data, VDATA, NF, a->nf);
> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>       return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>   }
>   
> @@ -617,6 +623,7 @@ static bool ldff_op(DisasContext *s, arg_r2nfvm *a, uint8_t seq)
>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>       data = FIELD_DP32(data, VDATA, NF, a->nf);
> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>       return ldff_trans(a->rd, a->rs1, data, fn, s);
>   }
>   
> @@ -724,6 +731,7 @@ static bool amo_op(DisasContext *s, arg_rwdvm *a, uint8_t seq)
>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>       data = FIELD_DP32(data, VDATA, WD, a->wd);
> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>       return amo_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>   }
>   /*
> diff --git a/target/riscv/internals.h b/target/riscv/internals.h
> index b15ad394bb..f74b8291e4 100644
> --- a/target/riscv/internals.h
> +++ b/target/riscv/internals.h
> @@ -27,6 +27,7 @@ FIELD(VDATA, VM, 8, 1)
>   FIELD(VDATA, LMUL, 9, 2)
>   FIELD(VDATA, NF, 11, 4)
>   FIELD(VDATA, WD, 11, 1)
> +FIELD(VDATA, OL, 15, 2)
>   
>   /* float point classify helpers */
>   target_ulong fclass_h(uint64_t frs1);
> diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
> index 535420ee66..451688c328 100644
> --- a/target/riscv/vector_helper.c
> +++ b/target/riscv/vector_helper.c
> @@ -112,6 +112,11 @@ static uint32_t vext_wd(uint32_t desc)
>       return (simd_data(desc) >> 11) & 0x1;
>   }
>   
> +static inline uint32_t vext_ol(uint32_t desc)
> +{
> +    return FIELD_EX32(simd_data(desc), VDATA, OL);
> +}

XLEN not OLEN.

> @@ -123,6 +128,14 @@ static inline uint32_t vext_maxsz(uint32_t desc)
>       return simd_maxsz(desc) << vext_lmul(desc);
>   }
>   
> +static inline target_ulong adjust_addr(target_ulong addr, uint32_t olen)
> +{
> +    if (olen < TARGET_LONG_BITS) {
> +        addr &= UINT32_MAX;
> +    }
> +    return addr;
> +}

Here's where I'm unsure.  This looks a lot like the changes that are required to support 
pointer-masking in vectors, which Alexey said he was going to look at.

(1) Do we need to pass anything in VEXT at all?
     We do have CPURISCVState, so we could just use cpu_get_ml,
     which we would also need for env->mmte etc for pointer masking.

(2) Do we try to streamline the "normal" case with a simple bit in VEXT
     that indicates if the address needs modification at all?  I.e. the
     bit is set if UXLEN < TARGET_LONG_BITS or if PM_ENABLED?

(3) Do we try to streamline the computation by passing down composite
     mask and base parameters.  This way we don't need to do complex
     examination of ENV to determine execution mode, and instead always
     compute

        addr = (addr & mask) | base;

     where mask = -1, base = 0 for "normal" addressing, and when
     UXLEN == 32, mask <= UINT32_MAX.

(4) Do we in fact want to pre-compute these into known slots on ENV,
     so that we don't have to pass these around as separate parameters?
     We would adjust these values during PM CSR changes and when
     changing privilege levels.


r~


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

* Re: [PATCH 08/13] target/riscv: Fix check range for first fault only
  2021-11-01 10:01   ` LIU Zhiwei
@ 2021-11-01 13:41     ` Richard Henderson
  -1 siblings, 0 replies; 88+ messages in thread
From: Richard Henderson @ 2021-11-01 13:41 UTC (permalink / raw)
  To: LIU Zhiwei, qemu-devel, qemu-riscv; +Cc: palmer, bin.meng, Alistair.Francis

On 11/1/21 6:01 AM, LIU Zhiwei wrote:
> Only check the range that has passed the address translation.
> 
> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
> ---
>   target/riscv/vector_helper.c | 4 ++--
>   1 file changed, 2 insertions(+), 2 deletions(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


> @@ -638,12 +638,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 * msz, PAGE_READ) < 0) {
> +                    if (page_check_range(addr, offset, PAGE_READ) < 0) {
>                           vl = i;
>                           goto ProbeSuccess;
>                       }
>   #else
> -                    probe_pages(env, addr, nf * msz, ra, MMU_DATA_LOAD);
> +                    probe_pages(env, addr, offset, ra, MMU_DATA_LOAD);
>   #endif

It looks like we could lose the ifdef here and always use probe_pages.
But that of course is a different change.


r~



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

* Re: [PATCH 08/13] target/riscv: Fix check range for first fault only
@ 2021-11-01 13:41     ` Richard Henderson
  0 siblings, 0 replies; 88+ messages in thread
From: Richard Henderson @ 2021-11-01 13:41 UTC (permalink / raw)
  To: LIU Zhiwei, qemu-devel, qemu-riscv; +Cc: Alistair.Francis, palmer, bin.meng

On 11/1/21 6:01 AM, LIU Zhiwei wrote:
> Only check the range that has passed the address translation.
> 
> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
> ---
>   target/riscv/vector_helper.c | 4 ++--
>   1 file changed, 2 insertions(+), 2 deletions(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


> @@ -638,12 +638,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 * msz, PAGE_READ) < 0) {
> +                    if (page_check_range(addr, offset, PAGE_READ) < 0) {
>                           vl = i;
>                           goto ProbeSuccess;
>                       }
>   #else
> -                    probe_pages(env, addr, nf * msz, ra, MMU_DATA_LOAD);
> +                    probe_pages(env, addr, offset, ra, MMU_DATA_LOAD);
>   #endif

It looks like we could lose the ifdef here and always use probe_pages.
But that of course is a different change.


r~



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

* Re: [PATCH 05/13] target/riscv: Calculate address according to ol
  2021-11-01 10:46     ` Richard Henderson
@ 2021-11-01 15:56       ` LIU Zhiwei
  -1 siblings, 0 replies; 88+ messages in thread
From: LIU Zhiwei @ 2021-11-01 15:56 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel, qemu-riscv
  Cc: palmer, bin.meng, Alistair.Francis


On 2021/11/1 下午6:46, Richard Henderson wrote:
> On 11/1/21 6:01 AM, LIU Zhiwei wrote:
>>   static bool trans_fld(DisasContext *ctx, arg_fld *a)
>>   {
>> -    TCGv addr;
>> +    TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
>> +    TCGv addr = temp_new(ctx);
>>         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;
>> -    }
>> +    tcg_gen_addi_tl(addr, src1, a->imm);
>>       addr = gen_pm_adjust_address(ctx, addr);
>
> No change here,
Oops, an error here.
>
>>   static bool trans_fsd(DisasContext *ctx, arg_fsd *a)
>>   {
>> -    TCGv addr;
>> +    TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
>> +    TCGv addr = temp_new(ctx);
>>         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;
>> -    }
>> +    tcg_gen_addi_tl(addr, src1, a->imm);
>>       addr = gen_pm_adjust_address(ctx, addr);
>
> Or here.
The same error.
>
>>   static bool trans_flw(DisasContext *ctx, arg_flw *a)
>>   {
>>       TCGv_i64 dest;
>> -    TCGv addr;
>> +    TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
>> +    TCGv addr = temp_new(ctx);
>>         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;
>> +    tcg_gen_addi_tl(addr, src1, a->imm);
>> +    if (ctx->ol == MXL_RV32) {
>> +        tcg_gen_ext32u_tl(addr, addr);
>>       }
>>       addr = gen_pm_adjust_address(ctx, addr);
>
> But you did here.
That's what I want to.
>
> (1) OL is wrong, use XL.
OK.
>
> (2) The address adjustment should be done in some common routine.
>     Probably rename gen_pm_adjust_address to make it more generic,
>     then add the XL truncation there.

Yes,  the XL truncation should be placed after gen_pm_adjust_address.
Maybe we can define a common routine to get address, and in the common 
routine
we calculate the address and adjust it with pointer mask and xl.

Thanks,
Zhiwei

>
>
> r~


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

* Re: [PATCH 05/13] target/riscv: Calculate address according to ol
@ 2021-11-01 15:56       ` LIU Zhiwei
  0 siblings, 0 replies; 88+ messages in thread
From: LIU Zhiwei @ 2021-11-01 15:56 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel, qemu-riscv
  Cc: Alistair.Francis, palmer, bin.meng


On 2021/11/1 下午6:46, Richard Henderson wrote:
> On 11/1/21 6:01 AM, LIU Zhiwei wrote:
>>   static bool trans_fld(DisasContext *ctx, arg_fld *a)
>>   {
>> -    TCGv addr;
>> +    TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
>> +    TCGv addr = temp_new(ctx);
>>         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;
>> -    }
>> +    tcg_gen_addi_tl(addr, src1, a->imm);
>>       addr = gen_pm_adjust_address(ctx, addr);
>
> No change here,
Oops, an error here.
>
>>   static bool trans_fsd(DisasContext *ctx, arg_fsd *a)
>>   {
>> -    TCGv addr;
>> +    TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
>> +    TCGv addr = temp_new(ctx);
>>         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;
>> -    }
>> +    tcg_gen_addi_tl(addr, src1, a->imm);
>>       addr = gen_pm_adjust_address(ctx, addr);
>
> Or here.
The same error.
>
>>   static bool trans_flw(DisasContext *ctx, arg_flw *a)
>>   {
>>       TCGv_i64 dest;
>> -    TCGv addr;
>> +    TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
>> +    TCGv addr = temp_new(ctx);
>>         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;
>> +    tcg_gen_addi_tl(addr, src1, a->imm);
>> +    if (ctx->ol == MXL_RV32) {
>> +        tcg_gen_ext32u_tl(addr, addr);
>>       }
>>       addr = gen_pm_adjust_address(ctx, addr);
>
> But you did here.
That's what I want to.
>
> (1) OL is wrong, use XL.
OK.
>
> (2) The address adjustment should be done in some common routine.
>     Probably rename gen_pm_adjust_address to make it more generic,
>     then add the XL truncation there.

Yes,  the XL truncation should be placed after gen_pm_adjust_address.
Maybe we can define a common routine to get address, and in the common 
routine
we calculate the address and adjust it with pointer mask and xl.

Thanks,
Zhiwei

>
>
> r~


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

* Re: [PATCH 10/13] target/riscv: Adjust scalar reg in vector with ol
  2021-11-01 10:01   ` LIU Zhiwei
@ 2021-11-01 16:33     ` Richard Henderson
  -1 siblings, 0 replies; 88+ messages in thread
From: Richard Henderson @ 2021-11-01 16:33 UTC (permalink / raw)
  To: LIU Zhiwei, qemu-devel, qemu-riscv; +Cc: palmer, bin.meng, Alistair.Francis

On 11/1/21 6:01 AM, LIU Zhiwei wrote:
> @@ -2677,6 +2677,7 @@ static bool trans_vmv_s_x(DisasContext *s, arg_vmv_s_x *a)
>           /* This instruction ignores LMUL and vector register groups */
>           int maxsz = s->vlen >> 3;
>           TCGv_i64 t1;
> +        TCGv src1 = get_gpr(s, a->rs1, EXT_ZERO);
>           TCGLabel *over = gen_new_label();
>   
>           tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
> @@ -2686,7 +2687,7 @@ static bool trans_vmv_s_x(DisasContext *s, arg_vmv_s_x *a)
>           }
>   
>           t1 = tcg_temp_new_i64();
> -        tcg_gen_extu_tl_i64(t1, cpu_gpr[a->rs1]);
> +        tcg_gen_extu_tl_i64(t1, src1);
>           vec_element_storei(s, a->rd, 0, t1);
>           tcg_temp_free_i64(t1);
>       done:

This isn't actually correct.  Or, may have been correct for the 0.7.1 revision, but the 
rvv 1.0 revision has a sign-extend here.

This probably shouldn't be touched until the rvv 1.0 patch set comes in.


> diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
> index 451688c328..5bdbbf7c71 100644
> --- a/target/riscv/vector_helper.c
> +++ b/target/riscv/vector_helper.c
> @@ -4763,6 +4763,7 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2,         \
>       uint32_t mlen = vext_mlen(desc);                                      \
>       uint32_t vlmax = env_archcpu(env)->cfg.vlen / mlen;                   \
>       uint32_t vm = vext_vm(desc);                                          \
> +    uint32_t olen = 16 << vext_ol(desc);                                  \
>       uint32_t vl = env->vl;                                                \
>       uint32_t i;                                                           \
>                                                                             \
> @@ -4771,7 +4772,7 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2,         \
>               continue;                                                     \
>           }                                                                 \
>           if (i == 0) {                                                     \
> -            *((ETYPE *)vd + H(i)) = s1;                                   \
> +            *((ETYPE *)vd + H(i)) = adjust_addr(s1, olen);                \
>           } else {                                                          \
>               *((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(i - 1));           \
>           }                                                                 \
> @@ -4792,6 +4793,7 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2,         \
>       uint32_t mlen = vext_mlen(desc);                                      \
>       uint32_t vlmax = env_archcpu(env)->cfg.vlen / mlen;                   \
>       uint32_t vm = vext_vm(desc);                                          \
> +    uint32_t olen = 16 << vext_ol(desc);                                  \
>       uint32_t vl = env->vl;                                                \
>       uint32_t i;                                                           \
>                                                                             \
> @@ -4800,7 +4802,7 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2,         \
>               continue;                                                     \
>           }                                                                 \
>           if (i == vl - 1) {                                                \
> -            *((ETYPE *)vd + H(i)) = s1;                                   \
> +            *((ETYPE *)vd + H(i)) = adjust_addr(s1, olen);                \
>           } else {                                                          \
>               *((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(i + 1));           \
>           }                                                                 \

What in the world is this?  S1 is not an address, it's just a value from X[RS1].


r~


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

* Re: [PATCH 10/13] target/riscv: Adjust scalar reg in vector with ol
@ 2021-11-01 16:33     ` Richard Henderson
  0 siblings, 0 replies; 88+ messages in thread
From: Richard Henderson @ 2021-11-01 16:33 UTC (permalink / raw)
  To: LIU Zhiwei, qemu-devel, qemu-riscv; +Cc: Alistair.Francis, palmer, bin.meng

On 11/1/21 6:01 AM, LIU Zhiwei wrote:
> @@ -2677,6 +2677,7 @@ static bool trans_vmv_s_x(DisasContext *s, arg_vmv_s_x *a)
>           /* This instruction ignores LMUL and vector register groups */
>           int maxsz = s->vlen >> 3;
>           TCGv_i64 t1;
> +        TCGv src1 = get_gpr(s, a->rs1, EXT_ZERO);
>           TCGLabel *over = gen_new_label();
>   
>           tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
> @@ -2686,7 +2687,7 @@ static bool trans_vmv_s_x(DisasContext *s, arg_vmv_s_x *a)
>           }
>   
>           t1 = tcg_temp_new_i64();
> -        tcg_gen_extu_tl_i64(t1, cpu_gpr[a->rs1]);
> +        tcg_gen_extu_tl_i64(t1, src1);
>           vec_element_storei(s, a->rd, 0, t1);
>           tcg_temp_free_i64(t1);
>       done:

This isn't actually correct.  Or, may have been correct for the 0.7.1 revision, but the 
rvv 1.0 revision has a sign-extend here.

This probably shouldn't be touched until the rvv 1.0 patch set comes in.


> diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
> index 451688c328..5bdbbf7c71 100644
> --- a/target/riscv/vector_helper.c
> +++ b/target/riscv/vector_helper.c
> @@ -4763,6 +4763,7 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2,         \
>       uint32_t mlen = vext_mlen(desc);                                      \
>       uint32_t vlmax = env_archcpu(env)->cfg.vlen / mlen;                   \
>       uint32_t vm = vext_vm(desc);                                          \
> +    uint32_t olen = 16 << vext_ol(desc);                                  \
>       uint32_t vl = env->vl;                                                \
>       uint32_t i;                                                           \
>                                                                             \
> @@ -4771,7 +4772,7 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2,         \
>               continue;                                                     \
>           }                                                                 \
>           if (i == 0) {                                                     \
> -            *((ETYPE *)vd + H(i)) = s1;                                   \
> +            *((ETYPE *)vd + H(i)) = adjust_addr(s1, olen);                \
>           } else {                                                          \
>               *((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(i - 1));           \
>           }                                                                 \
> @@ -4792,6 +4793,7 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2,         \
>       uint32_t mlen = vext_mlen(desc);                                      \
>       uint32_t vlmax = env_archcpu(env)->cfg.vlen / mlen;                   \
>       uint32_t vm = vext_vm(desc);                                          \
> +    uint32_t olen = 16 << vext_ol(desc);                                  \
>       uint32_t vl = env->vl;                                                \
>       uint32_t i;                                                           \
>                                                                             \
> @@ -4800,7 +4802,7 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2,         \
>               continue;                                                     \
>           }                                                                 \
>           if (i == vl - 1) {                                                \
> -            *((ETYPE *)vd + H(i)) = s1;                                   \
> +            *((ETYPE *)vd + H(i)) = adjust_addr(s1, olen);                \
>           } else {                                                          \
>               *((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(i + 1));           \
>           }                                                                 \

What in the world is this?  S1 is not an address, it's just a value from X[RS1].


r~


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

* Re: [PATCH 11/13] target/riscv: Switch context in exception return
  2021-11-01 10:01   ` LIU Zhiwei
@ 2021-11-01 16:43     ` Richard Henderson
  -1 siblings, 0 replies; 88+ messages in thread
From: Richard Henderson @ 2021-11-01 16:43 UTC (permalink / raw)
  To: LIU Zhiwei, qemu-devel, qemu-riscv; +Cc: palmer, bin.meng, Alistair.Francis

On 11/1/21 6:01 AM, LIU Zhiwei wrote:
> After excpetion return, we should give a xlen view of context in new
> priveledge, including the general registers, pc, and CSRs.
> 
> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
> ---
>   target/riscv/helper.h                         |  1 +
>   .../riscv/insn_trans/trans_privileged.c.inc   |  2 ++
>   target/riscv/op_helper.c                      | 26 +++++++++++++++++++
>   3 files changed, 29 insertions(+)
> 
> diff --git a/target/riscv/helper.h b/target/riscv/helper.h
> index e198d43981..9b379d7232 100644
> --- a/target/riscv/helper.h
> +++ b/target/riscv/helper.h
> @@ -71,6 +71,7 @@ DEF_HELPER_2(sret, tl, env, tl)
>   DEF_HELPER_2(mret, tl, env, tl)
>   DEF_HELPER_1(wfi, void, env)
>   DEF_HELPER_1(tlb_flush, void, env)
> +DEF_HELPER_1(switch_context_xl, void, env)
>   #endif
>   
>   /* Hypervisor functions */
> diff --git a/target/riscv/insn_trans/trans_privileged.c.inc b/target/riscv/insn_trans/trans_privileged.c.inc
> index 75c6ef80a6..6e39632f83 100644
> --- a/target/riscv/insn_trans/trans_privileged.c.inc
> +++ b/target/riscv/insn_trans/trans_privileged.c.inc
> @@ -78,6 +78,7 @@ static bool trans_sret(DisasContext *ctx, arg_sret *a)
>   
>       if (has_ext(ctx, RVS)) {
>           gen_helper_sret(cpu_pc, cpu_env, cpu_pc);
> +        gen_helper_switch_context_xl(cpu_env);
>           tcg_gen_exit_tb(NULL, 0); /* no chaining */
>           ctx->base.is_jmp = DISAS_NORETURN;
>       } else {
> @@ -94,6 +95,7 @@ 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_switch_context_xl(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 ee7c24efe7..20cf8ad883 100644
> --- a/target/riscv/op_helper.c
> +++ b/target/riscv/op_helper.c
> @@ -70,6 +70,32 @@ target_ulong helper_csrrw(CPURISCVState *env, int csr,
>   }
>   
>   #ifndef CONFIG_USER_ONLY
> +void helper_switch_context_xl(CPURISCVState *env)
> +{
> +    RISCVMXL xl = cpu_get_xl(env);
> +    if (xl == env->misa_mxl_max) {
> +        return;
> +    }
> +    assert(xl < env->misa_mxl_max);
> +    switch (xl) {
> +    case MXL_RV32:
> +        for (int i = 1; i < 32; i++) {
> +            env->gpr[i] = (int32_t)env->gpr[i];
> +        }

I think this is wrong.  As I read the spec, the new context ignores high bits and writes 
sign-extended values, but registers that are not written should not be changed.

I think that a unit test with SXLEN == 64 and UXLEN == 32, where the U-mode program 
executes only the ECALL instruction, should leave the high 32 bits of all gprs unchanged 
on re-entry to S-mode.

> +        env->pc = (int32_t)env->pc;

I think this will happen naturally via patch 3.

> +        /*
> +         * For the read-only bits of the previous-width CSR, the bits at the
> +         * same positions in the temporary register are set to zeros.
> +         */
> +        if ((env->priv == PRV_U) && (env->misa_ext & RVV)) {
> +            env->vl = 0;
> +            env->vtype = 0;
> +        }

I don't understand this.  The return from the S-mode interrupt handler to the U-mode 
program should preserve the U-mode VTYPE.


r~


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

* Re: [PATCH 11/13] target/riscv: Switch context in exception return
@ 2021-11-01 16:43     ` Richard Henderson
  0 siblings, 0 replies; 88+ messages in thread
From: Richard Henderson @ 2021-11-01 16:43 UTC (permalink / raw)
  To: LIU Zhiwei, qemu-devel, qemu-riscv; +Cc: Alistair.Francis, palmer, bin.meng

On 11/1/21 6:01 AM, LIU Zhiwei wrote:
> After excpetion return, we should give a xlen view of context in new
> priveledge, including the general registers, pc, and CSRs.
> 
> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
> ---
>   target/riscv/helper.h                         |  1 +
>   .../riscv/insn_trans/trans_privileged.c.inc   |  2 ++
>   target/riscv/op_helper.c                      | 26 +++++++++++++++++++
>   3 files changed, 29 insertions(+)
> 
> diff --git a/target/riscv/helper.h b/target/riscv/helper.h
> index e198d43981..9b379d7232 100644
> --- a/target/riscv/helper.h
> +++ b/target/riscv/helper.h
> @@ -71,6 +71,7 @@ DEF_HELPER_2(sret, tl, env, tl)
>   DEF_HELPER_2(mret, tl, env, tl)
>   DEF_HELPER_1(wfi, void, env)
>   DEF_HELPER_1(tlb_flush, void, env)
> +DEF_HELPER_1(switch_context_xl, void, env)
>   #endif
>   
>   /* Hypervisor functions */
> diff --git a/target/riscv/insn_trans/trans_privileged.c.inc b/target/riscv/insn_trans/trans_privileged.c.inc
> index 75c6ef80a6..6e39632f83 100644
> --- a/target/riscv/insn_trans/trans_privileged.c.inc
> +++ b/target/riscv/insn_trans/trans_privileged.c.inc
> @@ -78,6 +78,7 @@ static bool trans_sret(DisasContext *ctx, arg_sret *a)
>   
>       if (has_ext(ctx, RVS)) {
>           gen_helper_sret(cpu_pc, cpu_env, cpu_pc);
> +        gen_helper_switch_context_xl(cpu_env);
>           tcg_gen_exit_tb(NULL, 0); /* no chaining */
>           ctx->base.is_jmp = DISAS_NORETURN;
>       } else {
> @@ -94,6 +95,7 @@ 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_switch_context_xl(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 ee7c24efe7..20cf8ad883 100644
> --- a/target/riscv/op_helper.c
> +++ b/target/riscv/op_helper.c
> @@ -70,6 +70,32 @@ target_ulong helper_csrrw(CPURISCVState *env, int csr,
>   }
>   
>   #ifndef CONFIG_USER_ONLY
> +void helper_switch_context_xl(CPURISCVState *env)
> +{
> +    RISCVMXL xl = cpu_get_xl(env);
> +    if (xl == env->misa_mxl_max) {
> +        return;
> +    }
> +    assert(xl < env->misa_mxl_max);
> +    switch (xl) {
> +    case MXL_RV32:
> +        for (int i = 1; i < 32; i++) {
> +            env->gpr[i] = (int32_t)env->gpr[i];
> +        }

I think this is wrong.  As I read the spec, the new context ignores high bits and writes 
sign-extended values, but registers that are not written should not be changed.

I think that a unit test with SXLEN == 64 and UXLEN == 32, where the U-mode program 
executes only the ECALL instruction, should leave the high 32 bits of all gprs unchanged 
on re-entry to S-mode.

> +        env->pc = (int32_t)env->pc;

I think this will happen naturally via patch 3.

> +        /*
> +         * For the read-only bits of the previous-width CSR, the bits at the
> +         * same positions in the temporary register are set to zeros.
> +         */
> +        if ((env->priv == PRV_U) && (env->misa_ext & RVV)) {
> +            env->vl = 0;
> +            env->vtype = 0;
> +        }

I don't understand this.  The return from the S-mode interrupt handler to the U-mode 
program should preserve the U-mode VTYPE.


r~


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

* Re: [PATCH 12/13] target/riscv: Don't save pc when exception return
  2021-11-01 10:01   ` LIU Zhiwei
@ 2021-11-01 16:49     ` Richard Henderson
  -1 siblings, 0 replies; 88+ messages in thread
From: Richard Henderson @ 2021-11-01 16:49 UTC (permalink / raw)
  To: LIU Zhiwei, qemu-devel, qemu-riscv; +Cc: palmer, bin.meng, Alistair.Francis

On 11/1/21 6:01 AM, LIU Zhiwei wrote:
> 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>
> ---
>   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(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

r~


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

* Re: [PATCH 12/13] target/riscv: Don't save pc when exception return
@ 2021-11-01 16:49     ` Richard Henderson
  0 siblings, 0 replies; 88+ messages in thread
From: Richard Henderson @ 2021-11-01 16:49 UTC (permalink / raw)
  To: LIU Zhiwei, qemu-devel, qemu-riscv; +Cc: Alistair.Francis, palmer, bin.meng

On 11/1/21 6:01 AM, LIU Zhiwei wrote:
> 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>
> ---
>   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(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

r~


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

* Re: [PATCH 13/13] target/riscv: Enable uxl field write
  2021-11-01 10:01   ` LIU Zhiwei
@ 2021-11-01 17:01     ` Richard Henderson
  -1 siblings, 0 replies; 88+ messages in thread
From: Richard Henderson @ 2021-11-01 17:01 UTC (permalink / raw)
  To: LIU Zhiwei, qemu-devel, qemu-riscv; +Cc: palmer, bin.meng, Alistair.Francis

On 11/1/21 6:01 AM, LIU Zhiwei wrote:
>           mask |= MSTATUS_MPV | MSTATUS_GVA;
> +        if ((val ^ mstatus) & MSTATUS64_UXL) {
> +            mask |= MSTATUS64_UXL;
> +        }

Why do you need the conditional here?
Why is this not just

     mask |= MSTATUS_MPV | MSTATUS_GVA | MSTATUS64_UXL;


>  static bool trans_csrrw(DisasContext *ctx, arg_csrrw *a)
>  {
> -    TCGv src = get_gpr(ctx, a->rs1, EXT_NONE);
> +    TCGv src = get_gpr(ctx, a->rs1, EXT_ZERO);

Hmm.  Not sure about this.

It looks like we should in fact change mask, just a few lines down, at which point the 
extension (or not) for the source would not matter.  And likewise in trans_csrrwi.


r~


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

* Re: [PATCH 13/13] target/riscv: Enable uxl field write
@ 2021-11-01 17:01     ` Richard Henderson
  0 siblings, 0 replies; 88+ messages in thread
From: Richard Henderson @ 2021-11-01 17:01 UTC (permalink / raw)
  To: LIU Zhiwei, qemu-devel, qemu-riscv; +Cc: Alistair.Francis, palmer, bin.meng

On 11/1/21 6:01 AM, LIU Zhiwei wrote:
>           mask |= MSTATUS_MPV | MSTATUS_GVA;
> +        if ((val ^ mstatus) & MSTATUS64_UXL) {
> +            mask |= MSTATUS64_UXL;
> +        }

Why do you need the conditional here?
Why is this not just

     mask |= MSTATUS_MPV | MSTATUS_GVA | MSTATUS64_UXL;


>  static bool trans_csrrw(DisasContext *ctx, arg_csrrw *a)
>  {
> -    TCGv src = get_gpr(ctx, a->rs1, EXT_NONE);
> +    TCGv src = get_gpr(ctx, a->rs1, EXT_ZERO);

Hmm.  Not sure about this.

It looks like we should in fact change mask, just a few lines down, at which point the 
extension (or not) for the source would not matter.  And likewise in trans_csrrwi.


r~


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

* Re: [PATCH 02/13] target/riscv: Extend pc for runtime pc write
  2021-11-01 10:33     ` Richard Henderson
@ 2021-11-02  1:48       ` LIU Zhiwei
  -1 siblings, 0 replies; 88+ messages in thread
From: LIU Zhiwei @ 2021-11-02  1:48 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel, qemu-riscv
  Cc: palmer, bin.meng, Alistair.Francis


On 2021/11/1 下午6:33, Richard Henderson wrote:
> On 11/1/21 6:01 AM, LIU Zhiwei wrote:
>> In some cases, we must restore the guest PC to the address of the 
>> start of
>> the TB, such as when the instruction counter hit zero. So extend pc 
>> register
>> according to current xlen for these cases.
>>
>> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
>> ---
>>   target/riscv/cpu.c        | 20 +++++++++++++++++---
>>   target/riscv/cpu.h        |  2 ++
>>   target/riscv/cpu_helper.c |  2 +-
>>   3 files changed, 20 insertions(+), 4 deletions(-)
>>
>> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
>> index 7d53125dbc..7eefd4f6a6 100644
>> --- a/target/riscv/cpu.c
>> +++ b/target/riscv/cpu.c
>> @@ -319,7 +319,12 @@ static void riscv_cpu_set_pc(CPUState *cs, vaddr 
>> value)
>>   {
>>       RISCVCPU *cpu = RISCV_CPU(cs);
>>       CPURISCVState *env = &cpu->env;
>> -    env->pc = value;
>> +
>> +    if (cpu_get_xl(env) == MXL_RV32) {
>> +        env->pc = (int32_t)value;
>> +    } else {
>> +        env->pc = value;
>> +    }
>>   }
>
> Good.
>
>>   static void riscv_cpu_synchronize_from_tb(CPUState *cs,
>> @@ -327,7 +332,12 @@ static void 
>> riscv_cpu_synchronize_from_tb(CPUState *cs,
>>   {
>>       RISCVCPU *cpu = RISCV_CPU(cs);
>>       CPURISCVState *env = &cpu->env;
>> -    env->pc = tb->pc;
>> +
>> +    if (cpu_get_xl(env) == MXL_RV32) {
>> +        env->pc = (int32_t)tb->pc;
>> +    } else {
>> +        env->pc = tb->pc;
>> +    }
>
> Bad, since TB->PC should be extended properly.
> Though this waits on a change to cpu_get_tb_cpu_state.

Should the env->pc always hold the sign-extend result? In 
cpu_get_tb_cpu_state, we just truncate to the XLEN bits.

Thanks,
Zhiwei

>
>> @@ -348,7 +358,11 @@ static bool riscv_cpu_has_work(CPUState *cs)
>>   void restore_state_to_opc(CPURISCVState *env, TranslationBlock *tb,
>>                             target_ulong *data)
>>   {
>> -    env->pc = data[0];
>> +   if (cpu_get_xl(env) == MXL_RV32) {
>> +        env->pc = (int32_t)data[0];
>> +    } else {
>> +        env->pc = data[0];
>> +    }
>
> Likewise.
>
>
> r~


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

* Re: [PATCH 02/13] target/riscv: Extend pc for runtime pc write
@ 2021-11-02  1:48       ` LIU Zhiwei
  0 siblings, 0 replies; 88+ messages in thread
From: LIU Zhiwei @ 2021-11-02  1:48 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel, qemu-riscv
  Cc: Alistair.Francis, palmer, bin.meng


On 2021/11/1 下午6:33, Richard Henderson wrote:
> On 11/1/21 6:01 AM, LIU Zhiwei wrote:
>> In some cases, we must restore the guest PC to the address of the 
>> start of
>> the TB, such as when the instruction counter hit zero. So extend pc 
>> register
>> according to current xlen for these cases.
>>
>> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
>> ---
>>   target/riscv/cpu.c        | 20 +++++++++++++++++---
>>   target/riscv/cpu.h        |  2 ++
>>   target/riscv/cpu_helper.c |  2 +-
>>   3 files changed, 20 insertions(+), 4 deletions(-)
>>
>> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
>> index 7d53125dbc..7eefd4f6a6 100644
>> --- a/target/riscv/cpu.c
>> +++ b/target/riscv/cpu.c
>> @@ -319,7 +319,12 @@ static void riscv_cpu_set_pc(CPUState *cs, vaddr 
>> value)
>>   {
>>       RISCVCPU *cpu = RISCV_CPU(cs);
>>       CPURISCVState *env = &cpu->env;
>> -    env->pc = value;
>> +
>> +    if (cpu_get_xl(env) == MXL_RV32) {
>> +        env->pc = (int32_t)value;
>> +    } else {
>> +        env->pc = value;
>> +    }
>>   }
>
> Good.
>
>>   static void riscv_cpu_synchronize_from_tb(CPUState *cs,
>> @@ -327,7 +332,12 @@ static void 
>> riscv_cpu_synchronize_from_tb(CPUState *cs,
>>   {
>>       RISCVCPU *cpu = RISCV_CPU(cs);
>>       CPURISCVState *env = &cpu->env;
>> -    env->pc = tb->pc;
>> +
>> +    if (cpu_get_xl(env) == MXL_RV32) {
>> +        env->pc = (int32_t)tb->pc;
>> +    } else {
>> +        env->pc = tb->pc;
>> +    }
>
> Bad, since TB->PC should be extended properly.
> Though this waits on a change to cpu_get_tb_cpu_state.

Should the env->pc always hold the sign-extend result? In 
cpu_get_tb_cpu_state, we just truncate to the XLEN bits.

Thanks,
Zhiwei

>
>> @@ -348,7 +358,11 @@ static bool riscv_cpu_has_work(CPUState *cs)
>>   void restore_state_to_opc(CPURISCVState *env, TranslationBlock *tb,
>>                             target_ulong *data)
>>   {
>> -    env->pc = data[0];
>> +   if (cpu_get_xl(env) == MXL_RV32) {
>> +        env->pc = (int32_t)data[0];
>> +    } else {
>> +        env->pc = data[0];
>> +    }
>
> Likewise.
>
>
> r~


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

* Re: [PATCH 02/13] target/riscv: Extend pc for runtime pc write
  2021-11-02  1:48       ` LIU Zhiwei
@ 2021-11-02 10:18         ` Richard Henderson
  -1 siblings, 0 replies; 88+ messages in thread
From: Richard Henderson @ 2021-11-02 10:18 UTC (permalink / raw)
  To: LIU Zhiwei, qemu-devel, qemu-riscv; +Cc: palmer, bin.meng, Alistair.Francis

On 11/1/21 9:48 PM, LIU Zhiwei wrote:
> 
> On 2021/11/1 下午6:33, Richard Henderson wrote:
>> On 11/1/21 6:01 AM, LIU Zhiwei wrote:
>>> In some cases, we must restore the guest PC to the address of the start of
>>> the TB, such as when the instruction counter hit zero. So extend pc register
>>> according to current xlen for these cases.
>>>
>>> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
>>> ---
>>>   target/riscv/cpu.c        | 20 +++++++++++++++++---
>>>   target/riscv/cpu.h        |  2 ++
>>>   target/riscv/cpu_helper.c |  2 +-
>>>   3 files changed, 20 insertions(+), 4 deletions(-)
>>>
>>> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
>>> index 7d53125dbc..7eefd4f6a6 100644
>>> --- a/target/riscv/cpu.c
>>> +++ b/target/riscv/cpu.c
>>> @@ -319,7 +319,12 @@ static void riscv_cpu_set_pc(CPUState *cs, vaddr value)
>>>   {
>>>       RISCVCPU *cpu = RISCV_CPU(cs);
>>>       CPURISCVState *env = &cpu->env;
>>> -    env->pc = value;
>>> +
>>> +    if (cpu_get_xl(env) == MXL_RV32) {
>>> +        env->pc = (int32_t)value;
>>> +    } else {
>>> +        env->pc = value;
>>> +    }
>>>   }
>>
>> Good.
>>
>>>   static void riscv_cpu_synchronize_from_tb(CPUState *cs,
>>> @@ -327,7 +332,12 @@ static void riscv_cpu_synchronize_from_tb(CPUState *cs,
>>>   {
>>>       RISCVCPU *cpu = RISCV_CPU(cs);
>>>       CPURISCVState *env = &cpu->env;
>>> -    env->pc = tb->pc;
>>> +
>>> +    if (cpu_get_xl(env) == MXL_RV32) {
>>> +        env->pc = (int32_t)tb->pc;
>>> +    } else {
>>> +        env->pc = tb->pc;
>>> +    }
>>
>> Bad, since TB->PC should be extended properly.
>> Though this waits on a change to cpu_get_tb_cpu_state.
> 
> Should the env->pc always hold the sign-extend result? In cpu_get_tb_cpu_state, we just 
> truncate to the XLEN bits.

Oops, I mis-read patch 3; I thought that sign-extended.  Hmm.

I guess we need to zero-extend the pc for patch 3, to get the correct result in translate 
when we read from memory.  Therefore we need to sign-extend here to get the correct value 
back in env->pc.

Oh, let's not re-compute cpu_get_xl here, and restore_state_to_opc; it is in

     FIELD_EX32(tb->flags, TB_FLAGS, XL)


r~


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

* Re: [PATCH 02/13] target/riscv: Extend pc for runtime pc write
@ 2021-11-02 10:18         ` Richard Henderson
  0 siblings, 0 replies; 88+ messages in thread
From: Richard Henderson @ 2021-11-02 10:18 UTC (permalink / raw)
  To: LIU Zhiwei, qemu-devel, qemu-riscv; +Cc: Alistair.Francis, palmer, bin.meng

On 11/1/21 9:48 PM, LIU Zhiwei wrote:
> 
> On 2021/11/1 下午6:33, Richard Henderson wrote:
>> On 11/1/21 6:01 AM, LIU Zhiwei wrote:
>>> In some cases, we must restore the guest PC to the address of the start of
>>> the TB, such as when the instruction counter hit zero. So extend pc register
>>> according to current xlen for these cases.
>>>
>>> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
>>> ---
>>>   target/riscv/cpu.c        | 20 +++++++++++++++++---
>>>   target/riscv/cpu.h        |  2 ++
>>>   target/riscv/cpu_helper.c |  2 +-
>>>   3 files changed, 20 insertions(+), 4 deletions(-)
>>>
>>> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
>>> index 7d53125dbc..7eefd4f6a6 100644
>>> --- a/target/riscv/cpu.c
>>> +++ b/target/riscv/cpu.c
>>> @@ -319,7 +319,12 @@ static void riscv_cpu_set_pc(CPUState *cs, vaddr value)
>>>   {
>>>       RISCVCPU *cpu = RISCV_CPU(cs);
>>>       CPURISCVState *env = &cpu->env;
>>> -    env->pc = value;
>>> +
>>> +    if (cpu_get_xl(env) == MXL_RV32) {
>>> +        env->pc = (int32_t)value;
>>> +    } else {
>>> +        env->pc = value;
>>> +    }
>>>   }
>>
>> Good.
>>
>>>   static void riscv_cpu_synchronize_from_tb(CPUState *cs,
>>> @@ -327,7 +332,12 @@ static void riscv_cpu_synchronize_from_tb(CPUState *cs,
>>>   {
>>>       RISCVCPU *cpu = RISCV_CPU(cs);
>>>       CPURISCVState *env = &cpu->env;
>>> -    env->pc = tb->pc;
>>> +
>>> +    if (cpu_get_xl(env) == MXL_RV32) {
>>> +        env->pc = (int32_t)tb->pc;
>>> +    } else {
>>> +        env->pc = tb->pc;
>>> +    }
>>
>> Bad, since TB->PC should be extended properly.
>> Though this waits on a change to cpu_get_tb_cpu_state.
> 
> Should the env->pc always hold the sign-extend result? In cpu_get_tb_cpu_state, we just 
> truncate to the XLEN bits.

Oops, I mis-read patch 3; I thought that sign-extended.  Hmm.

I guess we need to zero-extend the pc for patch 3, to get the correct result in translate 
when we read from memory.  Therefore we need to sign-extend here to get the correct value 
back in env->pc.

Oh, let's not re-compute cpu_get_xl here, and restore_state_to_opc; it is in

     FIELD_EX32(tb->flags, TB_FLAGS, XL)


r~


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

* Re: [PATCH 03/13] target/riscv: Ignore the pc bits above XLEN
  2021-11-01 10:01   ` LIU Zhiwei
@ 2021-11-02 10:20     ` Richard Henderson
  -1 siblings, 0 replies; 88+ messages in thread
From: Richard Henderson @ 2021-11-02 10:20 UTC (permalink / raw)
  To: LIU Zhiwei, qemu-devel, qemu-riscv; +Cc: palmer, bin.meng, Alistair.Francis

On 11/1/21 6:01 AM, LIU Zhiwei wrote:
> 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>
> ---
>   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 7d0aee6769..eb425d74d2 100644
> --- a/target/riscv/cpu_helper.c
> +++ b/target/riscv/cpu_helper.c
> @@ -71,7 +71,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
>   {
>       uint32_t flags = 0;
>   
> -    *pc = env->pc;
> +    *pc = cpu_get_xl(env) == MXL_RV32 ? env->pc & UINT32_MAX : env->pc;
>       *cs_base = 0;

Oh, let's not compute cpu_get_xl twice -- currently we do it at the end of the function 
when we store into flags.  Move that as necessary.


r~


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

* Re: [PATCH 03/13] target/riscv: Ignore the pc bits above XLEN
@ 2021-11-02 10:20     ` Richard Henderson
  0 siblings, 0 replies; 88+ messages in thread
From: Richard Henderson @ 2021-11-02 10:20 UTC (permalink / raw)
  To: LIU Zhiwei, qemu-devel, qemu-riscv; +Cc: Alistair.Francis, palmer, bin.meng

On 11/1/21 6:01 AM, LIU Zhiwei wrote:
> 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>
> ---
>   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 7d0aee6769..eb425d74d2 100644
> --- a/target/riscv/cpu_helper.c
> +++ b/target/riscv/cpu_helper.c
> @@ -71,7 +71,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
>   {
>       uint32_t flags = 0;
>   
> -    *pc = env->pc;
> +    *pc = cpu_get_xl(env) == MXL_RV32 ? env->pc & UINT32_MAX : env->pc;
>       *cs_base = 0;

Oh, let's not compute cpu_get_xl twice -- currently we do it at the end of the function 
when we store into flags.  Move that as necessary.


r~


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

* Re: [PATCH 09/13] target/riscv: Adjust vector address with ol
  2021-11-01 11:35     ` Richard Henderson
@ 2021-11-08  9:28       ` LIU Zhiwei
  -1 siblings, 0 replies; 88+ messages in thread
From: LIU Zhiwei @ 2021-11-08  9:28 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel, qemu-riscv, Alexey Baturo
  Cc: palmer, bin.meng, Alistair.Francis

On 2021/11/1 下午7:35, Richard Henderson wrote:

> On 11/1/21 6:01 AM, LIU Zhiwei wrote:
>> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
>> ---
>>   target/riscv/insn_trans/trans_rvv.c.inc |  8 ++++
>>   target/riscv/internals.h                |  1 +
>>   target/riscv/vector_helper.c            | 54 +++++++++++++++++--------
>>   3 files changed, 46 insertions(+), 17 deletions(-)
>>
>> diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
>> b/target/riscv/insn_trans/trans_rvv.c.inc
>> index ed042f7bb9..5cd9b802df 100644
>> --- a/target/riscv/insn_trans/trans_rvv.c.inc
>> +++ b/target/riscv/insn_trans/trans_rvv.c.inc
>> @@ -233,6 +233,7 @@ static bool ld_us_op(DisasContext *s, arg_r2nfvm 
>> *a, uint8_t seq)
>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>       return ldst_us_trans(a->rd, a->rs1, data, fn, s);
>>   }
>>   @@ -286,6 +287,7 @@ static bool st_us_op(DisasContext *s, 
>> arg_r2nfvm *a, uint8_t seq)
>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>       return ldst_us_trans(a->rd, a->rs1, data, fn, s);
>>   }
>>   @@ -365,6 +367,7 @@ static bool ld_stride_op(DisasContext *s, 
>> arg_rnfvm *a, uint8_t seq)
>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>       return ldst_stride_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>>   }
>>   @@ -404,6 +407,7 @@ static bool st_stride_op(DisasContext *s, 
>> arg_rnfvm *a, uint8_t seq)
>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>       fn =  fns[seq][s->sew];
>>       if (fn == NULL) {
>>           return false;
>> @@ -490,6 +494,7 @@ static bool ld_index_op(DisasContext *s, 
>> arg_rnfvm *a, uint8_t seq)
>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>       return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>>   }
>>   @@ -542,6 +547,7 @@ static bool st_index_op(DisasContext *s, 
>> arg_rnfvm *a, uint8_t seq)
>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>       return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>>   }
>>   @@ -617,6 +623,7 @@ static bool ldff_op(DisasContext *s, arg_r2nfvm 
>> *a, uint8_t seq)
>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>       return ldff_trans(a->rd, a->rs1, data, fn, s);
>>   }
>>   @@ -724,6 +731,7 @@ static bool amo_op(DisasContext *s, arg_rwdvm 
>> *a, uint8_t seq)
>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>       data = FIELD_DP32(data, VDATA, WD, a->wd);
>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>       return amo_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>>   }
>>   /*
>> diff --git a/target/riscv/internals.h b/target/riscv/internals.h
>> index b15ad394bb..f74b8291e4 100644
>> --- a/target/riscv/internals.h
>> +++ b/target/riscv/internals.h
>> @@ -27,6 +27,7 @@ FIELD(VDATA, VM, 8, 1)
>>   FIELD(VDATA, LMUL, 9, 2)
>>   FIELD(VDATA, NF, 11, 4)
>>   FIELD(VDATA, WD, 11, 1)
>> +FIELD(VDATA, OL, 15, 2)
>>     /* float point classify helpers */
>>   target_ulong fclass_h(uint64_t frs1);
>> diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
>> index 535420ee66..451688c328 100644
>> --- a/target/riscv/vector_helper.c
>> +++ b/target/riscv/vector_helper.c
>> @@ -112,6 +112,11 @@ static uint32_t vext_wd(uint32_t desc)
>>       return (simd_data(desc) >> 11) & 0x1;
>>   }
>>   +static inline uint32_t vext_ol(uint32_t desc)
>> +{
>> +    return FIELD_EX32(simd_data(desc), VDATA, OL);
>> +}
>
> XLEN not OLEN.
OK.
>
>> @@ -123,6 +128,14 @@ static inline uint32_t vext_maxsz(uint32_t desc)
>>       return simd_maxsz(desc) << vext_lmul(desc);
>>   }
>>   +static inline target_ulong adjust_addr(target_ulong addr, uint32_t 
>> olen)
>> +{
>> +    if (olen < TARGET_LONG_BITS) {
>> +        addr &= UINT32_MAX;
>> +    }
>> +    return addr;
>> +}
>
> Here's where I'm unsure.  This looks a lot like the changes that are 
> required to support pointer-masking in vectors, which Alexey said he 
> was going to look at.
>
> (1) Do we need to pass anything in VEXT at all?
>     We do have CPURISCVState, so we could just use cpu_get_ml,
Yes, we should use cpu_get_xl.
> which we would also need for env->mmte etc for pointer masking.

Do you mean env->mpmmask and env->mpmbase? I think yes, we should also 
adjust these register behaviors with xlen.

>
> (2) Do we try to streamline the "normal" case with a simple bit in VEXT
>     that indicates if the address needs modification at all?  I.e. the
>     bit is set if UXLEN < TARGET_LONG_BITS or if PM_ENABLED?
>
> (3) Do we try to streamline the computation by passing down composite
>     mask and base parameters.  This way we don't need to do complex
>     examination of ENV to determine execution mode, and instead always
>     compute
>
>        addr = (addr & mask) | base;
>
>     where mask = -1, base = 0 for "normal" addressing, and when
>     UXLEN == 32, mask <= UINT32_MAX.

Do you mean add env->pmmask and env->pmbase?

I can initialize themin riscv_tr_init_disas_context, such as by 
env->xpmmask & UINT32_MAX .

>
> (4) Do we in fact want to pre-compute these into known slots on ENV,
>     so that we don't have to pass these around as separate parameters?
>     We would adjust these values during PM CSR changes and when
>     changing privilege levels.
>
>
> r~


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

* Re: [PATCH 09/13] target/riscv: Adjust vector address with ol
@ 2021-11-08  9:28       ` LIU Zhiwei
  0 siblings, 0 replies; 88+ messages in thread
From: LIU Zhiwei @ 2021-11-08  9:28 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel, qemu-riscv, Alexey Baturo
  Cc: Alistair.Francis, palmer, bin.meng

On 2021/11/1 下午7:35, Richard Henderson wrote:

> On 11/1/21 6:01 AM, LIU Zhiwei wrote:
>> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
>> ---
>>   target/riscv/insn_trans/trans_rvv.c.inc |  8 ++++
>>   target/riscv/internals.h                |  1 +
>>   target/riscv/vector_helper.c            | 54 +++++++++++++++++--------
>>   3 files changed, 46 insertions(+), 17 deletions(-)
>>
>> diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
>> b/target/riscv/insn_trans/trans_rvv.c.inc
>> index ed042f7bb9..5cd9b802df 100644
>> --- a/target/riscv/insn_trans/trans_rvv.c.inc
>> +++ b/target/riscv/insn_trans/trans_rvv.c.inc
>> @@ -233,6 +233,7 @@ static bool ld_us_op(DisasContext *s, arg_r2nfvm 
>> *a, uint8_t seq)
>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>       return ldst_us_trans(a->rd, a->rs1, data, fn, s);
>>   }
>>   @@ -286,6 +287,7 @@ static bool st_us_op(DisasContext *s, 
>> arg_r2nfvm *a, uint8_t seq)
>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>       return ldst_us_trans(a->rd, a->rs1, data, fn, s);
>>   }
>>   @@ -365,6 +367,7 @@ static bool ld_stride_op(DisasContext *s, 
>> arg_rnfvm *a, uint8_t seq)
>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>       return ldst_stride_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>>   }
>>   @@ -404,6 +407,7 @@ static bool st_stride_op(DisasContext *s, 
>> arg_rnfvm *a, uint8_t seq)
>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>       fn =  fns[seq][s->sew];
>>       if (fn == NULL) {
>>           return false;
>> @@ -490,6 +494,7 @@ static bool ld_index_op(DisasContext *s, 
>> arg_rnfvm *a, uint8_t seq)
>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>       return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>>   }
>>   @@ -542,6 +547,7 @@ static bool st_index_op(DisasContext *s, 
>> arg_rnfvm *a, uint8_t seq)
>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>       return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>>   }
>>   @@ -617,6 +623,7 @@ static bool ldff_op(DisasContext *s, arg_r2nfvm 
>> *a, uint8_t seq)
>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>       return ldff_trans(a->rd, a->rs1, data, fn, s);
>>   }
>>   @@ -724,6 +731,7 @@ static bool amo_op(DisasContext *s, arg_rwdvm 
>> *a, uint8_t seq)
>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>       data = FIELD_DP32(data, VDATA, WD, a->wd);
>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>       return amo_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>>   }
>>   /*
>> diff --git a/target/riscv/internals.h b/target/riscv/internals.h
>> index b15ad394bb..f74b8291e4 100644
>> --- a/target/riscv/internals.h
>> +++ b/target/riscv/internals.h
>> @@ -27,6 +27,7 @@ FIELD(VDATA, VM, 8, 1)
>>   FIELD(VDATA, LMUL, 9, 2)
>>   FIELD(VDATA, NF, 11, 4)
>>   FIELD(VDATA, WD, 11, 1)
>> +FIELD(VDATA, OL, 15, 2)
>>     /* float point classify helpers */
>>   target_ulong fclass_h(uint64_t frs1);
>> diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
>> index 535420ee66..451688c328 100644
>> --- a/target/riscv/vector_helper.c
>> +++ b/target/riscv/vector_helper.c
>> @@ -112,6 +112,11 @@ static uint32_t vext_wd(uint32_t desc)
>>       return (simd_data(desc) >> 11) & 0x1;
>>   }
>>   +static inline uint32_t vext_ol(uint32_t desc)
>> +{
>> +    return FIELD_EX32(simd_data(desc), VDATA, OL);
>> +}
>
> XLEN not OLEN.
OK.
>
>> @@ -123,6 +128,14 @@ static inline uint32_t vext_maxsz(uint32_t desc)
>>       return simd_maxsz(desc) << vext_lmul(desc);
>>   }
>>   +static inline target_ulong adjust_addr(target_ulong addr, uint32_t 
>> olen)
>> +{
>> +    if (olen < TARGET_LONG_BITS) {
>> +        addr &= UINT32_MAX;
>> +    }
>> +    return addr;
>> +}
>
> Here's where I'm unsure.  This looks a lot like the changes that are 
> required to support pointer-masking in vectors, which Alexey said he 
> was going to look at.
>
> (1) Do we need to pass anything in VEXT at all?
>     We do have CPURISCVState, so we could just use cpu_get_ml,
Yes, we should use cpu_get_xl.
> which we would also need for env->mmte etc for pointer masking.

Do you mean env->mpmmask and env->mpmbase? I think yes, we should also 
adjust these register behaviors with xlen.

>
> (2) Do we try to streamline the "normal" case with a simple bit in VEXT
>     that indicates if the address needs modification at all?  I.e. the
>     bit is set if UXLEN < TARGET_LONG_BITS or if PM_ENABLED?
>
> (3) Do we try to streamline the computation by passing down composite
>     mask and base parameters.  This way we don't need to do complex
>     examination of ENV to determine execution mode, and instead always
>     compute
>
>        addr = (addr & mask) | base;
>
>     where mask = -1, base = 0 for "normal" addressing, and when
>     UXLEN == 32, mask <= UINT32_MAX.

Do you mean add env->pmmask and env->pmbase?

I can initialize themin riscv_tr_init_disas_context, such as by 
env->xpmmask & UINT32_MAX .

>
> (4) Do we in fact want to pre-compute these into known slots on ENV,
>     so that we don't have to pass these around as separate parameters?
>     We would adjust these values during PM CSR changes and when
>     changing privilege levels.
>
>
> r~


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

* Re: [PATCH 10/13] target/riscv: Adjust scalar reg in vector with ol
  2021-11-01 16:33     ` Richard Henderson
@ 2021-11-08  9:38       ` LIU Zhiwei
  -1 siblings, 0 replies; 88+ messages in thread
From: LIU Zhiwei @ 2021-11-08  9:38 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel, qemu-riscv
  Cc: palmer, bin.meng, Alistair.Francis


On 2021/11/2 上午12:33, Richard Henderson wrote:
> On 11/1/21 6:01 AM, LIU Zhiwei wrote:
>> @@ -2677,6 +2677,7 @@ static bool trans_vmv_s_x(DisasContext *s, 
>> arg_vmv_s_x *a)
>>           /* This instruction ignores LMUL and vector register groups */
>>           int maxsz = s->vlen >> 3;
>>           TCGv_i64 t1;
>> +        TCGv src1 = get_gpr(s, a->rs1, EXT_ZERO);
>>           TCGLabel *over = gen_new_label();
>>             tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
>> @@ -2686,7 +2687,7 @@ static bool trans_vmv_s_x(DisasContext *s, 
>> arg_vmv_s_x *a)
>>           }
>>             t1 = tcg_temp_new_i64();
>> -        tcg_gen_extu_tl_i64(t1, cpu_gpr[a->rs1]);
>> +        tcg_gen_extu_tl_i64(t1, src1);
>>           vec_element_storei(s, a->rd, 0, t1);
>>           tcg_temp_free_i64(t1);
>>       done:
>
> This isn't actually correct.  Or, may have been correct for the 0.7.1 
> revision,
Yes.
> but the rvv 1.0 revision has a sign-extend here.
>
> This probably shouldn't be touched until the rvv 1.0 patch set comes in.

I try to make all sub extensions upstream are right.

Or we have to make an assert that the uxl32 is not ready for RVV.

>
>
>> diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
>> index 451688c328..5bdbbf7c71 100644
>> --- a/target/riscv/vector_helper.c
>> +++ b/target/riscv/vector_helper.c
>> @@ -4763,6 +4763,7 @@ void HELPER(NAME)(void *vd, void *v0, 
>> target_ulong s1, void *vs2,         \
>>       uint32_t mlen = 
>> vext_mlen(desc);                                      \
>>       uint32_t vlmax = env_archcpu(env)->cfg.vlen / 
>> mlen;                   \
>>       uint32_t vm = 
>> vext_vm(desc);                                          \
>> +    uint32_t olen = 16 << 
>> vext_ol(desc);                                  \
>>       uint32_t vl = 
>> env->vl;                                                \
>>       uint32_t 
>> i;                                                           \
>> \
>> @@ -4771,7 +4772,7 @@ void HELPER(NAME)(void *vd, void *v0, 
>> target_ulong s1, void *vs2,         \
>> continue;                                                     \
>> } \
>>           if (i == 0) 
>> {                                                     \
>> -            *((ETYPE *)vd + H(i)) = 
>> s1;                                   \
>> +            *((ETYPE *)vd + H(i)) = adjust_addr(s1, 
>> olen);                \
>>           } else 
>> {                                                          \
>>               *((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(i - 
>> 1));           \
>> } \
>> @@ -4792,6 +4793,7 @@ void HELPER(NAME)(void *vd, void *v0, 
>> target_ulong s1, void *vs2,         \
>>       uint32_t mlen = 
>> vext_mlen(desc);                                      \
>>       uint32_t vlmax = env_archcpu(env)->cfg.vlen / 
>> mlen;                   \
>>       uint32_t vm = 
>> vext_vm(desc);                                          \
>> +    uint32_t olen = 16 << 
>> vext_ol(desc);                                  \
>>       uint32_t vl = 
>> env->vl;                                                \
>>       uint32_t 
>> i;                                                           \
>> \
>> @@ -4800,7 +4802,7 @@ void HELPER(NAME)(void *vd, void *v0, 
>> target_ulong s1, void *vs2,         \
>> continue;                                                     \
>> } \
>>           if (i == vl - 1) 
>> {                                                \
>> -            *((ETYPE *)vd + H(i)) = 
>> s1;                                   \
>> +            *((ETYPE *)vd + H(i)) = adjust_addr(s1, 
>> olen);                \
>>           } else 
>> {                                                          \
>>               *((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(i + 
>> 1));           \
>> } \
>
> What in the world is this?  S1 is not an address, it's just a value 
> from X[RS1].

It's name is bad. Maybe I should just s1 & UINT32_MAX.

Zhiwei

>
>
>
> r~


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

* Re: [PATCH 10/13] target/riscv: Adjust scalar reg in vector with ol
@ 2021-11-08  9:38       ` LIU Zhiwei
  0 siblings, 0 replies; 88+ messages in thread
From: LIU Zhiwei @ 2021-11-08  9:38 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel, qemu-riscv
  Cc: Alistair.Francis, palmer, bin.meng


On 2021/11/2 上午12:33, Richard Henderson wrote:
> On 11/1/21 6:01 AM, LIU Zhiwei wrote:
>> @@ -2677,6 +2677,7 @@ static bool trans_vmv_s_x(DisasContext *s, 
>> arg_vmv_s_x *a)
>>           /* This instruction ignores LMUL and vector register groups */
>>           int maxsz = s->vlen >> 3;
>>           TCGv_i64 t1;
>> +        TCGv src1 = get_gpr(s, a->rs1, EXT_ZERO);
>>           TCGLabel *over = gen_new_label();
>>             tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
>> @@ -2686,7 +2687,7 @@ static bool trans_vmv_s_x(DisasContext *s, 
>> arg_vmv_s_x *a)
>>           }
>>             t1 = tcg_temp_new_i64();
>> -        tcg_gen_extu_tl_i64(t1, cpu_gpr[a->rs1]);
>> +        tcg_gen_extu_tl_i64(t1, src1);
>>           vec_element_storei(s, a->rd, 0, t1);
>>           tcg_temp_free_i64(t1);
>>       done:
>
> This isn't actually correct.  Or, may have been correct for the 0.7.1 
> revision,
Yes.
> but the rvv 1.0 revision has a sign-extend here.
>
> This probably shouldn't be touched until the rvv 1.0 patch set comes in.

I try to make all sub extensions upstream are right.

Or we have to make an assert that the uxl32 is not ready for RVV.

>
>
>> diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
>> index 451688c328..5bdbbf7c71 100644
>> --- a/target/riscv/vector_helper.c
>> +++ b/target/riscv/vector_helper.c
>> @@ -4763,6 +4763,7 @@ void HELPER(NAME)(void *vd, void *v0, 
>> target_ulong s1, void *vs2,         \
>>       uint32_t mlen = 
>> vext_mlen(desc);                                      \
>>       uint32_t vlmax = env_archcpu(env)->cfg.vlen / 
>> mlen;                   \
>>       uint32_t vm = 
>> vext_vm(desc);                                          \
>> +    uint32_t olen = 16 << 
>> vext_ol(desc);                                  \
>>       uint32_t vl = 
>> env->vl;                                                \
>>       uint32_t 
>> i;                                                           \
>> \
>> @@ -4771,7 +4772,7 @@ void HELPER(NAME)(void *vd, void *v0, 
>> target_ulong s1, void *vs2,         \
>> continue;                                                     \
>> } \
>>           if (i == 0) 
>> {                                                     \
>> -            *((ETYPE *)vd + H(i)) = 
>> s1;                                   \
>> +            *((ETYPE *)vd + H(i)) = adjust_addr(s1, 
>> olen);                \
>>           } else 
>> {                                                          \
>>               *((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(i - 
>> 1));           \
>> } \
>> @@ -4792,6 +4793,7 @@ void HELPER(NAME)(void *vd, void *v0, 
>> target_ulong s1, void *vs2,         \
>>       uint32_t mlen = 
>> vext_mlen(desc);                                      \
>>       uint32_t vlmax = env_archcpu(env)->cfg.vlen / 
>> mlen;                   \
>>       uint32_t vm = 
>> vext_vm(desc);                                          \
>> +    uint32_t olen = 16 << 
>> vext_ol(desc);                                  \
>>       uint32_t vl = 
>> env->vl;                                                \
>>       uint32_t 
>> i;                                                           \
>> \
>> @@ -4800,7 +4802,7 @@ void HELPER(NAME)(void *vd, void *v0, 
>> target_ulong s1, void *vs2,         \
>> continue;                                                     \
>> } \
>>           if (i == vl - 1) 
>> {                                                \
>> -            *((ETYPE *)vd + H(i)) = 
>> s1;                                   \
>> +            *((ETYPE *)vd + H(i)) = adjust_addr(s1, 
>> olen);                \
>>           } else 
>> {                                                          \
>>               *((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(i + 
>> 1));           \
>> } \
>
> What in the world is this?  S1 is not an address, it's just a value 
> from X[RS1].

It's name is bad. Maybe I should just s1 & UINT32_MAX.

Zhiwei

>
>
>
> r~


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

* Re: [PATCH 11/13] target/riscv: Switch context in exception return
  2021-11-01 16:43     ` Richard Henderson
@ 2021-11-08 11:23       ` LIU Zhiwei
  -1 siblings, 0 replies; 88+ messages in thread
From: LIU Zhiwei @ 2021-11-08 11:23 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel, qemu-riscv
  Cc: palmer, bin.meng, Alistair.Francis


On 2021/11/2 上午12:43, Richard Henderson wrote:
> On 11/1/21 6:01 AM, LIU Zhiwei wrote:
>> After excpetion return, we should give a xlen view of context in new
>> priveledge, including the general registers, pc, and CSRs.
>>
>> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
>> ---
>>   target/riscv/helper.h                         |  1 +
>>   .../riscv/insn_trans/trans_privileged.c.inc   |  2 ++
>>   target/riscv/op_helper.c                      | 26 +++++++++++++++++++
>>   3 files changed, 29 insertions(+)
>>
>> diff --git a/target/riscv/helper.h b/target/riscv/helper.h
>> index e198d43981..9b379d7232 100644
>> --- a/target/riscv/helper.h
>> +++ b/target/riscv/helper.h
>> @@ -71,6 +71,7 @@ DEF_HELPER_2(sret, tl, env, tl)
>>   DEF_HELPER_2(mret, tl, env, tl)
>>   DEF_HELPER_1(wfi, void, env)
>>   DEF_HELPER_1(tlb_flush, void, env)
>> +DEF_HELPER_1(switch_context_xl, void, env)
>>   #endif
>>     /* Hypervisor functions */
>> diff --git a/target/riscv/insn_trans/trans_privileged.c.inc 
>> b/target/riscv/insn_trans/trans_privileged.c.inc
>> index 75c6ef80a6..6e39632f83 100644
>> --- a/target/riscv/insn_trans/trans_privileged.c.inc
>> +++ b/target/riscv/insn_trans/trans_privileged.c.inc
>> @@ -78,6 +78,7 @@ static bool trans_sret(DisasContext *ctx, arg_sret *a)
>>         if (has_ext(ctx, RVS)) {
>>           gen_helper_sret(cpu_pc, cpu_env, cpu_pc);
>> +        gen_helper_switch_context_xl(cpu_env);
>>           tcg_gen_exit_tb(NULL, 0); /* no chaining */
>>           ctx->base.is_jmp = DISAS_NORETURN;
>>       } else {
>> @@ -94,6 +95,7 @@ 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_switch_context_xl(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 ee7c24efe7..20cf8ad883 100644
>> --- a/target/riscv/op_helper.c
>> +++ b/target/riscv/op_helper.c
>> @@ -70,6 +70,32 @@ target_ulong helper_csrrw(CPURISCVState *env, int 
>> csr,
>>   }
>>     #ifndef CONFIG_USER_ONLY
>> +void helper_switch_context_xl(CPURISCVState *env)
>> +{
>> +    RISCVMXL xl = cpu_get_xl(env);
>> +    if (xl == env->misa_mxl_max) {
>> +        return;
>> +    }
>> +    assert(xl < env->misa_mxl_max);
>> +    switch (xl) {
>> +    case MXL_RV32:
>> +        for (int i = 1; i < 32; i++) {
>> +            env->gpr[i] = (int32_t)env->gpr[i];
>> +        }
>
> I think this is wrong.  As I read the spec, the new context ignores 
> high bits and writes sign-extended values, but registers that are not 
> written should not be changed.
I think so.
>
> I think that a unit test with SXLEN == 64 and UXLEN == 32, where the 
> U-mode program executes only the ECALL instruction, should leave the 
> high 32 bits of all gprs unchanged on re-entry to S-mode.
Re-entry to U-mode?  I think you are right.  But currently I  don't have 
a hardware has implemented the UXL32.
>
>> +        env->pc = (int32_t)env->pc;
>
> I think this will happen naturally via patch 3.
Maybe we have to sign extend here as clarified in other reply.
>
>> +        /*
>> +         * For the read-only bits of the previous-width CSR, the 
>> bits at the
>> +         * same positions in the temporary register are set to zeros.
>> +         */
>> +        if ((env->priv == PRV_U) && (env->misa_ext & RVV)) {
>> +            env->vl = 0;
>> +            env->vtype = 0;
>> +        }
>
> I don't understand this.  The return from the S-mode interrupt handler 
> to the U-mode program should preserve the U-mode VTYPE.
>
>
According to the privileged architecture specification,  section 2.5,  
if the width of a CSR is changed, the read-only bits of the 
previous-width CSR are zeroed.
More general,  there is an algorithm how to calculate the new CSR value 
from the previous CSR.

I am not sure which is the right time  to do this context switch. The 
write time of  UXL field , or return to the U-mode?


Thanks,
Zhiwei

> r~


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

* Re: [PATCH 11/13] target/riscv: Switch context in exception return
@ 2021-11-08 11:23       ` LIU Zhiwei
  0 siblings, 0 replies; 88+ messages in thread
From: LIU Zhiwei @ 2021-11-08 11:23 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel, qemu-riscv
  Cc: Alistair.Francis, palmer, bin.meng


On 2021/11/2 上午12:43, Richard Henderson wrote:
> On 11/1/21 6:01 AM, LIU Zhiwei wrote:
>> After excpetion return, we should give a xlen view of context in new
>> priveledge, including the general registers, pc, and CSRs.
>>
>> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
>> ---
>>   target/riscv/helper.h                         |  1 +
>>   .../riscv/insn_trans/trans_privileged.c.inc   |  2 ++
>>   target/riscv/op_helper.c                      | 26 +++++++++++++++++++
>>   3 files changed, 29 insertions(+)
>>
>> diff --git a/target/riscv/helper.h b/target/riscv/helper.h
>> index e198d43981..9b379d7232 100644
>> --- a/target/riscv/helper.h
>> +++ b/target/riscv/helper.h
>> @@ -71,6 +71,7 @@ DEF_HELPER_2(sret, tl, env, tl)
>>   DEF_HELPER_2(mret, tl, env, tl)
>>   DEF_HELPER_1(wfi, void, env)
>>   DEF_HELPER_1(tlb_flush, void, env)
>> +DEF_HELPER_1(switch_context_xl, void, env)
>>   #endif
>>     /* Hypervisor functions */
>> diff --git a/target/riscv/insn_trans/trans_privileged.c.inc 
>> b/target/riscv/insn_trans/trans_privileged.c.inc
>> index 75c6ef80a6..6e39632f83 100644
>> --- a/target/riscv/insn_trans/trans_privileged.c.inc
>> +++ b/target/riscv/insn_trans/trans_privileged.c.inc
>> @@ -78,6 +78,7 @@ static bool trans_sret(DisasContext *ctx, arg_sret *a)
>>         if (has_ext(ctx, RVS)) {
>>           gen_helper_sret(cpu_pc, cpu_env, cpu_pc);
>> +        gen_helper_switch_context_xl(cpu_env);
>>           tcg_gen_exit_tb(NULL, 0); /* no chaining */
>>           ctx->base.is_jmp = DISAS_NORETURN;
>>       } else {
>> @@ -94,6 +95,7 @@ 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_switch_context_xl(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 ee7c24efe7..20cf8ad883 100644
>> --- a/target/riscv/op_helper.c
>> +++ b/target/riscv/op_helper.c
>> @@ -70,6 +70,32 @@ target_ulong helper_csrrw(CPURISCVState *env, int 
>> csr,
>>   }
>>     #ifndef CONFIG_USER_ONLY
>> +void helper_switch_context_xl(CPURISCVState *env)
>> +{
>> +    RISCVMXL xl = cpu_get_xl(env);
>> +    if (xl == env->misa_mxl_max) {
>> +        return;
>> +    }
>> +    assert(xl < env->misa_mxl_max);
>> +    switch (xl) {
>> +    case MXL_RV32:
>> +        for (int i = 1; i < 32; i++) {
>> +            env->gpr[i] = (int32_t)env->gpr[i];
>> +        }
>
> I think this is wrong.  As I read the spec, the new context ignores 
> high bits and writes sign-extended values, but registers that are not 
> written should not be changed.
I think so.
>
> I think that a unit test with SXLEN == 64 and UXLEN == 32, where the 
> U-mode program executes only the ECALL instruction, should leave the 
> high 32 bits of all gprs unchanged on re-entry to S-mode.
Re-entry to U-mode?  I think you are right.  But currently I  don't have 
a hardware has implemented the UXL32.
>
>> +        env->pc = (int32_t)env->pc;
>
> I think this will happen naturally via patch 3.
Maybe we have to sign extend here as clarified in other reply.
>
>> +        /*
>> +         * For the read-only bits of the previous-width CSR, the 
>> bits at the
>> +         * same positions in the temporary register are set to zeros.
>> +         */
>> +        if ((env->priv == PRV_U) && (env->misa_ext & RVV)) {
>> +            env->vl = 0;
>> +            env->vtype = 0;
>> +        }
>
> I don't understand this.  The return from the S-mode interrupt handler 
> to the U-mode program should preserve the U-mode VTYPE.
>
>
According to the privileged architecture specification,  section 2.5,  
if the width of a CSR is changed, the read-only bits of the 
previous-width CSR are zeroed.
More general,  there is an algorithm how to calculate the new CSR value 
from the previous CSR.

I am not sure which is the right time  to do this context switch. The 
write time of  UXL field , or return to the U-mode?


Thanks,
Zhiwei

> r~


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

* Re: [PATCH 13/13] target/riscv: Enable uxl field write
  2021-11-01 17:01     ` Richard Henderson
@ 2021-11-08 12:10       ` LIU Zhiwei
  -1 siblings, 0 replies; 88+ messages in thread
From: LIU Zhiwei @ 2021-11-08 12:10 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel, qemu-riscv
  Cc: palmer, bin.meng, Alistair.Francis


On 2021/11/2 上午1:01, Richard Henderson wrote:
> On 11/1/21 6:01 AM, LIU Zhiwei wrote:
>>           mask |= MSTATUS_MPV | MSTATUS_GVA;
>> +        if ((val ^ mstatus) & MSTATUS64_UXL) {
>> +            mask |= MSTATUS64_UXL;
>> +        }
>
> Why do you need the conditional here?
> Why is this not just
>
>     mask |= MSTATUS_MPV | MSTATUS_GVA | MSTATUS64_UXL;
OK
>
>
>>  static bool trans_csrrw(DisasContext *ctx, arg_csrrw *a)
>>  {
>> -    TCGv src = get_gpr(ctx, a->rs1, EXT_NONE);
>> +    TCGv src = get_gpr(ctx, a->rs1, EXT_ZERO);
>
> Hmm.  Not sure about this.
>
> It looks like we should in fact change mask, just a few lines down, at 
> which point the extension (or not) for the source would not matter.  
> And likewise in trans_csrrwi.

It's better to use the mask.

Thanks,
Zhiwei

>
>
> r~


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

* Re: [PATCH 13/13] target/riscv: Enable uxl field write
@ 2021-11-08 12:10       ` LIU Zhiwei
  0 siblings, 0 replies; 88+ messages in thread
From: LIU Zhiwei @ 2021-11-08 12:10 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel, qemu-riscv
  Cc: Alistair.Francis, palmer, bin.meng


On 2021/11/2 上午1:01, Richard Henderson wrote:
> On 11/1/21 6:01 AM, LIU Zhiwei wrote:
>>           mask |= MSTATUS_MPV | MSTATUS_GVA;
>> +        if ((val ^ mstatus) & MSTATUS64_UXL) {
>> +            mask |= MSTATUS64_UXL;
>> +        }
>
> Why do you need the conditional here?
> Why is this not just
>
>     mask |= MSTATUS_MPV | MSTATUS_GVA | MSTATUS64_UXL;
OK
>
>
>>  static bool trans_csrrw(DisasContext *ctx, arg_csrrw *a)
>>  {
>> -    TCGv src = get_gpr(ctx, a->rs1, EXT_NONE);
>> +    TCGv src = get_gpr(ctx, a->rs1, EXT_ZERO);
>
> Hmm.  Not sure about this.
>
> It looks like we should in fact change mask, just a few lines down, at 
> which point the extension (or not) for the source would not matter.  
> And likewise in trans_csrrwi.

It's better to use the mask.

Thanks,
Zhiwei

>
>
> r~


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

* Re: [PATCH 09/13] target/riscv: Adjust vector address with ol
  2021-11-08  9:28       ` LIU Zhiwei
@ 2021-11-09  6:37         ` Richard Henderson
  -1 siblings, 0 replies; 88+ messages in thread
From: Richard Henderson @ 2021-11-09  6:37 UTC (permalink / raw)
  To: LIU Zhiwei, qemu-devel, qemu-riscv, Alexey Baturo
  Cc: palmer, bin.meng, Alistair.Francis

On 11/8/21 10:28 AM, LIU Zhiwei wrote:
> On 2021/11/1 下午7:35, Richard Henderson wrote:
> 
>> On 11/1/21 6:01 AM, LIU Zhiwei wrote:
>>> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
>>> ---
>>>   target/riscv/insn_trans/trans_rvv.c.inc |  8 ++++
>>>   target/riscv/internals.h                |  1 +
>>>   target/riscv/vector_helper.c            | 54 +++++++++++++++++--------
>>>   3 files changed, 46 insertions(+), 17 deletions(-)
>>>
>>> diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
>>> b/target/riscv/insn_trans/trans_rvv.c.inc
>>> index ed042f7bb9..5cd9b802df 100644
>>> --- a/target/riscv/insn_trans/trans_rvv.c.inc
>>> +++ b/target/riscv/insn_trans/trans_rvv.c.inc
>>> @@ -233,6 +233,7 @@ static bool ld_us_op(DisasContext *s, arg_r2nfvm *a, uint8_t seq)
>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>       return ldst_us_trans(a->rd, a->rs1, data, fn, s);
>>>   }
>>>   @@ -286,6 +287,7 @@ static bool st_us_op(DisasContext *s, arg_r2nfvm *a, uint8_t seq)
>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>       return ldst_us_trans(a->rd, a->rs1, data, fn, s);
>>>   }
>>>   @@ -365,6 +367,7 @@ static bool ld_stride_op(DisasContext *s, arg_rnfvm *a, uint8_t seq)
>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>       return ldst_stride_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>>>   }
>>>   @@ -404,6 +407,7 @@ static bool st_stride_op(DisasContext *s, arg_rnfvm *a, uint8_t seq)
>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>       fn =  fns[seq][s->sew];
>>>       if (fn == NULL) {
>>>           return false;
>>> @@ -490,6 +494,7 @@ static bool ld_index_op(DisasContext *s, arg_rnfvm *a, uint8_t seq)
>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>       return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>>>   }
>>>   @@ -542,6 +547,7 @@ static bool st_index_op(DisasContext *s, arg_rnfvm *a, uint8_t seq)
>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>       return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>>>   }
>>>   @@ -617,6 +623,7 @@ static bool ldff_op(DisasContext *s, arg_r2nfvm *a, uint8_t seq)
>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>       return ldff_trans(a->rd, a->rs1, data, fn, s);
>>>   }
>>>   @@ -724,6 +731,7 @@ static bool amo_op(DisasContext *s, arg_rwdvm *a, uint8_t seq)
>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>       data = FIELD_DP32(data, VDATA, WD, a->wd);
>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>       return amo_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>>>   }
>>>   /*
>>> diff --git a/target/riscv/internals.h b/target/riscv/internals.h
>>> index b15ad394bb..f74b8291e4 100644
>>> --- a/target/riscv/internals.h
>>> +++ b/target/riscv/internals.h
>>> @@ -27,6 +27,7 @@ FIELD(VDATA, VM, 8, 1)
>>>   FIELD(VDATA, LMUL, 9, 2)
>>>   FIELD(VDATA, NF, 11, 4)
>>>   FIELD(VDATA, WD, 11, 1)
>>> +FIELD(VDATA, OL, 15, 2)
>>>     /* float point classify helpers */
>>>   target_ulong fclass_h(uint64_t frs1);
>>> diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
>>> index 535420ee66..451688c328 100644
>>> --- a/target/riscv/vector_helper.c
>>> +++ b/target/riscv/vector_helper.c
>>> @@ -112,6 +112,11 @@ static uint32_t vext_wd(uint32_t desc)
>>>       return (simd_data(desc) >> 11) & 0x1;
>>>   }
>>>   +static inline uint32_t vext_ol(uint32_t desc)
>>> +{
>>> +    return FIELD_EX32(simd_data(desc), VDATA, OL);
>>> +}
>>
>> XLEN not OLEN.
> OK.
>>
>>> @@ -123,6 +128,14 @@ static inline uint32_t vext_maxsz(uint32_t desc)
>>>       return simd_maxsz(desc) << vext_lmul(desc);
>>>   }
>>>   +static inline target_ulong adjust_addr(target_ulong addr, uint32_t olen)
>>> +{
>>> +    if (olen < TARGET_LONG_BITS) {
>>> +        addr &= UINT32_MAX;
>>> +    }
>>> +    return addr;
>>> +}
>>
>> Here's where I'm unsure.  This looks a lot like the changes that are required to support 
>> pointer-masking in vectors, which Alexey said he was going to look at.
>>
>> (1) Do we need to pass anything in VEXT at all?
>>     We do have CPURISCVState, so we could just use cpu_get_ml,
> Yes, we should use cpu_get_xl.
>> which we would also need for env->mmte etc for pointer masking.
> 
> Do you mean env->mpmmask and env->mpmbase? I think yes, we should also adjust these 
> register behaviors with xlen.

I mean the set of [msu]pmmask and [msu]pmbase, selected as appropriate for the current 
execution mode.

>> (3) Do we try to streamline the computation by passing down composite
>>     mask and base parameters.  This way we don't need to do complex
>>     examination of ENV to determine execution mode, and instead always
>>     compute
>>
>>        addr = (addr & mask) | base;
>>
>>     where mask = -1, base = 0 for "normal" addressing, and when
>>     UXLEN == 32, mask <= UINT32_MAX.
> 
> Do you mean add env->pmmask and env->pmbase?
> 
> I can initialize them in riscv_tr_init_disas_context, such as by env->xpmmask & UINT32_MAX .
> 
>>
>> (4) Do we in fact want to pre-compute these into known slots on ENV,
>>     so that we don't have to pass these around as separate parameters?
>>     We would adjust these values during PM CSR changes and when
>>     changing privilege levels.
For option (3), I was suggesting a mask + base pair passed down from TCG-generated code.

For option (4), I was suggesting embedding a mask + base pair in env, which would be 
re-computed at every privilege level change, plus reset and vmload.

In both cases, the mask would be a combination of [msu]pmmask & (RV32 ? UINT32_MAX : 
UINT64_MAX), as you say.


r~


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

* Re: [PATCH 09/13] target/riscv: Adjust vector address with ol
@ 2021-11-09  6:37         ` Richard Henderson
  0 siblings, 0 replies; 88+ messages in thread
From: Richard Henderson @ 2021-11-09  6:37 UTC (permalink / raw)
  To: LIU Zhiwei, qemu-devel, qemu-riscv, Alexey Baturo
  Cc: Alistair.Francis, palmer, bin.meng

On 11/8/21 10:28 AM, LIU Zhiwei wrote:
> On 2021/11/1 下午7:35, Richard Henderson wrote:
> 
>> On 11/1/21 6:01 AM, LIU Zhiwei wrote:
>>> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
>>> ---
>>>   target/riscv/insn_trans/trans_rvv.c.inc |  8 ++++
>>>   target/riscv/internals.h                |  1 +
>>>   target/riscv/vector_helper.c            | 54 +++++++++++++++++--------
>>>   3 files changed, 46 insertions(+), 17 deletions(-)
>>>
>>> diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
>>> b/target/riscv/insn_trans/trans_rvv.c.inc
>>> index ed042f7bb9..5cd9b802df 100644
>>> --- a/target/riscv/insn_trans/trans_rvv.c.inc
>>> +++ b/target/riscv/insn_trans/trans_rvv.c.inc
>>> @@ -233,6 +233,7 @@ static bool ld_us_op(DisasContext *s, arg_r2nfvm *a, uint8_t seq)
>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>       return ldst_us_trans(a->rd, a->rs1, data, fn, s);
>>>   }
>>>   @@ -286,6 +287,7 @@ static bool st_us_op(DisasContext *s, arg_r2nfvm *a, uint8_t seq)
>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>       return ldst_us_trans(a->rd, a->rs1, data, fn, s);
>>>   }
>>>   @@ -365,6 +367,7 @@ static bool ld_stride_op(DisasContext *s, arg_rnfvm *a, uint8_t seq)
>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>       return ldst_stride_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>>>   }
>>>   @@ -404,6 +407,7 @@ static bool st_stride_op(DisasContext *s, arg_rnfvm *a, uint8_t seq)
>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>       fn =  fns[seq][s->sew];
>>>       if (fn == NULL) {
>>>           return false;
>>> @@ -490,6 +494,7 @@ static bool ld_index_op(DisasContext *s, arg_rnfvm *a, uint8_t seq)
>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>       return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>>>   }
>>>   @@ -542,6 +547,7 @@ static bool st_index_op(DisasContext *s, arg_rnfvm *a, uint8_t seq)
>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>       return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>>>   }
>>>   @@ -617,6 +623,7 @@ static bool ldff_op(DisasContext *s, arg_r2nfvm *a, uint8_t seq)
>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>       return ldff_trans(a->rd, a->rs1, data, fn, s);
>>>   }
>>>   @@ -724,6 +731,7 @@ static bool amo_op(DisasContext *s, arg_rwdvm *a, uint8_t seq)
>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>       data = FIELD_DP32(data, VDATA, WD, a->wd);
>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>       return amo_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>>>   }
>>>   /*
>>> diff --git a/target/riscv/internals.h b/target/riscv/internals.h
>>> index b15ad394bb..f74b8291e4 100644
>>> --- a/target/riscv/internals.h
>>> +++ b/target/riscv/internals.h
>>> @@ -27,6 +27,7 @@ FIELD(VDATA, VM, 8, 1)
>>>   FIELD(VDATA, LMUL, 9, 2)
>>>   FIELD(VDATA, NF, 11, 4)
>>>   FIELD(VDATA, WD, 11, 1)
>>> +FIELD(VDATA, OL, 15, 2)
>>>     /* float point classify helpers */
>>>   target_ulong fclass_h(uint64_t frs1);
>>> diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
>>> index 535420ee66..451688c328 100644
>>> --- a/target/riscv/vector_helper.c
>>> +++ b/target/riscv/vector_helper.c
>>> @@ -112,6 +112,11 @@ static uint32_t vext_wd(uint32_t desc)
>>>       return (simd_data(desc) >> 11) & 0x1;
>>>   }
>>>   +static inline uint32_t vext_ol(uint32_t desc)
>>> +{
>>> +    return FIELD_EX32(simd_data(desc), VDATA, OL);
>>> +}
>>
>> XLEN not OLEN.
> OK.
>>
>>> @@ -123,6 +128,14 @@ static inline uint32_t vext_maxsz(uint32_t desc)
>>>       return simd_maxsz(desc) << vext_lmul(desc);
>>>   }
>>>   +static inline target_ulong adjust_addr(target_ulong addr, uint32_t olen)
>>> +{
>>> +    if (olen < TARGET_LONG_BITS) {
>>> +        addr &= UINT32_MAX;
>>> +    }
>>> +    return addr;
>>> +}
>>
>> Here's where I'm unsure.  This looks a lot like the changes that are required to support 
>> pointer-masking in vectors, which Alexey said he was going to look at.
>>
>> (1) Do we need to pass anything in VEXT at all?
>>     We do have CPURISCVState, so we could just use cpu_get_ml,
> Yes, we should use cpu_get_xl.
>> which we would also need for env->mmte etc for pointer masking.
> 
> Do you mean env->mpmmask and env->mpmbase? I think yes, we should also adjust these 
> register behaviors with xlen.

I mean the set of [msu]pmmask and [msu]pmbase, selected as appropriate for the current 
execution mode.

>> (3) Do we try to streamline the computation by passing down composite
>>     mask and base parameters.  This way we don't need to do complex
>>     examination of ENV to determine execution mode, and instead always
>>     compute
>>
>>        addr = (addr & mask) | base;
>>
>>     where mask = -1, base = 0 for "normal" addressing, and when
>>     UXLEN == 32, mask <= UINT32_MAX.
> 
> Do you mean add env->pmmask and env->pmbase?
> 
> I can initialize them in riscv_tr_init_disas_context, such as by env->xpmmask & UINT32_MAX .
> 
>>
>> (4) Do we in fact want to pre-compute these into known slots on ENV,
>>     so that we don't have to pass these around as separate parameters?
>>     We would adjust these values during PM CSR changes and when
>>     changing privilege levels.
For option (3), I was suggesting a mask + base pair passed down from TCG-generated code.

For option (4), I was suggesting embedding a mask + base pair in env, which would be 
re-computed at every privilege level change, plus reset and vmload.

In both cases, the mask would be a combination of [msu]pmmask & (RV32 ? UINT32_MAX : 
UINT64_MAX), as you say.


r~


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

* Re: [PATCH 11/13] target/riscv: Switch context in exception return
  2021-11-08 11:23       ` LIU Zhiwei
@ 2021-11-09  6:38         ` LIU Zhiwei
  -1 siblings, 0 replies; 88+ messages in thread
From: LIU Zhiwei @ 2021-11-09  6:38 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel, qemu-riscv
  Cc: Alistair.Francis, bin.meng, palmer

We only have to process the special CSRs(like vtype/misa) when xlen 
changes,  according to the explicitly  specified behavior about the CSR 
width change behavior.
For normal CSRs, the default behavior in section 2.4 , CSR Width 
Modulation, is enough.

And if we split the vill out, we will never need this patch. So I will 
remove it next patch set.

Thanks,
Zhiwei

On 2021/11/8 下午7:23, LIU Zhiwei wrote:
>
> On 2021/11/2 上午12:43, Richard Henderson wrote:
>> On 11/1/21 6:01 AM, LIU Zhiwei wrote:
>>> After excpetion return, we should give a xlen view of context in new
>>> priveledge, including the general registers, pc, and CSRs.
>>>
>>> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
>>> ---
>>>   target/riscv/helper.h                         |  1 +
>>>   .../riscv/insn_trans/trans_privileged.c.inc   |  2 ++
>>>   target/riscv/op_helper.c                      | 26 
>>> +++++++++++++++++++
>>>   3 files changed, 29 insertions(+)
>>>
>>> diff --git a/target/riscv/helper.h b/target/riscv/helper.h
>>> index e198d43981..9b379d7232 100644
>>> --- a/target/riscv/helper.h
>>> +++ b/target/riscv/helper.h
>>> @@ -71,6 +71,7 @@ DEF_HELPER_2(sret, tl, env, tl)
>>>   DEF_HELPER_2(mret, tl, env, tl)
>>>   DEF_HELPER_1(wfi, void, env)
>>>   DEF_HELPER_1(tlb_flush, void, env)
>>> +DEF_HELPER_1(switch_context_xl, void, env)
>>>   #endif
>>>     /* Hypervisor functions */
>>> diff --git a/target/riscv/insn_trans/trans_privileged.c.inc 
>>> b/target/riscv/insn_trans/trans_privileged.c.inc
>>> index 75c6ef80a6..6e39632f83 100644
>>> --- a/target/riscv/insn_trans/trans_privileged.c.inc
>>> +++ b/target/riscv/insn_trans/trans_privileged.c.inc
>>> @@ -78,6 +78,7 @@ static bool trans_sret(DisasContext *ctx, arg_sret 
>>> *a)
>>>         if (has_ext(ctx, RVS)) {
>>>           gen_helper_sret(cpu_pc, cpu_env, cpu_pc);
>>> +        gen_helper_switch_context_xl(cpu_env);
>>>           tcg_gen_exit_tb(NULL, 0); /* no chaining */
>>>           ctx->base.is_jmp = DISAS_NORETURN;
>>>       } else {
>>> @@ -94,6 +95,7 @@ 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_switch_context_xl(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 ee7c24efe7..20cf8ad883 100644
>>> --- a/target/riscv/op_helper.c
>>> +++ b/target/riscv/op_helper.c
>>> @@ -70,6 +70,32 @@ target_ulong helper_csrrw(CPURISCVState *env, int 
>>> csr,
>>>   }
>>>     #ifndef CONFIG_USER_ONLY
>>> +void helper_switch_context_xl(CPURISCVState *env)
>>> +{
>>> +    RISCVMXL xl = cpu_get_xl(env);
>>> +    if (xl == env->misa_mxl_max) {
>>> +        return;
>>> +    }
>>> +    assert(xl < env->misa_mxl_max);
>>> +    switch (xl) {
>>> +    case MXL_RV32:
>>> +        for (int i = 1; i < 32; i++) {
>>> +            env->gpr[i] = (int32_t)env->gpr[i];
>>> +        }
>>
>> I think this is wrong.  As I read the spec, the new context ignores 
>> high bits and writes sign-extended values, but registers that are not 
>> written should not be changed.
> I think so.
>>
>> I think that a unit test with SXLEN == 64 and UXLEN == 32, where the 
>> U-mode program executes only the ECALL instruction, should leave the 
>> high 32 bits of all gprs unchanged on re-entry to S-mode.
> Re-entry to U-mode?  I think you are right.  But currently I don't 
> have a hardware has implemented the UXL32.
>>
>>> +        env->pc = (int32_t)env->pc;
>>
>> I think this will happen naturally via patch 3.
> Maybe we have to sign extend here as clarified in other reply.
>>
>>> +        /*
>>> +         * For the read-only bits of the previous-width CSR, the 
>>> bits at the
>>> +         * same positions in the temporary register are set to zeros.
>>> +         */
>>> +        if ((env->priv == PRV_U) && (env->misa_ext & RVV)) {
>>> +            env->vl = 0;
>>> +            env->vtype = 0;
>>> +        }
>>
>> I don't understand this.  The return from the S-mode interrupt 
>> handler to the U-mode program should preserve the U-mode VTYPE.
>>
>>
> According to the privileged architecture specification,  section 2.5,  
> if the width of a CSR is changed, the read-only bits of the 
> previous-width CSR are zeroed.
> More general,  there is an algorithm how to calculate the new CSR 
> value from the previous CSR.
>
> I am not sure which is the right time  to do this context switch. The 
> write time of  UXL field , or return to the U-mode?
>
>
> Thanks,
> Zhiwei
>
>> r~
>


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

* Re: [PATCH 11/13] target/riscv: Switch context in exception return
@ 2021-11-09  6:38         ` LIU Zhiwei
  0 siblings, 0 replies; 88+ messages in thread
From: LIU Zhiwei @ 2021-11-09  6:38 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel, qemu-riscv
  Cc: palmer, bin.meng, Alistair.Francis

We only have to process the special CSRs(like vtype/misa) when xlen 
changes,  according to the explicitly  specified behavior about the CSR 
width change behavior.
For normal CSRs, the default behavior in section 2.4 , CSR Width 
Modulation, is enough.

And if we split the vill out, we will never need this patch. So I will 
remove it next patch set.

Thanks,
Zhiwei

On 2021/11/8 下午7:23, LIU Zhiwei wrote:
>
> On 2021/11/2 上午12:43, Richard Henderson wrote:
>> On 11/1/21 6:01 AM, LIU Zhiwei wrote:
>>> After excpetion return, we should give a xlen view of context in new
>>> priveledge, including the general registers, pc, and CSRs.
>>>
>>> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
>>> ---
>>>   target/riscv/helper.h                         |  1 +
>>>   .../riscv/insn_trans/trans_privileged.c.inc   |  2 ++
>>>   target/riscv/op_helper.c                      | 26 
>>> +++++++++++++++++++
>>>   3 files changed, 29 insertions(+)
>>>
>>> diff --git a/target/riscv/helper.h b/target/riscv/helper.h
>>> index e198d43981..9b379d7232 100644
>>> --- a/target/riscv/helper.h
>>> +++ b/target/riscv/helper.h
>>> @@ -71,6 +71,7 @@ DEF_HELPER_2(sret, tl, env, tl)
>>>   DEF_HELPER_2(mret, tl, env, tl)
>>>   DEF_HELPER_1(wfi, void, env)
>>>   DEF_HELPER_1(tlb_flush, void, env)
>>> +DEF_HELPER_1(switch_context_xl, void, env)
>>>   #endif
>>>     /* Hypervisor functions */
>>> diff --git a/target/riscv/insn_trans/trans_privileged.c.inc 
>>> b/target/riscv/insn_trans/trans_privileged.c.inc
>>> index 75c6ef80a6..6e39632f83 100644
>>> --- a/target/riscv/insn_trans/trans_privileged.c.inc
>>> +++ b/target/riscv/insn_trans/trans_privileged.c.inc
>>> @@ -78,6 +78,7 @@ static bool trans_sret(DisasContext *ctx, arg_sret 
>>> *a)
>>>         if (has_ext(ctx, RVS)) {
>>>           gen_helper_sret(cpu_pc, cpu_env, cpu_pc);
>>> +        gen_helper_switch_context_xl(cpu_env);
>>>           tcg_gen_exit_tb(NULL, 0); /* no chaining */
>>>           ctx->base.is_jmp = DISAS_NORETURN;
>>>       } else {
>>> @@ -94,6 +95,7 @@ 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_switch_context_xl(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 ee7c24efe7..20cf8ad883 100644
>>> --- a/target/riscv/op_helper.c
>>> +++ b/target/riscv/op_helper.c
>>> @@ -70,6 +70,32 @@ target_ulong helper_csrrw(CPURISCVState *env, int 
>>> csr,
>>>   }
>>>     #ifndef CONFIG_USER_ONLY
>>> +void helper_switch_context_xl(CPURISCVState *env)
>>> +{
>>> +    RISCVMXL xl = cpu_get_xl(env);
>>> +    if (xl == env->misa_mxl_max) {
>>> +        return;
>>> +    }
>>> +    assert(xl < env->misa_mxl_max);
>>> +    switch (xl) {
>>> +    case MXL_RV32:
>>> +        for (int i = 1; i < 32; i++) {
>>> +            env->gpr[i] = (int32_t)env->gpr[i];
>>> +        }
>>
>> I think this is wrong.  As I read the spec, the new context ignores 
>> high bits and writes sign-extended values, but registers that are not 
>> written should not be changed.
> I think so.
>>
>> I think that a unit test with SXLEN == 64 and UXLEN == 32, where the 
>> U-mode program executes only the ECALL instruction, should leave the 
>> high 32 bits of all gprs unchanged on re-entry to S-mode.
> Re-entry to U-mode?  I think you are right.  But currently I don't 
> have a hardware has implemented the UXL32.
>>
>>> +        env->pc = (int32_t)env->pc;
>>
>> I think this will happen naturally via patch 3.
> Maybe we have to sign extend here as clarified in other reply.
>>
>>> +        /*
>>> +         * For the read-only bits of the previous-width CSR, the 
>>> bits at the
>>> +         * same positions in the temporary register are set to zeros.
>>> +         */
>>> +        if ((env->priv == PRV_U) && (env->misa_ext & RVV)) {
>>> +            env->vl = 0;
>>> +            env->vtype = 0;
>>> +        }
>>
>> I don't understand this.  The return from the S-mode interrupt 
>> handler to the U-mode program should preserve the U-mode VTYPE.
>>
>>
> According to the privileged architecture specification,  section 2.5,  
> if the width of a CSR is changed, the read-only bits of the 
> previous-width CSR are zeroed.
> More general,  there is an algorithm how to calculate the new CSR 
> value from the previous CSR.
>
> I am not sure which is the right time  to do this context switch. The 
> write time of  UXL field , or return to the U-mode?
>
>
> Thanks,
> Zhiwei
>
>> r~
>


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

* Re: [PATCH 11/13] target/riscv: Switch context in exception return
  2021-11-08 11:23       ` LIU Zhiwei
@ 2021-11-09  6:51         ` LIU Zhiwei
  -1 siblings, 0 replies; 88+ messages in thread
From: LIU Zhiwei @ 2021-11-09  6:51 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel, qemu-riscv
  Cc: Alistair.Francis, bin.meng, palmer

We only have to process the special CSRs(like vtype/misa) when xlen 
changes,  according to the explicitly  specified behavior about the CSR 
width change behavior.
For normal CSRs, the default behavior in section 2.4 , CSR Width 
Modulation, is enough.

And if we split the vill out, we will never need this patch. So I will 
remove it next patch set.

Thanks,
Zhiwei

On 2021/11/8 下午7:23, LIU Zhiwei wrote:
>
> On 2021/11/2 上午12:43, Richard Henderson wrote:
>> On 11/1/21 6:01 AM, LIU Zhiwei wrote:
>>> After excpetion return, we should give a xlen view of context in new
>>> priveledge, including the general registers, pc, and CSRs.
>>>
>>> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
>>> ---
>>>   target/riscv/helper.h                         |  1 +
>>>   .../riscv/insn_trans/trans_privileged.c.inc   |  2 ++
>>>   target/riscv/op_helper.c                      | 26 
>>> +++++++++++++++++++
>>>   3 files changed, 29 insertions(+)
>>>
>>> diff --git a/target/riscv/helper.h b/target/riscv/helper.h
>>> index e198d43981..9b379d7232 100644
>>> --- a/target/riscv/helper.h
>>> +++ b/target/riscv/helper.h
>>> @@ -71,6 +71,7 @@ DEF_HELPER_2(sret, tl, env, tl)
>>>   DEF_HELPER_2(mret, tl, env, tl)
>>>   DEF_HELPER_1(wfi, void, env)
>>>   DEF_HELPER_1(tlb_flush, void, env)
>>> +DEF_HELPER_1(switch_context_xl, void, env)
>>>   #endif
>>>     /* Hypervisor functions */
>>> diff --git a/target/riscv/insn_trans/trans_privileged.c.inc 
>>> b/target/riscv/insn_trans/trans_privileged.c.inc
>>> index 75c6ef80a6..6e39632f83 100644
>>> --- a/target/riscv/insn_trans/trans_privileged.c.inc
>>> +++ b/target/riscv/insn_trans/trans_privileged.c.inc
>>> @@ -78,6 +78,7 @@ static bool trans_sret(DisasContext *ctx, arg_sret 
>>> *a)
>>>         if (has_ext(ctx, RVS)) {
>>>           gen_helper_sret(cpu_pc, cpu_env, cpu_pc);
>>> +        gen_helper_switch_context_xl(cpu_env);
>>>           tcg_gen_exit_tb(NULL, 0); /* no chaining */
>>>           ctx->base.is_jmp = DISAS_NORETURN;
>>>       } else {
>>> @@ -94,6 +95,7 @@ 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_switch_context_xl(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 ee7c24efe7..20cf8ad883 100644
>>> --- a/target/riscv/op_helper.c
>>> +++ b/target/riscv/op_helper.c
>>> @@ -70,6 +70,32 @@ target_ulong helper_csrrw(CPURISCVState *env, int 
>>> csr,
>>>   }
>>>     #ifndef CONFIG_USER_ONLY
>>> +void helper_switch_context_xl(CPURISCVState *env)
>>> +{
>>> +    RISCVMXL xl = cpu_get_xl(env);
>>> +    if (xl == env->misa_mxl_max) {
>>> +        return;
>>> +    }
>>> +    assert(xl < env->misa_mxl_max);
>>> +    switch (xl) {
>>> +    case MXL_RV32:
>>> +        for (int i = 1; i < 32; i++) {
>>> +            env->gpr[i] = (int32_t)env->gpr[i];
>>> +        }
>>
>> I think this is wrong.  As I read the spec, the new context ignores 
>> high bits and writes sign-extended values, but registers that are not 
>> written should not be changed.
> I think so.
>>
>> I think that a unit test with SXLEN == 64 and UXLEN == 32, where the 
>> U-mode program executes only the ECALL instruction, should leave the 
>> high 32 bits of all gprs unchanged on re-entry to S-mode.
> Re-entry to U-mode?  I think you are right.  But currently I don't 
> have a hardware has implemented the UXL32.
>>
>>> +        env->pc = (int32_t)env->pc;
>>
>> I think this will happen naturally via patch 3.
> Maybe we have to sign extend here as clarified in other reply.
>>
>>> +        /*
>>> +         * For the read-only bits of the previous-width CSR, the 
>>> bits at the
>>> +         * same positions in the temporary register are set to zeros.
>>> +         */
>>> +        if ((env->priv == PRV_U) && (env->misa_ext & RVV)) {
>>> +            env->vl = 0;
>>> +            env->vtype = 0;
>>> +        }
>>
>> I don't understand this.  The return from the S-mode interrupt 
>> handler to the U-mode program should preserve the U-mode VTYPE.
>>
>>
> According to the privileged architecture specification,  section 2.5,  
> if the width of a CSR is changed, the read-only bits of the 
> previous-width CSR are zeroed.
> More general,  there is an algorithm how to calculate the new CSR 
> value from the previous CSR.
>
> I am not sure which is the right time  to do this context switch. The 
> write time of  UXL field , or return to the U-mode?
>
>
> Thanks,
> Zhiwei
>
>> r~
>


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

* Re: [PATCH 11/13] target/riscv: Switch context in exception return
@ 2021-11-09  6:51         ` LIU Zhiwei
  0 siblings, 0 replies; 88+ messages in thread
From: LIU Zhiwei @ 2021-11-09  6:51 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel, qemu-riscv
  Cc: palmer, bin.meng, Alistair.Francis

We only have to process the special CSRs(like vtype/misa) when xlen 
changes,  according to the explicitly  specified behavior about the CSR 
width change behavior.
For normal CSRs, the default behavior in section 2.4 , CSR Width 
Modulation, is enough.

And if we split the vill out, we will never need this patch. So I will 
remove it next patch set.

Thanks,
Zhiwei

On 2021/11/8 下午7:23, LIU Zhiwei wrote:
>
> On 2021/11/2 上午12:43, Richard Henderson wrote:
>> On 11/1/21 6:01 AM, LIU Zhiwei wrote:
>>> After excpetion return, we should give a xlen view of context in new
>>> priveledge, including the general registers, pc, and CSRs.
>>>
>>> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
>>> ---
>>>   target/riscv/helper.h                         |  1 +
>>>   .../riscv/insn_trans/trans_privileged.c.inc   |  2 ++
>>>   target/riscv/op_helper.c                      | 26 
>>> +++++++++++++++++++
>>>   3 files changed, 29 insertions(+)
>>>
>>> diff --git a/target/riscv/helper.h b/target/riscv/helper.h
>>> index e198d43981..9b379d7232 100644
>>> --- a/target/riscv/helper.h
>>> +++ b/target/riscv/helper.h
>>> @@ -71,6 +71,7 @@ DEF_HELPER_2(sret, tl, env, tl)
>>>   DEF_HELPER_2(mret, tl, env, tl)
>>>   DEF_HELPER_1(wfi, void, env)
>>>   DEF_HELPER_1(tlb_flush, void, env)
>>> +DEF_HELPER_1(switch_context_xl, void, env)
>>>   #endif
>>>     /* Hypervisor functions */
>>> diff --git a/target/riscv/insn_trans/trans_privileged.c.inc 
>>> b/target/riscv/insn_trans/trans_privileged.c.inc
>>> index 75c6ef80a6..6e39632f83 100644
>>> --- a/target/riscv/insn_trans/trans_privileged.c.inc
>>> +++ b/target/riscv/insn_trans/trans_privileged.c.inc
>>> @@ -78,6 +78,7 @@ static bool trans_sret(DisasContext *ctx, arg_sret 
>>> *a)
>>>         if (has_ext(ctx, RVS)) {
>>>           gen_helper_sret(cpu_pc, cpu_env, cpu_pc);
>>> +        gen_helper_switch_context_xl(cpu_env);
>>>           tcg_gen_exit_tb(NULL, 0); /* no chaining */
>>>           ctx->base.is_jmp = DISAS_NORETURN;
>>>       } else {
>>> @@ -94,6 +95,7 @@ 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_switch_context_xl(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 ee7c24efe7..20cf8ad883 100644
>>> --- a/target/riscv/op_helper.c
>>> +++ b/target/riscv/op_helper.c
>>> @@ -70,6 +70,32 @@ target_ulong helper_csrrw(CPURISCVState *env, int 
>>> csr,
>>>   }
>>>     #ifndef CONFIG_USER_ONLY
>>> +void helper_switch_context_xl(CPURISCVState *env)
>>> +{
>>> +    RISCVMXL xl = cpu_get_xl(env);
>>> +    if (xl == env->misa_mxl_max) {
>>> +        return;
>>> +    }
>>> +    assert(xl < env->misa_mxl_max);
>>> +    switch (xl) {
>>> +    case MXL_RV32:
>>> +        for (int i = 1; i < 32; i++) {
>>> +            env->gpr[i] = (int32_t)env->gpr[i];
>>> +        }
>>
>> I think this is wrong.  As I read the spec, the new context ignores 
>> high bits and writes sign-extended values, but registers that are not 
>> written should not be changed.
> I think so.
>>
>> I think that a unit test with SXLEN == 64 and UXLEN == 32, where the 
>> U-mode program executes only the ECALL instruction, should leave the 
>> high 32 bits of all gprs unchanged on re-entry to S-mode.
> Re-entry to U-mode?  I think you are right.  But currently I don't 
> have a hardware has implemented the UXL32.
>>
>>> +        env->pc = (int32_t)env->pc;
>>
>> I think this will happen naturally via patch 3.
> Maybe we have to sign extend here as clarified in other reply.
>>
>>> +        /*
>>> +         * For the read-only bits of the previous-width CSR, the 
>>> bits at the
>>> +         * same positions in the temporary register are set to zeros.
>>> +         */
>>> +        if ((env->priv == PRV_U) && (env->misa_ext & RVV)) {
>>> +            env->vl = 0;
>>> +            env->vtype = 0;
>>> +        }
>>
>> I don't understand this.  The return from the S-mode interrupt 
>> handler to the U-mode program should preserve the U-mode VTYPE.
>>
>>
> According to the privileged architecture specification,  section 2.5,  
> if the width of a CSR is changed, the read-only bits of the 
> previous-width CSR are zeroed.
> More general,  there is an algorithm how to calculate the new CSR 
> value from the previous CSR.
>
> I am not sure which is the right time  to do this context switch. The 
> write time of  UXL field , or return to the U-mode?
>
>
> Thanks,
> Zhiwei
>
>> r~
>


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

* Re: [PATCH 09/13] target/riscv: Adjust vector address with ol
  2021-11-09  6:37         ` Richard Henderson
@ 2021-11-09  8:04           ` LIU Zhiwei
  -1 siblings, 0 replies; 88+ messages in thread
From: LIU Zhiwei @ 2021-11-09  8:04 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel, qemu-riscv, Alexey Baturo
  Cc: palmer, bin.meng, Alistair.Francis

On 2021/11/9 下午2:37, Richard Henderson wrote:

> On 11/8/21 10:28 AM, LIU Zhiwei wrote:
>> On 2021/11/1 下午7:35, Richard Henderson wrote:
>>
>>> On 11/1/21 6:01 AM, LIU Zhiwei wrote:
>>>> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
>>>> ---
>>>>   target/riscv/insn_trans/trans_rvv.c.inc |  8 ++++
>>>>   target/riscv/internals.h                |  1 +
>>>>   target/riscv/vector_helper.c            | 54 
>>>> +++++++++++++++++--------
>>>>   3 files changed, 46 insertions(+), 17 deletions(-)
>>>>
>>>> diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
>>>> b/target/riscv/insn_trans/trans_rvv.c.inc
>>>> index ed042f7bb9..5cd9b802df 100644
>>>> --- a/target/riscv/insn_trans/trans_rvv.c.inc
>>>> +++ b/target/riscv/insn_trans/trans_rvv.c.inc
>>>> @@ -233,6 +233,7 @@ static bool ld_us_op(DisasContext *s, 
>>>> arg_r2nfvm *a, uint8_t seq)
>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>       return ldst_us_trans(a->rd, a->rs1, data, fn, s);
>>>>   }
>>>>   @@ -286,6 +287,7 @@ static bool st_us_op(DisasContext *s, 
>>>> arg_r2nfvm *a, uint8_t seq)
>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>       return ldst_us_trans(a->rd, a->rs1, data, fn, s);
>>>>   }
>>>>   @@ -365,6 +367,7 @@ static bool ld_stride_op(DisasContext *s, 
>>>> arg_rnfvm *a, uint8_t seq)
>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>       return ldst_stride_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>>>>   }
>>>>   @@ -404,6 +407,7 @@ static bool st_stride_op(DisasContext *s, 
>>>> arg_rnfvm *a, uint8_t seq)
>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>       fn =  fns[seq][s->sew];
>>>>       if (fn == NULL) {
>>>>           return false;
>>>> @@ -490,6 +494,7 @@ static bool ld_index_op(DisasContext *s, 
>>>> arg_rnfvm *a, uint8_t seq)
>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>       return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>>>>   }
>>>>   @@ -542,6 +547,7 @@ static bool st_index_op(DisasContext *s, 
>>>> arg_rnfvm *a, uint8_t seq)
>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>       return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>>>>   }
>>>>   @@ -617,6 +623,7 @@ static bool ldff_op(DisasContext *s, 
>>>> arg_r2nfvm *a, uint8_t seq)
>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>       return ldff_trans(a->rd, a->rs1, data, fn, s);
>>>>   }
>>>>   @@ -724,6 +731,7 @@ static bool amo_op(DisasContext *s, arg_rwdvm 
>>>> *a, uint8_t seq)
>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>       data = FIELD_DP32(data, VDATA, WD, a->wd);
>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>       return amo_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>>>>   }
>>>>   /*
>>>> diff --git a/target/riscv/internals.h b/target/riscv/internals.h
>>>> index b15ad394bb..f74b8291e4 100644
>>>> --- a/target/riscv/internals.h
>>>> +++ b/target/riscv/internals.h
>>>> @@ -27,6 +27,7 @@ FIELD(VDATA, VM, 8, 1)
>>>>   FIELD(VDATA, LMUL, 9, 2)
>>>>   FIELD(VDATA, NF, 11, 4)
>>>>   FIELD(VDATA, WD, 11, 1)
>>>> +FIELD(VDATA, OL, 15, 2)
>>>>     /* float point classify helpers */
>>>>   target_ulong fclass_h(uint64_t frs1);
>>>> diff --git a/target/riscv/vector_helper.c 
>>>> b/target/riscv/vector_helper.c
>>>> index 535420ee66..451688c328 100644
>>>> --- a/target/riscv/vector_helper.c
>>>> +++ b/target/riscv/vector_helper.c
>>>> @@ -112,6 +112,11 @@ static uint32_t vext_wd(uint32_t desc)
>>>>       return (simd_data(desc) >> 11) & 0x1;
>>>>   }
>>>>   +static inline uint32_t vext_ol(uint32_t desc)
>>>> +{
>>>> +    return FIELD_EX32(simd_data(desc), VDATA, OL);
>>>> +}
>>>
>>> XLEN not OLEN.
>> OK.
>>>
>>>> @@ -123,6 +128,14 @@ static inline uint32_t vext_maxsz(uint32_t desc)
>>>>       return simd_maxsz(desc) << vext_lmul(desc);
>>>>   }
>>>>   +static inline target_ulong adjust_addr(target_ulong addr, 
>>>> uint32_t olen)
>>>> +{
>>>> +    if (olen < TARGET_LONG_BITS) {
>>>> +        addr &= UINT32_MAX;
>>>> +    }
>>>> +    return addr;
>>>> +}
>>>
>>> Here's where I'm unsure.  This looks a lot like the changes that are 
>>> required to support pointer-masking in vectors, which Alexey said he 
>>> was going to look at.
>>>
>>> (1) Do we need to pass anything in VEXT at all?
>>>     We do have CPURISCVState, so we could just use cpu_get_ml,
>> Yes, we should use cpu_get_xl.
>>> which we would also need for env->mmte etc for pointer masking.
>>
>> Do you mean env->mpmmask and env->mpmbase? I think yes, we should 
>> also adjust these register behaviors with xlen.
>
> I mean the set of [msu]pmmask and [msu]pmbase, selected as appropriate 
> for the current execution mode.
>
>>> (3) Do we try to streamline the computation by passing down composite
>>>     mask and base parameters.  This way we don't need to do complex
>>>     examination of ENV to determine execution mode, and instead always
>>>     compute
>>>
>>>        addr = (addr & mask) | base;
>>>
>>>     where mask = -1, base = 0 for "normal" addressing, and when
>>>     UXLEN == 32, mask <= UINT32_MAX.
>>
>> Do you mean add env->pmmask and env->pmbase?
>>
>> I can initialize them in riscv_tr_init_disas_context, such as by 
>> env->xpmmask & UINT32_MAX .
>>
>>>
>>> (4) Do we in fact want to pre-compute these into known slots on ENV,
>>>     so that we don't have to pass these around as separate parameters?
>>>     We would adjust these values during PM CSR changes and when
>>>     changing privilege levels.
> For option (3), I was suggesting a mask + base pair passed down from 
> TCG-generated code.
>
> For option (4), I was suggesting embedding a mask + base pair in env, 
> which would be re-computed at every privilege level change, plus reset 
> and vmload.
>
> In both cases, the mask would be a combination of [msu]pmmask & (RV32 
> ? UINT32_MAX : UINT64_MAX), as you say.

We will calculate [msu]pmmask by  csrrw , and we have ignored high bits 
there.

Can we just use the [msu]pmmmask?

Thanks,
Zhiwei

>
>
> r~


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

* Re: [PATCH 09/13] target/riscv: Adjust vector address with ol
@ 2021-11-09  8:04           ` LIU Zhiwei
  0 siblings, 0 replies; 88+ messages in thread
From: LIU Zhiwei @ 2021-11-09  8:04 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel, qemu-riscv, Alexey Baturo
  Cc: Alistair.Francis, palmer, bin.meng

On 2021/11/9 下午2:37, Richard Henderson wrote:

> On 11/8/21 10:28 AM, LIU Zhiwei wrote:
>> On 2021/11/1 下午7:35, Richard Henderson wrote:
>>
>>> On 11/1/21 6:01 AM, LIU Zhiwei wrote:
>>>> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
>>>> ---
>>>>   target/riscv/insn_trans/trans_rvv.c.inc |  8 ++++
>>>>   target/riscv/internals.h                |  1 +
>>>>   target/riscv/vector_helper.c            | 54 
>>>> +++++++++++++++++--------
>>>>   3 files changed, 46 insertions(+), 17 deletions(-)
>>>>
>>>> diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
>>>> b/target/riscv/insn_trans/trans_rvv.c.inc
>>>> index ed042f7bb9..5cd9b802df 100644
>>>> --- a/target/riscv/insn_trans/trans_rvv.c.inc
>>>> +++ b/target/riscv/insn_trans/trans_rvv.c.inc
>>>> @@ -233,6 +233,7 @@ static bool ld_us_op(DisasContext *s, 
>>>> arg_r2nfvm *a, uint8_t seq)
>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>       return ldst_us_trans(a->rd, a->rs1, data, fn, s);
>>>>   }
>>>>   @@ -286,6 +287,7 @@ static bool st_us_op(DisasContext *s, 
>>>> arg_r2nfvm *a, uint8_t seq)
>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>       return ldst_us_trans(a->rd, a->rs1, data, fn, s);
>>>>   }
>>>>   @@ -365,6 +367,7 @@ static bool ld_stride_op(DisasContext *s, 
>>>> arg_rnfvm *a, uint8_t seq)
>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>       return ldst_stride_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>>>>   }
>>>>   @@ -404,6 +407,7 @@ static bool st_stride_op(DisasContext *s, 
>>>> arg_rnfvm *a, uint8_t seq)
>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>       fn =  fns[seq][s->sew];
>>>>       if (fn == NULL) {
>>>>           return false;
>>>> @@ -490,6 +494,7 @@ static bool ld_index_op(DisasContext *s, 
>>>> arg_rnfvm *a, uint8_t seq)
>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>       return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>>>>   }
>>>>   @@ -542,6 +547,7 @@ static bool st_index_op(DisasContext *s, 
>>>> arg_rnfvm *a, uint8_t seq)
>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>       return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>>>>   }
>>>>   @@ -617,6 +623,7 @@ static bool ldff_op(DisasContext *s, 
>>>> arg_r2nfvm *a, uint8_t seq)
>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>       return ldff_trans(a->rd, a->rs1, data, fn, s);
>>>>   }
>>>>   @@ -724,6 +731,7 @@ static bool amo_op(DisasContext *s, arg_rwdvm 
>>>> *a, uint8_t seq)
>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>       data = FIELD_DP32(data, VDATA, WD, a->wd);
>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>       return amo_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>>>>   }
>>>>   /*
>>>> diff --git a/target/riscv/internals.h b/target/riscv/internals.h
>>>> index b15ad394bb..f74b8291e4 100644
>>>> --- a/target/riscv/internals.h
>>>> +++ b/target/riscv/internals.h
>>>> @@ -27,6 +27,7 @@ FIELD(VDATA, VM, 8, 1)
>>>>   FIELD(VDATA, LMUL, 9, 2)
>>>>   FIELD(VDATA, NF, 11, 4)
>>>>   FIELD(VDATA, WD, 11, 1)
>>>> +FIELD(VDATA, OL, 15, 2)
>>>>     /* float point classify helpers */
>>>>   target_ulong fclass_h(uint64_t frs1);
>>>> diff --git a/target/riscv/vector_helper.c 
>>>> b/target/riscv/vector_helper.c
>>>> index 535420ee66..451688c328 100644
>>>> --- a/target/riscv/vector_helper.c
>>>> +++ b/target/riscv/vector_helper.c
>>>> @@ -112,6 +112,11 @@ static uint32_t vext_wd(uint32_t desc)
>>>>       return (simd_data(desc) >> 11) & 0x1;
>>>>   }
>>>>   +static inline uint32_t vext_ol(uint32_t desc)
>>>> +{
>>>> +    return FIELD_EX32(simd_data(desc), VDATA, OL);
>>>> +}
>>>
>>> XLEN not OLEN.
>> OK.
>>>
>>>> @@ -123,6 +128,14 @@ static inline uint32_t vext_maxsz(uint32_t desc)
>>>>       return simd_maxsz(desc) << vext_lmul(desc);
>>>>   }
>>>>   +static inline target_ulong adjust_addr(target_ulong addr, 
>>>> uint32_t olen)
>>>> +{
>>>> +    if (olen < TARGET_LONG_BITS) {
>>>> +        addr &= UINT32_MAX;
>>>> +    }
>>>> +    return addr;
>>>> +}
>>>
>>> Here's where I'm unsure.  This looks a lot like the changes that are 
>>> required to support pointer-masking in vectors, which Alexey said he 
>>> was going to look at.
>>>
>>> (1) Do we need to pass anything in VEXT at all?
>>>     We do have CPURISCVState, so we could just use cpu_get_ml,
>> Yes, we should use cpu_get_xl.
>>> which we would also need for env->mmte etc for pointer masking.
>>
>> Do you mean env->mpmmask and env->mpmbase? I think yes, we should 
>> also adjust these register behaviors with xlen.
>
> I mean the set of [msu]pmmask and [msu]pmbase, selected as appropriate 
> for the current execution mode.
>
>>> (3) Do we try to streamline the computation by passing down composite
>>>     mask and base parameters.  This way we don't need to do complex
>>>     examination of ENV to determine execution mode, and instead always
>>>     compute
>>>
>>>        addr = (addr & mask) | base;
>>>
>>>     where mask = -1, base = 0 for "normal" addressing, and when
>>>     UXLEN == 32, mask <= UINT32_MAX.
>>
>> Do you mean add env->pmmask and env->pmbase?
>>
>> I can initialize them in riscv_tr_init_disas_context, such as by 
>> env->xpmmask & UINT32_MAX .
>>
>>>
>>> (4) Do we in fact want to pre-compute these into known slots on ENV,
>>>     so that we don't have to pass these around as separate parameters?
>>>     We would adjust these values during PM CSR changes and when
>>>     changing privilege levels.
> For option (3), I was suggesting a mask + base pair passed down from 
> TCG-generated code.
>
> For option (4), I was suggesting embedding a mask + base pair in env, 
> which would be re-computed at every privilege level change, plus reset 
> and vmload.
>
> In both cases, the mask would be a combination of [msu]pmmask & (RV32 
> ? UINT32_MAX : UINT64_MAX), as you say.

We will calculate [msu]pmmask by  csrrw , and we have ignored high bits 
there.

Can we just use the [msu]pmmmask?

Thanks,
Zhiwei

>
>
> r~


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

* Re: [PATCH 09/13] target/riscv: Adjust vector address with ol
  2021-11-09  8:04           ` LIU Zhiwei
@ 2021-11-09  8:18             ` Richard Henderson
  -1 siblings, 0 replies; 88+ messages in thread
From: Richard Henderson @ 2021-11-09  8:18 UTC (permalink / raw)
  To: LIU Zhiwei, qemu-devel, qemu-riscv, Alexey Baturo
  Cc: palmer, bin.meng, Alistair.Francis

On 11/9/21 9:04 AM, LIU Zhiwei wrote:
> On 2021/11/9 下午2:37, Richard Henderson wrote:
> 
>> On 11/8/21 10:28 AM, LIU Zhiwei wrote:
>>> On 2021/11/1 下午7:35, Richard Henderson wrote:
>>>
>>>> On 11/1/21 6:01 AM, LIU Zhiwei wrote:
>>>>> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
>>>>> ---
>>>>>   target/riscv/insn_trans/trans_rvv.c.inc |  8 ++++
>>>>>   target/riscv/internals.h                |  1 +
>>>>>   target/riscv/vector_helper.c            | 54 +++++++++++++++++--------
>>>>>   3 files changed, 46 insertions(+), 17 deletions(-)
>>>>>
>>>>> diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
>>>>> b/target/riscv/insn_trans/trans_rvv.c.inc
>>>>> index ed042f7bb9..5cd9b802df 100644
>>>>> --- a/target/riscv/insn_trans/trans_rvv.c.inc
>>>>> +++ b/target/riscv/insn_trans/trans_rvv.c.inc
>>>>> @@ -233,6 +233,7 @@ static bool ld_us_op(DisasContext *s, arg_r2nfvm *a, uint8_t seq)
>>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>>       return ldst_us_trans(a->rd, a->rs1, data, fn, s);
>>>>>   }
>>>>>   @@ -286,6 +287,7 @@ static bool st_us_op(DisasContext *s, arg_r2nfvm *a, uint8_t seq)
>>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>>       return ldst_us_trans(a->rd, a->rs1, data, fn, s);
>>>>>   }
>>>>>   @@ -365,6 +367,7 @@ static bool ld_stride_op(DisasContext *s, arg_rnfvm *a, uint8_t 
>>>>> seq)
>>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>>       return ldst_stride_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>>>>>   }
>>>>>   @@ -404,6 +407,7 @@ static bool st_stride_op(DisasContext *s, arg_rnfvm *a, uint8_t 
>>>>> seq)
>>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>>       fn =  fns[seq][s->sew];
>>>>>       if (fn == NULL) {
>>>>>           return false;
>>>>> @@ -490,6 +494,7 @@ static bool ld_index_op(DisasContext *s, arg_rnfvm *a, uint8_t seq)
>>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>>       return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>>>>>   }
>>>>>   @@ -542,6 +547,7 @@ static bool st_index_op(DisasContext *s, arg_rnfvm *a, uint8_t 
>>>>> seq)
>>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>>       return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>>>>>   }
>>>>>   @@ -617,6 +623,7 @@ static bool ldff_op(DisasContext *s, arg_r2nfvm *a, uint8_t seq)
>>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>>       return ldff_trans(a->rd, a->rs1, data, fn, s);
>>>>>   }
>>>>>   @@ -724,6 +731,7 @@ static bool amo_op(DisasContext *s, arg_rwdvm *a, uint8_t seq)
>>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>>       data = FIELD_DP32(data, VDATA, WD, a->wd);
>>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>>       return amo_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>>>>>   }
>>>>>   /*
>>>>> diff --git a/target/riscv/internals.h b/target/riscv/internals.h
>>>>> index b15ad394bb..f74b8291e4 100644
>>>>> --- a/target/riscv/internals.h
>>>>> +++ b/target/riscv/internals.h
>>>>> @@ -27,6 +27,7 @@ FIELD(VDATA, VM, 8, 1)
>>>>>   FIELD(VDATA, LMUL, 9, 2)
>>>>>   FIELD(VDATA, NF, 11, 4)
>>>>>   FIELD(VDATA, WD, 11, 1)
>>>>> +FIELD(VDATA, OL, 15, 2)
>>>>>     /* float point classify helpers */
>>>>>   target_ulong fclass_h(uint64_t frs1);
>>>>> diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
>>>>> index 535420ee66..451688c328 100644
>>>>> --- a/target/riscv/vector_helper.c
>>>>> +++ b/target/riscv/vector_helper.c
>>>>> @@ -112,6 +112,11 @@ static uint32_t vext_wd(uint32_t desc)
>>>>>       return (simd_data(desc) >> 11) & 0x1;
>>>>>   }
>>>>>   +static inline uint32_t vext_ol(uint32_t desc)
>>>>> +{
>>>>> +    return FIELD_EX32(simd_data(desc), VDATA, OL);
>>>>> +}
>>>>
>>>> XLEN not OLEN.
>>> OK.
>>>>
>>>>> @@ -123,6 +128,14 @@ static inline uint32_t vext_maxsz(uint32_t desc)
>>>>>       return simd_maxsz(desc) << vext_lmul(desc);
>>>>>   }
>>>>>   +static inline target_ulong adjust_addr(target_ulong addr, uint32_t olen)
>>>>> +{
>>>>> +    if (olen < TARGET_LONG_BITS) {
>>>>> +        addr &= UINT32_MAX;
>>>>> +    }
>>>>> +    return addr;
>>>>> +}
>>>>
>>>> Here's where I'm unsure.  This looks a lot like the changes that are required to 
>>>> support pointer-masking in vectors, which Alexey said he was going to look at.
>>>>
>>>> (1) Do we need to pass anything in VEXT at all?
>>>>     We do have CPURISCVState, so we could just use cpu_get_ml,
>>> Yes, we should use cpu_get_xl.
>>>> which we would also need for env->mmte etc for pointer masking.
>>>
>>> Do you mean env->mpmmask and env->mpmbase? I think yes, we should also adjust these 
>>> register behaviors with xlen.
>>
>> I mean the set of [msu]pmmask and [msu]pmbase, selected as appropriate for the current 
>> execution mode.
>>
>>>> (3) Do we try to streamline the computation by passing down composite
>>>>     mask and base parameters.  This way we don't need to do complex
>>>>     examination of ENV to determine execution mode, and instead always
>>>>     compute
>>>>
>>>>        addr = (addr & mask) | base;
>>>>
>>>>     where mask = -1, base = 0 for "normal" addressing, and when
>>>>     UXLEN == 32, mask <= UINT32_MAX.
>>>
>>> Do you mean add env->pmmask and env->pmbase?
>>>
>>> I can initialize them in riscv_tr_init_disas_context, such as by env->xpmmask & 
>>> UINT32_MAX .
>>>
>>>>
>>>> (4) Do we in fact want to pre-compute these into known slots on ENV,
>>>>     so that we don't have to pass these around as separate parameters?
>>>>     We would adjust these values during PM CSR changes and when
>>>>     changing privilege levels.
>> For option (3), I was suggesting a mask + base pair passed down from TCG-generated code.
>>
>> For option (4), I was suggesting embedding a mask + base pair in env, which would be 
>> re-computed at every privilege level change, plus reset and vmload.
>>
>> In both cases, the mask would be a combination of [msu]pmmask & (RV32 ? UINT32_MAX : 
>> UINT64_MAX), as you say.
> 
> We will calculate [msu]pmmask by  csrrw , and we have ignored high bits there.
> 
> Can we just use the [msu]pmmmask?

We could.  However:

In order to select [msu]pmmask, we have to look up the current cpu state.  In order to 
mask the high bits, we have to look up the current xl, which requires that we look up the 
current cpu state then extract the xl from misa  and mstatus.

All of which means that we're doing repeated lookups for every memory access.  I am 
suggesting that we either (3) compile those lookups into the generated code or (4) cache 
those lookups when state changes (csr writes and priv changes).


r~


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

* Re: [PATCH 09/13] target/riscv: Adjust vector address with ol
@ 2021-11-09  8:18             ` Richard Henderson
  0 siblings, 0 replies; 88+ messages in thread
From: Richard Henderson @ 2021-11-09  8:18 UTC (permalink / raw)
  To: LIU Zhiwei, qemu-devel, qemu-riscv, Alexey Baturo
  Cc: Alistair.Francis, palmer, bin.meng

On 11/9/21 9:04 AM, LIU Zhiwei wrote:
> On 2021/11/9 下午2:37, Richard Henderson wrote:
> 
>> On 11/8/21 10:28 AM, LIU Zhiwei wrote:
>>> On 2021/11/1 下午7:35, Richard Henderson wrote:
>>>
>>>> On 11/1/21 6:01 AM, LIU Zhiwei wrote:
>>>>> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
>>>>> ---
>>>>>   target/riscv/insn_trans/trans_rvv.c.inc |  8 ++++
>>>>>   target/riscv/internals.h                |  1 +
>>>>>   target/riscv/vector_helper.c            | 54 +++++++++++++++++--------
>>>>>   3 files changed, 46 insertions(+), 17 deletions(-)
>>>>>
>>>>> diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
>>>>> b/target/riscv/insn_trans/trans_rvv.c.inc
>>>>> index ed042f7bb9..5cd9b802df 100644
>>>>> --- a/target/riscv/insn_trans/trans_rvv.c.inc
>>>>> +++ b/target/riscv/insn_trans/trans_rvv.c.inc
>>>>> @@ -233,6 +233,7 @@ static bool ld_us_op(DisasContext *s, arg_r2nfvm *a, uint8_t seq)
>>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>>       return ldst_us_trans(a->rd, a->rs1, data, fn, s);
>>>>>   }
>>>>>   @@ -286,6 +287,7 @@ static bool st_us_op(DisasContext *s, arg_r2nfvm *a, uint8_t seq)
>>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>>       return ldst_us_trans(a->rd, a->rs1, data, fn, s);
>>>>>   }
>>>>>   @@ -365,6 +367,7 @@ static bool ld_stride_op(DisasContext *s, arg_rnfvm *a, uint8_t 
>>>>> seq)
>>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>>       return ldst_stride_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>>>>>   }
>>>>>   @@ -404,6 +407,7 @@ static bool st_stride_op(DisasContext *s, arg_rnfvm *a, uint8_t 
>>>>> seq)
>>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>>       fn =  fns[seq][s->sew];
>>>>>       if (fn == NULL) {
>>>>>           return false;
>>>>> @@ -490,6 +494,7 @@ static bool ld_index_op(DisasContext *s, arg_rnfvm *a, uint8_t seq)
>>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>>       return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>>>>>   }
>>>>>   @@ -542,6 +547,7 @@ static bool st_index_op(DisasContext *s, arg_rnfvm *a, uint8_t 
>>>>> seq)
>>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>>       return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>>>>>   }
>>>>>   @@ -617,6 +623,7 @@ static bool ldff_op(DisasContext *s, arg_r2nfvm *a, uint8_t seq)
>>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>>       return ldff_trans(a->rd, a->rs1, data, fn, s);
>>>>>   }
>>>>>   @@ -724,6 +731,7 @@ static bool amo_op(DisasContext *s, arg_rwdvm *a, uint8_t seq)
>>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>>       data = FIELD_DP32(data, VDATA, WD, a->wd);
>>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>>       return amo_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>>>>>   }
>>>>>   /*
>>>>> diff --git a/target/riscv/internals.h b/target/riscv/internals.h
>>>>> index b15ad394bb..f74b8291e4 100644
>>>>> --- a/target/riscv/internals.h
>>>>> +++ b/target/riscv/internals.h
>>>>> @@ -27,6 +27,7 @@ FIELD(VDATA, VM, 8, 1)
>>>>>   FIELD(VDATA, LMUL, 9, 2)
>>>>>   FIELD(VDATA, NF, 11, 4)
>>>>>   FIELD(VDATA, WD, 11, 1)
>>>>> +FIELD(VDATA, OL, 15, 2)
>>>>>     /* float point classify helpers */
>>>>>   target_ulong fclass_h(uint64_t frs1);
>>>>> diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
>>>>> index 535420ee66..451688c328 100644
>>>>> --- a/target/riscv/vector_helper.c
>>>>> +++ b/target/riscv/vector_helper.c
>>>>> @@ -112,6 +112,11 @@ static uint32_t vext_wd(uint32_t desc)
>>>>>       return (simd_data(desc) >> 11) & 0x1;
>>>>>   }
>>>>>   +static inline uint32_t vext_ol(uint32_t desc)
>>>>> +{
>>>>> +    return FIELD_EX32(simd_data(desc), VDATA, OL);
>>>>> +}
>>>>
>>>> XLEN not OLEN.
>>> OK.
>>>>
>>>>> @@ -123,6 +128,14 @@ static inline uint32_t vext_maxsz(uint32_t desc)
>>>>>       return simd_maxsz(desc) << vext_lmul(desc);
>>>>>   }
>>>>>   +static inline target_ulong adjust_addr(target_ulong addr, uint32_t olen)
>>>>> +{
>>>>> +    if (olen < TARGET_LONG_BITS) {
>>>>> +        addr &= UINT32_MAX;
>>>>> +    }
>>>>> +    return addr;
>>>>> +}
>>>>
>>>> Here's where I'm unsure.  This looks a lot like the changes that are required to 
>>>> support pointer-masking in vectors, which Alexey said he was going to look at.
>>>>
>>>> (1) Do we need to pass anything in VEXT at all?
>>>>     We do have CPURISCVState, so we could just use cpu_get_ml,
>>> Yes, we should use cpu_get_xl.
>>>> which we would also need for env->mmte etc for pointer masking.
>>>
>>> Do you mean env->mpmmask and env->mpmbase? I think yes, we should also adjust these 
>>> register behaviors with xlen.
>>
>> I mean the set of [msu]pmmask and [msu]pmbase, selected as appropriate for the current 
>> execution mode.
>>
>>>> (3) Do we try to streamline the computation by passing down composite
>>>>     mask and base parameters.  This way we don't need to do complex
>>>>     examination of ENV to determine execution mode, and instead always
>>>>     compute
>>>>
>>>>        addr = (addr & mask) | base;
>>>>
>>>>     where mask = -1, base = 0 for "normal" addressing, and when
>>>>     UXLEN == 32, mask <= UINT32_MAX.
>>>
>>> Do you mean add env->pmmask and env->pmbase?
>>>
>>> I can initialize them in riscv_tr_init_disas_context, such as by env->xpmmask & 
>>> UINT32_MAX .
>>>
>>>>
>>>> (4) Do we in fact want to pre-compute these into known slots on ENV,
>>>>     so that we don't have to pass these around as separate parameters?
>>>>     We would adjust these values during PM CSR changes and when
>>>>     changing privilege levels.
>> For option (3), I was suggesting a mask + base pair passed down from TCG-generated code.
>>
>> For option (4), I was suggesting embedding a mask + base pair in env, which would be 
>> re-computed at every privilege level change, plus reset and vmload.
>>
>> In both cases, the mask would be a combination of [msu]pmmask & (RV32 ? UINT32_MAX : 
>> UINT64_MAX), as you say.
> 
> We will calculate [msu]pmmask by  csrrw , and we have ignored high bits there.
> 
> Can we just use the [msu]pmmmask?

We could.  However:

In order to select [msu]pmmask, we have to look up the current cpu state.  In order to 
mask the high bits, we have to look up the current xl, which requires that we look up the 
current cpu state then extract the xl from misa  and mstatus.

All of which means that we're doing repeated lookups for every memory access.  I am 
suggesting that we either (3) compile those lookups into the generated code or (4) cache 
those lookups when state changes (csr writes and priv changes).


r~


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

* Re: [PATCH 09/13] target/riscv: Adjust vector address with ol
  2021-11-09  8:18             ` Richard Henderson
@ 2021-11-09  8:39               ` LIU Zhiwei
  -1 siblings, 0 replies; 88+ messages in thread
From: LIU Zhiwei @ 2021-11-09  8:39 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel, qemu-riscv, Alexey Baturo
  Cc: palmer, bin.meng, Alistair.Francis

[-- Attachment #1: Type: text/plain, Size: 9753 bytes --]


On 2021/11/9 下午4:18, Richard Henderson wrote:
> On 11/9/21 9:04 AM, LIU Zhiwei wrote:
>> On 2021/11/9 下午2:37, Richard Henderson wrote:
>>
>>> On 11/8/21 10:28 AM, LIU Zhiwei wrote:
>>>> On 2021/11/1 下午7:35, Richard Henderson wrote:
>>>>
>>>>> On 11/1/21 6:01 AM, LIU Zhiwei wrote:
>>>>>> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
>>>>>> ---
>>>>>>   target/riscv/insn_trans/trans_rvv.c.inc |  8 ++++
>>>>>>   target/riscv/internals.h                |  1 +
>>>>>>   target/riscv/vector_helper.c            | 54 
>>>>>> +++++++++++++++++--------
>>>>>>   3 files changed, 46 insertions(+), 17 deletions(-)
>>>>>>
>>>>>> diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
>>>>>> b/target/riscv/insn_trans/trans_rvv.c.inc
>>>>>> index ed042f7bb9..5cd9b802df 100644
>>>>>> --- a/target/riscv/insn_trans/trans_rvv.c.inc
>>>>>> +++ b/target/riscv/insn_trans/trans_rvv.c.inc
>>>>>> @@ -233,6 +233,7 @@ static bool ld_us_op(DisasContext *s, 
>>>>>> arg_r2nfvm *a, uint8_t seq)
>>>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>>>       return ldst_us_trans(a->rd, a->rs1, data, fn, s);
>>>>>>   }
>>>>>>   @@ -286,6 +287,7 @@ static bool st_us_op(DisasContext *s, 
>>>>>> arg_r2nfvm *a, uint8_t seq)
>>>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>>>       return ldst_us_trans(a->rd, a->rs1, data, fn, s);
>>>>>>   }
>>>>>>   @@ -365,6 +367,7 @@ static bool ld_stride_op(DisasContext *s, 
>>>>>> arg_rnfvm *a, uint8_t seq)
>>>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>>>       return ldst_stride_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>>>>>>   }
>>>>>>   @@ -404,6 +407,7 @@ static bool st_stride_op(DisasContext *s, 
>>>>>> arg_rnfvm *a, uint8_t seq)
>>>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>>>       fn =  fns[seq][s->sew];
>>>>>>       if (fn == NULL) {
>>>>>>           return false;
>>>>>> @@ -490,6 +494,7 @@ static bool ld_index_op(DisasContext *s, 
>>>>>> arg_rnfvm *a, uint8_t seq)
>>>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>>>       return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>>>>>>   }
>>>>>>   @@ -542,6 +547,7 @@ static bool st_index_op(DisasContext *s, 
>>>>>> arg_rnfvm *a, uint8_t seq)
>>>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>>>       return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>>>>>>   }
>>>>>>   @@ -617,6 +623,7 @@ static bool ldff_op(DisasContext *s, 
>>>>>> arg_r2nfvm *a, uint8_t seq)
>>>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>>>       return ldff_trans(a->rd, a->rs1, data, fn, s);
>>>>>>   }
>>>>>>   @@ -724,6 +731,7 @@ static bool amo_op(DisasContext *s, 
>>>>>> arg_rwdvm *a, uint8_t seq)
>>>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>>>       data = FIELD_DP32(data, VDATA, WD, a->wd);
>>>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>>>       return amo_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>>>>>>   }
>>>>>>   /*
>>>>>> diff --git a/target/riscv/internals.h b/target/riscv/internals.h
>>>>>> index b15ad394bb..f74b8291e4 100644
>>>>>> --- a/target/riscv/internals.h
>>>>>> +++ b/target/riscv/internals.h
>>>>>> @@ -27,6 +27,7 @@ FIELD(VDATA, VM, 8, 1)
>>>>>>   FIELD(VDATA, LMUL, 9, 2)
>>>>>>   FIELD(VDATA, NF, 11, 4)
>>>>>>   FIELD(VDATA, WD, 11, 1)
>>>>>> +FIELD(VDATA, OL, 15, 2)
>>>>>>     /* float point classify helpers */
>>>>>>   target_ulong fclass_h(uint64_t frs1);
>>>>>> diff --git a/target/riscv/vector_helper.c 
>>>>>> b/target/riscv/vector_helper.c
>>>>>> index 535420ee66..451688c328 100644
>>>>>> --- a/target/riscv/vector_helper.c
>>>>>> +++ b/target/riscv/vector_helper.c
>>>>>> @@ -112,6 +112,11 @@ static uint32_t vext_wd(uint32_t desc)
>>>>>>       return (simd_data(desc) >> 11) & 0x1;
>>>>>>   }
>>>>>>   +static inline uint32_t vext_ol(uint32_t desc)
>>>>>> +{
>>>>>> +    return FIELD_EX32(simd_data(desc), VDATA, OL);
>>>>>> +}
>>>>>
>>>>> XLEN not OLEN.
>>>> OK.
>>>>>
>>>>>> @@ -123,6 +128,14 @@ static inline uint32_t vext_maxsz(uint32_t 
>>>>>> desc)
>>>>>>       return simd_maxsz(desc) << vext_lmul(desc);
>>>>>>   }
>>>>>>   +static inline target_ulong adjust_addr(target_ulong addr, 
>>>>>> uint32_t olen)
>>>>>> +{
>>>>>> +    if (olen < TARGET_LONG_BITS) {
>>>>>> +        addr &= UINT32_MAX;
>>>>>> +    }
>>>>>> +    return addr;
>>>>>> +}
>>>>>
>>>>> Here's where I'm unsure.  This looks a lot like the changes that 
>>>>> are required to support pointer-masking in vectors, which Alexey 
>>>>> said he was going to look at.
>>>>>
>>>>> (1) Do we need to pass anything in VEXT at all?
>>>>>     We do have CPURISCVState, so we could just use cpu_get_ml,
>>>> Yes, we should use cpu_get_xl.
>>>>> which we would also need for env->mmte etc for pointer masking.
>>>>
>>>> Do you mean env->mpmmask and env->mpmbase? I think yes, we should 
>>>> also adjust these register behaviors with xlen.
>>>
>>> I mean the set of [msu]pmmask and [msu]pmbase, selected as 
>>> appropriate for the current execution mode.
>>>
>>>>> (3) Do we try to streamline the computation by passing down composite
>>>>>     mask and base parameters.  This way we don't need to do complex
>>>>>     examination of ENV to determine execution mode, and instead 
>>>>> always
>>>>>     compute
>>>>>
>>>>>        addr = (addr & mask) | base;
>>>>>
>>>>>     where mask = -1, base = 0 for "normal" addressing, and when
>>>>>     UXLEN == 32, mask <= UINT32_MAX.
>>>>
>>>> Do you mean add env->pmmask and env->pmbase?
>>>>
>>>> I can initialize them in riscv_tr_init_disas_context, such as by 
>>>> env->xpmmask & UINT32_MAX .
>>>>
>>>>>
>>>>> (4) Do we in fact want to pre-compute these into known slots on ENV,
>>>>>     so that we don't have to pass these around as separate 
>>>>> parameters?
>>>>>     We would adjust these values during PM CSR changes and when
>>>>>     changing privilege levels.
>>> For option (3), I was suggesting a mask + base pair passed down from 
>>> TCG-generated code.
>>>
>>> For option (4), I was suggesting embedding a mask + base pair in 
>>> env, which would be re-computed at every privilege level change, 
>>> plus reset and vmload.
>>>
>>> In both cases, the mask would be a combination of [msu]pmmask & 
>>> (RV32 ? UINT32_MAX : UINT64_MAX), as you say.
>>
>> We will calculate [msu]pmmask by  csrrw , and we have ignored high 
>> bits there.
>>
>> Can we just use the [msu]pmmmask?
>
> We could.  However:
>
> In order to select [msu]pmmask, we have to look up the current cpu 
> state.  In order to mask the high bits, we have to look up the current 
> xl, which requires that we look up the current cpu state then extract 
> the xl from misa  and mstatus.
>
> All of which means that we're doing repeated lookups for every memory 
> access.  I am suggesting that we either (3) compile those lookups into 
> the generated code or (4) cache those lookups when state changes (csr 
> writes and priv changes).


Do you mean we should add this code to riscv_tr_init_disas_context

     if (ctx->pm_enabled) {
          switch (priv) {
          case PRV_M:
              env->mask = env->mpmmask;
              env->base = env->mpmbase;
              break;
          case PRV_S:
              env->mask = env->spmmask;
              env->base = env->spmbase;
              break;
          case PRV_U:
              env->mask = env->upmmask;
              env->base = env->upmbase;
              break;
          default:
              g_assert_not_reached();
          }
          ctx->pm_mask = pm_mask[priv];
          ctx->pm_base = pm_base[priv];
          ctx->need_mask = true; /* new flag for mask */

      } else if (get_xlen(ctx)  < TARGET_LONG_BITS) {
          env->mask = UINT32_MAX;
          env->base = 0;
          ctx->pm_mask = tcg_constant_tl(UINT32_MAX);
          ctx->pm_base = tcg_constant_tl(0);

         ctx->need_mask = true;

      } else {
	 env->mask = UINT64_MAX;
          env->base = 0;
      }

Thanks,
Zhiwei

>
>
> r~

[-- Attachment #2: Type: text/html, Size: 15758 bytes --]

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

* Re: [PATCH 09/13] target/riscv: Adjust vector address with ol
@ 2021-11-09  8:39               ` LIU Zhiwei
  0 siblings, 0 replies; 88+ messages in thread
From: LIU Zhiwei @ 2021-11-09  8:39 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel, qemu-riscv, Alexey Baturo
  Cc: Alistair.Francis, palmer, bin.meng

[-- Attachment #1: Type: text/plain, Size: 9753 bytes --]


On 2021/11/9 下午4:18, Richard Henderson wrote:
> On 11/9/21 9:04 AM, LIU Zhiwei wrote:
>> On 2021/11/9 下午2:37, Richard Henderson wrote:
>>
>>> On 11/8/21 10:28 AM, LIU Zhiwei wrote:
>>>> On 2021/11/1 下午7:35, Richard Henderson wrote:
>>>>
>>>>> On 11/1/21 6:01 AM, LIU Zhiwei wrote:
>>>>>> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
>>>>>> ---
>>>>>>   target/riscv/insn_trans/trans_rvv.c.inc |  8 ++++
>>>>>>   target/riscv/internals.h                |  1 +
>>>>>>   target/riscv/vector_helper.c            | 54 
>>>>>> +++++++++++++++++--------
>>>>>>   3 files changed, 46 insertions(+), 17 deletions(-)
>>>>>>
>>>>>> diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
>>>>>> b/target/riscv/insn_trans/trans_rvv.c.inc
>>>>>> index ed042f7bb9..5cd9b802df 100644
>>>>>> --- a/target/riscv/insn_trans/trans_rvv.c.inc
>>>>>> +++ b/target/riscv/insn_trans/trans_rvv.c.inc
>>>>>> @@ -233,6 +233,7 @@ static bool ld_us_op(DisasContext *s, 
>>>>>> arg_r2nfvm *a, uint8_t seq)
>>>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>>>       return ldst_us_trans(a->rd, a->rs1, data, fn, s);
>>>>>>   }
>>>>>>   @@ -286,6 +287,7 @@ static bool st_us_op(DisasContext *s, 
>>>>>> arg_r2nfvm *a, uint8_t seq)
>>>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>>>       return ldst_us_trans(a->rd, a->rs1, data, fn, s);
>>>>>>   }
>>>>>>   @@ -365,6 +367,7 @@ static bool ld_stride_op(DisasContext *s, 
>>>>>> arg_rnfvm *a, uint8_t seq)
>>>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>>>       return ldst_stride_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>>>>>>   }
>>>>>>   @@ -404,6 +407,7 @@ static bool st_stride_op(DisasContext *s, 
>>>>>> arg_rnfvm *a, uint8_t seq)
>>>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>>>       fn =  fns[seq][s->sew];
>>>>>>       if (fn == NULL) {
>>>>>>           return false;
>>>>>> @@ -490,6 +494,7 @@ static bool ld_index_op(DisasContext *s, 
>>>>>> arg_rnfvm *a, uint8_t seq)
>>>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>>>       return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>>>>>>   }
>>>>>>   @@ -542,6 +547,7 @@ static bool st_index_op(DisasContext *s, 
>>>>>> arg_rnfvm *a, uint8_t seq)
>>>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>>>       return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>>>>>>   }
>>>>>>   @@ -617,6 +623,7 @@ static bool ldff_op(DisasContext *s, 
>>>>>> arg_r2nfvm *a, uint8_t seq)
>>>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>>>       return ldff_trans(a->rd, a->rs1, data, fn, s);
>>>>>>   }
>>>>>>   @@ -724,6 +731,7 @@ static bool amo_op(DisasContext *s, 
>>>>>> arg_rwdvm *a, uint8_t seq)
>>>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>>>       data = FIELD_DP32(data, VDATA, WD, a->wd);
>>>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>>>       return amo_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>>>>>>   }
>>>>>>   /*
>>>>>> diff --git a/target/riscv/internals.h b/target/riscv/internals.h
>>>>>> index b15ad394bb..f74b8291e4 100644
>>>>>> --- a/target/riscv/internals.h
>>>>>> +++ b/target/riscv/internals.h
>>>>>> @@ -27,6 +27,7 @@ FIELD(VDATA, VM, 8, 1)
>>>>>>   FIELD(VDATA, LMUL, 9, 2)
>>>>>>   FIELD(VDATA, NF, 11, 4)
>>>>>>   FIELD(VDATA, WD, 11, 1)
>>>>>> +FIELD(VDATA, OL, 15, 2)
>>>>>>     /* float point classify helpers */
>>>>>>   target_ulong fclass_h(uint64_t frs1);
>>>>>> diff --git a/target/riscv/vector_helper.c 
>>>>>> b/target/riscv/vector_helper.c
>>>>>> index 535420ee66..451688c328 100644
>>>>>> --- a/target/riscv/vector_helper.c
>>>>>> +++ b/target/riscv/vector_helper.c
>>>>>> @@ -112,6 +112,11 @@ static uint32_t vext_wd(uint32_t desc)
>>>>>>       return (simd_data(desc) >> 11) & 0x1;
>>>>>>   }
>>>>>>   +static inline uint32_t vext_ol(uint32_t desc)
>>>>>> +{
>>>>>> +    return FIELD_EX32(simd_data(desc), VDATA, OL);
>>>>>> +}
>>>>>
>>>>> XLEN not OLEN.
>>>> OK.
>>>>>
>>>>>> @@ -123,6 +128,14 @@ static inline uint32_t vext_maxsz(uint32_t 
>>>>>> desc)
>>>>>>       return simd_maxsz(desc) << vext_lmul(desc);
>>>>>>   }
>>>>>>   +static inline target_ulong adjust_addr(target_ulong addr, 
>>>>>> uint32_t olen)
>>>>>> +{
>>>>>> +    if (olen < TARGET_LONG_BITS) {
>>>>>> +        addr &= UINT32_MAX;
>>>>>> +    }
>>>>>> +    return addr;
>>>>>> +}
>>>>>
>>>>> Here's where I'm unsure.  This looks a lot like the changes that 
>>>>> are required to support pointer-masking in vectors, which Alexey 
>>>>> said he was going to look at.
>>>>>
>>>>> (1) Do we need to pass anything in VEXT at all?
>>>>>     We do have CPURISCVState, so we could just use cpu_get_ml,
>>>> Yes, we should use cpu_get_xl.
>>>>> which we would also need for env->mmte etc for pointer masking.
>>>>
>>>> Do you mean env->mpmmask and env->mpmbase? I think yes, we should 
>>>> also adjust these register behaviors with xlen.
>>>
>>> I mean the set of [msu]pmmask and [msu]pmbase, selected as 
>>> appropriate for the current execution mode.
>>>
>>>>> (3) Do we try to streamline the computation by passing down composite
>>>>>     mask and base parameters.  This way we don't need to do complex
>>>>>     examination of ENV to determine execution mode, and instead 
>>>>> always
>>>>>     compute
>>>>>
>>>>>        addr = (addr & mask) | base;
>>>>>
>>>>>     where mask = -1, base = 0 for "normal" addressing, and when
>>>>>     UXLEN == 32, mask <= UINT32_MAX.
>>>>
>>>> Do you mean add env->pmmask and env->pmbase?
>>>>
>>>> I can initialize them in riscv_tr_init_disas_context, such as by 
>>>> env->xpmmask & UINT32_MAX .
>>>>
>>>>>
>>>>> (4) Do we in fact want to pre-compute these into known slots on ENV,
>>>>>     so that we don't have to pass these around as separate 
>>>>> parameters?
>>>>>     We would adjust these values during PM CSR changes and when
>>>>>     changing privilege levels.
>>> For option (3), I was suggesting a mask + base pair passed down from 
>>> TCG-generated code.
>>>
>>> For option (4), I was suggesting embedding a mask + base pair in 
>>> env, which would be re-computed at every privilege level change, 
>>> plus reset and vmload.
>>>
>>> In both cases, the mask would be a combination of [msu]pmmask & 
>>> (RV32 ? UINT32_MAX : UINT64_MAX), as you say.
>>
>> We will calculate [msu]pmmask by  csrrw , and we have ignored high 
>> bits there.
>>
>> Can we just use the [msu]pmmmask?
>
> We could.  However:
>
> In order to select [msu]pmmask, we have to look up the current cpu 
> state.  In order to mask the high bits, we have to look up the current 
> xl, which requires that we look up the current cpu state then extract 
> the xl from misa  and mstatus.
>
> All of which means that we're doing repeated lookups for every memory 
> access.  I am suggesting that we either (3) compile those lookups into 
> the generated code or (4) cache those lookups when state changes (csr 
> writes and priv changes).


Do you mean we should add this code to riscv_tr_init_disas_context

     if (ctx->pm_enabled) {
          switch (priv) {
          case PRV_M:
              env->mask = env->mpmmask;
              env->base = env->mpmbase;
              break;
          case PRV_S:
              env->mask = env->spmmask;
              env->base = env->spmbase;
              break;
          case PRV_U:
              env->mask = env->upmmask;
              env->base = env->upmbase;
              break;
          default:
              g_assert_not_reached();
          }
          ctx->pm_mask = pm_mask[priv];
          ctx->pm_base = pm_base[priv];
          ctx->need_mask = true; /* new flag for mask */

      } else if (get_xlen(ctx)  < TARGET_LONG_BITS) {
          env->mask = UINT32_MAX;
          env->base = 0;
          ctx->pm_mask = tcg_constant_tl(UINT32_MAX);
          ctx->pm_base = tcg_constant_tl(0);

         ctx->need_mask = true;

      } else {
	 env->mask = UINT64_MAX;
          env->base = 0;
      }

Thanks,
Zhiwei

>
>
> r~

[-- Attachment #2: Type: text/html, Size: 15758 bytes --]

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

* Re: [PATCH 09/13] target/riscv: Adjust vector address with ol
  2021-11-09  8:39               ` LIU Zhiwei
@ 2021-11-09  9:05                 ` LIU Zhiwei
  -1 siblings, 0 replies; 88+ messages in thread
From: LIU Zhiwei @ 2021-11-09  9:05 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel, qemu-riscv, Alexey Baturo
  Cc: Alistair.Francis, bin.meng, palmer

[-- Attachment #1: Type: text/plain, Size: 10180 bytes --]


On 2021/11/9 下午4:39, LIU Zhiwei wrote:
>
>
> On 2021/11/9 下午4:18, Richard Henderson wrote:
>> On 11/9/21 9:04 AM, LIU Zhiwei wrote:
>>> On 2021/11/9 下午2:37, Richard Henderson wrote:
>>>
>>>> On 11/8/21 10:28 AM, LIU Zhiwei wrote:
>>>>> On 2021/11/1 下午7:35, Richard Henderson wrote:
>>>>>
>>>>>> On 11/1/21 6:01 AM, LIU Zhiwei wrote:
>>>>>>> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
>>>>>>> ---
>>>>>>>   target/riscv/insn_trans/trans_rvv.c.inc |  8 ++++
>>>>>>>   target/riscv/internals.h                |  1 +
>>>>>>>   target/riscv/vector_helper.c            | 54 
>>>>>>> +++++++++++++++++--------
>>>>>>>   3 files changed, 46 insertions(+), 17 deletions(-)
>>>>>>>
>>>>>>> diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
>>>>>>> b/target/riscv/insn_trans/trans_rvv.c.inc
>>>>>>> index ed042f7bb9..5cd9b802df 100644
>>>>>>> --- a/target/riscv/insn_trans/trans_rvv.c.inc
>>>>>>> +++ b/target/riscv/insn_trans/trans_rvv.c.inc
>>>>>>> @@ -233,6 +233,7 @@ static bool ld_us_op(DisasContext *s, 
>>>>>>> arg_r2nfvm *a, uint8_t seq)
>>>>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>>>>       return ldst_us_trans(a->rd, a->rs1, data, fn, s);
>>>>>>>   }
>>>>>>>   @@ -286,6 +287,7 @@ static bool st_us_op(DisasContext *s, 
>>>>>>> arg_r2nfvm *a, uint8_t seq)
>>>>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>>>>       return ldst_us_trans(a->rd, a->rs1, data, fn, s);
>>>>>>>   }
>>>>>>>   @@ -365,6 +367,7 @@ static bool ld_stride_op(DisasContext *s, 
>>>>>>> arg_rnfvm *a, uint8_t seq)
>>>>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>>>>       return ldst_stride_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>>>>>>>   }
>>>>>>>   @@ -404,6 +407,7 @@ static bool st_stride_op(DisasContext *s, 
>>>>>>> arg_rnfvm *a, uint8_t seq)
>>>>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>>>>       fn =  fns[seq][s->sew];
>>>>>>>       if (fn == NULL) {
>>>>>>>           return false;
>>>>>>> @@ -490,6 +494,7 @@ static bool ld_index_op(DisasContext *s, 
>>>>>>> arg_rnfvm *a, uint8_t seq)
>>>>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>>>>       return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>>>>>>>   }
>>>>>>>   @@ -542,6 +547,7 @@ static bool st_index_op(DisasContext *s, 
>>>>>>> arg_rnfvm *a, uint8_t seq)
>>>>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>>>>       return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>>>>>>>   }
>>>>>>>   @@ -617,6 +623,7 @@ static bool ldff_op(DisasContext *s, 
>>>>>>> arg_r2nfvm *a, uint8_t seq)
>>>>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>>>>       return ldff_trans(a->rd, a->rs1, data, fn, s);
>>>>>>>   }
>>>>>>>   @@ -724,6 +731,7 @@ static bool amo_op(DisasContext *s, 
>>>>>>> arg_rwdvm *a, uint8_t seq)
>>>>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>>>>       data = FIELD_DP32(data, VDATA, WD, a->wd);
>>>>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>>>>       return amo_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>>>>>>>   }
>>>>>>>   /*
>>>>>>> diff --git a/target/riscv/internals.h b/target/riscv/internals.h
>>>>>>> index b15ad394bb..f74b8291e4 100644
>>>>>>> --- a/target/riscv/internals.h
>>>>>>> +++ b/target/riscv/internals.h
>>>>>>> @@ -27,6 +27,7 @@ FIELD(VDATA, VM, 8, 1)
>>>>>>>   FIELD(VDATA, LMUL, 9, 2)
>>>>>>>   FIELD(VDATA, NF, 11, 4)
>>>>>>>   FIELD(VDATA, WD, 11, 1)
>>>>>>> +FIELD(VDATA, OL, 15, 2)
>>>>>>>     /* float point classify helpers */
>>>>>>>   target_ulong fclass_h(uint64_t frs1);
>>>>>>> diff --git a/target/riscv/vector_helper.c 
>>>>>>> b/target/riscv/vector_helper.c
>>>>>>> index 535420ee66..451688c328 100644
>>>>>>> --- a/target/riscv/vector_helper.c
>>>>>>> +++ b/target/riscv/vector_helper.c
>>>>>>> @@ -112,6 +112,11 @@ static uint32_t vext_wd(uint32_t desc)
>>>>>>>       return (simd_data(desc) >> 11) & 0x1;
>>>>>>>   }
>>>>>>>   +static inline uint32_t vext_ol(uint32_t desc)
>>>>>>> +{
>>>>>>> +    return FIELD_EX32(simd_data(desc), VDATA, OL);
>>>>>>> +}
>>>>>>
>>>>>> XLEN not OLEN.
>>>>> OK.
>>>>>>
>>>>>>> @@ -123,6 +128,14 @@ static inline uint32_t vext_maxsz(uint32_t 
>>>>>>> desc)
>>>>>>>       return simd_maxsz(desc) << vext_lmul(desc);
>>>>>>>   }
>>>>>>>   +static inline target_ulong adjust_addr(target_ulong addr, 
>>>>>>> uint32_t olen)
>>>>>>> +{
>>>>>>> +    if (olen < TARGET_LONG_BITS) {
>>>>>>> +        addr &= UINT32_MAX;
>>>>>>> +    }
>>>>>>> +    return addr;
>>>>>>> +}
>>>>>>
>>>>>> Here's where I'm unsure.  This looks a lot like the changes that 
>>>>>> are required to support pointer-masking in vectors, which Alexey 
>>>>>> said he was going to look at.
>>>>>>
>>>>>> (1) Do we need to pass anything in VEXT at all?
>>>>>>     We do have CPURISCVState, so we could just use cpu_get_ml,
>>>>> Yes, we should use cpu_get_xl.
>>>>>> which we would also need for env->mmte etc for pointer masking.
>>>>>
>>>>> Do you mean env->mpmmask and env->mpmbase? I think yes, we should 
>>>>> also adjust these register behaviors with xlen.
>>>>
>>>> I mean the set of [msu]pmmask and [msu]pmbase, selected as 
>>>> appropriate for the current execution mode.
>>>>
>>>>>> (3) Do we try to streamline the computation by passing down 
>>>>>> composite
>>>>>>     mask and base parameters.  This way we don't need to do complex
>>>>>>     examination of ENV to determine execution mode, and instead 
>>>>>> always
>>>>>>     compute
>>>>>>
>>>>>>        addr = (addr & mask) | base;
>>>>>>
>>>>>>     where mask = -1, base = 0 for "normal" addressing, and when
>>>>>>     UXLEN == 32, mask <= UINT32_MAX.
>>>>>
>>>>> Do you mean add env->pmmask and env->pmbase?
>>>>>
>>>>> I can initialize them in riscv_tr_init_disas_context, such as by 
>>>>> env->xpmmask & UINT32_MAX .
>>>>>
>>>>>>
>>>>>> (4) Do we in fact want to pre-compute these into known slots on ENV,
>>>>>>     so that we don't have to pass these around as separate 
>>>>>> parameters?
>>>>>>     We would adjust these values during PM CSR changes and when
>>>>>>     changing privilege levels.
>>>> For option (3), I was suggesting a mask + base pair passed down 
>>>> from TCG-generated code.
>>>>
>>>> For option (4), I was suggesting embedding a mask + base pair in 
>>>> env, which would be re-computed at every privilege level change, 
>>>> plus reset and vmload.
>>>>
>>>> In both cases, the mask would be a combination of [msu]pmmask & 
>>>> (RV32 ? UINT32_MAX : UINT64_MAX), as you say.
>>>
>>> We will calculate [msu]pmmask by  csrrw , and we have ignored high 
>>> bits there.
>>>
>>> Can we just use the [msu]pmmmask?
>>
>> We could.  However:
>>
>> In order to select [msu]pmmask, we have to look up the current cpu 
>> state.  In order to mask the high bits, we have to look up the 
>> current xl, which requires that we look up the current cpu state then 
>> extract the xl from misa  and mstatus.
>>
>> All of which means that we're doing repeated lookups for every memory 
>> access.  I am suggesting that we either (3) compile those lookups 
>> into the generated code or (4) cache those lookups when state changes 
>> (csr writes and priv changes).
>
>
> Do you mean we should add this code to riscv_tr_init_disas_context
>
>      if (ctx->pm_enabled) {
>           switch (priv) {
>           case PRV_M:
>               env->mask = env->mpmmask;
>               env->base = env->mpmbase;
>               break;
>           case PRV_S:
>               env->mask = env->spmmask;
>               env->base = env->spmbase;
>               break;
>           case PRV_U:
>               env->mask = env->upmmask;
>               env->base = env->upmbase;
>               break;
>           default:
>               g_assert_not_reached();
>           }
>           ctx->pm_mask = pm_mask[priv];
>           ctx->pm_base = pm_base[priv];
>           ctx->need_mask = true; /* new flag for mask */
>       } else if (get_xlen(ctx)  < TARGET_LONG_BITS) {
>           env->mask = UINT32_MAX;
>           env->base = 0;
>           ctx->pm_mask = tcg_constant_tl(UINT32_MAX);
>           ctx->pm_base = tcg_constant_tl(0);
>          ctx->need_mask = true;
>       } else {
> 	 env->mask = UINT64_MAX;
>           env->base = 0;
>       }

I think the code is wrong, perhaps we should modify the write_mpmmask
env->mask = env->mpmmask = value;

Zhiwei

> Thanks,
> Zhiwei
>>
>>
>> r~

[-- Attachment #2: Type: text/html, Size: 15166 bytes --]

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

* Re: [PATCH 09/13] target/riscv: Adjust vector address with ol
@ 2021-11-09  9:05                 ` LIU Zhiwei
  0 siblings, 0 replies; 88+ messages in thread
From: LIU Zhiwei @ 2021-11-09  9:05 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel, qemu-riscv, Alexey Baturo
  Cc: palmer, bin.meng, Alistair.Francis

[-- Attachment #1: Type: text/plain, Size: 10180 bytes --]


On 2021/11/9 下午4:39, LIU Zhiwei wrote:
>
>
> On 2021/11/9 下午4:18, Richard Henderson wrote:
>> On 11/9/21 9:04 AM, LIU Zhiwei wrote:
>>> On 2021/11/9 下午2:37, Richard Henderson wrote:
>>>
>>>> On 11/8/21 10:28 AM, LIU Zhiwei wrote:
>>>>> On 2021/11/1 下午7:35, Richard Henderson wrote:
>>>>>
>>>>>> On 11/1/21 6:01 AM, LIU Zhiwei wrote:
>>>>>>> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
>>>>>>> ---
>>>>>>>   target/riscv/insn_trans/trans_rvv.c.inc |  8 ++++
>>>>>>>   target/riscv/internals.h                |  1 +
>>>>>>>   target/riscv/vector_helper.c            | 54 
>>>>>>> +++++++++++++++++--------
>>>>>>>   3 files changed, 46 insertions(+), 17 deletions(-)
>>>>>>>
>>>>>>> diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
>>>>>>> b/target/riscv/insn_trans/trans_rvv.c.inc
>>>>>>> index ed042f7bb9..5cd9b802df 100644
>>>>>>> --- a/target/riscv/insn_trans/trans_rvv.c.inc
>>>>>>> +++ b/target/riscv/insn_trans/trans_rvv.c.inc
>>>>>>> @@ -233,6 +233,7 @@ static bool ld_us_op(DisasContext *s, 
>>>>>>> arg_r2nfvm *a, uint8_t seq)
>>>>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>>>>       return ldst_us_trans(a->rd, a->rs1, data, fn, s);
>>>>>>>   }
>>>>>>>   @@ -286,6 +287,7 @@ static bool st_us_op(DisasContext *s, 
>>>>>>> arg_r2nfvm *a, uint8_t seq)
>>>>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>>>>       return ldst_us_trans(a->rd, a->rs1, data, fn, s);
>>>>>>>   }
>>>>>>>   @@ -365,6 +367,7 @@ static bool ld_stride_op(DisasContext *s, 
>>>>>>> arg_rnfvm *a, uint8_t seq)
>>>>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>>>>       return ldst_stride_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>>>>>>>   }
>>>>>>>   @@ -404,6 +407,7 @@ static bool st_stride_op(DisasContext *s, 
>>>>>>> arg_rnfvm *a, uint8_t seq)
>>>>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>>>>       fn =  fns[seq][s->sew];
>>>>>>>       if (fn == NULL) {
>>>>>>>           return false;
>>>>>>> @@ -490,6 +494,7 @@ static bool ld_index_op(DisasContext *s, 
>>>>>>> arg_rnfvm *a, uint8_t seq)
>>>>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>>>>       return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>>>>>>>   }
>>>>>>>   @@ -542,6 +547,7 @@ static bool st_index_op(DisasContext *s, 
>>>>>>> arg_rnfvm *a, uint8_t seq)
>>>>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>>>>       return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>>>>>>>   }
>>>>>>>   @@ -617,6 +623,7 @@ static bool ldff_op(DisasContext *s, 
>>>>>>> arg_r2nfvm *a, uint8_t seq)
>>>>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>>>>       data = FIELD_DP32(data, VDATA, NF, a->nf);
>>>>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>>>>       return ldff_trans(a->rd, a->rs1, data, fn, s);
>>>>>>>   }
>>>>>>>   @@ -724,6 +731,7 @@ static bool amo_op(DisasContext *s, 
>>>>>>> arg_rwdvm *a, uint8_t seq)
>>>>>>>       data = FIELD_DP32(data, VDATA, VM, a->vm);
>>>>>>>       data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
>>>>>>>       data = FIELD_DP32(data, VDATA, WD, a->wd);
>>>>>>> +    data = FIELD_DP32(data, VDATA, OL, s->ol);
>>>>>>>       return amo_trans(a->rd, a->rs1, a->rs2, data, fn, s);
>>>>>>>   }
>>>>>>>   /*
>>>>>>> diff --git a/target/riscv/internals.h b/target/riscv/internals.h
>>>>>>> index b15ad394bb..f74b8291e4 100644
>>>>>>> --- a/target/riscv/internals.h
>>>>>>> +++ b/target/riscv/internals.h
>>>>>>> @@ -27,6 +27,7 @@ FIELD(VDATA, VM, 8, 1)
>>>>>>>   FIELD(VDATA, LMUL, 9, 2)
>>>>>>>   FIELD(VDATA, NF, 11, 4)
>>>>>>>   FIELD(VDATA, WD, 11, 1)
>>>>>>> +FIELD(VDATA, OL, 15, 2)
>>>>>>>     /* float point classify helpers */
>>>>>>>   target_ulong fclass_h(uint64_t frs1);
>>>>>>> diff --git a/target/riscv/vector_helper.c 
>>>>>>> b/target/riscv/vector_helper.c
>>>>>>> index 535420ee66..451688c328 100644
>>>>>>> --- a/target/riscv/vector_helper.c
>>>>>>> +++ b/target/riscv/vector_helper.c
>>>>>>> @@ -112,6 +112,11 @@ static uint32_t vext_wd(uint32_t desc)
>>>>>>>       return (simd_data(desc) >> 11) & 0x1;
>>>>>>>   }
>>>>>>>   +static inline uint32_t vext_ol(uint32_t desc)
>>>>>>> +{
>>>>>>> +    return FIELD_EX32(simd_data(desc), VDATA, OL);
>>>>>>> +}
>>>>>>
>>>>>> XLEN not OLEN.
>>>>> OK.
>>>>>>
>>>>>>> @@ -123,6 +128,14 @@ static inline uint32_t vext_maxsz(uint32_t 
>>>>>>> desc)
>>>>>>>       return simd_maxsz(desc) << vext_lmul(desc);
>>>>>>>   }
>>>>>>>   +static inline target_ulong adjust_addr(target_ulong addr, 
>>>>>>> uint32_t olen)
>>>>>>> +{
>>>>>>> +    if (olen < TARGET_LONG_BITS) {
>>>>>>> +        addr &= UINT32_MAX;
>>>>>>> +    }
>>>>>>> +    return addr;
>>>>>>> +}
>>>>>>
>>>>>> Here's where I'm unsure.  This looks a lot like the changes that 
>>>>>> are required to support pointer-masking in vectors, which Alexey 
>>>>>> said he was going to look at.
>>>>>>
>>>>>> (1) Do we need to pass anything in VEXT at all?
>>>>>>     We do have CPURISCVState, so we could just use cpu_get_ml,
>>>>> Yes, we should use cpu_get_xl.
>>>>>> which we would also need for env->mmte etc for pointer masking.
>>>>>
>>>>> Do you mean env->mpmmask and env->mpmbase? I think yes, we should 
>>>>> also adjust these register behaviors with xlen.
>>>>
>>>> I mean the set of [msu]pmmask and [msu]pmbase, selected as 
>>>> appropriate for the current execution mode.
>>>>
>>>>>> (3) Do we try to streamline the computation by passing down 
>>>>>> composite
>>>>>>     mask and base parameters.  This way we don't need to do complex
>>>>>>     examination of ENV to determine execution mode, and instead 
>>>>>> always
>>>>>>     compute
>>>>>>
>>>>>>        addr = (addr & mask) | base;
>>>>>>
>>>>>>     where mask = -1, base = 0 for "normal" addressing, and when
>>>>>>     UXLEN == 32, mask <= UINT32_MAX.
>>>>>
>>>>> Do you mean add env->pmmask and env->pmbase?
>>>>>
>>>>> I can initialize them in riscv_tr_init_disas_context, such as by 
>>>>> env->xpmmask & UINT32_MAX .
>>>>>
>>>>>>
>>>>>> (4) Do we in fact want to pre-compute these into known slots on ENV,
>>>>>>     so that we don't have to pass these around as separate 
>>>>>> parameters?
>>>>>>     We would adjust these values during PM CSR changes and when
>>>>>>     changing privilege levels.
>>>> For option (3), I was suggesting a mask + base pair passed down 
>>>> from TCG-generated code.
>>>>
>>>> For option (4), I was suggesting embedding a mask + base pair in 
>>>> env, which would be re-computed at every privilege level change, 
>>>> plus reset and vmload.
>>>>
>>>> In both cases, the mask would be a combination of [msu]pmmask & 
>>>> (RV32 ? UINT32_MAX : UINT64_MAX), as you say.
>>>
>>> We will calculate [msu]pmmask by  csrrw , and we have ignored high 
>>> bits there.
>>>
>>> Can we just use the [msu]pmmmask?
>>
>> We could.  However:
>>
>> In order to select [msu]pmmask, we have to look up the current cpu 
>> state.  In order to mask the high bits, we have to look up the 
>> current xl, which requires that we look up the current cpu state then 
>> extract the xl from misa  and mstatus.
>>
>> All of which means that we're doing repeated lookups for every memory 
>> access.  I am suggesting that we either (3) compile those lookups 
>> into the generated code or (4) cache those lookups when state changes 
>> (csr writes and priv changes).
>
>
> Do you mean we should add this code to riscv_tr_init_disas_context
>
>      if (ctx->pm_enabled) {
>           switch (priv) {
>           case PRV_M:
>               env->mask = env->mpmmask;
>               env->base = env->mpmbase;
>               break;
>           case PRV_S:
>               env->mask = env->spmmask;
>               env->base = env->spmbase;
>               break;
>           case PRV_U:
>               env->mask = env->upmmask;
>               env->base = env->upmbase;
>               break;
>           default:
>               g_assert_not_reached();
>           }
>           ctx->pm_mask = pm_mask[priv];
>           ctx->pm_base = pm_base[priv];
>           ctx->need_mask = true; /* new flag for mask */
>       } else if (get_xlen(ctx)  < TARGET_LONG_BITS) {
>           env->mask = UINT32_MAX;
>           env->base = 0;
>           ctx->pm_mask = tcg_constant_tl(UINT32_MAX);
>           ctx->pm_base = tcg_constant_tl(0);
>          ctx->need_mask = true;
>       } else {
> 	 env->mask = UINT64_MAX;
>           env->base = 0;
>       }

I think the code is wrong, perhaps we should modify the write_mpmmask
env->mask = env->mpmmask = value;

Zhiwei

> Thanks,
> Zhiwei
>>
>>
>> r~

[-- Attachment #2: Type: text/html, Size: 15166 bytes --]

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

* Re: [PATCH 09/13] target/riscv: Adjust vector address with ol
  2021-11-09  9:05                 ` LIU Zhiwei
@ 2021-11-09  9:25                   ` Richard Henderson
  -1 siblings, 0 replies; 88+ messages in thread
From: Richard Henderson @ 2021-11-09  9:25 UTC (permalink / raw)
  To: LIU Zhiwei, qemu-devel, qemu-riscv, Alexey Baturo
  Cc: Alistair.Francis, bin.meng, palmer

On 11/9/21 10:05 AM, LIU Zhiwei wrote:
>> Do you mean we should add this code to riscv_tr_init_disas_context
>>
>>      if (ctx->pm_enabled) {
>>           switch (priv) {
>>           case PRV_M:
>>               env->mask = env->mpmmask;
>>               env->base = env->mpmbase;
>>               break;
>>           case PRV_S:
>>               env->mask = env->spmmask;
>>               env->base = env->spmbase;
>>               break;
>>           case PRV_U:
>>               env->mask = env->upmmask;
>>               env->base = env->upmbase;
>>               break;
>>           default:
>>               g_assert_not_reached();
>>           }
>>           ctx->pm_mask = pm_mask[priv];
>>           ctx->pm_base = pm_base[priv];
>>           ctx->need_mask = true; /* new flag for mask */
>>       } else if (get_xlen(ctx)  < TARGET_LONG_BITS) {
>>           env->mask = UINT32_MAX;
>>           env->base = 0;

Certainly we cannot modify env in riscv_tr_init_disas_context.

>>           ctx->pm_mask = tcg_constant_tl(UINT32_MAX);
>>           ctx->pm_base = tcg_constant_tl(0);
>>          ctx->need_mask = true;
>>       } else {
>> 	 env->mask = UINT64_MAX;
>>           env->base = 0;
>>       }
> 
> I think the code is wrong, perhaps we should modify the write_mpmmask
> env->mask = env->mpmmask = value;

Something like that, yes.  However, env->mask must be set based on env->priv, etc; you 
can't just assign the same as mpmmask.

Then you also need to update env->mask in a hook like you created in patch 11 to switch 
context (though I would call it from helper_mret and helper_sret directly, and not create 
a new call from tcg).  Then you need to call the hook as well on exception entry, reset, 
and vmstate_riscv_cpu.post_load.


r~


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

* Re: [PATCH 09/13] target/riscv: Adjust vector address with ol
@ 2021-11-09  9:25                   ` Richard Henderson
  0 siblings, 0 replies; 88+ messages in thread
From: Richard Henderson @ 2021-11-09  9:25 UTC (permalink / raw)
  To: LIU Zhiwei, qemu-devel, qemu-riscv, Alexey Baturo
  Cc: palmer, bin.meng, Alistair.Francis

On 11/9/21 10:05 AM, LIU Zhiwei wrote:
>> Do you mean we should add this code to riscv_tr_init_disas_context
>>
>>      if (ctx->pm_enabled) {
>>           switch (priv) {
>>           case PRV_M:
>>               env->mask = env->mpmmask;
>>               env->base = env->mpmbase;
>>               break;
>>           case PRV_S:
>>               env->mask = env->spmmask;
>>               env->base = env->spmbase;
>>               break;
>>           case PRV_U:
>>               env->mask = env->upmmask;
>>               env->base = env->upmbase;
>>               break;
>>           default:
>>               g_assert_not_reached();
>>           }
>>           ctx->pm_mask = pm_mask[priv];
>>           ctx->pm_base = pm_base[priv];
>>           ctx->need_mask = true; /* new flag for mask */
>>       } else if (get_xlen(ctx)  < TARGET_LONG_BITS) {
>>           env->mask = UINT32_MAX;
>>           env->base = 0;

Certainly we cannot modify env in riscv_tr_init_disas_context.

>>           ctx->pm_mask = tcg_constant_tl(UINT32_MAX);
>>           ctx->pm_base = tcg_constant_tl(0);
>>          ctx->need_mask = true;
>>       } else {
>> 	 env->mask = UINT64_MAX;
>>           env->base = 0;
>>       }
> 
> I think the code is wrong, perhaps we should modify the write_mpmmask
> env->mask = env->mpmmask = value;

Something like that, yes.  However, env->mask must be set based on env->priv, etc; you 
can't just assign the same as mpmmask.

Then you also need to update env->mask in a hook like you created in patch 11 to switch 
context (though I would call it from helper_mret and helper_sret directly, and not create 
a new call from tcg).  Then you need to call the hook as well on exception entry, reset, 
and vmstate_riscv_cpu.post_load.


r~


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

* Re: [PATCH 13/13] target/riscv: Enable uxl field write
  2021-11-01 17:01     ` Richard Henderson
@ 2021-11-10  3:01       ` LIU Zhiwei
  -1 siblings, 0 replies; 88+ messages in thread
From: LIU Zhiwei @ 2021-11-10  3:01 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel, qemu-riscv
  Cc: palmer, bin.meng, Alistair.Francis


On 2021/11/2 上午1:01, Richard Henderson wrote:
> On 11/1/21 6:01 AM, LIU Zhiwei wrote:
>>           mask |= MSTATUS_MPV | MSTATUS_GVA;
>> +        if ((val ^ mstatus) & MSTATUS64_UXL) {
>> +            mask |= MSTATUS64_UXL;
>> +        }
>
> Why do you need the conditional here?
> Why is this not just
>
>     mask |= MSTATUS_MPV | MSTATUS_GVA | MSTATUS64_UXL;
>
>
>>  static bool trans_csrrw(DisasContext *ctx, arg_csrrw *a)
>>  {
>> -    TCGv src = get_gpr(ctx, a->rs1, EXT_NONE);
>> +    TCGv src = get_gpr(ctx, a->rs1, EXT_ZERO);
>
> Hmm.  Not sure about this.
>
> It looks like we should in fact change mask, just a few lines down, at 
> which point the extension (or not) for the source would not matter.  
> And likewise in trans_csrrwi.

Is there some benefits to use mask?
I see there is still a do_csrw, and we can't give it a mask at 
translation time.

Thanks,
Zhiwei

>
>
> r~


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

* Re: [PATCH 13/13] target/riscv: Enable uxl field write
@ 2021-11-10  3:01       ` LIU Zhiwei
  0 siblings, 0 replies; 88+ messages in thread
From: LIU Zhiwei @ 2021-11-10  3:01 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel, qemu-riscv
  Cc: Alistair.Francis, palmer, bin.meng


On 2021/11/2 上午1:01, Richard Henderson wrote:
> On 11/1/21 6:01 AM, LIU Zhiwei wrote:
>>           mask |= MSTATUS_MPV | MSTATUS_GVA;
>> +        if ((val ^ mstatus) & MSTATUS64_UXL) {
>> +            mask |= MSTATUS64_UXL;
>> +        }
>
> Why do you need the conditional here?
> Why is this not just
>
>     mask |= MSTATUS_MPV | MSTATUS_GVA | MSTATUS64_UXL;
>
>
>>  static bool trans_csrrw(DisasContext *ctx, arg_csrrw *a)
>>  {
>> -    TCGv src = get_gpr(ctx, a->rs1, EXT_NONE);
>> +    TCGv src = get_gpr(ctx, a->rs1, EXT_ZERO);
>
> Hmm.  Not sure about this.
>
> It looks like we should in fact change mask, just a few lines down, at 
> which point the extension (or not) for the source would not matter.  
> And likewise in trans_csrrwi.

Is there some benefits to use mask?
I see there is still a do_csrw, and we can't give it a mask at 
translation time.

Thanks,
Zhiwei

>
>
> r~


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

end of thread, other threads:[~2021-11-10  3:02 UTC | newest]

Thread overview: 88+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-01 10:01 [PATCH 00/13] Support UXL filed in xstatus LIU Zhiwei
2021-11-01 10:01 ` LIU Zhiwei
2021-11-01 10:01 ` [PATCH 01/13] target/riscv: Sign extend pc for different ol LIU Zhiwei
2021-11-01 10:01   ` LIU Zhiwei
2021-11-01 10:29   ` Richard Henderson
2021-11-01 10:29     ` Richard Henderson
2021-11-01 10:01 ` [PATCH 02/13] target/riscv: Extend pc for runtime pc write LIU Zhiwei
2021-11-01 10:01   ` LIU Zhiwei
2021-11-01 10:33   ` Richard Henderson
2021-11-01 10:33     ` Richard Henderson
2021-11-02  1:48     ` LIU Zhiwei
2021-11-02  1:48       ` LIU Zhiwei
2021-11-02 10:18       ` Richard Henderson
2021-11-02 10:18         ` Richard Henderson
2021-11-01 10:01 ` [PATCH 03/13] target/riscv: Ignore the pc bits above XLEN LIU Zhiwei
2021-11-01 10:01   ` LIU Zhiwei
2021-11-01 10:35   ` Richard Henderson
2021-11-01 10:35     ` Richard Henderson
2021-11-02 10:20   ` Richard Henderson
2021-11-02 10:20     ` Richard Henderson
2021-11-01 10:01 ` [PATCH 04/13] target/riscv: Use gdb xml according to max mxlen LIU Zhiwei
2021-11-01 10:01   ` LIU Zhiwei
2021-11-01 10:40   ` Richard Henderson
2021-11-01 10:40     ` Richard Henderson
2021-11-01 10:01 ` [PATCH 05/13] target/riscv: Calculate address according to ol LIU Zhiwei
2021-11-01 10:01   ` LIU Zhiwei
2021-11-01 10:46   ` Richard Henderson
2021-11-01 10:46     ` Richard Henderson
2021-11-01 15:56     ` LIU Zhiwei
2021-11-01 15:56       ` LIU Zhiwei
2021-11-01 10:01 ` [PATCH 06/13] target/riscv: Adjust vsetvl " LIU Zhiwei
2021-11-01 10:01   ` LIU Zhiwei
2021-11-01 10:53   ` Richard Henderson
2021-11-01 10:53     ` Richard Henderson
2021-11-01 10:01 ` [PATCH 07/13] target/riscv: Ajdust vector atomic check with ol LIU Zhiwei
2021-11-01 10:01   ` LIU Zhiwei
2021-11-01 10:55   ` Richard Henderson
2021-11-01 10:55     ` Richard Henderson
2021-11-01 10:01 ` [PATCH 08/13] target/riscv: Fix check range for first fault only LIU Zhiwei
2021-11-01 10:01   ` LIU Zhiwei
2021-11-01 13:41   ` Richard Henderson
2021-11-01 13:41     ` Richard Henderson
2021-11-01 10:01 ` [PATCH 09/13] target/riscv: Adjust vector address with ol LIU Zhiwei
2021-11-01 10:01   ` LIU Zhiwei
2021-11-01 11:35   ` Richard Henderson
2021-11-01 11:35     ` Richard Henderson
2021-11-08  9:28     ` LIU Zhiwei
2021-11-08  9:28       ` LIU Zhiwei
2021-11-09  6:37       ` Richard Henderson
2021-11-09  6:37         ` Richard Henderson
2021-11-09  8:04         ` LIU Zhiwei
2021-11-09  8:04           ` LIU Zhiwei
2021-11-09  8:18           ` Richard Henderson
2021-11-09  8:18             ` Richard Henderson
2021-11-09  8:39             ` LIU Zhiwei
2021-11-09  8:39               ` LIU Zhiwei
2021-11-09  9:05               ` LIU Zhiwei
2021-11-09  9:05                 ` LIU Zhiwei
2021-11-09  9:25                 ` Richard Henderson
2021-11-09  9:25                   ` Richard Henderson
2021-11-01 10:01 ` [PATCH 10/13] target/riscv: Adjust scalar reg in vector " LIU Zhiwei
2021-11-01 10:01   ` LIU Zhiwei
2021-11-01 16:33   ` Richard Henderson
2021-11-01 16:33     ` Richard Henderson
2021-11-08  9:38     ` LIU Zhiwei
2021-11-08  9:38       ` LIU Zhiwei
2021-11-01 10:01 ` [PATCH 11/13] target/riscv: Switch context in exception return LIU Zhiwei
2021-11-01 10:01   ` LIU Zhiwei
2021-11-01 16:43   ` Richard Henderson
2021-11-01 16:43     ` Richard Henderson
2021-11-08 11:23     ` LIU Zhiwei
2021-11-08 11:23       ` LIU Zhiwei
2021-11-09  6:38       ` LIU Zhiwei
2021-11-09  6:38         ` LIU Zhiwei
2021-11-09  6:51       ` LIU Zhiwei
2021-11-09  6:51         ` LIU Zhiwei
2021-11-01 10:01 ` [PATCH 12/13] target/riscv: Don't save pc when " LIU Zhiwei
2021-11-01 10:01   ` LIU Zhiwei
2021-11-01 16:49   ` Richard Henderson
2021-11-01 16:49     ` Richard Henderson
2021-11-01 10:01 ` [PATCH 13/13] target/riscv: Enable uxl field write LIU Zhiwei
2021-11-01 10:01   ` LIU Zhiwei
2021-11-01 17:01   ` Richard Henderson
2021-11-01 17:01     ` Richard Henderson
2021-11-08 12:10     ` LIU Zhiwei
2021-11-08 12:10       ` LIU Zhiwei
2021-11-10  3:01     ` LIU Zhiwei
2021-11-10  3:01       ` LIU Zhiwei

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.