All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/9] support subsets of code size reduction extension
@ 2022-11-17  7:03 Weiwei Li
  2022-11-17  7:03 ` [PATCH v3 1/9] target/riscv: add cfg properties for Zc* extension Weiwei Li
                   ` (8 more replies)
  0 siblings, 9 replies; 22+ messages in thread
From: Weiwei Li @ 2022-11-17  7:03 UTC (permalink / raw)
  To: richard.henderson, palmer, alistair.francis, bin.meng,
	qemu-riscv, qemu-devel
  Cc: wangjunqiang, lazyparser, 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



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

* [PATCH v3 1/9] target/riscv: add cfg properties for Zc* extension
  2022-11-17  7:03 [PATCH v3 0/9] support subsets of code size reduction extension Weiwei Li
@ 2022-11-17  7:03 ` Weiwei Li
  2022-11-17  8:54   ` Richard Henderson
  2022-11-17  7:03 ` [PATCH v3 2/9] target/riscv: add support for Zca extension Weiwei Li
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 22+ messages in thread
From: Weiwei Li @ 2022-11-17  7:03 UTC (permalink / raw)
  To: richard.henderson, palmer, alistair.francis, bin.meng,
	qemu-riscv, qemu-devel
  Cc: wangjunqiang, lazyparser, Weiwei Li

Add properties for Zca,Zcb,Zcf,Zcd,Zcmp,Zcmt extension
Add check for these properties

Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
Cc: Alistair Francis <alistair.francis@wdc.com>
---
 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



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

* [PATCH v3 2/9] target/riscv: add support for Zca extension
  2022-11-17  7:03 [PATCH v3 0/9] support subsets of code size reduction extension Weiwei Li
  2022-11-17  7:03 ` [PATCH v3 1/9] target/riscv: add cfg properties for Zc* extension Weiwei Li
@ 2022-11-17  7:03 ` Weiwei Li
  2022-11-17  8:56   ` Richard Henderson
  2022-11-17  7:03 ` [PATCH v3 3/9] target/riscv: add support for Zcf extension Weiwei Li
                   ` (6 subsequent siblings)
  8 siblings, 1 reply; 22+ messages in thread
From: Weiwei Li @ 2022-11-17  7:03 UTC (permalink / raw)
  To: richard.henderson, palmer, alistair.francis, bin.meng,
	qemu-riscv, qemu-devel
  Cc: wangjunqiang, lazyparser, Weiwei Li

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

Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
---
 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



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

* [PATCH v3 3/9] target/riscv: add support for Zcf extension
  2022-11-17  7:03 [PATCH v3 0/9] support subsets of code size reduction extension Weiwei Li
  2022-11-17  7:03 ` [PATCH v3 1/9] target/riscv: add cfg properties for Zc* extension Weiwei Li
  2022-11-17  7:03 ` [PATCH v3 2/9] target/riscv: add support for Zca extension Weiwei Li
@ 2022-11-17  7:03 ` Weiwei Li
  2022-11-17  8:58   ` Richard Henderson
  2022-11-17  7:03 ` [PATCH v3 4/9] target/riscv: add support for Zcd extension Weiwei Li
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 22+ messages in thread
From: Weiwei Li @ 2022-11-17  7:03 UTC (permalink / raw)
  To: richard.henderson, palmer, alistair.francis, bin.meng,
	qemu-riscv, qemu-devel
  Cc: wangjunqiang, lazyparser, Weiwei Li

Separate c_flw/c_fsw from flw/fsw to add check for Zcf extension

Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
---
 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 @@ sw                110  ... ... .. ... 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 @@ sw                110 .  .....  ..... 10 @c_swsp
 {
   c64_illegal     011 -  00000  ----- 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



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

* [PATCH v3 4/9] target/riscv: add support for Zcd extension
  2022-11-17  7:03 [PATCH v3 0/9] support subsets of code size reduction extension Weiwei Li
                   ` (2 preceding siblings ...)
  2022-11-17  7:03 ` [PATCH v3 3/9] target/riscv: add support for Zcf extension Weiwei Li
@ 2022-11-17  7:03 ` Weiwei Li
  2022-11-17  7:03 ` [PATCH v3 5/9] target/riscv: add support for Zcb extension Weiwei Li
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 22+ messages in thread
From: Weiwei Li @ 2022-11-17  7:03 UTC (permalink / raw)
  To: richard.henderson, palmer, alistair.francis, bin.meng,
	qemu-riscv, qemu-devel
  Cc: wangjunqiang, lazyparser, 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 <liweiwei@iscas.ac.cn>
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 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
 }
 lw                010  ... ... .. ... 00 @cl_w
 {
   sq              101  ... ... .. ... 00 @cs_q
-  fsd             101  ... ... .. ... 00 @cs_d
+  c_fsd           101  ... ... .. ... 00 @cs_d
 }
 sw                110  ... ... .. ... 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 -  00000  ----- 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
 }
 sw                110 .  .....  ..... 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



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

* [PATCH v3 5/9] target/riscv: add support for Zcb extension
  2022-11-17  7:03 [PATCH v3 0/9] support subsets of code size reduction extension Weiwei Li
                   ` (3 preceding siblings ...)
  2022-11-17  7:03 ` [PATCH v3 4/9] target/riscv: add support for Zcd extension Weiwei Li
@ 2022-11-17  7:03 ` Weiwei Li
  2022-11-17  9:10   ` Richard Henderson
  2022-11-17  7:03 ` [PATCH v3 6/9] target/riscv: add support for Zcmp extension Weiwei Li
                   ` (3 subsequent siblings)
  8 siblings, 1 reply; 22+ messages in thread
From: Weiwei Li @ 2022-11-17  7:03 UTC (permalink / raw)
  To: richard.henderson, palmer, alistair.francis, bin.meng,
	qemu-riscv, qemu-devel
  Cc: wangjunqiang, lazyparser, Weiwei Li

Add encode and trans* functions support for Zcb instructions

Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
---
 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
+&r2        rd 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 @@ sw                110 .  .....  ..... 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 0000000000..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, arg_c_lbu *a)
+{
+    REQUIRE_ZCB(ctx);
+    return gen_load(ctx, a, MO_UB);
+}
+
+static bool trans_c_lhu(DisasContext *ctx, arg_c_lhu *a)
+{
+    REQUIRE_ZCB(ctx);
+    return gen_load(ctx, a, MO_UW);
+}
+
+static bool trans_c_lh(DisasContext *ctx, arg_c_lh *a)
+{
+    REQUIRE_ZCB(ctx);
+    return gen_load(ctx, a, MO_SW);
+}
+
+static bool trans_c_sb(DisasContext *ctx, arg_c_sb *a)
+{
+    REQUIRE_ZCB(ctx);
+    return gen_store(ctx, a, MO_UB);
+}
+
+static bool trans_c_sh(DisasContext *ctx, arg_c_sh *a)
+{
+    REQUIRE_ZCB(ctx);
+    return gen_store(ctx, a, MO_UW);
+}
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index ee24b451e3..ca01da3309 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1069,6 +1069,8 @@ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)
 
 /* Include the auto-generated decoder for 16 bit insn */
 #include "decode-insn16.c.inc"
+#include "insn_trans/trans_rvzce.c.inc"
+
 /* Include decoders for factored-out extensions */
 #include "decode-XVentanaCondOps.c.inc"
 
-- 
2.25.1



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

* [PATCH v3 6/9] target/riscv: add support for Zcmp extension
  2022-11-17  7:03 [PATCH v3 0/9] support subsets of code size reduction extension Weiwei Li
                   ` (4 preceding siblings ...)
  2022-11-17  7:03 ` [PATCH v3 5/9] target/riscv: add support for Zcb extension Weiwei Li
@ 2022-11-17  7:03 ` Weiwei Li
  2022-11-17  9:44   ` Richard Henderson
  2022-11-17  7:03 ` [PATCH v3 7/9] target/riscv: add support for Zcmt extension Weiwei Li
                   ` (2 subsequent siblings)
  8 siblings, 1 reply; 22+ messages in thread
From: Weiwei Li @ 2022-11-17  7:03 UTC (permalink / raw)
  To: richard.henderson, palmer, alistair.francis, bin.meng,
	qemu-riscv, qemu-devel
  Cc: wangjunqiang, lazyparser, Weiwei Li

Add encode, trans* functions for Zcmp instructions

Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
---
 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_ci        12: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
 &r2        rd 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=%sreg2    rs1=%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  11110  .... .. 10 @zcmp
+    cm_popretz      101  11100  .... .. 10 @zcmp
+    cm_mva01s       101  011 ... 11 ... 10 @cm_mv
+    cm_mvsa01       101  011 ... 01 ... 10 @cm_mv
+  ]
 }
 sw                110 .  .....  ..... 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_S0    8
+#define X_S1    9
+#define X_Sn    16
+
+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;
+    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;
+    }
+
+    return stack_adj_base + spimm;
+}
+
+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;
+    target_ulong stack_adj = caculate_stack_adj(bytes, a->zcmp_rlist,
+                                                a->zcmp_spimm);
+    TCGv sp = dest_gpr(ctx, xSP);
+    TCGv addr = tcg_temp_new();
+    int i;
+
+    update_push_pop_list(a->zcmp_rlist, xreg_list);
+    tcg_gen_addi_tl(addr, sp, stack_adj - bytes);
+
+    for (i = X_Sn + 11; i >= 0; i--) {
+        if (xreg_list[i]) {
+            TCGv dest = dest_gpr(ctx, i);
+            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;
+            }
+            gen_set_gpr(ctx, i, dest);
+            tcg_gen_subi_tl(addr, addr, bytes);
+        }
+    }
+
+    tcg_gen_addi_tl(sp, sp, stack_adj);
+    gen_set_gpr(ctx, xSP, sp);
+
+    if (ret_val) {
+        gen_set_gpr(ctx, xA0, ctx->zero);
+    }
+
+    if (ret) {
+        TCGv ret_addr = get_gpr(ctx, xRA, EXT_NONE);
+        gen_set_pc(ctx, ret_addr);
+        tcg_gen_lookup_and_goto_ptr();
+        ctx->base.is_jmp = DISAS_NORETURN;
+    }
+
+    tcg_temp_free(addr);
+    return true;
+}
+
+static bool trans_cm_push(DisasContext *ctx, arg_cm_push *a)
+{
+    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;
+    target_ulong stack_adj = caculate_stack_adj(bytes, a->zcmp_rlist,
+                                                a->zcmp_spimm);
+    TCGv sp = dest_gpr(ctx, xSP);
+    TCGv addr = tcg_temp_new();
+    int i;
+
+    update_push_pop_list(a->zcmp_rlist, xreg_list);
+    tcg_gen_subi_tl(addr, sp, bytes);
+
+    for (i = X_Sn + 11; i >= 0; i--) {
+        if (xreg_list[i]) {
+            TCGv val = get_gpr(ctx, i, EXT_NONE);
+            switch (bytes) {
+            case 4:
+                tcg_gen_qemu_st_tl(val, addr, ctx->mem_idx, MO_32);
+                break;
+            case 8:
+                tcg_gen_qemu_st_tl(val, addr, ctx->mem_idx, MO_64);
+                break;
+            default:
+                break;
+            }
+            tcg_gen_subi_tl(addr, addr, bytes);
+        }
+    }
+
+    tcg_gen_subi_tl(sp, sp, stack_adj);
+    gen_set_gpr(ctx, xSP, sp);
+    return true;
+}
+
+static bool trans_cm_pop(DisasContext *ctx, arg_cm_pop *a)
+{
+    return gen_pop(ctx, a, false, false);
+}
+
+static bool trans_cm_popret(DisasContext *ctx, arg_cm_popret *a)
+{
+    return gen_pop(ctx, a, true, false);
+}
+
+static bool trans_cm_popretz(DisasContext *ctx, arg_cm_popret *a)
+{
+    return gen_pop(ctx, a, true, true);
+}
+
+static bool trans_cm_mva01s(DisasContext *ctx, arg_cm_mva01s *a)
+{
+    REQUIRE_ZCMP(ctx);
+
+    TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
+    TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE);
+
+    gen_set_gpr(ctx, xA0, src1);
+    gen_set_gpr(ctx, xA1, src2);
+
+    return true;
+}
+
+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);
+
+    return true;
+}
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index ca01da3309..1b2515650f 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -738,6 +738,11 @@ static int ex_rvc_register(DisasContext *ctx, int reg)
     return 8 + reg;
 }
 
+static int ex_sreg_register(DisasContext *ctx, int reg)
+{
+    return reg < 2 ? reg + 8 : reg + 16;
+}
+
 static int ex_rvc_shiftli(DisasContext *ctx, int imm)
 {
     /* For RV128 a shamt of 0 means a shift by 64. */
-- 
2.25.1



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

* [PATCH v3 7/9] target/riscv: add support for Zcmt extension
  2022-11-17  7:03 [PATCH v3 0/9] support subsets of code size reduction extension Weiwei Li
                   ` (5 preceding siblings ...)
  2022-11-17  7:03 ` [PATCH v3 6/9] target/riscv: add support for Zcmp extension Weiwei Li
@ 2022-11-17  7:03 ` Weiwei Li
  2022-11-17  9:56   ` Richard Henderson
  2022-11-17  7:03 ` [PATCH v3 8/9] target/riscv: expose properties for Zc* extension Weiwei Li
  2022-11-17  7:03 ` [PATCH v3 9/9] disas/riscv.c: add disasm support for Zc* Weiwei Li
  8 siblings, 1 reply; 22+ messages in thread
From: Weiwei Li @ 2022-11-17  7:03 UTC (permalink / raw)
  To: richard.henderson, palmer, alistair.francis, bin.meng,
	qemu-riscv, qemu-devel
  Cc: wangjunqiang, lazyparser, Weiwei Li

Add encode, trans* functions and helper functions support for Zcmt
instrutions
Add support for jvt csr

Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
---
 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_SEED            0x015
 
+/* Zcmt Extension */
+#define CSR_JVT             0x017
+
 /* mstatus CSR bits */
 #define MSTATUS_UIE         0x00000001
 #define MSTATUS_SIE         0x00000002
@@ -894,4 +898,7 @@ typedef enum RISCVException {
 #define MHPMEVENT_IDX_MASK                 0xFFFFF
 #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
@@ -106,6 +108,7 @@
 @zcb_sh       ... . .. ... .. ... ..  &s  imm=%zcb_h_uimm  rs1=%rs1_3 rs2=%rs2_3
 @zcmp         ... ...  ........   ..  &zcmp  %zcmp_rlist   %zcmp_spimm
 @cm_mv        ... ...  ... .. ... ..  &r2_s  rs2=%sreg2    rs1=%sreg1
+@zcmt_jt      ... ...  ........   ..  &zcmt  %zcmt_index
 
 # *** RV32/64C Standard Extension (Quadrant 0) ***
 {
@@ -186,7 +189,7 @@ slli              000 .  .....  ..... 10 @c_shift2
   sq              101  ... ... .. ... 10 @c_sqsp
   c_fsd           101   ......  ..... 10 @c_sdsp
 
-  # *** RV64 and RV32 Zcmp Extension ***
+  # *** RV64 and RV32 Zcmp/Zcmt Extension ***
   [
     cm_push         101  11000  .... .. 10 @zcmp
     cm_pop          101  11010  .... .. 10 @zcmp
@@ -194,6 +197,8 @@ slli              000 .  .....  ..... 10 @c_shift2
     cm_popretz      101  11100  .... .. 10 @zcmp
     cm_mva01s       101  011 ... 11 ... 10 @cm_mv
     cm_mvsa01       101  011 ... 01 ... 10 @cm_mv
+
+    cm_jalt         101  000   ........ 10 @zcmt_jt
   ]
 }
 sw                110 .  .....  ..... 10 @c_swsp
diff --git a/target/riscv/insn_trans/trans_rvf.c.inc b/target/riscv/insn_trans/trans_rvf.c.inc
index 426518957b..310fa80bf8 100644
--- a/target/riscv/insn_trans/trans_rvf.c.inc
+++ b/target/riscv/insn_trans/trans_rvf.c.inc
@@ -31,7 +31,7 @@
 } while (0)
 
 #ifndef CONFIG_USER_ONLY
-static inline bool smstateen_fcsr_check(DisasContext *ctx, int index)
+static inline bool smstateen_check(DisasContext *ctx, int index, uint64_t bit)
 {
     CPUState *cpu = ctx->cs;
     CPURISCVState *env = cpu->env_ptr;
@@ -49,7 +49,7 @@ static inline bool smstateen_fcsr_check(DisasContext *ctx, int index)
         stateen &= env->sstateen[index];
     }
 
-    if (!(stateen & SMSTATEEN0_FCSR)) {
+    if (!(stateen & bit)) {
         if (ctx->virt_enabled) {
             ctx->virt_inst_excp = true;
         }
@@ -59,7 +59,7 @@ static inline bool smstateen_fcsr_check(DisasContext *ctx, int index)
     return true;
 }
 #else
-#define smstateen_fcsr_check(ctx, index) (true)
+#define smstateen_check(ctx, index, bit) (true)
 #endif
 
 #define REQUIRE_ZFINX_OR_F(ctx) do { \
@@ -67,7 +67,7 @@ static inline bool smstateen_fcsr_check(DisasContext *ctx, int index)
         if (!ctx->cfg_ptr->ext_zfinx) { \
             return false; \
         } \
-        if (!smstateen_fcsr_check(ctx, 0)) { \
+        if (!smstateen_check(ctx, 0, SMSTATEEN0_FCSR)) { \
             return false; \
         } \
     } \
diff --git a/target/riscv/insn_trans/trans_rvzce.c.inc b/target/riscv/insn_trans/trans_rvzce.c.inc
index f45224e388..6b011c04a1 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 Zc[b,mp] Standard Extension.
+ * RISC-V translation routines for the Zc[b,mp,mt] Standard Extension.
  *
  * Copyright (c) 2021-2022 PLCT Lab
  *
@@ -26,6 +26,15 @@
         return false;            \
 } while (0)
 
+#define REQUIRE_ZCMT(ctx) do {                       \
+    if (!ctx->cfg_ptr->ext_zcmt) {                   \
+        return false;                                \
+    }                                                \
+    if (!smstateen_check(ctx, 0, SMSTATEEN0_JVT)) {  \
+        return false;                                \
+    }                                                \
+} while (0)
+
 static bool trans_c_zext_b(DisasContext *ctx, arg_c_zext_b *a)
 {
     REQUIRE_ZCB(ctx);
@@ -338,3 +347,21 @@ static bool trans_cm_mvsa01(DisasContext *ctx, arg_cm_mvsa01 *a)
 
     return true;
 }
+
+static bool trans_cm_jalt(DisasContext *ctx, arg_cm_jalt *a)
+{
+    REQUIRE_ZCMT(ctx);
+
+    TCGv index = tcg_const_tl(a->zcmt_index);
+    TCGv next_pc = tcg_const_tl(ctx->pc_succ_insn);
+
+    gen_helper_cm_jalt(cpu_pc, cpu_env, index, next_pc);
+
+    tcg_gen_lookup_and_goto_ptr();
+
+    ctx->base.is_jmp = DISAS_NORETURN;
+
+    tcg_temp_free(index);
+    tcg_temp_free(next_pc);
+    return true;
+}
diff --git a/target/riscv/insn_trans/trans_rvzfh.c.inc b/target/riscv/insn_trans/trans_rvzfh.c.inc
index 6c2e338c0a..a1c513bc8c 100644
--- a/target/riscv/insn_trans/trans_rvzfh.c.inc
+++ b/target/riscv/insn_trans/trans_rvzfh.c.inc
@@ -29,7 +29,7 @@
     if (!ctx->cfg_ptr->ext_zhinx && !ctx->cfg_ptr->ext_zfh) { \
         return false;                  \
     }                                  \
-    if (!smstateen_fcsr_check(ctx, 0)) { \
+    if (!smstateen_check(ctx, 0, SMSTATEEN0_FCSR)) { \
         return false; \
     } \
 } while (0)
@@ -38,7 +38,7 @@
     if (!(ctx->cfg_ptr->ext_zfh || ctx->cfg_ptr->ext_zfhmin)) { \
         return false;                         \
     }                                         \
-    if (!smstateen_fcsr_check(ctx, 0)) { \
+    if (!smstateen_check(ctx, 0, SMSTATEEN0_FCSR)) { \
         return false; \
     } \
 } while (0)
@@ -48,7 +48,7 @@
           ctx->cfg_ptr->ext_zhinx || ctx->cfg_ptr->ext_zhinxmin)) {     \
         return false;                                        \
     }                                                        \
-    if (!smstateen_fcsr_check(ctx, 0)) { \
+    if (!smstateen_check(ctx, 0, SMSTATEEN0_FCSR)) { \
         return false; \
     } \
 } while (0)
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
index 65a8549ec2..ee3a2deab6 100644
--- a/target/riscv/machine.c
+++ b/target/riscv/machine.c
@@ -331,6 +331,24 @@ static const VMStateDescription vmstate_pmu_ctr_state = {
     }
 };
 
+static bool jvt_needed(void *opaque)
+{
+    RISCVCPU *cpu = opaque;
+
+    return cpu->cfg.ext_zcmt;
+}
+
+static const VMStateDescription vmstate_jvt = {
+    .name = "cpu/jvt",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .needed = jvt_needed,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINTTL(env.jvt, RISCVCPU),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 const VMStateDescription vmstate_riscv_cpu = {
     .name = "cpu",
     .version_id = 5,
@@ -400,6 +418,7 @@ const VMStateDescription vmstate_riscv_cpu = {
         &vmstate_envcfg,
         &vmstate_debug,
         &vmstate_smstateen,
+        &vmstate_jvt,
         NULL
     }
 };
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
index ba25164d74..4bf9c9e632 100644
--- a/target/riscv/meson.build
+++ b/target/riscv/meson.build
@@ -18,7 +18,8 @@ riscv_ss.add(files(
   'bitmanip_helper.c',
   'translate.c',
   'm128_helper.c',
-  'crypto_helper.c'
+  'crypto_helper.c',
+  'zce_helper.c'
 ))
 riscv_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c'), if_false: files('kvm-stub.c'))
 
diff --git a/target/riscv/zce_helper.c b/target/riscv/zce_helper.c
new file mode 100644
index 0000000000..5822aa3740
--- /dev/null
+++ b/target/riscv/zce_helper.c
@@ -0,0 +1,57 @@
+/*
+ * 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/>.
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "exec/exec-all.h"
+#include "exec/helper-proto.h"
+#include "exec/cpu_ldst.h"
+
+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;
+}
-- 
2.25.1



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

* [PATCH v3 8/9] target/riscv: expose properties for Zc* extension
  2022-11-17  7:03 [PATCH v3 0/9] support subsets of code size reduction extension Weiwei Li
                   ` (6 preceding siblings ...)
  2022-11-17  7:03 ` [PATCH v3 7/9] target/riscv: add support for Zcmt extension Weiwei Li
@ 2022-11-17  7:03 ` Weiwei Li
  2022-11-17  7:03 ` [PATCH v3 9/9] disas/riscv.c: add disasm support for Zc* Weiwei Li
  8 siblings, 0 replies; 22+ messages in thread
From: Weiwei Li @ 2022-11-17  7:03 UTC (permalink / raw)
  To: richard.henderson, palmer, alistair.francis, bin.meng,
	qemu-riscv, qemu-devel
  Cc: wangjunqiang, lazyparser, Weiwei Li

Expose zca,zcb,zcf,zcd,zcmp,zcmt properties

Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
 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



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

* [PATCH v3 9/9] disas/riscv.c: add disasm support for Zc*
  2022-11-17  7:03 [PATCH v3 0/9] support subsets of code size reduction extension Weiwei Li
                   ` (7 preceding siblings ...)
  2022-11-17  7:03 ` [PATCH v3 8/9] target/riscv: expose properties for Zc* extension Weiwei Li
@ 2022-11-17  7:03 ` Weiwei Li
  8 siblings, 0 replies; 22+ messages in thread
From: Weiwei Li @ 2022-11-17  7:03 UTC (permalink / raw)
  To: richard.henderson, palmer, alistair.francis, bin.meng,
	qemu-riscv, qemu-devel
  Cc: wangjunqiang, lazyparser, Weiwei Li

Zcmp/Zcmt instructions will override disasm for c.fld*/c.fsd*
instructions currently

Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
---
 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 {
+                    op = rv_op_c_lh;
+                }
+                break;
+            case 2: op = rv_op_c_sb; break;
+            case 3:
+                if (((inst >> 6) & 1) == 0) {
+                    op = rv_op_c_sh;
+                }
+                break;
+            }
+            break;
         case 5:
             if (isa == rv128) {
                 op = rv_op_c_sq;
@@ -2362,6 +2433,17 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
                 case 3: op = rv_op_c_and; break;
                 case 4: op = rv_op_c_subw; break;
                 case 5: op = rv_op_c_addw; break;
+                case 6: op = rv_op_c_mul; break;
+                case 7:
+                    switch ((inst >> 2) & 0b111) {
+                    case 0: op = rv_op_c_zext_b; break;
+                    case 1: op = rv_op_c_sext_b; break;
+                    case 2: op = rv_op_c_zext_h; break;
+                    case 3: op = rv_op_c_sext_h; break;
+                    case 4: op = rv_op_c_zext_w; break;
+                    case 5: op = rv_op_c_not; break;
+                    }
+                    break;
                 }
                 break;
             }
@@ -2417,6 +2499,30 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
                 op = rv_op_c_sqsp;
             } else {
                 op = rv_op_c_fsdsp;
+                if (((inst >> 12) & 0b01)) {
+                    switch ((inst >> 8) & 0b01111) {
+                    case 8: op = rv_op_cm_push; break;
+                    case 10: op = rv_op_cm_pop; break;
+                    case 12: op = rv_op_cm_popretz; break;
+                    case 14: op = rv_op_cm_popret; break;
+                    }
+                } else {
+                    switch ((inst >> 10) & 0b011) {
+                    case 0:
+                        if (((inst >> 2) & 0xFF) >= 32) {
+                            op = rv_op_cm_jalt;
+                        } else {
+                            op = rv_op_cm_jt;
+                        }
+                        break;
+                    case 3:
+                        switch ((inst >> 5) & 0b011) {
+                        case 1: op = rv_op_cm_mvsa01; break;
+                        case 3: op = rv_op_cm_mva01s; break;
+                        }
+                        break;
+                    }
+                }
             }
             break;
         case 6: op = rv_op_c_swsp; break;
@@ -3661,6 +3767,21 @@ static uint32_t operand_crs2q(rv_inst inst)
     return (inst << 59) >> 61;
 }
 
+static uint32_t calculate_xreg(uint32_t sreg)
+{
+    return sreg < 2 ? sreg + 8 : sreg + 16;
+}
+
+static uint32_t operand_sreg1(rv_inst inst)
+{
+    return calculate_xreg((inst << 54) >> 61);
+}
+
+static uint32_t operand_sreg2(rv_inst inst)
+{
+    return calculate_xreg((inst << 59) >> 61);
+}
+
 static uint32_t operand_crd(rv_inst inst)
 {
     return (inst << 52) >> 59;
@@ -3883,6 +4004,97 @@ static uint32_t operand_vm(rv_inst inst)
     return (inst << 38) >> 63;
 }
 
+static uint32_t operand_uimm_c_lb(rv_inst inst)
+{
+    return (((inst << 58) >> 63) << 1) |
+        ((inst << 57) >> 63);
+}
+
+static uint32_t operand_uimm_c_lh(rv_inst inst)
+{
+    return (((inst << 58) >> 63) << 1);
+}
+
+static uint32_t operand_zcmp_spimm(rv_inst inst)
+{
+    return ((inst << 60) >> 62) << 4;
+}
+
+static uint32_t operand_zcmp_rlist(rv_inst inst)
+{
+    return ((inst << 56) >> 60);
+}
+
+static uint32_t calculate_stack_adj(rv_isa isa, uint32_t rlist, uint32_t spimm)
+{
+    uint32_t stack_adj_base = 0;
+    if (isa == rv64) {
+        switch (rlist) {
+        case 15:
+            stack_adj_base = 112;
+            break;
+        case 14:
+            stack_adj_base = 96;
+            break;
+        case 13:
+        case 12:
+            stack_adj_base = 80;
+            break;
+        case 11:
+        case 10:
+            stack_adj_base = 64;
+            break;
+        case 9:
+        case 8:
+            stack_adj_base = 48;
+            break;
+        case 7:
+        case 6:
+            stack_adj_base = 32;
+            break;
+        case 5:
+        case 4:
+            stack_adj_base = 16;
+            break;
+        }
+    } else {
+        switch (rlist) {
+        case 15:
+            stack_adj_base = 64;
+            break;
+        case 14:
+        case 13:
+        case 12:
+            stack_adj_base = 48;
+            break;
+        case 11:
+        case 10:
+        case 9:
+        case 8:
+            stack_adj_base = 32;
+            break;
+        case 7:
+        case 6:
+        case 5:
+        case 4:
+            stack_adj_base = 16;
+            break;
+        }
+    }
+    return stack_adj_base + spimm;
+}
+
+static uint32_t operand_zcmp_stack_adj(rv_inst inst, rv_isa isa)
+{
+    return calculate_stack_adj(isa, operand_zcmp_rlist(inst),
+                              operand_zcmp_spimm(inst));
+}
+
+static uint32_t operand_tbl_index(rv_inst inst)
+{
+    return ((inst << 54) >> 56);
+}
+
 /* decode operands */
 
 static void decode_inst_operands(rv_decode *dec, rv_isa isa)
@@ -4199,6 +4411,34 @@ static void decode_inst_operands(rv_decode *dec, rv_isa isa)
         dec->imm = operand_vimm(inst);
         dec->vzimm = operand_vzimm10(inst);
         break;
+    case rv_codec_zcb_lb:
+        dec->rs1 = operand_crs1q(inst) + 8;
+        dec->rs2 = operand_crs2q(inst) + 8;
+        dec->imm = operand_uimm_c_lb(inst);
+        break;
+    case rv_codec_zcb_lh:
+        dec->rs1 = operand_crs1q(inst) + 8;
+        dec->rs2 = operand_crs2q(inst) + 8;
+        dec->imm = operand_uimm_c_lh(inst);
+        break;
+    case rv_codec_zcb_ext:
+        dec->rd = operand_crs1q(inst) + 8;
+        break;
+    case rv_codec_zcb_mul:
+        dec->rd = operand_crs1rdq(inst) + 8;
+        dec->rs2 = operand_crs2q(inst) + 8;
+        break;
+    case rv_codec_zcmp_cm_pushpop:
+        dec->imm = operand_zcmp_stack_adj(inst, isa);
+        dec->rlist = operand_zcmp_rlist(inst);
+        break;
+    case rv_codec_zcmp_cm_mv:
+        dec->rd = operand_sreg1(inst);
+        dec->rs2 = operand_sreg2(inst);
+        break;
+    case rv_codec_zcmt_jt:
+        dec->imm = operand_tbl_index(inst);
+        break;
     };
 }
 
@@ -4358,6 +4598,9 @@ static void format_inst(char *buf, size_t buflen, size_t tab, rv_decode *dec)
         case ')':
             append(buf, ")", buflen);
             break;
+        case '-':
+            append(buf, "-", buflen);
+            break;
         case 'b':
             snprintf(tmp, sizeof(tmp), "%d", dec->bs);
             append(buf, tmp, buflen);
@@ -4541,6 +4784,48 @@ static void format_inst(char *buf, size_t buflen, size_t tab, rv_decode *dec)
             append(buf, vma, buflen);
             break;
         }
+        case 'x': {
+            switch(dec->rlist) {
+            case 4:
+                snprintf(tmp, sizeof(tmp), "{ra}");
+                break;
+            case 5:
+                snprintf(tmp, sizeof(tmp), "{ra, s0}");
+                break;
+            case 6:
+                snprintf(tmp, sizeof(tmp), "{ra, s0-s1}");
+                break;
+            case 7:
+                snprintf(tmp, sizeof(tmp), "{ra, s0-s2}");
+                break;
+            case 8:
+                snprintf(tmp, sizeof(tmp), "{ra, s0-s3}");
+                break;
+            case 9:
+                snprintf(tmp, sizeof(tmp), "{ra, s0-s4}");
+                break;
+            case 10:
+                snprintf(tmp, sizeof(tmp), "{ra, s0-s5}");
+                break;
+            case 11:
+                snprintf(tmp, sizeof(tmp), "{ra, s0-s6}");
+                break;
+            case 12:
+                snprintf(tmp, sizeof(tmp), "{ra, s0-s7}");
+                break;
+            case 13:
+                snprintf(tmp, sizeof(tmp), "{ra, s0-s8}");
+                break;
+            case 14:
+                snprintf(tmp, sizeof(tmp), "{ra, s0-s9}");
+                break;
+            case 15:
+                snprintf(tmp, sizeof(tmp), "{ra, s0-s11}");
+                break;
+            }
+            append(buf, tmp, buflen);
+            break;
+        }
         default:
             break;
         }
-- 
2.25.1



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

* Re: [PATCH v3 1/9] target/riscv: add cfg properties for Zc* extension
  2022-11-17  7:03 ` [PATCH v3 1/9] target/riscv: add cfg properties for Zc* extension Weiwei Li
@ 2022-11-17  8:54   ` Richard Henderson
  0 siblings, 0 replies; 22+ messages in thread
From: Richard Henderson @ 2022-11-17  8:54 UTC (permalink / raw)
  To: Weiwei Li, palmer, alistair.francis, bin.meng, qemu-riscv, qemu-devel
  Cc: wangjunqiang, lazyparser

On 11/16/22 23:03, Weiwei Li wrote:
> Add properties for Zca,Zcb,Zcf,Zcd,Zcmp,Zcmt extension
> Add check for these properties
> 
> Signed-off-by: Weiwei Li<liweiwei@iscas.ac.cn>
> Signed-off-by: Junqiang Wang<wangjunqiang@iscas.ac.cn>
> Cc: Alistair Francis<alistair.francis@wdc.com>
> ---
>   target/riscv/cpu.c | 43 +++++++++++++++++++++++++++++++++++++++++++
>   target/riscv/cpu.h |  6 ++++++
>   2 files changed, 49 insertions(+)

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

r~


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

* Re: [PATCH v3 2/9] target/riscv: add support for Zca extension
  2022-11-17  7:03 ` [PATCH v3 2/9] target/riscv: add support for Zca extension Weiwei Li
@ 2022-11-17  8:56   ` Richard Henderson
  0 siblings, 0 replies; 22+ messages in thread
From: Richard Henderson @ 2022-11-17  8:56 UTC (permalink / raw)
  To: Weiwei Li, palmer, alistair.francis, bin.meng, qemu-riscv, qemu-devel
  Cc: wangjunqiang, lazyparser

On 11/16/22 23:03, Weiwei Li wrote:
> Modify the check for C extension to Zca (C implies Zca)
> 
> Signed-off-by: Weiwei Li<liweiwei@iscas.ac.cn>
> Signed-off-by: Junqiang Wang<wangjunqiang@iscas.ac.cn>
> ---
>   target/riscv/insn_trans/trans_rvi.c.inc | 4 ++--
>   target/riscv/translate.c                | 8 ++++++--
>   2 files changed, 8 insertions(+), 4 deletions(-)

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

r~


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

* Re: [PATCH v3 3/9] target/riscv: add support for Zcf extension
  2022-11-17  7:03 ` [PATCH v3 3/9] target/riscv: add support for Zcf extension Weiwei Li
@ 2022-11-17  8:58   ` Richard Henderson
  0 siblings, 0 replies; 22+ messages in thread
From: Richard Henderson @ 2022-11-17  8:58 UTC (permalink / raw)
  To: Weiwei Li, palmer, alistair.francis, bin.meng, qemu-riscv, qemu-devel
  Cc: wangjunqiang, lazyparser

On 11/16/22 23:03, Weiwei Li wrote:
> Separate c_flw/c_fsw from flw/fsw to add check for Zcf extension
> 
> Signed-off-by: Weiwei Li<liweiwei@iscas.ac.cn>
> Signed-off-by: Junqiang Wang<wangjunqiang@iscas.ac.cn>
> ---
>   target/riscv/insn16.decode              |  8 ++++----
>   target/riscv/insn_trans/trans_rvf.c.inc | 18 ++++++++++++++++++
>   2 files changed, 22 insertions(+), 4 deletions(-)

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

r~


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

* Re: [PATCH v3 5/9] target/riscv: add support for Zcb extension
  2022-11-17  7:03 ` [PATCH v3 5/9] target/riscv: add support for Zcb extension Weiwei Li
@ 2022-11-17  9:10   ` Richard Henderson
  0 siblings, 0 replies; 22+ messages in thread
From: Richard Henderson @ 2022-11-17  9:10 UTC (permalink / raw)
  To: Weiwei Li, palmer, alistair.francis, bin.meng, qemu-riscv, qemu-devel
  Cc: wangjunqiang, lazyparser

On 11/16/22 23:03, Weiwei Li wrote:
> Add encode and trans* functions support for Zcb instructions
> 
> Signed-off-by: Weiwei Li<liweiwei@iscas.ac.cn>
> Signed-off-by: Junqiang Wang<wangjunqiang@iscas.ac.cn>
> ---
>   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

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

r~


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

* Re: [PATCH v3 6/9] target/riscv: add support for Zcmp extension
  2022-11-17  7:03 ` [PATCH v3 6/9] target/riscv: add support for Zcmp extension Weiwei Li
@ 2022-11-17  9:44   ` Richard Henderson
  2022-11-17 11:41     ` weiwei
  0 siblings, 1 reply; 22+ messages in thread
From: Richard Henderson @ 2022-11-17  9:44 UTC (permalink / raw)
  To: Weiwei Li, palmer, alistair.francis, bin.meng, qemu-riscv, qemu-devel
  Cc: wangjunqiang, lazyparser

On 11/16/22 23:03, Weiwei Li wrote:
> Add encode, trans* functions for Zcmp instructions
> 
> Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
> Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
> ---
>   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.

> +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


> +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);

> +            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);

> +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.


r~


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

* Re: [PATCH v3 7/9] target/riscv: add support for Zcmt extension
  2022-11-17  7:03 ` [PATCH v3 7/9] target/riscv: add support for Zcmt extension Weiwei Li
@ 2022-11-17  9:56   ` Richard Henderson
  2022-11-17 11:44     ` weiwei
  0 siblings, 1 reply; 22+ messages in thread
From: Richard Henderson @ 2022-11-17  9:56 UTC (permalink / raw)
  To: Weiwei Li, palmer, alistair.francis, bin.meng, qemu-riscv, qemu-devel
  Cc: wangjunqiang, lazyparser

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.


r~


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

* Re: [PATCH v3 6/9] target/riscv: add support for Zcmp extension
  2022-11-17  9:44   ` Richard Henderson
@ 2022-11-17 11:41     ` weiwei
  0 siblings, 0 replies; 22+ messages in thread
From: weiwei @ 2022-11-17 11:41 UTC (permalink / raw)
  To: Richard Henderson, palmer, alistair.francis, bin.meng,
	qemu-riscv, qemu-devel
  Cc: liweiwei, wangjunqiang, lazyparser

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 <liweiwei@iscas.ac.cn>
>> Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
>> ---
>>   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~



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

* Re: [PATCH v3 7/9] target/riscv: add support for Zcmt extension
  2022-11-17  9:56   ` Richard Henderson
@ 2022-11-17 11:44     ` weiwei
  2022-11-17 20:57       ` Richard Henderson
  0 siblings, 1 reply; 22+ messages in thread
From: weiwei @ 2022-11-17 11:44 UTC (permalink / raw)
  To: Richard Henderson, palmer, alistair.francis, bin.meng,
	qemu-riscv, qemu-devel
  Cc: liweiwei, wangjunqiang, lazyparser


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~



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

* Re: [PATCH v3 7/9] target/riscv: add support for Zcmt extension
  2022-11-17 11:44     ` weiwei
@ 2022-11-17 20:57       ` Richard Henderson
  2022-11-18  1:46         ` weiwei
  0 siblings, 1 reply; 22+ messages in thread
From: Richard Henderson @ 2022-11-17 20:57 UTC (permalink / raw)
  To: weiwei, palmer, alistair.francis, bin.meng, qemu-riscv,
	qemu-devel, mchitale
  Cc: wangjunqiang, lazyparser

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:

> 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.


r~


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

* Re: [PATCH v3 7/9] target/riscv: add support for Zcmt extension
  2022-11-17 20:57       ` Richard Henderson
@ 2022-11-18  1:46         ` weiwei
  2022-11-18  2:51           ` Richard Henderson
  0 siblings, 1 reply; 22+ messages in thread
From: weiwei @ 2022-11-18  1:46 UTC (permalink / raw)
  To: Richard Henderson, weiwei, palmer, alistair.francis, bin.meng,
	qemu-riscv, qemu-devel, mchitale
  Cc: wangjunqiang, lazyparser


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~



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

* Re: [PATCH v3 7/9] target/riscv: add support for Zcmt extension
  2022-11-18  1:46         ` weiwei
@ 2022-11-18  2:51           ` Richard Henderson
  2022-11-18  3:51             ` weiwei
  0 siblings, 1 reply; 22+ messages in thread
From: Richard Henderson @ 2022-11-18  2:51 UTC (permalink / raw)
  To: weiwei, palmer, alistair.francis, bin.meng, qemu-riscv,
	qemu-devel, mchitale
  Cc: wangjunqiang, lazyparser

On 11/17/22 17:46, weiwei wrote:
> 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)?

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.


r~


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

* Re: [PATCH v3 7/9] target/riscv: add support for Zcmt extension
  2022-11-18  2:51           ` Richard Henderson
@ 2022-11-18  3:51             ` weiwei
  0 siblings, 0 replies; 22+ messages in thread
From: weiwei @ 2022-11-18  3:51 UTC (permalink / raw)
  To: Richard Henderson, palmer, alistair.francis, bin.meng,
	qemu-riscv, qemu-devel, mchitale
  Cc: liweiwei, wangjunqiang, lazyparser


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



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

end of thread, other threads:[~2022-11-18  3:53 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-17  7:03 [PATCH v3 0/9] support subsets of code size reduction extension Weiwei Li
2022-11-17  7:03 ` [PATCH v3 1/9] target/riscv: add cfg properties for Zc* extension Weiwei Li
2022-11-17  8:54   ` Richard Henderson
2022-11-17  7:03 ` [PATCH v3 2/9] target/riscv: add support for Zca extension Weiwei Li
2022-11-17  8:56   ` Richard Henderson
2022-11-17  7:03 ` [PATCH v3 3/9] target/riscv: add support for Zcf extension Weiwei Li
2022-11-17  8:58   ` Richard Henderson
2022-11-17  7:03 ` [PATCH v3 4/9] target/riscv: add support for Zcd extension Weiwei Li
2022-11-17  7:03 ` [PATCH v3 5/9] target/riscv: add support for Zcb extension Weiwei Li
2022-11-17  9:10   ` Richard Henderson
2022-11-17  7:03 ` [PATCH v3 6/9] target/riscv: add support for Zcmp extension Weiwei Li
2022-11-17  9:44   ` Richard Henderson
2022-11-17 11:41     ` weiwei
2022-11-17  7:03 ` [PATCH v3 7/9] target/riscv: add support for Zcmt extension Weiwei Li
2022-11-17  9:56   ` Richard Henderson
2022-11-17 11:44     ` weiwei
2022-11-17 20:57       ` Richard Henderson
2022-11-18  1:46         ` weiwei
2022-11-18  2:51           ` Richard Henderson
2022-11-18  3:51             ` weiwei
2022-11-17  7:03 ` [PATCH v3 8/9] target/riscv: expose properties for Zc* extension Weiwei Li
2022-11-17  7:03 ` [PATCH v3 9/9] disas/riscv.c: add disasm support for Zc* Weiwei Li

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