Re: [PATCH v2 2/8] target/riscv: add support for Zca and Zcf extensions

2022-11-14 Thread weiwei



On 2022/11/14 05:40, Richard Henderson wrote:

On 11/13/22 12:32, Weiwei Li wrote:

+    } else if ((get_xl_max(ctx) == MXL_RV32) &&
+    !ctx->cfg_ptr->ext_zcf &&
+    (((opcode & 0xe003) == 0x6000) ||
+ ((opcode & 0xe003) == 0x6002) ||
+ ((opcode & 0xe003) == 0xe000) ||
+ ((opcode & 0xe003) == 0xe002))) {
  gen_exception_illegal(ctx);


Why aren't you using the same c_flw solution that you do for Zcd?

Yeah, it's OK for zcf intructions to use the c_flw solution.

I tried to remain the original logic for Zcf and Zcd instructions, 
However, this way is not suitable for Zcd instructions


since zcmp/zcmt instructions will overlap their encodings(but not the 
same).  So I changed the way of Zcd instructions.


Regards,

Weiwei Li




r~





Re: [PATCH v2 5/8] target/riscv: add support for Zcmp extension

2022-11-15 Thread weiwei



On 2022/11/15 21:44, Richard Henderson wrote:

On 11/13/22 12:32, Weiwei Li wrote:

  {
    sq  101  ... ... .. ... 10 @c_sqsp
    c_fsd   101   ..  . 10 @c_sdsp
+
+  # *** RV64 and RV32 Zcmp Extension ***
+  cm_push 101  11000   .. 10 @zcmp
+  cm_pop  101  11010   .. 10 @zcmp
+  cm_popret   101  0   .. 10 @zcmp
+  cm_popretz  101  11100   .. 10 @zcmp
+  cm_mva01s   101  011 ... 11 ... 10 @cm_mv
+  cm_mvsa01   101  011 ... 01 ... 10 @cm_mv
  }


There is no overlap in these, so they should be within nested [].

OK. I'll update these in next version.




diff --git a/target/riscv/zce_helper.c b/target/riscv/zce_helper.c
new file mode 100644
index 00..1346de1367
--- /dev/null
+++ b/target/riscv/zce_helper.c
@@ -0,0 +1,210 @@
+/*
+ * RISC-V Zc* extension Helpers for QEMU.
+ *
+ * Copyright (c) 2021-2022 PLCT Lab
+ *
+ * This program is free software; you can redistribute it and/or 
modify it

+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but 
WITHOUT
+ * ANY WARRANTY; without even the implied warranty of 
MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public 
License for

+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License 
along with

+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */


The entire contents of this helper file should be handled at 
translation time.




OK. I'll try to translate them in next version.

Regards,

Weiwei Li


r~





Re: [PATCH v3 6/9] target/riscv: add support for Zcmp extension

2022-11-17 Thread weiwei

Thanks for your detail comments!

On 2022/11/17 17:44, Richard Henderson wrote:

On 11/16/22 23:03, Weiwei Li wrote:

Add encode, trans* functions for Zcmp instructions

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
---
  target/riscv/insn16.decode    |  18 ++
  target/riscv/insn_trans/trans_rvzce.c.inc | 242 +-
  target/riscv/translate.c  |   5 +
  3 files changed, 264 insertions(+), 1 deletion(-)


Better, though...


+static bool gen_zcmp_check(DisasContext *ctx, arg_zcmp *a)
+{
+    /* rlist 0 to 3 are reserved for future EABI variant */
+    if (a->zcmp_rlist < 4) {
+    return false;
+    }
+
+    /* rlist <= 6 when RV32E/RV64E */
+    if (ctx->cfg_ptr->ext_e && a->zcmp_rlist > 6) {
+    return false;
+    }
+
+    return true;
+}


This could be merged into...


+
+#define X_S0    8
+#define X_S1    9
+#define X_Sn    16
+
+static inline void update_push_pop_list(target_ulong rlist, bool 
*xreg_list)


... here.

For instance, one way is to return false when the list is invalid.
Better is to return a uint32_t bitmap of the registers in the list, 
with 0 indicating invalid.


Nit 1: Remove the inline.
Nit 2: A better name might be decode_push_pop_list.

OK. I'll update this in next version.


+static inline target_ulong caculate_stack_adj(int bytes, 
target_ulong rlist,

+  target_ulong spimm)
+{
+    target_ulong stack_adj_base = 0;
+    switch (rlist) {
+    case 15:
+    stack_adj_base = bytes == 4 ? 64 : 112;
+    break;
+    case 14:
+    stack_adj_base = bytes == 4 ? 48 : 96;
+    break;
+    case 13:
+    case 12:
+    stack_adj_base = bytes == 4 ? 48 : 80;
+    break;
+    case 11:
+    case 10:
+    stack_adj_base = bytes == 4 ? 32 : 64;
+    break;
+    case 9:
+    case 8:
+    stack_adj_base = bytes == 4 ? 32 : 48;
+    break;
+    case 7:
+    case 6:
+    stack_adj_base = bytes == 4 ? 16 : 32;
+    break;
+    case 5:
+    case 4:
+    stack_adj_base = 16;
+    break;
+    }


I really dislike this, as it replicates the decoding done just above.
I think this ought to be simply:

    ROUND_UP(ctpop32(reg_bitmap) * reg_size, 16) + spimm

Yeah. This is more simply. I'll update this.



+static bool gen_pop(DisasContext *ctx, arg_zcmp *a, bool ret, bool 
ret_val)

+{
+    REQUIRE_ZCMP(ctx);
+
+    if (!gen_zcmp_check(ctx, a)) {
+    return false;
+    }
+
+    bool xreg_list[32] = {false};
+    int bytes = get_ol(ctx) == MXL_RV32 ? 4 : 8;


Better with

    MemOp memop = get_ol(ctx) == MXL_RV32 ? MO_TEUL : MO_TEUQ;
    int reg_size = memop_size(memop);

OK.



+    switch (bytes) {
+    case 4:
+    tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, MO_32);
+    break;
+    case 8:
+    tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, MO_64);
+    break;
+    default:
+    break;
+    }


These are incorrect in that they do not indicate the target endianness.
Better to merge the two using the common memop computed above:

    tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, memop);

Yeah. I didn't take the target endianness into consideration. I'll fix this.

+static bool trans_cm_mvsa01(DisasContext *ctx, arg_cm_mvsa01 *a)
+{
+    REQUIRE_ZCMP(ctx);
+
+    TCGv a0 = get_gpr(ctx, xA0, EXT_NONE);
+    TCGv a1 = get_gpr(ctx, xA1, EXT_NONE);
+
+    gen_set_gpr(ctx, a->rs1, a0);
+    gen_set_gpr(ctx, a->rs2, a1);


rs1 must not equal rs2.



Yeah. I lost this check. I'll add it.

Regards,

Weiwei Li


r~





Re: [PATCH v3 7/9] target/riscv: add support for Zcmt extension

2022-11-17 Thread weiwei



On 2022/11/17 17:56, Richard Henderson wrote:

On 11/16/22 23:03, Weiwei Li wrote:

+target_ulong HELPER(cm_jalt)(CPURISCVState *env, target_ulong index,
+ target_ulong next_pc)
+{
+    target_ulong target = next_pc;
+    target_ulong val = 0;
+    int xlen = riscv_cpu_xlen(env);
+
+    val = env->jvt;
+
+    uint8_t mode = get_field(val, JVT_MODE);
+    target_ulong base = get_field(val, JVT_BASE);
+
+    target_ulong t0;
+
+    if (mode != 0) {
+    riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
+    }
+
+    if (xlen == 32) {
+    t0 = base + (index << 2);
+    target = cpu_ldl_code(env, t0);
+    } else {
+    t0 = base + (index << 3);
+    target = cpu_ldq_code(env, t0);
+    }
+
+    /* index >= 32 for cm.jalt, otherwise for cm.jt */
+    if (index >= 32) {
+    env->gpr[1] = next_pc;
+    }
+
+    return target & ~0x1;
+}


Missing a smstateen_check.  Not mentioned in the instruction 
description itself, but it is within the State Enable section of JVT.


smstateen_check have been added in REQUIRE_ZCMT.

Regards,

Weiwei Li




r~





Re: [PATCH v3 7/9] target/riscv: add support for Zcmt extension

2022-11-17 Thread weiwei



On 2022/11/18 04:57, Richard Henderson wrote:

On 11/17/22 03:44, weiwei wrote:
Missing a smstateen_check.  Not mentioned in the instruction 
description itself, but it is within the State Enable section of JVT.


smstateen_check have been added in REQUIRE_ZCMT.



Oh. I see.  That's wrong, I think.

Returning false from trans_* means "no match" and continue on to try 
and match another pattern.  If Zcmt is present in the cpu, but the 
extension is not enabled by the OS, we have found the matching insn 
and should not look for another insn.

You need to separate the check like

    REQUIRE_ZCMT(ctx);

    if (!smstateen_check(ctx, 0, SMTATEEN0_JVT)) {
    gen_exception_illegal(ctx);
    return true;
    }

I see that the fpcr code that you're modifying in this patch, which is 
not yet upstream, is also incorrect in this.


Looking back through your git history,

https://github.com/plctlab/plct-qemu/commit/09668167880c492f88b74d0a921053ed25fc3b5c

is incorrect:



Yeah. This patchset is not yet upstream but have been added to 
riscv-to-apply.next.  I also suggested  similar way


 in this patchset at the beginning. However, to some extent, JVT and 
FCSR in statenen CSR are  used to enable/disable


Zfinx and Zcmt extensions.  When they are disabled, It seems reasonable 
to look for another insn, just like the


processor doesn't support them at all.

From the other aspect, is it possible that we support many overlapping 
extensions(such as Zcmt and Zcd or CD) in one


processor  and only one work once (just disable anothers if we need 
another to work)?





static inline bool smstateen_fcsr_check(DisasContext *ctx, int index)
{
    CPUState *cpu = ctx->cs;
    CPURISCVState *env = cpu->env_ptr;
    uint64_t stateen = env->mstateen[index];


You cannot read from env during translation like this.

Everything that you use for translation must be encoded in tb->flags.  
Otherwise the state will not be considered when selecting an existing 
TranslationBlock to execute, and the next execution through this 
instruction will not have the *current* state of env.


You probably get lucky with mstateen, because I could imagine that it 
gets set once while the OS is booting and is never changed again.  If 
true, then mstateen chould be treated like misa and flush all 
translations on write: see write_misa().  And also add a large comment 
to smstateen_check() explaining why the read from env is correct.


But if that "set once" assumption is not true, and mstateen is more 
like mstatus.fs, where a given extension is enabled/disabled often for 
lazy migration of state, then you won't want to continually flush 
translations.


Yeah. I didn't realize this question. I think we can use a specific 
helper to do this check, since  tb_flags may not be  big enough to catch 
all the information of xStateen csr.




r~





Re: [PATCH v3 7/9] target/riscv: add support for Zcmt extension

2022-11-17 Thread weiwei



On 2022/11/18 10:51, Richard Henderson wrote:
I don't think any processor will support overlapping, mutual exclusive 
extensions.  The decode within the processor would be wildly 
complicated by that.


While you might be able to get away with returning false in this 
particular case right now, it's incorrect usage of the tool and might 
just come back to cause bugs in the future. 


 Yeah, my previous assumption seems not very reasonable.  I'll try to 
take the check into the cm_jalt helper.


Regards,

Weiwei Li




Re: [PATCH v4 7/9] target/riscv: add support for Zcmt extension

2022-11-18 Thread weiwei



On 2022/11/18 18:24, Richard Henderson wrote:

On 11/17/22 23:17, Weiwei Li wrote:

+target_ulong HELPER(cm_jalt)(CPURISCVState *env, target_ulong index,
+ target_ulong next_pc)
+{
+
+#if !defined(CONFIG_USER_ONLY)
+    RISCVException ret = smstateen_acc_ok(env, 0, SMSTATEEN0_JVT);
+    if (ret != RISCV_EXCP_NONE) {
+    riscv_raise_exception(env, ret, GETPC());
+    }
+#endif
+
+    target_ulong target = next_pc;
+    target_ulong val = 0;
+    int xlen = riscv_cpu_xlen(env);
+
+    val = env->jvt;
+
+    uint8_t mode = get_field(val, JVT_MODE);
+    target_ulong base = get_field(val, JVT_BASE);
+    target_ulong t0;
+
+    if (mode != 0) {
+    riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
+    }
+
+    if (xlen == 32) {
+    t0 = base + (index << 2);
+    target = cpu_ldl_code(env, t0);
+    } else {
+    t0 = base + (index << 3);
+    target = cpu_ldq_code(env, t0);
+    }


Much better.  The only problem is here where cpu_ld*_code does not 
have support for unwind from exception.  If this load faults, we won't 
update env->pc on the way out (we are normally loading for code during 
translation, where pc is perforce up to date).  I should have noticed 
this before.


The way to fix this is to update cpu_pc to the current instruction 
before calling the helper.  At which point none of the other exception 
exits need to unwind either, so you can replace all of the GETPC() 
with 0.

OK.  I'll fix it.



+
+    /* index >= 32 for cm.jalt, otherwise for cm.jt */
+    if (index >= 32) {
+    env->gpr[1] = next_pc;
+    }


This is simple enough to do in the caller, and then you don't need to 
pass in next_pc.

And since you don't modify xRA in the helper you can do

DEF_HELPER_FLAGS_3(cm_jt, TCG_CALL_NO_WG, tl, env, tl, tl)

static bool trans_cm_jalt(DisasContext *ctx, arg_cm_jalt *a)
{
    REQUIRE_ZCMT(ctx);

    /*
 * Update pc to current for the non-unwinding exception
 * that might come from cpu_ld*_code() in the helper.
 */
    tcg_gen_movi_tl(cpu_pc, s->base.pc_next);
    gen_helper_cm_jt(cpu_pc, cpu_env, tcg_constant_i32(a->index))

    /* c.jt vs c.jalt depends on the index. */
    if (a->index >= 32) {
    gen_set_gpri(ctx, xRA, ctx->pc_succ_insn);
    }
    tcg_gen_lookup_and_goto_ptr();
    ctx->base.is_jmp = DISAS_NORETURN;
    return true;
}


OK. I'll update it. Thanks a lot.

Regards,

Weiwei Li



r~





Re: [PATCH v6 2/9] target/riscv: add support for Zca extension

2022-11-28 Thread weiwei


On 2022/11/29 07:06, Wilfred Mallawa wrote:

On Mon, 2022-11-28 at 20:29 +0800, Weiwei Li wrote:

Modify the check for C extension to Zca (C implies Zca)

Signed-off-by: Weiwei Li
Signed-off-by: Junqiang Wang
Reviewed-by: Richard Henderson
Reviewed-by: Alistair Francis
---
  target/riscv/insn_trans/trans_rvi.c.inc | 4 ++--
  target/riscv/translate.c    | 8 ++--
  2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvi.c.inc
b/target/riscv/insn_trans/trans_rvi.c.inc
index 4496f21266..ef7c3002b0 100644
--- a/target/riscv/insn_trans/trans_rvi.c.inc
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
@@ -56,7 +56,7 @@ static bool trans_jalr(DisasContext *ctx, arg_jalr
*a)
  tcg_gen_andi_tl(cpu_pc, cpu_pc, (target_ulong)-2);
  
  gen_set_pc(ctx, cpu_pc);

-    if (!has_ext(ctx, RVC)) {
+    if (!ctx->cfg_ptr->ext_zca) {
  TCGv t0 = tcg_temp_new();
  
  misaligned = gen_new_label();

@@ -178,7 +178,7 @@ static bool gen_branch(DisasContext *ctx, arg_b
*a, TCGCond cond)
  
  gen_set_label(l); /* branch taken */
  
-    if (!has_ext(ctx, RVC) && ((ctx->base.pc_next + a->imm) & 0x3))

{
+    if (!ctx->cfg_ptr->ext_zca && ((ctx->base.pc_next + a->imm) &
0x3)) {
  /* misaligned */
  gen_exception_inst_addr_mis(ctx);
  } else {
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 2ab8772ebe..ee24b451e3 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -557,7 +557,7 @@ static void gen_jal(DisasContext *ctx, int rd,
target_ulong imm)
  
  /* check misaligned: */

  next_pc = ctx->base.pc_next + imm;
-    if (!has_ext(ctx, RVC)) {
+    if (!ctx->cfg_ptr->ext_zca) {
  if ((next_pc & 0x3) != 0) {
  gen_exception_inst_addr_mis(ctx);
  return;
@@ -1097,7 +1097,11 @@ static void decode_opc(CPURISCVState *env,
DisasContext *ctx, uint16_t opcode)
  ctx->virt_inst_excp = false;
  /* Check for compressed insn */
  if (insn_len(opcode) == 2) {
-    if (!has_ext(ctx, RVC)) {
+    /*
+ * Zca support all of the existing C extension, excluding
all
+ * compressed floating point loads and stores
+ */

Look like a typo: *`supports` and *`C extensions`


Thanks a lot!

Yeah,  it should be 'supports' here (and it's 'is' here in original Zc* 
0.70.1 spec).


Maybe we can use the new description from newest spec here:

/"The Zca extension is added as way to refer to instructions in the C 
extension that do not i/


/nclude the//floating-point loads and stores."/

By the way, why do you think it should be 'C extensions' ?/
/

Regards,

Weiwei Li


+    if (!ctx->cfg_ptr->ext_zca) {
  gen_exception_illegal(ctx);
  } else {
  ctx->opcode = opcode;

otherwise,
Reviewed-by: Wilfred Mallawa

Wilfred

Re: [PATCH v7 9/9] disas/riscv.c: add disasm support for Zc*

2022-11-29 Thread weiwei


On 2022/11/30 11:04, Shaobo Song wrote:


At 2022-11-29 10:43:43, "Weiwei Li"  wrote:

>Zcmp/Zcmt instructions will override disasm for c.fld*/c.fsd*
>instructions currently
>
>Signed-off-by: Weiwei Li 
>Signed-off-by: Junqiang Wang 
>Acked-by: Alistair Francis 
>---
> disas/riscv.c | 287 +-
> 1 file changed, 286 insertions(+), 1 deletion(-)
>
>diff --git a/disas/riscv.c b/disas/riscv.c
>index d216b9c39b..81369063b5 100644
>--- a/disas/riscv.c
>+++ b/disas/riscv.c
>@@ -163,6 +163,13 @@ typedef enum {
> rv_codec_v_i,
> rv_codec_vsetvli,
> rv_codec_vsetivli,
>+rv_codec_zcb_ext,
>+rv_codec_zcb_mul,
>+rv_codec_zcb_lb,
>+rv_codec_zcb_lh,
>+rv_codec_zcmp_cm_pushpop,
>+rv_codec_zcmp_cm_mv,
>+rv_codec_zcmt_jt,
> } rv_codec;
> 
> typedef enum {

>@@ -935,6 +942,26 @@ typedef enum {
> rv_op_vsetvli = 766,
> rv_op_vsetivli = 767,
> rv_op_vsetvl = 768,
>+rv_op_c_zext_b = 769,
>+rv_op_c_sext_b = 770,
>+rv_op_c_zext_h = 771,
>+rv_op_c_sext_h = 772,
>+rv_op_c_zext_w = 773,
>+rv_op_c_not = 774,
>+rv_op_c_mul = 775,
>+rv_op_c_lbu = 776,
>+rv_op_c_lhu = 777,
>+rv_op_c_lh = 778,
>+rv_op_c_sb = 779,
>+rv_op_c_sh = 780,
>+rv_op_cm_push = 781,
>+rv_op_cm_pop = 782,
>+rv_op_cm_popret = 783,
>+rv_op_cm_popretz = 784,
>+rv_op_cm_mva01s = 785,
>+rv_op_cm_mvsa01 = 786,
>+rv_op_cm_jt = 787,
>+rv_op_cm_jalt = 788,
> } rv_op;
> 
> /* structures */

>@@ -958,6 +985,7 @@ typedef struct {
> uint8_t   rnum;
> uint8_t   vm;
> uint32_t  vzimm;
>+uint8_t   rlist;
> } rv_decode;
> 
> typedef struct {

>@@ -1070,6 +1098,10 @@ static const char rv_vreg_name_sym[32][4] = {
> #define rv_fmt_vd_vm  "O\tDm"
> #define rv_fmt_vsetvli"O\t0,1,v"
> #define rv_fmt_vsetivli   "O\t0,u,v"
>+#define rv_fmt_rs1_rs2_zce_ldst   "O\t2,i(1)"
>+#define rv_fmt_push_rlist "O\tx,-i"
>+#define rv_fmt_pop_rlist  "O\tx,i"
>+#define rv_fmt_zcmt_index "O\ti"
> 
> /* pseudo-instruction constraints */
> 
>@@ -2065,7 +2097,27 @@ const rv_opcode_data opcode_data[] = {

> { "vsext.vf8", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vsext_vf8, 
rv_op_vsext_vf8, 0 },
> { "vsetvli", rv_codec_vsetvli, rv_fmt_vsetvli, NULL, rv_op_vsetvli, 
rv_op_vsetvli, 0 },
> { "vsetivli", rv_codec_vsetivli, rv_fmt_vsetivli, NULL, rv_op_vsetivli, 
rv_op_vsetivli, 0 },
>-{ "vsetvl", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, rv_op_vsetvl, 
rv_op_vsetvl, 0 }
>+{ "vsetvl", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, rv_op_vsetvl, 
rv_op_vsetvl, 0 },
>+{ "c.zext.b", rv_codec_zcb_ext, rv_fmt_rd, NULL, 0 },
>+{ "c.sext.b", rv_codec_zcb_ext, rv_fmt_rd, NULL, 0 },
>+{ "c.zext.h", rv_codec_zcb_ext, rv_fmt_rd, NULL, 0 },
>+{ "c.sext.h", rv_codec_zcb_ext, rv_fmt_rd, NULL, 0 },
>+{ "c.zext.w", rv_codec_zcb_ext, rv_fmt_rd, NULL, 0 },
>+{ "c.not", rv_codec_zcb_ext, rv_fmt_rd, NULL, 0 },
>+{ "c.mul", rv_codec_zcb_mul, rv_fmt_rd_rs2, NULL, 0, 0 },
>+{ "c.lbu", rv_codec_zcb_lb, rv_fmt_rs1_rs2_zce_ldst, NULL, 0, 0, 0 },
>+{ "c.lhu", rv_codec_zcb_lh, rv_fmt_rs1_rs2_zce_ldst, NULL, 0, 0, 0 },
>+{ "c.lh", rv_codec_zcb_lh, rv_fmt_rs1_rs2_zce_ldst, NULL, 0, 0, 0 },
>+{ "c.sb", rv_codec_zcb_lb, rv_fmt_rs1_rs2_zce_ldst, NULL, 0, 0, 0 },
>+{ "c.sh", rv_codec_zcb_lh, rv_fmt_rs1_rs2_zce_ldst, NULL, 0, 0, 0 },
>+{ "cm.push", rv_codec_zcmp_cm_pushpop, rv_fmt_push_rlist, NULL, 0, 0 },
>+{ "cm.pop", rv_codec_zcmp_cm_pushpop, rv_fmt_pop_rlist, NULL, 0, 0 },
>+{ "cm.popret", rv_codec_zcmp_cm_pushpop, rv_fmt_pop_rlist, NULL, 0, 0, 0 
},
>+{ "cm.popretz", rv_codec_zcmp_cm_pushpop, rv_fmt_pop_rlist, NULL, 0, 0 },
>+{ "cm.mva01s", rv_codec_zcmp_cm_mv, rv_fmt_rd_rs2, NULL, 0, 0, 0 },
>+{ "cm.mvsa01", rv_codec_zcmp_cm_mv, rv_fmt_rd_rs2, NULL, 0, 0, 0 },
>+{ "cm.jt", rv_codec_zcmt_jt, rv_fmt_zcmt_index, NULL, 0 },
>+{ "cm.jalt", rv_codec_zcmt_jt, rv_fmt_zcmt_index, NULL, 0 },
> };
> 
> /* CSR names */

>@@ -2084,6 +2136,7 @@ static const char *csr_name(int csrno)
> case 0x000a: return "vxrm";
> case 0x000f: return "vcsr";
> case 0x0015: return "seed";
>+case 0x0017: return "jvt"

Re: [PATCH v9 0/9] support subsets of code size reduction extension

2023-01-10 Thread weiwei



On 2023/1/11 13:00, Alistair Francis wrote:

On Wed, Dec 28, 2022 at 4:23 PM Weiwei Li  wrote:

This patchset implements RISC-V Zc* extension v1.0.0.RC5.7 version instructions.

Specification:
https://github.com/riscv/riscv-code-size-reduction/tree/main/Zc-specification

The port is available here:
https://github.com/plctlab/plct-qemu/tree/plct-zce-upstream-v9

To test Zc* implementation, specify cpu argument with 'x-zca=true,x-zcb=true,x-zcf=true,f=true" and 
"x-zcd=true,d=true" (or "x-zcmp=true,x-zcmt=true" with c or d=false) to enable 
Zca/Zcb/Zcf and Zcd(or Zcmp,Zcmt) extensions support.


This implementation can pass the basic zc tests from 
https://github.com/yulong-plct/zc-test

v9:
* rebase on riscv-to-apply.next

v8:
* improve disas support in Patch 9

v7:
* Fix description for Zca

v6:
* fix base address for jump table in Patch 7
* rebase on riscv-to-apply.next

v5:
* fix exception unwind problem for cpu_ld*_code in helper of cm_jalt

v4:
* improve Zcmp suggested by Richard
* fix stateen related check for Zcmt

v3:
* update the solution for Zcf to the way of Zcd
* update Zcb to reuse gen_load/store
* use trans function instead of helper for push/pop

v2:
* add check for relationship between Zca/Zcf/Zcd with C/F/D based on related 
discussion in review of Zc* spec
* separate c.fld{sp}/fsd{sp} with fld{sp}/fsd{sp} before support of zcmp/zcmt

Weiwei Li (9):
   target/riscv: add cfg properties for Zc* extension
   target/riscv: add support for Zca extension
   target/riscv: add support for Zcf extension
   target/riscv: add support for Zcd extension
   target/riscv: add support for Zcb extension
   target/riscv: add support for Zcmp extension
   target/riscv: add support for Zcmt extension
   target/riscv: expose properties for Zc* extension
   disas/riscv.c: add disasm support for Zc*

This series broke a range of boards that use specific CPUs. I have
dropped it from my tree.

Daniel has sent a series that should fix it though
(https://www.mail-archive.com/qemu-devel@nongnu.org/msg930952.html). I
have applied his fixes. Can you rebase this series on
https://github.com/alistair23/qemu/tree/riscv-to-apply.next, test to
ensure the SiFive boards continue to work and then re-send the series?

Alistair


This seems "C implies Zca" is not applied on specific CPUs and it'll be 
fixed if Zc* related check is


moved to riscv_cpu_validate_set_extensions just as  Daniel's series.

I'll rebase on it and test the CPUs in next version.

Regards,

Weiwei Li


  disas/riscv.c | 228 +++-
  target/riscv/cpu.c|  56 
  target/riscv/cpu.h|  10 +
  target/riscv/cpu_bits.h   |   7 +
  target/riscv/csr.c|  38 ++-
  target/riscv/helper.h |   3 +
  target/riscv/insn16.decode|  63 -
  target/riscv/insn_trans/trans_rvd.c.inc   |  18 ++
  target/riscv/insn_trans/trans_rvf.c.inc   |  18 ++
  target/riscv/insn_trans/trans_rvi.c.inc   |   4 +-
  target/riscv/insn_trans/trans_rvzce.c.inc | 313 ++
  target/riscv/machine.c|  19 ++
  target/riscv/meson.build  |   3 +-
  target/riscv/translate.c  |  15 +-
  target/riscv/zce_helper.c |  55 
  15 files changed, 834 insertions(+), 16 deletions(-)
  create mode 100644 target/riscv/insn_trans/trans_rvzce.c.inc
  create mode 100644 target/riscv/zce_helper.c

--
2.25.1







Re: [PATCH 04/18] target/riscv: gdbstub: Do not generate CSR XML if Zicsr is disabled

2023-02-14 Thread weiwei



On 2023/2/14 02:02, Bin Meng wrote:

There is no need to generate the CSR XML if the Zicsr extension
is not enabled.

Signed-off-by: Bin Meng 

Reviewed-by: Weiwei Li 

Regards,
Weiwei Li

---

  target/riscv/gdbstub.c | 9 ++---
  1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
index 704f3d6922..294f0ceb1c 100644
--- a/target/riscv/gdbstub.c
+++ b/target/riscv/gdbstub.c
@@ -406,7 +406,10 @@ void riscv_cpu_register_gdb_regs_for_features(CPUState *cs)
  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),
- "riscv-csr.xml", 0);
+if (cpu->cfg.ext_icsr) {
+int base_reg = cs->gdb_num_regs;
+gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr,
+ riscv_gen_dynamic_csr_xml(cs, base_reg),
+ "riscv-csr.xml", 0);
+}
  }





Re: [PATCH 05/18] target/riscv: Coding style fixes in csr.c

2023-02-14 Thread weiwei



On 2023/2/14 02:02, Bin Meng wrote:

Fix various places that violate QEMU coding style:

- correct multi-line comment format
- indent to opening parenthesis

Signed-off-by: Bin Meng 

Reviewed-by: Weiwei Li 

Regards,
Weiwei Li

---

  target/riscv/csr.c | 62 --
  1 file changed, 32 insertions(+), 30 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index c2dd9d5af0..cc74819759 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -963,7 +963,7 @@ static RISCVException sstc_32(CPURISCVState *env, int csrno)
  }
  
  static RISCVException read_vstimecmp(CPURISCVState *env, int csrno,

-target_ulong *val)
+ target_ulong *val)
  {
  *val = env->vstimecmp;
  
@@ -971,7 +971,7 @@ static RISCVException read_vstimecmp(CPURISCVState *env, int csrno,

  }
  
  static RISCVException read_vstimecmph(CPURISCVState *env, int csrno,

-target_ulong *val)
+  target_ulong *val)
  {
  *val = env->vstimecmp >> 32;
  
@@ -979,7 +979,7 @@ static RISCVException read_vstimecmph(CPURISCVState *env, int csrno,

  }
  
  static RISCVException write_vstimecmp(CPURISCVState *env, int csrno,

-target_ulong val)
+  target_ulong val)
  {
  RISCVCPU *cpu = env_archcpu(env);
  
@@ -996,7 +996,7 @@ static RISCVException write_vstimecmp(CPURISCVState *env, int csrno,

  }
  
  static RISCVException write_vstimecmph(CPURISCVState *env, int csrno,

-target_ulong val)
+   target_ulong val)
  {
  RISCVCPU *cpu = env_archcpu(env);
  
@@ -1020,7 +1020,7 @@ static RISCVException read_stimecmp(CPURISCVState *env, int csrno,

  }
  
  static RISCVException read_stimecmph(CPURISCVState *env, int csrno,

-target_ulong *val)
+ target_ulong *val)
  {
  if (riscv_cpu_virt_enabled(env)) {
  *val = env->vstimecmp >> 32;
@@ -1032,7 +1032,7 @@ static RISCVException read_stimecmph(CPURISCVState *env, 
int csrno,
  }
  
  static RISCVException write_stimecmp(CPURISCVState *env, int csrno,

-target_ulong val)
+ target_ulong val)
  {
  RISCVCPU *cpu = env_archcpu(env);
  
@@ -1055,7 +1055,7 @@ static RISCVException write_stimecmp(CPURISCVState *env, int csrno,

  }
  
  static RISCVException write_stimecmph(CPURISCVState *env, int csrno,

-target_ulong val)
+  target_ulong val)
  {
  RISCVCPU *cpu = env_archcpu(env);
  
@@ -1342,7 +1342,8 @@ static RISCVException write_misa(CPURISCVState *env, int csrno,
  
  /* 'E' excludes all other extensions */

  if (val & RVE) {
-/* when we support 'E' we can do "val = RVE;" however
+/*
+ * when we support 'E' we can do "val = RVE;" however
   * for now we just drop writes if 'E' is present.
   */
  return RISCV_EXCP_NONE;
@@ -1364,7 +1365,8 @@ static RISCVException write_misa(CPURISCVState *env, int 
csrno,
  val &= ~RVD;
  }
  
-/* Suppress 'C' if next instruction is not aligned

+/*
+ * Suppress 'C' if next instruction is not aligned
   * TODO: this should check next_pc
   */
  if ((val & RVC) && (GETPC() & ~3) != 0) {
@@ -1833,28 +1835,28 @@ static RISCVException write_mscratch(CPURISCVState 
*env, int csrno,
  }
  
  static RISCVException read_mepc(CPURISCVState *env, int csrno,

- target_ulong *val)
+target_ulong *val)
  {
  *val = env->mepc;
  return RISCV_EXCP_NONE;
  }
  
  static RISCVException write_mepc(CPURISCVState *env, int csrno,

- target_ulong val)
+ target_ulong val)
  {
  env->mepc = val;
  return RISCV_EXCP_NONE;
  }
  
  static RISCVException read_mcause(CPURISCVState *env, int csrno,

- target_ulong *val)
+  target_ulong *val)
  {
  *val = env->mcause;
  return RISCV_EXCP_NONE;
  }
  
  static RISCVException write_mcause(CPURISCVState *env, int csrno,

- target_ulong val)
+   target_ulong val)
  {
  env->mcause = val;
  return RISCV_EXCP_NONE;
@@ -1876,14 +1878,14 @@ static RISCVException write_mtval(CPURISCVState *env, 
int csrno,
  
  /* Execution environment configuration setup */

  static RISCVException read_menvcfg(CPURISCVState *env, int csrno,
- 

Re: [Patch 05/14] target/riscv: Fix relationship between V, Zve*, F and D

2023-02-14 Thread weiwei



On 2023/2/14 21:21, Daniel Henrique Barboza wrote:



On 2/14/23 05:38, Weiwei Li wrote:

Add dependence chain:
*  V => Zve64d => Zve64f => Zve32f => F
*  V => Zve64d => D

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
---
  target/riscv/cpu.c | 21 ++---
  1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 9a89bea2a3..4797ef9c42 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -743,12 +743,27 @@ static void 
riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)

  return;
  }
  -    if (cpu->cfg.ext_v && !cpu->cfg.ext_d) {
-    error_setg(errp, "V extension requires D extension");
+    /* The V vector extension depends on the Zve64d extension */
+    if (cpu->cfg.ext_v) {
+    cpu->cfg.ext_zve64d = true;
+    }
+
+    /* The Zve64d extension depends on the Zve64f extension */
+    if (cpu->cfg.ext_zve64d) {
+    cpu->cfg.ext_zve64f = true;
+    }
+
+    /* The Zve64f extension depends on the Zve32f extension */
+    if (cpu->cfg.ext_zve64f) {
+    cpu->cfg.ext_zve32f = true;
+    }
+
+    if (cpu->cfg.ext_zve64d && !cpu->cfg.ext_d) {
+    error_setg(errp, "Zve64d extensions require D extension");
  return;


I'll be honest and confess that I wrote a short essay about the 
problems I have
with this code. I gave up because in the end it's all stuff that we've 
been doing
for a long time in riscv_cpu_validate_set_extensions(). I'll see if I 
can work in
a redesign of that function and in how we're setting extensions 
automatically

without checking user input and so on.

For now I'll say that this error message seems weird because Zve64d 
was set to true

without user input. So this ends up happening:

$ ./qemu-system-riscv64 -M virt -cpu rv64,v=true,d=false
qemu-system-riscv64: Zve64d extensions require D extension

It's weird because the user didn't enabled Zve64d but the error 
message is complaining
about it. Given that the root cause is that ext_v was set, and then 
we've set other
extensions under the hood, a saner error message in this case would be 
"V extension

requires D extension".


Thanks,


Daniel


Thanks for your comments.

V extension depends on Zve64d(which is actually parts of V). So Zve64d 
will be enabled when V is enabled.


And in fact, only the instructions in the Zve64d part of V require D 
extension.


To make it more readable, maybe it can be change to :

"Zve64d (or V) extension requires D extension"

Regards,

Weiwei Li






  }
  -    if ((cpu->cfg.ext_zve32f || cpu->cfg.ext_zve64f) && 
!cpu->cfg.ext_f) {

+    if (cpu->cfg.ext_zve32f && !cpu->cfg.ext_f) {
  error_setg(errp, "Zve32f/Zve64f extensions require F 
extension");

  return;
  }





Re: [Patch 13/14] target/riscv: Simplify check for EEW = 64 in trans_rvv.c.inc

2023-02-14 Thread weiwei



On 2023/2/14 21:37, Daniel Henrique Barboza wrote:



On 2/14/23 05:38, Weiwei Li wrote:

Only V extension support EEW = 64 in these case: Zve64* extensions
don't support EEW = 64 as commented


"as commented" where? In the previous patch?




Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
---


The code LGTM.

Reviewed-by: Daniel Henrique Barboza 



  target/riscv/insn_trans/trans_rvv.c.inc | 12 
  1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc

index 5dbdce073b..fc0d0d60e8 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -1998,8 +1998,7 @@ static bool vmulh_vv_check(DisasContext *s, 
arg_rmrr *a)

   * are not included for EEW=64 in Zve64*. (Section 18.2)
   */

" are not included for EEW=64 in Zve64*. (Section 18.2) "

The comment is here, and similar comments can be found in following code.

Regards,

Weiwei Li


  return opivv_check(s, a) &&
-   (!has_ext(s, RVV) &&
-    s->cfg_ptr->ext_zve64f ? s->sew != MO_64 : true);
+   (!has_ext(s, RVV) ? s->sew != MO_64 : true);
  }
    static bool vmulh_vx_check(DisasContext *s, arg_rmrr *a)
@@ -2012,8 +2011,7 @@ static bool vmulh_vx_check(DisasContext *s, 
arg_rmrr *a)

   * are not included for EEW=64 in Zve64*. (Section 18.2)
   */
  return opivx_check(s, a) &&
-   (!has_ext(s, RVV) &&
-    s->cfg_ptr->ext_zve64f ? s->sew != MO_64 : true);
+   (!has_ext(s, RVV) ? s->sew != MO_64 : true);
  }
    GEN_OPIVV_GVEC_TRANS(vmul_vv,  mul)
@@ -2230,8 +2228,7 @@ static bool vsmul_vv_check(DisasContext *s, 
arg_rmrr *a)

   * for EEW=64 in Zve64*. (Section 18.2)
   */
  return opivv_check(s, a) &&
-   (!has_ext(s, RVV) &&
-    s->cfg_ptr->ext_zve64f ? s->sew != MO_64 : true);
+   (!has_ext(s, RVV) ? s->sew != MO_64 : true);
  }
    static bool vsmul_vx_check(DisasContext *s, arg_rmrr *a)
@@ -2242,8 +2239,7 @@ static bool vsmul_vx_check(DisasContext *s, 
arg_rmrr *a)

   * for EEW=64 in Zve64*. (Section 18.2)
   */
  return opivx_check(s, a) &&
-   (!has_ext(s, RVV) &&
-    s->cfg_ptr->ext_zve64f ? s->sew != MO_64 : true);
+   (!has_ext(s, RVV) ? s->sew != MO_64 : true);
  }
    GEN_OPIVV_TRANS(vsmul_vv, vsmul_vv_check)





Re: [PATCH 08/18] target/riscv: Simplify getting RISCVCPU pointer from env

2023-02-14 Thread weiwei



On 2023/2/14 02:02, Bin Meng wrote:

Use env_archcpu() to get RISCVCPU pointer from env directly.

Signed-off-by: Bin Meng 

Reviewed-by: Weiwei Li 

Regards,
Weiwei Li

---

  target/riscv/csr.c | 36 
  1 file changed, 12 insertions(+), 24 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index da3b770894..0a3f2bef6f 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -46,8 +46,7 @@ static RISCVException smstateen_acc_ok(CPURISCVState *env, 
int index,
 uint64_t bit)
  {
  bool virt = riscv_cpu_virt_enabled(env);
-CPUState *cs = env_cpu(env);
-RISCVCPU *cpu = RISCV_CPU(cs);
+RISCVCPU *cpu = env_archcpu(env);
  
  if (env->priv == PRV_M || !cpu->cfg.ext_smstateen) {

  return RISCV_EXCP_NONE;
@@ -90,8 +89,7 @@ static RISCVException fs(CPURISCVState *env, int csrno)
  
  static RISCVException vs(CPURISCVState *env, int csrno)

  {
-CPUState *cs = env_cpu(env);
-RISCVCPU *cpu = RISCV_CPU(cs);
+RISCVCPU *cpu = env_archcpu(env);
  
  if (env->misa_ext & RVV ||

  cpu->cfg.ext_zve32f || cpu->cfg.ext_zve64f) {
@@ -108,8 +106,7 @@ static RISCVException vs(CPURISCVState *env, int csrno)
  static RISCVException ctr(CPURISCVState *env, int csrno)
  {
  #if !defined(CONFIG_USER_ONLY)
-CPUState *cs = env_cpu(env);
-RISCVCPU *cpu = RISCV_CPU(cs);
+RISCVCPU *cpu = env_archcpu(env);
  int ctr_index;
  target_ulong ctr_mask;
  int base_csrno = CSR_CYCLE;
@@ -166,8 +163,7 @@ static RISCVException ctr32(CPURISCVState *env, int csrno)
  #if !defined(CONFIG_USER_ONLY)
  static RISCVException mctr(CPURISCVState *env, int csrno)
  {
-CPUState *cs = env_cpu(env);
-RISCVCPU *cpu = RISCV_CPU(cs);
+RISCVCPU *cpu = env_archcpu(env);
  int ctr_index;
  int base_csrno = CSR_MHPMCOUNTER3;
  
@@ -195,8 +191,7 @@ static RISCVException mctr32(CPURISCVState *env, int csrno)
  
  static RISCVException sscofpmf(CPURISCVState *env, int csrno)

  {
-CPUState *cs = env_cpu(env);
-RISCVCPU *cpu = RISCV_CPU(cs);
+RISCVCPU *cpu = env_archcpu(env);
  
  if (!cpu->cfg.ext_sscofpmf) {

  return RISCV_EXCP_ILLEGAL_INST;
@@ -321,8 +316,7 @@ static RISCVException umode32(CPURISCVState *env, int csrno)
  
  static RISCVException mstateen(CPURISCVState *env, int csrno)

  {
-CPUState *cs = env_cpu(env);
-RISCVCPU *cpu = RISCV_CPU(cs);
+RISCVCPU *cpu = env_archcpu(env);
  
  if (!cpu->cfg.ext_smstateen) {

  return RISCV_EXCP_ILLEGAL_INST;
@@ -333,8 +327,7 @@ static RISCVException mstateen(CPURISCVState *env, int 
csrno)
  
  static RISCVException hstateen_pred(CPURISCVState *env, int csrno, int base)

  {
-CPUState *cs = env_cpu(env);
-RISCVCPU *cpu = RISCV_CPU(cs);
+RISCVCPU *cpu = env_archcpu(env);
  
  if (!cpu->cfg.ext_smstateen) {

  return RISCV_EXCP_ILLEGAL_INST;
@@ -363,8 +356,7 @@ static RISCVException sstateen(CPURISCVState *env, int 
csrno)
  {
  bool virt = riscv_cpu_virt_enabled(env);
  int index = csrno - CSR_SSTATEEN0;
-CPUState *cs = env_cpu(env);
-RISCVCPU *cpu = RISCV_CPU(cs);
+RISCVCPU *cpu = env_archcpu(env);
  
  if (!cpu->cfg.ext_smstateen) {

  return RISCV_EXCP_ILLEGAL_INST;
@@ -918,8 +910,7 @@ static RISCVException read_timeh(CPURISCVState *env, int 
csrno,
  
  static RISCVException sstc(CPURISCVState *env, int csrno)

  {
-CPUState *cs = env_cpu(env);
-RISCVCPU *cpu = RISCV_CPU(cs);
+RISCVCPU *cpu = env_archcpu(env);
  bool hmode_check = false;
  
  if (!cpu->cfg.ext_sstc || !env->rdtime_fn) {

@@ -1152,8 +1143,7 @@ static RISCVException write_ignore(CPURISCVState *env, 
int csrno,
  static RISCVException read_mvendorid(CPURISCVState *env, int csrno,
   target_ulong *val)
  {
-CPUState *cs = env_cpu(env);
-RISCVCPU *cpu = RISCV_CPU(cs);
+RISCVCPU *cpu = env_archcpu(env);
  
  *val = cpu->cfg.mvendorid;

  return RISCV_EXCP_NONE;
@@ -1162,8 +1152,7 @@ static RISCVException read_mvendorid(CPURISCVState *env, 
int csrno,
  static RISCVException read_marchid(CPURISCVState *env, int csrno,
 target_ulong *val)
  {
-CPUState *cs = env_cpu(env);
-RISCVCPU *cpu = RISCV_CPU(cs);
+RISCVCPU *cpu = env_archcpu(env);
  
  *val = cpu->cfg.marchid;

  return RISCV_EXCP_NONE;
@@ -1172,8 +1161,7 @@ static RISCVException read_marchid(CPURISCVState *env, 
int csrno,
  static RISCVException read_mimpid(CPURISCVState *env, int csrno,
target_ulong *val)
  {
-CPUState *cs = env_cpu(env);
-RISCVCPU *cpu = RISCV_CPU(cs);
+RISCVCPU *cpu = env_archcpu(env);
  
  *val = cpu->cfg.mimpid;

  return RISCV_EXCP_NONE;





Re: [PATCH 11/18] target/riscv: gdbstub: Drop the vector CSRs in riscv-vector.xml

2023-02-14 Thread weiwei



On 2023/2/14 02:02, Bin Meng wrote:

It's worth noting that the vector CSR predicate() has a similar
run-time check logic to the FPU CSR. With the previous patch our
gdbstub can correctly report these vector CSRs via the CSR xml.

Commit 719d3561b269 ("target/riscv: gdb: support vector registers for rv64 & 
rv32")
inserted these vector CSRs in an ad-hoc, non-standard way in the
riscv-vector.xml. Now we can treat these CSRs no different from
other CSRs.

Signed-off-by: Bin Meng 

Reviewed-by: Weiwei Li 

Regards,
Weiwei Li

---

  target/riscv/gdbstub.c | 75 --
  1 file changed, 75 deletions(-)

diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
index ef52f41460..6048541606 100644
--- a/target/riscv/gdbstub.c
+++ b/target/riscv/gdbstub.c
@@ -127,40 +127,6 @@ static int riscv_gdb_set_fpu(CPURISCVState *env, uint8_t 
*mem_buf, int n)
  return 0;
  }
  
-/*

- * Convert register index number passed by GDB to the correspond
- * vector CSR number. Vector CSRs are defined after vector registers
- * in dynamic generated riscv-vector.xml, thus the starting register index
- * of vector CSRs is 32.
- * Return 0 if register index number is out of range.
- */
-static int riscv_gdb_vector_csrno(int num_regs)
-{
-/*
- * The order of vector CSRs in the switch case
- * should match with the order defined in csr_ops[].
- */
-switch (num_regs) {
-case 32:
-return CSR_VSTART;
-case 33:
-return CSR_VXSAT;
-case 34:
-return CSR_VXRM;
-case 35:
-return CSR_VCSR;
-case 36:
-return CSR_VL;
-case 37:
-return CSR_VTYPE;
-case 38:
-return CSR_VLENB;
-default:
-/* Unknown register. */
-return 0;
-}
-}
-
  static int riscv_gdb_get_vector(CPURISCVState *env, GByteArray *buf, int n)
  {
  uint16_t vlenb = env_archcpu(env)->cfg.vlen >> 3;
@@ -174,19 +140,6 @@ static int riscv_gdb_get_vector(CPURISCVState *env, 
GByteArray *buf, int n)
  return cnt;
  }
  
-int csrno = riscv_gdb_vector_csrno(n);

-
-if (!csrno) {
-return 0;
-}
-
-target_ulong val = 0;
-int result = riscv_csrrw_debug(env, csrno, &val, 0, 0);
-
-if (result == RISCV_EXCP_NONE) {
-return gdb_get_regl(buf, val);
-}
-
  return 0;
  }
  
@@ -201,19 +154,6 @@ static int riscv_gdb_set_vector(CPURISCVState *env, uint8_t *mem_buf, int n)

  return vlenb;
  }
  
-int csrno = riscv_gdb_vector_csrno(n);

-
-if (!csrno) {
-return 0;
-}
-
-target_ulong val = ldtul_p(mem_buf);
-int result = riscv_csrrw_debug(env, csrno, NULL, val, -1);
-
-if (result == RISCV_EXCP_NONE) {
-return sizeof(target_ulong);
-}
-
  return 0;
  }
  
@@ -361,21 +301,6 @@ static int ricsv_gen_dynamic_vector_xml(CPUState *cs, int base_reg)

  num_regs++;
  }
  
-/* Define vector CSRs */

-const char *vector_csrs[7] = {
-"vstart", "vxsat", "vxrm", "vcsr",
-"vl", "vtype", "vlenb"
-};
-
-for (i = 0; i < 7; i++) {
-g_string_append_printf(s,
-   "",
-   vector_csrs[i], TARGET_LONG_BITS, base_reg++);
-num_regs++;
-}
-
  g_string_append_printf(s, "");
  
  cpu->dyn_vreg_xml = g_string_free(s, false);





Re: [PATCH 06/18] target/riscv: Use 'bool' type for read_only

2023-02-14 Thread weiwei



On 2023/2/14 02:02, Bin Meng wrote:

The read_only variable is currently declared as an 'int', but it
should really be a 'bool'.

Signed-off-by: Bin Meng 

Reviewed-by: Weiwei Li 

Regards,
Weiwei Li

---

  target/riscv/csr.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index cc74819759..8bbc75cbfa 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -3778,7 +3778,7 @@ static inline RISCVException 
riscv_csrrw_check(CPURISCVState *env,
 RISCVCPU *cpu)
  {
  /* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
-int read_only = get_field(csrno, 0xC00) == 3;
+bool read_only = get_field(csrno, 0xC00) == 3;
  int csr_min_priv = csr_ops[csrno].min_priv_ver;
  
  /* ensure the CSR extension is enabled. */





Re: [PATCH 10/18] target/riscv: gdbstub: Turn on debugger mode before calling CSR predicate()

2023-02-14 Thread weiwei



On 2023/2/14 02:02, Bin Meng wrote:

Since commit 94452ac4cf26 ("target/riscv: remove fflags, frm, and fcsr from 
riscv-*-fpu.xml")
the 3 FPU CSRs are removed from the XML target decription. The
original intent of that commit was based on the assumption that
the 3 FPU CSRs will show up in the riscv-csr.xml so the ones in
riscv-*-fpu.xml are redundant. But unforuantely that is not ture.


typo here -> true

otherwise, Reviewed-by: Weiwei Li 

Regards,
Weiwei Li


As the FPU CSR predicate() has a run-time check on MSTATUS.FS,
at the time when CSR XML is generated MSTATUS.FS is unset, hence
no FPU CSRs will be reported.

The FPU CSR predicate() already considered such a case of being
accessed by a debugger. All we need to do is to turn on debugger
mode before calling predicate().

Signed-off-by: Bin Meng 
---

  target/riscv/gdbstub.c | 9 +
  1 file changed, 9 insertions(+)

diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
index 294f0ceb1c..ef52f41460 100644
--- a/target/riscv/gdbstub.c
+++ b/target/riscv/gdbstub.c
@@ -280,6 +280,10 @@ static int riscv_gen_dynamic_csr_xml(CPUState *cs, int 
base_reg)
  int bitsize = 16 << env->misa_mxl_max;
  int i;
  
+#if !defined(CONFIG_USER_ONLY)

+env->debugger = true;
+#endif
+
  /* Until gdb knows about 128-bit registers */
  if (bitsize > 64) {
  bitsize = 64;
@@ -308,6 +312,11 @@ static int riscv_gen_dynamic_csr_xml(CPUState *cs, int 
base_reg)
  g_string_append_printf(s, "");
  
  cpu->dyn_csr_xml = g_string_free(s, false);

+
+#if !defined(CONFIG_USER_ONLY)
+env->debugger = false;
+#endif
+
  return CSR_TABLE_SIZE;
  }
  





Re: [PATCH 15/18] target/riscv: Allow debugger to access sstc CSRs

2023-02-14 Thread weiwei



On 2023/2/14 12:12, Bin Meng wrote:

At present with a debugger attached sstc CSRs can only be accssed
when CPU is in M-mode, or configured correctly.

Fix it by adjusting their predicate() routine logic so that the
static config check comes before the run-time check, as well as
addding a debugger check.

Signed-off-by: Bin Meng 


Similar typo, otherwise Reviewed-by: Weiwei Li 

Regards,
Weiwei Li

---

  target/riscv/csr.c | 19 ++-
  1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index d6bcb7f275..c6a7745cb2 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -951,6 +951,19 @@ static RISCVException sstc(CPURISCVState *env, int csrno)
  return RISCV_EXCP_ILLEGAL_INST;
  }
  
+if ((csrno == CSR_VSTIMECMP) || (csrno == CSR_VSTIMECMPH)) {

+hmode_check = true;
+}
+
+RISCVException ret = hmode_check ? hmode(env, csrno) : smode(env, csrno);
+if (ret != RISCV_EXCP_NONE) {
+return ret;
+}
+
+if (env->debugger) {
+return RISCV_EXCP_NONE;
+}
+
  if (env->priv == PRV_M) {
  return RISCV_EXCP_NONE;
  }
@@ -971,11 +984,7 @@ static RISCVException sstc(CPURISCVState *env, int csrno)
  }
  }
  
-if ((csrno == CSR_VSTIMECMP) || (csrno == CSR_VSTIMECMPH)) {

-hmode_check = true;
-}
-
-return hmode_check ? hmode(env, csrno) : smode(env, csrno);
+return RISCV_EXCP_NONE;
  }
  
  static RISCVException sstc_32(CPURISCVState *env, int csrno)





Re: [PATCH 09/18] target/riscv: Avoid reporting odd-numbered pmpcfgX in the CSR XML for RV64

2023-02-14 Thread weiwei


On 2023/2/14 02:02, Bin Meng wrote:

At present the odd-numbered PMP configuration registers for RV64 are
reported in the CSR XML by QEMU gdbstub. However these registers do
not exist on RV64 so trying to access them from gdb results in 'E14'.

Move the pmpcfgX index check from the actual read/write routine to
the PMP CSR predicate() routine, so that non-existent pmpcfgX won't
be reported in the CSR XML for RV64.

Signed-off-by: Bin Meng

Reviewed-by: Weiwei Li 

Regards,
Weiwei Li

---

  target/riscv/csr.c | 23 ---
  1 file changed, 8 insertions(+), 15 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 0a3f2bef6f..749d0ef83e 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -412,6 +412,14 @@ static int aia_hmode32(CPURISCVState *env, int csrno)
  static RISCVException pmp(CPURISCVState *env, int csrno)
  {
  if (riscv_feature(env, RISCV_FEATURE_PMP)) {
+if (csrno <= CSR_PMPCFG3) {
+uint32_t reg_index = csrno - CSR_PMPCFG0;
+
+if ((reg_index & 1) && (riscv_cpu_mxl(env) == MXL_RV64)) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+}
+
  return RISCV_EXCP_NONE;
  }
  
@@ -3334,23 +3342,11 @@ static RISCVException write_mseccfg(CPURISCVState *env, int csrno,

  return RISCV_EXCP_NONE;
  }
  
-static bool check_pmp_reg_index(CPURISCVState *env, uint32_t reg_index)

-{
-/* TODO: RV128 restriction check */
-if ((reg_index & 1) && (riscv_cpu_mxl(env) == MXL_RV64)) {
-return false;
-}
-return true;
-}
-
  static RISCVException read_pmpcfg(CPURISCVState *env, int csrno,
target_ulong *val)
  {
  uint32_t reg_index = csrno - CSR_PMPCFG0;
  
-if (!check_pmp_reg_index(env, reg_index)) {

-return RISCV_EXCP_ILLEGAL_INST;
-}
  *val = pmpcfg_csr_read(env, reg_index);
  return RISCV_EXCP_NONE;
  }
@@ -3360,9 +3356,6 @@ static RISCVException write_pmpcfg(CPURISCVState *env, 
int csrno,
  {
  uint32_t reg_index = csrno - CSR_PMPCFG0;
  
-if (!check_pmp_reg_index(env, reg_index)) {

-return RISCV_EXCP_ILLEGAL_INST;
-}
  pmpcfg_csr_write(env, reg_index, val);
  return RISCV_EXCP_NONE;
  }

Re: [PATCH 07/18] target/riscv: Simplify {read,write}_pmpcfg() a little bit

2023-02-14 Thread weiwei



On 2023/2/14 02:02, Bin Meng wrote:

Use the register index that has already been calculated in the
pmpcfg_csr_{read,write} call.

Signed-off-by: Bin Meng 

Reviewed-by: Weiwei Li 

Regards,
Weiwei Li

---

  target/riscv/csr.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 8bbc75cbfa..da3b770894 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -3363,7 +3363,7 @@ static RISCVException read_pmpcfg(CPURISCVState *env, int 
csrno,
  if (!check_pmp_reg_index(env, reg_index)) {
  return RISCV_EXCP_ILLEGAL_INST;
  }
-*val = pmpcfg_csr_read(env, csrno - CSR_PMPCFG0);
+*val = pmpcfg_csr_read(env, reg_index);
  return RISCV_EXCP_NONE;
  }
  
@@ -3375,7 +3375,7 @@ static RISCVException write_pmpcfg(CPURISCVState *env, int csrno,

  if (!check_pmp_reg_index(env, reg_index)) {
  return RISCV_EXCP_ILLEGAL_INST;
  }
-pmpcfg_csr_write(env, csrno - CSR_PMPCFG0, val);
+pmpcfg_csr_write(env, reg_index, val);
  return RISCV_EXCP_NONE;
  }
  





Re: [PATCH 14/18] target/riscv: Allow debugger to access {h, s}stateen CSRs

2023-02-14 Thread weiwei



On 2023/2/14 11:06, Bin Meng wrote:

At present {h,s}stateen CSRs are not reported in the CSR XML
hence gdb cannot access them.

Fix it by adjusting their predicate() routine logic so that the
static config check comes before the run-time check, as well as
addding a debugger check.

Signed-off-by: Bin Meng 


Similar typo,

Otherwise, Reviewed-by: Weiwei Li 

Regards,
Weiwei Li


---

  target/riscv/csr.c | 22 --
  1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index f1075b5728..d6bcb7f275 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -337,13 +337,22 @@ static RISCVException hstateen_pred(CPURISCVState *env, 
int csrno, int base)
  return RISCV_EXCP_ILLEGAL_INST;
  }
  
+RISCVException ret = hmode(env, csrno);

+if (ret != RISCV_EXCP_NONE) {
+return ret;
+}
+
+if (env->debugger) {
+return RISCV_EXCP_NONE;
+}
+
  if (env->priv < PRV_M) {
  if (!(env->mstateen[csrno - base] & SMSTATEEN_STATEEN)) {
  return RISCV_EXCP_ILLEGAL_INST;
  }
  }
  
-return hmode(env, csrno);

+return RISCV_EXCP_NONE;
  }
  
  static RISCVException hstateen(CPURISCVState *env, int csrno)

@@ -366,6 +375,15 @@ static RISCVException sstateen(CPURISCVState *env, int 
csrno)
  return RISCV_EXCP_ILLEGAL_INST;
  }
  
+RISCVException ret = smode(env, csrno);

+if (ret != RISCV_EXCP_NONE) {
+return ret;
+}
+
+if (env->debugger) {
+return RISCV_EXCP_NONE;
+}
+
  if (env->priv < PRV_M) {
  if (!(env->mstateen[index] & SMSTATEEN_STATEEN)) {
  return RISCV_EXCP_ILLEGAL_INST;
@@ -378,7 +396,7 @@ static RISCVException sstateen(CPURISCVState *env, int 
csrno)
  }
  }
  
-return smode(env, csrno);

+return RISCV_EXCP_NONE;
  }
  
  /* Checks if PointerMasking registers could be accessed */





Re: [PATCH 16/18] target/riscv: Drop priv level check in mseccfg predicate()

2023-02-14 Thread weiwei



On 2023/2/14 12:12, Bin Meng wrote:

riscv_csrrw_check() already does the generic privilege level check
hence there is no need to do the specific M-mode access check in
the mseccfg predicate().

With this change debugger can access the mseccfg CSR anytime.

Signed-off-by: Bin Meng 

Reviewed-by: Weiwei Li 

Regards,
Weiwei Li

---

  target/riscv/csr.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index c6a7745cb2..40aae9e7b3 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -450,7 +450,7 @@ static RISCVException pmp(CPURISCVState *env, int csrno)
  
  static RISCVException epmp(CPURISCVState *env, int csrno)

  {
-if (env->priv == PRV_M && riscv_feature(env, RISCV_FEATURE_EPMP)) {
+if (riscv_feature(env, RISCV_FEATURE_EPMP)) {
  return RISCV_EXCP_NONE;
  }
  





Re: [PATCH 01/18] target/riscv: gdbstub: Check priv spec version before reporting CSR

2023-02-14 Thread weiwei



On 2023/2/14 02:01, Bin Meng wrote:

The gdbstub CSR XML is dynamically generated according to the result
of the CSR predicate() result. This has been working fine until
commit 7100fe6c2441 ("target/riscv: Enable privileged spec version 1.12")
introduced the privilege spec version check in riscv_csrrw_check().

When debugging the 'sifive_u' machine whose priv spec is at 1.10,
gdbstub reports priv spec 1.12 CSRs like menvcfg in the XML, hence
we see "remote failure reply 'E14'" message when examining all CSRs
via "info register system" from gdb.

Add the priv spec version check in the CSR XML generation logic to
fix this issue.

Fixes: 7100fe6c2441 ("target/riscv: Enable privileged spec version 1.12")
Signed-off-by: Bin Meng 


Reviewed-by: Weiwei Li 

Regards,
Weiwei Li

---

  target/riscv/gdbstub.c | 3 +++
  1 file changed, 3 insertions(+)

diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
index 6e7bbdbd5e..e57372db38 100644
--- a/target/riscv/gdbstub.c
+++ b/target/riscv/gdbstub.c
@@ -290,6 +290,9 @@ static int riscv_gen_dynamic_csr_xml(CPUState *cs, int 
base_reg)
  g_string_append_printf(s, "");
  
  for (i = 0; i < CSR_TABLE_SIZE; i++) {

+if (env->priv_ver < csr_ops[i].min_priv_ver) {
+continue;
+}
  predicate = csr_ops[i].predicate;
  if (predicate && (predicate(env, i) == RISCV_EXCP_NONE)) {
  if (csr_ops[i].name) {





Re: [PATCH 02/18] target/riscv: Correct the priority policy of riscv_csrrw_check()

2023-02-14 Thread weiwei



On 2023/2/14 02:01, Bin Meng wrote:

The priority policy of riscv_csrrw_check() was once adjusted in
commit eacaf4401956 ("target/riscv: Fix priority of csr related check in 
riscv_csrrw_check")
whose commit message says the CSR existence check should come
before the access control check, but the code changes did not
agree with the commit message, that the predicate() check came
after the read / write check.

Hi Bin Meng,

Let me explain why I put read-only check before predicate() check in 
commit eacaf4401956:


*  The predicates don't do existence check only. They also do some 
access-control check , and


    will trigger virtual instruction exception in come cases.  I think 
read-only check should be done


    before these access-control check, and trigger illegal instruction 
exception instead of virtual


   instruction exception when writing to read-only CSRs in these cases.

 *  Read-only  check will trigger ILLEGAL_INST exception which is  also 
the exception triggered when


     CSR is not existed, so put this check before existence check will 
not affect the final exception.


Regards,

Weiwei Li


Fixes: eacaf4401956 ("target/riscv: Fix priority of csr related check in 
riscv_csrrw_check")
Signed-off-by: Bin Meng 
---

  target/riscv/csr.c | 8 
  1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 1b0a0c1693..c2dd9d5af0 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -3793,15 +3793,15 @@ static inline RISCVException 
riscv_csrrw_check(CPURISCVState *env,
  return RISCV_EXCP_ILLEGAL_INST;
  }
  
-if (write_mask && read_only) {

-return RISCV_EXCP_ILLEGAL_INST;
-}
-
  RISCVException ret = csr_ops[csrno].predicate(env, csrno);
  if (ret != RISCV_EXCP_NONE) {
  return ret;
  }
  
+if (write_mask && read_only) {

+return RISCV_EXCP_ILLEGAL_INST;
+}
+
  #if !defined(CONFIG_USER_ONLY)
  int csr_priv, effective_priv = env->priv;
  





Re: [PATCH 12/18] target/riscv: Allow debugger to access user timer and counter CSRs

2023-02-14 Thread weiwei



On 2023/2/14 09:09, Bin Meng wrote:

At present user timer and counter CSRs are not reported in the
CSR XML hence gdb cannot access them.

Fix it by addding a debugger check in their predicate() routine.


typo: adding

Otherwise, Reviewed-by: Weiwei Li 

Regards,
Weiwei Li


Signed-off-by: Bin Meng 
---

  target/riscv/csr.c | 4 
  1 file changed, 4 insertions(+)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 749d0ef83e..515b05348b 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -131,6 +131,10 @@ static RISCVException ctr(CPURISCVState *env, int csrno)
  
  skip_ext_pmu_check:
  
+if (env->debugger) {

+return RISCV_EXCP_NONE;
+}
+
  if (env->priv < PRV_M && !get_field(env->mcounteren, ctr_mask)) {
  return RISCV_EXCP_ILLEGAL_INST;
  }





Re: [PATCH 17/18] target/riscv: Group all predicate() routines together

2023-02-14 Thread weiwei



On 2023/2/14 12:31, Bin Meng wrote:

Move sstc()/sstc32() to where all predicate() routines live.

Signed-off-by: Bin Meng 

Reviewed-by: Weiwei Li 

Regards,
Weiwei Li

---

  target/riscv/csr.c | 108 ++---
  1 file changed, 54 insertions(+), 54 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 40aae9e7b3..37350b8a6d 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -399,6 +399,60 @@ static RISCVException sstateen(CPURISCVState *env, int 
csrno)
  return RISCV_EXCP_NONE;
  }
  
+static RISCVException sstc(CPURISCVState *env, int csrno)

+{
+RISCVCPU *cpu = env_archcpu(env);
+bool hmode_check = false;
+
+if (!cpu->cfg.ext_sstc || !env->rdtime_fn) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
+if ((csrno == CSR_VSTIMECMP) || (csrno == CSR_VSTIMECMPH)) {
+hmode_check = true;
+}
+
+RISCVException ret = hmode_check ? hmode(env, csrno) : smode(env, csrno);
+if (ret != RISCV_EXCP_NONE) {
+return ret;
+}
+
+if (env->debugger) {
+return RISCV_EXCP_NONE;
+}
+
+if (env->priv == PRV_M) {
+return RISCV_EXCP_NONE;
+}
+
+/*
+ * No need of separate function for rv32 as menvcfg stores both menvcfg
+ * menvcfgh for RV32.
+ */
+if (!(get_field(env->mcounteren, COUNTEREN_TM) &&
+  get_field(env->menvcfg, MENVCFG_STCE))) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
+if (riscv_cpu_virt_enabled(env)) {
+if (!(get_field(env->hcounteren, COUNTEREN_TM) &&
+  get_field(env->henvcfg, HENVCFG_STCE))) {
+return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
+}
+}
+
+return RISCV_EXCP_NONE;
+}
+
+static RISCVException sstc_32(CPURISCVState *env, int csrno)
+{
+if (riscv_cpu_mxl(env) != MXL_RV32) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
+return sstc(env, csrno);
+}
+
  /* Checks if PointerMasking registers could be accessed */
  static RISCVException pointer_masking(CPURISCVState *env, int csrno)
  {
@@ -942,60 +996,6 @@ static RISCVException read_timeh(CPURISCVState *env, int 
csrno,
  return RISCV_EXCP_NONE;
  }
  
-static RISCVException sstc(CPURISCVState *env, int csrno)

-{
-RISCVCPU *cpu = env_archcpu(env);
-bool hmode_check = false;
-
-if (!cpu->cfg.ext_sstc || !env->rdtime_fn) {
-return RISCV_EXCP_ILLEGAL_INST;
-}
-
-if ((csrno == CSR_VSTIMECMP) || (csrno == CSR_VSTIMECMPH)) {
-hmode_check = true;
-}
-
-RISCVException ret = hmode_check ? hmode(env, csrno) : smode(env, csrno);
-if (ret != RISCV_EXCP_NONE) {
-return ret;
-}
-
-if (env->debugger) {
-return RISCV_EXCP_NONE;
-}
-
-if (env->priv == PRV_M) {
-return RISCV_EXCP_NONE;
-}
-
-/*
- * No need of separate function for rv32 as menvcfg stores both menvcfg
- * menvcfgh for RV32.
- */
-if (!(get_field(env->mcounteren, COUNTEREN_TM) &&
-  get_field(env->menvcfg, MENVCFG_STCE))) {
-return RISCV_EXCP_ILLEGAL_INST;
-}
-
-if (riscv_cpu_virt_enabled(env)) {
-if (!(get_field(env->hcounteren, COUNTEREN_TM) &&
-  get_field(env->henvcfg, HENVCFG_STCE))) {
-return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
-}
-}
-
-return RISCV_EXCP_NONE;
-}
-
-static RISCVException sstc_32(CPURISCVState *env, int csrno)
-{
-if (riscv_cpu_mxl(env) != MXL_RV32) {
-return RISCV_EXCP_ILLEGAL_INST;
-}
-
-return sstc(env, csrno);
-}
-
  static RISCVException read_vstimecmp(CPURISCVState *env, int csrno,
   target_ulong *val)
  {





Re: [PATCH 03/18] target/riscv: gdbstub: Minor change for better readability

2023-02-14 Thread weiwei



On 2023/2/14 02:01, Bin Meng wrote:

Use a variable 'base_reg' to represent cs->gdb_num_regs so that
the call to ricsv_gen_dynamic_vector_xml() can be placed in one
single line for better readability.

Signed-off-by: Bin Meng 

Reviewed-by: Weiwei Li 

Regards,
Weiwei Li

---

  target/riscv/gdbstub.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
index e57372db38..704f3d6922 100644
--- a/target/riscv/gdbstub.c
+++ b/target/riscv/gdbstub.c
@@ -385,9 +385,9 @@ void riscv_cpu_register_gdb_regs_for_features(CPUState *cs)
   32, "riscv-32bit-fpu.xml", 0);
  }
  if (env->misa_ext & RVV) {
+int base_reg = cs->gdb_num_regs;
  gdb_register_coprocessor(cs, riscv_gdb_get_vector, 
riscv_gdb_set_vector,
- ricsv_gen_dynamic_vector_xml(cs,
-  
cs->gdb_num_regs),
+ ricsv_gen_dynamic_vector_xml(cs, base_reg),
   "riscv-vector.xml", 0);
  }
  switch (env->misa_mxl_max) {





Re: [PATCH 13/18] target/riscv: Allow debugger to access seed CSR

2023-02-14 Thread weiwei



On 2023/2/14 09:09, Bin Meng wrote:

At present seed CSR is not reported in the CSR XML hence gdb cannot
access it.

Fix it by addding a debugger check in its predicate() routine.


typo: adding

Otherwise, Reviewed-by: Weiwei Li 

Regards,
Weiwei Li



Signed-off-by: Bin Meng 
---

  target/riscv/csr.c | 4 
  1 file changed, 4 insertions(+)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 515b05348b..f1075b5728 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -458,6 +458,10 @@ static RISCVException seed(CPURISCVState *env, int csrno)
  }
  
  #if !defined(CONFIG_USER_ONLY)

+if (env->debugger) {
+return RISCV_EXCP_NONE;
+}
+
  /*
   * With a CSR read-write instruction:
   * 1) The seed CSR is always available in machine mode as normal.





Re: [PATCH 18/18] target/riscv: Move configuration check to envcfg CSRs predicate()

2023-02-14 Thread weiwei



On 2023/2/14 22:27, Bin Meng wrote:

At present the envcfg CSRs predicate() routines are generic one like
smode(), hmode. The configuration check is done in the read / write
routine. Create a new predicate routine to cover such check, so that
gdbstub can correctly report its existence.

Signed-off-by: Bin Meng 

---

  target/riscv/csr.c | 98 +-
  1 file changed, 61 insertions(+), 37 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 37350b8a6d..284ccc09dd 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -41,40 +41,6 @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops)
  }
  
  /* Predicates */

-#if !defined(CONFIG_USER_ONLY)
-static RISCVException smstateen_acc_ok(CPURISCVState *env, int index,
-   uint64_t bit)
-{
-bool virt = riscv_cpu_virt_enabled(env);
-RISCVCPU *cpu = env_archcpu(env);
-
-if (env->priv == PRV_M || !cpu->cfg.ext_smstateen) {
-return RISCV_EXCP_NONE;
-}
-
-if (!(env->mstateen[index] & bit)) {
-return RISCV_EXCP_ILLEGAL_INST;
-}
-
-if (virt) {
-if (!(env->hstateen[index] & bit)) {
-return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
-}
-
-if (env->priv == PRV_U && !(env->sstateen[index] & bit)) {
-return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
-}
-}
-
-if (env->priv == PRV_U && riscv_has_ext(env, RVS)) {
-if (!(env->sstateen[index] & bit)) {
-return RISCV_EXCP_ILLEGAL_INST;
-}
-}
-
-return RISCV_EXCP_NONE;
-}
-#endif
  
  static RISCVException fs(CPURISCVState *env, int csrno)

  {
@@ -318,6 +284,32 @@ static RISCVException umode32(CPURISCVState *env, int 
csrno)
  return umode(env, csrno);
  }
  
+static RISCVException envcfg(CPURISCVState *env, int csrno)

+{
+RISCVCPU *cpu = env_archcpu(env);
+riscv_csr_predicate_fn predicate;
+
+if (cpu->cfg.ext_smstateen) {
+return RISCV_EXCP_ILLEGAL_INST;
+}


This check seems not right here.  Why  ILLEGAL_INST is directly 
triggered if smstateen is enabled?


It seems that smstateen related check will be done  for 
senvcfg/henvcfg{h} when smstateen is enabled.


Regards,

Weiwei Li


+
+switch (csrno) {
+case CSR_SENVCFG:
+predicate = smode;
+break;
+case CSR_HENVCFG:
+predicate = hmode;
+break;
+case CSR_HENVCFGH:
+predicate = hmode32;
+break;
+default:
+g_assert_not_reached();
+}
+
+return predicate(env, csrno);
+}
+
  static RISCVException mstateen(CPURISCVState *env, int csrno)
  {
  RISCVCPU *cpu = env_archcpu(env);
@@ -1946,6 +1938,38 @@ static RISCVException write_menvcfgh(CPURISCVState *env, 
int csrno,
  return RISCV_EXCP_NONE;
  }
  
+static RISCVException smstateen_acc_ok(CPURISCVState *env, int index,

+   uint64_t bit)
+{
+bool virt = riscv_cpu_virt_enabled(env);
+
+if (env->priv == PRV_M) {
+return RISCV_EXCP_NONE;
+}
+
+if (!(env->mstateen[index] & bit)) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
+if (virt) {
+if (!(env->hstateen[index] & bit)) {
+return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
+}
+
+if (env->priv == PRV_U && !(env->sstateen[index] & bit)) {
+return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
+}
+}
+
+if (env->priv == PRV_U && riscv_has_ext(env, RVS)) {
+if (!(env->sstateen[index] & bit)) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+}
+
+return RISCV_EXCP_NONE;
+}
+
  static RISCVException read_senvcfg(CPURISCVState *env, int csrno,
 target_ulong *val)
  {
@@ -4087,11 +4111,11 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
 .min_priv_ver = PRIV_VERSION_1_12_0  },
  [CSR_MENVCFGH] = { "menvcfgh", umode32, read_menvcfgh, write_menvcfgh,
 .min_priv_ver = PRIV_VERSION_1_12_0  },
-[CSR_SENVCFG]  = { "senvcfg",  smode, read_senvcfg,  write_senvcfg,
+[CSR_SENVCFG]  = { "senvcfg",  envcfg, read_senvcfg,  write_senvcfg,
 .min_priv_ver = PRIV_VERSION_1_12_0  },
-[CSR_HENVCFG]  = { "henvcfg",  hmode, read_henvcfg, write_henvcfg,
+[CSR_HENVCFG]  = { "henvcfg",  envcfg, read_henvcfg,  write_henvcfg,
 .min_priv_ver = PRIV_VERSION_1_12_0  },
-[CSR_HENVCFGH] = { "henvcfgh", hmode32, read_henvcfgh, write_henvcfgh,
+[CSR_HENVCFGH] = { "henvcfgh", envcfg, read_henvcfgh, write_henvcfgh,
 .min_priv_ver = PRIV_VERSION_1_12_0  },
  
  /* Smstateen extension CSRs */





Re: [PATCH 02/11] target/riscv: allow users to actually write the MISA CSR

2023-02-14 Thread weiwei



On 2023/2/11 19:50, Daniel Henrique Barboza wrote:



On 2/10/23 23:43, weiwei wrote:


On 2023/2/10 21:36, Daniel Henrique Barboza wrote:

At this moment, and apparently since ever, we have no way of enabling
RISCV_FEATURE_MISA. This means that all the code from write_misa(), all
the nuts and bolts that handles how to properly write this CSR, has
always been a no-op as well because write_misa() will always exit
earlier.

This seems to be benign in the majority of cases. Booting an Ubuntu
'virt' guest and logging all the calls to 'write_misa' shows that no
writes to MISA CSR was attempted. Writing MISA, i.e. enabling/disabling
RISC-V extensions after the machine is powered on, seems to be a niche
use.

There is a good chance that the code in write_misa() hasn't been
properly tested. Allowing users to write MISA can open the 
floodgates of

new breeds of bugs. We could instead remove most (if not all) of
write_misa() since it's never used. Well, as a hardware emulator,
dealing with crashes because a register write went wrong is what we're
here for.

Create a 'misa-w' CPU property to allow users to choose whether writes
to MISA should be allowed. The default is set to 'false' for all RISC-V
machines to keep compatibility with what we´ve been doing so far.

Read cpu->cfg.misa_w directly in write_misa(), instead of executing
riscv_set_feature(RISCV_FEATURE_MISA) in riscv_cpu_realize(), that 
would

simply reflect the cpu->cfg.misa_w bool value in 'env->features' and
require a riscv_feature() call to read it back.

Signed-off-by: Daniel Henrique Barboza 
---
  target/riscv/cpu.c | 1 +
  target/riscv/cpu.h | 1 +
  target/riscv/csr.c | 4 +++-
  3 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 93b52b826c..69fb9e123f 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1197,6 +1197,7 @@ static void register_cpu_props(DeviceState *dev)
  static Property riscv_cpu_properties[] = {
  DEFINE_PROP_BOOL("debug", RISCVCPU, cfg.debug, true),
+    DEFINE_PROP_BOOL("misa-w", RISCVCPU, cfg.misa_w, false),
  DEFINE_PROP_UINT32("mvendorid", RISCVCPU, cfg.mvendorid, 0),
  DEFINE_PROP_UINT64("marchid", RISCVCPU, cfg.marchid, 
RISCV_CPU_MARCHID),

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 7128438d8e..103963b386 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -498,6 +498,7 @@ struct RISCVCPUConfig {
  bool pmp;
  bool epmp;
  bool debug;
+    bool misa_w;
  bool short_isa_string;
  };
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index e149b453da..4f9cc501b2 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1329,7 +1329,9 @@ static RISCVException read_misa(CPURISCVState 
*env, int csrno,

  static RISCVException write_misa(CPURISCVState *env, int csrno,
   target_ulong val)
  {
-    if (!riscv_feature(env, RISCV_FEATURE_MISA)) {
+    RISCVCPU *cpu = env_archcpu(env);
+
+    if (!cpu->cfg.misa_w) {


It's Ok to get it directly from cfg. However, personally, I prefer to 
keep the non-isa features in a separate list.


I don't mind a separated non-isa list. cpu->cfg has everything 
contained in it
though, ISA and non-ISA (e.g. vendor extensions that weren't ratified 
yet), and
the current RISCV_FEATURES_* list is just a duplicate of it that we 
need to

update it during riscv_cpu_realize().

In my opinion we can spare the extra effort of keeping a separated, 
up-to-date

non-ISA extension/features list, by just reading everything from cfg.


Thanks,


Daniel


OK. It's  acceptable to me.

Reviewed-by: Weiwei Li 

By the way, the riscv_cpu_cfg() in patch 4 can be used here.

Regards,

Weiwei Li





Regards,

Weiwei Li


  /* drop write to misa */
  return RISCV_EXCP_NONE;
  }







Re: [PATCH 03/11] target/riscv: remove RISCV_FEATURE_MISA

2023-02-14 Thread weiwei



On 2023/2/10 21:36, Daniel Henrique Barboza wrote:

This enum is no longer used after write_misa() started reading the value
from cpu->cfg.misa_w.

Signed-off-by: Daniel Henrique Barboza 


Reviewed-by: Weiwei Li r

Regards,

Weiwei Li


---
  target/riscv/cpu.h | 1 -
  1 file changed, 1 deletion(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 103963b386..6509ffa951 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -89,7 +89,6 @@ enum {
  RISCV_FEATURE_MMU,
  RISCV_FEATURE_PMP,
  RISCV_FEATURE_EPMP,
-RISCV_FEATURE_MISA,
  RISCV_FEATURE_DEBUG
  };
  





Re: [PATCH 04/11] target/riscv: introduce riscv_cpu_cfg()

2023-02-14 Thread weiwei



On 2023/2/10 21:36, Daniel Henrique Barboza wrote:

We're going to do changes that requires accessing the RISCVCPUConfig
struct from the RISCVCPU, having access only to a CPURISCVState 'env'
pointer. Add a helper to make the code easier to read.

Signed-off-by: Daniel Henrique Barboza 


Reviewed-by: Weiwei Li 

Regards,

Weiwei Li


---
  target/riscv/cpu.h | 5 +
  1 file changed, 5 insertions(+)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 6509ffa951..00a464c9c4 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -654,6 +654,11 @@ static inline RISCVMXL riscv_cpu_mxl(CPURISCVState *env)
  #endif
  #define riscv_cpu_mxl_bits(env) (1UL << (4 + riscv_cpu_mxl(env)))
  
+static inline RISCVCPUConfig riscv_cpu_cfg(CPURISCVState *env)

+{
+return env_archcpu(env)->cfg;
+}
+
  #if defined(TARGET_RISCV32)
  #define cpu_recompute_xl(env)  ((void)(env), MXL_RV32)
  #else





Re: [PATCH 05/11] target/riscv: remove RISCV_FEATURE_DEBUG

2023-02-14 Thread weiwei



On 2023/2/10 21:36, Daniel Henrique Barboza wrote:

RISCV_FEATURE_DEBUG will always follow the value defined by
cpu->cfg.debug flag. Read the flag instead.

Signed-off-by: Daniel Henrique Barboza 


Reviewed-by: Weiwei Li 

Regards,

Weiwei Li


---
  target/riscv/cpu.c| 6 +-
  target/riscv/cpu.h| 1 -
  target/riscv/cpu_helper.c | 2 +-
  target/riscv/csr.c| 2 +-
  target/riscv/machine.c| 3 +--
  5 files changed, 4 insertions(+), 10 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 69fb9e123f..272cf1a8bf 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -637,7 +637,7 @@ static void riscv_cpu_reset_hold(Object *obj)
  set_default_nan_mode(1, &env->fp_status);
  
  #ifndef CONFIG_USER_ONLY

-if (riscv_feature(env, RISCV_FEATURE_DEBUG)) {
+if (cpu->cfg.debug) {
  riscv_trigger_init(env);
  }
  
@@ -935,10 +935,6 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)

  }
  }
  
-if (cpu->cfg.debug) {

-riscv_set_feature(env, RISCV_FEATURE_DEBUG);
-}
-
  
  #ifndef CONFIG_USER_ONLY

  if (cpu->cfg.ext_sstc) {
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 00a464c9c4..46de6f2f7f 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -89,7 +89,6 @@ enum {
  RISCV_FEATURE_MMU,
  RISCV_FEATURE_PMP,
  RISCV_FEATURE_EPMP,
-RISCV_FEATURE_DEBUG
  };
  
  /* Privileged specification version */

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index ad8d82662c..4cdd247c6c 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -105,7 +105,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong 
*pc,
  flags = FIELD_DP32(flags, TB_FLAGS, MSTATUS_HS_VS,
 get_field(env->mstatus_hs, MSTATUS_VS));
  }
-if (riscv_feature(env, RISCV_FEATURE_DEBUG) && !icount_enabled()) {
+if (cpu->cfg.debug && !icount_enabled()) {
  flags = FIELD_DP32(flags, TB_FLAGS, ITRIGGER, env->itrigger_enabled);
  }
  #endif
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 4f9cc501b2..af4a44b33b 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -437,7 +437,7 @@ static RISCVException epmp(CPURISCVState *env, int csrno)
  
  static RISCVException debug(CPURISCVState *env, int csrno)

  {
-if (riscv_feature(env, RISCV_FEATURE_DEBUG)) {
+if (riscv_cpu_cfg(env).debug) {
  return RISCV_EXCP_NONE;
  }
  
diff --git a/target/riscv/machine.c b/target/riscv/machine.c

index c6ce318cce..4634968898 100644
--- a/target/riscv/machine.c
+++ b/target/riscv/machine.c
@@ -226,9 +226,8 @@ static const VMStateDescription vmstate_kvmtimer = {
  static bool debug_needed(void *opaque)
  {
  RISCVCPU *cpu = opaque;
-CPURISCVState *env = &cpu->env;
  
-return riscv_feature(env, RISCV_FEATURE_DEBUG);

+return cpu->cfg.debug;
  }
  
  static int debug_post_load(void *opaque, int version_id)





Re: [PATCH 06/11] target/riscv/cpu.c: error out if EPMP is enabled without PMP

2023-02-14 Thread weiwei



On 2023/2/10 21:36, Daniel Henrique Barboza wrote:

Instead of silently ignoring the EPMP setting if there is no PMP
available, error out informing the user that EPMP depends on PMP
support:

$ ./qemu-system-riscv64 -cpu rv64,pmp=false,x-epmp=true
qemu-system-riscv64: Invalid configuration: EPMP requires PMP support

This will force users to pick saner options in the QEMU command line.

Signed-off-by: Daniel Henrique Barboza 


Reviewed-by: Weiwei Li 

Regards,

Weiwei Li


---
  target/riscv/cpu.c | 9 +++--
  1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 272cf1a8bf..1e67e72f90 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -925,13 +925,18 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
  
  if (cpu->cfg.pmp) {

  riscv_set_feature(env, RISCV_FEATURE_PMP);
+}
+
+if (cpu->cfg.epmp) {
+riscv_set_feature(env, RISCV_FEATURE_EPMP);
  
  /*

   * Enhanced PMP should only be available
   * on harts with PMP support
   */
-if (cpu->cfg.epmp) {
-riscv_set_feature(env, RISCV_FEATURE_EPMP);
+if (!cpu->cfg.pmp) {
+error_setg(errp, "Invalid configuration: EPMP requires PMP 
support");
+return;
  }
  }
  





Re: [PATCH 07/11] target/riscv: remove RISCV_FEATURE_EPMP

2023-02-14 Thread weiwei



On 2023/2/10 21:36, Daniel Henrique Barboza wrote:

RISCV_FEATURE_EPMP is always set to the same value as the cpu->cfg.epmp
flag. Use the flag directly.

Signed-off-by: Daniel Henrique Barboza 


Reviewed-by: Weiwei Li 

Regards,

Weiwei Li


---
  target/riscv/cpu.c | 10 +++---
  target/riscv/cpu.h |  1 -
  target/riscv/csr.c |  2 +-
  target/riscv/pmp.c |  4 ++--
  4 files changed, 6 insertions(+), 11 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 1e67e72f90..430b6adccb 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -927,17 +927,13 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
  riscv_set_feature(env, RISCV_FEATURE_PMP);
  }
  
-if (cpu->cfg.epmp) {

-riscv_set_feature(env, RISCV_FEATURE_EPMP);
-
+if (cpu->cfg.epmp && !cpu->cfg.pmp) {
  /*
   * Enhanced PMP should only be available
   * on harts with PMP support
   */
-if (!cpu->cfg.pmp) {
-error_setg(errp, "Invalid configuration: EPMP requires PMP 
support");
-return;
-}
+error_setg(errp, "Invalid configuration: EPMP requires PMP support");
+return;
  }
  
  
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h

index 46de6f2f7f..d0de11fd41 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -88,7 +88,6 @@
  enum {
  RISCV_FEATURE_MMU,
  RISCV_FEATURE_PMP,
-RISCV_FEATURE_EPMP,
  };
  
  /* Privileged specification version */

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index af4a44b33b..5b974dad6b 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -428,7 +428,7 @@ static RISCVException pmp(CPURISCVState *env, int csrno)
  
  static RISCVException epmp(CPURISCVState *env, int csrno)

  {
-if (env->priv == PRV_M && riscv_feature(env, RISCV_FEATURE_EPMP)) {
+if (env->priv == PRV_M && riscv_cpu_cfg(env).epmp) {
  return RISCV_EXCP_NONE;
  }
  
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c

index 4bc4113531..bb54899635 100644
--- a/target/riscv/pmp.c
+++ b/target/riscv/pmp.c
@@ -88,7 +88,7 @@ static void pmp_write_cfg(CPURISCVState *env, uint32_t 
pmp_index, uint8_t val)
  if (pmp_index < MAX_RISCV_PMPS) {
  bool locked = true;
  
-if (riscv_feature(env, RISCV_FEATURE_EPMP)) {

+if (riscv_cpu_cfg(env).epmp) {
  /* mseccfg.RLB is set */
  if (MSECCFG_RLB_ISSET(env)) {
  locked = false;
@@ -239,7 +239,7 @@ static bool pmp_hart_has_privs_default(CPURISCVState *env, 
target_ulong addr,
  {
  bool ret;
  
-if (riscv_feature(env, RISCV_FEATURE_EPMP)) {

+if (riscv_cpu_cfg(env).epmp) {
  if (MSECCFG_MMWP_ISSET(env)) {
  /*
   * The Machine Mode Whitelist Policy (mseccfg.MMWP) is set





Re: [PATCH 08/11] target/riscv: remove RISCV_FEATURE_PMP

2023-02-14 Thread weiwei



On 2023/2/10 21:36, Daniel Henrique Barboza wrote:

RISCV_FEATURE_PMP is being set via riscv_set_feature() by mirroring the
cpu->cfg.pmp flag. Use the flag instead.

Signed-off-by: Daniel Henrique Barboza 


Reviewed-by: Weiwei Li 

Regards,

Weiwei Li


---
  target/riscv/cpu.c| 4 
  target/riscv/cpu.h| 1 -
  target/riscv/cpu_helper.c | 2 +-
  target/riscv/csr.c| 2 +-
  target/riscv/machine.c| 3 +--
  target/riscv/op_helper.c  | 2 +-
  target/riscv/pmp.c| 2 +-
  7 files changed, 5 insertions(+), 11 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 430b6adccb..a803395ed1 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -923,10 +923,6 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
  riscv_set_feature(env, RISCV_FEATURE_MMU);
  }
  
-if (cpu->cfg.pmp) {

-riscv_set_feature(env, RISCV_FEATURE_PMP);
-}
-
  if (cpu->cfg.epmp && !cpu->cfg.pmp) {
  /*
   * Enhanced PMP should only be available
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index d0de11fd41..62919cd5cc 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -87,7 +87,6 @@
 so a cpu features bitfield is required, likewise for optional PMP support 
*/
  enum {
  RISCV_FEATURE_MMU,
-RISCV_FEATURE_PMP,
  };
  
  /* Privileged specification version */

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 4cdd247c6c..15d9542691 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -706,7 +706,7 @@ static int get_physical_address_pmp(CPURISCVState *env, int 
*prot,
  pmp_priv_t pmp_priv;
  int pmp_index = -1;
  
-if (!riscv_feature(env, RISCV_FEATURE_PMP)) {

+if (!riscv_cpu_cfg(env).pmp) {
  *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
  return TRANSLATE_SUCCESS;
  }
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 5b974dad6b..3d55b1b138 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -419,7 +419,7 @@ static int aia_hmode32(CPURISCVState *env, int csrno)
  
  static RISCVException pmp(CPURISCVState *env, int csrno)

  {
-if (riscv_feature(env, RISCV_FEATURE_PMP)) {
+if (riscv_cpu_cfg(env).pmp) {
  return RISCV_EXCP_NONE;
  }
  
diff --git a/target/riscv/machine.c b/target/riscv/machine.c

index 4634968898..67e9e56853 100644
--- a/target/riscv/machine.c
+++ b/target/riscv/machine.c
@@ -27,9 +27,8 @@
  static bool pmp_needed(void *opaque)
  {
  RISCVCPU *cpu = opaque;
-CPURISCVState *env = &cpu->env;
  
-return riscv_feature(env, RISCV_FEATURE_PMP);

+return cpu->cfg.pmp;
  }
  
  static int pmp_post_load(void *opaque, int version_id)

diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index 48f918b71b..f34701b443 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -195,7 +195,7 @@ target_ulong helper_mret(CPURISCVState *env)
  uint64_t mstatus = env->mstatus;
  target_ulong prev_priv = get_field(mstatus, MSTATUS_MPP);
  
-if (riscv_feature(env, RISCV_FEATURE_PMP) &&

+if (riscv_cpu_cfg(env).pmp &&
  !pmp_get_num_rules(env) && (prev_priv != PRV_M)) {
  riscv_raise_exception(env, RISCV_EXCP_INST_ACCESS_FAULT, GETPC());
  }
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
index bb54899635..1e7903dffa 100644
--- a/target/riscv/pmp.c
+++ b/target/riscv/pmp.c
@@ -265,7 +265,7 @@ static bool pmp_hart_has_privs_default(CPURISCVState *env, 
target_ulong addr,
  }
  }
  
-if ((!riscv_feature(env, RISCV_FEATURE_PMP)) || (mode == PRV_M)) {

+if (!riscv_cpu_cfg(env).pmp || (mode == PRV_M)) {
  /*
   * Privileged spec v1.10 states if HW doesn't implement any PMP entry
   * or no PMP entry matches an M-Mode access, the access succeeds.





Re: [PATCH 09/11] hw/riscv/virt.c: do not use RISCV_FEATURE_MMU in create_fdt_socket_cpus()

2023-02-14 Thread weiwei



On 2023/2/10 21:36, Daniel Henrique Barboza wrote:

Read cpu_ptr->cfg.mmu directly. As a bonus, use cpu_ptr in
riscv_isa_string().

Signed-off-by: Daniel Henrique Barboza 
---
  hw/riscv/virt.c | 7 ---
  1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 86c4adc0c9..8ab6a3ec16 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -232,20 +232,21 @@ static void create_fdt_socket_cpus(RISCVVirtState *s, int 
socket,
  bool is_32_bit = riscv_is_32bit(&s->soc[0]);
  
  for (cpu = s->soc[socket].num_harts - 1; cpu >= 0; cpu--) {

+RISCVCPU *cpu_ptr = &s->soc[socket].harts[cpu];
+RISCVCPUConfig cpu_cfg = cpu_ptr->cfg;


Adding cpu_cfg seems not very necessary.

Otherwise, Reviewed-by: Weiwei Li 

Regards,

Weiwei Li


  cpu_phandle = (*phandle)++;
  
  cpu_name = g_strdup_printf("/cpus/cpu@%d",

  s->soc[socket].hartid_base + cpu);
  qemu_fdt_add_subnode(ms->fdt, cpu_name);
-if (riscv_feature(&s->soc[socket].harts[cpu].env,
-  RISCV_FEATURE_MMU)) {
+if (cpu_cfg.mmu) {
  qemu_fdt_setprop_string(ms->fdt, cpu_name, "mmu-type",
  (is_32_bit) ? "riscv,sv32" : 
"riscv,sv48");
  } else {
  qemu_fdt_setprop_string(ms->fdt, cpu_name, "mmu-type",
  "riscv,none");
  }
-name = riscv_isa_string(&s->soc[socket].harts[cpu]);
+name = riscv_isa_string(cpu_ptr);
  qemu_fdt_setprop_string(ms->fdt, cpu_name, "riscv,isa", name);
  g_free(name);
  qemu_fdt_setprop_string(ms->fdt, cpu_name, "compatible", "riscv");





Re: [PATCH 10/11] target/riscv: remove RISCV_FEATURE_MMU

2023-02-14 Thread weiwei



On 2023/2/10 21:36, Daniel Henrique Barboza wrote:

RISCV_FEATURE_MMU is set whether cpu->cfg.mmu is set, so let's just use
the flag directly instead.

With this change the enum is also removed. It is worth noticing that
this enum, and all the RISCV_FEATURES_* that were contained in it,
predates the existence of the cpu->cfg object. Today, using cpu->cfg is
an easier way to retrieve all the features and extensions enabled in the
hart.

Signed-off-by: Daniel Henrique Barboza 

Reviewed-by: Weiwei Li 

Regards,

Weiwei Li

---
  target/riscv/cpu.c| 4 
  target/riscv/cpu.h| 7 ---
  target/riscv/cpu_helper.c | 2 +-
  target/riscv/csr.c| 4 ++--
  target/riscv/monitor.c| 2 +-
  target/riscv/pmp.c| 2 +-
  6 files changed, 5 insertions(+), 16 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index a803395ed1..2859ebc3e6 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -919,10 +919,6 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
  }
  }
  
-if (cpu->cfg.mmu) {

-riscv_set_feature(env, RISCV_FEATURE_MMU);
-}
-
  if (cpu->cfg.epmp && !cpu->cfg.pmp) {
  /*
   * Enhanced PMP should only be available
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 62919cd5cc..83a9fa38d9 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -81,13 +81,6 @@
  #define RVH RV('H')
  #define RVJ RV('J')
  
-/* S extension denotes that Supervisor mode exists, however it is possible

-   to have a core that support S mode but does not have an MMU and there
-   is currently no bit in misa to indicate whether an MMU exists or not
-   so a cpu features bitfield is required, likewise for optional PMP support */
-enum {
-RISCV_FEATURE_MMU,
-};
  
  /* Privileged specification version */

  enum {
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 15d9542691..e76b206191 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -796,7 +796,7 @@ static int get_physical_address(CPURISCVState *env, hwaddr 
*physical,
  mode = PRV_U;
  }
  
-if (mode == PRV_M || !riscv_feature(env, RISCV_FEATURE_MMU)) {

+if (mode == PRV_M || !riscv_cpu_cfg(env).mmu) {
  *physical = addr;
  *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
  return TRANSLATE_SUCCESS;
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 3d55b1b138..9fb8e86b70 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -2623,7 +2623,7 @@ static RISCVException rmw_siph(CPURISCVState *env, int 
csrno,
  static RISCVException read_satp(CPURISCVState *env, int csrno,
  target_ulong *val)
  {
-if (!riscv_feature(env, RISCV_FEATURE_MMU)) {
+if (!riscv_cpu_cfg(env).mmu) {
  *val = 0;
  return RISCV_EXCP_NONE;
  }
@@ -2642,7 +2642,7 @@ static RISCVException write_satp(CPURISCVState *env, int 
csrno,
  {
  target_ulong vm, mask;
  
-if (!riscv_feature(env, RISCV_FEATURE_MMU)) {

+if (!riscv_cpu_cfg(env).mmu) {
  return RISCV_EXCP_NONE;
  }
  
diff --git a/target/riscv/monitor.c b/target/riscv/monitor.c

index 236f93b9f5..b7b8d0614f 100644
--- a/target/riscv/monitor.c
+++ b/target/riscv/monitor.c
@@ -218,7 +218,7 @@ void hmp_info_mem(Monitor *mon, const QDict *qdict)
  return;
  }
  
-if (!riscv_feature(env, RISCV_FEATURE_MMU)) {

+if (!riscv_cpu_cfg(env).mmu) {
  monitor_printf(mon, "S-mode MMU unavailable\n");
  return;
  }
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
index 1e7903dffa..c67de36942 100644
--- a/target/riscv/pmp.c
+++ b/target/riscv/pmp.c
@@ -315,7 +315,7 @@ int pmp_hart_has_privs(CPURISCVState *env, target_ulong 
addr,
  }
  
  if (size == 0) {

-if (riscv_feature(env, RISCV_FEATURE_MMU)) {
+if (riscv_cpu_cfg(env).mmu) {
  /*
   * If size is unknown (0), assume that all bytes
   * from addr to the end of the page will be accessed.





Re: [PATCH 11/11] target/riscv/cpu: remove CPUArchState^features and friends

2023-02-14 Thread weiwei



On 2023/2/10 21:36, Daniel Henrique Barboza wrote:

The attribute is no longer used since we can retrieve all the enabled
features in the hart by using cpu->cfg instead.

Remove env->feature, riscv_feature() and riscv_set_feature(). We also
need to bump vmstate_riscv_cpu version_id and minimal_version_id since
'features' is no longer being migrated.

Signed-off-by: Daniel Henrique Barboza 

Reviewed-by: Weiwei Li 

Regards,

Weiwei Li

---
  target/riscv/cpu.h | 12 
  target/riscv/machine.c |  5 ++---
  2 files changed, 2 insertions(+), 15 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 83a9fa38d9..6290c6d357 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -173,8 +173,6 @@ struct CPUArchState {
  /* 128-bit helpers upper part return value */
  target_ulong retxh;
  
-uint32_t features;

-
  #ifdef CONFIG_USER_ONLY
  uint32_t elf_flags;
  #endif
@@ -525,16 +523,6 @@ static inline int riscv_has_ext(CPURISCVState *env, 
target_ulong ext)
  return (env->misa_ext & ext) != 0;
  }
  
-static inline bool riscv_feature(CPURISCVState *env, int feature)

-{
-return env->features & (1ULL << feature);
-}
-
-static inline void riscv_set_feature(CPURISCVState *env, int feature)
-{
-env->features |= (1ULL << feature);
-}
-
  #include "cpu_user.h"
  
  extern const char * const riscv_int_regnames[];

diff --git a/target/riscv/machine.c b/target/riscv/machine.c
index 67e9e56853..9c455931d8 100644
--- a/target/riscv/machine.c
+++ b/target/riscv/machine.c
@@ -331,8 +331,8 @@ static const VMStateDescription vmstate_pmu_ctr_state = {
  
  const VMStateDescription vmstate_riscv_cpu = {

  .name = "cpu",
-.version_id = 6,
-.minimum_version_id = 6,
+.version_id = 7,
+.minimum_version_id = 7,
  .post_load = riscv_cpu_post_load,
  .fields = (VMStateField[]) {
  VMSTATE_UINTTL_ARRAY(env.gpr, RISCVCPU, 32),
@@ -351,7 +351,6 @@ const VMStateDescription vmstate_riscv_cpu = {
  VMSTATE_UINT32(env.misa_ext, RISCVCPU),
  VMSTATE_UINT32(env.misa_mxl_max, RISCVCPU),
  VMSTATE_UINT32(env.misa_ext_mask, RISCVCPU),
-VMSTATE_UINT32(env.features, RISCVCPU),
  VMSTATE_UINTTL(env.priv, RISCVCPU),
  VMSTATE_UINTTL(env.virt, RISCVCPU),
  VMSTATE_UINT64(env.resetvec, RISCVCPU),





Re: [PATCH 18/18] target/riscv: Move configuration check to envcfg CSRs predicate()

2023-02-14 Thread weiwei



On 2023/2/15 10:22, Bin Meng wrote:

On Tue, Feb 14, 2023 at 10:59 PM weiwei  wrote:


On 2023/2/14 22:27, Bin Meng wrote:

At present the envcfg CSRs predicate() routines are generic one like
smode(), hmode. The configuration check is done in the read / write
routine. Create a new predicate routine to cover such check, so that
gdbstub can correctly report its existence.

Signed-off-by: Bin Meng 

---

   target/riscv/csr.c | 98 +-
   1 file changed, 61 insertions(+), 37 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 37350b8a6d..284ccc09dd 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -41,40 +41,6 @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops)
   }

   /* Predicates */
-#if !defined(CONFIG_USER_ONLY)
-static RISCVException smstateen_acc_ok(CPURISCVState *env, int index,
-   uint64_t bit)
-{
-bool virt = riscv_cpu_virt_enabled(env);
-RISCVCPU *cpu = env_archcpu(env);
-
-if (env->priv == PRV_M || !cpu->cfg.ext_smstateen) {
-return RISCV_EXCP_NONE;
-}
-
-if (!(env->mstateen[index] & bit)) {
-return RISCV_EXCP_ILLEGAL_INST;
-}
-
-if (virt) {
-if (!(env->hstateen[index] & bit)) {
-return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
-}
-
-if (env->priv == PRV_U && !(env->sstateen[index] & bit)) {
-return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
-}
-}
-
-if (env->priv == PRV_U && riscv_has_ext(env, RVS)) {
-if (!(env->sstateen[index] & bit)) {
-return RISCV_EXCP_ILLEGAL_INST;
-}
-}
-
-return RISCV_EXCP_NONE;
-}
-#endif

   static RISCVException fs(CPURISCVState *env, int csrno)
   {
@@ -318,6 +284,32 @@ static RISCVException umode32(CPURISCVState *env, int 
csrno)
   return umode(env, csrno);
   }

+static RISCVException envcfg(CPURISCVState *env, int csrno)
+{
+RISCVCPU *cpu = env_archcpu(env);
+riscv_csr_predicate_fn predicate;
+
+if (cpu->cfg.ext_smstateen) {
+return RISCV_EXCP_ILLEGAL_INST;
+}

This check seems not right here.  Why  ILLEGAL_INST is directly
triggered if smstateen is enabled?

This logic was there in the original codes. I was confused when I
looked at this as well.


Sorry, I didn't find the original codes. Do you mean this:

if (env->priv == PRV_M || !cpu->cfg.ext_smstateen) {
return RISCV_EXCP_NONE;
}

If so, I think the check here is to make the following *stateen related
check ignored when smstateen extension is disabled.

Regards,

Weiwei Li


Anyway, if it is an issue, it should be a separate patch.


It seems that smstateen related check will be done  for
senvcfg/henvcfg{h} when smstateen is enabled.


Regards,
Bin





Re: [PATCH v3 02/10] target/riscv: always allow write_misa() to write MISA

2023-02-15 Thread weiwei



On 2023/2/16 02:57, Daniel Henrique Barboza wrote:

At this moment, and apparently since ever, we have no way of enabling
RISCV_FEATURE_MISA. This means that all the code from write_misa(), all
the nuts and bolts that handles how to properly write this CSR, has
always been a no-op as well because write_misa() will always exit
earlier.

This seems to be benign in the majority of cases. Booting an Ubuntu
'virt' guest and logging all the calls to 'write_misa' shows that no
writes to MISA CSR was attempted. Writing MISA, i.e. enabling/disabling
RISC-V extensions after the machine is powered on, seems to be a niche
use.

Regardless, the spec says that MISA is a WARL read-write CSR, and gating
the writes in the register doesn't make sense. OS and applications
should be wary of the consequences when writing it, but the write itself
must always be allowed.

Remove the RISCV_FEATURE_MISA verification at the start of write_misa(),
removing RISCV_FEATURE_MISA altogether since there will be no more
callers of this enum.

Signed-off-by: Daniel Henrique Barboza 
---
  target/riscv/cpu.h | 1 -
  target/riscv/csr.c | 5 -
  2 files changed, 6 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 7128438d8e..01803a020d 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -89,7 +89,6 @@ enum {
  RISCV_FEATURE_MMU,
  RISCV_FEATURE_PMP,
  RISCV_FEATURE_EPMP,
-RISCV_FEATURE_MISA,
  RISCV_FEATURE_DEBUG
  };
  
diff --git a/target/riscv/csr.c b/target/riscv/csr.c

index e149b453da..5bd4cdbef5 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1329,11 +1329,6 @@ static RISCVException read_misa(CPURISCVState *env, int 
csrno,
  static RISCVException write_misa(CPURISCVState *env, int csrno,
   target_ulong val)
  {
-if (!riscv_feature(env, RISCV_FEATURE_MISA)) {
-/* drop write to misa */
-return RISCV_EXCP_NONE;
-}
-


I have a question here:

If we directly remove this here without other limits, the bugs 
introduced by following code


will be exposed to users, such as:

- V may be still enabled when misa.D is cleared.

- Zfh/Zfhmin may be still enabled when misa.D is cleared

- Misa.U may be cleared when Misa.S is still set.

...

Should we fix these bugs before this patch? Or fix them in following 
patchset?


If we choose the latter, I think it's better to add a limitation(such 
as  writable_mask) to the changable fields of misa here.


Regards,

Weiwei Li


  /* 'I' or 'E' must be present */
  if (!(val & (RVI | RVE))) {
  /* It is not, drop write to misa */





Re: [PATCH v6 1/9] target/riscv: turn write_misa() into an official no-op

2023-02-16 Thread weiwei



On 2023/2/17 05:55, Daniel Henrique Barboza wrote:

At this moment, and apparently since ever, we have no way of enabling
RISCV_FEATURE_MISA. This means that all the code from write_misa(), all
the nuts and bolts that handles how to write this CSR, has always been a
no-op as well because write_misa() will always exit earlier.

This seems to be benign in the majority of cases. Booting an Ubuntu
'virt' guest and logging all the calls to 'write_misa' shows that no
writes to MISA CSR was attempted. Writing MISA, i.e. enabling/disabling
RISC-V extensions after the machine is powered on, seems to be a niche
use.

Before proceeding, let's recap what the spec says about MISA. It is a
CSR that is divided in 3 fields:

- MXL, Machine XLEN, described as "may be writable";

- MXLEN, the XLEN in M-mode, which is given by the setting of MXL or a
fixed value if MISA is zero;

- Extensions is defined as "a WARL field that can contain writable bits
where the implementation allows the supported ISA to be modified"

Thus what we have today (write_misa() being a no-op) is already a valid
spec implementation. We're not obliged to have a particular set of MISA
writable bits, and at this moment we have none.

Given that allowing the dormant code to write MISA can cause tricky bugs
to solve later on, and we don't have a particularly interesting case of
writing MISA to support today, and we're already not violating the
specification, let's erase all the body of write_misa() and turn it into
an official no-op instead of an accidental one. We'll keep consistent
with what we provide users today but with 50+ less lines to maintain.

RISCV_FEATURE_MISA enum is erased in the process since there's no one
else using it.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Bin Meng 
Reviewed-by: Andrew Jones 

Reviewed-by: Weiwei Li 

Regards,

Weiwei Li

---
  target/riscv/cpu.h |  1 -
  target/riscv/csr.c | 55 --
  2 files changed, 56 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 7128438d8e..01803a020d 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -89,7 +89,6 @@ enum {
  RISCV_FEATURE_MMU,
  RISCV_FEATURE_PMP,
  RISCV_FEATURE_EPMP,
-RISCV_FEATURE_MISA,
  RISCV_FEATURE_DEBUG
  };
  
diff --git a/target/riscv/csr.c b/target/riscv/csr.c

index 1b0a0c1693..f7862ff4a4 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1329,61 +1329,6 @@ static RISCVException read_misa(CPURISCVState *env, int 
csrno,
  static RISCVException write_misa(CPURISCVState *env, int csrno,
   target_ulong val)
  {
-if (!riscv_feature(env, RISCV_FEATURE_MISA)) {
-/* drop write to misa */
-return RISCV_EXCP_NONE;
-}
-
-/* 'I' or 'E' must be present */
-if (!(val & (RVI | RVE))) {
-/* It is not, drop write to misa */
-return RISCV_EXCP_NONE;
-}
-
-/* 'E' excludes all other extensions */
-if (val & RVE) {
-/* when we support 'E' we can do "val = RVE;" however
- * for now we just drop writes if 'E' is present.
- */
-return RISCV_EXCP_NONE;
-}
-
-/*
- * misa.MXL writes are not supported by QEMU.
- * Drop writes to those bits.
- */
-
-/* Mask extensions that are not supported by this hart */
-val &= env->misa_ext_mask;
-
-/* Mask extensions that are not supported by QEMU */
-val &= (RVI | RVE | RVM | RVA | RVF | RVD | RVC | RVS | RVU | RVV);
-
-/* 'D' depends on 'F', so clear 'D' if 'F' is not present */
-if ((val & RVD) && !(val & RVF)) {
-val &= ~RVD;
-}
-
-/* Suppress 'C' if next instruction is not aligned
- * TODO: this should check next_pc
- */
-if ((val & RVC) && (GETPC() & ~3) != 0) {
-val &= ~RVC;
-}
-
-/* If nothing changed, do nothing. */
-if (val == env->misa_ext) {
-return RISCV_EXCP_NONE;
-}
-
-if (!(val & RVF)) {
-env->mstatus &= ~MSTATUS_FS;
-}
-
-/* flush translation cache */
-tb_flush(env_cpu(env));
-env->misa_ext = val;
-env->xl = riscv_cpu_mxl(env);
  return RISCV_EXCP_NONE;
  }
  





Re: [PATCH v6 2/9] target/riscv: introduce riscv_cpu_cfg()

2023-02-16 Thread weiwei



On 2023/2/17 05:55, Daniel Henrique Barboza wrote:

We're going to do changes that requires accessing the RISCVCPUConfig
struct from the RISCVCPU, having access only to a CPURISCVState 'env'
pointer. Add a helper to make the code easier to read.

Signed-off-by: Daniel Henrique Barboza 

Reviewed-by: Weiwei Li 

Regards,

Weiwei Li

---
  target/riscv/cpu.h | 5 +
  1 file changed, 5 insertions(+)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 01803a020d..5e9626837b 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -653,6 +653,11 @@ static inline RISCVMXL riscv_cpu_mxl(CPURISCVState *env)
  #endif
  #define riscv_cpu_mxl_bits(env) (1UL << (4 + riscv_cpu_mxl(env)))
  
+static inline const RISCVCPUConfig *riscv_cpu_cfg(CPURISCVState *env)

+{
+return &env_archcpu(env)->cfg;
+}
+
  #if defined(TARGET_RISCV32)
  #define cpu_recompute_xl(env)  ((void)(env), MXL_RV32)
  #else





Re: [PATCH] [PATCH] disas/riscv Fix ctzw disassemble

2023-02-18 Thread weiwei



On 2023/2/18 00:10, Ivan Klokov wrote:

Due to typo in opcode list, ctzw is disassembled as clzw instruction.

Fixes: 02c1b569a15b ("disas/riscv: Add Zb[abcs] instructions")
Signed-off-by: Ivan Klokov 
---
v2:
- added fixes line


Reviewed-by: Weiwei Li 

Weiwei Li

---
  disas/riscv.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/disas/riscv.c b/disas/riscv.c
index ddda687c13..544558 100644
--- a/disas/riscv.c
+++ b/disas/riscv.c
@@ -1645,7 +1645,7 @@ const rv_opcode_data opcode_data[] = {
  { "max", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
  { "maxu", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
  { "clzw", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
-{ "clzw", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
+{ "ctzw", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
  { "cpopw", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
  { "slli.uw", rv_codec_i_sh5, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
  { "add.uw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },





Re: [PATCH v6 2/4] target/riscv: implement Zicboz extension

2023-02-18 Thread weiwei
ware; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define REQUIRE_ZICBOZ(ctx) do {\
+if (!ctx->cfg_ptr->ext_icboz) { \
+return false;   \
+}   \
+} while (0)
+
+static bool trans_cbo_zero(DisasContext *ctx, arg_cbo_zero *a)
+{
+REQUIRE_ZICBOZ(ctx);
+gen_helper_cbo_zero(cpu_env, cpu_gpr[a->rs1]);
+return true;
+}
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index 48f918b71b..c5053e9446 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -3,6 +3,7 @@
   *
   * Copyright (c) 2016-2017 Sagar Karandikar, sag...@eecs.berkeley.edu
   * Copyright (c) 2017-2018 SiFive, Inc.
+ * Copyright (c) 2022  VRULL GmbH
   *
   * This program is free software; you can redistribute it and/or modify it
   * under the terms and conditions of the GNU General Public License,
@@ -123,6 +124,60 @@ target_ulong helper_csrrw_i128(CPURISCVState *env, int csr,
  return int128_getlo(rv);
  }
  
+

+/*
+ * check_zicbo_envcfg
+ *
+ * Raise virtual exceptions and illegal instruction exceptions for
+ * Zicbo[mz] instructions based on the settings of [mhs]envcfg as
+ * specified in section 2.5.1 of the CMO specification.
+ */
+static void check_zicbo_envcfg(CPURISCVState *env, target_ulong envbits,
+uintptr_t ra)
+{
+#ifndef CONFIG_USER_ONLY
+/*
+ * Check for virtual instruction exceptions first, as we don't see
+ * VU and VS reflected in env->priv (these are just the translated
+ * U and S stated with virtualisation enabled.
+ */
+if (riscv_cpu_virt_enabled(env) &&
+(((env->priv < PRV_H) && !get_field(env->henvcfg, envbits)) ||
+ ((env->priv < PRV_S) && !get_field(env->senvcfg, envbits {
+riscv_raise_exception(env, RISCV_EXCP_VIRT_INSTRUCTION_FAULT, ra);
+}


Check of (env->priv < PRV_M) && !get_field(env->menvcfg, envbits) should 
be put before upper check.


Illegal instruction exception should be triggered if (env->priv < PRV_M) 
&& !get_field(env->menvcfg, envbits).


However, virtual instruction exception may be triggered if we do upper 
check firstly.


Regards,

Weiwei Li


+
+if (((env->priv < PRV_M) && !get_field(env->menvcfg, envbits)) ||
+((env->priv < PRV_S) && !get_field(env->senvcfg, envbits))) {
+riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, ra);
+}
+#endif
+}
+
+void helper_cbo_zero(CPURISCVState *env, target_ulong address)
+{
+RISCVCPU *cpu = env_archcpu(env);
+uintptr_t ra = GETPC();
+uint16_t cbozlen;
+void *mem;
+
+check_zicbo_envcfg(env, MENVCFG_CBZE, ra);
+
+/* Get the size of the cache block for zero instructions. */
+cbozlen = cpu->cfg.cboz_blocksize;
+
+/* Mask off low-bits to align-down to the cache-block. */
+address &= ~(cbozlen - 1);
+
+mem = tlb_vaddr_to_host(env, address, MMU_DATA_STORE,
+cpu_mmu_index(env, false));
+
+if (likely(mem)) {
+/* Zero the block */
+memset(mem, 0, cbozlen);
+}
+}
+
  #ifndef CONFIG_USER_ONLY
  
  target_ulong helper_sret(CPURISCVState *env)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 772f9d7973..7f687a7e37 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1104,6 +1104,7 @@ static uint32_t opcode_at(DisasContextBase *dcbase, 
target_ulong pc)
  #include "insn_trans/trans_rvv.c.inc"
  #include "insn_trans/trans_rvb.c.inc"
  #include "insn_trans/trans_rvzawrs.c.inc"
+#include "insn_trans/trans_rvzicbo.c.inc"
  #include "insn_trans/trans_rvzfh.c.inc"
  #include "insn_trans/trans_rvk.c.inc"
  #include "insn_trans/trans_privileged.c.inc"





Re: [PATCH v1 5/7] contrib/gitdm: add ISCAS to the academics group

2022-09-26 Thread weiwei



On 2022/9/26 21:46, Alex Bennée wrote:

The English website (http://english.is.cas.cn/) in on a slightly
different domain but has the same logo as http://www.iscas.ac.cn/.

Signed-off-by: Alex Bennée 
Cc: Weiwei Li 
---
  contrib/gitdm/group-map-academics | 3 +++
  1 file changed, 3 insertions(+)

diff --git a/contrib/gitdm/group-map-academics 
b/contrib/gitdm/group-map-academics
index 44745ca85b..877a11e69b 100644
--- a/contrib/gitdm/group-map-academics
+++ b/contrib/gitdm/group-map-academics
@@ -19,3 +19,6 @@ edu.cn
  
  # Boston University

  bu.edu
+
+# Institute of Software Chinese Academy of Sciences
+iscas.ac.cn


Thanks for your update.  It looks good to me.

Reviewed-by: Weiwei Li 

Regards,

Weiwei Li




Re: [PATCH v9 1/4] target/riscv: Add smstateen support

2022-09-28 Thread weiwei
dex] & SMSTATEEN_STATEEN)) {
+return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
+}
+}
+}
+
+return smode(env, csrno);
+}
+
  /* Checks if PointerMasking registers could be accessed */
  static RISCVException pointer_masking(CPURISCVState *env, int csrno)
  {
@@ -1856,6 +1922,263 @@ static RISCVException write_henvcfgh(CPURISCVState 
*env, int csrno,
  return RISCV_EXCP_NONE;
  }
  
+static inline void write_smstateen(CPURISCVState *env, uint64_t *reg,

+   uint64_t wr_mask, uint64_t new_val)
+{
+*reg = (*reg & ~wr_mask) | (new_val & wr_mask);
+}
+
+static RISCVException read_mstateen(CPURISCVState *env, int csrno,
+target_ulong *val)
+{
+*val = env->mstateen[csrno - CSR_MSTATEEN0];
+
+return RISCV_EXCP_NONE;
+}
+
+static RISCVException write_mstateen(CPURISCVState *env, int csrno,
+ uint64_t wr_mask, target_ulong new_val)
+{
+uint64_t *reg;
+
+reg = &env->mstateen[csrno - CSR_MSTATEEN0];
+write_smstateen(env, reg, wr_mask, new_val);
+
+return RISCV_EXCP_NONE;
+}
+
+static RISCVException write_mstateen0(CPURISCVState *env, int csrno,
+  target_ulong new_val)
+{
+uint64_t wr_mask = SMSTATEEN_STATEEN;
+
+return write_mstateen(env, csrno, wr_mask, new_val);
+}
+
+static RISCVException write_mstateen1(CPURISCVState *env, int csrno,
+  target_ulong new_val)
+{
+return write_mstateen(env, csrno, SMSTATEEN_STATEEN, new_val);
+}
+
+static RISCVException write_mstateen2(CPURISCVState *env, int csrno,
+  target_ulong new_val)
+{
+return write_mstateen(env, csrno, SMSTATEEN_STATEEN, new_val);
+}
+
+static RISCVException write_mstateen3(CPURISCVState *env, int csrno,
+  target_ulong new_val)
+{
+return write_mstateen(env, csrno, SMSTATEEN_STATEEN, new_val);
+}


I still prefer mstateen1~3 to share the same read/write function currently.

If you  insist on distinguishing them, I think it's better to pass index 
directly  than pass csrno to calculate index.


The same to following similar cases.

Otherwise,

Reviewed-by: Weiwei Li 

Regards,

Weiwei Li


+
+static RISCVException read_mstateenh(CPURISCVState *env, int csrno,
+  target_ulong *val)
+{
+*val = env->mstateen[csrno - CSR_MSTATEEN0H] >> 32;
+
+return RISCV_EXCP_NONE;
+}
+
+static RISCVException write_mstateenh(CPURISCVState *env, int csrno,
+  uint64_t wr_mask, target_ulong new_val)
+{
+uint64_t *reg, val;
+
+reg = &env->mstateen[csrno - CSR_MSTATEEN0H];
+val = (uint64_t)new_val << 32;
+val |= *reg & 0x;
+write_smstateen(env, reg, wr_mask, val);
+
+return RISCV_EXCP_NONE;
+}
+
+static RISCVException write_mstateen0h(CPURISCVState *env, int csrno,
+  target_ulong new_val)
+{
+uint64_t wr_mask = SMSTATEEN_STATEEN;
+
+return write_mstateenh(env, csrno, wr_mask, new_val);
+}
+
+static RISCVException write_mstateen1h(CPURISCVState *env, int csrno,
+  target_ulong new_val)
+{
+return write_mstateenh(env, csrno, SMSTATEEN_STATEEN, new_val);
+}
+
+static RISCVException write_mstateen2h(CPURISCVState *env, int csrno,
+  target_ulong new_val)
+{
+return write_mstateenh(env, csrno, SMSTATEEN_STATEEN, new_val);
+}
+
+static RISCVException write_mstateen3h(CPURISCVState *env, int csrno,
+  target_ulong new_val)
+{
+return write_mstateenh(env, csrno, SMSTATEEN_STATEEN, new_val);
+}
+
+static RISCVException read_hstateen(CPURISCVState *env, int csrno,
+target_ulong *val)
+{
+int index = csrno - CSR_HSTATEEN0;
+
+*val = env->hstateen[index] & env->mstateen[index];
+
+return RISCV_EXCP_NONE;
+}
+
+static RISCVException write_hstateen(CPURISCVState *env, int csrno,
+ uint64_t mask, target_ulong new_val)
+{
+int index = csrno - CSR_HSTATEEN0;
+uint64_t *reg, wr_mask;
+
+reg = &env->hstateen[index];
+wr_mask = env->mstateen[index] & mask;
+write_smstateen(env, reg, wr_mask, new_val);
+
+return RISCV_EXCP_NONE;
+}
+
+static RISCVException write_hstateen0(CPURISCVState *env, int csrno,
+  target_ulong new_val)
+{
+uint64_t wr_mask = SMSTATEEN_STATEEN;
+
+return write_hstateen(env, csrno, wr_mask, new_val);
+}
+
+static RISCVException write_hstateen1(CPURISCVState *env, int csrno,
+  target_ulong new_val)
+{
+return write_hstateen(env, csrno, SMSTATEEN_STATEEN, new_val);
+}
+
+static RISCVException write_hstateen2(CPURISCVStat

Re: [PATCH v9 3/4] target/riscv: smstateen check for fcsr

2022-09-28 Thread weiwei



On 2022/9/19 14:29, Mayuresh Chitale wrote:

If smstateen is implemented and sstateen0.fcsr is clear then the floating point
operations must return illegal instruction exception or virtual instruction
trap, if relevant.

Signed-off-by: Mayuresh Chitale 
---
  target/riscv/csr.c| 23 +
  target/riscv/insn_trans/trans_rvf.c.inc   | 40 +--
  target/riscv/insn_trans/trans_rvzfh.c.inc | 12 +++
  3 files changed, 72 insertions(+), 3 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 59d5aa74ee..edaecf53ce 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -84,6 +84,10 @@ static RISCVException fs(CPURISCVState *env, int csrno)
  !RISCV_CPU(env_cpu(env))->cfg.ext_zfinx) {
  return RISCV_EXCP_ILLEGAL_INST;
  }
+
+if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
+return smstateen_acc_ok(env, 0, SMSTATEEN0_FCSR);
+}
  #endif
  return RISCV_EXCP_NONE;
  }
@@ -2024,6 +2028,9 @@ static RISCVException write_mstateen0(CPURISCVState *env, 
int csrno,
target_ulong new_val)
  {
  uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
+if (!riscv_has_ext(env, RVF)) {
+wr_mask |= SMSTATEEN0_FCSR;
+}
  
  return write_mstateen(env, csrno, wr_mask, new_val);

  }
@@ -2072,6 +2079,10 @@ static RISCVException write_mstateen0h(CPURISCVState 
*env, int csrno,
  {
  uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
  
+if (!riscv_has_ext(env, RVF)) {

+wr_mask |= SMSTATEEN0_FCSR;
+}
+
  return write_mstateenh(env, csrno, wr_mask, new_val);
  }
  
@@ -2121,6 +2132,10 @@ static RISCVException write_hstateen0(CPURISCVState *env, int csrno,

  {
  uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
  
+if (!riscv_has_ext(env, RVF)) {

+wr_mask |= SMSTATEEN0_FCSR;
+}
+
  return write_hstateen(env, csrno, wr_mask, new_val);
  }
  
@@ -2172,6 +2187,10 @@ static RISCVException write_hstateen0h(CPURISCVState *env, int csrno,

  {
  uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
  
+if (!riscv_has_ext(env, RVF)) {

+wr_mask |= SMSTATEEN0_FCSR;
+}
+
  return write_hstateenh(env, csrno, wr_mask, new_val);
  }
  
@@ -2231,6 +2250,10 @@ static RISCVException write_sstateen0(CPURISCVState *env, int csrno,

  {
  uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
  
+if (!riscv_has_ext(env, RVF)) {

+wr_mask |= SMSTATEEN0_FCSR;
+}
+
  return write_sstateen(env, csrno, wr_mask, new_val);
  }
  
diff --git a/target/riscv/insn_trans/trans_rvf.c.inc b/target/riscv/insn_trans/trans_rvf.c.inc

index a1d3eb52ad..ce8a0cc34b 100644
--- a/target/riscv/insn_trans/trans_rvf.c.inc
+++ b/target/riscv/insn_trans/trans_rvf.c.inc
@@ -24,9 +24,43 @@
  return false; \
  } while (0)
  
-#define REQUIRE_ZFINX_OR_F(ctx) do {\

-if (!ctx->cfg_ptr->ext_zfinx) { \
-REQUIRE_EXT(ctx, RVF); \
+#ifndef CONFIG_USER_ONLY
+static inline bool smstateen_check(DisasContext *ctx, int index)
+{
+CPUState *cpu = ctx->cs;
+CPURISCVState *env = cpu->env_ptr;
+uint64_t stateen = env->mstateen[index];
+
+if (!ctx->cfg_ptr->ext_smstateen || env->priv == PRV_M) {
+return true;
+}
+
+if (ctx->virt_enabled) {
+stateen &= env->hstateen[index];
+}
+
+if (env->priv == PRV_U && has_ext(ctx, RVS)) {
+stateen &= env->sstateen[index];
+}
+
+if (!(stateen & SMSTATEEN0_FCSR)) {
+return false;
+}
+
+return true;
+}
+#else
+#define smstateen_check(ctx, index) (true)
+#endif
+
+#define REQUIRE_ZFINX_OR_F(ctx) do { \
+if (!has_ext(ctx, RVF)) { \
+if (!ctx->cfg_ptr->ext_zfinx) { \
+return false; \
+} \
+if (!smstateen_check(ctx, 0)) { \
+return false; \
+} \
  } \
  } while (0)


I think the potential exception triggered by smstateen_check is not 
correct here:


"return false"  can only trigger illegal instruction exception.

However, smstateen_check  is for accessing fcsr CSR, It may trigger 
illegal or  virtual instruction exception


based on the privilege mode and Xstateen CSRs.

Regards,

Weiwei Li

  
diff --git a/target/riscv/insn_trans/trans_rvzfh.c.inc b/target/riscv/insn_trans/trans_rvzfh.c.inc

index 5d07150cd0..44d962c920 100644
--- a/target/riscv/insn_trans/trans_rvzfh.c.inc
+++ b/target/riscv/insn_trans/trans_rvzfh.c.inc
@@ -20,18 +20,27 @@
  if (!ctx->cfg_ptr->ext_zfh) {  \
  return false; \
  } \
+if (!smstateen_check(ctx, 0)) { \
+return false; \
+} \
  } while (0)
  
  #define REQUIRE_ZHINX_OR_ZFH(ctx) do { \

  if (!ctx->cfg_ptr->ext_zhinx && !ctx->cfg_ptr->ext_zfh) { \
  return false;   

Re: [PATCH v10 4/5] target/riscv: smstateen check for fcsr

2022-10-03 Thread weiwei



On 2022/10/3 19:47, Mayuresh Chitale wrote:

If smstateen is implemented and sstateen0.fcsr is clear then the floating point
operations must return illegal instruction exception or virtual instruction
trap, if relevant.

Signed-off-by: Mayuresh Chitale 
---
  target/riscv/csr.c| 23 
  target/riscv/insn_trans/trans_rvf.c.inc   | 43 +--
  target/riscv/insn_trans/trans_rvzfh.c.inc | 12 +++
  3 files changed, 75 insertions(+), 3 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 71236f2b5d..8b25f885ec 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -84,6 +84,10 @@ static RISCVException fs(CPURISCVState *env, int csrno)
  !RISCV_CPU(env_cpu(env))->cfg.ext_zfinx) {
  return RISCV_EXCP_ILLEGAL_INST;
  }
+
+if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
+return smstateen_acc_ok(env, 0, SMSTATEEN0_FCSR);
+}
  #endif
  return RISCV_EXCP_NONE;
  }
@@ -2023,6 +2027,9 @@ static RISCVException write_mstateen0(CPURISCVState *env, 
int csrno,
target_ulong new_val)
  {
  uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
+if (!riscv_has_ext(env, RVF)) {
+wr_mask |= SMSTATEEN0_FCSR;
+}
  
  return write_mstateen(env, csrno, wr_mask, new_val);

  }
@@ -2059,6 +2066,10 @@ static RISCVException write_mstateen0h(CPURISCVState 
*env, int csrno,
  {
  uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
  
+if (!riscv_has_ext(env, RVF)) {

+wr_mask |= SMSTATEEN0_FCSR;
+}
+
  return write_mstateenh(env, csrno, wr_mask, new_val);
  }
  
@@ -2096,6 +2107,10 @@ static RISCVException write_hstateen0(CPURISCVState *env, int csrno,

  {
  uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
  
+if (!riscv_has_ext(env, RVF)) {

+wr_mask |= SMSTATEEN0_FCSR;
+}
+
  return write_hstateen(env, csrno, wr_mask, new_val);
  }
  
@@ -2135,6 +2150,10 @@ static RISCVException write_hstateen0h(CPURISCVState *env, int csrno,

  {
  uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
  
+if (!riscv_has_ext(env, RVF)) {

+wr_mask |= SMSTATEEN0_FCSR;
+}
+
  return write_hstateenh(env, csrno, wr_mask, new_val);
  }
  
@@ -2182,6 +2201,10 @@ static RISCVException write_sstateen0(CPURISCVState *env, int csrno,

  {
  uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
  
+if (!riscv_has_ext(env, RVF)) {

+wr_mask |= SMSTATEEN0_FCSR;
+}
+
  return write_sstateen(env, csrno, wr_mask, new_val);
  }
  
diff --git a/target/riscv/insn_trans/trans_rvf.c.inc b/target/riscv/insn_trans/trans_rvf.c.inc

index a1d3eb52ad..93657680c6 100644
--- a/target/riscv/insn_trans/trans_rvf.c.inc
+++ b/target/riscv/insn_trans/trans_rvf.c.inc
@@ -24,9 +24,46 @@
  return false; \
  } while (0)
  
-#define REQUIRE_ZFINX_OR_F(ctx) do {\

-if (!ctx->cfg_ptr->ext_zfinx) { \
-REQUIRE_EXT(ctx, RVF); \
+#ifndef CONFIG_USER_ONLY
+static inline bool smstateen_fcsr_check(DisasContext *ctx, int index)
+{
+CPUState *cpu = ctx->cs;
+CPURISCVState *env = cpu->env_ptr;
+uint64_t stateen = env->mstateen[index];
+
+if (!ctx->cfg_ptr->ext_smstateen || env->priv == PRV_M) {
+return true;
+}
+
+if (ctx->virt_enabled) {
+stateen &= env->hstateen[index];
+}
+
+if (env->priv == PRV_U && has_ext(ctx, RVS)) {
+stateen &= env->sstateen[index];
+}
+
+if (!(stateen & SMSTATEEN0_FCSR)) {
+if (ctx->virt_enabled) {
+ctx->virt_inst_excp = true;
+}


Are there any considerations for adding  virt_inst_excp instead of directly

"generate_exception(ctx, RISCV_EXCP_VIRT_INSTRUCTION_FAULT)" here?

Regards,

Weiwei Li


+return false;
+}
+
+return true;
+}
+#else
+#define smstateen_fcsr_check(ctx, index) (true)
+#endif
+
+#define REQUIRE_ZFINX_OR_F(ctx) do { \
+if (!has_ext(ctx, RVF)) { \
+if (!ctx->cfg_ptr->ext_zfinx) { \
+return false; \
+} \
+if (!smstateen_fcsr_check(ctx, 0)) { \
+return false; \
+} \
  } \
  } while (0)
  
diff --git a/target/riscv/insn_trans/trans_rvzfh.c.inc b/target/riscv/insn_trans/trans_rvzfh.c.inc

index 5d07150cd0..6c2e338c0a 100644
--- a/target/riscv/insn_trans/trans_rvzfh.c.inc
+++ b/target/riscv/insn_trans/trans_rvzfh.c.inc
@@ -20,18 +20,27 @@
  if (!ctx->cfg_ptr->ext_zfh) {  \
  return false; \
  } \
+if (!smstateen_fcsr_check(ctx, 0)) { \
+return false; \
+} \
  } while (0)
  
  #define REQUIRE_ZHINX_OR_ZFH(ctx) do { \

  if (!ctx->cfg_ptr->ext_zhinx && !ctx->cfg_ptr->ext_zfh) { \
  return false;  \
  }  

Re: [PATCH v10 4/5] target/riscv: smstateen check for fcsr

2022-10-04 Thread weiwei


On 2022/10/4 14:51, mchit...@ventanamicro.com wrote:

On Mon, 2022-10-03 at 21:02 +0800, weiwei wrote:

On 2022/10/3 19:47, Mayuresh Chitale wrote:

If smstateen is implemented and sstateen0.fcsr is clear then the
floating point
operations must return illegal instruction exception or virtual
instruction
trap, if relevant.

Signed-off-by: Mayuresh Chitale
---
   target/riscv/csr.c| 23 
   target/riscv/insn_trans/trans_rvf.c.inc   | 43
+--
   target/riscv/insn_trans/trans_rvzfh.c.inc | 12 +++
   3 files changed, 75 insertions(+), 3 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 71236f2b5d..8b25f885ec 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -84,6 +84,10 @@ static RISCVException fs(CPURISCVState *env, int
csrno)
   !RISCV_CPU(env_cpu(env))->cfg.ext_zfinx) {
   return RISCV_EXCP_ILLEGAL_INST;
   }
+
+if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
+return smstateen_acc_ok(env, 0, SMSTATEEN0_FCSR);
+}
   #endif
   return RISCV_EXCP_NONE;
   }
@@ -2023,6 +2027,9 @@ static RISCVException
write_mstateen0(CPURISCVState *env, int csrno,
 target_ulong new_val)
   {
   uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
+if (!riscv_has_ext(env, RVF)) {
+wr_mask |= SMSTATEEN0_FCSR;
+}
   
   return write_mstateen(env, csrno, wr_mask, new_val);

   }
@@ -2059,6 +2066,10 @@ static RISCVException
write_mstateen0h(CPURISCVState *env, int csrno,
   {
   uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
   
+if (!riscv_has_ext(env, RVF)) {

+wr_mask |= SMSTATEEN0_FCSR;
+}
+
   return write_mstateenh(env, csrno, wr_mask, new_val);
   }
   
@@ -2096,6 +2107,10 @@ static RISCVException

write_hstateen0(CPURISCVState *env, int csrno,
   {
   uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
   
+if (!riscv_has_ext(env, RVF)) {

+wr_mask |= SMSTATEEN0_FCSR;
+}
+
   return write_hstateen(env, csrno, wr_mask, new_val);
   }
   
@@ -2135,6 +2150,10 @@ static RISCVException

write_hstateen0h(CPURISCVState *env, int csrno,
   {
   uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
   
+if (!riscv_has_ext(env, RVF)) {

+wr_mask |= SMSTATEEN0_FCSR;
+}
+
   return write_hstateenh(env, csrno, wr_mask, new_val);
   }
   
@@ -2182,6 +2201,10 @@ static RISCVException

write_sstateen0(CPURISCVState *env, int csrno,
   {
   uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
   
+if (!riscv_has_ext(env, RVF)) {

+wr_mask |= SMSTATEEN0_FCSR;
+}
+
   return write_sstateen(env, csrno, wr_mask, new_val);
   }
   
diff --git a/target/riscv/insn_trans/trans_rvf.c.inc

b/target/riscv/insn_trans/trans_rvf.c.inc
index a1d3eb52ad..93657680c6 100644
--- a/target/riscv/insn_trans/trans_rvf.c.inc
+++ b/target/riscv/insn_trans/trans_rvf.c.inc
@@ -24,9 +24,46 @@
   return false; \
   } while (0)
   
-#define REQUIRE_ZFINX_OR_F(ctx) do {\

-if (!ctx->cfg_ptr->ext_zfinx) { \
-REQUIRE_EXT(ctx, RVF); \
+#ifndef CONFIG_USER_ONLY
+static inline bool smstateen_fcsr_check(DisasContext *ctx, int
index)
+{
+CPUState *cpu = ctx->cs;
+CPURISCVState *env = cpu->env_ptr;
+uint64_t stateen = env->mstateen[index];
+
+if (!ctx->cfg_ptr->ext_smstateen || env->priv == PRV_M) {
+return true;
+}
+
+if (ctx->virt_enabled) {
+stateen &= env->hstateen[index];
+}
+
+if (env->priv == PRV_U && has_ext(ctx, RVS)) {
+stateen &= env->sstateen[index];
+}
+
+if (!(stateen & SMSTATEEN0_FCSR)) {
+if (ctx->virt_enabled) {
+ctx->virt_inst_excp = true;
+}

Are there any considerations for adding  virt_inst_excp instead of
directly

"generate_exception(ctx, RISCV_EXCP_VIRT_INSTRUCTION_FAULT)" here?

Regards,

Weiwei Li

I had considered it but I think this is a simpler approach as the rest
of the code path stays the same as generating an illegal instruction
exception, for e.g setting the bins value (tval).


OK,  we did need to set bins value for virt instruction exception. 
However I prefer directly call a


new gen_exception_virt function(similar togen_exception_illegal) here.


  Also we need to
return true from all the caller trans_* functions even if the smstateen
check has failed.


False is returned when smstateen check fails currently.

Regards,

Weiwei Li


+return false;
+}
+
+return true;
+}
+#else
+#define smstateen_fcsr_check(ctx, index) (true)
+#endif
+
+#define REQUIRE_ZFINX_OR_F(ctx) do { \
+if (!has_ext(ctx, RVF)) { \
+if (!ctx->cfg_ptr->ext_zfinx) { \
+return false; \
+} \
+if (!smstateen_fcsr_check(ctx, 0)) { \
+return false; \
+} \
   }

Re: [RFC 6/8] target/riscv: delete redundant check for zcd instructions in decode_opc

2022-10-25 Thread weiwei



On 2022/10/25 11:39, Alistair Francis wrote:

On Fri, Sep 30, 2022 at 11:28 AM Weiwei Li  wrote:

All the check for Zcd instructions have been done in their trans function

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
---
  target/riscv/translate.c | 7 ---
  1 file changed, 7 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 347bc913eb..a55b4a7849 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1087,13 +1087,6 @@ static void decode_opc(CPURISCVState *env, DisasContext 
*ctx, uint16_t opcode)
   ((opcode & 0xe003) == 0xe000) ||
   ((opcode & 0xe003) == 0xe002))) {
  gen_exception_illegal(ctx);
-} else if (!(has_ext(ctx, RVC) || ctx->cfg_ptr->ext_zcd ||
- ctx->cfg_ptr->ext_zcmp || ctx->cfg_ptr->ext_zcmt) &&
-   (((opcode & 0xe003) == 0x2000) ||
-((opcode & 0xe003) == 0x2002) ||
-((opcode & 0xe003) == 0xa000) ||
-((opcode & 0xe003) == 0xa002))) {
-gen_exception_illegal(ctx);

It's probably best to never add this in the first place.

Remember that the extension can't be enabled until the last patch, so
it's ok if we don't support it all in one go

Alistair


OK.  I'll update it in next version.

Regards,

Weiwei Li




  } else {
  ctx->opcode = opcode;
  ctx->pc_succ_insn = ctx->base.pc_next + 2;
--
2.25.1







Re: [PATCH] MAINTAINERS: Add some RISC-V reviewers

2023-02-08 Thread weiwei



On 2023/2/9 08:33, Alistair Francis wrote:

From: Alistair Francis 

This patch adds some active RISC-V members as reviewers to the
MAINTAINERS file.

Signed-off-by: Alistair Francis 
---
  MAINTAINERS | 3 +++
  1 file changed, 3 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 96e25f62ac..847bc7f131 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -287,6 +287,9 @@ RISC-V TCG CPUs
  M: Palmer Dabbelt 
  M: Alistair Francis 
  M: Bin Meng 
+R: Weiwei Li 
+R: Daniel Henrique Barboza 
+R: Liu Zhiwei 
  L: qemu-ri...@nongnu.org
  S: Supported
  F: target/riscv/


Acked-by: Weiwei Li 

Regards,

Weiwei Li




Re: [PATCH 01/11] target/riscv: do not mask unsupported QEMU extensions in write_misa()

2023-02-10 Thread weiwei



On 2023/2/10 21:36, Daniel Henrique Barboza wrote:

The masking done using env->misa_ext_mask already filters any extension
that QEMU doesn't support. If the hart supports the extension then QEMU
supports it as well.

If the masking done by env->misa_ext_mask is somehow letting unsupported
QEMU extensions pass by, misa_ext_mask itself needs to be fixed instead.

Signed-off-by: Daniel Henrique Barboza 


Reviewed-by: Weiwei Li 

Regards,

Weiwei Li

---
  target/riscv/csr.c | 3 ---
  1 file changed, 3 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 1b0a0c1693..e149b453da 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1356,9 +1356,6 @@ static RISCVException write_misa(CPURISCVState *env, int 
csrno,
  /* Mask extensions that are not supported by this hart */
  val &= env->misa_ext_mask;
  
-/* Mask extensions that are not supported by QEMU */

-val &= (RVI | RVE | RVM | RVA | RVF | RVD | RVC | RVS | RVU | RVV);
-
  /* 'D' depends on 'F', so clear 'D' if 'F' is not present */
  if ((val & RVD) && !(val & RVF)) {
  val &= ~RVD;





Re: [PATCH 02/11] target/riscv: allow users to actually write the MISA CSR

2023-02-10 Thread weiwei



On 2023/2/10 21:36, Daniel Henrique Barboza wrote:

At this moment, and apparently since ever, we have no way of enabling
RISCV_FEATURE_MISA. This means that all the code from write_misa(), all
the nuts and bolts that handles how to properly write this CSR, has
always been a no-op as well because write_misa() will always exit
earlier.

This seems to be benign in the majority of cases. Booting an Ubuntu
'virt' guest and logging all the calls to 'write_misa' shows that no
writes to MISA CSR was attempted. Writing MISA, i.e. enabling/disabling
RISC-V extensions after the machine is powered on, seems to be a niche
use.

There is a good chance that the code in write_misa() hasn't been
properly tested. Allowing users to write MISA can open the floodgates of
new breeds of bugs. We could instead remove most (if not all) of
write_misa() since it's never used. Well, as a hardware emulator,
dealing with crashes because a register write went wrong is what we're
here for.

Create a 'misa-w' CPU property to allow users to choose whether writes
to MISA should be allowed. The default is set to 'false' for all RISC-V
machines to keep compatibility with what we´ve been doing so far.

Read cpu->cfg.misa_w directly in write_misa(), instead of executing
riscv_set_feature(RISCV_FEATURE_MISA) in riscv_cpu_realize(), that would
simply reflect the cpu->cfg.misa_w bool value in 'env->features' and
require a riscv_feature() call to read it back.

Signed-off-by: Daniel Henrique Barboza 
---
  target/riscv/cpu.c | 1 +
  target/riscv/cpu.h | 1 +
  target/riscv/csr.c | 4 +++-
  3 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 93b52b826c..69fb9e123f 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1197,6 +1197,7 @@ static void register_cpu_props(DeviceState *dev)
  
  static Property riscv_cpu_properties[] = {

  DEFINE_PROP_BOOL("debug", RISCVCPU, cfg.debug, true),
+DEFINE_PROP_BOOL("misa-w", RISCVCPU, cfg.misa_w, false),
  
  DEFINE_PROP_UINT32("mvendorid", RISCVCPU, cfg.mvendorid, 0),

  DEFINE_PROP_UINT64("marchid", RISCVCPU, cfg.marchid, RISCV_CPU_MARCHID),
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 7128438d8e..103963b386 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -498,6 +498,7 @@ struct RISCVCPUConfig {
  bool pmp;
  bool epmp;
  bool debug;
+bool misa_w;
  
  bool short_isa_string;

  };
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index e149b453da..4f9cc501b2 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1329,7 +1329,9 @@ static RISCVException read_misa(CPURISCVState *env, int 
csrno,
  static RISCVException write_misa(CPURISCVState *env, int csrno,
   target_ulong val)
  {
-if (!riscv_feature(env, RISCV_FEATURE_MISA)) {
+RISCVCPU *cpu = env_archcpu(env);
+
+if (!cpu->cfg.misa_w) {


It's Ok to get it directly from cfg. However, personally, I prefer to 
keep the non-isa features in a separate list.


Regards,

Weiwei Li


  /* drop write to misa */
  return RISCV_EXCP_NONE;
  }





Re: [PATCH] target/riscv: avoid env_archcpu() in cpu_get_tb_cpu_state()

2023-02-10 Thread weiwei



On 2023/2/10 20:38, Daniel Henrique Barboza wrote:

We have a RISCVCPU *cpu pointer available at the start of the function.

Signed-off-by: Daniel Henrique Barboza 

Reviewed-by: Weiwei Li 

Regards,

Weiwei Li

---
  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 ad8d82662c..3a9472a2ff 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -60,7 +60,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong 
*pc,
   * which is not supported by GVEC. So we set vl_eq_vlmax flag to true
   * only when maxsz >= 8 bytes.
   */
-uint32_t vlmax = vext_get_vlmax(env_archcpu(env), env->vtype);
+uint32_t vlmax = vext_get_vlmax(cpu, env->vtype);
  uint32_t sew = FIELD_EX64(env->vtype, VTYPE, VSEW);
  uint32_t maxsz = vlmax << sew;
  bool vl_eq_vlmax = (env->vstart == 0) && (vlmax == env->vl) &&





Re: [PATCH v1 RFC Zisslpcfi 1/9] target/riscv: adding zimops and zisslpcfi extension to RISCV cpu config

2023-02-10 Thread weiwei



On 2023/2/9 14:23, Deepak Gupta wrote:

Introducing riscv `zisslpcfi` extension to riscv target. `zisslpcfi`
extension provides hardware assistance to riscv hart to enable control
flow integrity (CFI) for software.

`zisslpcfi` extension expects hart to implement `zimops`. `zimops` stands
for "unprivileged integer maybe operations". `zimops` carve out certain
reserved opcodes encodings from integer spec to "may be operations"
encodings. `zimops` opcode encodings simply move 0 to rd.
`zisslpcfi` claims some of the `zimops` encodings and use them for shadow
stack management or indirect branch tracking. Any future extension can
also claim `zimops` encodings.

This patch also adds a dependency check for `zimops` to be enabled if
`zisslpcfi` is enabled on the hart.

Signed-off-by: Deepak Gupta 
Signed-off-by: Kip Walker  
---
  target/riscv/cpu.c | 13 +
  target/riscv/cpu.h |  2 ++
  2 files changed, 15 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index cc75ca7667..6b4e90eb91 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -110,6 +110,8 @@ static const struct isa_ext_data isa_edata_arr[] = {
  ISA_EXT_DATA_ENTRY(svnapot, true, PRIV_VERSION_1_12_0, ext_svnapot),
  ISA_EXT_DATA_ENTRY(svpbmt, true, PRIV_VERSION_1_12_0, ext_svpbmt),
  ISA_EXT_DATA_ENTRY(xventanacondops, true, PRIV_VERSION_1_12_0, 
ext_XVentanaCondOps),
+ISA_EXT_DATA_ENTRY(zimops, true, PRIV_VERSION_1_12_0, ext_zimops),
+ISA_EXT_DATA_ENTRY(zisslpcfi, true, PRIV_VERSION_1_12_0, ext_cfi),


By convention, it  should be ext_zisslpcfi  .


  };
  
  static bool isa_ext_is_enabled(RISCVCPU *cpu,

@@ -792,6 +794,11 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
  return;
  }
  
+if (cpu->cfg.ext_cfi && !cpu->cfg.ext_zimops) {

+error_setg(errp, "Zisslpcfi extension requires Zimops extension");
+return;
+}
+


If  Zisslpcfi implicitly means Zimops is implemented as commented in 
following code, I think we should just enable zimops  when zisslpcfi is 
enabled.



  /* Set the ISA extensions, checks should have happened above */
  if (cpu->cfg.ext_zdinx || cpu->cfg.ext_zhinx ||
  cpu->cfg.ext_zhinxmin) {
@@ -1102,6 +1109,12 @@ static Property riscv_cpu_properties[] = {
  #ifndef CONFIG_USER_ONLY
  DEFINE_PROP_UINT64("resetvec", RISCVCPU, env.resetvec, DEFAULT_RSTVEC),
  #endif
+/*
+ * Zisslpcfi CFI extension, Zisslpcfi implicitly means Zimops is
+ * implemented
+ */
+DEFINE_PROP_BOOL("zisslpcfi", RISCVCPU, cfg.ext_cfi, true),
+DEFINE_PROP_BOOL("zimops", RISCVCPU, cfg.ext_zimops, true),


These properties can not expose to users before all its functions are 
ready. And it need add 'x-' prefix as experimental extensions currently.


Regards,

Weiwei Li

  
  DEFINE_PROP_BOOL("short-isa-string", RISCVCPU, cfg.short_isa_string, false),
  
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h

index f5609b62a2..9a923760b2 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -471,6 +471,8 @@ struct RISCVCPUConfig {
  uint32_t mvendorid;
  uint64_t marchid;
  uint64_t mimpid;
+bool ext_zimops;
+bool ext_cfi;
  
  /* Vendor-specific custom extensions */

  bool ext_XVentanaCondOps;





Re: [PATCH v1 RFC Zisslpcfi 2/9] target/riscv: zisslpcfi CSR, bit positions and other definitions

2023-02-10 Thread weiwei
 MENVCFG_PBMTE
  #define HENVCFG_STCE   MENVCFG_STCE
  
  /* For RV32 */

+#define HENVCFGH_SFCFIENMENVCFGH_SFCFIEN
+#define HENVCFGH_CFIMENVCFGH_CFI
  #define HENVCFGH_PBMTE  MENVCFGH_PBMTE
  #define HENVCFGH_STCE   MENVCFGH_STCE
  
diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h

index da32c61c85..f5bfc4955b 100644
--- a/target/riscv/pmp.h
+++ b/target/riscv/pmp.h
@@ -43,7 +43,8 @@ typedef enum {
  MSECCFG_MMWP  = 1 << 1,
  MSECCFG_RLB   = 1 << 2,
  MSECCFG_USEED = 1 << 8,
-MSECCFG_SSEED = 1 << 9
+MSECCFG_SSEED = 1 << 9,
+MSECCFG_MFCFIEN =  1 << 10


It's unnecessary to use multiple space after '='.

Regards,

Weiwei Li


  } mseccfg_field_t;
  
  typedef struct {





Re: [PATCH] target/riscv: Fix vslide1up.vf and vslide1down.vf

2023-02-13 Thread weiwei



On 2023/2/13 17:45, LIU Zhiwei wrote:

vslide1up_##BITWIDTH is used by the vslide1up.vx and vslide1up.vf. So its
scalar input should be uint64_t to hold the 64 bits float register.And the
same for vslide1down_##BITWIDTH.

This bug is caught when run these instructions on qemu-riscv32.

Signed-off-by: LIU Zhiwei 
---
  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 00de879787..3073c54871 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -5038,7 +5038,7 @@ GEN_VEXT_VSLIDEDOWN_VX(vslidedown_vx_w, uint32_t, H4)
  GEN_VEXT_VSLIDEDOWN_VX(vslidedown_vx_d, uint64_t, H8)
  
  #define GEN_VEXT_VSLIE1UP(BITWIDTH, H)  \

-static void vslide1up_##BITWIDTH(void *vd, void *v0, target_ulong s1,   \
+static void vslide1up_##BITWIDTH(void *vd, void *v0, uint64_t s1,   \
   void *vs2, CPURISCVState *env, uint32_t desc)  \
  {   \
  typedef uint##BITWIDTH##_t ETYPE;   \
@@ -5086,7 +5086,7 @@ GEN_VEXT_VSLIDE1UP_VX(vslide1up_vx_w, 32)
  GEN_VEXT_VSLIDE1UP_VX(vslide1up_vx_d, 64)
  
  #define GEN_VEXT_VSLIDE1DOWN(BITWIDTH, H) \

-static void vslide1down_##BITWIDTH(void *vd, void *v0, target_ulong s1,   \
+static void vslide1down_##BITWIDTH(void *vd, void *v0, uint64_t s1,   \
 void *vs2, CPURISCVState *env, uint32_t desc)  
\
  { 
\
  typedef uint##BITWIDTH##_t ETYPE; 
\

Reviewed-by: Weiwei Li 
Regards,
Weiwei Li




Re: [PATCH v10 3/5] target/riscv: generate virtual instruction exception

2022-10-10 Thread weiwei



On 2022/10/3 19:47, Mayuresh Chitale wrote:

This patch adds a mechanism to generate a virtual instruction
instruction exception instead of an illegal instruction exception
during instruction decode when virt is enabled.

Signed-off-by: Mayuresh Chitale 
---
  target/riscv/translate.c | 9 -
  1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index db123da5ec..6926b639de 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -76,6 +76,7 @@ typedef struct DisasContext {
 to reset this known value.  */
  int frm;
  RISCVMXL ol;
+bool virt_inst_excp;
  bool virt_enabled;
  const RISCVCPUConfig *cfg_ptr;
  bool hlsx;
@@ -243,7 +244,11 @@ static void gen_exception_illegal(DisasContext *ctx)
  {
  tcg_gen_st_i32(tcg_constant_i32(ctx->opcode), cpu_env,
 offsetof(CPURISCVState, bins));
-generate_exception(ctx, RISCV_EXCP_ILLEGAL_INST);
+if (ctx->virt_inst_excp) {
+generate_exception(ctx, RISCV_EXCP_VIRT_INSTRUCTION_FAULT);
+} else {
+generate_exception(ctx, RISCV_EXCP_ILLEGAL_INST);
+}
  }
  
  static void gen_exception_inst_addr_mis(DisasContext *ctx)

@@ -1067,6 +1072,7 @@ static void decode_opc(CPURISCVState *env, DisasContext 
*ctx, uint16_t opcode)
  if (!has_ext(ctx, RVC)) {
  gen_exception_illegal(ctx);


I think we should also set virt_inst_excp to false before this 
gen_exception_illegal.

By the way, why not just put  "ctx->virt_inst_excp = false;" at the 
begin of the decode_opc?


Regards,

Weiwei Li


  } else {
+ctx->virt_inst_excp = false;
  ctx->opcode = opcode;
  ctx->pc_succ_insn = ctx->base.pc_next + 2;
  if (decode_insn16(ctx, opcode)) {
@@ -1078,6 +1084,7 @@ static void decode_opc(CPURISCVState *env, DisasContext 
*ctx, uint16_t opcode)
  opcode32 = deposit32(opcode32, 16, 16,
   translator_lduw(env, &ctx->base,
   ctx->base.pc_next + 2));
+ctx->virt_inst_excp = false;
  ctx->opcode = opcode32;
  ctx->pc_succ_insn = ctx->base.pc_next + 4;
  





Re: [PATCH v10 4/5] target/riscv: smstateen check for fcsr

2022-10-10 Thread weiwei


On 2022/10/7 01:06, mchit...@ventanamicro.com wrote:

On Tue, 2022-10-04 at 21:23 +0800, weiwei wrote:



On 2022/10/4 14:51, mchit...@ventanamicro.com wrote:

On Mon, 2022-10-03 at 21:02 +0800, weiwei wrote:

On 2022/10/3 19:47, Mayuresh Chitale wrote:

If smstateen is implemented and sstateen0.fcsr is clear then the
floating point
operations must return illegal instruction exception or virtual
instruction
trap, if relevant.
Signed-off-by: Mayuresh Chitale

---
   target/riscv/csr.c| 23 
   target/riscv/insn_trans/trans_rvf.c.inc   | 43
+--
   target/riscv/insn_trans/trans_rvzfh.c.inc | 12 +++
   3 files changed, 75 insertions(+), 3 deletions(-)
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 71236f2b5d..8b25f885ec 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -84,6 +84,10 @@ static RISCVException fs(CPURISCVState *env, int
csrno)
   !RISCV_CPU(env_cpu(env))->cfg.ext_zfinx) {
   return RISCV_EXCP_ILLEGAL_INST;
   }
+
+if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
+return smstateen_acc_ok(env, 0, SMSTATEEN0_FCSR);
+}
   #endif
   return RISCV_EXCP_NONE;
   }
@@ -2023,6 +2027,9 @@ static RISCVException
write_mstateen0(CPURISCVState *env, int csrno,
 target_ulong new_val)
   {
   uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
+if (!riscv_has_ext(env, RVF)) {
+wr_mask |= SMSTATEEN0_FCSR;
+}
   
   return write_mstateen(env, csrno, wr_mask, new_val);

   }
@@ -2059,6 +2066,10 @@ static RISCVException
write_mstateen0h(CPURISCVState *env, int csrno,
   {
   uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
   
+if (!riscv_has_ext(env, RVF)) {

+wr_mask |= SMSTATEEN0_FCSR;
+}
+
   return write_mstateenh(env, csrno, wr_mask, new_val);
   }
   
@@ -2096,6 +2107,10 @@ static RISCVException

write_hstateen0(CPURISCVState *env, int csrno,
   {
   uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
   
+if (!riscv_has_ext(env, RVF)) {

+wr_mask |= SMSTATEEN0_FCSR;
+}
+
   return write_hstateen(env, csrno, wr_mask, new_val);
   }
   
@@ -2135,6 +2150,10 @@ static RISCVException

write_hstateen0h(CPURISCVState *env, int csrno,
   {
   uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
   
+if (!riscv_has_ext(env, RVF)) {

+wr_mask |= SMSTATEEN0_FCSR;
+}
+
   return write_hstateenh(env, csrno, wr_mask, new_val);
   }
   
@@ -2182,6 +2201,10 @@ static RISCVException

write_sstateen0(CPURISCVState *env, int csrno,
   {
   uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
   
+if (!riscv_has_ext(env, RVF)) {

+wr_mask |= SMSTATEEN0_FCSR;
+}
+
   return write_sstateen(env, csrno, wr_mask, new_val);
   }
   
diff --git a/target/riscv/insn_trans/trans_rvf.c.inc

b/target/riscv/insn_trans/trans_rvf.c.inc
index a1d3eb52ad..93657680c6 100644
--- a/target/riscv/insn_trans/trans_rvf.c.inc
+++ b/target/riscv/insn_trans/trans_rvf.c.inc
@@ -24,9 +24,46 @@
   return false; \
   } while (0)
   
-#define REQUIRE_ZFINX_OR_F(ctx) do {\

-if (!ctx->cfg_ptr->ext_zfinx) { \
-REQUIRE_EXT(ctx, RVF); \
+#ifndef CONFIG_USER_ONLY
+static inline bool smstateen_fcsr_check(DisasContext *ctx, int
index)
+{
+CPUState *cpu = ctx->cs;
+CPURISCVState *env = cpu->env_ptr;
+uint64_t stateen = env->mstateen[index];
+
+if (!ctx->cfg_ptr->ext_smstateen || env->priv == PRV_M) {
+return true;
+}
+
+if (ctx->virt_enabled) {
+stateen &= env->hstateen[index];
+}
+
+if (env->priv == PRV_U && has_ext(ctx, RVS)) {
+stateen &= env->sstateen[index];
+}
+
+if (!(stateen & SMSTATEEN0_FCSR)) {
+if (ctx->virt_enabled) {
+ctx->virt_inst_excp = true;
+}

Are there any considerations for adding  virt_inst_excp instead of
directly
"generate_exception(ctx, RISCV_EXCP_VIRT_INSTRUCTION_FAULT)" here?
Regards,
Weiwei Li

I had considered it but I think this is a simpler approach as the rest
of the code path stays the same as generating an illegal instruction
exception, for e.g setting the bins value (tval).


OK,  we did need to set bins value for virt instruction exception. 
However I prefer directly call a


new gen_exception_virt function(similar togen_exception_illegal) here.


  Also we need to
return true from all the caller trans_* functions even if the smstateen
check has failed.


False is returned when smstateen check fails currently.

Yes, however if we make this change then should return true if the 
check fails so that the decode_opc doesnt fall through and generate 
another exception. It can be done but it would be contrary to the 
general convention.


OK.  Acceptable to me.

Reviewed-by: Weiwei Li 

Regards,

Weiwei Li


Rega

Re: [PATCH v11 3/5] target/riscv: generate virtual instruction exception

2022-10-16 Thread weiwei



On 2022/10/16 20:47, Mayuresh Chitale wrote:

This patch adds a mechanism to generate a virtual instruction
instruction exception instead of an illegal instruction exception
during instruction decode when virt is enabled.

Signed-off-by: Mayuresh Chitale 
---
  target/riscv/translate.c | 8 +++-
  1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index db123da5ec..8b0bd38bb2 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -76,6 +76,7 @@ typedef struct DisasContext {
 to reset this known value.  */
  int frm;
  RISCVMXL ol;
+bool virt_inst_excp;
  bool virt_enabled;
  const RISCVCPUConfig *cfg_ptr;
  bool hlsx;
@@ -243,7 +244,11 @@ static void gen_exception_illegal(DisasContext *ctx)
  {
  tcg_gen_st_i32(tcg_constant_i32(ctx->opcode), cpu_env,
 offsetof(CPURISCVState, bins));
-generate_exception(ctx, RISCV_EXCP_ILLEGAL_INST);
+if (ctx->virt_inst_excp) {
+generate_exception(ctx, RISCV_EXCP_VIRT_INSTRUCTION_FAULT);
+} else {
+generate_exception(ctx, RISCV_EXCP_ILLEGAL_INST);
+}
  }
  
  static void gen_exception_inst_addr_mis(DisasContext *ctx)

@@ -1062,6 +1067,7 @@ static void decode_opc(CPURISCVState *env, DisasContext 
*ctx, uint16_t opcode)
  { has_XVentanaCondOps_p,  decode_XVentanaCodeOps },
  };
  
+ctx->virt_inst_excp = false;

  /* Check for compressed insn */
  if (insn_len(opcode) == 2) {
  if (!has_ext(ctx, RVC)) {

Reviewed-by: Weiwei Li 
Regards,
Weiwei Li




[PATCH v3 5/9] target/riscv: add support for Zcb extension

2022-11-16 Thread Weiwei Li
Add encode and trans* functions support for Zcb instructions

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
---
 target/riscv/insn16.decode|  24 ++
 target/riscv/insn_trans/trans_rvzce.c.inc | 100 ++
 target/riscv/translate.c  |   2 +
 3 files changed, 126 insertions(+)
 create mode 100644 target/riscv/insn_trans/trans_rvzce.c.inc

diff --git a/target/riscv/insn16.decode b/target/riscv/insn16.decode
index b62664b6af..47603ec1e0 100644
--- a/target/riscv/insn16.decode
+++ b/target/riscv/insn16.decode
@@ -43,6 +43,8 @@
 %imm_addi16sp  12:s1 3:2 5:1 2:1 6:1 !function=ex_shift_4
 %imm_lui   12:s1 2:5 !function=ex_shift_12
 
+%zcb_b_uimm  5:1 6:1
+%zcb_h_uimm  5:1 !function=ex_shift_1
 
 # Argument sets imported from insn32.decode:
 &empty  !extern
@@ -53,6 +55,7 @@
 &b imm rs2 rs1  !extern
 &u imm rd   !extern
 &shift shamt rs1 rd !extern
+&r2rd rs1   !extern
 
 
 # Formats 16:
@@ -89,6 +92,13 @@
 
 @c_andi ... . .. ... . .. &i imm=%imm_ci rs1=%rs1_3 rd=%rs1_3
 
+@zcb_unary... ...  ... .. ... ..  &r2  rs1=%rs1_3 rd=%rs1_3
+@zcb_binary   ... ...  ... .. ... ..  &r  rs2=%rs2_3   rs1=%rs1_3 rd=%rs1_3
+@zcb_lb   ... . .. ... .. ... ..  &i  imm=%zcb_b_uimm  rs1=%rs1_3 rd=%rs2_3
+@zcb_lh   ... . .. ... .. ... ..  &i  imm=%zcb_h_uimm  rs1=%rs1_3 rd=%rs2_3
+@zcb_sb   ... . .. ... .. ... ..  &s  imm=%zcb_b_uimm  rs1=%rs1_3 
rs2=%rs2_3
+@zcb_sh   ... . .. ... .. ... ..  &s  imm=%zcb_h_uimm  rs1=%rs1_3 
rs2=%rs2_3
+
 # *** RV32/64C Standard Extension (Quadrant 0) ***
 {
   # Opcode of all zeros is illegal; rd != 0, nzuimm == 0 is reserved.
@@ -180,3 +190,17 @@ sw110 .  .  . 10 @c_swsp
   sd  111 .  .  . 10 @c_sdsp
   c_fsw   111 .  .  . 10 @c_swsp
 }
+
+# *** RV64 and RV32 Zcb Extension ***
+c_zext_b  100 111  ... 11 000 01 @zcb_unary
+c_sext_b  100 111  ... 11 001 01 @zcb_unary
+c_zext_h  100 111  ... 11 010 01 @zcb_unary
+c_sext_h  100 111  ... 11 011 01 @zcb_unary
+c_zext_w  100 111  ... 11 100 01 @zcb_unary
+c_not 100 111  ... 11 101 01 @zcb_unary
+c_mul 100 111  ... 10 ... 01 @zcb_binary
+c_lbu 100 000  ... .. ... 00 @zcb_lb
+c_lhu 100 001  ... 0. ... 00 @zcb_lh
+c_lh  100 001  ... 1. ... 00 @zcb_lh
+c_sb  100 010  ... .. ... 00 @zcb_sb
+c_sh  100 011  ... 0. ... 00 @zcb_sh
diff --git a/target/riscv/insn_trans/trans_rvzce.c.inc 
b/target/riscv/insn_trans/trans_rvzce.c.inc
new file mode 100644
index 00..de96c4afaf
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rvzce.c.inc
@@ -0,0 +1,100 @@
+/*
+ * RISC-V translation routines for the Zcb Standard Extension.
+ *
+ * Copyright (c) 2021-2022 PLCT Lab
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define REQUIRE_ZCB(ctx) do {   \
+if (!ctx->cfg_ptr->ext_zcb) \
+return false;   \
+} while (0)
+
+static bool trans_c_zext_b(DisasContext *ctx, arg_c_zext_b *a)
+{
+REQUIRE_ZCB(ctx);
+return gen_unary(ctx, a, EXT_NONE, tcg_gen_ext8u_tl);
+}
+
+static bool trans_c_zext_h(DisasContext *ctx, arg_c_zext_h *a)
+{
+REQUIRE_ZCB(ctx);
+REQUIRE_ZBB(ctx);
+return gen_unary(ctx, a, EXT_NONE, tcg_gen_ext16u_tl);
+}
+
+static bool trans_c_sext_b(DisasContext *ctx, arg_c_sext_b *a)
+{
+REQUIRE_ZCB(ctx);
+REQUIRE_ZBB(ctx);
+return gen_unary(ctx, a, EXT_NONE, tcg_gen_ext8s_tl);
+}
+
+static bool trans_c_sext_h(DisasContext *ctx, arg_c_sext_h *a)
+{
+REQUIRE_ZCB(ctx);
+REQUIRE_ZBB(ctx);
+return gen_unary(ctx, a, EXT_NONE, tcg_gen_ext16s_tl);
+}
+
+static bool trans_c_zext_w(DisasContext *ctx, arg_c_zext_w *a)
+{
+REQUIRE_64BIT(ctx);
+REQUIRE_ZCB(ctx);
+REQUIRE_ZBA(ctx);
+return gen_unary(ctx, a, EXT_NONE, tcg_gen_ext32u_tl);
+}
+
+static bool trans_c_not(DisasContext *ctx, arg_c_not *a)
+{
+REQUIRE_ZCB(ctx);
+return gen_unary(ctx, a, EXT_NONE, tcg_gen_not_tl);
+}
+
+static bool trans_c_mul(DisasContext *ctx, arg_c_mul *a)
+{
+REQUIRE_ZCB(ctx);
+REQUIRE_M_OR_ZMMUL(ctx);
+return gen_arith(ctx, a, EXT_NONE, tcg_gen_mul_tl, NULL);
+}
+
+static bool trans_c_lbu(DisasContext *ctx, 

[PATCH v3 3/9] target/riscv: add support for Zcf extension

2022-11-16 Thread Weiwei Li
Separate c_flw/c_fsw from flw/fsw to add check for Zcf extension

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
---
 target/riscv/insn16.decode  |  8 
 target/riscv/insn_trans/trans_rvf.c.inc | 18 ++
 2 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/target/riscv/insn16.decode b/target/riscv/insn16.decode
index ccfe59f294..f3ea650325 100644
--- a/target/riscv/insn16.decode
+++ b/target/riscv/insn16.decode
@@ -109,11 +109,11 @@ sw110  ... ... .. ... 00 @cs_w
 # *** RV32C and RV64C specific Standard Extension (Quadrant 0) ***
 {
   ld  011  ... ... .. ... 00 @cl_d
-  flw 011  ... ... .. ... 00 @cl_w
+  c_flw   011  ... ... .. ... 00 @cl_w
 }
 {
   sd  111  ... ... .. ... 00 @cs_d
-  fsw 111  ... ... .. ... 00 @cs_w
+  c_fsw   111  ... ... .. ... 00 @cs_w
 }
 
 # *** RV32/64C Standard Extension (Quadrant 1) ***
@@ -174,9 +174,9 @@ sw110 .  .  . 10 @c_swsp
 {
   c64_illegal 011 -  0  - 10 # c.ldsp, RES rd=0
   ld  011 .  .  . 10 @c_ldsp
-  flw 011 .  .  . 10 @c_lwsp
+  c_flw   011 .  .  . 10 @c_lwsp
 }
 {
   sd  111 .  .  . 10 @c_sdsp
-  fsw 111 .  .  . 10 @c_swsp
+  c_fsw   111 .  .  . 10 @c_swsp
 }
diff --git a/target/riscv/insn_trans/trans_rvf.c.inc 
b/target/riscv/insn_trans/trans_rvf.c.inc
index 93657680c6..426518957b 100644
--- a/target/riscv/insn_trans/trans_rvf.c.inc
+++ b/target/riscv/insn_trans/trans_rvf.c.inc
@@ -24,6 +24,12 @@
 return false; \
 } while (0)
 
+#define REQUIRE_ZCF(ctx) do {  \
+if (!ctx->cfg_ptr->ext_zcf) {  \
+return false;  \
+}  \
+} while (0)
+
 #ifndef CONFIG_USER_ONLY
 static inline bool smstateen_fcsr_check(DisasContext *ctx, int index)
 {
@@ -96,6 +102,18 @@ static bool trans_fsw(DisasContext *ctx, arg_fsw *a)
 return true;
 }
 
+static bool trans_c_flw(DisasContext *ctx, arg_flw *a)
+{
+REQUIRE_ZCF(ctx);
+return trans_flw(ctx, a);
+}
+
+static bool trans_c_fsw(DisasContext *ctx, arg_fsw *a)
+{
+REQUIRE_ZCF(ctx);
+return trans_fsw(ctx, a);
+}
+
 static bool trans_fmadd_s(DisasContext *ctx, arg_fmadd_s *a)
 {
 REQUIRE_FPU;
-- 
2.25.1




[PATCH v3 6/9] target/riscv: add support for Zcmp extension

2022-11-16 Thread Weiwei Li
Add encode, trans* functions for Zcmp instructions

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
---
 target/riscv/insn16.decode|  18 ++
 target/riscv/insn_trans/trans_rvzce.c.inc | 242 +-
 target/riscv/translate.c  |   5 +
 3 files changed, 264 insertions(+), 1 deletion(-)

diff --git a/target/riscv/insn16.decode b/target/riscv/insn16.decode
index 47603ec1e0..4654c23052 100644
--- a/target/riscv/insn16.decode
+++ b/target/riscv/insn16.decode
@@ -21,6 +21,8 @@
 %rs1_3 7:3!function=ex_rvc_register
 %rs2_3 2:3!function=ex_rvc_register
 %rs2_5 2:5
+%sreg1 7:3!function=ex_sreg_register
+%sreg2 2:3!function=ex_sreg_register
 
 # Immediates:
 %imm_ci12:s1 2:5
@@ -45,6 +47,8 @@
 
 %zcb_b_uimm  5:1 6:1
 %zcb_h_uimm  5:1 !function=ex_shift_1
+%zcmp_spimm  2:2 !function=ex_shift_4
+%zcmp_rlist  4:4
 
 # Argument sets imported from insn32.decode:
 &empty  !extern
@@ -56,7 +60,9 @@
 &u imm rd   !extern
 &shift shamt rs1 rd !extern
 &r2rd rs1   !extern
+&r2_s  rs1 rs2  !extern
 
+&zcmp  zcmp_rlist zcmp_spimm
 
 # Formats 16:
 @cr  . .  .. &r  rs2=%rs2_5   rs1=%rd %rd
@@ -98,6 +104,8 @@
 @zcb_lh   ... . .. ... .. ... ..  &i  imm=%zcb_h_uimm  rs1=%rs1_3 rd=%rs2_3
 @zcb_sb   ... . .. ... .. ... ..  &s  imm=%zcb_b_uimm  rs1=%rs1_3 
rs2=%rs2_3
 @zcb_sh   ... . .. ... .. ... ..  &s  imm=%zcb_h_uimm  rs1=%rs1_3 
rs2=%rs2_3
+@zcmp ... ...     ..  &zcmp  %zcmp_rlist   %zcmp_spimm
+@cm_mv... ...  ... .. ... ..  &r2_s  rs2=%sreg2rs1=%sreg1
 
 # *** RV32/64C Standard Extension (Quadrant 0) ***
 {
@@ -177,6 +185,16 @@ slli  000 .  .  . 10 @c_shift2
 {
   sq  101  ... ... .. ... 10 @c_sqsp
   c_fsd   101   ..  . 10 @c_sdsp
+
+  # *** RV64 and RV32 Zcmp Extension ***
+  [
+cm_push 101  11000   .. 10 @zcmp
+cm_pop  101  11010   .. 10 @zcmp
+cm_popret   101  0   .. 10 @zcmp
+cm_popretz  101  11100   .. 10 @zcmp
+cm_mva01s   101  011 ... 11 ... 10 @cm_mv
+cm_mvsa01   101  011 ... 01 ... 10 @cm_mv
+  ]
 }
 sw110 .  .  . 10 @c_swsp
 
diff --git a/target/riscv/insn_trans/trans_rvzce.c.inc 
b/target/riscv/insn_trans/trans_rvzce.c.inc
index de96c4afaf..f45224e388 100644
--- a/target/riscv/insn_trans/trans_rvzce.c.inc
+++ b/target/riscv/insn_trans/trans_rvzce.c.inc
@@ -1,5 +1,5 @@
 /*
- * RISC-V translation routines for the Zcb Standard Extension.
+ * RISC-V translation routines for the Zc[b,mp] Standard Extension.
  *
  * Copyright (c) 2021-2022 PLCT Lab
  *
@@ -21,6 +21,11 @@
 return false;   \
 } while (0)
 
+#define REQUIRE_ZCMP(ctx) do {   \
+if (!ctx->cfg_ptr->ext_zcmp) \
+return false;\
+} while (0)
+
 static bool trans_c_zext_b(DisasContext *ctx, arg_c_zext_b *a)
 {
 REQUIRE_ZCB(ctx);
@@ -98,3 +103,238 @@ static bool trans_c_sh(DisasContext *ctx, arg_c_sh *a)
 REQUIRE_ZCB(ctx);
 return gen_store(ctx, a, MO_UW);
 }
+
+static bool gen_zcmp_check(DisasContext *ctx, arg_zcmp *a)
+{
+/* rlist 0 to 3 are reserved for future EABI variant */
+if (a->zcmp_rlist < 4) {
+return false;
+}
+
+/* rlist <= 6 when RV32E/RV64E */
+if (ctx->cfg_ptr->ext_e && a->zcmp_rlist > 6) {
+return false;
+}
+
+return true;
+}
+
+#define X_S08
+#define X_S19
+#define X_Sn16
+
+static inline void update_push_pop_list(target_ulong rlist, bool *xreg_list)
+{
+switch (rlist) {
+case 15:
+xreg_list[X_Sn + 11] = true;
+xreg_list[X_Sn + 10] = true;
+/* FALL THROUGH */
+case 14:
+xreg_list[X_Sn + 9] = true;
+/* FALL THROUGH */
+case 13:
+xreg_list[X_Sn + 8] = true;
+/* FALL THROUGH */
+case 12:
+xreg_list[X_Sn + 7] = true;
+/* FALL THROUGH */
+case 11:
+xreg_list[X_Sn + 6] = true;
+/* FALL THROUGH */
+case 10:
+xreg_list[X_Sn + 5] = true;
+/* FALL THROUGH */
+case 9:
+xreg_list[X_Sn + 4] = true;
+/* FALL THROUGH */
+case 8:
+xreg_list[X_Sn + 3] = true;
+/* FALL THROUGH */
+case 7:
+xreg_list[X_Sn + 2] = true;
+/* FALL THROUGH */
+case 6:
+xreg_list[X_S1] = true;
+/* FALL THROUGH */
+case 5:
+xreg_list[X_S0] = true;
+/* FALL THROUGH */
+case 4:
+xreg_list[xRA] = true;
+break;
+}
+}
+
+static inline target_ulong caculate_stack_adj(int bytes, target_ulong rlist,
+  target_ulong spimm)
+{
+target_ulong stack_adj_base = 0;

[PATCH v3 2/9] target/riscv: add support for Zca extension

2022-11-16 Thread Weiwei Li
Modify the check for C extension to Zca (C implies Zca)

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
---
 target/riscv/insn_trans/trans_rvi.c.inc | 4 ++--
 target/riscv/translate.c| 8 ++--
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvi.c.inc 
b/target/riscv/insn_trans/trans_rvi.c.inc
index 5c69b88d1e..0d73b919ce 100644
--- a/target/riscv/insn_trans/trans_rvi.c.inc
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
@@ -56,7 +56,7 @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
 tcg_gen_andi_tl(cpu_pc, cpu_pc, (target_ulong)-2);
 
 gen_set_pc(ctx, cpu_pc);
-if (!has_ext(ctx, RVC)) {
+if (!ctx->cfg_ptr->ext_zca) {
 TCGv t0 = tcg_temp_new();
 
 misaligned = gen_new_label();
@@ -178,7 +178,7 @@ static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond 
cond)
 
 gen_set_label(l); /* branch taken */
 
-if (!has_ext(ctx, RVC) && ((ctx->base.pc_next + a->imm) & 0x3)) {
+if (!ctx->cfg_ptr->ext_zca && ((ctx->base.pc_next + a->imm) & 0x3)) {
 /* misaligned */
 gen_exception_inst_addr_mis(ctx);
 } else {
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 2ab8772ebe..ee24b451e3 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -557,7 +557,7 @@ static void gen_jal(DisasContext *ctx, int rd, target_ulong 
imm)
 
 /* check misaligned: */
 next_pc = ctx->base.pc_next + imm;
-if (!has_ext(ctx, RVC)) {
+if (!ctx->cfg_ptr->ext_zca) {
 if ((next_pc & 0x3) != 0) {
 gen_exception_inst_addr_mis(ctx);
 return;
@@ -1097,7 +1097,11 @@ static void decode_opc(CPURISCVState *env, DisasContext 
*ctx, uint16_t opcode)
 ctx->virt_inst_excp = false;
 /* Check for compressed insn */
 if (insn_len(opcode) == 2) {
-if (!has_ext(ctx, RVC)) {
+/*
+ * Zca support all of the existing C extension, excluding all
+ * compressed floating point loads and stores
+ */
+if (!ctx->cfg_ptr->ext_zca) {
 gen_exception_illegal(ctx);
 } else {
 ctx->opcode = opcode;
-- 
2.25.1




[PATCH v3 1/9] target/riscv: add cfg properties for Zc* extension

2022-11-16 Thread Weiwei Li
Add properties for Zca,Zcb,Zcf,Zcd,Zcmp,Zcmt extension
Add check for these properties

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Cc: Alistair Francis 
---
 target/riscv/cpu.c | 43 +++
 target/riscv/cpu.h |  6 ++
 2 files changed, 49 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 042fd541b4..1ab04ab246 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -805,6 +805,49 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 }
 }
 
+if (cpu->cfg.ext_c) {
+cpu->cfg.ext_zca = true;
+if (cpu->cfg.ext_f && env->misa_mxl_max == MXL_RV32) {
+cpu->cfg.ext_zcf = true;
+}
+if (cpu->cfg.ext_d) {
+cpu->cfg.ext_zcd = true;
+}
+}
+
+if (env->misa_mxl_max != MXL_RV32 && cpu->cfg.ext_zcf) {
+error_setg(errp, "Zcf extension is only relevant to RV32");
+return;
+}
+
+if (!cpu->cfg.ext_f && cpu->cfg.ext_zcf) {
+error_setg(errp, "Zcf extension requires F extension");
+return;
+}
+
+if (!cpu->cfg.ext_d && cpu->cfg.ext_zcd) {
+error_setg(errp, "Zcd extensionrequires D extension");
+return;
+}
+
+if ((cpu->cfg.ext_zcf || cpu->cfg.ext_zcd || cpu->cfg.ext_zcb ||
+ cpu->cfg.ext_zcmp || cpu->cfg.ext_zcmt) && !cpu->cfg.ext_zca) {
+error_setg(errp, "Zcf/Zcd/Zcb/Zcmp/Zcmt extensions require Zca "
+ "extension");
+return;
+}
+
+if (cpu->cfg.ext_zcd && (cpu->cfg.ext_zcmp || cpu->cfg.ext_zcmt)) {
+error_setg(errp, "Zcmp/Zcmt extensions are incompatible with "
+ "Zcd extension");
+return;
+}
+
+if (cpu->cfg.ext_zcmt && !cpu->cfg.ext_icsr) {
+error_setg(errp, "Zcmt extension requires Zicsr extension");
+return;
+}
+
 if (cpu->cfg.ext_zk) {
 cpu->cfg.ext_zkn = true;
 cpu->cfg.ext_zkr = true;
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 9bd539d77a..6e915b6937 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -434,6 +434,12 @@ struct RISCVCPUConfig {
 bool ext_zbkc;
 bool ext_zbkx;
 bool ext_zbs;
+bool ext_zca;
+bool ext_zcb;
+bool ext_zcd;
+bool ext_zcf;
+bool ext_zcmp;
+bool ext_zcmt;
 bool ext_zk;
 bool ext_zkn;
 bool ext_zknd;
-- 
2.25.1




[PATCH v3 7/9] target/riscv: add support for Zcmt extension

2022-11-16 Thread Weiwei Li
Add encode, trans* functions and helper functions support for Zcmt
instrutions
Add support for jvt csr

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
---
 target/riscv/cpu.h|  2 +
 target/riscv/cpu_bits.h   |  7 +++
 target/riscv/csr.c| 35 ++
 target/riscv/helper.h |  3 ++
 target/riscv/insn16.decode|  7 ++-
 target/riscv/insn_trans/trans_rvf.c.inc   |  8 ++--
 target/riscv/insn_trans/trans_rvzce.c.inc | 29 +++-
 target/riscv/insn_trans/trans_rvzfh.c.inc |  6 +--
 target/riscv/machine.c| 19 
 target/riscv/meson.build  |  3 +-
 target/riscv/zce_helper.c | 57 +++
 11 files changed, 166 insertions(+), 10 deletions(-)
 create mode 100644 target/riscv/zce_helper.c

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 6e915b6937..0f9fffab2f 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -181,6 +181,8 @@ struct CPUArchState {
 
 uint32_t features;
 
+target_ulong jvt;
+
 #ifdef CONFIG_USER_ONLY
 uint32_t elf_flags;
 #endif
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 8b0d7e20ea..ce347e5575 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -319,6 +319,7 @@
 #define SMSTATEEN_MAX_COUNT 4
 #define SMSTATEEN0_CS   (1ULL << 0)
 #define SMSTATEEN0_FCSR (1ULL << 1)
+#define SMSTATEEN0_JVT  (1ULL << 2)
 #define SMSTATEEN0_HSCONTXT (1ULL << 57)
 #define SMSTATEEN0_IMSIC(1ULL << 58)
 #define SMSTATEEN0_AIA  (1ULL << 59)
@@ -523,6 +524,9 @@
 /* Crypto Extension */
 #define CSR_SEED0x015
 
+/* Zcmt Extension */
+#define CSR_JVT 0x017
+
 /* mstatus CSR bits */
 #define MSTATUS_UIE 0x0001
 #define MSTATUS_SIE 0x0002
@@ -894,4 +898,7 @@ typedef enum RISCVException {
 #define MHPMEVENT_IDX_MASK 0xF
 #define MHPMEVENT_SSCOF_RESVD  16
 
+/* JVT CSR bits */
+#define JVT_MODE   0x3F
+#define JVT_BASE   (~0x3F)
 #endif
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 8b25f885ec..901da42b53 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -167,6 +167,24 @@ static RISCVException ctr32(CPURISCVState *env, int csrno)
 return ctr(env, csrno);
 }
 
+static RISCVException zcmt(CPURISCVState *env, int csrno)
+{
+RISCVCPU *cpu = env_archcpu(env);
+
+if (!cpu->cfg.ext_zcmt) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
+#if !defined(CONFIG_USER_ONLY)
+RISCVException ret = smstateen_acc_ok(env, 0, SMSTATEEN0_JVT);
+if (ret != RISCV_EXCP_NONE) {
+return ret;
+}
+#endif
+
+return RISCV_EXCP_NONE;
+}
+
 #if !defined(CONFIG_USER_ONLY)
 static RISCVException mctr(CPURISCVState *env, int csrno)
 {
@@ -3987,6 +4005,20 @@ RISCVException riscv_csrrw_debug(CPURISCVState *env, int 
csrno,
 return ret;
 }
 
+static RISCVException read_jvt(CPURISCVState *env, int csrno,
+   target_ulong *val)
+{
+*val = env->jvt;
+return RISCV_EXCP_NONE;
+}
+
+static RISCVException write_jvt(CPURISCVState *env, int csrno,
+target_ulong val)
+{
+env->jvt = val;
+return RISCV_EXCP_NONE;
+}
+
 /* Control and Status Register function table */
 riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
 /* User Floating-Point CSRs */
@@ -4024,6 +4056,9 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
 /* Crypto Extension */
 [CSR_SEED] = { "seed", seed, NULL, NULL, rmw_seed },
 
+/* Zcmt Extension */
+[CSR_JVT] = {"jvt", zcmt, read_jvt, write_jvt},
+
 #if !defined(CONFIG_USER_ONLY)
 /* Machine Timers and Counters */
 [CSR_MCYCLE]= { "mcycle",any,   read_hpmcounter,
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 227c7122ef..2ae98f04d2 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1136,3 +1136,6 @@ DEF_HELPER_FLAGS_1(aes64im, TCG_CALL_NO_RWG_SE, tl, tl)
 
 DEF_HELPER_FLAGS_3(sm4ed, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl)
 DEF_HELPER_FLAGS_3(sm4ks, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl)
+
+/* Zce helper */
+DEF_HELPER_3(cm_jalt, tl, env, tl, tl)
diff --git a/target/riscv/insn16.decode b/target/riscv/insn16.decode
index 4654c23052..c359c574ab 100644
--- a/target/riscv/insn16.decode
+++ b/target/riscv/insn16.decode
@@ -49,6 +49,7 @@
 %zcb_h_uimm  5:1 !function=ex_shift_1
 %zcmp_spimm  2:2 !function=ex_shift_4
 %zcmp_rlist  4:4
+%zcmt_index  2:8
 
 # Argument sets imported from insn32.decode:
 &empty  !extern
@@ -63,6 +64,7 @@
 &r2_s  rs1 rs2  !extern
 
 &zcmp  zcmp_rlist zcmp_spimm
+&zcmt  zcmt_index
 
 # Formats 16:
 @cr  . .  .. &r  rs2=%rs2_5   rs1=%rd %rd

[PATCH v3 9/9] disas/riscv.c: add disasm support for Zc*

2022-11-16 Thread Weiwei Li
Zcmp/Zcmt instructions will override disasm for c.fld*/c.fsd*
instructions currently

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
---
 disas/riscv.c | 287 +-
 1 file changed, 286 insertions(+), 1 deletion(-)

diff --git a/disas/riscv.c b/disas/riscv.c
index d216b9c39b..81369063b5 100644
--- a/disas/riscv.c
+++ b/disas/riscv.c
@@ -163,6 +163,13 @@ typedef enum {
 rv_codec_v_i,
 rv_codec_vsetvli,
 rv_codec_vsetivli,
+rv_codec_zcb_ext,
+rv_codec_zcb_mul,
+rv_codec_zcb_lb,
+rv_codec_zcb_lh,
+rv_codec_zcmp_cm_pushpop,
+rv_codec_zcmp_cm_mv,
+rv_codec_zcmt_jt,
 } rv_codec;
 
 typedef enum {
@@ -935,6 +942,26 @@ typedef enum {
 rv_op_vsetvli = 766,
 rv_op_vsetivli = 767,
 rv_op_vsetvl = 768,
+rv_op_c_zext_b = 769,
+rv_op_c_sext_b = 770,
+rv_op_c_zext_h = 771,
+rv_op_c_sext_h = 772,
+rv_op_c_zext_w = 773,
+rv_op_c_not = 774,
+rv_op_c_mul = 775,
+rv_op_c_lbu = 776,
+rv_op_c_lhu = 777,
+rv_op_c_lh = 778,
+rv_op_c_sb = 779,
+rv_op_c_sh = 780,
+rv_op_cm_push = 781,
+rv_op_cm_pop = 782,
+rv_op_cm_popret = 783,
+rv_op_cm_popretz = 784,
+rv_op_cm_mva01s = 785,
+rv_op_cm_mvsa01 = 786,
+rv_op_cm_jt = 787,
+rv_op_cm_jalt = 788,
 } rv_op;
 
 /* structures */
@@ -958,6 +985,7 @@ typedef struct {
 uint8_t   rnum;
 uint8_t   vm;
 uint32_t  vzimm;
+uint8_t   rlist;
 } rv_decode;
 
 typedef struct {
@@ -1070,6 +1098,10 @@ static const char rv_vreg_name_sym[32][4] = {
 #define rv_fmt_vd_vm  "O\tDm"
 #define rv_fmt_vsetvli"O\t0,1,v"
 #define rv_fmt_vsetivli   "O\t0,u,v"
+#define rv_fmt_rs1_rs2_zce_ldst   "O\t2,i(1)"
+#define rv_fmt_push_rlist "O\tx,-i"
+#define rv_fmt_pop_rlist  "O\tx,i"
+#define rv_fmt_zcmt_index "O\ti"
 
 /* pseudo-instruction constraints */
 
@@ -2065,7 +2097,27 @@ const rv_opcode_data opcode_data[] = {
 { "vsext.vf8", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vsext_vf8, 
rv_op_vsext_vf8, 0 },
 { "vsetvli", rv_codec_vsetvli, rv_fmt_vsetvli, NULL, rv_op_vsetvli, 
rv_op_vsetvli, 0 },
 { "vsetivli", rv_codec_vsetivli, rv_fmt_vsetivli, NULL, rv_op_vsetivli, 
rv_op_vsetivli, 0 },
-{ "vsetvl", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, rv_op_vsetvl, 
rv_op_vsetvl, 0 }
+{ "vsetvl", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, rv_op_vsetvl, 
rv_op_vsetvl, 0 },
+{ "c.zext.b", rv_codec_zcb_ext, rv_fmt_rd, NULL, 0 },
+{ "c.sext.b", rv_codec_zcb_ext, rv_fmt_rd, NULL, 0 },
+{ "c.zext.h", rv_codec_zcb_ext, rv_fmt_rd, NULL, 0 },
+{ "c.sext.h", rv_codec_zcb_ext, rv_fmt_rd, NULL, 0 },
+{ "c.zext.w", rv_codec_zcb_ext, rv_fmt_rd, NULL, 0 },
+{ "c.not", rv_codec_zcb_ext, rv_fmt_rd, NULL, 0 },
+{ "c.mul", rv_codec_zcb_mul, rv_fmt_rd_rs2, NULL, 0, 0 },
+{ "c.lbu", rv_codec_zcb_lb, rv_fmt_rs1_rs2_zce_ldst, NULL, 0, 0, 0 },
+{ "c.lhu", rv_codec_zcb_lh, rv_fmt_rs1_rs2_zce_ldst, NULL, 0, 0, 0 },
+{ "c.lh", rv_codec_zcb_lh, rv_fmt_rs1_rs2_zce_ldst, NULL, 0, 0, 0 },
+{ "c.sb", rv_codec_zcb_lb, rv_fmt_rs1_rs2_zce_ldst, NULL, 0, 0, 0 },
+{ "c.sh", rv_codec_zcb_lh, rv_fmt_rs1_rs2_zce_ldst, NULL, 0, 0, 0 },
+{ "cm.push", rv_codec_zcmp_cm_pushpop, rv_fmt_push_rlist, NULL, 0, 0 },
+{ "cm.pop", rv_codec_zcmp_cm_pushpop, rv_fmt_pop_rlist, NULL, 0, 0 },
+{ "cm.popret", rv_codec_zcmp_cm_pushpop, rv_fmt_pop_rlist, NULL, 0, 0, 0 },
+{ "cm.popretz", rv_codec_zcmp_cm_pushpop, rv_fmt_pop_rlist, NULL, 0, 0 },
+{ "cm.mva01s", rv_codec_zcmp_cm_mv, rv_fmt_rd_rs2, NULL, 0, 0, 0 },
+{ "cm.mvsa01", rv_codec_zcmp_cm_mv, rv_fmt_rd_rs2, NULL, 0, 0, 0 },
+{ "cm.jt", rv_codec_zcmt_jt, rv_fmt_zcmt_index, NULL, 0 },
+{ "cm.jalt", rv_codec_zcmt_jt, rv_fmt_zcmt_index, NULL, 0 },
 };
 
 /* CSR names */
@@ -2084,6 +2136,7 @@ static const char *csr_name(int csrno)
 case 0x000a: return "vxrm";
 case 0x000f: return "vcsr";
 case 0x0015: return "seed";
+case 0x0017: return "jvt";
 case 0x0040: return "uscratch";
 case 0x0041: return "uepc";
 case 0x0042: return "ucause";
@@ -2306,6 +2359,24 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa 
isa)
 op = rv_op_c_ld;
 }
 break;
+case 4:
+switch ((inst >> 10) & 0b111) {
+case 0: op = rv_op_c_lbu; break;
+case 1:
+if (((inst >> 6) & 1) == 0) {
+op = rv_op_c_lhu;
+} else {
+

[PATCH v3 0/9] support subsets of code size reduction extension

2022-11-16 Thread Weiwei Li
This patchset implements RISC-V Zc* extension v1.0.0.RC5.7 version 
instructions. 

Specification:
https://github.com/riscv/riscv-code-size-reduction/tree/main/Zc-specification

The port is available here:
https://github.com/plctlab/plct-qemu/tree/plct-zce-upstream-v3

To test Zc* implementation, specify cpu argument with 
'x-zca=true,x-zcb=true,x-zcf=true,f=true" and "x-zcd=true,d=true" (or 
"x-zcmp=true,x-zcmt=true" with c or d=false) to enable Zca/Zcb/Zcf and Zcd(or 
Zcmp,Zcmt) extension support. 

This implementation can pass the basic zc tests from 
https://github.com/yulong-plct/zc-test

v3:
* update the solution for Zcf to the way of Zcd
* update Zcb to reuse gen_load/store
* use trans function instead of helper for push/pop

v2:
* add check for relationship between Zca/Zcf/Zcd with C/F/D based on related 
discussion in review of Zc* spec
* separate c.fld{sp}/fsd{sp} with fld{sp}/fsd{sp} before support of zcmp/zcmt

Weiwei Li (9):
  target/riscv: add cfg properties for Zc* extension
  target/riscv: add support for Zca extension
  target/riscv: add support for Zcf extension
  target/riscv: add support for Zcd extension
  target/riscv: add support for Zcb extension
  target/riscv: add support for Zcmp extension
  target/riscv: add support for Zcmt extension
  target/riscv: expose properties for Zc* extension
  disas/riscv.c: add disasm support for Zc*

 disas/riscv.c | 287 -
 target/riscv/cpu.c|  56 
 target/riscv/cpu.h|   8 +
 target/riscv/cpu_bits.h   |   7 +
 target/riscv/csr.c|  35 +++
 target/riscv/helper.h |   3 +
 target/riscv/insn16.decode|  63 +++-
 target/riscv/insn_trans/trans_rvd.c.inc   |  18 ++
 target/riscv/insn_trans/trans_rvf.c.inc   |  26 +-
 target/riscv/insn_trans/trans_rvi.c.inc   |   4 +-
 target/riscv/insn_trans/trans_rvzce.c.inc | 367 ++
 target/riscv/insn_trans/trans_rvzfh.c.inc |   6 +-
 target/riscv/machine.c|  19 ++
 target/riscv/meson.build  |   3 +-
 target/riscv/translate.c  |  15 +-
 target/riscv/zce_helper.c |  57 
 16 files changed, 953 insertions(+), 21 deletions(-)
 create mode 100644 target/riscv/insn_trans/trans_rvzce.c.inc
 create mode 100644 target/riscv/zce_helper.c

-- 
2.25.1




[PATCH v3 8/9] target/riscv: expose properties for Zc* extension

2022-11-16 Thread Weiwei Li
Expose zca,zcb,zcf,zcd,zcmp,zcmt properties

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 1ab04ab246..b9e41df96c 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -81,6 +81,12 @@ static const struct isa_ext_data isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(zfhmin, true, PRIV_VERSION_1_12_0, ext_zfhmin),
 ISA_EXT_DATA_ENTRY(zfinx, true, PRIV_VERSION_1_12_0, ext_zfinx),
 ISA_EXT_DATA_ENTRY(zdinx, true, PRIV_VERSION_1_12_0, ext_zdinx),
+ISA_EXT_DATA_ENTRY(zca, true, PRIV_VERSION_1_12_0, ext_zca),
+ISA_EXT_DATA_ENTRY(zcb, true, PRIV_VERSION_1_12_0, ext_zcb),
+ISA_EXT_DATA_ENTRY(zcf, true, PRIV_VERSION_1_12_0, ext_zcf),
+ISA_EXT_DATA_ENTRY(zcd, true, PRIV_VERSION_1_12_0, ext_zcd),
+ISA_EXT_DATA_ENTRY(zcmp, true, PRIV_VERSION_1_12_0, ext_zcmp),
+ISA_EXT_DATA_ENTRY(zcmt, true, PRIV_VERSION_1_12_0, ext_zcmt),
 ISA_EXT_DATA_ENTRY(zba, true, PRIV_VERSION_1_12_0, ext_zba),
 ISA_EXT_DATA_ENTRY(zbb, true, PRIV_VERSION_1_12_0, ext_zbb),
 ISA_EXT_DATA_ENTRY(zbc, true, PRIV_VERSION_1_12_0, ext_zbc),
@@ -1114,6 +1120,13 @@ static Property riscv_cpu_extensions[] = {
 
 /* These are experimental so mark with 'x-' */
 DEFINE_PROP_BOOL("x-j", RISCVCPU, cfg.ext_j, false),
+
+DEFINE_PROP_BOOL("x-zca", RISCVCPU, cfg.ext_zca, false),
+DEFINE_PROP_BOOL("x-zcb", RISCVCPU, cfg.ext_zcb, false),
+DEFINE_PROP_BOOL("x-zcd", RISCVCPU, cfg.ext_zcd, false),
+DEFINE_PROP_BOOL("x-zcf", RISCVCPU, cfg.ext_zcf, false),
+DEFINE_PROP_BOOL("x-zcmp", RISCVCPU, cfg.ext_zcmp, false),
+DEFINE_PROP_BOOL("x-zcmt", RISCVCPU, cfg.ext_zcmt, false),
 /* ePMP 0.9.3 */
 DEFINE_PROP_BOOL("x-epmp", RISCVCPU, cfg.epmp, false),
 DEFINE_PROP_BOOL("x-smaia", RISCVCPU, cfg.ext_smaia, false),
-- 
2.25.1




[PATCH v3 4/9] target/riscv: add support for Zcd extension

2022-11-16 Thread Weiwei Li
Separate c_fld/c_fsd from fld/fsd to add additional check for
c.fld{sp}/c.fsd{sp} which is useful for zcmp/zcmt to reuse
their encodings

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Richard Henderson 
---
 target/riscv/insn16.decode  |  8 
 target/riscv/insn_trans/trans_rvd.c.inc | 18 ++
 2 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/target/riscv/insn16.decode b/target/riscv/insn16.decode
index f3ea650325..b62664b6af 100644
--- a/target/riscv/insn16.decode
+++ b/target/riscv/insn16.decode
@@ -97,12 +97,12 @@
 }
 {
   lq  001  ... ... .. ... 00 @cl_q
-  fld 001  ... ... .. ... 00 @cl_d
+  c_fld   001  ... ... .. ... 00 @cl_d
 }
 lw010  ... ... .. ... 00 @cl_w
 {
   sq  101  ... ... .. ... 00 @cs_q
-  fsd 101  ... ... .. ... 00 @cs_d
+  c_fsd   101  ... ... .. ... 00 @cs_d
 }
 sw110  ... ... .. ... 00 @cs_w
 
@@ -148,7 +148,7 @@ addw  100 1 11 ... 01 ... 01 @cs_2
 slli  000 .  .  . 10 @c_shift2
 {
   lq  001  ... ... .. ... 10 @c_lqsp
-  fld 001 .  .  . 10 @c_ldsp
+  c_fld   001 .  .  . 10 @c_ldsp
 }
 {
   illegal 010 -  0  - 10 # c.lwsp, RES rd=0
@@ -166,7 +166,7 @@ slli  000 .  .  . 10 @c_shift2
 }
 {
   sq  101  ... ... .. ... 10 @c_sqsp
-  fsd 101   ..  . 10 @c_sdsp
+  c_fsd   101   ..  . 10 @c_sdsp
 }
 sw110 .  .  . 10 @c_swsp
 
diff --git a/target/riscv/insn_trans/trans_rvd.c.inc 
b/target/riscv/insn_trans/trans_rvd.c.inc
index 1397c1ce1c..def0d7abfe 100644
--- a/target/riscv/insn_trans/trans_rvd.c.inc
+++ b/target/riscv/insn_trans/trans_rvd.c.inc
@@ -31,6 +31,12 @@
 } \
 } while (0)
 
+#define REQUIRE_ZCD(ctx) do { \
+if (!ctx->cfg_ptr->ext_zcd) {  \
+return false; \
+} \
+} while (0)
+
 static bool trans_fld(DisasContext *ctx, arg_fld *a)
 {
 TCGv addr;
@@ -57,6 +63,18 @@ static bool trans_fsd(DisasContext *ctx, arg_fsd *a)
 return true;
 }
 
+static bool trans_c_fld(DisasContext *ctx, arg_fld *a)
+{
+REQUIRE_ZCD(ctx);
+return trans_fld(ctx, a);
+}
+
+static bool trans_c_fsd(DisasContext *ctx, arg_fsd *a)
+{
+REQUIRE_ZCD(ctx);
+return trans_fsd(ctx, a);
+}
+
 static bool trans_fmadd_d(DisasContext *ctx, arg_fmadd_d *a)
 {
 REQUIRE_FPU;
-- 
2.25.1




[PATCH v4 9/9] disas/riscv.c: add disasm support for Zc*

2022-11-17 Thread Weiwei Li
Zcmp/Zcmt instructions will override disasm for c.fld*/c.fsd*
instructions currently

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
---
 disas/riscv.c | 287 +-
 1 file changed, 286 insertions(+), 1 deletion(-)

diff --git a/disas/riscv.c b/disas/riscv.c
index d216b9c39b..81369063b5 100644
--- a/disas/riscv.c
+++ b/disas/riscv.c
@@ -163,6 +163,13 @@ typedef enum {
 rv_codec_v_i,
 rv_codec_vsetvli,
 rv_codec_vsetivli,
+rv_codec_zcb_ext,
+rv_codec_zcb_mul,
+rv_codec_zcb_lb,
+rv_codec_zcb_lh,
+rv_codec_zcmp_cm_pushpop,
+rv_codec_zcmp_cm_mv,
+rv_codec_zcmt_jt,
 } rv_codec;
 
 typedef enum {
@@ -935,6 +942,26 @@ typedef enum {
 rv_op_vsetvli = 766,
 rv_op_vsetivli = 767,
 rv_op_vsetvl = 768,
+rv_op_c_zext_b = 769,
+rv_op_c_sext_b = 770,
+rv_op_c_zext_h = 771,
+rv_op_c_sext_h = 772,
+rv_op_c_zext_w = 773,
+rv_op_c_not = 774,
+rv_op_c_mul = 775,
+rv_op_c_lbu = 776,
+rv_op_c_lhu = 777,
+rv_op_c_lh = 778,
+rv_op_c_sb = 779,
+rv_op_c_sh = 780,
+rv_op_cm_push = 781,
+rv_op_cm_pop = 782,
+rv_op_cm_popret = 783,
+rv_op_cm_popretz = 784,
+rv_op_cm_mva01s = 785,
+rv_op_cm_mvsa01 = 786,
+rv_op_cm_jt = 787,
+rv_op_cm_jalt = 788,
 } rv_op;
 
 /* structures */
@@ -958,6 +985,7 @@ typedef struct {
 uint8_t   rnum;
 uint8_t   vm;
 uint32_t  vzimm;
+uint8_t   rlist;
 } rv_decode;
 
 typedef struct {
@@ -1070,6 +1098,10 @@ static const char rv_vreg_name_sym[32][4] = {
 #define rv_fmt_vd_vm  "O\tDm"
 #define rv_fmt_vsetvli"O\t0,1,v"
 #define rv_fmt_vsetivli   "O\t0,u,v"
+#define rv_fmt_rs1_rs2_zce_ldst   "O\t2,i(1)"
+#define rv_fmt_push_rlist "O\tx,-i"
+#define rv_fmt_pop_rlist  "O\tx,i"
+#define rv_fmt_zcmt_index "O\ti"
 
 /* pseudo-instruction constraints */
 
@@ -2065,7 +2097,27 @@ const rv_opcode_data opcode_data[] = {
 { "vsext.vf8", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vsext_vf8, 
rv_op_vsext_vf8, 0 },
 { "vsetvli", rv_codec_vsetvli, rv_fmt_vsetvli, NULL, rv_op_vsetvli, 
rv_op_vsetvli, 0 },
 { "vsetivli", rv_codec_vsetivli, rv_fmt_vsetivli, NULL, rv_op_vsetivli, 
rv_op_vsetivli, 0 },
-{ "vsetvl", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, rv_op_vsetvl, 
rv_op_vsetvl, 0 }
+{ "vsetvl", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, rv_op_vsetvl, 
rv_op_vsetvl, 0 },
+{ "c.zext.b", rv_codec_zcb_ext, rv_fmt_rd, NULL, 0 },
+{ "c.sext.b", rv_codec_zcb_ext, rv_fmt_rd, NULL, 0 },
+{ "c.zext.h", rv_codec_zcb_ext, rv_fmt_rd, NULL, 0 },
+{ "c.sext.h", rv_codec_zcb_ext, rv_fmt_rd, NULL, 0 },
+{ "c.zext.w", rv_codec_zcb_ext, rv_fmt_rd, NULL, 0 },
+{ "c.not", rv_codec_zcb_ext, rv_fmt_rd, NULL, 0 },
+{ "c.mul", rv_codec_zcb_mul, rv_fmt_rd_rs2, NULL, 0, 0 },
+{ "c.lbu", rv_codec_zcb_lb, rv_fmt_rs1_rs2_zce_ldst, NULL, 0, 0, 0 },
+{ "c.lhu", rv_codec_zcb_lh, rv_fmt_rs1_rs2_zce_ldst, NULL, 0, 0, 0 },
+{ "c.lh", rv_codec_zcb_lh, rv_fmt_rs1_rs2_zce_ldst, NULL, 0, 0, 0 },
+{ "c.sb", rv_codec_zcb_lb, rv_fmt_rs1_rs2_zce_ldst, NULL, 0, 0, 0 },
+{ "c.sh", rv_codec_zcb_lh, rv_fmt_rs1_rs2_zce_ldst, NULL, 0, 0, 0 },
+{ "cm.push", rv_codec_zcmp_cm_pushpop, rv_fmt_push_rlist, NULL, 0, 0 },
+{ "cm.pop", rv_codec_zcmp_cm_pushpop, rv_fmt_pop_rlist, NULL, 0, 0 },
+{ "cm.popret", rv_codec_zcmp_cm_pushpop, rv_fmt_pop_rlist, NULL, 0, 0, 0 },
+{ "cm.popretz", rv_codec_zcmp_cm_pushpop, rv_fmt_pop_rlist, NULL, 0, 0 },
+{ "cm.mva01s", rv_codec_zcmp_cm_mv, rv_fmt_rd_rs2, NULL, 0, 0, 0 },
+{ "cm.mvsa01", rv_codec_zcmp_cm_mv, rv_fmt_rd_rs2, NULL, 0, 0, 0 },
+{ "cm.jt", rv_codec_zcmt_jt, rv_fmt_zcmt_index, NULL, 0 },
+{ "cm.jalt", rv_codec_zcmt_jt, rv_fmt_zcmt_index, NULL, 0 },
 };
 
 /* CSR names */
@@ -2084,6 +2136,7 @@ static const char *csr_name(int csrno)
 case 0x000a: return "vxrm";
 case 0x000f: return "vcsr";
 case 0x0015: return "seed";
+case 0x0017: return "jvt";
 case 0x0040: return "uscratch";
 case 0x0041: return "uepc";
 case 0x0042: return "ucause";
@@ -2306,6 +2359,24 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa 
isa)
 op = rv_op_c_ld;
 }
 break;
+case 4:
+switch ((inst >> 10) & 0b111) {
+case 0: op = rv_op_c_lbu; break;
+case 1:
+if (((inst >> 6) & 1) == 0) {
+op = rv_op_c_lhu;
+} else {
+

[PATCH v4 8/9] target/riscv: expose properties for Zc* extension

2022-11-17 Thread Weiwei Li
Expose zca,zcb,zcf,zcd,zcmp,zcmt properties

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 1ab04ab246..b9e41df96c 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -81,6 +81,12 @@ static const struct isa_ext_data isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(zfhmin, true, PRIV_VERSION_1_12_0, ext_zfhmin),
 ISA_EXT_DATA_ENTRY(zfinx, true, PRIV_VERSION_1_12_0, ext_zfinx),
 ISA_EXT_DATA_ENTRY(zdinx, true, PRIV_VERSION_1_12_0, ext_zdinx),
+ISA_EXT_DATA_ENTRY(zca, true, PRIV_VERSION_1_12_0, ext_zca),
+ISA_EXT_DATA_ENTRY(zcb, true, PRIV_VERSION_1_12_0, ext_zcb),
+ISA_EXT_DATA_ENTRY(zcf, true, PRIV_VERSION_1_12_0, ext_zcf),
+ISA_EXT_DATA_ENTRY(zcd, true, PRIV_VERSION_1_12_0, ext_zcd),
+ISA_EXT_DATA_ENTRY(zcmp, true, PRIV_VERSION_1_12_0, ext_zcmp),
+ISA_EXT_DATA_ENTRY(zcmt, true, PRIV_VERSION_1_12_0, ext_zcmt),
 ISA_EXT_DATA_ENTRY(zba, true, PRIV_VERSION_1_12_0, ext_zba),
 ISA_EXT_DATA_ENTRY(zbb, true, PRIV_VERSION_1_12_0, ext_zbb),
 ISA_EXT_DATA_ENTRY(zbc, true, PRIV_VERSION_1_12_0, ext_zbc),
@@ -1114,6 +1120,13 @@ static Property riscv_cpu_extensions[] = {
 
 /* These are experimental so mark with 'x-' */
 DEFINE_PROP_BOOL("x-j", RISCVCPU, cfg.ext_j, false),
+
+DEFINE_PROP_BOOL("x-zca", RISCVCPU, cfg.ext_zca, false),
+DEFINE_PROP_BOOL("x-zcb", RISCVCPU, cfg.ext_zcb, false),
+DEFINE_PROP_BOOL("x-zcd", RISCVCPU, cfg.ext_zcd, false),
+DEFINE_PROP_BOOL("x-zcf", RISCVCPU, cfg.ext_zcf, false),
+DEFINE_PROP_BOOL("x-zcmp", RISCVCPU, cfg.ext_zcmp, false),
+DEFINE_PROP_BOOL("x-zcmt", RISCVCPU, cfg.ext_zcmt, false),
 /* ePMP 0.9.3 */
 DEFINE_PROP_BOOL("x-epmp", RISCVCPU, cfg.epmp, false),
 DEFINE_PROP_BOOL("x-smaia", RISCVCPU, cfg.ext_smaia, false),
-- 
2.25.1




[PATCH v4 5/9] target/riscv: add support for Zcb extension

2022-11-17 Thread Weiwei Li
Add encode and trans* functions support for Zcb instructions

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Richard Henderson 
---
 target/riscv/insn16.decode|  24 ++
 target/riscv/insn_trans/trans_rvzce.c.inc | 100 ++
 target/riscv/translate.c  |   2 +
 3 files changed, 126 insertions(+)
 create mode 100644 target/riscv/insn_trans/trans_rvzce.c.inc

diff --git a/target/riscv/insn16.decode b/target/riscv/insn16.decode
index b62664b6af..47603ec1e0 100644
--- a/target/riscv/insn16.decode
+++ b/target/riscv/insn16.decode
@@ -43,6 +43,8 @@
 %imm_addi16sp  12:s1 3:2 5:1 2:1 6:1 !function=ex_shift_4
 %imm_lui   12:s1 2:5 !function=ex_shift_12
 
+%zcb_b_uimm  5:1 6:1
+%zcb_h_uimm  5:1 !function=ex_shift_1
 
 # Argument sets imported from insn32.decode:
 &empty  !extern
@@ -53,6 +55,7 @@
 &b imm rs2 rs1  !extern
 &u imm rd   !extern
 &shift shamt rs1 rd !extern
+&r2rd rs1   !extern
 
 
 # Formats 16:
@@ -89,6 +92,13 @@
 
 @c_andi ... . .. ... . .. &i imm=%imm_ci rs1=%rs1_3 rd=%rs1_3
 
+@zcb_unary... ...  ... .. ... ..  &r2  rs1=%rs1_3 rd=%rs1_3
+@zcb_binary   ... ...  ... .. ... ..  &r  rs2=%rs2_3   rs1=%rs1_3 rd=%rs1_3
+@zcb_lb   ... . .. ... .. ... ..  &i  imm=%zcb_b_uimm  rs1=%rs1_3 rd=%rs2_3
+@zcb_lh   ... . .. ... .. ... ..  &i  imm=%zcb_h_uimm  rs1=%rs1_3 rd=%rs2_3
+@zcb_sb   ... . .. ... .. ... ..  &s  imm=%zcb_b_uimm  rs1=%rs1_3 
rs2=%rs2_3
+@zcb_sh   ... . .. ... .. ... ..  &s  imm=%zcb_h_uimm  rs1=%rs1_3 
rs2=%rs2_3
+
 # *** RV32/64C Standard Extension (Quadrant 0) ***
 {
   # Opcode of all zeros is illegal; rd != 0, nzuimm == 0 is reserved.
@@ -180,3 +190,17 @@ sw110 .  .  . 10 @c_swsp
   sd  111 .  .  . 10 @c_sdsp
   c_fsw   111 .  .  . 10 @c_swsp
 }
+
+# *** RV64 and RV32 Zcb Extension ***
+c_zext_b  100 111  ... 11 000 01 @zcb_unary
+c_sext_b  100 111  ... 11 001 01 @zcb_unary
+c_zext_h  100 111  ... 11 010 01 @zcb_unary
+c_sext_h  100 111  ... 11 011 01 @zcb_unary
+c_zext_w  100 111  ... 11 100 01 @zcb_unary
+c_not 100 111  ... 11 101 01 @zcb_unary
+c_mul 100 111  ... 10 ... 01 @zcb_binary
+c_lbu 100 000  ... .. ... 00 @zcb_lb
+c_lhu 100 001  ... 0. ... 00 @zcb_lh
+c_lh  100 001  ... 1. ... 00 @zcb_lh
+c_sb  100 010  ... .. ... 00 @zcb_sb
+c_sh  100 011  ... 0. ... 00 @zcb_sh
diff --git a/target/riscv/insn_trans/trans_rvzce.c.inc 
b/target/riscv/insn_trans/trans_rvzce.c.inc
new file mode 100644
index 00..de96c4afaf
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rvzce.c.inc
@@ -0,0 +1,100 @@
+/*
+ * RISC-V translation routines for the Zcb Standard Extension.
+ *
+ * Copyright (c) 2021-2022 PLCT Lab
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define REQUIRE_ZCB(ctx) do {   \
+if (!ctx->cfg_ptr->ext_zcb) \
+return false;   \
+} while (0)
+
+static bool trans_c_zext_b(DisasContext *ctx, arg_c_zext_b *a)
+{
+REQUIRE_ZCB(ctx);
+return gen_unary(ctx, a, EXT_NONE, tcg_gen_ext8u_tl);
+}
+
+static bool trans_c_zext_h(DisasContext *ctx, arg_c_zext_h *a)
+{
+REQUIRE_ZCB(ctx);
+REQUIRE_ZBB(ctx);
+return gen_unary(ctx, a, EXT_NONE, tcg_gen_ext16u_tl);
+}
+
+static bool trans_c_sext_b(DisasContext *ctx, arg_c_sext_b *a)
+{
+REQUIRE_ZCB(ctx);
+REQUIRE_ZBB(ctx);
+return gen_unary(ctx, a, EXT_NONE, tcg_gen_ext8s_tl);
+}
+
+static bool trans_c_sext_h(DisasContext *ctx, arg_c_sext_h *a)
+{
+REQUIRE_ZCB(ctx);
+REQUIRE_ZBB(ctx);
+return gen_unary(ctx, a, EXT_NONE, tcg_gen_ext16s_tl);
+}
+
+static bool trans_c_zext_w(DisasContext *ctx, arg_c_zext_w *a)
+{
+REQUIRE_64BIT(ctx);
+REQUIRE_ZCB(ctx);
+REQUIRE_ZBA(ctx);
+return gen_unary(ctx, a, EXT_NONE, tcg_gen_ext32u_tl);
+}
+
+static bool trans_c_not(DisasContext *ctx, arg_c_not *a)
+{
+REQUIRE_ZCB(ctx);
+return gen_unary(ctx, a, EXT_NONE, tcg_gen_not_tl);
+}
+
+static bool trans_c_mul(DisasContext *ctx, arg_c_mul *a)
+{
+REQUIRE_ZCB(ctx);
+REQUIRE_M_OR_ZMMUL(ctx);
+return gen_arith(ctx, a, EXT_NONE, tcg_gen_mul_tl, NULL);
+

[PATCH v4 2/9] target/riscv: add support for Zca extension

2022-11-17 Thread Weiwei Li
Modify the check for C extension to Zca (C implies Zca)

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Richard Henderson 
---
 target/riscv/insn_trans/trans_rvi.c.inc | 4 ++--
 target/riscv/translate.c| 8 ++--
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvi.c.inc 
b/target/riscv/insn_trans/trans_rvi.c.inc
index 5c69b88d1e..0d73b919ce 100644
--- a/target/riscv/insn_trans/trans_rvi.c.inc
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
@@ -56,7 +56,7 @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
 tcg_gen_andi_tl(cpu_pc, cpu_pc, (target_ulong)-2);
 
 gen_set_pc(ctx, cpu_pc);
-if (!has_ext(ctx, RVC)) {
+if (!ctx->cfg_ptr->ext_zca) {
 TCGv t0 = tcg_temp_new();
 
 misaligned = gen_new_label();
@@ -178,7 +178,7 @@ static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond 
cond)
 
 gen_set_label(l); /* branch taken */
 
-if (!has_ext(ctx, RVC) && ((ctx->base.pc_next + a->imm) & 0x3)) {
+if (!ctx->cfg_ptr->ext_zca && ((ctx->base.pc_next + a->imm) & 0x3)) {
 /* misaligned */
 gen_exception_inst_addr_mis(ctx);
 } else {
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 2ab8772ebe..ee24b451e3 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -557,7 +557,7 @@ static void gen_jal(DisasContext *ctx, int rd, target_ulong 
imm)
 
 /* check misaligned: */
 next_pc = ctx->base.pc_next + imm;
-if (!has_ext(ctx, RVC)) {
+if (!ctx->cfg_ptr->ext_zca) {
 if ((next_pc & 0x3) != 0) {
 gen_exception_inst_addr_mis(ctx);
 return;
@@ -1097,7 +1097,11 @@ static void decode_opc(CPURISCVState *env, DisasContext 
*ctx, uint16_t opcode)
 ctx->virt_inst_excp = false;
 /* Check for compressed insn */
 if (insn_len(opcode) == 2) {
-if (!has_ext(ctx, RVC)) {
+/*
+ * Zca support all of the existing C extension, excluding all
+ * compressed floating point loads and stores
+ */
+if (!ctx->cfg_ptr->ext_zca) {
 gen_exception_illegal(ctx);
 } else {
 ctx->opcode = opcode;
-- 
2.25.1




[PATCH v4 4/9] target/riscv: add support for Zcd extension

2022-11-17 Thread Weiwei Li
Separate c_fld/c_fsd from fld/fsd to add additional check for
c.fld{sp}/c.fsd{sp} which is useful for zcmp/zcmt to reuse
their encodings

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Richard Henderson 
---
 target/riscv/insn16.decode  |  8 
 target/riscv/insn_trans/trans_rvd.c.inc | 18 ++
 2 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/target/riscv/insn16.decode b/target/riscv/insn16.decode
index f3ea650325..b62664b6af 100644
--- a/target/riscv/insn16.decode
+++ b/target/riscv/insn16.decode
@@ -97,12 +97,12 @@
 }
 {
   lq  001  ... ... .. ... 00 @cl_q
-  fld 001  ... ... .. ... 00 @cl_d
+  c_fld   001  ... ... .. ... 00 @cl_d
 }
 lw010  ... ... .. ... 00 @cl_w
 {
   sq  101  ... ... .. ... 00 @cs_q
-  fsd 101  ... ... .. ... 00 @cs_d
+  c_fsd   101  ... ... .. ... 00 @cs_d
 }
 sw110  ... ... .. ... 00 @cs_w
 
@@ -148,7 +148,7 @@ addw  100 1 11 ... 01 ... 01 @cs_2
 slli  000 .  .  . 10 @c_shift2
 {
   lq  001  ... ... .. ... 10 @c_lqsp
-  fld 001 .  .  . 10 @c_ldsp
+  c_fld   001 .  .  . 10 @c_ldsp
 }
 {
   illegal 010 -  0  - 10 # c.lwsp, RES rd=0
@@ -166,7 +166,7 @@ slli  000 .  .  . 10 @c_shift2
 }
 {
   sq  101  ... ... .. ... 10 @c_sqsp
-  fsd 101   ..  . 10 @c_sdsp
+  c_fsd   101   ..  . 10 @c_sdsp
 }
 sw110 .  .  . 10 @c_swsp
 
diff --git a/target/riscv/insn_trans/trans_rvd.c.inc 
b/target/riscv/insn_trans/trans_rvd.c.inc
index 1397c1ce1c..def0d7abfe 100644
--- a/target/riscv/insn_trans/trans_rvd.c.inc
+++ b/target/riscv/insn_trans/trans_rvd.c.inc
@@ -31,6 +31,12 @@
 } \
 } while (0)
 
+#define REQUIRE_ZCD(ctx) do { \
+if (!ctx->cfg_ptr->ext_zcd) {  \
+return false; \
+} \
+} while (0)
+
 static bool trans_fld(DisasContext *ctx, arg_fld *a)
 {
 TCGv addr;
@@ -57,6 +63,18 @@ static bool trans_fsd(DisasContext *ctx, arg_fsd *a)
 return true;
 }
 
+static bool trans_c_fld(DisasContext *ctx, arg_fld *a)
+{
+REQUIRE_ZCD(ctx);
+return trans_fld(ctx, a);
+}
+
+static bool trans_c_fsd(DisasContext *ctx, arg_fsd *a)
+{
+REQUIRE_ZCD(ctx);
+return trans_fsd(ctx, a);
+}
+
 static bool trans_fmadd_d(DisasContext *ctx, arg_fmadd_d *a)
 {
 REQUIRE_FPU;
-- 
2.25.1




[PATCH v4 6/9] target/riscv: add support for Zcmp extension

2022-11-17 Thread Weiwei Li
Add encode, trans* functions for Zcmp instructions

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
---
 target/riscv/insn16.decode|  18 +++
 target/riscv/insn_trans/trans_rvzce.c.inc | 189 +-
 target/riscv/translate.c  |   5 +
 3 files changed, 211 insertions(+), 1 deletion(-)

diff --git a/target/riscv/insn16.decode b/target/riscv/insn16.decode
index 47603ec1e0..4654c23052 100644
--- a/target/riscv/insn16.decode
+++ b/target/riscv/insn16.decode
@@ -21,6 +21,8 @@
 %rs1_3 7:3!function=ex_rvc_register
 %rs2_3 2:3!function=ex_rvc_register
 %rs2_5 2:5
+%sreg1 7:3!function=ex_sreg_register
+%sreg2 2:3!function=ex_sreg_register
 
 # Immediates:
 %imm_ci12:s1 2:5
@@ -45,6 +47,8 @@
 
 %zcb_b_uimm  5:1 6:1
 %zcb_h_uimm  5:1 !function=ex_shift_1
+%zcmp_spimm  2:2 !function=ex_shift_4
+%zcmp_rlist  4:4
 
 # Argument sets imported from insn32.decode:
 &empty  !extern
@@ -56,7 +60,9 @@
 &u imm rd   !extern
 &shift shamt rs1 rd !extern
 &r2rd rs1   !extern
+&r2_s  rs1 rs2  !extern
 
+&zcmp  zcmp_rlist zcmp_spimm
 
 # Formats 16:
 @cr  . .  .. &r  rs2=%rs2_5   rs1=%rd %rd
@@ -98,6 +104,8 @@
 @zcb_lh   ... . .. ... .. ... ..  &i  imm=%zcb_h_uimm  rs1=%rs1_3 rd=%rs2_3
 @zcb_sb   ... . .. ... .. ... ..  &s  imm=%zcb_b_uimm  rs1=%rs1_3 
rs2=%rs2_3
 @zcb_sh   ... . .. ... .. ... ..  &s  imm=%zcb_h_uimm  rs1=%rs1_3 
rs2=%rs2_3
+@zcmp ... ...     ..  &zcmp  %zcmp_rlist   %zcmp_spimm
+@cm_mv... ...  ... .. ... ..  &r2_s  rs2=%sreg2rs1=%sreg1
 
 # *** RV32/64C Standard Extension (Quadrant 0) ***
 {
@@ -177,6 +185,16 @@ slli  000 .  .  . 10 @c_shift2
 {
   sq  101  ... ... .. ... 10 @c_sqsp
   c_fsd   101   ..  . 10 @c_sdsp
+
+  # *** RV64 and RV32 Zcmp Extension ***
+  [
+cm_push 101  11000   .. 10 @zcmp
+cm_pop  101  11010   .. 10 @zcmp
+cm_popret   101  0   .. 10 @zcmp
+cm_popretz  101  11100   .. 10 @zcmp
+cm_mva01s   101  011 ... 11 ... 10 @cm_mv
+cm_mvsa01   101  011 ... 01 ... 10 @cm_mv
+  ]
 }
 sw110 .  .  . 10 @c_swsp
 
diff --git a/target/riscv/insn_trans/trans_rvzce.c.inc 
b/target/riscv/insn_trans/trans_rvzce.c.inc
index de96c4afaf..f647b6ed15 100644
--- a/target/riscv/insn_trans/trans_rvzce.c.inc
+++ b/target/riscv/insn_trans/trans_rvzce.c.inc
@@ -1,5 +1,5 @@
 /*
- * RISC-V translation routines for the Zcb Standard Extension.
+ * RISC-V translation routines for the Zc[b,mp] Standard Extension.
  *
  * Copyright (c) 2021-2022 PLCT Lab
  *
@@ -21,6 +21,11 @@
 return false;   \
 } while (0)
 
+#define REQUIRE_ZCMP(ctx) do {   \
+if (!ctx->cfg_ptr->ext_zcmp) \
+return false;\
+} while (0)
+
 static bool trans_c_zext_b(DisasContext *ctx, arg_c_zext_b *a)
 {
 REQUIRE_ZCB(ctx);
@@ -98,3 +103,185 @@ static bool trans_c_sh(DisasContext *ctx, arg_c_sh *a)
 REQUIRE_ZCB(ctx);
 return gen_store(ctx, a, MO_UW);
 }
+
+#define X_S08
+#define X_S19
+#define X_Sn16
+
+static uint32_t decode_push_pop_list(DisasContext *ctx, target_ulong rlist)
+{
+uint32_t reg_bitmap = 0;
+
+if (ctx->cfg_ptr->ext_e && rlist > 6) {
+return 0;
+}
+
+switch (rlist) {
+case 15:
+reg_bitmap |=  1 << (X_Sn + 11) ;
+reg_bitmap |=  1 << (X_Sn + 10) ;
+/* FALL THROUGH */
+case 14:
+reg_bitmap |=  1 << (X_Sn + 9) ;
+/* FALL THROUGH */
+case 13:
+reg_bitmap |=  1 << (X_Sn + 8) ;
+/* FALL THROUGH */
+case 12:
+reg_bitmap |=  1 << (X_Sn + 7) ;
+/* FALL THROUGH */
+case 11:
+reg_bitmap |=  1 << (X_Sn + 6) ;
+/* FALL THROUGH */
+case 10:
+reg_bitmap |=  1 << (X_Sn + 5) ;
+/* FALL THROUGH */
+case 9:
+reg_bitmap |=  1 << (X_Sn + 4) ;
+/* FALL THROUGH */
+case 8:
+reg_bitmap |=  1 << (X_Sn + 3) ;
+/* FALL THROUGH */
+case 7:
+reg_bitmap |=  1 << (X_Sn + 2) ;
+/* FALL THROUGH */
+case 6:
+reg_bitmap |=  1 << X_S1 ;
+/* FALL THROUGH */
+case 5:
+reg_bitmap |= 1 << X_S0;
+/* FALL THROUGH */
+case 4:
+reg_bitmap |= 1 << xRA;
+break;
+default:
+break;
+}
+
+return reg_bitmap;
+}
+
+static bool gen_pop(DisasContext *ctx, arg_zcmp *a, bool ret, bool ret_val)
+{
+REQUIRE_ZCMP(ctx);
+
+uint32_t reg_bitmap = decode_push_pop_list(ctx, a->zcmp_rlist);
+if (reg_bitmap == 0) {
+return false;
+}

[PATCH v4 1/9] target/riscv: add cfg properties for Zc* extension

2022-11-17 Thread Weiwei Li
Add properties for Zca,Zcb,Zcf,Zcd,Zcmp,Zcmt extension
Add check for these properties

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Cc: Alistair Francis 
Reviewed-by: Richard Henderson 
---
 target/riscv/cpu.c | 43 +++
 target/riscv/cpu.h |  6 ++
 2 files changed, 49 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 042fd541b4..1ab04ab246 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -805,6 +805,49 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 }
 }
 
+if (cpu->cfg.ext_c) {
+cpu->cfg.ext_zca = true;
+if (cpu->cfg.ext_f && env->misa_mxl_max == MXL_RV32) {
+cpu->cfg.ext_zcf = true;
+}
+if (cpu->cfg.ext_d) {
+cpu->cfg.ext_zcd = true;
+}
+}
+
+if (env->misa_mxl_max != MXL_RV32 && cpu->cfg.ext_zcf) {
+error_setg(errp, "Zcf extension is only relevant to RV32");
+return;
+}
+
+if (!cpu->cfg.ext_f && cpu->cfg.ext_zcf) {
+error_setg(errp, "Zcf extension requires F extension");
+return;
+}
+
+if (!cpu->cfg.ext_d && cpu->cfg.ext_zcd) {
+error_setg(errp, "Zcd extensionrequires D extension");
+return;
+}
+
+if ((cpu->cfg.ext_zcf || cpu->cfg.ext_zcd || cpu->cfg.ext_zcb ||
+ cpu->cfg.ext_zcmp || cpu->cfg.ext_zcmt) && !cpu->cfg.ext_zca) {
+error_setg(errp, "Zcf/Zcd/Zcb/Zcmp/Zcmt extensions require Zca "
+ "extension");
+return;
+}
+
+if (cpu->cfg.ext_zcd && (cpu->cfg.ext_zcmp || cpu->cfg.ext_zcmt)) {
+error_setg(errp, "Zcmp/Zcmt extensions are incompatible with "
+ "Zcd extension");
+return;
+}
+
+if (cpu->cfg.ext_zcmt && !cpu->cfg.ext_icsr) {
+error_setg(errp, "Zcmt extension requires Zicsr extension");
+return;
+}
+
 if (cpu->cfg.ext_zk) {
 cpu->cfg.ext_zkn = true;
 cpu->cfg.ext_zkr = true;
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 9bd539d77a..6e915b6937 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -434,6 +434,12 @@ struct RISCVCPUConfig {
 bool ext_zbkc;
 bool ext_zbkx;
 bool ext_zbs;
+bool ext_zca;
+bool ext_zcb;
+bool ext_zcd;
+bool ext_zcf;
+bool ext_zcmp;
+bool ext_zcmt;
 bool ext_zk;
 bool ext_zkn;
 bool ext_zknd;
-- 
2.25.1




[PATCH v4 0/9] support subsets of code size reduction extension

2022-11-17 Thread Weiwei Li
This patchset implements RISC-V Zc* extension v1.0.0.RC5.7 version instructions.

Specification:
https://github.com/riscv/riscv-code-size-reduction/tree/main/Zc-specification

The port is available here:
https://github.com/plctlab/plct-qemu/tree/plct-zce-upstream-v4

To test Zc* implementation, specify cpu argument with 
'x-zca=true,x-zcb=true,x-zcf=true,f=true" and "x-zcd=true,d=true" (or 
"x-zcmp=true,x-zcmt=true" with c or d=false) to enable Zca/Zcb/Zcf and Zcd(or 
Zcmp,Zcmt) extension support.


This implementation can pass the basic zc tests from 
https://github.com/yulong-plct/zc-test

v4:
* improve Zcmp suggested by Richard
* fix stateen related check for Zcmt

v3:
* update the solution for Zcf to the way of Zcd
* update Zcb to reuse gen_load/store
* use trans function instead of helper for push/pop

v2:
* add check for relationship between Zca/Zcf/Zcd with C/F/D based on related 
discussion in review of Zc* spec
* separate c.fld{sp}/fsd{sp} with fld{sp}/fsd{sp} before support of zcmp/zcmt

Weiwei Li (9):
  target/riscv: add cfg properties for Zc* extension
  target/riscv: add support for Zca extension
  target/riscv: add support for Zcf extension
  target/riscv: add support for Zcd extension
  target/riscv: add support for Zcb extension
  target/riscv: add support for Zcmp extension
  target/riscv: add support for Zcmt extension
  target/riscv: expose properties for Zc* extension
  disas/riscv.c: add disasm support for Zc*

 disas/riscv.c | 287 +++-
 target/riscv/cpu.c|  56 
 target/riscv/cpu.h|  10 +
 target/riscv/cpu_bits.h   |   7 +
 target/riscv/csr.c|  38 ++-
 target/riscv/helper.h |   3 +
 target/riscv/insn16.decode|  63 -
 target/riscv/insn_trans/trans_rvd.c.inc   |  18 ++
 target/riscv/insn_trans/trans_rvf.c.inc   |  18 ++
 target/riscv/insn_trans/trans_rvi.c.inc   |   4 +-
 target/riscv/insn_trans/trans_rvzce.c.inc | 310 ++
 target/riscv/machine.c|  19 ++
 target/riscv/meson.build  |   3 +-
 target/riscv/translate.c  |  15 +-
 target/riscv/zce_helper.c |  64 +
 15 files changed, 899 insertions(+), 16 deletions(-)
 create mode 100644 target/riscv/insn_trans/trans_rvzce.c.inc
 create mode 100644 target/riscv/zce_helper.c

-- 
2.25.1




[PATCH v4 3/9] target/riscv: add support for Zcf extension

2022-11-17 Thread Weiwei Li
Separate c_flw/c_fsw from flw/fsw to add check for Zcf extension

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Richard Henderson 
---
 target/riscv/insn16.decode  |  8 
 target/riscv/insn_trans/trans_rvf.c.inc | 18 ++
 2 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/target/riscv/insn16.decode b/target/riscv/insn16.decode
index ccfe59f294..f3ea650325 100644
--- a/target/riscv/insn16.decode
+++ b/target/riscv/insn16.decode
@@ -109,11 +109,11 @@ sw110  ... ... .. ... 00 @cs_w
 # *** RV32C and RV64C specific Standard Extension (Quadrant 0) ***
 {
   ld  011  ... ... .. ... 00 @cl_d
-  flw 011  ... ... .. ... 00 @cl_w
+  c_flw   011  ... ... .. ... 00 @cl_w
 }
 {
   sd  111  ... ... .. ... 00 @cs_d
-  fsw 111  ... ... .. ... 00 @cs_w
+  c_fsw   111  ... ... .. ... 00 @cs_w
 }
 
 # *** RV32/64C Standard Extension (Quadrant 1) ***
@@ -174,9 +174,9 @@ sw110 .  .  . 10 @c_swsp
 {
   c64_illegal 011 -  0  - 10 # c.ldsp, RES rd=0
   ld  011 .  .  . 10 @c_ldsp
-  flw 011 .  .  . 10 @c_lwsp
+  c_flw   011 .  .  . 10 @c_lwsp
 }
 {
   sd  111 .  .  . 10 @c_sdsp
-  fsw 111 .  .  . 10 @c_swsp
+  c_fsw   111 .  .  . 10 @c_swsp
 }
diff --git a/target/riscv/insn_trans/trans_rvf.c.inc 
b/target/riscv/insn_trans/trans_rvf.c.inc
index 93657680c6..426518957b 100644
--- a/target/riscv/insn_trans/trans_rvf.c.inc
+++ b/target/riscv/insn_trans/trans_rvf.c.inc
@@ -24,6 +24,12 @@
 return false; \
 } while (0)
 
+#define REQUIRE_ZCF(ctx) do {  \
+if (!ctx->cfg_ptr->ext_zcf) {  \
+return false;  \
+}  \
+} while (0)
+
 #ifndef CONFIG_USER_ONLY
 static inline bool smstateen_fcsr_check(DisasContext *ctx, int index)
 {
@@ -96,6 +102,18 @@ static bool trans_fsw(DisasContext *ctx, arg_fsw *a)
 return true;
 }
 
+static bool trans_c_flw(DisasContext *ctx, arg_flw *a)
+{
+REQUIRE_ZCF(ctx);
+return trans_flw(ctx, a);
+}
+
+static bool trans_c_fsw(DisasContext *ctx, arg_fsw *a)
+{
+REQUIRE_ZCF(ctx);
+return trans_fsw(ctx, a);
+}
+
 static bool trans_fmadd_s(DisasContext *ctx, arg_fmadd_s *a)
 {
 REQUIRE_FPU;
-- 
2.25.1




[PATCH v4 7/9] target/riscv: add support for Zcmt extension

2022-11-17 Thread Weiwei Li
Add encode, trans* functions and helper functions support for Zcmt
instrutions
Add support for jvt csr

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
---
 target/riscv/cpu.h|  4 ++
 target/riscv/cpu_bits.h   |  7 +++
 target/riscv/csr.c| 38 +-
 target/riscv/helper.h |  3 ++
 target/riscv/insn16.decode|  7 ++-
 target/riscv/insn_trans/trans_rvzce.c.inc | 25 -
 target/riscv/machine.c| 19 +++
 target/riscv/meson.build  |  3 +-
 target/riscv/zce_helper.c | 64 +++
 9 files changed, 165 insertions(+), 5 deletions(-)
 create mode 100644 target/riscv/zce_helper.c

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 6e915b6937..7bcedc7467 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -181,6 +181,8 @@ struct CPUArchState {
 
 uint32_t features;
 
+target_ulong jvt;
+
 #ifdef CONFIG_USER_ONLY
 uint32_t elf_flags;
 #endif
@@ -600,6 +602,8 @@ void riscv_cpu_set_aia_ireg_rmw_fn(CPURISCVState *env, 
uint32_t priv,
  target_ulong new_val,
  target_ulong write_mask),
void *rmw_fn_arg);
+
+RISCVException smstateen_acc_ok(CPURISCVState *env, int index, uint64_t bit);
 #endif
 void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv);
 
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 8b0d7e20ea..ce347e5575 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -319,6 +319,7 @@
 #define SMSTATEEN_MAX_COUNT 4
 #define SMSTATEEN0_CS   (1ULL << 0)
 #define SMSTATEEN0_FCSR (1ULL << 1)
+#define SMSTATEEN0_JVT  (1ULL << 2)
 #define SMSTATEEN0_HSCONTXT (1ULL << 57)
 #define SMSTATEEN0_IMSIC(1ULL << 58)
 #define SMSTATEEN0_AIA  (1ULL << 59)
@@ -523,6 +524,9 @@
 /* Crypto Extension */
 #define CSR_SEED0x015
 
+/* Zcmt Extension */
+#define CSR_JVT 0x017
+
 /* mstatus CSR bits */
 #define MSTATUS_UIE 0x0001
 #define MSTATUS_SIE 0x0002
@@ -894,4 +898,7 @@ typedef enum RISCVException {
 #define MHPMEVENT_IDX_MASK 0xF
 #define MHPMEVENT_SSCOF_RESVD  16
 
+/* JVT CSR bits */
+#define JVT_MODE   0x3F
+#define JVT_BASE   (~0x3F)
 #endif
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 8b25f885ec..5115dc882d 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -42,8 +42,7 @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops)
 
 /* Predicates */
 #if !defined(CONFIG_USER_ONLY)
-static RISCVException smstateen_acc_ok(CPURISCVState *env, int index,
-   uint64_t bit)
+RISCVException smstateen_acc_ok(CPURISCVState *env, int index, uint64_t bit)
 {
 bool virt = riscv_cpu_virt_enabled(env);
 CPUState *cs = env_cpu(env);
@@ -167,6 +166,24 @@ static RISCVException ctr32(CPURISCVState *env, int csrno)
 return ctr(env, csrno);
 }
 
+static RISCVException zcmt(CPURISCVState *env, int csrno)
+{
+RISCVCPU *cpu = env_archcpu(env);
+
+if (!cpu->cfg.ext_zcmt) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
+#if !defined(CONFIG_USER_ONLY)
+RISCVException ret = smstateen_acc_ok(env, 0, SMSTATEEN0_JVT);
+if (ret != RISCV_EXCP_NONE) {
+return ret;
+}
+#endif
+
+return RISCV_EXCP_NONE;
+}
+
 #if !defined(CONFIG_USER_ONLY)
 static RISCVException mctr(CPURISCVState *env, int csrno)
 {
@@ -3987,6 +4004,20 @@ RISCVException riscv_csrrw_debug(CPURISCVState *env, int 
csrno,
 return ret;
 }
 
+static RISCVException read_jvt(CPURISCVState *env, int csrno,
+   target_ulong *val)
+{
+*val = env->jvt;
+return RISCV_EXCP_NONE;
+}
+
+static RISCVException write_jvt(CPURISCVState *env, int csrno,
+target_ulong val)
+{
+env->jvt = val;
+return RISCV_EXCP_NONE;
+}
+
 /* Control and Status Register function table */
 riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
 /* User Floating-Point CSRs */
@@ -4024,6 +4055,9 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
 /* Crypto Extension */
 [CSR_SEED] = { "seed", seed, NULL, NULL, rmw_seed },
 
+/* Zcmt Extension */
+[CSR_JVT] = {"jvt", zcmt, read_jvt, write_jvt},
+
 #if !defined(CONFIG_USER_ONLY)
 /* Machine Timers and Counters */
 [CSR_MCYCLE]= { "mcycle",any,   read_hpmcounter,
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 227c7122ef..2ae98f04d2 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1136,3 +1136,6 @@ DEF_HELPER_FLAGS_1(aes64im, TCG_CALL_NO_RWG_SE, tl, tl)
 
 DEF_HELPER_FLAGS_3(sm4ed, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl)
 DEF

[PATCH v5 4/9] target/riscv: add support for Zcd extension

2022-11-18 Thread Weiwei Li
Separate c_fld/c_fsd from fld/fsd to add additional check for
c.fld{sp}/c.fsd{sp} which is useful for zcmp/zcmt to reuse
their encodings

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Richard Henderson 
---
 target/riscv/insn16.decode  |  8 
 target/riscv/insn_trans/trans_rvd.c.inc | 18 ++
 2 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/target/riscv/insn16.decode b/target/riscv/insn16.decode
index f3ea650325..b62664b6af 100644
--- a/target/riscv/insn16.decode
+++ b/target/riscv/insn16.decode
@@ -97,12 +97,12 @@
 }
 {
   lq  001  ... ... .. ... 00 @cl_q
-  fld 001  ... ... .. ... 00 @cl_d
+  c_fld   001  ... ... .. ... 00 @cl_d
 }
 lw010  ... ... .. ... 00 @cl_w
 {
   sq  101  ... ... .. ... 00 @cs_q
-  fsd 101  ... ... .. ... 00 @cs_d
+  c_fsd   101  ... ... .. ... 00 @cs_d
 }
 sw110  ... ... .. ... 00 @cs_w
 
@@ -148,7 +148,7 @@ addw  100 1 11 ... 01 ... 01 @cs_2
 slli  000 .  .  . 10 @c_shift2
 {
   lq  001  ... ... .. ... 10 @c_lqsp
-  fld 001 .  .  . 10 @c_ldsp
+  c_fld   001 .  .  . 10 @c_ldsp
 }
 {
   illegal 010 -  0  - 10 # c.lwsp, RES rd=0
@@ -166,7 +166,7 @@ slli  000 .  .  . 10 @c_shift2
 }
 {
   sq  101  ... ... .. ... 10 @c_sqsp
-  fsd 101   ..  . 10 @c_sdsp
+  c_fsd   101   ..  . 10 @c_sdsp
 }
 sw110 .  .  . 10 @c_swsp
 
diff --git a/target/riscv/insn_trans/trans_rvd.c.inc 
b/target/riscv/insn_trans/trans_rvd.c.inc
index 1397c1ce1c..def0d7abfe 100644
--- a/target/riscv/insn_trans/trans_rvd.c.inc
+++ b/target/riscv/insn_trans/trans_rvd.c.inc
@@ -31,6 +31,12 @@
 } \
 } while (0)
 
+#define REQUIRE_ZCD(ctx) do { \
+if (!ctx->cfg_ptr->ext_zcd) {  \
+return false; \
+} \
+} while (0)
+
 static bool trans_fld(DisasContext *ctx, arg_fld *a)
 {
 TCGv addr;
@@ -57,6 +63,18 @@ static bool trans_fsd(DisasContext *ctx, arg_fsd *a)
 return true;
 }
 
+static bool trans_c_fld(DisasContext *ctx, arg_fld *a)
+{
+REQUIRE_ZCD(ctx);
+return trans_fld(ctx, a);
+}
+
+static bool trans_c_fsd(DisasContext *ctx, arg_fsd *a)
+{
+REQUIRE_ZCD(ctx);
+return trans_fsd(ctx, a);
+}
+
 static bool trans_fmadd_d(DisasContext *ctx, arg_fmadd_d *a)
 {
 REQUIRE_FPU;
-- 
2.25.1




[PATCH v5 3/9] target/riscv: add support for Zcf extension

2022-11-18 Thread Weiwei Li
Separate c_flw/c_fsw from flw/fsw to add check for Zcf extension

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Richard Henderson 
---
 target/riscv/insn16.decode  |  8 
 target/riscv/insn_trans/trans_rvf.c.inc | 18 ++
 2 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/target/riscv/insn16.decode b/target/riscv/insn16.decode
index ccfe59f294..f3ea650325 100644
--- a/target/riscv/insn16.decode
+++ b/target/riscv/insn16.decode
@@ -109,11 +109,11 @@ sw110  ... ... .. ... 00 @cs_w
 # *** RV32C and RV64C specific Standard Extension (Quadrant 0) ***
 {
   ld  011  ... ... .. ... 00 @cl_d
-  flw 011  ... ... .. ... 00 @cl_w
+  c_flw   011  ... ... .. ... 00 @cl_w
 }
 {
   sd  111  ... ... .. ... 00 @cs_d
-  fsw 111  ... ... .. ... 00 @cs_w
+  c_fsw   111  ... ... .. ... 00 @cs_w
 }
 
 # *** RV32/64C Standard Extension (Quadrant 1) ***
@@ -174,9 +174,9 @@ sw110 .  .  . 10 @c_swsp
 {
   c64_illegal 011 -  0  - 10 # c.ldsp, RES rd=0
   ld  011 .  .  . 10 @c_ldsp
-  flw 011 .  .  . 10 @c_lwsp
+  c_flw   011 .  .  . 10 @c_lwsp
 }
 {
   sd  111 .  .  . 10 @c_sdsp
-  fsw 111 .  .  . 10 @c_swsp
+  c_fsw   111 .  .  . 10 @c_swsp
 }
diff --git a/target/riscv/insn_trans/trans_rvf.c.inc 
b/target/riscv/insn_trans/trans_rvf.c.inc
index 93657680c6..426518957b 100644
--- a/target/riscv/insn_trans/trans_rvf.c.inc
+++ b/target/riscv/insn_trans/trans_rvf.c.inc
@@ -24,6 +24,12 @@
 return false; \
 } while (0)
 
+#define REQUIRE_ZCF(ctx) do {  \
+if (!ctx->cfg_ptr->ext_zcf) {  \
+return false;  \
+}  \
+} while (0)
+
 #ifndef CONFIG_USER_ONLY
 static inline bool smstateen_fcsr_check(DisasContext *ctx, int index)
 {
@@ -96,6 +102,18 @@ static bool trans_fsw(DisasContext *ctx, arg_fsw *a)
 return true;
 }
 
+static bool trans_c_flw(DisasContext *ctx, arg_flw *a)
+{
+REQUIRE_ZCF(ctx);
+return trans_flw(ctx, a);
+}
+
+static bool trans_c_fsw(DisasContext *ctx, arg_fsw *a)
+{
+REQUIRE_ZCF(ctx);
+return trans_fsw(ctx, a);
+}
+
 static bool trans_fmadd_s(DisasContext *ctx, arg_fmadd_s *a)
 {
 REQUIRE_FPU;
-- 
2.25.1




[PATCH v5 0/9] support subsets of code size reduction extension

2022-11-18 Thread Weiwei Li
This patchset implements RISC-V Zc* extension v1.0.0.RC5.7 version instructions.

Specification:
https://github.com/riscv/riscv-code-size-reduction/tree/main/Zc-specification

The port is available here:
https://github.com/plctlab/plct-qemu/tree/plct-zce-upstream-v5

To test Zc* implementation, specify cpu argument with 
'x-zca=true,x-zcb=true,x-zcf=true,f=true" and "x-zcd=true,d=true" (or 
"x-zcmp=true,x-zcmt=true" with c or d=false) to enable Zca/Zcb/Zcf and Zcd(or 
Zcmp,Zcmt) extension support.


This implementation can pass the basic zc tests from 
https://github.com/yulong-plct/zc-test

v5:
* fix exception unwind problem for cpu_ld*_code in helper of cm_jalt

v4:
* improve Zcmp suggested by Richard
* fix stateen related check for Zcmt

v3:
* update the solution for Zcf to the way of Zcd
* update Zcb to reuse gen_load/store
* use trans function instead of helper for push/pop

v2:
* add check for relationship between Zca/Zcf/Zcd with C/F/D based on related 
discussion in review of Zc* spec
* separate c.fld{sp}/fsd{sp} with fld{sp}/fsd{sp} before support of zcmp/zcmt

Weiwei Li (9):
  target/riscv: add cfg properties for Zc* extension
  target/riscv: add support for Zca extension
  target/riscv: add support for Zcf extension
  target/riscv: add support for Zcd extension
  target/riscv: add support for Zcb extension
  target/riscv: add support for Zcmp extension
  target/riscv: add support for Zcmt extension
  target/riscv: expose properties for Zc* extension
  disas/riscv.c: add disasm support for Zc*

 disas/riscv.c | 287 +++-
 target/riscv/cpu.c|  56 
 target/riscv/cpu.h|  10 +
 target/riscv/cpu_bits.h   |   7 +
 target/riscv/csr.c|  38 ++-
 target/riscv/helper.h |   3 +
 target/riscv/insn16.decode|  63 -
 target/riscv/insn_trans/trans_rvd.c.inc   |  18 ++
 target/riscv/insn_trans/trans_rvf.c.inc   |  18 ++
 target/riscv/insn_trans/trans_rvi.c.inc   |   4 +-
 target/riscv/insn_trans/trans_rvzce.c.inc | 313 ++
 target/riscv/machine.c|  19 ++
 target/riscv/meson.build  |   3 +-
 target/riscv/translate.c  |  15 +-
 target/riscv/zce_helper.c |  55 
 15 files changed, 893 insertions(+), 16 deletions(-)
 create mode 100644 target/riscv/insn_trans/trans_rvzce.c.inc
 create mode 100644 target/riscv/zce_helper.c

-- 
2.25.1




[PATCH v5 7/9] target/riscv: add support for Zcmt extension

2022-11-18 Thread Weiwei Li
Add encode, trans* functions and helper functions support for Zcmt
instrutions
Add support for jvt csr

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
---
 target/riscv/cpu.h|  4 ++
 target/riscv/cpu_bits.h   |  7 +++
 target/riscv/csr.c| 38 +++-
 target/riscv/helper.h |  3 ++
 target/riscv/insn16.decode|  7 ++-
 target/riscv/insn_trans/trans_rvzce.c.inc | 28 +++-
 target/riscv/machine.c| 19 
 target/riscv/meson.build  |  3 +-
 target/riscv/zce_helper.c | 55 +++
 9 files changed, 159 insertions(+), 5 deletions(-)
 create mode 100644 target/riscv/zce_helper.c

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 6e915b6937..7bcedc7467 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -181,6 +181,8 @@ struct CPUArchState {
 
 uint32_t features;
 
+target_ulong jvt;
+
 #ifdef CONFIG_USER_ONLY
 uint32_t elf_flags;
 #endif
@@ -600,6 +602,8 @@ void riscv_cpu_set_aia_ireg_rmw_fn(CPURISCVState *env, 
uint32_t priv,
  target_ulong new_val,
  target_ulong write_mask),
void *rmw_fn_arg);
+
+RISCVException smstateen_acc_ok(CPURISCVState *env, int index, uint64_t bit);
 #endif
 void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv);
 
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 8b0d7e20ea..ce347e5575 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -319,6 +319,7 @@
 #define SMSTATEEN_MAX_COUNT 4
 #define SMSTATEEN0_CS   (1ULL << 0)
 #define SMSTATEEN0_FCSR (1ULL << 1)
+#define SMSTATEEN0_JVT  (1ULL << 2)
 #define SMSTATEEN0_HSCONTXT (1ULL << 57)
 #define SMSTATEEN0_IMSIC(1ULL << 58)
 #define SMSTATEEN0_AIA  (1ULL << 59)
@@ -523,6 +524,9 @@
 /* Crypto Extension */
 #define CSR_SEED0x015
 
+/* Zcmt Extension */
+#define CSR_JVT 0x017
+
 /* mstatus CSR bits */
 #define MSTATUS_UIE 0x0001
 #define MSTATUS_SIE 0x0002
@@ -894,4 +898,7 @@ typedef enum RISCVException {
 #define MHPMEVENT_IDX_MASK 0xF
 #define MHPMEVENT_SSCOF_RESVD  16
 
+/* JVT CSR bits */
+#define JVT_MODE   0x3F
+#define JVT_BASE   (~0x3F)
 #endif
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 8b25f885ec..5115dc882d 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -42,8 +42,7 @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops)
 
 /* Predicates */
 #if !defined(CONFIG_USER_ONLY)
-static RISCVException smstateen_acc_ok(CPURISCVState *env, int index,
-   uint64_t bit)
+RISCVException smstateen_acc_ok(CPURISCVState *env, int index, uint64_t bit)
 {
 bool virt = riscv_cpu_virt_enabled(env);
 CPUState *cs = env_cpu(env);
@@ -167,6 +166,24 @@ static RISCVException ctr32(CPURISCVState *env, int csrno)
 return ctr(env, csrno);
 }
 
+static RISCVException zcmt(CPURISCVState *env, int csrno)
+{
+RISCVCPU *cpu = env_archcpu(env);
+
+if (!cpu->cfg.ext_zcmt) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
+#if !defined(CONFIG_USER_ONLY)
+RISCVException ret = smstateen_acc_ok(env, 0, SMSTATEEN0_JVT);
+if (ret != RISCV_EXCP_NONE) {
+return ret;
+}
+#endif
+
+return RISCV_EXCP_NONE;
+}
+
 #if !defined(CONFIG_USER_ONLY)
 static RISCVException mctr(CPURISCVState *env, int csrno)
 {
@@ -3987,6 +4004,20 @@ RISCVException riscv_csrrw_debug(CPURISCVState *env, int 
csrno,
 return ret;
 }
 
+static RISCVException read_jvt(CPURISCVState *env, int csrno,
+   target_ulong *val)
+{
+*val = env->jvt;
+return RISCV_EXCP_NONE;
+}
+
+static RISCVException write_jvt(CPURISCVState *env, int csrno,
+target_ulong val)
+{
+env->jvt = val;
+return RISCV_EXCP_NONE;
+}
+
 /* Control and Status Register function table */
 riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
 /* User Floating-Point CSRs */
@@ -4024,6 +4055,9 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
 /* Crypto Extension */
 [CSR_SEED] = { "seed", seed, NULL, NULL, rmw_seed },
 
+/* Zcmt Extension */
+[CSR_JVT] = {"jvt", zcmt, read_jvt, write_jvt},
+
 #if !defined(CONFIG_USER_ONLY)
 /* Machine Timers and Counters */
 [CSR_MCYCLE]= { "mcycle",any,   read_hpmcounter,
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 227c7122ef..d979f0bfc4 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1136,3 +1136,6 @@ DEF_HELPER_FLAGS_1(aes64im, TCG_CALL_NO_RWG_SE, tl, tl)
 
 DEF_HELPER_FLAGS_3(sm4ed, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl)
 DEF

[PATCH v5 2/9] target/riscv: add support for Zca extension

2022-11-18 Thread Weiwei Li
Modify the check for C extension to Zca (C implies Zca)

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Richard Henderson 
---
 target/riscv/insn_trans/trans_rvi.c.inc | 4 ++--
 target/riscv/translate.c| 8 ++--
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvi.c.inc 
b/target/riscv/insn_trans/trans_rvi.c.inc
index 5c69b88d1e..0d73b919ce 100644
--- a/target/riscv/insn_trans/trans_rvi.c.inc
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
@@ -56,7 +56,7 @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
 tcg_gen_andi_tl(cpu_pc, cpu_pc, (target_ulong)-2);
 
 gen_set_pc(ctx, cpu_pc);
-if (!has_ext(ctx, RVC)) {
+if (!ctx->cfg_ptr->ext_zca) {
 TCGv t0 = tcg_temp_new();
 
 misaligned = gen_new_label();
@@ -178,7 +178,7 @@ static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond 
cond)
 
 gen_set_label(l); /* branch taken */
 
-if (!has_ext(ctx, RVC) && ((ctx->base.pc_next + a->imm) & 0x3)) {
+if (!ctx->cfg_ptr->ext_zca && ((ctx->base.pc_next + a->imm) & 0x3)) {
 /* misaligned */
 gen_exception_inst_addr_mis(ctx);
 } else {
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 2ab8772ebe..ee24b451e3 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -557,7 +557,7 @@ static void gen_jal(DisasContext *ctx, int rd, target_ulong 
imm)
 
 /* check misaligned: */
 next_pc = ctx->base.pc_next + imm;
-if (!has_ext(ctx, RVC)) {
+if (!ctx->cfg_ptr->ext_zca) {
 if ((next_pc & 0x3) != 0) {
 gen_exception_inst_addr_mis(ctx);
 return;
@@ -1097,7 +1097,11 @@ static void decode_opc(CPURISCVState *env, DisasContext 
*ctx, uint16_t opcode)
 ctx->virt_inst_excp = false;
 /* Check for compressed insn */
 if (insn_len(opcode) == 2) {
-if (!has_ext(ctx, RVC)) {
+/*
+ * Zca support all of the existing C extension, excluding all
+ * compressed floating point loads and stores
+ */
+if (!ctx->cfg_ptr->ext_zca) {
 gen_exception_illegal(ctx);
 } else {
 ctx->opcode = opcode;
-- 
2.25.1




[PATCH v5 5/9] target/riscv: add support for Zcb extension

2022-11-18 Thread Weiwei Li
Add encode and trans* functions support for Zcb instructions

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Richard Henderson 
---
 target/riscv/insn16.decode|  24 ++
 target/riscv/insn_trans/trans_rvzce.c.inc | 100 ++
 target/riscv/translate.c  |   2 +
 3 files changed, 126 insertions(+)
 create mode 100644 target/riscv/insn_trans/trans_rvzce.c.inc

diff --git a/target/riscv/insn16.decode b/target/riscv/insn16.decode
index b62664b6af..47603ec1e0 100644
--- a/target/riscv/insn16.decode
+++ b/target/riscv/insn16.decode
@@ -43,6 +43,8 @@
 %imm_addi16sp  12:s1 3:2 5:1 2:1 6:1 !function=ex_shift_4
 %imm_lui   12:s1 2:5 !function=ex_shift_12
 
+%zcb_b_uimm  5:1 6:1
+%zcb_h_uimm  5:1 !function=ex_shift_1
 
 # Argument sets imported from insn32.decode:
 &empty  !extern
@@ -53,6 +55,7 @@
 &b imm rs2 rs1  !extern
 &u imm rd   !extern
 &shift shamt rs1 rd !extern
+&r2rd rs1   !extern
 
 
 # Formats 16:
@@ -89,6 +92,13 @@
 
 @c_andi ... . .. ... . .. &i imm=%imm_ci rs1=%rs1_3 rd=%rs1_3
 
+@zcb_unary... ...  ... .. ... ..  &r2  rs1=%rs1_3 rd=%rs1_3
+@zcb_binary   ... ...  ... .. ... ..  &r  rs2=%rs2_3   rs1=%rs1_3 rd=%rs1_3
+@zcb_lb   ... . .. ... .. ... ..  &i  imm=%zcb_b_uimm  rs1=%rs1_3 rd=%rs2_3
+@zcb_lh   ... . .. ... .. ... ..  &i  imm=%zcb_h_uimm  rs1=%rs1_3 rd=%rs2_3
+@zcb_sb   ... . .. ... .. ... ..  &s  imm=%zcb_b_uimm  rs1=%rs1_3 
rs2=%rs2_3
+@zcb_sh   ... . .. ... .. ... ..  &s  imm=%zcb_h_uimm  rs1=%rs1_3 
rs2=%rs2_3
+
 # *** RV32/64C Standard Extension (Quadrant 0) ***
 {
   # Opcode of all zeros is illegal; rd != 0, nzuimm == 0 is reserved.
@@ -180,3 +190,17 @@ sw110 .  .  . 10 @c_swsp
   sd  111 .  .  . 10 @c_sdsp
   c_fsw   111 .  .  . 10 @c_swsp
 }
+
+# *** RV64 and RV32 Zcb Extension ***
+c_zext_b  100 111  ... 11 000 01 @zcb_unary
+c_sext_b  100 111  ... 11 001 01 @zcb_unary
+c_zext_h  100 111  ... 11 010 01 @zcb_unary
+c_sext_h  100 111  ... 11 011 01 @zcb_unary
+c_zext_w  100 111  ... 11 100 01 @zcb_unary
+c_not 100 111  ... 11 101 01 @zcb_unary
+c_mul 100 111  ... 10 ... 01 @zcb_binary
+c_lbu 100 000  ... .. ... 00 @zcb_lb
+c_lhu 100 001  ... 0. ... 00 @zcb_lh
+c_lh  100 001  ... 1. ... 00 @zcb_lh
+c_sb  100 010  ... .. ... 00 @zcb_sb
+c_sh  100 011  ... 0. ... 00 @zcb_sh
diff --git a/target/riscv/insn_trans/trans_rvzce.c.inc 
b/target/riscv/insn_trans/trans_rvzce.c.inc
new file mode 100644
index 00..de96c4afaf
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rvzce.c.inc
@@ -0,0 +1,100 @@
+/*
+ * RISC-V translation routines for the Zcb Standard Extension.
+ *
+ * Copyright (c) 2021-2022 PLCT Lab
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define REQUIRE_ZCB(ctx) do {   \
+if (!ctx->cfg_ptr->ext_zcb) \
+return false;   \
+} while (0)
+
+static bool trans_c_zext_b(DisasContext *ctx, arg_c_zext_b *a)
+{
+REQUIRE_ZCB(ctx);
+return gen_unary(ctx, a, EXT_NONE, tcg_gen_ext8u_tl);
+}
+
+static bool trans_c_zext_h(DisasContext *ctx, arg_c_zext_h *a)
+{
+REQUIRE_ZCB(ctx);
+REQUIRE_ZBB(ctx);
+return gen_unary(ctx, a, EXT_NONE, tcg_gen_ext16u_tl);
+}
+
+static bool trans_c_sext_b(DisasContext *ctx, arg_c_sext_b *a)
+{
+REQUIRE_ZCB(ctx);
+REQUIRE_ZBB(ctx);
+return gen_unary(ctx, a, EXT_NONE, tcg_gen_ext8s_tl);
+}
+
+static bool trans_c_sext_h(DisasContext *ctx, arg_c_sext_h *a)
+{
+REQUIRE_ZCB(ctx);
+REQUIRE_ZBB(ctx);
+return gen_unary(ctx, a, EXT_NONE, tcg_gen_ext16s_tl);
+}
+
+static bool trans_c_zext_w(DisasContext *ctx, arg_c_zext_w *a)
+{
+REQUIRE_64BIT(ctx);
+REQUIRE_ZCB(ctx);
+REQUIRE_ZBA(ctx);
+return gen_unary(ctx, a, EXT_NONE, tcg_gen_ext32u_tl);
+}
+
+static bool trans_c_not(DisasContext *ctx, arg_c_not *a)
+{
+REQUIRE_ZCB(ctx);
+return gen_unary(ctx, a, EXT_NONE, tcg_gen_not_tl);
+}
+
+static bool trans_c_mul(DisasContext *ctx, arg_c_mul *a)
+{
+REQUIRE_ZCB(ctx);
+REQUIRE_M_OR_ZMMUL(ctx);
+return gen_arith(ctx, a, EXT_NONE, tcg_gen_mul_tl, NULL);
+

[PATCH v5 1/9] target/riscv: add cfg properties for Zc* extension

2022-11-18 Thread Weiwei Li
Add properties for Zca,Zcb,Zcf,Zcd,Zcmp,Zcmt extension
Add check for these properties

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Cc: Alistair Francis 
Reviewed-by: Richard Henderson 
---
 target/riscv/cpu.c | 43 +++
 target/riscv/cpu.h |  6 ++
 2 files changed, 49 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 042fd541b4..1ab04ab246 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -805,6 +805,49 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 }
 }
 
+if (cpu->cfg.ext_c) {
+cpu->cfg.ext_zca = true;
+if (cpu->cfg.ext_f && env->misa_mxl_max == MXL_RV32) {
+cpu->cfg.ext_zcf = true;
+}
+if (cpu->cfg.ext_d) {
+cpu->cfg.ext_zcd = true;
+}
+}
+
+if (env->misa_mxl_max != MXL_RV32 && cpu->cfg.ext_zcf) {
+error_setg(errp, "Zcf extension is only relevant to RV32");
+return;
+}
+
+if (!cpu->cfg.ext_f && cpu->cfg.ext_zcf) {
+error_setg(errp, "Zcf extension requires F extension");
+return;
+}
+
+if (!cpu->cfg.ext_d && cpu->cfg.ext_zcd) {
+error_setg(errp, "Zcd extensionrequires D extension");
+return;
+}
+
+if ((cpu->cfg.ext_zcf || cpu->cfg.ext_zcd || cpu->cfg.ext_zcb ||
+ cpu->cfg.ext_zcmp || cpu->cfg.ext_zcmt) && !cpu->cfg.ext_zca) {
+error_setg(errp, "Zcf/Zcd/Zcb/Zcmp/Zcmt extensions require Zca "
+ "extension");
+return;
+}
+
+if (cpu->cfg.ext_zcd && (cpu->cfg.ext_zcmp || cpu->cfg.ext_zcmt)) {
+error_setg(errp, "Zcmp/Zcmt extensions are incompatible with "
+ "Zcd extension");
+return;
+}
+
+if (cpu->cfg.ext_zcmt && !cpu->cfg.ext_icsr) {
+error_setg(errp, "Zcmt extension requires Zicsr extension");
+return;
+}
+
 if (cpu->cfg.ext_zk) {
 cpu->cfg.ext_zkn = true;
 cpu->cfg.ext_zkr = true;
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 9bd539d77a..6e915b6937 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -434,6 +434,12 @@ struct RISCVCPUConfig {
 bool ext_zbkc;
 bool ext_zbkx;
 bool ext_zbs;
+bool ext_zca;
+bool ext_zcb;
+bool ext_zcd;
+bool ext_zcf;
+bool ext_zcmp;
+bool ext_zcmt;
 bool ext_zk;
 bool ext_zkn;
 bool ext_zknd;
-- 
2.25.1




[PATCH v5 9/9] disas/riscv.c: add disasm support for Zc*

2022-11-18 Thread Weiwei Li
Zcmp/Zcmt instructions will override disasm for c.fld*/c.fsd*
instructions currently

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
---
 disas/riscv.c | 287 +-
 1 file changed, 286 insertions(+), 1 deletion(-)

diff --git a/disas/riscv.c b/disas/riscv.c
index d216b9c39b..81369063b5 100644
--- a/disas/riscv.c
+++ b/disas/riscv.c
@@ -163,6 +163,13 @@ typedef enum {
 rv_codec_v_i,
 rv_codec_vsetvli,
 rv_codec_vsetivli,
+rv_codec_zcb_ext,
+rv_codec_zcb_mul,
+rv_codec_zcb_lb,
+rv_codec_zcb_lh,
+rv_codec_zcmp_cm_pushpop,
+rv_codec_zcmp_cm_mv,
+rv_codec_zcmt_jt,
 } rv_codec;
 
 typedef enum {
@@ -935,6 +942,26 @@ typedef enum {
 rv_op_vsetvli = 766,
 rv_op_vsetivli = 767,
 rv_op_vsetvl = 768,
+rv_op_c_zext_b = 769,
+rv_op_c_sext_b = 770,
+rv_op_c_zext_h = 771,
+rv_op_c_sext_h = 772,
+rv_op_c_zext_w = 773,
+rv_op_c_not = 774,
+rv_op_c_mul = 775,
+rv_op_c_lbu = 776,
+rv_op_c_lhu = 777,
+rv_op_c_lh = 778,
+rv_op_c_sb = 779,
+rv_op_c_sh = 780,
+rv_op_cm_push = 781,
+rv_op_cm_pop = 782,
+rv_op_cm_popret = 783,
+rv_op_cm_popretz = 784,
+rv_op_cm_mva01s = 785,
+rv_op_cm_mvsa01 = 786,
+rv_op_cm_jt = 787,
+rv_op_cm_jalt = 788,
 } rv_op;
 
 /* structures */
@@ -958,6 +985,7 @@ typedef struct {
 uint8_t   rnum;
 uint8_t   vm;
 uint32_t  vzimm;
+uint8_t   rlist;
 } rv_decode;
 
 typedef struct {
@@ -1070,6 +1098,10 @@ static const char rv_vreg_name_sym[32][4] = {
 #define rv_fmt_vd_vm  "O\tDm"
 #define rv_fmt_vsetvli"O\t0,1,v"
 #define rv_fmt_vsetivli   "O\t0,u,v"
+#define rv_fmt_rs1_rs2_zce_ldst   "O\t2,i(1)"
+#define rv_fmt_push_rlist "O\tx,-i"
+#define rv_fmt_pop_rlist  "O\tx,i"
+#define rv_fmt_zcmt_index "O\ti"
 
 /* pseudo-instruction constraints */
 
@@ -2065,7 +2097,27 @@ const rv_opcode_data opcode_data[] = {
 { "vsext.vf8", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vsext_vf8, 
rv_op_vsext_vf8, 0 },
 { "vsetvli", rv_codec_vsetvli, rv_fmt_vsetvli, NULL, rv_op_vsetvli, 
rv_op_vsetvli, 0 },
 { "vsetivli", rv_codec_vsetivli, rv_fmt_vsetivli, NULL, rv_op_vsetivli, 
rv_op_vsetivli, 0 },
-{ "vsetvl", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, rv_op_vsetvl, 
rv_op_vsetvl, 0 }
+{ "vsetvl", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, rv_op_vsetvl, 
rv_op_vsetvl, 0 },
+{ "c.zext.b", rv_codec_zcb_ext, rv_fmt_rd, NULL, 0 },
+{ "c.sext.b", rv_codec_zcb_ext, rv_fmt_rd, NULL, 0 },
+{ "c.zext.h", rv_codec_zcb_ext, rv_fmt_rd, NULL, 0 },
+{ "c.sext.h", rv_codec_zcb_ext, rv_fmt_rd, NULL, 0 },
+{ "c.zext.w", rv_codec_zcb_ext, rv_fmt_rd, NULL, 0 },
+{ "c.not", rv_codec_zcb_ext, rv_fmt_rd, NULL, 0 },
+{ "c.mul", rv_codec_zcb_mul, rv_fmt_rd_rs2, NULL, 0, 0 },
+{ "c.lbu", rv_codec_zcb_lb, rv_fmt_rs1_rs2_zce_ldst, NULL, 0, 0, 0 },
+{ "c.lhu", rv_codec_zcb_lh, rv_fmt_rs1_rs2_zce_ldst, NULL, 0, 0, 0 },
+{ "c.lh", rv_codec_zcb_lh, rv_fmt_rs1_rs2_zce_ldst, NULL, 0, 0, 0 },
+{ "c.sb", rv_codec_zcb_lb, rv_fmt_rs1_rs2_zce_ldst, NULL, 0, 0, 0 },
+{ "c.sh", rv_codec_zcb_lh, rv_fmt_rs1_rs2_zce_ldst, NULL, 0, 0, 0 },
+{ "cm.push", rv_codec_zcmp_cm_pushpop, rv_fmt_push_rlist, NULL, 0, 0 },
+{ "cm.pop", rv_codec_zcmp_cm_pushpop, rv_fmt_pop_rlist, NULL, 0, 0 },
+{ "cm.popret", rv_codec_zcmp_cm_pushpop, rv_fmt_pop_rlist, NULL, 0, 0, 0 },
+{ "cm.popretz", rv_codec_zcmp_cm_pushpop, rv_fmt_pop_rlist, NULL, 0, 0 },
+{ "cm.mva01s", rv_codec_zcmp_cm_mv, rv_fmt_rd_rs2, NULL, 0, 0, 0 },
+{ "cm.mvsa01", rv_codec_zcmp_cm_mv, rv_fmt_rd_rs2, NULL, 0, 0, 0 },
+{ "cm.jt", rv_codec_zcmt_jt, rv_fmt_zcmt_index, NULL, 0 },
+{ "cm.jalt", rv_codec_zcmt_jt, rv_fmt_zcmt_index, NULL, 0 },
 };
 
 /* CSR names */
@@ -2084,6 +2136,7 @@ static const char *csr_name(int csrno)
 case 0x000a: return "vxrm";
 case 0x000f: return "vcsr";
 case 0x0015: return "seed";
+case 0x0017: return "jvt";
 case 0x0040: return "uscratch";
 case 0x0041: return "uepc";
 case 0x0042: return "ucause";
@@ -2306,6 +2359,24 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa 
isa)
 op = rv_op_c_ld;
 }
 break;
+case 4:
+switch ((inst >> 10) & 0b111) {
+case 0: op = rv_op_c_lbu; break;
+case 1:
+if (((inst >> 6) & 1) == 0) {
+op = rv_op_c_lhu;
+} else {
+

[PATCH v5 8/9] target/riscv: expose properties for Zc* extension

2022-11-18 Thread Weiwei Li
Expose zca,zcb,zcf,zcd,zcmp,zcmt properties

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 1ab04ab246..b9e41df96c 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -81,6 +81,12 @@ static const struct isa_ext_data isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(zfhmin, true, PRIV_VERSION_1_12_0, ext_zfhmin),
 ISA_EXT_DATA_ENTRY(zfinx, true, PRIV_VERSION_1_12_0, ext_zfinx),
 ISA_EXT_DATA_ENTRY(zdinx, true, PRIV_VERSION_1_12_0, ext_zdinx),
+ISA_EXT_DATA_ENTRY(zca, true, PRIV_VERSION_1_12_0, ext_zca),
+ISA_EXT_DATA_ENTRY(zcb, true, PRIV_VERSION_1_12_0, ext_zcb),
+ISA_EXT_DATA_ENTRY(zcf, true, PRIV_VERSION_1_12_0, ext_zcf),
+ISA_EXT_DATA_ENTRY(zcd, true, PRIV_VERSION_1_12_0, ext_zcd),
+ISA_EXT_DATA_ENTRY(zcmp, true, PRIV_VERSION_1_12_0, ext_zcmp),
+ISA_EXT_DATA_ENTRY(zcmt, true, PRIV_VERSION_1_12_0, ext_zcmt),
 ISA_EXT_DATA_ENTRY(zba, true, PRIV_VERSION_1_12_0, ext_zba),
 ISA_EXT_DATA_ENTRY(zbb, true, PRIV_VERSION_1_12_0, ext_zbb),
 ISA_EXT_DATA_ENTRY(zbc, true, PRIV_VERSION_1_12_0, ext_zbc),
@@ -1114,6 +1120,13 @@ static Property riscv_cpu_extensions[] = {
 
 /* These are experimental so mark with 'x-' */
 DEFINE_PROP_BOOL("x-j", RISCVCPU, cfg.ext_j, false),
+
+DEFINE_PROP_BOOL("x-zca", RISCVCPU, cfg.ext_zca, false),
+DEFINE_PROP_BOOL("x-zcb", RISCVCPU, cfg.ext_zcb, false),
+DEFINE_PROP_BOOL("x-zcd", RISCVCPU, cfg.ext_zcd, false),
+DEFINE_PROP_BOOL("x-zcf", RISCVCPU, cfg.ext_zcf, false),
+DEFINE_PROP_BOOL("x-zcmp", RISCVCPU, cfg.ext_zcmp, false),
+DEFINE_PROP_BOOL("x-zcmt", RISCVCPU, cfg.ext_zcmt, false),
 /* ePMP 0.9.3 */
 DEFINE_PROP_BOOL("x-epmp", RISCVCPU, cfg.epmp, false),
 DEFINE_PROP_BOOL("x-smaia", RISCVCPU, cfg.ext_smaia, false),
-- 
2.25.1




[PATCH v5 6/9] target/riscv: add support for Zcmp extension

2022-11-18 Thread Weiwei Li
Add encode, trans* functions for Zcmp instructions

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Richard Henderson 
---
 target/riscv/insn16.decode|  18 +++
 target/riscv/insn_trans/trans_rvzce.c.inc | 189 +-
 target/riscv/translate.c  |   5 +
 3 files changed, 211 insertions(+), 1 deletion(-)

diff --git a/target/riscv/insn16.decode b/target/riscv/insn16.decode
index 47603ec1e0..4654c23052 100644
--- a/target/riscv/insn16.decode
+++ b/target/riscv/insn16.decode
@@ -21,6 +21,8 @@
 %rs1_3 7:3!function=ex_rvc_register
 %rs2_3 2:3!function=ex_rvc_register
 %rs2_5 2:5
+%sreg1 7:3!function=ex_sreg_register
+%sreg2 2:3!function=ex_sreg_register
 
 # Immediates:
 %imm_ci12:s1 2:5
@@ -45,6 +47,8 @@
 
 %zcb_b_uimm  5:1 6:1
 %zcb_h_uimm  5:1 !function=ex_shift_1
+%zcmp_spimm  2:2 !function=ex_shift_4
+%zcmp_rlist  4:4
 
 # Argument sets imported from insn32.decode:
 &empty  !extern
@@ -56,7 +60,9 @@
 &u imm rd   !extern
 &shift shamt rs1 rd !extern
 &r2rd rs1   !extern
+&r2_s  rs1 rs2  !extern
 
+&zcmp  zcmp_rlist zcmp_spimm
 
 # Formats 16:
 @cr  . .  .. &r  rs2=%rs2_5   rs1=%rd %rd
@@ -98,6 +104,8 @@
 @zcb_lh   ... . .. ... .. ... ..  &i  imm=%zcb_h_uimm  rs1=%rs1_3 rd=%rs2_3
 @zcb_sb   ... . .. ... .. ... ..  &s  imm=%zcb_b_uimm  rs1=%rs1_3 
rs2=%rs2_3
 @zcb_sh   ... . .. ... .. ... ..  &s  imm=%zcb_h_uimm  rs1=%rs1_3 
rs2=%rs2_3
+@zcmp ... ...     ..  &zcmp  %zcmp_rlist   %zcmp_spimm
+@cm_mv... ...  ... .. ... ..  &r2_s  rs2=%sreg2rs1=%sreg1
 
 # *** RV32/64C Standard Extension (Quadrant 0) ***
 {
@@ -177,6 +185,16 @@ slli  000 .  .  . 10 @c_shift2
 {
   sq  101  ... ... .. ... 10 @c_sqsp
   c_fsd   101   ..  . 10 @c_sdsp
+
+  # *** RV64 and RV32 Zcmp Extension ***
+  [
+cm_push 101  11000   .. 10 @zcmp
+cm_pop  101  11010   .. 10 @zcmp
+cm_popret   101  0   .. 10 @zcmp
+cm_popretz  101  11100   .. 10 @zcmp
+cm_mva01s   101  011 ... 11 ... 10 @cm_mv
+cm_mvsa01   101  011 ... 01 ... 10 @cm_mv
+  ]
 }
 sw110 .  .  . 10 @c_swsp
 
diff --git a/target/riscv/insn_trans/trans_rvzce.c.inc 
b/target/riscv/insn_trans/trans_rvzce.c.inc
index de96c4afaf..f647b6ed15 100644
--- a/target/riscv/insn_trans/trans_rvzce.c.inc
+++ b/target/riscv/insn_trans/trans_rvzce.c.inc
@@ -1,5 +1,5 @@
 /*
- * RISC-V translation routines for the Zcb Standard Extension.
+ * RISC-V translation routines for the Zc[b,mp] Standard Extension.
  *
  * Copyright (c) 2021-2022 PLCT Lab
  *
@@ -21,6 +21,11 @@
 return false;   \
 } while (0)
 
+#define REQUIRE_ZCMP(ctx) do {   \
+if (!ctx->cfg_ptr->ext_zcmp) \
+return false;\
+} while (0)
+
 static bool trans_c_zext_b(DisasContext *ctx, arg_c_zext_b *a)
 {
 REQUIRE_ZCB(ctx);
@@ -98,3 +103,185 @@ static bool trans_c_sh(DisasContext *ctx, arg_c_sh *a)
 REQUIRE_ZCB(ctx);
 return gen_store(ctx, a, MO_UW);
 }
+
+#define X_S08
+#define X_S19
+#define X_Sn16
+
+static uint32_t decode_push_pop_list(DisasContext *ctx, target_ulong rlist)
+{
+uint32_t reg_bitmap = 0;
+
+if (ctx->cfg_ptr->ext_e && rlist > 6) {
+return 0;
+}
+
+switch (rlist) {
+case 15:
+reg_bitmap |=  1 << (X_Sn + 11) ;
+reg_bitmap |=  1 << (X_Sn + 10) ;
+/* FALL THROUGH */
+case 14:
+reg_bitmap |=  1 << (X_Sn + 9) ;
+/* FALL THROUGH */
+case 13:
+reg_bitmap |=  1 << (X_Sn + 8) ;
+/* FALL THROUGH */
+case 12:
+reg_bitmap |=  1 << (X_Sn + 7) ;
+/* FALL THROUGH */
+case 11:
+reg_bitmap |=  1 << (X_Sn + 6) ;
+/* FALL THROUGH */
+case 10:
+reg_bitmap |=  1 << (X_Sn + 5) ;
+/* FALL THROUGH */
+case 9:
+reg_bitmap |=  1 << (X_Sn + 4) ;
+/* FALL THROUGH */
+case 8:
+reg_bitmap |=  1 << (X_Sn + 3) ;
+/* FALL THROUGH */
+case 7:
+reg_bitmap |=  1 << (X_Sn + 2) ;
+/* FALL THROUGH */
+case 6:
+reg_bitmap |=  1 << X_S1 ;
+/* FALL THROUGH */
+case 5:
+reg_bitmap |= 1 << X_S0;
+/* FALL THROUGH */
+case 4:
+reg_bitmap |= 1 << xRA;
+break;
+default:
+break;
+}
+
+return reg_bitmap;
+}
+
+static bool gen_pop(DisasContext *ctx, arg_zcmp *a, bool ret, bool ret_val)
+{
+REQUIRE_ZCMP(ctx);
+
+uint32_t reg_bitmap = decode_push_pop_list(ctx, a->zcmp_rlist);
+if (reg_bitmap == 0) {

[PATCH v6 8/9] target/riscv: expose properties for Zc* extension

2022-11-28 Thread Weiwei Li
Expose zca,zcb,zcf,zcd,zcmp,zcmt properties

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 9f4aa0fe55..64027a07e6 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -81,6 +81,12 @@ static const struct isa_ext_data isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(zfhmin, true, PRIV_VERSION_1_12_0, ext_zfhmin),
 ISA_EXT_DATA_ENTRY(zfinx, true, PRIV_VERSION_1_12_0, ext_zfinx),
 ISA_EXT_DATA_ENTRY(zdinx, true, PRIV_VERSION_1_12_0, ext_zdinx),
+ISA_EXT_DATA_ENTRY(zca, true, PRIV_VERSION_1_12_0, ext_zca),
+ISA_EXT_DATA_ENTRY(zcb, true, PRIV_VERSION_1_12_0, ext_zcb),
+ISA_EXT_DATA_ENTRY(zcf, true, PRIV_VERSION_1_12_0, ext_zcf),
+ISA_EXT_DATA_ENTRY(zcd, true, PRIV_VERSION_1_12_0, ext_zcd),
+ISA_EXT_DATA_ENTRY(zcmp, true, PRIV_VERSION_1_12_0, ext_zcmp),
+ISA_EXT_DATA_ENTRY(zcmt, true, PRIV_VERSION_1_12_0, ext_zcmt),
 ISA_EXT_DATA_ENTRY(zba, true, PRIV_VERSION_1_12_0, ext_zba),
 ISA_EXT_DATA_ENTRY(zbb, true, PRIV_VERSION_1_12_0, ext_zbb),
 ISA_EXT_DATA_ENTRY(zbc, true, PRIV_VERSION_1_12_0, ext_zbc),
@@ -1116,6 +1122,13 @@ static Property riscv_cpu_extensions[] = {
 
 /* These are experimental so mark with 'x-' */
 DEFINE_PROP_BOOL("x-j", RISCVCPU, cfg.ext_j, false),
+
+DEFINE_PROP_BOOL("x-zca", RISCVCPU, cfg.ext_zca, false),
+DEFINE_PROP_BOOL("x-zcb", RISCVCPU, cfg.ext_zcb, false),
+DEFINE_PROP_BOOL("x-zcd", RISCVCPU, cfg.ext_zcd, false),
+DEFINE_PROP_BOOL("x-zcf", RISCVCPU, cfg.ext_zcf, false),
+DEFINE_PROP_BOOL("x-zcmp", RISCVCPU, cfg.ext_zcmp, false),
+DEFINE_PROP_BOOL("x-zcmt", RISCVCPU, cfg.ext_zcmt, false),
 /* ePMP 0.9.3 */
 DEFINE_PROP_BOOL("x-epmp", RISCVCPU, cfg.epmp, false),
 DEFINE_PROP_BOOL("x-smaia", RISCVCPU, cfg.ext_smaia, false),
-- 
2.25.1




[PATCH v6 2/9] target/riscv: add support for Zca extension

2022-11-28 Thread Weiwei Li
Modify the check for C extension to Zca (C implies Zca)

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/insn_trans/trans_rvi.c.inc | 4 ++--
 target/riscv/translate.c| 8 ++--
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvi.c.inc 
b/target/riscv/insn_trans/trans_rvi.c.inc
index 4496f21266..ef7c3002b0 100644
--- a/target/riscv/insn_trans/trans_rvi.c.inc
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
@@ -56,7 +56,7 @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
 tcg_gen_andi_tl(cpu_pc, cpu_pc, (target_ulong)-2);
 
 gen_set_pc(ctx, cpu_pc);
-if (!has_ext(ctx, RVC)) {
+if (!ctx->cfg_ptr->ext_zca) {
 TCGv t0 = tcg_temp_new();
 
 misaligned = gen_new_label();
@@ -178,7 +178,7 @@ static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond 
cond)
 
 gen_set_label(l); /* branch taken */
 
-if (!has_ext(ctx, RVC) && ((ctx->base.pc_next + a->imm) & 0x3)) {
+if (!ctx->cfg_ptr->ext_zca && ((ctx->base.pc_next + a->imm) & 0x3)) {
 /* misaligned */
 gen_exception_inst_addr_mis(ctx);
 } else {
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 2ab8772ebe..ee24b451e3 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -557,7 +557,7 @@ static void gen_jal(DisasContext *ctx, int rd, target_ulong 
imm)
 
 /* check misaligned: */
 next_pc = ctx->base.pc_next + imm;
-if (!has_ext(ctx, RVC)) {
+if (!ctx->cfg_ptr->ext_zca) {
 if ((next_pc & 0x3) != 0) {
 gen_exception_inst_addr_mis(ctx);
 return;
@@ -1097,7 +1097,11 @@ static void decode_opc(CPURISCVState *env, DisasContext 
*ctx, uint16_t opcode)
 ctx->virt_inst_excp = false;
 /* Check for compressed insn */
 if (insn_len(opcode) == 2) {
-if (!has_ext(ctx, RVC)) {
+/*
+ * Zca support all of the existing C extension, excluding all
+ * compressed floating point loads and stores
+ */
+if (!ctx->cfg_ptr->ext_zca) {
 gen_exception_illegal(ctx);
 } else {
 ctx->opcode = opcode;
-- 
2.25.1




[PATCH v6 3/9] target/riscv: add support for Zcf extension

2022-11-28 Thread Weiwei Li
Separate c_flw/c_fsw from flw/fsw to add check for Zcf extension

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/insn16.decode  |  8 
 target/riscv/insn_trans/trans_rvf.c.inc | 18 ++
 2 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/target/riscv/insn16.decode b/target/riscv/insn16.decode
index ccfe59f294..f3ea650325 100644
--- a/target/riscv/insn16.decode
+++ b/target/riscv/insn16.decode
@@ -109,11 +109,11 @@ sw110  ... ... .. ... 00 @cs_w
 # *** RV32C and RV64C specific Standard Extension (Quadrant 0) ***
 {
   ld  011  ... ... .. ... 00 @cl_d
-  flw 011  ... ... .. ... 00 @cl_w
+  c_flw   011  ... ... .. ... 00 @cl_w
 }
 {
   sd  111  ... ... .. ... 00 @cs_d
-  fsw 111  ... ... .. ... 00 @cs_w
+  c_fsw   111  ... ... .. ... 00 @cs_w
 }
 
 # *** RV32/64C Standard Extension (Quadrant 1) ***
@@ -174,9 +174,9 @@ sw110 .  .  . 10 @c_swsp
 {
   c64_illegal 011 -  0  - 10 # c.ldsp, RES rd=0
   ld  011 .  .  . 10 @c_ldsp
-  flw 011 .  .  . 10 @c_lwsp
+  c_flw   011 .  .  . 10 @c_lwsp
 }
 {
   sd  111 .  .  . 10 @c_sdsp
-  fsw 111 .  .  . 10 @c_swsp
+  c_fsw   111 .  .  . 10 @c_swsp
 }
diff --git a/target/riscv/insn_trans/trans_rvf.c.inc 
b/target/riscv/insn_trans/trans_rvf.c.inc
index 965e1f8d11..5df9c148dc 100644
--- a/target/riscv/insn_trans/trans_rvf.c.inc
+++ b/target/riscv/insn_trans/trans_rvf.c.inc
@@ -30,6 +30,12 @@
 } \
 } while (0)
 
+#define REQUIRE_ZCF(ctx) do {  \
+if (!ctx->cfg_ptr->ext_zcf) {  \
+return false;  \
+}  \
+} while (0)
+
 static bool trans_flw(DisasContext *ctx, arg_flw *a)
 {
 TCGv_i64 dest;
@@ -61,6 +67,18 @@ static bool trans_fsw(DisasContext *ctx, arg_fsw *a)
 return true;
 }
 
+static bool trans_c_flw(DisasContext *ctx, arg_flw *a)
+{
+REQUIRE_ZCF(ctx);
+return trans_flw(ctx, a);
+}
+
+static bool trans_c_fsw(DisasContext *ctx, arg_fsw *a)
+{
+REQUIRE_ZCF(ctx);
+return trans_fsw(ctx, a);
+}
+
 static bool trans_fmadd_s(DisasContext *ctx, arg_fmadd_s *a)
 {
 REQUIRE_FPU;
-- 
2.25.1




[PATCH v6 6/9] target/riscv: add support for Zcmp extension

2022-11-28 Thread Weiwei Li
Add encode, trans* functions for Zcmp instructions

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/insn16.decode|  18 +++
 target/riscv/insn_trans/trans_rvzce.c.inc | 189 +-
 target/riscv/translate.c  |   5 +
 3 files changed, 211 insertions(+), 1 deletion(-)

diff --git a/target/riscv/insn16.decode b/target/riscv/insn16.decode
index 47603ec1e0..4654c23052 100644
--- a/target/riscv/insn16.decode
+++ b/target/riscv/insn16.decode
@@ -21,6 +21,8 @@
 %rs1_3 7:3!function=ex_rvc_register
 %rs2_3 2:3!function=ex_rvc_register
 %rs2_5 2:5
+%sreg1 7:3!function=ex_sreg_register
+%sreg2 2:3!function=ex_sreg_register
 
 # Immediates:
 %imm_ci12:s1 2:5
@@ -45,6 +47,8 @@
 
 %zcb_b_uimm  5:1 6:1
 %zcb_h_uimm  5:1 !function=ex_shift_1
+%zcmp_spimm  2:2 !function=ex_shift_4
+%zcmp_rlist  4:4
 
 # Argument sets imported from insn32.decode:
 &empty  !extern
@@ -56,7 +60,9 @@
 &u imm rd   !extern
 &shift shamt rs1 rd !extern
 &r2rd rs1   !extern
+&r2_s  rs1 rs2  !extern
 
+&zcmp  zcmp_rlist zcmp_spimm
 
 # Formats 16:
 @cr  . .  .. &r  rs2=%rs2_5   rs1=%rd %rd
@@ -98,6 +104,8 @@
 @zcb_lh   ... . .. ... .. ... ..  &i  imm=%zcb_h_uimm  rs1=%rs1_3 rd=%rs2_3
 @zcb_sb   ... . .. ... .. ... ..  &s  imm=%zcb_b_uimm  rs1=%rs1_3 
rs2=%rs2_3
 @zcb_sh   ... . .. ... .. ... ..  &s  imm=%zcb_h_uimm  rs1=%rs1_3 
rs2=%rs2_3
+@zcmp ... ...     ..  &zcmp  %zcmp_rlist   %zcmp_spimm
+@cm_mv... ...  ... .. ... ..  &r2_s  rs2=%sreg2rs1=%sreg1
 
 # *** RV32/64C Standard Extension (Quadrant 0) ***
 {
@@ -177,6 +185,16 @@ slli  000 .  .  . 10 @c_shift2
 {
   sq  101  ... ... .. ... 10 @c_sqsp
   c_fsd   101   ..  . 10 @c_sdsp
+
+  # *** RV64 and RV32 Zcmp Extension ***
+  [
+cm_push 101  11000   .. 10 @zcmp
+cm_pop  101  11010   .. 10 @zcmp
+cm_popret   101  0   .. 10 @zcmp
+cm_popretz  101  11100   .. 10 @zcmp
+cm_mva01s   101  011 ... 11 ... 10 @cm_mv
+cm_mvsa01   101  011 ... 01 ... 10 @cm_mv
+  ]
 }
 sw110 .  .  . 10 @c_swsp
 
diff --git a/target/riscv/insn_trans/trans_rvzce.c.inc 
b/target/riscv/insn_trans/trans_rvzce.c.inc
index de96c4afaf..f647b6ed15 100644
--- a/target/riscv/insn_trans/trans_rvzce.c.inc
+++ b/target/riscv/insn_trans/trans_rvzce.c.inc
@@ -1,5 +1,5 @@
 /*
- * RISC-V translation routines for the Zcb Standard Extension.
+ * RISC-V translation routines for the Zc[b,mp] Standard Extension.
  *
  * Copyright (c) 2021-2022 PLCT Lab
  *
@@ -21,6 +21,11 @@
 return false;   \
 } while (0)
 
+#define REQUIRE_ZCMP(ctx) do {   \
+if (!ctx->cfg_ptr->ext_zcmp) \
+return false;\
+} while (0)
+
 static bool trans_c_zext_b(DisasContext *ctx, arg_c_zext_b *a)
 {
 REQUIRE_ZCB(ctx);
@@ -98,3 +103,185 @@ static bool trans_c_sh(DisasContext *ctx, arg_c_sh *a)
 REQUIRE_ZCB(ctx);
 return gen_store(ctx, a, MO_UW);
 }
+
+#define X_S08
+#define X_S19
+#define X_Sn16
+
+static uint32_t decode_push_pop_list(DisasContext *ctx, target_ulong rlist)
+{
+uint32_t reg_bitmap = 0;
+
+if (ctx->cfg_ptr->ext_e && rlist > 6) {
+return 0;
+}
+
+switch (rlist) {
+case 15:
+reg_bitmap |=  1 << (X_Sn + 11) ;
+reg_bitmap |=  1 << (X_Sn + 10) ;
+/* FALL THROUGH */
+case 14:
+reg_bitmap |=  1 << (X_Sn + 9) ;
+/* FALL THROUGH */
+case 13:
+reg_bitmap |=  1 << (X_Sn + 8) ;
+/* FALL THROUGH */
+case 12:
+reg_bitmap |=  1 << (X_Sn + 7) ;
+/* FALL THROUGH */
+case 11:
+reg_bitmap |=  1 << (X_Sn + 6) ;
+/* FALL THROUGH */
+case 10:
+reg_bitmap |=  1 << (X_Sn + 5) ;
+/* FALL THROUGH */
+case 9:
+reg_bitmap |=  1 << (X_Sn + 4) ;
+/* FALL THROUGH */
+case 8:
+reg_bitmap |=  1 << (X_Sn + 3) ;
+/* FALL THROUGH */
+case 7:
+reg_bitmap |=  1 << (X_Sn + 2) ;
+/* FALL THROUGH */
+case 6:
+reg_bitmap |=  1 << X_S1 ;
+/* FALL THROUGH */
+case 5:
+reg_bitmap |= 1 << X_S0;
+/* FALL THROUGH */
+case 4:
+reg_bitmap |= 1 << xRA;
+break;
+default:
+break;
+}
+
+return reg_bitmap;
+}
+
+static bool gen_pop(DisasContext *ctx, arg_zcmp *a, bool ret, bool ret_val)
+{
+REQUIRE_ZCMP(ctx);
+
+uint32_t reg_bitmap = decode_push_pop_list(ctx, a->zc

[PATCH v6 0/9] support subsets of code size reduction extension

2022-11-28 Thread Weiwei Li
This patchset implements RISC-V Zc* extension v1.0.0.RC5.7 version instructions.

Specification:
https://github.com/riscv/riscv-code-size-reduction/tree/main/Zc-specification

The port is available here:
https://github.com/plctlab/plct-qemu/tree/plct-zce-upstream-v6

To test Zc* implementation, specify cpu argument with 
'x-zca=true,x-zcb=true,x-zcf=true,f=true" and "x-zcd=true,d=true" (or 
"x-zcmp=true,x-zcmt=true" with c or d=false) to enable Zca/Zcb/Zcf and Zcd(or 
Zcmp,Zcmt) extension support.


This implementation can pass the basic zc tests from 
https://github.com/yulong-plct/zc-test

v6:
* fix base address for jump table in Patch 7
* rebase on riscv-to-apply.next

v5:
* fix exception unwind problem for cpu_ld*_code in helper of cm_jalt

v4:
* improve Zcmp suggested by Richard
* fix stateen related check for Zcmt

v3:
* update the solution for Zcf to the way of Zcd
* update Zcb to reuse gen_load/store
* use trans function instead of helper for push/pop

v2:
* add check for relationship between Zca/Zcf/Zcd with C/F/D based on related 
discussion in review of Zc* spec
* separate c.fld{sp}/fsd{sp} with fld{sp}/fsd{sp} before support of zcmp/zcmt

Weiwei Li (9):
  target/riscv: add cfg properties for Zc* extension
  target/riscv: add support for Zca extension
  target/riscv: add support for Zcf extension
  target/riscv: add support for Zcd extension
  target/riscv: add support for Zcb extension
  target/riscv: add support for Zcmp extension
  target/riscv: add support for Zcmt extension
  target/riscv: expose properties for Zc* extension
  disas/riscv.c: add disasm support for Zc*

 disas/riscv.c | 287 +++-
 target/riscv/cpu.c|  56 
 target/riscv/cpu.h|  10 +
 target/riscv/cpu_bits.h   |   7 +
 target/riscv/csr.c|  38 ++-
 target/riscv/helper.h |   3 +
 target/riscv/insn16.decode|  63 -
 target/riscv/insn_trans/trans_rvd.c.inc   |  18 ++
 target/riscv/insn_trans/trans_rvf.c.inc   |  18 ++
 target/riscv/insn_trans/trans_rvi.c.inc   |   4 +-
 target/riscv/insn_trans/trans_rvzce.c.inc | 313 ++
 target/riscv/machine.c|  19 ++
 target/riscv/meson.build  |   3 +-
 target/riscv/translate.c  |  15 +-
 target/riscv/zce_helper.c |  55 
 15 files changed, 893 insertions(+), 16 deletions(-)
 create mode 100644 target/riscv/insn_trans/trans_rvzce.c.inc
 create mode 100644 target/riscv/zce_helper.c

-- 
2.25.1




[PATCH v6 1/9] target/riscv: add cfg properties for Zc* extension

2022-11-28 Thread Weiwei Li
Add properties for Zca,Zcb,Zcf,Zcd,Zcmp,Zcmt extension
Add check for these properties

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu.c | 43 +++
 target/riscv/cpu.h |  6 ++
 2 files changed, 49 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index c705331bbe..9f4aa0fe55 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -808,6 +808,49 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 }
 }
 
+if (cpu->cfg.ext_c) {
+cpu->cfg.ext_zca = true;
+if (cpu->cfg.ext_f && env->misa_mxl_max == MXL_RV32) {
+cpu->cfg.ext_zcf = true;
+}
+if (cpu->cfg.ext_d) {
+cpu->cfg.ext_zcd = true;
+}
+}
+
+if (env->misa_mxl_max != MXL_RV32 && cpu->cfg.ext_zcf) {
+error_setg(errp, "Zcf extension is only relevant to RV32");
+return;
+}
+
+if (!cpu->cfg.ext_f && cpu->cfg.ext_zcf) {
+error_setg(errp, "Zcf extension requires F extension");
+return;
+}
+
+if (!cpu->cfg.ext_d && cpu->cfg.ext_zcd) {
+error_setg(errp, "Zcd extensionrequires D extension");
+return;
+}
+
+if ((cpu->cfg.ext_zcf || cpu->cfg.ext_zcd || cpu->cfg.ext_zcb ||
+ cpu->cfg.ext_zcmp || cpu->cfg.ext_zcmt) && !cpu->cfg.ext_zca) {
+error_setg(errp, "Zcf/Zcd/Zcb/Zcmp/Zcmt extensions require Zca "
+ "extension");
+return;
+}
+
+if (cpu->cfg.ext_zcd && (cpu->cfg.ext_zcmp || cpu->cfg.ext_zcmt)) {
+error_setg(errp, "Zcmp/Zcmt extensions are incompatible with "
+ "Zcd extension");
+return;
+}
+
+if (cpu->cfg.ext_zcmt && !cpu->cfg.ext_icsr) {
+error_setg(errp, "Zcmt extension requires Zicsr extension");
+return;
+}
+
 if (cpu->cfg.ext_zk) {
 cpu->cfg.ext_zkn = true;
 cpu->cfg.ext_zkr = true;
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 9bd539d77a..6e915b6937 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -434,6 +434,12 @@ struct RISCVCPUConfig {
 bool ext_zbkc;
 bool ext_zbkx;
 bool ext_zbs;
+bool ext_zca;
+bool ext_zcb;
+bool ext_zcd;
+bool ext_zcf;
+bool ext_zcmp;
+bool ext_zcmt;
 bool ext_zk;
 bool ext_zkn;
 bool ext_zknd;
-- 
2.25.1




[PATCH v6 9/9] disas/riscv.c: add disasm support for Zc*

2022-11-28 Thread Weiwei Li
Zcmp/Zcmt instructions will override disasm for c.fld*/c.fsd*
instructions currently

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Acked-by: Alistair Francis 
---
 disas/riscv.c | 287 +-
 1 file changed, 286 insertions(+), 1 deletion(-)

diff --git a/disas/riscv.c b/disas/riscv.c
index d216b9c39b..81369063b5 100644
--- a/disas/riscv.c
+++ b/disas/riscv.c
@@ -163,6 +163,13 @@ typedef enum {
 rv_codec_v_i,
 rv_codec_vsetvli,
 rv_codec_vsetivli,
+rv_codec_zcb_ext,
+rv_codec_zcb_mul,
+rv_codec_zcb_lb,
+rv_codec_zcb_lh,
+rv_codec_zcmp_cm_pushpop,
+rv_codec_zcmp_cm_mv,
+rv_codec_zcmt_jt,
 } rv_codec;
 
 typedef enum {
@@ -935,6 +942,26 @@ typedef enum {
 rv_op_vsetvli = 766,
 rv_op_vsetivli = 767,
 rv_op_vsetvl = 768,
+rv_op_c_zext_b = 769,
+rv_op_c_sext_b = 770,
+rv_op_c_zext_h = 771,
+rv_op_c_sext_h = 772,
+rv_op_c_zext_w = 773,
+rv_op_c_not = 774,
+rv_op_c_mul = 775,
+rv_op_c_lbu = 776,
+rv_op_c_lhu = 777,
+rv_op_c_lh = 778,
+rv_op_c_sb = 779,
+rv_op_c_sh = 780,
+rv_op_cm_push = 781,
+rv_op_cm_pop = 782,
+rv_op_cm_popret = 783,
+rv_op_cm_popretz = 784,
+rv_op_cm_mva01s = 785,
+rv_op_cm_mvsa01 = 786,
+rv_op_cm_jt = 787,
+rv_op_cm_jalt = 788,
 } rv_op;
 
 /* structures */
@@ -958,6 +985,7 @@ typedef struct {
 uint8_t   rnum;
 uint8_t   vm;
 uint32_t  vzimm;
+uint8_t   rlist;
 } rv_decode;
 
 typedef struct {
@@ -1070,6 +1098,10 @@ static const char rv_vreg_name_sym[32][4] = {
 #define rv_fmt_vd_vm  "O\tDm"
 #define rv_fmt_vsetvli"O\t0,1,v"
 #define rv_fmt_vsetivli   "O\t0,u,v"
+#define rv_fmt_rs1_rs2_zce_ldst   "O\t2,i(1)"
+#define rv_fmt_push_rlist "O\tx,-i"
+#define rv_fmt_pop_rlist  "O\tx,i"
+#define rv_fmt_zcmt_index "O\ti"
 
 /* pseudo-instruction constraints */
 
@@ -2065,7 +2097,27 @@ const rv_opcode_data opcode_data[] = {
 { "vsext.vf8", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vsext_vf8, 
rv_op_vsext_vf8, 0 },
 { "vsetvli", rv_codec_vsetvli, rv_fmt_vsetvli, NULL, rv_op_vsetvli, 
rv_op_vsetvli, 0 },
 { "vsetivli", rv_codec_vsetivli, rv_fmt_vsetivli, NULL, rv_op_vsetivli, 
rv_op_vsetivli, 0 },
-{ "vsetvl", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, rv_op_vsetvl, 
rv_op_vsetvl, 0 }
+{ "vsetvl", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, rv_op_vsetvl, 
rv_op_vsetvl, 0 },
+{ "c.zext.b", rv_codec_zcb_ext, rv_fmt_rd, NULL, 0 },
+{ "c.sext.b", rv_codec_zcb_ext, rv_fmt_rd, NULL, 0 },
+{ "c.zext.h", rv_codec_zcb_ext, rv_fmt_rd, NULL, 0 },
+{ "c.sext.h", rv_codec_zcb_ext, rv_fmt_rd, NULL, 0 },
+{ "c.zext.w", rv_codec_zcb_ext, rv_fmt_rd, NULL, 0 },
+{ "c.not", rv_codec_zcb_ext, rv_fmt_rd, NULL, 0 },
+{ "c.mul", rv_codec_zcb_mul, rv_fmt_rd_rs2, NULL, 0, 0 },
+{ "c.lbu", rv_codec_zcb_lb, rv_fmt_rs1_rs2_zce_ldst, NULL, 0, 0, 0 },
+{ "c.lhu", rv_codec_zcb_lh, rv_fmt_rs1_rs2_zce_ldst, NULL, 0, 0, 0 },
+{ "c.lh", rv_codec_zcb_lh, rv_fmt_rs1_rs2_zce_ldst, NULL, 0, 0, 0 },
+{ "c.sb", rv_codec_zcb_lb, rv_fmt_rs1_rs2_zce_ldst, NULL, 0, 0, 0 },
+{ "c.sh", rv_codec_zcb_lh, rv_fmt_rs1_rs2_zce_ldst, NULL, 0, 0, 0 },
+{ "cm.push", rv_codec_zcmp_cm_pushpop, rv_fmt_push_rlist, NULL, 0, 0 },
+{ "cm.pop", rv_codec_zcmp_cm_pushpop, rv_fmt_pop_rlist, NULL, 0, 0 },
+{ "cm.popret", rv_codec_zcmp_cm_pushpop, rv_fmt_pop_rlist, NULL, 0, 0, 0 },
+{ "cm.popretz", rv_codec_zcmp_cm_pushpop, rv_fmt_pop_rlist, NULL, 0, 0 },
+{ "cm.mva01s", rv_codec_zcmp_cm_mv, rv_fmt_rd_rs2, NULL, 0, 0, 0 },
+{ "cm.mvsa01", rv_codec_zcmp_cm_mv, rv_fmt_rd_rs2, NULL, 0, 0, 0 },
+{ "cm.jt", rv_codec_zcmt_jt, rv_fmt_zcmt_index, NULL, 0 },
+{ "cm.jalt", rv_codec_zcmt_jt, rv_fmt_zcmt_index, NULL, 0 },
 };
 
 /* CSR names */
@@ -2084,6 +2136,7 @@ static const char *csr_name(int csrno)
 case 0x000a: return "vxrm";
 case 0x000f: return "vcsr";
 case 0x0015: return "seed";
+case 0x0017: return "jvt";
 case 0x0040: return "uscratch";
 case 0x0041: return "uepc";
 case 0x0042: return "ucause";
@@ -2306,6 +2359,24 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa 
isa)
 op = rv_op_c_ld;
 }
 break;
+case 4:
+switch ((inst >> 10) & 0b111) {
+case 0: op = rv_op_c_lbu; break;
+case 1:
+if (((inst >> 6) & 1) == 0) {
+op = rv_op_c_lhu;
+   

[PATCH v6 7/9] target/riscv: add support for Zcmt extension

2022-11-28 Thread Weiwei Li
Add encode, trans* functions and helper functions support for Zcmt
instrutions
Add support for jvt csr

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu.h|  4 ++
 target/riscv/cpu_bits.h   |  7 +++
 target/riscv/csr.c| 38 +++-
 target/riscv/helper.h |  3 ++
 target/riscv/insn16.decode|  7 ++-
 target/riscv/insn_trans/trans_rvzce.c.inc | 28 +++-
 target/riscv/machine.c| 19 
 target/riscv/meson.build  |  3 +-
 target/riscv/zce_helper.c | 55 +++
 9 files changed, 159 insertions(+), 5 deletions(-)
 create mode 100644 target/riscv/zce_helper.c

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 6e915b6937..7bcedc7467 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -181,6 +181,8 @@ struct CPUArchState {
 
 uint32_t features;
 
+target_ulong jvt;
+
 #ifdef CONFIG_USER_ONLY
 uint32_t elf_flags;
 #endif
@@ -600,6 +602,8 @@ void riscv_cpu_set_aia_ireg_rmw_fn(CPURISCVState *env, 
uint32_t priv,
  target_ulong new_val,
  target_ulong write_mask),
void *rmw_fn_arg);
+
+RISCVException smstateen_acc_ok(CPURISCVState *env, int index, uint64_t bit);
 #endif
 void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv);
 
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 8b0d7e20ea..ce347e5575 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -319,6 +319,7 @@
 #define SMSTATEEN_MAX_COUNT 4
 #define SMSTATEEN0_CS   (1ULL << 0)
 #define SMSTATEEN0_FCSR (1ULL << 1)
+#define SMSTATEEN0_JVT  (1ULL << 2)
 #define SMSTATEEN0_HSCONTXT (1ULL << 57)
 #define SMSTATEEN0_IMSIC(1ULL << 58)
 #define SMSTATEEN0_AIA  (1ULL << 59)
@@ -523,6 +524,9 @@
 /* Crypto Extension */
 #define CSR_SEED0x015
 
+/* Zcmt Extension */
+#define CSR_JVT 0x017
+
 /* mstatus CSR bits */
 #define MSTATUS_UIE 0x0001
 #define MSTATUS_SIE 0x0002
@@ -894,4 +898,7 @@ typedef enum RISCVException {
 #define MHPMEVENT_IDX_MASK 0xF
 #define MHPMEVENT_SSCOF_RESVD  16
 
+/* JVT CSR bits */
+#define JVT_MODE   0x3F
+#define JVT_BASE   (~0x3F)
 #endif
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index e6f8250929..a752e8b215 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -42,8 +42,7 @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops)
 
 /* Predicates */
 #if !defined(CONFIG_USER_ONLY)
-static RISCVException smstateen_acc_ok(CPURISCVState *env, int index,
-   uint64_t bit)
+RISCVException smstateen_acc_ok(CPURISCVState *env, int index, uint64_t bit)
 {
 bool virt = riscv_cpu_virt_enabled(env);
 CPUState *cs = env_cpu(env);
@@ -163,6 +162,24 @@ static RISCVException ctr32(CPURISCVState *env, int csrno)
 return ctr(env, csrno);
 }
 
+static RISCVException zcmt(CPURISCVState *env, int csrno)
+{
+RISCVCPU *cpu = env_archcpu(env);
+
+if (!cpu->cfg.ext_zcmt) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
+#if !defined(CONFIG_USER_ONLY)
+RISCVException ret = smstateen_acc_ok(env, 0, SMSTATEEN0_JVT);
+if (ret != RISCV_EXCP_NONE) {
+return ret;
+}
+#endif
+
+return RISCV_EXCP_NONE;
+}
+
 #if !defined(CONFIG_USER_ONLY)
 static RISCVException mctr(CPURISCVState *env, int csrno)
 {
@@ -3980,6 +3997,20 @@ RISCVException riscv_csrrw_debug(CPURISCVState *env, int 
csrno,
 return ret;
 }
 
+static RISCVException read_jvt(CPURISCVState *env, int csrno,
+   target_ulong *val)
+{
+*val = env->jvt;
+return RISCV_EXCP_NONE;
+}
+
+static RISCVException write_jvt(CPURISCVState *env, int csrno,
+target_ulong val)
+{
+env->jvt = val;
+return RISCV_EXCP_NONE;
+}
+
 /* Control and Status Register function table */
 riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
 /* User Floating-Point CSRs */
@@ -4017,6 +4048,9 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
 /* Crypto Extension */
 [CSR_SEED] = { "seed", seed, NULL, NULL, rmw_seed },
 
+/* Zcmt Extension */
+[CSR_JVT] = {"jvt", zcmt, read_jvt, write_jvt},
+
 #if !defined(CONFIG_USER_ONLY)
 /* Machine Timers and Counters */
 [CSR_MCYCLE]= { "mcycle",any,   read_hpmcounter,
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 227c7122ef..d979f0bfc4 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1136,3 +1136,6 @@ DEF_HELPER_FLAGS_1(aes64im, TCG_CALL_NO_RWG_

  1   2   3   4   5   6   7   8   9   10   >