* [PATCH v2 0/8] disas/riscv: Add vendor extension support
@ 2023-06-12 11:10 Christoph Muellner
2023-06-12 11:10 ` [PATCH v2 1/8] target/riscv: Use xl instead of mxl for disassemble Christoph Muellner
` (8 more replies)
0 siblings, 9 replies; 16+ messages in thread
From: Christoph Muellner @ 2023-06-12 11:10 UTC (permalink / raw)
To: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
Philipp Tomsich, Palmer Dabbelt, Richard Henderson, Zhiwei Liu,
Daniel Henrique Barboza
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.
Changes for v2:
* Rebase on Alistair's riscv-to-apply.next branch
[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 (7):
target/riscv: Factor out extension tests to cpu_cfg.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
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 | 378 ++++++---------------
disas/riscv.h | 299 +++++++++++++++++
target/riscv/cpu.c | 3 +-
target/riscv/cpu_cfg.h | 37 ++
target/riscv/translate.c | 27 +-
10 files changed, 1246 insertions(+), 298 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
--
2.40.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v2 1/8] target/riscv: Use xl instead of mxl for disassemble
2023-06-12 11:10 [PATCH v2 0/8] disas/riscv: Add vendor extension support Christoph Muellner
@ 2023-06-12 11:10 ` Christoph Muellner
2023-06-12 11:10 ` [PATCH v2 2/8] target/riscv: Factor out extension tests to cpu_cfg.h Christoph Muellner
` (7 subsequent siblings)
8 siblings, 0 replies; 16+ messages in thread
From: Christoph Muellner @ 2023-06-12 11:10 UTC (permalink / raw)
To: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
Philipp Tomsich, Palmer Dabbelt, Richard Henderson, Zhiwei Liu,
Daniel Henrique Barboza
Cc: Christoph Müllner, Weiwei Li
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 881bddf393..63faf16499 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -858,9 +858,10 @@ 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;
info->target_info = &cpu->cfg;
- 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] 16+ messages in thread
* [PATCH v2 2/8] target/riscv: Factor out extension tests to cpu_cfg.h
2023-06-12 11:10 [PATCH v2 0/8] disas/riscv: Add vendor extension support Christoph Muellner
2023-06-12 11:10 ` [PATCH v2 1/8] target/riscv: Use xl instead of mxl for disassemble Christoph Muellner
@ 2023-06-12 11:10 ` Christoph Muellner
2023-06-12 11:58 ` LIU Zhiwei
` (2 more replies)
2023-06-12 11:10 ` [PATCH v2 3/8] disas/riscv: Move types/constants to new header file Christoph Muellner
` (6 subsequent siblings)
8 siblings, 3 replies; 16+ messages in thread
From: Christoph Muellner @ 2023-06-12 11:10 UTC (permalink / raw)
To: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
Philipp Tomsich, Palmer Dabbelt, Richard Henderson, Zhiwei Liu,
Daniel Henrique Barboza
Cc: Christoph Müllner, Weiwei Li
From: Christoph Müllner <christoph.muellner@vrull.eu>
This patch moves the extension test functions that are used
to gate vendor extension decoders, into cpu_cfg.h.
This allows to reuse them in the disassembler.
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*' to keep
the code in cpu_cfg.h self-contained.
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
---
target/riscv/cpu_cfg.h | 26 ++++++++++++++++++++++++++
target/riscv/translate.c | 27 ++-------------------------
2 files changed, 28 insertions(+), 25 deletions(-)
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
index c4a627d335..0b4fe4b540 100644
--- a/target/riscv/cpu_cfg.h
+++ b/target/riscv/cpu_cfg.h
@@ -133,4 +133,30 @@ struct RISCVCPUConfig {
};
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
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 859d5b2dcf..275b922811 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)
@@ -1132,7 +1109,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 },
@@ -1161,7 +1138,7 @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
ctx->opcode = opcode32;
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] 16+ messages in thread
* [PATCH v2 3/8] disas/riscv: Move types/constants to new header file
2023-06-12 11:10 [PATCH v2 0/8] disas/riscv: Add vendor extension support Christoph Muellner
2023-06-12 11:10 ` [PATCH v2 1/8] target/riscv: Use xl instead of mxl for disassemble Christoph Muellner
2023-06-12 11:10 ` [PATCH v2 2/8] target/riscv: Factor out extension tests to cpu_cfg.h Christoph Muellner
@ 2023-06-12 11:10 ` Christoph Muellner
2023-06-12 11:10 ` [PATCH v2 4/8] disas/riscv: Make rv_op_illegal a shared enum value Christoph Muellner
` (5 subsequent siblings)
8 siblings, 0 replies; 16+ messages in thread
From: Christoph Muellner @ 2023-06-12 11:10 UTC (permalink / raw)
To: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
Philipp Tomsich, Palmer Dabbelt, Richard Henderson, Zhiwei Liu,
Daniel Henrique Barboza
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.
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
---
disas/riscv.c | 270 +----------------------------------------------
disas/riscv.h | 282 ++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 283 insertions(+), 269 deletions(-)
create mode 100644 disas/riscv.h
diff --git a/disas/riscv.c b/disas/riscv.c
index 5005364aba..4a55348267 100644
--- a/disas/riscv.c
+++ b/disas/riscv.c
@@ -20,157 +20,7 @@
#include "qemu/osdep.h"
#include "disas/dis-asm.h"
#include "target/riscv/cpu_cfg.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,51 +816,6 @@ typedef enum {
rv_op_czero_nez = 790,
} rv_op;
-/* structures */
-
-typedef struct {
- RISCVCPUConfig *cfg;
- 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] = {
@@ -1034,79 +839,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..9288255915
--- /dev/null
+++ b/disas/riscv.h
@@ -0,0 +1,282 @@
+/*
+ * 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"
+#include "target/riscv/cpu_cfg.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 {
+ RISCVCPUConfig *cfg;
+ 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] 16+ messages in thread
* [PATCH v2 4/8] disas/riscv: Make rv_op_illegal a shared enum value
2023-06-12 11:10 [PATCH v2 0/8] disas/riscv: Add vendor extension support Christoph Muellner
` (2 preceding siblings ...)
2023-06-12 11:10 ` [PATCH v2 3/8] disas/riscv: Move types/constants to new header file Christoph Muellner
@ 2023-06-12 11:10 ` Christoph Muellner
2023-06-12 11:10 ` [PATCH v2 5/8] disas/riscv: Encapsulate opcode_data into decode Christoph Muellner
` (4 subsequent siblings)
8 siblings, 0 replies; 16+ messages in thread
From: Christoph Muellner @ 2023-06-12 11:10 UTC (permalink / raw)
To: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
Philipp Tomsich, Palmer Dabbelt, Richard Henderson, Zhiwei Liu,
Daniel Henrique Barboza
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.
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
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 4a55348267..b6ced2a26a 100644
--- a/disas/riscv.c
+++ b/disas/riscv.c
@@ -23,7 +23,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 9288255915..debbe69239 100644
--- a/disas/riscv.h
+++ b/disas/riscv.h
@@ -191,6 +191,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] 16+ messages in thread
* [PATCH v2 5/8] disas/riscv: Encapsulate opcode_data into decode
2023-06-12 11:10 [PATCH v2 0/8] disas/riscv: Add vendor extension support Christoph Muellner
` (3 preceding siblings ...)
2023-06-12 11:10 ` [PATCH v2 4/8] disas/riscv: Make rv_op_illegal a shared enum value Christoph Muellner
@ 2023-06-12 11:10 ` Christoph Muellner
2023-06-12 11:10 ` [PATCH v2 6/8] disas/riscv: Provide infrastructure for vendor extensions Christoph Muellner
` (3 subsequent siblings)
8 siblings, 0 replies; 16+ messages in thread
From: Christoph Muellner @ 2023-06-12 11:10 UTC (permalink / raw)
To: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
Philipp Tomsich, Palmer Dabbelt, Richard Henderson, Zhiwei Liu,
Daniel Henrique Barboza
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>
Reviewed-by: Alistair Francis <alistair.francis@wdc.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 b6ced2a26a..b6789ab92a 100644
--- a/disas/riscv.c
+++ b/disas/riscv.c
@@ -1068,7 +1068,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 },
@@ -3889,6 +3889,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) {
@@ -4371,6 +4372,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;
@@ -4612,6 +4614,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;
@@ -4630,6 +4633,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)
@@ -4644,6 +4648,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)
@@ -4658,6 +4663,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)
@@ -4694,6 +4700,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;
dec.cfg = cfg;
decode_inst_opcode(&dec, isa);
decode_inst_operands(&dec, isa);
diff --git a/disas/riscv.h b/disas/riscv.h
index debbe69239..460196510c 100644
--- a/disas/riscv.h
+++ b/disas/riscv.h
@@ -163,10 +163,27 @@ 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 {
RISCVCPUConfig *cfg;
uint64_t pc;
uint64_t inst;
+ const rv_opcode_data *opcode_data;
int32_t imm;
uint16_t op;
uint8_t codec;
@@ -186,11 +203,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
};
@@ -199,17 +211,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] 16+ messages in thread
* [PATCH v2 6/8] disas/riscv: Provide infrastructure for vendor extensions
2023-06-12 11:10 [PATCH v2 0/8] disas/riscv: Add vendor extension support Christoph Muellner
` (4 preceding siblings ...)
2023-06-12 11:10 ` [PATCH v2 5/8] disas/riscv: Encapsulate opcode_data into decode Christoph Muellner
@ 2023-06-12 11:10 ` Christoph Muellner
2023-06-12 11:10 ` [PATCH v2 7/8] disas/riscv: Add support for XVentanaCondOps Christoph Muellner
` (2 subsequent siblings)
8 siblings, 0 replies; 16+ messages in thread
From: Christoph Muellner @ 2023-06-12 11:10 UTC (permalink / raw)
To: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
Philipp Tomsich, Palmer Dabbelt, Richard Henderson, Zhiwei Liu,
Daniel Henrique Barboza
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.
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
---
disas/riscv.c | 28 ++++++++++++++++++++++++++--
1 file changed, 26 insertions(+), 2 deletions(-)
diff --git a/disas/riscv.c b/disas/riscv.c
index b6789ab92a..dc3bfb0123 100644
--- a/disas/riscv.c
+++ b/disas/riscv.c
@@ -4700,9 +4700,33 @@ 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;
dec.cfg = cfg;
- 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);
--
2.40.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v2 7/8] disas/riscv: Add support for XVentanaCondOps
2023-06-12 11:10 [PATCH v2 0/8] disas/riscv: Add vendor extension support Christoph Muellner
` (5 preceding siblings ...)
2023-06-12 11:10 ` [PATCH v2 6/8] disas/riscv: Provide infrastructure for vendor extensions Christoph Muellner
@ 2023-06-12 11:10 ` Christoph Muellner
2023-06-14 9:00 ` Daniel Henrique Barboza
2023-06-12 11:10 ` [PATCH v2 8/8] disas/riscv: Add support for XThead* instructions Christoph Muellner
2023-06-22 1:03 ` [PATCH v2 0/8] disas/riscv: Add vendor extension support Alistair Francis
8 siblings, 1 reply; 16+ messages in thread
From: Christoph Muellner @ 2023-06-12 11:10 UTC (permalink / raw)
To: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
Philipp Tomsich, Palmer Dabbelt, Richard Henderson, Zhiwei Liu,
Daniel Henrique Barboza
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>
Acked-by: Alistair Francis <alistair.francis@wdc.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 dc3bfb0123..c7bfd4ed32 100644
--- a/disas/riscv.c
+++ b/disas/riscv.c
@@ -22,6 +22,9 @@
#include "target/riscv/cpu_cfg.h"
#include "disas/riscv.h"
+/* Vendor extensions */
+#include "disas/riscv-xventana.h"
+
typedef enum {
/* 0 is reserved for rv_op_illegal. */
rv_op_lui = 1,
@@ -4708,6 +4711,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] 16+ messages in thread
* [PATCH v2 8/8] disas/riscv: Add support for XThead* instructions
2023-06-12 11:10 [PATCH v2 0/8] disas/riscv: Add vendor extension support Christoph Muellner
` (6 preceding siblings ...)
2023-06-12 11:10 ` [PATCH v2 7/8] disas/riscv: Add support for XVentanaCondOps Christoph Muellner
@ 2023-06-12 11:10 ` Christoph Muellner
2023-06-15 6:53 ` Weiwei Li
2023-06-22 1:03 ` [PATCH v2 0/8] disas/riscv: Add vendor extension support Alistair Francis
8 siblings, 1 reply; 16+ messages in thread
From: Christoph Muellner @ 2023-06-12 11:10 UTC (permalink / raw)
To: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
Philipp Tomsich, Palmer Dabbelt, Richard Henderson, Zhiwei Liu,
Daniel Henrique Barboza
Cc: Christoph Müllner, Alistair Francis, Weiwei Li
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>
Acked-by: Alistair Francis <alistair.francis@wdc.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_cfg.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 c7bfd4ed32..94e568a7e9 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 "target/riscv/cpu_cfg.h"
#include "disas/riscv.h"
/* Vendor extensions */
+#include "disas/riscv-xthead.h"
#include "disas/riscv-xventana.h"
typedef enum {
@@ -3869,6 +3871,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;
@@ -4233,6 +4255,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;
};
}
@@ -4446,6 +4500,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);
@@ -4711,6 +4769,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 460196510c..052a0c4281 100644
--- a/disas/riscv.h
+++ b/disas/riscv.h
@@ -159,6 +159,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 */
@@ -185,6 +191,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;
@@ -283,5 +290,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_cfg.h b/target/riscv/cpu_cfg.h
index 0b4fe4b540..6b7e736bc2 100644
--- a/target/riscv/cpu_cfg.h
+++ b/target/riscv/cpu_cfg.h
@@ -157,6 +157,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
--
2.40.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH v2 2/8] target/riscv: Factor out extension tests to cpu_cfg.h
2023-06-12 11:10 ` [PATCH v2 2/8] target/riscv: Factor out extension tests to cpu_cfg.h Christoph Muellner
@ 2023-06-12 11:58 ` LIU Zhiwei
2023-06-14 8:58 ` Daniel Henrique Barboza
2023-06-15 6:35 ` Weiwei Li
2 siblings, 0 replies; 16+ messages in thread
From: LIU Zhiwei @ 2023-06-12 11:58 UTC (permalink / raw)
To: Christoph Muellner, qemu-riscv, qemu-devel, Alistair Francis,
Bin Meng, Philipp Tomsich, Palmer Dabbelt, Richard Henderson,
Zhiwei Liu, Daniel Henrique Barboza
Cc: Weiwei Li
On 2023/6/12 19:10, Christoph Muellner wrote:
> From: Christoph Müllner <christoph.muellner@vrull.eu>
>
> This patch moves the extension test functions that are used
> to gate vendor extension decoders, into cpu_cfg.h.
> This allows to reuse them in the disassembler.
>
> 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*' to keep
> the code in cpu_cfg.h self-contained.
>
> Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
Zhiwei
> ---
> target/riscv/cpu_cfg.h | 26 ++++++++++++++++++++++++++
> target/riscv/translate.c | 27 ++-------------------------
> 2 files changed, 28 insertions(+), 25 deletions(-)
>
> diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
> index c4a627d335..0b4fe4b540 100644
> --- a/target/riscv/cpu_cfg.h
> +++ b/target/riscv/cpu_cfg.h
> @@ -133,4 +133,30 @@ struct RISCVCPUConfig {
> };
>
> 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
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index 859d5b2dcf..275b922811 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)
> @@ -1132,7 +1109,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 },
> @@ -1161,7 +1138,7 @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
> ctx->opcode = opcode32;
>
> 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] 16+ messages in thread
* Re: [PATCH v2 2/8] target/riscv: Factor out extension tests to cpu_cfg.h
2023-06-12 11:10 ` [PATCH v2 2/8] target/riscv: Factor out extension tests to cpu_cfg.h Christoph Muellner
2023-06-12 11:58 ` LIU Zhiwei
@ 2023-06-14 8:58 ` Daniel Henrique Barboza
2023-06-15 6:35 ` Weiwei Li
2 siblings, 0 replies; 16+ messages in thread
From: Daniel Henrique Barboza @ 2023-06-14 8:58 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
On 6/12/23 08:10, Christoph Muellner wrote:
> From: Christoph Müllner <christoph.muellner@vrull.eu>
>
> This patch moves the extension test functions that are used
> to gate vendor extension decoders, into cpu_cfg.h.
> This allows to reuse them in the disassembler.
>
> 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*' to keep
> the code in cpu_cfg.h self-contained.
>
> Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
> ---
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> target/riscv/cpu_cfg.h | 26 ++++++++++++++++++++++++++
> target/riscv/translate.c | 27 ++-------------------------
> 2 files changed, 28 insertions(+), 25 deletions(-)
>
> diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
> index c4a627d335..0b4fe4b540 100644
> --- a/target/riscv/cpu_cfg.h
> +++ b/target/riscv/cpu_cfg.h
> @@ -133,4 +133,30 @@ struct RISCVCPUConfig {
> };
>
> 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
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index 859d5b2dcf..275b922811 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)
> @@ -1132,7 +1109,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 },
> @@ -1161,7 +1138,7 @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
> ctx->opcode = opcode32;
>
> 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] 16+ messages in thread
* Re: [PATCH v2 7/8] disas/riscv: Add support for XVentanaCondOps
2023-06-12 11:10 ` [PATCH v2 7/8] disas/riscv: Add support for XVentanaCondOps Christoph Muellner
@ 2023-06-14 9:00 ` Daniel Henrique Barboza
0 siblings, 0 replies; 16+ messages in thread
From: Daniel Henrique Barboza @ 2023-06-14 9:00 UTC (permalink / raw)
To: Christoph Muellner, qemu-riscv, qemu-devel, Alistair Francis,
Bin Meng, Philipp Tomsich, Palmer Dabbelt, Richard Henderson,
Zhiwei Liu
On 6/12/23 08:10, Christoph Muellner 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>
> Acked-by: Alistair Francis <alistair.francis@wdc.com>
> Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
> ---
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> 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 dc3bfb0123..c7bfd4ed32 100644
> --- a/disas/riscv.c
> +++ b/disas/riscv.c
> @@ -22,6 +22,9 @@
> #include "target/riscv/cpu_cfg.h"
> #include "disas/riscv.h"
>
> +/* Vendor extensions */
> +#include "disas/riscv-xventana.h"
> +
> typedef enum {
> /* 0 is reserved for rv_op_illegal. */
> rv_op_lui = 1,
> @@ -4708,6 +4711,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++) {
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 2/8] target/riscv: Factor out extension tests to cpu_cfg.h
2023-06-12 11:10 ` [PATCH v2 2/8] target/riscv: Factor out extension tests to cpu_cfg.h Christoph Muellner
2023-06-12 11:58 ` LIU Zhiwei
2023-06-14 8:58 ` Daniel Henrique Barboza
@ 2023-06-15 6:35 ` Weiwei Li
2 siblings, 0 replies; 16+ messages in thread
From: Weiwei Li @ 2023-06-15 6:35 UTC (permalink / raw)
To: Christoph Muellner, qemu-riscv, qemu-devel, Alistair Francis,
Bin Meng, Philipp Tomsich, Palmer Dabbelt, Richard Henderson,
Zhiwei Liu, Daniel Henrique Barboza
Cc: Weiwei Li
On 2023/6/12 19:10, Christoph Muellner wrote:
> From: Christoph Müllner <christoph.muellner@vrull.eu>
>
> This patch moves the extension test functions that are used
> to gate vendor extension decoders, into cpu_cfg.h.
> This allows to reuse them in the disassembler.
>
> 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*' to keep
> the code in cpu_cfg.h self-contained.
>
> Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
> ---
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
Weiwei Li
> target/riscv/cpu_cfg.h | 26 ++++++++++++++++++++++++++
> target/riscv/translate.c | 27 ++-------------------------
> 2 files changed, 28 insertions(+), 25 deletions(-)
>
> diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
> index c4a627d335..0b4fe4b540 100644
> --- a/target/riscv/cpu_cfg.h
> +++ b/target/riscv/cpu_cfg.h
> @@ -133,4 +133,30 @@ struct RISCVCPUConfig {
> };
>
> 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
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index 859d5b2dcf..275b922811 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)
> @@ -1132,7 +1109,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 },
> @@ -1161,7 +1138,7 @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
> ctx->opcode = opcode32;
>
> 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] 16+ messages in thread
* Re: [PATCH v2 8/8] disas/riscv: Add support for XThead* instructions
2023-06-12 11:10 ` [PATCH v2 8/8] disas/riscv: Add support for XThead* instructions Christoph Muellner
@ 2023-06-15 6:53 ` Weiwei Li
2023-06-26 8:02 ` Christoph Müllner
0 siblings, 1 reply; 16+ messages in thread
From: Weiwei Li @ 2023-06-15 6:53 UTC (permalink / raw)
To: Christoph Muellner, qemu-riscv, qemu-devel, Alistair Francis,
Bin Meng, Philipp Tomsich, Palmer Dabbelt, Richard Henderson,
Zhiwei Liu, Daniel Henrique Barboza
Cc: Weiwei Li
On 2023/6/12 19:10, Christoph Muellner 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>
> Acked-by: Alistair Francis <alistair.francis@wdc.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_cfg.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 c7bfd4ed32..94e568a7e9 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 "target/riscv/cpu_cfg.h"
> #include "disas/riscv.h"
>
> /* Vendor extensions */
> +#include "disas/riscv-xthead.h"
> #include "disas/riscv-xventana.h"
>
> typedef enum {
> @@ -3869,6 +3871,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;
> @@ -4233,6 +4255,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;
> };
> }
>
> @@ -4446,6 +4500,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);
> @@ -4711,6 +4769,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 },
Why not merge all thead specific extensions into a big decode_xthead
as the translation progress?
Regards,
Weiwei Li
> { has_XVentanaCondOps_p, ventana_opcode_data, decode_xventanacondops },
> };
>
> diff --git a/disas/riscv.h b/disas/riscv.h
> index 460196510c..052a0c4281 100644
> --- a/disas/riscv.h
> +++ b/disas/riscv.h
> @@ -159,6 +159,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 */
> @@ -185,6 +191,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;
> @@ -283,5 +290,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_cfg.h b/target/riscv/cpu_cfg.h
> index 0b4fe4b540..6b7e736bc2 100644
> --- a/target/riscv/cpu_cfg.h
> +++ b/target/riscv/cpu_cfg.h
> @@ -157,6 +157,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
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 0/8] disas/riscv: Add vendor extension support
2023-06-12 11:10 [PATCH v2 0/8] disas/riscv: Add vendor extension support Christoph Muellner
` (7 preceding siblings ...)
2023-06-12 11:10 ` [PATCH v2 8/8] disas/riscv: Add support for XThead* instructions Christoph Muellner
@ 2023-06-22 1:03 ` Alistair Francis
8 siblings, 0 replies; 16+ messages in thread
From: Alistair Francis @ 2023-06-22 1:03 UTC (permalink / raw)
To: Christoph Muellner
Cc: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
Philipp Tomsich, Palmer Dabbelt, Richard Henderson, Zhiwei Liu,
Daniel Henrique Barboza
On Mon, Jun 12, 2023 at 9:11 PM Christoph Muellner
<christoph.muellner@vrull.eu> 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.
>
> Changes for v2:
> * Rebase on Alistair's riscv-to-apply.next branch
>
> [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 (7):
> target/riscv: Factor out extension tests to cpu_cfg.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
> 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
Thanks!
Applied to riscv-to-apply.next
Alistair
>
> 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 | 378 ++++++---------------
> disas/riscv.h | 299 +++++++++++++++++
> target/riscv/cpu.c | 3 +-
> target/riscv/cpu_cfg.h | 37 ++
> target/riscv/translate.c | 27 +-
> 10 files changed, 1246 insertions(+), 298 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
>
> --
> 2.40.1
>
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 8/8] disas/riscv: Add support for XThead* instructions
2023-06-15 6:53 ` Weiwei Li
@ 2023-06-26 8:02 ` Christoph Müllner
0 siblings, 0 replies; 16+ messages in thread
From: Christoph Müllner @ 2023-06-26 8:02 UTC (permalink / raw)
To: Weiwei Li
Cc: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
Philipp Tomsich, Palmer Dabbelt, Richard Henderson, Zhiwei Liu,
Daniel Henrique Barboza
On Thu, Jun 15, 2023 at 8:53 AM Weiwei Li <liweiwei@iscas.ac.cn> wrote:
>
>
> On 2023/6/12 19:10, Christoph Muellner 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>
> > Acked-by: Alistair Francis <alistair.francis@wdc.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_cfg.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 c7bfd4ed32..94e568a7e9 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 "target/riscv/cpu_cfg.h"
> > #include "disas/riscv.h"
> >
> > /* Vendor extensions */
> > +#include "disas/riscv-xthead.h"
> > #include "disas/riscv-xventana.h"
> >
> > typedef enum {
> > @@ -3869,6 +3871,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;
> > @@ -4233,6 +4255,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;
> > };
> > }
> >
> > @@ -4446,6 +4500,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);
> > @@ -4711,6 +4769,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 },
>
> Why not merge all thead specific extensions into a big decode_xthead
> as the translation progress?
Having one decoder per extension allows to gate them on a
per-extension granularity.
Other disassemblers (e.g. GNU Assembler) behave the same.
BR
Christoph
>
> Regards,
>
> Weiwei Li
>
> > { has_XVentanaCondOps_p, ventana_opcode_data, decode_xventanacondops },
> > };
> >
> > diff --git a/disas/riscv.h b/disas/riscv.h
> > index 460196510c..052a0c4281 100644
> > --- a/disas/riscv.h
> > +++ b/disas/riscv.h
> > @@ -159,6 +159,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 */
> > @@ -185,6 +191,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;
> > @@ -283,5 +290,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_cfg.h b/target/riscv/cpu_cfg.h
> > index 0b4fe4b540..6b7e736bc2 100644
> > --- a/target/riscv/cpu_cfg.h
> > +++ b/target/riscv/cpu_cfg.h
> > @@ -157,6 +157,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
>
>
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2023-06-26 8:03 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-06-12 11:10 [PATCH v2 0/8] disas/riscv: Add vendor extension support Christoph Muellner
2023-06-12 11:10 ` [PATCH v2 1/8] target/riscv: Use xl instead of mxl for disassemble Christoph Muellner
2023-06-12 11:10 ` [PATCH v2 2/8] target/riscv: Factor out extension tests to cpu_cfg.h Christoph Muellner
2023-06-12 11:58 ` LIU Zhiwei
2023-06-14 8:58 ` Daniel Henrique Barboza
2023-06-15 6:35 ` Weiwei Li
2023-06-12 11:10 ` [PATCH v2 3/8] disas/riscv: Move types/constants to new header file Christoph Muellner
2023-06-12 11:10 ` [PATCH v2 4/8] disas/riscv: Make rv_op_illegal a shared enum value Christoph Muellner
2023-06-12 11:10 ` [PATCH v2 5/8] disas/riscv: Encapsulate opcode_data into decode Christoph Muellner
2023-06-12 11:10 ` [PATCH v2 6/8] disas/riscv: Provide infrastructure for vendor extensions Christoph Muellner
2023-06-12 11:10 ` [PATCH v2 7/8] disas/riscv: Add support for XVentanaCondOps Christoph Muellner
2023-06-14 9:00 ` Daniel Henrique Barboza
2023-06-12 11:10 ` [PATCH v2 8/8] disas/riscv: Add support for XThead* instructions Christoph Muellner
2023-06-15 6:53 ` Weiwei Li
2023-06-26 8:02 ` Christoph Müllner
2023-06-22 1:03 ` [PATCH v2 0/8] disas/riscv: Add vendor extension support Alistair Francis
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).