qemu-riscv.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/9] disas/riscv: Add vendor extension support
@ 2023-05-30 13:18 Christoph Muellner
  2023-05-30 13:18 ` [PATCH 1/9] target/riscv: Use xl instead of mxl for disassemble Christoph Muellner
                   ` (9 more replies)
  0 siblings, 10 replies; 30+ messages in thread
From: Christoph Muellner @ 2023-05-30 13:18 UTC (permalink / raw)
  To: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
	Philipp Tomsich, Palmer Dabbelt, Richard Henderson, Zhiwei Liu
  Cc: Christoph Müllner

From: Christoph Müllner <christoph.muellner@vrull.eu>

This series adds vendor extension support to the QEMU disassembler
for RISC-V. The following vendor extensions are covered:
* XThead{Ba,Bb,Bs,Cmo,CondMov,FMemIdx,Fmv,Mac,MemIdx,MemPair,Sync}
* XVentanaCondOps

So far, there have been two attempts to add vendor extension support
to the QEMU disassembler. The first one [1] was posted in August 2022
by LIU Zhiwei and attempts to separate vendor extension specifics
from standard extension code in combination with a patch that introduced
support for XVentanaCondOps. The second one [2] was posted in March 2023
by me and added XThead* support without separating the vendor extensions
from the standard code.

This patchset represents the third attempt to add vendor extension
support to the QEMU disassembler. It adds all features of the previous
attempts and integrates them into a patchset that uses the same
mechanism for testing the extension availability like translate.c
(using the booleans RISCVCPUConfig::ext_*).
To achieve that, a couple of patches were needed to restructure
the existing code.

Note, that this patchset allows an instruction encoder function for each
vendor extension, but operand decoding and instruction printing remains
common code. This is irrelevant for XVentanaCondOps, but the patch for
the XThead* extensions includes changes in riscv.c and riscv.h.
This could be changed to force more separation with the cost of
duplication.

The first patch of this series is cherry-picked from LIU Zhiwei's series.
It was reviewed by Alistair Francis and Richard Henderson, but never
made it on master. I've added "Reviewed-by" tags to the commit.

I've added "Co-developed-by" tags to those commits that are derived
from the series of LIU Zhiwei.

[1] https://lists.nongnu.org/archive/html/qemu-devel/2022-08/msg03662.html
[2] https://lists.nongnu.org/archive/html/qemu-devel/2023-03/msg04566.html

Christoph Müllner (8):
  target/riscv: Factor out RISCVCPUConfig from cpu.h
  disas/riscv: Move types/constants to new header file
  disas/riscv: Make rv_op_illegal a shared enum value
  disas/riscv: Encapsulate opcode_data into decode
  target/riscv/cpu: Share RISCVCPUConfig with disassembler
  disas/riscv: Provide infrastructure for vendor extensions
  disas/riscv: Add support for XVentanaCondOps
  disas/riscv: Add support for XThead* instructions

LIU Zhiwei (1):
  target/riscv: Use xl instead of mxl for disassemble

 disas/meson.build         |   6 +-
 disas/riscv-xthead.c      | 707 ++++++++++++++++++++++++++++++++++++++
 disas/riscv-xthead.h      |  28 ++
 disas/riscv-xventana.c    |  41 +++
 disas/riscv-xventana.h    |  18 +
 disas/riscv.c             | 384 ++++++---------------
 disas/riscv.h             | 297 ++++++++++++++++
 target/riscv/cpu-config.h | 159 +++++++++
 target/riscv/cpu.c        |   6 +-
 target/riscv/cpu.h        | 114 +-----
 target/riscv/translate.c  |  27 +-
 11 files changed, 1374 insertions(+), 413 deletions(-)
 create mode 100644 disas/riscv-xthead.c
 create mode 100644 disas/riscv-xthead.h
 create mode 100644 disas/riscv-xventana.c
 create mode 100644 disas/riscv-xventana.h
 create mode 100644 disas/riscv.h
 create mode 100644 target/riscv/cpu-config.h

-- 
2.40.1



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

* [PATCH 1/9] target/riscv: Use xl instead of mxl for disassemble
  2023-05-30 13:18 [PATCH 0/9] disas/riscv: Add vendor extension support Christoph Muellner
@ 2023-05-30 13:18 ` Christoph Muellner
  2023-05-30 13:18 ` [PATCH 2/9] target/riscv: Factor out RISCVCPUConfig from cpu.h Christoph Muellner
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 30+ messages in thread
From: Christoph Muellner @ 2023-05-30 13:18 UTC (permalink / raw)
  To: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
	Philipp Tomsich, Palmer Dabbelt, Richard Henderson, Zhiwei Liu
  Cc: Christoph Müllner, Weiwei Li, Daniel Henrique Barboza

From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>

Disassemble function(plugin_disas, target_disas, monitor_disas) will
always call set_disas_info before disassembling instructions.

plugin_disas  and target_disas will always be called under a TB, which
has the same XLEN.

We can't ensure that monitor_disas will always be called under a TB,
but current XLEN will still be a better choice, thus we can ensure at
least the disassemble of the nearest one TB is right.

Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
---
 target/riscv/cpu.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index db0875fb43..5b7818dbd1 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -818,8 +818,9 @@ static void riscv_cpu_reset_hold(Object *obj)
 static void riscv_cpu_disas_set_info(CPUState *s, disassemble_info *info)
 {
     RISCVCPU *cpu = RISCV_CPU(s);
+    CPURISCVState *env = &cpu->env;
 
-    switch (riscv_cpu_mxl(&cpu->env)) {
+    switch (env->xl) {
     case MXL_RV32:
         info->print_insn = print_insn_riscv32;
         break;
-- 
2.40.1



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

* [PATCH 2/9] target/riscv: Factor out RISCVCPUConfig from cpu.h
  2023-05-30 13:18 [PATCH 0/9] disas/riscv: Add vendor extension support Christoph Muellner
  2023-05-30 13:18 ` [PATCH 1/9] target/riscv: Use xl instead of mxl for disassemble Christoph Muellner
@ 2023-05-30 13:18 ` Christoph Muellner
  2023-06-12  3:21   ` Alistair Francis
  2023-06-12  6:40   ` LIU Zhiwei
  2023-05-30 13:18 ` [PATCH 3/9] disas/riscv: Move types/constants to new header file Christoph Muellner
                   ` (7 subsequent siblings)
  9 siblings, 2 replies; 30+ messages in thread
From: Christoph Muellner @ 2023-05-30 13:18 UTC (permalink / raw)
  To: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
	Philipp Tomsich, Palmer Dabbelt, Richard Henderson, Zhiwei Liu
  Cc: Christoph Müllner, Weiwei Li, Daniel Henrique Barboza

From: Christoph Müllner <christoph.muellner@vrull.eu>

The file target/riscv/cpu.h cannot be included by files outside
of target/riscv/. To share data with other parts of QEMU (e.g.
the disassembler) we need to factor out the relevant code.
Therefore, this patch moves the definition of RISCVCPUConfig
(and tightly coupled dependencies and functions) into its
own target/riscv/cpu-config.h file.
The goal is to be able to share the enablement-status of
the RISC-V ISA extensions (RISCVCPUConfig::ext_*) with
other parts of QEMU.

This patch does not introduce new functionality.
However, the patch includes a small change:
The parameter for the extension test functions has been changed
from 'DisasContext*' to 'const RISCVCPUConfig*'.
This allows to keep these functions in cpu-config.h.

Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
---
 target/riscv/cpu-config.h | 148 ++++++++++++++++++++++++++++++++++++++
 target/riscv/cpu.h        | 114 +----------------------------
 target/riscv/translate.c  |  27 +------
 3 files changed, 151 insertions(+), 138 deletions(-)
 create mode 100644 target/riscv/cpu-config.h

diff --git a/target/riscv/cpu-config.h b/target/riscv/cpu-config.h
new file mode 100644
index 0000000000..ca368af0b2
--- /dev/null
+++ b/target/riscv/cpu-config.h
@@ -0,0 +1,148 @@
+/*
+ * QEMU RISC-V CPU Config
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef RISCV_CPU_CONFIG_H
+#define RISCV_CPU_CONFIG_H
+
+/*
+ * map is a 16-bit bitmap: the most significant set bit in map is the maximum
+ * satp mode that is supported. It may be chosen by the user and must respect
+ * what qemu implements (valid_1_10_32/64) and what the hw is capable of
+ * (supported bitmap below).
+ *
+ * init is a 16-bit bitmap used to make sure the user selected a correct
+ * configuration as per the specification.
+ *
+ * supported is a 16-bit bitmap used to reflect the hw capabilities.
+ */
+typedef struct {
+    uint16_t map, init, supported;
+} RISCVSATPMap;
+
+struct RISCVCPUConfig {
+    bool ext_zba;
+    bool ext_zbb;
+    bool ext_zbc;
+    bool ext_zbkb;
+    bool ext_zbkc;
+    bool ext_zbkx;
+    bool ext_zbs;
+    bool ext_zca;
+    bool ext_zcb;
+    bool ext_zcd;
+    bool ext_zce;
+    bool ext_zcf;
+    bool ext_zcmp;
+    bool ext_zcmt;
+    bool ext_zk;
+    bool ext_zkn;
+    bool ext_zknd;
+    bool ext_zkne;
+    bool ext_zknh;
+    bool ext_zkr;
+    bool ext_zks;
+    bool ext_zksed;
+    bool ext_zksh;
+    bool ext_zkt;
+    bool ext_ifencei;
+    bool ext_icsr;
+    bool ext_icbom;
+    bool ext_icboz;
+    bool ext_zicond;
+    bool ext_zihintpause;
+    bool ext_smstateen;
+    bool ext_sstc;
+    bool ext_svadu;
+    bool ext_svinval;
+    bool ext_svnapot;
+    bool ext_svpbmt;
+    bool ext_zdinx;
+    bool ext_zawrs;
+    bool ext_zfh;
+    bool ext_zfhmin;
+    bool ext_zfinx;
+    bool ext_zhinx;
+    bool ext_zhinxmin;
+    bool ext_zve32f;
+    bool ext_zve64f;
+    bool ext_zve64d;
+    bool ext_zmmul;
+    bool ext_zvfh;
+    bool ext_zvfhmin;
+    bool ext_smaia;
+    bool ext_ssaia;
+    bool ext_sscofpmf;
+    bool rvv_ta_all_1s;
+    bool rvv_ma_all_1s;
+
+    uint32_t mvendorid;
+    uint64_t marchid;
+    uint64_t mimpid;
+
+    /* Vendor-specific custom extensions */
+    bool ext_xtheadba;
+    bool ext_xtheadbb;
+    bool ext_xtheadbs;
+    bool ext_xtheadcmo;
+    bool ext_xtheadcondmov;
+    bool ext_xtheadfmemidx;
+    bool ext_xtheadfmv;
+    bool ext_xtheadmac;
+    bool ext_xtheadmemidx;
+    bool ext_xtheadmempair;
+    bool ext_xtheadsync;
+    bool ext_XVentanaCondOps;
+
+    uint8_t pmu_num;
+    char *priv_spec;
+    char *user_spec;
+    char *bext_spec;
+    char *vext_spec;
+    uint16_t vlen;
+    uint16_t elen;
+    uint16_t cbom_blocksize;
+    uint16_t cboz_blocksize;
+    bool mmu;
+    bool pmp;
+    bool epmp;
+    bool debug;
+    bool misa_w;
+
+    bool short_isa_string;
+
+#ifndef CONFIG_USER_ONLY
+    RISCVSATPMap satp_mode;
+#endif
+};
+
+typedef struct RISCVCPUConfig RISCVCPUConfig;
+
+/* Helper functions to test for extensions.  */
+
+static inline bool always_true_p(const RISCVCPUConfig *cfg __attribute__((__unused__)))
+{
+    return true;
+}
+
+static inline bool has_xthead_p(const RISCVCPUConfig *cfg)
+{
+    return cfg->ext_xtheadba || cfg->ext_xtheadbb ||
+           cfg->ext_xtheadbs || cfg->ext_xtheadcmo ||
+           cfg->ext_xtheadcondmov ||
+           cfg->ext_xtheadfmemidx || cfg->ext_xtheadfmv ||
+           cfg->ext_xtheadmac || cfg->ext_xtheadmemidx ||
+           cfg->ext_xtheadmempair || cfg->ext_xtheadsync;
+}
+
+#define MATERIALISE_EXT_PREDICATE(ext) \
+    static inline bool has_ ## ext ## _p(const RISCVCPUConfig *cfg) \
+    { \
+        return cfg->ext_ ## ext ; \
+    }
+
+MATERIALISE_EXT_PREDICATE(XVentanaCondOps)
+
+#endif /* RISCV_CPU_CONFIG_H */
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index de7e43126a..895a307bad 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -28,6 +28,7 @@
 #include "qemu/int128.h"
 #include "cpu_bits.h"
 #include "qapi/qapi-types-common.h"
+#include "cpu-config.h"
 #include "cpu-qom.h"
 
 #define TCG_GUEST_DEFAULT_MO 0
@@ -368,119 +369,6 @@ struct CPUArchState {
     uint64_t kvm_timer_frequency;
 };
 
-/*
- * map is a 16-bit bitmap: the most significant set bit in map is the maximum
- * satp mode that is supported. It may be chosen by the user and must respect
- * what qemu implements (valid_1_10_32/64) and what the hw is capable of
- * (supported bitmap below).
- *
- * init is a 16-bit bitmap used to make sure the user selected a correct
- * configuration as per the specification.
- *
- * supported is a 16-bit bitmap used to reflect the hw capabilities.
- */
-typedef struct {
-    uint16_t map, init, supported;
-} RISCVSATPMap;
-
-struct RISCVCPUConfig {
-    bool ext_zba;
-    bool ext_zbb;
-    bool ext_zbc;
-    bool ext_zbkb;
-    bool ext_zbkc;
-    bool ext_zbkx;
-    bool ext_zbs;
-    bool ext_zca;
-    bool ext_zcb;
-    bool ext_zcd;
-    bool ext_zce;
-    bool ext_zcf;
-    bool ext_zcmp;
-    bool ext_zcmt;
-    bool ext_zk;
-    bool ext_zkn;
-    bool ext_zknd;
-    bool ext_zkne;
-    bool ext_zknh;
-    bool ext_zkr;
-    bool ext_zks;
-    bool ext_zksed;
-    bool ext_zksh;
-    bool ext_zkt;
-    bool ext_ifencei;
-    bool ext_icsr;
-    bool ext_icbom;
-    bool ext_icboz;
-    bool ext_zicond;
-    bool ext_zihintpause;
-    bool ext_smstateen;
-    bool ext_sstc;
-    bool ext_svadu;
-    bool ext_svinval;
-    bool ext_svnapot;
-    bool ext_svpbmt;
-    bool ext_zdinx;
-    bool ext_zawrs;
-    bool ext_zfh;
-    bool ext_zfhmin;
-    bool ext_zfinx;
-    bool ext_zhinx;
-    bool ext_zhinxmin;
-    bool ext_zve32f;
-    bool ext_zve64f;
-    bool ext_zve64d;
-    bool ext_zmmul;
-    bool ext_zvfh;
-    bool ext_zvfhmin;
-    bool ext_smaia;
-    bool ext_ssaia;
-    bool ext_sscofpmf;
-    bool rvv_ta_all_1s;
-    bool rvv_ma_all_1s;
-
-    uint32_t mvendorid;
-    uint64_t marchid;
-    uint64_t mimpid;
-
-    /* Vendor-specific custom extensions */
-    bool ext_xtheadba;
-    bool ext_xtheadbb;
-    bool ext_xtheadbs;
-    bool ext_xtheadcmo;
-    bool ext_xtheadcondmov;
-    bool ext_xtheadfmemidx;
-    bool ext_xtheadfmv;
-    bool ext_xtheadmac;
-    bool ext_xtheadmemidx;
-    bool ext_xtheadmempair;
-    bool ext_xtheadsync;
-    bool ext_XVentanaCondOps;
-
-    uint8_t pmu_num;
-    char *priv_spec;
-    char *user_spec;
-    char *bext_spec;
-    char *vext_spec;
-    uint16_t vlen;
-    uint16_t elen;
-    uint16_t cbom_blocksize;
-    uint16_t cboz_blocksize;
-    bool mmu;
-    bool pmp;
-    bool epmp;
-    bool debug;
-    bool misa_w;
-
-    bool short_isa_string;
-
-#ifndef CONFIG_USER_ONLY
-    RISCVSATPMap satp_mode;
-#endif
-};
-
-typedef struct RISCVCPUConfig RISCVCPUConfig;
-
 /*
  * RISCVCPU:
  * @env: #CPURISCVState
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 928da0d3f0..2697cc26d0 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -119,29 +119,6 @@ static inline bool has_ext(DisasContext *ctx, uint32_t ext)
     return ctx->misa_ext & ext;
 }
 
-static bool always_true_p(DisasContext *ctx  __attribute__((__unused__)))
-{
-    return true;
-}
-
-static bool has_xthead_p(DisasContext *ctx  __attribute__((__unused__)))
-{
-    return ctx->cfg_ptr->ext_xtheadba || ctx->cfg_ptr->ext_xtheadbb ||
-           ctx->cfg_ptr->ext_xtheadbs || ctx->cfg_ptr->ext_xtheadcmo ||
-           ctx->cfg_ptr->ext_xtheadcondmov ||
-           ctx->cfg_ptr->ext_xtheadfmemidx || ctx->cfg_ptr->ext_xtheadfmv ||
-           ctx->cfg_ptr->ext_xtheadmac || ctx->cfg_ptr->ext_xtheadmemidx ||
-           ctx->cfg_ptr->ext_xtheadmempair || ctx->cfg_ptr->ext_xtheadsync;
-}
-
-#define MATERIALISE_EXT_PREDICATE(ext)  \
-    static bool has_ ## ext ## _p(DisasContext *ctx)    \
-    { \
-        return ctx->cfg_ptr->ext_ ## ext ; \
-    }
-
-MATERIALISE_EXT_PREDICATE(XVentanaCondOps);
-
 #ifdef TARGET_RISCV32
 #define get_xl(ctx)    MXL_RV32
 #elif defined(CONFIG_USER_ONLY)
@@ -1106,7 +1083,7 @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
      * that are tested in-order until a decoder matches onto the opcode.
      */
     static const struct {
-        bool (*guard_func)(DisasContext *);
+        bool (*guard_func)(const RISCVCPUConfig *);
         bool (*decode_func)(DisasContext *, uint32_t);
     } decoders[] = {
         { always_true_p,  decode_insn32 },
@@ -1135,7 +1112,7 @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
         ctx->pc_succ_insn = ctx->base.pc_next + 4;
 
         for (size_t i = 0; i < ARRAY_SIZE(decoders); ++i) {
-            if (decoders[i].guard_func(ctx) &&
+            if (decoders[i].guard_func(ctx->cfg_ptr) &&
                 decoders[i].decode_func(ctx, opcode32)) {
                 return;
             }
-- 
2.40.1



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

* [PATCH 3/9] disas/riscv: Move types/constants to new header file
  2023-05-30 13:18 [PATCH 0/9] disas/riscv: Add vendor extension support Christoph Muellner
  2023-05-30 13:18 ` [PATCH 1/9] target/riscv: Use xl instead of mxl for disassemble Christoph Muellner
  2023-05-30 13:18 ` [PATCH 2/9] target/riscv: Factor out RISCVCPUConfig from cpu.h Christoph Muellner
@ 2023-05-30 13:18 ` Christoph Muellner
  2023-06-09  2:04   ` LIU Zhiwei
  2023-06-12  3:22   ` Alistair Francis
  2023-05-30 13:18 ` [PATCH 4/9] disas/riscv: Make rv_op_illegal a shared enum value Christoph Muellner
                   ` (6 subsequent siblings)
  9 siblings, 2 replies; 30+ messages in thread
From: Christoph Muellner @ 2023-05-30 13:18 UTC (permalink / raw)
  To: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
	Philipp Tomsich, Palmer Dabbelt, Richard Henderson, Zhiwei Liu
  Cc: Christoph Müllner, Alistair Francis

From: Christoph Müllner <christoph.muellner@vrull.eu>

In order to enable vendor disassembler support, we need to
move types and constants into a header file so that other
compilation units can use them as well.

This patch does not introduce any functional changes.

Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
---
 disas/riscv.c | 270 +-----------------------------------------------
 disas/riscv.h | 280 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 281 insertions(+), 269 deletions(-)
 create mode 100644 disas/riscv.h

diff --git a/disas/riscv.c b/disas/riscv.c
index d597161d46..a062fb48cc 100644
--- a/disas/riscv.c
+++ b/disas/riscv.c
@@ -19,158 +19,7 @@
 
 #include "qemu/osdep.h"
 #include "disas/dis-asm.h"
-
-
-/* types */
-
-typedef uint64_t rv_inst;
-typedef uint16_t rv_opcode;
-
-/* enums */
-
-typedef enum {
-    rv32,
-    rv64,
-    rv128
-} rv_isa;
-
-typedef enum {
-    rv_rm_rne = 0,
-    rv_rm_rtz = 1,
-    rv_rm_rdn = 2,
-    rv_rm_rup = 3,
-    rv_rm_rmm = 4,
-    rv_rm_dyn = 7,
-} rv_rm;
-
-typedef enum {
-    rv_fence_i = 8,
-    rv_fence_o = 4,
-    rv_fence_r = 2,
-    rv_fence_w = 1,
-} rv_fence;
-
-typedef enum {
-    rv_ireg_zero,
-    rv_ireg_ra,
-    rv_ireg_sp,
-    rv_ireg_gp,
-    rv_ireg_tp,
-    rv_ireg_t0,
-    rv_ireg_t1,
-    rv_ireg_t2,
-    rv_ireg_s0,
-    rv_ireg_s1,
-    rv_ireg_a0,
-    rv_ireg_a1,
-    rv_ireg_a2,
-    rv_ireg_a3,
-    rv_ireg_a4,
-    rv_ireg_a5,
-    rv_ireg_a6,
-    rv_ireg_a7,
-    rv_ireg_s2,
-    rv_ireg_s3,
-    rv_ireg_s4,
-    rv_ireg_s5,
-    rv_ireg_s6,
-    rv_ireg_s7,
-    rv_ireg_s8,
-    rv_ireg_s9,
-    rv_ireg_s10,
-    rv_ireg_s11,
-    rv_ireg_t3,
-    rv_ireg_t4,
-    rv_ireg_t5,
-    rv_ireg_t6,
-} rv_ireg;
-
-typedef enum {
-    rvc_end,
-    rvc_rd_eq_ra,
-    rvc_rd_eq_x0,
-    rvc_rs1_eq_x0,
-    rvc_rs2_eq_x0,
-    rvc_rs2_eq_rs1,
-    rvc_rs1_eq_ra,
-    rvc_imm_eq_zero,
-    rvc_imm_eq_n1,
-    rvc_imm_eq_p1,
-    rvc_csr_eq_0x001,
-    rvc_csr_eq_0x002,
-    rvc_csr_eq_0x003,
-    rvc_csr_eq_0xc00,
-    rvc_csr_eq_0xc01,
-    rvc_csr_eq_0xc02,
-    rvc_csr_eq_0xc80,
-    rvc_csr_eq_0xc81,
-    rvc_csr_eq_0xc82,
-} rvc_constraint;
-
-typedef enum {
-    rv_codec_illegal,
-    rv_codec_none,
-    rv_codec_u,
-    rv_codec_uj,
-    rv_codec_i,
-    rv_codec_i_sh5,
-    rv_codec_i_sh6,
-    rv_codec_i_sh7,
-    rv_codec_i_csr,
-    rv_codec_s,
-    rv_codec_sb,
-    rv_codec_r,
-    rv_codec_r_m,
-    rv_codec_r4_m,
-    rv_codec_r_a,
-    rv_codec_r_l,
-    rv_codec_r_f,
-    rv_codec_cb,
-    rv_codec_cb_imm,
-    rv_codec_cb_sh5,
-    rv_codec_cb_sh6,
-    rv_codec_ci,
-    rv_codec_ci_sh5,
-    rv_codec_ci_sh6,
-    rv_codec_ci_16sp,
-    rv_codec_ci_lwsp,
-    rv_codec_ci_ldsp,
-    rv_codec_ci_lqsp,
-    rv_codec_ci_li,
-    rv_codec_ci_lui,
-    rv_codec_ci_none,
-    rv_codec_ciw_4spn,
-    rv_codec_cj,
-    rv_codec_cj_jal,
-    rv_codec_cl_lw,
-    rv_codec_cl_ld,
-    rv_codec_cl_lq,
-    rv_codec_cr,
-    rv_codec_cr_mv,
-    rv_codec_cr_jalr,
-    rv_codec_cr_jr,
-    rv_codec_cs,
-    rv_codec_cs_sw,
-    rv_codec_cs_sd,
-    rv_codec_cs_sq,
-    rv_codec_css_swsp,
-    rv_codec_css_sdsp,
-    rv_codec_css_sqsp,
-    rv_codec_k_bs,
-    rv_codec_k_rnum,
-    rv_codec_v_r,
-    rv_codec_v_ldst,
-    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;
+#include "disas/riscv.h"
 
 typedef enum {
     rv_op_illegal = 0,
@@ -966,50 +815,6 @@ typedef enum {
     rv_op_czero_nez = 790,
 } rv_op;
 
-/* structures */
-
-typedef struct {
-    uint64_t  pc;
-    uint64_t  inst;
-    int32_t   imm;
-    uint16_t  op;
-    uint8_t   codec;
-    uint8_t   rd;
-    uint8_t   rs1;
-    uint8_t   rs2;
-    uint8_t   rs3;
-    uint8_t   rm;
-    uint8_t   pred;
-    uint8_t   succ;
-    uint8_t   aq;
-    uint8_t   rl;
-    uint8_t   bs;
-    uint8_t   rnum;
-    uint8_t   vm;
-    uint32_t  vzimm;
-    uint8_t   rlist;
-} rv_decode;
-
-typedef struct {
-    const int op;
-    const rvc_constraint *constraints;
-} rv_comp_data;
-
-enum {
-    rvcd_imm_nz = 0x1
-};
-
-typedef struct {
-    const char * const name;
-    const rv_codec codec;
-    const char * const format;
-    const rv_comp_data *pseudo;
-    const short decomp_rv32;
-    const short decomp_rv64;
-    const short decomp_rv128;
-    const short decomp_data;
-} rv_opcode_data;
-
 /* register names */
 
 static const char rv_ireg_name_sym[32][5] = {
@@ -1033,79 +838,6 @@ static const char rv_vreg_name_sym[32][4] = {
     "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"
 };
 
-/* instruction formats */
-
-#define rv_fmt_none                   "O\t"
-#define rv_fmt_rs1                    "O\t1"
-#define rv_fmt_offset                 "O\to"
-#define rv_fmt_pred_succ              "O\tp,s"
-#define rv_fmt_rs1_rs2                "O\t1,2"
-#define rv_fmt_rd_imm                 "O\t0,i"
-#define rv_fmt_rd_offset              "O\t0,o"
-#define rv_fmt_rd_rs1_rs2             "O\t0,1,2"
-#define rv_fmt_frd_rs1                "O\t3,1"
-#define rv_fmt_frd_frs1               "O\t3,4"
-#define rv_fmt_rd_frs1                "O\t0,4"
-#define rv_fmt_rd_frs1_frs2           "O\t0,4,5"
-#define rv_fmt_frd_frs1_frs2          "O\t3,4,5"
-#define rv_fmt_rm_frd_frs1            "O\tr,3,4"
-#define rv_fmt_rm_frd_rs1             "O\tr,3,1"
-#define rv_fmt_rm_rd_frs1             "O\tr,0,4"
-#define rv_fmt_rm_frd_frs1_frs2       "O\tr,3,4,5"
-#define rv_fmt_rm_frd_frs1_frs2_frs3  "O\tr,3,4,5,6"
-#define rv_fmt_rd_rs1_imm             "O\t0,1,i"
-#define rv_fmt_rd_rs1_offset          "O\t0,1,i"
-#define rv_fmt_rd_offset_rs1          "O\t0,i(1)"
-#define rv_fmt_frd_offset_rs1         "O\t3,i(1)"
-#define rv_fmt_rd_csr_rs1             "O\t0,c,1"
-#define rv_fmt_rd_csr_zimm            "O\t0,c,7"
-#define rv_fmt_rs2_offset_rs1         "O\t2,i(1)"
-#define rv_fmt_frs2_offset_rs1        "O\t5,i(1)"
-#define rv_fmt_rs1_rs2_offset         "O\t1,2,o"
-#define rv_fmt_rs2_rs1_offset         "O\t2,1,o"
-#define rv_fmt_aqrl_rd_rs2_rs1        "OAR\t0,2,(1)"
-#define rv_fmt_aqrl_rd_rs1            "OAR\t0,(1)"
-#define rv_fmt_rd                     "O\t0"
-#define rv_fmt_rd_zimm                "O\t0,7"
-#define rv_fmt_rd_rs1                 "O\t0,1"
-#define rv_fmt_rd_rs2                 "O\t0,2"
-#define rv_fmt_rs1_offset             "O\t1,o"
-#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_ldst_vd_rs1_vm         "O\tD,(1)m"
-#define rv_fmt_ldst_vd_rs1_rs2_vm     "O\tD,(1),2m"
-#define rv_fmt_ldst_vd_rs1_vs2_vm     "O\tD,(1),Fm"
-#define rv_fmt_vd_vs2_vs1             "O\tD,F,E"
-#define rv_fmt_vd_vs2_vs1_vl          "O\tD,F,El"
-#define rv_fmt_vd_vs2_vs1_vm          "O\tD,F,Em"
-#define rv_fmt_vd_vs2_rs1_vl          "O\tD,F,1l"
-#define rv_fmt_vd_vs2_fs1_vl          "O\tD,F,4l"
-#define rv_fmt_vd_vs2_rs1_vm          "O\tD,F,1m"
-#define rv_fmt_vd_vs2_fs1_vm          "O\tD,F,4m"
-#define rv_fmt_vd_vs2_imm_vl          "O\tD,F,il"
-#define rv_fmt_vd_vs2_imm_vm          "O\tD,F,im"
-#define rv_fmt_vd_vs2_uimm_vm         "O\tD,F,um"
-#define rv_fmt_vd_vs1_vs2_vm          "O\tD,E,Fm"
-#define rv_fmt_vd_rs1_vs2_vm          "O\tD,1,Fm"
-#define rv_fmt_vd_fs1_vs2_vm          "O\tD,4,Fm"
-#define rv_fmt_vd_vs1                 "O\tD,E"
-#define rv_fmt_vd_rs1                 "O\tD,1"
-#define rv_fmt_vd_fs1                 "O\tD,4"
-#define rv_fmt_vd_imm                 "O\tD,i"
-#define rv_fmt_vd_vs2                 "O\tD,F"
-#define rv_fmt_vd_vs2_vm              "O\tD,Fm"
-#define rv_fmt_rd_vs2_vm              "O\t0,Fm"
-#define rv_fmt_rd_vs2                 "O\t0,F"
-#define rv_fmt_fd_vs2                 "O\t3,F"
-#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 */
 
 static const rvc_constraint rvcc_jal[] = { rvc_rd_eq_ra, rvc_end };
diff --git a/disas/riscv.h b/disas/riscv.h
new file mode 100644
index 0000000000..0f34b71518
--- /dev/null
+++ b/disas/riscv.h
@@ -0,0 +1,280 @@
+/*
+ * QEMU disassembler -- RISC-V specific header.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef DISAS_RISCV_H
+#define DISAS_RISCV_H
+
+#include "qemu/osdep.h"
+
+/* types */
+
+typedef uint64_t rv_inst;
+typedef uint16_t rv_opcode;
+
+/* enums */
+
+typedef enum {
+    rv32,
+    rv64,
+    rv128
+} rv_isa;
+
+typedef enum {
+    rv_rm_rne = 0,
+    rv_rm_rtz = 1,
+    rv_rm_rdn = 2,
+    rv_rm_rup = 3,
+    rv_rm_rmm = 4,
+    rv_rm_dyn = 7,
+} rv_rm;
+
+typedef enum {
+    rv_fence_i = 8,
+    rv_fence_o = 4,
+    rv_fence_r = 2,
+    rv_fence_w = 1,
+} rv_fence;
+
+typedef enum {
+    rv_ireg_zero,
+    rv_ireg_ra,
+    rv_ireg_sp,
+    rv_ireg_gp,
+    rv_ireg_tp,
+    rv_ireg_t0,
+    rv_ireg_t1,
+    rv_ireg_t2,
+    rv_ireg_s0,
+    rv_ireg_s1,
+    rv_ireg_a0,
+    rv_ireg_a1,
+    rv_ireg_a2,
+    rv_ireg_a3,
+    rv_ireg_a4,
+    rv_ireg_a5,
+    rv_ireg_a6,
+    rv_ireg_a7,
+    rv_ireg_s2,
+    rv_ireg_s3,
+    rv_ireg_s4,
+    rv_ireg_s5,
+    rv_ireg_s6,
+    rv_ireg_s7,
+    rv_ireg_s8,
+    rv_ireg_s9,
+    rv_ireg_s10,
+    rv_ireg_s11,
+    rv_ireg_t3,
+    rv_ireg_t4,
+    rv_ireg_t5,
+    rv_ireg_t6,
+} rv_ireg;
+
+typedef enum {
+    rvc_end,
+    rvc_rd_eq_ra,
+    rvc_rd_eq_x0,
+    rvc_rs1_eq_x0,
+    rvc_rs2_eq_x0,
+    rvc_rs2_eq_rs1,
+    rvc_rs1_eq_ra,
+    rvc_imm_eq_zero,
+    rvc_imm_eq_n1,
+    rvc_imm_eq_p1,
+    rvc_csr_eq_0x001,
+    rvc_csr_eq_0x002,
+    rvc_csr_eq_0x003,
+    rvc_csr_eq_0xc00,
+    rvc_csr_eq_0xc01,
+    rvc_csr_eq_0xc02,
+    rvc_csr_eq_0xc80,
+    rvc_csr_eq_0xc81,
+    rvc_csr_eq_0xc82,
+} rvc_constraint;
+
+typedef enum {
+    rv_codec_illegal,
+    rv_codec_none,
+    rv_codec_u,
+    rv_codec_uj,
+    rv_codec_i,
+    rv_codec_i_sh5,
+    rv_codec_i_sh6,
+    rv_codec_i_sh7,
+    rv_codec_i_csr,
+    rv_codec_s,
+    rv_codec_sb,
+    rv_codec_r,
+    rv_codec_r_m,
+    rv_codec_r4_m,
+    rv_codec_r_a,
+    rv_codec_r_l,
+    rv_codec_r_f,
+    rv_codec_cb,
+    rv_codec_cb_imm,
+    rv_codec_cb_sh5,
+    rv_codec_cb_sh6,
+    rv_codec_ci,
+    rv_codec_ci_sh5,
+    rv_codec_ci_sh6,
+    rv_codec_ci_16sp,
+    rv_codec_ci_lwsp,
+    rv_codec_ci_ldsp,
+    rv_codec_ci_lqsp,
+    rv_codec_ci_li,
+    rv_codec_ci_lui,
+    rv_codec_ci_none,
+    rv_codec_ciw_4spn,
+    rv_codec_cj,
+    rv_codec_cj_jal,
+    rv_codec_cl_lw,
+    rv_codec_cl_ld,
+    rv_codec_cl_lq,
+    rv_codec_cr,
+    rv_codec_cr_mv,
+    rv_codec_cr_jalr,
+    rv_codec_cr_jr,
+    rv_codec_cs,
+    rv_codec_cs_sw,
+    rv_codec_cs_sd,
+    rv_codec_cs_sq,
+    rv_codec_css_swsp,
+    rv_codec_css_sdsp,
+    rv_codec_css_sqsp,
+    rv_codec_k_bs,
+    rv_codec_k_rnum,
+    rv_codec_v_r,
+    rv_codec_v_ldst,
+    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;
+
+/* structures */
+
+typedef struct {
+    uint64_t  pc;
+    uint64_t  inst;
+    int32_t   imm;
+    uint16_t  op;
+    uint8_t   codec;
+    uint8_t   rd;
+    uint8_t   rs1;
+    uint8_t   rs2;
+    uint8_t   rs3;
+    uint8_t   rm;
+    uint8_t   pred;
+    uint8_t   succ;
+    uint8_t   aq;
+    uint8_t   rl;
+    uint8_t   bs;
+    uint8_t   rnum;
+    uint8_t   vm;
+    uint32_t  vzimm;
+    uint8_t   rlist;
+} rv_decode;
+
+typedef struct {
+    const int op;
+    const rvc_constraint *constraints;
+} rv_comp_data;
+
+enum {
+    rvcd_imm_nz = 0x1
+};
+
+typedef struct {
+    const char * const name;
+    const rv_codec codec;
+    const char * const format;
+    const rv_comp_data *pseudo;
+    const short decomp_rv32;
+    const short decomp_rv64;
+    const short decomp_rv128;
+    const short decomp_data;
+} rv_opcode_data;
+
+/* instruction formats */
+
+#define rv_fmt_none                   "O\t"
+#define rv_fmt_rs1                    "O\t1"
+#define rv_fmt_offset                 "O\to"
+#define rv_fmt_pred_succ              "O\tp,s"
+#define rv_fmt_rs1_rs2                "O\t1,2"
+#define rv_fmt_rd_imm                 "O\t0,i"
+#define rv_fmt_rd_offset              "O\t0,o"
+#define rv_fmt_rd_rs1_rs2             "O\t0,1,2"
+#define rv_fmt_frd_rs1                "O\t3,1"
+#define rv_fmt_frd_frs1               "O\t3,4"
+#define rv_fmt_rd_frs1                "O\t0,4"
+#define rv_fmt_rd_frs1_frs2           "O\t0,4,5"
+#define rv_fmt_frd_frs1_frs2          "O\t3,4,5"
+#define rv_fmt_rm_frd_frs1            "O\tr,3,4"
+#define rv_fmt_rm_frd_rs1             "O\tr,3,1"
+#define rv_fmt_rm_rd_frs1             "O\tr,0,4"
+#define rv_fmt_rm_frd_frs1_frs2       "O\tr,3,4,5"
+#define rv_fmt_rm_frd_frs1_frs2_frs3  "O\tr,3,4,5,6"
+#define rv_fmt_rd_rs1_imm             "O\t0,1,i"
+#define rv_fmt_rd_rs1_offset          "O\t0,1,i"
+#define rv_fmt_rd_offset_rs1          "O\t0,i(1)"
+#define rv_fmt_frd_offset_rs1         "O\t3,i(1)"
+#define rv_fmt_rd_csr_rs1             "O\t0,c,1"
+#define rv_fmt_rd_csr_zimm            "O\t0,c,7"
+#define rv_fmt_rs2_offset_rs1         "O\t2,i(1)"
+#define rv_fmt_frs2_offset_rs1        "O\t5,i(1)"
+#define rv_fmt_rs1_rs2_offset         "O\t1,2,o"
+#define rv_fmt_rs2_rs1_offset         "O\t2,1,o"
+#define rv_fmt_aqrl_rd_rs2_rs1        "OAR\t0,2,(1)"
+#define rv_fmt_aqrl_rd_rs1            "OAR\t0,(1)"
+#define rv_fmt_rd                     "O\t0"
+#define rv_fmt_rd_zimm                "O\t0,7"
+#define rv_fmt_rd_rs1                 "O\t0,1"
+#define rv_fmt_rd_rs2                 "O\t0,2"
+#define rv_fmt_rs1_offset             "O\t1,o"
+#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_ldst_vd_rs1_vm         "O\tD,(1)m"
+#define rv_fmt_ldst_vd_rs1_rs2_vm     "O\tD,(1),2m"
+#define rv_fmt_ldst_vd_rs1_vs2_vm     "O\tD,(1),Fm"
+#define rv_fmt_vd_vs2_vs1             "O\tD,F,E"
+#define rv_fmt_vd_vs2_vs1_vl          "O\tD,F,El"
+#define rv_fmt_vd_vs2_vs1_vm          "O\tD,F,Em"
+#define rv_fmt_vd_vs2_rs1_vl          "O\tD,F,1l"
+#define rv_fmt_vd_vs2_fs1_vl          "O\tD,F,4l"
+#define rv_fmt_vd_vs2_rs1_vm          "O\tD,F,1m"
+#define rv_fmt_vd_vs2_fs1_vm          "O\tD,F,4m"
+#define rv_fmt_vd_vs2_imm_vl          "O\tD,F,il"
+#define rv_fmt_vd_vs2_imm_vm          "O\tD,F,im"
+#define rv_fmt_vd_vs2_uimm_vm         "O\tD,F,um"
+#define rv_fmt_vd_vs1_vs2_vm          "O\tD,E,Fm"
+#define rv_fmt_vd_rs1_vs2_vm          "O\tD,1,Fm"
+#define rv_fmt_vd_fs1_vs2_vm          "O\tD,4,Fm"
+#define rv_fmt_vd_vs1                 "O\tD,E"
+#define rv_fmt_vd_rs1                 "O\tD,1"
+#define rv_fmt_vd_fs1                 "O\tD,4"
+#define rv_fmt_vd_imm                 "O\tD,i"
+#define rv_fmt_vd_vs2                 "O\tD,F"
+#define rv_fmt_vd_vs2_vm              "O\tD,Fm"
+#define rv_fmt_rd_vs2_vm              "O\t0,Fm"
+#define rv_fmt_rd_vs2                 "O\t0,F"
+#define rv_fmt_fd_vs2                 "O\t3,F"
+#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"
+
+#endif /* DISAS_RISCV_H */
-- 
2.40.1



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

* [PATCH 4/9] disas/riscv: Make rv_op_illegal a shared enum value
  2023-05-30 13:18 [PATCH 0/9] disas/riscv: Add vendor extension support Christoph Muellner
                   ` (2 preceding siblings ...)
  2023-05-30 13:18 ` [PATCH 3/9] disas/riscv: Move types/constants to new header file Christoph Muellner
@ 2023-05-30 13:18 ` Christoph Muellner
  2023-06-12  3:24   ` Alistair Francis
  2023-06-12  6:48   ` LIU Zhiwei
  2023-05-30 13:18 ` [PATCH 5/9] disas/riscv: Encapsulate opcode_data into decode Christoph Muellner
                   ` (5 subsequent siblings)
  9 siblings, 2 replies; 30+ messages in thread
From: Christoph Muellner @ 2023-05-30 13:18 UTC (permalink / raw)
  To: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
	Philipp Tomsich, Palmer Dabbelt, Richard Henderson, Zhiwei Liu
  Cc: Christoph Müllner, Alistair Francis

From: Christoph Müllner <christoph.muellner@vrull.eu>

The enum value 'rv_op_illegal' does not represent an
instruction, but is a catch-all value in case we have
no match in the decoder. Let's make the value a shared
one, so that other compile units can reuse it.

Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
---
 disas/riscv.c | 2 +-
 disas/riscv.h | 4 ++++
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/disas/riscv.c b/disas/riscv.c
index a062fb48cc..4cf477bc02 100644
--- a/disas/riscv.c
+++ b/disas/riscv.c
@@ -22,7 +22,7 @@
 #include "disas/riscv.h"
 
 typedef enum {
-    rv_op_illegal = 0,
+    /* 0 is reserved for rv_op_illegal. */
     rv_op_lui = 1,
     rv_op_auipc = 2,
     rv_op_jal = 3,
diff --git a/disas/riscv.h b/disas/riscv.h
index 0f34b71518..de2623e3cc 100644
--- a/disas/riscv.h
+++ b/disas/riscv.h
@@ -189,6 +189,10 @@ typedef struct {
     const rvc_constraint *constraints;
 } rv_comp_data;
 
+enum {
+    rv_op_illegal = 0
+};
+
 enum {
     rvcd_imm_nz = 0x1
 };
-- 
2.40.1



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

* [PATCH 5/9] disas/riscv: Encapsulate opcode_data into decode
  2023-05-30 13:18 [PATCH 0/9] disas/riscv: Add vendor extension support Christoph Muellner
                   ` (3 preceding siblings ...)
  2023-05-30 13:18 ` [PATCH 4/9] disas/riscv: Make rv_op_illegal a shared enum value Christoph Muellner
@ 2023-05-30 13:18 ` Christoph Muellner
  2023-06-12  3:26   ` Alistair Francis
  2023-05-30 13:18 ` [PATCH 6/9] target/riscv/cpu: Share RISCVCPUConfig with disassembler Christoph Muellner
                   ` (4 subsequent siblings)
  9 siblings, 1 reply; 30+ messages in thread
From: Christoph Muellner @ 2023-05-30 13:18 UTC (permalink / raw)
  To: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
	Philipp Tomsich, Palmer Dabbelt, Richard Henderson, Zhiwei Liu
  Cc: Christoph Müllner, Alistair Francis

From: Christoph Müllner <christoph.muellner@vrull.eu>

This patch adds a reference to a struct rv_opcode_data object
into struct rv_decode. This further allows to remove all references
to the global variable opcode_data (which is renamed to rvi_opcode_data).

This patch does not introduce any functional change, but prepares
the code for more struct rv_opcode_data objects in the future.

This patch is based on previous work from Liu Zhiwei:
  https://lists.nongnu.org/archive/html/qemu-devel/2022-08/msg03662.html

Co-developed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
---
 disas/riscv.c |  9 ++++++++-
 disas/riscv.h | 33 +++++++++++++++++----------------
 2 files changed, 25 insertions(+), 17 deletions(-)

diff --git a/disas/riscv.c b/disas/riscv.c
index 4cf477bc02..086edee6a2 100644
--- a/disas/riscv.c
+++ b/disas/riscv.c
@@ -1055,7 +1055,7 @@ static const rv_comp_data rvcp_fsgnjx_q[] = {
 
 /* instruction metadata */
 
-const rv_opcode_data opcode_data[] = {
+const rv_opcode_data rvi_opcode_data[] = {
     { "illegal", rv_codec_illegal, rv_fmt_none, NULL, 0, 0, 0 },
     { "lui", rv_codec_u, rv_fmt_rd_imm, NULL, 0, 0, 0 },
     { "auipc", rv_codec_u, rv_fmt_rd_offset, NULL, 0, 0, 0 },
@@ -3803,6 +3803,7 @@ static uint32_t operand_tbl_index(rv_inst inst)
 
 static void decode_inst_operands(rv_decode *dec, rv_isa isa)
 {
+    const rv_opcode_data *opcode_data = dec->opcode_data;
     rv_inst inst = dec->inst;
     dec->codec = opcode_data[dec->op].codec;
     switch (dec->codec) {
@@ -4284,6 +4285,7 @@ static void append(char *s1, const char *s2, size_t n)
 
 static void format_inst(char *buf, size_t buflen, size_t tab, rv_decode *dec)
 {
+    const rv_opcode_data *opcode_data = dec->opcode_data;
     char tmp[64];
     const char *fmt;
 
@@ -4517,6 +4519,7 @@ static void format_inst(char *buf, size_t buflen, size_t tab, rv_decode *dec)
 
 static void decode_inst_lift_pseudo(rv_decode *dec)
 {
+    const rv_opcode_data *opcode_data = dec->opcode_data;
     const rv_comp_data *comp_data = opcode_data[dec->op].pseudo;
     if (!comp_data) {
         return;
@@ -4535,6 +4538,7 @@ static void decode_inst_lift_pseudo(rv_decode *dec)
 
 static void decode_inst_decompress_rv32(rv_decode *dec)
 {
+    const rv_opcode_data *opcode_data = dec->opcode_data;
     int decomp_op = opcode_data[dec->op].decomp_rv32;
     if (decomp_op != rv_op_illegal) {
         if ((opcode_data[dec->op].decomp_data & rvcd_imm_nz)
@@ -4549,6 +4553,7 @@ static void decode_inst_decompress_rv32(rv_decode *dec)
 
 static void decode_inst_decompress_rv64(rv_decode *dec)
 {
+    const rv_opcode_data *opcode_data = dec->opcode_data;
     int decomp_op = opcode_data[dec->op].decomp_rv64;
     if (decomp_op != rv_op_illegal) {
         if ((opcode_data[dec->op].decomp_data & rvcd_imm_nz)
@@ -4563,6 +4568,7 @@ static void decode_inst_decompress_rv64(rv_decode *dec)
 
 static void decode_inst_decompress_rv128(rv_decode *dec)
 {
+    const rv_opcode_data *opcode_data = dec->opcode_data;
     int decomp_op = opcode_data[dec->op].decomp_rv128;
     if (decomp_op != rv_op_illegal) {
         if ((opcode_data[dec->op].decomp_data & rvcd_imm_nz)
@@ -4598,6 +4604,7 @@ disasm_inst(char *buf, size_t buflen, rv_isa isa, uint64_t pc, rv_inst inst)
     rv_decode dec = { 0 };
     dec.pc = pc;
     dec.inst = inst;
+    dec.opcode_data = rvi_opcode_data;
     decode_inst_opcode(&dec, isa);
     decode_inst_operands(&dec, isa);
     decode_inst_decompress(&dec, isa);
diff --git a/disas/riscv.h b/disas/riscv.h
index de2623e3cc..188f03feeb 100644
--- a/disas/riscv.h
+++ b/disas/riscv.h
@@ -162,9 +162,26 @@ typedef enum {
 
 /* structures */
 
+typedef struct {
+    const int op;
+    const rvc_constraint *constraints;
+} rv_comp_data;
+
+typedef struct {
+    const char * const name;
+    const rv_codec codec;
+    const char * const format;
+    const rv_comp_data *pseudo;
+    const short decomp_rv32;
+    const short decomp_rv64;
+    const short decomp_rv128;
+    const short decomp_data;
+} rv_opcode_data;
+
 typedef struct {
     uint64_t  pc;
     uint64_t  inst;
+    const rv_opcode_data *opcode_data;
     int32_t   imm;
     uint16_t  op;
     uint8_t   codec;
@@ -184,11 +201,6 @@ typedef struct {
     uint8_t   rlist;
 } rv_decode;
 
-typedef struct {
-    const int op;
-    const rvc_constraint *constraints;
-} rv_comp_data;
-
 enum {
     rv_op_illegal = 0
 };
@@ -197,17 +209,6 @@ enum {
     rvcd_imm_nz = 0x1
 };
 
-typedef struct {
-    const char * const name;
-    const rv_codec codec;
-    const char * const format;
-    const rv_comp_data *pseudo;
-    const short decomp_rv32;
-    const short decomp_rv64;
-    const short decomp_rv128;
-    const short decomp_data;
-} rv_opcode_data;
-
 /* instruction formats */
 
 #define rv_fmt_none                   "O\t"
-- 
2.40.1



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

* [PATCH 6/9] target/riscv/cpu: Share RISCVCPUConfig with disassembler
  2023-05-30 13:18 [PATCH 0/9] disas/riscv: Add vendor extension support Christoph Muellner
                   ` (4 preceding siblings ...)
  2023-05-30 13:18 ` [PATCH 5/9] disas/riscv: Encapsulate opcode_data into decode Christoph Muellner
@ 2023-05-30 13:18 ` Christoph Muellner
  2023-06-12  3:34   ` Alistair Francis
  2023-06-12  6:25   ` LIU Zhiwei
  2023-05-30 13:18 ` [PATCH 7/9] disas/riscv: Provide infrastructure for vendor extensions Christoph Muellner
                   ` (3 subsequent siblings)
  9 siblings, 2 replies; 30+ messages in thread
From: Christoph Muellner @ 2023-05-30 13:18 UTC (permalink / raw)
  To: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
	Philipp Tomsich, Palmer Dabbelt, Richard Henderson, Zhiwei Liu
  Cc: Christoph Müllner, Weiwei Li, Daniel Henrique Barboza

From: Christoph Müllner <christoph.muellner@vrull.eu>

The disassembler needs the available extensions in order
to properly decode instructions in case of overlapping
encodings (e.g. for vendor extensions).

Let's use the field 'disassemble_info::private_data' to store
our RISCVCPUConfig pointer.

Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
---
 target/riscv/cpu.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 5b7818dbd1..6f0cd9a0bb 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -819,6 +819,9 @@ static void riscv_cpu_disas_set_info(CPUState *s, disassemble_info *info)
 {
     RISCVCPU *cpu = RISCV_CPU(s);
     CPURISCVState *env = &cpu->env;
+    RISCVCPUConfig *cfg = &cpu->cfg;
+
+    info->private_data = cfg;
 
     switch (env->xl) {
     case MXL_RV32:
-- 
2.40.1



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

* [PATCH 7/9] disas/riscv: Provide infrastructure for vendor extensions
  2023-05-30 13:18 [PATCH 0/9] disas/riscv: Add vendor extension support Christoph Muellner
                   ` (5 preceding siblings ...)
  2023-05-30 13:18 ` [PATCH 6/9] target/riscv/cpu: Share RISCVCPUConfig with disassembler Christoph Muellner
@ 2023-05-30 13:18 ` Christoph Muellner
  2023-06-08 13:04   ` LIU Zhiwei
  2023-06-12  3:37   ` Alistair Francis
  2023-05-30 13:18 ` [PATCH 8/9] disas/riscv: Add support for XVentanaCondOps Christoph Muellner
                   ` (2 subsequent siblings)
  9 siblings, 2 replies; 30+ messages in thread
From: Christoph Muellner @ 2023-05-30 13:18 UTC (permalink / raw)
  To: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
	Philipp Tomsich, Palmer Dabbelt, Richard Henderson, Zhiwei Liu
  Cc: Christoph Müllner, Alistair Francis

From: Christoph Müllner <christoph.muellner@vrull.eu>

A previous patch provides a pointer to the RISCVCPUConfig data.
Let's use this to add the necessary code for vendor extensions.
This patch does not change the current behaviour, but clearly
defines how vendor extension support can be added to the disassembler.

Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
---
 disas/riscv.c | 34 ++++++++++++++++++++++++++++++----
 1 file changed, 30 insertions(+), 4 deletions(-)

diff --git a/disas/riscv.c b/disas/riscv.c
index 086edee6a2..db98e3ea6a 100644
--- a/disas/riscv.c
+++ b/disas/riscv.c
@@ -20,6 +20,7 @@
 #include "qemu/osdep.h"
 #include "disas/dis-asm.h"
 #include "disas/riscv.h"
+#include "target/riscv/cpu-config.h"
 
 typedef enum {
     /* 0 is reserved for rv_op_illegal. */
@@ -4599,13 +4600,38 @@ static void decode_inst_decompress(rv_decode *dec, rv_isa isa)
 /* disassemble instruction */
 
 static void
-disasm_inst(char *buf, size_t buflen, rv_isa isa, uint64_t pc, rv_inst inst)
+disasm_inst(char *buf, size_t buflen, rv_isa isa, uint64_t pc, rv_inst inst,
+            struct disassemble_info *info)
 {
+    RISCVCPUConfig *cfg = info->private_data;
     rv_decode dec = { 0 };
     dec.pc = pc;
     dec.inst = inst;
-    dec.opcode_data = rvi_opcode_data;
-    decode_inst_opcode(&dec, isa);
+
+    static const struct {
+        bool (*guard_func)(const RISCVCPUConfig *);
+        const rv_opcode_data *opcode_data;
+        void (*decode_func)(rv_decode *, rv_isa);
+    } decoders[] = {
+        { always_true_p, rvi_opcode_data, decode_inst_opcode },
+    };
+
+    for (size_t i = 0; i < ARRAY_SIZE(decoders); i++) {
+        bool (*guard_func)(const RISCVCPUConfig *) = decoders[i].guard_func;
+        const rv_opcode_data *opcode_data = decoders[i].opcode_data;
+        void (*decode_func)(rv_decode *, rv_isa) = decoders[i].decode_func;
+
+        if (guard_func(cfg)) {
+            dec.opcode_data = opcode_data;
+            decode_func(&dec, isa);
+            if (dec.op != rv_op_illegal)
+                break;
+        }
+    }
+
+    if (dec.op == rv_op_illegal)
+        dec.opcode_data = rvi_opcode_data;
+
     decode_inst_operands(&dec, isa);
     decode_inst_decompress(&dec, isa);
     decode_inst_lift_pseudo(&dec);
@@ -4659,7 +4685,7 @@ print_insn_riscv(bfd_vma memaddr, struct disassemble_info *info, rv_isa isa)
         break;
     }
 
-    disasm_inst(buf, sizeof(buf), isa, memaddr, inst);
+    disasm_inst(buf, sizeof(buf), isa, memaddr, inst, info);
     (*info->fprintf_func)(info->stream, "%s", buf);
 
     return len;
-- 
2.40.1



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

* [PATCH 8/9] disas/riscv: Add support for XVentanaCondOps
  2023-05-30 13:18 [PATCH 0/9] disas/riscv: Add vendor extension support Christoph Muellner
                   ` (6 preceding siblings ...)
  2023-05-30 13:18 ` [PATCH 7/9] disas/riscv: Provide infrastructure for vendor extensions Christoph Muellner
@ 2023-05-30 13:18 ` Christoph Muellner
  2023-06-12  3:38   ` Alistair Francis
  2023-05-30 13:18 ` [PATCH 9/9] disas/riscv: Add support for XThead* instructions Christoph Muellner
  2023-06-06 17:38 ` [PATCH 0/9] disas/riscv: Add vendor extension support Daniel Henrique Barboza
  9 siblings, 1 reply; 30+ messages in thread
From: Christoph Muellner @ 2023-05-30 13:18 UTC (permalink / raw)
  To: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
	Philipp Tomsich, Palmer Dabbelt, Richard Henderson, Zhiwei Liu
  Cc: Christoph Müllner, Alistair Francis

From: Christoph Müllner <christoph.muellner@vrull.eu>

This patch adds XVentanaCondOps support to the RISC-V disassembler.

Co-developed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
---
 disas/meson.build      |  5 ++++-
 disas/riscv-xventana.c | 41 +++++++++++++++++++++++++++++++++++++++++
 disas/riscv-xventana.h | 18 ++++++++++++++++++
 disas/riscv.c          |  4 ++++
 4 files changed, 67 insertions(+), 1 deletion(-)
 create mode 100644 disas/riscv-xventana.c
 create mode 100644 disas/riscv-xventana.h

diff --git a/disas/meson.build b/disas/meson.build
index 832727e4b3..e0ee326411 100644
--- a/disas/meson.build
+++ b/disas/meson.build
@@ -6,7 +6,10 @@ common_ss.add(when: 'CONFIG_M68K_DIS', if_true: files('m68k.c'))
 common_ss.add(when: 'CONFIG_MICROBLAZE_DIS', if_true: files('microblaze.c'))
 common_ss.add(when: 'CONFIG_MIPS_DIS', if_true: files('mips.c', 'nanomips.c'))
 common_ss.add(when: 'CONFIG_NIOS2_DIS', if_true: files('nios2.c'))
-common_ss.add(when: 'CONFIG_RISCV_DIS', if_true: files('riscv.c'))
+common_ss.add(when: 'CONFIG_RISCV_DIS', if_true: files(
+    'riscv.c',
+    'riscv-xventana.c'
+))
 common_ss.add(when: 'CONFIG_SH4_DIS', if_true: files('sh4.c'))
 common_ss.add(when: 'CONFIG_SPARC_DIS', if_true: files('sparc.c'))
 common_ss.add(when: 'CONFIG_XTENSA_DIS', if_true: files('xtensa.c'))
diff --git a/disas/riscv-xventana.c b/disas/riscv-xventana.c
new file mode 100644
index 0000000000..a0224d1fb3
--- /dev/null
+++ b/disas/riscv-xventana.c
@@ -0,0 +1,41 @@
+/*
+ * QEMU RISC-V Disassembler for xventana.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "disas/riscv.h"
+#include "disas/riscv-xventana.h"
+
+typedef enum {
+    /* 0 is reserved for rv_op_illegal. */
+    ventana_op_vt_maskc = 1,
+    ventana_op_vt_maskcn = 2,
+} rv_ventana_op;
+
+const rv_opcode_data ventana_opcode_data[] = {
+    { "vt.illegal", rv_codec_illegal, rv_fmt_none, NULL, 0, 0, 0 },
+    { "vt.maskc", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
+    { "vt.maskcn", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
+};
+
+void decode_xventanacondops(rv_decode *dec, rv_isa isa)
+{
+    rv_inst inst = dec->inst;
+    rv_opcode op = rv_op_illegal;
+
+    switch (((inst >> 0) & 0b11)) {
+    case 3:
+        switch (((inst >> 2) & 0b11111)) {
+        case 30:
+            switch (((inst >> 22) & 0b1111111000) | ((inst >> 12) & 0b0000000111)) {
+            case 6: op = ventana_op_vt_maskc; break;
+            case 7: op = ventana_op_vt_maskcn; break;
+            }
+            break;
+        }
+        break;
+    }
+
+    dec->op = op;
+}
diff --git a/disas/riscv-xventana.h b/disas/riscv-xventana.h
new file mode 100644
index 0000000000..72be9ffa16
--- /dev/null
+++ b/disas/riscv-xventana.h
@@ -0,0 +1,18 @@
+/*
+ * QEMU disassembler -- RISC-V specific header (xventana*).
+ *
+ * Copyright (c) 2023 VRULL GmbH
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef DISAS_RISCV_XVENTANA_H
+#define DISAS_RISCV_XVENTANA_H
+
+#include "disas/riscv.h"
+
+extern const rv_opcode_data ventana_opcode_data[];
+
+void decode_xventanacondops(rv_decode*, rv_isa);
+
+#endif /* DISAS_RISCV_XVENTANA_H */
diff --git a/disas/riscv.c b/disas/riscv.c
index db98e3ea6a..4f71333c45 100644
--- a/disas/riscv.c
+++ b/disas/riscv.c
@@ -22,6 +22,9 @@
 #include "disas/riscv.h"
 #include "target/riscv/cpu-config.h"
 
+/* Vendor extensions */
+#include "disas/riscv-xventana.h"
+
 typedef enum {
     /* 0 is reserved for rv_op_illegal. */
     rv_op_lui = 1,
@@ -4614,6 +4617,7 @@ disasm_inst(char *buf, size_t buflen, rv_isa isa, uint64_t pc, rv_inst inst,
         void (*decode_func)(rv_decode *, rv_isa);
     } decoders[] = {
         { always_true_p, rvi_opcode_data, decode_inst_opcode },
+        { has_XVentanaCondOps_p, ventana_opcode_data, decode_xventanacondops },
     };
 
     for (size_t i = 0; i < ARRAY_SIZE(decoders); i++) {
-- 
2.40.1



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

* [PATCH 9/9] disas/riscv: Add support for XThead* instructions
  2023-05-30 13:18 [PATCH 0/9] disas/riscv: Add vendor extension support Christoph Muellner
                   ` (7 preceding siblings ...)
  2023-05-30 13:18 ` [PATCH 8/9] disas/riscv: Add support for XVentanaCondOps Christoph Muellner
@ 2023-05-30 13:18 ` Christoph Muellner
  2023-06-12  3:40   ` Alistair Francis
  2023-06-06 17:38 ` [PATCH 0/9] disas/riscv: Add vendor extension support Daniel Henrique Barboza
  9 siblings, 1 reply; 30+ messages in thread
From: Christoph Muellner @ 2023-05-30 13:18 UTC (permalink / raw)
  To: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
	Philipp Tomsich, Palmer Dabbelt, Richard Henderson, Zhiwei Liu
  Cc: Christoph Müllner, Alistair Francis, Weiwei Li,
	Daniel Henrique Barboza

From: Christoph Müllner <christoph.muellner@vrull.eu>

Support for emulating XThead* instruction has been added recently.
This patch adds support for these instructions to the RISC-V disassembler.

Co-developed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
---
 disas/meson.build         |   1 +
 disas/riscv-xthead.c      | 707 ++++++++++++++++++++++++++++++++++++++
 disas/riscv-xthead.h      |  28 ++
 disas/riscv.c             |  69 ++++
 disas/riscv.h             |  12 +
 target/riscv/cpu-config.h |  11 +
 6 files changed, 828 insertions(+)
 create mode 100644 disas/riscv-xthead.c
 create mode 100644 disas/riscv-xthead.h

diff --git a/disas/meson.build b/disas/meson.build
index e0ee326411..8f64e378f9 100644
--- a/disas/meson.build
+++ b/disas/meson.build
@@ -8,6 +8,7 @@ common_ss.add(when: 'CONFIG_MIPS_DIS', if_true: files('mips.c', 'nanomips.c'))
 common_ss.add(when: 'CONFIG_NIOS2_DIS', if_true: files('nios2.c'))
 common_ss.add(when: 'CONFIG_RISCV_DIS', if_true: files(
     'riscv.c',
+    'riscv-xthead.c',
     'riscv-xventana.c'
 ))
 common_ss.add(when: 'CONFIG_SH4_DIS', if_true: files('sh4.c'))
diff --git a/disas/riscv-xthead.c b/disas/riscv-xthead.c
new file mode 100644
index 0000000000..99da679d16
--- /dev/null
+++ b/disas/riscv-xthead.c
@@ -0,0 +1,707 @@
+/*
+ * QEMU RISC-V Disassembler for xthead.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "disas/riscv.h"
+#include "disas/riscv-xthead.h"
+
+typedef enum {
+    /* 0 is reserved for rv_op_illegal. */
+    /* XTheadBa */
+    rv_op_th_addsl = 1,
+    /* XTheadBb */
+    rv_op_th_srri,
+    rv_op_th_srriw,
+    rv_op_th_ext,
+    rv_op_th_extu,
+    rv_op_th_ff0,
+    rv_op_th_ff1,
+    rv_op_th_rev,
+    rv_op_th_revw,
+    rv_op_th_tstnbz,
+    /* XTheadBs */
+    rv_op_th_tst,
+    /* XTheadCmo */
+    rv_op_th_dcache_call,
+    rv_op_th_dcache_ciall,
+    rv_op_th_dcache_iall,
+    rv_op_th_dcache_cpa,
+    rv_op_th_dcache_cipa,
+    rv_op_th_dcache_ipa,
+    rv_op_th_dcache_cva,
+    rv_op_th_dcache_civa,
+    rv_op_th_dcache_iva,
+    rv_op_th_dcache_csw,
+    rv_op_th_dcache_cisw,
+    rv_op_th_dcache_isw,
+    rv_op_th_dcache_cpal1,
+    rv_op_th_dcache_cval1,
+    rv_op_th_icache_iall,
+    rv_op_th_icache_ialls,
+    rv_op_th_icache_ipa,
+    rv_op_th_icache_iva,
+    rv_op_th_l2cache_call,
+    rv_op_th_l2cache_ciall,
+    rv_op_th_l2cache_iall,
+    /* XTheadCondMov */
+    rv_op_th_mveqz,
+    rv_op_th_mvnez,
+    /* XTheadFMemIdx */
+    rv_op_th_flrd,
+    rv_op_th_flrw,
+    rv_op_th_flurd,
+    rv_op_th_flurw,
+    rv_op_th_fsrd,
+    rv_op_th_fsrw,
+    rv_op_th_fsurd,
+    rv_op_th_fsurw,
+    /* XTheadFmv */
+    rv_op_th_fmv_hw_x,
+    rv_op_th_fmv_x_hw,
+    /* XTheadMac */
+    rv_op_th_mula,
+    rv_op_th_mulah,
+    rv_op_th_mulaw,
+    rv_op_th_muls,
+    rv_op_th_mulsw,
+    rv_op_th_mulsh,
+    /* XTheadMemIdx */
+    rv_op_th_lbia,
+    rv_op_th_lbib,
+    rv_op_th_lbuia,
+    rv_op_th_lbuib,
+    rv_op_th_lhia,
+    rv_op_th_lhib,
+    rv_op_th_lhuia,
+    rv_op_th_lhuib,
+    rv_op_th_lwia,
+    rv_op_th_lwib,
+    rv_op_th_lwuia,
+    rv_op_th_lwuib,
+    rv_op_th_ldia,
+    rv_op_th_ldib,
+    rv_op_th_sbia,
+    rv_op_th_sbib,
+    rv_op_th_shia,
+    rv_op_th_shib,
+    rv_op_th_swia,
+    rv_op_th_swib,
+    rv_op_th_sdia,
+    rv_op_th_sdib,
+    rv_op_th_lrb,
+    rv_op_th_lrbu,
+    rv_op_th_lrh,
+    rv_op_th_lrhu,
+    rv_op_th_lrw,
+    rv_op_th_lrwu,
+    rv_op_th_lrd,
+    rv_op_th_srb,
+    rv_op_th_srh,
+    rv_op_th_srw,
+    rv_op_th_srd,
+    rv_op_th_lurb,
+    rv_op_th_lurbu,
+    rv_op_th_lurh,
+    rv_op_th_lurhu,
+    rv_op_th_lurw,
+    rv_op_th_lurwu,
+    rv_op_th_lurd,
+    rv_op_th_surb,
+    rv_op_th_surh,
+    rv_op_th_surw,
+    rv_op_th_surd,
+    /* XTheadMemPair */
+    rv_op_th_ldd,
+    rv_op_th_lwd,
+    rv_op_th_lwud,
+    rv_op_th_sdd,
+    rv_op_th_swd,
+    /* XTheadSync */
+    rv_op_th_sfence_vmas,
+    rv_op_th_sync,
+    rv_op_th_sync_i,
+    rv_op_th_sync_is,
+    rv_op_th_sync_s,
+} rv_xthead_op;
+
+const rv_opcode_data xthead_opcode_data[] = {
+    { "th.illegal", rv_codec_illegal, rv_fmt_none, NULL, 0, 0, 0 },
+    /* XTheadBa */
+    { "th.addsl", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
+    /* XTheadBb */
+    { "th.srri", rv_codec_r2_imm6, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
+    { "th.srriw", rv_codec_r2_imm5, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
+    { "th.ext", rv_codec_r2_immhl, rv_fmt_rd_rs1_immh_imml, NULL, 0, 0, 0 },
+    { "th.extu", rv_codec_r2_immhl, rv_fmt_rd_rs1_immh_imml, NULL, 0, 0, 0 },
+    { "th.ff0", rv_codec_r2, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
+    { "th.ff1", rv_codec_r2, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
+    { "th.rev", rv_codec_r2, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
+    { "th.revw", rv_codec_r2, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
+    { "th.tstnbz", rv_codec_r2, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
+    /* XTheadBs */
+    { "th.tst", rv_codec_r2_imm6, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
+    /* XTheadCmo */
+    { "th.dcache.call", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
+    { "th.dcache.ciall", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
+    { "th.dcache.iall", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
+    { "th.dcache.cpa", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 },
+    { "th.dcache.cipa", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 },
+    { "th.dcache.ipa", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 },
+    { "th.dcache.cva", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 },
+    { "th.dcache.civa", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 },
+    { "th.dcache.iva", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 },
+    { "th.dcache.csw", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 },
+    { "th.dcache.cisw", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 },
+    { "th.dcache.isw", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 },
+    { "th.dcache.cpal1", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 },
+    { "th.dcache.cval1", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 },
+    { "th.icache.iall", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
+    { "th.icache.ialls", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
+    { "th.icache.ipa", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 },
+    { "th.icache.iva", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 },
+    { "th.l2cache.call", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
+    { "th.l2cache.ciall", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
+    { "th.l2cache.iall", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
+    /* XTheadCondMov */
+    { "th.mveqz", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
+    { "th.mvnez", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
+    /* XTheadFMemIdx */
+    { "th.flrd", rv_codec_r_imm2, rv_fmt_frd_rs1_rs2_imm, NULL, 0, 0, 0 },
+    { "th.flrw", rv_codec_r_imm2, rv_fmt_frd_rs1_rs2_imm, NULL, 0, 0, 0 },
+    { "th.flurd", rv_codec_r_imm2, rv_fmt_frd_rs1_rs2_imm, NULL, 0, 0, 0 },
+    { "th.flurw", rv_codec_r_imm2, rv_fmt_frd_rs1_rs2_imm, NULL, 0, 0, 0 },
+    { "th.fsrd", rv_codec_r_imm2, rv_fmt_frd_rs1_rs2_imm, NULL, 0, 0, 0 },
+    { "th.fsrw", rv_codec_r_imm2, rv_fmt_frd_rs1_rs2_imm, NULL, 0, 0, 0 },
+    { "th.fsurd", rv_codec_r_imm2, rv_fmt_frd_rs1_rs2_imm, NULL, 0, 0, 0 },
+    { "th.fsurw", rv_codec_r_imm2, rv_fmt_frd_rs1_rs2_imm, NULL, 0, 0, 0 },
+    /* XTheadFmv */
+    { "th.fmv.hw.x", rv_codec_r, rv_fmt_rd_frs1, NULL, 0, 0, 0 },
+    { "th.fmv.x.hw", rv_codec_r, rv_fmt_rd_frs1, NULL, 0, 0, 0 },
+    /* XTheadMac */
+    { "th.mula", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
+    { "th.mulaw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
+    { "th.mulah", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
+    { "th.muls", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
+    { "th.mulsw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
+    { "th.mulsh", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
+    /* XTheadMemIdx */
+    { "th.lbia", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
+    { "th.lbib", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml, NULL, 0, 0, 0 },
+    { "th.lbuia", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
+    { "th.lbuib", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
+    { "th.lhia", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
+    { "th.lhib", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
+    { "th.lhuia", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
+    { "th.lhuib", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
+    { "th.lwia", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
+    { "th.lwib", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
+    { "th.lwuia", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
+    { "th.lwuib", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
+    { "th.ldia", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
+    { "th.ldib", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
+    { "th.sbia", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
+    { "th.sbib", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
+    { "th.shia", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
+    { "th.shib", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
+    { "th.swia", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
+    { "th.swib", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
+    { "th.sdia", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
+    { "th.sdib", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
+    { "th.lrb", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
+    { "th.lrbu", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
+    { "th.lrh", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
+    { "th.lrhu", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
+    { "th.lrw", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
+    { "th.lrwu", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
+    { "th.lrd", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
+    { "th.srb", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
+    { "th.srh", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
+    { "th.srw", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
+    { "th.srd", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
+    { "th.lurb", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
+    { "th.lurbu", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
+    { "th.lurh", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
+    { "th.lurhu", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
+    { "th.lurw", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
+    { "th.lurwu", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
+    { "th.lurd", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
+    { "th.surb", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
+    { "th.surh", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
+    { "th.surw", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
+    { "th.surd", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
+    /* XTheadMemPair */
+    { "th.ldd", rv_codec_r_imm2, rv_fmt_rd2_imm, NULL, 0, 0, 0 },
+    { "th.lwd", rv_codec_r_imm2, rv_fmt_rd2_imm, NULL, 0, 0, 0 },
+    { "th.lwud", rv_codec_r_imm2, rv_fmt_rd2_imm, NULL, 0, 0, 0 },
+    { "th.sdd", rv_codec_r_imm2, rv_fmt_rd2_imm, NULL, 0, 0, 0 },
+    { "th.swd", rv_codec_r_imm2, rv_fmt_rd2_imm, NULL, 0, 0, 0 },
+    /* XTheadSync */
+    { "th.sfence.vmas", rv_codec_r, rv_fmt_rs1_rs2, NULL, 0, 0, 0 },
+    { "th.sync", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
+    { "th.sync.i", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
+    { "th.sync.is", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
+    { "th.sync.s", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
+};
+
+void decode_xtheadba(rv_decode *dec, rv_isa isa)
+{
+    rv_inst inst = dec->inst;
+    rv_opcode op = rv_op_illegal;
+
+    switch (((inst >> 0) & 0b11)) {
+    case 3:
+        switch (((inst >> 2) & 0b11111)) {
+        case 2:
+            /* custom-0 */
+            switch ((inst >> 12) & 0b111) {
+            case 1:
+                switch ((inst >> 25) & 0b1111111) {
+                case 0b0000000:
+                case 0b0000001:
+                case 0b0000010:
+                case 0b0000011: op = rv_op_th_addsl; break;
+                }
+                break;
+            }
+            break;
+            /* custom-0 */
+        }
+        break;
+    }
+
+    dec->op = op;
+}
+
+void decode_xtheadbb(rv_decode *dec, rv_isa isa)
+{
+    rv_inst inst = dec->inst;
+    rv_opcode op = rv_op_illegal;
+
+    switch (((inst >> 0) & 0b11)) {
+    case 3:
+        switch (((inst >> 2) & 0b11111)) {
+        case 2:
+            /* custom-0 */
+            switch ((inst >> 12) & 0b111) {
+            case 1:
+                switch ((inst >> 25) & 0b1111111) {
+                case 0b0001010: op = rv_op_th_srriw; break;
+                case 0b1000000:
+                    if (((inst >> 20) & 0b11111) == 0) {
+                        op = rv_op_th_tstnbz;
+                    }
+                    break;
+                case 0b1000001:
+                    if (((inst >> 20) & 0b11111) == 0) {
+                        op = rv_op_th_rev;
+                    }
+                    break;
+                case 0b1000010:
+                    if (((inst >> 20) & 0b11111) == 0) {
+                        op = rv_op_th_ff0;
+                    }
+                    break;
+                case 0b1000011:
+                    if (((inst >> 20) & 0b11111) == 0) {
+                        op = rv_op_th_ff1;
+                    }
+                    break;
+                case 0b1000100:
+                case 0b1001000:
+                    if (((inst >> 20) & 0b11111) == 0) {
+                        op = rv_op_th_revw;
+                    }
+                    break;
+                case 0b0000100:
+                case 0b0000101: op = rv_op_th_srri; break;
+                }
+                break;
+            case 2: op = rv_op_th_ext; break;
+            case 3: op = rv_op_th_extu; break;
+            }
+            break;
+            /* custom-0 */
+        }
+        break;
+    }
+
+    dec->op = op;
+}
+
+void decode_xtheadbs(rv_decode *dec, rv_isa isa)
+{
+    rv_inst inst = dec->inst;
+    rv_opcode op = rv_op_illegal;
+
+    switch (((inst >> 0) & 0b11)) {
+    case 3:
+        switch (((inst >> 2) & 0b11111)) {
+        case 2:
+            /* custom-0 */
+            switch ((inst >> 12) & 0b111) {
+            case 1:
+                switch ((inst >> 26) & 0b111111) {
+                case 0b100010: op = rv_op_th_tst; break;
+                }
+                break;
+            }
+            break;
+            /* custom-0 */
+        }
+        break;
+    }
+
+    dec->op = op;
+}
+
+void decode_xtheadcmo(rv_decode *dec, rv_isa isa)
+{
+    rv_inst inst = dec->inst;
+    rv_opcode op = rv_op_illegal;
+
+    switch (((inst >> 0) & 0b11)) {
+    case 3:
+        switch (((inst >> 2) & 0b11111)) {
+        case 2:
+            /* custom-0 */
+            switch ((inst >> 12) & 0b111) {
+            case 0:
+                switch ((inst >> 20 & 0b111111111111)) {
+                case 0b000000000001:
+                    if (((inst >> 20) & 0b11111) == 0) {
+                        op = rv_op_th_dcache_call;
+                    }
+                    break;
+                case 0b000000000011:
+                    if (((inst >> 20) & 0b11111) == 0) {
+                        op = rv_op_th_dcache_ciall;
+                    }
+                    break;
+                case 0b000000000010:
+                    if (((inst >> 20) & 0b11111) == 0) {
+                        op = rv_op_th_dcache_iall;
+                    }
+                    break;
+                case 0b000000101001: op = rv_op_th_dcache_cpa; break;
+                case 0b000000101011: op = rv_op_th_dcache_cipa; break;
+                case 0b000000101010: op = rv_op_th_dcache_ipa; break;
+                case 0b000000100101: op = rv_op_th_dcache_cva; break;
+                case 0b000000100111: op = rv_op_th_dcache_civa; break;
+                case 0b000000100110: op = rv_op_th_dcache_iva; break;
+                case 0b000000100001: op = rv_op_th_dcache_csw; break;
+                case 0b000000100011: op = rv_op_th_dcache_cisw; break;
+                case 0b000000100010: op = rv_op_th_dcache_isw; break;
+                case 0b000000101000: op = rv_op_th_dcache_cpal1; break;
+                case 0b000000100100: op = rv_op_th_dcache_cval1; break;
+                case 0b000000010000:
+                    if (((inst >> 20) & 0b11111) == 0) {
+                        op = rv_op_th_icache_iall;
+                    }
+                    break;
+                case 0b000000010001:
+                    if (((inst >> 20) & 0b11111) == 0) {
+                        op = rv_op_th_icache_ialls;
+                    }
+                    break;
+                case 0b000000111000: op = rv_op_th_icache_ipa; break;
+                case 0b000000110000: op = rv_op_th_icache_iva; break;
+                case 0b000000010101:
+                    if (((inst >> 20) & 0b11111) == 0) {
+                        op = rv_op_th_l2cache_call;
+                    }
+                    break;
+                case 0b000000010111:
+                    if (((inst >> 20) & 0b11111) == 0) {
+                        op = rv_op_th_l2cache_ciall;
+                    }
+                    break;
+                case 0b000000010110:
+                    if (((inst >> 20) & 0b11111) == 0) {
+                        op = rv_op_th_l2cache_iall;
+                    }
+                    break;
+                }
+                break;
+            }
+            break;
+            /* custom-0 */
+        }
+        break;
+    }
+
+    dec->op = op;
+}
+
+void decode_xtheadcondmov(rv_decode *dec, rv_isa isa)
+{
+    rv_inst inst = dec->inst;
+    rv_opcode op = rv_op_illegal;
+
+    switch (((inst >> 0) & 0b11)) {
+    case 3:
+        switch (((inst >> 2) & 0b11111)) {
+        case 2:
+            /* custom-0 */
+            switch ((inst >> 12) & 0b111) {
+            case 1:
+                switch ((inst >> 25) & 0b1111111) {
+                case 0b0100000: op = rv_op_th_mveqz; break;
+                case 0b0100001: op = rv_op_th_mvnez; break;
+                }
+                break;
+            }
+            break;
+            /* custom-0 */
+        }
+        break;
+    }
+
+    dec->op = op;
+}
+
+void decode_xtheadfmemidx(rv_decode *dec, rv_isa isa)
+{
+    rv_inst inst = dec->inst;
+    rv_opcode op = rv_op_illegal;
+
+    switch (((inst >> 0) & 0b11)) {
+    case 3:
+        switch (((inst >> 2) & 0b11111)) {
+        case 2:
+            /* custom-0 */
+            switch ((inst >> 12) & 0b111) {
+            case 6:
+                switch ((inst >> 27) & 0b11111) {
+                case 8: op = rv_op_th_flrw; break;
+                case 10: op = rv_op_th_flurw; break;
+                case 12: op = rv_op_th_flrd; break;
+                case 14: op = rv_op_th_flurd; break;
+                }
+                break;
+            case 7:
+                switch ((inst >> 27) & 0b11111) {
+                case 8: op = rv_op_th_fsrw; break;
+                case 10: op = rv_op_th_fsurw; break;
+                case 12: op = rv_op_th_fsrd; break;
+                case 14: op = rv_op_th_fsurd; break;
+                }
+                break;
+            }
+            break;
+            /* custom-0 */
+        }
+        break;
+    }
+
+    dec->op = op;
+}
+
+void decode_xtheadfmv(rv_decode *dec, rv_isa isa)
+{
+    rv_inst inst = dec->inst;
+    rv_opcode op = rv_op_illegal;
+
+    switch (((inst >> 0) & 0b11)) {
+    case 3:
+        switch (((inst >> 2) & 0b11111)) {
+        case 2:
+            /* custom-0 */
+            switch ((inst >> 12) & 0b111) {
+            case 1:
+                switch ((inst >> 25) & 0b1111111) {
+                case 0b1010000:
+                    if (((inst >> 20) & 0b11111) == 0) {
+                        op = rv_op_th_fmv_hw_x;
+                    }
+                    break;
+                case 0b1100000:
+                    if (((inst >> 20) & 0b11111) == 0) {
+                        op = rv_op_th_fmv_x_hw;
+                    }
+                    break;
+                }
+                break;
+            }
+            break;
+            /* custom-0 */
+        }
+        break;
+    }
+
+    dec->op = op;
+}
+
+void decode_xtheadmac(rv_decode *dec, rv_isa isa)
+{
+    rv_inst inst = dec->inst;
+    rv_opcode op = rv_op_illegal;
+
+    switch (((inst >> 0) & 0b11)) {
+    case 3:
+        switch (((inst >> 2) & 0b11111)) {
+        case 2:
+            /* custom-0 */
+            switch ((inst >> 12) & 0b111) {
+            case 1:
+                switch ((inst >> 25) & 0b1111111) {
+                case 0b0010000: op = rv_op_th_mula; break;
+                case 0b0010001: op = rv_op_th_muls; break;
+                case 0b0010010: op = rv_op_th_mulaw; break;
+                case 0b0010011: op = rv_op_th_mulsw; break;
+                case 0b0010100: op = rv_op_th_mulah; break;
+                case 0b0010101: op = rv_op_th_mulsh; break;
+                }
+                break;
+            }
+            break;
+            /* custom-0 */
+        }
+        break;
+    }
+
+    dec->op = op;
+}
+
+void decode_xtheadmemidx(rv_decode *dec, rv_isa isa)
+{
+    rv_inst inst = dec->inst;
+    rv_opcode op = rv_op_illegal;
+
+    switch (((inst >> 0) & 0b11)) {
+    case 3:
+        switch (((inst >> 2) & 0b11111)) {
+        case 2:
+            /* custom-0 */
+            switch ((inst >> 12) & 0b111) {
+            case 4:
+                switch ((inst >> 27) & 0b11111) {
+                case 0: op = rv_op_th_lrb; break;
+                case 1: op = rv_op_th_lbib; break;
+                case 2: op = rv_op_th_lurb; break;
+                case 3: op = rv_op_th_lbia; break;
+                case 4: op = rv_op_th_lrh; break;
+                case 5: op = rv_op_th_lhib; break;
+                case 6: op = rv_op_th_lurh; break;
+                case 7: op = rv_op_th_lhia; break;
+                case 8: op = rv_op_th_lrw; break;
+                case 9: op = rv_op_th_lwib; break;
+                case 10: op = rv_op_th_lurw; break;
+                case 11: op = rv_op_th_lwia; break;
+                case 12: op = rv_op_th_lrd; break;
+                case 13: op = rv_op_th_ldib; break;
+                case 14: op = rv_op_th_lurd; break;
+                case 15: op = rv_op_th_ldia; break;
+                case 16: op = rv_op_th_lrbu; break;
+                case 17: op = rv_op_th_lbuib; break;
+                case 18: op = rv_op_th_lurbu; break;
+                case 19: op = rv_op_th_lbuia; break;
+                case 20: op = rv_op_th_lrhu; break;
+                case 21: op = rv_op_th_lhuib; break;
+                case 22: op = rv_op_th_lurhu; break;
+                case 23: op = rv_op_th_lhuia; break;
+                case 24: op = rv_op_th_lrwu; break;
+                case 25: op = rv_op_th_lwuib; break;
+                case 26: op = rv_op_th_lurwu; break;
+                case 27: op = rv_op_th_lwuia; break;
+                }
+                break;
+            case 5:
+                switch ((inst >> 27) & 0b11111) {
+                case 0: op = rv_op_th_srb; break;
+                case 1: op = rv_op_th_sbib; break;
+                case 2: op = rv_op_th_surb; break;
+                case 3: op = rv_op_th_sbia; break;
+                case 4: op = rv_op_th_srh; break;
+                case 5: op = rv_op_th_shib; break;
+                case 6: op = rv_op_th_surh; break;
+                case 7: op = rv_op_th_shia; break;
+                case 8: op = rv_op_th_srw; break;
+                case 9: op = rv_op_th_swib; break;
+                case 10: op = rv_op_th_surw; break;
+                case 11: op = rv_op_th_swia; break;
+                case 12: op = rv_op_th_srd; break;
+                case 13: op = rv_op_th_sdib; break;
+                case 14: op = rv_op_th_surd; break;
+                case 15: op = rv_op_th_sdia; break;
+                }
+                break;
+                break;
+            }
+            break;
+            /* custom-0 */
+        }
+        break;
+    }
+
+    dec->op = op;
+}
+
+void decode_xtheadmempair(rv_decode *dec, rv_isa isa)
+{
+    rv_inst inst = dec->inst;
+    rv_opcode op = rv_op_illegal;
+
+    switch (((inst >> 0) & 0b11)) {
+    case 3:
+        switch (((inst >> 2) & 0b11111)) {
+        case 2:
+            /* custom-0 */
+            switch ((inst >> 12) & 0b111) {
+            case 4:
+                switch ((inst >> 27) & 0b11111) {
+                case 28: op = rv_op_th_lwd; break;
+                case 30: op = rv_op_th_lwud; break;
+                case 31: op = rv_op_th_ldd; break;
+                }
+                break;
+            case 5:
+                switch ((inst >> 27) & 0b11111) {
+                case 28: op = rv_op_th_swd; break;
+                case 31: op = rv_op_th_sdd; break;
+                }
+                break;
+            }
+            break;
+            /* custom-0 */
+        }
+        break;
+    }
+
+    dec->op = op;
+}
+
+void decode_xtheadsync(rv_decode *dec, rv_isa isa)
+{
+    rv_inst inst = dec->inst;
+    rv_opcode op = rv_op_illegal;
+
+    switch (((inst >> 0) & 0b11)) {
+    case 3:
+        switch (((inst >> 2) & 0b11111)) {
+        case 2:
+            /* custom-0 */
+            switch ((inst >> 12) & 0b111) {
+            case 0:
+                switch ((inst >> 25) & 0b1111111) {
+                case 0b0000010: op = rv_op_th_sfence_vmas; break;
+                case 0b0000000:
+                    switch ((inst >> 20) & 0b11111) {
+                    case 0b11000: op = rv_op_th_sync; break;
+                    case 0b11010: op = rv_op_th_sync_i; break;
+                    case 0b11011: op = rv_op_th_sync_is; break;
+                    case 0b11001: op = rv_op_th_sync_s; break;
+                    }
+                    break;
+                }
+                break;
+            }
+            break;
+            /* custom-0 */
+        }
+        break;
+    }
+
+    dec->op = op;
+}
diff --git a/disas/riscv-xthead.h b/disas/riscv-xthead.h
new file mode 100644
index 0000000000..fcd42746e7
--- /dev/null
+++ b/disas/riscv-xthead.h
@@ -0,0 +1,28 @@
+/*
+ * QEMU disassembler -- RISC-V specific header (xthead*).
+ *
+ * Copyright (c) 2023 VRULL GmbH
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef DISAS_RISCV_XTHEAD_H
+#define DISAS_RISCV_XTHEAD_H
+
+#include "disas/riscv.h"
+
+extern const rv_opcode_data xthead_opcode_data[];
+
+void decode_xtheadba(rv_decode *, rv_isa);
+void decode_xtheadbb(rv_decode *, rv_isa);
+void decode_xtheadbs(rv_decode *, rv_isa);
+void decode_xtheadcmo(rv_decode *, rv_isa);
+void decode_xtheadcondmov(rv_decode *, rv_isa);
+void decode_xtheadfmemidx(rv_decode *, rv_isa);
+void decode_xtheadfmv(rv_decode *, rv_isa);
+void decode_xtheadmac(rv_decode *, rv_isa);
+void decode_xtheadmemidx(rv_decode *, rv_isa);
+void decode_xtheadmempair(rv_decode *, rv_isa);
+void decode_xtheadsync(rv_decode *, rv_isa);
+
+#endif /* DISAS_RISCV_XTHEAD_H */
diff --git a/disas/riscv.c b/disas/riscv.c
index 4f71333c45..b1a30928df 100644
--- a/disas/riscv.c
+++ b/disas/riscv.c
@@ -18,11 +18,13 @@
  */
 
 #include "qemu/osdep.h"
+#include "qemu/bitops.h"
 #include "disas/dis-asm.h"
 #include "disas/riscv.h"
 #include "target/riscv/cpu-config.h"
 
 /* Vendor extensions */
+#include "disas/riscv-xthead.h"
 #include "disas/riscv-xventana.h"
 
 typedef enum {
@@ -3784,6 +3786,26 @@ static uint32_t operand_zcmp_rlist(rv_inst inst)
     return ((inst << 56) >> 60);
 }
 
+static uint32_t operand_imm6(rv_inst inst)
+{
+    return (inst << 38) >> 60;
+}
+
+static uint32_t operand_imm2(rv_inst inst)
+{
+    return (inst << 37) >> 62;
+}
+
+static uint32_t operand_immh(rv_inst inst)
+{
+    return (inst << 32) >> 58;
+}
+
+static uint32_t operand_imml(rv_inst inst)
+{
+    return (inst << 38) >> 58;
+}
+
 static uint32_t calculate_stack_adj(rv_isa isa, uint32_t rlist, uint32_t spimm)
 {
     int xlen_bytes_log2 = isa == rv64 ? 3 : 2;
@@ -4148,6 +4170,38 @@ static void decode_inst_operands(rv_decode *dec, rv_isa isa)
     case rv_codec_zcmt_jt:
         dec->imm = operand_tbl_index(inst);
         break;
+    case rv_codec_r2_imm5:
+        dec->rd = operand_rd(inst);
+        dec->rs1 = operand_rs1(inst);
+        dec->imm = operand_rs2(inst);
+        break;
+    case rv_codec_r2:
+        dec->rd = operand_rd(inst);
+        dec->rs1 = operand_rs1(inst);
+        break;
+    case rv_codec_r2_imm6:
+        dec->rd = operand_rd(inst);
+        dec->rs1 = operand_rs1(inst);
+        dec->imm = operand_imm6(inst);
+        break;
+    case rv_codec_r_imm2:
+        dec->rd = operand_rd(inst);
+        dec->rs1 = operand_rs1(inst);
+        dec->rs2 = operand_rs2(inst);
+        dec->imm = operand_imm2(inst);
+        break;
+    case rv_codec_r2_immhl:
+        dec->rd = operand_rd(inst);
+        dec->rs1 = operand_rs1(inst);
+        dec->imm = operand_immh(inst);
+        dec->imm1 = operand_imml(inst);
+        break;
+    case rv_codec_r2_imm2_imm5:
+        dec->rd = operand_rd(inst);
+        dec->rs1 = operand_rs1(inst);
+        dec->imm = sextract32(operand_rs2(inst), 0, 5);
+        dec->imm1 = operand_imm2(inst);
+        break;
     };
 }
 
@@ -4352,6 +4406,10 @@ static void format_inst(char *buf, size_t buflen, size_t tab, rv_decode *dec)
             snprintf(tmp, sizeof(tmp), "%u", ((uint32_t)dec->imm & 0b11111));
             append(buf, tmp, buflen);
             break;
+        case 'j':
+            snprintf(tmp, sizeof(tmp), "%d", dec->imm1);
+            append(buf, tmp, buflen);
+            break;
         case 'o':
             snprintf(tmp, sizeof(tmp), "%d", dec->imm);
             append(buf, tmp, buflen);
@@ -4617,6 +4675,17 @@ disasm_inst(char *buf, size_t buflen, rv_isa isa, uint64_t pc, rv_inst inst,
         void (*decode_func)(rv_decode *, rv_isa);
     } decoders[] = {
         { always_true_p, rvi_opcode_data, decode_inst_opcode },
+        { has_xtheadba_p, xthead_opcode_data, decode_xtheadba },
+        { has_xtheadbb_p, xthead_opcode_data, decode_xtheadbb },
+        { has_xtheadbs_p, xthead_opcode_data, decode_xtheadbs },
+        { has_xtheadcmo_p, xthead_opcode_data, decode_xtheadcmo },
+        { has_xtheadcondmov_p, xthead_opcode_data, decode_xtheadcondmov },
+        { has_xtheadfmemidx_p, xthead_opcode_data, decode_xtheadfmemidx },
+        { has_xtheadfmv_p, xthead_opcode_data, decode_xtheadfmv },
+        { has_xtheadmac_p, xthead_opcode_data, decode_xtheadmac },
+        { has_xtheadmemidx_p, xthead_opcode_data, decode_xtheadmemidx },
+        { has_xtheadmempair_p, xthead_opcode_data, decode_xtheadmempair },
+        { has_xtheadsync_p, xthead_opcode_data, decode_xtheadsync },
         { has_XVentanaCondOps_p, ventana_opcode_data, decode_xventanacondops },
     };
 
diff --git a/disas/riscv.h b/disas/riscv.h
index 188f03feeb..f7ece1bb53 100644
--- a/disas/riscv.h
+++ b/disas/riscv.h
@@ -158,6 +158,12 @@ typedef enum {
     rv_codec_zcmp_cm_pushpop,
     rv_codec_zcmp_cm_mv,
     rv_codec_zcmt_jt,
+    rv_codec_r2_imm5,
+    rv_codec_r2,
+    rv_codec_r2_imm6,
+    rv_codec_r_imm2,
+    rv_codec_r2_immhl,
+    rv_codec_r2_imm2_imm5,
 } rv_codec;
 
 /* structures */
@@ -183,6 +189,7 @@ typedef struct {
     uint64_t  inst;
     const rv_opcode_data *opcode_data;
     int32_t   imm;
+    int32_t   imm1;
     uint16_t  op;
     uint8_t   codec;
     uint8_t   rd;
@@ -281,5 +288,10 @@ enum {
 #define rv_fmt_push_rlist             "O\tx,-i"
 #define rv_fmt_pop_rlist              "O\tx,i"
 #define rv_fmt_zcmt_index             "O\ti"
+#define rv_fmt_rd_rs1_rs2_imm         "O\t0,1,2,i"
+#define rv_fmt_frd_rs1_rs2_imm        "O\t3,1,2,i"
+#define rv_fmt_rd_rs1_immh_imml       "O\t0,1,i,j"
+#define rv_fmt_rd_rs1_immh_imml_addr  "O\t0,(1),i,j"
+#define rv_fmt_rd2_imm                "O\t0,2,(1),i"
 
 #endif /* DISAS_RISCV_H */
diff --git a/target/riscv/cpu-config.h b/target/riscv/cpu-config.h
index ca368af0b2..ae7c1a44ff 100644
--- a/target/riscv/cpu-config.h
+++ b/target/riscv/cpu-config.h
@@ -143,6 +143,17 @@ static inline bool has_xthead_p(const RISCVCPUConfig *cfg)
         return cfg->ext_ ## ext ; \
     }
 
+MATERIALISE_EXT_PREDICATE(xtheadba)
+MATERIALISE_EXT_PREDICATE(xtheadbb)
+MATERIALISE_EXT_PREDICATE(xtheadbs)
+MATERIALISE_EXT_PREDICATE(xtheadcmo)
+MATERIALISE_EXT_PREDICATE(xtheadcondmov)
+MATERIALISE_EXT_PREDICATE(xtheadfmemidx)
+MATERIALISE_EXT_PREDICATE(xtheadfmv)
+MATERIALISE_EXT_PREDICATE(xtheadmac)
+MATERIALISE_EXT_PREDICATE(xtheadmemidx)
+MATERIALISE_EXT_PREDICATE(xtheadmempair)
+MATERIALISE_EXT_PREDICATE(xtheadsync)
 MATERIALISE_EXT_PREDICATE(XVentanaCondOps)
 
 #endif /* RISCV_CPU_CONFIG_H */
-- 
2.40.1



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

* Re: [PATCH 0/9] disas/riscv: Add vendor extension support
  2023-05-30 13:18 [PATCH 0/9] disas/riscv: Add vendor extension support Christoph Muellner
                   ` (8 preceding siblings ...)
  2023-05-30 13:18 ` [PATCH 9/9] disas/riscv: Add support for XThead* instructions Christoph Muellner
@ 2023-06-06 17:38 ` Daniel Henrique Barboza
  2023-06-12 11:17   ` Christoph Müllner
  9 siblings, 1 reply; 30+ messages in thread
From: Daniel Henrique Barboza @ 2023-06-06 17:38 UTC (permalink / raw)
  To: Christoph Muellner, qemu-riscv, qemu-devel, Alistair Francis,
	Bin Meng, Philipp Tomsich, Palmer Dabbelt, Richard Henderson,
	Zhiwei Liu

Hi,

Can you please rebase on top of Alistair's riscv-to-apply.next and re-send?

Some patches can't be applied cleanly, in particular patch 2, which conflicts
with Weiwei's "target/riscv: Split RISCVCPUConfig declarations from cpu.h
into cpu_cfg.h" that landed into riscv-to-apply.next a few weeks ago. In
this particular case patch 2 of this series would need to move just the
bits of target/ppc/translate.c to the already existing cpu_cfg.h file.


Put me in the CC when you re-send and I'll review it asap. Thanks,


Daniel

On 5/30/23 10:18, Christoph Muellner wrote:
> From: Christoph Müllner <christoph.muellner@vrull.eu>
> 
> This series adds vendor extension support to the QEMU disassembler
> for RISC-V. The following vendor extensions are covered:
> * XThead{Ba,Bb,Bs,Cmo,CondMov,FMemIdx,Fmv,Mac,MemIdx,MemPair,Sync}
> * XVentanaCondOps
> 
> So far, there have been two attempts to add vendor extension support
> to the QEMU disassembler. The first one [1] was posted in August 2022
> by LIU Zhiwei and attempts to separate vendor extension specifics
> from standard extension code in combination with a patch that introduced
> support for XVentanaCondOps. The second one [2] was posted in March 2023
> by me and added XThead* support without separating the vendor extensions
> from the standard code.
> 
> This patchset represents the third attempt to add vendor extension
> support to the QEMU disassembler. It adds all features of the previous
> attempts and integrates them into a patchset that uses the same
> mechanism for testing the extension availability like translate.c
> (using the booleans RISCVCPUConfig::ext_*).
> To achieve that, a couple of patches were needed to restructure
> the existing code.
> 
> Note, that this patchset allows an instruction encoder function for each
> vendor extension, but operand decoding and instruction printing remains
> common code. This is irrelevant for XVentanaCondOps, but the patch for
> the XThead* extensions includes changes in riscv.c and riscv.h.
> This could be changed to force more separation with the cost of
> duplication.
> 
> The first patch of this series is cherry-picked from LIU Zhiwei's series.
> It was reviewed by Alistair Francis and Richard Henderson, but never
> made it on master. I've added "Reviewed-by" tags to the commit.
> 
> I've added "Co-developed-by" tags to those commits that are derived
> from the series of LIU Zhiwei.
> 
> [1] https://lists.nongnu.org/archive/html/qemu-devel/2022-08/msg03662.html
> [2] https://lists.nongnu.org/archive/html/qemu-devel/2023-03/msg04566.html
> 
> Christoph Müllner (8):
>    target/riscv: Factor out RISCVCPUConfig from cpu.h
>    disas/riscv: Move types/constants to new header file
>    disas/riscv: Make rv_op_illegal a shared enum value
>    disas/riscv: Encapsulate opcode_data into decode
>    target/riscv/cpu: Share RISCVCPUConfig with disassembler
>    disas/riscv: Provide infrastructure for vendor extensions
>    disas/riscv: Add support for XVentanaCondOps
>    disas/riscv: Add support for XThead* instructions
> 
> LIU Zhiwei (1):
>    target/riscv: Use xl instead of mxl for disassemble
> 
>   disas/meson.build         |   6 +-
>   disas/riscv-xthead.c      | 707 ++++++++++++++++++++++++++++++++++++++
>   disas/riscv-xthead.h      |  28 ++
>   disas/riscv-xventana.c    |  41 +++
>   disas/riscv-xventana.h    |  18 +
>   disas/riscv.c             | 384 ++++++---------------
>   disas/riscv.h             | 297 ++++++++++++++++
>   target/riscv/cpu-config.h | 159 +++++++++
>   target/riscv/cpu.c        |   6 +-
>   target/riscv/cpu.h        | 114 +-----
>   target/riscv/translate.c  |  27 +-
>   11 files changed, 1374 insertions(+), 413 deletions(-)
>   create mode 100644 disas/riscv-xthead.c
>   create mode 100644 disas/riscv-xthead.h
>   create mode 100644 disas/riscv-xventana.c
>   create mode 100644 disas/riscv-xventana.h
>   create mode 100644 disas/riscv.h
>   create mode 100644 target/riscv/cpu-config.h
> 


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

* Re: [PATCH 7/9] disas/riscv: Provide infrastructure for vendor extensions
  2023-05-30 13:18 ` [PATCH 7/9] disas/riscv: Provide infrastructure for vendor extensions Christoph Muellner
@ 2023-06-08 13:04   ` LIU Zhiwei
  2023-06-12 11:11     ` Christoph Müllner
  2023-06-12  3:37   ` Alistair Francis
  1 sibling, 1 reply; 30+ messages in thread
From: LIU Zhiwei @ 2023-06-08 13:04 UTC (permalink / raw)
  To: Christoph Muellner, qemu-riscv, qemu-devel, Alistair Francis,
	Bin Meng, Philipp Tomsich, Palmer Dabbelt, Richard Henderson


On 2023/5/30 21:18, Christoph Muellner wrote:
> From: Christoph Müllner <christoph.muellner@vrull.eu>
>
> A previous patch provides a pointer to the RISCVCPUConfig data.
> Let's use this to add the necessary code for vendor extensions.
> This patch does not change the current behaviour, but clearly
> defines how vendor extension support can be added to the disassembler.
>
> Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
> ---
>   disas/riscv.c | 34 ++++++++++++++++++++++++++++++----
>   1 file changed, 30 insertions(+), 4 deletions(-)
>
> diff --git a/disas/riscv.c b/disas/riscv.c
> index 086edee6a2..db98e3ea6a 100644
> --- a/disas/riscv.c
> +++ b/disas/riscv.c
> @@ -20,6 +20,7 @@
>   #include "qemu/osdep.h"
>   #include "disas/dis-asm.h"
>   #include "disas/riscv.h"
> +#include "target/riscv/cpu-config.h"
>   
>   typedef enum {
>       /* 0 is reserved for rv_op_illegal. */
> @@ -4599,13 +4600,38 @@ static void decode_inst_decompress(rv_decode *dec, rv_isa isa)
>   /* disassemble instruction */
>   
>   static void
> -disasm_inst(char *buf, size_t buflen, rv_isa isa, uint64_t pc, rv_inst inst)
> +disasm_inst(char *buf, size_t buflen, rv_isa isa, uint64_t pc, rv_inst inst,
> +            struct disassemble_info *info)
>   {
> +    RISCVCPUConfig *cfg = info->private_data;
>       rv_decode dec = { 0 };
>       dec.pc = pc;
>       dec.inst = inst;
> -    dec.opcode_data = rvi_opcode_data;
> -    decode_inst_opcode(&dec, isa);
> +
> +    static const struct {
> +        bool (*guard_func)(const RISCVCPUConfig *);
> +        const rv_opcode_data *opcode_data;
> +        void (*decode_func)(rv_decode *, rv_isa);
> +    } decoders[] = {
> +        { always_true_p, rvi_opcode_data, decode_inst_opcode },
> +    };
> +
> +    for (size_t i = 0; i < ARRAY_SIZE(decoders); i++) {
> +        bool (*guard_func)(const RISCVCPUConfig *) = decoders[i].guard_func;
> +        const rv_opcode_data *opcode_data = decoders[i].opcode_data;
> +        void (*decode_func)(rv_decode *, rv_isa) = decoders[i].decode_func;
> +
> +        if (guard_func(cfg)) {
> +            dec.opcode_data = opcode_data;
> +            decode_func(&dec, isa);
> +            if (dec.op != rv_op_illegal)
> +                break;
> +        }
> +    }
> +
> +    if (dec.op == rv_op_illegal)
> +        dec.opcode_data = rvi_opcode_data;

Always enclose the if sentence.

Otherwise,

Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>

> +
>       decode_inst_operands(&dec, isa);
>       decode_inst_decompress(&dec, isa);
>       decode_inst_lift_pseudo(&dec);
> @@ -4659,7 +4685,7 @@ print_insn_riscv(bfd_vma memaddr, struct disassemble_info *info, rv_isa isa)
>           break;
>       }
>   
> -    disasm_inst(buf, sizeof(buf), isa, memaddr, inst);
> +    disasm_inst(buf, sizeof(buf), isa, memaddr, inst, info);
>       (*info->fprintf_func)(info->stream, "%s", buf);
>   
>       return len;


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

* Re: [PATCH 3/9] disas/riscv: Move types/constants to new header file
  2023-05-30 13:18 ` [PATCH 3/9] disas/riscv: Move types/constants to new header file Christoph Muellner
@ 2023-06-09  2:04   ` LIU Zhiwei
  2023-06-12  3:22   ` Alistair Francis
  1 sibling, 0 replies; 30+ messages in thread
From: LIU Zhiwei @ 2023-06-09  2:04 UTC (permalink / raw)
  To: Christoph Muellner, qemu-riscv, qemu-devel, Alistair Francis,
	Bin Meng, Philipp Tomsich, Palmer Dabbelt, Richard Henderson


On 2023/5/30 21:18, Christoph Muellner wrote:
> From: Christoph Müllner <christoph.muellner@vrull.eu>
>
> In order to enable vendor disassembler support, we need to
> move types and constants into a header file so that other
> compilation units can use them as well.
>
> This patch does not introduce any functional changes.
>
> Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>

Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>

Zhiwei

> ---
>   disas/riscv.c | 270 +-----------------------------------------------
>   disas/riscv.h | 280 ++++++++++++++++++++++++++++++++++++++++++++++++++
>   2 files changed, 281 insertions(+), 269 deletions(-)
>   create mode 100644 disas/riscv.h
>
> diff --git a/disas/riscv.c b/disas/riscv.c
> index d597161d46..a062fb48cc 100644
> --- a/disas/riscv.c
> +++ b/disas/riscv.c
> @@ -19,158 +19,7 @@
>   
>   #include "qemu/osdep.h"
>   #include "disas/dis-asm.h"
> -
> -
> -/* types */
> -
> -typedef uint64_t rv_inst;
> -typedef uint16_t rv_opcode;
> -
> -/* enums */
> -
> -typedef enum {
> -    rv32,
> -    rv64,
> -    rv128
> -} rv_isa;
> -
> -typedef enum {
> -    rv_rm_rne = 0,
> -    rv_rm_rtz = 1,
> -    rv_rm_rdn = 2,
> -    rv_rm_rup = 3,
> -    rv_rm_rmm = 4,
> -    rv_rm_dyn = 7,
> -} rv_rm;
> -
> -typedef enum {
> -    rv_fence_i = 8,
> -    rv_fence_o = 4,
> -    rv_fence_r = 2,
> -    rv_fence_w = 1,
> -} rv_fence;
> -
> -typedef enum {
> -    rv_ireg_zero,
> -    rv_ireg_ra,
> -    rv_ireg_sp,
> -    rv_ireg_gp,
> -    rv_ireg_tp,
> -    rv_ireg_t0,
> -    rv_ireg_t1,
> -    rv_ireg_t2,
> -    rv_ireg_s0,
> -    rv_ireg_s1,
> -    rv_ireg_a0,
> -    rv_ireg_a1,
> -    rv_ireg_a2,
> -    rv_ireg_a3,
> -    rv_ireg_a4,
> -    rv_ireg_a5,
> -    rv_ireg_a6,
> -    rv_ireg_a7,
> -    rv_ireg_s2,
> -    rv_ireg_s3,
> -    rv_ireg_s4,
> -    rv_ireg_s5,
> -    rv_ireg_s6,
> -    rv_ireg_s7,
> -    rv_ireg_s8,
> -    rv_ireg_s9,
> -    rv_ireg_s10,
> -    rv_ireg_s11,
> -    rv_ireg_t3,
> -    rv_ireg_t4,
> -    rv_ireg_t5,
> -    rv_ireg_t6,
> -} rv_ireg;
> -
> -typedef enum {
> -    rvc_end,
> -    rvc_rd_eq_ra,
> -    rvc_rd_eq_x0,
> -    rvc_rs1_eq_x0,
> -    rvc_rs2_eq_x0,
> -    rvc_rs2_eq_rs1,
> -    rvc_rs1_eq_ra,
> -    rvc_imm_eq_zero,
> -    rvc_imm_eq_n1,
> -    rvc_imm_eq_p1,
> -    rvc_csr_eq_0x001,
> -    rvc_csr_eq_0x002,
> -    rvc_csr_eq_0x003,
> -    rvc_csr_eq_0xc00,
> -    rvc_csr_eq_0xc01,
> -    rvc_csr_eq_0xc02,
> -    rvc_csr_eq_0xc80,
> -    rvc_csr_eq_0xc81,
> -    rvc_csr_eq_0xc82,
> -} rvc_constraint;
> -
> -typedef enum {
> -    rv_codec_illegal,
> -    rv_codec_none,
> -    rv_codec_u,
> -    rv_codec_uj,
> -    rv_codec_i,
> -    rv_codec_i_sh5,
> -    rv_codec_i_sh6,
> -    rv_codec_i_sh7,
> -    rv_codec_i_csr,
> -    rv_codec_s,
> -    rv_codec_sb,
> -    rv_codec_r,
> -    rv_codec_r_m,
> -    rv_codec_r4_m,
> -    rv_codec_r_a,
> -    rv_codec_r_l,
> -    rv_codec_r_f,
> -    rv_codec_cb,
> -    rv_codec_cb_imm,
> -    rv_codec_cb_sh5,
> -    rv_codec_cb_sh6,
> -    rv_codec_ci,
> -    rv_codec_ci_sh5,
> -    rv_codec_ci_sh6,
> -    rv_codec_ci_16sp,
> -    rv_codec_ci_lwsp,
> -    rv_codec_ci_ldsp,
> -    rv_codec_ci_lqsp,
> -    rv_codec_ci_li,
> -    rv_codec_ci_lui,
> -    rv_codec_ci_none,
> -    rv_codec_ciw_4spn,
> -    rv_codec_cj,
> -    rv_codec_cj_jal,
> -    rv_codec_cl_lw,
> -    rv_codec_cl_ld,
> -    rv_codec_cl_lq,
> -    rv_codec_cr,
> -    rv_codec_cr_mv,
> -    rv_codec_cr_jalr,
> -    rv_codec_cr_jr,
> -    rv_codec_cs,
> -    rv_codec_cs_sw,
> -    rv_codec_cs_sd,
> -    rv_codec_cs_sq,
> -    rv_codec_css_swsp,
> -    rv_codec_css_sdsp,
> -    rv_codec_css_sqsp,
> -    rv_codec_k_bs,
> -    rv_codec_k_rnum,
> -    rv_codec_v_r,
> -    rv_codec_v_ldst,
> -    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;
> +#include "disas/riscv.h"
>   
>   typedef enum {
>       rv_op_illegal = 0,
> @@ -966,50 +815,6 @@ typedef enum {
>       rv_op_czero_nez = 790,
>   } rv_op;
>   
> -/* structures */
> -
> -typedef struct {
> -    uint64_t  pc;
> -    uint64_t  inst;
> -    int32_t   imm;
> -    uint16_t  op;
> -    uint8_t   codec;
> -    uint8_t   rd;
> -    uint8_t   rs1;
> -    uint8_t   rs2;
> -    uint8_t   rs3;
> -    uint8_t   rm;
> -    uint8_t   pred;
> -    uint8_t   succ;
> -    uint8_t   aq;
> -    uint8_t   rl;
> -    uint8_t   bs;
> -    uint8_t   rnum;
> -    uint8_t   vm;
> -    uint32_t  vzimm;
> -    uint8_t   rlist;
> -} rv_decode;
> -
> -typedef struct {
> -    const int op;
> -    const rvc_constraint *constraints;
> -} rv_comp_data;
> -
> -enum {
> -    rvcd_imm_nz = 0x1
> -};
> -
> -typedef struct {
> -    const char * const name;
> -    const rv_codec codec;
> -    const char * const format;
> -    const rv_comp_data *pseudo;
> -    const short decomp_rv32;
> -    const short decomp_rv64;
> -    const short decomp_rv128;
> -    const short decomp_data;
> -} rv_opcode_data;
> -
>   /* register names */
>   
>   static const char rv_ireg_name_sym[32][5] = {
> @@ -1033,79 +838,6 @@ static const char rv_vreg_name_sym[32][4] = {
>       "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"
>   };
>   
> -/* instruction formats */
> -
> -#define rv_fmt_none                   "O\t"
> -#define rv_fmt_rs1                    "O\t1"
> -#define rv_fmt_offset                 "O\to"
> -#define rv_fmt_pred_succ              "O\tp,s"
> -#define rv_fmt_rs1_rs2                "O\t1,2"
> -#define rv_fmt_rd_imm                 "O\t0,i"
> -#define rv_fmt_rd_offset              "O\t0,o"
> -#define rv_fmt_rd_rs1_rs2             "O\t0,1,2"
> -#define rv_fmt_frd_rs1                "O\t3,1"
> -#define rv_fmt_frd_frs1               "O\t3,4"
> -#define rv_fmt_rd_frs1                "O\t0,4"
> -#define rv_fmt_rd_frs1_frs2           "O\t0,4,5"
> -#define rv_fmt_frd_frs1_frs2          "O\t3,4,5"
> -#define rv_fmt_rm_frd_frs1            "O\tr,3,4"
> -#define rv_fmt_rm_frd_rs1             "O\tr,3,1"
> -#define rv_fmt_rm_rd_frs1             "O\tr,0,4"
> -#define rv_fmt_rm_frd_frs1_frs2       "O\tr,3,4,5"
> -#define rv_fmt_rm_frd_frs1_frs2_frs3  "O\tr,3,4,5,6"
> -#define rv_fmt_rd_rs1_imm             "O\t0,1,i"
> -#define rv_fmt_rd_rs1_offset          "O\t0,1,i"
> -#define rv_fmt_rd_offset_rs1          "O\t0,i(1)"
> -#define rv_fmt_frd_offset_rs1         "O\t3,i(1)"
> -#define rv_fmt_rd_csr_rs1             "O\t0,c,1"
> -#define rv_fmt_rd_csr_zimm            "O\t0,c,7"
> -#define rv_fmt_rs2_offset_rs1         "O\t2,i(1)"
> -#define rv_fmt_frs2_offset_rs1        "O\t5,i(1)"
> -#define rv_fmt_rs1_rs2_offset         "O\t1,2,o"
> -#define rv_fmt_rs2_rs1_offset         "O\t2,1,o"
> -#define rv_fmt_aqrl_rd_rs2_rs1        "OAR\t0,2,(1)"
> -#define rv_fmt_aqrl_rd_rs1            "OAR\t0,(1)"
> -#define rv_fmt_rd                     "O\t0"
> -#define rv_fmt_rd_zimm                "O\t0,7"
> -#define rv_fmt_rd_rs1                 "O\t0,1"
> -#define rv_fmt_rd_rs2                 "O\t0,2"
> -#define rv_fmt_rs1_offset             "O\t1,o"
> -#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_ldst_vd_rs1_vm         "O\tD,(1)m"
> -#define rv_fmt_ldst_vd_rs1_rs2_vm     "O\tD,(1),2m"
> -#define rv_fmt_ldst_vd_rs1_vs2_vm     "O\tD,(1),Fm"
> -#define rv_fmt_vd_vs2_vs1             "O\tD,F,E"
> -#define rv_fmt_vd_vs2_vs1_vl          "O\tD,F,El"
> -#define rv_fmt_vd_vs2_vs1_vm          "O\tD,F,Em"
> -#define rv_fmt_vd_vs2_rs1_vl          "O\tD,F,1l"
> -#define rv_fmt_vd_vs2_fs1_vl          "O\tD,F,4l"
> -#define rv_fmt_vd_vs2_rs1_vm          "O\tD,F,1m"
> -#define rv_fmt_vd_vs2_fs1_vm          "O\tD,F,4m"
> -#define rv_fmt_vd_vs2_imm_vl          "O\tD,F,il"
> -#define rv_fmt_vd_vs2_imm_vm          "O\tD,F,im"
> -#define rv_fmt_vd_vs2_uimm_vm         "O\tD,F,um"
> -#define rv_fmt_vd_vs1_vs2_vm          "O\tD,E,Fm"
> -#define rv_fmt_vd_rs1_vs2_vm          "O\tD,1,Fm"
> -#define rv_fmt_vd_fs1_vs2_vm          "O\tD,4,Fm"
> -#define rv_fmt_vd_vs1                 "O\tD,E"
> -#define rv_fmt_vd_rs1                 "O\tD,1"
> -#define rv_fmt_vd_fs1                 "O\tD,4"
> -#define rv_fmt_vd_imm                 "O\tD,i"
> -#define rv_fmt_vd_vs2                 "O\tD,F"
> -#define rv_fmt_vd_vs2_vm              "O\tD,Fm"
> -#define rv_fmt_rd_vs2_vm              "O\t0,Fm"
> -#define rv_fmt_rd_vs2                 "O\t0,F"
> -#define rv_fmt_fd_vs2                 "O\t3,F"
> -#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 */
>   
>   static const rvc_constraint rvcc_jal[] = { rvc_rd_eq_ra, rvc_end };
> diff --git a/disas/riscv.h b/disas/riscv.h
> new file mode 100644
> index 0000000000..0f34b71518
> --- /dev/null
> +++ b/disas/riscv.h
> @@ -0,0 +1,280 @@
> +/*
> + * QEMU disassembler -- RISC-V specific header.
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#ifndef DISAS_RISCV_H
> +#define DISAS_RISCV_H
> +
> +#include "qemu/osdep.h"
> +
> +/* types */
> +
> +typedef uint64_t rv_inst;
> +typedef uint16_t rv_opcode;
> +
> +/* enums */
> +
> +typedef enum {
> +    rv32,
> +    rv64,
> +    rv128
> +} rv_isa;
> +
> +typedef enum {
> +    rv_rm_rne = 0,
> +    rv_rm_rtz = 1,
> +    rv_rm_rdn = 2,
> +    rv_rm_rup = 3,
> +    rv_rm_rmm = 4,
> +    rv_rm_dyn = 7,
> +} rv_rm;
> +
> +typedef enum {
> +    rv_fence_i = 8,
> +    rv_fence_o = 4,
> +    rv_fence_r = 2,
> +    rv_fence_w = 1,
> +} rv_fence;
> +
> +typedef enum {
> +    rv_ireg_zero,
> +    rv_ireg_ra,
> +    rv_ireg_sp,
> +    rv_ireg_gp,
> +    rv_ireg_tp,
> +    rv_ireg_t0,
> +    rv_ireg_t1,
> +    rv_ireg_t2,
> +    rv_ireg_s0,
> +    rv_ireg_s1,
> +    rv_ireg_a0,
> +    rv_ireg_a1,
> +    rv_ireg_a2,
> +    rv_ireg_a3,
> +    rv_ireg_a4,
> +    rv_ireg_a5,
> +    rv_ireg_a6,
> +    rv_ireg_a7,
> +    rv_ireg_s2,
> +    rv_ireg_s3,
> +    rv_ireg_s4,
> +    rv_ireg_s5,
> +    rv_ireg_s6,
> +    rv_ireg_s7,
> +    rv_ireg_s8,
> +    rv_ireg_s9,
> +    rv_ireg_s10,
> +    rv_ireg_s11,
> +    rv_ireg_t3,
> +    rv_ireg_t4,
> +    rv_ireg_t5,
> +    rv_ireg_t6,
> +} rv_ireg;
> +
> +typedef enum {
> +    rvc_end,
> +    rvc_rd_eq_ra,
> +    rvc_rd_eq_x0,
> +    rvc_rs1_eq_x0,
> +    rvc_rs2_eq_x0,
> +    rvc_rs2_eq_rs1,
> +    rvc_rs1_eq_ra,
> +    rvc_imm_eq_zero,
> +    rvc_imm_eq_n1,
> +    rvc_imm_eq_p1,
> +    rvc_csr_eq_0x001,
> +    rvc_csr_eq_0x002,
> +    rvc_csr_eq_0x003,
> +    rvc_csr_eq_0xc00,
> +    rvc_csr_eq_0xc01,
> +    rvc_csr_eq_0xc02,
> +    rvc_csr_eq_0xc80,
> +    rvc_csr_eq_0xc81,
> +    rvc_csr_eq_0xc82,
> +} rvc_constraint;
> +
> +typedef enum {
> +    rv_codec_illegal,
> +    rv_codec_none,
> +    rv_codec_u,
> +    rv_codec_uj,
> +    rv_codec_i,
> +    rv_codec_i_sh5,
> +    rv_codec_i_sh6,
> +    rv_codec_i_sh7,
> +    rv_codec_i_csr,
> +    rv_codec_s,
> +    rv_codec_sb,
> +    rv_codec_r,
> +    rv_codec_r_m,
> +    rv_codec_r4_m,
> +    rv_codec_r_a,
> +    rv_codec_r_l,
> +    rv_codec_r_f,
> +    rv_codec_cb,
> +    rv_codec_cb_imm,
> +    rv_codec_cb_sh5,
> +    rv_codec_cb_sh6,
> +    rv_codec_ci,
> +    rv_codec_ci_sh5,
> +    rv_codec_ci_sh6,
> +    rv_codec_ci_16sp,
> +    rv_codec_ci_lwsp,
> +    rv_codec_ci_ldsp,
> +    rv_codec_ci_lqsp,
> +    rv_codec_ci_li,
> +    rv_codec_ci_lui,
> +    rv_codec_ci_none,
> +    rv_codec_ciw_4spn,
> +    rv_codec_cj,
> +    rv_codec_cj_jal,
> +    rv_codec_cl_lw,
> +    rv_codec_cl_ld,
> +    rv_codec_cl_lq,
> +    rv_codec_cr,
> +    rv_codec_cr_mv,
> +    rv_codec_cr_jalr,
> +    rv_codec_cr_jr,
> +    rv_codec_cs,
> +    rv_codec_cs_sw,
> +    rv_codec_cs_sd,
> +    rv_codec_cs_sq,
> +    rv_codec_css_swsp,
> +    rv_codec_css_sdsp,
> +    rv_codec_css_sqsp,
> +    rv_codec_k_bs,
> +    rv_codec_k_rnum,
> +    rv_codec_v_r,
> +    rv_codec_v_ldst,
> +    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;
> +
> +/* structures */
> +
> +typedef struct {
> +    uint64_t  pc;
> +    uint64_t  inst;
> +    int32_t   imm;
> +    uint16_t  op;
> +    uint8_t   codec;
> +    uint8_t   rd;
> +    uint8_t   rs1;
> +    uint8_t   rs2;
> +    uint8_t   rs3;
> +    uint8_t   rm;
> +    uint8_t   pred;
> +    uint8_t   succ;
> +    uint8_t   aq;
> +    uint8_t   rl;
> +    uint8_t   bs;
> +    uint8_t   rnum;
> +    uint8_t   vm;
> +    uint32_t  vzimm;
> +    uint8_t   rlist;
> +} rv_decode;
> +
> +typedef struct {
> +    const int op;
> +    const rvc_constraint *constraints;
> +} rv_comp_data;
> +
> +enum {
> +    rvcd_imm_nz = 0x1
> +};
> +
> +typedef struct {
> +    const char * const name;
> +    const rv_codec codec;
> +    const char * const format;
> +    const rv_comp_data *pseudo;
> +    const short decomp_rv32;
> +    const short decomp_rv64;
> +    const short decomp_rv128;
> +    const short decomp_data;
> +} rv_opcode_data;
> +
> +/* instruction formats */
> +
> +#define rv_fmt_none                   "O\t"
> +#define rv_fmt_rs1                    "O\t1"
> +#define rv_fmt_offset                 "O\to"
> +#define rv_fmt_pred_succ              "O\tp,s"
> +#define rv_fmt_rs1_rs2                "O\t1,2"
> +#define rv_fmt_rd_imm                 "O\t0,i"
> +#define rv_fmt_rd_offset              "O\t0,o"
> +#define rv_fmt_rd_rs1_rs2             "O\t0,1,2"
> +#define rv_fmt_frd_rs1                "O\t3,1"
> +#define rv_fmt_frd_frs1               "O\t3,4"
> +#define rv_fmt_rd_frs1                "O\t0,4"
> +#define rv_fmt_rd_frs1_frs2           "O\t0,4,5"
> +#define rv_fmt_frd_frs1_frs2          "O\t3,4,5"
> +#define rv_fmt_rm_frd_frs1            "O\tr,3,4"
> +#define rv_fmt_rm_frd_rs1             "O\tr,3,1"
> +#define rv_fmt_rm_rd_frs1             "O\tr,0,4"
> +#define rv_fmt_rm_frd_frs1_frs2       "O\tr,3,4,5"
> +#define rv_fmt_rm_frd_frs1_frs2_frs3  "O\tr,3,4,5,6"
> +#define rv_fmt_rd_rs1_imm             "O\t0,1,i"
> +#define rv_fmt_rd_rs1_offset          "O\t0,1,i"
> +#define rv_fmt_rd_offset_rs1          "O\t0,i(1)"
> +#define rv_fmt_frd_offset_rs1         "O\t3,i(1)"
> +#define rv_fmt_rd_csr_rs1             "O\t0,c,1"
> +#define rv_fmt_rd_csr_zimm            "O\t0,c,7"
> +#define rv_fmt_rs2_offset_rs1         "O\t2,i(1)"
> +#define rv_fmt_frs2_offset_rs1        "O\t5,i(1)"
> +#define rv_fmt_rs1_rs2_offset         "O\t1,2,o"
> +#define rv_fmt_rs2_rs1_offset         "O\t2,1,o"
> +#define rv_fmt_aqrl_rd_rs2_rs1        "OAR\t0,2,(1)"
> +#define rv_fmt_aqrl_rd_rs1            "OAR\t0,(1)"
> +#define rv_fmt_rd                     "O\t0"
> +#define rv_fmt_rd_zimm                "O\t0,7"
> +#define rv_fmt_rd_rs1                 "O\t0,1"
> +#define rv_fmt_rd_rs2                 "O\t0,2"
> +#define rv_fmt_rs1_offset             "O\t1,o"
> +#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_ldst_vd_rs1_vm         "O\tD,(1)m"
> +#define rv_fmt_ldst_vd_rs1_rs2_vm     "O\tD,(1),2m"
> +#define rv_fmt_ldst_vd_rs1_vs2_vm     "O\tD,(1),Fm"
> +#define rv_fmt_vd_vs2_vs1             "O\tD,F,E"
> +#define rv_fmt_vd_vs2_vs1_vl          "O\tD,F,El"
> +#define rv_fmt_vd_vs2_vs1_vm          "O\tD,F,Em"
> +#define rv_fmt_vd_vs2_rs1_vl          "O\tD,F,1l"
> +#define rv_fmt_vd_vs2_fs1_vl          "O\tD,F,4l"
> +#define rv_fmt_vd_vs2_rs1_vm          "O\tD,F,1m"
> +#define rv_fmt_vd_vs2_fs1_vm          "O\tD,F,4m"
> +#define rv_fmt_vd_vs2_imm_vl          "O\tD,F,il"
> +#define rv_fmt_vd_vs2_imm_vm          "O\tD,F,im"
> +#define rv_fmt_vd_vs2_uimm_vm         "O\tD,F,um"
> +#define rv_fmt_vd_vs1_vs2_vm          "O\tD,E,Fm"
> +#define rv_fmt_vd_rs1_vs2_vm          "O\tD,1,Fm"
> +#define rv_fmt_vd_fs1_vs2_vm          "O\tD,4,Fm"
> +#define rv_fmt_vd_vs1                 "O\tD,E"
> +#define rv_fmt_vd_rs1                 "O\tD,1"
> +#define rv_fmt_vd_fs1                 "O\tD,4"
> +#define rv_fmt_vd_imm                 "O\tD,i"
> +#define rv_fmt_vd_vs2                 "O\tD,F"
> +#define rv_fmt_vd_vs2_vm              "O\tD,Fm"
> +#define rv_fmt_rd_vs2_vm              "O\t0,Fm"
> +#define rv_fmt_rd_vs2                 "O\t0,F"
> +#define rv_fmt_fd_vs2                 "O\t3,F"
> +#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"
> +
> +#endif /* DISAS_RISCV_H */


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

* Re: [PATCH 2/9] target/riscv: Factor out RISCVCPUConfig from cpu.h
  2023-05-30 13:18 ` [PATCH 2/9] target/riscv: Factor out RISCVCPUConfig from cpu.h Christoph Muellner
@ 2023-06-12  3:21   ` Alistair Francis
  2023-06-12  6:40   ` LIU Zhiwei
  1 sibling, 0 replies; 30+ messages in thread
From: Alistair Francis @ 2023-06-12  3:21 UTC (permalink / raw)
  To: Christoph Muellner
  Cc: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
	Philipp Tomsich, Palmer Dabbelt, Richard Henderson, Zhiwei Liu,
	Weiwei Li, Daniel Henrique Barboza

On Tue, May 30, 2023 at 11:21 PM Christoph Muellner
<christoph.muellner@vrull.eu> wrote:
>
> From: Christoph Müllner <christoph.muellner@vrull.eu>
>
> The file target/riscv/cpu.h cannot be included by files outside
> of target/riscv/. To share data with other parts of QEMU (e.g.
> the disassembler) we need to factor out the relevant code.
> Therefore, this patch moves the definition of RISCVCPUConfig
> (and tightly coupled dependencies and functions) into its
> own target/riscv/cpu-config.h file.
> The goal is to be able to share the enablement-status of
> the RISC-V ISA extensions (RISCVCPUConfig::ext_*) with
> other parts of QEMU.
>
> This patch does not introduce new functionality.
> However, the patch includes a small change:
> The parameter for the extension test functions has been changed
> from 'DisasContext*' to 'const RISCVCPUConfig*'.
> This allows to keep these functions in cpu-config.h.
>
> Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>

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

Alistair

> ---
>  target/riscv/cpu-config.h | 148 ++++++++++++++++++++++++++++++++++++++
>  target/riscv/cpu.h        | 114 +----------------------------
>  target/riscv/translate.c  |  27 +------
>  3 files changed, 151 insertions(+), 138 deletions(-)
>  create mode 100644 target/riscv/cpu-config.h
>
> diff --git a/target/riscv/cpu-config.h b/target/riscv/cpu-config.h
> new file mode 100644
> index 0000000000..ca368af0b2
> --- /dev/null
> +++ b/target/riscv/cpu-config.h
> @@ -0,0 +1,148 @@
> +/*
> + * QEMU RISC-V CPU Config
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#ifndef RISCV_CPU_CONFIG_H
> +#define RISCV_CPU_CONFIG_H
> +
> +/*
> + * map is a 16-bit bitmap: the most significant set bit in map is the maximum
> + * satp mode that is supported. It may be chosen by the user and must respect
> + * what qemu implements (valid_1_10_32/64) and what the hw is capable of
> + * (supported bitmap below).
> + *
> + * init is a 16-bit bitmap used to make sure the user selected a correct
> + * configuration as per the specification.
> + *
> + * supported is a 16-bit bitmap used to reflect the hw capabilities.
> + */
> +typedef struct {
> +    uint16_t map, init, supported;
> +} RISCVSATPMap;
> +
> +struct RISCVCPUConfig {
> +    bool ext_zba;
> +    bool ext_zbb;
> +    bool ext_zbc;
> +    bool ext_zbkb;
> +    bool ext_zbkc;
> +    bool ext_zbkx;
> +    bool ext_zbs;
> +    bool ext_zca;
> +    bool ext_zcb;
> +    bool ext_zcd;
> +    bool ext_zce;
> +    bool ext_zcf;
> +    bool ext_zcmp;
> +    bool ext_zcmt;
> +    bool ext_zk;
> +    bool ext_zkn;
> +    bool ext_zknd;
> +    bool ext_zkne;
> +    bool ext_zknh;
> +    bool ext_zkr;
> +    bool ext_zks;
> +    bool ext_zksed;
> +    bool ext_zksh;
> +    bool ext_zkt;
> +    bool ext_ifencei;
> +    bool ext_icsr;
> +    bool ext_icbom;
> +    bool ext_icboz;
> +    bool ext_zicond;
> +    bool ext_zihintpause;
> +    bool ext_smstateen;
> +    bool ext_sstc;
> +    bool ext_svadu;
> +    bool ext_svinval;
> +    bool ext_svnapot;
> +    bool ext_svpbmt;
> +    bool ext_zdinx;
> +    bool ext_zawrs;
> +    bool ext_zfh;
> +    bool ext_zfhmin;
> +    bool ext_zfinx;
> +    bool ext_zhinx;
> +    bool ext_zhinxmin;
> +    bool ext_zve32f;
> +    bool ext_zve64f;
> +    bool ext_zve64d;
> +    bool ext_zmmul;
> +    bool ext_zvfh;
> +    bool ext_zvfhmin;
> +    bool ext_smaia;
> +    bool ext_ssaia;
> +    bool ext_sscofpmf;
> +    bool rvv_ta_all_1s;
> +    bool rvv_ma_all_1s;
> +
> +    uint32_t mvendorid;
> +    uint64_t marchid;
> +    uint64_t mimpid;
> +
> +    /* Vendor-specific custom extensions */
> +    bool ext_xtheadba;
> +    bool ext_xtheadbb;
> +    bool ext_xtheadbs;
> +    bool ext_xtheadcmo;
> +    bool ext_xtheadcondmov;
> +    bool ext_xtheadfmemidx;
> +    bool ext_xtheadfmv;
> +    bool ext_xtheadmac;
> +    bool ext_xtheadmemidx;
> +    bool ext_xtheadmempair;
> +    bool ext_xtheadsync;
> +    bool ext_XVentanaCondOps;
> +
> +    uint8_t pmu_num;
> +    char *priv_spec;
> +    char *user_spec;
> +    char *bext_spec;
> +    char *vext_spec;
> +    uint16_t vlen;
> +    uint16_t elen;
> +    uint16_t cbom_blocksize;
> +    uint16_t cboz_blocksize;
> +    bool mmu;
> +    bool pmp;
> +    bool epmp;
> +    bool debug;
> +    bool misa_w;
> +
> +    bool short_isa_string;
> +
> +#ifndef CONFIG_USER_ONLY
> +    RISCVSATPMap satp_mode;
> +#endif
> +};
> +
> +typedef struct RISCVCPUConfig RISCVCPUConfig;
> +
> +/* Helper functions to test for extensions.  */
> +
> +static inline bool always_true_p(const RISCVCPUConfig *cfg __attribute__((__unused__)))
> +{
> +    return true;
> +}
> +
> +static inline bool has_xthead_p(const RISCVCPUConfig *cfg)
> +{
> +    return cfg->ext_xtheadba || cfg->ext_xtheadbb ||
> +           cfg->ext_xtheadbs || cfg->ext_xtheadcmo ||
> +           cfg->ext_xtheadcondmov ||
> +           cfg->ext_xtheadfmemidx || cfg->ext_xtheadfmv ||
> +           cfg->ext_xtheadmac || cfg->ext_xtheadmemidx ||
> +           cfg->ext_xtheadmempair || cfg->ext_xtheadsync;
> +}
> +
> +#define MATERIALISE_EXT_PREDICATE(ext) \
> +    static inline bool has_ ## ext ## _p(const RISCVCPUConfig *cfg) \
> +    { \
> +        return cfg->ext_ ## ext ; \
> +    }
> +
> +MATERIALISE_EXT_PREDICATE(XVentanaCondOps)
> +
> +#endif /* RISCV_CPU_CONFIG_H */
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index de7e43126a..895a307bad 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -28,6 +28,7 @@
>  #include "qemu/int128.h"
>  #include "cpu_bits.h"
>  #include "qapi/qapi-types-common.h"
> +#include "cpu-config.h"
>  #include "cpu-qom.h"
>
>  #define TCG_GUEST_DEFAULT_MO 0
> @@ -368,119 +369,6 @@ struct CPUArchState {
>      uint64_t kvm_timer_frequency;
>  };
>
> -/*
> - * map is a 16-bit bitmap: the most significant set bit in map is the maximum
> - * satp mode that is supported. It may be chosen by the user and must respect
> - * what qemu implements (valid_1_10_32/64) and what the hw is capable of
> - * (supported bitmap below).
> - *
> - * init is a 16-bit bitmap used to make sure the user selected a correct
> - * configuration as per the specification.
> - *
> - * supported is a 16-bit bitmap used to reflect the hw capabilities.
> - */
> -typedef struct {
> -    uint16_t map, init, supported;
> -} RISCVSATPMap;
> -
> -struct RISCVCPUConfig {
> -    bool ext_zba;
> -    bool ext_zbb;
> -    bool ext_zbc;
> -    bool ext_zbkb;
> -    bool ext_zbkc;
> -    bool ext_zbkx;
> -    bool ext_zbs;
> -    bool ext_zca;
> -    bool ext_zcb;
> -    bool ext_zcd;
> -    bool ext_zce;
> -    bool ext_zcf;
> -    bool ext_zcmp;
> -    bool ext_zcmt;
> -    bool ext_zk;
> -    bool ext_zkn;
> -    bool ext_zknd;
> -    bool ext_zkne;
> -    bool ext_zknh;
> -    bool ext_zkr;
> -    bool ext_zks;
> -    bool ext_zksed;
> -    bool ext_zksh;
> -    bool ext_zkt;
> -    bool ext_ifencei;
> -    bool ext_icsr;
> -    bool ext_icbom;
> -    bool ext_icboz;
> -    bool ext_zicond;
> -    bool ext_zihintpause;
> -    bool ext_smstateen;
> -    bool ext_sstc;
> -    bool ext_svadu;
> -    bool ext_svinval;
> -    bool ext_svnapot;
> -    bool ext_svpbmt;
> -    bool ext_zdinx;
> -    bool ext_zawrs;
> -    bool ext_zfh;
> -    bool ext_zfhmin;
> -    bool ext_zfinx;
> -    bool ext_zhinx;
> -    bool ext_zhinxmin;
> -    bool ext_zve32f;
> -    bool ext_zve64f;
> -    bool ext_zve64d;
> -    bool ext_zmmul;
> -    bool ext_zvfh;
> -    bool ext_zvfhmin;
> -    bool ext_smaia;
> -    bool ext_ssaia;
> -    bool ext_sscofpmf;
> -    bool rvv_ta_all_1s;
> -    bool rvv_ma_all_1s;
> -
> -    uint32_t mvendorid;
> -    uint64_t marchid;
> -    uint64_t mimpid;
> -
> -    /* Vendor-specific custom extensions */
> -    bool ext_xtheadba;
> -    bool ext_xtheadbb;
> -    bool ext_xtheadbs;
> -    bool ext_xtheadcmo;
> -    bool ext_xtheadcondmov;
> -    bool ext_xtheadfmemidx;
> -    bool ext_xtheadfmv;
> -    bool ext_xtheadmac;
> -    bool ext_xtheadmemidx;
> -    bool ext_xtheadmempair;
> -    bool ext_xtheadsync;
> -    bool ext_XVentanaCondOps;
> -
> -    uint8_t pmu_num;
> -    char *priv_spec;
> -    char *user_spec;
> -    char *bext_spec;
> -    char *vext_spec;
> -    uint16_t vlen;
> -    uint16_t elen;
> -    uint16_t cbom_blocksize;
> -    uint16_t cboz_blocksize;
> -    bool mmu;
> -    bool pmp;
> -    bool epmp;
> -    bool debug;
> -    bool misa_w;
> -
> -    bool short_isa_string;
> -
> -#ifndef CONFIG_USER_ONLY
> -    RISCVSATPMap satp_mode;
> -#endif
> -};
> -
> -typedef struct RISCVCPUConfig RISCVCPUConfig;
> -
>  /*
>   * RISCVCPU:
>   * @env: #CPURISCVState
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index 928da0d3f0..2697cc26d0 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -119,29 +119,6 @@ static inline bool has_ext(DisasContext *ctx, uint32_t ext)
>      return ctx->misa_ext & ext;
>  }
>
> -static bool always_true_p(DisasContext *ctx  __attribute__((__unused__)))
> -{
> -    return true;
> -}
> -
> -static bool has_xthead_p(DisasContext *ctx  __attribute__((__unused__)))
> -{
> -    return ctx->cfg_ptr->ext_xtheadba || ctx->cfg_ptr->ext_xtheadbb ||
> -           ctx->cfg_ptr->ext_xtheadbs || ctx->cfg_ptr->ext_xtheadcmo ||
> -           ctx->cfg_ptr->ext_xtheadcondmov ||
> -           ctx->cfg_ptr->ext_xtheadfmemidx || ctx->cfg_ptr->ext_xtheadfmv ||
> -           ctx->cfg_ptr->ext_xtheadmac || ctx->cfg_ptr->ext_xtheadmemidx ||
> -           ctx->cfg_ptr->ext_xtheadmempair || ctx->cfg_ptr->ext_xtheadsync;
> -}
> -
> -#define MATERIALISE_EXT_PREDICATE(ext)  \
> -    static bool has_ ## ext ## _p(DisasContext *ctx)    \
> -    { \
> -        return ctx->cfg_ptr->ext_ ## ext ; \
> -    }
> -
> -MATERIALISE_EXT_PREDICATE(XVentanaCondOps);
> -
>  #ifdef TARGET_RISCV32
>  #define get_xl(ctx)    MXL_RV32
>  #elif defined(CONFIG_USER_ONLY)
> @@ -1106,7 +1083,7 @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
>       * that are tested in-order until a decoder matches onto the opcode.
>       */
>      static const struct {
> -        bool (*guard_func)(DisasContext *);
> +        bool (*guard_func)(const RISCVCPUConfig *);
>          bool (*decode_func)(DisasContext *, uint32_t);
>      } decoders[] = {
>          { always_true_p,  decode_insn32 },
> @@ -1135,7 +1112,7 @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
>          ctx->pc_succ_insn = ctx->base.pc_next + 4;
>
>          for (size_t i = 0; i < ARRAY_SIZE(decoders); ++i) {
> -            if (decoders[i].guard_func(ctx) &&
> +            if (decoders[i].guard_func(ctx->cfg_ptr) &&
>                  decoders[i].decode_func(ctx, opcode32)) {
>                  return;
>              }
> --
> 2.40.1
>
>


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

* Re: [PATCH 3/9] disas/riscv: Move types/constants to new header file
  2023-05-30 13:18 ` [PATCH 3/9] disas/riscv: Move types/constants to new header file Christoph Muellner
  2023-06-09  2:04   ` LIU Zhiwei
@ 2023-06-12  3:22   ` Alistair Francis
  1 sibling, 0 replies; 30+ messages in thread
From: Alistair Francis @ 2023-06-12  3:22 UTC (permalink / raw)
  To: Christoph Muellner
  Cc: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
	Philipp Tomsich, Palmer Dabbelt, Richard Henderson, Zhiwei Liu

On Tue, May 30, 2023 at 11:23 PM Christoph Muellner
<christoph.muellner@vrull.eu> wrote:
>
> From: Christoph Müllner <christoph.muellner@vrull.eu>
>
> In order to enable vendor disassembler support, we need to
> move types and constants into a header file so that other
> compilation units can use them as well.
>
> This patch does not introduce any functional changes.
>
> Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>

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

Alistair

> ---
>  disas/riscv.c | 270 +-----------------------------------------------
>  disas/riscv.h | 280 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 281 insertions(+), 269 deletions(-)
>  create mode 100644 disas/riscv.h
>
> diff --git a/disas/riscv.c b/disas/riscv.c
> index d597161d46..a062fb48cc 100644
> --- a/disas/riscv.c
> +++ b/disas/riscv.c
> @@ -19,158 +19,7 @@
>
>  #include "qemu/osdep.h"
>  #include "disas/dis-asm.h"
> -
> -
> -/* types */
> -
> -typedef uint64_t rv_inst;
> -typedef uint16_t rv_opcode;
> -
> -/* enums */
> -
> -typedef enum {
> -    rv32,
> -    rv64,
> -    rv128
> -} rv_isa;
> -
> -typedef enum {
> -    rv_rm_rne = 0,
> -    rv_rm_rtz = 1,
> -    rv_rm_rdn = 2,
> -    rv_rm_rup = 3,
> -    rv_rm_rmm = 4,
> -    rv_rm_dyn = 7,
> -} rv_rm;
> -
> -typedef enum {
> -    rv_fence_i = 8,
> -    rv_fence_o = 4,
> -    rv_fence_r = 2,
> -    rv_fence_w = 1,
> -} rv_fence;
> -
> -typedef enum {
> -    rv_ireg_zero,
> -    rv_ireg_ra,
> -    rv_ireg_sp,
> -    rv_ireg_gp,
> -    rv_ireg_tp,
> -    rv_ireg_t0,
> -    rv_ireg_t1,
> -    rv_ireg_t2,
> -    rv_ireg_s0,
> -    rv_ireg_s1,
> -    rv_ireg_a0,
> -    rv_ireg_a1,
> -    rv_ireg_a2,
> -    rv_ireg_a3,
> -    rv_ireg_a4,
> -    rv_ireg_a5,
> -    rv_ireg_a6,
> -    rv_ireg_a7,
> -    rv_ireg_s2,
> -    rv_ireg_s3,
> -    rv_ireg_s4,
> -    rv_ireg_s5,
> -    rv_ireg_s6,
> -    rv_ireg_s7,
> -    rv_ireg_s8,
> -    rv_ireg_s9,
> -    rv_ireg_s10,
> -    rv_ireg_s11,
> -    rv_ireg_t3,
> -    rv_ireg_t4,
> -    rv_ireg_t5,
> -    rv_ireg_t6,
> -} rv_ireg;
> -
> -typedef enum {
> -    rvc_end,
> -    rvc_rd_eq_ra,
> -    rvc_rd_eq_x0,
> -    rvc_rs1_eq_x0,
> -    rvc_rs2_eq_x0,
> -    rvc_rs2_eq_rs1,
> -    rvc_rs1_eq_ra,
> -    rvc_imm_eq_zero,
> -    rvc_imm_eq_n1,
> -    rvc_imm_eq_p1,
> -    rvc_csr_eq_0x001,
> -    rvc_csr_eq_0x002,
> -    rvc_csr_eq_0x003,
> -    rvc_csr_eq_0xc00,
> -    rvc_csr_eq_0xc01,
> -    rvc_csr_eq_0xc02,
> -    rvc_csr_eq_0xc80,
> -    rvc_csr_eq_0xc81,
> -    rvc_csr_eq_0xc82,
> -} rvc_constraint;
> -
> -typedef enum {
> -    rv_codec_illegal,
> -    rv_codec_none,
> -    rv_codec_u,
> -    rv_codec_uj,
> -    rv_codec_i,
> -    rv_codec_i_sh5,
> -    rv_codec_i_sh6,
> -    rv_codec_i_sh7,
> -    rv_codec_i_csr,
> -    rv_codec_s,
> -    rv_codec_sb,
> -    rv_codec_r,
> -    rv_codec_r_m,
> -    rv_codec_r4_m,
> -    rv_codec_r_a,
> -    rv_codec_r_l,
> -    rv_codec_r_f,
> -    rv_codec_cb,
> -    rv_codec_cb_imm,
> -    rv_codec_cb_sh5,
> -    rv_codec_cb_sh6,
> -    rv_codec_ci,
> -    rv_codec_ci_sh5,
> -    rv_codec_ci_sh6,
> -    rv_codec_ci_16sp,
> -    rv_codec_ci_lwsp,
> -    rv_codec_ci_ldsp,
> -    rv_codec_ci_lqsp,
> -    rv_codec_ci_li,
> -    rv_codec_ci_lui,
> -    rv_codec_ci_none,
> -    rv_codec_ciw_4spn,
> -    rv_codec_cj,
> -    rv_codec_cj_jal,
> -    rv_codec_cl_lw,
> -    rv_codec_cl_ld,
> -    rv_codec_cl_lq,
> -    rv_codec_cr,
> -    rv_codec_cr_mv,
> -    rv_codec_cr_jalr,
> -    rv_codec_cr_jr,
> -    rv_codec_cs,
> -    rv_codec_cs_sw,
> -    rv_codec_cs_sd,
> -    rv_codec_cs_sq,
> -    rv_codec_css_swsp,
> -    rv_codec_css_sdsp,
> -    rv_codec_css_sqsp,
> -    rv_codec_k_bs,
> -    rv_codec_k_rnum,
> -    rv_codec_v_r,
> -    rv_codec_v_ldst,
> -    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;
> +#include "disas/riscv.h"
>
>  typedef enum {
>      rv_op_illegal = 0,
> @@ -966,50 +815,6 @@ typedef enum {
>      rv_op_czero_nez = 790,
>  } rv_op;
>
> -/* structures */
> -
> -typedef struct {
> -    uint64_t  pc;
> -    uint64_t  inst;
> -    int32_t   imm;
> -    uint16_t  op;
> -    uint8_t   codec;
> -    uint8_t   rd;
> -    uint8_t   rs1;
> -    uint8_t   rs2;
> -    uint8_t   rs3;
> -    uint8_t   rm;
> -    uint8_t   pred;
> -    uint8_t   succ;
> -    uint8_t   aq;
> -    uint8_t   rl;
> -    uint8_t   bs;
> -    uint8_t   rnum;
> -    uint8_t   vm;
> -    uint32_t  vzimm;
> -    uint8_t   rlist;
> -} rv_decode;
> -
> -typedef struct {
> -    const int op;
> -    const rvc_constraint *constraints;
> -} rv_comp_data;
> -
> -enum {
> -    rvcd_imm_nz = 0x1
> -};
> -
> -typedef struct {
> -    const char * const name;
> -    const rv_codec codec;
> -    const char * const format;
> -    const rv_comp_data *pseudo;
> -    const short decomp_rv32;
> -    const short decomp_rv64;
> -    const short decomp_rv128;
> -    const short decomp_data;
> -} rv_opcode_data;
> -
>  /* register names */
>
>  static const char rv_ireg_name_sym[32][5] = {
> @@ -1033,79 +838,6 @@ static const char rv_vreg_name_sym[32][4] = {
>      "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"
>  };
>
> -/* instruction formats */
> -
> -#define rv_fmt_none                   "O\t"
> -#define rv_fmt_rs1                    "O\t1"
> -#define rv_fmt_offset                 "O\to"
> -#define rv_fmt_pred_succ              "O\tp,s"
> -#define rv_fmt_rs1_rs2                "O\t1,2"
> -#define rv_fmt_rd_imm                 "O\t0,i"
> -#define rv_fmt_rd_offset              "O\t0,o"
> -#define rv_fmt_rd_rs1_rs2             "O\t0,1,2"
> -#define rv_fmt_frd_rs1                "O\t3,1"
> -#define rv_fmt_frd_frs1               "O\t3,4"
> -#define rv_fmt_rd_frs1                "O\t0,4"
> -#define rv_fmt_rd_frs1_frs2           "O\t0,4,5"
> -#define rv_fmt_frd_frs1_frs2          "O\t3,4,5"
> -#define rv_fmt_rm_frd_frs1            "O\tr,3,4"
> -#define rv_fmt_rm_frd_rs1             "O\tr,3,1"
> -#define rv_fmt_rm_rd_frs1             "O\tr,0,4"
> -#define rv_fmt_rm_frd_frs1_frs2       "O\tr,3,4,5"
> -#define rv_fmt_rm_frd_frs1_frs2_frs3  "O\tr,3,4,5,6"
> -#define rv_fmt_rd_rs1_imm             "O\t0,1,i"
> -#define rv_fmt_rd_rs1_offset          "O\t0,1,i"
> -#define rv_fmt_rd_offset_rs1          "O\t0,i(1)"
> -#define rv_fmt_frd_offset_rs1         "O\t3,i(1)"
> -#define rv_fmt_rd_csr_rs1             "O\t0,c,1"
> -#define rv_fmt_rd_csr_zimm            "O\t0,c,7"
> -#define rv_fmt_rs2_offset_rs1         "O\t2,i(1)"
> -#define rv_fmt_frs2_offset_rs1        "O\t5,i(1)"
> -#define rv_fmt_rs1_rs2_offset         "O\t1,2,o"
> -#define rv_fmt_rs2_rs1_offset         "O\t2,1,o"
> -#define rv_fmt_aqrl_rd_rs2_rs1        "OAR\t0,2,(1)"
> -#define rv_fmt_aqrl_rd_rs1            "OAR\t0,(1)"
> -#define rv_fmt_rd                     "O\t0"
> -#define rv_fmt_rd_zimm                "O\t0,7"
> -#define rv_fmt_rd_rs1                 "O\t0,1"
> -#define rv_fmt_rd_rs2                 "O\t0,2"
> -#define rv_fmt_rs1_offset             "O\t1,o"
> -#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_ldst_vd_rs1_vm         "O\tD,(1)m"
> -#define rv_fmt_ldst_vd_rs1_rs2_vm     "O\tD,(1),2m"
> -#define rv_fmt_ldst_vd_rs1_vs2_vm     "O\tD,(1),Fm"
> -#define rv_fmt_vd_vs2_vs1             "O\tD,F,E"
> -#define rv_fmt_vd_vs2_vs1_vl          "O\tD,F,El"
> -#define rv_fmt_vd_vs2_vs1_vm          "O\tD,F,Em"
> -#define rv_fmt_vd_vs2_rs1_vl          "O\tD,F,1l"
> -#define rv_fmt_vd_vs2_fs1_vl          "O\tD,F,4l"
> -#define rv_fmt_vd_vs2_rs1_vm          "O\tD,F,1m"
> -#define rv_fmt_vd_vs2_fs1_vm          "O\tD,F,4m"
> -#define rv_fmt_vd_vs2_imm_vl          "O\tD,F,il"
> -#define rv_fmt_vd_vs2_imm_vm          "O\tD,F,im"
> -#define rv_fmt_vd_vs2_uimm_vm         "O\tD,F,um"
> -#define rv_fmt_vd_vs1_vs2_vm          "O\tD,E,Fm"
> -#define rv_fmt_vd_rs1_vs2_vm          "O\tD,1,Fm"
> -#define rv_fmt_vd_fs1_vs2_vm          "O\tD,4,Fm"
> -#define rv_fmt_vd_vs1                 "O\tD,E"
> -#define rv_fmt_vd_rs1                 "O\tD,1"
> -#define rv_fmt_vd_fs1                 "O\tD,4"
> -#define rv_fmt_vd_imm                 "O\tD,i"
> -#define rv_fmt_vd_vs2                 "O\tD,F"
> -#define rv_fmt_vd_vs2_vm              "O\tD,Fm"
> -#define rv_fmt_rd_vs2_vm              "O\t0,Fm"
> -#define rv_fmt_rd_vs2                 "O\t0,F"
> -#define rv_fmt_fd_vs2                 "O\t3,F"
> -#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 */
>
>  static const rvc_constraint rvcc_jal[] = { rvc_rd_eq_ra, rvc_end };
> diff --git a/disas/riscv.h b/disas/riscv.h
> new file mode 100644
> index 0000000000..0f34b71518
> --- /dev/null
> +++ b/disas/riscv.h
> @@ -0,0 +1,280 @@
> +/*
> + * QEMU disassembler -- RISC-V specific header.
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#ifndef DISAS_RISCV_H
> +#define DISAS_RISCV_H
> +
> +#include "qemu/osdep.h"
> +
> +/* types */
> +
> +typedef uint64_t rv_inst;
> +typedef uint16_t rv_opcode;
> +
> +/* enums */
> +
> +typedef enum {
> +    rv32,
> +    rv64,
> +    rv128
> +} rv_isa;
> +
> +typedef enum {
> +    rv_rm_rne = 0,
> +    rv_rm_rtz = 1,
> +    rv_rm_rdn = 2,
> +    rv_rm_rup = 3,
> +    rv_rm_rmm = 4,
> +    rv_rm_dyn = 7,
> +} rv_rm;
> +
> +typedef enum {
> +    rv_fence_i = 8,
> +    rv_fence_o = 4,
> +    rv_fence_r = 2,
> +    rv_fence_w = 1,
> +} rv_fence;
> +
> +typedef enum {
> +    rv_ireg_zero,
> +    rv_ireg_ra,
> +    rv_ireg_sp,
> +    rv_ireg_gp,
> +    rv_ireg_tp,
> +    rv_ireg_t0,
> +    rv_ireg_t1,
> +    rv_ireg_t2,
> +    rv_ireg_s0,
> +    rv_ireg_s1,
> +    rv_ireg_a0,
> +    rv_ireg_a1,
> +    rv_ireg_a2,
> +    rv_ireg_a3,
> +    rv_ireg_a4,
> +    rv_ireg_a5,
> +    rv_ireg_a6,
> +    rv_ireg_a7,
> +    rv_ireg_s2,
> +    rv_ireg_s3,
> +    rv_ireg_s4,
> +    rv_ireg_s5,
> +    rv_ireg_s6,
> +    rv_ireg_s7,
> +    rv_ireg_s8,
> +    rv_ireg_s9,
> +    rv_ireg_s10,
> +    rv_ireg_s11,
> +    rv_ireg_t3,
> +    rv_ireg_t4,
> +    rv_ireg_t5,
> +    rv_ireg_t6,
> +} rv_ireg;
> +
> +typedef enum {
> +    rvc_end,
> +    rvc_rd_eq_ra,
> +    rvc_rd_eq_x0,
> +    rvc_rs1_eq_x0,
> +    rvc_rs2_eq_x0,
> +    rvc_rs2_eq_rs1,
> +    rvc_rs1_eq_ra,
> +    rvc_imm_eq_zero,
> +    rvc_imm_eq_n1,
> +    rvc_imm_eq_p1,
> +    rvc_csr_eq_0x001,
> +    rvc_csr_eq_0x002,
> +    rvc_csr_eq_0x003,
> +    rvc_csr_eq_0xc00,
> +    rvc_csr_eq_0xc01,
> +    rvc_csr_eq_0xc02,
> +    rvc_csr_eq_0xc80,
> +    rvc_csr_eq_0xc81,
> +    rvc_csr_eq_0xc82,
> +} rvc_constraint;
> +
> +typedef enum {
> +    rv_codec_illegal,
> +    rv_codec_none,
> +    rv_codec_u,
> +    rv_codec_uj,
> +    rv_codec_i,
> +    rv_codec_i_sh5,
> +    rv_codec_i_sh6,
> +    rv_codec_i_sh7,
> +    rv_codec_i_csr,
> +    rv_codec_s,
> +    rv_codec_sb,
> +    rv_codec_r,
> +    rv_codec_r_m,
> +    rv_codec_r4_m,
> +    rv_codec_r_a,
> +    rv_codec_r_l,
> +    rv_codec_r_f,
> +    rv_codec_cb,
> +    rv_codec_cb_imm,
> +    rv_codec_cb_sh5,
> +    rv_codec_cb_sh6,
> +    rv_codec_ci,
> +    rv_codec_ci_sh5,
> +    rv_codec_ci_sh6,
> +    rv_codec_ci_16sp,
> +    rv_codec_ci_lwsp,
> +    rv_codec_ci_ldsp,
> +    rv_codec_ci_lqsp,
> +    rv_codec_ci_li,
> +    rv_codec_ci_lui,
> +    rv_codec_ci_none,
> +    rv_codec_ciw_4spn,
> +    rv_codec_cj,
> +    rv_codec_cj_jal,
> +    rv_codec_cl_lw,
> +    rv_codec_cl_ld,
> +    rv_codec_cl_lq,
> +    rv_codec_cr,
> +    rv_codec_cr_mv,
> +    rv_codec_cr_jalr,
> +    rv_codec_cr_jr,
> +    rv_codec_cs,
> +    rv_codec_cs_sw,
> +    rv_codec_cs_sd,
> +    rv_codec_cs_sq,
> +    rv_codec_css_swsp,
> +    rv_codec_css_sdsp,
> +    rv_codec_css_sqsp,
> +    rv_codec_k_bs,
> +    rv_codec_k_rnum,
> +    rv_codec_v_r,
> +    rv_codec_v_ldst,
> +    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;
> +
> +/* structures */
> +
> +typedef struct {
> +    uint64_t  pc;
> +    uint64_t  inst;
> +    int32_t   imm;
> +    uint16_t  op;
> +    uint8_t   codec;
> +    uint8_t   rd;
> +    uint8_t   rs1;
> +    uint8_t   rs2;
> +    uint8_t   rs3;
> +    uint8_t   rm;
> +    uint8_t   pred;
> +    uint8_t   succ;
> +    uint8_t   aq;
> +    uint8_t   rl;
> +    uint8_t   bs;
> +    uint8_t   rnum;
> +    uint8_t   vm;
> +    uint32_t  vzimm;
> +    uint8_t   rlist;
> +} rv_decode;
> +
> +typedef struct {
> +    const int op;
> +    const rvc_constraint *constraints;
> +} rv_comp_data;
> +
> +enum {
> +    rvcd_imm_nz = 0x1
> +};
> +
> +typedef struct {
> +    const char * const name;
> +    const rv_codec codec;
> +    const char * const format;
> +    const rv_comp_data *pseudo;
> +    const short decomp_rv32;
> +    const short decomp_rv64;
> +    const short decomp_rv128;
> +    const short decomp_data;
> +} rv_opcode_data;
> +
> +/* instruction formats */
> +
> +#define rv_fmt_none                   "O\t"
> +#define rv_fmt_rs1                    "O\t1"
> +#define rv_fmt_offset                 "O\to"
> +#define rv_fmt_pred_succ              "O\tp,s"
> +#define rv_fmt_rs1_rs2                "O\t1,2"
> +#define rv_fmt_rd_imm                 "O\t0,i"
> +#define rv_fmt_rd_offset              "O\t0,o"
> +#define rv_fmt_rd_rs1_rs2             "O\t0,1,2"
> +#define rv_fmt_frd_rs1                "O\t3,1"
> +#define rv_fmt_frd_frs1               "O\t3,4"
> +#define rv_fmt_rd_frs1                "O\t0,4"
> +#define rv_fmt_rd_frs1_frs2           "O\t0,4,5"
> +#define rv_fmt_frd_frs1_frs2          "O\t3,4,5"
> +#define rv_fmt_rm_frd_frs1            "O\tr,3,4"
> +#define rv_fmt_rm_frd_rs1             "O\tr,3,1"
> +#define rv_fmt_rm_rd_frs1             "O\tr,0,4"
> +#define rv_fmt_rm_frd_frs1_frs2       "O\tr,3,4,5"
> +#define rv_fmt_rm_frd_frs1_frs2_frs3  "O\tr,3,4,5,6"
> +#define rv_fmt_rd_rs1_imm             "O\t0,1,i"
> +#define rv_fmt_rd_rs1_offset          "O\t0,1,i"
> +#define rv_fmt_rd_offset_rs1          "O\t0,i(1)"
> +#define rv_fmt_frd_offset_rs1         "O\t3,i(1)"
> +#define rv_fmt_rd_csr_rs1             "O\t0,c,1"
> +#define rv_fmt_rd_csr_zimm            "O\t0,c,7"
> +#define rv_fmt_rs2_offset_rs1         "O\t2,i(1)"
> +#define rv_fmt_frs2_offset_rs1        "O\t5,i(1)"
> +#define rv_fmt_rs1_rs2_offset         "O\t1,2,o"
> +#define rv_fmt_rs2_rs1_offset         "O\t2,1,o"
> +#define rv_fmt_aqrl_rd_rs2_rs1        "OAR\t0,2,(1)"
> +#define rv_fmt_aqrl_rd_rs1            "OAR\t0,(1)"
> +#define rv_fmt_rd                     "O\t0"
> +#define rv_fmt_rd_zimm                "O\t0,7"
> +#define rv_fmt_rd_rs1                 "O\t0,1"
> +#define rv_fmt_rd_rs2                 "O\t0,2"
> +#define rv_fmt_rs1_offset             "O\t1,o"
> +#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_ldst_vd_rs1_vm         "O\tD,(1)m"
> +#define rv_fmt_ldst_vd_rs1_rs2_vm     "O\tD,(1),2m"
> +#define rv_fmt_ldst_vd_rs1_vs2_vm     "O\tD,(1),Fm"
> +#define rv_fmt_vd_vs2_vs1             "O\tD,F,E"
> +#define rv_fmt_vd_vs2_vs1_vl          "O\tD,F,El"
> +#define rv_fmt_vd_vs2_vs1_vm          "O\tD,F,Em"
> +#define rv_fmt_vd_vs2_rs1_vl          "O\tD,F,1l"
> +#define rv_fmt_vd_vs2_fs1_vl          "O\tD,F,4l"
> +#define rv_fmt_vd_vs2_rs1_vm          "O\tD,F,1m"
> +#define rv_fmt_vd_vs2_fs1_vm          "O\tD,F,4m"
> +#define rv_fmt_vd_vs2_imm_vl          "O\tD,F,il"
> +#define rv_fmt_vd_vs2_imm_vm          "O\tD,F,im"
> +#define rv_fmt_vd_vs2_uimm_vm         "O\tD,F,um"
> +#define rv_fmt_vd_vs1_vs2_vm          "O\tD,E,Fm"
> +#define rv_fmt_vd_rs1_vs2_vm          "O\tD,1,Fm"
> +#define rv_fmt_vd_fs1_vs2_vm          "O\tD,4,Fm"
> +#define rv_fmt_vd_vs1                 "O\tD,E"
> +#define rv_fmt_vd_rs1                 "O\tD,1"
> +#define rv_fmt_vd_fs1                 "O\tD,4"
> +#define rv_fmt_vd_imm                 "O\tD,i"
> +#define rv_fmt_vd_vs2                 "O\tD,F"
> +#define rv_fmt_vd_vs2_vm              "O\tD,Fm"
> +#define rv_fmt_rd_vs2_vm              "O\t0,Fm"
> +#define rv_fmt_rd_vs2                 "O\t0,F"
> +#define rv_fmt_fd_vs2                 "O\t3,F"
> +#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"
> +
> +#endif /* DISAS_RISCV_H */
> --
> 2.40.1
>
>


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

* Re: [PATCH 4/9] disas/riscv: Make rv_op_illegal a shared enum value
  2023-05-30 13:18 ` [PATCH 4/9] disas/riscv: Make rv_op_illegal a shared enum value Christoph Muellner
@ 2023-06-12  3:24   ` Alistair Francis
  2023-06-12  6:48   ` LIU Zhiwei
  1 sibling, 0 replies; 30+ messages in thread
From: Alistair Francis @ 2023-06-12  3:24 UTC (permalink / raw)
  To: Christoph Muellner
  Cc: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
	Philipp Tomsich, Palmer Dabbelt, Richard Henderson, Zhiwei Liu

On Tue, May 30, 2023 at 11:22 PM Christoph Muellner
<christoph.muellner@vrull.eu> wrote:
>
> From: Christoph Müllner <christoph.muellner@vrull.eu>
>
> The enum value 'rv_op_illegal' does not represent an
> instruction, but is a catch-all value in case we have
> no match in the decoder. Let's make the value a shared
> one, so that other compile units can reuse it.
>
> Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>

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

Alistair

> ---
>  disas/riscv.c | 2 +-
>  disas/riscv.h | 4 ++++
>  2 files changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/disas/riscv.c b/disas/riscv.c
> index a062fb48cc..4cf477bc02 100644
> --- a/disas/riscv.c
> +++ b/disas/riscv.c
> @@ -22,7 +22,7 @@
>  #include "disas/riscv.h"
>
>  typedef enum {
> -    rv_op_illegal = 0,
> +    /* 0 is reserved for rv_op_illegal. */
>      rv_op_lui = 1,
>      rv_op_auipc = 2,
>      rv_op_jal = 3,
> diff --git a/disas/riscv.h b/disas/riscv.h
> index 0f34b71518..de2623e3cc 100644
> --- a/disas/riscv.h
> +++ b/disas/riscv.h
> @@ -189,6 +189,10 @@ typedef struct {
>      const rvc_constraint *constraints;
>  } rv_comp_data;
>
> +enum {
> +    rv_op_illegal = 0
> +};
> +
>  enum {
>      rvcd_imm_nz = 0x1
>  };
> --
> 2.40.1
>
>


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

* Re: [PATCH 5/9] disas/riscv: Encapsulate opcode_data into decode
  2023-05-30 13:18 ` [PATCH 5/9] disas/riscv: Encapsulate opcode_data into decode Christoph Muellner
@ 2023-06-12  3:26   ` Alistair Francis
  0 siblings, 0 replies; 30+ messages in thread
From: Alistair Francis @ 2023-06-12  3:26 UTC (permalink / raw)
  To: Christoph Muellner
  Cc: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
	Philipp Tomsich, Palmer Dabbelt, Richard Henderson, Zhiwei Liu

On Tue, May 30, 2023 at 11:23 PM Christoph Muellner
<christoph.muellner@vrull.eu> wrote:
>
> From: Christoph Müllner <christoph.muellner@vrull.eu>
>
> This patch adds a reference to a struct rv_opcode_data object
> into struct rv_decode. This further allows to remove all references
> to the global variable opcode_data (which is renamed to rvi_opcode_data).
>
> This patch does not introduce any functional change, but prepares
> the code for more struct rv_opcode_data objects in the future.
>
> This patch is based on previous work from Liu Zhiwei:
>   https://lists.nongnu.org/archive/html/qemu-devel/2022-08/msg03662.html
>
> Co-developed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
> Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>

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

Alistair

> ---
>  disas/riscv.c |  9 ++++++++-
>  disas/riscv.h | 33 +++++++++++++++++----------------
>  2 files changed, 25 insertions(+), 17 deletions(-)
>
> diff --git a/disas/riscv.c b/disas/riscv.c
> index 4cf477bc02..086edee6a2 100644
> --- a/disas/riscv.c
> +++ b/disas/riscv.c
> @@ -1055,7 +1055,7 @@ static const rv_comp_data rvcp_fsgnjx_q[] = {
>
>  /* instruction metadata */
>
> -const rv_opcode_data opcode_data[] = {
> +const rv_opcode_data rvi_opcode_data[] = {
>      { "illegal", rv_codec_illegal, rv_fmt_none, NULL, 0, 0, 0 },
>      { "lui", rv_codec_u, rv_fmt_rd_imm, NULL, 0, 0, 0 },
>      { "auipc", rv_codec_u, rv_fmt_rd_offset, NULL, 0, 0, 0 },
> @@ -3803,6 +3803,7 @@ static uint32_t operand_tbl_index(rv_inst inst)
>
>  static void decode_inst_operands(rv_decode *dec, rv_isa isa)
>  {
> +    const rv_opcode_data *opcode_data = dec->opcode_data;
>      rv_inst inst = dec->inst;
>      dec->codec = opcode_data[dec->op].codec;
>      switch (dec->codec) {
> @@ -4284,6 +4285,7 @@ static void append(char *s1, const char *s2, size_t n)
>
>  static void format_inst(char *buf, size_t buflen, size_t tab, rv_decode *dec)
>  {
> +    const rv_opcode_data *opcode_data = dec->opcode_data;
>      char tmp[64];
>      const char *fmt;
>
> @@ -4517,6 +4519,7 @@ static void format_inst(char *buf, size_t buflen, size_t tab, rv_decode *dec)
>
>  static void decode_inst_lift_pseudo(rv_decode *dec)
>  {
> +    const rv_opcode_data *opcode_data = dec->opcode_data;
>      const rv_comp_data *comp_data = opcode_data[dec->op].pseudo;
>      if (!comp_data) {
>          return;
> @@ -4535,6 +4538,7 @@ static void decode_inst_lift_pseudo(rv_decode *dec)
>
>  static void decode_inst_decompress_rv32(rv_decode *dec)
>  {
> +    const rv_opcode_data *opcode_data = dec->opcode_data;
>      int decomp_op = opcode_data[dec->op].decomp_rv32;
>      if (decomp_op != rv_op_illegal) {
>          if ((opcode_data[dec->op].decomp_data & rvcd_imm_nz)
> @@ -4549,6 +4553,7 @@ static void decode_inst_decompress_rv32(rv_decode *dec)
>
>  static void decode_inst_decompress_rv64(rv_decode *dec)
>  {
> +    const rv_opcode_data *opcode_data = dec->opcode_data;
>      int decomp_op = opcode_data[dec->op].decomp_rv64;
>      if (decomp_op != rv_op_illegal) {
>          if ((opcode_data[dec->op].decomp_data & rvcd_imm_nz)
> @@ -4563,6 +4568,7 @@ static void decode_inst_decompress_rv64(rv_decode *dec)
>
>  static void decode_inst_decompress_rv128(rv_decode *dec)
>  {
> +    const rv_opcode_data *opcode_data = dec->opcode_data;
>      int decomp_op = opcode_data[dec->op].decomp_rv128;
>      if (decomp_op != rv_op_illegal) {
>          if ((opcode_data[dec->op].decomp_data & rvcd_imm_nz)
> @@ -4598,6 +4604,7 @@ disasm_inst(char *buf, size_t buflen, rv_isa isa, uint64_t pc, rv_inst inst)
>      rv_decode dec = { 0 };
>      dec.pc = pc;
>      dec.inst = inst;
> +    dec.opcode_data = rvi_opcode_data;
>      decode_inst_opcode(&dec, isa);
>      decode_inst_operands(&dec, isa);
>      decode_inst_decompress(&dec, isa);
> diff --git a/disas/riscv.h b/disas/riscv.h
> index de2623e3cc..188f03feeb 100644
> --- a/disas/riscv.h
> +++ b/disas/riscv.h
> @@ -162,9 +162,26 @@ typedef enum {
>
>  /* structures */
>
> +typedef struct {
> +    const int op;
> +    const rvc_constraint *constraints;
> +} rv_comp_data;
> +
> +typedef struct {
> +    const char * const name;
> +    const rv_codec codec;
> +    const char * const format;
> +    const rv_comp_data *pseudo;
> +    const short decomp_rv32;
> +    const short decomp_rv64;
> +    const short decomp_rv128;
> +    const short decomp_data;
> +} rv_opcode_data;
> +
>  typedef struct {
>      uint64_t  pc;
>      uint64_t  inst;
> +    const rv_opcode_data *opcode_data;
>      int32_t   imm;
>      uint16_t  op;
>      uint8_t   codec;
> @@ -184,11 +201,6 @@ typedef struct {
>      uint8_t   rlist;
>  } rv_decode;
>
> -typedef struct {
> -    const int op;
> -    const rvc_constraint *constraints;
> -} rv_comp_data;
> -
>  enum {
>      rv_op_illegal = 0
>  };
> @@ -197,17 +209,6 @@ enum {
>      rvcd_imm_nz = 0x1
>  };
>
> -typedef struct {
> -    const char * const name;
> -    const rv_codec codec;
> -    const char * const format;
> -    const rv_comp_data *pseudo;
> -    const short decomp_rv32;
> -    const short decomp_rv64;
> -    const short decomp_rv128;
> -    const short decomp_data;
> -} rv_opcode_data;
> -
>  /* instruction formats */
>
>  #define rv_fmt_none                   "O\t"
> --
> 2.40.1
>
>


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

* Re: [PATCH 6/9] target/riscv/cpu: Share RISCVCPUConfig with disassembler
  2023-05-30 13:18 ` [PATCH 6/9] target/riscv/cpu: Share RISCVCPUConfig with disassembler Christoph Muellner
@ 2023-06-12  3:34   ` Alistair Francis
  2023-06-12  6:25   ` LIU Zhiwei
  1 sibling, 0 replies; 30+ messages in thread
From: Alistair Francis @ 2023-06-12  3:34 UTC (permalink / raw)
  To: Christoph Muellner
  Cc: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
	Philipp Tomsich, Palmer Dabbelt, Richard Henderson, Zhiwei Liu,
	Weiwei Li, Daniel Henrique Barboza

On Tue, May 30, 2023 at 11:20 PM Christoph Muellner
<christoph.muellner@vrull.eu> wrote:
>
> From: Christoph Müllner <christoph.muellner@vrull.eu>
>
> The disassembler needs the available extensions in order
> to properly decode instructions in case of overlapping
> encodings (e.g. for vendor extensions).
>
> Let's use the field 'disassemble_info::private_data' to store
> our RISCVCPUConfig pointer.
>
> Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>

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

Alistair

> ---
>  target/riscv/cpu.c | 3 +++
>  1 file changed, 3 insertions(+)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 5b7818dbd1..6f0cd9a0bb 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -819,6 +819,9 @@ static void riscv_cpu_disas_set_info(CPUState *s, disassemble_info *info)
>  {
>      RISCVCPU *cpu = RISCV_CPU(s);
>      CPURISCVState *env = &cpu->env;
> +    RISCVCPUConfig *cfg = &cpu->cfg;
> +
> +    info->private_data = cfg;
>
>      switch (env->xl) {
>      case MXL_RV32:
> --
> 2.40.1
>
>


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

* Re: [PATCH 7/9] disas/riscv: Provide infrastructure for vendor extensions
  2023-05-30 13:18 ` [PATCH 7/9] disas/riscv: Provide infrastructure for vendor extensions Christoph Muellner
  2023-06-08 13:04   ` LIU Zhiwei
@ 2023-06-12  3:37   ` Alistair Francis
  1 sibling, 0 replies; 30+ messages in thread
From: Alistair Francis @ 2023-06-12  3:37 UTC (permalink / raw)
  To: Christoph Muellner
  Cc: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
	Philipp Tomsich, Palmer Dabbelt, Richard Henderson, Zhiwei Liu

On Tue, May 30, 2023 at 11:21 PM Christoph Muellner
<christoph.muellner@vrull.eu> wrote:
>
> From: Christoph Müllner <christoph.muellner@vrull.eu>
>
> A previous patch provides a pointer to the RISCVCPUConfig data.
> Let's use this to add the necessary code for vendor extensions.
> This patch does not change the current behaviour, but clearly
> defines how vendor extension support can be added to the disassembler.
>
> Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>

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

Alistair

> ---
>  disas/riscv.c | 34 ++++++++++++++++++++++++++++++----
>  1 file changed, 30 insertions(+), 4 deletions(-)
>
> diff --git a/disas/riscv.c b/disas/riscv.c
> index 086edee6a2..db98e3ea6a 100644
> --- a/disas/riscv.c
> +++ b/disas/riscv.c
> @@ -20,6 +20,7 @@
>  #include "qemu/osdep.h"
>  #include "disas/dis-asm.h"
>  #include "disas/riscv.h"
> +#include "target/riscv/cpu-config.h"
>
>  typedef enum {
>      /* 0 is reserved for rv_op_illegal. */
> @@ -4599,13 +4600,38 @@ static void decode_inst_decompress(rv_decode *dec, rv_isa isa)
>  /* disassemble instruction */
>
>  static void
> -disasm_inst(char *buf, size_t buflen, rv_isa isa, uint64_t pc, rv_inst inst)
> +disasm_inst(char *buf, size_t buflen, rv_isa isa, uint64_t pc, rv_inst inst,
> +            struct disassemble_info *info)
>  {
> +    RISCVCPUConfig *cfg = info->private_data;
>      rv_decode dec = { 0 };
>      dec.pc = pc;
>      dec.inst = inst;
> -    dec.opcode_data = rvi_opcode_data;
> -    decode_inst_opcode(&dec, isa);
> +
> +    static const struct {
> +        bool (*guard_func)(const RISCVCPUConfig *);
> +        const rv_opcode_data *opcode_data;
> +        void (*decode_func)(rv_decode *, rv_isa);
> +    } decoders[] = {
> +        { always_true_p, rvi_opcode_data, decode_inst_opcode },
> +    };
> +
> +    for (size_t i = 0; i < ARRAY_SIZE(decoders); i++) {
> +        bool (*guard_func)(const RISCVCPUConfig *) = decoders[i].guard_func;
> +        const rv_opcode_data *opcode_data = decoders[i].opcode_data;
> +        void (*decode_func)(rv_decode *, rv_isa) = decoders[i].decode_func;
> +
> +        if (guard_func(cfg)) {
> +            dec.opcode_data = opcode_data;
> +            decode_func(&dec, isa);
> +            if (dec.op != rv_op_illegal)
> +                break;
> +        }
> +    }
> +
> +    if (dec.op == rv_op_illegal)
> +        dec.opcode_data = rvi_opcode_data;
> +
>      decode_inst_operands(&dec, isa);
>      decode_inst_decompress(&dec, isa);
>      decode_inst_lift_pseudo(&dec);
> @@ -4659,7 +4685,7 @@ print_insn_riscv(bfd_vma memaddr, struct disassemble_info *info, rv_isa isa)
>          break;
>      }
>
> -    disasm_inst(buf, sizeof(buf), isa, memaddr, inst);
> +    disasm_inst(buf, sizeof(buf), isa, memaddr, inst, info);
>      (*info->fprintf_func)(info->stream, "%s", buf);
>
>      return len;
> --
> 2.40.1
>
>


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

* Re: [PATCH 8/9] disas/riscv: Add support for XVentanaCondOps
  2023-05-30 13:18 ` [PATCH 8/9] disas/riscv: Add support for XVentanaCondOps Christoph Muellner
@ 2023-06-12  3:38   ` Alistair Francis
  0 siblings, 0 replies; 30+ messages in thread
From: Alistair Francis @ 2023-06-12  3:38 UTC (permalink / raw)
  To: Christoph Muellner
  Cc: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
	Philipp Tomsich, Palmer Dabbelt, Richard Henderson, Zhiwei Liu

On Tue, May 30, 2023 at 11:23 PM Christoph Muellner
<christoph.muellner@vrull.eu> wrote:
>
> From: Christoph Müllner <christoph.muellner@vrull.eu>
>
> This patch adds XVentanaCondOps support to the RISC-V disassembler.
>
> Co-developed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
> Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>

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

Alistair

> ---
>  disas/meson.build      |  5 ++++-
>  disas/riscv-xventana.c | 41 +++++++++++++++++++++++++++++++++++++++++
>  disas/riscv-xventana.h | 18 ++++++++++++++++++
>  disas/riscv.c          |  4 ++++
>  4 files changed, 67 insertions(+), 1 deletion(-)
>  create mode 100644 disas/riscv-xventana.c
>  create mode 100644 disas/riscv-xventana.h
>
> diff --git a/disas/meson.build b/disas/meson.build
> index 832727e4b3..e0ee326411 100644
> --- a/disas/meson.build
> +++ b/disas/meson.build
> @@ -6,7 +6,10 @@ common_ss.add(when: 'CONFIG_M68K_DIS', if_true: files('m68k.c'))
>  common_ss.add(when: 'CONFIG_MICROBLAZE_DIS', if_true: files('microblaze.c'))
>  common_ss.add(when: 'CONFIG_MIPS_DIS', if_true: files('mips.c', 'nanomips.c'))
>  common_ss.add(when: 'CONFIG_NIOS2_DIS', if_true: files('nios2.c'))
> -common_ss.add(when: 'CONFIG_RISCV_DIS', if_true: files('riscv.c'))
> +common_ss.add(when: 'CONFIG_RISCV_DIS', if_true: files(
> +    'riscv.c',
> +    'riscv-xventana.c'
> +))
>  common_ss.add(when: 'CONFIG_SH4_DIS', if_true: files('sh4.c'))
>  common_ss.add(when: 'CONFIG_SPARC_DIS', if_true: files('sparc.c'))
>  common_ss.add(when: 'CONFIG_XTENSA_DIS', if_true: files('xtensa.c'))
> diff --git a/disas/riscv-xventana.c b/disas/riscv-xventana.c
> new file mode 100644
> index 0000000000..a0224d1fb3
> --- /dev/null
> +++ b/disas/riscv-xventana.c
> @@ -0,0 +1,41 @@
> +/*
> + * QEMU RISC-V Disassembler for xventana.
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#include "disas/riscv.h"
> +#include "disas/riscv-xventana.h"
> +
> +typedef enum {
> +    /* 0 is reserved for rv_op_illegal. */
> +    ventana_op_vt_maskc = 1,
> +    ventana_op_vt_maskcn = 2,
> +} rv_ventana_op;
> +
> +const rv_opcode_data ventana_opcode_data[] = {
> +    { "vt.illegal", rv_codec_illegal, rv_fmt_none, NULL, 0, 0, 0 },
> +    { "vt.maskc", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
> +    { "vt.maskcn", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
> +};
> +
> +void decode_xventanacondops(rv_decode *dec, rv_isa isa)
> +{
> +    rv_inst inst = dec->inst;
> +    rv_opcode op = rv_op_illegal;
> +
> +    switch (((inst >> 0) & 0b11)) {
> +    case 3:
> +        switch (((inst >> 2) & 0b11111)) {
> +        case 30:
> +            switch (((inst >> 22) & 0b1111111000) | ((inst >> 12) & 0b0000000111)) {
> +            case 6: op = ventana_op_vt_maskc; break;
> +            case 7: op = ventana_op_vt_maskcn; break;
> +            }
> +            break;
> +        }
> +        break;
> +    }
> +
> +    dec->op = op;
> +}
> diff --git a/disas/riscv-xventana.h b/disas/riscv-xventana.h
> new file mode 100644
> index 0000000000..72be9ffa16
> --- /dev/null
> +++ b/disas/riscv-xventana.h
> @@ -0,0 +1,18 @@
> +/*
> + * QEMU disassembler -- RISC-V specific header (xventana*).
> + *
> + * Copyright (c) 2023 VRULL GmbH
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#ifndef DISAS_RISCV_XVENTANA_H
> +#define DISAS_RISCV_XVENTANA_H
> +
> +#include "disas/riscv.h"
> +
> +extern const rv_opcode_data ventana_opcode_data[];
> +
> +void decode_xventanacondops(rv_decode*, rv_isa);
> +
> +#endif /* DISAS_RISCV_XVENTANA_H */
> diff --git a/disas/riscv.c b/disas/riscv.c
> index db98e3ea6a..4f71333c45 100644
> --- a/disas/riscv.c
> +++ b/disas/riscv.c
> @@ -22,6 +22,9 @@
>  #include "disas/riscv.h"
>  #include "target/riscv/cpu-config.h"
>
> +/* Vendor extensions */
> +#include "disas/riscv-xventana.h"
> +
>  typedef enum {
>      /* 0 is reserved for rv_op_illegal. */
>      rv_op_lui = 1,
> @@ -4614,6 +4617,7 @@ disasm_inst(char *buf, size_t buflen, rv_isa isa, uint64_t pc, rv_inst inst,
>          void (*decode_func)(rv_decode *, rv_isa);
>      } decoders[] = {
>          { always_true_p, rvi_opcode_data, decode_inst_opcode },
> +        { has_XVentanaCondOps_p, ventana_opcode_data, decode_xventanacondops },
>      };
>
>      for (size_t i = 0; i < ARRAY_SIZE(decoders); i++) {
> --
> 2.40.1
>
>


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

* Re: [PATCH 9/9] disas/riscv: Add support for XThead* instructions
  2023-05-30 13:18 ` [PATCH 9/9] disas/riscv: Add support for XThead* instructions Christoph Muellner
@ 2023-06-12  3:40   ` Alistair Francis
  0 siblings, 0 replies; 30+ messages in thread
From: Alistair Francis @ 2023-06-12  3:40 UTC (permalink / raw)
  To: Christoph Muellner
  Cc: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
	Philipp Tomsich, Palmer Dabbelt, Richard Henderson, Zhiwei Liu,
	Weiwei Li, Daniel Henrique Barboza

On Tue, May 30, 2023 at 11:21 PM Christoph Muellner
<christoph.muellner@vrull.eu> wrote:
>
> From: Christoph Müllner <christoph.muellner@vrull.eu>
>
> Support for emulating XThead* instruction has been added recently.
> This patch adds support for these instructions to the RISC-V disassembler.
>
> Co-developed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
> Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>

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

Alistair

> ---
>  disas/meson.build         |   1 +
>  disas/riscv-xthead.c      | 707 ++++++++++++++++++++++++++++++++++++++
>  disas/riscv-xthead.h      |  28 ++
>  disas/riscv.c             |  69 ++++
>  disas/riscv.h             |  12 +
>  target/riscv/cpu-config.h |  11 +
>  6 files changed, 828 insertions(+)
>  create mode 100644 disas/riscv-xthead.c
>  create mode 100644 disas/riscv-xthead.h
>
> diff --git a/disas/meson.build b/disas/meson.build
> index e0ee326411..8f64e378f9 100644
> --- a/disas/meson.build
> +++ b/disas/meson.build
> @@ -8,6 +8,7 @@ common_ss.add(when: 'CONFIG_MIPS_DIS', if_true: files('mips.c', 'nanomips.c'))
>  common_ss.add(when: 'CONFIG_NIOS2_DIS', if_true: files('nios2.c'))
>  common_ss.add(when: 'CONFIG_RISCV_DIS', if_true: files(
>      'riscv.c',
> +    'riscv-xthead.c',
>      'riscv-xventana.c'
>  ))
>  common_ss.add(when: 'CONFIG_SH4_DIS', if_true: files('sh4.c'))
> diff --git a/disas/riscv-xthead.c b/disas/riscv-xthead.c
> new file mode 100644
> index 0000000000..99da679d16
> --- /dev/null
> +++ b/disas/riscv-xthead.c
> @@ -0,0 +1,707 @@
> +/*
> + * QEMU RISC-V Disassembler for xthead.
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#include "disas/riscv.h"
> +#include "disas/riscv-xthead.h"
> +
> +typedef enum {
> +    /* 0 is reserved for rv_op_illegal. */
> +    /* XTheadBa */
> +    rv_op_th_addsl = 1,
> +    /* XTheadBb */
> +    rv_op_th_srri,
> +    rv_op_th_srriw,
> +    rv_op_th_ext,
> +    rv_op_th_extu,
> +    rv_op_th_ff0,
> +    rv_op_th_ff1,
> +    rv_op_th_rev,
> +    rv_op_th_revw,
> +    rv_op_th_tstnbz,
> +    /* XTheadBs */
> +    rv_op_th_tst,
> +    /* XTheadCmo */
> +    rv_op_th_dcache_call,
> +    rv_op_th_dcache_ciall,
> +    rv_op_th_dcache_iall,
> +    rv_op_th_dcache_cpa,
> +    rv_op_th_dcache_cipa,
> +    rv_op_th_dcache_ipa,
> +    rv_op_th_dcache_cva,
> +    rv_op_th_dcache_civa,
> +    rv_op_th_dcache_iva,
> +    rv_op_th_dcache_csw,
> +    rv_op_th_dcache_cisw,
> +    rv_op_th_dcache_isw,
> +    rv_op_th_dcache_cpal1,
> +    rv_op_th_dcache_cval1,
> +    rv_op_th_icache_iall,
> +    rv_op_th_icache_ialls,
> +    rv_op_th_icache_ipa,
> +    rv_op_th_icache_iva,
> +    rv_op_th_l2cache_call,
> +    rv_op_th_l2cache_ciall,
> +    rv_op_th_l2cache_iall,
> +    /* XTheadCondMov */
> +    rv_op_th_mveqz,
> +    rv_op_th_mvnez,
> +    /* XTheadFMemIdx */
> +    rv_op_th_flrd,
> +    rv_op_th_flrw,
> +    rv_op_th_flurd,
> +    rv_op_th_flurw,
> +    rv_op_th_fsrd,
> +    rv_op_th_fsrw,
> +    rv_op_th_fsurd,
> +    rv_op_th_fsurw,
> +    /* XTheadFmv */
> +    rv_op_th_fmv_hw_x,
> +    rv_op_th_fmv_x_hw,
> +    /* XTheadMac */
> +    rv_op_th_mula,
> +    rv_op_th_mulah,
> +    rv_op_th_mulaw,
> +    rv_op_th_muls,
> +    rv_op_th_mulsw,
> +    rv_op_th_mulsh,
> +    /* XTheadMemIdx */
> +    rv_op_th_lbia,
> +    rv_op_th_lbib,
> +    rv_op_th_lbuia,
> +    rv_op_th_lbuib,
> +    rv_op_th_lhia,
> +    rv_op_th_lhib,
> +    rv_op_th_lhuia,
> +    rv_op_th_lhuib,
> +    rv_op_th_lwia,
> +    rv_op_th_lwib,
> +    rv_op_th_lwuia,
> +    rv_op_th_lwuib,
> +    rv_op_th_ldia,
> +    rv_op_th_ldib,
> +    rv_op_th_sbia,
> +    rv_op_th_sbib,
> +    rv_op_th_shia,
> +    rv_op_th_shib,
> +    rv_op_th_swia,
> +    rv_op_th_swib,
> +    rv_op_th_sdia,
> +    rv_op_th_sdib,
> +    rv_op_th_lrb,
> +    rv_op_th_lrbu,
> +    rv_op_th_lrh,
> +    rv_op_th_lrhu,
> +    rv_op_th_lrw,
> +    rv_op_th_lrwu,
> +    rv_op_th_lrd,
> +    rv_op_th_srb,
> +    rv_op_th_srh,
> +    rv_op_th_srw,
> +    rv_op_th_srd,
> +    rv_op_th_lurb,
> +    rv_op_th_lurbu,
> +    rv_op_th_lurh,
> +    rv_op_th_lurhu,
> +    rv_op_th_lurw,
> +    rv_op_th_lurwu,
> +    rv_op_th_lurd,
> +    rv_op_th_surb,
> +    rv_op_th_surh,
> +    rv_op_th_surw,
> +    rv_op_th_surd,
> +    /* XTheadMemPair */
> +    rv_op_th_ldd,
> +    rv_op_th_lwd,
> +    rv_op_th_lwud,
> +    rv_op_th_sdd,
> +    rv_op_th_swd,
> +    /* XTheadSync */
> +    rv_op_th_sfence_vmas,
> +    rv_op_th_sync,
> +    rv_op_th_sync_i,
> +    rv_op_th_sync_is,
> +    rv_op_th_sync_s,
> +} rv_xthead_op;
> +
> +const rv_opcode_data xthead_opcode_data[] = {
> +    { "th.illegal", rv_codec_illegal, rv_fmt_none, NULL, 0, 0, 0 },
> +    /* XTheadBa */
> +    { "th.addsl", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
> +    /* XTheadBb */
> +    { "th.srri", rv_codec_r2_imm6, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
> +    { "th.srriw", rv_codec_r2_imm5, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
> +    { "th.ext", rv_codec_r2_immhl, rv_fmt_rd_rs1_immh_imml, NULL, 0, 0, 0 },
> +    { "th.extu", rv_codec_r2_immhl, rv_fmt_rd_rs1_immh_imml, NULL, 0, 0, 0 },
> +    { "th.ff0", rv_codec_r2, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
> +    { "th.ff1", rv_codec_r2, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
> +    { "th.rev", rv_codec_r2, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
> +    { "th.revw", rv_codec_r2, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
> +    { "th.tstnbz", rv_codec_r2, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
> +    /* XTheadBs */
> +    { "th.tst", rv_codec_r2_imm6, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
> +    /* XTheadCmo */
> +    { "th.dcache.call", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
> +    { "th.dcache.ciall", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
> +    { "th.dcache.iall", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
> +    { "th.dcache.cpa", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 },
> +    { "th.dcache.cipa", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 },
> +    { "th.dcache.ipa", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 },
> +    { "th.dcache.cva", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 },
> +    { "th.dcache.civa", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 },
> +    { "th.dcache.iva", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 },
> +    { "th.dcache.csw", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 },
> +    { "th.dcache.cisw", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 },
> +    { "th.dcache.isw", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 },
> +    { "th.dcache.cpal1", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 },
> +    { "th.dcache.cval1", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 },
> +    { "th.icache.iall", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
> +    { "th.icache.ialls", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
> +    { "th.icache.ipa", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 },
> +    { "th.icache.iva", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 },
> +    { "th.l2cache.call", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
> +    { "th.l2cache.ciall", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
> +    { "th.l2cache.iall", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
> +    /* XTheadCondMov */
> +    { "th.mveqz", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
> +    { "th.mvnez", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
> +    /* XTheadFMemIdx */
> +    { "th.flrd", rv_codec_r_imm2, rv_fmt_frd_rs1_rs2_imm, NULL, 0, 0, 0 },
> +    { "th.flrw", rv_codec_r_imm2, rv_fmt_frd_rs1_rs2_imm, NULL, 0, 0, 0 },
> +    { "th.flurd", rv_codec_r_imm2, rv_fmt_frd_rs1_rs2_imm, NULL, 0, 0, 0 },
> +    { "th.flurw", rv_codec_r_imm2, rv_fmt_frd_rs1_rs2_imm, NULL, 0, 0, 0 },
> +    { "th.fsrd", rv_codec_r_imm2, rv_fmt_frd_rs1_rs2_imm, NULL, 0, 0, 0 },
> +    { "th.fsrw", rv_codec_r_imm2, rv_fmt_frd_rs1_rs2_imm, NULL, 0, 0, 0 },
> +    { "th.fsurd", rv_codec_r_imm2, rv_fmt_frd_rs1_rs2_imm, NULL, 0, 0, 0 },
> +    { "th.fsurw", rv_codec_r_imm2, rv_fmt_frd_rs1_rs2_imm, NULL, 0, 0, 0 },
> +    /* XTheadFmv */
> +    { "th.fmv.hw.x", rv_codec_r, rv_fmt_rd_frs1, NULL, 0, 0, 0 },
> +    { "th.fmv.x.hw", rv_codec_r, rv_fmt_rd_frs1, NULL, 0, 0, 0 },
> +    /* XTheadMac */
> +    { "th.mula", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
> +    { "th.mulaw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
> +    { "th.mulah", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
> +    { "th.muls", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
> +    { "th.mulsw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
> +    { "th.mulsh", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
> +    /* XTheadMemIdx */
> +    { "th.lbia", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
> +    { "th.lbib", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml, NULL, 0, 0, 0 },
> +    { "th.lbuia", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
> +    { "th.lbuib", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
> +    { "th.lhia", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
> +    { "th.lhib", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
> +    { "th.lhuia", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
> +    { "th.lhuib", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
> +    { "th.lwia", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
> +    { "th.lwib", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
> +    { "th.lwuia", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
> +    { "th.lwuib", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
> +    { "th.ldia", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
> +    { "th.ldib", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
> +    { "th.sbia", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
> +    { "th.sbib", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
> +    { "th.shia", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
> +    { "th.shib", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
> +    { "th.swia", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
> +    { "th.swib", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
> +    { "th.sdia", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
> +    { "th.sdib", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
> +    { "th.lrb", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
> +    { "th.lrbu", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
> +    { "th.lrh", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
> +    { "th.lrhu", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
> +    { "th.lrw", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
> +    { "th.lrwu", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
> +    { "th.lrd", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
> +    { "th.srb", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
> +    { "th.srh", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
> +    { "th.srw", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
> +    { "th.srd", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
> +    { "th.lurb", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
> +    { "th.lurbu", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
> +    { "th.lurh", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
> +    { "th.lurhu", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
> +    { "th.lurw", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
> +    { "th.lurwu", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
> +    { "th.lurd", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
> +    { "th.surb", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
> +    { "th.surh", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
> +    { "th.surw", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
> +    { "th.surd", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
> +    /* XTheadMemPair */
> +    { "th.ldd", rv_codec_r_imm2, rv_fmt_rd2_imm, NULL, 0, 0, 0 },
> +    { "th.lwd", rv_codec_r_imm2, rv_fmt_rd2_imm, NULL, 0, 0, 0 },
> +    { "th.lwud", rv_codec_r_imm2, rv_fmt_rd2_imm, NULL, 0, 0, 0 },
> +    { "th.sdd", rv_codec_r_imm2, rv_fmt_rd2_imm, NULL, 0, 0, 0 },
> +    { "th.swd", rv_codec_r_imm2, rv_fmt_rd2_imm, NULL, 0, 0, 0 },
> +    /* XTheadSync */
> +    { "th.sfence.vmas", rv_codec_r, rv_fmt_rs1_rs2, NULL, 0, 0, 0 },
> +    { "th.sync", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
> +    { "th.sync.i", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
> +    { "th.sync.is", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
> +    { "th.sync.s", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
> +};
> +
> +void decode_xtheadba(rv_decode *dec, rv_isa isa)
> +{
> +    rv_inst inst = dec->inst;
> +    rv_opcode op = rv_op_illegal;
> +
> +    switch (((inst >> 0) & 0b11)) {
> +    case 3:
> +        switch (((inst >> 2) & 0b11111)) {
> +        case 2:
> +            /* custom-0 */
> +            switch ((inst >> 12) & 0b111) {
> +            case 1:
> +                switch ((inst >> 25) & 0b1111111) {
> +                case 0b0000000:
> +                case 0b0000001:
> +                case 0b0000010:
> +                case 0b0000011: op = rv_op_th_addsl; break;
> +                }
> +                break;
> +            }
> +            break;
> +            /* custom-0 */
> +        }
> +        break;
> +    }
> +
> +    dec->op = op;
> +}
> +
> +void decode_xtheadbb(rv_decode *dec, rv_isa isa)
> +{
> +    rv_inst inst = dec->inst;
> +    rv_opcode op = rv_op_illegal;
> +
> +    switch (((inst >> 0) & 0b11)) {
> +    case 3:
> +        switch (((inst >> 2) & 0b11111)) {
> +        case 2:
> +            /* custom-0 */
> +            switch ((inst >> 12) & 0b111) {
> +            case 1:
> +                switch ((inst >> 25) & 0b1111111) {
> +                case 0b0001010: op = rv_op_th_srriw; break;
> +                case 0b1000000:
> +                    if (((inst >> 20) & 0b11111) == 0) {
> +                        op = rv_op_th_tstnbz;
> +                    }
> +                    break;
> +                case 0b1000001:
> +                    if (((inst >> 20) & 0b11111) == 0) {
> +                        op = rv_op_th_rev;
> +                    }
> +                    break;
> +                case 0b1000010:
> +                    if (((inst >> 20) & 0b11111) == 0) {
> +                        op = rv_op_th_ff0;
> +                    }
> +                    break;
> +                case 0b1000011:
> +                    if (((inst >> 20) & 0b11111) == 0) {
> +                        op = rv_op_th_ff1;
> +                    }
> +                    break;
> +                case 0b1000100:
> +                case 0b1001000:
> +                    if (((inst >> 20) & 0b11111) == 0) {
> +                        op = rv_op_th_revw;
> +                    }
> +                    break;
> +                case 0b0000100:
> +                case 0b0000101: op = rv_op_th_srri; break;
> +                }
> +                break;
> +            case 2: op = rv_op_th_ext; break;
> +            case 3: op = rv_op_th_extu; break;
> +            }
> +            break;
> +            /* custom-0 */
> +        }
> +        break;
> +    }
> +
> +    dec->op = op;
> +}
> +
> +void decode_xtheadbs(rv_decode *dec, rv_isa isa)
> +{
> +    rv_inst inst = dec->inst;
> +    rv_opcode op = rv_op_illegal;
> +
> +    switch (((inst >> 0) & 0b11)) {
> +    case 3:
> +        switch (((inst >> 2) & 0b11111)) {
> +        case 2:
> +            /* custom-0 */
> +            switch ((inst >> 12) & 0b111) {
> +            case 1:
> +                switch ((inst >> 26) & 0b111111) {
> +                case 0b100010: op = rv_op_th_tst; break;
> +                }
> +                break;
> +            }
> +            break;
> +            /* custom-0 */
> +        }
> +        break;
> +    }
> +
> +    dec->op = op;
> +}
> +
> +void decode_xtheadcmo(rv_decode *dec, rv_isa isa)
> +{
> +    rv_inst inst = dec->inst;
> +    rv_opcode op = rv_op_illegal;
> +
> +    switch (((inst >> 0) & 0b11)) {
> +    case 3:
> +        switch (((inst >> 2) & 0b11111)) {
> +        case 2:
> +            /* custom-0 */
> +            switch ((inst >> 12) & 0b111) {
> +            case 0:
> +                switch ((inst >> 20 & 0b111111111111)) {
> +                case 0b000000000001:
> +                    if (((inst >> 20) & 0b11111) == 0) {
> +                        op = rv_op_th_dcache_call;
> +                    }
> +                    break;
> +                case 0b000000000011:
> +                    if (((inst >> 20) & 0b11111) == 0) {
> +                        op = rv_op_th_dcache_ciall;
> +                    }
> +                    break;
> +                case 0b000000000010:
> +                    if (((inst >> 20) & 0b11111) == 0) {
> +                        op = rv_op_th_dcache_iall;
> +                    }
> +                    break;
> +                case 0b000000101001: op = rv_op_th_dcache_cpa; break;
> +                case 0b000000101011: op = rv_op_th_dcache_cipa; break;
> +                case 0b000000101010: op = rv_op_th_dcache_ipa; break;
> +                case 0b000000100101: op = rv_op_th_dcache_cva; break;
> +                case 0b000000100111: op = rv_op_th_dcache_civa; break;
> +                case 0b000000100110: op = rv_op_th_dcache_iva; break;
> +                case 0b000000100001: op = rv_op_th_dcache_csw; break;
> +                case 0b000000100011: op = rv_op_th_dcache_cisw; break;
> +                case 0b000000100010: op = rv_op_th_dcache_isw; break;
> +                case 0b000000101000: op = rv_op_th_dcache_cpal1; break;
> +                case 0b000000100100: op = rv_op_th_dcache_cval1; break;
> +                case 0b000000010000:
> +                    if (((inst >> 20) & 0b11111) == 0) {
> +                        op = rv_op_th_icache_iall;
> +                    }
> +                    break;
> +                case 0b000000010001:
> +                    if (((inst >> 20) & 0b11111) == 0) {
> +                        op = rv_op_th_icache_ialls;
> +                    }
> +                    break;
> +                case 0b000000111000: op = rv_op_th_icache_ipa; break;
> +                case 0b000000110000: op = rv_op_th_icache_iva; break;
> +                case 0b000000010101:
> +                    if (((inst >> 20) & 0b11111) == 0) {
> +                        op = rv_op_th_l2cache_call;
> +                    }
> +                    break;
> +                case 0b000000010111:
> +                    if (((inst >> 20) & 0b11111) == 0) {
> +                        op = rv_op_th_l2cache_ciall;
> +                    }
> +                    break;
> +                case 0b000000010110:
> +                    if (((inst >> 20) & 0b11111) == 0) {
> +                        op = rv_op_th_l2cache_iall;
> +                    }
> +                    break;
> +                }
> +                break;
> +            }
> +            break;
> +            /* custom-0 */
> +        }
> +        break;
> +    }
> +
> +    dec->op = op;
> +}
> +
> +void decode_xtheadcondmov(rv_decode *dec, rv_isa isa)
> +{
> +    rv_inst inst = dec->inst;
> +    rv_opcode op = rv_op_illegal;
> +
> +    switch (((inst >> 0) & 0b11)) {
> +    case 3:
> +        switch (((inst >> 2) & 0b11111)) {
> +        case 2:
> +            /* custom-0 */
> +            switch ((inst >> 12) & 0b111) {
> +            case 1:
> +                switch ((inst >> 25) & 0b1111111) {
> +                case 0b0100000: op = rv_op_th_mveqz; break;
> +                case 0b0100001: op = rv_op_th_mvnez; break;
> +                }
> +                break;
> +            }
> +            break;
> +            /* custom-0 */
> +        }
> +        break;
> +    }
> +
> +    dec->op = op;
> +}
> +
> +void decode_xtheadfmemidx(rv_decode *dec, rv_isa isa)
> +{
> +    rv_inst inst = dec->inst;
> +    rv_opcode op = rv_op_illegal;
> +
> +    switch (((inst >> 0) & 0b11)) {
> +    case 3:
> +        switch (((inst >> 2) & 0b11111)) {
> +        case 2:
> +            /* custom-0 */
> +            switch ((inst >> 12) & 0b111) {
> +            case 6:
> +                switch ((inst >> 27) & 0b11111) {
> +                case 8: op = rv_op_th_flrw; break;
> +                case 10: op = rv_op_th_flurw; break;
> +                case 12: op = rv_op_th_flrd; break;
> +                case 14: op = rv_op_th_flurd; break;
> +                }
> +                break;
> +            case 7:
> +                switch ((inst >> 27) & 0b11111) {
> +                case 8: op = rv_op_th_fsrw; break;
> +                case 10: op = rv_op_th_fsurw; break;
> +                case 12: op = rv_op_th_fsrd; break;
> +                case 14: op = rv_op_th_fsurd; break;
> +                }
> +                break;
> +            }
> +            break;
> +            /* custom-0 */
> +        }
> +        break;
> +    }
> +
> +    dec->op = op;
> +}
> +
> +void decode_xtheadfmv(rv_decode *dec, rv_isa isa)
> +{
> +    rv_inst inst = dec->inst;
> +    rv_opcode op = rv_op_illegal;
> +
> +    switch (((inst >> 0) & 0b11)) {
> +    case 3:
> +        switch (((inst >> 2) & 0b11111)) {
> +        case 2:
> +            /* custom-0 */
> +            switch ((inst >> 12) & 0b111) {
> +            case 1:
> +                switch ((inst >> 25) & 0b1111111) {
> +                case 0b1010000:
> +                    if (((inst >> 20) & 0b11111) == 0) {
> +                        op = rv_op_th_fmv_hw_x;
> +                    }
> +                    break;
> +                case 0b1100000:
> +                    if (((inst >> 20) & 0b11111) == 0) {
> +                        op = rv_op_th_fmv_x_hw;
> +                    }
> +                    break;
> +                }
> +                break;
> +            }
> +            break;
> +            /* custom-0 */
> +        }
> +        break;
> +    }
> +
> +    dec->op = op;
> +}
> +
> +void decode_xtheadmac(rv_decode *dec, rv_isa isa)
> +{
> +    rv_inst inst = dec->inst;
> +    rv_opcode op = rv_op_illegal;
> +
> +    switch (((inst >> 0) & 0b11)) {
> +    case 3:
> +        switch (((inst >> 2) & 0b11111)) {
> +        case 2:
> +            /* custom-0 */
> +            switch ((inst >> 12) & 0b111) {
> +            case 1:
> +                switch ((inst >> 25) & 0b1111111) {
> +                case 0b0010000: op = rv_op_th_mula; break;
> +                case 0b0010001: op = rv_op_th_muls; break;
> +                case 0b0010010: op = rv_op_th_mulaw; break;
> +                case 0b0010011: op = rv_op_th_mulsw; break;
> +                case 0b0010100: op = rv_op_th_mulah; break;
> +                case 0b0010101: op = rv_op_th_mulsh; break;
> +                }
> +                break;
> +            }
> +            break;
> +            /* custom-0 */
> +        }
> +        break;
> +    }
> +
> +    dec->op = op;
> +}
> +
> +void decode_xtheadmemidx(rv_decode *dec, rv_isa isa)
> +{
> +    rv_inst inst = dec->inst;
> +    rv_opcode op = rv_op_illegal;
> +
> +    switch (((inst >> 0) & 0b11)) {
> +    case 3:
> +        switch (((inst >> 2) & 0b11111)) {
> +        case 2:
> +            /* custom-0 */
> +            switch ((inst >> 12) & 0b111) {
> +            case 4:
> +                switch ((inst >> 27) & 0b11111) {
> +                case 0: op = rv_op_th_lrb; break;
> +                case 1: op = rv_op_th_lbib; break;
> +                case 2: op = rv_op_th_lurb; break;
> +                case 3: op = rv_op_th_lbia; break;
> +                case 4: op = rv_op_th_lrh; break;
> +                case 5: op = rv_op_th_lhib; break;
> +                case 6: op = rv_op_th_lurh; break;
> +                case 7: op = rv_op_th_lhia; break;
> +                case 8: op = rv_op_th_lrw; break;
> +                case 9: op = rv_op_th_lwib; break;
> +                case 10: op = rv_op_th_lurw; break;
> +                case 11: op = rv_op_th_lwia; break;
> +                case 12: op = rv_op_th_lrd; break;
> +                case 13: op = rv_op_th_ldib; break;
> +                case 14: op = rv_op_th_lurd; break;
> +                case 15: op = rv_op_th_ldia; break;
> +                case 16: op = rv_op_th_lrbu; break;
> +                case 17: op = rv_op_th_lbuib; break;
> +                case 18: op = rv_op_th_lurbu; break;
> +                case 19: op = rv_op_th_lbuia; break;
> +                case 20: op = rv_op_th_lrhu; break;
> +                case 21: op = rv_op_th_lhuib; break;
> +                case 22: op = rv_op_th_lurhu; break;
> +                case 23: op = rv_op_th_lhuia; break;
> +                case 24: op = rv_op_th_lrwu; break;
> +                case 25: op = rv_op_th_lwuib; break;
> +                case 26: op = rv_op_th_lurwu; break;
> +                case 27: op = rv_op_th_lwuia; break;
> +                }
> +                break;
> +            case 5:
> +                switch ((inst >> 27) & 0b11111) {
> +                case 0: op = rv_op_th_srb; break;
> +                case 1: op = rv_op_th_sbib; break;
> +                case 2: op = rv_op_th_surb; break;
> +                case 3: op = rv_op_th_sbia; break;
> +                case 4: op = rv_op_th_srh; break;
> +                case 5: op = rv_op_th_shib; break;
> +                case 6: op = rv_op_th_surh; break;
> +                case 7: op = rv_op_th_shia; break;
> +                case 8: op = rv_op_th_srw; break;
> +                case 9: op = rv_op_th_swib; break;
> +                case 10: op = rv_op_th_surw; break;
> +                case 11: op = rv_op_th_swia; break;
> +                case 12: op = rv_op_th_srd; break;
> +                case 13: op = rv_op_th_sdib; break;
> +                case 14: op = rv_op_th_surd; break;
> +                case 15: op = rv_op_th_sdia; break;
> +                }
> +                break;
> +                break;
> +            }
> +            break;
> +            /* custom-0 */
> +        }
> +        break;
> +    }
> +
> +    dec->op = op;
> +}
> +
> +void decode_xtheadmempair(rv_decode *dec, rv_isa isa)
> +{
> +    rv_inst inst = dec->inst;
> +    rv_opcode op = rv_op_illegal;
> +
> +    switch (((inst >> 0) & 0b11)) {
> +    case 3:
> +        switch (((inst >> 2) & 0b11111)) {
> +        case 2:
> +            /* custom-0 */
> +            switch ((inst >> 12) & 0b111) {
> +            case 4:
> +                switch ((inst >> 27) & 0b11111) {
> +                case 28: op = rv_op_th_lwd; break;
> +                case 30: op = rv_op_th_lwud; break;
> +                case 31: op = rv_op_th_ldd; break;
> +                }
> +                break;
> +            case 5:
> +                switch ((inst >> 27) & 0b11111) {
> +                case 28: op = rv_op_th_swd; break;
> +                case 31: op = rv_op_th_sdd; break;
> +                }
> +                break;
> +            }
> +            break;
> +            /* custom-0 */
> +        }
> +        break;
> +    }
> +
> +    dec->op = op;
> +}
> +
> +void decode_xtheadsync(rv_decode *dec, rv_isa isa)
> +{
> +    rv_inst inst = dec->inst;
> +    rv_opcode op = rv_op_illegal;
> +
> +    switch (((inst >> 0) & 0b11)) {
> +    case 3:
> +        switch (((inst >> 2) & 0b11111)) {
> +        case 2:
> +            /* custom-0 */
> +            switch ((inst >> 12) & 0b111) {
> +            case 0:
> +                switch ((inst >> 25) & 0b1111111) {
> +                case 0b0000010: op = rv_op_th_sfence_vmas; break;
> +                case 0b0000000:
> +                    switch ((inst >> 20) & 0b11111) {
> +                    case 0b11000: op = rv_op_th_sync; break;
> +                    case 0b11010: op = rv_op_th_sync_i; break;
> +                    case 0b11011: op = rv_op_th_sync_is; break;
> +                    case 0b11001: op = rv_op_th_sync_s; break;
> +                    }
> +                    break;
> +                }
> +                break;
> +            }
> +            break;
> +            /* custom-0 */
> +        }
> +        break;
> +    }
> +
> +    dec->op = op;
> +}
> diff --git a/disas/riscv-xthead.h b/disas/riscv-xthead.h
> new file mode 100644
> index 0000000000..fcd42746e7
> --- /dev/null
> +++ b/disas/riscv-xthead.h
> @@ -0,0 +1,28 @@
> +/*
> + * QEMU disassembler -- RISC-V specific header (xthead*).
> + *
> + * Copyright (c) 2023 VRULL GmbH
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#ifndef DISAS_RISCV_XTHEAD_H
> +#define DISAS_RISCV_XTHEAD_H
> +
> +#include "disas/riscv.h"
> +
> +extern const rv_opcode_data xthead_opcode_data[];
> +
> +void decode_xtheadba(rv_decode *, rv_isa);
> +void decode_xtheadbb(rv_decode *, rv_isa);
> +void decode_xtheadbs(rv_decode *, rv_isa);
> +void decode_xtheadcmo(rv_decode *, rv_isa);
> +void decode_xtheadcondmov(rv_decode *, rv_isa);
> +void decode_xtheadfmemidx(rv_decode *, rv_isa);
> +void decode_xtheadfmv(rv_decode *, rv_isa);
> +void decode_xtheadmac(rv_decode *, rv_isa);
> +void decode_xtheadmemidx(rv_decode *, rv_isa);
> +void decode_xtheadmempair(rv_decode *, rv_isa);
> +void decode_xtheadsync(rv_decode *, rv_isa);
> +
> +#endif /* DISAS_RISCV_XTHEAD_H */
> diff --git a/disas/riscv.c b/disas/riscv.c
> index 4f71333c45..b1a30928df 100644
> --- a/disas/riscv.c
> +++ b/disas/riscv.c
> @@ -18,11 +18,13 @@
>   */
>
>  #include "qemu/osdep.h"
> +#include "qemu/bitops.h"
>  #include "disas/dis-asm.h"
>  #include "disas/riscv.h"
>  #include "target/riscv/cpu-config.h"
>
>  /* Vendor extensions */
> +#include "disas/riscv-xthead.h"
>  #include "disas/riscv-xventana.h"
>
>  typedef enum {
> @@ -3784,6 +3786,26 @@ static uint32_t operand_zcmp_rlist(rv_inst inst)
>      return ((inst << 56) >> 60);
>  }
>
> +static uint32_t operand_imm6(rv_inst inst)
> +{
> +    return (inst << 38) >> 60;
> +}
> +
> +static uint32_t operand_imm2(rv_inst inst)
> +{
> +    return (inst << 37) >> 62;
> +}
> +
> +static uint32_t operand_immh(rv_inst inst)
> +{
> +    return (inst << 32) >> 58;
> +}
> +
> +static uint32_t operand_imml(rv_inst inst)
> +{
> +    return (inst << 38) >> 58;
> +}
> +
>  static uint32_t calculate_stack_adj(rv_isa isa, uint32_t rlist, uint32_t spimm)
>  {
>      int xlen_bytes_log2 = isa == rv64 ? 3 : 2;
> @@ -4148,6 +4170,38 @@ static void decode_inst_operands(rv_decode *dec, rv_isa isa)
>      case rv_codec_zcmt_jt:
>          dec->imm = operand_tbl_index(inst);
>          break;
> +    case rv_codec_r2_imm5:
> +        dec->rd = operand_rd(inst);
> +        dec->rs1 = operand_rs1(inst);
> +        dec->imm = operand_rs2(inst);
> +        break;
> +    case rv_codec_r2:
> +        dec->rd = operand_rd(inst);
> +        dec->rs1 = operand_rs1(inst);
> +        break;
> +    case rv_codec_r2_imm6:
> +        dec->rd = operand_rd(inst);
> +        dec->rs1 = operand_rs1(inst);
> +        dec->imm = operand_imm6(inst);
> +        break;
> +    case rv_codec_r_imm2:
> +        dec->rd = operand_rd(inst);
> +        dec->rs1 = operand_rs1(inst);
> +        dec->rs2 = operand_rs2(inst);
> +        dec->imm = operand_imm2(inst);
> +        break;
> +    case rv_codec_r2_immhl:
> +        dec->rd = operand_rd(inst);
> +        dec->rs1 = operand_rs1(inst);
> +        dec->imm = operand_immh(inst);
> +        dec->imm1 = operand_imml(inst);
> +        break;
> +    case rv_codec_r2_imm2_imm5:
> +        dec->rd = operand_rd(inst);
> +        dec->rs1 = operand_rs1(inst);
> +        dec->imm = sextract32(operand_rs2(inst), 0, 5);
> +        dec->imm1 = operand_imm2(inst);
> +        break;
>      };
>  }
>
> @@ -4352,6 +4406,10 @@ static void format_inst(char *buf, size_t buflen, size_t tab, rv_decode *dec)
>              snprintf(tmp, sizeof(tmp), "%u", ((uint32_t)dec->imm & 0b11111));
>              append(buf, tmp, buflen);
>              break;
> +        case 'j':
> +            snprintf(tmp, sizeof(tmp), "%d", dec->imm1);
> +            append(buf, tmp, buflen);
> +            break;
>          case 'o':
>              snprintf(tmp, sizeof(tmp), "%d", dec->imm);
>              append(buf, tmp, buflen);
> @@ -4617,6 +4675,17 @@ disasm_inst(char *buf, size_t buflen, rv_isa isa, uint64_t pc, rv_inst inst,
>          void (*decode_func)(rv_decode *, rv_isa);
>      } decoders[] = {
>          { always_true_p, rvi_opcode_data, decode_inst_opcode },
> +        { has_xtheadba_p, xthead_opcode_data, decode_xtheadba },
> +        { has_xtheadbb_p, xthead_opcode_data, decode_xtheadbb },
> +        { has_xtheadbs_p, xthead_opcode_data, decode_xtheadbs },
> +        { has_xtheadcmo_p, xthead_opcode_data, decode_xtheadcmo },
> +        { has_xtheadcondmov_p, xthead_opcode_data, decode_xtheadcondmov },
> +        { has_xtheadfmemidx_p, xthead_opcode_data, decode_xtheadfmemidx },
> +        { has_xtheadfmv_p, xthead_opcode_data, decode_xtheadfmv },
> +        { has_xtheadmac_p, xthead_opcode_data, decode_xtheadmac },
> +        { has_xtheadmemidx_p, xthead_opcode_data, decode_xtheadmemidx },
> +        { has_xtheadmempair_p, xthead_opcode_data, decode_xtheadmempair },
> +        { has_xtheadsync_p, xthead_opcode_data, decode_xtheadsync },
>          { has_XVentanaCondOps_p, ventana_opcode_data, decode_xventanacondops },
>      };
>
> diff --git a/disas/riscv.h b/disas/riscv.h
> index 188f03feeb..f7ece1bb53 100644
> --- a/disas/riscv.h
> +++ b/disas/riscv.h
> @@ -158,6 +158,12 @@ typedef enum {
>      rv_codec_zcmp_cm_pushpop,
>      rv_codec_zcmp_cm_mv,
>      rv_codec_zcmt_jt,
> +    rv_codec_r2_imm5,
> +    rv_codec_r2,
> +    rv_codec_r2_imm6,
> +    rv_codec_r_imm2,
> +    rv_codec_r2_immhl,
> +    rv_codec_r2_imm2_imm5,
>  } rv_codec;
>
>  /* structures */
> @@ -183,6 +189,7 @@ typedef struct {
>      uint64_t  inst;
>      const rv_opcode_data *opcode_data;
>      int32_t   imm;
> +    int32_t   imm1;
>      uint16_t  op;
>      uint8_t   codec;
>      uint8_t   rd;
> @@ -281,5 +288,10 @@ enum {
>  #define rv_fmt_push_rlist             "O\tx,-i"
>  #define rv_fmt_pop_rlist              "O\tx,i"
>  #define rv_fmt_zcmt_index             "O\ti"
> +#define rv_fmt_rd_rs1_rs2_imm         "O\t0,1,2,i"
> +#define rv_fmt_frd_rs1_rs2_imm        "O\t3,1,2,i"
> +#define rv_fmt_rd_rs1_immh_imml       "O\t0,1,i,j"
> +#define rv_fmt_rd_rs1_immh_imml_addr  "O\t0,(1),i,j"
> +#define rv_fmt_rd2_imm                "O\t0,2,(1),i"
>
>  #endif /* DISAS_RISCV_H */
> diff --git a/target/riscv/cpu-config.h b/target/riscv/cpu-config.h
> index ca368af0b2..ae7c1a44ff 100644
> --- a/target/riscv/cpu-config.h
> +++ b/target/riscv/cpu-config.h
> @@ -143,6 +143,17 @@ static inline bool has_xthead_p(const RISCVCPUConfig *cfg)
>          return cfg->ext_ ## ext ; \
>      }
>
> +MATERIALISE_EXT_PREDICATE(xtheadba)
> +MATERIALISE_EXT_PREDICATE(xtheadbb)
> +MATERIALISE_EXT_PREDICATE(xtheadbs)
> +MATERIALISE_EXT_PREDICATE(xtheadcmo)
> +MATERIALISE_EXT_PREDICATE(xtheadcondmov)
> +MATERIALISE_EXT_PREDICATE(xtheadfmemidx)
> +MATERIALISE_EXT_PREDICATE(xtheadfmv)
> +MATERIALISE_EXT_PREDICATE(xtheadmac)
> +MATERIALISE_EXT_PREDICATE(xtheadmemidx)
> +MATERIALISE_EXT_PREDICATE(xtheadmempair)
> +MATERIALISE_EXT_PREDICATE(xtheadsync)
>  MATERIALISE_EXT_PREDICATE(XVentanaCondOps)
>
>  #endif /* RISCV_CPU_CONFIG_H */
> --
> 2.40.1
>
>


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

* Re: [PATCH 6/9] target/riscv/cpu: Share RISCVCPUConfig with disassembler
  2023-05-30 13:18 ` [PATCH 6/9] target/riscv/cpu: Share RISCVCPUConfig with disassembler Christoph Muellner
  2023-06-12  3:34   ` Alistair Francis
@ 2023-06-12  6:25   ` LIU Zhiwei
  2023-06-12  9:47     ` Christoph Müllner
  1 sibling, 1 reply; 30+ messages in thread
From: LIU Zhiwei @ 2023-06-12  6:25 UTC (permalink / raw)
  To: Christoph Muellner, qemu-riscv, qemu-devel, Alistair Francis,
	Bin Meng, Philipp Tomsich, Palmer Dabbelt, Richard Henderson,
	Zhiwei Liu
  Cc: Weiwei Li, Daniel Henrique Barboza


On 2023/5/30 21:18, Christoph Muellner wrote:
> From: Christoph Müllner <christoph.muellner@vrull.eu>
>
> The disassembler needs the available extensions in order
> to properly decode instructions in case of overlapping
> encodings (e.g. for vendor extensions).
>
> Let's use the field 'disassemble_info::private_data' to store
> our RISCVCPUConfig pointer.
>
> Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
> ---
>   target/riscv/cpu.c | 3 +++
>   1 file changed, 3 insertions(+)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 5b7818dbd1..6f0cd9a0bb 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -819,6 +819,9 @@ static void riscv_cpu_disas_set_info(CPUState *s, disassemble_info *info)
>   {
>       RISCVCPU *cpu = RISCV_CPU(s);
>       CPURISCVState *env = &cpu->env;
> +    RISCVCPUConfig *cfg = &cpu->cfg;
> +
> +    info->private_data = cfg;

I don't know if this field will be overridden by the binutils. Can we 
extend the struct disassemble_info, and add some fields like supporting 
for Capstone?

Zhiwei

>   
>       switch (env->xl) {
>       case MXL_RV32:


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

* Re: [PATCH 2/9] target/riscv: Factor out RISCVCPUConfig from cpu.h
  2023-05-30 13:18 ` [PATCH 2/9] target/riscv: Factor out RISCVCPUConfig from cpu.h Christoph Muellner
  2023-06-12  3:21   ` Alistair Francis
@ 2023-06-12  6:40   ` LIU Zhiwei
  1 sibling, 0 replies; 30+ messages in thread
From: LIU Zhiwei @ 2023-06-12  6:40 UTC (permalink / raw)
  To: Christoph Muellner, qemu-riscv, qemu-devel, Alistair Francis,
	Bin Meng, Philipp Tomsich, Palmer Dabbelt, Richard Henderson
  Cc: Weiwei Li, Daniel Henrique Barboza


On 2023/5/30 21:18, Christoph Muellner wrote:
> From: Christoph Müllner <christoph.muellner@vrull.eu>
>
> The file target/riscv/cpu.h cannot be included by files outside
> of target/riscv/. To share data with other parts of QEMU (e.g.
> the disassembler) we need to factor out the relevant code.
> Therefore, this patch moves the definition of RISCVCPUConfig
> (and tightly coupled dependencies and functions) into its
> own target/riscv/cpu-config.h file.
> The goal is to be able to share the enablement-status of
> the RISC-V ISA extensions (RISCVCPUConfig::ext_*) with
> other parts of QEMU.
>
> This patch does not introduce new functionality.
> However, the patch includes a small change:
> The parameter for the extension test functions has been changed
> from 'DisasContext*' to 'const RISCVCPUConfig*'.
> This allows to keep these functions in cpu-config.h.
>
> Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>

Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>

Zhiwei

> ---
>   target/riscv/cpu-config.h | 148 ++++++++++++++++++++++++++++++++++++++
>   target/riscv/cpu.h        | 114 +----------------------------
>   target/riscv/translate.c  |  27 +------
>   3 files changed, 151 insertions(+), 138 deletions(-)
>   create mode 100644 target/riscv/cpu-config.h
>
> diff --git a/target/riscv/cpu-config.h b/target/riscv/cpu-config.h
> new file mode 100644
> index 0000000000..ca368af0b2
> --- /dev/null
> +++ b/target/riscv/cpu-config.h
> @@ -0,0 +1,148 @@
> +/*
> + * QEMU RISC-V CPU Config
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#ifndef RISCV_CPU_CONFIG_H
> +#define RISCV_CPU_CONFIG_H
> +
> +/*
> + * map is a 16-bit bitmap: the most significant set bit in map is the maximum
> + * satp mode that is supported. It may be chosen by the user and must respect
> + * what qemu implements (valid_1_10_32/64) and what the hw is capable of
> + * (supported bitmap below).
> + *
> + * init is a 16-bit bitmap used to make sure the user selected a correct
> + * configuration as per the specification.
> + *
> + * supported is a 16-bit bitmap used to reflect the hw capabilities.
> + */
> +typedef struct {
> +    uint16_t map, init, supported;
> +} RISCVSATPMap;
> +
> +struct RISCVCPUConfig {
> +    bool ext_zba;
> +    bool ext_zbb;
> +    bool ext_zbc;
> +    bool ext_zbkb;
> +    bool ext_zbkc;
> +    bool ext_zbkx;
> +    bool ext_zbs;
> +    bool ext_zca;
> +    bool ext_zcb;
> +    bool ext_zcd;
> +    bool ext_zce;
> +    bool ext_zcf;
> +    bool ext_zcmp;
> +    bool ext_zcmt;
> +    bool ext_zk;
> +    bool ext_zkn;
> +    bool ext_zknd;
> +    bool ext_zkne;
> +    bool ext_zknh;
> +    bool ext_zkr;
> +    bool ext_zks;
> +    bool ext_zksed;
> +    bool ext_zksh;
> +    bool ext_zkt;
> +    bool ext_ifencei;
> +    bool ext_icsr;
> +    bool ext_icbom;
> +    bool ext_icboz;
> +    bool ext_zicond;
> +    bool ext_zihintpause;
> +    bool ext_smstateen;
> +    bool ext_sstc;
> +    bool ext_svadu;
> +    bool ext_svinval;
> +    bool ext_svnapot;
> +    bool ext_svpbmt;
> +    bool ext_zdinx;
> +    bool ext_zawrs;
> +    bool ext_zfh;
> +    bool ext_zfhmin;
> +    bool ext_zfinx;
> +    bool ext_zhinx;
> +    bool ext_zhinxmin;
> +    bool ext_zve32f;
> +    bool ext_zve64f;
> +    bool ext_zve64d;
> +    bool ext_zmmul;
> +    bool ext_zvfh;
> +    bool ext_zvfhmin;
> +    bool ext_smaia;
> +    bool ext_ssaia;
> +    bool ext_sscofpmf;
> +    bool rvv_ta_all_1s;
> +    bool rvv_ma_all_1s;
> +
> +    uint32_t mvendorid;
> +    uint64_t marchid;
> +    uint64_t mimpid;
> +
> +    /* Vendor-specific custom extensions */
> +    bool ext_xtheadba;
> +    bool ext_xtheadbb;
> +    bool ext_xtheadbs;
> +    bool ext_xtheadcmo;
> +    bool ext_xtheadcondmov;
> +    bool ext_xtheadfmemidx;
> +    bool ext_xtheadfmv;
> +    bool ext_xtheadmac;
> +    bool ext_xtheadmemidx;
> +    bool ext_xtheadmempair;
> +    bool ext_xtheadsync;
> +    bool ext_XVentanaCondOps;
> +
> +    uint8_t pmu_num;
> +    char *priv_spec;
> +    char *user_spec;
> +    char *bext_spec;
> +    char *vext_spec;
> +    uint16_t vlen;
> +    uint16_t elen;
> +    uint16_t cbom_blocksize;
> +    uint16_t cboz_blocksize;
> +    bool mmu;
> +    bool pmp;
> +    bool epmp;
> +    bool debug;
> +    bool misa_w;
> +
> +    bool short_isa_string;
> +
> +#ifndef CONFIG_USER_ONLY
> +    RISCVSATPMap satp_mode;
> +#endif
> +};
> +
> +typedef struct RISCVCPUConfig RISCVCPUConfig;
> +
> +/* Helper functions to test for extensions.  */
> +
> +static inline bool always_true_p(const RISCVCPUConfig *cfg __attribute__((__unused__)))
> +{
> +    return true;
> +}
> +
> +static inline bool has_xthead_p(const RISCVCPUConfig *cfg)
> +{
> +    return cfg->ext_xtheadba || cfg->ext_xtheadbb ||
> +           cfg->ext_xtheadbs || cfg->ext_xtheadcmo ||
> +           cfg->ext_xtheadcondmov ||
> +           cfg->ext_xtheadfmemidx || cfg->ext_xtheadfmv ||
> +           cfg->ext_xtheadmac || cfg->ext_xtheadmemidx ||
> +           cfg->ext_xtheadmempair || cfg->ext_xtheadsync;
> +}
> +
> +#define MATERIALISE_EXT_PREDICATE(ext) \
> +    static inline bool has_ ## ext ## _p(const RISCVCPUConfig *cfg) \
> +    { \
> +        return cfg->ext_ ## ext ; \
> +    }
> +
> +MATERIALISE_EXT_PREDICATE(XVentanaCondOps)
> +
> +#endif /* RISCV_CPU_CONFIG_H */
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index de7e43126a..895a307bad 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -28,6 +28,7 @@
>   #include "qemu/int128.h"
>   #include "cpu_bits.h"
>   #include "qapi/qapi-types-common.h"
> +#include "cpu-config.h"
>   #include "cpu-qom.h"
>   
>   #define TCG_GUEST_DEFAULT_MO 0
> @@ -368,119 +369,6 @@ struct CPUArchState {
>       uint64_t kvm_timer_frequency;
>   };
>   
> -/*
> - * map is a 16-bit bitmap: the most significant set bit in map is the maximum
> - * satp mode that is supported. It may be chosen by the user and must respect
> - * what qemu implements (valid_1_10_32/64) and what the hw is capable of
> - * (supported bitmap below).
> - *
> - * init is a 16-bit bitmap used to make sure the user selected a correct
> - * configuration as per the specification.
> - *
> - * supported is a 16-bit bitmap used to reflect the hw capabilities.
> - */
> -typedef struct {
> -    uint16_t map, init, supported;
> -} RISCVSATPMap;
> -
> -struct RISCVCPUConfig {
> -    bool ext_zba;
> -    bool ext_zbb;
> -    bool ext_zbc;
> -    bool ext_zbkb;
> -    bool ext_zbkc;
> -    bool ext_zbkx;
> -    bool ext_zbs;
> -    bool ext_zca;
> -    bool ext_zcb;
> -    bool ext_zcd;
> -    bool ext_zce;
> -    bool ext_zcf;
> -    bool ext_zcmp;
> -    bool ext_zcmt;
> -    bool ext_zk;
> -    bool ext_zkn;
> -    bool ext_zknd;
> -    bool ext_zkne;
> -    bool ext_zknh;
> -    bool ext_zkr;
> -    bool ext_zks;
> -    bool ext_zksed;
> -    bool ext_zksh;
> -    bool ext_zkt;
> -    bool ext_ifencei;
> -    bool ext_icsr;
> -    bool ext_icbom;
> -    bool ext_icboz;
> -    bool ext_zicond;
> -    bool ext_zihintpause;
> -    bool ext_smstateen;
> -    bool ext_sstc;
> -    bool ext_svadu;
> -    bool ext_svinval;
> -    bool ext_svnapot;
> -    bool ext_svpbmt;
> -    bool ext_zdinx;
> -    bool ext_zawrs;
> -    bool ext_zfh;
> -    bool ext_zfhmin;
> -    bool ext_zfinx;
> -    bool ext_zhinx;
> -    bool ext_zhinxmin;
> -    bool ext_zve32f;
> -    bool ext_zve64f;
> -    bool ext_zve64d;
> -    bool ext_zmmul;
> -    bool ext_zvfh;
> -    bool ext_zvfhmin;
> -    bool ext_smaia;
> -    bool ext_ssaia;
> -    bool ext_sscofpmf;
> -    bool rvv_ta_all_1s;
> -    bool rvv_ma_all_1s;
> -
> -    uint32_t mvendorid;
> -    uint64_t marchid;
> -    uint64_t mimpid;
> -
> -    /* Vendor-specific custom extensions */
> -    bool ext_xtheadba;
> -    bool ext_xtheadbb;
> -    bool ext_xtheadbs;
> -    bool ext_xtheadcmo;
> -    bool ext_xtheadcondmov;
> -    bool ext_xtheadfmemidx;
> -    bool ext_xtheadfmv;
> -    bool ext_xtheadmac;
> -    bool ext_xtheadmemidx;
> -    bool ext_xtheadmempair;
> -    bool ext_xtheadsync;
> -    bool ext_XVentanaCondOps;
> -
> -    uint8_t pmu_num;
> -    char *priv_spec;
> -    char *user_spec;
> -    char *bext_spec;
> -    char *vext_spec;
> -    uint16_t vlen;
> -    uint16_t elen;
> -    uint16_t cbom_blocksize;
> -    uint16_t cboz_blocksize;
> -    bool mmu;
> -    bool pmp;
> -    bool epmp;
> -    bool debug;
> -    bool misa_w;
> -
> -    bool short_isa_string;
> -
> -#ifndef CONFIG_USER_ONLY
> -    RISCVSATPMap satp_mode;
> -#endif
> -};
> -
> -typedef struct RISCVCPUConfig RISCVCPUConfig;
> -
>   /*
>    * RISCVCPU:
>    * @env: #CPURISCVState
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index 928da0d3f0..2697cc26d0 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -119,29 +119,6 @@ static inline bool has_ext(DisasContext *ctx, uint32_t ext)
>       return ctx->misa_ext & ext;
>   }
>   
> -static bool always_true_p(DisasContext *ctx  __attribute__((__unused__)))
> -{
> -    return true;
> -}
> -
> -static bool has_xthead_p(DisasContext *ctx  __attribute__((__unused__)))
> -{
> -    return ctx->cfg_ptr->ext_xtheadba || ctx->cfg_ptr->ext_xtheadbb ||
> -           ctx->cfg_ptr->ext_xtheadbs || ctx->cfg_ptr->ext_xtheadcmo ||
> -           ctx->cfg_ptr->ext_xtheadcondmov ||
> -           ctx->cfg_ptr->ext_xtheadfmemidx || ctx->cfg_ptr->ext_xtheadfmv ||
> -           ctx->cfg_ptr->ext_xtheadmac || ctx->cfg_ptr->ext_xtheadmemidx ||
> -           ctx->cfg_ptr->ext_xtheadmempair || ctx->cfg_ptr->ext_xtheadsync;
> -}
> -
> -#define MATERIALISE_EXT_PREDICATE(ext)  \
> -    static bool has_ ## ext ## _p(DisasContext *ctx)    \
> -    { \
> -        return ctx->cfg_ptr->ext_ ## ext ; \
> -    }
> -
> -MATERIALISE_EXT_PREDICATE(XVentanaCondOps);
> -
>   #ifdef TARGET_RISCV32
>   #define get_xl(ctx)    MXL_RV32
>   #elif defined(CONFIG_USER_ONLY)
> @@ -1106,7 +1083,7 @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
>        * that are tested in-order until a decoder matches onto the opcode.
>        */
>       static const struct {
> -        bool (*guard_func)(DisasContext *);
> +        bool (*guard_func)(const RISCVCPUConfig *);
>           bool (*decode_func)(DisasContext *, uint32_t);
>       } decoders[] = {
>           { always_true_p,  decode_insn32 },
> @@ -1135,7 +1112,7 @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
>           ctx->pc_succ_insn = ctx->base.pc_next + 4;
>   
>           for (size_t i = 0; i < ARRAY_SIZE(decoders); ++i) {
> -            if (decoders[i].guard_func(ctx) &&
> +            if (decoders[i].guard_func(ctx->cfg_ptr) &&
>                   decoders[i].decode_func(ctx, opcode32)) {
>                   return;
>               }


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

* Re: [PATCH 4/9] disas/riscv: Make rv_op_illegal a shared enum value
  2023-05-30 13:18 ` [PATCH 4/9] disas/riscv: Make rv_op_illegal a shared enum value Christoph Muellner
  2023-06-12  3:24   ` Alistair Francis
@ 2023-06-12  6:48   ` LIU Zhiwei
  1 sibling, 0 replies; 30+ messages in thread
From: LIU Zhiwei @ 2023-06-12  6:48 UTC (permalink / raw)
  To: Christoph Muellner, qemu-riscv, qemu-devel, Alistair Francis,
	Bin Meng, Philipp Tomsich, Palmer Dabbelt, Richard Henderson


On 2023/5/30 21:18, Christoph Muellner wrote:
> From: Christoph Müllner <christoph.muellner@vrull.eu>
>
> The enum value 'rv_op_illegal' does not represent an
> instruction, but is a catch-all value in case we have
> no match in the decoder. Let's make the value a shared
> one, so that other compile units can reuse it.
>
> Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
> ---
>   disas/riscv.c | 2 +-
>   disas/riscv.h | 4 ++++
>   2 files changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/disas/riscv.c b/disas/riscv.c
> index a062fb48cc..4cf477bc02 100644
> --- a/disas/riscv.c
> +++ b/disas/riscv.c
> @@ -22,7 +22,7 @@
>   #include "disas/riscv.h"
>   
>   typedef enum {
> -    rv_op_illegal = 0,
> +    /* 0 is reserved for rv_op_illegal. */
>       rv_op_lui = 1,
>       rv_op_auipc = 2,
>       rv_op_jal = 3,
> diff --git a/disas/riscv.h b/disas/riscv.h
> index 0f34b71518..de2623e3cc 100644
> --- a/disas/riscv.h
> +++ b/disas/riscv.h
> @@ -189,6 +189,10 @@ typedef struct {
>       const rvc_constraint *constraints;
>   } rv_comp_data;
>   
> +enum {
> +    rv_op_illegal = 0
> +};
> +

Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>

Zhiwei

>   enum {
>       rvcd_imm_nz = 0x1
>   };


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

* Re: [PATCH 6/9] target/riscv/cpu: Share RISCVCPUConfig with disassembler
  2023-06-12  6:25   ` LIU Zhiwei
@ 2023-06-12  9:47     ` Christoph Müllner
  2023-06-12 10:01       ` LIU Zhiwei
  0 siblings, 1 reply; 30+ messages in thread
From: Christoph Müllner @ 2023-06-12  9:47 UTC (permalink / raw)
  To: LIU Zhiwei
  Cc: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
	Philipp Tomsich, Palmer Dabbelt, Richard Henderson, Zhiwei Liu,
	Weiwei Li, Daniel Henrique Barboza

On Mon, Jun 12, 2023 at 8:25 AM LIU Zhiwei <baxiantai@gmail.com> wrote:
>
>
> On 2023/5/30 21:18, Christoph Muellner wrote:
> > From: Christoph Müllner <christoph.muellner@vrull.eu>
> >
> > The disassembler needs the available extensions in order
> > to properly decode instructions in case of overlapping
> > encodings (e.g. for vendor extensions).
> >
> > Let's use the field 'disassemble_info::private_data' to store
> > our RISCVCPUConfig pointer.
> >
> > Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
> > ---
> >   target/riscv/cpu.c | 3 +++
> >   1 file changed, 3 insertions(+)
> >
> > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> > index 5b7818dbd1..6f0cd9a0bb 100644
> > --- a/target/riscv/cpu.c
> > +++ b/target/riscv/cpu.c
> > @@ -819,6 +819,9 @@ static void riscv_cpu_disas_set_info(CPUState *s, disassemble_info *info)
> >   {
> >       RISCVCPU *cpu = RISCV_CPU(s);
> >       CPURISCVState *env = &cpu->env;
> > +    RISCVCPUConfig *cfg = &cpu->cfg;
> > +
> > +    info->private_data = cfg;
>
> I don't know if this field will be overridden by the binutils. Can we
> extend the struct disassemble_info, and add some fields like supporting
> for Capstone?


Initially I wanted to add a new field, but then I noticed that the field
'disassemble_info::private_data' is used for a similar purpose by
disas/cris.c, disas/m68k.c, and dias/xtensa.c.
So I decided to not add yet another field, which only serves one architecture.

But if that's the preferred way, then I can change.

Thanks
Christoph

>
> Zhiwei
>
> >
> >       switch (env->xl) {
> >       case MXL_RV32:


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

* Re: [PATCH 6/9] target/riscv/cpu: Share RISCVCPUConfig with disassembler
  2023-06-12  9:47     ` Christoph Müllner
@ 2023-06-12 10:01       ` LIU Zhiwei
  2023-06-12 10:04         ` Christoph Müllner
  0 siblings, 1 reply; 30+ messages in thread
From: LIU Zhiwei @ 2023-06-12 10:01 UTC (permalink / raw)
  To: Christoph Müllner
  Cc: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
	Philipp Tomsich, Palmer Dabbelt, Richard Henderson, Zhiwei Liu,
	Weiwei Li, Daniel Henrique Barboza


On 2023/6/12 17:47, Christoph Müllner wrote:
> On Mon, Jun 12, 2023 at 8:25 AM LIU Zhiwei <baxiantai@gmail.com> wrote:
>>
>> On 2023/5/30 21:18, Christoph Muellner wrote:
>>> From: Christoph Müllner <christoph.muellner@vrull.eu>
>>>
>>> The disassembler needs the available extensions in order
>>> to properly decode instructions in case of overlapping
>>> encodings (e.g. for vendor extensions).
>>>
>>> Let's use the field 'disassemble_info::private_data' to store
>>> our RISCVCPUConfig pointer.
>>>
>>> Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
>>> ---
>>>    target/riscv/cpu.c | 3 +++
>>>    1 file changed, 3 insertions(+)
>>>
>>> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
>>> index 5b7818dbd1..6f0cd9a0bb 100644
>>> --- a/target/riscv/cpu.c
>>> +++ b/target/riscv/cpu.c
>>> @@ -819,6 +819,9 @@ static void riscv_cpu_disas_set_info(CPUState *s, disassemble_info *info)
>>>    {
>>>        RISCVCPU *cpu = RISCV_CPU(s);
>>>        CPURISCVState *env = &cpu->env;
>>> +    RISCVCPUConfig *cfg = &cpu->cfg;
>>> +
>>> +    info->private_data = cfg;
>> I don't know if this field will be overridden by the binutils. Can we
>> extend the struct disassemble_info, and add some fields like supporting
>> for Capstone?
>
> Initially I wanted to add a new field, but then I noticed that the field
> 'disassemble_info::private_data' is used for a similar purpose by
> disas/cris.c, disas/m68k.c, and dias/xtensa.c.
> So I decided to not add yet another field, which only serves one architecture.
I think you can CC these arch maintainers to see if it need some 
specially process before using the private_data.
>
> But if that's the preferred way, then I can change.

I prefer this way, but not insist on  if it really works using the 
private_data.

Zhiwei

>
> Thanks
> Christoph
>
>> Zhiwei
>>
>>>        switch (env->xl) {
>>>        case MXL_RV32:


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

* Re: [PATCH 6/9] target/riscv/cpu: Share RISCVCPUConfig with disassembler
  2023-06-12 10:01       ` LIU Zhiwei
@ 2023-06-12 10:04         ` Christoph Müllner
  2023-06-12 11:56           ` LIU Zhiwei
  0 siblings, 1 reply; 30+ messages in thread
From: Christoph Müllner @ 2023-06-12 10:04 UTC (permalink / raw)
  To: LIU Zhiwei
  Cc: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
	Philipp Tomsich, Palmer Dabbelt, Richard Henderson, Zhiwei Liu,
	Weiwei Li, Daniel Henrique Barboza

On Mon, Jun 12, 2023 at 12:01 PM LIU Zhiwei <baxiantai@gmail.com> wrote:
>
>
> On 2023/6/12 17:47, Christoph Müllner wrote:
> > On Mon, Jun 12, 2023 at 8:25 AM LIU Zhiwei <baxiantai@gmail.com> wrote:
> >>
> >> On 2023/5/30 21:18, Christoph Muellner wrote:
> >>> From: Christoph Müllner <christoph.muellner@vrull.eu>
> >>>
> >>> The disassembler needs the available extensions in order
> >>> to properly decode instructions in case of overlapping
> >>> encodings (e.g. for vendor extensions).
> >>>
> >>> Let's use the field 'disassemble_info::private_data' to store
> >>> our RISCVCPUConfig pointer.
> >>>
> >>> Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
> >>> ---
> >>>    target/riscv/cpu.c | 3 +++
> >>>    1 file changed, 3 insertions(+)
> >>>
> >>> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> >>> index 5b7818dbd1..6f0cd9a0bb 100644
> >>> --- a/target/riscv/cpu.c
> >>> +++ b/target/riscv/cpu.c
> >>> @@ -819,6 +819,9 @@ static void riscv_cpu_disas_set_info(CPUState *s, disassemble_info *info)
> >>>    {
> >>>        RISCVCPU *cpu = RISCV_CPU(s);
> >>>        CPURISCVState *env = &cpu->env;
> >>> +    RISCVCPUConfig *cfg = &cpu->cfg;
> >>> +
> >>> +    info->private_data = cfg;
> >> I don't know if this field will be overridden by the binutils. Can we
> >> extend the struct disassemble_info, and add some fields like supporting
> >> for Capstone?
> >
> > Initially I wanted to add a new field, but then I noticed that the field
> > 'disassemble_info::private_data' is used for a similar purpose by
> > disas/cris.c, disas/m68k.c, and dias/xtensa.c.
> > So I decided to not add yet another field, which only serves one architecture.
> I think you can CC these arch maintainers to see if it need some
> specially process before using the private_data.
> >
> > But if that's the preferred way, then I can change.
>
> I prefer this way, but not insist on  if it really works using the
> private_data.

This topic is already resolved by using the field 'info->target_info'.
So I dropped this patch anyway.

BR
Christoph

>
> Zhiwei
>
> >
> > Thanks
> > Christoph
> >
> >> Zhiwei
> >>
> >>>        switch (env->xl) {
> >>>        case MXL_RV32:


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

* Re: [PATCH 7/9] disas/riscv: Provide infrastructure for vendor extensions
  2023-06-08 13:04   ` LIU Zhiwei
@ 2023-06-12 11:11     ` Christoph Müllner
  0 siblings, 0 replies; 30+ messages in thread
From: Christoph Müllner @ 2023-06-12 11:11 UTC (permalink / raw)
  To: LIU Zhiwei
  Cc: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
	Philipp Tomsich, Palmer Dabbelt, Richard Henderson

On Thu, Jun 8, 2023 at 3:05 PM LIU Zhiwei <zhiwei_liu@linux.alibaba.com> wrote:
>
>
> On 2023/5/30 21:18, Christoph Muellner wrote:
> > From: Christoph Müllner <christoph.muellner@vrull.eu>
> >
> > A previous patch provides a pointer to the RISCVCPUConfig data.
> > Let's use this to add the necessary code for vendor extensions.
> > This patch does not change the current behaviour, but clearly
> > defines how vendor extension support can be added to the disassembler.
> >
> > Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
> > ---
> >   disas/riscv.c | 34 ++++++++++++++++++++++++++++++----
> >   1 file changed, 30 insertions(+), 4 deletions(-)
> >
> > diff --git a/disas/riscv.c b/disas/riscv.c
> > index 086edee6a2..db98e3ea6a 100644
> > --- a/disas/riscv.c
> > +++ b/disas/riscv.c
> > @@ -20,6 +20,7 @@
> >   #include "qemu/osdep.h"
> >   #include "disas/dis-asm.h"
> >   #include "disas/riscv.h"
> > +#include "target/riscv/cpu-config.h"
> >
> >   typedef enum {
> >       /* 0 is reserved for rv_op_illegal. */
> > @@ -4599,13 +4600,38 @@ static void decode_inst_decompress(rv_decode *dec, rv_isa isa)
> >   /* disassemble instruction */
> >
> >   static void
> > -disasm_inst(char *buf, size_t buflen, rv_isa isa, uint64_t pc, rv_inst inst)
> > +disasm_inst(char *buf, size_t buflen, rv_isa isa, uint64_t pc, rv_inst inst,
> > +            struct disassemble_info *info)
> >   {
> > +    RISCVCPUConfig *cfg = info->private_data;
> >       rv_decode dec = { 0 };
> >       dec.pc = pc;
> >       dec.inst = inst;
> > -    dec.opcode_data = rvi_opcode_data;
> > -    decode_inst_opcode(&dec, isa);
> > +
> > +    static const struct {
> > +        bool (*guard_func)(const RISCVCPUConfig *);
> > +        const rv_opcode_data *opcode_data;
> > +        void (*decode_func)(rv_decode *, rv_isa);
> > +    } decoders[] = {
> > +        { always_true_p, rvi_opcode_data, decode_inst_opcode },
> > +    };
> > +
> > +    for (size_t i = 0; i < ARRAY_SIZE(decoders); i++) {
> > +        bool (*guard_func)(const RISCVCPUConfig *) = decoders[i].guard_func;
> > +        const rv_opcode_data *opcode_data = decoders[i].opcode_data;
> > +        void (*decode_func)(rv_decode *, rv_isa) = decoders[i].decode_func;
> > +
> > +        if (guard_func(cfg)) {
> > +            dec.opcode_data = opcode_data;
> > +            decode_func(&dec, isa);
> > +            if (dec.op != rv_op_illegal)
> > +                break;
> > +        }
> > +    }
> > +
> > +    if (dec.op == rv_op_illegal)
> > +        dec.opcode_data = rvi_opcode_data;
>
> Always enclose the if sentence.

Done.

Thanks,
Christoph

>
> Otherwise,
>
> Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
>
> > +
> >       decode_inst_operands(&dec, isa);
> >       decode_inst_decompress(&dec, isa);
> >       decode_inst_lift_pseudo(&dec);
> > @@ -4659,7 +4685,7 @@ print_insn_riscv(bfd_vma memaddr, struct disassemble_info *info, rv_isa isa)
> >           break;
> >       }
> >
> > -    disasm_inst(buf, sizeof(buf), isa, memaddr, inst);
> > +    disasm_inst(buf, sizeof(buf), isa, memaddr, inst, info);
> >       (*info->fprintf_func)(info->stream, "%s", buf);
> >
> >       return len;


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

* Re: [PATCH 0/9] disas/riscv: Add vendor extension support
  2023-06-06 17:38 ` [PATCH 0/9] disas/riscv: Add vendor extension support Daniel Henrique Barboza
@ 2023-06-12 11:17   ` Christoph Müllner
  0 siblings, 0 replies; 30+ messages in thread
From: Christoph Müllner @ 2023-06-12 11:17 UTC (permalink / raw)
  To: Daniel Henrique Barboza
  Cc: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
	Philipp Tomsich, Palmer Dabbelt, Richard Henderson, Zhiwei Liu

On Tue, Jun 6, 2023 at 7:38 PM Daniel Henrique Barboza
<dbarboza@ventanamicro.com> wrote:
>
> Hi,
>
> Can you please rebase on top of Alistair's riscv-to-apply.next and re-send?

Done.

Thanks,
Christoph

>
> Some patches can't be applied cleanly, in particular patch 2, which conflicts
> with Weiwei's "target/riscv: Split RISCVCPUConfig declarations from cpu.h
> into cpu_cfg.h" that landed into riscv-to-apply.next a few weeks ago. In
> this particular case patch 2 of this series would need to move just the
> bits of target/ppc/translate.c to the already existing cpu_cfg.h file.
>
>
> Put me in the CC when you re-send and I'll review it asap. Thanks,
>
>
> Daniel
>
> On 5/30/23 10:18, Christoph Muellner wrote:
> > From: Christoph Müllner <christoph.muellner@vrull.eu>
> >
> > This series adds vendor extension support to the QEMU disassembler
> > for RISC-V. The following vendor extensions are covered:
> > * XThead{Ba,Bb,Bs,Cmo,CondMov,FMemIdx,Fmv,Mac,MemIdx,MemPair,Sync}
> > * XVentanaCondOps
> >
> > So far, there have been two attempts to add vendor extension support
> > to the QEMU disassembler. The first one [1] was posted in August 2022
> > by LIU Zhiwei and attempts to separate vendor extension specifics
> > from standard extension code in combination with a patch that introduced
> > support for XVentanaCondOps. The second one [2] was posted in March 2023
> > by me and added XThead* support without separating the vendor extensions
> > from the standard code.
> >
> > This patchset represents the third attempt to add vendor extension
> > support to the QEMU disassembler. It adds all features of the previous
> > attempts and integrates them into a patchset that uses the same
> > mechanism for testing the extension availability like translate.c
> > (using the booleans RISCVCPUConfig::ext_*).
> > To achieve that, a couple of patches were needed to restructure
> > the existing code.
> >
> > Note, that this patchset allows an instruction encoder function for each
> > vendor extension, but operand decoding and instruction printing remains
> > common code. This is irrelevant for XVentanaCondOps, but the patch for
> > the XThead* extensions includes changes in riscv.c and riscv.h.
> > This could be changed to force more separation with the cost of
> > duplication.
> >
> > The first patch of this series is cherry-picked from LIU Zhiwei's series.
> > It was reviewed by Alistair Francis and Richard Henderson, but never
> > made it on master. I've added "Reviewed-by" tags to the commit.
> >
> > I've added "Co-developed-by" tags to those commits that are derived
> > from the series of LIU Zhiwei.
> >
> > [1] https://lists.nongnu.org/archive/html/qemu-devel/2022-08/msg03662.html
> > [2] https://lists.nongnu.org/archive/html/qemu-devel/2023-03/msg04566.html
> >
> > Christoph Müllner (8):
> >    target/riscv: Factor out RISCVCPUConfig from cpu.h
> >    disas/riscv: Move types/constants to new header file
> >    disas/riscv: Make rv_op_illegal a shared enum value
> >    disas/riscv: Encapsulate opcode_data into decode
> >    target/riscv/cpu: Share RISCVCPUConfig with disassembler
> >    disas/riscv: Provide infrastructure for vendor extensions
> >    disas/riscv: Add support for XVentanaCondOps
> >    disas/riscv: Add support for XThead* instructions
> >
> > LIU Zhiwei (1):
> >    target/riscv: Use xl instead of mxl for disassemble
> >
> >   disas/meson.build         |   6 +-
> >   disas/riscv-xthead.c      | 707 ++++++++++++++++++++++++++++++++++++++
> >   disas/riscv-xthead.h      |  28 ++
> >   disas/riscv-xventana.c    |  41 +++
> >   disas/riscv-xventana.h    |  18 +
> >   disas/riscv.c             | 384 ++++++---------------
> >   disas/riscv.h             | 297 ++++++++++++++++
> >   target/riscv/cpu-config.h | 159 +++++++++
> >   target/riscv/cpu.c        |   6 +-
> >   target/riscv/cpu.h        | 114 +-----
> >   target/riscv/translate.c  |  27 +-
> >   11 files changed, 1374 insertions(+), 413 deletions(-)
> >   create mode 100644 disas/riscv-xthead.c
> >   create mode 100644 disas/riscv-xthead.h
> >   create mode 100644 disas/riscv-xventana.c
> >   create mode 100644 disas/riscv-xventana.h
> >   create mode 100644 disas/riscv.h
> >   create mode 100644 target/riscv/cpu-config.h
> >


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

* Re: [PATCH 6/9] target/riscv/cpu: Share RISCVCPUConfig with disassembler
  2023-06-12 10:04         ` Christoph Müllner
@ 2023-06-12 11:56           ` LIU Zhiwei
  0 siblings, 0 replies; 30+ messages in thread
From: LIU Zhiwei @ 2023-06-12 11:56 UTC (permalink / raw)
  To: Christoph Müllner
  Cc: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
	Philipp Tomsich, Palmer Dabbelt, Richard Henderson, Zhiwei Liu,
	Weiwei Li, Daniel Henrique Barboza


On 2023/6/12 18:04, Christoph Müllner wrote:
> On Mon, Jun 12, 2023 at 12:01 PM LIU Zhiwei <baxiantai@gmail.com> wrote:
>>
>> On 2023/6/12 17:47, Christoph Müllner wrote:
>>> On Mon, Jun 12, 2023 at 8:25 AM LIU Zhiwei <baxiantai@gmail.com> wrote:
>>>> On 2023/5/30 21:18, Christoph Muellner wrote:
>>>>> From: Christoph Müllner <christoph.muellner@vrull.eu>
>>>>>
>>>>> The disassembler needs the available extensions in order
>>>>> to properly decode instructions in case of overlapping
>>>>> encodings (e.g. for vendor extensions).
>>>>>
>>>>> Let's use the field 'disassemble_info::private_data' to store
>>>>> our RISCVCPUConfig pointer.
>>>>>
>>>>> Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
>>>>> ---
>>>>>     target/riscv/cpu.c | 3 +++
>>>>>     1 file changed, 3 insertions(+)
>>>>>
>>>>> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
>>>>> index 5b7818dbd1..6f0cd9a0bb 100644
>>>>> --- a/target/riscv/cpu.c
>>>>> +++ b/target/riscv/cpu.c
>>>>> @@ -819,6 +819,9 @@ static void riscv_cpu_disas_set_info(CPUState *s, disassemble_info *info)
>>>>>     {
>>>>>         RISCVCPU *cpu = RISCV_CPU(s);
>>>>>         CPURISCVState *env = &cpu->env;
>>>>> +    RISCVCPUConfig *cfg = &cpu->cfg;
>>>>> +
>>>>> +    info->private_data = cfg;
>>>> I don't know if this field will be overridden by the binutils. Can we
>>>> extend the struct disassemble_info, and add some fields like supporting
>>>> for Capstone?
>>> Initially I wanted to add a new field, but then I noticed that the field
>>> 'disassemble_info::private_data' is used for a similar purpose by
>>> disas/cris.c, disas/m68k.c, and dias/xtensa.c.
>>> So I decided to not add yet another field, which only serves one architecture.
>> I think you can CC these arch maintainers to see if it need some
>> specially process before using the private_data.
>>> But if that's the preferred way, then I can change.
>> I prefer this way, but not insist on  if it really works using the
>> private_data.
> This topic is already resolved by using the field 'info->target_info'.
> So I dropped this patch anyway.

OK. I remembered I also used this field to pass the ISA information in 
the multi-path disassemble patch set.

Zhiwei

>
> BR
> Christoph
>
>> Zhiwei
>>
>>> Thanks
>>> Christoph
>>>
>>>> Zhiwei
>>>>
>>>>>         switch (env->xl) {
>>>>>         case MXL_RV32:


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

end of thread, other threads:[~2023-06-12 11:56 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-05-30 13:18 [PATCH 0/9] disas/riscv: Add vendor extension support Christoph Muellner
2023-05-30 13:18 ` [PATCH 1/9] target/riscv: Use xl instead of mxl for disassemble Christoph Muellner
2023-05-30 13:18 ` [PATCH 2/9] target/riscv: Factor out RISCVCPUConfig from cpu.h Christoph Muellner
2023-06-12  3:21   ` Alistair Francis
2023-06-12  6:40   ` LIU Zhiwei
2023-05-30 13:18 ` [PATCH 3/9] disas/riscv: Move types/constants to new header file Christoph Muellner
2023-06-09  2:04   ` LIU Zhiwei
2023-06-12  3:22   ` Alistair Francis
2023-05-30 13:18 ` [PATCH 4/9] disas/riscv: Make rv_op_illegal a shared enum value Christoph Muellner
2023-06-12  3:24   ` Alistair Francis
2023-06-12  6:48   ` LIU Zhiwei
2023-05-30 13:18 ` [PATCH 5/9] disas/riscv: Encapsulate opcode_data into decode Christoph Muellner
2023-06-12  3:26   ` Alistair Francis
2023-05-30 13:18 ` [PATCH 6/9] target/riscv/cpu: Share RISCVCPUConfig with disassembler Christoph Muellner
2023-06-12  3:34   ` Alistair Francis
2023-06-12  6:25   ` LIU Zhiwei
2023-06-12  9:47     ` Christoph Müllner
2023-06-12 10:01       ` LIU Zhiwei
2023-06-12 10:04         ` Christoph Müllner
2023-06-12 11:56           ` LIU Zhiwei
2023-05-30 13:18 ` [PATCH 7/9] disas/riscv: Provide infrastructure for vendor extensions Christoph Muellner
2023-06-08 13:04   ` LIU Zhiwei
2023-06-12 11:11     ` Christoph Müllner
2023-06-12  3:37   ` Alistair Francis
2023-05-30 13:18 ` [PATCH 8/9] disas/riscv: Add support for XVentanaCondOps Christoph Muellner
2023-06-12  3:38   ` Alistair Francis
2023-05-30 13:18 ` [PATCH 9/9] disas/riscv: Add support for XThead* instructions Christoph Muellner
2023-06-12  3:40   ` Alistair Francis
2023-06-06 17:38 ` [PATCH 0/9] disas/riscv: Add vendor extension support Daniel Henrique Barboza
2023-06-12 11:17   ` Christoph Müllner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).