aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--accel/tcg/cpu-exec.c3
-rw-r--r--disas/riscv.c1194
-rw-r--r--docs/system/riscv/virt.rst31
-rw-r--r--hw/intc/riscv_aplic.c4
-rw-r--r--hw/riscv/numa.c6
-rw-r--r--hw/riscv/opentitan.c38
-rw-r--r--hw/riscv/virt.c59
-rw-r--r--include/disas/dis-asm.h2
-rw-r--r--include/hw/core/cpu.h2
-rw-r--r--include/hw/riscv/opentitan.h6
-rw-r--r--include/qemu/log.h1
-rw-r--r--target/riscv/cpu.c384
-rw-r--r--target/riscv/cpu.h117
-rw-r--r--target/riscv/cpu_cfg.h136
-rw-r--r--target/riscv/cpu_helper.c37
-rw-r--r--target/riscv/csr.c75
-rw-r--r--target/riscv/insn_trans/trans_privileged.c.inc2
-rw-r--r--target/riscv/insn_trans/trans_rvd.c.inc12
-rw-r--r--target/riscv/insn_trans/trans_rvf.c.inc21
-rw-r--r--target/riscv/insn_trans/trans_rvi.c.inc46
-rw-r--r--target/riscv/insn_trans/trans_rvv.c.inc4
-rw-r--r--target/riscv/insn_trans/trans_rvzawrs.c.inc2
-rw-r--r--target/riscv/insn_trans/trans_rvzce.c.inc10
-rw-r--r--target/riscv/insn_trans/trans_xthead.c.inc2
-rw-r--r--target/riscv/pmp.c205
-rw-r--r--target/riscv/pmp.h11
-rw-r--r--target/riscv/translate.c99
-rw-r--r--target/riscv/vector_helper.c33
-rw-r--r--util/log.c2
29 files changed, 1442 insertions, 1102 deletions
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
index 42086525d7..ebc1db03d7 100644
--- a/accel/tcg/cpu-exec.c
+++ b/accel/tcg/cpu-exec.c
@@ -313,6 +313,9 @@ static void log_cpu_exec(target_ulong pc, CPUState *cpu,
#if defined(TARGET_I386)
flags |= CPU_DUMP_CCOP;
#endif
+ if (qemu_loglevel_mask(CPU_LOG_TB_VPU)) {
+ flags |= CPU_DUMP_VPU;
+ }
cpu_dump_state(cpu, logfile, flags);
qemu_log_unlock(logfile);
}
diff --git a/disas/riscv.c b/disas/riscv.c
index d597161d46..5005364aba 100644
--- a/disas/riscv.c
+++ b/disas/riscv.c
@@ -19,7 +19,7 @@
#include "qemu/osdep.h"
#include "disas/dis-asm.h"
-
+#include "target/riscv/cpu_cfg.h"
/* types */
@@ -969,6 +969,7 @@ typedef enum {
/* structures */
typedef struct {
+ RISCVCPUConfig *cfg;
uint64_t pc;
uint64_t inst;
int32_t imm;
@@ -1109,8 +1110,10 @@ static const char rv_vreg_name_sym[32][4] = {
/* pseudo-instruction constraints */
static const rvc_constraint rvcc_jal[] = { rvc_rd_eq_ra, rvc_end };
-static const rvc_constraint rvcc_jalr[] = { rvc_rd_eq_ra, rvc_imm_eq_zero, rvc_end };
-static const rvc_constraint rvcc_nop[] = { rvc_rd_eq_x0, rvc_rs1_eq_x0, rvc_imm_eq_zero, rvc_end };
+static const rvc_constraint rvcc_jalr[] = { rvc_rd_eq_ra, rvc_imm_eq_zero,
+ rvc_end };
+static const rvc_constraint rvcc_nop[] = { rvc_rd_eq_x0, rvc_rs1_eq_x0,
+ rvc_imm_eq_zero, rvc_end };
static const rvc_constraint rvcc_mv[] = { rvc_imm_eq_zero, rvc_end };
static const rvc_constraint rvcc_not[] = { rvc_imm_eq_n1, rvc_end };
static const rvc_constraint rvcc_neg[] = { rvc_rs1_eq_x0, rvc_end };
@@ -1140,18 +1143,28 @@ static const rvc_constraint rvcc_bleu[] = { rvc_end };
static const rvc_constraint rvcc_bgt[] = { rvc_end };
static const rvc_constraint rvcc_bgtu[] = { rvc_end };
static const rvc_constraint rvcc_j[] = { rvc_rd_eq_x0, rvc_end };
-static const rvc_constraint rvcc_ret[] = { rvc_rd_eq_x0, rvc_rs1_eq_ra, rvc_end };
-static const rvc_constraint rvcc_jr[] = { rvc_rd_eq_x0, rvc_imm_eq_zero, rvc_end };
-static const rvc_constraint rvcc_rdcycle[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc00, rvc_end };
-static const rvc_constraint rvcc_rdtime[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc01, rvc_end };
-static const rvc_constraint rvcc_rdinstret[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc02, rvc_end };
-static const rvc_constraint rvcc_rdcycleh[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc80, rvc_end };
-static const rvc_constraint rvcc_rdtimeh[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc81, rvc_end };
+static const rvc_constraint rvcc_ret[] = { rvc_rd_eq_x0, rvc_rs1_eq_ra,
+ rvc_end };
+static const rvc_constraint rvcc_jr[] = { rvc_rd_eq_x0, rvc_imm_eq_zero,
+ rvc_end };
+static const rvc_constraint rvcc_rdcycle[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc00,
+ rvc_end };
+static const rvc_constraint rvcc_rdtime[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc01,
+ rvc_end };
+static const rvc_constraint rvcc_rdinstret[] = { rvc_rs1_eq_x0,
+ rvc_csr_eq_0xc02, rvc_end };
+static const rvc_constraint rvcc_rdcycleh[] = { rvc_rs1_eq_x0,
+ rvc_csr_eq_0xc80, rvc_end };
+static const rvc_constraint rvcc_rdtimeh[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc81,
+ rvc_end };
static const rvc_constraint rvcc_rdinstreth[] = { rvc_rs1_eq_x0,
rvc_csr_eq_0xc82, rvc_end };
-static const rvc_constraint rvcc_frcsr[] = { rvc_rs1_eq_x0, rvc_csr_eq_0x003, rvc_end };
-static const rvc_constraint rvcc_frrm[] = { rvc_rs1_eq_x0, rvc_csr_eq_0x002, rvc_end };
-static const rvc_constraint rvcc_frflags[] = { rvc_rs1_eq_x0, rvc_csr_eq_0x001, rvc_end };
+static const rvc_constraint rvcc_frcsr[] = { rvc_rs1_eq_x0, rvc_csr_eq_0x003,
+ rvc_end };
+static const rvc_constraint rvcc_frrm[] = { rvc_rs1_eq_x0, rvc_csr_eq_0x002,
+ rvc_end };
+static const rvc_constraint rvcc_frflags[] = { rvc_rs1_eq_x0, rvc_csr_eq_0x001,
+ rvc_end };
static const rvc_constraint rvcc_fscsr[] = { rvc_csr_eq_0x003, rvc_end };
static const rvc_constraint rvcc_fsrm[] = { rvc_csr_eq_0x002, rvc_end };
static const rvc_constraint rvcc_fsflags[] = { rvc_csr_eq_0x001, rvc_end };
@@ -1553,17 +1566,23 @@ const rv_opcode_data opcode_data[] = {
{ "fmv.q.x", rv_codec_r, rv_fmt_frd_rs1, NULL, 0, 0, 0 },
{ "c.addi4spn", rv_codec_ciw_4spn, rv_fmt_rd_rs1_imm, NULL, rv_op_addi,
rv_op_addi, rv_op_addi, rvcd_imm_nz },
- { "c.fld", rv_codec_cl_ld, rv_fmt_frd_offset_rs1, NULL, rv_op_fld, rv_op_fld, 0 },
- { "c.lw", rv_codec_cl_lw, rv_fmt_rd_offset_rs1, NULL, rv_op_lw, rv_op_lw, rv_op_lw },
+ { "c.fld", rv_codec_cl_ld, rv_fmt_frd_offset_rs1, NULL, rv_op_fld,
+ rv_op_fld, 0 },
+ { "c.lw", rv_codec_cl_lw, rv_fmt_rd_offset_rs1, NULL, rv_op_lw, rv_op_lw,
+ rv_op_lw },
{ "c.flw", rv_codec_cl_lw, rv_fmt_frd_offset_rs1, NULL, rv_op_flw, 0, 0 },
- { "c.fsd", rv_codec_cs_sd, rv_fmt_frs2_offset_rs1, NULL, rv_op_fsd, rv_op_fsd, 0 },
- { "c.sw", rv_codec_cs_sw, rv_fmt_rs2_offset_rs1, NULL, rv_op_sw, rv_op_sw, rv_op_sw },
+ { "c.fsd", rv_codec_cs_sd, rv_fmt_frs2_offset_rs1, NULL, rv_op_fsd,
+ rv_op_fsd, 0 },
+ { "c.sw", rv_codec_cs_sw, rv_fmt_rs2_offset_rs1, NULL, rv_op_sw, rv_op_sw,
+ rv_op_sw },
{ "c.fsw", rv_codec_cs_sw, rv_fmt_frs2_offset_rs1, NULL, rv_op_fsw, 0, 0 },
- { "c.nop", rv_codec_ci_none, rv_fmt_none, NULL, rv_op_addi, rv_op_addi, rv_op_addi },
+ { "c.nop", rv_codec_ci_none, rv_fmt_none, NULL, rv_op_addi, rv_op_addi,
+ rv_op_addi },
{ "c.addi", rv_codec_ci, rv_fmt_rd_rs1_imm, NULL, rv_op_addi, rv_op_addi,
rv_op_addi, rvcd_imm_nz },
{ "c.jal", rv_codec_cj_jal, rv_fmt_rd_offset, NULL, rv_op_jal, 0, 0 },
- { "c.li", rv_codec_ci_li, rv_fmt_rd_rs1_imm, NULL, rv_op_addi, rv_op_addi, rv_op_addi },
+ { "c.li", rv_codec_ci_li, rv_fmt_rd_rs1_imm, NULL, rv_op_addi, rv_op_addi,
+ rv_op_addi },
{ "c.addi16sp", rv_codec_ci_16sp, rv_fmt_rd_rs1_imm, NULL, rv_op_addi,
rv_op_addi, rv_op_addi, rvcd_imm_nz },
{ "c.lui", rv_codec_ci_lui, rv_fmt_rd_imm, NULL, rv_op_lui, rv_op_lui,
@@ -1574,37 +1593,63 @@ const rv_opcode_data opcode_data[] = {
rv_op_srai, rv_op_srai, rvcd_imm_nz },
{ "c.andi", rv_codec_cb_imm, rv_fmt_rd_rs1_imm, NULL, rv_op_andi,
rv_op_andi, rv_op_andi },
- { "c.sub", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_sub, rv_op_sub, rv_op_sub },
- { "c.xor", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_xor, rv_op_xor, rv_op_xor },
- { "c.or", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_or, rv_op_or, rv_op_or },
- { "c.and", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_and, rv_op_and, rv_op_and },
- { "c.subw", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_subw, rv_op_subw, rv_op_subw },
- { "c.addw", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_addw, rv_op_addw, rv_op_addw },
- { "c.j", rv_codec_cj, rv_fmt_rd_offset, NULL, rv_op_jal, rv_op_jal, rv_op_jal },
- { "c.beqz", rv_codec_cb, rv_fmt_rs1_rs2_offset, NULL, rv_op_beq, rv_op_beq, rv_op_beq },
- { "c.bnez", rv_codec_cb, rv_fmt_rs1_rs2_offset, NULL, rv_op_bne, rv_op_bne, rv_op_bne },
+ { "c.sub", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_sub, rv_op_sub,
+ rv_op_sub },
+ { "c.xor", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_xor, rv_op_xor,
+ rv_op_xor },
+ { "c.or", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_or, rv_op_or,
+ rv_op_or },
+ { "c.and", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_and, rv_op_and,
+ rv_op_and },
+ { "c.subw", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_subw, rv_op_subw,
+ rv_op_subw },
+ { "c.addw", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_addw, rv_op_addw,
+ rv_op_addw },
+ { "c.j", rv_codec_cj, rv_fmt_rd_offset, NULL, rv_op_jal, rv_op_jal,
+ rv_op_jal },
+ { "c.beqz", rv_codec_cb, rv_fmt_rs1_rs2_offset, NULL, rv_op_beq, rv_op_beq,
+ rv_op_beq },
+ { "c.bnez", rv_codec_cb, rv_fmt_rs1_rs2_offset, NULL, rv_op_bne, rv_op_bne,
+ rv_op_bne },
{ "c.slli", rv_codec_ci_sh6, rv_fmt_rd_rs1_imm, NULL, rv_op_slli,
rv_op_slli, rv_op_slli, rvcd_imm_nz },
- { "c.fldsp", rv_codec_ci_ldsp, rv_fmt_frd_offset_rs1, NULL, rv_op_fld, rv_op_fld, rv_op_fld },
- { "c.lwsp", rv_codec_ci_lwsp, rv_fmt_rd_offset_rs1, NULL, rv_op_lw, rv_op_lw, rv_op_lw },
- { "c.flwsp", rv_codec_ci_lwsp, rv_fmt_frd_offset_rs1, NULL, rv_op_flw, 0, 0 },
- { "c.jr", rv_codec_cr_jr, rv_fmt_rd_rs1_offset, NULL, rv_op_jalr, rv_op_jalr, rv_op_jalr },
- { "c.mv", rv_codec_cr_mv, rv_fmt_rd_rs1_rs2, NULL, rv_op_addi, rv_op_addi, rv_op_addi },
- { "c.ebreak", rv_codec_ci_none, rv_fmt_none, NULL, rv_op_ebreak, rv_op_ebreak, rv_op_ebreak },
- { "c.jalr", rv_codec_cr_jalr, rv_fmt_rd_rs1_offset, NULL, rv_op_jalr, rv_op_jalr, rv_op_jalr },
- { "c.add", rv_codec_cr, rv_fmt_rd_rs1_rs2, NULL, rv_op_add, rv_op_add, rv_op_add },
- { "c.fsdsp", rv_codec_css_sdsp, rv_fmt_frs2_offset_rs1, NULL, rv_op_fsd, rv_op_fsd, rv_op_fsd },
- { "c.swsp", rv_codec_css_swsp, rv_fmt_rs2_offset_rs1, NULL, rv_op_sw, rv_op_sw, rv_op_sw },
- { "c.fswsp", rv_codec_css_swsp, rv_fmt_frs2_offset_rs1, NULL, rv_op_fsw, 0, 0 },
- { "c.ld", rv_codec_cl_ld, rv_fmt_rd_offset_rs1, NULL, 0, rv_op_ld, rv_op_ld },
- { "c.sd", rv_codec_cs_sd, rv_fmt_rs2_offset_rs1, NULL, 0, rv_op_sd, rv_op_sd },
- { "c.addiw", rv_codec_ci, rv_fmt_rd_rs1_imm, NULL, 0, rv_op_addiw, rv_op_addiw },
- { "c.ldsp", rv_codec_ci_ldsp, rv_fmt_rd_offset_rs1, NULL, 0, rv_op_ld, rv_op_ld },
- { "c.sdsp", rv_codec_css_sdsp, rv_fmt_rs2_offset_rs1, NULL, 0, rv_op_sd, rv_op_sd },
+ { "c.fldsp", rv_codec_ci_ldsp, rv_fmt_frd_offset_rs1, NULL, rv_op_fld,
+ rv_op_fld, rv_op_fld },
+ { "c.lwsp", rv_codec_ci_lwsp, rv_fmt_rd_offset_rs1, NULL, rv_op_lw,
+ rv_op_lw, rv_op_lw },
+ { "c.flwsp", rv_codec_ci_lwsp, rv_fmt_frd_offset_rs1, NULL, rv_op_flw, 0,
+ 0 },
+ { "c.jr", rv_codec_cr_jr, rv_fmt_rd_rs1_offset, NULL, rv_op_jalr,
+ rv_op_jalr, rv_op_jalr },
+ { "c.mv", rv_codec_cr_mv, rv_fmt_rd_rs1_rs2, NULL, rv_op_addi, rv_op_addi,
+ rv_op_addi },
+ { "c.ebreak", rv_codec_ci_none, rv_fmt_none, NULL, rv_op_ebreak,
+ rv_op_ebreak, rv_op_ebreak },
+ { "c.jalr", rv_codec_cr_jalr, rv_fmt_rd_rs1_offset, NULL, rv_op_jalr,
+ rv_op_jalr, rv_op_jalr },
+ { "c.add", rv_codec_cr, rv_fmt_rd_rs1_rs2, NULL, rv_op_add, rv_op_add,
+ rv_op_add },
+ { "c.fsdsp", rv_codec_css_sdsp, rv_fmt_frs2_offset_rs1, NULL, rv_op_fsd,
+ rv_op_fsd, rv_op_fsd },
+ { "c.swsp", rv_codec_css_swsp, rv_fmt_rs2_offset_rs1, NULL, rv_op_sw,
+ rv_op_sw, rv_op_sw },
+ { "c.fswsp", rv_codec_css_swsp, rv_fmt_frs2_offset_rs1, NULL, rv_op_fsw, 0,
+ 0 },
+ { "c.ld", rv_codec_cl_ld, rv_fmt_rd_offset_rs1, NULL, 0, rv_op_ld,
+ rv_op_ld },
+ { "c.sd", rv_codec_cs_sd, rv_fmt_rs2_offset_rs1, NULL, 0, rv_op_sd,
+ rv_op_sd },
+ { "c.addiw", rv_codec_ci, rv_fmt_rd_rs1_imm, NULL, 0, rv_op_addiw,
+ rv_op_addiw },
+ { "c.ldsp", rv_codec_ci_ldsp, rv_fmt_rd_offset_rs1, NULL, 0, rv_op_ld,
+ rv_op_ld },
+ { "c.sdsp", rv_codec_css_sdsp, rv_fmt_rs2_offset_rs1, NULL, 0, rv_op_sd,
+ rv_op_sd },
{ "c.lq", rv_codec_cl_lq, rv_fmt_rd_offset_rs1, NULL, 0, 0, rv_op_lq },
{ "c.sq", rv_codec_cs_sq, rv_fmt_rs2_offset_rs1, NULL, 0, 0, rv_op_sq },
{ "c.lqsp", rv_codec_ci_lqsp, rv_fmt_rd_offset_rs1, NULL, 0, 0, rv_op_lq },
- { "c.sqsp", rv_codec_css_sqsp, rv_fmt_rs2_offset_rs1, NULL, 0, 0, rv_op_sq },
+ { "c.sqsp", rv_codec_css_sqsp, rv_fmt_rs2_offset_rs1, NULL, 0, 0,
+ rv_op_sq },
{ "nop", rv_codec_i, rv_fmt_none, NULL, 0, 0, 0 },
{ "mv", rv_codec_i, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
{ "not", rv_codec_i, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
@@ -1731,376 +1776,376 @@ const rv_opcode_data opcode_data[] = {
{ "zip", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
{ "xperm4", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
{ "xperm8", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
- { "vle8.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vle8_v, rv_op_vle8_v, 0 },
- { "vle16.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vle16_v, rv_op_vle16_v, 0 },
- { "vle32.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vle32_v, rv_op_vle32_v, 0 },
- { "vle64.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vle64_v, rv_op_vle64_v, 0 },
- { "vse8.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vse8_v, rv_op_vse8_v, 0 },
- { "vse16.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vse16_v, rv_op_vse16_v, 0 },
- { "vse32.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vse32_v, rv_op_vse32_v, 0 },
- { "vse64.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vse64_v, rv_op_vse64_v, 0 },
- { "vlm.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vlm_v, rv_op_vlm_v, 0 },
- { "vsm.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vsm_v, rv_op_vsm_v, 0 },
- { "vlse8.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_rs2_vm, NULL, rv_op_vlse8_v, rv_op_vlse8_v, 0 },
- { "vlse16.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_rs2_vm, NULL, rv_op_vlse16_v, rv_op_vlse16_v, 0 },
- { "vlse32.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_rs2_vm, NULL, rv_op_vlse32_v, rv_op_vlse32_v, 0 },
- { "vlse64.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_rs2_vm, NULL, rv_op_vlse64_v, rv_op_vlse64_v, 0 },
- { "vsse8.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_rs2_vm, NULL, rv_op_vsse8_v, rv_op_vsse8_v, 0 },
- { "vsse16.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_rs2_vm, NULL, rv_op_vsse16_v, rv_op_vsse16_v, 0 },
- { "vsse32.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_rs2_vm, NULL, rv_op_vsse32_v, rv_op_vsse32_v, 0 },
- { "vsse64.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_rs2_vm, NULL, rv_op_vsse64_v, rv_op_vsse64_v, 0 },
- { "vluxei8.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, rv_op_vluxei8_v, rv_op_vluxei8_v, 0 },
- { "vluxei16.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, rv_op_vluxei16_v, rv_op_vluxei16_v, 0 },
- { "vluxei32.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, rv_op_vluxei32_v, rv_op_vluxei32_v, 0 },
- { "vluxei64.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, rv_op_vluxei64_v, rv_op_vluxei64_v, 0 },
- { "vloxei8.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, rv_op_vloxei8_v, rv_op_vloxei8_v, 0 },
- { "vloxei16.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, rv_op_vloxei16_v, rv_op_vloxei16_v, 0 },
- { "vloxei32.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, rv_op_vloxei32_v, rv_op_vloxei32_v, 0 },
- { "vloxei64.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, rv_op_vloxei64_v, rv_op_vloxei64_v, 0 },
- { "vsuxei8.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, rv_op_vsuxei8_v, rv_op_vsuxei8_v, 0 },
- { "vsuxei16.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, rv_op_vsuxei16_v, rv_op_vsuxei16_v, 0 },
- { "vsuxei32.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, rv_op_vsuxei32_v, rv_op_vsuxei32_v, 0 },
- { "vsuxei64.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, rv_op_vsuxei64_v, rv_op_vsuxei64_v, 0 },
- { "vsoxei8.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, rv_op_vsoxei8_v, rv_op_vsoxei8_v, 0 },
- { "vsoxei16.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, rv_op_vsoxei16_v, rv_op_vsoxei16_v, 0 },
- { "vsoxei32.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, rv_op_vsoxei32_v, rv_op_vsoxei32_v, 0 },
- { "vsoxei64.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, rv_op_vsoxei64_v, rv_op_vsoxei64_v, 0 },
- { "vle8ff.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vle8ff_v, rv_op_vle8ff_v, 0 },
- { "vle16ff.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vle16ff_v, rv_op_vle16ff_v, 0 },
- { "vle32ff.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vle32ff_v, rv_op_vle32ff_v, 0 },
- { "vle64ff.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vle64ff_v, rv_op_vle64ff_v, 0 },
- { "vl1re8.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vl1re8_v, rv_op_vl1re8_v, 0 },
- { "vl1re16.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vl1re16_v, rv_op_vl1re16_v, 0 },
- { "vl1re32.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vl1re32_v, rv_op_vl1re32_v, 0 },
- { "vl1re64.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vl1re64_v, rv_op_vl1re64_v, 0 },
- { "vl2re8.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vl2re8_v, rv_op_vl2re8_v, 0 },
- { "vl2re16.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vl2re16_v, rv_op_vl2re16_v, 0 },
- { "vl2re32.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vl2re32_v, rv_op_vl2re32_v, 0 },
- { "vl2re64.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vl2re64_v, rv_op_vl2re64_v, 0 },
- { "vl4re8.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vl4re8_v, rv_op_vl4re8_v, 0 },
- { "vl4re16.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vl4re16_v, rv_op_vl4re16_v, 0 },
- { "vl4re32.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vl4re32_v, rv_op_vl4re32_v, 0 },
- { "vl4re64.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vl4re64_v, rv_op_vl4re64_v, 0 },
- { "vl8re8.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vl8re8_v, rv_op_vl8re8_v, 0 },
- { "vl8re16.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vl8re16_v, rv_op_vl8re16_v, 0 },
- { "vl8re32.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vl8re32_v, rv_op_vl8re32_v, 0 },
- { "vl8re64.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vl8re64_v, rv_op_vl8re64_v, 0 },
- { "vs1r.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vs1r_v, rv_op_vs1r_v, 0 },
- { "vs2r.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vs2r_v, rv_op_vs2r_v, 0 },
- { "vs4r.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vs4r_v, rv_op_vs4r_v, 0 },
- { "vs8r.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, rv_op_vs8r_v, rv_op_vs8r_v, 0 },
- { "vadd.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vadd_vv, rv_op_vadd_vv, 0 },
- { "vadd.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vadd_vx, rv_op_vadd_vx, 0 },
- { "vadd.vi", rv_codec_v_i, rv_fmt_vd_vs2_imm_vm, NULL, rv_op_vadd_vi, rv_op_vadd_vi, 0 },
- { "vsub.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vsub_vv, rv_op_vsub_vv, 0 },
- { "vsub.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vsub_vx, rv_op_vsub_vx, 0 },
- { "vrsub.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vrsub_vx, rv_op_vrsub_vx, 0 },
- { "vrsub.vi", rv_codec_v_i, rv_fmt_vd_vs2_imm_vm, NULL, rv_op_vrsub_vi, rv_op_vrsub_vi, 0 },
- { "vwaddu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vwaddu_vv, rv_op_vwaddu_vv, 0 },
- { "vwaddu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vwaddu_vx, rv_op_vwaddu_vx, 0 },
- { "vwadd.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vwadd_vv, rv_op_vwadd_vv, 0 },
- { "vwadd.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vwadd_vx, rv_op_vwadd_vx, 0 },
- { "vwsubu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vwsubu_vv, rv_op_vwsubu_vv, 0 },
- { "vwsubu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vwsubu_vx, rv_op_vwsubu_vx, 0 },
- { "vwsub.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vwsub_vv, rv_op_vwsub_vv, 0 },
- { "vwsub.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vwsub_vx, rv_op_vwsub_vx, 0 },
- { "vwaddu.wv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vwaddu_wv, rv_op_vwaddu_wv, 0 },
- { "vwaddu.wx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vwaddu_wx, rv_op_vwaddu_wx, 0 },
- { "vwadd.wv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vwadd_wv, rv_op_vwadd_wv, 0 },
- { "vwadd.wx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vwadd_wx, rv_op_vwadd_wx, 0 },
- { "vwsubu.wv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vwsubu_wv, rv_op_vwsubu_wv, 0 },
- { "vwsubu.wx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vwsubu_wx, rv_op_vwsubu_wx, 0 },
- { "vwsub.wv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vwsub_wv, rv_op_vwsub_wv, 0 },
- { "vwsub.wx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vwsub_wx, rv_op_vwsub_wx, 0 },
- { "vadc.vvm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vl, NULL, rv_op_vadc_vvm, rv_op_vadc_vvm, 0 },
- { "vadc.vxm", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vl, NULL, rv_op_vadc_vxm, rv_op_vadc_vxm, 0 },
- { "vadc.vim", rv_codec_v_i, rv_fmt_vd_vs2_imm_vl, NULL, rv_op_vadc_vim, rv_op_vadc_vim, 0 },
- { "vmadc.vvm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vl, NULL, rv_op_vmadc_vvm, rv_op_vmadc_vvm, 0 },
- { "vmadc.vxm", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vl, NULL, rv_op_vmadc_vxm, rv_op_vmadc_vxm, 0 },
- { "vmadc.vim", rv_codec_v_i, rv_fmt_vd_vs2_imm_vl, NULL, rv_op_vmadc_vim, rv_op_vmadc_vim, 0 },
- { "vsbc.vvm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vl, NULL, rv_op_vsbc_vvm, rv_op_vsbc_vvm, 0 },
- { "vsbc.vxm", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vl, NULL, rv_op_vsbc_vxm, rv_op_vsbc_vxm, 0 },
- { "vmsbc.vvm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vl, NULL, rv_op_vmsbc_vvm, rv_op_vmsbc_vvm, 0 },
- { "vmsbc.vxm", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vl, NULL, rv_op_vmsbc_vxm, rv_op_vmsbc_vxm, 0 },
- { "vand.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vand_vv, rv_op_vand_vv, 0 },
- { "vand.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vand_vx, rv_op_vand_vx, 0 },
- { "vand.vi", rv_codec_v_i, rv_fmt_vd_vs2_imm_vm, NULL, rv_op_vand_vi, rv_op_vand_vi, 0 },
- { "vor.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vor_vv, rv_op_vor_vv, 0 },
- { "vor.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vor_vx, rv_op_vor_vx, 0 },
- { "vor.vi", rv_codec_v_i, rv_fmt_vd_vs2_imm_vm, NULL, rv_op_vor_vi, rv_op_vor_vi, 0 },
- { "vxor.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vxor_vv, rv_op_vxor_vv, 0 },
- { "vxor.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vxor_vx, rv_op_vxor_vx, 0 },
- { "vxor.vi", rv_codec_v_i, rv_fmt_vd_vs2_imm_vm, NULL, rv_op_vxor_vi, rv_op_vxor_vi, 0 },
- { "vsll.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vsll_vv, rv_op_vsll_vv, 0 },
- { "vsll.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vsll_vx, rv_op_vsll_vx, 0 },
- { "vsll.vi", rv_codec_v_i, rv_fmt_vd_vs2_uimm_vm, NULL, rv_op_vsll_vi, rv_op_vsll_vi, 0 },
- { "vsrl.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vsrl_vv, rv_op_vsrl_vv, 0 },
- { "vsrl.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vsrl_vx, rv_op_vsrl_vx, 0 },
- { "vsrl.vi", rv_codec_v_i, rv_fmt_vd_vs2_uimm_vm, NULL, rv_op_vsrl_vi, rv_op_vsrl_vi, 0 },
- { "vsra.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vsra_vv, rv_op_vsra_vv, 0 },
- { "vsra.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vsra_vx, rv_op_vsra_vx, 0 },
- { "vsra.vi", rv_codec_v_i, rv_fmt_vd_vs2_uimm_vm, NULL, rv_op_vsra_vi, rv_op_vsra_vi, 0 },
- { "vnsrl.wv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vnsrl_wv, rv_op_vnsrl_wv, 0 },
- { "vnsrl.wx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vnsrl_wx, rv_op_vnsrl_wx, 0 },
- { "vnsrl.wi", rv_codec_v_i, rv_fmt_vd_vs2_uimm_vm, NULL, rv_op_vnsrl_wi, rv_op_vnsrl_wi, 0 },
- { "vnsra.wv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vnsra_wv, rv_op_vnsra_wv, 0 },
- { "vnsra.wx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vnsra_wx, rv_op_vnsra_wx, 0 },
- { "vnsra.wi", rv_codec_v_i, rv_fmt_vd_vs2_uimm_vm, NULL, rv_op_vnsra_wi, rv_op_vnsra_wi, 0 },
- { "vmseq.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vmseq_vv, rv_op_vmseq_vv, 0 },
- { "vmseq.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vmseq_vx, rv_op_vmseq_vx, 0 },
- { "vmseq.vi", rv_codec_v_i, rv_fmt_vd_vs2_imm_vm, NULL, rv_op_vmseq_vi, rv_op_vmseq_vi, 0 },
- { "vmsne.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vmsne_vv, rv_op_vmsne_vv, 0 },
- { "vmsne.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vmsne_vx, rv_op_vmsne_vx, 0 },
- { "vmsne.vi", rv_codec_v_i, rv_fmt_vd_vs2_imm_vm, NULL, rv_op_vmsne_vi, rv_op_vmsne_vi, 0 },
- { "vmsltu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vmsltu_vv, rv_op_vmsltu_vv, 0 },
- { "vmsltu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vmsltu_vx, rv_op_vmsltu_vx, 0 },
- { "vmslt.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vmslt_vv, rv_op_vmslt_vv, 0 },
- { "vmslt.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vmslt_vx, rv_op_vmslt_vx, 0 },
- { "vmsleu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vmsleu_vv, rv_op_vmsleu_vv, 0 },
- { "vmsleu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vmsleu_vx, rv_op_vmsleu_vx, 0 },
- { "vmsleu.vi", rv_codec_v_i, rv_fmt_vd_vs2_imm_vm, NULL, rv_op_vmsleu_vi, rv_op_vmsleu_vi, 0 },
- { "vmsle.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vmsle_vv, rv_op_vmsle_vv, 0 },
- { "vmsle.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vmsle_vx, rv_op_vmsle_vx, 0 },
- { "vmsle.vi", rv_codec_v_i, rv_fmt_vd_vs2_imm_vm, NULL, rv_op_vmsle_vi, rv_op_vmsle_vi, 0 },
- { "vmsgtu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vmsgtu_vx, rv_op_vmsgtu_vx, 0 },
- { "vmsgtu.vi", rv_codec_v_i, rv_fmt_vd_vs2_imm_vm, NULL, rv_op_vmsgtu_vi, rv_op_vmsgtu_vi, 0 },
- { "vmsgt.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vmsgt_vx, rv_op_vmsgt_vx, 0 },
- { "vmsgt.vi", rv_codec_v_i, rv_fmt_vd_vs2_imm_vm, NULL, rv_op_vmsgt_vi, rv_op_vmsgt_vi, 0 },
- { "vminu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vminu_vv, rv_op_vminu_vv, 0 },
- { "vminu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vminu_vx, rv_op_vminu_vx, 0 },
- { "vmin.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vmin_vv, rv_op_vmin_vv, 0 },
- { "vmin.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vmin_vx, rv_op_vmin_vx, 0 },
- { "vmaxu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vmaxu_vv, rv_op_vmaxu_vv, 0 },
- { "vmaxu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vmaxu_vx, rv_op_vmaxu_vx, 0 },
- { "vmax.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vmax_vv, rv_op_vmax_vv, 0 },
- { "vmax.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vmax_vx, rv_op_vmax_vx, 0 },
- { "vmul.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vmul_vv, rv_op_vmul_vv, 0 },
- { "vmul.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vmul_vx, rv_op_vmul_vx, 0 },
- { "vmulh.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vmulh_vv, rv_op_vmulh_vv, 0 },
- { "vmulh.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vmulh_vx, rv_op_vmulh_vx, 0 },
- { "vmulhu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vmulhu_vv, rv_op_vmulhu_vv, 0 },
- { "vmulhu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vmulhu_vx, rv_op_vmulhu_vx, 0 },
- { "vmulhsu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vmulhsu_vv, rv_op_vmulhsu_vv, 0 },
- { "vmulhsu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vmulhsu_vx, rv_op_vmulhsu_vx, 0 },
- { "vdivu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vdivu_vv, rv_op_vdivu_vv, 0 },
- { "vdivu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vdivu_vx, rv_op_vdivu_vx, 0 },
- { "vdiv.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vdiv_vv, rv_op_vdiv_vv, 0 },
- { "vdiv.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vdiv_vx, rv_op_vdiv_vx, 0 },
- { "vremu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vremu_vv, rv_op_vremu_vv, 0 },
- { "vremu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vremu_vx, rv_op_vremu_vx, 0 },
- { "vrem.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vrem_vv, rv_op_vrem_vv, 0 },
- { "vrem.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vrem_vx, rv_op_vrem_vx, 0 },
- { "vwmulu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vwmulu_vv, rv_op_vwmulu_vv, 0 },
- { "vwmulu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vwmulu_vx, rv_op_vwmulu_vx, 0 },
- { "vwmulsu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vwmulsu_vv, rv_op_vwmulsu_vv, 0 },
- { "vwmulsu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vwmulsu_vx, rv_op_vwmulsu_vx, 0 },
- { "vwmul.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vwmul_vv, rv_op_vwmul_vv, 0 },
- { "vwmul.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vwmul_vx, rv_op_vwmul_vx, 0 },
- { "vmacc.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, rv_op_vmacc_vv, rv_op_vmacc_vv, 0 },
- { "vmacc.vx", rv_codec_v_r, rv_fmt_vd_rs1_vs2_vm, NULL, rv_op_vmacc_vx, rv_op_vmacc_vx, 0 },
- { "vnmsac.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, rv_op_vnmsac_vv, rv_op_vnmsac_vv, 0 },
- { "vnmsac.vx", rv_codec_v_r, rv_fmt_vd_rs1_vs2_vm, NULL, rv_op_vnmsac_vx, rv_op_vnmsac_vx, 0 },
- { "vmadd.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, rv_op_vmadd_vv, rv_op_vmadd_vv, 0 },
- { "vmadd.vx", rv_codec_v_r, rv_fmt_vd_rs1_vs2_vm, NULL, rv_op_vmadd_vx, rv_op_vmadd_vx, 0 },
- { "vnmsub.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, rv_op_vnmsub_vv, rv_op_vnmsub_vv, 0 },
- { "vnmsub.vx", rv_codec_v_r, rv_fmt_vd_rs1_vs2_vm, NULL, rv_op_vnmsub_vx, rv_op_vnmsub_vx, 0 },
- { "vwmaccu.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, rv_op_vwmaccu_vv, rv_op_vwmaccu_vv, 0 },
- { "vwmaccu.vx", rv_codec_v_r, rv_fmt_vd_rs1_vs2_vm, NULL, rv_op_vwmaccu_vx, rv_op_vwmaccu_vx, 0 },
- { "vwmacc.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, rv_op_vwmacc_vv, rv_op_vwmacc_vv, 0 },
- { "vwmacc.vx", rv_codec_v_r, rv_fmt_vd_rs1_vs2_vm, NULL, rv_op_vwmacc_vx, rv_op_vwmacc_vx, 0 },
- { "vwmaccsu.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, rv_op_vwmaccsu_vv, rv_op_vwmaccsu_vv, 0 },
- { "vwmaccsu.vx", rv_codec_v_r, rv_fmt_vd_rs1_vs2_vm, NULL, rv_op_vwmaccsu_vx, rv_op_vwmaccsu_vx, 0 },
- { "vwmaccus.vx", rv_codec_v_r, rv_fmt_vd_rs1_vs2_vm, NULL, rv_op_vwmaccus_vx, rv_op_vwmaccus_vx, 0 },
- { "vmv.v.v", rv_codec_v_r, rv_fmt_vd_vs1, NULL, rv_op_vmv_v_v, rv_op_vmv_v_v, 0 },
- { "vmv.v.x", rv_codec_v_r, rv_fmt_vd_rs1, NULL, rv_op_vmv_v_x, rv_op_vmv_v_x, 0 },
- { "vmv.v.i", rv_codec_v_i, rv_fmt_vd_imm, NULL, rv_op_vmv_v_i, rv_op_vmv_v_i, 0 },
- { "vmerge.vvm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vl, NULL, rv_op_vmerge_vvm, rv_op_vmerge_vvm, 0 },
- { "vmerge.vxm", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vl, NULL, rv_op_vmerge_vxm, rv_op_vmerge_vxm, 0 },
- { "vmerge.vim", rv_codec_v_i, rv_fmt_vd_vs2_imm_vl, NULL, rv_op_vmerge_vim, rv_op_vmerge_vim, 0 },
- { "vsaddu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vsaddu_vv, rv_op_vsaddu_vv, 0 },
- { "vsaddu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vsaddu_vx, rv_op_vsaddu_vx, 0 },
- { "vsaddu.vi", rv_codec_v_i, rv_fmt_vd_vs2_imm_vm, NULL, rv_op_vsaddu_vi, rv_op_vsaddu_vi, 0 },
- { "vsadd.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vsadd_vv, rv_op_vsadd_vv, 0 },
- { "vsadd.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vsadd_vx, rv_op_vsadd_vx, 0 },
- { "vsadd.vi", rv_codec_v_i, rv_fmt_vd_vs2_imm_vm, NULL, rv_op_vsadd_vi, rv_op_vsadd_vi, 0 },
- { "vssubu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vssubu_vv, rv_op_vssubu_vv, 0 },
- { "vssubu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vssubu_vx, rv_op_vssubu_vx, 0 },
- { "vssub.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vssub_vv, rv_op_vssub_vv, 0 },
- { "vssub.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vssub_vx, rv_op_vssub_vx, 0 },
- { "vaadd.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vaadd_vv, rv_op_vaadd_vv, 0 },
- { "vaadd.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vaadd_vx, rv_op_vaadd_vx, 0 },
- { "vaaddu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vaaddu_vv, rv_op_vaaddu_vv, 0 },
- { "vaaddu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vaaddu_vx, rv_op_vaaddu_vx, 0 },
- { "vasub.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vasub_vv, rv_op_vasub_vv, 0 },
- { "vasub.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vasub_vx, rv_op_vasub_vx, 0 },
- { "vasubu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vasubu_vv, rv_op_vasubu_vv, 0 },
- { "vasubu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vasubu_vx, rv_op_vasubu_vx, 0 },
- { "vsmul.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vsmul_vv, rv_op_vsmul_vv, 0 },
- { "vsmul.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vsmul_vx, rv_op_vsmul_vx, 0 },
- { "vssrl.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vssrl_vv, rv_op_vssrl_vv, 0 },
- { "vssrl.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vssrl_vx, rv_op_vssrl_vx, 0 },
- { "vssrl.vi", rv_codec_v_i, rv_fmt_vd_vs2_uimm_vm, NULL, rv_op_vssrl_vi, rv_op_vssrl_vi, 0 },
- { "vssra.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vssra_vv, rv_op_vssra_vv, 0 },
- { "vssra.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vssra_vx, rv_op_vssra_vx, 0 },
- { "vssra.vi", rv_codec_v_i, rv_fmt_vd_vs2_uimm_vm, NULL, rv_op_vssra_vi, rv_op_vssra_vi, 0 },
- { "vnclipu.wv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vnclipu_wv, rv_op_vnclipu_wv, 0 },
- { "vnclipu.wx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vnclipu_wx, rv_op_vnclipu_wx, 0 },
- { "vnclipu.wi", rv_codec_v_i, rv_fmt_vd_vs2_uimm_vm, NULL, rv_op_vnclipu_wi, rv_op_vnclipu_wi, 0 },
- { "vnclip.wv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vnclip_wv, rv_op_vnclip_wv, 0 },
- { "vnclip.wx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vnclip_wx, rv_op_vnclip_wx, 0 },
- { "vnclip.wi", rv_codec_v_i, rv_fmt_vd_vs2_uimm_vm, NULL, rv_op_vnclip_wi, rv_op_vnclip_wi, 0 },
- { "vfadd.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vfadd_vv, rv_op_vfadd_vv, 0 },
- { "vfadd.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, rv_op_vfadd_vf, rv_op_vfadd_vf, 0 },
- { "vfsub.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vfsub_vv, rv_op_vfsub_vv, 0 },
- { "vfsub.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, rv_op_vfsub_vf, rv_op_vfsub_vf, 0 },
- { "vfrsub.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, rv_op_vfrsub_vf, rv_op_vfrsub_vf, 0 },
- { "vfwadd.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vfwadd_vv, rv_op_vfwadd_vv, 0 },
- { "vfwadd.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, rv_op_vfwadd_vf, rv_op_vfwadd_vf, 0 },
- { "vfwadd.wv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vfwadd_wv, rv_op_vfwadd_wv, 0 },
- { "vfwadd.wf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, rv_op_vfwadd_wf, rv_op_vfwadd_wf, 0 },
- { "vfwsub.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vfwsub_vv, rv_op_vfwsub_vv, 0 },
- { "vfwsub.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, rv_op_vfwsub_vf, rv_op_vfwsub_vf, 0 },
- { "vfwsub.wv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vfwsub_wv, rv_op_vfwsub_wv, 0 },
- { "vfwsub.wf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, rv_op_vfwsub_wf, rv_op_vfwsub_wf, 0 },
- { "vfmul.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vfmul_vv, rv_op_vfmul_vv, 0 },
- { "vfmul.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, rv_op_vfmul_vf, rv_op_vfmul_vf, 0 },
- { "vfdiv.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vfdiv_vv, rv_op_vfdiv_vv, 0 },
- { "vfdiv.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, rv_op_vfdiv_vf, rv_op_vfdiv_vf, 0 },
- { "vfrdiv.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, rv_op_vfrdiv_vf, rv_op_vfrdiv_vf, 0 },
- { "vfwmul.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vfwmul_vv, rv_op_vfwmul_vv, 0 },
- { "vfwmul.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, rv_op_vfwmul_vf, rv_op_vfwmul_vf, 0 },
- { "vfmacc.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, rv_op_vfmacc_vv, rv_op_vfmacc_vv, 0 },
- { "vfmacc.vf", rv_codec_v_r, rv_fmt_vd_fs1_vs2_vm, NULL, rv_op_vfmacc_vf, rv_op_vfmacc_vf, 0 },
- { "vfnmacc.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, rv_op_vfnmacc_vv, rv_op_vfnmacc_vv, 0 },
- { "vfnmacc.vf", rv_codec_v_r, rv_fmt_vd_fs1_vs2_vm, NULL, rv_op_vfnmacc_vf, rv_op_vfnmacc_vf, 0 },
- { "vfmsac.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, rv_op_vfmsac_vv, rv_op_vfmsac_vv, 0 },
- { "vfmsac.vf", rv_codec_v_r, rv_fmt_vd_fs1_vs2_vm, NULL, rv_op_vfmsac_vf, rv_op_vfmsac_vf, 0 },
- { "vfnmsac.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, rv_op_vfnmsac_vv, rv_op_vfnmsac_vv, 0 },
- { "vfnmsac.vf", rv_codec_v_r, rv_fmt_vd_fs1_vs2_vm, NULL, rv_op_vfnmsac_vf, rv_op_vfnmsac_vf, 0 },
- { "vfmadd.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, rv_op_vfmadd_vv, rv_op_vfmadd_vv, 0 },
- { "vfmadd.vf", rv_codec_v_r, rv_fmt_vd_fs1_vs2_vm, NULL, rv_op_vfmadd_vf, rv_op_vfmadd_vf, 0 },
- { "vfnmadd.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, rv_op_vfnmadd_vv, rv_op_vfnmadd_vv, 0 },
- { "vfnmadd.vf", rv_codec_v_r, rv_fmt_vd_fs1_vs2_vm, NULL, rv_op_vfnmadd_vf, rv_op_vfnmadd_vf, 0 },
- { "vfmsub.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, rv_op_vfmsub_vv, rv_op_vfmsub_vv, 0 },
- { "vfmsub.vf", rv_codec_v_r, rv_fmt_vd_fs1_vs2_vm, NULL, rv_op_vfmsub_vf, rv_op_vfmsub_vf, 0 },
- { "vfnmsub.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, rv_op_vfnmsub_vv, rv_op_vfnmsub_vv, 0 },
- { "vfnmsub.vf", rv_codec_v_r, rv_fmt_vd_fs1_vs2_vm, NULL, rv_op_vfnmsub_vf, rv_op_vfnmsub_vf, 0 },
- { "vfwmacc.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, rv_op_vfwmacc_vv, rv_op_vfwmacc_vv, 0 },
- { "vfwmacc.vf", rv_codec_v_r, rv_fmt_vd_fs1_vs2_vm, NULL, rv_op_vfwmacc_vf, rv_op_vfwmacc_vf, 0 },
- { "vfwnmacc.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, rv_op_vfwnmacc_vv, rv_op_vfwnmacc_vv, 0 },
- { "vfwnmacc.vf", rv_codec_v_r, rv_fmt_vd_fs1_vs2_vm, NULL, rv_op_vfwnmacc_vf, rv_op_vfwnmacc_vf, 0 },
- { "vfwmsac.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, rv_op_vfwmsac_vv, rv_op_vfwmsac_vv, 0 },
- { "vfwmsac.vf", rv_codec_v_r, rv_fmt_vd_fs1_vs2_vm, NULL, rv_op_vfwmsac_vf, rv_op_vfwmsac_vf, 0 },
- { "vfwnmsac.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, rv_op_vfwnmsac_vv, rv_op_vfwnmsac_vv, 0 },
- { "vfwnmsac.vf", rv_codec_v_r, rv_fmt_vd_fs1_vs2_vm, NULL, rv_op_vfwnmsac_vf, rv_op_vfwnmsac_vf, 0 },
- { "vfsqrt.v", rv_codec_v_r, rv_fmt_vd_vs2, NULL, rv_op_vfsqrt_v, rv_op_vfsqrt_v, 0 },
- { "vfrsqrt7.v", rv_codec_v_r, rv_fmt_vd_vs2, NULL, rv_op_vfrsqrt7_v, rv_op_vfrsqrt7_v, 0 },
- { "vfrec7.v", rv_codec_v_r, rv_fmt_vd_vs2, NULL, rv_op_vfrec7_v, rv_op_vfrec7_v, 0 },
- { "vfmin.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vfmin_vv, rv_op_vfmin_vv, 0 },
- { "vfmin.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, rv_op_vfmin_vf, rv_op_vfmin_vf, 0 },
- { "vfmax.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vfmax_vv, rv_op_vfmax_vv, 0 },
- { "vfmax.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, rv_op_vfmax_vf, rv_op_vfmax_vf, 0 },
- { "vfsgnj.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vfsgnj_vv, rv_op_vfsgnj_vv, 0 },
- { "vfsgnj.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, rv_op_vfsgnj_vf, rv_op_vfsgnj_vf, 0 },
- { "vfsgnjn.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vfsgnjn_vv, rv_op_vfsgnjn_vv, 0 },
- { "vfsgnjn.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, rv_op_vfsgnjn_vf, rv_op_vfsgnjn_vf, 0 },
- { "vfsgnjx.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vfsgnjx_vv, rv_op_vfsgnjx_vv, 0 },
- { "vfsgnjx.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, rv_op_vfsgnjx_vf, rv_op_vfsgnjx_vf, 0 },
- { "vfslide1up.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, rv_op_vfslide1up_vf, rv_op_vfslide1up_vf, 0 },
- { "vfslide1down.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, rv_op_vfslide1down_vf, rv_op_vfslide1down_vf, 0 },
- { "vmfeq.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vmfeq_vv, rv_op_vmfeq_vv, 0 },
- { "vmfeq.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, rv_op_vmfeq_vf, rv_op_vmfeq_vf, 0 },
- { "vmfne.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vmfne_vv, rv_op_vmfne_vv, 0 },
- { "vmfne.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, rv_op_vmfne_vf, rv_op_vmfne_vf, 0 },
- { "vmflt.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vmflt_vv, rv_op_vmflt_vv, 0 },
- { "vmflt.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, rv_op_vmflt_vf, rv_op_vmflt_vf, 0 },
- { "vmfle.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vmfle_vv, rv_op_vmfle_vv, 0 },
- { "vmfle.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, rv_op_vmfle_vf, rv_op_vmfle_vf, 0 },
- { "vmfgt.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, rv_op_vmfgt_vf, rv_op_vmfgt_vf, 0 },
- { "vmfge.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, rv_op_vmfge_vf, rv_op_vmfge_vf, 0 },
- { "vfclass.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vfclass_v, rv_op_vfclass_v, 0 },
- { "vfmerge.vfm", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vl, NULL, rv_op_vfmerge_vfm, rv_op_vfmerge_vfm, 0 },
- { "vfmv.v.f", rv_codec_v_r, rv_fmt_vd_fs1, NULL, rv_op_vfmv_v_f, rv_op_vfmv_v_f, 0 },
- { "vfcvt.xu.f.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vfcvt_xu_f_v, rv_op_vfcvt_xu_f_v, 0 },
- { "vfcvt.x.f.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vfcvt_x_f_v, rv_op_vfcvt_x_f_v, 0 },
- { "vfcvt.f.xu.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vfcvt_f_xu_v, rv_op_vfcvt_f_xu_v, 0 },
- { "vfcvt.f.x.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vfcvt_f_x_v, rv_op_vfcvt_f_x_v, 0 },
- { "vfcvt.rtz.xu.f.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vfcvt_rtz_xu_f_v, rv_op_vfcvt_rtz_xu_f_v, 0 },
- { "vfcvt.rtz.x.f.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vfcvt_rtz_x_f_v, rv_op_vfcvt_rtz_x_f_v, 0 },
- { "vfwcvt.xu.f.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vfwcvt_xu_f_v, rv_op_vfwcvt_xu_f_v, 0 },
- { "vfwcvt.x.f.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vfwcvt_x_f_v, rv_op_vfwcvt_x_f_v, 0 },
- { "vfwcvt.f.xu.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vfwcvt_f_xu_v, rv_op_vfwcvt_f_xu_v, 0 },
- { "vfwcvt.f.x.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vfwcvt_f_x_v, rv_op_vfwcvt_f_x_v, 0 },
- { "vfwcvt.f.f.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vfwcvt_f_f_v, rv_op_vfwcvt_f_f_v, 0 },
- { "vfwcvt.rtz.xu.f.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vfwcvt_rtz_xu_f_v, rv_op_vfwcvt_rtz_xu_f_v, 0 },
- { "vfwcvt.rtz.x.f.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vfwcvt_rtz_x_f_v, rv_op_vfwcvt_rtz_x_f_v, 0 },
- { "vfncvt.xu.f.w", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vfncvt_xu_f_w, rv_op_vfncvt_xu_f_w, 0 },
- { "vfncvt.x.f.w", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vfncvt_x_f_w, rv_op_vfncvt_x_f_w, 0 },
- { "vfncvt.f.xu.w", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vfncvt_f_xu_w, rv_op_vfncvt_f_xu_w, 0 },
- { "vfncvt.f.x.w", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vfncvt_f_x_w, rv_op_vfncvt_f_x_w, 0 },
- { "vfncvt.f.f.w", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vfncvt_f_f_w, rv_op_vfncvt_f_f_w, 0 },
- { "vfncvt.rod.f.f.w", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vfncvt_rod_f_f_w, rv_op_vfncvt_rod_f_f_w, 0 },
- { "vfncvt.rtz.xu.f.w", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vfncvt_rtz_xu_f_w, rv_op_vfncvt_rtz_xu_f_w, 0 },
- { "vfncvt.rtz.x.f.w", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vfncvt_rtz_x_f_w, rv_op_vfncvt_rtz_x_f_w, 0 },
- { "vredsum.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vredsum_vs, rv_op_vredsum_vs, 0 },
- { "vredand.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vredand_vs, rv_op_vredand_vs, 0 },
- { "vredor.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vredor_vs, rv_op_vredor_vs, 0 },
- { "vredxor.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vredxor_vs, rv_op_vredxor_vs, 0 },
- { "vredminu.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vredminu_vs, rv_op_vredminu_vs, 0 },
- { "vredmin.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vredmin_vs, rv_op_vredmin_vs, 0 },
- { "vredmaxu.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vredmaxu_vs, rv_op_vredmaxu_vs, 0 },
- { "vredmax.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vredmax_vs, rv_op_vredmax_vs, 0 },
- { "vwredsumu.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vwredsumu_vs, rv_op_vwredsumu_vs, 0 },
- { "vwredsum.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vwredsum_vs, rv_op_vwredsum_vs, 0 },
- { "vfredusum.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vfredusum_vs, rv_op_vfredusum_vs, 0 },
- { "vfredosum.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vfredosum_vs, rv_op_vfredosum_vs, 0 },
- { "vfredmin.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vfredmin_vs, rv_op_vfredmin_vs, 0 },
- { "vfredmax.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vfredmax_vs, rv_op_vfredmax_vs, 0 },
- { "vfwredusum.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vfwredusum_vs, rv_op_vfwredusum_vs, 0 },
- { "vfwredosum.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vfwredosum_vs, rv_op_vfwredosum_vs, 0 },
- { "vmand.mm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vmand_mm, rv_op_vmand_mm, 0 },
- { "vmnand.mm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vmnand_mm, rv_op_vmnand_mm, 0 },
- { "vmandn.mm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vmandn_mm, rv_op_vmandn_mm, 0 },
- { "vmxor.mm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vmxor_mm, rv_op_vmxor_mm, 0 },
- { "vmor.mm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vmor_mm, rv_op_vmor_mm, 0 },
- { "vmnor.mm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vmnor_mm, rv_op_vmnor_mm, 0 },
- { "vmorn.mm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vmorn_mm, rv_op_vmorn_mm, 0 },
- { "vmxnor.mm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vmxnor_mm, rv_op_vmxnor_mm, 0 },
- { "vcpop.m", rv_codec_v_r, rv_fmt_rd_vs2_vm, NULL, rv_op_vcpop_m, rv_op_vcpop_m, 0 },
- { "vfirst.m", rv_codec_v_r, rv_fmt_rd_vs2_vm, NULL, rv_op_vfirst_m, rv_op_vfirst_m, 0 },
- { "vmsbf.m", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vmsbf_m, rv_op_vmsbf_m, 0 },
- { "vmsif.m", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vmsif_m, rv_op_vmsif_m, 0 },
- { "vmsof.m", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vmsof_m, rv_op_vmsof_m, 0 },
- { "viota.m", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_viota_m, rv_op_viota_m, 0 },
- { "vid.v", rv_codec_v_r, rv_fmt_vd_vm, NULL, rv_op_vid_v, rv_op_vid_v, 0 },
- { "vmv.x.s", rv_codec_v_r, rv_fmt_rd_vs2, NULL, rv_op_vmv_x_s, rv_op_vmv_x_s, 0 },
- { "vmv.s.x", rv_codec_v_r, rv_fmt_vd_rs1, NULL, rv_op_vmv_s_x, rv_op_vmv_s_x, 0 },
- { "vfmv.f.s", rv_codec_v_r, rv_fmt_fd_vs2, NULL, rv_op_vfmv_f_s, rv_op_vfmv_f_s, 0 },
- { "vfmv.s.f", rv_codec_v_r, rv_fmt_vd_fs1, NULL, rv_op_vfmv_s_f, rv_op_vfmv_s_f, 0 },
- { "vslideup.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vslideup_vx, rv_op_vslideup_vx, 0 },
- { "vslideup.vi", rv_codec_v_i, rv_fmt_vd_vs2_uimm_vm, NULL, rv_op_vslideup_vi, rv_op_vslideup_vi, 0 },
- { "vslide1up.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vslide1up_vx, rv_op_vslide1up_vx, 0 },
- { "vslidedown.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vslidedown_vx, rv_op_vslidedown_vx, 0 },
- { "vslidedown.vi", rv_codec_v_i, rv_fmt_vd_vs2_uimm_vm, NULL, rv_op_vslidedown_vi, rv_op_vslidedown_vi, 0 },
- { "vslide1down.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vslide1down_vx, rv_op_vslide1down_vx, 0 },
- { "vrgather.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vrgather_vv, rv_op_vrgather_vv, 0 },
- { "vrgatherei16.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, rv_op_vrgatherei16_vv, rv_op_vrgatherei16_vv, 0 },
- { "vrgather.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, rv_op_vrgather_vx, rv_op_vrgather_vx, 0 },
- { "vrgather.vi", rv_codec_v_i, rv_fmt_vd_vs2_uimm_vm, NULL, rv_op_vrgather_vi, rv_op_vrgather_vi, 0 },
- { "vcompress.vm", rv_codec_v_r, rv_fmt_vd_vs2_vs1, NULL, rv_op_vcompress_vm, rv_op_vcompress_vm, 0 },
- { "vmv1r.v", rv_codec_v_r, rv_fmt_vd_vs2, NULL, rv_op_vmv1r_v, rv_op_vmv1r_v, 0 },
- { "vmv2r.v", rv_codec_v_r, rv_fmt_vd_vs2, NULL, rv_op_vmv2r_v, rv_op_vmv2r_v, 0 },
- { "vmv4r.v", rv_codec_v_r, rv_fmt_vd_vs2, NULL, rv_op_vmv4r_v, rv_op_vmv4r_v, 0 },
- { "vmv8r.v", rv_codec_v_r, rv_fmt_vd_vs2, NULL, rv_op_vmv8r_v, rv_op_vmv8r_v, 0 },
- { "vzext.vf2", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vzext_vf2, rv_op_vzext_vf2, 0 },
- { "vzext.vf4", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vzext_vf4, rv_op_vzext_vf4, 0 },
- { "vzext.vf8", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vzext_vf8, rv_op_vzext_vf8, 0 },
- { "vsext.vf2", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vsext_vf2, rv_op_vsext_vf2, 0 },
- { "vsext.vf4", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vsext_vf4, rv_op_vsext_vf4, 0 },
- { "vsext.vf8", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vsext_vf8, rv_op_vsext_vf8, 0 },
- { "vsetvli", rv_codec_vsetvli, rv_fmt_vsetvli, NULL, rv_op_vsetvli, rv_op_vsetvli, 0 },
- { "vsetivli", rv_codec_vsetivli, rv_fmt_vsetivli, NULL, rv_op_vsetivli, rv_op_vsetivli, 0 },
- { "vsetvl", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, rv_op_vsetvl, rv_op_vsetvl, 0 },
+ { "vle8.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 },
+ { "vle16.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 },
+ { "vle32.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 },
+ { "vle64.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 },
+ { "vse8.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 },
+ { "vse16.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 },
+ { "vse32.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 },
+ { "vse64.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 },
+ { "vlm.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 },
+ { "vsm.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 },
+ { "vlse8.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_rs2_vm, NULL, 0, 0, 0 },
+ { "vlse16.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_rs2_vm, NULL, 0, 0, 0 },
+ { "vlse32.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_rs2_vm, NULL, 0, 0, 0 },
+ { "vlse64.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_rs2_vm, NULL, 0, 0, 0 },
+ { "vsse8.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_rs2_vm, NULL, 0, 0, 0 },
+ { "vsse16.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_rs2_vm, NULL, 0, 0, 0 },
+ { "vsse32.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_rs2_vm, NULL, 0, 0, 0 },
+ { "vsse64.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_rs2_vm, NULL, 0, 0, 0 },
+ { "vluxei8.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vluxei16.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vluxei32.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vluxei64.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vloxei8.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vloxei16.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vloxei32.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vloxei64.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vsuxei8.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vsuxei16.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vsuxei32.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vsuxei64.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vsoxei8.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vsoxei16.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vsoxei32.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vsoxei64.v", rv_codec_v_r, rv_fmt_ldst_vd_rs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vle8ff.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 },
+ { "vle16ff.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 },
+ { "vle32ff.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 },
+ { "vle64ff.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 },
+ { "vl1re8.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 },
+ { "vl1re16.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 },
+ { "vl1re32.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 },
+ { "vl1re64.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 },
+ { "vl2re8.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 },
+ { "vl2re16.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 },
+ { "vl2re32.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 },
+ { "vl2re64.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 },
+ { "vl4re8.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 },
+ { "vl4re16.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 },
+ { "vl4re32.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 },
+ { "vl4re64.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 },
+ { "vl8re8.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 },
+ { "vl8re16.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 },
+ { "vl8re32.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 },
+ { "vl8re64.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 },
+ { "vs1r.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 },
+ { "vs2r.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 },
+ { "vs4r.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 },
+ { "vs8r.v", rv_codec_v_ldst, rv_fmt_ldst_vd_rs1_vm, NULL, 0, 0, 0 },
+ { "vadd.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vadd.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vadd.vi", rv_codec_v_i, rv_fmt_vd_vs2_imm_vm, NULL, 0, 0, 0 },
+ { "vsub.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vsub.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vrsub.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vrsub.vi", rv_codec_v_i, rv_fmt_vd_vs2_imm_vm, NULL, 0, 0, 0 },
+ { "vwaddu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vwaddu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vwadd.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vwadd.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vwsubu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vwsubu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vwsub.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vwsub.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vwaddu.wv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vwaddu.wx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vwadd.wv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vwadd.wx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vwsubu.wv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vwsubu.wx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vwsub.wv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vwsub.wx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vadc.vvm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vl, NULL, 0, 0, 0 },
+ { "vadc.vxm", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vl, NULL, 0, 0, 0 },
+ { "vadc.vim", rv_codec_v_i, rv_fmt_vd_vs2_imm_vl, NULL, 0, 0, 0 },
+ { "vmadc.vvm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vl, NULL, 0, 0, 0 },
+ { "vmadc.vxm", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vl, NULL, 0, 0, 0 },
+ { "vmadc.vim", rv_codec_v_i, rv_fmt_vd_vs2_imm_vl, NULL, 0, 0, 0 },
+ { "vsbc.vvm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vl, NULL, 0, 0, 0 },
+ { "vsbc.vxm", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vl, NULL, 0, 0, 0 },
+ { "vmsbc.vvm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vl, NULL, 0, 0, 0 },
+ { "vmsbc.vxm", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vl, NULL, 0, 0, 0 },
+ { "vand.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vand.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vand.vi", rv_codec_v_i, rv_fmt_vd_vs2_imm_vm, NULL, 0, 0, 0 },
+ { "vor.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vor.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vor.vi", rv_codec_v_i, rv_fmt_vd_vs2_imm_vm, NULL, 0, 0, 0 },
+ { "vxor.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vxor.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vxor.vi", rv_codec_v_i, rv_fmt_vd_vs2_imm_vm, NULL, 0, 0, 0 },
+ { "vsll.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vsll.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vsll.vi", rv_codec_v_i, rv_fmt_vd_vs2_uimm_vm, NULL, 0, 0, 0 },
+ { "vsrl.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vsrl.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vsrl.vi", rv_codec_v_i, rv_fmt_vd_vs2_uimm_vm, NULL, 0, 0, 0 },
+ { "vsra.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vsra.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vsra.vi", rv_codec_v_i, rv_fmt_vd_vs2_uimm_vm, NULL, 0, 0, 0 },
+ { "vnsrl.wv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vnsrl.wx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vnsrl.wi", rv_codec_v_i, rv_fmt_vd_vs2_uimm_vm, NULL, 0, 0, 0 },
+ { "vnsra.wv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vnsra.wx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vnsra.wi", rv_codec_v_i, rv_fmt_vd_vs2_uimm_vm, NULL, 0, 0, 0 },
+ { "vmseq.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vmseq.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vmseq.vi", rv_codec_v_i, rv_fmt_vd_vs2_imm_vm, NULL, 0, 0, 0 },
+ { "vmsne.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vmsne.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vmsne.vi", rv_codec_v_i, rv_fmt_vd_vs2_imm_vm, NULL, 0, 0, 0 },
+ { "vmsltu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vmsltu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vmslt.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vmslt.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vmsleu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vmsleu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vmsleu.vi", rv_codec_v_i, rv_fmt_vd_vs2_imm_vm, NULL, 0, 0, 0 },
+ { "vmsle.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vmsle.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vmsle.vi", rv_codec_v_i, rv_fmt_vd_vs2_imm_vm, NULL, 0, 0, 0 },
+ { "vmsgtu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vmsgtu.vi", rv_codec_v_i, rv_fmt_vd_vs2_imm_vm, NULL, 0, 0, 0 },
+ { "vmsgt.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vmsgt.vi", rv_codec_v_i, rv_fmt_vd_vs2_imm_vm, NULL, 0, 0, 0 },
+ { "vminu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vminu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vmin.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vmin.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vmaxu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vmaxu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vmax.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vmax.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vmul.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vmul.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vmulh.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vmulh.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vmulhu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vmulhu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vmulhsu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vmulhsu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vdivu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vdivu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vdiv.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vdiv.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vremu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vremu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vrem.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vrem.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vwmulu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vwmulu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vwmulsu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vwmulsu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vwmul.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vwmul.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vmacc.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vmacc.vx", rv_codec_v_r, rv_fmt_vd_rs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vnmsac.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vnmsac.vx", rv_codec_v_r, rv_fmt_vd_rs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vmadd.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vmadd.vx", rv_codec_v_r, rv_fmt_vd_rs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vnmsub.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vnmsub.vx", rv_codec_v_r, rv_fmt_vd_rs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vwmaccu.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vwmaccu.vx", rv_codec_v_r, rv_fmt_vd_rs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vwmacc.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vwmacc.vx", rv_codec_v_r, rv_fmt_vd_rs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vwmaccsu.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vwmaccsu.vx", rv_codec_v_r, rv_fmt_vd_rs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vwmaccus.vx", rv_codec_v_r, rv_fmt_vd_rs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vmv.v.v", rv_codec_v_r, rv_fmt_vd_vs1, NULL, 0, 0, 0 },
+ { "vmv.v.x", rv_codec_v_r, rv_fmt_vd_rs1, NULL, 0, 0, 0 },
+ { "vmv.v.i", rv_codec_v_i, rv_fmt_vd_imm, NULL, 0, 0, 0 },
+ { "vmerge.vvm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vl, NULL, 0, 0, 0 },
+ { "vmerge.vxm", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vl, NULL, 0, 0, 0 },
+ { "vmerge.vim", rv_codec_v_i, rv_fmt_vd_vs2_imm_vl, NULL, 0, 0, 0 },
+ { "vsaddu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vsaddu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vsaddu.vi", rv_codec_v_i, rv_fmt_vd_vs2_imm_vm, NULL, 0, 0, 0 },
+ { "vsadd.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vsadd.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vsadd.vi", rv_codec_v_i, rv_fmt_vd_vs2_imm_vm, NULL, 0, 0, 0 },
+ { "vssubu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vssubu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vssub.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vssub.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vaadd.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vaadd.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vaaddu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vaaddu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vasub.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vasub.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vasubu.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vasubu.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vsmul.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vsmul.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vssrl.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vssrl.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vssrl.vi", rv_codec_v_i, rv_fmt_vd_vs2_uimm_vm, NULL, 0, 0, 0 },
+ { "vssra.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vssra.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vssra.vi", rv_codec_v_i, rv_fmt_vd_vs2_uimm_vm, NULL, 0, 0, 0 },
+ { "vnclipu.wv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vnclipu.wx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vnclipu.wi", rv_codec_v_i, rv_fmt_vd_vs2_uimm_vm, NULL, 0, 0, 0 },
+ { "vnclip.wv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vnclip.wx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vnclip.wi", rv_codec_v_i, rv_fmt_vd_vs2_uimm_vm, NULL, 0, 0, 0 },
+ { "vfadd.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vfadd.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, 0, 0, 0 },
+ { "vfsub.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vfsub.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, 0, 0, 0 },
+ { "vfrsub.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, 0, 0, 0 },
+ { "vfwadd.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vfwadd.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, 0, 0, 0 },
+ { "vfwadd.wv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vfwadd.wf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, 0, 0, 0 },
+ { "vfwsub.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vfwsub.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, 0, 0, 0 },
+ { "vfwsub.wv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vfwsub.wf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, 0, 0, 0 },
+ { "vfmul.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vfmul.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, 0, 0, 0 },
+ { "vfdiv.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vfdiv.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, 0, 0, 0 },
+ { "vfrdiv.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, 0, 0, 0 },
+ { "vfwmul.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vfwmul.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, 0, 0, 0 },
+ { "vfmacc.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vfmacc.vf", rv_codec_v_r, rv_fmt_vd_fs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vfnmacc.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vfnmacc.vf", rv_codec_v_r, rv_fmt_vd_fs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vfmsac.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vfmsac.vf", rv_codec_v_r, rv_fmt_vd_fs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vfnmsac.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vfnmsac.vf", rv_codec_v_r, rv_fmt_vd_fs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vfmadd.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vfmadd.vf", rv_codec_v_r, rv_fmt_vd_fs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vfnmadd.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vfnmadd.vf", rv_codec_v_r, rv_fmt_vd_fs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vfmsub.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vfmsub.vf", rv_codec_v_r, rv_fmt_vd_fs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vfnmsub.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vfnmsub.vf", rv_codec_v_r, rv_fmt_vd_fs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vfwmacc.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vfwmacc.vf", rv_codec_v_r, rv_fmt_vd_fs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vfwnmacc.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vfwnmacc.vf", rv_codec_v_r, rv_fmt_vd_fs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vfwmsac.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vfwmsac.vf", rv_codec_v_r, rv_fmt_vd_fs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vfwnmsac.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vfwnmsac.vf", rv_codec_v_r, rv_fmt_vd_fs1_vs2_vm, NULL, 0, 0, 0 },
+ { "vfsqrt.v", rv_codec_v_r, rv_fmt_vd_vs2, NULL, 0, 0, 0 },
+ { "vfrsqrt7.v", rv_codec_v_r, rv_fmt_vd_vs2, NULL, 0, 0, 0 },
+ { "vfrec7.v", rv_codec_v_r, rv_fmt_vd_vs2, NULL, 0, 0, 0 },
+ { "vfmin.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vfmin.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, 0, 0, 0 },
+ { "vfmax.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vfmax.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, 0, 0, 0 },
+ { "vfsgnj.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vfsgnj.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, 0, 0, 0 },
+ { "vfsgnjn.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vfsgnjn.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, 0, 0, 0 },
+ { "vfsgnjx.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vfsgnjx.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, 0, 0, 0 },
+ { "vfslide1up.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, 0, 0, 0 },
+ { "vfslide1down.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, 0, 0, 0 },
+ { "vmfeq.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vmfeq.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, 0, 0, 0 },
+ { "vmfne.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vmfne.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, 0, 0, 0 },
+ { "vmflt.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vmflt.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, 0, 0, 0 },
+ { "vmfle.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vmfle.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, 0, 0, 0 },
+ { "vmfgt.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, 0, 0, 0 },
+ { "vmfge.vf", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vm, NULL, 0, 0, 0 },
+ { "vfclass.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 },
+ { "vfmerge.vfm", rv_codec_v_r, rv_fmt_vd_vs2_fs1_vl, NULL, 0, 0, 0 },
+ { "vfmv.v.f", rv_codec_v_r, rv_fmt_vd_fs1, NULL, 0, 0, 0 },
+ { "vfcvt.xu.f.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 },
+ { "vfcvt.x.f.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 },
+ { "vfcvt.f.xu.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 },
+ { "vfcvt.f.x.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 },
+ { "vfcvt.rtz.xu.f.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 },
+ { "vfcvt.rtz.x.f.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 },
+ { "vfwcvt.xu.f.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 },
+ { "vfwcvt.x.f.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 },
+ { "vfwcvt.f.xu.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 },
+ { "vfwcvt.f.x.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 },
+ { "vfwcvt.f.f.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 },
+ { "vfwcvt.rtz.xu.f.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 },
+ { "vfwcvt.rtz.x.f.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 },
+ { "vfncvt.xu.f.w", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 },
+ { "vfncvt.x.f.w", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 },
+ { "vfncvt.f.xu.w", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 },
+ { "vfncvt.f.x.w", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 },
+ { "vfncvt.f.f.w", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 },
+ { "vfncvt.rod.f.f.w", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 },
+ { "vfncvt.rtz.xu.f.w", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 },
+ { "vfncvt.rtz.x.f.w", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 },
+ { "vredsum.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vredand.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vredor.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vredxor.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vredminu.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vredmin.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vredmaxu.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vredmax.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vwredsumu.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vwredsum.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vfredusum.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vfredosum.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vfredmin.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vfredmax.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vfwredusum.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vfwredosum.vs", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vmand.mm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vmnand.mm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vmandn.mm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vmxor.mm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vmor.mm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vmnor.mm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vmorn.mm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vmxnor.mm", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vcpop.m", rv_codec_v_r, rv_fmt_rd_vs2_vm, NULL, 0, 0, 0 },
+ { "vfirst.m", rv_codec_v_r, rv_fmt_rd_vs2_vm, NULL, 0, 0, 0 },
+ { "vmsbf.m", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 },
+ { "vmsif.m", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 },
+ { "vmsof.m", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 },
+ { "viota.m", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 },
+ { "vid.v", rv_codec_v_r, rv_fmt_vd_vm, NULL, 0, 0, 0 },
+ { "vmv.x.s", rv_codec_v_r, rv_fmt_rd_vs2, NULL, 0, 0, 0 },
+ { "vmv.s.x", rv_codec_v_r, rv_fmt_vd_rs1, NULL, 0, 0, 0 },
+ { "vfmv.f.s", rv_codec_v_r, rv_fmt_fd_vs2, NULL, 0, 0, 0 },
+ { "vfmv.s.f", rv_codec_v_r, rv_fmt_vd_fs1, NULL, 0, 0, 0 },
+ { "vslideup.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vslideup.vi", rv_codec_v_i, rv_fmt_vd_vs2_uimm_vm, NULL, 0, 0, 0 },
+ { "vslide1up.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vslidedown.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vslidedown.vi", rv_codec_v_i, rv_fmt_vd_vs2_uimm_vm, NULL, 0, 0, 0 },
+ { "vslide1down.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vrgather.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vrgatherei16.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 },
+ { "vrgather.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 },
+ { "vrgather.vi", rv_codec_v_i, rv_fmt_vd_vs2_uimm_vm, NULL, 0, 0, 0 },
+ { "vcompress.vm", rv_codec_v_r, rv_fmt_vd_vs2_vs1, NULL, 0, 0, 0 },
+ { "vmv1r.v", rv_codec_v_r, rv_fmt_vd_vs2, NULL, 0, 0, 0 },
+ { "vmv2r.v", rv_codec_v_r, rv_fmt_vd_vs2, NULL, 0, 0, 0 },
+ { "vmv4r.v", rv_codec_v_r, rv_fmt_vd_vs2, NULL, 0, 0, 0 },
+ { "vmv8r.v", rv_codec_v_r, rv_fmt_vd_vs2, NULL, 0, 0, 0 },
+ { "vzext.vf2", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 },
+ { "vzext.vf4", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 },
+ { "vzext.vf8", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 },
+ { "vsext.vf2", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 },
+ { "vsext.vf4", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 },
+ { "vsext.vf8", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 },
+ { "vsetvli", rv_codec_vsetvli, rv_fmt_vsetvli, NULL, 0, 0, 0 },
+ { "vsetivli", rv_codec_vsetivli, rv_fmt_vsetivli, NULL, 0, 0, 0 },
+ { "vsetvl", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
{ "c.zext.b", rv_codec_zcb_ext, rv_fmt_rd, NULL, 0 },
{ "c.sext.b", rv_codec_zcb_ext, rv_fmt_rd, NULL, 0 },
{ "c.zext.h", rv_codec_zcb_ext, rv_fmt_rd, NULL, 0 },
@@ -2345,9 +2390,9 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
{
rv_inst inst = dec->inst;
rv_opcode op = rv_op_illegal;
- switch (((inst >> 0) & 0b11)) {
+ switch ((inst >> 0) & 0b11) {
case 0:
- switch (((inst >> 13) & 0b111)) {
+ switch ((inst >> 13) & 0b111) {
case 0: op = rv_op_c_addi4spn; break;
case 1:
if (isa == rv128) {
@@ -2400,9 +2445,9 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
}
break;
case 1:
- switch (((inst >> 13) & 0b111)) {
+ switch ((inst >> 13) & 0b111) {
case 0:
- switch (((inst >> 2) & 0b11111111111)) {
+ switch ((inst >> 2) & 0b11111111111) {
case 0: op = rv_op_c_nop; break;
default: op = rv_op_c_addi; break;
}
@@ -2416,13 +2461,13 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
break;
case 2: op = rv_op_c_li; break;
case 3:
- switch (((inst >> 7) & 0b11111)) {
+ switch ((inst >> 7) & 0b11111) {
case 2: op = rv_op_c_addi16sp; break;
default: op = rv_op_c_lui; break;
}
break;
case 4:
- switch (((inst >> 10) & 0b11)) {
+ switch ((inst >> 10) & 0b11) {
case 0:
op = rv_op_c_srli;
break;
@@ -2459,7 +2504,7 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
}
break;
case 2:
- switch (((inst >> 13) & 0b111)) {
+ switch ((inst >> 13) & 0b111) {
case 0:
op = rv_op_c_slli;
break;
@@ -2479,17 +2524,17 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
}
break;
case 4:
- switch (((inst >> 12) & 0b1)) {
+ switch ((inst >> 12) & 0b1) {
case 0:
- switch (((inst >> 2) & 0b11111)) {
+ switch ((inst >> 2) & 0b11111) {
case 0: op = rv_op_c_jr; break;
default: op = rv_op_c_mv; break;
}
break;
case 1:
- switch (((inst >> 2) & 0b11111)) {
+ switch ((inst >> 2) & 0b11111) {
case 0:
- switch (((inst >> 7) & 0b11111)) {
+ switch ((inst >> 7) & 0b11111) {
case 0: op = rv_op_c_ebreak; break;
default: op = rv_op_c_jalr; break;
}
@@ -2504,7 +2549,7 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
op = rv_op_c_sqsp;
} else {
op = rv_op_c_fsdsp;
- if (((inst >> 12) & 0b01)) {
+ if (dec->cfg->ext_zcmp && ((inst >> 12) & 0b01)) {
switch ((inst >> 8) & 0b01111) {
case 8:
if (((inst >> 4) & 0b01111) >= 4) {
@@ -2530,6 +2575,9 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
} else {
switch ((inst >> 10) & 0b011) {
case 0:
+ if (!dec->cfg->ext_zcmt) {
+ break;
+ }
if (((inst >> 2) & 0xFF) >= 32) {
op = rv_op_cm_jalt;
} else {
@@ -2537,6 +2585,9 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
}
break;
case 3:
+ if (!dec->cfg->ext_zcmp) {
+ break;
+ }
switch ((inst >> 5) & 0b011) {
case 1: op = rv_op_cm_mvsa01; break;
case 3: op = rv_op_cm_mva01s; break;
@@ -2557,9 +2608,9 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
}
break;
case 3:
- switch (((inst >> 2) & 0b11111)) {
+ switch ((inst >> 2) & 0b11111) {
case 0:
- switch (((inst >> 12) & 0b111)) {
+ switch ((inst >> 12) & 0b111) {
case 0: op = rv_op_lb; break;
case 1: op = rv_op_lh; break;
case 2: op = rv_op_lw; break;
@@ -2571,17 +2622,17 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
}
break;
case 1:
- switch (((inst >> 12) & 0b111)) {
+ switch ((inst >> 12) & 0b111) {
case 0:
- switch (((inst >> 20) & 0b111111111111)) {
+ switch ((inst >> 20) & 0b111111111111) {
case 40: op = rv_op_vl1re8_v; break;
case 552: op = rv_op_vl2re8_v; break;
case 1576: op = rv_op_vl4re8_v; break;
case 3624: op = rv_op_vl8re8_v; break;
}
- switch (((inst >> 26) & 0b111)) {
+ switch ((inst >> 26) & 0b111) {
case 0:
- switch (((inst >> 20) & 0b11111)) {
+ switch ((inst >> 20) & 0b11111) {
case 0: op = rv_op_vle8_v; break;
case 11: op = rv_op_vlm_v; break;
case 16: op = rv_op_vle8ff_v; break;
@@ -2596,15 +2647,15 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
case 3: op = rv_op_fld; break;
case 4: op = rv_op_flq; break;
case 5:
- switch (((inst >> 20) & 0b111111111111)) {
+ switch ((inst >> 20) & 0b111111111111) {
case 40: op = rv_op_vl1re16_v; break;
case 552: op = rv_op_vl2re16_v; break;
case 1576: op = rv_op_vl4re16_v; break;
case 3624: op = rv_op_vl8re16_v; break;
}
- switch (((inst >> 26) & 0b111)) {
+ switch ((inst >> 26) & 0b111) {
case 0:
- switch (((inst >> 20) & 0b11111)) {
+ switch ((inst >> 20) & 0b11111) {
case 0: op = rv_op_vle16_v; break;
case 16: op = rv_op_vle16ff_v; break;
}
@@ -2615,15 +2666,15 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
}
break;
case 6:
- switch (((inst >> 20) & 0b111111111111)) {
+ switch ((inst >> 20) & 0b111111111111) {
case 40: op = rv_op_vl1re32_v; break;
case 552: op = rv_op_vl2re32_v; break;
case 1576: op = rv_op_vl4re32_v; break;
case 3624: op = rv_op_vl8re32_v; break;
}
- switch (((inst >> 26) & 0b111)) {
+ switch ((inst >> 26) & 0b111) {
case 0:
- switch (((inst >> 20) & 0b11111)) {
+ switch ((inst >> 20) & 0b11111) {
case 0: op = rv_op_vle32_v; break;
case 16: op = rv_op_vle32ff_v; break;
}
@@ -2634,15 +2685,15 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
}
break;
case 7:
- switch (((inst >> 20) & 0b111111111111)) {
+ switch ((inst >> 20) & 0b111111111111) {
case 40: op = rv_op_vl1re64_v; break;
case 552: op = rv_op_vl2re64_v; break;
case 1576: op = rv_op_vl4re64_v; break;
case 3624: op = rv_op_vl8re64_v; break;
}
- switch (((inst >> 26) & 0b111)) {
+ switch ((inst >> 26) & 0b111) {
case 0:
- switch (((inst >> 20) & 0b11111)) {
+ switch ((inst >> 20) & 0b11111) {
case 0: op = rv_op_vle64_v; break;
case 16: op = rv_op_vle64ff_v; break;
}
@@ -2655,25 +2706,25 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
}
break;
case 3:
- switch (((inst >> 12) & 0b111)) {
+ switch ((inst >> 12) & 0b111) {
case 0: op = rv_op_fence; break;
case 1: op = rv_op_fence_i; break;
case 2: op = rv_op_lq; break;
}
break;
case 4:
- switch (((inst >> 12) & 0b111)) {
+ switch ((inst >> 12) & 0b111) {
case 0: op = rv_op_addi; break;
case 1:
- switch (((inst >> 27) & 0b11111)) {
+ switch ((inst >> 27) & 0b11111) {
case 0b00000: op = rv_op_slli; break;
case 0b00001:
- switch (((inst >> 20) & 0b1111111)) {
+ switch ((inst >> 20) & 0b1111111) {
case 0b0001111: op = rv_op_zip; break;
}
break;
case 0b00010:
- switch (((inst >> 20) & 0b1111111)) {
+ switch ((inst >> 20) & 0b1111111) {
case 0b0000000: op = rv_op_sha256sum0; break;
case 0b0000001: op = rv_op_sha256sum1; break;
case 0b0000010: op = rv_op_sha256sig0; break;
@@ -2688,7 +2739,7 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
break;
case 0b00101: op = rv_op_bseti; break;
case 0b00110:
- switch (((inst >> 20) & 0b1111111)) {
+ switch ((inst >> 20) & 0b1111111) {
case 0b0000000: op = rv_op_aes64im; break;
default:
if (((inst >> 24) & 0b0111) == 0b001) {
@@ -2700,7 +2751,7 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
case 0b01001: op = rv_op_bclri; break;
case 0b01101: op = rv_op_binvi; break;
case 0b01100:
- switch (((inst >> 20) & 0b1111111)) {
+ switch ((inst >> 20) & 0b1111111) {
case 0b0000000: op = rv_op_clz; break;
case 0b0000001: op = rv_op_ctz; break;
case 0b0000010: op = rv_op_cpop; break;
@@ -2715,10 +2766,10 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
case 3: op = rv_op_sltiu; break;
case 4: op = rv_op_xori; break;
case 5:
- switch (((inst >> 27) & 0b11111)) {
+ switch ((inst >> 27) & 0b11111) {
case 0b00000: op = rv_op_srli; break;
case 0b00001:
- switch (((inst >> 20) & 0b1111111)) {
+ switch ((inst >> 20) & 0b1111111) {
case 0b0001111: op = rv_op_unzip; break;
}
break;
@@ -2741,10 +2792,10 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
break;
case 5: op = rv_op_auipc; break;
case 6:
- switch (((inst >> 12) & 0b111)) {
+ switch ((inst >> 12) & 0b111) {
case 0: op = rv_op_addiw; break;
case 1:
- switch (((inst >> 26) & 0b111111)) {
+ switch ((inst >> 26) & 0b111111) {
case 0: op = rv_op_slliw; break;
case 2: op = rv_op_slli_uw; break;
case 24:
@@ -2757,7 +2808,7 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
}
break;
case 5:
- switch (((inst >> 25) & 0b1111111)) {
+ switch ((inst >> 25) & 0b1111111) {
case 0: op = rv_op_srliw; break;
case 32: op = rv_op_sraiw; break;
case 48: op = rv_op_roriw; break;
@@ -2766,7 +2817,7 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
}
break;
case 8:
- switch (((inst >> 12) & 0b111)) {
+ switch ((inst >> 12) & 0b111) {
case 0: op = rv_op_sb; break;
case 1: op = rv_op_sh; break;
case 2: op = rv_op_sw; break;
@@ -2775,17 +2826,17 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
}
break;
case 9:
- switch (((inst >> 12) & 0b111)) {
+ switch ((inst >> 12) & 0b111) {
case 0:
- switch (((inst >> 20) & 0b111111111111)) {
+ switch ((inst >> 20) & 0b111111111111) {
case 40: op = rv_op_vs1r_v; break;
case 552: op = rv_op_vs2r_v; break;
case 1576: op = rv_op_vs4r_v; break;
case 3624: op = rv_op_vs8r_v; break;
}
- switch (((inst >> 26) & 0b111)) {
+ switch ((inst >> 26) & 0b111) {
case 0:
- switch (((inst >> 20) & 0b11111)) {
+ switch ((inst >> 20) & 0b11111) {
case 0: op = rv_op_vse8_v; break;
case 11: op = rv_op_vsm_v; break;
}
@@ -2799,9 +2850,9 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
case 3: op = rv_op_fsd; break;
case 4: op = rv_op_fsq; break;
case 5:
- switch (((inst >> 26) & 0b111)) {
+ switch ((inst >> 26) & 0b111) {
case 0:
- switch (((inst >> 20) & 0b11111)) {
+ switch ((inst >> 20) & 0b11111) {
case 0: op = rv_op_vse16_v; break;
}
break;
@@ -2811,9 +2862,9 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
}
break;
case 6:
- switch (((inst >> 26) & 0b111)) {
+ switch ((inst >> 26) & 0b111) {
case 0:
- switch (((inst >> 20) & 0b11111)) {
+ switch ((inst >> 20) & 0b11111) {
case 0: op = rv_op_vse32_v; break;
}
break;
@@ -2823,9 +2874,9 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
}
break;
case 7:
- switch (((inst >> 26) & 0b111)) {
+ switch ((inst >> 26) & 0b111) {
case 0:
- switch (((inst >> 20) & 0b11111)) {
+ switch ((inst >> 20) & 0b11111) {
case 0: op = rv_op_vse64_v; break;
}
break;
@@ -2837,7 +2888,8 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
}
break;
case 11:
- switch (((inst >> 24) & 0b11111000) | ((inst >> 12) & 0b00000111)) {
+ switch (((inst >> 24) & 0b11111000) |
+ ((inst >> 12) & 0b00000111)) {
case 2: op = rv_op_amoadd_w; break;
case 3: op = rv_op_amoadd_d; break;
case 4: op = rv_op_amoadd_q; break;
@@ -2845,17 +2897,17 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
case 11: op = rv_op_amoswap_d; break;
case 12: op = rv_op_amoswap_q; break;
case 18:
- switch (((inst >> 20) & 0b11111)) {
+ switch ((inst >> 20) & 0b11111) {
case 0: op = rv_op_lr_w; break;
}
break;
case 19:
- switch (((inst >> 20) & 0b11111)) {
+ switch ((inst >> 20) & 0b11111) {
case 0: op = rv_op_lr_d; break;
}
break;
case 20:
- switch (((inst >> 20) & 0b11111)) {
+ switch ((inst >> 20) & 0b11111) {
case 0: op = rv_op_lr_q; break;
}
break;
@@ -2886,7 +2938,8 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
}
break;
case 12:
- switch (((inst >> 22) & 0b1111111000) | ((inst >> 12) & 0b0000000111)) {
+ switch (((inst >> 22) & 0b1111111000) |
+ ((inst >> 12) & 0b0000000111)) {
case 0: op = rv_op_add; break;
case 1: op = rv_op_sll; break;
case 2: op = rv_op_slt; break;
@@ -2959,7 +3012,8 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
break;
case 13: op = rv_op_lui; break;
case 14:
- switch (((inst >> 22) & 0b1111111000) | ((inst >> 12) & 0b0000000111)) {
+ switch (((inst >> 22) & 0b1111111000) |
+ ((inst >> 12) & 0b0000000111)) {
case 0: op = rv_op_addw; break;
case 1: op = rv_op_sllw; break;
case 5: op = rv_op_srlw; break;
@@ -2985,35 +3039,35 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
}
break;
case 16:
- switch (((inst >> 25) & 0b11)) {
+ switch ((inst >> 25) & 0b11) {
case 0: op = rv_op_fmadd_s; break;
case 1: op = rv_op_fmadd_d; break;
case 3: op = rv_op_fmadd_q; break;
}
break;
case 17:
- switch (((inst >> 25) & 0b11)) {
+ switch ((inst >> 25) & 0b11) {
case 0: op = rv_op_fmsub_s; break;
case 1: op = rv_op_fmsub_d; break;
case 3: op = rv_op_fmsub_q; break;
}
break;
case 18:
- switch (((inst >> 25) & 0b11)) {
+ switch ((inst >> 25) & 0b11) {
case 0: op = rv_op_fnmsub_s; break;
case 1: op = rv_op_fnmsub_d; break;
case 3: op = rv_op_fnmsub_q; break;
}
break;
case 19:
- switch (((inst >> 25) & 0b11)) {
+ switch ((inst >> 25) & 0b11) {
case 0: op = rv_op_fnmadd_s; break;
case 1: op = rv_op_fnmadd_d; break;
case 3: op = rv_op_fnmadd_q; break;
}
break;
case 20:
- switch (((inst >> 25) & 0b1111111)) {
+ switch ((inst >> 25) & 0b1111111) {
case 0: op = rv_op_fadd_s; break;
case 1: op = rv_op_fadd_d; break;
case 3: op = rv_op_fadd_q; break;
@@ -3027,100 +3081,100 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
case 13: op = rv_op_fdiv_d; break;
case 15: op = rv_op_fdiv_q; break;
case 16:
- switch (((inst >> 12) & 0b111)) {
+ switch ((inst >> 12) & 0b111) {
case 0: op = rv_op_fsgnj_s; break;
case 1: op = rv_op_fsgnjn_s; break;
case 2: op = rv_op_fsgnjx_s; break;
}
break;
case 17:
- switch (((inst >> 12) & 0b111)) {
+ switch ((inst >> 12) & 0b111) {
case 0: op = rv_op_fsgnj_d; break;
case 1: op = rv_op_fsgnjn_d; break;
case 2: op = rv_op_fsgnjx_d; break;
}
break;
case 19:
- switch (((inst >> 12) & 0b111)) {
+ switch ((inst >> 12) & 0b111) {
case 0: op = rv_op_fsgnj_q; break;
case 1: op = rv_op_fsgnjn_q; break;
case 2: op = rv_op_fsgnjx_q; break;
}
break;
case 20:
- switch (((inst >> 12) & 0b111)) {
+ switch ((inst >> 12) & 0b111) {
case 0: op = rv_op_fmin_s; break;
case 1: op = rv_op_fmax_s; break;
}
break;
case 21:
- switch (((inst >> 12) & 0b111)) {
+ switch ((inst >> 12) & 0b111) {
case 0: op = rv_op_fmin_d; break;
case 1: op = rv_op_fmax_d; break;
}
break;
case 23:
- switch (((inst >> 12) & 0b111)) {
+ switch ((inst >> 12) & 0b111) {
case 0: op = rv_op_fmin_q; break;
case 1: op = rv_op_fmax_q; break;
}
break;
case 32:
- switch (((inst >> 20) & 0b11111)) {
+ switch ((inst >> 20) & 0b11111) {
case 1: op = rv_op_fcvt_s_d; break;
case 3: op = rv_op_fcvt_s_q; break;
}
break;
case 33:
- switch (((inst >> 20) & 0b11111)) {
+ switch ((inst >> 20) & 0b11111) {
case 0: op = rv_op_fcvt_d_s; break;
case 3: op = rv_op_fcvt_d_q; break;
}
break;
case 35:
- switch (((inst >> 20) & 0b11111)) {
+ switch ((inst >> 20) & 0b11111) {
case 0: op = rv_op_fcvt_q_s; break;
case 1: op = rv_op_fcvt_q_d; break;
}
break;
case 44:
- switch (((inst >> 20) & 0b11111)) {
+ switch ((inst >> 20) & 0b11111) {
case 0: op = rv_op_fsqrt_s; break;
}
break;
case 45:
- switch (((inst >> 20) & 0b11111)) {
+ switch ((inst >> 20) & 0b11111) {
case 0: op = rv_op_fsqrt_d; break;
}
break;
case 47:
- switch (((inst >> 20) & 0b11111)) {
+ switch ((inst >> 20) & 0b11111) {
case 0: op = rv_op_fsqrt_q; break;
}
break;
case 80:
- switch (((inst >> 12) & 0b111)) {
+ switch ((inst >> 12) & 0b111) {
case 0: op = rv_op_fle_s; break;
case 1: op = rv_op_flt_s; break;
case 2: op = rv_op_feq_s; break;
}
break;
case 81:
- switch (((inst >> 12) & 0b111)) {
+ switch ((inst >> 12) & 0b111) {
case 0: op = rv_op_fle_d; break;
case 1: op = rv_op_flt_d; break;
case 2: op = rv_op_feq_d; break;
}
break;
case 83:
- switch (((inst >> 12) & 0b111)) {
+ switch ((inst >> 12) & 0b111) {
case 0: op = rv_op_fle_q; break;
case 1: op = rv_op_flt_q; break;
case 2: op = rv_op_feq_q; break;
}
break;
case 96:
- switch (((inst >> 20) & 0b11111)) {
+ switch ((inst >> 20) & 0b11111) {
case 0: op = rv_op_fcvt_w_s; break;
case 1: op = rv_op_fcvt_wu_s; break;
case 2: op = rv_op_fcvt_l_s; break;
@@ -3128,7 +3182,7 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
}
break;
case 97:
- switch (((inst >> 20) & 0b11111)) {
+ switch ((inst >> 20) & 0b11111) {
case 0: op = rv_op_fcvt_w_d; break;
case 1: op = rv_op_fcvt_wu_d; break;
case 2: op = rv_op_fcvt_l_d; break;
@@ -3136,7 +3190,7 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
}
break;
case 99:
- switch (((inst >> 20) & 0b11111)) {
+ switch ((inst >> 20) & 0b11111) {
case 0: op = rv_op_fcvt_w_q; break;
case 1: op = rv_op_fcvt_wu_q; break;
case 2: op = rv_op_fcvt_l_q; break;
@@ -3144,7 +3198,7 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
}
break;
case 104:
- switch (((inst >> 20) & 0b11111)) {
+ switch ((inst >> 20) & 0b11111) {
case 0: op = rv_op_fcvt_s_w; break;
case 1: op = rv_op_fcvt_s_wu; break;
case 2: op = rv_op_fcvt_s_l; break;
@@ -3152,7 +3206,7 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
}
break;
case 105:
- switch (((inst >> 20) & 0b11111)) {
+ switch ((inst >> 20) & 0b11111) {
case 0: op = rv_op_fcvt_d_w; break;
case 1: op = rv_op_fcvt_d_wu; break;
case 2: op = rv_op_fcvt_d_l; break;
@@ -3160,7 +3214,7 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
}
break;
case 107:
- switch (((inst >> 20) & 0b11111)) {
+ switch ((inst >> 20) & 0b11111) {
case 0: op = rv_op_fcvt_q_w; break;
case 1: op = rv_op_fcvt_q_wu; break;
case 2: op = rv_op_fcvt_q_l; break;
@@ -3168,44 +3222,50 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
}
break;
case 112:
- switch (((inst >> 17) & 0b11111000) | ((inst >> 12) & 0b00000111)) {
+ switch (((inst >> 17) & 0b11111000) |
+ ((inst >> 12) & 0b00000111)) {
case 0: op = rv_op_fmv_x_s; break;
case 1: op = rv_op_fclass_s; break;
}
break;
case 113:
- switch (((inst >> 17) & 0b11111000) | ((inst >> 12) & 0b00000111)) {
+ switch (((inst >> 17) & 0b11111000) |
+ ((inst >> 12) & 0b00000111)) {
case 0: op = rv_op_fmv_x_d; break;
case 1: op = rv_op_fclass_d; break;
}
break;
case 115:
- switch (((inst >> 17) & 0b11111000) | ((inst >> 12) & 0b00000111)) {
+ switch (((inst >> 17) & 0b11111000) |
+ ((inst >> 12) & 0b00000111)) {
case 0: op = rv_op_fmv_x_q; break;
case 1: op = rv_op_fclass_q; break;
}
break;
case 120:
- switch (((inst >> 17) & 0b11111000) | ((inst >> 12) & 0b00000111)) {
+ switch (((inst >> 17) & 0b11111000) |
+ ((inst >> 12) & 0b00000111)) {
case 0: op = rv_op_fmv_s_x; break;
}
break;
case 121:
- switch (((inst >> 17) & 0b11111000) | ((inst >> 12) & 0b00000111)) {
+ switch (((inst >> 17) & 0b11111000) |
+ ((inst >> 12) & 0b00000111)) {
case 0: op = rv_op_fmv_d_x; break;
}
break;
case 123:
- switch (((inst >> 17) & 0b11111000) | ((inst >> 12) & 0b00000111)) {
+ switch (((inst >> 17) & 0b11111000) |
+ ((inst >> 12) & 0b00000111)) {
case 0: op = rv_op_fmv_q_x; break;
}
break;
}
break;
case 21:
- switch (((inst >> 12) & 0b111)) {
+ switch ((inst >> 12) & 0b111) {
case 0:
- switch (((inst >> 26) & 0b111111)) {
+ switch ((inst >> 26) & 0b111111) {
case 0: op = rv_op_vadd_vv; break;
case 2: op = rv_op_vsub_vv; break;
case 4: op = rv_op_vminu_vv; break;
@@ -3217,9 +3277,17 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
case 11: op = rv_op_vxor_vv; break;
case 12: op = rv_op_vrgather_vv; break;
case 14: op = rv_op_vrgatherei16_vv; break;
- case 16: if (((inst >> 25) & 1) == 0) op = rv_op_vadc_vvm; break;
+ case 16:
+ if (((inst >> 25) & 1) == 0) {
+ op = rv_op_vadc_vvm;
+ }
+ break;
case 17: op = rv_op_vmadc_vvm; break;
- case 18: if (((inst >> 25) & 1) == 0) op = rv_op_vsbc_vvm; break;
+ case 18:
+ if (((inst >> 25) & 1) == 0) {
+ op = rv_op_vsbc_vvm;
+ }
+ break;
case 19: op = rv_op_vmsbc_vvm; break;
case 23:
if (((inst >> 20) & 0b111111) == 32)
@@ -3252,7 +3320,7 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
}
break;
case 1:
- switch (((inst >> 26) & 0b111111)) {
+ switch ((inst >> 26) & 0b111111) {
case 0: op = rv_op_vfadd_vv; break;
case 1: op = rv_op_vfredusum_vs; break;
case 2: op = rv_op_vfsub_vv; break;
@@ -3265,12 +3333,12 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
case 9: op = rv_op_vfsgnjn_vv; break;
case 10: op = rv_op_vfsgnjx_vv; break;
case 16:
- switch (((inst >> 15) & 0b11111)) {
+ switch ((inst >> 15) & 0b11111) {
case 0: if ((inst >> 25) & 1) op = rv_op_vfmv_f_s; break;
}
break;
case 18:
- switch (((inst >> 15) & 0b11111)) {
+ switch ((inst >> 15) & 0b11111) {
case 0: op = rv_op_vfcvt_xu_f_v; break;
case 1: op = rv_op_vfcvt_x_f_v; break;
case 2: op = rv_op_vfcvt_f_xu_v; break;
@@ -3295,7 +3363,7 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
}
break;
case 19:
- switch (((inst >> 15) & 0b11111)) {
+ switch ((inst >> 15) & 0b11111) {
case 0: op = rv_op_vfsqrt_v; break;
case 4: op = rv_op_vfrsqrt7_v; break;
case 5: op = rv_op_vfrec7_v; break;
@@ -3330,7 +3398,7 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
}
break;
case 2:
- switch (((inst >> 26) & 0b111111)) {
+ switch ((inst >> 26) & 0b111111) {
case 0: op = rv_op_vredsum_vs; break;
case 1: op = rv_op_vredand_vs; break;
case 2: op = rv_op_vredor_vs; break;
@@ -3344,14 +3412,14 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
case 10: op = rv_op_vasubu_vv; break;
case 11: op = rv_op_vasub_vv; break;
case 16:
- switch (((inst >> 15) & 0b11111)) {
+ switch ((inst >> 15) & 0b11111) {
case 0: if ((inst >> 25) & 1) op = rv_op_vmv_x_s; break;
case 16: op = rv_op_vcpop_m; break;
case 17: op = rv_op_vfirst_m; break;
}
break;
case 18:
- switch (((inst >> 15) & 0b11111)) {
+ switch ((inst >> 15) & 0b11111) {
case 2: op = rv_op_vzext_vf8; break;
case 3: op = rv_op_vsext_vf8; break;
case 4: op = rv_op_vzext_vf4; break;
@@ -3361,12 +3429,16 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
}
break;
case 20:
- switch (((inst >> 15) & 0b11111)) {
+ switch ((inst >> 15) & 0b11111) {
case 1: op = rv_op_vmsbf_m; break;
case 2: op = rv_op_vmsof_m; break;
case 3: op = rv_op_vmsif_m; break;
case 16: op = rv_op_viota_m; break;
- case 17: if (((inst >> 20) & 0b11111) == 0) op = rv_op_vid_v; break;
+ case 17:
+ if (((inst >> 20) & 0b11111) == 0) {
+ op = rv_op_vid_v;
+ }
+ break;
}
break;
case 23: if ((inst >> 25) & 1) op = rv_op_vcompress_vm; break;
@@ -3407,7 +3479,7 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
}
break;
case 3:
- switch (((inst >> 26) & 0b111111)) {
+ switch ((inst >> 26) & 0b111111) {
case 0: op = rv_op_vadd_vi; break;
case 3: op = rv_op_vrsub_vi; break;
case 9: op = rv_op_vand_vi; break;
@@ -3416,7 +3488,11 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
case 12: op = rv_op_vrgather_vi; break;
case 14: op = rv_op_vslideup_vi; break;
case 15: op = rv_op_vslidedown_vi; break;
- case 16: if (((inst >> 25) & 1) == 0) op = rv_op_vadc_vim; break;
+ case 16:
+ if (((inst >> 25) & 1) == 0) {
+ op = rv_op_vadc_vim;
+ }
+ break;
case 17: op = rv_op_vmadc_vim; break;
case 23:
if (((inst >> 20) & 0b111111) == 32)
@@ -3434,7 +3510,7 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
case 33: op = rv_op_vsadd_vi; break;
case 37: op = rv_op_vsll_vi; break;
case 39:
- switch (((inst >> 15) & 0b11111)) {
+ switch ((inst >> 15) & 0b11111) {
case 0: op = rv_op_vmv1r_v; break;
case 1: op = rv_op_vmv2r_v; break;
case 3: op = rv_op_vmv4r_v; break;
@@ -3452,7 +3528,7 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
}
break;
case 4:
- switch (((inst >> 26) & 0b111111)) {
+ switch ((inst >> 26) & 0b111111) {
case 0: op = rv_op_vadd_vx; break;
case 2: op = rv_op_vsub_vx; break;
case 3: op = rv_op_vrsub_vx; break;
@@ -3466,9 +3542,17 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
case 12: op = rv_op_vrgather_vx; break;
case 14: op = rv_op_vslideup_vx; break;
case 15: op = rv_op_vslidedown_vx; break;
- case 16: if (((inst >> 25) & 1) == 0) op = rv_op_vadc_vxm; break;
+ case 16:
+ if (((inst >> 25) & 1) == 0) {
+ op = rv_op_vadc_vxm;
+ }
+ break;
case 17: op = rv_op_vmadc_vxm; break;
- case 18: if (((inst >> 25) & 1) == 0) op = rv_op_vsbc_vxm; break;
+ case 18:
+ if (((inst >> 25) & 1) == 0) {
+ op = rv_op_vsbc_vxm;
+ }
+ break;
case 19: op = rv_op_vmsbc_vxm; break;
case 23:
if (((inst >> 20) & 0b111111) == 32)
@@ -3501,7 +3585,7 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
}
break;
case 5:
- switch (((inst >> 26) & 0b111111)) {
+ switch ((inst >> 26) & 0b111111) {
case 0: op = rv_op_vfadd_vf; break;
case 2: op = rv_op_vfsub_vf; break;
case 4: op = rv_op_vfmin_vf; break;
@@ -3512,7 +3596,7 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
case 14: op = rv_op_vfslide1up_vf; break;
case 15: op = rv_op_vfslide1down_vf; break;
case 16:
- switch (((inst >> 20) & 0b11111)) {
+ switch ((inst >> 20) & 0b11111) {
case 0: if ((inst >> 25) & 1) op = rv_op_vfmv_s_f; break;
}
break;
@@ -3552,7 +3636,7 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
}
break;
case 6:
- switch (((inst >> 26) & 0b111111)) {
+ switch ((inst >> 26) & 0b111111) {
case 8: op = rv_op_vaaddu_vx; break;
case 9: op = rv_op_vaadd_vx; break;
case 10: op = rv_op_vasubu_vx; break;
@@ -3560,7 +3644,7 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
case 14: op = rv_op_vslide1up_vx; break;
case 15: op = rv_op_vslide1down_vx; break;
case 16:
- switch (((inst >> 20) & 0b11111)) {
+ switch ((inst >> 20) & 0b11111) {
case 0: if ((inst >> 25) & 1) op = rv_op_vmv_s_x; break;
}
break;
@@ -3605,15 +3689,15 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
}
break;
case 22:
- switch (((inst >> 12) & 0b111)) {
+ switch ((inst >> 12) & 0b111) {
case 0: op = rv_op_addid; break;
case 1:
- switch (((inst >> 26) & 0b111111)) {
+ switch ((inst >> 26) & 0b111111) {
case 0: op = rv_op_sllid; break;
}
break;
case 5:
- switch (((inst >> 26) & 0b111111)) {
+ switch ((inst >> 26) & 0b111111) {
case 0: op = rv_op_srlid; break;
case 16: op = rv_op_sraid; break;
}
@@ -3621,7 +3705,7 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
}
break;
case 24:
- switch (((inst >> 12) & 0b111)) {
+ switch ((inst >> 12) & 0b111) {
case 0: op = rv_op_beq; break;
case 1: op = rv_op_bne; break;
case 4: op = rv_op_blt; break;
@@ -3631,32 +3715,33 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
}
break;
case 25:
- switch (((inst >> 12) & 0b111)) {
+ switch ((inst >> 12) & 0b111) {
case 0: op = rv_op_jalr; break;
}
break;
case 27: op = rv_op_jal; break;
case 28:
- switch (((inst >> 12) & 0b111)) {
+ switch ((inst >> 12) & 0b111) {
case 0:
- switch (((inst >> 20) & 0b111111100000) | ((inst >> 7) & 0b000000011111)) {
+ switch (((inst >> 20) & 0b111111100000) |
+ ((inst >> 7) & 0b000000011111)) {
case 0:
- switch (((inst >> 15) & 0b1111111111)) {
+ switch ((inst >> 15) & 0b1111111111) {
case 0: op = rv_op_ecall; break;
case 32: op = rv_op_ebreak; break;
case 64: op = rv_op_uret; break;
}
break;
case 256:
- switch (((inst >> 20) & 0b11111)) {
+ switch ((inst >> 20) & 0b11111) {
case 2:
- switch (((inst >> 15) & 0b11111)) {
+ switch ((inst >> 15) & 0b11111) {
case 0: op = rv_op_sret; break;
}
break;
case 4: op = rv_op_sfence_vm; break;
case 5:
- switch (((inst >> 15) & 0b11111)) {
+ switch ((inst >> 15) & 0b11111) {
case 0: op = rv_op_wfi; break;
}
break;
@@ -3664,17 +3749,17 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
break;
case 288: op = rv_op_sfence_vma; break;
case 512:
- switch (((inst >> 15) & 0b1111111111)) {
+ switch ((inst >> 15) & 0b1111111111) {
case 64: op = rv_op_hret; break;
}
break;
case 768:
- switch (((inst >> 15) & 0b1111111111)) {
+ switch ((inst >> 15) & 0b1111111111) {
case 64: op = rv_op_mret; break;
}
break;
case 1952:
- switch (((inst >> 15) & 0b1111111111)) {
+ switch ((inst >> 15) & 0b1111111111) {
case 576: op = rv_op_dret; break;
}
break;
@@ -3689,7 +3774,8 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
}
break;
case 30:
- switch (((inst >> 22) & 0b1111111000) | ((inst >> 12) & 0b0000000111)) {
+ switch (((inst >> 22) & 0b1111111000) |
+ ((inst >> 12) & 0b0000000111)) {
case 0: op = rv_op_addd; break;
case 1: op = rv_op_slld; break;
case 5: op = rv_op_srld; break;
@@ -4525,7 +4611,8 @@ static size_t inst_length(rv_inst inst)
{
/* NOTE: supports maximum instruction size of 64-bits */
- /* instruction length coding
+ /*
+ * instruction length coding
*
* aa - 16 bit aa != 11
* bbb11 - 32 bit bbb != 111
@@ -4591,16 +4678,24 @@ static void format_inst(char *buf, size_t buflen, size_t tab, rv_decode *dec)
append(buf, rv_ireg_name_sym[dec->rs2], buflen);
break;
case '3':
- append(buf, rv_freg_name_sym[dec->rd], buflen);
+ append(buf, dec->cfg->ext_zfinx ? rv_ireg_name_sym[dec->rd] :
+ rv_freg_name_sym[dec->rd],
+ buflen);
break;
case '4':
- append(buf, rv_freg_name_sym[dec->rs1], buflen);
+ append(buf, dec->cfg->ext_zfinx ? rv_ireg_name_sym[dec->rs1] :
+ rv_freg_name_sym[dec->rs1],
+ buflen);
break;
case '5':
- append(buf, rv_freg_name_sym[dec->rs2], buflen);
+ append(buf, dec->cfg->ext_zfinx ? rv_ireg_name_sym[dec->rs2] :
+ rv_freg_name_sym[dec->rs2],
+ buflen);
break;
case '6':
- append(buf, rv_freg_name_sym[dec->rs3], buflen);
+ append(buf, dec->cfg->ext_zfinx ? rv_ireg_name_sym[dec->rs3] :
+ rv_freg_name_sym[dec->rs3],
+ buflen);
break;
case '7':
snprintf(tmp, sizeof(tmp), "%d", dec->rs1);
@@ -4861,11 +4956,13 @@ static void decode_inst_decompress(rv_decode *dec, rv_isa isa)
/* disassemble instruction */
static void
-disasm_inst(char *buf, size_t buflen, rv_isa isa, uint64_t pc, rv_inst inst)
+disasm_inst(char *buf, size_t buflen, rv_isa isa, uint64_t pc, rv_inst inst,
+ RISCVCPUConfig *cfg)
{
rv_decode dec = { 0 };
dec.pc = pc;
dec.inst = inst;
+ dec.cfg = cfg;
decode_inst_opcode(&dec, isa);
decode_inst_operands(&dec, isa);
decode_inst_decompress(&dec, isa);
@@ -4920,7 +5017,8 @@ 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,
+ (RISCVCPUConfig *)info->target_info);
(*info->fprintf_func)(info->stream, "%s", buf);
return len;
diff --git a/docs/system/riscv/virt.rst b/docs/system/riscv/virt.rst
index 4b16e41d7f..b33f45e5b3 100644
--- a/docs/system/riscv/virt.rst
+++ b/docs/system/riscv/virt.rst
@@ -53,6 +53,37 @@ with the default OpenSBI firmware image as the -bios. It also supports
the recommended RISC-V bootflow: U-Boot SPL (M-mode) loads OpenSBI fw_dynamic
firmware and U-Boot proper (S-mode), using the standard -bios functionality.
+Using flash devices
+-------------------
+
+By default, the first flash device (pflash0) is expected to contain
+S-mode firmware code. It can be configured as read-only, with the
+second flash device (pflash1) available to store configuration data.
+
+For example, booting edk2 looks like
+
+.. code-block:: bash
+
+ $ qemu-system-riscv64 \
+ -blockdev node-name=pflash0,driver=file,read-only=on,filename=<edk2_code> \
+ -blockdev node-name=pflash1,driver=file,filename=<edk2_vars> \
+ -M virt,pflash0=pflash0,pflash1=pflash1 \
+ ... other args ....
+
+For TCG guests only, it is also possible to boot M-mode firmware from
+the first flash device (pflash0) by additionally passing ``-bios
+none``, as in
+
+.. code-block:: bash
+
+ $ qemu-system-riscv64 \
+ -bios none \
+ -blockdev node-name=pflash0,driver=file,read-only=on,filename=<m_mode_code> \
+ -M virt,pflash0=pflash0 \
+ ... other args ....
+
+Firmware images used for pflash must be exactly 32 MiB in size.
+
Machine-specific options
------------------------
diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c
index afc5b54dbb..4bdc6a5d1a 100644
--- a/hw/intc/riscv_aplic.c
+++ b/hw/intc/riscv_aplic.c
@@ -688,13 +688,13 @@ static void riscv_aplic_write(void *opaque, hwaddr addr, uint64_t value,
* domains).
*/
if (aplic->num_children &&
- !(aplic->smsicfgaddrH & APLIC_xMSICFGADDRH_L)) {
+ !(aplic->mmsicfgaddrH & APLIC_xMSICFGADDRH_L)) {
aplic->smsicfgaddr = value;
}
} else if (aplic->mmode && aplic->msimode &&
(addr == APLIC_SMSICFGADDRH)) {
if (aplic->num_children &&
- !(aplic->smsicfgaddrH & APLIC_xMSICFGADDRH_L)) {
+ !(aplic->mmsicfgaddrH & APLIC_xMSICFGADDRH_L)) {
aplic->smsicfgaddrH = value & APLIC_xMSICFGADDRH_VALID_MASK;
}
} else if ((APLIC_SETIP_BASE <= addr) &&
diff --git a/hw/riscv/numa.c b/hw/riscv/numa.c
index 4720102561..e0414d5b1b 100644
--- a/hw/riscv/numa.c
+++ b/hw/riscv/numa.c
@@ -207,6 +207,12 @@ int64_t riscv_numa_get_default_cpu_node_id(const MachineState *ms, int idx)
{
int64_t nidx = 0;
+ if (ms->numa_state->num_nodes > ms->smp.cpus) {
+ error_report("Number of NUMA nodes (%d)"
+ " cannot exceed the number of available CPUs (%d).",
+ ms->numa_state->num_nodes, ms->smp.max_cpus);
+ exit(EXIT_FAILURE);
+ }
if (ms->numa_state->num_nodes) {
nidx = idx / (ms->smp.cpus / ms->numa_state->num_nodes);
if (ms->numa_state->num_nodes <= nidx) {
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
index bc678766e7..6a2fcc4ade 100644
--- a/hw/riscv/opentitan.c
+++ b/hw/riscv/opentitan.c
@@ -75,11 +75,11 @@ static const MemMapEntry ibex_memmap[] = {
[IBEX_DEV_FLASH_VIRTUAL] = { 0x80000000, 0x80000 },
};
-static void opentitan_board_init(MachineState *machine)
+static void opentitan_machine_init(MachineState *machine)
{
MachineClass *mc = MACHINE_GET_CLASS(machine);
+ OpenTitanState *s = OPENTITAN_MACHINE(machine);
const MemMapEntry *memmap = ibex_memmap;
- OpenTitanState *s = g_new0(OpenTitanState, 1);
MemoryRegion *sys_mem = get_system_memory();
if (machine->ram_size != mc->default_ram_size) {
@@ -108,18 +108,18 @@ static void opentitan_board_init(MachineState *machine)
}
}
-static void opentitan_machine_init(MachineClass *mc)
+static void opentitan_machine_class_init(ObjectClass *oc, void *data)
{
+ MachineClass *mc = MACHINE_CLASS(oc);
+
mc->desc = "RISC-V Board compatible with OpenTitan";
- mc->init = opentitan_board_init;
+ mc->init = opentitan_machine_init;
mc->max_cpus = 1;
mc->default_cpu_type = TYPE_RISCV_CPU_IBEX;
mc->default_ram_id = "riscv.lowrisc.ibex.ram";
mc->default_ram_size = ibex_memmap[IBEX_DEV_RAM].size;
}
-DEFINE_MACHINE("opentitan", opentitan_machine_init)
-
static void lowrisc_ibex_soc_init(Object *obj)
{
LowRISCIbexSoCState *s = RISCV_IBEX_SOC(obj);
@@ -320,17 +320,19 @@ static void lowrisc_ibex_soc_class_init(ObjectClass *oc, void *data)
dc->user_creatable = false;
}
-static const TypeInfo lowrisc_ibex_soc_type_info = {
- .name = TYPE_RISCV_IBEX_SOC,
- .parent = TYPE_DEVICE,
- .instance_size = sizeof(LowRISCIbexSoCState),
- .instance_init = lowrisc_ibex_soc_init,
- .class_init = lowrisc_ibex_soc_class_init,
+static const TypeInfo open_titan_types[] = {
+ {
+ .name = TYPE_RISCV_IBEX_SOC,
+ .parent = TYPE_DEVICE,
+ .instance_size = sizeof(LowRISCIbexSoCState),
+ .instance_init = lowrisc_ibex_soc_init,
+ .class_init = lowrisc_ibex_soc_class_init,
+ }, {
+ .name = TYPE_OPENTITAN_MACHINE,
+ .parent = TYPE_MACHINE,
+ .instance_size = sizeof(OpenTitanState),
+ .class_init = opentitan_machine_class_init,
+ }
};
-static void lowrisc_ibex_soc_register_types(void)
-{
- type_register_static(&lowrisc_ibex_soc_type_info);
-}
-
-type_init(lowrisc_ibex_soc_register_types)
+DEFINE_TYPES(open_titan_types)
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 245c7b97b2..95708d890e 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -1245,7 +1245,8 @@ static void virt_machine_done(Notifier *notifier, void *data)
target_ulong firmware_end_addr, kernel_start_addr;
const char *firmware_name = riscv_default_firmware_name(&s->soc[0]);
uint32_t fdt_load_addr;
- uint64_t kernel_entry;
+ uint64_t kernel_entry = 0;
+ BlockBackend *pflash_blk0;
/*
* Only direct boot kernel is currently supported for KVM VM,
@@ -1266,42 +1267,32 @@ static void virt_machine_done(Notifier *notifier, void *data)
firmware_end_addr = riscv_find_and_load_firmware(machine, firmware_name,
start_addr, NULL);
- if (drive_get(IF_PFLASH, 0, 1)) {
- /*
- * S-mode FW like EDK2 will be kept in second plash (unit 1).
- * When both kernel, initrd and pflash options are provided in the
- * command line, the kernel and initrd will be copied to the fw_cfg
- * table and opensbi will jump to the flash address which is the
- * entry point of S-mode FW. It is the job of the S-mode FW to load
- * the kernel and initrd using fw_cfg table.
- *
- * If only pflash is given but not -kernel, then it is the job of
- * of the S-mode firmware to locate and load the kernel.
- * In either case, the next_addr for opensbi will be the flash address.
- */
- riscv_setup_firmware_boot(machine);
- kernel_entry = virt_memmap[VIRT_FLASH].base +
- virt_memmap[VIRT_FLASH].size / 2;
- } else if (machine->kernel_filename) {
+ pflash_blk0 = pflash_cfi01_get_blk(s->flash[0]);
+ if (pflash_blk0) {
+ if (machine->firmware && !strcmp(machine->firmware, "none") &&
+ !kvm_enabled()) {
+ /*
+ * Pflash was supplied but bios is none and not KVM guest,
+ * let's overwrite the address we jump to after reset to
+ * the base of the flash.
+ */
+ start_addr = virt_memmap[VIRT_FLASH].base;
+ } else {
+ /*
+ * Pflash was supplied but either KVM guest or bios is not none.
+ * In this case, base of the flash would contain S-mode payload.
+ */
+ riscv_setup_firmware_boot(machine);
+ kernel_entry = virt_memmap[VIRT_FLASH].base;
+ }
+ }
+
+ if (machine->kernel_filename && !kernel_entry) {
kernel_start_addr = riscv_calc_kernel_start_addr(&s->soc[0],
firmware_end_addr);
kernel_entry = riscv_load_kernel(machine, &s->soc[0],
kernel_start_addr, true, NULL);
- } else {
- /*
- * If dynamic firmware is used, it doesn't know where is the next mode
- * if kernel argument is not set.
- */
- kernel_entry = 0;
- }
-
- if (drive_get(IF_PFLASH, 0, 0)) {
- /*
- * Pflash was supplied, let's overwrite the address we jump to after
- * reset to the base of the flash.
- */
- start_addr = virt_memmap[VIRT_FLASH].base;
}
fdt_load_addr = riscv_compute_fdt_addr(memmap[VIRT_DRAM].base,
@@ -1510,8 +1501,6 @@ static void virt_machine_init(MachineState *machine)
sysbus_create_simple("goldfish_rtc", memmap[VIRT_RTC].base,
qdev_get_gpio_in(mmio_irqchip, RTC_IRQ));
- virt_flash_create(s);
-
for (i = 0; i < ARRAY_SIZE(s->flash); i++) {
/* Map legacy -drive if=pflash to machine properties */
pflash_cfi01_legacy_drive(s->flash[i],
@@ -1538,6 +1527,8 @@ static void virt_machine_instance_init(Object *obj)
{
RISCVVirtState *s = RISCV_VIRT_MACHINE(obj);
+ virt_flash_create(s);
+
s->oem_id = g_strndup(ACPI_BUILD_APPNAME6, 6);
s->oem_table_id = g_strndup(ACPI_BUILD_APPNAME8, 8);
s->acpi = ON_OFF_AUTO_AUTO;
diff --git a/include/disas/dis-asm.h b/include/disas/dis-asm.h
index 2f6f91c2ee..2324f6b1a4 100644
--- a/include/disas/dis-asm.h
+++ b/include/disas/dis-asm.h
@@ -397,7 +397,7 @@ typedef struct disassemble_info {
char * disassembler_options;
/* Field intended to be used by targets in any way they deem suitable. */
- int64_t target_info;
+ void *target_info;
/* Options for Capstone disassembly. */
int cap_arch;
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index 383456d1b3..d84fbccaab 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -544,11 +544,13 @@ GuestPanicInformation *cpu_get_crash_info(CPUState *cpu);
* @CPU_DUMP_CODE:
* @CPU_DUMP_FPU: dump FPU register state, not just integer
* @CPU_DUMP_CCOP: dump info about TCG QEMU's condition code optimization state
+ * @CPU_DUMP_VPU: dump VPU registers
*/
enum CPUDumpFlags {
CPU_DUMP_CODE = 0x00010000,
CPU_DUMP_FPU = 0x00020000,
CPU_DUMP_CCOP = 0x00040000,
+ CPU_DUMP_VPU = 0x00080000,
};
/**
diff --git a/include/hw/riscv/opentitan.h b/include/hw/riscv/opentitan.h
index c40b05052a..609473d07b 100644
--- a/include/hw/riscv/opentitan.h
+++ b/include/hw/riscv/opentitan.h
@@ -24,6 +24,7 @@
#include "hw/char/ibex_uart.h"
#include "hw/timer/ibex_timer.h"
#include "hw/ssi/ibex_spi_host.h"
+#include "hw/boards.h"
#include "qom/object.h"
#define TYPE_RISCV_IBEX_SOC "riscv.lowrisc.ibex.soc"
@@ -53,9 +54,12 @@ struct LowRISCIbexSoCState {
MemoryRegion flash_alias;
};
+#define TYPE_OPENTITAN_MACHINE MACHINE_TYPE_NAME("opentitan")
+OBJECT_DECLARE_SIMPLE_TYPE(OpenTitanState, OPENTITAN_MACHINE)
+
typedef struct OpenTitanState {
/*< private >*/
- SysBusDevice parent_obj;
+ MachineState parent_obj;
/*< public >*/
LowRISCIbexSoCState soc;
diff --git a/include/qemu/log.h b/include/qemu/log.h
index c5643d8dd5..df59bfabcd 100644
--- a/include/qemu/log.h
+++ b/include/qemu/log.h
@@ -35,6 +35,7 @@ bool qemu_log_separate(void);
/* LOG_STRACE is used for user-mode strace logging. */
#define LOG_STRACE (1 << 19)
#define LOG_PER_THREAD (1 << 20)
+#define CPU_LOG_TB_VPU (1 << 21)
/* Lock/unlock output. */
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index db0875fb43..881bddf393 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -119,6 +119,7 @@ static const struct isa_ext_data isa_edata_arr[] = {
ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx),
ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin),
ISA_EXT_DATA_ENTRY(smaia, PRIV_VERSION_1_12_0, ext_smaia),
+ ISA_EXT_DATA_ENTRY(smstateen, PRIV_VERSION_1_12_0, ext_smstateen),
ISA_EXT_DATA_ENTRY(ssaia, PRIV_VERSION_1_12_0, ext_ssaia),
ISA_EXT_DATA_ENTRY(sscofpmf, PRIV_VERSION_1_12_0, ext_sscofpmf),
ISA_EXT_DATA_ENTRY(sstc, PRIV_VERSION_1_12_0, ext_sstc),
@@ -247,16 +248,6 @@ static void set_misa(CPURISCVState *env, RISCVMXL mxl, uint32_t ext)
env->misa_ext_mask = env->misa_ext = ext;
}
-static void set_priv_version(CPURISCVState *env, int priv_ver)
-{
- env->priv_ver = priv_ver;
-}
-
-static void set_vext_version(CPURISCVState *env, int vext_ver)
-{
- env->vext_ver = vext_ver;
-}
-
#ifndef CONFIG_USER_ONLY
static uint8_t satp_mode_from_str(const char *satp_mode_str)
{
@@ -342,7 +333,8 @@ static void set_satp_mode_default_map(RISCVCPU *cpu)
static void riscv_any_cpu_init(Object *obj)
{
- CPURISCVState *env = &RISCV_CPU(obj)->env;
+ RISCVCPU *cpu = RISCV_CPU(obj);
+ CPURISCVState *env = &cpu->env;
#if defined(TARGET_RISCV32)
set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVD | RVC | RVU);
#elif defined(TARGET_RISCV64)
@@ -355,7 +347,13 @@ static void riscv_any_cpu_init(Object *obj)
VM_1_10_SV32 : VM_1_10_SV57);
#endif
- set_priv_version(env, PRIV_VERSION_1_12_0);
+ env->priv_ver = PRIV_VERSION_LATEST;
+
+ /* inherited from parent obj via riscv_cpu_init() */
+ cpu->cfg.ext_ifencei = true;
+ cpu->cfg.ext_icsr = true;
+ cpu->cfg.mmu = true;
+ cpu->cfg.pmp = true;
}
#if defined(TARGET_RISCV64)
@@ -366,7 +364,7 @@ static void rv64_base_cpu_init(Object *obj)
set_misa(env, MXL_RV64, 0);
riscv_cpu_add_user_properties(obj);
/* Set latest version of privileged specification */
- set_priv_version(env, PRIV_VERSION_1_12_0);
+ env->priv_ver = PRIV_VERSION_LATEST;
#ifndef CONFIG_USER_ONLY
set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV57);
#endif
@@ -374,12 +372,19 @@ static void rv64_base_cpu_init(Object *obj)
static void rv64_sifive_u_cpu_init(Object *obj)
{
- CPURISCVState *env = &RISCV_CPU(obj)->env;
+ RISCVCPU *cpu = RISCV_CPU(obj);
+ CPURISCVState *env = &cpu->env;
set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
- set_priv_version(env, PRIV_VERSION_1_10_0);
+ env->priv_ver = PRIV_VERSION_1_10_0;
#ifndef CONFIG_USER_ONLY
set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV39);
#endif
+
+ /* inherited from parent obj via riscv_cpu_init() */
+ cpu->cfg.ext_ifencei = true;
+ cpu->cfg.ext_icsr = true;
+ cpu->cfg.mmu = true;
+ cpu->cfg.pmp = true;
}
static void rv64_sifive_e_cpu_init(Object *obj)
@@ -388,11 +393,15 @@ static void rv64_sifive_e_cpu_init(Object *obj)
RISCVCPU *cpu = RISCV_CPU(obj);
set_misa(env, MXL_RV64, RVI | RVM | RVA | RVC | RVU);
- set_priv_version(env, PRIV_VERSION_1_10_0);
- cpu->cfg.mmu = false;
+ env->priv_ver = PRIV_VERSION_1_10_0;
#ifndef CONFIG_USER_ONLY
set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
#endif
+
+ /* inherited from parent obj via riscv_cpu_init() */
+ cpu->cfg.ext_ifencei = true;
+ cpu->cfg.ext_icsr = true;
+ cpu->cfg.pmp = true;
}
static void rv64_thead_c906_cpu_init(Object *obj)
@@ -401,7 +410,7 @@ static void rv64_thead_c906_cpu_init(Object *obj)
RISCVCPU *cpu = RISCV_CPU(obj);
set_misa(env, MXL_RV64, RVG | RVC | RVS | RVU);
- set_priv_version(env, PRIV_VERSION_1_11_0);
+ env->priv_ver = PRIV_VERSION_1_11_0;
cpu->cfg.ext_zfh = true;
cpu->cfg.mmu = true;
@@ -420,6 +429,9 @@ static void rv64_thead_c906_cpu_init(Object *obj)
#ifndef CONFIG_USER_ONLY
set_satp_mode_max_supported(cpu, VM_1_10_SV39);
#endif
+
+ /* inherited from parent obj via riscv_cpu_init() */
+ cpu->cfg.pmp = true;
}
static void rv64_veyron_v1_cpu_init(Object *obj)
@@ -472,7 +484,7 @@ static void rv128_base_cpu_init(Object *obj)
set_misa(env, MXL_RV128, 0);
riscv_cpu_add_user_properties(obj);
/* Set latest version of privileged specification */
- set_priv_version(env, PRIV_VERSION_1_12_0);
+ env->priv_ver = PRIV_VERSION_LATEST;
#ifndef CONFIG_USER_ONLY
set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV57);
#endif
@@ -485,7 +497,7 @@ static void rv32_base_cpu_init(Object *obj)
set_misa(env, MXL_RV32, 0);
riscv_cpu_add_user_properties(obj);
/* Set latest version of privileged specification */
- set_priv_version(env, PRIV_VERSION_1_12_0);
+ env->priv_ver = PRIV_VERSION_LATEST;
#ifndef CONFIG_USER_ONLY
set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV32);
#endif
@@ -493,12 +505,19 @@ static void rv32_base_cpu_init(Object *obj)
static void rv32_sifive_u_cpu_init(Object *obj)
{
- CPURISCVState *env = &RISCV_CPU(obj)->env;
+ RISCVCPU *cpu = RISCV_CPU(obj);
+ CPURISCVState *env = &cpu->env;
set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
- set_priv_version(env, PRIV_VERSION_1_10_0);
+ env->priv_ver = PRIV_VERSION_1_10_0;
#ifndef CONFIG_USER_ONLY
set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV32);
#endif
+
+ /* inherited from parent obj via riscv_cpu_init() */
+ cpu->cfg.ext_ifencei = true;
+ cpu->cfg.ext_icsr = true;
+ cpu->cfg.mmu = true;
+ cpu->cfg.pmp = true;
}
static void rv32_sifive_e_cpu_init(Object *obj)
@@ -507,11 +526,15 @@ static void rv32_sifive_e_cpu_init(Object *obj)
RISCVCPU *cpu = RISCV_CPU(obj);
set_misa(env, MXL_RV32, RVI | RVM | RVA | RVC | RVU);
- set_priv_version(env, PRIV_VERSION_1_10_0);
- cpu->cfg.mmu = false;
+ env->priv_ver = PRIV_VERSION_1_10_0;
#ifndef CONFIG_USER_ONLY
set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
#endif
+
+ /* inherited from parent obj via riscv_cpu_init() */
+ cpu->cfg.ext_ifencei = true;
+ cpu->cfg.ext_icsr = true;
+ cpu->cfg.pmp = true;
}
static void rv32_ibex_cpu_init(Object *obj)
@@ -520,12 +543,16 @@ static void rv32_ibex_cpu_init(Object *obj)
RISCVCPU *cpu = RISCV_CPU(obj);
set_misa(env, MXL_RV32, RVI | RVM | RVC | RVU);
- set_priv_version(env, PRIV_VERSION_1_11_0);
- cpu->cfg.mmu = false;
+ env->priv_ver = PRIV_VERSION_1_11_0;
#ifndef CONFIG_USER_ONLY
set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
#endif
cpu->cfg.epmp = true;
+
+ /* inherited from parent obj via riscv_cpu_init() */
+ cpu->cfg.ext_ifencei = true;
+ cpu->cfg.ext_icsr = true;
+ cpu->cfg.pmp = true;
}
static void rv32_imafcu_nommu_cpu_init(Object *obj)
@@ -534,11 +561,15 @@ static void rv32_imafcu_nommu_cpu_init(Object *obj)
RISCVCPU *cpu = RISCV_CPU(obj);
set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVC | RVU);
- set_priv_version(env, PRIV_VERSION_1_10_0);
- cpu->cfg.mmu = false;
+ env->priv_ver = PRIV_VERSION_1_10_0;
#ifndef CONFIG_USER_ONLY
set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
#endif
+
+ /* inherited from parent obj via riscv_cpu_init() */
+ cpu->cfg.ext_ifencei = true;
+ cpu->cfg.ext_icsr = true;
+ cpu->cfg.pmp = true;
}
#endif
@@ -690,16 +721,18 @@ static vaddr riscv_cpu_get_pc(CPUState *cs)
static void riscv_cpu_synchronize_from_tb(CPUState *cs,
const TranslationBlock *tb)
{
- RISCVCPU *cpu = RISCV_CPU(cs);
- CPURISCVState *env = &cpu->env;
- RISCVMXL xl = FIELD_EX32(tb->flags, TB_FLAGS, XL);
+ if (!(tb_cflags(tb) & CF_PCREL)) {
+ RISCVCPU *cpu = RISCV_CPU(cs);
+ CPURISCVState *env = &cpu->env;
+ RISCVMXL xl = FIELD_EX32(tb->flags, TB_FLAGS, XL);
- tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL));
+ tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL));
- if (xl == MXL_RV32) {
- env->pc = (int32_t) tb->pc;
- } else {
- env->pc = tb->pc;
+ if (xl == MXL_RV32) {
+ env->pc = (int32_t) tb->pc;
+ } else {
+ env->pc = tb->pc;
+ }
}
}
@@ -725,11 +758,18 @@ static void riscv_restore_state_to_opc(CPUState *cs,
RISCVCPU *cpu = RISCV_CPU(cs);
CPURISCVState *env = &cpu->env;
RISCVMXL xl = FIELD_EX32(tb->flags, TB_FLAGS, XL);
+ target_ulong pc;
+
+ if (tb_cflags(tb) & CF_PCREL) {
+ pc = (env->pc & TARGET_PAGE_MASK) | data[0];
+ } else {
+ pc = data[0];
+ }
if (xl == MXL_RV32) {
- env->pc = (int32_t)data[0];
+ env->pc = (int32_t)pc;
} else {
- env->pc = data[0];
+ env->pc = pc;
}
env->bins = data[1];
}
@@ -818,6 +858,7 @@ 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);
+ info->target_info = &cpu->cfg;
switch (riscv_cpu_mxl(&cpu->env)) {
case MXL_RV32:
@@ -834,13 +875,127 @@ static void riscv_cpu_disas_set_info(CPUState *s, disassemble_info *info)
}
}
+static void riscv_cpu_validate_v(CPURISCVState *env, RISCVCPUConfig *cfg,
+ Error **errp)
+{
+ int vext_version = VEXT_VERSION_1_00_0;
+
+ if (!is_power_of_2(cfg->vlen)) {
+ error_setg(errp, "Vector extension VLEN must be power of 2");
+ return;
+ }
+ if (cfg->vlen > RV_VLEN_MAX || cfg->vlen < 128) {
+ error_setg(errp,
+ "Vector extension implementation only supports VLEN "
+ "in the range [128, %d]", RV_VLEN_MAX);
+ return;
+ }
+ if (!is_power_of_2(cfg->elen)) {
+ error_setg(errp, "Vector extension ELEN must be power of 2");
+ return;
+ }
+ if (cfg->elen > 64 || cfg->elen < 8) {
+ error_setg(errp,
+ "Vector extension implementation only supports ELEN "
+ "in the range [8, 64]");
+ return;
+ }
+ if (cfg->vext_spec) {
+ if (!g_strcmp0(cfg->vext_spec, "v1.0")) {
+ vext_version = VEXT_VERSION_1_00_0;
+ } else {
+ error_setg(errp, "Unsupported vector spec version '%s'",
+ cfg->vext_spec);
+ return;
+ }
+ } else {
+ qemu_log("vector version is not specified, "
+ "use the default value v1.0\n");
+ }
+ env->vext_ver = vext_version;
+}
+
+static void riscv_cpu_validate_priv_spec(RISCVCPU *cpu, Error **errp)
+{
+ CPURISCVState *env = &cpu->env;
+ int priv_version = -1;
+
+ if (cpu->cfg.priv_spec) {
+ if (!g_strcmp0(cpu->cfg.priv_spec, "v1.12.0")) {
+ priv_version = PRIV_VERSION_1_12_0;
+ } else if (!g_strcmp0(cpu->cfg.priv_spec, "v1.11.0")) {
+ priv_version = PRIV_VERSION_1_11_0;
+ } else if (!g_strcmp0(cpu->cfg.priv_spec, "v1.10.0")) {
+ priv_version = PRIV_VERSION_1_10_0;
+ } else {
+ error_setg(errp,
+ "Unsupported privilege spec version '%s'",
+ cpu->cfg.priv_spec);
+ return;
+ }
+
+ env->priv_ver = priv_version;
+ }
+}
+
+static void riscv_cpu_disable_priv_spec_isa_exts(RISCVCPU *cpu)
+{
+ CPURISCVState *env = &cpu->env;
+ int i;
+
+ /* Force disable extensions if priv spec version does not match */
+ for (i = 0; i < ARRAY_SIZE(isa_edata_arr); i++) {
+ if (isa_ext_is_enabled(cpu, &isa_edata_arr[i]) &&
+ (env->priv_ver < isa_edata_arr[i].min_version)) {
+ isa_ext_update_enabled(cpu, &isa_edata_arr[i], false);
+#ifndef CONFIG_USER_ONLY
+ warn_report("disabling %s extension for hart 0x" TARGET_FMT_lx
+ " because privilege spec version does not match",
+ isa_edata_arr[i].name, env->mhartid);
+#else
+ warn_report("disabling %s extension because "
+ "privilege spec version does not match",
+ isa_edata_arr[i].name);
+#endif
+ }
+ }
+}
+
+static void riscv_cpu_validate_misa_mxl(RISCVCPU *cpu, Error **errp)
+{
+ RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cpu);
+ CPUClass *cc = CPU_CLASS(mcc);
+ CPURISCVState *env = &cpu->env;
+
+ /* Validate that MISA_MXL is set properly. */
+ switch (env->misa_mxl_max) {
+#ifdef TARGET_RISCV64
+ case MXL_RV64:
+ case MXL_RV128:
+ cc->gdb_core_xml_file = "riscv-64bit-cpu.xml";
+ break;
+#endif
+ case MXL_RV32:
+ cc->gdb_core_xml_file = "riscv-32bit-cpu.xml";
+ break;
+ default:
+ g_assert_not_reached();
+ }
+
+ if (env->misa_mxl_max != env->misa_mxl) {
+ error_setg(errp, "misa_mxl_max must be equal to misa_mxl");
+ return;
+ }
+}
+
/*
* Check consistency between chosen extensions while setting
* cpu->cfg accordingly.
*/
-static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
+void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
{
CPURISCVState *env = &cpu->env;
+ Error *local_err = NULL;
/* Do some ISA extension error checking */
if (riscv_has_ext(env, RVG) &&
@@ -853,7 +1008,7 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
cpu->cfg.ext_ifencei = true;
env->misa_ext |= RVI | RVM | RVA | RVF | RVD;
- env->misa_ext_mask = env->misa_ext;
+ env->misa_ext_mask |= RVI | RVM | RVA | RVF | RVD;
}
if (riscv_has_ext(env, RVI) && riscv_has_ext(env, RVE)) {
@@ -909,8 +1064,14 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
return;
}
- /* The V vector extension depends on the Zve64d extension */
if (riscv_has_ext(env, RVV)) {
+ riscv_cpu_validate_v(env, &cpu->cfg, &local_err);
+ if (local_err != NULL) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
+ /* The V vector extension depends on the Zve64d extension */
cpu->cfg.ext_zve64d = true;
}
@@ -1046,45 +1207,11 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
cpu->cfg.ext_zksh = true;
}
- if (riscv_has_ext(env, RVV)) {
- int vext_version = VEXT_VERSION_1_00_0;
- if (!is_power_of_2(cpu->cfg.vlen)) {
- error_setg(errp,
- "Vector extension VLEN must be power of 2");
- return;
- }
- if (cpu->cfg.vlen > RV_VLEN_MAX || cpu->cfg.vlen < 128) {
- error_setg(errp,
- "Vector extension implementation only supports VLEN "
- "in the range [128, %d]", RV_VLEN_MAX);
- return;
- }
- if (!is_power_of_2(cpu->cfg.elen)) {
- error_setg(errp,
- "Vector extension ELEN must be power of 2");
- return;
- }
- if (cpu->cfg.elen > 64 || cpu->cfg.elen < 8) {
- error_setg(errp,
- "Vector extension implementation only supports ELEN "
- "in the range [8, 64]");
- return;
- }
- if (cpu->cfg.vext_spec) {
- if (!g_strcmp0(cpu->cfg.vext_spec, "v1.0")) {
- vext_version = VEXT_VERSION_1_00_0;
- } else {
- error_setg(errp,
- "Unsupported vector spec version '%s'",
- cpu->cfg.vext_spec);
- return;
- }
- } else {
- qemu_log("vector version is not specified, "
- "use the default value v1.0\n");
- }
- set_vext_version(env, vext_version);
- }
+ /*
+ * Disable isa extensions based on priv spec after we
+ * validated and set everything we need.
+ */
+ riscv_cpu_disable_priv_spec_isa_exts(cpu);
}
#ifndef CONFIG_USER_ONLY
@@ -1183,8 +1310,6 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
RISCVCPU *cpu = RISCV_CPU(dev);
CPURISCVState *env = &cpu->env;
RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev);
- CPUClass *cc = CPU_CLASS(mcc);
- int i, priv_version = -1;
Error *local_err = NULL;
cpu_exec_realizefn(cs, &local_err);
@@ -1193,23 +1318,16 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
return;
}
- if (cpu->cfg.priv_spec) {
- if (!g_strcmp0(cpu->cfg.priv_spec, "v1.12.0")) {
- priv_version = PRIV_VERSION_1_12_0;
- } else if (!g_strcmp0(cpu->cfg.priv_spec, "v1.11.0")) {
- priv_version = PRIV_VERSION_1_11_0;
- } else if (!g_strcmp0(cpu->cfg.priv_spec, "v1.10.0")) {
- priv_version = PRIV_VERSION_1_10_0;
- } else {
- error_setg(errp,
- "Unsupported privilege spec version '%s'",
- cpu->cfg.priv_spec);
- return;
- }
+ riscv_cpu_validate_misa_mxl(cpu, &local_err);
+ if (local_err != NULL) {
+ error_propagate(errp, local_err);
+ return;
}
- if (priv_version >= PRIV_VERSION_1_10_0) {
- set_priv_version(env, priv_version);
+ riscv_cpu_validate_priv_spec(cpu, &local_err);
+ if (local_err != NULL) {
+ error_propagate(errp, local_err);
+ return;
}
riscv_cpu_validate_misa_priv(env, &local_err);
@@ -1218,23 +1336,6 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
return;
}
- /* Force disable extensions if priv spec version does not match */
- for (i = 0; i < ARRAY_SIZE(isa_edata_arr); i++) {
- if (isa_ext_is_enabled(cpu, &isa_edata_arr[i]) &&
- (env->priv_ver < isa_edata_arr[i].min_version)) {
- isa_ext_update_enabled(cpu, &isa_edata_arr[i], false);
-#ifndef CONFIG_USER_ONLY
- warn_report("disabling %s extension for hart 0x" TARGET_FMT_lx
- " because privilege spec version does not match",
- isa_edata_arr[i].name, env->mhartid);
-#else
- warn_report("disabling %s extension because "
- "privilege spec version does not match",
- isa_edata_arr[i].name);
-#endif
- }
- }
-
if (cpu->cfg.epmp && !cpu->cfg.pmp) {
/*
* Enhanced PMP should only be available
@@ -1244,29 +1345,6 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
return;
}
-
-#ifndef CONFIG_USER_ONLY
- if (cpu->cfg.ext_sstc) {
- riscv_timer_init(cpu);
- }
-#endif /* CONFIG_USER_ONLY */
-
- /* Validate that MISA_MXL is set properly. */
- switch (env->misa_mxl_max) {
-#ifdef TARGET_RISCV64
- case MXL_RV64:
- case MXL_RV128:
- cc->gdb_core_xml_file = "riscv-64bit-cpu.xml";
- break;
-#endif
- case MXL_RV32:
- cc->gdb_core_xml_file = "riscv-32bit-cpu.xml";
- break;
- default:
- g_assert_not_reached();
- }
- assert(env->misa_mxl_max == env->misa_mxl);
-
riscv_cpu_validate_set_extensions(cpu, &local_err);
if (local_err != NULL) {
error_propagate(errp, local_err);
@@ -1274,6 +1352,12 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
}
#ifndef CONFIG_USER_ONLY
+ cs->tcg_cflags |= CF_PCREL;
+
+ if (cpu->cfg.ext_sstc) {
+ riscv_timer_init(cpu);
+ }
+
if (cpu->cfg.pmu_num) {
if (!riscv_pmu_init(cpu, cpu->cfg.pmu_num) && cpu->cfg.ext_sscofpmf) {
cpu->pmu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
@@ -1410,11 +1494,6 @@ static void riscv_cpu_init(Object *obj)
{
RISCVCPU *cpu = RISCV_CPU(obj);
- cpu->cfg.ext_ifencei = true;
- cpu->cfg.ext_icsr = true;
- cpu->cfg.mmu = true;
- cpu->cfg.pmp = true;
-
cpu_set_cpustate_pointers(cpu);
#ifndef CONFIG_USER_ONLY
@@ -1535,8 +1614,8 @@ static Property riscv_cpu_extensions[] = {
DEFINE_PROP_UINT16("vlen", RISCVCPU, cfg.vlen, 128),
DEFINE_PROP_UINT16("elen", RISCVCPU, cfg.elen, 64),
+ DEFINE_PROP_BOOL("smstateen", RISCVCPU, cfg.ext_smstateen, false),
DEFINE_PROP_BOOL("svadu", RISCVCPU, cfg.ext_svadu, true),
-
DEFINE_PROP_BOOL("svinval", RISCVCPU, cfg.ext_svinval, false),
DEFINE_PROP_BOOL("svnapot", RISCVCPU, cfg.ext_svnapot, false),
DEFINE_PROP_BOOL("svpbmt", RISCVCPU, cfg.ext_svpbmt, false),
@@ -1571,6 +1650,14 @@ static Property riscv_cpu_extensions[] = {
DEFINE_PROP_BOOL("zmmul", RISCVCPU, cfg.ext_zmmul, false),
+ DEFINE_PROP_BOOL("zca", RISCVCPU, cfg.ext_zca, false),
+ DEFINE_PROP_BOOL("zcb", RISCVCPU, cfg.ext_zcb, false),
+ DEFINE_PROP_BOOL("zcd", RISCVCPU, cfg.ext_zcd, false),
+ DEFINE_PROP_BOOL("zce", RISCVCPU, cfg.ext_zce, false),
+ DEFINE_PROP_BOOL("zcf", RISCVCPU, cfg.ext_zcf, false),
+ DEFINE_PROP_BOOL("zcmp", RISCVCPU, cfg.ext_zcmp, false),
+ DEFINE_PROP_BOOL("zcmt", RISCVCPU, cfg.ext_zcmt, false),
+
/* Vendor-specific custom extensions */
DEFINE_PROP_BOOL("xtheadba", RISCVCPU, cfg.ext_xtheadba, false),
DEFINE_PROP_BOOL("xtheadbb", RISCVCPU, cfg.ext_xtheadbb, false),
@@ -1588,14 +1675,6 @@ static Property riscv_cpu_extensions[] = {
/* These are experimental so mark with 'x-' */
DEFINE_PROP_BOOL("x-zicond", RISCVCPU, cfg.ext_zicond, false),
- DEFINE_PROP_BOOL("x-zca", RISCVCPU, cfg.ext_zca, false),
- DEFINE_PROP_BOOL("x-zcb", RISCVCPU, cfg.ext_zcb, false),
- DEFINE_PROP_BOOL("x-zcd", RISCVCPU, cfg.ext_zcd, false),
- DEFINE_PROP_BOOL("x-zce", RISCVCPU, cfg.ext_zce, false),
- DEFINE_PROP_BOOL("x-zcf", RISCVCPU, cfg.ext_zcf, false),
- DEFINE_PROP_BOOL("x-zcmp", RISCVCPU, cfg.ext_zcmp, false),
- DEFINE_PROP_BOOL("x-zcmt", RISCVCPU, cfg.ext_zcmt, false),
-
/* ePMP 0.9.3 */
DEFINE_PROP_BOOL("x-epmp", RISCVCPU, cfg.epmp, false),
DEFINE_PROP_BOOL("x-smaia", RISCVCPU, cfg.ext_smaia, false),
@@ -1761,7 +1840,8 @@ static void riscv_isa_string_ext(RISCVCPU *cpu, char **isa_str,
int i;
for (i = 0; i < ARRAY_SIZE(isa_edata_arr); i++) {
- if (isa_ext_is_enabled(cpu, &isa_edata_arr[i])) {
+ if (cpu->env.priv_ver >= isa_edata_arr[i].min_version &&
+ isa_ext_is_enabled(cpu, &isa_edata_arr[i])) {
new = g_strconcat(old, "_", isa_edata_arr[i].name, NULL);
g_free(old);
old = new;
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index de7e43126a..e3e08d315f 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -27,6 +27,7 @@
#include "qom/object.h"
#include "qemu/int128.h"
#include "cpu_bits.h"
+#include "cpu_cfg.h"
#include "qapi/qapi-types-common.h"
#include "cpu-qom.h"
@@ -61,6 +62,8 @@ enum {
PRIV_VERSION_1_10_0 = 0,
PRIV_VERSION_1_11_0,
PRIV_VERSION_1_12_0,
+
+ PRIV_VERSION_LATEST = PRIV_VERSION_1_12_0,
};
#define VEXT_VERSION_1_00_0 0x00010000
@@ -369,119 +372,6 @@ struct CPUArchState {
};
/*
- * map is a 16-bit bitmap: the most significant set bit in map is the maximum
- * satp mode that is supported. It may be chosen by the user and must respect
- * what qemu implements (valid_1_10_32/64) and what the hw is capable of
- * (supported bitmap below).
- *
- * init is a 16-bit bitmap used to make sure the user selected a correct
- * configuration as per the specification.
- *
- * supported is a 16-bit bitmap used to reflect the hw capabilities.
- */
-typedef struct {
- uint16_t map, init, supported;
-} RISCVSATPMap;
-
-struct RISCVCPUConfig {
- bool ext_zba;
- bool ext_zbb;
- bool ext_zbc;
- bool ext_zbkb;
- bool ext_zbkc;
- bool ext_zbkx;
- bool ext_zbs;
- bool ext_zca;
- bool ext_zcb;
- bool ext_zcd;
- bool ext_zce;
- bool ext_zcf;
- bool ext_zcmp;
- bool ext_zcmt;
- bool ext_zk;
- bool ext_zkn;
- bool ext_zknd;
- bool ext_zkne;
- bool ext_zknh;
- bool ext_zkr;
- bool ext_zks;
- bool ext_zksed;
- bool ext_zksh;
- bool ext_zkt;
- bool ext_ifencei;
- bool ext_icsr;
- bool ext_icbom;
- bool ext_icboz;
- bool ext_zicond;
- bool ext_zihintpause;
- bool ext_smstateen;
- bool ext_sstc;
- bool ext_svadu;
- bool ext_svinval;
- bool ext_svnapot;
- bool ext_svpbmt;
- bool ext_zdinx;
- bool ext_zawrs;
- bool ext_zfh;
- bool ext_zfhmin;
- bool ext_zfinx;
- bool ext_zhinx;
- bool ext_zhinxmin;
- bool ext_zve32f;
- bool ext_zve64f;
- bool ext_zve64d;
- bool ext_zmmul;
- bool ext_zvfh;
- bool ext_zvfhmin;
- bool ext_smaia;
- bool ext_ssaia;
- bool ext_sscofpmf;
- bool rvv_ta_all_1s;
- bool rvv_ma_all_1s;
-
- uint32_t mvendorid;
- uint64_t marchid;
- uint64_t mimpid;
-
- /* Vendor-specific custom extensions */
- bool ext_xtheadba;
- bool ext_xtheadbb;
- bool ext_xtheadbs;
- bool ext_xtheadcmo;
- bool ext_xtheadcondmov;
- bool ext_xtheadfmemidx;
- bool ext_xtheadfmv;
- bool ext_xtheadmac;
- bool ext_xtheadmemidx;
- bool ext_xtheadmempair;
- bool ext_xtheadsync;
- bool ext_XVentanaCondOps;
-
- uint8_t pmu_num;
- char *priv_spec;
- char *user_spec;
- char *bext_spec;
- char *vext_spec;
- uint16_t vlen;
- uint16_t elen;
- uint16_t cbom_blocksize;
- uint16_t cboz_blocksize;
- bool mmu;
- bool pmp;
- bool epmp;
- bool debug;
- bool misa_w;
-
- bool short_isa_string;
-
-#ifndef CONFIG_USER_ONLY
- RISCVSATPMap satp_mode;
-#endif
-};
-
-typedef struct RISCVCPUConfig RISCVCPUConfig;
-
-/*
* RISCVCPU:
* @env: #CPURISCVState
*
@@ -546,6 +436,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
bool probe, uintptr_t retaddr);
char *riscv_isa_string(RISCVCPU *cpu);
void riscv_cpu_list(void);
+void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp);
#define cpu_list riscv_cpu_list
#define cpu_mmu_index riscv_cpu_mmu_index
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
new file mode 100644
index 0000000000..c4a627d335
--- /dev/null
+++ b/target/riscv/cpu_cfg.h
@@ -0,0 +1,136 @@
+/*
+ * QEMU RISC-V CPU CFG
+ *
+ * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
+ * Copyright (c) 2017-2018 SiFive, Inc.
+ * Copyright (c) 2021-2023 PLCT Lab
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef RISCV_CPU_CFG_H
+#define RISCV_CPU_CFG_H
+
+/*
+ * map is a 16-bit bitmap: the most significant set bit in map is the maximum
+ * satp mode that is supported. It may be chosen by the user and must respect
+ * what qemu implements (valid_1_10_32/64) and what the hw is capable of
+ * (supported bitmap below).
+ *
+ * init is a 16-bit bitmap used to make sure the user selected a correct
+ * configuration as per the specification.
+ *
+ * supported is a 16-bit bitmap used to reflect the hw capabilities.
+ */
+typedef struct {
+ uint16_t map, init, supported;
+} RISCVSATPMap;
+
+struct RISCVCPUConfig {
+ bool ext_zba;
+ bool ext_zbb;
+ bool ext_zbc;
+ bool ext_zbkb;
+ bool ext_zbkc;
+ bool ext_zbkx;
+ bool ext_zbs;
+ bool ext_zca;
+ bool ext_zcb;
+ bool ext_zcd;
+ bool ext_zce;
+ bool ext_zcf;
+ bool ext_zcmp;
+ bool ext_zcmt;
+ bool ext_zk;
+ bool ext_zkn;
+ bool ext_zknd;
+ bool ext_zkne;
+ bool ext_zknh;
+ bool ext_zkr;
+ bool ext_zks;
+ bool ext_zksed;
+ bool ext_zksh;
+ bool ext_zkt;
+ bool ext_ifencei;
+ bool ext_icsr;
+ bool ext_icbom;
+ bool ext_icboz;
+ bool ext_zicond;
+ bool ext_zihintpause;
+ bool ext_smstateen;
+ bool ext_sstc;
+ bool ext_svadu;
+ bool ext_svinval;
+ bool ext_svnapot;
+ bool ext_svpbmt;
+ bool ext_zdinx;
+ bool ext_zawrs;
+ bool ext_zfh;
+ bool ext_zfhmin;
+ bool ext_zfinx;
+ bool ext_zhinx;
+ bool ext_zhinxmin;
+ bool ext_zve32f;
+ bool ext_zve64f;
+ bool ext_zve64d;
+ bool ext_zmmul;
+ bool ext_zvfh;
+ bool ext_zvfhmin;
+ bool ext_smaia;
+ bool ext_ssaia;
+ bool ext_sscofpmf;
+ bool rvv_ta_all_1s;
+ bool rvv_ma_all_1s;
+
+ uint32_t mvendorid;
+ uint64_t marchid;
+ uint64_t mimpid;
+
+ /* Vendor-specific custom extensions */
+ bool ext_xtheadba;
+ bool ext_xtheadbb;
+ bool ext_xtheadbs;
+ bool ext_xtheadcmo;
+ bool ext_xtheadcondmov;
+ bool ext_xtheadfmemidx;
+ bool ext_xtheadfmv;
+ bool ext_xtheadmac;
+ bool ext_xtheadmemidx;
+ bool ext_xtheadmempair;
+ bool ext_xtheadsync;
+ bool ext_XVentanaCondOps;
+
+ uint8_t pmu_num;
+ char *priv_spec;
+ char *user_spec;
+ char *bext_spec;
+ char *vext_spec;
+ uint16_t vlen;
+ uint16_t elen;
+ uint16_t cbom_blocksize;
+ uint16_t cboz_blocksize;
+ bool mmu;
+ bool pmp;
+ bool epmp;
+ bool debug;
+ bool misa_w;
+
+ bool short_isa_string;
+
+#ifndef CONFIG_USER_ONLY
+ RISCVSATPMap satp_mode;
+#endif
+};
+
+typedef struct RISCVCPUConfig RISCVCPUConfig;
+#endif
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 56381aaf26..90cef9856d 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -120,6 +120,12 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
vs = MIN(vs, get_field(env->mstatus_hs, MSTATUS_VS));
}
+ /* With Zfinx, floating point is enabled/disabled by Smstateen. */
+ if (!riscv_has_ext(env, RVF)) {
+ fs = (smstateen_acc_ok(env, 0, SMSTATEEN0_FCSR) == RISCV_EXCP_NONE)
+ ? EXT_STATUS_DIRTY : EXT_STATUS_DISABLED;
+ }
+
if (cpu->cfg.debug && !icount_enabled()) {
flags = FIELD_DP32(flags, TB_FLAGS, ITRIGGER, env->itrigger_enabled);
}
@@ -128,7 +134,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
flags = FIELD_DP32(flags, TB_FLAGS, FS, fs);
flags = FIELD_DP32(flags, TB_FLAGS, VS, vs);
flags = FIELD_DP32(flags, TB_FLAGS, XL, env->xl);
- if (env->cur_pmmask < (env->xl == MXL_RV32 ? UINT32_MAX : UINT64_MAX)) {
+ if (env->cur_pmmask != 0) {
flags = FIELD_DP32(flags, TB_FLAGS, PM_MASK_ENABLED, 1);
}
if (env->cur_pmbase != 0) {
@@ -140,7 +146,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
void riscv_cpu_update_mask(CPURISCVState *env)
{
- target_ulong mask = -1, base = 0;
+ target_ulong mask = 0, base = 0;
/*
* TODO: Current RVJ spec does not specify
* how the extension interacts with XLEN.
@@ -688,39 +694,30 @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv)
*
* @env: CPURISCVState
* @prot: The returned protection attributes
- * @tlb_size: TLB page size containing addr. It could be modified after PMP
- * permission checking. NULL if not set TLB page for addr.
* @addr: The physical address to be checked permission
* @access_type: The type of MMU access
* @mode: Indicates current privilege level.
*/
-static int get_physical_address_pmp(CPURISCVState *env, int *prot,
- target_ulong *tlb_size, hwaddr addr,
+static int get_physical_address_pmp(CPURISCVState *env, int *prot, hwaddr addr,
int size, MMUAccessType access_type,
int mode)
{
pmp_priv_t pmp_priv;
- int pmp_index = -1;
+ bool pmp_has_privs;
if (!riscv_cpu_cfg(env)->pmp) {
*prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
return TRANSLATE_SUCCESS;
}
- pmp_index = pmp_hart_has_privs(env, addr, size, 1 << access_type,
- &pmp_priv, mode);
- if (pmp_index < 0) {
+ pmp_has_privs = pmp_hart_has_privs(env, addr, size, 1 << access_type,
+ &pmp_priv, mode);
+ if (!pmp_has_privs) {
*prot = 0;
return TRANSLATE_PMP_FAIL;
}
*prot = pmp_priv_to_page_prot(pmp_priv);
- if ((tlb_size != NULL) && pmp_index != MAX_RISCV_PMPS) {
- target_ulong tlb_sa = addr & ~(TARGET_PAGE_SIZE - 1);
- target_ulong tlb_ea = tlb_sa + TARGET_PAGE_SIZE - 1;
-
- *tlb_size = pmp_get_tlb_size(env, pmp_index, tlb_sa, tlb_ea);
- }
return TRANSLATE_SUCCESS;
}
@@ -909,7 +906,7 @@ restart:
}
int pmp_prot;
- int pmp_ret = get_physical_address_pmp(env, &pmp_prot, NULL, pte_addr,
+ int pmp_ret = get_physical_address_pmp(env, &pmp_prot, pte_addr,
sizeof(target_ulong),
MMU_DATA_LOAD, PRV_S);
if (pmp_ret != TRANSLATE_SUCCESS) {
@@ -1305,8 +1302,9 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
prot &= prot2;
if (ret == TRANSLATE_SUCCESS) {
- ret = get_physical_address_pmp(env, &prot_pmp, &tlb_size, pa,
+ ret = get_physical_address_pmp(env, &prot_pmp, pa,
size, access_type, mode);
+ tlb_size = pmp_get_tlb_size(env, pa);
qemu_log_mask(CPU_LOG_MMU,
"%s PMP address=" HWADDR_FMT_plx " ret %d prot"
@@ -1338,8 +1336,9 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
__func__, address, ret, pa, prot);
if (ret == TRANSLATE_SUCCESS) {
- ret = get_physical_address_pmp(env, &prot_pmp, &tlb_size, pa,
+ ret = get_physical_address_pmp(env, &prot_pmp, pa,
size, access_type, mode);
+ tlb_size = pmp_get_tlb_size(env, pa);
qemu_log_mask(CPU_LOG_MMU,
"%s PMP address=" HWADDR_FMT_plx " ret %d prot"
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 4451bd1263..58499b5afc 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -82,6 +82,10 @@ static RISCVException fs(CPURISCVState *env, int csrno)
!riscv_cpu_cfg(env)->ext_zfinx) {
return RISCV_EXCP_ILLEGAL_INST;
}
+
+ if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
+ return smstateen_acc_ok(env, 0, SMSTATEEN0_FCSR);
+ }
#endif
return RISCV_EXCP_NONE;
}
@@ -1324,8 +1328,15 @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno,
mstatus = set_field(mstatus, MSTATUS64_SXL, xl);
}
env->mstatus = mstatus;
- env->xl = cpu_recompute_xl(env);
+ /*
+ * Except in debug mode, UXL/SXL can only be modified by higher
+ * privilege mode. So xl will not be changed in normal mode.
+ */
+ if (env->debugger) {
+ env->xl = cpu_recompute_xl(env);
+ riscv_cpu_update_mask(env);
+ }
return RISCV_EXCP_NONE;
}
@@ -1387,39 +1398,18 @@ static RISCVException read_misa(CPURISCVState *env, int csrno,
static RISCVException write_misa(CPURISCVState *env, int csrno,
target_ulong val)
{
+ RISCVCPU *cpu = env_archcpu(env);
+ uint32_t orig_misa_ext = env->misa_ext;
+ Error *local_err = NULL;
+
if (!riscv_cpu_cfg(env)->misa_w) {
/* drop write to misa */
return RISCV_EXCP_NONE;
}
- /* 'I' or 'E' must be present */
- if (!(val & (RVI | RVE))) {
- /* It is not, drop write to misa */
- return RISCV_EXCP_NONE;
- }
-
- /* 'E' excludes all other extensions */
- if (val & RVE) {
- /*
- * when we support 'E' we can do "val = RVE;" however
- * for now we just drop writes if 'E' is present.
- */
- return RISCV_EXCP_NONE;
- }
-
- /*
- * misa.MXL writes are not supported by QEMU.
- * Drop writes to those bits.
- */
-
/* Mask extensions that are not supported by this hart */
val &= env->misa_ext_mask;
- /* 'D' depends on 'F', so clear 'D' if 'F' is not present */
- if ((val & RVD) && !(val & RVF)) {
- val &= ~RVD;
- }
-
/*
* Suppress 'C' if next instruction is not aligned
* TODO: this should check next_pc
@@ -1428,18 +1418,36 @@ static RISCVException write_misa(CPURISCVState *env, int csrno,
val &= ~RVC;
}
+ /* Disable RVG if any of its dependencies are disabled */
+ if (!(val & RVI && val & RVM && val & RVA &&
+ val & RVF && val & RVD)) {
+ val &= ~RVG;
+ }
+
/* If nothing changed, do nothing. */
if (val == env->misa_ext) {
return RISCV_EXCP_NONE;
}
- if (!(val & RVF)) {
+ env->misa_ext = val;
+ riscv_cpu_validate_set_extensions(cpu, &local_err);
+ if (local_err != NULL) {
+ /* Rollback on validation error */
+ qemu_log_mask(LOG_GUEST_ERROR, "Unable to write MISA ext value "
+ "0x%x, keeping existing MISA ext 0x%x\n",
+ env->misa_ext, orig_misa_ext);
+
+ env->misa_ext = orig_misa_ext;
+
+ return RISCV_EXCP_NONE;
+ }
+
+ if (!(env->misa_ext & RVF)) {
env->mstatus &= ~MSTATUS_FS;
}
/* flush translation cache */
tb_flush(env_cpu(env));
- env->misa_ext = val;
env->xl = riscv_cpu_mxl(env);
return RISCV_EXCP_NONE;
}
@@ -2100,6 +2108,9 @@ static RISCVException write_mstateen0(CPURISCVState *env, int csrno,
target_ulong new_val)
{
uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
+ if (!riscv_has_ext(env, RVF)) {
+ wr_mask |= SMSTATEEN0_FCSR;
+ }
return write_mstateen(env, csrno, wr_mask, new_val);
}
@@ -2173,6 +2184,10 @@ static RISCVException write_hstateen0(CPURISCVState *env, int csrno,
{
uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
+ if (!riscv_has_ext(env, RVF)) {
+ wr_mask |= SMSTATEEN0_FCSR;
+ }
+
return write_hstateen(env, csrno, wr_mask, new_val);
}
@@ -2259,6 +2274,10 @@ static RISCVException write_sstateen0(CPURISCVState *env, int csrno,
{
uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
+ if (!riscv_has_ext(env, RVF)) {
+ wr_mask |= SMSTATEEN0_FCSR;
+ }
+
return write_sstateen(env, csrno, wr_mask, new_val);
}
diff --git a/target/riscv/insn_trans/trans_privileged.c.inc b/target/riscv/insn_trans/trans_privileged.c.inc
index 528baa1652..dc14d7fc7a 100644
--- a/target/riscv/insn_trans/trans_privileged.c.inc
+++ b/target/riscv/insn_trans/trans_privileged.c.inc
@@ -108,7 +108,7 @@ static bool trans_wfi(DisasContext *ctx, arg_wfi *a)
{
#ifndef CONFIG_USER_ONLY
decode_save_opc(ctx);
- gen_set_pc_imm(ctx, ctx->pc_succ_insn);
+ gen_update_pc(ctx, ctx->cur_insn_len);
gen_helper_wfi(cpu_env);
return true;
#else
diff --git a/target/riscv/insn_trans/trans_rvd.c.inc b/target/riscv/insn_trans/trans_rvd.c.inc
index 2c51e01c40..6bdb55ef43 100644
--- a/target/riscv/insn_trans/trans_rvd.c.inc
+++ b/target/riscv/insn_trans/trans_rvd.c.inc
@@ -31,9 +31,11 @@
} \
} while (0)
-#define REQUIRE_ZCD(ctx) do { \
- if (!ctx->cfg_ptr->ext_zcd) { \
- return false; \
+#define REQUIRE_ZCD_OR_DC(ctx) do { \
+ if (!ctx->cfg_ptr->ext_zcd) { \
+ if (!has_ext(ctx, RVD) || !has_ext(ctx, RVC)) { \
+ return false; \
+ } \
} \
} while (0)
@@ -67,13 +69,13 @@ static bool trans_fsd(DisasContext *ctx, arg_fsd *a)
static bool trans_c_fld(DisasContext *ctx, arg_fld *a)
{
- REQUIRE_ZCD(ctx);
+ REQUIRE_ZCD_OR_DC(ctx);
return trans_fld(ctx, a);
}
static bool trans_c_fsd(DisasContext *ctx, arg_fsd *a)
{
- REQUIRE_ZCD(ctx);
+ REQUIRE_ZCD_OR_DC(ctx);
return trans_fsd(ctx, a);
}
diff --git a/target/riscv/insn_trans/trans_rvf.c.inc b/target/riscv/insn_trans/trans_rvf.c.inc
index b2de4fcf3f..a0da7391c7 100644
--- a/target/riscv/insn_trans/trans_rvf.c.inc
+++ b/target/riscv/insn_trans/trans_rvf.c.inc
@@ -19,9 +19,10 @@
*/
#define REQUIRE_FPU do {\
- if (ctx->mstatus_fs == EXT_STATUS_DISABLED) \
- if (!ctx->cfg_ptr->ext_zfinx) \
- return false; \
+ if (ctx->mstatus_fs == EXT_STATUS_DISABLED) { \
+ ctx->virt_inst_excp = ctx->virt_enabled && ctx->cfg_ptr->ext_zfinx; \
+ return false; \
+ } \
} while (0)
#define REQUIRE_ZFINX_OR_F(ctx) do {\
@@ -30,10 +31,12 @@
} \
} while (0)
-#define REQUIRE_ZCF(ctx) do { \
- if (!ctx->cfg_ptr->ext_zcf) { \
- return false; \
- } \
+#define REQUIRE_ZCF_OR_FC(ctx) do { \
+ if (!ctx->cfg_ptr->ext_zcf) { \
+ if (!has_ext(ctx, RVF) || !has_ext(ctx, RVC)) { \
+ return false; \
+ } \
+ } \
} while (0)
static bool trans_flw(DisasContext *ctx, arg_flw *a)
@@ -69,13 +72,13 @@ static bool trans_fsw(DisasContext *ctx, arg_fsw *a)
static bool trans_c_flw(DisasContext *ctx, arg_flw *a)
{
- REQUIRE_ZCF(ctx);
+ REQUIRE_ZCF_OR_FC(ctx);
return trans_flw(ctx, a);
}
static bool trans_c_fsw(DisasContext *ctx, arg_fsw *a)
{
- REQUIRE_ZCF(ctx);
+ REQUIRE_ZCF_OR_FC(ctx);
return trans_fsw(ctx, a);
}
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
index 2031e9931e..297142208e 100644
--- a/target/riscv/insn_trans/trans_rvi.c.inc
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
@@ -38,7 +38,9 @@ static bool trans_lui(DisasContext *ctx, arg_lui *a)
static bool trans_auipc(DisasContext *ctx, arg_auipc *a)
{
- gen_set_gpri(ctx, a->rd, a->imm + ctx->base.pc_next);
+ TCGv target_pc = dest_gpr(ctx, a->rd);
+ gen_pc_plus_diff(target_pc, ctx, a->imm);
+ gen_set_gpr(ctx, a->rd, target_pc);
return true;
}
@@ -51,25 +53,33 @@ static bool trans_jal(DisasContext *ctx, arg_jal *a)
static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
{
TCGLabel *misaligned = NULL;
+ TCGv target_pc = tcg_temp_new();
+ TCGv succ_pc = dest_gpr(ctx, a->rd);
- tcg_gen_addi_tl(cpu_pc, get_gpr(ctx, a->rs1, EXT_NONE), a->imm);
- tcg_gen_andi_tl(cpu_pc, cpu_pc, (target_ulong)-2);
+ tcg_gen_addi_tl(target_pc, get_gpr(ctx, a->rs1, EXT_NONE), a->imm);
+ tcg_gen_andi_tl(target_pc, target_pc, (target_ulong)-2);
- gen_set_pc(ctx, cpu_pc);
- if (!ctx->cfg_ptr->ext_zca) {
+ if (get_xl(ctx) == MXL_RV32) {
+ tcg_gen_ext32s_tl(target_pc, target_pc);
+ }
+
+ if (!has_ext(ctx, RVC) && !ctx->cfg_ptr->ext_zca) {
TCGv t0 = tcg_temp_new();
misaligned = gen_new_label();
- tcg_gen_andi_tl(t0, cpu_pc, 0x2);
+ tcg_gen_andi_tl(t0, target_pc, 0x2);
tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0x0, misaligned);
}
- gen_set_gpri(ctx, a->rd, ctx->pc_succ_insn);
+ gen_pc_plus_diff(succ_pc, ctx, ctx->cur_insn_len);
+ gen_set_gpr(ctx, a->rd, succ_pc);
+
+ tcg_gen_mov_tl(cpu_pc, target_pc);
lookup_and_goto_ptr(ctx);
if (misaligned) {
gen_set_label(misaligned);
- gen_exception_inst_addr_mis(ctx);
+ gen_exception_inst_addr_mis(ctx, target_pc);
}
ctx->base.is_jmp = DISAS_NORETURN;
@@ -153,6 +163,7 @@ static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond)
TCGLabel *l = gen_new_label();
TCGv src1 = get_gpr(ctx, a->rs1, EXT_SIGN);
TCGv src2 = get_gpr(ctx, a->rs2, EXT_SIGN);
+ target_ulong orig_pc_save = ctx->pc_save;
if (get_xl(ctx) == MXL_RV128) {
TCGv src1h = get_gprh(ctx, a->rs1);
@@ -165,16 +176,21 @@ static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond)
} else {
tcg_gen_brcond_tl(cond, src1, src2, l);
}
- gen_goto_tb(ctx, 1, ctx->pc_succ_insn);
+ gen_goto_tb(ctx, 1, ctx->cur_insn_len);
+ ctx->pc_save = orig_pc_save;
gen_set_label(l); /* branch taken */
- if (!ctx->cfg_ptr->ext_zca && ((ctx->base.pc_next + a->imm) & 0x3)) {
+ if (!has_ext(ctx, RVC) && !ctx->cfg_ptr->ext_zca &&
+ (a->imm & 0x3)) {
/* misaligned */
- gen_exception_inst_addr_mis(ctx);
+ TCGv target_pc = tcg_temp_new();
+ gen_pc_plus_diff(target_pc, ctx, a->imm);
+ gen_exception_inst_addr_mis(ctx, target_pc);
} else {
- gen_goto_tb(ctx, 0, ctx->base.pc_next + a->imm);
+ gen_goto_tb(ctx, 0, a->imm);
}
+ ctx->pc_save = -1;
ctx->base.is_jmp = DISAS_NORETURN;
return true;
@@ -767,7 +783,7 @@ static bool trans_pause(DisasContext *ctx, arg_pause *a)
* PAUSE is a no-op in QEMU,
* end the TB and return to main loop
*/
- gen_set_pc_imm(ctx, ctx->pc_succ_insn);
+ gen_update_pc(ctx, ctx->cur_insn_len);
exit_tb(ctx);
ctx->base.is_jmp = DISAS_NORETURN;
@@ -791,7 +807,7 @@ static bool trans_fence_i(DisasContext *ctx, arg_fence_i *a)
* FENCE_I is a no-op in QEMU,
* however we need to end the translation block
*/
- gen_set_pc_imm(ctx, ctx->pc_succ_insn);
+ gen_update_pc(ctx, ctx->cur_insn_len);
exit_tb(ctx);
ctx->base.is_jmp = DISAS_NORETURN;
return true;
@@ -802,7 +818,7 @@ static bool do_csr_post(DisasContext *ctx)
/* The helper may raise ILLEGAL_INSN -- record binv for unwind. */
decode_save_opc(ctx);
/* We may have changed important cpu state -- exit to main loop. */
- gen_set_pc_imm(ctx, ctx->pc_succ_insn);
+ gen_update_pc(ctx, ctx->cur_insn_len);
exit_tb(ctx);
ctx->base.is_jmp = DISAS_NORETURN;
return true;
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
index 6c07eebc52..c2f7527f53 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -169,7 +169,7 @@ static bool do_vsetvl(DisasContext *s, int rd, int rs1, TCGv s2)
gen_set_gpr(s, rd, dst);
mark_vs_dirty(s);
- gen_set_pc_imm(s, s->pc_succ_insn);
+ gen_update_pc(s, s->cur_insn_len);
lookup_and_goto_ptr(s);
s->base.is_jmp = DISAS_NORETURN;
return true;
@@ -188,7 +188,7 @@ static bool do_vsetivli(DisasContext *s, int rd, TCGv s1, TCGv s2)
gen_helper_vsetvl(dst, cpu_env, s1, s2);
gen_set_gpr(s, rd, dst);
mark_vs_dirty(s);
- gen_set_pc_imm(s, s->pc_succ_insn);
+ gen_update_pc(s, s->cur_insn_len);
lookup_and_goto_ptr(s);
s->base.is_jmp = DISAS_NORETURN;
diff --git a/target/riscv/insn_trans/trans_rvzawrs.c.inc b/target/riscv/insn_trans/trans_rvzawrs.c.inc
index 8254e7dfe2..32efbff4d5 100644
--- a/target/riscv/insn_trans/trans_rvzawrs.c.inc
+++ b/target/riscv/insn_trans/trans_rvzawrs.c.inc
@@ -33,7 +33,7 @@ static bool trans_wrs(DisasContext *ctx)
/* Clear the load reservation (if any). */
tcg_gen_movi_tl(load_res, -1);
- gen_set_pc_imm(ctx, ctx->pc_succ_insn);
+ gen_update_pc(ctx, ctx->cur_insn_len);
tcg_gen_exit_tb(NULL, 0);
ctx->base.is_jmp = DISAS_NORETURN;
diff --git a/target/riscv/insn_trans/trans_rvzce.c.inc b/target/riscv/insn_trans/trans_rvzce.c.inc
index a727169a4b..8d8a64f493 100644
--- a/target/riscv/insn_trans/trans_rvzce.c.inc
+++ b/target/riscv/insn_trans/trans_rvzce.c.inc
@@ -202,8 +202,8 @@ static bool gen_pop(DisasContext *ctx, arg_cmpp *a, bool ret, bool ret_val)
}
if (ret) {
- TCGv ret_addr = get_gpr(ctx, xRA, EXT_NONE);
- gen_set_pc(ctx, ret_addr);
+ TCGv ret_addr = get_gpr(ctx, xRA, EXT_SIGN);
+ tcg_gen_mov_tl(cpu_pc, ret_addr);
tcg_gen_lookup_and_goto_ptr();
ctx->base.is_jmp = DISAS_NORETURN;
}
@@ -297,12 +297,14 @@ static bool trans_cm_jalt(DisasContext *ctx, arg_cm_jalt *a)
* Update pc to current for the non-unwinding exception
* that might come from cpu_ld*_code() in the helper.
*/
- tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
+ gen_update_pc(ctx, 0);
gen_helper_cm_jalt(cpu_pc, cpu_env, tcg_constant_i32(a->index));
/* c.jt vs c.jalt depends on the index. */
if (a->index >= 32) {
- gen_set_gpri(ctx, xRA, ctx->pc_succ_insn);
+ TCGv succ_pc = dest_gpr(ctx, xRA);
+ gen_pc_plus_diff(succ_pc, ctx, ctx->cur_insn_len);
+ gen_set_gpr(ctx, xRA, succ_pc);
}
tcg_gen_lookup_and_goto_ptr();
diff --git a/target/riscv/insn_trans/trans_xthead.c.inc b/target/riscv/insn_trans/trans_xthead.c.inc
index 3e13b1d74d..da093a4cec 100644
--- a/target/riscv/insn_trans/trans_xthead.c.inc
+++ b/target/riscv/insn_trans/trans_xthead.c.inc
@@ -999,7 +999,7 @@ static void gen_th_sync_local(DisasContext *ctx)
* Emulate out-of-order barriers with pipeline flush
* by exiting the translation block.
*/
- gen_set_pc_imm(ctx, ctx->pc_succ_insn);
+ gen_update_pc(ctx, ctx->cur_insn_len);
tcg_gen_exit_tb(NULL, 0);
ctx->base.is_jmp = DISAS_NORETURN;
}
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
index 1f5aca42e8..9d8db493e6 100644
--- a/target/riscv/pmp.c
+++ b/target/riscv/pmp.c
@@ -26,10 +26,9 @@
#include "trace.h"
#include "exec/exec-all.h"
-static void pmp_write_cfg(CPURISCVState *env, uint32_t addr_index,
+static bool pmp_write_cfg(CPURISCVState *env, uint32_t addr_index,
uint8_t val);
static uint8_t pmp_read_cfg(CPURISCVState *env, uint32_t addr_index);
-static void pmp_update_rule(CPURISCVState *env, uint32_t pmp_index);
/*
* Accessor method to extract address matching type 'a field' from cfg reg
@@ -83,7 +82,7 @@ static inline uint8_t pmp_read_cfg(CPURISCVState *env, uint32_t pmp_index)
* Accessor to set the cfg reg for a specific PMP/HART
* Bounds checks and relevant lock bit.
*/
-static void pmp_write_cfg(CPURISCVState *env, uint32_t pmp_index, uint8_t val)
+static bool pmp_write_cfg(CPURISCVState *env, uint32_t pmp_index, uint8_t val)
{
if (pmp_index < MAX_RISCV_PMPS) {
bool locked = true;
@@ -119,14 +118,17 @@ static void pmp_write_cfg(CPURISCVState *env, uint32_t pmp_index, uint8_t val)
if (locked) {
qemu_log_mask(LOG_GUEST_ERROR, "ignoring pmpcfg write - locked\n");
- } else {
+ } else if (env->pmp_state.pmp[pmp_index].cfg_reg != val) {
env->pmp_state.pmp[pmp_index].cfg_reg = val;
- pmp_update_rule(env, pmp_index);
+ pmp_update_rule_addr(env, pmp_index);
+ return true;
}
} else {
qemu_log_mask(LOG_GUEST_ERROR,
"ignoring pmpcfg write - out of bounds\n");
}
+
+ return false;
}
static void pmp_decode_napot(target_ulong a, target_ulong *sa,
@@ -206,18 +208,6 @@ void pmp_update_rule_nums(CPURISCVState *env)
}
}
-/*
- * Convert cfg/addr reg values here into simple 'sa' --> start address and 'ea'
- * end address values.
- * This function is called relatively infrequently whereas the check that
- * an address is within a pmp rule is called often, so optimise that one
- */
-static void pmp_update_rule(CPURISCVState *env, uint32_t pmp_index)
-{
- pmp_update_rule_addr(env, pmp_index);
- pmp_update_rule_nums(env);
-}
-
static int pmp_is_in_range(CPURISCVState *env, int pmp_index,
target_ulong addr)
{
@@ -236,37 +226,34 @@ static int pmp_is_in_range(CPURISCVState *env, int pmp_index,
/*
* Check if the address has required RWX privs when no PMP entry is matched.
*/
-static bool pmp_hart_has_privs_default(CPURISCVState *env, target_ulong addr,
- target_ulong size, pmp_priv_t privs,
+static bool pmp_hart_has_privs_default(CPURISCVState *env, pmp_priv_t privs,
pmp_priv_t *allowed_privs,
target_ulong mode)
{
bool ret;
- if (riscv_cpu_cfg(env)->epmp) {
- if (MSECCFG_MMWP_ISSET(env)) {
- /*
- * The Machine Mode Whitelist Policy (mseccfg.MMWP) is set
- * so we default to deny all, even for M-mode.
- */
+ if (MSECCFG_MMWP_ISSET(env)) {
+ /*
+ * The Machine Mode Whitelist Policy (mseccfg.MMWP) is set
+ * so we default to deny all, even for M-mode.
+ */
+ *allowed_privs = 0;
+ return false;
+ } else if (MSECCFG_MML_ISSET(env)) {
+ /*
+ * The Machine Mode Lockdown (mseccfg.MML) bit is set
+ * so we can only execute code in M-mode with an applicable
+ * rule. Other modes are disabled.
+ */
+ if (mode == PRV_M && !(privs & PMP_EXEC)) {
+ ret = true;
+ *allowed_privs = PMP_READ | PMP_WRITE;
+ } else {
+ ret = false;
*allowed_privs = 0;
- return false;
- } else if (MSECCFG_MML_ISSET(env)) {
- /*
- * The Machine Mode Lockdown (mseccfg.MML) bit is set
- * so we can only execute code in M-mode with an applicable
- * rule. Other modes are disabled.
- */
- if (mode == PRV_M && !(privs & PMP_EXEC)) {
- ret = true;
- *allowed_privs = PMP_READ | PMP_WRITE;
- } else {
- ret = false;
- *allowed_privs = 0;
- }
-
- return ret;
}
+
+ return ret;
}
if (!riscv_cpu_cfg(env)->pmp || (mode == PRV_M)) {
@@ -296,26 +283,21 @@ static bool pmp_hart_has_privs_default(CPURISCVState *env, target_ulong addr,
/*
* Check if the address has required RWX privs to complete desired operation
- * Return PMP rule index if a pmp rule match
- * Return MAX_RISCV_PMPS if default match
- * Return negtive value if no match
+ * Return true if a pmp rule match or default match
+ * Return false if no match
*/
-int pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
- target_ulong size, pmp_priv_t privs,
- pmp_priv_t *allowed_privs, target_ulong mode)
+bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
+ target_ulong size, pmp_priv_t privs,
+ pmp_priv_t *allowed_privs, target_ulong mode)
{
int i = 0;
- int ret = -1;
int pmp_size = 0;
target_ulong s = 0;
target_ulong e = 0;
/* Short cut if no rules */
if (0 == pmp_get_num_rules(env)) {
- if (pmp_hart_has_privs_default(env, addr, size, privs,
- allowed_privs, mode)) {
- ret = MAX_RISCV_PMPS;
- }
+ return pmp_hart_has_privs_default(env, privs, allowed_privs, mode);
}
if (size == 0) {
@@ -344,8 +326,8 @@ int pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
if ((s + e) == 1) {
qemu_log_mask(LOG_GUEST_ERROR,
"pmp violation - access is partially inside\n");
- ret = -1;
- break;
+ *allowed_privs = 0;
+ return false;
}
/* fully inside */
@@ -452,20 +434,12 @@ int pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
* defined with PMP must be used. We shouldn't fallback on
* finding default privileges.
*/
- ret = i;
- break;
+ return (privs & *allowed_privs) == privs;
}
}
/* No rule matched */
- if (ret == -1) {
- if (pmp_hart_has_privs_default(env, addr, size, privs,
- allowed_privs, mode)) {
- ret = MAX_RISCV_PMPS;
- }
- }
-
- return ret;
+ return pmp_hart_has_privs_default(env, privs, allowed_privs, mode);
}
/*
@@ -477,16 +451,20 @@ void pmpcfg_csr_write(CPURISCVState *env, uint32_t reg_index,
int i;
uint8_t cfg_val;
int pmpcfg_nums = 2 << riscv_cpu_mxl(env);
+ bool modified = false;
trace_pmpcfg_csr_write(env->mhartid, reg_index, val);
for (i = 0; i < pmpcfg_nums; i++) {
cfg_val = (val >> 8 * i) & 0xff;
- pmp_write_cfg(env, (reg_index * 4) + i, cfg_val);
+ modified |= pmp_write_cfg(env, (reg_index * 4) + i, cfg_val);
}
/* If PMP permission of any addr has been changed, flush TLB pages. */
- tlb_flush(env_cpu(env));
+ if (modified) {
+ pmp_update_rule_nums(env);
+ tlb_flush(env_cpu(env));
+ }
}
@@ -517,6 +495,7 @@ void pmpaddr_csr_write(CPURISCVState *env, uint32_t addr_index,
target_ulong val)
{
trace_pmpaddr_csr_write(env->mhartid, addr_index, val);
+ bool is_next_cfg_tor = false;
if (addr_index < MAX_RISCV_PMPS) {
/*
@@ -525,9 +504,9 @@ void pmpaddr_csr_write(CPURISCVState *env, uint32_t addr_index,
*/
if (addr_index + 1 < MAX_RISCV_PMPS) {
uint8_t pmp_cfg = env->pmp_state.pmp[addr_index + 1].cfg_reg;
+ is_next_cfg_tor = PMP_AMATCH_TOR == pmp_get_a_field(pmp_cfg);
- if (pmp_cfg & PMP_LOCK &&
- PMP_AMATCH_TOR == pmp_get_a_field(pmp_cfg)) {
+ if (pmp_cfg & PMP_LOCK && is_next_cfg_tor) {
qemu_log_mask(LOG_GUEST_ERROR,
"ignoring pmpaddr write - pmpcfg + 1 locked\n");
return;
@@ -535,8 +514,14 @@ void pmpaddr_csr_write(CPURISCVState *env, uint32_t addr_index,
}
if (!pmp_is_locked(env, addr_index)) {
- env->pmp_state.pmp[addr_index].addr_reg = val;
- pmp_update_rule(env, addr_index);
+ if (env->pmp_state.pmp[addr_index].addr_reg != val) {
+ env->pmp_state.pmp[addr_index].addr_reg = val;
+ pmp_update_rule_addr(env, addr_index);
+ if (is_next_cfg_tor) {
+ pmp_update_rule_addr(env, addr_index + 1);
+ }
+ tlb_flush(env_cpu(env));
+ }
} else {
qemu_log_mask(LOG_GUEST_ERROR,
"ignoring pmpaddr write - locked\n");
@@ -585,8 +570,15 @@ void mseccfg_csr_write(CPURISCVState *env, target_ulong val)
}
}
- /* Sticky bits */
- val |= (env->mseccfg & (MSECCFG_MMWP | MSECCFG_MML));
+ if (riscv_cpu_cfg(env)->epmp) {
+ /* Sticky bits */
+ val |= (env->mseccfg & (MSECCFG_MMWP | MSECCFG_MML));
+ if ((val ^ env->mseccfg) & (MSECCFG_MMWP | MSECCFG_MML)) {
+ tlb_flush(env_cpu(env));
+ }
+ } else {
+ val &= ~(MSECCFG_MMWP | MSECCFG_MML | MSECCFG_RLB);
+ }
env->mseccfg = val;
}
@@ -601,28 +593,67 @@ target_ulong mseccfg_csr_read(CPURISCVState *env)
}
/*
- * Calculate the TLB size if the start address or the end address of
- * PMP entry is presented in the TLB page.
+ * Calculate the TLB size.
+ * It's possible that PMP regions only cover partial of the TLB page, and
+ * this may split the page into regions with different permissions.
+ * For example if PMP0 is (0x80000008~0x8000000F, R) and PMP1 is (0x80000000
+ * ~0x80000FFF, RWX), then region 0x80000008~0x8000000F has R permission, and
+ * the other regions in this page have RWX permissions.
+ * A write access to 0x80000000 will match PMP1. However we cannot cache the
+ * translation result in the TLB since this will make the write access to
+ * 0x80000008 bypass the check of PMP0.
+ * To avoid this we return a size of 1 (which means no caching) if the PMP
+ * region only covers partial of the TLB page.
*/
-target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index,
- target_ulong tlb_sa, target_ulong tlb_ea)
+target_ulong pmp_get_tlb_size(CPURISCVState *env, target_ulong addr)
{
- target_ulong pmp_sa = env->pmp_state.addr[pmp_index].sa;
- target_ulong pmp_ea = env->pmp_state.addr[pmp_index].ea;
+ target_ulong pmp_sa;
+ target_ulong pmp_ea;
+ target_ulong tlb_sa = addr & ~(TARGET_PAGE_SIZE - 1);
+ target_ulong tlb_ea = tlb_sa + TARGET_PAGE_SIZE - 1;
+ int i;
- if (pmp_sa <= tlb_sa && pmp_ea >= tlb_ea) {
+ /*
+ * If PMP is not supported or there are no PMP rules, the TLB page will not
+ * be split into regions with different permissions by PMP so we set the
+ * size to TARGET_PAGE_SIZE.
+ */
+ if (!riscv_cpu_cfg(env)->pmp || !pmp_get_num_rules(env)) {
return TARGET_PAGE_SIZE;
- } else {
+ }
+
+ for (i = 0; i < MAX_RISCV_PMPS; i++) {
+ if (pmp_get_a_field(env->pmp_state.pmp[i].cfg_reg) == PMP_AMATCH_OFF) {
+ continue;
+ }
+
+ pmp_sa = env->pmp_state.addr[i].sa;
+ pmp_ea = env->pmp_state.addr[i].ea;
+
/*
- * At this point we have a tlb_size that is the smallest possible size
- * That fits within a TARGET_PAGE_SIZE and the PMP region.
- *
- * If the size is less then TARGET_PAGE_SIZE we drop the size to 1.
- * This means the result isn't cached in the TLB and is only used for
- * a single translation.
+ * Only the first PMP entry that covers (whole or partial of) the TLB
+ * page really matters:
+ * If it covers the whole TLB page, set the size to TARGET_PAGE_SIZE,
+ * since the following PMP entries have lower priority and will not
+ * affect the permissions of the page.
+ * If it only covers partial of the TLB page, set the size to 1 since
+ * the allowed permissions of the region may be different from other
+ * region of the page.
*/
- return 1;
+ if (pmp_sa <= tlb_sa && pmp_ea >= tlb_ea) {
+ return TARGET_PAGE_SIZE;
+ } else if ((pmp_sa >= tlb_sa && pmp_sa <= tlb_ea) ||
+ (pmp_ea >= tlb_sa && pmp_ea <= tlb_ea)) {
+ return 1;
+ }
}
+
+ /*
+ * If no PMP entry matches the TLB page, the TLB page will also not be
+ * split into regions with different permissions by PMP so we set the size
+ * to TARGET_PAGE_SIZE.
+ */
+ return TARGET_PAGE_SIZE;
}
/*
diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h
index b296ea1fc6..cf5c99f8e6 100644
--- a/target/riscv/pmp.h
+++ b/target/riscv/pmp.h
@@ -72,12 +72,11 @@ target_ulong mseccfg_csr_read(CPURISCVState *env);
void pmpaddr_csr_write(CPURISCVState *env, uint32_t addr_index,
target_ulong val);
target_ulong pmpaddr_csr_read(CPURISCVState *env, uint32_t addr_index);
-int pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
- target_ulong size, pmp_priv_t privs,
- pmp_priv_t *allowed_privs,
- target_ulong mode);
-target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index,
- target_ulong tlb_sa, target_ulong tlb_ea);
+bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
+ target_ulong size, pmp_priv_t privs,
+ pmp_priv_t *allowed_privs,
+ target_ulong mode);
+target_ulong pmp_get_tlb_size(CPURISCVState *env, target_ulong addr);
void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index);
void pmp_update_rule_nums(CPURISCVState *env);
uint32_t pmp_get_num_rules(CPURISCVState *env);
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 933b11c50d..8a33da811e 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -59,8 +59,8 @@ typedef enum {
typedef struct DisasContext {
DisasContextBase base;
- /* pc_succ_insn points to the instruction following base.pc_next */
- target_ulong pc_succ_insn;
+ target_ulong cur_insn_len;
+ target_ulong pc_save;
target_ulong priv_ver;
RISCVMXL misa_mxl_max;
RISCVMXL xl;
@@ -224,26 +224,34 @@ static void decode_save_opc(DisasContext *ctx)
ctx->insn_start = NULL;
}
-static void gen_set_pc_imm(DisasContext *ctx, target_ulong dest)
+static void gen_pc_plus_diff(TCGv target, DisasContext *ctx,
+ target_long diff)
{
- if (get_xl(ctx) == MXL_RV32) {
- dest = (int32_t)dest;
+ target_ulong dest = ctx->base.pc_next + diff;
+
+ assert(ctx->pc_save != -1);
+ if (tb_cflags(ctx->base.tb) & CF_PCREL) {
+ tcg_gen_addi_tl(target, cpu_pc, dest - ctx->pc_save);
+ if (get_xl(ctx) == MXL_RV32) {
+ tcg_gen_ext32s_tl(target, target);
+ }
+ } else {
+ if (get_xl(ctx) == MXL_RV32) {
+ dest = (int32_t)dest;
+ }
+ tcg_gen_movi_tl(target, dest);
}
- tcg_gen_movi_tl(cpu_pc, dest);
}
-static void gen_set_pc(DisasContext *ctx, TCGv dest)
+static void gen_update_pc(DisasContext *ctx, target_long diff)
{
- if (get_xl(ctx) == MXL_RV32) {
- tcg_gen_ext32s_tl(cpu_pc, dest);
- } else {
- tcg_gen_mov_tl(cpu_pc, dest);
- }
+ gen_pc_plus_diff(cpu_pc, ctx, diff);
+ ctx->pc_save = ctx->base.pc_next + diff;
}
static void generate_exception(DisasContext *ctx, int excp)
{
- gen_set_pc_imm(ctx, ctx->base.pc_next);
+ gen_update_pc(ctx, 0);
gen_helper_raise_exception(cpu_env, tcg_constant_i32(excp));
ctx->base.is_jmp = DISAS_NORETURN;
}
@@ -259,9 +267,9 @@ static void gen_exception_illegal(DisasContext *ctx)
}
}
-static void gen_exception_inst_addr_mis(DisasContext *ctx)
+static void gen_exception_inst_addr_mis(DisasContext *ctx, TCGv target)
{
- tcg_gen_st_tl(cpu_pc, cpu_env, offsetof(CPURISCVState, badaddr));
+ tcg_gen_st_tl(target, cpu_env, offsetof(CPURISCVState, badaddr));
generate_exception(ctx, RISCV_EXCP_INST_ADDR_MIS);
}
@@ -285,18 +293,33 @@ static void exit_tb(DisasContext *ctx)
tcg_gen_exit_tb(NULL, 0);
}
-static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
+static void gen_goto_tb(DisasContext *ctx, int n, target_long diff)
{
+ target_ulong dest = ctx->base.pc_next + diff;
+
/*
* Under itrigger, instruction executes one by one like singlestep,
* direct block chain benefits will be small.
*/
if (translator_use_goto_tb(&ctx->base, dest) && !ctx->itrigger) {
- tcg_gen_goto_tb(n);
- gen_set_pc_imm(ctx, dest);
+ /*
+ * For pcrel, the pc must always be up-to-date on entry to
+ * the linked TB, so that it can use simple additions for all
+ * further adjustments. For !pcrel, the linked TB is compiled
+ * to know its full virtual address, so we can delay the
+ * update to pc to the unlinked path. A long chain of links
+ * can thus avoid many updates to the PC.
+ */
+ if (tb_cflags(ctx->base.tb) & CF_PCREL) {
+ gen_update_pc(ctx, diff);
+ tcg_gen_goto_tb(n);
+ } else {
+ tcg_gen_goto_tb(n);
+ gen_update_pc(ctx, diff);
+ }
tcg_gen_exit_tb(ctx->base.tb, n);
} else {
- gen_set_pc_imm(ctx, dest);
+ gen_update_pc(ctx, diff);
lookup_and_goto_ptr(ctx);
}
}
@@ -547,19 +570,22 @@ static void gen_set_fpr_d(DisasContext *ctx, int reg_num, TCGv_i64 t)
static void gen_jal(DisasContext *ctx, int rd, target_ulong imm)
{
- target_ulong next_pc;
+ TCGv succ_pc = dest_gpr(ctx, rd);
/* check misaligned: */
- next_pc = ctx->base.pc_next + imm;
- if (!ctx->cfg_ptr->ext_zca) {
- if ((next_pc & 0x3) != 0) {
- gen_exception_inst_addr_mis(ctx);
+ if (!has_ext(ctx, RVC) && !ctx->cfg_ptr->ext_zca) {
+ if ((imm & 0x3) != 0) {
+ TCGv target_pc = tcg_temp_new();
+ gen_pc_plus_diff(target_pc, ctx, imm);
+ gen_exception_inst_addr_mis(ctx, target_pc);
return;
}
}
- gen_set_gpri(ctx, rd, ctx->pc_succ_insn);
- gen_goto_tb(ctx, 0, ctx->base.pc_next + imm); /* must use this for safety */
+ gen_pc_plus_diff(succ_pc, ctx, ctx->cur_insn_len);
+ gen_set_gpr(ctx, rd, succ_pc);
+
+ gen_goto_tb(ctx, 0, imm); /* must use this for safety */
ctx->base.is_jmp = DISAS_NORETURN;
}
@@ -1117,15 +1143,16 @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
};
ctx->virt_inst_excp = false;
+ ctx->cur_insn_len = insn_len(opcode);
/* Check for compressed insn */
- if (insn_len(opcode) == 2) {
+ if (ctx->cur_insn_len == 2) {
ctx->opcode = opcode;
- ctx->pc_succ_insn = ctx->base.pc_next + 2;
/*
* The Zca extension is added as way to refer to instructions in the C
* extension that do not include the floating-point loads and stores
*/
- if (ctx->cfg_ptr->ext_zca && decode_insn16(ctx, opcode)) {
+ if ((has_ext(ctx, RVC) || ctx->cfg_ptr->ext_zca) &&
+ decode_insn16(ctx, opcode)) {
return;
}
} else {
@@ -1134,7 +1161,6 @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
translator_lduw(env, &ctx->base,
ctx->base.pc_next + 2));
ctx->opcode = opcode32;
- ctx->pc_succ_insn = ctx->base.pc_next + 4;
for (size_t i = 0; i < ARRAY_SIZE(decoders); ++i) {
if (decoders[i].guard_func(ctx) &&
@@ -1154,7 +1180,7 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
RISCVCPU *cpu = RISCV_CPU(cs);
uint32_t tb_flags = ctx->base.tb->flags;
- ctx->pc_succ_insn = ctx->base.pc_first;
+ ctx->pc_save = ctx->base.pc_first;
ctx->priv = FIELD_EX32(tb_flags, TB_FLAGS, PRIV);
ctx->mem_idx = FIELD_EX32(tb_flags, TB_FLAGS, MEM_IDX);
ctx->mstatus_fs = FIELD_EX32(tb_flags, TB_FLAGS, FS);
@@ -1189,8 +1215,13 @@ static void riscv_tr_tb_start(DisasContextBase *db, CPUState *cpu)
static void riscv_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
{
DisasContext *ctx = container_of(dcbase, DisasContext, base);
+ target_ulong pc_next = ctx->base.pc_next;
+
+ if (tb_cflags(dcbase->tb) & CF_PCREL) {
+ pc_next &= ~TARGET_PAGE_MASK;
+ }
- tcg_gen_insn_start(ctx->base.pc_next, 0);
+ tcg_gen_insn_start(pc_next, 0);
ctx->insn_start = tcg_last_op();
}
@@ -1202,7 +1233,7 @@ static void riscv_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
ctx->ol = ctx->xl;
decode_opc(env, ctx, opcode16);
- ctx->base.pc_next = ctx->pc_succ_insn;
+ ctx->base.pc_next += ctx->cur_insn_len;
/* Only the first insn within a TB is allowed to cross a page boundary. */
if (ctx->base.is_jmp == DISAS_NEXT) {
@@ -1229,7 +1260,7 @@ static void riscv_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
switch (ctx->base.is_jmp) {
case DISAS_TOO_MANY:
- gen_goto_tb(ctx, 0, ctx->base.pc_next);
+ gen_goto_tb(ctx, 0, 0);
break;
case DISAS_NORETURN:
break;
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index f4d0438988..1e06e7447c 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -169,7 +169,7 @@ static inline uint32_t vext_get_total_elems(CPURISCVState *env, uint32_t desc,
static inline target_ulong adjust_addr(CPURISCVState *env, target_ulong addr)
{
- return (addr & env->cur_pmmask) | env->cur_pmbase;
+ return (addr & ~env->cur_pmmask) | env->cur_pmbase;
}
/*
@@ -264,26 +264,21 @@ GEN_VEXT_ST_ELEM(ste_h, int16_t, H2, stw)
GEN_VEXT_ST_ELEM(ste_w, int32_t, H4, stl)
GEN_VEXT_ST_ELEM(ste_d, int64_t, H8, stq)
-static void vext_set_tail_elems_1s(CPURISCVState *env, target_ulong vl,
- void *vd, uint32_t desc, uint32_t nf,
+static void vext_set_tail_elems_1s(target_ulong vl, void *vd,
+ uint32_t desc, uint32_t nf,
uint32_t esz, uint32_t max_elems)
{
- uint32_t total_elems = vext_get_total_elems(env, desc, esz);
- uint32_t vlenb = riscv_cpu_cfg(env)->vlen >> 3;
uint32_t vta = vext_vta(desc);
- uint32_t registers_used;
int k;
+ if (vta == 0) {
+ return;
+ }
+
for (k = 0; k < nf; ++k) {
vext_set_elems_1s(vd, vta, (k * max_elems + vl) * esz,
(k * max_elems + max_elems) * esz);
}
-
- if (nf * max_elems % total_elems != 0) {
- registers_used = ((nf * max_elems) * esz + (vlenb - 1)) / vlenb;
- vext_set_elems_1s(vd, vta, (nf * max_elems) * esz,
- registers_used * vlenb);
- }
}
/*
@@ -319,7 +314,7 @@ vext_ldst_stride(void *vd, void *v0, target_ulong base,
}
env->vstart = 0;
- vext_set_tail_elems_1s(env, env->vl, vd, desc, nf, esz, max_elems);
+ vext_set_tail_elems_1s(env->vl, vd, desc, nf, esz, max_elems);
}
#define GEN_VEXT_LD_STRIDE(NAME, ETYPE, LOAD_FN) \
@@ -378,12 +373,12 @@ vext_ldst_us(void *vd, target_ulong base, CPURISCVState *env, uint32_t desc,
}
env->vstart = 0;
- vext_set_tail_elems_1s(env, evl, vd, desc, nf, esz, max_elems);
+ vext_set_tail_elems_1s(evl, vd, desc, nf, esz, max_elems);
}
/*
* masked unit-stride load and store operation will be a special case of
- * stride, stride = NF * sizeof (MTYPE)
+ * stride, stride = NF * sizeof (ETYPE)
*/
#define GEN_VEXT_LD_US(NAME, ETYPE, LOAD_FN) \
@@ -499,7 +494,7 @@ vext_ldst_index(void *vd, void *v0, target_ulong base,
}
env->vstart = 0;
- vext_set_tail_elems_1s(env, env->vl, vd, desc, nf, esz, max_elems);
+ vext_set_tail_elems_1s(env->vl, vd, desc, nf, esz, max_elems);
}
#define GEN_VEXT_LD_INDEX(NAME, ETYPE, INDEX_FN, LOAD_FN) \
@@ -629,7 +624,7 @@ ProbeSuccess:
}
env->vstart = 0;
- vext_set_tail_elems_1s(env, env->vl, vd, desc, nf, esz, max_elems);
+ vext_set_tail_elems_1s(env->vl, vd, desc, nf, esz, max_elems);
}
#define GEN_VEXT_LDFF(NAME, ETYPE, LOAD_FN) \
@@ -655,10 +650,6 @@ GEN_VEXT_LDFF(vle64ff_v, int64_t, lde_d)
#define DO_MAX(N, M) ((N) >= (M) ? (N) : (M))
#define DO_MIN(N, M) ((N) >= (M) ? (M) : (N))
-/* Unsigned min/max */
-#define DO_MAXU(N, M) DO_MAX((UMTYPE)N, (UMTYPE)M)
-#define DO_MINU(N, M) DO_MIN((UMTYPE)N, (UMTYPE)M)
-
/*
* load and store whole register instructions
*/
diff --git a/util/log.c b/util/log.c
index 53b4f6c58e..def88a9402 100644
--- a/util/log.c
+++ b/util/log.c
@@ -495,6 +495,8 @@ const QEMULogItem qemu_log_items[] = {
"log every user-mode syscall, its input, and its result" },
{ LOG_PER_THREAD, "tid",
"open a separate log file per thread; filename must contain '%d'" },
+ { CPU_LOG_TB_VPU, "vpu",
+ "include VPU registers in the 'cpu' logging" },
{ 0, NULL, NULL },
};