All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC 0/8] support subsets of code size reduction extension
@ 2022-09-30  1:23 Weiwei Li
  2022-09-30  1:23 ` [RFC 1/8] target/riscv: add cfg properties for Zc* extension Weiwei Li
                   ` (7 more replies)
  0 siblings, 8 replies; 13+ messages in thread
From: Weiwei Li @ 2022-09-30  1:23 UTC (permalink / raw)
  To: 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.6 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

To test Zc* implementation, specify cpu argument with 'x-zca=true,x-zcb=true,x-zcf=true" and "x-zcd=true" (or "x-zcmp=true,x-zcmt=true") 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

Weiwei Li (8):
  target/riscv: add cfg properties for Zc* extension
  target/riscv: add support for Zca, Zcf and 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: delete redundant check for zcd instructions in
    decode_opc
  target/riscv: expose properties for Zc* extension
  disas/riscv.c: add disasm support for Zc*

 disas/riscv.c                             | 287 +++++++++++++++++++++-
 target/riscv/cpu.c                        |  37 +++
 target/riscv/cpu.h                        |   8 +
 target/riscv/cpu_bits.h                   |   6 +
 target/riscv/csr.c                        |  28 +++
 target/riscv/helper.h                     |   7 +
 target/riscv/insn16.decode                |  52 +++-
 target/riscv/insn_trans/trans_rvi.c.inc   |   5 +-
 target/riscv/insn_trans/trans_rvzce.c.inc | 279 +++++++++++++++++++++
 target/riscv/machine.c                    |  19 ++
 target/riscv/meson.build                  |   3 +-
 target/riscv/translate.c                  |  25 +-
 target/riscv/zce_helper.c                 | 244 ++++++++++++++++++
 13 files changed, 990 insertions(+), 10 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] 13+ messages in thread

* [RFC 1/8] target/riscv: add cfg properties for Zc* extension
  2022-09-30  1:23 [RFC 0/8] support subsets of code size reduction extension Weiwei Li
@ 2022-09-30  1:23 ` Weiwei Li
  2022-10-25  3:14   ` Alistair Francis
  2022-09-30  1:23 ` [RFC 2/8] target/riscv: add support for Zca, Zcf and Zcd extension Weiwei Li
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 13+ messages in thread
From: Weiwei Li @ 2022-09-30  1:23 UTC (permalink / raw)
  To: 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>
---
 target/riscv/cpu.c | 24 ++++++++++++++++++++++++
 target/riscv/cpu.h |  6 ++++++
 2 files changed, 30 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index b29c88b9f0..7da3de1725 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -782,6 +782,30 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
             }
         }
 
+        if (env->misa_mxl_max != MXL_RV32 && cpu->cfg.ext_zcf) {
+            error_setg(errp, "Zcf is only relevant to RV32");
+            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 require Zca extension");
+            return;
+        }
+
+        if ((((env->misa_ext & RVD) && (env->misa_ext & RVC)) ||
+             cpu->cfg.ext_zcd) && (cpu->cfg.ext_zcmp || cpu->cfg.ext_zcmt)) {
+            error_setg(errp,
+                       "Zcmp/Zcmt are incompatible with Zcd, which is "
+                       "included when C and D extensions are both present");
+            return;
+        }
+
+        if (cpu->cfg.ext_zcmt && !cpu->cfg.ext_icsr) {
+            error_setg(errp, "Zcmt extension requires Zicsr");
+            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 b131fa8c8e..db3eca1d8a 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -428,6 +428,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] 13+ messages in thread

* [RFC 2/8] target/riscv: add support for Zca, Zcf and Zcd extension
  2022-09-30  1:23 [RFC 0/8] support subsets of code size reduction extension Weiwei Li
  2022-09-30  1:23 ` [RFC 1/8] target/riscv: add cfg properties for Zc* extension Weiwei Li
@ 2022-09-30  1:23 ` Weiwei Li
  2022-09-30  1:23 ` [RFC 3/8] target/riscv: add support for Zcb extension Weiwei Li
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 13+ messages in thread
From: Weiwei Li @ 2022-09-30  1:23 UTC (permalink / raw)
  To: palmer, alistair.francis, bin.meng, qemu-riscv, qemu-devel
  Cc: wangjunqiang, lazyparser, Weiwei Li

Add check for Zca, Zcf and Zcd extensions in decode_opc

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 |  5 +++--
 target/riscv/translate.c                | 23 +++++++++++++++++++++--
 2 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
index c49dbec0eb..d178da89f9 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 (!has_ext(ctx, RVC) && !ctx->cfg_ptr->ext_zca) {
         TCGv t0 = tcg_temp_new();
 
         misaligned = gen_new_label();
@@ -178,7 +178,8 @@ 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 (!has_ext(ctx, RVC) && !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 db123da5ec..a257f0123e 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -526,7 +526,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 (!has_ext(ctx, RVC) && !ctx->cfg_ptr->ext_zca) {
         if ((next_pc & 0x3) != 0) {
             gen_exception_inst_addr_mis(ctx);
             return;
@@ -1064,7 +1064,26 @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
 
     /* 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
+         * Zcf(RV32 only) support c.flw, c.flwsp, c.fsw, c.fswsp
+         * Zcd support c.fld, c.fldsp, c.fsd, c.fsdsp
+         */
+        if (!(has_ext(ctx, RVC) || ctx->cfg_ptr->ext_zca)) {
+            gen_exception_illegal(ctx);
+        } else if ((get_xl_max(ctx) == MXL_RV32) &&
+            !(has_ext(ctx, RVC) || ctx->cfg_ptr->ext_zcf) &&
+            (((opcode & 0xe003) == 0x6000) ||
+             ((opcode & 0xe003) == 0x6002) ||
+             ((opcode & 0xe003) == 0xe000) ||
+             ((opcode & 0xe003) == 0xe002))) {
+            gen_exception_illegal(ctx);
+        } else if (!(has_ext(ctx, RVC) || ctx->cfg_ptr->ext_zcd) &&
+                   (((opcode & 0xe003) == 0x2000) ||
+                    ((opcode & 0xe003) == 0x2002) ||
+                    ((opcode & 0xe003) == 0xa000) ||
+                    ((opcode & 0xe003) == 0xa002))) {
             gen_exception_illegal(ctx);
         } else {
             ctx->opcode = opcode;
-- 
2.25.1



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

* [RFC 3/8] target/riscv: add support for Zcb extension
  2022-09-30  1:23 [RFC 0/8] support subsets of code size reduction extension Weiwei Li
  2022-09-30  1:23 ` [RFC 1/8] target/riscv: add cfg properties for Zc* extension Weiwei Li
  2022-09-30  1:23 ` [RFC 2/8] target/riscv: add support for Zca, Zcf and Zcd extension Weiwei Li
@ 2022-09-30  1:23 ` Weiwei Li
  2022-09-30  1:23 ` [RFC 4/8] target/riscv: add support for Zcmp extension Weiwei Li
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 13+ messages in thread
From: Weiwei Li @ 2022-09-30  1:23 UTC (permalink / raw)
  To: 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                |  22 ++++
 target/riscv/insn_trans/trans_rvzce.c.inc | 133 ++++++++++++++++++++++
 target/riscv/translate.c                  |   2 +
 3 files changed, 157 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 ccfe59f294..7ad673692e 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,11 @@
 
 @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_b        ... . .. ... .. ... ..  &i  imm=%zcb_b_uimm  rs1=%rs1_3 rd=%rs2_3
+@zcb_h        ... . .. ... .. ... ..  &i  imm=%zcb_h_uimm  rs1=%rs1_3 rd=%rs2_3
+
 # *** RV32/64C Standard Extension (Quadrant 0) ***
 {
   # Opcode of all zeros is illegal; rd != 0, nzuimm == 0 is reserved.
@@ -180,3 +188,17 @@ sw                110 .  .....  ..... 10 @c_swsp
   sd              111 .  .....  ..... 10 @c_sdsp
   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_b
+c_lhu             100 001  ... 0. ... 00 @zcb_h
+c_lh              100 001  ... 1. ... 00 @zcb_h
+c_sb              100 010  ... .. ... 00 @zcb_b
+c_sh              100 011  ... 0. ... 00 @zcb_h
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..0947190f2d
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rvzce.c.inc
@@ -0,0 +1,133 @@
+/*
+ * 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 gen_zce_load(DisasContext *ctx, arg_i *a, MemOp memop)
+{
+    TCGv dest = dest_gpr(ctx, a->rd);
+    TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
+    TCGv t0 = tcg_temp_new();
+
+    tcg_gen_addi_tl(t0, src1, a->imm);
+
+    tcg_gen_qemu_ld_tl(dest, t0, ctx->mem_idx, memop);
+    gen_set_gpr(ctx, a->rd, dest);
+
+    tcg_temp_free(t0);
+    return true;
+}
+
+static bool trans_c_lbu(DisasContext *ctx, arg_c_lbu *a)
+{
+    REQUIRE_ZCB(ctx);
+    MemOp memop = MO_UB;
+    return gen_zce_load(ctx, a, memop);
+}
+
+static bool trans_c_lhu(DisasContext *ctx, arg_c_lhu *a)
+{
+    REQUIRE_ZCB(ctx);
+    MemOp memop = MO_UW;
+    return gen_zce_load(ctx, a, memop);
+}
+
+static bool trans_c_lh(DisasContext *ctx, arg_c_lh *a)
+{
+    REQUIRE_ZCB(ctx);
+    MemOp memop = MO_SW;
+    return gen_zce_load(ctx, a, memop);
+}
+
+static bool gen_zce_store(DisasContext *ctx, arg_i *a, MemOp memop)
+{
+    TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
+    TCGv src2 = get_gpr(ctx, a->rd, EXT_NONE);
+    TCGv t0 = tcg_temp_new();
+
+    tcg_gen_addi_tl(t0, src1, a->imm);
+    tcg_gen_qemu_st_tl(src2, t0, ctx->mem_idx, memop);
+
+    tcg_temp_free(t0);
+    return true;
+}
+
+static bool trans_c_sb(DisasContext *ctx, arg_c_sb *a)
+{
+    REQUIRE_ZCB(ctx);
+    MemOp memop = MO_UB;
+    return gen_zce_store(ctx, a, memop);
+}
+
+static bool trans_c_sh(DisasContext *ctx, arg_c_sh *a)
+{
+    REQUIRE_ZCB(ctx);
+    MemOp memop = MO_UW;
+    return gen_zce_store(ctx, a, memop);
+}
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index a257f0123e..c0b8aa340b 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1037,6 +1037,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] 13+ messages in thread

* [RFC 4/8] target/riscv: add support for Zcmp extension
  2022-09-30  1:23 [RFC 0/8] support subsets of code size reduction extension Weiwei Li
                   ` (2 preceding siblings ...)
  2022-09-30  1:23 ` [RFC 3/8] target/riscv: add support for Zcb extension Weiwei Li
@ 2022-09-30  1:23 ` Weiwei Li
  2022-09-30  1:23 ` [RFC 5/8] target/riscv: add support for Zcmt extension Weiwei Li
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 13+ messages in thread
From: Weiwei Li @ 2022-09-30  1:23 UTC (permalink / raw)
  To: palmer, alistair.francis, bin.meng, qemu-riscv, qemu-devel
  Cc: wangjunqiang, lazyparser, Weiwei Li

Add encode, trans* functions and helper functions support for Zcmp
instructions

Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
---
 target/riscv/helper.h                     |   6 +
 target/riscv/insn16.decode                |  24 ++-
 target/riscv/insn_trans/trans_rvzce.c.inc | 123 +++++++++++++
 target/riscv/meson.build                  |   3 +-
 target/riscv/translate.c                  |   9 +-
 target/riscv/zce_helper.c                 | 210 ++++++++++++++++++++++
 6 files changed, 369 insertions(+), 6 deletions(-)
 create mode 100644 target/riscv/zce_helper.c

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index a03014fe67..9250e01cb6 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1134,3 +1134,9 @@ 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_4(cm_pop, tl, env, tl, tl, tl)
+DEF_HELPER_4(cm_push, void, env, tl, tl, tl)
+DEF_HELPER_4(cm_popret, tl, env, tl, tl, tl)
+DEF_HELPER_4(cm_popretz, tl, env, tl, tl, tl)
diff --git a/target/riscv/insn16.decode b/target/riscv/insn16.decode
index 7ad673692e..941146633d 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
@@ -96,6 +102,8 @@
 @zcb_binary   ... ...  ... .. ... ..  &r  rs2=%rs2_3       rs1=%rs1_3 rd=%rs1_3
 @zcb_b        ... . .. ... .. ... ..  &i  imm=%zcb_b_uimm  rs1=%rs1_3 rd=%rs2_3
 @zcb_h        ... . .. ... .. ... ..  &i  imm=%zcb_h_uimm  rs1=%rs1_3 rd=%rs2_3
+@zcmp         ... ...  ........   ..  &zcmp  %zcmp_rlist   %zcmp_spimm
+@cm_mv        ... ...  ... .. ... ..  &r2_s  rs2=%sreg2    rs1=%sreg1
 
 # *** RV32/64C Standard Extension (Quadrant 0) ***
 {
@@ -105,12 +113,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
 
@@ -156,7 +164,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
@@ -174,7 +182,15 @@ slli              000 .  .....  ..... 10 @c_shift2
 }
 {
   sq              101  ... ... .. ... 10 @c_sqsp
-  fsd             101   ......  ..... 10 @c_sdsp
+  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 0947190f2d..710e572cfe 100644
--- a/target/riscv/insn_trans/trans_rvzce.c.inc
+++ b/target/riscv/insn_trans/trans_rvzce.c.inc
@@ -21,6 +21,17 @@
         return false;           \
 } while (0)
 
+#define REQUIRE_C_OR_ZCD(ctx) do { \
+    if (!ctx->cfg_ptr->ext_zcd) {  \
+        REQUIRE_EXT(ctx, RVC);     \
+    } \
+} 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);
@@ -131,3 +142,115 @@ static bool trans_c_sh(DisasContext *ctx, arg_c_sh *a)
     MemOp memop = MO_UW;
     return gen_zce_store(ctx, a, memop);
 }
+
+static bool trans_c_fld(DisasContext *ctx, arg_c_fld *a)
+{
+    REQUIRE_C_OR_ZCD(ctx);
+    return trans_fld(ctx, a);
+}
+
+static bool trans_c_fsd(DisasContext *ctx, arg_c_fsd *a)
+{
+    REQUIRE_C_OR_ZCD(ctx);
+    return trans_fsd(ctx, a);
+}
+
+static bool gen_zcmp_check(DisasContext *ctx, arg_zcmp *a)
+{
+    /* rlist 0 to 3 are reserved for a future EABI variant called cm.popret.e */
+    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;
+}
+
+static bool gen_pop(DisasContext *ctx, arg_zcmp *a, bool ret,
+                    void (*func)(TCGv, TCGv_env, TCGv, TCGv, TCGv))
+{
+    if (!gen_zcmp_check(ctx, a)) {
+        return false;
+    }
+
+    TCGv sp = get_gpr(ctx, xSP, EXT_NONE);
+    TCGv rlist = tcg_const_tl(a->zcmp_rlist);
+    TCGv spimm = tcg_const_tl(a->zcmp_spimm);
+
+    func(cpu_pc, cpu_env, sp, spimm, rlist);
+
+    if (ret) {
+        gen_set_pc(ctx, cpu_pc);
+        tcg_gen_lookup_and_goto_ptr();
+        ctx->base.is_jmp = DISAS_NORETURN;
+    }
+    tcg_temp_free(spimm);
+    tcg_temp_free(rlist);
+    return true;
+}
+
+static bool trans_cm_push(DisasContext *ctx, arg_cm_push *a)
+{
+    REQUIRE_ZCMP(ctx);
+
+    if (!gen_zcmp_check(ctx, a)) {
+        return false;
+    }
+
+    TCGv sp = get_gpr(ctx, xSP, EXT_NONE);
+    TCGv rlist = tcg_const_tl(a->zcmp_rlist);
+    TCGv spimm = tcg_const_tl(a->zcmp_spimm);
+    gen_helper_cm_push(cpu_env, sp, spimm, rlist);
+
+    tcg_temp_free(spimm);
+    tcg_temp_free(rlist);
+    return true;
+}
+
+static bool trans_cm_pop(DisasContext *ctx, arg_cm_pop *a)
+{
+    REQUIRE_ZCMP(ctx);
+    return gen_pop(ctx, a, false, gen_helper_cm_pop);
+}
+
+static bool trans_cm_popret(DisasContext *ctx, arg_cm_popret *a)
+{
+    REQUIRE_ZCMP(ctx);
+    return gen_pop(ctx, a, true, gen_helper_cm_popret);
+}
+
+static bool trans_cm_popretz(DisasContext *ctx, arg_cm_popret *a)
+{
+    REQUIRE_ZCMP(ctx);
+    return gen_pop(ctx, a, true, gen_helper_cm_popretz);
+}
+
+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/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/translate.c b/target/riscv/translate.c
index c0b8aa340b..c4882db56b 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -707,6 +707,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. */
@@ -1071,6 +1076,7 @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
          * compressed floating point loads and stores
          * Zcf(RV32 only) support c.flw, c.flwsp, c.fsw, c.fswsp
          * Zcd support c.fld, c.fldsp, c.fsd, c.fsdsp
+         * Zcm* reuse the encode of Zcd
          */
         if (!(has_ext(ctx, RVC) || ctx->cfg_ptr->ext_zca)) {
             gen_exception_illegal(ctx);
@@ -1081,7 +1087,8 @@ 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) &&
+        } else if (!(has_ext(ctx, RVC) || ctx->cfg_ptr->ext_zcd ||
+                     ctx->cfg_ptr->ext_zcmp) &&
                    (((opcode & 0xe003) == 0x2000) ||
                     ((opcode & 0xe003) == 0x2002) ||
                     ((opcode & 0xe003) == 0xa000) ||
diff --git a/target/riscv/zce_helper.c b/target/riscv/zce_helper.c
new file mode 100644
index 0000000000..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/>.
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "exec/exec-all.h"
+#include "exec/helper-proto.h"
+#include "exec/cpu_ldst.h"
+
+#define X_S0    8
+#define X_S1    9
+#define X_Sn    16
+#define X_RA    1
+#define X_A0    10
+#define X_S4_E  7
+#define X_S3_E  6
+#define X_S2_E  14
+
+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[X_RA] = 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 inline target_ulong zcmp_pop(CPURISCVState *env, target_ulong sp,
+                                    target_ulong rlist, target_ulong spimm,
+                                    bool ret_val, bool ret)
+{
+    bool xreg_list[32] = {false};
+    target_ulong addr;
+    target_ulong stack_adj;
+    int bytes = riscv_cpu_xlen(env) == 32 ? 4 : 8;
+    int i;
+
+    update_push_pop_list(rlist, xreg_list);
+    stack_adj = caculate_stack_adj(bytes, rlist, spimm);
+    addr = sp + stack_adj - bytes;
+    for (i = 31; i >= 0; i--) {
+        if (xreg_list[i]) {
+            switch (bytes) {
+            case 4:
+                env->gpr[i] = cpu_ldl_le_data(env, addr);
+                break;
+            case 8:
+                env->gpr[i] = cpu_ldq_le_data(env, addr);
+                break;
+            default:
+                break;
+            }
+            addr -= bytes;
+        }
+    }
+
+    if (ret_val) {
+        env->gpr[xA0] = 0;
+    }
+
+    env->gpr[xSP] = sp + stack_adj;
+    if (ret) {
+        return env->gpr[xRA];
+    } else {
+        return env->pc;
+    }
+}
+
+static inline void zcmp_push(CPURISCVState *env, target_ulong sp,
+                             target_ulong rlist, target_ulong spimm)
+{
+    target_ulong addr = sp;
+    bool xreg_list[32] = {false};
+    target_ulong stack_adj;
+    int bytes = riscv_cpu_xlen(env) == 32 ? 4 : 8;
+    int i;
+
+    update_push_pop_list(rlist, xreg_list);
+    stack_adj = caculate_stack_adj(bytes, rlist, spimm);
+    addr -= bytes;
+    for (i = 31; i >= 0; i--) {
+        if (xreg_list[i]) {
+            switch (bytes) {
+            case 4:
+                cpu_stl_le_data(env, addr, env->gpr[i]);
+                break;
+            case 8:
+                cpu_stq_le_data(env, addr, env->gpr[i]);
+                break;
+            default:
+                break;
+            }
+            addr -= bytes;
+        }
+    }
+    env->gpr[xSP] = sp - stack_adj;
+}
+
+void HELPER(cm_push)(CPURISCVState *env, target_ulong sp, target_ulong spimm,
+                     target_ulong rlist)
+{
+    return zcmp_push(env, sp, rlist, spimm);
+}
+
+target_ulong HELPER(cm_pop)(CPURISCVState *env, target_ulong sp,
+                            target_ulong spimm, target_ulong rlist)
+{
+    return zcmp_pop(env, sp, rlist, spimm, false, false);
+}
+
+target_ulong HELPER(cm_popret)(CPURISCVState *env, target_ulong sp,
+                               target_ulong spimm, target_ulong rlist)
+{
+    return zcmp_pop(env, sp, rlist, spimm, false, true);
+}
+
+target_ulong HELPER(cm_popretz)(CPURISCVState *env, target_ulong sp,
+                                target_ulong spimm, target_ulong rlist)
+{
+    return zcmp_pop(env, sp, rlist, spimm, true, true);
+}
+#undef X_S0
+#undef X_Sn
+#undef ZCMP_POP
+#undef ZCMP_PUSH
-- 
2.25.1



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

* [RFC 5/8] target/riscv: add support for Zcmt extension
  2022-09-30  1:23 [RFC 0/8] support subsets of code size reduction extension Weiwei Li
                   ` (3 preceding siblings ...)
  2022-09-30  1:23 ` [RFC 4/8] target/riscv: add support for Zcmp extension Weiwei Li
@ 2022-09-30  1:23 ` Weiwei Li
  2022-09-30  1:23 ` [RFC 6/8] target/riscv: delete redundant check for zcd instructions in decode_opc Weiwei Li
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 13+ messages in thread
From: Weiwei Li @ 2022-09-30  1:23 UTC (permalink / raw)
  To: 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                   |  6 ++++
 target/riscv/csr.c                        | 28 +++++++++++++++++++
 target/riscv/helper.h                     |  1 +
 target/riscv/insn16.decode                |  6 ++++
 target/riscv/insn_trans/trans_rvzce.c.inc | 25 ++++++++++++++++-
 target/riscv/machine.c                    | 19 +++++++++++++
 target/riscv/translate.c                  |  2 +-
 target/riscv/zce_helper.c                 | 34 +++++++++++++++++++++++
 9 files changed, 121 insertions(+), 2 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index db3eca1d8a..2782ea9546 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 d8f5f0abed..37bf87f808 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -486,6 +486,9 @@
 /* Crypto Extension */
 #define CSR_SEED            0x015
 
+/* Zcmt Extension */
+#define CSR_JVT             0x017
+
 /* mstatus CSR bits */
 #define MSTATUS_UIE         0x00000001
 #define MSTATUS_SIE         0x00000002
@@ -857,4 +860,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 5c9a7ee287..a6d8115065 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -127,6 +127,17 @@ 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;
+    }
+
+    return RISCV_EXCP_NONE;
+}
+
 #if !defined(CONFIG_USER_ONLY)
 static RISCVException mctr(CPURISCVState *env, int csrno)
 {
@@ -3634,6 +3645,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 */
@@ -3671,6 +3696,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 9250e01cb6..3cc1de9641 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1140,3 +1140,4 @@ DEF_HELPER_4(cm_pop, tl, env, tl, tl, tl)
 DEF_HELPER_4(cm_push, void, env, tl, tl, tl)
 DEF_HELPER_4(cm_popret, tl, env, tl, tl, tl)
 DEF_HELPER_4(cm_popretz, tl, env, tl, tl, tl)
+DEF_HELPER_3(cm_jalt, tl, env, tl, tl)
diff --git a/target/riscv/insn16.decode b/target/riscv/insn16.decode
index 941146633d..25e274d582 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
@@ -104,6 +106,7 @@
 @zcb_h        ... . .. ... .. ... ..  &i  imm=%zcb_h_uimm  rs1=%rs1_3 rd=%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) ***
 {
@@ -191,6 +194,9 @@ 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
+
+  # *** RV64 and RV32 Zcmt Extension ***
+  cm_jalt         101  000   ........ 10 @zcmt_jt
 }
 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 710e572cfe..8f3c93cc6b 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,d,mp,mt] Standard Extension.
  *
  * Copyright (c) 2021-2022 PLCT Lab
  *
@@ -32,6 +32,11 @@
         return false;            \
 } while (0)
 
+#define REQUIRE_ZCMT(ctx) do {   \
+    if (!ctx->cfg_ptr->ext_zcmt) \
+        return false;            \
+} while (0)
+
 static bool trans_c_zext_b(DisasContext *ctx, arg_c_zext_b *a)
 {
     REQUIRE_ZCB(ctx);
@@ -254,3 +259,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/machine.c b/target/riscv/machine.c
index c2a94a82b3..138eb75d00 100644
--- a/target/riscv/machine.c
+++ b/target/riscv/machine.c
@@ -296,6 +296,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,
@@ -364,6 +382,7 @@ const VMStateDescription vmstate_riscv_cpu = {
         &vmstate_kvmtimer,
         &vmstate_envcfg,
         &vmstate_debug,
+        &vmstate_jvt,
         NULL
     }
 };
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index c4882db56b..347bc913eb 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1088,7 +1088,7 @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
              ((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_zcmp || ctx->cfg_ptr->ext_zcmt) &&
                    (((opcode & 0xe003) == 0x2000) ||
                     ((opcode & 0xe003) == 0x2002) ||
                     ((opcode & 0xe003) == 0xa000) ||
diff --git a/target/riscv/zce_helper.c b/target/riscv/zce_helper.c
index 1346de1367..f687c6fc85 100644
--- a/target/riscv/zce_helper.c
+++ b/target/riscv/zce_helper.c
@@ -208,3 +208,37 @@ target_ulong HELPER(cm_popretz)(CPURISCVState *env, target_ulong sp,
 #undef X_Sn
 #undef ZCMP_POP
 #undef ZCMP_PUSH
+
+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] 13+ messages in thread

* [RFC 6/8] target/riscv: delete redundant check for zcd instructions in decode_opc
  2022-09-30  1:23 [RFC 0/8] support subsets of code size reduction extension Weiwei Li
                   ` (4 preceding siblings ...)
  2022-09-30  1:23 ` [RFC 5/8] target/riscv: add support for Zcmt extension Weiwei Li
@ 2022-09-30  1:23 ` Weiwei Li
  2022-10-25  3:39   ` Alistair Francis
  2022-09-30  1:23 ` [RFC 7/8] target/riscv: expose properties for Zc* extension Weiwei Li
  2022-09-30  1:23 ` [RFC 8/8] disas/riscv.c: add disasm support for Zc* Weiwei Li
  7 siblings, 1 reply; 13+ messages in thread
From: Weiwei Li @ 2022-09-30  1:23 UTC (permalink / raw)
  To: palmer, alistair.francis, bin.meng, qemu-riscv, qemu-devel
  Cc: wangjunqiang, lazyparser, Weiwei Li

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

Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
---
 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);
         } else {
             ctx->opcode = opcode;
             ctx->pc_succ_insn = ctx->base.pc_next + 2;
-- 
2.25.1



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

* [RFC 7/8] target/riscv: expose properties for Zc* extension
  2022-09-30  1:23 [RFC 0/8] support subsets of code size reduction extension Weiwei Li
                   ` (5 preceding siblings ...)
  2022-09-30  1:23 ` [RFC 6/8] target/riscv: delete redundant check for zcd instructions in decode_opc Weiwei Li
@ 2022-09-30  1:23 ` Weiwei Li
  2022-10-25  3:39   ` Alistair Francis
  2022-09-30  1:23 ` [RFC 8/8] disas/riscv.c: add disasm support for Zc* Weiwei Li
  7 siblings, 1 reply; 13+ messages in thread
From: Weiwei Li @ 2022-09-30  1:23 UTC (permalink / raw)
  To: 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>
---
 target/riscv/cpu.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 7da3de1725..e6f722278c 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -80,6 +80,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),
@@ -1070,6 +1076,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] 13+ messages in thread

* [RFC 8/8] disas/riscv.c: add disasm support for Zc*
  2022-09-30  1:23 [RFC 0/8] support subsets of code size reduction extension Weiwei Li
                   ` (6 preceding siblings ...)
  2022-09-30  1:23 ` [RFC 7/8] target/riscv: expose properties for Zc* extension Weiwei Li
@ 2022-09-30  1:23 ` Weiwei Li
  7 siblings, 0 replies; 13+ messages in thread
From: Weiwei Li @ 2022-09-30  1:23 UTC (permalink / raw)
  To: 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 f107d94c4c..9368cc185c 100644
--- a/disas/riscv.c
+++ b/disas/riscv.c
@@ -158,6 +158,13 @@ typedef enum {
     rv_codec_css_sqsp,
     rv_codec_k_bs,
     rv_codec_k_rnum,
+    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 {
@@ -560,6 +567,26 @@ typedef enum {
     rv_op_zip = 396,
     rv_op_xperm4 = 397,
     rv_op_xperm8 = 398,
+    rv_op_c_zext_b = 399,
+    rv_op_c_sext_b = 400,
+    rv_op_c_zext_h = 401,
+    rv_op_c_sext_h = 402,
+    rv_op_c_zext_w = 403,
+    rv_op_c_not = 404,
+    rv_op_c_mul = 405,
+    rv_op_c_lbu = 406,
+    rv_op_c_lhu = 407,
+    rv_op_c_lh = 408,
+    rv_op_c_sb = 409,
+    rv_op_c_sh = 410,
+    rv_op_cm_push = 411,
+    rv_op_cm_pop = 412,
+    rv_op_cm_popret = 413,
+    rv_op_cm_popretz = 414,
+    rv_op_cm_mva01s = 415,
+    rv_op_cm_mvsa01 = 416,
+    rv_op_cm_jt = 417,
+    rv_op_cm_jalt = 418,
 } rv_op;
 
 /* structures */
@@ -581,6 +608,7 @@ typedef struct {
     uint8_t   rl;
     uint8_t   bs;
     uint8_t   rnum;
+    uint8_t   rlist;
 } rv_decode;
 
 typedef struct {
@@ -658,6 +686,10 @@ static const char rv_freg_name_sym[32][5] = {
 #define rv_fmt_rs2_offset             "O\t2,o"
 #define rv_fmt_rs1_rs2_bs             "O\t1,2,b"
 #define rv_fmt_rd_rs1_rnum            "O\t0,1,n"
+#define rv_fmt_rs1_rs2_zce_ldst       "O\t2,i(1)"
+#define rv_fmt_push_rlist             "O\tl,-i"
+#define rv_fmt_pop_rlist              "O\tl,i"
+#define rv_fmt_zcmt_index             "O\ti"
 
 /* pseudo-instruction constraints */
 
@@ -1283,7 +1315,27 @@ const rv_opcode_data opcode_data[] = {
     { "unzip", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
     { "zip", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
     { "xperm4", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
-    { "xperm8", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }
+    { "xperm8", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 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 */
@@ -1298,6 +1350,7 @@ static const char *csr_name(int csrno)
     case 0x0004: return "uie";
     case 0x0005: return "utvec";
     case 0x0015: return "seed";
+    case 0x0017: return "jvt";
     case 0x0040: return "uscratch";
     case 0x0041: return "uepc";
     case 0x0042: return "ucause";
@@ -1517,6 +1570,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;
@@ -1573,6 +1644,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;
             }
@@ -1628,6 +1710,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;
@@ -2338,6 +2444,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;
@@ -2540,6 +2661,97 @@ static uint32_t operand_rnum(rv_inst inst)
     return (inst << 40) >> 60;
 }
 
+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)
@@ -2829,6 +3041,34 @@ static void decode_inst_operands(rv_decode *dec, rv_isa isa)
         dec->rs1 = operand_rs1(inst);
         dec->rnum = operand_rnum(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;
     };
 }
 
@@ -2988,6 +3228,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);
@@ -3113,6 +3356,48 @@ static void format_inst(char *buf, size_t buflen, size_t tab, rv_decode *dec)
                 append(buf, ".rl", buflen);
             }
             break;
+        case 'l': {
+            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] 13+ messages in thread

* Re: [RFC 1/8] target/riscv: add cfg properties for Zc* extension
  2022-09-30  1:23 ` [RFC 1/8] target/riscv: add cfg properties for Zc* extension Weiwei Li
@ 2022-10-25  3:14   ` Alistair Francis
  0 siblings, 0 replies; 13+ messages in thread
From: Alistair Francis @ 2022-10-25  3:14 UTC (permalink / raw)
  To: Weiwei Li
  Cc: palmer, alistair.francis, bin.meng, qemu-riscv, qemu-devel,
	wangjunqiang, lazyparser

On Fri, Sep 30, 2022 at 11:28 AM Weiwei Li <liweiwei@iscas.ac.cn> 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>

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

Alistair

> ---
>  target/riscv/cpu.c | 24 ++++++++++++++++++++++++
>  target/riscv/cpu.h |  6 ++++++
>  2 files changed, 30 insertions(+)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index b29c88b9f0..7da3de1725 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -782,6 +782,30 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
>              }
>          }
>
> +        if (env->misa_mxl_max != MXL_RV32 && cpu->cfg.ext_zcf) {
> +            error_setg(errp, "Zcf is only relevant to RV32");
> +            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 require Zca extension");
> +            return;
> +        }
> +
> +        if ((((env->misa_ext & RVD) && (env->misa_ext & RVC)) ||
> +             cpu->cfg.ext_zcd) && (cpu->cfg.ext_zcmp || cpu->cfg.ext_zcmt)) {
> +            error_setg(errp,
> +                       "Zcmp/Zcmt are incompatible with Zcd, which is "
> +                       "included when C and D extensions are both present");
> +            return;
> +        }
> +
> +        if (cpu->cfg.ext_zcmt && !cpu->cfg.ext_icsr) {
> +            error_setg(errp, "Zcmt extension requires Zicsr");
> +            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 b131fa8c8e..db3eca1d8a 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -428,6 +428,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	[flat|nested] 13+ messages in thread

* Re: [RFC 6/8] target/riscv: delete redundant check for zcd instructions in decode_opc
  2022-09-30  1:23 ` [RFC 6/8] target/riscv: delete redundant check for zcd instructions in decode_opc Weiwei Li
@ 2022-10-25  3:39   ` Alistair Francis
  2022-10-25  7:03     ` weiwei
  0 siblings, 1 reply; 13+ messages in thread
From: Alistair Francis @ 2022-10-25  3:39 UTC (permalink / raw)
  To: Weiwei Li
  Cc: palmer, alistair.francis, bin.meng, qemu-riscv, qemu-devel,
	wangjunqiang, lazyparser

On Fri, Sep 30, 2022 at 11:28 AM Weiwei Li <liweiwei@iscas.ac.cn> wrote:
>
> All the check for Zcd instructions have been done in their trans function
>
> Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
> Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
> ---
>  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

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


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

* Re: [RFC 7/8] target/riscv: expose properties for Zc* extension
  2022-09-30  1:23 ` [RFC 7/8] target/riscv: expose properties for Zc* extension Weiwei Li
@ 2022-10-25  3:39   ` Alistair Francis
  0 siblings, 0 replies; 13+ messages in thread
From: Alistair Francis @ 2022-10-25  3:39 UTC (permalink / raw)
  To: Weiwei Li
  Cc: palmer, alistair.francis, bin.meng, qemu-riscv, qemu-devel,
	wangjunqiang, lazyparser

On Fri, Sep 30, 2022 at 11:29 AM Weiwei Li <liweiwei@iscas.ac.cn> wrote:
>
> 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>

Alistair

> ---
>  target/riscv/cpu.c | 13 +++++++++++++
>  1 file changed, 13 insertions(+)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 7da3de1725..e6f722278c 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -80,6 +80,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),
> @@ -1070,6 +1076,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	[flat|nested] 13+ messages in thread

* Re: [RFC 6/8] target/riscv: delete redundant check for zcd instructions in decode_opc
  2022-10-25  3:39   ` Alistair Francis
@ 2022-10-25  7:03     ` weiwei
  0 siblings, 0 replies; 13+ messages in thread
From: weiwei @ 2022-10-25  7:03 UTC (permalink / raw)
  To: Alistair Francis
  Cc: liweiwei, palmer, alistair.francis, bin.meng, qemu-riscv,
	qemu-devel, wangjunqiang, lazyparser


On 2022/10/25 11:39, Alistair Francis wrote:
> On Fri, Sep 30, 2022 at 11:28 AM Weiwei Li <liweiwei@iscas.ac.cn> wrote:
>> All the check for Zcd instructions have been done in their trans function
>>
>> Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
>> Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
>> ---
>>   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
>>
>>



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

end of thread, other threads:[~2022-10-25  8:27 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-09-30  1:23 [RFC 0/8] support subsets of code size reduction extension Weiwei Li
2022-09-30  1:23 ` [RFC 1/8] target/riscv: add cfg properties for Zc* extension Weiwei Li
2022-10-25  3:14   ` Alistair Francis
2022-09-30  1:23 ` [RFC 2/8] target/riscv: add support for Zca, Zcf and Zcd extension Weiwei Li
2022-09-30  1:23 ` [RFC 3/8] target/riscv: add support for Zcb extension Weiwei Li
2022-09-30  1:23 ` [RFC 4/8] target/riscv: add support for Zcmp extension Weiwei Li
2022-09-30  1:23 ` [RFC 5/8] target/riscv: add support for Zcmt extension Weiwei Li
2022-09-30  1:23 ` [RFC 6/8] target/riscv: delete redundant check for zcd instructions in decode_opc Weiwei Li
2022-10-25  3:39   ` Alistair Francis
2022-10-25  7:03     ` weiwei
2022-09-30  1:23 ` [RFC 7/8] target/riscv: expose properties for Zc* extension Weiwei Li
2022-10-25  3:39   ` Alistair Francis
2022-09-30  1:23 ` [RFC 8/8] 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.