[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[RFC PATCH 4/4] target/riscv: Support Ventana disassemble
From: |
LIU Zhiwei |
Subject: |
[RFC PATCH 4/4] target/riscv: Support Ventana disassemble |
Date: |
Wed, 24 Aug 2022 21:03:31 +0800 |
Pass through the custom information to disassemble by the target_info
field. In disassemble, select the decode path according to the custom
extension.
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
---
disas/riscv.c | 56 +++++++++++++++++++++++++++++++++++++++++--
target/riscv/cpu.c | 19 +++++++++++++++
target/riscv/custom.h | 25 +++++++++++++++++++
3 files changed, 98 insertions(+), 2 deletions(-)
create mode 100644 target/riscv/custom.h
diff --git a/disas/riscv.c b/disas/riscv.c
index aaf85b2aba..590cdba0f6 100644
--- a/disas/riscv.c
+++ b/disas/riscv.c
@@ -19,6 +19,7 @@
#include "qemu/osdep.h"
#include "disas/dis-asm.h"
+#include "target/riscv/custom.h"
/* types */
@@ -562,6 +563,11 @@ typedef enum {
rv_op_xperm8 = 398,
} rv_op;
+typedef enum {
+ Ventana_op_vt_maskc = 0,
+ Ventana_op_vt_maskcn = 1,
+} rv_Ventana_op;
+
/* structures */
typedef struct {
@@ -602,6 +608,7 @@ typedef struct {
uint8_t bs;
uint8_t rnum;
const rv_opcode_data *used_opcode_data;
+ const rv_opcode_data *custom_opcode_data;
} rv_decode;
/* register names */
@@ -1287,6 +1294,11 @@ const rv_opcode_data opcode_data[] = {
{ "xperm8", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }
};
+const rv_opcode_data Ventana_opcode_data[] = {
+ { "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 },
+};
+
/* CSR names */
static const char *csr_name(int csrno)
@@ -2244,6 +2256,18 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa
isa)
case 0: op = rv_op_addd; break;
case 1: op = rv_op_slld; break;
case 5: op = rv_op_srld; break;
+ case 6: /* Todo: Move custom decode to sperate decode function */
+ if (dec->custom_opcode_data == Ventana_opcode_data) {
+ op = Ventana_op_vt_maskc;
+ dec->used_opcode_data = dec->custom_opcode_data;
+ }
+ break;
+ case 7:
+ if (dec->custom_opcode_data == Ventana_opcode_data) {
+ op = Ventana_op_vt_maskcn;
+ dec->used_opcode_data = dec->custom_opcode_data;
+ }
+ break;
case 8: op = rv_op_muld; break;
case 12: op = rv_op_divd; break;
case 13: op = rv_op_divud; break;
@@ -3190,15 +3214,43 @@ static void decode_inst_decompress(rv_decode *dec,
rv_isa isa)
}
}
+static const struct {
+ enum RISCVCustom ext;
+ const rv_opcode_data *opcode_data;
+} custom_opcode_table[] = {
+ { VENTANA_CUSTOM, Ventana_opcode_data },
+};
+
+static const rv_opcode_data *
+get_custom_opcode_data(struct disassemble_info *info)
+{
+ for (size_t i = 0; i < ARRAY_SIZE(custom_opcode_table); ++i) {
+ if (info->target_info & (1ULL << custom_opcode_table[i].ext)) {
+ return custom_opcode_table[i].opcode_data;
+ }
+ }
+ return NULL;
+}
+
/* disassemble instruction */
static void
-disasm_inst(char *buf, size_t buflen, rv_isa isa, uint64_t pc, rv_inst inst)
+disasm_inst(char *buf, size_t buflen, rv_isa isa, uint64_t pc, rv_inst inst,
+ struct disassemble_info *info)
{
rv_decode dec = { 0 };
dec.pc = pc;
dec.inst = inst;
+
+ /*
+ * Set default opcode_data.
+ * Only overide the default opcode_data only when
+ * 1. There is a custom opcode data.
+ * 2. The instruction belongs to the custom extension.
+ */
dec.used_opcode_data = opcode_data;
+ dec.custom_opcode_data = get_custom_opcode_data(info);
+
decode_inst_opcode(&dec, isa);
decode_inst_operands(&dec);
decode_inst_decompress(&dec, isa);
@@ -3253,7 +3305,7 @@ print_insn_riscv(bfd_vma memaddr, struct disassemble_info
*info, rv_isa isa)
break;
}
- disasm_inst(buf, sizeof(buf), isa, memaddr, inst);
+ disasm_inst(buf, sizeof(buf), isa, memaddr, inst, info);
(*info->fprintf_func)(info->stream, "%s", buf);
return len;
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index a5f84f211d..cc6ef9303f 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -31,6 +31,7 @@
#include "fpu/softfloat-helpers.h"
#include "sysemu/kvm.h"
#include "kvm_riscv.h"
+#include "custom.h"
/* RISC-V CPU definitions */
@@ -504,11 +505,29 @@ static void riscv_cpu_reset(DeviceState *dev)
#endif
}
+static bool has_Ventana_ext(const RISCVCPUConfig *cfg_ptr)
+{
+ return cfg_ptr->ext_XVentanaCondOps;
+}
+
static void riscv_cpu_disas_set_info(CPUState *s, disassemble_info *info)
{
RISCVCPU *cpu = RISCV_CPU(s);
CPURISCVState *env = &cpu->env;
+ static const struct {
+ bool (*guard_func)(const RISCVCPUConfig *);
+ enum RISCVCustom ext;
+ } customs[] = {
+ { has_Ventana_ext, VENTANA_CUSTOM },
+ };
+
+ for (size_t i = 0; i < ARRAY_SIZE(customs); ++i) {
+ if (customs[i].guard_func(&(cpu->cfg))) {
+ info->target_info |= 1ULL << customs[i].ext;
+ }
+ }
+
switch (env->xl) {
case MXL_RV32:
info->print_insn = print_insn_riscv32;
diff --git a/target/riscv/custom.h b/target/riscv/custom.h
new file mode 100644
index 0000000000..1a161984c0
--- /dev/null
+++ b/target/riscv/custom.h
@@ -0,0 +1,25 @@
+/*
+ * QEMU RISC-V CPU -- custom extensions
+ *
+ * Copyright (c) 2022 T-Head Semiconductor Co., Ltd. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef RISCV_CPU_CUSTOM_H
+#define RISCV_CPU_CUSTOM_H
+
+enum RISCVCustom {
+ VENTANA_CUSTOM = 0,
+};
+
+#endif
--
2.25.1