aboutsummaryrefslogtreecommitdiff
path: root/target
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2021-06-08 13:54:23 +0100
committerPeter Maydell <peter.maydell@linaro.org>2021-06-08 13:54:23 +0100
commita4716fd8d7c877185652f5f8e25032dc7699d51b (patch)
treeb89e4cabdf30fb88a514c243522028c5719ed681 /target
parent33ba8b0adc91482dd4247a0773cfe7def011933f (diff)
parentd2c1a177b138be35cb96216baa870c3564b123e4 (diff)
downloadqemu-a4716fd8d7c877185652f5f8e25032dc7699d51b.zip
qemu-a4716fd8d7c877185652f5f8e25032dc7699d51b.tar.gz
qemu-a4716fd8d7c877185652f5f8e25032dc7699d51b.tar.bz2
Merge remote-tracking branch 'remotes/alistair/tags/pull-riscv-to-apply-20210608-1' into staging
Second RISC-V PR for QEMU 6.1 - Update the PLIC and CLINT DT bindings - Improve documentation for RISC-V machines - Support direct kernel boot for microchip_pfsoc - Fix WFI exception behaviour - Improve CSR printing - Initial support for the experimental Bit Manip extension # gpg: Signature made Tue 08 Jun 2021 01:28:27 BST # gpg: using RSA key F6C4AC46D4934868D3B8CE8F21E10D29DF977054 # gpg: Good signature from "Alistair Francis <alistair@alistair23.me>" [full] # Primary key fingerprint: F6C4 AC46 D493 4868 D3B8 CE8F 21E1 0D29 DF97 7054 * remotes/alistair/tags/pull-riscv-to-apply-20210608-1: (32 commits) target/riscv: rvb: add b-ext version cpu option target/riscv: rvb: support and turn on B-extension from command line target/riscv: rvb: add/shift with prefix zero-extend target/riscv: rvb: address calculation target/riscv: rvb: generalized or-combine target/riscv: rvb: generalized reverse target/riscv: rvb: rotate (left/right) target/riscv: rvb: shift ones target/riscv: rvb: single-bit instructions target/riscv: add gen_shifti() and gen_shiftiw() helper functions target/riscv: rvb: sign-extend instructions target/riscv: rvb: min/max instructions target/riscv: rvb: pack two words into one register target/riscv: rvb: logic-with-negate target/riscv: rvb: count bits set target/riscv: rvb: count leading/trailing zeros target/riscv: reformat @sh format encoding for B-extension target/riscv: Pass the same value to oprsz and maxsz. target/riscv/pmp: Add assert for ePMP operations target/riscv: Dump CSR mscratch/sscratch/satp ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target')
-rw-r--r--target/riscv/bitmanip_helper.c90
-rw-r--r--target/riscv/cpu.c38
-rw-r--r--target/riscv/cpu.h7
-rw-r--r--target/riscv/cpu_bits.h1
-rw-r--r--target/riscv/helper.h6
-rw-r--r--target/riscv/insn32.decode87
-rw-r--r--target/riscv/insn_trans/trans_rvb.c.inc438
-rw-r--r--target/riscv/insn_trans/trans_rvi.c.inc54
-rw-r--r--target/riscv/insn_trans/trans_rvv.c.inc89
-rw-r--r--target/riscv/meson.build1
-rw-r--r--target/riscv/op_helper.c11
-rw-r--r--target/riscv/pmp.c4
-rw-r--r--target/riscv/translate.c306
13 files changed, 1028 insertions, 104 deletions
diff --git a/target/riscv/bitmanip_helper.c b/target/riscv/bitmanip_helper.c
new file mode 100644
index 0000000..5b2f795
--- /dev/null
+++ b/target/riscv/bitmanip_helper.c
@@ -0,0 +1,90 @@
+/*
+ * RISC-V Bitmanip Extension Helpers for QEMU.
+ *
+ * Copyright (c) 2020 Kito Cheng, kito.cheng@sifive.com
+ * Copyright (c) 2020 Frank Chang, frank.chang@sifive.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/host-utils.h"
+#include "exec/exec-all.h"
+#include "exec/helper-proto.h"
+#include "tcg/tcg.h"
+
+static const uint64_t adjacent_masks[] = {
+ dup_const(MO_8, 0x55),
+ dup_const(MO_8, 0x33),
+ dup_const(MO_8, 0x0f),
+ dup_const(MO_16, 0xff),
+ dup_const(MO_32, 0xffff),
+ UINT32_MAX
+};
+
+static inline target_ulong do_swap(target_ulong x, uint64_t mask, int shift)
+{
+ return ((x & mask) << shift) | ((x & ~mask) >> shift);
+}
+
+static target_ulong do_grev(target_ulong rs1,
+ target_ulong rs2,
+ int bits)
+{
+ target_ulong x = rs1;
+ int i, shift;
+
+ for (i = 0, shift = 1; shift < bits; i++, shift <<= 1) {
+ if (rs2 & shift) {
+ x = do_swap(x, adjacent_masks[i], shift);
+ }
+ }
+
+ return x;
+}
+
+target_ulong HELPER(grev)(target_ulong rs1, target_ulong rs2)
+{
+ return do_grev(rs1, rs2, TARGET_LONG_BITS);
+}
+
+target_ulong HELPER(grevw)(target_ulong rs1, target_ulong rs2)
+{
+ return do_grev(rs1, rs2, 32);
+}
+
+static target_ulong do_gorc(target_ulong rs1,
+ target_ulong rs2,
+ int bits)
+{
+ target_ulong x = rs1;
+ int i, shift;
+
+ for (i = 0, shift = 1; shift < bits; i++, shift <<= 1) {
+ if (rs2 & shift) {
+ x |= do_swap(x, adjacent_masks[i], shift);
+ }
+ }
+
+ return x;
+}
+
+target_ulong HELPER(gorc)(target_ulong rs1, target_ulong rs2)
+{
+ return do_gorc(rs1, rs2, TARGET_LONG_BITS);
+}
+
+target_ulong HELPER(gorcw)(target_ulong rs1, target_ulong rs2)
+{
+ return do_gorc(rs1, rs2, 32);
+}
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 1f1cef1..991a6bb 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -51,7 +51,7 @@ const char * const riscv_fpr_regnames[] = {
"f30/ft10", "f31/ft11"
};
-const char * const riscv_excp_names[] = {
+static const char * const riscv_excp_names[] = {
"misaligned_fetch",
"fault_fetch",
"illegal_instruction",
@@ -78,7 +78,7 @@ const char * const riscv_excp_names[] = {
"guest_store_page_fault",
};
-const char * const riscv_intr_names[] = {
+static const char * const riscv_intr_names[] = {
"u_software",
"s_software",
"vs_software",
@@ -127,6 +127,11 @@ static void set_priv_version(CPURISCVState *env, int priv_ver)
env->priv_ver = priv_ver;
}
+static void set_bext_version(CPURISCVState *env, int bext_ver)
+{
+ env->bext_ver = bext_ver;
+}
+
static void set_vext_version(CPURISCVState *env, int vext_ver)
{
env->vext_ver = vext_ver;
@@ -286,12 +291,15 @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags)
if (riscv_has_ext(env, RVH)) {
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "vscause ", env->vscause);
}
- qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mtval ", env->mtval);
- qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "stval ", env->stval);
+ qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mtval ", env->mtval);
+ qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "stval ", env->stval);
if (riscv_has_ext(env, RVH)) {
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "htval ", env->htval);
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mtval2 ", env->mtval2);
}
+ qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mscratch", env->mscratch);
+ qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "sscratch", env->sscratch);
+ qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "satp ", env->satp);
#endif
for (i = 0; i < 32; i++) {
@@ -385,6 +393,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
CPURISCVState *env = &cpu->env;
RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev);
int priv_version = PRIV_VERSION_1_11_0;
+ int bext_version = BEXT_VERSION_0_93_0;
int vext_version = VEXT_VERSION_0_07_1;
target_ulong target_misa = env->misa;
Error *local_err = NULL;
@@ -409,6 +418,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
}
set_priv_version(env, priv_version);
+ set_bext_version(env, bext_version);
set_vext_version(env, vext_version);
if (cpu->cfg.mmu) {
@@ -486,6 +496,24 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
if (cpu->cfg.ext_h) {
target_misa |= RVH;
}
+ if (cpu->cfg.ext_b) {
+ target_misa |= RVB;
+
+ if (cpu->cfg.bext_spec) {
+ if (!g_strcmp0(cpu->cfg.bext_spec, "v0.93")) {
+ bext_version = BEXT_VERSION_0_93_0;
+ } else {
+ error_setg(errp,
+ "Unsupported bitmanip spec version '%s'",
+ cpu->cfg.bext_spec);
+ return;
+ }
+ } else {
+ qemu_log("bitmanip version is not specified, "
+ "use the default value v0.93\n");
+ }
+ set_bext_version(env, bext_version);
+ }
if (cpu->cfg.ext_v) {
target_misa |= RVV;
if (!is_power_of_2(cpu->cfg.vlen)) {
@@ -556,12 +584,14 @@ static Property riscv_cpu_properties[] = {
DEFINE_PROP_BOOL("s", RISCVCPU, cfg.ext_s, true),
DEFINE_PROP_BOOL("u", RISCVCPU, cfg.ext_u, true),
/* This is experimental so mark with 'x-' */
+ DEFINE_PROP_BOOL("x-b", RISCVCPU, cfg.ext_b, false),
DEFINE_PROP_BOOL("x-h", RISCVCPU, cfg.ext_h, false),
DEFINE_PROP_BOOL("x-v", RISCVCPU, cfg.ext_v, false),
DEFINE_PROP_BOOL("Counters", RISCVCPU, cfg.ext_counters, true),
DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
DEFINE_PROP_STRING("priv_spec", RISCVCPU, cfg.priv_spec),
+ DEFINE_PROP_STRING("bext_spec", RISCVCPU, cfg.bext_spec),
DEFINE_PROP_STRING("vext_spec", RISCVCPU, cfg.vext_spec),
DEFINE_PROP_UINT16("vlen", RISCVCPU, cfg.vlen, 128),
DEFINE_PROP_UINT16("elen", RISCVCPU, cfg.elen, 64),
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 0619b49..bf1c899 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -67,6 +67,7 @@
#define RVS RV('S')
#define RVU RV('U')
#define RVH RV('H')
+#define RVB RV('B')
/* S extension denotes that Supervisor mode exists, however it is possible
to have a core that support S mode but does not have an MMU and there
@@ -82,6 +83,7 @@ enum {
#define PRIV_VERSION_1_10_0 0x00011000
#define PRIV_VERSION_1_11_0 0x00011100
+#define BEXT_VERSION_0_93_0 0x00009300
#define VEXT_VERSION_0_07_1 0x00000701
enum {
@@ -131,6 +133,7 @@ struct CPURISCVState {
target_ulong guest_phys_fault_addr;
target_ulong priv_ver;
+ target_ulong bext_ver;
target_ulong vext_ver;
target_ulong misa;
target_ulong misa_mask;
@@ -285,6 +288,7 @@ struct RISCVCPU {
bool ext_f;
bool ext_d;
bool ext_c;
+ bool ext_b;
bool ext_s;
bool ext_u;
bool ext_h;
@@ -295,6 +299,7 @@ struct RISCVCPU {
char *priv_spec;
char *user_spec;
+ char *bext_spec;
char *vext_spec;
uint16_t vlen;
uint16_t elen;
@@ -320,8 +325,6 @@ static inline bool riscv_feature(CPURISCVState *env, int feature)
extern const char * const riscv_int_regnames[];
extern const char * const riscv_fpr_regnames[];
-extern const char * const riscv_excp_names[];
-extern const char * const riscv_intr_names[];
const char *riscv_cpu_get_trap_name(target_ulong cause, bool async);
void riscv_cpu_do_interrupt(CPUState *cpu);
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 52640e6..7330ff5 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -390,6 +390,7 @@
#define HSTATUS_HU 0x00000200
#define HSTATUS_VGEIN 0x0003F000
#define HSTATUS_VTVM 0x00100000
+#define HSTATUS_VTW 0x00200000
#define HSTATUS_VTSR 0x00400000
#define HSTATUS_VSXL 0x300000000
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index c726759..415e37b 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -58,6 +58,12 @@ DEF_HELPER_FLAGS_2(fcvt_d_l, TCG_CALL_NO_RWG, i64, env, tl)
DEF_HELPER_FLAGS_2(fcvt_d_lu, TCG_CALL_NO_RWG, i64, env, tl)
DEF_HELPER_FLAGS_1(fclass_d, TCG_CALL_NO_RWG_SE, tl, i64)
+/* Bitmanip */
+DEF_HELPER_FLAGS_2(grev, TCG_CALL_NO_RWG_SE, tl, tl, tl)
+DEF_HELPER_FLAGS_2(grevw, TCG_CALL_NO_RWG_SE, tl, tl, tl)
+DEF_HELPER_FLAGS_2(gorc, TCG_CALL_NO_RWG_SE, tl, tl, tl)
+DEF_HELPER_FLAGS_2(gorcw, TCG_CALL_NO_RWG_SE, tl, tl, tl)
+
/* Special functions */
DEF_HELPER_3(csrrw, tl, env, tl, tl)
DEF_HELPER_4(csrrs, tl, env, tl, tl, tl)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 8901ba1..f09f8d5 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -23,7 +23,7 @@
%rd 7:5
%sh5 20:5
-%sh10 20:10
+%sh7 20:7
%csr 20:12
%rm 12:3
%nf 29:3 !function=ex_plus_1
@@ -41,6 +41,7 @@
&i imm rs1 rd
&j imm rd
&r rd rs1 rs2
+&r2 rd rs1
&s imm rs1 rs2
&u imm rd
&shift shamt rs1 rd
@@ -59,7 +60,7 @@
@u .................... ..... ....... &u imm=%imm_u %rd
@j .................... ..... ....... &j imm=%imm_j %rd
-@sh ...... ...... ..... ... ..... ....... &shift shamt=%sh10 %rs1 %rd
+@sh ...... ...... ..... ... ..... ....... &shift shamt=%sh7 %rs1 %rd
@csr ............ ..... ... ..... ....... %csr %rs1 %rd
@atom_ld ..... aq:1 rl:1 ..... ........ ..... ....... &atomic rs2=0 %rs1 %rd
@@ -68,7 +69,7 @@
@r4_rm ..... .. ..... ..... ... ..... ....... %rs3 %rs2 %rs1 %rm %rd
@r_rm ....... ..... ..... ... ..... ....... %rs2 %rs1 %rm %rd
@r2_rm ....... ..... ..... ... ..... ....... %rs1 %rm %rd
-@r2 ....... ..... ..... ... ..... ....... %rs1 %rd
+@r2 ....... ..... ..... ... ..... ....... &r2 %rs1 %rd
@r2_nfvm ... ... vm:1 ..... ..... ... ..... ....... &r2nfvm %nf %rs1 %rd
@r2_vm ...... vm:1 ..... ..... ... ..... ....... &rmr %rs2 %rd
@r1_vm ...... vm:1 ..... ..... ... ..... ....... %rd
@@ -125,9 +126,9 @@ sltiu ............ ..... 011 ..... 0010011 @i
xori ............ ..... 100 ..... 0010011 @i
ori ............ ..... 110 ..... 0010011 @i
andi ............ ..... 111 ..... 0010011 @i
-slli 00.... ...... ..... 001 ..... 0010011 @sh
-srli 00.... ...... ..... 101 ..... 0010011 @sh
-srai 01.... ...... ..... 101 ..... 0010011 @sh
+slli 00000. ...... ..... 001 ..... 0010011 @sh
+srli 00000. ...... ..... 101 ..... 0010011 @sh
+srai 01000. ...... ..... 101 ..... 0010011 @sh
add 0000000 ..... ..... 000 ..... 0110011 @r
sub 0100000 ..... ..... 000 ..... 0110011 @r
sll 0000000 ..... ..... 001 ..... 0110011 @r
@@ -657,3 +658,77 @@ vamomind_v 10000 . . ..... ..... 111 ..... 0101111 @r_wdvm
vamomaxd_v 10100 . . ..... ..... 111 ..... 0101111 @r_wdvm
vamominud_v 11000 . . ..... ..... 111 ..... 0101111 @r_wdvm
vamomaxud_v 11100 . . ..... ..... 111 ..... 0101111 @r_wdvm
+
+# *** RV32B Standard Extension ***
+clz 011000 000000 ..... 001 ..... 0010011 @r2
+ctz 011000 000001 ..... 001 ..... 0010011 @r2
+cpop 011000 000010 ..... 001 ..... 0010011 @r2
+sext_b 011000 000100 ..... 001 ..... 0010011 @r2
+sext_h 011000 000101 ..... 001 ..... 0010011 @r2
+
+andn 0100000 .......... 111 ..... 0110011 @r
+orn 0100000 .......... 110 ..... 0110011 @r
+xnor 0100000 .......... 100 ..... 0110011 @r
+pack 0000100 .......... 100 ..... 0110011 @r
+packu 0100100 .......... 100 ..... 0110011 @r
+packh 0000100 .......... 111 ..... 0110011 @r
+min 0000101 .......... 100 ..... 0110011 @r
+minu 0000101 .......... 101 ..... 0110011 @r
+max 0000101 .......... 110 ..... 0110011 @r
+maxu 0000101 .......... 111 ..... 0110011 @r
+bset 0010100 .......... 001 ..... 0110011 @r
+bclr 0100100 .......... 001 ..... 0110011 @r
+binv 0110100 .......... 001 ..... 0110011 @r
+bext 0100100 .......... 101 ..... 0110011 @r
+slo 0010000 .......... 001 ..... 0110011 @r
+sro 0010000 .......... 101 ..... 0110011 @r
+ror 0110000 .......... 101 ..... 0110011 @r
+rol 0110000 .......... 001 ..... 0110011 @r
+grev 0110100 .......... 101 ..... 0110011 @r
+gorc 0010100 .......... 101 ..... 0110011 @r
+sh1add 0010000 .......... 010 ..... 0110011 @r
+sh2add 0010000 .......... 100 ..... 0110011 @r
+sh3add 0010000 .......... 110 ..... 0110011 @r
+
+bseti 00101. ........... 001 ..... 0010011 @sh
+bclri 01001. ........... 001 ..... 0010011 @sh
+binvi 01101. ........... 001 ..... 0010011 @sh
+bexti 01001. ........... 101 ..... 0010011 @sh
+sloi 00100. ........... 001 ..... 0010011 @sh
+sroi 00100. ........... 101 ..... 0010011 @sh
+rori 01100. ........... 101 ..... 0010011 @sh
+grevi 01101. ........... 101 ..... 0010011 @sh
+gorci 00101. ........... 101 ..... 0010011 @sh
+
+# *** RV64B Standard Extension (in addition to RV32B) ***
+clzw 0110000 00000 ..... 001 ..... 0011011 @r2
+ctzw 0110000 00001 ..... 001 ..... 0011011 @r2
+cpopw 0110000 00010 ..... 001 ..... 0011011 @r2
+
+packw 0000100 .......... 100 ..... 0111011 @r
+packuw 0100100 .......... 100 ..... 0111011 @r
+bsetw 0010100 .......... 001 ..... 0111011 @r
+bclrw 0100100 .......... 001 ..... 0111011 @r
+binvw 0110100 .......... 001 ..... 0111011 @r
+bextw 0100100 .......... 101 ..... 0111011 @r
+slow 0010000 .......... 001 ..... 0111011 @r
+srow 0010000 .......... 101 ..... 0111011 @r
+rorw 0110000 .......... 101 ..... 0111011 @r
+rolw 0110000 .......... 001 ..... 0111011 @r
+grevw 0110100 .......... 101 ..... 0111011 @r
+gorcw 0010100 .......... 101 ..... 0111011 @r
+sh1add_uw 0010000 .......... 010 ..... 0111011 @r
+sh2add_uw 0010000 .......... 100 ..... 0111011 @r
+sh3add_uw 0010000 .......... 110 ..... 0111011 @r
+add_uw 0000100 .......... 000 ..... 0111011 @r
+
+bsetiw 0010100 .......... 001 ..... 0011011 @sh5
+bclriw 0100100 .......... 001 ..... 0011011 @sh5
+binviw 0110100 .......... 001 ..... 0011011 @sh5
+sloiw 0010000 .......... 001 ..... 0011011 @sh5
+sroiw 0010000 .......... 101 ..... 0011011 @sh5
+roriw 0110000 .......... 101 ..... 0011011 @sh5
+greviw 0110100 .......... 101 ..... 0011011 @sh5
+gorciw 0010100 .......... 101 ..... 0011011 @sh5
+
+slli_uw 00001. ........... 001 ..... 0011011 @sh
diff --git a/target/riscv/insn_trans/trans_rvb.c.inc b/target/riscv/insn_trans/trans_rvb.c.inc
new file mode 100644
index 0000000..9e81f6e
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rvb.c.inc
@@ -0,0 +1,438 @@
+/*
+ * RISC-V translation routines for the RVB Standard Extension.
+ *
+ * Copyright (c) 2020 Kito Cheng, kito.cheng@sifive.com
+ * Copyright (c) 2020 Frank Chang, frank.chang@sifive.com
+ *
+ * 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/>.
+ */
+
+static bool trans_clz(DisasContext *ctx, arg_clz *a)
+{
+ REQUIRE_EXT(ctx, RVB);
+ return gen_unary(ctx, a, gen_clz);
+}
+
+static bool trans_ctz(DisasContext *ctx, arg_ctz *a)
+{
+ REQUIRE_EXT(ctx, RVB);
+ return gen_unary(ctx, a, gen_ctz);
+}
+
+static bool trans_cpop(DisasContext *ctx, arg_cpop *a)
+{
+ REQUIRE_EXT(ctx, RVB);
+ return gen_unary(ctx, a, tcg_gen_ctpop_tl);
+}
+
+static bool trans_andn(DisasContext *ctx, arg_andn *a)
+{
+ REQUIRE_EXT(ctx, RVB);
+ return gen_arith(ctx, a, tcg_gen_andc_tl);
+}
+
+static bool trans_orn(DisasContext *ctx, arg_orn *a)
+{
+ REQUIRE_EXT(ctx, RVB);
+ return gen_arith(ctx, a, tcg_gen_orc_tl);
+}
+
+static bool trans_xnor(DisasContext *ctx, arg_xnor *a)
+{
+ REQUIRE_EXT(ctx, RVB);
+ return gen_arith(ctx, a, tcg_gen_eqv_tl);
+}
+
+static bool trans_pack(DisasContext *ctx, arg_pack *a)
+{
+ REQUIRE_EXT(ctx, RVB);
+ return gen_arith(ctx, a, gen_pack);
+}
+
+static bool trans_packu(DisasContext *ctx, arg_packu *a)
+{
+ REQUIRE_EXT(ctx, RVB);
+ return gen_arith(ctx, a, gen_packu);
+}
+
+static bool trans_packh(DisasContext *ctx, arg_packh *a)
+{
+ REQUIRE_EXT(ctx, RVB);
+ return gen_arith(ctx, a, gen_packh);
+}
+
+static bool trans_min(DisasContext *ctx, arg_min *a)
+{
+ REQUIRE_EXT(ctx, RVB);
+ return gen_arith(ctx, a, tcg_gen_smin_tl);
+}
+
+static bool trans_max(DisasContext *ctx, arg_max *a)
+{
+ REQUIRE_EXT(ctx, RVB);
+ return gen_arith(ctx, a, tcg_gen_smax_tl);
+}
+
+static bool trans_minu(DisasContext *ctx, arg_minu *a)
+{
+ REQUIRE_EXT(ctx, RVB);
+ return gen_arith(ctx, a, tcg_gen_umin_tl);
+}
+
+static bool trans_maxu(DisasContext *ctx, arg_maxu *a)
+{
+ REQUIRE_EXT(ctx, RVB);
+ return gen_arith(ctx, a, tcg_gen_umax_tl);
+}
+
+static bool trans_sext_b(DisasContext *ctx, arg_sext_b *a)
+{
+ REQUIRE_EXT(ctx, RVB);
+ return gen_unary(ctx, a, tcg_gen_ext8s_tl);
+}
+
+static bool trans_sext_h(DisasContext *ctx, arg_sext_h *a)
+{
+ REQUIRE_EXT(ctx, RVB);
+ return gen_unary(ctx, a, tcg_gen_ext16s_tl);
+}
+
+static bool trans_bset(DisasContext *ctx, arg_bset *a)
+{
+ REQUIRE_EXT(ctx, RVB);
+ return gen_shift(ctx, a, gen_bset);
+}
+
+static bool trans_bseti(DisasContext *ctx, arg_bseti *a)
+{
+ REQUIRE_EXT(ctx, RVB);
+ return gen_shifti(ctx, a, gen_bset);
+}
+
+static bool trans_bclr(DisasContext *ctx, arg_bclr *a)
+{
+ REQUIRE_EXT(ctx, RVB);
+ return gen_shift(ctx, a, gen_bclr);
+}
+
+static bool trans_bclri(DisasContext *ctx, arg_bclri *a)
+{
+ REQUIRE_EXT(ctx, RVB);
+ return gen_shifti(ctx, a, gen_bclr);
+}
+
+static bool trans_binv(DisasContext *ctx, arg_binv *a)
+{
+ REQUIRE_EXT(ctx, RVB);
+ return gen_shift(ctx, a, gen_binv);
+}
+
+static bool trans_binvi(DisasContext *ctx, arg_binvi *a)
+{
+ REQUIRE_EXT(ctx, RVB);
+ return gen_shifti(ctx, a, gen_binv);
+}
+
+static bool trans_bext(DisasContext *ctx, arg_bext *a)
+{
+ REQUIRE_EXT(ctx, RVB);
+ return gen_shift(ctx, a, gen_bext);
+}
+
+static bool trans_bexti(DisasContext *ctx, arg_bexti *a)
+{
+ REQUIRE_EXT(ctx, RVB);
+ return gen_shifti(ctx, a, gen_bext);
+}
+
+static bool trans_slo(DisasContext *ctx, arg_slo *a)
+{
+ REQUIRE_EXT(ctx, RVB);
+ return gen_shift(ctx, a, gen_slo);
+}
+
+static bool trans_sloi(DisasContext *ctx, arg_sloi *a)
+{
+ REQUIRE_EXT(ctx, RVB);
+ return gen_shifti(ctx, a, gen_slo);
+}
+
+static bool trans_sro(DisasContext *ctx, arg_sro *a)
+{
+ REQUIRE_EXT(ctx, RVB);
+ return gen_shift(ctx, a, gen_sro);
+}
+
+static bool trans_sroi(DisasContext *ctx, arg_sroi *a)
+{
+ REQUIRE_EXT(ctx, RVB);
+ return gen_shifti(ctx, a, gen_sro);
+}
+
+static bool trans_ror(DisasContext *ctx, arg_ror *a)
+{
+ REQUIRE_EXT(ctx, RVB);
+ return gen_shift(ctx, a, tcg_gen_rotr_tl);
+}
+
+static bool trans_rori(DisasContext *ctx, arg_rori *a)
+{
+ REQUIRE_EXT(ctx, RVB);
+ return gen_shifti(ctx, a, tcg_gen_rotr_tl);
+}
+
+static bool trans_rol(DisasContext *ctx, arg_rol *a)
+{
+ REQUIRE_EXT(ctx, RVB);
+ return gen_shift(ctx, a, tcg_gen_rotl_tl);
+}
+
+static bool trans_grev(DisasContext *ctx, arg_grev *a)
+{
+ REQUIRE_EXT(ctx, RVB);
+ return gen_shift(ctx, a, gen_helper_grev);
+}
+
+static bool trans_grevi(DisasContext *ctx, arg_grevi *a)
+{
+ REQUIRE_EXT(ctx, RVB);
+
+ if (a->shamt >= TARGET_LONG_BITS) {
+ return false;
+ }
+
+ return gen_grevi(ctx, a);
+}
+
+static bool trans_gorc(DisasContext *ctx, arg_gorc *a)
+{
+ REQUIRE_EXT(ctx, RVB);
+ return gen_shift(ctx, a, gen_helper_gorc);
+}
+
+static bool trans_gorci(DisasContext *ctx, arg_gorci *a)
+{
+ REQUIRE_EXT(ctx, RVB);
+ return gen_shifti(ctx, a, gen_helper_gorc);
+}
+
+#define GEN_TRANS_SHADD(SHAMT) \
+static bool trans_sh##SHAMT##add(DisasContext *ctx, arg_sh##SHAMT##add *a) \
+{ \
+ REQUIRE_EXT(ctx, RVB); \
+ return gen_arith(ctx, a, gen_sh##SHAMT##add); \
+}
+
+GEN_TRANS_SHADD(1)
+GEN_TRANS_SHADD(2)
+GEN_TRANS_SHADD(3)
+
+static bool trans_clzw(DisasContext *ctx, arg_clzw *a)
+{
+ REQUIRE_64BIT(ctx);
+ REQUIRE_EXT(ctx, RVB);
+ return gen_unary(ctx, a, gen_clzw);
+}
+
+static bool trans_ctzw(DisasContext *ctx, arg_ctzw *a)
+{
+ REQUIRE_64BIT(ctx);
+ REQUIRE_EXT(ctx, RVB);
+ return gen_unary(ctx, a, gen_ctzw);
+}
+
+static bool trans_cpopw(DisasContext *ctx, arg_cpopw *a)
+{
+ REQUIRE_64BIT(ctx);
+ REQUIRE_EXT(ctx, RVB);
+ return gen_unary(ctx, a, gen_cpopw);
+}
+
+static bool trans_packw(DisasContext *ctx, arg_packw *a)
+{
+ REQUIRE_64BIT(ctx);
+ REQUIRE_EXT(ctx, RVB);
+ return gen_arith(ctx, a, gen_packw);
+}
+
+static bool trans_packuw(DisasContext *ctx, arg_packuw *a)
+{
+ REQUIRE_64BIT(ctx);
+ REQUIRE_EXT(ctx, RVB);
+ return gen_arith(ctx, a, gen_packuw);
+}
+
+static bool trans_bsetw(DisasContext *ctx, arg_bsetw *a)
+{
+ REQUIRE_64BIT(ctx);
+ REQUIRE_EXT(ctx, RVB);
+ return gen_shiftw(ctx, a, gen_bset);
+}
+
+static bool trans_bsetiw(DisasContext *ctx, arg_bsetiw *a)
+{
+ REQUIRE_64BIT(ctx);
+ REQUIRE_EXT(ctx, RVB);
+ return gen_shiftiw(ctx, a, gen_bset);
+}
+
+static bool trans_bclrw(DisasContext *ctx, arg_bclrw *a)
+{
+ REQUIRE_64BIT(ctx);
+ REQUIRE_EXT(ctx, RVB);
+ return gen_shiftw(ctx, a, gen_bclr);
+}
+
+static bool trans_bclriw(DisasContext *ctx, arg_bclriw *a)
+{
+ REQUIRE_64BIT(ctx);
+ REQUIRE_EXT(ctx, RVB);
+ return gen_shiftiw(ctx, a, gen_bclr);
+}
+
+static bool trans_binvw(DisasContext *ctx, arg_binvw *a)
+{
+ REQUIRE_64BIT(ctx);
+ REQUIRE_EXT(ctx, RVB);
+ return gen_shiftw(ctx, a, gen_binv);
+}
+
+static bool trans_binviw(DisasContext *ctx, arg_binviw *a)
+{
+ REQUIRE_64BIT(ctx);
+ REQUIRE_EXT(ctx, RVB);
+ return gen_shiftiw(ctx, a, gen_binv);
+}
+
+static bool trans_bextw(DisasContext *ctx, arg_bextw *a)
+{
+ REQUIRE_64BIT(ctx);
+ REQUIRE_EXT(ctx, RVB);
+ return gen_shiftw(ctx, a, gen_bext);
+}
+
+static bool trans_slow(DisasContext *ctx, arg_slow *a)
+{
+ REQUIRE_64BIT(ctx);
+ REQUIRE_EXT(ctx, RVB);
+ return gen_shiftw(ctx, a, gen_slo);
+}
+
+static bool trans_sloiw(DisasContext *ctx, arg_sloiw *a)
+{
+ REQUIRE_64BIT(ctx);
+ REQUIRE_EXT(ctx, RVB);
+ return gen_shiftiw(ctx, a, gen_slo);
+}
+
+static bool trans_srow(DisasContext *ctx, arg_srow *a)
+{
+ REQUIRE_64BIT(ctx);
+ REQUIRE_EXT(ctx, RVB);
+ return gen_shiftw(ctx, a, gen_sro);
+}
+
+static bool trans_sroiw(DisasContext *ctx, arg_sroiw *a)
+{
+ REQUIRE_64BIT(ctx);
+ REQUIRE_EXT(ctx, RVB);
+ return gen_shiftiw(ctx, a, gen_sro);
+}
+
+static bool trans_rorw(DisasContext *ctx, arg_rorw *a)
+{
+ REQUIRE_64BIT(ctx);
+ REQUIRE_EXT(ctx, RVB);
+ return gen_shiftw(ctx, a, gen_rorw);
+}
+
+static bool trans_roriw(DisasContext *ctx, arg_roriw *a)
+{
+ REQUIRE_64BIT(ctx);
+ REQUIRE_EXT(ctx, RVB);
+ return gen_shiftiw(ctx, a, gen_rorw);
+}
+
+static bool trans_rolw(DisasContext *ctx, arg_rolw *a)
+{
+ REQUIRE_64BIT(ctx);
+ REQUIRE_EXT(ctx, RVB);
+ return gen_shiftw(ctx, a, gen_rolw);
+}
+
+static bool trans_grevw(DisasContext *ctx, arg_grevw *a)
+{
+ REQUIRE_64BIT(ctx);
+ REQUIRE_EXT(ctx, RVB);
+ return gen_shiftw(ctx, a, gen_grevw);
+}
+
+static bool trans_greviw(DisasContext *ctx, arg_greviw *a)
+{
+ REQUIRE_64BIT(ctx);
+ REQUIRE_EXT(ctx, RVB);
+ return gen_shiftiw(ctx, a, gen_grevw);
+}
+
+static bool trans_gorcw(DisasContext *ctx, arg_gorcw *a)
+{
+ REQUIRE_64BIT(ctx);
+ REQUIRE_EXT(ctx, RVB);
+ return gen_shiftw(ctx, a, gen_gorcw);
+}
+
+static bool trans_gorciw(DisasContext *ctx, arg_gorciw *a)
+{
+ REQUIRE_64BIT(ctx);
+ REQUIRE_EXT(ctx, RVB);
+ return gen_shiftiw(ctx, a, gen_gorcw);
+}
+
+#define GEN_TRANS_SHADD_UW(SHAMT) \
+static bool trans_sh##SHAMT##add_uw(DisasContext *ctx, \
+ arg_sh##SHAMT##add_uw *a) \
+{ \
+ REQUIRE_64BIT(ctx); \
+ REQUIRE_EXT(ctx, RVB); \
+ return gen_arith(ctx, a, gen_sh##SHAMT##add_uw); \
+}
+
+GEN_TRANS_SHADD_UW(1)
+GEN_TRANS_SHADD_UW(2)
+GEN_TRANS_SHADD_UW(3)
+
+static bool trans_add_uw(DisasContext *ctx, arg_add_uw *a)
+{
+ REQUIRE_64BIT(ctx);
+ REQUIRE_EXT(ctx, RVB);
+ return gen_arith(ctx, a, gen_add_uw);
+}
+
+static bool trans_slli_uw(DisasContext *ctx, arg_slli_uw *a)
+{
+ REQUIRE_64BIT(ctx);
+ REQUIRE_EXT(ctx, RVB);
+
+ TCGv source1 = tcg_temp_new();
+ gen_get_gpr(source1, a->rs1);
+
+ if (a->shamt < 32) {
+ tcg_gen_deposit_z_tl(source1, source1, a->shamt, 32);
+ } else {
+ tcg_gen_shli_tl(source1, source1, a->shamt);
+ }
+
+ gen_set_gpr(a->rd, source1);
+ tcg_temp_free(source1);
+ return true;
+}
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
index bd93f63..6e736c9 100644
--- a/target/riscv/insn_trans/trans_rvi.c.inc
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
@@ -268,54 +268,17 @@ static bool trans_andi(DisasContext *ctx, arg_andi *a)
}
static bool trans_slli(DisasContext *ctx, arg_slli *a)
{
- if (a->shamt >= TARGET_LONG_BITS) {
- return false;
- }
-
- if (a->rd != 0) {
- TCGv t = tcg_temp_new();
- gen_get_gpr(t, a->rs1);
-
- tcg_gen_shli_tl(t, t, a->shamt);
-
- gen_set_gpr(a->rd, t);
- tcg_temp_free(t);
- } /* NOP otherwise */
- return true;
+ return gen_shifti(ctx, a, tcg_gen_shl_tl);
}
static bool trans_srli(DisasContext *ctx, arg_srli *a)
{
- if (a->shamt >= TARGET_LONG_BITS) {
- return false;
- }
-
- if (a->rd != 0) {
- TCGv t = tcg_temp_new();
- gen_get_gpr(t, a->rs1);
-
- tcg_gen_shri_tl(t, t, a->shamt);
- gen_set_gpr(a->rd, t);
- tcg_temp_free(t);
- } /* NOP otherwise */
- return true;
+ return gen_shifti(ctx, a, tcg_gen_shr_tl);
}
static bool trans_srai(DisasContext *ctx, arg_srai *a)
{
- if (a->shamt >= TARGET_LONG_BITS) {
- return false;
- }
-
- if (a->rd != 0) {
- TCGv t = tcg_temp_new();
- gen_get_gpr(t, a->rs1);
-
- tcg_gen_sari_tl(t, t, a->shamt);
- gen_set_gpr(a->rd, t);
- tcg_temp_free(t);
- } /* NOP otherwise */
- return true;
+ return gen_shifti(ctx, a, tcg_gen_sar_tl);
}
static bool trans_add(DisasContext *ctx, arg_add *a)
@@ -377,16 +340,7 @@ static bool trans_addiw(DisasContext *ctx, arg_addiw *a)
static bool trans_slliw(DisasContext *ctx, arg_slliw *a)
{
REQUIRE_64BIT(ctx);
- TCGv source1;
- source1 = tcg_temp_new();
- gen_get_gpr(source1, a->rs1);
-
- tcg_gen_shli_tl(source1, source1, a->shamt);
- tcg_gen_ext32s_tl(source1, source1);
- gen_set_gpr(a->rd, source1);
-
- tcg_temp_free(source1);
- return true;
+ return gen_shiftiw(ctx, a, tcg_gen_shl_tl);
}
static bool trans_srliw(DisasContext *ctx, arg_srliw *a)
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
index 47914a3..83d9a28 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -183,7 +183,7 @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data,
* The first part is vlen in bytes, encoded in maxsz of simd_desc.
* The second part is lmul, encoded in data of simd_desc.
*/
- desc = tcg_const_i32(simd_desc(0, s->vlen / 8, data));
+ desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
gen_get_gpr(base, rs1);
tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
@@ -334,7 +334,7 @@ static bool ldst_stride_trans(uint32_t vd, uint32_t rs1, uint32_t rs2,
mask = tcg_temp_new_ptr();
base = tcg_temp_new();
stride = tcg_temp_new();
- desc = tcg_const_i32(simd_desc(0, s->vlen / 8, data));
+ desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
gen_get_gpr(base, rs1);
gen_get_gpr(stride, rs2);
@@ -462,7 +462,7 @@ static bool ldst_index_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
mask = tcg_temp_new_ptr();
index = tcg_temp_new_ptr();
base = tcg_temp_new();
- desc = tcg_const_i32(simd_desc(0, s->vlen / 8, data));
+ desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
gen_get_gpr(base, rs1);
tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
@@ -594,7 +594,7 @@ static bool ldff_trans(uint32_t vd, uint32_t rs1, uint32_t data,
dest = tcg_temp_new_ptr();
mask = tcg_temp_new_ptr();
base = tcg_temp_new();
- desc = tcg_const_i32(simd_desc(0, s->vlen / 8, data));
+ desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
gen_get_gpr(base, rs1);
tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
@@ -671,7 +671,7 @@ static bool amo_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
mask = tcg_temp_new_ptr();
index = tcg_temp_new_ptr();
base = tcg_temp_new();
- desc = tcg_const_i32(simd_desc(0, s->vlen / 8, data));
+ desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
gen_get_gpr(base, rs1);
tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
@@ -831,7 +831,7 @@ do_opivv_gvec(DisasContext *s, arg_rmrr *a, GVecGen3Fn *gvec_fn,
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),
vreg_ofs(s, a->rs1), vreg_ofs(s, a->rs2),
- cpu_env, 0, s->vlen / 8, data, fn);
+ cpu_env, s->vlen / 8, s->vlen / 8, data, fn);
}
gen_set_label(over);
return true;
@@ -874,7 +874,7 @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, uint32_t vm,
data = FIELD_DP32(data, VDATA, MLEN, s->mlen);
data = FIELD_DP32(data, VDATA, VM, vm);
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
- desc = tcg_const_i32(simd_desc(0, s->vlen / 8, data));
+ desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, vs2));
@@ -1021,7 +1021,7 @@ static bool opivi_trans(uint32_t vd, uint32_t imm, uint32_t vs2, uint32_t vm,
data = FIELD_DP32(data, VDATA, MLEN, s->mlen);
data = FIELD_DP32(data, VDATA, VM, vm);
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
- desc = tcg_const_i32(simd_desc(0, s->vlen / 8, data));
+ desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, vs2));
@@ -1119,7 +1119,7 @@ static bool do_opivv_widen(DisasContext *s, arg_rmrr *a,
tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),
vreg_ofs(s, a->rs1),
vreg_ofs(s, a->rs2),
- cpu_env, 0, s->vlen / 8,
+ cpu_env, s->vlen / 8, s->vlen / 8,
data, fn);
gen_set_label(over);
return true;
@@ -1207,7 +1207,7 @@ static bool do_opiwv_widen(DisasContext *s, arg_rmrr *a,
tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),
vreg_ofs(s, a->rs1),
vreg_ofs(s, a->rs2),
- cpu_env, 0, s->vlen / 8, data, fn);
+ cpu_env, s->vlen / 8, s->vlen / 8, data, fn);
gen_set_label(over);
return true;
}
@@ -1284,8 +1284,9 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
vreg_ofs(s, a->rs1), \
- vreg_ofs(s, a->rs2), cpu_env, 0, \
- s->vlen / 8, data, fns[s->sew]); \
+ vreg_ofs(s, a->rs2), cpu_env, \
+ s->vlen / 8, s->vlen / 8, data, \
+ fns[s->sew]); \
gen_set_label(over); \
return true; \
} \
@@ -1473,8 +1474,9 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
vreg_ofs(s, a->rs1), \
- vreg_ofs(s, a->rs2), cpu_env, 0, \
- s->vlen / 8, data, fns[s->sew]); \
+ vreg_ofs(s, a->rs2), cpu_env, \
+ s->vlen / 8, s->vlen / 8, data, \
+ fns[s->sew]); \
gen_set_label(over); \
return true; \
} \
@@ -1690,7 +1692,7 @@ static bool trans_vmv_v_x(DisasContext *s, arg_vmv_v_x *a)
};
tcg_gen_ext_tl_i64(s1_i64, s1);
- desc = tcg_const_i32(simd_desc(0, s->vlen / 8, data));
+ desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, a->rd));
fns[s->sew](dest, s1_i64, cpu_env, desc);
@@ -1729,7 +1731,7 @@ static bool trans_vmv_v_i(DisasContext *s, arg_vmv_v_i *a)
s1 = tcg_const_i64(simm);
dest = tcg_temp_new_ptr();
- desc = tcg_const_i32(simd_desc(0, s->vlen / 8, data));
+ desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, a->rd));
fns[s->sew](dest, s1, cpu_env, desc);
@@ -1838,8 +1840,9 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
vreg_ofs(s, a->rs1), \
- vreg_ofs(s, a->rs2), cpu_env, 0, \
- s->vlen / 8, data, fns[s->sew - 1]); \
+ vreg_ofs(s, a->rs2), cpu_env, \
+ s->vlen / 8, s->vlen / 8, data, \
+ fns[s->sew - 1]); \
gen_set_label(over); \
return true; \
} \
@@ -1863,7 +1866,7 @@ static bool opfvf_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
dest = tcg_temp_new_ptr();
mask = tcg_temp_new_ptr();
src2 = tcg_temp_new_ptr();
- desc = tcg_const_i32(simd_desc(0, s->vlen / 8, data));
+ desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, vs2));
@@ -1950,8 +1953,9 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
vreg_ofs(s, a->rs1), \
- vreg_ofs(s, a->rs2), cpu_env, 0, \
- s->vlen / 8, data, fns[s->sew - 1]); \
+ vreg_ofs(s, a->rs2), cpu_env, \
+ s->vlen / 8, s->vlen / 8, data, \
+ fns[s->sew - 1]); \
gen_set_label(over); \
return true; \
} \
@@ -2024,8 +2028,9 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
vreg_ofs(s, a->rs1), \
- vreg_ofs(s, a->rs2), cpu_env, 0, \
- s->vlen / 8, data, fns[s->sew - 1]); \
+ vreg_ofs(s, a->rs2), cpu_env, \
+ s->vlen / 8, s->vlen / 8, data, \
+ fns[s->sew - 1]); \
gen_set_label(over); \
return true; \
} \
@@ -2138,8 +2143,9 @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
data = FIELD_DP32(data, VDATA, VM, a->vm); \
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
- vreg_ofs(s, a->rs2), cpu_env, 0, \
- s->vlen / 8, data, fns[s->sew - 1]); \
+ vreg_ofs(s, a->rs2), cpu_env, \
+ s->vlen / 8, s->vlen / 8, data, \
+ fns[s->sew - 1]); \
gen_set_label(over); \
return true; \
} \
@@ -2225,7 +2231,7 @@ static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f *a)
tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
dest = tcg_temp_new_ptr();
- desc = tcg_const_i32(simd_desc(0, s->vlen / 8, data));
+ desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, a->rd));
fns[s->sew - 1](dest, cpu_fpr[a->rs1], cpu_env, desc);
@@ -2278,8 +2284,9 @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
data = FIELD_DP32(data, VDATA, VM, a->vm); \
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
- vreg_ofs(s, a->rs2), cpu_env, 0, \
- s->vlen / 8, data, fns[s->sew - 1]); \
+ vreg_ofs(s, a->rs2), cpu_env, \
+ s->vlen / 8, s->vlen / 8, data, \
+ fns[s->sew - 1]); \
gen_set_label(over); \
return true; \
} \
@@ -2326,8 +2333,9 @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
data = FIELD_DP32(data, VDATA, VM, a->vm); \
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
- vreg_ofs(s, a->rs2), cpu_env, 0, \
- s->vlen / 8, data, fns[s->sew - 1]); \
+ vreg_ofs(s, a->rs2), cpu_env, \
+ s->vlen / 8, s->vlen / 8, data, \
+ fns[s->sew - 1]); \
gen_set_label(over); \
return true; \
} \
@@ -2388,8 +2396,8 @@ static bool trans_##NAME(DisasContext *s, arg_r *a) \
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
vreg_ofs(s, a->rs1), \
- vreg_ofs(s, a->rs2), cpu_env, 0, \
- s->vlen / 8, data, fn); \
+ vreg_ofs(s, a->rs2), cpu_env, \
+ s->vlen / 8, s->vlen / 8, data, fn); \
gen_set_label(over); \
return true; \
} \
@@ -2420,7 +2428,7 @@ static bool trans_vmpopc_m(DisasContext *s, arg_rmr *a)
mask = tcg_temp_new_ptr();
src2 = tcg_temp_new_ptr();
dst = tcg_temp_new();
- desc = tcg_const_i32(simd_desc(0, s->vlen / 8, data));
+ desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, a->rs2));
tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
@@ -2452,7 +2460,7 @@ static bool trans_vmfirst_m(DisasContext *s, arg_rmr *a)
mask = tcg_temp_new_ptr();
src2 = tcg_temp_new_ptr();
dst = tcg_temp_new();
- desc = tcg_const_i32(simd_desc(0, s->vlen / 8, data));
+ desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, a->rs2));
tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
@@ -2486,7 +2494,8 @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), \
vreg_ofs(s, 0), vreg_ofs(s, a->rs2), \
- cpu_env, 0, s->vlen / 8, data, fn); \
+ cpu_env, s->vlen / 8, s->vlen / 8, \
+ data, fn); \
gen_set_label(over); \
return true; \
} \
@@ -2516,8 +2525,8 @@ static bool trans_viota_m(DisasContext *s, arg_viota_m *a)
gen_helper_viota_m_w, gen_helper_viota_m_d,
};
tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),
- vreg_ofs(s, a->rs2), cpu_env, 0,
- s->vlen / 8, data, fns[s->sew]);
+ vreg_ofs(s, a->rs2), cpu_env,
+ s->vlen / 8, s->vlen / 8, data, fns[s->sew]);
gen_set_label(over);
return true;
}
@@ -2542,7 +2551,8 @@ static bool trans_vid_v(DisasContext *s, arg_vid_v *a)
gen_helper_vid_v_w, gen_helper_vid_v_d,
};
tcg_gen_gvec_2_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),
- cpu_env, 0, s->vlen / 8, data, fns[s->sew]);
+ cpu_env, s->vlen / 8, s->vlen / 8,
+ data, fns[s->sew]);
gen_set_label(over);
return true;
}
@@ -2895,7 +2905,8 @@ static bool trans_vcompress_vm(DisasContext *s, arg_r *a)
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),
vreg_ofs(s, a->rs1), vreg_ofs(s, a->rs2),
- cpu_env, 0, s->vlen / 8, data, fns[s->sew]);
+ cpu_env, s->vlen / 8, s->vlen / 8, data,
+ fns[s->sew]);
gen_set_label(over);
return true;
}
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
index af6c341..d5e0bc9 100644
--- a/target/riscv/meson.build
+++ b/target/riscv/meson.build
@@ -16,6 +16,7 @@ riscv_ss.add(files(
'gdbstub.c',
'op_helper.c',
'vector_helper.c',
+ 'bitmanip_helper.c',
'translate.c',
))
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index 170b494..3c48e73 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -177,10 +177,15 @@ target_ulong helper_mret(CPURISCVState *env, target_ulong cpu_pc_deb)
void helper_wfi(CPURISCVState *env)
{
CPUState *cs = env_cpu(env);
+ bool rvs = riscv_has_ext(env, RVS);
+ bool prv_u = env->priv == PRV_U;
+ bool prv_s = env->priv == PRV_S;
- if ((env->priv == PRV_S &&
- get_field(env->mstatus, MSTATUS_TW)) ||
- riscv_cpu_virt_enabled(env)) {
+ if (((prv_s || (!rvs && prv_u)) && get_field(env->mstatus, MSTATUS_TW)) ||
+ (rvs && prv_u && !riscv_cpu_virt_enabled(env))) {
+ riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
+ } else if (riscv_cpu_virt_enabled(env) && (prv_u ||
+ (prv_s && get_field(env->hstatus, HSTATUS_VTW)))) {
riscv_raise_exception(env, RISCV_EXCP_VIRT_INSTRUCTION_FAULT, GETPC());
} else {
cs->halted = 1;
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
index 7820329..82ed020 100644
--- a/target/riscv/pmp.c
+++ b/target/riscv/pmp.c
@@ -402,6 +402,8 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
case 15:
*allowed_privs = PMP_READ;
break;
+ default:
+ g_assert_not_reached();
}
} else {
switch (epmp_operation) {
@@ -433,6 +435,8 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
case 7:
*allowed_privs = PMP_READ | PMP_WRITE | PMP_EXEC;
break;
+ default:
+ g_assert_not_reached();
}
}
}
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index e945352..c6e8739 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -548,6 +548,229 @@ static bool gen_arith_div_uw(DisasContext *ctx, arg_r *a,
return true;
}
+static void gen_pack(TCGv ret, TCGv arg1, TCGv arg2)
+{
+ tcg_gen_deposit_tl(ret, arg1, arg2,
+ TARGET_LONG_BITS / 2,
+ TARGET_LONG_BITS / 2);
+}
+
+static void gen_packu(TCGv ret, TCGv arg1, TCGv arg2)
+{
+ TCGv t = tcg_temp_new();
+ tcg_gen_shri_tl(t, arg1, TARGET_LONG_BITS / 2);
+ tcg_gen_deposit_tl(ret, arg2, t, 0, TARGET_LONG_BITS / 2);
+ tcg_temp_free(t);
+}
+
+static void gen_packh(TCGv ret, TCGv arg1, TCGv arg2)
+{
+ TCGv t = tcg_temp_new();
+ tcg_gen_ext8u_tl(t, arg2);
+ tcg_gen_deposit_tl(ret, arg1, t, 8, TARGET_LONG_BITS - 8);
+ tcg_temp_free(t);
+}
+
+static void gen_sbop_mask(TCGv ret, TCGv shamt)
+{
+ tcg_gen_movi_tl(ret, 1);
+ tcg_gen_shl_tl(ret, ret, shamt);
+}
+
+static void gen_bset(TCGv ret, TCGv arg1, TCGv shamt)
+{
+ TCGv t = tcg_temp_new();
+
+ gen_sbop_mask(t, shamt);
+ tcg_gen_or_tl(ret, arg1, t);
+
+ tcg_temp_free(t);
+}
+
+static void gen_bclr(TCGv ret, TCGv arg1, TCGv shamt)
+{
+ TCGv t = tcg_temp_new();
+
+ gen_sbop_mask(t, shamt);
+ tcg_gen_andc_tl(ret, arg1, t);
+
+ tcg_temp_free(t);
+}
+
+static void gen_binv(TCGv ret, TCGv arg1, TCGv shamt)
+{
+ TCGv t = tcg_temp_new();
+
+ gen_sbop_mask(t, shamt);
+ tcg_gen_xor_tl(ret, arg1, t);
+
+ tcg_temp_free(t);
+}
+
+static void gen_bext(TCGv ret, TCGv arg1, TCGv shamt)
+{
+ tcg_gen_shr_tl(ret, arg1, shamt);
+ tcg_gen_andi_tl(ret, ret, 1);
+}
+
+static void gen_slo(TCGv ret, TCGv arg1, TCGv arg2)
+{
+ tcg_gen_not_tl(ret, arg1);
+ tcg_gen_shl_tl(ret, ret, arg2);
+ tcg_gen_not_tl(ret, ret);
+}
+
+static void gen_sro(TCGv ret, TCGv arg1, TCGv arg2)
+{
+ tcg_gen_not_tl(ret, arg1);
+ tcg_gen_shr_tl(ret, ret, arg2);
+ tcg_gen_not_tl(ret, ret);
+}
+
+static bool gen_grevi(DisasContext *ctx, arg_grevi *a)
+{
+ TCGv source1 = tcg_temp_new();
+ TCGv source2;
+
+ gen_get_gpr(source1, a->rs1);
+
+ if (a->shamt == (TARGET_LONG_BITS - 8)) {
+ /* rev8, byte swaps */
+ tcg_gen_bswap_tl(source1, source1);
+ } else {
+ source2 = tcg_temp_new();
+ tcg_gen_movi_tl(source2, a->shamt);
+ gen_helper_grev(source1, source1, source2);
+ tcg_temp_free(source2);
+ }
+
+ gen_set_gpr(a->rd, source1);
+ tcg_temp_free(source1);
+ return true;
+}
+
+#define GEN_SHADD(SHAMT) \
+static void gen_sh##SHAMT##add(TCGv ret, TCGv arg1, TCGv arg2) \
+{ \
+ TCGv t = tcg_temp_new(); \
+ \
+ tcg_gen_shli_tl(t, arg1, SHAMT); \
+ tcg_gen_add_tl(ret, t, arg2); \
+ \
+ tcg_temp_free(t); \
+}
+
+GEN_SHADD(1)
+GEN_SHADD(2)
+GEN_SHADD(3)
+
+static void gen_ctzw(TCGv ret, TCGv arg1)
+{
+ tcg_gen_ori_tl(ret, arg1, (target_ulong)MAKE_64BIT_MASK(32, 32));
+ tcg_gen_ctzi_tl(ret, ret, 64);
+}
+
+static void gen_clzw(TCGv ret, TCGv arg1)
+{
+ tcg_gen_ext32u_tl(ret, arg1);
+ tcg_gen_clzi_tl(ret, ret, 64);
+ tcg_gen_subi_tl(ret, ret, 32);
+}
+
+static void gen_cpopw(TCGv ret, TCGv arg1)
+{
+ tcg_gen_ext32u_tl(arg1, arg1);
+ tcg_gen_ctpop_tl(ret, arg1);
+}
+
+static void gen_packw(TCGv ret, TCGv arg1, TCGv arg2)
+{
+ TCGv t = tcg_temp_new();
+ tcg_gen_ext16s_tl(t, arg2);
+ tcg_gen_deposit_tl(ret, arg1, t, 16, 48);
+ tcg_temp_free(t);
+}
+
+static void gen_packuw(TCGv ret, TCGv arg1, TCGv arg2)
+{
+ TCGv t = tcg_temp_new();
+ tcg_gen_shri_tl(t, arg1, 16);
+ tcg_gen_deposit_tl(ret, arg2, t, 0, 16);
+ tcg_gen_ext32s_tl(ret, ret);
+ tcg_temp_free(t);
+}
+
+static void gen_rorw(TCGv ret, TCGv arg1, TCGv arg2)
+{
+ TCGv_i32 t1 = tcg_temp_new_i32();
+ TCGv_i32 t2 = tcg_temp_new_i32();
+
+ /* truncate to 32-bits */
+ tcg_gen_trunc_tl_i32(t1, arg1);
+ tcg_gen_trunc_tl_i32(t2, arg2);
+
+ tcg_gen_rotr_i32(t1, t1, t2);
+
+ /* sign-extend 64-bits */
+ tcg_gen_ext_i32_tl(ret, t1);
+
+ tcg_temp_free_i32(t1);
+ tcg_temp_free_i32(t2);
+}
+
+static void gen_rolw(TCGv ret, TCGv arg1, TCGv arg2)
+{
+ TCGv_i32 t1 = tcg_temp_new_i32();
+ TCGv_i32 t2 = tcg_temp_new_i32();
+
+ /* truncate to 32-bits */
+ tcg_gen_trunc_tl_i32(t1, arg1);
+ tcg_gen_trunc_tl_i32(t2, arg2);
+
+ tcg_gen_rotl_i32(t1, t1, t2);
+
+ /* sign-extend 64-bits */
+ tcg_gen_ext_i32_tl(ret, t1);
+
+ tcg_temp_free_i32(t1);
+ tcg_temp_free_i32(t2);
+}
+
+static void gen_grevw(TCGv ret, TCGv arg1, TCGv arg2)
+{
+ tcg_gen_ext32u_tl(arg1, arg1);
+ gen_helper_grev(ret, arg1, arg2);
+}
+
+static void gen_gorcw(TCGv ret, TCGv arg1, TCGv arg2)
+{
+ tcg_gen_ext32u_tl(arg1, arg1);
+ gen_helper_gorcw(ret, arg1, arg2);
+}
+
+#define GEN_SHADD_UW(SHAMT) \
+static void gen_sh##SHAMT##add_uw(TCGv ret, TCGv arg1, TCGv arg2) \
+{ \
+ TCGv t = tcg_temp_new(); \
+ \
+ tcg_gen_ext32u_tl(t, arg1); \
+ \
+ tcg_gen_shli_tl(t, t, SHAMT); \
+ tcg_gen_add_tl(ret, t, arg2); \
+ \
+ tcg_temp_free(t); \
+}
+
+GEN_SHADD_UW(1)
+GEN_SHADD_UW(2)
+GEN_SHADD_UW(3)
+
+static void gen_add_uw(TCGv ret, TCGv arg1, TCGv arg2)
+{
+ tcg_gen_ext32u_tl(arg1, arg1);
+ tcg_gen_add_tl(ret, arg1, arg2);
+}
+
static bool gen_arith(DisasContext *ctx, arg_r *a,
void(*func)(TCGv, TCGv, TCGv))
{
@@ -593,6 +816,88 @@ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)
return cpu_ldl_code(env, pc);
}
+static bool gen_shifti(DisasContext *ctx, arg_shift *a,
+ void(*func)(TCGv, TCGv, TCGv))
+{
+ if (a->shamt >= TARGET_LONG_BITS) {
+ return false;
+ }
+
+ TCGv source1 = tcg_temp_new();
+ TCGv source2 = tcg_temp_new();
+
+ gen_get_gpr(source1, a->rs1);
+
+ tcg_gen_movi_tl(source2, a->shamt);
+ (*func)(source1, source1, source2);
+
+ gen_set_gpr(a->rd, source1);
+ tcg_temp_free(source1);
+ tcg_temp_free(source2);
+ return true;
+}
+
+static bool gen_shiftw(DisasContext *ctx, arg_r *a,
+ void(*func)(TCGv, TCGv, TCGv))
+{
+ TCGv source1 = tcg_temp_new();
+ TCGv source2 = tcg_temp_new();
+
+ gen_get_gpr(source1, a->rs1);
+ gen_get_gpr(source2, a->rs2);
+
+ tcg_gen_andi_tl(source2, source2, 31);
+ (*func)(source1, source1, source2);
+ tcg_gen_ext32s_tl(source1, source1);
+
+ gen_set_gpr(a->rd, source1);
+ tcg_temp_free(source1);
+ tcg_temp_free(source2);
+ return true;
+}
+
+static bool gen_shiftiw(DisasContext *ctx, arg_shift *a,
+ void(*func)(TCGv, TCGv, TCGv))
+{
+ TCGv source1 = tcg_temp_new();
+ TCGv source2 = tcg_temp_new();
+
+ gen_get_gpr(source1, a->rs1);
+ tcg_gen_movi_tl(source2, a->shamt);
+
+ (*func)(source1, source1, source2);
+ tcg_gen_ext32s_tl(source1, source1);
+
+ gen_set_gpr(a->rd, source1);
+ tcg_temp_free(source1);
+ tcg_temp_free(source2);
+ return true;
+}
+
+static void gen_ctz(TCGv ret, TCGv arg1)
+{
+ tcg_gen_ctzi_tl(ret, arg1, TARGET_LONG_BITS);
+}
+
+static void gen_clz(TCGv ret, TCGv arg1)
+{
+ tcg_gen_clzi_tl(ret, arg1, TARGET_LONG_BITS);
+}
+
+static bool gen_unary(DisasContext *ctx, arg_r2 *a,
+ void(*func)(TCGv, TCGv))
+{
+ TCGv source = tcg_temp_new();
+
+ gen_get_gpr(source, a->rs1);
+
+ (*func)(source, source);
+
+ gen_set_gpr(a->rd, source);
+ tcg_temp_free(source);
+ return true;
+}
+
/* Include insn module translation function */
#include "insn_trans/trans_rvi.c.inc"
#include "insn_trans/trans_rvm.c.inc"
@@ -601,6 +906,7 @@ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)
#include "insn_trans/trans_rvd.c.inc"
#include "insn_trans/trans_rvh.c.inc"
#include "insn_trans/trans_rvv.c.inc"
+#include "insn_trans/trans_rvb.c.inc"
#include "insn_trans/trans_privileged.c.inc"
/* Include the auto-generated decoder for 16 bit insn */