diff --git a/.gitlab-ci/cva6.yml b/.gitlab-ci/cva6.yml index fce1cab9f..783dea3dc 100644 --- a/.gitlab-ci/cva6.yml +++ b/.gitlab-ci/cva6.yml @@ -152,8 +152,8 @@ pub_build_tools: # If initially set to "__local__", SPIKE_INSTALL_DIR will be resolved # to an absolute path by the installation script. - source cva6/regress/install-spike.sh - # Strip locally built binaries and customext library to reduce artifact size. - - '[ -f $(pwd)/tools/spike/bin/spike ] && strip $(pwd)/tools/spike/bin/spike* $(pwd)/tools/spike/lib/libcustomext.so' + # Strip locally built binaries and libraries to reduce artifact size. + - '[ -f $(pwd)/tools/spike/bin/spike ] && strip $(pwd)/tools/spike/bin/spike* $(pwd)/tools/spike/lib/lib*.*' artifacts: paths: - tools/spike/ diff --git a/cva6/sim/Makefile b/cva6/sim/Makefile index eb89cff38..dfb88a8af 100644 --- a/cva6/sim/Makefile +++ b/cva6/sim/Makefile @@ -196,7 +196,7 @@ endif dpi-library = $(VCS_WORK_DIR)/work-dpi dpi_build: mkdir -p $(dpi-library) - g++ -shared -fPIC -std=c++0x -Bsymbolic -std=c++11 -I../corev_apu/tb/dpi -O3 -I$(SPIKE_ROOT)/include \ + g++ -shared -fPIC -std=c++17 -Bsymbolic -I../corev_apu/tb/dpi -O3 -I$(SPIKE_ROOT)/include \ -I$(VCS_HOME)/include -I$(RISCV)/include -c $(CVA6_REPO_DIR)/corev_apu/tb/dpi/elfloader.cc \ -o $(dpi-library)/elfloader.o g++ -shared -m64 -o $(dpi-library)/ariane_dpi.so $(dpi-library)/elfloader.o -L$(RISCV)/lib -Wl,-rpath,$(RISCV)/lib diff --git a/vendor/patches/riscv/riscv-isa-sim/0001-generate-shared-fesvr-lib.patch b/vendor/patches/riscv/riscv-isa-sim/0001-generate-shared-fesvr-lib.patch new file mode 100644 index 000000000..78c71e567 --- /dev/null +++ b/vendor/patches/riscv/riscv-isa-sim/0001-generate-shared-fesvr-lib.patch @@ -0,0 +1,12 @@ +diff --git a/fesvr/fesvr.mk.in b/fesvr/fesvr.mk.in +index 695de5278..43aed6786 100644 +--- a/fesvr/fesvr.mk.in ++++ b/fesvr/fesvr.mk.in +@@ -20,6 +20,7 @@ fesvr_install_hdrs = $(fesvr_hdrs) + fesvr_install_config_hdr = yes + + fesvr_install_lib = yes ++fesvr_install_shared_lib = yes + + fesvr_srcs = \ + elfloader.cc \ diff --git a/vendor/patches/riscv/riscv-isa-sim/0002-improve-extension-loading-diagnostics.patch b/vendor/patches/riscv/riscv-isa-sim/0002-improve-extension-loading-diagnostics.patch new file mode 100644 index 000000000..490a8ee50 --- /dev/null +++ b/vendor/patches/riscv/riscv-isa-sim/0002-improve-extension-loading-diagnostics.patch @@ -0,0 +1,15 @@ +diff --git a/riscv/extensions.cc b/riscv/extensions.cc +index 347dc5e91..b488aad15 100644 +--- a/riscv/extensions.cc ++++ b/riscv/extensions.cc +@@ -27,8 +27,8 @@ std::function find_extension(const char* name) + if (!dlh) { + dlh = dlopen(libdefault.c_str(), RTLD_LAZY); + if (!dlh) { +- fprintf(stderr, "couldn't find shared library either '%s' or '%s')\n", +- libname.c_str(), libdefault.c_str()); ++ fprintf(stderr, "couldn't load shared library (either '%s' or '%s'), reason: %s\n", ++ libname.c_str(), libdefault.c_str(), dlerror()); + exit(-1); + } + diff --git a/vendor/patches/riscv/riscv-isa-sim/0003-add-cvxif-extension.patch b/vendor/patches/riscv/riscv-isa-sim/0003-add-cvxif-extension.patch new file mode 100644 index 000000000..3445cda99 --- /dev/null +++ b/vendor/patches/riscv/riscv-isa-sim/0003-add-cvxif-extension.patch @@ -0,0 +1,533 @@ +diff --git a/customext/customext.mk.in b/customext/customext.mk.in +index a14e771c2..888634b46 100644 +--- a/customext/customext.mk.in ++++ b/customext/customext.mk.in +@@ -7,5 +7,6 @@ customext_subproject_deps = \ + customext_srcs = \ + dummy_rocc.cc \ + cflush.cc \ ++ cvxif.cc \ + + customext_install_shared_lib = yes +diff --git a/customext/cvxif.cc b/customext/cvxif.cc +new file mode 100644 +index 000000000..dd1a7329a +--- /dev/null ++++ b/customext/cvxif.cc +@@ -0,0 +1,226 @@ ++// Copyright (C) 2022 Thales DIS Design Services SAS ++// ++// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0. ++// ++// Original Author: Zbigniew CHAMSKI ++ ++#include "cvxif.h" ++#include "mmu.h" ++#include ++ ++// Define custom insns templates. ++// The insn-level wrapper is 'c##n' (default implementation, ++// writeback disabled), the default implementation ++// is 'custom##n': illegal instruction, return 0. ++// The writeback controller 'cvxif_extn_t::do_writeback_p' ++// is in charge of determining if writeback is required or not. ++// Expected instruction encoding is 4 bytes. ++#define customX(n) \ ++static reg_t c##n(processor_t* p, insn_t insn, reg_t pc) \ ++ { \ ++ cvxif_t* cvxif = static_cast(p->get_extension()); \ ++ cvxif_insn_t custom_insn; \ ++ custom_insn.i = insn; \ ++ reg_t xd = cvxif->default_custom##n(custom_insn); \ ++ if (cvxif->do_writeback_p(custom_insn)) \ ++ WRITE_RD(xd); \ ++ return pc+4; \ ++ } \ ++ \ ++ reg_t default_custom##n(cvxif_insn_t insn) \ ++ { \ ++ return custom##n(insn); \ ++ } ++ ++// This class instantiates the CV-X-IF interface. ++class cvxif_t : public cvxif_extn_t ++{ ++ public: ++ const char* name() { return "cvxif_spike"; } ++ ++ bool do_writeback_p(cvxif_insn_t copro_insn) ++ { ++ // INSN_R personality serves to simplify access to standard encoding fields. ++ cvxif_r_insn_t insn_r = copro_insn.r_type; ++ ++ if (insn_r.opcode != MATCH_CUSTOM3) ++ return false; ++ else switch (insn_r.funct3) ++ { ++ case 0b000: ++ // CUSTOM_NOP and CUSTOM_EXC have rd == x0. ++ // Return TRUE if destination is NOT x0. ++ return (insn_r.rd != 0x0); ++ ++ case 0b010: ++ // Return false for CUS_SD. ++ return false; ++ ++ default: ++ // All other cases: writeback is assumed REQUIRED. ++ return true; ++ } ++ } ++ ++ // Custom0 instructions: default behaviour. ++ reg_t custom0(cvxif_insn_t incoming_insn) ++ { ++ illegal_instruction(); ++ return -1; ++ } ++ ++ // Custom1 instructions: default behaviour. ++ reg_t custom1(cvxif_insn_t incoming_insn) ++ { ++ illegal_instruction(); ++ return -1; ++ } ++ ++ // Custom2 instructions: default behaviour. ++ reg_t custom2(cvxif_insn_t incoming_insn) ++ { ++ illegal_instruction(); ++ return -1; ++ } ++ ++ // Custom3 instructions: provide an explicit implementation of decode+exec. ++ reg_t custom3(cvxif_insn_t incoming_insn) ++ { ++ // Assume R-type insn: it shares opcode and funct3 fields with other CVXIF insn formats. ++ cvxif_r_insn_t r_insn = incoming_insn.r_type; ++ // INSN_T simplifies access to register values. ++ insn_t insn = incoming_insn.i; ++ ++ switch (r_insn.funct3) ++ { ++ case 0: ++ ++ // funct7[1:0] == 0b01: three-input RV add. ++ // If rd is x0: illegal instruction. ++ if ((r_insn.funct7 & 0x3) == 0b01) ++ { ++ if (insn.rd() == 0x0) ++ illegal_instruction(); ++ ++ // Destination is not x0: R4-type insn performing a 3-operand RV add ++ return (reg_t) ((reg_t) RS1 + (reg_t) RS2 + (reg_t) RS3); ++ } ++ ++ // Non-memory operations (including NOP and EXC) ++ switch (r_insn.funct7 & 0b1111001) ++ { ++ case 0: ++ { ++ // Single-cycle RV addition with privilege: all non-privilege bits are zero. ++ // funct7[2:1] == 0x0 (PRV_U): CUS_ADD (single-cycle RV ADD, any mode) ++ // funct7[2:1] == 0x1 (PRV_S): CUS_S_ADD (single-cycle S-/M-mode RV ADD) ++ // funct7[2:1] == 0x2 (PRV_HS): ILLEGAL ++ // funct7[2:1] == 0x3 (PRV_M): CUS_M_ADD (single-cycle M-mode RV ADD) ++ reg_t required_priv = (r_insn.funct7 & 0x6) >> 1; ++ if (required_priv != PRV_HS && (p->get_state()->prv & required_priv) == required_priv) ++ return (reg_t) ((reg_t) RS1 + (reg_t) RS2); ++ else ++ illegal_instruction(); ++ } ++ ++ case 0x8: ++ // Multi-cycle RV add. ++ // TODO FIXME: Represent delay. ++ return (reg_t) ((reg_t) RS1 + (reg_t) RS2); ++ ++ case 0x40: ++ // Exception. MCAUSE[4:0] encoded in RS1, MCAUSE[5] assumed to be 0. ++ if (insn.rd() == 0x0 && insn.rs2() == 0x0) ++ { ++ // Raise an exception only if registers rd and rs2 are both x0 (no 'bit 5' extension yet). ++ raise_exception(insn, insn.rs1()); ++ // Writeback will be disabled by 'do_writeback_p'. ++ return (reg_t) -1; ++ } ++ else ++ // Illegal instruction. ++ illegal_instruction(); ++ ++ default: ++ illegal_instruction(); ++ } ++ ++ case 1: ++ // Perform RV load. If runtime XLEN is not 64, assume 32. ++ if (p->get_xlen() == 64) ++ return MMU.load_int64(RS1 + insn.i_imm()); ++ else ++ return MMU.load_int32(RS1 + insn.i_imm()); ++ ++ case 2: ++ // Perform RV store. If runtime XLEN is not 64, assume 32. ++ if (p->get_xlen() == 64) ++ MMU.store_uint64(RS1 + insn.s_imm(), RS2); ++ else ++ MMU.store_uint32(RS1 + insn.s_imm(), RS2); ++ ++ // Writeback will be disabled by 'do_writeback_p'. ++ break; ++ ++ default: ++ illegal_instruction(); ++ } ++ ++ // FORNOW: Return 0xf......f to simplify debugging. ++ return (reg_t) -1; ++ } ++ ++ cvxif_t() ++ { ++ } ++ ++ void raise_exception(insn_t insn, reg_t exc_index) ++ { ++ switch (exc_index) { ++ case CAUSE_MISALIGNED_LOAD: ++ // Use 0x1 as perfectly unaligned address;-) ++ throw trap_load_address_misaligned((p ? p->get_state()->v : false), 1, 0, 0); ++ case CAUSE_LOAD_ACCESS: ++ // Use 0x1 as invalid address. ++ throw trap_load_access_fault((p ? p->get_state()->v : false), 1, 0, 0); ++ case CAUSE_MISALIGNED_STORE: ++ // Use 0x1 as perfectly unaligned address;-) ++ throw trap_store_address_misaligned((p ? p->get_state()->v : false), 1, 0, 0); ++ case CAUSE_STORE_ACCESS: ++ // Use 0x1 as invalid address. ++ throw trap_store_access_fault((p ? p->get_state()->v : false), 1, 0, 0); ++ case CAUSE_LOAD_PAGE_FAULT: ++ // Use 0x1 as always-faulting address. ++ throw trap_load_page_fault((p ? p->get_state()->v : false), 1, 0, 0); ++ case CAUSE_STORE_PAGE_FAULT: ++ // Use 0x1 as always-faulting address. ++ throw trap_store_page_fault((p ? p->get_state()->v : false), 1, 0, 0); ++ default: ++ illegal_instruction(); ++ } ++ } ++ ++ // Define templates of new instructions. ++ customX(0) ++ customX(1) ++ customX(2) ++ customX(3) ++ ++ // Set instruction handlers for customN opcode patterns. ++ // NOTE: This method may need revisiting if multiple custom extensions are to be loaded ++ // simultaneously in the future. ++ std::vector get_instructions() ++ { ++ std::vector insns; ++ insns.push_back((insn_desc_t){0x0b, 0x7f, &::illegal_instruction, c0}); ++ insns.push_back((insn_desc_t){0x2b, 0x7f, &::illegal_instruction, c1}); ++ insns.push_back((insn_desc_t){0x5b, 0x7f, &::illegal_instruction, c2}); ++ insns.push_back((insn_desc_t){0x7b, 0x7f, &c3, c3}); ++ return insns; ++ } ++ ++private: ++ // State variables go here. ++}; ++ ++REGISTER_EXTENSION(cvxif, []() { return new cvxif_t; }) +diff --git a/customext/cvxif_test.c b/customext/cvxif_test.c +new file mode 100644 +index 000000000..d39ca2229 +--- /dev/null ++++ b/customext/cvxif_test.c +@@ -0,0 +1,111 @@ ++// Copyright (C) 2022 Thales DIS Design Services SAS ++// ++// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0. ++// ++// Original Author: Zbigniew CHAMSKI ++// ++// The following is a RISC-V program to test the functionality of the ++// basic CVXIF accelerator interface on the Core-V side. ++// Compile using "riscv-none-elf-gcc -O2 cvxif_test.elf cvxif_test.c" ++// with -march=/-mabi= settings appropriate for your project. ++// Run using "spike -l --extension=cvxif cvxif_test.elf", adding ++// an --isa= setting appropriate for your project. ++// ++// Upon simulating the compiled program, the trace should contain five ++// instances of custom3 instructions (the third one being decoded as ++// 'unknown'). ++// The last occurrence of 'custom3' instruction in the trace, encoded as ++// 0x8002007b, should be immediately followed by exception ++// 'trap_load_address_misaligned' with a tval equal to 0x1 and the ++// execution should terminate correctly with exit code 0. ++// ++// In 64-bit mode, the trace of the last occurrence of custom3 ++// instruction should be equivalent to ++// ++// core 0: 0x0000000080002686 (0x8002007b) custom3 (args unknown) ++// core 0: exception trap_load_address_misaligned, epc 0x0000000080002686 ++// core 0: tval 0x0000000000000001 ++// ++// The corresponding trace in 32-bit mode should be equivalent to ++// ++// core 0: 0x8000205a (0x8002007b) custom3 (args unknown) ++// core 0: exception trap_load_address_misaligned, epc 0x8000205a ++// core 0: tval 0x00000001 ++ ++#include ++#include ++#include ++#include ++ ++// Values of MCAUSE corresponding to exceptions coming from the coprocessor I/F ++#define CAUSE_MISALIGNED_LOAD 0x4 ++#define CAUSE_LOAD_ACCESS 0x5 ++#define CAUSE_MISALIGNED_STORE 0x6 ++#define CAUSE_STORE_ACCESS 0x7 ++#define CAUSE_LOAD_PAGE_FAULT 0xd ++#define CAUSE_STORE_PAGE_FAULT 0xf ++#define CAUSE_COPROCESSOR_EXCEPTION 0x20 ++ ++// Value of TVAL to pass around. ++#define COPRO_TVAL_TEST 0x1a ++ ++// Macro to read a CSR (from spike's "encoding.h") ++#define read_csr(reg) ({ unsigned long __tmp; \ ++ asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \ ++ __tmp; }) ++ ++int main() { ++ // "unsigned long int" is always XLEN bits wide. ++ unsigned long int x = 123, y = 456, z = 0, t = 0; ++ static unsigned long int amem = 111, bmem = 0; ++ unsigned long a; ++ ++ // Add x + y into z. Funct7 == 0, funct3 == 0x0. ++ asm volatile (".insn r CUSTOM_3, 0, 0, %0, %1, %2" : "=r"(z) : "r"(x), "r"(y)); ++ if (z != 123 + 456) ++ { ++ // printf("FAILURE!!!\n"); ++ return 1; ++ } ++ ++ // Add three operands in a single R4-type add. ++ // Leverage current values of x, y and z (z == x + y). ++ asm volatile (".insn r CUSTOM_3, 0, 0x1, %0, %1, %2, %3" : "=r"(t) : "r"(x), "r"(y), "r"(z)); ++ if (t != x + y + z) ++ { ++ // printf("FAILURE"); ++ return 2; ++ } ++ // Load 'a' from 'amem'. CUSTOM_LD: opcode == CUSTOM_3, insn_type == I, funct3 == 0x1. ++ asm volatile (".insn i CUSTOM_3, 0x1, %0, %1" : "=r"(a) : "m"(amem), "I"(0)); ++ if (a != 111) ++ { ++ // printf("FAILURE!!!\n"); ++ return 3; ++ } ++ ++ // Store 'a' in 'bmem'. CUSTOM_SD: opcode == CUSTOM_3, insn_type == S, funct3 == 0x2. ++ asm volatile (".insn s CUSTOM_3, 0x2, %0, %1" : : "r"(a), "m"(bmem)); ++ if (bmem != 111) ++ { ++ // printf("FAILURE!!!\n"); ++ return 4; ++ } ++ ++ // Generate a misaligned load exception (mcause == 0x4). ++ asm volatile (".insn r CUSTOM_3, 0x0, 0x40, x0, x4, x0" : : ); ++ ++ // If we get here, then the exception test failed ==> exit with general failure code. ++ exit(1337); ++} ++ ++// Override default trap handler. ++uintptr_t handle_trap(uintptr_t cause, uintptr_t epc, uintptr_t regs[32]) ++{ ++ if (cause == CAUSE_MISALIGNED_LOAD) ++ // Successfully terminate. ++ exit(0); ++ else ++ // Fail with explicit retcode. ++ exit(5); ++} +diff --git a/riscv/cvxif.h b/riscv/cvxif.h +new file mode 100644 +index 000000000..e3a6fba1d +--- /dev/null ++++ b/riscv/cvxif.h +@@ -0,0 +1,77 @@ ++// Copyright (C) 2022 Thales DIS Design Services SAS ++// ++// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0. ++// ++// Original Author: Zbigniew CHAMSKI ++ ++#ifndef _RISCV_CVXIF_H ++#define _RISCV_CVXIF_H ++ ++#include "extension.h" ++ ++// R-type instruction format ++struct cvxif_r_insn_t ++{ ++ unsigned opcode : 7; ++ unsigned rd : 5; ++ unsigned funct3 : 3; ++ unsigned rs1 : 5; ++ unsigned rs2 : 5; ++ unsigned funct7 : 7; ++}; ++ ++// R4-type instruction format ++struct cvxif_r4_insn_t ++{ ++ unsigned opcode : 7; ++ unsigned rd : 5; ++ unsigned funct3 : 3; ++ unsigned rs1 : 5; ++ unsigned rs2 : 5; ++ unsigned funct2 : 2; ++ unsigned rs3 : 5; ++}; ++ ++// I-type instruction format ++struct cvxif_i_insn_t ++{ ++ unsigned opcode : 7; ++ unsigned rd : 5; ++ unsigned funct3 : 3; ++ unsigned rs1 : 5; ++ unsigned imm : 12; ++}; ++ ++// S-type instruction format ++struct cvxif_s_insn_t ++{ ++ unsigned opcode : 7; ++ unsigned imm_low : 5; ++ unsigned funct3 : 3; ++ unsigned rs1 : 5; ++ unsigned rs2 : 5; ++ unsigned imm_high : 7; ++}; ++ ++union cvxif_insn_t ++{ ++ cvxif_r_insn_t r_type; ++ cvxif_r4_insn_t r4_type; ++ cvxif_i_insn_t i_type; ++ cvxif_s_insn_t s_type; ++ insn_t i; ++}; ++ ++class cvxif_extn_t : public extension_t ++{ ++ public: ++ virtual bool do_writeback_p(cvxif_insn_t insn); ++ virtual reg_t custom0(cvxif_insn_t insn); ++ virtual reg_t custom1(cvxif_insn_t insn); ++ virtual reg_t custom2(cvxif_insn_t insn); ++ virtual reg_t custom3(cvxif_insn_t insn); ++ std::vector get_instructions(); ++ std::vector get_disasms(); ++}; ++ ++#endif +diff --git a/riscv/cvxif_base.cc b/riscv/cvxif_base.cc +new file mode 100644 +index 000000000..5097344c5 +--- /dev/null ++++ b/riscv/cvxif_base.cc +@@ -0,0 +1,64 @@ ++// Copyright (C) 2022 Thales DIS Design Services SAS ++// ++// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0. ++// ++// Original Author: Zbigniew CHAMSKI ++ ++#include "cvxif.h" ++#include "trap.h" ++#include ++ ++// Virtual base class of CVXIF. ++ ++// Return true if writeback is required. ++// Be on the safe side, disable writeback. ++bool cvxif_extn_t::do_writeback_p(cvxif_insn_t insn) ++{ ++ return false; ++} ++ ++// Define custom insns templates. ++// The insn-level wrapper is 'c##n' (default implementation, ++// writeback disabled), the default implementation ++// is 'custom##n': illegal instruction, return 0. ++// The writeback controller 'cvxif_extn_t::do_writeback_p' ++// is in charge of determining if writeback is required or not. ++// Expected instruction encoding is 4 bytes. ++#define customX(n) \ ++static reg_t c##n(processor_t* p, insn_t insn, reg_t pc) \ ++ { \ ++ cvxif_extn_t* cvxif = static_cast(p->get_extension()); \ ++ cvxif_insn_t custom_insn; \ ++ custom_insn.i = insn; \ ++ reg_t xd = cvxif->custom##n(custom_insn); \ ++ if (cvxif->do_writeback_p(custom_insn)) \ ++ WRITE_RD(xd); \ ++ return pc+4; \ ++ } \ ++ \ ++ reg_t cvxif_extn_t::custom##n(cvxif_insn_t insn) \ ++ { \ ++ illegal_instruction(); \ ++ return -1; \ ++ } ++ ++customX(0) ++customX(1) ++customX(2) ++customX(3) ++ ++std::vector cvxif_extn_t::get_instructions() ++{ ++ std::vector insns; ++ insns.push_back((insn_desc_t){0x0b, 0x7f, &::illegal_instruction, c0}); ++ insns.push_back((insn_desc_t){0x2b, 0x7f, &::illegal_instruction, c1}); ++ insns.push_back((insn_desc_t){0x5b, 0x7f, &::illegal_instruction, c2}); ++ insns.push_back((insn_desc_t){0x7b, 0x7f, &::illegal_instruction, c3}); ++ return insns; ++} ++ ++std::vector cvxif_extn_t::get_disasms() ++{ ++ std::vector insns; ++ return insns; ++} +diff --git a/riscv/riscv.mk.in b/riscv/riscv.mk.in +index 56014662c..3da5f6d8b 100644 +--- a/riscv/riscv.mk.in ++++ b/riscv/riscv.mk.in +@@ -26,6 +26,7 @@ riscv_hdrs = \ + cfg.h \ + common.h \ + csrs.h \ ++ cvxif.h \ + debug_defines.h \ + debug_module.h \ + debug_rom_defines.h \ +@@ -58,6 +59,7 @@ + extension.cc \ + extensions.cc \ + rocc.cc \ ++ cvxif_base.cc \ + devices.cc \ + rom.cc \ + clint.cc \ diff --git a/vendor/riscv/riscv-isa-sim/.gitignore b/vendor/riscv/riscv-isa-sim/.gitignore index 14326e9c6..6bae0e15f 100644 --- a/vendor/riscv/riscv-isa-sim/.gitignore +++ b/vendor/riscv/riscv-isa-sim/.gitignore @@ -5,3 +5,5 @@ autom4te.cache/ *.o *.d .gdb_history +.#* +*~ diff --git a/vendor/riscv/riscv-isa-sim/Makefile.in b/vendor/riscv/riscv-isa-sim/Makefile.in index f2f82782c..c3e1822d3 100644 --- a/vendor/riscv/riscv-isa-sim/Makefile.in +++ b/vendor/riscv/riscv-isa-sim/Makefile.in @@ -94,11 +94,11 @@ VPATH := $(addprefix $(src_dir)/, $(sprojs_enabled)) # highest. default-CFLAGS := -DPREFIX=\"$(prefix)\" -Wall -Wno-unused -Wno-nonportable-include-path -g -O2 -fPIC -default-CXXFLAGS := $(default-CFLAGS) -std=c++11 +default-CXXFLAGS := $(default-CFLAGS) -std=c++17 mcppbs-CPPFLAGS := @CPPFLAGS@ mcppbs-CFLAGS := $(default-CFLAGS) @CFLAGS@ -mcppbs-CXXFLAGS := $(default-CXXFLAGS) @CXXFLAGS@ +mcppbs-CXXFLAGS := $(mcppbs-CFLAGS) $(default-CXXFLAGS) @CXXFLAGS@ CC := @CC@ CXX := @CXX@ @@ -219,7 +219,7 @@ $(2)_deps := $$(patsubst %.o, %.d, $$($(2)_objs)) $(2)_deps += $$(patsubst %.o, %.d, $$($(2)_c_objs)) $(2)_deps += $$(patsubst %.h, %.h.d, $$($(2)_precompiled_hdrs)) $$($(2)_pch) : %.h.gch : %.h - $(COMPILE) -x c++-header $$< -o $$@ + $(COMPILE) -x c++-header $$< -c -o $$@ $$($(2)_objs) : %.o : %.cc $$($(2)_gen_hdrs) $$($(2)_pch) $(COMPILE) $(if $(HAVE_CLANG_PCH), $$(if $$($(2)_pch), -include-pch $$($(2)_pch))) $$($(2)_CFLAGS) -c $$< $$($(2)_c_objs) : %.o : %.c $$($(2)_gen_hdrs) @@ -241,7 +241,8 @@ $(2)_lib_libnames := $$(patsubst %, lib%.a, $$($(2)_lib_libs)) $(2)_lib_libarg := $$(patsubst %, -l%, $$($(2)_lib_libs)) $(2)_lib_libnames_shared := $$(if $$($(2)_install_shared_lib),lib$(1).so,) -lib$(1).a : $$($(2)_objs) $$($(2)_c_objs) $$($(2)_lib_libnames) +lib$(1).a : $$($(2)_objs) $$($(2)_c_objs) + rm -f $$@ $(AR) rcs $$@ $$^ lib$(1).so : $$($(2)_objs) $$($(2)_c_objs) $$($(2)_lib_libnames_shared) $$($(2)_lib_libnames) $(LINK) -shared -o $$@ $(if $(filter Darwin,$(shell uname -s)),-install_name $(install_libs_dir)/$$@) $$^ $$($(2)_lib_libnames) $(LIBS) @@ -326,10 +327,6 @@ clean-$(1) : # Update running variables -libs += lib$(1).a -objs += $$($(2)_objs) -srcs += $$(addprefix $(src_dir)/$(1)/, $$($(2)_srcs)) -hdrs += $$(addprefix $(src_dir)/$(1)/, $$($(2)_hdrs)) $$($(2)_gen_hdrs) junk += $$($(2)_junk) deps += $$($(2)_deps) diff --git a/vendor/riscv/riscv-isa-sim/README.md b/vendor/riscv/riscv-isa-sim/README.md index 0b097ced0..9455bfae6 100644 --- a/vendor/riscv/riscv-isa-sim/README.md +++ b/vendor/riscv/riscv-isa-sim/README.md @@ -27,13 +27,28 @@ Spike supports the following RISC-V ISA features: - Zbb extension, v1.0 - Zbc extension, v1.0 - Zbs extension, v1.0 + - Zfh and Zfhmin half-precision floating-point extensions, v1.0 + - Zfinx extension, v1.0 + - Zmmul integer multiplication extension, v1.0 + - Zicbom, Zicbop, Zicboz cache-block maintenance extensions, v1.0 - Conformance to both RVWMO and RVTSO (Spike is sequentially consistent) - Machine, Supervisor, and User modes, v1.11 - Hypervisor extension, v1.0 - Svnapot extension, v1.0 - Svpbmt extension, v1.0 - Svinval extension, v1.0 - - Debug v0.14 + - Sdext extension, v1.0-STABLE + - Sdtrig extension, v1.0-STABLE + - 4 triggers support type={2, 3, 4, 5, 6, 15} (mcontrol, icount, itrigger, etrigger, mcontrol6, disabled) + - Smepmp extension v1.0 + - Smstateen extension, v1.0 + - Sscofpmf v0.5.2 + - Zca extension, v1.0 + - Zcb extension, v1.0 + - Zcf extension, v1.0 + - Zcd extension, v1.0 + - Zcmp extension, v1.0 + - Zcmt extension, v1.0 As a Spike extension, the remainder of the proposed [Bit-Manipulation Extensions](https://github.com/riscv/riscv-bitmanip) @@ -41,6 +56,14 @@ is provided under the Spike-custom extension name _Xbitmanip_. These instructions (and, of course, the extension name) are not RISC-V standards. +These proposed bit-manipulation extensions can be split into further +groups: Zbp, Zbs, Zbe, Zbf, Zbc, Zbm, Zbr, Zbt. Note that Zbc is +ratified, but the original proposal contained some extra instructions +(64-bit carryless multiplies) which are captured here. + +To enable these extensions individually, use the Spike-custom +extension names _XZbp_, _XZbs_, _XZbc_, and so on. + Versioning and APIs ------------------- @@ -211,7 +234,7 @@ OUTPUT_ARCH( "riscv" ) SECTIONS { - . = 0x10010000; + . = 0x10110000; .text : { *(.text) } .data : { *(.data) } } @@ -221,19 +244,19 @@ $ riscv64-unknown-elf-gcc -g -Og -T spike.lds -nostartfiles -o rot13-64 rot13-64 To debug this program, first run spike telling it to listen for OpenOCD: ``` -$ spike --rbb-port=9824 -m0x10000000:0x20000 rot13-64 +$ spike --rbb-port=9824 -m0x10100000:0x20000 rot13-64 Listening for remote bitbang connection on port 9824. ``` In a separate shell run OpenOCD with the appropriate configuration file: ``` $ cat spike.cfg -interface remote_bitbang -remote_bitbang_host localhost -remote_bitbang_port 9824 +adapter driver remote_bitbang +remote_bitbang host localhost +remote_bitbang port 9824 set _CHIPNAME riscv -jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x10e31913 +jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0xdeadbeef set _TARGETNAME $_CHIPNAME.cpu target create $_TARGETNAME riscv -chain-position $_TARGETNAME @@ -277,7 +300,7 @@ $2 = 0 (gdb) print text $3 = "Vafgehpgvba frgf jnag gb or serr!" (gdb) b done -Breakpoint 1 at 0x10010064: file rot13.c, line 22. +Breakpoint 1 at 0x10110064: file rot13.c, line 22. (gdb) c Continuing. Disabling abstract command writes to CSRs. diff --git a/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/Makefile_common.inc b/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/Makefile_common.inc new file mode 100644 index 000000000..c43222de3 --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/Makefile_common.inc @@ -0,0 +1,34 @@ +TARGET_SIM ?= spike +TARGET_FLAGS ?= $(RISCV_TARGET_FLAGS) +ifeq ($(shell command -v $(TARGET_SIM) 2> /dev/null),) + $(error Target simulator executable '$(TARGET_SIM)` not found) +endif + +RISCV_PREFIX ?= riscv$(XLEN)-unknown-elf- +RISCV_GCC ?= $(RISCV_PREFIX)gcc +RISCV_OBJDUMP ?= $(RISCV_PREFIX)objdump +RISCV_GCC_OPTS ?= -g -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles $(RVTEST_DEFINES) + +COMPILE_CMD = $$(RISCV_GCC) $(1) $$(RISCV_GCC_OPTS) \ + -I$(ROOTDIR)/riscv-test-suite/env/ \ + -I$(TARGETDIR)/$(RISCV_TARGET)/ \ + -T$(TARGETDIR)/$(RISCV_TARGET)/link.ld \ + $$(<) -o $$@ +OBJ_CMD = $$(RISCV_OBJDUMP) $$@ -D > $$@.objdump; \ + $$(RISCV_OBJDUMP) $$@ --source > $$@.debug + + +COMPILE_TARGET=\ + $(COMPILE_CMD); \ + if [ $$$$? -ne 0 ] ; \ + then \ + echo "\e[31m$$(RISCV_GCC) failed for target $$(@) \e[39m" ; \ + exit 1 ; \ + fi ; \ + $(OBJ_CMD); \ + if [ $$$$? -ne 0 ] ; \ + then \ + echo "\e[31m $$(RISCV_OBJDUMP) failed for target $$(@) \e[39m" ; \ + exit 1 ; \ + fi ; + diff --git a/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv32e_unratified/C/Makefile.include b/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv32e_unratified/C/Makefile.include new file mode 100644 index 000000000..daf0f4349 --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv32e_unratified/C/Makefile.include @@ -0,0 +1,7 @@ +include $(TARGETDIR)/spike/device/Makefile_common.inc +RUN_CMD = $(TARGET_SIM) $(TARGET_FLAGS) --isa=rv32ec \ + +signature=$(*).signature.output +signature-granularity=4\ + $< + +RUN_TARGET=\ + $(RUN_CMD) diff --git a/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv32e_unratified/E/Makefile.include b/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv32e_unratified/E/Makefile.include new file mode 100644 index 000000000..548b17d7d --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv32e_unratified/E/Makefile.include @@ -0,0 +1,7 @@ +include $(TARGETDIR)/spike/device/Makefile_common.inc +RUN_CMD = $(TARGET_SIM) $(TARGET_FLAGS) --isa=rv32e \ + +signature=$(*).signature.output +signature-granularity=4\ + $< + +RUN_TARGET=\ + $(RUN_CMD) diff --git a/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv32e_unratified/M/Makefile.include b/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv32e_unratified/M/Makefile.include new file mode 100644 index 000000000..749c7fc2a --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv32e_unratified/M/Makefile.include @@ -0,0 +1,7 @@ +include $(TARGETDIR)/spike/device/Makefile_common.inc +RUN_CMD = $(TARGET_SIM) $(TARGET_FLAGS) --isa=rv32em \ + +signature=$(*).signature.output +signature-granularity=4\ + $< + +RUN_TARGET=\ + $(RUN_CMD) diff --git a/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv32i_m/C/Makefile.include b/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv32i_m/C/Makefile.include index 7853bafe9..346feaae7 100644 --- a/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv32i_m/C/Makefile.include +++ b/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv32i_m/C/Makefile.include @@ -1,37 +1,4 @@ -TARGET_SIM ?= spike -TARGET_FLAGS ?= $(RISCV_TARGET_FLAGS) -ifeq ($(shell command -v $(TARGET_SIM) 2> /dev/null),) - $(error Target simulator executable '$(TARGET_SIM)` not found) -endif - -RISCV_PREFIX ?= riscv32-unknown-elf- -RISCV_GCC ?= $(RISCV_PREFIX)gcc -RISCV_OBJDUMP ?= $(RISCV_PREFIX)objdump -RISCV_GCC_OPTS ?= -g -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles $(RVTEST_DEFINES) - -COMPILE_CMD = $$(RISCV_GCC) $(1) $$(RISCV_GCC_OPTS) \ - -I$(ROOTDIR)/riscv-test-suite/env/ \ - -I$(TARGETDIR)/$(RISCV_TARGET)/ \ - -T$(TARGETDIR)/$(RISCV_TARGET)/link.ld \ - $$(<) -o $$@ -OBJ_CMD = $$(RISCV_OBJDUMP) $$@ -D > $$@.objdump; \ - $$(RISCV_OBJDUMP) $$@ --source > $$@.debug - - -COMPILE_TARGET=\ - $(COMPILE_CMD); \ - if [ $$$$? -ne 0 ] ; \ - then \ - echo "\e[31m$$(RISCV_GCC) failed for target $$(@) \e[39m" ; \ - exit 1 ; \ - fi ; \ - $(OBJ_CMD); \ - if [ $$$$? -ne 0 ] ; \ - then \ - echo "\e[31m $$(RISCV_OBJDUMP) failed for target $$(@) \e[39m" ; \ - exit 1 ; \ - fi ; - +include $(TARGETDIR)/spike/device/Makefile_common.inc RUN_CMD = $(TARGET_SIM) $(TARGET_FLAGS) --isa=rv32ic \ +signature=$(*).signature.output +signature-granularity=4\ $< diff --git a/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv32i_m/F/Makefile.include b/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv32i_m/F/Makefile.include new file mode 100644 index 000000000..4fb87c622 --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv32i_m/F/Makefile.include @@ -0,0 +1,7 @@ +include $(TARGETDIR)/spike/device/Makefile_common.inc +RUN_CMD = $(TARGET_SIM) $(TARGET_FLAGS) --isa=rv32if \ + +signature=$(*).signature.output +signature-granularity=4\ + $< + +RUN_TARGET=\ + $(RUN_CMD) diff --git a/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv32i_m/I/Makefile.include b/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv32i_m/I/Makefile.include index 6c3693c56..740755c0f 100644 --- a/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv32i_m/I/Makefile.include +++ b/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv32i_m/I/Makefile.include @@ -1,37 +1,4 @@ -TARGET_SIM ?= spike -TARGET_FLAGS ?= $(RISCV_TARGET_FLAGS) -ifeq ($(shell command -v $(TARGET_SIM) 2> /dev/null),) - $(error Target simulator executable '$(TARGET_SIM)` not found) -endif - -RISCV_PREFIX ?= riscv32-unknown-elf- -RISCV_GCC ?= $(RISCV_PREFIX)gcc -RISCV_OBJDUMP ?= $(RISCV_PREFIX)objdump -RISCV_GCC_OPTS ?= -g -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles $(RVTEST_DEFINES) - -COMPILE_CMD = $$(RISCV_GCC) $(1) $$(RISCV_GCC_OPTS) \ - -I$(ROOTDIR)/riscv-test-suite/env/ \ - -I$(TARGETDIR)/$(RISCV_TARGET)/ \ - -T$(TARGETDIR)/$(RISCV_TARGET)/link.ld \ - $$(<) -o $$@ -OBJ_CMD = $$(RISCV_OBJDUMP) $$@ -D > $$@.objdump; \ - $$(RISCV_OBJDUMP) $$@ --source > $$@.debug - - -COMPILE_TARGET=\ - $(COMPILE_CMD); \ - if [ $$$$? -ne 0 ] ; \ - then \ - echo "\e[31m$$(RISCV_GCC) failed for target $$(@) \e[39m" ; \ - exit 1 ; \ - fi ; \ - $(OBJ_CMD); \ - if [ $$$$? -ne 0 ] ; \ - then \ - echo "\e[31m $$(RISCV_OBJDUMP) failed for target $$(@) \e[39m" ; \ - exit 1 ; \ - fi ; - +include $(TARGETDIR)/spike/device/Makefile_common.inc RUN_CMD = $(TARGET_SIM) $(TARGET_FLAGS) --isa=rv32i \ +signature=$(*).signature.output +signature-granularity=4\ $< diff --git a/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv32i_m/M/Makefile.include b/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv32i_m/M/Makefile.include index 2f1e83cb6..5d8de47ce 100644 --- a/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv32i_m/M/Makefile.include +++ b/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv32i_m/M/Makefile.include @@ -1,37 +1,4 @@ -TARGET_SIM ?= spike -TARGET_FLAGS ?= $(RISCV_TARGET_FLAGS) -ifeq ($(shell command -v $(TARGET_SIM) 2> /dev/null),) - $(error Target simulator executable '$(TARGET_SIM)` not found) -endif - -RISCV_PREFIX ?= riscv32-unknown-elf- -RISCV_GCC ?= $(RISCV_PREFIX)gcc -RISCV_OBJDUMP ?= $(RISCV_PREFIX)objdump -RISCV_GCC_OPTS ?= -g -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles $(RVTEST_DEFINES) - -COMPILE_CMD = $$(RISCV_GCC) $(1) $$(RISCV_GCC_OPTS) \ - -I$(ROOTDIR)/riscv-test-suite/env/ \ - -I$(TARGETDIR)/$(RISCV_TARGET)/ \ - -T$(TARGETDIR)/$(RISCV_TARGET)/link.ld \ - $$(<) -o $$@ -OBJ_CMD = $$(RISCV_OBJDUMP) $$@ -D > $$@.objdump; \ - $$(RISCV_OBJDUMP) $$@ --source > $$@.debug - - -COMPILE_TARGET=\ - $(COMPILE_CMD); \ - if [ $$$$? -ne 0 ] ; \ - then \ - echo "\e[31m$$(RISCV_GCC) failed for target $$(@) \e[39m" ; \ - exit 1 ; \ - fi ; \ - $(OBJ_CMD); \ - if [ $$$$? -ne 0 ] ; \ - then \ - echo "\e[31m $$(RISCV_OBJDUMP) failed for target $$(@) \e[39m" ; \ - exit 1 ; \ - fi ; - +include $(TARGETDIR)/spike/device/Makefile_common.inc RUN_CMD = $(TARGET_SIM) $(TARGET_FLAGS) --isa=rv32im \ +signature=$(*).signature.output +signature-granularity=4\ $< diff --git a/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv32i_m/Zifencei/Makefile.include b/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv32i_m/Zifencei/Makefile.include index 6c3693c56..740755c0f 100644 --- a/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv32i_m/Zifencei/Makefile.include +++ b/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv32i_m/Zifencei/Makefile.include @@ -1,37 +1,4 @@ -TARGET_SIM ?= spike -TARGET_FLAGS ?= $(RISCV_TARGET_FLAGS) -ifeq ($(shell command -v $(TARGET_SIM) 2> /dev/null),) - $(error Target simulator executable '$(TARGET_SIM)` not found) -endif - -RISCV_PREFIX ?= riscv32-unknown-elf- -RISCV_GCC ?= $(RISCV_PREFIX)gcc -RISCV_OBJDUMP ?= $(RISCV_PREFIX)objdump -RISCV_GCC_OPTS ?= -g -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles $(RVTEST_DEFINES) - -COMPILE_CMD = $$(RISCV_GCC) $(1) $$(RISCV_GCC_OPTS) \ - -I$(ROOTDIR)/riscv-test-suite/env/ \ - -I$(TARGETDIR)/$(RISCV_TARGET)/ \ - -T$(TARGETDIR)/$(RISCV_TARGET)/link.ld \ - $$(<) -o $$@ -OBJ_CMD = $$(RISCV_OBJDUMP) $$@ -D > $$@.objdump; \ - $$(RISCV_OBJDUMP) $$@ --source > $$@.debug - - -COMPILE_TARGET=\ - $(COMPILE_CMD); \ - if [ $$$$? -ne 0 ] ; \ - then \ - echo "\e[31m$$(RISCV_GCC) failed for target $$(@) \e[39m" ; \ - exit 1 ; \ - fi ; \ - $(OBJ_CMD); \ - if [ $$$$? -ne 0 ] ; \ - then \ - echo "\e[31m $$(RISCV_OBJDUMP) failed for target $$(@) \e[39m" ; \ - exit 1 ; \ - fi ; - +include $(TARGETDIR)/spike/device/Makefile_common.inc RUN_CMD = $(TARGET_SIM) $(TARGET_FLAGS) --isa=rv32i \ +signature=$(*).signature.output +signature-granularity=4\ $< diff --git a/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv32i_m/privilege/Makefile.include b/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv32i_m/privilege/Makefile.include index 2d55242f9..8275495db 100644 --- a/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv32i_m/privilege/Makefile.include +++ b/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv32i_m/privilege/Makefile.include @@ -1,37 +1,4 @@ -TARGET_SIM ?= spike -TARGET_FLAGS ?= $(RISCV_TARGET_FLAGS) -ifeq ($(shell command -v $(TARGET_SIM) 2> /dev/null),) - $(error Target simulator executable '$(TARGET_SIM)` not found) -endif - -RISCV_PREFIX ?= riscv32-unknown-elf- -RISCV_GCC ?= $(RISCV_PREFIX)gcc -RISCV_OBJDUMP ?= $(RISCV_PREFIX)objdump -RISCV_GCC_OPTS ?= -g -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles $(RVTEST_DEFINES) - -COMPILE_CMD = $$(RISCV_GCC) $(1) $$(RISCV_GCC_OPTS) \ - -I$(ROOTDIR)/riscv-test-suite/env/ \ - -I$(TARGETDIR)/$(RISCV_TARGET)/ \ - -T$(TARGETDIR)/$(RISCV_TARGET)/link.ld \ - $$(<) -o $$@ -OBJ_CMD = $$(RISCV_OBJDUMP) $$@ -D > $$@.objdump; \ - $$(RISCV_OBJDUMP) $$@ --source > $$@.debug - - -COMPILE_TARGET=\ - $(COMPILE_CMD); \ - if [ $$$$? -ne 0 ] ; \ - then \ - echo "\e[31m$$(RISCV_GCC) failed for target $$(@) \e[39m" ; \ - exit 1 ; \ - fi ; \ - $(OBJ_CMD); \ - if [ $$$$? -ne 0 ] ; \ - then \ - echo "\e[31m $$(RISCV_OBJDUMP) failed for target $$(@) \e[39m" ; \ - exit 1 ; \ - fi ; - +include $(TARGETDIR)/spike/device/Makefile_common.inc RUN_CMD = $(TARGET_SIM) $(TARGET_FLAGS) --isa=rv32ic \ +signature=$(*).signature.output +signature-granularity=4\ $< diff --git a/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv64i_m/C/Makefile.include b/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv64i_m/C/Makefile.include index 4d957593f..e6ca9fb3b 100644 --- a/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv64i_m/C/Makefile.include +++ b/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv64i_m/C/Makefile.include @@ -1,37 +1,4 @@ -TARGET_SIM ?= spike -TARGET_FLAGS ?= $(RISCV_TARGET_FLAGS) -ifeq ($(shell command -v $(TARGET_SIM) 2> /dev/null),) - $(error Target simulator executable '$(TARGET_SIM)` not found) -endif - -RISCV_PREFIX ?= riscv64-unknown-elf- -RISCV_GCC ?= $(RISCV_PREFIX)gcc -RISCV_OBJDUMP ?= $(RISCV_PREFIX)objdump -RISCV_GCC_OPTS ?= -g -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles $(RVTEST_DEFINES) - -COMPILE_CMD = $$(RISCV_GCC) $(1) $$(RISCV_GCC_OPTS) \ - -I$(ROOTDIR)/riscv-test-suite/env/ \ - -I$(TARGETDIR)/$(RISCV_TARGET)/ \ - -T$(TARGETDIR)/$(RISCV_TARGET)/link.ld \ - $$(<) -o $$@ -OBJ_CMD = $$(RISCV_OBJDUMP) $$@ -D > $$@.objdump; \ - $$(RISCV_OBJDUMP) $$@ --source > $$@.debug - - -COMPILE_TARGET=\ - $(COMPILE_CMD); \ - if [ $$$$? -ne 0 ] ; \ - then \ - echo "\e[31m$$(RISCV_GCC) failed for target $$(@) \e[39m" ; \ - exit 1 ; \ - fi ; \ - $(OBJ_CMD); \ - if [ $$$$? -ne 0 ] ; \ - then \ - echo "\e[31m $$(RISCV_OBJDUMP) failed for target $$(@) \e[39m" ; \ - exit 1 ; \ - fi ; - +include $(TARGETDIR)/spike/device/Makefile_common.inc RUN_CMD = $(TARGET_SIM) $(TARGET_FLAGS) --isa=rv64ic \ +signature=$(*).signature.output +signature-granularity=4\ $< diff --git a/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv64i_m/D/Makefile.include b/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv64i_m/D/Makefile.include new file mode 100644 index 000000000..26113946a --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv64i_m/D/Makefile.include @@ -0,0 +1,8 @@ +include $(TARGETDIR)/spike/device/Makefile_common.inc +RUN_CMD = $(TARGET_SIM) $(TARGET_FLAGS) --isa=rv64ifd \ + +signature=$(*).signature.output +signature-granularity=4\ + $< + +RUN_TARGET=\ + $(RUN_CMD) + diff --git a/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv64i_m/I/Makefile.include b/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv64i_m/I/Makefile.include index 20a1fdc1a..2c763bf56 100644 --- a/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv64i_m/I/Makefile.include +++ b/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv64i_m/I/Makefile.include @@ -1,37 +1,4 @@ -TARGET_SIM ?= spike -TARGET_FLAGS ?= $(RISCV_TARGET_FLAGS) -ifeq ($(shell command -v $(TARGET_SIM) 2> /dev/null),) - $(error Target simulator executable '$(TARGET_SIM)` not found) -endif - -RISCV_PREFIX ?= riscv64-unknown-elf- -RISCV_GCC ?= $(RISCV_PREFIX)gcc -RISCV_OBJDUMP ?= $(RISCV_PREFIX)objdump -RISCV_GCC_OPTS ?= -g -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles $(RVTEST_DEFINES) - -COMPILE_CMD = $$(RISCV_GCC) $(1) $$(RISCV_GCC_OPTS) \ - -I$(ROOTDIR)/riscv-test-suite/env/ \ - -I$(TARGETDIR)/$(RISCV_TARGET)/ \ - -T$(TARGETDIR)/$(RISCV_TARGET)/link.ld \ - $$(<) -o $$@ -OBJ_CMD = $$(RISCV_OBJDUMP) $$@ -D > $$@.objdump; \ - $$(RISCV_OBJDUMP) $$@ --source > $$@.debug - - -COMPILE_TARGET=\ - $(COMPILE_CMD); \ - if [ $$$$? -ne 0 ] ; \ - then \ - echo "\e[31m$$(RISCV_GCC) failed for target $$(@) \e[39m" ; \ - exit 1 ; \ - fi ; \ - $(OBJ_CMD); \ - if [ $$$$? -ne 0 ] ; \ - then \ - echo "\e[31m $$(RISCV_OBJDUMP) failed for target $$(@) \e[39m" ; \ - exit 1 ; \ - fi ; - +include $(TARGETDIR)/spike/device/Makefile_common.inc RUN_CMD = $(TARGET_SIM) $(TARGET_FLAGS) --isa=rv64i \ +signature=$(*).signature.output +signature-granularity=4\ $< diff --git a/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv64i_m/M/Makefile.include b/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv64i_m/M/Makefile.include index 0ae9f0af9..8ce555c64 100644 --- a/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv64i_m/M/Makefile.include +++ b/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv64i_m/M/Makefile.include @@ -1,37 +1,4 @@ -TARGET_SIM ?= spike -TARGET_FLAGS ?= $(RISCV_TARGET_FLAGS) -ifeq ($(shell command -v $(TARGET_SIM) 2> /dev/null),) - $(error Target simulator executable '$(TARGET_SIM)` not found) -endif - -RISCV_PREFIX ?= riscv64-unknown-elf- -RISCV_GCC ?= $(RISCV_PREFIX)gcc -RISCV_OBJDUMP ?= $(RISCV_PREFIX)objdump -RISCV_GCC_OPTS ?= -g -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles $(RVTEST_DEFINES) - -COMPILE_CMD = $$(RISCV_GCC) $(1) $$(RISCV_GCC_OPTS) \ - -I$(ROOTDIR)/riscv-test-suite/env/ \ - -I$(TARGETDIR)/$(RISCV_TARGET)/ \ - -T$(TARGETDIR)/$(RISCV_TARGET)/link.ld \ - $$(<) -o $$@ -OBJ_CMD = $$(RISCV_OBJDUMP) $$@ -D > $$@.objdump; \ - $$(RISCV_OBJDUMP) $$@ --source > $$@.debug - - -COMPILE_TARGET=\ - $(COMPILE_CMD); \ - if [ $$$$? -ne 0 ] ; \ - then \ - echo "\e[31m$$(RISCV_GCC) failed for target $$(@) \e[39m" ; \ - exit 1 ; \ - fi ; \ - $(OBJ_CMD); \ - if [ $$$$? -ne 0 ] ; \ - then \ - echo "\e[31m $$(RISCV_OBJDUMP) failed for target $$(@) \e[39m" ; \ - exit 1 ; \ - fi ; - +include $(TARGETDIR)/spike/device/Makefile_common.inc RUN_CMD = $(TARGET_SIM) $(TARGET_FLAGS) --isa=rv64im \ +signature=$(*).signature.output +signature-granularity=4\ $< diff --git a/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv64i_m/Zifencei/Makefile.include b/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv64i_m/Zifencei/Makefile.include index 61916a29a..2c763bf56 100644 --- a/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv64i_m/Zifencei/Makefile.include +++ b/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv64i_m/Zifencei/Makefile.include @@ -1,38 +1,4 @@ -TARGET_SIM ?= spike -TARGET_FLAGS ?= $(RISCV_TARGET_FLAGS) -ifeq ($(shell command -v $(TARGET_SIM) 2> /dev/null),) - $(error Target simulator executable '$(TARGET_SIM)` not found) -endif - -RISCV_PREFIX ?= riscv64-unknown-elf- -RISCV_GCC ?= $(RISCV_PREFIX)gcc -RISCV_OBJDUMP ?= $(RISCV_PREFIX)objdump -RISCV_GCC_OPTS ?= -g -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles $(RVTEST_DEFINES) - -COMPILE_CMD = $$(RISCV_GCC) $(1) $$(RISCV_GCC_OPTS) \ - -I$(ROOTDIR)/riscv-test-suite/env/ \ - -I$(TARGETDIR)/$(RISCV_TARGET)/ \ - -T$(TARGETDIR)/$(RISCV_TARGET)/link.ld \ - $$(<) -o $$@ -OBJ_CMD = $$(RISCV_OBJDUMP) $$@ -D > $$@.objdump; \ - $$(RISCV_OBJDUMP) $$@ --source > $$@.debug - - - -COMPILE_TARGET=\ - $(COMPILE_CMD); \ - if [ $$$$? -ne 0 ] ; \ - then \ - echo "\e[31m$$(RISCV_GCC) failed for target $$(@) \e[39m" ; \ - exit 1 ; \ - fi ; \ - $(OBJ_CMD); \ - if [ $$$$? -ne 0 ] ; \ - then \ - echo "\e[31m $$(RISCV_OBJDUMP) failed for target $$(@) \e[39m" ; \ - exit 1 ; \ - fi ; - +include $(TARGETDIR)/spike/device/Makefile_common.inc RUN_CMD = $(TARGET_SIM) $(TARGET_FLAGS) --isa=rv64i \ +signature=$(*).signature.output +signature-granularity=4\ $< diff --git a/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv64i_m/privilege/Makefile.include b/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv64i_m/privilege/Makefile.include index 80e4a690a..5ef2802f9 100644 --- a/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv64i_m/privilege/Makefile.include +++ b/vendor/riscv/riscv-isa-sim/arch_test_target/spike/device/rv64i_m/privilege/Makefile.include @@ -1,37 +1,4 @@ -TARGET_SIM ?= spike -TARGET_FLAGS ?= $(RISCV_TARGET_FLAGS) -ifeq ($(shell command -v $(TARGET_SIM) 2> /dev/null),) - $(error Target simulator executable '$(TARGET_SIM)` not found) -endif - -RISCV_PREFIX ?= riscv64-unknown-elf- -RISCV_GCC ?= $(RISCV_PREFIX)gcc -RISCV_OBJDUMP ?= $(RISCV_PREFIX)objdump -RISCV_GCC_OPTS ?= -g -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles $(RVTEST_DEFINES) - -COMPILE_CMD = $$(RISCV_GCC) $(1) $$(RISCV_GCC_OPTS) \ - -I$(ROOTDIR)/riscv-test-suite/env/ \ - -I$(TARGETDIR)/$(RISCV_TARGET)/ \ - -T$(TARGETDIR)/$(RISCV_TARGET)/link.ld \ - $$(<) -o $$@ -OBJ_CMD = $$(RISCV_OBJDUMP) $$@ -D > $$@.objdump; \ - $$(RISCV_OBJDUMP) $$@ --source > $$@.debug - - -COMPILE_TARGET=\ - $(COMPILE_CMD); \ - if [ $$$$? -ne 0 ] ; \ - then \ - echo "\e[31m$$(RISCV_GCC) failed for target $$(@) \e[39m" ; \ - exit 1 ; \ - fi ; \ - $(OBJ_CMD); \ - if [ $$$$? -ne 0 ] ; \ - then \ - echo "\e[31m $$(RISCV_OBJDUMP) failed for target $$(@) \e[39m" ; \ - exit 1 ; \ - fi ; - +include $(TARGETDIR)/spike/device/Makefile_common.inc RUN_CMD = $(TARGET_SIM) $(TARGET_FLAGS) --isa=rv64ic \ +signature=$(*).signature.output +signature-granularity=4\ $< diff --git a/vendor/riscv/riscv-isa-sim/arch_test_target/spike/model_test.h b/vendor/riscv/riscv-isa-sim/arch_test_target/spike/model_test.h index 6aeb1c2dd..e968e43aa 100644 --- a/vendor/riscv/riscv-isa-sim/arch_test_target/spike/model_test.h +++ b/vendor/riscv/riscv-isa-sim/arch_test_target/spike/model_test.h @@ -22,7 +22,7 @@ addi x1, x1, 4; \ li x1, 1; \ write_tohost: \ - sw x1, tohost, t5; \ + sw x1, tohost, t1; \ self_loop: j self_loop; #define RVMODEL_BOOT diff --git a/vendor/riscv/riscv-isa-sim/config.h.in b/vendor/riscv/riscv-isa-sim/config.h.in index 46d8c00bb..f6755a1dd 100644 --- a/vendor/riscv/riscv-isa-sim/config.h.in +++ b/vendor/riscv/riscv-isa-sim/config.h.in @@ -33,6 +33,9 @@ /* define if the Boost::ASIO library is available */ #undef HAVE_BOOST_ASIO +/* define if the Boost::Regex library is available */ +#undef HAVE_BOOST_REGEX + /* Dynamic library loading is supported */ #undef HAVE_DLOPEN @@ -99,21 +102,9 @@ /* Define if subproject MCPPBS_SPROJ_NORM is enabled */ #undef RISCV_ENABLED -/* Enable commit log generation */ -#undef RISCV_ENABLE_COMMITLOG - -/* Enable hardware management of PTE accessed and dirty bits */ -#undef RISCV_ENABLE_DIRTY - /* Enable support for running target in either endianness */ #undef RISCV_ENABLE_DUAL_ENDIAN -/* Enable PC histogram generation */ -#undef RISCV_ENABLE_HISTOGRAM - -/* Enable hardware support for misaligned loads and stores */ -#undef RISCV_ENABLE_MISALIGNED - /* Define if subproject MCPPBS_SPROJ_NORM is enabled */ #undef SOFTFLOAT_ENABLED @@ -126,7 +117,7 @@ /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS -/* Default value for --with-target switch */ +/* Default value for --target switch */ #undef TARGET_ARCH /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most diff --git a/vendor/riscv/riscv-isa-sim/configure b/vendor/riscv/riscv-isa-sim/configure index 0af582f3c..419132f75 100755 --- a/vendor/riscv/riscv-isa-sim/configure +++ b/vendor/riscv/riscv-isa-sim/configure @@ -715,10 +715,6 @@ with_isa with_priv with_varch with_target -enable_commitlog -enable_histogram -enable_dirty -enable_misaligned enable_dual_endian ' ac_precious_vars='build_alias @@ -1362,12 +1358,6 @@ Optional Features: --enable-stow Enable stow-based install --enable-optional-subprojects Enable all optional subprojects - --enable-commitlog Enable commit log generation - --enable-histogram Enable PC histogram generation - --enable-dirty Enable hardware management of PTE accessed and dirty - bits - --enable-misaligned Enable hardware support for misaligned loads and - stores --enable-dual-endian Enable support for running target in either endianness @@ -1391,7 +1381,8 @@ Optional Packages: use the Regex library from boost - it is possible to specify a certain library for the linker e.g. --with-boost-regex=boost_regex-gcc-mt-d-1_33_1 - --with-isa=RV64IMAFDC Sets the default RISC-V ISA + --with-isa=RV64IMAFDC_zicntr_zihpm + Sets the default RISC-V ISA --with-priv=MSU Sets the default RISC-V privilege modes supported --with-varch=vlen:128,elen:64 Sets the default vector config @@ -5886,7 +5877,7 @@ _ACEOF else cat >>confdefs.h <<_ACEOF -#define DEFAULT_ISA "RV64IMAFDC" +#define DEFAULT_ISA "RV64IMAFDC_zicntr_zihpm" _ACEOF fi @@ -6054,58 +6045,6 @@ else fi -# Check whether --enable-commitlog was given. -if test "${enable_commitlog+set}" = set; then : - enableval=$enable_commitlog; -fi - -if test "x$enable_commitlog" = "xyes"; then : - - -$as_echo "#define RISCV_ENABLE_COMMITLOG /**/" >>confdefs.h - - -fi - -# Check whether --enable-histogram was given. -if test "${enable_histogram+set}" = set; then : - enableval=$enable_histogram; -fi - -if test "x$enable_histogram" = "xyes"; then : - - -$as_echo "#define RISCV_ENABLE_HISTOGRAM /**/" >>confdefs.h - - -fi - -# Check whether --enable-dirty was given. -if test "${enable_dirty+set}" = set; then : - enableval=$enable_dirty; -fi - -if test "x$enable_dirty" = "xyes"; then : - - -$as_echo "#define RISCV_ENABLE_DIRTY /**/" >>confdefs.h - - -fi - -# Check whether --enable-misaligned was given. -if test "${enable_misaligned+set}" = set; then : - enableval=$enable_misaligned; -fi - -if test "x$enable_misaligned" = "xyes"; then : - - -$as_echo "#define RISCV_ENABLE_MISALIGNED /**/" >>confdefs.h - - -fi - # Check whether --enable-dual-endian was given. if test "${enable_dual_endian+set}" = set; then : enableval=$enable_dual_endian; diff --git a/vendor/riscv/riscv-isa-sim/customext/cflush.cc b/vendor/riscv/riscv-isa-sim/customext/cflush.cc index 640c29fcc..485716a0a 100644 --- a/vendor/riscv/riscv-isa-sim/customext/cflush.cc +++ b/vendor/riscv/riscv-isa-sim/customext/cflush.cc @@ -1,5 +1,6 @@ #include "insn_macros.h" #include "extension.h" +#include "decode_macros.h" #include struct : public arg_t { @@ -24,9 +25,9 @@ class cflush_t : public extension_t std::vector get_instructions() { std::vector insns; - insns.push_back((insn_desc_t){0xFC000073, 0xFFF07FFF, custom_cflush, custom_cflush}); - insns.push_back((insn_desc_t){0xFC200073, 0xFFF07FFF, custom_cflush, custom_cflush}); - insns.push_back((insn_desc_t){0xFC100073, 0xFFF07FFF, custom_cflush, custom_cflush}); + insns.push_back((insn_desc_t){0xFC000073, 0xFFF07FFF, custom_cflush, custom_cflush, custom_cflush, custom_cflush, custom_cflush, custom_cflush, custom_cflush, custom_cflush}); + insns.push_back((insn_desc_t){0xFC200073, 0xFFF07FFF, custom_cflush, custom_cflush, custom_cflush, custom_cflush, custom_cflush, custom_cflush, custom_cflush, custom_cflush}); + insns.push_back((insn_desc_t){0xFC100073, 0xFFF07FFF, custom_cflush, custom_cflush, custom_cflush, custom_cflush, custom_cflush, custom_cflush, custom_cflush, custom_cflush}); return insns; } diff --git a/vendor/riscv/riscv-isa-sim/customext/cvxif.cc b/vendor/riscv/riscv-isa-sim/customext/cvxif.cc index dd1a7329a..11155500a 100644 --- a/vendor/riscv/riscv-isa-sim/customext/cvxif.cc +++ b/vendor/riscv/riscv-isa-sim/customext/cvxif.cc @@ -4,6 +4,8 @@ // // Original Author: Zbigniew CHAMSKI +#define DECODE_MACRO_USAGE_LOGGED 1 +#include "decode_macros.h" #include "cvxif.h" #include "mmu.h" #include @@ -43,7 +45,7 @@ class cvxif_t : public cvxif_extn_t // INSN_R personality serves to simplify access to standard encoding fields. cvxif_r_insn_t insn_r = copro_insn.r_type; - if (insn_r.opcode != MATCH_CUSTOM3) + if (insn_r.opcode != 0x7b /* MATCH_CUSTOM3 */) return false; else switch (insn_r.funct3) { @@ -148,16 +150,16 @@ class cvxif_t : public cvxif_extn_t case 1: // Perform RV load. If runtime XLEN is not 64, assume 32. if (p->get_xlen() == 64) - return MMU.load_int64(RS1 + insn.i_imm()); + return MMU.load(RS1 + insn.i_imm()); else - return MMU.load_int32(RS1 + insn.i_imm()); + return MMU.load(RS1 + insn.i_imm()); case 2: // Perform RV store. If runtime XLEN is not 64, assume 32. if (p->get_xlen() == 64) - MMU.store_uint64(RS1 + insn.s_imm(), RS2); + MMU.store(RS1 + insn.s_imm(), RS2); else - MMU.store_uint32(RS1 + insn.s_imm(), RS2); + MMU.store(RS1 + insn.s_imm(), RS2); // Writeback will be disabled by 'do_writeback_p'. break; diff --git a/vendor/riscv/riscv-isa-sim/customext/cvxif_test.c b/vendor/riscv/riscv-isa-sim/customext/cvxif_test.c index d39ca2229..bcd86151d 100644 --- a/vendor/riscv/riscv-isa-sim/customext/cvxif_test.c +++ b/vendor/riscv/riscv-isa-sim/customext/cvxif_test.c @@ -27,7 +27,7 @@ // core 0: tval 0x0000000000000001 // // The corresponding trace in 32-bit mode should be equivalent to -// +// // core 0: 0x8000205a (0x8002007b) custom3 (args unknown) // core 0: exception trap_load_address_misaligned, epc 0x8000205a // core 0: tval 0x00000001 diff --git a/vendor/riscv/riscv-isa-sim/customext/dummy_rocc.cc b/vendor/riscv/riscv-isa-sim/customext/dummy_rocc.cc index 85ab7aa69..8c051fad2 100644 --- a/vendor/riscv/riscv-isa-sim/customext/dummy_rocc.cc +++ b/vendor/riscv/riscv-isa-sim/customext/dummy_rocc.cc @@ -7,7 +7,7 @@ class dummy_rocc_t : public rocc_t public: const char* name() { return "dummy_rocc"; } - reg_t custom0(rocc_insn_t insn, reg_t xs1, reg_t xs2) + reg_t custom0(rocc_insn_t insn, reg_t xs1, reg_t UNUSED xs2) { reg_t prev_acc = acc[insn.rs2]; @@ -22,7 +22,7 @@ class dummy_rocc_t : public rocc_t case 1: // xd <- acc (the only real work is the return statement below) break; case 2: // acc[rs2] <- Mem[xs1] - acc[insn.rs2] = p->get_mmu()->load_uint64(xs1); + acc[insn.rs2] = p->get_mmu()->load(xs1); break; case 3: // acc[rs2] <- accX + xs1 acc[insn.rs2] += xs1; diff --git a/vendor/riscv/riscv-isa-sim/debug_rom/Makefile b/vendor/riscv/riscv-isa-sim/debug_rom/Makefile index c5f2205de..d6546e9a6 100644 --- a/vendor/riscv/riscv-isa-sim/debug_rom/Makefile +++ b/vendor/riscv/riscv-isa-sim/debug_rom/Makefile @@ -18,7 +18,7 @@ all: $(patsubst %,%.h,$(ELFS)) $(OBJCOPY) -O binary --only-section .text $^ $@ debug_rom: $(DEPS) - $(COMPILE) -o $@ $^ + $(COMPILE) -o $@ $< clean: rm -f $(ELFS) debug_rom*.raw debug_rom.h diff --git a/vendor/riscv/riscv-isa-sim/debug_rom/debug_rom.S b/vendor/riscv/riscv-isa-sim/debug_rom/debug_rom.S index 8d8e4cd03..2d361397e 100755 --- a/vendor/riscv/riscv-isa-sim/debug_rom/debug_rom.S +++ b/vendor/riscv/riscv-isa-sim/debug_rom/debug_rom.S @@ -23,7 +23,7 @@ _entry: // This fence is required because the execution may have written something // into the Abstract Data or Program Buffer registers. fence - csrw CSR_DSCRATCH, s0 // Save s0 to allow signaling MHARTID + csrw CSR_DSCRATCH0, s0 // Save s0 to allow signaling MHARTID // We continue to let the hart know that we are halted in order that // a DM which was reset is still made aware that a hart is halted. @@ -46,14 +46,14 @@ _exception: // Restore S0, which we always save to dscratch. // We need this in case the user tried an abstract write to a // non-existent CSR. - csrr s0, CSR_DSCRATCH + csrr s0, CSR_DSCRATCH0 sw zero, DEBUG_ROM_EXCEPTION(zero) // Let debug module know you got an exception. ebreak going: csrr s0, CSR_MHARTID sw s0, DEBUG_ROM_GOING(zero) // When debug module sees this write, the GO flag is reset. - csrr s0, CSR_DSCRATCH // Restore s0 here + csrr s0, CSR_DSCRATCH0 // Restore s0 here fence fence.i jalr zero, zero, %lo(whereto) // Debug module will put different instructions and data in the RAM, @@ -63,7 +63,7 @@ going: _resume: csrr s0, CSR_MHARTID sw s0, DEBUG_ROM_RESUMING(zero) // When Debug Module sees this write, the RESUME flag is reset. - csrr s0, CSR_DSCRATCH // Restore s0 + csrr s0, CSR_DSCRATCH0 // Restore s0 dret // END OF ACTUAL "ROM" CONTENTS. BELOW IS JUST FOR LINKER SCRIPT. diff --git a/vendor/riscv/riscv-isa-sim/disasm/disasm.cc b/vendor/riscv/riscv-isa-sim/disasm/disasm.cc index 1e39c70e6..fef9facab 100644 --- a/vendor/riscv/riscv-isa-sim/disasm/disasm.cc +++ b/vendor/riscv/riscv-isa-sim/disasm/disasm.cc @@ -1,12 +1,19 @@ // See LICENSE for license details. #include "disasm.h" +#include "decode_macros.h" #include #include #include #include #include #include +// For std::reverse: +#include + +#ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wunused-variable" +#endif // Indicates that the next arg (only) is optional. // If the result of converting the next arg to a string is "" @@ -19,6 +26,18 @@ struct : public arg_t { } } load_address; +struct : public arg_t { + std::string to_string(insn_t insn) const { + return std::to_string((int)insn.rvc_lbimm()) + '(' + xpr_name[insn.rvc_rs1s()] + ')'; + } +} rvb_b_address; + +struct : public arg_t { + std::string to_string(insn_t insn) const { + return std::to_string((int)insn.rvc_lhimm()) + '(' + xpr_name[insn.rvc_rs1s()] + ')'; + } +} rvb_h_address; + struct : public arg_t { std::string to_string(insn_t insn) const { return std::to_string((int)insn.s_imm()) + '(' + xpr_name[insn.rs1()] + ')'; @@ -43,6 +62,52 @@ struct : public arg_t { } } xrs1; +struct : public arg_t { + std::string to_string(insn_t insn) const { + return std::to_string((uint32_t)insn.rvc_index()); + } +} rvcm_jt_index; + +struct : public arg_t { + std::string to_string(insn_t insn) const { + int rlist = insn.rvc_rlist(); + if (rlist >= 4) { + switch(rlist) { + case 4: return "{ra}"; + case 5: return "{ra, s0}"; + case 15: return "{ra, s0-s11}"; + default: return "{ra, s0-s" + std::to_string(rlist - 5)+'}'; + } + } else { + return "unsupport rlist"; + } + } +} rvcm_pushpop_rlist; + +struct : public arg_t { + std::string to_string(insn_t insn) const { + return '-' + std::to_string(insn.zcmp_stack_adjustment(32)); + } +} rvcm_push_stack_adj_32; + +struct : public arg_t { + std::string to_string(insn_t insn) const { + return '-' + std::to_string(insn.zcmp_stack_adjustment(64)); + } +} rvcm_push_stack_adj_64; + +struct : public arg_t { + std::string to_string(insn_t insn) const { + return std::to_string(insn.zcmp_stack_adjustment(32)); + } +} rvcm_pop_stack_adj_32; + +struct : public arg_t { + std::string to_string(insn_t insn) const { + return std::to_string(insn.zcmp_stack_adjustment(64)); + } +} rvcm_pop_stack_adj_64; + struct : public arg_t { std::string to_string(insn_t insn) const { return xpr_name[insn.rs2()]; @@ -178,7 +243,7 @@ struct : public arg_t { } rvc_fp_rs2s; struct : public arg_t { - std::string to_string(insn_t insn) const { + std::string to_string(insn_t UNUSED insn) const { return xpr_name[X_SP]; } } rvc_sp; @@ -312,7 +377,7 @@ struct : public arg_t { } vm; struct : public arg_t { - std::string to_string(insn_t insn) const { + std::string to_string(insn_t UNUSED insn) const { return "v0"; } } v0; @@ -356,7 +421,7 @@ struct : public arg_t { } v_vtype; struct : public arg_t { - std::string to_string(insn_t insn) const { + std::string to_string(insn_t UNUSED insn) const { return "x0"; } } x0; @@ -415,6 +480,18 @@ struct : public arg_t { } } p_imm6; +struct : public arg_t { + std::string to_string(insn_t insn) const { + return std::to_string((int)insn.bs()); + } +} bs; + +struct : public arg_t { + std::string to_string(insn_t insn) const { + return std::to_string((int)insn.rcon()); + } +} rcon; + typedef struct { reg_t match; reg_t mask; @@ -622,7 +699,7 @@ static void NOINLINE add_unknown_insns(disassembler_t* d) #undef DECLARE_INSN } -disassembler_t::disassembler_t(int xlen) +void disassembler_t::add_instructions(const isa_parser_t* isa) { const uint32_t mask_rd = 0x1fUL << 7; const uint32_t match_rd_ra = 1UL << 7; @@ -658,6 +735,7 @@ disassembler_t::disassembler_t(int xlen) #define DEFINE_I0TYPE(name, code) DISASM_INSN(name, code, mask_rs1, {&xrd, &imm}) #define DEFINE_I1TYPE(name, code) DISASM_INSN(name, code, mask_imm, {&xrd, &xrs1}) #define DEFINE_I2TYPE(name, code) DISASM_INSN(name, code, mask_rd | mask_imm, {&xrs1}) + #define DEFINE_PREFETCH(code) DISASM_INSN(#code, code, 0, {&store_address}) #define DEFINE_LTYPE(code) DISASM_INSN(#code, code, 0, {&xrd, &bigimm}) #define DEFINE_BTYPE(code) add_btype_insn(this, #code, match_##code, mask_##code); #define DEFINE_B1TYPE(name, code) add_b1type_insn(this, name, match_##code, mask_##code); @@ -679,6 +757,14 @@ disassembler_t::disassembler_t(int xlen) add_insn(new disasm_insn_t("unimp", match_csrrw|(CSR_CYCLE<<20), 0xffffffff, {})); add_insn(new disasm_insn_t("c.unimp", 0, 0xffff, {})); + // Following are HINTs, so they must precede their corresponding base-ISA + // instructions. We do not condition them on Zicbop/Zihintpause because, + // definitionally, all implementations provide them. + DEFINE_PREFETCH(prefetch_r); + DEFINE_PREFETCH(prefetch_w); + DEFINE_PREFETCH(prefetch_i); + DEFINE_NOARG(pause); + DEFINE_XLOAD(lb) DEFINE_XLOAD(lbu) DEFINE_XLOAD(lh) @@ -692,39 +778,30 @@ disassembler_t::disassembler_t(int xlen) DEFINE_XSTORE(sw) DEFINE_XSTORE(sd) - DEFINE_XAMO(amoadd_w) - DEFINE_XAMO(amoswap_w) - DEFINE_XAMO(amoand_w) - DEFINE_XAMO(amoor_w) - DEFINE_XAMO(amoxor_w) - DEFINE_XAMO(amomin_w) - DEFINE_XAMO(amomax_w) - DEFINE_XAMO(amominu_w) - DEFINE_XAMO(amomaxu_w) - DEFINE_XAMO(amoadd_d) - DEFINE_XAMO(amoswap_d) - DEFINE_XAMO(amoand_d) - DEFINE_XAMO(amoor_d) - DEFINE_XAMO(amoxor_d) - DEFINE_XAMO(amomin_d) - DEFINE_XAMO(amomax_d) - DEFINE_XAMO(amominu_d) - DEFINE_XAMO(amomaxu_d) - - DEFINE_XLOAD_BASE(lr_w) - DEFINE_XAMO(sc_w) - DEFINE_XLOAD_BASE(lr_d) - DEFINE_XAMO(sc_d) - - DEFINE_FLOAD(flw) - DEFINE_FLOAD(fld) - DEFINE_FLOAD(flh) - DEFINE_FLOAD(flq) - - DEFINE_FSTORE(fsw) - DEFINE_FSTORE(fsd) - DEFINE_FSTORE(fsh) - DEFINE_FSTORE(fsq) + if (isa->extension_enabled('A')) { + DEFINE_XAMO(amoadd_w) + DEFINE_XAMO(amoswap_w) + DEFINE_XAMO(amoand_w) + DEFINE_XAMO(amoor_w) + DEFINE_XAMO(amoxor_w) + DEFINE_XAMO(amomin_w) + DEFINE_XAMO(amomax_w) + DEFINE_XAMO(amominu_w) + DEFINE_XAMO(amomaxu_w) + DEFINE_XAMO(amoadd_d) + DEFINE_XAMO(amoswap_d) + DEFINE_XAMO(amoand_d) + DEFINE_XAMO(amoor_d) + DEFINE_XAMO(amoxor_d) + DEFINE_XAMO(amomin_d) + DEFINE_XAMO(amomax_d) + DEFINE_XAMO(amominu_d) + DEFINE_XAMO(amomaxu_d) + DEFINE_XLOAD_BASE(lr_w) + DEFINE_XAMO(sc_w) + DEFINE_XLOAD_BASE(lr_d) + DEFINE_XAMO(sc_d) + } add_insn(new disasm_insn_t("j", match_jal, mask_jal | mask_rd, {&jump_target})); add_insn(new disasm_insn_t("jal", match_jal | match_rd_ra, mask_jal | mask_rd, {&jump_target})); @@ -783,102 +860,19 @@ disassembler_t::disassembler_t(int xlen) DEFINE_RTYPE(sra); DEFINE_RTYPE(or); DEFINE_RTYPE(and); - DEFINE_RTYPE(mul); - DEFINE_RTYPE(mulh); - DEFINE_RTYPE(mulhu); - DEFINE_RTYPE(mulhsu); - DEFINE_RTYPE(div); - DEFINE_RTYPE(divu); - DEFINE_RTYPE(rem); - DEFINE_RTYPE(remu); DEFINE_RTYPE(addw); DEFINE_RTYPE(subw); DEFINE_RTYPE(sllw); DEFINE_RTYPE(srlw); DEFINE_RTYPE(sraw); - DEFINE_RTYPE(mulw); - DEFINE_RTYPE(divw); - DEFINE_RTYPE(divuw); - DEFINE_RTYPE(remw); - DEFINE_RTYPE(remuw); - - DEFINE_ITYPE_SHIFT(slli_uw); - add_insn(new disasm_insn_t("zext.w", match_add_uw, mask_add_uw | mask_rs2, {&xrd, &xrs1})); - DEFINE_RTYPE(add_uw); - DEFINE_RTYPE(sh1add); - DEFINE_RTYPE(sh2add); - DEFINE_RTYPE(sh3add); - DEFINE_RTYPE(sh1add_uw); - DEFINE_RTYPE(sh2add_uw); - DEFINE_RTYPE(sh3add_uw); - DEFINE_RTYPE(ror); - DEFINE_RTYPE(rorw); - DEFINE_RTYPE(rol); - DEFINE_RTYPE(rolw); - DEFINE_ITYPE_SHIFT(rori); - DEFINE_ITYPE_SHIFT(roriw); - DEFINE_R1TYPE(ctz); - DEFINE_R1TYPE(ctzw); - DEFINE_R1TYPE(clz); - DEFINE_R1TYPE(clzw); - DEFINE_R1TYPE(cpop); - DEFINE_R1TYPE(cpopw); - DEFINE_RTYPE(min); - DEFINE_RTYPE(minu); - DEFINE_RTYPE(max); - DEFINE_RTYPE(maxu); - DEFINE_RTYPE(andn); - DEFINE_RTYPE(orn); - DEFINE_RTYPE(xnor); - DEFINE_R1TYPE(sext_b); - DEFINE_R1TYPE(sext_h); - add_insn(new disasm_insn_t("zext.h", (xlen == 32 ? match_pack : match_packw), mask_pack | mask_rs2, {&xrd, &xrs1})); - DEFINE_RTYPE(pack); - DEFINE_RTYPE(packu); - DEFINE_RTYPE(packw); - DEFINE_RTYPE(grev); - add_insn(new disasm_insn_t("rev", match_grevi | ((xlen - 1) << imm_shift), mask_grevi | mask_imm, {&xrd, &xrs1})); - add_insn(new disasm_insn_t("rev8", match_grevi | ((xlen - 8) << imm_shift), mask_grevi | mask_imm, {&xrd, &xrs1})); - add_insn(new disasm_insn_t("brev8", match_grevi | (0x7 << imm_shift), mask_grevi | mask_imm, {&xrd, &xrs1})); // brev8 - add_insn(new disasm_insn_t("rev8.h", match_grevi | (0x8 << imm_shift), mask_grevi | mask_imm, {&xrd, &xrs1})); // swap16 - DEFINE_ITYPE_SHIFT(grevi); - DEFINE_RTYPE(gorc); - add_insn(new disasm_insn_t("orc.b", match_gorci | (0x7 << imm_shift), mask_grevi | mask_imm, {&xrd, &xrs1})); - DEFINE_ITYPE_SHIFT(gorci); - DEFINE_RTYPE(xperm4); - DEFINE_RTYPE(xperm8); - DEFINE_RTYPE(xperm16); - DEFINE_RTYPE(xperm32); - - DEFINE_RTYPE(bclr); - DEFINE_RTYPE(binv); - DEFINE_RTYPE(bset); - DEFINE_RTYPE(bext); - DEFINE_ITYPE_SHIFT(bclri); - DEFINE_ITYPE_SHIFT(binvi); - DEFINE_ITYPE_SHIFT(bseti); - DEFINE_ITYPE_SHIFT(bexti); - - DEFINE_R3TYPE(cmix); - DEFINE_R3TYPE(fsr); - DEFINE_R3TYPE(fsri); - DEFINE_R3TYPE(fsriw); - DEFINE_R3TYPE(fsrw); DEFINE_NOARG(ecall); DEFINE_NOARG(ebreak); - DEFINE_NOARG(sret); DEFINE_NOARG(mret); DEFINE_NOARG(dret); DEFINE_NOARG(wfi); add_insn(new disasm_insn_t("fence", match_fence, mask_fence, {&iorw})); DEFINE_NOARG(fence_i); - DEFINE_SFENCE_TYPE(sfence_vma); - DEFINE_NOARG(sfence_w_inval); - DEFINE_NOARG(sfence_inval_ir); - DEFINE_SFENCE_TYPE(sinval_vma); - DEFINE_SFENCE_TYPE(hinval_vvma); - DEFINE_SFENCE_TYPE(hinval_gvma); add_insn(new disasm_insn_t("csrr", match_csrrs, mask_csrrs | mask_rs1, {&xrd, &csr})); add_insn(new disasm_insn_t("csrw", match_csrrw, mask_csrrw | mask_rd, {&csr, &xrs1})); @@ -894,625 +888,901 @@ disassembler_t::disassembler_t(int xlen) add_insn(new disasm_insn_t("csrrsi", match_csrrsi, mask_csrrsi, {&xrd, &csr, &zimm5})); add_insn(new disasm_insn_t("csrrci", match_csrrci, mask_csrrci, {&xrd, &csr, &zimm5})); - DEFINE_FRTYPE(fadd_s); - DEFINE_FRTYPE(fsub_s); - DEFINE_FRTYPE(fmul_s); - DEFINE_FRTYPE(fdiv_s); - DEFINE_FR1TYPE(fsqrt_s); - DEFINE_FRTYPE(fmin_s); - DEFINE_FRTYPE(fmax_s); - DEFINE_FR3TYPE(fmadd_s); - DEFINE_FR3TYPE(fmsub_s); - DEFINE_FR3TYPE(fnmadd_s); - DEFINE_FR3TYPE(fnmsub_s); - DEFINE_FRTYPE(fsgnj_s); - DEFINE_FRTYPE(fsgnjn_s); - DEFINE_FRTYPE(fsgnjx_s); - DEFINE_FR1TYPE(fcvt_s_d); - DEFINE_FR1TYPE(fcvt_s_q); - DEFINE_XFTYPE(fcvt_s_l); - DEFINE_XFTYPE(fcvt_s_lu); - DEFINE_XFTYPE(fcvt_s_w); - DEFINE_XFTYPE(fcvt_s_wu); - DEFINE_XFTYPE(fcvt_s_wu); - DEFINE_XFTYPE(fmv_w_x); - DEFINE_FXTYPE(fcvt_l_s); - DEFINE_FXTYPE(fcvt_lu_s); - DEFINE_FXTYPE(fcvt_w_s); - DEFINE_FXTYPE(fcvt_wu_s); - DEFINE_FXTYPE(fclass_s); - DEFINE_FXTYPE(fmv_x_w); - DEFINE_FX2TYPE(feq_s); - DEFINE_FX2TYPE(flt_s); - DEFINE_FX2TYPE(fle_s); + if (isa->extension_enabled('S')) { + DEFINE_NOARG(sret); + DEFINE_SFENCE_TYPE(sfence_vma); + } - DEFINE_FRTYPE(fadd_d); - DEFINE_FRTYPE(fsub_d); - DEFINE_FRTYPE(fmul_d); - DEFINE_FRTYPE(fdiv_d); - DEFINE_FR1TYPE(fsqrt_d); - DEFINE_FRTYPE(fmin_d); - DEFINE_FRTYPE(fmax_d); - DEFINE_FR3TYPE(fmadd_d); - DEFINE_FR3TYPE(fmsub_d); - DEFINE_FR3TYPE(fnmadd_d); - DEFINE_FR3TYPE(fnmsub_d); - DEFINE_FRTYPE(fsgnj_d); - DEFINE_FRTYPE(fsgnjn_d); - DEFINE_FRTYPE(fsgnjx_d); - DEFINE_FR1TYPE(fcvt_d_s); - DEFINE_FR1TYPE(fcvt_d_q); - DEFINE_XFTYPE(fcvt_d_l); - DEFINE_XFTYPE(fcvt_d_lu); - DEFINE_XFTYPE(fcvt_d_w); - DEFINE_XFTYPE(fcvt_d_wu); - DEFINE_XFTYPE(fcvt_d_wu); - DEFINE_XFTYPE(fmv_d_x); - DEFINE_FXTYPE(fcvt_l_d); - DEFINE_FXTYPE(fcvt_lu_d); - DEFINE_FXTYPE(fcvt_w_d); - DEFINE_FXTYPE(fcvt_wu_d); - DEFINE_FXTYPE(fclass_d); - DEFINE_FXTYPE(fmv_x_d); - DEFINE_FX2TYPE(feq_d); - DEFINE_FX2TYPE(flt_d); - DEFINE_FX2TYPE(fle_d); + if (isa->extension_enabled('M')) { + DEFINE_RTYPE(mul); + DEFINE_RTYPE(mulh); + DEFINE_RTYPE(mulhu); + DEFINE_RTYPE(mulhsu); + DEFINE_RTYPE(mulw); + DEFINE_RTYPE(div); + DEFINE_RTYPE(divu); + DEFINE_RTYPE(rem); + DEFINE_RTYPE(remu); + DEFINE_RTYPE(divw); + DEFINE_RTYPE(divuw); + DEFINE_RTYPE(remw); + DEFINE_RTYPE(remuw); + } - DEFINE_FRTYPE(fadd_h); - DEFINE_FRTYPE(fsub_h); - DEFINE_FRTYPE(fmul_h); - DEFINE_FRTYPE(fdiv_h); - DEFINE_FR1TYPE(fsqrt_h); - DEFINE_FRTYPE(fmin_h); - DEFINE_FRTYPE(fmax_h); - DEFINE_FR3TYPE(fmadd_h); - DEFINE_FR3TYPE(fmsub_h); - DEFINE_FR3TYPE(fnmadd_h); - DEFINE_FR3TYPE(fnmsub_h); - DEFINE_FRTYPE(fsgnj_h); - DEFINE_FRTYPE(fsgnjn_h); - DEFINE_FRTYPE(fsgnjx_h); - DEFINE_FR1TYPE(fcvt_h_s); - DEFINE_FR1TYPE(fcvt_h_d); - DEFINE_FR1TYPE(fcvt_h_q); - DEFINE_FR1TYPE(fcvt_s_h); - DEFINE_FR1TYPE(fcvt_d_h); - DEFINE_FR1TYPE(fcvt_q_h); - DEFINE_XFTYPE(fcvt_h_l); - DEFINE_XFTYPE(fcvt_h_lu); - DEFINE_XFTYPE(fcvt_h_w); - DEFINE_XFTYPE(fcvt_h_wu); - DEFINE_XFTYPE(fcvt_h_wu); - DEFINE_XFTYPE(fmv_h_x); - DEFINE_FXTYPE(fcvt_l_h); - DEFINE_FXTYPE(fcvt_lu_h); - DEFINE_FXTYPE(fcvt_w_h); - DEFINE_FXTYPE(fcvt_wu_h); - DEFINE_FXTYPE(fclass_h); - DEFINE_FXTYPE(fmv_x_h); - DEFINE_FX2TYPE(feq_h); - DEFINE_FX2TYPE(flt_h); - DEFINE_FX2TYPE(fle_h); - - DEFINE_FRTYPE(fadd_q); - DEFINE_FRTYPE(fsub_q); - DEFINE_FRTYPE(fmul_q); - DEFINE_FRTYPE(fdiv_q); - DEFINE_FR1TYPE(fsqrt_q); - DEFINE_FRTYPE(fmin_q); - DEFINE_FRTYPE(fmax_q); - DEFINE_FR3TYPE(fmadd_q); - DEFINE_FR3TYPE(fmsub_q); - DEFINE_FR3TYPE(fnmadd_q); - DEFINE_FR3TYPE(fnmsub_q); - DEFINE_FRTYPE(fsgnj_q); - DEFINE_FRTYPE(fsgnjn_q); - DEFINE_FRTYPE(fsgnjx_q); - DEFINE_FR1TYPE(fcvt_q_s); - DEFINE_FR1TYPE(fcvt_q_d); - DEFINE_XFTYPE(fcvt_q_l); - DEFINE_XFTYPE(fcvt_q_lu); - DEFINE_XFTYPE(fcvt_q_w); - DEFINE_XFTYPE(fcvt_q_wu); - DEFINE_XFTYPE(fcvt_q_wu); - DEFINE_FXTYPE(fcvt_l_q); - DEFINE_FXTYPE(fcvt_lu_q); - DEFINE_FXTYPE(fcvt_w_q); - DEFINE_FXTYPE(fcvt_wu_q); - DEFINE_FXTYPE(fclass_q); - DEFINE_FX2TYPE(feq_q); - DEFINE_FX2TYPE(flt_q); - DEFINE_FX2TYPE(fle_q); - - - // ext-h - DEFINE_XLOAD_BASE(hlv_b) - DEFINE_XLOAD_BASE(hlv_bu) - DEFINE_XLOAD_BASE(hlv_h) - DEFINE_XLOAD_BASE(hlv_hu) - DEFINE_XLOAD_BASE(hlv_w) - DEFINE_XLOAD_BASE(hlv_wu) - DEFINE_XLOAD_BASE(hlv_d) - - DEFINE_XLOAD_BASE(hlvx_hu) - DEFINE_XLOAD_BASE(hlvx_wu) - - DEFINE_XSTORE_BASE(hsv_b) - DEFINE_XSTORE_BASE(hsv_h) - DEFINE_XSTORE_BASE(hsv_w) - DEFINE_XSTORE_BASE(hsv_d) - - DEFINE_SFENCE_TYPE(hfence_gvma); - DEFINE_SFENCE_TYPE(hfence_vvma); - - - // ext-c - DISASM_INSN("c.ebreak", c_add, mask_rd | mask_rvc_rs2, {}); - add_insn(new disasm_insn_t("ret", match_c_jr | match_rd_ra, mask_c_jr | mask_rd | mask_rvc_imm, {})); - DISASM_INSN("c.jr", c_jr, mask_rvc_imm, {&rvc_rs1}); - DISASM_INSN("c.jalr", c_jalr, mask_rvc_imm, {&rvc_rs1}); - DISASM_INSN("c.nop", c_addi, mask_rd | mask_rvc_imm, {}); - DISASM_INSN("c.addi16sp", c_addi16sp, mask_rd, {&rvc_sp, &rvc_addi16sp_imm}); - DISASM_INSN("c.addi4spn", c_addi4spn, 0, {&rvc_rs2s, &rvc_sp, &rvc_addi4spn_imm}); - DISASM_INSN("c.li", c_li, 0, {&xrd, &rvc_imm}); - DISASM_INSN("c.lui", c_lui, 0, {&xrd, &rvc_uimm}); - DISASM_INSN("c.addi", c_addi, 0, {&xrd, &rvc_imm}); - DISASM_INSN("c.slli", c_slli, 0, {&rvc_rs1, &rvc_shamt}); - DISASM_INSN("c.srli", c_srli, 0, {&rvc_rs1s, &rvc_shamt}); - DISASM_INSN("c.srai", c_srai, 0, {&rvc_rs1s, &rvc_shamt}); - DISASM_INSN("c.andi", c_andi, 0, {&rvc_rs1s, &rvc_imm}); - DISASM_INSN("c.mv", c_mv, 0, {&xrd, &rvc_rs2}); - DISASM_INSN("c.add", c_add, 0, {&xrd, &rvc_rs2}); - DISASM_INSN("c.addw", c_addw, 0, {&rvc_rs1s, &rvc_rs2s}); - DISASM_INSN("c.sub", c_sub, 0, {&rvc_rs1s, &rvc_rs2s}); - DISASM_INSN("c.subw", c_subw, 0, {&rvc_rs1s, &rvc_rs2s}); - DISASM_INSN("c.and", c_and, 0, {&rvc_rs1s, &rvc_rs2s}); - DISASM_INSN("c.or", c_or, 0, {&rvc_rs1s, &rvc_rs2s}); - DISASM_INSN("c.xor", c_xor, 0, {&rvc_rs1s, &rvc_rs2s}); - DISASM_INSN("c.lwsp", c_lwsp, 0, {&xrd, &rvc_lwsp_address}); - DISASM_INSN("c.fld", c_fld, 0, {&rvc_fp_rs2s, &rvc_ld_address}); - DISASM_INSN("c.swsp", c_swsp, 0, {&rvc_rs2, &rvc_swsp_address}); - DISASM_INSN("c.lw", c_lw, 0, {&rvc_rs2s, &rvc_lw_address}); - DISASM_INSN("c.sw", c_sw, 0, {&rvc_rs2s, &rvc_lw_address}); - DISASM_INSN("c.beqz", c_beqz, 0, {&rvc_rs1s, &rvc_branch_target}); - DISASM_INSN("c.bnez", c_bnez, 0, {&rvc_rs1s, &rvc_branch_target}); - DISASM_INSN("c.j", c_j, 0, {&rvc_jump_target}); - DISASM_INSN("c.fldsp", c_fldsp, 0, {&frd, &rvc_ldsp_address}); - DISASM_INSN("c.fsd", c_fsd, 0, {&rvc_fp_rs2s, &rvc_ld_address}); - DISASM_INSN("c.fsdsp", c_fsdsp, 0, {&rvc_fp_rs2, &rvc_sdsp_address}); - - DISASM_INSN("vsetivli", vsetivli, 0, {&xrd, &zimm5, &v_vtype}); - DISASM_INSN("vsetvli", vsetvli, 0, {&xrd, &xrs1, &v_vtype}); - DEFINE_RTYPE(vsetvl); - - std::vector v_ld_unit = {&vd, &v_address, opt, &vm}; - std::vector v_st_unit = {&vs3, &v_address, opt, &vm}; - std::vector v_ld_stride = {&vd, &v_address, &xrs2, opt, &vm}; - std::vector v_st_stride = {&vs3, &v_address, &xrs2, opt, &vm}; - std::vector v_ld_index = {&vd, &v_address, &vs2, opt, &vm}; - std::vector v_st_index = {&vs3, &v_address, &vs2, opt, &vm}; - - add_insn(new disasm_insn_t("vlm.v", match_vlm_v, mask_vlm_v, v_ld_unit)); - add_insn(new disasm_insn_t("vsm.v", match_vsm_v, mask_vsm_v, v_st_unit)); - - // handle vector segment load/store - for (size_t elt = 0; elt <= 7; ++elt) { - const custom_fmt_t template_insn[] = { - {match_vle8_v, mask_vle8_v, "vl%se%d.v", v_ld_unit}, - {match_vse8_v, mask_vse8_v, "vs%se%d.v", v_st_unit}, - - {match_vluxei8_v, mask_vluxei8_v, "vlux%sei%d.v", v_ld_index}, - {match_vsuxei8_v, mask_vsuxei8_v, "vsux%sei%d.v", v_st_index}, - - {match_vlse8_v, mask_vlse8_v, "vls%se%d.v", v_ld_stride}, - {match_vsse8_v, mask_vsse8_v, "vss%se%d.v", v_st_stride}, - - {match_vloxei8_v, mask_vloxei8_v, "vlox%sei%d.v", v_ld_index}, - {match_vsoxei8_v, mask_vsoxei8_v, "vsox%sei%d.v", v_st_index}, - - {match_vle8ff_v, mask_vle8ff_v, "vl%se%dff.v", v_ld_unit} - }; - - reg_t elt_map[] = {0x00000000, 0x00005000, 0x00006000, 0x00007000, - 0x10000000, 0x10005000, 0x10006000, 0x10007000}; - - for (unsigned nf = 0; nf <= 7; ++nf) { - char seg_str[8] = ""; - if (nf) - sprintf(seg_str, "seg%u", nf + 1); - - for (auto item : template_insn) { - const reg_t match_nf = nf << 29; - char buf[128]; - sprintf(buf, item.fmt, seg_str, 8 << elt); - add_insn(new disasm_insn_t( - buf, - ((item.match | match_nf) & ~mask_vldst) | elt_map[elt], - item.mask | mask_nf, - item.arg - )); - } - } - - const custom_fmt_t template_insn2[] = { - {match_vl1re8_v, mask_vl1re8_v, "vl%dre%d.v", v_ld_unit}, - }; - - for (reg_t i = 0, nf = 7; i < 4; i++, nf >>= 1) { - for (auto item : template_insn2) { - const reg_t match_nf = nf << 29; - char buf[128]; - sprintf(buf, item.fmt, nf + 1, 8 << elt); - add_insn(new disasm_insn_t( - buf, - item.match | match_nf | elt_map[elt], - item.mask | mask_nf, - item.arg - )); - } + if (isa->extension_enabled(EXT_ZBA)) { + DEFINE_RTYPE(sh1add); + DEFINE_RTYPE(sh2add); + DEFINE_RTYPE(sh3add); + if (isa->get_max_xlen() == 64) { + DEFINE_ITYPE_SHIFT(slli_uw); + add_insn(new disasm_insn_t("zext.w", match_add_uw, mask_add_uw | mask_rs2, {&xrd, &xrs1})); + DEFINE_RTYPE(add_uw); + DEFINE_RTYPE(sh1add_uw); + DEFINE_RTYPE(sh2add_uw); + DEFINE_RTYPE(sh3add_uw); } } - #define DISASM_ST_WHOLE_INSN(name, nf) \ - add_insn(new disasm_insn_t(#name, match_vs1r_v | (nf << 29), \ - mask_vs1r_v | mask_nf, \ - {&vs3, &v_address})); - DISASM_ST_WHOLE_INSN(vs1r.v, 0); - DISASM_ST_WHOLE_INSN(vs2r.v, 1); - DISASM_ST_WHOLE_INSN(vs4r.v, 3); - DISASM_ST_WHOLE_INSN(vs8r.v, 7); + if (isa->extension_enabled(EXT_ZBB)) { + DEFINE_RTYPE(ror); + DEFINE_RTYPE(rol); + DEFINE_ITYPE_SHIFT(rori); + DEFINE_R1TYPE(ctz); + DEFINE_R1TYPE(clz); + DEFINE_R1TYPE(cpop); + DEFINE_RTYPE(min); + DEFINE_RTYPE(minu); + DEFINE_RTYPE(max); + DEFINE_RTYPE(maxu); + DEFINE_RTYPE(andn); + DEFINE_RTYPE(orn); + DEFINE_RTYPE(xnor); + DEFINE_R1TYPE(sext_b); + DEFINE_R1TYPE(sext_h); + add_insn(new disasm_insn_t("rev8", match_grevi | ((isa->get_max_xlen() - 8) << imm_shift), mask_grevi | mask_imm, {&xrd, &xrs1})); + add_insn(new disasm_insn_t("orc.b", match_gorci | (0x7 << imm_shift), mask_grevi | mask_imm, {&xrd, &xrs1})); + add_insn(new disasm_insn_t("zext.h", (isa->get_max_xlen() == 32 ? match_pack : match_packw), mask_pack | mask_rs2, {&xrd, &xrs1})); + if (isa->get_max_xlen() == 64) { + DEFINE_RTYPE(rorw); + DEFINE_RTYPE(rolw); + DEFINE_ITYPE_SHIFT(roriw); + DEFINE_R1TYPE(ctzw); + DEFINE_R1TYPE(clzw); + DEFINE_R1TYPE(cpopw); + } + } - #undef DISASM_ST_WHOLE_INSN + if (isa->extension_enabled(EXT_ZBC)) { + DEFINE_RTYPE(clmul); + DEFINE_RTYPE(clmulh); + DEFINE_RTYPE(clmulr); + } - #define DEFINE_VECTOR_V(code) add_vector_v_insn(this, #code, match_##code, mask_##code) - #define DEFINE_VECTOR_VV(code) add_vector_vv_insn(this, #code, match_##code, mask_##code) - #define DEFINE_VECTOR_VX(code) add_vector_vx_insn(this, #code, match_##code, mask_##code) - #define DEFINE_VECTOR_VF(code) add_vector_vf_insn(this, #code, match_##code, mask_##code) - #define DEFINE_VECTOR_VI(code) add_vector_vi_insn(this, #code, match_##code, mask_##code) - #define DEFINE_VECTOR_VIU(code) add_vector_viu_insn(this, #code, match_##code, mask_##code) + if (isa->extension_enabled(EXT_ZBS)) { + DEFINE_RTYPE(bclr); + DEFINE_RTYPE(binv); + DEFINE_RTYPE(bset); + DEFINE_RTYPE(bext); + DEFINE_ITYPE_SHIFT(bclri); + DEFINE_ITYPE_SHIFT(binvi); + DEFINE_ITYPE_SHIFT(bseti); + DEFINE_ITYPE_SHIFT(bexti); + } - #define DISASM_OPIV_VXI_INSN(name, sign, suf) \ - DEFINE_VECTOR_VV(name##_##suf##v); \ - DEFINE_VECTOR_VX(name##_##suf##x); \ - if (sign) \ - DEFINE_VECTOR_VI(name##_##suf##i); \ - else \ - DEFINE_VECTOR_VIU(name##_##suf##i) + if (isa->extension_enabled(EXT_ZBKB)) { + add_insn(new disasm_insn_t("brev8", match_grevi | (0x7 << imm_shift), mask_grevi | mask_imm, {&xrd, &xrs1})); // brev8 + add_insn(new disasm_insn_t("rev8", match_grevi | ((isa->get_max_xlen() - 8) << imm_shift), mask_grevi | mask_imm, {&xrd, &xrs1})); + DEFINE_RTYPE(pack); + DEFINE_RTYPE(packh); + if (isa->get_max_xlen() == 64) { + DEFINE_RTYPE(packw); + } + } - #define DISASM_OPIV_VX__INSN(name, sign) \ - DEFINE_VECTOR_VV(name##_vv); \ - DEFINE_VECTOR_VX(name##_vx) + if (isa->extension_enabled(EXT_SVINVAL)) { + DEFINE_NOARG(sfence_w_inval); + DEFINE_NOARG(sfence_inval_ir); + DEFINE_SFENCE_TYPE(sinval_vma); + DEFINE_SFENCE_TYPE(hinval_vvma); + DEFINE_SFENCE_TYPE(hinval_gvma); + } - #define DISASM_OPIV__XI_INSN(name, sign) \ - DEFINE_VECTOR_VX(name##_vx); \ - if (sign) \ - DEFINE_VECTOR_VI(name##_vi); \ - else \ - DEFINE_VECTOR_VIU(name##_vi) + if (isa->extension_enabled('F')) { + DEFINE_FLOAD(flw) + DEFINE_FSTORE(fsw) + DEFINE_FRTYPE(fadd_s); + DEFINE_FRTYPE(fsub_s); + DEFINE_FRTYPE(fmul_s); + DEFINE_FRTYPE(fdiv_s); + DEFINE_FR1TYPE(fsqrt_s); + DEFINE_FRTYPE(fmin_s); + DEFINE_FRTYPE(fmax_s); + DEFINE_FR3TYPE(fmadd_s); + DEFINE_FR3TYPE(fmsub_s); + DEFINE_FR3TYPE(fnmadd_s); + DEFINE_FR3TYPE(fnmsub_s); + DEFINE_FRTYPE(fsgnj_s); + DEFINE_FRTYPE(fsgnjn_s); + DEFINE_FRTYPE(fsgnjx_s); + DEFINE_FR1TYPE(fcvt_s_d); + DEFINE_FR1TYPE(fcvt_s_q); + DEFINE_XFTYPE(fcvt_s_l); + DEFINE_XFTYPE(fcvt_s_lu); + DEFINE_XFTYPE(fcvt_s_w); + DEFINE_XFTYPE(fcvt_s_wu); + DEFINE_XFTYPE(fcvt_s_wu); + DEFINE_XFTYPE(fmv_w_x); + DEFINE_FXTYPE(fcvt_l_s); + DEFINE_FXTYPE(fcvt_lu_s); + DEFINE_FXTYPE(fcvt_w_s); + DEFINE_FXTYPE(fcvt_wu_s); + DEFINE_FXTYPE(fclass_s); + DEFINE_FXTYPE(fmv_x_w); + DEFINE_FX2TYPE(feq_s); + DEFINE_FX2TYPE(flt_s); + DEFINE_FX2TYPE(fle_s); + } - #define DISASM_OPIV_V___INSN(name, sign) DEFINE_VECTOR_VV(name##_vv) + if (isa->extension_enabled(EXT_ZFINX)) { + DEFINE_RTYPE(fadd_s); + DEFINE_RTYPE(fsub_s); + DEFINE_RTYPE(fmul_s); + DEFINE_RTYPE(fdiv_s); + DEFINE_R1TYPE(fsqrt_s); + DEFINE_RTYPE(fmin_s); + DEFINE_RTYPE(fmax_s); + DEFINE_R3TYPE(fmadd_s); + DEFINE_R3TYPE(fmsub_s); + DEFINE_R3TYPE(fnmadd_s); + DEFINE_R3TYPE(fnmsub_s); + DEFINE_RTYPE(fsgnj_s); + DEFINE_RTYPE(fsgnjn_s); + DEFINE_RTYPE(fsgnjx_s); + DEFINE_R1TYPE(fcvt_s_d); + //DEFINE_R1TYPE(fcvt_s_q); + DEFINE_R1TYPE(fcvt_s_l); + DEFINE_R1TYPE(fcvt_s_lu); + DEFINE_R1TYPE(fcvt_s_w); + DEFINE_R1TYPE(fcvt_s_wu); + DEFINE_R1TYPE(fcvt_s_wu); + DEFINE_R1TYPE(fcvt_l_s); + DEFINE_R1TYPE(fcvt_lu_s); + DEFINE_R1TYPE(fcvt_w_s); + DEFINE_R1TYPE(fcvt_wu_s); + DEFINE_R1TYPE(fclass_s); + DEFINE_RTYPE(feq_s); + DEFINE_RTYPE(flt_s); + DEFINE_RTYPE(fle_s); + } - #define DISASM_OPIV_S___INSN(name, sign) DEFINE_VECTOR_VV(name##_vs) + if (isa->extension_enabled('D')) { + DEFINE_FLOAD(fld) + DEFINE_FSTORE(fsd) + DEFINE_FRTYPE(fadd_d); + DEFINE_FRTYPE(fsub_d); + DEFINE_FRTYPE(fmul_d); + DEFINE_FRTYPE(fdiv_d); + DEFINE_FR1TYPE(fsqrt_d); + DEFINE_FRTYPE(fmin_d); + DEFINE_FRTYPE(fmax_d); + DEFINE_FR3TYPE(fmadd_d); + DEFINE_FR3TYPE(fmsub_d); + DEFINE_FR3TYPE(fnmadd_d); + DEFINE_FR3TYPE(fnmsub_d); + DEFINE_FRTYPE(fsgnj_d); + DEFINE_FRTYPE(fsgnjn_d); + DEFINE_FRTYPE(fsgnjx_d); + DEFINE_FR1TYPE(fcvt_d_s); + DEFINE_FR1TYPE(fcvt_d_q); + DEFINE_XFTYPE(fcvt_d_l); + DEFINE_XFTYPE(fcvt_d_lu); + DEFINE_XFTYPE(fcvt_d_w); + DEFINE_XFTYPE(fcvt_d_wu); + DEFINE_XFTYPE(fcvt_d_wu); + DEFINE_XFTYPE(fmv_d_x); + DEFINE_FXTYPE(fcvt_l_d); + DEFINE_FXTYPE(fcvt_lu_d); + DEFINE_FXTYPE(fcvt_w_d); + DEFINE_FXTYPE(fcvt_wu_d); + DEFINE_FXTYPE(fclass_d); + DEFINE_FXTYPE(fmv_x_d); + DEFINE_FX2TYPE(feq_d); + DEFINE_FX2TYPE(flt_d); + DEFINE_FX2TYPE(fle_d); + } - #define DISASM_OPIV_W___INSN(name, sign) \ - DEFINE_VECTOR_VV(name##_wv); \ - DEFINE_VECTOR_VX(name##_wx) + if (isa->extension_enabled(EXT_ZDINX)) { + DEFINE_RTYPE(fadd_d); + DEFINE_RTYPE(fsub_d); + DEFINE_RTYPE(fmul_d); + DEFINE_RTYPE(fdiv_d); + DEFINE_R1TYPE(fsqrt_d); + DEFINE_RTYPE(fmin_d); + DEFINE_RTYPE(fmax_d); + DEFINE_R3TYPE(fmadd_d); + DEFINE_R3TYPE(fmsub_d); + DEFINE_R3TYPE(fnmadd_d); + DEFINE_R3TYPE(fnmsub_d); + DEFINE_RTYPE(fsgnj_d); + DEFINE_RTYPE(fsgnjn_d); + DEFINE_RTYPE(fsgnjx_d); + DEFINE_R1TYPE(fcvt_d_s); + //DEFINE_R1TYPE(fcvt_d_q); + DEFINE_R1TYPE(fcvt_d_l); + DEFINE_R1TYPE(fcvt_d_lu); + DEFINE_R1TYPE(fcvt_d_w); + DEFINE_R1TYPE(fcvt_d_wu); + DEFINE_R1TYPE(fcvt_d_wu); + DEFINE_R1TYPE(fcvt_l_d); + DEFINE_R1TYPE(fcvt_lu_d); + DEFINE_R1TYPE(fcvt_w_d); + DEFINE_R1TYPE(fcvt_wu_d); + DEFINE_R1TYPE(fclass_d); + DEFINE_RTYPE(feq_d); + DEFINE_RTYPE(flt_d); + DEFINE_RTYPE(fle_d); + } - #define DISASM_OPIV_M___INSN(name, sign) DEFINE_VECTOR_VV(name##_mm) + if (isa->extension_enabled(EXT_ZFH)) { + DEFINE_FRTYPE(fadd_h); + DEFINE_FRTYPE(fsub_h); + DEFINE_FRTYPE(fmul_h); + DEFINE_FRTYPE(fdiv_h); + DEFINE_FR1TYPE(fsqrt_h); + DEFINE_FRTYPE(fmin_h); + DEFINE_FRTYPE(fmax_h); + DEFINE_FR3TYPE(fmadd_h); + DEFINE_FR3TYPE(fmsub_h); + DEFINE_FR3TYPE(fnmadd_h); + DEFINE_FR3TYPE(fnmsub_h); + DEFINE_FRTYPE(fsgnj_h); + DEFINE_FRTYPE(fsgnjn_h); + DEFINE_FRTYPE(fsgnjx_h); + DEFINE_XFTYPE(fcvt_h_l); + DEFINE_XFTYPE(fcvt_h_lu); + DEFINE_XFTYPE(fcvt_h_w); + DEFINE_XFTYPE(fcvt_h_wu); + DEFINE_XFTYPE(fcvt_h_wu); + DEFINE_FXTYPE(fcvt_l_h); + DEFINE_FXTYPE(fcvt_lu_h); + DEFINE_FXTYPE(fcvt_w_h); + DEFINE_FXTYPE(fcvt_wu_h); + DEFINE_FXTYPE(fclass_h); + DEFINE_FX2TYPE(feq_h); + DEFINE_FX2TYPE(flt_h); + DEFINE_FX2TYPE(fle_h); + } - #define DISASM_OPIV__X__INSN(name, sign) DEFINE_VECTOR_VX(name##_vx) + if (isa->extension_enabled(EXT_ZHINX)) { + DEFINE_RTYPE(fadd_h); + DEFINE_RTYPE(fsub_h); + DEFINE_RTYPE(fmul_h); + DEFINE_RTYPE(fdiv_h); + DEFINE_R1TYPE(fsqrt_h); + DEFINE_RTYPE(fmin_h); + DEFINE_RTYPE(fmax_h); + DEFINE_R3TYPE(fmadd_h); + DEFINE_R3TYPE(fmsub_h); + DEFINE_R3TYPE(fnmadd_h); + DEFINE_R3TYPE(fnmsub_h); + DEFINE_RTYPE(fsgnj_h); + DEFINE_RTYPE(fsgnjn_h); + DEFINE_RTYPE(fsgnjx_h); + DEFINE_R1TYPE(fcvt_h_l); + DEFINE_R1TYPE(fcvt_h_lu); + DEFINE_R1TYPE(fcvt_h_w); + DEFINE_R1TYPE(fcvt_h_wu); + DEFINE_R1TYPE(fcvt_h_wu); + DEFINE_R1TYPE(fcvt_l_h); + DEFINE_R1TYPE(fcvt_lu_h); + DEFINE_R1TYPE(fcvt_w_h); + DEFINE_R1TYPE(fcvt_wu_h); + DEFINE_R1TYPE(fclass_h); + DEFINE_RTYPE(feq_h); + DEFINE_RTYPE(flt_h); + DEFINE_RTYPE(fle_h); + } - #define DEFINE_VECTOR_VVM(name, has_vm) \ - add_vector_vvm_insn(this, #name, match_##name, mask_##name | mask_vm); \ - if (has_vm) \ - add_vector_vv_insn(this, #name, match_##name, mask_##name | mask_vm) + if (isa->extension_enabled(EXT_ZFHMIN)) { + DEFINE_FLOAD(flh) + DEFINE_FSTORE(fsh) + DEFINE_FR1TYPE(fcvt_h_s); + DEFINE_FR1TYPE(fcvt_h_d); + DEFINE_FR1TYPE(fcvt_h_q); + DEFINE_FR1TYPE(fcvt_s_h); + DEFINE_FR1TYPE(fcvt_d_h); + DEFINE_FR1TYPE(fcvt_q_h); + DEFINE_XFTYPE(fmv_h_x); + DEFINE_FXTYPE(fmv_x_h); + } - #define DEFINE_VECTOR_VXM(name, has_vm) \ - add_vector_vxm_insn(this, #name, match_##name, mask_##name | mask_vm); \ - if (has_vm) \ - add_vector_vx_insn(this, #name, match_##name, mask_##name | mask_vm) + if (isa->extension_enabled(EXT_ZHINXMIN)) { + DEFINE_R1TYPE(fcvt_h_s); + DEFINE_R1TYPE(fcvt_h_d); + //DEFINE_R1TYPE(fcvt_h_q); + DEFINE_R1TYPE(fcvt_s_h); + DEFINE_R1TYPE(fcvt_d_h); + //DEFINE_R1TYPE(fcvt_q_h); + } - #define DEFINE_VECTOR_VIM(name, has_vm) \ - add_vector_vim_insn(this, #name, match_##name, mask_##name | mask_vm); \ - if (has_vm) \ - add_vector_vi_insn(this, #name, match_##name, mask_##name | mask_vm) + if (isa->extension_enabled('Q')) { + DEFINE_FLOAD(flq) + DEFINE_FSTORE(fsq) + DEFINE_FRTYPE(fadd_q); + DEFINE_FRTYPE(fsub_q); + DEFINE_FRTYPE(fmul_q); + DEFINE_FRTYPE(fdiv_q); + DEFINE_FR1TYPE(fsqrt_q); + DEFINE_FRTYPE(fmin_q); + DEFINE_FRTYPE(fmax_q); + DEFINE_FR3TYPE(fmadd_q); + DEFINE_FR3TYPE(fmsub_q); + DEFINE_FR3TYPE(fnmadd_q); + DEFINE_FR3TYPE(fnmsub_q); + DEFINE_FRTYPE(fsgnj_q); + DEFINE_FRTYPE(fsgnjn_q); + DEFINE_FRTYPE(fsgnjx_q); + DEFINE_FR1TYPE(fcvt_q_s); + DEFINE_FR1TYPE(fcvt_q_d); + DEFINE_XFTYPE(fcvt_q_l); + DEFINE_XFTYPE(fcvt_q_lu); + DEFINE_XFTYPE(fcvt_q_w); + DEFINE_XFTYPE(fcvt_q_wu); + DEFINE_XFTYPE(fcvt_q_wu); + DEFINE_FXTYPE(fcvt_l_q); + DEFINE_FXTYPE(fcvt_lu_q); + DEFINE_FXTYPE(fcvt_w_q); + DEFINE_FXTYPE(fcvt_wu_q); + DEFINE_FXTYPE(fclass_q); + DEFINE_FX2TYPE(feq_q); + DEFINE_FX2TYPE(flt_q); + DEFINE_FX2TYPE(fle_q); + } - #define DISASM_OPIV_VXIM_INSN(name, sign, has_vm) \ - DEFINE_VECTOR_VVM(name##_vvm, has_vm); \ - DEFINE_VECTOR_VXM(name##_vxm, has_vm); \ - DEFINE_VECTOR_VIM(name##_vim, has_vm) + // ext-h + if (isa->extension_enabled('H')) { + DEFINE_XLOAD_BASE(hlv_b) + DEFINE_XLOAD_BASE(hlv_bu) + DEFINE_XLOAD_BASE(hlv_h) + DEFINE_XLOAD_BASE(hlv_hu) + DEFINE_XLOAD_BASE(hlv_w) + DEFINE_XLOAD_BASE(hlv_wu) + DEFINE_XLOAD_BASE(hlv_d) - #define DISASM_OPIV_VX_M_INSN(name, sign, has_vm) \ - DEFINE_VECTOR_VVM(name##_vvm, has_vm); \ - DEFINE_VECTOR_VXM(name##_vxm, has_vm) + DEFINE_XLOAD_BASE(hlvx_hu) + DEFINE_XLOAD_BASE(hlvx_wu) - //OPFVV/OPFVF - //0b00_0000 - DISASM_OPIV_VXI_INSN(vadd, 1, v); - DISASM_OPIV_VX__INSN(vsub, 1); - DISASM_OPIV__XI_INSN(vrsub, 1); - DISASM_OPIV_VX__INSN(vminu, 0); - DISASM_OPIV_VX__INSN(vmin, 1); - DISASM_OPIV_VX__INSN(vmaxu, 1); - DISASM_OPIV_VX__INSN(vmax, 0); - DISASM_OPIV_VXI_INSN(vand, 1, v); - DISASM_OPIV_VXI_INSN(vor, 1, v); - DISASM_OPIV_VXI_INSN(vxor, 1, v); - DISASM_OPIV_VXI_INSN(vrgather, 0, v); - DISASM_OPIV_V___INSN(vrgatherei16, 0); - DISASM_OPIV__XI_INSN(vslideup, 0); - DISASM_OPIV__XI_INSN(vslidedown, 0); + DEFINE_XSTORE_BASE(hsv_b) + DEFINE_XSTORE_BASE(hsv_h) + DEFINE_XSTORE_BASE(hsv_w) + DEFINE_XSTORE_BASE(hsv_d) - //0b01_0000 - DISASM_OPIV_VXIM_INSN(vadc, 1, 0); - DISASM_OPIV_VXIM_INSN(vmadc, 1, 1); - DISASM_OPIV_VX_M_INSN(vsbc, 1, 0); - DISASM_OPIV_VX_M_INSN(vmsbc, 1, 1); - DISASM_OPIV_VXIM_INSN(vmerge, 1, 0); - DISASM_INSN("vmv.v.i", vmv_v_i, 0, {&vd, &v_simm5}); - DISASM_INSN("vmv.v.v", vmv_v_v, 0, {&vd, &vs1}); - DISASM_INSN("vmv.v.x", vmv_v_x, 0, {&vd, &xrs1}); - DISASM_OPIV_VXI_INSN(vmseq, 1, v); - DISASM_OPIV_VXI_INSN(vmsne, 1, v); - DISASM_OPIV_VX__INSN(vmsltu, 0); - DISASM_OPIV_VX__INSN(vmslt, 1); - DISASM_OPIV_VXI_INSN(vmsleu, 0, v); - DISASM_OPIV_VXI_INSN(vmsle, 1, v); - DISASM_OPIV__XI_INSN(vmsgtu, 0); - DISASM_OPIV__XI_INSN(vmsgt, 1); + DEFINE_SFENCE_TYPE(hfence_gvma); + DEFINE_SFENCE_TYPE(hfence_vvma); + } - //0b10_0000 - DISASM_OPIV_VXI_INSN(vsaddu, 0, v); - DISASM_OPIV_VXI_INSN(vsadd, 1, v); - DISASM_OPIV_VX__INSN(vssubu, 0); - DISASM_OPIV_VX__INSN(vssub, 1); - DISASM_OPIV_VXI_INSN(vsll, 1, v); - DISASM_INSN("vmv1r.v", vmv1r_v, 0, {&vd, &vs2}); - DISASM_INSN("vmv2r.v", vmv2r_v, 0, {&vd, &vs2}); - DISASM_INSN("vmv4r.v", vmv4r_v, 0, {&vd, &vs2}); - DISASM_INSN("vmv8r.v", vmv8r_v, 0, {&vd, &vs2}); - DISASM_OPIV_VX__INSN(vsmul, 1); - DISASM_OPIV_VXI_INSN(vsrl, 0, v); - DISASM_OPIV_VXI_INSN(vsra, 0, v); - DISASM_OPIV_VXI_INSN(vssrl, 0, v); - DISASM_OPIV_VXI_INSN(vssra, 0, v); - DISASM_OPIV_VXI_INSN(vnsrl, 0, w); - DISASM_OPIV_VXI_INSN(vnsra, 0, w); - DISASM_OPIV_VXI_INSN(vnclipu, 0, w); - DISASM_OPIV_VXI_INSN(vnclip, 0, w); + // ext-c + if (isa->extension_enabled(EXT_ZCA)) { + DISASM_INSN("c.ebreak", c_add, mask_rd | mask_rvc_rs2, {}); + add_insn(new disasm_insn_t("ret", match_c_jr | match_rd_ra, mask_c_jr | mask_rd | mask_rvc_imm, {})); + DISASM_INSN("c.jr", c_jr, mask_rvc_imm, {&rvc_rs1}); + DISASM_INSN("c.jalr", c_jalr, mask_rvc_imm, {&rvc_rs1}); + DISASM_INSN("c.nop", c_addi, mask_rd | mask_rvc_imm, {}); + DISASM_INSN("c.addi16sp", c_addi16sp, mask_rd, {&rvc_sp, &rvc_addi16sp_imm}); + DISASM_INSN("c.addi4spn", c_addi4spn, 0, {&rvc_rs2s, &rvc_sp, &rvc_addi4spn_imm}); + DISASM_INSN("c.li", c_li, 0, {&xrd, &rvc_imm}); + DISASM_INSN("c.lui", c_lui, 0, {&xrd, &rvc_uimm}); + DISASM_INSN("c.addi", c_addi, 0, {&xrd, &rvc_imm}); + DISASM_INSN("c.slli", c_slli, 0, {&rvc_rs1, &rvc_shamt}); + DISASM_INSN("c.srli", c_srli, 0, {&rvc_rs1s, &rvc_shamt}); + DISASM_INSN("c.srai", c_srai, 0, {&rvc_rs1s, &rvc_shamt}); + DISASM_INSN("c.andi", c_andi, 0, {&rvc_rs1s, &rvc_imm}); + DISASM_INSN("c.mv", c_mv, 0, {&xrd, &rvc_rs2}); + DISASM_INSN("c.add", c_add, 0, {&xrd, &rvc_rs2}); + DISASM_INSN("c.addw", c_addw, 0, {&rvc_rs1s, &rvc_rs2s}); + DISASM_INSN("c.sub", c_sub, 0, {&rvc_rs1s, &rvc_rs2s}); + DISASM_INSN("c.subw", c_subw, 0, {&rvc_rs1s, &rvc_rs2s}); + DISASM_INSN("c.and", c_and, 0, {&rvc_rs1s, &rvc_rs2s}); + DISASM_INSN("c.or", c_or, 0, {&rvc_rs1s, &rvc_rs2s}); + DISASM_INSN("c.xor", c_xor, 0, {&rvc_rs1s, &rvc_rs2s}); + DISASM_INSN("c.lwsp", c_lwsp, 0, {&xrd, &rvc_lwsp_address}); + DISASM_INSN("c.swsp", c_swsp, 0, {&rvc_rs2, &rvc_swsp_address}); + DISASM_INSN("c.lw", c_lw, 0, {&rvc_rs2s, &rvc_lw_address}); + DISASM_INSN("c.sw", c_sw, 0, {&rvc_rs2s, &rvc_lw_address}); + DISASM_INSN("c.beqz", c_beqz, 0, {&rvc_rs1s, &rvc_branch_target}); + DISASM_INSN("c.bnez", c_bnez, 0, {&rvc_rs1s, &rvc_branch_target}); + DISASM_INSN("c.j", c_j, 0, {&rvc_jump_target}); + if (isa->get_max_xlen() == 32) { + DISASM_INSN("c.jal", c_jal, 0, {&rvc_jump_target}); + } else { + DISASM_INSN("c.ld", c_ld, 0, {&rvc_rs2s, &rvc_ld_address}); + DISASM_INSN("c.ldsp", c_ldsp, 0, {&xrd, &rvc_ldsp_address}); + DISASM_INSN("c.sd", c_sd, 0, {&rvc_rs2s, &rvc_ld_address}); + DISASM_INSN("c.sdsp", c_sdsp, 0, {&rvc_rs2, &rvc_sdsp_address}); + DISASM_INSN("c.addiw", c_addiw, 0, {&xrd, &rvc_imm}); + } + } - //0b11_0000 - DISASM_OPIV_S___INSN(vwredsumu, 0); - DISASM_OPIV_S___INSN(vwredsum, 1); + if (isa->extension_enabled(EXT_ZCD) && isa->extension_enabled('D')) { + DISASM_INSN("c.fld", c_fld, 0, {&rvc_fp_rs2s, &rvc_ld_address}); + DISASM_INSN("c.fldsp", c_fldsp, 0, {&frd, &rvc_ldsp_address}); + DISASM_INSN("c.fsd", c_fsd, 0, {&rvc_fp_rs2s, &rvc_ld_address}); + DISASM_INSN("c.fsdsp", c_fsdsp, 0, {&rvc_fp_rs2, &rvc_sdsp_address}); + } - //OPMVV/OPMVX - //0b00_0000 - DISASM_OPIV_VX__INSN(vaaddu, 0); - DISASM_OPIV_VX__INSN(vaadd, 0); - DISASM_OPIV_VX__INSN(vasubu, 0); - DISASM_OPIV_VX__INSN(vasub, 0); + if (isa->extension_enabled(EXT_ZCF) && isa->extension_enabled('F')) { + DISASM_INSN("c.flw", c_flw, 0, {&rvc_fp_rs2s, &rvc_lw_address}); + DISASM_INSN("c.flwsp", c_flwsp, 0, {&frd, &rvc_lwsp_address}); + DISASM_INSN("c.fsw", c_fsw, 0, {&rvc_fp_rs2s, &rvc_lw_address}); + DISASM_INSN("c.fswsp", c_fswsp, 0, {&rvc_fp_rs2, &rvc_swsp_address}); + } - DISASM_OPIV_S___INSN(vredsum, 1); - DISASM_OPIV_S___INSN(vredand, 1); - DISASM_OPIV_S___INSN(vredor, 1); - DISASM_OPIV_S___INSN(vredxor, 1); - DISASM_OPIV_S___INSN(vredminu, 0); - DISASM_OPIV_S___INSN(vredmin, 1); - DISASM_OPIV_S___INSN(vredmaxu, 0); - DISASM_OPIV_S___INSN(vredmax, 1); - DISASM_OPIV__X__INSN(vslide1up, 1); - DISASM_OPIV__X__INSN(vslide1down,1); + if (isa->extension_enabled(EXT_ZCB)) { + DISASM_INSN("c.zext.b", c_zext_b, 0, {&rvc_rs1s}); + DISASM_INSN("c.sext.b", c_sext_b, 0, {&rvc_rs1s}); + DISASM_INSN("c.zext.h", c_zext_h, 0, {&rvc_rs1s}); + DISASM_INSN("c.sext.h", c_sext_h, 0, {&rvc_rs1s}); + if (isa->get_max_xlen() == 64) { + DISASM_INSN("c.zext.w", c_zext_w, 0, {&rvc_rs1s}); + } + DISASM_INSN("c.not", c_not, 0, {&rvc_rs1s}); + DISASM_INSN("c.mul", c_mul, 0, {&rvc_rs1s, &rvc_rs2s}); + DISASM_INSN("c.lbu", c_lbu, 0, {&rvc_rs2s, &rvb_b_address}); + DISASM_INSN("c.lhu", c_lhu, 0, {&rvc_rs2s, &rvb_h_address}); + DISASM_INSN("c.lh", c_lh, 0, {&rvc_rs2s, &rvb_h_address}); + DISASM_INSN("c.sb", c_sb, 0, {&rvc_rs2s, &rvb_b_address}); + DISASM_INSN("c.sh", c_sh, 0, {&rvc_rs2s, &rvb_h_address}); + } - //0b01_0000 - //VWXUNARY0 - DISASM_INSN("vmv.x.s", vmv_x_s, 0, {&xrd, &vs2}); - DISASM_INSN("vcpop.m", vcpop_m, 0, {&xrd, &vs2, opt, &vm}); - DISASM_INSN("vfirst.m", vfirst_m, 0, {&xrd, &vs2, opt, &vm}); + if (isa->extension_enabled(EXT_ZCMP)) { + if (isa->get_max_xlen() == 32) { + DISASM_INSN("cm.push", cm_push, 0, {&rvcm_pushpop_rlist, &rvcm_push_stack_adj_32}); + DISASM_INSN("cm.pop", cm_pop, 0, {&rvcm_pushpop_rlist, &rvcm_pop_stack_adj_32}); + DISASM_INSN("cm.popret", cm_popret, 0, {&rvcm_pushpop_rlist, &rvcm_pop_stack_adj_32}); + DISASM_INSN("cm.popretz", cm_popretz, 0, {&rvcm_pushpop_rlist, &rvcm_pop_stack_adj_32}); + } else { + DISASM_INSN("cm.push", cm_push, 0, {&rvcm_pushpop_rlist, &rvcm_push_stack_adj_64}); + DISASM_INSN("cm.pop", cm_pop, 0, {&rvcm_pushpop_rlist, &rvcm_pop_stack_adj_64}); + DISASM_INSN("cm.popret", cm_popret, 0, {&rvcm_pushpop_rlist, &rvcm_pop_stack_adj_64}); + DISASM_INSN("cm.popretz", cm_popretz, 0, {&rvcm_pushpop_rlist, &rvcm_pop_stack_adj_64}); + } - //VRXUNARY0 - DISASM_INSN("vmv.s.x", vmv_s_x, 0, {&vd, &xrs1}); + DISASM_INSN("cm.mva01s", cm_mva01s, 0, {&rvc_rs1s, &rvc_rs2s}); + DISASM_INSN("cm.mvsa01", cm_mvsa01, 0, {&rvc_rs1s, &rvc_rs2s}); + } - //VXUNARY0 - DEFINE_VECTOR_V(vzext_vf2); - DEFINE_VECTOR_V(vsext_vf2); - DEFINE_VECTOR_V(vzext_vf4); - DEFINE_VECTOR_V(vsext_vf4); - DEFINE_VECTOR_V(vzext_vf8); - DEFINE_VECTOR_V(vsext_vf8); + if (isa->extension_enabled(EXT_ZCMT)) { + DISASM_INSN("cm.jt", cm_jalt, 0x380, {&rvcm_jt_index}); + DISASM_INSN("cm.jalt", cm_jalt, 0, {&rvcm_jt_index}); + } - //VMUNARY0 - DEFINE_VECTOR_V(vmsbf_m); - DEFINE_VECTOR_V(vmsof_m); - DEFINE_VECTOR_V(vmsif_m); - DEFINE_VECTOR_V(viota_m); - DISASM_INSN("vid.v", vid_v, 0, {&vd, opt, &vm}); + if (isa->extension_enabled('V')) { + DISASM_INSN("vsetivli", vsetivli, 0, {&xrd, &zimm5, &v_vtype}); + DISASM_INSN("vsetvli", vsetvli, 0, {&xrd, &xrs1, &v_vtype}); + DEFINE_RTYPE(vsetvl); - DISASM_INSN("vid.v", vid_v, 0, {&vd, opt, &vm}); + std::vector v_ld_unit = {&vd, &v_address, opt, &vm}; + std::vector v_st_unit = {&vs3, &v_address, opt, &vm}; + std::vector v_ld_stride = {&vd, &v_address, &xrs2, opt, &vm}; + std::vector v_st_stride = {&vs3, &v_address, &xrs2, opt, &vm}; + std::vector v_ld_index = {&vd, &v_address, &vs2, opt, &vm}; + std::vector v_st_index = {&vs3, &v_address, &vs2, opt, &vm}; - DISASM_INSN("vcompress.vm", vcompress_vm, 0, {&vd, &vs2, &vs1}); + add_insn(new disasm_insn_t("vlm.v", match_vlm_v, mask_vlm_v, v_ld_unit)); + add_insn(new disasm_insn_t("vsm.v", match_vsm_v, mask_vsm_v, v_st_unit)); - DISASM_OPIV_M___INSN(vmandn, 1); - DISASM_OPIV_M___INSN(vmand, 1); - DISASM_OPIV_M___INSN(vmor, 1); - DISASM_OPIV_M___INSN(vmxor, 1); - DISASM_OPIV_M___INSN(vmorn, 1); - DISASM_OPIV_M___INSN(vmnand, 1); - DISASM_OPIV_M___INSN(vmnor, 1); - DISASM_OPIV_M___INSN(vmxnor, 1); + // handle vector segment load/store + for (size_t elt = 0; elt <= 7; ++elt) { + const custom_fmt_t template_insn[] = { + {match_vle8_v, mask_vle8_v, "vl%se%d.v", v_ld_unit}, + {match_vse8_v, mask_vse8_v, "vs%se%d.v", v_st_unit}, - //0b10_0000 - DISASM_OPIV_VX__INSN(vdivu, 0); - DISASM_OPIV_VX__INSN(vdiv, 1); - DISASM_OPIV_VX__INSN(vremu, 0); - DISASM_OPIV_VX__INSN(vrem, 1); - DISASM_OPIV_VX__INSN(vmulhu, 0); - DISASM_OPIV_VX__INSN(vmul, 1); - DISASM_OPIV_VX__INSN(vmulhsu, 0); - DISASM_OPIV_VX__INSN(vmulh, 1); - DISASM_OPIV_VX__INSN(vmadd, 1); - DISASM_OPIV_VX__INSN(vnmsub, 1); - DISASM_OPIV_VX__INSN(vmacc, 1); - DISASM_OPIV_VX__INSN(vnmsac, 1); + {match_vluxei8_v, mask_vluxei8_v, "vlux%sei%d.v", v_ld_index}, + {match_vsuxei8_v, mask_vsuxei8_v, "vsux%sei%d.v", v_st_index}, - //0b11_0000 - DISASM_OPIV_VX__INSN(vwaddu, 0); - DISASM_OPIV_VX__INSN(vwadd, 1); - DISASM_OPIV_VX__INSN(vwsubu, 0); - DISASM_OPIV_VX__INSN(vwsub, 1); - DISASM_OPIV_W___INSN(vwaddu, 0); - DISASM_OPIV_W___INSN(vwadd, 1); - DISASM_OPIV_W___INSN(vwsubu, 0); - DISASM_OPIV_W___INSN(vwsub, 1); - DISASM_OPIV_VX__INSN(vwmulu, 0); - DISASM_OPIV_VX__INSN(vwmulsu, 0); - DISASM_OPIV_VX__INSN(vwmul, 1); - DISASM_OPIV_VX__INSN(vwmaccu, 0); - DISASM_OPIV_VX__INSN(vwmacc, 1); - DISASM_OPIV__X__INSN(vwmaccus, 1); - DISASM_OPIV_VX__INSN(vwmaccsu, 0); + {match_vlse8_v, mask_vlse8_v, "vls%se%d.v", v_ld_stride}, + {match_vsse8_v, mask_vsse8_v, "vss%se%d.v", v_st_stride}, - #undef DISASM_OPIV_VXI_INSN - #undef DISASM_OPIV_VX__INSN - #undef DISASM_OPIV__XI_INSN - #undef DISASM_OPIV_V___INSN - #undef DISASM_OPIV_S___INSN - #undef DISASM_OPIV_W___INSN - #undef DISASM_OPIV_M___INSN - #undef DISASM_OPIV__X__INSN - #undef DISASM_OPIV_VXIM_INSN - #undef DISASM_OPIV_VX_M_INSN + {match_vloxei8_v, mask_vloxei8_v, "vlox%sei%d.v", v_ld_index}, + {match_vsoxei8_v, mask_vsoxei8_v, "vsox%sei%d.v", v_st_index}, - #define DISASM_OPIV_VF_INSN(name) \ - DEFINE_VECTOR_VV(name##_vv); \ - DEFINE_VECTOR_VF(name##_vf) + {match_vle8ff_v, mask_vle8ff_v, "vl%se%dff.v", v_ld_unit} + }; - #define DISASM_OPIV_WF_INSN(name) \ - DEFINE_VECTOR_VV(name##_wv); \ - DEFINE_VECTOR_VF(name##_wf) + reg_t elt_map[] = {0x00000000, 0x00005000, 0x00006000, 0x00007000, + 0x10000000, 0x10005000, 0x10006000, 0x10007000}; - #define DISASM_OPIV_S__INSN(name) \ - DEFINE_VECTOR_VV(name##_vs) + for (unsigned nf = 0; nf <= 7; ++nf) { + const auto seg_str = nf ? "seg" + std::to_string(nf + 1) : ""; - #define DISASM_OPIV__F_INSN(name) \ - DEFINE_VECTOR_VF(name##_vf) + for (auto item : template_insn) { + const reg_t match_nf = nf << 29; + char buf[128]; + snprintf(buf, sizeof(buf), item.fmt, seg_str.c_str(), 8 << elt); + add_insn(new disasm_insn_t( + buf, + ((item.match | match_nf) & ~mask_vldst) | elt_map[elt], + item.mask | mask_nf, + item.arg + )); + } + } - #define DISASM_VFUNARY0_INSN(name, suf) \ - DEFINE_VECTOR_V(name##cvt_rtz_xu_f_##suf); \ - DEFINE_VECTOR_V(name##cvt_rtz_x_f_##suf); \ - DEFINE_VECTOR_V(name##cvt_xu_f_##suf); \ - DEFINE_VECTOR_V(name##cvt_x_f_##suf); \ - DEFINE_VECTOR_V(name##cvt_f_xu_##suf); \ - DEFINE_VECTOR_V(name##cvt_f_x_##suf) + const custom_fmt_t template_insn2[] = { + {match_vl1re8_v, mask_vl1re8_v, "vl%dre%d.v", v_ld_unit}, + }; - //OPFVV/OPFVF - //0b00_0000 - DISASM_OPIV_VF_INSN(vfadd); - DISASM_OPIV_S__INSN(vfredusum); - DISASM_OPIV_VF_INSN(vfsub); - DISASM_OPIV_S__INSN(vfredosum); - DISASM_OPIV_VF_INSN(vfmin); - DISASM_OPIV_S__INSN(vfredmin); - DISASM_OPIV_VF_INSN(vfmax); - DISASM_OPIV_S__INSN(vfredmax); - DISASM_OPIV_VF_INSN(vfsgnj); - DISASM_OPIV_VF_INSN(vfsgnjn); - DISASM_OPIV_VF_INSN(vfsgnjx); - DISASM_INSN("vfmv.f.s", vfmv_f_s, 0, {&frd, &vs2}); - DISASM_INSN("vfmv.s.f", vfmv_s_f, mask_vfmv_s_f, {&vd, &frs1}); - DISASM_OPIV__F_INSN(vfslide1up); - DISASM_OPIV__F_INSN(vfslide1down); + for (reg_t i = 0, nf = 7; i < 4; i++, nf >>= 1) { + for (auto item : template_insn2) { + const reg_t match_nf = nf << 29; + char buf[128]; + snprintf(buf, sizeof(buf), item.fmt, nf + 1, 8 << elt); + add_insn(new disasm_insn_t( + buf, + item.match | match_nf | elt_map[elt], + item.mask | mask_nf, + item.arg + )); + } + } + } - //0b01_0000 - DISASM_INSN("vfmerge.vfm", vfmerge_vfm, 0, {&vd, &vs2, &frs1, &v0}); - DISASM_INSN("vfmv.v.f", vfmv_v_f, 0, {&vd, &frs1}); - DISASM_OPIV_VF_INSN(vmfeq); - DISASM_OPIV_VF_INSN(vmfle); - DISASM_OPIV_VF_INSN(vmflt); - DISASM_OPIV_VF_INSN(vmfne); - DISASM_OPIV__F_INSN(vmfgt); - DISASM_OPIV__F_INSN(vmfge); + #define DISASM_ST_WHOLE_INSN(name, nf) \ + add_insn(new disasm_insn_t(#name, match_vs1r_v | (nf << 29), \ + mask_vs1r_v | mask_nf, \ + {&vs3, &v_address})); + DISASM_ST_WHOLE_INSN(vs1r.v, 0); + DISASM_ST_WHOLE_INSN(vs2r.v, 1); + DISASM_ST_WHOLE_INSN(vs4r.v, 3); + DISASM_ST_WHOLE_INSN(vs8r.v, 7); - //0b10_0000 - DISASM_OPIV_VF_INSN(vfdiv); - DISASM_OPIV__F_INSN(vfrdiv); + #undef DISASM_ST_WHOLE_INSN - //vfunary0 - DISASM_VFUNARY0_INSN(vf, v); + #define DEFINE_VECTOR_V(code) add_vector_v_insn(this, #code, match_##code, mask_##code) + #define DEFINE_VECTOR_VV(code) add_vector_vv_insn(this, #code, match_##code, mask_##code) + #define DEFINE_VECTOR_VX(code) add_vector_vx_insn(this, #code, match_##code, mask_##code) + #define DEFINE_VECTOR_VF(code) add_vector_vf_insn(this, #code, match_##code, mask_##code) + #define DEFINE_VECTOR_VI(code) add_vector_vi_insn(this, #code, match_##code, mask_##code) + #define DEFINE_VECTOR_VIU(code) add_vector_viu_insn(this, #code, match_##code, mask_##code) - DISASM_VFUNARY0_INSN(vfw, v); - DEFINE_VECTOR_V(vfwcvt_f_f_v); + #define DISASM_OPIV_VXI_INSN(name, sign, suf) \ + DEFINE_VECTOR_VV(name##_##suf##v); \ + DEFINE_VECTOR_VX(name##_##suf##x); \ + if (sign) \ + DEFINE_VECTOR_VI(name##_##suf##i); \ + else \ + DEFINE_VECTOR_VIU(name##_##suf##i) - DISASM_VFUNARY0_INSN(vfn, w); - DEFINE_VECTOR_V(vfncvt_f_f_w); - DEFINE_VECTOR_V(vfncvt_rod_f_f_w); + #define DISASM_OPIV_VX__INSN(name, sign) \ + DEFINE_VECTOR_VV(name##_vv); \ + DEFINE_VECTOR_VX(name##_vx) - //vfunary1 - DEFINE_VECTOR_V(vfsqrt_v); - DEFINE_VECTOR_V(vfrsqrt7_v); - DEFINE_VECTOR_V(vfrec7_v); - DEFINE_VECTOR_V(vfclass_v); + #define DISASM_OPIV__XI_INSN(name, sign) \ + DEFINE_VECTOR_VX(name##_vx); \ + if (sign) \ + DEFINE_VECTOR_VI(name##_vi); \ + else \ + DEFINE_VECTOR_VIU(name##_vi) - DISASM_OPIV_VF_INSN(vfmul); - DISASM_OPIV__F_INSN(vfrsub); - DISASM_OPIV_VF_INSN(vfmadd); - DISASM_OPIV_VF_INSN(vfnmadd); - DISASM_OPIV_VF_INSN(vfmsub); - DISASM_OPIV_VF_INSN(vfnmsub); - DISASM_OPIV_VF_INSN(vfmacc); - DISASM_OPIV_VF_INSN(vfnmacc); - DISASM_OPIV_VF_INSN(vfmsac); - DISASM_OPIV_VF_INSN(vfnmsac); + #define DISASM_OPIV_V___INSN(name, sign) DEFINE_VECTOR_VV(name##_vv) - //0b11_0000 - DISASM_OPIV_VF_INSN(vfwadd); - DISASM_OPIV_S__INSN(vfwredusum); - DISASM_OPIV_VF_INSN(vfwsub); - DISASM_OPIV_S__INSN(vfwredosum); - DISASM_OPIV_WF_INSN(vfwadd); - DISASM_OPIV_WF_INSN(vfwsub); - DISASM_OPIV_VF_INSN(vfwmul); - DISASM_OPIV_VF_INSN(vfwmacc); - DISASM_OPIV_VF_INSN(vfwnmacc); - DISASM_OPIV_VF_INSN(vfwmsac); - DISASM_OPIV_VF_INSN(vfwnmsac); + #define DISASM_OPIV_S___INSN(name, sign) DEFINE_VECTOR_VV(name##_vs) - #undef DISASM_OPIV_VF_INSN - #undef DISASM_OPIV__F_INSN - #undef DISASM_OPIV_S__INSN - #undef DISASM_OPIV_W__INSN - #undef DISASM_VFUNARY0_INSN + #define DISASM_OPIV_W___INSN(name, sign) \ + DEFINE_VECTOR_VV(name##_wv); \ + DEFINE_VECTOR_VX(name##_wx) - // vector amo - std::vector v_fmt_amo_wd = {&vd, &v_address, &vs2, &vd, opt, &vm}; - std::vector v_fmt_amo = {&x0, &v_address, &vs2, &vd, opt, &vm}; - for (size_t elt = 0; elt <= 3; ++elt) { - const custom_fmt_t template_insn[] = { - {match_vamoaddei8_v | mask_wd, mask_vamoaddei8_v | mask_wd, - "%sei%d.v", v_fmt_amo_wd}, - {match_vamoaddei8_v, mask_vamoaddei8_v | mask_wd, - "%sei%d.v", v_fmt_amo}, - }; - std::pair amo_map[] = { - {"vamoswap", 0x01ul << 27}, - {"vamoadd", 0x00ul << 27}, - {"vamoxor", 0x04ul << 27}, - {"vamoand", 0x0cul << 27}, - {"vamoor", 0x08ul << 27}, - {"vamomin", 0x10ul << 27}, - {"vamomax", 0x14ul << 27}, - {"vamominu", 0x18ul << 27}, - {"vamomaxu", 0x1cul << 27}}; - const reg_t elt_map[] = {0x0ul << 12, 0x5ul << 12, - 0x6ul <<12, 0x7ul << 12}; + #define DISASM_OPIV_M___INSN(name, sign) DEFINE_VECTOR_VV(name##_mm) - for (size_t idx = 0; idx < sizeof(amo_map) / sizeof(amo_map[0]); ++idx) { - for (auto item : template_insn) { - char buf[128]; - sprintf(buf, item.fmt, amo_map[idx].first, 8 << elt); - add_insn(new disasm_insn_t(buf, - item.match | amo_map[idx].second | elt_map[elt], - item.mask, - item.arg)); + #define DISASM_OPIV__X__INSN(name, sign) DEFINE_VECTOR_VX(name##_vx) + + #define DEFINE_VECTOR_VVM(name) \ + add_vector_vvm_insn(this, #name, match_##name, mask_##name | mask_vm) + + #define DEFINE_VECTOR_VXM(name) \ + add_vector_vxm_insn(this, #name, match_##name, mask_##name | mask_vm) + + #define DEFINE_VECTOR_VIM(name) \ + add_vector_vim_insn(this, #name, match_##name, mask_##name | mask_vm) + + #define DISASM_OPIV_VXIM_INSN(name) \ + DEFINE_VECTOR_VVM(name##_vvm); \ + DEFINE_VECTOR_VXM(name##_vxm); \ + DEFINE_VECTOR_VIM(name##_vim) + + #define DISASM_OPIV_VX_M_INSN(name) \ + DEFINE_VECTOR_VVM(name##_vvm); \ + DEFINE_VECTOR_VXM(name##_vxm) + + //OPFVV/OPFVF + //0b00_0000 + DISASM_OPIV_VXI_INSN(vadd, 1, v); + DISASM_OPIV_VX__INSN(vsub, 1); + DISASM_OPIV__XI_INSN(vrsub, 1); + DISASM_OPIV_VX__INSN(vminu, 0); + DISASM_OPIV_VX__INSN(vmin, 1); + DISASM_OPIV_VX__INSN(vmaxu, 1); + DISASM_OPIV_VX__INSN(vmax, 0); + DISASM_OPIV_VXI_INSN(vand, 1, v); + DISASM_OPIV_VXI_INSN(vor, 1, v); + DISASM_OPIV_VXI_INSN(vxor, 1, v); + DISASM_OPIV_VXI_INSN(vrgather, 0, v); + DISASM_OPIV_V___INSN(vrgatherei16, 0); + DISASM_OPIV__XI_INSN(vslideup, 0); + DISASM_OPIV__XI_INSN(vslidedown, 0); + + //0b01_0000 + DISASM_OPIV_VXIM_INSN(vadc); + DISASM_OPIV_VX_M_INSN(vsbc); + DISASM_OPIV_VXIM_INSN(vmadc); + DISASM_OPIV_VXI_INSN(vmadc, 1, v); + DISASM_OPIV_VX_M_INSN(vmsbc); + DISASM_OPIV_VX__INSN(vmsbc, 1); + DISASM_OPIV_VXIM_INSN(vmerge); + DISASM_INSN("vmv.v.i", vmv_v_i, 0, {&vd, &v_simm5}); + DISASM_INSN("vmv.v.v", vmv_v_v, 0, {&vd, &vs1}); + DISASM_INSN("vmv.v.x", vmv_v_x, 0, {&vd, &xrs1}); + DISASM_OPIV_VXI_INSN(vmseq, 1, v); + DISASM_OPIV_VXI_INSN(vmsne, 1, v); + DISASM_OPIV_VX__INSN(vmsltu, 0); + DISASM_OPIV_VX__INSN(vmslt, 1); + DISASM_OPIV_VXI_INSN(vmsleu, 0, v); + DISASM_OPIV_VXI_INSN(vmsle, 1, v); + DISASM_OPIV__XI_INSN(vmsgtu, 0); + DISASM_OPIV__XI_INSN(vmsgt, 1); + + //0b10_0000 + DISASM_OPIV_VXI_INSN(vsaddu, 0, v); + DISASM_OPIV_VXI_INSN(vsadd, 1, v); + DISASM_OPIV_VX__INSN(vssubu, 0); + DISASM_OPIV_VX__INSN(vssub, 1); + DISASM_OPIV_VXI_INSN(vsll, 1, v); + DISASM_INSN("vmv1r.v", vmv1r_v, 0, {&vd, &vs2}); + DISASM_INSN("vmv2r.v", vmv2r_v, 0, {&vd, &vs2}); + DISASM_INSN("vmv4r.v", vmv4r_v, 0, {&vd, &vs2}); + DISASM_INSN("vmv8r.v", vmv8r_v, 0, {&vd, &vs2}); + DISASM_OPIV_VX__INSN(vsmul, 1); + DISASM_OPIV_VXI_INSN(vsrl, 0, v); + DISASM_OPIV_VXI_INSN(vsra, 0, v); + DISASM_OPIV_VXI_INSN(vssrl, 0, v); + DISASM_OPIV_VXI_INSN(vssra, 0, v); + DISASM_OPIV_VXI_INSN(vnsrl, 0, w); + DISASM_OPIV_VXI_INSN(vnsra, 0, w); + DISASM_OPIV_VXI_INSN(vnclipu, 0, w); + DISASM_OPIV_VXI_INSN(vnclip, 0, w); + + //0b11_0000 + DISASM_OPIV_S___INSN(vwredsumu, 0); + DISASM_OPIV_S___INSN(vwredsum, 1); + + //OPMVV/OPMVX + //0b00_0000 + DISASM_OPIV_VX__INSN(vaaddu, 0); + DISASM_OPIV_VX__INSN(vaadd, 0); + DISASM_OPIV_VX__INSN(vasubu, 0); + DISASM_OPIV_VX__INSN(vasub, 0); + + DISASM_OPIV_S___INSN(vredsum, 1); + DISASM_OPIV_S___INSN(vredand, 1); + DISASM_OPIV_S___INSN(vredor, 1); + DISASM_OPIV_S___INSN(vredxor, 1); + DISASM_OPIV_S___INSN(vredminu, 0); + DISASM_OPIV_S___INSN(vredmin, 1); + DISASM_OPIV_S___INSN(vredmaxu, 0); + DISASM_OPIV_S___INSN(vredmax, 1); + DISASM_OPIV__X__INSN(vslide1up, 1); + DISASM_OPIV__X__INSN(vslide1down,1); + + //0b01_0000 + //VWXUNARY0 + DISASM_INSN("vmv.x.s", vmv_x_s, 0, {&xrd, &vs2}); + DISASM_INSN("vcpop.m", vcpop_m, 0, {&xrd, &vs2, opt, &vm}); + DISASM_INSN("vfirst.m", vfirst_m, 0, {&xrd, &vs2, opt, &vm}); + + //VRXUNARY0 + DISASM_INSN("vmv.s.x", vmv_s_x, 0, {&vd, &xrs1}); + + //VXUNARY0 + DEFINE_VECTOR_V(vzext_vf2); + DEFINE_VECTOR_V(vsext_vf2); + DEFINE_VECTOR_V(vzext_vf4); + DEFINE_VECTOR_V(vsext_vf4); + DEFINE_VECTOR_V(vzext_vf8); + DEFINE_VECTOR_V(vsext_vf8); + + //VMUNARY0 + DEFINE_VECTOR_V(vmsbf_m); + DEFINE_VECTOR_V(vmsof_m); + DEFINE_VECTOR_V(vmsif_m); + DEFINE_VECTOR_V(viota_m); + DISASM_INSN("vid.v", vid_v, 0, {&vd, opt, &vm}); + + DISASM_INSN("vid.v", vid_v, 0, {&vd, opt, &vm}); + + DISASM_INSN("vcompress.vm", vcompress_vm, 0, {&vd, &vs2, &vs1}); + + DISASM_OPIV_M___INSN(vmandn, 1); + DISASM_OPIV_M___INSN(vmand, 1); + DISASM_OPIV_M___INSN(vmor, 1); + DISASM_OPIV_M___INSN(vmxor, 1); + DISASM_OPIV_M___INSN(vmorn, 1); + DISASM_OPIV_M___INSN(vmnand, 1); + DISASM_OPIV_M___INSN(vmnor, 1); + DISASM_OPIV_M___INSN(vmxnor, 1); + + //0b10_0000 + DISASM_OPIV_VX__INSN(vdivu, 0); + DISASM_OPIV_VX__INSN(vdiv, 1); + DISASM_OPIV_VX__INSN(vremu, 0); + DISASM_OPIV_VX__INSN(vrem, 1); + DISASM_OPIV_VX__INSN(vmulhu, 0); + DISASM_OPIV_VX__INSN(vmul, 1); + DISASM_OPIV_VX__INSN(vmulhsu, 0); + DISASM_OPIV_VX__INSN(vmulh, 1); + DISASM_OPIV_VX__INSN(vmadd, 1); + DISASM_OPIV_VX__INSN(vnmsub, 1); + DISASM_OPIV_VX__INSN(vmacc, 1); + DISASM_OPIV_VX__INSN(vnmsac, 1); + + //0b11_0000 + DISASM_OPIV_VX__INSN(vwaddu, 0); + DISASM_OPIV_VX__INSN(vwadd, 1); + DISASM_OPIV_VX__INSN(vwsubu, 0); + DISASM_OPIV_VX__INSN(vwsub, 1); + DISASM_OPIV_W___INSN(vwaddu, 0); + DISASM_OPIV_W___INSN(vwadd, 1); + DISASM_OPIV_W___INSN(vwsubu, 0); + DISASM_OPIV_W___INSN(vwsub, 1); + DISASM_OPIV_VX__INSN(vwmulu, 0); + DISASM_OPIV_VX__INSN(vwmulsu, 0); + DISASM_OPIV_VX__INSN(vwmul, 1); + DISASM_OPIV_VX__INSN(vwmaccu, 0); + DISASM_OPIV_VX__INSN(vwmacc, 1); + DISASM_OPIV__X__INSN(vwmaccus, 1); + DISASM_OPIV_VX__INSN(vwmaccsu, 0); + + #undef DISASM_OPIV_VXI_INSN + #undef DISASM_OPIV_VX__INSN + #undef DISASM_OPIV__XI_INSN + #undef DISASM_OPIV_V___INSN + #undef DISASM_OPIV_S___INSN + #undef DISASM_OPIV_W___INSN + #undef DISASM_OPIV_M___INSN + #undef DISASM_OPIV__X__INSN + #undef DISASM_OPIV_VXIM_INSN + #undef DISASM_OPIV_VX_M_INSN + + #define DISASM_OPIV_VF_INSN(name) \ + DEFINE_VECTOR_VV(name##_vv); \ + DEFINE_VECTOR_VF(name##_vf) + + #define DISASM_OPIV_WF_INSN(name) \ + DEFINE_VECTOR_VV(name##_wv); \ + DEFINE_VECTOR_VF(name##_wf) + + #define DISASM_OPIV_S__INSN(name) \ + DEFINE_VECTOR_VV(name##_vs) + + #define DISASM_OPIV__F_INSN(name) \ + DEFINE_VECTOR_VF(name##_vf) + + #define DISASM_VFUNARY0_INSN(name, suf) \ + DEFINE_VECTOR_V(name##cvt_rtz_xu_f_##suf); \ + DEFINE_VECTOR_V(name##cvt_rtz_x_f_##suf); \ + DEFINE_VECTOR_V(name##cvt_xu_f_##suf); \ + DEFINE_VECTOR_V(name##cvt_x_f_##suf); \ + DEFINE_VECTOR_V(name##cvt_f_xu_##suf); \ + DEFINE_VECTOR_V(name##cvt_f_x_##suf) + + //OPFVV/OPFVF + //0b00_0000 + DISASM_OPIV_VF_INSN(vfadd); + DISASM_OPIV_S__INSN(vfredusum); + DISASM_OPIV_VF_INSN(vfsub); + DISASM_OPIV_S__INSN(vfredosum); + DISASM_OPIV_VF_INSN(vfmin); + DISASM_OPIV_S__INSN(vfredmin); + DISASM_OPIV_VF_INSN(vfmax); + DISASM_OPIV_S__INSN(vfredmax); + DISASM_OPIV_VF_INSN(vfsgnj); + DISASM_OPIV_VF_INSN(vfsgnjn); + DISASM_OPIV_VF_INSN(vfsgnjx); + DISASM_INSN("vfmv.f.s", vfmv_f_s, 0, {&frd, &vs2}); + DISASM_INSN("vfmv.s.f", vfmv_s_f, mask_vfmv_s_f, {&vd, &frs1}); + DISASM_OPIV__F_INSN(vfslide1up); + DISASM_OPIV__F_INSN(vfslide1down); + + //0b01_0000 + DISASM_INSN("vfmerge.vfm", vfmerge_vfm, 0, {&vd, &vs2, &frs1, &v0}); + DISASM_INSN("vfmv.v.f", vfmv_v_f, 0, {&vd, &frs1}); + DISASM_OPIV_VF_INSN(vmfeq); + DISASM_OPIV_VF_INSN(vmfle); + DISASM_OPIV_VF_INSN(vmflt); + DISASM_OPIV_VF_INSN(vmfne); + DISASM_OPIV__F_INSN(vmfgt); + DISASM_OPIV__F_INSN(vmfge); + + //0b10_0000 + DISASM_OPIV_VF_INSN(vfdiv); + DISASM_OPIV__F_INSN(vfrdiv); + + //vfunary0 + DISASM_VFUNARY0_INSN(vf, v); + DISASM_VFUNARY0_INSN(vfw, v); + DEFINE_VECTOR_V(vfwcvt_f_f_v); + + DISASM_VFUNARY0_INSN(vfn, w); + DEFINE_VECTOR_V(vfncvt_f_f_w); + DEFINE_VECTOR_V(vfncvt_rod_f_f_w); + + //vfunary1 + DEFINE_VECTOR_V(vfsqrt_v); + DEFINE_VECTOR_V(vfrsqrt7_v); + DEFINE_VECTOR_V(vfrec7_v); + DEFINE_VECTOR_V(vfclass_v); + + DISASM_OPIV_VF_INSN(vfmul); + DISASM_OPIV__F_INSN(vfrsub); + DISASM_OPIV_VF_INSN(vfmadd); + DISASM_OPIV_VF_INSN(vfnmadd); + DISASM_OPIV_VF_INSN(vfmsub); + DISASM_OPIV_VF_INSN(vfnmsub); + DISASM_OPIV_VF_INSN(vfmacc); + DISASM_OPIV_VF_INSN(vfnmacc); + DISASM_OPIV_VF_INSN(vfmsac); + DISASM_OPIV_VF_INSN(vfnmsac); + + //0b11_0000 + DISASM_OPIV_VF_INSN(vfwadd); + DISASM_OPIV_S__INSN(vfwredusum); + DISASM_OPIV_VF_INSN(vfwsub); + DISASM_OPIV_S__INSN(vfwredosum); + DISASM_OPIV_WF_INSN(vfwadd); + DISASM_OPIV_WF_INSN(vfwsub); + DISASM_OPIV_VF_INSN(vfwmul); + DISASM_OPIV_VF_INSN(vfwmacc); + DISASM_OPIV_VF_INSN(vfwnmacc); + DISASM_OPIV_VF_INSN(vfwmsac); + DISASM_OPIV_VF_INSN(vfwnmsac); + + #undef DISASM_OPIV_VF_INSN + #undef DISASM_OPIV__F_INSN + #undef DISASM_OPIV_S__INSN + #undef DISASM_OPIV_W__INSN + #undef DISASM_VFUNARY0_INSN + + // vector amo + std::vector v_fmt_amo_wd = {&vd, &v_address, &vs2, &vd, opt, &vm}; + std::vector v_fmt_amo = {&x0, &v_address, &vs2, &vd, opt, &vm}; + for (size_t elt = 0; elt <= 3; ++elt) { + const custom_fmt_t template_insn[] = { + {match_vamoaddei8_v | mask_wd, mask_vamoaddei8_v | mask_wd, + "%sei%d.v", v_fmt_amo_wd}, + {match_vamoaddei8_v, mask_vamoaddei8_v | mask_wd, + "%sei%d.v", v_fmt_amo}, + }; + std::pair amo_map[] = { + {"vamoswap", 0x01ul << 27}, + {"vamoadd", 0x00ul << 27}, + {"vamoxor", 0x04ul << 27}, + {"vamoand", 0x0cul << 27}, + {"vamoor", 0x08ul << 27}, + {"vamomin", 0x10ul << 27}, + {"vamomax", 0x14ul << 27}, + {"vamominu", 0x18ul << 27}, + {"vamomaxu", 0x1cul << 27}}; + const reg_t elt_map[] = {0x0ul << 12, 0x5ul << 12, + 0x6ul <<12, 0x7ul << 12}; + + for (size_t idx = 0; idx < sizeof(amo_map) / sizeof(amo_map[0]); ++idx) { + for (auto item : template_insn) { + char buf[128]; + snprintf(buf, sizeof(buf), item.fmt, amo_map[idx].first, 8 << elt); + add_insn(new disasm_insn_t(buf, + item.match | amo_map[idx].second | elt_map[elt], + item.mask, + item.arg)); + } } } } @@ -1541,304 +1811,435 @@ disassembler_t::disassembler_t(int xlen) #define DISASM_RINSN_AND_ROUND(code) \ DEFINE_RTYPE(code); \ DEFINE_RTYPE(code##_u); \ - - DISASM_8_AND_16_RINSN(add); - DISASM_8_AND_16_RINSN(radd); - DISASM_8_AND_16_RINSN(uradd); - DISASM_8_AND_16_RINSN(kadd); - DISASM_8_AND_16_RINSN(ukadd); - DISASM_8_AND_16_RINSN(sub); - DISASM_8_AND_16_RINSN(rsub); - DISASM_8_AND_16_RINSN(ursub); - DISASM_8_AND_16_RINSN(ksub); - DISASM_8_AND_16_RINSN(uksub); - DEFINE_RTYPE(cras16); - DEFINE_RTYPE(rcras16); - DEFINE_RTYPE(urcras16); - DEFINE_RTYPE(kcras16); - DEFINE_RTYPE(ukcras16); - DEFINE_RTYPE(crsa16); - DEFINE_RTYPE(rcrsa16); - DEFINE_RTYPE(urcrsa16); - DEFINE_RTYPE(kcrsa16); - DEFINE_RTYPE(ukcrsa16); - DEFINE_RTYPE(stas16); - DEFINE_RTYPE(rstas16); - DEFINE_RTYPE(urstas16); - DEFINE_RTYPE(kstas16); - DEFINE_RTYPE(ukstas16); - DEFINE_RTYPE(stsa16); - DEFINE_RTYPE(rstsa16); - DEFINE_RTYPE(urstsa16); - DEFINE_RTYPE(kstsa16); - DEFINE_RTYPE(ukstsa16); - - DISASM_8_AND_16_RINSN(sra); - DISASM_8_AND_16_RINSN(srl); - DISASM_8_AND_16_RINSN(sll); - DISASM_8_AND_16_RINSN(ksll); - DISASM_8_AND_16_RINSN(kslra); - DISASM_8_AND_16_PIINSN(srai); - DISASM_8_AND_16_PIINSN(srli); - DISASM_8_AND_16_PIINSN(slli); - DISASM_8_AND_16_PIINSN(kslli); - DISASM_8_AND_16_RINSN_ROUND(sra); - DISASM_8_AND_16_RINSN_ROUND(srl); - DISASM_8_AND_16_RINSN_ROUND(kslra); - DISASM_8_AND_16_PIINSN_ROUND(srai); - DISASM_8_AND_16_PIINSN_ROUND(srli); - - DISASM_8_AND_16_RINSN(cmpeq); - DISASM_8_AND_16_RINSN(scmplt); - DISASM_8_AND_16_RINSN(scmple); - DISASM_8_AND_16_RINSN(ucmplt); - DISASM_8_AND_16_RINSN(ucmple); - - DISASM_8_AND_16_RINSN(smul); - DISASM_8_AND_16_RINSN(smulx); - DISASM_8_AND_16_RINSN(umul); - DISASM_8_AND_16_RINSN(umulx); - DISASM_8_AND_16_RINSN(khm); - DISASM_8_AND_16_RINSN(khmx); - - DISASM_8_AND_16_RINSN(smin); - DISASM_8_AND_16_RINSN(umin); - DISASM_8_AND_16_RINSN(smax); - DISASM_8_AND_16_RINSN(umax); - DISASM_8_AND_16_PIINSN(sclip); - DISASM_8_AND_16_PIINSN(uclip); - DEFINE_R1TYPE(kabs16); - DEFINE_R1TYPE(clrs16); - DEFINE_R1TYPE(clz16); - DEFINE_R1TYPE(kabs8); - DEFINE_R1TYPE(clrs8); - DEFINE_R1TYPE(clz8); - - DEFINE_R1TYPE(sunpkd810); - DEFINE_R1TYPE(sunpkd820); - DEFINE_R1TYPE(sunpkd830); - DEFINE_R1TYPE(sunpkd831); - DEFINE_R1TYPE(sunpkd832); - DEFINE_R1TYPE(zunpkd810); - DEFINE_R1TYPE(zunpkd820); - DEFINE_R1TYPE(zunpkd830); - DEFINE_R1TYPE(zunpkd831); - DEFINE_R1TYPE(zunpkd832); - - DEFINE_RTYPE(pkbb16); - DEFINE_RTYPE(pkbt16); - DEFINE_RTYPE(pktb16); - DEFINE_RTYPE(pktt16); - DISASM_RINSN_AND_ROUND(smmul); - DISASM_RINSN_AND_ROUND(kmmac); - DISASM_RINSN_AND_ROUND(kmmsb); - DISASM_RINSN_AND_ROUND(kwmmul); - DISASM_RINSN_AND_ROUND(smmwb); - DISASM_RINSN_AND_ROUND(smmwt); - DISASM_RINSN_AND_ROUND(kmmawb); - DISASM_RINSN_AND_ROUND(kmmawt); - DISASM_RINSN_AND_ROUND(kmmwb2); - DISASM_RINSN_AND_ROUND(kmmwt2); - DISASM_RINSN_AND_ROUND(kmmawb2); - DISASM_RINSN_AND_ROUND(kmmawt2); - DEFINE_RTYPE(smbb16) - DEFINE_RTYPE(smbt16) - DEFINE_RTYPE(smtt16) - DEFINE_RTYPE(kmda) - DEFINE_RTYPE(kmxda) - DEFINE_RTYPE(smds) - DEFINE_RTYPE(smdrs) - DEFINE_RTYPE(smxds) - DEFINE_RTYPE(kmabb) - DEFINE_RTYPE(kmabt) - DEFINE_RTYPE(kmatt) - DEFINE_RTYPE(kmada) - DEFINE_RTYPE(kmaxda) - DEFINE_RTYPE(kmads) - DEFINE_RTYPE(kmadrs) - DEFINE_RTYPE(kmaxds) - DEFINE_RTYPE(kmsda) - DEFINE_RTYPE(kmsxda) - DEFINE_RTYPE(smal) - DEFINE_RTYPE(sclip32) - DEFINE_RTYPE(uclip32) - DEFINE_R1TYPE(clrs32); - DEFINE_R1TYPE(clz32); - DEFINE_RTYPE(pbsad); - DEFINE_RTYPE(pbsada); - DEFINE_RTYPE(smaqa); - DEFINE_RTYPE(umaqa); - DEFINE_RTYPE(smaqa_su); - - DEFINE_RTYPE(radd64); - DEFINE_RTYPE(uradd64); - DEFINE_RTYPE(kadd64); - DEFINE_RTYPE(ukadd64); - DEFINE_RTYPE(rsub64); - DEFINE_RTYPE(ursub64); - DEFINE_RTYPE(ksub64); - DEFINE_RTYPE(uksub64); - DEFINE_RTYPE(smar64); - DEFINE_RTYPE(smsr64); - DEFINE_RTYPE(umar64); - DEFINE_RTYPE(umsr64); - DEFINE_RTYPE(kmar64); - DEFINE_RTYPE(kmsr64); - DEFINE_RTYPE(ukmar64); - DEFINE_RTYPE(ukmsr64); - DEFINE_RTYPE(smalbb); - DEFINE_RTYPE(smalbt); - DEFINE_RTYPE(smaltt); - DEFINE_RTYPE(smalda); - DEFINE_RTYPE(smalxda); - DEFINE_RTYPE(smalds); - DEFINE_RTYPE(smaldrs); - DEFINE_RTYPE(smalxds); - DEFINE_RTYPE(smslda); - DEFINE_RTYPE(smslxda); - - DEFINE_RTYPE(kaddh); - DEFINE_RTYPE(ksubh); - DEFINE_RTYPE(khmbb); - DEFINE_RTYPE(khmbt); - DEFINE_RTYPE(khmtt); - DEFINE_RTYPE(ukaddh); - DEFINE_RTYPE(uksubh); - DEFINE_RTYPE(kaddw); - DEFINE_RTYPE(ukaddw); - DEFINE_RTYPE(ksubw); - DEFINE_RTYPE(uksubw); - DEFINE_RTYPE(kdmbb); - DEFINE_RTYPE(kdmbt); - DEFINE_RTYPE(kdmtt); - DEFINE_RTYPE(kslraw); - DEFINE_RTYPE(kslraw_u); - DEFINE_RTYPE(ksllw); - DEFINE_PI5TYPE(kslliw); - DEFINE_RTYPE(kdmabb); - DEFINE_RTYPE(kdmabt); - DEFINE_RTYPE(kdmatt); - DEFINE_RTYPE(kabsw); - DEFINE_RTYPE(raddw); - DEFINE_RTYPE(uraddw); - DEFINE_RTYPE(rsubw); - DEFINE_RTYPE(ursubw); - DEFINE_RTYPE(max); - DEFINE_RTYPE(min); - DEFINE_RTYPE(mulr64); - DEFINE_RTYPE(mulsr64); - DEFINE_RTYPE(msubr32); - DEFINE_RTYPE(ave); - DEFINE_RTYPE(sra_u); - DEFINE_PI5TYPE(srai_u); - DEFINE_PI3TYPE(insb); - DEFINE_RTYPE(maddr32) - - if (xlen == 32) { - DISASM_INSN("c.flw", c_flw, 0, {&rvc_fp_rs2s, &rvc_lw_address}); - DISASM_INSN("c.flwsp", c_flwsp, 0, {&frd, &rvc_lwsp_address}); - DISASM_INSN("c.fsw", c_fsw, 0, {&rvc_fp_rs2s, &rvc_lw_address}); - DISASM_INSN("c.fswsp", c_fswsp, 0, {&rvc_fp_rs2, &rvc_swsp_address}); - DISASM_INSN("c.jal", c_jal, 0, {&rvc_jump_target}); - - DEFINE_RTYPE(add64); - DEFINE_RTYPE(sub64); - } else { - DISASM_INSN("c.ld", c_ld, 0, {&rvc_rs2s, &rvc_ld_address}); - DISASM_INSN("c.ldsp", c_ldsp, 0, {&xrd, &rvc_ldsp_address}); - DISASM_INSN("c.sd", c_sd, 0, {&rvc_rs2s, &rvc_ld_address}); - DISASM_INSN("c.sdsp", c_sdsp, 0, {&rvc_rs2, &rvc_sdsp_address}); - DISASM_INSN("c.addiw", c_addiw, 0, {&xrd, &rvc_imm}); - - DEFINE_RTYPE(add32); - DEFINE_RTYPE(radd32); - DEFINE_RTYPE(uradd32); - DEFINE_RTYPE(kadd32); - DEFINE_RTYPE(ukadd32); - DEFINE_RTYPE(sub32); - DEFINE_RTYPE(rsub32); - DEFINE_RTYPE(ursub32); - DEFINE_RTYPE(ksub32); - DEFINE_RTYPE(uksub32); - DEFINE_RTYPE(cras32); - DEFINE_RTYPE(rcras32); - DEFINE_RTYPE(urcras32); - DEFINE_RTYPE(kcras32); - DEFINE_RTYPE(ukcras32); - DEFINE_RTYPE(crsa32); - DEFINE_RTYPE(rcrsa32); - DEFINE_RTYPE(urcrsa32); - DEFINE_RTYPE(kcrsa32); - DEFINE_RTYPE(ukcrsa32); - DEFINE_RTYPE(stas32); - DEFINE_RTYPE(rstas32); - DEFINE_RTYPE(urstas32); - DEFINE_RTYPE(kstas32); - DEFINE_RTYPE(ukstas32); - DEFINE_RTYPE(stsa32); - DEFINE_RTYPE(rstsa32); - DEFINE_RTYPE(urstsa32); - DEFINE_RTYPE(kstsa32); - DEFINE_RTYPE(ukstsa32); - DEFINE_RTYPE(sra32); - DEFINE_PI5TYPE(srai32); - DEFINE_RTYPE(sra32_u); - DEFINE_PI5TYPE(srai32_u); - DEFINE_RTYPE(srl32); - DEFINE_PI5TYPE(srli32); - DEFINE_RTYPE(srl32_u); - DEFINE_PI5TYPE(srli32_u); - DEFINE_RTYPE(sll32); - DEFINE_PI5TYPE(slli32); - DEFINE_RTYPE(ksll32); - DEFINE_PI5TYPE(kslli32); - DEFINE_RTYPE(kslra32); - DEFINE_RTYPE(kslra32_u); - DEFINE_RTYPE(smin32); - DEFINE_RTYPE(umin32); - DEFINE_RTYPE(smax32); - DEFINE_RTYPE(umax32); - DEFINE_R1TYPE(kabs32); - DEFINE_RTYPE(khmbb16); - DEFINE_RTYPE(khmbt16); - DEFINE_RTYPE(khmtt16); - DEFINE_RTYPE(kdmbb16); - DEFINE_RTYPE(kdmbt16); - DEFINE_RTYPE(kdmtt16); - DEFINE_RTYPE(kdmabb16); - DEFINE_RTYPE(kdmabt16); - DEFINE_RTYPE(kdmatt16); - DEFINE_RTYPE(smbt32); - DEFINE_RTYPE(smtt32); - DEFINE_RTYPE(kmabb32); - DEFINE_RTYPE(kmabt32); - DEFINE_RTYPE(kmatt32); - DEFINE_RTYPE(kmda32); - DEFINE_RTYPE(kmxda32); - DEFINE_RTYPE(kmaxda32); - DEFINE_RTYPE(kmads32); - DEFINE_RTYPE(kmadrs32); - DEFINE_RTYPE(kmaxds32); - DEFINE_RTYPE(kmsda32); - DEFINE_RTYPE(kmsxda32); - DEFINE_RTYPE(smds32); - DEFINE_RTYPE(smdrs32); - DEFINE_RTYPE(smxds32); - DEFINE_PI5TYPE(sraiw_u); - DEFINE_RTYPE(pkbb32); - DEFINE_RTYPE(pkbt32); - DEFINE_RTYPE(pktb32); - DEFINE_RTYPE(pktt32); + + if (isa->extension_enabled(EXT_ZMMUL)) { + DEFINE_RTYPE(mul); + DEFINE_RTYPE(mulh); + DEFINE_RTYPE(mulhu); + DEFINE_RTYPE(mulhsu); + DEFINE_RTYPE(mulw); } + if (isa->extension_enabled(EXT_ZBPBO)) { + DEFINE_RTYPE(min); + DEFINE_RTYPE(max); + DEFINE_R3TYPE(cmix); + DEFINE_RTYPE(pack); + DEFINE_RTYPE(packu); + add_insn(new disasm_insn_t("rev", match_grevi | ((isa->get_max_xlen() - 1) << imm_shift), mask_grevi | mask_imm, {&xrd, &xrs1})); + add_insn(new disasm_insn_t("rev8.h", match_grevi | (0x8 << imm_shift), mask_grevi | mask_imm, {&xrd, &xrs1})); // swap16 + if (isa->get_max_xlen() == 32) { + DEFINE_R1TYPE(clz); + DEFINE_R3TYPE(fsr); + DEFINE_R3TYPE(fsri); + } else { + DEFINE_R3TYPE(fsrw); + } + } + + if (isa->extension_enabled(EXT_ZPSFOPERAND)) { + DEFINE_RTYPE(smal) + DEFINE_RTYPE(radd64); + DEFINE_RTYPE(uradd64); + DEFINE_RTYPE(kadd64); + DEFINE_RTYPE(ukadd64); + DEFINE_RTYPE(rsub64); + DEFINE_RTYPE(ursub64); + DEFINE_RTYPE(ksub64); + DEFINE_RTYPE(uksub64); + DEFINE_RTYPE(smar64); + DEFINE_RTYPE(smsr64); + DEFINE_RTYPE(umar64); + DEFINE_RTYPE(umsr64); + DEFINE_RTYPE(kmar64); + DEFINE_RTYPE(kmsr64); + DEFINE_RTYPE(ukmar64); + DEFINE_RTYPE(ukmsr64); + DEFINE_RTYPE(smalbb); + DEFINE_RTYPE(smalbt); + DEFINE_RTYPE(smaltt); + DEFINE_RTYPE(smalda); + DEFINE_RTYPE(smalxda); + DEFINE_RTYPE(smalds); + DEFINE_RTYPE(smaldrs); + DEFINE_RTYPE(smalxds); + DEFINE_RTYPE(smslda); + DEFINE_RTYPE(smslxda); + DEFINE_RTYPE(mulr64); + DEFINE_RTYPE(mulsr64); + if (isa->get_max_xlen() == 32) { + DEFINE_RTYPE(add64); + DEFINE_RTYPE(sub64); + } + } + + if (isa->extension_enabled(EXT_ZPN)) { + DISASM_8_AND_16_RINSN(add); + DISASM_8_AND_16_RINSN(radd); + DISASM_8_AND_16_RINSN(uradd); + DISASM_8_AND_16_RINSN(kadd); + DISASM_8_AND_16_RINSN(ukadd); + DISASM_8_AND_16_RINSN(sub); + DISASM_8_AND_16_RINSN(rsub); + DISASM_8_AND_16_RINSN(ursub); + DISASM_8_AND_16_RINSN(ksub); + DISASM_8_AND_16_RINSN(uksub); + DEFINE_RTYPE(cras16); + DEFINE_RTYPE(rcras16); + DEFINE_RTYPE(urcras16); + DEFINE_RTYPE(kcras16); + DEFINE_RTYPE(ukcras16); + DEFINE_RTYPE(crsa16); + DEFINE_RTYPE(rcrsa16); + DEFINE_RTYPE(urcrsa16); + DEFINE_RTYPE(kcrsa16); + DEFINE_RTYPE(ukcrsa16); + DEFINE_RTYPE(stas16); + DEFINE_RTYPE(rstas16); + DEFINE_RTYPE(urstas16); + DEFINE_RTYPE(kstas16); + DEFINE_RTYPE(ukstas16); + DEFINE_RTYPE(stsa16); + DEFINE_RTYPE(rstsa16); + DEFINE_RTYPE(urstsa16); + DEFINE_RTYPE(kstsa16); + DEFINE_RTYPE(ukstsa16); + DISASM_8_AND_16_RINSN(sra); + DISASM_8_AND_16_RINSN(srl); + DISASM_8_AND_16_RINSN(sll); + DISASM_8_AND_16_RINSN(ksll); + DISASM_8_AND_16_RINSN(kslra); + DISASM_8_AND_16_PIINSN(srai); + DISASM_8_AND_16_PIINSN(srli); + DISASM_8_AND_16_PIINSN(slli); + DISASM_8_AND_16_PIINSN(kslli); + DISASM_8_AND_16_RINSN_ROUND(sra); + DISASM_8_AND_16_RINSN_ROUND(srl); + DISASM_8_AND_16_RINSN_ROUND(kslra); + DISASM_8_AND_16_PIINSN_ROUND(srai); + DISASM_8_AND_16_PIINSN_ROUND(srli); + + DISASM_8_AND_16_RINSN(cmpeq); + DISASM_8_AND_16_RINSN(scmplt); + DISASM_8_AND_16_RINSN(scmple); + DISASM_8_AND_16_RINSN(ucmplt); + DISASM_8_AND_16_RINSN(ucmple); + + DISASM_8_AND_16_RINSN(smul); + DISASM_8_AND_16_RINSN(smulx); + DISASM_8_AND_16_RINSN(umul); + DISASM_8_AND_16_RINSN(umulx); + DISASM_8_AND_16_RINSN(khm); + DISASM_8_AND_16_RINSN(khmx); + + DISASM_8_AND_16_RINSN(smin); + DISASM_8_AND_16_RINSN(umin); + DISASM_8_AND_16_RINSN(smax); + DISASM_8_AND_16_RINSN(umax); + DISASM_8_AND_16_PIINSN(sclip); + DISASM_8_AND_16_PIINSN(uclip); + DEFINE_R1TYPE(kabs16); + DEFINE_R1TYPE(clrs16); + DEFINE_R1TYPE(clz16); + DEFINE_R1TYPE(kabs8); + DEFINE_R1TYPE(clrs8); + DEFINE_R1TYPE(clz8); + + DEFINE_R1TYPE(sunpkd810); + DEFINE_R1TYPE(sunpkd820); + DEFINE_R1TYPE(sunpkd830); + DEFINE_R1TYPE(sunpkd831); + DEFINE_R1TYPE(sunpkd832); + DEFINE_R1TYPE(zunpkd810); + DEFINE_R1TYPE(zunpkd820); + DEFINE_R1TYPE(zunpkd830); + DEFINE_R1TYPE(zunpkd831); + DEFINE_R1TYPE(zunpkd832); + + DEFINE_RTYPE(pkbb16); + DEFINE_RTYPE(pkbt16); + DEFINE_RTYPE(pktb16); + DEFINE_RTYPE(pktt16); + DISASM_RINSN_AND_ROUND(smmul); + DISASM_RINSN_AND_ROUND(kmmac); + DISASM_RINSN_AND_ROUND(kmmsb); + DISASM_RINSN_AND_ROUND(kwmmul); + DISASM_RINSN_AND_ROUND(smmwb); + DISASM_RINSN_AND_ROUND(smmwt); + DISASM_RINSN_AND_ROUND(kmmawb); + DISASM_RINSN_AND_ROUND(kmmawt); + DISASM_RINSN_AND_ROUND(kmmwb2); + DISASM_RINSN_AND_ROUND(kmmwt2); + DISASM_RINSN_AND_ROUND(kmmawb2); + DISASM_RINSN_AND_ROUND(kmmawt2); + DEFINE_RTYPE(smbb16) + DEFINE_RTYPE(smbt16) + DEFINE_RTYPE(smtt16) + DEFINE_RTYPE(kmda) + DEFINE_RTYPE(kmxda) + DEFINE_RTYPE(smds) + DEFINE_RTYPE(smdrs) + DEFINE_RTYPE(smxds) + DEFINE_RTYPE(kmabb) + DEFINE_RTYPE(kmabt) + DEFINE_RTYPE(kmatt) + DEFINE_RTYPE(kmada) + DEFINE_RTYPE(kmaxda) + DEFINE_RTYPE(kmads) + DEFINE_RTYPE(kmadrs) + DEFINE_RTYPE(kmaxds) + DEFINE_RTYPE(kmsda) + DEFINE_RTYPE(kmsxda) + DEFINE_RTYPE(sclip32) + DEFINE_RTYPE(uclip32) + DEFINE_R1TYPE(clrs32); + DEFINE_R1TYPE(clz32); + DEFINE_RTYPE(pbsad); + DEFINE_RTYPE(pbsada); + DEFINE_RTYPE(smaqa); + DEFINE_RTYPE(umaqa); + DEFINE_RTYPE(smaqa_su); + + DEFINE_RTYPE(kaddh); + DEFINE_RTYPE(ksubh); + DEFINE_RTYPE(khmbb); + DEFINE_RTYPE(khmbt); + DEFINE_RTYPE(khmtt); + DEFINE_RTYPE(ukaddh); + DEFINE_RTYPE(uksubh); + DEFINE_RTYPE(kaddw); + DEFINE_RTYPE(ukaddw); + DEFINE_RTYPE(ksubw); + DEFINE_RTYPE(uksubw); + DEFINE_RTYPE(kdmbb); + DEFINE_RTYPE(kdmbt); + DEFINE_RTYPE(kdmtt); + DEFINE_RTYPE(kslraw); + DEFINE_RTYPE(kslraw_u); + DEFINE_RTYPE(ksllw); + DEFINE_PI5TYPE(kslliw); + DEFINE_RTYPE(kdmabb); + DEFINE_RTYPE(kdmabt); + DEFINE_RTYPE(kdmatt); + DEFINE_RTYPE(kabsw); + DEFINE_RTYPE(raddw); + DEFINE_RTYPE(uraddw); + DEFINE_RTYPE(rsubw); + DEFINE_RTYPE(ursubw); + DEFINE_RTYPE(msubr32); + DEFINE_RTYPE(ave); + DEFINE_RTYPE(sra_u); + DEFINE_PI6TYPE(srai_u); + DEFINE_PI3TYPE(insb); + DEFINE_RTYPE(maddr32) + + if (isa->get_max_xlen() == 64) { + DEFINE_RTYPE(add32); + DEFINE_RTYPE(radd32); + DEFINE_RTYPE(uradd32); + DEFINE_RTYPE(kadd32); + DEFINE_RTYPE(ukadd32); + DEFINE_RTYPE(sub32); + DEFINE_RTYPE(rsub32); + DEFINE_RTYPE(ursub32); + DEFINE_RTYPE(ksub32); + DEFINE_RTYPE(uksub32); + DEFINE_RTYPE(cras32); + DEFINE_RTYPE(rcras32); + DEFINE_RTYPE(urcras32); + DEFINE_RTYPE(kcras32); + DEFINE_RTYPE(ukcras32); + DEFINE_RTYPE(crsa32); + DEFINE_RTYPE(rcrsa32); + DEFINE_RTYPE(urcrsa32); + DEFINE_RTYPE(kcrsa32); + DEFINE_RTYPE(ukcrsa32); + DEFINE_RTYPE(stas32); + DEFINE_RTYPE(rstas32); + DEFINE_RTYPE(urstas32); + DEFINE_RTYPE(kstas32); + DEFINE_RTYPE(ukstas32); + DEFINE_RTYPE(stsa32); + DEFINE_RTYPE(rstsa32); + DEFINE_RTYPE(urstsa32); + DEFINE_RTYPE(kstsa32); + DEFINE_RTYPE(ukstsa32); + DEFINE_RTYPE(sra32); + DEFINE_PI5TYPE(srai32); + DEFINE_RTYPE(sra32_u); + DEFINE_PI5TYPE(srai32_u); + DEFINE_RTYPE(srl32); + DEFINE_PI5TYPE(srli32); + DEFINE_RTYPE(srl32_u); + DEFINE_PI5TYPE(srli32_u); + DEFINE_RTYPE(sll32); + DEFINE_PI5TYPE(slli32); + DEFINE_RTYPE(ksll32); + DEFINE_PI5TYPE(kslli32); + DEFINE_RTYPE(kslra32); + DEFINE_RTYPE(kslra32_u); + DEFINE_RTYPE(smin32); + DEFINE_RTYPE(umin32); + DEFINE_RTYPE(smax32); + DEFINE_RTYPE(umax32); + DEFINE_R1TYPE(kabs32); + DEFINE_RTYPE(khmbb16); + DEFINE_RTYPE(khmbt16); + DEFINE_RTYPE(khmtt16); + DEFINE_RTYPE(kdmbb16); + DEFINE_RTYPE(kdmbt16); + DEFINE_RTYPE(kdmtt16); + DEFINE_RTYPE(kdmabb16); + DEFINE_RTYPE(kdmabt16); + DEFINE_RTYPE(kdmatt16); + DEFINE_RTYPE(smbt32); + DEFINE_RTYPE(smtt32); + DEFINE_RTYPE(kmabb32); + DEFINE_RTYPE(kmabt32); + DEFINE_RTYPE(kmatt32); + DEFINE_RTYPE(kmda32); + DEFINE_RTYPE(kmxda32); + DEFINE_RTYPE(kmaxda32); + DEFINE_RTYPE(kmads32); + DEFINE_RTYPE(kmadrs32); + DEFINE_RTYPE(kmaxds32); + DEFINE_RTYPE(kmsda32); + DEFINE_RTYPE(kmsxda32); + DEFINE_RTYPE(smds32); + DEFINE_RTYPE(smdrs32); + DEFINE_RTYPE(smxds32); + DEFINE_PI5TYPE(sraiw_u); + DEFINE_RTYPE(pkbt32); + DEFINE_RTYPE(pktb32); + } + } + + if (isa->extension_enabled(EXT_XZBP)) { + DEFINE_ITYPE_SHIFT(grevi); + DEFINE_ITYPE_SHIFT(gorci); + DEFINE_RTYPE(pack); + DEFINE_RTYPE(packh); + DEFINE_RTYPE(packu); + DEFINE_RTYPE(grev); + DEFINE_RTYPE(gorc); + DEFINE_RTYPE(xperm4); + DEFINE_RTYPE(xperm8); + DEFINE_RTYPE(xperm16); + DEFINE_RTYPE(xperm32); + } + + if (isa->extension_enabled(EXT_XZBP) || + isa->extension_enabled(EXT_XZBE) || + isa->extension_enabled(EXT_XZBF)) { + if(isa->get_max_xlen() == 64) { + DEFINE_RTYPE(packw); + } + } + + if (isa->extension_enabled(EXT_XZBT)) { + DEFINE_R3TYPE(cmix); + DEFINE_R3TYPE(fsr); + DEFINE_R3TYPE(fsri); + if(isa->get_max_xlen() == 64) { + DEFINE_R3TYPE(fsriw); + DEFINE_R3TYPE(fsrw); + } + } + + if (isa->extension_enabled(EXT_ZICBOM)) { + DISASM_INSN("cbo.clean", cbo_clean, 0, {&base_only_address}); + DISASM_INSN("cbo.flush", cbo_flush, 0, {&base_only_address}); + DISASM_INSN("cbo.inval", cbo_inval, 0, {&base_only_address}); + } + + if (isa->extension_enabled(EXT_ZICBOZ)) { + DISASM_INSN("cbo.zero", cbo_zero, 0, {&base_only_address}); + } + + if (isa->extension_enabled(EXT_ZKND) || + isa->extension_enabled(EXT_ZKNE)) { + DISASM_INSN("aes64ks1i", aes64ks1i, 0, {&xrd, &xrs1, &rcon}); + DEFINE_RTYPE(aes64ks2); + } + + if (isa->extension_enabled(EXT_ZKND)) { + if(isa->get_max_xlen() == 64) { + DEFINE_RTYPE(aes64ds); + DEFINE_RTYPE(aes64dsm); + DEFINE_R1TYPE(aes64im); + } else if (isa->get_max_xlen() == 32) { + DISASM_INSN("aes32dsi", aes32dsi, 0, {&xrd, &xrs1, &xrs2, &bs}); + DISASM_INSN("aes32dsmi", aes32dsmi, 0, {&xrd, &xrs1, &xrs2, &bs}); + } + } + + if (isa->extension_enabled(EXT_ZKNE)) { + if(isa->get_max_xlen() == 64) { + DEFINE_RTYPE(aes64es); + DEFINE_RTYPE(aes64esm); + } else if (isa->get_max_xlen() == 32) { + DISASM_INSN("aes32esi", aes32esi, 0, {&xrd, &xrs1, &xrs2, &bs}); + DISASM_INSN("aes32esmi", aes32esmi, 0, {&xrd, &xrs1, &xrs2, &bs}); + } + } + + if (isa->extension_enabled(EXT_ZKNH)) { + DEFINE_R1TYPE(sha256sig0); + DEFINE_R1TYPE(sha256sig1); + DEFINE_R1TYPE(sha256sum0); + DEFINE_R1TYPE(sha256sum1); + if(isa->get_max_xlen() == 64) { + DEFINE_R1TYPE(sha512sig0); + DEFINE_R1TYPE(sha512sig1); + DEFINE_R1TYPE(sha512sum0); + DEFINE_R1TYPE(sha512sum1); + } else if (isa->get_max_xlen() == 32) { + DEFINE_RTYPE(sha512sig0h); + DEFINE_RTYPE(sha512sig0l); + DEFINE_RTYPE(sha512sig1h); + DEFINE_RTYPE(sha512sig1l); + DEFINE_RTYPE(sha512sum0r); + DEFINE_RTYPE(sha512sum1r); + } + } + + if (isa->extension_enabled(EXT_ZKSED)) { + DISASM_INSN("sm4ed", sm4ed, 0, {&xrd, &xrs1, &xrs2, &bs}); + DISASM_INSN("sm4ks", sm4ks, 0, {&xrd, &xrs1, &xrs2, &bs}); + } + + if (isa->extension_enabled(EXT_ZKSH)) { + DEFINE_R1TYPE(sm3p0); + DEFINE_R1TYPE(sm3p1); + } + +} + +disassembler_t::disassembler_t(const isa_parser_t *isa) +{ + // highest priority: instructions explicitly enabled + add_instructions(isa); + + // next-highest priority: other instructions in same base ISA + std::string fallback_isa_string = std::string("rv") + std::to_string(isa->get_max_xlen()) + + "gqchv_zfh_zba_zbb_zbc_zbs_zcb_zicbom_zicboz_zkn_zkr_zks_svinval_xbitmanip"; + isa_parser_t fallback_isa(fallback_isa_string.c_str(), DEFAULT_PRIV); + add_instructions(&fallback_isa); + + // finally: instructions with known opcodes but unknown arguments add_unknown_insns(this); + + // Now, reverse the lists, because we search them back-to-front (so that + // custom instructions later added with add_insn have highest priority). + for (size_t i = 0; i < HASH_SIZE+1; i++) + std::reverse(chain[i].begin(), chain[i].end()); } const disasm_insn_t* disassembler_t::probe_once(insn_t insn, size_t idx) const { - for (size_t j = 0; j < chain[idx].size(); j++) - if(*chain[idx][j] == insn) - return chain[idx][j]; + for (auto it = chain[idx].rbegin(); it != chain[idx].rend(); ++it) + if (*(*it) == insn) + return *it; return NULL; } diff --git a/vendor/riscv/riscv-isa-sim/fdt/fdt.mk.in b/vendor/riscv/riscv-isa-sim/fdt/fdt.mk.in index 273375efb..8c8dbe53c 100644 --- a/vendor/riscv/riscv-isa-sim/fdt/fdt.mk.in +++ b/vendor/riscv/riscv-isa-sim/fdt/fdt.mk.in @@ -1,10 +1,5 @@ fdt_subproject_deps = \ -fdt_hdrs = \ - fdt.h \ - libfdt.h \ - libfdt_env.h \ - fdt_c_srcs = \ fdt.c \ fdt_ro.c \ diff --git a/vendor/riscv/riscv-isa-sim/fesvr/context.cc b/vendor/riscv/riscv-isa-sim/fesvr/context.cc index ca7381376..1dceeec82 100644 --- a/vendor/riscv/riscv-isa-sim/fesvr/context.cc +++ b/vendor/riscv/riscv-isa-sim/fesvr/context.cc @@ -49,7 +49,7 @@ void context_t::init(void (*f)(void*), void* a) #ifdef USE_UCONTEXT getcontext(context.get()); context->uc_link = creator->context.get(); - context->uc_stack.ss_size = 64*1024; + context->uc_stack.ss_size = 1024 * 1024; context->uc_stack.ss_sp = new void*[context->uc_stack.ss_size/sizeof(void*)]; #ifndef GLIBC_64BIT_PTR_BUG makecontext(context.get(), (void(*)(void))&context_t::wrapper, 1, this); diff --git a/vendor/riscv/riscv-isa-sim/fesvr/debug_defines.h b/vendor/riscv/riscv-isa-sim/fesvr/debug_defines.h deleted file mode 100644 index e5f929105..000000000 --- a/vendor/riscv/riscv-isa-sim/fesvr/debug_defines.h +++ /dev/null @@ -1,1418 +0,0 @@ -#define DTM_IDCODE 0x01 -/* -* Identifies the release version of this part. - */ -#define DTM_IDCODE_VERSION_OFFSET 28 -#define DTM_IDCODE_VERSION_LENGTH 4 -#define DTM_IDCODE_VERSION (0xf << DTM_IDCODE_VERSION_OFFSET) -/* -* Identifies the designer's part number of this part. - */ -#define DTM_IDCODE_PARTNUMBER_OFFSET 12 -#define DTM_IDCODE_PARTNUMBER_LENGTH 16 -#define DTM_IDCODE_PARTNUMBER (0xffff << DTM_IDCODE_PARTNUMBER_OFFSET) -/* -* Identifies the designer/manufacturer of this part. Bits 6:0 must be -* bits 6:0 of the designer/manufacturer's Identification Code as -* assigned by JEDEC Standard JEP106. Bits 10:7 contain the modulo-16 -* count of the number of continuation characters (0x7f) in that same -* Identification Code. - */ -#define DTM_IDCODE_MANUFID_OFFSET 1 -#define DTM_IDCODE_MANUFID_LENGTH 11 -#define DTM_IDCODE_MANUFID (0x7ff << DTM_IDCODE_MANUFID_OFFSET) -#define DTM_IDCODE_1_OFFSET 0 -#define DTM_IDCODE_1_LENGTH 1 -#define DTM_IDCODE_1 (0x1 << DTM_IDCODE_1_OFFSET) -#define DTM_DTMCS 0x10 -/* -* Writing 1 to this bit does a hard reset of the DTM, -* causing the DTM to forget about any outstanding DMI transactions. -* In general this should only be used when the Debugger has -* reason to expect that the outstanding DMI transaction will never -* complete (e.g. a reset condition caused an inflight DMI transaction to -* be cancelled). - */ -#define DTM_DTMCS_DMIHARDRESET_OFFSET 17 -#define DTM_DTMCS_DMIHARDRESET_LENGTH 1 -#define DTM_DTMCS_DMIHARDRESET (0x1 << DTM_DTMCS_DMIHARDRESET_OFFSET) -/* -* Writing 1 to this bit clears the sticky error state -* and allows the DTM to retry or complete the previous -* transaction. - */ -#define DTM_DTMCS_DMIRESET_OFFSET 16 -#define DTM_DTMCS_DMIRESET_LENGTH 1 -#define DTM_DTMCS_DMIRESET (0x1 << DTM_DTMCS_DMIRESET_OFFSET) -/* -* This is a hint to the debugger of the minimum number of -* cycles a debugger should spend in -* Run-Test/Idle after every DMI scan to avoid a `busy' -* return code (\Fdmistat of 3). A debugger must still -* check \Fdmistat when necessary. -* -* 0: It is not necessary to enter Run-Test/Idle at all. -* -* 1: Enter Run-Test/Idle and leave it immediately. -* -* 2: Enter Run-Test/Idle and stay there for 1 cycle before leaving. -* -* And so on. - */ -#define DTM_DTMCS_IDLE_OFFSET 12 -#define DTM_DTMCS_IDLE_LENGTH 3 -#define DTM_DTMCS_IDLE (0x7 << DTM_DTMCS_IDLE_OFFSET) -/* -* 0: No error. -* -* 1: Reserved. Interpret the same as 2. -* -* 2: An operation failed (resulted in \Fop of 2). -* -* 3: An operation was attempted while a DMI access was still in -* progress (resulted in \Fop of 3). - */ -#define DTM_DTMCS_DMISTAT_OFFSET 10 -#define DTM_DTMCS_DMISTAT_LENGTH 2 -#define DTM_DTMCS_DMISTAT (0x3 << DTM_DTMCS_DMISTAT_OFFSET) -/* -* The size of \Faddress in \Rdmi. - */ -#define DTM_DTMCS_ABITS_OFFSET 4 -#define DTM_DTMCS_ABITS_LENGTH 6 -#define DTM_DTMCS_ABITS (0x3f << DTM_DTMCS_ABITS_OFFSET) -/* -* 0: Version described in spec version 0.11. -* -* 1: Version described in spec version 0.13 (and later?), which -* reduces the DMI data width to 32 bits. -* -* Other values are reserved for future use. - */ -#define DTM_DTMCS_VERSION_OFFSET 0 -#define DTM_DTMCS_VERSION_LENGTH 4 -#define DTM_DTMCS_VERSION (0xf << DTM_DTMCS_VERSION_OFFSET) -#define DTM_DMI 0x11 -/* -* Address used for DMI access. In Update-DR this value is used -* to access the DM over the DMI. - */ -#define DTM_DMI_ADDRESS_OFFSET 34 -#define DTM_DMI_ADDRESS_LENGTH abits -#define DTM_DMI_ADDRESS (((1L< #include #include +#include class memif_t; diff --git a/vendor/riscv/riscv-isa-sim/fesvr/dtm.cc b/vendor/riscv/riscv-isa-sim/fesvr/dtm.cc index 418ac63ab..0f810e723 100644 --- a/vendor/riscv/riscv-isa-sim/fesvr/dtm.cc +++ b/vendor/riscv/riscv-isa-sim/fesvr/dtm.cc @@ -1,6 +1,5 @@ #include "dtm.h" -#include "debug_defines.h" -#include "encoding.h" +#include "riscv/debug_defines.h" #include #include #include @@ -38,16 +37,13 @@ #define S1 9 #define AC_AR_REGNO(x) ((0x1000 | x) << AC_ACCESS_REGISTER_REGNO_OFFSET) -#define AC_AR_SIZE(x) (((x == 128)? 4 : (x == 64 ? 3 : 2)) << AC_ACCESS_REGISTER_SIZE_OFFSET) +#define AC_AR_SIZE(x) (((x == 128)? 4 : (x == 64 ? 3 : 2)) << AC_ACCESS_REGISTER_AARSIZE_OFFSET) #define WRITE 1 #define SET 2 #define CLEAR 3 #define CSRRx(type, dst, csr, src) (0x73 | ((type) << 12) | ((dst) << 7) | ((src) << 15) | (uint32_t)((csr) << 20)) -#define get_field(reg, mask) (((reg) & (mask)) / ((mask) & ~((mask) << 1))) -#define set_field(reg, mask, val) (((reg) & ~(mask)) | (((val) * ((mask) & ~((mask) << 1))) & (mask))) - #define RUN_AC_OR_DIE(a, b, c, d, e) { \ uint32_t cmderr = run_abstract_command(a, b, c, d, e); \ if (cmderr) { \ @@ -79,22 +75,22 @@ void dtm_t::nop() } void dtm_t::select_hart(int hartsel) { - int dmcontrol = read(DMI_DMCONTROL); - write (DMI_DMCONTROL, set_field(dmcontrol, DMI_DMCONTROL_HARTSEL, hartsel)); + int dmcontrol = read(DM_DMCONTROL); + write (DM_DMCONTROL, set_field(dmcontrol, DM_DMCONTROL_HASEL, hartsel)); current_hart = hartsel; } int dtm_t::enumerate_harts() { - int max_hart = (1 << DMI_DMCONTROL_HARTSEL_LENGTH) - 1; - write(DMI_DMCONTROL, set_field(read(DMI_DMCONTROL), DMI_DMCONTROL_HARTSEL, max_hart)); - read(DMI_DMSTATUS); - max_hart = get_field(read(DMI_DMCONTROL), DMI_DMCONTROL_HARTSEL); + int max_hart = (1 << DM_DMCONTROL_HASEL_LENGTH) - 1; + write(DM_DMCONTROL, set_field(read(DM_DMCONTROL), DM_DMCONTROL_HASEL, max_hart)); + read(DM_DMSTATUS); + max_hart = get_field(read(DM_DMCONTROL), DM_DMCONTROL_HASEL); int hartsel; for (hartsel = 0; hartsel <= max_hart; hartsel++) { select_hart(hartsel); - int dmstatus = read(DMI_DMSTATUS); - if (get_field(dmstatus, DMI_DMSTATUS_ANYNONEXISTENT)) + int dmstatus = read(DM_DMSTATUS); + if (get_field(dmstatus, DM_DMSTATUS_ANYNONEXISTENT)) break; } return hartsel; @@ -103,44 +99,44 @@ int dtm_t::enumerate_harts() { void dtm_t::halt(int hartsel) { if (running) { - write(DMI_DMCONTROL, DMI_DMCONTROL_DMACTIVE); + write(DM_DMCONTROL, DM_DMCONTROL_DMACTIVE); // Read dmstatus to avoid back-to-back writes to dmcontrol. - read(DMI_DMSTATUS); + read(DM_DMSTATUS); } - int dmcontrol = DMI_DMCONTROL_HALTREQ | DMI_DMCONTROL_DMACTIVE; - dmcontrol = set_field(dmcontrol, DMI_DMCONTROL_HARTSEL, hartsel); - write(DMI_DMCONTROL, dmcontrol); + int dmcontrol = DM_DMCONTROL_HALTREQ | DM_DMCONTROL_DMACTIVE; + dmcontrol = set_field(dmcontrol, DM_DMCONTROL_HASEL, hartsel); + write(DM_DMCONTROL, dmcontrol); int dmstatus; do { - dmstatus = read(DMI_DMSTATUS); - } while(get_field(dmstatus, DMI_DMSTATUS_ALLHALTED) == 0); - dmcontrol &= ~DMI_DMCONTROL_HALTREQ; - write(DMI_DMCONTROL, dmcontrol); + dmstatus = read(DM_DMSTATUS); + } while(get_field(dmstatus, DM_DMSTATUS_ALLHALTED) == 0); + dmcontrol &= ~DM_DMCONTROL_HALTREQ; + write(DM_DMCONTROL, dmcontrol); // Read dmstatus to avoid back-to-back writes to dmcontrol. - read(DMI_DMSTATUS); + read(DM_DMSTATUS); current_hart = hartsel; } void dtm_t::resume(int hartsel) { - int dmcontrol = DMI_DMCONTROL_RESUMEREQ | DMI_DMCONTROL_DMACTIVE; - dmcontrol = set_field(dmcontrol, DMI_DMCONTROL_HARTSEL, hartsel); - write(DMI_DMCONTROL, dmcontrol); + int dmcontrol = DM_DMCONTROL_RESUMEREQ | DM_DMCONTROL_DMACTIVE; + dmcontrol = set_field(dmcontrol, DM_DMCONTROL_HASEL, hartsel); + write(DM_DMCONTROL, dmcontrol); int dmstatus; do { - dmstatus = read(DMI_DMSTATUS); - } while (get_field(dmstatus, DMI_DMSTATUS_ALLRESUMEACK) == 0); - dmcontrol &= ~DMI_DMCONTROL_RESUMEREQ; - write(DMI_DMCONTROL, dmcontrol); + dmstatus = read(DM_DMSTATUS); + } while (get_field(dmstatus, DM_DMSTATUS_ALLRESUMEACK) == 0); + dmcontrol &= ~DM_DMCONTROL_RESUMEREQ; + write(DM_DMCONTROL, dmcontrol); // Read dmstatus to avoid back-to-back writes to dmcontrol. - read(DMI_DMSTATUS); + read(DM_DMSTATUS); current_hart = hartsel; if (running) { - write(DMI_DMCONTROL, DMI_DMCONTROL_DMACTIVE); + write(DM_DMCONTROL, DM_DMCONTROL_DMACTIVE); // Read dmstatus to avoid back-to-back writes to dmcontrol. - read(DMI_DMSTATUS); + read(DM_DMSTATUS); } } @@ -182,32 +178,32 @@ uint32_t dtm_t::run_abstract_command(uint32_t command, assert(data_n <= data_words); for (size_t i = 0; i < program_n; i++) { - write(DMI_PROGBUF0 + i, program[i]); + write(DM_PROGBUF0 + i, program[i]); } if (get_field(command, AC_ACCESS_REGISTER_WRITE) && get_field(command, AC_ACCESS_REGISTER_TRANSFER)) { for (size_t i = 0; i < data_n; i++) { - write(DMI_DATA0 + i, data[i]); + write(DM_DATA0 + i, data[i]); } } - write(DMI_COMMAND, command); + write(DM_COMMAND, command); // Wait for not busy and then check for error. uint32_t abstractcs; do { - abstractcs = read(DMI_ABSTRACTCS); - } while (abstractcs & DMI_ABSTRACTCS_BUSY); + abstractcs = read(DM_ABSTRACTCS); + } while (abstractcs & DM_ABSTRACTCS_BUSY); if ((get_field(command, AC_ACCESS_REGISTER_WRITE) == 0) && get_field(command, AC_ACCESS_REGISTER_TRANSFER)) { for (size_t i = 0; i < data_n; i++){ - data[i] = read(DMI_DATA0 + i); + data[i] = read(DM_DATA0 + i); } } - return get_field(abstractcs, DMI_ABSTRACTCS_CMDERR); + return get_field(abstractcs, DM_ABSTRACTCS_CMDERR); } @@ -317,24 +313,24 @@ void dtm_t::write_chunk(uint64_t taddr, size_t len, const void* src) uint32_t abstractcs; for (size_t i = 1; i < (len * 8 / xlen); i++){ if (i == 1) { - write(DMI_ABSTRACTAUTO, 1 << DMI_ABSTRACTAUTO_AUTOEXECDATA_OFFSET); + write(DM_ABSTRACTAUTO, 1 << DM_ABSTRACTAUTO_AUTOEXECDATA_OFFSET); } memcpy(data, curr, xlen/8); curr += xlen/8; if (xlen == 64) { - write(DMI_DATA0 + 1, data[1]); + write(DM_DATA0 + 1, data[1]); } - write(DMI_DATA0, data[0]); //Triggers a command w/ autoexec. + write(DM_DATA0, data[0]); //Triggers a command w/ autoexec. do { - abstractcs = read(DMI_ABSTRACTCS); - } while (abstractcs & DMI_ABSTRACTCS_BUSY); - if ( get_field(abstractcs, DMI_ABSTRACTCS_CMDERR)) { - die(get_field(abstractcs, DMI_ABSTRACTCS_CMDERR)); + abstractcs = read(DM_ABSTRACTCS); + } while (abstractcs & DM_ABSTRACTCS_BUSY); + if ( get_field(abstractcs, DM_ABSTRACTCS_CMDERR)) { + die(get_field(abstractcs, DM_ABSTRACTCS_CMDERR)); } } if ((len * 8 / xlen) > 1) { - write(DMI_ABSTRACTAUTO, 0); + write(DM_ABSTRACTAUTO, 0); } restore_reg(S0, s0); @@ -360,7 +356,7 @@ void dtm_t::die(uint32_t cmderr) //throw std::runtime_error("Debug Abstract Command Error #" + std::to_string(cmderr) + "(" + msg + ")"); printf("ERROR: %s:%d, Debug Abstract Command Error #%d (%s)", __FILE__, __LINE__, cmderr, msg); printf("ERROR: %s:%d, Should die, but allowing simulation to continue and fail.", __FILE__, __LINE__); - write(DMI_ABSTRACTCS, DMI_ABSTRACTCS_CMDERR); + write(DM_ABSTRACTCS, DM_ABSTRACTCS_CMDERR); } @@ -458,9 +454,9 @@ uint64_t dtm_t::modify_csr(unsigned which, uint64_t data, uint32_t type) RUN_AC_OR_DIE(command, prog, sizeof(prog) / sizeof(*prog), adata, xlen/(4*8)); - uint64_t res = read(DMI_DATA0);//adata[0]; + uint64_t res = read(DM_DATA0);//adata[0]; if (xlen == 64) - res |= read(DMI_DATA0 + 1);//((uint64_t) adata[1]) << 32; + res |= read(DM_DATA0 + 1);//((uint64_t) adata[1]) << 32; resume(current_hart); return res; @@ -490,13 +486,13 @@ uint32_t dtm_t::get_xlen() abort(); return 128; } - write(DMI_ABSTRACTCS, DMI_ABSTRACTCS_CMDERR); + write(DM_ABSTRACTCS, DM_ABSTRACTCS_CMDERR); cmderr = run_abstract_command(command | AC_AR_SIZE(64), prog, 0, data, 0); if (cmderr == 0){ return 64; } - write(DMI_ABSTRACTCS, DMI_ABSTRACTCS_CMDERR); + write(DM_ABSTRACTCS, DM_ABSTRACTCS_CMDERR); cmderr = run_abstract_command(command | AC_AR_SIZE(32), prog, 0, data, 0); if (cmderr == 0){ @@ -545,7 +541,7 @@ void dtm_t::reset() // In theory any hart can handle the memory accesses, // this will enforce that hart 0 handles them. select_hart(0); - read(DMI_DMSTATUS); + read(DM_DMSTATUS); } void dtm_t::idle() @@ -560,23 +556,23 @@ void dtm_t::producer_thread() // depend on in this code. // Enable the debugger. - write(DMI_DMCONTROL, DMI_DMCONTROL_DMACTIVE); + write(DM_DMCONTROL, DM_DMCONTROL_DMACTIVE); // Poll until the debugger agrees it's enabled. - while ((read(DMI_DMCONTROL) & DMI_DMCONTROL_DMACTIVE) == 0) ; + while ((read(DM_DMCONTROL) & DM_DMCONTROL_DMACTIVE) == 0) ; // These are checked every time we run an abstract command. - uint32_t abstractcs = read(DMI_ABSTRACTCS); - ram_words = get_field(abstractcs, DMI_ABSTRACTCS_PROGSIZE); - data_words = get_field(abstractcs, DMI_ABSTRACTCS_DATACOUNT); + uint32_t abstractcs = read(DM_ABSTRACTCS); + ram_words = get_field(abstractcs, DM_ABSTRACTCS_PROGBUFSIZE); + data_words = get_field(abstractcs, DM_ABSTRACTCS_DATACOUNT); // These things are only needed for the 'modify_csr' function. // That could be re-written to not use these at some performance // overhead. - uint32_t hartinfo = read(DMI_HARTINFO); - assert(get_field(hartinfo, DMI_HARTINFO_NSCRATCH) > 0); - assert(get_field(hartinfo, DMI_HARTINFO_DATAACCESS)); + uint32_t hartinfo = read(DM_HARTINFO); + assert(get_field(hartinfo, DM_HARTINFO_NSCRATCH) > 0); + assert(get_field(hartinfo, DM_HARTINFO_DATAACCESS)); - data_base = get_field(hartinfo, DMI_HARTINFO_DATAADDR); + data_base = get_field(hartinfo, DM_HARTINFO_DATAADDR); num_harts = enumerate_harts(); halt(0); diff --git a/vendor/riscv/riscv-isa-sim/fesvr/dtm.h b/vendor/riscv/riscv-isa-sim/fesvr/dtm.h index fbf161efe..1f5ee3e89 100644 --- a/vendor/riscv/riscv-isa-sim/fesvr/dtm.h +++ b/vendor/riscv/riscv-isa-sim/fesvr/dtm.h @@ -64,6 +64,16 @@ class dtm_t : public htif_t virtual void reset() override; virtual void idle() override; + uint32_t run_abstract_command(uint32_t command, const uint32_t program[], size_t program_n, + uint32_t data[], size_t data_n); + + void die(uint32_t cmderr); + void halt(int); + int enumerate_harts(); + void select_hart(int); + void resume(int); + uint32_t get_data_base() { return data_base; }; + private: context_t host; context_t* target; @@ -76,14 +86,6 @@ class dtm_t : public htif_t resp resp_buf; bool running; - uint32_t run_abstract_command(uint32_t command, const uint32_t program[], size_t program_n, - uint32_t data[], size_t data_n); - - void die(uint32_t cmderr); - void halt(int); - int enumerate_harts(); - void select_hart(int); - void resume(int); uint64_t save_reg(unsigned regno); void restore_reg(unsigned regno, uint64_t val); diff --git a/vendor/riscv/riscv-isa-sim/fesvr/elfloader.cc b/vendor/riscv/riscv-isa-sim/fesvr/elfloader.cc index 76cd6da57..c70de12db 100644 --- a/vendor/riscv/riscv-isa-sim/fesvr/elfloader.cc +++ b/vendor/riscv/riscv-isa-sim/fesvr/elfloader.cc @@ -1,5 +1,6 @@ // See LICENSE for license details. +#include "config.h" #include "elf.h" #include "memif.h" #include "byteorder.h" @@ -16,22 +17,28 @@ #include #include -std::map load_elf(const char* fn, memif_t* memif, reg_t* entry) +std::map load_elf(const char* fn, memif_t* memif, reg_t* entry, unsigned required_xlen = 0) { int fd = open(fn, O_RDONLY); struct stat s; - assert(fd != -1); + if (fd == -1) + throw std::invalid_argument(std::string("Specified ELF can't be opened: ") + strerror(errno)); if (fstat(fd, &s) < 0) abort(); size_t size = s.st_size; char* buf = (char*)mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0); - assert(buf != MAP_FAILED); + if (buf == MAP_FAILED) + throw std::invalid_argument(std::string("Specified ELF can't be mapped: ") + strerror(errno)); close(fd); assert(size >= sizeof(Elf64_Ehdr)); const Elf64_Ehdr* eh64 = (const Elf64_Ehdr*)buf; assert(IS_ELF32(*eh64) || IS_ELF64(*eh64)); + unsigned xlen = IS_ELF32(*eh64) ? 32 : 64; + if (required_xlen != 0 && required_xlen != xlen) { + throw incompat_xlen(required_xlen, xlen); + } assert(IS_ELFLE(*eh64) || IS_ELFBE(*eh64)); assert(IS_ELF_EXEC(*eh64)); assert(IS_ELF_RISCV(*eh64) || IS_ELF_EM_NONE(*eh64)); @@ -94,7 +101,9 @@ std::map load_elf(const char* fn, memif_t* memif, reg_t* } while (0) if (IS_ELFLE(*eh64)) { - memif->set_target_endianness(memif_endianness_little); + if (memif->get_target_endianness() != endianness_little) { + throw std::invalid_argument("Specified ELF is little endian, but system uses a big-endian memory system. Rerun without --big-endian"); + } if (IS_ELF32(*eh64)) LOAD_ELF(Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr, Elf32_Sym, from_le); else @@ -103,7 +112,9 @@ std::map load_elf(const char* fn, memif_t* memif, reg_t* #ifndef RISCV_ENABLE_DUAL_ENDIAN throw std::invalid_argument("Specified ELF is big endian. Configure with --enable-dual-endian to enable support"); #else - memif->set_target_endianness(memif_endianness_big); + if (memif->get_target_endianness() != endianness_big) { + throw std::invalid_argument("Specified ELF is big endian, but system uses a little-endian memory system. Rerun with --big-endian"); + } if (IS_ELF32(*eh64)) LOAD_ELF(Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr, Elf32_Sym, from_be); else diff --git a/vendor/riscv/riscv-isa-sim/fesvr/elfloader.h b/vendor/riscv/riscv-isa-sim/fesvr/elfloader.h index 696ef4784..ae4ee78c2 100644 --- a/vendor/riscv/riscv-isa-sim/fesvr/elfloader.h +++ b/vendor/riscv/riscv-isa-sim/fesvr/elfloader.h @@ -8,6 +8,6 @@ #include class memif_t; -std::map load_elf(const char* fn, memif_t* memif, reg_t* entry); +std::map load_elf(const char* fn, memif_t* memif, reg_t* entry, unsigned required_xlen = 0); #endif diff --git a/vendor/riscv/riscv-isa-sim/fesvr/fesvr.mk.in b/vendor/riscv/riscv-isa-sim/fesvr/fesvr.mk.in index 43aed6786..c85493991 100644 --- a/vendor/riscv/riscv-isa-sim/fesvr/fesvr.mk.in +++ b/vendor/riscv/riscv-isa-sim/fesvr/fesvr.mk.in @@ -1,4 +1,4 @@ -fesvr_hdrs = \ +fesvr_install_hdrs = \ byteorder.h \ elf.h \ elfloader.h \ @@ -15,8 +15,6 @@ fesvr_hdrs = \ rfb.h \ tsi.h \ -fesvr_install_hdrs = $(fesvr_hdrs) - fesvr_install_config_hdr = yes fesvr_install_lib = yes diff --git a/vendor/riscv/riscv-isa-sim/fesvr/htif.cc b/vendor/riscv/riscv-isa-sim/fesvr/htif.cc index 715003996..3f93f7b50 100644 --- a/vendor/riscv/riscv-isa-sim/fesvr/htif.cc +++ b/vendor/riscv/riscv-isa-sim/fesvr/htif.cc @@ -1,16 +1,20 @@ // See LICENSE for license details. +#include "config.h" #include "htif.h" #include "rfb.h" #include "elfloader.h" #include "platform.h" #include "byteorder.h" +#include "trap.h" +#include "../riscv/common.h" #include #include #include #include #include #include +#include #include #include #include @@ -80,12 +84,25 @@ htif_t::~htif_t() void htif_t::start() { - if (!targs.empty() && targs[0] != "none") + if (!targs.empty() && targs[0] != "none") { + try { load_program(); + } catch (const incompat_xlen & err) { + fprintf(stderr, "Error: cannot execute %d-bit program on RV%d hart\n", err.actual_xlen, err.expected_xlen); + exit(1); + } + } reset(); } +static void bad_address(const std::string& situation, reg_t addr) +{ + std::cerr << "Access exception occurred while " << situation << ":\n"; + std::cerr << "Memory address 0x" << std::hex << addr << " is invalid\n"; + exit(-1); +} + std::map htif_t::load_payload(const std::string& payload, reg_t* entry) { std::string path; @@ -96,6 +113,12 @@ std::map htif_t::load_payload(const std::string& payload, std::string test_path = PREFIX TARGET_DIR + payload; if (access(test_path.c_str(), F_OK) == 0) path = test_path; + else + throw std::runtime_error( + "could not open " + payload + "; searched paths:\n" + + "\t. (current directory)\n" + + "\t" + PREFIX TARGET_DIR + " (based on configured --prefix and --with-target)" + ); } if (path.empty()) @@ -119,7 +142,12 @@ std::map htif_t::load_payload(const std::string& payload, htif_t* htif; } preload_aware_memif(this); - return load_elf(path.c_str(), &preload_aware_memif, entry); + try { + return load_elf(path.c_str(), &preload_aware_memif, entry, expected_xlen); + } catch (mem_trap_t& t) { + bad_address("loading payload " + payload, t.get_tval()); + abort(); + } } void htif_t::load_program() @@ -134,26 +162,39 @@ void htif_t::load_program() } // detect torture tests so we can print the memory signature at the end - if (symbols.count("begin_signature") && symbols.count("end_signature")) - { + if (symbols.count("begin_signature") && symbols.count("end_signature")) { sig_addr = symbols["begin_signature"]; sig_len = symbols["end_signature"] - sig_addr; } - for (auto payload : payloads) - { + for (auto payload : payloads) { reg_t dummy_entry; load_payload(payload, &dummy_entry); } - for (auto i : symbols) - { - auto it = addr2symbol.find(i.second); - if ( it == addr2symbol.end()) - addr2symbol[i.second] = i.first; - } + class nop_memif_t : public memif_t { + public: + nop_memif_t(htif_t* htif) : memif_t(htif), htif(htif) {} + void read(addr_t UNUSED addr, size_t UNUSED len, void UNUSED *bytes) override {} + void write(addr_t UNUSED taddr, size_t UNUSED len, const void UNUSED *src) override {} + private: + htif_t* htif; + } nop_memif(this); - return; + reg_t nop_entry; + for (auto &s : symbol_elfs) { + std::map other_symbols = load_elf(s.c_str(), &nop_memif, &nop_entry, + expected_xlen); + symbols.merge(other_symbols); + } + + for (auto i : symbols) { + auto it = addr2symbol.find(i.second); + if ( it == addr2symbol.end()) + addr2symbol[i.second] = i.first; + } + + return; } const char* htif_t::get_symbol(uint64_t addr) @@ -218,19 +259,37 @@ int htif_t::run() while (!signal_exit && exitcode == 0) { - if (auto tohost = from_target(mem.read_uint64(tohost_addr))) { - mem.write_uint64(tohost_addr, target_endian::zero); - command_t cmd(mem, tohost, fromhost_callback); - device_list.handle_command(cmd); - } else { - idle(); + uint64_t tohost; + + try { + if ((tohost = from_target(mem.read_uint64(tohost_addr))) != 0) + mem.write_uint64(tohost_addr, target_endian::zero); + } catch (mem_trap_t& t) { + bad_address("accessing tohost", t.get_tval()); } - device_list.tick(); + try { + if (tohost != 0) { + command_t cmd(mem, tohost, fromhost_callback); + device_list.handle_command(cmd); + } else { + idle(); + } - if (!fromhost_queue.empty() && !mem.read_uint64(fromhost_addr)) { - mem.write_uint64(fromhost_addr, to_target(fromhost_queue.front())); - fromhost_queue.pop(); + device_list.tick(); + } catch (mem_trap_t& t) { + std::stringstream tohost_hex; + tohost_hex << std::hex << tohost; + bad_address("host was accessing memory on behalf of target (tohost = 0x" + tohost_hex.str() + ")", t.get_tval()); + } + + try { + if (!fromhost_queue.empty() && !mem.read_uint64(fromhost_addr)) { + mem.write_uint64(fromhost_addr, to_target(fromhost_queue.front())); + fromhost_queue.pop(); + } + } catch (mem_trap_t& t) { + bad_address("accessing fromhost", t.get_tval()); } } @@ -282,7 +341,12 @@ void htif_t::parse_arguments(int argc, char ** argv) break; case HTIF_LONG_OPTIONS_OPTIND + 5: line_size = atoi(optarg); - + break; + case HTIF_LONG_OPTIONS_OPTIND + 6: + targs.push_back(optarg); + break; + case HTIF_LONG_OPTIONS_OPTIND + 7: + symbol_elfs.push_back(optarg); break; case '?': if (!opterr) @@ -318,9 +382,17 @@ void htif_t::parse_arguments(int argc, char ** argv) c = HTIF_LONG_OPTIONS_OPTIND + 4; optarg = optarg + 9; } - else if(arg.find("+signature-granularity=")==0){ - c = HTIF_LONG_OPTIONS_OPTIND + 5; - optarg = optarg + 23; + else if (arg.find("+signature-granularity=") == 0) { + c = HTIF_LONG_OPTIONS_OPTIND + 5; + optarg = optarg + 23; + } + else if (arg.find("+target-argument=") == 0) { + c = HTIF_LONG_OPTIONS_OPTIND + 6; + optarg = optarg + 17; + } + else if (arg.find("+symbol-elf=") == 0) { + c = HTIF_LONG_OPTIONS_OPTIND + 7; + optarg = optarg + 12; } else if (arg.find("+permissive-off") == 0) { if (opterr) diff --git a/vendor/riscv/riscv-isa-sim/fesvr/htif.h b/vendor/riscv/riscv-isa-sim/fesvr/htif.h index 3cee25f7c..dd7c060e4 100644 --- a/vendor/riscv/riscv-isa-sim/fesvr/htif.h +++ b/vendor/riscv/riscv-isa-sim/fesvr/htif.h @@ -26,33 +26,28 @@ class htif_t : public chunked_memif_t int run(); bool done(); int exit_code(); - + void set_expected_xlen(unsigned int m) { expected_xlen = m; } virtual memif_t& memif() { return mem; } template inline T from_target(target_endian n) const { -#ifdef RISCV_ENABLE_DUAL_ENDIAN - memif_endianness_t endianness = get_target_endianness(); - assert(endianness == memif_endianness_little || endianness == memif_endianness_big); + endianness_t endianness = get_target_endianness(); + assert(endianness == endianness_little || endianness == endianness_big); - return endianness == memif_endianness_big? n.from_be() : n.from_le(); -#else - return n.from_le(); -#endif + return endianness == endianness_big? n.from_be() : n.from_le(); } template inline target_endian to_target(T n) const { -#ifdef RISCV_ENABLE_DUAL_ENDIAN - memif_endianness_t endianness = get_target_endianness(); - assert(endianness == memif_endianness_little || endianness == memif_endianness_big); + endianness_t endianness = get_target_endianness(); + assert(endianness == endianness_little || endianness == endianness_big); - return endianness == memif_endianness_big? target_endian::to_be(n) : target_endian::to_le(n); -#else - return target_endian::to_le(n); -#endif + return endianness == endianness_big? target_endian::to_be(n) : target_endian::to_le(n); } + addr_t get_tohost_addr() { return tohost_addr; } + addr_t get_fromhost_addr() { return fromhost_addr; } + protected: virtual void reset() = 0; @@ -68,12 +63,13 @@ class htif_t : public chunked_memif_t virtual void idle() {} const std::vector& host_args() { return hargs; } + const std::vector& target_args() { return targs; } reg_t get_entry_point() { return entry; } // indicates that the initial program load can skip writing this address // range to memory, because it has already been loaded through a sideband - virtual bool is_address_preloaded(addr_t taddr, size_t len) { return false; } + virtual bool is_address_preloaded(addr_t, size_t) { return false; } // Given an address, return symbol from addr2symbol map const char* get_symbol(uint64_t addr); @@ -82,7 +78,7 @@ class htif_t : public chunked_memif_t void parse_arguments(int argc, char ** argv); void register_devices(); void usage(const char * program_name); - + unsigned int expected_xlen = 0; memif_t mem; reg_t entry; bool writezeros; @@ -103,8 +99,7 @@ class htif_t : public chunked_memif_t std::vector dynamic_devices; std::vector payloads; - const std::vector& target_args() { return targs; } - + std::vector symbol_elfs; std::map addr2symbol; friend class memif_t; @@ -133,6 +128,8 @@ class htif_t : public chunked_memif_t +chroot=PATH\n\ --payload=PATH Load PATH memory as an additional ELF payload\n\ +payload=PATH\n\ + --symbol-elf=PATH Populate the symbol table with the ELF file at PATH\n\ + +symbol-elf=PATH\n\ \n\ HOST OPTIONS (currently unsupported)\n\ --disk=DISK Add DISK device. Use a ramdisk since this isn't\n\ @@ -150,7 +147,9 @@ TARGET (RISC-V BINARY) OPTIONS\n\ {"signature", required_argument, 0, HTIF_LONG_OPTIONS_OPTIND + 2 }, \ {"chroot", required_argument, 0, HTIF_LONG_OPTIONS_OPTIND + 3 }, \ {"payload", required_argument, 0, HTIF_LONG_OPTIONS_OPTIND + 4 }, \ -{"signature-granularity", optional_argument, 0, HTIF_LONG_OPTIONS_OPTIND + 5 }, \ +{"signature-granularity", required_argument, 0, HTIF_LONG_OPTIONS_OPTIND + 5 }, \ +{"target-argument", required_argument, 0, HTIF_LONG_OPTIONS_OPTIND + 6 }, \ +{"symbol-elf", required_argument, 0, HTIF_LONG_OPTIONS_OPTIND + 7 }, \ {0, 0, 0, 0} #endif // __HTIF_H diff --git a/vendor/riscv/riscv-isa-sim/fesvr/htif_hexwriter.h b/vendor/riscv/riscv-isa-sim/fesvr/htif_hexwriter.h index 725616626..0cd859b1b 100644 --- a/vendor/riscv/riscv-isa-sim/fesvr/htif_hexwriter.h +++ b/vendor/riscv/riscv-isa-sim/fesvr/htif_hexwriter.h @@ -21,7 +21,7 @@ protected: void read_chunk(addr_t taddr, size_t len, void* dst); void write_chunk(addr_t taddr, size_t len, const void* src); - void clear_chunk(addr_t taddr, size_t len) {} + void clear_chunk(addr_t, size_t) {} size_t chunk_max_size() { return width; } size_t chunk_align() { return width; } diff --git a/vendor/riscv/riscv-isa-sim/fesvr/memif.h b/vendor/riscv/riscv-isa-sim/fesvr/memif.h index 001c42544..ebed3d728 100644 --- a/vendor/riscv/riscv-isa-sim/fesvr/memif.h +++ b/vendor/riscv/riscv-isa-sim/fesvr/memif.h @@ -5,18 +5,14 @@ #include #include +#include #include "byteorder.h" +#include "../riscv/cfg.h" typedef uint64_t reg_t; typedef int64_t sreg_t; typedef reg_t addr_t; -typedef enum { - memif_endianness_undecided, - memif_endianness_little, - memif_endianness_big -} memif_endianness_t; - class chunked_memif_t { public: @@ -27,10 +23,11 @@ public: virtual size_t chunk_align() = 0; virtual size_t chunk_max_size() = 0; - virtual void set_target_endianness(memif_endianness_t endianness) {} - virtual memif_endianness_t get_target_endianness() const { - return memif_endianness_undecided; + virtual endianness_t get_target_endianness() const { + return endianness_little; } + + virtual ~chunked_memif_t() = default; }; class memif_t @@ -68,10 +65,7 @@ public: virtual void write_int64(addr_t addr, target_endian val); // endianness - virtual void set_target_endianness(memif_endianness_t endianness) { - cmemif->set_target_endianness(endianness); - } - virtual memif_endianness_t get_target_endianness() const { + virtual endianness_t get_target_endianness() const { return cmemif->get_target_endianness(); } @@ -79,4 +73,11 @@ protected: chunked_memif_t* cmemif; }; +class incompat_xlen : public std::exception { +public: + const unsigned expected_xlen; + const unsigned actual_xlen; + incompat_xlen(unsigned _expected_xlen, unsigned _actual_xlen) : expected_xlen(_expected_xlen), actual_xlen(_actual_xlen) {} +}; + #endif // __MEMIF_H diff --git a/vendor/riscv/riscv-isa-sim/fesvr/rfb.cc b/vendor/riscv/riscv-isa-sim/fesvr/rfb.cc index 2594a1b87..bd72fda7b 100644 --- a/vendor/riscv/riscv-isa-sim/fesvr/rfb.cc +++ b/vendor/riscv/riscv-isa-sim/fesvr/rfb.cc @@ -119,7 +119,7 @@ void rfb_t::set_pixel_format(const std::string& s) throw std::runtime_error("bad pixel format"); } -void rfb_t::fb_update(const std::string& s) +void rfb_t::fb_update() { std::string u; u += str(uint8_t(0)); @@ -153,7 +153,7 @@ void rfb_t::tick() std::swap(fb1, fb2); if (pthread_mutex_trylock(&lock) == 0) { - fb_update(""); + fb_update(); pthread_mutex_unlock(&lock); } } diff --git a/vendor/riscv/riscv-isa-sim/fesvr/rfb.h b/vendor/riscv/riscv-isa-sim/fesvr/rfb.h index 263663a24..e153bc80a 100644 --- a/vendor/riscv/riscv-isa-sim/fesvr/rfb.h +++ b/vendor/riscv/riscv-isa-sim/fesvr/rfb.h @@ -25,7 +25,7 @@ class rfb_t : public device_t void thread_main(); friend void* rfb_thread_main(void*); std::string pixel_format(); - void fb_update(const std::string& s); + void fb_update(); void set_encodings(const std::string& s); void set_pixel_format(const std::string& s); void write(const std::string& s); diff --git a/vendor/riscv/riscv-isa-sim/fesvr/syscall.cc b/vendor/riscv/riscv-isa-sim/fesvr/syscall.cc index ab7fc3b4c..e277be19b 100644 --- a/vendor/riscv/riscv-isa-sim/fesvr/syscall.cc +++ b/vendor/riscv/riscv-isa-sim/fesvr/syscall.cc @@ -1,5 +1,6 @@ // See LICENSE for license details. +#include "config.h" #include "syscall.h" #include "htif.h" #include "byteorder.h" @@ -17,6 +18,10 @@ using namespace std::placeholders; #define RISCV_AT_FDCWD -100 +#ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + struct riscv_stat { target_endian dev; @@ -169,9 +174,16 @@ syscall_t::syscall_t(htif_t* htif) if (stdin_fd < 0 || stdout_fd0 < 0 || stdout_fd1 < 0) throw std::runtime_error("could not dup stdin/stdout"); - fds.alloc(stdin_fd); // stdin -> stdin - fds.alloc(stdout_fd0); // stdout -> stdout - fds.alloc(stdout_fd1); // stderr -> stdout + fds_index.push_back(fds.alloc(stdin_fd)); // stdin -> stdin + fds_index.push_back(fds.alloc(stdout_fd0)); // stdout -> stdout + fds_index.push_back(fds.alloc(stdout_fd1)); // stderr -> stdout +} + +syscall_t::~syscall_t() { + for (auto i: fds_index) { + close(fds.lookup(i)); + fds.dealloc(i); + } } std::string syscall_t::do_chroot(const char* fn) diff --git a/vendor/riscv/riscv-isa-sim/fesvr/syscall.h b/vendor/riscv/riscv-isa-sim/fesvr/syscall.h index 4915efd68..c002e6c66 100644 --- a/vendor/riscv/riscv-isa-sim/fesvr/syscall.h +++ b/vendor/riscv/riscv-isa-sim/fesvr/syscall.h @@ -28,6 +28,7 @@ class syscall_t : public device_t { public: syscall_t(htif_t*); + ~syscall_t(); void set_chroot(const char* where); @@ -38,6 +39,7 @@ class syscall_t : public device_t memif_t* memif; std::vector table; fds_t fds; + std::vector fds_index; void handle_syscall(command_t cmd); void dispatch(addr_t mm); diff --git a/vendor/riscv/riscv-isa-sim/riscv-disasm.pc.in b/vendor/riscv/riscv-isa-sim/riscv-disasm.pc.in index 8e022e930..915136aa3 100644 --- a/vendor/riscv/riscv-isa-sim/riscv-disasm.pc.in +++ b/vendor/riscv/riscv-isa-sim/riscv-disasm.pc.in @@ -1,7 +1,7 @@ prefix=@prefix@ exec_prefix=@prefix@ -libdir=${prefix}/@libdir@ -includedir=${prefix}/@includedir@ +libdir=@libdir@ +includedir=@includedir@ Name: riscv-disasm Description: RISC-V disassembler diff --git a/vendor/riscv/riscv-isa-sim/riscv-fesvr.pc.in b/vendor/riscv/riscv-isa-sim/riscv-fesvr.pc.in index efd7eed1e..82a95693d 100644 --- a/vendor/riscv/riscv-isa-sim/riscv-fesvr.pc.in +++ b/vendor/riscv/riscv-isa-sim/riscv-fesvr.pc.in @@ -1,7 +1,7 @@ prefix=@prefix@ exec_prefix=@prefix@ -libdir=${prefix}/@libdir@ -includedir=${prefix}/@includedir@ +libdir=@libdir@ +includedir=@includedir@ Name: riscv-fesvr Description: RISC-V front-end server diff --git a/vendor/riscv/riscv-isa-sim/riscv/abstract_interrupt_controller.h b/vendor/riscv/riscv-isa-sim/riscv/abstract_interrupt_controller.h new file mode 100644 index 000000000..946b079f7 --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/abstract_interrupt_controller.h @@ -0,0 +1,14 @@ +#ifndef _RISCV_ABSTRACT_INTERRUPT_CONTROLLER_H +#define _RISCV_ABSTRACT_INTERRUPT_CONTROLLER_H + +#include "decode.h" +#include +#include + +class abstract_interrupt_controller_t { + public: + virtual void set_interrupt_level(uint32_t interrupt_id, int level) = 0; + virtual ~abstract_interrupt_controller_t() {} +}; + +#endif diff --git a/vendor/riscv/riscv-isa-sim/riscv/arith.h b/vendor/riscv/riscv-isa-sim/riscv/arith.h index 9e0c2f749..3b807e969 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/arith.h +++ b/vendor/riscv/riscv-isa-sim/riscv/arith.h @@ -20,7 +20,6 @@ inline uint64_t mulhu(uint64_t a, uint64_t b) y2 = t >> 32; t = a0*b1 + y1; - y1 = t; t = a1*b1 + y2 + (t >> 32); y2 = t; @@ -188,6 +187,15 @@ static inline int clz(uint64_t val) return res; } +// Count number of contiguous 1 bits starting from the LSB. +static inline int cto(uint64_t val) +{ + int res = 0; + while ((val & 1) == 1) + val >>= 1, res++; + return res; +} + static inline int log2(uint64_t val) { if (!val) diff --git a/vendor/riscv/riscv-isa-sim/riscv/cachesim.cc b/vendor/riscv/riscv-isa-sim/riscv/cachesim.cc index 6e030d13e..24e87d377 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/cachesim.cc +++ b/vendor/riscv/riscv-isa-sim/riscv/cachesim.cc @@ -39,9 +39,9 @@ cache_sim_t* cache_sim_t::construct(const char* config, const char* name) void cache_sim_t::init() { - if(sets == 0 || (sets & (sets-1))) + if (sets == 0 || (sets & (sets-1))) help(); - if(linesz < 8 || (linesz & (linesz-1))) + if (linesz < 8 || (linesz & (linesz-1))) help(); idx_shift = 0; @@ -76,9 +76,6 @@ cache_sim_t::~cache_sim_t() void cache_sim_t::print_stats() { - if(read_accesses + write_accesses == 0) - return; - float mr = 100.0f*(read_misses+write_misses)/(read_accesses+write_accesses); std::cout << std::setprecision(3) << std::fixed; @@ -159,6 +156,31 @@ void cache_sim_t::access(uint64_t addr, size_t bytes, bool store) *check_tag(addr) |= DIRTY; } +void cache_sim_t::clean_invalidate(uint64_t addr, size_t bytes, bool clean, bool inval) +{ + uint64_t start_addr = addr & ~(linesz-1); + uint64_t end_addr = (addr + bytes + linesz-1) & ~(linesz-1); + uint64_t cur_addr = start_addr; + while (cur_addr < end_addr) { + uint64_t* hit_way = check_tag(cur_addr); + if (likely(hit_way != NULL)) + { + if (clean) { + if (*hit_way & DIRTY) { + writebacks++; + *hit_way &= ~DIRTY; + } + } + + if (inval) + *hit_way &= ~VALID; + } + cur_addr += linesz; + } + if (miss_handler) + miss_handler->clean_invalidate(addr, bytes, clean, inval); +} + fa_cache_sim_t::fa_cache_sim_t(size_t ways, size_t linesz, const char* name) : cache_sim_t(1, ways, linesz, name) { diff --git a/vendor/riscv/riscv-isa-sim/riscv/cachesim.h b/vendor/riscv/riscv-isa-sim/riscv/cachesim.h index 259725acf..a96e639f8 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/cachesim.h +++ b/vendor/riscv/riscv-isa-sim/riscv/cachesim.h @@ -4,6 +4,7 @@ #define _RISCV_CACHE_SIM_H #include "memtracer.h" +#include "common.h" #include #include #include @@ -27,6 +28,7 @@ class cache_sim_t virtual ~cache_sim_t(); void access(uint64_t addr, size_t bytes, bool store); + void clean_invalidate(uint64_t addr, size_t bytes, bool clean, bool inval); void print_stats(); void set_miss_handler(cache_sim_t* mh) { miss_handler = mh; } void set_log(bool _log) { log = _log; } @@ -90,10 +92,18 @@ class cache_memtracer_t : public memtracer_t { cache->set_miss_handler(mh); } + void clean_invalidate(uint64_t addr, size_t bytes, bool clean, bool inval) + { + cache->clean_invalidate(addr, bytes, clean, inval); + } void set_log(bool log) { cache->set_log(log); } + void print_stats() + { + cache->print_stats(); + } protected: cache_sim_t* cache; @@ -102,8 +112,9 @@ class cache_memtracer_t : public memtracer_t class icache_sim_t : public cache_memtracer_t { public: - icache_sim_t(const char* config) : cache_memtracer_t(config, "I$") {} - bool interested_in_range(uint64_t begin, uint64_t end, access_type type) + icache_sim_t(const char* config, const char* name = "I$") + : cache_memtracer_t(config, name) {} + bool interested_in_range(uint64_t UNUSED begin, uint64_t UNUSED end, access_type type) { return type == FETCH; } @@ -116,8 +127,9 @@ class icache_sim_t : public cache_memtracer_t class dcache_sim_t : public cache_memtracer_t { public: - dcache_sim_t(const char* config) : cache_memtracer_t(config, "D$") {} - bool interested_in_range(uint64_t begin, uint64_t end, access_type type) + dcache_sim_t(const char* config, const char* name = "D$") + : cache_memtracer_t(config, name) {} + bool interested_in_range(uint64_t UNUSED begin, uint64_t UNUSED end, access_type type) { return type == LOAD || type == STORE; } diff --git a/vendor/riscv/riscv-isa-sim/riscv/cfg.cc b/vendor/riscv/riscv-isa-sim/riscv/cfg.cc new file mode 100644 index 000000000..457aa92ba --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/cfg.cc @@ -0,0 +1,27 @@ +// See LICENSE for license details. + +#include "cfg.h" +#include "mmu.h" +#include "decode.h" + +mem_cfg_t::mem_cfg_t(reg_t base, reg_t size) : base(base), size(size) +{ + assert(mem_cfg_t::check_if_supported(base, size)); +} + +bool mem_cfg_t::check_if_supported(reg_t base, reg_t size) +{ + // The truth of these conditions should be ensured by whatever is creating + // the regions in the first place, but we have them here to make sure that + // we can't end up describing memory regions that don't make sense. They + // ask that the page size is a multiple of the minimum page size, that the + // page is aligned to the minimum page size, that the page is non-empty and + // that the top address is still representable in a reg_t. + // + // Note: (base + size == 0) part of the assertion is to handle cases like + // { base = 0xffff_ffff_ffff_f000, size: 0x1000 } + return (size % PGSIZE == 0) && + (base % PGSIZE == 0) && + (size > 0) && + ((base + size > base) || (base + size == 0)); +} diff --git a/vendor/riscv/riscv-isa-sim/riscv/cfg.h b/vendor/riscv/riscv-isa-sim/riscv/cfg.h new file mode 100644 index 000000000..8ead618b7 --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/cfg.h @@ -0,0 +1,109 @@ +// See LICENSE for license details. +#ifndef _RISCV_CFG_H +#define _RISCV_CFG_H + +#include +#include +#include "decode.h" +#include + +typedef enum { + endianness_little, + endianness_big +} endianness_t; + +template +class cfg_arg_t { +public: + cfg_arg_t(T default_val) + : value(default_val), was_set(false) {} + + bool overridden() const { return was_set; } + + T operator()() const { return value; } + + T operator=(const T v) { + value = v; + was_set = true; + return value; + } + +private: + T value; + bool was_set; +}; + +// Configuration that describes a memory region +class mem_cfg_t +{ +public: + static bool check_if_supported(reg_t base, reg_t size); + + mem_cfg_t(reg_t base, reg_t size); + + reg_t get_base() const { + return base; + } + + reg_t get_size() const { + return size; + } + + reg_t get_inclusive_end() const { + return base + size - 1; + } + +private: + reg_t base; + reg_t size; +}; + +class cfg_t +{ +public: + cfg_t(std::pair default_initrd_bounds, + const char *default_bootargs, + const char *default_isa, const char *default_priv, + const char *default_varch, + const bool default_misaligned, + const endianness_t default_endianness, + const reg_t default_pmpregions, + const std::vector &default_mem_layout, + const std::vector default_hartids, + bool default_real_time_clint, + const reg_t default_trigger_count) + : initrd_bounds(default_initrd_bounds), + bootargs(default_bootargs), + isa(default_isa), + priv(default_priv), + varch(default_varch), + misaligned(default_misaligned), + endianness(default_endianness), + pmpregions(default_pmpregions), + mem_layout(default_mem_layout), + hartids(default_hartids), + explicit_hartids(false), + real_time_clint(default_real_time_clint), + trigger_count(default_trigger_count) + {} + + cfg_arg_t> initrd_bounds; + cfg_arg_t bootargs; + cfg_arg_t isa; + cfg_arg_t priv; + cfg_arg_t varch; + bool misaligned; + endianness_t endianness; + reg_t pmpregions; + cfg_arg_t> mem_layout; + std::optional start_pc; + cfg_arg_t> hartids; + bool explicit_hartids; + cfg_arg_t real_time_clint; + reg_t trigger_count; + + size_t nprocs() const { return hartids().size(); } + size_t max_hartid() const { return hartids().back(); } +}; + +#endif diff --git a/vendor/riscv/riscv-isa-sim/riscv/clint.cc b/vendor/riscv/riscv-isa-sim/riscv/clint.cc index 72d1bbeb8..f27f02c34 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/clint.cc +++ b/vendor/riscv/riscv-isa-sim/riscv/clint.cc @@ -1,9 +1,10 @@ #include #include "devices.h" #include "processor.h" +#include "simif.h" -clint_t::clint_t(std::vector& procs, uint64_t freq_hz, bool real_time) - : procs(procs), freq_hz(freq_hz), real_time(real_time), mtime(0), mtimecmp(procs.size()) +clint_t::clint_t(simif_t* sim, uint64_t freq_hz, bool real_time) + : sim(sim), freq_hz(freq_hz), real_time(real_time), mtime(0) { struct timeval base; @@ -11,6 +12,7 @@ clint_t::clint_t(std::vector& procs, uint64_t freq_hz, bool real_t real_time_ref_secs = base.tv_sec; real_time_ref_usecs = base.tv_usec; + increment(0); } /* 0000 msip hart 0 @@ -29,16 +31,29 @@ clint_t::clint_t(std::vector& procs, uint64_t freq_hz, bool real_t bool clint_t::load(reg_t addr, size_t len, uint8_t* bytes) { + if (len > 8) + return false; + increment(0); - if (addr >= MSIP_BASE && addr + len <= MSIP_BASE + procs.size()*sizeof(msip_t)) { - std::vector msip(procs.size()); - for (size_t i = 0; i < procs.size(); ++i) - msip[i] = !!(procs[i]->state.mip->read() & MIP_MSIP); - memcpy(bytes, (uint8_t*)&msip[0] + addr - MSIP_BASE, len); - } else if (addr >= MTIMECMP_BASE && addr + len <= MTIMECMP_BASE + procs.size()*sizeof(mtimecmp_t)) { - memcpy(bytes, (uint8_t*)&mtimecmp[0] + addr - MTIMECMP_BASE, len); - } else if (addr >= MTIME_BASE && addr + len <= MTIME_BASE + sizeof(mtime_t)) { - memcpy(bytes, (uint8_t*)&mtime + addr - MTIME_BASE, len); + + if (addr >= MSIP_BASE && addr < MTIMECMP_BASE) { + if (len == 8) { + // Implement double-word loads as a pair of word loads + return load(addr, 4, bytes) && load(addr + 4, 4, bytes + 4); + } + + const auto hart_id = (addr - MSIP_BASE) / sizeof(msip_t); + const msip_t res = sim->get_harts().count(hart_id) && (sim->get_harts().at(hart_id)->state.mip->read() & MIP_MSIP); + read_little_endian_reg(res, addr, len, bytes); + return true; + } else if (addr >= MTIMECMP_BASE && addr < MTIME_BASE) { + const auto hart_id = (addr - MTIMECMP_BASE) / sizeof(mtimecmp_t); + const mtime_t res = sim->get_harts().count(hart_id) ? mtimecmp[hart_id] : 0; + read_little_endian_reg(res, addr, len, bytes); + } else if (addr >= MTIME_BASE && addr < MTIME_BASE + sizeof(mtime_t)) { + read_little_endian_reg(mtime, addr, len, bytes); + } else if (addr + len <= CLINT_SIZE) { + memset(bytes, 0, len); } else { return false; } @@ -47,21 +62,31 @@ bool clint_t::load(reg_t addr, size_t len, uint8_t* bytes) bool clint_t::store(reg_t addr, size_t len, const uint8_t* bytes) { - if (addr >= MSIP_BASE && addr + len <= MSIP_BASE + procs.size()*sizeof(msip_t)) { - std::vector msip(procs.size()); - std::vector mask(procs.size(), 0); - memcpy((uint8_t*)&msip[0] + addr - MSIP_BASE, bytes, len); - memset((uint8_t*)&mask[0] + addr - MSIP_BASE, 0xff, len); - for (size_t i = 0; i < procs.size(); ++i) { - if (!(mask[i] & 0xFF)) continue; - procs[i]->state.mip->backdoor_write_with_mask(MIP_MSIP, 0); - if (!!(msip[i] & 1)) - procs[i]->state.mip->backdoor_write_with_mask(MIP_MSIP, MIP_MSIP); + if (len > 8) + return false; + + if (addr >= MSIP_BASE && addr < MTIMECMP_BASE) { + if (len == 8) { + // Implement double-word stores as a pair of word stores + return store(addr, 4, bytes) && store(addr + 4, 4, bytes + 4); } - } else if (addr >= MTIMECMP_BASE && addr + len <= MTIMECMP_BASE + procs.size()*sizeof(mtimecmp_t)) { - memcpy((uint8_t*)&mtimecmp[0] + addr - MTIMECMP_BASE, bytes, len); - } else if (addr >= MTIME_BASE && addr + len <= MTIME_BASE + sizeof(mtime_t)) { - memcpy((uint8_t*)&mtime + addr - MTIME_BASE, bytes, len); + + if (addr % sizeof(msip_t) == 0) { // ignore in-between bytes + msip_t msip = 0; + write_little_endian_reg(&msip, addr, len, bytes); + + const auto hart_id = (addr - MSIP_BASE) / sizeof(msip_t); + if (sim->get_harts().count(hart_id)) + sim->get_harts().at(hart_id)->state.mip->backdoor_write_with_mask(MIP_MSIP, msip & 1 ? MIP_MSIP : 0); + } + } else if (addr >= MTIMECMP_BASE && addr < MTIME_BASE) { + const auto hart_id = (addr - MTIMECMP_BASE) / sizeof(mtimecmp_t); + if (sim->get_harts().count(hart_id)) + write_little_endian_reg(&mtimecmp[hart_id], addr, len, bytes); + } else if (addr >= MTIME_BASE && addr < MTIME_BASE + sizeof(mtime_t)) { + write_little_endian_reg(&mtime, addr, len, bytes); + } else if (addr + len <= CLINT_SIZE) { + // Do nothing } else { return false; } @@ -81,9 +106,9 @@ void clint_t::increment(reg_t inc) } else { mtime += inc; } - for (size_t i = 0; i < procs.size(); i++) { - procs[i]->state.mip->backdoor_write_with_mask(MIP_MTIP, 0); - if (mtime >= mtimecmp[i]) - procs[i]->state.mip->backdoor_write_with_mask(MIP_MTIP, MIP_MTIP); + + for (const auto& [hart_id, hart] : sim->get_harts()) { + hart->state.time->sync(mtime); + hart->state.mip->backdoor_write_with_mask(MIP_MTIP, mtime >= mtimecmp[hart_id] ? MIP_MTIP : 0); } } diff --git a/vendor/riscv/riscv-isa-sim/riscv/common.h b/vendor/riscv/riscv-isa-sim/riscv/common.h index 002a83f0e..a354ced0c 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/common.h +++ b/vendor/riscv/riscv-isa-sim/riscv/common.h @@ -8,11 +8,15 @@ # define unlikely(x) __builtin_expect(x, 0) # define NOINLINE __attribute__ ((noinline)) # define NORETURN __attribute__ ((noreturn)) +# define ALWAYS_INLINE __attribute__ ((always_inline)) +# define UNUSED __attribute__ ((unused)) #else # define likely(x) (x) # define unlikely(x) (x) # define NOINLINE # define NORETURN +# define ALWAYS_INLINE +# define UNUSED #endif #endif diff --git a/vendor/riscv/riscv-isa-sim/riscv/csrs.cc b/vendor/riscv/riscv-isa-sim/riscv/csrs.cc index 49b505bf8..2e01983b6 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/csrs.cc +++ b/vendor/riscv/riscv-isa-sim/riscv/csrs.cc @@ -1,11 +1,14 @@ // See LICENSE for license details. +// For std::any_of +#include + #include "csrs.h" // For processor_t: #include "processor.h" #include "mmu.h" // For get_field(): -#include "decode.h" +#include "decode_macros.h" // For trap_virtual_instruction and trap_illegal_instruction: #include "trap.h" // For require(): @@ -15,7 +18,6 @@ #undef STATE #define STATE (*state) - // implement class csr_t csr_t::csr_t(processor_t* const proc, const reg_t addr): proc(proc), @@ -44,7 +46,6 @@ void csr_t::verify_permissions(insn_t insn, bool write) const { } } - csr_t::~csr_t() { } @@ -59,10 +60,9 @@ void csr_t::log_write() const noexcept { log_special_write(address, written_value()); } -void csr_t::log_special_write(const reg_t address, const reg_t val) const noexcept { -#if defined(RISCV_ENABLE_COMMITLOG) - proc->get_state()->log_reg_write[((address) << 4) | 4] = {val, 0}; -#endif +void csr_t::log_special_write(const reg_t UNUSED address, const reg_t UNUSED val) const noexcept { + if (proc->get_log_commits_enabled()) + proc->get_state()->log_reg_write[((address) << 4) | 4] = {val, 0}; } reg_t csr_t::written_value() const noexcept { @@ -75,16 +75,11 @@ basic_csr_t::basic_csr_t(processor_t* const proc, const reg_t addr, const reg_t val(init) { } -reg_t basic_csr_t::read() const noexcept { - return val; -} - bool basic_csr_t::unlogged_write(const reg_t val) noexcept { this->val = val; return true; } - // implement class pmpaddr_csr_t pmpaddr_csr_t::pmpaddr_csr_t(processor_t* const proc, const reg_t addr): csr_t(proc, addr), @@ -93,7 +88,6 @@ pmpaddr_csr_t::pmpaddr_csr_t(processor_t* const proc, const reg_t addr): pmpidx(address - CSR_PMPADDR0) { } - void pmpaddr_csr_t::verify_permissions(insn_t insn, bool write) const { csr_t::verify_permissions(insn, write); // If n_pmp is zero, that means pmp is not implemented hence raise @@ -104,14 +98,12 @@ void pmpaddr_csr_t::verify_permissions(insn_t insn, bool write) const { throw trap_illegal_instruction(insn.bits()); } - reg_t pmpaddr_csr_t::read() const noexcept { if ((cfg & PMP_A) >= PMP_NAPOT) return val | (~proc->pmp_tor_mask() >> 1); return val & proc->pmp_tor_mask(); } - bool pmpaddr_csr_t::unlogged_write(const reg_t val) noexcept { // If no PMPs are configured, disallow access to all. Otherwise, // allow access to all, but unimplemented ones are hardwired to @@ -121,7 +113,9 @@ bool pmpaddr_csr_t::unlogged_write(const reg_t val) noexcept { if (proc->n_pmp == 0) return false; - bool locked = cfg & PMP_L; + const bool lock_bypass = state->mseccfg->get_rlb(); + const bool locked = !lock_bypass && (cfg & PMP_L); + if (pmpidx < proc->n_pmp && !locked && !next_locked_and_tor()) { this->val = val & ((reg_t(1) << (MAX_PADDR_BITS - PMP_SHIFT)) - 1); } @@ -133,30 +127,27 @@ bool pmpaddr_csr_t::unlogged_write(const reg_t val) noexcept { bool pmpaddr_csr_t::next_locked_and_tor() const noexcept { if (pmpidx+1 >= state->max_pmp) return false; // this is the last entry - bool next_locked = state->pmpaddr[pmpidx+1]->cfg & PMP_L; - bool next_tor = (state->pmpaddr[pmpidx+1]->cfg & PMP_A) == PMP_TOR; + const bool lock_bypass = state->mseccfg->get_rlb(); + const bool next_locked = !lock_bypass && (state->pmpaddr[pmpidx+1]->cfg & PMP_L); + const bool next_tor = (state->pmpaddr[pmpidx+1]->cfg & PMP_A) == PMP_TOR; return next_locked && next_tor; } - reg_t pmpaddr_csr_t::tor_paddr() const noexcept { return (val & proc->pmp_tor_mask()) << PMP_SHIFT; } - reg_t pmpaddr_csr_t::tor_base_paddr() const noexcept { if (pmpidx == 0) return 0; // entry 0 always uses 0 as base return state->pmpaddr[pmpidx-1]->tor_paddr(); } - reg_t pmpaddr_csr_t::napot_mask() const noexcept { bool is_na4 = (cfg & PMP_A) == PMP_NA4; reg_t mask = (val << 1) | (!is_na4) | ~proc->pmp_tor_mask(); return ~(mask & ~(mask + 1)) << PMP_SHIFT; } - bool pmpaddr_csr_t::match4(reg_t addr) const noexcept { if ((cfg & PMP_A) == 0) return false; bool is_tor = (cfg & PMP_A) == PMP_TOR; @@ -165,7 +156,6 @@ bool pmpaddr_csr_t::match4(reg_t addr) const noexcept { return ((addr ^ tor_paddr()) & napot_mask()) == 0; } - bool pmpaddr_csr_t::subset_match(reg_t addr, reg_t len) const noexcept { if ((addr | len) & (len - 1)) abort(); @@ -188,21 +178,55 @@ bool pmpaddr_csr_t::subset_match(reg_t addr, reg_t len) const noexcept { return !(is_tor ? tor_homogeneous : napot_homogeneous); } - bool pmpaddr_csr_t::access_ok(access_type type, reg_t mode) const noexcept { - return - (mode == PRV_M && !(cfg & PMP_L)) || - (type == LOAD && (cfg & PMP_R)) || - (type == STORE && (cfg & PMP_W)) || - (type == FETCH && (cfg & PMP_X)); -} + const bool cfgx = cfg & PMP_X; + const bool cfgw = cfg & PMP_W; + const bool cfgr = cfg & PMP_R; + const bool cfgl = cfg & PMP_L; + const bool prvm = mode == PRV_M; + + const bool typer = type == LOAD; + const bool typex = type == FETCH; + const bool typew = type == STORE; + const bool normal_rwx = (typer && cfgr) || (typew && cfgw) || (typex && cfgx); + const bool mseccfg_mml = state->mseccfg->get_mml(); + + if (mseccfg_mml) { + if (cfgx && cfgw && cfgr && cfgl) { + // Locked Shared data region: Read only on both M and S/U mode. + return typer; + } else { + const bool mml_shared_region = !cfgr && cfgw; + const bool mml_chk_normal = (prvm == cfgl) && normal_rwx; + const bool mml_chk_shared = + (!cfgl && cfgx && (typer || typew)) || + (!cfgl && !cfgx && (typer || (typew && prvm))) || + (cfgl && typex) || + (cfgl && typer && cfgx && prvm); + return mml_shared_region ? mml_chk_shared : mml_chk_normal; + } + } else { + const bool m_bypass = (prvm && !cfgl); + return m_bypass || normal_rwx; + } +} // implement class pmpcfg_csr_t pmpcfg_csr_t::pmpcfg_csr_t(processor_t* const proc, const reg_t addr): csr_t(proc, addr) { } +void pmpcfg_csr_t::verify_permissions(insn_t insn, bool write) const { + csr_t::verify_permissions(insn, write); + // If n_pmp is zero, that means pmp is not implemented hence raise + // trap if it tries to access the csr. I would prefer to implement + // this by not instantiating any pmpcfg_csr_t for these regs, but + // n_pmp can change after reset() is run. + if (proc->n_pmp == 0) + throw trap_illegal_instruction(insn.bits()); +} + reg_t pmpcfg_csr_t::read() const noexcept { reg_t cfg_res = 0; for (size_t i0 = (address - CSR_PMPCFG0) * 4, i = i0; i < i0 + proc->get_xlen() / 8 && i < state->max_pmp; i++) @@ -215,14 +239,35 @@ bool pmpcfg_csr_t::unlogged_write(const reg_t val) noexcept { return false; bool write_success = false; + const bool rlb = state->mseccfg->get_rlb(); + const bool mml = state->mseccfg->get_mml(); for (size_t i0 = (address - CSR_PMPCFG0) * 4, i = i0; i < i0 + proc->get_xlen() / 8; i++) { if (i < proc->n_pmp) { - if (!(state->pmpaddr[i]->cfg & PMP_L)) { + const bool locked = (state->pmpaddr[i]->cfg & PMP_L); + if (rlb || !locked) { uint8_t cfg = (val >> (8 * (i - i0))) & (PMP_R | PMP_W | PMP_X | PMP_A | PMP_L); - cfg &= ~PMP_W | ((cfg & PMP_R) ? PMP_W : 0); // Disallow R=0 W=1 + // Drop R=0 W=1 when MML = 0 + // Remove the restriction when MML = 1 + if (!mml) { + cfg &= ~PMP_W | ((cfg & PMP_R) ? PMP_W : 0); + } + // Disallow A=NA4 when granularity > 4 if (proc->lg_pmp_granularity != PMP_SHIFT && (cfg & PMP_A) == PMP_NA4) - cfg |= PMP_NAPOT; // Disallow A=NA4 when granularity > 4 - state->pmpaddr[i]->cfg = cfg; + cfg |= PMP_NAPOT; + /* + * Adding a rule with executable privileges that either is M-mode-only or a locked Shared-Region + * is not possible and such pmpcfg writes are ignored, leaving pmpcfg unchanged. + * This restriction can be temporarily lifted e.g. during the boot process, by setting mseccfg.RLB. + */ + const bool cfgx = cfg & PMP_X; + const bool cfgw = cfg & PMP_W; + const bool cfgr = cfg & PMP_R; + if (rlb || !(mml && ((cfg & PMP_L) // M-mode-only or a locked Shared-Region + && !(cfgx && cfgw && cfgr) // RWX = 111 is allowed + && (cfgx || (cfgw && !cfgr)) // X=1 or RW=01 is not allowed + ))) { + state->pmpaddr[i]->cfg = cfg; + } } write_success = true; } @@ -231,6 +276,52 @@ bool pmpcfg_csr_t::unlogged_write(const reg_t val) noexcept { return write_success; } +// implement class mseccfg_csr_t +mseccfg_csr_t::mseccfg_csr_t(processor_t* const proc, const reg_t addr): + basic_csr_t(proc, addr, 0) { +} + +void mseccfg_csr_t::verify_permissions(insn_t insn, bool write) const { + basic_csr_t::verify_permissions(insn, write); + if (!proc->extension_enabled(EXT_SMEPMP)) + throw trap_illegal_instruction(insn.bits()); +} + +bool mseccfg_csr_t::get_mml() const noexcept { + return (read() & MSECCFG_MML); +} + +bool mseccfg_csr_t::get_mmwp() const noexcept { + return (read() & MSECCFG_MMWP); +} + +bool mseccfg_csr_t::get_rlb() const noexcept { + return (read() & MSECCFG_RLB); +} + +bool mseccfg_csr_t::unlogged_write(const reg_t val) noexcept { + if (proc->n_pmp == 0) + return false; + + // pmpcfg.L is 1 in any rule or entry (including disabled entries) + const bool pmplock_recorded = std::any_of(state->pmpaddr, state->pmpaddr + proc->n_pmp, + [](const pmpaddr_csr_t_p & c) { return c->is_locked(); } ); + reg_t new_val = read(); + + // When RLB is 0 and pmplock_recorded, RLB is locked to 0. + // Otherwise set the RLB bit according val + if (!(pmplock_recorded && (read() & MSECCFG_RLB) == 0)) { + new_val &= ~MSECCFG_RLB; + new_val |= (val & MSECCFG_RLB); + } + + new_val |= (val & MSECCFG_MMWP); //MMWP is sticky + new_val |= (val & MSECCFG_MML); //MML is sticky + + proc->get_mmu()->flush_tlb(); + + return basic_csr_t::unlogged_write(new_val); +} // implement class virtualized_csr_t virtualized_csr_t::virtualized_csr_t(processor_t* const proc, csr_t_p orig, csr_t_p virt): @@ -239,7 +330,6 @@ virtualized_csr_t::virtualized_csr_t(processor_t* const proc, csr_t_p orig, csr_ virt_csr(virt) { } - reg_t virtualized_csr_t::read() const noexcept { return readvirt(state->v); } @@ -256,60 +346,51 @@ bool virtualized_csr_t::unlogged_write(const reg_t val) noexcept { return false; // virt_csr or orig_csr has already logged } - // implement class epc_csr_t epc_csr_t::epc_csr_t(processor_t* const proc, const reg_t addr): csr_t(proc, addr), val(0) { } - reg_t epc_csr_t::read() const noexcept { return val & proc->pc_alignment_mask(); } - bool epc_csr_t::unlogged_write(const reg_t val) noexcept { this->val = val & ~(reg_t)1; return true; } - // implement class tvec_csr_t tvec_csr_t::tvec_csr_t(processor_t* const proc, const reg_t addr): csr_t(proc, addr), val(0) { } - reg_t tvec_csr_t::read() const noexcept { return val; } - bool tvec_csr_t::unlogged_write(const reg_t val) noexcept { this->val = val & ~(reg_t)2; return true; } - // implement class cause_csr_t cause_csr_t::cause_csr_t(processor_t* const proc, const reg_t addr): basic_csr_t(proc, addr, 0) { } - reg_t cause_csr_t::read() const noexcept { reg_t val = basic_csr_t::read(); // When reading, the interrupt bit needs to adjust to xlen. Spike does // not generally support dynamic xlen, but this code was (partly) // there since at least 2015 (ea58df8 and c4350ef). - if (proc->get_max_xlen() > proc->get_xlen()) // Move interrupt bit to top of xlen - return val | ((val >> (proc->get_max_xlen()-1)) << (proc->get_xlen()-1)); + if (proc->get_isa().get_max_xlen() > proc->get_xlen()) // Move interrupt bit to top of xlen + return val | ((val >> (proc->get_isa().get_max_xlen()-1)) << (proc->get_xlen()-1)); return val; } - // implement class base_status_csr_t base_status_csr_t::base_status_csr_t(processor_t* const proc, const reg_t addr): csr_t(proc, addr), @@ -319,19 +400,12 @@ base_status_csr_t::base_status_csr_t(processor_t* const proc, const reg_t addr): | (proc->get_const_xlen() == 32 ? SSTATUS32_SD : SSTATUS64_SD)) { } - -bool base_status_csr_t::enabled(const reg_t which) { - // If the field doesn't exist, it is always enabled. See #823. - if ((sstatus_write_mask & which) == 0) return true; - return (read() & which) != 0; -} - reg_t base_status_csr_t::compute_sstatus_write_mask() const noexcept { // If a configuration has FS bits, they will always be accessible no // matter the state of misa. - const bool has_fs = proc->extension_enabled('S') || proc->extension_enabled('F') - || proc->extension_enabled_const('V'); - const bool has_vs = proc->extension_enabled_const('V'); + const bool has_fs = (proc->extension_enabled('S') || proc->extension_enabled('F') + || proc->extension_enabled('V')) && !proc->extension_enabled(EXT_ZFINX); + const bool has_vs = proc->extension_enabled('V'); return 0 | (proc->extension_enabled('S') ? (SSTATUS_SIE | SSTATUS_SPIE | SSTATUS_SPP) : 0) | (has_page ? (SSTATUS_SUM | SSTATUS_MXR) : 0) @@ -341,7 +415,6 @@ reg_t base_status_csr_t::compute_sstatus_write_mask() const noexcept { ; } - reg_t base_status_csr_t::adjust_sd(const reg_t val) const noexcept { // This uses get_const_xlen() instead of get_xlen() not only because // the variable is static, so it's only called once, but also @@ -357,7 +430,6 @@ reg_t base_status_csr_t::adjust_sd(const reg_t val) const noexcept { return val & ~sd_bit; } - void base_status_csr_t::maybe_flush_tlb(const reg_t newval) noexcept { if ((newval ^ read()) & (MSTATUS_MPP | MSTATUS_MPRV @@ -366,7 +438,6 @@ void base_status_csr_t::maybe_flush_tlb(const reg_t newval) noexcept { proc->get_mmu()->flush_tlb(); } - namespace { int xlen_to_uxl(int xlen) { if (xlen == 32) @@ -377,17 +448,12 @@ namespace { } } - // implement class vsstatus_csr_t vsstatus_csr_t::vsstatus_csr_t(processor_t* const proc, const reg_t addr): base_status_csr_t(proc, addr), val(proc->get_state()->mstatus->read() & sstatus_read_mask) { } -reg_t vsstatus_csr_t::read() const noexcept { - return val; -} - bool vsstatus_csr_t::unlogged_write(const reg_t val) noexcept { const reg_t newval = (this->val & ~sstatus_write_mask) | (val & sstatus_write_mask); if (state->v) maybe_flush_tlb(newval); @@ -395,50 +461,36 @@ bool vsstatus_csr_t::unlogged_write(const reg_t val) noexcept { return true; } - // implement class sstatus_proxy_csr_t -sstatus_proxy_csr_t::sstatus_proxy_csr_t(processor_t* const proc, const reg_t addr, csr_t_p mstatus): +sstatus_proxy_csr_t::sstatus_proxy_csr_t(processor_t* const proc, const reg_t addr, mstatus_csr_t_p mstatus): base_status_csr_t(proc, addr), mstatus(mstatus) { } -reg_t sstatus_proxy_csr_t::read() const noexcept { - return mstatus->read() & sstatus_read_mask; -} - bool sstatus_proxy_csr_t::unlogged_write(const reg_t val) noexcept { const reg_t new_mstatus = (mstatus->read() & ~sstatus_write_mask) | (val & sstatus_write_mask); + // On RV32 this will only log the low 32 bits, so make sure we're + // not modifying anything in the upper 32 bits. + assert((sstatus_write_mask & 0xffffffffU) == sstatus_write_mask); + mstatus->write(new_mstatus); return false; // avoid double logging: already logged by mstatus->write() } - // implement class mstatus_csr_t mstatus_csr_t::mstatus_csr_t(processor_t* const proc, const reg_t addr): base_status_csr_t(proc, addr), - val(0 - | (proc->extension_enabled_const('U') ? set_field((reg_t)0, MSTATUS_UXL, xlen_to_uxl(proc->get_const_xlen())) : 0) - | (proc->extension_enabled_const('S') ? set_field((reg_t)0, MSTATUS_SXL, xlen_to_uxl(proc->get_const_xlen())) : 0) -#ifdef RISCV_ENABLE_DUAL_ENDIAN - | (proc->get_mmu()->is_target_big_endian() ? MSTATUS_UBE | MSTATUS_SBE | MSTATUS_MBE : 0) -#endif - | 0 // initial value for mstatus - ) { + val(compute_mstatus_initial_value()) { } - -reg_t mstatus_csr_t::read() const noexcept { - return val; -} - - bool mstatus_csr_t::unlogged_write(const reg_t val) noexcept { - const bool has_mpv = proc->extension_enabled('S') && proc->extension_enabled('H'); + const bool has_mpv = proc->extension_enabled('H'); const bool has_gva = has_mpv; const reg_t mask = sstatus_write_mask - | MSTATUS_MIE | MSTATUS_MPIE | MSTATUS_MPRV + | MSTATUS_MIE | MSTATUS_MPIE + | (proc->extension_enabled('U') ? MSTATUS_MPRV : 0) | MSTATUS_MPP | MSTATUS_TW | (proc->extension_enabled('S') ? MSTATUS_TSR : 0) | (has_page ? MSTATUS_TVM : 0) @@ -453,77 +505,164 @@ bool mstatus_csr_t::unlogged_write(const reg_t val) noexcept { return true; } -// implement class mstatush_csr_t -mstatush_csr_t::mstatush_csr_t(processor_t* const proc, const reg_t addr, mstatus_csr_t_p mstatus): +reg_t mstatus_csr_t::compute_mstatus_initial_value() const noexcept { + const reg_t big_endian_bits = (proc->extension_enabled_const('U') ? MSTATUS_UBE : 0) + | (proc->extension_enabled_const('S') ? MSTATUS_SBE : 0) + | MSTATUS_MBE; + return 0 + | (proc->extension_enabled_const('U') && (proc->get_const_xlen() != 32) ? set_field((reg_t)0, MSTATUS_UXL, xlen_to_uxl(proc->get_const_xlen())) : 0) + | (proc->extension_enabled_const('S') && (proc->get_const_xlen() != 32) ? set_field((reg_t)0, MSTATUS_SXL, xlen_to_uxl(proc->get_const_xlen())) : 0) + | (proc->get_mmu()->is_target_big_endian() ? big_endian_bits : 0) + | 0; // initial value for mstatus +} + +// implement class mnstatus_csr_t +mnstatus_csr_t::mnstatus_csr_t(processor_t* const proc, const reg_t addr): + basic_csr_t(proc, addr, 0) { +} + +bool mnstatus_csr_t::unlogged_write(const reg_t val) noexcept { + // NMIE can be set but not cleared + const reg_t mask = (~read() & MNSTATUS_NMIE) + | (proc->extension_enabled('H') ? MNSTATUS_MNPV : 0) + | MNSTATUS_MNPP; + + const reg_t requested_mnpp = proc->legalize_privilege(get_field(val, MNSTATUS_MNPP)); + const reg_t adjusted_val = set_field(val, MNSTATUS_MNPP, requested_mnpp); + const reg_t new_mnstatus = (read() & ~mask) | (adjusted_val & mask); + + return basic_csr_t::unlogged_write(new_mnstatus); +} + +// implement class rv32_low_csr_t +rv32_low_csr_t::rv32_low_csr_t(processor_t* const proc, const reg_t addr, csr_t_p orig): csr_t(proc, addr), - mstatus(mstatus), - mask(MSTATUSH_MPV | MSTATUSH_GVA | MSTATUSH_SBE | MSTATUSH_MBE) { + orig(orig) { } -reg_t mstatush_csr_t::read() const noexcept { - return (mstatus->read() >> 32) & mask; +reg_t rv32_low_csr_t::read() const noexcept { + return orig->read() & 0xffffffffU; } -bool mstatush_csr_t::unlogged_write(const reg_t val) noexcept { - return mstatus->unlogged_write((mstatus->written_value() & ~(mask << 32)) | ((val & mask) << 32)); +void rv32_low_csr_t::verify_permissions(insn_t insn, bool write) const { + orig->verify_permissions(insn, write); +} + +bool rv32_low_csr_t::unlogged_write(const reg_t val) noexcept { + return orig->unlogged_write((orig->written_value() >> 32 << 32) | (val & 0xffffffffU)); +} + +reg_t rv32_low_csr_t::written_value() const noexcept { + return orig->written_value() & 0xffffffffU; +} + +// implement class rv32_high_csr_t +rv32_high_csr_t::rv32_high_csr_t(processor_t* const proc, const reg_t addr, csr_t_p orig): + csr_t(proc, addr), + orig(orig) { +} + +reg_t rv32_high_csr_t::read() const noexcept { + return (orig->read() >> 32) & 0xffffffffU; +} + +void rv32_high_csr_t::verify_permissions(insn_t insn, bool write) const { + orig->verify_permissions(insn, write); +} + +bool rv32_high_csr_t::unlogged_write(const reg_t val) noexcept { + return orig->unlogged_write((orig->written_value() << 32 >> 32) | ((val & 0xffffffffU) << 32)); +} + +reg_t rv32_high_csr_t::written_value() const noexcept { + return (orig->written_value() >> 32) & 0xffffffffU; } // implement class sstatus_csr_t -sstatus_csr_t::sstatus_csr_t(processor_t* const proc, base_status_csr_t_p orig, base_status_csr_t_p virt): +sstatus_csr_t::sstatus_csr_t(processor_t* const proc, sstatus_proxy_csr_t_p orig, vsstatus_csr_t_p virt): virtualized_csr_t(proc, orig, virt), orig_sstatus(orig), virt_sstatus(virt) { } void sstatus_csr_t::dirty(const reg_t dirties) { + // As an optimization, return early if already dirty. + if ((orig_sstatus->read() & dirties) == dirties) { + if (likely(!state->v || (virt_sstatus->read() & dirties) == dirties)) + return; + } + // Catch problems like #823 where P-extension instructions were not // checking for mstatus.VS!=Off: if (!enabled(dirties)) abort(); - orig_csr->write(orig_csr->read() | dirties); + orig_sstatus->write(orig_sstatus->read() | dirties); if (state->v) { - virt_csr->write(virt_csr->read() | dirties); + virt_sstatus->write(virt_sstatus->read() | dirties); } } bool sstatus_csr_t::enabled(const reg_t which) { - if (!orig_sstatus->enabled(which)) - return false; - if (state->v && !virt_sstatus->enabled(which)) - return false; - return true; -} + if ((orig_sstatus->read() & which) != 0) { + if (!state->v || (virt_sstatus->read() & which) != 0) + return true; + } + // If the field doesn't exist, it is always enabled. See #823. + if (!orig_sstatus->field_exists(which)) + return true; + + return false; +} // implement class misa_csr_t misa_csr_t::misa_csr_t(processor_t* const proc, const reg_t addr, const reg_t max_isa): basic_csr_t(proc, addr, max_isa), max_isa(max_isa), - write_mask(max_isa & (0 // allow MAFDCH bits in MISA to be modified + write_mask(max_isa & (0 // allow MAFDQCHV bits in MISA to be modified | (1L << ('M' - 'A')) | (1L << ('A' - 'A')) | (1L << ('F' - 'A')) | (1L << ('D' - 'A')) + | (1L << ('Q' - 'A')) | (1L << ('C' - 'A')) | (1L << ('H' - 'A')) + | (1L << ('V' - 'A')) ) ) { } +reg_t misa_csr_t::dependency(const reg_t val, const char feature, const char depends_on) const noexcept { + return (val & (1L << (depends_on - 'A'))) ? val : (val & ~(1L << (feature - 'A'))); +} + bool misa_csr_t::unlogged_write(const reg_t val) noexcept { + const reg_t old_misa = read(); + // the write is ignored if increasing IALIGN would misalign the PC - if (!(val & (1L << ('C' - 'A'))) && (state->pc & 2)) + if (!(val & (1L << ('C' - 'A'))) && (old_misa & (1L << ('C' - 'A'))) && (state->pc & 2)) return false; - const bool val_supports_f = val & (1L << ('F' - 'A')); - const reg_t val_without_d = val & ~(1L << ('D' - 'A')); - const reg_t adjusted_val = val_supports_f ? val : val_without_d; + reg_t adjusted_val = val; + adjusted_val = dependency(adjusted_val, 'D', 'F'); + adjusted_val = dependency(adjusted_val, 'Q', 'D'); + adjusted_val = dependency(adjusted_val, 'V', 'D'); - const reg_t old_misa = read(); const bool prev_h = old_misa & (1L << ('H' - 'A')); const reg_t new_misa = (adjusted_val & write_mask) | (old_misa & ~write_mask); const bool new_h = new_misa & (1L << ('H' - 'A')); + proc->set_extension_enable(EXT_ZCA, (new_misa & (1L << ('C' - 'A'))) || !proc->get_isa().extension_enabled('C')); + proc->set_extension_enable(EXT_ZCF, (new_misa & (1L << ('F' - 'A'))) && proc->extension_enabled(EXT_ZCA)); + proc->set_extension_enable(EXT_ZCD, (new_misa & (1L << ('D' - 'A'))) && proc->extension_enabled(EXT_ZCA)); + proc->set_extension_enable(EXT_ZCB, proc->extension_enabled(EXT_ZCA)); + proc->set_extension_enable(EXT_ZCMP, proc->extension_enabled(EXT_ZCA)); + proc->set_extension_enable(EXT_ZCMT, proc->extension_enabled(EXT_ZCA)); + proc->set_extension_enable(EXT_ZFH, new_misa & (1L << ('F' - 'A'))); + proc->set_extension_enable(EXT_ZFHMIN, new_misa & (1L << ('F' - 'A'))); + proc->set_extension_enable(EXT_ZVFH, (new_misa & (1L << ('V' - 'A'))) && proc->extension_enabled(EXT_ZFHMIN)); + proc->set_extension_enable(EXT_ZVFHMIN, new_misa & (1L << ('V' - 'A'))); + // update the hypervisor-only bits in MEDELEG and other CSRs if (!new_h && prev_h) { reg_t hypervisor_exceptions = 0 @@ -533,27 +672,29 @@ bool misa_csr_t::unlogged_write(const reg_t val) noexcept { | (1 << CAUSE_VIRTUAL_INSTRUCTION) | (1 << CAUSE_STORE_GUEST_PAGE_FAULT) ; + state->medeleg->write(state->medeleg->read() & ~hypervisor_exceptions); - state->mstatus->write(state->mstatus->read() & ~(MSTATUS_GVA | MSTATUS_MPV)); + if (state->mnstatus) state->mnstatus->write(state->mnstatus->read() & ~MNSTATUS_MNPV); + const reg_t new_mstatus = state->mstatus->read() & ~(MSTATUS_GVA | MSTATUS_MPV); + state->mstatus->write(new_mstatus); + if (state->mstatush) state->mstatush->write(new_mstatus >> 32); // log mstatush change state->mie->write_with_mask(MIP_HS_MASK, 0); // also takes care of hie, sie state->mip->write_with_mask(MIP_HS_MASK, 0); // also takes care of hip, sip, hvip state->hstatus->write(0); + for (reg_t i = 3; i < N_HPMCOUNTERS + 3; ++i) { + const reg_t new_mevent = state->mevent[i - 3]->read() & ~(MHPMEVENT_VUINH | MHPMEVENT_VSINH); + state->mevent[i - 3]->write(new_mevent); + } } return basic_csr_t::unlogged_write(new_misa); } -bool misa_csr_t::extension_enabled(unsigned char ext) const noexcept { - assert(ext >= 'A' && ext <= 'Z'); - return (read() >> (ext - 'A')) & 1; -} - bool misa_csr_t::extension_enabled_const(unsigned char ext) const noexcept { assert(!(1 & (write_mask >> (ext - 'A')))); return extension_enabled(ext); } - // implement class mip_or_mie_csr_t mip_or_mie_csr_t::mip_or_mie_csr_t(processor_t* const proc, const reg_t addr): csr_t(proc, addr), @@ -574,7 +715,6 @@ bool mip_or_mie_csr_t::unlogged_write(const reg_t val) noexcept { return false; // avoid double logging: already logged by write_with_mask() } - mip_csr_t::mip_csr_t(processor_t* const proc, const reg_t addr): mip_or_mie_csr_t(proc, addr) { } @@ -584,7 +724,9 @@ void mip_csr_t::backdoor_write_with_mask(const reg_t mask, const reg_t val) noex } reg_t mip_csr_t::write_mask() const noexcept { - const reg_t supervisor_ints = proc->extension_enabled('S') ? MIP_SSIP | MIP_STIP | MIP_SEIP : 0; + // MIP_STIP is writable unless SSTC exists and STCE is set in MENVCFG + const reg_t supervisor_ints = proc->extension_enabled('S') ? MIP_SSIP | ((state->menvcfg->read() & MENVCFG_STCE) ? 0 : MIP_STIP) | MIP_SEIP : 0; + const reg_t lscof_int = proc->extension_enabled(EXT_SSCOFPMF) ? MIP_LCOFIP : 0; const reg_t vssip_int = proc->extension_enabled('H') ? MIP_VSSIP : 0; const reg_t hypervisor_ints = proc->extension_enabled('H') ? MIP_HS_MASK : 0; // We must mask off sgeip, vstip, and vseip. All three of these @@ -592,26 +734,24 @@ reg_t mip_csr_t::write_mask() const noexcept { // * sgeip is read-only -- write hgeip instead // * vseip is read-only -- write hvip instead // * vstip is read-only -- write hvip instead - return (supervisor_ints | hypervisor_ints) & - (MIP_SEIP | MIP_SSIP | MIP_STIP | vssip_int); + return (supervisor_ints | hypervisor_ints | lscof_int) & + (MIP_SEIP | MIP_SSIP | MIP_STIP | MIP_LCOFIP | vssip_int); } - mie_csr_t::mie_csr_t(processor_t* const proc, const reg_t addr): mip_or_mie_csr_t(proc, addr) { } - reg_t mie_csr_t::write_mask() const noexcept { const reg_t supervisor_ints = proc->extension_enabled('S') ? MIP_SSIP | MIP_STIP | MIP_SEIP : 0; + const reg_t lscof_int = proc->extension_enabled(EXT_SSCOFPMF) ? MIP_LCOFIP : 0; const reg_t hypervisor_ints = proc->extension_enabled('H') ? MIP_HS_MASK : 0; const reg_t coprocessor_ints = (reg_t)proc->any_custom_extensions() << IRQ_COP; - const reg_t delegable_ints = supervisor_ints | coprocessor_ints; + const reg_t delegable_ints = supervisor_ints | coprocessor_ints | lscof_int; const reg_t all_ints = delegable_ints | hypervisor_ints | MIP_MSIP | MIP_MTIP | MIP_MEIP; return all_ints; } - // implement class generic_int_accessor_t generic_int_accessor_t::generic_int_accessor_t(state_t* const state, const reg_t read_mask, @@ -652,7 +792,6 @@ reg_t generic_int_accessor_t::deleg_mask() const { return hideleg_mask & mideleg_mask; } - // implement class mip_proxy_csr_t mip_proxy_csr_t::mip_proxy_csr_t(processor_t* const proc, const reg_t addr, generic_int_accessor_t_p accr): csr_t(proc, addr), @@ -683,7 +822,6 @@ bool mie_proxy_csr_t::unlogged_write(const reg_t val) noexcept { return false; // accr has already logged } - // implement class mideleg_csr_t mideleg_csr_t::mideleg_csr_t(processor_t* const proc, const reg_t addr): basic_csr_t(proc, addr, 0) { @@ -705,13 +843,13 @@ void mideleg_csr_t::verify_permissions(insn_t insn, bool write) const { bool mideleg_csr_t::unlogged_write(const reg_t val) noexcept { const reg_t supervisor_ints = proc->extension_enabled('S') ? MIP_SSIP | MIP_STIP | MIP_SEIP : 0; + const reg_t lscof_int = proc->extension_enabled(EXT_SSCOFPMF) ? MIP_LCOFIP : 0; const reg_t coprocessor_ints = (reg_t)proc->any_custom_extensions() << IRQ_COP; - const reg_t delegable_ints = supervisor_ints | coprocessor_ints; + const reg_t delegable_ints = supervisor_ints | coprocessor_ints | lscof_int; return basic_csr_t::unlogged_write(val & delegable_ints); } - // implement class medeleg_csr_t medeleg_csr_t::medeleg_csr_t(processor_t* const proc, const reg_t addr): basic_csr_t(proc, addr, 0), @@ -733,7 +871,13 @@ void medeleg_csr_t::verify_permissions(insn_t insn, bool write) const { bool medeleg_csr_t::unlogged_write(const reg_t val) noexcept { const reg_t mask = 0 | (1 << CAUSE_MISALIGNED_FETCH) + | (1 << CAUSE_FETCH_ACCESS) + | (1 << CAUSE_ILLEGAL_INSTRUCTION) | (1 << CAUSE_BREAKPOINT) + | (1 << CAUSE_MISALIGNED_LOAD) + | (1 << CAUSE_LOAD_ACCESS) + | (1 << CAUSE_MISALIGNED_STORE) + | (1 << CAUSE_STORE_ACCESS) | (1 << CAUSE_USER_ECALL) | (1 << CAUSE_SUPERVISOR_ECALL) | (1 << CAUSE_FETCH_PAGE_FAULT) @@ -744,7 +888,6 @@ bool medeleg_csr_t::unlogged_write(const reg_t val) noexcept { return basic_csr_t::unlogged_write((read() & ~mask) | (val & mask)); } - // implement class masked_csr_t masked_csr_t::masked_csr_t(processor_t* const proc, const reg_t addr, const reg_t mask, const reg_t init): basic_csr_t(proc, addr, init), @@ -755,13 +898,17 @@ bool masked_csr_t::unlogged_write(const reg_t val) noexcept { return basic_csr_t::unlogged_write((read() & ~mask) | (val & mask)); } +// implement class henvcfg_csr_t +henvcfg_csr_t::henvcfg_csr_t(processor_t* const proc, const reg_t addr, const reg_t mask, const reg_t init, csr_t_p menvcfg): + masked_csr_t(proc, addr, mask, init), + menvcfg(menvcfg) { +} // implement class base_atp_csr_t and family base_atp_csr_t::base_atp_csr_t(processor_t* const proc, const reg_t addr): basic_csr_t(proc, addr, 0) { } - bool base_atp_csr_t::unlogged_write(const reg_t val) noexcept { const reg_t newval = proc->supports_impl(IMPL_MMU) ? compute_new_satp(val) : 0; if (newval != read()) @@ -780,6 +927,7 @@ bool base_atp_csr_t::satp_valid(reg_t val) const noexcept { switch (get_field(val, SATP64_MODE)) { case SATP_MODE_SV39: return proc->supports_impl(IMPL_MMU_SV39); case SATP_MODE_SV48: return proc->supports_impl(IMPL_MMU_SV48); + case SATP_MODE_SV57: return proc->supports_impl(IMPL_MMU_SV57); case SATP_MODE_OFF: return true; default: return false; } @@ -790,8 +938,10 @@ reg_t base_atp_csr_t::compute_new_satp(reg_t val) const noexcept { reg_t rv64_ppn_mask = (reg_t(1) << (MAX_PADDR_BITS - PGSHIFT)) - 1; reg_t mode_mask = proc->get_xlen() == 32 ? SATP32_MODE : SATP64_MODE; + reg_t asid_mask_if_enabled = proc->get_xlen() == 32 ? SATP32_ASID : SATP64_ASID; + reg_t asid_mask = proc->supports_impl(IMPL_MMU_ASID) ? asid_mask_if_enabled : 0; reg_t ppn_mask = proc->get_xlen() == 32 ? SATP32_PPN : SATP64_PPN & rv64_ppn_mask; - reg_t new_mask = (satp_valid(val) ? mode_mask : 0) | ppn_mask; + reg_t new_mask = (satp_valid(val) ? mode_mask : 0) | asid_mask | ppn_mask; reg_t old_mask = satp_valid(val) ? 0 : mode_mask; return (new_mask & val) | (old_mask & read()); @@ -804,7 +954,7 @@ satp_csr_t::satp_csr_t(processor_t* const proc, const reg_t addr): void satp_csr_t::verify_permissions(insn_t insn, bool write) const { base_atp_csr_t::verify_permissions(insn, write); if (get_field(state->mstatus->read(), MSTATUS_TVM)) - require(state->prv >= PRV_M); + require(state->prv == PRV_M); } virtualized_satp_csr_t::virtualized_satp_csr_t(processor_t* const proc, satp_csr_t_p orig, csr_t_p virt): @@ -832,26 +982,22 @@ bool virtualized_satp_csr_t::unlogged_write(const reg_t val) noexcept { return virtualized_csr_t::unlogged_write(newval); } - -// implement class minstret_csr_t -minstret_csr_t::minstret_csr_t(processor_t* const proc, const reg_t addr): +// implement class wide_counter_csr_t +wide_counter_csr_t::wide_counter_csr_t(processor_t* const proc, const reg_t addr): csr_t(proc, addr), val(0) { } -reg_t minstret_csr_t::read() const noexcept { +reg_t wide_counter_csr_t::read() const noexcept { return val; } -void minstret_csr_t::bump(const reg_t howmuch) noexcept { +void wide_counter_csr_t::bump(const reg_t howmuch) noexcept { val += howmuch; // to keep log reasonable size, don't log every bump } -bool minstret_csr_t::unlogged_write(const reg_t val) noexcept { - if (proc->get_xlen() == 32) - this->val = (this->val >> 32 << 32) | (val & 0xffffffffU); - else - this->val = val; +bool wide_counter_csr_t::unlogged_write(const reg_t val) noexcept { + this->val = val; // The ISA mandates that if an instruction writes instret, the write // takes precedence over the increment to instret. However, Spike // unconditionally increments instret after executing an instruction. @@ -860,34 +1006,35 @@ bool minstret_csr_t::unlogged_write(const reg_t val) noexcept { return true; } -reg_t minstret_csr_t::written_value() const noexcept { +reg_t wide_counter_csr_t::written_value() const noexcept { // Re-adjust for upcoming bump() return this->val + 1; } -void minstret_csr_t::write_upper_half(const reg_t val) noexcept { - this->val = (val << 32) | (this->val << 32 >> 32); - this->val--; // See comment above. - // Log upper half only. - log_special_write(address + (CSR_MINSTRETH - CSR_MINSTRET), written_value() >> 32); -} - - -minstreth_csr_t::minstreth_csr_t(processor_t* const proc, const reg_t addr, minstret_csr_t_p minstret): +// implement class time_counter_csr_t +time_counter_csr_t::time_counter_csr_t(processor_t* const proc, const reg_t addr): csr_t(proc, addr), - minstret(minstret) { + shadow_val(0) { } -reg_t minstreth_csr_t::read() const noexcept { - return minstret->read() >> 32; +reg_t time_counter_csr_t::read() const noexcept { + // reading the time CSR in VS or VU mode returns the sum of the contents of + // htimedelta and the actual value of time. + if (state->v) + return shadow_val + state->htimedelta->read(); + else + return shadow_val; } -bool minstreth_csr_t::unlogged_write(const reg_t val) noexcept { - minstret->write_upper_half(val); - return true; +void time_counter_csr_t::sync(const reg_t val) noexcept { + shadow_val = val; + if (proc->extension_enabled(EXT_SSTC)) { + const reg_t mip_val = (shadow_val >= state->stimecmp->read() ? MIP_STIP : 0) | + (shadow_val + state->htimedelta->read() >= state->vstimecmp->read() ? MIP_VSTIP : 0); + state->mip->backdoor_write_with_mask(MIP_STIP | MIP_VSTIP, mip_val); + } } - proxy_csr_t::proxy_csr_t(processor_t* const proc, const reg_t addr, csr_t_p delegate): csr_t(proc, addr), delegate(delegate) { @@ -902,7 +1049,6 @@ bool proxy_csr_t::unlogged_write(const reg_t val) noexcept { return false; } - const_csr_t::const_csr_t(processor_t* const proc, const reg_t addr, reg_t val): csr_t(proc, addr), val(val) { @@ -912,11 +1058,10 @@ reg_t const_csr_t::read() const noexcept { return val; } -bool const_csr_t::unlogged_write(const reg_t val) noexcept { +bool const_csr_t::unlogged_write(const reg_t UNUSED val) noexcept { return false; } - counter_proxy_csr_t::counter_proxy_csr_t(processor_t* const proc, const reg_t addr, csr_t_p delegate): proxy_csr_t(proc, addr, delegate) { } @@ -944,6 +1089,17 @@ void counter_proxy_csr_t::verify_permissions(insn_t insn, bool write) const { } } +mevent_csr_t::mevent_csr_t(processor_t* const proc, const reg_t addr): + basic_csr_t(proc, addr, 0) { +} + +bool mevent_csr_t::unlogged_write(const reg_t val) noexcept { + const reg_t mask = proc->extension_enabled(EXT_SSCOFPMF) ? MHPMEVENT_OF | MHPMEVENT_MINH + | (proc->extension_enabled_const('U') ? MHPMEVENT_UINH : 0) + | (proc->extension_enabled_const('S') ? MHPMEVENT_SINH : 0) + | (proc->extension_enabled('H') ? MHPMEVENT_VUINH | MHPMEVENT_VSINH : 0) : 0; + return basic_csr_t::unlogged_write((read() & ~mask) | (val & mask)); +} hypervisor_csr_t::hypervisor_csr_t(processor_t* const proc, const reg_t addr): basic_csr_t(proc, addr, 0) { @@ -955,7 +1111,6 @@ void hypervisor_csr_t::verify_permissions(insn_t insn, bool write) const { throw trap_illegal_instruction(insn.bits()); } - hideleg_csr_t::hideleg_csr_t(processor_t* const proc, const reg_t addr, csr_t_p mideleg): masked_csr_t(proc, addr, MIP_VS_MASK, 0), mideleg(mideleg) { @@ -965,7 +1120,6 @@ reg_t hideleg_csr_t::read() const noexcept { return masked_csr_t::read() & mideleg->read(); }; - hgatp_csr_t::hgatp_csr_t(processor_t* const proc, const reg_t addr): basic_csr_t(proc, addr, 0) { } @@ -981,103 +1135,74 @@ bool hgatp_csr_t::unlogged_write(const reg_t val) noexcept { reg_t mask; if (proc->get_const_xlen() == 32) { - mask = HGATP32_PPN | HGATP32_MODE; + mask = HGATP32_PPN | + HGATP32_MODE | + (proc->supports_impl(IMPL_MMU_VMID) ? HGATP32_VMID : 0); } else { - mask = HGATP64_PPN & ((reg_t(1) << (MAX_PADDR_BITS - PGSHIFT)) - 1); + mask = (HGATP64_PPN & ((reg_t(1) << (MAX_PADDR_BITS - PGSHIFT)) - 1)) | + (proc->supports_impl(IMPL_MMU_VMID) ? HGATP64_VMID : 0); if (get_field(val, HGATP64_MODE) == HGATP_MODE_OFF || - get_field(val, HGATP64_MODE) == HGATP_MODE_SV39X4 || - get_field(val, HGATP64_MODE) == HGATP_MODE_SV48X4) + (proc->supports_impl(IMPL_MMU_SV39) && get_field(val, HGATP64_MODE) == HGATP_MODE_SV39X4) || + (proc->supports_impl(IMPL_MMU_SV48) && get_field(val, HGATP64_MODE) == HGATP_MODE_SV48X4) || + (proc->supports_impl(IMPL_MMU_SV57) && get_field(val, HGATP64_MODE) == HGATP_MODE_SV57X4)) mask |= HGATP64_MODE; } mask &= ~(reg_t)3; return basic_csr_t::unlogged_write((read() & ~mask) | (val & mask)); } - tselect_csr_t::tselect_csr_t(processor_t* const proc, const reg_t addr): basic_csr_t(proc, addr, 0) { } bool tselect_csr_t::unlogged_write(const reg_t val) noexcept { - return basic_csr_t::unlogged_write((val < state->num_triggers) ? val : read()); + return basic_csr_t::unlogged_write((val < proc->TM.count()) ? val : read()); } - tdata1_csr_t::tdata1_csr_t(processor_t* const proc, const reg_t addr): csr_t(proc, addr) { } reg_t tdata1_csr_t::read() const noexcept { - reg_t v = 0; - auto xlen = proc->get_xlen(); - mcontrol_t *mc = &state->mcontrol[state->tselect->read()]; - v = set_field(v, MCONTROL_TYPE(xlen), mc->type); - v = set_field(v, MCONTROL_DMODE(xlen), mc->dmode); - v = set_field(v, MCONTROL_MASKMAX(xlen), mc->maskmax); - v = set_field(v, MCONTROL_SELECT, mc->select); - v = set_field(v, MCONTROL_TIMING, mc->timing); - v = set_field(v, MCONTROL_ACTION, mc->action); - v = set_field(v, MCONTROL_CHAIN, mc->chain); - v = set_field(v, MCONTROL_MATCH, mc->match); - v = set_field(v, MCONTROL_M, mc->m); - v = set_field(v, MCONTROL_H, mc->h); - v = set_field(v, MCONTROL_S, mc->s); - v = set_field(v, MCONTROL_U, mc->u); - v = set_field(v, MCONTROL_EXECUTE, mc->execute); - v = set_field(v, MCONTROL_STORE, mc->store); - v = set_field(v, MCONTROL_LOAD, mc->load); - return v; + return proc->TM.tdata1_read(state->tselect->read()); } bool tdata1_csr_t::unlogged_write(const reg_t val) noexcept { - mcontrol_t *mc = &state->mcontrol[state->tselect->read()]; - if (mc->dmode && !state->debug_mode) { - return false; - } - auto xlen = proc->get_xlen(); - mc->dmode = get_field(val, MCONTROL_DMODE(xlen)); - mc->select = get_field(val, MCONTROL_SELECT); - mc->timing = get_field(val, MCONTROL_TIMING); - mc->action = (mcontrol_action_t) get_field(val, MCONTROL_ACTION); - mc->chain = get_field(val, MCONTROL_CHAIN); - mc->match = (mcontrol_match_t) get_field(val, MCONTROL_MATCH); - mc->m = get_field(val, MCONTROL_M); - mc->h = get_field(val, MCONTROL_H); - mc->s = get_field(val, MCONTROL_S); - mc->u = get_field(val, MCONTROL_U); - mc->execute = get_field(val, MCONTROL_EXECUTE); - mc->store = get_field(val, MCONTROL_STORE); - mc->load = get_field(val, MCONTROL_LOAD); - // Assume we're here because of csrw. - if (mc->execute) - mc->timing = 0; - proc->trigger_updated(); - return true; + return proc->TM.tdata1_write(state->tselect->read(), val); } - -tdata2_csr_t::tdata2_csr_t(processor_t* const proc, const reg_t addr, const size_t count): - csr_t(proc, addr), - vals(count, 0) { +tdata2_csr_t::tdata2_csr_t(processor_t* const proc, const reg_t addr): + csr_t(proc, addr) { } reg_t tdata2_csr_t::read() const noexcept { - return read(state->tselect->read()); -} - -reg_t tdata2_csr_t::read(const size_t idx) const noexcept { - return vals[idx]; + return proc->TM.tdata2_read(state->tselect->read()); } bool tdata2_csr_t::unlogged_write(const reg_t val) noexcept { - if (state->mcontrol[state->tselect->read()].dmode && !state->debug_mode) { - return false; - } - vals[state->tselect->read()] = val; - return true; + return proc->TM.tdata2_write(state->tselect->read(), val); } +tdata3_csr_t::tdata3_csr_t(processor_t* const proc, const reg_t addr): + csr_t(proc, addr) { +} + +reg_t tdata3_csr_t::read() const noexcept { + return proc->TM.tdata3_read(state->tselect->read()); +} + +bool tdata3_csr_t::unlogged_write(const reg_t val) noexcept { + return proc->TM.tdata3_write(state->tselect->read(), val); +} + +tinfo_csr_t::tinfo_csr_t(processor_t* const proc, const reg_t addr) : + csr_t(proc, addr) { +} + +reg_t tinfo_csr_t::read() const noexcept { + return proc->TM.tinfo_read(state->tselect->read()); +} debug_mode_csr_t::debug_mode_csr_t(processor_t* const proc, const reg_t addr): basic_csr_t(proc, addr, 0) { @@ -1099,7 +1224,6 @@ void dpc_csr_t::verify_permissions(insn_t insn, bool write) const { throw trap_illegal_instruction(insn.bits()); } - dcsr_csr_t::dcsr_csr_t(processor_t* const proc, const reg_t addr): csr_t(proc, addr), prv(0), @@ -1151,16 +1275,30 @@ void dcsr_csr_t::write_cause_and_prv(uint8_t cause, reg_t prv) noexcept { log_write(); } - float_csr_t::float_csr_t(processor_t* const proc, const reg_t addr, const reg_t mask, const reg_t init): masked_csr_t(proc, addr, mask, init) { } void float_csr_t::verify_permissions(insn_t insn, bool write) const { masked_csr_t::verify_permissions(insn, write); - require_fp; - if (!proc->extension_enabled('F')) + require_fs; + if (!proc->extension_enabled('F') && !proc->extension_enabled(EXT_ZFINX)) throw trap_illegal_instruction(insn.bits()); + + if (proc->extension_enabled(EXT_SMSTATEEN) && proc->extension_enabled(EXT_ZFINX)) { + if ((state->prv < PRV_M) && !(state->mstateen[0]->read() & MSTATEEN0_FCSR)) + throw trap_illegal_instruction(insn.bits()); + + if (state->v && !(state->hstateen[0]->read() & HSTATEEN0_FCSR)) + throw trap_virtual_instruction(insn.bits()); + + if ((proc->extension_enabled('S') && state->prv < PRV_S) && !(state->sstateen[0]->read() & SSTATEEN0_FCSR)) { + if (state->v) + throw trap_virtual_instruction(insn.bits()); + else + throw trap_illegal_instruction(insn.bits()); + } + } } bool float_csr_t::unlogged_write(const reg_t val) noexcept { @@ -1168,7 +1306,6 @@ bool float_csr_t::unlogged_write(const reg_t val) noexcept { return masked_csr_t::unlogged_write(val); } - composite_csr_t::composite_csr_t(processor_t* const proc, const reg_t addr, csr_t_p upper_csr, csr_t_p lower_csr, const unsigned upper_lsb): csr_t(proc, addr), upper_csr(upper_csr), @@ -1192,7 +1329,6 @@ bool composite_csr_t::unlogged_write(const reg_t val) noexcept { return false; // logging is done only by the underlying CSRs } - seed_csr_t::seed_csr_t(processor_t* const proc, const reg_t addr): csr_t(proc, addr) { } @@ -1214,8 +1350,6 @@ bool seed_csr_t::unlogged_write(const reg_t val) noexcept { return true; } - - vector_csr_t::vector_csr_t(processor_t* const proc, const reg_t addr, const reg_t mask, const reg_t init): basic_csr_t(proc, addr, init), mask(mask) { @@ -1240,7 +1374,6 @@ bool vector_csr_t::unlogged_write(const reg_t val) noexcept { return basic_csr_t::unlogged_write(val & mask); } - vxsat_csr_t::vxsat_csr_t(processor_t* const proc, const reg_t addr): masked_csr_t(proc, addr, /*mask*/ 1, /*init*/ 0) { } @@ -1256,3 +1389,178 @@ bool vxsat_csr_t::unlogged_write(const reg_t val) noexcept { dirty_vs_state; return masked_csr_t::unlogged_write(val); } + +// implement class hstateen_csr_t +hstateen_csr_t::hstateen_csr_t(processor_t* const proc, const reg_t addr, const reg_t mask, + const reg_t init, uint8_t index): + masked_csr_t(proc, addr, mask, init), + index(index) { +} + +reg_t hstateen_csr_t::read() const noexcept { + // For every bit in an mstateen CSR that is zero (whether read-only zero or set to zero), + // the same bit appears as read-only zero in the matching hstateen and sstateen CSRs + return masked_csr_t::read() & state->mstateen[index]->read(); +} + +bool hstateen_csr_t::unlogged_write(const reg_t val) noexcept { + // For every bit in an mstateen CSR that is zero (whether read-only zero or set to zero), + // the same bit appears as read-only zero in the matching hstateen and sstateen CSRs + return masked_csr_t::unlogged_write(val & state->mstateen[index]->read()); +} + +void hstateen_csr_t::verify_permissions(insn_t insn, bool write) const { + if ((state->prv < PRV_M) && !(state->mstateen[index]->read() & MSTATEEN_HSTATEEN)) + throw trap_illegal_instruction(insn.bits()); + masked_csr_t::verify_permissions(insn, write); +} + +// implement class sstateen_csr_t +sstateen_csr_t::sstateen_csr_t(processor_t* const proc, const reg_t addr, const reg_t mask, + const reg_t init, uint8_t index): + hstateen_csr_t(proc, addr, mask, init, index) { +} + +reg_t sstateen_csr_t::read() const noexcept { + // For every bit in an mstateen CSR that is zero (whether read-only zero or set to zero), + // the same bit appears as read-only zero in the matching hstateen and sstateen CSRs + // For every bit in an hstateen CSR that is zero (whether read-only zero or set to zero), + // the same bit appears as read-only zero in sstateen when accessed in VS-mode + if (state->v) + return hstateen_csr_t::read() & state->hstateen[index]->read(); + else + return hstateen_csr_t::read(); +} + +bool sstateen_csr_t::unlogged_write(const reg_t val) noexcept { + // For every bit in an mstateen CSR that is zero (whether read-only zero or set to zero), + // the same bit appears as read-only zero in the matching hstateen and sstateen CSRs + // For every bit in an hstateen CSR that is zero (whether read-only zero or set to zero), + // the same bit appears as read-only zero in sstateen when accessed in VS-mode + if (state->v) + return hstateen_csr_t::unlogged_write(val & state->hstateen[index]->read()); + else + return hstateen_csr_t::unlogged_write(val); +} + +void sstateen_csr_t::verify_permissions(insn_t insn, bool write) const { + hstateen_csr_t::verify_permissions(insn, write); + + if (state->v && !(state->hstateen[index]->read() & HSTATEEN_SSTATEEN)) + throw trap_virtual_instruction(insn.bits()); +} + +// implement class senvcfg_csr_t +senvcfg_csr_t::senvcfg_csr_t(processor_t* const proc, const reg_t addr, const reg_t mask, + const reg_t init): + masked_csr_t(proc, addr, mask, init) { +} + +void senvcfg_csr_t::verify_permissions(insn_t insn, bool write) const { + if (proc->extension_enabled(EXT_SMSTATEEN)) { + if ((state->prv < PRV_M) && !(state->mstateen[0]->read() & MSTATEEN0_HENVCFG)) + throw trap_illegal_instruction(insn.bits()); + + if (state->v && !(state->hstateen[0]->read() & HSTATEEN0_SENVCFG)) + throw trap_virtual_instruction(insn.bits()); + } + + masked_csr_t::verify_permissions(insn, write); +} + +void henvcfg_csr_t::verify_permissions(insn_t insn, bool write) const { + if (proc->extension_enabled(EXT_SMSTATEEN)) { + if ((state->prv < PRV_M) && !(state->mstateen[0]->read() & MSTATEEN0_HENVCFG)) + throw trap_illegal_instruction(insn.bits()); + } + + masked_csr_t::verify_permissions(insn, write); +} + +stimecmp_csr_t::stimecmp_csr_t(processor_t* const proc, const reg_t addr, const reg_t imask): + basic_csr_t(proc, addr, 0), intr_mask(imask) { +} + +bool stimecmp_csr_t::unlogged_write(const reg_t val) noexcept { + state->mip->backdoor_write_with_mask(intr_mask, state->time->read() >= val ? intr_mask : 0); + return basic_csr_t::unlogged_write(val); +} + +virtualized_stimecmp_csr_t::virtualized_stimecmp_csr_t(processor_t* const proc, csr_t_p orig, csr_t_p virt): + virtualized_csr_t(proc, orig, virt) { +} + +void virtualized_stimecmp_csr_t::verify_permissions(insn_t insn, bool write) const { + if (!(state->menvcfg->read() & MENVCFG_STCE)) { + // access to (v)stimecmp with MENVCFG.STCE = 0 + if (state->prv < PRV_M) + throw trap_illegal_instruction(insn.bits()); + } + + state->time_proxy->verify_permissions(insn, false); + + if (state->v && !(state->henvcfg->read() & HENVCFG_STCE)) { + // access to vstimecmp with MENVCFG.STCE = 1 and HENVCFG.STCE = 0 when V = 1 + throw trap_virtual_instruction(insn.bits()); + } + + virtualized_csr_t::verify_permissions(insn, write); +} + +scountovf_csr_t::scountovf_csr_t(processor_t* const proc, const reg_t addr): + csr_t(proc, addr) { +} + +void scountovf_csr_t::verify_permissions(insn_t insn, bool write) const { + if (!proc->extension_enabled(EXT_SSCOFPMF)) + throw trap_illegal_instruction(insn.bits()); + csr_t::verify_permissions(insn, write); +} + +reg_t scountovf_csr_t::read() const noexcept { + reg_t val = 0; + for (reg_t i = 3; i < N_HPMCOUNTERS + 3; ++i) { + bool of = state->mevent[i - 3]->read() & MHPMEVENT_OF; + val |= of << i; + } + + /* In M and S modes, scountovf bit X is readable when mcounteren bit X is set, */ + /* and otherwise reads as zero. Similarly, in VS mode, scountovf bit X is readable */ + /* when mcounteren bit X and hcounteren bit X are both set, and otherwise reads as zero. */ + val &= state->mcounteren->read(); + if (state->v) + val &= state->hcounteren->read(); + return val; +} + +bool scountovf_csr_t::unlogged_write(const reg_t UNUSED val) noexcept { + /* this function is unused */ + return false; +} + +// implement class jvt_csr_t +jvt_csr_t::jvt_csr_t(processor_t* const proc, const reg_t addr, const reg_t init): + basic_csr_t(proc, addr, init) { +} + +void jvt_csr_t::verify_permissions(insn_t insn, bool write) const { + basic_csr_t::verify_permissions(insn, write); + + if (!proc->extension_enabled(EXT_ZCMT)) + throw trap_illegal_instruction(insn.bits()); + + if (proc->extension_enabled(EXT_SMSTATEEN)) { + if ((state->prv < PRV_M) && !(state->mstateen[0]->read() & SSTATEEN0_JVT)) + throw trap_illegal_instruction(insn.bits()); + + if (state->v && !(state->hstateen[0]->read() & SSTATEEN0_JVT)) + throw trap_virtual_instruction(insn.bits()); + + if ((proc->extension_enabled('S') && state->prv < PRV_S) && !(state->sstateen[0]->read() & SSTATEEN0_JVT)) { + if (state->v) + throw trap_virtual_instruction(insn.bits()); + else + throw trap_illegal_instruction(insn.bits()); + } + } +} diff --git a/vendor/riscv/riscv-isa-sim/riscv/csrs.h b/vendor/riscv/riscv-isa-sim/riscv/csrs.h index 245edf5ba..65be79932 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/csrs.h +++ b/vendor/riscv/riscv-isa-sim/riscv/csrs.h @@ -2,12 +2,15 @@ #ifndef _RISCV_CSRS_H #define _RISCV_CSRS_H +#include "common.h" +#include "encoding.h" // For reg_t: #include "decode.h" // For std::shared_ptr #include // For access_type: #include "memtracer.h" +#include class processor_t; struct state_t; @@ -52,23 +55,29 @@ class csr_t { private: const unsigned csr_priv; const bool csr_read_only; + + // For access to written_value() and unlogged_write(): + friend class rv32_high_csr_t; + friend class rv32_low_csr_t; }; typedef std::shared_ptr csr_t_p; - // Basic CSRs, with XLEN bits fully readable and writable. class basic_csr_t: public csr_t { public: basic_csr_t(processor_t* const proc, const reg_t addr, const reg_t init); - virtual reg_t read() const noexcept override; + + virtual reg_t read() const noexcept override { + return val; + } + protected: virtual bool unlogged_write(const reg_t val) noexcept override; private: reg_t val; }; - class pmpaddr_csr_t: public csr_t { public: pmpaddr_csr_t(processor_t* const proc, const reg_t addr); @@ -84,6 +93,11 @@ class pmpaddr_csr_t: public csr_t { // Is the specified access allowed given the pmpcfg privileges? bool access_ok(access_type type, reg_t mode) const noexcept; + // To check lock bit status from outside like mseccfg + bool is_locked() const noexcept { + return cfg & PMP_L; + } + protected: virtual bool unlogged_write(const reg_t val) noexcept override; private: @@ -112,11 +126,24 @@ typedef std::shared_ptr pmpaddr_csr_t_p; class pmpcfg_csr_t: public csr_t { public: pmpcfg_csr_t(processor_t* const proc, const reg_t addr); + virtual void verify_permissions(insn_t insn, bool write) const override; virtual reg_t read() const noexcept override; protected: virtual bool unlogged_write(const reg_t val) noexcept override; }; +class mseccfg_csr_t: public basic_csr_t { + public: + mseccfg_csr_t(processor_t* const proc, const reg_t addr); + virtual void verify_permissions(insn_t insn, bool write) const override; + bool get_mml() const noexcept; + bool get_mmwp() const noexcept; + bool get_rlb() const noexcept; + protected: + virtual bool unlogged_write(const reg_t val) noexcept override; +}; + +typedef std::shared_ptr mseccfg_csr_t_p; // For CSRs that have a virtualized copy under another name. Each // instance of virtualized_csr_t will read/write one of two CSRs, @@ -153,7 +180,6 @@ class epc_csr_t: public csr_t { reg_t val; }; - // For mtvec, stvec, and vstvec class tvec_csr_t: public csr_t { public: @@ -166,7 +192,6 @@ class tvec_csr_t: public csr_t { reg_t val; }; - // For mcause, scause, and vscause class cause_csr_t: public basic_csr_t { public: @@ -175,13 +200,15 @@ class cause_csr_t: public basic_csr_t { virtual reg_t read() const noexcept override; }; - // For *status family of CSRs class base_status_csr_t: public csr_t { public: base_status_csr_t(processor_t* const proc, const reg_t addr); - // Return true if the specified bits are not 00 (Off) - bool enabled(const reg_t which); + + bool field_exists(const reg_t which) { + return (sstatus_write_mask & which) != 0; + } + protected: reg_t adjust_sd(const reg_t val) const noexcept; void maybe_flush_tlb(const reg_t newval) noexcept; @@ -194,13 +221,16 @@ class base_status_csr_t: public csr_t { typedef std::shared_ptr base_status_csr_t_p; - // For vsstatus, which is its own separate architectural register // (unlike sstatus) -class vsstatus_csr_t: public base_status_csr_t { +class vsstatus_csr_t final: public base_status_csr_t { public: vsstatus_csr_t(processor_t* const proc, const reg_t addr); - virtual reg_t read() const noexcept override; + + reg_t read() const noexcept override { + return val; + } + protected: virtual bool unlogged_write(const reg_t val) noexcept override; private: @@ -209,75 +239,107 @@ class vsstatus_csr_t: public base_status_csr_t { typedef std::shared_ptr vsstatus_csr_t_p; - -class sstatus_proxy_csr_t: public base_status_csr_t { - public: - sstatus_proxy_csr_t(processor_t* const proc, const reg_t addr, csr_t_p mstatus); - virtual reg_t read() const noexcept override; - protected: - virtual bool unlogged_write(const reg_t val) noexcept override; - private: - csr_t_p mstatus; -}; - - -class mstatus_csr_t: public base_status_csr_t { +class mstatus_csr_t final: public base_status_csr_t { public: mstatus_csr_t(processor_t* const proc, const reg_t addr); - virtual reg_t read() const noexcept override; + + reg_t read() const noexcept override { + return val; + } + protected: virtual bool unlogged_write(const reg_t val) noexcept override; private: + reg_t compute_mstatus_initial_value() const noexcept; reg_t val; - friend class mstatush_csr_t; }; typedef std::shared_ptr mstatus_csr_t_p; - -class mstatush_csr_t: public csr_t { +class mnstatus_csr_t final: public basic_csr_t { public: - mstatush_csr_t(processor_t* const proc, const reg_t addr, mstatus_csr_t_p mstatus); + mnstatus_csr_t(processor_t* const proc, const reg_t addr); + protected: + virtual bool unlogged_write(const reg_t val) noexcept override; +}; + +// For RV32 CSRs that are split into two, e.g. mstatus/mstatush +// CSRW should only modify the lower half +class rv32_low_csr_t: public csr_t { + public: + rv32_low_csr_t(processor_t* const proc, const reg_t addr, csr_t_p orig); virtual reg_t read() const noexcept override; + virtual void verify_permissions(insn_t insn, bool write) const override; + protected: + virtual bool unlogged_write(const reg_t val) noexcept override; + virtual reg_t written_value() const noexcept override; + private: + csr_t_p orig; +}; + +class rv32_high_csr_t: public csr_t { + public: + rv32_high_csr_t(processor_t* const proc, const reg_t addr, csr_t_p orig); + virtual reg_t read() const noexcept override; + virtual void verify_permissions(insn_t insn, bool write) const override; + protected: + virtual bool unlogged_write(const reg_t val) noexcept override; + virtual reg_t written_value() const noexcept override; + private: + csr_t_p orig; +}; + +class sstatus_proxy_csr_t final: public base_status_csr_t { + public: + sstatus_proxy_csr_t(processor_t* const proc, const reg_t addr, mstatus_csr_t_p mstatus); + + reg_t read() const noexcept override { + return mstatus->read() & sstatus_read_mask; + } + protected: virtual bool unlogged_write(const reg_t val) noexcept override; private: mstatus_csr_t_p mstatus; - const reg_t mask; }; +typedef std::shared_ptr sstatus_proxy_csr_t_p; class sstatus_csr_t: public virtualized_csr_t { public: - sstatus_csr_t(processor_t* const proc, base_status_csr_t_p orig, base_status_csr_t_p virt); + sstatus_csr_t(processor_t* const proc, sstatus_proxy_csr_t_p orig, vsstatus_csr_t_p virt); // Set FS, VS, or XS bits to dirty void dirty(const reg_t dirties); // Return true if the specified bits are not 00 (Off) bool enabled(const reg_t which); private: - base_status_csr_t_p orig_sstatus; - base_status_csr_t_p virt_sstatus; + sstatus_proxy_csr_t_p orig_sstatus; + vsstatus_csr_t_p virt_sstatus; }; typedef std::shared_ptr sstatus_csr_t_p; - -class misa_csr_t: public basic_csr_t { +class misa_csr_t final: public basic_csr_t { public: misa_csr_t(processor_t* const proc, const reg_t addr, const reg_t max_isa); - bool extension_enabled(unsigned char ext) const noexcept; + + bool extension_enabled(unsigned char ext) const noexcept { + assert(ext >= 'A' && ext <= 'Z'); + return (read() >> (ext - 'A')) & 1; + } + bool extension_enabled_const(unsigned char ext) const noexcept; protected: virtual bool unlogged_write(const reg_t val) noexcept override; private: const reg_t max_isa; const reg_t write_mask; + reg_t dependency(const reg_t val, const char feature, const char depends_on) const noexcept; }; typedef std::shared_ptr misa_csr_t_p; - class mip_or_mie_csr_t: public csr_t { public: mip_or_mie_csr_t(processor_t* const proc, const reg_t addr); @@ -292,7 +354,6 @@ class mip_or_mie_csr_t: public csr_t { virtual reg_t write_mask() const noexcept = 0; }; - // mip is special because some of the bits are driven by hardware pins class mip_csr_t: public mip_or_mie_csr_t { public: @@ -306,7 +367,6 @@ class mip_csr_t: public mip_or_mie_csr_t { typedef std::shared_ptr mip_csr_t_p; - class mie_csr_t: public mip_or_mie_csr_t { public: mie_csr_t(processor_t* const proc, const reg_t addr); @@ -316,7 +376,6 @@ class mie_csr_t: public mip_or_mie_csr_t { typedef std::shared_ptr mie_csr_t_p; - // For sip, hip, hvip, vsip, sie, hie, vsie which are all just (masked // & shifted) views into mip or mie. Each pair will have one of these // objects describing the view, e.g. one for sip+sie, one for hip+hie, @@ -348,7 +407,6 @@ class generic_int_accessor_t { typedef std::shared_ptr generic_int_accessor_t_p; - // For all CSRs that are simply (masked & shifted) views into mip class mip_proxy_csr_t: public csr_t { public: @@ -371,8 +429,6 @@ class mie_proxy_csr_t: public csr_t { generic_int_accessor_t_p accr; }; - - class mideleg_csr_t: public basic_csr_t { public: mideleg_csr_t(processor_t* const proc, const reg_t addr); @@ -382,7 +438,6 @@ class mideleg_csr_t: public basic_csr_t { virtual bool unlogged_write(const reg_t val) noexcept override; }; - class medeleg_csr_t: public basic_csr_t { public: medeleg_csr_t(processor_t* const proc, const reg_t addr); @@ -393,7 +448,6 @@ class medeleg_csr_t: public basic_csr_t { const reg_t hypervisor_exceptions; }; - // For CSRs with certain bits hardwired class masked_csr_t: public basic_csr_t { public: @@ -404,6 +458,22 @@ class masked_csr_t: public basic_csr_t { const reg_t mask; }; +// henvcfg.pbmte is read_only 0 when menvcfg.pbmte = 0 +// henvcfg.stce is read_only 0 when menvcfg.stce = 0 +// henvcfg.hade is read_only 0 when menvcfg.hade = 0 +class henvcfg_csr_t final: public masked_csr_t { + public: + henvcfg_csr_t(processor_t* const proc, const reg_t addr, const reg_t mask, const reg_t init, csr_t_p menvcfg); + + reg_t read() const noexcept override { + return (menvcfg->read() | ~(MENVCFG_PBMTE | MENVCFG_STCE | MENVCFG_HADE)) & masked_csr_t::read(); + } + + virtual void verify_permissions(insn_t insn, bool write) const override; + + private: + csr_t_p menvcfg; +}; // For satp and vsatp // These are three classes in order to handle the [V]TVM bits permission checks @@ -435,17 +505,15 @@ class virtualized_satp_csr_t: public virtualized_csr_t { satp_csr_t_p orig_satp; }; - -// For minstret, which is always 64 bits, but in RV32 is split into -// high and low halves. The first class always holds the full 64-bit -// value. -class minstret_csr_t: public csr_t { +// For minstret and mcycle, which are always 64 bits, but in RV32 are +// split into high and low halves. The first class always holds the +// full 64-bit value. +class wide_counter_csr_t: public csr_t { public: - minstret_csr_t(processor_t* const proc, const reg_t addr); + wide_counter_csr_t(processor_t* const proc, const reg_t addr); // Always returns full 64-bit value virtual reg_t read() const noexcept override; void bump(const reg_t howmuch) noexcept; - void write_upper_half(const reg_t val) noexcept; protected: virtual bool unlogged_write(const reg_t val) noexcept override; virtual reg_t written_value() const noexcept override; @@ -453,22 +521,22 @@ class minstret_csr_t: public csr_t { reg_t val; }; -typedef std::shared_ptr minstret_csr_t_p; +typedef std::shared_ptr wide_counter_csr_t_p; - -// A simple proxy to read/write the upper half of minstret -class minstreth_csr_t: public csr_t { +class time_counter_csr_t: public csr_t { public: - minstreth_csr_t(processor_t* const proc, const reg_t addr, minstret_csr_t_p minstret); + time_counter_csr_t(processor_t* const proc, const reg_t addr); virtual reg_t read() const noexcept override; + + void sync(const reg_t val) noexcept; + protected: - virtual bool unlogged_write(const reg_t val) noexcept override; + virtual bool unlogged_write(const reg_t UNUSED val) noexcept override { return false; }; private: - minstret_csr_t_p minstret; + reg_t shadow_val; }; -typedef std::shared_ptr minstreth_csr_t_p; - +typedef std::shared_ptr time_counter_csr_t_p; // For a CSR that is an alias of another class proxy_csr_t: public csr_t { @@ -481,7 +549,6 @@ class proxy_csr_t: public csr_t { csr_t_p delegate; }; - // For a CSR with a fixed, unchanging value class const_csr_t: public csr_t { public: @@ -493,7 +560,6 @@ class const_csr_t: public csr_t { const reg_t val; }; - // For a CSR that is an unprivileged accessor of a privileged counter class counter_proxy_csr_t: public proxy_csr_t { public: @@ -503,6 +569,12 @@ class counter_proxy_csr_t: public proxy_csr_t { bool myenable(csr_t_p counteren) const noexcept; }; +class mevent_csr_t: public basic_csr_t { + public: + mevent_csr_t(processor_t* const proc, const reg_t addr); + protected: + virtual bool unlogged_write(const reg_t val) noexcept override; +}; // For machine-level CSRs that only exist with Hypervisor class hypervisor_csr_t: public basic_csr_t { @@ -511,7 +583,6 @@ class hypervisor_csr_t: public basic_csr_t { virtual void verify_permissions(insn_t insn, bool write) const override; }; - class hideleg_csr_t: public masked_csr_t { public: hideleg_csr_t(processor_t* const proc, const reg_t addr, csr_t_p mideleg); @@ -520,7 +591,6 @@ class hideleg_csr_t: public masked_csr_t { csr_t_p mideleg; }; - class hgatp_csr_t: public basic_csr_t { public: hgatp_csr_t(processor_t* const proc, const reg_t addr); @@ -529,7 +599,6 @@ class hgatp_csr_t: public basic_csr_t { virtual bool unlogged_write(const reg_t val) noexcept override; }; - class tselect_csr_t: public basic_csr_t { public: tselect_csr_t(processor_t* const proc, const reg_t addr); @@ -537,7 +606,6 @@ class tselect_csr_t: public basic_csr_t { virtual bool unlogged_write(const reg_t val) noexcept override; }; - class tdata1_csr_t: public csr_t { public: tdata1_csr_t(processor_t* const proc, const reg_t addr); @@ -548,13 +616,26 @@ class tdata1_csr_t: public csr_t { class tdata2_csr_t: public csr_t { public: - tdata2_csr_t(processor_t* const proc, const reg_t addr, const size_t count); + tdata2_csr_t(processor_t* const proc, const reg_t addr); virtual reg_t read() const noexcept override; - reg_t read(const size_t idx) const noexcept; protected: virtual bool unlogged_write(const reg_t val) noexcept override; - private: - std::vector vals; +}; + +class tdata3_csr_t: public csr_t { + public: + tdata3_csr_t(processor_t* const proc, const reg_t addr); + virtual reg_t read() const noexcept override; + protected: + virtual bool unlogged_write(const reg_t val) noexcept override; +}; + +class tinfo_csr_t: public csr_t { + public: + tinfo_csr_t(processor_t* const proc, const reg_t addr); + virtual reg_t read() const noexcept override; + protected: + virtual bool unlogged_write(const reg_t UNUSED val) noexcept override { return false; }; }; // For CSRs that are only writable from debug mode @@ -564,9 +645,6 @@ class debug_mode_csr_t: public basic_csr_t { virtual void verify_permissions(insn_t insn, bool write) const override; }; -typedef std::shared_ptr tdata2_csr_t_p; - - class dpc_csr_t: public epc_csr_t { public: dpc_csr_t(processor_t* const proc, const reg_t addr); @@ -594,8 +672,7 @@ class dcsr_csr_t: public csr_t { typedef std::shared_ptr dcsr_csr_t_p; - -class float_csr_t: public masked_csr_t { +class float_csr_t final: public masked_csr_t { public: float_csr_t(processor_t* const proc, const reg_t addr, const reg_t mask, const reg_t init); virtual void verify_permissions(insn_t insn, bool write) const override; @@ -603,6 +680,7 @@ class float_csr_t: public masked_csr_t { virtual bool unlogged_write(const reg_t val) noexcept override; }; +typedef std::shared_ptr float_csr_t_p; // For a CSR like FCSR, that is actually a view into multiple // underlying registers. @@ -620,7 +698,6 @@ class composite_csr_t: public csr_t { const unsigned upper_lsb; }; - class seed_csr_t: public csr_t { public: seed_csr_t(processor_t* const proc, const reg_t addr); @@ -630,7 +707,6 @@ class seed_csr_t: public csr_t { virtual bool unlogged_write(const reg_t val) noexcept override; }; - class vector_csr_t: public basic_csr_t { public: vector_csr_t(processor_t* const proc, const reg_t addr, const reg_t mask, const reg_t init=0); @@ -645,7 +721,6 @@ class vector_csr_t: public basic_csr_t { typedef std::shared_ptr vector_csr_t_p; - // For CSRs shared between Vector and P extensions (vxsat) class vxsat_csr_t: public masked_csr_t { public: @@ -655,4 +730,59 @@ class vxsat_csr_t: public masked_csr_t { virtual bool unlogged_write(const reg_t val) noexcept override; }; +class hstateen_csr_t: public masked_csr_t { + public: + hstateen_csr_t(processor_t* const proc, const reg_t addr, const reg_t mask, const reg_t init, uint8_t index); + virtual reg_t read() const noexcept override; + virtual void verify_permissions(insn_t insn, bool write) const override; + protected: + virtual bool unlogged_write(const reg_t val) noexcept override; +protected: + uint8_t index; +}; + +class sstateen_csr_t: public hstateen_csr_t { + public: + sstateen_csr_t(processor_t* const proc, const reg_t addr, const reg_t mask, const reg_t init, uint8_t index); + virtual reg_t read() const noexcept override; + virtual void verify_permissions(insn_t insn, bool write) const override; + protected: + virtual bool unlogged_write(const reg_t val) noexcept override; +}; + +class senvcfg_csr_t final: public masked_csr_t { + public: + senvcfg_csr_t(processor_t* const proc, const reg_t addr, const reg_t mask, const reg_t init); + virtual void verify_permissions(insn_t insn, bool write) const override; +}; + +class stimecmp_csr_t: public basic_csr_t { + public: + stimecmp_csr_t(processor_t* const proc, const reg_t addr, const reg_t imask); + protected: + virtual bool unlogged_write(const reg_t val) noexcept override; + private: + reg_t intr_mask; +}; + +class virtualized_stimecmp_csr_t: public virtualized_csr_t { + public: + virtualized_stimecmp_csr_t(processor_t* const proc, csr_t_p orig, csr_t_p virt); + virtual void verify_permissions(insn_t insn, bool write) const override; +}; + +class scountovf_csr_t: public csr_t { + public: + scountovf_csr_t(processor_t* const proc, const reg_t addr); + virtual void verify_permissions(insn_t insn, bool write) const override; + virtual reg_t read() const noexcept override; + protected: + virtual bool unlogged_write(const reg_t val) noexcept override; +}; + +class jvt_csr_t: public basic_csr_t { + public: + jvt_csr_t(processor_t* const proc, const reg_t addr, const reg_t init); + virtual void verify_permissions(insn_t insn, bool write) const override; +}; #endif diff --git a/vendor/riscv/riscv-isa-sim/riscv/cvxif_base.cc b/vendor/riscv/riscv-isa-sim/riscv/cvxif_base.cc index 5097344c5..c9c045e6d 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/cvxif_base.cc +++ b/vendor/riscv/riscv-isa-sim/riscv/cvxif_base.cc @@ -4,6 +4,8 @@ // // Original Author: Zbigniew CHAMSKI +#define DECODE_MACRO_USAGE_LOGGED 1 +#include "decode_macros.h" #include "cvxif.h" #include "trap.h" #include diff --git a/vendor/riscv/riscv-isa-sim/riscv/debug_defines.h b/vendor/riscv/riscv-isa-sim/riscv/debug_defines.h index e6c2c5d3e..06ba082d9 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/debug_defines.h +++ b/vendor/riscv/riscv-isa-sim/riscv/debug_defines.h @@ -1,1839 +1,3078 @@ +/* + * This file is auto-generated by running 'make debug_defines.h' in + * https://github.com/riscv/riscv-debug-spec/ (0e4d91e) + */ + #define DTM_IDCODE 0x01 /* -* Identifies the release version of this part. + * Identifies the release version of this part. */ -#define DTM_IDCODE_VERSION_OFFSET 28 +#define DTM_IDCODE_VERSION_OFFSET 0x1c #define DTM_IDCODE_VERSION_LENGTH 4 -#define DTM_IDCODE_VERSION (0xfU << DTM_IDCODE_VERSION_OFFSET) +#define DTM_IDCODE_VERSION 0xf0000000U /* -* Identifies the designer's part number of this part. + * Identifies the designer's part number of this part. */ -#define DTM_IDCODE_PARTNUMBER_OFFSET 12 -#define DTM_IDCODE_PARTNUMBER_LENGTH 16 -#define DTM_IDCODE_PARTNUMBER (0xffffU << DTM_IDCODE_PARTNUMBER_OFFSET) +#define DTM_IDCODE_PARTNUMBER_OFFSET 0xc +#define DTM_IDCODE_PARTNUMBER_LENGTH 0x10 +#define DTM_IDCODE_PARTNUMBER 0xffff000 /* -* Identifies the designer/manufacturer of this part. Bits 6:0 must be -* bits 6:0 of the designer/manufacturer's Identification Code as -* assigned by JEDEC Standard JEP106. Bits 10:7 contain the modulo-16 -* count of the number of continuation characters (0x7f) in that same -* Identification Code. + * Identifies the designer/manufacturer of this part. Bits 6:0 must be + * bits 6:0 of the designer/manufacturer's Identification Code as + * assigned by JEDEC Standard JEP106. Bits 10:7 contain the modulo-16 + * count of the number of continuation characters (0x7f) in that same + * Identification Code. */ #define DTM_IDCODE_MANUFID_OFFSET 1 -#define DTM_IDCODE_MANUFID_LENGTH 11 -#define DTM_IDCODE_MANUFID (0x7ffU << DTM_IDCODE_MANUFID_OFFSET) +#define DTM_IDCODE_MANUFID_LENGTH 0xb +#define DTM_IDCODE_MANUFID 0xffe #define DTM_IDCODE_1_OFFSET 0 #define DTM_IDCODE_1_LENGTH 1 -#define DTM_IDCODE_1 (0x1U << DTM_IDCODE_1_OFFSET) +#define DTM_IDCODE_1 1 #define DTM_DTMCS 0x10 /* -* Writing 1 to this bit does a hard reset of the DTM, -* causing the DTM to forget about any outstanding DMI transactions. -* In general this should only be used when the Debugger has -* reason to expect that the outstanding DMI transaction will never -* complete (e.g. a reset condition caused an inflight DMI transaction to -* be cancelled). + * Writing 1 to this bit does a hard reset of the DTM, + * causing the DTM to forget about any outstanding DMI transactions, and + * returning all registers and internal state to their reset value. + * In general this should only be used when the Debugger has + * reason to expect that the outstanding DMI transaction will never + * complete (e.g. a reset condition caused an inflight DMI transaction to + * be cancelled). */ -#define DTM_DTMCS_DMIHARDRESET_OFFSET 17 +#define DTM_DTMCS_DMIHARDRESET_OFFSET 0x11 #define DTM_DTMCS_DMIHARDRESET_LENGTH 1 -#define DTM_DTMCS_DMIHARDRESET (0x1U << DTM_DTMCS_DMIHARDRESET_OFFSET) +#define DTM_DTMCS_DMIHARDRESET 0x20000 /* -* Writing 1 to this bit clears the sticky error state -* and allows the DTM to retry or complete the previous -* transaction. + * Writing 1 to this bit clears the sticky error state, but does + * not affect outstanding DMI transactions. */ -#define DTM_DTMCS_DMIRESET_OFFSET 16 +#define DTM_DTMCS_DMIRESET_OFFSET 0x10 #define DTM_DTMCS_DMIRESET_LENGTH 1 -#define DTM_DTMCS_DMIRESET (0x1U << DTM_DTMCS_DMIRESET_OFFSET) +#define DTM_DTMCS_DMIRESET 0x10000 /* -* This is a hint to the debugger of the minimum number of -* cycles a debugger should spend in -* Run-Test/Idle after every DMI scan to avoid a `busy' -* return code (\Fdmistat of 3). A debugger must still -* check \Fdmistat when necessary. -* -* 0: It is not necessary to enter Run-Test/Idle at all. -* -* 1: Enter Run-Test/Idle and leave it immediately. -* -* 2: Enter Run-Test/Idle and stay there for 1 cycle before leaving. -* -* And so on. + * This is a hint to the debugger of the minimum number of + * cycles a debugger should spend in + * Run-Test/Idle after every DMI scan to avoid a `busy' + * return code (\FdtmDtmcsDmistat of 3). A debugger must still + * check \FdtmDtmcsDmistat when necessary. + * + * 0: It is not necessary to enter Run-Test/Idle at all. + * + * 1: Enter Run-Test/Idle and leave it immediately. + * + * 2: Enter Run-Test/Idle and stay there for 1 cycle before leaving. + * + * And so on. */ -#define DTM_DTMCS_IDLE_OFFSET 12 +#define DTM_DTMCS_IDLE_OFFSET 0xc #define DTM_DTMCS_IDLE_LENGTH 3 -#define DTM_DTMCS_IDLE (0x7U << DTM_DTMCS_IDLE_OFFSET) +#define DTM_DTMCS_IDLE 0x7000 /* -* 0: No error. -* -* 1: Reserved. Interpret the same as 2. -* -* 2: An operation failed (resulted in \Fop of 2). -* -* 3: An operation was attempted while a DMI access was still in -* progress (resulted in \Fop of 3). + * Read-only alias of \FdtmDmiOp. */ -#define DTM_DTMCS_DMISTAT_OFFSET 10 +#define DTM_DTMCS_DMISTAT_OFFSET 0xa #define DTM_DTMCS_DMISTAT_LENGTH 2 -#define DTM_DTMCS_DMISTAT (0x3U << DTM_DTMCS_DMISTAT_OFFSET) +#define DTM_DTMCS_DMISTAT 0xc00 /* -* The size of \Faddress in \Rdmi. + * The size of \FdmSbaddressZeroAddress in \RdtmDmi. */ #define DTM_DTMCS_ABITS_OFFSET 4 #define DTM_DTMCS_ABITS_LENGTH 6 -#define DTM_DTMCS_ABITS (0x3fU << DTM_DTMCS_ABITS_OFFSET) -/* -* 0: Version described in spec version 0.11. -* -* 1: Version described in spec version 0.13. -* -* 15: Version not described in any available version of this spec. - */ +#define DTM_DTMCS_ABITS 0x3f0 #define DTM_DTMCS_VERSION_OFFSET 0 #define DTM_DTMCS_VERSION_LENGTH 4 -#define DTM_DTMCS_VERSION (0xfU << DTM_DTMCS_VERSION_OFFSET) +#define DTM_DTMCS_VERSION 0xf +/* + * 0.11: Version described in spec version 0.11. + */ +#define DTM_DTMCS_VERSION_0_11 0 +/* + * 1.0: Version described in spec versions 0.13 and 1.0. + */ +#define DTM_DTMCS_VERSION_1_0 1 +/* + * custom: Version not described in any available version of this spec. + */ +#define DTM_DTMCS_VERSION_CUSTOM 15 #define DTM_DMI 0x11 /* -* Address used for DMI access. In Update-DR this value is used -* to access the DM over the DMI. + * Address used for DMI access. In Update-DR this value is used + * to access the DM over the DMI. */ -#define DTM_DMI_ADDRESS_OFFSET 34 -#define DTM_DMI_ADDRESS_LENGTH abits -#define DTM_DMI_ADDRESS (((1L< -#include "sim.h" +#include "simif.h" +#include "devices.h" #include "debug_module.h" #include "debug_defines.h" #include "opcodes.h" @@ -31,26 +32,29 @@ static unsigned field_width(unsigned n) ///////////////////////// debug_module_t -debug_module_t::debug_module_t(sim_t *sim, const debug_module_config_t &config) : - nprocs(sim->nprocs()), +debug_module_t::debug_module_t(simif_t *sim, const debug_module_config_t &config) : config(config), program_buffer_bytes((config.support_impebreak ? 4 : 0) + 4*config.progbufsize), debug_progbuf_start(debug_data_start - program_buffer_bytes), debug_abstract_start(debug_progbuf_start - debug_abstract_size*4), custom_base(0), - hartsellen(field_width(sim->nprocs())), sim(sim), // The spec lets a debugger select nonexistent harts. Create hart_state for // them because I'm too lazy to add the code to just ignore accesses. - hart_state(1 << field_width(sim->nprocs())), - hart_array_mask(sim->nprocs()), + hart_state(1 << field_width(sim->get_cfg().max_hartid() + 1)), + hart_array_mask(sim->get_cfg().max_hartid() + 1), rti_remaining(0) { D(fprintf(stderr, "debug_data_start=0x%x\n", debug_data_start)); D(fprintf(stderr, "debug_progbuf_start=0x%x\n", debug_progbuf_start)); D(fprintf(stderr, "debug_abstract_start=0x%x\n", debug_abstract_start)); - assert(nprocs <= 1024); + const unsigned max_procs = 1024; + if (sim->get_cfg().max_hartid() >= max_procs) { + fprintf(stderr, "Hart IDs must not exceed %u (%zu harts with max hart ID %zu requested)\n", + max_procs - 1, sim->get_cfg().nprocs(), sim->get_cfg().max_hartid()); + exit(1); + } program_buffer = new uint8_t[program_buffer_bytes]; @@ -80,11 +84,8 @@ debug_module_t::~debug_module_t() void debug_module_t::reset() { - assert(sim->nprocs() > 0); - for (unsigned i = 0; i < sim->nprocs(); i++) { - processor_t *proc = sim->get_core(i); - if (proc) - proc->halt_request = proc->HR_NONE; + for (const auto& [hart_id, hart] : sim->get_harts()) { + hart->halt_request = hart->HR_NONE; } memset(&dmcontrol, 0, sizeof(dmcontrol)); @@ -165,18 +166,18 @@ bool debug_module_t::load(reg_t addr, size_t len, uint8_t* bytes) bool debug_module_t::store(reg_t addr, size_t len, const uint8_t* bytes) { D( - switch (len) { - case 4: - fprintf(stderr, "store(addr=0x%lx, len=%d, bytes=0x%08x); " - "hartsel=0x%x\n", addr, (unsigned) len, *(uint32_t *) bytes, - dmcontrol.hartsel); - break; - default: - fprintf(stderr, "store(addr=0x%lx, len=%d, bytes=...); " - "hartsel=0x%x\n", addr, (unsigned) len, dmcontrol.hartsel); - break; - } - ); + switch (len) { + case 4: + fprintf(stderr, "store(addr=0x%lx, len=%d, bytes=0x%08x); " + "hartsel=0x%x\n", addr, (unsigned) len, *(uint32_t *) bytes, + dmcontrol.hartsel); + break; + default: + fprintf(stderr, "store(addr=0x%lx, len=%d, bytes=...); " + "hartsel=0x%x\n", addr, (unsigned) len, dmcontrol.hartsel); + break; + } + ); uint8_t id_bytes[4]; uint32_t id = 0; @@ -203,23 +204,20 @@ bool debug_module_t::store(reg_t addr, size_t len, const uint8_t* bytes) if (!hart_state[id].halted) { hart_state[id].halted = true; if (hart_state[id].haltgroup) { - for (unsigned i = 0; i < nprocs; i++) { - if (!hart_state[i].halted && - hart_state[i].haltgroup == hart_state[id].haltgroup) { - processor_t *proc = sim->get_core(i); - proc->halt_request = proc->HR_GROUP; + for (const auto& [hart_id, hart] : sim->get_harts()) { + if (!hart_state[hart_id].halted && + hart_state[hart_id].haltgroup == hart_state[id].haltgroup) { + hart->halt_request = hart->HR_GROUP; // TODO: What if the debugger comes and writes dmcontrol before the // halt occurs? } } } } - if (dmcontrol.hartsel == id) { - if (0 == (debug_rom_flags[id] & (1 << DEBUG_ROM_FLAG_GO))){ - if (dmcontrol.hartsel == id) { - abstract_command_completed = true; - } - } + if (selected_hart_id() == id) { + if (0 == (debug_rom_flags[id] & (1 << DEBUG_ROM_FLAG_GO))) { + abstract_command_completed = true; + } } return true; } @@ -269,23 +267,9 @@ uint32_t debug_module_t::read32(uint8_t *memory, unsigned int index) return value; } -processor_t *debug_module_t::processor(unsigned hartid) const -{ - processor_t *proc = NULL; - try { - proc = sim->get_core(hartid); - } catch (const std::out_of_range&) { - } - return proc; -} - bool debug_module_t::hart_selected(unsigned hartid) const { - if (dmcontrol.hasel) { - return hartid == dmcontrol.hartsel || hart_array_mask[hartid]; - } else { - return hartid == dmcontrol.hartsel; - } + return hartid == selected_hart_id() || (dmcontrol.hasel && hart_array_mask[hartid]); } unsigned debug_module_t::sb_access_bits() @@ -318,13 +302,13 @@ void debug_module_t::sb_read() reg_t address = ((uint64_t) sbaddress[1] << 32) | sbaddress[0]; try { if (sbcs.sbaccess == 0 && config.max_sba_data_width >= 8) { - sbdata[0] = sim->debug_mmu->load_uint8(address); + sbdata[0] = sim->debug_mmu->load(address); } else if (sbcs.sbaccess == 1 && config.max_sba_data_width >= 16) { - sbdata[0] = sim->debug_mmu->load_uint16(address); + sbdata[0] = sim->debug_mmu->load(address); } else if (sbcs.sbaccess == 2 && config.max_sba_data_width >= 32) { - sbdata[0] = sim->debug_mmu->load_uint32(address); + sbdata[0] = sim->debug_mmu->load(address); } else if (sbcs.sbaccess == 3 && config.max_sba_data_width >= 64) { - uint64_t value = sim->debug_mmu->load_uint64(address); + uint64_t value = sim->debug_mmu->load(address); sbdata[0] = value; sbdata[1] = value >> 32; } else { @@ -340,13 +324,13 @@ void debug_module_t::sb_write() reg_t address = ((uint64_t) sbaddress[1] << 32) | sbaddress[0]; D(fprintf(stderr, "sb_write() 0x%x @ 0x%lx\n", sbdata[0], address)); if (sbcs.sbaccess == 0 && config.max_sba_data_width >= 8) { - sim->debug_mmu->store_uint8(address, sbdata[0]); + sim->debug_mmu->store(address, sbdata[0]); } else if (sbcs.sbaccess == 1 && config.max_sba_data_width >= 16) { - sim->debug_mmu->store_uint16(address, sbdata[0]); + sim->debug_mmu->store(address, sbdata[0]); } else if (sbcs.sbaccess == 2 && config.max_sba_data_width >= 32) { - sim->debug_mmu->store_uint32(address, sbdata[0]); + sim->debug_mmu->store(address, sbdata[0]); } else if (sbcs.sbaccess == 3 && config.max_sba_data_width >= 64) { - sim->debug_mmu->store_uint64(address, + sim->debug_mmu->store(address, (((uint64_t) sbdata[1]) << 32) | sbdata[0]); } else { sbcs.error = 3; @@ -357,8 +341,8 @@ bool debug_module_t::dmi_read(unsigned address, uint32_t *value) { uint32_t result = 0; D(fprintf(stderr, "dmi_read(0x%x) -> ", address)); - if (address >= DMI_DATA0 && address < DMI_DATA0 + abstractcs.datacount) { - unsigned i = address - DMI_DATA0; + if (address >= DM_DATA0 && address < DM_DATA0 + abstractcs.datacount) { + unsigned i = address - DM_DATA0; result = read32(dmdata, i); if (abstractcs.busy) { result = -1; @@ -372,8 +356,8 @@ bool debug_module_t::dmi_read(unsigned address, uint32_t *value) if (!abstractcs.busy && ((abstractauto.autoexecdata >> i) & 1)) { perform_abstract_command(); } - } else if (address >= DMI_PROGBUF0 && address < DMI_PROGBUF0 + config.progbufsize) { - unsigned i = address - DMI_PROGBUF0; + } else if (address >= DM_PROGBUF0 && address < DM_PROGBUF0 + config.progbufsize) { + unsigned i = address - DM_PROGBUF0; result = read32(program_buffer, i); if (abstractcs.busy) { result = -1; @@ -385,37 +369,37 @@ bool debug_module_t::dmi_read(unsigned address, uint32_t *value) } else { switch (address) { - case DMI_DMCONTROL: + case DM_DMCONTROL: { - result = set_field(result, DMI_DMCONTROL_HALTREQ, dmcontrol.haltreq); - result = set_field(result, DMI_DMCONTROL_RESUMEREQ, dmcontrol.resumereq); - result = set_field(result, DMI_DMCONTROL_HARTSELHI, - dmcontrol.hartsel >> DMI_DMCONTROL_HARTSELLO_LENGTH); - result = set_field(result, DMI_DMCONTROL_HASEL, dmcontrol.hasel); - result = set_field(result, DMI_DMCONTROL_HARTSELLO, dmcontrol.hartsel); - result = set_field(result, DMI_DMCONTROL_HARTRESET, dmcontrol.hartreset); - result = set_field(result, DMI_DMCONTROL_NDMRESET, dmcontrol.ndmreset); - result = set_field(result, DMI_DMCONTROL_DMACTIVE, dmcontrol.dmactive); + result = set_field(result, DM_DMCONTROL_HALTREQ, dmcontrol.haltreq); + result = set_field(result, DM_DMCONTROL_RESUMEREQ, dmcontrol.resumereq); + result = set_field(result, DM_DMCONTROL_HARTSELHI, + dmcontrol.hartsel >> DM_DMCONTROL_HARTSELLO_LENGTH); + result = set_field(result, DM_DMCONTROL_HASEL, dmcontrol.hasel); + result = set_field(result, DM_DMCONTROL_HARTSELLO, dmcontrol.hartsel); + result = set_field(result, DM_DMCONTROL_HARTRESET, dmcontrol.hartreset); + result = set_field(result, DM_DMCONTROL_NDMRESET, dmcontrol.ndmreset); + result = set_field(result, DM_DMCONTROL_DMACTIVE, dmcontrol.dmactive); } break; - case DMI_DMSTATUS: + case DM_DMSTATUS: { - dmstatus.allhalted = true; + dmstatus.allhalted = true; dmstatus.anyhalted = false; - dmstatus.allrunning = true; + dmstatus.allrunning = true; dmstatus.anyrunning = false; dmstatus.allnonexistant = true; dmstatus.allresumeack = true; dmstatus.anyresumeack = false; - for (unsigned i = 0; i < nprocs; i++) { - if (hart_selected(i)) { + for (const auto& [hart_id, hart] : sim->get_harts()) { + if (hart_selected(hart_id)) { dmstatus.allnonexistant = false; - if (hart_state[i].resumeack) { + if (hart_state[hart_id].resumeack) { dmstatus.anyresumeack = true; } else { dmstatus.allresumeack = false; } - if (hart_state[i].halted) { + if (hart_state[hart_id].halted) { dmstatus.allrunning = false; dmstatus.anyhalted = true; } else { @@ -428,93 +412,91 @@ bool debug_module_t::dmi_read(unsigned address, uint32_t *value) // We don't allow selecting non-existant harts through // hart_array_mask, so the only way it's possible is by writing a // non-existant hartsel. - dmstatus.anynonexistant = (dmcontrol.hartsel >= nprocs); + dmstatus.anynonexistant = dmcontrol.hartsel >= sim->get_cfg().nprocs(); - dmstatus.allunavail = false; - dmstatus.anyunavail = false; + dmstatus.allunavail = false; + dmstatus.anyunavail = false; - result = set_field(result, DMI_DMSTATUS_IMPEBREAK, + result = set_field(result, DM_DMSTATUS_IMPEBREAK, dmstatus.impebreak); - result = set_field(result, DMI_DMSTATUS_ALLHAVERESET, - hart_state[dmcontrol.hartsel].havereset); - result = set_field(result, DMI_DMSTATUS_ANYHAVERESET, - hart_state[dmcontrol.hartsel].havereset); - result = set_field(result, DMI_DMSTATUS_ALLNONEXISTENT, dmstatus.allnonexistant); - result = set_field(result, DMI_DMSTATUS_ALLUNAVAIL, dmstatus.allunavail); - result = set_field(result, DMI_DMSTATUS_ALLRUNNING, dmstatus.allrunning); - result = set_field(result, DMI_DMSTATUS_ALLHALTED, dmstatus.allhalted); - result = set_field(result, DMI_DMSTATUS_ALLRESUMEACK, dmstatus.allresumeack); - result = set_field(result, DMI_DMSTATUS_ANYNONEXISTENT, dmstatus.anynonexistant); - result = set_field(result, DMI_DMSTATUS_ANYUNAVAIL, dmstatus.anyunavail); - result = set_field(result, DMI_DMSTATUS_ANYRUNNING, dmstatus.anyrunning); - result = set_field(result, DMI_DMSTATUS_ANYHALTED, dmstatus.anyhalted); - result = set_field(result, DMI_DMSTATUS_ANYRESUMEACK, dmstatus.anyresumeack); - result = set_field(result, DMI_DMSTATUS_AUTHENTICATED, dmstatus.authenticated); - result = set_field(result, DMI_DMSTATUS_AUTHBUSY, dmstatus.authbusy); - result = set_field(result, DMI_DMSTATUS_VERSION, dmstatus.version); + result = set_field(result, DM_DMSTATUS_ALLHAVERESET, selected_hart_state().havereset); + result = set_field(result, DM_DMSTATUS_ANYHAVERESET, selected_hart_state().havereset); + result = set_field(result, DM_DMSTATUS_ALLNONEXISTENT, dmstatus.allnonexistant); + result = set_field(result, DM_DMSTATUS_ALLUNAVAIL, dmstatus.allunavail); + result = set_field(result, DM_DMSTATUS_ALLRUNNING, dmstatus.allrunning); + result = set_field(result, DM_DMSTATUS_ALLHALTED, dmstatus.allhalted); + result = set_field(result, DM_DMSTATUS_ALLRESUMEACK, dmstatus.allresumeack); + result = set_field(result, DM_DMSTATUS_ANYNONEXISTENT, dmstatus.anynonexistant); + result = set_field(result, DM_DMSTATUS_ANYUNAVAIL, dmstatus.anyunavail); + result = set_field(result, DM_DMSTATUS_ANYRUNNING, dmstatus.anyrunning); + result = set_field(result, DM_DMSTATUS_ANYHALTED, dmstatus.anyhalted); + result = set_field(result, DM_DMSTATUS_ANYRESUMEACK, dmstatus.anyresumeack); + result = set_field(result, DM_DMSTATUS_AUTHENTICATED, dmstatus.authenticated); + result = set_field(result, DM_DMSTATUS_AUTHBUSY, dmstatus.authbusy); + result = set_field(result, DM_DMSTATUS_VERSION, dmstatus.version); } break; - case DMI_ABSTRACTCS: - result = set_field(result, DMI_ABSTRACTCS_CMDERR, abstractcs.cmderr); - result = set_field(result, DMI_ABSTRACTCS_BUSY, abstractcs.busy); - result = set_field(result, DMI_ABSTRACTCS_DATACOUNT, abstractcs.datacount); - result = set_field(result, DMI_ABSTRACTCS_PROGBUFSIZE, + case DM_ABSTRACTCS: + result = set_field(result, DM_ABSTRACTCS_CMDERR, abstractcs.cmderr); + result = set_field(result, DM_ABSTRACTCS_BUSY, abstractcs.busy); + result = set_field(result, DM_ABSTRACTCS_DATACOUNT, abstractcs.datacount); + result = set_field(result, DM_ABSTRACTCS_PROGBUFSIZE, abstractcs.progbufsize); break; - case DMI_ABSTRACTAUTO: - result = set_field(result, DMI_ABSTRACTAUTO_AUTOEXECPROGBUF, abstractauto.autoexecprogbuf); - result = set_field(result, DMI_ABSTRACTAUTO_AUTOEXECDATA, abstractauto.autoexecdata); + case DM_ABSTRACTAUTO: + result = set_field(result, DM_ABSTRACTAUTO_AUTOEXECPROGBUF, abstractauto.autoexecprogbuf); + result = set_field(result, DM_ABSTRACTAUTO_AUTOEXECDATA, abstractauto.autoexecdata); break; - case DMI_COMMAND: + case DM_COMMAND: result = 0; break; - case DMI_HARTINFO: - result = set_field(result, DMI_HARTINFO_NSCRATCH, 1); - result = set_field(result, DMI_HARTINFO_DATAACCESS, 1); - result = set_field(result, DMI_HARTINFO_DATASIZE, abstractcs.datacount); - result = set_field(result, DMI_HARTINFO_DATAADDR, debug_data_start); + case DM_HARTINFO: + result = set_field(result, DM_HARTINFO_NSCRATCH, 1); + result = set_field(result, DM_HARTINFO_DATAACCESS, 1); + result = set_field(result, DM_HARTINFO_DATASIZE, abstractcs.datacount); + result = set_field(result, DM_HARTINFO_DATAADDR, debug_data_start); break; - case DMI_HAWINDOWSEL: + case DM_HAWINDOWSEL: result = hawindowsel; break; - case DMI_HAWINDOW: + case DM_HAWINDOW: { unsigned base = hawindowsel * 32; for (unsigned i = 0; i < 32; i++) { unsigned n = base + i; - if (n < nprocs && hart_array_mask[n]) { + if (n < sim->get_cfg().nprocs() && hart_array_mask[sim->get_cfg().hartids()[n]]) { result |= 1 << i; } } } break; - case DMI_SBCS: - result = set_field(result, DMI_SBCS_SBVERSION, sbcs.version); - result = set_field(result, DMI_SBCS_SBREADONADDR, sbcs.readonaddr); - result = set_field(result, DMI_SBCS_SBACCESS, sbcs.sbaccess); - result = set_field(result, DMI_SBCS_SBAUTOINCREMENT, sbcs.autoincrement); - result = set_field(result, DMI_SBCS_SBREADONDATA, sbcs.readondata); - result = set_field(result, DMI_SBCS_SBERROR, sbcs.error); - result = set_field(result, DMI_SBCS_SBASIZE, sbcs.asize); - result = set_field(result, DMI_SBCS_SBACCESS128, sbcs.access128); - result = set_field(result, DMI_SBCS_SBACCESS64, sbcs.access64); - result = set_field(result, DMI_SBCS_SBACCESS32, sbcs.access32); - result = set_field(result, DMI_SBCS_SBACCESS16, sbcs.access16); - result = set_field(result, DMI_SBCS_SBACCESS8, sbcs.access8); + case DM_SBCS: + result = set_field(result, DM_SBCS_SBVERSION, sbcs.version); + result = set_field(result, DM_SBCS_SBREADONADDR, sbcs.readonaddr); + result = set_field(result, DM_SBCS_SBACCESS, sbcs.sbaccess); + result = set_field(result, DM_SBCS_SBAUTOINCREMENT, sbcs.autoincrement); + result = set_field(result, DM_SBCS_SBREADONDATA, sbcs.readondata); + result = set_field(result, DM_SBCS_SBERROR, sbcs.error); + result = set_field(result, DM_SBCS_SBASIZE, sbcs.asize); + result = set_field(result, DM_SBCS_SBACCESS128, sbcs.access128); + result = set_field(result, DM_SBCS_SBACCESS64, sbcs.access64); + result = set_field(result, DM_SBCS_SBACCESS32, sbcs.access32); + result = set_field(result, DM_SBCS_SBACCESS16, sbcs.access16); + result = set_field(result, DM_SBCS_SBACCESS8, sbcs.access8); break; - case DMI_SBADDRESS0: + case DM_SBADDRESS0: result = sbaddress[0]; break; - case DMI_SBADDRESS1: + case DM_SBADDRESS1: result = sbaddress[1]; break; - case DMI_SBADDRESS2: + case DM_SBADDRESS2: result = sbaddress[2]; break; - case DMI_SBADDRESS3: + case DM_SBADDRESS3: result = sbaddress[3]; break; - case DMI_SBDATA0: + case DM_SBDATA0: result = sbdata[0]; if (sbcs.error == 0) { if (sbcs.readondata) { @@ -525,21 +507,20 @@ bool debug_module_t::dmi_read(unsigned address, uint32_t *value) } } break; - case DMI_SBDATA1: + case DM_SBDATA1: result = sbdata[1]; break; - case DMI_SBDATA2: + case DM_SBDATA2: result = sbdata[2]; break; - case DMI_SBDATA3: + case DM_SBDATA3: result = sbdata[3]; break; - case DMI_AUTHDATA: + case DM_AUTHDATA: result = challenge; break; - case DMI_DMCS2: - result = set_field(result, DMI_DMCS2_HALTGROUP, - hart_state[dmcontrol.hartsel].haltgroup); + case DM_DMCS2: + result = set_field(result, DM_DMCS2_GROUP, selected_hart_state().haltgroup); break; default: result = 0; @@ -583,7 +564,7 @@ bool debug_module_t::perform_abstract_command() bool write = get_field(command, AC_ACCESS_REGISTER_WRITE); unsigned regno = get_field(command, AC_ACCESS_REGISTER_REGNO); - if (!hart_state[dmcontrol.hartsel].halted) { + if (!selected_hart_state().halted) { abstractcs.cmderr = CMDERR_HALTRESUME; return true; } @@ -672,7 +653,7 @@ bool debug_module_t::perform_abstract_command() write32(debug_abstract, i++, csrw(S0, CSR_DSCRATCH0)); } - } else if (regno >= 0x1020 && regno < 0x1040) { + } else if (regno >= 0x1020 && regno < 0x1040 && config.support_abstract_fpr_access) { unsigned fprnum = regno - 0x1020; if (write) { @@ -738,7 +719,7 @@ bool debug_module_t::perform_abstract_command() write32(debug_abstract, i++, ebreak()); } - debug_rom_flags[dmcontrol.hartsel] |= 1 << DEBUG_ROM_FLAG_GO; + debug_rom_flags[selected_hart_id()] |= 1 << DEBUG_ROM_FLAG_GO; rti_remaining = config.abstract_rti; abstract_command_completed = false; @@ -753,14 +734,14 @@ bool debug_module_t::dmi_write(unsigned address, uint32_t value) { D(fprintf(stderr, "dmi_write(0x%x, 0x%x)\n", address, value)); - if (!dmstatus.authenticated && address != DMI_AUTHDATA && - address != DMI_DMCONTROL) + if (!dmstatus.authenticated && address != DM_AUTHDATA && + address != DM_DMCONTROL) return false; - if (address >= DMI_DATA0 && address < DMI_DATA0 + abstractcs.datacount) { - unsigned i = address - DMI_DATA0; + if (address >= DM_DATA0 && address < DM_DATA0 + abstractcs.datacount) { + unsigned i = address - DM_DATA0; if (!abstractcs.busy) - write32(dmdata, address - DMI_DATA0, value); + write32(dmdata, address - DM_DATA0, value); if (abstractcs.busy && abstractcs.cmderr == CMDERR_NONE) { abstractcs.cmderr = CMDERR_BUSY; @@ -771,8 +752,8 @@ bool debug_module_t::dmi_write(unsigned address, uint32_t value) } return true; - } else if (address >= DMI_PROGBUF0 && address < DMI_PROGBUF0 + config.progbufsize) { - unsigned i = address - DMI_PROGBUF0; + } else if (address >= DM_PROGBUF0 && address < DM_PROGBUF0 + config.progbufsize) { + unsigned i = address - DM_PROGBUF0; if (!abstractcs.busy) write32(program_buffer, i, value); @@ -784,112 +765,108 @@ bool debug_module_t::dmi_write(unsigned address, uint32_t value) } else { switch (address) { - case DMI_DMCONTROL: + case DM_DMCONTROL: { - if (!dmcontrol.dmactive && get_field(value, DMI_DMCONTROL_DMACTIVE)) + if (!dmcontrol.dmactive && get_field(value, DM_DMCONTROL_DMACTIVE)) reset(); - dmcontrol.dmactive = get_field(value, DMI_DMCONTROL_DMACTIVE); + dmcontrol.dmactive = get_field(value, DM_DMCONTROL_DMACTIVE); if (!dmstatus.authenticated || !dmcontrol.dmactive) return true; - dmcontrol.haltreq = get_field(value, DMI_DMCONTROL_HALTREQ); - dmcontrol.resumereq = get_field(value, DMI_DMCONTROL_RESUMEREQ); - dmcontrol.hartreset = get_field(value, DMI_DMCONTROL_HARTRESET); - dmcontrol.ndmreset = get_field(value, DMI_DMCONTROL_NDMRESET); + dmcontrol.haltreq = get_field(value, DM_DMCONTROL_HALTREQ); + dmcontrol.resumereq = get_field(value, DM_DMCONTROL_RESUMEREQ); + dmcontrol.hartreset = get_field(value, DM_DMCONTROL_HARTRESET); + dmcontrol.ndmreset = get_field(value, DM_DMCONTROL_NDMRESET); if (config.support_hasel) - dmcontrol.hasel = get_field(value, DMI_DMCONTROL_HASEL); + dmcontrol.hasel = get_field(value, DM_DMCONTROL_HASEL); else dmcontrol.hasel = 0; - dmcontrol.hartsel = get_field(value, DMI_DMCONTROL_HARTSELHI) << - DMI_DMCONTROL_HARTSELLO_LENGTH; - dmcontrol.hartsel |= get_field(value, DMI_DMCONTROL_HARTSELLO); - dmcontrol.hartsel &= (1L<get_cfg().nprocs() - 1); + for (const auto& [hart_id, hart] : sim->get_harts()) { + if (hart_selected(hart_id)) { + if (get_field(value, DM_DMCONTROL_ACKHAVERESET)) { + hart_state[hart_id].havereset = false; } - processor_t *proc = processor(i); - if (proc) { - proc->halt_request = dmcontrol.haltreq ? proc->HR_REGULAR : proc->HR_NONE; - if (dmcontrol.haltreq) { - D(fprintf(stderr, "halt hart %d\n", i)); - } - if (dmcontrol.resumereq) { - D(fprintf(stderr, "resume hart %d\n", i)); - debug_rom_flags[i] |= (1 << DEBUG_ROM_FLAG_RESUME); - hart_state[i].resumeack = false; - } - if (dmcontrol.hartreset) { - proc->reset(); - } + hart->halt_request = dmcontrol.haltreq ? hart->HR_REGULAR : hart->HR_NONE; + if (dmcontrol.haltreq) { + D(fprintf(stderr, "halt hart %d\n", hart_id)); + } + if (dmcontrol.resumereq) { + D(fprintf(stderr, "resume hart %d\n", hart_id)); + debug_rom_flags[hart_id] |= (1 << DEBUG_ROM_FLAG_RESUME); + hart_state[hart_id].resumeack = false; + } + if (dmcontrol.hartreset) { + hart->reset(); } } } if (dmcontrol.ndmreset) { - for (size_t i = 0; i < sim->nprocs(); i++) { - processor_t *proc = sim->get_core(i); - proc->reset(); + for (const auto& [hart_id, hart] : sim->get_harts()) { + hart->reset(); } } } return true; - case DMI_COMMAND: + case DM_COMMAND: command = value; return perform_abstract_command(); - case DMI_HAWINDOWSEL: - hawindowsel = value & ((1U<> i) & 1; + if (n < sim->get_cfg().nprocs()) { + hart_array_mask[sim->get_cfg().hartids()[n]] = (value >> i) & 1; } } } return true; - case DMI_ABSTRACTCS: - abstractcs.cmderr = (cmderr_t) (((uint32_t) (abstractcs.cmderr)) & (~(uint32_t)(get_field(value, DMI_ABSTRACTCS_CMDERR)))); + case DM_ABSTRACTCS: + abstractcs.cmderr = (cmderr_t) (((uint32_t) (abstractcs.cmderr)) & (~(uint32_t)(get_field(value, DM_ABSTRACTCS_CMDERR)))); return true; - case DMI_ABSTRACTAUTO: + case DM_ABSTRACTAUTO: abstractauto.autoexecprogbuf = get_field(value, - DMI_ABSTRACTAUTO_AUTOEXECPROGBUF); + DM_ABSTRACTAUTO_AUTOEXECPROGBUF); abstractauto.autoexecdata = get_field(value, - DMI_ABSTRACTAUTO_AUTOEXECDATA); + DM_ABSTRACTAUTO_AUTOEXECDATA); return true; - case DMI_SBCS: - sbcs.readonaddr = get_field(value, DMI_SBCS_SBREADONADDR); - sbcs.sbaccess = get_field(value, DMI_SBCS_SBACCESS); - sbcs.autoincrement = get_field(value, DMI_SBCS_SBAUTOINCREMENT); - sbcs.readondata = get_field(value, DMI_SBCS_SBREADONDATA); - sbcs.error &= ~get_field(value, DMI_SBCS_SBERROR); + case DM_SBCS: + sbcs.readonaddr = get_field(value, DM_SBCS_SBREADONADDR); + sbcs.sbaccess = get_field(value, DM_SBCS_SBACCESS); + sbcs.autoincrement = get_field(value, DM_SBCS_SBAUTOINCREMENT); + sbcs.readondata = get_field(value, DM_SBCS_SBREADONDATA); + sbcs.error &= ~get_field(value, DM_SBCS_SBERROR); return true; - case DMI_SBADDRESS0: + case DM_SBADDRESS0: sbaddress[0] = value; if (sbcs.error == 0 && sbcs.readonaddr) { sb_read(); sb_autoincrement(); } return true; - case DMI_SBADDRESS1: + case DM_SBADDRESS1: sbaddress[1] = value; return true; - case DMI_SBADDRESS2: + case DM_SBADDRESS2: sbaddress[2] = value; return true; - case DMI_SBADDRESS3: + case DM_SBADDRESS3: sbaddress[3] = value; return true; - case DMI_SBDATA0: + case DM_SBDATA0: sbdata[0] = value; if (sbcs.error == 0) { sb_write(); @@ -898,16 +875,16 @@ bool debug_module_t::dmi_write(unsigned address, uint32_t value) } } return true; - case DMI_SBDATA1: + case DM_SBDATA1: sbdata[1] = value; return true; - case DMI_SBDATA2: + case DM_SBDATA2: sbdata[2] = value; return true; - case DMI_SBDATA3: + case DM_SBDATA3: sbdata[3] = value; return true; - case DMI_AUTHDATA: + case DM_AUTHDATA: D(fprintf(stderr, "debug authentication: got 0x%x; 0x%x unlocks\n", value, challenge + secret)); if (config.require_authentication) { @@ -919,10 +896,11 @@ bool debug_module_t::dmi_write(unsigned address, uint32_t value) } } return true; - case DMI_DMCS2: - if (config.support_haltgroups && get_field(value, DMI_DMCS2_HGWRITE)) { - hart_state[dmcontrol.hartsel].haltgroup = get_field(value, - DMI_DMCS2_HALTGROUP); + case DM_DMCS2: + if (config.support_haltgroups && + get_field(value, DM_DMCS2_HGWRITE) && + get_field(value, DM_DMCS2_GROUPTYPE) == 0) { + selected_hart_state().haltgroup = get_field(value, DM_DMCS2_GROUP); } return true; } @@ -936,3 +914,13 @@ void debug_module_t::proc_reset(unsigned id) hart_state[id].halted = false; hart_state[id].haltgroup = 0; } + +hart_debug_state_t& debug_module_t::selected_hart_state() +{ + return hart_state[selected_hart_id()]; +} + +size_t debug_module_t::selected_hart_id() const +{ + return sim->get_cfg().hartids().at(dmcontrol.hartsel); +} diff --git a/vendor/riscv/riscv-isa-sim/riscv/debug_module.h b/vendor/riscv/riscv-isa-sim/riscv/debug_module.h index d79ce7d10..0a62d7758 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/debug_module.h +++ b/vendor/riscv/riscv-isa-sim/riscv/debug_module.h @@ -3,24 +3,26 @@ #define _RISCV_DEBUG_MODULE_H #include +#include #include "abstract_device.h" -#include "mmu.h" -class sim_t; +class simif_t; class bus_t; +class processor_t; typedef struct { - // Size of program_buffer in 32-bit words, as exposed to the rest of the - // world. - unsigned progbufsize; - unsigned max_sba_data_width; - bool require_authentication; - unsigned abstract_rti; - bool support_hasel; - bool support_abstract_csr_access; - bool support_haltgroups; - bool support_impebreak; + // Size of program_buffer in 32-bit words, as exposed to the rest of the + // world. + unsigned progbufsize; + unsigned max_sba_data_width; + bool require_authentication; + unsigned abstract_rti; + bool support_hasel; + bool support_abstract_csr_access; + bool support_abstract_fpr_access; + bool support_haltgroups; + bool support_impebreak; } debug_module_config_t; typedef struct { @@ -54,12 +56,12 @@ typedef struct { } dmstatus_t; typedef enum cmderr { - CMDERR_NONE = 0, - CMDERR_BUSY = 1, - CMDERR_NOTSUP = 2, - CMDERR_EXCEPTION = 3, - CMDERR_HALTRESUME = 4, - CMDERR_OTHER = 7 + CMDERR_NONE = 0, + CMDERR_BUSY = 1, + CMDERR_NOTSUP = 2, + CMDERR_EXCEPTION = 3, + CMDERR_HALTRESUME = 4, + CMDERR_OTHER = 7 } cmderr_t; typedef struct { @@ -108,7 +110,7 @@ class debug_module_t : public abstract_device_t * abstract_rti is extra run-test/idle cycles that each abstract command * takes to execute. Useful for testing OpenOCD. */ - debug_module_t(sim_t *sim, const debug_module_config_t &config); + debug_module_t(simif_t *sim, const debug_module_config_t &config); ~debug_module_t(); void add_device(bus_t *bus); @@ -130,7 +132,6 @@ class debug_module_t : public abstract_device_t private: static const unsigned datasize = 2; - unsigned nprocs; debug_module_config_t config; // Actual size of the program buffer, which is 1 word bigger than we let on // to implement the implicit ebreak at the end. @@ -144,11 +145,7 @@ class debug_module_t : public abstract_device_t // functionality. unsigned custom_base; - // We only support 1024 harts currently. More requires at least resizing - // the arrays below, and their corresponding special memory regions. - unsigned hartsellen = 10; - - sim_t *sim; + simif_t *sim; uint8_t debug_rom_whereto[4]; uint8_t debug_abstract[debug_abstract_size * 4]; @@ -181,13 +178,15 @@ class debug_module_t : public abstract_device_t uint32_t challenge; const uint32_t secret = 1; - processor_t *processor(unsigned hartid) const; bool hart_selected(unsigned hartid) const; void reset(); bool perform_abstract_command(); bool abstract_command_completed; unsigned rti_remaining; + + size_t selected_hart_id() const; + hart_debug_state_t& selected_hart_state(); }; #endif diff --git a/vendor/riscv/riscv-isa-sim/riscv/decode.h b/vendor/riscv/riscv-isa-sim/riscv/decode.h index 8b372c2f1..a55b06946 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/decode.h +++ b/vendor/riscv/riscv-isa-sim/riscv/decode.h @@ -7,19 +7,17 @@ # error spike requires a two''s-complement c++ implementation #endif +#include "../softfloat/softfloat_types.h" #include #include #include #include -#include "encoding.h" -#include "config.h" -#include "common.h" -#include "softfloat_types.h" -#include "specialize.h" #include +#include typedef int64_t sreg_t; typedef uint64_t reg_t; +typedef float128_t freg_t; #ifdef __SIZEOF_INT128__ typedef __int128 int128_t; @@ -33,6 +31,10 @@ const int NCSR = 4096; #define X_RA 1 #define X_SP 2 +#define X_S0 8 +#define X_A0 10 +#define X_A1 11 +#define X_Sn 16 #define VCSR_VXRM_SHIFT 1 #define VCSR_VXRM (0x3 << VCSR_VXRM_SHIFT) @@ -67,24 +69,25 @@ const int NCSR = 4096; (((x) & 0x03) < 0x03 ? 2 : \ ((x) & 0x1f) < 0x1f ? 4 : \ ((x) & 0x3f) < 0x3f ? 6 : \ - ((x) & 0x7f) == 0x7f ? 4 : \ 8) #define MAX_INSN_LENGTH 8 #define PC_ALIGN 2 +#define Sn(n) ((n) < 2 ? X_S0 + (n) : X_Sn + (n)) + typedef uint64_t insn_bits_t; class insn_t { public: insn_t() = default; insn_t(insn_bits_t bits) : b(bits) {} - insn_bits_t bits() { return b & ~((UINT64_MAX) << (length() * 8)); } + insn_bits_t bits() { return b; } int length() { return insn_length(b); } - int64_t i_imm() { return int64_t(b) >> 20; } + int64_t i_imm() { return xs(20, 12); } int64_t shamt() { return x(20, 6); } int64_t s_imm() { return x(7, 5) + (xs(25, 7) << 5); } - int64_t sb_imm() { return (x(8, 4) << 1) + (x(25,6) << 5) + (x(7,1) << 11) + (imm_sign() << 12); } - int64_t u_imm() { return int64_t(b) >> 12 << 12; } + int64_t sb_imm() { return (x(8, 4) << 1) + (x(25, 6) << 5) + (x(7, 1) << 11) + (imm_sign() << 12); } + int64_t u_imm() { return xs(12, 20) << 12; } int64_t uj_imm() { return (x(21, 10) << 1) + (x(20, 1) << 11) + (x(12, 8) << 12) + (imm_sign() << 20); } uint64_t rd() { return x(7, 5); } uint64_t rs1() { return x(15, 5); } @@ -93,8 +96,8 @@ public: uint64_t rm() { return x(12, 3); } uint64_t csr() { return x(20, 12); } uint64_t iorw() { return x(20, 8); } - uint64_t bs () {return x(30,2);} // Crypto ISE - SM4/AES32 byte select. - uint64_t rcon() {return x(20,4);} // Crypto ISE - AES64 round const. + uint64_t bs() { return x(30, 2); } // Crypto ISE - SM4/AES32 byte select. + uint64_t rcon() { return x(20, 4); } // Crypto ISE - AES64 round const. int64_t rvc_imm() { return x(2, 5) + (xs(12, 1) << 5); } int64_t rvc_zimm() { return x(2, 5) + (x(12, 1) << 5); } @@ -115,6 +118,16 @@ public: uint64_t rvc_rs1s() { return 8 + x(7, 3); } uint64_t rvc_rs2s() { return 8 + x(2, 3); } + uint64_t rvc_lbimm() { return (x(5, 1) << 1) + x(6, 1); } + uint64_t rvc_lhimm() { return (x(5, 1) << 1); } + + uint64_t rvc_r1sc() { return x(7, 3); } + uint64_t rvc_r2sc() { return x(2, 3); } + uint64_t rvc_rlist() { return x(4, 4); } + uint64_t rvc_spimm() { return x(2, 2) << 4; } + + uint64_t rvc_index() { return x(2, 8); } + uint64_t v_vm() { return x(25, 1); } uint64_t v_wd() { return x(26, 1); } uint64_t v_nf() { return x(29, 3); } @@ -139,11 +152,58 @@ public: uint64_t p_imm5() { return x(20, 5); } uint64_t p_imm6() { return x(20, 6); } + uint64_t zcmp_regmask() { + unsigned mask = 0; + uint64_t rlist = rvc_rlist(); + + if (rlist >= 4) + mask |= 1U << X_RA; + + for (reg_t i = 5; i <= rlist; i++) + mask |= 1U << Sn(i - 5); + + if (rlist == 15) + mask |= 1U << Sn(11); + + return mask; + } + + uint64_t zcmp_stack_adjustment(int xlen) { + reg_t stack_adj_base = 0; + switch (rvc_rlist()) { + case 15: + stack_adj_base += 16; + case 14: + if (xlen == 64) + stack_adj_base += 16; + case 13: + case 12: + stack_adj_base += 16; + case 11: + case 10: + if (xlen == 64) + stack_adj_base += 16; + case 9: + case 8: + stack_adj_base += 16; + case 7: + case 6: + if (xlen == 64) + stack_adj_base += 16; + case 5: + case 4: + stack_adj_base += 16; + break; + } + + return stack_adj_base + rvc_spimm(); + } + private: insn_bits_t b; - uint64_t x(int lo, int len) { return (b >> lo) & ((insn_bits_t(1) << len)-1); } - uint64_t xs(int lo, int len) { return int64_t(b) << (64-lo-len) >> (64-len); } - uint64_t imm_sign() { return xs(63, 1); } + uint64_t x(int lo, int len) { return (b >> lo) & ((insn_bits_t(1) << len) - 1); } + uint64_t xs(int lo, int len) { return int64_t(b) << (64 - lo - len) >> (64 - len); } + uint64_t imm_sign() { return xs(31, 1); } }; template @@ -171,2870 +231,11 @@ private: T data[N]; }; -// helpful macros, etc -#define MMU (*p->get_mmu()) -#define STATE (*p->get_state()) -#define FLEN (p->get_flen()) -#define CHECK_REG(reg) ((void) 0) -#define READ_REG(reg) ({ CHECK_REG(reg); STATE.XPR[reg]; }) -#define READ_FREG(reg) STATE.FPR[reg] -#define RD READ_REG(insn.rd()) -#define RS1 READ_REG(insn.rs1()) -#define RS2 READ_REG(insn.rs2()) -#define RS3 READ_REG(insn.rs3()) -#define WRITE_RD(value) WRITE_REG(insn.rd(), value) +#define get_field(reg, mask) \ + (((reg) & (std::remove_cv::type)(mask)) / ((mask) & ~((mask) << 1))) -#ifndef RISCV_ENABLE_COMMITLOG -# define WRITE_REG(reg, value) ({ CHECK_REG(reg); STATE.XPR.write(reg, value); }) -# define WRITE_FREG(reg, value) DO_WRITE_FREG(reg, freg(value)) -# define WRITE_VSTATUS {} -#else - /* 0 : int - * 1 : floating - * 2 : vector reg - * 3 : vector hint - * 4 : csr - */ -# define WRITE_REG(reg, value) ({ \ - reg_t wdata = (value); /* value may have side effects */ \ - STATE.log_reg_write[(reg) << 4] = {wdata, 0}; \ - CHECK_REG(reg); \ - STATE.XPR.write(reg, wdata); \ - }) -# define WRITE_FREG(reg, value) ({ \ - freg_t wdata = freg(value); /* value may have side effects */ \ - STATE.log_reg_write[((reg) << 4) | 1] = wdata; \ - DO_WRITE_FREG(reg, wdata); \ - }) -# define WRITE_VSTATUS STATE.log_reg_write[3] = {0, 0}; -#endif - -// RVC macros -#define WRITE_RVC_RS1S(value) WRITE_REG(insn.rvc_rs1s(), value) -#define WRITE_RVC_RS2S(value) WRITE_REG(insn.rvc_rs2s(), value) -#define WRITE_RVC_FRS2S(value) WRITE_FREG(insn.rvc_rs2s(), value) -#define RVC_RS1 READ_REG(insn.rvc_rs1()) -#define RVC_RS2 READ_REG(insn.rvc_rs2()) -#define RVC_RS1S READ_REG(insn.rvc_rs1s()) -#define RVC_RS2S READ_REG(insn.rvc_rs2s()) -#define RVC_FRS2 READ_FREG(insn.rvc_rs2()) -#define RVC_FRS2S READ_FREG(insn.rvc_rs2s()) -#define RVC_SP READ_REG(X_SP) - -// FPU macros -#define FRS1 READ_FREG(insn.rs1()) -#define FRS2 READ_FREG(insn.rs2()) -#define FRS3 READ_FREG(insn.rs3()) -#define dirty_fp_state STATE.sstatus->dirty(SSTATUS_FS) -#define dirty_ext_state STATE.sstatus->dirty(SSTATUS_XS) -#define dirty_vs_state STATE.sstatus->dirty(SSTATUS_VS) -#define DO_WRITE_FREG(reg, value) (STATE.FPR.write(reg, value), dirty_fp_state) -#define WRITE_FRD(value) WRITE_FREG(insn.rd(), value) - -#define SHAMT (insn.i_imm() & 0x3F) -#define BRANCH_TARGET (pc + insn.sb_imm()) -#define JUMP_TARGET (pc + insn.uj_imm()) -#define RM ({ int rm = insn.rm(); \ - if(rm == 7) rm = STATE.frm->read(); \ - if(rm > 4) throw trap_illegal_instruction(insn.bits()); \ - rm; }) - -#define get_field(reg, mask) (((reg) & (decltype(reg))(mask)) / ((mask) & ~((mask) << 1))) -#define set_field(reg, mask, val) (((reg) & ~(decltype(reg))(mask)) | (((decltype(reg))(val) * ((mask) & ~((mask) << 1))) & (decltype(reg))(mask))) - -#define require_privilege(p) require(STATE.prv >= (p)) -#define require_novirt() if (unlikely(STATE.v)) throw trap_virtual_instruction(insn.bits()) -#define require_rv64 require(xlen == 64) -#define require_rv32 require(xlen == 32) -#define require_extension(s) require(p->extension_enabled(s)) -#define require_either_extension(A,B) require(p->extension_enabled(A) || p->extension_enabled(B)); -#define require_impl(s) require(p->supports_impl(s)) -#define require_fp require(STATE.sstatus->enabled(SSTATUS_FS)) -#define require_accelerator require(STATE.sstatus->enabled(SSTATUS_XS)) -#define require_vector_vs require(STATE.sstatus->enabled(SSTATUS_VS)) -#define require_vector(alu) \ - do { \ - require_vector_vs; \ - require_extension('V'); \ - require(!P.VU.vill); \ - if (alu && !P.VU.vstart_alu) \ - require(P.VU.vstart->read() == 0); \ - WRITE_VSTATUS; \ - dirty_vs_state; \ - } while (0); -#define require_vector_novtype(is_log, alu) \ - do { \ - require_vector_vs; \ - require_extension('V'); \ - if (alu && !P.VU.vstart_alu) \ - require(P.VU.vstart->read() == 0); \ - if (is_log) \ - WRITE_VSTATUS; \ - dirty_vs_state; \ - } while (0); -#define require_align(val, pos) require(is_aligned(val, pos)) -#define require_noover(astart, asize, bstart, bsize) \ - require(!is_overlapped(astart, asize, bstart, bsize)) -#define require_noover_widen(astart, asize, bstart, bsize) \ - require(!is_overlapped_widen(astart, asize, bstart, bsize)) -#define require_vm do { if (insn.v_vm() == 0) require(insn.rd() != 0);} while(0); - -#define set_fp_exceptions ({ if (softfloat_exceptionFlags) { \ - STATE.fflags->write(STATE.fflags->read() | softfloat_exceptionFlags); \ - } \ - softfloat_exceptionFlags = 0; }) - -#define sext32(x) ((sreg_t)(int32_t)(x)) -#define zext32(x) ((reg_t)(uint32_t)(x)) -#define sext_xlen(x) (((sreg_t)(x) << (64-xlen)) >> (64-xlen)) -#define zext(x, pos) (((reg_t)(x) << (64-(pos))) >> (64-(pos))) -#define zext_xlen(x) zext(x, xlen) - -#define set_pc(x) \ - do { p->check_pc_alignment(x); \ - npc = sext_xlen(x); \ - } while(0) - -#define set_pc_and_serialize(x) \ - do { reg_t __npc = (x) & p->pc_alignment_mask(); \ - npc = PC_SERIALIZE_AFTER; \ - STATE.pc = __npc; \ - } while(0) - -class wait_for_interrupt_t {}; - -#define wfi() \ - do { set_pc_and_serialize(npc); \ - npc = PC_SERIALIZE_WFI; \ - throw wait_for_interrupt_t(); \ - } while(0) - -#define serialize() set_pc_and_serialize(npc) - -/* Sentinel PC values to serialize simulator pipeline */ -#define PC_SERIALIZE_BEFORE 3 -#define PC_SERIALIZE_AFTER 5 -#define PC_SERIALIZE_WFI 7 -#define invalid_pc(pc) ((pc) & 1) - -/* Convenience wrappers to simplify softfloat code sequences */ -#define isBoxedF16(r) (isBoxedF32(r) && ((uint64_t)((r.v[0] >> 16) + 1) == ((uint64_t)1 << 48))) -#define unboxF16(r) (isBoxedF16(r) ? (uint16_t)r.v[0] : defaultNaNF16UI) -#define isBoxedF32(r) (isBoxedF64(r) && ((uint32_t)((r.v[0] >> 32) + 1) == 0)) -#define unboxF32(r) (isBoxedF32(r) ? (uint32_t)r.v[0] : defaultNaNF32UI) -#define isBoxedF64(r) ((r.v[1] + 1) == 0) -#define unboxF64(r) (isBoxedF64(r) ? r.v[0] : defaultNaNF64UI) -typedef float128_t freg_t; -inline float16_t f16(uint16_t v) { return { v }; } -inline float32_t f32(uint32_t v) { return { v }; } -inline float64_t f64(uint64_t v) { return { v }; } -inline float16_t f16(freg_t r) { return f16(unboxF16(r)); } -inline float32_t f32(freg_t r) { return f32(unboxF32(r)); } -inline float64_t f64(freg_t r) { return f64(unboxF64(r)); } -inline float128_t f128(freg_t r) { return r; } -inline freg_t freg(float16_t f) { return { ((uint64_t)-1 << 16) | f.v, (uint64_t)-1 }; } -inline freg_t freg(float32_t f) { return { ((uint64_t)-1 << 32) | f.v, (uint64_t)-1 }; } -inline freg_t freg(float64_t f) { return { f.v, (uint64_t)-1 }; } -inline freg_t freg(float128_t f) { return f; } -#define F16_SIGN ((uint16_t)1 << 15) -#define F32_SIGN ((uint32_t)1 << 31) -#define F64_SIGN ((uint64_t)1 << 63) -#define fsgnj16(a, b, n, x) \ - f16((f16(a).v & ~F16_SIGN) | ((((x) ? f16(a).v : (n) ? F16_SIGN : 0) ^ f16(b).v) & F16_SIGN)) -#define fsgnj32(a, b, n, x) \ - f32((f32(a).v & ~F32_SIGN) | ((((x) ? f32(a).v : (n) ? F32_SIGN : 0) ^ f32(b).v) & F32_SIGN)) -#define fsgnj64(a, b, n, x) \ - f64((f64(a).v & ~F64_SIGN) | ((((x) ? f64(a).v : (n) ? F64_SIGN : 0) ^ f64(b).v) & F64_SIGN)) - -#define isNaNF128(x) isNaNF128UI(x.v[1], x.v[0]) -inline float128_t defaultNaNF128() -{ - float128_t nan; - nan.v[1] = defaultNaNF128UI64; - nan.v[0] = defaultNaNF128UI0; - return nan; -} -inline freg_t fsgnj128(freg_t a, freg_t b, bool n, bool x) -{ - a.v[1] = (a.v[1] & ~F64_SIGN) | (((x ? a.v[1] : n ? F64_SIGN : 0) ^ b.v[1]) & F64_SIGN); - return a; -} -inline freg_t f128_negate(freg_t a) -{ - a.v[1] ^= F64_SIGN; - return a; -} - -#define validate_csr(which, write) ({ \ - if (!STATE.serialized) return PC_SERIALIZE_BEFORE; \ - STATE.serialized = false; \ - /* permissions check occurs in get_csr */ \ - (which); }) - -/* For debug only. This will fail if the native machine's float types are not IEEE */ -inline float to_f(float32_t f){float r; memcpy(&r, &f, sizeof(r)); return r;} -inline double to_f(float64_t f){double r; memcpy(&r, &f, sizeof(r)); return r;} -inline long double to_f(float128_t f){long double r; memcpy(&r, &f, sizeof(r)); return r;} - -// Vector macros -#define e8 8 // 8b elements -#define e16 16 // 16b elements -#define e32 32 // 32b elements -#define e64 64 // 64b elements -#define e128 128 // 128b elements -#define e256 256 // 256b elements -#define e512 512 // 512b elements -#define e1024 1024 // 1024b elements - -#define vsext(x, sew) (((sreg_t)(x) << (64-sew)) >> (64-sew)) -#define vzext(x, sew) (((reg_t)(x) << (64-sew)) >> (64-sew)) - -#define DEBUG_RVV 0 - -#if DEBUG_RVV -#define DEBUG_RVV_FP_VV \ - printf("vfp(%lu) vd=%f vs1=%f vs2=%f\n", i, to_f(vd), to_f(vs1), to_f(vs2)); -#define DEBUG_RVV_FP_VF \ - printf("vfp(%lu) vd=%f vs1=%f vs2=%f\n", i, to_f(vd), to_f(rs1), to_f(vs2)); -#define DEBUG_RVV_FMA_VV \ - printf("vfma(%lu) vd=%f vs1=%f vs2=%f vd_old=%f\n", i, to_f(vd), to_f(vs1), to_f(vs2), to_f(vd_old)); -#define DEBUG_RVV_FMA_VF \ - printf("vfma(%lu) vd=%f vs1=%f vs2=%f vd_old=%f\n", i, to_f(vd), to_f(rs1), to_f(vs2), to_f(vd_old)); -#else -#define DEBUG_RVV_FP_VV 0 -#define DEBUG_RVV_FP_VF 0 -#define DEBUG_RVV_FMA_VV 0 -#define DEBUG_RVV_FMA_VF 0 -#endif - -// -// vector: masking skip helper -// -#define VI_MASK_VARS \ - const int midx = i / 64; \ - const int mpos = i % 64; - -#define VI_LOOP_ELEMENT_SKIP(BODY) \ - VI_MASK_VARS \ - if (insn.v_vm() == 0) { \ - BODY; \ - bool skip = ((P.VU.elt(0, midx) >> mpos) & 0x1) == 0; \ - if (skip) {\ - continue; \ - }\ - } - -#define VI_ELEMENT_SKIP(inx) \ - if (inx >= vl) { \ - continue; \ - } else if (inx < P.VU.vstart->read()) { \ - continue; \ - } else { \ - VI_LOOP_ELEMENT_SKIP(); \ - } - -// -// vector: operation and register acccess check helper -// -static inline bool is_overlapped(const int astart, int asize, - const int bstart, int bsize) -{ - asize = asize == 0 ? 1 : asize; - bsize = bsize == 0 ? 1 : bsize; - - const int aend = astart + asize; - const int bend = bstart + bsize; - - return std::max(aend, bend) - std::min(astart, bstart) < asize + bsize; -} - -static inline bool is_overlapped_widen(const int astart, int asize, - const int bstart, int bsize) -{ - asize = asize == 0 ? 1 : asize; - bsize = bsize == 0 ? 1 : bsize; - - const int aend = astart + asize; - const int bend = bstart + bsize; - - if (astart < bstart && - is_overlapped(astart, asize, bstart, bsize) && - !is_overlapped(astart, asize, bstart + bsize, bsize)) { - return false; - } else { - return std::max(aend, bend) - std::min(astart, bstart) < asize + bsize; - } -} - -static inline bool is_aligned(const unsigned val, const unsigned pos) -{ - return pos ? (val & (pos - 1)) == 0 : true; -} - -#define VI_NARROW_CHECK_COMMON \ - require_vector(true);\ - require(P.VU.vflmul <= 4); \ - require(P.VU.vsew * 2 <= P.VU.ELEN); \ - require_align(insn.rs2(), P.VU.vflmul * 2); \ - require_align(insn.rd(), P.VU.vflmul); \ - require_vm; \ - -#define VI_WIDE_CHECK_COMMON \ - require_vector(true);\ - require(P.VU.vflmul <= 4); \ - require(P.VU.vsew * 2 <= P.VU.ELEN); \ - require_align(insn.rd(), P.VU.vflmul * 2); \ - require_vm; \ - -#define VI_CHECK_ST_INDEX(elt_width) \ - require_vector(false); \ - float vemul = ((float)elt_width / P.VU.vsew * P.VU.vflmul); \ - require(vemul >= 0.125 && vemul <= 8); \ - reg_t emul = vemul < 1 ? 1 : vemul; \ - reg_t flmul = P.VU.vflmul < 1 ? 1 : P.VU.vflmul; \ - require_align(insn.rd(), P.VU.vflmul); \ - require_align(insn.rs2(), vemul); \ - require((nf * flmul) <= (NVPR / 4) && \ - (insn.rd() + nf * flmul) <= NVPR); \ - -#define VI_CHECK_LD_INDEX(elt_width) \ - VI_CHECK_ST_INDEX(elt_width); \ - for (reg_t idx = 0; idx < nf; ++idx) { \ - reg_t flmul = P.VU.vflmul < 1 ? 1 : P.VU.vflmul; \ - reg_t seg_vd = insn.rd() + flmul * idx; \ - if (elt_width > P.VU.vsew) { \ - if (seg_vd != insn.rs2()) \ - require_noover(seg_vd, P.VU.vflmul, insn.rs2(), vemul); \ - } else if (elt_width < P.VU.vsew) { \ - if (vemul < 1) {\ - require_noover(seg_vd, P.VU.vflmul, insn.rs2(), vemul); \ - } else {\ - require_noover_widen(seg_vd, P.VU.vflmul, insn.rs2(), vemul); \ - } \ - } \ - if (nf >= 2) { \ - require_noover(seg_vd, P.VU.vflmul, insn.rs2(), vemul); \ - } \ - } \ - require_vm; \ - -#define VI_CHECK_MSS(is_vs1) \ - if (insn.rd() != insn.rs2()) \ - require_noover(insn.rd(), 1, insn.rs2(), P.VU.vflmul); \ - require_align(insn.rs2(), P.VU.vflmul); \ - if (is_vs1) {\ - if (insn.rd() != insn.rs1()) \ - require_noover(insn.rd(), 1, insn.rs1(), P.VU.vflmul); \ - require_align(insn.rs1(), P.VU.vflmul); \ - } \ - -#define VI_CHECK_SSS(is_vs1) \ - require_vm; \ - if (P.VU.vflmul > 1) { \ - require_align(insn.rd(), P.VU.vflmul); \ - require_align(insn.rs2(), P.VU.vflmul); \ - if (is_vs1) { \ - require_align(insn.rs1(), P.VU.vflmul); \ - } \ - } - -#define VI_CHECK_STORE(elt_width, is_mask_ldst) \ - require_vector(false); \ - reg_t veew = is_mask_ldst ? 1 : sizeof(elt_width##_t) * 8; \ - float vemul = is_mask_ldst ? 1 : ((float)veew / P.VU.vsew * P.VU.vflmul); \ - reg_t emul = vemul < 1 ? 1 : vemul; \ - require(vemul >= 0.125 && vemul <= 8); \ - require_align(insn.rd(), vemul); \ - require((nf * emul) <= (NVPR / 4) && \ - (insn.rd() + nf * emul) <= NVPR); \ - -#define VI_CHECK_LOAD(elt_width, is_mask_ldst) \ - VI_CHECK_STORE(elt_width, is_mask_ldst); \ - require_vm; \ - -#define VI_CHECK_DSS(is_vs1) \ - VI_WIDE_CHECK_COMMON; \ - require_align(insn.rs2(), P.VU.vflmul); \ - if (P.VU.vflmul < 1) {\ - require_noover(insn.rd(), P.VU.vflmul * 2, insn.rs2(), P.VU.vflmul); \ - } else {\ - require_noover_widen(insn.rd(), P.VU.vflmul * 2, insn.rs2(), P.VU.vflmul); \ - } \ - if (is_vs1) {\ - require_align(insn.rs1(), P.VU.vflmul); \ - if (P.VU.vflmul < 1) {\ - require_noover(insn.rd(), P.VU.vflmul * 2, insn.rs1(), P.VU.vflmul); \ - } else {\ - require_noover_widen(insn.rd(), P.VU.vflmul * 2, insn.rs1(), P.VU.vflmul); \ - } \ - } - -#define VI_CHECK_DDS(is_rs) \ - VI_WIDE_CHECK_COMMON; \ - require_align(insn.rs2(), P.VU.vflmul * 2); \ - if (is_rs) { \ - require_align(insn.rs1(), P.VU.vflmul); \ - if (P.VU.vflmul < 1) {\ - require_noover(insn.rd(), P.VU.vflmul * 2, insn.rs1(), P.VU.vflmul); \ - } else {\ - require_noover_widen(insn.rd(), P.VU.vflmul * 2, insn.rs1(), P.VU.vflmul); \ - } \ - } - -#define VI_CHECK_SDS(is_vs1) \ - VI_NARROW_CHECK_COMMON; \ - if (insn.rd() != insn.rs2()) \ - require_noover(insn.rd(), P.VU.vflmul, insn.rs2(), P.VU.vflmul * 2); \ - if (is_vs1) \ - require_align(insn.rs1(), P.VU.vflmul); \ - -#define VI_CHECK_REDUCTION(is_wide) \ - require_vector(true);\ - if (is_wide) {\ - require(P.VU.vsew * 2 <= P.VU.ELEN); \ - } \ - require_align(insn.rs2(), P.VU.vflmul); \ - require(P.VU.vstart->read() == 0); \ - -#define VI_CHECK_SLIDE(is_over) \ - require_align(insn.rs2(), P.VU.vflmul); \ - require_align(insn.rd(), P.VU.vflmul); \ - require_vm; \ - if (is_over) \ - require(insn.rd() != insn.rs2()); \ - - -// -// vector: loop header and end helper -// -#define VI_GENERAL_LOOP_BASE \ - require(P.VU.vsew >= e8 && P.VU.vsew <= e64); \ - require_vector(true);\ - reg_t vl = P.VU.vl->read(); \ - reg_t sew = P.VU.vsew; \ - reg_t rd_num = insn.rd(); \ - reg_t rs1_num = insn.rs1(); \ - reg_t rs2_num = insn.rs2(); \ - for (reg_t i=P.VU.vstart->read(); iwrite(0); - -#define VI_LOOP_REDUCTION_END(x) \ - } \ - if (vl > 0) { \ - vd_0_des = vd_0_res; \ - } \ - P.VU.vstart->write(0); - -#define VI_LOOP_CARRY_BASE \ - VI_GENERAL_LOOP_BASE \ - VI_MASK_VARS \ - auto v0 = P.VU.elt(0, midx); \ - const uint64_t mmask = UINT64_C(1) << mpos; \ - const uint128_t op_mask = (UINT64_MAX >> (64 - sew)); \ - uint64_t carry = insn.v_vm() == 0 ? (v0 >> mpos) & 0x1 : 0; \ - uint128_t res = 0; \ - auto &vd = P.VU.elt(rd_num, midx, true); - -#define VI_LOOP_CARRY_END \ - vd = (vd & ~mmask) | (((res) << mpos) & mmask); \ - } \ - P.VU.vstart->write(0); -#define VI_LOOP_WITH_CARRY_BASE \ - VI_GENERAL_LOOP_BASE \ - VI_MASK_VARS \ - auto &v0 = P.VU.elt(0, midx); \ - const uint128_t op_mask = (UINT64_MAX >> (64 - sew)); \ - uint64_t carry = (v0 >> mpos) & 0x1; - -#define VI_LOOP_CMP_BASE \ - require(P.VU.vsew >= e8 && P.VU.vsew <= e64); \ - require_vector(true);\ - reg_t vl = P.VU.vl->read(); \ - reg_t sew = P.VU.vsew; \ - reg_t rd_num = insn.rd(); \ - reg_t rs1_num = insn.rs1(); \ - reg_t rs2_num = insn.rs2(); \ - for (reg_t i=P.VU.vstart->read(); i(insn.rd(), midx, true); \ - uint64_t res = 0; - -#define VI_LOOP_CMP_END \ - vdi = (vdi & ~mmask) | (((res) << mpos) & mmask); \ - } \ - P.VU.vstart->write(0); - -#define VI_LOOP_MASK(op) \ - require(P.VU.vsew <= e64); \ - require_vector(true);\ - reg_t vl = P.VU.vl->read(); \ - for (reg_t i = P.VU.vstart->read(); i < vl; ++i) { \ - int midx = i / 64; \ - int mpos = i % 64; \ - uint64_t mmask = UINT64_C(1) << mpos; \ - uint64_t vs2 = P.VU.elt(insn.rs2(), midx); \ - uint64_t vs1 = P.VU.elt(insn.rs1(), midx); \ - uint64_t &res = P.VU.elt(insn.rd(), midx, true); \ - res = (res & ~mmask) | ((op) & (1ULL << mpos)); \ - } \ - P.VU.vstart->write(0); - -#define VI_LOOP_NSHIFT_BASE \ - VI_GENERAL_LOOP_BASE; \ - VI_LOOP_ELEMENT_SKIP({\ - require(!(insn.rd() == 0 && P.VU.vflmul > 1));\ - }); - - -#define INT_ROUNDING(result, xrm, gb) \ - do { \ - const uint64_t lsb = 1UL << (gb); \ - const uint64_t lsb_half = lsb >> 1; \ - switch (xrm) {\ - case VRM::RNU:\ - result += lsb_half; \ - break;\ - case VRM::RNE:\ - if ((result & lsb_half) && ((result & (lsb_half - 1)) || (result & lsb))) \ - result += lsb; \ - break;\ - case VRM::RDN:\ - break;\ - case VRM::ROD:\ - if (result & (lsb - 1)) \ - result |= lsb; \ - break;\ - case VRM::INVALID_RM:\ - assert(true);\ - } \ - } while (0) - -// -// vector: integer and masking operand access helper -// -#define VXI_PARAMS(x) \ - type_sew_t::type &vd = P.VU.elt::type>(rd_num, i, true); \ - type_sew_t::type vs1 = P.VU.elt::type>(rs1_num, i); \ - type_sew_t::type vs2 = P.VU.elt::type>(rs2_num, i); \ - type_sew_t::type rs1 = (type_sew_t::type)RS1; \ - type_sew_t::type simm5 = (type_sew_t::type)insn.v_simm5(); - -#define VV_U_PARAMS(x) \ - type_usew_t::type &vd = P.VU.elt::type>(rd_num, i, true); \ - type_usew_t::type vs1 = P.VU.elt::type>(rs1_num, i); \ - type_usew_t::type vs2 = P.VU.elt::type>(rs2_num, i); - -#define VX_U_PARAMS(x) \ - type_usew_t::type &vd = P.VU.elt::type>(rd_num, i, true); \ - type_usew_t::type rs1 = (type_usew_t::type)RS1; \ - type_usew_t::type vs2 = P.VU.elt::type>(rs2_num, i); - -#define VI_U_PARAMS(x) \ - type_usew_t::type &vd = P.VU.elt::type>(rd_num, i, true); \ - type_usew_t::type zimm5 = (type_usew_t::type)insn.v_zimm5(); \ - type_usew_t::type vs2 = P.VU.elt::type>(rs2_num, i); - -#define VV_PARAMS(x) \ - type_sew_t::type &vd = P.VU.elt::type>(rd_num, i, true); \ - type_sew_t::type vs1 = P.VU.elt::type>(rs1_num, i); \ - type_sew_t::type vs2 = P.VU.elt::type>(rs2_num, i); - -#define VX_PARAMS(x) \ - type_sew_t::type &vd = P.VU.elt::type>(rd_num, i, true); \ - type_sew_t::type rs1 = (type_sew_t::type)RS1; \ - type_sew_t::type vs2 = P.VU.elt::type>(rs2_num, i); - -#define VI_PARAMS(x) \ - type_sew_t::type &vd = P.VU.elt::type>(rd_num, i, true); \ - type_sew_t::type simm5 = (type_sew_t::type)insn.v_simm5(); \ - type_sew_t::type vs2 = P.VU.elt::type>(rs2_num, i); - -#define XV_PARAMS(x) \ - type_sew_t::type &vd = P.VU.elt::type>(rd_num, i, true); \ - type_usew_t::type vs2 = P.VU.elt::type>(rs2_num, RS1); - -#define VV_SU_PARAMS(x) \ - type_sew_t::type &vd = P.VU.elt::type>(rd_num, i, true); \ - type_usew_t::type vs1 = P.VU.elt::type>(rs1_num, i); \ - type_sew_t::type vs2 = P.VU.elt::type>(rs2_num, i); - -#define VX_SU_PARAMS(x) \ - type_sew_t::type &vd = P.VU.elt::type>(rd_num, i, true); \ - type_usew_t::type rs1 = (type_usew_t::type)RS1; \ - type_sew_t::type vs2 = P.VU.elt::type>(rs2_num, i); - -#define VV_UCMP_PARAMS(x) \ - type_usew_t::type vs1 = P.VU.elt::type>(rs1_num, i); \ - type_usew_t::type vs2 = P.VU.elt::type>(rs2_num, i); - -#define VX_UCMP_PARAMS(x) \ - type_usew_t::type rs1 = (type_usew_t::type)RS1; \ - type_usew_t::type vs2 = P.VU.elt::type>(rs2_num, i); - -#define VI_UCMP_PARAMS(x) \ - type_usew_t::type vs2 = P.VU.elt::type>(rs2_num, i); - -#define VV_CMP_PARAMS(x) \ - type_sew_t::type vs1 = P.VU.elt::type>(rs1_num, i); \ - type_sew_t::type vs2 = P.VU.elt::type>(rs2_num, i); - -#define VX_CMP_PARAMS(x) \ - type_sew_t::type rs1 = (type_sew_t::type)RS1; \ - type_sew_t::type vs2 = P.VU.elt::type>(rs2_num, i); - -#define VI_CMP_PARAMS(x) \ - type_sew_t::type simm5 = (type_sew_t::type)insn.v_simm5(); \ - type_sew_t::type vs2 = P.VU.elt::type>(rs2_num, i); - -#define VI_XI_SLIDEDOWN_PARAMS(x, off) \ - auto &vd = P.VU.elt::type>(rd_num, i, true); \ - auto vs2 = P.VU.elt::type>(rs2_num, i + off); - -#define VI_XI_SLIDEUP_PARAMS(x, offset) \ - auto &vd = P.VU.elt::type>(rd_num, i, true); \ - auto vs2 = P.VU.elt::type>(rs2_num, i - offset); - -#define VI_NARROW_PARAMS(sew1, sew2) \ - auto &vd = P.VU.elt::type>(rd_num, i, true); \ - auto vs2_u = P.VU.elt::type>(rs2_num, i); \ - auto vs2 = P.VU.elt::type>(rs2_num, i); \ - auto zimm5 = (type_usew_t::type)insn.v_zimm5(); - -#define VX_NARROW_PARAMS(sew1, sew2) \ - auto &vd = P.VU.elt::type>(rd_num, i, true); \ - auto vs2_u = P.VU.elt::type>(rs2_num, i); \ - auto vs2 = P.VU.elt::type>(rs2_num, i); \ - auto rs1 = (type_sew_t::type)RS1; - -#define VV_NARROW_PARAMS(sew1, sew2) \ - auto &vd = P.VU.elt::type>(rd_num, i, true); \ - auto vs2_u = P.VU.elt::type>(rs2_num, i); \ - auto vs2 = P.VU.elt::type>(rs2_num, i); \ - auto vs1 = P.VU.elt::type>(rs1_num, i); - -#define XI_CARRY_PARAMS(x) \ - auto vs2 = P.VU.elt::type>(rs2_num, i); \ - auto rs1 = (type_sew_t::type)RS1; \ - auto simm5 = (type_sew_t::type)insn.v_simm5(); \ - -#define VV_CARRY_PARAMS(x) \ - auto vs2 = P.VU.elt::type>(rs2_num, i); \ - auto vs1 = P.VU.elt::type>(rs1_num, i); \ - -#define XI_WITH_CARRY_PARAMS(x) \ - auto vs2 = P.VU.elt::type>(rs2_num, i); \ - auto rs1 = (type_sew_t::type)RS1; \ - auto simm5 = (type_sew_t::type)insn.v_simm5(); \ - auto &vd = P.VU.elt::type>(rd_num, i, true); - -#define VV_WITH_CARRY_PARAMS(x) \ - auto vs2 = P.VU.elt::type>(rs2_num, i); \ - auto vs1 = P.VU.elt::type>(rs1_num, i); \ - auto &vd = P.VU.elt::type>(rd_num, i, true); - -#define VFP_V_PARAMS(width) \ - float##width##_t &vd = P.VU.elt(rd_num, i, true); \ - float##width##_t vs2 = P.VU.elt(rs2_num, i); - -#define VFP_VV_PARAMS(width) \ - float##width##_t &vd = P.VU.elt(rd_num, i, true); \ - float##width##_t vs1 = P.VU.elt(rs1_num, i); \ - float##width##_t vs2 = P.VU.elt(rs2_num, i); - -#define VFP_VF_PARAMS(width) \ - float##width##_t &vd = P.VU.elt(rd_num, i, true); \ - float##width##_t rs1 = f##width(READ_FREG(rs1_num)); \ - float##width##_t vs2 = P.VU.elt(rs2_num, i); - -#define CVT_FP_TO_FP_PARAMS(from_width, to_width) \ - auto vs2 = P.VU.elt(rs2_num, i); \ - auto &vd = P.VU.elt(rd_num, i, true); - -#define CVT_INT_TO_FP_PARAMS(from_width, to_width, sign) \ - auto vs2 = P.VU.elt(rs2_num, i); \ - auto &vd = P.VU.elt(rd_num, i, true); - -#define CVT_FP_TO_INT_PARAMS(from_width, to_width, sign) \ - auto vs2 = P.VU.elt(rs2_num, i); \ - auto &vd = P.VU.elt(rd_num, i, true); - -// -// vector: integer and masking operation loop -// - -// comparision result to masking register -#define VI_VV_LOOP_CMP(BODY) \ - VI_CHECK_MSS(true); \ - VI_LOOP_CMP_BASE \ - if (sew == e8){ \ - VV_CMP_PARAMS(e8); \ - BODY; \ - }else if(sew == e16){ \ - VV_CMP_PARAMS(e16); \ - BODY; \ - }else if(sew == e32){ \ - VV_CMP_PARAMS(e32); \ - BODY; \ - }else if(sew == e64){ \ - VV_CMP_PARAMS(e64); \ - BODY; \ - } \ - VI_LOOP_CMP_END - -#define VI_VX_LOOP_CMP(BODY) \ - VI_CHECK_MSS(false); \ - VI_LOOP_CMP_BASE \ - if (sew == e8){ \ - VX_CMP_PARAMS(e8); \ - BODY; \ - }else if(sew == e16){ \ - VX_CMP_PARAMS(e16); \ - BODY; \ - }else if(sew == e32){ \ - VX_CMP_PARAMS(e32); \ - BODY; \ - }else if(sew == e64){ \ - VX_CMP_PARAMS(e64); \ - BODY; \ - } \ - VI_LOOP_CMP_END - -#define VI_VI_LOOP_CMP(BODY) \ - VI_CHECK_MSS(false); \ - VI_LOOP_CMP_BASE \ - if (sew == e8){ \ - VI_CMP_PARAMS(e8); \ - BODY; \ - }else if(sew == e16){ \ - VI_CMP_PARAMS(e16); \ - BODY; \ - }else if(sew == e32){ \ - VI_CMP_PARAMS(e32); \ - BODY; \ - }else if(sew == e64){ \ - VI_CMP_PARAMS(e64); \ - BODY; \ - } \ - VI_LOOP_CMP_END - -#define VI_VV_ULOOP_CMP(BODY) \ - VI_CHECK_MSS(true); \ - VI_LOOP_CMP_BASE \ - if (sew == e8){ \ - VV_UCMP_PARAMS(e8); \ - BODY; \ - }else if(sew == e16){ \ - VV_UCMP_PARAMS(e16); \ - BODY; \ - }else if(sew == e32){ \ - VV_UCMP_PARAMS(e32); \ - BODY; \ - }else if(sew == e64){ \ - VV_UCMP_PARAMS(e64); \ - BODY; \ - } \ - VI_LOOP_CMP_END - -#define VI_VX_ULOOP_CMP(BODY) \ - VI_CHECK_MSS(false); \ - VI_LOOP_CMP_BASE \ - if (sew == e8){ \ - VX_UCMP_PARAMS(e8); \ - BODY; \ - }else if(sew == e16){ \ - VX_UCMP_PARAMS(e16); \ - BODY; \ - }else if(sew == e32){ \ - VX_UCMP_PARAMS(e32); \ - BODY; \ - }else if(sew == e64){ \ - VX_UCMP_PARAMS(e64); \ - BODY; \ - } \ - VI_LOOP_CMP_END - -#define VI_VI_ULOOP_CMP(BODY) \ - VI_CHECK_MSS(false); \ - VI_LOOP_CMP_BASE \ - if (sew == e8){ \ - VI_UCMP_PARAMS(e8); \ - BODY; \ - }else if(sew == e16){ \ - VI_UCMP_PARAMS(e16); \ - BODY; \ - }else if(sew == e32){ \ - VI_UCMP_PARAMS(e32); \ - BODY; \ - }else if(sew == e64){ \ - VI_UCMP_PARAMS(e64); \ - BODY; \ - } \ - VI_LOOP_CMP_END - -// merge and copy loop -#define VI_MERGE_VARS \ - VI_MASK_VARS \ - bool use_first = (P.VU.elt(0, midx) >> mpos) & 0x1; - -#define VI_MERGE_LOOP_BASE \ - require_vector(true); \ - VI_GENERAL_LOOP_BASE \ - VI_MERGE_VARS - -#define VI_VV_MERGE_LOOP(BODY) \ - VI_CHECK_SSS(true); \ - VI_MERGE_LOOP_BASE \ - if (sew == e8){ \ - VV_PARAMS(e8); \ - BODY; \ - }else if(sew == e16){ \ - VV_PARAMS(e16); \ - BODY; \ - }else if(sew == e32){ \ - VV_PARAMS(e32); \ - BODY; \ - }else if(sew == e64){ \ - VV_PARAMS(e64); \ - BODY; \ - } \ - VI_LOOP_END - -#define VI_VX_MERGE_LOOP(BODY) \ - VI_CHECK_SSS(false); \ - VI_MERGE_LOOP_BASE \ - if (sew == e8){ \ - VX_PARAMS(e8); \ - BODY; \ - }else if(sew == e16){ \ - VX_PARAMS(e16); \ - BODY; \ - }else if(sew == e32){ \ - VX_PARAMS(e32); \ - BODY; \ - }else if(sew == e64){ \ - VX_PARAMS(e64); \ - BODY; \ - } \ - VI_LOOP_END - -#define VI_VI_MERGE_LOOP(BODY) \ - VI_CHECK_SSS(false); \ - VI_MERGE_LOOP_BASE \ - if (sew == e8){ \ - VI_PARAMS(e8); \ - BODY; \ - }else if(sew == e16){ \ - VI_PARAMS(e16); \ - BODY; \ - }else if(sew == e32){ \ - VI_PARAMS(e32); \ - BODY; \ - }else if(sew == e64){ \ - VI_PARAMS(e64); \ - BODY; \ - } \ - VI_LOOP_END - -#define VI_VF_MERGE_LOOP(BODY) \ - VI_CHECK_SSS(false); \ - VI_VFP_COMMON \ - for (reg_t i=P.VU.vstart->read(); i= e8 && x <= e64); \ - reg_t vl = P.VU.vl->read(); \ - reg_t rd_num = insn.rd(); \ - reg_t rs1_num = insn.rs1(); \ - reg_t rs2_num = insn.rs2(); \ - auto &vd_0_des = P.VU.elt::type>(rd_num, 0, true); \ - auto vd_0_res = P.VU.elt::type>(rs1_num, 0); \ - for (reg_t i=P.VU.vstart->read(); i::type>(rs2_num, i); \ - -#define REDUCTION_LOOP(x, BODY) \ - VI_LOOP_REDUCTION_BASE(x) \ - BODY; \ - VI_LOOP_REDUCTION_END(x) - -#define VI_VV_LOOP_REDUCTION(BODY) \ - VI_CHECK_REDUCTION(false); \ - reg_t sew = P.VU.vsew; \ - if (sew == e8) { \ - REDUCTION_LOOP(e8, BODY) \ - } else if(sew == e16) { \ - REDUCTION_LOOP(e16, BODY) \ - } else if(sew == e32) { \ - REDUCTION_LOOP(e32, BODY) \ - } else if(sew == e64) { \ - REDUCTION_LOOP(e64, BODY) \ - } - -// reduction loop - unsigned -#define VI_ULOOP_REDUCTION_BASE(x) \ - require(x >= e8 && x <= e64); \ - reg_t vl = P.VU.vl->read(); \ - reg_t rd_num = insn.rd(); \ - reg_t rs1_num = insn.rs1(); \ - reg_t rs2_num = insn.rs2(); \ - auto &vd_0_des = P.VU.elt::type>(rd_num, 0, true); \ - auto vd_0_res = P.VU.elt::type>(rs1_num, 0); \ - for (reg_t i=P.VU.vstart->read(); i::type>(rs2_num, i); - -#define REDUCTION_ULOOP(x, BODY) \ - VI_ULOOP_REDUCTION_BASE(x) \ - BODY; \ - VI_LOOP_REDUCTION_END(x) - -#define VI_VV_ULOOP_REDUCTION(BODY) \ - VI_CHECK_REDUCTION(false); \ - reg_t sew = P.VU.vsew; \ - if (sew == e8){ \ - REDUCTION_ULOOP(e8, BODY) \ - } else if(sew == e16) { \ - REDUCTION_ULOOP(e16, BODY) \ - } else if(sew == e32) { \ - REDUCTION_ULOOP(e32, BODY) \ - } else if(sew == e64) { \ - REDUCTION_ULOOP(e64, BODY) \ - } - - -// genearl VXI signed/unsigned loop -#define VI_VV_ULOOP(BODY) \ - VI_CHECK_SSS(true) \ - VI_LOOP_BASE \ - if (sew == e8){ \ - VV_U_PARAMS(e8); \ - BODY; \ - }else if(sew == e16){ \ - VV_U_PARAMS(e16); \ - BODY; \ - }else if(sew == e32){ \ - VV_U_PARAMS(e32); \ - BODY; \ - }else if(sew == e64){ \ - VV_U_PARAMS(e64); \ - BODY; \ - } \ - VI_LOOP_END - -#define VI_VV_LOOP(BODY) \ - VI_CHECK_SSS(true) \ - VI_LOOP_BASE \ - if (sew == e8){ \ - VV_PARAMS(e8); \ - BODY; \ - }else if(sew == e16){ \ - VV_PARAMS(e16); \ - BODY; \ - }else if(sew == e32){ \ - VV_PARAMS(e32); \ - BODY; \ - }else if(sew == e64){ \ - VV_PARAMS(e64); \ - BODY; \ - } \ - VI_LOOP_END - -#define VI_VX_ULOOP(BODY) \ - VI_CHECK_SSS(false) \ - VI_LOOP_BASE \ - if (sew == e8){ \ - VX_U_PARAMS(e8); \ - BODY; \ - }else if(sew == e16){ \ - VX_U_PARAMS(e16); \ - BODY; \ - }else if(sew == e32){ \ - VX_U_PARAMS(e32); \ - BODY; \ - }else if(sew == e64){ \ - VX_U_PARAMS(e64); \ - BODY; \ - } \ - VI_LOOP_END - -#define VI_VX_LOOP(BODY) \ - VI_CHECK_SSS(false) \ - VI_LOOP_BASE \ - if (sew == e8){ \ - VX_PARAMS(e8); \ - BODY; \ - }else if(sew == e16){ \ - VX_PARAMS(e16); \ - BODY; \ - }else if(sew == e32){ \ - VX_PARAMS(e32); \ - BODY; \ - }else if(sew == e64){ \ - VX_PARAMS(e64); \ - BODY; \ - } \ - VI_LOOP_END - -#define VI_VI_ULOOP(BODY) \ - VI_CHECK_SSS(false) \ - VI_LOOP_BASE \ - if (sew == e8){ \ - VI_U_PARAMS(e8); \ - BODY; \ - }else if(sew == e16){ \ - VI_U_PARAMS(e16); \ - BODY; \ - }else if(sew == e32){ \ - VI_U_PARAMS(e32); \ - BODY; \ - }else if(sew == e64){ \ - VI_U_PARAMS(e64); \ - BODY; \ - } \ - VI_LOOP_END - -#define VI_VI_LOOP(BODY) \ - VI_CHECK_SSS(false) \ - VI_LOOP_BASE \ - if (sew == e8){ \ - VI_PARAMS(e8); \ - BODY; \ - }else if(sew == e16){ \ - VI_PARAMS(e16); \ - BODY; \ - }else if(sew == e32){ \ - VI_PARAMS(e32); \ - BODY; \ - }else if(sew == e64){ \ - VI_PARAMS(e64); \ - BODY; \ - } \ - VI_LOOP_END - -// signed unsigned operation loop (e.g. mulhsu) -#define VI_VV_SU_LOOP(BODY) \ - VI_CHECK_SSS(true) \ - VI_LOOP_BASE \ - if (sew == e8){ \ - VV_SU_PARAMS(e8); \ - BODY; \ - }else if(sew == e16){ \ - VV_SU_PARAMS(e16); \ - BODY; \ - }else if(sew == e32){ \ - VV_SU_PARAMS(e32); \ - BODY; \ - }else if(sew == e64){ \ - VV_SU_PARAMS(e64); \ - BODY; \ - } \ - VI_LOOP_END - -#define VI_VX_SU_LOOP(BODY) \ - VI_CHECK_SSS(false) \ - VI_LOOP_BASE \ - if (sew == e8){ \ - VX_SU_PARAMS(e8); \ - BODY; \ - }else if(sew == e16){ \ - VX_SU_PARAMS(e16); \ - BODY; \ - }else if(sew == e32){ \ - VX_SU_PARAMS(e32); \ - BODY; \ - }else if(sew == e64){ \ - VX_SU_PARAMS(e64); \ - BODY; \ - } \ - VI_LOOP_END - -// narrow operation loop -#define VI_VV_LOOP_NARROW(BODY) \ - VI_CHECK_SDS(true); \ - VI_LOOP_BASE \ - if (sew == e8){ \ - VV_NARROW_PARAMS(e8, e16) \ - BODY; \ - }else if(sew == e16){ \ - VV_NARROW_PARAMS(e16, e32) \ - BODY; \ - }else if(sew == e32){ \ - VV_NARROW_PARAMS(e32, e64) \ - BODY; \ - } \ - VI_LOOP_END - -#define VI_VX_LOOP_NARROW(BODY) \ - VI_CHECK_SDS(false); \ - VI_LOOP_BASE \ - if (sew == e8){ \ - VX_NARROW_PARAMS(e8, e16) \ - BODY; \ - }else if(sew == e16){ \ - VX_NARROW_PARAMS(e16, e32) \ - BODY; \ - }else if(sew == e32){ \ - VX_NARROW_PARAMS(e32, e64) \ - BODY; \ - } \ - VI_LOOP_END - -#define VI_VI_LOOP_NARROW(BODY) \ - VI_CHECK_SDS(false); \ - VI_LOOP_BASE \ - if (sew == e8){ \ - VI_NARROW_PARAMS(e8, e16) \ - BODY; \ - }else if(sew == e16){ \ - VI_NARROW_PARAMS(e16, e32) \ - BODY; \ - }else if(sew == e32){ \ - VI_NARROW_PARAMS(e32, e64) \ - BODY; \ - } \ - VI_LOOP_END - -#define VI_VI_LOOP_NSHIFT(BODY) \ - VI_CHECK_SDS(false); \ - VI_LOOP_NSHIFT_BASE \ - if (sew == e8){ \ - VI_NARROW_PARAMS(e8, e16) \ - BODY; \ - } else if (sew == e16) { \ - VI_NARROW_PARAMS(e16, e32) \ - BODY; \ - } else if (sew == e32) { \ - VI_NARROW_PARAMS(e32, e64) \ - BODY; \ - } \ - VI_LOOP_END - -#define VI_VX_LOOP_NSHIFT(BODY) \ - VI_CHECK_SDS(false); \ - VI_LOOP_NSHIFT_BASE \ - if (sew == e8){ \ - VX_NARROW_PARAMS(e8, e16) \ - BODY; \ - } else if (sew == e16) { \ - VX_NARROW_PARAMS(e16, e32) \ - BODY; \ - } else if (sew == e32) { \ - VX_NARROW_PARAMS(e32, e64) \ - BODY; \ - } \ - VI_LOOP_END - -#define VI_VV_LOOP_NSHIFT(BODY) \ - VI_CHECK_SDS(true); \ - VI_LOOP_NSHIFT_BASE \ - if (sew == e8){ \ - VV_NARROW_PARAMS(e8, e16) \ - BODY; \ - } else if (sew == e16) { \ - VV_NARROW_PARAMS(e16, e32) \ - BODY; \ - } else if (sew == e32) { \ - VV_NARROW_PARAMS(e32, e64) \ - BODY; \ - } \ - VI_LOOP_END - -// widen operation loop -#define VI_VV_LOOP_WIDEN(BODY) \ - VI_LOOP_BASE \ - if (sew == e8){ \ - VV_PARAMS(e8); \ - BODY; \ - }else if(sew == e16){ \ - VV_PARAMS(e16); \ - BODY; \ - }else if(sew == e32){ \ - VV_PARAMS(e32); \ - BODY; \ - } \ - VI_LOOP_END - -#define VI_VX_LOOP_WIDEN(BODY) \ - VI_LOOP_BASE \ - if (sew == e8){ \ - VX_PARAMS(e8); \ - BODY; \ - }else if(sew == e16){ \ - VX_PARAMS(e16); \ - BODY; \ - }else if(sew == e32){ \ - VX_PARAMS(e32); \ - BODY; \ - } \ - VI_LOOP_END - -#define VI_WIDE_OP_AND_ASSIGN(var0, var1, var2, op0, op1, sign) \ - switch(P.VU.vsew) { \ - case e8: { \ - sign##16_t vd_w = P.VU.elt(rd_num, i); \ - P.VU.elt(rd_num, i, true) = \ - op1((sign##16_t)(sign##8_t)var0 op0 (sign##16_t)(sign##8_t)var1) + var2; \ - } \ - break; \ - case e16: { \ - sign##32_t vd_w = P.VU.elt(rd_num, i); \ - P.VU.elt(rd_num, i, true) = \ - op1((sign##32_t)(sign##16_t)var0 op0 (sign##32_t)(sign##16_t)var1) + var2; \ - } \ - break; \ - default: { \ - sign##64_t vd_w = P.VU.elt(rd_num, i); \ - P.VU.elt(rd_num, i, true) = \ - op1((sign##64_t)(sign##32_t)var0 op0 (sign##64_t)(sign##32_t)var1) + var2; \ - } \ - break; \ - } - -#define VI_WIDE_OP_AND_ASSIGN_MIX(var0, var1, var2, op0, op1, sign_d, sign_1, sign_2) \ - switch(P.VU.vsew) { \ - case e8: { \ - sign_d##16_t vd_w = P.VU.elt(rd_num, i); \ - P.VU.elt(rd_num, i, true) = \ - op1((sign_1##16_t)(sign_1##8_t)var0 op0 (sign_2##16_t)(sign_2##8_t)var1) + var2; \ - } \ - break; \ - case e16: { \ - sign_d##32_t vd_w = P.VU.elt(rd_num, i); \ - P.VU.elt(rd_num, i, true) = \ - op1((sign_1##32_t)(sign_1##16_t)var0 op0 (sign_2##32_t)(sign_2##16_t)var1) + var2; \ - } \ - break; \ - default: { \ - sign_d##64_t vd_w = P.VU.elt(rd_num, i); \ - P.VU.elt(rd_num, i, true) = \ - op1((sign_1##64_t)(sign_1##32_t)var0 op0 (sign_2##64_t)(sign_2##32_t)var1) + var2; \ - } \ - break; \ - } - -#define VI_WIDE_WVX_OP(var0, op0, sign) \ - switch(P.VU.vsew) { \ - case e8: { \ - sign##16_t &vd_w = P.VU.elt(rd_num, i, true); \ - sign##16_t vs2_w = P.VU.elt(rs2_num, i); \ - vd_w = vs2_w op0 (sign##16_t)(sign##8_t)var0; \ - } \ - break; \ - case e16: { \ - sign##32_t &vd_w = P.VU.elt(rd_num, i, true); \ - sign##32_t vs2_w = P.VU.elt(rs2_num, i); \ - vd_w = vs2_w op0 (sign##32_t)(sign##16_t)var0; \ - } \ - break; \ - default: { \ - sign##64_t &vd_w = P.VU.elt(rd_num, i, true); \ - sign##64_t vs2_w = P.VU.elt(rs2_num, i); \ - vd_w = vs2_w op0 (sign##64_t)(sign##32_t)var0; \ - } \ - break; \ - } - -// wide reduction loop - signed -#define VI_LOOP_WIDE_REDUCTION_BASE(sew1, sew2) \ - reg_t vl = P.VU.vl->read(); \ - reg_t rd_num = insn.rd(); \ - reg_t rs1_num = insn.rs1(); \ - reg_t rs2_num = insn.rs2(); \ - auto &vd_0_des = P.VU.elt::type>(rd_num, 0, true); \ - auto vd_0_res = P.VU.elt::type>(rs1_num, 0); \ - for (reg_t i=P.VU.vstart->read(); i::type>(rs2_num, i); - -#define WIDE_REDUCTION_LOOP(sew1, sew2, BODY) \ - VI_LOOP_WIDE_REDUCTION_BASE(sew1, sew2) \ - BODY; \ - VI_LOOP_REDUCTION_END(sew2) - -#define VI_VV_LOOP_WIDE_REDUCTION(BODY) \ - VI_CHECK_REDUCTION(true); \ - reg_t sew = P.VU.vsew; \ - if (sew == e8){ \ - WIDE_REDUCTION_LOOP(e8, e16, BODY) \ - } else if(sew == e16){ \ - WIDE_REDUCTION_LOOP(e16, e32, BODY) \ - } else if(sew == e32){ \ - WIDE_REDUCTION_LOOP(e32, e64, BODY) \ - } - -// wide reduction loop - unsigned -#define VI_ULOOP_WIDE_REDUCTION_BASE(sew1, sew2) \ - reg_t vl = P.VU.vl->read(); \ - reg_t rd_num = insn.rd(); \ - reg_t rs1_num = insn.rs1(); \ - reg_t rs2_num = insn.rs2(); \ - auto &vd_0_des = P.VU.elt::type>(rd_num, 0, true); \ - auto vd_0_res = P.VU.elt::type>(rs1_num, 0); \ - for (reg_t i=P.VU.vstart->read(); i::type>(rs2_num, i); - -#define WIDE_REDUCTION_ULOOP(sew1, sew2, BODY) \ - VI_ULOOP_WIDE_REDUCTION_BASE(sew1, sew2) \ - BODY; \ - VI_LOOP_REDUCTION_END(sew2) - -#define VI_VV_ULOOP_WIDE_REDUCTION(BODY) \ - VI_CHECK_REDUCTION(true); \ - reg_t sew = P.VU.vsew; \ - if (sew == e8){ \ - WIDE_REDUCTION_ULOOP(e8, e16, BODY) \ - } else if(sew == e16){ \ - WIDE_REDUCTION_ULOOP(e16, e32, BODY) \ - } else if(sew == e32){ \ - WIDE_REDUCTION_ULOOP(e32, e64, BODY) \ - } - -// carry/borrow bit loop -#define VI_VV_LOOP_CARRY(BODY) \ - VI_CHECK_MSS(true); \ - VI_LOOP_CARRY_BASE \ - if (sew == e8){ \ - VV_CARRY_PARAMS(e8) \ - BODY; \ - } else if (sew == e16) { \ - VV_CARRY_PARAMS(e16) \ - BODY; \ - } else if (sew == e32) { \ - VV_CARRY_PARAMS(e32) \ - BODY; \ - } else if (sew == e64) { \ - VV_CARRY_PARAMS(e64) \ - BODY; \ - } \ - VI_LOOP_CARRY_END - -#define VI_XI_LOOP_CARRY(BODY) \ - VI_CHECK_MSS(false); \ - VI_LOOP_CARRY_BASE \ - if (sew == e8){ \ - XI_CARRY_PARAMS(e8) \ - BODY; \ - } else if (sew == e16) { \ - XI_CARRY_PARAMS(e16) \ - BODY; \ - } else if (sew == e32) { \ - XI_CARRY_PARAMS(e32) \ - BODY; \ - } else if (sew == e64) { \ - XI_CARRY_PARAMS(e64) \ - BODY; \ - } \ - VI_LOOP_CARRY_END - -#define VI_VV_LOOP_WITH_CARRY(BODY) \ - require_vm; \ - VI_CHECK_SSS(true); \ - VI_LOOP_WITH_CARRY_BASE \ - if (sew == e8){ \ - VV_WITH_CARRY_PARAMS(e8) \ - BODY; \ - } else if (sew == e16) { \ - VV_WITH_CARRY_PARAMS(e16) \ - BODY; \ - } else if (sew == e32) { \ - VV_WITH_CARRY_PARAMS(e32) \ - BODY; \ - } else if (sew == e64) { \ - VV_WITH_CARRY_PARAMS(e64) \ - BODY; \ - } \ - VI_LOOP_END - -#define VI_XI_LOOP_WITH_CARRY(BODY) \ - require_vm; \ - VI_CHECK_SSS(false); \ - VI_LOOP_WITH_CARRY_BASE \ - if (sew == e8){ \ - XI_WITH_CARRY_PARAMS(e8) \ - BODY; \ - } else if (sew == e16) { \ - XI_WITH_CARRY_PARAMS(e16) \ - BODY; \ - } else if (sew == e32) { \ - XI_WITH_CARRY_PARAMS(e32) \ - BODY; \ - } else if (sew == e64) { \ - XI_WITH_CARRY_PARAMS(e64) \ - BODY; \ - } \ - VI_LOOP_END - -// average loop -#define VI_VV_LOOP_AVG(op) \ -VRM xrm = p->VU.get_vround_mode(); \ -VI_VV_LOOP({ \ - uint128_t res = ((uint128_t)vs2) op vs1; \ - INT_ROUNDING(res, xrm, 1); \ - vd = res >> 1; \ -}) - -#define VI_VX_LOOP_AVG(op) \ -VRM xrm = p->VU.get_vround_mode(); \ -VI_VX_LOOP({ \ - uint128_t res = ((uint128_t)vs2) op rs1; \ - INT_ROUNDING(res, xrm, 1); \ - vd = res >> 1; \ -}) - -#define VI_VV_ULOOP_AVG(op) \ -VRM xrm = p->VU.get_vround_mode(); \ -VI_VV_ULOOP({ \ - uint128_t res = ((uint128_t)vs2) op vs1; \ - INT_ROUNDING(res, xrm, 1); \ - vd = res >> 1; \ -}) - -#define VI_VX_ULOOP_AVG(op) \ -VRM xrm = p->VU.get_vround_mode(); \ -VI_VX_ULOOP({ \ - uint128_t res = ((uint128_t)vs2) op rs1; \ - INT_ROUNDING(res, xrm, 1); \ - vd = res >> 1; \ -}) - -// -// vector: load/store helper -// -#define VI_STRIP(inx) \ - reg_t vreg_inx = inx; - -#define VI_DUPLICATE_VREG(reg_num, idx_sew) \ -reg_t index[P.VU.vlmax]; \ - for (reg_t i = 0; i < P.VU.vlmax && P.VU.vl->read() != 0; ++i) { \ - switch(idx_sew) { \ - case e8: \ - index[i] = P.VU.elt(reg_num, i); \ - break; \ - case e16: \ - index[i] = P.VU.elt(reg_num, i); \ - break; \ - case e32: \ - index[i] = P.VU.elt(reg_num, i); \ - break; \ - case e64: \ - index[i] = P.VU.elt(reg_num, i); \ - break; \ - } \ -} - -#define VI_LD(stride, offset, elt_width, is_mask_ldst) \ - const reg_t nf = insn.v_nf() + 1; \ - const reg_t vl = is_mask_ldst ? ((P.VU.vl->read() + 7) / 8) : P.VU.vl->read(); \ - const reg_t baseAddr = RS1; \ - const reg_t vd = insn.rd(); \ - VI_CHECK_LOAD(elt_width, is_mask_ldst); \ - for (reg_t i = 0; i < vl; ++i) { \ - VI_ELEMENT_SKIP(i); \ - VI_STRIP(i); \ - P.VU.vstart->write(i); \ - for (reg_t fn = 0; fn < nf; ++fn) { \ - elt_width##_t val = MMU.load_##elt_width( \ - baseAddr + (stride) + (offset) * sizeof(elt_width##_t)); \ - P.VU.elt(vd + fn * emul, vreg_inx, true) = val; \ - } \ - } \ - P.VU.vstart->write(0); - -#define VI_LD_INDEX(elt_width, is_seg) \ - const reg_t nf = insn.v_nf() + 1; \ - const reg_t vl = P.VU.vl->read(); \ - const reg_t baseAddr = RS1; \ - const reg_t vd = insn.rd(); \ - if (!is_seg) \ - require(nf == 1); \ - VI_CHECK_LD_INDEX(elt_width); \ - VI_DUPLICATE_VREG(insn.rs2(), elt_width); \ - for (reg_t i = 0; i < vl; ++i) { \ - VI_ELEMENT_SKIP(i); \ - VI_STRIP(i); \ - P.VU.vstart->write(i); \ - for (reg_t fn = 0; fn < nf; ++fn) { \ - switch(P.VU.vsew){ \ - case e8: \ - P.VU.elt(vd + fn * flmul, vreg_inx, true) = \ - MMU.load_uint8(baseAddr + index[i] + fn * 1); \ - break; \ - case e16: \ - P.VU.elt(vd + fn * flmul, vreg_inx, true) = \ - MMU.load_uint16(baseAddr + index[i] + fn * 2); \ - break; \ - case e32: \ - P.VU.elt(vd + fn * flmul, vreg_inx, true) = \ - MMU.load_uint32(baseAddr + index[i] + fn * 4); \ - break; \ - default: \ - P.VU.elt(vd + fn * flmul, vreg_inx, true) = \ - MMU.load_uint64(baseAddr + index[i] + fn * 8); \ - break; \ - } \ - } \ - } \ - P.VU.vstart->write(0); - -#define VI_ST(stride, offset, elt_width, is_mask_ldst) \ - const reg_t nf = insn.v_nf() + 1; \ - const reg_t vl = is_mask_ldst ? ((P.VU.vl->read() + 7) / 8) : P.VU.vl->read(); \ - const reg_t baseAddr = RS1; \ - const reg_t vs3 = insn.rd(); \ - VI_CHECK_STORE(elt_width, is_mask_ldst); \ - for (reg_t i = 0; i < vl; ++i) { \ - VI_STRIP(i) \ - VI_ELEMENT_SKIP(i); \ - P.VU.vstart->write(i); \ - for (reg_t fn = 0; fn < nf; ++fn) { \ - elt_width##_t val = P.VU.elt(vs3 + fn * emul, vreg_inx); \ - MMU.store_##elt_width( \ - baseAddr + (stride) + (offset) * sizeof(elt_width##_t), val); \ - } \ - } \ - P.VU.vstart->write(0); - -#define VI_ST_INDEX(elt_width, is_seg) \ - const reg_t nf = insn.v_nf() + 1; \ - const reg_t vl = P.VU.vl->read(); \ - const reg_t baseAddr = RS1; \ - const reg_t vs3 = insn.rd(); \ - if (!is_seg) \ - require(nf == 1); \ - VI_CHECK_ST_INDEX(elt_width); \ - VI_DUPLICATE_VREG(insn.rs2(), elt_width); \ - for (reg_t i = 0; i < vl; ++i) { \ - VI_STRIP(i) \ - VI_ELEMENT_SKIP(i); \ - P.VU.vstart->write(i); \ - for (reg_t fn = 0; fn < nf; ++fn) { \ - switch (P.VU.vsew) { \ - case e8: \ - MMU.store_uint8(baseAddr + index[i] + fn * 1, \ - P.VU.elt(vs3 + fn * flmul, vreg_inx)); \ - break; \ - case e16: \ - MMU.store_uint16(baseAddr + index[i] + fn * 2, \ - P.VU.elt(vs3 + fn * flmul, vreg_inx)); \ - break; \ - case e32: \ - MMU.store_uint32(baseAddr + index[i] + fn * 4, \ - P.VU.elt(vs3 + fn * flmul, vreg_inx)); \ - break; \ - default: \ - MMU.store_uint64(baseAddr + index[i] + fn * 8, \ - P.VU.elt(vs3 + fn * flmul, vreg_inx)); \ - break; \ - } \ - } \ - } \ - P.VU.vstart->write(0); - -#define VI_LDST_FF(elt_width) \ - const reg_t nf = insn.v_nf() + 1; \ - const reg_t sew = p->VU.vsew; \ - const reg_t vl = p->VU.vl->read(); \ - const reg_t baseAddr = RS1; \ - const reg_t rd_num = insn.rd(); \ - VI_CHECK_LOAD(elt_width, false); \ - bool early_stop = false; \ - for (reg_t i = p->VU.vstart->read(); i < vl; ++i) { \ - VI_STRIP(i); \ - VI_ELEMENT_SKIP(i); \ - \ - for (reg_t fn = 0; fn < nf; ++fn) { \ - uint64_t val; \ - try { \ - val = MMU.load_##elt_width( \ - baseAddr + (i * nf + fn) * sizeof(elt_width##_t)); \ - } catch (trap_t& t) { \ - if (i == 0) \ - throw; /* Only take exception on zeroth element */ \ - /* Reduce VL if an exception occurs on a later element */ \ - early_stop = true; \ - P.VU.vl->write_raw(i); \ - break; \ - } \ - p->VU.elt(rd_num + fn * emul, vreg_inx, true) = val; \ - } \ - \ - if (early_stop) { \ - break; \ - } \ - } \ - p->VU.vstart->write(0); - -#define VI_LD_WHOLE(elt_width) \ - require_vector_novtype(true, false); \ - const reg_t baseAddr = RS1; \ - const reg_t vd = insn.rd(); \ - const reg_t len = insn.v_nf() + 1; \ - require_align(vd, len); \ - const reg_t elt_per_reg = P.VU.vlenb / sizeof(elt_width ## _t); \ - const reg_t size = len * elt_per_reg; \ - if (P.VU.vstart->read() < size) { \ - reg_t i = P.VU.vstart->read() / elt_per_reg; \ - reg_t off = P.VU.vstart->read() % elt_per_reg; \ - if (off) { \ - for (reg_t pos = off; pos < elt_per_reg; ++pos) { \ - auto val = MMU.load_## elt_width(baseAddr + \ - P.VU.vstart->read() * sizeof(elt_width ## _t)); \ - P.VU.elt(vd + i, pos, true) = val; \ - P.VU.vstart->write(P.VU.vstart->read() + 1); \ - } \ - ++i; \ - } \ - for (; i < len; ++i) { \ - for (reg_t pos = 0; pos < elt_per_reg; ++pos) { \ - auto val = MMU.load_## elt_width(baseAddr + \ - P.VU.vstart->read() * sizeof(elt_width ## _t)); \ - P.VU.elt(vd + i, pos, true) = val; \ - P.VU.vstart->write(P.VU.vstart->read() + 1); \ - } \ - } \ - } \ - P.VU.vstart->write(0); - -#define VI_ST_WHOLE \ - require_vector_novtype(true, false); \ - const reg_t baseAddr = RS1; \ - const reg_t vs3 = insn.rd(); \ - const reg_t len = insn.v_nf() + 1; \ - require_align(vs3, len); \ - const reg_t size = len * P.VU.vlenb; \ - \ - if (P.VU.vstart->read() < size) { \ - reg_t i = P.VU.vstart->read() / P.VU.vlenb; \ - reg_t off = P.VU.vstart->read() % P.VU.vlenb; \ - if (off) { \ - for (reg_t pos = off; pos < P.VU.vlenb; ++pos) { \ - auto val = P.VU.elt(vs3 + i, pos); \ - MMU.store_uint8(baseAddr + P.VU.vstart->read(), val); \ - P.VU.vstart->write(P.VU.vstart->read() + 1); \ - } \ - i++; \ - } \ - for (; i < len; ++i) { \ - for (reg_t pos = 0; pos < P.VU.vlenb; ++pos) { \ - auto val = P.VU.elt(vs3 + i, pos); \ - MMU.store_uint8(baseAddr + P.VU.vstart->read(), val); \ - P.VU.vstart->write(P.VU.vstart->read() + 1); \ - } \ - } \ - } \ - P.VU.vstart->write(0); - -// -// vector: amo -// -#define VI_AMO(op, type, idx_type) \ - require_vector(false); \ - require_align(insn.rd(), P.VU.vflmul); \ - require(P.VU.vsew <= P.get_xlen() && P.VU.vsew >= 32); \ - require_align(insn.rd(), P.VU.vflmul); \ - float vemul = ((float)idx_type / P.VU.vsew * P.VU.vflmul); \ - require(vemul >= 0.125 && vemul <= 8); \ - require_align(insn.rs2(), vemul); \ - if (insn.v_wd()) {\ - require_vm; \ - if (idx_type > P.VU.vsew) { \ - if (insn.rd() != insn.rs2()) \ - require_noover(insn.rd(), P.VU.vflmul, insn.rs2(), vemul); \ - } else if (idx_type < P.VU.vsew) { \ - if (vemul < 1) {\ - require_noover(insn.rd(), P.VU.vflmul, insn.rs2(), vemul); \ - } else {\ - require_noover_widen(insn.rd(), P.VU.vflmul, insn.rs2(), vemul); \ - } \ - } \ - } \ - VI_DUPLICATE_VREG(insn.rs2(), idx_type); \ - const reg_t vl = P.VU.vl->read(); \ - const reg_t baseAddr = RS1; \ - const reg_t vd = insn.rd(); \ - for (reg_t i = P.VU.vstart->read(); i < vl; ++i) { \ - VI_ELEMENT_SKIP(i); \ - VI_STRIP(i); \ - P.VU.vstart->write(i); \ - switch (P.VU.vsew) { \ - case e32: {\ - auto vs3 = P.VU.elt< type ## 32_t>(vd, vreg_inx); \ - auto val = MMU.amo_uint32(baseAddr + index[i], [&]( type ## 32_t lhs) { op }); \ - if (insn.v_wd()) \ - P.VU.elt< type ## 32_t>(vd, vreg_inx, true) = val; \ - } \ - break; \ - case e64: {\ - auto vs3 = P.VU.elt< type ## 64_t>(vd, vreg_inx); \ - auto val = MMU.amo_uint64(baseAddr + index[i], [&]( type ## 64_t lhs) { op }); \ - if (insn.v_wd()) \ - P.VU.elt< type ## 64_t>(vd, vreg_inx, true) = val; \ - } \ - break; \ - default: \ - require(0); \ - break; \ - } \ - } \ - P.VU.vstart->write(0); - -// vector: sign/unsiged extension -#define VI_VV_EXT(div, type) \ - require(insn.rd() != insn.rs2()); \ - require_vm; \ - reg_t from = P.VU.vsew / div; \ - require(from >= e8 && from <= e64); \ - require(((float)P.VU.vflmul / div) >= 0.125 && ((float)P.VU.vflmul / div) <= 8 ); \ - require_align(insn.rd(), P.VU.vflmul); \ - require_align(insn.rs2(), P.VU.vflmul / div); \ - if ((P.VU.vflmul / div) < 1) { \ - require_noover(insn.rd(), P.VU.vflmul, insn.rs2(), P.VU.vflmul / div); \ - } else {\ - require_noover_widen(insn.rd(), P.VU.vflmul, insn.rs2(), P.VU.vflmul / div); \ - } \ - reg_t pat = (((P.VU.vsew >> 3) << 4) | from >> 3); \ - VI_GENERAL_LOOP_BASE \ - VI_LOOP_ELEMENT_SKIP(); \ - switch (pat) { \ - case 0x21: \ - P.VU.elt(rd_num, i, true) = P.VU.elt(rs2_num, i); \ - break; \ - case 0x41: \ - P.VU.elt(rd_num, i, true) = P.VU.elt(rs2_num, i); \ - break; \ - case 0x81: \ - P.VU.elt(rd_num, i, true) = P.VU.elt(rs2_num, i); \ - break; \ - case 0x42: \ - P.VU.elt(rd_num, i, true) = P.VU.elt(rs2_num, i); \ - break; \ - case 0x82: \ - P.VU.elt(rd_num, i, true) = P.VU.elt(rs2_num, i); \ - break; \ - case 0x84: \ - P.VU.elt(rd_num, i, true) = P.VU.elt(rs2_num, i); \ - break; \ - case 0x88: \ - P.VU.elt(rd_num, i, true) = P.VU.elt(rs2_num, i); \ - break; \ - default: \ - break; \ - } \ - VI_LOOP_END - -// -// vector: vfp helper -// -#define VI_VFP_COMMON \ - require_fp; \ - require((P.VU.vsew == e16 && p->extension_enabled(EXT_ZFH)) || \ - (P.VU.vsew == e32 && p->extension_enabled('F')) || \ - (P.VU.vsew == e64 && p->extension_enabled('D'))); \ - require_vector(true);\ - require(STATE.frm->read() < 0x5);\ - reg_t vl = P.VU.vl->read(); \ - reg_t rd_num = insn.rd(); \ - reg_t rs1_num = insn.rs1(); \ - reg_t rs2_num = insn.rs2(); \ - softfloat_roundingMode = STATE.frm->read(); - -#define VI_VFP_LOOP_BASE \ - VI_VFP_COMMON \ - for (reg_t i=P.VU.vstart->read(); iread(); i < vl; ++i) { \ - VI_LOOP_ELEMENT_SKIP(); \ - uint64_t mmask = UINT64_C(1) << mpos; \ - uint64_t &vd = P.VU.elt(rd_num, midx, true); \ - uint64_t res = 0; - -#define VI_VFP_LOOP_REDUCTION_BASE(width) \ - float##width##_t vd_0 = P.VU.elt(rd_num, 0); \ - float##width##_t vs1_0 = P.VU.elt(rs1_num, 0); \ - vd_0 = vs1_0; \ - bool is_active = false; \ - for (reg_t i=P.VU.vstart->read(); i(rs2_num, i); \ - is_active = true; \ - -#define VI_VFP_LOOP_WIDE_REDUCTION_BASE \ - VI_VFP_COMMON \ - float64_t vd_0 = f64(P.VU.elt(rs1_num, 0).v); \ - for (reg_t i=P.VU.vstart->read(); iwrite(0); \ - -#define VI_VFP_LOOP_REDUCTION_END(x) \ - } \ - P.VU.vstart->write(0); \ - if (vl > 0) { \ - if (is_propagate && !is_active) { \ - switch (x) { \ - case e16: {\ - auto ret = f16_classify(f16(vd_0.v)); \ - if (ret & 0x300) { \ - if (ret & 0x100) { \ - softfloat_exceptionFlags |= softfloat_flag_invalid; \ - set_fp_exceptions; \ - } \ - P.VU.elt(rd_num, 0, true) = defaultNaNF16UI; \ - } else { \ - P.VU.elt(rd_num, 0, true) = vd_0.v; \ - } \ - } \ - break; \ - case e32: { \ - auto ret = f32_classify(f32(vd_0.v)); \ - if (ret & 0x300) { \ - if (ret & 0x100) { \ - softfloat_exceptionFlags |= softfloat_flag_invalid; \ - set_fp_exceptions; \ - } \ - P.VU.elt(rd_num, 0, true) = defaultNaNF32UI; \ - } else { \ - P.VU.elt(rd_num, 0, true) = vd_0.v; \ - } \ - } \ - break; \ - case e64: {\ - auto ret = f64_classify(f64(vd_0.v)); \ - if (ret & 0x300) { \ - if (ret & 0x100) { \ - softfloat_exceptionFlags |= softfloat_flag_invalid; \ - set_fp_exceptions; \ - } \ - P.VU.elt(rd_num, 0, true) = defaultNaNF64UI; \ - } else { \ - P.VU.elt(rd_num, 0, true) = vd_0.v; \ - } \ - } \ - break; \ - } \ - } else { \ - P.VU.elt::type>(rd_num, 0, true) = vd_0.v; \ - } \ - } - -#define VI_VFP_LOOP_CMP_END \ - switch(P.VU.vsew) { \ - case e16: \ - case e32: \ - case e64: { \ - vd = (vd & ~mmask) | (((res) << mpos) & mmask); \ - break; \ - } \ - default: \ - require(0); \ - break; \ - }; \ - } \ - P.VU.vstart->write(0); - -#define VI_VFP_VV_LOOP(BODY16, BODY32, BODY64) \ - VI_CHECK_SSS(true); \ - VI_VFP_LOOP_BASE \ - switch(P.VU.vsew) { \ - case e16: {\ - VFP_VV_PARAMS(16); \ - BODY16; \ - set_fp_exceptions; \ - break; \ - }\ - case e32: {\ - VFP_VV_PARAMS(32); \ - BODY32; \ - set_fp_exceptions; \ - break; \ - }\ - case e64: {\ - VFP_VV_PARAMS(64); \ - BODY64; \ - set_fp_exceptions; \ - break; \ - }\ - default: \ - require(0); \ - break; \ - }; \ - DEBUG_RVV_FP_VV; \ - VI_VFP_LOOP_END - -#define VI_VFP_V_LOOP(BODY16, BODY32, BODY64) \ - VI_CHECK_SSS(false); \ - VI_VFP_LOOP_BASE \ - switch(P.VU.vsew) { \ - case e16: {\ - VFP_V_PARAMS(16); \ - BODY16; \ - break; \ - }\ - case e32: {\ - VFP_V_PARAMS(32); \ - BODY32; \ - break; \ - }\ - case e64: {\ - VFP_V_PARAMS(64); \ - BODY64; \ - break; \ - }\ - default: \ - require(0); \ - break; \ - }; \ - set_fp_exceptions; \ - VI_VFP_LOOP_END - -#define VI_VFP_VV_LOOP_REDUCTION(BODY16, BODY32, BODY64) \ - VI_CHECK_REDUCTION(false) \ - VI_VFP_COMMON \ - switch(P.VU.vsew) { \ - case e16: {\ - VI_VFP_LOOP_REDUCTION_BASE(16) \ - BODY16; \ - set_fp_exceptions; \ - VI_VFP_LOOP_REDUCTION_END(e16) \ - break; \ - }\ - case e32: {\ - VI_VFP_LOOP_REDUCTION_BASE(32) \ - BODY32; \ - set_fp_exceptions; \ - VI_VFP_LOOP_REDUCTION_END(e32) \ - break; \ - }\ - case e64: {\ - VI_VFP_LOOP_REDUCTION_BASE(64) \ - BODY64; \ - set_fp_exceptions; \ - VI_VFP_LOOP_REDUCTION_END(e64) \ - break; \ - }\ - default: \ - require(0); \ - break; \ - }; \ - -#define VI_VFP_VV_LOOP_WIDE_REDUCTION(BODY16, BODY32) \ - VI_CHECK_REDUCTION(true) \ - VI_VFP_COMMON \ - require((P.VU.vsew == e16 && p->extension_enabled('F')) || \ - (P.VU.vsew == e32 && p->extension_enabled('D'))); \ - bool is_active = false; \ - switch(P.VU.vsew) { \ - case e16: {\ - float32_t vd_0 = P.VU.elt(rs1_num, 0); \ - for (reg_t i=P.VU.vstart->read(); i(rs2_num, i)); \ - BODY16; \ - set_fp_exceptions; \ - VI_VFP_LOOP_REDUCTION_END(e32) \ - break; \ - }\ - case e32: {\ - float64_t vd_0 = P.VU.elt(rs1_num, 0); \ - for (reg_t i=P.VU.vstart->read(); i(rs2_num, i)); \ - BODY32; \ - set_fp_exceptions; \ - VI_VFP_LOOP_REDUCTION_END(e64) \ - break; \ - }\ - default: \ - require(0); \ - break; \ - }; \ - -#define VI_VFP_VF_LOOP(BODY16, BODY32, BODY64) \ - VI_CHECK_SSS(false); \ - VI_VFP_LOOP_BASE \ - switch(P.VU.vsew) { \ - case e16: {\ - VFP_VF_PARAMS(16); \ - BODY16; \ - set_fp_exceptions; \ - break; \ - }\ - case e32: {\ - VFP_VF_PARAMS(32); \ - BODY32; \ - set_fp_exceptions; \ - break; \ - }\ - case e64: {\ - VFP_VF_PARAMS(64); \ - BODY64; \ - set_fp_exceptions; \ - break; \ - }\ - default: \ - require(0); \ - break; \ - }; \ - DEBUG_RVV_FP_VF; \ - VI_VFP_LOOP_END - -#define VI_VFP_VV_LOOP_CMP(BODY16, BODY32, BODY64) \ - VI_CHECK_MSS(true); \ - VI_VFP_LOOP_CMP_BASE \ - switch(P.VU.vsew) { \ - case e16: {\ - VFP_VV_PARAMS(16); \ - BODY16; \ - set_fp_exceptions; \ - break; \ - }\ - case e32: {\ - VFP_VV_PARAMS(32); \ - BODY32; \ - set_fp_exceptions; \ - break; \ - }\ - case e64: {\ - VFP_VV_PARAMS(64); \ - BODY64; \ - set_fp_exceptions; \ - break; \ - }\ - default: \ - require(0); \ - break; \ - }; \ - VI_VFP_LOOP_CMP_END \ - -#define VI_VFP_VF_LOOP_CMP(BODY16, BODY32, BODY64) \ - VI_CHECK_MSS(false); \ - VI_VFP_LOOP_CMP_BASE \ - switch(P.VU.vsew) { \ - case e16: {\ - VFP_VF_PARAMS(16); \ - BODY16; \ - set_fp_exceptions; \ - break; \ - }\ - case e32: {\ - VFP_VF_PARAMS(32); \ - BODY32; \ - set_fp_exceptions; \ - break; \ - }\ - case e64: {\ - VFP_VF_PARAMS(64); \ - BODY64; \ - set_fp_exceptions; \ - break; \ - }\ - default: \ - require(0); \ - break; \ - }; \ - VI_VFP_LOOP_CMP_END \ - -#define VI_VFP_VF_LOOP_WIDE(BODY16, BODY32) \ - VI_CHECK_DSS(false); \ - VI_VFP_LOOP_BASE \ - switch(P.VU.vsew) { \ - case e16: { \ - float32_t &vd = P.VU.elt(rd_num, i, true); \ - float32_t vs2 = f16_to_f32(P.VU.elt(rs2_num, i)); \ - float32_t rs1 = f16_to_f32(f16(READ_FREG(rs1_num))); \ - BODY16; \ - set_fp_exceptions; \ - break; \ - } \ - case e32: {\ - float64_t &vd = P.VU.elt(rd_num, i, true); \ - float64_t vs2 = f32_to_f64(P.VU.elt(rs2_num, i)); \ - float64_t rs1 = f32_to_f64(f32(READ_FREG(rs1_num))); \ - BODY32; \ - set_fp_exceptions; \ - break; \ - }\ - default: \ - require(0); \ - break; \ - }; \ - DEBUG_RVV_FP_VV; \ - VI_VFP_LOOP_END - - -#define VI_VFP_VV_LOOP_WIDE(BODY16, BODY32) \ - VI_CHECK_DSS(true); \ - VI_VFP_LOOP_BASE \ - switch(P.VU.vsew) { \ - case e16: {\ - float32_t &vd = P.VU.elt(rd_num, i, true); \ - float32_t vs2 = f16_to_f32(P.VU.elt(rs2_num, i)); \ - float32_t vs1 = f16_to_f32(P.VU.elt(rs1_num, i)); \ - BODY16; \ - set_fp_exceptions; \ - break; \ - }\ - case e32: {\ - float64_t &vd = P.VU.elt(rd_num, i, true); \ - float64_t vs2 = f32_to_f64(P.VU.elt(rs2_num, i)); \ - float64_t vs1 = f32_to_f64(P.VU.elt(rs1_num, i)); \ - BODY32; \ - set_fp_exceptions; \ - break; \ - }\ - default: \ - require(0); \ - break; \ - }; \ - DEBUG_RVV_FP_VV; \ - VI_VFP_LOOP_END - -#define VI_VFP_WF_LOOP_WIDE(BODY16, BODY32) \ - VI_CHECK_DDS(false); \ - VI_VFP_LOOP_BASE \ - switch(P.VU.vsew) { \ - case e16: {\ - float32_t &vd = P.VU.elt(rd_num, i, true); \ - float32_t vs2 = P.VU.elt(rs2_num, i); \ - float32_t rs1 = f16_to_f32(f16(READ_FREG(rs1_num))); \ - BODY16; \ - set_fp_exceptions; \ - break; \ - }\ - case e32: {\ - float64_t &vd = P.VU.elt(rd_num, i, true); \ - float64_t vs2 = P.VU.elt(rs2_num, i); \ - float64_t rs1 = f32_to_f64(f32(READ_FREG(rs1_num))); \ - BODY32; \ - set_fp_exceptions; \ - break; \ - }\ - default: \ - require(0); \ - }; \ - DEBUG_RVV_FP_VV; \ - VI_VFP_LOOP_END - -#define VI_VFP_WV_LOOP_WIDE(BODY16, BODY32) \ - VI_CHECK_DDS(true); \ - VI_VFP_LOOP_BASE \ - switch(P.VU.vsew) { \ - case e16: {\ - float32_t &vd = P.VU.elt(rd_num, i, true); \ - float32_t vs2 = P.VU.elt(rs2_num, i); \ - float32_t vs1 = f16_to_f32(P.VU.elt(rs1_num, i)); \ - BODY16; \ - set_fp_exceptions; \ - break; \ - }\ - case e32: {\ - float64_t &vd = P.VU.elt(rd_num, i, true); \ - float64_t vs2 = P.VU.elt(rs2_num, i); \ - float64_t vs1 = f32_to_f64(P.VU.elt(rs1_num, i)); \ - BODY32; \ - set_fp_exceptions; \ - break; \ - }\ - default: \ - require(0); \ - }; \ - DEBUG_RVV_FP_VV; \ - VI_VFP_LOOP_END - -#define VI_VFP_LOOP_SCALE_BASE \ - require_fp; \ - require_vector(true);\ - require(STATE.frm->read() < 0x5);\ - reg_t vl = P.VU.vl->read(); \ - reg_t rd_num = insn.rd(); \ - reg_t rs1_num = insn.rs1(); \ - reg_t rs2_num = insn.rs2(); \ - softfloat_roundingMode = STATE.frm->read(); \ - for (reg_t i=P.VU.vstart->read(); iextension_enabled(EXT_ZFH); }, \ - BODY16); } \ - break; \ - case e32: \ - { VI_VFP_CVT_LOOP(CVT_INT_TO_FP_PARAMS(32, 32, sign), \ - { p->extension_enabled('F'); }, \ - BODY32); } \ - break; \ - case e64: \ - { VI_VFP_CVT_LOOP(CVT_INT_TO_FP_PARAMS(64, 64, sign), \ - { p->extension_enabled('D'); }, \ - BODY64); } \ - break; \ - default: \ - require(0); \ - break; \ - } - -#define VI_VFP_CVT_FP_TO_INT(BODY16, BODY32, BODY64, sign) \ - VI_CHECK_SSS(false); \ - switch(P.VU.vsew) { \ - case e16: \ - { VI_VFP_CVT_LOOP(CVT_FP_TO_INT_PARAMS(16, 16, sign), \ - { p->extension_enabled(EXT_ZFH); }, \ - BODY16); } \ - break; \ - case e32: \ - { VI_VFP_CVT_LOOP(CVT_FP_TO_INT_PARAMS(32, 32, sign), \ - { p->extension_enabled('F'); }, \ - BODY32); } \ - break; \ - case e64: \ - { VI_VFP_CVT_LOOP(CVT_FP_TO_INT_PARAMS(64, 64, sign), \ - { p->extension_enabled('D'); }, \ - BODY64); } \ - break; \ - default: \ - require(0); \ - break; \ - } - -#define VI_VFP_WCVT_FP_TO_FP(BODY8, BODY16, BODY32, \ - CHECK8, CHECK16, CHECK32) \ - VI_CHECK_DSS(false); \ - switch(P.VU.vsew) { \ - case e16: \ - { VI_VFP_CVT_LOOP(CVT_FP_TO_FP_PARAMS(16, 32), CHECK16, BODY16); } \ - break; \ - case e32: \ - { VI_VFP_CVT_LOOP(CVT_FP_TO_FP_PARAMS(32, 64), CHECK32, BODY32); } \ - break; \ - default: \ - require(0); \ - break; \ - } - -#define VI_VFP_WCVT_INT_TO_FP(BODY8, BODY16, BODY32, \ - CHECK8, CHECK16, CHECK32, \ - sign) \ - VI_CHECK_DSS(false); \ - switch(P.VU.vsew) { \ - case e8: \ - { VI_VFP_CVT_LOOP(CVT_INT_TO_FP_PARAMS(8, 16, sign), CHECK8, BODY8); } \ - break; \ - case e16: \ - { VI_VFP_CVT_LOOP(CVT_INT_TO_FP_PARAMS(16, 32, sign), CHECK16, BODY16); } \ - break; \ - case e32: \ - { VI_VFP_CVT_LOOP(CVT_INT_TO_FP_PARAMS(32, 64, sign), CHECK32, BODY32); } \ - break; \ - default: \ - require(0); \ - break; \ - } - -#define VI_VFP_WCVT_FP_TO_INT(BODY8, BODY16, BODY32, \ - CHECK8, CHECK16, CHECK32, \ - sign) \ - VI_CHECK_DSS(false); \ - switch(P.VU.vsew) { \ - case e16: \ - { VI_VFP_CVT_LOOP(CVT_FP_TO_INT_PARAMS(16, 32, sign), CHECK16, BODY16); } \ - break; \ - case e32: \ - { VI_VFP_CVT_LOOP(CVT_FP_TO_INT_PARAMS(32, 64, sign), CHECK32, BODY32); } \ - break; \ - default: \ - require(0); \ - break; \ - } - -#define VI_VFP_NCVT_FP_TO_FP(BODY8, BODY16, BODY32, \ - CHECK8, CHECK16, CHECK32) \ - VI_CHECK_SDS(false); \ - switch(P.VU.vsew) { \ - case e16: \ - { VI_VFP_CVT_LOOP(CVT_FP_TO_FP_PARAMS(32, 16), CHECK16, BODY16); } \ - break; \ - case e32: \ - { VI_VFP_CVT_LOOP(CVT_FP_TO_FP_PARAMS(64, 32), CHECK32, BODY32); } \ - break; \ - default: \ - require(0); \ - break; \ - } - -#define VI_VFP_NCVT_INT_TO_FP(BODY8, BODY16, BODY32, \ - CHECK8, CHECK16, CHECK32, \ - sign) \ - VI_CHECK_SDS(false); \ - switch(P.VU.vsew) { \ - case e16: \ - { VI_VFP_CVT_LOOP(CVT_INT_TO_FP_PARAMS(32, 16, sign), CHECK16, BODY16); } \ - break; \ - case e32: \ - { VI_VFP_CVT_LOOP(CVT_INT_TO_FP_PARAMS(64, 32, sign), CHECK32, BODY32); } \ - break; \ - default: \ - require(0); \ - break; \ - } - -#define VI_VFP_NCVT_FP_TO_INT(BODY8, BODY16, BODY32, \ - CHECK8, CHECK16, CHECK32, \ - sign) \ - VI_CHECK_SDS(false); \ - switch(P.VU.vsew) { \ - case e8: \ - { VI_VFP_CVT_LOOP(CVT_FP_TO_INT_PARAMS(16, 8, sign), CHECK8, BODY8); } \ - break; \ - case e16: \ - { VI_VFP_CVT_LOOP(CVT_FP_TO_INT_PARAMS(32, 16, sign), CHECK16, BODY16); } \ - break; \ - case e32: \ - { VI_VFP_CVT_LOOP(CVT_FP_TO_INT_PARAMS(64, 32, sign), CHECK32, BODY32); } \ - break; \ - default: \ - require(0); \ - break; \ - } - -// The p-extension support is contributed by -// Programming Langauge Lab, Department of Computer Science, National Tsing-Hua University, Taiwan - -#define P_FIELD(R, INDEX, SIZE) \ - (type_sew_t::type)get_field(R, make_mask64(((INDEX) * SIZE), SIZE)) - -#define P_UFIELD(R, INDEX, SIZE) \ - (type_usew_t::type)get_field(R, make_mask64(((INDEX) * SIZE), SIZE)) - -#define P_B(R, INDEX) P_UFIELD(R, INDEX, 8) -#define P_H(R, INDEX) P_UFIELD(R, INDEX, 16) -#define P_W(R, INDEX) P_UFIELD(R, INDEX, 32) -#define P_SB(R, INDEX) P_FIELD(R, INDEX, 8) -#define P_SH(R, INDEX) P_FIELD(R, INDEX, 16) -#define P_SW(R, INDEX) P_FIELD(R, INDEX, 32) - -#define READ_REG_PAIR(reg) ({ \ - require((reg) % 2 == 0); \ - (reg) == 0 ? reg_t(0) : \ - (READ_REG((reg) + 1) << 32) + zext32(READ_REG(reg)); }) - -#define RS1_PAIR READ_REG_PAIR(insn.rs1()) -#define RS2_PAIR READ_REG_PAIR(insn.rs2()) -#define RD_PAIR READ_REG_PAIR(insn.rd()) - -#define WRITE_PD() \ - rd_tmp = set_field(rd_tmp, make_mask64((i * sizeof(pd) * 8), sizeof(pd) * 8), pd); - -#define WRITE_RD_PAIR(value) \ - if (insn.rd() != 0) { \ - require(insn.rd() % 2 == 0); \ - WRITE_REG(insn.rd(), sext32(value)); \ - WRITE_REG(insn.rd() + 1, (sreg_t(value)) >> 32); \ - } - -#define P_SET_OV(ov) \ - if (ov) P.VU.vxsat->write(1); - -#define P_SAT(R, BIT) \ - if (R > INT##BIT##_MAX) { \ - R = INT##BIT##_MAX; \ - P_SET_OV(1); \ - } else if (R < INT##BIT##_MIN) { \ - R = INT##BIT##_MIN; \ - P_SET_OV(1); \ - } - -#define P_SATU(R, BIT) \ - if (R > UINT##BIT##_MAX) { \ - R = UINT##BIT##_MAX; \ - P_SET_OV(1); \ - } else if (R < 0) { \ - P_SET_OV(1); \ - R = 0; \ - } - -#define P_LOOP_BASE(BIT) \ - require_extension(EXT_ZPN); \ - require(BIT == e8 || BIT == e16 || BIT == e32); \ - reg_t rd_tmp = RD; \ - reg_t rs1 = RS1; \ - reg_t rs2 = RS2; \ - sreg_t len = xlen / BIT; \ - for (sreg_t i = len - 1; i >= 0; --i) { - -#define P_ONE_LOOP_BASE(BIT) \ - require_extension(EXT_ZPN); \ - require(BIT == e8 || BIT == e16 || BIT == e32); \ - reg_t rd_tmp = RD; \ - reg_t rs1 = RS1; \ - sreg_t len = xlen / BIT; \ - for (sreg_t i = len - 1; i >= 0; --i) { - -#define P_I_LOOP_BASE(BIT, IMMBIT) \ - require_extension(EXT_ZPN); \ - require(BIT == e8 || BIT == e16 || BIT == e32); \ - reg_t rd_tmp = RD; \ - reg_t rs1 = RS1; \ - type_usew_t::type imm##IMMBIT##u = insn.p_imm##IMMBIT(); \ - sreg_t len = xlen / BIT; \ - for (sreg_t i = len - 1; i >= 0; --i) { - -#define P_X_LOOP_BASE(BIT, LOWBIT) \ - require_extension(EXT_ZPN); \ - require(BIT == e8 || BIT == e16 || BIT == e32); \ - reg_t rd_tmp = RD; \ - reg_t rs1 = RS1; \ - type_usew_t::type sa = RS2 & ((uint64_t(1) << LOWBIT) - 1); \ - type_sew_t::type ssa = int64_t(RS2) << (64 - LOWBIT) >> (64 - LOWBIT); \ - sreg_t len = xlen / BIT; \ - for (sreg_t i = len - 1; i >= 0; --i) { - -#define P_MUL_LOOP_BASE(BIT) \ - require_extension(EXT_ZPN); \ - require(BIT == e8 || BIT == e16 || BIT == e32); \ - reg_t rd_tmp = RD; \ - reg_t rs1 = RS1; \ - reg_t rs2 = RS2; \ - sreg_t len = 32 / BIT; \ - for (sreg_t i = len - 1; i >= 0; --i) { - -#define P_REDUCTION_LOOP_BASE(BIT, BIT_INNER, USE_RD) \ - require_extension(EXT_ZPN); \ - require(BIT == e16 || BIT == e32 || BIT == e64); \ - reg_t rd_tmp = USE_RD ? zext_xlen(RD) : 0; \ - reg_t rs1 = zext_xlen(RS1); \ - reg_t rs2 = zext_xlen(RS2); \ - sreg_t len = 64 / BIT; \ - sreg_t len_inner = BIT / BIT_INNER; \ - for (sreg_t i = len - 1; i >= 0; --i) { \ - sreg_t pd_res = P_FIELD(rd_tmp, i, BIT); \ - for (sreg_t j = i * len_inner; j < (i + 1) * len_inner; ++j) { - -#define P_REDUCTION_ULOOP_BASE(BIT, BIT_INNER, USE_RD) \ - require_extension(EXT_ZPN); \ - require(BIT == e16 || BIT == e32 || BIT == e64); \ - reg_t rd_tmp = USE_RD ? zext_xlen(RD) : 0; \ - reg_t rs1 = zext_xlen(RS1); \ - reg_t rs2 = zext_xlen(RS2); \ - sreg_t len = 64 / BIT; \ - sreg_t len_inner = BIT / BIT_INNER; \ - for (sreg_t i = len - 1; i >=0; --i) { \ - reg_t pd_res = P_UFIELD(rd_tmp, i, BIT); \ - for (sreg_t j = i * len_inner; j < (i + 1) * len_inner; ++j) { - -#define P_PARAMS(BIT) \ - auto pd = P_FIELD(rd_tmp, i, BIT); \ - auto ps1 = P_FIELD(rs1, i, BIT); \ - auto ps2 = P_FIELD(rs2, i, BIT); - -#define P_UPARAMS(BIT) \ - auto pd = P_UFIELD(rd_tmp, i, BIT); \ - auto ps1 = P_UFIELD(rs1, i, BIT); \ - auto ps2 = P_UFIELD(rs2, i, BIT); - -#define P_CORSS_PARAMS(BIT) \ - auto pd = P_FIELD(rd_tmp, i, BIT); \ - auto ps1 = P_FIELD(rs1, i, BIT); \ - auto ps2 = P_FIELD(rs2, (i ^ 1), BIT); - -#define P_CORSS_UPARAMS(BIT) \ - auto pd = P_UFIELD(rd_tmp, i, BIT); \ - auto ps1 = P_UFIELD(rs1, i, BIT); \ - auto ps2 = P_UFIELD(rs2, (i ^ 1), BIT); - -#define P_ONE_PARAMS(BIT) \ - auto pd = P_FIELD(rd_tmp, i, BIT); \ - auto ps1 = P_FIELD(rs1, i, BIT); - -#define P_ONE_UPARAMS(BIT) \ - auto pd = P_UFIELD(rd_tmp, i, BIT); \ - auto ps1 = P_UFIELD(rs1, i, BIT); - -#define P_ONE_SUPARAMS(BIT) \ - auto pd = P_UFIELD(rd_tmp, i, BIT); \ - auto ps1 = P_FIELD(rs1, i, BIT); - -#define P_MUL_PARAMS(BIT) \ - auto pd = P_FIELD(rd_tmp, i, BIT * 2); \ - auto ps1 = P_FIELD(rs1, i, BIT); \ - auto ps2 = P_FIELD(rs2, i, BIT); - -#define P_MUL_UPARAMS(BIT) \ - auto pd = P_UFIELD(rd_tmp, i, BIT * 2); \ - auto ps1 = P_UFIELD(rs1, i, BIT); \ - auto ps2 = P_UFIELD(rs2, i, BIT); - -#define P_MUL_CROSS_PARAMS(BIT) \ - auto pd = P_FIELD(rd_tmp, i, BIT * 2); \ - auto ps1 = P_FIELD(rs1, i, BIT); \ - auto ps2 = P_FIELD(rs2, (i ^ 1), BIT); - -#define P_MUL_CROSS_UPARAMS(BIT) \ - auto pd = P_UFIELD(rd_tmp, i, BIT*2); \ - auto ps1 = P_UFIELD(rs1, i, BIT); \ - auto ps2 = P_UFIELD(rs2, (i ^ 1), BIT); - -#define P_REDUCTION_PARAMS(BIT_INNER) \ - auto ps1 = P_FIELD(rs1, j, BIT_INNER); \ - auto ps2 = P_FIELD(rs2, j, BIT_INNER); - -#define P_REDUCTION_UPARAMS(BIT_INNER) \ - auto ps1 = P_UFIELD(rs1, j, BIT_INNER); \ - auto ps2 = P_UFIELD(rs2, j, BIT_INNER); - -#define P_REDUCTION_SUPARAMS(BIT_INNER) \ - auto ps1 = P_FIELD(rs1, j, BIT_INNER); \ - auto ps2 = P_UFIELD(rs2, j, BIT_INNER); - -#define P_REDUCTION_CROSS_PARAMS(BIT_INNER) \ - auto ps1 = P_FIELD(rs1, j, BIT_INNER); \ - auto ps2 = P_FIELD(rs2, (j ^ 1), BIT_INNER); - -#define P_LOOP_BODY(BIT, BODY) { \ - P_PARAMS(BIT) \ - BODY \ - WRITE_PD(); \ -} - -#define P_ULOOP_BODY(BIT, BODY) { \ - P_UPARAMS(BIT) \ - BODY \ - WRITE_PD(); \ -} - -#define P_ONE_LOOP_BODY(BIT, BODY) { \ - P_ONE_PARAMS(BIT) \ - BODY \ - WRITE_PD(); \ -} - -#define P_CROSS_LOOP_BODY(BIT, BODY) { \ - P_CORSS_PARAMS(BIT) \ - BODY \ - WRITE_PD(); \ -} - -#define P_CROSS_ULOOP_BODY(BIT, BODY) { \ - P_CORSS_UPARAMS(BIT) \ - BODY \ - WRITE_PD(); \ -} - -#define P_ONE_ULOOP_BODY(BIT, BODY) { \ - P_ONE_UPARAMS(BIT) \ - BODY \ - WRITE_PD(); \ -} - -#define P_MUL_LOOP_BODY(BIT, BODY) { \ - P_MUL_PARAMS(BIT) \ - BODY \ - WRITE_PD(); \ -} - -#define P_MUL_ULOOP_BODY(BIT, BODY) { \ - P_MUL_UPARAMS(BIT) \ - BODY \ - WRITE_PD(); \ -} - -#define P_MUL_CROSS_LOOP_BODY(BIT, BODY) { \ - P_MUL_CROSS_PARAMS(BIT) \ - BODY \ - WRITE_PD(); \ -} - -#define P_MUL_CROSS_ULOOP_BODY(BIT, BODY) { \ - P_MUL_CROSS_UPARAMS(BIT) \ - BODY \ - WRITE_PD(); \ -} - -#define P_LOOP(BIT, BODY) \ - P_LOOP_BASE(BIT) \ - P_LOOP_BODY(BIT, BODY) \ - P_LOOP_END() - -#define P_ONE_LOOP(BIT, BODY) \ - P_ONE_LOOP_BASE(BIT) \ - P_ONE_LOOP_BODY(BIT, BODY) \ - P_LOOP_END() - -#define P_ULOOP(BIT, BODY) \ - P_LOOP_BASE(BIT) \ - P_ULOOP_BODY(BIT, BODY) \ - P_LOOP_END() - -#define P_CROSS_LOOP(BIT, BODY1, BODY2) \ - P_LOOP_BASE(BIT) \ - P_CROSS_LOOP_BODY(BIT, BODY1) \ - --i; \ - if (sizeof(#BODY2) == 1) { \ - P_CROSS_LOOP_BODY(BIT, BODY1) \ - } \ - else { \ - P_CROSS_LOOP_BODY(BIT, BODY2) \ - } \ - P_LOOP_END() - -#define P_CROSS_ULOOP(BIT, BODY1, BODY2) \ - P_LOOP_BASE(BIT) \ - P_CROSS_ULOOP_BODY(BIT, BODY1) \ - --i; \ - P_CROSS_ULOOP_BODY(BIT, BODY2) \ - P_LOOP_END() - -#define P_STRAIGHT_LOOP(BIT, BODY1, BODY2) \ - P_LOOP_BASE(BIT) \ - P_LOOP_BODY(BIT, BODY1) \ - --i; \ - P_LOOP_BODY(BIT, BODY2) \ - P_LOOP_END() - -#define P_STRAIGHT_ULOOP(BIT, BODY1, BODY2) \ - P_LOOP_BASE(BIT) \ - P_ULOOP_BODY(BIT, BODY1) \ - --i; \ - P_ULOOP_BODY(BIT, BODY2) \ - P_LOOP_END() - -#define P_X_LOOP(BIT, RS2_LOW_BIT, BODY) \ - P_X_LOOP_BASE(BIT, RS2_LOW_BIT) \ - P_ONE_LOOP_BODY(BIT, BODY) \ - P_LOOP_END() - -#define P_X_ULOOP(BIT, RS2_LOW_BIT, BODY) \ - P_X_LOOP_BASE(BIT, RS2_LOW_BIT) \ - P_ONE_ULOOP_BODY(BIT, BODY) \ - P_LOOP_END() - -#define P_I_LOOP(BIT, IMMBIT, BODY) \ - P_I_LOOP_BASE(BIT, IMMBIT) \ - P_ONE_LOOP_BODY(BIT, BODY) \ - P_LOOP_END() - -#define P_I_ULOOP(BIT, IMMBIT, BODY) \ - P_I_LOOP_BASE(BIT, IMMBIT) \ - P_ONE_ULOOP_BODY(BIT, BODY) \ - P_LOOP_END() - -#define P_MUL_LOOP(BIT, BODY) \ - P_MUL_LOOP_BASE(BIT) \ - P_MUL_LOOP_BODY(BIT, BODY) \ - P_PAIR_LOOP_END() - -#define P_MUL_ULOOP(BIT, BODY) \ - P_MUL_LOOP_BASE(BIT) \ - P_MUL_ULOOP_BODY(BIT, BODY) \ - P_PAIR_LOOP_END() - -#define P_MUL_CROSS_LOOP(BIT, BODY) \ - P_MUL_LOOP_BASE(BIT) \ - P_MUL_CROSS_LOOP_BODY(BIT, BODY) \ - P_PAIR_LOOP_END() - -#define P_MUL_CROSS_ULOOP(BIT, BODY) \ - P_MUL_LOOP_BASE(BIT) \ - P_MUL_CROSS_ULOOP_BODY(BIT, BODY) \ - P_PAIR_LOOP_END() - -#define P_REDUCTION_LOOP(BIT, BIT_INNER, USE_RD, IS_SAT, BODY) \ - P_REDUCTION_LOOP_BASE(BIT, BIT_INNER, USE_RD) \ - P_REDUCTION_PARAMS(BIT_INNER) \ - BODY \ - P_REDUCTION_LOOP_END(BIT, IS_SAT) - -#define P_REDUCTION_ULOOP(BIT, BIT_INNER, USE_RD, IS_SAT, BODY) \ - P_REDUCTION_ULOOP_BASE(BIT, BIT_INNER, USE_RD) \ - P_REDUCTION_UPARAMS(BIT_INNER) \ - BODY \ - P_REDUCTION_ULOOP_END(BIT, IS_SAT) - -#define P_REDUCTION_SULOOP(BIT, BIT_INNER, USE_RD, IS_SAT, BODY) \ - P_REDUCTION_LOOP_BASE(BIT, BIT_INNER, USE_RD) \ - P_REDUCTION_SUPARAMS(BIT_INNER) \ - BODY \ - P_REDUCTION_LOOP_END(BIT, IS_SAT) - -#define P_REDUCTION_CROSS_LOOP(BIT, BIT_INNER, USE_RD, IS_SAT, BODY) \ - P_REDUCTION_LOOP_BASE(BIT, BIT_INNER, USE_RD) \ - P_REDUCTION_CROSS_PARAMS(BIT_INNER) \ - BODY \ - P_REDUCTION_LOOP_END(BIT, IS_SAT) - -#define P_LOOP_END() \ - } \ - WRITE_RD(sext_xlen(rd_tmp)); - -#define P_PAIR_LOOP_END() \ - } \ - if (xlen == 32) { \ - WRITE_RD_PAIR(rd_tmp); \ - } \ - else { \ - WRITE_RD(sext_xlen(rd_tmp)); \ - } - -#define P_REDUCTION_LOOP_END(BIT, IS_SAT) \ - } \ - if (IS_SAT) { \ - P_SAT(pd_res, BIT); \ - } \ - type_usew_t::type pd = pd_res; \ - WRITE_PD(); \ - } \ - WRITE_RD(sext_xlen(rd_tmp)); - -#define P_REDUCTION_ULOOP_END(BIT, IS_SAT) \ - } \ - if (IS_SAT) { \ - P_SATU(pd_res, BIT); \ - } \ - type_usew_t::type pd = pd_res; \ - WRITE_PD(); \ - } \ - WRITE_RD(sext_xlen(rd_tmp)); - -#define P_SUNPKD8(X, Y) \ - require_extension(EXT_ZPN); \ - reg_t rd_tmp = 0; \ - int16_t pd[4] = { \ - P_SB(RS1, Y), \ - P_SB(RS1, X), \ - P_SB(RS1, Y + 4), \ - P_SB(RS1, X + 4), \ - }; \ - if (xlen == 64) { \ - memcpy(&rd_tmp, pd, 8); \ - } else { \ - memcpy(&rd_tmp, pd, 4); \ - } \ - WRITE_RD(sext_xlen(rd_tmp)); - -#define P_ZUNPKD8(X, Y) \ - require_extension(EXT_ZPN); \ - reg_t rd_tmp = 0; \ - uint16_t pd[4] = { \ - P_B(RS1, Y), \ - P_B(RS1, X), \ - P_B(RS1, Y + 4), \ - P_B(RS1, X + 4), \ - }; \ - if (xlen == 64) { \ - memcpy(&rd_tmp, pd, 8); \ - } else { \ - memcpy(&rd_tmp, pd, 4); \ - } \ - WRITE_RD(sext_xlen(rd_tmp)); - -#define P_PK(BIT, X, Y) \ - require_extension(EXT_ZPN); \ - require(BIT == e16 || BIT == e32); \ - reg_t rd_tmp = 0, rs1 = RS1, rs2 = RS2; \ - for (sreg_t i = 0; i < xlen / BIT / 2; i++) { \ - rd_tmp = set_field(rd_tmp, make_mask64(i * 2 * BIT, BIT), \ - P_UFIELD(RS2, i * 2 + Y, BIT)); \ - rd_tmp = set_field(rd_tmp, make_mask64((i * 2 + 1) * BIT, BIT), \ - P_UFIELD(RS1, i * 2 + X, BIT)); \ - } \ - WRITE_RD(sext_xlen(rd_tmp)); - -#define P_64_PROFILE_BASE() \ - require_extension(EXT_ZPSFOPERAND); \ - sreg_t rd, rs1, rs2; - -#define P_64_UPROFILE_BASE() \ - require_extension(EXT_ZPSFOPERAND); \ - reg_t rd, rs1, rs2; - -#define P_64_PROFILE_PARAM(USE_RD, INPUT_PAIR) \ - if (xlen == 32) { \ - rs1 = INPUT_PAIR ? RS1_PAIR : RS1; \ - rs2 = INPUT_PAIR ? RS2_PAIR : RS2; \ - rd = USE_RD ? RD_PAIR : 0; \ - } else { \ - rs1 = RS1; \ - rs2 = RS2; \ - rd = USE_RD ? RD : 0; \ - } - -#define P_64_PROFILE(BODY) \ - P_64_PROFILE_BASE() \ - P_64_PROFILE_PARAM(false, true) \ - BODY \ - P_64_PROFILE_END() \ - -#define P_64_UPROFILE(BODY) \ - P_64_UPROFILE_BASE() \ - P_64_PROFILE_PARAM(false, true) \ - BODY \ - P_64_PROFILE_END() \ - -#define P_64_PROFILE_REDUCTION(BIT, BODY) \ - P_64_PROFILE_BASE() \ - P_64_PROFILE_PARAM(true, false) \ - for (sreg_t i = 0; i < xlen / BIT; i++) { \ - sreg_t ps1 = P_FIELD(rs1, i, BIT); \ - sreg_t ps2 = P_FIELD(rs2, i, BIT); \ - BODY \ - } \ - P_64_PROFILE_END() \ - -#define P_64_UPROFILE_REDUCTION(BIT, BODY) \ - P_64_UPROFILE_BASE() \ - P_64_PROFILE_PARAM(true, false) \ - for (sreg_t i = 0; i < xlen / BIT; i++) { \ - reg_t ps1 = P_UFIELD(rs1, i, BIT); \ - reg_t ps2 = P_UFIELD(rs2, i, BIT); \ - BODY \ - } \ - P_64_PROFILE_END() \ - -#define P_64_PROFILE_END() \ - if (xlen == 32) { \ - WRITE_RD_PAIR(rd); \ - } else { \ - WRITE_RD(sext_xlen(rd)); \ - } +#define set_field(reg, mask, val) \ + (((reg) & ~(std::remove_cv::type)(mask)) | (((std::remove_cv::type)(val) * ((mask) & ~((mask) << 1))) & (std::remove_cv::type)(mask))) #define DEBUG_START 0x0 #define DEBUG_END (0x1000 - 1) diff --git a/vendor/riscv/riscv-isa-sim/riscv/decode_macros.h b/vendor/riscv/riscv-isa-sim/riscv/decode_macros.h new file mode 100644 index 000000000..fee8ae7fa --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/decode_macros.h @@ -0,0 +1,312 @@ +// See LICENSE for license details. + +#ifndef _RISCV_DECODE_MACROS_H +#define _RISCV_DECODE_MACROS_H + +#include "config.h" +#include "decode.h" +#include "encoding.h" +#include "common.h" +#include "softfloat_types.h" +#include "specialize.h" + +// helpful macros, etc +#define MMU (*p->get_mmu()) +#define STATE (*p->get_state()) +#define FLEN (p->get_flen()) +#define CHECK_REG(reg) ((void) 0) +#define READ_REG(reg) (CHECK_REG(reg), STATE.XPR[reg]) +#define READ_FREG(reg) STATE.FPR[reg] +#define RD READ_REG(insn.rd()) +#define RS1 READ_REG(insn.rs1()) +#define RS2 READ_REG(insn.rs2()) +#define RS3 READ_REG(insn.rs3()) +#define WRITE_RD(value) WRITE_REG(insn.rd(), value) + +/* 0 : int + * 1 : floating + * 2 : vector reg + * 3 : vector hint + * 4 : csr + */ +#define WRITE_REG(reg, value) ({ \ + reg_t wdata = (value); /* value may have side effects */ \ + if (DECODE_MACRO_USAGE_LOGGED) STATE.log_reg_write[(reg) << 4] = {wdata, 0}; \ + CHECK_REG(reg); \ + STATE.XPR.write(reg, wdata); \ + }) +#define WRITE_FREG(reg, value) ({ \ + freg_t wdata = freg(value); /* value may have side effects */ \ + if (DECODE_MACRO_USAGE_LOGGED) STATE.log_reg_write[((reg) << 4) | 1] = wdata; \ + DO_WRITE_FREG(reg, wdata); \ + }) +#define WRITE_VSTATUS STATE.log_reg_write[3] = {0, 0}; + +// RVC macros +#define WRITE_RVC_RS1S(value) WRITE_REG(insn.rvc_rs1s(), value) +#define WRITE_RVC_RS2S(value) WRITE_REG(insn.rvc_rs2s(), value) +#define WRITE_RVC_FRS2S(value) WRITE_FREG(insn.rvc_rs2s(), value) +#define RVC_RS1 READ_REG(insn.rvc_rs1()) +#define RVC_RS2 READ_REG(insn.rvc_rs2()) +#define RVC_RS1S READ_REG(insn.rvc_rs1s()) +#define RVC_RS2S READ_REG(insn.rvc_rs2s()) +#define RVC_FRS2 READ_FREG(insn.rvc_rs2()) +#define RVC_FRS2S READ_FREG(insn.rvc_rs2s()) +#define RVC_SP READ_REG(X_SP) + +// Zc* macros +#define RVC_R1S (Sn(insn.rvc_r1sc())) +#define RVC_R2S (Sn(insn.rvc_r2sc())) +#define SP READ_REG(X_SP) +#define RA READ_REG(X_RA) + +// FPU macros +#define READ_ZDINX_REG(reg) (xlen == 32 ? f64(READ_REG_PAIR(reg)) : f64(STATE.XPR[reg] & (uint64_t)-1)) +#define READ_FREG_H(reg) (p->extension_enabled(EXT_ZFINX) ? f16(STATE.XPR[reg] & (uint16_t)-1) : f16(READ_FREG(reg))) +#define READ_FREG_F(reg) (p->extension_enabled(EXT_ZFINX) ? f32(STATE.XPR[reg] & (uint32_t)-1) : f32(READ_FREG(reg))) +#define READ_FREG_D(reg) (p->extension_enabled(EXT_ZFINX) ? READ_ZDINX_REG(reg) : f64(READ_FREG(reg))) +#define FRS1 READ_FREG(insn.rs1()) +#define FRS2 READ_FREG(insn.rs2()) +#define FRS3 READ_FREG(insn.rs3()) +#define FRS1_H READ_FREG_H(insn.rs1()) +#define FRS1_F READ_FREG_F(insn.rs1()) +#define FRS1_D READ_FREG_D(insn.rs1()) +#define FRS2_H READ_FREG_H(insn.rs2()) +#define FRS2_F READ_FREG_F(insn.rs2()) +#define FRS2_D READ_FREG_D(insn.rs2()) +#define FRS3_H READ_FREG_H(insn.rs3()) +#define FRS3_F READ_FREG_F(insn.rs3()) +#define FRS3_D READ_FREG_D(insn.rs3()) +#define dirty_fp_state STATE.sstatus->dirty(SSTATUS_FS) +#define dirty_ext_state STATE.sstatus->dirty(SSTATUS_XS) +#define dirty_vs_state STATE.sstatus->dirty(SSTATUS_VS) +#define DO_WRITE_FREG(reg, value) (STATE.FPR.write(reg, value), dirty_fp_state) +#define WRITE_FRD(value) WRITE_FREG(insn.rd(), value) +#define WRITE_FRD_H(value) \ +do { \ + if (p->extension_enabled(EXT_ZFINX)) \ + WRITE_REG(insn.rd(), sext_xlen((int16_t)((value).v))); \ + else { \ + WRITE_FRD(value); \ + } \ +} while (0) +#define WRITE_FRD_F(value) \ +do { \ + if (p->extension_enabled(EXT_ZFINX)) \ + WRITE_REG(insn.rd(), sext_xlen((value).v)); \ + else { \ + WRITE_FRD(value); \ + } \ +} while (0) +#define WRITE_FRD_D(value) \ +do { \ + if (p->extension_enabled(EXT_ZFINX)) { \ + if (xlen == 32) { \ + uint64_t val = (value).v; \ + WRITE_RD_PAIR(val); \ + } else { \ + WRITE_REG(insn.rd(), (value).v); \ + } \ + } else { \ + WRITE_FRD(value); \ + } \ +} while (0) + +#define SHAMT (insn.i_imm() & 0x3F) +#define BRANCH_TARGET (pc + insn.sb_imm()) +#define JUMP_TARGET (pc + insn.uj_imm()) +#define RM ({ int rm = insn.rm(); \ + if (rm == 7) rm = STATE.frm->read(); \ + if (rm > 4) throw trap_illegal_instruction(insn.bits()); \ + rm; }) + + +#define require_privilege(p) require(STATE.prv >= (p)) +#define require_novirt() (unlikely(STATE.v) ? throw trap_virtual_instruction(insn.bits()) : (void) 0) +#define require_hs_qualified(cond) (STATE.v && !(cond) ? require_novirt() : require(cond)) +#define require_privilege_hs_qualified(p) require_hs_qualified(STATE.prv >= (p)) +#define require_rv64 require(xlen == 64) +#define require_rv32 require(xlen == 32) +#define require_extension(s) require(p->extension_enabled(s)) +#define require_either_extension(A,B) require(p->extension_enabled(A) || p->extension_enabled(B)); +#define require_impl(s) require(p->supports_impl(s)) +#define require_fs require(STATE.sstatus->enabled(SSTATUS_FS)) +#define require_fp STATE.fflags->verify_permissions(insn, false) +#define require_accelerator require(STATE.sstatus->enabled(SSTATUS_XS)) +#define require_vector_vs require(STATE.sstatus->enabled(SSTATUS_VS)) +#define require_vector(alu) \ + do { \ + require_vector_vs; \ + require_extension('V'); \ + require(!P.VU.vill); \ + if (alu && !P.VU.vstart_alu) \ + require(P.VU.vstart->read() == 0); \ + WRITE_VSTATUS; \ + dirty_vs_state; \ + } while (0); +#define require_vector_novtype(is_log) \ + do { \ + require_vector_vs; \ + require_extension('V'); \ + if (is_log) \ + WRITE_VSTATUS; \ + dirty_vs_state; \ + } while (0); +#define require_align(val, pos) require(is_aligned(val, pos)) +#define require_noover(astart, asize, bstart, bsize) \ + require(!is_overlapped(astart, asize, bstart, bsize)) +#define require_noover_widen(astart, asize, bstart, bsize) \ + require(!is_overlapped_widen(astart, asize, bstart, bsize)) +#define require_vm do { if (insn.v_vm() == 0) require(insn.rd() != 0); } while (0); +#define require_envcfg(field) \ + do { \ + if (((STATE.prv != PRV_M) && (m##field == 0)) || \ + ((STATE.prv == PRV_U && !STATE.v) && (s##field == 0))) \ + throw trap_illegal_instruction(insn.bits()); \ + else if (STATE.v && ((h##field == 0) || \ + ((STATE.prv == PRV_U) && (s##field == 0)))) \ + throw trap_virtual_instruction(insn.bits()); \ + } while (0); + +#define require_zcmp_pushpop \ + do { \ + require_extension(EXT_ZCMP); \ + reg_t rlist = insn.rvc_rlist(); \ + require(rlist >= 4); \ + \ + if (p->extension_enabled('E')) { \ + require(rlist <= 6); \ + } \ + } while (0); + +#define set_fp_exceptions ({ if (softfloat_exceptionFlags) { \ + STATE.fflags->write(STATE.fflags->read() | softfloat_exceptionFlags); \ + } \ + softfloat_exceptionFlags = 0; }) + +#define sext32(x) ((sreg_t)(int32_t)(x)) +#define zext32(x) ((reg_t)(uint32_t)(x)) +#define sext_xlen(x) (((sreg_t)(x) << (64 - xlen)) >> (64 - xlen)) +#define zext(x, pos) (((reg_t)(x) << (64 - (pos))) >> (64 - (pos))) +#define zext_xlen(x) zext(x, xlen) + +#define set_pc(x) \ + do { p->check_pc_alignment(x); \ + npc = sext_xlen(x); \ + } while (0) + +#define set_pc_and_serialize(x) \ + do { reg_t __npc = (x) & p->pc_alignment_mask(); \ + npc = PC_SERIALIZE_AFTER; \ + STATE.pc = __npc; \ + } while (0) + +class wait_for_interrupt_t {}; + +#define wfi() \ + do { set_pc_and_serialize(npc); \ + throw wait_for_interrupt_t(); \ + } while (0) + +#define serialize() set_pc_and_serialize(npc) + +/* Sentinel PC values to serialize simulator pipeline */ +#define PC_SERIALIZE_BEFORE 3 +#define PC_SERIALIZE_AFTER 5 +#define invalid_pc(pc) ((pc) & 1) + +/* Convenience wrappers to simplify softfloat code sequences */ +#define isBoxedF16(r) (isBoxedF32(r) && ((uint64_t)((r.v[0] >> 16) + 1) == ((uint64_t)1 << 48))) +#define unboxF16(r) (isBoxedF16(r) ? (uint16_t)r.v[0] : defaultNaNF16UI) +#define isBoxedF32(r) (isBoxedF64(r) && ((uint32_t)((r.v[0] >> 32) + 1) == 0)) +#define unboxF32(r) (isBoxedF32(r) ? (uint32_t)r.v[0] : defaultNaNF32UI) +#define isBoxedF64(r) ((r.v[1] + 1) == 0) +#define unboxF64(r) (isBoxedF64(r) ? r.v[0] : defaultNaNF64UI) +inline float16_t f16(uint16_t v) { return { v }; } +inline float32_t f32(uint32_t v) { return { v }; } +inline float64_t f64(uint64_t v) { return { v }; } +inline float16_t f16(freg_t r) { return f16(unboxF16(r)); } +inline float32_t f32(freg_t r) { return f32(unboxF32(r)); } +inline float64_t f64(freg_t r) { return f64(unboxF64(r)); } +inline float128_t f128(freg_t r) { return r; } +inline freg_t freg(float16_t f) { return { ((uint64_t)-1 << 16) | f.v, (uint64_t)-1 }; } +inline freg_t freg(float32_t f) { return { ((uint64_t)-1 << 32) | f.v, (uint64_t)-1 }; } +inline freg_t freg(float64_t f) { return { f.v, (uint64_t)-1 }; } +inline freg_t freg(float128_t f) { return f; } +#define F16_SIGN ((uint16_t)1 << 15) +#define F32_SIGN ((uint32_t)1 << 31) +#define F64_SIGN ((uint64_t)1 << 63) +#define fsgnj16(a, b, n, x) \ + f16((f16(a).v & ~F16_SIGN) | ((((x) ? f16(a).v : (n) ? F16_SIGN : 0) ^ f16(b).v) & F16_SIGN)) +#define fsgnj32(a, b, n, x) \ + f32((f32(a).v & ~F32_SIGN) | ((((x) ? f32(a).v : (n) ? F32_SIGN : 0) ^ f32(b).v) & F32_SIGN)) +#define fsgnj64(a, b, n, x) \ + f64((f64(a).v & ~F64_SIGN) | ((((x) ? f64(a).v : (n) ? F64_SIGN : 0) ^ f64(b).v) & F64_SIGN)) + +#define isNaNF128(x) isNaNF128UI(x.v[1], x.v[0]) +inline float128_t defaultNaNF128() +{ + float128_t nan; + nan.v[1] = defaultNaNF128UI64; + nan.v[0] = defaultNaNF128UI0; + return nan; +} +inline freg_t fsgnj128(freg_t a, freg_t b, bool n, bool x) +{ + a.v[1] = (a.v[1] & ~F64_SIGN) | (((x ? a.v[1] : n ? F64_SIGN : 0) ^ b.v[1]) & F64_SIGN); + return a; +} +inline freg_t f128_negate(freg_t a) +{ + a.v[1] ^= F64_SIGN; + return a; +} + +#define validate_csr(which, write) ({ \ + if (!STATE.serialized) return PC_SERIALIZE_BEFORE; \ + STATE.serialized = false; \ + /* permissions check occurs in get_csr */ \ + (which); }) + +/* For debug only. This will fail if the native machine's float types are not IEEE */ +inline float to_f(float32_t f) { float r; memcpy(&r, &f, sizeof(r)); return r; } +inline double to_f(float64_t f) { double r; memcpy(&r, &f, sizeof(r)); return r; } +inline long double to_f(float128_t f) { long double r; memcpy(&r, &f, sizeof(r)); return r; } + +// Vector macros +#define e8 8 // 8b elements +#define e16 16 // 16b elements +#define e32 32 // 32b elements +#define e64 64 // 64b elements +#define e128 128 // 128b elements +#define e256 256 // 256b elements +#define e512 512 // 512b elements +#define e1024 1024 // 1024b elements + +#define vsext(x, sew) (((sreg_t)(x) << (64 - sew)) >> (64 - sew)) +#define vzext(x, sew) (((reg_t)(x) << (64 - sew)) >> (64 - sew)) + +#define DEBUG_RVV 0 + +#if DEBUG_RVV +#define DEBUG_RVV_FP_VV \ + printf("vfp(%lu) vd=%f vs1=%f vs2=%f\n", i, to_f(vd), to_f(vs1), to_f(vs2)); +#define DEBUG_RVV_FP_VF \ + printf("vfp(%lu) vd=%f vs1=%f vs2=%f\n", i, to_f(vd), to_f(rs1), to_f(vs2)); +#define DEBUG_RVV_FMA_VV \ + printf("vfma(%lu) vd=%f vs1=%f vs2=%f vd_old=%f\n", i, to_f(vd), to_f(vs1), to_f(vs2), to_f(vd_old)); +#define DEBUG_RVV_FMA_VF \ + printf("vfma(%lu) vd=%f vs1=%f vs2=%f vd_old=%f\n", i, to_f(vd), to_f(rs1), to_f(vs2), to_f(vd_old)); +#else +#define DEBUG_RVV_FP_VV 0 +#define DEBUG_RVV_FP_VF 0 +#define DEBUG_RVV_FMA_VV 0 +#define DEBUG_RVV_FMA_VF 0 +#endif + +#define DECLARE_XENVCFG_VARS(field) \ + reg_t m##field = get_field(STATE.menvcfg->read(), MENVCFG_##field); \ + reg_t s##field = get_field(STATE.senvcfg->read(), SENVCFG_##field); \ + reg_t h##field = get_field(STATE.henvcfg->read(), HENVCFG_##field) + +#endif diff --git a/vendor/riscv/riscv-isa-sim/riscv/devices.cc b/vendor/riscv/riscv-isa-sim/riscv/devices.cc index eb677a588..81b232d12 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/devices.cc +++ b/vendor/riscv/riscv-isa-sim/riscv/devices.cc @@ -137,3 +137,16 @@ char* mem_t::contents(reg_t addr) { } return search->second + pgoff; } + +void mem_t::dump(std::ostream& o) { + const char empty[PGSIZE] = {0}; + for (reg_t i = 0; i < sz; i += PGSIZE) { + reg_t ppn = i >> PGSHIFT; + auto search = sparse_memory_map.find(ppn); + if (search == sparse_memory_map.end()) { + o.write(empty, PGSIZE); + } else { + o.write(sparse_memory_map[ppn], PGSIZE); + } + } +} diff --git a/vendor/riscv/riscv-isa-sim/riscv/devices.h b/vendor/riscv/riscv-isa-sim/riscv/devices.h index 9200f29b9..02d9e9806 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/devices.h +++ b/vendor/riscv/riscv-isa-sim/riscv/devices.h @@ -4,12 +4,16 @@ #include "decode.h" #include "mmio_plugin.h" #include "abstract_device.h" +#include "abstract_interrupt_controller.h" #include "platform.h" #include +#include #include #include +#include class processor_t; +class simif_t; class bus_t : public abstract_device_t { public: @@ -43,6 +47,7 @@ class mem_t : public abstract_device_t { bool store(reg_t addr, size_t len, const uint8_t* bytes) { return load_store(addr, len, const_cast(bytes), true); } char* contents(reg_t addr); reg_t size() { return sz; } + void dump(std::ostream& o); private: bool load_store(reg_t addr, size_t len, uint8_t* bytes, bool store); @@ -53,22 +58,104 @@ class mem_t : public abstract_device_t { class clint_t : public abstract_device_t { public: - clint_t(std::vector&, uint64_t freq_hz, bool real_time); + clint_t(simif_t*, uint64_t freq_hz, bool real_time); bool load(reg_t addr, size_t len, uint8_t* bytes); bool store(reg_t addr, size_t len, const uint8_t* bytes); size_t size() { return CLINT_SIZE; } void increment(reg_t inc); + uint64_t get_mtimecmp(reg_t hartid) { return mtimecmp[hartid]; } + uint64_t get_mtime() { return mtime; } private: typedef uint64_t mtime_t; typedef uint64_t mtimecmp_t; typedef uint32_t msip_t; - std::vector& procs; + simif_t* sim; uint64_t freq_hz; bool real_time; uint64_t real_time_ref_secs; uint64_t real_time_ref_usecs; mtime_t mtime; - std::vector mtimecmp; + std::map mtimecmp; +}; + +#define PLIC_MAX_DEVICES 1024 + +struct plic_context_t { + plic_context_t(processor_t* proc, bool mmode) + : proc(proc), mmode(mmode) + {} + + processor_t *proc; + bool mmode; + + uint8_t priority_threshold {}; + uint32_t enable[PLIC_MAX_DEVICES/32] {}; + uint32_t pending[PLIC_MAX_DEVICES/32] {}; + uint8_t pending_priority[PLIC_MAX_DEVICES] {}; + uint32_t claimed[PLIC_MAX_DEVICES/32] {}; +}; + +class plic_t : public abstract_device_t, public abstract_interrupt_controller_t { + public: + plic_t(simif_t*, uint32_t ndev); + bool load(reg_t addr, size_t len, uint8_t* bytes); + bool store(reg_t addr, size_t len, const uint8_t* bytes); + void set_interrupt_level(uint32_t id, int lvl); + size_t size() { return PLIC_SIZE; } + private: + std::vector contexts; + uint32_t num_ids; + uint32_t num_ids_word; + uint32_t max_prio; + uint8_t priority[PLIC_MAX_DEVICES]; + uint32_t level[PLIC_MAX_DEVICES/32]; + uint32_t context_best_pending(const plic_context_t *c); + void context_update(const plic_context_t *context); + uint32_t context_claim(plic_context_t *c); + bool priority_read(reg_t offset, uint32_t *val); + bool priority_write(reg_t offset, uint32_t val); + bool pending_read(reg_t offset, uint32_t *val); + bool context_enable_read(const plic_context_t *context, + reg_t offset, uint32_t *val); + bool context_enable_write(plic_context_t *context, + reg_t offset, uint32_t val); + bool context_read(plic_context_t *context, + reg_t offset, uint32_t *val); + bool context_write(plic_context_t *context, + reg_t offset, uint32_t val); +}; + +class ns16550_t : public abstract_device_t { + public: + ns16550_t(class bus_t *bus, abstract_interrupt_controller_t *intctrl, + uint32_t interrupt_id, uint32_t reg_shift, uint32_t reg_io_width); + bool load(reg_t addr, size_t len, uint8_t* bytes); + bool store(reg_t addr, size_t len, const uint8_t* bytes); + void tick(void); + size_t size() { return NS16550_SIZE; } + private: + class bus_t *bus; + abstract_interrupt_controller_t *intctrl; + uint32_t interrupt_id; + uint32_t reg_shift; + uint32_t reg_io_width; + std::queue rx_queue; + uint8_t dll; + uint8_t dlm; + uint8_t iir; + uint8_t ier; + uint8_t fcr; + uint8_t lcr; + uint8_t mcr; + uint8_t lsr; + uint8_t msr; + uint8_t scr; + void update_interrupt(void); + uint8_t rx_byte(void); + void tx_byte(uint8_t val); + + int backoff_counter; + static const int MAX_BACKOFF = 16; }; class mmio_plugin_device_t : public abstract_device_t { @@ -84,4 +171,26 @@ class mmio_plugin_device_t : public abstract_device_t { void* user_data; }; +template +void write_little_endian_reg(T* word, reg_t addr, size_t len, const uint8_t* bytes) +{ + assert(len <= sizeof(T)); + + for (size_t i = 0; i < len; i++) { + const int shift = 8 * ((addr + i) % sizeof(T)); + *word = (*word & ~(T(0xFF) << shift)) | (T(bytes[i]) << shift); + } +} + +template +void read_little_endian_reg(T word, reg_t addr, size_t len, uint8_t* bytes) +{ + assert(len <= sizeof(T)); + + for (size_t i = 0; i < len; i++) { + const int shift = 8 * ((addr + i) % sizeof(T)); + bytes[i] = word >> shift; + } +} + #endif diff --git a/vendor/riscv/riscv-isa-sim/riscv/disasm.h b/vendor/riscv/riscv-isa-sim/riscv/disasm.h index 0f528a303..d4b8c2c40 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/disasm.h +++ b/vendor/riscv/riscv-isa-sim/riscv/disasm.h @@ -3,7 +3,9 @@ #ifndef _RISCV_DISASM_H #define _RISCV_DISASM_H +#include "common.h" #include "decode.h" +#include "isa_parser.h" #include #include #include @@ -80,7 +82,7 @@ class disasm_insn_t class disassembler_t { public: - disassembler_t(int xlen); + disassembler_t(const isa_parser_t *isa); ~disassembler_t(); std::string disassemble(insn_t insn) const; @@ -92,6 +94,8 @@ class disassembler_t static const int HASH_SIZE = 255; std::vector chain[HASH_SIZE+1]; + void add_instructions(const isa_parser_t* isa); + const disasm_insn_t* probe_once(insn_t insn, size_t idx) const; static const unsigned int MASK1 = 0x7f; diff --git a/vendor/riscv/riscv-isa-sim/riscv/dts.cc b/vendor/riscv/riscv-isa-sim/riscv/dts.cc index 46000d8f4..200288ef2 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/dts.cc +++ b/vendor/riscv/riscv-isa-sim/riscv/dts.cc @@ -1,8 +1,10 @@ // See LICENSE for license details. +#include "config.h" #include "dts.h" #include "libfdt.h" #include "platform.h" +#include #include #include #include @@ -13,6 +15,7 @@ std::string make_dts(size_t insns_per_rtc_tick, size_t cpu_hz, reg_t initrd_start, reg_t initrd_end, const char* bootargs, + size_t pmpregions, std::vector procs, std::vector> mems) { @@ -25,15 +28,16 @@ std::string make_dts(size_t insns_per_rtc_tick, size_t cpu_hz, " #size-cells = <2>;\n" " compatible = \"ucbbar,spike-bare-dev\";\n" " model = \"ucbbar,spike-bare\";\n" - " chosen {\n"; + " chosen {\n" + " stdout-path = &SERIAL0;\n"; if (initrd_start < initrd_end) { s << " linux,initrd-start = <" << (size_t)initrd_start << ">;\n" " linux,initrd-end = <" << (size_t)initrd_end << ">;\n"; if (!bootargs) - bootargs = "root=/dev/ram console=hvc0 earlycon=sbi"; + bootargs = "root=/dev/ram " DEFAULT_KERNEL_BOOTARGS; } else { if (!bootargs) - bootargs = "console=hvc0 earlycon=sbi"; + bootargs = DEFAULT_KERNEL_BOOTARGS; } s << " bootargs = \""; for (size_t i = 0; i < strlen(bootargs); i++) { @@ -54,10 +58,10 @@ std::string make_dts(size_t insns_per_rtc_tick, size_t cpu_hz, " reg = <" << i << ">;\n" " status = \"okay\";\n" " compatible = \"riscv\";\n" - " riscv,isa = \"" << procs[i]->get_isa_string() << "\";\n" - " mmu-type = \"riscv," << (procs[i]->get_max_xlen() <= 32 ? "sv32" : "sv48") << "\";\n" - " riscv,pmpregions = <16>;\n" - " riscv,pmpgranularity = <4>;\n" + " riscv,isa = \"" << procs[i]->get_isa().get_isa_string() << "\";\n" + " mmu-type = \"riscv," << (procs[i]->get_isa().get_max_xlen() <= 32 ? "sv32" : "sv57") << "\";\n" + " riscv,pmpregions = <" << pmpregions << ">;\n" + " riscv,pmpgranularity = <" << (1 << PMP_SHIFT) << ">;\n" " clock-frequency = <" << cpu_hz << ">;\n" " CPU" << i << "_intc: interrupt-controller {\n" " #address-cells = <2>;\n" @@ -92,6 +96,35 @@ std::string make_dts(size_t insns_per_rtc_tick, size_t cpu_hz, " reg = <0x" << (clintbs >> 32) << " 0x" << (clintbs & (uint32_t)-1) << " 0x" << (clintsz >> 32) << " 0x" << (clintsz & (uint32_t)-1) << ">;\n" " };\n" + " PLIC: plic@" << PLIC_BASE << " {\n" + " compatible = \"riscv,plic0\";\n" + " #address-cells = <2>;\n" + " interrupts-extended = <" << std::dec; + for (size_t i = 0; i < procs.size(); i++) + s << "&CPU" << i << "_intc 11 &CPU" << i << "_intc 9 "; + reg_t plicbs = PLIC_BASE; + reg_t plicsz = PLIC_SIZE; + s << std::hex << ">;\n" + " reg = <0x" << (plicbs >> 32) << " 0x" << (plicbs & (uint32_t)-1) << + " 0x" << (plicsz >> 32) << " 0x" << (plicsz & (uint32_t)-1) << ">;\n" + " riscv,ndev = <0x" << PLIC_NDEV << ">;\n" + " riscv,max-priority = <0x" << ((1U << PLIC_PRIO_BITS) - 1) << ">;\n" + " #interrupt-cells = <1>;\n" + " interrupt-controller;\n" + " };\n" + " SERIAL0: ns16550@" << NS16550_BASE << " {\n" + " compatible = \"ns16550a\";\n" + " clock-frequency = <" << std::dec << (cpu_hz/insns_per_rtc_tick) << ">;\n" + " interrupt-parent = <&PLIC>;\n" + " interrupts = <" << std::dec << NS16550_INTERRUPT_ID; + reg_t ns16550bs = NS16550_BASE; + reg_t ns16550sz = NS16550_SIZE; + s << std::hex << ">;\n" + " reg = <0x" << (ns16550bs >> 32) << " 0x" << (ns16550bs & (uint32_t)-1) << + " 0x" << (ns16550sz >> 32) << " 0x" << (ns16550sz & (uint32_t)-1) << ">;\n" + " reg-shift = <0x" << NS16550_REG_SHIFT << ">;\n" + " reg-io-width = <0x" << NS16550_REG_IO_WIDTH << ">;\n" + " };\n" " };\n" " htif {\n" " compatible = \"ucb,htif0\";\n" @@ -143,7 +176,7 @@ std::string dts_compile(const std::string& dts) close(dts_pipe[1]); close(dtb_pipe[0]); close(dtb_pipe[1]); - execlp(DTC, DTC, "-O", "dtb", 0); + execlp(DTC, DTC, "-O", "dtb", (char *)0); std::cerr << "Failed to run " DTC ": " << strerror(errno) << std::endl; exit(1); } @@ -182,7 +215,6 @@ std::string dts_compile(const std::string& dts) return dtb.str(); } - static int fdt_get_node_addr_size(void *fdt, int node, reg_t *addr, unsigned long *size, const char *field) { @@ -244,7 +276,6 @@ static int check_cpu_node(void *fdt, int cpu_offset) return 0; } - int fdt_get_offset(void *fdt, const char *field) { return fdt_path_offset(fdt, field); @@ -276,6 +307,64 @@ int fdt_parse_clint(void *fdt, reg_t *clint_addr, return 0; } +int fdt_parse_plic(void *fdt, reg_t *plic_addr, uint32_t *ndev, + const char *compatible) +{ + int nodeoffset, len, rc; + const fdt32_t *ndev_p; + + nodeoffset = fdt_node_offset_by_compatible(fdt, -1, compatible); + if (nodeoffset < 0) + return nodeoffset; + + rc = fdt_get_node_addr_size(fdt, nodeoffset, plic_addr, NULL, "reg"); + if (rc < 0 || !plic_addr) + return -ENODEV; + + ndev_p = (fdt32_t *)fdt_getprop(fdt, nodeoffset, "riscv,ndev", &len); + if (!ndev || !ndev_p) + return -ENODEV; + *ndev = fdt32_to_cpu(*ndev_p); + + return 0; +} + +int fdt_parse_ns16550(void *fdt, reg_t *ns16550_addr, + uint32_t *reg_shift, uint32_t *reg_io_width, + const char *compatible) +{ + int nodeoffset, len, rc; + const fdt32_t *reg_p; + + nodeoffset = fdt_node_offset_by_compatible(fdt, -1, compatible); + if (nodeoffset < 0) + return nodeoffset; + + rc = fdt_get_node_addr_size(fdt, nodeoffset, ns16550_addr, NULL, "reg"); + if (rc < 0 || !ns16550_addr) + return -ENODEV; + + reg_p = (fdt32_t *)fdt_getprop(fdt, nodeoffset, "reg-shift", &len); + if (reg_shift) { + if (reg_p) { + *reg_shift = fdt32_to_cpu(*reg_p); + } else { + *reg_shift = NS16550_REG_SHIFT; + } + } + + reg_p = (fdt32_t *)fdt_getprop(fdt, nodeoffset, "reg-io-width", &len); + if (reg_io_width) { + if (reg_p) { + *reg_io_width = fdt32_to_cpu(*reg_p); + } else { + *reg_io_width = NS16550_REG_IO_WIDTH; + } + } + + return 0; +} + int fdt_parse_pmp_num(void *fdt, int cpu_offset, reg_t *pmp_num) { int rc; @@ -306,8 +395,10 @@ int fdt_parse_pmp_alignment(void *fdt, int cpu_offset, reg_t *pmp_align) return 0; } -int fdt_parse_mmu_type(void *fdt, int cpu_offset, char *mmu_type) +int fdt_parse_mmu_type(void *fdt, int cpu_offset, const char **mmu_type) { + assert(mmu_type); + int len, rc; const void *prop; @@ -318,7 +409,7 @@ int fdt_parse_mmu_type(void *fdt, int cpu_offset, char *mmu_type) if (!prop || !len) return -EINVAL; - strcpy(mmu_type, (char *)prop); + *mmu_type = (const char *)prop; return 0; } diff --git a/vendor/riscv/riscv-isa-sim/riscv/dts.h b/vendor/riscv/riscv-isa-sim/riscv/dts.h index 1c3a54d2c..7a64d7bc6 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/dts.h +++ b/vendor/riscv/riscv-isa-sim/riscv/dts.h @@ -10,6 +10,7 @@ std::string make_dts(size_t insns_per_rtc_tick, size_t cpu_hz, reg_t initrd_start, reg_t initrd_end, const char* bootargs, + size_t pmpregions, std::vector procs, std::vector> mems); @@ -21,7 +22,12 @@ int fdt_get_next_subnode(void *fdt, int node); int fdt_parse_clint(void *fdt, reg_t *clint_addr, const char *compatible); +int fdt_parse_plic(void *fdt, reg_t *plic_addr, uint32_t *ndev, + const char *compatible); +int fdt_parse_ns16550(void *fdt, reg_t *ns16550_addr, + uint32_t *reg_shift, uint32_t *reg_io_width, + const char *compatible); int fdt_parse_pmp_num(void *fdt, int cpu_offset, reg_t *pmp_num); int fdt_parse_pmp_alignment(void *fdt, int cpu_offset, reg_t *pmp_align); -int fdt_parse_mmu_type(void *fdt, int cpu_offset, char *mmu_type); +int fdt_parse_mmu_type(void *fdt, int cpu_offset, const char **mmu_type); #endif diff --git a/vendor/riscv/riscv-isa-sim/riscv/encoding.h b/vendor/riscv/riscv-isa-sim/riscv/encoding.h index 1f2cc52b0..48cb5c005 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/encoding.h +++ b/vendor/riscv/riscv-isa-sim/riscv/encoding.h @@ -1,9 +1,11 @@ -/* - * This file is auto-generated by running 'make ../riscv-isa-sim/riscv/encoding.h' in - * https://github.com/riscv/riscv-opcodes (ce0bd39) - */ +/* SPDX-License-Identifier: BSD-3-Clause */ -/* See LICENSE for license details. */ +/* Copyright (c) 2023 RISC-V International */ + +/* + * This file is auto-generated by running 'make' in + * https://github.com/riscv/riscv-opcodes (5adef50) + */ #ifndef RISCV_CSR_ENCODING_H #define RISCV_CSR_ENCODING_H @@ -70,6 +72,10 @@ #define USTATUS_UIE 0x00000001 #define USTATUS_UPIE 0x00000010 +#define MNSTATUS_NMIE 0x00000008 +#define MNSTATUS_MNPP 0x00001800 +#define MNSTATUS_MNPV 0x00000080 + #define DCSR_XDEBUGVER (3U<<30) #define DCSR_NDRESET (1<<29) #define DCSR_FULLRESET (1<<28) @@ -139,6 +145,7 @@ #define MIP_VSEIP (1 << IRQ_VS_EXT) #define MIP_MEIP (1 << IRQ_M_EXT) #define MIP_SGEIP (1 << IRQ_S_GEXT) +#define MIP_LCOFIP (1 << IRQ_LCOF) #define MIP_S_MASK (MIP_SSIP | MIP_STIP | MIP_SEIP) #define MIP_VS_MASK (MIP_VSSIP | MIP_VSTIP | MIP_VSEIP) @@ -149,6 +156,85 @@ #define SIP_SSIP MIP_SSIP #define SIP_STIP MIP_STIP +#define MENVCFG_FIOM 0x00000001 +#define MENVCFG_CBIE 0x00000030 +#define MENVCFG_CBCFE 0x00000040 +#define MENVCFG_CBZE 0x00000080 +#define MENVCFG_HADE 0x2000000000000000 +#define MENVCFG_PBMTE 0x4000000000000000 +#define MENVCFG_STCE 0x8000000000000000 + +#define MENVCFGH_HADE 0x20000000 +#define MENVCFGH_PBMTE 0x40000000 +#define MENVCFGH_STCE 0x80000000 + +#define MSTATEEN0_CS 0x00000001 +#define MSTATEEN0_FCSR 0x00000002 +#define MSTATEEN0_JVT 0x00000004 +#define MSTATEEN0_HCONTEXT 0x0200000000000000 +#define MSTATEEN0_HENVCFG 0x4000000000000000 +#define MSTATEEN_HSTATEEN 0x8000000000000000 + +#define MSTATEEN0H_HCONTEXT 0x02000000 +#define MSTATEEN0H_HENVCFG 0x40000000 +#define MSTATEENH_HSTATEEN 0x80000000 + +#define MHPMEVENT_VUINH 0x0400000000000000 +#define MHPMEVENT_VSINH 0x0800000000000000 +#define MHPMEVENT_UINH 0x1000000000000000 +#define MHPMEVENT_SINH 0x2000000000000000 +#define MHPMEVENT_MINH 0x4000000000000000 +#define MHPMEVENT_OF 0x8000000000000000 + +#define MHPMEVENTH_VUINH 0x04000000 +#define MHPMEVENTH_VSINH 0x08000000 +#define MHPMEVENTH_UINH 0x10000000 +#define MHPMEVENTH_SINH 0x20000000 +#define MHPMEVENTH_MINH 0x40000000 +#define MHPMEVENTH_OF 0x80000000 + +#define HENVCFG_FIOM 0x00000001 +#define HENVCFG_CBIE 0x00000030 +#define HENVCFG_CBCFE 0x00000040 +#define HENVCFG_CBZE 0x00000080 +#define HENVCFG_HADE 0x2000000000000000 +#define HENVCFG_PBMTE 0x4000000000000000 +#define HENVCFG_STCE 0x8000000000000000 + +#define HENVCFGH_HADE 0x20000000 +#define HENVCFGH_PBMTE 0x40000000 +#define HENVCFGH_STCE 0x80000000 + +#define HSTATEEN0_CS 0x00000001 +#define HSTATEEN0_FCSR 0x00000002 +#define HSTATEEN0_JVT 0x00000004 +#define HSTATEEN0_SCONTEXT 0x0200000000000000 +#define HSTATEEN0_SENVCFG 0x4000000000000000 +#define HSTATEEN_SSTATEEN 0x8000000000000000 + +#define HSTATEEN0H_SCONTEXT 0x02000000 +#define HSTATEEN0H_SENVCFG 0x40000000 +#define HSTATEENH_SSTATEEN 0x80000000 + +#define SENVCFG_FIOM 0x00000001 +#define SENVCFG_CBIE 0x00000030 +#define SENVCFG_CBCFE 0x00000040 +#define SENVCFG_CBZE 0x00000080 + +#define SSTATEEN0_CS 0x00000001 +#define SSTATEEN0_FCSR 0x00000002 +#define SSTATEEN0_JVT 0x00000004 + +#define MSECCFG_MML 0x00000001 +#define MSECCFG_MMWP 0x00000002 +#define MSECCFG_RLB 0x00000004 +#define MSECCFG_USEED 0x00000100 +#define MSECCFG_SSEED 0x00000200 + +/* jvt fields */ +#define JVT_MODE 0x3F +#define JVT_BASE (~0x3F) + #define PRV_U 0 #define PRV_S 1 #define PRV_M 3 @@ -181,6 +267,7 @@ #define HGATP_MODE_SV32X4 1 #define HGATP_MODE_SV39X4 8 #define HGATP_MODE_SV48X4 9 +#define HGATP_MODE_SV57X4 10 #define PMP_R 0x01 #define PMP_W 0x02 @@ -207,7 +294,7 @@ #define IRQ_M_EXT 11 #define IRQ_S_GEXT 12 #define IRQ_COP 12 -#define IRQ_HOST 13 +#define IRQ_LCOF 13 /* page table entry (PTE) fields */ #define PTE_V 0x001 /* Valid */ @@ -278,2521 +365,2537 @@ #endif #endif -/* Automatically generated by parse_opcodes. */ + +/* Automatically generated by parse_opcodes. */ #ifndef RISCV_ENCODING_H #define RISCV_ENCODING_H -#define MATCH_SLLI_RV32 0x1013 -#define MASK_SLLI_RV32 0xfe00707f -#define MATCH_SRLI_RV32 0x5013 -#define MASK_SRLI_RV32 0xfe00707f -#define MATCH_SRAI_RV32 0x40005013 -#define MASK_SRAI_RV32 0xfe00707f -#define MATCH_FRFLAGS 0x102073 -#define MASK_FRFLAGS 0xfffff07f -#define MATCH_FSFLAGS 0x101073 -#define MASK_FSFLAGS 0xfff0707f -#define MATCH_FSFLAGSI 0x105073 -#define MASK_FSFLAGSI 0xfff0707f -#define MATCH_FRRM 0x202073 -#define MASK_FRRM 0xfffff07f -#define MATCH_FSRM 0x201073 -#define MASK_FSRM 0xfff0707f -#define MATCH_FSRMI 0x205073 -#define MASK_FSRMI 0xfff0707f -#define MATCH_FSCSR 0x301073 -#define MASK_FSCSR 0xfff0707f -#define MATCH_FRCSR 0x302073 -#define MASK_FRCSR 0xfffff07f -#define MATCH_RDCYCLE 0xc0002073 -#define MASK_RDCYCLE 0xfffff07f -#define MATCH_RDTIME 0xc0102073 -#define MASK_RDTIME 0xfffff07f -#define MATCH_RDINSTRET 0xc0202073 -#define MASK_RDINSTRET 0xfffff07f -#define MATCH_RDCYCLEH 0xc8002073 -#define MASK_RDCYCLEH 0xfffff07f -#define MATCH_RDTIMEH 0xc8102073 -#define MASK_RDTIMEH 0xfffff07f -#define MATCH_RDINSTRETH 0xc8202073 -#define MASK_RDINSTRETH 0xfffff07f -#define MATCH_SCALL 0x73 -#define MASK_SCALL 0xffffffff -#define MATCH_SBREAK 0x100073 -#define MASK_SBREAK 0xffffffff -#define MATCH_FMV_X_S 0xe0000053 -#define MASK_FMV_X_S 0xfff0707f -#define MATCH_FMV_S_X 0xf0000053 -#define MASK_FMV_S_X 0xfff0707f -#define MATCH_FENCE_TSO 0x8330000f -#define MASK_FENCE_TSO 0xfff0707f -#define MATCH_PAUSE 0x100000f -#define MASK_PAUSE 0xffffffff -#define MATCH_BEQ 0x63 -#define MASK_BEQ 0x707f -#define MATCH_BNE 0x1063 -#define MASK_BNE 0x707f -#define MATCH_BLT 0x4063 -#define MASK_BLT 0x707f -#define MATCH_BGE 0x5063 -#define MASK_BGE 0x707f -#define MATCH_BLTU 0x6063 -#define MASK_BLTU 0x707f -#define MATCH_BGEU 0x7063 -#define MASK_BGEU 0x707f -#define MATCH_JALR 0x67 -#define MASK_JALR 0x707f -#define MATCH_JAL 0x6f -#define MASK_JAL 0x7f -#define MATCH_LUI 0x37 -#define MASK_LUI 0x7f -#define MATCH_AUIPC 0x17 -#define MASK_AUIPC 0x7f -#define MATCH_ADDI 0x13 -#define MASK_ADDI 0x707f -#define MATCH_SLTI 0x2013 -#define MASK_SLTI 0x707f -#define MATCH_SLTIU 0x3013 -#define MASK_SLTIU 0x707f -#define MATCH_XORI 0x4013 -#define MASK_XORI 0x707f -#define MATCH_ORI 0x6013 -#define MASK_ORI 0x707f -#define MATCH_ANDI 0x7013 -#define MASK_ANDI 0x707f #define MATCH_ADD 0x33 -#define MASK_ADD 0xfe00707f -#define MATCH_SUB 0x40000033 -#define MASK_SUB 0xfe00707f -#define MATCH_SLL 0x1033 -#define MASK_SLL 0xfe00707f -#define MATCH_SLT 0x2033 -#define MASK_SLT 0xfe00707f -#define MATCH_SLTU 0x3033 -#define MASK_SLTU 0xfe00707f -#define MATCH_XOR 0x4033 -#define MASK_XOR 0xfe00707f -#define MATCH_SRL 0x5033 -#define MASK_SRL 0xfe00707f -#define MATCH_SRA 0x40005033 -#define MASK_SRA 0xfe00707f -#define MATCH_OR 0x6033 -#define MASK_OR 0xfe00707f -#define MATCH_AND 0x7033 -#define MASK_AND 0xfe00707f -#define MATCH_LB 0x3 -#define MASK_LB 0x707f -#define MATCH_LH 0x1003 -#define MASK_LH 0x707f -#define MATCH_LW 0x2003 -#define MASK_LW 0x707f -#define MATCH_LBU 0x4003 -#define MASK_LBU 0x707f -#define MATCH_LHU 0x5003 -#define MASK_LHU 0x707f -#define MATCH_SB 0x23 -#define MASK_SB 0x707f -#define MATCH_SH 0x1023 -#define MASK_SH 0x707f -#define MATCH_SW 0x2023 -#define MASK_SW 0x707f -#define MATCH_FENCE 0xf -#define MASK_FENCE 0x707f -#define MATCH_FENCE_I 0x100f -#define MASK_FENCE_I 0x707f -#define MATCH_ADDIW 0x1b -#define MASK_ADDIW 0x707f -#define MATCH_SLLIW 0x101b -#define MASK_SLLIW 0xfe00707f -#define MATCH_SRLIW 0x501b -#define MASK_SRLIW 0xfe00707f -#define MATCH_SRAIW 0x4000501b -#define MASK_SRAIW 0xfe00707f -#define MATCH_ADDW 0x3b -#define MASK_ADDW 0xfe00707f -#define MATCH_SUBW 0x4000003b -#define MASK_SUBW 0xfe00707f -#define MATCH_SLLW 0x103b -#define MASK_SLLW 0xfe00707f -#define MATCH_SRLW 0x503b -#define MASK_SRLW 0xfe00707f -#define MATCH_SRAW 0x4000503b -#define MASK_SRAW 0xfe00707f -#define MATCH_LD 0x3003 -#define MASK_LD 0x707f -#define MATCH_LWU 0x6003 -#define MASK_LWU 0x707f -#define MATCH_SD 0x3023 -#define MASK_SD 0x707f -#define MATCH_SLLI 0x1013 -#define MASK_SLLI 0xfc00707f -#define MATCH_SRLI 0x5013 -#define MASK_SRLI 0xfc00707f -#define MATCH_SRAI 0x40005013 -#define MASK_SRAI 0xfc00707f -#define MATCH_MUL 0x2000033 -#define MASK_MUL 0xfe00707f -#define MATCH_MULH 0x2001033 -#define MASK_MULH 0xfe00707f -#define MATCH_MULHSU 0x2002033 -#define MASK_MULHSU 0xfe00707f -#define MATCH_MULHU 0x2003033 -#define MASK_MULHU 0xfe00707f -#define MATCH_DIV 0x2004033 -#define MASK_DIV 0xfe00707f -#define MATCH_DIVU 0x2005033 -#define MASK_DIVU 0xfe00707f -#define MATCH_REM 0x2006033 -#define MASK_REM 0xfe00707f -#define MATCH_REMU 0x2007033 -#define MASK_REMU 0xfe00707f -#define MATCH_MULW 0x200003b -#define MASK_MULW 0xfe00707f -#define MATCH_DIVW 0x200403b -#define MASK_DIVW 0xfe00707f -#define MATCH_DIVUW 0x200503b -#define MASK_DIVUW 0xfe00707f -#define MATCH_REMW 0x200603b -#define MASK_REMW 0xfe00707f -#define MATCH_REMUW 0x200703b -#define MASK_REMUW 0xfe00707f -#define MATCH_AMOADD_W 0x202f -#define MASK_AMOADD_W 0xf800707f -#define MATCH_AMOXOR_W 0x2000202f -#define MASK_AMOXOR_W 0xf800707f -#define MATCH_AMOOR_W 0x4000202f -#define MASK_AMOOR_W 0xf800707f -#define MATCH_AMOAND_W 0x6000202f -#define MASK_AMOAND_W 0xf800707f -#define MATCH_AMOMIN_W 0x8000202f -#define MASK_AMOMIN_W 0xf800707f -#define MATCH_AMOMAX_W 0xa000202f -#define MASK_AMOMAX_W 0xf800707f -#define MATCH_AMOMINU_W 0xc000202f -#define MASK_AMOMINU_W 0xf800707f -#define MATCH_AMOMAXU_W 0xe000202f -#define MASK_AMOMAXU_W 0xf800707f -#define MATCH_AMOSWAP_W 0x800202f -#define MASK_AMOSWAP_W 0xf800707f -#define MATCH_LR_W 0x1000202f -#define MASK_LR_W 0xf9f0707f -#define MATCH_SC_W 0x1800202f -#define MASK_SC_W 0xf800707f -#define MATCH_AMOADD_D 0x302f -#define MASK_AMOADD_D 0xf800707f -#define MATCH_AMOXOR_D 0x2000302f -#define MASK_AMOXOR_D 0xf800707f -#define MATCH_AMOOR_D 0x4000302f -#define MASK_AMOOR_D 0xf800707f -#define MATCH_AMOAND_D 0x6000302f -#define MASK_AMOAND_D 0xf800707f -#define MATCH_AMOMIN_D 0x8000302f -#define MASK_AMOMIN_D 0xf800707f -#define MATCH_AMOMAX_D 0xa000302f -#define MASK_AMOMAX_D 0xf800707f -#define MATCH_AMOMINU_D 0xc000302f -#define MASK_AMOMINU_D 0xf800707f -#define MATCH_AMOMAXU_D 0xe000302f -#define MASK_AMOMAXU_D 0xf800707f -#define MATCH_AMOSWAP_D 0x800302f -#define MASK_AMOSWAP_D 0xf800707f -#define MATCH_LR_D 0x1000302f -#define MASK_LR_D 0xf9f0707f -#define MATCH_SC_D 0x1800302f -#define MASK_SC_D 0xf800707f -#define MATCH_HFENCE_VVMA 0x22000073 -#define MASK_HFENCE_VVMA 0xfe007fff -#define MATCH_HFENCE_GVMA 0x62000073 -#define MASK_HFENCE_GVMA 0xfe007fff -#define MATCH_HLV_B 0x60004073 -#define MASK_HLV_B 0xfff0707f -#define MATCH_HLV_BU 0x60104073 -#define MASK_HLV_BU 0xfff0707f -#define MATCH_HLV_H 0x64004073 -#define MASK_HLV_H 0xfff0707f -#define MATCH_HLV_HU 0x64104073 -#define MASK_HLV_HU 0xfff0707f -#define MATCH_HLVX_HU 0x64304073 -#define MASK_HLVX_HU 0xfff0707f -#define MATCH_HLV_W 0x68004073 -#define MASK_HLV_W 0xfff0707f -#define MATCH_HLVX_WU 0x68304073 -#define MASK_HLVX_WU 0xfff0707f -#define MATCH_HSV_B 0x62004073 -#define MASK_HSV_B 0xfe007fff -#define MATCH_HSV_H 0x66004073 -#define MASK_HSV_H 0xfe007fff -#define MATCH_HSV_W 0x6a004073 -#define MASK_HSV_W 0xfe007fff -#define MATCH_HLV_WU 0x68104073 -#define MASK_HLV_WU 0xfff0707f -#define MATCH_HLV_D 0x6c004073 -#define MASK_HLV_D 0xfff0707f -#define MATCH_HSV_D 0x6e004073 -#define MASK_HSV_D 0xfe007fff -#define MATCH_FADD_S 0x53 -#define MASK_FADD_S 0xfe00007f -#define MATCH_FSUB_S 0x8000053 -#define MASK_FSUB_S 0xfe00007f -#define MATCH_FMUL_S 0x10000053 -#define MASK_FMUL_S 0xfe00007f -#define MATCH_FDIV_S 0x18000053 -#define MASK_FDIV_S 0xfe00007f -#define MATCH_FSGNJ_S 0x20000053 -#define MASK_FSGNJ_S 0xfe00707f -#define MATCH_FSGNJN_S 0x20001053 -#define MASK_FSGNJN_S 0xfe00707f -#define MATCH_FSGNJX_S 0x20002053 -#define MASK_FSGNJX_S 0xfe00707f -#define MATCH_FMIN_S 0x28000053 -#define MASK_FMIN_S 0xfe00707f -#define MATCH_FMAX_S 0x28001053 -#define MASK_FMAX_S 0xfe00707f -#define MATCH_FSQRT_S 0x58000053 -#define MASK_FSQRT_S 0xfff0007f -#define MATCH_FLE_S 0xa0000053 -#define MASK_FLE_S 0xfe00707f -#define MATCH_FLT_S 0xa0001053 -#define MASK_FLT_S 0xfe00707f -#define MATCH_FEQ_S 0xa0002053 -#define MASK_FEQ_S 0xfe00707f -#define MATCH_FCVT_W_S 0xc0000053 -#define MASK_FCVT_W_S 0xfff0007f -#define MATCH_FCVT_WU_S 0xc0100053 -#define MASK_FCVT_WU_S 0xfff0007f -#define MATCH_FMV_X_W 0xe0000053 -#define MASK_FMV_X_W 0xfff0707f -#define MATCH_FCLASS_S 0xe0001053 -#define MASK_FCLASS_S 0xfff0707f -#define MATCH_FCVT_S_W 0xd0000053 -#define MASK_FCVT_S_W 0xfff0007f -#define MATCH_FCVT_S_WU 0xd0100053 -#define MASK_FCVT_S_WU 0xfff0007f -#define MATCH_FMV_W_X 0xf0000053 -#define MASK_FMV_W_X 0xfff0707f -#define MATCH_FLW 0x2007 -#define MASK_FLW 0x707f -#define MATCH_FSW 0x2027 -#define MASK_FSW 0x707f -#define MATCH_FMADD_S 0x43 -#define MASK_FMADD_S 0x600007f -#define MATCH_FMSUB_S 0x47 -#define MASK_FMSUB_S 0x600007f -#define MATCH_FNMSUB_S 0x4b -#define MASK_FNMSUB_S 0x600007f -#define MATCH_FNMADD_S 0x4f -#define MASK_FNMADD_S 0x600007f -#define MATCH_FCVT_L_S 0xc0200053 -#define MASK_FCVT_L_S 0xfff0007f -#define MATCH_FCVT_LU_S 0xc0300053 -#define MASK_FCVT_LU_S 0xfff0007f -#define MATCH_FCVT_S_L 0xd0200053 -#define MASK_FCVT_S_L 0xfff0007f -#define MATCH_FCVT_S_LU 0xd0300053 -#define MASK_FCVT_S_LU 0xfff0007f -#define MATCH_FADD_D 0x2000053 -#define MASK_FADD_D 0xfe00007f -#define MATCH_FSUB_D 0xa000053 -#define MASK_FSUB_D 0xfe00007f -#define MATCH_FMUL_D 0x12000053 -#define MASK_FMUL_D 0xfe00007f -#define MATCH_FDIV_D 0x1a000053 -#define MASK_FDIV_D 0xfe00007f -#define MATCH_FSGNJ_D 0x22000053 -#define MASK_FSGNJ_D 0xfe00707f -#define MATCH_FSGNJN_D 0x22001053 -#define MASK_FSGNJN_D 0xfe00707f -#define MATCH_FSGNJX_D 0x22002053 -#define MASK_FSGNJX_D 0xfe00707f -#define MATCH_FMIN_D 0x2a000053 -#define MASK_FMIN_D 0xfe00707f -#define MATCH_FMAX_D 0x2a001053 -#define MASK_FMAX_D 0xfe00707f -#define MATCH_FCVT_S_D 0x40100053 -#define MASK_FCVT_S_D 0xfff0007f -#define MATCH_FCVT_D_S 0x42000053 -#define MASK_FCVT_D_S 0xfff0007f -#define MATCH_FSQRT_D 0x5a000053 -#define MASK_FSQRT_D 0xfff0007f -#define MATCH_FLE_D 0xa2000053 -#define MASK_FLE_D 0xfe00707f -#define MATCH_FLT_D 0xa2001053 -#define MASK_FLT_D 0xfe00707f -#define MATCH_FEQ_D 0xa2002053 -#define MASK_FEQ_D 0xfe00707f -#define MATCH_FCVT_W_D 0xc2000053 -#define MASK_FCVT_W_D 0xfff0007f -#define MATCH_FCVT_WU_D 0xc2100053 -#define MASK_FCVT_WU_D 0xfff0007f -#define MATCH_FCLASS_D 0xe2001053 -#define MASK_FCLASS_D 0xfff0707f -#define MATCH_FCVT_D_W 0xd2000053 -#define MASK_FCVT_D_W 0xfff0007f -#define MATCH_FCVT_D_WU 0xd2100053 -#define MASK_FCVT_D_WU 0xfff0007f -#define MATCH_FLD 0x3007 -#define MASK_FLD 0x707f -#define MATCH_FSD 0x3027 -#define MASK_FSD 0x707f -#define MATCH_FMADD_D 0x2000043 -#define MASK_FMADD_D 0x600007f -#define MATCH_FMSUB_D 0x2000047 -#define MASK_FMSUB_D 0x600007f -#define MATCH_FNMSUB_D 0x200004b -#define MASK_FNMSUB_D 0x600007f -#define MATCH_FNMADD_D 0x200004f -#define MASK_FNMADD_D 0x600007f -#define MATCH_FCVT_L_D 0xc2200053 -#define MASK_FCVT_L_D 0xfff0007f -#define MATCH_FCVT_LU_D 0xc2300053 -#define MASK_FCVT_LU_D 0xfff0007f -#define MATCH_FMV_X_D 0xe2000053 -#define MASK_FMV_X_D 0xfff0707f -#define MATCH_FCVT_D_L 0xd2200053 -#define MASK_FCVT_D_L 0xfff0007f -#define MATCH_FCVT_D_LU 0xd2300053 -#define MASK_FCVT_D_LU 0xfff0007f -#define MATCH_FMV_D_X 0xf2000053 -#define MASK_FMV_D_X 0xfff0707f -#define MATCH_FADD_Q 0x6000053 -#define MASK_FADD_Q 0xfe00007f -#define MATCH_FSUB_Q 0xe000053 -#define MASK_FSUB_Q 0xfe00007f -#define MATCH_FMUL_Q 0x16000053 -#define MASK_FMUL_Q 0xfe00007f -#define MATCH_FDIV_Q 0x1e000053 -#define MASK_FDIV_Q 0xfe00007f -#define MATCH_FSGNJ_Q 0x26000053 -#define MASK_FSGNJ_Q 0xfe00707f -#define MATCH_FSGNJN_Q 0x26001053 -#define MASK_FSGNJN_Q 0xfe00707f -#define MATCH_FSGNJX_Q 0x26002053 -#define MASK_FSGNJX_Q 0xfe00707f -#define MATCH_FMIN_Q 0x2e000053 -#define MASK_FMIN_Q 0xfe00707f -#define MATCH_FMAX_Q 0x2e001053 -#define MASK_FMAX_Q 0xfe00707f -#define MATCH_FCVT_S_Q 0x40300053 -#define MASK_FCVT_S_Q 0xfff0007f -#define MATCH_FCVT_Q_S 0x46000053 -#define MASK_FCVT_Q_S 0xfff0007f -#define MATCH_FCVT_D_Q 0x42300053 -#define MASK_FCVT_D_Q 0xfff0007f -#define MATCH_FCVT_Q_D 0x46100053 -#define MASK_FCVT_Q_D 0xfff0007f -#define MATCH_FSQRT_Q 0x5e000053 -#define MASK_FSQRT_Q 0xfff0007f -#define MATCH_FLE_Q 0xa6000053 -#define MASK_FLE_Q 0xfe00707f -#define MATCH_FLT_Q 0xa6001053 -#define MASK_FLT_Q 0xfe00707f -#define MATCH_FEQ_Q 0xa6002053 -#define MASK_FEQ_Q 0xfe00707f -#define MATCH_FCVT_W_Q 0xc6000053 -#define MASK_FCVT_W_Q 0xfff0007f -#define MATCH_FCVT_WU_Q 0xc6100053 -#define MASK_FCVT_WU_Q 0xfff0007f -#define MATCH_FCLASS_Q 0xe6001053 -#define MASK_FCLASS_Q 0xfff0707f -#define MATCH_FCVT_Q_W 0xd6000053 -#define MASK_FCVT_Q_W 0xfff0007f -#define MATCH_FCVT_Q_WU 0xd6100053 -#define MASK_FCVT_Q_WU 0xfff0007f -#define MATCH_FLQ 0x4007 -#define MASK_FLQ 0x707f -#define MATCH_FSQ 0x4027 -#define MASK_FSQ 0x707f -#define MATCH_FMADD_Q 0x6000043 -#define MASK_FMADD_Q 0x600007f -#define MATCH_FMSUB_Q 0x6000047 -#define MASK_FMSUB_Q 0x600007f -#define MATCH_FNMSUB_Q 0x600004b -#define MASK_FNMSUB_Q 0x600007f -#define MATCH_FNMADD_Q 0x600004f -#define MASK_FNMADD_Q 0x600007f -#define MATCH_FCVT_L_Q 0xc6200053 -#define MASK_FCVT_L_Q 0xfff0007f -#define MATCH_FCVT_LU_Q 0xc6300053 -#define MASK_FCVT_LU_Q 0xfff0007f -#define MATCH_FCVT_Q_L 0xd6200053 -#define MASK_FCVT_Q_L 0xfff0007f -#define MATCH_FCVT_Q_LU 0xd6300053 -#define MASK_FCVT_Q_LU 0xfff0007f -#define MATCH_ANDN 0x40007033 -#define MASK_ANDN 0xfe00707f -#define MATCH_ORN 0x40006033 -#define MASK_ORN 0xfe00707f -#define MATCH_XNOR 0x40004033 -#define MASK_XNOR 0xfe00707f -#define MATCH_SLO 0x20001033 -#define MASK_SLO 0xfe00707f -#define MATCH_SRO 0x20005033 -#define MASK_SRO 0xfe00707f -#define MATCH_ROL 0x60001033 -#define MASK_ROL 0xfe00707f -#define MATCH_ROR 0x60005033 -#define MASK_ROR 0xfe00707f -#define MATCH_BCLR 0x48001033 -#define MASK_BCLR 0xfe00707f -#define MATCH_BSET 0x28001033 -#define MASK_BSET 0xfe00707f -#define MATCH_BINV 0x68001033 -#define MASK_BINV 0xfe00707f -#define MATCH_BEXT 0x48005033 -#define MASK_BEXT 0xfe00707f -#define MATCH_GORC 0x28005033 -#define MASK_GORC 0xfe00707f -#define MATCH_GREV 0x68005033 -#define MASK_GREV 0xfe00707f -#define MATCH_SLOI 0x20001013 -#define MASK_SLOI 0xfc00707f -#define MATCH_SROI 0x20005013 -#define MASK_SROI 0xfc00707f -#define MATCH_RORI 0x60005013 -#define MASK_RORI 0xfc00707f -#define MATCH_BCLRI 0x48001013 -#define MASK_BCLRI 0xfc00707f -#define MATCH_BSETI 0x28001013 -#define MASK_BSETI 0xfc00707f -#define MATCH_BINVI 0x68001013 -#define MASK_BINVI 0xfc00707f -#define MATCH_BEXTI 0x48005013 -#define MASK_BEXTI 0xfc00707f -#define MATCH_GORCI 0x28005013 -#define MASK_GORCI 0xfc00707f -#define MATCH_GREVI 0x68005013 -#define MASK_GREVI 0xfc00707f -#define MATCH_CMIX 0x6001033 -#define MASK_CMIX 0x600707f -#define MATCH_CMOV 0x6005033 -#define MASK_CMOV 0x600707f -#define MATCH_FSL 0x4001033 -#define MASK_FSL 0x600707f -#define MATCH_FSR 0x4005033 -#define MASK_FSR 0x600707f -#define MATCH_FSRI 0x4005013 -#define MASK_FSRI 0x400707f -#define MATCH_CLZ 0x60001013 -#define MASK_CLZ 0xfff0707f -#define MATCH_CTZ 0x60101013 -#define MASK_CTZ 0xfff0707f -#define MATCH_CPOP 0x60201013 -#define MASK_CPOP 0xfff0707f -#define MATCH_SEXT_B 0x60401013 -#define MASK_SEXT_B 0xfff0707f -#define MATCH_SEXT_H 0x60501013 -#define MASK_SEXT_H 0xfff0707f -#define MATCH_CRC32_B 0x61001013 -#define MASK_CRC32_B 0xfff0707f -#define MATCH_CRC32_H 0x61101013 -#define MASK_CRC32_H 0xfff0707f -#define MATCH_CRC32_W 0x61201013 -#define MASK_CRC32_W 0xfff0707f -#define MATCH_CRC32C_B 0x61801013 -#define MASK_CRC32C_B 0xfff0707f -#define MATCH_CRC32C_H 0x61901013 -#define MASK_CRC32C_H 0xfff0707f -#define MATCH_CRC32C_W 0x61a01013 -#define MASK_CRC32C_W 0xfff0707f -#define MATCH_SH1ADD 0x20002033 -#define MASK_SH1ADD 0xfe00707f -#define MATCH_SH2ADD 0x20004033 -#define MASK_SH2ADD 0xfe00707f -#define MATCH_SH3ADD 0x20006033 -#define MASK_SH3ADD 0xfe00707f -#define MATCH_CLMUL 0xa001033 -#define MASK_CLMUL 0xfe00707f -#define MATCH_CLMULR 0xa002033 -#define MASK_CLMULR 0xfe00707f -#define MATCH_CLMULH 0xa003033 -#define MASK_CLMULH 0xfe00707f -#define MATCH_MIN 0xa004033 -#define MASK_MIN 0xfe00707f -#define MATCH_MINU 0xa005033 -#define MASK_MINU 0xfe00707f -#define MATCH_MAX 0xa006033 -#define MASK_MAX 0xfe00707f -#define MATCH_MAXU 0xa007033 -#define MASK_MAXU 0xfe00707f -#define MATCH_SHFL 0x8001033 -#define MASK_SHFL 0xfe00707f -#define MATCH_UNSHFL 0x8005033 -#define MASK_UNSHFL 0xfe00707f -#define MATCH_BCOMPRESS 0x8006033 -#define MASK_BCOMPRESS 0xfe00707f -#define MATCH_BDECOMPRESS 0x48006033 -#define MASK_BDECOMPRESS 0xfe00707f -#define MATCH_PACK 0x8004033 -#define MASK_PACK 0xfe00707f -#define MATCH_PACKU 0x48004033 -#define MASK_PACKU 0xfe00707f -#define MATCH_PACKH 0x8007033 -#define MASK_PACKH 0xfe00707f -#define MATCH_BFP 0x48007033 -#define MASK_BFP 0xfe00707f -#define MATCH_SHFLI 0x8001013 -#define MASK_SHFLI 0xfe00707f -#define MATCH_UNSHFLI 0x8005013 -#define MASK_UNSHFLI 0xfe00707f -#define MATCH_XPERM4 0x28002033 -#define MASK_XPERM4 0xfe00707f -#define MATCH_XPERM8 0x28004033 -#define MASK_XPERM8 0xfe00707f -#define MATCH_XPERM16 0x28006033 -#define MASK_XPERM16 0xfe00707f -#define MATCH_BMATFLIP 0x60301013 -#define MASK_BMATFLIP 0xfff0707f -#define MATCH_CRC32_D 0x61301013 -#define MASK_CRC32_D 0xfff0707f -#define MATCH_CRC32C_D 0x61b01013 -#define MASK_CRC32C_D 0xfff0707f -#define MATCH_BMATOR 0x8003033 -#define MASK_BMATOR 0xfe00707f -#define MATCH_BMATXOR 0x48003033 -#define MASK_BMATXOR 0xfe00707f -#define MATCH_SLLI_UW 0x800101b -#define MASK_SLLI_UW 0xfc00707f -#define MATCH_ADD_UW 0x800003b -#define MASK_ADD_UW 0xfe00707f -#define MATCH_SLOW 0x2000103b -#define MASK_SLOW 0xfe00707f -#define MATCH_SROW 0x2000503b -#define MASK_SROW 0xfe00707f -#define MATCH_ROLW 0x6000103b -#define MASK_ROLW 0xfe00707f -#define MATCH_RORW 0x6000503b -#define MASK_RORW 0xfe00707f -#define MATCH_SBCLRW 0x4800103b -#define MASK_SBCLRW 0xfe00707f -#define MATCH_SBSETW 0x2800103b -#define MASK_SBSETW 0xfe00707f -#define MATCH_SBINVW 0x6800103b -#define MASK_SBINVW 0xfe00707f -#define MATCH_SBEXTW 0x4800503b -#define MASK_SBEXTW 0xfe00707f -#define MATCH_GORCW 0x2800503b -#define MASK_GORCW 0xfe00707f -#define MATCH_GREVW 0x6800503b -#define MASK_GREVW 0xfe00707f -#define MATCH_SLOIW 0x2000101b -#define MASK_SLOIW 0xfe00707f -#define MATCH_SROIW 0x2000501b -#define MASK_SROIW 0xfe00707f -#define MATCH_RORIW 0x6000501b -#define MASK_RORIW 0xfe00707f -#define MATCH_SBCLRIW 0x4800101b -#define MASK_SBCLRIW 0xfe00707f -#define MATCH_SBSETIW 0x2800101b -#define MASK_SBSETIW 0xfe00707f -#define MATCH_SBINVIW 0x6800101b -#define MASK_SBINVIW 0xfe00707f -#define MATCH_GORCIW 0x2800501b -#define MASK_GORCIW 0xfe00707f -#define MATCH_GREVIW 0x6800501b -#define MASK_GREVIW 0xfe00707f -#define MATCH_FSLW 0x400103b -#define MASK_FSLW 0x600707f -#define MATCH_FSRW 0x400503b -#define MASK_FSRW 0x600707f -#define MATCH_FSRIW 0x400501b -#define MASK_FSRIW 0x600707f -#define MATCH_CLZW 0x6000101b -#define MASK_CLZW 0xfff0707f -#define MATCH_CTZW 0x6010101b -#define MASK_CTZW 0xfff0707f -#define MATCH_CPOPW 0x6020101b -#define MASK_CPOPW 0xfff0707f -#define MATCH_SH1ADD_UW 0x2000203b -#define MASK_SH1ADD_UW 0xfe00707f -#define MATCH_SH2ADD_UW 0x2000403b -#define MASK_SH2ADD_UW 0xfe00707f -#define MATCH_SH3ADD_UW 0x2000603b -#define MASK_SH3ADD_UW 0xfe00707f -#define MATCH_SHFLW 0x800103b -#define MASK_SHFLW 0xfe00707f -#define MATCH_UNSHFLW 0x800503b -#define MASK_UNSHFLW 0xfe00707f -#define MATCH_BCOMPRESSW 0x800603b -#define MASK_BCOMPRESSW 0xfe00707f -#define MATCH_BDECOMPRESSW 0x4800603b -#define MASK_BDECOMPRESSW 0xfe00707f -#define MATCH_PACKW 0x800403b -#define MASK_PACKW 0xfe00707f -#define MATCH_PACKUW 0x4800403b -#define MASK_PACKUW 0xfe00707f -#define MATCH_BFPW 0x4800703b -#define MASK_BFPW 0xfe00707f -#define MATCH_XPERM32 0x28000033 -#define MASK_XPERM32 0xfe00707f -#define MATCH_ECALL 0x73 -#define MASK_ECALL 0xffffffff -#define MATCH_EBREAK 0x100073 -#define MASK_EBREAK 0xffffffff -#define MATCH_SRET 0x10200073 -#define MASK_SRET 0xffffffff -#define MATCH_MRET 0x30200073 -#define MASK_MRET 0xffffffff -#define MATCH_DRET 0x7b200073 -#define MASK_DRET 0xffffffff -#define MATCH_SFENCE_VMA 0x12000073 -#define MASK_SFENCE_VMA 0xfe007fff -#define MATCH_WFI 0x10500073 -#define MASK_WFI 0xffffffff -#define MATCH_CSRRW 0x1073 -#define MASK_CSRRW 0x707f -#define MATCH_CSRRS 0x2073 -#define MASK_CSRRS 0x707f -#define MATCH_CSRRC 0x3073 -#define MASK_CSRRC 0x707f -#define MATCH_CSRRWI 0x5073 -#define MASK_CSRRWI 0x707f -#define MATCH_CSRRSI 0x6073 -#define MASK_CSRRSI 0x707f -#define MATCH_CSRRCI 0x7073 -#define MASK_CSRRCI 0x707f -#define MATCH_SINVAL_VMA 0x16000073 -#define MASK_SINVAL_VMA 0xfe007fff -#define MATCH_SFENCE_W_INVAL 0x18000073 -#define MASK_SFENCE_W_INVAL 0xffffffff -#define MATCH_SFENCE_INVAL_IR 0x18100073 -#define MASK_SFENCE_INVAL_IR 0xffffffff -#define MATCH_HINVAL_VVMA 0x36000073 -#define MASK_HINVAL_VVMA 0xfe007fff -#define MATCH_HINVAL_GVMA 0x76000073 -#define MASK_HINVAL_GVMA 0xfe007fff -#define MATCH_FADD_H 0x4000053 -#define MASK_FADD_H 0xfe00007f -#define MATCH_FSUB_H 0xc000053 -#define MASK_FSUB_H 0xfe00007f -#define MATCH_FMUL_H 0x14000053 -#define MASK_FMUL_H 0xfe00007f -#define MATCH_FDIV_H 0x1c000053 -#define MASK_FDIV_H 0xfe00007f -#define MATCH_FSGNJ_H 0x24000053 -#define MASK_FSGNJ_H 0xfe00707f -#define MATCH_FSGNJN_H 0x24001053 -#define MASK_FSGNJN_H 0xfe00707f -#define MATCH_FSGNJX_H 0x24002053 -#define MASK_FSGNJX_H 0xfe00707f -#define MATCH_FMIN_H 0x2c000053 -#define MASK_FMIN_H 0xfe00707f -#define MATCH_FMAX_H 0x2c001053 -#define MASK_FMAX_H 0xfe00707f -#define MATCH_FCVT_H_S 0x44000053 -#define MASK_FCVT_H_S 0xfff0007f -#define MATCH_FCVT_S_H 0x40200053 -#define MASK_FCVT_S_H 0xfff0007f -#define MATCH_FSQRT_H 0x5c000053 -#define MASK_FSQRT_H 0xfff0007f -#define MATCH_FLE_H 0xa4000053 -#define MASK_FLE_H 0xfe00707f -#define MATCH_FLT_H 0xa4001053 -#define MASK_FLT_H 0xfe00707f -#define MATCH_FEQ_H 0xa4002053 -#define MASK_FEQ_H 0xfe00707f -#define MATCH_FCVT_W_H 0xc4000053 -#define MASK_FCVT_W_H 0xfff0007f -#define MATCH_FCVT_WU_H 0xc4100053 -#define MASK_FCVT_WU_H 0xfff0007f -#define MATCH_FMV_X_H 0xe4000053 -#define MASK_FMV_X_H 0xfff0707f -#define MATCH_FCLASS_H 0xe4001053 -#define MASK_FCLASS_H 0xfff0707f -#define MATCH_FCVT_H_W 0xd4000053 -#define MASK_FCVT_H_W 0xfff0007f -#define MATCH_FCVT_H_WU 0xd4100053 -#define MASK_FCVT_H_WU 0xfff0007f -#define MATCH_FMV_H_X 0xf4000053 -#define MASK_FMV_H_X 0xfff0707f -#define MATCH_FLH 0x1007 -#define MASK_FLH 0x707f -#define MATCH_FSH 0x1027 -#define MASK_FSH 0x707f -#define MATCH_FMADD_H 0x4000043 -#define MASK_FMADD_H 0x600007f -#define MATCH_FMSUB_H 0x4000047 -#define MASK_FMSUB_H 0x600007f -#define MATCH_FNMSUB_H 0x400004b -#define MASK_FNMSUB_H 0x600007f -#define MATCH_FNMADD_H 0x400004f -#define MASK_FNMADD_H 0x600007f -#define MATCH_FCVT_H_D 0x44100053 -#define MASK_FCVT_H_D 0xfff0007f -#define MATCH_FCVT_D_H 0x42200053 -#define MASK_FCVT_D_H 0xfff0007f -#define MATCH_FCVT_H_Q 0x44300053 -#define MASK_FCVT_H_Q 0xfff0007f -#define MATCH_FCVT_Q_H 0x46200053 -#define MASK_FCVT_Q_H 0xfff0007f -#define MATCH_FCVT_L_H 0xc4200053 -#define MASK_FCVT_L_H 0xfff0007f -#define MATCH_FCVT_LU_H 0xc4300053 -#define MASK_FCVT_LU_H 0xfff0007f -#define MATCH_FCVT_H_L 0xd4200053 -#define MASK_FCVT_H_L 0xfff0007f -#define MATCH_FCVT_H_LU 0xd4300053 -#define MASK_FCVT_H_LU 0xfff0007f -#define MATCH_SM4ED 0x30000033 -#define MASK_SM4ED 0x3e00707f -#define MATCH_SM4KS 0x34000033 -#define MASK_SM4KS 0x3e00707f -#define MATCH_SM3P0 0x10801013 -#define MASK_SM3P0 0xfff0707f -#define MATCH_SM3P1 0x10901013 -#define MASK_SM3P1 0xfff0707f -#define MATCH_SHA256SUM0 0x10001013 -#define MASK_SHA256SUM0 0xfff0707f -#define MATCH_SHA256SUM1 0x10101013 -#define MASK_SHA256SUM1 0xfff0707f -#define MATCH_SHA256SIG0 0x10201013 -#define MASK_SHA256SIG0 0xfff0707f -#define MATCH_SHA256SIG1 0x10301013 -#define MASK_SHA256SIG1 0xfff0707f -#define MATCH_AES32ESMI 0x26000033 -#define MASK_AES32ESMI 0x3e00707f -#define MATCH_AES32ESI 0x22000033 -#define MASK_AES32ESI 0x3e00707f -#define MATCH_AES32DSMI 0x2e000033 -#define MASK_AES32DSMI 0x3e00707f -#define MATCH_AES32DSI 0x2a000033 -#define MASK_AES32DSI 0x3e00707f -#define MATCH_SHA512SUM0R 0x50000033 -#define MASK_SHA512SUM0R 0xfe00707f -#define MATCH_SHA512SUM1R 0x52000033 -#define MASK_SHA512SUM1R 0xfe00707f -#define MATCH_SHA512SIG0L 0x54000033 -#define MASK_SHA512SIG0L 0xfe00707f -#define MATCH_SHA512SIG0H 0x5c000033 -#define MASK_SHA512SIG0H 0xfe00707f -#define MATCH_SHA512SIG1L 0x56000033 -#define MASK_SHA512SIG1L 0xfe00707f -#define MATCH_SHA512SIG1H 0x5e000033 -#define MASK_SHA512SIG1H 0xfe00707f -#define MATCH_AES64KS1I 0x31001013 -#define MASK_AES64KS1I 0xff00707f -#define MATCH_AES64IM 0x30001013 -#define MASK_AES64IM 0xfff0707f -#define MATCH_AES64KS2 0x7e000033 -#define MASK_AES64KS2 0xfe00707f -#define MATCH_AES64ESM 0x36000033 -#define MASK_AES64ESM 0xfe00707f -#define MATCH_AES64ES 0x32000033 -#define MASK_AES64ES 0xfe00707f -#define MATCH_AES64DSM 0x3e000033 -#define MASK_AES64DSM 0xfe00707f -#define MATCH_AES64DS 0x3a000033 -#define MASK_AES64DS 0xfe00707f -#define MATCH_SHA512SUM0 0x10401013 -#define MASK_SHA512SUM0 0xfff0707f -#define MATCH_SHA512SUM1 0x10501013 -#define MASK_SHA512SUM1 0xfff0707f -#define MATCH_SHA512SIG0 0x10601013 -#define MASK_SHA512SIG0 0xfff0707f -#define MATCH_SHA512SIG1 0x10701013 -#define MASK_SHA512SIG1 0xfff0707f -#define MATCH_C_NOP 0x1 -#define MASK_C_NOP 0xffff -#define MATCH_C_ADDI16SP 0x6101 -#define MASK_C_ADDI16SP 0xef83 -#define MATCH_C_JR 0x8002 -#define MASK_C_JR 0xf07f -#define MATCH_C_JALR 0x9002 -#define MASK_C_JALR 0xf07f -#define MATCH_C_EBREAK 0x9002 -#define MASK_C_EBREAK 0xffff -#define MATCH_C_ADDI4SPN 0x0 -#define MASK_C_ADDI4SPN 0xe003 -#define MATCH_C_FLD 0x2000 -#define MASK_C_FLD 0xe003 -#define MATCH_C_LW 0x4000 -#define MASK_C_LW 0xe003 -#define MATCH_C_FLW 0x6000 -#define MASK_C_FLW 0xe003 -#define MATCH_C_FSD 0xa000 -#define MASK_C_FSD 0xe003 -#define MATCH_C_SW 0xc000 -#define MASK_C_SW 0xe003 -#define MATCH_C_FSW 0xe000 -#define MASK_C_FSW 0xe003 -#define MATCH_C_ADDI 0x1 -#define MASK_C_ADDI 0xe003 -#define MATCH_C_JAL 0x2001 -#define MASK_C_JAL 0xe003 -#define MATCH_C_LI 0x4001 -#define MASK_C_LI 0xe003 -#define MATCH_C_LUI 0x6001 -#define MASK_C_LUI 0xe003 -#define MATCH_C_SRLI 0x8001 -#define MASK_C_SRLI 0xec03 -#define MATCH_C_SRAI 0x8401 -#define MASK_C_SRAI 0xec03 -#define MATCH_C_ANDI 0x8801 -#define MASK_C_ANDI 0xec03 -#define MATCH_C_SUB 0x8c01 -#define MASK_C_SUB 0xfc63 -#define MATCH_C_XOR 0x8c21 -#define MASK_C_XOR 0xfc63 -#define MATCH_C_OR 0x8c41 -#define MASK_C_OR 0xfc63 -#define MATCH_C_AND 0x8c61 -#define MASK_C_AND 0xfc63 -#define MATCH_C_J 0xa001 -#define MASK_C_J 0xe003 -#define MATCH_C_BEQZ 0xc001 -#define MASK_C_BEQZ 0xe003 -#define MATCH_C_BNEZ 0xe001 -#define MASK_C_BNEZ 0xe003 -#define MATCH_C_SLLI 0x2 -#define MASK_C_SLLI 0xe003 -#define MATCH_C_FLDSP 0x2002 -#define MASK_C_FLDSP 0xe003 -#define MATCH_C_LWSP 0x4002 -#define MASK_C_LWSP 0xe003 -#define MATCH_C_FLWSP 0x6002 -#define MASK_C_FLWSP 0xe003 -#define MATCH_C_MV 0x8002 -#define MASK_C_MV 0xf003 -#define MATCH_C_ADD 0x9002 -#define MASK_C_ADD 0xf003 -#define MATCH_C_FSDSP 0xa002 -#define MASK_C_FSDSP 0xe003 -#define MATCH_C_SWSP 0xc002 -#define MASK_C_SWSP 0xe003 -#define MATCH_C_FSWSP 0xe002 -#define MASK_C_FSWSP 0xe003 -#define MATCH_C_SRLI_RV32 0x8001 -#define MASK_C_SRLI_RV32 0xfc03 -#define MATCH_C_SRAI_RV32 0x8401 -#define MASK_C_SRAI_RV32 0xfc03 -#define MATCH_C_SLLI_RV32 0x2 -#define MASK_C_SLLI_RV32 0xf003 -#define MATCH_C_LD 0x6000 -#define MASK_C_LD 0xe003 -#define MATCH_C_SD 0xe000 -#define MASK_C_SD 0xe003 -#define MATCH_C_SUBW 0x9c01 -#define MASK_C_SUBW 0xfc63 -#define MATCH_C_ADDW 0x9c21 -#define MASK_C_ADDW 0xfc63 -#define MATCH_C_ADDIW 0x2001 -#define MASK_C_ADDIW 0xe003 -#define MATCH_C_LDSP 0x6002 -#define MASK_C_LDSP 0xe003 -#define MATCH_C_SDSP 0xe002 -#define MASK_C_SDSP 0xe003 -#define MATCH_CUSTOM0 0xb -#define MASK_CUSTOM0 0x707f -#define MATCH_CUSTOM0_RS1 0x200b -#define MASK_CUSTOM0_RS1 0x707f -#define MATCH_CUSTOM0_RS1_RS2 0x300b -#define MASK_CUSTOM0_RS1_RS2 0x707f -#define MATCH_CUSTOM0_RD 0x400b -#define MASK_CUSTOM0_RD 0x707f -#define MATCH_CUSTOM0_RD_RS1 0x600b -#define MASK_CUSTOM0_RD_RS1 0x707f -#define MATCH_CUSTOM0_RD_RS1_RS2 0x700b -#define MASK_CUSTOM0_RD_RS1_RS2 0x707f -#define MATCH_CUSTOM1 0x2b -#define MASK_CUSTOM1 0x707f -#define MATCH_CUSTOM1_RS1 0x202b -#define MASK_CUSTOM1_RS1 0x707f -#define MATCH_CUSTOM1_RS1_RS2 0x302b -#define MASK_CUSTOM1_RS1_RS2 0x707f -#define MATCH_CUSTOM1_RD 0x402b -#define MASK_CUSTOM1_RD 0x707f -#define MATCH_CUSTOM1_RD_RS1 0x602b -#define MASK_CUSTOM1_RD_RS1 0x707f -#define MATCH_CUSTOM1_RD_RS1_RS2 0x702b -#define MASK_CUSTOM1_RD_RS1_RS2 0x707f -#define MATCH_CUSTOM2 0x5b -#define MASK_CUSTOM2 0x707f -#define MATCH_CUSTOM2_RS1 0x205b -#define MASK_CUSTOM2_RS1 0x707f -#define MATCH_CUSTOM2_RS1_RS2 0x305b -#define MASK_CUSTOM2_RS1_RS2 0x707f -#define MATCH_CUSTOM2_RD 0x405b -#define MASK_CUSTOM2_RD 0x707f -#define MATCH_CUSTOM2_RD_RS1 0x605b -#define MASK_CUSTOM2_RD_RS1 0x707f -#define MATCH_CUSTOM2_RD_RS1_RS2 0x705b -#define MASK_CUSTOM2_RD_RS1_RS2 0x707f -#define MATCH_CUSTOM3 0x7b -#define MASK_CUSTOM3 0x707f -#define MATCH_CUSTOM3_RS1 0x207b -#define MASK_CUSTOM3_RS1 0x707f -#define MATCH_CUSTOM3_RS1_RS2 0x307b -#define MASK_CUSTOM3_RS1_RS2 0x707f -#define MATCH_CUSTOM3_RD 0x407b -#define MASK_CUSTOM3_RD 0x707f -#define MATCH_CUSTOM3_RD_RS1 0x607b -#define MASK_CUSTOM3_RD_RS1 0x707f -#define MATCH_CUSTOM3_RD_RS1_RS2 0x707b -#define MASK_CUSTOM3_RD_RS1_RS2 0x707f -#define MATCH_VSETIVLI 0xc0007057 -#define MASK_VSETIVLI 0xc000707f -#define MATCH_VSETVLI 0x7057 -#define MASK_VSETVLI 0x8000707f -#define MATCH_VSETVL 0x80007057 -#define MASK_VSETVL 0xfe00707f -#define MATCH_VLM_V 0x2b00007 -#define MASK_VLM_V 0xfff0707f -#define MATCH_VSM_V 0x2b00027 -#define MASK_VSM_V 0xfff0707f -#define MATCH_VLE8_V 0x7 -#define MASK_VLE8_V 0x1df0707f -#define MATCH_VLE16_V 0x5007 -#define MASK_VLE16_V 0x1df0707f -#define MATCH_VLE32_V 0x6007 -#define MASK_VLE32_V 0x1df0707f -#define MATCH_VLE64_V 0x7007 -#define MASK_VLE64_V 0x1df0707f -#define MATCH_VLE128_V 0x10000007 -#define MASK_VLE128_V 0x1df0707f -#define MATCH_VLE256_V 0x10005007 -#define MASK_VLE256_V 0x1df0707f -#define MATCH_VLE512_V 0x10006007 -#define MASK_VLE512_V 0x1df0707f -#define MATCH_VLE1024_V 0x10007007 -#define MASK_VLE1024_V 0x1df0707f -#define MATCH_VSE8_V 0x27 -#define MASK_VSE8_V 0x1df0707f -#define MATCH_VSE16_V 0x5027 -#define MASK_VSE16_V 0x1df0707f -#define MATCH_VSE32_V 0x6027 -#define MASK_VSE32_V 0x1df0707f -#define MATCH_VSE64_V 0x7027 -#define MASK_VSE64_V 0x1df0707f -#define MATCH_VSE128_V 0x10000027 -#define MASK_VSE128_V 0x1df0707f -#define MATCH_VSE256_V 0x10005027 -#define MASK_VSE256_V 0x1df0707f -#define MATCH_VSE512_V 0x10006027 -#define MASK_VSE512_V 0x1df0707f -#define MATCH_VSE1024_V 0x10007027 -#define MASK_VSE1024_V 0x1df0707f -#define MATCH_VLUXEI8_V 0x4000007 -#define MASK_VLUXEI8_V 0x1c00707f -#define MATCH_VLUXEI16_V 0x4005007 -#define MASK_VLUXEI16_V 0x1c00707f -#define MATCH_VLUXEI32_V 0x4006007 -#define MASK_VLUXEI32_V 0x1c00707f -#define MATCH_VLUXEI64_V 0x4007007 -#define MASK_VLUXEI64_V 0x1c00707f -#define MATCH_VLUXEI128_V 0x14000007 -#define MASK_VLUXEI128_V 0x1c00707f -#define MATCH_VLUXEI256_V 0x14005007 -#define MASK_VLUXEI256_V 0x1c00707f -#define MATCH_VLUXEI512_V 0x14006007 -#define MASK_VLUXEI512_V 0x1c00707f -#define MATCH_VLUXEI1024_V 0x14007007 -#define MASK_VLUXEI1024_V 0x1c00707f -#define MATCH_VSUXEI8_V 0x4000027 -#define MASK_VSUXEI8_V 0x1c00707f -#define MATCH_VSUXEI16_V 0x4005027 -#define MASK_VSUXEI16_V 0x1c00707f -#define MATCH_VSUXEI32_V 0x4006027 -#define MASK_VSUXEI32_V 0x1c00707f -#define MATCH_VSUXEI64_V 0x4007027 -#define MASK_VSUXEI64_V 0x1c00707f -#define MATCH_VSUXEI128_V 0x14000027 -#define MASK_VSUXEI128_V 0x1c00707f -#define MATCH_VSUXEI256_V 0x14005027 -#define MASK_VSUXEI256_V 0x1c00707f -#define MATCH_VSUXEI512_V 0x14006027 -#define MASK_VSUXEI512_V 0x1c00707f -#define MATCH_VSUXEI1024_V 0x14007027 -#define MASK_VSUXEI1024_V 0x1c00707f -#define MATCH_VLSE8_V 0x8000007 -#define MASK_VLSE8_V 0x1c00707f -#define MATCH_VLSE16_V 0x8005007 -#define MASK_VLSE16_V 0x1c00707f -#define MATCH_VLSE32_V 0x8006007 -#define MASK_VLSE32_V 0x1c00707f -#define MATCH_VLSE64_V 0x8007007 -#define MASK_VLSE64_V 0x1c00707f -#define MATCH_VLSE128_V 0x18000007 -#define MASK_VLSE128_V 0x1c00707f -#define MATCH_VLSE256_V 0x18005007 -#define MASK_VLSE256_V 0x1c00707f -#define MATCH_VLSE512_V 0x18006007 -#define MASK_VLSE512_V 0x1c00707f -#define MATCH_VLSE1024_V 0x18007007 -#define MASK_VLSE1024_V 0x1c00707f -#define MATCH_VSSE8_V 0x8000027 -#define MASK_VSSE8_V 0x1c00707f -#define MATCH_VSSE16_V 0x8005027 -#define MASK_VSSE16_V 0x1c00707f -#define MATCH_VSSE32_V 0x8006027 -#define MASK_VSSE32_V 0x1c00707f -#define MATCH_VSSE64_V 0x8007027 -#define MASK_VSSE64_V 0x1c00707f -#define MATCH_VSSE128_V 0x18000027 -#define MASK_VSSE128_V 0x1c00707f -#define MATCH_VSSE256_V 0x18005027 -#define MASK_VSSE256_V 0x1c00707f -#define MATCH_VSSE512_V 0x18006027 -#define MASK_VSSE512_V 0x1c00707f -#define MATCH_VSSE1024_V 0x18007027 -#define MASK_VSSE1024_V 0x1c00707f -#define MATCH_VLOXEI8_V 0xc000007 -#define MASK_VLOXEI8_V 0x1c00707f -#define MATCH_VLOXEI16_V 0xc005007 -#define MASK_VLOXEI16_V 0x1c00707f -#define MATCH_VLOXEI32_V 0xc006007 -#define MASK_VLOXEI32_V 0x1c00707f -#define MATCH_VLOXEI64_V 0xc007007 -#define MASK_VLOXEI64_V 0x1c00707f -#define MATCH_VLOXEI128_V 0x1c000007 -#define MASK_VLOXEI128_V 0x1c00707f -#define MATCH_VLOXEI256_V 0x1c005007 -#define MASK_VLOXEI256_V 0x1c00707f -#define MATCH_VLOXEI512_V 0x1c006007 -#define MASK_VLOXEI512_V 0x1c00707f -#define MATCH_VLOXEI1024_V 0x1c007007 -#define MASK_VLOXEI1024_V 0x1c00707f -#define MATCH_VSOXEI8_V 0xc000027 -#define MASK_VSOXEI8_V 0x1c00707f -#define MATCH_VSOXEI16_V 0xc005027 -#define MASK_VSOXEI16_V 0x1c00707f -#define MATCH_VSOXEI32_V 0xc006027 -#define MASK_VSOXEI32_V 0x1c00707f -#define MATCH_VSOXEI64_V 0xc007027 -#define MASK_VSOXEI64_V 0x1c00707f -#define MATCH_VSOXEI128_V 0x1c000027 -#define MASK_VSOXEI128_V 0x1c00707f -#define MATCH_VSOXEI256_V 0x1c005027 -#define MASK_VSOXEI256_V 0x1c00707f -#define MATCH_VSOXEI512_V 0x1c006027 -#define MASK_VSOXEI512_V 0x1c00707f -#define MATCH_VSOXEI1024_V 0x1c007027 -#define MASK_VSOXEI1024_V 0x1c00707f -#define MATCH_VLE8FF_V 0x1000007 -#define MASK_VLE8FF_V 0x1df0707f -#define MATCH_VLE16FF_V 0x1005007 -#define MASK_VLE16FF_V 0x1df0707f -#define MATCH_VLE32FF_V 0x1006007 -#define MASK_VLE32FF_V 0x1df0707f -#define MATCH_VLE64FF_V 0x1007007 -#define MASK_VLE64FF_V 0x1df0707f -#define MATCH_VLE128FF_V 0x11000007 -#define MASK_VLE128FF_V 0x1df0707f -#define MATCH_VLE256FF_V 0x11005007 -#define MASK_VLE256FF_V 0x1df0707f -#define MATCH_VLE512FF_V 0x11006007 -#define MASK_VLE512FF_V 0x1df0707f -#define MATCH_VLE1024FF_V 0x11007007 -#define MASK_VLE1024FF_V 0x1df0707f -#define MATCH_VL1RE8_V 0x2800007 -#define MASK_VL1RE8_V 0xfff0707f -#define MATCH_VL1RE16_V 0x2805007 -#define MASK_VL1RE16_V 0xfff0707f -#define MATCH_VL1RE32_V 0x2806007 -#define MASK_VL1RE32_V 0xfff0707f -#define MATCH_VL1RE64_V 0x2807007 -#define MASK_VL1RE64_V 0xfff0707f -#define MATCH_VL2RE8_V 0x22800007 -#define MASK_VL2RE8_V 0xfff0707f -#define MATCH_VL2RE16_V 0x22805007 -#define MASK_VL2RE16_V 0xfff0707f -#define MATCH_VL2RE32_V 0x22806007 -#define MASK_VL2RE32_V 0xfff0707f -#define MATCH_VL2RE64_V 0x22807007 -#define MASK_VL2RE64_V 0xfff0707f -#define MATCH_VL4RE8_V 0x62800007 -#define MASK_VL4RE8_V 0xfff0707f -#define MATCH_VL4RE16_V 0x62805007 -#define MASK_VL4RE16_V 0xfff0707f -#define MATCH_VL4RE32_V 0x62806007 -#define MASK_VL4RE32_V 0xfff0707f -#define MATCH_VL4RE64_V 0x62807007 -#define MASK_VL4RE64_V 0xfff0707f -#define MATCH_VL8RE8_V 0xe2800007 -#define MASK_VL8RE8_V 0xfff0707f -#define MATCH_VL8RE16_V 0xe2805007 -#define MASK_VL8RE16_V 0xfff0707f -#define MATCH_VL8RE32_V 0xe2806007 -#define MASK_VL8RE32_V 0xfff0707f -#define MATCH_VL8RE64_V 0xe2807007 -#define MASK_VL8RE64_V 0xfff0707f -#define MATCH_VS1R_V 0x2800027 -#define MASK_VS1R_V 0xfff0707f -#define MATCH_VS2R_V 0x22800027 -#define MASK_VS2R_V 0xfff0707f -#define MATCH_VS4R_V 0x62800027 -#define MASK_VS4R_V 0xfff0707f -#define MATCH_VS8R_V 0xe2800027 -#define MASK_VS8R_V 0xfff0707f -#define MATCH_VFADD_VF 0x5057 -#define MASK_VFADD_VF 0xfc00707f -#define MATCH_VFSUB_VF 0x8005057 -#define MASK_VFSUB_VF 0xfc00707f -#define MATCH_VFMIN_VF 0x10005057 -#define MASK_VFMIN_VF 0xfc00707f -#define MATCH_VFMAX_VF 0x18005057 -#define MASK_VFMAX_VF 0xfc00707f -#define MATCH_VFSGNJ_VF 0x20005057 -#define MASK_VFSGNJ_VF 0xfc00707f -#define MATCH_VFSGNJN_VF 0x24005057 -#define MASK_VFSGNJN_VF 0xfc00707f -#define MATCH_VFSGNJX_VF 0x28005057 -#define MASK_VFSGNJX_VF 0xfc00707f -#define MATCH_VFSLIDE1UP_VF 0x38005057 -#define MASK_VFSLIDE1UP_VF 0xfc00707f -#define MATCH_VFSLIDE1DOWN_VF 0x3c005057 -#define MASK_VFSLIDE1DOWN_VF 0xfc00707f -#define MATCH_VFMV_S_F 0x42005057 -#define MASK_VFMV_S_F 0xfff0707f -#define MATCH_VFMERGE_VFM 0x5c005057 -#define MASK_VFMERGE_VFM 0xfe00707f -#define MATCH_VFMV_V_F 0x5e005057 -#define MASK_VFMV_V_F 0xfff0707f -#define MATCH_VMFEQ_VF 0x60005057 -#define MASK_VMFEQ_VF 0xfc00707f -#define MATCH_VMFLE_VF 0x64005057 -#define MASK_VMFLE_VF 0xfc00707f -#define MATCH_VMFLT_VF 0x6c005057 -#define MASK_VMFLT_VF 0xfc00707f -#define MATCH_VMFNE_VF 0x70005057 -#define MASK_VMFNE_VF 0xfc00707f -#define MATCH_VMFGT_VF 0x74005057 -#define MASK_VMFGT_VF 0xfc00707f -#define MATCH_VMFGE_VF 0x7c005057 -#define MASK_VMFGE_VF 0xfc00707f -#define MATCH_VFDIV_VF 0x80005057 -#define MASK_VFDIV_VF 0xfc00707f -#define MATCH_VFRDIV_VF 0x84005057 -#define MASK_VFRDIV_VF 0xfc00707f -#define MATCH_VFMUL_VF 0x90005057 -#define MASK_VFMUL_VF 0xfc00707f -#define MATCH_VFRSUB_VF 0x9c005057 -#define MASK_VFRSUB_VF 0xfc00707f -#define MATCH_VFMADD_VF 0xa0005057 -#define MASK_VFMADD_VF 0xfc00707f -#define MATCH_VFNMADD_VF 0xa4005057 -#define MASK_VFNMADD_VF 0xfc00707f -#define MATCH_VFMSUB_VF 0xa8005057 -#define MASK_VFMSUB_VF 0xfc00707f -#define MATCH_VFNMSUB_VF 0xac005057 -#define MASK_VFNMSUB_VF 0xfc00707f -#define MATCH_VFMACC_VF 0xb0005057 -#define MASK_VFMACC_VF 0xfc00707f -#define MATCH_VFNMACC_VF 0xb4005057 -#define MASK_VFNMACC_VF 0xfc00707f -#define MATCH_VFMSAC_VF 0xb8005057 -#define MASK_VFMSAC_VF 0xfc00707f -#define MATCH_VFNMSAC_VF 0xbc005057 -#define MASK_VFNMSAC_VF 0xfc00707f -#define MATCH_VFWADD_VF 0xc0005057 -#define MASK_VFWADD_VF 0xfc00707f -#define MATCH_VFWSUB_VF 0xc8005057 -#define MASK_VFWSUB_VF 0xfc00707f -#define MATCH_VFWADD_WF 0xd0005057 -#define MASK_VFWADD_WF 0xfc00707f -#define MATCH_VFWSUB_WF 0xd8005057 -#define MASK_VFWSUB_WF 0xfc00707f -#define MATCH_VFWMUL_VF 0xe0005057 -#define MASK_VFWMUL_VF 0xfc00707f -#define MATCH_VFWMACC_VF 0xf0005057 -#define MASK_VFWMACC_VF 0xfc00707f -#define MATCH_VFWNMACC_VF 0xf4005057 -#define MASK_VFWNMACC_VF 0xfc00707f -#define MATCH_VFWMSAC_VF 0xf8005057 -#define MASK_VFWMSAC_VF 0xfc00707f -#define MATCH_VFWNMSAC_VF 0xfc005057 -#define MASK_VFWNMSAC_VF 0xfc00707f -#define MATCH_VFADD_VV 0x1057 -#define MASK_VFADD_VV 0xfc00707f -#define MATCH_VFREDUSUM_VS 0x4001057 -#define MASK_VFREDUSUM_VS 0xfc00707f -#define MATCH_VFSUB_VV 0x8001057 -#define MASK_VFSUB_VV 0xfc00707f -#define MATCH_VFREDOSUM_VS 0xc001057 -#define MASK_VFREDOSUM_VS 0xfc00707f -#define MATCH_VFMIN_VV 0x10001057 -#define MASK_VFMIN_VV 0xfc00707f -#define MATCH_VFREDMIN_VS 0x14001057 -#define MASK_VFREDMIN_VS 0xfc00707f -#define MATCH_VFMAX_VV 0x18001057 -#define MASK_VFMAX_VV 0xfc00707f -#define MATCH_VFREDMAX_VS 0x1c001057 -#define MASK_VFREDMAX_VS 0xfc00707f -#define MATCH_VFSGNJ_VV 0x20001057 -#define MASK_VFSGNJ_VV 0xfc00707f -#define MATCH_VFSGNJN_VV 0x24001057 -#define MASK_VFSGNJN_VV 0xfc00707f -#define MATCH_VFSGNJX_VV 0x28001057 -#define MASK_VFSGNJX_VV 0xfc00707f -#define MATCH_VFMV_F_S 0x42001057 -#define MASK_VFMV_F_S 0xfe0ff07f -#define MATCH_VMFEQ_VV 0x60001057 -#define MASK_VMFEQ_VV 0xfc00707f -#define MATCH_VMFLE_VV 0x64001057 -#define MASK_VMFLE_VV 0xfc00707f -#define MATCH_VMFLT_VV 0x6c001057 -#define MASK_VMFLT_VV 0xfc00707f -#define MATCH_VMFNE_VV 0x70001057 -#define MASK_VMFNE_VV 0xfc00707f -#define MATCH_VFDIV_VV 0x80001057 -#define MASK_VFDIV_VV 0xfc00707f -#define MATCH_VFMUL_VV 0x90001057 -#define MASK_VFMUL_VV 0xfc00707f -#define MATCH_VFMADD_VV 0xa0001057 -#define MASK_VFMADD_VV 0xfc00707f -#define MATCH_VFNMADD_VV 0xa4001057 -#define MASK_VFNMADD_VV 0xfc00707f -#define MATCH_VFMSUB_VV 0xa8001057 -#define MASK_VFMSUB_VV 0xfc00707f -#define MATCH_VFNMSUB_VV 0xac001057 -#define MASK_VFNMSUB_VV 0xfc00707f -#define MATCH_VFMACC_VV 0xb0001057 -#define MASK_VFMACC_VV 0xfc00707f -#define MATCH_VFNMACC_VV 0xb4001057 -#define MASK_VFNMACC_VV 0xfc00707f -#define MATCH_VFMSAC_VV 0xb8001057 -#define MASK_VFMSAC_VV 0xfc00707f -#define MATCH_VFNMSAC_VV 0xbc001057 -#define MASK_VFNMSAC_VV 0xfc00707f -#define MATCH_VFCVT_XU_F_V 0x48001057 -#define MASK_VFCVT_XU_F_V 0xfc0ff07f -#define MATCH_VFCVT_X_F_V 0x48009057 -#define MASK_VFCVT_X_F_V 0xfc0ff07f -#define MATCH_VFCVT_F_XU_V 0x48011057 -#define MASK_VFCVT_F_XU_V 0xfc0ff07f -#define MATCH_VFCVT_F_X_V 0x48019057 -#define MASK_VFCVT_F_X_V 0xfc0ff07f -#define MATCH_VFCVT_RTZ_XU_F_V 0x48031057 -#define MASK_VFCVT_RTZ_XU_F_V 0xfc0ff07f -#define MATCH_VFCVT_RTZ_X_F_V 0x48039057 -#define MASK_VFCVT_RTZ_X_F_V 0xfc0ff07f -#define MATCH_VFWCVT_XU_F_V 0x48041057 -#define MASK_VFWCVT_XU_F_V 0xfc0ff07f -#define MATCH_VFWCVT_X_F_V 0x48049057 -#define MASK_VFWCVT_X_F_V 0xfc0ff07f -#define MATCH_VFWCVT_F_XU_V 0x48051057 -#define MASK_VFWCVT_F_XU_V 0xfc0ff07f -#define MATCH_VFWCVT_F_X_V 0x48059057 -#define MASK_VFWCVT_F_X_V 0xfc0ff07f -#define MATCH_VFWCVT_F_F_V 0x48061057 -#define MASK_VFWCVT_F_F_V 0xfc0ff07f -#define MATCH_VFWCVT_RTZ_XU_F_V 0x48071057 -#define MASK_VFWCVT_RTZ_XU_F_V 0xfc0ff07f -#define MATCH_VFWCVT_RTZ_X_F_V 0x48079057 -#define MASK_VFWCVT_RTZ_X_F_V 0xfc0ff07f -#define MATCH_VFNCVT_XU_F_W 0x48081057 -#define MASK_VFNCVT_XU_F_W 0xfc0ff07f -#define MATCH_VFNCVT_X_F_W 0x48089057 -#define MASK_VFNCVT_X_F_W 0xfc0ff07f -#define MATCH_VFNCVT_F_XU_W 0x48091057 -#define MASK_VFNCVT_F_XU_W 0xfc0ff07f -#define MATCH_VFNCVT_F_X_W 0x48099057 -#define MASK_VFNCVT_F_X_W 0xfc0ff07f -#define MATCH_VFNCVT_F_F_W 0x480a1057 -#define MASK_VFNCVT_F_F_W 0xfc0ff07f -#define MATCH_VFNCVT_ROD_F_F_W 0x480a9057 -#define MASK_VFNCVT_ROD_F_F_W 0xfc0ff07f -#define MATCH_VFNCVT_RTZ_XU_F_W 0x480b1057 -#define MASK_VFNCVT_RTZ_XU_F_W 0xfc0ff07f -#define MATCH_VFNCVT_RTZ_X_F_W 0x480b9057 -#define MASK_VFNCVT_RTZ_X_F_W 0xfc0ff07f -#define MATCH_VFSQRT_V 0x4c001057 -#define MASK_VFSQRT_V 0xfc0ff07f -#define MATCH_VFRSQRT7_V 0x4c021057 -#define MASK_VFRSQRT7_V 0xfc0ff07f -#define MATCH_VFREC7_V 0x4c029057 -#define MASK_VFREC7_V 0xfc0ff07f -#define MATCH_VFCLASS_V 0x4c081057 -#define MASK_VFCLASS_V 0xfc0ff07f -#define MATCH_VFWADD_VV 0xc0001057 -#define MASK_VFWADD_VV 0xfc00707f -#define MATCH_VFWREDUSUM_VS 0xc4001057 -#define MASK_VFWREDUSUM_VS 0xfc00707f -#define MATCH_VFWSUB_VV 0xc8001057 -#define MASK_VFWSUB_VV 0xfc00707f -#define MATCH_VFWREDOSUM_VS 0xcc001057 -#define MASK_VFWREDOSUM_VS 0xfc00707f -#define MATCH_VFWADD_WV 0xd0001057 -#define MASK_VFWADD_WV 0xfc00707f -#define MATCH_VFWSUB_WV 0xd8001057 -#define MASK_VFWSUB_WV 0xfc00707f -#define MATCH_VFWMUL_VV 0xe0001057 -#define MASK_VFWMUL_VV 0xfc00707f -#define MATCH_VFWMACC_VV 0xf0001057 -#define MASK_VFWMACC_VV 0xfc00707f -#define MATCH_VFWNMACC_VV 0xf4001057 -#define MASK_VFWNMACC_VV 0xfc00707f -#define MATCH_VFWMSAC_VV 0xf8001057 -#define MASK_VFWMSAC_VV 0xfc00707f -#define MATCH_VFWNMSAC_VV 0xfc001057 -#define MASK_VFWNMSAC_VV 0xfc00707f -#define MATCH_VADD_VX 0x4057 -#define MASK_VADD_VX 0xfc00707f -#define MATCH_VSUB_VX 0x8004057 -#define MASK_VSUB_VX 0xfc00707f -#define MATCH_VRSUB_VX 0xc004057 -#define MASK_VRSUB_VX 0xfc00707f -#define MATCH_VMINU_VX 0x10004057 -#define MASK_VMINU_VX 0xfc00707f -#define MATCH_VMIN_VX 0x14004057 -#define MASK_VMIN_VX 0xfc00707f -#define MATCH_VMAXU_VX 0x18004057 -#define MASK_VMAXU_VX 0xfc00707f -#define MATCH_VMAX_VX 0x1c004057 -#define MASK_VMAX_VX 0xfc00707f -#define MATCH_VAND_VX 0x24004057 -#define MASK_VAND_VX 0xfc00707f -#define MATCH_VOR_VX 0x28004057 -#define MASK_VOR_VX 0xfc00707f -#define MATCH_VXOR_VX 0x2c004057 -#define MASK_VXOR_VX 0xfc00707f -#define MATCH_VRGATHER_VX 0x30004057 -#define MASK_VRGATHER_VX 0xfc00707f -#define MATCH_VSLIDEUP_VX 0x38004057 -#define MASK_VSLIDEUP_VX 0xfc00707f -#define MATCH_VSLIDEDOWN_VX 0x3c004057 -#define MASK_VSLIDEDOWN_VX 0xfc00707f -#define MATCH_VADC_VXM 0x40004057 -#define MASK_VADC_VXM 0xfe00707f -#define MATCH_VMADC_VXM 0x44004057 -#define MASK_VMADC_VXM 0xfe00707f -#define MATCH_VMADC_VX 0x46004057 -#define MASK_VMADC_VX 0xfe00707f -#define MATCH_VSBC_VXM 0x48004057 -#define MASK_VSBC_VXM 0xfe00707f -#define MATCH_VMSBC_VXM 0x4c004057 -#define MASK_VMSBC_VXM 0xfe00707f -#define MATCH_VMSBC_VX 0x4e004057 -#define MASK_VMSBC_VX 0xfe00707f -#define MATCH_VMERGE_VXM 0x5c004057 -#define MASK_VMERGE_VXM 0xfe00707f -#define MATCH_VMV_V_X 0x5e004057 -#define MASK_VMV_V_X 0xfff0707f -#define MATCH_VMSEQ_VX 0x60004057 -#define MASK_VMSEQ_VX 0xfc00707f -#define MATCH_VMSNE_VX 0x64004057 -#define MASK_VMSNE_VX 0xfc00707f -#define MATCH_VMSLTU_VX 0x68004057 -#define MASK_VMSLTU_VX 0xfc00707f -#define MATCH_VMSLT_VX 0x6c004057 -#define MASK_VMSLT_VX 0xfc00707f -#define MATCH_VMSLEU_VX 0x70004057 -#define MASK_VMSLEU_VX 0xfc00707f -#define MATCH_VMSLE_VX 0x74004057 -#define MASK_VMSLE_VX 0xfc00707f -#define MATCH_VMSGTU_VX 0x78004057 -#define MASK_VMSGTU_VX 0xfc00707f -#define MATCH_VMSGT_VX 0x7c004057 -#define MASK_VMSGT_VX 0xfc00707f -#define MATCH_VSADDU_VX 0x80004057 -#define MASK_VSADDU_VX 0xfc00707f -#define MATCH_VSADD_VX 0x84004057 -#define MASK_VSADD_VX 0xfc00707f -#define MATCH_VSSUBU_VX 0x88004057 -#define MASK_VSSUBU_VX 0xfc00707f -#define MATCH_VSSUB_VX 0x8c004057 -#define MASK_VSSUB_VX 0xfc00707f -#define MATCH_VSLL_VX 0x94004057 -#define MASK_VSLL_VX 0xfc00707f -#define MATCH_VSMUL_VX 0x9c004057 -#define MASK_VSMUL_VX 0xfc00707f -#define MATCH_VSRL_VX 0xa0004057 -#define MASK_VSRL_VX 0xfc00707f -#define MATCH_VSRA_VX 0xa4004057 -#define MASK_VSRA_VX 0xfc00707f -#define MATCH_VSSRL_VX 0xa8004057 -#define MASK_VSSRL_VX 0xfc00707f -#define MATCH_VSSRA_VX 0xac004057 -#define MASK_VSSRA_VX 0xfc00707f -#define MATCH_VNSRL_WX 0xb0004057 -#define MASK_VNSRL_WX 0xfc00707f -#define MATCH_VNSRA_WX 0xb4004057 -#define MASK_VNSRA_WX 0xfc00707f -#define MATCH_VNCLIPU_WX 0xb8004057 -#define MASK_VNCLIPU_WX 0xfc00707f -#define MATCH_VNCLIP_WX 0xbc004057 -#define MASK_VNCLIP_WX 0xfc00707f -#define MATCH_VADD_VV 0x57 -#define MASK_VADD_VV 0xfc00707f -#define MATCH_VSUB_VV 0x8000057 -#define MASK_VSUB_VV 0xfc00707f -#define MATCH_VMINU_VV 0x10000057 -#define MASK_VMINU_VV 0xfc00707f -#define MATCH_VMIN_VV 0x14000057 -#define MASK_VMIN_VV 0xfc00707f -#define MATCH_VMAXU_VV 0x18000057 -#define MASK_VMAXU_VV 0xfc00707f -#define MATCH_VMAX_VV 0x1c000057 -#define MASK_VMAX_VV 0xfc00707f -#define MATCH_VAND_VV 0x24000057 -#define MASK_VAND_VV 0xfc00707f -#define MATCH_VOR_VV 0x28000057 -#define MASK_VOR_VV 0xfc00707f -#define MATCH_VXOR_VV 0x2c000057 -#define MASK_VXOR_VV 0xfc00707f -#define MATCH_VRGATHER_VV 0x30000057 -#define MASK_VRGATHER_VV 0xfc00707f -#define MATCH_VRGATHEREI16_VV 0x38000057 -#define MASK_VRGATHEREI16_VV 0xfc00707f -#define MATCH_VADC_VVM 0x40000057 -#define MASK_VADC_VVM 0xfe00707f -#define MATCH_VMADC_VVM 0x44000057 -#define MASK_VMADC_VVM 0xfe00707f -#define MATCH_VMADC_VV 0x46000057 -#define MASK_VMADC_VV 0xfe00707f -#define MATCH_VSBC_VVM 0x48000057 -#define MASK_VSBC_VVM 0xfe00707f -#define MATCH_VMSBC_VVM 0x4c000057 -#define MASK_VMSBC_VVM 0xfe00707f -#define MATCH_VMSBC_VV 0x4e000057 -#define MASK_VMSBC_VV 0xfe00707f -#define MATCH_VMERGE_VVM 0x5c000057 -#define MASK_VMERGE_VVM 0xfe00707f -#define MATCH_VMV_V_V 0x5e000057 -#define MASK_VMV_V_V 0xfff0707f -#define MATCH_VMSEQ_VV 0x60000057 -#define MASK_VMSEQ_VV 0xfc00707f -#define MATCH_VMSNE_VV 0x64000057 -#define MASK_VMSNE_VV 0xfc00707f -#define MATCH_VMSLTU_VV 0x68000057 -#define MASK_VMSLTU_VV 0xfc00707f -#define MATCH_VMSLT_VV 0x6c000057 -#define MASK_VMSLT_VV 0xfc00707f -#define MATCH_VMSLEU_VV 0x70000057 -#define MASK_VMSLEU_VV 0xfc00707f -#define MATCH_VMSLE_VV 0x74000057 -#define MASK_VMSLE_VV 0xfc00707f -#define MATCH_VSADDU_VV 0x80000057 -#define MASK_VSADDU_VV 0xfc00707f -#define MATCH_VSADD_VV 0x84000057 -#define MASK_VSADD_VV 0xfc00707f -#define MATCH_VSSUBU_VV 0x88000057 -#define MASK_VSSUBU_VV 0xfc00707f -#define MATCH_VSSUB_VV 0x8c000057 -#define MASK_VSSUB_VV 0xfc00707f -#define MATCH_VSLL_VV 0x94000057 -#define MASK_VSLL_VV 0xfc00707f -#define MATCH_VSMUL_VV 0x9c000057 -#define MASK_VSMUL_VV 0xfc00707f -#define MATCH_VSRL_VV 0xa0000057 -#define MASK_VSRL_VV 0xfc00707f -#define MATCH_VSRA_VV 0xa4000057 -#define MASK_VSRA_VV 0xfc00707f -#define MATCH_VSSRL_VV 0xa8000057 -#define MASK_VSSRL_VV 0xfc00707f -#define MATCH_VSSRA_VV 0xac000057 -#define MASK_VSSRA_VV 0xfc00707f -#define MATCH_VNSRL_WV 0xb0000057 -#define MASK_VNSRL_WV 0xfc00707f -#define MATCH_VNSRA_WV 0xb4000057 -#define MASK_VNSRA_WV 0xfc00707f -#define MATCH_VNCLIPU_WV 0xb8000057 -#define MASK_VNCLIPU_WV 0xfc00707f -#define MATCH_VNCLIP_WV 0xbc000057 -#define MASK_VNCLIP_WV 0xfc00707f -#define MATCH_VWREDSUMU_VS 0xc0000057 -#define MASK_VWREDSUMU_VS 0xfc00707f -#define MATCH_VWREDSUM_VS 0xc4000057 -#define MASK_VWREDSUM_VS 0xfc00707f -#define MATCH_VADD_VI 0x3057 -#define MASK_VADD_VI 0xfc00707f -#define MATCH_VRSUB_VI 0xc003057 -#define MASK_VRSUB_VI 0xfc00707f -#define MATCH_VAND_VI 0x24003057 -#define MASK_VAND_VI 0xfc00707f -#define MATCH_VOR_VI 0x28003057 -#define MASK_VOR_VI 0xfc00707f -#define MATCH_VXOR_VI 0x2c003057 -#define MASK_VXOR_VI 0xfc00707f -#define MATCH_VRGATHER_VI 0x30003057 -#define MASK_VRGATHER_VI 0xfc00707f -#define MATCH_VSLIDEUP_VI 0x38003057 -#define MASK_VSLIDEUP_VI 0xfc00707f -#define MATCH_VSLIDEDOWN_VI 0x3c003057 -#define MASK_VSLIDEDOWN_VI 0xfc00707f -#define MATCH_VADC_VIM 0x40003057 -#define MASK_VADC_VIM 0xfe00707f -#define MATCH_VMADC_VIM 0x44003057 -#define MASK_VMADC_VIM 0xfe00707f -#define MATCH_VMADC_VI 0x46003057 -#define MASK_VMADC_VI 0xfe00707f -#define MATCH_VMERGE_VIM 0x5c003057 -#define MASK_VMERGE_VIM 0xfe00707f -#define MATCH_VMV_V_I 0x5e003057 -#define MASK_VMV_V_I 0xfff0707f -#define MATCH_VMSEQ_VI 0x60003057 -#define MASK_VMSEQ_VI 0xfc00707f -#define MATCH_VMSNE_VI 0x64003057 -#define MASK_VMSNE_VI 0xfc00707f -#define MATCH_VMSLEU_VI 0x70003057 -#define MASK_VMSLEU_VI 0xfc00707f -#define MATCH_VMSLE_VI 0x74003057 -#define MASK_VMSLE_VI 0xfc00707f -#define MATCH_VMSGTU_VI 0x78003057 -#define MASK_VMSGTU_VI 0xfc00707f -#define MATCH_VMSGT_VI 0x7c003057 -#define MASK_VMSGT_VI 0xfc00707f -#define MATCH_VSADDU_VI 0x80003057 -#define MASK_VSADDU_VI 0xfc00707f -#define MATCH_VSADD_VI 0x84003057 -#define MASK_VSADD_VI 0xfc00707f -#define MATCH_VSLL_VI 0x94003057 -#define MASK_VSLL_VI 0xfc00707f -#define MATCH_VMV1R_V 0x9e003057 -#define MASK_VMV1R_V 0xfe0ff07f -#define MATCH_VMV2R_V 0x9e00b057 -#define MASK_VMV2R_V 0xfe0ff07f -#define MATCH_VMV4R_V 0x9e01b057 -#define MASK_VMV4R_V 0xfe0ff07f -#define MATCH_VMV8R_V 0x9e03b057 -#define MASK_VMV8R_V 0xfe0ff07f -#define MATCH_VSRL_VI 0xa0003057 -#define MASK_VSRL_VI 0xfc00707f -#define MATCH_VSRA_VI 0xa4003057 -#define MASK_VSRA_VI 0xfc00707f -#define MATCH_VSSRL_VI 0xa8003057 -#define MASK_VSSRL_VI 0xfc00707f -#define MATCH_VSSRA_VI 0xac003057 -#define MASK_VSSRA_VI 0xfc00707f -#define MATCH_VNSRL_WI 0xb0003057 -#define MASK_VNSRL_WI 0xfc00707f -#define MATCH_VNSRA_WI 0xb4003057 -#define MASK_VNSRA_WI 0xfc00707f -#define MATCH_VNCLIPU_WI 0xb8003057 -#define MASK_VNCLIPU_WI 0xfc00707f -#define MATCH_VNCLIP_WI 0xbc003057 -#define MASK_VNCLIP_WI 0xfc00707f -#define MATCH_VREDSUM_VS 0x2057 -#define MASK_VREDSUM_VS 0xfc00707f -#define MATCH_VREDAND_VS 0x4002057 -#define MASK_VREDAND_VS 0xfc00707f -#define MATCH_VREDOR_VS 0x8002057 -#define MASK_VREDOR_VS 0xfc00707f -#define MATCH_VREDXOR_VS 0xc002057 -#define MASK_VREDXOR_VS 0xfc00707f -#define MATCH_VREDMINU_VS 0x10002057 -#define MASK_VREDMINU_VS 0xfc00707f -#define MATCH_VREDMIN_VS 0x14002057 -#define MASK_VREDMIN_VS 0xfc00707f -#define MATCH_VREDMAXU_VS 0x18002057 -#define MASK_VREDMAXU_VS 0xfc00707f -#define MATCH_VREDMAX_VS 0x1c002057 -#define MASK_VREDMAX_VS 0xfc00707f -#define MATCH_VAADDU_VV 0x20002057 -#define MASK_VAADDU_VV 0xfc00707f -#define MATCH_VAADD_VV 0x24002057 -#define MASK_VAADD_VV 0xfc00707f -#define MATCH_VASUBU_VV 0x28002057 -#define MASK_VASUBU_VV 0xfc00707f -#define MATCH_VASUB_VV 0x2c002057 -#define MASK_VASUB_VV 0xfc00707f -#define MATCH_VMV_X_S 0x42002057 -#define MASK_VMV_X_S 0xfe0ff07f -#define MATCH_VZEXT_VF8 0x48012057 -#define MASK_VZEXT_VF8 0xfc0ff07f -#define MATCH_VSEXT_VF8 0x4801a057 -#define MASK_VSEXT_VF8 0xfc0ff07f -#define MATCH_VZEXT_VF4 0x48022057 -#define MASK_VZEXT_VF4 0xfc0ff07f -#define MATCH_VSEXT_VF4 0x4802a057 -#define MASK_VSEXT_VF4 0xfc0ff07f -#define MATCH_VZEXT_VF2 0x48032057 -#define MASK_VZEXT_VF2 0xfc0ff07f -#define MATCH_VSEXT_VF2 0x4803a057 -#define MASK_VSEXT_VF2 0xfc0ff07f -#define MATCH_VCOMPRESS_VM 0x5e002057 -#define MASK_VCOMPRESS_VM 0xfe00707f -#define MATCH_VMANDN_MM 0x60002057 -#define MASK_VMANDN_MM 0xfc00707f -#define MATCH_VMAND_MM 0x64002057 -#define MASK_VMAND_MM 0xfc00707f -#define MATCH_VMOR_MM 0x68002057 -#define MASK_VMOR_MM 0xfc00707f -#define MATCH_VMXOR_MM 0x6c002057 -#define MASK_VMXOR_MM 0xfc00707f -#define MATCH_VMORN_MM 0x70002057 -#define MASK_VMORN_MM 0xfc00707f -#define MATCH_VMNAND_MM 0x74002057 -#define MASK_VMNAND_MM 0xfc00707f -#define MATCH_VMNOR_MM 0x78002057 -#define MASK_VMNOR_MM 0xfc00707f -#define MATCH_VMXNOR_MM 0x7c002057 -#define MASK_VMXNOR_MM 0xfc00707f -#define MATCH_VMSBF_M 0x5000a057 -#define MASK_VMSBF_M 0xfc0ff07f -#define MATCH_VMSOF_M 0x50012057 -#define MASK_VMSOF_M 0xfc0ff07f -#define MATCH_VMSIF_M 0x5001a057 -#define MASK_VMSIF_M 0xfc0ff07f -#define MATCH_VIOTA_M 0x50082057 -#define MASK_VIOTA_M 0xfc0ff07f -#define MATCH_VID_V 0x5008a057 -#define MASK_VID_V 0xfdfff07f -#define MATCH_VCPOP_M 0x40082057 -#define MASK_VCPOP_M 0xfc0ff07f -#define MATCH_VFIRST_M 0x4008a057 -#define MASK_VFIRST_M 0xfc0ff07f -#define MATCH_VDIVU_VV 0x80002057 -#define MASK_VDIVU_VV 0xfc00707f -#define MATCH_VDIV_VV 0x84002057 -#define MASK_VDIV_VV 0xfc00707f -#define MATCH_VREMU_VV 0x88002057 -#define MASK_VREMU_VV 0xfc00707f -#define MATCH_VREM_VV 0x8c002057 -#define MASK_VREM_VV 0xfc00707f -#define MATCH_VMULHU_VV 0x90002057 -#define MASK_VMULHU_VV 0xfc00707f -#define MATCH_VMUL_VV 0x94002057 -#define MASK_VMUL_VV 0xfc00707f -#define MATCH_VMULHSU_VV 0x98002057 -#define MASK_VMULHSU_VV 0xfc00707f -#define MATCH_VMULH_VV 0x9c002057 -#define MASK_VMULH_VV 0xfc00707f -#define MATCH_VMADD_VV 0xa4002057 -#define MASK_VMADD_VV 0xfc00707f -#define MATCH_VNMSUB_VV 0xac002057 -#define MASK_VNMSUB_VV 0xfc00707f -#define MATCH_VMACC_VV 0xb4002057 -#define MASK_VMACC_VV 0xfc00707f -#define MATCH_VNMSAC_VV 0xbc002057 -#define MASK_VNMSAC_VV 0xfc00707f -#define MATCH_VWADDU_VV 0xc0002057 -#define MASK_VWADDU_VV 0xfc00707f -#define MATCH_VWADD_VV 0xc4002057 -#define MASK_VWADD_VV 0xfc00707f -#define MATCH_VWSUBU_VV 0xc8002057 -#define MASK_VWSUBU_VV 0xfc00707f -#define MATCH_VWSUB_VV 0xcc002057 -#define MASK_VWSUB_VV 0xfc00707f -#define MATCH_VWADDU_WV 0xd0002057 -#define MASK_VWADDU_WV 0xfc00707f -#define MATCH_VWADD_WV 0xd4002057 -#define MASK_VWADD_WV 0xfc00707f -#define MATCH_VWSUBU_WV 0xd8002057 -#define MASK_VWSUBU_WV 0xfc00707f -#define MATCH_VWSUB_WV 0xdc002057 -#define MASK_VWSUB_WV 0xfc00707f -#define MATCH_VWMULU_VV 0xe0002057 -#define MASK_VWMULU_VV 0xfc00707f -#define MATCH_VWMULSU_VV 0xe8002057 -#define MASK_VWMULSU_VV 0xfc00707f -#define MATCH_VWMUL_VV 0xec002057 -#define MASK_VWMUL_VV 0xfc00707f -#define MATCH_VWMACCU_VV 0xf0002057 -#define MASK_VWMACCU_VV 0xfc00707f -#define MATCH_VWMACC_VV 0xf4002057 -#define MASK_VWMACC_VV 0xfc00707f -#define MATCH_VWMACCSU_VV 0xfc002057 -#define MASK_VWMACCSU_VV 0xfc00707f -#define MATCH_VAADDU_VX 0x20006057 -#define MASK_VAADDU_VX 0xfc00707f -#define MATCH_VAADD_VX 0x24006057 -#define MASK_VAADD_VX 0xfc00707f -#define MATCH_VASUBU_VX 0x28006057 -#define MASK_VASUBU_VX 0xfc00707f -#define MATCH_VASUB_VX 0x2c006057 -#define MASK_VASUB_VX 0xfc00707f -#define MATCH_VMV_S_X 0x42006057 -#define MASK_VMV_S_X 0xfff0707f -#define MATCH_VSLIDE1UP_VX 0x38006057 -#define MASK_VSLIDE1UP_VX 0xfc00707f -#define MATCH_VSLIDE1DOWN_VX 0x3c006057 -#define MASK_VSLIDE1DOWN_VX 0xfc00707f -#define MATCH_VDIVU_VX 0x80006057 -#define MASK_VDIVU_VX 0xfc00707f -#define MATCH_VDIV_VX 0x84006057 -#define MASK_VDIV_VX 0xfc00707f -#define MATCH_VREMU_VX 0x88006057 -#define MASK_VREMU_VX 0xfc00707f -#define MATCH_VREM_VX 0x8c006057 -#define MASK_VREM_VX 0xfc00707f -#define MATCH_VMULHU_VX 0x90006057 -#define MASK_VMULHU_VX 0xfc00707f -#define MATCH_VMUL_VX 0x94006057 -#define MASK_VMUL_VX 0xfc00707f -#define MATCH_VMULHSU_VX 0x98006057 -#define MASK_VMULHSU_VX 0xfc00707f -#define MATCH_VMULH_VX 0x9c006057 -#define MASK_VMULH_VX 0xfc00707f -#define MATCH_VMADD_VX 0xa4006057 -#define MASK_VMADD_VX 0xfc00707f -#define MATCH_VNMSUB_VX 0xac006057 -#define MASK_VNMSUB_VX 0xfc00707f -#define MATCH_VMACC_VX 0xb4006057 -#define MASK_VMACC_VX 0xfc00707f -#define MATCH_VNMSAC_VX 0xbc006057 -#define MASK_VNMSAC_VX 0xfc00707f -#define MATCH_VWADDU_VX 0xc0006057 -#define MASK_VWADDU_VX 0xfc00707f -#define MATCH_VWADD_VX 0xc4006057 -#define MASK_VWADD_VX 0xfc00707f -#define MATCH_VWSUBU_VX 0xc8006057 -#define MASK_VWSUBU_VX 0xfc00707f -#define MATCH_VWSUB_VX 0xcc006057 -#define MASK_VWSUB_VX 0xfc00707f -#define MATCH_VWADDU_WX 0xd0006057 -#define MASK_VWADDU_WX 0xfc00707f -#define MATCH_VWADD_WX 0xd4006057 -#define MASK_VWADD_WX 0xfc00707f -#define MATCH_VWSUBU_WX 0xd8006057 -#define MASK_VWSUBU_WX 0xfc00707f -#define MATCH_VWSUB_WX 0xdc006057 -#define MASK_VWSUB_WX 0xfc00707f -#define MATCH_VWMULU_VX 0xe0006057 -#define MASK_VWMULU_VX 0xfc00707f -#define MATCH_VWMULSU_VX 0xe8006057 -#define MASK_VWMULSU_VX 0xfc00707f -#define MATCH_VWMUL_VX 0xec006057 -#define MASK_VWMUL_VX 0xfc00707f -#define MATCH_VWMACCU_VX 0xf0006057 -#define MASK_VWMACCU_VX 0xfc00707f -#define MATCH_VWMACC_VX 0xf4006057 -#define MASK_VWMACC_VX 0xfc00707f -#define MATCH_VWMACCUS_VX 0xf8006057 -#define MASK_VWMACCUS_VX 0xfc00707f -#define MATCH_VWMACCSU_VX 0xfc006057 -#define MASK_VWMACCSU_VX 0xfc00707f -#define MATCH_VAMOSWAPEI8_V 0x800002f -#define MASK_VAMOSWAPEI8_V 0xf800707f -#define MATCH_VAMOADDEI8_V 0x2f -#define MASK_VAMOADDEI8_V 0xf800707f -#define MATCH_VAMOXOREI8_V 0x2000002f -#define MASK_VAMOXOREI8_V 0xf800707f -#define MATCH_VAMOANDEI8_V 0x6000002f -#define MASK_VAMOANDEI8_V 0xf800707f -#define MATCH_VAMOOREI8_V 0x4000002f -#define MASK_VAMOOREI8_V 0xf800707f -#define MATCH_VAMOMINEI8_V 0x8000002f -#define MASK_VAMOMINEI8_V 0xf800707f -#define MATCH_VAMOMAXEI8_V 0xa000002f -#define MASK_VAMOMAXEI8_V 0xf800707f -#define MATCH_VAMOMINUEI8_V 0xc000002f -#define MASK_VAMOMINUEI8_V 0xf800707f -#define MATCH_VAMOMAXUEI8_V 0xe000002f -#define MASK_VAMOMAXUEI8_V 0xf800707f -#define MATCH_VAMOSWAPEI16_V 0x800502f -#define MASK_VAMOSWAPEI16_V 0xf800707f -#define MATCH_VAMOADDEI16_V 0x502f -#define MASK_VAMOADDEI16_V 0xf800707f -#define MATCH_VAMOXOREI16_V 0x2000502f -#define MASK_VAMOXOREI16_V 0xf800707f -#define MATCH_VAMOANDEI16_V 0x6000502f -#define MASK_VAMOANDEI16_V 0xf800707f -#define MATCH_VAMOOREI16_V 0x4000502f -#define MASK_VAMOOREI16_V 0xf800707f -#define MATCH_VAMOMINEI16_V 0x8000502f -#define MASK_VAMOMINEI16_V 0xf800707f -#define MATCH_VAMOMAXEI16_V 0xa000502f -#define MASK_VAMOMAXEI16_V 0xf800707f -#define MATCH_VAMOMINUEI16_V 0xc000502f -#define MASK_VAMOMINUEI16_V 0xf800707f -#define MATCH_VAMOMAXUEI16_V 0xe000502f -#define MASK_VAMOMAXUEI16_V 0xf800707f -#define MATCH_VAMOSWAPEI32_V 0x800602f -#define MASK_VAMOSWAPEI32_V 0xf800707f -#define MATCH_VAMOADDEI32_V 0x602f -#define MASK_VAMOADDEI32_V 0xf800707f -#define MATCH_VAMOXOREI32_V 0x2000602f -#define MASK_VAMOXOREI32_V 0xf800707f -#define MATCH_VAMOANDEI32_V 0x6000602f -#define MASK_VAMOANDEI32_V 0xf800707f -#define MATCH_VAMOOREI32_V 0x4000602f -#define MASK_VAMOOREI32_V 0xf800707f -#define MATCH_VAMOMINEI32_V 0x8000602f -#define MASK_VAMOMINEI32_V 0xf800707f -#define MATCH_VAMOMAXEI32_V 0xa000602f -#define MASK_VAMOMAXEI32_V 0xf800707f -#define MATCH_VAMOMINUEI32_V 0xc000602f -#define MASK_VAMOMINUEI32_V 0xf800707f -#define MATCH_VAMOMAXUEI32_V 0xe000602f -#define MASK_VAMOMAXUEI32_V 0xf800707f -#define MATCH_VAMOSWAPEI64_V 0x800702f -#define MASK_VAMOSWAPEI64_V 0xf800707f -#define MATCH_VAMOADDEI64_V 0x702f -#define MASK_VAMOADDEI64_V 0xf800707f -#define MATCH_VAMOXOREI64_V 0x2000702f -#define MASK_VAMOXOREI64_V 0xf800707f -#define MATCH_VAMOANDEI64_V 0x6000702f -#define MASK_VAMOANDEI64_V 0xf800707f -#define MATCH_VAMOOREI64_V 0x4000702f -#define MASK_VAMOOREI64_V 0xf800707f -#define MATCH_VAMOMINEI64_V 0x8000702f -#define MASK_VAMOMINEI64_V 0xf800707f -#define MATCH_VAMOMAXEI64_V 0xa000702f -#define MASK_VAMOMAXEI64_V 0xf800707f -#define MATCH_VAMOMINUEI64_V 0xc000702f -#define MASK_VAMOMINUEI64_V 0xf800707f -#define MATCH_VAMOMAXUEI64_V 0xe000702f -#define MASK_VAMOMAXUEI64_V 0xf800707f -#define MATCH_ADD8 0x48000077 -#define MASK_ADD8 0xfe00707f +#define MASK_ADD 0xfe00707f #define MATCH_ADD16 0x40000077 -#define MASK_ADD16 0xfe00707f -#define MATCH_ADD64 0xc0001077 -#define MASK_ADD64 0xfe00707f -#define MATCH_AVE 0xe0000077 -#define MASK_AVE 0xfe00707f -#define MATCH_BITREV 0xe6000077 -#define MASK_BITREV 0xfe00707f -#define MATCH_BITREVI 0xe8000077 -#define MASK_BITREVI 0xfc00707f -#define MATCH_BPICK 0x3077 -#define MASK_BPICK 0x600707f -#define MATCH_CLRS8 0xae000077 -#define MASK_CLRS8 0xfff0707f -#define MATCH_CLRS16 0xae800077 -#define MASK_CLRS16 0xfff0707f -#define MATCH_CLRS32 0xaf800077 -#define MASK_CLRS32 0xfff0707f -#define MATCH_CLO8 0xae300077 -#define MASK_CLO8 0xfff0707f -#define MATCH_CLO16 0xaeb00077 -#define MASK_CLO16 0xfff0707f -#define MATCH_CLO32 0xafb00077 -#define MASK_CLO32 0xfff0707f -#define MATCH_CLZ8 0xae100077 -#define MASK_CLZ8 0xfff0707f -#define MATCH_CLZ16 0xae900077 -#define MASK_CLZ16 0xfff0707f -#define MATCH_CLZ32 0xaf900077 -#define MASK_CLZ32 0xfff0707f -#define MATCH_CMPEQ8 0x4e000077 -#define MASK_CMPEQ8 0xfe00707f -#define MATCH_CMPEQ16 0x4c000077 -#define MASK_CMPEQ16 0xfe00707f -#define MATCH_CRAS16 0x44000077 -#define MASK_CRAS16 0xfe00707f -#define MATCH_CRSA16 0x46000077 -#define MASK_CRSA16 0xfe00707f -#define MATCH_INSB 0xac000077 -#define MASK_INSB 0xff80707f -#define MATCH_KABS8 0xad000077 -#define MASK_KABS8 0xfff0707f -#define MATCH_KABS16 0xad100077 -#define MASK_KABS16 0xfff0707f -#define MATCH_KABSW 0xad400077 -#define MASK_KABSW 0xfff0707f -#define MATCH_KADD8 0x18000077 -#define MASK_KADD8 0xfe00707f -#define MATCH_KADD16 0x10000077 -#define MASK_KADD16 0xfe00707f -#define MATCH_KADD64 0x90001077 -#define MASK_KADD64 0xfe00707f -#define MATCH_KADDH 0x4001077 -#define MASK_KADDH 0xfe00707f -#define MATCH_KADDW 0x1077 -#define MASK_KADDW 0xfe00707f -#define MATCH_KCRAS16 0x14000077 -#define MASK_KCRAS16 0xfe00707f -#define MATCH_KCRSA16 0x16000077 -#define MASK_KCRSA16 0xfe00707f -#define MATCH_KDMBB 0xa001077 -#define MASK_KDMBB 0xfe00707f -#define MATCH_KDMBT 0x1a001077 -#define MASK_KDMBT 0xfe00707f -#define MATCH_KDMTT 0x2a001077 -#define MASK_KDMTT 0xfe00707f -#define MATCH_KDMABB 0xd2001077 -#define MASK_KDMABB 0xfe00707f -#define MATCH_KDMABT 0xe2001077 -#define MASK_KDMABT 0xfe00707f -#define MATCH_KDMATT 0xf2001077 -#define MASK_KDMATT 0xfe00707f -#define MATCH_KHM8 0x8e000077 -#define MASK_KHM8 0xfe00707f -#define MATCH_KHMX8 0x9e000077 -#define MASK_KHMX8 0xfe00707f -#define MATCH_KHM16 0x86000077 -#define MASK_KHM16 0xfe00707f -#define MATCH_KHMX16 0x96000077 -#define MASK_KHMX16 0xfe00707f -#define MATCH_KHMBB 0xc001077 -#define MASK_KHMBB 0xfe00707f -#define MATCH_KHMBT 0x1c001077 -#define MASK_KHMBT 0xfe00707f -#define MATCH_KHMTT 0x2c001077 -#define MASK_KHMTT 0xfe00707f -#define MATCH_KMABB 0x5a001077 -#define MASK_KMABB 0xfe00707f -#define MATCH_KMABT 0x6a001077 -#define MASK_KMABT 0xfe00707f -#define MATCH_KMATT 0x7a001077 -#define MASK_KMATT 0xfe00707f -#define MATCH_KMADA 0x48001077 -#define MASK_KMADA 0xfe00707f -#define MATCH_KMAXDA 0x4a001077 -#define MASK_KMAXDA 0xfe00707f -#define MATCH_KMADS 0x5c001077 -#define MASK_KMADS 0xfe00707f -#define MATCH_KMADRS 0x6c001077 -#define MASK_KMADRS 0xfe00707f -#define MATCH_KMAXDS 0x7c001077 -#define MASK_KMAXDS 0xfe00707f -#define MATCH_KMAR64 0x94001077 -#define MASK_KMAR64 0xfe00707f -#define MATCH_KMDA 0x38001077 -#define MASK_KMDA 0xfe00707f -#define MATCH_KMXDA 0x3a001077 -#define MASK_KMXDA 0xfe00707f -#define MATCH_KMMAC 0x60001077 -#define MASK_KMMAC 0xfe00707f -#define MATCH_KMMAC_U 0x70001077 -#define MASK_KMMAC_U 0xfe00707f -#define MATCH_KMMAWB 0x46001077 -#define MASK_KMMAWB 0xfe00707f -#define MATCH_KMMAWB_U 0x56001077 -#define MASK_KMMAWB_U 0xfe00707f -#define MATCH_KMMAWB2 0xce001077 -#define MASK_KMMAWB2 0xfe00707f -#define MATCH_KMMAWB2_U 0xde001077 -#define MASK_KMMAWB2_U 0xfe00707f -#define MATCH_KMMAWT 0x66001077 -#define MASK_KMMAWT 0xfe00707f -#define MATCH_KMMAWT_U 0x76001077 -#define MASK_KMMAWT_U 0xfe00707f -#define MATCH_KMMAWT2 0xee001077 -#define MASK_KMMAWT2 0xfe00707f -#define MATCH_KMMAWT2_U 0xfe001077 -#define MASK_KMMAWT2_U 0xfe00707f -#define MATCH_KMMSB 0x42001077 -#define MASK_KMMSB 0xfe00707f -#define MATCH_KMMSB_U 0x52001077 -#define MASK_KMMSB_U 0xfe00707f -#define MATCH_KMMWB2 0x8e001077 -#define MASK_KMMWB2 0xfe00707f -#define MATCH_KMMWB2_U 0x9e001077 -#define MASK_KMMWB2_U 0xfe00707f -#define MATCH_KMMWT2 0xae001077 -#define MASK_KMMWT2 0xfe00707f -#define MATCH_KMMWT2_U 0xbe001077 -#define MASK_KMMWT2_U 0xfe00707f -#define MATCH_KMSDA 0x4c001077 -#define MASK_KMSDA 0xfe00707f -#define MATCH_KMSXDA 0x4e001077 -#define MASK_KMSXDA 0xfe00707f -#define MATCH_KMSR64 0x96001077 -#define MASK_KMSR64 0xfe00707f -#define MATCH_KSLLW 0x26001077 -#define MASK_KSLLW 0xfe00707f -#define MATCH_KSLLIW 0x36001077 -#define MASK_KSLLIW 0xfe00707f -#define MATCH_KSLL8 0x6c000077 -#define MASK_KSLL8 0xfe00707f -#define MATCH_KSLLI8 0x7c800077 -#define MASK_KSLLI8 0xff80707f -#define MATCH_KSLL16 0x64000077 -#define MASK_KSLL16 0xfe00707f -#define MATCH_KSLLI16 0x75000077 -#define MASK_KSLLI16 0xff00707f -#define MATCH_KSLRA8 0x5e000077 -#define MASK_KSLRA8 0xfe00707f -#define MATCH_KSLRA8_U 0x6e000077 -#define MASK_KSLRA8_U 0xfe00707f -#define MATCH_KSLRA16 0x56000077 -#define MASK_KSLRA16 0xfe00707f -#define MATCH_KSLRA16_U 0x66000077 -#define MASK_KSLRA16_U 0xfe00707f -#define MATCH_KSLRAW 0x6e001077 -#define MASK_KSLRAW 0xfe00707f -#define MATCH_KSLRAW_U 0x7e001077 -#define MASK_KSLRAW_U 0xfe00707f -#define MATCH_KSTAS16 0xc4002077 -#define MASK_KSTAS16 0xfe00707f -#define MATCH_KSTSA16 0xc6002077 -#define MASK_KSTSA16 0xfe00707f -#define MATCH_KSUB8 0x1a000077 -#define MASK_KSUB8 0xfe00707f -#define MATCH_KSUB16 0x12000077 -#define MASK_KSUB16 0xfe00707f -#define MATCH_KSUB64 0x92001077 -#define MASK_KSUB64 0xfe00707f -#define MATCH_KSUBH 0x6001077 -#define MASK_KSUBH 0xfe00707f -#define MATCH_KSUBW 0x2001077 -#define MASK_KSUBW 0xfe00707f -#define MATCH_KWMMUL 0x62001077 -#define MASK_KWMMUL 0xfe00707f -#define MATCH_KWMMUL_U 0x72001077 -#define MASK_KWMMUL_U 0xfe00707f -#define MATCH_MADDR32 0xc4001077 -#define MASK_MADDR32 0xfe00707f -#define MATCH_MAXW 0xf2000077 -#define MASK_MAXW 0xfe00707f -#define MATCH_MINW 0xf0000077 -#define MASK_MINW 0xfe00707f -#define MATCH_MSUBR32 0xc6001077 -#define MASK_MSUBR32 0xfe00707f -#define MATCH_MULR64 0xf0001077 -#define MASK_MULR64 0xfe00707f -#define MATCH_MULSR64 0xe0001077 -#define MASK_MULSR64 0xfe00707f -#define MATCH_PBSAD 0xfc000077 -#define MASK_PBSAD 0xfe00707f -#define MATCH_PBSADA 0xfe000077 -#define MASK_PBSADA 0xfe00707f -#define MATCH_PKBB16 0xe001077 -#define MASK_PKBB16 0xfe00707f -#define MATCH_PKBT16 0x1e001077 -#define MASK_PKBT16 0xfe00707f -#define MATCH_PKTT16 0x2e001077 -#define MASK_PKTT16 0xfe00707f -#define MATCH_PKTB16 0x3e001077 -#define MASK_PKTB16 0xfe00707f -#define MATCH_RADD8 0x8000077 -#define MASK_RADD8 0xfe00707f -#define MATCH_RADD16 0x77 -#define MASK_RADD16 0xfe00707f -#define MATCH_RADD64 0x80001077 -#define MASK_RADD64 0xfe00707f -#define MATCH_RADDW 0x20001077 -#define MASK_RADDW 0xfe00707f -#define MATCH_RCRAS16 0x4000077 -#define MASK_RCRAS16 0xfe00707f -#define MATCH_RCRSA16 0x6000077 -#define MASK_RCRSA16 0xfe00707f -#define MATCH_RSTAS16 0xb4002077 -#define MASK_RSTAS16 0xfe00707f -#define MATCH_RSTSA16 0xb6002077 -#define MASK_RSTSA16 0xfe00707f -#define MATCH_RSUB8 0xa000077 -#define MASK_RSUB8 0xfe00707f -#define MATCH_RSUB16 0x2000077 -#define MASK_RSUB16 0xfe00707f -#define MATCH_RSUB64 0x82001077 -#define MASK_RSUB64 0xfe00707f -#define MATCH_RSUBW 0x22001077 -#define MASK_RSUBW 0xfe00707f -#define MATCH_SCLIP8 0x8c000077 -#define MASK_SCLIP8 0xff80707f -#define MATCH_SCLIP16 0x84000077 -#define MASK_SCLIP16 0xff00707f -#define MATCH_SCLIP32 0xe4000077 -#define MASK_SCLIP32 0xfe00707f -#define MATCH_SCMPLE8 0x1e000077 -#define MASK_SCMPLE8 0xfe00707f -#define MATCH_SCMPLE16 0x1c000077 -#define MASK_SCMPLE16 0xfe00707f -#define MATCH_SCMPLT8 0xe000077 -#define MASK_SCMPLT8 0xfe00707f -#define MATCH_SCMPLT16 0xc000077 -#define MASK_SCMPLT16 0xfe00707f -#define MATCH_SLL8 0x5c000077 -#define MASK_SLL8 0xfe00707f -#define MATCH_SLLI8 0x7c000077 -#define MASK_SLLI8 0xff80707f -#define MATCH_SLL16 0x54000077 -#define MASK_SLL16 0xfe00707f -#define MATCH_SLLI16 0x74000077 -#define MASK_SLLI16 0xff00707f -#define MATCH_SMAL 0x5e001077 -#define MASK_SMAL 0xfe00707f -#define MATCH_SMALBB 0x88001077 -#define MASK_SMALBB 0xfe00707f -#define MATCH_SMALBT 0x98001077 -#define MASK_SMALBT 0xfe00707f -#define MATCH_SMALTT 0xa8001077 -#define MASK_SMALTT 0xfe00707f -#define MATCH_SMALDA 0x8c001077 -#define MASK_SMALDA 0xfe00707f -#define MATCH_SMALXDA 0x9c001077 -#define MASK_SMALXDA 0xfe00707f -#define MATCH_SMALDS 0x8a001077 -#define MASK_SMALDS 0xfe00707f -#define MATCH_SMALDRS 0x9a001077 -#define MASK_SMALDRS 0xfe00707f -#define MATCH_SMALXDS 0xaa001077 -#define MASK_SMALXDS 0xfe00707f -#define MATCH_SMAR64 0x84001077 -#define MASK_SMAR64 0xfe00707f -#define MATCH_SMAQA 0xc8000077 -#define MASK_SMAQA 0xfe00707f -#define MATCH_SMAQA_SU 0xca000077 -#define MASK_SMAQA_SU 0xfe00707f -#define MATCH_SMAX8 0x8a000077 -#define MASK_SMAX8 0xfe00707f -#define MATCH_SMAX16 0x82000077 -#define MASK_SMAX16 0xfe00707f -#define MATCH_SMBB16 0x8001077 -#define MASK_SMBB16 0xfe00707f -#define MATCH_SMBT16 0x18001077 -#define MASK_SMBT16 0xfe00707f -#define MATCH_SMTT16 0x28001077 -#define MASK_SMTT16 0xfe00707f -#define MATCH_SMDS 0x58001077 -#define MASK_SMDS 0xfe00707f -#define MATCH_SMDRS 0x68001077 -#define MASK_SMDRS 0xfe00707f -#define MATCH_SMXDS 0x78001077 -#define MASK_SMXDS 0xfe00707f -#define MATCH_SMIN8 0x88000077 -#define MASK_SMIN8 0xfe00707f -#define MATCH_SMIN16 0x80000077 -#define MASK_SMIN16 0xfe00707f -#define MATCH_SMMUL 0x40001077 -#define MASK_SMMUL 0xfe00707f -#define MATCH_SMMUL_U 0x50001077 -#define MASK_SMMUL_U 0xfe00707f -#define MATCH_SMMWB 0x44001077 -#define MASK_SMMWB 0xfe00707f -#define MATCH_SMMWB_U 0x54001077 -#define MASK_SMMWB_U 0xfe00707f -#define MATCH_SMMWT 0x64001077 -#define MASK_SMMWT 0xfe00707f -#define MATCH_SMMWT_U 0x74001077 -#define MASK_SMMWT_U 0xfe00707f -#define MATCH_SMSLDA 0xac001077 -#define MASK_SMSLDA 0xfe00707f -#define MATCH_SMSLXDA 0xbc001077 -#define MASK_SMSLXDA 0xfe00707f -#define MATCH_SMSR64 0x86001077 -#define MASK_SMSR64 0xfe00707f -#define MATCH_SMUL8 0xa8000077 -#define MASK_SMUL8 0xfe00707f -#define MATCH_SMULX8 0xaa000077 -#define MASK_SMULX8 0xfe00707f -#define MATCH_SMUL16 0xa0000077 -#define MASK_SMUL16 0xfe00707f -#define MATCH_SMULX16 0xa2000077 -#define MASK_SMULX16 0xfe00707f -#define MATCH_SRA_U 0x24001077 -#define MASK_SRA_U 0xfe00707f -#define MATCH_SRAI_U 0xd4001077 -#define MASK_SRAI_U 0xfc00707f -#define MATCH_SRA8 0x58000077 -#define MASK_SRA8 0xfe00707f -#define MATCH_SRA8_U 0x68000077 -#define MASK_SRA8_U 0xfe00707f -#define MATCH_SRAI8 0x78000077 -#define MASK_SRAI8 0xff80707f -#define MATCH_SRAI8_U 0x78800077 -#define MASK_SRAI8_U 0xff80707f -#define MATCH_SRA16 0x50000077 -#define MASK_SRA16 0xfe00707f -#define MATCH_SRA16_U 0x60000077 -#define MASK_SRA16_U 0xfe00707f -#define MATCH_SRAI16 0x70000077 -#define MASK_SRAI16 0xff00707f -#define MATCH_SRAI16_U 0x71000077 -#define MASK_SRAI16_U 0xff00707f -#define MATCH_SRL8 0x5a000077 -#define MASK_SRL8 0xfe00707f -#define MATCH_SRL8_U 0x6a000077 -#define MASK_SRL8_U 0xfe00707f -#define MATCH_SRLI8 0x7a000077 -#define MASK_SRLI8 0xff80707f -#define MATCH_SRLI8_U 0x7a800077 -#define MASK_SRLI8_U 0xff80707f -#define MATCH_SRL16 0x52000077 -#define MASK_SRL16 0xfe00707f -#define MATCH_SRL16_U 0x62000077 -#define MASK_SRL16_U 0xfe00707f -#define MATCH_SRLI16 0x72000077 -#define MASK_SRLI16 0xff00707f -#define MATCH_SRLI16_U 0x73000077 -#define MASK_SRLI16_U 0xff00707f -#define MATCH_STAS16 0xf4002077 -#define MASK_STAS16 0xfe00707f -#define MATCH_STSA16 0xf6002077 -#define MASK_STSA16 0xfe00707f -#define MATCH_SUB8 0x4a000077 -#define MASK_SUB8 0xfe00707f -#define MATCH_SUB16 0x42000077 -#define MASK_SUB16 0xfe00707f -#define MATCH_SUB64 0xc2001077 -#define MASK_SUB64 0xfe00707f -#define MATCH_SUNPKD810 0xac800077 -#define MASK_SUNPKD810 0xfff0707f -#define MATCH_SUNPKD820 0xac900077 -#define MASK_SUNPKD820 0xfff0707f -#define MATCH_SUNPKD830 0xaca00077 -#define MASK_SUNPKD830 0xfff0707f -#define MATCH_SUNPKD831 0xacb00077 -#define MASK_SUNPKD831 0xfff0707f -#define MATCH_SUNPKD832 0xad300077 -#define MASK_SUNPKD832 0xfff0707f -#define MATCH_SWAP8 0xad800077 -#define MASK_SWAP8 0xfff0707f -#define MATCH_UCLIP8 0x8d000077 -#define MASK_UCLIP8 0xff80707f -#define MATCH_UCLIP16 0x85000077 -#define MASK_UCLIP16 0xff00707f -#define MATCH_UCLIP32 0xf4000077 -#define MASK_UCLIP32 0xfe00707f -#define MATCH_UCMPLE8 0x3e000077 -#define MASK_UCMPLE8 0xfe00707f -#define MATCH_UCMPLE16 0x3c000077 -#define MASK_UCMPLE16 0xfe00707f -#define MATCH_UCMPLT8 0x2e000077 -#define MASK_UCMPLT8 0xfe00707f -#define MATCH_UCMPLT16 0x2c000077 -#define MASK_UCMPLT16 0xfe00707f -#define MATCH_UKADD8 0x38000077 -#define MASK_UKADD8 0xfe00707f -#define MATCH_UKADD16 0x30000077 -#define MASK_UKADD16 0xfe00707f -#define MATCH_UKADD64 0xb0001077 -#define MASK_UKADD64 0xfe00707f -#define MATCH_UKADDH 0x14001077 -#define MASK_UKADDH 0xfe00707f -#define MATCH_UKADDW 0x10001077 -#define MASK_UKADDW 0xfe00707f -#define MATCH_UKCRAS16 0x34000077 -#define MASK_UKCRAS16 0xfe00707f -#define MATCH_UKCRSA16 0x36000077 -#define MASK_UKCRSA16 0xfe00707f -#define MATCH_UKMAR64 0xb4001077 -#define MASK_UKMAR64 0xfe00707f -#define MATCH_UKMSR64 0xb6001077 -#define MASK_UKMSR64 0xfe00707f -#define MATCH_UKSTAS16 0xe4002077 -#define MASK_UKSTAS16 0xfe00707f -#define MATCH_UKSTSA16 0xe6002077 -#define MASK_UKSTSA16 0xfe00707f -#define MATCH_UKSUB8 0x3a000077 -#define MASK_UKSUB8 0xfe00707f -#define MATCH_UKSUB16 0x32000077 -#define MASK_UKSUB16 0xfe00707f -#define MATCH_UKSUB64 0xb2001077 -#define MASK_UKSUB64 0xfe00707f -#define MATCH_UKSUBH 0x16001077 -#define MASK_UKSUBH 0xfe00707f -#define MATCH_UKSUBW 0x12001077 -#define MASK_UKSUBW 0xfe00707f -#define MATCH_UMAR64 0xa4001077 -#define MASK_UMAR64 0xfe00707f -#define MATCH_UMAQA 0xcc000077 -#define MASK_UMAQA 0xfe00707f -#define MATCH_UMAX8 0x9a000077 -#define MASK_UMAX8 0xfe00707f -#define MATCH_UMAX16 0x92000077 -#define MASK_UMAX16 0xfe00707f -#define MATCH_UMIN8 0x98000077 -#define MASK_UMIN8 0xfe00707f -#define MATCH_UMIN16 0x90000077 -#define MASK_UMIN16 0xfe00707f -#define MATCH_UMSR64 0xa6001077 -#define MASK_UMSR64 0xfe00707f -#define MATCH_UMUL8 0xb8000077 -#define MASK_UMUL8 0xfe00707f -#define MATCH_UMULX8 0xba000077 -#define MASK_UMULX8 0xfe00707f -#define MATCH_UMUL16 0xb0000077 -#define MASK_UMUL16 0xfe00707f -#define MATCH_UMULX16 0xb2000077 -#define MASK_UMULX16 0xfe00707f -#define MATCH_URADD8 0x28000077 -#define MASK_URADD8 0xfe00707f -#define MATCH_URADD16 0x20000077 -#define MASK_URADD16 0xfe00707f -#define MATCH_URADD64 0xa0001077 -#define MASK_URADD64 0xfe00707f -#define MATCH_URADDW 0x30001077 -#define MASK_URADDW 0xfe00707f -#define MATCH_URCRAS16 0x24000077 -#define MASK_URCRAS16 0xfe00707f -#define MATCH_URCRSA16 0x26000077 -#define MASK_URCRSA16 0xfe00707f -#define MATCH_URSTAS16 0xd4002077 -#define MASK_URSTAS16 0xfe00707f -#define MATCH_URSTSA16 0xd6002077 -#define MASK_URSTSA16 0xfe00707f -#define MATCH_URSUB8 0x2a000077 -#define MASK_URSUB8 0xfe00707f -#define MATCH_URSUB16 0x22000077 -#define MASK_URSUB16 0xfe00707f -#define MATCH_URSUB64 0xa2001077 -#define MASK_URSUB64 0xfe00707f -#define MATCH_URSUBW 0x32001077 -#define MASK_URSUBW 0xfe00707f -#define MATCH_WEXTI 0xde000077 -#define MASK_WEXTI 0xfe00707f -#define MATCH_WEXT 0xce000077 -#define MASK_WEXT 0xfe00707f -#define MATCH_ZUNPKD810 0xacc00077 -#define MASK_ZUNPKD810 0xfff0707f -#define MATCH_ZUNPKD820 0xacd00077 -#define MASK_ZUNPKD820 0xfff0707f -#define MATCH_ZUNPKD830 0xace00077 -#define MASK_ZUNPKD830 0xfff0707f -#define MATCH_ZUNPKD831 0xacf00077 -#define MASK_ZUNPKD831 0xfff0707f -#define MATCH_ZUNPKD832 0xad700077 -#define MASK_ZUNPKD832 0xfff0707f +#define MASK_ADD16 0xfe00707f #define MATCH_ADD32 0x40002077 -#define MASK_ADD32 0xfe00707f +#define MASK_ADD32 0xfe00707f +#define MATCH_ADD64 0xc0001077 +#define MASK_ADD64 0xfe00707f +#define MATCH_ADD8 0x48000077 +#define MASK_ADD8 0xfe00707f +#define MATCH_ADD_UW 0x800003b +#define MASK_ADD_UW 0xfe00707f +#define MATCH_ADDD 0x7b +#define MASK_ADDD 0xfe00707f +#define MATCH_ADDI 0x13 +#define MASK_ADDI 0x707f +#define MATCH_ADDID 0x5b +#define MASK_ADDID 0x707f +#define MATCH_ADDIW 0x1b +#define MASK_ADDIW 0x707f +#define MATCH_ADDW 0x3b +#define MASK_ADDW 0xfe00707f +#define MATCH_AES32DSI 0x2a000033 +#define MASK_AES32DSI 0x3e00707f +#define MATCH_AES32DSMI 0x2e000033 +#define MASK_AES32DSMI 0x3e00707f +#define MATCH_AES32ESI 0x22000033 +#define MASK_AES32ESI 0x3e00707f +#define MATCH_AES32ESMI 0x26000033 +#define MASK_AES32ESMI 0x3e00707f +#define MATCH_AES64DS 0x3a000033 +#define MASK_AES64DS 0xfe00707f +#define MATCH_AES64DSM 0x3e000033 +#define MASK_AES64DSM 0xfe00707f +#define MATCH_AES64ES 0x32000033 +#define MASK_AES64ES 0xfe00707f +#define MATCH_AES64ESM 0x36000033 +#define MASK_AES64ESM 0xfe00707f +#define MATCH_AES64IM 0x30001013 +#define MASK_AES64IM 0xfff0707f +#define MATCH_AES64KS1I 0x31001013 +#define MASK_AES64KS1I 0xff00707f +#define MATCH_AES64KS2 0x7e000033 +#define MASK_AES64KS2 0xfe00707f +#define MATCH_AMOADD_D 0x302f +#define MASK_AMOADD_D 0xf800707f +#define MATCH_AMOADD_W 0x202f +#define MASK_AMOADD_W 0xf800707f +#define MATCH_AMOAND_D 0x6000302f +#define MASK_AMOAND_D 0xf800707f +#define MATCH_AMOAND_W 0x6000202f +#define MASK_AMOAND_W 0xf800707f +#define MATCH_AMOMAX_D 0xa000302f +#define MASK_AMOMAX_D 0xf800707f +#define MATCH_AMOMAX_W 0xa000202f +#define MASK_AMOMAX_W 0xf800707f +#define MATCH_AMOMAXU_D 0xe000302f +#define MASK_AMOMAXU_D 0xf800707f +#define MATCH_AMOMAXU_W 0xe000202f +#define MASK_AMOMAXU_W 0xf800707f +#define MATCH_AMOMIN_D 0x8000302f +#define MASK_AMOMIN_D 0xf800707f +#define MATCH_AMOMIN_W 0x8000202f +#define MASK_AMOMIN_W 0xf800707f +#define MATCH_AMOMINU_D 0xc000302f +#define MASK_AMOMINU_D 0xf800707f +#define MATCH_AMOMINU_W 0xc000202f +#define MASK_AMOMINU_W 0xf800707f +#define MATCH_AMOOR_D 0x4000302f +#define MASK_AMOOR_D 0xf800707f +#define MATCH_AMOOR_W 0x4000202f +#define MASK_AMOOR_W 0xf800707f +#define MATCH_AMOSWAP_D 0x800302f +#define MASK_AMOSWAP_D 0xf800707f +#define MATCH_AMOSWAP_W 0x800202f +#define MASK_AMOSWAP_W 0xf800707f +#define MATCH_AMOXOR_D 0x2000302f +#define MASK_AMOXOR_D 0xf800707f +#define MATCH_AMOXOR_W 0x2000202f +#define MASK_AMOXOR_W 0xf800707f +#define MATCH_AND 0x7033 +#define MASK_AND 0xfe00707f +#define MATCH_ANDI 0x7013 +#define MASK_ANDI 0x707f +#define MATCH_ANDN 0x40007033 +#define MASK_ANDN 0xfe00707f +#define MATCH_AUIPC 0x17 +#define MASK_AUIPC 0x7f +#define MATCH_AVE 0xe0000077 +#define MASK_AVE 0xfe00707f +#define MATCH_BCLR 0x48001033 +#define MASK_BCLR 0xfe00707f +#define MATCH_BCLRI 0x48001013 +#define MASK_BCLRI 0xfc00707f +#define MATCH_BCOMPRESS 0x8006033 +#define MASK_BCOMPRESS 0xfe00707f +#define MATCH_BCOMPRESSW 0x800603b +#define MASK_BCOMPRESSW 0xfe00707f +#define MATCH_BDECOMPRESS 0x48006033 +#define MASK_BDECOMPRESS 0xfe00707f +#define MATCH_BDECOMPRESSW 0x4800603b +#define MASK_BDECOMPRESSW 0xfe00707f +#define MATCH_BEQ 0x63 +#define MASK_BEQ 0x707f +#define MATCH_BEXT 0x48005033 +#define MASK_BEXT 0xfe00707f +#define MATCH_BEXTI 0x48005013 +#define MASK_BEXTI 0xfc00707f +#define MATCH_BFP 0x48007033 +#define MASK_BFP 0xfe00707f +#define MATCH_BFPW 0x4800703b +#define MASK_BFPW 0xfe00707f +#define MATCH_BGE 0x5063 +#define MASK_BGE 0x707f +#define MATCH_BGEU 0x7063 +#define MASK_BGEU 0x707f +#define MATCH_BINV 0x68001033 +#define MASK_BINV 0xfe00707f +#define MATCH_BINVI 0x68001013 +#define MASK_BINVI 0xfc00707f +#define MATCH_BLT 0x4063 +#define MASK_BLT 0x707f +#define MATCH_BLTU 0x6063 +#define MASK_BLTU 0x707f +#define MATCH_BMATFLIP 0x60301013 +#define MASK_BMATFLIP 0xfff0707f +#define MATCH_BMATOR 0x8003033 +#define MASK_BMATOR 0xfe00707f +#define MATCH_BMATXOR 0x48003033 +#define MASK_BMATXOR 0xfe00707f +#define MATCH_BNE 0x1063 +#define MASK_BNE 0x707f +#define MATCH_BSET 0x28001033 +#define MASK_BSET 0xfe00707f +#define MATCH_BSETI 0x28001013 +#define MASK_BSETI 0xfc00707f +#define MATCH_C_ADD 0x9002 +#define MASK_C_ADD 0xf003 +#define MATCH_C_ADDI 0x1 +#define MASK_C_ADDI 0xe003 +#define MATCH_C_ADDI16SP 0x6101 +#define MASK_C_ADDI16SP 0xef83 +#define MATCH_C_ADDI4SPN 0x0 +#define MASK_C_ADDI4SPN 0xe003 +#define MATCH_C_ADDIW 0x2001 +#define MASK_C_ADDIW 0xe003 +#define MATCH_C_ADDW 0x9c21 +#define MASK_C_ADDW 0xfc63 +#define MATCH_C_AND 0x8c61 +#define MASK_C_AND 0xfc63 +#define MATCH_C_ANDI 0x8801 +#define MASK_C_ANDI 0xec03 +#define MATCH_C_BEQZ 0xc001 +#define MASK_C_BEQZ 0xe003 +#define MATCH_C_BNEZ 0xe001 +#define MASK_C_BNEZ 0xe003 +#define MATCH_C_EBREAK 0x9002 +#define MASK_C_EBREAK 0xffff +#define MATCH_C_FLD 0x2000 +#define MASK_C_FLD 0xe003 +#define MATCH_C_FLDSP 0x2002 +#define MASK_C_FLDSP 0xe003 +#define MATCH_C_FLW 0x6000 +#define MASK_C_FLW 0xe003 +#define MATCH_C_FLWSP 0x6002 +#define MASK_C_FLWSP 0xe003 +#define MATCH_C_FSD 0xa000 +#define MASK_C_FSD 0xe003 +#define MATCH_C_FSDSP 0xa002 +#define MASK_C_FSDSP 0xe003 +#define MATCH_C_FSW 0xe000 +#define MASK_C_FSW 0xe003 +#define MATCH_C_FSWSP 0xe002 +#define MASK_C_FSWSP 0xe003 +#define MATCH_C_J 0xa001 +#define MASK_C_J 0xe003 +#define MATCH_C_JAL 0x2001 +#define MASK_C_JAL 0xe003 +#define MATCH_C_JALR 0x9002 +#define MASK_C_JALR 0xf07f +#define MATCH_C_JR 0x8002 +#define MASK_C_JR 0xf07f +#define MATCH_C_LBU 0x8000 +#define MASK_C_LBU 0xfc03 +#define MATCH_C_LD 0x6000 +#define MASK_C_LD 0xe003 +#define MATCH_C_LDSP 0x6002 +#define MASK_C_LDSP 0xe003 +#define MATCH_C_LH 0x8440 +#define MASK_C_LH 0xfc43 +#define MATCH_C_LHU 0x8400 +#define MASK_C_LHU 0xfc43 +#define MATCH_C_LI 0x4001 +#define MASK_C_LI 0xe003 +#define MATCH_C_LQ 0x2000 +#define MASK_C_LQ 0xe003 +#define MATCH_C_LQSP 0x2002 +#define MASK_C_LQSP 0xe003 +#define MATCH_C_LUI 0x6001 +#define MASK_C_LUI 0xe003 +#define MATCH_C_LW 0x4000 +#define MASK_C_LW 0xe003 +#define MATCH_C_LWSP 0x4002 +#define MASK_C_LWSP 0xe003 +#define MATCH_C_MUL 0x9c41 +#define MASK_C_MUL 0xfc63 +#define MATCH_C_MV 0x8002 +#define MASK_C_MV 0xf003 +#define MATCH_C_NOP 0x1 +#define MASK_C_NOP 0xef83 +#define MATCH_C_NOT 0x9c75 +#define MASK_C_NOT 0xfc7f +#define MATCH_C_OR 0x8c41 +#define MASK_C_OR 0xfc63 +#define MATCH_C_SB 0x8800 +#define MASK_C_SB 0xfc03 +#define MATCH_C_SD 0xe000 +#define MASK_C_SD 0xe003 +#define MATCH_C_SDSP 0xe002 +#define MASK_C_SDSP 0xe003 +#define MATCH_C_SEXT_B 0x9c65 +#define MASK_C_SEXT_B 0xfc7f +#define MATCH_C_SEXT_H 0x9c6d +#define MASK_C_SEXT_H 0xfc7f +#define MATCH_C_SH 0x8c00 +#define MASK_C_SH 0xfc43 +#define MATCH_C_SLLI 0x2 +#define MASK_C_SLLI 0xe003 +#define MATCH_C_SQ 0xa000 +#define MASK_C_SQ 0xe003 +#define MATCH_C_SQSP 0xa002 +#define MASK_C_SQSP 0xe003 +#define MATCH_C_SRAI 0x8401 +#define MASK_C_SRAI 0xec03 +#define MATCH_C_SRLI 0x8001 +#define MASK_C_SRLI 0xec03 +#define MATCH_C_SUB 0x8c01 +#define MASK_C_SUB 0xfc63 +#define MATCH_C_SUBW 0x9c01 +#define MASK_C_SUBW 0xfc63 +#define MATCH_C_SW 0xc000 +#define MASK_C_SW 0xe003 +#define MATCH_C_SWSP 0xc002 +#define MASK_C_SWSP 0xe003 +#define MATCH_C_XOR 0x8c21 +#define MASK_C_XOR 0xfc63 +#define MATCH_C_ZEXT_B 0x9c61 +#define MASK_C_ZEXT_B 0xfc7f +#define MATCH_C_ZEXT_H 0x9c69 +#define MASK_C_ZEXT_H 0xfc7f +#define MATCH_C_ZEXT_W 0x9c71 +#define MASK_C_ZEXT_W 0xfc7f +#define MATCH_CBO_CLEAN 0x10200f +#define MASK_CBO_CLEAN 0xfff07fff +#define MATCH_CBO_FLUSH 0x20200f +#define MASK_CBO_FLUSH 0xfff07fff +#define MATCH_CBO_INVAL 0x200f +#define MASK_CBO_INVAL 0xfff07fff +#define MATCH_CBO_ZERO 0x40200f +#define MASK_CBO_ZERO 0xfff07fff +#define MATCH_CLMUL 0xa001033 +#define MASK_CLMUL 0xfe00707f +#define MATCH_CLMULH 0xa003033 +#define MASK_CLMULH 0xfe00707f +#define MATCH_CLMULR 0xa002033 +#define MASK_CLMULR 0xfe00707f +#define MATCH_CLRS16 0xae800077 +#define MASK_CLRS16 0xfff0707f +#define MATCH_CLRS32 0xaf800077 +#define MASK_CLRS32 0xfff0707f +#define MATCH_CLRS8 0xae000077 +#define MASK_CLRS8 0xfff0707f +#define MATCH_CLZ 0x60001013 +#define MASK_CLZ 0xfff0707f +#define MATCH_CLZ16 0xae900077 +#define MASK_CLZ16 0xfff0707f +#define MATCH_CLZ32 0xaf900077 +#define MASK_CLZ32 0xfff0707f +#define MATCH_CLZ8 0xae100077 +#define MASK_CLZ8 0xfff0707f +#define MATCH_CLZW 0x6000101b +#define MASK_CLZW 0xfff0707f +#define MATCH_CM_JALT 0xa002 +#define MASK_CM_JALT 0xfc03 +#define MATCH_CM_MVA01S 0xac62 +#define MASK_CM_MVA01S 0xfc63 +#define MATCH_CM_MVSA01 0xac22 +#define MASK_CM_MVSA01 0xfc63 +#define MATCH_CM_POP 0xba02 +#define MASK_CM_POP 0xff03 +#define MATCH_CM_POPRET 0xbe02 +#define MASK_CM_POPRET 0xff03 +#define MATCH_CM_POPRETZ 0xbc02 +#define MASK_CM_POPRETZ 0xff03 +#define MATCH_CM_PUSH 0xb802 +#define MASK_CM_PUSH 0xff03 +#define MATCH_CMIX 0x6001033 +#define MASK_CMIX 0x600707f +#define MATCH_CMOV 0x6005033 +#define MASK_CMOV 0x600707f +#define MATCH_CMPEQ16 0x4c000077 +#define MASK_CMPEQ16 0xfe00707f +#define MATCH_CMPEQ8 0x4e000077 +#define MASK_CMPEQ8 0xfe00707f +#define MATCH_CPOP 0x60201013 +#define MASK_CPOP 0xfff0707f +#define MATCH_CPOPW 0x6020101b +#define MASK_CPOPW 0xfff0707f +#define MATCH_CRAS16 0x44000077 +#define MASK_CRAS16 0xfe00707f #define MATCH_CRAS32 0x44002077 -#define MASK_CRAS32 0xfe00707f +#define MASK_CRAS32 0xfe00707f +#define MATCH_CRC32_B 0x61001013 +#define MASK_CRC32_B 0xfff0707f +#define MATCH_CRC32_D 0x61301013 +#define MASK_CRC32_D 0xfff0707f +#define MATCH_CRC32_H 0x61101013 +#define MASK_CRC32_H 0xfff0707f +#define MATCH_CRC32_W 0x61201013 +#define MASK_CRC32_W 0xfff0707f +#define MATCH_CRC32C_B 0x61801013 +#define MASK_CRC32C_B 0xfff0707f +#define MATCH_CRC32C_D 0x61b01013 +#define MASK_CRC32C_D 0xfff0707f +#define MATCH_CRC32C_H 0x61901013 +#define MASK_CRC32C_H 0xfff0707f +#define MATCH_CRC32C_W 0x61a01013 +#define MASK_CRC32C_W 0xfff0707f +#define MATCH_CRSA16 0x46000077 +#define MASK_CRSA16 0xfe00707f #define MATCH_CRSA32 0x46002077 -#define MASK_CRSA32 0xfe00707f +#define MASK_CRSA32 0xfe00707f +#define MATCH_CSRRC 0x3073 +#define MASK_CSRRC 0x707f +#define MATCH_CSRRCI 0x7073 +#define MASK_CSRRCI 0x707f +#define MATCH_CSRRS 0x2073 +#define MASK_CSRRS 0x707f +#define MATCH_CSRRSI 0x6073 +#define MASK_CSRRSI 0x707f +#define MATCH_CSRRW 0x1073 +#define MASK_CSRRW 0x707f +#define MATCH_CSRRWI 0x5073 +#define MASK_CSRRWI 0x707f +#define MATCH_CTZ 0x60101013 +#define MASK_CTZ 0xfff0707f +#define MATCH_CTZW 0x6010101b +#define MASK_CTZW 0xfff0707f +#define MATCH_CZERO_EQZ 0xe005033 +#define MASK_CZERO_EQZ 0xfe00707f +#define MATCH_CZERO_NEZ 0xe007033 +#define MASK_CZERO_NEZ 0xfe00707f +#define MATCH_DIV 0x2004033 +#define MASK_DIV 0xfe00707f +#define MATCH_DIVU 0x2005033 +#define MASK_DIVU 0xfe00707f +#define MATCH_DIVUW 0x200503b +#define MASK_DIVUW 0xfe00707f +#define MATCH_DIVW 0x200403b +#define MASK_DIVW 0xfe00707f +#define MATCH_DRET 0x7b200073 +#define MASK_DRET 0xffffffff +#define MATCH_EBREAK 0x100073 +#define MASK_EBREAK 0xffffffff +#define MATCH_ECALL 0x73 +#define MASK_ECALL 0xffffffff +#define MATCH_FADD_D 0x2000053 +#define MASK_FADD_D 0xfe00007f +#define MATCH_FADD_H 0x4000053 +#define MASK_FADD_H 0xfe00007f +#define MATCH_FADD_Q 0x6000053 +#define MASK_FADD_Q 0xfe00007f +#define MATCH_FADD_S 0x53 +#define MASK_FADD_S 0xfe00007f +#define MATCH_FCLASS_D 0xe2001053 +#define MASK_FCLASS_D 0xfff0707f +#define MATCH_FCLASS_H 0xe4001053 +#define MASK_FCLASS_H 0xfff0707f +#define MATCH_FCLASS_Q 0xe6001053 +#define MASK_FCLASS_Q 0xfff0707f +#define MATCH_FCLASS_S 0xe0001053 +#define MASK_FCLASS_S 0xfff0707f +#define MATCH_FCVT_D_H 0x42200053 +#define MASK_FCVT_D_H 0xfff0007f +#define MATCH_FCVT_D_L 0xd2200053 +#define MASK_FCVT_D_L 0xfff0007f +#define MATCH_FCVT_D_LU 0xd2300053 +#define MASK_FCVT_D_LU 0xfff0007f +#define MATCH_FCVT_D_Q 0x42300053 +#define MASK_FCVT_D_Q 0xfff0007f +#define MATCH_FCVT_D_S 0x42000053 +#define MASK_FCVT_D_S 0xfff0007f +#define MATCH_FCVT_D_W 0xd2000053 +#define MASK_FCVT_D_W 0xfff0007f +#define MATCH_FCVT_D_WU 0xd2100053 +#define MASK_FCVT_D_WU 0xfff0007f +#define MATCH_FCVT_H_D 0x44100053 +#define MASK_FCVT_H_D 0xfff0007f +#define MATCH_FCVT_H_L 0xd4200053 +#define MASK_FCVT_H_L 0xfff0007f +#define MATCH_FCVT_H_LU 0xd4300053 +#define MASK_FCVT_H_LU 0xfff0007f +#define MATCH_FCVT_H_Q 0x44300053 +#define MASK_FCVT_H_Q 0xfff0007f +#define MATCH_FCVT_H_S 0x44000053 +#define MASK_FCVT_H_S 0xfff0007f +#define MATCH_FCVT_H_W 0xd4000053 +#define MASK_FCVT_H_W 0xfff0007f +#define MATCH_FCVT_H_WU 0xd4100053 +#define MASK_FCVT_H_WU 0xfff0007f +#define MATCH_FCVT_L_D 0xc2200053 +#define MASK_FCVT_L_D 0xfff0007f +#define MATCH_FCVT_L_H 0xc4200053 +#define MASK_FCVT_L_H 0xfff0007f +#define MATCH_FCVT_L_Q 0xc6200053 +#define MASK_FCVT_L_Q 0xfff0007f +#define MATCH_FCVT_L_S 0xc0200053 +#define MASK_FCVT_L_S 0xfff0007f +#define MATCH_FCVT_LU_D 0xc2300053 +#define MASK_FCVT_LU_D 0xfff0007f +#define MATCH_FCVT_LU_H 0xc4300053 +#define MASK_FCVT_LU_H 0xfff0007f +#define MATCH_FCVT_LU_Q 0xc6300053 +#define MASK_FCVT_LU_Q 0xfff0007f +#define MATCH_FCVT_LU_S 0xc0300053 +#define MASK_FCVT_LU_S 0xfff0007f +#define MATCH_FCVT_Q_D 0x46100053 +#define MASK_FCVT_Q_D 0xfff0007f +#define MATCH_FCVT_Q_H 0x46200053 +#define MASK_FCVT_Q_H 0xfff0007f +#define MATCH_FCVT_Q_L 0xd6200053 +#define MASK_FCVT_Q_L 0xfff0007f +#define MATCH_FCVT_Q_LU 0xd6300053 +#define MASK_FCVT_Q_LU 0xfff0007f +#define MATCH_FCVT_Q_S 0x46000053 +#define MASK_FCVT_Q_S 0xfff0007f +#define MATCH_FCVT_Q_W 0xd6000053 +#define MASK_FCVT_Q_W 0xfff0007f +#define MATCH_FCVT_Q_WU 0xd6100053 +#define MASK_FCVT_Q_WU 0xfff0007f +#define MATCH_FCVT_S_D 0x40100053 +#define MASK_FCVT_S_D 0xfff0007f +#define MATCH_FCVT_S_H 0x40200053 +#define MASK_FCVT_S_H 0xfff0007f +#define MATCH_FCVT_S_L 0xd0200053 +#define MASK_FCVT_S_L 0xfff0007f +#define MATCH_FCVT_S_LU 0xd0300053 +#define MASK_FCVT_S_LU 0xfff0007f +#define MATCH_FCVT_S_Q 0x40300053 +#define MASK_FCVT_S_Q 0xfff0007f +#define MATCH_FCVT_S_W 0xd0000053 +#define MASK_FCVT_S_W 0xfff0007f +#define MATCH_FCVT_S_WU 0xd0100053 +#define MASK_FCVT_S_WU 0xfff0007f +#define MATCH_FCVT_W_D 0xc2000053 +#define MASK_FCVT_W_D 0xfff0007f +#define MATCH_FCVT_W_H 0xc4000053 +#define MASK_FCVT_W_H 0xfff0007f +#define MATCH_FCVT_W_Q 0xc6000053 +#define MASK_FCVT_W_Q 0xfff0007f +#define MATCH_FCVT_W_S 0xc0000053 +#define MASK_FCVT_W_S 0xfff0007f +#define MATCH_FCVT_WU_D 0xc2100053 +#define MASK_FCVT_WU_D 0xfff0007f +#define MATCH_FCVT_WU_H 0xc4100053 +#define MASK_FCVT_WU_H 0xfff0007f +#define MATCH_FCVT_WU_Q 0xc6100053 +#define MASK_FCVT_WU_Q 0xfff0007f +#define MATCH_FCVT_WU_S 0xc0100053 +#define MASK_FCVT_WU_S 0xfff0007f +#define MATCH_FCVTMOD_W_D 0xc2801053 +#define MASK_FCVTMOD_W_D 0xfff0707f +#define MATCH_FDIV_D 0x1a000053 +#define MASK_FDIV_D 0xfe00007f +#define MATCH_FDIV_H 0x1c000053 +#define MASK_FDIV_H 0xfe00007f +#define MATCH_FDIV_Q 0x1e000053 +#define MASK_FDIV_Q 0xfe00007f +#define MATCH_FDIV_S 0x18000053 +#define MASK_FDIV_S 0xfe00007f +#define MATCH_FENCE 0xf +#define MASK_FENCE 0x707f +#define MATCH_FENCE_I 0x100f +#define MASK_FENCE_I 0x707f +#define MATCH_FEQ_D 0xa2002053 +#define MASK_FEQ_D 0xfe00707f +#define MATCH_FEQ_H 0xa4002053 +#define MASK_FEQ_H 0xfe00707f +#define MATCH_FEQ_Q 0xa6002053 +#define MASK_FEQ_Q 0xfe00707f +#define MATCH_FEQ_S 0xa0002053 +#define MASK_FEQ_S 0xfe00707f +#define MATCH_FLD 0x3007 +#define MASK_FLD 0x707f +#define MATCH_FLE_D 0xa2000053 +#define MASK_FLE_D 0xfe00707f +#define MATCH_FLE_H 0xa4000053 +#define MASK_FLE_H 0xfe00707f +#define MATCH_FLE_Q 0xa6000053 +#define MASK_FLE_Q 0xfe00707f +#define MATCH_FLE_S 0xa0000053 +#define MASK_FLE_S 0xfe00707f +#define MATCH_FLEQ_D 0xa2004053 +#define MASK_FLEQ_D 0xfe00707f +#define MATCH_FLEQ_H 0xa4004053 +#define MASK_FLEQ_H 0xfe00707f +#define MATCH_FLEQ_Q 0xa6004053 +#define MASK_FLEQ_Q 0xfe00707f +#define MATCH_FLEQ_S 0xa0004053 +#define MASK_FLEQ_S 0xfe00707f +#define MATCH_FLH 0x1007 +#define MASK_FLH 0x707f +#define MATCH_FLI_D 0xf2100053 +#define MASK_FLI_D 0xfff0707f +#define MATCH_FLI_H 0xf4100053 +#define MASK_FLI_H 0xfff0707f +#define MATCH_FLI_Q 0xf6100053 +#define MASK_FLI_Q 0xfff0707f +#define MATCH_FLI_S 0xf0100053 +#define MASK_FLI_S 0xfff0707f +#define MATCH_FLQ 0x4007 +#define MASK_FLQ 0x707f +#define MATCH_FLT_D 0xa2001053 +#define MASK_FLT_D 0xfe00707f +#define MATCH_FLT_H 0xa4001053 +#define MASK_FLT_H 0xfe00707f +#define MATCH_FLT_Q 0xa6001053 +#define MASK_FLT_Q 0xfe00707f +#define MATCH_FLT_S 0xa0001053 +#define MASK_FLT_S 0xfe00707f +#define MATCH_FLTQ_D 0xa2005053 +#define MASK_FLTQ_D 0xfe00707f +#define MATCH_FLTQ_H 0xa4005053 +#define MASK_FLTQ_H 0xfe00707f +#define MATCH_FLTQ_Q 0xa6005053 +#define MASK_FLTQ_Q 0xfe00707f +#define MATCH_FLTQ_S 0xa0005053 +#define MASK_FLTQ_S 0xfe00707f +#define MATCH_FLW 0x2007 +#define MASK_FLW 0x707f +#define MATCH_FMADD_D 0x2000043 +#define MASK_FMADD_D 0x600007f +#define MATCH_FMADD_H 0x4000043 +#define MASK_FMADD_H 0x600007f +#define MATCH_FMADD_Q 0x6000043 +#define MASK_FMADD_Q 0x600007f +#define MATCH_FMADD_S 0x43 +#define MASK_FMADD_S 0x600007f +#define MATCH_FMAX_D 0x2a001053 +#define MASK_FMAX_D 0xfe00707f +#define MATCH_FMAX_H 0x2c001053 +#define MASK_FMAX_H 0xfe00707f +#define MATCH_FMAX_Q 0x2e001053 +#define MASK_FMAX_Q 0xfe00707f +#define MATCH_FMAX_S 0x28001053 +#define MASK_FMAX_S 0xfe00707f +#define MATCH_FMAXM_D 0x2a003053 +#define MASK_FMAXM_D 0xfe00707f +#define MATCH_FMAXM_H 0x2c003053 +#define MASK_FMAXM_H 0xfe00707f +#define MATCH_FMAXM_Q 0x2e003053 +#define MASK_FMAXM_Q 0xfe00707f +#define MATCH_FMAXM_S 0x28003053 +#define MASK_FMAXM_S 0xfe00707f +#define MATCH_FMIN_D 0x2a000053 +#define MASK_FMIN_D 0xfe00707f +#define MATCH_FMIN_H 0x2c000053 +#define MASK_FMIN_H 0xfe00707f +#define MATCH_FMIN_Q 0x2e000053 +#define MASK_FMIN_Q 0xfe00707f +#define MATCH_FMIN_S 0x28000053 +#define MASK_FMIN_S 0xfe00707f +#define MATCH_FMINM_D 0x2a002053 +#define MASK_FMINM_D 0xfe00707f +#define MATCH_FMINM_H 0x2c002053 +#define MASK_FMINM_H 0xfe00707f +#define MATCH_FMINM_Q 0x2e002053 +#define MASK_FMINM_Q 0xfe00707f +#define MATCH_FMINM_S 0x28002053 +#define MASK_FMINM_S 0xfe00707f +#define MATCH_FMSUB_D 0x2000047 +#define MASK_FMSUB_D 0x600007f +#define MATCH_FMSUB_H 0x4000047 +#define MASK_FMSUB_H 0x600007f +#define MATCH_FMSUB_Q 0x6000047 +#define MASK_FMSUB_Q 0x600007f +#define MATCH_FMSUB_S 0x47 +#define MASK_FMSUB_S 0x600007f +#define MATCH_FMUL_D 0x12000053 +#define MASK_FMUL_D 0xfe00007f +#define MATCH_FMUL_H 0x14000053 +#define MASK_FMUL_H 0xfe00007f +#define MATCH_FMUL_Q 0x16000053 +#define MASK_FMUL_Q 0xfe00007f +#define MATCH_FMUL_S 0x10000053 +#define MASK_FMUL_S 0xfe00007f +#define MATCH_FMV_D_X 0xf2000053 +#define MASK_FMV_D_X 0xfff0707f +#define MATCH_FMV_H_X 0xf4000053 +#define MASK_FMV_H_X 0xfff0707f +#define MATCH_FMV_W_X 0xf0000053 +#define MASK_FMV_W_X 0xfff0707f +#define MATCH_FMV_X_D 0xe2000053 +#define MASK_FMV_X_D 0xfff0707f +#define MATCH_FMV_X_H 0xe4000053 +#define MASK_FMV_X_H 0xfff0707f +#define MATCH_FMV_X_W 0xe0000053 +#define MASK_FMV_X_W 0xfff0707f +#define MATCH_FMVH_X_D 0xe2100053 +#define MASK_FMVH_X_D 0xfff0707f +#define MATCH_FMVH_X_Q 0xe6100053 +#define MASK_FMVH_X_Q 0xfff0707f +#define MATCH_FMVP_D_X 0xb2100053 +#define MASK_FMVP_D_X 0xfff0707f +#define MATCH_FMVP_Q_X 0xb6100053 +#define MASK_FMVP_Q_X 0xfff0707f +#define MATCH_FNMADD_D 0x200004f +#define MASK_FNMADD_D 0x600007f +#define MATCH_FNMADD_H 0x400004f +#define MASK_FNMADD_H 0x600007f +#define MATCH_FNMADD_Q 0x600004f +#define MASK_FNMADD_Q 0x600007f +#define MATCH_FNMADD_S 0x4f +#define MASK_FNMADD_S 0x600007f +#define MATCH_FNMSUB_D 0x200004b +#define MASK_FNMSUB_D 0x600007f +#define MATCH_FNMSUB_H 0x400004b +#define MASK_FNMSUB_H 0x600007f +#define MATCH_FNMSUB_Q 0x600004b +#define MASK_FNMSUB_Q 0x600007f +#define MATCH_FNMSUB_S 0x4b +#define MASK_FNMSUB_S 0x600007f +#define MATCH_FROUND_D 0x42400053 +#define MASK_FROUND_D 0xfff0007f +#define MATCH_FROUND_H 0x44400053 +#define MASK_FROUND_H 0xfff0007f +#define MATCH_FROUND_Q 0x46400053 +#define MASK_FROUND_Q 0xfff0007f +#define MATCH_FROUND_S 0x40400053 +#define MASK_FROUND_S 0xfff0007f +#define MATCH_FROUNDNX_D 0x42500053 +#define MASK_FROUNDNX_D 0xfff0007f +#define MATCH_FROUNDNX_H 0x44500053 +#define MASK_FROUNDNX_H 0xfff0007f +#define MATCH_FROUNDNX_Q 0x46500053 +#define MASK_FROUNDNX_Q 0xfff0007f +#define MATCH_FROUNDNX_S 0x40500053 +#define MASK_FROUNDNX_S 0xfff0007f +#define MATCH_FSD 0x3027 +#define MASK_FSD 0x707f +#define MATCH_FSGNJ_D 0x22000053 +#define MASK_FSGNJ_D 0xfe00707f +#define MATCH_FSGNJ_H 0x24000053 +#define MASK_FSGNJ_H 0xfe00707f +#define MATCH_FSGNJ_Q 0x26000053 +#define MASK_FSGNJ_Q 0xfe00707f +#define MATCH_FSGNJ_S 0x20000053 +#define MASK_FSGNJ_S 0xfe00707f +#define MATCH_FSGNJN_D 0x22001053 +#define MASK_FSGNJN_D 0xfe00707f +#define MATCH_FSGNJN_H 0x24001053 +#define MASK_FSGNJN_H 0xfe00707f +#define MATCH_FSGNJN_Q 0x26001053 +#define MASK_FSGNJN_Q 0xfe00707f +#define MATCH_FSGNJN_S 0x20001053 +#define MASK_FSGNJN_S 0xfe00707f +#define MATCH_FSGNJX_D 0x22002053 +#define MASK_FSGNJX_D 0xfe00707f +#define MATCH_FSGNJX_H 0x24002053 +#define MASK_FSGNJX_H 0xfe00707f +#define MATCH_FSGNJX_Q 0x26002053 +#define MASK_FSGNJX_Q 0xfe00707f +#define MATCH_FSGNJX_S 0x20002053 +#define MASK_FSGNJX_S 0xfe00707f +#define MATCH_FSH 0x1027 +#define MASK_FSH 0x707f +#define MATCH_FSL 0x4001033 +#define MASK_FSL 0x600707f +#define MATCH_FSLW 0x400103b +#define MASK_FSLW 0x600707f +#define MATCH_FSQ 0x4027 +#define MASK_FSQ 0x707f +#define MATCH_FSQRT_D 0x5a000053 +#define MASK_FSQRT_D 0xfff0007f +#define MATCH_FSQRT_H 0x5c000053 +#define MASK_FSQRT_H 0xfff0007f +#define MATCH_FSQRT_Q 0x5e000053 +#define MASK_FSQRT_Q 0xfff0007f +#define MATCH_FSQRT_S 0x58000053 +#define MASK_FSQRT_S 0xfff0007f +#define MATCH_FSR 0x4005033 +#define MASK_FSR 0x600707f +#define MATCH_FSRI 0x4005013 +#define MASK_FSRI 0x400707f +#define MATCH_FSRIW 0x400501b +#define MASK_FSRIW 0x600707f +#define MATCH_FSRW 0x400503b +#define MASK_FSRW 0x600707f +#define MATCH_FSUB_D 0xa000053 +#define MASK_FSUB_D 0xfe00007f +#define MATCH_FSUB_H 0xc000053 +#define MASK_FSUB_H 0xfe00007f +#define MATCH_FSUB_Q 0xe000053 +#define MASK_FSUB_Q 0xfe00007f +#define MATCH_FSUB_S 0x8000053 +#define MASK_FSUB_S 0xfe00007f +#define MATCH_FSW 0x2027 +#define MASK_FSW 0x707f +#define MATCH_GORC 0x28005033 +#define MASK_GORC 0xfe00707f +#define MATCH_GORCI 0x28005013 +#define MASK_GORCI 0xfc00707f +#define MATCH_GORCIW 0x2800501b +#define MASK_GORCIW 0xfe00707f +#define MATCH_GORCW 0x2800503b +#define MASK_GORCW 0xfe00707f +#define MATCH_GREV 0x68005033 +#define MASK_GREV 0xfe00707f +#define MATCH_GREVI 0x68005013 +#define MASK_GREVI 0xfc00707f +#define MATCH_GREVIW 0x6800501b +#define MASK_GREVIW 0xfe00707f +#define MATCH_GREVW 0x6800503b +#define MASK_GREVW 0xfe00707f +#define MATCH_HFENCE_GVMA 0x62000073 +#define MASK_HFENCE_GVMA 0xfe007fff +#define MATCH_HFENCE_VVMA 0x22000073 +#define MASK_HFENCE_VVMA 0xfe007fff +#define MATCH_HINVAL_GVMA 0x66000073 +#define MASK_HINVAL_GVMA 0xfe007fff +#define MATCH_HINVAL_VVMA 0x26000073 +#define MASK_HINVAL_VVMA 0xfe007fff +#define MATCH_HLV_B 0x60004073 +#define MASK_HLV_B 0xfff0707f +#define MATCH_HLV_BU 0x60104073 +#define MASK_HLV_BU 0xfff0707f +#define MATCH_HLV_D 0x6c004073 +#define MASK_HLV_D 0xfff0707f +#define MATCH_HLV_H 0x64004073 +#define MASK_HLV_H 0xfff0707f +#define MATCH_HLV_HU 0x64104073 +#define MASK_HLV_HU 0xfff0707f +#define MATCH_HLV_W 0x68004073 +#define MASK_HLV_W 0xfff0707f +#define MATCH_HLV_WU 0x68104073 +#define MASK_HLV_WU 0xfff0707f +#define MATCH_HLVX_HU 0x64304073 +#define MASK_HLVX_HU 0xfff0707f +#define MATCH_HLVX_WU 0x68304073 +#define MASK_HLVX_WU 0xfff0707f +#define MATCH_HSV_B 0x62004073 +#define MASK_HSV_B 0xfe007fff +#define MATCH_HSV_D 0x6e004073 +#define MASK_HSV_D 0xfe007fff +#define MATCH_HSV_H 0x66004073 +#define MASK_HSV_H 0xfe007fff +#define MATCH_HSV_W 0x6a004073 +#define MASK_HSV_W 0xfe007fff +#define MATCH_INSB 0xac000077 +#define MASK_INSB 0xff80707f +#define MATCH_JAL 0x6f +#define MASK_JAL 0x7f +#define MATCH_JALR 0x67 +#define MASK_JALR 0x707f +#define MATCH_KABS16 0xad100077 +#define MASK_KABS16 0xfff0707f #define MATCH_KABS32 0xad200077 -#define MASK_KABS32 0xfff0707f +#define MASK_KABS32 0xfff0707f +#define MATCH_KABS8 0xad000077 +#define MASK_KABS8 0xfff0707f +#define MATCH_KABSW 0xad400077 +#define MASK_KABSW 0xfff0707f +#define MATCH_KADD16 0x10000077 +#define MASK_KADD16 0xfe00707f #define MATCH_KADD32 0x10002077 -#define MASK_KADD32 0xfe00707f +#define MASK_KADD32 0xfe00707f +#define MATCH_KADD64 0x90001077 +#define MASK_KADD64 0xfe00707f +#define MATCH_KADD8 0x18000077 +#define MASK_KADD8 0xfe00707f +#define MATCH_KADDH 0x4001077 +#define MASK_KADDH 0xfe00707f +#define MATCH_KADDW 0x1077 +#define MASK_KADDW 0xfe00707f +#define MATCH_KCRAS16 0x14000077 +#define MASK_KCRAS16 0xfe00707f #define MATCH_KCRAS32 0x14002077 -#define MASK_KCRAS32 0xfe00707f +#define MASK_KCRAS32 0xfe00707f +#define MATCH_KCRSA16 0x16000077 +#define MASK_KCRSA16 0xfe00707f #define MATCH_KCRSA32 0x16002077 -#define MASK_KCRSA32 0xfe00707f -#define MATCH_KDMBB16 0xda001077 -#define MASK_KDMBB16 0xfe00707f -#define MATCH_KDMBT16 0xea001077 -#define MASK_KDMBT16 0xfe00707f -#define MATCH_KDMTT16 0xfa001077 -#define MASK_KDMTT16 0xfe00707f +#define MASK_KCRSA32 0xfe00707f +#define MATCH_KDMABB 0xd2001077 +#define MASK_KDMABB 0xfe00707f #define MATCH_KDMABB16 0xd8001077 -#define MASK_KDMABB16 0xfe00707f +#define MASK_KDMABB16 0xfe00707f +#define MATCH_KDMABT 0xe2001077 +#define MASK_KDMABT 0xfe00707f #define MATCH_KDMABT16 0xe8001077 -#define MASK_KDMABT16 0xfe00707f +#define MASK_KDMABT16 0xfe00707f +#define MATCH_KDMATT 0xf2001077 +#define MASK_KDMATT 0xfe00707f #define MATCH_KDMATT16 0xf8001077 -#define MASK_KDMATT16 0xfe00707f +#define MASK_KDMATT16 0xfe00707f +#define MATCH_KDMBB 0xa001077 +#define MASK_KDMBB 0xfe00707f +#define MATCH_KDMBB16 0xda001077 +#define MASK_KDMBB16 0xfe00707f +#define MATCH_KDMBT 0x1a001077 +#define MASK_KDMBT 0xfe00707f +#define MATCH_KDMBT16 0xea001077 +#define MASK_KDMBT16 0xfe00707f +#define MATCH_KDMTT 0x2a001077 +#define MASK_KDMTT 0xfe00707f +#define MATCH_KDMTT16 0xfa001077 +#define MASK_KDMTT16 0xfe00707f +#define MATCH_KHM16 0x86000077 +#define MASK_KHM16 0xfe00707f +#define MATCH_KHM8 0x8e000077 +#define MASK_KHM8 0xfe00707f +#define MATCH_KHMBB 0xc001077 +#define MASK_KHMBB 0xfe00707f #define MATCH_KHMBB16 0xdc001077 -#define MASK_KHMBB16 0xfe00707f +#define MASK_KHMBB16 0xfe00707f +#define MATCH_KHMBT 0x1c001077 +#define MASK_KHMBT 0xfe00707f #define MATCH_KHMBT16 0xec001077 -#define MASK_KHMBT16 0xfe00707f +#define MASK_KHMBT16 0xfe00707f +#define MATCH_KHMTT 0x2c001077 +#define MASK_KHMTT 0xfe00707f #define MATCH_KHMTT16 0xfc001077 -#define MASK_KHMTT16 0xfe00707f +#define MASK_KHMTT16 0xfe00707f +#define MATCH_KHMX16 0x96000077 +#define MASK_KHMX16 0xfe00707f +#define MATCH_KHMX8 0x9e000077 +#define MASK_KHMX8 0xfe00707f +#define MATCH_KMABB 0x5a001077 +#define MASK_KMABB 0xfe00707f #define MATCH_KMABB32 0x5a002077 -#define MASK_KMABB32 0xfe00707f +#define MASK_KMABB32 0xfe00707f +#define MATCH_KMABT 0x6a001077 +#define MASK_KMABT 0xfe00707f #define MATCH_KMABT32 0x6a002077 -#define MASK_KMABT32 0xfe00707f -#define MATCH_KMATT32 0x7a002077 -#define MASK_KMATT32 0xfe00707f -#define MATCH_KMAXDA32 0x4a002077 -#define MASK_KMAXDA32 0xfe00707f -#define MATCH_KMDA32 0x38002077 -#define MASK_KMDA32 0xfe00707f -#define MATCH_KMXDA32 0x3a002077 -#define MASK_KMXDA32 0xfe00707f -#define MATCH_KMADS32 0x5c002077 -#define MASK_KMADS32 0xfe00707f +#define MASK_KMABT32 0xfe00707f +#define MATCH_KMADA 0x48001077 +#define MASK_KMADA 0xfe00707f +#define MATCH_KMADRS 0x6c001077 +#define MASK_KMADRS 0xfe00707f #define MATCH_KMADRS32 0x6c002077 -#define MASK_KMADRS32 0xfe00707f +#define MASK_KMADRS32 0xfe00707f +#define MATCH_KMADS 0x5c001077 +#define MASK_KMADS 0xfe00707f +#define MATCH_KMADS32 0x5c002077 +#define MASK_KMADS32 0xfe00707f +#define MATCH_KMAR64 0x94001077 +#define MASK_KMAR64 0xfe00707f +#define MATCH_KMATT 0x7a001077 +#define MASK_KMATT 0xfe00707f +#define MATCH_KMATT32 0x7a002077 +#define MASK_KMATT32 0xfe00707f +#define MATCH_KMAXDA 0x4a001077 +#define MASK_KMAXDA 0xfe00707f +#define MATCH_KMAXDA32 0x4a002077 +#define MASK_KMAXDA32 0xfe00707f +#define MATCH_KMAXDS 0x7c001077 +#define MASK_KMAXDS 0xfe00707f #define MATCH_KMAXDS32 0x7c002077 -#define MASK_KMAXDS32 0xfe00707f +#define MASK_KMAXDS32 0xfe00707f +#define MATCH_KMDA 0x38001077 +#define MASK_KMDA 0xfe00707f +#define MATCH_KMDA32 0x38002077 +#define MASK_KMDA32 0xfe00707f +#define MATCH_KMMAC 0x60001077 +#define MASK_KMMAC 0xfe00707f +#define MATCH_KMMAC_U 0x70001077 +#define MASK_KMMAC_U 0xfe00707f +#define MATCH_KMMAWB 0x46001077 +#define MASK_KMMAWB 0xfe00707f +#define MATCH_KMMAWB2 0xce001077 +#define MASK_KMMAWB2 0xfe00707f +#define MATCH_KMMAWB2_U 0xde001077 +#define MASK_KMMAWB2_U 0xfe00707f +#define MATCH_KMMAWB_U 0x56001077 +#define MASK_KMMAWB_U 0xfe00707f +#define MATCH_KMMAWT 0x66001077 +#define MASK_KMMAWT 0xfe00707f +#define MATCH_KMMAWT2 0xee001077 +#define MASK_KMMAWT2 0xfe00707f +#define MATCH_KMMAWT2_U 0xfe001077 +#define MASK_KMMAWT2_U 0xfe00707f +#define MATCH_KMMAWT_U 0x76001077 +#define MASK_KMMAWT_U 0xfe00707f +#define MATCH_KMMSB 0x42001077 +#define MASK_KMMSB 0xfe00707f +#define MATCH_KMMSB_U 0x52001077 +#define MASK_KMMSB_U 0xfe00707f +#define MATCH_KMMWB2 0x8e001077 +#define MASK_KMMWB2 0xfe00707f +#define MATCH_KMMWB2_U 0x9e001077 +#define MASK_KMMWB2_U 0xfe00707f +#define MATCH_KMMWT2 0xae001077 +#define MASK_KMMWT2 0xfe00707f +#define MATCH_KMMWT2_U 0xbe001077 +#define MASK_KMMWT2_U 0xfe00707f +#define MATCH_KMSDA 0x4c001077 +#define MASK_KMSDA 0xfe00707f #define MATCH_KMSDA32 0x4c002077 -#define MASK_KMSDA32 0xfe00707f +#define MASK_KMSDA32 0xfe00707f +#define MATCH_KMSR64 0x96001077 +#define MASK_KMSR64 0xfe00707f +#define MATCH_KMSXDA 0x4e001077 +#define MASK_KMSXDA 0xfe00707f #define MATCH_KMSXDA32 0x4e002077 -#define MASK_KMSXDA32 0xfe00707f +#define MASK_KMSXDA32 0xfe00707f +#define MATCH_KMXDA 0x3a001077 +#define MASK_KMXDA 0xfe00707f +#define MATCH_KMXDA32 0x3a002077 +#define MASK_KMXDA32 0xfe00707f +#define MATCH_KSLL16 0x64000077 +#define MASK_KSLL16 0xfe00707f #define MATCH_KSLL32 0x64002077 -#define MASK_KSLL32 0xfe00707f +#define MASK_KSLL32 0xfe00707f +#define MATCH_KSLL8 0x6c000077 +#define MASK_KSLL8 0xfe00707f +#define MATCH_KSLLI16 0x75000077 +#define MASK_KSLLI16 0xff00707f #define MATCH_KSLLI32 0x84002077 -#define MASK_KSLLI32 0xfe00707f +#define MASK_KSLLI32 0xfe00707f +#define MATCH_KSLLI8 0x7c800077 +#define MASK_KSLLI8 0xff80707f +#define MATCH_KSLLIW 0x36001077 +#define MASK_KSLLIW 0xfe00707f +#define MATCH_KSLLW 0x26001077 +#define MASK_KSLLW 0xfe00707f +#define MATCH_KSLRA16 0x56000077 +#define MASK_KSLRA16 0xfe00707f +#define MATCH_KSLRA16_U 0x66000077 +#define MASK_KSLRA16_U 0xfe00707f #define MATCH_KSLRA32 0x56002077 -#define MASK_KSLRA32 0xfe00707f +#define MASK_KSLRA32 0xfe00707f #define MATCH_KSLRA32_U 0x66002077 -#define MASK_KSLRA32_U 0xfe00707f +#define MASK_KSLRA32_U 0xfe00707f +#define MATCH_KSLRA8 0x5e000077 +#define MASK_KSLRA8 0xfe00707f +#define MATCH_KSLRA8_U 0x6e000077 +#define MASK_KSLRA8_U 0xfe00707f +#define MATCH_KSLRAW 0x6e001077 +#define MASK_KSLRAW 0xfe00707f +#define MATCH_KSLRAW_U 0x7e001077 +#define MASK_KSLRAW_U 0xfe00707f +#define MATCH_KSTAS16 0xc4002077 +#define MASK_KSTAS16 0xfe00707f #define MATCH_KSTAS32 0xc0002077 -#define MASK_KSTAS32 0xfe00707f +#define MASK_KSTAS32 0xfe00707f +#define MATCH_KSTSA16 0xc6002077 +#define MASK_KSTSA16 0xfe00707f #define MATCH_KSTSA32 0xc2002077 -#define MASK_KSTSA32 0xfe00707f +#define MASK_KSTSA32 0xfe00707f +#define MATCH_KSUB16 0x12000077 +#define MASK_KSUB16 0xfe00707f #define MATCH_KSUB32 0x12002077 -#define MASK_KSUB32 0xfe00707f -#define MATCH_PKBB32 0xe002077 -#define MASK_PKBB32 0xfe00707f +#define MASK_KSUB32 0xfe00707f +#define MATCH_KSUB64 0x92001077 +#define MASK_KSUB64 0xfe00707f +#define MATCH_KSUB8 0x1a000077 +#define MASK_KSUB8 0xfe00707f +#define MATCH_KSUBH 0x6001077 +#define MASK_KSUBH 0xfe00707f +#define MATCH_KSUBW 0x2001077 +#define MASK_KSUBW 0xfe00707f +#define MATCH_KWMMUL 0x62001077 +#define MASK_KWMMUL 0xfe00707f +#define MATCH_KWMMUL_U 0x72001077 +#define MASK_KWMMUL_U 0xfe00707f +#define MATCH_LB 0x3 +#define MASK_LB 0x707f +#define MATCH_LBU 0x4003 +#define MASK_LBU 0x707f +#define MATCH_LD 0x3003 +#define MASK_LD 0x707f +#define MATCH_LDU 0x7003 +#define MASK_LDU 0x707f +#define MATCH_LH 0x1003 +#define MASK_LH 0x707f +#define MATCH_LHU 0x5003 +#define MASK_LHU 0x707f +#define MATCH_LQ 0x300f +#define MASK_LQ 0x707f +#define MATCH_LR_D 0x1000302f +#define MASK_LR_D 0xf9f0707f +#define MATCH_LR_W 0x1000202f +#define MASK_LR_W 0xf9f0707f +#define MATCH_LUI 0x37 +#define MASK_LUI 0x7f +#define MATCH_LW 0x2003 +#define MASK_LW 0x707f +#define MATCH_LWU 0x6003 +#define MASK_LWU 0x707f +#define MATCH_MADDR32 0xc4001077 +#define MASK_MADDR32 0xfe00707f +#define MATCH_MAX 0xa006033 +#define MASK_MAX 0xfe00707f +#define MATCH_MAXU 0xa007033 +#define MASK_MAXU 0xfe00707f +#define MATCH_MIN 0xa004033 +#define MASK_MIN 0xfe00707f +#define MATCH_MINU 0xa005033 +#define MASK_MINU 0xfe00707f +#define MATCH_MNRET 0x70200073 +#define MASK_MNRET 0xffffffff +#define MATCH_MRET 0x30200073 +#define MASK_MRET 0xffffffff +#define MATCH_MSUBR32 0xc6001077 +#define MASK_MSUBR32 0xfe00707f +#define MATCH_MUL 0x2000033 +#define MASK_MUL 0xfe00707f +#define MATCH_MULH 0x2001033 +#define MASK_MULH 0xfe00707f +#define MATCH_MULHSU 0x2002033 +#define MASK_MULHSU 0xfe00707f +#define MATCH_MULHU 0x2003033 +#define MASK_MULHU 0xfe00707f +#define MATCH_MULR64 0xf0001077 +#define MASK_MULR64 0xfe00707f +#define MATCH_MULSR64 0xe0001077 +#define MASK_MULSR64 0xfe00707f +#define MATCH_MULW 0x200003b +#define MASK_MULW 0xfe00707f +#define MATCH_OR 0x6033 +#define MASK_OR 0xfe00707f +#define MATCH_ORI 0x6013 +#define MASK_ORI 0x707f +#define MATCH_ORN 0x40006033 +#define MASK_ORN 0xfe00707f +#define MATCH_PACK 0x8004033 +#define MASK_PACK 0xfe00707f +#define MATCH_PACKH 0x8007033 +#define MASK_PACKH 0xfe00707f +#define MATCH_PACKU 0x48004033 +#define MASK_PACKU 0xfe00707f +#define MATCH_PACKUW 0x4800403b +#define MASK_PACKUW 0xfe00707f +#define MATCH_PACKW 0x800403b +#define MASK_PACKW 0xfe00707f +#define MATCH_PAUSE 0x100000f +#define MASK_PAUSE 0xffffffff +#define MATCH_PBSAD 0xfc000077 +#define MASK_PBSAD 0xfe00707f +#define MATCH_PBSADA 0xfe000077 +#define MASK_PBSADA 0xfe00707f +#define MATCH_PKBB16 0xe001077 +#define MASK_PKBB16 0xfe00707f +#define MATCH_PKBT16 0x1e001077 +#define MASK_PKBT16 0xfe00707f #define MATCH_PKBT32 0x1e002077 -#define MASK_PKBT32 0xfe00707f -#define MATCH_PKTT32 0x2e002077 -#define MASK_PKTT32 0xfe00707f +#define MASK_PKBT32 0xfe00707f +#define MATCH_PKTB16 0x3e001077 +#define MASK_PKTB16 0xfe00707f #define MATCH_PKTB32 0x3e002077 -#define MASK_PKTB32 0xfe00707f +#define MASK_PKTB32 0xfe00707f +#define MATCH_PKTT16 0x2e001077 +#define MASK_PKTT16 0xfe00707f +#define MATCH_PREFETCH_I 0x6013 +#define MASK_PREFETCH_I 0x1f07fff +#define MATCH_PREFETCH_R 0x106013 +#define MASK_PREFETCH_R 0x1f07fff +#define MATCH_PREFETCH_W 0x306013 +#define MASK_PREFETCH_W 0x1f07fff +#define MATCH_RADD16 0x77 +#define MASK_RADD16 0xfe00707f #define MATCH_RADD32 0x2077 -#define MASK_RADD32 0xfe00707f +#define MASK_RADD32 0xfe00707f +#define MATCH_RADD64 0x80001077 +#define MASK_RADD64 0xfe00707f +#define MATCH_RADD8 0x8000077 +#define MASK_RADD8 0xfe00707f +#define MATCH_RADDW 0x20001077 +#define MASK_RADDW 0xfe00707f +#define MATCH_RCRAS16 0x4000077 +#define MASK_RCRAS16 0xfe00707f #define MATCH_RCRAS32 0x4002077 -#define MASK_RCRAS32 0xfe00707f +#define MASK_RCRAS32 0xfe00707f +#define MATCH_RCRSA16 0x6000077 +#define MASK_RCRSA16 0xfe00707f #define MATCH_RCRSA32 0x6002077 -#define MASK_RCRSA32 0xfe00707f +#define MASK_RCRSA32 0xfe00707f +#define MATCH_REM 0x2006033 +#define MASK_REM 0xfe00707f +#define MATCH_REMU 0x2007033 +#define MASK_REMU 0xfe00707f +#define MATCH_REMUW 0x200703b +#define MASK_REMUW 0xfe00707f +#define MATCH_REMW 0x200603b +#define MASK_REMW 0xfe00707f +#define MATCH_ROL 0x60001033 +#define MASK_ROL 0xfe00707f +#define MATCH_ROLW 0x6000103b +#define MASK_ROLW 0xfe00707f +#define MATCH_ROR 0x60005033 +#define MASK_ROR 0xfe00707f +#define MATCH_RORI 0x60005013 +#define MASK_RORI 0xfc00707f +#define MATCH_RORIW 0x6000501b +#define MASK_RORIW 0xfe00707f +#define MATCH_RORW 0x6000503b +#define MASK_RORW 0xfe00707f +#define MATCH_RSTAS16 0xb4002077 +#define MASK_RSTAS16 0xfe00707f #define MATCH_RSTAS32 0xb0002077 -#define MASK_RSTAS32 0xfe00707f +#define MASK_RSTAS32 0xfe00707f +#define MATCH_RSTSA16 0xb6002077 +#define MASK_RSTSA16 0xfe00707f #define MATCH_RSTSA32 0xb2002077 -#define MASK_RSTSA32 0xfe00707f +#define MASK_RSTSA32 0xfe00707f +#define MATCH_RSUB16 0x2000077 +#define MASK_RSUB16 0xfe00707f #define MATCH_RSUB32 0x2002077 -#define MASK_RSUB32 0xfe00707f +#define MASK_RSUB32 0xfe00707f +#define MATCH_RSUB64 0x82001077 +#define MASK_RSUB64 0xfe00707f +#define MATCH_RSUB8 0xa000077 +#define MASK_RSUB8 0xfe00707f +#define MATCH_RSUBW 0x22001077 +#define MASK_RSUBW 0xfe00707f +#define MATCH_SB 0x23 +#define MASK_SB 0x707f +#define MATCH_SC_D 0x1800302f +#define MASK_SC_D 0xf800707f +#define MATCH_SC_W 0x1800202f +#define MASK_SC_W 0xf800707f +#define MATCH_SCLIP16 0x84000077 +#define MASK_SCLIP16 0xff00707f +#define MATCH_SCLIP32 0xe4000077 +#define MASK_SCLIP32 0xfe00707f +#define MATCH_SCLIP8 0x8c000077 +#define MASK_SCLIP8 0xff80707f +#define MATCH_SCMPLE16 0x1c000077 +#define MASK_SCMPLE16 0xfe00707f +#define MATCH_SCMPLE8 0x1e000077 +#define MASK_SCMPLE8 0xfe00707f +#define MATCH_SCMPLT16 0xc000077 +#define MASK_SCMPLT16 0xfe00707f +#define MATCH_SCMPLT8 0xe000077 +#define MASK_SCMPLT8 0xfe00707f +#define MATCH_SD 0x3023 +#define MASK_SD 0x707f +#define MATCH_SEXT_B 0x60401013 +#define MASK_SEXT_B 0xfff0707f +#define MATCH_SEXT_H 0x60501013 +#define MASK_SEXT_H 0xfff0707f +#define MATCH_SFENCE_INVAL_IR 0x18100073 +#define MASK_SFENCE_INVAL_IR 0xffffffff +#define MATCH_SFENCE_VMA 0x12000073 +#define MASK_SFENCE_VMA 0xfe007fff +#define MATCH_SFENCE_W_INVAL 0x18000073 +#define MASK_SFENCE_W_INVAL 0xffffffff +#define MATCH_SH 0x1023 +#define MASK_SH 0x707f +#define MATCH_SH1ADD 0x20002033 +#define MASK_SH1ADD 0xfe00707f +#define MATCH_SH1ADD_UW 0x2000203b +#define MASK_SH1ADD_UW 0xfe00707f +#define MATCH_SH2ADD 0x20004033 +#define MASK_SH2ADD 0xfe00707f +#define MATCH_SH2ADD_UW 0x2000403b +#define MASK_SH2ADD_UW 0xfe00707f +#define MATCH_SH3ADD 0x20006033 +#define MASK_SH3ADD 0xfe00707f +#define MATCH_SH3ADD_UW 0x2000603b +#define MASK_SH3ADD_UW 0xfe00707f +#define MATCH_SHA256SIG0 0x10201013 +#define MASK_SHA256SIG0 0xfff0707f +#define MATCH_SHA256SIG1 0x10301013 +#define MASK_SHA256SIG1 0xfff0707f +#define MATCH_SHA256SUM0 0x10001013 +#define MASK_SHA256SUM0 0xfff0707f +#define MATCH_SHA256SUM1 0x10101013 +#define MASK_SHA256SUM1 0xfff0707f +#define MATCH_SHA512SIG0 0x10601013 +#define MASK_SHA512SIG0 0xfff0707f +#define MATCH_SHA512SIG0H 0x5c000033 +#define MASK_SHA512SIG0H 0xfe00707f +#define MATCH_SHA512SIG0L 0x54000033 +#define MASK_SHA512SIG0L 0xfe00707f +#define MATCH_SHA512SIG1 0x10701013 +#define MASK_SHA512SIG1 0xfff0707f +#define MATCH_SHA512SIG1H 0x5e000033 +#define MASK_SHA512SIG1H 0xfe00707f +#define MATCH_SHA512SIG1L 0x56000033 +#define MASK_SHA512SIG1L 0xfe00707f +#define MATCH_SHA512SUM0 0x10401013 +#define MASK_SHA512SUM0 0xfff0707f +#define MATCH_SHA512SUM0R 0x50000033 +#define MASK_SHA512SUM0R 0xfe00707f +#define MATCH_SHA512SUM1 0x10501013 +#define MASK_SHA512SUM1 0xfff0707f +#define MATCH_SHA512SUM1R 0x52000033 +#define MASK_SHA512SUM1R 0xfe00707f +#define MATCH_SHFL 0x8001033 +#define MASK_SHFL 0xfe00707f +#define MATCH_SHFLI 0x8001013 +#define MASK_SHFLI 0xfe00707f +#define MATCH_SHFLW 0x800103b +#define MASK_SHFLW 0xfe00707f +#define MATCH_SINVAL_VMA 0x16000073 +#define MASK_SINVAL_VMA 0xfe007fff +#define MATCH_SLL 0x1033 +#define MASK_SLL 0xfe00707f +#define MATCH_SLL16 0x54000077 +#define MASK_SLL16 0xfe00707f #define MATCH_SLL32 0x54002077 -#define MASK_SLL32 0xfe00707f +#define MASK_SLL32 0xfe00707f +#define MATCH_SLL8 0x5c000077 +#define MASK_SLL8 0xfe00707f +#define MATCH_SLLD 0x107b +#define MASK_SLLD 0xfe00707f +#define MATCH_SLLI 0x1013 +#define MASK_SLLI 0xfc00707f +#define MATCH_SLLI16 0x74000077 +#define MASK_SLLI16 0xff00707f #define MATCH_SLLI32 0x74002077 -#define MASK_SLLI32 0xfe00707f +#define MASK_SLLI32 0xfe00707f +#define MATCH_SLLI8 0x7c000077 +#define MASK_SLLI8 0xff80707f +#define MATCH_SLLI_RV128 0x1013 +#define MASK_SLLI_RV128 0xf800707f +#define MATCH_SLLI_RV32 0x1013 +#define MASK_SLLI_RV32 0xfe00707f +#define MATCH_SLLI_UW 0x800101b +#define MASK_SLLI_UW 0xfc00707f +#define MATCH_SLLID 0x105b +#define MASK_SLLID 0xfc00707f +#define MATCH_SLLIW 0x101b +#define MASK_SLLIW 0xfe00707f +#define MATCH_SLLW 0x103b +#define MASK_SLLW 0xfe00707f +#define MATCH_SLO 0x20001033 +#define MASK_SLO 0xfe00707f +#define MATCH_SLOI 0x20001013 +#define MASK_SLOI 0xfc00707f +#define MATCH_SLOIW 0x2000101b +#define MASK_SLOIW 0xfe00707f +#define MATCH_SLOW 0x2000103b +#define MASK_SLOW 0xfe00707f +#define MATCH_SLT 0x2033 +#define MASK_SLT 0xfe00707f +#define MATCH_SLTI 0x2013 +#define MASK_SLTI 0x707f +#define MATCH_SLTIU 0x3013 +#define MASK_SLTIU 0x707f +#define MATCH_SLTU 0x3033 +#define MASK_SLTU 0xfe00707f +#define MATCH_SM3P0 0x10801013 +#define MASK_SM3P0 0xfff0707f +#define MATCH_SM3P1 0x10901013 +#define MASK_SM3P1 0xfff0707f +#define MATCH_SM4ED 0x30000033 +#define MASK_SM4ED 0x3e00707f +#define MATCH_SM4KS 0x34000033 +#define MASK_SM4KS 0x3e00707f +#define MATCH_SMAL 0x5e001077 +#define MASK_SMAL 0xfe00707f +#define MATCH_SMALBB 0x88001077 +#define MASK_SMALBB 0xfe00707f +#define MATCH_SMALBT 0x98001077 +#define MASK_SMALBT 0xfe00707f +#define MATCH_SMALDA 0x8c001077 +#define MASK_SMALDA 0xfe00707f +#define MATCH_SMALDRS 0x9a001077 +#define MASK_SMALDRS 0xfe00707f +#define MATCH_SMALDS 0x8a001077 +#define MASK_SMALDS 0xfe00707f +#define MATCH_SMALTT 0xa8001077 +#define MASK_SMALTT 0xfe00707f +#define MATCH_SMALXDA 0x9c001077 +#define MASK_SMALXDA 0xfe00707f +#define MATCH_SMALXDS 0xaa001077 +#define MASK_SMALXDS 0xfe00707f +#define MATCH_SMAQA 0xc8000077 +#define MASK_SMAQA 0xfe00707f +#define MATCH_SMAQA_SU 0xca000077 +#define MASK_SMAQA_SU 0xfe00707f +#define MATCH_SMAR64 0x84001077 +#define MASK_SMAR64 0xfe00707f +#define MATCH_SMAX16 0x82000077 +#define MASK_SMAX16 0xfe00707f #define MATCH_SMAX32 0x92002077 -#define MASK_SMAX32 0xfe00707f +#define MASK_SMAX32 0xfe00707f +#define MATCH_SMAX8 0x8a000077 +#define MASK_SMAX8 0xfe00707f +#define MATCH_SMBB16 0x8001077 +#define MASK_SMBB16 0xfe00707f +#define MATCH_SMBT16 0x18001077 +#define MASK_SMBT16 0xfe00707f #define MATCH_SMBT32 0x18002077 -#define MASK_SMBT32 0xfe00707f -#define MATCH_SMTT32 0x28002077 -#define MASK_SMTT32 0xfe00707f -#define MATCH_SMDS32 0x58002077 -#define MASK_SMDS32 0xfe00707f +#define MASK_SMBT32 0xfe00707f +#define MATCH_SMDRS 0x68001077 +#define MASK_SMDRS 0xfe00707f #define MATCH_SMDRS32 0x68002077 -#define MASK_SMDRS32 0xfe00707f -#define MATCH_SMXDS32 0x78002077 -#define MASK_SMXDS32 0xfe00707f +#define MASK_SMDRS32 0xfe00707f +#define MATCH_SMDS 0x58001077 +#define MASK_SMDS 0xfe00707f +#define MATCH_SMDS32 0x58002077 +#define MASK_SMDS32 0xfe00707f +#define MATCH_SMIN16 0x80000077 +#define MASK_SMIN16 0xfe00707f #define MATCH_SMIN32 0x90002077 -#define MASK_SMIN32 0xfe00707f +#define MASK_SMIN32 0xfe00707f +#define MATCH_SMIN8 0x88000077 +#define MASK_SMIN8 0xfe00707f +#define MATCH_SMMUL 0x40001077 +#define MASK_SMMUL 0xfe00707f +#define MATCH_SMMUL_U 0x50001077 +#define MASK_SMMUL_U 0xfe00707f +#define MATCH_SMMWB 0x44001077 +#define MASK_SMMWB 0xfe00707f +#define MATCH_SMMWB_U 0x54001077 +#define MASK_SMMWB_U 0xfe00707f +#define MATCH_SMMWT 0x64001077 +#define MASK_SMMWT 0xfe00707f +#define MATCH_SMMWT_U 0x74001077 +#define MASK_SMMWT_U 0xfe00707f +#define MATCH_SMSLDA 0xac001077 +#define MASK_SMSLDA 0xfe00707f +#define MATCH_SMSLXDA 0xbc001077 +#define MASK_SMSLXDA 0xfe00707f +#define MATCH_SMSR64 0x86001077 +#define MASK_SMSR64 0xfe00707f +#define MATCH_SMTT16 0x28001077 +#define MASK_SMTT16 0xfe00707f +#define MATCH_SMTT32 0x28002077 +#define MASK_SMTT32 0xfe00707f +#define MATCH_SMUL16 0xa0000077 +#define MASK_SMUL16 0xfe00707f +#define MATCH_SMUL8 0xa8000077 +#define MASK_SMUL8 0xfe00707f +#define MATCH_SMULX16 0xa2000077 +#define MASK_SMULX16 0xfe00707f +#define MATCH_SMULX8 0xaa000077 +#define MASK_SMULX8 0xfe00707f +#define MATCH_SMXDS 0x78001077 +#define MASK_SMXDS 0xfe00707f +#define MATCH_SMXDS32 0x78002077 +#define MASK_SMXDS32 0xfe00707f +#define MATCH_SQ 0x4023 +#define MASK_SQ 0x707f +#define MATCH_SRA 0x40005033 +#define MASK_SRA 0xfe00707f +#define MATCH_SRA16 0x50000077 +#define MASK_SRA16 0xfe00707f +#define MATCH_SRA16_U 0x60000077 +#define MASK_SRA16_U 0xfe00707f #define MATCH_SRA32 0x50002077 -#define MASK_SRA32 0xfe00707f +#define MASK_SRA32 0xfe00707f #define MATCH_SRA32_U 0x60002077 -#define MASK_SRA32_U 0xfe00707f +#define MASK_SRA32_U 0xfe00707f +#define MATCH_SRA8 0x58000077 +#define MASK_SRA8 0xfe00707f +#define MATCH_SRA8_U 0x68000077 +#define MASK_SRA8_U 0xfe00707f +#define MATCH_SRA_U 0x24001077 +#define MASK_SRA_U 0xfe00707f +#define MATCH_SRAD 0x4000507b +#define MASK_SRAD 0xfe00707f +#define MATCH_SRAI 0x40005013 +#define MASK_SRAI 0xfc00707f +#define MATCH_SRAI16 0x70000077 +#define MASK_SRAI16 0xff00707f +#define MATCH_SRAI16_U 0x71000077 +#define MASK_SRAI16_U 0xff00707f #define MATCH_SRAI32 0x70002077 -#define MASK_SRAI32 0xfe00707f +#define MASK_SRAI32 0xfe00707f #define MATCH_SRAI32_U 0x80002077 -#define MASK_SRAI32_U 0xfe00707f +#define MASK_SRAI32_U 0xfe00707f +#define MATCH_SRAI8 0x78000077 +#define MASK_SRAI8 0xff80707f +#define MATCH_SRAI8_U 0x78800077 +#define MASK_SRAI8_U 0xff80707f +#define MATCH_SRAI_RV128 0x40005013 +#define MASK_SRAI_RV128 0xf800707f +#define MATCH_SRAI_RV32 0x40005013 +#define MASK_SRAI_RV32 0xfe00707f +#define MATCH_SRAI_U 0xd4001077 +#define MASK_SRAI_U 0xfc00707f +#define MATCH_SRAID 0x4000505b +#define MASK_SRAID 0xfc00707f +#define MATCH_SRAIW 0x4000501b +#define MASK_SRAIW 0xfe00707f #define MATCH_SRAIW_U 0x34001077 -#define MASK_SRAIW_U 0xfe00707f +#define MASK_SRAIW_U 0xfe00707f +#define MATCH_SRAW 0x4000503b +#define MASK_SRAW 0xfe00707f +#define MATCH_SRET 0x10200073 +#define MASK_SRET 0xffffffff +#define MATCH_SRL 0x5033 +#define MASK_SRL 0xfe00707f +#define MATCH_SRL16 0x52000077 +#define MASK_SRL16 0xfe00707f +#define MATCH_SRL16_U 0x62000077 +#define MASK_SRL16_U 0xfe00707f #define MATCH_SRL32 0x52002077 -#define MASK_SRL32 0xfe00707f +#define MASK_SRL32 0xfe00707f #define MATCH_SRL32_U 0x62002077 -#define MASK_SRL32_U 0xfe00707f +#define MASK_SRL32_U 0xfe00707f +#define MATCH_SRL8 0x5a000077 +#define MASK_SRL8 0xfe00707f +#define MATCH_SRL8_U 0x6a000077 +#define MASK_SRL8_U 0xfe00707f +#define MATCH_SRLD 0x507b +#define MASK_SRLD 0xfe00707f +#define MATCH_SRLI 0x5013 +#define MASK_SRLI 0xfc00707f +#define MATCH_SRLI16 0x72000077 +#define MASK_SRLI16 0xff00707f +#define MATCH_SRLI16_U 0x73000077 +#define MASK_SRLI16_U 0xff00707f #define MATCH_SRLI32 0x72002077 -#define MASK_SRLI32 0xfe00707f +#define MASK_SRLI32 0xfe00707f #define MATCH_SRLI32_U 0x82002077 -#define MASK_SRLI32_U 0xfe00707f +#define MASK_SRLI32_U 0xfe00707f +#define MATCH_SRLI8 0x7a000077 +#define MASK_SRLI8 0xff80707f +#define MATCH_SRLI8_U 0x7a800077 +#define MASK_SRLI8_U 0xff80707f +#define MATCH_SRLI_RV128 0x5013 +#define MASK_SRLI_RV128 0xf800707f +#define MATCH_SRLI_RV32 0x5013 +#define MASK_SRLI_RV32 0xfe00707f +#define MATCH_SRLID 0x505b +#define MASK_SRLID 0xfc00707f +#define MATCH_SRLIW 0x501b +#define MASK_SRLIW 0xfe00707f +#define MATCH_SRLW 0x503b +#define MASK_SRLW 0xfe00707f +#define MATCH_SRO 0x20005033 +#define MASK_SRO 0xfe00707f +#define MATCH_SROI 0x20005013 +#define MASK_SROI 0xfc00707f +#define MATCH_SROIW 0x2000501b +#define MASK_SROIW 0xfe00707f +#define MATCH_SROW 0x2000503b +#define MASK_SROW 0xfe00707f +#define MATCH_STAS16 0xf4002077 +#define MASK_STAS16 0xfe00707f #define MATCH_STAS32 0xf0002077 -#define MASK_STAS32 0xfe00707f +#define MASK_STAS32 0xfe00707f +#define MATCH_STSA16 0xf6002077 +#define MASK_STSA16 0xfe00707f #define MATCH_STSA32 0xf2002077 -#define MASK_STSA32 0xfe00707f +#define MASK_STSA32 0xfe00707f +#define MATCH_SUB 0x40000033 +#define MASK_SUB 0xfe00707f +#define MATCH_SUB16 0x42000077 +#define MASK_SUB16 0xfe00707f #define MATCH_SUB32 0x42002077 -#define MASK_SUB32 0xfe00707f +#define MASK_SUB32 0xfe00707f +#define MATCH_SUB64 0xc2001077 +#define MASK_SUB64 0xfe00707f +#define MATCH_SUB8 0x4a000077 +#define MASK_SUB8 0xfe00707f +#define MATCH_SUBD 0x4000007b +#define MASK_SUBD 0xfe00707f +#define MATCH_SUBW 0x4000003b +#define MASK_SUBW 0xfe00707f +#define MATCH_SUNPKD810 0xac800077 +#define MASK_SUNPKD810 0xfff0707f +#define MATCH_SUNPKD820 0xac900077 +#define MASK_SUNPKD820 0xfff0707f +#define MATCH_SUNPKD830 0xaca00077 +#define MASK_SUNPKD830 0xfff0707f +#define MATCH_SUNPKD831 0xacb00077 +#define MASK_SUNPKD831 0xfff0707f +#define MATCH_SUNPKD832 0xad300077 +#define MASK_SUNPKD832 0xfff0707f +#define MATCH_SW 0x2023 +#define MASK_SW 0x707f +#define MATCH_UCLIP16 0x85000077 +#define MASK_UCLIP16 0xff00707f +#define MATCH_UCLIP32 0xf4000077 +#define MASK_UCLIP32 0xfe00707f +#define MATCH_UCLIP8 0x8d000077 +#define MASK_UCLIP8 0xff80707f +#define MATCH_UCMPLE16 0x3c000077 +#define MASK_UCMPLE16 0xfe00707f +#define MATCH_UCMPLE8 0x3e000077 +#define MASK_UCMPLE8 0xfe00707f +#define MATCH_UCMPLT16 0x2c000077 +#define MASK_UCMPLT16 0xfe00707f +#define MATCH_UCMPLT8 0x2e000077 +#define MASK_UCMPLT8 0xfe00707f +#define MATCH_UKADD16 0x30000077 +#define MASK_UKADD16 0xfe00707f #define MATCH_UKADD32 0x30002077 -#define MASK_UKADD32 0xfe00707f +#define MASK_UKADD32 0xfe00707f +#define MATCH_UKADD64 0xb0001077 +#define MASK_UKADD64 0xfe00707f +#define MATCH_UKADD8 0x38000077 +#define MASK_UKADD8 0xfe00707f +#define MATCH_UKADDH 0x14001077 +#define MASK_UKADDH 0xfe00707f +#define MATCH_UKADDW 0x10001077 +#define MASK_UKADDW 0xfe00707f +#define MATCH_UKCRAS16 0x34000077 +#define MASK_UKCRAS16 0xfe00707f #define MATCH_UKCRAS32 0x34002077 -#define MASK_UKCRAS32 0xfe00707f +#define MASK_UKCRAS32 0xfe00707f +#define MATCH_UKCRSA16 0x36000077 +#define MASK_UKCRSA16 0xfe00707f #define MATCH_UKCRSA32 0x36002077 -#define MASK_UKCRSA32 0xfe00707f +#define MASK_UKCRSA32 0xfe00707f +#define MATCH_UKMAR64 0xb4001077 +#define MASK_UKMAR64 0xfe00707f +#define MATCH_UKMSR64 0xb6001077 +#define MASK_UKMSR64 0xfe00707f +#define MATCH_UKSTAS16 0xe4002077 +#define MASK_UKSTAS16 0xfe00707f #define MATCH_UKSTAS32 0xe0002077 -#define MASK_UKSTAS32 0xfe00707f +#define MASK_UKSTAS32 0xfe00707f +#define MATCH_UKSTSA16 0xe6002077 +#define MASK_UKSTSA16 0xfe00707f #define MATCH_UKSTSA32 0xe2002077 -#define MASK_UKSTSA32 0xfe00707f +#define MASK_UKSTSA32 0xfe00707f +#define MATCH_UKSUB16 0x32000077 +#define MASK_UKSUB16 0xfe00707f #define MATCH_UKSUB32 0x32002077 -#define MASK_UKSUB32 0xfe00707f +#define MASK_UKSUB32 0xfe00707f +#define MATCH_UKSUB64 0xb2001077 +#define MASK_UKSUB64 0xfe00707f +#define MATCH_UKSUB8 0x3a000077 +#define MASK_UKSUB8 0xfe00707f +#define MATCH_UKSUBH 0x16001077 +#define MASK_UKSUBH 0xfe00707f +#define MATCH_UKSUBW 0x12001077 +#define MASK_UKSUBW 0xfe00707f +#define MATCH_UMAQA 0xcc000077 +#define MASK_UMAQA 0xfe00707f +#define MATCH_UMAR64 0xa4001077 +#define MASK_UMAR64 0xfe00707f +#define MATCH_UMAX16 0x92000077 +#define MASK_UMAX16 0xfe00707f #define MATCH_UMAX32 0xa2002077 -#define MASK_UMAX32 0xfe00707f +#define MASK_UMAX32 0xfe00707f +#define MATCH_UMAX8 0x9a000077 +#define MASK_UMAX8 0xfe00707f +#define MATCH_UMIN16 0x90000077 +#define MASK_UMIN16 0xfe00707f #define MATCH_UMIN32 0xa0002077 -#define MASK_UMIN32 0xfe00707f +#define MASK_UMIN32 0xfe00707f +#define MATCH_UMIN8 0x98000077 +#define MASK_UMIN8 0xfe00707f +#define MATCH_UMSR64 0xa6001077 +#define MASK_UMSR64 0xfe00707f +#define MATCH_UMUL16 0xb0000077 +#define MASK_UMUL16 0xfe00707f +#define MATCH_UMUL8 0xb8000077 +#define MASK_UMUL8 0xfe00707f +#define MATCH_UMULX16 0xb2000077 +#define MASK_UMULX16 0xfe00707f +#define MATCH_UMULX8 0xba000077 +#define MASK_UMULX8 0xfe00707f +#define MATCH_UNSHFL 0x8005033 +#define MASK_UNSHFL 0xfe00707f +#define MATCH_UNSHFLI 0x8005013 +#define MASK_UNSHFLI 0xfe00707f +#define MATCH_UNSHFLW 0x800503b +#define MASK_UNSHFLW 0xfe00707f +#define MATCH_URADD16 0x20000077 +#define MASK_URADD16 0xfe00707f #define MATCH_URADD32 0x20002077 -#define MASK_URADD32 0xfe00707f +#define MASK_URADD32 0xfe00707f +#define MATCH_URADD64 0xa0001077 +#define MASK_URADD64 0xfe00707f +#define MATCH_URADD8 0x28000077 +#define MASK_URADD8 0xfe00707f +#define MATCH_URADDW 0x30001077 +#define MASK_URADDW 0xfe00707f +#define MATCH_URCRAS16 0x24000077 +#define MASK_URCRAS16 0xfe00707f #define MATCH_URCRAS32 0x24002077 -#define MASK_URCRAS32 0xfe00707f +#define MASK_URCRAS32 0xfe00707f +#define MATCH_URCRSA16 0x26000077 +#define MASK_URCRSA16 0xfe00707f #define MATCH_URCRSA32 0x26002077 -#define MASK_URCRSA32 0xfe00707f +#define MASK_URCRSA32 0xfe00707f +#define MATCH_URSTAS16 0xd4002077 +#define MASK_URSTAS16 0xfe00707f #define MATCH_URSTAS32 0xd0002077 -#define MASK_URSTAS32 0xfe00707f +#define MASK_URSTAS32 0xfe00707f +#define MATCH_URSTSA16 0xd6002077 +#define MASK_URSTSA16 0xfe00707f #define MATCH_URSTSA32 0xd2002077 -#define MASK_URSTSA32 0xfe00707f +#define MASK_URSTSA32 0xfe00707f +#define MATCH_URSUB16 0x22000077 +#define MASK_URSUB16 0xfe00707f #define MATCH_URSUB32 0x22002077 -#define MASK_URSUB32 0xfe00707f -#define MATCH_VMVNFR_V 0x9e003057 -#define MASK_VMVNFR_V 0xfe00707f -#define MATCH_VL1R_V 0x2800007 -#define MASK_VL1R_V 0xfff0707f -#define MATCH_VL2R_V 0x6805007 -#define MASK_VL2R_V 0xfff0707f -#define MATCH_VL4R_V 0xe806007 -#define MASK_VL4R_V 0xfff0707f -#define MATCH_VL8R_V 0x1e807007 -#define MASK_VL8R_V 0xfff0707f -#define MATCH_VLE1_V 0x2b00007 -#define MASK_VLE1_V 0xfff0707f -#define MATCH_VSE1_V 0x2b00027 -#define MASK_VSE1_V 0xfff0707f -#define MATCH_VFREDSUM_VS 0x4001057 -#define MASK_VFREDSUM_VS 0xfc00707f -#define MATCH_VFWREDSUM_VS 0xc4001057 -#define MASK_VFWREDSUM_VS 0xfc00707f -#define MATCH_VPOPC_M 0x40082057 -#define MASK_VPOPC_M 0xfc0ff07f +#define MASK_URSUB32 0xfe00707f +#define MATCH_URSUB64 0xa2001077 +#define MASK_URSUB64 0xfe00707f +#define MATCH_URSUB8 0x2a000077 +#define MASK_URSUB8 0xfe00707f +#define MATCH_URSUBW 0x32001077 +#define MASK_URSUBW 0xfe00707f +#define MATCH_VAADD_VV 0x24002057 +#define MASK_VAADD_VV 0xfc00707f +#define MATCH_VAADD_VX 0x24006057 +#define MASK_VAADD_VX 0xfc00707f +#define MATCH_VAADDU_VV 0x20002057 +#define MASK_VAADDU_VV 0xfc00707f +#define MATCH_VAADDU_VX 0x20006057 +#define MASK_VAADDU_VX 0xfc00707f +#define MATCH_VADC_VIM 0x40003057 +#define MASK_VADC_VIM 0xfe00707f +#define MATCH_VADC_VVM 0x40000057 +#define MASK_VADC_VVM 0xfe00707f +#define MATCH_VADC_VXM 0x40004057 +#define MASK_VADC_VXM 0xfe00707f +#define MATCH_VADD_VI 0x3057 +#define MASK_VADD_VI 0xfc00707f +#define MATCH_VADD_VV 0x57 +#define MASK_VADD_VV 0xfc00707f +#define MATCH_VADD_VX 0x4057 +#define MASK_VADD_VX 0xfc00707f +#define MATCH_VAMOADDEI16_V 0x502f +#define MASK_VAMOADDEI16_V 0xf800707f +#define MATCH_VAMOADDEI32_V 0x602f +#define MASK_VAMOADDEI32_V 0xf800707f +#define MATCH_VAMOADDEI64_V 0x702f +#define MASK_VAMOADDEI64_V 0xf800707f +#define MATCH_VAMOADDEI8_V 0x2f +#define MASK_VAMOADDEI8_V 0xf800707f +#define MATCH_VAMOANDEI16_V 0x6000502f +#define MASK_VAMOANDEI16_V 0xf800707f +#define MATCH_VAMOANDEI32_V 0x6000602f +#define MASK_VAMOANDEI32_V 0xf800707f +#define MATCH_VAMOANDEI64_V 0x6000702f +#define MASK_VAMOANDEI64_V 0xf800707f +#define MATCH_VAMOANDEI8_V 0x6000002f +#define MASK_VAMOANDEI8_V 0xf800707f +#define MATCH_VAMOMAXEI16_V 0xa000502f +#define MASK_VAMOMAXEI16_V 0xf800707f +#define MATCH_VAMOMAXEI32_V 0xa000602f +#define MASK_VAMOMAXEI32_V 0xf800707f +#define MATCH_VAMOMAXEI64_V 0xa000702f +#define MASK_VAMOMAXEI64_V 0xf800707f +#define MATCH_VAMOMAXEI8_V 0xa000002f +#define MASK_VAMOMAXEI8_V 0xf800707f +#define MATCH_VAMOMAXUEI16_V 0xe000502f +#define MASK_VAMOMAXUEI16_V 0xf800707f +#define MATCH_VAMOMAXUEI32_V 0xe000602f +#define MASK_VAMOMAXUEI32_V 0xf800707f +#define MATCH_VAMOMAXUEI64_V 0xe000702f +#define MASK_VAMOMAXUEI64_V 0xf800707f +#define MATCH_VAMOMAXUEI8_V 0xe000002f +#define MASK_VAMOMAXUEI8_V 0xf800707f +#define MATCH_VAMOMINEI16_V 0x8000502f +#define MASK_VAMOMINEI16_V 0xf800707f +#define MATCH_VAMOMINEI32_V 0x8000602f +#define MASK_VAMOMINEI32_V 0xf800707f +#define MATCH_VAMOMINEI64_V 0x8000702f +#define MASK_VAMOMINEI64_V 0xf800707f +#define MATCH_VAMOMINEI8_V 0x8000002f +#define MASK_VAMOMINEI8_V 0xf800707f +#define MATCH_VAMOMINUEI16_V 0xc000502f +#define MASK_VAMOMINUEI16_V 0xf800707f +#define MATCH_VAMOMINUEI32_V 0xc000602f +#define MASK_VAMOMINUEI32_V 0xf800707f +#define MATCH_VAMOMINUEI64_V 0xc000702f +#define MASK_VAMOMINUEI64_V 0xf800707f +#define MATCH_VAMOMINUEI8_V 0xc000002f +#define MASK_VAMOMINUEI8_V 0xf800707f +#define MATCH_VAMOOREI16_V 0x4000502f +#define MASK_VAMOOREI16_V 0xf800707f +#define MATCH_VAMOOREI32_V 0x4000602f +#define MASK_VAMOOREI32_V 0xf800707f +#define MATCH_VAMOOREI64_V 0x4000702f +#define MASK_VAMOOREI64_V 0xf800707f +#define MATCH_VAMOOREI8_V 0x4000002f +#define MASK_VAMOOREI8_V 0xf800707f +#define MATCH_VAMOSWAPEI16_V 0x800502f +#define MASK_VAMOSWAPEI16_V 0xf800707f +#define MATCH_VAMOSWAPEI32_V 0x800602f +#define MASK_VAMOSWAPEI32_V 0xf800707f +#define MATCH_VAMOSWAPEI64_V 0x800702f +#define MASK_VAMOSWAPEI64_V 0xf800707f +#define MATCH_VAMOSWAPEI8_V 0x800002f +#define MASK_VAMOSWAPEI8_V 0xf800707f +#define MATCH_VAMOXOREI16_V 0x2000502f +#define MASK_VAMOXOREI16_V 0xf800707f +#define MATCH_VAMOXOREI32_V 0x2000602f +#define MASK_VAMOXOREI32_V 0xf800707f +#define MATCH_VAMOXOREI64_V 0x2000702f +#define MASK_VAMOXOREI64_V 0xf800707f +#define MATCH_VAMOXOREI8_V 0x2000002f +#define MASK_VAMOXOREI8_V 0xf800707f +#define MATCH_VAND_VI 0x24003057 +#define MASK_VAND_VI 0xfc00707f +#define MATCH_VAND_VV 0x24000057 +#define MASK_VAND_VV 0xfc00707f +#define MATCH_VAND_VX 0x24004057 +#define MASK_VAND_VX 0xfc00707f +#define MATCH_VASUB_VV 0x2c002057 +#define MASK_VASUB_VV 0xfc00707f +#define MATCH_VASUB_VX 0x2c006057 +#define MASK_VASUB_VX 0xfc00707f +#define MATCH_VASUBU_VV 0x28002057 +#define MASK_VASUBU_VV 0xfc00707f +#define MATCH_VASUBU_VX 0x28006057 +#define MASK_VASUBU_VX 0xfc00707f +#define MATCH_VCOMPRESS_VM 0x5e002057 +#define MASK_VCOMPRESS_VM 0xfe00707f +#define MATCH_VCPOP_M 0x40082057 +#define MASK_VCPOP_M 0xfc0ff07f +#define MATCH_VDIV_VV 0x84002057 +#define MASK_VDIV_VV 0xfc00707f +#define MATCH_VDIV_VX 0x84006057 +#define MASK_VDIV_VX 0xfc00707f +#define MATCH_VDIVU_VV 0x80002057 +#define MASK_VDIVU_VV 0xfc00707f +#define MATCH_VDIVU_VX 0x80006057 +#define MASK_VDIVU_VX 0xfc00707f +#define MATCH_VFADD_VF 0x5057 +#define MASK_VFADD_VF 0xfc00707f +#define MATCH_VFADD_VV 0x1057 +#define MASK_VFADD_VV 0xfc00707f +#define MATCH_VFCLASS_V 0x4c081057 +#define MASK_VFCLASS_V 0xfc0ff07f +#define MATCH_VFCVT_F_X_V 0x48019057 +#define MASK_VFCVT_F_X_V 0xfc0ff07f +#define MATCH_VFCVT_F_XU_V 0x48011057 +#define MASK_VFCVT_F_XU_V 0xfc0ff07f +#define MATCH_VFCVT_RTZ_X_F_V 0x48039057 +#define MASK_VFCVT_RTZ_X_F_V 0xfc0ff07f +#define MATCH_VFCVT_RTZ_XU_F_V 0x48031057 +#define MASK_VFCVT_RTZ_XU_F_V 0xfc0ff07f +#define MATCH_VFCVT_X_F_V 0x48009057 +#define MASK_VFCVT_X_F_V 0xfc0ff07f +#define MATCH_VFCVT_XU_F_V 0x48001057 +#define MASK_VFCVT_XU_F_V 0xfc0ff07f +#define MATCH_VFDIV_VF 0x80005057 +#define MASK_VFDIV_VF 0xfc00707f +#define MATCH_VFDIV_VV 0x80001057 +#define MASK_VFDIV_VV 0xfc00707f +#define MATCH_VFIRST_M 0x4008a057 +#define MASK_VFIRST_M 0xfc0ff07f +#define MATCH_VFMACC_VF 0xb0005057 +#define MASK_VFMACC_VF 0xfc00707f +#define MATCH_VFMACC_VV 0xb0001057 +#define MASK_VFMACC_VV 0xfc00707f +#define MATCH_VFMADD_VF 0xa0005057 +#define MASK_VFMADD_VF 0xfc00707f +#define MATCH_VFMADD_VV 0xa0001057 +#define MASK_VFMADD_VV 0xfc00707f +#define MATCH_VFMAX_VF 0x18005057 +#define MASK_VFMAX_VF 0xfc00707f +#define MATCH_VFMAX_VV 0x18001057 +#define MASK_VFMAX_VV 0xfc00707f +#define MATCH_VFMERGE_VFM 0x5c005057 +#define MASK_VFMERGE_VFM 0xfe00707f +#define MATCH_VFMIN_VF 0x10005057 +#define MASK_VFMIN_VF 0xfc00707f +#define MATCH_VFMIN_VV 0x10001057 +#define MASK_VFMIN_VV 0xfc00707f +#define MATCH_VFMSAC_VF 0xb8005057 +#define MASK_VFMSAC_VF 0xfc00707f +#define MATCH_VFMSAC_VV 0xb8001057 +#define MASK_VFMSAC_VV 0xfc00707f +#define MATCH_VFMSUB_VF 0xa8005057 +#define MASK_VFMSUB_VF 0xfc00707f +#define MATCH_VFMSUB_VV 0xa8001057 +#define MASK_VFMSUB_VV 0xfc00707f +#define MATCH_VFMUL_VF 0x90005057 +#define MASK_VFMUL_VF 0xfc00707f +#define MATCH_VFMUL_VV 0x90001057 +#define MASK_VFMUL_VV 0xfc00707f +#define MATCH_VFMV_F_S 0x42001057 +#define MASK_VFMV_F_S 0xfe0ff07f +#define MATCH_VFMV_S_F 0x42005057 +#define MASK_VFMV_S_F 0xfff0707f +#define MATCH_VFMV_V_F 0x5e005057 +#define MASK_VFMV_V_F 0xfff0707f +#define MATCH_VFNCVT_F_F_W 0x480a1057 +#define MASK_VFNCVT_F_F_W 0xfc0ff07f +#define MATCH_VFNCVT_F_X_W 0x48099057 +#define MASK_VFNCVT_F_X_W 0xfc0ff07f +#define MATCH_VFNCVT_F_XU_W 0x48091057 +#define MASK_VFNCVT_F_XU_W 0xfc0ff07f +#define MATCH_VFNCVT_ROD_F_F_W 0x480a9057 +#define MASK_VFNCVT_ROD_F_F_W 0xfc0ff07f +#define MATCH_VFNCVT_RTZ_X_F_W 0x480b9057 +#define MASK_VFNCVT_RTZ_X_F_W 0xfc0ff07f +#define MATCH_VFNCVT_RTZ_XU_F_W 0x480b1057 +#define MASK_VFNCVT_RTZ_XU_F_W 0xfc0ff07f +#define MATCH_VFNCVT_X_F_W 0x48089057 +#define MASK_VFNCVT_X_F_W 0xfc0ff07f +#define MATCH_VFNCVT_XU_F_W 0x48081057 +#define MASK_VFNCVT_XU_F_W 0xfc0ff07f +#define MATCH_VFNMACC_VF 0xb4005057 +#define MASK_VFNMACC_VF 0xfc00707f +#define MATCH_VFNMACC_VV 0xb4001057 +#define MASK_VFNMACC_VV 0xfc00707f +#define MATCH_VFNMADD_VF 0xa4005057 +#define MASK_VFNMADD_VF 0xfc00707f +#define MATCH_VFNMADD_VV 0xa4001057 +#define MASK_VFNMADD_VV 0xfc00707f +#define MATCH_VFNMSAC_VF 0xbc005057 +#define MASK_VFNMSAC_VF 0xfc00707f +#define MATCH_VFNMSAC_VV 0xbc001057 +#define MASK_VFNMSAC_VV 0xfc00707f +#define MATCH_VFNMSUB_VF 0xac005057 +#define MASK_VFNMSUB_VF 0xfc00707f +#define MATCH_VFNMSUB_VV 0xac001057 +#define MASK_VFNMSUB_VV 0xfc00707f +#define MATCH_VFRDIV_VF 0x84005057 +#define MASK_VFRDIV_VF 0xfc00707f +#define MATCH_VFREC7_V 0x4c029057 +#define MASK_VFREC7_V 0xfc0ff07f +#define MATCH_VFREDMAX_VS 0x1c001057 +#define MASK_VFREDMAX_VS 0xfc00707f +#define MATCH_VFREDMIN_VS 0x14001057 +#define MASK_VFREDMIN_VS 0xfc00707f +#define MATCH_VFREDOSUM_VS 0xc001057 +#define MASK_VFREDOSUM_VS 0xfc00707f +#define MATCH_VFREDUSUM_VS 0x4001057 +#define MASK_VFREDUSUM_VS 0xfc00707f +#define MATCH_VFRSQRT7_V 0x4c021057 +#define MASK_VFRSQRT7_V 0xfc0ff07f +#define MATCH_VFRSUB_VF 0x9c005057 +#define MASK_VFRSUB_VF 0xfc00707f +#define MATCH_VFSGNJ_VF 0x20005057 +#define MASK_VFSGNJ_VF 0xfc00707f +#define MATCH_VFSGNJ_VV 0x20001057 +#define MASK_VFSGNJ_VV 0xfc00707f +#define MATCH_VFSGNJN_VF 0x24005057 +#define MASK_VFSGNJN_VF 0xfc00707f +#define MATCH_VFSGNJN_VV 0x24001057 +#define MASK_VFSGNJN_VV 0xfc00707f +#define MATCH_VFSGNJX_VF 0x28005057 +#define MASK_VFSGNJX_VF 0xfc00707f +#define MATCH_VFSGNJX_VV 0x28001057 +#define MASK_VFSGNJX_VV 0xfc00707f +#define MATCH_VFSLIDE1DOWN_VF 0x3c005057 +#define MASK_VFSLIDE1DOWN_VF 0xfc00707f +#define MATCH_VFSLIDE1UP_VF 0x38005057 +#define MASK_VFSLIDE1UP_VF 0xfc00707f +#define MATCH_VFSQRT_V 0x4c001057 +#define MASK_VFSQRT_V 0xfc0ff07f +#define MATCH_VFSUB_VF 0x8005057 +#define MASK_VFSUB_VF 0xfc00707f +#define MATCH_VFSUB_VV 0x8001057 +#define MASK_VFSUB_VV 0xfc00707f +#define MATCH_VFWADD_VF 0xc0005057 +#define MASK_VFWADD_VF 0xfc00707f +#define MATCH_VFWADD_VV 0xc0001057 +#define MASK_VFWADD_VV 0xfc00707f +#define MATCH_VFWADD_WF 0xd0005057 +#define MASK_VFWADD_WF 0xfc00707f +#define MATCH_VFWADD_WV 0xd0001057 +#define MASK_VFWADD_WV 0xfc00707f +#define MATCH_VFWCVT_F_F_V 0x48061057 +#define MASK_VFWCVT_F_F_V 0xfc0ff07f +#define MATCH_VFWCVT_F_X_V 0x48059057 +#define MASK_VFWCVT_F_X_V 0xfc0ff07f +#define MATCH_VFWCVT_F_XU_V 0x48051057 +#define MASK_VFWCVT_F_XU_V 0xfc0ff07f +#define MATCH_VFWCVT_RTZ_X_F_V 0x48079057 +#define MASK_VFWCVT_RTZ_X_F_V 0xfc0ff07f +#define MATCH_VFWCVT_RTZ_XU_F_V 0x48071057 +#define MASK_VFWCVT_RTZ_XU_F_V 0xfc0ff07f +#define MATCH_VFWCVT_X_F_V 0x48049057 +#define MASK_VFWCVT_X_F_V 0xfc0ff07f +#define MATCH_VFWCVT_XU_F_V 0x48041057 +#define MASK_VFWCVT_XU_F_V 0xfc0ff07f +#define MATCH_VFWMACC_VF 0xf0005057 +#define MASK_VFWMACC_VF 0xfc00707f +#define MATCH_VFWMACC_VV 0xf0001057 +#define MASK_VFWMACC_VV 0xfc00707f +#define MATCH_VFWMSAC_VF 0xf8005057 +#define MASK_VFWMSAC_VF 0xfc00707f +#define MATCH_VFWMSAC_VV 0xf8001057 +#define MASK_VFWMSAC_VV 0xfc00707f +#define MATCH_VFWMUL_VF 0xe0005057 +#define MASK_VFWMUL_VF 0xfc00707f +#define MATCH_VFWMUL_VV 0xe0001057 +#define MASK_VFWMUL_VV 0xfc00707f +#define MATCH_VFWNMACC_VF 0xf4005057 +#define MASK_VFWNMACC_VF 0xfc00707f +#define MATCH_VFWNMACC_VV 0xf4001057 +#define MASK_VFWNMACC_VV 0xfc00707f +#define MATCH_VFWNMSAC_VF 0xfc005057 +#define MASK_VFWNMSAC_VF 0xfc00707f +#define MATCH_VFWNMSAC_VV 0xfc001057 +#define MASK_VFWNMSAC_VV 0xfc00707f +#define MATCH_VFWREDOSUM_VS 0xcc001057 +#define MASK_VFWREDOSUM_VS 0xfc00707f +#define MATCH_VFWREDUSUM_VS 0xc4001057 +#define MASK_VFWREDUSUM_VS 0xfc00707f +#define MATCH_VFWSUB_VF 0xc8005057 +#define MASK_VFWSUB_VF 0xfc00707f +#define MATCH_VFWSUB_VV 0xc8001057 +#define MASK_VFWSUB_VV 0xfc00707f +#define MATCH_VFWSUB_WF 0xd8005057 +#define MASK_VFWSUB_WF 0xfc00707f +#define MATCH_VFWSUB_WV 0xd8001057 +#define MASK_VFWSUB_WV 0xfc00707f +#define MATCH_VID_V 0x5008a057 +#define MASK_VID_V 0xfdfff07f +#define MATCH_VIOTA_M 0x50082057 +#define MASK_VIOTA_M 0xfc0ff07f +#define MATCH_VL1RE16_V 0x2805007 +#define MASK_VL1RE16_V 0xfff0707f +#define MATCH_VL1RE32_V 0x2806007 +#define MASK_VL1RE32_V 0xfff0707f +#define MATCH_VL1RE64_V 0x2807007 +#define MASK_VL1RE64_V 0xfff0707f +#define MATCH_VL1RE8_V 0x2800007 +#define MASK_VL1RE8_V 0xfff0707f +#define MATCH_VL2RE16_V 0x22805007 +#define MASK_VL2RE16_V 0xfff0707f +#define MATCH_VL2RE32_V 0x22806007 +#define MASK_VL2RE32_V 0xfff0707f +#define MATCH_VL2RE64_V 0x22807007 +#define MASK_VL2RE64_V 0xfff0707f +#define MATCH_VL2RE8_V 0x22800007 +#define MASK_VL2RE8_V 0xfff0707f +#define MATCH_VL4RE16_V 0x62805007 +#define MASK_VL4RE16_V 0xfff0707f +#define MATCH_VL4RE32_V 0x62806007 +#define MASK_VL4RE32_V 0xfff0707f +#define MATCH_VL4RE64_V 0x62807007 +#define MASK_VL4RE64_V 0xfff0707f +#define MATCH_VL4RE8_V 0x62800007 +#define MASK_VL4RE8_V 0xfff0707f +#define MATCH_VL8RE16_V 0xe2805007 +#define MASK_VL8RE16_V 0xfff0707f +#define MATCH_VL8RE32_V 0xe2806007 +#define MASK_VL8RE32_V 0xfff0707f +#define MATCH_VL8RE64_V 0xe2807007 +#define MASK_VL8RE64_V 0xfff0707f +#define MATCH_VL8RE8_V 0xe2800007 +#define MASK_VL8RE8_V 0xfff0707f +#define MATCH_VLE1024_V 0x10007007 +#define MASK_VLE1024_V 0x1df0707f +#define MATCH_VLE1024FF_V 0x11007007 +#define MASK_VLE1024FF_V 0x1df0707f +#define MATCH_VLE128_V 0x10000007 +#define MASK_VLE128_V 0x1df0707f +#define MATCH_VLE128FF_V 0x11000007 +#define MASK_VLE128FF_V 0x1df0707f +#define MATCH_VLE16_V 0x5007 +#define MASK_VLE16_V 0x1df0707f +#define MATCH_VLE16FF_V 0x1005007 +#define MASK_VLE16FF_V 0x1df0707f +#define MATCH_VLE256_V 0x10005007 +#define MASK_VLE256_V 0x1df0707f +#define MATCH_VLE256FF_V 0x11005007 +#define MASK_VLE256FF_V 0x1df0707f +#define MATCH_VLE32_V 0x6007 +#define MASK_VLE32_V 0x1df0707f +#define MATCH_VLE32FF_V 0x1006007 +#define MASK_VLE32FF_V 0x1df0707f +#define MATCH_VLE512_V 0x10006007 +#define MASK_VLE512_V 0x1df0707f +#define MATCH_VLE512FF_V 0x11006007 +#define MASK_VLE512FF_V 0x1df0707f +#define MATCH_VLE64_V 0x7007 +#define MASK_VLE64_V 0x1df0707f +#define MATCH_VLE64FF_V 0x1007007 +#define MASK_VLE64FF_V 0x1df0707f +#define MATCH_VLE8_V 0x7 +#define MASK_VLE8_V 0x1df0707f +#define MATCH_VLE8FF_V 0x1000007 +#define MASK_VLE8FF_V 0x1df0707f +#define MATCH_VLM_V 0x2b00007 +#define MASK_VLM_V 0xfff0707f +#define MATCH_VLOXEI1024_V 0x1c007007 +#define MASK_VLOXEI1024_V 0x1c00707f +#define MATCH_VLOXEI128_V 0x1c000007 +#define MASK_VLOXEI128_V 0x1c00707f +#define MATCH_VLOXEI16_V 0xc005007 +#define MASK_VLOXEI16_V 0x1c00707f +#define MATCH_VLOXEI256_V 0x1c005007 +#define MASK_VLOXEI256_V 0x1c00707f +#define MATCH_VLOXEI32_V 0xc006007 +#define MASK_VLOXEI32_V 0x1c00707f +#define MATCH_VLOXEI512_V 0x1c006007 +#define MASK_VLOXEI512_V 0x1c00707f +#define MATCH_VLOXEI64_V 0xc007007 +#define MASK_VLOXEI64_V 0x1c00707f +#define MATCH_VLOXEI8_V 0xc000007 +#define MASK_VLOXEI8_V 0x1c00707f +#define MATCH_VLSE1024_V 0x18007007 +#define MASK_VLSE1024_V 0x1c00707f +#define MATCH_VLSE128_V 0x18000007 +#define MASK_VLSE128_V 0x1c00707f +#define MATCH_VLSE16_V 0x8005007 +#define MASK_VLSE16_V 0x1c00707f +#define MATCH_VLSE256_V 0x18005007 +#define MASK_VLSE256_V 0x1c00707f +#define MATCH_VLSE32_V 0x8006007 +#define MASK_VLSE32_V 0x1c00707f +#define MATCH_VLSE512_V 0x18006007 +#define MASK_VLSE512_V 0x1c00707f +#define MATCH_VLSE64_V 0x8007007 +#define MASK_VLSE64_V 0x1c00707f +#define MATCH_VLSE8_V 0x8000007 +#define MASK_VLSE8_V 0x1c00707f +#define MATCH_VLUXEI1024_V 0x14007007 +#define MASK_VLUXEI1024_V 0x1c00707f +#define MATCH_VLUXEI128_V 0x14000007 +#define MASK_VLUXEI128_V 0x1c00707f +#define MATCH_VLUXEI16_V 0x4005007 +#define MASK_VLUXEI16_V 0x1c00707f +#define MATCH_VLUXEI256_V 0x14005007 +#define MASK_VLUXEI256_V 0x1c00707f +#define MATCH_VLUXEI32_V 0x4006007 +#define MASK_VLUXEI32_V 0x1c00707f +#define MATCH_VLUXEI512_V 0x14006007 +#define MASK_VLUXEI512_V 0x1c00707f +#define MATCH_VLUXEI64_V 0x4007007 +#define MASK_VLUXEI64_V 0x1c00707f +#define MATCH_VLUXEI8_V 0x4000007 +#define MASK_VLUXEI8_V 0x1c00707f +#define MATCH_VMACC_VV 0xb4002057 +#define MASK_VMACC_VV 0xfc00707f +#define MATCH_VMACC_VX 0xb4006057 +#define MASK_VMACC_VX 0xfc00707f +#define MATCH_VMADC_VI 0x46003057 +#define MASK_VMADC_VI 0xfe00707f +#define MATCH_VMADC_VIM 0x44003057 +#define MASK_VMADC_VIM 0xfe00707f +#define MATCH_VMADC_VV 0x46000057 +#define MASK_VMADC_VV 0xfe00707f +#define MATCH_VMADC_VVM 0x44000057 +#define MASK_VMADC_VVM 0xfe00707f +#define MATCH_VMADC_VX 0x46004057 +#define MASK_VMADC_VX 0xfe00707f +#define MATCH_VMADC_VXM 0x44004057 +#define MASK_VMADC_VXM 0xfe00707f +#define MATCH_VMADD_VV 0xa4002057 +#define MASK_VMADD_VV 0xfc00707f +#define MATCH_VMADD_VX 0xa4006057 +#define MASK_VMADD_VX 0xfc00707f +#define MATCH_VMAND_MM 0x64002057 +#define MASK_VMAND_MM 0xfc00707f +#define MATCH_VMANDN_MM 0x60002057 +#define MASK_VMANDN_MM 0xfc00707f +#define MATCH_VMAX_VV 0x1c000057 +#define MASK_VMAX_VV 0xfc00707f +#define MATCH_VMAX_VX 0x1c004057 +#define MASK_VMAX_VX 0xfc00707f +#define MATCH_VMAXU_VV 0x18000057 +#define MASK_VMAXU_VV 0xfc00707f +#define MATCH_VMAXU_VX 0x18004057 +#define MASK_VMAXU_VX 0xfc00707f +#define MATCH_VMERGE_VIM 0x5c003057 +#define MASK_VMERGE_VIM 0xfe00707f +#define MATCH_VMERGE_VVM 0x5c000057 +#define MASK_VMERGE_VVM 0xfe00707f +#define MATCH_VMERGE_VXM 0x5c004057 +#define MASK_VMERGE_VXM 0xfe00707f +#define MATCH_VMFEQ_VF 0x60005057 +#define MASK_VMFEQ_VF 0xfc00707f +#define MATCH_VMFEQ_VV 0x60001057 +#define MASK_VMFEQ_VV 0xfc00707f +#define MATCH_VMFGE_VF 0x7c005057 +#define MASK_VMFGE_VF 0xfc00707f +#define MATCH_VMFGT_VF 0x74005057 +#define MASK_VMFGT_VF 0xfc00707f +#define MATCH_VMFLE_VF 0x64005057 +#define MASK_VMFLE_VF 0xfc00707f +#define MATCH_VMFLE_VV 0x64001057 +#define MASK_VMFLE_VV 0xfc00707f +#define MATCH_VMFLT_VF 0x6c005057 +#define MASK_VMFLT_VF 0xfc00707f +#define MATCH_VMFLT_VV 0x6c001057 +#define MASK_VMFLT_VV 0xfc00707f +#define MATCH_VMFNE_VF 0x70005057 +#define MASK_VMFNE_VF 0xfc00707f +#define MATCH_VMFNE_VV 0x70001057 +#define MASK_VMFNE_VV 0xfc00707f +#define MATCH_VMIN_VV 0x14000057 +#define MASK_VMIN_VV 0xfc00707f +#define MATCH_VMIN_VX 0x14004057 +#define MASK_VMIN_VX 0xfc00707f +#define MATCH_VMINU_VV 0x10000057 +#define MASK_VMINU_VV 0xfc00707f +#define MATCH_VMINU_VX 0x10004057 +#define MASK_VMINU_VX 0xfc00707f +#define MATCH_VMNAND_MM 0x74002057 +#define MASK_VMNAND_MM 0xfc00707f +#define MATCH_VMNOR_MM 0x78002057 +#define MASK_VMNOR_MM 0xfc00707f +#define MATCH_VMOR_MM 0x68002057 +#define MASK_VMOR_MM 0xfc00707f +#define MATCH_VMORN_MM 0x70002057 +#define MASK_VMORN_MM 0xfc00707f +#define MATCH_VMSBC_VV 0x4e000057 +#define MASK_VMSBC_VV 0xfe00707f +#define MATCH_VMSBC_VVM 0x4c000057 +#define MASK_VMSBC_VVM 0xfe00707f +#define MATCH_VMSBC_VX 0x4e004057 +#define MASK_VMSBC_VX 0xfe00707f +#define MATCH_VMSBC_VXM 0x4c004057 +#define MASK_VMSBC_VXM 0xfe00707f +#define MATCH_VMSBF_M 0x5000a057 +#define MASK_VMSBF_M 0xfc0ff07f +#define MATCH_VMSEQ_VI 0x60003057 +#define MASK_VMSEQ_VI 0xfc00707f +#define MATCH_VMSEQ_VV 0x60000057 +#define MASK_VMSEQ_VV 0xfc00707f +#define MATCH_VMSEQ_VX 0x60004057 +#define MASK_VMSEQ_VX 0xfc00707f +#define MATCH_VMSGT_VI 0x7c003057 +#define MASK_VMSGT_VI 0xfc00707f +#define MATCH_VMSGT_VX 0x7c004057 +#define MASK_VMSGT_VX 0xfc00707f +#define MATCH_VMSGTU_VI 0x78003057 +#define MASK_VMSGTU_VI 0xfc00707f +#define MATCH_VMSGTU_VX 0x78004057 +#define MASK_VMSGTU_VX 0xfc00707f +#define MATCH_VMSIF_M 0x5001a057 +#define MASK_VMSIF_M 0xfc0ff07f +#define MATCH_VMSLE_VI 0x74003057 +#define MASK_VMSLE_VI 0xfc00707f +#define MATCH_VMSLE_VV 0x74000057 +#define MASK_VMSLE_VV 0xfc00707f +#define MATCH_VMSLE_VX 0x74004057 +#define MASK_VMSLE_VX 0xfc00707f +#define MATCH_VMSLEU_VI 0x70003057 +#define MASK_VMSLEU_VI 0xfc00707f +#define MATCH_VMSLEU_VV 0x70000057 +#define MASK_VMSLEU_VV 0xfc00707f +#define MATCH_VMSLEU_VX 0x70004057 +#define MASK_VMSLEU_VX 0xfc00707f +#define MATCH_VMSLT_VV 0x6c000057 +#define MASK_VMSLT_VV 0xfc00707f +#define MATCH_VMSLT_VX 0x6c004057 +#define MASK_VMSLT_VX 0xfc00707f +#define MATCH_VMSLTU_VV 0x68000057 +#define MASK_VMSLTU_VV 0xfc00707f +#define MATCH_VMSLTU_VX 0x68004057 +#define MASK_VMSLTU_VX 0xfc00707f +#define MATCH_VMSNE_VI 0x64003057 +#define MASK_VMSNE_VI 0xfc00707f +#define MATCH_VMSNE_VV 0x64000057 +#define MASK_VMSNE_VV 0xfc00707f +#define MATCH_VMSNE_VX 0x64004057 +#define MASK_VMSNE_VX 0xfc00707f +#define MATCH_VMSOF_M 0x50012057 +#define MASK_VMSOF_M 0xfc0ff07f +#define MATCH_VMUL_VV 0x94002057 +#define MASK_VMUL_VV 0xfc00707f +#define MATCH_VMUL_VX 0x94006057 +#define MASK_VMUL_VX 0xfc00707f +#define MATCH_VMULH_VV 0x9c002057 +#define MASK_VMULH_VV 0xfc00707f +#define MATCH_VMULH_VX 0x9c006057 +#define MASK_VMULH_VX 0xfc00707f +#define MATCH_VMULHSU_VV 0x98002057 +#define MASK_VMULHSU_VV 0xfc00707f +#define MATCH_VMULHSU_VX 0x98006057 +#define MASK_VMULHSU_VX 0xfc00707f +#define MATCH_VMULHU_VV 0x90002057 +#define MASK_VMULHU_VV 0xfc00707f +#define MATCH_VMULHU_VX 0x90006057 +#define MASK_VMULHU_VX 0xfc00707f +#define MATCH_VMV1R_V 0x9e003057 +#define MASK_VMV1R_V 0xfe0ff07f +#define MATCH_VMV2R_V 0x9e00b057 +#define MASK_VMV2R_V 0xfe0ff07f +#define MATCH_VMV4R_V 0x9e01b057 +#define MASK_VMV4R_V 0xfe0ff07f +#define MATCH_VMV8R_V 0x9e03b057 +#define MASK_VMV8R_V 0xfe0ff07f +#define MATCH_VMV_S_X 0x42006057 +#define MASK_VMV_S_X 0xfff0707f +#define MATCH_VMV_V_I 0x5e003057 +#define MASK_VMV_V_I 0xfff0707f +#define MATCH_VMV_V_V 0x5e000057 +#define MASK_VMV_V_V 0xfff0707f +#define MATCH_VMV_V_X 0x5e004057 +#define MASK_VMV_V_X 0xfff0707f +#define MATCH_VMV_X_S 0x42002057 +#define MASK_VMV_X_S 0xfe0ff07f +#define MATCH_VMXNOR_MM 0x7c002057 +#define MASK_VMXNOR_MM 0xfc00707f +#define MATCH_VMXOR_MM 0x6c002057 +#define MASK_VMXOR_MM 0xfc00707f +#define MATCH_VNCLIP_WI 0xbc003057 +#define MASK_VNCLIP_WI 0xfc00707f +#define MATCH_VNCLIP_WV 0xbc000057 +#define MASK_VNCLIP_WV 0xfc00707f +#define MATCH_VNCLIP_WX 0xbc004057 +#define MASK_VNCLIP_WX 0xfc00707f +#define MATCH_VNCLIPU_WI 0xb8003057 +#define MASK_VNCLIPU_WI 0xfc00707f +#define MATCH_VNCLIPU_WV 0xb8000057 +#define MASK_VNCLIPU_WV 0xfc00707f +#define MATCH_VNCLIPU_WX 0xb8004057 +#define MASK_VNCLIPU_WX 0xfc00707f +#define MATCH_VNMSAC_VV 0xbc002057 +#define MASK_VNMSAC_VV 0xfc00707f +#define MATCH_VNMSAC_VX 0xbc006057 +#define MASK_VNMSAC_VX 0xfc00707f +#define MATCH_VNMSUB_VV 0xac002057 +#define MASK_VNMSUB_VV 0xfc00707f +#define MATCH_VNMSUB_VX 0xac006057 +#define MASK_VNMSUB_VX 0xfc00707f +#define MATCH_VNSRA_WI 0xb4003057 +#define MASK_VNSRA_WI 0xfc00707f +#define MATCH_VNSRA_WV 0xb4000057 +#define MASK_VNSRA_WV 0xfc00707f +#define MATCH_VNSRA_WX 0xb4004057 +#define MASK_VNSRA_WX 0xfc00707f +#define MATCH_VNSRL_WI 0xb0003057 +#define MASK_VNSRL_WI 0xfc00707f +#define MATCH_VNSRL_WV 0xb0000057 +#define MASK_VNSRL_WV 0xfc00707f +#define MATCH_VNSRL_WX 0xb0004057 +#define MASK_VNSRL_WX 0xfc00707f +#define MATCH_VOR_VI 0x28003057 +#define MASK_VOR_VI 0xfc00707f +#define MATCH_VOR_VV 0x28000057 +#define MASK_VOR_VV 0xfc00707f +#define MATCH_VOR_VX 0x28004057 +#define MASK_VOR_VX 0xfc00707f +#define MATCH_VREDAND_VS 0x4002057 +#define MASK_VREDAND_VS 0xfc00707f +#define MATCH_VREDMAX_VS 0x1c002057 +#define MASK_VREDMAX_VS 0xfc00707f +#define MATCH_VREDMAXU_VS 0x18002057 +#define MASK_VREDMAXU_VS 0xfc00707f +#define MATCH_VREDMIN_VS 0x14002057 +#define MASK_VREDMIN_VS 0xfc00707f +#define MATCH_VREDMINU_VS 0x10002057 +#define MASK_VREDMINU_VS 0xfc00707f +#define MATCH_VREDOR_VS 0x8002057 +#define MASK_VREDOR_VS 0xfc00707f +#define MATCH_VREDSUM_VS 0x2057 +#define MASK_VREDSUM_VS 0xfc00707f +#define MATCH_VREDXOR_VS 0xc002057 +#define MASK_VREDXOR_VS 0xfc00707f +#define MATCH_VREM_VV 0x8c002057 +#define MASK_VREM_VV 0xfc00707f +#define MATCH_VREM_VX 0x8c006057 +#define MASK_VREM_VX 0xfc00707f +#define MATCH_VREMU_VV 0x88002057 +#define MASK_VREMU_VV 0xfc00707f +#define MATCH_VREMU_VX 0x88006057 +#define MASK_VREMU_VX 0xfc00707f +#define MATCH_VRGATHER_VI 0x30003057 +#define MASK_VRGATHER_VI 0xfc00707f +#define MATCH_VRGATHER_VV 0x30000057 +#define MASK_VRGATHER_VV 0xfc00707f +#define MATCH_VRGATHER_VX 0x30004057 +#define MASK_VRGATHER_VX 0xfc00707f +#define MATCH_VRGATHEREI16_VV 0x38000057 +#define MASK_VRGATHEREI16_VV 0xfc00707f +#define MATCH_VRSUB_VI 0xc003057 +#define MASK_VRSUB_VI 0xfc00707f +#define MATCH_VRSUB_VX 0xc004057 +#define MASK_VRSUB_VX 0xfc00707f +#define MATCH_VS1R_V 0x2800027 +#define MASK_VS1R_V 0xfff0707f +#define MATCH_VS2R_V 0x22800027 +#define MASK_VS2R_V 0xfff0707f +#define MATCH_VS4R_V 0x62800027 +#define MASK_VS4R_V 0xfff0707f +#define MATCH_VS8R_V 0xe2800027 +#define MASK_VS8R_V 0xfff0707f +#define MATCH_VSADD_VI 0x84003057 +#define MASK_VSADD_VI 0xfc00707f +#define MATCH_VSADD_VV 0x84000057 +#define MASK_VSADD_VV 0xfc00707f +#define MATCH_VSADD_VX 0x84004057 +#define MASK_VSADD_VX 0xfc00707f +#define MATCH_VSADDU_VI 0x80003057 +#define MASK_VSADDU_VI 0xfc00707f +#define MATCH_VSADDU_VV 0x80000057 +#define MASK_VSADDU_VV 0xfc00707f +#define MATCH_VSADDU_VX 0x80004057 +#define MASK_VSADDU_VX 0xfc00707f +#define MATCH_VSBC_VVM 0x48000057 +#define MASK_VSBC_VVM 0xfe00707f +#define MATCH_VSBC_VXM 0x48004057 +#define MASK_VSBC_VXM 0xfe00707f +#define MATCH_VSE1024_V 0x10007027 +#define MASK_VSE1024_V 0x1df0707f +#define MATCH_VSE128_V 0x10000027 +#define MASK_VSE128_V 0x1df0707f +#define MATCH_VSE16_V 0x5027 +#define MASK_VSE16_V 0x1df0707f +#define MATCH_VSE256_V 0x10005027 +#define MASK_VSE256_V 0x1df0707f +#define MATCH_VSE32_V 0x6027 +#define MASK_VSE32_V 0x1df0707f +#define MATCH_VSE512_V 0x10006027 +#define MASK_VSE512_V 0x1df0707f +#define MATCH_VSE64_V 0x7027 +#define MASK_VSE64_V 0x1df0707f +#define MATCH_VSE8_V 0x27 +#define MASK_VSE8_V 0x1df0707f +#define MATCH_VSETIVLI 0xc0007057 +#define MASK_VSETIVLI 0xc000707f +#define MATCH_VSETVL 0x80007057 +#define MASK_VSETVL 0xfe00707f +#define MATCH_VSETVLI 0x7057 +#define MASK_VSETVLI 0x8000707f +#define MATCH_VSEXT_VF2 0x4803a057 +#define MASK_VSEXT_VF2 0xfc0ff07f +#define MATCH_VSEXT_VF4 0x4802a057 +#define MASK_VSEXT_VF4 0xfc0ff07f +#define MATCH_VSEXT_VF8 0x4801a057 +#define MASK_VSEXT_VF8 0xfc0ff07f +#define MATCH_VSLIDE1DOWN_VX 0x3c006057 +#define MASK_VSLIDE1DOWN_VX 0xfc00707f +#define MATCH_VSLIDE1UP_VX 0x38006057 +#define MASK_VSLIDE1UP_VX 0xfc00707f +#define MATCH_VSLIDEDOWN_VI 0x3c003057 +#define MASK_VSLIDEDOWN_VI 0xfc00707f +#define MATCH_VSLIDEDOWN_VX 0x3c004057 +#define MASK_VSLIDEDOWN_VX 0xfc00707f +#define MATCH_VSLIDEUP_VI 0x38003057 +#define MASK_VSLIDEUP_VI 0xfc00707f +#define MATCH_VSLIDEUP_VX 0x38004057 +#define MASK_VSLIDEUP_VX 0xfc00707f +#define MATCH_VSLL_VI 0x94003057 +#define MASK_VSLL_VI 0xfc00707f +#define MATCH_VSLL_VV 0x94000057 +#define MASK_VSLL_VV 0xfc00707f +#define MATCH_VSLL_VX 0x94004057 +#define MASK_VSLL_VX 0xfc00707f +#define MATCH_VSM_V 0x2b00027 +#define MASK_VSM_V 0xfff0707f +#define MATCH_VSMUL_VV 0x9c000057 +#define MASK_VSMUL_VV 0xfc00707f +#define MATCH_VSMUL_VX 0x9c004057 +#define MASK_VSMUL_VX 0xfc00707f +#define MATCH_VSOXEI1024_V 0x1c007027 +#define MASK_VSOXEI1024_V 0x1c00707f +#define MATCH_VSOXEI128_V 0x1c000027 +#define MASK_VSOXEI128_V 0x1c00707f +#define MATCH_VSOXEI16_V 0xc005027 +#define MASK_VSOXEI16_V 0x1c00707f +#define MATCH_VSOXEI256_V 0x1c005027 +#define MASK_VSOXEI256_V 0x1c00707f +#define MATCH_VSOXEI32_V 0xc006027 +#define MASK_VSOXEI32_V 0x1c00707f +#define MATCH_VSOXEI512_V 0x1c006027 +#define MASK_VSOXEI512_V 0x1c00707f +#define MATCH_VSOXEI64_V 0xc007027 +#define MASK_VSOXEI64_V 0x1c00707f +#define MATCH_VSOXEI8_V 0xc000027 +#define MASK_VSOXEI8_V 0x1c00707f +#define MATCH_VSRA_VI 0xa4003057 +#define MASK_VSRA_VI 0xfc00707f +#define MATCH_VSRA_VV 0xa4000057 +#define MASK_VSRA_VV 0xfc00707f +#define MATCH_VSRA_VX 0xa4004057 +#define MASK_VSRA_VX 0xfc00707f +#define MATCH_VSRL_VI 0xa0003057 +#define MASK_VSRL_VI 0xfc00707f +#define MATCH_VSRL_VV 0xa0000057 +#define MASK_VSRL_VV 0xfc00707f +#define MATCH_VSRL_VX 0xa0004057 +#define MASK_VSRL_VX 0xfc00707f +#define MATCH_VSSE1024_V 0x18007027 +#define MASK_VSSE1024_V 0x1c00707f +#define MATCH_VSSE128_V 0x18000027 +#define MASK_VSSE128_V 0x1c00707f +#define MATCH_VSSE16_V 0x8005027 +#define MASK_VSSE16_V 0x1c00707f +#define MATCH_VSSE256_V 0x18005027 +#define MASK_VSSE256_V 0x1c00707f +#define MATCH_VSSE32_V 0x8006027 +#define MASK_VSSE32_V 0x1c00707f +#define MATCH_VSSE512_V 0x18006027 +#define MASK_VSSE512_V 0x1c00707f +#define MATCH_VSSE64_V 0x8007027 +#define MASK_VSSE64_V 0x1c00707f +#define MATCH_VSSE8_V 0x8000027 +#define MASK_VSSE8_V 0x1c00707f +#define MATCH_VSSRA_VI 0xac003057 +#define MASK_VSSRA_VI 0xfc00707f +#define MATCH_VSSRA_VV 0xac000057 +#define MASK_VSSRA_VV 0xfc00707f +#define MATCH_VSSRA_VX 0xac004057 +#define MASK_VSSRA_VX 0xfc00707f +#define MATCH_VSSRL_VI 0xa8003057 +#define MASK_VSSRL_VI 0xfc00707f +#define MATCH_VSSRL_VV 0xa8000057 +#define MASK_VSSRL_VV 0xfc00707f +#define MATCH_VSSRL_VX 0xa8004057 +#define MASK_VSSRL_VX 0xfc00707f +#define MATCH_VSSUB_VV 0x8c000057 +#define MASK_VSSUB_VV 0xfc00707f +#define MATCH_VSSUB_VX 0x8c004057 +#define MASK_VSSUB_VX 0xfc00707f +#define MATCH_VSSUBU_VV 0x88000057 +#define MASK_VSSUBU_VV 0xfc00707f +#define MATCH_VSSUBU_VX 0x88004057 +#define MASK_VSSUBU_VX 0xfc00707f +#define MATCH_VSUB_VV 0x8000057 +#define MASK_VSUB_VV 0xfc00707f +#define MATCH_VSUB_VX 0x8004057 +#define MASK_VSUB_VX 0xfc00707f +#define MATCH_VSUXEI1024_V 0x14007027 +#define MASK_VSUXEI1024_V 0x1c00707f +#define MATCH_VSUXEI128_V 0x14000027 +#define MASK_VSUXEI128_V 0x1c00707f +#define MATCH_VSUXEI16_V 0x4005027 +#define MASK_VSUXEI16_V 0x1c00707f +#define MATCH_VSUXEI256_V 0x14005027 +#define MASK_VSUXEI256_V 0x1c00707f +#define MATCH_VSUXEI32_V 0x4006027 +#define MASK_VSUXEI32_V 0x1c00707f +#define MATCH_VSUXEI512_V 0x14006027 +#define MASK_VSUXEI512_V 0x1c00707f +#define MATCH_VSUXEI64_V 0x4007027 +#define MASK_VSUXEI64_V 0x1c00707f +#define MATCH_VSUXEI8_V 0x4000027 +#define MASK_VSUXEI8_V 0x1c00707f +#define MATCH_VWADD_VV 0xc4002057 +#define MASK_VWADD_VV 0xfc00707f +#define MATCH_VWADD_VX 0xc4006057 +#define MASK_VWADD_VX 0xfc00707f +#define MATCH_VWADD_WV 0xd4002057 +#define MASK_VWADD_WV 0xfc00707f +#define MATCH_VWADD_WX 0xd4006057 +#define MASK_VWADD_WX 0xfc00707f +#define MATCH_VWADDU_VV 0xc0002057 +#define MASK_VWADDU_VV 0xfc00707f +#define MATCH_VWADDU_VX 0xc0006057 +#define MASK_VWADDU_VX 0xfc00707f +#define MATCH_VWADDU_WV 0xd0002057 +#define MASK_VWADDU_WV 0xfc00707f +#define MATCH_VWADDU_WX 0xd0006057 +#define MASK_VWADDU_WX 0xfc00707f +#define MATCH_VWMACC_VV 0xf4002057 +#define MASK_VWMACC_VV 0xfc00707f +#define MATCH_VWMACC_VX 0xf4006057 +#define MASK_VWMACC_VX 0xfc00707f +#define MATCH_VWMACCSU_VV 0xfc002057 +#define MASK_VWMACCSU_VV 0xfc00707f +#define MATCH_VWMACCSU_VX 0xfc006057 +#define MASK_VWMACCSU_VX 0xfc00707f +#define MATCH_VWMACCU_VV 0xf0002057 +#define MASK_VWMACCU_VV 0xfc00707f +#define MATCH_VWMACCU_VX 0xf0006057 +#define MASK_VWMACCU_VX 0xfc00707f +#define MATCH_VWMACCUS_VX 0xf8006057 +#define MASK_VWMACCUS_VX 0xfc00707f +#define MATCH_VWMUL_VV 0xec002057 +#define MASK_VWMUL_VV 0xfc00707f +#define MATCH_VWMUL_VX 0xec006057 +#define MASK_VWMUL_VX 0xfc00707f +#define MATCH_VWMULSU_VV 0xe8002057 +#define MASK_VWMULSU_VV 0xfc00707f +#define MATCH_VWMULSU_VX 0xe8006057 +#define MASK_VWMULSU_VX 0xfc00707f +#define MATCH_VWMULU_VV 0xe0002057 +#define MASK_VWMULU_VV 0xfc00707f +#define MATCH_VWMULU_VX 0xe0006057 +#define MASK_VWMULU_VX 0xfc00707f +#define MATCH_VWREDSUM_VS 0xc4000057 +#define MASK_VWREDSUM_VS 0xfc00707f +#define MATCH_VWREDSUMU_VS 0xc0000057 +#define MASK_VWREDSUMU_VS 0xfc00707f +#define MATCH_VWSUB_VV 0xcc002057 +#define MASK_VWSUB_VV 0xfc00707f +#define MATCH_VWSUB_VX 0xcc006057 +#define MASK_VWSUB_VX 0xfc00707f +#define MATCH_VWSUB_WV 0xdc002057 +#define MASK_VWSUB_WV 0xfc00707f +#define MATCH_VWSUB_WX 0xdc006057 +#define MASK_VWSUB_WX 0xfc00707f +#define MATCH_VWSUBU_VV 0xc8002057 +#define MASK_VWSUBU_VV 0xfc00707f +#define MATCH_VWSUBU_VX 0xc8006057 +#define MASK_VWSUBU_VX 0xfc00707f +#define MATCH_VWSUBU_WV 0xd8002057 +#define MASK_VWSUBU_WV 0xfc00707f +#define MATCH_VWSUBU_WX 0xd8006057 +#define MASK_VWSUBU_WX 0xfc00707f +#define MATCH_VXOR_VI 0x2c003057 +#define MASK_VXOR_VI 0xfc00707f +#define MATCH_VXOR_VV 0x2c000057 +#define MASK_VXOR_VV 0xfc00707f +#define MATCH_VXOR_VX 0x2c004057 +#define MASK_VXOR_VX 0xfc00707f +#define MATCH_VZEXT_VF2 0x48032057 +#define MASK_VZEXT_VF2 0xfc0ff07f +#define MATCH_VZEXT_VF4 0x48022057 +#define MASK_VZEXT_VF4 0xfc0ff07f +#define MATCH_VZEXT_VF8 0x48012057 +#define MASK_VZEXT_VF8 0xfc0ff07f +#define MATCH_WFI 0x10500073 +#define MASK_WFI 0xffffffff +#define MATCH_WRS_NTO 0xd00073 +#define MASK_WRS_NTO 0xffffffff +#define MATCH_WRS_STO 0x1d00073 +#define MASK_WRS_STO 0xffffffff +#define MATCH_XNOR 0x40004033 +#define MASK_XNOR 0xfe00707f +#define MATCH_XOR 0x4033 +#define MASK_XOR 0xfe00707f +#define MATCH_XORI 0x4013 +#define MASK_XORI 0x707f +#define MATCH_XPERM16 0x28006033 +#define MASK_XPERM16 0xfe00707f +#define MATCH_XPERM32 0x28000033 +#define MASK_XPERM32 0xfe00707f +#define MATCH_XPERM4 0x28002033 +#define MASK_XPERM4 0xfe00707f +#define MATCH_XPERM8 0x28004033 +#define MASK_XPERM8 0xfe00707f +#define MATCH_ZUNPKD810 0xacc00077 +#define MASK_ZUNPKD810 0xfff0707f +#define MATCH_ZUNPKD820 0xacd00077 +#define MASK_ZUNPKD820 0xfff0707f +#define MATCH_ZUNPKD830 0xace00077 +#define MASK_ZUNPKD830 0xfff0707f +#define MATCH_ZUNPKD831 0xacf00077 +#define MASK_ZUNPKD831 0xfff0707f +#define MATCH_ZUNPKD832 0xad700077 +#define MASK_ZUNPKD832 0xfff0707f + #define CSR_FFLAGS 0x1 #define CSR_FRM 0x2 #define CSR_FCSR 0x3 @@ -2801,6 +2904,7 @@ #define CSR_VXRM 0xa #define CSR_VCSR 0xf #define CSR_SEED 0x15 +#define CSR_JVT 0x17 #define CSR_CYCLE 0xc00 #define CSR_TIME 0xc01 #define CSR_INSTRET 0xc02 @@ -2842,12 +2946,22 @@ #define CSR_SIE 0x104 #define CSR_STVEC 0x105 #define CSR_SCOUNTEREN 0x106 +#define CSR_SENVCFG 0x10a +#define CSR_SSTATEEN0 0x10c +#define CSR_SSTATEEN1 0x10d +#define CSR_SSTATEEN2 0x10e +#define CSR_SSTATEEN3 0x10f #define CSR_SSCRATCH 0x140 #define CSR_SEPC 0x141 #define CSR_SCAUSE 0x142 #define CSR_STVAL 0x143 #define CSR_SIP 0x144 +#define CSR_STIMECMP 0x14d +#define CSR_SISELECT 0x150 +#define CSR_SIREG 0x151 +#define CSR_STOPEI 0x15c #define CSR_SATP 0x180 +#define CSR_SCONTEXT 0x5a8 #define CSR_VSSTATUS 0x200 #define CSR_VSIE 0x204 #define CSR_VSTVEC 0x205 @@ -2856,6 +2970,10 @@ #define CSR_VSCAUSE 0x242 #define CSR_VSTVAL 0x243 #define CSR_VSIP 0x244 +#define CSR_VSTIMECMP 0x24d +#define CSR_VSISELECT 0x250 +#define CSR_VSIREG 0x251 +#define CSR_VSTOPEI 0x25c #define CSR_VSATP 0x280 #define CSR_HSTATUS 0x600 #define CSR_HEDELEG 0x602 @@ -2864,12 +2982,25 @@ #define CSR_HTIMEDELTA 0x605 #define CSR_HCOUNTEREN 0x606 #define CSR_HGEIE 0x607 +#define CSR_HVIEN 0x608 +#define CSR_HVICTL 0x609 +#define CSR_HENVCFG 0x60a +#define CSR_HSTATEEN0 0x60c +#define CSR_HSTATEEN1 0x60d +#define CSR_HSTATEEN2 0x60e +#define CSR_HSTATEEN3 0x60f #define CSR_HTVAL 0x643 #define CSR_HIP 0x644 #define CSR_HVIP 0x645 +#define CSR_HVIPRIO1 0x646 +#define CSR_HVIPRIO2 0x647 #define CSR_HTINST 0x64a #define CSR_HGATP 0x680 +#define CSR_HCONTEXT 0x6a8 #define CSR_HGEIP 0xe12 +#define CSR_VSTOPI 0xeb0 +#define CSR_SCOUNTOVF 0xda0 +#define CSR_STOPI 0xdb0 #define CSR_UTVT 0x7 #define CSR_UNXTI 0x45 #define CSR_UINTSTATUS 0x46 @@ -2892,6 +3023,13 @@ #define CSR_MIE 0x304 #define CSR_MTVEC 0x305 #define CSR_MCOUNTEREN 0x306 +#define CSR_MVIEN 0x308 +#define CSR_MVIP 0x309 +#define CSR_MENVCFG 0x30a +#define CSR_MSTATEEN0 0x30c +#define CSR_MSTATEEN1 0x30d +#define CSR_MSTATEEN2 0x30e +#define CSR_MSTATEEN3 0x30f #define CSR_MCOUNTINHIBIT 0x320 #define CSR_MSCRATCH 0x340 #define CSR_MEPC 0x341 @@ -2900,10 +3038,25 @@ #define CSR_MIP 0x344 #define CSR_MTINST 0x34a #define CSR_MTVAL2 0x34b +#define CSR_MISELECT 0x350 +#define CSR_MIREG 0x351 +#define CSR_MTOPEI 0x35c #define CSR_PMPCFG0 0x3a0 #define CSR_PMPCFG1 0x3a1 #define CSR_PMPCFG2 0x3a2 #define CSR_PMPCFG3 0x3a3 +#define CSR_PMPCFG4 0x3a4 +#define CSR_PMPCFG5 0x3a5 +#define CSR_PMPCFG6 0x3a6 +#define CSR_PMPCFG7 0x3a7 +#define CSR_PMPCFG8 0x3a8 +#define CSR_PMPCFG9 0x3a9 +#define CSR_PMPCFG10 0x3aa +#define CSR_PMPCFG11 0x3ab +#define CSR_PMPCFG12 0x3ac +#define CSR_PMPCFG13 0x3ad +#define CSR_PMPCFG14 0x3ae +#define CSR_PMPCFG15 0x3af #define CSR_PMPADDR0 0x3b0 #define CSR_PMPADDR1 0x3b1 #define CSR_PMPADDR2 0x3b2 @@ -2920,6 +3073,55 @@ #define CSR_PMPADDR13 0x3bd #define CSR_PMPADDR14 0x3be #define CSR_PMPADDR15 0x3bf +#define CSR_PMPADDR16 0x3c0 +#define CSR_PMPADDR17 0x3c1 +#define CSR_PMPADDR18 0x3c2 +#define CSR_PMPADDR19 0x3c3 +#define CSR_PMPADDR20 0x3c4 +#define CSR_PMPADDR21 0x3c5 +#define CSR_PMPADDR22 0x3c6 +#define CSR_PMPADDR23 0x3c7 +#define CSR_PMPADDR24 0x3c8 +#define CSR_PMPADDR25 0x3c9 +#define CSR_PMPADDR26 0x3ca +#define CSR_PMPADDR27 0x3cb +#define CSR_PMPADDR28 0x3cc +#define CSR_PMPADDR29 0x3cd +#define CSR_PMPADDR30 0x3ce +#define CSR_PMPADDR31 0x3cf +#define CSR_PMPADDR32 0x3d0 +#define CSR_PMPADDR33 0x3d1 +#define CSR_PMPADDR34 0x3d2 +#define CSR_PMPADDR35 0x3d3 +#define CSR_PMPADDR36 0x3d4 +#define CSR_PMPADDR37 0x3d5 +#define CSR_PMPADDR38 0x3d6 +#define CSR_PMPADDR39 0x3d7 +#define CSR_PMPADDR40 0x3d8 +#define CSR_PMPADDR41 0x3d9 +#define CSR_PMPADDR42 0x3da +#define CSR_PMPADDR43 0x3db +#define CSR_PMPADDR44 0x3dc +#define CSR_PMPADDR45 0x3dd +#define CSR_PMPADDR46 0x3de +#define CSR_PMPADDR47 0x3df +#define CSR_PMPADDR48 0x3e0 +#define CSR_PMPADDR49 0x3e1 +#define CSR_PMPADDR50 0x3e2 +#define CSR_PMPADDR51 0x3e3 +#define CSR_PMPADDR52 0x3e4 +#define CSR_PMPADDR53 0x3e5 +#define CSR_PMPADDR54 0x3e6 +#define CSR_PMPADDR55 0x3e7 +#define CSR_PMPADDR56 0x3e8 +#define CSR_PMPADDR57 0x3e9 +#define CSR_PMPADDR58 0x3ea +#define CSR_PMPADDR59 0x3eb +#define CSR_PMPADDR60 0x3ec +#define CSR_PMPADDR61 0x3ed +#define CSR_PMPADDR62 0x3ee +#define CSR_PMPADDR63 0x3ef +#define CSR_MSECCFG 0x747 #define CSR_TSELECT 0x7a0 #define CSR_TDATA1 0x7a1 #define CSR_TDATA2 0x7a2 @@ -2927,7 +3129,7 @@ #define CSR_TINFO 0x7a4 #define CSR_TCONTROL 0x7a5 #define CSR_MCONTEXT 0x7a8 -#define CSR_SCONTEXT 0x7aa +#define CSR_MSCONTEXT 0x7aa #define CSR_DCSR 0x7b0 #define CSR_DPC 0x7b1 #define CSR_DSCRATCH0 0x7b2 @@ -2996,7 +3198,25 @@ #define CSR_MARCHID 0xf12 #define CSR_MIMPID 0xf13 #define CSR_MHARTID 0xf14 +#define CSR_MCONFIGPTR 0xf15 +#define CSR_MTOPI 0xfb0 +#define CSR_SIEH 0x114 +#define CSR_SIPH 0x154 +#define CSR_STIMECMPH 0x15d +#define CSR_VSIEH 0x214 +#define CSR_VSIPH 0x254 +#define CSR_VSTIMECMPH 0x25d #define CSR_HTIMEDELTAH 0x615 +#define CSR_HIDELEGH 0x613 +#define CSR_HVIENH 0x618 +#define CSR_HENVCFGH 0x61a +#define CSR_HVIPH 0x655 +#define CSR_HVIPRIO1H 0x656 +#define CSR_HVIPRIO2H 0x657 +#define CSR_HSTATEEN0H 0x61c +#define CSR_HSTATEEN1H 0x61d +#define CSR_HSTATEEN2H 0x61e +#define CSR_HSTATEEN3H 0x61f #define CSR_CYCLEH 0xc80 #define CSR_TIMEH 0xc81 #define CSR_INSTRETH 0xc82 @@ -3030,6 +3250,50 @@ #define CSR_HPMCOUNTER30H 0xc9e #define CSR_HPMCOUNTER31H 0xc9f #define CSR_MSTATUSH 0x310 +#define CSR_MIDELEGH 0x313 +#define CSR_MIEH 0x314 +#define CSR_MVIENH 0x318 +#define CSR_MVIPH 0x319 +#define CSR_MENVCFGH 0x31a +#define CSR_MSTATEEN0H 0x31c +#define CSR_MSTATEEN1H 0x31d +#define CSR_MSTATEEN2H 0x31e +#define CSR_MSTATEEN3H 0x31f +#define CSR_MIPH 0x354 +#define CSR_MHPMEVENT3H 0x723 +#define CSR_MHPMEVENT4H 0x724 +#define CSR_MHPMEVENT5H 0x725 +#define CSR_MHPMEVENT6H 0x726 +#define CSR_MHPMEVENT7H 0x727 +#define CSR_MHPMEVENT8H 0x728 +#define CSR_MHPMEVENT9H 0x729 +#define CSR_MHPMEVENT10H 0x72a +#define CSR_MHPMEVENT11H 0x72b +#define CSR_MHPMEVENT12H 0x72c +#define CSR_MHPMEVENT13H 0x72d +#define CSR_MHPMEVENT14H 0x72e +#define CSR_MHPMEVENT15H 0x72f +#define CSR_MHPMEVENT16H 0x730 +#define CSR_MHPMEVENT17H 0x731 +#define CSR_MHPMEVENT18H 0x732 +#define CSR_MHPMEVENT19H 0x733 +#define CSR_MHPMEVENT20H 0x734 +#define CSR_MHPMEVENT21H 0x735 +#define CSR_MHPMEVENT22H 0x736 +#define CSR_MHPMEVENT23H 0x737 +#define CSR_MHPMEVENT24H 0x738 +#define CSR_MHPMEVENT25H 0x739 +#define CSR_MHPMEVENT26H 0x73a +#define CSR_MHPMEVENT27H 0x73b +#define CSR_MHPMEVENT28H 0x73c +#define CSR_MHPMEVENT29H 0x73d +#define CSR_MHPMEVENT30H 0x73e +#define CSR_MHPMEVENT31H 0x73f +#define CSR_MNSCRATCH 0x740 +#define CSR_MNEPC 0x741 +#define CSR_MNCAUSE 0x742 +#define CSR_MNSTATUS 0x744 +#define CSR_MSECCFGH 0x757 #define CSR_MCYCLEH 0xb80 #define CSR_MINSTRETH 0xb82 #define CSR_MHPMCOUNTER3H 0xb83 @@ -3061,6 +3325,7 @@ #define CSR_MHPMCOUNTER29H 0xb9d #define CSR_MHPMCOUNTER30H 0xb9e #define CSR_MHPMCOUNTER31H 0xb9f + #define CAUSE_MISALIGNED_FETCH 0x0 #define CAUSE_FETCH_ACCESS 0x1 #define CAUSE_ILLEGAL_INSTRUCTION 0x2 @@ -3080,993 +3345,552 @@ #define CAUSE_LOAD_GUEST_PAGE_FAULT 0x15 #define CAUSE_VIRTUAL_INSTRUCTION 0x16 #define CAUSE_STORE_GUEST_PAGE_FAULT 0x17 + +#define INSN_FIELD_RD 0xf80 +#define INSN_FIELD_RT 0xf8000 +#define INSN_FIELD_RS1 0xf8000 +#define INSN_FIELD_RS2 0x1f00000 +#define INSN_FIELD_RS3 0xf8000000 +#define INSN_FIELD_AQRL 0x6000000 +#define INSN_FIELD_AQ 0x4000000 +#define INSN_FIELD_RL 0x2000000 +#define INSN_FIELD_FM 0xf0000000 +#define INSN_FIELD_PRED 0xf000000 +#define INSN_FIELD_SUCC 0xf00000 +#define INSN_FIELD_RM 0x7000 +#define INSN_FIELD_FUNCT3 0x7000 +#define INSN_FIELD_FUNCT2 0x6000000 +#define INSN_FIELD_IMM20 0xfffff000 +#define INSN_FIELD_JIMM20 0xfffff000 +#define INSN_FIELD_IMM12 0xfff00000 +#define INSN_FIELD_CSR 0xfff00000 +#define INSN_FIELD_IMM12HI 0xfe000000 +#define INSN_FIELD_BIMM12HI 0xfe000000 +#define INSN_FIELD_IMM12LO 0xf80 +#define INSN_FIELD_BIMM12LO 0xf80 +#define INSN_FIELD_ZIMM 0xf8000 +#define INSN_FIELD_SHAMTQ 0x7f00000 +#define INSN_FIELD_SHAMTW 0x1f00000 +#define INSN_FIELD_SHAMTW4 0xf00000 +#define INSN_FIELD_SHAMTD 0x3f00000 +#define INSN_FIELD_BS 0xc0000000 +#define INSN_FIELD_RNUM 0xf00000 +#define INSN_FIELD_RC 0x3e000000 +#define INSN_FIELD_IMM2 0x300000 +#define INSN_FIELD_IMM3 0x700000 +#define INSN_FIELD_IMM4 0xf00000 +#define INSN_FIELD_IMM5 0x1f00000 +#define INSN_FIELD_IMM6 0x3f00000 +#define INSN_FIELD_OPCODE 0x7f +#define INSN_FIELD_FUNCT7 0xfe000000 +#define INSN_FIELD_VD 0xf80 +#define INSN_FIELD_VS3 0xf80 +#define INSN_FIELD_VS1 0xf8000 +#define INSN_FIELD_VS2 0x1f00000 +#define INSN_FIELD_VM 0x2000000 +#define INSN_FIELD_WD 0x4000000 +#define INSN_FIELD_AMOOP 0xf8000000 +#define INSN_FIELD_NF 0xe0000000 +#define INSN_FIELD_SIMM5 0xf8000 +#define INSN_FIELD_ZIMM10 0x3ff00000 +#define INSN_FIELD_ZIMM11 0x7ff00000 +#define INSN_FIELD_C_NZUIMM10 0x1fe0 +#define INSN_FIELD_C_UIMM7LO 0x60 +#define INSN_FIELD_C_UIMM7HI 0x1c00 +#define INSN_FIELD_C_UIMM8LO 0x60 +#define INSN_FIELD_C_UIMM8HI 0x1c00 +#define INSN_FIELD_C_UIMM9LO 0x60 +#define INSN_FIELD_C_UIMM9HI 0x1c00 +#define INSN_FIELD_C_NZIMM6LO 0x7c +#define INSN_FIELD_C_NZIMM6HI 0x1000 +#define INSN_FIELD_C_IMM6LO 0x7c +#define INSN_FIELD_C_IMM6HI 0x1000 +#define INSN_FIELD_C_NZIMM10HI 0x1000 +#define INSN_FIELD_C_NZIMM10LO 0x7c +#define INSN_FIELD_C_NZIMM18HI 0x1000 +#define INSN_FIELD_C_NZIMM18LO 0x7c +#define INSN_FIELD_C_IMM12 0x1ffc +#define INSN_FIELD_C_BIMM9LO 0x7c +#define INSN_FIELD_C_BIMM9HI 0x1c00 +#define INSN_FIELD_C_NZUIMM5 0x7c +#define INSN_FIELD_C_NZUIMM6LO 0x7c +#define INSN_FIELD_C_NZUIMM6HI 0x1000 +#define INSN_FIELD_C_UIMM8SPLO 0x7c +#define INSN_FIELD_C_UIMM8SPHI 0x1000 +#define INSN_FIELD_C_UIMM8SP_S 0x1f80 +#define INSN_FIELD_C_UIMM10SPLO 0x7c +#define INSN_FIELD_C_UIMM10SPHI 0x1000 +#define INSN_FIELD_C_UIMM9SPLO 0x7c +#define INSN_FIELD_C_UIMM9SPHI 0x1000 +#define INSN_FIELD_C_UIMM10SP_S 0x1f80 +#define INSN_FIELD_C_UIMM9SP_S 0x1f80 +#define INSN_FIELD_C_UIMM2 0x60 +#define INSN_FIELD_C_UIMM1 0x20 +#define INSN_FIELD_C_RLIST 0xf0 +#define INSN_FIELD_C_SPIMM 0xc +#define INSN_FIELD_C_INDEX 0x3fc +#define INSN_FIELD_RS1_P 0x380 +#define INSN_FIELD_RS2_P 0x1c +#define INSN_FIELD_RD_P 0x1c +#define INSN_FIELD_RD_RS1_N0 0xf80 +#define INSN_FIELD_RD_RS1_P 0x380 +#define INSN_FIELD_RD_RS1 0xf80 +#define INSN_FIELD_RD_N2 0xf80 +#define INSN_FIELD_RD_N0 0xf80 +#define INSN_FIELD_RS1_N0 0xf80 +#define INSN_FIELD_C_RS2_N0 0x7c +#define INSN_FIELD_C_RS1_N0 0xf80 +#define INSN_FIELD_C_RS2 0x7c +#define INSN_FIELD_C_SREG1 0x380 +#define INSN_FIELD_C_SREG2 0x1c #endif #ifdef DECLARE_INSN -DECLARE_INSN(slli_rv32, MATCH_SLLI_RV32, MASK_SLLI_RV32) -DECLARE_INSN(srli_rv32, MATCH_SRLI_RV32, MASK_SRLI_RV32) -DECLARE_INSN(srai_rv32, MATCH_SRAI_RV32, MASK_SRAI_RV32) -DECLARE_INSN(frflags, MATCH_FRFLAGS, MASK_FRFLAGS) -DECLARE_INSN(fsflags, MATCH_FSFLAGS, MASK_FSFLAGS) -DECLARE_INSN(fsflagsi, MATCH_FSFLAGSI, MASK_FSFLAGSI) -DECLARE_INSN(frrm, MATCH_FRRM, MASK_FRRM) -DECLARE_INSN(fsrm, MATCH_FSRM, MASK_FSRM) -DECLARE_INSN(fsrmi, MATCH_FSRMI, MASK_FSRMI) -DECLARE_INSN(fscsr, MATCH_FSCSR, MASK_FSCSR) -DECLARE_INSN(frcsr, MATCH_FRCSR, MASK_FRCSR) -DECLARE_INSN(rdcycle, MATCH_RDCYCLE, MASK_RDCYCLE) -DECLARE_INSN(rdtime, MATCH_RDTIME, MASK_RDTIME) -DECLARE_INSN(rdinstret, MATCH_RDINSTRET, MASK_RDINSTRET) -DECLARE_INSN(rdcycleh, MATCH_RDCYCLEH, MASK_RDCYCLEH) -DECLARE_INSN(rdtimeh, MATCH_RDTIMEH, MASK_RDTIMEH) -DECLARE_INSN(rdinstreth, MATCH_RDINSTRETH, MASK_RDINSTRETH) -DECLARE_INSN(scall, MATCH_SCALL, MASK_SCALL) -DECLARE_INSN(sbreak, MATCH_SBREAK, MASK_SBREAK) -DECLARE_INSN(fmv_x_s, MATCH_FMV_X_S, MASK_FMV_X_S) -DECLARE_INSN(fmv_s_x, MATCH_FMV_S_X, MASK_FMV_S_X) -DECLARE_INSN(fence_tso, MATCH_FENCE_TSO, MASK_FENCE_TSO) -DECLARE_INSN(pause, MATCH_PAUSE, MASK_PAUSE) -DECLARE_INSN(beq, MATCH_BEQ, MASK_BEQ) -DECLARE_INSN(bne, MATCH_BNE, MASK_BNE) -DECLARE_INSN(blt, MATCH_BLT, MASK_BLT) -DECLARE_INSN(bge, MATCH_BGE, MASK_BGE) -DECLARE_INSN(bltu, MATCH_BLTU, MASK_BLTU) -DECLARE_INSN(bgeu, MATCH_BGEU, MASK_BGEU) -DECLARE_INSN(jalr, MATCH_JALR, MASK_JALR) -DECLARE_INSN(jal, MATCH_JAL, MASK_JAL) -DECLARE_INSN(lui, MATCH_LUI, MASK_LUI) -DECLARE_INSN(auipc, MATCH_AUIPC, MASK_AUIPC) -DECLARE_INSN(addi, MATCH_ADDI, MASK_ADDI) -DECLARE_INSN(slti, MATCH_SLTI, MASK_SLTI) -DECLARE_INSN(sltiu, MATCH_SLTIU, MASK_SLTIU) -DECLARE_INSN(xori, MATCH_XORI, MASK_XORI) -DECLARE_INSN(ori, MATCH_ORI, MASK_ORI) -DECLARE_INSN(andi, MATCH_ANDI, MASK_ANDI) DECLARE_INSN(add, MATCH_ADD, MASK_ADD) -DECLARE_INSN(sub, MATCH_SUB, MASK_SUB) -DECLARE_INSN(sll, MATCH_SLL, MASK_SLL) -DECLARE_INSN(slt, MATCH_SLT, MASK_SLT) -DECLARE_INSN(sltu, MATCH_SLTU, MASK_SLTU) -DECLARE_INSN(xor, MATCH_XOR, MASK_XOR) -DECLARE_INSN(srl, MATCH_SRL, MASK_SRL) -DECLARE_INSN(sra, MATCH_SRA, MASK_SRA) -DECLARE_INSN(or, MATCH_OR, MASK_OR) -DECLARE_INSN(and, MATCH_AND, MASK_AND) -DECLARE_INSN(lb, MATCH_LB, MASK_LB) -DECLARE_INSN(lh, MATCH_LH, MASK_LH) -DECLARE_INSN(lw, MATCH_LW, MASK_LW) -DECLARE_INSN(lbu, MATCH_LBU, MASK_LBU) -DECLARE_INSN(lhu, MATCH_LHU, MASK_LHU) -DECLARE_INSN(sb, MATCH_SB, MASK_SB) -DECLARE_INSN(sh, MATCH_SH, MASK_SH) -DECLARE_INSN(sw, MATCH_SW, MASK_SW) -DECLARE_INSN(fence, MATCH_FENCE, MASK_FENCE) -DECLARE_INSN(fence_i, MATCH_FENCE_I, MASK_FENCE_I) +DECLARE_INSN(add16, MATCH_ADD16, MASK_ADD16) +DECLARE_INSN(add32, MATCH_ADD32, MASK_ADD32) +DECLARE_INSN(add64, MATCH_ADD64, MASK_ADD64) +DECLARE_INSN(add8, MATCH_ADD8, MASK_ADD8) +DECLARE_INSN(add_uw, MATCH_ADD_UW, MASK_ADD_UW) +DECLARE_INSN(addd, MATCH_ADDD, MASK_ADDD) +DECLARE_INSN(addi, MATCH_ADDI, MASK_ADDI) +DECLARE_INSN(addid, MATCH_ADDID, MASK_ADDID) DECLARE_INSN(addiw, MATCH_ADDIW, MASK_ADDIW) -DECLARE_INSN(slliw, MATCH_SLLIW, MASK_SLLIW) -DECLARE_INSN(srliw, MATCH_SRLIW, MASK_SRLIW) -DECLARE_INSN(sraiw, MATCH_SRAIW, MASK_SRAIW) DECLARE_INSN(addw, MATCH_ADDW, MASK_ADDW) -DECLARE_INSN(subw, MATCH_SUBW, MASK_SUBW) -DECLARE_INSN(sllw, MATCH_SLLW, MASK_SLLW) -DECLARE_INSN(srlw, MATCH_SRLW, MASK_SRLW) -DECLARE_INSN(sraw, MATCH_SRAW, MASK_SRAW) -DECLARE_INSN(ld, MATCH_LD, MASK_LD) -DECLARE_INSN(lwu, MATCH_LWU, MASK_LWU) -DECLARE_INSN(sd, MATCH_SD, MASK_SD) -DECLARE_INSN(slli, MATCH_SLLI, MASK_SLLI) -DECLARE_INSN(srli, MATCH_SRLI, MASK_SRLI) -DECLARE_INSN(srai, MATCH_SRAI, MASK_SRAI) -DECLARE_INSN(mul, MATCH_MUL, MASK_MUL) -DECLARE_INSN(mulh, MATCH_MULH, MASK_MULH) -DECLARE_INSN(mulhsu, MATCH_MULHSU, MASK_MULHSU) -DECLARE_INSN(mulhu, MATCH_MULHU, MASK_MULHU) -DECLARE_INSN(div, MATCH_DIV, MASK_DIV) -DECLARE_INSN(divu, MATCH_DIVU, MASK_DIVU) -DECLARE_INSN(rem, MATCH_REM, MASK_REM) -DECLARE_INSN(remu, MATCH_REMU, MASK_REMU) -DECLARE_INSN(mulw, MATCH_MULW, MASK_MULW) -DECLARE_INSN(divw, MATCH_DIVW, MASK_DIVW) -DECLARE_INSN(divuw, MATCH_DIVUW, MASK_DIVUW) -DECLARE_INSN(remw, MATCH_REMW, MASK_REMW) -DECLARE_INSN(remuw, MATCH_REMUW, MASK_REMUW) -DECLARE_INSN(amoadd_w, MATCH_AMOADD_W, MASK_AMOADD_W) -DECLARE_INSN(amoxor_w, MATCH_AMOXOR_W, MASK_AMOXOR_W) -DECLARE_INSN(amoor_w, MATCH_AMOOR_W, MASK_AMOOR_W) -DECLARE_INSN(amoand_w, MATCH_AMOAND_W, MASK_AMOAND_W) -DECLARE_INSN(amomin_w, MATCH_AMOMIN_W, MASK_AMOMIN_W) -DECLARE_INSN(amomax_w, MATCH_AMOMAX_W, MASK_AMOMAX_W) -DECLARE_INSN(amominu_w, MATCH_AMOMINU_W, MASK_AMOMINU_W) -DECLARE_INSN(amomaxu_w, MATCH_AMOMAXU_W, MASK_AMOMAXU_W) -DECLARE_INSN(amoswap_w, MATCH_AMOSWAP_W, MASK_AMOSWAP_W) -DECLARE_INSN(lr_w, MATCH_LR_W, MASK_LR_W) -DECLARE_INSN(sc_w, MATCH_SC_W, MASK_SC_W) +DECLARE_INSN(aes32dsi, MATCH_AES32DSI, MASK_AES32DSI) +DECLARE_INSN(aes32dsmi, MATCH_AES32DSMI, MASK_AES32DSMI) +DECLARE_INSN(aes32esi, MATCH_AES32ESI, MASK_AES32ESI) +DECLARE_INSN(aes32esmi, MATCH_AES32ESMI, MASK_AES32ESMI) +DECLARE_INSN(aes64ds, MATCH_AES64DS, MASK_AES64DS) +DECLARE_INSN(aes64dsm, MATCH_AES64DSM, MASK_AES64DSM) +DECLARE_INSN(aes64es, MATCH_AES64ES, MASK_AES64ES) +DECLARE_INSN(aes64esm, MATCH_AES64ESM, MASK_AES64ESM) +DECLARE_INSN(aes64im, MATCH_AES64IM, MASK_AES64IM) +DECLARE_INSN(aes64ks1i, MATCH_AES64KS1I, MASK_AES64KS1I) +DECLARE_INSN(aes64ks2, MATCH_AES64KS2, MASK_AES64KS2) DECLARE_INSN(amoadd_d, MATCH_AMOADD_D, MASK_AMOADD_D) -DECLARE_INSN(amoxor_d, MATCH_AMOXOR_D, MASK_AMOXOR_D) -DECLARE_INSN(amoor_d, MATCH_AMOOR_D, MASK_AMOOR_D) +DECLARE_INSN(amoadd_w, MATCH_AMOADD_W, MASK_AMOADD_W) DECLARE_INSN(amoand_d, MATCH_AMOAND_D, MASK_AMOAND_D) -DECLARE_INSN(amomin_d, MATCH_AMOMIN_D, MASK_AMOMIN_D) +DECLARE_INSN(amoand_w, MATCH_AMOAND_W, MASK_AMOAND_W) DECLARE_INSN(amomax_d, MATCH_AMOMAX_D, MASK_AMOMAX_D) -DECLARE_INSN(amominu_d, MATCH_AMOMINU_D, MASK_AMOMINU_D) +DECLARE_INSN(amomax_w, MATCH_AMOMAX_W, MASK_AMOMAX_W) DECLARE_INSN(amomaxu_d, MATCH_AMOMAXU_D, MASK_AMOMAXU_D) +DECLARE_INSN(amomaxu_w, MATCH_AMOMAXU_W, MASK_AMOMAXU_W) +DECLARE_INSN(amomin_d, MATCH_AMOMIN_D, MASK_AMOMIN_D) +DECLARE_INSN(amomin_w, MATCH_AMOMIN_W, MASK_AMOMIN_W) +DECLARE_INSN(amominu_d, MATCH_AMOMINU_D, MASK_AMOMINU_D) +DECLARE_INSN(amominu_w, MATCH_AMOMINU_W, MASK_AMOMINU_W) +DECLARE_INSN(amoor_d, MATCH_AMOOR_D, MASK_AMOOR_D) +DECLARE_INSN(amoor_w, MATCH_AMOOR_W, MASK_AMOOR_W) DECLARE_INSN(amoswap_d, MATCH_AMOSWAP_D, MASK_AMOSWAP_D) -DECLARE_INSN(lr_d, MATCH_LR_D, MASK_LR_D) -DECLARE_INSN(sc_d, MATCH_SC_D, MASK_SC_D) -DECLARE_INSN(hfence_vvma, MATCH_HFENCE_VVMA, MASK_HFENCE_VVMA) -DECLARE_INSN(hfence_gvma, MATCH_HFENCE_GVMA, MASK_HFENCE_GVMA) -DECLARE_INSN(hlv_b, MATCH_HLV_B, MASK_HLV_B) -DECLARE_INSN(hlv_bu, MATCH_HLV_BU, MASK_HLV_BU) -DECLARE_INSN(hlv_h, MATCH_HLV_H, MASK_HLV_H) -DECLARE_INSN(hlv_hu, MATCH_HLV_HU, MASK_HLV_HU) -DECLARE_INSN(hlvx_hu, MATCH_HLVX_HU, MASK_HLVX_HU) -DECLARE_INSN(hlv_w, MATCH_HLV_W, MASK_HLV_W) -DECLARE_INSN(hlvx_wu, MATCH_HLVX_WU, MASK_HLVX_WU) -DECLARE_INSN(hsv_b, MATCH_HSV_B, MASK_HSV_B) -DECLARE_INSN(hsv_h, MATCH_HSV_H, MASK_HSV_H) -DECLARE_INSN(hsv_w, MATCH_HSV_W, MASK_HSV_W) -DECLARE_INSN(hlv_wu, MATCH_HLV_WU, MASK_HLV_WU) -DECLARE_INSN(hlv_d, MATCH_HLV_D, MASK_HLV_D) -DECLARE_INSN(hsv_d, MATCH_HSV_D, MASK_HSV_D) -DECLARE_INSN(fadd_s, MATCH_FADD_S, MASK_FADD_S) -DECLARE_INSN(fsub_s, MATCH_FSUB_S, MASK_FSUB_S) -DECLARE_INSN(fmul_s, MATCH_FMUL_S, MASK_FMUL_S) -DECLARE_INSN(fdiv_s, MATCH_FDIV_S, MASK_FDIV_S) -DECLARE_INSN(fsgnj_s, MATCH_FSGNJ_S, MASK_FSGNJ_S) -DECLARE_INSN(fsgnjn_s, MATCH_FSGNJN_S, MASK_FSGNJN_S) -DECLARE_INSN(fsgnjx_s, MATCH_FSGNJX_S, MASK_FSGNJX_S) -DECLARE_INSN(fmin_s, MATCH_FMIN_S, MASK_FMIN_S) -DECLARE_INSN(fmax_s, MATCH_FMAX_S, MASK_FMAX_S) -DECLARE_INSN(fsqrt_s, MATCH_FSQRT_S, MASK_FSQRT_S) -DECLARE_INSN(fle_s, MATCH_FLE_S, MASK_FLE_S) -DECLARE_INSN(flt_s, MATCH_FLT_S, MASK_FLT_S) -DECLARE_INSN(feq_s, MATCH_FEQ_S, MASK_FEQ_S) -DECLARE_INSN(fcvt_w_s, MATCH_FCVT_W_S, MASK_FCVT_W_S) -DECLARE_INSN(fcvt_wu_s, MATCH_FCVT_WU_S, MASK_FCVT_WU_S) -DECLARE_INSN(fmv_x_w, MATCH_FMV_X_W, MASK_FMV_X_W) -DECLARE_INSN(fclass_s, MATCH_FCLASS_S, MASK_FCLASS_S) -DECLARE_INSN(fcvt_s_w, MATCH_FCVT_S_W, MASK_FCVT_S_W) -DECLARE_INSN(fcvt_s_wu, MATCH_FCVT_S_WU, MASK_FCVT_S_WU) -DECLARE_INSN(fmv_w_x, MATCH_FMV_W_X, MASK_FMV_W_X) -DECLARE_INSN(flw, MATCH_FLW, MASK_FLW) -DECLARE_INSN(fsw, MATCH_FSW, MASK_FSW) -DECLARE_INSN(fmadd_s, MATCH_FMADD_S, MASK_FMADD_S) -DECLARE_INSN(fmsub_s, MATCH_FMSUB_S, MASK_FMSUB_S) -DECLARE_INSN(fnmsub_s, MATCH_FNMSUB_S, MASK_FNMSUB_S) -DECLARE_INSN(fnmadd_s, MATCH_FNMADD_S, MASK_FNMADD_S) -DECLARE_INSN(fcvt_l_s, MATCH_FCVT_L_S, MASK_FCVT_L_S) -DECLARE_INSN(fcvt_lu_s, MATCH_FCVT_LU_S, MASK_FCVT_LU_S) -DECLARE_INSN(fcvt_s_l, MATCH_FCVT_S_L, MASK_FCVT_S_L) -DECLARE_INSN(fcvt_s_lu, MATCH_FCVT_S_LU, MASK_FCVT_S_LU) -DECLARE_INSN(fadd_d, MATCH_FADD_D, MASK_FADD_D) -DECLARE_INSN(fsub_d, MATCH_FSUB_D, MASK_FSUB_D) -DECLARE_INSN(fmul_d, MATCH_FMUL_D, MASK_FMUL_D) -DECLARE_INSN(fdiv_d, MATCH_FDIV_D, MASK_FDIV_D) -DECLARE_INSN(fsgnj_d, MATCH_FSGNJ_D, MASK_FSGNJ_D) -DECLARE_INSN(fsgnjn_d, MATCH_FSGNJN_D, MASK_FSGNJN_D) -DECLARE_INSN(fsgnjx_d, MATCH_FSGNJX_D, MASK_FSGNJX_D) -DECLARE_INSN(fmin_d, MATCH_FMIN_D, MASK_FMIN_D) -DECLARE_INSN(fmax_d, MATCH_FMAX_D, MASK_FMAX_D) -DECLARE_INSN(fcvt_s_d, MATCH_FCVT_S_D, MASK_FCVT_S_D) -DECLARE_INSN(fcvt_d_s, MATCH_FCVT_D_S, MASK_FCVT_D_S) -DECLARE_INSN(fsqrt_d, MATCH_FSQRT_D, MASK_FSQRT_D) -DECLARE_INSN(fle_d, MATCH_FLE_D, MASK_FLE_D) -DECLARE_INSN(flt_d, MATCH_FLT_D, MASK_FLT_D) -DECLARE_INSN(feq_d, MATCH_FEQ_D, MASK_FEQ_D) -DECLARE_INSN(fcvt_w_d, MATCH_FCVT_W_D, MASK_FCVT_W_D) -DECLARE_INSN(fcvt_wu_d, MATCH_FCVT_WU_D, MASK_FCVT_WU_D) -DECLARE_INSN(fclass_d, MATCH_FCLASS_D, MASK_FCLASS_D) -DECLARE_INSN(fcvt_d_w, MATCH_FCVT_D_W, MASK_FCVT_D_W) -DECLARE_INSN(fcvt_d_wu, MATCH_FCVT_D_WU, MASK_FCVT_D_WU) -DECLARE_INSN(fld, MATCH_FLD, MASK_FLD) -DECLARE_INSN(fsd, MATCH_FSD, MASK_FSD) -DECLARE_INSN(fmadd_d, MATCH_FMADD_D, MASK_FMADD_D) -DECLARE_INSN(fmsub_d, MATCH_FMSUB_D, MASK_FMSUB_D) -DECLARE_INSN(fnmsub_d, MATCH_FNMSUB_D, MASK_FNMSUB_D) -DECLARE_INSN(fnmadd_d, MATCH_FNMADD_D, MASK_FNMADD_D) -DECLARE_INSN(fcvt_l_d, MATCH_FCVT_L_D, MASK_FCVT_L_D) -DECLARE_INSN(fcvt_lu_d, MATCH_FCVT_LU_D, MASK_FCVT_LU_D) -DECLARE_INSN(fmv_x_d, MATCH_FMV_X_D, MASK_FMV_X_D) -DECLARE_INSN(fcvt_d_l, MATCH_FCVT_D_L, MASK_FCVT_D_L) -DECLARE_INSN(fcvt_d_lu, MATCH_FCVT_D_LU, MASK_FCVT_D_LU) -DECLARE_INSN(fmv_d_x, MATCH_FMV_D_X, MASK_FMV_D_X) -DECLARE_INSN(fadd_q, MATCH_FADD_Q, MASK_FADD_Q) -DECLARE_INSN(fsub_q, MATCH_FSUB_Q, MASK_FSUB_Q) -DECLARE_INSN(fmul_q, MATCH_FMUL_Q, MASK_FMUL_Q) -DECLARE_INSN(fdiv_q, MATCH_FDIV_Q, MASK_FDIV_Q) -DECLARE_INSN(fsgnj_q, MATCH_FSGNJ_Q, MASK_FSGNJ_Q) -DECLARE_INSN(fsgnjn_q, MATCH_FSGNJN_Q, MASK_FSGNJN_Q) -DECLARE_INSN(fsgnjx_q, MATCH_FSGNJX_Q, MASK_FSGNJX_Q) -DECLARE_INSN(fmin_q, MATCH_FMIN_Q, MASK_FMIN_Q) -DECLARE_INSN(fmax_q, MATCH_FMAX_Q, MASK_FMAX_Q) -DECLARE_INSN(fcvt_s_q, MATCH_FCVT_S_Q, MASK_FCVT_S_Q) -DECLARE_INSN(fcvt_q_s, MATCH_FCVT_Q_S, MASK_FCVT_Q_S) -DECLARE_INSN(fcvt_d_q, MATCH_FCVT_D_Q, MASK_FCVT_D_Q) -DECLARE_INSN(fcvt_q_d, MATCH_FCVT_Q_D, MASK_FCVT_Q_D) -DECLARE_INSN(fsqrt_q, MATCH_FSQRT_Q, MASK_FSQRT_Q) -DECLARE_INSN(fle_q, MATCH_FLE_Q, MASK_FLE_Q) -DECLARE_INSN(flt_q, MATCH_FLT_Q, MASK_FLT_Q) -DECLARE_INSN(feq_q, MATCH_FEQ_Q, MASK_FEQ_Q) -DECLARE_INSN(fcvt_w_q, MATCH_FCVT_W_Q, MASK_FCVT_W_Q) -DECLARE_INSN(fcvt_wu_q, MATCH_FCVT_WU_Q, MASK_FCVT_WU_Q) -DECLARE_INSN(fclass_q, MATCH_FCLASS_Q, MASK_FCLASS_Q) -DECLARE_INSN(fcvt_q_w, MATCH_FCVT_Q_W, MASK_FCVT_Q_W) -DECLARE_INSN(fcvt_q_wu, MATCH_FCVT_Q_WU, MASK_FCVT_Q_WU) -DECLARE_INSN(flq, MATCH_FLQ, MASK_FLQ) -DECLARE_INSN(fsq, MATCH_FSQ, MASK_FSQ) -DECLARE_INSN(fmadd_q, MATCH_FMADD_Q, MASK_FMADD_Q) -DECLARE_INSN(fmsub_q, MATCH_FMSUB_Q, MASK_FMSUB_Q) -DECLARE_INSN(fnmsub_q, MATCH_FNMSUB_Q, MASK_FNMSUB_Q) -DECLARE_INSN(fnmadd_q, MATCH_FNMADD_Q, MASK_FNMADD_Q) -DECLARE_INSN(fcvt_l_q, MATCH_FCVT_L_Q, MASK_FCVT_L_Q) -DECLARE_INSN(fcvt_lu_q, MATCH_FCVT_LU_Q, MASK_FCVT_LU_Q) -DECLARE_INSN(fcvt_q_l, MATCH_FCVT_Q_L, MASK_FCVT_Q_L) -DECLARE_INSN(fcvt_q_lu, MATCH_FCVT_Q_LU, MASK_FCVT_Q_LU) +DECLARE_INSN(amoswap_w, MATCH_AMOSWAP_W, MASK_AMOSWAP_W) +DECLARE_INSN(amoxor_d, MATCH_AMOXOR_D, MASK_AMOXOR_D) +DECLARE_INSN(amoxor_w, MATCH_AMOXOR_W, MASK_AMOXOR_W) +DECLARE_INSN(and, MATCH_AND, MASK_AND) +DECLARE_INSN(andi, MATCH_ANDI, MASK_ANDI) DECLARE_INSN(andn, MATCH_ANDN, MASK_ANDN) -DECLARE_INSN(orn, MATCH_ORN, MASK_ORN) -DECLARE_INSN(xnor, MATCH_XNOR, MASK_XNOR) -DECLARE_INSN(slo, MATCH_SLO, MASK_SLO) -DECLARE_INSN(sro, MATCH_SRO, MASK_SRO) -DECLARE_INSN(rol, MATCH_ROL, MASK_ROL) -DECLARE_INSN(ror, MATCH_ROR, MASK_ROR) +DECLARE_INSN(auipc, MATCH_AUIPC, MASK_AUIPC) +DECLARE_INSN(ave, MATCH_AVE, MASK_AVE) DECLARE_INSN(bclr, MATCH_BCLR, MASK_BCLR) -DECLARE_INSN(bset, MATCH_BSET, MASK_BSET) -DECLARE_INSN(binv, MATCH_BINV, MASK_BINV) -DECLARE_INSN(bext, MATCH_BEXT, MASK_BEXT) -DECLARE_INSN(gorc, MATCH_GORC, MASK_GORC) -DECLARE_INSN(grev, MATCH_GREV, MASK_GREV) -DECLARE_INSN(sloi, MATCH_SLOI, MASK_SLOI) -DECLARE_INSN(sroi, MATCH_SROI, MASK_SROI) -DECLARE_INSN(rori, MATCH_RORI, MASK_RORI) DECLARE_INSN(bclri, MATCH_BCLRI, MASK_BCLRI) -DECLARE_INSN(bseti, MATCH_BSETI, MASK_BSETI) -DECLARE_INSN(binvi, MATCH_BINVI, MASK_BINVI) +DECLARE_INSN(bcompress, MATCH_BCOMPRESS, MASK_BCOMPRESS) +DECLARE_INSN(bcompressw, MATCH_BCOMPRESSW, MASK_BCOMPRESSW) +DECLARE_INSN(bdecompress, MATCH_BDECOMPRESS, MASK_BDECOMPRESS) +DECLARE_INSN(bdecompressw, MATCH_BDECOMPRESSW, MASK_BDECOMPRESSW) +DECLARE_INSN(beq, MATCH_BEQ, MASK_BEQ) +DECLARE_INSN(bext, MATCH_BEXT, MASK_BEXT) DECLARE_INSN(bexti, MATCH_BEXTI, MASK_BEXTI) -DECLARE_INSN(gorci, MATCH_GORCI, MASK_GORCI) -DECLARE_INSN(grevi, MATCH_GREVI, MASK_GREVI) +DECLARE_INSN(bfp, MATCH_BFP, MASK_BFP) +DECLARE_INSN(bfpw, MATCH_BFPW, MASK_BFPW) +DECLARE_INSN(bge, MATCH_BGE, MASK_BGE) +DECLARE_INSN(bgeu, MATCH_BGEU, MASK_BGEU) +DECLARE_INSN(binv, MATCH_BINV, MASK_BINV) +DECLARE_INSN(binvi, MATCH_BINVI, MASK_BINVI) +DECLARE_INSN(blt, MATCH_BLT, MASK_BLT) +DECLARE_INSN(bltu, MATCH_BLTU, MASK_BLTU) +DECLARE_INSN(bmatflip, MATCH_BMATFLIP, MASK_BMATFLIP) +DECLARE_INSN(bmator, MATCH_BMATOR, MASK_BMATOR) +DECLARE_INSN(bmatxor, MATCH_BMATXOR, MASK_BMATXOR) +DECLARE_INSN(bne, MATCH_BNE, MASK_BNE) +DECLARE_INSN(bset, MATCH_BSET, MASK_BSET) +DECLARE_INSN(bseti, MATCH_BSETI, MASK_BSETI) +DECLARE_INSN(c_add, MATCH_C_ADD, MASK_C_ADD) +DECLARE_INSN(c_addi, MATCH_C_ADDI, MASK_C_ADDI) +DECLARE_INSN(c_addi16sp, MATCH_C_ADDI16SP, MASK_C_ADDI16SP) +DECLARE_INSN(c_addi4spn, MATCH_C_ADDI4SPN, MASK_C_ADDI4SPN) +DECLARE_INSN(c_addiw, MATCH_C_ADDIW, MASK_C_ADDIW) +DECLARE_INSN(c_addw, MATCH_C_ADDW, MASK_C_ADDW) +DECLARE_INSN(c_and, MATCH_C_AND, MASK_C_AND) +DECLARE_INSN(c_andi, MATCH_C_ANDI, MASK_C_ANDI) +DECLARE_INSN(c_beqz, MATCH_C_BEQZ, MASK_C_BEQZ) +DECLARE_INSN(c_bnez, MATCH_C_BNEZ, MASK_C_BNEZ) +DECLARE_INSN(c_ebreak, MATCH_C_EBREAK, MASK_C_EBREAK) +DECLARE_INSN(c_fld, MATCH_C_FLD, MASK_C_FLD) +DECLARE_INSN(c_fldsp, MATCH_C_FLDSP, MASK_C_FLDSP) +DECLARE_INSN(c_flw, MATCH_C_FLW, MASK_C_FLW) +DECLARE_INSN(c_flwsp, MATCH_C_FLWSP, MASK_C_FLWSP) +DECLARE_INSN(c_fsd, MATCH_C_FSD, MASK_C_FSD) +DECLARE_INSN(c_fsdsp, MATCH_C_FSDSP, MASK_C_FSDSP) +DECLARE_INSN(c_fsw, MATCH_C_FSW, MASK_C_FSW) +DECLARE_INSN(c_fswsp, MATCH_C_FSWSP, MASK_C_FSWSP) +DECLARE_INSN(c_j, MATCH_C_J, MASK_C_J) +DECLARE_INSN(c_jal, MATCH_C_JAL, MASK_C_JAL) +DECLARE_INSN(c_jalr, MATCH_C_JALR, MASK_C_JALR) +DECLARE_INSN(c_jr, MATCH_C_JR, MASK_C_JR) +DECLARE_INSN(c_lbu, MATCH_C_LBU, MASK_C_LBU) +DECLARE_INSN(c_ld, MATCH_C_LD, MASK_C_LD) +DECLARE_INSN(c_ldsp, MATCH_C_LDSP, MASK_C_LDSP) +DECLARE_INSN(c_lh, MATCH_C_LH, MASK_C_LH) +DECLARE_INSN(c_lhu, MATCH_C_LHU, MASK_C_LHU) +DECLARE_INSN(c_li, MATCH_C_LI, MASK_C_LI) +DECLARE_INSN(c_lq, MATCH_C_LQ, MASK_C_LQ) +DECLARE_INSN(c_lqsp, MATCH_C_LQSP, MASK_C_LQSP) +DECLARE_INSN(c_lui, MATCH_C_LUI, MASK_C_LUI) +DECLARE_INSN(c_lw, MATCH_C_LW, MASK_C_LW) +DECLARE_INSN(c_lwsp, MATCH_C_LWSP, MASK_C_LWSP) +DECLARE_INSN(c_mul, MATCH_C_MUL, MASK_C_MUL) +DECLARE_INSN(c_mv, MATCH_C_MV, MASK_C_MV) +DECLARE_INSN(c_nop, MATCH_C_NOP, MASK_C_NOP) +DECLARE_INSN(c_not, MATCH_C_NOT, MASK_C_NOT) +DECLARE_INSN(c_or, MATCH_C_OR, MASK_C_OR) +DECLARE_INSN(c_sb, MATCH_C_SB, MASK_C_SB) +DECLARE_INSN(c_sd, MATCH_C_SD, MASK_C_SD) +DECLARE_INSN(c_sdsp, MATCH_C_SDSP, MASK_C_SDSP) +DECLARE_INSN(c_sext_b, MATCH_C_SEXT_B, MASK_C_SEXT_B) +DECLARE_INSN(c_sext_h, MATCH_C_SEXT_H, MASK_C_SEXT_H) +DECLARE_INSN(c_sh, MATCH_C_SH, MASK_C_SH) +DECLARE_INSN(c_slli, MATCH_C_SLLI, MASK_C_SLLI) +DECLARE_INSN(c_sq, MATCH_C_SQ, MASK_C_SQ) +DECLARE_INSN(c_sqsp, MATCH_C_SQSP, MASK_C_SQSP) +DECLARE_INSN(c_srai, MATCH_C_SRAI, MASK_C_SRAI) +DECLARE_INSN(c_srli, MATCH_C_SRLI, MASK_C_SRLI) +DECLARE_INSN(c_sub, MATCH_C_SUB, MASK_C_SUB) +DECLARE_INSN(c_subw, MATCH_C_SUBW, MASK_C_SUBW) +DECLARE_INSN(c_sw, MATCH_C_SW, MASK_C_SW) +DECLARE_INSN(c_swsp, MATCH_C_SWSP, MASK_C_SWSP) +DECLARE_INSN(c_xor, MATCH_C_XOR, MASK_C_XOR) +DECLARE_INSN(c_zext_b, MATCH_C_ZEXT_B, MASK_C_ZEXT_B) +DECLARE_INSN(c_zext_h, MATCH_C_ZEXT_H, MASK_C_ZEXT_H) +DECLARE_INSN(c_zext_w, MATCH_C_ZEXT_W, MASK_C_ZEXT_W) +DECLARE_INSN(cbo_clean, MATCH_CBO_CLEAN, MASK_CBO_CLEAN) +DECLARE_INSN(cbo_flush, MATCH_CBO_FLUSH, MASK_CBO_FLUSH) +DECLARE_INSN(cbo_inval, MATCH_CBO_INVAL, MASK_CBO_INVAL) +DECLARE_INSN(cbo_zero, MATCH_CBO_ZERO, MASK_CBO_ZERO) +DECLARE_INSN(clmul, MATCH_CLMUL, MASK_CLMUL) +DECLARE_INSN(clmulh, MATCH_CLMULH, MASK_CLMULH) +DECLARE_INSN(clmulr, MATCH_CLMULR, MASK_CLMULR) +DECLARE_INSN(clrs16, MATCH_CLRS16, MASK_CLRS16) +DECLARE_INSN(clrs32, MATCH_CLRS32, MASK_CLRS32) +DECLARE_INSN(clrs8, MATCH_CLRS8, MASK_CLRS8) +DECLARE_INSN(clz, MATCH_CLZ, MASK_CLZ) +DECLARE_INSN(clz16, MATCH_CLZ16, MASK_CLZ16) +DECLARE_INSN(clz32, MATCH_CLZ32, MASK_CLZ32) +DECLARE_INSN(clz8, MATCH_CLZ8, MASK_CLZ8) +DECLARE_INSN(clzw, MATCH_CLZW, MASK_CLZW) +DECLARE_INSN(cm_jalt, MATCH_CM_JALT, MASK_CM_JALT) +DECLARE_INSN(cm_mva01s, MATCH_CM_MVA01S, MASK_CM_MVA01S) +DECLARE_INSN(cm_mvsa01, MATCH_CM_MVSA01, MASK_CM_MVSA01) +DECLARE_INSN(cm_pop, MATCH_CM_POP, MASK_CM_POP) +DECLARE_INSN(cm_popret, MATCH_CM_POPRET, MASK_CM_POPRET) +DECLARE_INSN(cm_popretz, MATCH_CM_POPRETZ, MASK_CM_POPRETZ) +DECLARE_INSN(cm_push, MATCH_CM_PUSH, MASK_CM_PUSH) DECLARE_INSN(cmix, MATCH_CMIX, MASK_CMIX) DECLARE_INSN(cmov, MATCH_CMOV, MASK_CMOV) -DECLARE_INSN(fsl, MATCH_FSL, MASK_FSL) -DECLARE_INSN(fsr, MATCH_FSR, MASK_FSR) -DECLARE_INSN(fsri, MATCH_FSRI, MASK_FSRI) -DECLARE_INSN(clz, MATCH_CLZ, MASK_CLZ) -DECLARE_INSN(ctz, MATCH_CTZ, MASK_CTZ) +DECLARE_INSN(cmpeq16, MATCH_CMPEQ16, MASK_CMPEQ16) +DECLARE_INSN(cmpeq8, MATCH_CMPEQ8, MASK_CMPEQ8) DECLARE_INSN(cpop, MATCH_CPOP, MASK_CPOP) -DECLARE_INSN(sext_b, MATCH_SEXT_B, MASK_SEXT_B) -DECLARE_INSN(sext_h, MATCH_SEXT_H, MASK_SEXT_H) +DECLARE_INSN(cpopw, MATCH_CPOPW, MASK_CPOPW) +DECLARE_INSN(cras16, MATCH_CRAS16, MASK_CRAS16) +DECLARE_INSN(cras32, MATCH_CRAS32, MASK_CRAS32) DECLARE_INSN(crc32_b, MATCH_CRC32_B, MASK_CRC32_B) +DECLARE_INSN(crc32_d, MATCH_CRC32_D, MASK_CRC32_D) DECLARE_INSN(crc32_h, MATCH_CRC32_H, MASK_CRC32_H) DECLARE_INSN(crc32_w, MATCH_CRC32_W, MASK_CRC32_W) DECLARE_INSN(crc32c_b, MATCH_CRC32C_B, MASK_CRC32C_B) +DECLARE_INSN(crc32c_d, MATCH_CRC32C_D, MASK_CRC32C_D) DECLARE_INSN(crc32c_h, MATCH_CRC32C_H, MASK_CRC32C_H) DECLARE_INSN(crc32c_w, MATCH_CRC32C_W, MASK_CRC32C_W) -DECLARE_INSN(sh1add, MATCH_SH1ADD, MASK_SH1ADD) -DECLARE_INSN(sh2add, MATCH_SH2ADD, MASK_SH2ADD) -DECLARE_INSN(sh3add, MATCH_SH3ADD, MASK_SH3ADD) -DECLARE_INSN(clmul, MATCH_CLMUL, MASK_CLMUL) -DECLARE_INSN(clmulr, MATCH_CLMULR, MASK_CLMULR) -DECLARE_INSN(clmulh, MATCH_CLMULH, MASK_CLMULH) -DECLARE_INSN(min, MATCH_MIN, MASK_MIN) -DECLARE_INSN(minu, MATCH_MINU, MASK_MINU) -DECLARE_INSN(max, MATCH_MAX, MASK_MAX) -DECLARE_INSN(maxu, MATCH_MAXU, MASK_MAXU) -DECLARE_INSN(shfl, MATCH_SHFL, MASK_SHFL) -DECLARE_INSN(unshfl, MATCH_UNSHFL, MASK_UNSHFL) -DECLARE_INSN(bcompress, MATCH_BCOMPRESS, MASK_BCOMPRESS) -DECLARE_INSN(bdecompress, MATCH_BDECOMPRESS, MASK_BDECOMPRESS) -DECLARE_INSN(pack, MATCH_PACK, MASK_PACK) -DECLARE_INSN(packu, MATCH_PACKU, MASK_PACKU) -DECLARE_INSN(packh, MATCH_PACKH, MASK_PACKH) -DECLARE_INSN(bfp, MATCH_BFP, MASK_BFP) -DECLARE_INSN(shfli, MATCH_SHFLI, MASK_SHFLI) -DECLARE_INSN(unshfli, MATCH_UNSHFLI, MASK_UNSHFLI) -DECLARE_INSN(xperm4, MATCH_XPERM4, MASK_XPERM4) -DECLARE_INSN(xperm8, MATCH_XPERM8, MASK_XPERM8) -DECLARE_INSN(xperm16, MATCH_XPERM16, MASK_XPERM16) -DECLARE_INSN(bmatflip, MATCH_BMATFLIP, MASK_BMATFLIP) -DECLARE_INSN(crc32_d, MATCH_CRC32_D, MASK_CRC32_D) -DECLARE_INSN(crc32c_d, MATCH_CRC32C_D, MASK_CRC32C_D) -DECLARE_INSN(bmator, MATCH_BMATOR, MASK_BMATOR) -DECLARE_INSN(bmatxor, MATCH_BMATXOR, MASK_BMATXOR) -DECLARE_INSN(slli_uw, MATCH_SLLI_UW, MASK_SLLI_UW) -DECLARE_INSN(add_uw, MATCH_ADD_UW, MASK_ADD_UW) -DECLARE_INSN(slow, MATCH_SLOW, MASK_SLOW) -DECLARE_INSN(srow, MATCH_SROW, MASK_SROW) -DECLARE_INSN(rolw, MATCH_ROLW, MASK_ROLW) -DECLARE_INSN(rorw, MATCH_RORW, MASK_RORW) -DECLARE_INSN(sbclrw, MATCH_SBCLRW, MASK_SBCLRW) -DECLARE_INSN(sbsetw, MATCH_SBSETW, MASK_SBSETW) -DECLARE_INSN(sbinvw, MATCH_SBINVW, MASK_SBINVW) -DECLARE_INSN(sbextw, MATCH_SBEXTW, MASK_SBEXTW) -DECLARE_INSN(gorcw, MATCH_GORCW, MASK_GORCW) -DECLARE_INSN(grevw, MATCH_GREVW, MASK_GREVW) -DECLARE_INSN(sloiw, MATCH_SLOIW, MASK_SLOIW) -DECLARE_INSN(sroiw, MATCH_SROIW, MASK_SROIW) -DECLARE_INSN(roriw, MATCH_RORIW, MASK_RORIW) -DECLARE_INSN(sbclriw, MATCH_SBCLRIW, MASK_SBCLRIW) -DECLARE_INSN(sbsetiw, MATCH_SBSETIW, MASK_SBSETIW) -DECLARE_INSN(sbinviw, MATCH_SBINVIW, MASK_SBINVIW) -DECLARE_INSN(gorciw, MATCH_GORCIW, MASK_GORCIW) -DECLARE_INSN(greviw, MATCH_GREVIW, MASK_GREVIW) -DECLARE_INSN(fslw, MATCH_FSLW, MASK_FSLW) -DECLARE_INSN(fsrw, MATCH_FSRW, MASK_FSRW) -DECLARE_INSN(fsriw, MATCH_FSRIW, MASK_FSRIW) -DECLARE_INSN(clzw, MATCH_CLZW, MASK_CLZW) -DECLARE_INSN(ctzw, MATCH_CTZW, MASK_CTZW) -DECLARE_INSN(cpopw, MATCH_CPOPW, MASK_CPOPW) -DECLARE_INSN(sh1add_uw, MATCH_SH1ADD_UW, MASK_SH1ADD_UW) -DECLARE_INSN(sh2add_uw, MATCH_SH2ADD_UW, MASK_SH2ADD_UW) -DECLARE_INSN(sh3add_uw, MATCH_SH3ADD_UW, MASK_SH3ADD_UW) -DECLARE_INSN(shflw, MATCH_SHFLW, MASK_SHFLW) -DECLARE_INSN(unshflw, MATCH_UNSHFLW, MASK_UNSHFLW) -DECLARE_INSN(bcompressw, MATCH_BCOMPRESSW, MASK_BCOMPRESSW) -DECLARE_INSN(bdecompressw, MATCH_BDECOMPRESSW, MASK_BDECOMPRESSW) -DECLARE_INSN(packw, MATCH_PACKW, MASK_PACKW) -DECLARE_INSN(packuw, MATCH_PACKUW, MASK_PACKUW) -DECLARE_INSN(bfpw, MATCH_BFPW, MASK_BFPW) -DECLARE_INSN(xperm32, MATCH_XPERM32, MASK_XPERM32) -DECLARE_INSN(ecall, MATCH_ECALL, MASK_ECALL) -DECLARE_INSN(ebreak, MATCH_EBREAK, MASK_EBREAK) -DECLARE_INSN(sret, MATCH_SRET, MASK_SRET) -DECLARE_INSN(mret, MATCH_MRET, MASK_MRET) -DECLARE_INSN(dret, MATCH_DRET, MASK_DRET) -DECLARE_INSN(sfence_vma, MATCH_SFENCE_VMA, MASK_SFENCE_VMA) -DECLARE_INSN(wfi, MATCH_WFI, MASK_WFI) -DECLARE_INSN(csrrw, MATCH_CSRRW, MASK_CSRRW) -DECLARE_INSN(csrrs, MATCH_CSRRS, MASK_CSRRS) +DECLARE_INSN(crsa16, MATCH_CRSA16, MASK_CRSA16) +DECLARE_INSN(crsa32, MATCH_CRSA32, MASK_CRSA32) DECLARE_INSN(csrrc, MATCH_CSRRC, MASK_CSRRC) -DECLARE_INSN(csrrwi, MATCH_CSRRWI, MASK_CSRRWI) -DECLARE_INSN(csrrsi, MATCH_CSRRSI, MASK_CSRRSI) DECLARE_INSN(csrrci, MATCH_CSRRCI, MASK_CSRRCI) -DECLARE_INSN(sinval_vma, MATCH_SINVAL_VMA, MASK_SINVAL_VMA) -DECLARE_INSN(sfence_w_inval, MATCH_SFENCE_W_INVAL, MASK_SFENCE_W_INVAL) -DECLARE_INSN(sfence_inval_ir, MATCH_SFENCE_INVAL_IR, MASK_SFENCE_INVAL_IR) -DECLARE_INSN(hinval_vvma, MATCH_HINVAL_VVMA, MASK_HINVAL_VVMA) -DECLARE_INSN(hinval_gvma, MATCH_HINVAL_GVMA, MASK_HINVAL_GVMA) +DECLARE_INSN(csrrs, MATCH_CSRRS, MASK_CSRRS) +DECLARE_INSN(csrrsi, MATCH_CSRRSI, MASK_CSRRSI) +DECLARE_INSN(csrrw, MATCH_CSRRW, MASK_CSRRW) +DECLARE_INSN(csrrwi, MATCH_CSRRWI, MASK_CSRRWI) +DECLARE_INSN(ctz, MATCH_CTZ, MASK_CTZ) +DECLARE_INSN(ctzw, MATCH_CTZW, MASK_CTZW) +DECLARE_INSN(czero_eqz, MATCH_CZERO_EQZ, MASK_CZERO_EQZ) +DECLARE_INSN(czero_nez, MATCH_CZERO_NEZ, MASK_CZERO_NEZ) +DECLARE_INSN(div, MATCH_DIV, MASK_DIV) +DECLARE_INSN(divu, MATCH_DIVU, MASK_DIVU) +DECLARE_INSN(divuw, MATCH_DIVUW, MASK_DIVUW) +DECLARE_INSN(divw, MATCH_DIVW, MASK_DIVW) +DECLARE_INSN(dret, MATCH_DRET, MASK_DRET) +DECLARE_INSN(ebreak, MATCH_EBREAK, MASK_EBREAK) +DECLARE_INSN(ecall, MATCH_ECALL, MASK_ECALL) +DECLARE_INSN(fadd_d, MATCH_FADD_D, MASK_FADD_D) DECLARE_INSN(fadd_h, MATCH_FADD_H, MASK_FADD_H) -DECLARE_INSN(fsub_h, MATCH_FSUB_H, MASK_FSUB_H) -DECLARE_INSN(fmul_h, MATCH_FMUL_H, MASK_FMUL_H) -DECLARE_INSN(fdiv_h, MATCH_FDIV_H, MASK_FDIV_H) -DECLARE_INSN(fsgnj_h, MATCH_FSGNJ_H, MASK_FSGNJ_H) -DECLARE_INSN(fsgnjn_h, MATCH_FSGNJN_H, MASK_FSGNJN_H) -DECLARE_INSN(fsgnjx_h, MATCH_FSGNJX_H, MASK_FSGNJX_H) -DECLARE_INSN(fmin_h, MATCH_FMIN_H, MASK_FMIN_H) -DECLARE_INSN(fmax_h, MATCH_FMAX_H, MASK_FMAX_H) -DECLARE_INSN(fcvt_h_s, MATCH_FCVT_H_S, MASK_FCVT_H_S) -DECLARE_INSN(fcvt_s_h, MATCH_FCVT_S_H, MASK_FCVT_S_H) -DECLARE_INSN(fsqrt_h, MATCH_FSQRT_H, MASK_FSQRT_H) -DECLARE_INSN(fle_h, MATCH_FLE_H, MASK_FLE_H) -DECLARE_INSN(flt_h, MATCH_FLT_H, MASK_FLT_H) -DECLARE_INSN(feq_h, MATCH_FEQ_H, MASK_FEQ_H) -DECLARE_INSN(fcvt_w_h, MATCH_FCVT_W_H, MASK_FCVT_W_H) -DECLARE_INSN(fcvt_wu_h, MATCH_FCVT_WU_H, MASK_FCVT_WU_H) -DECLARE_INSN(fmv_x_h, MATCH_FMV_X_H, MASK_FMV_X_H) +DECLARE_INSN(fadd_q, MATCH_FADD_Q, MASK_FADD_Q) +DECLARE_INSN(fadd_s, MATCH_FADD_S, MASK_FADD_S) +DECLARE_INSN(fclass_d, MATCH_FCLASS_D, MASK_FCLASS_D) DECLARE_INSN(fclass_h, MATCH_FCLASS_H, MASK_FCLASS_H) -DECLARE_INSN(fcvt_h_w, MATCH_FCVT_H_W, MASK_FCVT_H_W) -DECLARE_INSN(fcvt_h_wu, MATCH_FCVT_H_WU, MASK_FCVT_H_WU) -DECLARE_INSN(fmv_h_x, MATCH_FMV_H_X, MASK_FMV_H_X) -DECLARE_INSN(flh, MATCH_FLH, MASK_FLH) -DECLARE_INSN(fsh, MATCH_FSH, MASK_FSH) -DECLARE_INSN(fmadd_h, MATCH_FMADD_H, MASK_FMADD_H) -DECLARE_INSN(fmsub_h, MATCH_FMSUB_H, MASK_FMSUB_H) -DECLARE_INSN(fnmsub_h, MATCH_FNMSUB_H, MASK_FNMSUB_H) -DECLARE_INSN(fnmadd_h, MATCH_FNMADD_H, MASK_FNMADD_H) -DECLARE_INSN(fcvt_h_d, MATCH_FCVT_H_D, MASK_FCVT_H_D) +DECLARE_INSN(fclass_q, MATCH_FCLASS_Q, MASK_FCLASS_Q) +DECLARE_INSN(fclass_s, MATCH_FCLASS_S, MASK_FCLASS_S) DECLARE_INSN(fcvt_d_h, MATCH_FCVT_D_H, MASK_FCVT_D_H) -DECLARE_INSN(fcvt_h_q, MATCH_FCVT_H_Q, MASK_FCVT_H_Q) -DECLARE_INSN(fcvt_q_h, MATCH_FCVT_Q_H, MASK_FCVT_Q_H) -DECLARE_INSN(fcvt_l_h, MATCH_FCVT_L_H, MASK_FCVT_L_H) -DECLARE_INSN(fcvt_lu_h, MATCH_FCVT_LU_H, MASK_FCVT_LU_H) +DECLARE_INSN(fcvt_d_l, MATCH_FCVT_D_L, MASK_FCVT_D_L) +DECLARE_INSN(fcvt_d_lu, MATCH_FCVT_D_LU, MASK_FCVT_D_LU) +DECLARE_INSN(fcvt_d_q, MATCH_FCVT_D_Q, MASK_FCVT_D_Q) +DECLARE_INSN(fcvt_d_s, MATCH_FCVT_D_S, MASK_FCVT_D_S) +DECLARE_INSN(fcvt_d_w, MATCH_FCVT_D_W, MASK_FCVT_D_W) +DECLARE_INSN(fcvt_d_wu, MATCH_FCVT_D_WU, MASK_FCVT_D_WU) +DECLARE_INSN(fcvt_h_d, MATCH_FCVT_H_D, MASK_FCVT_H_D) DECLARE_INSN(fcvt_h_l, MATCH_FCVT_H_L, MASK_FCVT_H_L) DECLARE_INSN(fcvt_h_lu, MATCH_FCVT_H_LU, MASK_FCVT_H_LU) -DECLARE_INSN(sm4ed, MATCH_SM4ED, MASK_SM4ED) -DECLARE_INSN(sm4ks, MATCH_SM4KS, MASK_SM4KS) -DECLARE_INSN(sm3p0, MATCH_SM3P0, MASK_SM3P0) -DECLARE_INSN(sm3p1, MATCH_SM3P1, MASK_SM3P1) -DECLARE_INSN(sha256sum0, MATCH_SHA256SUM0, MASK_SHA256SUM0) -DECLARE_INSN(sha256sum1, MATCH_SHA256SUM1, MASK_SHA256SUM1) -DECLARE_INSN(sha256sig0, MATCH_SHA256SIG0, MASK_SHA256SIG0) -DECLARE_INSN(sha256sig1, MATCH_SHA256SIG1, MASK_SHA256SIG1) -DECLARE_INSN(aes32esmi, MATCH_AES32ESMI, MASK_AES32ESMI) -DECLARE_INSN(aes32esi, MATCH_AES32ESI, MASK_AES32ESI) -DECLARE_INSN(aes32dsmi, MATCH_AES32DSMI, MASK_AES32DSMI) -DECLARE_INSN(aes32dsi, MATCH_AES32DSI, MASK_AES32DSI) -DECLARE_INSN(sha512sum0r, MATCH_SHA512SUM0R, MASK_SHA512SUM0R) -DECLARE_INSN(sha512sum1r, MATCH_SHA512SUM1R, MASK_SHA512SUM1R) -DECLARE_INSN(sha512sig0l, MATCH_SHA512SIG0L, MASK_SHA512SIG0L) -DECLARE_INSN(sha512sig0h, MATCH_SHA512SIG0H, MASK_SHA512SIG0H) -DECLARE_INSN(sha512sig1l, MATCH_SHA512SIG1L, MASK_SHA512SIG1L) -DECLARE_INSN(sha512sig1h, MATCH_SHA512SIG1H, MASK_SHA512SIG1H) -DECLARE_INSN(aes64ks1i, MATCH_AES64KS1I, MASK_AES64KS1I) -DECLARE_INSN(aes64im, MATCH_AES64IM, MASK_AES64IM) -DECLARE_INSN(aes64ks2, MATCH_AES64KS2, MASK_AES64KS2) -DECLARE_INSN(aes64esm, MATCH_AES64ESM, MASK_AES64ESM) -DECLARE_INSN(aes64es, MATCH_AES64ES, MASK_AES64ES) -DECLARE_INSN(aes64dsm, MATCH_AES64DSM, MASK_AES64DSM) -DECLARE_INSN(aes64ds, MATCH_AES64DS, MASK_AES64DS) -DECLARE_INSN(sha512sum0, MATCH_SHA512SUM0, MASK_SHA512SUM0) -DECLARE_INSN(sha512sum1, MATCH_SHA512SUM1, MASK_SHA512SUM1) -DECLARE_INSN(sha512sig0, MATCH_SHA512SIG0, MASK_SHA512SIG0) -DECLARE_INSN(sha512sig1, MATCH_SHA512SIG1, MASK_SHA512SIG1) -DECLARE_INSN(c_nop, MATCH_C_NOP, MASK_C_NOP) -DECLARE_INSN(c_addi16sp, MATCH_C_ADDI16SP, MASK_C_ADDI16SP) -DECLARE_INSN(c_jr, MATCH_C_JR, MASK_C_JR) -DECLARE_INSN(c_jalr, MATCH_C_JALR, MASK_C_JALR) -DECLARE_INSN(c_ebreak, MATCH_C_EBREAK, MASK_C_EBREAK) -DECLARE_INSN(c_addi4spn, MATCH_C_ADDI4SPN, MASK_C_ADDI4SPN) -DECLARE_INSN(c_fld, MATCH_C_FLD, MASK_C_FLD) -DECLARE_INSN(c_lw, MATCH_C_LW, MASK_C_LW) -DECLARE_INSN(c_flw, MATCH_C_FLW, MASK_C_FLW) -DECLARE_INSN(c_fsd, MATCH_C_FSD, MASK_C_FSD) -DECLARE_INSN(c_sw, MATCH_C_SW, MASK_C_SW) -DECLARE_INSN(c_fsw, MATCH_C_FSW, MASK_C_FSW) -DECLARE_INSN(c_addi, MATCH_C_ADDI, MASK_C_ADDI) -DECLARE_INSN(c_jal, MATCH_C_JAL, MASK_C_JAL) -DECLARE_INSN(c_li, MATCH_C_LI, MASK_C_LI) -DECLARE_INSN(c_lui, MATCH_C_LUI, MASK_C_LUI) -DECLARE_INSN(c_srli, MATCH_C_SRLI, MASK_C_SRLI) -DECLARE_INSN(c_srai, MATCH_C_SRAI, MASK_C_SRAI) -DECLARE_INSN(c_andi, MATCH_C_ANDI, MASK_C_ANDI) -DECLARE_INSN(c_sub, MATCH_C_SUB, MASK_C_SUB) -DECLARE_INSN(c_xor, MATCH_C_XOR, MASK_C_XOR) -DECLARE_INSN(c_or, MATCH_C_OR, MASK_C_OR) -DECLARE_INSN(c_and, MATCH_C_AND, MASK_C_AND) -DECLARE_INSN(c_j, MATCH_C_J, MASK_C_J) -DECLARE_INSN(c_beqz, MATCH_C_BEQZ, MASK_C_BEQZ) -DECLARE_INSN(c_bnez, MATCH_C_BNEZ, MASK_C_BNEZ) -DECLARE_INSN(c_slli, MATCH_C_SLLI, MASK_C_SLLI) -DECLARE_INSN(c_fldsp, MATCH_C_FLDSP, MASK_C_FLDSP) -DECLARE_INSN(c_lwsp, MATCH_C_LWSP, MASK_C_LWSP) -DECLARE_INSN(c_flwsp, MATCH_C_FLWSP, MASK_C_FLWSP) -DECLARE_INSN(c_mv, MATCH_C_MV, MASK_C_MV) -DECLARE_INSN(c_add, MATCH_C_ADD, MASK_C_ADD) -DECLARE_INSN(c_fsdsp, MATCH_C_FSDSP, MASK_C_FSDSP) -DECLARE_INSN(c_swsp, MATCH_C_SWSP, MASK_C_SWSP) -DECLARE_INSN(c_fswsp, MATCH_C_FSWSP, MASK_C_FSWSP) -DECLARE_INSN(c_srli_rv32, MATCH_C_SRLI_RV32, MASK_C_SRLI_RV32) -DECLARE_INSN(c_srai_rv32, MATCH_C_SRAI_RV32, MASK_C_SRAI_RV32) -DECLARE_INSN(c_slli_rv32, MATCH_C_SLLI_RV32, MASK_C_SLLI_RV32) -DECLARE_INSN(c_ld, MATCH_C_LD, MASK_C_LD) -DECLARE_INSN(c_sd, MATCH_C_SD, MASK_C_SD) -DECLARE_INSN(c_subw, MATCH_C_SUBW, MASK_C_SUBW) -DECLARE_INSN(c_addw, MATCH_C_ADDW, MASK_C_ADDW) -DECLARE_INSN(c_addiw, MATCH_C_ADDIW, MASK_C_ADDIW) -DECLARE_INSN(c_ldsp, MATCH_C_LDSP, MASK_C_LDSP) -DECLARE_INSN(c_sdsp, MATCH_C_SDSP, MASK_C_SDSP) -DECLARE_INSN(custom0, MATCH_CUSTOM0, MASK_CUSTOM0) -DECLARE_INSN(custom0_rs1, MATCH_CUSTOM0_RS1, MASK_CUSTOM0_RS1) -DECLARE_INSN(custom0_rs1_rs2, MATCH_CUSTOM0_RS1_RS2, MASK_CUSTOM0_RS1_RS2) -DECLARE_INSN(custom0_rd, MATCH_CUSTOM0_RD, MASK_CUSTOM0_RD) -DECLARE_INSN(custom0_rd_rs1, MATCH_CUSTOM0_RD_RS1, MASK_CUSTOM0_RD_RS1) -DECLARE_INSN(custom0_rd_rs1_rs2, MATCH_CUSTOM0_RD_RS1_RS2, MASK_CUSTOM0_RD_RS1_RS2) -DECLARE_INSN(custom1, MATCH_CUSTOM1, MASK_CUSTOM1) -DECLARE_INSN(custom1_rs1, MATCH_CUSTOM1_RS1, MASK_CUSTOM1_RS1) -DECLARE_INSN(custom1_rs1_rs2, MATCH_CUSTOM1_RS1_RS2, MASK_CUSTOM1_RS1_RS2) -DECLARE_INSN(custom1_rd, MATCH_CUSTOM1_RD, MASK_CUSTOM1_RD) -DECLARE_INSN(custom1_rd_rs1, MATCH_CUSTOM1_RD_RS1, MASK_CUSTOM1_RD_RS1) -DECLARE_INSN(custom1_rd_rs1_rs2, MATCH_CUSTOM1_RD_RS1_RS2, MASK_CUSTOM1_RD_RS1_RS2) -DECLARE_INSN(custom2, MATCH_CUSTOM2, MASK_CUSTOM2) -DECLARE_INSN(custom2_rs1, MATCH_CUSTOM2_RS1, MASK_CUSTOM2_RS1) -DECLARE_INSN(custom2_rs1_rs2, MATCH_CUSTOM2_RS1_RS2, MASK_CUSTOM2_RS1_RS2) -DECLARE_INSN(custom2_rd, MATCH_CUSTOM2_RD, MASK_CUSTOM2_RD) -DECLARE_INSN(custom2_rd_rs1, MATCH_CUSTOM2_RD_RS1, MASK_CUSTOM2_RD_RS1) -DECLARE_INSN(custom2_rd_rs1_rs2, MATCH_CUSTOM2_RD_RS1_RS2, MASK_CUSTOM2_RD_RS1_RS2) -DECLARE_INSN(custom3, MATCH_CUSTOM3, MASK_CUSTOM3) -DECLARE_INSN(custom3_rs1, MATCH_CUSTOM3_RS1, MASK_CUSTOM3_RS1) -DECLARE_INSN(custom3_rs1_rs2, MATCH_CUSTOM3_RS1_RS2, MASK_CUSTOM3_RS1_RS2) -DECLARE_INSN(custom3_rd, MATCH_CUSTOM3_RD, MASK_CUSTOM3_RD) -DECLARE_INSN(custom3_rd_rs1, MATCH_CUSTOM3_RD_RS1, MASK_CUSTOM3_RD_RS1) -DECLARE_INSN(custom3_rd_rs1_rs2, MATCH_CUSTOM3_RD_RS1_RS2, MASK_CUSTOM3_RD_RS1_RS2) -DECLARE_INSN(vsetivli, MATCH_VSETIVLI, MASK_VSETIVLI) -DECLARE_INSN(vsetvli, MATCH_VSETVLI, MASK_VSETVLI) -DECLARE_INSN(vsetvl, MATCH_VSETVL, MASK_VSETVL) -DECLARE_INSN(vlm_v, MATCH_VLM_V, MASK_VLM_V) -DECLARE_INSN(vsm_v, MATCH_VSM_V, MASK_VSM_V) -DECLARE_INSN(vle8_v, MATCH_VLE8_V, MASK_VLE8_V) -DECLARE_INSN(vle16_v, MATCH_VLE16_V, MASK_VLE16_V) -DECLARE_INSN(vle32_v, MATCH_VLE32_V, MASK_VLE32_V) -DECLARE_INSN(vle64_v, MATCH_VLE64_V, MASK_VLE64_V) -DECLARE_INSN(vle128_v, MATCH_VLE128_V, MASK_VLE128_V) -DECLARE_INSN(vle256_v, MATCH_VLE256_V, MASK_VLE256_V) -DECLARE_INSN(vle512_v, MATCH_VLE512_V, MASK_VLE512_V) -DECLARE_INSN(vle1024_v, MATCH_VLE1024_V, MASK_VLE1024_V) -DECLARE_INSN(vse8_v, MATCH_VSE8_V, MASK_VSE8_V) -DECLARE_INSN(vse16_v, MATCH_VSE16_V, MASK_VSE16_V) -DECLARE_INSN(vse32_v, MATCH_VSE32_V, MASK_VSE32_V) -DECLARE_INSN(vse64_v, MATCH_VSE64_V, MASK_VSE64_V) -DECLARE_INSN(vse128_v, MATCH_VSE128_V, MASK_VSE128_V) -DECLARE_INSN(vse256_v, MATCH_VSE256_V, MASK_VSE256_V) -DECLARE_INSN(vse512_v, MATCH_VSE512_V, MASK_VSE512_V) -DECLARE_INSN(vse1024_v, MATCH_VSE1024_V, MASK_VSE1024_V) -DECLARE_INSN(vluxei8_v, MATCH_VLUXEI8_V, MASK_VLUXEI8_V) -DECLARE_INSN(vluxei16_v, MATCH_VLUXEI16_V, MASK_VLUXEI16_V) -DECLARE_INSN(vluxei32_v, MATCH_VLUXEI32_V, MASK_VLUXEI32_V) -DECLARE_INSN(vluxei64_v, MATCH_VLUXEI64_V, MASK_VLUXEI64_V) -DECLARE_INSN(vluxei128_v, MATCH_VLUXEI128_V, MASK_VLUXEI128_V) -DECLARE_INSN(vluxei256_v, MATCH_VLUXEI256_V, MASK_VLUXEI256_V) -DECLARE_INSN(vluxei512_v, MATCH_VLUXEI512_V, MASK_VLUXEI512_V) -DECLARE_INSN(vluxei1024_v, MATCH_VLUXEI1024_V, MASK_VLUXEI1024_V) -DECLARE_INSN(vsuxei8_v, MATCH_VSUXEI8_V, MASK_VSUXEI8_V) -DECLARE_INSN(vsuxei16_v, MATCH_VSUXEI16_V, MASK_VSUXEI16_V) -DECLARE_INSN(vsuxei32_v, MATCH_VSUXEI32_V, MASK_VSUXEI32_V) -DECLARE_INSN(vsuxei64_v, MATCH_VSUXEI64_V, MASK_VSUXEI64_V) -DECLARE_INSN(vsuxei128_v, MATCH_VSUXEI128_V, MASK_VSUXEI128_V) -DECLARE_INSN(vsuxei256_v, MATCH_VSUXEI256_V, MASK_VSUXEI256_V) -DECLARE_INSN(vsuxei512_v, MATCH_VSUXEI512_V, MASK_VSUXEI512_V) -DECLARE_INSN(vsuxei1024_v, MATCH_VSUXEI1024_V, MASK_VSUXEI1024_V) -DECLARE_INSN(vlse8_v, MATCH_VLSE8_V, MASK_VLSE8_V) -DECLARE_INSN(vlse16_v, MATCH_VLSE16_V, MASK_VLSE16_V) -DECLARE_INSN(vlse32_v, MATCH_VLSE32_V, MASK_VLSE32_V) -DECLARE_INSN(vlse64_v, MATCH_VLSE64_V, MASK_VLSE64_V) -DECLARE_INSN(vlse128_v, MATCH_VLSE128_V, MASK_VLSE128_V) -DECLARE_INSN(vlse256_v, MATCH_VLSE256_V, MASK_VLSE256_V) -DECLARE_INSN(vlse512_v, MATCH_VLSE512_V, MASK_VLSE512_V) -DECLARE_INSN(vlse1024_v, MATCH_VLSE1024_V, MASK_VLSE1024_V) -DECLARE_INSN(vsse8_v, MATCH_VSSE8_V, MASK_VSSE8_V) -DECLARE_INSN(vsse16_v, MATCH_VSSE16_V, MASK_VSSE16_V) -DECLARE_INSN(vsse32_v, MATCH_VSSE32_V, MASK_VSSE32_V) -DECLARE_INSN(vsse64_v, MATCH_VSSE64_V, MASK_VSSE64_V) -DECLARE_INSN(vsse128_v, MATCH_VSSE128_V, MASK_VSSE128_V) -DECLARE_INSN(vsse256_v, MATCH_VSSE256_V, MASK_VSSE256_V) -DECLARE_INSN(vsse512_v, MATCH_VSSE512_V, MASK_VSSE512_V) -DECLARE_INSN(vsse1024_v, MATCH_VSSE1024_V, MASK_VSSE1024_V) -DECLARE_INSN(vloxei8_v, MATCH_VLOXEI8_V, MASK_VLOXEI8_V) -DECLARE_INSN(vloxei16_v, MATCH_VLOXEI16_V, MASK_VLOXEI16_V) -DECLARE_INSN(vloxei32_v, MATCH_VLOXEI32_V, MASK_VLOXEI32_V) -DECLARE_INSN(vloxei64_v, MATCH_VLOXEI64_V, MASK_VLOXEI64_V) -DECLARE_INSN(vloxei128_v, MATCH_VLOXEI128_V, MASK_VLOXEI128_V) -DECLARE_INSN(vloxei256_v, MATCH_VLOXEI256_V, MASK_VLOXEI256_V) -DECLARE_INSN(vloxei512_v, MATCH_VLOXEI512_V, MASK_VLOXEI512_V) -DECLARE_INSN(vloxei1024_v, MATCH_VLOXEI1024_V, MASK_VLOXEI1024_V) -DECLARE_INSN(vsoxei8_v, MATCH_VSOXEI8_V, MASK_VSOXEI8_V) -DECLARE_INSN(vsoxei16_v, MATCH_VSOXEI16_V, MASK_VSOXEI16_V) -DECLARE_INSN(vsoxei32_v, MATCH_VSOXEI32_V, MASK_VSOXEI32_V) -DECLARE_INSN(vsoxei64_v, MATCH_VSOXEI64_V, MASK_VSOXEI64_V) -DECLARE_INSN(vsoxei128_v, MATCH_VSOXEI128_V, MASK_VSOXEI128_V) -DECLARE_INSN(vsoxei256_v, MATCH_VSOXEI256_V, MASK_VSOXEI256_V) -DECLARE_INSN(vsoxei512_v, MATCH_VSOXEI512_V, MASK_VSOXEI512_V) -DECLARE_INSN(vsoxei1024_v, MATCH_VSOXEI1024_V, MASK_VSOXEI1024_V) -DECLARE_INSN(vle8ff_v, MATCH_VLE8FF_V, MASK_VLE8FF_V) -DECLARE_INSN(vle16ff_v, MATCH_VLE16FF_V, MASK_VLE16FF_V) -DECLARE_INSN(vle32ff_v, MATCH_VLE32FF_V, MASK_VLE32FF_V) -DECLARE_INSN(vle64ff_v, MATCH_VLE64FF_V, MASK_VLE64FF_V) -DECLARE_INSN(vle128ff_v, MATCH_VLE128FF_V, MASK_VLE128FF_V) -DECLARE_INSN(vle256ff_v, MATCH_VLE256FF_V, MASK_VLE256FF_V) -DECLARE_INSN(vle512ff_v, MATCH_VLE512FF_V, MASK_VLE512FF_V) -DECLARE_INSN(vle1024ff_v, MATCH_VLE1024FF_V, MASK_VLE1024FF_V) -DECLARE_INSN(vl1re8_v, MATCH_VL1RE8_V, MASK_VL1RE8_V) -DECLARE_INSN(vl1re16_v, MATCH_VL1RE16_V, MASK_VL1RE16_V) -DECLARE_INSN(vl1re32_v, MATCH_VL1RE32_V, MASK_VL1RE32_V) -DECLARE_INSN(vl1re64_v, MATCH_VL1RE64_V, MASK_VL1RE64_V) -DECLARE_INSN(vl2re8_v, MATCH_VL2RE8_V, MASK_VL2RE8_V) -DECLARE_INSN(vl2re16_v, MATCH_VL2RE16_V, MASK_VL2RE16_V) -DECLARE_INSN(vl2re32_v, MATCH_VL2RE32_V, MASK_VL2RE32_V) -DECLARE_INSN(vl2re64_v, MATCH_VL2RE64_V, MASK_VL2RE64_V) -DECLARE_INSN(vl4re8_v, MATCH_VL4RE8_V, MASK_VL4RE8_V) -DECLARE_INSN(vl4re16_v, MATCH_VL4RE16_V, MASK_VL4RE16_V) -DECLARE_INSN(vl4re32_v, MATCH_VL4RE32_V, MASK_VL4RE32_V) -DECLARE_INSN(vl4re64_v, MATCH_VL4RE64_V, MASK_VL4RE64_V) -DECLARE_INSN(vl8re8_v, MATCH_VL8RE8_V, MASK_VL8RE8_V) -DECLARE_INSN(vl8re16_v, MATCH_VL8RE16_V, MASK_VL8RE16_V) -DECLARE_INSN(vl8re32_v, MATCH_VL8RE32_V, MASK_VL8RE32_V) -DECLARE_INSN(vl8re64_v, MATCH_VL8RE64_V, MASK_VL8RE64_V) -DECLARE_INSN(vs1r_v, MATCH_VS1R_V, MASK_VS1R_V) -DECLARE_INSN(vs2r_v, MATCH_VS2R_V, MASK_VS2R_V) -DECLARE_INSN(vs4r_v, MATCH_VS4R_V, MASK_VS4R_V) -DECLARE_INSN(vs8r_v, MATCH_VS8R_V, MASK_VS8R_V) -DECLARE_INSN(vfadd_vf, MATCH_VFADD_VF, MASK_VFADD_VF) -DECLARE_INSN(vfsub_vf, MATCH_VFSUB_VF, MASK_VFSUB_VF) -DECLARE_INSN(vfmin_vf, MATCH_VFMIN_VF, MASK_VFMIN_VF) -DECLARE_INSN(vfmax_vf, MATCH_VFMAX_VF, MASK_VFMAX_VF) -DECLARE_INSN(vfsgnj_vf, MATCH_VFSGNJ_VF, MASK_VFSGNJ_VF) -DECLARE_INSN(vfsgnjn_vf, MATCH_VFSGNJN_VF, MASK_VFSGNJN_VF) -DECLARE_INSN(vfsgnjx_vf, MATCH_VFSGNJX_VF, MASK_VFSGNJX_VF) -DECLARE_INSN(vfslide1up_vf, MATCH_VFSLIDE1UP_VF, MASK_VFSLIDE1UP_VF) -DECLARE_INSN(vfslide1down_vf, MATCH_VFSLIDE1DOWN_VF, MASK_VFSLIDE1DOWN_VF) -DECLARE_INSN(vfmv_s_f, MATCH_VFMV_S_F, MASK_VFMV_S_F) -DECLARE_INSN(vfmerge_vfm, MATCH_VFMERGE_VFM, MASK_VFMERGE_VFM) -DECLARE_INSN(vfmv_v_f, MATCH_VFMV_V_F, MASK_VFMV_V_F) -DECLARE_INSN(vmfeq_vf, MATCH_VMFEQ_VF, MASK_VMFEQ_VF) -DECLARE_INSN(vmfle_vf, MATCH_VMFLE_VF, MASK_VMFLE_VF) -DECLARE_INSN(vmflt_vf, MATCH_VMFLT_VF, MASK_VMFLT_VF) -DECLARE_INSN(vmfne_vf, MATCH_VMFNE_VF, MASK_VMFNE_VF) -DECLARE_INSN(vmfgt_vf, MATCH_VMFGT_VF, MASK_VMFGT_VF) -DECLARE_INSN(vmfge_vf, MATCH_VMFGE_VF, MASK_VMFGE_VF) -DECLARE_INSN(vfdiv_vf, MATCH_VFDIV_VF, MASK_VFDIV_VF) -DECLARE_INSN(vfrdiv_vf, MATCH_VFRDIV_VF, MASK_VFRDIV_VF) -DECLARE_INSN(vfmul_vf, MATCH_VFMUL_VF, MASK_VFMUL_VF) -DECLARE_INSN(vfrsub_vf, MATCH_VFRSUB_VF, MASK_VFRSUB_VF) -DECLARE_INSN(vfmadd_vf, MATCH_VFMADD_VF, MASK_VFMADD_VF) -DECLARE_INSN(vfnmadd_vf, MATCH_VFNMADD_VF, MASK_VFNMADD_VF) -DECLARE_INSN(vfmsub_vf, MATCH_VFMSUB_VF, MASK_VFMSUB_VF) -DECLARE_INSN(vfnmsub_vf, MATCH_VFNMSUB_VF, MASK_VFNMSUB_VF) -DECLARE_INSN(vfmacc_vf, MATCH_VFMACC_VF, MASK_VFMACC_VF) -DECLARE_INSN(vfnmacc_vf, MATCH_VFNMACC_VF, MASK_VFNMACC_VF) -DECLARE_INSN(vfmsac_vf, MATCH_VFMSAC_VF, MASK_VFMSAC_VF) -DECLARE_INSN(vfnmsac_vf, MATCH_VFNMSAC_VF, MASK_VFNMSAC_VF) -DECLARE_INSN(vfwadd_vf, MATCH_VFWADD_VF, MASK_VFWADD_VF) -DECLARE_INSN(vfwsub_vf, MATCH_VFWSUB_VF, MASK_VFWSUB_VF) -DECLARE_INSN(vfwadd_wf, MATCH_VFWADD_WF, MASK_VFWADD_WF) -DECLARE_INSN(vfwsub_wf, MATCH_VFWSUB_WF, MASK_VFWSUB_WF) -DECLARE_INSN(vfwmul_vf, MATCH_VFWMUL_VF, MASK_VFWMUL_VF) -DECLARE_INSN(vfwmacc_vf, MATCH_VFWMACC_VF, MASK_VFWMACC_VF) -DECLARE_INSN(vfwnmacc_vf, MATCH_VFWNMACC_VF, MASK_VFWNMACC_VF) -DECLARE_INSN(vfwmsac_vf, MATCH_VFWMSAC_VF, MASK_VFWMSAC_VF) -DECLARE_INSN(vfwnmsac_vf, MATCH_VFWNMSAC_VF, MASK_VFWNMSAC_VF) -DECLARE_INSN(vfadd_vv, MATCH_VFADD_VV, MASK_VFADD_VV) -DECLARE_INSN(vfredusum_vs, MATCH_VFREDUSUM_VS, MASK_VFREDUSUM_VS) -DECLARE_INSN(vfsub_vv, MATCH_VFSUB_VV, MASK_VFSUB_VV) -DECLARE_INSN(vfredosum_vs, MATCH_VFREDOSUM_VS, MASK_VFREDOSUM_VS) -DECLARE_INSN(vfmin_vv, MATCH_VFMIN_VV, MASK_VFMIN_VV) -DECLARE_INSN(vfredmin_vs, MATCH_VFREDMIN_VS, MASK_VFREDMIN_VS) -DECLARE_INSN(vfmax_vv, MATCH_VFMAX_VV, MASK_VFMAX_VV) -DECLARE_INSN(vfredmax_vs, MATCH_VFREDMAX_VS, MASK_VFREDMAX_VS) -DECLARE_INSN(vfsgnj_vv, MATCH_VFSGNJ_VV, MASK_VFSGNJ_VV) -DECLARE_INSN(vfsgnjn_vv, MATCH_VFSGNJN_VV, MASK_VFSGNJN_VV) -DECLARE_INSN(vfsgnjx_vv, MATCH_VFSGNJX_VV, MASK_VFSGNJX_VV) -DECLARE_INSN(vfmv_f_s, MATCH_VFMV_F_S, MASK_VFMV_F_S) -DECLARE_INSN(vmfeq_vv, MATCH_VMFEQ_VV, MASK_VMFEQ_VV) -DECLARE_INSN(vmfle_vv, MATCH_VMFLE_VV, MASK_VMFLE_VV) -DECLARE_INSN(vmflt_vv, MATCH_VMFLT_VV, MASK_VMFLT_VV) -DECLARE_INSN(vmfne_vv, MATCH_VMFNE_VV, MASK_VMFNE_VV) -DECLARE_INSN(vfdiv_vv, MATCH_VFDIV_VV, MASK_VFDIV_VV) -DECLARE_INSN(vfmul_vv, MATCH_VFMUL_VV, MASK_VFMUL_VV) -DECLARE_INSN(vfmadd_vv, MATCH_VFMADD_VV, MASK_VFMADD_VV) -DECLARE_INSN(vfnmadd_vv, MATCH_VFNMADD_VV, MASK_VFNMADD_VV) -DECLARE_INSN(vfmsub_vv, MATCH_VFMSUB_VV, MASK_VFMSUB_VV) -DECLARE_INSN(vfnmsub_vv, MATCH_VFNMSUB_VV, MASK_VFNMSUB_VV) -DECLARE_INSN(vfmacc_vv, MATCH_VFMACC_VV, MASK_VFMACC_VV) -DECLARE_INSN(vfnmacc_vv, MATCH_VFNMACC_VV, MASK_VFNMACC_VV) -DECLARE_INSN(vfmsac_vv, MATCH_VFMSAC_VV, MASK_VFMSAC_VV) -DECLARE_INSN(vfnmsac_vv, MATCH_VFNMSAC_VV, MASK_VFNMSAC_VV) -DECLARE_INSN(vfcvt_xu_f_v, MATCH_VFCVT_XU_F_V, MASK_VFCVT_XU_F_V) -DECLARE_INSN(vfcvt_x_f_v, MATCH_VFCVT_X_F_V, MASK_VFCVT_X_F_V) -DECLARE_INSN(vfcvt_f_xu_v, MATCH_VFCVT_F_XU_V, MASK_VFCVT_F_XU_V) -DECLARE_INSN(vfcvt_f_x_v, MATCH_VFCVT_F_X_V, MASK_VFCVT_F_X_V) -DECLARE_INSN(vfcvt_rtz_xu_f_v, MATCH_VFCVT_RTZ_XU_F_V, MASK_VFCVT_RTZ_XU_F_V) -DECLARE_INSN(vfcvt_rtz_x_f_v, MATCH_VFCVT_RTZ_X_F_V, MASK_VFCVT_RTZ_X_F_V) -DECLARE_INSN(vfwcvt_xu_f_v, MATCH_VFWCVT_XU_F_V, MASK_VFWCVT_XU_F_V) -DECLARE_INSN(vfwcvt_x_f_v, MATCH_VFWCVT_X_F_V, MASK_VFWCVT_X_F_V) -DECLARE_INSN(vfwcvt_f_xu_v, MATCH_VFWCVT_F_XU_V, MASK_VFWCVT_F_XU_V) -DECLARE_INSN(vfwcvt_f_x_v, MATCH_VFWCVT_F_X_V, MASK_VFWCVT_F_X_V) -DECLARE_INSN(vfwcvt_f_f_v, MATCH_VFWCVT_F_F_V, MASK_VFWCVT_F_F_V) -DECLARE_INSN(vfwcvt_rtz_xu_f_v, MATCH_VFWCVT_RTZ_XU_F_V, MASK_VFWCVT_RTZ_XU_F_V) -DECLARE_INSN(vfwcvt_rtz_x_f_v, MATCH_VFWCVT_RTZ_X_F_V, MASK_VFWCVT_RTZ_X_F_V) -DECLARE_INSN(vfncvt_xu_f_w, MATCH_VFNCVT_XU_F_W, MASK_VFNCVT_XU_F_W) -DECLARE_INSN(vfncvt_x_f_w, MATCH_VFNCVT_X_F_W, MASK_VFNCVT_X_F_W) -DECLARE_INSN(vfncvt_f_xu_w, MATCH_VFNCVT_F_XU_W, MASK_VFNCVT_F_XU_W) -DECLARE_INSN(vfncvt_f_x_w, MATCH_VFNCVT_F_X_W, MASK_VFNCVT_F_X_W) -DECLARE_INSN(vfncvt_f_f_w, MATCH_VFNCVT_F_F_W, MASK_VFNCVT_F_F_W) -DECLARE_INSN(vfncvt_rod_f_f_w, MATCH_VFNCVT_ROD_F_F_W, MASK_VFNCVT_ROD_F_F_W) -DECLARE_INSN(vfncvt_rtz_xu_f_w, MATCH_VFNCVT_RTZ_XU_F_W, MASK_VFNCVT_RTZ_XU_F_W) -DECLARE_INSN(vfncvt_rtz_x_f_w, MATCH_VFNCVT_RTZ_X_F_W, MASK_VFNCVT_RTZ_X_F_W) -DECLARE_INSN(vfsqrt_v, MATCH_VFSQRT_V, MASK_VFSQRT_V) -DECLARE_INSN(vfrsqrt7_v, MATCH_VFRSQRT7_V, MASK_VFRSQRT7_V) -DECLARE_INSN(vfrec7_v, MATCH_VFREC7_V, MASK_VFREC7_V) -DECLARE_INSN(vfclass_v, MATCH_VFCLASS_V, MASK_VFCLASS_V) -DECLARE_INSN(vfwadd_vv, MATCH_VFWADD_VV, MASK_VFWADD_VV) -DECLARE_INSN(vfwredusum_vs, MATCH_VFWREDUSUM_VS, MASK_VFWREDUSUM_VS) -DECLARE_INSN(vfwsub_vv, MATCH_VFWSUB_VV, MASK_VFWSUB_VV) -DECLARE_INSN(vfwredosum_vs, MATCH_VFWREDOSUM_VS, MASK_VFWREDOSUM_VS) -DECLARE_INSN(vfwadd_wv, MATCH_VFWADD_WV, MASK_VFWADD_WV) -DECLARE_INSN(vfwsub_wv, MATCH_VFWSUB_WV, MASK_VFWSUB_WV) -DECLARE_INSN(vfwmul_vv, MATCH_VFWMUL_VV, MASK_VFWMUL_VV) -DECLARE_INSN(vfwmacc_vv, MATCH_VFWMACC_VV, MASK_VFWMACC_VV) -DECLARE_INSN(vfwnmacc_vv, MATCH_VFWNMACC_VV, MASK_VFWNMACC_VV) -DECLARE_INSN(vfwmsac_vv, MATCH_VFWMSAC_VV, MASK_VFWMSAC_VV) -DECLARE_INSN(vfwnmsac_vv, MATCH_VFWNMSAC_VV, MASK_VFWNMSAC_VV) -DECLARE_INSN(vadd_vx, MATCH_VADD_VX, MASK_VADD_VX) -DECLARE_INSN(vsub_vx, MATCH_VSUB_VX, MASK_VSUB_VX) -DECLARE_INSN(vrsub_vx, MATCH_VRSUB_VX, MASK_VRSUB_VX) -DECLARE_INSN(vminu_vx, MATCH_VMINU_VX, MASK_VMINU_VX) -DECLARE_INSN(vmin_vx, MATCH_VMIN_VX, MASK_VMIN_VX) -DECLARE_INSN(vmaxu_vx, MATCH_VMAXU_VX, MASK_VMAXU_VX) -DECLARE_INSN(vmax_vx, MATCH_VMAX_VX, MASK_VMAX_VX) -DECLARE_INSN(vand_vx, MATCH_VAND_VX, MASK_VAND_VX) -DECLARE_INSN(vor_vx, MATCH_VOR_VX, MASK_VOR_VX) -DECLARE_INSN(vxor_vx, MATCH_VXOR_VX, MASK_VXOR_VX) -DECLARE_INSN(vrgather_vx, MATCH_VRGATHER_VX, MASK_VRGATHER_VX) -DECLARE_INSN(vslideup_vx, MATCH_VSLIDEUP_VX, MASK_VSLIDEUP_VX) -DECLARE_INSN(vslidedown_vx, MATCH_VSLIDEDOWN_VX, MASK_VSLIDEDOWN_VX) -DECLARE_INSN(vadc_vxm, MATCH_VADC_VXM, MASK_VADC_VXM) -DECLARE_INSN(vmadc_vxm, MATCH_VMADC_VXM, MASK_VMADC_VXM) -DECLARE_INSN(vmadc_vx, MATCH_VMADC_VX, MASK_VMADC_VX) -DECLARE_INSN(vsbc_vxm, MATCH_VSBC_VXM, MASK_VSBC_VXM) -DECLARE_INSN(vmsbc_vxm, MATCH_VMSBC_VXM, MASK_VMSBC_VXM) -DECLARE_INSN(vmsbc_vx, MATCH_VMSBC_VX, MASK_VMSBC_VX) -DECLARE_INSN(vmerge_vxm, MATCH_VMERGE_VXM, MASK_VMERGE_VXM) -DECLARE_INSN(vmv_v_x, MATCH_VMV_V_X, MASK_VMV_V_X) -DECLARE_INSN(vmseq_vx, MATCH_VMSEQ_VX, MASK_VMSEQ_VX) -DECLARE_INSN(vmsne_vx, MATCH_VMSNE_VX, MASK_VMSNE_VX) -DECLARE_INSN(vmsltu_vx, MATCH_VMSLTU_VX, MASK_VMSLTU_VX) -DECLARE_INSN(vmslt_vx, MATCH_VMSLT_VX, MASK_VMSLT_VX) -DECLARE_INSN(vmsleu_vx, MATCH_VMSLEU_VX, MASK_VMSLEU_VX) -DECLARE_INSN(vmsle_vx, MATCH_VMSLE_VX, MASK_VMSLE_VX) -DECLARE_INSN(vmsgtu_vx, MATCH_VMSGTU_VX, MASK_VMSGTU_VX) -DECLARE_INSN(vmsgt_vx, MATCH_VMSGT_VX, MASK_VMSGT_VX) -DECLARE_INSN(vsaddu_vx, MATCH_VSADDU_VX, MASK_VSADDU_VX) -DECLARE_INSN(vsadd_vx, MATCH_VSADD_VX, MASK_VSADD_VX) -DECLARE_INSN(vssubu_vx, MATCH_VSSUBU_VX, MASK_VSSUBU_VX) -DECLARE_INSN(vssub_vx, MATCH_VSSUB_VX, MASK_VSSUB_VX) -DECLARE_INSN(vsll_vx, MATCH_VSLL_VX, MASK_VSLL_VX) -DECLARE_INSN(vsmul_vx, MATCH_VSMUL_VX, MASK_VSMUL_VX) -DECLARE_INSN(vsrl_vx, MATCH_VSRL_VX, MASK_VSRL_VX) -DECLARE_INSN(vsra_vx, MATCH_VSRA_VX, MASK_VSRA_VX) -DECLARE_INSN(vssrl_vx, MATCH_VSSRL_VX, MASK_VSSRL_VX) -DECLARE_INSN(vssra_vx, MATCH_VSSRA_VX, MASK_VSSRA_VX) -DECLARE_INSN(vnsrl_wx, MATCH_VNSRL_WX, MASK_VNSRL_WX) -DECLARE_INSN(vnsra_wx, MATCH_VNSRA_WX, MASK_VNSRA_WX) -DECLARE_INSN(vnclipu_wx, MATCH_VNCLIPU_WX, MASK_VNCLIPU_WX) -DECLARE_INSN(vnclip_wx, MATCH_VNCLIP_WX, MASK_VNCLIP_WX) -DECLARE_INSN(vadd_vv, MATCH_VADD_VV, MASK_VADD_VV) -DECLARE_INSN(vsub_vv, MATCH_VSUB_VV, MASK_VSUB_VV) -DECLARE_INSN(vminu_vv, MATCH_VMINU_VV, MASK_VMINU_VV) -DECLARE_INSN(vmin_vv, MATCH_VMIN_VV, MASK_VMIN_VV) -DECLARE_INSN(vmaxu_vv, MATCH_VMAXU_VV, MASK_VMAXU_VV) -DECLARE_INSN(vmax_vv, MATCH_VMAX_VV, MASK_VMAX_VV) -DECLARE_INSN(vand_vv, MATCH_VAND_VV, MASK_VAND_VV) -DECLARE_INSN(vor_vv, MATCH_VOR_VV, MASK_VOR_VV) -DECLARE_INSN(vxor_vv, MATCH_VXOR_VV, MASK_VXOR_VV) -DECLARE_INSN(vrgather_vv, MATCH_VRGATHER_VV, MASK_VRGATHER_VV) -DECLARE_INSN(vrgatherei16_vv, MATCH_VRGATHEREI16_VV, MASK_VRGATHEREI16_VV) -DECLARE_INSN(vadc_vvm, MATCH_VADC_VVM, MASK_VADC_VVM) -DECLARE_INSN(vmadc_vvm, MATCH_VMADC_VVM, MASK_VMADC_VVM) -DECLARE_INSN(vmadc_vv, MATCH_VMADC_VV, MASK_VMADC_VV) -DECLARE_INSN(vsbc_vvm, MATCH_VSBC_VVM, MASK_VSBC_VVM) -DECLARE_INSN(vmsbc_vvm, MATCH_VMSBC_VVM, MASK_VMSBC_VVM) -DECLARE_INSN(vmsbc_vv, MATCH_VMSBC_VV, MASK_VMSBC_VV) -DECLARE_INSN(vmerge_vvm, MATCH_VMERGE_VVM, MASK_VMERGE_VVM) -DECLARE_INSN(vmv_v_v, MATCH_VMV_V_V, MASK_VMV_V_V) -DECLARE_INSN(vmseq_vv, MATCH_VMSEQ_VV, MASK_VMSEQ_VV) -DECLARE_INSN(vmsne_vv, MATCH_VMSNE_VV, MASK_VMSNE_VV) -DECLARE_INSN(vmsltu_vv, MATCH_VMSLTU_VV, MASK_VMSLTU_VV) -DECLARE_INSN(vmslt_vv, MATCH_VMSLT_VV, MASK_VMSLT_VV) -DECLARE_INSN(vmsleu_vv, MATCH_VMSLEU_VV, MASK_VMSLEU_VV) -DECLARE_INSN(vmsle_vv, MATCH_VMSLE_VV, MASK_VMSLE_VV) -DECLARE_INSN(vsaddu_vv, MATCH_VSADDU_VV, MASK_VSADDU_VV) -DECLARE_INSN(vsadd_vv, MATCH_VSADD_VV, MASK_VSADD_VV) -DECLARE_INSN(vssubu_vv, MATCH_VSSUBU_VV, MASK_VSSUBU_VV) -DECLARE_INSN(vssub_vv, MATCH_VSSUB_VV, MASK_VSSUB_VV) -DECLARE_INSN(vsll_vv, MATCH_VSLL_VV, MASK_VSLL_VV) -DECLARE_INSN(vsmul_vv, MATCH_VSMUL_VV, MASK_VSMUL_VV) -DECLARE_INSN(vsrl_vv, MATCH_VSRL_VV, MASK_VSRL_VV) -DECLARE_INSN(vsra_vv, MATCH_VSRA_VV, MASK_VSRA_VV) -DECLARE_INSN(vssrl_vv, MATCH_VSSRL_VV, MASK_VSSRL_VV) -DECLARE_INSN(vssra_vv, MATCH_VSSRA_VV, MASK_VSSRA_VV) -DECLARE_INSN(vnsrl_wv, MATCH_VNSRL_WV, MASK_VNSRL_WV) -DECLARE_INSN(vnsra_wv, MATCH_VNSRA_WV, MASK_VNSRA_WV) -DECLARE_INSN(vnclipu_wv, MATCH_VNCLIPU_WV, MASK_VNCLIPU_WV) -DECLARE_INSN(vnclip_wv, MATCH_VNCLIP_WV, MASK_VNCLIP_WV) -DECLARE_INSN(vwredsumu_vs, MATCH_VWREDSUMU_VS, MASK_VWREDSUMU_VS) -DECLARE_INSN(vwredsum_vs, MATCH_VWREDSUM_VS, MASK_VWREDSUM_VS) -DECLARE_INSN(vadd_vi, MATCH_VADD_VI, MASK_VADD_VI) -DECLARE_INSN(vrsub_vi, MATCH_VRSUB_VI, MASK_VRSUB_VI) -DECLARE_INSN(vand_vi, MATCH_VAND_VI, MASK_VAND_VI) -DECLARE_INSN(vor_vi, MATCH_VOR_VI, MASK_VOR_VI) -DECLARE_INSN(vxor_vi, MATCH_VXOR_VI, MASK_VXOR_VI) -DECLARE_INSN(vrgather_vi, MATCH_VRGATHER_VI, MASK_VRGATHER_VI) -DECLARE_INSN(vslideup_vi, MATCH_VSLIDEUP_VI, MASK_VSLIDEUP_VI) -DECLARE_INSN(vslidedown_vi, MATCH_VSLIDEDOWN_VI, MASK_VSLIDEDOWN_VI) -DECLARE_INSN(vadc_vim, MATCH_VADC_VIM, MASK_VADC_VIM) -DECLARE_INSN(vmadc_vim, MATCH_VMADC_VIM, MASK_VMADC_VIM) -DECLARE_INSN(vmadc_vi, MATCH_VMADC_VI, MASK_VMADC_VI) -DECLARE_INSN(vmerge_vim, MATCH_VMERGE_VIM, MASK_VMERGE_VIM) -DECLARE_INSN(vmv_v_i, MATCH_VMV_V_I, MASK_VMV_V_I) -DECLARE_INSN(vmseq_vi, MATCH_VMSEQ_VI, MASK_VMSEQ_VI) -DECLARE_INSN(vmsne_vi, MATCH_VMSNE_VI, MASK_VMSNE_VI) -DECLARE_INSN(vmsleu_vi, MATCH_VMSLEU_VI, MASK_VMSLEU_VI) -DECLARE_INSN(vmsle_vi, MATCH_VMSLE_VI, MASK_VMSLE_VI) -DECLARE_INSN(vmsgtu_vi, MATCH_VMSGTU_VI, MASK_VMSGTU_VI) -DECLARE_INSN(vmsgt_vi, MATCH_VMSGT_VI, MASK_VMSGT_VI) -DECLARE_INSN(vsaddu_vi, MATCH_VSADDU_VI, MASK_VSADDU_VI) -DECLARE_INSN(vsadd_vi, MATCH_VSADD_VI, MASK_VSADD_VI) -DECLARE_INSN(vsll_vi, MATCH_VSLL_VI, MASK_VSLL_VI) -DECLARE_INSN(vmv1r_v, MATCH_VMV1R_V, MASK_VMV1R_V) -DECLARE_INSN(vmv2r_v, MATCH_VMV2R_V, MASK_VMV2R_V) -DECLARE_INSN(vmv4r_v, MATCH_VMV4R_V, MASK_VMV4R_V) -DECLARE_INSN(vmv8r_v, MATCH_VMV8R_V, MASK_VMV8R_V) -DECLARE_INSN(vsrl_vi, MATCH_VSRL_VI, MASK_VSRL_VI) -DECLARE_INSN(vsra_vi, MATCH_VSRA_VI, MASK_VSRA_VI) -DECLARE_INSN(vssrl_vi, MATCH_VSSRL_VI, MASK_VSSRL_VI) -DECLARE_INSN(vssra_vi, MATCH_VSSRA_VI, MASK_VSSRA_VI) -DECLARE_INSN(vnsrl_wi, MATCH_VNSRL_WI, MASK_VNSRL_WI) -DECLARE_INSN(vnsra_wi, MATCH_VNSRA_WI, MASK_VNSRA_WI) -DECLARE_INSN(vnclipu_wi, MATCH_VNCLIPU_WI, MASK_VNCLIPU_WI) -DECLARE_INSN(vnclip_wi, MATCH_VNCLIP_WI, MASK_VNCLIP_WI) -DECLARE_INSN(vredsum_vs, MATCH_VREDSUM_VS, MASK_VREDSUM_VS) -DECLARE_INSN(vredand_vs, MATCH_VREDAND_VS, MASK_VREDAND_VS) -DECLARE_INSN(vredor_vs, MATCH_VREDOR_VS, MASK_VREDOR_VS) -DECLARE_INSN(vredxor_vs, MATCH_VREDXOR_VS, MASK_VREDXOR_VS) -DECLARE_INSN(vredminu_vs, MATCH_VREDMINU_VS, MASK_VREDMINU_VS) -DECLARE_INSN(vredmin_vs, MATCH_VREDMIN_VS, MASK_VREDMIN_VS) -DECLARE_INSN(vredmaxu_vs, MATCH_VREDMAXU_VS, MASK_VREDMAXU_VS) -DECLARE_INSN(vredmax_vs, MATCH_VREDMAX_VS, MASK_VREDMAX_VS) -DECLARE_INSN(vaaddu_vv, MATCH_VAADDU_VV, MASK_VAADDU_VV) -DECLARE_INSN(vaadd_vv, MATCH_VAADD_VV, MASK_VAADD_VV) -DECLARE_INSN(vasubu_vv, MATCH_VASUBU_VV, MASK_VASUBU_VV) -DECLARE_INSN(vasub_vv, MATCH_VASUB_VV, MASK_VASUB_VV) -DECLARE_INSN(vmv_x_s, MATCH_VMV_X_S, MASK_VMV_X_S) -DECLARE_INSN(vzext_vf8, MATCH_VZEXT_VF8, MASK_VZEXT_VF8) -DECLARE_INSN(vsext_vf8, MATCH_VSEXT_VF8, MASK_VSEXT_VF8) -DECLARE_INSN(vzext_vf4, MATCH_VZEXT_VF4, MASK_VZEXT_VF4) -DECLARE_INSN(vsext_vf4, MATCH_VSEXT_VF4, MASK_VSEXT_VF4) -DECLARE_INSN(vzext_vf2, MATCH_VZEXT_VF2, MASK_VZEXT_VF2) -DECLARE_INSN(vsext_vf2, MATCH_VSEXT_VF2, MASK_VSEXT_VF2) -DECLARE_INSN(vcompress_vm, MATCH_VCOMPRESS_VM, MASK_VCOMPRESS_VM) -DECLARE_INSN(vmandn_mm, MATCH_VMANDN_MM, MASK_VMANDN_MM) -DECLARE_INSN(vmand_mm, MATCH_VMAND_MM, MASK_VMAND_MM) -DECLARE_INSN(vmor_mm, MATCH_VMOR_MM, MASK_VMOR_MM) -DECLARE_INSN(vmxor_mm, MATCH_VMXOR_MM, MASK_VMXOR_MM) -DECLARE_INSN(vmorn_mm, MATCH_VMORN_MM, MASK_VMORN_MM) -DECLARE_INSN(vmnand_mm, MATCH_VMNAND_MM, MASK_VMNAND_MM) -DECLARE_INSN(vmnor_mm, MATCH_VMNOR_MM, MASK_VMNOR_MM) -DECLARE_INSN(vmxnor_mm, MATCH_VMXNOR_MM, MASK_VMXNOR_MM) -DECLARE_INSN(vmsbf_m, MATCH_VMSBF_M, MASK_VMSBF_M) -DECLARE_INSN(vmsof_m, MATCH_VMSOF_M, MASK_VMSOF_M) -DECLARE_INSN(vmsif_m, MATCH_VMSIF_M, MASK_VMSIF_M) -DECLARE_INSN(viota_m, MATCH_VIOTA_M, MASK_VIOTA_M) -DECLARE_INSN(vid_v, MATCH_VID_V, MASK_VID_V) -DECLARE_INSN(vcpop_m, MATCH_VCPOP_M, MASK_VCPOP_M) -DECLARE_INSN(vfirst_m, MATCH_VFIRST_M, MASK_VFIRST_M) -DECLARE_INSN(vdivu_vv, MATCH_VDIVU_VV, MASK_VDIVU_VV) -DECLARE_INSN(vdiv_vv, MATCH_VDIV_VV, MASK_VDIV_VV) -DECLARE_INSN(vremu_vv, MATCH_VREMU_VV, MASK_VREMU_VV) -DECLARE_INSN(vrem_vv, MATCH_VREM_VV, MASK_VREM_VV) -DECLARE_INSN(vmulhu_vv, MATCH_VMULHU_VV, MASK_VMULHU_VV) -DECLARE_INSN(vmul_vv, MATCH_VMUL_VV, MASK_VMUL_VV) -DECLARE_INSN(vmulhsu_vv, MATCH_VMULHSU_VV, MASK_VMULHSU_VV) -DECLARE_INSN(vmulh_vv, MATCH_VMULH_VV, MASK_VMULH_VV) -DECLARE_INSN(vmadd_vv, MATCH_VMADD_VV, MASK_VMADD_VV) -DECLARE_INSN(vnmsub_vv, MATCH_VNMSUB_VV, MASK_VNMSUB_VV) -DECLARE_INSN(vmacc_vv, MATCH_VMACC_VV, MASK_VMACC_VV) -DECLARE_INSN(vnmsac_vv, MATCH_VNMSAC_VV, MASK_VNMSAC_VV) -DECLARE_INSN(vwaddu_vv, MATCH_VWADDU_VV, MASK_VWADDU_VV) -DECLARE_INSN(vwadd_vv, MATCH_VWADD_VV, MASK_VWADD_VV) -DECLARE_INSN(vwsubu_vv, MATCH_VWSUBU_VV, MASK_VWSUBU_VV) -DECLARE_INSN(vwsub_vv, MATCH_VWSUB_VV, MASK_VWSUB_VV) -DECLARE_INSN(vwaddu_wv, MATCH_VWADDU_WV, MASK_VWADDU_WV) -DECLARE_INSN(vwadd_wv, MATCH_VWADD_WV, MASK_VWADD_WV) -DECLARE_INSN(vwsubu_wv, MATCH_VWSUBU_WV, MASK_VWSUBU_WV) -DECLARE_INSN(vwsub_wv, MATCH_VWSUB_WV, MASK_VWSUB_WV) -DECLARE_INSN(vwmulu_vv, MATCH_VWMULU_VV, MASK_VWMULU_VV) -DECLARE_INSN(vwmulsu_vv, MATCH_VWMULSU_VV, MASK_VWMULSU_VV) -DECLARE_INSN(vwmul_vv, MATCH_VWMUL_VV, MASK_VWMUL_VV) -DECLARE_INSN(vwmaccu_vv, MATCH_VWMACCU_VV, MASK_VWMACCU_VV) -DECLARE_INSN(vwmacc_vv, MATCH_VWMACC_VV, MASK_VWMACC_VV) -DECLARE_INSN(vwmaccsu_vv, MATCH_VWMACCSU_VV, MASK_VWMACCSU_VV) -DECLARE_INSN(vaaddu_vx, MATCH_VAADDU_VX, MASK_VAADDU_VX) -DECLARE_INSN(vaadd_vx, MATCH_VAADD_VX, MASK_VAADD_VX) -DECLARE_INSN(vasubu_vx, MATCH_VASUBU_VX, MASK_VASUBU_VX) -DECLARE_INSN(vasub_vx, MATCH_VASUB_VX, MASK_VASUB_VX) -DECLARE_INSN(vmv_s_x, MATCH_VMV_S_X, MASK_VMV_S_X) -DECLARE_INSN(vslide1up_vx, MATCH_VSLIDE1UP_VX, MASK_VSLIDE1UP_VX) -DECLARE_INSN(vslide1down_vx, MATCH_VSLIDE1DOWN_VX, MASK_VSLIDE1DOWN_VX) -DECLARE_INSN(vdivu_vx, MATCH_VDIVU_VX, MASK_VDIVU_VX) -DECLARE_INSN(vdiv_vx, MATCH_VDIV_VX, MASK_VDIV_VX) -DECLARE_INSN(vremu_vx, MATCH_VREMU_VX, MASK_VREMU_VX) -DECLARE_INSN(vrem_vx, MATCH_VREM_VX, MASK_VREM_VX) -DECLARE_INSN(vmulhu_vx, MATCH_VMULHU_VX, MASK_VMULHU_VX) -DECLARE_INSN(vmul_vx, MATCH_VMUL_VX, MASK_VMUL_VX) -DECLARE_INSN(vmulhsu_vx, MATCH_VMULHSU_VX, MASK_VMULHSU_VX) -DECLARE_INSN(vmulh_vx, MATCH_VMULH_VX, MASK_VMULH_VX) -DECLARE_INSN(vmadd_vx, MATCH_VMADD_VX, MASK_VMADD_VX) -DECLARE_INSN(vnmsub_vx, MATCH_VNMSUB_VX, MASK_VNMSUB_VX) -DECLARE_INSN(vmacc_vx, MATCH_VMACC_VX, MASK_VMACC_VX) -DECLARE_INSN(vnmsac_vx, MATCH_VNMSAC_VX, MASK_VNMSAC_VX) -DECLARE_INSN(vwaddu_vx, MATCH_VWADDU_VX, MASK_VWADDU_VX) -DECLARE_INSN(vwadd_vx, MATCH_VWADD_VX, MASK_VWADD_VX) -DECLARE_INSN(vwsubu_vx, MATCH_VWSUBU_VX, MASK_VWSUBU_VX) -DECLARE_INSN(vwsub_vx, MATCH_VWSUB_VX, MASK_VWSUB_VX) -DECLARE_INSN(vwaddu_wx, MATCH_VWADDU_WX, MASK_VWADDU_WX) -DECLARE_INSN(vwadd_wx, MATCH_VWADD_WX, MASK_VWADD_WX) -DECLARE_INSN(vwsubu_wx, MATCH_VWSUBU_WX, MASK_VWSUBU_WX) -DECLARE_INSN(vwsub_wx, MATCH_VWSUB_WX, MASK_VWSUB_WX) -DECLARE_INSN(vwmulu_vx, MATCH_VWMULU_VX, MASK_VWMULU_VX) -DECLARE_INSN(vwmulsu_vx, MATCH_VWMULSU_VX, MASK_VWMULSU_VX) -DECLARE_INSN(vwmul_vx, MATCH_VWMUL_VX, MASK_VWMUL_VX) -DECLARE_INSN(vwmaccu_vx, MATCH_VWMACCU_VX, MASK_VWMACCU_VX) -DECLARE_INSN(vwmacc_vx, MATCH_VWMACC_VX, MASK_VWMACC_VX) -DECLARE_INSN(vwmaccus_vx, MATCH_VWMACCUS_VX, MASK_VWMACCUS_VX) -DECLARE_INSN(vwmaccsu_vx, MATCH_VWMACCSU_VX, MASK_VWMACCSU_VX) -DECLARE_INSN(vamoswapei8_v, MATCH_VAMOSWAPEI8_V, MASK_VAMOSWAPEI8_V) -DECLARE_INSN(vamoaddei8_v, MATCH_VAMOADDEI8_V, MASK_VAMOADDEI8_V) -DECLARE_INSN(vamoxorei8_v, MATCH_VAMOXOREI8_V, MASK_VAMOXOREI8_V) -DECLARE_INSN(vamoandei8_v, MATCH_VAMOANDEI8_V, MASK_VAMOANDEI8_V) -DECLARE_INSN(vamoorei8_v, MATCH_VAMOOREI8_V, MASK_VAMOOREI8_V) -DECLARE_INSN(vamominei8_v, MATCH_VAMOMINEI8_V, MASK_VAMOMINEI8_V) -DECLARE_INSN(vamomaxei8_v, MATCH_VAMOMAXEI8_V, MASK_VAMOMAXEI8_V) -DECLARE_INSN(vamominuei8_v, MATCH_VAMOMINUEI8_V, MASK_VAMOMINUEI8_V) -DECLARE_INSN(vamomaxuei8_v, MATCH_VAMOMAXUEI8_V, MASK_VAMOMAXUEI8_V) -DECLARE_INSN(vamoswapei16_v, MATCH_VAMOSWAPEI16_V, MASK_VAMOSWAPEI16_V) -DECLARE_INSN(vamoaddei16_v, MATCH_VAMOADDEI16_V, MASK_VAMOADDEI16_V) -DECLARE_INSN(vamoxorei16_v, MATCH_VAMOXOREI16_V, MASK_VAMOXOREI16_V) -DECLARE_INSN(vamoandei16_v, MATCH_VAMOANDEI16_V, MASK_VAMOANDEI16_V) -DECLARE_INSN(vamoorei16_v, MATCH_VAMOOREI16_V, MASK_VAMOOREI16_V) -DECLARE_INSN(vamominei16_v, MATCH_VAMOMINEI16_V, MASK_VAMOMINEI16_V) -DECLARE_INSN(vamomaxei16_v, MATCH_VAMOMAXEI16_V, MASK_VAMOMAXEI16_V) -DECLARE_INSN(vamominuei16_v, MATCH_VAMOMINUEI16_V, MASK_VAMOMINUEI16_V) -DECLARE_INSN(vamomaxuei16_v, MATCH_VAMOMAXUEI16_V, MASK_VAMOMAXUEI16_V) -DECLARE_INSN(vamoswapei32_v, MATCH_VAMOSWAPEI32_V, MASK_VAMOSWAPEI32_V) -DECLARE_INSN(vamoaddei32_v, MATCH_VAMOADDEI32_V, MASK_VAMOADDEI32_V) -DECLARE_INSN(vamoxorei32_v, MATCH_VAMOXOREI32_V, MASK_VAMOXOREI32_V) -DECLARE_INSN(vamoandei32_v, MATCH_VAMOANDEI32_V, MASK_VAMOANDEI32_V) -DECLARE_INSN(vamoorei32_v, MATCH_VAMOOREI32_V, MASK_VAMOOREI32_V) -DECLARE_INSN(vamominei32_v, MATCH_VAMOMINEI32_V, MASK_VAMOMINEI32_V) -DECLARE_INSN(vamomaxei32_v, MATCH_VAMOMAXEI32_V, MASK_VAMOMAXEI32_V) -DECLARE_INSN(vamominuei32_v, MATCH_VAMOMINUEI32_V, MASK_VAMOMINUEI32_V) -DECLARE_INSN(vamomaxuei32_v, MATCH_VAMOMAXUEI32_V, MASK_VAMOMAXUEI32_V) -DECLARE_INSN(vamoswapei64_v, MATCH_VAMOSWAPEI64_V, MASK_VAMOSWAPEI64_V) -DECLARE_INSN(vamoaddei64_v, MATCH_VAMOADDEI64_V, MASK_VAMOADDEI64_V) -DECLARE_INSN(vamoxorei64_v, MATCH_VAMOXOREI64_V, MASK_VAMOXOREI64_V) -DECLARE_INSN(vamoandei64_v, MATCH_VAMOANDEI64_V, MASK_VAMOANDEI64_V) -DECLARE_INSN(vamoorei64_v, MATCH_VAMOOREI64_V, MASK_VAMOOREI64_V) -DECLARE_INSN(vamominei64_v, MATCH_VAMOMINEI64_V, MASK_VAMOMINEI64_V) -DECLARE_INSN(vamomaxei64_v, MATCH_VAMOMAXEI64_V, MASK_VAMOMAXEI64_V) -DECLARE_INSN(vamominuei64_v, MATCH_VAMOMINUEI64_V, MASK_VAMOMINUEI64_V) -DECLARE_INSN(vamomaxuei64_v, MATCH_VAMOMAXUEI64_V, MASK_VAMOMAXUEI64_V) -DECLARE_INSN(add8, MATCH_ADD8, MASK_ADD8) -DECLARE_INSN(add16, MATCH_ADD16, MASK_ADD16) -DECLARE_INSN(add64, MATCH_ADD64, MASK_ADD64) -DECLARE_INSN(ave, MATCH_AVE, MASK_AVE) -DECLARE_INSN(bitrev, MATCH_BITREV, MASK_BITREV) -DECLARE_INSN(bitrevi, MATCH_BITREVI, MASK_BITREVI) -DECLARE_INSN(bpick, MATCH_BPICK, MASK_BPICK) -DECLARE_INSN(clrs8, MATCH_CLRS8, MASK_CLRS8) -DECLARE_INSN(clrs16, MATCH_CLRS16, MASK_CLRS16) -DECLARE_INSN(clrs32, MATCH_CLRS32, MASK_CLRS32) -DECLARE_INSN(clo8, MATCH_CLO8, MASK_CLO8) -DECLARE_INSN(clo16, MATCH_CLO16, MASK_CLO16) -DECLARE_INSN(clo32, MATCH_CLO32, MASK_CLO32) -DECLARE_INSN(clz8, MATCH_CLZ8, MASK_CLZ8) -DECLARE_INSN(clz16, MATCH_CLZ16, MASK_CLZ16) -DECLARE_INSN(clz32, MATCH_CLZ32, MASK_CLZ32) -DECLARE_INSN(cmpeq8, MATCH_CMPEQ8, MASK_CMPEQ8) -DECLARE_INSN(cmpeq16, MATCH_CMPEQ16, MASK_CMPEQ16) -DECLARE_INSN(cras16, MATCH_CRAS16, MASK_CRAS16) -DECLARE_INSN(crsa16, MATCH_CRSA16, MASK_CRSA16) +DECLARE_INSN(fcvt_h_q, MATCH_FCVT_H_Q, MASK_FCVT_H_Q) +DECLARE_INSN(fcvt_h_s, MATCH_FCVT_H_S, MASK_FCVT_H_S) +DECLARE_INSN(fcvt_h_w, MATCH_FCVT_H_W, MASK_FCVT_H_W) +DECLARE_INSN(fcvt_h_wu, MATCH_FCVT_H_WU, MASK_FCVT_H_WU) +DECLARE_INSN(fcvt_l_d, MATCH_FCVT_L_D, MASK_FCVT_L_D) +DECLARE_INSN(fcvt_l_h, MATCH_FCVT_L_H, MASK_FCVT_L_H) +DECLARE_INSN(fcvt_l_q, MATCH_FCVT_L_Q, MASK_FCVT_L_Q) +DECLARE_INSN(fcvt_l_s, MATCH_FCVT_L_S, MASK_FCVT_L_S) +DECLARE_INSN(fcvt_lu_d, MATCH_FCVT_LU_D, MASK_FCVT_LU_D) +DECLARE_INSN(fcvt_lu_h, MATCH_FCVT_LU_H, MASK_FCVT_LU_H) +DECLARE_INSN(fcvt_lu_q, MATCH_FCVT_LU_Q, MASK_FCVT_LU_Q) +DECLARE_INSN(fcvt_lu_s, MATCH_FCVT_LU_S, MASK_FCVT_LU_S) +DECLARE_INSN(fcvt_q_d, MATCH_FCVT_Q_D, MASK_FCVT_Q_D) +DECLARE_INSN(fcvt_q_h, MATCH_FCVT_Q_H, MASK_FCVT_Q_H) +DECLARE_INSN(fcvt_q_l, MATCH_FCVT_Q_L, MASK_FCVT_Q_L) +DECLARE_INSN(fcvt_q_lu, MATCH_FCVT_Q_LU, MASK_FCVT_Q_LU) +DECLARE_INSN(fcvt_q_s, MATCH_FCVT_Q_S, MASK_FCVT_Q_S) +DECLARE_INSN(fcvt_q_w, MATCH_FCVT_Q_W, MASK_FCVT_Q_W) +DECLARE_INSN(fcvt_q_wu, MATCH_FCVT_Q_WU, MASK_FCVT_Q_WU) +DECLARE_INSN(fcvt_s_d, MATCH_FCVT_S_D, MASK_FCVT_S_D) +DECLARE_INSN(fcvt_s_h, MATCH_FCVT_S_H, MASK_FCVT_S_H) +DECLARE_INSN(fcvt_s_l, MATCH_FCVT_S_L, MASK_FCVT_S_L) +DECLARE_INSN(fcvt_s_lu, MATCH_FCVT_S_LU, MASK_FCVT_S_LU) +DECLARE_INSN(fcvt_s_q, MATCH_FCVT_S_Q, MASK_FCVT_S_Q) +DECLARE_INSN(fcvt_s_w, MATCH_FCVT_S_W, MASK_FCVT_S_W) +DECLARE_INSN(fcvt_s_wu, MATCH_FCVT_S_WU, MASK_FCVT_S_WU) +DECLARE_INSN(fcvt_w_d, MATCH_FCVT_W_D, MASK_FCVT_W_D) +DECLARE_INSN(fcvt_w_h, MATCH_FCVT_W_H, MASK_FCVT_W_H) +DECLARE_INSN(fcvt_w_q, MATCH_FCVT_W_Q, MASK_FCVT_W_Q) +DECLARE_INSN(fcvt_w_s, MATCH_FCVT_W_S, MASK_FCVT_W_S) +DECLARE_INSN(fcvt_wu_d, MATCH_FCVT_WU_D, MASK_FCVT_WU_D) +DECLARE_INSN(fcvt_wu_h, MATCH_FCVT_WU_H, MASK_FCVT_WU_H) +DECLARE_INSN(fcvt_wu_q, MATCH_FCVT_WU_Q, MASK_FCVT_WU_Q) +DECLARE_INSN(fcvt_wu_s, MATCH_FCVT_WU_S, MASK_FCVT_WU_S) +DECLARE_INSN(fcvtmod_w_d, MATCH_FCVTMOD_W_D, MASK_FCVTMOD_W_D) +DECLARE_INSN(fdiv_d, MATCH_FDIV_D, MASK_FDIV_D) +DECLARE_INSN(fdiv_h, MATCH_FDIV_H, MASK_FDIV_H) +DECLARE_INSN(fdiv_q, MATCH_FDIV_Q, MASK_FDIV_Q) +DECLARE_INSN(fdiv_s, MATCH_FDIV_S, MASK_FDIV_S) +DECLARE_INSN(fence, MATCH_FENCE, MASK_FENCE) +DECLARE_INSN(fence_i, MATCH_FENCE_I, MASK_FENCE_I) +DECLARE_INSN(feq_d, MATCH_FEQ_D, MASK_FEQ_D) +DECLARE_INSN(feq_h, MATCH_FEQ_H, MASK_FEQ_H) +DECLARE_INSN(feq_q, MATCH_FEQ_Q, MASK_FEQ_Q) +DECLARE_INSN(feq_s, MATCH_FEQ_S, MASK_FEQ_S) +DECLARE_INSN(fld, MATCH_FLD, MASK_FLD) +DECLARE_INSN(fle_d, MATCH_FLE_D, MASK_FLE_D) +DECLARE_INSN(fle_h, MATCH_FLE_H, MASK_FLE_H) +DECLARE_INSN(fle_q, MATCH_FLE_Q, MASK_FLE_Q) +DECLARE_INSN(fle_s, MATCH_FLE_S, MASK_FLE_S) +DECLARE_INSN(fleq_d, MATCH_FLEQ_D, MASK_FLEQ_D) +DECLARE_INSN(fleq_h, MATCH_FLEQ_H, MASK_FLEQ_H) +DECLARE_INSN(fleq_q, MATCH_FLEQ_Q, MASK_FLEQ_Q) +DECLARE_INSN(fleq_s, MATCH_FLEQ_S, MASK_FLEQ_S) +DECLARE_INSN(flh, MATCH_FLH, MASK_FLH) +DECLARE_INSN(fli_d, MATCH_FLI_D, MASK_FLI_D) +DECLARE_INSN(fli_h, MATCH_FLI_H, MASK_FLI_H) +DECLARE_INSN(fli_q, MATCH_FLI_Q, MASK_FLI_Q) +DECLARE_INSN(fli_s, MATCH_FLI_S, MASK_FLI_S) +DECLARE_INSN(flq, MATCH_FLQ, MASK_FLQ) +DECLARE_INSN(flt_d, MATCH_FLT_D, MASK_FLT_D) +DECLARE_INSN(flt_h, MATCH_FLT_H, MASK_FLT_H) +DECLARE_INSN(flt_q, MATCH_FLT_Q, MASK_FLT_Q) +DECLARE_INSN(flt_s, MATCH_FLT_S, MASK_FLT_S) +DECLARE_INSN(fltq_d, MATCH_FLTQ_D, MASK_FLTQ_D) +DECLARE_INSN(fltq_h, MATCH_FLTQ_H, MASK_FLTQ_H) +DECLARE_INSN(fltq_q, MATCH_FLTQ_Q, MASK_FLTQ_Q) +DECLARE_INSN(fltq_s, MATCH_FLTQ_S, MASK_FLTQ_S) +DECLARE_INSN(flw, MATCH_FLW, MASK_FLW) +DECLARE_INSN(fmadd_d, MATCH_FMADD_D, MASK_FMADD_D) +DECLARE_INSN(fmadd_h, MATCH_FMADD_H, MASK_FMADD_H) +DECLARE_INSN(fmadd_q, MATCH_FMADD_Q, MASK_FMADD_Q) +DECLARE_INSN(fmadd_s, MATCH_FMADD_S, MASK_FMADD_S) +DECLARE_INSN(fmax_d, MATCH_FMAX_D, MASK_FMAX_D) +DECLARE_INSN(fmax_h, MATCH_FMAX_H, MASK_FMAX_H) +DECLARE_INSN(fmax_q, MATCH_FMAX_Q, MASK_FMAX_Q) +DECLARE_INSN(fmax_s, MATCH_FMAX_S, MASK_FMAX_S) +DECLARE_INSN(fmaxm_d, MATCH_FMAXM_D, MASK_FMAXM_D) +DECLARE_INSN(fmaxm_h, MATCH_FMAXM_H, MASK_FMAXM_H) +DECLARE_INSN(fmaxm_q, MATCH_FMAXM_Q, MASK_FMAXM_Q) +DECLARE_INSN(fmaxm_s, MATCH_FMAXM_S, MASK_FMAXM_S) +DECLARE_INSN(fmin_d, MATCH_FMIN_D, MASK_FMIN_D) +DECLARE_INSN(fmin_h, MATCH_FMIN_H, MASK_FMIN_H) +DECLARE_INSN(fmin_q, MATCH_FMIN_Q, MASK_FMIN_Q) +DECLARE_INSN(fmin_s, MATCH_FMIN_S, MASK_FMIN_S) +DECLARE_INSN(fminm_d, MATCH_FMINM_D, MASK_FMINM_D) +DECLARE_INSN(fminm_h, MATCH_FMINM_H, MASK_FMINM_H) +DECLARE_INSN(fminm_q, MATCH_FMINM_Q, MASK_FMINM_Q) +DECLARE_INSN(fminm_s, MATCH_FMINM_S, MASK_FMINM_S) +DECLARE_INSN(fmsub_d, MATCH_FMSUB_D, MASK_FMSUB_D) +DECLARE_INSN(fmsub_h, MATCH_FMSUB_H, MASK_FMSUB_H) +DECLARE_INSN(fmsub_q, MATCH_FMSUB_Q, MASK_FMSUB_Q) +DECLARE_INSN(fmsub_s, MATCH_FMSUB_S, MASK_FMSUB_S) +DECLARE_INSN(fmul_d, MATCH_FMUL_D, MASK_FMUL_D) +DECLARE_INSN(fmul_h, MATCH_FMUL_H, MASK_FMUL_H) +DECLARE_INSN(fmul_q, MATCH_FMUL_Q, MASK_FMUL_Q) +DECLARE_INSN(fmul_s, MATCH_FMUL_S, MASK_FMUL_S) +DECLARE_INSN(fmv_d_x, MATCH_FMV_D_X, MASK_FMV_D_X) +DECLARE_INSN(fmv_h_x, MATCH_FMV_H_X, MASK_FMV_H_X) +DECLARE_INSN(fmv_w_x, MATCH_FMV_W_X, MASK_FMV_W_X) +DECLARE_INSN(fmv_x_d, MATCH_FMV_X_D, MASK_FMV_X_D) +DECLARE_INSN(fmv_x_h, MATCH_FMV_X_H, MASK_FMV_X_H) +DECLARE_INSN(fmv_x_w, MATCH_FMV_X_W, MASK_FMV_X_W) +DECLARE_INSN(fmvh_x_d, MATCH_FMVH_X_D, MASK_FMVH_X_D) +DECLARE_INSN(fmvh_x_q, MATCH_FMVH_X_Q, MASK_FMVH_X_Q) +DECLARE_INSN(fmvp_d_x, MATCH_FMVP_D_X, MASK_FMVP_D_X) +DECLARE_INSN(fmvp_q_x, MATCH_FMVP_Q_X, MASK_FMVP_Q_X) +DECLARE_INSN(fnmadd_d, MATCH_FNMADD_D, MASK_FNMADD_D) +DECLARE_INSN(fnmadd_h, MATCH_FNMADD_H, MASK_FNMADD_H) +DECLARE_INSN(fnmadd_q, MATCH_FNMADD_Q, MASK_FNMADD_Q) +DECLARE_INSN(fnmadd_s, MATCH_FNMADD_S, MASK_FNMADD_S) +DECLARE_INSN(fnmsub_d, MATCH_FNMSUB_D, MASK_FNMSUB_D) +DECLARE_INSN(fnmsub_h, MATCH_FNMSUB_H, MASK_FNMSUB_H) +DECLARE_INSN(fnmsub_q, MATCH_FNMSUB_Q, MASK_FNMSUB_Q) +DECLARE_INSN(fnmsub_s, MATCH_FNMSUB_S, MASK_FNMSUB_S) +DECLARE_INSN(fround_d, MATCH_FROUND_D, MASK_FROUND_D) +DECLARE_INSN(fround_h, MATCH_FROUND_H, MASK_FROUND_H) +DECLARE_INSN(fround_q, MATCH_FROUND_Q, MASK_FROUND_Q) +DECLARE_INSN(fround_s, MATCH_FROUND_S, MASK_FROUND_S) +DECLARE_INSN(froundnx_d, MATCH_FROUNDNX_D, MASK_FROUNDNX_D) +DECLARE_INSN(froundnx_h, MATCH_FROUNDNX_H, MASK_FROUNDNX_H) +DECLARE_INSN(froundnx_q, MATCH_FROUNDNX_Q, MASK_FROUNDNX_Q) +DECLARE_INSN(froundnx_s, MATCH_FROUNDNX_S, MASK_FROUNDNX_S) +DECLARE_INSN(fsd, MATCH_FSD, MASK_FSD) +DECLARE_INSN(fsgnj_d, MATCH_FSGNJ_D, MASK_FSGNJ_D) +DECLARE_INSN(fsgnj_h, MATCH_FSGNJ_H, MASK_FSGNJ_H) +DECLARE_INSN(fsgnj_q, MATCH_FSGNJ_Q, MASK_FSGNJ_Q) +DECLARE_INSN(fsgnj_s, MATCH_FSGNJ_S, MASK_FSGNJ_S) +DECLARE_INSN(fsgnjn_d, MATCH_FSGNJN_D, MASK_FSGNJN_D) +DECLARE_INSN(fsgnjn_h, MATCH_FSGNJN_H, MASK_FSGNJN_H) +DECLARE_INSN(fsgnjn_q, MATCH_FSGNJN_Q, MASK_FSGNJN_Q) +DECLARE_INSN(fsgnjn_s, MATCH_FSGNJN_S, MASK_FSGNJN_S) +DECLARE_INSN(fsgnjx_d, MATCH_FSGNJX_D, MASK_FSGNJX_D) +DECLARE_INSN(fsgnjx_h, MATCH_FSGNJX_H, MASK_FSGNJX_H) +DECLARE_INSN(fsgnjx_q, MATCH_FSGNJX_Q, MASK_FSGNJX_Q) +DECLARE_INSN(fsgnjx_s, MATCH_FSGNJX_S, MASK_FSGNJX_S) +DECLARE_INSN(fsh, MATCH_FSH, MASK_FSH) +DECLARE_INSN(fsl, MATCH_FSL, MASK_FSL) +DECLARE_INSN(fslw, MATCH_FSLW, MASK_FSLW) +DECLARE_INSN(fsq, MATCH_FSQ, MASK_FSQ) +DECLARE_INSN(fsqrt_d, MATCH_FSQRT_D, MASK_FSQRT_D) +DECLARE_INSN(fsqrt_h, MATCH_FSQRT_H, MASK_FSQRT_H) +DECLARE_INSN(fsqrt_q, MATCH_FSQRT_Q, MASK_FSQRT_Q) +DECLARE_INSN(fsqrt_s, MATCH_FSQRT_S, MASK_FSQRT_S) +DECLARE_INSN(fsr, MATCH_FSR, MASK_FSR) +DECLARE_INSN(fsri, MATCH_FSRI, MASK_FSRI) +DECLARE_INSN(fsriw, MATCH_FSRIW, MASK_FSRIW) +DECLARE_INSN(fsrw, MATCH_FSRW, MASK_FSRW) +DECLARE_INSN(fsub_d, MATCH_FSUB_D, MASK_FSUB_D) +DECLARE_INSN(fsub_h, MATCH_FSUB_H, MASK_FSUB_H) +DECLARE_INSN(fsub_q, MATCH_FSUB_Q, MASK_FSUB_Q) +DECLARE_INSN(fsub_s, MATCH_FSUB_S, MASK_FSUB_S) +DECLARE_INSN(fsw, MATCH_FSW, MASK_FSW) +DECLARE_INSN(gorc, MATCH_GORC, MASK_GORC) +DECLARE_INSN(gorci, MATCH_GORCI, MASK_GORCI) +DECLARE_INSN(gorciw, MATCH_GORCIW, MASK_GORCIW) +DECLARE_INSN(gorcw, MATCH_GORCW, MASK_GORCW) +DECLARE_INSN(grev, MATCH_GREV, MASK_GREV) +DECLARE_INSN(grevi, MATCH_GREVI, MASK_GREVI) +DECLARE_INSN(greviw, MATCH_GREVIW, MASK_GREVIW) +DECLARE_INSN(grevw, MATCH_GREVW, MASK_GREVW) +DECLARE_INSN(hfence_gvma, MATCH_HFENCE_GVMA, MASK_HFENCE_GVMA) +DECLARE_INSN(hfence_vvma, MATCH_HFENCE_VVMA, MASK_HFENCE_VVMA) +DECLARE_INSN(hinval_gvma, MATCH_HINVAL_GVMA, MASK_HINVAL_GVMA) +DECLARE_INSN(hinval_vvma, MATCH_HINVAL_VVMA, MASK_HINVAL_VVMA) +DECLARE_INSN(hlv_b, MATCH_HLV_B, MASK_HLV_B) +DECLARE_INSN(hlv_bu, MATCH_HLV_BU, MASK_HLV_BU) +DECLARE_INSN(hlv_d, MATCH_HLV_D, MASK_HLV_D) +DECLARE_INSN(hlv_h, MATCH_HLV_H, MASK_HLV_H) +DECLARE_INSN(hlv_hu, MATCH_HLV_HU, MASK_HLV_HU) +DECLARE_INSN(hlv_w, MATCH_HLV_W, MASK_HLV_W) +DECLARE_INSN(hlv_wu, MATCH_HLV_WU, MASK_HLV_WU) +DECLARE_INSN(hlvx_hu, MATCH_HLVX_HU, MASK_HLVX_HU) +DECLARE_INSN(hlvx_wu, MATCH_HLVX_WU, MASK_HLVX_WU) +DECLARE_INSN(hsv_b, MATCH_HSV_B, MASK_HSV_B) +DECLARE_INSN(hsv_d, MATCH_HSV_D, MASK_HSV_D) +DECLARE_INSN(hsv_h, MATCH_HSV_H, MASK_HSV_H) +DECLARE_INSN(hsv_w, MATCH_HSV_W, MASK_HSV_W) DECLARE_INSN(insb, MATCH_INSB, MASK_INSB) -DECLARE_INSN(kabs8, MATCH_KABS8, MASK_KABS8) +DECLARE_INSN(jal, MATCH_JAL, MASK_JAL) +DECLARE_INSN(jalr, MATCH_JALR, MASK_JALR) DECLARE_INSN(kabs16, MATCH_KABS16, MASK_KABS16) +DECLARE_INSN(kabs32, MATCH_KABS32, MASK_KABS32) +DECLARE_INSN(kabs8, MATCH_KABS8, MASK_KABS8) DECLARE_INSN(kabsw, MATCH_KABSW, MASK_KABSW) -DECLARE_INSN(kadd8, MATCH_KADD8, MASK_KADD8) DECLARE_INSN(kadd16, MATCH_KADD16, MASK_KADD16) +DECLARE_INSN(kadd32, MATCH_KADD32, MASK_KADD32) DECLARE_INSN(kadd64, MATCH_KADD64, MASK_KADD64) +DECLARE_INSN(kadd8, MATCH_KADD8, MASK_KADD8) DECLARE_INSN(kaddh, MATCH_KADDH, MASK_KADDH) DECLARE_INSN(kaddw, MATCH_KADDW, MASK_KADDW) DECLARE_INSN(kcras16, MATCH_KCRAS16, MASK_KCRAS16) +DECLARE_INSN(kcras32, MATCH_KCRAS32, MASK_KCRAS32) DECLARE_INSN(kcrsa16, MATCH_KCRSA16, MASK_KCRSA16) -DECLARE_INSN(kdmbb, MATCH_KDMBB, MASK_KDMBB) -DECLARE_INSN(kdmbt, MATCH_KDMBT, MASK_KDMBT) -DECLARE_INSN(kdmtt, MATCH_KDMTT, MASK_KDMTT) +DECLARE_INSN(kcrsa32, MATCH_KCRSA32, MASK_KCRSA32) DECLARE_INSN(kdmabb, MATCH_KDMABB, MASK_KDMABB) +DECLARE_INSN(kdmabb16, MATCH_KDMABB16, MASK_KDMABB16) DECLARE_INSN(kdmabt, MATCH_KDMABT, MASK_KDMABT) +DECLARE_INSN(kdmabt16, MATCH_KDMABT16, MASK_KDMABT16) DECLARE_INSN(kdmatt, MATCH_KDMATT, MASK_KDMATT) -DECLARE_INSN(khm8, MATCH_KHM8, MASK_KHM8) -DECLARE_INSN(khmx8, MATCH_KHMX8, MASK_KHMX8) +DECLARE_INSN(kdmatt16, MATCH_KDMATT16, MASK_KDMATT16) +DECLARE_INSN(kdmbb, MATCH_KDMBB, MASK_KDMBB) +DECLARE_INSN(kdmbb16, MATCH_KDMBB16, MASK_KDMBB16) +DECLARE_INSN(kdmbt, MATCH_KDMBT, MASK_KDMBT) +DECLARE_INSN(kdmbt16, MATCH_KDMBT16, MASK_KDMBT16) +DECLARE_INSN(kdmtt, MATCH_KDMTT, MASK_KDMTT) +DECLARE_INSN(kdmtt16, MATCH_KDMTT16, MASK_KDMTT16) DECLARE_INSN(khm16, MATCH_KHM16, MASK_KHM16) -DECLARE_INSN(khmx16, MATCH_KHMX16, MASK_KHMX16) +DECLARE_INSN(khm8, MATCH_KHM8, MASK_KHM8) DECLARE_INSN(khmbb, MATCH_KHMBB, MASK_KHMBB) +DECLARE_INSN(khmbb16, MATCH_KHMBB16, MASK_KHMBB16) DECLARE_INSN(khmbt, MATCH_KHMBT, MASK_KHMBT) +DECLARE_INSN(khmbt16, MATCH_KHMBT16, MASK_KHMBT16) DECLARE_INSN(khmtt, MATCH_KHMTT, MASK_KHMTT) +DECLARE_INSN(khmtt16, MATCH_KHMTT16, MASK_KHMTT16) +DECLARE_INSN(khmx16, MATCH_KHMX16, MASK_KHMX16) +DECLARE_INSN(khmx8, MATCH_KHMX8, MASK_KHMX8) DECLARE_INSN(kmabb, MATCH_KMABB, MASK_KMABB) +DECLARE_INSN(kmabb32, MATCH_KMABB32, MASK_KMABB32) DECLARE_INSN(kmabt, MATCH_KMABT, MASK_KMABT) -DECLARE_INSN(kmatt, MATCH_KMATT, MASK_KMATT) +DECLARE_INSN(kmabt32, MATCH_KMABT32, MASK_KMABT32) DECLARE_INSN(kmada, MATCH_KMADA, MASK_KMADA) -DECLARE_INSN(kmaxda, MATCH_KMAXDA, MASK_KMAXDA) -DECLARE_INSN(kmads, MATCH_KMADS, MASK_KMADS) DECLARE_INSN(kmadrs, MATCH_KMADRS, MASK_KMADRS) -DECLARE_INSN(kmaxds, MATCH_KMAXDS, MASK_KMAXDS) +DECLARE_INSN(kmadrs32, MATCH_KMADRS32, MASK_KMADRS32) +DECLARE_INSN(kmads, MATCH_KMADS, MASK_KMADS) +DECLARE_INSN(kmads32, MATCH_KMADS32, MASK_KMADS32) DECLARE_INSN(kmar64, MATCH_KMAR64, MASK_KMAR64) +DECLARE_INSN(kmatt, MATCH_KMATT, MASK_KMATT) +DECLARE_INSN(kmatt32, MATCH_KMATT32, MASK_KMATT32) +DECLARE_INSN(kmaxda, MATCH_KMAXDA, MASK_KMAXDA) +DECLARE_INSN(kmaxda32, MATCH_KMAXDA32, MASK_KMAXDA32) +DECLARE_INSN(kmaxds, MATCH_KMAXDS, MASK_KMAXDS) +DECLARE_INSN(kmaxds32, MATCH_KMAXDS32, MASK_KMAXDS32) DECLARE_INSN(kmda, MATCH_KMDA, MASK_KMDA) -DECLARE_INSN(kmxda, MATCH_KMXDA, MASK_KMXDA) +DECLARE_INSN(kmda32, MATCH_KMDA32, MASK_KMDA32) DECLARE_INSN(kmmac, MATCH_KMMAC, MASK_KMMAC) DECLARE_INSN(kmmac_u, MATCH_KMMAC_U, MASK_KMMAC_U) DECLARE_INSN(kmmawb, MATCH_KMMAWB, MASK_KMMAWB) -DECLARE_INSN(kmmawb_u, MATCH_KMMAWB_U, MASK_KMMAWB_U) DECLARE_INSN(kmmawb2, MATCH_KMMAWB2, MASK_KMMAWB2) DECLARE_INSN(kmmawb2_u, MATCH_KMMAWB2_U, MASK_KMMAWB2_U) +DECLARE_INSN(kmmawb_u, MATCH_KMMAWB_U, MASK_KMMAWB_U) DECLARE_INSN(kmmawt, MATCH_KMMAWT, MASK_KMMAWT) -DECLARE_INSN(kmmawt_u, MATCH_KMMAWT_U, MASK_KMMAWT_U) DECLARE_INSN(kmmawt2, MATCH_KMMAWT2, MASK_KMMAWT2) DECLARE_INSN(kmmawt2_u, MATCH_KMMAWT2_U, MASK_KMMAWT2_U) +DECLARE_INSN(kmmawt_u, MATCH_KMMAWT_U, MASK_KMMAWT_U) DECLARE_INSN(kmmsb, MATCH_KMMSB, MASK_KMMSB) DECLARE_INSN(kmmsb_u, MATCH_KMMSB_U, MASK_KMMSB_U) DECLARE_INSN(kmmwb2, MATCH_KMMWB2, MASK_KMMWB2) @@ -4074,86 +3898,208 @@ DECLARE_INSN(kmmwb2_u, MATCH_KMMWB2_U, MASK_KMMWB2_U) DECLARE_INSN(kmmwt2, MATCH_KMMWT2, MASK_KMMWT2) DECLARE_INSN(kmmwt2_u, MATCH_KMMWT2_U, MASK_KMMWT2_U) DECLARE_INSN(kmsda, MATCH_KMSDA, MASK_KMSDA) -DECLARE_INSN(kmsxda, MATCH_KMSXDA, MASK_KMSXDA) +DECLARE_INSN(kmsda32, MATCH_KMSDA32, MASK_KMSDA32) DECLARE_INSN(kmsr64, MATCH_KMSR64, MASK_KMSR64) -DECLARE_INSN(ksllw, MATCH_KSLLW, MASK_KSLLW) -DECLARE_INSN(kslliw, MATCH_KSLLIW, MASK_KSLLIW) -DECLARE_INSN(ksll8, MATCH_KSLL8, MASK_KSLL8) -DECLARE_INSN(kslli8, MATCH_KSLLI8, MASK_KSLLI8) +DECLARE_INSN(kmsxda, MATCH_KMSXDA, MASK_KMSXDA) +DECLARE_INSN(kmsxda32, MATCH_KMSXDA32, MASK_KMSXDA32) +DECLARE_INSN(kmxda, MATCH_KMXDA, MASK_KMXDA) +DECLARE_INSN(kmxda32, MATCH_KMXDA32, MASK_KMXDA32) DECLARE_INSN(ksll16, MATCH_KSLL16, MASK_KSLL16) +DECLARE_INSN(ksll32, MATCH_KSLL32, MASK_KSLL32) +DECLARE_INSN(ksll8, MATCH_KSLL8, MASK_KSLL8) DECLARE_INSN(kslli16, MATCH_KSLLI16, MASK_KSLLI16) -DECLARE_INSN(kslra8, MATCH_KSLRA8, MASK_KSLRA8) -DECLARE_INSN(kslra8_u, MATCH_KSLRA8_U, MASK_KSLRA8_U) +DECLARE_INSN(kslli32, MATCH_KSLLI32, MASK_KSLLI32) +DECLARE_INSN(kslli8, MATCH_KSLLI8, MASK_KSLLI8) +DECLARE_INSN(kslliw, MATCH_KSLLIW, MASK_KSLLIW) +DECLARE_INSN(ksllw, MATCH_KSLLW, MASK_KSLLW) DECLARE_INSN(kslra16, MATCH_KSLRA16, MASK_KSLRA16) DECLARE_INSN(kslra16_u, MATCH_KSLRA16_U, MASK_KSLRA16_U) +DECLARE_INSN(kslra32, MATCH_KSLRA32, MASK_KSLRA32) +DECLARE_INSN(kslra32_u, MATCH_KSLRA32_U, MASK_KSLRA32_U) +DECLARE_INSN(kslra8, MATCH_KSLRA8, MASK_KSLRA8) +DECLARE_INSN(kslra8_u, MATCH_KSLRA8_U, MASK_KSLRA8_U) DECLARE_INSN(kslraw, MATCH_KSLRAW, MASK_KSLRAW) DECLARE_INSN(kslraw_u, MATCH_KSLRAW_U, MASK_KSLRAW_U) DECLARE_INSN(kstas16, MATCH_KSTAS16, MASK_KSTAS16) +DECLARE_INSN(kstas32, MATCH_KSTAS32, MASK_KSTAS32) DECLARE_INSN(kstsa16, MATCH_KSTSA16, MASK_KSTSA16) -DECLARE_INSN(ksub8, MATCH_KSUB8, MASK_KSUB8) +DECLARE_INSN(kstsa32, MATCH_KSTSA32, MASK_KSTSA32) DECLARE_INSN(ksub16, MATCH_KSUB16, MASK_KSUB16) +DECLARE_INSN(ksub32, MATCH_KSUB32, MASK_KSUB32) DECLARE_INSN(ksub64, MATCH_KSUB64, MASK_KSUB64) +DECLARE_INSN(ksub8, MATCH_KSUB8, MASK_KSUB8) DECLARE_INSN(ksubh, MATCH_KSUBH, MASK_KSUBH) DECLARE_INSN(ksubw, MATCH_KSUBW, MASK_KSUBW) DECLARE_INSN(kwmmul, MATCH_KWMMUL, MASK_KWMMUL) DECLARE_INSN(kwmmul_u, MATCH_KWMMUL_U, MASK_KWMMUL_U) +DECLARE_INSN(lb, MATCH_LB, MASK_LB) +DECLARE_INSN(lbu, MATCH_LBU, MASK_LBU) +DECLARE_INSN(ld, MATCH_LD, MASK_LD) +DECLARE_INSN(ldu, MATCH_LDU, MASK_LDU) +DECLARE_INSN(lh, MATCH_LH, MASK_LH) +DECLARE_INSN(lhu, MATCH_LHU, MASK_LHU) +DECLARE_INSN(lq, MATCH_LQ, MASK_LQ) +DECLARE_INSN(lr_d, MATCH_LR_D, MASK_LR_D) +DECLARE_INSN(lr_w, MATCH_LR_W, MASK_LR_W) +DECLARE_INSN(lui, MATCH_LUI, MASK_LUI) +DECLARE_INSN(lw, MATCH_LW, MASK_LW) +DECLARE_INSN(lwu, MATCH_LWU, MASK_LWU) DECLARE_INSN(maddr32, MATCH_MADDR32, MASK_MADDR32) -DECLARE_INSN(maxw, MATCH_MAXW, MASK_MAXW) -DECLARE_INSN(minw, MATCH_MINW, MASK_MINW) +DECLARE_INSN(max, MATCH_MAX, MASK_MAX) +DECLARE_INSN(maxu, MATCH_MAXU, MASK_MAXU) +DECLARE_INSN(min, MATCH_MIN, MASK_MIN) +DECLARE_INSN(minu, MATCH_MINU, MASK_MINU) +DECLARE_INSN(mnret, MATCH_MNRET, MASK_MNRET) +DECLARE_INSN(mret, MATCH_MRET, MASK_MRET) DECLARE_INSN(msubr32, MATCH_MSUBR32, MASK_MSUBR32) +DECLARE_INSN(mul, MATCH_MUL, MASK_MUL) +DECLARE_INSN(mulh, MATCH_MULH, MASK_MULH) +DECLARE_INSN(mulhsu, MATCH_MULHSU, MASK_MULHSU) +DECLARE_INSN(mulhu, MATCH_MULHU, MASK_MULHU) DECLARE_INSN(mulr64, MATCH_MULR64, MASK_MULR64) DECLARE_INSN(mulsr64, MATCH_MULSR64, MASK_MULSR64) +DECLARE_INSN(mulw, MATCH_MULW, MASK_MULW) +DECLARE_INSN(or, MATCH_OR, MASK_OR) +DECLARE_INSN(ori, MATCH_ORI, MASK_ORI) +DECLARE_INSN(orn, MATCH_ORN, MASK_ORN) +DECLARE_INSN(pack, MATCH_PACK, MASK_PACK) +DECLARE_INSN(packh, MATCH_PACKH, MASK_PACKH) +DECLARE_INSN(packu, MATCH_PACKU, MASK_PACKU) +DECLARE_INSN(packuw, MATCH_PACKUW, MASK_PACKUW) +DECLARE_INSN(packw, MATCH_PACKW, MASK_PACKW) +DECLARE_INSN(pause, MATCH_PAUSE, MASK_PAUSE) DECLARE_INSN(pbsad, MATCH_PBSAD, MASK_PBSAD) DECLARE_INSN(pbsada, MATCH_PBSADA, MASK_PBSADA) DECLARE_INSN(pkbb16, MATCH_PKBB16, MASK_PKBB16) DECLARE_INSN(pkbt16, MATCH_PKBT16, MASK_PKBT16) -DECLARE_INSN(pktt16, MATCH_PKTT16, MASK_PKTT16) +DECLARE_INSN(pkbt32, MATCH_PKBT32, MASK_PKBT32) DECLARE_INSN(pktb16, MATCH_PKTB16, MASK_PKTB16) -DECLARE_INSN(radd8, MATCH_RADD8, MASK_RADD8) +DECLARE_INSN(pktb32, MATCH_PKTB32, MASK_PKTB32) +DECLARE_INSN(pktt16, MATCH_PKTT16, MASK_PKTT16) +DECLARE_INSN(prefetch_i, MATCH_PREFETCH_I, MASK_PREFETCH_I) +DECLARE_INSN(prefetch_r, MATCH_PREFETCH_R, MASK_PREFETCH_R) +DECLARE_INSN(prefetch_w, MATCH_PREFETCH_W, MASK_PREFETCH_W) DECLARE_INSN(radd16, MATCH_RADD16, MASK_RADD16) +DECLARE_INSN(radd32, MATCH_RADD32, MASK_RADD32) DECLARE_INSN(radd64, MATCH_RADD64, MASK_RADD64) +DECLARE_INSN(radd8, MATCH_RADD8, MASK_RADD8) DECLARE_INSN(raddw, MATCH_RADDW, MASK_RADDW) DECLARE_INSN(rcras16, MATCH_RCRAS16, MASK_RCRAS16) +DECLARE_INSN(rcras32, MATCH_RCRAS32, MASK_RCRAS32) DECLARE_INSN(rcrsa16, MATCH_RCRSA16, MASK_RCRSA16) +DECLARE_INSN(rcrsa32, MATCH_RCRSA32, MASK_RCRSA32) +DECLARE_INSN(rem, MATCH_REM, MASK_REM) +DECLARE_INSN(remu, MATCH_REMU, MASK_REMU) +DECLARE_INSN(remuw, MATCH_REMUW, MASK_REMUW) +DECLARE_INSN(remw, MATCH_REMW, MASK_REMW) +DECLARE_INSN(rol, MATCH_ROL, MASK_ROL) +DECLARE_INSN(rolw, MATCH_ROLW, MASK_ROLW) +DECLARE_INSN(ror, MATCH_ROR, MASK_ROR) +DECLARE_INSN(rori, MATCH_RORI, MASK_RORI) +DECLARE_INSN(roriw, MATCH_RORIW, MASK_RORIW) +DECLARE_INSN(rorw, MATCH_RORW, MASK_RORW) DECLARE_INSN(rstas16, MATCH_RSTAS16, MASK_RSTAS16) +DECLARE_INSN(rstas32, MATCH_RSTAS32, MASK_RSTAS32) DECLARE_INSN(rstsa16, MATCH_RSTSA16, MASK_RSTSA16) -DECLARE_INSN(rsub8, MATCH_RSUB8, MASK_RSUB8) +DECLARE_INSN(rstsa32, MATCH_RSTSA32, MASK_RSTSA32) DECLARE_INSN(rsub16, MATCH_RSUB16, MASK_RSUB16) +DECLARE_INSN(rsub32, MATCH_RSUB32, MASK_RSUB32) DECLARE_INSN(rsub64, MATCH_RSUB64, MASK_RSUB64) +DECLARE_INSN(rsub8, MATCH_RSUB8, MASK_RSUB8) DECLARE_INSN(rsubw, MATCH_RSUBW, MASK_RSUBW) -DECLARE_INSN(sclip8, MATCH_SCLIP8, MASK_SCLIP8) +DECLARE_INSN(sb, MATCH_SB, MASK_SB) +DECLARE_INSN(sc_d, MATCH_SC_D, MASK_SC_D) +DECLARE_INSN(sc_w, MATCH_SC_W, MASK_SC_W) DECLARE_INSN(sclip16, MATCH_SCLIP16, MASK_SCLIP16) DECLARE_INSN(sclip32, MATCH_SCLIP32, MASK_SCLIP32) -DECLARE_INSN(scmple8, MATCH_SCMPLE8, MASK_SCMPLE8) +DECLARE_INSN(sclip8, MATCH_SCLIP8, MASK_SCLIP8) DECLARE_INSN(scmple16, MATCH_SCMPLE16, MASK_SCMPLE16) -DECLARE_INSN(scmplt8, MATCH_SCMPLT8, MASK_SCMPLT8) +DECLARE_INSN(scmple8, MATCH_SCMPLE8, MASK_SCMPLE8) DECLARE_INSN(scmplt16, MATCH_SCMPLT16, MASK_SCMPLT16) -DECLARE_INSN(sll8, MATCH_SLL8, MASK_SLL8) -DECLARE_INSN(slli8, MATCH_SLLI8, MASK_SLLI8) +DECLARE_INSN(scmplt8, MATCH_SCMPLT8, MASK_SCMPLT8) +DECLARE_INSN(sd, MATCH_SD, MASK_SD) +DECLARE_INSN(sext_b, MATCH_SEXT_B, MASK_SEXT_B) +DECLARE_INSN(sext_h, MATCH_SEXT_H, MASK_SEXT_H) +DECLARE_INSN(sfence_inval_ir, MATCH_SFENCE_INVAL_IR, MASK_SFENCE_INVAL_IR) +DECLARE_INSN(sfence_vma, MATCH_SFENCE_VMA, MASK_SFENCE_VMA) +DECLARE_INSN(sfence_w_inval, MATCH_SFENCE_W_INVAL, MASK_SFENCE_W_INVAL) +DECLARE_INSN(sh, MATCH_SH, MASK_SH) +DECLARE_INSN(sh1add, MATCH_SH1ADD, MASK_SH1ADD) +DECLARE_INSN(sh1add_uw, MATCH_SH1ADD_UW, MASK_SH1ADD_UW) +DECLARE_INSN(sh2add, MATCH_SH2ADD, MASK_SH2ADD) +DECLARE_INSN(sh2add_uw, MATCH_SH2ADD_UW, MASK_SH2ADD_UW) +DECLARE_INSN(sh3add, MATCH_SH3ADD, MASK_SH3ADD) +DECLARE_INSN(sh3add_uw, MATCH_SH3ADD_UW, MASK_SH3ADD_UW) +DECLARE_INSN(sha256sig0, MATCH_SHA256SIG0, MASK_SHA256SIG0) +DECLARE_INSN(sha256sig1, MATCH_SHA256SIG1, MASK_SHA256SIG1) +DECLARE_INSN(sha256sum0, MATCH_SHA256SUM0, MASK_SHA256SUM0) +DECLARE_INSN(sha256sum1, MATCH_SHA256SUM1, MASK_SHA256SUM1) +DECLARE_INSN(sha512sig0, MATCH_SHA512SIG0, MASK_SHA512SIG0) +DECLARE_INSN(sha512sig0h, MATCH_SHA512SIG0H, MASK_SHA512SIG0H) +DECLARE_INSN(sha512sig0l, MATCH_SHA512SIG0L, MASK_SHA512SIG0L) +DECLARE_INSN(sha512sig1, MATCH_SHA512SIG1, MASK_SHA512SIG1) +DECLARE_INSN(sha512sig1h, MATCH_SHA512SIG1H, MASK_SHA512SIG1H) +DECLARE_INSN(sha512sig1l, MATCH_SHA512SIG1L, MASK_SHA512SIG1L) +DECLARE_INSN(sha512sum0, MATCH_SHA512SUM0, MASK_SHA512SUM0) +DECLARE_INSN(sha512sum0r, MATCH_SHA512SUM0R, MASK_SHA512SUM0R) +DECLARE_INSN(sha512sum1, MATCH_SHA512SUM1, MASK_SHA512SUM1) +DECLARE_INSN(sha512sum1r, MATCH_SHA512SUM1R, MASK_SHA512SUM1R) +DECLARE_INSN(shfl, MATCH_SHFL, MASK_SHFL) +DECLARE_INSN(shfli, MATCH_SHFLI, MASK_SHFLI) +DECLARE_INSN(shflw, MATCH_SHFLW, MASK_SHFLW) +DECLARE_INSN(sinval_vma, MATCH_SINVAL_VMA, MASK_SINVAL_VMA) +DECLARE_INSN(sll, MATCH_SLL, MASK_SLL) DECLARE_INSN(sll16, MATCH_SLL16, MASK_SLL16) +DECLARE_INSN(sll32, MATCH_SLL32, MASK_SLL32) +DECLARE_INSN(sll8, MATCH_SLL8, MASK_SLL8) +DECLARE_INSN(slld, MATCH_SLLD, MASK_SLLD) +DECLARE_INSN(slli, MATCH_SLLI, MASK_SLLI) DECLARE_INSN(slli16, MATCH_SLLI16, MASK_SLLI16) +DECLARE_INSN(slli32, MATCH_SLLI32, MASK_SLLI32) +DECLARE_INSN(slli8, MATCH_SLLI8, MASK_SLLI8) +DECLARE_INSN(slli_rv128, MATCH_SLLI_RV128, MASK_SLLI_RV128) +DECLARE_INSN(slli_rv32, MATCH_SLLI_RV32, MASK_SLLI_RV32) +DECLARE_INSN(slli_uw, MATCH_SLLI_UW, MASK_SLLI_UW) +DECLARE_INSN(sllid, MATCH_SLLID, MASK_SLLID) +DECLARE_INSN(slliw, MATCH_SLLIW, MASK_SLLIW) +DECLARE_INSN(sllw, MATCH_SLLW, MASK_SLLW) +DECLARE_INSN(slo, MATCH_SLO, MASK_SLO) +DECLARE_INSN(sloi, MATCH_SLOI, MASK_SLOI) +DECLARE_INSN(sloiw, MATCH_SLOIW, MASK_SLOIW) +DECLARE_INSN(slow, MATCH_SLOW, MASK_SLOW) +DECLARE_INSN(slt, MATCH_SLT, MASK_SLT) +DECLARE_INSN(slti, MATCH_SLTI, MASK_SLTI) +DECLARE_INSN(sltiu, MATCH_SLTIU, MASK_SLTIU) +DECLARE_INSN(sltu, MATCH_SLTU, MASK_SLTU) +DECLARE_INSN(sm3p0, MATCH_SM3P0, MASK_SM3P0) +DECLARE_INSN(sm3p1, MATCH_SM3P1, MASK_SM3P1) +DECLARE_INSN(sm4ed, MATCH_SM4ED, MASK_SM4ED) +DECLARE_INSN(sm4ks, MATCH_SM4KS, MASK_SM4KS) DECLARE_INSN(smal, MATCH_SMAL, MASK_SMAL) DECLARE_INSN(smalbb, MATCH_SMALBB, MASK_SMALBB) DECLARE_INSN(smalbt, MATCH_SMALBT, MASK_SMALBT) -DECLARE_INSN(smaltt, MATCH_SMALTT, MASK_SMALTT) DECLARE_INSN(smalda, MATCH_SMALDA, MASK_SMALDA) -DECLARE_INSN(smalxda, MATCH_SMALXDA, MASK_SMALXDA) -DECLARE_INSN(smalds, MATCH_SMALDS, MASK_SMALDS) DECLARE_INSN(smaldrs, MATCH_SMALDRS, MASK_SMALDRS) +DECLARE_INSN(smalds, MATCH_SMALDS, MASK_SMALDS) +DECLARE_INSN(smaltt, MATCH_SMALTT, MASK_SMALTT) +DECLARE_INSN(smalxda, MATCH_SMALXDA, MASK_SMALXDA) DECLARE_INSN(smalxds, MATCH_SMALXDS, MASK_SMALXDS) -DECLARE_INSN(smar64, MATCH_SMAR64, MASK_SMAR64) DECLARE_INSN(smaqa, MATCH_SMAQA, MASK_SMAQA) DECLARE_INSN(smaqa_su, MATCH_SMAQA_SU, MASK_SMAQA_SU) -DECLARE_INSN(smax8, MATCH_SMAX8, MASK_SMAX8) +DECLARE_INSN(smar64, MATCH_SMAR64, MASK_SMAR64) DECLARE_INSN(smax16, MATCH_SMAX16, MASK_SMAX16) +DECLARE_INSN(smax32, MATCH_SMAX32, MASK_SMAX32) +DECLARE_INSN(smax8, MATCH_SMAX8, MASK_SMAX8) DECLARE_INSN(smbb16, MATCH_SMBB16, MASK_SMBB16) DECLARE_INSN(smbt16, MATCH_SMBT16, MASK_SMBT16) -DECLARE_INSN(smtt16, MATCH_SMTT16, MASK_SMTT16) -DECLARE_INSN(smds, MATCH_SMDS, MASK_SMDS) +DECLARE_INSN(smbt32, MATCH_SMBT32, MASK_SMBT32) DECLARE_INSN(smdrs, MATCH_SMDRS, MASK_SMDRS) -DECLARE_INSN(smxds, MATCH_SMXDS, MASK_SMXDS) -DECLARE_INSN(smin8, MATCH_SMIN8, MASK_SMIN8) +DECLARE_INSN(smdrs32, MATCH_SMDRS32, MASK_SMDRS32) +DECLARE_INSN(smds, MATCH_SMDS, MASK_SMDS) +DECLARE_INSN(smds32, MATCH_SMDS32, MASK_SMDS32) DECLARE_INSN(smin16, MATCH_SMIN16, MASK_SMIN16) +DECLARE_INSN(smin32, MATCH_SMIN32, MASK_SMIN32) +DECLARE_INSN(smin8, MATCH_SMIN8, MASK_SMIN8) DECLARE_INSN(smmul, MATCH_SMMUL, MASK_SMMUL) DECLARE_INSN(smmul_u, MATCH_SMMUL_U, MASK_SMMUL_U) DECLARE_INSN(smmwb, MATCH_SMMWB, MASK_SMMWB) @@ -4163,181 +4109,605 @@ DECLARE_INSN(smmwt_u, MATCH_SMMWT_U, MASK_SMMWT_U) DECLARE_INSN(smslda, MATCH_SMSLDA, MASK_SMSLDA) DECLARE_INSN(smslxda, MATCH_SMSLXDA, MASK_SMSLXDA) DECLARE_INSN(smsr64, MATCH_SMSR64, MASK_SMSR64) -DECLARE_INSN(smul8, MATCH_SMUL8, MASK_SMUL8) -DECLARE_INSN(smulx8, MATCH_SMULX8, MASK_SMULX8) +DECLARE_INSN(smtt16, MATCH_SMTT16, MASK_SMTT16) +DECLARE_INSN(smtt32, MATCH_SMTT32, MASK_SMTT32) DECLARE_INSN(smul16, MATCH_SMUL16, MASK_SMUL16) +DECLARE_INSN(smul8, MATCH_SMUL8, MASK_SMUL8) DECLARE_INSN(smulx16, MATCH_SMULX16, MASK_SMULX16) -DECLARE_INSN(sra_u, MATCH_SRA_U, MASK_SRA_U) -DECLARE_INSN(srai_u, MATCH_SRAI_U, MASK_SRAI_U) -DECLARE_INSN(sra8, MATCH_SRA8, MASK_SRA8) -DECLARE_INSN(sra8_u, MATCH_SRA8_U, MASK_SRA8_U) -DECLARE_INSN(srai8, MATCH_SRAI8, MASK_SRAI8) -DECLARE_INSN(srai8_u, MATCH_SRAI8_U, MASK_SRAI8_U) +DECLARE_INSN(smulx8, MATCH_SMULX8, MASK_SMULX8) +DECLARE_INSN(smxds, MATCH_SMXDS, MASK_SMXDS) +DECLARE_INSN(smxds32, MATCH_SMXDS32, MASK_SMXDS32) +DECLARE_INSN(sq, MATCH_SQ, MASK_SQ) +DECLARE_INSN(sra, MATCH_SRA, MASK_SRA) DECLARE_INSN(sra16, MATCH_SRA16, MASK_SRA16) DECLARE_INSN(sra16_u, MATCH_SRA16_U, MASK_SRA16_U) +DECLARE_INSN(sra32, MATCH_SRA32, MASK_SRA32) +DECLARE_INSN(sra32_u, MATCH_SRA32_U, MASK_SRA32_U) +DECLARE_INSN(sra8, MATCH_SRA8, MASK_SRA8) +DECLARE_INSN(sra8_u, MATCH_SRA8_U, MASK_SRA8_U) +DECLARE_INSN(sra_u, MATCH_SRA_U, MASK_SRA_U) +DECLARE_INSN(srad, MATCH_SRAD, MASK_SRAD) +DECLARE_INSN(srai, MATCH_SRAI, MASK_SRAI) DECLARE_INSN(srai16, MATCH_SRAI16, MASK_SRAI16) DECLARE_INSN(srai16_u, MATCH_SRAI16_U, MASK_SRAI16_U) -DECLARE_INSN(srl8, MATCH_SRL8, MASK_SRL8) -DECLARE_INSN(srl8_u, MATCH_SRL8_U, MASK_SRL8_U) -DECLARE_INSN(srli8, MATCH_SRLI8, MASK_SRLI8) -DECLARE_INSN(srli8_u, MATCH_SRLI8_U, MASK_SRLI8_U) +DECLARE_INSN(srai32, MATCH_SRAI32, MASK_SRAI32) +DECLARE_INSN(srai32_u, MATCH_SRAI32_U, MASK_SRAI32_U) +DECLARE_INSN(srai8, MATCH_SRAI8, MASK_SRAI8) +DECLARE_INSN(srai8_u, MATCH_SRAI8_U, MASK_SRAI8_U) +DECLARE_INSN(srai_rv128, MATCH_SRAI_RV128, MASK_SRAI_RV128) +DECLARE_INSN(srai_rv32, MATCH_SRAI_RV32, MASK_SRAI_RV32) +DECLARE_INSN(srai_u, MATCH_SRAI_U, MASK_SRAI_U) +DECLARE_INSN(sraid, MATCH_SRAID, MASK_SRAID) +DECLARE_INSN(sraiw, MATCH_SRAIW, MASK_SRAIW) +DECLARE_INSN(sraiw_u, MATCH_SRAIW_U, MASK_SRAIW_U) +DECLARE_INSN(sraw, MATCH_SRAW, MASK_SRAW) +DECLARE_INSN(sret, MATCH_SRET, MASK_SRET) +DECLARE_INSN(srl, MATCH_SRL, MASK_SRL) DECLARE_INSN(srl16, MATCH_SRL16, MASK_SRL16) DECLARE_INSN(srl16_u, MATCH_SRL16_U, MASK_SRL16_U) +DECLARE_INSN(srl32, MATCH_SRL32, MASK_SRL32) +DECLARE_INSN(srl32_u, MATCH_SRL32_U, MASK_SRL32_U) +DECLARE_INSN(srl8, MATCH_SRL8, MASK_SRL8) +DECLARE_INSN(srl8_u, MATCH_SRL8_U, MASK_SRL8_U) +DECLARE_INSN(srld, MATCH_SRLD, MASK_SRLD) +DECLARE_INSN(srli, MATCH_SRLI, MASK_SRLI) DECLARE_INSN(srli16, MATCH_SRLI16, MASK_SRLI16) DECLARE_INSN(srli16_u, MATCH_SRLI16_U, MASK_SRLI16_U) +DECLARE_INSN(srli32, MATCH_SRLI32, MASK_SRLI32) +DECLARE_INSN(srli32_u, MATCH_SRLI32_U, MASK_SRLI32_U) +DECLARE_INSN(srli8, MATCH_SRLI8, MASK_SRLI8) +DECLARE_INSN(srli8_u, MATCH_SRLI8_U, MASK_SRLI8_U) +DECLARE_INSN(srli_rv128, MATCH_SRLI_RV128, MASK_SRLI_RV128) +DECLARE_INSN(srli_rv32, MATCH_SRLI_RV32, MASK_SRLI_RV32) +DECLARE_INSN(srlid, MATCH_SRLID, MASK_SRLID) +DECLARE_INSN(srliw, MATCH_SRLIW, MASK_SRLIW) +DECLARE_INSN(srlw, MATCH_SRLW, MASK_SRLW) +DECLARE_INSN(sro, MATCH_SRO, MASK_SRO) +DECLARE_INSN(sroi, MATCH_SROI, MASK_SROI) +DECLARE_INSN(sroiw, MATCH_SROIW, MASK_SROIW) +DECLARE_INSN(srow, MATCH_SROW, MASK_SROW) DECLARE_INSN(stas16, MATCH_STAS16, MASK_STAS16) +DECLARE_INSN(stas32, MATCH_STAS32, MASK_STAS32) DECLARE_INSN(stsa16, MATCH_STSA16, MASK_STSA16) -DECLARE_INSN(sub8, MATCH_SUB8, MASK_SUB8) +DECLARE_INSN(stsa32, MATCH_STSA32, MASK_STSA32) +DECLARE_INSN(sub, MATCH_SUB, MASK_SUB) DECLARE_INSN(sub16, MATCH_SUB16, MASK_SUB16) +DECLARE_INSN(sub32, MATCH_SUB32, MASK_SUB32) DECLARE_INSN(sub64, MATCH_SUB64, MASK_SUB64) +DECLARE_INSN(sub8, MATCH_SUB8, MASK_SUB8) +DECLARE_INSN(subd, MATCH_SUBD, MASK_SUBD) +DECLARE_INSN(subw, MATCH_SUBW, MASK_SUBW) DECLARE_INSN(sunpkd810, MATCH_SUNPKD810, MASK_SUNPKD810) DECLARE_INSN(sunpkd820, MATCH_SUNPKD820, MASK_SUNPKD820) DECLARE_INSN(sunpkd830, MATCH_SUNPKD830, MASK_SUNPKD830) DECLARE_INSN(sunpkd831, MATCH_SUNPKD831, MASK_SUNPKD831) DECLARE_INSN(sunpkd832, MATCH_SUNPKD832, MASK_SUNPKD832) -DECLARE_INSN(swap8, MATCH_SWAP8, MASK_SWAP8) -DECLARE_INSN(uclip8, MATCH_UCLIP8, MASK_UCLIP8) +DECLARE_INSN(sw, MATCH_SW, MASK_SW) DECLARE_INSN(uclip16, MATCH_UCLIP16, MASK_UCLIP16) DECLARE_INSN(uclip32, MATCH_UCLIP32, MASK_UCLIP32) -DECLARE_INSN(ucmple8, MATCH_UCMPLE8, MASK_UCMPLE8) +DECLARE_INSN(uclip8, MATCH_UCLIP8, MASK_UCLIP8) DECLARE_INSN(ucmple16, MATCH_UCMPLE16, MASK_UCMPLE16) -DECLARE_INSN(ucmplt8, MATCH_UCMPLT8, MASK_UCMPLT8) +DECLARE_INSN(ucmple8, MATCH_UCMPLE8, MASK_UCMPLE8) DECLARE_INSN(ucmplt16, MATCH_UCMPLT16, MASK_UCMPLT16) -DECLARE_INSN(ukadd8, MATCH_UKADD8, MASK_UKADD8) +DECLARE_INSN(ucmplt8, MATCH_UCMPLT8, MASK_UCMPLT8) DECLARE_INSN(ukadd16, MATCH_UKADD16, MASK_UKADD16) +DECLARE_INSN(ukadd32, MATCH_UKADD32, MASK_UKADD32) DECLARE_INSN(ukadd64, MATCH_UKADD64, MASK_UKADD64) +DECLARE_INSN(ukadd8, MATCH_UKADD8, MASK_UKADD8) DECLARE_INSN(ukaddh, MATCH_UKADDH, MASK_UKADDH) DECLARE_INSN(ukaddw, MATCH_UKADDW, MASK_UKADDW) DECLARE_INSN(ukcras16, MATCH_UKCRAS16, MASK_UKCRAS16) +DECLARE_INSN(ukcras32, MATCH_UKCRAS32, MASK_UKCRAS32) DECLARE_INSN(ukcrsa16, MATCH_UKCRSA16, MASK_UKCRSA16) +DECLARE_INSN(ukcrsa32, MATCH_UKCRSA32, MASK_UKCRSA32) DECLARE_INSN(ukmar64, MATCH_UKMAR64, MASK_UKMAR64) DECLARE_INSN(ukmsr64, MATCH_UKMSR64, MASK_UKMSR64) DECLARE_INSN(ukstas16, MATCH_UKSTAS16, MASK_UKSTAS16) +DECLARE_INSN(ukstas32, MATCH_UKSTAS32, MASK_UKSTAS32) DECLARE_INSN(ukstsa16, MATCH_UKSTSA16, MASK_UKSTSA16) -DECLARE_INSN(uksub8, MATCH_UKSUB8, MASK_UKSUB8) +DECLARE_INSN(ukstsa32, MATCH_UKSTSA32, MASK_UKSTSA32) DECLARE_INSN(uksub16, MATCH_UKSUB16, MASK_UKSUB16) +DECLARE_INSN(uksub32, MATCH_UKSUB32, MASK_UKSUB32) DECLARE_INSN(uksub64, MATCH_UKSUB64, MASK_UKSUB64) +DECLARE_INSN(uksub8, MATCH_UKSUB8, MASK_UKSUB8) DECLARE_INSN(uksubh, MATCH_UKSUBH, MASK_UKSUBH) DECLARE_INSN(uksubw, MATCH_UKSUBW, MASK_UKSUBW) -DECLARE_INSN(umar64, MATCH_UMAR64, MASK_UMAR64) DECLARE_INSN(umaqa, MATCH_UMAQA, MASK_UMAQA) -DECLARE_INSN(umax8, MATCH_UMAX8, MASK_UMAX8) +DECLARE_INSN(umar64, MATCH_UMAR64, MASK_UMAR64) DECLARE_INSN(umax16, MATCH_UMAX16, MASK_UMAX16) -DECLARE_INSN(umin8, MATCH_UMIN8, MASK_UMIN8) +DECLARE_INSN(umax32, MATCH_UMAX32, MASK_UMAX32) +DECLARE_INSN(umax8, MATCH_UMAX8, MASK_UMAX8) DECLARE_INSN(umin16, MATCH_UMIN16, MASK_UMIN16) +DECLARE_INSN(umin32, MATCH_UMIN32, MASK_UMIN32) +DECLARE_INSN(umin8, MATCH_UMIN8, MASK_UMIN8) DECLARE_INSN(umsr64, MATCH_UMSR64, MASK_UMSR64) -DECLARE_INSN(umul8, MATCH_UMUL8, MASK_UMUL8) -DECLARE_INSN(umulx8, MATCH_UMULX8, MASK_UMULX8) DECLARE_INSN(umul16, MATCH_UMUL16, MASK_UMUL16) +DECLARE_INSN(umul8, MATCH_UMUL8, MASK_UMUL8) DECLARE_INSN(umulx16, MATCH_UMULX16, MASK_UMULX16) -DECLARE_INSN(uradd8, MATCH_URADD8, MASK_URADD8) +DECLARE_INSN(umulx8, MATCH_UMULX8, MASK_UMULX8) +DECLARE_INSN(unshfl, MATCH_UNSHFL, MASK_UNSHFL) +DECLARE_INSN(unshfli, MATCH_UNSHFLI, MASK_UNSHFLI) +DECLARE_INSN(unshflw, MATCH_UNSHFLW, MASK_UNSHFLW) DECLARE_INSN(uradd16, MATCH_URADD16, MASK_URADD16) +DECLARE_INSN(uradd32, MATCH_URADD32, MASK_URADD32) DECLARE_INSN(uradd64, MATCH_URADD64, MASK_URADD64) +DECLARE_INSN(uradd8, MATCH_URADD8, MASK_URADD8) DECLARE_INSN(uraddw, MATCH_URADDW, MASK_URADDW) DECLARE_INSN(urcras16, MATCH_URCRAS16, MASK_URCRAS16) +DECLARE_INSN(urcras32, MATCH_URCRAS32, MASK_URCRAS32) DECLARE_INSN(urcrsa16, MATCH_URCRSA16, MASK_URCRSA16) +DECLARE_INSN(urcrsa32, MATCH_URCRSA32, MASK_URCRSA32) DECLARE_INSN(urstas16, MATCH_URSTAS16, MASK_URSTAS16) +DECLARE_INSN(urstas32, MATCH_URSTAS32, MASK_URSTAS32) DECLARE_INSN(urstsa16, MATCH_URSTSA16, MASK_URSTSA16) -DECLARE_INSN(ursub8, MATCH_URSUB8, MASK_URSUB8) +DECLARE_INSN(urstsa32, MATCH_URSTSA32, MASK_URSTSA32) DECLARE_INSN(ursub16, MATCH_URSUB16, MASK_URSUB16) +DECLARE_INSN(ursub32, MATCH_URSUB32, MASK_URSUB32) DECLARE_INSN(ursub64, MATCH_URSUB64, MASK_URSUB64) +DECLARE_INSN(ursub8, MATCH_URSUB8, MASK_URSUB8) DECLARE_INSN(ursubw, MATCH_URSUBW, MASK_URSUBW) -DECLARE_INSN(wexti, MATCH_WEXTI, MASK_WEXTI) -DECLARE_INSN(wext, MATCH_WEXT, MASK_WEXT) +DECLARE_INSN(vaadd_vv, MATCH_VAADD_VV, MASK_VAADD_VV) +DECLARE_INSN(vaadd_vx, MATCH_VAADD_VX, MASK_VAADD_VX) +DECLARE_INSN(vaaddu_vv, MATCH_VAADDU_VV, MASK_VAADDU_VV) +DECLARE_INSN(vaaddu_vx, MATCH_VAADDU_VX, MASK_VAADDU_VX) +DECLARE_INSN(vadc_vim, MATCH_VADC_VIM, MASK_VADC_VIM) +DECLARE_INSN(vadc_vvm, MATCH_VADC_VVM, MASK_VADC_VVM) +DECLARE_INSN(vadc_vxm, MATCH_VADC_VXM, MASK_VADC_VXM) +DECLARE_INSN(vadd_vi, MATCH_VADD_VI, MASK_VADD_VI) +DECLARE_INSN(vadd_vv, MATCH_VADD_VV, MASK_VADD_VV) +DECLARE_INSN(vadd_vx, MATCH_VADD_VX, MASK_VADD_VX) +DECLARE_INSN(vamoaddei16_v, MATCH_VAMOADDEI16_V, MASK_VAMOADDEI16_V) +DECLARE_INSN(vamoaddei32_v, MATCH_VAMOADDEI32_V, MASK_VAMOADDEI32_V) +DECLARE_INSN(vamoaddei64_v, MATCH_VAMOADDEI64_V, MASK_VAMOADDEI64_V) +DECLARE_INSN(vamoaddei8_v, MATCH_VAMOADDEI8_V, MASK_VAMOADDEI8_V) +DECLARE_INSN(vamoandei16_v, MATCH_VAMOANDEI16_V, MASK_VAMOANDEI16_V) +DECLARE_INSN(vamoandei32_v, MATCH_VAMOANDEI32_V, MASK_VAMOANDEI32_V) +DECLARE_INSN(vamoandei64_v, MATCH_VAMOANDEI64_V, MASK_VAMOANDEI64_V) +DECLARE_INSN(vamoandei8_v, MATCH_VAMOANDEI8_V, MASK_VAMOANDEI8_V) +DECLARE_INSN(vamomaxei16_v, MATCH_VAMOMAXEI16_V, MASK_VAMOMAXEI16_V) +DECLARE_INSN(vamomaxei32_v, MATCH_VAMOMAXEI32_V, MASK_VAMOMAXEI32_V) +DECLARE_INSN(vamomaxei64_v, MATCH_VAMOMAXEI64_V, MASK_VAMOMAXEI64_V) +DECLARE_INSN(vamomaxei8_v, MATCH_VAMOMAXEI8_V, MASK_VAMOMAXEI8_V) +DECLARE_INSN(vamomaxuei16_v, MATCH_VAMOMAXUEI16_V, MASK_VAMOMAXUEI16_V) +DECLARE_INSN(vamomaxuei32_v, MATCH_VAMOMAXUEI32_V, MASK_VAMOMAXUEI32_V) +DECLARE_INSN(vamomaxuei64_v, MATCH_VAMOMAXUEI64_V, MASK_VAMOMAXUEI64_V) +DECLARE_INSN(vamomaxuei8_v, MATCH_VAMOMAXUEI8_V, MASK_VAMOMAXUEI8_V) +DECLARE_INSN(vamominei16_v, MATCH_VAMOMINEI16_V, MASK_VAMOMINEI16_V) +DECLARE_INSN(vamominei32_v, MATCH_VAMOMINEI32_V, MASK_VAMOMINEI32_V) +DECLARE_INSN(vamominei64_v, MATCH_VAMOMINEI64_V, MASK_VAMOMINEI64_V) +DECLARE_INSN(vamominei8_v, MATCH_VAMOMINEI8_V, MASK_VAMOMINEI8_V) +DECLARE_INSN(vamominuei16_v, MATCH_VAMOMINUEI16_V, MASK_VAMOMINUEI16_V) +DECLARE_INSN(vamominuei32_v, MATCH_VAMOMINUEI32_V, MASK_VAMOMINUEI32_V) +DECLARE_INSN(vamominuei64_v, MATCH_VAMOMINUEI64_V, MASK_VAMOMINUEI64_V) +DECLARE_INSN(vamominuei8_v, MATCH_VAMOMINUEI8_V, MASK_VAMOMINUEI8_V) +DECLARE_INSN(vamoorei16_v, MATCH_VAMOOREI16_V, MASK_VAMOOREI16_V) +DECLARE_INSN(vamoorei32_v, MATCH_VAMOOREI32_V, MASK_VAMOOREI32_V) +DECLARE_INSN(vamoorei64_v, MATCH_VAMOOREI64_V, MASK_VAMOOREI64_V) +DECLARE_INSN(vamoorei8_v, MATCH_VAMOOREI8_V, MASK_VAMOOREI8_V) +DECLARE_INSN(vamoswapei16_v, MATCH_VAMOSWAPEI16_V, MASK_VAMOSWAPEI16_V) +DECLARE_INSN(vamoswapei32_v, MATCH_VAMOSWAPEI32_V, MASK_VAMOSWAPEI32_V) +DECLARE_INSN(vamoswapei64_v, MATCH_VAMOSWAPEI64_V, MASK_VAMOSWAPEI64_V) +DECLARE_INSN(vamoswapei8_v, MATCH_VAMOSWAPEI8_V, MASK_VAMOSWAPEI8_V) +DECLARE_INSN(vamoxorei16_v, MATCH_VAMOXOREI16_V, MASK_VAMOXOREI16_V) +DECLARE_INSN(vamoxorei32_v, MATCH_VAMOXOREI32_V, MASK_VAMOXOREI32_V) +DECLARE_INSN(vamoxorei64_v, MATCH_VAMOXOREI64_V, MASK_VAMOXOREI64_V) +DECLARE_INSN(vamoxorei8_v, MATCH_VAMOXOREI8_V, MASK_VAMOXOREI8_V) +DECLARE_INSN(vand_vi, MATCH_VAND_VI, MASK_VAND_VI) +DECLARE_INSN(vand_vv, MATCH_VAND_VV, MASK_VAND_VV) +DECLARE_INSN(vand_vx, MATCH_VAND_VX, MASK_VAND_VX) +DECLARE_INSN(vasub_vv, MATCH_VASUB_VV, MASK_VASUB_VV) +DECLARE_INSN(vasub_vx, MATCH_VASUB_VX, MASK_VASUB_VX) +DECLARE_INSN(vasubu_vv, MATCH_VASUBU_VV, MASK_VASUBU_VV) +DECLARE_INSN(vasubu_vx, MATCH_VASUBU_VX, MASK_VASUBU_VX) +DECLARE_INSN(vcompress_vm, MATCH_VCOMPRESS_VM, MASK_VCOMPRESS_VM) +DECLARE_INSN(vcpop_m, MATCH_VCPOP_M, MASK_VCPOP_M) +DECLARE_INSN(vdiv_vv, MATCH_VDIV_VV, MASK_VDIV_VV) +DECLARE_INSN(vdiv_vx, MATCH_VDIV_VX, MASK_VDIV_VX) +DECLARE_INSN(vdivu_vv, MATCH_VDIVU_VV, MASK_VDIVU_VV) +DECLARE_INSN(vdivu_vx, MATCH_VDIVU_VX, MASK_VDIVU_VX) +DECLARE_INSN(vfadd_vf, MATCH_VFADD_VF, MASK_VFADD_VF) +DECLARE_INSN(vfadd_vv, MATCH_VFADD_VV, MASK_VFADD_VV) +DECLARE_INSN(vfclass_v, MATCH_VFCLASS_V, MASK_VFCLASS_V) +DECLARE_INSN(vfcvt_f_x_v, MATCH_VFCVT_F_X_V, MASK_VFCVT_F_X_V) +DECLARE_INSN(vfcvt_f_xu_v, MATCH_VFCVT_F_XU_V, MASK_VFCVT_F_XU_V) +DECLARE_INSN(vfcvt_rtz_x_f_v, MATCH_VFCVT_RTZ_X_F_V, MASK_VFCVT_RTZ_X_F_V) +DECLARE_INSN(vfcvt_rtz_xu_f_v, MATCH_VFCVT_RTZ_XU_F_V, MASK_VFCVT_RTZ_XU_F_V) +DECLARE_INSN(vfcvt_x_f_v, MATCH_VFCVT_X_F_V, MASK_VFCVT_X_F_V) +DECLARE_INSN(vfcvt_xu_f_v, MATCH_VFCVT_XU_F_V, MASK_VFCVT_XU_F_V) +DECLARE_INSN(vfdiv_vf, MATCH_VFDIV_VF, MASK_VFDIV_VF) +DECLARE_INSN(vfdiv_vv, MATCH_VFDIV_VV, MASK_VFDIV_VV) +DECLARE_INSN(vfirst_m, MATCH_VFIRST_M, MASK_VFIRST_M) +DECLARE_INSN(vfmacc_vf, MATCH_VFMACC_VF, MASK_VFMACC_VF) +DECLARE_INSN(vfmacc_vv, MATCH_VFMACC_VV, MASK_VFMACC_VV) +DECLARE_INSN(vfmadd_vf, MATCH_VFMADD_VF, MASK_VFMADD_VF) +DECLARE_INSN(vfmadd_vv, MATCH_VFMADD_VV, MASK_VFMADD_VV) +DECLARE_INSN(vfmax_vf, MATCH_VFMAX_VF, MASK_VFMAX_VF) +DECLARE_INSN(vfmax_vv, MATCH_VFMAX_VV, MASK_VFMAX_VV) +DECLARE_INSN(vfmerge_vfm, MATCH_VFMERGE_VFM, MASK_VFMERGE_VFM) +DECLARE_INSN(vfmin_vf, MATCH_VFMIN_VF, MASK_VFMIN_VF) +DECLARE_INSN(vfmin_vv, MATCH_VFMIN_VV, MASK_VFMIN_VV) +DECLARE_INSN(vfmsac_vf, MATCH_VFMSAC_VF, MASK_VFMSAC_VF) +DECLARE_INSN(vfmsac_vv, MATCH_VFMSAC_VV, MASK_VFMSAC_VV) +DECLARE_INSN(vfmsub_vf, MATCH_VFMSUB_VF, MASK_VFMSUB_VF) +DECLARE_INSN(vfmsub_vv, MATCH_VFMSUB_VV, MASK_VFMSUB_VV) +DECLARE_INSN(vfmul_vf, MATCH_VFMUL_VF, MASK_VFMUL_VF) +DECLARE_INSN(vfmul_vv, MATCH_VFMUL_VV, MASK_VFMUL_VV) +DECLARE_INSN(vfmv_f_s, MATCH_VFMV_F_S, MASK_VFMV_F_S) +DECLARE_INSN(vfmv_s_f, MATCH_VFMV_S_F, MASK_VFMV_S_F) +DECLARE_INSN(vfmv_v_f, MATCH_VFMV_V_F, MASK_VFMV_V_F) +DECLARE_INSN(vfncvt_f_f_w, MATCH_VFNCVT_F_F_W, MASK_VFNCVT_F_F_W) +DECLARE_INSN(vfncvt_f_x_w, MATCH_VFNCVT_F_X_W, MASK_VFNCVT_F_X_W) +DECLARE_INSN(vfncvt_f_xu_w, MATCH_VFNCVT_F_XU_W, MASK_VFNCVT_F_XU_W) +DECLARE_INSN(vfncvt_rod_f_f_w, MATCH_VFNCVT_ROD_F_F_W, MASK_VFNCVT_ROD_F_F_W) +DECLARE_INSN(vfncvt_rtz_x_f_w, MATCH_VFNCVT_RTZ_X_F_W, MASK_VFNCVT_RTZ_X_F_W) +DECLARE_INSN(vfncvt_rtz_xu_f_w, MATCH_VFNCVT_RTZ_XU_F_W, MASK_VFNCVT_RTZ_XU_F_W) +DECLARE_INSN(vfncvt_x_f_w, MATCH_VFNCVT_X_F_W, MASK_VFNCVT_X_F_W) +DECLARE_INSN(vfncvt_xu_f_w, MATCH_VFNCVT_XU_F_W, MASK_VFNCVT_XU_F_W) +DECLARE_INSN(vfnmacc_vf, MATCH_VFNMACC_VF, MASK_VFNMACC_VF) +DECLARE_INSN(vfnmacc_vv, MATCH_VFNMACC_VV, MASK_VFNMACC_VV) +DECLARE_INSN(vfnmadd_vf, MATCH_VFNMADD_VF, MASK_VFNMADD_VF) +DECLARE_INSN(vfnmadd_vv, MATCH_VFNMADD_VV, MASK_VFNMADD_VV) +DECLARE_INSN(vfnmsac_vf, MATCH_VFNMSAC_VF, MASK_VFNMSAC_VF) +DECLARE_INSN(vfnmsac_vv, MATCH_VFNMSAC_VV, MASK_VFNMSAC_VV) +DECLARE_INSN(vfnmsub_vf, MATCH_VFNMSUB_VF, MASK_VFNMSUB_VF) +DECLARE_INSN(vfnmsub_vv, MATCH_VFNMSUB_VV, MASK_VFNMSUB_VV) +DECLARE_INSN(vfrdiv_vf, MATCH_VFRDIV_VF, MASK_VFRDIV_VF) +DECLARE_INSN(vfrec7_v, MATCH_VFREC7_V, MASK_VFREC7_V) +DECLARE_INSN(vfredmax_vs, MATCH_VFREDMAX_VS, MASK_VFREDMAX_VS) +DECLARE_INSN(vfredmin_vs, MATCH_VFREDMIN_VS, MASK_VFREDMIN_VS) +DECLARE_INSN(vfredosum_vs, MATCH_VFREDOSUM_VS, MASK_VFREDOSUM_VS) +DECLARE_INSN(vfredusum_vs, MATCH_VFREDUSUM_VS, MASK_VFREDUSUM_VS) +DECLARE_INSN(vfrsqrt7_v, MATCH_VFRSQRT7_V, MASK_VFRSQRT7_V) +DECLARE_INSN(vfrsub_vf, MATCH_VFRSUB_VF, MASK_VFRSUB_VF) +DECLARE_INSN(vfsgnj_vf, MATCH_VFSGNJ_VF, MASK_VFSGNJ_VF) +DECLARE_INSN(vfsgnj_vv, MATCH_VFSGNJ_VV, MASK_VFSGNJ_VV) +DECLARE_INSN(vfsgnjn_vf, MATCH_VFSGNJN_VF, MASK_VFSGNJN_VF) +DECLARE_INSN(vfsgnjn_vv, MATCH_VFSGNJN_VV, MASK_VFSGNJN_VV) +DECLARE_INSN(vfsgnjx_vf, MATCH_VFSGNJX_VF, MASK_VFSGNJX_VF) +DECLARE_INSN(vfsgnjx_vv, MATCH_VFSGNJX_VV, MASK_VFSGNJX_VV) +DECLARE_INSN(vfslide1down_vf, MATCH_VFSLIDE1DOWN_VF, MASK_VFSLIDE1DOWN_VF) +DECLARE_INSN(vfslide1up_vf, MATCH_VFSLIDE1UP_VF, MASK_VFSLIDE1UP_VF) +DECLARE_INSN(vfsqrt_v, MATCH_VFSQRT_V, MASK_VFSQRT_V) +DECLARE_INSN(vfsub_vf, MATCH_VFSUB_VF, MASK_VFSUB_VF) +DECLARE_INSN(vfsub_vv, MATCH_VFSUB_VV, MASK_VFSUB_VV) +DECLARE_INSN(vfwadd_vf, MATCH_VFWADD_VF, MASK_VFWADD_VF) +DECLARE_INSN(vfwadd_vv, MATCH_VFWADD_VV, MASK_VFWADD_VV) +DECLARE_INSN(vfwadd_wf, MATCH_VFWADD_WF, MASK_VFWADD_WF) +DECLARE_INSN(vfwadd_wv, MATCH_VFWADD_WV, MASK_VFWADD_WV) +DECLARE_INSN(vfwcvt_f_f_v, MATCH_VFWCVT_F_F_V, MASK_VFWCVT_F_F_V) +DECLARE_INSN(vfwcvt_f_x_v, MATCH_VFWCVT_F_X_V, MASK_VFWCVT_F_X_V) +DECLARE_INSN(vfwcvt_f_xu_v, MATCH_VFWCVT_F_XU_V, MASK_VFWCVT_F_XU_V) +DECLARE_INSN(vfwcvt_rtz_x_f_v, MATCH_VFWCVT_RTZ_X_F_V, MASK_VFWCVT_RTZ_X_F_V) +DECLARE_INSN(vfwcvt_rtz_xu_f_v, MATCH_VFWCVT_RTZ_XU_F_V, MASK_VFWCVT_RTZ_XU_F_V) +DECLARE_INSN(vfwcvt_x_f_v, MATCH_VFWCVT_X_F_V, MASK_VFWCVT_X_F_V) +DECLARE_INSN(vfwcvt_xu_f_v, MATCH_VFWCVT_XU_F_V, MASK_VFWCVT_XU_F_V) +DECLARE_INSN(vfwmacc_vf, MATCH_VFWMACC_VF, MASK_VFWMACC_VF) +DECLARE_INSN(vfwmacc_vv, MATCH_VFWMACC_VV, MASK_VFWMACC_VV) +DECLARE_INSN(vfwmsac_vf, MATCH_VFWMSAC_VF, MASK_VFWMSAC_VF) +DECLARE_INSN(vfwmsac_vv, MATCH_VFWMSAC_VV, MASK_VFWMSAC_VV) +DECLARE_INSN(vfwmul_vf, MATCH_VFWMUL_VF, MASK_VFWMUL_VF) +DECLARE_INSN(vfwmul_vv, MATCH_VFWMUL_VV, MASK_VFWMUL_VV) +DECLARE_INSN(vfwnmacc_vf, MATCH_VFWNMACC_VF, MASK_VFWNMACC_VF) +DECLARE_INSN(vfwnmacc_vv, MATCH_VFWNMACC_VV, MASK_VFWNMACC_VV) +DECLARE_INSN(vfwnmsac_vf, MATCH_VFWNMSAC_VF, MASK_VFWNMSAC_VF) +DECLARE_INSN(vfwnmsac_vv, MATCH_VFWNMSAC_VV, MASK_VFWNMSAC_VV) +DECLARE_INSN(vfwredosum_vs, MATCH_VFWREDOSUM_VS, MASK_VFWREDOSUM_VS) +DECLARE_INSN(vfwredusum_vs, MATCH_VFWREDUSUM_VS, MASK_VFWREDUSUM_VS) +DECLARE_INSN(vfwsub_vf, MATCH_VFWSUB_VF, MASK_VFWSUB_VF) +DECLARE_INSN(vfwsub_vv, MATCH_VFWSUB_VV, MASK_VFWSUB_VV) +DECLARE_INSN(vfwsub_wf, MATCH_VFWSUB_WF, MASK_VFWSUB_WF) +DECLARE_INSN(vfwsub_wv, MATCH_VFWSUB_WV, MASK_VFWSUB_WV) +DECLARE_INSN(vid_v, MATCH_VID_V, MASK_VID_V) +DECLARE_INSN(viota_m, MATCH_VIOTA_M, MASK_VIOTA_M) +DECLARE_INSN(vl1re16_v, MATCH_VL1RE16_V, MASK_VL1RE16_V) +DECLARE_INSN(vl1re32_v, MATCH_VL1RE32_V, MASK_VL1RE32_V) +DECLARE_INSN(vl1re64_v, MATCH_VL1RE64_V, MASK_VL1RE64_V) +DECLARE_INSN(vl1re8_v, MATCH_VL1RE8_V, MASK_VL1RE8_V) +DECLARE_INSN(vl2re16_v, MATCH_VL2RE16_V, MASK_VL2RE16_V) +DECLARE_INSN(vl2re32_v, MATCH_VL2RE32_V, MASK_VL2RE32_V) +DECLARE_INSN(vl2re64_v, MATCH_VL2RE64_V, MASK_VL2RE64_V) +DECLARE_INSN(vl2re8_v, MATCH_VL2RE8_V, MASK_VL2RE8_V) +DECLARE_INSN(vl4re16_v, MATCH_VL4RE16_V, MASK_VL4RE16_V) +DECLARE_INSN(vl4re32_v, MATCH_VL4RE32_V, MASK_VL4RE32_V) +DECLARE_INSN(vl4re64_v, MATCH_VL4RE64_V, MASK_VL4RE64_V) +DECLARE_INSN(vl4re8_v, MATCH_VL4RE8_V, MASK_VL4RE8_V) +DECLARE_INSN(vl8re16_v, MATCH_VL8RE16_V, MASK_VL8RE16_V) +DECLARE_INSN(vl8re32_v, MATCH_VL8RE32_V, MASK_VL8RE32_V) +DECLARE_INSN(vl8re64_v, MATCH_VL8RE64_V, MASK_VL8RE64_V) +DECLARE_INSN(vl8re8_v, MATCH_VL8RE8_V, MASK_VL8RE8_V) +DECLARE_INSN(vle1024_v, MATCH_VLE1024_V, MASK_VLE1024_V) +DECLARE_INSN(vle1024ff_v, MATCH_VLE1024FF_V, MASK_VLE1024FF_V) +DECLARE_INSN(vle128_v, MATCH_VLE128_V, MASK_VLE128_V) +DECLARE_INSN(vle128ff_v, MATCH_VLE128FF_V, MASK_VLE128FF_V) +DECLARE_INSN(vle16_v, MATCH_VLE16_V, MASK_VLE16_V) +DECLARE_INSN(vle16ff_v, MATCH_VLE16FF_V, MASK_VLE16FF_V) +DECLARE_INSN(vle256_v, MATCH_VLE256_V, MASK_VLE256_V) +DECLARE_INSN(vle256ff_v, MATCH_VLE256FF_V, MASK_VLE256FF_V) +DECLARE_INSN(vle32_v, MATCH_VLE32_V, MASK_VLE32_V) +DECLARE_INSN(vle32ff_v, MATCH_VLE32FF_V, MASK_VLE32FF_V) +DECLARE_INSN(vle512_v, MATCH_VLE512_V, MASK_VLE512_V) +DECLARE_INSN(vle512ff_v, MATCH_VLE512FF_V, MASK_VLE512FF_V) +DECLARE_INSN(vle64_v, MATCH_VLE64_V, MASK_VLE64_V) +DECLARE_INSN(vle64ff_v, MATCH_VLE64FF_V, MASK_VLE64FF_V) +DECLARE_INSN(vle8_v, MATCH_VLE8_V, MASK_VLE8_V) +DECLARE_INSN(vle8ff_v, MATCH_VLE8FF_V, MASK_VLE8FF_V) +DECLARE_INSN(vlm_v, MATCH_VLM_V, MASK_VLM_V) +DECLARE_INSN(vloxei1024_v, MATCH_VLOXEI1024_V, MASK_VLOXEI1024_V) +DECLARE_INSN(vloxei128_v, MATCH_VLOXEI128_V, MASK_VLOXEI128_V) +DECLARE_INSN(vloxei16_v, MATCH_VLOXEI16_V, MASK_VLOXEI16_V) +DECLARE_INSN(vloxei256_v, MATCH_VLOXEI256_V, MASK_VLOXEI256_V) +DECLARE_INSN(vloxei32_v, MATCH_VLOXEI32_V, MASK_VLOXEI32_V) +DECLARE_INSN(vloxei512_v, MATCH_VLOXEI512_V, MASK_VLOXEI512_V) +DECLARE_INSN(vloxei64_v, MATCH_VLOXEI64_V, MASK_VLOXEI64_V) +DECLARE_INSN(vloxei8_v, MATCH_VLOXEI8_V, MASK_VLOXEI8_V) +DECLARE_INSN(vlse1024_v, MATCH_VLSE1024_V, MASK_VLSE1024_V) +DECLARE_INSN(vlse128_v, MATCH_VLSE128_V, MASK_VLSE128_V) +DECLARE_INSN(vlse16_v, MATCH_VLSE16_V, MASK_VLSE16_V) +DECLARE_INSN(vlse256_v, MATCH_VLSE256_V, MASK_VLSE256_V) +DECLARE_INSN(vlse32_v, MATCH_VLSE32_V, MASK_VLSE32_V) +DECLARE_INSN(vlse512_v, MATCH_VLSE512_V, MASK_VLSE512_V) +DECLARE_INSN(vlse64_v, MATCH_VLSE64_V, MASK_VLSE64_V) +DECLARE_INSN(vlse8_v, MATCH_VLSE8_V, MASK_VLSE8_V) +DECLARE_INSN(vluxei1024_v, MATCH_VLUXEI1024_V, MASK_VLUXEI1024_V) +DECLARE_INSN(vluxei128_v, MATCH_VLUXEI128_V, MASK_VLUXEI128_V) +DECLARE_INSN(vluxei16_v, MATCH_VLUXEI16_V, MASK_VLUXEI16_V) +DECLARE_INSN(vluxei256_v, MATCH_VLUXEI256_V, MASK_VLUXEI256_V) +DECLARE_INSN(vluxei32_v, MATCH_VLUXEI32_V, MASK_VLUXEI32_V) +DECLARE_INSN(vluxei512_v, MATCH_VLUXEI512_V, MASK_VLUXEI512_V) +DECLARE_INSN(vluxei64_v, MATCH_VLUXEI64_V, MASK_VLUXEI64_V) +DECLARE_INSN(vluxei8_v, MATCH_VLUXEI8_V, MASK_VLUXEI8_V) +DECLARE_INSN(vmacc_vv, MATCH_VMACC_VV, MASK_VMACC_VV) +DECLARE_INSN(vmacc_vx, MATCH_VMACC_VX, MASK_VMACC_VX) +DECLARE_INSN(vmadc_vi, MATCH_VMADC_VI, MASK_VMADC_VI) +DECLARE_INSN(vmadc_vim, MATCH_VMADC_VIM, MASK_VMADC_VIM) +DECLARE_INSN(vmadc_vv, MATCH_VMADC_VV, MASK_VMADC_VV) +DECLARE_INSN(vmadc_vvm, MATCH_VMADC_VVM, MASK_VMADC_VVM) +DECLARE_INSN(vmadc_vx, MATCH_VMADC_VX, MASK_VMADC_VX) +DECLARE_INSN(vmadc_vxm, MATCH_VMADC_VXM, MASK_VMADC_VXM) +DECLARE_INSN(vmadd_vv, MATCH_VMADD_VV, MASK_VMADD_VV) +DECLARE_INSN(vmadd_vx, MATCH_VMADD_VX, MASK_VMADD_VX) +DECLARE_INSN(vmand_mm, MATCH_VMAND_MM, MASK_VMAND_MM) +DECLARE_INSN(vmandn_mm, MATCH_VMANDN_MM, MASK_VMANDN_MM) +DECLARE_INSN(vmax_vv, MATCH_VMAX_VV, MASK_VMAX_VV) +DECLARE_INSN(vmax_vx, MATCH_VMAX_VX, MASK_VMAX_VX) +DECLARE_INSN(vmaxu_vv, MATCH_VMAXU_VV, MASK_VMAXU_VV) +DECLARE_INSN(vmaxu_vx, MATCH_VMAXU_VX, MASK_VMAXU_VX) +DECLARE_INSN(vmerge_vim, MATCH_VMERGE_VIM, MASK_VMERGE_VIM) +DECLARE_INSN(vmerge_vvm, MATCH_VMERGE_VVM, MASK_VMERGE_VVM) +DECLARE_INSN(vmerge_vxm, MATCH_VMERGE_VXM, MASK_VMERGE_VXM) +DECLARE_INSN(vmfeq_vf, MATCH_VMFEQ_VF, MASK_VMFEQ_VF) +DECLARE_INSN(vmfeq_vv, MATCH_VMFEQ_VV, MASK_VMFEQ_VV) +DECLARE_INSN(vmfge_vf, MATCH_VMFGE_VF, MASK_VMFGE_VF) +DECLARE_INSN(vmfgt_vf, MATCH_VMFGT_VF, MASK_VMFGT_VF) +DECLARE_INSN(vmfle_vf, MATCH_VMFLE_VF, MASK_VMFLE_VF) +DECLARE_INSN(vmfle_vv, MATCH_VMFLE_VV, MASK_VMFLE_VV) +DECLARE_INSN(vmflt_vf, MATCH_VMFLT_VF, MASK_VMFLT_VF) +DECLARE_INSN(vmflt_vv, MATCH_VMFLT_VV, MASK_VMFLT_VV) +DECLARE_INSN(vmfne_vf, MATCH_VMFNE_VF, MASK_VMFNE_VF) +DECLARE_INSN(vmfne_vv, MATCH_VMFNE_VV, MASK_VMFNE_VV) +DECLARE_INSN(vmin_vv, MATCH_VMIN_VV, MASK_VMIN_VV) +DECLARE_INSN(vmin_vx, MATCH_VMIN_VX, MASK_VMIN_VX) +DECLARE_INSN(vminu_vv, MATCH_VMINU_VV, MASK_VMINU_VV) +DECLARE_INSN(vminu_vx, MATCH_VMINU_VX, MASK_VMINU_VX) +DECLARE_INSN(vmnand_mm, MATCH_VMNAND_MM, MASK_VMNAND_MM) +DECLARE_INSN(vmnor_mm, MATCH_VMNOR_MM, MASK_VMNOR_MM) +DECLARE_INSN(vmor_mm, MATCH_VMOR_MM, MASK_VMOR_MM) +DECLARE_INSN(vmorn_mm, MATCH_VMORN_MM, MASK_VMORN_MM) +DECLARE_INSN(vmsbc_vv, MATCH_VMSBC_VV, MASK_VMSBC_VV) +DECLARE_INSN(vmsbc_vvm, MATCH_VMSBC_VVM, MASK_VMSBC_VVM) +DECLARE_INSN(vmsbc_vx, MATCH_VMSBC_VX, MASK_VMSBC_VX) +DECLARE_INSN(vmsbc_vxm, MATCH_VMSBC_VXM, MASK_VMSBC_VXM) +DECLARE_INSN(vmsbf_m, MATCH_VMSBF_M, MASK_VMSBF_M) +DECLARE_INSN(vmseq_vi, MATCH_VMSEQ_VI, MASK_VMSEQ_VI) +DECLARE_INSN(vmseq_vv, MATCH_VMSEQ_VV, MASK_VMSEQ_VV) +DECLARE_INSN(vmseq_vx, MATCH_VMSEQ_VX, MASK_VMSEQ_VX) +DECLARE_INSN(vmsgt_vi, MATCH_VMSGT_VI, MASK_VMSGT_VI) +DECLARE_INSN(vmsgt_vx, MATCH_VMSGT_VX, MASK_VMSGT_VX) +DECLARE_INSN(vmsgtu_vi, MATCH_VMSGTU_VI, MASK_VMSGTU_VI) +DECLARE_INSN(vmsgtu_vx, MATCH_VMSGTU_VX, MASK_VMSGTU_VX) +DECLARE_INSN(vmsif_m, MATCH_VMSIF_M, MASK_VMSIF_M) +DECLARE_INSN(vmsle_vi, MATCH_VMSLE_VI, MASK_VMSLE_VI) +DECLARE_INSN(vmsle_vv, MATCH_VMSLE_VV, MASK_VMSLE_VV) +DECLARE_INSN(vmsle_vx, MATCH_VMSLE_VX, MASK_VMSLE_VX) +DECLARE_INSN(vmsleu_vi, MATCH_VMSLEU_VI, MASK_VMSLEU_VI) +DECLARE_INSN(vmsleu_vv, MATCH_VMSLEU_VV, MASK_VMSLEU_VV) +DECLARE_INSN(vmsleu_vx, MATCH_VMSLEU_VX, MASK_VMSLEU_VX) +DECLARE_INSN(vmslt_vv, MATCH_VMSLT_VV, MASK_VMSLT_VV) +DECLARE_INSN(vmslt_vx, MATCH_VMSLT_VX, MASK_VMSLT_VX) +DECLARE_INSN(vmsltu_vv, MATCH_VMSLTU_VV, MASK_VMSLTU_VV) +DECLARE_INSN(vmsltu_vx, MATCH_VMSLTU_VX, MASK_VMSLTU_VX) +DECLARE_INSN(vmsne_vi, MATCH_VMSNE_VI, MASK_VMSNE_VI) +DECLARE_INSN(vmsne_vv, MATCH_VMSNE_VV, MASK_VMSNE_VV) +DECLARE_INSN(vmsne_vx, MATCH_VMSNE_VX, MASK_VMSNE_VX) +DECLARE_INSN(vmsof_m, MATCH_VMSOF_M, MASK_VMSOF_M) +DECLARE_INSN(vmul_vv, MATCH_VMUL_VV, MASK_VMUL_VV) +DECLARE_INSN(vmul_vx, MATCH_VMUL_VX, MASK_VMUL_VX) +DECLARE_INSN(vmulh_vv, MATCH_VMULH_VV, MASK_VMULH_VV) +DECLARE_INSN(vmulh_vx, MATCH_VMULH_VX, MASK_VMULH_VX) +DECLARE_INSN(vmulhsu_vv, MATCH_VMULHSU_VV, MASK_VMULHSU_VV) +DECLARE_INSN(vmulhsu_vx, MATCH_VMULHSU_VX, MASK_VMULHSU_VX) +DECLARE_INSN(vmulhu_vv, MATCH_VMULHU_VV, MASK_VMULHU_VV) +DECLARE_INSN(vmulhu_vx, MATCH_VMULHU_VX, MASK_VMULHU_VX) +DECLARE_INSN(vmv1r_v, MATCH_VMV1R_V, MASK_VMV1R_V) +DECLARE_INSN(vmv2r_v, MATCH_VMV2R_V, MASK_VMV2R_V) +DECLARE_INSN(vmv4r_v, MATCH_VMV4R_V, MASK_VMV4R_V) +DECLARE_INSN(vmv8r_v, MATCH_VMV8R_V, MASK_VMV8R_V) +DECLARE_INSN(vmv_s_x, MATCH_VMV_S_X, MASK_VMV_S_X) +DECLARE_INSN(vmv_v_i, MATCH_VMV_V_I, MASK_VMV_V_I) +DECLARE_INSN(vmv_v_v, MATCH_VMV_V_V, MASK_VMV_V_V) +DECLARE_INSN(vmv_v_x, MATCH_VMV_V_X, MASK_VMV_V_X) +DECLARE_INSN(vmv_x_s, MATCH_VMV_X_S, MASK_VMV_X_S) +DECLARE_INSN(vmxnor_mm, MATCH_VMXNOR_MM, MASK_VMXNOR_MM) +DECLARE_INSN(vmxor_mm, MATCH_VMXOR_MM, MASK_VMXOR_MM) +DECLARE_INSN(vnclip_wi, MATCH_VNCLIP_WI, MASK_VNCLIP_WI) +DECLARE_INSN(vnclip_wv, MATCH_VNCLIP_WV, MASK_VNCLIP_WV) +DECLARE_INSN(vnclip_wx, MATCH_VNCLIP_WX, MASK_VNCLIP_WX) +DECLARE_INSN(vnclipu_wi, MATCH_VNCLIPU_WI, MASK_VNCLIPU_WI) +DECLARE_INSN(vnclipu_wv, MATCH_VNCLIPU_WV, MASK_VNCLIPU_WV) +DECLARE_INSN(vnclipu_wx, MATCH_VNCLIPU_WX, MASK_VNCLIPU_WX) +DECLARE_INSN(vnmsac_vv, MATCH_VNMSAC_VV, MASK_VNMSAC_VV) +DECLARE_INSN(vnmsac_vx, MATCH_VNMSAC_VX, MASK_VNMSAC_VX) +DECLARE_INSN(vnmsub_vv, MATCH_VNMSUB_VV, MASK_VNMSUB_VV) +DECLARE_INSN(vnmsub_vx, MATCH_VNMSUB_VX, MASK_VNMSUB_VX) +DECLARE_INSN(vnsra_wi, MATCH_VNSRA_WI, MASK_VNSRA_WI) +DECLARE_INSN(vnsra_wv, MATCH_VNSRA_WV, MASK_VNSRA_WV) +DECLARE_INSN(vnsra_wx, MATCH_VNSRA_WX, MASK_VNSRA_WX) +DECLARE_INSN(vnsrl_wi, MATCH_VNSRL_WI, MASK_VNSRL_WI) +DECLARE_INSN(vnsrl_wv, MATCH_VNSRL_WV, MASK_VNSRL_WV) +DECLARE_INSN(vnsrl_wx, MATCH_VNSRL_WX, MASK_VNSRL_WX) +DECLARE_INSN(vor_vi, MATCH_VOR_VI, MASK_VOR_VI) +DECLARE_INSN(vor_vv, MATCH_VOR_VV, MASK_VOR_VV) +DECLARE_INSN(vor_vx, MATCH_VOR_VX, MASK_VOR_VX) +DECLARE_INSN(vredand_vs, MATCH_VREDAND_VS, MASK_VREDAND_VS) +DECLARE_INSN(vredmax_vs, MATCH_VREDMAX_VS, MASK_VREDMAX_VS) +DECLARE_INSN(vredmaxu_vs, MATCH_VREDMAXU_VS, MASK_VREDMAXU_VS) +DECLARE_INSN(vredmin_vs, MATCH_VREDMIN_VS, MASK_VREDMIN_VS) +DECLARE_INSN(vredminu_vs, MATCH_VREDMINU_VS, MASK_VREDMINU_VS) +DECLARE_INSN(vredor_vs, MATCH_VREDOR_VS, MASK_VREDOR_VS) +DECLARE_INSN(vredsum_vs, MATCH_VREDSUM_VS, MASK_VREDSUM_VS) +DECLARE_INSN(vredxor_vs, MATCH_VREDXOR_VS, MASK_VREDXOR_VS) +DECLARE_INSN(vrem_vv, MATCH_VREM_VV, MASK_VREM_VV) +DECLARE_INSN(vrem_vx, MATCH_VREM_VX, MASK_VREM_VX) +DECLARE_INSN(vremu_vv, MATCH_VREMU_VV, MASK_VREMU_VV) +DECLARE_INSN(vremu_vx, MATCH_VREMU_VX, MASK_VREMU_VX) +DECLARE_INSN(vrgather_vi, MATCH_VRGATHER_VI, MASK_VRGATHER_VI) +DECLARE_INSN(vrgather_vv, MATCH_VRGATHER_VV, MASK_VRGATHER_VV) +DECLARE_INSN(vrgather_vx, MATCH_VRGATHER_VX, MASK_VRGATHER_VX) +DECLARE_INSN(vrgatherei16_vv, MATCH_VRGATHEREI16_VV, MASK_VRGATHEREI16_VV) +DECLARE_INSN(vrsub_vi, MATCH_VRSUB_VI, MASK_VRSUB_VI) +DECLARE_INSN(vrsub_vx, MATCH_VRSUB_VX, MASK_VRSUB_VX) +DECLARE_INSN(vs1r_v, MATCH_VS1R_V, MASK_VS1R_V) +DECLARE_INSN(vs2r_v, MATCH_VS2R_V, MASK_VS2R_V) +DECLARE_INSN(vs4r_v, MATCH_VS4R_V, MASK_VS4R_V) +DECLARE_INSN(vs8r_v, MATCH_VS8R_V, MASK_VS8R_V) +DECLARE_INSN(vsadd_vi, MATCH_VSADD_VI, MASK_VSADD_VI) +DECLARE_INSN(vsadd_vv, MATCH_VSADD_VV, MASK_VSADD_VV) +DECLARE_INSN(vsadd_vx, MATCH_VSADD_VX, MASK_VSADD_VX) +DECLARE_INSN(vsaddu_vi, MATCH_VSADDU_VI, MASK_VSADDU_VI) +DECLARE_INSN(vsaddu_vv, MATCH_VSADDU_VV, MASK_VSADDU_VV) +DECLARE_INSN(vsaddu_vx, MATCH_VSADDU_VX, MASK_VSADDU_VX) +DECLARE_INSN(vsbc_vvm, MATCH_VSBC_VVM, MASK_VSBC_VVM) +DECLARE_INSN(vsbc_vxm, MATCH_VSBC_VXM, MASK_VSBC_VXM) +DECLARE_INSN(vse1024_v, MATCH_VSE1024_V, MASK_VSE1024_V) +DECLARE_INSN(vse128_v, MATCH_VSE128_V, MASK_VSE128_V) +DECLARE_INSN(vse16_v, MATCH_VSE16_V, MASK_VSE16_V) +DECLARE_INSN(vse256_v, MATCH_VSE256_V, MASK_VSE256_V) +DECLARE_INSN(vse32_v, MATCH_VSE32_V, MASK_VSE32_V) +DECLARE_INSN(vse512_v, MATCH_VSE512_V, MASK_VSE512_V) +DECLARE_INSN(vse64_v, MATCH_VSE64_V, MASK_VSE64_V) +DECLARE_INSN(vse8_v, MATCH_VSE8_V, MASK_VSE8_V) +DECLARE_INSN(vsetivli, MATCH_VSETIVLI, MASK_VSETIVLI) +DECLARE_INSN(vsetvl, MATCH_VSETVL, MASK_VSETVL) +DECLARE_INSN(vsetvli, MATCH_VSETVLI, MASK_VSETVLI) +DECLARE_INSN(vsext_vf2, MATCH_VSEXT_VF2, MASK_VSEXT_VF2) +DECLARE_INSN(vsext_vf4, MATCH_VSEXT_VF4, MASK_VSEXT_VF4) +DECLARE_INSN(vsext_vf8, MATCH_VSEXT_VF8, MASK_VSEXT_VF8) +DECLARE_INSN(vslide1down_vx, MATCH_VSLIDE1DOWN_VX, MASK_VSLIDE1DOWN_VX) +DECLARE_INSN(vslide1up_vx, MATCH_VSLIDE1UP_VX, MASK_VSLIDE1UP_VX) +DECLARE_INSN(vslidedown_vi, MATCH_VSLIDEDOWN_VI, MASK_VSLIDEDOWN_VI) +DECLARE_INSN(vslidedown_vx, MATCH_VSLIDEDOWN_VX, MASK_VSLIDEDOWN_VX) +DECLARE_INSN(vslideup_vi, MATCH_VSLIDEUP_VI, MASK_VSLIDEUP_VI) +DECLARE_INSN(vslideup_vx, MATCH_VSLIDEUP_VX, MASK_VSLIDEUP_VX) +DECLARE_INSN(vsll_vi, MATCH_VSLL_VI, MASK_VSLL_VI) +DECLARE_INSN(vsll_vv, MATCH_VSLL_VV, MASK_VSLL_VV) +DECLARE_INSN(vsll_vx, MATCH_VSLL_VX, MASK_VSLL_VX) +DECLARE_INSN(vsm_v, MATCH_VSM_V, MASK_VSM_V) +DECLARE_INSN(vsmul_vv, MATCH_VSMUL_VV, MASK_VSMUL_VV) +DECLARE_INSN(vsmul_vx, MATCH_VSMUL_VX, MASK_VSMUL_VX) +DECLARE_INSN(vsoxei1024_v, MATCH_VSOXEI1024_V, MASK_VSOXEI1024_V) +DECLARE_INSN(vsoxei128_v, MATCH_VSOXEI128_V, MASK_VSOXEI128_V) +DECLARE_INSN(vsoxei16_v, MATCH_VSOXEI16_V, MASK_VSOXEI16_V) +DECLARE_INSN(vsoxei256_v, MATCH_VSOXEI256_V, MASK_VSOXEI256_V) +DECLARE_INSN(vsoxei32_v, MATCH_VSOXEI32_V, MASK_VSOXEI32_V) +DECLARE_INSN(vsoxei512_v, MATCH_VSOXEI512_V, MASK_VSOXEI512_V) +DECLARE_INSN(vsoxei64_v, MATCH_VSOXEI64_V, MASK_VSOXEI64_V) +DECLARE_INSN(vsoxei8_v, MATCH_VSOXEI8_V, MASK_VSOXEI8_V) +DECLARE_INSN(vsra_vi, MATCH_VSRA_VI, MASK_VSRA_VI) +DECLARE_INSN(vsra_vv, MATCH_VSRA_VV, MASK_VSRA_VV) +DECLARE_INSN(vsra_vx, MATCH_VSRA_VX, MASK_VSRA_VX) +DECLARE_INSN(vsrl_vi, MATCH_VSRL_VI, MASK_VSRL_VI) +DECLARE_INSN(vsrl_vv, MATCH_VSRL_VV, MASK_VSRL_VV) +DECLARE_INSN(vsrl_vx, MATCH_VSRL_VX, MASK_VSRL_VX) +DECLARE_INSN(vsse1024_v, MATCH_VSSE1024_V, MASK_VSSE1024_V) +DECLARE_INSN(vsse128_v, MATCH_VSSE128_V, MASK_VSSE128_V) +DECLARE_INSN(vsse16_v, MATCH_VSSE16_V, MASK_VSSE16_V) +DECLARE_INSN(vsse256_v, MATCH_VSSE256_V, MASK_VSSE256_V) +DECLARE_INSN(vsse32_v, MATCH_VSSE32_V, MASK_VSSE32_V) +DECLARE_INSN(vsse512_v, MATCH_VSSE512_V, MASK_VSSE512_V) +DECLARE_INSN(vsse64_v, MATCH_VSSE64_V, MASK_VSSE64_V) +DECLARE_INSN(vsse8_v, MATCH_VSSE8_V, MASK_VSSE8_V) +DECLARE_INSN(vssra_vi, MATCH_VSSRA_VI, MASK_VSSRA_VI) +DECLARE_INSN(vssra_vv, MATCH_VSSRA_VV, MASK_VSSRA_VV) +DECLARE_INSN(vssra_vx, MATCH_VSSRA_VX, MASK_VSSRA_VX) +DECLARE_INSN(vssrl_vi, MATCH_VSSRL_VI, MASK_VSSRL_VI) +DECLARE_INSN(vssrl_vv, MATCH_VSSRL_VV, MASK_VSSRL_VV) +DECLARE_INSN(vssrl_vx, MATCH_VSSRL_VX, MASK_VSSRL_VX) +DECLARE_INSN(vssub_vv, MATCH_VSSUB_VV, MASK_VSSUB_VV) +DECLARE_INSN(vssub_vx, MATCH_VSSUB_VX, MASK_VSSUB_VX) +DECLARE_INSN(vssubu_vv, MATCH_VSSUBU_VV, MASK_VSSUBU_VV) +DECLARE_INSN(vssubu_vx, MATCH_VSSUBU_VX, MASK_VSSUBU_VX) +DECLARE_INSN(vsub_vv, MATCH_VSUB_VV, MASK_VSUB_VV) +DECLARE_INSN(vsub_vx, MATCH_VSUB_VX, MASK_VSUB_VX) +DECLARE_INSN(vsuxei1024_v, MATCH_VSUXEI1024_V, MASK_VSUXEI1024_V) +DECLARE_INSN(vsuxei128_v, MATCH_VSUXEI128_V, MASK_VSUXEI128_V) +DECLARE_INSN(vsuxei16_v, MATCH_VSUXEI16_V, MASK_VSUXEI16_V) +DECLARE_INSN(vsuxei256_v, MATCH_VSUXEI256_V, MASK_VSUXEI256_V) +DECLARE_INSN(vsuxei32_v, MATCH_VSUXEI32_V, MASK_VSUXEI32_V) +DECLARE_INSN(vsuxei512_v, MATCH_VSUXEI512_V, MASK_VSUXEI512_V) +DECLARE_INSN(vsuxei64_v, MATCH_VSUXEI64_V, MASK_VSUXEI64_V) +DECLARE_INSN(vsuxei8_v, MATCH_VSUXEI8_V, MASK_VSUXEI8_V) +DECLARE_INSN(vwadd_vv, MATCH_VWADD_VV, MASK_VWADD_VV) +DECLARE_INSN(vwadd_vx, MATCH_VWADD_VX, MASK_VWADD_VX) +DECLARE_INSN(vwadd_wv, MATCH_VWADD_WV, MASK_VWADD_WV) +DECLARE_INSN(vwadd_wx, MATCH_VWADD_WX, MASK_VWADD_WX) +DECLARE_INSN(vwaddu_vv, MATCH_VWADDU_VV, MASK_VWADDU_VV) +DECLARE_INSN(vwaddu_vx, MATCH_VWADDU_VX, MASK_VWADDU_VX) +DECLARE_INSN(vwaddu_wv, MATCH_VWADDU_WV, MASK_VWADDU_WV) +DECLARE_INSN(vwaddu_wx, MATCH_VWADDU_WX, MASK_VWADDU_WX) +DECLARE_INSN(vwmacc_vv, MATCH_VWMACC_VV, MASK_VWMACC_VV) +DECLARE_INSN(vwmacc_vx, MATCH_VWMACC_VX, MASK_VWMACC_VX) +DECLARE_INSN(vwmaccsu_vv, MATCH_VWMACCSU_VV, MASK_VWMACCSU_VV) +DECLARE_INSN(vwmaccsu_vx, MATCH_VWMACCSU_VX, MASK_VWMACCSU_VX) +DECLARE_INSN(vwmaccu_vv, MATCH_VWMACCU_VV, MASK_VWMACCU_VV) +DECLARE_INSN(vwmaccu_vx, MATCH_VWMACCU_VX, MASK_VWMACCU_VX) +DECLARE_INSN(vwmaccus_vx, MATCH_VWMACCUS_VX, MASK_VWMACCUS_VX) +DECLARE_INSN(vwmul_vv, MATCH_VWMUL_VV, MASK_VWMUL_VV) +DECLARE_INSN(vwmul_vx, MATCH_VWMUL_VX, MASK_VWMUL_VX) +DECLARE_INSN(vwmulsu_vv, MATCH_VWMULSU_VV, MASK_VWMULSU_VV) +DECLARE_INSN(vwmulsu_vx, MATCH_VWMULSU_VX, MASK_VWMULSU_VX) +DECLARE_INSN(vwmulu_vv, MATCH_VWMULU_VV, MASK_VWMULU_VV) +DECLARE_INSN(vwmulu_vx, MATCH_VWMULU_VX, MASK_VWMULU_VX) +DECLARE_INSN(vwredsum_vs, MATCH_VWREDSUM_VS, MASK_VWREDSUM_VS) +DECLARE_INSN(vwredsumu_vs, MATCH_VWREDSUMU_VS, MASK_VWREDSUMU_VS) +DECLARE_INSN(vwsub_vv, MATCH_VWSUB_VV, MASK_VWSUB_VV) +DECLARE_INSN(vwsub_vx, MATCH_VWSUB_VX, MASK_VWSUB_VX) +DECLARE_INSN(vwsub_wv, MATCH_VWSUB_WV, MASK_VWSUB_WV) +DECLARE_INSN(vwsub_wx, MATCH_VWSUB_WX, MASK_VWSUB_WX) +DECLARE_INSN(vwsubu_vv, MATCH_VWSUBU_VV, MASK_VWSUBU_VV) +DECLARE_INSN(vwsubu_vx, MATCH_VWSUBU_VX, MASK_VWSUBU_VX) +DECLARE_INSN(vwsubu_wv, MATCH_VWSUBU_WV, MASK_VWSUBU_WV) +DECLARE_INSN(vwsubu_wx, MATCH_VWSUBU_WX, MASK_VWSUBU_WX) +DECLARE_INSN(vxor_vi, MATCH_VXOR_VI, MASK_VXOR_VI) +DECLARE_INSN(vxor_vv, MATCH_VXOR_VV, MASK_VXOR_VV) +DECLARE_INSN(vxor_vx, MATCH_VXOR_VX, MASK_VXOR_VX) +DECLARE_INSN(vzext_vf2, MATCH_VZEXT_VF2, MASK_VZEXT_VF2) +DECLARE_INSN(vzext_vf4, MATCH_VZEXT_VF4, MASK_VZEXT_VF4) +DECLARE_INSN(vzext_vf8, MATCH_VZEXT_VF8, MASK_VZEXT_VF8) +DECLARE_INSN(wfi, MATCH_WFI, MASK_WFI) +DECLARE_INSN(wrs_nto, MATCH_WRS_NTO, MASK_WRS_NTO) +DECLARE_INSN(wrs_sto, MATCH_WRS_STO, MASK_WRS_STO) +DECLARE_INSN(xnor, MATCH_XNOR, MASK_XNOR) +DECLARE_INSN(xor, MATCH_XOR, MASK_XOR) +DECLARE_INSN(xori, MATCH_XORI, MASK_XORI) +DECLARE_INSN(xperm16, MATCH_XPERM16, MASK_XPERM16) +DECLARE_INSN(xperm32, MATCH_XPERM32, MASK_XPERM32) +DECLARE_INSN(xperm4, MATCH_XPERM4, MASK_XPERM4) +DECLARE_INSN(xperm8, MATCH_XPERM8, MASK_XPERM8) DECLARE_INSN(zunpkd810, MATCH_ZUNPKD810, MASK_ZUNPKD810) DECLARE_INSN(zunpkd820, MATCH_ZUNPKD820, MASK_ZUNPKD820) DECLARE_INSN(zunpkd830, MATCH_ZUNPKD830, MASK_ZUNPKD830) DECLARE_INSN(zunpkd831, MATCH_ZUNPKD831, MASK_ZUNPKD831) DECLARE_INSN(zunpkd832, MATCH_ZUNPKD832, MASK_ZUNPKD832) -DECLARE_INSN(add32, MATCH_ADD32, MASK_ADD32) -DECLARE_INSN(cras32, MATCH_CRAS32, MASK_CRAS32) -DECLARE_INSN(crsa32, MATCH_CRSA32, MASK_CRSA32) -DECLARE_INSN(kabs32, MATCH_KABS32, MASK_KABS32) -DECLARE_INSN(kadd32, MATCH_KADD32, MASK_KADD32) -DECLARE_INSN(kcras32, MATCH_KCRAS32, MASK_KCRAS32) -DECLARE_INSN(kcrsa32, MATCH_KCRSA32, MASK_KCRSA32) -DECLARE_INSN(kdmbb16, MATCH_KDMBB16, MASK_KDMBB16) -DECLARE_INSN(kdmbt16, MATCH_KDMBT16, MASK_KDMBT16) -DECLARE_INSN(kdmtt16, MATCH_KDMTT16, MASK_KDMTT16) -DECLARE_INSN(kdmabb16, MATCH_KDMABB16, MASK_KDMABB16) -DECLARE_INSN(kdmabt16, MATCH_KDMABT16, MASK_KDMABT16) -DECLARE_INSN(kdmatt16, MATCH_KDMATT16, MASK_KDMATT16) -DECLARE_INSN(khmbb16, MATCH_KHMBB16, MASK_KHMBB16) -DECLARE_INSN(khmbt16, MATCH_KHMBT16, MASK_KHMBT16) -DECLARE_INSN(khmtt16, MATCH_KHMTT16, MASK_KHMTT16) -DECLARE_INSN(kmabb32, MATCH_KMABB32, MASK_KMABB32) -DECLARE_INSN(kmabt32, MATCH_KMABT32, MASK_KMABT32) -DECLARE_INSN(kmatt32, MATCH_KMATT32, MASK_KMATT32) -DECLARE_INSN(kmaxda32, MATCH_KMAXDA32, MASK_KMAXDA32) -DECLARE_INSN(kmda32, MATCH_KMDA32, MASK_KMDA32) -DECLARE_INSN(kmxda32, MATCH_KMXDA32, MASK_KMXDA32) -DECLARE_INSN(kmads32, MATCH_KMADS32, MASK_KMADS32) -DECLARE_INSN(kmadrs32, MATCH_KMADRS32, MASK_KMADRS32) -DECLARE_INSN(kmaxds32, MATCH_KMAXDS32, MASK_KMAXDS32) -DECLARE_INSN(kmsda32, MATCH_KMSDA32, MASK_KMSDA32) -DECLARE_INSN(kmsxda32, MATCH_KMSXDA32, MASK_KMSXDA32) -DECLARE_INSN(ksll32, MATCH_KSLL32, MASK_KSLL32) -DECLARE_INSN(kslli32, MATCH_KSLLI32, MASK_KSLLI32) -DECLARE_INSN(kslra32, MATCH_KSLRA32, MASK_KSLRA32) -DECLARE_INSN(kslra32_u, MATCH_KSLRA32_U, MASK_KSLRA32_U) -DECLARE_INSN(kstas32, MATCH_KSTAS32, MASK_KSTAS32) -DECLARE_INSN(kstsa32, MATCH_KSTSA32, MASK_KSTSA32) -DECLARE_INSN(ksub32, MATCH_KSUB32, MASK_KSUB32) -DECLARE_INSN(pkbb32, MATCH_PKBB32, MASK_PKBB32) -DECLARE_INSN(pkbt32, MATCH_PKBT32, MASK_PKBT32) -DECLARE_INSN(pktt32, MATCH_PKTT32, MASK_PKTT32) -DECLARE_INSN(pktb32, MATCH_PKTB32, MASK_PKTB32) -DECLARE_INSN(radd32, MATCH_RADD32, MASK_RADD32) -DECLARE_INSN(rcras32, MATCH_RCRAS32, MASK_RCRAS32) -DECLARE_INSN(rcrsa32, MATCH_RCRSA32, MASK_RCRSA32) -DECLARE_INSN(rstas32, MATCH_RSTAS32, MASK_RSTAS32) -DECLARE_INSN(rstsa32, MATCH_RSTSA32, MASK_RSTSA32) -DECLARE_INSN(rsub32, MATCH_RSUB32, MASK_RSUB32) -DECLARE_INSN(sll32, MATCH_SLL32, MASK_SLL32) -DECLARE_INSN(slli32, MATCH_SLLI32, MASK_SLLI32) -DECLARE_INSN(smax32, MATCH_SMAX32, MASK_SMAX32) -DECLARE_INSN(smbt32, MATCH_SMBT32, MASK_SMBT32) -DECLARE_INSN(smtt32, MATCH_SMTT32, MASK_SMTT32) -DECLARE_INSN(smds32, MATCH_SMDS32, MASK_SMDS32) -DECLARE_INSN(smdrs32, MATCH_SMDRS32, MASK_SMDRS32) -DECLARE_INSN(smxds32, MATCH_SMXDS32, MASK_SMXDS32) -DECLARE_INSN(smin32, MATCH_SMIN32, MASK_SMIN32) -DECLARE_INSN(sra32, MATCH_SRA32, MASK_SRA32) -DECLARE_INSN(sra32_u, MATCH_SRA32_U, MASK_SRA32_U) -DECLARE_INSN(srai32, MATCH_SRAI32, MASK_SRAI32) -DECLARE_INSN(srai32_u, MATCH_SRAI32_U, MASK_SRAI32_U) -DECLARE_INSN(sraiw_u, MATCH_SRAIW_U, MASK_SRAIW_U) -DECLARE_INSN(srl32, MATCH_SRL32, MASK_SRL32) -DECLARE_INSN(srl32_u, MATCH_SRL32_U, MASK_SRL32_U) -DECLARE_INSN(srli32, MATCH_SRLI32, MASK_SRLI32) -DECLARE_INSN(srli32_u, MATCH_SRLI32_U, MASK_SRLI32_U) -DECLARE_INSN(stas32, MATCH_STAS32, MASK_STAS32) -DECLARE_INSN(stsa32, MATCH_STSA32, MASK_STSA32) -DECLARE_INSN(sub32, MATCH_SUB32, MASK_SUB32) -DECLARE_INSN(ukadd32, MATCH_UKADD32, MASK_UKADD32) -DECLARE_INSN(ukcras32, MATCH_UKCRAS32, MASK_UKCRAS32) -DECLARE_INSN(ukcrsa32, MATCH_UKCRSA32, MASK_UKCRSA32) -DECLARE_INSN(ukstas32, MATCH_UKSTAS32, MASK_UKSTAS32) -DECLARE_INSN(ukstsa32, MATCH_UKSTSA32, MASK_UKSTSA32) -DECLARE_INSN(uksub32, MATCH_UKSUB32, MASK_UKSUB32) -DECLARE_INSN(umax32, MATCH_UMAX32, MASK_UMAX32) -DECLARE_INSN(umin32, MATCH_UMIN32, MASK_UMIN32) -DECLARE_INSN(uradd32, MATCH_URADD32, MASK_URADD32) -DECLARE_INSN(urcras32, MATCH_URCRAS32, MASK_URCRAS32) -DECLARE_INSN(urcrsa32, MATCH_URCRSA32, MASK_URCRSA32) -DECLARE_INSN(urstas32, MATCH_URSTAS32, MASK_URSTAS32) -DECLARE_INSN(urstsa32, MATCH_URSTSA32, MASK_URSTSA32) -DECLARE_INSN(ursub32, MATCH_URSUB32, MASK_URSUB32) -DECLARE_INSN(vmvnfr_v, MATCH_VMVNFR_V, MASK_VMVNFR_V) -DECLARE_INSN(vl1r_v, MATCH_VL1R_V, MASK_VL1R_V) -DECLARE_INSN(vl2r_v, MATCH_VL2R_V, MASK_VL2R_V) -DECLARE_INSN(vl4r_v, MATCH_VL4R_V, MASK_VL4R_V) -DECLARE_INSN(vl8r_v, MATCH_VL8R_V, MASK_VL8R_V) -DECLARE_INSN(vle1_v, MATCH_VLE1_V, MASK_VLE1_V) -DECLARE_INSN(vse1_v, MATCH_VSE1_V, MASK_VSE1_V) -DECLARE_INSN(vfredsum_vs, MATCH_VFREDSUM_VS, MASK_VFREDSUM_VS) -DECLARE_INSN(vfwredsum_vs, MATCH_VFWREDSUM_VS, MASK_VFWREDSUM_VS) -DECLARE_INSN(vpopc_m, MATCH_VPOPC_M, MASK_VPOPC_M) #endif #ifdef DECLARE_CSR DECLARE_CSR(fflags, CSR_FFLAGS) @@ -4348,6 +4718,7 @@ DECLARE_CSR(vxsat, CSR_VXSAT) DECLARE_CSR(vxrm, CSR_VXRM) DECLARE_CSR(vcsr, CSR_VCSR) DECLARE_CSR(seed, CSR_SEED) +DECLARE_CSR(jvt, CSR_JVT) DECLARE_CSR(cycle, CSR_CYCLE) DECLARE_CSR(time, CSR_TIME) DECLARE_CSR(instret, CSR_INSTRET) @@ -4389,12 +4760,22 @@ DECLARE_CSR(sideleg, CSR_SIDELEG) DECLARE_CSR(sie, CSR_SIE) DECLARE_CSR(stvec, CSR_STVEC) DECLARE_CSR(scounteren, CSR_SCOUNTEREN) +DECLARE_CSR(senvcfg, CSR_SENVCFG) +DECLARE_CSR(sstateen0, CSR_SSTATEEN0) +DECLARE_CSR(sstateen1, CSR_SSTATEEN1) +DECLARE_CSR(sstateen2, CSR_SSTATEEN2) +DECLARE_CSR(sstateen3, CSR_SSTATEEN3) DECLARE_CSR(sscratch, CSR_SSCRATCH) DECLARE_CSR(sepc, CSR_SEPC) DECLARE_CSR(scause, CSR_SCAUSE) DECLARE_CSR(stval, CSR_STVAL) DECLARE_CSR(sip, CSR_SIP) +DECLARE_CSR(stimecmp, CSR_STIMECMP) +DECLARE_CSR(siselect, CSR_SISELECT) +DECLARE_CSR(sireg, CSR_SIREG) +DECLARE_CSR(stopei, CSR_STOPEI) DECLARE_CSR(satp, CSR_SATP) +DECLARE_CSR(scontext, CSR_SCONTEXT) DECLARE_CSR(vsstatus, CSR_VSSTATUS) DECLARE_CSR(vsie, CSR_VSIE) DECLARE_CSR(vstvec, CSR_VSTVEC) @@ -4403,6 +4784,10 @@ DECLARE_CSR(vsepc, CSR_VSEPC) DECLARE_CSR(vscause, CSR_VSCAUSE) DECLARE_CSR(vstval, CSR_VSTVAL) DECLARE_CSR(vsip, CSR_VSIP) +DECLARE_CSR(vstimecmp, CSR_VSTIMECMP) +DECLARE_CSR(vsiselect, CSR_VSISELECT) +DECLARE_CSR(vsireg, CSR_VSIREG) +DECLARE_CSR(vstopei, CSR_VSTOPEI) DECLARE_CSR(vsatp, CSR_VSATP) DECLARE_CSR(hstatus, CSR_HSTATUS) DECLARE_CSR(hedeleg, CSR_HEDELEG) @@ -4411,12 +4796,25 @@ DECLARE_CSR(hie, CSR_HIE) DECLARE_CSR(htimedelta, CSR_HTIMEDELTA) DECLARE_CSR(hcounteren, CSR_HCOUNTEREN) DECLARE_CSR(hgeie, CSR_HGEIE) +DECLARE_CSR(hvien, CSR_HVIEN) +DECLARE_CSR(hvictl, CSR_HVICTL) +DECLARE_CSR(henvcfg, CSR_HENVCFG) +DECLARE_CSR(hstateen0, CSR_HSTATEEN0) +DECLARE_CSR(hstateen1, CSR_HSTATEEN1) +DECLARE_CSR(hstateen2, CSR_HSTATEEN2) +DECLARE_CSR(hstateen3, CSR_HSTATEEN3) DECLARE_CSR(htval, CSR_HTVAL) DECLARE_CSR(hip, CSR_HIP) DECLARE_CSR(hvip, CSR_HVIP) +DECLARE_CSR(hviprio1, CSR_HVIPRIO1) +DECLARE_CSR(hviprio2, CSR_HVIPRIO2) DECLARE_CSR(htinst, CSR_HTINST) DECLARE_CSR(hgatp, CSR_HGATP) +DECLARE_CSR(hcontext, CSR_HCONTEXT) DECLARE_CSR(hgeip, CSR_HGEIP) +DECLARE_CSR(vstopi, CSR_VSTOPI) +DECLARE_CSR(scountovf, CSR_SCOUNTOVF) +DECLARE_CSR(stopi, CSR_STOPI) DECLARE_CSR(utvt, CSR_UTVT) DECLARE_CSR(unxti, CSR_UNXTI) DECLARE_CSR(uintstatus, CSR_UINTSTATUS) @@ -4439,6 +4837,13 @@ DECLARE_CSR(mideleg, CSR_MIDELEG) DECLARE_CSR(mie, CSR_MIE) DECLARE_CSR(mtvec, CSR_MTVEC) DECLARE_CSR(mcounteren, CSR_MCOUNTEREN) +DECLARE_CSR(mvien, CSR_MVIEN) +DECLARE_CSR(mvip, CSR_MVIP) +DECLARE_CSR(menvcfg, CSR_MENVCFG) +DECLARE_CSR(mstateen0, CSR_MSTATEEN0) +DECLARE_CSR(mstateen1, CSR_MSTATEEN1) +DECLARE_CSR(mstateen2, CSR_MSTATEEN2) +DECLARE_CSR(mstateen3, CSR_MSTATEEN3) DECLARE_CSR(mcountinhibit, CSR_MCOUNTINHIBIT) DECLARE_CSR(mscratch, CSR_MSCRATCH) DECLARE_CSR(mepc, CSR_MEPC) @@ -4447,10 +4852,25 @@ DECLARE_CSR(mtval, CSR_MTVAL) DECLARE_CSR(mip, CSR_MIP) DECLARE_CSR(mtinst, CSR_MTINST) DECLARE_CSR(mtval2, CSR_MTVAL2) +DECLARE_CSR(miselect, CSR_MISELECT) +DECLARE_CSR(mireg, CSR_MIREG) +DECLARE_CSR(mtopei, CSR_MTOPEI) DECLARE_CSR(pmpcfg0, CSR_PMPCFG0) DECLARE_CSR(pmpcfg1, CSR_PMPCFG1) DECLARE_CSR(pmpcfg2, CSR_PMPCFG2) DECLARE_CSR(pmpcfg3, CSR_PMPCFG3) +DECLARE_CSR(pmpcfg4, CSR_PMPCFG4) +DECLARE_CSR(pmpcfg5, CSR_PMPCFG5) +DECLARE_CSR(pmpcfg6, CSR_PMPCFG6) +DECLARE_CSR(pmpcfg7, CSR_PMPCFG7) +DECLARE_CSR(pmpcfg8, CSR_PMPCFG8) +DECLARE_CSR(pmpcfg9, CSR_PMPCFG9) +DECLARE_CSR(pmpcfg10, CSR_PMPCFG10) +DECLARE_CSR(pmpcfg11, CSR_PMPCFG11) +DECLARE_CSR(pmpcfg12, CSR_PMPCFG12) +DECLARE_CSR(pmpcfg13, CSR_PMPCFG13) +DECLARE_CSR(pmpcfg14, CSR_PMPCFG14) +DECLARE_CSR(pmpcfg15, CSR_PMPCFG15) DECLARE_CSR(pmpaddr0, CSR_PMPADDR0) DECLARE_CSR(pmpaddr1, CSR_PMPADDR1) DECLARE_CSR(pmpaddr2, CSR_PMPADDR2) @@ -4467,6 +4887,55 @@ DECLARE_CSR(pmpaddr12, CSR_PMPADDR12) DECLARE_CSR(pmpaddr13, CSR_PMPADDR13) DECLARE_CSR(pmpaddr14, CSR_PMPADDR14) DECLARE_CSR(pmpaddr15, CSR_PMPADDR15) +DECLARE_CSR(pmpaddr16, CSR_PMPADDR16) +DECLARE_CSR(pmpaddr17, CSR_PMPADDR17) +DECLARE_CSR(pmpaddr18, CSR_PMPADDR18) +DECLARE_CSR(pmpaddr19, CSR_PMPADDR19) +DECLARE_CSR(pmpaddr20, CSR_PMPADDR20) +DECLARE_CSR(pmpaddr21, CSR_PMPADDR21) +DECLARE_CSR(pmpaddr22, CSR_PMPADDR22) +DECLARE_CSR(pmpaddr23, CSR_PMPADDR23) +DECLARE_CSR(pmpaddr24, CSR_PMPADDR24) +DECLARE_CSR(pmpaddr25, CSR_PMPADDR25) +DECLARE_CSR(pmpaddr26, CSR_PMPADDR26) +DECLARE_CSR(pmpaddr27, CSR_PMPADDR27) +DECLARE_CSR(pmpaddr28, CSR_PMPADDR28) +DECLARE_CSR(pmpaddr29, CSR_PMPADDR29) +DECLARE_CSR(pmpaddr30, CSR_PMPADDR30) +DECLARE_CSR(pmpaddr31, CSR_PMPADDR31) +DECLARE_CSR(pmpaddr32, CSR_PMPADDR32) +DECLARE_CSR(pmpaddr33, CSR_PMPADDR33) +DECLARE_CSR(pmpaddr34, CSR_PMPADDR34) +DECLARE_CSR(pmpaddr35, CSR_PMPADDR35) +DECLARE_CSR(pmpaddr36, CSR_PMPADDR36) +DECLARE_CSR(pmpaddr37, CSR_PMPADDR37) +DECLARE_CSR(pmpaddr38, CSR_PMPADDR38) +DECLARE_CSR(pmpaddr39, CSR_PMPADDR39) +DECLARE_CSR(pmpaddr40, CSR_PMPADDR40) +DECLARE_CSR(pmpaddr41, CSR_PMPADDR41) +DECLARE_CSR(pmpaddr42, CSR_PMPADDR42) +DECLARE_CSR(pmpaddr43, CSR_PMPADDR43) +DECLARE_CSR(pmpaddr44, CSR_PMPADDR44) +DECLARE_CSR(pmpaddr45, CSR_PMPADDR45) +DECLARE_CSR(pmpaddr46, CSR_PMPADDR46) +DECLARE_CSR(pmpaddr47, CSR_PMPADDR47) +DECLARE_CSR(pmpaddr48, CSR_PMPADDR48) +DECLARE_CSR(pmpaddr49, CSR_PMPADDR49) +DECLARE_CSR(pmpaddr50, CSR_PMPADDR50) +DECLARE_CSR(pmpaddr51, CSR_PMPADDR51) +DECLARE_CSR(pmpaddr52, CSR_PMPADDR52) +DECLARE_CSR(pmpaddr53, CSR_PMPADDR53) +DECLARE_CSR(pmpaddr54, CSR_PMPADDR54) +DECLARE_CSR(pmpaddr55, CSR_PMPADDR55) +DECLARE_CSR(pmpaddr56, CSR_PMPADDR56) +DECLARE_CSR(pmpaddr57, CSR_PMPADDR57) +DECLARE_CSR(pmpaddr58, CSR_PMPADDR58) +DECLARE_CSR(pmpaddr59, CSR_PMPADDR59) +DECLARE_CSR(pmpaddr60, CSR_PMPADDR60) +DECLARE_CSR(pmpaddr61, CSR_PMPADDR61) +DECLARE_CSR(pmpaddr62, CSR_PMPADDR62) +DECLARE_CSR(pmpaddr63, CSR_PMPADDR63) +DECLARE_CSR(mseccfg, CSR_MSECCFG) DECLARE_CSR(tselect, CSR_TSELECT) DECLARE_CSR(tdata1, CSR_TDATA1) DECLARE_CSR(tdata2, CSR_TDATA2) @@ -4474,7 +4943,7 @@ DECLARE_CSR(tdata3, CSR_TDATA3) DECLARE_CSR(tinfo, CSR_TINFO) DECLARE_CSR(tcontrol, CSR_TCONTROL) DECLARE_CSR(mcontext, CSR_MCONTEXT) -DECLARE_CSR(scontext, CSR_SCONTEXT) +DECLARE_CSR(mscontext, CSR_MSCONTEXT) DECLARE_CSR(dcsr, CSR_DCSR) DECLARE_CSR(dpc, CSR_DPC) DECLARE_CSR(dscratch0, CSR_DSCRATCH0) @@ -4543,7 +5012,25 @@ DECLARE_CSR(mvendorid, CSR_MVENDORID) DECLARE_CSR(marchid, CSR_MARCHID) DECLARE_CSR(mimpid, CSR_MIMPID) DECLARE_CSR(mhartid, CSR_MHARTID) +DECLARE_CSR(mconfigptr, CSR_MCONFIGPTR) +DECLARE_CSR(mtopi, CSR_MTOPI) +DECLARE_CSR(sieh, CSR_SIEH) +DECLARE_CSR(siph, CSR_SIPH) +DECLARE_CSR(stimecmph, CSR_STIMECMPH) +DECLARE_CSR(vsieh, CSR_VSIEH) +DECLARE_CSR(vsiph, CSR_VSIPH) +DECLARE_CSR(vstimecmph, CSR_VSTIMECMPH) DECLARE_CSR(htimedeltah, CSR_HTIMEDELTAH) +DECLARE_CSR(hidelegh, CSR_HIDELEGH) +DECLARE_CSR(hvienh, CSR_HVIENH) +DECLARE_CSR(henvcfgh, CSR_HENVCFGH) +DECLARE_CSR(hviph, CSR_HVIPH) +DECLARE_CSR(hviprio1h, CSR_HVIPRIO1H) +DECLARE_CSR(hviprio2h, CSR_HVIPRIO2H) +DECLARE_CSR(hstateen0h, CSR_HSTATEEN0H) +DECLARE_CSR(hstateen1h, CSR_HSTATEEN1H) +DECLARE_CSR(hstateen2h, CSR_HSTATEEN2H) +DECLARE_CSR(hstateen3h, CSR_HSTATEEN3H) DECLARE_CSR(cycleh, CSR_CYCLEH) DECLARE_CSR(timeh, CSR_TIMEH) DECLARE_CSR(instreth, CSR_INSTRETH) @@ -4577,6 +5064,50 @@ DECLARE_CSR(hpmcounter29h, CSR_HPMCOUNTER29H) DECLARE_CSR(hpmcounter30h, CSR_HPMCOUNTER30H) DECLARE_CSR(hpmcounter31h, CSR_HPMCOUNTER31H) DECLARE_CSR(mstatush, CSR_MSTATUSH) +DECLARE_CSR(midelegh, CSR_MIDELEGH) +DECLARE_CSR(mieh, CSR_MIEH) +DECLARE_CSR(mvienh, CSR_MVIENH) +DECLARE_CSR(mviph, CSR_MVIPH) +DECLARE_CSR(menvcfgh, CSR_MENVCFGH) +DECLARE_CSR(mstateen0h, CSR_MSTATEEN0H) +DECLARE_CSR(mstateen1h, CSR_MSTATEEN1H) +DECLARE_CSR(mstateen2h, CSR_MSTATEEN2H) +DECLARE_CSR(mstateen3h, CSR_MSTATEEN3H) +DECLARE_CSR(miph, CSR_MIPH) +DECLARE_CSR(mhpmevent3h, CSR_MHPMEVENT3H) +DECLARE_CSR(mhpmevent4h, CSR_MHPMEVENT4H) +DECLARE_CSR(mhpmevent5h, CSR_MHPMEVENT5H) +DECLARE_CSR(mhpmevent6h, CSR_MHPMEVENT6H) +DECLARE_CSR(mhpmevent7h, CSR_MHPMEVENT7H) +DECLARE_CSR(mhpmevent8h, CSR_MHPMEVENT8H) +DECLARE_CSR(mhpmevent9h, CSR_MHPMEVENT9H) +DECLARE_CSR(mhpmevent10h, CSR_MHPMEVENT10H) +DECLARE_CSR(mhpmevent11h, CSR_MHPMEVENT11H) +DECLARE_CSR(mhpmevent12h, CSR_MHPMEVENT12H) +DECLARE_CSR(mhpmevent13h, CSR_MHPMEVENT13H) +DECLARE_CSR(mhpmevent14h, CSR_MHPMEVENT14H) +DECLARE_CSR(mhpmevent15h, CSR_MHPMEVENT15H) +DECLARE_CSR(mhpmevent16h, CSR_MHPMEVENT16H) +DECLARE_CSR(mhpmevent17h, CSR_MHPMEVENT17H) +DECLARE_CSR(mhpmevent18h, CSR_MHPMEVENT18H) +DECLARE_CSR(mhpmevent19h, CSR_MHPMEVENT19H) +DECLARE_CSR(mhpmevent20h, CSR_MHPMEVENT20H) +DECLARE_CSR(mhpmevent21h, CSR_MHPMEVENT21H) +DECLARE_CSR(mhpmevent22h, CSR_MHPMEVENT22H) +DECLARE_CSR(mhpmevent23h, CSR_MHPMEVENT23H) +DECLARE_CSR(mhpmevent24h, CSR_MHPMEVENT24H) +DECLARE_CSR(mhpmevent25h, CSR_MHPMEVENT25H) +DECLARE_CSR(mhpmevent26h, CSR_MHPMEVENT26H) +DECLARE_CSR(mhpmevent27h, CSR_MHPMEVENT27H) +DECLARE_CSR(mhpmevent28h, CSR_MHPMEVENT28H) +DECLARE_CSR(mhpmevent29h, CSR_MHPMEVENT29H) +DECLARE_CSR(mhpmevent30h, CSR_MHPMEVENT30H) +DECLARE_CSR(mhpmevent31h, CSR_MHPMEVENT31H) +DECLARE_CSR(mnscratch, CSR_MNSCRATCH) +DECLARE_CSR(mnepc, CSR_MNEPC) +DECLARE_CSR(mncause, CSR_MNCAUSE) +DECLARE_CSR(mnstatus, CSR_MNSTATUS) +DECLARE_CSR(mseccfgh, CSR_MSECCFGH) DECLARE_CSR(mcycleh, CSR_MCYCLEH) DECLARE_CSR(minstreth, CSR_MINSTRETH) DECLARE_CSR(mhpmcounter3h, CSR_MHPMCOUNTER3H) diff --git a/vendor/riscv/riscv-isa-sim/riscv/entropy_source.h b/vendor/riscv/riscv-isa-sim/riscv/entropy_source.h index 47823ff73..148e6b052 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/entropy_source.h +++ b/vendor/riscv/riscv-isa-sim/riscv/entropy_source.h @@ -2,7 +2,7 @@ #include #include -#include "internals.h" +#include "common.h" // // Used to model the cryptography extension entropy source. @@ -30,13 +30,12 @@ public: // seed register // ------------------------------------------------------------ - void set_seed(reg_t val) { + void set_seed(reg_t UNUSED val) { // Always ignore writes to seed. // This CSR is strictly read only. It occupies a RW CSR address // to handle the side-effect of the changing seed value on a read. } - // // The format of seed is described in Section 4.1 of // the scalar cryptography specification. @@ -50,27 +49,27 @@ public: // the bare minimum. uint32_t return_status = OPST_ES16; - if(return_status == OPST_ES16) { + if (return_status == OPST_ES16) { - // Add some sampled entropy into the low 16 bits - uint16_t entropy = this -> get_two_random_bytes(); - result |= entropy; + // Add some sampled entropy into the low 16 bits + uint16_t entropy = this -> get_two_random_bytes(); + result |= entropy; - } else if(return_status == OPST_BIST) { + } else if (return_status == OPST_BIST) { - // Do nothing. + // Do nothing. - } else if(return_status == OPST_WAIT) { + } else if (return_status == OPST_WAIT) { - // Do nothing. + // Do nothing. - } else if(return_status == OPST_DEAD) { + } else if (return_status == OPST_DEAD) { - // Do nothing. Stay dead. + // Do nothing. Stay dead. } else { - // Unreachable. + // Unreachable. } @@ -93,25 +92,25 @@ public: // Read two random bytes from the entropy source file. uint16_t get_two_random_bytes() { - std::ifstream fh(this -> randomness_source, std::ios::binary); + std::ifstream fh(this -> randomness_source, std::ios::binary); - if(fh.is_open()) { + if (fh.is_open()) { - uint16_t random_bytes; + uint16_t random_bytes; - fh.read((char*)(&random_bytes), 2); + fh.read((char*)(&random_bytes), 2); - fh.close(); + fh.close(); - return random_bytes; + return random_bytes; - } else { + } else { - fprintf(stderr, "Could not open randomness source file:\n\t"); - fprintf(stderr, "%s", randomness_source.c_str()); - abort(); + fprintf(stderr, "Could not open randomness source file:\n\t"); + fprintf(stderr, "%s", randomness_source.c_str()); + abort(); - } + } } diff --git a/vendor/riscv/riscv-isa-sim/riscv/execute.cc b/vendor/riscv/riscv-isa-sim/riscv/execute.cc index 3f7584ea7..acf0e908c 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/execute.cc +++ b/vendor/riscv/riscv-isa-sim/riscv/execute.cc @@ -1,11 +1,12 @@ // See LICENSE for license details. +#include "config.h" #include "processor.h" #include "mmu.h" #include "disasm.h" +#include "decode_macros.h" #include -#ifdef RISCV_ENABLE_COMMITLOG static void commit_log_reset(processor_t* p) { p->get_state()->log_reg_write.clear(); @@ -27,7 +28,7 @@ static void commit_log_print_value(FILE *log_file, int width, const void *data) switch (width) { case 8: - fprintf(log_file, "0x%01" PRIx8, *(const uint8_t *)data); + fprintf(log_file, "0x%02" PRIx8, *(const uint8_t *)data); break; case 16: fprintf(log_file, "0x%04" PRIx16, *(const uint16_t *)data); @@ -59,11 +60,6 @@ static void commit_log_print_value(FILE *log_file, int width, uint64_t val) commit_log_print_value(log_file, width, &val); } -const char* processor_t::get_symbol(uint64_t addr) -{ - return sim->get_symbol(addr); -} - static void commit_log_print_insn(processor_t *p, reg_t pc, insn_t insn) { FILE *log_file = p->get_log_file(); @@ -122,10 +118,10 @@ static void commit_log_print_insn(processor_t *p, reg_t pc, insn_t insn) if (!show_vec && (is_vreg || is_vec)) { fprintf(log_file, " e%ld %s%ld l%ld", - p->VU.vsew, + (long)p->VU.vsew, p->VU.vflmul < 1 ? "mf" : "m", - p->VU.vflmul < 1 ? (reg_t)(1 / p->VU.vflmul) : (reg_t)p->VU.vflmul, - p->VU.vl->read()); + p->VU.vflmul < 1 ? (long)(1 / p->VU.vflmul) : (long)p->VU.vflmul, + (long)p->VU.vl->read()); show_vec = true; } @@ -133,7 +129,7 @@ static void commit_log_print_insn(processor_t *p, reg_t pc, insn_t insn) if (prefix == 'c') fprintf(log_file, " c%d_%s ", rd, csr_name(rd)); else - fprintf(log_file, " %c%2d ", prefix, rd); + fprintf(log_file, " %c%-2d ", prefix, rd); if (is_vreg) commit_log_print_value(log_file, size, &p->VU.elt(rd, 0)); else @@ -154,40 +150,34 @@ static void commit_log_print_insn(processor_t *p, reg_t pc, insn_t insn) } fprintf(log_file, "\n"); } -#else -static void commit_log_reset(processor_t* p) {} -static void commit_log_stash_privilege(processor_t* p) {} -static void commit_log_print_insn(processor_t* p, reg_t pc, insn_t insn) {} -#endif inline void processor_t::update_histogram(reg_t pc) { -#ifdef RISCV_ENABLE_HISTOGRAM - pc_histogram[pc]++; -#endif + if (histogram_enabled) + pc_histogram[pc]++; } -// This is expected to be inlined by the compiler so each use of execute_insn -// includes a duplicated body of the function to get separate fetch.func -// function calls. -static inline reg_t execute_insn(processor_t* p, reg_t pc, insn_fetch_t fetch) +// These two functions are expected to be inlined by the compiler separately in +// the processor_t::step() loop. The logged variant is used in the slow path +static inline reg_t execute_insn_fast(processor_t* p, reg_t pc, insn_fetch_t fetch) { + return fetch.func(p, fetch.insn, pc); +} +static inline reg_t execute_insn_logged(processor_t* p, reg_t pc, insn_fetch_t fetch) { - commit_log_reset(p); - commit_log_stash_privilege(p); + if (p->get_log_commits_enabled()) { + commit_log_reset(p); + commit_log_stash_privilege(p); + } + reg_t npc; try { npc = fetch.func(p, fetch.insn, pc); if (npc != PC_SERIALIZE_BEFORE) { - -#ifdef RISCV_ENABLE_COMMITLOG if (p->get_log_commits_enabled()) { commit_log_print_insn(p, pc, fetch.insn); } -#endif - } -#ifdef RISCV_ENABLE_COMMITLOG } catch (wait_for_interrupt_t &t) { if (p->get_log_commits_enabled()) { commit_log_print_insn(p, pc, fetch.insn); @@ -204,7 +194,6 @@ static inline reg_t execute_insn(processor_t* p, reg_t pc, insn_fetch_t fetch) } } throw; -#endif } catch(...) { throw; } @@ -215,7 +204,8 @@ static inline reg_t execute_insn(processor_t* p, reg_t pc, insn_fetch_t fetch) bool processor_t::slow_path() { - return debug || state.single_step != state.STEP_NONE || state.debug_mode; + return debug || state.single_step != state.STEP_NONE || state.debug_mode || + log_commits_enabled || histogram_enabled || in_wfi || check_triggers_icount; } // fetch/decode/execute loop @@ -238,19 +228,18 @@ void processor_t::step(size_t n) mmu_t* _mmu = mmu; #define advance_pc() \ - if (unlikely(invalid_pc(pc))) { \ - switch (pc) { \ - case PC_SERIALIZE_BEFORE: state.serialized = true; break; \ - case PC_SERIALIZE_AFTER: ++instret; break; \ - case PC_SERIALIZE_WFI: n = ++instret; break; \ - default: abort(); \ - } \ - pc = state.pc; \ - break; \ - } else { \ - state.pc = pc; \ - instret++; \ - } + if (unlikely(invalid_pc(pc))) { \ + switch (pc) { \ + case PC_SERIALIZE_BEFORE: state.serialized = true; break; \ + case PC_SERIALIZE_AFTER: ++instret; break; \ + default: abort(); \ + } \ + pc = state.pc; \ + break; \ + } else { \ + state.pc = pc; \ + instret++; \ + } try { @@ -274,10 +263,24 @@ void processor_t::step(size_t n) state.single_step = state.STEP_STEPPED; } + if (!state.serialized && check_triggers_icount) { + auto match = TM.detect_icount_match(); + if (match.has_value()) { + assert(match->timing == triggers::TIMING_BEFORE); + throw triggers::matched_t((triggers::operation_t)0, 0, match->action); + } + } + + // debug mode wfis must nop + if (unlikely(in_wfi && !state.debug_mode)) { + throw wait_for_interrupt_t(); + } + + in_wfi = false; insn_fetch_t fetch = mmu->load_insn(pc); if (debug && !state.serialized) disasm(fetch.insn); - pc = execute_insn(this, pc, fetch); + pc = execute_insn_logged(this, pc, fetch); advance_pc(); } } @@ -286,7 +289,7 @@ void processor_t::step(size_t n) // Main simulation loop, fast path. for (auto ic_entry = _mmu->access_icache(pc); ; ) { auto fetch = ic_entry->data; - pc = execute_insn(this, pc, fetch); + pc = execute_insn_fast(this, pc, fetch); ic_entry = ic_entry->next; if (unlikely(ic_entry->tag != pc)) break; @@ -304,38 +307,26 @@ void processor_t::step(size_t n) take_trap(t, pc); n = instret; - if (unlikely(state.single_step == state.STEP_STEPPED)) { + // Trigger action takes priority over single step + auto match = TM.detect_trap_match(t); + if (match.has_value()) + take_trigger_action(match->action, 0, state.pc); + else if (unlikely(state.single_step == state.STEP_STEPPED)) { state.single_step = state.STEP_NONE; enter_debug_mode(DCSR_CAUSE_STEP); } } - catch (trigger_matched_t& t) + catch (triggers::matched_t& t) { if (mmu->matched_trigger) { - // This exception came from the MMU. That means the instruction hasn't - // fully executed yet. We start it again, but this time it won't throw - // an exception because matched_trigger is already set. (All memory - // instructions are idempotent so restarting is safe.) - - insn_fetch_t fetch = mmu->load_insn(pc); - pc = execute_insn(this, pc, fetch); - advance_pc(); - delete mmu->matched_trigger; mmu->matched_trigger = NULL; } - switch (state.mcontrol[t.index].action) { - case ACTION_DEBUG_MODE: - enter_debug_mode(DCSR_CAUSE_HWBP); - break; - case ACTION_DEBUG_EXCEPTION: { - trap_breakpoint trap(state.v, t.address); - take_trap(trap, pc); - break; - } - default: - abort(); - } + take_trigger_action(t.action, t.address, pc); + } + catch(trap_debug_mode&) + { + enter_debug_mode(DCSR_CAUSE_SWBP); } catch (wait_for_interrupt_t &t) { @@ -346,9 +337,14 @@ void processor_t::step(size_t n) // allows us to switch to other threads only once per idle loop in case // there is activity. n = ++instret; + in_wfi = true; } state.minstret->bump(instret); + + // Model a hart whose CPI is 1. + state.mcycle->bump(instret); + n -= instret; } } diff --git a/vendor/riscv/riscv-isa-sim/riscv/extension.h b/vendor/riscv/riscv-isa-sim/riscv/extension.h index d1e847d9b..de6ece3e6 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/extension.h +++ b/vendor/riscv/riscv-isa-sim/riscv/extension.h @@ -15,7 +15,7 @@ class extension_t virtual std::vector get_disasms() = 0; virtual const char* name() = 0; virtual void reset() {}; - virtual void set_debug(bool value) {}; + virtual void set_debug(bool UNUSED value) {} virtual ~extension_t(); void set_processor(processor_t* _p) { p = _p; } diff --git a/vendor/riscv/riscv-isa-sim/riscv/insn_macros.h b/vendor/riscv/riscv-isa-sim/riscv/insn_macros.h index 2fdfcedc5..8ec8f763e 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insn_macros.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insn_macros.h @@ -4,6 +4,6 @@ // These conflict with Boost headers so can't be included from insn_template.h #define P (*p) -#define require(x) do { if (unlikely(!(x))) throw trap_illegal_instruction(insn.bits()); } while (0) +#define require(x) (unlikely(!(x)) ? throw trap_illegal_instruction(insn.bits()) : (void) 0) #endif diff --git a/vendor/riscv/riscv-isa-sim/riscv/insn_template.cc b/vendor/riscv/riscv-isa-sim/riscv/insn_template.cc index e6a2f52c2..9194d19f4 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insn_template.cc +++ b/vendor/riscv/riscv-isa-sim/riscv/insn_template.cc @@ -3,7 +3,9 @@ #include "insn_template.h" #include "insn_macros.h" -reg_t rv32i_NAME(processor_t* p, insn_t insn, reg_t pc) +#define DECODE_MACRO_USAGE_LOGGED 0 + +reg_t fast_rv32i_NAME(processor_t* p, insn_t insn, reg_t pc) { #define xlen 32 reg_t npc = sext_xlen(pc + insn_length(OPCODE)); @@ -13,7 +15,30 @@ reg_t rv32i_NAME(processor_t* p, insn_t insn, reg_t pc) return npc; } -reg_t rv64i_NAME(processor_t* p, insn_t insn, reg_t pc) +reg_t fast_rv64i_NAME(processor_t* p, insn_t insn, reg_t pc) +{ + #define xlen 64 + reg_t npc = sext_xlen(pc + insn_length(OPCODE)); + #include "insns/NAME.h" + trace_opcode(p, OPCODE, insn); + #undef xlen + return npc; +} + +#undef DECODE_MACRO_USAGE_LOGGED +#define DECODE_MACRO_USAGE_LOGGED 1 + +reg_t logged_rv32i_NAME(processor_t* p, insn_t insn, reg_t pc) +{ + #define xlen 32 + reg_t npc = sext_xlen(pc + insn_length(OPCODE)); + #include "insns/NAME.h" + trace_opcode(p, OPCODE, insn); + #undef xlen + return npc; +} + +reg_t logged_rv64i_NAME(processor_t* p, insn_t insn, reg_t pc) { #define xlen 64 reg_t npc = sext_xlen(pc + insn_length(OPCODE)); @@ -26,7 +51,10 @@ reg_t rv64i_NAME(processor_t* p, insn_t insn, reg_t pc) #undef CHECK_REG #define CHECK_REG(reg) require((reg) < 16) -reg_t rv32e_NAME(processor_t* p, insn_t insn, reg_t pc) +#undef DECODE_MACRO_USAGE_LOGGED +#define DECODE_MACRO_USAGE_LOGGED 0 + +reg_t fast_rv32e_NAME(processor_t* p, insn_t insn, reg_t pc) { #define xlen 32 reg_t npc = sext_xlen(pc + insn_length(OPCODE)); @@ -36,7 +64,30 @@ reg_t rv32e_NAME(processor_t* p, insn_t insn, reg_t pc) return npc; } -reg_t rv64e_NAME(processor_t* p, insn_t insn, reg_t pc) +reg_t fast_rv64e_NAME(processor_t* p, insn_t insn, reg_t pc) +{ + #define xlen 64 + reg_t npc = sext_xlen(pc + insn_length(OPCODE)); + #include "insns/NAME.h" + trace_opcode(p, OPCODE, insn); + #undef xlen + return npc; +} + +#undef DECODE_MACRO_USAGE_LOGGED +#define DECODE_MACRO_USAGE_LOGGED 1 + +reg_t logged_rv32e_NAME(processor_t* p, insn_t insn, reg_t pc) +{ + #define xlen 32 + reg_t npc = sext_xlen(pc + insn_length(OPCODE)); + #include "insns/NAME.h" + trace_opcode(p, OPCODE, insn); + #undef xlen + return npc; +} + +reg_t logged_rv64e_NAME(processor_t* p, insn_t insn, reg_t pc) { #define xlen 64 reg_t npc = sext_xlen(pc + insn_length(OPCODE)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insn_template.h b/vendor/riscv/riscv-isa-sim/riscv/insn_template.h index 3c36d10e5..cead6d7dc 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insn_template.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insn_template.h @@ -1,9 +1,12 @@ // See LICENSE for license details. +#include "decode_macros.h" #include "arith.h" #include "mmu.h" #include "softfloat.h" #include "internals.h" #include "specialize.h" #include "tracer.h" +#include "p_ext_macros.h" +#include "v_ext_macros.h" #include diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/aes64ks1i.h b/vendor/riscv/riscv-isa-sim/riscv/insns/aes64ks1i.h index fff7109c4..c7354d6cb 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/aes64ks1i.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/aes64ks1i.h @@ -10,16 +10,13 @@ uint8_t round_consts [10] = { uint8_t enc_rcon = insn.rcon() ; -if(enc_rcon > 0xA) { - // Invalid opcode. - throw trap_illegal_instruction(0); -} +require(enc_rcon <= 0xA); uint32_t temp = (RS1 >> 32) & 0xFFFFFFFF ; uint8_t rcon = 0 ; uint64_t result ; -if(enc_rcon != 0xA) { +if (enc_rcon != 0xA) { temp = (temp >> 8) | (temp << 24); // Rotate right by 8 rcon = round_consts[enc_rcon]; } diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/aes_common.h b/vendor/riscv/riscv-isa-sim/riscv/insns/aes_common.h index 9cc353c1d..4f3f618db 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/aes_common.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/aes_common.h @@ -1,5 +1,5 @@ -uint8_t AES_ENC_SBOX[]= { +static uint8_t UNUSED AES_ENC_SBOX[]= { 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, @@ -34,7 +34,7 @@ uint8_t AES_ENC_SBOX[]= { 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16 }; -uint8_t AES_DEC_SBOX[] = { +static uint8_t UNUSED AES_DEC_SBOX[] = { 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/amoadd_d.h b/vendor/riscv/riscv-isa-sim/riscv/insns/amoadd_d.h index 6090fbc53..8573aa50e 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/amoadd_d.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/amoadd_d.h @@ -1,3 +1,3 @@ require_extension('A'); require_rv64; -WRITE_RD(MMU.amo_uint64(RS1, [&](uint64_t lhs) { return lhs + RS2; })); +WRITE_RD(MMU.amo(RS1, [&](uint64_t lhs) { return lhs + RS2; })); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/amoadd_w.h b/vendor/riscv/riscv-isa-sim/riscv/insns/amoadd_w.h index 2c6471afb..c288b3bc4 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/amoadd_w.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/amoadd_w.h @@ -1,2 +1,2 @@ require_extension('A'); -WRITE_RD(sext32(MMU.amo_uint32(RS1, [&](uint32_t lhs) { return lhs + RS2; }))); +WRITE_RD(sext32(MMU.amo(RS1, [&](uint32_t lhs) { return lhs + RS2; }))); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/amoand_d.h b/vendor/riscv/riscv-isa-sim/riscv/insns/amoand_d.h index 80aea184d..2df7ce2af 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/amoand_d.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/amoand_d.h @@ -1,3 +1,3 @@ require_extension('A'); require_rv64; -WRITE_RD(MMU.amo_uint64(RS1, [&](uint64_t lhs) { return lhs & RS2; })); +WRITE_RD(MMU.amo(RS1, [&](uint64_t lhs) { return lhs & RS2; })); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/amoand_w.h b/vendor/riscv/riscv-isa-sim/riscv/insns/amoand_w.h index f7e1ba7c0..962165f15 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/amoand_w.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/amoand_w.h @@ -1,2 +1,2 @@ require_extension('A'); -WRITE_RD(sext32(MMU.amo_uint32(RS1, [&](uint32_t lhs) { return lhs & RS2; }))); +WRITE_RD(sext32(MMU.amo(RS1, [&](uint32_t lhs) { return lhs & RS2; }))); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/amomax_d.h b/vendor/riscv/riscv-isa-sim/riscv/insns/amomax_d.h index 496d8ada9..ab95da09e 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/amomax_d.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/amomax_d.h @@ -1,3 +1,3 @@ require_extension('A'); require_rv64; -WRITE_RD(MMU.amo_uint64(RS1, [&](int64_t lhs) { return std::max(lhs, int64_t(RS2)); })); +WRITE_RD(MMU.amo(RS1, [&](int64_t lhs) { return std::max(lhs, int64_t(RS2)); })); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/amomax_w.h b/vendor/riscv/riscv-isa-sim/riscv/insns/amomax_w.h index 757bdd2cc..132c2e041 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/amomax_w.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/amomax_w.h @@ -1,2 +1,2 @@ require_extension('A'); -WRITE_RD(sext32(MMU.amo_uint32(RS1, [&](int32_t lhs) { return std::max(lhs, int32_t(RS2)); }))); +WRITE_RD(sext32(MMU.amo(RS1, [&](int32_t lhs) { return std::max(lhs, int32_t(RS2)); }))); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/amomaxu_d.h b/vendor/riscv/riscv-isa-sim/riscv/insns/amomaxu_d.h index 12b173313..e2371aa05 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/amomaxu_d.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/amomaxu_d.h @@ -1,3 +1,3 @@ require_extension('A'); require_rv64; -WRITE_RD(MMU.amo_uint64(RS1, [&](uint64_t lhs) { return std::max(lhs, RS2); })); +WRITE_RD(MMU.amo(RS1, [&](uint64_t lhs) { return std::max(lhs, RS2); })); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/amomaxu_w.h b/vendor/riscv/riscv-isa-sim/riscv/insns/amomaxu_w.h index 538df1c40..ebbdd415c 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/amomaxu_w.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/amomaxu_w.h @@ -1,2 +1,2 @@ require_extension('A'); -WRITE_RD(sext32(MMU.amo_uint32(RS1, [&](uint32_t lhs) { return std::max(lhs, uint32_t(RS2)); }))); +WRITE_RD(sext32(MMU.amo(RS1, [&](uint32_t lhs) { return std::max(lhs, uint32_t(RS2)); }))); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/amomin_d.h b/vendor/riscv/riscv-isa-sim/riscv/insns/amomin_d.h index 725d9839f..419e42e68 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/amomin_d.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/amomin_d.h @@ -1,3 +1,3 @@ require_extension('A'); require_rv64; -WRITE_RD(MMU.amo_uint64(RS1, [&](int64_t lhs) { return std::min(lhs, int64_t(RS2)); })); +WRITE_RD(MMU.amo(RS1, [&](int64_t lhs) { return std::min(lhs, int64_t(RS2)); })); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/amomin_w.h b/vendor/riscv/riscv-isa-sim/riscv/insns/amomin_w.h index ee53faa0c..749149c71 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/amomin_w.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/amomin_w.h @@ -1,2 +1,2 @@ require_extension('A'); -WRITE_RD(sext32(MMU.amo_uint32(RS1, [&](int32_t lhs) { return std::min(lhs, int32_t(RS2)); }))); +WRITE_RD(sext32(MMU.amo(RS1, [&](int32_t lhs) { return std::min(lhs, int32_t(RS2)); }))); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/amominu_d.h b/vendor/riscv/riscv-isa-sim/riscv/insns/amominu_d.h index 15b6c0a48..b4bab4753 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/amominu_d.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/amominu_d.h @@ -1,3 +1,3 @@ require_extension('A'); require_rv64; -WRITE_RD(MMU.amo_uint64(RS1, [&](uint64_t lhs) { return std::min(lhs, RS2); })); +WRITE_RD(MMU.amo(RS1, [&](uint64_t lhs) { return std::min(lhs, RS2); })); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/amominu_w.h b/vendor/riscv/riscv-isa-sim/riscv/insns/amominu_w.h index 52e1141b8..680eef271 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/amominu_w.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/amominu_w.h @@ -1,2 +1,2 @@ require_extension('A'); -WRITE_RD(sext32(MMU.amo_uint32(RS1, [&](uint32_t lhs) { return std::min(lhs, uint32_t(RS2)); }))); +WRITE_RD(sext32(MMU.amo(RS1, [&](uint32_t lhs) { return std::min(lhs, uint32_t(RS2)); }))); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/amoor_d.h b/vendor/riscv/riscv-isa-sim/riscv/insns/amoor_d.h index de8762745..c201d88a4 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/amoor_d.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/amoor_d.h @@ -1,3 +1,3 @@ require_extension('A'); require_rv64; -WRITE_RD(MMU.amo_uint64(RS1, [&](uint64_t lhs) { return lhs | RS2; })); +WRITE_RD(MMU.amo(RS1, [&](uint64_t lhs) { return lhs | RS2; })); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/amoor_w.h b/vendor/riscv/riscv-isa-sim/riscv/insns/amoor_w.h index 3455981d8..0adac5b72 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/amoor_w.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/amoor_w.h @@ -1,2 +1,2 @@ require_extension('A'); -WRITE_RD(sext32(MMU.amo_uint32(RS1, [&](uint32_t lhs) { return lhs | RS2; }))); +WRITE_RD(sext32(MMU.amo(RS1, [&](uint32_t lhs) { return lhs | RS2; }))); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/amoswap_d.h b/vendor/riscv/riscv-isa-sim/riscv/insns/amoswap_d.h index e1bffdeb5..62a95b0a0 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/amoswap_d.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/amoswap_d.h @@ -1,3 +1,3 @@ require_extension('A'); require_rv64; -WRITE_RD(MMU.amo_uint64(RS1, [&](uint64_t lhs) { return RS2; })); +WRITE_RD(MMU.amo(RS1, [&](uint64_t UNUSED lhs) { return RS2; })); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/amoswap_w.h b/vendor/riscv/riscv-isa-sim/riscv/insns/amoswap_w.h index 0f78369c7..819579cdd 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/amoswap_w.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/amoswap_w.h @@ -1,2 +1,2 @@ require_extension('A'); -WRITE_RD(sext32(MMU.amo_uint32(RS1, [&](uint32_t lhs) { return RS2; }))); +WRITE_RD(sext32(MMU.amo(RS1, [&](uint32_t UNUSED lhs) { return RS2; }))); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/amoxor_d.h b/vendor/riscv/riscv-isa-sim/riscv/insns/amoxor_d.h index 1b3c0bf41..a40050fd0 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/amoxor_d.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/amoxor_d.h @@ -1,3 +1,3 @@ require_extension('A'); require_rv64; -WRITE_RD(MMU.amo_uint64(RS1, [&](uint64_t lhs) { return lhs ^ RS2; })); +WRITE_RD(MMU.amo(RS1, [&](uint64_t lhs) { return lhs ^ RS2; })); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/amoxor_w.h b/vendor/riscv/riscv-isa-sim/riscv/insns/amoxor_w.h index a1ea82f1d..af025d689 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/amoxor_w.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/amoxor_w.h @@ -1,2 +1,2 @@ require_extension('A'); -WRITE_RD(sext32(MMU.amo_uint32(RS1, [&](uint32_t lhs) { return lhs ^ RS2; }))); +WRITE_RD(sext32(MMU.amo(RS1, [&](uint32_t lhs) { return lhs ^ RS2; }))); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/bcompress.h b/vendor/riscv/riscv-isa-sim/riscv/insns/bcompress.h index aaafbe38f..579346f46 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/bcompress.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/bcompress.h @@ -1,4 +1,4 @@ -require_extension(EXT_XBITMANIP); +require_extension(EXT_XZBE); uint64_t c = 0, i = 0, data = zext_xlen(RS1), mask = zext_xlen(RS2); while (mask) { uint64_t b = mask & ~((mask | (mask-1)) + 1); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/bcompressw.h b/vendor/riscv/riscv-isa-sim/riscv/insns/bcompressw.h index 7fe25933e..2c1017cd1 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/bcompressw.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/bcompressw.h @@ -1,5 +1,5 @@ require_rv64; -require_extension(EXT_XBITMANIP); +require_extension(EXT_XZBE); uint64_t c = 0, i = 0, data = zext32(RS1), mask = zext32(RS2); while (mask) { uint64_t b = mask & ~((mask | (mask-1)) + 1); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/bdecompress.h b/vendor/riscv/riscv-isa-sim/riscv/insns/bdecompress.h index b5bfe3b0d..2894be014 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/bdecompress.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/bdecompress.h @@ -1,4 +1,4 @@ -require_extension(EXT_XBITMANIP); +require_extension(EXT_XZBE); uint64_t c = 0, i = 0, data = zext_xlen(RS1), mask = zext_xlen(RS2); while (mask) { uint64_t b = mask & ~((mask | (mask-1)) + 1); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/bdecompressw.h b/vendor/riscv/riscv-isa-sim/riscv/insns/bdecompressw.h index 836d376a5..468a7260a 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/bdecompressw.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/bdecompressw.h @@ -1,5 +1,5 @@ require_rv64; -require_extension(EXT_XBITMANIP); +require_extension(EXT_XZBE); uint64_t c = 0, i = 0, data = zext32(RS1), mask = zext32(RS2); while (mask) { uint64_t b = mask & ~((mask | (mask-1)) + 1); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/beq.h b/vendor/riscv/riscv-isa-sim/riscv/insns/beq.h index fd7e06149..3d2c9758d 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/beq.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/beq.h @@ -1,2 +1,2 @@ -if(RS1 == RS2) +if (RS1 == RS2) set_pc(BRANCH_TARGET); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/bfp.h b/vendor/riscv/riscv-isa-sim/riscv/insns/bfp.h index 1b63ffb83..886d84053 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/bfp.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/bfp.h @@ -1,4 +1,4 @@ -require_extension(EXT_XBITMANIP); +require_extension(EXT_XZBF); reg_t cfg = RS2 >> (xlen/2); if ((cfg >> 30) == 2) cfg = cfg >> 16; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/bfpw.h b/vendor/riscv/riscv-isa-sim/riscv/insns/bfpw.h index bd0411917..42479e72f 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/bfpw.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/bfpw.h @@ -1,5 +1,5 @@ require_rv64; -require_extension(EXT_XBITMANIP); +require_extension(EXT_XZBF); reg_t cfg = RS2 >> 16; int len = (cfg >> 8) & 15; int off = cfg & 31; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/bge.h b/vendor/riscv/riscv-isa-sim/riscv/insns/bge.h index da0c68e6a..b2421c229 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/bge.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/bge.h @@ -1,2 +1,2 @@ -if(sreg_t(RS1) >= sreg_t(RS2)) +if (sreg_t(RS1) >= sreg_t(RS2)) set_pc(BRANCH_TARGET); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/bgeu.h b/vendor/riscv/riscv-isa-sim/riscv/insns/bgeu.h index d764a347e..f09b7f4d0 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/bgeu.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/bgeu.h @@ -1,2 +1,2 @@ -if(RS1 >= RS2) +if (RS1 >= RS2) set_pc(BRANCH_TARGET); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/blt.h b/vendor/riscv/riscv-isa-sim/riscv/insns/blt.h index c54fb7693..cad064be3 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/blt.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/blt.h @@ -1,2 +1,2 @@ -if(sreg_t(RS1) < sreg_t(RS2)) +if (sreg_t(RS1) < sreg_t(RS2)) set_pc(BRANCH_TARGET); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/bltu.h b/vendor/riscv/riscv-isa-sim/riscv/insns/bltu.h index ff75e8a6d..b7c3300b3 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/bltu.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/bltu.h @@ -1,2 +1,2 @@ -if(RS1 < RS2) +if (RS1 < RS2) set_pc(BRANCH_TARGET); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/bmatflip.h b/vendor/riscv/riscv-isa-sim/riscv/insns/bmatflip.h index 2ddf1c4b2..c10df8f9a 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/bmatflip.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/bmatflip.h @@ -1,5 +1,5 @@ require_rv64; -require_extension(EXT_XBITMANIP); +require_extension(EXT_XZBM); reg_t x = RS1; for (int i = 0; i < 3; i++) { x = (x & 0xFFFF00000000FFFFLL) | ((x & 0x0000FFFF00000000LL) >> 16) | ((x & 0x00000000FFFF0000LL) << 16); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/bmator.h b/vendor/riscv/riscv-isa-sim/riscv/insns/bmator.h index 7a1237f51..33057ca04 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/bmator.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/bmator.h @@ -1,5 +1,5 @@ require_rv64; -require_extension(EXT_XBITMANIP); +require_extension(EXT_XZBM); // transpose of rs2 int64_t rs2t = RS2; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/bmatxor.h b/vendor/riscv/riscv-isa-sim/riscv/insns/bmatxor.h index 094e8284b..ca2d09671 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/bmatxor.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/bmatxor.h @@ -1,5 +1,5 @@ require_rv64; -require_extension(EXT_XBITMANIP); +require_extension(EXT_XZBM); // transpose of rs2 int64_t rs2t = RS2; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/bne.h b/vendor/riscv/riscv-isa-sim/riscv/insns/bne.h index 1e6cb7c7a..e832fa14e 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/bne.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/bne.h @@ -1,2 +1,2 @@ -if(RS1 != RS2) +if (RS1 != RS2) set_pc(BRANCH_TARGET); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/c_add.h b/vendor/riscv/riscv-isa-sim/riscv/insns/c_add.h index ab7d4d4c8..796e634a4 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/c_add.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/c_add.h @@ -1,3 +1,3 @@ -require_extension('C'); +require_extension(EXT_ZCA); require(insn.rvc_rs2() != 0); WRITE_RD(sext_xlen(RVC_RS1 + RVC_RS2)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/c_addi.h b/vendor/riscv/riscv-isa-sim/riscv/insns/c_addi.h index eb983442a..62d063992 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/c_addi.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/c_addi.h @@ -1,2 +1,2 @@ -require_extension('C'); +require_extension(EXT_ZCA); WRITE_RD(sext_xlen(RVC_RS1 + insn.rvc_imm())); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/c_addi4spn.h b/vendor/riscv/riscv-isa-sim/riscv/insns/c_addi4spn.h index e5f3832f6..a1d5425eb 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/c_addi4spn.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/c_addi4spn.h @@ -1,3 +1,3 @@ -require_extension('C'); +require_extension(EXT_ZCA); require(insn.rvc_addi4spn_imm() != 0); WRITE_RVC_RS2S(sext_xlen(RVC_SP + insn.rvc_addi4spn_imm())); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/c_addw.h b/vendor/riscv/riscv-isa-sim/riscv/insns/c_addw.h index 6e0ae3a52..bd64b1e7a 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/c_addw.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/c_addw.h @@ -1,3 +1,3 @@ -require_extension('C'); +require_extension(EXT_ZCA); require_rv64; WRITE_RVC_RS1S(sext32(RVC_RS1S + RVC_RS2S)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/c_and.h b/vendor/riscv/riscv-isa-sim/riscv/insns/c_and.h index 4d7bab6c5..9054e05df 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/c_and.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/c_and.h @@ -1,2 +1,2 @@ -require_extension('C'); +require_extension(EXT_ZCA); WRITE_RVC_RS1S(RVC_RS1S & RVC_RS2S); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/c_andi.h b/vendor/riscv/riscv-isa-sim/riscv/insns/c_andi.h index 9de5a1acb..156e4405c 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/c_andi.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/c_andi.h @@ -1,2 +1,2 @@ -require_extension('C'); +require_extension(EXT_ZCA); WRITE_RVC_RS1S(RVC_RS1S & insn.rvc_imm()); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/c_beqz.h b/vendor/riscv/riscv-isa-sim/riscv/insns/c_beqz.h index 35c119603..65bdcf6ab 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/c_beqz.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/c_beqz.h @@ -1,3 +1,3 @@ -require_extension('C'); +require_extension(EXT_ZCA); if (RVC_RS1S == 0) set_pc(pc + insn.rvc_b_imm()); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/c_bnez.h b/vendor/riscv/riscv-isa-sim/riscv/insns/c_bnez.h index 1e40ea78e..2a2e9a9ac 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/c_bnez.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/c_bnez.h @@ -1,3 +1,3 @@ -require_extension('C'); +require_extension(EXT_ZCA); if (RVC_RS1S != 0) set_pc(pc + insn.rvc_b_imm()); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/c_ebreak.h b/vendor/riscv/riscv-isa-sim/riscv/insns/c_ebreak.h index 7d04f46d4..14b513631 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/c_ebreak.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/c_ebreak.h @@ -1,2 +1,9 @@ -require_extension('C'); -throw trap_breakpoint(STATE.v, pc); +require_extension(EXT_ZCA); +if (!STATE.debug_mode && + ((STATE.prv == PRV_M && STATE.dcsr->ebreakm) || + (STATE.prv == PRV_S && STATE.dcsr->ebreaks) || + (STATE.prv == PRV_U && STATE.dcsr->ebreaku))) { + throw trap_debug_mode(); +} else { + throw trap_breakpoint(STATE.v, pc); +} diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/c_fld.h b/vendor/riscv/riscv-isa-sim/riscv/insns/c_fld.h index 319615b8e..dac173826 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/c_fld.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/c_fld.h @@ -1,4 +1,3 @@ -require_extension('C'); -require_extension('D'); +require_extension(EXT_ZCD); require_fp; -WRITE_RVC_FRS2S(f64(MMU.load_uint64(RVC_RS1S + insn.rvc_ld_imm()))); +WRITE_RVC_FRS2S(f64(MMU.load(RVC_RS1S + insn.rvc_ld_imm()))); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/c_fldsp.h b/vendor/riscv/riscv-isa-sim/riscv/insns/c_fldsp.h index 534eef7d2..b49a88a6e 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/c_fldsp.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/c_fldsp.h @@ -1,4 +1,3 @@ -require_extension('C'); -require_extension('D'); +require_extension(EXT_ZCD); require_fp; -WRITE_FRD(f64(MMU.load_uint64(RVC_SP + insn.rvc_ldsp_imm()))); +WRITE_FRD(f64(MMU.load(RVC_SP + insn.rvc_ldsp_imm()))); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/c_flw.h b/vendor/riscv/riscv-isa-sim/riscv/insns/c_flw.h index 682566c70..95ae26028 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/c_flw.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/c_flw.h @@ -1,8 +1,8 @@ -require_extension('C'); if (xlen == 32) { - require_extension('F'); + require_extension(EXT_ZCF); require_fp; - WRITE_RVC_FRS2S(f32(MMU.load_uint32(RVC_RS1S + insn.rvc_lw_imm()))); + WRITE_RVC_FRS2S(f32(MMU.load(RVC_RS1S + insn.rvc_lw_imm()))); } else { // c.ld - WRITE_RVC_RS2S(MMU.load_int64(RVC_RS1S + insn.rvc_ld_imm())); + require_extension(EXT_ZCA); + WRITE_RVC_RS2S(MMU.load(RVC_RS1S + insn.rvc_ld_imm())); } diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/c_flwsp.h b/vendor/riscv/riscv-isa-sim/riscv/insns/c_flwsp.h index 79058c40a..eea0ec53c 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/c_flwsp.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/c_flwsp.h @@ -1,9 +1,9 @@ -require_extension('C'); if (xlen == 32) { - require_extension('F'); + require_extension(EXT_ZCF); require_fp; - WRITE_FRD(f32(MMU.load_uint32(RVC_SP + insn.rvc_lwsp_imm()))); + WRITE_FRD(f32(MMU.load(RVC_SP + insn.rvc_lwsp_imm()))); } else { // c.ldsp + require_extension(EXT_ZCA); require(insn.rvc_rd() != 0); - WRITE_RD(MMU.load_int64(RVC_SP + insn.rvc_ldsp_imm())); + WRITE_RD(MMU.load(RVC_SP + insn.rvc_ldsp_imm())); } diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/c_fsd.h b/vendor/riscv/riscv-isa-sim/riscv/insns/c_fsd.h index 6f2c8f4c3..d86b47e4c 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/c_fsd.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/c_fsd.h @@ -1,4 +1,3 @@ -require_extension('C'); -require_extension('D'); +require_extension(EXT_ZCD); require_fp; -MMU.store_uint64(RVC_RS1S + insn.rvc_ld_imm(), RVC_FRS2S.v[0]); +MMU.store(RVC_RS1S + insn.rvc_ld_imm(), RVC_FRS2S.v[0]); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/c_fsdsp.h b/vendor/riscv/riscv-isa-sim/riscv/insns/c_fsdsp.h index 27b933191..980dbc4c5 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/c_fsdsp.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/c_fsdsp.h @@ -1,4 +1,3 @@ -require_extension('C'); -require_extension('D'); +require_extension(EXT_ZCD); require_fp; -MMU.store_uint64(RVC_SP + insn.rvc_sdsp_imm(), RVC_FRS2.v[0]); +MMU.store(RVC_SP + insn.rvc_sdsp_imm(), RVC_FRS2.v[0]); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/c_fsw.h b/vendor/riscv/riscv-isa-sim/riscv/insns/c_fsw.h index 708582296..d7d6fed36 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/c_fsw.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/c_fsw.h @@ -1,8 +1,8 @@ -require_extension('C'); if (xlen == 32) { - require_extension('F'); + require_extension(EXT_ZCF); require_fp; - MMU.store_uint32(RVC_RS1S + insn.rvc_lw_imm(), RVC_FRS2S.v[0]); + MMU.store(RVC_RS1S + insn.rvc_lw_imm(), RVC_FRS2S.v[0]); } else { // c.sd - MMU.store_uint64(RVC_RS1S + insn.rvc_ld_imm(), RVC_RS2S); + require_extension(EXT_ZCA); + MMU.store(RVC_RS1S + insn.rvc_ld_imm(), RVC_RS2S); } diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/c_fswsp.h b/vendor/riscv/riscv-isa-sim/riscv/insns/c_fswsp.h index c5a003fcd..595225107 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/c_fswsp.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/c_fswsp.h @@ -1,8 +1,8 @@ -require_extension('C'); if (xlen == 32) { - require_extension('F'); + require_extension(EXT_ZCF); require_fp; - MMU.store_uint32(RVC_SP + insn.rvc_swsp_imm(), RVC_FRS2.v[0]); + MMU.store(RVC_SP + insn.rvc_swsp_imm(), RVC_FRS2.v[0]); } else { // c.sdsp - MMU.store_uint64(RVC_SP + insn.rvc_sdsp_imm(), RVC_RS2); + require_extension(EXT_ZCA); + MMU.store(RVC_SP + insn.rvc_sdsp_imm(), RVC_RS2); } diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/c_j.h b/vendor/riscv/riscv-isa-sim/riscv/insns/c_j.h index 6d8939c47..a2712c322 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/c_j.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/c_j.h @@ -1,2 +1,2 @@ -require_extension('C'); +require_extension(EXT_ZCA); set_pc(pc + insn.rvc_j_imm()); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/c_jal.h b/vendor/riscv/riscv-isa-sim/riscv/insns/c_jal.h index 4f156f61f..49e20f4b6 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/c_jal.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/c_jal.h @@ -1,4 +1,4 @@ -require_extension('C'); +require_extension(EXT_ZCA); if (xlen == 32) { reg_t tmp = npc; set_pc(pc + insn.rvc_j_imm()); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/c_jalr.h b/vendor/riscv/riscv-isa-sim/riscv/insns/c_jalr.h index cb1e4222d..0a00f1cc0 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/c_jalr.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/c_jalr.h @@ -1,4 +1,4 @@ -require_extension('C'); +require_extension(EXT_ZCA); require(insn.rvc_rs1() != 0); reg_t tmp = npc; set_pc(RVC_RS1 & ~reg_t(1)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/c_jr.h b/vendor/riscv/riscv-isa-sim/riscv/insns/c_jr.h index 9c4a8ea9a..020cafd81 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/c_jr.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/c_jr.h @@ -1,3 +1,3 @@ -require_extension('C'); +require_extension(EXT_ZCA); require(insn.rvc_rs1() != 0); set_pc(RVC_RS1 & ~reg_t(1)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/c_lbu.h b/vendor/riscv/riscv-isa-sim/riscv/insns/c_lbu.h new file mode 100644 index 000000000..e8fb380c9 --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/c_lbu.h @@ -0,0 +1,2 @@ +require_extension(EXT_ZCB); +WRITE_RVC_RS2S(MMU.load(RVC_RS1S + insn.rvc_lbimm())); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/c_lh.h b/vendor/riscv/riscv-isa-sim/riscv/insns/c_lh.h new file mode 100644 index 000000000..6a00146cf --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/c_lh.h @@ -0,0 +1,2 @@ +require_extension(EXT_ZCB); +WRITE_RVC_RS2S(MMU.load(RVC_RS1S + insn.rvc_lhimm())); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/c_lhu.h b/vendor/riscv/riscv-isa-sim/riscv/insns/c_lhu.h new file mode 100644 index 000000000..fb190c550 --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/c_lhu.h @@ -0,0 +1,2 @@ +require_extension(EXT_ZCB); +WRITE_RVC_RS2S(MMU.load(RVC_RS1S + insn.rvc_lhimm())); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/c_li.h b/vendor/riscv/riscv-isa-sim/riscv/insns/c_li.h index f9fd66b2f..bfe16a2b0 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/c_li.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/c_li.h @@ -1,2 +1,2 @@ -require_extension('C'); +require_extension(EXT_ZCA); WRITE_RD(insn.rvc_imm()); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/c_lui.h b/vendor/riscv/riscv-isa-sim/riscv/insns/c_lui.h index 75d8eb892..956fa448b 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/c_lui.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/c_lui.h @@ -1,4 +1,4 @@ -require_extension('C'); +require_extension(EXT_ZCA); if (insn.rvc_rd() == 2) { // c.addi16sp require(insn.rvc_addi16sp_imm() != 0); WRITE_REG(X_SP, sext_xlen(RVC_SP + insn.rvc_addi16sp_imm())); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/c_lw.h b/vendor/riscv/riscv-isa-sim/riscv/insns/c_lw.h index ef49dd909..63b708c9a 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/c_lw.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/c_lw.h @@ -1,2 +1,2 @@ -require_extension('C'); -WRITE_RVC_RS2S(MMU.load_int32(RVC_RS1S + insn.rvc_lw_imm())); +require_extension(EXT_ZCA); +WRITE_RVC_RS2S(MMU.load(RVC_RS1S + insn.rvc_lw_imm())); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/c_lwsp.h b/vendor/riscv/riscv-isa-sim/riscv/insns/c_lwsp.h index b3d74dbf0..de23cd970 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/c_lwsp.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/c_lwsp.h @@ -1,3 +1,3 @@ -require_extension('C'); +require_extension(EXT_ZCA); require(insn.rvc_rd() != 0); -WRITE_RD(MMU.load_int32(RVC_SP + insn.rvc_lwsp_imm())); +WRITE_RD(MMU.load(RVC_SP + insn.rvc_lwsp_imm())); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/c_mul.h b/vendor/riscv/riscv-isa-sim/riscv/insns/c_mul.h new file mode 100644 index 000000000..3ac0b01b3 --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/c_mul.h @@ -0,0 +1,3 @@ +require_extension(EXT_ZCB); +require_either_extension('M', EXT_ZMMUL); +WRITE_RVC_RS1S(sext_xlen(RVC_RS1S * RVC_RS2S)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/c_mv.h b/vendor/riscv/riscv-isa-sim/riscv/insns/c_mv.h index a03d0d076..b227005e4 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/c_mv.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/c_mv.h @@ -1,3 +1,3 @@ -require_extension('C'); +require_extension(EXT_ZCA); require(insn.rvc_rs2() != 0); WRITE_RD(RVC_RS2); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/c_not.h b/vendor/riscv/riscv-isa-sim/riscv/insns/c_not.h new file mode 100644 index 000000000..26c1626d2 --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/c_not.h @@ -0,0 +1,2 @@ +require_extension(EXT_ZCB); +WRITE_RVC_RS1S(sext_xlen(~RVC_RS1S)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/c_or.h b/vendor/riscv/riscv-isa-sim/riscv/insns/c_or.h index 56436d1a1..736ec997c 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/c_or.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/c_or.h @@ -1,2 +1,2 @@ -require_extension('C'); +require_extension(EXT_ZCA); WRITE_RVC_RS1S(RVC_RS1S | RVC_RS2S); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/c_sb.h b/vendor/riscv/riscv-isa-sim/riscv/insns/c_sb.h new file mode 100644 index 000000000..5badc28c9 --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/c_sb.h @@ -0,0 +1,2 @@ +require_extension(EXT_ZCB); +MMU.store(RVC_RS1S + insn.rvc_lbimm(), RVC_RS2S); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/c_sext_b.h b/vendor/riscv/riscv-isa-sim/riscv/insns/c_sext_b.h new file mode 100644 index 000000000..dca6af1a2 --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/c_sext_b.h @@ -0,0 +1,3 @@ +require_extension(EXT_ZCB); +require_extension(EXT_ZBB); +WRITE_RVC_RS1S((sreg_t)(int8_t)(RVC_RS1S)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/c_sext_h.h b/vendor/riscv/riscv-isa-sim/riscv/insns/c_sext_h.h new file mode 100644 index 000000000..b286d0769 --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/c_sext_h.h @@ -0,0 +1,3 @@ +require_extension(EXT_ZCB); +require_extension(EXT_ZBB); +WRITE_RVC_RS1S((sreg_t)(int16_t)(RVC_RS1S)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/c_sh.h b/vendor/riscv/riscv-isa-sim/riscv/insns/c_sh.h new file mode 100644 index 000000000..271ca09db --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/c_sh.h @@ -0,0 +1,2 @@ +require_extension(EXT_ZCB); +MMU.store(RVC_RS1S + insn.rvc_lhimm(), RVC_RS2S); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/c_slli.h b/vendor/riscv/riscv-isa-sim/riscv/insns/c_slli.h index 24fbb1335..1358d4d21 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/c_slli.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/c_slli.h @@ -1,3 +1,3 @@ -require_extension('C'); +require_extension(EXT_ZCA); require(insn.rvc_zimm() < xlen); WRITE_RD(sext_xlen(RVC_RS1 << insn.rvc_zimm())); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/c_srai.h b/vendor/riscv/riscv-isa-sim/riscv/insns/c_srai.h index f6638b1e2..8f25e39c8 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/c_srai.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/c_srai.h @@ -1,3 +1,3 @@ -require_extension('C'); +require_extension(EXT_ZCA); require(insn.rvc_zimm() < xlen); WRITE_RVC_RS1S(sext_xlen(sext_xlen(RVC_RS1S) >> insn.rvc_zimm())); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/c_srli.h b/vendor/riscv/riscv-isa-sim/riscv/insns/c_srli.h index f410fefda..de0803121 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/c_srli.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/c_srli.h @@ -1,3 +1,3 @@ -require_extension('C'); +require_extension(EXT_ZCA); require(insn.rvc_zimm() < xlen); WRITE_RVC_RS1S(sext_xlen(zext_xlen(RVC_RS1S) >> insn.rvc_zimm())); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/c_sub.h b/vendor/riscv/riscv-isa-sim/riscv/insns/c_sub.h index 1b8e3735c..2a9d51b6e 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/c_sub.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/c_sub.h @@ -1,2 +1,2 @@ -require_extension('C'); +require_extension(EXT_ZCA); WRITE_RVC_RS1S(sext_xlen(RVC_RS1S - RVC_RS2S)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/c_subw.h b/vendor/riscv/riscv-isa-sim/riscv/insns/c_subw.h index 580f5b54e..80999735b 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/c_subw.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/c_subw.h @@ -1,3 +1,3 @@ -require_extension('C'); +require_extension(EXT_ZCA); require_rv64; WRITE_RVC_RS1S(sext32(RVC_RS1S - RVC_RS2S)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/c_sw.h b/vendor/riscv/riscv-isa-sim/riscv/insns/c_sw.h index 3073e9d62..5fdf4a166 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/c_sw.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/c_sw.h @@ -1,2 +1,2 @@ -require_extension('C'); -MMU.store_uint32(RVC_RS1S + insn.rvc_lw_imm(), RVC_RS2S); +require_extension(EXT_ZCA); +MMU.store(RVC_RS1S + insn.rvc_lw_imm(), RVC_RS2S); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/c_swsp.h b/vendor/riscv/riscv-isa-sim/riscv/insns/c_swsp.h index b8995ab05..d6684fda1 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/c_swsp.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/c_swsp.h @@ -1,2 +1,2 @@ -require_extension('C'); -MMU.store_uint32(RVC_SP + insn.rvc_swsp_imm(), RVC_RS2); +require_extension(EXT_ZCA); +MMU.store(RVC_SP + insn.rvc_swsp_imm(), RVC_RS2); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/c_xor.h b/vendor/riscv/riscv-isa-sim/riscv/insns/c_xor.h index 9981c1af9..7fd72ec9c 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/c_xor.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/c_xor.h @@ -1,2 +1,2 @@ -require_extension('C'); +require_extension(EXT_ZCA); WRITE_RVC_RS1S(RVC_RS1S ^ RVC_RS2S); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/c_zext_b.h b/vendor/riscv/riscv-isa-sim/riscv/insns/c_zext_b.h new file mode 100644 index 000000000..71c518e66 --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/c_zext_b.h @@ -0,0 +1,2 @@ +require_extension(EXT_ZCB); +WRITE_RVC_RS1S((reg_t)(uint8_t)(RVC_RS1S)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/c_zext_h.h b/vendor/riscv/riscv-isa-sim/riscv/insns/c_zext_h.h new file mode 100644 index 000000000..6b8fd8fb0 --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/c_zext_h.h @@ -0,0 +1,3 @@ +require_extension(EXT_ZCB); +require_extension(EXT_ZBB); +WRITE_RVC_RS1S((reg_t)(uint16_t)(RVC_RS1S)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/c_zext_w.h b/vendor/riscv/riscv-isa-sim/riscv/insns/c_zext_w.h new file mode 100644 index 000000000..1ad12a4a4 --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/c_zext_w.h @@ -0,0 +1,4 @@ +require_extension(EXT_ZCB); +require_extension(EXT_ZBA); +require_rv64; +WRITE_RVC_RS1S((reg_t)(uint32_t)(RVC_RS1S)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/cbo_clean.h b/vendor/riscv/riscv-isa-sim/riscv/insns/cbo_clean.h new file mode 100644 index 000000000..201fa4476 --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/cbo_clean.h @@ -0,0 +1,4 @@ +require_extension(EXT_ZICBOM); +DECLARE_XENVCFG_VARS(CBCFE); +require_envcfg(CBCFE); +MMU.clean_inval(RS1, true, false); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/cbo_flush.h b/vendor/riscv/riscv-isa-sim/riscv/insns/cbo_flush.h new file mode 100644 index 000000000..b17f5cf1a --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/cbo_flush.h @@ -0,0 +1,4 @@ +require_extension(EXT_ZICBOM); +DECLARE_XENVCFG_VARS(CBCFE); +require_envcfg(CBCFE); +MMU.clean_inval(RS1, true, true); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/cbo_inval.h b/vendor/riscv/riscv-isa-sim/riscv/insns/cbo_inval.h new file mode 100644 index 000000000..bd80a6fd2 --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/cbo_inval.h @@ -0,0 +1,9 @@ +require_extension(EXT_ZICBOM); +DECLARE_XENVCFG_VARS(CBIE); +require_envcfg(CBIE); +if (((STATE.prv != PRV_M) && (mCBIE == 1)) || + ((!STATE.v && (STATE.prv == PRV_U)) && (sCBIE = 1)) || + (STATE.v && ((hCBIE == 1) || ((STATE.prv == PRV_U) && (sCBIE== 0))))) + MMU.clean_inval(RS1, true, true); +else + MMU.clean_inval(RS1, false, true); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/cbo_zero.h b/vendor/riscv/riscv-isa-sim/riscv/insns/cbo_zero.h new file mode 100644 index 000000000..4bbe28d3e --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/cbo_zero.h @@ -0,0 +1,4 @@ +require_extension(EXT_ZICBOZ); +DECLARE_XENVCFG_VARS(CBZE); +require_envcfg(CBZE); +MMU.cbo_zero(RS1); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/clmulhw.h b/vendor/riscv/riscv-isa-sim/riscv/insns/clmulhw.h index 1fc0942a3..f41acb0e8 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/clmulhw.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/clmulhw.h @@ -1,4 +1,4 @@ -require_extension(EXT_XBITMANIP); +require_extension(EXT_XZBC); reg_t a = zext32(RS1), b = zext32(RS2), x = 0; for (int i = 1; i < 32; i++) if ((b >> i) & 1) diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/clmulrw.h b/vendor/riscv/riscv-isa-sim/riscv/insns/clmulrw.h index bc7510d4c..784859ae7 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/clmulrw.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/clmulrw.h @@ -1,4 +1,4 @@ -require_extension(EXT_XBITMANIP); +require_extension(EXT_XZBC); reg_t a = zext32(RS1), b = zext32(RS2), x = 0; for (int i = 0; i < 32; i++) if ((b >> i) & 1) diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/clmulw.h b/vendor/riscv/riscv-isa-sim/riscv/insns/clmulw.h index 83ecebb63..5bb753fe3 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/clmulw.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/clmulw.h @@ -1,4 +1,4 @@ -require_extension(EXT_XBITMANIP); +require_extension(EXT_XZBC); reg_t a = zext32(RS1), b = zext32(RS2), x = 0; for (int i = 0; i < 32; i++) if ((b >> i) & 1) diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/cm_jalt.h b/vendor/riscv/riscv-isa-sim/riscv/insns/cm_jalt.h new file mode 100644 index 000000000..be88dc401 --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/cm_jalt.h @@ -0,0 +1,23 @@ +require_extension(EXT_ZCMT); +STATE.jvt->verify_permissions(insn, false); +reg_t jvt = STATE.jvt->read(); +uint8_t mode = get_field(jvt, JVT_MODE); +reg_t base = jvt & JVT_BASE; +reg_t index = insn.rvc_index(); +reg_t target; +switch (mode) { +case 0: // jump table mode + if (xlen == 32) + target = MMU.fetch_jump_table(base + (index << 2)); + else // xlen = 64 + target = MMU.fetch_jump_table(base + (index << 3)); + + if (index >= 32) // cm.jalt + WRITE_REG(1, npc); + + set_pc(target & ~reg_t(1)); + break; +default: + require(0); + break; +} diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/cm_mva01s.h b/vendor/riscv/riscv-isa-sim/riscv/insns/cm_mva01s.h new file mode 100644 index 000000000..6504caef7 --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/cm_mva01s.h @@ -0,0 +1,3 @@ +require_extension(EXT_ZCMP); +WRITE_REG(X_A0, READ_REG(RVC_R1S)); +WRITE_REG(X_A1, READ_REG(RVC_R2S)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/cm_mvsa01.h b/vendor/riscv/riscv-isa-sim/riscv/insns/cm_mvsa01.h new file mode 100644 index 000000000..221489705 --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/cm_mvsa01.h @@ -0,0 +1,4 @@ +require_extension(EXT_ZCMP); +require(insn.rvc_r1sc() != insn.rvc_r2sc()); +WRITE_REG(RVC_R1S, READ_REG(X_A0)); +WRITE_REG(RVC_R2S, READ_REG(X_A1)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/cm_pop.h b/vendor/riscv/riscv-isa-sim/riscv/insns/cm_pop.h new file mode 100644 index 000000000..0563bf53d --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/cm_pop.h @@ -0,0 +1,17 @@ +require_zcmp_pushpop; + +const auto new_sp = SP + insn.zcmp_stack_adjustment(xlen); +auto addr = new_sp; + +for (int i = Sn(11); i >= 0; i--) { + if (insn.zcmp_regmask() & (1 << i)) { + addr -= xlen / 8; + + if (xlen == 32) + WRITE_REG(i, MMU.load(addr)); + else + WRITE_REG(i, MMU.load(addr)); + } +} + +WRITE_REG(X_SP, new_sp); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/cm_popret.h b/vendor/riscv/riscv-isa-sim/riscv/insns/cm_popret.h new file mode 100644 index 000000000..4873c029d --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/cm_popret.h @@ -0,0 +1,2 @@ +#include "cm_pop.h" +set_pc(RA); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/cm_popretz.h b/vendor/riscv/riscv-isa-sim/riscv/insns/cm_popretz.h new file mode 100644 index 000000000..104235161 --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/cm_popretz.h @@ -0,0 +1,2 @@ +#include "cm_popret.h" +WRITE_REG(X_A0, 0); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/cm_push.h b/vendor/riscv/riscv-isa-sim/riscv/insns/cm_push.h new file mode 100644 index 000000000..64accd4b5 --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/cm_push.h @@ -0,0 +1,17 @@ +require_zcmp_pushpop; + +const auto new_sp = SP - insn.zcmp_stack_adjustment(xlen); +auto addr = SP; + +for (int i = Sn(11); i >= 0; i--) { + if (insn.zcmp_regmask() & (1 << i)) { + addr -= xlen / 8; + + if (xlen == 32) + MMU.store(addr, READ_REG(i)); + else + MMU.store(addr, READ_REG(i)); + } +} + +WRITE_REG(X_SP, new_sp); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/cmix.h b/vendor/riscv/riscv-isa-sim/riscv/insns/cmix.h index 62f8d4b29..98eb0bca2 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/cmix.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/cmix.h @@ -1,2 +1,2 @@ -require_either_extension(EXT_ZBPBO, EXT_XBITMANIP); +require_either_extension(EXT_ZBPBO, EXT_XZBT); WRITE_RD((RS1 & RS2) | (RS3 & ~RS2)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/cmov.h b/vendor/riscv/riscv-isa-sim/riscv/insns/cmov.h index eef025f2f..c7551bc64 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/cmov.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/cmov.h @@ -1,2 +1,2 @@ -require_extension(EXT_XBITMANIP); +require_extension(EXT_XZBT); WRITE_RD(RS2 ? RS1 : RS3); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/crc32_b.h b/vendor/riscv/riscv-isa-sim/riscv/insns/crc32_b.h index 1297852a4..3111fe572 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/crc32_b.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/crc32_b.h @@ -1,4 +1,4 @@ -require_extension(EXT_XBITMANIP); +require_extension(EXT_XZBR); reg_t x = zext_xlen(RS1); for (int i = 0; i < 8; i++) x = (x >> 1) ^ (0xEDB88320 & ~((x&1)-1)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/crc32_d.h b/vendor/riscv/riscv-isa-sim/riscv/insns/crc32_d.h index 0bc08d221..7fd7a38f2 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/crc32_d.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/crc32_d.h @@ -1,5 +1,5 @@ require_rv64; -require_extension(EXT_XBITMANIP); +require_extension(EXT_XZBR); reg_t x = zext_xlen(RS1); for (int i = 0; i < 64; i++) x = (x >> 1) ^ (0xEDB88320 & ~((x&1)-1)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/crc32_h.h b/vendor/riscv/riscv-isa-sim/riscv/insns/crc32_h.h index 73e768385..5063fefd6 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/crc32_h.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/crc32_h.h @@ -1,4 +1,4 @@ -require_extension(EXT_XBITMANIP); +require_extension(EXT_XZBR); reg_t x = zext_xlen(RS1); for (int i = 0; i < 16; i++) x = (x >> 1) ^ (0xEDB88320 & ~((x&1)-1)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/crc32_w.h b/vendor/riscv/riscv-isa-sim/riscv/insns/crc32_w.h index 7b328f9d7..6e425ab8d 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/crc32_w.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/crc32_w.h @@ -1,4 +1,4 @@ -require_extension(EXT_XBITMANIP); +require_extension(EXT_XZBR); reg_t x = zext_xlen(RS1); for (int i = 0; i < 32; i++) x = (x >> 1) ^ (0xEDB88320 & ~((x&1)-1)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/crc32c_b.h b/vendor/riscv/riscv-isa-sim/riscv/insns/crc32c_b.h index 30312d8b6..d11b0dda8 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/crc32c_b.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/crc32c_b.h @@ -1,4 +1,4 @@ -require_extension(EXT_XBITMANIP); +require_extension(EXT_XZBR); reg_t x = zext_xlen(RS1); for (int i = 0; i < 8; i++) x = (x >> 1) ^ (0x82F63B78 & ~((x&1)-1)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/crc32c_d.h b/vendor/riscv/riscv-isa-sim/riscv/insns/crc32c_d.h index 0595087a6..81175fd9c 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/crc32c_d.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/crc32c_d.h @@ -1,5 +1,5 @@ require_rv64; -require_extension(EXT_XBITMANIP); +require_extension(EXT_XZBR); reg_t x = zext_xlen(RS1); for (int i = 0; i < 64; i++) x = (x >> 1) ^ (0x82F63B78 & ~((x&1)-1)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/crc32c_h.h b/vendor/riscv/riscv-isa-sim/riscv/insns/crc32c_h.h index 8e34ce2a6..ef5817d99 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/crc32c_h.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/crc32c_h.h @@ -1,4 +1,4 @@ -require_extension(EXT_XBITMANIP); +require_extension(EXT_XZBR); reg_t x = zext_xlen(RS1); for (int i = 0; i < 16; i++) x = (x >> 1) ^ (0x82F63B78 & ~((x&1)-1)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/crc32c_w.h b/vendor/riscv/riscv-isa-sim/riscv/insns/crc32c_w.h index c3ca1a849..879354029 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/crc32c_w.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/crc32c_w.h @@ -1,4 +1,4 @@ -require_extension(EXT_XBITMANIP); +require_extension(EXT_XZBR); reg_t x = zext_xlen(RS1); for (int i = 0; i < 32; i++) x = (x >> 1) ^ (0x82F63B78 & ~((x&1)-1)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/csrrc.h b/vendor/riscv/riscv-isa-sim/riscv/insns/csrrc.h index 37384b0e5..019a9ce4e 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/csrrc.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/csrrc.h @@ -2,7 +2,7 @@ bool write = insn.rs1() != 0; int csr = validate_csr(insn.csr(), write); reg_t old = p->get_csr(csr, insn, write); if (write) { - p->set_csr(csr, old & ~RS1); + p->put_csr(csr, old & ~RS1); } WRITE_RD(sext_xlen(old)); serialize(); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/csrrci.h b/vendor/riscv/riscv-isa-sim/riscv/insns/csrrci.h index ad40c8f4c..f02d32688 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/csrrci.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/csrrci.h @@ -2,7 +2,7 @@ bool write = insn.rs1() != 0; int csr = validate_csr(insn.csr(), write); reg_t old = p->get_csr(csr, insn, write); if (write) { - p->set_csr(csr, old & ~(reg_t)insn.rs1()); + p->put_csr(csr, old & ~(reg_t)insn.rs1()); } WRITE_RD(sext_xlen(old)); serialize(); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/csrrs.h b/vendor/riscv/riscv-isa-sim/riscv/insns/csrrs.h index 91fcc7a34..7632d1f40 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/csrrs.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/csrrs.h @@ -2,7 +2,7 @@ bool write = insn.rs1() != 0; int csr = validate_csr(insn.csr(), write); reg_t old = p->get_csr(csr, insn, write); if (write) { - p->set_csr(csr, old | RS1); + p->put_csr(csr, old | RS1); } WRITE_RD(sext_xlen(old)); serialize(); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/csrrsi.h b/vendor/riscv/riscv-isa-sim/riscv/insns/csrrsi.h index f348e570b..9acfcfcf7 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/csrrsi.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/csrrsi.h @@ -2,7 +2,7 @@ bool write = insn.rs1() != 0; int csr = validate_csr(insn.csr(), write); reg_t old = p->get_csr(csr, insn, write); if (write) { - p->set_csr(csr, old | insn.rs1()); + p->put_csr(csr, old | insn.rs1()); } WRITE_RD(sext_xlen(old)); serialize(); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/csrrw.h b/vendor/riscv/riscv-isa-sim/riscv/insns/csrrw.h index cc0c28dc9..e4c605bd8 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/csrrw.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/csrrw.h @@ -1,5 +1,5 @@ int csr = validate_csr(insn.csr(), true); reg_t old = p->get_csr(csr, insn, true); -p->set_csr(csr, RS1); +p->put_csr(csr, RS1); WRITE_RD(sext_xlen(old)); serialize(); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/csrrwi.h b/vendor/riscv/riscv-isa-sim/riscv/insns/csrrwi.h index 4d5d06468..77fec1543 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/csrrwi.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/csrrwi.h @@ -1,5 +1,5 @@ int csr = validate_csr(insn.csr(), true); reg_t old = p->get_csr(csr, insn, true); -p->set_csr(csr, insn.rs1()); +p->put_csr(csr, insn.rs1()); WRITE_RD(sext_xlen(old)); serialize(); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/czero_eqz.h b/vendor/riscv/riscv-isa-sim/riscv/insns/czero_eqz.h new file mode 100644 index 000000000..24062af9e --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/czero_eqz.h @@ -0,0 +1,2 @@ +require_extension(EXT_ZICOND); +WRITE_RD(RS2 == 0 ? 0 : RS1); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/czero_nez.h b/vendor/riscv/riscv-isa-sim/riscv/insns/czero_nez.h new file mode 100644 index 000000000..cd6c8af7c --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/czero_nez.h @@ -0,0 +1,2 @@ +require_extension(EXT_ZICOND); +WRITE_RD(RS2 != 0 ? 0 : RS1); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/div.h b/vendor/riscv/riscv-isa-sim/riscv/insns/div.h index 9cbe8d6b3..fb62437bb 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/div.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/div.h @@ -1,9 +1,9 @@ require_extension('M'); sreg_t lhs = sext_xlen(RS1); sreg_t rhs = sext_xlen(RS2); -if(rhs == 0) +if (rhs == 0) WRITE_RD(UINT64_MAX); -else if(lhs == INT64_MIN && rhs == -1) +else if (lhs == INT64_MIN && rhs == -1) WRITE_RD(lhs); else WRITE_RD(sext_xlen(lhs / rhs)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/divu.h b/vendor/riscv/riscv-isa-sim/riscv/insns/divu.h index 31d758560..ed0581862 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/divu.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/divu.h @@ -1,7 +1,7 @@ require_extension('M'); reg_t lhs = zext_xlen(RS1); reg_t rhs = zext_xlen(RS2); -if(rhs == 0) +if (rhs == 0) WRITE_RD(UINT64_MAX); else WRITE_RD(sext_xlen(lhs / rhs)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/divuw.h b/vendor/riscv/riscv-isa-sim/riscv/insns/divuw.h index e127619aa..bc7e9d2d3 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/divuw.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/divuw.h @@ -2,7 +2,7 @@ require_extension('M'); require_rv64; reg_t lhs = zext32(RS1); reg_t rhs = zext32(RS2); -if(rhs == 0) +if (rhs == 0) WRITE_RD(UINT64_MAX); else WRITE_RD(sext32(lhs / rhs)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/divw.h b/vendor/riscv/riscv-isa-sim/riscv/insns/divw.h index 11be17e4c..54409b07a 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/divw.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/divw.h @@ -2,7 +2,7 @@ require_extension('M'); require_rv64; sreg_t lhs = sext32(RS1); sreg_t rhs = sext32(RS2); -if(rhs == 0) +if (rhs == 0) WRITE_RD(UINT64_MAX); else WRITE_RD(sext32(lhs / rhs)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/dret.h b/vendor/riscv/riscv-isa-sim/riscv/insns/dret.h index 01a39923c..56ce25bce 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/dret.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/dret.h @@ -1,6 +1,8 @@ require(STATE.debug_mode); set_pc_and_serialize(STATE.dpc->read()); p->set_privilege(STATE.dcsr->prv); +if (STATE.prv < PRV_M) + STATE.mstatus->write(STATE.mstatus->read() & ~MSTATUS_MPRV); /* We're not in Debug Mode anymore. */ STATE.debug_mode = false; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/ebreak.h b/vendor/riscv/riscv-isa-sim/riscv/insns/ebreak.h index 9f3d44d92..227ab9352 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/ebreak.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/ebreak.h @@ -1 +1,8 @@ -throw trap_breakpoint(STATE.v, pc); +if (!STATE.debug_mode && + ((STATE.prv == PRV_M && STATE.dcsr->ebreakm) || + (STATE.prv == PRV_S && STATE.dcsr->ebreaks) || + (STATE.prv == PRV_U && STATE.dcsr->ebreaku))) { + throw trap_debug_mode(); +} else { + throw trap_breakpoint(STATE.v, pc); +} diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fadd_d.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fadd_d.h index 4a436e248..9bfff5fb9 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fadd_d.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fadd_d.h @@ -1,5 +1,5 @@ -require_extension('D'); +require_either_extension('D', EXT_ZDINX); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f64_add(f64(FRS1), f64(FRS2))); +WRITE_FRD_D(f64_add(FRS1_D, FRS2_D)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fadd_h.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fadd_h.h index 2b646ae77..f57e5fa79 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fadd_h.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fadd_h.h @@ -1,5 +1,5 @@ -require_extension(EXT_ZFH); +require_either_extension(EXT_ZFH, EXT_ZHINX); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f16_add(f16(FRS1), f16(FRS2))); +WRITE_FRD_H(f16_add(FRS1_H, FRS2_H)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fadd_s.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fadd_s.h index cc18d58cd..7a40b1bf1 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fadd_s.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fadd_s.h @@ -1,5 +1,5 @@ -require_extension('F'); +require_either_extension('F', EXT_ZFINX); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f32_add(f32(FRS1), f32(FRS2))); +WRITE_FRD_F(f32_add(FRS1_F, FRS2_F)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fclass_d.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fclass_d.h index 9456123d3..a35506298 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fclass_d.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fclass_d.h @@ -1,3 +1,3 @@ -require_extension('D'); +require_either_extension('D', EXT_ZDINX); require_fp; -WRITE_RD(f64_classify(f64(FRS1))); +WRITE_RD(f64_classify(FRS1_D)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fclass_h.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fclass_h.h index 066a2d24d..2638ac8d3 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fclass_h.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fclass_h.h @@ -1,3 +1,3 @@ -require_extension(EXT_ZFH); +require_either_extension(EXT_ZFH, EXT_ZHINX); require_fp; -WRITE_RD(f16_classify(f16(FRS1))); +WRITE_RD(f16_classify(FRS1_H)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fclass_s.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fclass_s.h index a392db881..3d529adc8 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fclass_s.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fclass_s.h @@ -1,3 +1,3 @@ -require_extension('F'); +require_either_extension('F', EXT_ZFINX); require_fp; -WRITE_RD(f32_classify(f32(FRS1))); +WRITE_RD(f32_classify(FRS1_F)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_d_h.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_d_h.h index 04e9ff4e2..061a2710d 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_d_h.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_d_h.h @@ -1,6 +1,6 @@ -require_extension(EXT_ZFHMIN); -require_extension('D'); +require_either_extension(EXT_ZFHMIN, EXT_ZHINXMIN); +require_either_extension('D', EXT_ZDINX); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f16_to_f64(f16(FRS1))); +WRITE_FRD_D(f16_to_f64(FRS1_H)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_d_l.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_d_l.h index 08716cffe..7788f1f0b 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_d_l.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_d_l.h @@ -1,6 +1,6 @@ -require_extension('D'); +require_either_extension('D', EXT_ZDINX); require_rv64; require_fp; softfloat_roundingMode = RM; -WRITE_FRD(i64_to_f64(RS1)); +WRITE_FRD_D(i64_to_f64(RS1)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_d_lu.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_d_lu.h index 306d7fedd..edb694f7a 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_d_lu.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_d_lu.h @@ -1,6 +1,6 @@ -require_extension('D'); +require_either_extension('D', EXT_ZDINX); require_rv64; require_fp; softfloat_roundingMode = RM; -WRITE_FRD(ui64_to_f64(RS1)); +WRITE_FRD_D(ui64_to_f64(RS1)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_d_s.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_d_s.h index 5f805b061..8039e9465 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_d_s.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_d_s.h @@ -1,5 +1,5 @@ -require_extension('D'); +require_either_extension('D', EXT_ZDINX); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f32_to_f64(f32(FRS1))); +WRITE_FRD_D(f32_to_f64(FRS1_F)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_d_w.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_d_w.h index 4c4861c15..e3375faf6 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_d_w.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_d_w.h @@ -1,5 +1,5 @@ -require_extension('D'); +require_either_extension('D', EXT_ZDINX); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(i32_to_f64((int32_t)RS1)); +WRITE_FRD_D(i32_to_f64((int32_t)RS1)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_d_wu.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_d_wu.h index 1dbf218a1..d903561ff 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_d_wu.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_d_wu.h @@ -1,5 +1,5 @@ -require_extension('D'); +require_either_extension('D', EXT_ZDINX); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(ui32_to_f64((uint32_t)RS1)); +WRITE_FRD_D(ui32_to_f64((uint32_t)RS1)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_h_d.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_h_d.h index e9987b7f3..e06b1a555 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_h_d.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_h_d.h @@ -1,6 +1,6 @@ -require_extension(EXT_ZFHMIN); -require_extension('D'); +require_either_extension(EXT_ZFHMIN, EXT_ZHINXMIN); +require_either_extension('D', EXT_ZDINX); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f64_to_f16(f64(FRS1))); +WRITE_FRD_H(f64_to_f16(FRS1_D)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_h_l.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_h_l.h index 39178c2fd..31e8a1e4f 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_h_l.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_h_l.h @@ -1,6 +1,6 @@ -require_extension(EXT_ZFH); +require_either_extension(EXT_ZFH, EXT_ZHINX); require_rv64; require_fp; softfloat_roundingMode = RM; -WRITE_FRD(i64_to_f16(RS1)); +WRITE_FRD_H(i64_to_f16(RS1)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_h_lu.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_h_lu.h index a872c4809..189b1601a 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_h_lu.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_h_lu.h @@ -1,6 +1,6 @@ -require_extension(EXT_ZFH); +require_either_extension(EXT_ZFH, EXT_ZHINX); require_rv64; require_fp; softfloat_roundingMode = RM; -WRITE_FRD(ui64_to_f16(RS1)); +WRITE_FRD_H(ui64_to_f16(RS1)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_h_s.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_h_s.h index ce39d8148..57ba0059d 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_h_s.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_h_s.h @@ -1,5 +1,5 @@ -require_extension(EXT_ZFHMIN); +require_either_extension(EXT_ZFHMIN, EXT_ZHINXMIN); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f32_to_f16(f32(FRS1))); +WRITE_FRD_H(f32_to_f16(FRS1_F)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_h_w.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_h_w.h index c08245451..de4cbe56c 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_h_w.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_h_w.h @@ -1,5 +1,5 @@ -require_extension(EXT_ZFH); +require_either_extension(EXT_ZFH, EXT_ZHINX); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(i32_to_f16((int32_t)RS1)); +WRITE_FRD_H(i32_to_f16((int32_t)RS1)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_h_wu.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_h_wu.h index 9f2f5f6a7..230c354fe 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_h_wu.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_h_wu.h @@ -1,5 +1,5 @@ -require_extension(EXT_ZFH); +require_either_extension(EXT_ZFH, EXT_ZHINX); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(ui32_to_f16((uint32_t)RS1)); +WRITE_FRD_H(ui32_to_f16((uint32_t)RS1)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_l_d.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_l_d.h index c09e6c447..f2374d269 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_l_d.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_l_d.h @@ -1,6 +1,6 @@ -require_extension('D'); +require_either_extension('D', EXT_ZDINX); require_rv64; require_fp; softfloat_roundingMode = RM; -WRITE_RD(f64_to_i64(f64(FRS1), RM, true)); +WRITE_RD(f64_to_i64(FRS1_D, RM, true)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_l_h.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_l_h.h index 5a1fea850..3b630276e 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_l_h.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_l_h.h @@ -1,6 +1,6 @@ -require_extension(EXT_ZFH); +require_either_extension(EXT_ZFH, EXT_ZHINX); require_rv64; require_fp; softfloat_roundingMode = RM; -WRITE_RD(f16_to_i64(f16(FRS1), RM, true)); +WRITE_RD(f16_to_i64(FRS1_H, RM, true)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_l_s.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_l_s.h index 267e0eb8c..d121a65c3 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_l_s.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_l_s.h @@ -1,6 +1,6 @@ -require_extension('F'); +require_either_extension('F', EXT_ZFINX); require_rv64; require_fp; softfloat_roundingMode = RM; -WRITE_RD(f32_to_i64(f32(FRS1), RM, true)); +WRITE_RD(f32_to_i64(FRS1_F, RM, true)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_lu_d.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_lu_d.h index 3a021204c..939bc0e18 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_lu_d.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_lu_d.h @@ -1,6 +1,6 @@ -require_extension('D'); +require_either_extension('D', EXT_ZDINX); require_rv64; require_fp; softfloat_roundingMode = RM; -WRITE_RD(f64_to_ui64(f64(FRS1), RM, true)); +WRITE_RD(f64_to_ui64(FRS1_D, RM, true)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_lu_h.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_lu_h.h index f1454c3e9..d27f175e2 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_lu_h.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_lu_h.h @@ -1,6 +1,6 @@ -require_extension(EXT_ZFH); +require_either_extension(EXT_ZFH, EXT_ZHINX); require_rv64; require_fp; softfloat_roundingMode = RM; -WRITE_RD(f16_to_ui64(f16(FRS1), RM, true)); +WRITE_RD(f16_to_ui64(FRS1_H, RM, true)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_lu_s.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_lu_s.h index 94115a3f3..69c95ef05 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_lu_s.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_lu_s.h @@ -1,6 +1,6 @@ -require_extension('F'); +require_either_extension('F', EXT_ZFINX); require_rv64; require_fp; softfloat_roundingMode = RM; -WRITE_RD(f32_to_ui64(f32(FRS1), RM, true)); +WRITE_RD(f32_to_ui64(FRS1_F, RM, true)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_s_d.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_s_d.h index 40333359f..f3cd26e9a 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_s_d.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_s_d.h @@ -1,5 +1,5 @@ -require_extension('D'); +require_either_extension('D', EXT_ZDINX); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f64_to_f32(f64(FRS1))); +WRITE_FRD_F(f64_to_f32(FRS1_D)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_s_h.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_s_h.h index 22cdd728d..346440a97 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_s_h.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_s_h.h @@ -1,5 +1,5 @@ -require_extension(EXT_ZFHMIN); +require_either_extension(EXT_ZFHMIN, EXT_ZHINXMIN); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f16_to_f32(f16(FRS1))); +WRITE_FRD_F(f16_to_f32(FRS1_H)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_s_l.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_s_l.h index 9abcc8050..1d096d2ca 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_s_l.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_s_l.h @@ -1,6 +1,6 @@ -require_extension('F'); +require_either_extension('F', EXT_ZFINX); require_rv64; require_fp; softfloat_roundingMode = RM; -WRITE_FRD(i64_to_f32(RS1)); +WRITE_FRD_F(i64_to_f32(RS1)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_s_lu.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_s_lu.h index 70c676edf..e4e84cf42 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_s_lu.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_s_lu.h @@ -1,6 +1,6 @@ -require_extension('F'); +require_either_extension('F', EXT_ZFINX); require_rv64; require_fp; softfloat_roundingMode = RM; -WRITE_FRD(ui64_to_f32(RS1)); +WRITE_FRD_F(ui64_to_f32(RS1)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_s_w.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_s_w.h index 1ddabd87c..75c87db50 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_s_w.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_s_w.h @@ -1,5 +1,5 @@ -require_extension('F'); +require_either_extension('F', EXT_ZFINX); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(i32_to_f32((int32_t)RS1)); +WRITE_FRD_F(i32_to_f32((int32_t)RS1)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_s_wu.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_s_wu.h index c1394c3fd..ec90fad93 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_s_wu.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_s_wu.h @@ -1,5 +1,5 @@ -require_extension('F'); +require_either_extension('F', EXT_ZFINX); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(ui32_to_f32((uint32_t)RS1)); +WRITE_FRD_F(ui32_to_f32((uint32_t)RS1)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_w_d.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_w_d.h index 28eb2456d..a839f4ba8 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_w_d.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_w_d.h @@ -1,5 +1,5 @@ -require_extension('D'); +require_either_extension('D', EXT_ZDINX); require_fp; softfloat_roundingMode = RM; -WRITE_RD(sext32(f64_to_i32(f64(FRS1), RM, true))); +WRITE_RD(sext32(f64_to_i32(FRS1_D, RM, true))); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_w_h.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_w_h.h index fe8bb48fb..97e49a554 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_w_h.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_w_h.h @@ -1,5 +1,5 @@ -require_extension(EXT_ZFH); +require_either_extension(EXT_ZFH, EXT_ZHINX); require_fp; softfloat_roundingMode = RM; -WRITE_RD(sext32(f16_to_i32(f16(FRS1), RM, true))); +WRITE_RD(sext32(f16_to_i32(FRS1_H, RM, true))); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_w_s.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_w_s.h index d30f1b440..6aeb5101a 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_w_s.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_w_s.h @@ -1,5 +1,5 @@ -require_extension('F'); +require_either_extension('F', EXT_ZFINX); require_fp; softfloat_roundingMode = RM; -WRITE_RD(sext32(f32_to_i32(f32(FRS1), RM, true))); +WRITE_RD(sext32(f32_to_i32(FRS1_F, RM, true))); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_wu_d.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_wu_d.h index 5cdc004c8..906f003fb 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_wu_d.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_wu_d.h @@ -1,5 +1,5 @@ -require_extension('D'); +require_either_extension('D', EXT_ZDINX); require_fp; softfloat_roundingMode = RM; -WRITE_RD(sext32(f64_to_ui32(f64(FRS1), RM, true))); +WRITE_RD(sext32(f64_to_ui32(FRS1_D, RM, true))); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_wu_h.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_wu_h.h index bf6648d3c..ce111438b 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_wu_h.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_wu_h.h @@ -1,5 +1,5 @@ -require_extension(EXT_ZFH); +require_either_extension(EXT_ZFH, EXT_ZHINX); require_fp; softfloat_roundingMode = RM; -WRITE_RD(sext32(f16_to_ui32(f16(FRS1), RM, true))); +WRITE_RD(sext32(f16_to_ui32(FRS1_H, RM, true))); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_wu_s.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_wu_s.h index 034d68162..a8b845577 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_wu_s.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvt_wu_s.h @@ -1,5 +1,5 @@ -require_extension('F'); +require_either_extension('F', EXT_ZFINX); require_fp; softfloat_roundingMode = RM; -WRITE_RD(sext32(f32_to_ui32(f32(FRS1), RM, true))); +WRITE_RD(sext32(f32_to_ui32(FRS1_F, RM, true))); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fcvtmod_w_d.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvtmod_w_d.h new file mode 100644 index 000000000..89b9b9522 --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fcvtmod_w_d.h @@ -0,0 +1,58 @@ +require_extension('D'); +require_extension(EXT_ZFA); +require_fp; +uint64_t a = FRS1_D.v; + +uint32_t sign = signF64UI(a); +uint32_t exp = expF64UI(a); +uint64_t frac = fracF64UI(a); + +bool inexact = false; +bool invalid = false; + +if (exp == 0) { + inexact = (frac != 0); + frac = 0; +} else if (exp == 0x7ff) { + /* inf or NaN */ + invalid = true; + frac = 0; +} else { + int true_exp = exp - 1023; + int shift = true_exp - 52; + + /* Restore implicit bit. */ + frac |= 1ull << 52; + + /* Shift the fraction into place. */ + if (shift >= 64) { + /* The fraction is shifted out entirely. */ + frac = 0; + } else if ((shift >= 0) && (shift < 64)) { + /* The number is so large we must shift the fraction left. */ + frac <<= shift; + } else if ((shift > -64) && (shift < 0)) { + /* Normal case -- shift right and notice if bits shift out. */ + inexact = (frac << (64 + shift)) != 0; + frac >>= -shift; + } else { + /* The fraction is shifted out entirely. */ + frac = 0; + } + + /* Notice overflow or inexact exceptions. */ + if (true_exp > 31 || frac > (sign ? 0x80000000ull : 0x7fffffff)) { + /* Overflow, for which this operation raises invalid. */ + invalid = true; + } + + /* Honor the sign. */ + if (sign) { + frac = -frac; + } +} + +WRITE_RD(sext32(frac)); +STATE.fflags->write(STATE.fflags->read() | + (inexact ? softfloat_flag_inexact : 0) | + (invalid ? softfloat_flag_invalid : 0)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fdiv_d.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fdiv_d.h index ae7911ae9..990afca02 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fdiv_d.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fdiv_d.h @@ -1,5 +1,5 @@ -require_extension('D'); +require_either_extension('D', EXT_ZDINX); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f64_div(f64(FRS1), f64(FRS2))); +WRITE_FRD_D(f64_div(FRS1_D, FRS2_D)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fdiv_h.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fdiv_h.h index a169eae83..91c518b4e 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fdiv_h.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fdiv_h.h @@ -1,5 +1,5 @@ -require_extension(EXT_ZFH); +require_either_extension(EXT_ZFH, EXT_ZHINX); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f16_div(f16(FRS1), f16(FRS2))); +WRITE_FRD_H(f16_div(FRS1_H, FRS2_H)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fdiv_s.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fdiv_s.h index c74ff0415..180b41dd2 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fdiv_s.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fdiv_s.h @@ -1,5 +1,5 @@ -require_extension('F'); +require_either_extension('F', EXT_ZFINX); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f32_div(f32(FRS1), f32(FRS2))); +WRITE_FRD_F(f32_div(FRS1_F, FRS2_F)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/feq_d.h b/vendor/riscv/riscv-isa-sim/riscv/insns/feq_d.h index 541ed5bbc..9585bad70 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/feq_d.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/feq_d.h @@ -1,4 +1,4 @@ -require_extension('D'); +require_either_extension('D', EXT_ZDINX); require_fp; -WRITE_RD(f64_eq(f64(FRS1), f64(FRS2))); +WRITE_RD(f64_eq(FRS1_D, FRS2_D)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/feq_h.h b/vendor/riscv/riscv-isa-sim/riscv/insns/feq_h.h index 47e75a5b9..5988db900 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/feq_h.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/feq_h.h @@ -1,4 +1,4 @@ -require_extension(EXT_ZFH); +require_either_extension(EXT_ZFH, EXT_ZHINX); require_fp; -WRITE_RD(f16_eq(f16(FRS1), f16(FRS2))); +WRITE_RD(f16_eq(FRS1_H, FRS2_H)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/feq_s.h b/vendor/riscv/riscv-isa-sim/riscv/insns/feq_s.h index 489bea693..97b57c2ed 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/feq_s.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/feq_s.h @@ -1,4 +1,4 @@ -require_extension('F'); +require_either_extension('F', EXT_ZFINX); require_fp; -WRITE_RD(f32_eq(f32(FRS1), f32(FRS2))); +WRITE_RD(f32_eq(FRS1_F, FRS2_F)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fld.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fld.h index 4dea1d47e..bbe859fe9 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fld.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fld.h @@ -1,3 +1,3 @@ require_extension('D'); require_fp; -WRITE_FRD(f64(MMU.load_uint64(RS1 + insn.i_imm()))); +WRITE_FRD(f64(MMU.load(RS1 + insn.i_imm()))); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fle_d.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fle_d.h index 419a36fc1..17b49320e 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fle_d.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fle_d.h @@ -1,4 +1,4 @@ -require_extension('D'); +require_either_extension('D', EXT_ZDINX); require_fp; -WRITE_RD(f64_le(f64(FRS1), f64(FRS2))); +WRITE_RD(f64_le(FRS1_D, FRS2_D)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fle_h.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fle_h.h index 9fc596853..31ed8a750 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fle_h.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fle_h.h @@ -1,4 +1,4 @@ -require_extension(EXT_ZFH); +require_either_extension(EXT_ZFH, EXT_ZHINX); require_fp; -WRITE_RD(f16_le(f16(FRS1), f16(FRS2))); +WRITE_RD(f16_le(FRS1_H, FRS2_H)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fle_s.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fle_s.h index 5c0124ef2..e26f05563 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fle_s.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fle_s.h @@ -1,4 +1,4 @@ -require_extension('F'); +require_either_extension('F', EXT_ZFINX); require_fp; -WRITE_RD(f32_le(f32(FRS1), f32(FRS2))); +WRITE_RD(f32_le(FRS1_F, FRS2_F)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fleq_d.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fleq_d.h new file mode 100644 index 000000000..762e14703 --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fleq_d.h @@ -0,0 +1,4 @@ +require_extension('D'); +require_extension(EXT_ZFA); +require_fp; +WRITE_RD(f64_le_quiet(FRS1_D, FRS2_D)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fleq_h.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fleq_h.h new file mode 100644 index 000000000..7e6db59ae --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fleq_h.h @@ -0,0 +1,4 @@ +require_extension(EXT_ZFH); +require_extension(EXT_ZFA); +require_fp; +WRITE_RD(f16_le_quiet(FRS1_H, FRS2_H)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fleq_q.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fleq_q.h new file mode 100644 index 000000000..8533d11d1 --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fleq_q.h @@ -0,0 +1,4 @@ +require_extension('Q'); +require_extension(EXT_ZFA); +require_fp; +WRITE_RD(f128_le_quiet(f128(FRS1), f128(FRS2))); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fleq_s.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fleq_s.h new file mode 100644 index 000000000..8c0a90944 --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fleq_s.h @@ -0,0 +1,4 @@ +require_extension('F'); +require_extension(EXT_ZFA); +require_fp; +WRITE_RD(f32_le_quiet(FRS1_F, FRS2_F)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/flh.h b/vendor/riscv/riscv-isa-sim/riscv/insns/flh.h index bdb22d3ef..befff2cd3 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/flh.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/flh.h @@ -1,3 +1,3 @@ require_extension(EXT_ZFHMIN); require_fp; -WRITE_FRD(f16(MMU.load_uint16(RS1 + insn.i_imm()))); +WRITE_FRD(f16(MMU.load(RS1 + insn.i_imm()))); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fli_d.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fli_d.h new file mode 100644 index 000000000..090e88c72 --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fli_d.h @@ -0,0 +1,40 @@ +require_extension('D'); +require_extension(EXT_ZFA); +require_fp; +{ + const uint64_t bits[32] = { + [0b00000] = 0xbff0000000000000ull, /* -1.0 */ + [0b00001] = 0x0010000000000000ull, /* minimum positive normal */ + [0b00010] = 0x3ef0000000000000ull, /* 1.0 * 2^-16 */ + [0b00011] = 0x3f00000000000000ull, /* 1.0 * 2^-15 */ + [0b00100] = 0x3f70000000000000ull, /* 1.0 * 2^-8 */ + [0b00101] = 0x3f80000000000000ull, /* 1.0 * 2^-7 */ + [0b00110] = 0x3fb0000000000000ull, /* 1.0 * 2^-4 */ + [0b00111] = 0x3fc0000000000000ull, /* 1.0 * 2^-3 */ + [0b01000] = 0x3fd0000000000000ull, /* 0.25 */ + [0b01001] = 0x3fd4000000000000ull, /* 0.3125 */ + [0b01010] = 0x3fd8000000000000ull, /* 0.375 */ + [0b01011] = 0x3fdc000000000000ull, /* 0.4375 */ + [0b01100] = 0x3fe0000000000000ull, /* 0.5 */ + [0b01101] = 0x3fe4000000000000ull, /* 0.625 */ + [0b01110] = 0x3fe8000000000000ull, /* 0.75 */ + [0b01111] = 0x3fec000000000000ull, /* 0.875 */ + [0b10000] = 0x3ff0000000000000ull, /* 1.0 */ + [0b10001] = 0x3ff4000000000000ull, /* 1.25 */ + [0b10010] = 0x3ff8000000000000ull, /* 1.5 */ + [0b10011] = 0x3ffc000000000000ull, /* 1.75 */ + [0b10100] = 0x4000000000000000ull, /* 2.0 */ + [0b10101] = 0x4004000000000000ull, /* 2.5 */ + [0b10110] = 0x4008000000000000ull, /* 3 */ + [0b10111] = 0x4010000000000000ull, /* 4 */ + [0b11000] = 0x4020000000000000ull, /* 8 */ + [0b11001] = 0x4030000000000000ull, /* 16 */ + [0b11010] = 0x4060000000000000ull, /* 2^7 */ + [0b11011] = 0x4070000000000000ull, /* 2^8 */ + [0b11100] = 0x40e0000000000000ull, /* 2^15 */ + [0b11101] = 0x40f0000000000000ull, /* 2^16 */ + [0b11110] = 0x7ff0000000000000ull, /* +inf */ + [0b11111] = defaultNaNF64UI + }; + WRITE_FRD_D(f64(bits[insn.rs1()])); +} diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fli_h.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fli_h.h new file mode 100644 index 000000000..ddf41a9d3 --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fli_h.h @@ -0,0 +1,40 @@ +require_extension(EXT_ZFH); +require_extension(EXT_ZFA); +require_fp; +{ + static const uint16_t bits[32] = { + [0b00000] = 0xbc00, /* -1.0 */ + [0b00001] = 0x0400, /* minimum positive normal */ + [0b00010] = 0x0100, /* 1.0 * 2^-16 */ + [0b00011] = 0x0200, /* 1.0 * 2^-15 */ + [0b00100] = 0x1c00, /* 1.0 * 2^-8 */ + [0b00101] = 0x2000, /* 1.0 * 2^-7 */ + [0b00110] = 0x2c00, /* 1.0 * 2^-4 */ + [0b00111] = 0x3000, /* 1.0 * 2^-3 */ + [0b01000] = 0x3400, /* 0.25 */ + [0b01001] = 0x3500, /* 0.3125 */ + [0b01010] = 0x3600, /* 0.375 */ + [0b01011] = 0x3700, /* 0.4375 */ + [0b01100] = 0x3800, /* 0.5 */ + [0b01101] = 0x3900, /* 0.625 */ + [0b01110] = 0x3a00, /* 0.75 */ + [0b01111] = 0x3b00, /* 0.875 */ + [0b10000] = 0x3c00, /* 1.0 */ + [0b10001] = 0x3d00, /* 1.25 */ + [0b10010] = 0x3e00, /* 1.5 */ + [0b10011] = 0x3f00, /* 1.75 */ + [0b10100] = 0x4000, /* 2.0 */ + [0b10101] = 0x4100, /* 2.5 */ + [0b10110] = 0x4200, /* 3 */ + [0b10111] = 0x4400, /* 4 */ + [0b11000] = 0x4800, /* 8 */ + [0b11001] = 0x4c00, /* 16 */ + [0b11010] = 0x5800, /* 2^7 */ + [0b11011] = 0x5c00, /* 2^8 */ + [0b11100] = 0x7800, /* 2^15 */ + [0b11101] = 0x7c00, /* +inf (2^16 is not expressible) */ + [0b11110] = 0x7c00, /* +inf */ + [0b11111] = defaultNaNF16UI + }; + WRITE_FRD_H(f16(bits[insn.rs1()])); +} diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fli_q.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fli_q.h new file mode 100644 index 000000000..7ba569bf0 --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fli_q.h @@ -0,0 +1,46 @@ +require_extension('D'); +require_extension(EXT_ZFA); +require_fp; +{ + const uint64_t bits[32] = { + [0b00000] = 0xBFFF000000000000ull, /* -1.0 */ + [0b00001] = 0x0001000000000000ull, /* minimum positive normal */ + [0b00010] = 0x3FEF000000000000ull, /* 1.0 * 2^-16 */ + [0b00011] = 0x3FF0000000000000ull, /* 1.0 * 2^-15 */ + [0b00100] = 0x3FF7000000000000ull, /* 1.0 * 2^-8 */ + [0b00101] = 0x3FF8000000000000ull, /* 1.0 * 2^-7 */ + [0b00110] = 0x3FFB000000000000ull, /* 1.0 * 2^-4 */ + [0b00111] = 0x3FF9000000000000ull, /* 1.0 * 2^-3 */ + [0b01000] = 0x3FFD000000000000ull, /* 0.25 */ + [0b01001] = 0x3FFD400000000000ull, /* 0.3125 */ + [0b01010] = 0x3FFD800000000000ull, /* 0.375 */ + [0b01011] = 0x3FFDC00000000000ull, /* 0.4375 */ + [0b01100] = 0x3FFE000000000000ull, /* 0.5 */ + [0b01101] = 0x3FFE400000000000ull, /* 0.625 */ + [0b01110] = 0x3FFE800000000000ull, /* 0.75 */ + [0b01111] = 0x3FFEC00000000000ull, /* 0.875 */ + [0b10000] = 0x3FFF000000000000ull, /* 1.0 */ + [0b10001] = 0x3FFF400000000000ull, /* 1.25 */ + [0b10010] = 0x3FFFC00000000000ull, /* 1.5 */ + [0b10011] = 0x4000000000000000ull, /* 1.75 */ + [0b10100] = 0x4000400000000000ull, /* 2.0 */ + [0b10101] = 0x4000800000000000ull, /* 2.5 */ + [0b10110] = 0x4001000000000000ull, /* 3 */ + [0b10111] = 0x4002000000000000ull, /* 4 */ + [0b11000] = 0x4003000000000000ull, /* 8 */ + [0b11001] = 0x400D000000000000ull, /* 16 */ + [0b11010] = 0x4006000000000000ull, /* 2^7 */ + [0b11011] = 0x4007000000000000ull, /* 2^8 */ + [0b11100] = 0x400E000000000000ull, /* 2^15 */ + [0b11101] = 0x400F000000000000ull, /* 2^16 */ + [0b11110] = 0x7FFF000000000000ull, /* +inf */ + [0b11111] = defaultNaNF128UI64 + }; + + static_assert(defaultNaNF128UI0 == 0, "LSBs of quad-precision NaN must be zero"); + + ui128_f128 ui; + ui.ui.v64 = bits[insn.rs1()]; + ui.ui.v0 = 0; + WRITE_FRD(f128(ui.f)); +} diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fli_s.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fli_s.h new file mode 100644 index 000000000..e03b3b7f1 --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fli_s.h @@ -0,0 +1,40 @@ +require_extension('F'); +require_extension(EXT_ZFA); +require_fp; +{ + const uint32_t bits[32] = { + [0b00000] = 0xbf800000, /* -1.0 */ + [0b00001] = 0x00800000, /* minimum positive normal */ + [0b00010] = 0x37800000, /* 1.0 * 2^-16 */ + [0b00011] = 0x38000000, /* 1.0 * 2^-15 */ + [0b00100] = 0x3b800000, /* 1.0 * 2^-8 */ + [0b00101] = 0x3c000000, /* 1.0 * 2^-7 */ + [0b00110] = 0x3d800000, /* 1.0 * 2^-4 */ + [0b00111] = 0x3e000000, /* 1.0 * 2^-3 */ + [0b01000] = 0x3e800000, /* 0.25 */ + [0b01001] = 0x3ea00000, /* 0.3125 */ + [0b01010] = 0x3ec00000, /* 0.375 */ + [0b01011] = 0x3ee00000, /* 0.4375 */ + [0b01100] = 0x3f000000, /* 0.5 */ + [0b01101] = 0x3f200000, /* 0.625 */ + [0b01110] = 0x3f400000, /* 0.75 */ + [0b01111] = 0x3f600000, /* 0.875 */ + [0b10000] = 0x3f800000, /* 1.0 */ + [0b10001] = 0x3fa00000, /* 1.25 */ + [0b10010] = 0x3fc00000, /* 1.5 */ + [0b10011] = 0x3fe00000, /* 1.75 */ + [0b10100] = 0x40000000, /* 2.0 */ + [0b10101] = 0x40200000, /* 2.5 */ + [0b10110] = 0x40400000, /* 3 */ + [0b10111] = 0x40800000, /* 4 */ + [0b11000] = 0x41000000, /* 8 */ + [0b11001] = 0x41800000, /* 16 */ + [0b11010] = 0x43000000, /* 2^7 */ + [0b11011] = 0x43800000, /* 2^8 */ + [0b11100] = 0x47000000, /* 2^15 */ + [0b11101] = 0x47800000, /* 2^16 */ + [0b11110] = 0x7f800000, /* +inf */ + [0b11111] = defaultNaNF32UI + }; + WRITE_FRD_F(f32(bits[insn.rs1()])); +} diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/flt_d.h b/vendor/riscv/riscv-isa-sim/riscv/insns/flt_d.h index 7176a961d..5fb057242 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/flt_d.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/flt_d.h @@ -1,4 +1,4 @@ -require_extension('D'); +require_either_extension('D', EXT_ZDINX); require_fp; -WRITE_RD(f64_lt(f64(FRS1), f64(FRS2))); +WRITE_RD(f64_lt(FRS1_D, FRS2_D)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/flt_h.h b/vendor/riscv/riscv-isa-sim/riscv/insns/flt_h.h index f516a38a6..dd6bc79fd 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/flt_h.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/flt_h.h @@ -1,4 +1,4 @@ -require_extension(EXT_ZFH); +require_either_extension(EXT_ZFH, EXT_ZHINX); require_fp; -WRITE_RD(f16_lt(f16(FRS1), f16(FRS2))); +WRITE_RD(f16_lt(FRS1_H, FRS2_H)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/flt_s.h b/vendor/riscv/riscv-isa-sim/riscv/insns/flt_s.h index 40acc34b9..2f50ed6c3 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/flt_s.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/flt_s.h @@ -1,4 +1,4 @@ -require_extension('F'); +require_either_extension('F', EXT_ZFINX); require_fp; -WRITE_RD(f32_lt(f32(FRS1), f32(FRS2))); +WRITE_RD(f32_lt(FRS1_F, FRS2_F)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fltq_d.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fltq_d.h new file mode 100644 index 000000000..c7ec9f112 --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fltq_d.h @@ -0,0 +1,4 @@ +require_extension('D'); +require_extension(EXT_ZFA); +require_fp; +WRITE_RD(f64_lt_quiet(FRS1_D, FRS2_D)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fltq_h.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fltq_h.h new file mode 100644 index 000000000..84d880a63 --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fltq_h.h @@ -0,0 +1,4 @@ +require_extension(EXT_ZFH); +require_extension(EXT_ZFA); +require_fp; +WRITE_RD(f16_lt_quiet(FRS1_H, FRS2_H)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fltq_q.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fltq_q.h new file mode 100644 index 000000000..a65ca769b --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fltq_q.h @@ -0,0 +1,4 @@ +require_extension('Q'); +require_extension(EXT_ZFA); +require_fp; +WRITE_RD(f128_lt_quiet(f128(FRS1), f128(FRS2))); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fltq_s.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fltq_s.h new file mode 100644 index 000000000..1ee09837b --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fltq_s.h @@ -0,0 +1,4 @@ +require_extension('F'); +require_extension(EXT_ZFA); +require_fp; +WRITE_RD(f32_lt_quiet(FRS1_F, FRS2_F)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/flw.h b/vendor/riscv/riscv-isa-sim/riscv/insns/flw.h index 612975444..c57306a4f 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/flw.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/flw.h @@ -1,3 +1,3 @@ require_extension('F'); require_fp; -WRITE_FRD(f32(MMU.load_uint32(RS1 + insn.i_imm()))); +WRITE_FRD(f32(MMU.load(RS1 + insn.i_imm()))); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fmadd_d.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fmadd_d.h index ab22bebbf..07a8b255b 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fmadd_d.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fmadd_d.h @@ -1,5 +1,5 @@ -require_extension('D'); +require_either_extension('D', EXT_ZDINX); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f64_mulAdd(f64(FRS1), f64(FRS2), f64(FRS3))); +WRITE_FRD_D(f64_mulAdd(FRS1_D, FRS2_D, FRS3_D)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fmadd_h.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fmadd_h.h index 6551de5e3..5428897a9 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fmadd_h.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fmadd_h.h @@ -1,5 +1,5 @@ -require_extension(EXT_ZFH); +require_either_extension(EXT_ZFH, EXT_ZHINX); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f16_mulAdd(f16(FRS1), f16(FRS2), f16(FRS3))); +WRITE_FRD_H(f16_mulAdd(FRS1_H, FRS2_H, FRS3_H)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fmadd_s.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fmadd_s.h index e919190ca..5a72cf81b 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fmadd_s.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fmadd_s.h @@ -1,5 +1,5 @@ -require_extension('F'); +require_either_extension('F', EXT_ZFINX); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f32_mulAdd(f32(FRS1), f32(FRS2), f32(FRS3))); +WRITE_FRD_F(f32_mulAdd(FRS1_F, FRS2_F, FRS3_F)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fmax_d.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fmax_d.h index 11491f54b..3e05b7e60 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fmax_d.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fmax_d.h @@ -1,9 +1,9 @@ -require_extension('D'); +require_either_extension('D', EXT_ZDINX); require_fp; -bool greater = f64_lt_quiet(f64(FRS2), f64(FRS1)) || - (f64_eq(f64(FRS2), f64(FRS1)) && (f64(FRS2).v & F64_SIGN)); -if (isNaNF64UI(f64(FRS1).v) && isNaNF64UI(f64(FRS2).v)) - WRITE_FRD(f64(defaultNaNF64UI)); +bool greater = f64_lt_quiet(FRS2_D, FRS1_D) || + (f64_eq(FRS2_D, FRS1_D) && (FRS2_D.v & F64_SIGN)); +if (isNaNF64UI(FRS1_D.v) && isNaNF64UI(FRS2_D.v)) + WRITE_FRD_D(f64(defaultNaNF64UI)); else - WRITE_FRD(greater || isNaNF64UI(f64(FRS2).v) ? FRS1 : FRS2); + WRITE_FRD_D((greater || isNaNF64UI(FRS2_D.v) ? FRS1_D : FRS2_D)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fmax_h.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fmax_h.h index 3d4c40ebf..c86425841 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fmax_h.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fmax_h.h @@ -1,4 +1,4 @@ -require_extension(EXT_ZFH); +require_either_extension(EXT_ZFH, EXT_ZHINX); require_fp; -WRITE_FRD(f16_max(f16(FRS1), f16(FRS2))); +WRITE_FRD_H(f16_max(FRS1_H, FRS2_H)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fmax_s.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fmax_s.h index 41d8f921f..17d8b3c8d 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fmax_s.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fmax_s.h @@ -1,9 +1,9 @@ -require_extension('F'); +require_either_extension('F', EXT_ZFINX); require_fp; -bool greater = f32_lt_quiet(f32(FRS2), f32(FRS1)) || - (f32_eq(f32(FRS2), f32(FRS1)) && (f32(FRS2).v & F32_SIGN)); -if (isNaNF32UI(f32(FRS1).v) && isNaNF32UI(f32(FRS2).v)) - WRITE_FRD(f32(defaultNaNF32UI)); +bool greater = f32_lt_quiet(FRS2_F, FRS1_F) || + (f32_eq(FRS2_F, FRS1_F) && (FRS2_F.v & F32_SIGN)); +if (isNaNF32UI(FRS1_F.v) && isNaNF32UI(FRS2_F.v)) + WRITE_FRD_F(f32(defaultNaNF32UI)); else - WRITE_FRD(greater || isNaNF32UI(f32(FRS2).v) ? FRS1 : FRS2); + WRITE_FRD_F((greater || isNaNF32UI(FRS2_F.v) ? FRS1_F : FRS2_F)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fmaxm_d.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fmaxm_d.h new file mode 100644 index 000000000..0cecd640e --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fmaxm_d.h @@ -0,0 +1,10 @@ +require_extension('D'); +require_extension(EXT_ZFA); +require_fp; +bool greater = f64_lt_quiet(FRS2_D, FRS1_D) || + (f64_eq(FRS2_D, FRS1_D) && (FRS2_D.v & F64_SIGN)); +if (isNaNF64UI(FRS1_D.v) || isNaNF64UI(FRS2_D.v)) + WRITE_FRD_D(f64(defaultNaNF64UI)); +else + WRITE_FRD_D(greater ? FRS1_D : FRS2_D); +set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fmaxm_h.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fmaxm_h.h new file mode 100644 index 000000000..0eb00eaf9 --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fmaxm_h.h @@ -0,0 +1,10 @@ +require_extension(EXT_ZFH); +require_extension(EXT_ZFA); +require_fp; +bool greater = f16_lt_quiet(FRS2_H, FRS1_H) || + (f16_eq(FRS2_H, FRS1_H) && (FRS2_H.v & F16_SIGN)); +if (isNaNF16UI(FRS1_H.v) || isNaNF16UI(FRS2_H.v)) + WRITE_FRD_H(f16(defaultNaNF16UI)); +else + WRITE_FRD_H(greater ? FRS1_H : FRS2_H); +set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fmaxm_q.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fmaxm_q.h new file mode 100644 index 000000000..a48031e22 --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fmaxm_q.h @@ -0,0 +1,17 @@ +require_extension('D'); +require_extension(EXT_ZFA); +require_fp; +ui128_f128 ui1; +ui1.f = f128(FRS1); +ui128_f128 ui2; +ui2.f = f128(FRS2); +bool greater = f128_lt_quiet(f128(FRS2), f128(FRS1)) || + (f128_eq(f128(FRS1), f128(FRS2)) && (signF128UI64(ui2.ui.v64))); +if (isNaNF128UI(ui1.ui.v64, ui1.ui.v0) || isNaNF128UI(ui2.ui.v64, ui2.ui.v0)) { + ui128_f128 ui; + ui.ui.v64 = defaultNaNF128UI64; + ui.ui.v0 = defaultNaNF128UI0; + WRITE_FRD(f128(ui.f)); + } else + WRITE_FRD(greater ? f128(FRS1) : f128(FRS2)); +set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fmaxm_s.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fmaxm_s.h new file mode 100644 index 000000000..ebf195a15 --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fmaxm_s.h @@ -0,0 +1,10 @@ +require_extension('F'); +require_extension(EXT_ZFA); +require_fp; +bool greater = f32_lt_quiet(FRS2_F, FRS1_F) || + (f32_eq(FRS2_F, FRS1_F) && (FRS2_F.v & F32_SIGN)); +if (isNaNF32UI(FRS1_F.v) || isNaNF32UI(FRS2_F.v)) + WRITE_FRD_F(f32(defaultNaNF32UI)); +else + WRITE_FRD_F(greater ? FRS1_F : FRS2_F); +set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fmin_d.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fmin_d.h index 5cf349d47..f60a73e79 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fmin_d.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fmin_d.h @@ -1,9 +1,9 @@ -require_extension('D'); +require_either_extension('D', EXT_ZDINX); require_fp; -bool less = f64_lt_quiet(f64(FRS1), f64(FRS2)) || - (f64_eq(f64(FRS1), f64(FRS2)) && (f64(FRS1).v & F64_SIGN)); -if (isNaNF64UI(f64(FRS1).v) && isNaNF64UI(f64(FRS2).v)) - WRITE_FRD(f64(defaultNaNF64UI)); +bool less = f64_lt_quiet(FRS1_D, FRS2_D) || + (f64_eq(FRS1_D, FRS2_D) && (FRS1_D.v & F64_SIGN)); +if (isNaNF64UI(FRS1_D.v) && isNaNF64UI(FRS2_D.v)) + WRITE_FRD_D(f64(defaultNaNF64UI)); else - WRITE_FRD(less || isNaNF64UI(f64(FRS2).v) ? FRS1 : FRS2); + WRITE_FRD_D((less || isNaNF64UI(FRS2_D.v) ? FRS1_D : FRS2_D)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fmin_h.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fmin_h.h index 5fb1404fe..cd02f20e1 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fmin_h.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fmin_h.h @@ -1,4 +1,4 @@ -require_extension(EXT_ZFH); +require_either_extension(EXT_ZFH, EXT_ZHINX); require_fp; -WRITE_FRD(f16_min(f16(FRS1), f16(FRS2))); +WRITE_FRD_H(f16_min(FRS1_H, FRS2_H)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fmin_s.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fmin_s.h index 19e119381..476a58609 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fmin_s.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fmin_s.h @@ -1,9 +1,9 @@ -require_extension('F'); +require_either_extension('F', EXT_ZFINX); require_fp; -bool less = f32_lt_quiet(f32(FRS1), f32(FRS2)) || - (f32_eq(f32(FRS1), f32(FRS2)) && (f32(FRS1).v & F32_SIGN)); -if (isNaNF32UI(f32(FRS1).v) && isNaNF32UI(f32(FRS2).v)) - WRITE_FRD(f32(defaultNaNF32UI)); +bool less = f32_lt_quiet(FRS1_F, FRS2_F) || + (f32_eq(FRS1_F, FRS2_F) && (FRS1_F.v & F32_SIGN)); +if (isNaNF32UI(FRS1_F.v) && isNaNF32UI(FRS2_F.v)) + WRITE_FRD_F(f32(defaultNaNF32UI)); else - WRITE_FRD(less || isNaNF32UI(f32(FRS2).v) ? FRS1 : FRS2); + WRITE_FRD_F((less || isNaNF32UI(FRS2_F.v) ? FRS1_F : FRS2_F)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fminm_d.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fminm_d.h new file mode 100644 index 000000000..a60d3e88c --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fminm_d.h @@ -0,0 +1,10 @@ +require_extension('D'); +require_extension(EXT_ZFA); +require_fp; +bool less = f64_lt_quiet(FRS1_D, FRS2_D) || + (f64_eq(FRS2_D, FRS1_D) && (FRS1_D.v & F64_SIGN)); +if (isNaNF64UI(FRS1_D.v) || isNaNF64UI(FRS2_D.v)) + WRITE_FRD_D(f64(defaultNaNF64UI)); +else + WRITE_FRD_D(less ? FRS1_D : FRS2_D); +set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fminm_h.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fminm_h.h new file mode 100644 index 000000000..0f207e806 --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fminm_h.h @@ -0,0 +1,10 @@ +require_extension(EXT_ZFH); +require_extension(EXT_ZFA); +require_fp; +bool less = f16_lt_quiet(FRS1_H, FRS2_H) || + (f16_eq(FRS2_H, FRS1_H) && (FRS1_H.v & F16_SIGN)); +if (isNaNF16UI(FRS1_H.v) || isNaNF16UI(FRS2_H.v)) + WRITE_FRD_H(f16(defaultNaNF16UI)); +else + WRITE_FRD_H(less ? FRS1_H : FRS2_H); +set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fminm_q.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fminm_q.h new file mode 100644 index 000000000..bccd7ed63 --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fminm_q.h @@ -0,0 +1,17 @@ +require_extension('Q'); +require_extension(EXT_ZFA); +require_fp; +ui128_f128 ui1; +ui1.f = f128(FRS1); +ui128_f128 ui2; +ui2.f = f128(FRS2); +bool less = f128_lt_quiet(f128(FRS1), f128(FRS2)) || + (f128_eq(f128(FRS1), f128(FRS2)) && (signF128UI64(ui1.ui.v64))); +if (isNaNF128UI(ui1.ui.v64, ui1.ui.v0) || isNaNF128UI(ui2.ui.v64, ui2.ui.v0)) { + ui128_f128 ui; + ui.ui.v64 = defaultNaNF128UI64; + ui.ui.v0 = defaultNaNF128UI0; + WRITE_FRD(f128(ui.f)); + } else + WRITE_FRD(less ? f128(FRS1) : f128(FRS2)); +set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fminm_s.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fminm_s.h new file mode 100644 index 000000000..b1c60f84d --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fminm_s.h @@ -0,0 +1,10 @@ +require_extension('F'); +require_extension(EXT_ZFA); +require_fp; +bool less = f32_lt_quiet(FRS1_F, FRS2_F) || + (f32_eq(FRS2_F, FRS1_F) && (FRS1_F.v & F32_SIGN)); +if (isNaNF32UI(FRS1_F.v) || isNaNF32UI(FRS2_F.v)) + WRITE_FRD_F(f32(defaultNaNF32UI)); +else + WRITE_FRD_F(less ? FRS1_F : FRS2_F); +set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fmsub_d.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fmsub_d.h index 5b5bc0f75..1a7d7847c 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fmsub_d.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fmsub_d.h @@ -1,5 +1,5 @@ -require_extension('D'); +require_either_extension('D', EXT_ZDINX); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f64_mulAdd(f64(FRS1), f64(FRS2), f64(f64(FRS3).v ^ F64_SIGN))); +WRITE_FRD_D(f64_mulAdd(FRS1_D, FRS2_D, f64(FRS3_D.v ^ F64_SIGN))); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fmsub_h.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fmsub_h.h index 934291fc8..dc6a8e6c8 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fmsub_h.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fmsub_h.h @@ -1,5 +1,5 @@ -require_extension(EXT_ZFH); +require_either_extension(EXT_ZFH, EXT_ZHINX); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f16_mulAdd(f16(FRS1), f16(FRS2), f16(f16(FRS3).v ^ F16_SIGN))); +WRITE_FRD_H(f16_mulAdd(FRS1_H, FRS2_H, f16(FRS3_H.v ^ F16_SIGN))); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fmsub_s.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fmsub_s.h index d46c887e7..179cc2f65 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fmsub_s.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fmsub_s.h @@ -1,5 +1,5 @@ -require_extension('F'); +require_either_extension('F', EXT_ZFINX); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f32_mulAdd(f32(FRS1), f32(FRS2), f32(f32(FRS3).v ^ F32_SIGN))); +WRITE_FRD_F(f32_mulAdd(FRS1_F, FRS2_F, f32(FRS3_F.v ^ F32_SIGN))); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fmul_d.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fmul_d.h index 9189d8d9e..e5caa34c9 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fmul_d.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fmul_d.h @@ -1,5 +1,5 @@ -require_extension('D'); +require_either_extension('D', EXT_ZDINX); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f64_mul(f64(FRS1), f64(FRS2))); +WRITE_FRD_D(f64_mul(FRS1_D, FRS2_D)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fmul_h.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fmul_h.h index 0152df8f0..dc7f9c47b 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fmul_h.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fmul_h.h @@ -1,5 +1,5 @@ -require_extension(EXT_ZFH); +require_either_extension(EXT_ZFH, EXT_ZHINX); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f16_mul(f16(FRS1), f16(FRS2))); +WRITE_FRD_H(f16_mul(FRS1_H, FRS2_H)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fmul_s.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fmul_s.h index 145d5ce4d..9cf30b4bd 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fmul_s.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fmul_s.h @@ -1,5 +1,5 @@ -require_extension('F'); +require_either_extension('F', EXT_ZFINX); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f32_mul(f32(FRS1), f32(FRS2))); +WRITE_FRD_F(f32_mul(FRS1_F, FRS2_F)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fmvh_x_d.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fmvh_x_d.h new file mode 100644 index 000000000..961ad765d --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fmvh_x_d.h @@ -0,0 +1,7 @@ +require_rv32; +require_extension('D'); +require_extension(EXT_ZFA); +require_fp; +ui64_f64 ui; +ui.f = FRS1_D; +WRITE_RD(ui.ui >> 32); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fmvh_x_q.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fmvh_x_q.h new file mode 100644 index 000000000..12a3923ba --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fmvh_x_q.h @@ -0,0 +1,7 @@ +require_rv64; +require_extension('Q'); +require_extension(EXT_ZFA); +require_fp; +ui128_f128 ui; +ui.f = f128(FRS1); +WRITE_RD(ui.ui.v64); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fmvp_d_x.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fmvp_d_x.h new file mode 100644 index 000000000..f95cfe968 --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fmvp_d_x.h @@ -0,0 +1,8 @@ +require_rv32; +require_extension('D'); +require_extension(EXT_ZFA); +require_fp; +ui64_f64 ui; +ui.ui = ((uint64_t)RS2) << 32; +ui.ui |= RS1; +WRITE_FRD_D(f64(ui.ui)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fmvp_q_x.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fmvp_q_x.h new file mode 100644 index 000000000..99c7bfd62 --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fmvp_q_x.h @@ -0,0 +1,8 @@ +require_rv64; +require_extension('Q'); +require_extension(EXT_ZFA); +require_fp; +ui128_f128 ui; +ui.ui.v64 = RS2; +ui.ui.v0 = RS1; +WRITE_FRD(f128(ui.f)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fnmadd_d.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fnmadd_d.h index e8dd74323..a2a14e9cd 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fnmadd_d.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fnmadd_d.h @@ -1,5 +1,5 @@ -require_extension('D'); +require_either_extension('D', EXT_ZDINX); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f64_mulAdd(f64(f64(FRS1).v ^ F64_SIGN), f64(FRS2), f64(f64(FRS3).v ^ F64_SIGN))); +WRITE_FRD_D(f64_mulAdd(f64(FRS1_D.v ^ F64_SIGN), FRS2_D, f64(FRS3_D.v ^ F64_SIGN))); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fnmadd_h.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fnmadd_h.h index e4c619e77..b1ca28328 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fnmadd_h.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fnmadd_h.h @@ -1,5 +1,5 @@ -require_extension(EXT_ZFH); +require_either_extension(EXT_ZFH, EXT_ZHINX); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f16_mulAdd(f16(f16(FRS1).v ^ F16_SIGN), f16(FRS2), f16(f16(FRS3).v ^ F16_SIGN))); +WRITE_FRD_H(f16_mulAdd(f16(FRS1_H.v ^ F16_SIGN), FRS2_H, f16(FRS3_H.v ^ F16_SIGN))); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fnmadd_s.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fnmadd_s.h index 1c2996e31..683257ad8 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fnmadd_s.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fnmadd_s.h @@ -1,5 +1,5 @@ -require_extension('F'); +require_either_extension('F', EXT_ZFINX); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f32_mulAdd(f32(f32(FRS1).v ^ F32_SIGN), f32(FRS2), f32(f32(FRS3).v ^ F32_SIGN))); +WRITE_FRD_F(f32_mulAdd(f32(FRS1_F.v ^ F32_SIGN), FRS2_F, f32(FRS3_F.v ^ F32_SIGN))); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fnmsub_d.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fnmsub_d.h index c29a0b93c..9352c3fd2 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fnmsub_d.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fnmsub_d.h @@ -1,5 +1,5 @@ -require_extension('D'); +require_either_extension('D', EXT_ZDINX); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f64_mulAdd(f64(f64(FRS1).v ^ F64_SIGN), f64(FRS2), f64(FRS3))); +WRITE_FRD_D(f64_mulAdd(f64(FRS1_D.v ^ F64_SIGN), FRS2_D, FRS3_D)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fnmsub_h.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fnmsub_h.h index 0410c3bba..e05fcd1fb 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fnmsub_h.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fnmsub_h.h @@ -1,5 +1,5 @@ -require_extension(EXT_ZFH); +require_either_extension(EXT_ZFH, EXT_ZHINX); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f16_mulAdd(f16(f16(FRS1).v ^ F16_SIGN), f16(FRS2), f16(FRS3))); +WRITE_FRD_H(f16_mulAdd(f16(FRS1_H.v ^ F16_SIGN), FRS2_H, FRS3_H)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fnmsub_s.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fnmsub_s.h index 4c61fc7c8..b22b3db6d 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fnmsub_s.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fnmsub_s.h @@ -1,5 +1,5 @@ -require_extension('F'); +require_either_extension('F', EXT_ZFINX); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f32_mulAdd(f32(f32(FRS1).v ^ F32_SIGN), f32(FRS2), f32(FRS3))); +WRITE_FRD_F(f32_mulAdd(f32(FRS1_F.v ^ F32_SIGN), FRS2_F, FRS3_F)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fround_d.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fround_d.h new file mode 100644 index 000000000..112713509 --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fround_d.h @@ -0,0 +1,5 @@ +require_extension('D'); +require_extension(EXT_ZFA); +require_fp; +WRITE_FRD_D(f64_roundToInt(FRS1_D, RM, true)); +set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fround_h.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fround_h.h new file mode 100644 index 000000000..6417a39c6 --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fround_h.h @@ -0,0 +1,5 @@ +require_extension(EXT_ZFH); +require_extension(EXT_ZFA); +require_fp; +WRITE_FRD_H(f16_roundToInt(FRS1_H, RM, true)); +set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fround_q.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fround_q.h new file mode 100644 index 000000000..51ebce237 --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fround_q.h @@ -0,0 +1,5 @@ +require_extension('Q'); +require_extension(EXT_ZFA); +require_fp; +WRITE_FRD(f128_roundToInt(f128(FRS1), RM, true)); +set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fround_s.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fround_s.h new file mode 100644 index 000000000..272897ed1 --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fround_s.h @@ -0,0 +1,5 @@ +require_extension('F'); +require_extension(EXT_ZFA); +require_fp; +WRITE_FRD_F(f32_roundToInt(FRS1_F, RM, true)); +set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/froundnx_d.h b/vendor/riscv/riscv-isa-sim/riscv/insns/froundnx_d.h new file mode 100644 index 000000000..0e8a1ba6d --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/froundnx_d.h @@ -0,0 +1,5 @@ +require_extension('D'); +require_extension(EXT_ZFA); +require_fp; +WRITE_FRD_D(f64_roundToInt(FRS1_D, RM, false)); +set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/froundnx_h.h b/vendor/riscv/riscv-isa-sim/riscv/insns/froundnx_h.h new file mode 100644 index 000000000..0c6cdae4c --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/froundnx_h.h @@ -0,0 +1,5 @@ +require_extension(EXT_ZFH); +require_extension(EXT_ZFA); +require_fp; +WRITE_FRD_H(f16_roundToInt(FRS1_H, RM, false)); +set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/froundnx_q.h b/vendor/riscv/riscv-isa-sim/riscv/insns/froundnx_q.h new file mode 100644 index 000000000..91bab77e2 --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/froundnx_q.h @@ -0,0 +1,5 @@ +require_extension('Q'); +require_extension(EXT_ZFA); +require_fp; +WRITE_FRD(f128_roundToInt(f128(FRS1), RM, false)); +set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/froundnx_s.h b/vendor/riscv/riscv-isa-sim/riscv/insns/froundnx_s.h new file mode 100644 index 000000000..f6e75f5d3 --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/froundnx_s.h @@ -0,0 +1,5 @@ +require_extension('F'); +require_extension(EXT_ZFA); +require_fp; +WRITE_FRD_F(f32_roundToInt(FRS1_F, RM, false)); +set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fsd.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fsd.h index 38c702b7a..babc9e58f 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fsd.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fsd.h @@ -1,3 +1,3 @@ require_extension('D'); require_fp; -MMU.store_uint64(RS1 + insn.s_imm(), FRS2.v[0]); +MMU.store(RS1 + insn.s_imm(), FRS2.v[0]); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fsgnj_d.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fsgnj_d.h index 78f9ce787..8f02fd11f 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fsgnj_d.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fsgnj_d.h @@ -1,3 +1,3 @@ -require_extension('D'); +require_either_extension('D', EXT_ZDINX); require_fp; -WRITE_FRD(fsgnj64(FRS1, FRS2, false, false)); +WRITE_FRD_D(fsgnj64(freg(FRS1_D), freg(FRS2_D), false, false)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fsgnj_h.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fsgnj_h.h index 79d50f5fa..080f27d8c 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fsgnj_h.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fsgnj_h.h @@ -1,3 +1,3 @@ -require_extension(EXT_ZFH); +require_either_extension(EXT_ZFH, EXT_ZHINX); require_fp; -WRITE_FRD(fsgnj16(FRS1, FRS2, false, false)); +WRITE_FRD_H(fsgnj16(freg(FRS1_H), freg(FRS2_H), false, false)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fsgnj_s.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fsgnj_s.h index c1a70cb79..ea511b89e 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fsgnj_s.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fsgnj_s.h @@ -1,3 +1,3 @@ -require_extension('F'); +require_either_extension('F', EXT_ZFINX); require_fp; -WRITE_FRD(fsgnj32(FRS1, FRS2, false, false)); +WRITE_FRD_F(fsgnj32(freg(FRS1_F), freg(FRS2_F), false, false)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fsgnjn_d.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fsgnjn_d.h index f02c3116b..870a9793f 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fsgnjn_d.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fsgnjn_d.h @@ -1,3 +1,3 @@ -require_extension('D'); +require_either_extension('D', EXT_ZDINX); require_fp; -WRITE_FRD(fsgnj64(FRS1, FRS2, true, false)); +WRITE_FRD_D(fsgnj64(freg(FRS1_D), freg(FRS2_D), true, false)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fsgnjn_h.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fsgnjn_h.h index ebb4ac9f5..1d7bf03b9 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fsgnjn_h.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fsgnjn_h.h @@ -1,3 +1,3 @@ -require_extension(EXT_ZFH); +require_either_extension(EXT_ZFH, EXT_ZHINX); require_fp; -WRITE_FRD(fsgnj16(FRS1, FRS2, true, false)); +WRITE_FRD_H(fsgnj16(freg(FRS1_H), freg(FRS2_H), true, false)); \ No newline at end of file diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fsgnjn_q.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fsgnjn_q.h index 38c7bbffb..dcf723550 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fsgnjn_q.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fsgnjn_q.h @@ -1,3 +1,3 @@ require_extension('Q'); require_fp; -WRITE_FRD(fsgnj128(FRS1, FRS2, true, false)); +WRITE_FRD(fsgnj128(FRS1, FRS2, true, false)); \ No newline at end of file diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fsgnjn_s.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fsgnjn_s.h index 35906d657..a0994b499 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fsgnjn_s.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fsgnjn_s.h @@ -1,3 +1,3 @@ -require_extension('F'); +require_either_extension('F', EXT_ZFINX); require_fp; -WRITE_FRD(fsgnj32(FRS1, FRS2, true, false)); +WRITE_FRD_F(fsgnj32(freg(FRS1_F), freg(FRS2_F), true, false)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fsgnjx_d.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fsgnjx_d.h index c12173719..25906f089 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fsgnjx_d.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fsgnjx_d.h @@ -1,3 +1,3 @@ -require_extension('D'); +require_either_extension('D', EXT_ZDINX); require_fp; -WRITE_FRD(fsgnj64(FRS1, FRS2, false, true)); +WRITE_FRD_D(fsgnj64(freg(FRS1_D), freg(FRS2_D), false, true)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fsgnjx_h.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fsgnjx_h.h index 931026954..1d29bb1fc 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fsgnjx_h.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fsgnjx_h.h @@ -1,3 +1,3 @@ -require_extension(EXT_ZFH); +require_either_extension(EXT_ZFH, EXT_ZHINX); require_fp; -WRITE_FRD(fsgnj16(FRS1, FRS2, false, true)); +WRITE_FRD_H(fsgnj16(freg(FRS1_H), freg(FRS2_H), false, true)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fsgnjx_s.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fsgnjx_s.h index 4d5c624b6..9bc079888 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fsgnjx_s.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fsgnjx_s.h @@ -1,3 +1,3 @@ -require_extension('F'); +require_either_extension('F', EXT_ZFINX); require_fp; -WRITE_FRD(fsgnj32(FRS1, FRS2, false, true)); +WRITE_FRD_F(fsgnj32(freg(FRS1_F), freg(FRS2_F), false, true)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fsh.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fsh.h index 9eaae1eb8..dfd6bc5ca 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fsh.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fsh.h @@ -1,3 +1,3 @@ require_extension(EXT_ZFHMIN); require_fp; -MMU.store_uint16(RS1 + insn.s_imm(), FRS2.v[0]); +MMU.store(RS1 + insn.s_imm(), FRS2.v[0]); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fsl.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fsl.h index c39133cdc..53a21608d 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fsl.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fsl.h @@ -1,4 +1,4 @@ -require_extension(EXT_XBITMANIP); +require_extension(EXT_XZBT); int shamt = RS2 & (2*xlen-1); reg_t a = RS1, b = RS3; if (shamt >= xlen) { diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fslw.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fslw.h index de69fd289..83940105b 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fslw.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fslw.h @@ -1,5 +1,5 @@ require_rv64; -require_extension(EXT_XBITMANIP); +require_extension(EXT_XZBT); int shamt = RS2 & 63; reg_t a = RS1, b = RS3; if (shamt >= 32) { diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fsqrt_d.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fsqrt_d.h index da138ba19..363b457f4 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fsqrt_d.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fsqrt_d.h @@ -1,5 +1,5 @@ -require_extension('D'); +require_either_extension('D', EXT_ZDINX); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f64_sqrt(f64(FRS1))); +WRITE_FRD_D(f64_sqrt(FRS1_D)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fsqrt_h.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fsqrt_h.h index 138d57274..fea429bd0 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fsqrt_h.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fsqrt_h.h @@ -1,5 +1,5 @@ -require_extension(EXT_ZFH); +require_either_extension(EXT_ZFH, EXT_ZHINX); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f16_sqrt(f16(FRS1))); +WRITE_FRD_H(f16_sqrt(FRS1_H)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fsqrt_s.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fsqrt_s.h index 747684664..d44503a76 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fsqrt_s.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fsqrt_s.h @@ -1,5 +1,5 @@ -require_extension('F'); +require_either_extension('F', EXT_ZFINX); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f32_sqrt(f32(FRS1))); +WRITE_FRD_F(f32_sqrt(FRS1_F)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fsr.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fsr.h index 5a1dc19f4..dfb26f11e 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fsr.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fsr.h @@ -1,4 +1,4 @@ -require_either_extension(xlen == 32 ? EXT_ZBPBO : EXT_XBITMANIP, EXT_XBITMANIP); +require_either_extension(xlen == 32 ? EXT_ZBPBO : EXT_XZBT, EXT_XZBT); int shamt = RS2 & (2*xlen-1); reg_t a = RS1, b = RS3; if (shamt >= xlen) { diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fsri.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fsri.h index 6664d1482..f7186f1b6 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fsri.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fsri.h @@ -1,4 +1,4 @@ -require_either_extension(xlen == 32 ? EXT_ZBPBO : EXT_XBITMANIP, EXT_XBITMANIP); +require_either_extension(xlen == 32 ? EXT_ZBPBO : EXT_XZBT, EXT_XZBT); int shamt = SHAMT & (2*xlen-1); reg_t a = RS1, b = RS3; if (shamt >= xlen) { diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fsriw.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fsriw.h index bfe64f258..7956de7ce 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fsriw.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fsriw.h @@ -1,5 +1,5 @@ require_rv64; -require_extension(EXT_XBITMANIP); +require_extension(EXT_XZBT); int shamt = SHAMT & 63; reg_t a = RS1, b = RS3; if (shamt >= 32) { diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fsrw.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fsrw.h index 0040f02e5..494fe260c 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fsrw.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fsrw.h @@ -1,5 +1,5 @@ require_rv64; -require_either_extension(EXT_ZBPBO, EXT_XBITMANIP); +require_either_extension(EXT_ZBPBO, EXT_XZBT); int shamt = RS2 & 63; reg_t a = RS1, b = RS3; if (shamt >= 32) { diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fsub_d.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fsub_d.h index 1418a063d..4f8bf509b 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fsub_d.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fsub_d.h @@ -1,5 +1,5 @@ -require_extension('D'); +require_either_extension('D', EXT_ZDINX); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f64_sub(f64(FRS1), f64(FRS2))); +WRITE_FRD_D(f64_sub(FRS1_D, FRS2_D)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fsub_h.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fsub_h.h index 43b51cc2e..f7006fb08 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fsub_h.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fsub_h.h @@ -1,5 +1,5 @@ -require_extension(EXT_ZFH); +require_either_extension(EXT_ZFH, EXT_ZHINX); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f16_sub(f16(FRS1), f16(FRS2))); +WRITE_FRD_H(f16_sub(FRS1_H, FRS2_H)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fsub_s.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fsub_s.h index f6183ea00..1a33ffdbf 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fsub_s.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fsub_s.h @@ -1,5 +1,5 @@ -require_extension('F'); +require_either_extension('F', EXT_ZFINX); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f32_sub(f32(FRS1), f32(FRS2))); +WRITE_FRD_F(f32_sub(FRS1_F, FRS2_F)); set_fp_exceptions; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/fsw.h b/vendor/riscv/riscv-isa-sim/riscv/insns/fsw.h index 8af51845f..887f03ea8 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/fsw.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/fsw.h @@ -1,3 +1,3 @@ require_extension('F'); require_fp; -MMU.store_uint32(RS1 + insn.s_imm(), FRS2.v[0]); +MMU.store(RS1 + insn.s_imm(), FRS2.v[0]); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/gorc.h b/vendor/riscv/riscv-isa-sim/riscv/insns/gorc.h index 08e7e673f..ffe441347 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/gorc.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/gorc.h @@ -1,4 +1,4 @@ -require_extension(EXT_XBITMANIP); +require_extension(EXT_XZBP); reg_t x = RS1; int shamt = RS2 & (xlen-1); if (shamt & 1) x |= ((x & 0x5555555555555555LL) << 1) | ((x & 0xAAAAAAAAAAAAAAAALL) >> 1); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/gorci.h b/vendor/riscv/riscv-isa-sim/riscv/insns/gorci.h index 30575f70b..d3017f499 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/gorci.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/gorci.h @@ -1,6 +1,6 @@ // Zbb contains orc.b but not general gorci require(((SHAMT == 7) && p->extension_enabled(EXT_ZBB)) - || p->extension_enabled(EXT_XBITMANIP)); + || p->extension_enabled(EXT_XZBP)); require(SHAMT < xlen); reg_t x = RS1; int shamt = SHAMT; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/gorciw.h b/vendor/riscv/riscv-isa-sim/riscv/insns/gorciw.h index a4e7f7161..44ade807e 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/gorciw.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/gorciw.h @@ -1,5 +1,5 @@ require_rv64; -require_extension(EXT_XBITMANIP); +require_extension(EXT_XZBP); require(SHAMT < 32); reg_t x = RS1; int shamt = SHAMT; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/gorcw.h b/vendor/riscv/riscv-isa-sim/riscv/insns/gorcw.h index 04c6bdcdb..611b3caa4 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/gorcw.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/gorcw.h @@ -1,5 +1,5 @@ require_rv64; -require_extension(EXT_XBITMANIP); +require_extension(EXT_XZBP); reg_t x = RS1; int shamt = RS2 & 31; if (shamt & 1) x |= ((x & 0x5555555555555555LL) << 1) | ((x & 0xAAAAAAAAAAAAAAAALL) >> 1); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/grev.h b/vendor/riscv/riscv-isa-sim/riscv/insns/grev.h index 053348636..7181b3cda 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/grev.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/grev.h @@ -1,4 +1,4 @@ -require_extension(EXT_XBITMANIP); +require_extension(EXT_XZBP); reg_t x = RS1; int shamt = RS2 & (xlen-1); if (shamt & 1) x = ((x & 0x5555555555555555LL) << 1) | ((x & 0xAAAAAAAAAAAAAAAALL) >> 1); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/grevi.h b/vendor/riscv/riscv-isa-sim/riscv/insns/grevi.h index 069fd9a1b..d4718145b 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/grevi.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/grevi.h @@ -5,7 +5,7 @@ require(((shamt == xlen - 8) && (p->extension_enabled(EXT_ZBB) || p->extension_e || ((shamt == 7) && p->extension_enabled(EXT_ZBKB)) // rev8.b || ((shamt == 8) && p->extension_enabled(EXT_ZPN)) // rev8.h || ((shamt == xlen - 1) && p->extension_enabled(EXT_ZPN)) // rev - || p->extension_enabled(EXT_XBITMANIP)); + || p->extension_enabled(EXT_XZBP)); require(shamt < xlen); reg_t x = RS1; if (shamt & 1) x = ((x & 0x5555555555555555LL) << 1) | ((x & 0xAAAAAAAAAAAAAAAALL) >> 1); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/greviw.h b/vendor/riscv/riscv-isa-sim/riscv/insns/greviw.h index d845eb940..004ecf347 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/greviw.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/greviw.h @@ -1,5 +1,5 @@ require_rv64; -require_extension(EXT_XBITMANIP); +require_extension(EXT_XZBP); require(SHAMT < 32); reg_t x = RS1; int shamt = SHAMT; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/grevw.h b/vendor/riscv/riscv-isa-sim/riscv/insns/grevw.h index 63dbe5296..3fbcf228d 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/grevw.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/grevw.h @@ -1,5 +1,5 @@ require_rv64; -require_extension(EXT_XBITMANIP); +require_extension(EXT_XZBP); reg_t x = RS1; int shamt = RS2 & 31; if (shamt & 1) x = ((x & 0x5555555555555555LL) << 1) | ((x & 0xAAAAAAAAAAAAAAAALL) >> 1); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/hlv_b.h b/vendor/riscv/riscv-isa-sim/riscv/insns/hlv_b.h index 2ccb0463a..308d038f4 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/hlv_b.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/hlv_b.h @@ -1,4 +1,4 @@ require_extension('H'); require_novirt(); require_privilege(get_field(STATE.hstatus->read(), HSTATUS_HU) ? PRV_U : PRV_S); -WRITE_RD(MMU.guest_load_int8(RS1)); +WRITE_RD(MMU.guest_load(RS1)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/hlv_bu.h b/vendor/riscv/riscv-isa-sim/riscv/insns/hlv_bu.h index 560f94af1..1fe4d6a93 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/hlv_bu.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/hlv_bu.h @@ -1,4 +1,4 @@ require_extension('H'); require_novirt(); require_privilege(get_field(STATE.hstatus->read(), HSTATUS_HU) ? PRV_U : PRV_S); -WRITE_RD(MMU.guest_load_uint8(RS1)); +WRITE_RD(MMU.guest_load(RS1)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/hlv_d.h b/vendor/riscv/riscv-isa-sim/riscv/insns/hlv_d.h index f432b650f..8e92ce3e0 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/hlv_d.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/hlv_d.h @@ -2,4 +2,4 @@ require_extension('H'); require_rv64; require_novirt(); require_privilege(get_field(STATE.hstatus->read(), HSTATUS_HU) ? PRV_U : PRV_S); -WRITE_RD(MMU.guest_load_int64(RS1)); +WRITE_RD(MMU.guest_load(RS1)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/hlv_h.h b/vendor/riscv/riscv-isa-sim/riscv/insns/hlv_h.h index 4cb07e99b..f2e14c4b0 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/hlv_h.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/hlv_h.h @@ -1,4 +1,4 @@ require_extension('H'); require_novirt(); require_privilege(get_field(STATE.hstatus->read(), HSTATUS_HU) ? PRV_U : PRV_S); -WRITE_RD(MMU.guest_load_int16(RS1)); +WRITE_RD(MMU.guest_load(RS1)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/hlv_hu.h b/vendor/riscv/riscv-isa-sim/riscv/insns/hlv_hu.h index adec2f0b1..f7f12ef0e 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/hlv_hu.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/hlv_hu.h @@ -1,4 +1,4 @@ require_extension('H'); require_novirt(); require_privilege(get_field(STATE.hstatus->read(), HSTATUS_HU) ? PRV_U : PRV_S); -WRITE_RD(MMU.guest_load_uint16(RS1)); +WRITE_RD(MMU.guest_load(RS1)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/hlv_w.h b/vendor/riscv/riscv-isa-sim/riscv/insns/hlv_w.h index b2e102f0e..72f69eaaf 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/hlv_w.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/hlv_w.h @@ -1,4 +1,4 @@ require_extension('H'); require_novirt(); require_privilege(get_field(STATE.hstatus->read(), HSTATUS_HU) ? PRV_U : PRV_S); -WRITE_RD(MMU.guest_load_int32(RS1)); +WRITE_RD(MMU.guest_load(RS1)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/hlv_wu.h b/vendor/riscv/riscv-isa-sim/riscv/insns/hlv_wu.h index 1f921c0fa..854269fe2 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/hlv_wu.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/hlv_wu.h @@ -2,4 +2,4 @@ require_extension('H'); require_rv64; require_novirt(); require_privilege(get_field(STATE.hstatus->read(), HSTATUS_HU) ? PRV_U : PRV_S); -WRITE_RD(MMU.guest_load_uint32(RS1)); +WRITE_RD(MMU.guest_load(RS1)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/hlvx_hu.h b/vendor/riscv/riscv-isa-sim/riscv/insns/hlvx_hu.h index 3eb699c19..95dcb2042 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/hlvx_hu.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/hlvx_hu.h @@ -1,4 +1,4 @@ require_extension('H'); require_novirt(); require_privilege(get_field(STATE.hstatus->read(), HSTATUS_HU) ? PRV_U : PRV_S); -WRITE_RD(MMU.guest_load_x_uint16(RS1)); +WRITE_RD(MMU.guest_load_x(RS1)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/hlvx_wu.h b/vendor/riscv/riscv-isa-sim/riscv/insns/hlvx_wu.h index 33e2fa1b5..c751ba588 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/hlvx_wu.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/hlvx_wu.h @@ -1,4 +1,4 @@ require_extension('H'); require_novirt(); require_privilege(get_field(STATE.hstatus->read(), HSTATUS_HU) ? PRV_U : PRV_S); -WRITE_RD(sext_xlen(MMU.guest_load_x_uint32(RS1))); +WRITE_RD(sext_xlen(MMU.guest_load_x(RS1))); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/hsv_b.h b/vendor/riscv/riscv-isa-sim/riscv/insns/hsv_b.h index 15f6a2689..d56483fb2 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/hsv_b.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/hsv_b.h @@ -1,4 +1,4 @@ require_extension('H'); require_novirt(); require_privilege(get_field(STATE.hstatus->read(), HSTATUS_HU) ? PRV_U : PRV_S); -MMU.guest_store_uint8(RS1, RS2); +MMU.guest_store(RS1, RS2); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/hsv_d.h b/vendor/riscv/riscv-isa-sim/riscv/insns/hsv_d.h index 83c3376eb..ed7f5bb92 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/hsv_d.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/hsv_d.h @@ -2,4 +2,4 @@ require_extension('H'); require_rv64; require_novirt(); require_privilege(get_field(STATE.hstatus->read(), HSTATUS_HU) ? PRV_U : PRV_S); -MMU.guest_store_uint64(RS1, RS2); +MMU.guest_store(RS1, RS2); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/hsv_h.h b/vendor/riscv/riscv-isa-sim/riscv/insns/hsv_h.h index eaa2a2cb5..596f1684c 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/hsv_h.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/hsv_h.h @@ -1,4 +1,4 @@ require_extension('H'); require_novirt(); require_privilege(get_field(STATE.hstatus->read(), HSTATUS_HU) ? PRV_U : PRV_S); -MMU.guest_store_uint16(RS1, RS2); +MMU.guest_store(RS1, RS2); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/hsv_w.h b/vendor/riscv/riscv-isa-sim/riscv/insns/hsv_w.h index 0d2c3d4d5..f011e2dfa 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/hsv_w.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/hsv_w.h @@ -1,4 +1,4 @@ require_extension('H'); require_novirt(); require_privilege(get_field(STATE.hstatus->read(), HSTATUS_HU) ? PRV_U : PRV_S); -MMU.guest_store_uint32(RS1, RS2); +MMU.guest_store(RS1, RS2); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/kmar64.h b/vendor/riscv/riscv-isa-sim/riscv/insns/kmar64.h index 49f448231..a4d332b0d 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/kmar64.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/kmar64.h @@ -5,7 +5,6 @@ P_64_PROFILE_PARAM(true, false) bool sat = false; sreg_t mres0 = (sreg_t)P_SW(rs1, 0) * P_SW(rs2, 0); sreg_t mres1 = (sreg_t)P_SW(rs1, 1) * P_SW(rs2, 1); -sreg_t res; if (xlen == 32) { rd = (sat_add(rd, mres0, sat)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/kmmawb2.h b/vendor/riscv/riscv-isa-sim/riscv/insns/kmmawb2.h index 6b3aa0ddc..274f9dd83 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/kmmawb2.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/kmmawb2.h @@ -3,7 +3,7 @@ P_LOOP(32, { int64_t addop = 0; int64_t mres = 0; bool sat = false; - if((INT32_MIN != ps1) | (INT16_MIN != P_SH(ps2, 0))) { + if ((INT32_MIN != ps1) | (INT16_MIN != P_SH(ps2, 0))) { mres = ((int64_t) ps1 * P_SH(ps2, 0)) << 1; addop = mres >> 16; } else { diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/kmmawb2_u.h b/vendor/riscv/riscv-isa-sim/riscv/insns/kmmawb2_u.h index f44346e19..447a3f455 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/kmmawb2_u.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/kmmawb2_u.h @@ -3,7 +3,7 @@ P_LOOP(32, { int64_t addop = 0; int64_t mres = 0; bool sat = false; - if((INT32_MIN != ps1) | (INT16_MIN != P_SH(ps2, 0))) { + if ((INT32_MIN != ps1) | (INT16_MIN != P_SH(ps2, 0))) { mres = ((int64_t) ps1 * P_SH(ps2, 0)) << 1; addop = ((mres >> 15) + 1) >> 1; } else { diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/kmmawt2.h b/vendor/riscv/riscv-isa-sim/riscv/insns/kmmawt2.h index 3cd72de7c..6eb22ac08 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/kmmawt2.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/kmmawt2.h @@ -3,7 +3,7 @@ P_LOOP(32, { int64_t addop = 0; int64_t mres = 0; bool sat = false; - if((INT32_MIN != ps1) | (INT16_MIN != P_SH(ps2, 1))) { + if ((INT32_MIN != ps1) | (INT16_MIN != P_SH(ps2, 1))) { mres = ((int64_t) ps1 * P_SH(ps2, 1)) << 1; addop = mres >> 16; } else { diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/kmmawt2_u.h b/vendor/riscv/riscv-isa-sim/riscv/insns/kmmawt2_u.h index 7fe378c1f..b82e0909c 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/kmmawt2_u.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/kmmawt2_u.h @@ -3,7 +3,7 @@ P_LOOP(32, { int64_t addop = 0; int64_t mres = 0; bool sat = false; - if((INT32_MIN != ps1) | (INT16_MIN != P_SH(ps2, 1))) { + if ((INT32_MIN != ps1) | (INT16_MIN != P_SH(ps2, 1))) { mres = ((int64_t) ps1 * P_SH(ps2, 1)) << 1; addop = ((mres >> 15) + 1) >> 1; } else { diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/kmmwb2.h b/vendor/riscv/riscv-isa-sim/riscv/insns/kmmwb2.h index 272f73804..d08b0ef5a 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/kmmwb2.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/kmmwb2.h @@ -1,6 +1,6 @@ require_vector_vs; P_LOOP(32, { - if((INT32_MIN != ps1) | (INT16_MIN != P_SH(ps2, 0))) { + if ((INT32_MIN != ps1) | (INT16_MIN != P_SH(ps2, 0))) { int64_t mres = ((int64_t) ps1 * P_SH(ps2, 0)) << 1; pd = mres >> 16; } else { diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/kmmwb2_u.h b/vendor/riscv/riscv-isa-sim/riscv/insns/kmmwb2_u.h index b5a5006c5..d308bf3a3 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/kmmwb2_u.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/kmmwb2_u.h @@ -1,6 +1,6 @@ require_vector_vs; P_LOOP(32, { - if((INT32_MIN != ps1) | (INT16_MIN != P_SH(ps2, 0))) { + if ((INT32_MIN != ps1) | (INT16_MIN != P_SH(ps2, 0))) { int64_t mres = ((int64_t) ps1 * P_SH(ps2, 0)) << 1; pd = ((mres >> 15) + 1) >> 1; } else { diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/kmmwt2.h b/vendor/riscv/riscv-isa-sim/riscv/insns/kmmwt2.h index 73d3dc8c1..38ba9b18f 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/kmmwt2.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/kmmwt2.h @@ -1,6 +1,6 @@ require_vector_vs; P_LOOP(32, { - if((INT32_MIN != ps1) | (INT16_MIN != P_SH(ps2, 1))) { + if ((INT32_MIN != ps1) | (INT16_MIN != P_SH(ps2, 1))) { int64_t mres = ((int64_t) ps1 * P_SH(ps2, 1)) << 1; pd = mres >> 16; } else { diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/kmmwt2_u.h b/vendor/riscv/riscv-isa-sim/riscv/insns/kmmwt2_u.h index 1f525a8ae..e85578630 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/kmmwt2_u.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/kmmwt2_u.h @@ -1,6 +1,6 @@ require_vector_vs; P_LOOP(32, { - if((INT32_MIN != ps1) | (INT16_MIN != P_SH(ps2, 1))) { + if ((INT32_MIN != ps1) | (INT16_MIN != P_SH(ps2, 1))) { int64_t mres = ((int64_t) ps1 * P_SH(ps2, 1)) << 1; pd = ((mres >> 15) + 1) >> 1; } else { diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/kslra16_u.h b/vendor/riscv/riscv-isa-sim/riscv/insns/kslra16_u.h index 8335f3e81..27bb77c4b 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/kslra16_u.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/kslra16_u.h @@ -3,7 +3,7 @@ P_X_LOOP(16, 5, { if (ssa < 0) { sa = -ssa; sa = (sa == 16) ? 15 : sa; - if(sa != 0) + if (sa != 0) pd = ((ps1 >> (sa - 1)) + 1) >> 1; else pd = ps1; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/kslra32_u.h b/vendor/riscv/riscv-isa-sim/riscv/insns/kslra32_u.h index d53c8fe13..b9c06cfee 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/kslra32_u.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/kslra32_u.h @@ -4,7 +4,7 @@ P_X_LOOP(32, 6, { if (ssa < 0) { sa = -ssa; sa = (sa == 32) ? 31 : sa; - if(sa != 0) + if (sa != 0) pd = ((ps1 >> (sa - 1)) + 1) >> 1; else pd = ps1; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/kslra8_u.h b/vendor/riscv/riscv-isa-sim/riscv/insns/kslra8_u.h index 620f3bd35..340283f64 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/kslra8_u.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/kslra8_u.h @@ -3,7 +3,7 @@ P_X_LOOP(8, 4, { if (ssa < 0) { sa = -ssa; sa = (sa == 8) ? 7 : sa; - if(sa != 0) + if (sa != 0) pd = ((ps1 >> (sa - 1)) + 1) >> 1; else pd = ps1; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/kwmmul.h b/vendor/riscv/riscv-isa-sim/riscv/insns/kwmmul.h index b0ab8d4de..ca654f2f7 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/kwmmul.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/kwmmul.h @@ -1,6 +1,6 @@ require_vector_vs; P_LOOP(32, { - if((INT32_MIN != ps1) | (INT32_MIN != ps2)) { + if ((INT32_MIN != ps1) | (INT32_MIN != ps2)) { int64_t mres = ((int64_t) ps1 * (int64_t) ps2) << 1; pd = mres >> 32; } else { diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/kwmmul_u.h b/vendor/riscv/riscv-isa-sim/riscv/insns/kwmmul_u.h index c2045e191..b435561cb 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/kwmmul_u.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/kwmmul_u.h @@ -1,6 +1,6 @@ require_vector_vs; P_LOOP(32, { - if((INT32_MIN != ps1) | (INT32_MIN != ps2)) { + if ((INT32_MIN != ps1) | (INT32_MIN != ps2)) { int64_t mres = ((int64_t) ps1 * (int64_t) ps2) << 1; pd = ((mres >> 31) + 1) >> 1; } else { diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/lb.h b/vendor/riscv/riscv-isa-sim/riscv/insns/lb.h index 0f0999caa..cd6b46125 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/lb.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/lb.h @@ -1 +1 @@ -WRITE_RD(MMU.load_int8(RS1 + insn.i_imm())); +WRITE_RD(MMU.load(RS1 + insn.i_imm())); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/lbu.h b/vendor/riscv/riscv-isa-sim/riscv/insns/lbu.h index 64d4a688b..bcdf7cad6 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/lbu.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/lbu.h @@ -1 +1 @@ -WRITE_RD(MMU.load_uint8(RS1 + insn.i_imm())); +WRITE_RD(MMU.load(RS1 + insn.i_imm())); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/ld.h b/vendor/riscv/riscv-isa-sim/riscv/insns/ld.h index 1122b9807..3dea301e2 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/ld.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/ld.h @@ -1,2 +1,2 @@ require_rv64; -WRITE_RD(MMU.load_int64(RS1 + insn.i_imm())); +WRITE_RD(MMU.load(RS1 + insn.i_imm())); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/lh.h b/vendor/riscv/riscv-isa-sim/riscv/insns/lh.h index 0d458e0ee..845451a78 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/lh.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/lh.h @@ -1 +1 @@ -WRITE_RD(MMU.load_int16(RS1 + insn.i_imm())); +WRITE_RD(MMU.load(RS1 + insn.i_imm())); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/lhu.h b/vendor/riscv/riscv-isa-sim/riscv/insns/lhu.h index 9d240702a..6eac0bb9a 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/lhu.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/lhu.h @@ -1 +1 @@ -WRITE_RD(MMU.load_uint16(RS1 + insn.i_imm())); +WRITE_RD(MMU.load(RS1 + insn.i_imm())); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/lr_d.h b/vendor/riscv/riscv-isa-sim/riscv/insns/lr_d.h index 6dd8d6721..214daff26 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/lr_d.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/lr_d.h @@ -1,5 +1,3 @@ require_extension('A'); require_rv64; -auto res = MMU.load_int64(RS1, true); -MMU.acquire_load_reservation(RS1); -WRITE_RD(res); +WRITE_RD(MMU.load_reserved(RS1)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/lr_w.h b/vendor/riscv/riscv-isa-sim/riscv/insns/lr_w.h index 185be53b1..354590f26 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/lr_w.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/lr_w.h @@ -1,4 +1,2 @@ require_extension('A'); -auto res = MMU.load_int32(RS1, true); -MMU.acquire_load_reservation(RS1); -WRITE_RD(res); +WRITE_RD(MMU.load_reserved(RS1)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/lw.h b/vendor/riscv/riscv-isa-sim/riscv/insns/lw.h index 4e8ed040d..82d704444 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/lw.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/lw.h @@ -1 +1 @@ -WRITE_RD(MMU.load_int32(RS1 + insn.i_imm())); +WRITE_RD(MMU.load(RS1 + insn.i_imm())); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/lwu.h b/vendor/riscv/riscv-isa-sim/riscv/insns/lwu.h index dcc4d75ba..cbc7e2abd 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/lwu.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/lwu.h @@ -1,2 +1,2 @@ require_rv64; -WRITE_RD(MMU.load_uint32(RS1 + insn.i_imm())); +WRITE_RD(MMU.load(RS1 + insn.i_imm())); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/mnret.h b/vendor/riscv/riscv-isa-sim/riscv/insns/mnret.h new file mode 100644 index 000000000..bc6951062 --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/mnret.h @@ -0,0 +1,15 @@ +require_extension(EXT_SMRNMI); +require_privilege(PRV_M); +set_pc_and_serialize(p->get_state()->mnepc->read()); +reg_t s = STATE.mnstatus->read(); +reg_t prev_prv = get_field(s, MNSTATUS_MNPP); +reg_t prev_virt = get_field(s, MNSTATUS_MNPV); +if (prev_prv != PRV_M) { + reg_t mstatus = STATE.mstatus->read(); + mstatus = set_field(mstatus, MSTATUS_MPRV, 0); + STATE.mstatus->write(mstatus); +} +s = set_field(s, MNSTATUS_NMIE, 1); +STATE.mnstatus->write(s); +p->set_privilege(prev_prv); +p->set_virt(prev_virt); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/mret.h b/vendor/riscv/riscv-isa-sim/riscv/insns/mret.h index be9f2473a..5198b8fc6 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/mret.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/mret.h @@ -7,8 +7,8 @@ if (prev_prv != PRV_M) s = set_field(s, MSTATUS_MPRV, 0); s = set_field(s, MSTATUS_MIE, get_field(s, MSTATUS_MPIE)); s = set_field(s, MSTATUS_MPIE, 1); -s = set_field(s, MSTATUS_MPP, PRV_U); +s = set_field(s, MSTATUS_MPP, p->extension_enabled('U') ? PRV_U : PRV_M); s = set_field(s, MSTATUS_MPV, 0); -p->set_csr(CSR_MSTATUS, s); +p->put_csr(CSR_MSTATUS, s); p->set_privilege(prev_prv); p->set_virt(prev_virt); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/ori.h b/vendor/riscv/riscv-isa-sim/riscv/insns/ori.h index 6403c39b5..3aba1cb2d 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/ori.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/ori.h @@ -1 +1,2 @@ +// prefetch.i/r/w hint when rd = 0 and i_imm[4:0] = 0/1/3 WRITE_RD(insn.i_imm() | RS1); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/pack.h b/vendor/riscv/riscv-isa-sim/riscv/insns/pack.h index d4f6858ea..2140f918d 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/pack.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/pack.h @@ -2,7 +2,10 @@ require(((xlen == 32) && (insn.rs2() == 0) && p->extension_enabled(EXT_ZBB)) || p->extension_enabled(EXT_ZPN) || p->extension_enabled(EXT_ZBKB) - || p->extension_enabled(EXT_XBITMANIP)); + || p->extension_enabled(EXT_XZBP) + || p->extension_enabled(EXT_XZBE) + || p->extension_enabled(EXT_XZBF) + || ((xlen == 64) && p->extension_enabled(EXT_XZBM))); reg_t lo = zext_xlen(RS1 << (xlen/2)) >> (xlen/2); reg_t hi = zext_xlen(RS2 << (xlen/2)); WRITE_RD(sext_xlen(lo | hi)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/packh.h b/vendor/riscv/riscv-isa-sim/riscv/insns/packh.h index b5bb7042f..82886e329 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/packh.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/packh.h @@ -1,4 +1,7 @@ -require_either_extension(EXT_ZBKB, EXT_XBITMANIP); +require(p->extension_enabled(EXT_ZBKB) || + p->extension_enabled(EXT_XZBP) || + p->extension_enabled(EXT_XZBE) || + p->extension_enabled(EXT_XZBF)); reg_t lo = zext_xlen(RS1 << (xlen-8)) >> (xlen-8); reg_t hi = zext_xlen(RS2 << (xlen-8)) >> (xlen-16); WRITE_RD(sext_xlen(lo | hi)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/packu.h b/vendor/riscv/riscv-isa-sim/riscv/insns/packu.h index 0eb6707d8..441207c32 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/packu.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/packu.h @@ -1,4 +1,6 @@ -require_either_extension(EXT_ZPN, EXT_XBITMANIP); +require(p->extension_enabled(EXT_ZPN) || + p->extension_enabled(EXT_XZBP) || + ((xlen == 64) && p->extension_enabled(EXT_XZBM))); reg_t lo = zext_xlen(RS1) >> (xlen/2); reg_t hi = zext_xlen(RS2) >> (xlen/2) << (xlen/2); WRITE_RD(sext_xlen(lo | hi)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/packuw.h b/vendor/riscv/riscv-isa-sim/riscv/insns/packuw.h index 1156a2b32..1b3f7d5f5 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/packuw.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/packuw.h @@ -1,5 +1,5 @@ require_rv64; -require_extension(EXT_XBITMANIP); +require_extension(EXT_XZBP); reg_t lo = zext32(RS1) >> 16; reg_t hi = zext32(RS2) >> 16 << 16; WRITE_RD(sext32(lo | hi)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/packw.h b/vendor/riscv/riscv-isa-sim/riscv/insns/packw.h index e5be6171c..084c190d0 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/packw.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/packw.h @@ -1,7 +1,9 @@ // RV64Zbb contains zext.h but not general packw require(((insn.rs2() == 0) && p->extension_enabled(EXT_ZBB)) || p->extension_enabled(EXT_ZBKB) - || p->extension_enabled(EXT_XBITMANIP)); + || p->extension_enabled(EXT_XZBP) + || p->extension_enabled(EXT_XZBE) + || p->extension_enabled(EXT_XZBF)); require_rv64; reg_t lo = zext32(RS1 << 16) >> 16; reg_t hi = zext32(RS2 << 16); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/rem.h b/vendor/riscv/riscv-isa-sim/riscv/insns/rem.h index 858799577..d2ee06684 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/rem.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/rem.h @@ -1,9 +1,9 @@ require_extension('M'); sreg_t lhs = sext_xlen(RS1); sreg_t rhs = sext_xlen(RS2); -if(rhs == 0) +if (rhs == 0) WRITE_RD(lhs); -else if(lhs == INT64_MIN && rhs == -1) +else if (lhs == INT64_MIN && rhs == -1) WRITE_RD(0); else WRITE_RD(sext_xlen(lhs % rhs)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/remu.h b/vendor/riscv/riscv-isa-sim/riscv/insns/remu.h index e74774cc2..676747ade 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/remu.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/remu.h @@ -1,7 +1,7 @@ require_extension('M'); reg_t lhs = zext_xlen(RS1); reg_t rhs = zext_xlen(RS2); -if(rhs == 0) +if (rhs == 0) WRITE_RD(sext_xlen(RS1)); else WRITE_RD(sext_xlen(lhs % rhs)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/remuw.h b/vendor/riscv/riscv-isa-sim/riscv/insns/remuw.h index b239c8f32..caa1583ef 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/remuw.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/remuw.h @@ -2,7 +2,7 @@ require_extension('M'); require_rv64; reg_t lhs = zext32(RS1); reg_t rhs = zext32(RS2); -if(rhs == 0) +if (rhs == 0) WRITE_RD(sext32(lhs)); else WRITE_RD(sext32(lhs % rhs)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/remw.h b/vendor/riscv/riscv-isa-sim/riscv/insns/remw.h index 56221ccd4..076096c1f 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/remw.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/remw.h @@ -2,7 +2,7 @@ require_extension('M'); require_rv64; sreg_t lhs = sext32(RS1); sreg_t rhs = sext32(RS2); -if(rhs == 0) +if (rhs == 0) WRITE_RD(lhs); else WRITE_RD(sext32(lhs % rhs)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/rsub64.h b/vendor/riscv/riscv-isa-sim/riscv/insns/rsub64.h index 397c973d4..2a5848519 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/rsub64.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/rsub64.h @@ -2,7 +2,7 @@ P_64_PROFILE({ rd = (rs1 - rs2) >> 1; if (rs1 > 0 && rs2 < 0) { rd &= ~((reg_t)1 << 63); - } else if(rs1 < 0 && rs2 > 0) { + } else if (rs1 < 0 && rs2 > 0) { rd |= ((reg_t)1 << 63); } }) diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/sb.h b/vendor/riscv/riscv-isa-sim/riscv/insns/sb.h index 8729c2d47..d9cc8f9f4 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/sb.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/sb.h @@ -1 +1 @@ -MMU.store_uint8(RS1 + insn.s_imm(), RS2); +MMU.store(RS1 + insn.s_imm(), RS2); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/sc_d.h b/vendor/riscv/riscv-isa-sim/riscv/insns/sc_d.h index 54023ed44..ac82c3ec6 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/sc_d.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/sc_d.h @@ -1,11 +1,6 @@ require_extension('A'); require_rv64; -bool have_reservation = MMU.check_load_reservation(RS1, 8); - -if (have_reservation) - MMU.store_uint64(RS1, RS2); - -MMU.yield_load_reservation(); +bool have_reservation = MMU.store_conditional(RS1, RS2); WRITE_RD(!have_reservation); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/sc_w.h b/vendor/riscv/riscv-isa-sim/riscv/insns/sc_w.h index e430dcb2e..48fea4b5b 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/sc_w.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/sc_w.h @@ -1,10 +1,5 @@ require_extension('A'); -bool have_reservation = MMU.check_load_reservation(RS1, 4); - -if (have_reservation) - MMU.store_uint32(RS1, RS2); - -MMU.yield_load_reservation(); +bool have_reservation = MMU.store_conditional(RS1, RS2); WRITE_RD(!have_reservation); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/sd.h b/vendor/riscv/riscv-isa-sim/riscv/insns/sd.h index 664deb2c9..5c9dd4e1b 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/sd.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/sd.h @@ -1,2 +1,2 @@ require_rv64; -MMU.store_uint64(RS1 + insn.s_imm(), RS2); +MMU.store(RS1 + insn.s_imm(), RS2); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/sfence_inval_ir.h b/vendor/riscv/riscv-isa-sim/riscv/insns/sfence_inval_ir.h index f566d6327..6f76a3ff4 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/sfence_inval_ir.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/sfence_inval_ir.h @@ -1,3 +1,4 @@ require_extension('S'); require_extension(EXT_SVINVAL); require_impl(IMPL_MMU); +require_privilege_hs_qualified(PRV_S); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/sfence_w_inval.h b/vendor/riscv/riscv-isa-sim/riscv/insns/sfence_w_inval.h index f566d6327..d1af529f9 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/sfence_w_inval.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/sfence_w_inval.h @@ -1,3 +1 @@ -require_extension('S'); -require_extension(EXT_SVINVAL); -require_impl(IMPL_MMU); +#include "sfence_inval_ir.h" diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/sh.h b/vendor/riscv/riscv-isa-sim/riscv/insns/sh.h index 22aa3a889..8f780c383 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/sh.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/sh.h @@ -1 +1 @@ -MMU.store_uint16(RS1 + insn.s_imm(), RS2); +MMU.store(RS1 + insn.s_imm(), RS2); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/shfl.h b/vendor/riscv/riscv-isa-sim/riscv/insns/shfl.h index 77a1bd4cb..3004871e2 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/shfl.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/shfl.h @@ -1,4 +1,4 @@ -require_extension(EXT_XBITMANIP); +require_extension(EXT_XZBP); reg_t x = RS1; int shamt = RS2 & ((xlen-1) >> 1); if (shamt & 16) x = (x & 0xFFFF00000000FFFFLL) | ((x & 0x0000FFFF00000000LL) >> 16) | ((x & 0x00000000FFFF0000LL) << 16); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/shfli.h b/vendor/riscv/riscv-isa-sim/riscv/insns/shfli.h index fc786ff73..f8636190f 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/shfli.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/shfli.h @@ -1,6 +1,6 @@ // Zbkb contains zip but not general shfli require(((insn.rs2() == (xlen / 2 - 1)) && p->extension_enabled(EXT_ZBKB)) - || p->extension_enabled(EXT_XBITMANIP)); + || p->extension_enabled(EXT_XZBP)); require(SHAMT < (xlen/2)); reg_t x = RS1; int shamt = SHAMT & ((xlen-1) >> 1); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/shflw.h b/vendor/riscv/riscv-isa-sim/riscv/insns/shflw.h index af89d2c53..06ee36045 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/shflw.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/shflw.h @@ -1,5 +1,5 @@ require_rv64; -require_extension(EXT_XBITMANIP); +require_extension(EXT_XZBP); reg_t x = RS1; int shamt = RS2 & 15; if (shamt & 8) x = (x & 0xFF0000FFFF0000FFLL) | ((x & 0x00FF000000FF0000LL) >> 8) | ((x & 0x0000FF000000FF00LL) << 8); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/slo.h b/vendor/riscv/riscv-isa-sim/riscv/insns/slo.h index 9aa5777ac..a27ec37e2 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/slo.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/slo.h @@ -1,2 +1,2 @@ -require_extension(EXT_XBITMANIP); +require_extension(EXT_XZBP); WRITE_RD(sext_xlen(~((~RS1) << (RS2 & (xlen-1))))); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/sloi.h b/vendor/riscv/riscv-isa-sim/riscv/insns/sloi.h index 17e6936e4..62278b030 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/sloi.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/sloi.h @@ -1,3 +1,3 @@ require(SHAMT < xlen); -require_extension(EXT_XBITMANIP); +require_extension(EXT_XZBP); WRITE_RD(sext_xlen(~((~RS1) << SHAMT))); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/sloiw.h b/vendor/riscv/riscv-isa-sim/riscv/insns/sloiw.h index af25f739e..492c94a11 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/sloiw.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/sloiw.h @@ -1,3 +1,3 @@ require_rv64; -require_extension(EXT_XBITMANIP); +require_extension(EXT_XZBP); WRITE_RD(sext32(~((~RS1) << SHAMT))); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/slow.h b/vendor/riscv/riscv-isa-sim/riscv/insns/slow.h index 6cb1a9cf1..04c90a45d 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/slow.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/slow.h @@ -1,3 +1,3 @@ require_rv64; -require_extension(EXT_XBITMANIP); +require_extension(EXT_XZBP); WRITE_RD(sext32(~((~RS1) << (RS2 & 0x1F)))); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/smul16.h b/vendor/riscv/riscv-isa-sim/riscv/insns/smul16.h index 8f87612d3..7e0f08abb 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/smul16.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/smul16.h @@ -1,3 +1,3 @@ P_MUL_LOOP(16, { - pd = ps1 * ps2; + pd = (int32_t)ps1 * (int32_t)ps2; }) diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/smul8.h b/vendor/riscv/riscv-isa-sim/riscv/insns/smul8.h index 155e50e08..a4a3ed93f 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/smul8.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/smul8.h @@ -1,3 +1,3 @@ P_MUL_LOOP(8, { - pd = ps1 * ps2; + pd = (int16_t)ps1 * (int16_t)ps2; }) diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/smulx16.h b/vendor/riscv/riscv-isa-sim/riscv/insns/smulx16.h index 14ae047f4..58e9a08d0 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/smulx16.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/smulx16.h @@ -1,3 +1,3 @@ P_MUL_CROSS_LOOP(16, { - pd = ps1 * ps2; + pd = (int32_t)ps1 * (int32_t)ps2; }) diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/smulx8.h b/vendor/riscv/riscv-isa-sim/riscv/insns/smulx8.h index b5ae41ca5..9270ce361 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/smulx8.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/smulx8.h @@ -1,3 +1,3 @@ P_MUL_CROSS_LOOP(8, { - pd = ps1 * ps2; + pd = (int16_t)ps1 * (int16_t)ps2; }) diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/sra16_u.h b/vendor/riscv/riscv-isa-sim/riscv/insns/sra16_u.h index c28178e7d..6fcc398f1 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/sra16_u.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/sra16_u.h @@ -1,5 +1,5 @@ P_X_LOOP(16, 4, { - if(sa > 0) + if (sa > 0) pd = ((ps1 >> (sa - 1)) + 1) >> 1; else pd = ps1; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/sra32_u.h b/vendor/riscv/riscv-isa-sim/riscv/insns/sra32_u.h index e062a8865..1a4488c58 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/sra32_u.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/sra32_u.h @@ -1,6 +1,6 @@ require_rv64; P_X_LOOP(32, 5, { - if(sa > 0) + if (sa > 0) pd = (((uint64_t)(ps1 >> (sa - 1))) + 1) >> 1; else pd = ps1; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/sra8_u.h b/vendor/riscv/riscv-isa-sim/riscv/insns/sra8_u.h index 7061fc484..1f47623e8 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/sra8_u.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/sra8_u.h @@ -1,5 +1,5 @@ P_X_LOOP(8, 3, { - if(sa > 0) + if (sa > 0) pd = ((ps1 >> (sa - 1)) + 1) >> 1; else pd = ps1; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/sret.h b/vendor/riscv/riscv-isa-sim/riscv/insns/sret.h index 9dc38e6ba..5102c15cc 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/sret.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/sret.h @@ -16,11 +16,12 @@ s = set_field(s, MSTATUS_SPP, PRV_U); STATE.sstatus->write(s); p->set_privilege(prev_prv); if (!STATE.v) { - reg_t prev_virt = get_field(prev_hstatus, HSTATUS_SPV); - p->set_virt(prev_virt); - - reg_t new_hstatus = set_field(prev_hstatus, HSTATUS_SPV, 0); - STATE.hstatus->write(new_hstatus); + if (p->extension_enabled('H')) { + reg_t prev_virt = get_field(prev_hstatus, HSTATUS_SPV); + p->set_virt(prev_virt); + reg_t new_hstatus = set_field(prev_hstatus, HSTATUS_SPV, 0); + STATE.hstatus->write(new_hstatus); + } STATE.mstatus->write(set_field(STATE.mstatus->read(), MSTATUS_MPRV, 0)); } diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/sro.h b/vendor/riscv/riscv-isa-sim/riscv/insns/sro.h index 4c243f754..3ac050daf 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/sro.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/sro.h @@ -1,2 +1,2 @@ -require_extension(EXT_XBITMANIP); +require_extension(EXT_XZBP); WRITE_RD(sext_xlen(~((zext_xlen(~RS1)) >> (RS2 & (xlen-1))))); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/sroi.h b/vendor/riscv/riscv-isa-sim/riscv/insns/sroi.h index fea997ff3..e87889280 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/sroi.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/sroi.h @@ -1,3 +1,3 @@ require(SHAMT < xlen); -require_extension(EXT_XBITMANIP); +require_extension(EXT_XZBP); WRITE_RD(sext_xlen(~((zext_xlen(~RS1)) >> SHAMT))); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/sroiw.h b/vendor/riscv/riscv-isa-sim/riscv/insns/sroiw.h index 32b4ef916..83480705f 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/sroiw.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/sroiw.h @@ -1,3 +1,3 @@ require_rv64; -require_extension(EXT_XBITMANIP); +require_extension(EXT_XZBP); WRITE_RD(sext32(~((~(uint32_t)RS1) >> SHAMT))); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/srow.h b/vendor/riscv/riscv-isa-sim/riscv/insns/srow.h index d5d673c70..808af8dbb 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/srow.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/srow.h @@ -1,3 +1,3 @@ require_rv64; -require_extension(EXT_XBITMANIP); +require_extension(EXT_XZBP); WRITE_RD(sext32(~((~(uint32_t)RS1) >> (RS2 & 0x1F)))); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/sw.h b/vendor/riscv/riscv-isa-sim/riscv/insns/sw.h index aa5ead372..a9d726895 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/sw.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/sw.h @@ -1 +1 @@ -MMU.store_uint32(RS1 + insn.s_imm(), RS2); +MMU.store(RS1 + insn.s_imm(), RS2); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/umul16.h b/vendor/riscv/riscv-isa-sim/riscv/insns/umul16.h index 860f9420e..09b839ca9 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/umul16.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/umul16.h @@ -1,3 +1,3 @@ P_MUL_ULOOP(16, { - pd = ps1 * ps2; + pd = (uint32_t)ps1 * (uint32_t)ps2; }) diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/umul8.h b/vendor/riscv/riscv-isa-sim/riscv/insns/umul8.h index 04d7a6ef0..29cae8850 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/umul8.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/umul8.h @@ -1,3 +1,3 @@ P_MUL_ULOOP(8, { - pd = ps1 * ps2; + pd = (uint16_t)ps1 * (uint16_t)ps2; }) diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/umulx16.h b/vendor/riscv/riscv-isa-sim/riscv/insns/umulx16.h index 5abe9cf81..3f0cce8ba 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/umulx16.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/umulx16.h @@ -1,3 +1,3 @@ P_MUL_CROSS_ULOOP(16, { - pd = ps1 * ps2; + pd = (uint32_t)ps1 * (uint32_t)ps2; }) diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/umulx8.h b/vendor/riscv/riscv-isa-sim/riscv/insns/umulx8.h index a2b073dee..848b5d588 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/umulx8.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/umulx8.h @@ -1,3 +1,3 @@ P_MUL_CROSS_ULOOP(8, { - pd = ps1 * ps2; + pd = (uint16_t)ps1 * (uint16_t)ps2; }) diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/unshfl.h b/vendor/riscv/riscv-isa-sim/riscv/insns/unshfl.h index 9a8e90fc1..78990b876 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/unshfl.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/unshfl.h @@ -1,4 +1,4 @@ -require_extension(EXT_XBITMANIP); +require_extension(EXT_XZBP); reg_t x = RS1; int shamt = RS2 & ((xlen-1) >> 1); if (shamt & 1) x = (x & 0x9999999999999999LL) | ((x & 0x4444444444444444LL) >> 1) | ((x & 0x2222222222222222LL) << 1); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/unshfli.h b/vendor/riscv/riscv-isa-sim/riscv/insns/unshfli.h index 0053bbb6b..26920f140 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/unshfli.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/unshfli.h @@ -1,6 +1,6 @@ // Zbkb contains unzip but not general unshfli require(((insn.rs2() == (xlen / 2 - 1)) && p->extension_enabled(EXT_ZBKB)) - || p->extension_enabled(EXT_XBITMANIP)); + || p->extension_enabled(EXT_XZBP)); require(SHAMT < (xlen/2)); reg_t x = RS1; int shamt = SHAMT & ((xlen-1) >> 1); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/unshflw.h b/vendor/riscv/riscv-isa-sim/riscv/insns/unshflw.h index 27d637092..776534e74 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/unshflw.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/unshflw.h @@ -1,5 +1,5 @@ require_rv64; -require_extension(EXT_XBITMANIP); +require_extension(EXT_XZBP); reg_t x = RS1; int shamt = RS2 & 15; if (shamt & 1) x = (x & 0x9999999999999999LL) | ((x & 0x4444444444444444LL) >> 1) | ((x & 0x2222222222222222LL) << 1); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/vcpop_m.h b/vendor/riscv/riscv-isa-sim/riscv/insns/vcpop_m.h index cbe45a4b4..671362f72 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/vcpop_m.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/vcpop_m.h @@ -2,8 +2,6 @@ require(P.VU.vsew >= e8 && P.VU.vsew <= e64); require_vector(true); reg_t vl = P.VU.vl->read(); -reg_t sew = P.VU.vsew; -reg_t rd_num = insn.rd(); reg_t rs2_num = insn.rs2(); require(P.VU.vstart->read() == 0); reg_t popcount = 0; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/vdiv_vx.h b/vendor/riscv/riscv-isa-sim/riscv/insns/vdiv_vx.h index 405295270..2b93eace5 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/vdiv_vx.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/vdiv_vx.h @@ -1,9 +1,9 @@ // vdiv.vx vd, vs2, rs1 VI_VX_LOOP ({ - if(rs1 == 0) + if (rs1 == 0) vd = -1; - else if(vs2 == (INT64_MIN >> (64 - sew)) && rs1 == -1) + else if (vs2 == (INT64_MIN >> (64 - sew)) && rs1 == -1) vd = vs2; else vd = vs2 / rs1; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/vdivu_vv.h b/vendor/riscv/riscv-isa-sim/riscv/insns/vdivu_vv.h index ef6e777d6..89aeed625 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/vdivu_vv.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/vdivu_vv.h @@ -1,7 +1,7 @@ // vdivu.vv vd, vs2, vs1 VI_VV_ULOOP ({ - if(vs1 == 0) + if (vs1 == 0) vd = -1; else vd = vs2 / vs1; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/vdivu_vx.h b/vendor/riscv/riscv-isa-sim/riscv/insns/vdivu_vx.h index 7ffe1c680..ce3e9644c 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/vdivu_vx.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/vdivu_vx.h @@ -1,7 +1,7 @@ // vdivu.vx vd, vs2, rs1 VI_VX_ULOOP ({ - if(rs1 == 0) + if (rs1 == 0) vd = -1; else vd = vs2 / rs1; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/vfirst_m.h b/vendor/riscv/riscv-isa-sim/riscv/insns/vfirst_m.h index 5b768ed4d..9ddc82b40 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/vfirst_m.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/vfirst_m.h @@ -2,8 +2,6 @@ require(P.VU.vsew >= e8 && P.VU.vsew <= e64); require_vector(true); reg_t vl = P.VU.vl->read(); -reg_t sew = P.VU.vsew; -reg_t rd_num = insn.rd(); reg_t rs2_num = insn.rs2(); require(P.VU.vstart->read() == 0); reg_t pos = -1; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/vfmv_f_s.h b/vendor/riscv/riscv-isa-sim/riscv/insns/vfmv_f_s.h index 81605eaf1..1ad6bc693 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/vfmv_f_s.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/vfmv_f_s.h @@ -1,7 +1,7 @@ // vfmv_f_s: rd = vs2[0] (rs1=0) require_vector(true); require_fp; -require((P.VU.vsew == e16 && p->extension_enabled(EXT_ZFH)) || +require((P.VU.vsew == e16 && p->extension_enabled(EXT_ZVFH)) || (P.VU.vsew == e32 && p->extension_enabled('F')) || (P.VU.vsew == e64 && p->extension_enabled('D'))); require(STATE.frm->read() < 0x5); @@ -9,7 +9,7 @@ require(STATE.frm->read() < 0x5); reg_t rs2_num = insn.rs2(); uint64_t vs2_0 = 0; const reg_t sew = P.VU.vsew; -switch(sew) { +switch (sew) { case e16: vs2_0 = P.VU.elt(rs2_num, 0); break; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/vfmv_s_f.h b/vendor/riscv/riscv-isa-sim/riscv/insns/vfmv_s_f.h index edc376e8b..4b1b955e5 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/vfmv_s_f.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/vfmv_s_f.h @@ -1,7 +1,7 @@ // vfmv_s_f: vd[0] = rs1 (vs2=0) require_vector(true); require_fp; -require((P.VU.vsew == e16 && p->extension_enabled(EXT_ZFH)) || +require((P.VU.vsew == e16 && p->extension_enabled(EXT_ZVFH)) || (P.VU.vsew == e32 && p->extension_enabled('F')) || (P.VU.vsew == e64 && p->extension_enabled('D'))); require(STATE.frm->read() < 0x5); @@ -11,7 +11,7 @@ reg_t vl = P.VU.vl->read(); if (vl > 0 && P.VU.vstart->read() < vl) { reg_t rd_num = insn.rd(); - switch(P.VU.vsew) { + switch (P.VU.vsew) { case e16: P.VU.elt(rd_num, 0, true) = f16(FRS1).v; break; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/vfncvt_f_f_w.h b/vendor/riscv/riscv-isa-sim/riscv/insns/vfncvt_f_f_w.h index f4996f5df..97de40e27 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/vfncvt_f_f_w.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/vfncvt_f_f_w.h @@ -1,9 +1,7 @@ -// vfncvt.f.f.v vd, vs2, vm +// vfncvt.f.f.w vd, vs2, vm VI_VFP_NCVT_FP_TO_FP( - {;}, // BODY16 - { vd = f32_to_f16(vs2); }, // BODY32 - { vd = f64_to_f32(vs2); }, // BODY64 - {;}, // CHECK16 - { require_extension(EXT_ZFH); }, // CHECK32 - { require_extension('D'); } // CHECK64 + { vd = f32_to_f16(vs2); }, // BODY32 + { vd = f64_to_f32(vs2); }, // BODY64 + { require_extension(EXT_ZVFHMIN); }, // CHECK32 + { require_extension('D'); } // CHECK64 ) diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/vfncvt_f_x_w.h b/vendor/riscv/riscv-isa-sim/riscv/insns/vfncvt_f_x_w.h index d587be265..46f2d92f7 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/vfncvt_f_x_w.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/vfncvt_f_x_w.h @@ -1,10 +1,8 @@ -// vfncvt.f.x.v vd, vs2, vm +// vfncvt.f.x.w vd, vs2, vm VI_VFP_NCVT_INT_TO_FP( - {;}, // BODY16 - { vd = i32_to_f16(vs2); }, // BODY32 - { vd = i64_to_f32(vs2); }, // BODY64 - {;}, // CHECK16 - { require_extension(EXT_ZFH); }, // CHECK32 - { require_extension('F'); }, // CHECK64 - int // sign + { vd = i32_to_f16(vs2); }, // BODY32 + { vd = i64_to_f32(vs2); }, // BODY64 + { require_extension(EXT_ZVFH); }, // CHECK32 + { require_extension('F'); }, // CHECK64 + int // sign ) diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/vfncvt_f_xu_w.h b/vendor/riscv/riscv-isa-sim/riscv/insns/vfncvt_f_xu_w.h index 5e0e34faf..729fb528e 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/vfncvt_f_xu_w.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/vfncvt_f_xu_w.h @@ -1,10 +1,8 @@ -// vfncvt.f.xu.v vd, vs2, vm +// vfncvt.f.xu.w vd, vs2, vm VI_VFP_NCVT_INT_TO_FP( - {;}, // BODY16 - { vd = ui32_to_f16(vs2); }, // BODY32 - { vd = ui64_to_f32(vs2); }, // BODY64 - {;}, // CHECK16 - { require_extension(EXT_ZFH); }, // CHECK32 - { require_extension('F'); }, // CHECK64 - uint // sign + { vd = ui32_to_f16(vs2); }, // BODY32 + { vd = ui64_to_f32(vs2); }, // BODY64 + { require_extension(EXT_ZVFH); }, // CHECK32 + { require_extension('F'); }, // CHECK64 + uint // sign ) diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/vfncvt_rod_f_f_w.h b/vendor/riscv/riscv-isa-sim/riscv/insns/vfncvt_rod_f_f_w.h index 89bdc05fa..93002dc0f 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/vfncvt_rod_f_f_w.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/vfncvt_rod_f_f_w.h @@ -1,15 +1,13 @@ -// vfncvt.rod.f.f.v vd, vs2, vm +// vfncvt.rod.f.f.w vd, vs2, vm VI_VFP_NCVT_FP_TO_FP( - {;}, // BODY16 - { // BODY32 + { // BODY32 softfloat_roundingMode = softfloat_round_odd; vd = f32_to_f16(vs2); }, - { // BODY64 + { // BODY64 softfloat_roundingMode = softfloat_round_odd; vd = f64_to_f32(vs2); }, - {;}, // CHECK16 - { require_extension(EXT_ZFH); }, // CHECK32 - { require_extension('F'); } // CHECK64 + { require_extension(EXT_ZVFH); }, // CHECK32 + { require_extension('F'); } // CHECK64 ) diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/vfncvt_rtz_x_f_w.h b/vendor/riscv/riscv-isa-sim/riscv/insns/vfncvt_rtz_x_f_w.h index 23b4d5e28..ee47e2236 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/vfncvt_rtz_x_f_w.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/vfncvt_rtz_x_f_w.h @@ -3,7 +3,7 @@ VI_VFP_NCVT_FP_TO_INT( { vd = f16_to_i8(vs2, softfloat_round_minMag, true); }, // BODY16 { vd = f32_to_i16(vs2, softfloat_round_minMag, true); }, // BODY32 { vd = f64_to_i32(vs2, softfloat_round_minMag, true); }, // BODY64 - { require_extension(EXT_ZFH); }, // CHECK16 + { require_extension(EXT_ZVFH); }, // CHECK16 { require(p->extension_enabled('F')); }, // CHECK32 { require(p->extension_enabled('D')); }, // CHECK64 int // sign diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/vfncvt_rtz_xu_f_w.h b/vendor/riscv/riscv-isa-sim/riscv/insns/vfncvt_rtz_xu_f_w.h index f55c680ba..3d029f3eb 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/vfncvt_rtz_xu_f_w.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/vfncvt_rtz_xu_f_w.h @@ -3,7 +3,7 @@ VI_VFP_NCVT_FP_TO_INT( { vd = f16_to_ui8(vs2, softfloat_round_minMag, true); }, // BODY16 { vd = f32_to_ui16(vs2, softfloat_round_minMag, true); }, // BODY32 { vd = f64_to_ui32(vs2, softfloat_round_minMag, true); }, // BODY64 - { require_extension(EXT_ZFH); }, // CHECK16 + { require_extension(EXT_ZVFH); }, // CHECK16 { require(p->extension_enabled('F')); }, // CHECK32 { require(p->extension_enabled('D')); }, // CHECK64 uint // sign diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/vfncvt_x_f_w.h b/vendor/riscv/riscv-isa-sim/riscv/insns/vfncvt_x_f_w.h index a7f3c3340..0da5a75f3 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/vfncvt_x_f_w.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/vfncvt_x_f_w.h @@ -3,7 +3,7 @@ VI_VFP_NCVT_FP_TO_INT( { vd = f16_to_i8(vs2, softfloat_roundingMode, true); }, // BODY16 { vd = f32_to_i16(vs2, softfloat_roundingMode, true); }, // BODY32 { vd = f64_to_i32(vs2, softfloat_roundingMode, true); }, // BODY64 - { require_extension(EXT_ZFH); }, // CHECK16 + { require_extension(EXT_ZVFH); }, // CHECK16 { require(p->extension_enabled('F')); }, // CHECK32 { require(p->extension_enabled('D')); }, // CHECK64 int // sign diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/vfncvt_xu_f_w.h b/vendor/riscv/riscv-isa-sim/riscv/insns/vfncvt_xu_f_w.h index 02046e8b9..da5a52d3c 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/vfncvt_xu_f_w.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/vfncvt_xu_f_w.h @@ -3,7 +3,7 @@ VI_VFP_NCVT_FP_TO_INT( { vd = f16_to_ui8(vs2, softfloat_roundingMode, true); }, // BODY16 { vd = f32_to_ui16(vs2, softfloat_roundingMode, true); }, // BODY32 { vd = f64_to_ui32(vs2, softfloat_roundingMode, true); }, // BODY64 - { require_extension(EXT_ZFH); }, // CHECK16 + { require_extension(EXT_ZVFH); }, // CHECK16 { require(p->extension_enabled('F')); }, // CHECK32 { require(p->extension_enabled('D')); }, // CHECK64 uint // sign diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/vfslide1down_vf.h b/vendor/riscv/riscv-isa-sim/riscv/insns/vfslide1down_vf.h index 66eeaccbf..40f3c1815 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/vfslide1down_vf.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/vfslide1down_vf.h @@ -23,13 +23,13 @@ if (i != vl - 1) { } else { switch (P.VU.vsew) { case e16: - P.VU.elt(rd_num, vl - 1, true) = f16(FRS1); + P.VU.elt(rd_num, vl - 1, true) = FRS1_H; break; case e32: - P.VU.elt(rd_num, vl - 1, true) = f32(FRS1); + P.VU.elt(rd_num, vl - 1, true) = FRS1_F; break; case e64: - P.VU.elt(rd_num, vl - 1, true) = f64(FRS1); + P.VU.elt(rd_num, vl - 1, true) = FRS1_D; break; } } diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/vfslide1up_vf.h b/vendor/riscv/riscv-isa-sim/riscv/insns/vfslide1up_vf.h index b9c2817c2..4e4e499ab 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/vfslide1up_vf.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/vfslide1up_vf.h @@ -23,13 +23,13 @@ if (i != 0) { } else { switch (P.VU.vsew) { case e16: - P.VU.elt(rd_num, 0, true) = f16(FRS1); + P.VU.elt(rd_num, 0, true) = FRS1_H; break; case e32: - P.VU.elt(rd_num, 0, true) = f32(FRS1); + P.VU.elt(rd_num, 0, true) = FRS1_F; break; case e64: - P.VU.elt(rd_num, 0, true) = f64(FRS1); + P.VU.elt(rd_num, 0, true) = FRS1_D; break; } } diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/vfwcvt_f_f_v.h b/vendor/riscv/riscv-isa-sim/riscv/insns/vfwcvt_f_f_v.h index 0700070a1..111a231b7 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/vfwcvt_f_f_v.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/vfwcvt_f_f_v.h @@ -1,9 +1,7 @@ // vfwcvt.f.f.v vd, vs2, vm VI_VFP_WCVT_FP_TO_FP( - {;}, // BODY8 - { vd = f16_to_f32(vs2); }, // BODY16 - { vd = f32_to_f64(vs2); }, // BODY32 - {;}, // CHECK8 - { require_extension(EXT_ZFH); }, // CHECK16 - { require_extension('D'); } // CHECK32 + { vd = f16_to_f32(vs2); }, // BODY16 + { vd = f32_to_f64(vs2); }, // BODY32 + { require_extension(EXT_ZVFHMIN); }, // CHECK16 + { require_extension('D'); } // CHECK32 ) diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/vfwcvt_f_x_v.h b/vendor/riscv/riscv-isa-sim/riscv/insns/vfwcvt_f_x_v.h index f51e8e3e9..c7678dcc9 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/vfwcvt_f_x_v.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/vfwcvt_f_x_v.h @@ -1,10 +1,10 @@ // vfwcvt.f.x.v vd, vs2, vm VI_VFP_WCVT_INT_TO_FP( - { vd = i32_to_f16(vs2); }, // BODY8 - { vd = i32_to_f32(vs2); }, // BODY16 - { vd = i32_to_f64(vs2); }, // BODY32 - { require(p->extension_enabled(EXT_ZFH)); }, // CHECK8 - { require_extension('F'); }, // CHECK16 - { require_extension('D'); }, // CHECK32 - int // sign + { vd = i32_to_f16(vs2); }, // BODY8 + { vd = i32_to_f32(vs2); }, // BODY16 + { vd = i32_to_f64(vs2); }, // BODY32 + { require(p->extension_enabled(EXT_ZVFH)); }, // CHECK8 + { require_extension('F'); }, // CHECK16 + { require_extension('D'); }, // CHECK32 + int // sign ) diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/vfwcvt_f_xu_v.h b/vendor/riscv/riscv-isa-sim/riscv/insns/vfwcvt_f_xu_v.h index 7dd497219..e3b7e9f8b 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/vfwcvt_f_xu_v.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/vfwcvt_f_xu_v.h @@ -1,10 +1,10 @@ // vfwcvt.f.xu.v vd, vs2, vm VI_VFP_WCVT_INT_TO_FP( - { vd = ui32_to_f16(vs2); }, // BODY8 - { vd = ui32_to_f32(vs2); }, // BODY16 - { vd = ui32_to_f64(vs2); }, // BODY32 - { require(p->extension_enabled(EXT_ZFH)); }, // CHECK8 - { require_extension('F'); }, // CHECK16 - { require_extension('D'); }, // CHECK32 - uint // sign + { vd = ui32_to_f16(vs2); }, // BODY8 + { vd = ui32_to_f32(vs2); }, // BODY16 + { vd = ui32_to_f64(vs2); }, // BODY32 + { require(p->extension_enabled(EXT_ZVFH)); }, // CHECK8 + { require_extension('F'); }, // CHECK16 + { require_extension('D'); }, // CHECK32 + uint // sign ) diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/vfwcvt_rtz_x_f_v.h b/vendor/riscv/riscv-isa-sim/riscv/insns/vfwcvt_rtz_x_f_v.h index 74e5b9a0d..9caf617db 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/vfwcvt_rtz_x_f_v.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/vfwcvt_rtz_x_f_v.h @@ -1,10 +1,8 @@ // vfwcvt.rtz.x.f.v vd, vs2, vm VI_VFP_WCVT_FP_TO_INT( - {;}, // BODY8 { vd = f16_to_i32(vs2, softfloat_round_minMag, true); }, // BODY16 { vd = f32_to_i64(vs2, softfloat_round_minMag, true); }, // BODY32 - {;}, // CHECK8 - { require_extension(EXT_ZFH); }, // CHECK16 + { require_extension(EXT_ZVFH); }, // CHECK16 { require_extension('F'); }, // CHECK32 int // sign ) diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/vfwcvt_rtz_xu_f_v.h b/vendor/riscv/riscv-isa-sim/riscv/insns/vfwcvt_rtz_xu_f_v.h index 72b8c6eef..a25d84763 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/vfwcvt_rtz_xu_f_v.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/vfwcvt_rtz_xu_f_v.h @@ -1,10 +1,8 @@ // vfwcvt.rtz,xu.f.v vd, vs2, vm VI_VFP_WCVT_FP_TO_INT( - {;}, // BODY8 { vd = f16_to_ui32(vs2, softfloat_round_minMag, true); }, // BODY16 { vd = f32_to_ui64(vs2, softfloat_round_minMag, true); }, // BODY32 - {;}, // CHECK8 - { require_extension(EXT_ZFH); }, // CHECK16 + { require_extension(EXT_ZVFH); }, // CHECK16 { require_extension('F'); }, // CHECK32 uint // sign ) diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/vfwcvt_x_f_v.h b/vendor/riscv/riscv-isa-sim/riscv/insns/vfwcvt_x_f_v.h index 74497f4a4..2d536adba 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/vfwcvt_x_f_v.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/vfwcvt_x_f_v.h @@ -1,10 +1,8 @@ // vfwcvt.x.f.v vd, vs2, vm VI_VFP_WCVT_FP_TO_INT( - {;}, // BODY8 { vd = f16_to_i32(vs2, softfloat_roundingMode, true); }, // BODY16 { vd = f32_to_i64(vs2, softfloat_roundingMode, true); }, // BODY32 - {;}, // CHECK8 - { require_extension(EXT_ZFH); }, // CHECK16 + { require_extension(EXT_ZVFH); }, // CHECK16 { require_extension('F'); }, // CHECK32 int // sign ) diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/vfwcvt_xu_f_v.h b/vendor/riscv/riscv-isa-sim/riscv/insns/vfwcvt_xu_f_v.h index ad96c9c37..37201f5b2 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/vfwcvt_xu_f_v.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/vfwcvt_xu_f_v.h @@ -1,10 +1,8 @@ // vfwcvt.xu.f.v vd, vs2, vm VI_VFP_WCVT_FP_TO_INT( - {;}, // BODY8 { vd = f16_to_ui32(vs2, softfloat_roundingMode, true); }, // BODY16 { vd = f32_to_ui64(vs2, softfloat_roundingMode, true); }, // BODY32 - {;}, // CHECK8 - { require_extension(EXT_ZFH); }, // CHECK16 + { require_extension(EXT_ZVFH); }, // CHECK16 { require_extension('F'); }, // CHECK32 uint // sign ) diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/vid_v.h b/vendor/riscv/riscv-isa-sim/riscv/insns/vid_v.h index c31629154..510132def 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/vid_v.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/vid_v.h @@ -1,11 +1,8 @@ // vmpopc rd, vs2, vm require(P.VU.vsew >= e8 && P.VU.vsew <= e64); require_vector(true); -reg_t vl = P.VU.vl->read(); reg_t sew = P.VU.vsew; reg_t rd_num = insn.rd(); -reg_t rs1_num = insn.rs1(); -reg_t rs2_num = insn.rs2(); require_align(rd_num, P.VU.vflmul); require_vm; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/viota_m.h b/vendor/riscv/riscv-isa-sim/riscv/insns/viota_m.h index f74f2c24f..1ee92295a 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/viota_m.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/viota_m.h @@ -4,7 +4,6 @@ require_vector(true); reg_t vl = P.VU.vl->read(); reg_t sew = P.VU.vsew; reg_t rd_num = insn.rd(); -reg_t rs1_num = insn.rs1(); reg_t rs2_num = insn.rs2(); require(P.VU.vstart->read() == 0); require_vm; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/vmsbf_m.h b/vendor/riscv/riscv-isa-sim/riscv/insns/vmsbf_m.h index 6147f6de3..127587214 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/vmsbf_m.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/vmsbf_m.h @@ -24,7 +24,7 @@ for (reg_t i = P.VU.vstart->read(); i < vl; ++i) { uint64_t res = 0; if (!has_one && !vs2_lsb) { res = 1; - } else if(!has_one && vs2_lsb) { + } else if (!has_one && vs2_lsb) { has_one = true; } vd = (vd & ~mmask) | ((res << mpos) & mmask); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/vmsif_m.h b/vendor/riscv/riscv-isa-sim/riscv/insns/vmsif_m.h index 447813fed..cbcbc2a68 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/vmsif_m.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/vmsif_m.h @@ -23,7 +23,7 @@ for (reg_t i = P.VU.vstart->read(); i < vl; ++i) { uint64_t res = 0; if (!has_one && !vs2_lsb) { res = 1; - } else if(!has_one && vs2_lsb) { + } else if (!has_one && vs2_lsb) { has_one = true; res = 1; } diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/vmsof_m.h b/vendor/riscv/riscv-isa-sim/riscv/insns/vmsof_m.h index b9edcf3bd..9bd4f0c07 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/vmsof_m.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/vmsof_m.h @@ -21,7 +21,7 @@ for (reg_t i = P.VU.vstart->read() ; i < vl; ++i) { if (insn.v_vm() == 1 || (insn.v_vm() == 0 && do_mask)) { uint64_t &vd = P.VU.elt(rd_num, midx, true); uint64_t res = 0; - if(!has_one && vs2_lsb) { + if (!has_one && vs2_lsb) { has_one = true; res = 1; } diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/vmv_s_x.h b/vendor/riscv/riscv-isa-sim/riscv/insns/vmv_s_x.h index b66855bec..23a6b56d3 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/vmv_s_x.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/vmv_s_x.h @@ -8,7 +8,7 @@ if (vl > 0 && P.VU.vstart->read() < vl) { reg_t rd_num = insn.rd(); reg_t sew = P.VU.vsew; - switch(sew) { + switch (sew) { case e8: P.VU.elt(rd_num, 0, true) = RS1; break; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/vmv_x_s.h b/vendor/riscv/riscv-isa-sim/riscv/insns/vmv_x_s.h index 39752f9ba..57a9e1a9a 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/vmv_x_s.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/vmv_x_s.h @@ -1,31 +1,27 @@ -// vmv_x_s: rd = vs2[rs1] +// vmv_x_s: rd = vs2[0] require_vector(true); require(insn.v_vm() == 1); -uint64_t xmask = UINT64_MAX >> (64 - P.get_max_xlen()); -reg_t rs1 = RS1; reg_t sew = P.VU.vsew; reg_t rs2_num = insn.rs2(); +reg_t res; -if (!(rs1 >= 0 && rs1 < (P.VU.get_vlen() / sew))) { - WRITE_RD(0); -} else { - switch(sew) { - case e8: - WRITE_RD(P.VU.elt(rs2_num, rs1)); - break; - case e16: - WRITE_RD(P.VU.elt(rs2_num, rs1)); - break; - case e32: - WRITE_RD(P.VU.elt(rs2_num, rs1)); - break; - case e64: - if (P.get_max_xlen() <= sew) - WRITE_RD(P.VU.elt(rs2_num, rs1) & xmask); - else - WRITE_RD(P.VU.elt(rs2_num, rs1)); - break; - } +switch (sew) { +case e8: + res = P.VU.elt(rs2_num, 0); + break; +case e16: + res = P.VU.elt(rs2_num, 0); + break; +case e32: + res = P.VU.elt(rs2_num, 0); + break; +case e64: + res = P.VU.elt(rs2_num, 0); + break; +default: + abort(); } +WRITE_RD(sext_xlen(res)); + P.VU.vstart->write(0); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/vmvnfr_v.h b/vendor/riscv/riscv-isa-sim/riscv/insns/vmvnfr_v.h index 3604935b6..9c5281047 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/vmvnfr_v.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/vmvnfr_v.h @@ -1,17 +1,17 @@ -// vmv1r.v vd, vs2 -require_vector_novtype(true, true); -const reg_t baseAddr = RS1; +// vmvr.v vd, vs2 +require_vector(true); const reg_t vd = insn.rd(); const reg_t vs2 = insn.rs2(); const reg_t len = insn.rs1() + 1; require_align(vd, len); require_align(vs2, len); const reg_t size = len * P.VU.vlenb; +const reg_t start = P.VU.vstart->read() * (P.VU.vsew >> 3); //register needs one-by-one copy to keep commitlog correct -if (vd != vs2 && P.VU.vstart->read() < size) { - reg_t i = P.VU.vstart->read() / P.VU.vlenb; - reg_t off = P.VU.vstart->read() % P.VU.vlenb; +if (vd != vs2 && start < size) { + reg_t i = start / P.VU.vlenb; + reg_t off = start % P.VU.vlenb; if (off) { memcpy(&P.VU.elt(vd + i, off, true), &P.VU.elt(vs2 + i, off), P.VU.vlenb - off); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/vrem_vv.h b/vendor/riscv/riscv-isa-sim/riscv/insns/vrem_vv.h index 260716a0e..5c58fa499 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/vrem_vv.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/vrem_vv.h @@ -3,7 +3,7 @@ VI_VV_LOOP ({ if (vs1 == 0) vd = vs2; - else if(vs2 == -(((intmax_t)1) << (sew - 1)) && vs1 == -1) + else if (vs2 == -(((intmax_t)1) << (sew - 1)) && vs1 == -1) vd = 0; else { vd = vs2 % vs1; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/vrgather_vi.h b/vendor/riscv/riscv-isa-sim/riscv/insns/vrgather_vi.h index 56e11e16d..85ba621cb 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/vrgather_vi.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/vrgather_vi.h @@ -7,10 +7,6 @@ require_vm; reg_t zimm5 = insn.v_zimm5(); VI_LOOP_BASE - -for (reg_t i = P.VU.vstart->read(); i < vl; ++i) { - VI_LOOP_ELEMENT_SKIP(); - switch (sew) { case e8: P.VU.elt(rd_num, i, true) = zimm5 >= P.VU.vlmax ? 0 : P.VU.elt(rs2_num, zimm5); @@ -25,6 +21,4 @@ for (reg_t i = P.VU.vstart->read(); i < vl; ++i) { P.VU.elt(rd_num, i, true) = zimm5 >= P.VU.vlmax ? 0 : P.VU.elt(rs2_num, zimm5); break; } -} - VI_LOOP_END; diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/vsadd_vi.h b/vendor/riscv/riscv-isa-sim/riscv/insns/vsadd_vi.h index 7e3b652e1..3a8b1d486 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/vsadd_vi.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/vsadd_vi.h @@ -2,7 +2,7 @@ VI_CHECK_SSS(false); VI_LOOP_BASE bool sat = false; -switch(sew) { +switch (sew) { case e8: { VI_PARAMS(e8); vd = sat_add(vs2, vsext(simm5, sew), sat); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/vsadd_vv.h b/vendor/riscv/riscv-isa-sim/riscv/insns/vsadd_vv.h index 60ad5f3ca..d4cfe78a1 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/vsadd_vv.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/vsadd_vv.h @@ -2,7 +2,7 @@ VI_CHECK_SSS(true); VI_LOOP_BASE bool sat = false; -switch(sew) { +switch (sew) { case e8: { VV_PARAMS(e8); vd = sat_add(vs2, vs1, sat); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/vsadd_vx.h b/vendor/riscv/riscv-isa-sim/riscv/insns/vsadd_vx.h index bf68f1514..e5e6c408d 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/vsadd_vx.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/vsadd_vx.h @@ -2,7 +2,7 @@ VI_CHECK_SSS(false); VI_LOOP_BASE bool sat = false; -switch(sew) { +switch (sew) { case e8: { VX_PARAMS(e8); vd = sat_add(vs2, rs1, sat); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/vsetivli.h b/vendor/riscv/riscv-isa-sim/riscv/insns/vsetivli.h index 04900a2ff..f880e96a3 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/vsetivli.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/vsetivli.h @@ -1,2 +1,2 @@ -require_vector_novtype(false, false); +require_vector_novtype(false); WRITE_RD(P.VU.set_vl(insn.rd(), -1, insn.rs1(), insn.v_zimm10())); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/vsetvl.h b/vendor/riscv/riscv-isa-sim/riscv/insns/vsetvl.h index 2969edc6c..4d03542ec 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/vsetvl.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/vsetvl.h @@ -1,2 +1,2 @@ -require_vector_novtype(false, false); +require_vector_novtype(false); WRITE_RD(P.VU.set_vl(insn.rd(), insn.rs1(), RS1, RS2)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/vsetvli.h b/vendor/riscv/riscv-isa-sim/riscv/insns/vsetvli.h index 7b1f1d716..d1f43b571 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/vsetvli.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/vsetvli.h @@ -1,2 +1,2 @@ -require_vector_novtype(false, false); +require_vector_novtype(false); WRITE_RD(P.VU.set_vl(insn.rd(), insn.rs1(), RS1, insn.v_zimm11())); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/vslide1up_vx.h b/vendor/riscv/riscv-isa-sim/riscv/insns/vslide1up_vx.h index 33cb9ed64..256419ead 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/vslide1up_vx.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/vslide1up_vx.h @@ -6,24 +6,24 @@ if (i != 0) { if (sew == e8) { VI_XI_SLIDEUP_PARAMS(e8, 1); vd = vs2; - } else if(sew == e16) { + } else if (sew == e16) { VI_XI_SLIDEUP_PARAMS(e16, 1); vd = vs2; - } else if(sew == e32) { + } else if (sew == e32) { VI_XI_SLIDEUP_PARAMS(e32, 1); vd = vs2; - } else if(sew == e64) { + } else if (sew == e64) { VI_XI_SLIDEUP_PARAMS(e64, 1); vd = vs2; } } else { if (sew == e8) { P.VU.elt(rd_num, 0, true) = RS1; - } else if(sew == e16) { + } else if (sew == e16) { P.VU.elt(rd_num, 0, true) = RS1; - } else if(sew == e32) { + } else if (sew == e32) { P.VU.elt(rd_num, 0, true) = RS1; - } else if(sew == e64) { + } else if (sew == e64) { P.VU.elt(rd_num, 0, true) = RS1; } } diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/vsmul_vv.h b/vendor/riscv/riscv-isa-sim/riscv/insns/vsmul_vv.h index 413981cee..49e42c1fa 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/vsmul_vv.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/vsmul_vv.h @@ -2,27 +2,19 @@ VRM xrm = P.VU.get_vround_mode(); int64_t int_max = INT64_MAX >> (64 - P.VU.vsew); int64_t int_min = INT64_MIN >> (64 - P.VU.vsew); -int64_t sign_mask = uint64_t(1) << (P.VU.vsew - 1); VI_VV_LOOP ({ - int64_t vs1_sign; - int64_t vs2_sign; - int64_t result_sign; - - vs1_sign = vs1 & sign_mask; - vs2_sign = vs2 & sign_mask; bool overflow = vs1 == vs2 && vs1 == int_min; - int128_t result = (int128_t)vs1 * (int128_t)vs2; - result_sign = (vs1_sign ^ vs2_sign) & sign_mask; // rounding INT_ROUNDING(result, xrm, sew - 1); + // remove guard bits result = result >> (sew - 1); - // saturation + // max saturation if (overflow) { result = int_max; P_SET_OV(1); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/vsmul_vx.h b/vendor/riscv/riscv-isa-sim/riscv/insns/vsmul_vx.h index 2e25670dd..d2724eee4 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/vsmul_vx.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/vsmul_vx.h @@ -2,20 +2,11 @@ VRM xrm = P.VU.get_vround_mode(); int64_t int_max = INT64_MAX >> (64 - P.VU.vsew); int64_t int_min = INT64_MIN >> (64 - P.VU.vsew); -int64_t sign_mask = uint64_t(1) << (P.VU.vsew - 1); VI_VX_LOOP ({ - int64_t rs1_sign; - int64_t vs2_sign; - int64_t result_sign; - - rs1_sign = rs1 & sign_mask; - vs2_sign = vs2 & sign_mask; bool overflow = rs1 == vs2 && rs1 == int_min; - int128_t result = (int128_t)rs1 * (int128_t)vs2; - result_sign = (rs1_sign ^ vs2_sign) & sign_mask; // rounding INT_ROUNDING(result, xrm, sew - 1); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/wfi.h b/vendor/riscv/riscv-isa-sim/riscv/insns/wfi.h index 299cb01f5..3411da0ce 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/wfi.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/wfi.h @@ -5,7 +5,9 @@ if (STATE.v && STATE.prv == PRV_U) { } else if (STATE.v) { // VS-mode if (get_field(STATE.hstatus->read(), HSTATUS_VTW)) require_novirt(); -} else { +} else if (p->extension_enabled('S')) { + // When S-mode is implemented, then executing WFI in + // U-mode causes an illegal instruction exception. require_privilege(PRV_S); } wfi(); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/xperm16.h b/vendor/riscv/riscv-isa-sim/riscv/insns/xperm16.h index dee8e9bb5..6b0ad51f0 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/xperm16.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/xperm16.h @@ -1,2 +1,2 @@ -require_extension(EXT_XBITMANIP); +require_extension(EXT_XZBP); WRITE_RD(sext_xlen(xperm(RS1, RS2, 4, xlen))); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/xperm32.h b/vendor/riscv/riscv-isa-sim/riscv/insns/xperm32.h index 78456c43c..64d90a406 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/xperm32.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/xperm32.h @@ -1,3 +1,3 @@ require_rv64; -require_extension(EXT_XBITMANIP); +require_extension(EXT_XZBP); WRITE_RD(xperm(RS1, RS2, 5, xlen)); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/xperm4.h b/vendor/riscv/riscv-isa-sim/riscv/insns/xperm4.h index dab6c4a4e..38800f3bf 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/xperm4.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/xperm4.h @@ -1,2 +1,2 @@ -require_either_extension(EXT_ZBKX, EXT_XBITMANIP); +require_either_extension(EXT_ZBKX, EXT_XZBP); WRITE_RD(sext_xlen(xperm(RS1, RS2, 2, xlen))); diff --git a/vendor/riscv/riscv-isa-sim/riscv/insns/xperm8.h b/vendor/riscv/riscv-isa-sim/riscv/insns/xperm8.h index c0bd05877..c272d6694 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/insns/xperm8.h +++ b/vendor/riscv/riscv-isa-sim/riscv/insns/xperm8.h @@ -1,2 +1,2 @@ -require_either_extension(EXT_ZBKX, EXT_XBITMANIP); +require_either_extension(EXT_ZBKX, EXT_XZBP); WRITE_RD(sext_xlen(xperm(RS1, RS2, 3, xlen))); diff --git a/vendor/riscv/riscv-isa-sim/riscv/interactive.cc b/vendor/riscv/riscv-isa-sim/riscv/interactive.cc index 172cd3335..d9fb39b41 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/interactive.cc +++ b/vendor/riscv/riscv-isa-sim/riscv/interactive.cc @@ -1,9 +1,13 @@ // See LICENSE for license details. +#include "config.h" #include "sim.h" #include "decode.h" +#include "decode_macros.h" #include "disasm.h" #include "mmu.h" +#include "vector_unit.h" +#include "socketif.h" #include #include #include @@ -20,13 +24,45 @@ #include #include +#ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + #define MAX_CMD_STR 40 // maximum possible size of a command line +#define BITS_PER_CHAR 8 #define STR_(X) #X // these definitions allow to use a macro as a string #define STR(X) STR_(X) DECLARE_TRAP(-1, interactive) +static std::vector history_commands; + +// if input an arrow/home key, there will be a 3/4-key input sequence, +// so we use an uint32_t to buffer it +typedef uint32_t keybuffer_t; + +enum KEYCODE +{ + KEYCODE_HEADER0 = 0x1b, + KEYCODE_HEADER1 = 0x1b5b, + KEYCODE_LEFT = 0x1b5b44, + KEYCODE_RIGHT = 0x1b5b43, + KEYCODE_UP = 0x1b5b41, + KEYCODE_DOWN = 0x1b5b42, + KEYCODE_HOME0 = 0x1b5b48, + KEYCODE_HOME1_0 = 0x1b5b31, + KEYCODE_HOME1_1 = 0x1b5b317e, + KEYCODE_END0 = 0x1b5b46, + KEYCODE_END1_0 = 0x1b5b34, + KEYCODE_END1_1 = 0x1b5b347e, + KEYCODE_BACKSPACE0 = 0x8, + KEYCODE_BACKSPACE1_0 = 0x1b5b33, + KEYCODE_BACKSPACE1_1 = 0x1b5b337e, + KEYCODE_BACKSPACE2 = 0x7f, + KEYCODE_ENTER = '\n', +}; + processor_t *sim_t::get_core(const std::string& i) { char *ptr; @@ -36,87 +72,198 @@ processor_t *sim_t::get_core(const std::string& i) return get_core(p); } +static void clear_str(bool noncanonical, int fd, std::string target_str) +{ + if (noncanonical) + { + std::string clear_motion; + clear_motion += '\r'; + for (unsigned i = 0; i < target_str.size(); i++) + { + clear_motion += ' '; + } + clear_motion += '\r'; + if (write(fd, clear_motion.c_str(), clear_motion.size() + 1)) + ; // shut up gcc + } +} + +static void send_key(bool noncanonical, int fd, keybuffer_t key_code, const int len) +{ + if (noncanonical) + { + std::string key_motion; + for (int i = len - 1; i >= 0; i--) + { + key_motion += (char) ((key_code >> (i * BITS_PER_CHAR)) & 0xff); + } + if (write(fd, key_motion.c_str(), len) != len) + ; // shut up gcc + } +} + static std::string readline(int fd) { struct termios tios; + // try to make sure the terminal is noncanonical and nonecho + if (tcgetattr(fd, &tios) == 0) + { + tios.c_lflag &= (~ICANON); + tios.c_lflag &= (~ECHO); + tcsetattr(fd, TCSANOW, &tios); + } bool noncanonical = tcgetattr(fd, &tios) == 0 && (tios.c_lflag & ICANON) == 0; - std::string s; + std::string s_head = std::string("(spike) "); + std::string s = s_head; + keybuffer_t key_buffer = 0; + // index for up/down arrow + size_t history_index = 0; + // position for left/right arrow + size_t cursor_pos = s.size(); + const size_t initial_s_len = cursor_pos; + std::cerr << s << std::flush; for (char ch; read(fd, &ch, 1) == 1; ) { - if (ch == '\x7f') + uint32_t keycode = key_buffer << BITS_PER_CHAR | ch; + switch (keycode) { - if (s.empty()) - continue; - s.erase(s.end()-1); - - if (noncanonical && write(fd, "\b \b", 3) != 3) {} - } - else if (noncanonical && write(fd, &ch, 1) != 1) {} - - if (ch == '\n') - break; - if (ch != '\x7f') - s += ch; - } - return s; -} - -#ifdef HAVE_BOOST_ASIO -// read input command string -std::string sim_t::rin(boost::asio::streambuf *bout_ptr) { - std::string s; - if (acceptor_ptr) { // if we are listening, get commands from socket - try { - socket_ptr.reset(new boost::asio::ip::tcp::socket(*io_service_ptr)); - acceptor_ptr->accept(*socket_ptr); // wait for someone to open connection - boost::asio::streambuf buf; - boost::asio::read_until(*socket_ptr, buf, "\n"); // wait for command - s = boost::asio::buffer_cast(buf.data()); - boost::erase_all(s, "\r"); // get rid off any cr and lf - boost::erase_all(s, "\n"); - // The socket client is a web server and it appends the IP of the computer - // that sent the command from its web browser. - - // For now, erase the IP if it is there. - boost::regex re(" ((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}" - "(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])$"); - s = boost::regex_replace(s, re, (std::string)""); - - // TODO: check the IP against the IP used to upload RISC-V source files - } catch (std::exception& e) { - std::cerr << e.what() << std::endl; - } - // output goes to socket - sout_.rdbuf(bout_ptr); - } else { // if we are not listening on a socket, get commands from terminal - std::cerr << ": " << std::flush; - s = readline(2); // 2 is stderr, but when doing reads it reverts to stdin - // output goes to stderr - sout_.rdbuf(std::cerr.rdbuf()); - } - return s; -} - -// write sout_ to socket (via bout) -void sim_t::wout(boost::asio::streambuf *bout_ptr) { - if (!cmd_file && acceptor_ptr) { // only if we are not getting command inputs from a file - // and if a socket has been created - try { - boost::system::error_code ignored_error; - boost::asio::write(*socket_ptr, *bout_ptr, boost::asio::transfer_all(), ignored_error); - socket_ptr->close(); // close the socket after each command input/ouput - // This is need to in order to make the socket interface - // acessible by HTTP GET via a socket client in a web server. - } catch (std::exception& e) { - std::cerr << e.what() << std::endl; + // the partial keycode, add to the key_buffer + case KEYCODE_HEADER0: + case KEYCODE_HEADER1: + case KEYCODE_HOME1_0: + case KEYCODE_END1_0: + case KEYCODE_BACKSPACE1_0: + key_buffer = keycode; + break; + // for backspace key + case KEYCODE_BACKSPACE0: + case KEYCODE_BACKSPACE1_1: + case KEYCODE_BACKSPACE2: + if (cursor_pos <= initial_s_len) + continue; + clear_str(noncanonical, fd, s); + cursor_pos--; + s.erase(cursor_pos, 1); + if (noncanonical && write(fd, s.c_str(), s.size() + 1) != 1) + ; // shut up gcc + // move cursor by left arrow key + for (unsigned i = 0; i < s.size() - cursor_pos; i++) { + send_key(noncanonical, fd, KEYCODE_LEFT, 3); + } + key_buffer = 0; + break; + case KEYCODE_HOME0: + case KEYCODE_HOME1_1: + // move cursor by left arrow key + for (unsigned i = 0; i < cursor_pos - initial_s_len; i++) { + send_key(noncanonical, fd, KEYCODE_LEFT, 3); + } + cursor_pos = initial_s_len; + key_buffer = 0; + break; + case KEYCODE_END0: + case KEYCODE_END1_1: + // move cursor by right arrow key + for (unsigned i = 0; i < s.size() - cursor_pos; i++) { + send_key(noncanonical, fd, KEYCODE_RIGHT, 3); + } + cursor_pos = s.size(); + key_buffer = 0; + break; + case KEYCODE_UP: + // up arrow + if (history_commands.size() > 0) { + clear_str(noncanonical, fd, s); + history_index = std::min(history_commands.size(), history_index + 1); + s = history_commands[history_commands.size() - history_index]; + if (noncanonical && write(fd, s.c_str(), s.size() + 1)) + ; // shut up gcc + cursor_pos = s.size(); + } + key_buffer = 0; + break; + case KEYCODE_DOWN: + // down arrow + if (history_commands.size() > 0) { + clear_str(noncanonical, fd, s); + history_index = std::max(0, (int)history_index - 1); + if (history_index == 0) { + s = s_head; + } else { + s = history_commands[history_commands.size() - history_index]; + } + if (noncanonical && write(fd, s.c_str(), s.size() + 1)) + ; // shut up gcc + cursor_pos = s.size(); + } + key_buffer = 0; + break; + case KEYCODE_LEFT: + if (s.size() > initial_s_len) { + cursor_pos = cursor_pos - 1; + if ((int)cursor_pos < (int)initial_s_len) { + cursor_pos = initial_s_len; + } else { + send_key(noncanonical, fd, KEYCODE_LEFT, 3); + } + } + key_buffer = 0; + break; + case KEYCODE_RIGHT: + if (s.size() > initial_s_len) { + cursor_pos = cursor_pos + 1; + if (cursor_pos > s.size()) { + cursor_pos = s.size(); + } else { + send_key(noncanonical, fd, KEYCODE_RIGHT, 3); + } + } + key_buffer = 0; + break; + case KEYCODE_ENTER: + if (noncanonical && write(fd, &ch, 1) != 1) + ; // shut up gcc + if (s.size() > initial_s_len && (history_commands.size() == 0 || s != history_commands[history_commands.size() - 1])) { + history_commands.push_back(s); + } + return s.substr(initial_s_len); + default: + DEFAULT_KEY: + // unknown buffered key, do nothing + if (key_buffer != 0) { + key_buffer = 0; + break; + } + clear_str(noncanonical, fd, s); + s.insert(cursor_pos, 1, ch); + cursor_pos++; + if (noncanonical && write(fd, s.c_str(), s.size() + 1) != 1) + ; // shut up gcc + // send left arrow key to move cursor + for (unsigned i = 0; i < s.size() - cursor_pos; i++) { + send_key(noncanonical, fd, KEYCODE_LEFT, 3); + } + break; } } + return s.substr(initial_s_len); } -#endif void sim_t::interactive() { + if (ctrlc_pressed) { + next_interactive_action = std::nullopt; + ctrlc_pressed = false; + } + + if (next_interactive_action.has_value()) { + ctrlc_pressed = false; + auto f = next_interactive_action.value(); + next_interactive_action = std::nullopt; + return f(); + } + typedef void (sim_t::*interactive_func)(const std::string&, const std::vector&); std::map funcs; @@ -130,11 +277,15 @@ void sim_t::interactive() funcs["fregs"] = &sim_t::interactive_fregs; funcs["fregd"] = &sim_t::interactive_fregd; funcs["pc"] = &sim_t::interactive_pc; + funcs["priv"] = &sim_t::interactive_priv; funcs["mem"] = &sim_t::interactive_mem; funcs["str"] = &sim_t::interactive_str; + funcs["mtime"] = &sim_t::interactive_mtime; + funcs["mtimecmp"] = &sim_t::interactive_mtimecmp; funcs["until"] = &sim_t::interactive_until_silent; funcs["untiln"] = &sim_t::interactive_until_noisy; funcs["while"] = &sim_t::interactive_until_silent; + funcs["dump"] = &sim_t::interactive_dumpmems; funcs["quit"] = &sim_t::interactive_quit; funcs["q"] = funcs["quit"]; funcs["help"] = &sim_t::interactive_help; @@ -142,26 +293,26 @@ void sim_t::interactive() while (!done()) { -#ifdef HAVE_BOOST_ASIO - boost::asio::streambuf bout; // socket output -#endif std::string s; char cmd_str[MAX_CMD_STR+1]; // only used for following fscanf // first get commands from file, if cmd_file has been set if (cmd_file && !feof(cmd_file) && fscanf(cmd_file,"%" STR(MAX_CMD_STR) "[^\n]\n", cmd_str)==1) { // up to MAX_CMD_STR characters before \n, skipping \n - s = cmd_str; - // while we get input from file, output goes to stderr - sout_.rdbuf(std::cerr.rdbuf()); + s = cmd_str; + // while we get input from file, output goes to stderr + sout_.rdbuf(std::cerr.rdbuf()); } else { - // when there are no commands left from file or if there was no file from the beginning - cmd_file = NULL; // mark file pointer as being not valid, so any method can test this easily + // when there are no commands left from file or if there was no file from the beginning + cmd_file = NULL; // mark file pointer as being not valid, so any method can test this easily #ifdef HAVE_BOOST_ASIO - s = rin(&bout); // get command string from socket or terminal -#else - std::cerr << ": " << std::flush; - s = readline(2); // 2 is stderr, but when doing reads it reverts to stdin + if (socketif) { + s = socketif->rin(sout_); // get command string from socket or terminal + } + else #endif + { + s = readline(2); // 2 is stderr, but when doing reads it reverts to stdin + } } std::stringstream ss(s); @@ -173,9 +324,10 @@ void sim_t::interactive() set_procs_debug(true); step(1); #ifdef HAVE_BOOST_ASIO - wout(&bout); // socket output, if required + if (socketif) + socketif->wout(); // socket output, if required #endif - continue; + break; } while (ss >> tmp) @@ -193,8 +345,12 @@ void sim_t::interactive() out << "Bad or missing arguments for command " << cmd << std::endl; } #ifdef HAVE_BOOST_ASIO - wout(&bout); // socket output, if required + if (socketif) + socketif->wout(); // socket output, if required #endif + + if (next_interactive_action.has_value()) + break; } ctrlc_pressed = false; } @@ -211,15 +367,21 @@ void sim_t::interactive_help(const std::string& cmd, const std::vector # Display double precision in \n" "vreg [reg] # Display vector [reg] (all if omitted) in \n" "pc # Show current PC in \n" - "mem # Show contents of physical memory\n" - "str # Show NUL-terminated C string at in core \n" + "priv # Show current privilege level in \n" + "mem [core] # Show contents of virtual memory in [core] (physical memory if omitted)\n" + "str [core] # Show NUL-terminated C string at virtual address in [core] (physical address if omitted)\n" + "dump # Dump physical memory to binary files\n" + "mtime # Show mtime\n" + "mtimecmp # Show mtimecmp for \n" "until reg # Stop when in hits \n" + "untiln reg # Run noisy and stop when in hits \n" "until pc # Stop when PC in hits \n" "untiln pc # Run noisy and stop when PC in hits \n" - "until mem # Stop when memory becomes \n" + "until mem [core] # Stop when virtual memory in [core] (physical address if omitted) becomes \n" + "untiln mem [core] # Run noisy and stop when virtual memory in [core] (physical address if omitted) becomes \n" "while reg # Run while in is \n" "while pc # Run while PC in is \n" - "while mem # Run while memory is \n" + "while mem [core] # Run while virtual memory in [core] (physical memory if omitted) is \n" "run [count] # Resume noisy execution (until CTRL+C, or [count] insns)\n" "r [count] Alias for run\n" "rs [count] # Resume silent execution (until CTRL+C, or [count] insns)\n" @@ -244,11 +406,17 @@ void sim_t::interactive_run_silent(const std::string& cmd, const std::vector& args, bool noisy) { size_t steps = args.size() ? atoll(args[0].c_str()) : -1; - ctrlc_pressed = false; set_procs_debug(noisy); - for (size_t i = 0; i < steps && !ctrlc_pressed && !done(); i++) + + const size_t actual_steps = std::min(INTERLEAVE, steps); + for (size_t i = 0; i < actual_steps && !ctrlc_pressed && !done(); i++) step(1); + if (actual_steps < steps) { + next_interactive_action = [=](){ interactive_run(cmd, {std::to_string(steps - actual_steps)}, noisy); }; + return; + } + std::ostream out(sout_.rdbuf()); if (!noisy) out << ":" << std::endl; } @@ -269,17 +437,27 @@ reg_t sim_t::get_pc(const std::vector& args) void sim_t::interactive_pc(const std::string& cmd, const std::vector& args) { - if(args.size() != 1) + if (args.size() != 1) throw trap_interactive(); processor_t *p = get_core(args[0]); - int max_xlen = p->get_max_xlen(); + int max_xlen = p->get_isa().get_max_xlen(); std::ostream out(sout_.rdbuf()); out << std::hex << std::setfill('0') << "0x" << std::setw(max_xlen/4) << zext(get_pc(args), max_xlen) << std::endl; } +void sim_t::interactive_priv(const std::string& cmd, const std::vector& args) +{ + if (args.size() != 1) + throw trap_interactive(); + + processor_t *p = get_core(args[0]); + std::ostream out(sout_.rdbuf()); + out << p->get_privilege_string() << std::endl; +} + reg_t sim_t::get_reg(const std::vector& args) { if (args.size() != 2) @@ -305,19 +483,33 @@ reg_t sim_t::get_reg(const std::vector& args) return p->get_state()->XPR[r]; } -freg_t sim_t::get_freg(const std::vector& args) +freg_t sim_t::get_freg(const std::vector& args, int size) { - if(args.size() != 2) + if (args.size() != 2) throw trap_interactive(); processor_t *p = get_core(args[0]); - int r = std::find(fpr_name, fpr_name + NFPR, args[1]) - fpr_name; - if (r == NFPR) - r = atoi(args[1].c_str()); - if (r >= NFPR) - throw trap_interactive(); - - return p->get_state()->FPR[r]; + if (p->extension_enabled(EXT_ZFINX)) { + int r = std::find(xpr_name, xpr_name + NXPR, args[1]) - xpr_name; + if (r == NXPR) + r = atoi(args[1].c_str()); + if (r >= NXPR) + throw trap_interactive(); + if ((p->get_xlen() == 32) && (size == 64)) { + if (r % 2 != 0) + throw trap_interactive(); + return freg(f64(r== 0 ? reg_t(0) : (READ_REG(r + 1) << 32) + zext32(READ_REG(r)))); + } else { //xlen >= size + return {p->get_state()->XPR[r] | ~(((uint64_t)-1) >> (64 - size)) ,(uint64_t)-1}; + } + } else { + int r = std::find(fpr_name, fpr_name + NFPR, args[1]) - fpr_name; + if (r == NFPR) + r = atoi(args[1].c_str()); + if (r >= NFPR) + throw trap_interactive(); + return p->get_state()->FPR[r]; + } } void sim_t::interactive_vreg(const std::string& cmd, const std::vector& args) @@ -347,9 +539,9 @@ void sim_t::interactive_vreg(const std::string& cmd, const std::vector= 0; --e){ + for (int e = num_elem-1; e >= 0; --e) { uint64_t val; - switch(elen){ + switch (elen) { case 8: val = p->VU.elt(r, e); out << std::dec << "[" << e << "]: 0x" << std::hex << std::setfill ('0') << std::setw(16) << val << " "; @@ -372,14 +564,13 @@ void sim_t::interactive_vreg(const std::string& cmd, const std::vector& args) { if (args.size() < 1) - throw trap_interactive(); + throw trap_interactive(); processor_t *p = get_core(args[0]); - int max_xlen = p->get_max_xlen(); + int max_xlen = p->get_isa().get_max_xlen(); std::ostream out(sout_.rdbuf()); out << std::hex; @@ -389,14 +580,14 @@ void sim_t::interactive_reg(const std::string& cmd, const std::vectorget_state()->XPR[r], max_xlen); + << ": 0x" << std::setfill('0') << std::setw(max_xlen/4) + << zext(p->get_state()->XPR[r], max_xlen); if ((r + 1) % 4 == 0) out << std::endl; } } else { - out << "0x" << std::setfill('0') << std::setw(max_xlen/4) - << zext(get_reg(args), max_xlen) << std::endl; + out << "0x" << std::setfill('0') << std::setw(max_xlen/4) + << zext(get_reg(args), max_xlen) << std::endl; } } @@ -409,7 +600,7 @@ union fpr void sim_t::interactive_freg(const std::string& cmd, const std::vector& args) { - freg_t r = get_freg(args); + freg_t r = get_freg(args, 64); std::ostream out(sout_.rdbuf()); out << std::hex << "0x" << std::setfill ('0') << std::setw(16) << r.v[1] << std::setw(16) << r.v[0] << std::endl; @@ -418,7 +609,7 @@ void sim_t::interactive_freg(const std::string& cmd, const std::vector& args) { fpr f; - f.r = freg(f16_to_f32(f16(get_freg(args)))); + f.r = freg(f16_to_f32(f16(get_freg(args, 16)))); std::ostream out(sout_.rdbuf()); out << (isBoxedF32(f.r) ? (double)f.s : NAN) << std::endl; @@ -427,7 +618,7 @@ void sim_t::interactive_fregh(const std::string& cmd, const std::vector& args) { fpr f; - f.r = get_freg(args); + f.r = get_freg(args, 32); std::ostream out(sout_.rdbuf()); out << (isBoxedF32(f.r) ? (double)f.s : NAN) << std::endl; @@ -436,7 +627,7 @@ void sim_t::interactive_fregs(const std::string& cmd, const std::vector& args) { fpr f; - f.r = get_freg(args); + f.r = get_freg(args, 64); std::ostream out(sout_.rdbuf()); out << (isBoxedF64(f.r) ? f.d : NAN) << std::endl; @@ -460,20 +651,20 @@ reg_t sim_t::get_mem(const std::vector& args) if (addr == LONG_MAX) addr = strtoul(addr_str.c_str(),NULL,16); - switch(addr % 8) + switch (addr % 8) { case 0: - val = mmu->load_uint64(addr); + val = mmu->load(addr); break; case 4: - val = mmu->load_uint32(addr); + val = mmu->load(addr); break; case 2: case 6: - val = mmu->load_uint16(addr); + val = mmu->load(addr); break; default: - val = mmu->load_uint8(addr); + val = mmu->load(addr); break; } return val; @@ -481,7 +672,7 @@ reg_t sim_t::get_mem(const std::vector& args) void sim_t::interactive_mem(const std::string& cmd, const std::vector& args) { - int max_xlen = procs[0]->get_max_xlen(); + int max_xlen = procs[0]->get_isa().get_max_xlen(); std::ostream out(sout_.rdbuf()); out << std::hex << "0x" << std::setfill('0') << std::setw(max_xlen/4) @@ -507,7 +698,7 @@ void sim_t::interactive_str(const std::string& cmd, const std::vectorload_uint8(addr++))) + while ((ch = mmu->load(addr++))) out << ch; out << std::endl; @@ -541,7 +732,7 @@ void sim_t::interactive_until(const std::string& cmd, const std::vectorget_max_xlen(); + int max_xlen = procs[strtol(args[1].c_str(),NULL,10)]->get_isa().get_max_xlen(); if (max_xlen == 32) val &= 0xFFFFFFFF; std::vector args2; @@ -555,9 +746,7 @@ void sim_t::interactive_until(const std::string& cmd, const std::vector& args) +{ + for (unsigned i = 0; i < mems.size(); i++) { + std::stringstream mem_fname; + mem_fname << "mem.0x" << std::hex << mems[i].first << ".bin"; + + std::ofstream mem_file(mem_fname.str()); + mems[i].second->dump(mem_file); + mem_file.close(); + } +} + +void sim_t::interactive_mtime(const std::string& cmd, const std::vector& args) +{ + std::ostream out(sout_.rdbuf()); + out << std::hex << std::setfill('0') << "0x" << std::setw(16) + << clint->get_mtime() << std::endl; +} + +void sim_t::interactive_mtimecmp(const std::string& cmd, const std::vector& args) +{ + if (args.size() != 1) + throw trap_interactive(); + + processor_t *p = get_core(args[0]); + std::ostream out(sout_.rdbuf()); + out << std::hex << std::setfill('0') << "0x" << std::setw(16) + << clint->get_mtimecmp(p->get_id()) << std::endl; +} + diff --git a/vendor/riscv/riscv-isa-sim/riscv/isa_parser.cc b/vendor/riscv/riscv-isa-sim/riscv/isa_parser.cc new file mode 100644 index 000000000..7335a147e --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/isa_parser.cc @@ -0,0 +1,334 @@ +#include "isa_parser.h" +#include "extension.h" + +static std::string strtolower(const char* str) +{ + std::string res; + for (const char *r = str; *r; r++) + res += std::tolower(*r); + return res; +} + +static void bad_option_string(const char *option, const char *value, + const char *msg) +{ + fprintf(stderr, "error: bad %s option '%s'. %s\n", option, value, msg); + abort(); +} + +static void bad_isa_string(const char* isa, const char* msg) +{ + bad_option_string("--isa", isa, msg); +} + +static void bad_priv_string(const char* priv) +{ + fprintf(stderr, "error: bad --priv option %s\n", priv); + abort(); +} + +isa_parser_t::isa_parser_t(const char* str, const char *priv) +{ + isa_string = strtolower(str); + const char* all_subsets = "mafdqchpv"; + + if (isa_string.compare(0, 4, "rv32") == 0) + max_xlen = 32; + else if (isa_string.compare(0, 4, "rv64") == 0) + max_xlen = 64; + else + bad_isa_string(str, "ISA strings must begin with RV32 or RV64"); + + switch (isa_string[4]) { + case 'g': + // G = IMAFD_Zicsr_Zifencei, but Spike includes the latter two + // unconditionally, so they need not be explicitly added here. + isa_string = isa_string.substr(0, 4) + "imafd" + isa_string.substr(5); + // Fall through + case 'i': + extension_table['I'] = true; + break; + + case 'e': + extension_table['E'] = true; + break; + + default: + bad_isa_string(str, ("'" + isa_string.substr(0, 4) + "' must be followed by I, E, or G").c_str()); + } + + const char* isa_str = isa_string.c_str(); + auto p = isa_str, subset = all_subsets; + for (p += 5; islower(*p) && !strchr("zsx", *p); ++p) { + while (*subset && (*p != *subset)) + ++subset; + + if (!*subset) { + if (strchr(all_subsets, *p)) + bad_isa_string(str, ("Extension '" + std::string(1, *p) + "' appears too late in ISA string").c_str()); + else + bad_isa_string(str, ("Unsupported extension '" + std::string(1, *p) + "'").c_str()); + } + + switch (*p) { + case 'p': extension_table[EXT_ZBPBO] = true; + extension_table[EXT_ZPN] = true; + extension_table[EXT_ZPSFOPERAND] = true; + extension_table[EXT_ZMMUL] = true; break; + case 'v': // even rv32iv implies double float + case 'q': extension_table['D'] = true; + // Fall through + case 'd': extension_table['F'] = true; + } + extension_table[toupper(*p)] = true; + while (isdigit(*(p + 1))) { + ++p; // skip major version, point, and minor version if presented + if (*(p + 1) == 'p') ++p; + } + p += *(p + 1) == '_'; // underscores may be used to improve readability + } + + while (islower(*p) || (*p == '_')) { + p += *p == '_'; // first underscore is optional + auto end = p; + do ++end; while (*end && *end != '_'); + auto ext_str = std::string(p, end); + if (ext_str == "zfh" || ext_str == "zfhmin") { + if (!extension_table['F']) + bad_isa_string(str, ("'" + ext_str + "' extension requires 'F'").c_str()); + extension_table[EXT_ZFHMIN] = true; + if (ext_str == "zfh") + extension_table[EXT_ZFH] = true; + } else if (ext_str == "zvfh" || ext_str == "zvfhmin") { + if (!extension_table['V']) + bad_isa_string(str, ("'" + ext_str + "' extension requires 'V'").c_str()); + + extension_table[EXT_ZVFHMIN] = true; + + if (ext_str == "zvfh") { + extension_table[EXT_ZVFH] = true; + // Zvfh implies Zfhmin + extension_table[EXT_ZFHMIN] = true; + } + } else if (ext_str == "zicsr") { + // Spike necessarily has Zicsr, because + // Zicsr is implied by the privileged architecture + } else if (ext_str == "zifencei") { + // For compatibility with version 2.0 of the base ISAs, we + // unconditionally include FENCE.I, so Zifencei adds nothing more. + } else if (ext_str == "zihintpause") { + // HINTs encoded in base-ISA instructions are always present. + } else if (ext_str == "zihintntl") { + // HINTs encoded in base-ISA instructions are always present. + } else if (ext_str == "zmmul") { + extension_table[EXT_ZMMUL] = true; + } else if (ext_str == "zba") { + extension_table[EXT_ZBA] = true; + } else if (ext_str == "zbb") { + extension_table[EXT_ZBB] = true; + } else if (ext_str == "zbc") { + extension_table[EXT_ZBC] = true; + } else if (ext_str == "zbs") { + extension_table[EXT_ZBS] = true; + } else if (ext_str == "zbkb") { + extension_table[EXT_ZBKB] = true; + } else if (ext_str == "zbkc") { + extension_table[EXT_ZBKC] = true; + } else if (ext_str == "zbkx") { + extension_table[EXT_ZBKX] = true; + } else if (ext_str == "zdinx") { + extension_table[EXT_ZFINX] = true; + extension_table[EXT_ZDINX] = true; + } else if (ext_str == "zfinx") { + extension_table[EXT_ZFINX] = true; + } else if (ext_str == "zhinx") { + extension_table[EXT_ZFINX] = true; + extension_table[EXT_ZHINX] = true; + extension_table[EXT_ZHINXMIN] = true; + } else if (ext_str == "zhinxmin") { + extension_table[EXT_ZFINX] = true; + extension_table[EXT_ZHINXMIN] = true; + } else if (ext_str == "zce") { + extension_table[EXT_ZCA] = true; + extension_table[EXT_ZCB] = true; + extension_table[EXT_ZCMT] = true; + extension_table[EXT_ZCMP] = true; + if (extension_table['F'] && max_xlen == 32) + extension_table[EXT_ZCF] = true; + } else if (ext_str == "zca") { + extension_table[EXT_ZCA] = true; + } else if (ext_str == "zcf") { + if (max_xlen != 32) + bad_isa_string(str, "'Zcf' requires RV32"); + extension_table[EXT_ZCF] = true; + } else if (ext_str == "zcb") { + extension_table[EXT_ZCB] = true; + } else if (ext_str == "zcd") { + extension_table[EXT_ZCD] = true; + } else if (ext_str == "zcmp") { + extension_table[EXT_ZCMP] = true; + } else if (ext_str == "zcmt") { + extension_table[EXT_ZCMT] = true; + } else if (ext_str == "zk") { + extension_table[EXT_ZBKB] = true; + extension_table[EXT_ZBKC] = true; + extension_table[EXT_ZBKX] = true; + extension_table[EXT_ZKND] = true; + extension_table[EXT_ZKNE] = true; + extension_table[EXT_ZKNH] = true; + extension_table[EXT_ZKR] = true; + } else if (ext_str == "zkn") { + extension_table[EXT_ZBKB] = true; + extension_table[EXT_ZBKC] = true; + extension_table[EXT_ZBKX] = true; + extension_table[EXT_ZKND] = true; + extension_table[EXT_ZKNE] = true; + extension_table[EXT_ZKNH] = true; + } else if (ext_str == "zknd") { + extension_table[EXT_ZKND] = true; + } else if (ext_str == "zkne") { + extension_table[EXT_ZKNE] = true; + } else if (ext_str == "zknh") { + extension_table[EXT_ZKNH] = true; + } else if (ext_str == "zks") { + extension_table[EXT_ZBKB] = true; + extension_table[EXT_ZBKC] = true; + extension_table[EXT_ZBKX] = true; + extension_table[EXT_ZKSED] = true; + extension_table[EXT_ZKSH] = true; + } else if (ext_str == "zksed") { + extension_table[EXT_ZKSED] = true; + } else if (ext_str == "zksh") { + extension_table[EXT_ZKSH] = true; + } else if (ext_str == "zkr") { + extension_table[EXT_ZKR] = true; + } else if (ext_str == "zkt") { + } else if (ext_str == "smepmp") { + extension_table[EXT_SMEPMP] = true; + } else if (ext_str == "smstateen") { + extension_table[EXT_SMSTATEEN] = true; + } else if (ext_str == "smrnmi") { + extension_table[EXT_SMRNMI] = true; + } else if (ext_str == "sscofpmf") { + extension_table[EXT_SSCOFPMF] = true; + } else if (ext_str == "svadu") { + extension_table[EXT_SVADU] = true; + } else if (ext_str == "svnapot") { + extension_table[EXT_SVNAPOT] = true; + } else if (ext_str == "svpbmt") { + extension_table[EXT_SVPBMT] = true; + } else if (ext_str == "svinval") { + extension_table[EXT_SVINVAL] = true; + } else if (ext_str == "zfa") { + extension_table[EXT_ZFA] = true; + } else if (ext_str == "zicbom") { + extension_table[EXT_ZICBOM] = true; + } else if (ext_str == "zicboz") { + extension_table[EXT_ZICBOZ] = true; + } else if (ext_str == "zicbop") { + } else if (ext_str == "zicntr") { + extension_table[EXT_ZICNTR] = true; + } else if (ext_str == "zicond") { + extension_table[EXT_ZICOND] = true; + } else if (ext_str == "zihpm") { + extension_table[EXT_ZIHPM] = true; + } else if (ext_str == "sstc") { + extension_table[EXT_SSTC] = true; + } else if (ext_str[0] == 'x') { + extension_table['X'] = true; + if (ext_str == "xbitmanip") { + extension_table[EXT_XZBP] = true; + extension_table[EXT_XZBS] = true; + extension_table[EXT_XZBE] = true; + extension_table[EXT_XZBF] = true; + extension_table[EXT_XZBC] = true; + extension_table[EXT_XZBM] = true; + extension_table[EXT_XZBR] = true; + extension_table[EXT_XZBT] = true; + } else if (ext_str == "xzbp") { + extension_table[EXT_XZBP] = true; + } else if (ext_str == "xzbs") { + extension_table[EXT_XZBS] = true; + } else if (ext_str == "xzbe") { + extension_table[EXT_XZBE] = true; + } else if (ext_str == "xzbf") { + extension_table[EXT_XZBF] = true; + } else if (ext_str == "xzbc") { + extension_table[EXT_XZBC] = true; + } else if (ext_str == "xzbm") { + extension_table[EXT_XZBM] = true; + } else if (ext_str == "xzbr") { + extension_table[EXT_XZBR] = true; + } else if (ext_str == "xzbt") { + extension_table[EXT_XZBT] = true; + } else if (ext_str.size() == 1) { + bad_isa_string(str, "single 'X' is not a proper name"); + } else if (ext_str != "xdummy") { + extension_t* x = find_extension(ext_str.substr(1).c_str())(); + if (!extensions.insert(std::make_pair(x->name(), x)).second) { + fprintf(stderr, "extensions must have unique names (got two named \"%s\"!)\n", x->name()); + abort(); + } + } + } else { + bad_isa_string(str, ("unsupported extension: " + ext_str).c_str()); + } + p = end; + } + if (*p) { + bad_isa_string(str, ("can't parse: " + std::string(p)).c_str()); + } + + if (extension_table['C']) { + extension_table[EXT_ZCA] = true; + if (extension_table['F'] && max_xlen == 32) + extension_table[EXT_ZCF] = true; + if (extension_table['D']) + extension_table[EXT_ZCD] = true; + } + + if (extension_table[EXT_ZFINX] && extension_table['F']) { + bad_isa_string(str, ("Zfinx/Zdinx/Zhinx{min} extensions conflict with 'F/D/Q/Zfh{min}' extensions")); + } + + if (extension_table[EXT_ZCF] && !extension_table['F']) { + bad_isa_string(str, "'Zcf' extension requires 'F' extension"); + } + + if (extension_table[EXT_ZCD] && !extension_table['D']) { + bad_isa_string(str, "'Zcd' extension requires 'D' extension"); + } + + if ((extension_table[EXT_ZCMP] || extension_table[EXT_ZCMT]) && extension_table[EXT_ZCD]) { + bad_isa_string(str, "Zcmp' and 'Zcmt' exensions are incompatible with 'Zcd' extension"); + } + + if ((extension_table[EXT_ZCF] || extension_table[EXT_ZCD] || extension_table[EXT_ZCB] || + extension_table[EXT_ZCMP] || extension_table[EXT_ZCMT]) && !extension_table[EXT_ZCA]) { + bad_isa_string(str, "'Zcf/Zcd/Zcb/Zcmp/Zcmt' extensions require 'Zca' extension"); + } + + std::string lowercase = strtolower(priv); + bool user = false, supervisor = false; + + if (lowercase == "m") + ; + else if (lowercase == "mu") + user = true; + else if (lowercase == "msu") + user = supervisor = true; + else + bad_priv_string(priv); + + extension_table['U'] = user; + extension_table['S'] = supervisor; + + if (extension_table['H'] && !supervisor) + bad_isa_string(str, "'H' extension requires S mode"); + + max_isa = max_xlen == 32 ? reg_t(1) << 30 : reg_t(2) << 62; + for (unsigned char ch = 'A'; ch <= 'Z'; ch++) { + if (extension_table[ch]) + max_isa |= 1UL << (ch - 'A'); + } +} diff --git a/vendor/riscv/riscv-isa-sim/riscv/isa_parser.h b/vendor/riscv/riscv-isa-sim/riscv/isa_parser.h new file mode 100644 index 000000000..9effd164d --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/isa_parser.h @@ -0,0 +1,110 @@ +// See LICENSE for license details. +#ifndef _RISCV_ISA_PARSER_H +#define _RISCV_ISA_PARSER_H + +#include "decode.h" + +#include +#include +#include + +class extension_t; + +typedef enum { + // 65('A') ~ 90('Z') is reserved for standard isa in misa + EXT_ZFH = 'Z' + 1, + EXT_ZFHMIN, + EXT_ZBA, + EXT_ZBB, + EXT_ZBC, + EXT_ZBS, + EXT_ZBKB, + EXT_ZBKC, + EXT_ZBKX, + EXT_ZCA, + EXT_ZCB, + EXT_ZCD, + EXT_ZCF, + EXT_ZCMP, + EXT_ZCMT, + EXT_ZKND, + EXT_ZKNE, + EXT_ZKNH, + EXT_ZKSED, + EXT_ZKSH, + EXT_ZKR, + EXT_ZMMUL, + EXT_ZBPBO, + EXT_ZPN, + EXT_ZPSFOPERAND, + EXT_ZVFH, + EXT_ZVFHMIN, + EXT_SMEPMP, + EXT_SMSTATEEN, + EXT_SMRNMI, + EXT_SSCOFPMF, + EXT_SVADU, + EXT_SVNAPOT, + EXT_SVPBMT, + EXT_SVINVAL, + EXT_ZDINX, + EXT_ZFA, + EXT_ZFINX, + EXT_ZHINX, + EXT_ZHINXMIN, + EXT_ZICBOM, + EXT_ZICBOZ, + EXT_ZICNTR, + EXT_ZICOND, + EXT_ZIHPM, + EXT_XZBP, + EXT_XZBS, + EXT_XZBE, + EXT_XZBF, + EXT_XZBC, + EXT_XZBM, + EXT_XZBR, + EXT_XZBT, + EXT_SSTC, + NUM_ISA_EXTENSIONS +} isa_extension_t; + +typedef enum { + IMPL_MMU_SV32, + IMPL_MMU_SV39, + IMPL_MMU_SV48, + IMPL_MMU_SV57, + IMPL_MMU_SBARE, + IMPL_MMU, + IMPL_MMU_VMID, + IMPL_MMU_ASID, +} impl_extension_t; + +class isa_parser_t { +public: + isa_parser_t(const char* str, const char *priv); + ~isa_parser_t() {}; + unsigned get_max_xlen() const { return max_xlen; } + reg_t get_max_isa() const { return max_isa; } + std::string get_isa_string() const { return isa_string; } + bool extension_enabled(unsigned char ext) const { + return extension_enabled(isa_extension_t(ext)); + } + bool extension_enabled(isa_extension_t ext) const { + return extension_table[ext]; + } + + std::bitset get_extension_table() const { return extension_table; } + + const std::unordered_map & + get_extensions() const { return extensions; } + +protected: + unsigned max_xlen; + reg_t max_isa; + std::bitset extension_table; + std::string isa_string; + std::unordered_map extensions; +}; + +#endif diff --git a/vendor/riscv/riscv-isa-sim/riscv/memtracer.h b/vendor/riscv/riscv-isa-sim/riscv/memtracer.h index 6952e2f87..72bb3a88b 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/memtracer.h +++ b/vendor/riscv/riscv-isa-sim/riscv/memtracer.h @@ -21,6 +21,7 @@ class memtracer_t virtual bool interested_in_range(uint64_t begin, uint64_t end, access_type type) = 0; virtual void trace(uint64_t addr, size_t bytes, access_type type) = 0; + virtual void clean_invalidate(uint64_t addr, size_t bytes, bool clean, bool inval) = 0; }; class memtracer_list_t : public memtracer_t @@ -29,15 +30,20 @@ class memtracer_list_t : public memtracer_t bool empty() { return list.empty(); } bool interested_in_range(uint64_t begin, uint64_t end, access_type type) { - for (std::vector::iterator it = list.begin(); it != list.end(); ++it) - if ((*it)->interested_in_range(begin, end, type)) + for (auto it: list) + if (it->interested_in_range(begin, end, type)) return true; return false; } void trace(uint64_t addr, size_t bytes, access_type type) { - for (std::vector::iterator it = list.begin(); it != list.end(); ++it) - (*it)->trace(addr, bytes, type); + for (auto it: list) + it->trace(addr, bytes, type); + } + void clean_invalidate(uint64_t addr, size_t bytes, bool clean, bool inval) + { + for (auto it: list) + it->clean_invalidate(addr, bytes, clean, inval); } void hook(memtracer_t* h) { diff --git a/vendor/riscv/riscv-isa-sim/riscv/mmu.cc b/vendor/riscv/riscv-isa-sim/riscv/mmu.cc index 275383d73..be24f40f0 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/mmu.cc +++ b/vendor/riscv/riscv-isa-sim/riscv/mmu.cc @@ -1,20 +1,24 @@ // See LICENSE for license details. +#include "config.h" #include "mmu.h" #include "arith.h" #include "simif.h" #include "processor.h" -mmu_t::mmu_t(simif_t* sim, processor_t* proc) +mmu_t::mmu_t(simif_t* sim, endianness_t endianness, processor_t* proc) : sim(sim), proc(proc), #ifdef RISCV_ENABLE_DUAL_ENDIAN - target_big_endian(false), + target_big_endian(endianness == endianness_big), #endif check_triggers_fetch(false), check_triggers_load(false), check_triggers_store(false), matched_trigger(NULL) { +#ifndef RISCV_ENABLE_DUAL_ENDIAN + assert(endianness == endianness_little); +#endif flush_tlb(); yield_load_reservation(); } @@ -38,7 +42,7 @@ void mmu_t::flush_tlb() flush_icache(); } -static void throw_access_exception(bool virt, reg_t addr, access_type type) +void throw_access_exception(bool virt, reg_t addr, access_type type) { switch (type) { case FETCH: throw trap_instruction_access_fault(virt, addr, 0, 0); @@ -57,7 +61,7 @@ reg_t mmu_t::translate(reg_t addr, reg_t len, access_type type, uint32_t xlate_f bool hlvx = xlate_flags & RISCV_XLATE_VIRT_HLVX; reg_t mode = proc->state.prv; if (type != FETCH) { - if (!proc->state.debug_mode && get_field(proc->state.mstatus->read(), MSTATUS_MPRV)) { + if (in_mprv()) { mode = get_field(proc->state.mstatus->read(), MSTATUS_MPP); if (get_field(proc->state.mstatus->read(), MSTATUS_MPV) && mode != PRV_M) virt = true; @@ -76,16 +80,26 @@ reg_t mmu_t::translate(reg_t addr, reg_t len, access_type type, uint32_t xlate_f tlb_entry_t mmu_t::fetch_slow_path(reg_t vaddr) { - reg_t paddr = translate(vaddr, sizeof(fetch_temp), FETCH, 0); + check_triggers(triggers::OPERATION_EXECUTE, vaddr); - if (auto host_addr = sim->addr_to_mem(paddr)) { - return refill_tlb(vaddr, paddr, host_addr, FETCH); + tlb_entry_t result; + reg_t vpn = vaddr >> PGSHIFT; + if (unlikely(tlb_insn_tag[vpn % TLB_ENTRIES] != (vpn | TLB_CHECK_TRIGGERS))) { + reg_t paddr = translate(vaddr, sizeof(fetch_temp), FETCH, 0); + if (auto host_addr = sim->addr_to_mem(paddr)) { + result = refill_tlb(vaddr, paddr, host_addr, FETCH); + } else { + if (!mmio_fetch(paddr, sizeof fetch_temp, (uint8_t*)&fetch_temp)) + throw trap_instruction_access_fault(proc->state.v, vaddr, 0, 0); + result = {(char*)&fetch_temp - vaddr, paddr - vaddr}; + } } else { - if (!mmio_load(paddr, sizeof fetch_temp, (uint8_t*)&fetch_temp)) - throw trap_instruction_access_fault(proc->state.v, vaddr, 0, 0); - tlb_entry_t entry = {(char*)&fetch_temp - vaddr, paddr - vaddr}; - return entry; + result = tlb_data[vpn % TLB_ENTRIES]; } + + check_triggers(triggers::OPERATION_EXECUTE, vaddr, from_le(*(const uint16_t*)(result.host_offset + vaddr))); + + return result; } reg_t reg_from_bytes(size_t len, const uint8_t* bytes) @@ -114,72 +128,175 @@ reg_t reg_from_bytes(size_t len, const uint8_t* bytes) abort(); } -bool mmu_t::mmio_ok(reg_t addr, access_type type) +bool mmu_t::mmio_ok(reg_t paddr, access_type UNUSED type) { // Disallow access to debug region when not in debug mode - if (addr >= DEBUG_START && addr <= DEBUG_END && proc && !proc->state.debug_mode) + if (paddr >= DEBUG_START && paddr <= DEBUG_END && proc && !proc->state.debug_mode) return false; return true; } -bool mmu_t::mmio_load(reg_t addr, size_t len, uint8_t* bytes) +bool mmu_t::mmio_fetch(reg_t paddr, size_t len, uint8_t* bytes) { - if (!mmio_ok(addr, LOAD)) + if (!mmio_ok(paddr, FETCH)) return false; - return sim->mmio_load(addr, len, bytes); + return sim->mmio_fetch(paddr, len, bytes); } -bool mmu_t::mmio_store(reg_t addr, size_t len, const uint8_t* bytes) +bool mmu_t::mmio_load(reg_t paddr, size_t len, uint8_t* bytes) { - if (!mmio_ok(addr, STORE)) - return false; - - return sim->mmio_store(addr, len, bytes); + return mmio(paddr, len, bytes, LOAD); } -void mmu_t::load_slow_path(reg_t addr, reg_t len, uint8_t* bytes, uint32_t xlate_flags) +bool mmu_t::mmio_store(reg_t paddr, size_t len, const uint8_t* bytes) { + return mmio(paddr, len, const_cast(bytes), STORE); +} + +bool mmu_t::mmio(reg_t paddr, size_t len, uint8_t* bytes, access_type type) +{ + bool power_of_2 = (len & (len - 1)) == 0; + bool naturally_aligned = (paddr & (len - 1)) == 0; + + if (power_of_2 && naturally_aligned) { + if (!mmio_ok(paddr, type)) + return false; + + if (type == STORE) + return sim->mmio_store(paddr, len, bytes); + else + return sim->mmio_load(paddr, len, bytes); + } + + for (size_t i = 0; i < len; i++) { + if (!mmio(paddr + i, 1, bytes + i, type)) + return false; + } + + return true; +} + +void mmu_t::check_triggers(triggers::operation_t operation, reg_t address, std::optional data) +{ + if (matched_trigger || !proc) + return; + + auto match = proc->TM.detect_memory_access_match(operation, address, data); + + if (match.has_value()) + switch (match->timing) { + case triggers::TIMING_BEFORE: + throw triggers::matched_t(operation, address, match->action); + + case triggers::TIMING_AFTER: + // We want to take this exception on the next instruction. We check + // whether to do so in the I$ refill path, so flush the I$. + flush_icache(); + matched_trigger = new triggers::matched_t(operation, address, match->action); + } +} + +void mmu_t::load_slow_path_intrapage(reg_t addr, reg_t len, uint8_t* bytes, uint32_t xlate_flags) +{ + reg_t vpn = addr >> PGSHIFT; + if (xlate_flags == 0 && vpn == (tlb_load_tag[vpn % TLB_ENTRIES] & ~TLB_CHECK_TRIGGERS)) { + auto host_addr = tlb_data[vpn % TLB_ENTRIES].host_offset + addr; + memcpy(bytes, host_addr, len); + return; + } + reg_t paddr = translate(addr, len, LOAD, xlate_flags); + if ((xlate_flags & RISCV_XLATE_LR) && !sim->reservable(paddr)) { + throw trap_load_access_fault((proc) ? proc->state.v : false, addr, 0, 0); + } + if (auto host_addr = sim->addr_to_mem(paddr)) { memcpy(bytes, host_addr, len); if (tracer.interested_in_range(paddr, paddr + PGSIZE, LOAD)) tracer.trace(paddr, len, LOAD); else if (xlate_flags == 0) refill_tlb(addr, paddr, host_addr, LOAD); + } else if (!mmio_load(paddr, len, bytes)) { throw trap_load_access_fault((proc) ? proc->state.v : false, addr, 0, 0); } - if (!matched_trigger) { - reg_t data = reg_from_bytes(len, bytes); - matched_trigger = trigger_exception(OPERATION_LOAD, addr, data); - if (matched_trigger) - throw *matched_trigger; + if (xlate_flags & RISCV_XLATE_LR) { + load_reservation_address = paddr; } } -void mmu_t::store_slow_path(reg_t addr, reg_t len, const uint8_t* bytes, uint32_t xlate_flags) +void mmu_t::load_slow_path(reg_t addr, reg_t len, uint8_t* bytes, uint32_t xlate_flags) { - reg_t paddr = translate(addr, len, STORE, xlate_flags); + check_triggers(triggers::OPERATION_LOAD, addr); - if (!matched_trigger) { - reg_t data = reg_from_bytes(len, bytes); - matched_trigger = trigger_exception(OPERATION_STORE, addr, data); - if (matched_trigger) - throw *matched_trigger; + if ((addr & (len - 1)) == 0) { + load_slow_path_intrapage(addr, len, bytes, xlate_flags); + } else { + bool gva = ((proc) ? proc->state.v : false) || (RISCV_XLATE_VIRT & xlate_flags); + if (!is_misaligned_enabled()) + throw trap_load_address_misaligned(gva, addr, 0, 0); + + if (xlate_flags & RISCV_XLATE_LR) + throw trap_load_access_fault(gva, addr, 0, 0); + + reg_t len_page0 = std::min(len, PGSIZE - addr % PGSIZE); + load_slow_path_intrapage(addr, len_page0, bytes, xlate_flags); + if (len_page0 != len) + load_slow_path_intrapage(addr + len_page0, len - len_page0, bytes + len_page0, xlate_flags); } - if (auto host_addr = sim->addr_to_mem(paddr)) { - memcpy(host_addr, bytes, len); - if (tracer.interested_in_range(paddr, paddr + PGSIZE, STORE)) - tracer.trace(paddr, len, STORE); - else if (xlate_flags == 0) - refill_tlb(addr, paddr, host_addr, STORE); - } else if (!mmio_store(paddr, len, bytes)) { - throw trap_store_access_fault((proc) ? proc->state.v : false, addr, 0, 0); + check_triggers(triggers::OPERATION_LOAD, addr, reg_from_bytes(len, bytes)); +} + +void mmu_t::store_slow_path_intrapage(reg_t addr, reg_t len, const uint8_t* bytes, uint32_t xlate_flags, bool actually_store) +{ + reg_t vpn = addr >> PGSHIFT; + if (xlate_flags == 0 && vpn == (tlb_store_tag[vpn % TLB_ENTRIES] & ~TLB_CHECK_TRIGGERS)) { + if (actually_store) { + auto host_addr = tlb_data[vpn % TLB_ENTRIES].host_offset + addr; + memcpy(host_addr, bytes, len); + } + return; + } + + reg_t paddr = translate(addr, len, STORE, xlate_flags); + + if (actually_store) { + if (auto host_addr = sim->addr_to_mem(paddr)) { + memcpy(host_addr, bytes, len); + if (tracer.interested_in_range(paddr, paddr + PGSIZE, STORE)) + tracer.trace(paddr, len, STORE); + else if (xlate_flags == 0) + refill_tlb(addr, paddr, host_addr, STORE); + } else if (!mmio_store(paddr, len, bytes)) { + throw trap_store_access_fault((proc) ? proc->state.v : false, addr, 0, 0); + } + } +} + +void mmu_t::store_slow_path(reg_t addr, reg_t len, const uint8_t* bytes, uint32_t xlate_flags, bool actually_store, bool UNUSED require_alignment) +{ + if (actually_store) + check_triggers(triggers::OPERATION_STORE, addr, reg_from_bytes(len, bytes)); + + if (addr & (len - 1)) { + bool gva = ((proc) ? proc->state.v : false) || (RISCV_XLATE_VIRT & xlate_flags); + if (!is_misaligned_enabled()) + throw trap_store_address_misaligned(gva, addr, 0, 0); + + if (require_alignment) + throw trap_store_access_fault(gva, addr, 0, 0); + + reg_t len_page0 = std::min(len, PGSIZE - addr % PGSIZE); + store_slow_path_intrapage(addr, len_page0, bytes, xlate_flags, actually_store); + if (len_page0 != len) + store_slow_path_intrapage(addr + len_page0, len - len_page0, bytes + len_page0, xlate_flags, actually_store); + } else { + store_slow_path_intrapage(addr, len, bytes, xlate_flags, actually_store); } } @@ -190,7 +307,7 @@ tlb_entry_t mmu_t::refill_tlb(reg_t vaddr, reg_t paddr, char* host_addr, access_ tlb_entry_t entry = {host_addr - vaddr, paddr - vaddr}; - if (proc && get_field(proc->state.mstatus->read(), MSTATUS_MPRV)) + if (in_mprv()) return entry; if ((tlb_load_tag[idx] & ~TLB_CHECK_TRIGGERS) != expected_tag) @@ -240,7 +357,11 @@ bool mmu_t::pmp_ok(reg_t addr, reg_t len, access_type type, reg_t mode) } } - return mode == PRV_M; + // in case matching region is not found + const bool mseccfg_mml = proc->state.mseccfg->get_mml(); + const bool mseccfg_mmwp = proc->state.mseccfg->get_mmwp(); + return ((mode == PRV_M) && !mseccfg_mmwp + && (!mseccfg_mml || ((type == LOAD) || (type == STORE)))); } reg_t mmu_t::pmp_homogeneous(reg_t addr, reg_t len) @@ -281,19 +402,18 @@ reg_t mmu_t::s2xlate(reg_t gva, reg_t gpa, access_type type, access_type trap_ty // check that physical address of PTE is legal auto pte_paddr = base + idx * vm.ptesize; - auto ppte = sim->addr_to_mem(pte_paddr); - if (!ppte || !pmp_ok(pte_paddr, vm.ptesize, LOAD, PRV_S)) { - throw_access_exception(virt, gva, trap_type); - } - - reg_t pte = vm.ptesize == 4 ? from_target(*(target_endian*)ppte) : from_target(*(target_endian*)ppte); + reg_t pte = pte_load(pte_paddr, gva, virt, trap_type, vm.ptesize); reg_t ppn = (pte & ~reg_t(PTE_ATTR)) >> PTE_PPN_SHIFT; + bool pbmte = proc->get_state()->menvcfg->read() & MENVCFG_PBMTE; + bool hade = proc->get_state()->menvcfg->read() & MENVCFG_HADE; if (pte & PTE_RSVD) { break; } else if (!proc->extension_enabled(EXT_SVNAPOT) && (pte & PTE_N)) { break; - } else if (!proc->extension_enabled(EXT_SVPBMT) && (pte & PTE_PBMT)) { + } else if (!pbmte && (pte & PTE_PBMT)) { + break; + } else if ((pte & PTE_PBMT) == PTE_PBMT) { break; } else if (PTE_TABLE(pte)) { // next level of page table if (pte & (PTE_D | PTE_A | PTE_U | PTE_N | PTE_PBMT)) @@ -311,18 +431,17 @@ reg_t mmu_t::s2xlate(reg_t gva, reg_t gpa, access_type type, access_type trap_ty break; } else { reg_t ad = PTE_A | ((type == STORE) * PTE_D); -#ifdef RISCV_ENABLE_DIRTY - // set accessed and possibly dirty bits. + if ((pte & ad) != ad) { - if (!pmp_ok(pte_paddr, vm.ptesize, STORE, PRV_S)) - throw_access_exception(virt, gva, trap_type); - *(target_endian*)ppte |= to_target((uint32_t)ad); + if (hade) { + // set accessed and possibly dirty bits + pte_store(pte_paddr, pte | ad, gva, virt, type, vm.ptesize); + } else { + // take exception if access or possibly dirty bit is not set. + break; + } } -#else - // take exception if access or possibly dirty bit is not set. - if ((pte & ad) != ad) - break; -#endif + reg_t vpn = gpa >> PGSHIFT; reg_t page_mask = (reg_t(1) << PGSHIFT) - 1; @@ -372,18 +491,18 @@ reg_t mmu_t::walk(reg_t addr, access_type type, reg_t mode, bool virt, bool hlvx // check that physical address of PTE is legal auto pte_paddr = s2xlate(addr, base + idx * vm.ptesize, LOAD, type, virt, false); - auto ppte = sim->addr_to_mem(pte_paddr); - if (!ppte || !pmp_ok(pte_paddr, vm.ptesize, LOAD, PRV_S)) - throw_access_exception(virt, addr, type); - - reg_t pte = vm.ptesize == 4 ? from_target(*(target_endian*)ppte) : from_target(*(target_endian*)ppte); + reg_t pte = pte_load(pte_paddr, addr, virt, type, vm.ptesize); reg_t ppn = (pte & ~reg_t(PTE_ATTR)) >> PTE_PPN_SHIFT; + bool pbmte = virt ? (proc->get_state()->henvcfg->read() & HENVCFG_PBMTE) : (proc->get_state()->menvcfg->read() & MENVCFG_PBMTE); + bool hade = virt ? (proc->get_state()->henvcfg->read() & HENVCFG_HADE) : (proc->get_state()->menvcfg->read() & MENVCFG_HADE); if (pte & PTE_RSVD) { break; } else if (!proc->extension_enabled(EXT_SVNAPOT) && (pte & PTE_N)) { break; - } else if (!proc->extension_enabled(EXT_SVPBMT) && (pte & PTE_PBMT)) { + } else if (!pbmte && (pte & PTE_PBMT)) { + break; + } else if ((pte & PTE_PBMT) == PTE_PBMT) { break; } else if (PTE_TABLE(pte)) { // next level of page table if (pte & (PTE_D | PTE_A | PTE_U | PTE_N | PTE_PBMT)) @@ -401,18 +520,17 @@ reg_t mmu_t::walk(reg_t addr, access_type type, reg_t mode, bool virt, bool hlvx break; } else { reg_t ad = PTE_A | ((type == STORE) * PTE_D); -#ifdef RISCV_ENABLE_DIRTY - // set accessed and possibly dirty bits. + if ((pte & ad) != ad) { - if (!pmp_ok(pte_paddr, vm.ptesize, STORE, PRV_S)) - throw_access_exception(virt, addr, type); - *(target_endian*)ppte |= to_target((uint32_t)ad); + if (hade) { + // set accessed and possibly dirty bits. + pte_store(pte_paddr, pte | ad, addr, virt, type, vm.ptesize); + } else { + // take exception if access or possibly dirty bit is not set. + break; + } } -#else - // take exception if access or possibly dirty bit is not set. - if ((pte & ad) != ad) - break; -#endif + // for superpage or Svnapot NAPOT mappings, make a fake leaf PTE for the TLB's benefit. reg_t vpn = addr >> PGSHIFT; diff --git a/vendor/riscv/riscv-isa-sim/riscv/mmu.h b/vendor/riscv/riscv-isa-sim/riscv/mmu.h index 0b86f6cc3..ef054cf59 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/mmu.h +++ b/vendor/riscv/riscv-isa-sim/riscv/mmu.h @@ -6,11 +6,12 @@ #include "decode.h" #include "trap.h" #include "common.h" -#include "config.h" #include "simif.h" #include "processor.h" #include "memtracer.h" -#include "byteorder.h" +#include "../fesvr/byteorder.h" +#include "triggers.h" +#include "cfg.h" #include #include @@ -37,18 +38,7 @@ struct tlb_entry_t { reg_t target_offset; }; -class trigger_matched_t -{ - public: - trigger_matched_t(int index, - trigger_operation_t operation, reg_t address, reg_t data) : - index(index), operation(operation), address(address), data(data) {} - - int index; - trigger_operation_t operation; - reg_t address; - reg_t data; -}; +void throw_access_exception(bool virt, reg_t addr, access_type type); // this class implements a processor's port into the virtual memory system. // an MMU and instruction cache are maintained for simulator performance. @@ -58,234 +48,162 @@ private: std::map alloc_cache; std::vector> addr_tbl; public: - mmu_t(simif_t* sim, processor_t* proc); + mmu_t(simif_t* sim, endianness_t endianness, processor_t* proc); ~mmu_t(); -#define RISCV_XLATE_VIRT (1U << 0) +#define RISCV_XLATE_VIRT (1U << 0) #define RISCV_XLATE_VIRT_HLVX (1U << 1) +#define RISCV_XLATE_LR (1U << 2) - inline reg_t misaligned_load(reg_t addr, size_t size, uint32_t xlate_flags) - { -#ifdef RISCV_ENABLE_MISALIGNED - reg_t res = 0; - for (size_t i = 0; i < size; i++) - res += (reg_t)load_uint8(addr + (target_big_endian? size-1-i : i)) << (i * 8); - return res; -#else - bool gva = ((proc) ? proc->state.v : false) || (RISCV_XLATE_VIRT & xlate_flags); - throw trap_load_address_misaligned(gva, addr, 0, 0); -#endif - } + template + T ALWAYS_INLINE load(reg_t addr, uint32_t xlate_flags = 0) { + target_endian res; + reg_t vpn = addr >> PGSHIFT; + bool aligned = (addr & (sizeof(T) - 1)) == 0; + bool tlb_hit = tlb_load_tag[vpn % TLB_ENTRIES] == vpn; - inline void misaligned_store(reg_t addr, reg_t data, size_t size, uint32_t xlate_flags) - { -#ifdef RISCV_ENABLE_MISALIGNED - for (size_t i = 0; i < size; i++) - store_uint8(addr + (target_big_endian? size-1-i : i), data >> (i * 8)); -#else - bool gva = ((proc) ? proc->state.v : false) || (RISCV_XLATE_VIRT & xlate_flags); - throw trap_store_address_misaligned(gva, addr, 0, 0); -#endif - } - -#ifndef RISCV_ENABLE_COMMITLOG -# define READ_MEM(addr, size) ({}) -#else -# define READ_MEM(addr, size) \ - proc->state.log_mem_read.push_back(std::make_tuple(addr, 0, size)); -#endif - - // template for functions that load an aligned value from memory - #define load_func(type, prefix, xlate_flags) \ - inline type##_t prefix##_##type(reg_t addr, bool require_alignment = false) { \ - if (unlikely(addr & (sizeof(type##_t)-1))) { \ - if (require_alignment) load_reserved_address_misaligned(addr); \ - else return misaligned_load(addr, sizeof(type##_t), xlate_flags); \ - } \ - reg_t vpn = addr >> PGSHIFT; \ - size_t size = sizeof(type##_t); \ - if ((xlate_flags) == 0 && likely(tlb_load_tag[vpn % TLB_ENTRIES] == vpn)) { \ - if (proc) READ_MEM(addr, size); \ - return from_target(*(target_endian*)(tlb_data[vpn % TLB_ENTRIES].host_offset + addr)); \ - } \ - if ((xlate_flags) == 0 && unlikely(tlb_load_tag[vpn % TLB_ENTRIES] == (vpn | TLB_CHECK_TRIGGERS))) { \ - type##_t data = from_target(*(target_endian*)(tlb_data[vpn % TLB_ENTRIES].host_offset + addr)); \ - if (!matched_trigger) { \ - matched_trigger = trigger_exception(OPERATION_LOAD, addr, data); \ - if (matched_trigger) \ - throw *matched_trigger; \ - } \ - if (proc) READ_MEM(addr, size); \ - return data; \ - } \ - target_endian res; \ - load_slow_path(addr, sizeof(type##_t), (uint8_t*)&res, (xlate_flags)); \ - if (proc) READ_MEM(addr, size); \ - return from_target(res); \ + if (likely(xlate_flags == 0 && aligned && tlb_hit)) { + res = *(target_endian*)(tlb_data[vpn % TLB_ENTRIES].host_offset + addr); + } else { + load_slow_path(addr, sizeof(T), (uint8_t*)&res, xlate_flags); } - // load value from memory at aligned address; zero extend to register width - load_func(uint8, load, 0) - load_func(uint16, load, 0) - load_func(uint32, load, 0) - load_func(uint64, load, 0) + if (unlikely(proc && proc->get_log_commits_enabled())) + proc->state.log_mem_read.push_back(std::make_tuple(addr, 0, sizeof(T))); - // load value from guest memory at aligned address; zero extend to register width - load_func(uint8, guest_load, RISCV_XLATE_VIRT) - load_func(uint16, guest_load, RISCV_XLATE_VIRT) - load_func(uint32, guest_load, RISCV_XLATE_VIRT) - load_func(uint64, guest_load, RISCV_XLATE_VIRT) - load_func(uint16, guest_load_x, RISCV_XLATE_VIRT|RISCV_XLATE_VIRT_HLVX) - load_func(uint32, guest_load_x, RISCV_XLATE_VIRT|RISCV_XLATE_VIRT_HLVX) - - // load value from memory at aligned address; sign extend to register width - load_func(int8, load, 0) - load_func(int16, load, 0) - load_func(int32, load, 0) - load_func(int64, load, 0) - - // load value from guest memory at aligned address; sign extend to register width - load_func(int8, guest_load, RISCV_XLATE_VIRT) - load_func(int16, guest_load, RISCV_XLATE_VIRT) - load_func(int32, guest_load, RISCV_XLATE_VIRT) - load_func(int64, guest_load, RISCV_XLATE_VIRT) - -#ifndef RISCV_ENABLE_COMMITLOG -# define WRITE_MEM(addr, value, size) ({}) -#else -# define WRITE_MEM(addr, val, size) \ - proc->state.log_mem_write.push_back(std::make_tuple(addr, val, size)); -#endif - - // template for functions that store an aligned value to memory - #define store_func(type, prefix, xlate_flags) \ - void prefix##_##type(reg_t addr, type##_t val) { \ - if (unlikely(addr & (sizeof(type##_t)-1))) \ - return misaligned_store(addr, val, sizeof(type##_t), xlate_flags); \ - reg_t vpn = addr >> PGSHIFT; \ - size_t size = sizeof(type##_t); \ - if ((xlate_flags) == 0 && likely(tlb_store_tag[vpn % TLB_ENTRIES] == vpn)) { \ - if (proc) WRITE_MEM(addr, val, size); \ - *(target_endian*)(tlb_data[vpn % TLB_ENTRIES].host_offset + addr) = to_target(val); \ - } \ - else if ((xlate_flags) == 0 && unlikely(tlb_store_tag[vpn % TLB_ENTRIES] == (vpn | TLB_CHECK_TRIGGERS))) { \ - if (!matched_trigger) { \ - matched_trigger = trigger_exception(OPERATION_STORE, addr, val); \ - if (matched_trigger) \ - throw *matched_trigger; \ - } \ - if (proc) WRITE_MEM(addr, val, size); \ - *(target_endian*)(tlb_data[vpn % TLB_ENTRIES].host_offset + addr) = to_target(val); \ - } \ - else { \ - target_endian target_val = to_target(val); \ - store_slow_path(addr, sizeof(type##_t), (const uint8_t*)&target_val, (xlate_flags)); \ - if (proc) WRITE_MEM(addr, val, size); \ - } \ + return from_target(res); } + template + T load_reserved(reg_t addr) { + return load(addr, RISCV_XLATE_LR); + } + + template + T guest_load(reg_t addr) { + return load(addr, RISCV_XLATE_VIRT); + } + + template + T guest_load_x(reg_t addr) { + return load(addr, RISCV_XLATE_VIRT|RISCV_XLATE_VIRT_HLVX); + } + + template + void ALWAYS_INLINE store(reg_t addr, T val, uint32_t xlate_flags = 0) { + reg_t vpn = addr >> PGSHIFT; + bool aligned = (addr & (sizeof(T) - 1)) == 0; + bool tlb_hit = tlb_store_tag[vpn % TLB_ENTRIES] == vpn; + + if (xlate_flags == 0 && likely(aligned && tlb_hit)) { + *(target_endian*)(tlb_data[vpn % TLB_ENTRIES].host_offset + addr) = to_target(val); + } else { + target_endian target_val = to_target(val); + store_slow_path(addr, sizeof(T), (const uint8_t*)&target_val, xlate_flags, true, false); + } + + if (unlikely(proc && proc->get_log_commits_enabled())) + proc->state.log_mem_write.push_back(std::make_tuple(addr, val, sizeof(T))); + } + + template + void guest_store(reg_t addr, T val) { + store(addr, val, RISCV_XLATE_VIRT); + } + + // AMO/Zicbom faults should be reported as store faults + #define convert_load_traps_to_store_traps(BODY) \ + try { \ + BODY \ + } catch (trap_load_address_misaligned& t) { \ + /* Misaligned fault will not be triggered by Zicbom */ \ + throw trap_store_address_misaligned(t.has_gva(), t.get_tval(), t.get_tval2(), t.get_tinst()); \ + } catch (trap_load_page_fault& t) { \ + throw trap_store_page_fault(t.has_gva(), t.get_tval(), t.get_tval2(), t.get_tinst()); \ + } catch (trap_load_access_fault& t) { \ + throw trap_store_access_fault(t.has_gva(), t.get_tval(), t.get_tval2(), t.get_tinst()); \ + } catch (trap_load_guest_page_fault& t) { \ + throw trap_store_guest_page_fault(t.get_tval(), t.get_tval2(), t.get_tinst()); \ + } + // template for functions that perform an atomic memory operation - #define amo_func(type) \ - template \ - type##_t amo_##type(reg_t addr, op f) { \ - try { \ - auto lhs = load_##type(addr, true); \ - store_##type(addr, f(lhs)); \ - return lhs; \ - } catch (trap_load_address_misaligned& t) { \ - /* AMO faults should be reported as store faults */ \ - throw trap_store_address_misaligned(t.has_gva(), t.get_tval(), t.get_tval2(), t.get_tinst()); \ - } catch (trap_load_page_fault& t) { \ - /* AMO faults should be reported as store faults */ \ - throw trap_store_page_fault(t.has_gva(), t.get_tval(), t.get_tval2(), t.get_tinst()); \ - } catch (trap_load_access_fault& t) { \ - /* AMO faults should be reported as store faults */ \ - throw trap_store_access_fault(t.has_gva(), t.get_tval(), t.get_tval2(), t.get_tinst()); \ - } catch (trap_load_guest_page_fault& t) { \ - /* AMO faults should be reported as store faults */ \ - throw trap_store_guest_page_fault(t.get_tval(), t.get_tval2(), t.get_tinst()); \ - } \ - } + template + T amo(reg_t addr, op f) { + convert_load_traps_to_store_traps({ + store_slow_path(addr, sizeof(T), nullptr, 0, false, true); + auto lhs = load(addr); + store(addr, f(lhs)); + return lhs; + }) + } void store_float128(reg_t addr, float128_t val) { -#ifndef RISCV_ENABLE_MISALIGNED - if (unlikely(addr & (sizeof(float128_t)-1))) + if (unlikely(addr & (sizeof(float128_t)-1)) && !is_misaligned_enabled()) { throw trap_store_address_misaligned((proc) ? proc->state.v : false, addr, 0, 0); -#endif - store_uint64(addr, val.v[0]); - store_uint64(addr + 8, val.v[1]); + } + + store(addr, val.v[0]); + store(addr + 8, val.v[1]); } float128_t load_float128(reg_t addr) { -#ifndef RISCV_ENABLE_MISALIGNED - if (unlikely(addr & (sizeof(float128_t)-1))) + if (unlikely(addr & (sizeof(float128_t)-1)) && !is_misaligned_enabled()) { throw trap_load_address_misaligned((proc) ? proc->state.v : false, addr, 0, 0); -#endif - return (float128_t){load_uint64(addr), load_uint64(addr + 8)}; + } + + return (float128_t){load(addr), load(addr + 8)}; } - // store value to memory at aligned address - store_func(uint8, store, 0) - store_func(uint16, store, 0) - store_func(uint32, store, 0) - store_func(uint64, store, 0) + void cbo_zero(reg_t addr) { + auto base = addr & ~(blocksz - 1); + for (size_t offset = 0; offset < blocksz; offset += 1) + store(base + offset, 0); + } - // store value to guest memory at aligned address - store_func(uint8, guest_store, RISCV_XLATE_VIRT) - store_func(uint16, guest_store, RISCV_XLATE_VIRT) - store_func(uint32, guest_store, RISCV_XLATE_VIRT) - store_func(uint64, guest_store, RISCV_XLATE_VIRT) - - // perform an atomic memory operation at an aligned address - amo_func(uint32) - amo_func(uint64) + void clean_inval(reg_t addr, bool clean, bool inval) { + convert_load_traps_to_store_traps({ + const reg_t paddr = translate(addr, blocksz, LOAD, 0) & ~(blocksz - 1); + if (sim->reservable(paddr)) { + if (tracer.interested_in_range(paddr, paddr + PGSIZE, LOAD)) + tracer.clean_invalidate(paddr, blocksz, clean, inval); + } else { + throw trap_store_access_fault((proc) ? proc->state.v : false, addr, 0, 0); + } + }) + } inline void yield_load_reservation() { load_reservation_address = (reg_t)-1; } - inline void acquire_load_reservation(reg_t vaddr) - { - reg_t paddr = translate(vaddr, 1, LOAD, 0); - if (auto host_addr = sim->addr_to_mem(paddr)) - load_reservation_address = refill_tlb(vaddr, paddr, host_addr, LOAD).target_offset + vaddr; - else - throw trap_load_access_fault((proc) ? proc->state.v : false, vaddr, 0, 0); // disallow LR to I/O space - } - - inline void load_reserved_address_misaligned(reg_t vaddr) - { - bool gva = proc ? proc->state.v : false; -#ifdef RISCV_ENABLE_MISALIGNED - throw trap_load_access_fault(gva, vaddr, 0, 0); -#else - throw trap_load_address_misaligned(gva, vaddr, 0, 0); -#endif - } - - inline void store_conditional_address_misaligned(reg_t vaddr) - { - bool gva = proc ? proc->state.v : false; -#ifdef RISCV_ENABLE_MISALIGNED - throw trap_store_access_fault(gva, vaddr, 0, 0); -#else - throw trap_store_address_misaligned(gva, vaddr, 0, 0); -#endif - } - inline bool check_load_reservation(reg_t vaddr, size_t size) { - if (vaddr & (size-1)) - store_conditional_address_misaligned(vaddr); + if (vaddr & (size-1)) { + // Raise either access fault or misaligned exception + store_slow_path(vaddr, size, nullptr, 0, false, true); + } reg_t paddr = translate(vaddr, 1, STORE, 0); - if (auto host_addr = sim->addr_to_mem(paddr)) - return load_reservation_address == refill_tlb(vaddr, paddr, host_addr, STORE).target_offset + vaddr; + if (sim->reservable(paddr)) + return load_reservation_address == paddr; else - throw trap_store_access_fault((proc) ? proc->state.v : false, vaddr, 0, 0); // disallow SC to I/O space + throw trap_store_access_fault((proc) ? proc->state.v : false, vaddr, 0, 0); + } + + template + bool store_conditional(reg_t addr, T val) + { + bool have_reservation = check_load_reservation(addr, sizeof(T)); + + if (have_reservation) + store(addr, val); + + yield_load_reservation(); + + return have_reservation; } static const reg_t ICACHE_ENTRIES = 1024; @@ -295,22 +213,31 @@ public: return (addr / PC_ALIGN) % ICACHE_ENTRIES; } + template + T ALWAYS_INLINE fetch_jump_table(reg_t addr) { + auto tlb_entry = translate_insn_addr(addr); + return from_target(*(target_endian*)(tlb_entry.host_offset + addr)); + } + inline icache_entry_t* refill_icache(reg_t addr, icache_entry_t* entry) { + if (matched_trigger) + throw *matched_trigger; + auto tlb_entry = translate_insn_addr(addr); insn_bits_t insn = from_le(*(uint16_t*)(tlb_entry.host_offset + addr)); int length = insn_length(insn); if (likely(length == 4)) { - insn |= (insn_bits_t)from_le(*(const int16_t*)translate_insn_addr_to_host(addr + 2)) << 16; + insn |= (insn_bits_t)from_le(*(const uint16_t*)translate_insn_addr_to_host(addr + 2)) << 16; } else if (length == 2) { - insn = (int16_t)insn; + // entire instruction already fetched } else if (length == 6) { - insn |= (insn_bits_t)from_le(*(const int16_t*)translate_insn_addr_to_host(addr + 4)) << 32; + insn |= (insn_bits_t)from_le(*(const uint16_t*)translate_insn_addr_to_host(addr + 4)) << 32; insn |= (insn_bits_t)from_le(*(const uint16_t*)translate_insn_addr_to_host(addr + 2)) << 16; } else { static_assert(sizeof(insn_bits_t) == 8, "insn_bits_t must be uint64_t"); - insn |= (insn_bits_t)from_le(*(const int16_t*)translate_insn_addr_to_host(addr + 6)) << 48; + insn |= (insn_bits_t)from_le(*(const uint16_t*)translate_insn_addr_to_host(addr + 6)) << 48; insn |= (insn_bits_t)from_le(*(const uint16_t*)translate_insn_addr_to_host(addr + 4)) << 32; insn |= (insn_bits_t)from_le(*(const uint16_t*)translate_insn_addr_to_host(addr + 2)) << 16; } @@ -347,31 +274,9 @@ public: void register_memtracer(memtracer_t*); - int is_dirty_enabled() - { -#ifdef RISCV_ENABLE_DIRTY - return 1; -#else - return 0; -#endif - } - int is_misaligned_enabled() { -#ifdef RISCV_ENABLE_MISALIGNED - return 1; -#else - return 0; -#endif - } - - void set_target_big_endian(bool enable) - { -#ifdef RISCV_ENABLE_DUAL_ENDIAN - target_big_endian = enable; -#else - assert(enable == false); -#endif + return proc && proc->get_cfg().misaligned; } bool is_target_big_endian() @@ -389,12 +294,18 @@ public: return target_big_endian? target_endian::to_be(n) : target_endian::to_le(n); } + void set_cache_blocksz(reg_t size) + { + blocksz = size; + } + private: simif_t* sim; processor_t* proc; memtracer_list_t tracer; reg_t load_reservation_address; uint16_t fetch_temp; + reg_t blocksz; // implement an instruction cache for simulator performance icache_entry_t icache[ICACHE_ENTRIES]; @@ -422,50 +333,82 @@ private: // handle uncommon cases: TLB misses, page faults, MMIO tlb_entry_t fetch_slow_path(reg_t addr); void load_slow_path(reg_t addr, reg_t len, uint8_t* bytes, uint32_t xlate_flags); - void store_slow_path(reg_t addr, reg_t len, const uint8_t* bytes, uint32_t xlate_flags); - bool mmio_load(reg_t addr, size_t len, uint8_t* bytes); - bool mmio_store(reg_t addr, size_t len, const uint8_t* bytes); - bool mmio_ok(reg_t addr, access_type type); + void load_slow_path_intrapage(reg_t addr, reg_t len, uint8_t* bytes, uint32_t xlate_flags); + void store_slow_path(reg_t addr, reg_t len, const uint8_t* bytes, uint32_t xlate_flags, bool actually_store, bool require_alignment); + void store_slow_path_intrapage(reg_t addr, reg_t len, const uint8_t* bytes, uint32_t xlate_flags, bool actually_store); + bool mmio_fetch(reg_t paddr, size_t len, uint8_t* bytes); + bool mmio_load(reg_t paddr, size_t len, uint8_t* bytes); + bool mmio_store(reg_t paddr, size_t len, const uint8_t* bytes); + bool mmio(reg_t paddr, size_t len, uint8_t* bytes, access_type type); + bool mmio_ok(reg_t paddr, access_type type); + void check_triggers(triggers::operation_t operation, reg_t address, std::optional data = std::nullopt); reg_t translate(reg_t addr, reg_t len, access_type type, uint32_t xlate_flags); + reg_t pte_load(reg_t pte_paddr, reg_t addr, bool virt, access_type trap_type, size_t ptesize) { + if (ptesize == 4) + return pte_load(pte_paddr, addr, virt, trap_type); + else + return pte_load(pte_paddr, addr, virt, trap_type); + } + + void pte_store(reg_t pte_paddr, reg_t new_pte, reg_t addr, bool virt, access_type trap_type, size_t ptesize) { + if (ptesize == 4) + return pte_store(pte_paddr, new_pte, addr, virt, trap_type); + else + return pte_store(pte_paddr, new_pte, addr, virt, trap_type); + } + + template inline reg_t pte_load(reg_t pte_paddr, reg_t addr, bool virt, access_type trap_type) + { + const size_t ptesize = sizeof(T); + + if (!pmp_ok(pte_paddr, ptesize, LOAD, PRV_S)) + throw_access_exception(virt, addr, trap_type); + + void* host_pte_addr = sim->addr_to_mem(pte_paddr); + target_endian target_pte; + if (host_pte_addr) { + memcpy(&target_pte, host_pte_addr, ptesize); + } else if (!mmio_load(pte_paddr, ptesize, (uint8_t*)&target_pte)) { + throw_access_exception(virt, addr, trap_type); + } + return from_target(target_pte); + } + + template inline void pte_store(reg_t pte_paddr, reg_t new_pte, reg_t addr, bool virt, access_type trap_type) + { + const size_t ptesize = sizeof(T); + + if (!pmp_ok(pte_paddr, ptesize, STORE, PRV_S)) + throw_access_exception(virt, addr, trap_type); + + void* host_pte_addr = sim->addr_to_mem(pte_paddr); + target_endian target_pte = to_target((T)new_pte); + if (host_pte_addr) { + memcpy(host_pte_addr, &target_pte, ptesize); + } else if (!mmio_store(pte_paddr, ptesize, (uint8_t*)&target_pte)) { + throw_access_exception(virt, addr, trap_type); + } + } + // ITLB lookup inline tlb_entry_t translate_insn_addr(reg_t addr) { reg_t vpn = addr >> PGSHIFT; if (likely(tlb_insn_tag[vpn % TLB_ENTRIES] == vpn)) return tlb_data[vpn % TLB_ENTRIES]; - tlb_entry_t result; - if (unlikely(tlb_insn_tag[vpn % TLB_ENTRIES] != (vpn | TLB_CHECK_TRIGGERS))) { - result = fetch_slow_path(addr); - } else { - result = tlb_data[vpn % TLB_ENTRIES]; - } - if (unlikely(tlb_insn_tag[vpn % TLB_ENTRIES] == (vpn | TLB_CHECK_TRIGGERS))) { - target_endian* ptr = (target_endian*)(tlb_data[vpn % TLB_ENTRIES].host_offset + addr); - int match = proc->trigger_match(OPERATION_EXECUTE, addr, from_target(*ptr)); - if (match >= 0) { - throw trigger_matched_t(match, OPERATION_EXECUTE, addr, from_target(*ptr)); - } - } - return result; + return fetch_slow_path(addr); } inline const uint16_t* translate_insn_addr_to_host(reg_t addr) { return (uint16_t*)(translate_insn_addr(addr).host_offset + addr); } - inline trigger_matched_t *trigger_exception(trigger_operation_t operation, - reg_t address, reg_t data) + inline bool in_mprv() { - if (!proc) { - return NULL; - } - int match = proc->trigger_match(operation, address, data); - if (match == -1) - return NULL; - if (proc->state.mcontrol[match].timing == 0) { - throw trigger_matched_t(match, operation, address, data); - } - return new trigger_matched_t(match, operation, address, data); + return proc != nullptr + && !(proc->state.mnstatus && !get_field(proc->state.mnstatus->read(), MNSTATUS_NMIE)) + && !proc->state.debug_mode + && get_field(proc->state.mstatus->read(), MSTATUS_MPRV); } reg_t pmp_homogeneous(reg_t addr, reg_t len); @@ -480,7 +423,7 @@ private: bool check_triggers_load; bool check_triggers_store; // The exception describing a matched trigger, or NULL. - trigger_matched_t *matched_trigger; + triggers::matched_t *matched_trigger; friend class processor_t; }; @@ -523,6 +466,7 @@ inline vm_info decode_vm_info(int xlen, bool stage2, reg_t prv, reg_t satp) case HGATP_MODE_OFF: return {0, 0, 0, 0, 0}; case HGATP_MODE_SV39X4: return {3, 9, 2, 8, (satp & HGATP64_PPN) << PGSHIFT}; case HGATP_MODE_SV48X4: return {4, 9, 2, 8, (satp & HGATP64_PPN) << PGSHIFT}; + case HGATP_MODE_SV57X4: return {5, 9, 2, 8, (satp & HGATP64_PPN) << PGSHIFT}; default: abort(); } } else { diff --git a/vendor/riscv/riscv-isa-sim/riscv/ns16550.cc b/vendor/riscv/riscv-isa-sim/riscv/ns16550.cc new file mode 100644 index 000000000..8d7e4de2d --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/ns16550.cc @@ -0,0 +1,319 @@ +#include +#include "devices.h" +#include "processor.h" +#include "term.h" + +#define UART_QUEUE_SIZE 64 + +#define UART_RX 0 /* In: Receive buffer */ +#define UART_TX 0 /* Out: Transmit buffer */ + +#define UART_IER 1 /* Out: Interrupt Enable Register */ +#define UART_IER_MSI 0x08 /* Enable Modem status interrupt */ +#define UART_IER_RLSI 0x04 /* Enable receiver line status interrupt */ +#define UART_IER_THRI 0x02 /* Enable Transmitter holding register int. */ +#define UART_IER_RDI 0x01 /* Enable receiver data interrupt */ + +#define UART_IIR 2 /* In: Interrupt ID Register */ +#define UART_IIR_NO_INT 0x01 /* No interrupts pending */ +#define UART_IIR_ID 0x0e /* Mask for the interrupt ID */ +#define UART_IIR_MSI 0x00 /* Modem status interrupt */ +#define UART_IIR_THRI 0x02 /* Transmitter holding register empty */ +#define UART_IIR_RDI 0x04 /* Receiver data interrupt */ +#define UART_IIR_RLSI 0x06 /* Receiver line status interrupt */ + +#define UART_IIR_TYPE_BITS 0xc0 + +#define UART_FCR 2 /* Out: FIFO Control Register */ +#define UART_FCR_ENABLE_FIFO 0x01 /* Enable the FIFO */ +#define UART_FCR_CLEAR_RCVR 0x02 /* Clear the RCVR FIFO */ +#define UART_FCR_CLEAR_XMIT 0x04 /* Clear the XMIT FIFO */ +#define UART_FCR_DMA_SELECT 0x08 /* For DMA applications */ + +#define UART_LCR 3 /* Out: Line Control Register */ +#define UART_LCR_DLAB 0x80 /* Divisor latch access bit */ +#define UART_LCR_SBC 0x40 /* Set break control */ +#define UART_LCR_SPAR 0x20 /* Stick parity (?) */ +#define UART_LCR_EPAR 0x10 /* Even parity select */ +#define UART_LCR_PARITY 0x08 /* Parity Enable */ +#define UART_LCR_STOP 0x04 /* Stop bits: 0=1 bit, 1=2 bits */ + +#define UART_MCR 4 /* Out: Modem Control Register */ +#define UART_MCR_LOOP 0x10 /* Enable loopback test mode */ +#define UART_MCR_OUT2 0x08 /* Out2 complement */ +#define UART_MCR_OUT1 0x04 /* Out1 complement */ +#define UART_MCR_RTS 0x02 /* RTS complement */ +#define UART_MCR_DTR 0x01 /* DTR complement */ + +#define UART_LSR 5 /* In: Line Status Register */ +#define UART_LSR_FIFOE 0x80 /* Fifo error */ +#define UART_LSR_TEMT 0x40 /* Transmitter empty */ +#define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */ +#define UART_LSR_BI 0x10 /* Break interrupt indicator */ +#define UART_LSR_FE 0x08 /* Frame error indicator */ +#define UART_LSR_PE 0x04 /* Parity error indicator */ +#define UART_LSR_OE 0x02 /* Overrun error indicator */ +#define UART_LSR_DR 0x01 /* Receiver data ready */ +#define UART_LSR_BRK_ERROR_BITS 0x1E /* BI, FE, PE, OE bits */ + +#define UART_MSR 6 /* In: Modem Status Register */ +#define UART_MSR_DCD 0x80 /* Data Carrier Detect */ +#define UART_MSR_RI 0x40 /* Ring Indicator */ +#define UART_MSR_DSR 0x20 /* Data Set Ready */ +#define UART_MSR_CTS 0x10 /* Clear to Send */ +#define UART_MSR_DDCD 0x08 /* Delta DCD */ +#define UART_MSR_TERI 0x04 /* Trailing edge ring indicator */ +#define UART_MSR_DDSR 0x02 /* Delta DSR */ +#define UART_MSR_DCTS 0x01 /* Delta CTS */ +#define UART_MSR_ANY_DELTA 0x0F /* Any of the delta bits! */ + +#define UART_SCR 7 /* I/O: Scratch Register */ + +ns16550_t::ns16550_t(class bus_t *bus, abstract_interrupt_controller_t *intctrl, + uint32_t interrupt_id, uint32_t reg_shift, uint32_t reg_io_width) + : bus(bus), intctrl(intctrl), interrupt_id(interrupt_id), reg_shift(reg_shift), reg_io_width(reg_io_width), backoff_counter(0) +{ + ier = 0; + iir = UART_IIR_NO_INT; + fcr = 0; + lcr = 0; + lsr = UART_LSR_TEMT | UART_LSR_THRE; + msr = UART_MSR_DCD | UART_MSR_DSR | UART_MSR_CTS; + dll = 0x0C; + mcr = UART_MCR_OUT2; + scr = 0; +} + +void ns16550_t::update_interrupt(void) +{ + uint8_t interrupts = 0; + + /* Handle clear rx */ + if (lcr & UART_FCR_CLEAR_RCVR) { + lcr &= ~UART_FCR_CLEAR_RCVR; + while (!rx_queue.empty()) { + rx_queue.pop(); + } + lsr &= ~UART_LSR_DR; + } + + /* Handle clear tx */ + if (lcr & UART_FCR_CLEAR_XMIT) { + lcr &= ~UART_FCR_CLEAR_XMIT; + lsr |= UART_LSR_TEMT | UART_LSR_THRE; + } + + /* Data ready and rcv interrupt enabled ? */ + if ((ier & UART_IER_RDI) && (lsr & UART_LSR_DR)) { + interrupts |= UART_IIR_RDI; + } + + /* Transmitter empty and interrupt enabled ? */ + if ((ier & UART_IER_THRI) && (lsr & UART_LSR_TEMT)) { + interrupts |= UART_IIR_THRI; + } + + /* Now update the interrup line, if necessary */ + if (!interrupts) { + iir = UART_IIR_NO_INT; + intctrl->set_interrupt_level(interrupt_id, 0); + } else { + iir = interrupts; + intctrl->set_interrupt_level(interrupt_id, 1); + } + + /* + * If the OS disabled the tx interrupt, we know that there is nothing + * more to transmit. + */ + if (!(ier & UART_IER_THRI)) { + lsr |= UART_LSR_TEMT | UART_LSR_THRE; + } +} + +uint8_t ns16550_t::rx_byte(void) +{ + if (rx_queue.empty()) { + lsr &= ~UART_LSR_DR; + return 0; + } + + /* Break issued ? */ + if (lsr & UART_LSR_BI) { + lsr &= ~UART_LSR_BI; + return 0; + } + + uint8_t ret = rx_queue.front(); + rx_queue.pop(); + if (rx_queue.empty()) { + lsr &= ~UART_LSR_DR; + } + + return ret; +} + +void ns16550_t::tx_byte(uint8_t val) +{ + lsr |= UART_LSR_TEMT | UART_LSR_THRE; + canonical_terminal_t::write(val); +} + +bool ns16550_t::load(reg_t addr, size_t len, uint8_t* bytes) +{ + uint8_t val; + bool ret = true, update = false; + + if (reg_io_width != len) { + return false; + } + addr >>= reg_shift; + addr &= 7; + + switch (addr) { + case UART_RX: + if (lcr & UART_LCR_DLAB) { + val = dll; + } else { + val = rx_byte(); + } + update = true; + break; + case UART_IER: + if (lcr & UART_LCR_DLAB) { + val = dlm; + } else { + val = ier; + } + break; + case UART_IIR: + val = iir | UART_IIR_TYPE_BITS; + break; + case UART_LCR: + val = lcr; + break; + case UART_MCR: + val = mcr; + break; + case UART_LSR: + val = lsr; + break; + case UART_MSR: + val = msr; + break; + case UART_SCR: + val = scr; + break; + default: + ret = false; + break; + }; + + if (ret) { + bytes[0] = val; + } + if (update) { + update_interrupt(); + } + + return ret; +} + +bool ns16550_t::store(reg_t addr, size_t len, const uint8_t* bytes) +{ + uint8_t val; + bool ret = true, update = false; + + if (reg_io_width != len) { + return false; + } + addr >>= reg_shift; + addr &= 7; + val = bytes[0]; + + switch (addr) { + case UART_TX: + update = true; + + if (lcr & UART_LCR_DLAB) { + dll = val; + break; + } + + /* Loopback mode */ + if (mcr & UART_MCR_LOOP) { + if (rx_queue.size() < UART_QUEUE_SIZE) { + rx_queue.push(val); + lsr |= UART_LSR_DR; + } + break; + } + + tx_byte(val); + break; + case UART_IER: + if (!(lcr & UART_LCR_DLAB)) { + ier = val & 0x0f; + } else { + dlm = val; + } + update = true; + break; + case UART_FCR: + fcr = val; + update = true; + break; + case UART_LCR: + lcr = val; + update = true; + break; + case UART_MCR: + mcr = val; + update = true; + break; + case UART_LSR: + /* Factory test */ + break; + case UART_MSR: + /* Not used */ + break; + case UART_SCR: + scr = val; + break; + default: + ret = false; + break; + }; + + if (update) { + update_interrupt(); + } + + return ret; +} + +void ns16550_t::tick(void) +{ + if (!(fcr & UART_FCR_ENABLE_FIFO) || + (mcr & UART_MCR_LOOP) || + (UART_QUEUE_SIZE <= rx_queue.size())) { + return; + } + + if (backoff_counter > 0 && backoff_counter < MAX_BACKOFF) { + backoff_counter++; + return; + } + + int rc = canonical_terminal_t::read(); + if (rc < 0) { + backoff_counter = 1; + return; + } + + backoff_counter = 0; + + rx_queue.push((uint8_t)rc); + lsr |= UART_LSR_DR; + update_interrupt(); +} diff --git a/vendor/riscv/riscv-isa-sim/riscv/overlap_list.h b/vendor/riscv/riscv-isa-sim/riscv/overlap_list.h new file mode 100644 index 000000000..fc3b30774 --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/overlap_list.h @@ -0,0 +1,11 @@ +DECLARE_OVERLAP_INSN(c_fsdsp, EXT_ZCD) +DECLARE_OVERLAP_INSN(c_fld, EXT_ZCD) +DECLARE_OVERLAP_INSN(c_fldsp, EXT_ZCD) +DECLARE_OVERLAP_INSN(cm_push, EXT_ZCMP) +DECLARE_OVERLAP_INSN(cm_pop, EXT_ZCMP) +DECLARE_OVERLAP_INSN(cm_popret, EXT_ZCMP) +DECLARE_OVERLAP_INSN(cm_popretz, EXT_ZCMP) +DECLARE_OVERLAP_INSN(cm_mva01s, EXT_ZCMP) +DECLARE_OVERLAP_INSN(cm_mvsa01, EXT_ZCMP) +DECLARE_OVERLAP_INSN(cm_jalt, EXT_ZCMT) +DECLARE_OVERLAP_INSN(c_fsd, EXT_ZCD) diff --git a/vendor/riscv/riscv-isa-sim/riscv/p_ext_macros.h b/vendor/riscv/riscv-isa-sim/riscv/p_ext_macros.h new file mode 100644 index 000000000..29437ad2e --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/p_ext_macros.h @@ -0,0 +1,506 @@ +// See LICENSE for license details. + +#ifndef _RISCV_P_EXT_MACROS_H +#define _RISCV_P_EXT_MACROS_H + +// The p-extension support is contributed by +// Programming Langauge Lab, Department of Computer Science, National Tsing-Hua University, Taiwan + +#define P_FIELD(R, INDEX, SIZE) \ + (type_sew_t::type)get_field(R, make_mask64(((INDEX) * SIZE), SIZE)) + +#define P_UFIELD(R, INDEX, SIZE) \ + (type_usew_t::type)get_field(R, make_mask64(((INDEX) * SIZE), SIZE)) + +#define P_B(R, INDEX) P_UFIELD(R, INDEX, 8) +#define P_H(R, INDEX) P_UFIELD(R, INDEX, 16) +#define P_W(R, INDEX) P_UFIELD(R, INDEX, 32) +#define P_SB(R, INDEX) P_FIELD(R, INDEX, 8) +#define P_SH(R, INDEX) P_FIELD(R, INDEX, 16) +#define P_SW(R, INDEX) P_FIELD(R, INDEX, 32) + +#define READ_REG_PAIR(reg) ({ \ + require((reg) % 2 == 0); \ + (reg) == 0 ? reg_t(0) : \ + (READ_REG((reg) + 1) << 32) + zext32(READ_REG(reg)); }) + +#define RS1_PAIR READ_REG_PAIR(insn.rs1()) +#define RS2_PAIR READ_REG_PAIR(insn.rs2()) +#define RD_PAIR READ_REG_PAIR(insn.rd()) + +#define WRITE_PD() \ + rd_tmp = set_field(rd_tmp, make_mask64((i * sizeof(pd) * 8), sizeof(pd) * 8), pd); + +#define WRITE_RD_PAIR(value) \ + if (insn.rd() != 0) { \ + require(insn.rd() % 2 == 0); \ + WRITE_REG(insn.rd(), sext32(value)); \ + WRITE_REG(insn.rd() + 1, (sreg_t(value)) >> 32); \ + } + +#define P_SET_OV(ov) \ + if (ov) P.VU.vxsat->write(1); + +#define P_SAT(R, BIT) \ + if (R > INT##BIT##_MAX) { \ + R = INT##BIT##_MAX; \ + P_SET_OV(1); \ + } else if (R < INT##BIT##_MIN) { \ + R = INT##BIT##_MIN; \ + P_SET_OV(1); \ + } + +#define P_SATU(R, BIT) \ + if (R > UINT##BIT##_MAX) { \ + R = UINT##BIT##_MAX; \ + P_SET_OV(1); \ + } else if (R < 0) { \ + P_SET_OV(1); \ + R = 0; \ + } + +#define P_LOOP_BASE(BIT) \ + require_extension(EXT_ZPN); \ + require(BIT == e8 || BIT == e16 || BIT == e32); \ + reg_t rd_tmp = RD; \ + reg_t rs1 = RS1; \ + reg_t rs2 = RS2; \ + sreg_t len = xlen / BIT; \ + for (sreg_t i = len - 1; i >= 0; --i) { + +#define P_ONE_LOOP_BASE(BIT) \ + require_extension(EXT_ZPN); \ + require(BIT == e8 || BIT == e16 || BIT == e32); \ + reg_t rd_tmp = RD; \ + reg_t rs1 = RS1; \ + sreg_t len = xlen / BIT; \ + for (sreg_t i = len - 1; i >= 0; --i) { + +#define P_I_LOOP_BASE(BIT, IMMBIT) \ + require_extension(EXT_ZPN); \ + require(BIT == e8 || BIT == e16 || BIT == e32); \ + reg_t rd_tmp = RD; \ + reg_t rs1 = RS1; \ + type_usew_t::type imm##IMMBIT##u = insn.p_imm##IMMBIT(); \ + sreg_t len = xlen / BIT; \ + for (sreg_t i = len - 1; i >= 0; --i) { + +#define P_X_LOOP_BASE(BIT, LOWBIT) \ + require_extension(EXT_ZPN); \ + require(BIT == e8 || BIT == e16 || BIT == e32); \ + reg_t rd_tmp = RD; \ + reg_t rs1 = RS1; \ + type_usew_t::type sa = RS2 & ((uint64_t(1) << LOWBIT) - 1); \ + type_sew_t::type UNUSED ssa = int64_t(RS2) << (64 - LOWBIT) >> (64 - LOWBIT); \ + sreg_t len = xlen / BIT; \ + for (sreg_t i = len - 1; i >= 0; --i) { + +#define P_MUL_LOOP_BASE(BIT) \ + require_extension(EXT_ZPN); \ + require(BIT == e8 || BIT == e16 || BIT == e32); \ + reg_t rd_tmp = RD; \ + reg_t rs1 = RS1; \ + reg_t rs2 = RS2; \ + sreg_t len = 32 / BIT; \ + for (sreg_t i = len - 1; i >= 0; --i) { + +#define P_REDUCTION_LOOP_BASE(BIT, BIT_INNER, USE_RD) \ + require_extension(EXT_ZPN); \ + require(BIT == e16 || BIT == e32 || BIT == e64); \ + reg_t rd_tmp = USE_RD ? zext_xlen(RD) : 0; \ + reg_t rs1 = zext_xlen(RS1); \ + reg_t rs2 = zext_xlen(RS2); \ + sreg_t len = 64 / BIT; \ + sreg_t len_inner = BIT / BIT_INNER; \ + for (sreg_t i = len - 1; i >= 0; --i) { \ + sreg_t pd_res = P_FIELD(rd_tmp, i, BIT); \ + for (sreg_t j = i * len_inner; j < (i + 1) * len_inner; ++j) { + +#define P_REDUCTION_ULOOP_BASE(BIT, BIT_INNER, USE_RD) \ + require_extension(EXT_ZPN); \ + require(BIT == e16 || BIT == e32 || BIT == e64); \ + reg_t rd_tmp = USE_RD ? zext_xlen(RD) : 0; \ + reg_t rs1 = zext_xlen(RS1); \ + reg_t rs2 = zext_xlen(RS2); \ + sreg_t len = 64 / BIT; \ + sreg_t len_inner = BIT / BIT_INNER; \ + for (sreg_t i = len - 1; i >=0; --i) { \ + reg_t pd_res = P_UFIELD(rd_tmp, i, BIT); \ + for (sreg_t j = i * len_inner; j < (i + 1) * len_inner; ++j) { + +#define P_PARAMS(BIT) \ + auto pd = P_FIELD(rd_tmp, i, BIT); \ + auto ps1 = P_FIELD(rs1, i, BIT); \ + auto ps2 = P_FIELD(rs2, i, BIT); + +#define P_UPARAMS(BIT) \ + auto pd = P_UFIELD(rd_tmp, i, BIT); \ + auto ps1 = P_UFIELD(rs1, i, BIT); \ + auto ps2 = P_UFIELD(rs2, i, BIT); + +#define P_CORSS_PARAMS(BIT) \ + auto pd = P_FIELD(rd_tmp, i, BIT); \ + auto UNUSED ps1 = P_FIELD(rs1, i, BIT); \ + auto UNUSED ps2 = P_FIELD(rs2, (i ^ 1), BIT); + +#define P_CORSS_UPARAMS(BIT) \ + auto pd = P_UFIELD(rd_tmp, i, BIT); \ + auto ps1 = P_UFIELD(rs1, i, BIT); \ + auto ps2 = P_UFIELD(rs2, (i ^ 1), BIT); + +#define P_ONE_PARAMS(BIT) \ + auto pd = P_FIELD(rd_tmp, i, BIT); \ + auto ps1 = P_FIELD(rs1, i, BIT); + +#define P_ONE_UPARAMS(BIT) \ + auto pd = P_UFIELD(rd_tmp, i, BIT); \ + auto ps1 = P_UFIELD(rs1, i, BIT); + +#define P_ONE_SUPARAMS(BIT) \ + auto pd = P_UFIELD(rd_tmp, i, BIT); \ + auto ps1 = P_FIELD(rs1, i, BIT); + +#define P_MUL_PARAMS(BIT) \ + auto pd = P_FIELD(rd_tmp, i, BIT * 2); \ + auto ps1 = P_FIELD(rs1, i, BIT); \ + auto ps2 = P_FIELD(rs2, i, BIT); + +#define P_MUL_UPARAMS(BIT) \ + auto pd = P_UFIELD(rd_tmp, i, BIT * 2); \ + auto ps1 = P_UFIELD(rs1, i, BIT); \ + auto ps2 = P_UFIELD(rs2, i, BIT); + +#define P_MUL_CROSS_PARAMS(BIT) \ + auto pd = P_FIELD(rd_tmp, i, BIT * 2); \ + auto ps1 = P_FIELD(rs1, i, BIT); \ + auto ps2 = P_FIELD(rs2, (i ^ 1), BIT); + +#define P_MUL_CROSS_UPARAMS(BIT) \ + auto pd = P_UFIELD(rd_tmp, i, BIT*2); \ + auto ps1 = P_UFIELD(rs1, i, BIT); \ + auto ps2 = P_UFIELD(rs2, (i ^ 1), BIT); + +#define P_REDUCTION_PARAMS(BIT_INNER) \ + auto ps1 = P_FIELD(rs1, j, BIT_INNER); \ + auto ps2 = P_FIELD(rs2, j, BIT_INNER); + +#define P_REDUCTION_UPARAMS(BIT_INNER) \ + auto ps1 = P_UFIELD(rs1, j, BIT_INNER); \ + auto ps2 = P_UFIELD(rs2, j, BIT_INNER); + +#define P_REDUCTION_SUPARAMS(BIT_INNER) \ + auto ps1 = P_FIELD(rs1, j, BIT_INNER); \ + auto ps2 = P_UFIELD(rs2, j, BIT_INNER); + +#define P_REDUCTION_CROSS_PARAMS(BIT_INNER) \ + auto ps1 = P_FIELD(rs1, j, BIT_INNER); \ + auto ps2 = P_FIELD(rs2, (j ^ 1), BIT_INNER); + +#define P_LOOP_BODY(BIT, BODY) { \ + P_PARAMS(BIT) \ + BODY \ + WRITE_PD(); \ +} + +#define P_ULOOP_BODY(BIT, BODY) { \ + P_UPARAMS(BIT) \ + BODY \ + WRITE_PD(); \ +} + +#define P_ONE_LOOP_BODY(BIT, BODY) { \ + P_ONE_PARAMS(BIT) \ + BODY \ + WRITE_PD(); \ +} + +#define P_CROSS_LOOP_BODY(BIT, BODY) { \ + P_CORSS_PARAMS(BIT) \ + BODY \ + WRITE_PD(); \ +} + +#define P_CROSS_ULOOP_BODY(BIT, BODY) { \ + P_CORSS_UPARAMS(BIT) \ + BODY \ + WRITE_PD(); \ +} + +#define P_ONE_ULOOP_BODY(BIT, BODY) { \ + P_ONE_UPARAMS(BIT) \ + BODY \ + WRITE_PD(); \ +} + +#define P_MUL_LOOP_BODY(BIT, BODY) { \ + P_MUL_PARAMS(BIT) \ + BODY \ + WRITE_PD(); \ +} + +#define P_MUL_ULOOP_BODY(BIT, BODY) { \ + P_MUL_UPARAMS(BIT) \ + BODY \ + WRITE_PD(); \ +} + +#define P_MUL_CROSS_LOOP_BODY(BIT, BODY) { \ + P_MUL_CROSS_PARAMS(BIT) \ + BODY \ + WRITE_PD(); \ +} + +#define P_MUL_CROSS_ULOOP_BODY(BIT, BODY) { \ + P_MUL_CROSS_UPARAMS(BIT) \ + BODY \ + WRITE_PD(); \ +} + +#define P_LOOP(BIT, BODY) \ + P_LOOP_BASE(BIT) \ + P_LOOP_BODY(BIT, BODY) \ + P_LOOP_END() + +#define P_ONE_LOOP(BIT, BODY) \ + P_ONE_LOOP_BASE(BIT) \ + P_ONE_LOOP_BODY(BIT, BODY) \ + P_LOOP_END() + +#define P_ULOOP(BIT, BODY) \ + P_LOOP_BASE(BIT) \ + P_ULOOP_BODY(BIT, BODY) \ + P_LOOP_END() + +#define P_CROSS_LOOP(BIT, BODY1, BODY2) \ + P_LOOP_BASE(BIT) \ + P_CROSS_LOOP_BODY(BIT, BODY1) \ + --i; \ + if (sizeof(#BODY2) == 1) { \ + P_CROSS_LOOP_BODY(BIT, BODY1) \ + } \ + else { \ + P_CROSS_LOOP_BODY(BIT, BODY2) \ + } \ + P_LOOP_END() + +#define P_CROSS_ULOOP(BIT, BODY1, BODY2) \ + P_LOOP_BASE(BIT) \ + P_CROSS_ULOOP_BODY(BIT, BODY1) \ + --i; \ + P_CROSS_ULOOP_BODY(BIT, BODY2) \ + P_LOOP_END() + +#define P_STRAIGHT_LOOP(BIT, BODY1, BODY2) \ + P_LOOP_BASE(BIT) \ + P_LOOP_BODY(BIT, BODY1) \ + --i; \ + P_LOOP_BODY(BIT, BODY2) \ + P_LOOP_END() + +#define P_STRAIGHT_ULOOP(BIT, BODY1, BODY2) \ + P_LOOP_BASE(BIT) \ + P_ULOOP_BODY(BIT, BODY1) \ + --i; \ + P_ULOOP_BODY(BIT, BODY2) \ + P_LOOP_END() + +#define P_X_LOOP(BIT, RS2_LOW_BIT, BODY) \ + P_X_LOOP_BASE(BIT, RS2_LOW_BIT) \ + P_ONE_LOOP_BODY(BIT, BODY) \ + P_LOOP_END() + +#define P_X_ULOOP(BIT, RS2_LOW_BIT, BODY) \ + P_X_LOOP_BASE(BIT, RS2_LOW_BIT) \ + P_ONE_ULOOP_BODY(BIT, BODY) \ + P_LOOP_END() + +#define P_I_LOOP(BIT, IMMBIT, BODY) \ + P_I_LOOP_BASE(BIT, IMMBIT) \ + P_ONE_LOOP_BODY(BIT, BODY) \ + P_LOOP_END() + +#define P_I_ULOOP(BIT, IMMBIT, BODY) \ + P_I_LOOP_BASE(BIT, IMMBIT) \ + P_ONE_ULOOP_BODY(BIT, BODY) \ + P_LOOP_END() + +#define P_MUL_LOOP(BIT, BODY) \ + P_MUL_LOOP_BASE(BIT) \ + P_MUL_LOOP_BODY(BIT, BODY) \ + P_PAIR_LOOP_END() + +#define P_MUL_ULOOP(BIT, BODY) \ + P_MUL_LOOP_BASE(BIT) \ + P_MUL_ULOOP_BODY(BIT, BODY) \ + P_PAIR_LOOP_END() + +#define P_MUL_CROSS_LOOP(BIT, BODY) \ + P_MUL_LOOP_BASE(BIT) \ + P_MUL_CROSS_LOOP_BODY(BIT, BODY) \ + P_PAIR_LOOP_END() + +#define P_MUL_CROSS_ULOOP(BIT, BODY) \ + P_MUL_LOOP_BASE(BIT) \ + P_MUL_CROSS_ULOOP_BODY(BIT, BODY) \ + P_PAIR_LOOP_END() + +#define P_REDUCTION_LOOP(BIT, BIT_INNER, USE_RD, IS_SAT, BODY) \ + P_REDUCTION_LOOP_BASE(BIT, BIT_INNER, USE_RD) \ + P_REDUCTION_PARAMS(BIT_INNER) \ + BODY \ + P_REDUCTION_LOOP_END(BIT, IS_SAT) + +#define P_REDUCTION_ULOOP(BIT, BIT_INNER, USE_RD, IS_SAT, BODY) \ + P_REDUCTION_ULOOP_BASE(BIT, BIT_INNER, USE_RD) \ + P_REDUCTION_UPARAMS(BIT_INNER) \ + BODY \ + P_REDUCTION_ULOOP_END(BIT, IS_SAT) + +#define P_REDUCTION_SULOOP(BIT, BIT_INNER, USE_RD, IS_SAT, BODY) \ + P_REDUCTION_LOOP_BASE(BIT, BIT_INNER, USE_RD) \ + P_REDUCTION_SUPARAMS(BIT_INNER) \ + BODY \ + P_REDUCTION_LOOP_END(BIT, IS_SAT) + +#define P_REDUCTION_CROSS_LOOP(BIT, BIT_INNER, USE_RD, IS_SAT, BODY) \ + P_REDUCTION_LOOP_BASE(BIT, BIT_INNER, USE_RD) \ + P_REDUCTION_CROSS_PARAMS(BIT_INNER) \ + BODY \ + P_REDUCTION_LOOP_END(BIT, IS_SAT) + +#define P_LOOP_END() \ + } \ + WRITE_RD(sext_xlen(rd_tmp)); + +#define P_PAIR_LOOP_END() \ + } \ + if (xlen == 32) { \ + WRITE_RD_PAIR(rd_tmp); \ + } \ + else { \ + WRITE_RD(sext_xlen(rd_tmp)); \ + } + +#define P_REDUCTION_LOOP_END(BIT, IS_SAT) \ + } \ + if (IS_SAT) { \ + P_SAT(pd_res, BIT); \ + } \ + type_usew_t::type pd = pd_res; \ + WRITE_PD(); \ + } \ + WRITE_RD(sext_xlen(rd_tmp)); + +#define P_REDUCTION_ULOOP_END(BIT, IS_SAT) \ + } \ + if (IS_SAT) { \ + P_SATU(pd_res, BIT); \ + } \ + type_usew_t::type pd = pd_res; \ + WRITE_PD(); \ + } \ + WRITE_RD(sext_xlen(rd_tmp)); + +#define P_SUNPKD8(X, Y) \ + require_extension(EXT_ZPN); \ + reg_t rd_tmp = 0; \ + int16_t pd[4] = { \ + P_SB(RS1, Y), \ + P_SB(RS1, X), \ + P_SB(RS1, Y + 4), \ + P_SB(RS1, X + 4), \ + }; \ + if (xlen == 64) { \ + memcpy(&rd_tmp, pd, 8); \ + } else { \ + memcpy(&rd_tmp, pd, 4); \ + } \ + WRITE_RD(sext_xlen(rd_tmp)); + +#define P_ZUNPKD8(X, Y) \ + require_extension(EXT_ZPN); \ + reg_t rd_tmp = 0; \ + uint16_t pd[4] = { \ + P_B(RS1, Y), \ + P_B(RS1, X), \ + P_B(RS1, Y + 4), \ + P_B(RS1, X + 4), \ + }; \ + if (xlen == 64) { \ + memcpy(&rd_tmp, pd, 8); \ + } else { \ + memcpy(&rd_tmp, pd, 4); \ + } \ + WRITE_RD(sext_xlen(rd_tmp)); + +#define P_PK(BIT, X, Y) \ + require_extension(EXT_ZPN); \ + require(BIT == e16 || BIT == e32); \ + reg_t rd_tmp = 0, UNUSED rs1 = RS1, UNUSED rs2 = RS2; \ + for (sreg_t i = 0; i < xlen / BIT / 2; i++) { \ + rd_tmp = set_field(rd_tmp, make_mask64(i * 2 * BIT, BIT), \ + P_UFIELD(RS2, i * 2 + Y, BIT)); \ + rd_tmp = set_field(rd_tmp, make_mask64((i * 2 + 1) * BIT, BIT), \ + P_UFIELD(RS1, i * 2 + X, BIT)); \ + } \ + WRITE_RD(sext_xlen(rd_tmp)); + +#define P_64_PROFILE_BASE() \ + require_extension(EXT_ZPSFOPERAND); \ + sreg_t rd, rs1, rs2; + +#define P_64_UPROFILE_BASE() \ + require_extension(EXT_ZPSFOPERAND); \ + reg_t rd, rs1, rs2; + +#define P_64_PROFILE_PARAM(USE_RD, INPUT_PAIR) \ + if (xlen == 32) { \ + rs1 = INPUT_PAIR ? RS1_PAIR : RS1; \ + rs2 = INPUT_PAIR ? RS2_PAIR : RS2; \ + rd = USE_RD ? RD_PAIR : 0; \ + } else { \ + rs1 = RS1; \ + rs2 = RS2; \ + rd = USE_RD ? RD : 0; \ + } + +#define P_64_PROFILE(BODY) \ + P_64_PROFILE_BASE() \ + P_64_PROFILE_PARAM(false, true) \ + BODY \ + P_64_PROFILE_END() \ + +#define P_64_UPROFILE(BODY) \ + P_64_UPROFILE_BASE() \ + P_64_PROFILE_PARAM(false, true) \ + BODY \ + P_64_PROFILE_END() \ + +#define P_64_PROFILE_REDUCTION(BIT, BODY) \ + P_64_PROFILE_BASE() \ + P_64_PROFILE_PARAM(true, false) \ + for (sreg_t i = 0; i < xlen / BIT; i++) { \ + sreg_t ps1 = P_FIELD(rs1, i, BIT); \ + sreg_t ps2 = P_FIELD(rs2, i, BIT); \ + BODY \ + } \ + P_64_PROFILE_END() \ + +#define P_64_UPROFILE_REDUCTION(BIT, BODY) \ + P_64_UPROFILE_BASE() \ + P_64_PROFILE_PARAM(true, false) \ + for (sreg_t i = 0; i < xlen / BIT; i++) { \ + reg_t ps1 = P_UFIELD(rs1, i, BIT); \ + reg_t ps2 = P_UFIELD(rs2, i, BIT); \ + BODY \ + } \ + P_64_PROFILE_END() \ + +#define P_64_PROFILE_END() \ + if (xlen == 32) { \ + WRITE_RD_PAIR(rd); \ + } else { \ + WRITE_RD(sext_xlen(rd)); \ + } + +#endif diff --git a/vendor/riscv/riscv-isa-sim/riscv/platform.h b/vendor/riscv/riscv-isa-sim/riscv/platform.h index 6618d44e4..7fffdc84b 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/platform.h +++ b/vendor/riscv/riscv-isa-sim/riscv/platform.h @@ -2,9 +2,19 @@ #ifndef _RISCV_PLATFORM_H #define _RISCV_PLATFORM_H +#define DEFAULT_KERNEL_BOOTARGS "console=ttyS0 earlycon" #define DEFAULT_RSTVEC 0x00001000 #define CLINT_BASE 0x02000000 #define CLINT_SIZE 0x000c0000 +#define PLIC_BASE 0x0c000000 +#define PLIC_SIZE 0x01000000 +#define PLIC_NDEV 31 +#define PLIC_PRIO_BITS 4 +#define NS16550_BASE 0x10000000 +#define NS16550_SIZE 0x100 +#define NS16550_REG_SHIFT 0 +#define NS16550_REG_IO_WIDTH 1 +#define NS16550_INTERRUPT_ID 1 #define EXT_IO_BASE 0x40000000 #define DRAM_BASE 0x80000000 diff --git a/vendor/riscv/riscv-isa-sim/riscv/plic.cc b/vendor/riscv/riscv-isa-sim/riscv/plic.cc new file mode 100644 index 000000000..37a5f53ba --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/plic.cc @@ -0,0 +1,390 @@ +#include +#include "devices.h" +#include "processor.h" +#include "simif.h" + +#define PLIC_MAX_CONTEXTS 15872 + +/* + * The PLIC consists of memory-mapped control registers, with a memory map + * as follows: + * + * base + 0x000000: Reserved (interrupt source 0 does not exist) + * base + 0x000004: Interrupt source 1 priority + * base + 0x000008: Interrupt source 2 priority + * ... + * base + 0x000FFC: Interrupt source 1023 priority + * base + 0x001000: Pending 0 + * base + 0x001FFF: Pending + * base + 0x002000: Enable bits for sources 0-31 on context 0 + * base + 0x002004: Enable bits for sources 32-63 on context 0 + * ... + * base + 0x0020FC: Enable bits for sources 992-1023 on context 0 + * base + 0x002080: Enable bits for sources 0-31 on context 1 + * ... + * base + 0x002100: Enable bits for sources 0-31 on context 2 + * ... + * base + 0x1F1F80: Enable bits for sources 992-1023 on context 15871 + * base + 0x1F1F84: Reserved + * ... (higher context IDs would fit here, but wouldn't fit + * inside the per-context priority vector) + * base + 0x1FFFFC: Reserved + * base + 0x200000: Priority threshold for context 0 + * base + 0x200004: Claim/complete for context 0 + * base + 0x200008: Reserved + * ... + * base + 0x200FFC: Reserved + * base + 0x201000: Priority threshold for context 1 + * base + 0x201004: Claim/complete for context 1 + * ... + * base + 0xFFE000: Priority threshold for context 15871 + * base + 0xFFE004: Claim/complete for context 15871 + * base + 0xFFE008: Reserved + * ... + * base + 0xFFFFFC: Reserved + */ + +/* Each interrupt source has a priority register associated with it. */ +#define PRIORITY_BASE 0 +#define PRIORITY_PER_ID 4 + +/* Each interrupt source has a pending bit associated with it. */ +#define PENDING_BASE 0x1000 + +/* + * Each hart context has a vector of interupt enable bits associated with it. + * There's one bit for each interrupt source. + */ +#define ENABLE_BASE 0x2000 +#define ENABLE_PER_HART 0x80 + +/* + * Each hart context has a set of control registers associated with it. Right + * now there's only two: a source priority threshold over which the hart will + * take an interrupt, and a register to claim interrupts. + */ +#define CONTEXT_BASE 0x200000 +#define CONTEXT_PER_HART 0x1000 +#define CONTEXT_THRESHOLD 0 +#define CONTEXT_CLAIM 4 + +#define REG_SIZE 0x1000000 + +plic_t::plic_t(simif_t* sim, uint32_t ndev) + : num_ids(ndev + 1), num_ids_word(((ndev + 1) + (32 - 1)) / 32), + max_prio((1UL << PLIC_PRIO_BITS) - 1), priority{}, level{} +{ + // PLIC contexts are contiguous in memory even if harts are discontiguous. + for (const auto& [hart_id, hart] : sim->get_harts()) { + contexts.push_back(plic_context_t(hart, true)); + + if (hart->extension_enabled_const('S')) { + contexts.push_back(plic_context_t(hart, false)); + } + } +} + +uint32_t plic_t::context_best_pending(const plic_context_t *c) +{ + uint8_t best_id_prio = 0; + uint32_t best_id = 0; + + for (uint32_t i = 0; i < num_ids_word; i++) { + if (!c->pending[i]) { + continue; + } + + for (uint32_t j = 0; j < 32; j++) { + uint32_t id = i * 32 + j; + if ((num_ids <= id) || + !(c->pending[i] & (1 << j)) || + (c->claimed[i] & (1 << j))) { + continue; + } + + if (!best_id || + (best_id_prio < c->pending_priority[id])) { + best_id = id; + best_id_prio = c->pending_priority[id]; + } + } + } + + return best_id; +} + +void plic_t::context_update(const plic_context_t *c) +{ + uint32_t best_id = context_best_pending(c); + reg_t mask = c->mmode ? MIP_MEIP : MIP_SEIP; + + c->proc->state.mip->backdoor_write_with_mask(mask, best_id ? mask : 0); +} + +uint32_t plic_t::context_claim(plic_context_t *c) +{ + uint32_t best_id = context_best_pending(c); + uint32_t best_id_word = best_id / 32; + uint32_t best_id_mask = (1 << (best_id % 32)); + + if (best_id) { + c->claimed[best_id_word] |= best_id_mask; + } + + context_update(c); + return best_id; +} + +bool plic_t::priority_read(reg_t offset, uint32_t *val) +{ + uint32_t id = (offset >> 2); + + if (id > 0 && id < num_ids) + *val = priority[id]; + else + *val = 0; + + return true; +} + +bool plic_t::priority_write(reg_t offset, uint32_t val) +{ + uint32_t id = (offset >> 2); + + if (id > 0 && id < num_ids) { + val &= ((1 << PLIC_PRIO_BITS) - 1); + priority[id] = val; + } + + return true; +} + +bool plic_t::pending_read(reg_t offset, uint32_t *val) +{ + uint32_t id_word = (offset >> 2); + + if (id_word < num_ids_word) { + *val = 0; + for (auto context: contexts) { + *val |= context.pending[id_word]; + } + } else + *val = 0; + + return true; +} + +bool plic_t::context_enable_read(const plic_context_t *c, + reg_t offset, uint32_t *val) +{ + uint32_t id_word = offset >> 2; + + if (id_word < num_ids_word) + *val = c->enable[id_word]; + else + *val = 0; + + return true; +} + +bool plic_t::context_enable_write(plic_context_t *c, + reg_t offset, uint32_t val) +{ + uint32_t id_word = offset >> 2; + + if (id_word >= num_ids_word) + return true; + + uint32_t old_val = c->enable[id_word]; + uint32_t new_val = id_word == 0 ? val & ~(uint32_t)1 : val; + uint32_t xor_val = old_val ^ new_val; + + c->enable[id_word] = new_val; + + for (uint32_t i = 0; i < 32; i++) { + uint32_t id = id_word * 32 + i; + uint32_t id_mask = 1 << i; + uint8_t id_prio = priority[id]; + if (!(xor_val & id_mask)) { + continue; + } + if ((new_val & id_mask) && + (level[id_word] & id_mask)) { + c->pending[id_word] |= id_mask; + c->pending_priority[id] = id_prio; + } else if (!(new_val & id_mask)) { + c->pending[id_word] &= ~id_mask; + c->pending_priority[id] = 0; + c->claimed[id_word] &= ~id_mask; + } + } + + context_update(c); + return true; +} + +bool plic_t::context_read(plic_context_t *c, + reg_t offset, uint32_t *val) +{ + switch (offset) { + case CONTEXT_THRESHOLD: + *val = c->priority_threshold; + return true; + case CONTEXT_CLAIM: + *val = context_claim(c); + return true; + default: + return true; + }; +} + +bool plic_t::context_write(plic_context_t *c, + reg_t offset, uint32_t val) +{ + bool ret = true, update = false; + + switch (offset) { + case CONTEXT_THRESHOLD: + val &= ((1 << PLIC_PRIO_BITS) - 1); + if (val <= max_prio) { + c->priority_threshold = val; + update = true; + } else { + ret = false; + } + break; + case CONTEXT_CLAIM: { + uint32_t id_word = val / 32; + uint32_t id_mask = 1 << (val % 32); + if ((val < num_ids) && + (c->enable[id_word] & id_mask)) { + c->claimed[id_word] &= ~id_mask; + update = true; + } + break; + } + default: + ret = false; + break; + }; + + if (update) { + context_update(c); + } + + return ret; +} + +void plic_t::set_interrupt_level(uint32_t id, int lvl) +{ + if (id <= 0 || num_ids <= id) { + return; + } + + uint8_t id_prio = priority[id]; + uint32_t id_word = id / 32; + uint32_t id_mask = 1 << (id % 32); + + if (lvl) { + level[id_word] |= id_mask; + } else { + level[id_word] &= ~id_mask; + } + + /* + * Note: PLIC interrupts are level-triggered. As of now, + * there is no notion of edge-triggered interrupts. To + * handle this we auto-clear edge-triggered interrupts + * when PLIC context CLAIM register is read. + */ + for (size_t i = 0; i < contexts.size(); i++) { + plic_context_t* c = &contexts[i]; + + if (c->enable[id_word] & id_mask) { + if (lvl) { + c->pending[id_word] |= id_mask; + c->pending_priority[id] = id_prio; + } else { + c->pending[id_word] &= ~id_mask; + c->pending_priority[id] = 0; + c->claimed[id_word] &= ~id_mask; + } + context_update(c); + break; + } + } +} + +bool plic_t::load(reg_t addr, size_t len, uint8_t* bytes) +{ + bool ret = false; + uint32_t val = 0; + + switch (len) { + case 4: + break; + case 8: + // Implement double-word loads as a pair of word loads + return load(addr, 4, bytes) && load(addr + 4, 4, bytes + 4); + default: + // Subword loads are not supported + return false; + } + + if (PRIORITY_BASE <= addr && addr < PENDING_BASE) { + ret = priority_read(addr, &val); + } else if (PENDING_BASE <= addr && addr < ENABLE_BASE) { + ret = pending_read(addr - PENDING_BASE, &val); + } else if (ENABLE_BASE <= addr && addr < CONTEXT_BASE) { + uint32_t cntx = (addr - ENABLE_BASE) / ENABLE_PER_HART; + addr -= cntx * ENABLE_PER_HART + ENABLE_BASE; + if (cntx < contexts.size()) { + ret = context_enable_read(&contexts[cntx], addr, &val); + } + } else if (CONTEXT_BASE <= addr && addr < REG_SIZE) { + uint32_t cntx = (addr - CONTEXT_BASE) / CONTEXT_PER_HART; + addr -= cntx * CONTEXT_PER_HART + CONTEXT_BASE; + if (cntx < contexts.size()) { + ret = context_read(&contexts[cntx], addr, &val); + } + } + + read_little_endian_reg(val, addr, len, bytes); + + return ret; +} + +bool plic_t::store(reg_t addr, size_t len, const uint8_t* bytes) +{ + bool ret = false; + uint32_t val = 0; + + switch (len) { + case 4: + break; + case 8: + // Implement double-word stores as a pair of word stores + return store(addr, 4, bytes) && store(addr + 4, 4, bytes + 4); + default: + // Subword stores are not supported + return false; + } + + write_little_endian_reg(&val, addr, len, bytes); + + if (PRIORITY_BASE <= addr && addr < ENABLE_BASE) { + ret = priority_write(addr, val); + } else if (ENABLE_BASE <= addr && addr < CONTEXT_BASE) { + uint32_t cntx = (addr - ENABLE_BASE) / ENABLE_PER_HART; + addr -= cntx * ENABLE_PER_HART + ENABLE_BASE; + if (cntx < contexts.size()) + ret = context_enable_write(&contexts[cntx], addr, val); + } else if (CONTEXT_BASE <= addr && addr < REG_SIZE) { + uint32_t cntx = (addr - CONTEXT_BASE) / CONTEXT_PER_HART; + addr -= cntx * CONTEXT_PER_HART + CONTEXT_BASE; + if (cntx < contexts.size()) + ret = context_write(&contexts[cntx], addr, val); + } + + return ret; +} diff --git a/vendor/riscv/riscv-isa-sim/riscv/processor.cc b/vendor/riscv/riscv-isa-sim/riscv/processor.cc index 920792ff1..330bd30c7 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/processor.cc +++ b/vendor/riscv/riscv-isa-sim/riscv/processor.cc @@ -5,10 +5,12 @@ #include "extension.h" #include "common.h" #include "config.h" +#include "decode_macros.h" #include "simif.h" #include "mmu.h" #include "disasm.h" #include "platform.h" +#include "vector_unit.h" #include #include #include @@ -20,52 +22,68 @@ #include #include +#ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wunused-variable" +#endif + #undef STATE #define STATE state -processor_t::processor_t(const char* isa, const char* priv, const char* varch, +processor_t::processor_t(const isa_parser_t *isa, const cfg_t *cfg, simif_t* sim, uint32_t id, bool halt_on_reset, FILE* log_file, std::ostream& sout_) - : debug(false), halt_request(HR_NONE), sim(sim), id(id), xlen(0), + : debug(false), halt_request(HR_NONE), isa(isa), cfg(cfg), sim(sim), id(id), xlen(0), histogram_enabled(false), log_commits_enabled(false), log_file(log_file), sout_(sout_.rdbuf()), halt_on_reset(halt_on_reset), - extension_table(256, false), impl_table(256, false), last_pc(1), executions(1) + in_wfi(false), check_triggers_icount(false), + impl_table(256, false), extension_enable_table(isa->get_extension_table()), + last_pc(1), executions(1), TM(cfg->trigger_count) { VU.p = this; + TM.proc = this; - parse_isa_string(isa); - parse_priv_string(priv); - parse_varch_string(varch); +#ifndef __SIZEOF_INT128__ + if (extension_enabled('V')) { + fprintf(stderr, "V extension is not supported on platforms without __int128 type\n"); + abort(); + } +#endif + + parse_varch_string(cfg->varch()); register_base_instructions(); - mmu = new mmu_t(sim, this); + mmu = new mmu_t(sim, cfg->endianness, this); - disassembler = new disassembler_t(max_xlen); - for (auto e : custom_extensions) - for (auto disasm_insn : e.second->get_disasms()) - disassembler->add_insn(disasm_insn); + disassembler = new disassembler_t(isa); + for (auto e : isa->get_extensions()) + register_extension(e.second); set_pmp_granularity(1 << PMP_SHIFT); - set_pmp_num(state.max_pmp); + set_pmp_num(cfg->pmpregions); - if (max_xlen == 32) + if (isa->get_max_xlen() == 32) set_mmu_capability(IMPL_MMU_SV32); - else if (max_xlen == 64) - set_mmu_capability(IMPL_MMU_SV48); + else if (isa->get_max_xlen() == 64) + set_mmu_capability(IMPL_MMU_SV57); + + set_impl(IMPL_MMU_ASID, true); + set_impl(IMPL_MMU_VMID, true); reset(); } processor_t::~processor_t() { -#ifdef RISCV_ENABLE_HISTOGRAM if (histogram_enabled) { - fprintf(stderr, "PC Histogram size:%zu\n", pc_histogram.size()); - for (auto it : pc_histogram) + std::vector> ordered_histo(pc_histogram.begin(), pc_histogram.end()); + std::sort(ordered_histo.begin(), ordered_histo.end(), + [](auto& lhs, auto& rhs) { return lhs.second < rhs.second; }); + + fprintf(stderr, "PC Histogram size:%zu\n", ordered_histo.size()); + for (auto it : ordered_histo) fprintf(stderr, "%0" PRIx64 " %" PRIu64 "\n", it.first, it.second); } -#endif delete mmu; delete disassembler; @@ -78,17 +96,6 @@ static void bad_option_string(const char *option, const char *value, abort(); } -static void bad_isa_string(const char* isa, const char* msg) -{ - bad_option_string("--isa", isa, msg); -} - -static void bad_priv_string(const char* priv) -{ - fprintf(stderr, "error: bad --priv option %s\n", priv); - abort(); -} - static void bad_varch_string(const char* varch, const char *msg) { bad_option_string("--varch", varch, msg); @@ -152,7 +159,7 @@ void processor_t::parse_varch_string(const char* s) } // The integer should be the power of 2 - if (!check_pow2(vlen) || !check_pow2(elen)){ + if (!check_pow2(vlen) || !check_pow2(elen)) { bad_varch_string(s, "The integer value should be the power of 2"); } @@ -170,192 +177,6 @@ void processor_t::parse_varch_string(const char* s) VU.vstart_alu = vstart_alu; } -void processor_t::parse_priv_string(const char* str) -{ - std::string lowercase = strtolower(str); - bool user = false, supervisor = false; - - if (lowercase == "m") - ; - else if (lowercase == "mu") - user = true; - else if (lowercase == "msu") - user = supervisor = true; - else - bad_priv_string(str); - - if (user) { - max_isa |= reg_t(user) << ('u' - 'a'); - extension_table['U'] = true; - } - - if (supervisor) { - max_isa |= reg_t(supervisor) << ('s' - 'a'); - extension_table['S'] = true; - } -} - -void processor_t::parse_isa_string(const char* str) -{ - isa_string = strtolower(str); - const char* all_subsets = "mafdqchp" -#ifdef __SIZEOF_INT128__ - "v" -#endif - ""; - - max_isa = reg_t(2) << 62; - if (isa_string.compare(0, 4, "rv32") == 0) - max_xlen = 32, max_isa = reg_t(1) << 30; - else if (isa_string.compare(0, 4, "rv64") == 0) - max_xlen = 64; - else - bad_isa_string(str, "ISA strings must begin with RV32 or RV64"); - - switch (isa_string[4]) { - case 'g': - // G = IMAFD_Zicsr_Zifencei, but Spike includes the latter two - // unconditionally, so they need not be explicitly added here. - isa_string = isa_string.substr(0, 4) + "imafd" + isa_string.substr(5); - // Fall through - case 'i': - max_isa |= 1L << ('i' - 'a'); - break; - - case 'e': - max_isa |= 1L << ('e' - 'a'); - break; - - default: - bad_isa_string(str, ("'" + isa_string.substr(0, 4) + "' must be followed by I, E, or G").c_str()); - } - - const char* isa_str = isa_string.c_str(); - auto p = isa_str, subset = all_subsets; - for (p += 5; islower(*p) && !strchr("zsx", *p); ++p) { - while (*subset && (*p != *subset)) - ++subset; - - if (!*subset) { - if (strchr(all_subsets, *p)) - bad_isa_string(str, ("Extension '" + std::string(1, *p) + "' appears too late in ISA string").c_str()); - else - bad_isa_string(str, ("Unsupported extension '" + std::string(1, *p) + "'").c_str()); - } - - switch (*p) { - case 'p': extension_table[EXT_ZBPBO] = true; - extension_table[EXT_ZPN] = true; - extension_table[EXT_ZPSFOPERAND] = true; - extension_table[EXT_ZMMUL] = true; break; - case 'q': max_isa |= 1L << ('d' - 'a'); - // Fall through - case 'd': max_isa |= 1L << ('f' - 'a'); - } - max_isa |= 1L << (*p - 'a'); - extension_table[toupper(*p)] = true; - while (isdigit(*(p + 1))) { - ++p; // skip major version, point, and minor version if presented - if (*(p + 1) == 'p') ++p; - } - p += *(p + 1) == '_'; // underscores may be used to improve readability - } - - while (islower(*p) || (*p == '_')) { - p += *p == '_'; // first underscore is optional - auto end = p; - do ++end; while (*end && *end != '_'); - auto ext_str = std::string(p, end); - if (ext_str == "zfh" || ext_str == "zfhmin") { - if (!((max_isa >> ('f' - 'a')) & 1)) - bad_isa_string(str, ("'" + ext_str + "' extension requires 'F'").c_str()); - extension_table[EXT_ZFHMIN] = true; - if (ext_str == "zfh") - extension_table[EXT_ZFH] = true; - } else if (ext_str == "zicsr") { - // Spike necessarily has Zicsr, because - // Zicsr is implied by the privileged architecture - } else if (ext_str == "zifencei") { - // For compatibility with version 2.0 of the base ISAs, we - // unconditionally include FENCE.I, so Zifencei adds nothing more. - } else if (ext_str == "zihintpause") { - // HINTs encoded in base-ISA instructions are always present. - } else if (ext_str == "zmmul") { - extension_table[EXT_ZMMUL] = true; - } else if (ext_str == "zba") { - extension_table[EXT_ZBA] = true; - } else if (ext_str == "zbb") { - extension_table[EXT_ZBB] = true; - } else if (ext_str == "zbc") { - extension_table[EXT_ZBC] = true; - } else if (ext_str == "zbs") { - extension_table[EXT_ZBS] = true; - } else if (ext_str == "zbkb") { - extension_table[EXT_ZBKB] = true; - } else if (ext_str == "zbkc") { - extension_table[EXT_ZBKC] = true; - } else if (ext_str == "zbkx") { - extension_table[EXT_ZBKX] = true; - } else if (ext_str == "zk") { - extension_table[EXT_ZBKB] = true; - extension_table[EXT_ZBKC] = true; - extension_table[EXT_ZBKX] = true; - extension_table[EXT_ZKND] = true; - extension_table[EXT_ZKNE] = true; - extension_table[EXT_ZKNH] = true; - extension_table[EXT_ZKR] = true; - } else if (ext_str == "zkn") { - extension_table[EXT_ZBKB] = true; - extension_table[EXT_ZBKC] = true; - extension_table[EXT_ZBKX] = true; - extension_table[EXT_ZKND] = true; - extension_table[EXT_ZKNE] = true; - extension_table[EXT_ZKNH] = true; - } else if (ext_str == "zknd") { - extension_table[EXT_ZKND] = true; - } else if (ext_str == "zkne") { - extension_table[EXT_ZKNE] = true; - } else if (ext_str == "zknh") { - extension_table[EXT_ZKNH] = true; - } else if (ext_str == "zks") { - extension_table[EXT_ZBKB] = true; - extension_table[EXT_ZBKC] = true; - extension_table[EXT_ZBKX] = true; - extension_table[EXT_ZKSED] = true; - extension_table[EXT_ZKSH] = true; - } else if (ext_str == "zksed") { - extension_table[EXT_ZKSED] = true; - } else if (ext_str == "zksh") { - extension_table[EXT_ZKSH] = true; - } else if (ext_str == "zkr") { - extension_table[EXT_ZKR] = true; - } else if (ext_str == "zkt") { - } else if (ext_str == "svnapot") { - extension_table[EXT_SVNAPOT] = true; - } else if (ext_str == "svpbmt") { - extension_table[EXT_SVPBMT] = true; - } else if (ext_str == "svinval") { - extension_table[EXT_SVINVAL] = true; - } else if (ext_str[0] == 'x') { - max_isa |= 1L << ('x' - 'a'); - extension_table[toupper('x')] = true; - if (ext_str == "xbitmanip") { - extension_table[EXT_XBITMANIP] = true; - } else if (ext_str.size() == 1) { - bad_isa_string(str, "single 'X' is not a proper name"); - } else if (ext_str != "xdummy") { - register_extension(find_extension(ext_str.substr(1).c_str())()); - } - } else { - bad_isa_string(str, ("unsupported extension: " + ext_str).c_str()); - } - p = end; - } - if (*p) { - bad_isa_string(str, ("can't parse: " + std::string(p)).c_str()); - } -} - static int xlen_to_uxl(int xlen) { if (xlen == 32) @@ -365,8 +186,6 @@ static int xlen_to_uxl(int xlen) abort(); } -const int state_t::num_triggers; - void state_t::reset(processor_t* const proc, reg_t max_isa) { pc = DEFAULT_RSTVEC; @@ -375,55 +194,88 @@ void state_t::reset(processor_t* const proc, reg_t max_isa) // This assumes xlen is always max_xlen, which is true today (see // mstatus_csr_t::unlogged_write()): - auto xlen = proc->get_max_xlen(); + auto xlen = proc->get_isa().get_max_xlen(); prv = PRV_M; v = false; csrmap[CSR_MISA] = misa = std::make_shared(proc, CSR_MISA, max_isa); - csrmap[CSR_MSTATUS] = mstatus = std::make_shared(proc, CSR_MSTATUS); - if (xlen == 32) csrmap[CSR_MSTATUSH] = std::make_shared(proc, CSR_MSTATUSH, mstatus); + mstatus = std::make_shared(proc, CSR_MSTATUS); + + if (xlen == 32) { + csrmap[CSR_MSTATUS] = std::make_shared(proc, CSR_MSTATUS, mstatus); + csrmap[CSR_MSTATUSH] = mstatush = std::make_shared(proc, CSR_MSTATUSH, mstatus); + } else { + csrmap[CSR_MSTATUS] = mstatus; + } csrmap[CSR_MEPC] = mepc = std::make_shared(proc, CSR_MEPC); csrmap[CSR_MTVAL] = mtval = std::make_shared(proc, CSR_MTVAL, 0); csrmap[CSR_MSCRATCH] = std::make_shared(proc, CSR_MSCRATCH, 0); csrmap[CSR_MTVEC] = mtvec = std::make_shared(proc, CSR_MTVEC); csrmap[CSR_MCAUSE] = mcause = std::make_shared(proc, CSR_MCAUSE); - csrmap[CSR_MINSTRET] = minstret = std::make_shared(proc, CSR_MINSTRET); - csrmap[CSR_MCYCLE] = std::make_shared(proc, CSR_MCYCLE, minstret); - csrmap[CSR_INSTRET] = std::make_shared(proc, CSR_INSTRET, minstret); - csrmap[CSR_CYCLE] = std::make_shared(proc, CSR_CYCLE, minstret); - if (xlen == 32) { - minstreth_csr_t_p minstreth; - csrmap[CSR_MINSTRETH] = minstreth = std::make_shared(proc, CSR_MINSTRETH, minstret); - csrmap[CSR_MCYCLEH] = std::make_shared(proc, CSR_MCYCLEH, minstreth); - csrmap[CSR_INSTRETH] = std::make_shared(proc, CSR_INSTRETH, minstreth); - csrmap[CSR_CYCLEH] = std::make_shared(proc, CSR_CYCLEH, minstreth); + minstret = std::make_shared(proc, CSR_MINSTRET); + mcycle = std::make_shared(proc, CSR_MCYCLE); + time = std::make_shared(proc, CSR_TIME); + if (proc->extension_enabled_const(EXT_ZICNTR)) { + csrmap[CSR_INSTRET] = std::make_shared(proc, CSR_INSTRET, minstret); + csrmap[CSR_CYCLE] = std::make_shared(proc, CSR_CYCLE, mcycle); + csrmap[CSR_TIME] = time_proxy = std::make_shared(proc, CSR_TIME, time); } - for (reg_t i=3; i<=31; ++i) { + if (xlen == 32) { + csr_t_p minstreth, mcycleh; + csrmap[CSR_MINSTRET] = std::make_shared(proc, CSR_MINSTRET, minstret); + csrmap[CSR_MINSTRETH] = minstreth = std::make_shared(proc, CSR_MINSTRETH, minstret); + csrmap[CSR_MCYCLE] = std::make_shared(proc, CSR_MCYCLE, mcycle); + csrmap[CSR_MCYCLEH] = mcycleh = std::make_shared(proc, CSR_MCYCLEH, mcycle); + if (proc->extension_enabled_const(EXT_ZICNTR)) { + auto timeh = std::make_shared(proc, CSR_TIMEH, time); + csrmap[CSR_INSTRETH] = std::make_shared(proc, CSR_INSTRETH, minstreth); + csrmap[CSR_CYCLEH] = std::make_shared(proc, CSR_CYCLEH, mcycleh); + csrmap[CSR_TIMEH] = std::make_shared(proc, CSR_TIMEH, timeh); + } + } else { + csrmap[CSR_MINSTRET] = minstret; + csrmap[CSR_MCYCLE] = mcycle; + } + for (reg_t i = 3; i < N_HPMCOUNTERS + 3; ++i) { const reg_t which_mevent = CSR_MHPMEVENT3 + i - 3; + const reg_t which_meventh = CSR_MHPMEVENT3H + i - 3; const reg_t which_mcounter = CSR_MHPMCOUNTER3 + i - 3; const reg_t which_mcounterh = CSR_MHPMCOUNTER3H + i - 3; const reg_t which_counter = CSR_HPMCOUNTER3 + i - 3; const reg_t which_counterh = CSR_HPMCOUNTER3H + i - 3; - auto mevent = std::make_shared(proc, which_mevent, 0); + mevent[i - 3] = std::make_shared(proc, which_mevent); auto mcounter = std::make_shared(proc, which_mcounter, 0); - auto counter = std::make_shared(proc, which_counter, mcounter); - csrmap[which_mevent] = mevent; csrmap[which_mcounter] = mcounter; - csrmap[which_counter] = counter; + + if (proc->extension_enabled_const(EXT_ZIHPM)) { + auto counter = std::make_shared(proc, which_counter, mcounter); + csrmap[which_counter] = counter; + } if (xlen == 32) { + csrmap[which_mevent] = std::make_shared(proc, which_mevent, mevent[i - 3]);; auto mcounterh = std::make_shared(proc, which_mcounterh, 0); - auto counterh = std::make_shared(proc, which_counterh, mcounterh); csrmap[which_mcounterh] = mcounterh; - csrmap[which_counterh] = counterh; + if (proc->extension_enabled_const(EXT_ZIHPM)) { + auto counterh = std::make_shared(proc, which_counterh, mcounterh); + csrmap[which_counterh] = counterh; + } + if (proc->extension_enabled_const(EXT_SSCOFPMF)) { + auto meventh = std::make_shared(proc, which_meventh, mevent[i - 3]); + csrmap[which_meventh] = meventh; + } + } else { + csrmap[which_mevent] = mevent[i - 3]; } } csrmap[CSR_MCOUNTINHIBIT] = std::make_shared(proc, CSR_MCOUNTINHIBIT, 0); + if (proc->extension_enabled_const(EXT_SSCOFPMF)) + csrmap[CSR_SCOUNTOVF] = std::make_shared(proc, CSR_SCOUNTOVF); csrmap[CSR_MIE] = mie = std::make_shared(proc, CSR_MIE); csrmap[CSR_MIP] = mip = std::make_shared(proc, CSR_MIP); auto sip_sie_accr = std::make_shared( this, ~MIP_HS_MASK, // read_mask - MIP_SSIP, // ip_write_mask + MIP_SSIP | MIP_LCOFIP, // ip_write_mask ~MIP_HS_MASK, // ie_write_mask generic_int_accessor_t::mask_mode_t::MIDELEG, 0 // shiftamt @@ -471,7 +323,7 @@ void state_t::reset(processor_t* const proc, reg_t max_isa) csrmap[CSR_MEDELEG] = medeleg = std::make_shared(proc, CSR_MEDELEG); csrmap[CSR_MIDELEG] = mideleg = std::make_shared(proc, CSR_MIDELEG); - const reg_t counteren_mask = 0xffffffffULL; + const reg_t counteren_mask = (proc->extension_enabled_const(EXT_ZICNTR) ? 0x7UL : 0x0) | (proc->extension_enabled_const(EXT_ZIHPM) ? 0xfffffff8ULL : 0x0); mcounteren = std::make_shared(proc, CSR_MCOUNTEREN, counteren_mask, 0); if (proc->extension_enabled_const('U')) csrmap[CSR_MCOUNTEREN] = mcounteren; csrmap[CSR_SCOUNTEREN] = scounteren = std::make_shared(proc, CSR_SCOUNTEREN, counteren_mask, 0); @@ -520,6 +372,13 @@ void state_t::reset(processor_t* const proc, reg_t max_isa) (1 << CAUSE_STORE_PAGE_FAULT); csrmap[CSR_HEDELEG] = hedeleg = std::make_shared(proc, CSR_HEDELEG, hedeleg_mask, 0); csrmap[CSR_HCOUNTEREN] = hcounteren = std::make_shared(proc, CSR_HCOUNTEREN, counteren_mask, 0); + htimedelta = std::make_shared(proc, CSR_HTIMEDELTA, 0); + if (xlen == 32) { + csrmap[CSR_HTIMEDELTA] = std::make_shared(proc, CSR_HTIMEDELTA, htimedelta); + csrmap[CSR_HTIMEDELTAH] = std::make_shared(proc, CSR_HTIMEDELTAH, htimedelta); + } else { + csrmap[CSR_HTIMEDELTA] = htimedelta; + } csrmap[CSR_HTVAL] = htval = std::make_shared(proc, CSR_HTVAL, 0); csrmap[CSR_HTINST] = htinst = std::make_shared(proc, CSR_HTINST, 0); csrmap[CSR_HGATP] = hgatp = std::make_shared(proc, CSR_HGATP); @@ -533,21 +392,32 @@ void state_t::reset(processor_t* const proc, reg_t max_isa) csrmap[CSR_DCSR] = dcsr = std::make_shared(proc, CSR_DCSR); csrmap[CSR_TSELECT] = tselect = std::make_shared(proc, CSR_TSELECT); - memset(this->mcontrol, 0, sizeof(this->mcontrol)); - for (auto &item : mcontrol) - item.type = 2; - - csrmap[CSR_TDATA1] = std::make_shared(proc, CSR_TDATA1); - csrmap[CSR_TDATA2] = tdata2 = std::make_shared(proc, CSR_TDATA2, num_triggers); - csrmap[CSR_TDATA3] = std::make_shared(proc, CSR_TDATA3, 0); + if (proc->get_cfg().trigger_count > 0) { + csrmap[CSR_TDATA1] = std::make_shared(proc, CSR_TDATA1); + csrmap[CSR_TDATA2] = tdata2 = std::make_shared(proc, CSR_TDATA2); + csrmap[CSR_TDATA3] = std::make_shared(proc, CSR_TDATA3); + csrmap[CSR_TINFO] = std::make_shared(proc, CSR_TINFO); + } else { + csrmap[CSR_TDATA1] = std::make_shared(proc, CSR_TDATA1, 0); + csrmap[CSR_TDATA2] = tdata2 = std::make_shared(proc, CSR_TDATA2, 0); + csrmap[CSR_TDATA3] = std::make_shared(proc, CSR_TDATA3, 0); + csrmap[CSR_TINFO] = std::make_shared(proc, CSR_TINFO, 0); + } + unsigned scontext_length = (xlen == 32 ? 16 : 34); // debug spec suggests 16-bit for RV32 and 34-bit for RV64 + csrmap[CSR_SCONTEXT] = scontext = std::make_shared(proc, CSR_SCONTEXT, (reg_t(1) << scontext_length) - 1, 0); + unsigned hcontext_length = (xlen == 32 ? 6 : 13) + (proc->extension_enabled('H') ? 1 : 0); // debug spec suggest 7-bit (6-bit) for RV32 and 14-bit (13-bit) for RV64 with (without) H extension + csrmap[CSR_HCONTEXT] = std::make_shared(proc, CSR_HCONTEXT, (reg_t(1) << hcontext_length) - 1, 0); + csrmap[CSR_MCONTEXT] = mcontext = std::make_shared(proc, CSR_MCONTEXT, csrmap[CSR_HCONTEXT]); debug_mode = false; single_step = STEP_NONE; - for (int i=0; i < max_pmp; ++i) { + csrmap[CSR_MSECCFG] = mseccfg = std::make_shared(proc, CSR_MSECCFG); + + for (int i = 0; i < max_pmp; ++i) { csrmap[CSR_PMPADDR0 + i] = pmpaddr[i] = std::make_shared(proc, CSR_PMPADDR0 + i); } - for (int i=0; i < max_pmp; i += xlen/8) { - reg_t addr = CSR_PMPCFG0 + i/4; + for (int i = 0; i < max_pmp; i += xlen / 8) { + reg_t addr = CSR_PMPCFG0 + i / 4; csrmap[addr] = std::make_shared(proc, addr); } @@ -562,75 +432,101 @@ void state_t::reset(processor_t* const proc, reg_t max_isa) csrmap[CSR_MIMPID] = std::make_shared(proc, CSR_MIMPID, 0); csrmap[CSR_MVENDORID] = std::make_shared(proc, CSR_MVENDORID, 0); csrmap[CSR_MHARTID] = std::make_shared(proc, CSR_MHARTID, proc->get_id()); + csrmap[CSR_MCONFIGPTR] = std::make_shared(proc, CSR_MCONFIGPTR, 0); + if (proc->extension_enabled_const('U')) { + const reg_t menvcfg_mask = (proc->extension_enabled(EXT_ZICBOM) ? MENVCFG_CBCFE | MENVCFG_CBIE : 0) | + (proc->extension_enabled(EXT_ZICBOZ) ? MENVCFG_CBZE : 0) | + (proc->extension_enabled(EXT_SVADU) ? MENVCFG_HADE: 0) | + (proc->extension_enabled(EXT_SVPBMT) ? MENVCFG_PBMTE : 0) | + (proc->extension_enabled(EXT_SSTC) ? MENVCFG_STCE : 0); + const reg_t menvcfg_init = (proc->extension_enabled(EXT_SVPBMT) ? MENVCFG_PBMTE : 0); + menvcfg = std::make_shared(proc, CSR_MENVCFG, menvcfg_mask, menvcfg_init); + if (xlen == 32) { + csrmap[CSR_MENVCFG] = std::make_shared(proc, CSR_MENVCFG, menvcfg); + csrmap[CSR_MENVCFGH] = std::make_shared(proc, CSR_MENVCFGH, menvcfg); + } else { + csrmap[CSR_MENVCFG] = menvcfg; + } + const reg_t senvcfg_mask = (proc->extension_enabled(EXT_ZICBOM) ? SENVCFG_CBCFE | SENVCFG_CBIE : 0) | + (proc->extension_enabled(EXT_ZICBOZ) ? SENVCFG_CBZE : 0); + csrmap[CSR_SENVCFG] = senvcfg = std::make_shared(proc, CSR_SENVCFG, senvcfg_mask, 0); + const reg_t henvcfg_mask = (proc->extension_enabled(EXT_ZICBOM) ? HENVCFG_CBCFE | HENVCFG_CBIE : 0) | + (proc->extension_enabled(EXT_ZICBOZ) ? HENVCFG_CBZE : 0) | + (proc->extension_enabled(EXT_SVADU) ? HENVCFG_HADE: 0) | + (proc->extension_enabled(EXT_SVPBMT) ? HENVCFG_PBMTE : 0) | + (proc->extension_enabled(EXT_SSTC) ? HENVCFG_STCE : 0); + const reg_t henvcfg_init = (proc->extension_enabled(EXT_SVPBMT) ? HENVCFG_PBMTE : 0); + henvcfg = std::make_shared(proc, CSR_HENVCFG, henvcfg_mask, henvcfg_init, menvcfg); + if (xlen == 32) { + csrmap[CSR_HENVCFG] = std::make_shared(proc, CSR_HENVCFG, henvcfg); + csrmap[CSR_HENVCFGH] = std::make_shared(proc, CSR_HENVCFGH, henvcfg); + } else { + csrmap[CSR_HENVCFG] = henvcfg; + } + } + if (proc->extension_enabled_const(EXT_SMSTATEEN)) { + const reg_t sstateen0_mask = (proc->extension_enabled(EXT_ZFINX) ? SSTATEEN0_FCSR : 0) | + (proc->extension_enabled(EXT_ZCMT) ? SSTATEEN0_JVT : 0) | + SSTATEEN0_CS; + const reg_t hstateen0_mask = sstateen0_mask | HSTATEEN0_SENVCFG | HSTATEEN_SSTATEEN; + const reg_t mstateen0_mask = hstateen0_mask; + for (int i = 0; i < 4; i++) { + const reg_t mstateen_mask = i == 0 ? mstateen0_mask : MSTATEEN_HSTATEEN; + mstateen[i] = std::make_shared(proc, CSR_MSTATEEN0 + i, mstateen_mask, 0); + if (xlen == 32) { + csrmap[CSR_MSTATEEN0 + i] = std::make_shared(proc, CSR_MSTATEEN0 + i, mstateen[i]); + csrmap[CSR_MSTATEEN0H + i] = std::make_shared(proc, CSR_MSTATEEN0H + i, mstateen[i]); + } else { + csrmap[CSR_MSTATEEN0 + i] = mstateen[i]; + } + + const reg_t hstateen_mask = i == 0 ? hstateen0_mask : HSTATEEN_SSTATEEN; + hstateen[i] = std::make_shared(proc, CSR_HSTATEEN0 + i, hstateen_mask, 0, i); + if (xlen == 32) { + csrmap[CSR_HSTATEEN0 + i] = std::make_shared(proc, CSR_HSTATEEN0 + i, hstateen[i]); + csrmap[CSR_HSTATEEN0H + i] = std::make_shared(proc, CSR_HSTATEEN0H + i, hstateen[i]); + } else { + csrmap[CSR_HSTATEEN0 + i] = hstateen[i]; + } + + const reg_t sstateen_mask = i == 0 ? sstateen0_mask : 0; + csrmap[CSR_SSTATEEN0 + i] = sstateen[i] = std::make_shared(proc, CSR_HSTATEEN0 + i, sstateen_mask, 0, i); + } + } + + if (proc->extension_enabled_const(EXT_SMRNMI)) { + csrmap[CSR_MNSCRATCH] = std::make_shared(proc, CSR_MNSCRATCH, 0); + csrmap[CSR_MNEPC] = mnepc = std::make_shared(proc, CSR_MNEPC); + csrmap[CSR_MNCAUSE] = std::make_shared(proc, CSR_MNCAUSE, (reg_t)1 << (xlen - 1)); + csrmap[CSR_MNSTATUS] = mnstatus = std::make_shared(proc, CSR_MNSTATUS); + } + + if (proc->extension_enabled_const(EXT_SSTC)) { + stimecmp = std::make_shared(proc, CSR_STIMECMP, MIP_STIP); + vstimecmp = std::make_shared(proc, CSR_VSTIMECMP, MIP_VSTIP); + auto virtualized_stimecmp = std::make_shared(proc, stimecmp, vstimecmp); + if (xlen == 32) { + csrmap[CSR_STIMECMP] = std::make_shared(proc, CSR_STIMECMP, virtualized_stimecmp); + csrmap[CSR_STIMECMPH] = std::make_shared(proc, CSR_STIMECMPH, virtualized_stimecmp); + csrmap[CSR_VSTIMECMP] = std::make_shared(proc, CSR_VSTIMECMP, vstimecmp); + csrmap[CSR_VSTIMECMPH] = std::make_shared(proc, CSR_VSTIMECMPH, vstimecmp); + } else { + csrmap[CSR_STIMECMP] = virtualized_stimecmp; + csrmap[CSR_VSTIMECMP] = vstimecmp; + } + } + + if (proc->extension_enabled(EXT_ZCMT)) + csrmap[CSR_JVT] = jvt = std::make_shared(proc, CSR_JVT, 0); serialized = false; -#ifdef RISCV_ENABLE_COMMITLOG log_reg_write.clear(); log_mem_read.clear(); log_mem_write.clear(); last_inst_priv = 0; last_inst_xlen = 0; last_inst_flen = 0; -#endif -} - -void processor_t::vectorUnit_t::reset(){ - free(reg_file); - VLEN = get_vlen(); - ELEN = get_elen(); - reg_file = malloc(NVPR * vlenb); - memset(reg_file, 0, NVPR * vlenb); - - auto& csrmap = p->get_state()->csrmap; - csrmap[CSR_VXSAT] = vxsat = std::make_shared(p, CSR_VXSAT); - csrmap[CSR_VSTART] = vstart = std::make_shared(p, CSR_VSTART, /*mask*/ VLEN - 1); - csrmap[CSR_VXRM] = vxrm = std::make_shared(p, CSR_VXRM, /*mask*/ 0x3ul); - csrmap[CSR_VL] = vl = std::make_shared(p, CSR_VL, /*mask*/ 0); - csrmap[CSR_VTYPE] = vtype = std::make_shared(p, CSR_VTYPE, /*mask*/ 0); - csrmap[CSR_VLENB] = std::make_shared(p, CSR_VLENB, /*mask*/ 0, /*init*/ vlenb); - assert(VCSR_VXSAT_SHIFT == 0); // composite_csr_t assumes vxsat begins at bit 0 - csrmap[CSR_VCSR] = std::make_shared(p, CSR_VCSR, vxrm, vxsat, VCSR_VXRM_SHIFT); - - vtype->write_raw(0); - set_vl(0, 0, 0, -1); // default to illegal configuration -} - -reg_t processor_t::vectorUnit_t::set_vl(int rd, int rs1, reg_t reqVL, reg_t newType){ - int new_vlmul = 0; - if (vtype->read() != newType){ - vtype->write_raw(newType); - vsew = 1 << (extract64(newType, 3, 3) + 3); - new_vlmul = int8_t(extract64(newType, 0, 3) << 5) >> 5; - vflmul = new_vlmul >= 0 ? 1 << new_vlmul : 1.0 / (1 << -new_vlmul); - vlmax = (VLEN/vsew) * vflmul; - vta = extract64(newType, 6, 1); - vma = extract64(newType, 7, 1); - - vill = !(vflmul >= 0.125 && vflmul <= 8) - || vsew > std::min(vflmul, 1.0f) * ELEN - || (newType >> 8) != 0; - - if (vill) { - vlmax = 0; - vtype->write_raw(UINT64_MAX << (p->get_xlen() - 1)); - } - } - - // set vl - if (vlmax == 0) { - vl->write_raw(0); - } else if (rd == 0 && rs1 == 0) { - vl->write_raw(vl->read() > vlmax ? vlmax : vl->read()); - } else if (rd != 0 && rs1 == 0) { - vl->write_raw(vlmax); - } else if (rs1 != 0) { - vl->write_raw(reqVL > vlmax ? vlmax : reqVL); - } - - vstart->write_raw(0); - setvl_count++; - return vl->read(); } void processor_t::set_debug(bool value) @@ -644,38 +540,30 @@ void processor_t::set_debug(bool value) void processor_t::set_histogram(bool value) { histogram_enabled = value; -#ifndef RISCV_ENABLE_HISTOGRAM - if (value) { - fprintf(stderr, "PC Histogram support has not been properly enabled;"); - fprintf(stderr, " please re-build the riscv-isa-sim project using \"configure --enable-histogram\".\n"); - abort(); - } -#endif } -#ifdef RISCV_ENABLE_COMMITLOG void processor_t::enable_log_commits() { log_commits_enabled = true; } -#endif void processor_t::reset() { - xlen = max_xlen; - state.reset(this, max_isa); + xlen = isa->get_max_xlen(); + state.reset(this, isa->get_max_isa()); state.dcsr->halt = halt_on_reset; halt_on_reset = false; VU.reset(); + in_wfi = false; if (n_pmp > 0) { // For backwards compatibility with software that is unaware of PMP, // initialize PMP to permit unprivileged access to all of memory. - set_csr(CSR_PMPADDR0, ~reg_t(0)); - set_csr(CSR_PMPCFG0, PMP_R | PMP_W | PMP_X | PMP_NAPOT); + put_csr(CSR_PMPADDR0, ~reg_t(0)); + put_csr(CSR_PMPCFG0, PMP_R | PMP_W | PMP_X | PMP_NAPOT); } - for (auto e : custom_extensions) // reset any extensions + for (auto e : custom_extensions) // reset any extensions e.second->reset(); if (sim) @@ -706,16 +594,18 @@ void processor_t::set_pmp_num(reg_t n) { // check the number of pmp is in a reasonable range if (n > state.max_pmp) { - fprintf(stderr, "error: bad number of pmp regions: '%ld' from the dtb\n", (unsigned long)n); + fprintf(stderr, "error: number of PMP regions requested (%" PRIu64 ") exceeds maximum (%d)\n", n, state.max_pmp); abort(); } n_pmp = n; } -void processor_t::set_pmp_granularity(reg_t gran) { +void processor_t::set_pmp_granularity(reg_t gran) +{ // check the pmp granularity is set from dtb(!=0) and is power of 2 - if (gran < (1 << PMP_SHIFT) || (gran & (gran - 1)) != 0) { - fprintf(stderr, "error: bad pmp granularity '%ld' from the dtb\n", (unsigned long)gran); + unsigned min = 1 << PMP_SHIFT; + if (gran < min || (gran & (gran - 1)) != 0) { + fprintf(stderr, "error: PMP granularity (%" PRIu64 ") must be a power of two and at least %u\n", gran, min); abort(); } @@ -726,15 +616,16 @@ void processor_t::set_mmu_capability(int cap) { switch (cap) { case IMPL_MMU_SV32: - set_impl(cap, true); - set_impl(IMPL_MMU, true); - break; - case IMPL_MMU_SV39: - set_impl(cap, true); + set_impl(IMPL_MMU_SV32, true); set_impl(IMPL_MMU, true); break; + case IMPL_MMU_SV57: + set_impl(IMPL_MMU_SV57, true); + // Fall through case IMPL_MMU_SV48: - set_impl(cap, true); + set_impl(IMPL_MMU_SV48, true); + // Fall through + case IMPL_MMU_SV39: set_impl(IMPL_MMU_SV39, true); set_impl(IMPL_MMU, true); break; @@ -742,6 +633,7 @@ void processor_t::set_mmu_capability(int cap) set_impl(IMPL_MMU_SV32, false); set_impl(IMPL_MMU_SV39, false); set_impl(IMPL_MMU_SV48, false); + set_impl(IMPL_MMU_SV57, false); set_impl(IMPL_MMU, false); break; } @@ -754,6 +646,9 @@ void processor_t::take_interrupt(reg_t pending_interrupts) return; } + // Exit WFI if there are any pending interrupts + in_wfi = false; + // M-ints have higher priority over HS-ints and VS-ints const reg_t mie = get_field(state.mstatus->read(), MSTATUS_MIE); const reg_t m_enabled = state.prv < PRV_M || (state.prv == PRV_M && mie); @@ -772,7 +667,8 @@ void processor_t::take_interrupt(reg_t pending_interrupts) } } - if (!state.debug_mode && enabled_interrupts) { + const bool nmie = !(state.mnstatus && !get_field(state.mnstatus->read(), MNSTATUS_NMIE)); + if (!state.debug_mode && nmie && enabled_interrupts) { // nonstandard interrupts have highest priority if (enabled_interrupts >> (IRQ_M_EXT + 1)) enabled_interrupts = enabled_interrupts >> (IRQ_M_EXT + 1) << (IRQ_M_EXT + 1); @@ -789,6 +685,8 @@ void processor_t::take_interrupt(reg_t pending_interrupts) enabled_interrupts = MIP_SSIP; else if (enabled_interrupts & MIP_STIP) enabled_interrupts = MIP_STIP; + else if (enabled_interrupts & MIP_LCOFIP) + enabled_interrupts = MIP_LCOFIP; else if (enabled_interrupts & MIP_VSEIP) enabled_interrupts = MIP_VSEIP; else if (enabled_interrupts & MIP_VSSIP) @@ -798,7 +696,8 @@ void processor_t::take_interrupt(reg_t pending_interrupts) else abort(); - throw trap_t(((reg_t)1 << (max_xlen-1)) | ctz(enabled_interrupts)); + if (check_triggers_icount) TM.detect_icount_match(); + throw trap_t(((reg_t)1 << (isa->get_max_xlen() - 1)) | ctz(enabled_interrupts)); } } @@ -821,6 +720,26 @@ void processor_t::set_privilege(reg_t prv) state.prv = legalize_privilege(prv); } +const char* processor_t::get_privilege_string() +{ + if (state.debug_mode) + return "D"; + if (state.v) { + switch (state.prv) { + case 0x0: return "VU"; + case 0x1: return "VS"; + } + } else { + switch (state.prv) { + case 0x0: return "U"; + case 0x1: return "S"; + case 0x3: return "M"; + } + } + fprintf(stderr, "Invalid prv=%lx v=%x\n", (unsigned long)state.prv, state.v); + abort(); +} + void processor_t::set_virt(bool virt) { reg_t tmp, mask; @@ -848,11 +767,12 @@ void processor_t::enter_debug_mode(uint8_t cause) set_privilege(PRV_M); state.dpc->write(state.pc); state.pc = DEBUG_ROM_ENTRY; + in_wfi = false; } void processor_t::debug_output_log(std::stringstream *s) { - if (log_file==stderr) { + if (log_file == stderr) { std::ostream out(sout_.rdbuf()); out << s->str(); // handles command line options -d -s -l } else { @@ -862,6 +782,8 @@ void processor_t::debug_output_log(std::stringstream *s) void processor_t::take_trap(trap_t& t, reg_t epc) { + unsigned max_xlen = isa->get_max_xlen(); + if (debug) { std::stringstream s; // first put everything in a string, later send it to output s << "core " << std::dec << std::setfill(' ') << std::setw(3) << id @@ -869,7 +791,7 @@ void processor_t::take_trap(trap_t& t, reg_t epc) << std::hex << std::setfill('0') << std::setw(max_xlen/4) << zext(epc, max_xlen) << std::endl; if (t.has_tval()) s << "core " << std::dec << std::setfill(' ') << std::setw(3) << id - << ": tval 0x" << std::hex << std::setfill('0') << std::setw(max_xlen/4) + << ": tval 0x" << std::hex << std::setfill('0') << std::setw(max_xlen / 4) << zext(t.get_tval(), max_xlen) << std::endl; debug_output_log(&s); } @@ -883,30 +805,22 @@ void processor_t::take_trap(trap_t& t, reg_t epc) return; } - if (t.cause() == CAUSE_BREAKPOINT && ( - (state.prv == PRV_M && state.dcsr->ebreakm) || - (state.prv == PRV_S && state.dcsr->ebreaks) || - (state.prv == PRV_U && state.dcsr->ebreaku))) { - enter_debug_mode(DCSR_CAUSE_SWBP); - return; - } - // By default, trap to M-mode, unless delegated to HS-mode or VS-mode reg_t vsdeleg, hsdeleg; reg_t bit = t.cause(); bool curr_virt = state.v; - bool interrupt = (bit & ((reg_t)1 << (max_xlen-1))) != 0; + bool interrupt = (bit & ((reg_t)1 << (max_xlen - 1))) != 0; if (interrupt) { vsdeleg = (curr_virt && state.prv <= PRV_S) ? state.hideleg->read() : 0; hsdeleg = (state.prv <= PRV_S) ? state.mideleg->read() : 0; - bit &= ~((reg_t)1 << (max_xlen-1)); + bit &= ~((reg_t)1 << (max_xlen - 1)); } else { vsdeleg = (curr_virt && state.prv <= PRV_S) ? (state.medeleg->read() & state.hedeleg->read()) : 0; hsdeleg = (state.prv <= PRV_S) ? state.medeleg->read() : 0; } if (state.prv <= PRV_S && bit < max_xlen && ((vsdeleg >> bit) & 1)) { // Handle the trap in VS-mode - reg_t vector = (state.vstvec->read() & 1) && interrupt ? 4*bit : 0; + reg_t vector = (state.vstvec->read() & 1) && interrupt ? 4 * bit : 0; state.pc = (state.vstvec->read() & ~(reg_t)1) + vector; state.vscause->write((interrupt) ? (t.cause() - 1) : t.cause()); state.vsepc->write(epc); @@ -921,7 +835,7 @@ void processor_t::take_trap(trap_t& t, reg_t epc) } else if (state.prv <= PRV_S && bit < max_xlen && ((hsdeleg >> bit) & 1)) { // Handle the trap in HS-mode set_virt(false); - reg_t vector = (state.stvec->read() & 1) && interrupt ? 4*bit : 0; + reg_t vector = (state.stvec->read() & 1) && interrupt ? 4 * bit : 0; state.pc = (state.stvec->read() & ~(reg_t)1) + vector; state.scause->write(t.cause()); state.sepc->write(epc); @@ -946,8 +860,13 @@ void processor_t::take_trap(trap_t& t, reg_t epc) } else { // Handle the trap in M-mode set_virt(false); - reg_t vector = (state.mtvec->read() & 1) && interrupt ? 4*bit : 0; - state.pc = (state.mtvec->read() & ~(reg_t)1) + vector; + const reg_t vector = (state.mtvec->read() & 1) && interrupt ? 4 * bit : 0; + const reg_t trap_handler_address = (state.mtvec->read() & ~(reg_t)1) + vector; + // RNMI exception vector is implementation-defined. Since we don't model + // RNMI sources, the feature isn't very useful, so pick an invalid address. + const reg_t rnmi_trap_handler_address = 0; + const bool nmie = !(state.mnstatus && !get_field(state.mnstatus->read(), MNSTATUS_NMIE)); + state.pc = !nmie ? rnmi_trap_handler_address : trap_handler_address; state.mepc->write(epc); state.mcause->write(t.cause()); state.mtval->write(t.get_tval()); @@ -961,32 +880,61 @@ void processor_t::take_trap(trap_t& t, reg_t epc) s = set_field(s, MSTATUS_MPV, curr_virt); s = set_field(s, MSTATUS_GVA, t.has_gva()); state.mstatus->write(s); + if (state.mstatush) state.mstatush->write(s >> 32); // log mstatush change set_privilege(PRV_M); } } +void processor_t::take_trigger_action(triggers::action_t action, reg_t breakpoint_tval, reg_t epc) +{ + if (debug) { + std::stringstream s; // first put everything in a string, later send it to output + s << "core " << std::dec << std::setfill(' ') << std::setw(3) << id + << ": trigger action " << (int)action << std::endl; + debug_output_log(&s); + } + + switch (action) { + case triggers::ACTION_DEBUG_MODE: + enter_debug_mode(DCSR_CAUSE_HWBP); + break; + case triggers::ACTION_DEBUG_EXCEPTION: { + trap_breakpoint trap(state.v, breakpoint_tval); + take_trap(trap, epc); + break; + } + default: + abort(); + } +} + +const char* processor_t::get_symbol(uint64_t addr) +{ + return sim->get_symbol(addr); +} + void processor_t::disasm(insn_t insn) { - uint64_t bits = insn.bits() & ((1ULL << (8 * insn_length(insn.bits()))) - 1); + uint64_t bits = insn.bits(); if (last_pc != state.pc || last_bits != bits) { std::stringstream s; // first put everything in a string, later send it to output -#ifdef RISCV_ENABLE_COMMITLOG const char* sym = get_symbol(state.pc); if (sym != nullptr) { s << "core " << std::dec << std::setfill(' ') << std::setw(3) << id << ": >>>> " << sym << std::endl; } -#endif if (executions != 1) { s << "core " << std::dec << std::setfill(' ') << std::setw(3) << id << ": Executed " << executions << " times" << std::endl; } + unsigned max_xlen = isa->get_max_xlen(); + s << "core " << std::dec << std::setfill(' ') << std::setw(3) << id - << std::hex << ": 0x" << std::setfill('0') << std::setw(max_xlen/4) + << std::hex << ": 0x" << std::setfill('0') << std::setw(max_xlen / 4) << zext(state.pc, max_xlen) << " (0x" << std::setw(8) << bits << ") " << disassembler->disassemble(insn) << std::endl; @@ -1002,11 +950,12 @@ void processor_t::disasm(insn_t insn) int processor_t::paddr_bits() { + unsigned max_xlen = isa->get_max_xlen(); assert(xlen == max_xlen); return max_xlen == 64 ? 50 : 34; } -void processor_t::set_csr(int which, reg_t val) +void processor_t::put_csr(int which, reg_t val) { val = zext_xlen(val); auto search = state.csrmap.find(which); @@ -1032,9 +981,12 @@ reg_t processor_t::get_csr(int which, insn_t insn, bool write, bool peek) throw trap_illegal_instruction(insn.bits()); } -reg_t illegal_instruction(processor_t* p, insn_t insn, reg_t pc) +reg_t illegal_instruction(processor_t UNUSED *p, insn_t insn, reg_t UNUSED pc) { - throw trap_illegal_instruction(insn.bits()); + // The illegal instruction can be longer than ILEN bits, where the tval will + // contain the first ILEN bits of the faulting instruction. We hard-code the + // ILEN to 32 bits since all official instructions have at most 32 bits. + throw trap_illegal_instruction(insn.bits() & 0xffffffffULL); } insn_func_t processor_t::decode_insn(insn_t insn) @@ -1045,19 +997,19 @@ insn_func_t processor_t::decode_insn(insn_t insn) bool rve = extension_enabled('E'); - if (unlikely(insn.bits() != desc.match || !desc.func(xlen, rve))) { + if (unlikely(insn.bits() != desc.match)) { // fall back to linear search int cnt = 0; insn_desc_t* p = &instructions[0]; - while ((insn.bits() & p->mask) != p->match || !desc.func(xlen, rve)) + while ((insn.bits() & p->mask) != p->match) p++, cnt++; desc = *p; if (p->mask != 0 && p > &instructions[0]) { - if (p->match != (p-1)->match && p->match != (p+1)->match) { + if (p->match != (p - 1)->match && p->match != (p + 1)->match) { // move to front of opcode list to reduce miss penalty while (--p >= &instructions[0]) - *(p+1) = *p; + *(p + 1) = *p; instructions[0] = desc; } } @@ -1066,11 +1018,14 @@ insn_func_t processor_t::decode_insn(insn_t insn) opcode_cache[idx].match = insn.bits(); } - return desc.func(xlen, rve); + return desc.func(xlen, rve, log_commits_enabled); } void processor_t::register_insn(insn_desc_t desc) { + assert(desc.fast_rv32i && desc.fast_rv64i && desc.fast_rv32e && desc.fast_rv64e && + desc.logged_rv32i && desc.logged_rv64i && desc.logged_rv32e && desc.logged_rv64e); + instructions.push_back(desc); } @@ -1095,37 +1050,51 @@ void processor_t::register_extension(extension_t* x) register_insn(insn); build_opcode_map(); - if (disassembler) - for (auto disasm_insn : x->get_disasms()) - disassembler->add_insn(disasm_insn); + for (auto disasm_insn : x->get_disasms()) + disassembler->add_insn(disasm_insn); if (!custom_extensions.insert(std::make_pair(x->name(), x)).second) { fprintf(stderr, "extensions must have unique names (got two named \"%s\"!)\n", x->name()); abort(); } - x->set_processor(this); } void processor_t::register_base_instructions() { #define DECLARE_INSN(name, match, mask) \ - insn_bits_t name##_match = (match), name##_mask = (mask); + insn_bits_t name##_match = (match), name##_mask = (mask); \ + bool name##_supported = true; + #include "encoding.h" #undef DECLARE_INSN + #define DECLARE_OVERLAP_INSN(name, ext) { name##_supported = isa->extension_enabled(ext); } + #include "overlap_list.h" + #undef DECLARE_OVERLAP_INSN + #define DEFINE_INSN(name) \ - extern reg_t rv32i_##name(processor_t*, insn_t, reg_t); \ - extern reg_t rv64i_##name(processor_t*, insn_t, reg_t); \ - extern reg_t rv32e_##name(processor_t*, insn_t, reg_t); \ - extern reg_t rv64e_##name(processor_t*, insn_t, reg_t); \ - register_insn((insn_desc_t){ \ - name##_match, \ - name##_mask, \ - rv32i_##name, \ - rv64i_##name, \ - rv32e_##name, \ - rv64e_##name}); + extern reg_t fast_rv32i_##name(processor_t*, insn_t, reg_t); \ + extern reg_t fast_rv64i_##name(processor_t*, insn_t, reg_t); \ + extern reg_t fast_rv32e_##name(processor_t*, insn_t, reg_t); \ + extern reg_t fast_rv64e_##name(processor_t*, insn_t, reg_t); \ + extern reg_t logged_rv32i_##name(processor_t*, insn_t, reg_t); \ + extern reg_t logged_rv64i_##name(processor_t*, insn_t, reg_t); \ + extern reg_t logged_rv32e_##name(processor_t*, insn_t, reg_t); \ + extern reg_t logged_rv64e_##name(processor_t*, insn_t, reg_t); \ + if (name##_supported) { \ + register_insn((insn_desc_t) { \ + name##_match, \ + name##_mask, \ + fast_rv32i_##name, \ + fast_rv64i_##name, \ + fast_rv32e_##name, \ + fast_rv64e_##name, \ + logged_rv32i_##name, \ + logged_rv64i_##name, \ + logged_rv32e_##name, \ + logged_rv64e_##name}); \ + } #include "insn_list.h" #undef DEFINE_INSN @@ -1166,22 +1135,26 @@ bool processor_t::store(reg_t addr, size_t len, const uint8_t* bytes) return false; } -void processor_t::trigger_updated() +void processor_t::trigger_updated(const std::vector &triggers) { mmu->flush_tlb(); mmu->check_triggers_fetch = false; mmu->check_triggers_load = false; mmu->check_triggers_store = false; + check_triggers_icount = false; - for (unsigned i = 0; i < state.num_triggers; i++) { - if (state.mcontrol[i].execute) { + for (auto trigger : triggers) { + if (trigger->get_execute()) { mmu->check_triggers_fetch = true; } - if (state.mcontrol[i].load) { + if (trigger->get_load()) { mmu->check_triggers_load = true; } - if (state.mcontrol[i].store) { + if (trigger->get_store()) { mmu->check_triggers_store = true; } + if (trigger->icount_check_needed()) { + check_triggers_icount = true; + } } } diff --git a/vendor/riscv/riscv-isa-sim/riscv/processor.h b/vendor/riscv/riscv-isa-sim/riscv/processor.h index 35f8afc4c..8117568c6 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/processor.h +++ b/vendor/riscv/riscv-isa-sim/riscv/processor.h @@ -3,7 +3,6 @@ #define _RISCV_PROCESSOR_H #include "decode.h" -#include "config.h" #include "trap.h" #include "abstract_device.h" #include @@ -14,6 +13,12 @@ #include "debug_rom_defines.h" #include "entropy_source.h" #include "csrs.h" +#include "isa_parser.h" +#include "triggers.h" +#include "../fesvr/memif.h" +#include "vector_unit.h" + +#define N_HPMCOUNTERS 29 class processor_t; class mmu_t; @@ -29,22 +34,34 @@ struct insn_desc_t { insn_bits_t match; insn_bits_t mask; - insn_func_t rv32i; - insn_func_t rv64i; - insn_func_t rv32e; - insn_func_t rv64e; + insn_func_t fast_rv32i; + insn_func_t fast_rv64i; + insn_func_t fast_rv32e; + insn_func_t fast_rv64e; + insn_func_t logged_rv32i; + insn_func_t logged_rv64i; + insn_func_t logged_rv32e; + insn_func_t logged_rv64e; - insn_func_t func(int xlen, bool rve) + insn_func_t func(int xlen, bool rve, bool logged) { - if (rve) - return xlen == 64 ? rv64e : rv32e; + if (logged) + if (rve) + return xlen == 64 ? logged_rv64e : logged_rv32e; + else + return xlen == 64 ? logged_rv64i : logged_rv32i; else - return xlen == 64 ? rv64i : rv32i; + if (rve) + return xlen == 64 ? fast_rv64e : fast_rv32e; + else + return xlen == 64 ? fast_rv64i : fast_rv32i; } static insn_desc_t illegal() { - return {0, 0, &illegal_instruction, &illegal_instruction, &illegal_instruction, &illegal_instruction}; + return {0, 0, + &illegal_instruction, &illegal_instruction, &illegal_instruction, &illegal_instruction, + &illegal_instruction, &illegal_instruction, &illegal_instruction, &illegal_instruction}; } }; @@ -54,114 +71,11 @@ typedef std::unordered_map commit_log_reg_t; // addr, value, size typedef std::vector> commit_log_mem_t; -typedef enum -{ - ACTION_DEBUG_EXCEPTION = MCONTROL_ACTION_DEBUG_EXCEPTION, - ACTION_DEBUG_MODE = MCONTROL_ACTION_DEBUG_MODE, - ACTION_TRACE_START = MCONTROL_ACTION_TRACE_START, - ACTION_TRACE_STOP = MCONTROL_ACTION_TRACE_STOP, - ACTION_TRACE_EMIT = MCONTROL_ACTION_TRACE_EMIT -} mcontrol_action_t; - -typedef enum -{ - MATCH_EQUAL = MCONTROL_MATCH_EQUAL, - MATCH_NAPOT = MCONTROL_MATCH_NAPOT, - MATCH_GE = MCONTROL_MATCH_GE, - MATCH_LT = MCONTROL_MATCH_LT, - MATCH_MASK_LOW = MCONTROL_MATCH_MASK_LOW, - MATCH_MASK_HIGH = MCONTROL_MATCH_MASK_HIGH -} mcontrol_match_t; - -typedef struct -{ - uint8_t type; - bool dmode; - uint8_t maskmax; - bool select; - bool timing; - mcontrol_action_t action; - bool chain; - mcontrol_match_t match; - bool m; - bool h; - bool s; - bool u; - bool execute; - bool store; - bool load; -} mcontrol_t; - -enum VRM{ - RNU = 0, - RNE, - RDN, - ROD, - INVALID_RM -}; - -template -struct type_usew_t; - -template<> -struct type_usew_t<8> -{ - using type=uint8_t; -}; - -template<> -struct type_usew_t<16> -{ - using type=uint16_t; -}; - -template<> -struct type_usew_t<32> -{ - using type=uint32_t; -}; - -template<> -struct type_usew_t<64> -{ - using type=uint64_t; -}; - -template -struct type_sew_t; - -template<> -struct type_sew_t<8> -{ - using type=int8_t; -}; - -template<> -struct type_sew_t<16> -{ - using type=int16_t; -}; - -template<> -struct type_sew_t<32> -{ - using type=int32_t; -}; - -template<> -struct type_sew_t<64> -{ - using type=int64_t; -}; - - // architectural state of a RISC-V hart struct state_t { void reset(processor_t* const proc, reg_t max_isa); - static const int num_triggers = 4; - reg_t pc; regfile_t XPR; regfile_t FPR; @@ -172,16 +86,21 @@ struct state_t bool v; misa_csr_t_p misa; mstatus_csr_t_p mstatus; + csr_t_p mstatush; csr_t_p mepc; csr_t_p mtval; csr_t_p mtvec; csr_t_p mcause; - minstret_csr_t_p minstret; + wide_counter_csr_t_p minstret; + wide_counter_csr_t_p mcycle; mie_csr_t_p mie; mip_csr_t_p mip; csr_t_p medeleg; csr_t_p mideleg; csr_t_p mcounteren; + csr_t_p mevent[N_HPMCOUNTERS]; + csr_t_p mnstatus; + csr_t_p mnepc; csr_t_p scounteren; csr_t_p sepc; csr_t_p stval; @@ -209,15 +128,37 @@ struct state_t csr_t_p dpc; dcsr_csr_t_p dcsr; csr_t_p tselect; - mcontrol_t mcontrol[num_triggers]; - tdata2_csr_t_p tdata2; + csr_t_p tdata2; + csr_t_p scontext; + csr_t_p mcontext; + + csr_t_p jvt; + bool debug_mode; - static const int max_pmp = 16; + mseccfg_csr_t_p mseccfg; + + static const int max_pmp = 64; pmpaddr_csr_t_p pmpaddr[max_pmp]; - csr_t_p fflags; - csr_t_p frm; + float_csr_t_p fflags; + float_csr_t_p frm; + + csr_t_p menvcfg; + csr_t_p senvcfg; + csr_t_p henvcfg; + + csr_t_p mstateen[4]; + csr_t_p sstateen[4]; + csr_t_p hstateen[4]; + + csr_t_p htimedelta; + time_counter_csr_t_p time; + csr_t_p time_proxy; + + csr_t_p stimecmp; + csr_t_p vstimecmp; + bool serialized; // whether timer CSRs are in a well-defined state // When true, execute a single instruction and then enter debug mode. This @@ -228,99 +169,46 @@ struct state_t STEP_STEPPED } single_step; -#ifdef RISCV_ENABLE_COMMITLOG commit_log_reg_t log_reg_write; commit_log_mem_t log_mem_read; commit_log_mem_t log_mem_write; reg_t last_inst_priv; int last_inst_xlen; int last_inst_flen; -#endif }; -typedef enum { - OPERATION_EXECUTE, - OPERATION_STORE, - OPERATION_LOAD, -} trigger_operation_t; - -typedef enum { - // 65('A') ~ 90('Z') is reserved for standard isa in misa - EXT_ZFH, - EXT_ZFHMIN, - EXT_ZBA, - EXT_ZBB, - EXT_ZBC, - EXT_ZBS, - EXT_ZBKB, - EXT_ZBKC, - EXT_ZBKX, - EXT_ZKND, - EXT_ZKNE, - EXT_ZKNH, - EXT_ZKSED, - EXT_ZKSH, - EXT_ZKR, - EXT_ZMMUL, - EXT_ZBPBO, - EXT_ZPN, - EXT_ZPSFOPERAND, - EXT_SVNAPOT, - EXT_SVPBMT, - EXT_SVINVAL, - EXT_XBITMANIP, -} isa_extension_t; - -typedef enum { - IMPL_MMU_SV32, - IMPL_MMU_SV39, - IMPL_MMU_SV48, - IMPL_MMU_SBARE, - IMPL_MMU, -} impl_extension_t; - -// Count number of contiguous 1 bits starting from the LSB. -static int cto(reg_t val) -{ - int res = 0; - while ((val & 1) == 1) - val >>= 1, res++; - return res; -} - // this class represents one processor in a RISC-V machine. class processor_t : public abstract_device_t { public: - processor_t(const char* isa, const char* priv, const char* varch, + processor_t(const isa_parser_t *isa, const cfg_t* cfg, simif_t* sim, uint32_t id, bool halt_on_reset, FILE *log_file, std::ostream& sout_); // because of command line option --log and -s we need both ~processor_t(); + const isa_parser_t &get_isa() { return *isa; } + const cfg_t &get_cfg() { return *cfg; } + void set_debug(bool value); void set_histogram(bool value); -#ifdef RISCV_ENABLE_COMMITLOG void enable_log_commits(); bool get_log_commits_enabled() const { return log_commits_enabled; } -#endif void reset(); void step(size_t n); // run for n cycles - void set_csr(int which, reg_t val); + void put_csr(int which, reg_t val); uint32_t get_id() const { return id; } reg_t get_csr(int which, insn_t insn, bool write, bool peek = 0); reg_t get_csr(int which) { return get_csr(which, insn_t(0), false, true); } mmu_t* get_mmu() { return mmu; } state_t* get_state() { return &state; } - unsigned get_xlen() { return xlen; } - unsigned get_const_xlen() { + unsigned get_xlen() const { return xlen; } + unsigned get_const_xlen() const { // Any code that assumes a const xlen should use this method to // document that assumption. If Spike ever changes to allow // variable xlen, this method should be removed. return xlen; } - unsigned get_max_xlen() { return max_xlen; } - std::string get_isa_string() { return isa_string; } - unsigned get_flen() { + unsigned get_flen() const { return extension_enabled('Q') ? 128 : extension_enabled('D') ? 64 : extension_enabled('F') ? 32 : 0; @@ -331,26 +219,41 @@ public: return !custom_extensions.empty(); } bool extension_enabled(unsigned char ext) const { + return extension_enabled(isa_extension_t(ext)); + } + bool extension_enabled(isa_extension_t ext) const { if (ext >= 'A' && ext <= 'Z') return state.misa->extension_enabled(ext); else - return extension_table[ext]; + return extension_enable_table[ext]; } // Is this extension enabled? and abort if this extension can // possibly be disabled dynamically. Useful for documenting // assumptions about writable misa bits. bool extension_enabled_const(unsigned char ext) const { - if (ext >= 'A' && ext <= 'Z') + return extension_enabled_const(isa_extension_t(ext)); + } + bool extension_enabled_const(isa_extension_t ext) const { + if (ext >= 'A' && ext <= 'Z') { return state.misa->extension_enabled_const(ext); - else - return extension_table[ext]; // assume this can't change + } else { + assert(!extension_dynamic[ext]); + extension_assumed_const[ext] = true; + return extension_enabled(ext); + } + } + void set_extension_enable(unsigned char ext, bool enable) { + assert(!extension_assumed_const[ext]); + extension_dynamic[ext] = true; + extension_enable_table[ext] = enable && isa->extension_enabled(ext); } void set_impl(uint8_t impl, bool val) { impl_table[impl] = val; } bool supports_impl(uint8_t impl) const { return impl_table[impl]; } reg_t pc_alignment_mask() { - return ~(reg_t)(extension_enabled('C') ? 0 : 2); + const int ialign = extension_enabled(EXT_ZCA) ? 16 : 32; + return ~(reg_t)(ialign == 16 ? 0 : 2); } void check_pc_alignment(reg_t pc) { if (unlikely(pc & ~pc_alignment_mask())) @@ -359,6 +262,7 @@ public: reg_t legalize_privilege(reg_t); void set_privilege(reg_t); void set_virt(bool); + const char* get_privilege_string(); void update_histogram(reg_t pc); const disassembler_t* get_disassembler() { return disassembler; } @@ -382,88 +286,7 @@ public: HR_GROUP /* Halt requested due to halt group. */ } halt_request; - // Return the index of a trigger that matched, or -1. - inline int trigger_match(trigger_operation_t operation, reg_t address, reg_t data) - { - if (state.debug_mode) - return -1; - - bool chain_ok = true; - - for (unsigned int i = 0; i < state.num_triggers; i++) { - if (!chain_ok) { - chain_ok |= !state.mcontrol[i].chain; - continue; - } - - if ((operation == OPERATION_EXECUTE && !state.mcontrol[i].execute) || - (operation == OPERATION_STORE && !state.mcontrol[i].store) || - (operation == OPERATION_LOAD && !state.mcontrol[i].load) || - (state.prv == PRV_M && !state.mcontrol[i].m) || - (state.prv == PRV_S && !state.mcontrol[i].s) || - (state.prv == PRV_U && !state.mcontrol[i].u)) { - continue; - } - - reg_t value; - if (state.mcontrol[i].select) { - value = data; - } else { - value = address; - } - - // We need this because in 32-bit mode sometimes the PC bits get sign - // extended. - if (xlen == 32) { - value &= 0xffffffff; - } - - auto tdata2 = state.tdata2->read(i); - switch (state.mcontrol[i].match) { - case MATCH_EQUAL: - if (value != tdata2) - continue; - break; - case MATCH_NAPOT: - { - reg_t mask = ~((1 << (cto(tdata2)+1)) - 1); - if ((value & mask) != (tdata2 & mask)) - continue; - } - break; - case MATCH_GE: - if (value < tdata2) - continue; - break; - case MATCH_LT: - if (value >= tdata2) - continue; - break; - case MATCH_MASK_LOW: - { - reg_t mask = tdata2 >> (xlen/2); - if ((value & mask) != (tdata2 & mask)) - continue; - } - break; - case MATCH_MASK_HIGH: - { - reg_t mask = tdata2 >> (xlen/2); - if (((value >> (xlen/2)) & mask) != (tdata2 & mask)) - continue; - } - break; - } - - if (!state.mcontrol[i].chain) { - return i; - } - chain_ok = true; - } - return -1; - } - - void trigger_updated(); + void trigger_updated(const std::vector &triggers); void set_pmp_num(reg_t pmp_num); void set_pmp_granularity(reg_t pmp_granularity); @@ -471,27 +294,36 @@ public: const char* get_symbol(uint64_t addr); + void clear_waiting_for_interrupt() { in_wfi = false; }; + bool is_waiting_for_interrupt() { return in_wfi; }; + private: + const isa_parser_t * const isa; + const cfg_t * const cfg; + simif_t* sim; mmu_t* mmu; // main memory is always accessed via the mmu std::unordered_map custom_extensions; disassembler_t* disassembler; state_t state; uint32_t id; - unsigned max_xlen; unsigned xlen; - reg_t max_isa; - std::string isa_string; bool histogram_enabled; bool log_commits_enabled; FILE *log_file; std::ostream sout_; // needed for socket command interface -s, also used for -d and -l, but not for --log bool halt_on_reset; - std::vector extension_table; + bool in_wfi; + bool check_triggers_icount; std::vector impl_table; + // Note: does not include single-letter extensions in misa + std::bitset extension_enable_table; + std::bitset extension_dynamic; + mutable std::bitset extension_assumed_const; + std::vector instructions; - std::map pc_histogram; + std::unordered_map pc_histogram; static const size_t OPCODE_CACHE_SIZE = 8191; insn_desc_t opcode_cache[OPCODE_CACHE_SIZE]; @@ -499,6 +331,7 @@ private: void take_pending_interrupt() { take_interrupt(state.mip->read() & state.mie->read()); } void take_interrupt(reg_t mask); // take first enabled interrupt in mask void take_trap(trap_t& t, reg_t epc); // take an exception + void take_trigger_action(triggers::action_t action, reg_t breakpoint_tval, reg_t epc); void disasm(insn_t insn); // disassemble and print an instruction int paddr_bits(); @@ -508,11 +341,11 @@ private: friend class mmu_t; friend class clint_t; + friend class plic_t; friend class extension_t; void parse_varch_string(const char*); void parse_priv_string(const char*); - void parse_isa_string(const char*); void build_opcode_map(); void register_base_instructions(); insn_func_t decode_insn(insn_t insn); @@ -526,89 +359,8 @@ public: reg_t lg_pmp_granularity; reg_t pmp_tor_mask() { return -(reg_t(1) << (lg_pmp_granularity - PMP_SHIFT)); } - class vectorUnit_t { - public: - processor_t* p; - void *reg_file; - char reg_referenced[NVPR]; - int setvl_count; - reg_t vlmax; - reg_t vlenb; - csr_t_p vxsat; - vector_csr_t_p vxrm, vstart, vl, vtype; - reg_t vma, vta; - reg_t vsew; - float vflmul; - reg_t ELEN, VLEN; - bool vill; - bool vstart_alu; - - // vector element for varies SEW - template - T& elt(reg_t vReg, reg_t n, bool is_write = false){ - assert(vsew != 0); - assert((VLEN >> 3)/sizeof(T) > 0); - reg_t elts_per_reg = (VLEN >> 3) / (sizeof(T)); - vReg += n / elts_per_reg; - n = n % elts_per_reg; -#ifdef WORDS_BIGENDIAN - // "V" spec 0.7.1 requires lower indices to map to lower significant - // bits when changing SEW, thus we need to index from the end on BE. - n ^= elts_per_reg - 1; -#endif - reg_referenced[vReg] = 1; - -#ifdef RISCV_ENABLE_COMMITLOG - if (is_write) - p->get_state()->log_reg_write[((vReg) << 4) | 2] = {0, 0}; -#endif - - T *regStart = (T*)((char*)reg_file + vReg * (VLEN >> 3)); - return regStart[n]; - } - public: - - void reset(); - - vectorUnit_t(): - p(0), - reg_file(0), - reg_referenced{0}, - setvl_count(0), - vlmax(0), - vlenb(0), - vxsat(0), - vxrm(0), - vstart(0), - vl(0), - vtype(0), - vma(0), - vta(0), - vsew(0), - vflmul(0), - ELEN(0), - VLEN(0), - vill(false), - vstart_alu(false) { - } - - ~vectorUnit_t(){ - free(reg_file); - reg_file = 0; - } - - reg_t set_vl(int rd, int rs1, reg_t reqVL, reg_t newType); - - reg_t get_vlen() { return VLEN; } - reg_t get_elen() { return ELEN; } - reg_t get_slen() { return VLEN; } - - VRM get_vround_mode() { - return (VRM)(vxrm->read()); - } - }; - vectorUnit_t VU; + triggers::module_t TM; }; #endif diff --git a/vendor/riscv/riscv-isa-sim/riscv/riscv.ac b/vendor/riscv/riscv-isa-sim/riscv/riscv.ac index 9d14335d5..e52c57016 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/riscv.ac +++ b/vendor/riscv/riscv-isa-sim/riscv/riscv.ac @@ -9,10 +9,10 @@ AC_CHECK_LIB([boost_system], [main], [], []) AC_CHECK_LIB([boost_regex], [main], [], []) AC_ARG_WITH(isa, - [AS_HELP_STRING([--with-isa=RV64IMAFDC], + [AS_HELP_STRING([--with-isa=RV64IMAFDC_zicntr_zihpm], [Sets the default RISC-V ISA])], AC_DEFINE_UNQUOTED([DEFAULT_ISA], "$withval", [Default value for --isa switch]), - AC_DEFINE_UNQUOTED([DEFAULT_ISA], "RV64IMAFDC", [Default value for --isa switch])) + AC_DEFINE_UNQUOTED([DEFAULT_ISA], "RV64IMAFDC_zicntr_zihpm", [Default value for --isa switch])) AC_ARG_WITH(priv, [AS_HELP_STRING([--with-priv=MSU], @@ -39,26 +39,6 @@ AC_SEARCH_LIBS([dlopen], [dl dld], [ AC_CHECK_LIB(pthread, pthread_create, [], [AC_MSG_ERROR([libpthread is required])]) -AC_ARG_ENABLE([commitlog], AS_HELP_STRING([--enable-commitlog], [Enable commit log generation])) -AS_IF([test "x$enable_commitlog" = "xyes"], [ - AC_DEFINE([RISCV_ENABLE_COMMITLOG],,[Enable commit log generation]) -]) - -AC_ARG_ENABLE([histogram], AS_HELP_STRING([--enable-histogram], [Enable PC histogram generation])) -AS_IF([test "x$enable_histogram" = "xyes"], [ - AC_DEFINE([RISCV_ENABLE_HISTOGRAM],,[Enable PC histogram generation]) -]) - -AC_ARG_ENABLE([dirty], AS_HELP_STRING([--enable-dirty], [Enable hardware management of PTE accessed and dirty bits])) -AS_IF([test "x$enable_dirty" = "xyes"], [ - AC_DEFINE([RISCV_ENABLE_DIRTY],,[Enable hardware management of PTE accessed and dirty bits]) -]) - -AC_ARG_ENABLE([misaligned], AS_HELP_STRING([--enable-misaligned], [Enable hardware support for misaligned loads and stores])) -AS_IF([test "x$enable_misaligned" = "xyes"], [ - AC_DEFINE([RISCV_ENABLE_MISALIGNED],,[Enable hardware support for misaligned loads and stores]) -]) - AC_ARG_ENABLE([dual-endian], AS_HELP_STRING([--enable-dual-endian], [Enable support for running target in either endianness])) AS_IF([test "x$enable_dual_endian" = "xyes"], [ AC_DEFINE([RISCV_ENABLE_DUAL_ENDIAN],,[Enable support for running target in either endianness]) diff --git a/vendor/riscv/riscv-isa-sim/riscv/riscv.mk.in b/vendor/riscv/riscv-isa-sim/riscv/riscv.mk.in index 3da5f6d8b..5765a91ff 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/riscv.mk.in +++ b/vendor/riscv/riscv-isa-sim/riscv/riscv.mk.in @@ -3,52 +3,59 @@ get_opcode = $(shell grep ^DECLARE_INSN.*\\\<$(2)\\\> $(1) | sed 's/DECLARE_INSN riscv_subproject_deps = \ fdt \ + disasm \ + fesvr \ softfloat \ +riscv_CFLAGS = -fPIC + +riscv_install_shared_lib = yes + riscv_install_prog_srcs = \ -riscv_hdrs = \ +riscv_install_hdrs = \ abstract_device.h \ + abstract_interrupt_controller.h \ + cachesim.h \ + cfg.h \ common.h \ + csrs.h \ + cvxif.h \ + debug_defines.h \ + debug_module.h \ + debug_rom_defines.h \ decode.h \ devices.h \ disasm.h \ - dts.h \ + encoding.h \ + entropy_source.h \ + extension.h \ + isa_parser.h \ + log_file.h \ + memtracer.h \ + mmio_plugin.h \ mmu.h \ + platform.h \ processor.h \ + rocc.h \ sim.h \ simif.h \ trap.h \ - encoding.h \ - cachesim.h \ - memtracer.h \ - mmio_plugin.h \ - tracer.h \ - extension.h \ - rocc.h \ - cvxif.h \ - insn_template.h \ - debug_module.h \ - debug_rom_defines.h \ - remote_bitbang.h \ - jtag_dtm.h \ - csrs.h \ - -riscv_install_hdrs = mmio_plugin.h + triggers.h \ + vector_unit.h \ riscv_precompiled_hdrs = \ insn_template.h \ riscv_srcs = \ + isa_parser.cc \ processor.cc \ execute.cc \ dts.cc \ sim.cc \ interactive.cc \ - trap.cc \ cachesim.cc \ mmu.cc \ - disasm.cc \ extension.cc \ extensions.cc \ rocc.cc \ @@ -56,10 +63,16 @@ riscv_srcs = \ devices.cc \ rom.cc \ clint.cc \ + plic.cc \ + ns16550.cc \ debug_module.cc \ remote_bitbang.cc \ jtag_dtm.cc \ csrs.cc \ + triggers.cc \ + vector_unit.cc \ + socketif.cc \ + cfg.cc \ $(riscv_gen_srcs) \ riscv_test_srcs = @@ -229,6 +242,15 @@ riscv_insn_ext_f = \ fsub_s \ fsw \ +riscv_insn_ext_f_zfa= \ + fli_s \ + fmaxm_s \ + fminm_s \ + fround_s \ + froundnx_s \ + fleq_s \ + fltq_s + riscv_insn_ext_d = \ fadd_d \ fclass_d \ @@ -264,6 +286,18 @@ riscv_insn_ext_d = \ fsqrt_d \ fsub_d \ +riscv_insn_ext_d_zfa = \ + fli_d \ + fmaxm_d \ + fminm_d \ + fround_d \ + froundnx_d \ + fmvh_x_d \ + fmvp_d_x \ + fcvtmod_w_d \ + fleq_d \ + fltq_d + riscv_insn_ext_zfh = \ fadd_h \ fclass_h \ @@ -302,6 +336,15 @@ riscv_insn_ext_zfh = \ fsqrt_h \ fsub_h \ +riscv_insn_ext_zfh_zfa = \ + fli_h \ + fmaxm_h \ + fminm_h \ + fround_h \ + froundnx_h \ + fleq_h \ + fltq_h + riscv_insn_ext_q = \ fadd_q \ fclass_q \ @@ -335,6 +378,17 @@ riscv_insn_ext_q = \ fsqrt_q \ fsub_q \ +riscv_insn_ext_q_zfa = \ + fli_q \ + fmaxm_q \ + fminm_q \ + fround_q \ + froundnx_q \ + fmvh_x_q \ + fmvp_q_x \ + fleq_q \ + fltq_q + riscv_insn_ext_b = \ add_uw \ andn \ @@ -1255,6 +1309,9 @@ riscv_insn_priv = \ sret \ wfi \ +riscv_insn_smrnmi = \ + mnret \ + riscv_insn_svinval = \ sfence_w_inval \ sfence_inval_ir \ @@ -1262,25 +1319,72 @@ riscv_insn_svinval = \ hinval_vvma \ hinval_gvma \ +riscv_insn_ext_zcb = \ + c_zext_b \ + c_zext_h \ + c_zext_w \ + c_sext_b \ + c_sext_h \ + c_not \ + c_mul \ + c_lbu \ + c_lhu \ + c_lh \ + c_sb \ + c_sh \ + +riscv_insn_ext_zcmp = \ + cm_push \ + cm_pop \ + cm_popret \ + cm_popretz \ + cm_mva01s \ + cm_mvsa01 \ + +riscv_insn_ext_zcmt = \ + cm_jalt \ + +riscv_insn_ext_zce = \ + $(riscv_insn_ext_zcb) \ + $(riscv_insn_ext_zcmp) \ + $(riscv_insn_ext_zcmt) \ + +riscv_insn_ext_cmo = \ + cbo_clean \ + cbo_flush \ + cbo_inval \ + cbo_zero \ + +riscv_insn_ext_zicond = \ + czero_eqz \ + czero_nez \ + riscv_insn_list = \ $(riscv_insn_ext_a) \ $(riscv_insn_ext_c) \ $(riscv_insn_ext_i) \ $(riscv_insn_ext_m) \ $(riscv_insn_ext_f) \ + $(riscv_insn_ext_f_zfa) \ $(riscv_insn_ext_d) \ + $(riscv_insn_ext_d_zfa) \ $(riscv_insn_ext_zfh) \ + $(riscv_insn_ext_zfh_zfa) \ $(riscv_insn_ext_q) \ + $(riscv_insn_ext_q_zfa) \ $(riscv_insn_ext_b) \ - $(riscv_insn_ext_k) \ + $(riscv_insn_ext_k) \ $(if $(HAVE_INT128),$(riscv_insn_ext_v),) \ + $(riscv_insn_ext_zce) \ $(riscv_insn_ext_h) \ $(riscv_insn_ext_p) \ $(riscv_insn_priv) \ $(riscv_insn_svinval) \ + $(riscv_insn_smrnmi) \ + $(riscv_insn_ext_cmo) \ + $(riscv_insn_ext_zicond) \ -riscv_gen_srcs = \ - $(addsuffix .cc,$(riscv_insn_list)) +riscv_gen_srcs = $(addsuffix .cc,$(riscv_insn_list)) insn_list.h: $(src_dir)/riscv/riscv.mk.in for insn in $(foreach insn,$(riscv_insn_list),$(subst .,_,$(insn))) ; do \ diff --git a/vendor/riscv/riscv-isa-sim/riscv/rocc.cc b/vendor/riscv/riscv-isa-sim/riscv/rocc.cc index db03e37c4..53ee0512b 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/rocc.cc +++ b/vendor/riscv/riscv-isa-sim/riscv/rocc.cc @@ -1,5 +1,7 @@ // See LICENSE for license details. +#define DECODE_MACRO_USAGE_LOGGED 1 +#include "decode_macros.h" #include "rocc.h" #include "trap.h" #include @@ -18,7 +20,7 @@ return pc+4; \ } \ \ - reg_t rocc_t::custom##n(rocc_insn_t insn, reg_t xs1, reg_t xs2) \ + reg_t rocc_t::custom##n(rocc_insn_t UNUSED insn, reg_t UNUSED xs1, reg_t UNUSED xs2) \ { \ illegal_instruction(); \ return 0; \ @@ -32,10 +34,18 @@ customX(3) std::vector rocc_t::get_instructions() { std::vector insns; - insns.push_back((insn_desc_t){0x0b, 0x7f, &::illegal_instruction, c0}); - insns.push_back((insn_desc_t){0x2b, 0x7f, &::illegal_instruction, c1}); - insns.push_back((insn_desc_t){0x5b, 0x7f, &::illegal_instruction, c2}); - insns.push_back((insn_desc_t){0x7b, 0x7f, &::illegal_instruction, c3}); + insns.push_back((insn_desc_t){0x0b, 0x7f, + &::illegal_instruction, c0, &::illegal_instruction, c0, + &::illegal_instruction, c0, &::illegal_instruction, c0}); + insns.push_back((insn_desc_t){0x2b, 0x7f, + &::illegal_instruction, c1, &::illegal_instruction, c1, + &::illegal_instruction, c1, &::illegal_instruction, c1}); + insns.push_back((insn_desc_t){0x5b, 0x7f, + &::illegal_instruction, c2, &::illegal_instruction, c2, + &::illegal_instruction, c2, &::illegal_instruction, c2}); + insns.push_back((insn_desc_t){0x7b, 0x7f, + &::illegal_instruction, c3, &::illegal_instruction, c3, + &::illegal_instruction, c0, &::illegal_instruction, c3}); return insns; } diff --git a/vendor/riscv/riscv-isa-sim/riscv/rocc.h b/vendor/riscv/riscv-isa-sim/riscv/rocc.h index 1a522ab43..d65ec979a 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/rocc.h +++ b/vendor/riscv/riscv-isa-sim/riscv/rocc.h @@ -37,17 +37,25 @@ class rocc_t : public extension_t { \ type_name* rocc = static_cast(p->get_extension(ext_name_str)); \ rocc_insn_union_t u; \ - u.i = insn; \ - reg_t xs1 = u.r.xs1 ? RS1 : -1; \ - reg_t xs2 = u.r.xs2 ? RS2 : -1; \ - reg_t xd = rocc->method_name(u.r, xs1, xs2); \ - if (u.r.xd) \ - WRITE_RD(xd); \ + state_t* state = p->get_state(); \ + u.i = insn; \ + reg_t xs1 = u.r.xs1 ? state->XPR[insn.rs1()] : -1; \ + reg_t xs2 = u.r.xs2 ? state->XPR[insn.rs2()] : -1; \ + reg_t xd = rocc->method_name(u.r, xs1, xs2); \ + if (u.r.xd) { \ + state->log_reg_write[insn.rd() << 4] = {xd, 0}; \ + state->XPR.write(insn.rd(), xd); \ + } \ return pc+4; \ } \ #define push_custom_insn(insn_list, opcode, opcode_mask, func_name_32, func_name_64) \ - insn_list.push_back((insn_desc_t){opcode, opcode_mask, func_name_32, func_name_64}) + insn_list.push_back((insn_desc_t){opcode, opcode_mask, \ + func_name_32, func_name_64, \ + func_name_32, func_name_64, \ + func_name_32, func_name_64, \ + func_name_32, func_name_64, \ + }) \ #define ILLEGAL_INSN_FUNC &::illegal_instruction diff --git a/vendor/riscv/riscv-isa-sim/riscv/rom.cc b/vendor/riscv/riscv-isa-sim/riscv/rom.cc index b8528621a..6f25652ae 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/rom.cc +++ b/vendor/riscv/riscv-isa-sim/riscv/rom.cc @@ -1,3 +1,4 @@ +#include "common.h" #include "devices.h" rom_device_t::rom_device_t(std::vector data) @@ -13,7 +14,7 @@ bool rom_device_t::load(reg_t addr, size_t len, uint8_t* bytes) return true; } -bool rom_device_t::store(reg_t addr, size_t len, const uint8_t* bytes) +bool rom_device_t::store(reg_t UNUSED addr, size_t UNUSED len, const uint8_t UNUSED *bytes) { return false; } diff --git a/vendor/riscv/riscv-isa-sim/riscv/sim.cc b/vendor/riscv/riscv-isa-sim/riscv/sim.cc index 1ec6a9f7a..dcbd469d3 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/sim.cc +++ b/vendor/riscv/riscv-isa-sim/riscv/sim.cc @@ -1,11 +1,14 @@ // See LICENSE for license details. +#include "config.h" #include "sim.h" #include "mmu.h" #include "dts.h" #include "remote_bitbang.h" #include "byteorder.h" #include "platform.h" +#include "libfdt.h" +#include "socketif.h" #include #include #include @@ -27,36 +30,26 @@ static void handle_signal(int sig) signal(sig, &handle_signal); } -sim_t::sim_t(const char* isa, const char* priv, const char* varch, - size_t nprocs, bool halted, bool real_time_clint, - reg_t initrd_start, reg_t initrd_end, const char* bootargs, - reg_t start_pc, std::vector> mems, +const size_t sim_t::INTERLEAVE; + +sim_t::sim_t(const cfg_t *cfg, bool halted, + std::vector> mems, std::vector> plugin_devices, const std::vector& args, - std::vector const hartids, const debug_module_config_t &dm_config, const char *log_path, bool dtb_enabled, const char *dtb_file, -#ifdef HAVE_BOOST_ASIO - boost::asio::io_service *io_service_ptr, boost::asio::ip::tcp::acceptor *acceptor_ptr, // option -s -#endif + bool socket_enabled, FILE *cmd_file) // needed for command line option --cmd : htif_t(args), + isa(cfg->isa(), cfg->priv()), + cfg(cfg), mems(mems), plugin_devices(plugin_devices), - procs(std::max(nprocs, size_t(1))), - initrd_start(initrd_start), - initrd_end(initrd_end), - bootargs(bootargs), - start_pc(start_pc), - dtb_file(dtb_file ? dtb_file : ""), + procs(std::max(cfg->nprocs(), size_t(1))), dtb_enabled(dtb_enabled), log_file(log_path), cmd_file(cmd_file), -#ifdef HAVE_BOOST_ASIO - io_service_ptr(io_service_ptr), // socket interface - acceptor_ptr(acceptor_ptr), -#endif sout_(nullptr), current_step(0), current_proc(0), @@ -78,34 +71,83 @@ sim_t::sim_t(const char* isa, const char* priv, const char* varch, debug_module.add_device(&bus); - debug_mmu = new mmu_t(this, NULL); - - if (! (hartids.empty() || hartids.size() == nprocs)) { - std::cerr << "Number of specified hartids (" - << hartids.size() - << ") doesn't match number of processors (" - << nprocs << ").\n"; - exit(1); + socketif = NULL; +#ifdef HAVE_BOOST_ASIO + if (socket_enabled) { + socketif = new socketif_t(); } +#else + if (socket_enabled) { + fputs("Socket support requires compilation with boost asio; " + "please rebuild the riscv-isa-sim project using " + "\"configure --with-boost-asio\".\n", + stderr); + abort(); + } +#endif - for (size_t i = 0; i < nprocs; i++) { - int hart_id = hartids.empty() ? i : hartids[i]; - procs[i] = new processor_t(isa, priv, varch, this, hart_id, halted, +#ifndef RISCV_ENABLE_DUAL_ENDIAN + if (cfg->endianness != endianness_little) { + fputs("Big-endian support has not been prroperly enabled; " + "please rebuild the riscv-isa-sim project using " + "\"configure --enable-dual-endian\".\n", + stderr); + abort(); + } +#endif + + debug_mmu = new mmu_t(this, cfg->endianness, NULL); + + for (size_t i = 0; i < cfg->nprocs(); i++) { + procs[i] = new processor_t(&isa, cfg, this, cfg->hartids()[i], halted, log_file.get(), sout_); + harts[cfg->hartids()[i]] = procs[i]; } - make_dtb(); + // When running without using a dtb, skip the fdt-based configuration steps + if (!dtb_enabled) return; + + // Load dtb_file if provided, otherwise self-generate a dts/dtb + make_dtb(dtb_file); void *fdt = (void *)dtb.c_str(); - //handle clic - clint.reset(new clint_t(procs, CPU_HZ / INSNS_PER_RTC_TICK, real_time_clint)); + + // Only make a CLINT (Core-Local INTerrupt controller) if one is specified in + // the device tree configuration. + // + // This isn't *quite* as general as we could get (because you might have one + // that's not bus-accessible), but it should handle the normal use cases. In + // particular, the default device tree configuration that you get without + // setting the dtb_file argument has one. reg_t clint_base; - if (fdt_parse_clint(fdt, &clint_base, "riscv,clint0")) { - bus.add_device(CLINT_BASE, clint.get()); - } else { + if (fdt_parse_clint(fdt, &clint_base, "riscv,clint0") == 0) { + clint.reset(new clint_t(this, CPU_HZ / INSNS_PER_RTC_TICK, cfg->real_time_clint())); bus.add_device(clint_base, clint.get()); } + // pointer to wired interrupt controller + abstract_interrupt_controller_t *intctrl = NULL; + + // create plic + reg_t plic_base; + uint32_t plic_ndev; + if (fdt_parse_plic(fdt, &plic_base, &plic_ndev, "riscv,plic0") == 0) { + plic.reset(new plic_t(this, plic_ndev)); + bus.add_device(plic_base, plic.get()); + intctrl = plic.get(); + } + + // create ns16550 + reg_t ns16550_base; + uint32_t ns16550_shift, ns16550_io_width; + if (fdt_parse_ns16550(fdt, &ns16550_base, + &ns16550_shift, &ns16550_io_width, "ns16550a") == 0) { + assert(intctrl); + ns16550.reset(new ns16550_t(&bus, intctrl, NS16550_INTERRUPT_ID, + ns16550_shift, ns16550_io_width)); + bus.add_device(ns16550_base, ns16550.get()); + } + //per core attribute int cpu_offset = 0, rc; size_t cpu_idx = 0; @@ -116,22 +158,22 @@ sim_t::sim_t(const char* isa, const char* priv, const char* varch, for (cpu_offset = fdt_get_first_subnode(fdt, cpu_offset); cpu_offset >= 0; cpu_offset = fdt_get_next_subnode(fdt, cpu_offset)) { - if (cpu_idx >= nprocs) + if (cpu_idx >= nprocs()) break; //handle pmp - reg_t pmp_num = 0, pmp_granularity = 0; - if (fdt_parse_pmp_num(fdt, cpu_offset, &pmp_num) == 0) { - procs[cpu_idx]->set_pmp_num(pmp_num); - } + reg_t pmp_num, pmp_granularity; + if (fdt_parse_pmp_num(fdt, cpu_offset, &pmp_num) != 0) + pmp_num = 0; + procs[cpu_idx]->set_pmp_num(pmp_num); if (fdt_parse_pmp_alignment(fdt, cpu_offset, &pmp_granularity) == 0) { procs[cpu_idx]->set_pmp_granularity(pmp_granularity); } //handle mmu-type - char mmu_type[256] = ""; - rc = fdt_parse_mmu_type(fdt, cpu_offset, mmu_type); + const char *mmu_type; + rc = fdt_parse_mmu_type(fdt, cpu_offset, &mmu_type); if (rc == 0) { procs[cpu_idx]->set_mmu_capability(IMPL_MMU_SBARE); if (strncmp(mmu_type, "riscv,sv32", strlen("riscv,sv32")) == 0) { @@ -140,25 +182,29 @@ sim_t::sim_t(const char* isa, const char* priv, const char* varch, procs[cpu_idx]->set_mmu_capability(IMPL_MMU_SV39); } else if (strncmp(mmu_type, "riscv,sv48", strlen("riscv,sv48")) == 0) { procs[cpu_idx]->set_mmu_capability(IMPL_MMU_SV48); + } else if (strncmp(mmu_type, "riscv,sv57", strlen("riscv,sv57")) == 0) { + procs[cpu_idx]->set_mmu_capability(IMPL_MMU_SV57); } else if (strncmp(mmu_type, "riscv,sbare", strlen("riscv,sbare")) == 0) { //has been set in the beginning } else { std::cerr << "core (" - << hartids.size() - << ") doesn't have valid 'mmu-type'" + << cpu_idx + << ") has an invalid 'mmu-type': " << mmu_type << ").\n"; exit(1); } + } else { + procs[cpu_idx]->set_mmu_capability(IMPL_MMU_SBARE); } cpu_idx++; } - if (cpu_idx != nprocs) { + if (cpu_idx != nprocs()) { std::cerr << "core number in dts (" << cpu_idx << ") doesn't match it in command line (" - << nprocs << ").\n"; + << nprocs() << ").\n"; exit(1); } } @@ -170,32 +216,15 @@ sim_t::~sim_t() delete debug_mmu; } -void sim_thread_main(void* arg) -{ - ((sim_t*)arg)->main(); -} - -void sim_t::main() +int sim_t::run() { if (!debug && log) set_procs_debug(true); - while (!done()) - { - if (debug || ctrlc_pressed) - interactive(); - else - step(INTERLEAVE); - if (remote_bitbang) { - remote_bitbang->tick(); - } - } -} + htif_t::set_expected_xlen(isa.get_max_xlen()); -int sim_t::run() -{ - host = context_t::current(); - target.init(sim_thread_main, this); + // htif_t::run() will repeatedly call back into sim_t::idle(), each + // invocation of which will advance target time return htif_t::run(); } @@ -213,10 +242,9 @@ void sim_t::step(size_t n) procs[current_proc]->get_mmu()->yield_load_reservation(); if (++current_proc == procs.size()) { current_proc = 0; - clint->increment(INTERLEAVE / INSNS_PER_RTC_TICK); + if (clint) clint->increment(INTERLEAVE / INSNS_PER_RTC_TICK); + if (ns16550) ns16550->tick(); } - - host->switch_to(); } } } @@ -241,17 +269,9 @@ void sim_t::configure_log(bool enable_log, bool enable_commitlog) if (!enable_commitlog) return; -#ifndef RISCV_ENABLE_COMMITLOG - fputs("Commit logging support has not been properly enabled; " - "please re-build the riscv-isa-sim project using " - "\"configure --enable-commitlog\".\n", - stderr); - abort(); -#else for (processor_t *proc : procs) { proc->enable_log_commits(); } -#endif } void sim_t::set_procs_debug(bool value) @@ -265,24 +285,24 @@ static bool paddr_ok(reg_t addr) return (addr >> MAX_PADDR_BITS) == 0; } -bool sim_t::mmio_load(reg_t addr, size_t len, uint8_t* bytes) +bool sim_t::mmio_load(reg_t paddr, size_t len, uint8_t* bytes) { - if (addr + len < addr || !paddr_ok(addr + len - 1)) + if (paddr + len < paddr || !paddr_ok(paddr + len - 1)) return false; - return bus.load(addr, len, bytes); + return bus.load(paddr, len, bytes); } -bool sim_t::mmio_store(reg_t addr, size_t len, const uint8_t* bytes) +bool sim_t::mmio_store(reg_t paddr, size_t len, const uint8_t* bytes) { - if (addr + len < addr || !paddr_ok(addr + len - 1)) + if (paddr + len < paddr || !paddr_ok(paddr + len - 1)) return false; - return bus.store(addr, len, bytes); + return bus.store(paddr, len, bytes); } -void sim_t::make_dtb() +void sim_t::make_dtb(const char* dtb_file) { - if (!dtb_file.empty()) { - std::ifstream fin(dtb_file.c_str(), std::ios::binary); + if (dtb_file) { + std::ifstream fin(dtb_file, std::ios::binary); if (!fin.good()) { std::cerr << "can't find dtb file: " << dtb_file << std::endl; exit(-1); @@ -293,16 +313,31 @@ void sim_t::make_dtb() dtb = strstream.str(); } else { - dts = make_dts(INSNS_PER_RTC_TICK, CPU_HZ, initrd_start, initrd_end, bootargs, procs, mems); + std::pair initrd_bounds = cfg->initrd_bounds(); + dts = make_dts(INSNS_PER_RTC_TICK, CPU_HZ, + initrd_bounds.first, initrd_bounds.second, + cfg->bootargs(), cfg->pmpregions, procs, mems); dtb = dts_compile(dts); } + + int fdt_code = fdt_check_header(dtb.c_str()); + if (fdt_code) { + std::cerr << "Failed to read DTB from "; + if (!dtb_file) { + std::cerr << "auto-generated DTS string"; + } else { + std::cerr << "`" << dtb_file << "'"; + } + std::cerr << ": " << fdt_strerror(fdt_code) << ".\n"; + exit(-1); + } } void sim_t::set_rom() { const int reset_vec_size = 8; - start_pc = start_pc == reg_t(-1) ? get_entry_point() : start_pc; + reg_t start_pc = cfg->start_pc.value_or(get_entry_point()); uint32_t reset_vec[reset_vec_size] = { 0x297, // auipc t0,0x0 @@ -316,7 +351,7 @@ void sim_t::set_rom() (uint32_t) (start_pc & 0xffffffff), (uint32_t) (start_pc >> 32) }; - if (get_target_endianness() == memif_endianness_big) { + if (get_target_endianness() == endianness_big) { int i; // Instuctions are little endian for (i = 0; reset_vec[i] != 0; i++) @@ -335,23 +370,6 @@ void sim_t::set_rom() std::vector rom((char*)reset_vec, (char*)reset_vec + sizeof(reset_vec)); - std::string dtb; - if (!dtb_file.empty()) { - std::ifstream fin(dtb_file.c_str(), std::ios::binary); - if (!fin.good()) { - std::cerr << "can't find dtb file: " << dtb_file << std::endl; - exit(-1); - } - - std::stringstream strstream; - strstream << fin.rdbuf(); - - dtb = strstream.str(); - } else { - dts = make_dts(INSNS_PER_RTC_TICK, CPU_HZ, initrd_start, initrd_end, bootargs, procs, mems); - dtb = dts_compile(dts); - } - rom.insert(rom.end(), dtb.begin(), dtb.end()); const int align = 0x1000; rom.resize((rom.size() + align - 1) / align * align); @@ -360,19 +378,19 @@ void sim_t::set_rom() bus.add_device(DEFAULT_RSTVEC, boot_rom.get()); } -char* sim_t::addr_to_mem(reg_t addr) { - if (!paddr_ok(addr)) +char* sim_t::addr_to_mem(reg_t paddr) { + if (!paddr_ok(paddr)) return NULL; - auto desc = bus.find_device(addr); + auto desc = bus.find_device(paddr); if (auto mem = dynamic_cast(desc.second)) - if (addr - desc.first < mem->size()) - return mem->contents(addr - desc.first); + if (paddr - desc.first < mem->size()) + return mem->contents(paddr - desc.first); return NULL; } -const char* sim_t::get_symbol(uint64_t addr) +const char* sim_t::get_symbol(uint64_t paddr) { - return htif_t::get_symbol(addr); + return htif_t::get_symbol(paddr); } // htif @@ -385,13 +403,22 @@ void sim_t::reset() void sim_t::idle() { - target.switch_to(); + if (done()) + return; + + if (debug || ctrlc_pressed) + interactive(); + else + step(INTERLEAVE); + + if (remote_bitbang) + remote_bitbang->tick(); } void sim_t::read_chunk(addr_t taddr, size_t len, void* dst) { assert(len == 8); - auto data = debug_mmu->to_target(debug_mmu->load_uint64(taddr)); + auto data = debug_mmu->to_target(debug_mmu->load(taddr)); memcpy(dst, &data, sizeof data); } @@ -400,32 +427,12 @@ void sim_t::write_chunk(addr_t taddr, size_t len, const void* src) assert(len == 8); target_endian data; memcpy(&data, src, sizeof data); - debug_mmu->store_uint64(taddr, debug_mmu->from_target(data)); + debug_mmu->store(taddr, debug_mmu->from_target(data)); } -void sim_t::set_target_endianness(memif_endianness_t endianness) +endianness_t sim_t::get_target_endianness() const { -#ifdef RISCV_ENABLE_DUAL_ENDIAN - assert(endianness == memif_endianness_little || endianness == memif_endianness_big); - - bool enable = endianness == memif_endianness_big; - debug_mmu->set_target_big_endian(enable); - for (size_t i = 0; i < procs.size(); i++) { - procs[i]->get_mmu()->set_target_big_endian(enable); - procs[i]->reset(); - } -#else - assert(endianness == memif_endianness_little); -#endif -} - -memif_endianness_t sim_t::get_target_endianness() const -{ -#ifdef RISCV_ENABLE_DUAL_ENDIAN - return debug_mmu->is_target_big_endian()? memif_endianness_big : memif_endianness_little; -#else - return memif_endianness_little; -#endif + return debug_mmu->is_target_big_endian()? endianness_big : endianness_little; } void sim_t::proc_reset(unsigned id) diff --git a/vendor/riscv/riscv-isa-sim/riscv/sim.h b/vendor/riscv/riscv-isa-sim/riscv/sim.h index a425da48b..3109173f1 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/sim.h +++ b/vendor/riscv/riscv-isa-sim/riscv/sim.h @@ -3,14 +3,7 @@ #ifndef _RISCV_SIM_H #define _RISCV_SIM_H -#include "config.h" - -#ifdef HAVE_BOOST_ASIO -#include -#include -#include -#endif - +#include "cfg.h" #include "debug_module.h" #include "devices.h" #include "log_file.h" @@ -18,30 +11,27 @@ #include "simif.h" #include -#include #include +#include #include #include #include class mmu_t; class remote_bitbang_t; +class socketif_t; // this class encapsulates the processors and memory in a RISC-V machine. class sim_t : public htif_t, public simif_t { public: - sim_t(const char* isa, const char* priv, const char* varch, size_t _nprocs, - bool halted, bool real_time_clint, - reg_t initrd_start, reg_t initrd_end, const char* bootargs, - reg_t start_pc, std::vector> mems, + sim_t(const cfg_t *cfg, bool halted, + std::vector> mems, std::vector> plugin_devices, - const std::vector& args, const std::vector hartids, + const std::vector& args, const debug_module_config_t &dm_config, const char *log_path, bool dtb_enabled, const char *dtb_file, -#ifdef HAVE_BOOST_ASIO - boost::asio::io_service *io_service_ptr_ctor, boost::asio::ip::tcp::acceptor *acceptor_ptr_ctor, // option -s -#endif + bool socket_enabled, FILE *cmd_file); // needed for command line option --cmd ~sim_t(); @@ -53,50 +43,43 @@ public: // Configure logging // // If enable_log is true, an instruction trace will be generated. If - // enable_commitlog is true, so will the commit results (if this - // build was configured without support for commit logging, the - // function will print an error message and abort). + // enable_commitlog is true, so will the commit results void configure_log(bool enable_log, bool enable_commitlog); void set_procs_debug(bool value); void set_remote_bitbang(remote_bitbang_t* remote_bitbang) { this->remote_bitbang = remote_bitbang; } - const char* get_dts() { if (dts.empty()) reset(); return dts.c_str(); } + const char* get_dts() { return dts.c_str(); } processor_t* get_core(size_t i) { return procs.at(i); } - unsigned nprocs() const { return procs.size(); } + virtual const cfg_t &get_cfg() const override { return *cfg; } + + virtual const std::map& get_harts() const override { return harts; } // Callback for processors to let the simulation know they were reset. - void proc_reset(unsigned id); + virtual void proc_reset(unsigned id) override; private: + isa_parser_t isa; + const cfg_t * const cfg; std::vector> mems; std::vector> plugin_devices; - mmu_t* debug_mmu; // debug port into main memory std::vector procs; - reg_t initrd_start; - reg_t initrd_end; - const char* bootargs; - reg_t start_pc; + std::map harts; + std::pair initrd_range; std::string dts; std::string dtb; - std::string dtb_file; bool dtb_enabled; std::unique_ptr boot_rom; std::unique_ptr clint; + std::unique_ptr plic; + std::unique_ptr ns16550; bus_t bus; log_file_t log_file; FILE *cmd_file; // pointer to debug command input file -#ifdef HAVE_BOOST_ASIO - // the following are needed for command socket interface - boost::asio::io_service *io_service_ptr; - boost::asio::ip::tcp::acceptor *acceptor_ptr; - std::unique_ptr socket_ptr; - std::string rin(boost::asio::streambuf *bout_ptr); // read input command string - void wout(boost::asio::streambuf *bout_ptr); // write output to socket -#endif + socketif_t *socketif; std::ostream sout_; // used for socket and terminal interface processor_t* get_core(const std::string& i); @@ -110,15 +93,16 @@ private: bool histogram_enabled; // provide a histogram of PCs bool log; remote_bitbang_t* remote_bitbang; + std::optional> next_interactive_action; // memory-mapped I/O routines - char* addr_to_mem(reg_t addr); - bool mmio_load(reg_t addr, size_t len, uint8_t* bytes); - bool mmio_store(reg_t addr, size_t len, const uint8_t* bytes); - void make_dtb(); + virtual char* addr_to_mem(reg_t paddr) override; + virtual bool mmio_load(reg_t paddr, size_t len, uint8_t* bytes) override; + virtual bool mmio_store(reg_t paddr, size_t len, const uint8_t* bytes) override; + void make_dtb(const char* dtb_file); void set_rom(); - const char* get_symbol(uint64_t addr); + virtual const char* get_symbol(uint64_t paddr) override; // presents a prompt for introspection into the simulation void interactive(); @@ -136,34 +120,31 @@ private: void interactive_fregs(const std::string& cmd, const std::vector& args); void interactive_fregd(const std::string& cmd, const std::vector& args); void interactive_pc(const std::string& cmd, const std::vector& args); + void interactive_priv(const std::string& cmd, const std::vector& args); void interactive_mem(const std::string& cmd, const std::vector& args); void interactive_str(const std::string& cmd, const std::vector& args); + void interactive_dumpmems(const std::string& cmd, const std::vector& args); + void interactive_mtime(const std::string& cmd, const std::vector& args); + void interactive_mtimecmp(const std::string& cmd, const std::vector& args); void interactive_until(const std::string& cmd, const std::vector& args, bool noisy); void interactive_until_silent(const std::string& cmd, const std::vector& args); void interactive_until_noisy(const std::string& cmd, const std::vector& args); reg_t get_reg(const std::vector& args); - freg_t get_freg(const std::vector& args); + freg_t get_freg(const std::vector& args, int size); reg_t get_mem(const std::vector& args); reg_t get_pc(const std::vector& args); friend class processor_t; friend class mmu_t; - friend class debug_module_t; // htif - friend void sim_thread_main(void*); - void main(); - - context_t* host; - context_t target; - void reset(); - void idle(); - void read_chunk(addr_t taddr, size_t len, void* dst); - void write_chunk(addr_t taddr, size_t len, const void* src); - size_t chunk_align() { return 8; } - size_t chunk_max_size() { return 8; } - void set_target_endianness(memif_endianness_t endianness); - memif_endianness_t get_target_endianness() const; + virtual void reset() override; + virtual void idle() override; + virtual void read_chunk(addr_t taddr, size_t len, void* dst) override; + virtual void write_chunk(addr_t taddr, size_t len, const void* src) override; + virtual size_t chunk_align() override { return 8; } + virtual size_t chunk_max_size() override { return 8; } + virtual endianness_t get_target_endianness() const override; public: // Initialize this after procs, because in debug_module_t::reset() we diff --git a/vendor/riscv/riscv-isa-sim/riscv/simif.h b/vendor/riscv/riscv-isa-sim/riscv/simif.h index 0e75d45b1..aeab5dba7 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/simif.h +++ b/vendor/riscv/riscv-isa-sim/riscv/simif.h @@ -3,22 +3,37 @@ #ifndef _RISCV_SIMIF_H #define _RISCV_SIMIF_H +#include #include "decode.h" +#include "cfg.h" + +class processor_t; +class mmu_t; // this is the interface to the simulator used by the processors and memory class simif_t { public: // should return NULL for MMIO addresses - virtual char* addr_to_mem(reg_t addr) = 0; + virtual char* addr_to_mem(reg_t paddr) = 0; + virtual bool reservable(reg_t paddr) { return addr_to_mem(paddr); } // used for MMIO addresses - virtual bool mmio_load(reg_t addr, size_t len, uint8_t* bytes) = 0; - virtual bool mmio_store(reg_t addr, size_t len, const uint8_t* bytes) = 0; + virtual bool mmio_fetch(reg_t paddr, size_t len, uint8_t* bytes) { return mmio_load(paddr, len, bytes); } + virtual bool mmio_load(reg_t paddr, size_t len, uint8_t* bytes) = 0; + virtual bool mmio_store(reg_t paddr, size_t len, const uint8_t* bytes) = 0; // Callback for processors to let the simulation know they were reset. virtual void proc_reset(unsigned id) = 0; - virtual const char* get_symbol(uint64_t addr) = 0; + virtual const cfg_t &get_cfg() const = 0; + virtual const std::map& get_harts() const = 0; + virtual const char* get_symbol(uint64_t paddr) = 0; + + virtual ~simif_t() = default; + + unsigned nprocs() const { return get_cfg().nprocs(); } + + mmu_t* debug_mmu; // debug port into main memory, for use by debug_module }; #endif diff --git a/vendor/riscv/riscv-isa-sim/riscv/socketif.cc b/vendor/riscv/riscv-isa-sim/riscv/socketif.cc new file mode 100644 index 000000000..088475259 --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/socketif.cc @@ -0,0 +1,74 @@ +// See LICENSE for license details. + +#include "socketif.h" + +#ifdef HAVE_BOOST_ASIO + +#include + +socketif_t::socketif_t() +{ + try { // create socket server + using boost::asio::ip::tcp; + io_service_ptr = new boost::asio::io_service; + acceptor_ptr = new tcp::acceptor(*io_service_ptr, tcp::endpoint(tcp::v4(), 0)); + // acceptor is created passing argument port=0, so O.S. will choose a free port + std::string name = boost::asio::ip::host_name(); + std::cout << "Listening for debug commands on " << name.substr(0,name.find('.')) + << " port " << acceptor_ptr->local_endpoint().port() << " ." << std::endl; + // at the end, add space and some other character for convenience of javascript .split(" ") + } catch (std::exception& e) { + std::cerr << e.what() << std::endl; + exit(-1); + } +} + +socketif_t::~socketif_t() +{ + delete io_service_ptr; + delete acceptor_ptr; +} + +// read input command string +std::string socketif_t::rin(std::ostream &sout_) +{ + std::string s; + try { + socket_ptr.reset(new boost::asio::ip::tcp::socket(*io_service_ptr)); + acceptor_ptr->accept(*socket_ptr); // wait for someone to open connection + boost::asio::streambuf buf; + boost::asio::read_until(*socket_ptr, buf, "\n"); // wait for command + s = boost::asio::buffer_cast(buf.data()); + boost::erase_all(s, "\r"); // get rid off any cr and lf + boost::erase_all(s, "\n"); + // The socket client is a web server and it appends the IP of the computer + // that sent the command from its web browser. + + // For now, erase the IP if it is there. + boost::regex re(" ((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}" + "(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])$"); + s = boost::regex_replace(s, re, (std::string)""); + + // TODO: check the IP against the IP used to upload RISC-V source files + } catch (std::exception& e) { + std::cerr << e.what() << std::endl; + } + // output goes to socket + sout_.rdbuf(&bout); + return s; +} + +// write sout_ to socket (via bout) +void socketif_t::wout() { + try { + boost::system::error_code ignored_error; + boost::asio::write(*socket_ptr, bout, boost::asio::transfer_all(), ignored_error); + socket_ptr->close(); // close the socket after each command input/ouput + // This is need to in order to make the socket interface + // acessible by HTTP GET via a socket client in a web server. + } catch (std::exception& e) { + std::cerr << e.what() << std::endl; + } +} + +#endif diff --git a/vendor/riscv/riscv-isa-sim/riscv/socketif.h b/vendor/riscv/riscv-isa-sim/riscv/socketif.h new file mode 100644 index 000000000..7ce9142d3 --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/socketif.h @@ -0,0 +1,32 @@ +// See LICENSE for license details. + +#ifndef _RISCV_SOCKETIF_H +#define _RISCV_SOCKETIF_H + +#include "config.h" + +#ifdef HAVE_BOOST_ASIO + +#include +#include +#include + +class socketif_t +{ +public: + socketif_t(); + ~socketif_t(); + + std::string rin(std::ostream &sout_); // read input command string + void wout(); // write output to socket + +private: + // the following are needed for command socket interface + boost::asio::io_service *io_service_ptr; + boost::asio::ip::tcp::acceptor *acceptor_ptr; + std::unique_ptr socket_ptr; + boost::asio::streambuf bout; +}; + +#endif +#endif diff --git a/vendor/riscv/riscv-isa-sim/riscv/tracer.h b/vendor/riscv/riscv-isa-sim/riscv/tracer.h index 9f1bc7841..d74edae90 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/tracer.h +++ b/vendor/riscv/riscv-isa-sim/riscv/tracer.h @@ -5,7 +5,7 @@ #include "processor.h" -static inline void trace_opcode(processor_t* p, insn_bits_t opc, insn_t insn) { +static inline void trace_opcode(processor_t UNUSED *p, insn_bits_t UNUSED opc, insn_t UNUSED insn) { } #endif diff --git a/vendor/riscv/riscv-isa-sim/riscv/trap.cc b/vendor/riscv/riscv-isa-sim/riscv/trap.cc deleted file mode 100644 index 4ac2f1f71..000000000 --- a/vendor/riscv/riscv-isa-sim/riscv/trap.cc +++ /dev/null @@ -1,12 +0,0 @@ -// See LICENSE for license details. - -#include "trap.h" -#include "processor.h" -#include - -const char* trap_t::name() -{ - const char* fmt = uint8_t(which) == which ? "trap #%u" : "interrupt #%u"; - sprintf(_name, fmt, uint8_t(which)); - return _name; -} diff --git a/vendor/riscv/riscv-isa-sim/riscv/trap.h b/vendor/riscv/riscv-isa-sim/riscv/trap.h index 5ae780668..54948fdde 100644 --- a/vendor/riscv/riscv-isa-sim/riscv/trap.h +++ b/vendor/riscv/riscv-isa-sim/riscv/trap.h @@ -4,15 +4,20 @@ #define _RISCV_TRAP_H #include "decode.h" -#include +#include "encoding.h" +#include struct state_t; +class trap_debug_mode +{ + /* Used to enter debug mode, which isn't quite a normal trap. */ +}; + class trap_t { public: trap_t(reg_t which) : which(which) {} - virtual const char* name(); virtual bool has_gva() { return false; } virtual bool has_tval() { return false; } virtual reg_t get_tval() { return 0; } @@ -20,9 +25,18 @@ class trap_t virtual reg_t get_tval2() { return 0; } virtual bool has_tinst() { return false; } virtual reg_t get_tinst() { return 0; } - reg_t cause() { return which; } + reg_t cause() const { return which; } + + virtual std::string name() + { + const uint8_t code = uint8_t(which); + const bool is_interrupt = code != which; + return (is_interrupt ? "interrupt #" : "trap #") + std::to_string(code); + } + + virtual ~trap_t() = default; + private: - char _name[16]; reg_t which; }; @@ -59,31 +73,31 @@ class mem_trap_t : public trap_t #define DECLARE_TRAP(n, x) class trap_##x : public trap_t { \ public: \ trap_##x() : trap_t(n) {} \ - const char* name() { return "trap_"#x; } \ + std::string name() { return "trap_"#x; } \ }; #define DECLARE_INST_TRAP(n, x) class trap_##x : public insn_trap_t { \ public: \ trap_##x(reg_t tval) : insn_trap_t(n, /*gva*/false, tval) {} \ - const char* name() { return "trap_"#x; } \ + std::string name() { return "trap_"#x; } \ }; #define DECLARE_INST_WITH_GVA_TRAP(n, x) class trap_##x : public insn_trap_t { \ public: \ trap_##x(bool gva, reg_t tval) : insn_trap_t(n, gva, tval) {} \ - const char* name() { return "trap_"#x; } \ + std::string name() { return "trap_"#x; } \ }; #define DECLARE_MEM_TRAP(n, x) class trap_##x : public mem_trap_t { \ public: \ trap_##x(bool gva, reg_t tval, reg_t tval2, reg_t tinst) : mem_trap_t(n, gva, tval, tval2, tinst) {} \ - const char* name() { return "trap_"#x; } \ + std::string name() { return "trap_"#x; } \ }; #define DECLARE_MEM_GVA_TRAP(n, x) class trap_##x : public mem_trap_t { \ public: \ trap_##x(reg_t tval, reg_t tval2, reg_t tinst) : mem_trap_t(n, true, tval, tval2, tinst) {} \ - const char* name() { return "trap_"#x; } \ + std::string name() { return "trap_"#x; } \ }; DECLARE_MEM_TRAP(CAUSE_MISALIGNED_FETCH, instruction_address_misaligned) diff --git a/vendor/riscv/riscv-isa-sim/riscv/triggers.cc b/vendor/riscv/riscv-isa-sim/riscv/triggers.cc new file mode 100644 index 000000000..86dcc81a1 --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/triggers.cc @@ -0,0 +1,620 @@ +#include "arith.h" +#include "debug_defines.h" +#include "processor.h" +#include "triggers.h" + +#define ASIDMAX(SXLEN) (SXLEN == 32 ? 9 : 16) +#define SATP_ASID(SXLEN) (SXLEN == 32 ? SATP32_ASID : SATP64_ASID) +#define VMIDMAX(HSXLEN) (HSXLEN == 32 ? 7 : 14) +#define HGATP_VMID(HSXLEN) (HSXLEN == 32 ? HGATP32_VMID : HGATP64_VMID) + +#define CSR_TEXTRA_MHVALUE_LENGTH(XLEN) (XLEN == 32 ? CSR_TEXTRA32_MHVALUE_LENGTH : CSR_TEXTRA64_MHVALUE_LENGTH) +#define CSR_TEXTRA_MHVALUE(XLEN) (XLEN == 32 ? CSR_TEXTRA32_MHVALUE : CSR_TEXTRA64_MHVALUE) +#define CSR_TEXTRA_MHSELECT(XLEN) (XLEN == 32 ? CSR_TEXTRA32_MHSELECT : CSR_TEXTRA64_MHSELECT) +#define CSR_TEXTRA_SBYTEMASK(XLEN) (XLEN == 32 ? CSR_TEXTRA32_SBYTEMASK : CSR_TEXTRA64_SBYTEMASK) +#define CSR_TEXTRA_SVALUE(XLEN) (XLEN == 32 ? CSR_TEXTRA32_SVALUE : CSR_TEXTRA64_SVALUE) +#define CSR_TEXTRA_SSELECT(XLEN) (XLEN == 32 ? CSR_TEXTRA32_SSELECT : CSR_TEXTRA64_SSELECT) + +namespace triggers { + +reg_t trigger_t::tdata2_read(const processor_t UNUSED * const proc) const noexcept { + return tdata2; +} + +void trigger_t::tdata2_write(processor_t UNUSED * const proc, const reg_t UNUSED val) noexcept { + tdata2 = val; +} + +action_t trigger_t::legalize_action(reg_t val, reg_t action_mask, reg_t dmode_mask) noexcept { + reg_t act = get_field(val, action_mask); + return (act > ACTION_MAXVAL || (act == ACTION_DEBUG_MODE && get_field(val, dmode_mask) == 0)) ? ACTION_DEBUG_EXCEPTION : (action_t)act; +} + +unsigned trigger_t::legalize_mhselect(bool h_enabled) const noexcept { + const auto interp = interpret_mhselect(h_enabled); + return interp.mhselect; +} + +reg_t trigger_t::tdata3_read(const processor_t * const proc) const noexcept { + auto xlen = proc->get_xlen(); + reg_t tdata3 = 0; + tdata3 = set_field(tdata3, CSR_TEXTRA_MHVALUE(xlen), mhvalue); + tdata3 = set_field(tdata3, CSR_TEXTRA_MHSELECT(xlen), legalize_mhselect(proc->extension_enabled('H'))); + tdata3 = set_field(tdata3, CSR_TEXTRA_SBYTEMASK(xlen), sbytemask); + tdata3 = set_field(tdata3, CSR_TEXTRA_SVALUE(xlen), svalue); + tdata3 = set_field(tdata3, CSR_TEXTRA_SSELECT(xlen), sselect); + return tdata3; +} + +void trigger_t::tdata3_write(processor_t * const proc, const reg_t val) noexcept { + auto xlen = proc->get_xlen(); + mhvalue = get_field(val, CSR_TEXTRA_MHVALUE(xlen)); + mhselect = get_field(val, CSR_TEXTRA_MHSELECT(xlen)); + sbytemask = get_field(val, CSR_TEXTRA_SBYTEMASK(xlen)); + svalue = proc->extension_enabled_const('S') ? get_field(val, CSR_TEXTRA_SVALUE(xlen)) : 0; + sselect = (sselect_t)((proc->extension_enabled_const('S') && get_field(val, CSR_TEXTRA_SSELECT(xlen)) <= SSELECT_MAXVAL) ? get_field(val, CSR_TEXTRA_SSELECT(xlen)) : SSELECT_IGNORE); +} + +bool trigger_t::common_match(processor_t * const proc) const noexcept { + return mode_match(proc->get_state()) && textra_match(proc); +} + +bool trigger_t::mode_match(state_t * const state) const noexcept +{ + switch (state->prv) { + case PRV_M: return m; + case PRV_S: return state->v ? vs : s; + case PRV_U: return state->v ? vu : u; + default: assert(false); + } +} + +bool trigger_t::textra_match(processor_t * const proc) const noexcept +{ + auto xlen = proc->get_xlen(); + auto hsxlen = proc->get_xlen(); // use xlen since no hsxlen + state_t * const state = proc->get_state(); + + assert(sselect <= SSELECT_MAXVAL); + if (sselect == SSELECT_SCONTEXT) { + reg_t mask = (reg_t(1) << ((xlen == 32) ? CSR_TEXTRA32_SVALUE_LENGTH : CSR_TEXTRA64_SVALUE_LENGTH)) - 1; + assert(CSR_TEXTRA32_SBYTEMASK_LENGTH < CSR_TEXTRA64_SBYTEMASK_LENGTH); + for (int i = 0; i < CSR_TEXTRA64_SBYTEMASK_LENGTH; i++) + if (sbytemask & (1 << i)) + mask &= 0xff << (i * 8); + if ((state->scontext->read() & mask) != (svalue & mask)) + return false; + } else if (sselect == SSELECT_ASID) { + const reg_t satp = state->satp->read(); + const reg_t asid = get_field(satp, SATP_ASID(xlen)); + if (asid != (svalue & ((1 << ASIDMAX(xlen)) - 1))) + return false; + } + + const auto mhselect_interp = interpret_mhselect(proc->extension_enabled('H')); + const mhselect_mode_t mode = mhselect_interp.mode; + if (mode == MHSELECT_MODE_MCONTEXT) { // 4, 1, and 5 are mcontext + reg_t mask = (1 << (CSR_TEXTRA_MHVALUE_LENGTH(xlen) + 1)) - 1; + if ((state->mcontext->read() & mask) != mhselect_interp.compare_val(mhvalue)) + return false; + } else if (mode == MHSELECT_MODE_VMID) { // 2 and 6 are vmid + const reg_t vmid = get_field(state->hgatp->read(), HGATP_VMID(hsxlen)); + if (vmid != (mhselect_interp.compare_val(mhvalue) & ((1 << VMIDMAX(hsxlen)) - 1))) + return false; + } + + return true; +} + +bool trigger_t::allow_action(const state_t * const state) const +{ + if (get_action() == ACTION_DEBUG_EXCEPTION) { + const bool mstatus_mie = state->mstatus->read() & MSTATUS_MIE; + const bool sstatus_sie = state->sstatus->read() & MSTATUS_SIE; + const bool vsstatus_sie = state->vsstatus->read() & MSTATUS_SIE; + const bool medeleg_breakpoint = (state->medeleg->read() >> CAUSE_BREAKPOINT) & 1; + const bool hedeleg_breakpoint = (state->hedeleg->read() >> CAUSE_BREAKPOINT) & 1; + return (state->prv != PRV_M || mstatus_mie) && + (state->prv != PRV_S || state->v || !medeleg_breakpoint || sstatus_sie) && + (state->prv != PRV_S || !state->v || !medeleg_breakpoint || !hedeleg_breakpoint || vsstatus_sie); + } + return true; +} + +reg_t disabled_trigger_t::tdata1_read(const processor_t * const proc) const noexcept +{ + auto xlen = proc->get_xlen(); + reg_t tdata1 = 0; + tdata1 = set_field(tdata1, CSR_TDATA1_TYPE(xlen), CSR_TDATA1_TYPE_DISABLED); + tdata1 = set_field(tdata1, CSR_TDATA1_DMODE(xlen), dmode); + return tdata1; +} + +void disabled_trigger_t::tdata1_write(processor_t * const proc, const reg_t val, const bool UNUSED allow_chain) noexcept +{ + // Any supported tdata.type results in disabled trigger + auto xlen = proc->get_xlen(); + dmode = get_field(val, CSR_TDATA1_DMODE(xlen)); +} + +reg_t mcontrol_t::tdata1_read(const processor_t * const proc) const noexcept { + reg_t v = 0; + auto xlen = proc->get_xlen(); + v = set_field(v, MCONTROL_TYPE(xlen), CSR_TDATA1_TYPE_MCONTROL); + v = set_field(v, CSR_MCONTROL_DMODE(xlen), dmode); + v = set_field(v, MCONTROL_MASKMAX(xlen), 0); + v = set_field(v, CSR_MCONTROL_HIT, hit); + v = set_field(v, MCONTROL_SELECT, select); + v = set_field(v, MCONTROL_TIMING, timing); + v = set_field(v, MCONTROL_ACTION, action); + v = set_field(v, MCONTROL_CHAIN, chain); + v = set_field(v, MCONTROL_MATCH, match); + v = set_field(v, MCONTROL_M, m); + v = set_field(v, MCONTROL_S, s); + v = set_field(v, MCONTROL_U, u); + v = set_field(v, MCONTROL_EXECUTE, execute); + v = set_field(v, MCONTROL_STORE, store); + v = set_field(v, MCONTROL_LOAD, load); + return v; +} + +void mcontrol_t::tdata1_write(processor_t * const proc, const reg_t val, const bool allow_chain) noexcept { + auto xlen = proc->get_xlen(); + assert(get_field(val, CSR_MCONTROL_TYPE(xlen)) == CSR_TDATA1_TYPE_MCONTROL); + dmode = get_field(val, CSR_MCONTROL_DMODE(xlen)); + hit = get_field(val, CSR_MCONTROL_HIT); + select = get_field(val, MCONTROL_SELECT); + timing = legalize_timing(val, MCONTROL_TIMING, MCONTROL_SELECT, MCONTROL_EXECUTE, MCONTROL_LOAD); + action = legalize_action(val, MCONTROL_ACTION, CSR_MCONTROL_DMODE(xlen)); + chain = allow_chain ? get_field(val, MCONTROL_CHAIN) : 0; + match = legalize_match(get_field(val, MCONTROL_MATCH)); + m = get_field(val, MCONTROL_M); + s = proc->extension_enabled_const('S') ? get_field(val, CSR_MCONTROL_S) : 0; + u = proc->extension_enabled_const('U') ? get_field(val, CSR_MCONTROL_U) : 0; + execute = get_field(val, MCONTROL_EXECUTE); + store = get_field(val, MCONTROL_STORE); + load = get_field(val, MCONTROL_LOAD); +} + +bool mcontrol_common_t::simple_match(unsigned xlen, reg_t value) const { + switch (match) { + case MATCH_EQUAL: + return value == tdata2; + case MATCH_NAPOT: + { + reg_t mask = ~((1 << (cto(tdata2)+1)) - 1); + return (value & mask) == (tdata2 & mask); + } + case MATCH_GE: + return value >= tdata2; + case MATCH_LT: + return value < tdata2; + case MATCH_MASK_LOW: + { + reg_t mask = tdata2 >> (xlen/2); + return (value & mask) == (tdata2 & mask); + } + case MATCH_MASK_HIGH: + { + reg_t mask = tdata2 >> (xlen/2); + return ((value >> (xlen/2)) & mask) == (tdata2 & mask); + } + } + assert(0); +} + +std::optional mcontrol_common_t::detect_memory_access_match(processor_t * const proc, operation_t operation, reg_t address, std::optional data) noexcept { + if ((operation == triggers::OPERATION_EXECUTE && !execute) || + (operation == triggers::OPERATION_STORE && !store) || + (operation == triggers::OPERATION_LOAD && !load) || + !common_match(proc)) { + return std::nullopt; + } + + reg_t value; + if (select) { + if (!data.has_value()) + return std::nullopt; + value = *data; + } else { + value = address; + } + + // We need this because in 32-bit mode sometimes the PC bits get sign + // extended. + auto xlen = proc->get_xlen(); + if (xlen == 32) { + value &= 0xffffffff; + } + + if (simple_match(xlen, value) && allow_action(proc->get_state())) { + /* This is OK because this function is only called if the trigger was not + * inhibited by the previous trigger in the chain. */ + hit = true; + return match_result_t(timing_t(timing), action); + } + return std::nullopt; +} + +mcontrol_common_t::match_t mcontrol_common_t::legalize_match(reg_t val) noexcept +{ + switch (val) { + case MATCH_EQUAL: + case MATCH_NAPOT: + case MATCH_GE: + case MATCH_LT: + case MATCH_MASK_LOW: + case MATCH_MASK_HIGH: + return (match_t)val; + default: + return MATCH_EQUAL; + } +} + +bool mcontrol_common_t::legalize_timing(reg_t val, reg_t timing_mask, reg_t select_mask, reg_t execute_mask, reg_t load_mask) noexcept { + // For load data triggers, force timing=after to avoid debugger having to repeat loads which may have side effects. + if (get_field(val, select_mask) && get_field(val, load_mask)) + return TIMING_AFTER; + if (get_field(val, execute_mask)) + return TIMING_BEFORE; + return get_field(val, timing_mask); +} + +reg_t mcontrol6_t::tdata1_read(const processor_t * const proc) const noexcept { + unsigned xlen = proc->get_const_xlen(); + reg_t tdata1 = 0; + tdata1 = set_field(tdata1, CSR_MCONTROL6_TYPE(xlen), CSR_TDATA1_TYPE_MCONTROL6); + tdata1 = set_field(tdata1, CSR_MCONTROL6_DMODE(xlen), dmode); + tdata1 = set_field(tdata1, CSR_MCONTROL6_VS, proc->extension_enabled('H') ? vs : 0); + tdata1 = set_field(tdata1, CSR_MCONTROL6_VU, proc->extension_enabled('H') ? vu : 0); + tdata1 = set_field(tdata1, CSR_MCONTROL6_HIT, hit); + tdata1 = set_field(tdata1, CSR_MCONTROL6_SELECT, select); + tdata1 = set_field(tdata1, CSR_MCONTROL6_TIMING, timing); + tdata1 = set_field(tdata1, CSR_MCONTROL6_ACTION, action); + tdata1 = set_field(tdata1, CSR_MCONTROL6_CHAIN, chain); + tdata1 = set_field(tdata1, CSR_MCONTROL6_MATCH, match); + tdata1 = set_field(tdata1, CSR_MCONTROL6_M, m); + tdata1 = set_field(tdata1, CSR_MCONTROL6_S, s); + tdata1 = set_field(tdata1, CSR_MCONTROL6_U, u); + tdata1 = set_field(tdata1, CSR_MCONTROL6_EXECUTE, execute); + tdata1 = set_field(tdata1, CSR_MCONTROL6_STORE, store); + tdata1 = set_field(tdata1, CSR_MCONTROL6_LOAD, load); + return tdata1; +} + +void mcontrol6_t::tdata1_write(processor_t * const proc, const reg_t val, const bool allow_chain) noexcept { + auto xlen = proc->get_const_xlen(); + assert(get_field(val, CSR_MCONTROL6_TYPE(xlen)) == CSR_TDATA1_TYPE_MCONTROL6); + dmode = get_field(val, CSR_MCONTROL6_DMODE(xlen)); + vs = get_field(val, CSR_MCONTROL6_VS); + vu = get_field(val, CSR_MCONTROL6_VU); + hit = get_field(val, CSR_MCONTROL6_HIT); + select = get_field(val, CSR_MCONTROL6_SELECT); + timing = legalize_timing(val, CSR_MCONTROL6_TIMING, CSR_MCONTROL6_SELECT, CSR_MCONTROL6_EXECUTE, CSR_MCONTROL6_LOAD); + action = legalize_action(val, CSR_MCONTROL6_ACTION, CSR_MCONTROL6_DMODE(xlen)); + chain = allow_chain ? get_field(val, CSR_MCONTROL6_CHAIN) : 0; + match = legalize_match(get_field(val, CSR_MCONTROL6_MATCH)); + m = get_field(val, CSR_MCONTROL6_M); + s = proc->extension_enabled_const('S') ? get_field(val, CSR_MCONTROL6_S) : 0; + u = proc->extension_enabled_const('U') ? get_field(val, CSR_MCONTROL6_U) : 0; + execute = get_field(val, CSR_MCONTROL6_EXECUTE); + store = get_field(val, CSR_MCONTROL6_STORE); + load = get_field(val, CSR_MCONTROL6_LOAD); +} + +std::optional icount_t::detect_icount_match(processor_t * const proc) noexcept +{ + if (!common_match(proc) || !allow_action(proc->get_state())) + return std::nullopt; + + std::optional ret = std::nullopt; + if (pending) { + pending = 0; + hit = true; + ret = match_result_t(TIMING_BEFORE, action); + } + + if (count >= 1) { + if (count == 1) + pending = 1; + count = count - 1; + } + + return ret; +} + +reg_t icount_t::tdata1_read(const processor_t * const proc) const noexcept +{ + auto xlen = proc->get_xlen(); + reg_t tdata1 = 0; + tdata1 = set_field(tdata1, CSR_ICOUNT_TYPE(xlen), CSR_TDATA1_TYPE_ICOUNT); + tdata1 = set_field(tdata1, CSR_ICOUNT_DMODE(xlen), dmode); + tdata1 = set_field(tdata1, CSR_ICOUNT_VS, proc->extension_enabled('H') ? vs : 0); + tdata1 = set_field(tdata1, CSR_ICOUNT_VU, proc->extension_enabled('H') ? vu : 0); + tdata1 = set_field(tdata1, CSR_ICOUNT_HIT, hit); + tdata1 = set_field(tdata1, CSR_ICOUNT_COUNT, count_read_value); + tdata1 = set_field(tdata1, CSR_ICOUNT_M, m); + tdata1 = set_field(tdata1, CSR_ICOUNT_PENDING, pending_read_value); + tdata1 = set_field(tdata1, CSR_ICOUNT_S, s); + tdata1 = set_field(tdata1, CSR_ICOUNT_U, u); + tdata1 = set_field(tdata1, CSR_ICOUNT_ACTION, action); + return tdata1; +} + +void icount_t::tdata1_write(processor_t * const proc, const reg_t val, const bool UNUSED allow_chain) noexcept +{ + auto xlen = proc->get_xlen(); + assert(get_field(val, CSR_ICOUNT_TYPE(xlen)) == CSR_TDATA1_TYPE_ICOUNT); + dmode = proc->get_state()->debug_mode ? get_field(val, CSR_ICOUNT_DMODE(xlen)) : 0; + vs = get_field(val, CSR_ICOUNT_VS); + vu = get_field(val, CSR_ICOUNT_VU); + hit = get_field(val, CSR_ICOUNT_HIT); + count = count_read_value = get_field(val, CSR_ICOUNT_COUNT); + m = get_field(val, CSR_ICOUNT_M); + pending = pending_read_value = get_field(val, CSR_ICOUNT_PENDING); + s = proc->extension_enabled_const('S') ? get_field(val, CSR_ICOUNT_S) : 0; + u = proc->extension_enabled_const('U') ? get_field(val, CSR_ICOUNT_U) : 0; + action = legalize_action(val, CSR_ICOUNT_ACTION, CSR_ICOUNT_DMODE(xlen)); +} + +void icount_t::stash_read_values() +{ + count_read_value = count; + pending_read_value = pending; +} + +reg_t itrigger_t::tdata1_read(const processor_t * const proc) const noexcept +{ + auto xlen = proc->get_xlen(); + reg_t tdata1 = 0; + tdata1 = set_field(tdata1, CSR_ITRIGGER_TYPE(xlen), CSR_TDATA1_TYPE_ITRIGGER); + tdata1 = set_field(tdata1, CSR_ITRIGGER_DMODE(xlen), dmode); + tdata1 = set_field(tdata1, CSR_ITRIGGER_HIT(xlen), hit); + tdata1 = set_field(tdata1, CSR_ITRIGGER_VS, proc->extension_enabled('H') ? vs : 0); + tdata1 = set_field(tdata1, CSR_ITRIGGER_VU, proc->extension_enabled('H') ? vu : 0); + tdata1 = set_field(tdata1, CSR_ITRIGGER_NMI, nmi); + tdata1 = set_field(tdata1, CSR_ITRIGGER_M, m); + tdata1 = set_field(tdata1, CSR_ITRIGGER_S, s); + tdata1 = set_field(tdata1, CSR_ITRIGGER_U, u); + tdata1 = set_field(tdata1, CSR_ITRIGGER_ACTION, action); + return tdata1; +} + +void itrigger_t::tdata1_write(processor_t * const proc, const reg_t val, const bool UNUSED allow_chain) noexcept +{ + auto xlen = proc->get_xlen(); + assert(get_field(val, CSR_ITRIGGER_TYPE(xlen)) == CSR_TDATA1_TYPE_ITRIGGER); + dmode = get_field(val, CSR_ITRIGGER_DMODE(xlen)); + hit = get_field(val, CSR_ITRIGGER_HIT(xlen)); + vs = get_field(val, CSR_ITRIGGER_VS); + vu = get_field(val, CSR_ITRIGGER_VU); + nmi = get_field(val, CSR_ITRIGGER_NMI); + m = get_field(val, CSR_ITRIGGER_M); + s = proc->extension_enabled_const('S') ? get_field(val, CSR_ITRIGGER_S) : 0; + u = proc->extension_enabled_const('U') ? get_field(val, CSR_ITRIGGER_U) : 0; + action = legalize_action(val, CSR_ITRIGGER_ACTION, CSR_ITRIGGER_DMODE(xlen)); +} + +std::optional trap_common_t::detect_trap_match(processor_t * const proc, const trap_t& t) noexcept +{ + if (!common_match(proc)) + return std::nullopt; + + auto xlen = proc->get_xlen(); + bool interrupt = (t.cause() & ((reg_t)1 << (xlen - 1))) != 0; + reg_t bit = t.cause() & ~((reg_t)1 << (xlen - 1)); + assert(bit < xlen); + if (simple_match(interrupt, bit) && allow_action(proc->get_state())) { + hit = true; + return match_result_t(TIMING_AFTER, action); + } + return std::nullopt; +} + +bool itrigger_t::simple_match(bool interrupt, reg_t bit) const +{ + return interrupt && ((bit == 0 && nmi) || ((tdata2 >> bit) & 1)); // Assume NMI's exception code is 0 +} + +reg_t etrigger_t::tdata1_read(const processor_t * const proc) const noexcept +{ + auto xlen = proc->get_xlen(); + reg_t tdata1 = 0; + tdata1 = set_field(tdata1, CSR_ETRIGGER_TYPE(xlen), CSR_TDATA1_TYPE_ETRIGGER); + tdata1 = set_field(tdata1, CSR_ETRIGGER_DMODE(xlen), dmode); + tdata1 = set_field(tdata1, CSR_ETRIGGER_HIT(xlen), hit); + tdata1 = set_field(tdata1, CSR_ETRIGGER_VS, proc->extension_enabled('H') ? vs : 0); + tdata1 = set_field(tdata1, CSR_ETRIGGER_VU, proc->extension_enabled('H') ? vu : 0); + tdata1 = set_field(tdata1, CSR_ETRIGGER_M, m); + tdata1 = set_field(tdata1, CSR_ETRIGGER_S, s); + tdata1 = set_field(tdata1, CSR_ETRIGGER_U, u); + tdata1 = set_field(tdata1, CSR_ETRIGGER_ACTION, action); + return tdata1; +} + +void etrigger_t::tdata1_write(processor_t * const proc, const reg_t val, const bool UNUSED allow_chain) noexcept +{ + auto xlen = proc->get_xlen(); + assert(get_field(val, CSR_ETRIGGER_TYPE(xlen)) == CSR_TDATA1_TYPE_ETRIGGER); + dmode = get_field(val, CSR_ETRIGGER_DMODE(xlen)); + hit = get_field(val, CSR_ETRIGGER_HIT(xlen)); + vs = get_field(val, CSR_ETRIGGER_VS); + vu = get_field(val, CSR_ETRIGGER_VU); + m = get_field(val, CSR_ETRIGGER_M); + s = proc->extension_enabled_const('S') ? get_field(val, CSR_ETRIGGER_S) : 0; + u = proc->extension_enabled_const('U') ? get_field(val, CSR_ETRIGGER_U) : 0; + action = legalize_action(val, CSR_ETRIGGER_ACTION, CSR_ETRIGGER_DMODE(xlen)); +} + +bool etrigger_t::simple_match(bool interrupt, reg_t bit) const +{ + return !interrupt && ((tdata2 >> bit) & 1); +} + +module_t::module_t(unsigned count) : triggers(count) { + for (unsigned i = 0; i < count; i++) { + triggers[i] = new disabled_trigger_t(); + } +} + +module_t::~module_t() { + for (auto trigger : triggers) { + delete trigger; + } +} + +reg_t module_t::tdata1_read(unsigned index) const noexcept +{ + return triggers[index]->tdata1_read(proc); +} + +bool module_t::tdata1_write(unsigned index, const reg_t val) noexcept +{ + if (triggers[index]->get_dmode() && !proc->get_state()->debug_mode) { + return false; + } + + auto xlen = proc->get_xlen(); + + reg_t tdata1 = val; + + // hardware must zero chain in writes that set dmode to 0 if the next trigger has dmode of 1 + const bool allow_chain = !(index+1 < triggers.size() && triggers[index+1]->get_dmode() && !get_field(val, CSR_TDATA1_DMODE(xlen))); + + // dmode only writable from debug mode + if (!proc->get_state()->debug_mode) { + assert(CSR_TDATA1_DMODE(xlen) == CSR_MCONTROL_DMODE(xlen)); + assert(CSR_TDATA1_DMODE(xlen) == CSR_ITRIGGER_DMODE(xlen)); + assert(CSR_TDATA1_DMODE(xlen) == CSR_ETRIGGER_DMODE(xlen)); + tdata1 = set_field(tdata1, CSR_TDATA1_DMODE(xlen), 0); + } + + // hardware should ignore writes that set dmode to 1 if the previous trigger has both dmode of 0 and chain of 1 + if (index > 0 && !triggers[index-1]->get_dmode() && triggers[index-1]->get_chain() && get_field(tdata1, CSR_TDATA1_DMODE(xlen))) + return false; + + unsigned type = get_field(val, CSR_TDATA1_TYPE(xlen)); + reg_t tdata2 = triggers[index]->tdata2_read(proc); + reg_t tdata3 = triggers[index]->tdata3_read(proc); + delete triggers[index]; + switch (type) { + case CSR_TDATA1_TYPE_MCONTROL: triggers[index] = new mcontrol_t(); break; + case CSR_TDATA1_TYPE_ICOUNT: triggers[index] = new icount_t(); break; + case CSR_TDATA1_TYPE_ITRIGGER: triggers[index] = new itrigger_t(); break; + case CSR_TDATA1_TYPE_ETRIGGER: triggers[index] = new etrigger_t(); break; + case CSR_TDATA1_TYPE_MCONTROL6: triggers[index] = new mcontrol6_t(); break; + default: triggers[index] = new disabled_trigger_t(); break; + } + + triggers[index]->tdata1_write(proc, tdata1, allow_chain); + triggers[index]->tdata2_write(proc, tdata2); + triggers[index]->tdata3_write(proc, tdata3); + proc->trigger_updated(triggers); + return true; +} + +reg_t module_t::tdata2_read(unsigned index) const noexcept +{ + return triggers[index]->tdata2_read(proc); +} + +bool module_t::tdata2_write(unsigned index, const reg_t val) noexcept +{ + if (triggers[index]->get_dmode() && !proc->get_state()->debug_mode) { + return false; + } + triggers[index]->tdata2_write(proc, val); + proc->trigger_updated(triggers); + return true; +} + +reg_t module_t::tdata3_read(unsigned index) const noexcept +{ + return triggers[index]->tdata3_read(proc); +} + +bool module_t::tdata3_write(unsigned index, const reg_t val) noexcept +{ + if (triggers[index]->get_dmode() && !proc->get_state()->debug_mode) { + return false; + } + triggers[index]->tdata3_write(proc, val); + proc->trigger_updated(triggers); + return true; +} + +std::optional module_t::detect_memory_access_match(operation_t operation, reg_t address, std::optional data) noexcept +{ + state_t * const state = proc->get_state(); + if (state->debug_mode) + return std::nullopt; + + bool chain_ok = true; + + std::optional ret = std::nullopt; + for (auto trigger: triggers) { + if (!chain_ok) { + chain_ok = !trigger->get_chain(); + continue; + } + + /* Note: We call detect_memory_access_match for each trigger in a chain as long as + * the triggers are matching. This results in "temperature coding" so that + * `hit` is set on each of the consecutive triggers that matched, even if the + * entire chain did not match. This is allowed by the spec, because the final + * trigger in the chain will never get `hit` set unless the entire chain + * matches. */ + auto result = trigger->detect_memory_access_match(proc, operation, address, data); + if (result.has_value() && !trigger->get_chain() && (!ret.has_value() || ret->action < result->action)) + ret = result; + + chain_ok = result.has_value() || !trigger->get_chain(); + } + return ret; +} + +std::optional module_t::detect_icount_match() noexcept +{ + for (auto trigger: triggers) + trigger->stash_read_values(); + + state_t * const state = proc->get_state(); + if (state->debug_mode) + return std::nullopt; + + std::optional ret = std::nullopt; + for (auto trigger: triggers) { + auto result = trigger->detect_icount_match(proc); + if (result.has_value() && (!ret.has_value() || ret->action < result->action)) + ret = result; + } + return ret; +} + +std::optional module_t::detect_trap_match(const trap_t& t) noexcept +{ + state_t * const state = proc->get_state(); + if (state->debug_mode) + return std::nullopt; + + std::optional ret = std::nullopt; + for (auto trigger: triggers) { + auto result = trigger->detect_trap_match(proc, t); + if (result.has_value() && (!ret.has_value() || ret->action < result->action)) + ret = result; + } + return ret; +} + +reg_t module_t::tinfo_read(unsigned UNUSED index) const noexcept +{ + /* In spike, every trigger supports the same types. */ + return (1 << CSR_TDATA1_TYPE_MCONTROL) | + (1 << CSR_TDATA1_TYPE_ICOUNT) | + (1 << CSR_TDATA1_TYPE_ITRIGGER) | + (1 << CSR_TDATA1_TYPE_ETRIGGER) | + (1 << CSR_TDATA1_TYPE_MCONTROL6) | + (1 << CSR_TDATA1_TYPE_DISABLED); +} + +}; diff --git a/vendor/riscv/riscv-isa-sim/riscv/triggers.h b/vendor/riscv/riscv-isa-sim/riscv/triggers.h new file mode 100644 index 000000000..6e3d74d8c --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/triggers.h @@ -0,0 +1,286 @@ +#ifndef _RISCV_TRIGGERS_H +#define _RISCV_TRIGGERS_H + +#include +#include + +#include "decode.h" + +namespace triggers { + +typedef enum { + OPERATION_EXECUTE, + OPERATION_STORE, + OPERATION_LOAD, +} operation_t; + +typedef enum +{ + ACTION_DEBUG_EXCEPTION = MCONTROL_ACTION_DEBUG_EXCEPTION, + ACTION_DEBUG_MODE = MCONTROL_ACTION_DEBUG_MODE, + ACTION_TRACE_START = MCONTROL_ACTION_TRACE_START, + ACTION_TRACE_STOP = MCONTROL_ACTION_TRACE_STOP, + ACTION_TRACE_EMIT = MCONTROL_ACTION_TRACE_EMIT, + ACTION_MAXVAL = MCONTROL_ACTION_TRACE_EMIT +} action_t; + +typedef enum { + TIMING_BEFORE = 0, + TIMING_AFTER = 1 +} timing_t; + +typedef enum { + SSELECT_IGNORE = 0, + SSELECT_SCONTEXT = 1, + SSELECT_ASID = 2, + SSELECT_MAXVAL = 2 +} sselect_t; + +typedef enum { + MHSELECT_MODE_IGNORE, + MHSELECT_MODE_MCONTEXT, + MHSELECT_MODE_VMID, +} mhselect_mode_t; + +struct match_result_t { + match_result_t(const timing_t t=TIMING_BEFORE, const action_t a=ACTION_DEBUG_EXCEPTION) { + timing = t; + action = a; + } + timing_t timing; + action_t action; +}; + +class matched_t +{ + public: + matched_t(triggers::operation_t operation, reg_t address, action_t action) : + operation(operation), address(address), action(action) {} + + triggers::operation_t operation; + reg_t address; + action_t action; +}; + +class trigger_t { +public: + virtual ~trigger_t() {}; + + virtual reg_t tdata1_read(const processor_t * const proc) const noexcept = 0; + virtual void tdata1_write(processor_t * const proc, const reg_t val, const bool allow_chain) noexcept = 0; + reg_t tdata2_read(const processor_t * const proc) const noexcept; + void tdata2_write(processor_t * const proc, const reg_t val) noexcept; + reg_t tdata3_read(const processor_t * const proc) const noexcept; + void tdata3_write(processor_t * const proc, const reg_t val) noexcept; + + virtual bool get_dmode() const = 0; + virtual bool get_chain() const { return false; } + virtual bool get_execute() const { return false; } + virtual bool get_store() const { return false; } + virtual bool get_load() const { return false; } + virtual action_t get_action() const { return ACTION_DEBUG_EXCEPTION; } + virtual bool icount_check_needed() const { return false; } + virtual void stash_read_values() {} + + virtual std::optional detect_memory_access_match(processor_t UNUSED * const proc, + operation_t UNUSED operation, reg_t UNUSED address, std::optional UNUSED data) noexcept { return std::nullopt; } + virtual std::optional detect_icount_match(processor_t UNUSED * const proc) { return std::nullopt; } + virtual std::optional detect_trap_match(processor_t UNUSED * const proc, const trap_t UNUSED & t) noexcept { return std::nullopt; } + +protected: + static action_t legalize_action(reg_t val, reg_t action_mask, reg_t dmode_mask) noexcept; + bool common_match(processor_t * const proc) const noexcept; + bool allow_action(const state_t * const state) const; + reg_t tdata2; + + bool vs = false; + bool vu = false; + bool m = false; + bool s = false; + bool u = false; + +private: + unsigned legalize_mhselect(bool h_enabled) const noexcept; + bool mode_match(state_t * const state) const noexcept; + bool textra_match(processor_t * const proc) const noexcept; + + struct mhselect_interpretation { + const unsigned mhselect; + const mhselect_mode_t mode; + const std::optional shift_mhvalue; + unsigned compare_val(const unsigned mhvalue) const { + return shift_mhvalue.value() ? (mhvalue << 1 | mhselect >> 2) : mhvalue; + }; + }; + + mhselect_interpretation interpret_mhselect(bool h_enabled) const noexcept { + static unsigned warlize_if_h[8] = { 0, 1, 2, 0, 4, 5, 6, 4 }; // 3,7 downgrade + static unsigned warlize_no_h[8] = { 0, 0, 0, 0, 4, 4, 4, 4 }; // only 0,4 legal + static std::optional table[8] = { + mhselect_interpretation{ 0, MHSELECT_MODE_IGNORE, std::nullopt }, + mhselect_interpretation{ 1, MHSELECT_MODE_MCONTEXT, true }, + mhselect_interpretation{ 2, MHSELECT_MODE_VMID, true }, + std::nullopt, + mhselect_interpretation{ 4, MHSELECT_MODE_MCONTEXT, false }, + mhselect_interpretation{ 5, MHSELECT_MODE_MCONTEXT, true }, + mhselect_interpretation{ 6, MHSELECT_MODE_VMID, true }, + std::nullopt + }; + assert(mhselect < 8); + unsigned legal = h_enabled ? warlize_if_h[mhselect] : warlize_no_h[mhselect]; + assert(legal < 8); + return table[legal].value(); + } + + sselect_t sselect; + unsigned svalue; + unsigned sbytemask; + unsigned mhselect; + unsigned mhvalue; +}; + +class disabled_trigger_t : public trigger_t { +public: + virtual reg_t tdata1_read(const processor_t * const proc) const noexcept override; + virtual void tdata1_write(processor_t * const proc, const reg_t val, const bool allow_chain) noexcept override; + + virtual bool get_dmode() const override { return dmode; } + +private: + bool dmode; +}; + +class trap_common_t : public trigger_t { +public: + bool get_dmode() const override { return dmode; } + virtual action_t get_action() const override { return action; } + + virtual std::optional detect_trap_match(processor_t * const proc, const trap_t& t) noexcept override; + +private: + virtual bool simple_match(bool interrupt, reg_t bit) const = 0; + +protected: + bool dmode; + bool hit; + action_t action; +}; + +class itrigger_t : public trap_common_t { +public: + virtual reg_t tdata1_read(const processor_t * const proc) const noexcept override; + virtual void tdata1_write(processor_t * const proc, const reg_t val, const bool allow_chain) noexcept override; + +private: + virtual bool simple_match(bool interrupt, reg_t bit) const override; + bool nmi; +}; + +class etrigger_t : public trap_common_t { +public: + virtual reg_t tdata1_read(const processor_t * const proc) const noexcept override; + virtual void tdata1_write(processor_t * const proc, const reg_t val, const bool allow_chain) noexcept override; + +private: + virtual bool simple_match(bool interrupt, reg_t bit) const override; +}; + +class mcontrol_common_t : public trigger_t { +public: + typedef enum + { + MATCH_EQUAL = MCONTROL_MATCH_EQUAL, + MATCH_NAPOT = MCONTROL_MATCH_NAPOT, + MATCH_GE = MCONTROL_MATCH_GE, + MATCH_LT = MCONTROL_MATCH_LT, + MATCH_MASK_LOW = MCONTROL_MATCH_MASK_LOW, + MATCH_MASK_HIGH = MCONTROL_MATCH_MASK_HIGH + } match_t; + + virtual bool get_dmode() const override { return dmode; } + virtual bool get_chain() const override { return chain; } + virtual bool get_execute() const override { return execute; } + virtual bool get_store() const override { return store; } + virtual bool get_load() const override { return load; } + virtual action_t get_action() const override { return action; } + + virtual std::optional detect_memory_access_match(processor_t * const proc, + operation_t operation, reg_t address, std::optional data) noexcept override; + +private: + bool simple_match(unsigned xlen, reg_t value) const; + +protected: + static match_t legalize_match(reg_t val) noexcept; + static bool legalize_timing(reg_t val, reg_t timing_mask, reg_t select_mask, reg_t execute_mask, reg_t load_mask) noexcept; + bool dmode = false; + action_t action = ACTION_DEBUG_EXCEPTION; + bool hit = false; + bool select = false; + bool timing = false; + bool chain = false; + match_t match = MATCH_EQUAL; + bool execute = false; + bool store = false; + bool load = false; +}; + +class mcontrol_t : public mcontrol_common_t { +public: + virtual reg_t tdata1_read(const processor_t * const proc) const noexcept override; + virtual void tdata1_write(processor_t * const proc, const reg_t val, const bool allow_chain) noexcept override; +}; + +class mcontrol6_t : public mcontrol_common_t { +public: + virtual reg_t tdata1_read(const processor_t * const proc) const noexcept override; + virtual void tdata1_write(processor_t * const proc, const reg_t val, const bool allow_chain) noexcept override; +}; + +class icount_t : public trigger_t { +public: + virtual reg_t tdata1_read(const processor_t * const proc) const noexcept override; + virtual void tdata1_write(processor_t * const proc, const reg_t val, const bool allow_chain) noexcept override; + + bool get_dmode() const override { return dmode; } + virtual action_t get_action() const override { return action; } + virtual bool icount_check_needed() const override { return count > 0 || pending; } + virtual void stash_read_values() override; + + virtual std::optional detect_icount_match(processor_t * const proc) noexcept override; + +private: + bool dmode = false; + bool hit = false; + unsigned count = 1, count_read_value = 1; + bool pending = false, pending_read_value = false; + action_t action = (action_t)0; +}; + +class module_t { +public: + module_t(unsigned count); + ~module_t(); + + reg_t tdata1_read(unsigned index) const noexcept; + bool tdata1_write(unsigned index, const reg_t val) noexcept; + reg_t tdata2_read(unsigned index) const noexcept; + bool tdata2_write(unsigned index, const reg_t val) noexcept; + reg_t tdata3_read(unsigned index) const noexcept; + bool tdata3_write(unsigned index, const reg_t val) noexcept; + reg_t tinfo_read(unsigned index) const noexcept; + + unsigned count() const { return triggers.size(); } + + std::optional detect_memory_access_match(operation_t operation, reg_t address, std::optional data) noexcept; + std::optional detect_icount_match() noexcept; + std::optional detect_trap_match(const trap_t& t) noexcept; + + processor_t *proc; +private: + std::vector triggers; +}; + +}; + +#endif diff --git a/vendor/riscv/riscv-isa-sim/riscv/v_ext_macros.h b/vendor/riscv/riscv-isa-sim/riscv/v_ext_macros.h new file mode 100644 index 000000000..e00b0c0a3 --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/v_ext_macros.h @@ -0,0 +1,2073 @@ +// See LICENSE for license details. + +#ifndef _RISCV_V_EXT_MACROS_H +#define _RISCV_V_EXT_MACROS_H + +#include "vector_unit.h" + +// +// vector: masking skip helper +// +#define VI_MASK_VARS \ + const int midx = i / 64; \ + const int mpos = i % 64; + +#define VI_LOOP_ELEMENT_SKIP(BODY) \ + VI_MASK_VARS \ + if (insn.v_vm() == 0) { \ + BODY; \ + bool skip = ((P.VU.elt(0, midx) >> mpos) & 0x1) == 0; \ + if (skip) { \ + continue; \ + } \ + } + +#define VI_ELEMENT_SKIP \ + if (i >= vl) { \ + continue; \ + } else if (i < P.VU.vstart->read()) { \ + continue; \ + } else { \ + VI_LOOP_ELEMENT_SKIP(); \ + } + +// +// vector: operation and register acccess check helper +// +static inline bool is_overlapped(const int astart, int asize, + const int bstart, int bsize) +{ + asize = asize == 0 ? 1 : asize; + bsize = bsize == 0 ? 1 : bsize; + + const int aend = astart + asize; + const int bend = bstart + bsize; + + return std::max(aend, bend) - std::min(astart, bstart) < asize + bsize; +} + +static inline bool is_overlapped_widen(const int astart, int asize, + const int bstart, int bsize) +{ + asize = asize == 0 ? 1 : asize; + bsize = bsize == 0 ? 1 : bsize; + + const int aend = astart + asize; + const int bend = bstart + bsize; + + if (astart < bstart && + is_overlapped(astart, asize, bstart, bsize) && + !is_overlapped(astart, asize, bstart + bsize, bsize)) { + return false; + } else { + return std::max(aend, bend) - std::min(astart, bstart) < asize + bsize; + } +} + +static inline bool is_aligned(const unsigned val, const unsigned pos) +{ + return pos ? (val & (pos - 1)) == 0 : true; +} + +#define VI_NARROW_CHECK_COMMON \ + require_vector(true); \ + require(P.VU.vflmul <= 4); \ + require(P.VU.vsew * 2 <= P.VU.ELEN); \ + require_align(insn.rs2(), P.VU.vflmul * 2); \ + require_align(insn.rd(), P.VU.vflmul); \ + require_vm; \ + +#define VI_WIDE_CHECK_COMMON \ + require_vector(true); \ + require(P.VU.vflmul <= 4); \ + require(P.VU.vsew * 2 <= P.VU.ELEN); \ + require_align(insn.rd(), P.VU.vflmul * 2); \ + require_vm; \ + +#define VI_CHECK_ST_INDEX(elt_width) \ + require_vector(false); \ + require(elt_width <= P.VU.ELEN); \ + float vemul = ((float)elt_width / P.VU.vsew * P.VU.vflmul); \ + require(vemul >= 0.125 && vemul <= 8); \ + reg_t UNUSED emul = vemul < 1 ? 1 : vemul; \ + reg_t flmul = P.VU.vflmul < 1 ? 1 : P.VU.vflmul; \ + require_align(insn.rd(), P.VU.vflmul); \ + require_align(insn.rs2(), vemul); \ + require((nf * flmul) <= (NVPR / 4) && \ + (insn.rd() + nf * flmul) <= NVPR); \ + +#define VI_CHECK_LD_INDEX(elt_width) \ + VI_CHECK_ST_INDEX(elt_width); \ + for (reg_t idx = 0; idx < nf; ++idx) { \ + reg_t flmul = P.VU.vflmul < 1 ? 1 : P.VU.vflmul; \ + reg_t seg_vd = insn.rd() + flmul * idx; \ + if (elt_width > P.VU.vsew) { \ + if (seg_vd != insn.rs2()) \ + require_noover(seg_vd, P.VU.vflmul, insn.rs2(), vemul); \ + } else if (elt_width < P.VU.vsew) { \ + if (vemul < 1) { \ + require_noover(seg_vd, P.VU.vflmul, insn.rs2(), vemul); \ + } else { \ + require_noover_widen(seg_vd, P.VU.vflmul, insn.rs2(), vemul); \ + } \ + } \ + if (nf >= 2) { \ + require_noover(seg_vd, P.VU.vflmul, insn.rs2(), vemul); \ + } \ + } \ + require_vm; \ + +#define VI_CHECK_MSS(is_vs1) \ + if (insn.rd() != insn.rs2()) \ + require_noover(insn.rd(), 1, insn.rs2(), P.VU.vflmul); \ + require_align(insn.rs2(), P.VU.vflmul); \ + if (is_vs1) { \ + if (insn.rd() != insn.rs1()) \ + require_noover(insn.rd(), 1, insn.rs1(), P.VU.vflmul); \ + require_align(insn.rs1(), P.VU.vflmul); \ + } \ + +#define VI_CHECK_SSS(is_vs1) \ + require_vm; \ + if (P.VU.vflmul > 1) { \ + require_align(insn.rd(), P.VU.vflmul); \ + require_align(insn.rs2(), P.VU.vflmul); \ + if (is_vs1) { \ + require_align(insn.rs1(), P.VU.vflmul); \ + } \ + } + +#define VI_CHECK_STORE(elt_width, is_mask_ldst) \ + require_vector(false); \ + reg_t veew = is_mask_ldst ? 1 : sizeof(elt_width##_t) * 8; \ + float vemul = is_mask_ldst ? 1 : ((float)veew / P.VU.vsew * P.VU.vflmul); \ + reg_t emul = vemul < 1 ? 1 : vemul; \ + require(vemul >= 0.125 && vemul <= 8); \ + require_align(insn.rd(), vemul); \ + require((nf * emul) <= (NVPR / 4) && \ + (insn.rd() + nf * emul) <= NVPR); \ + require(veew <= P.VU.ELEN); \ + +#define VI_CHECK_LOAD(elt_width, is_mask_ldst) \ + VI_CHECK_STORE(elt_width, is_mask_ldst); \ + require_vm; \ + +#define VI_CHECK_DSS(is_vs1) \ + VI_WIDE_CHECK_COMMON; \ + require_align(insn.rs2(), P.VU.vflmul); \ + if (P.VU.vflmul < 1) { \ + require_noover(insn.rd(), P.VU.vflmul * 2, insn.rs2(), P.VU.vflmul); \ + } else { \ + require_noover_widen(insn.rd(), P.VU.vflmul * 2, insn.rs2(), P.VU.vflmul); \ + } \ + if (is_vs1) { \ + require_align(insn.rs1(), P.VU.vflmul); \ + if (P.VU.vflmul < 1) { \ + require_noover(insn.rd(), P.VU.vflmul * 2, insn.rs1(), P.VU.vflmul); \ + } else { \ + require_noover_widen(insn.rd(), P.VU.vflmul * 2, insn.rs1(), P.VU.vflmul); \ + } \ + } + +#define VI_CHECK_DDS(is_rs) \ + VI_WIDE_CHECK_COMMON; \ + require_align(insn.rs2(), P.VU.vflmul * 2); \ + if (is_rs) { \ + require_align(insn.rs1(), P.VU.vflmul); \ + if (P.VU.vflmul < 1) { \ + require_noover(insn.rd(), P.VU.vflmul * 2, insn.rs1(), P.VU.vflmul); \ + } else { \ + require_noover_widen(insn.rd(), P.VU.vflmul * 2, insn.rs1(), P.VU.vflmul); \ + } \ + } + +#define VI_CHECK_SDS(is_vs1) \ + VI_NARROW_CHECK_COMMON; \ + if (insn.rd() != insn.rs2()) \ + require_noover(insn.rd(), P.VU.vflmul, insn.rs2(), P.VU.vflmul * 2); \ + if (is_vs1) \ + require_align(insn.rs1(), P.VU.vflmul); \ + +#define VI_CHECK_REDUCTION(is_wide) \ + require_vector(true); \ + if (is_wide) { \ + require(P.VU.vsew * 2 <= P.VU.ELEN); \ + } \ + require_align(insn.rs2(), P.VU.vflmul); \ + require(P.VU.vstart->read() == 0); \ + +#define VI_CHECK_SLIDE(is_over) \ + require_align(insn.rs2(), P.VU.vflmul); \ + require_align(insn.rd(), P.VU.vflmul); \ + require_vm; \ + if (is_over) \ + require(insn.rd() != insn.rs2()); \ + +// +// vector: loop header and end helper +// +#define VI_GENERAL_LOOP_BASE \ + require(P.VU.vsew >= e8 && P.VU.vsew <= e64); \ + require_vector(true); \ + reg_t vl = P.VU.vl->read(); \ + reg_t UNUSED sew = P.VU.vsew; \ + reg_t rd_num = insn.rd(); \ + reg_t UNUSED rs1_num = insn.rs1(); \ + reg_t rs2_num = insn.rs2(); \ + for (reg_t i = P.VU.vstart->read(); i < vl; ++i) { + +#define VI_LOOP_BASE \ + VI_GENERAL_LOOP_BASE \ + VI_LOOP_ELEMENT_SKIP(); + +#define VI_LOOP_END \ + } \ + P.VU.vstart->write(0); + +#define VI_LOOP_REDUCTION_END(x) \ + } \ + if (vl > 0) { \ + vd_0_des = vd_0_res; \ + } \ + P.VU.vstart->write(0); + +#define VI_LOOP_CARRY_BASE \ + VI_GENERAL_LOOP_BASE \ + VI_MASK_VARS \ + auto v0 = P.VU.elt(0, midx); \ + const uint64_t mmask = UINT64_C(1) << mpos; \ + const uint128_t op_mask = (UINT64_MAX >> (64 - sew)); \ + uint64_t carry = insn.v_vm() == 0 ? (v0 >> mpos) & 0x1 : 0; \ + uint128_t res = 0; \ + auto &vd = P.VU.elt(rd_num, midx, true); + +#define VI_LOOP_CARRY_END \ + vd = (vd & ~mmask) | (((res) << mpos) & mmask); \ + } \ + P.VU.vstart->write(0); +#define VI_LOOP_WITH_CARRY_BASE \ + VI_GENERAL_LOOP_BASE \ + VI_MASK_VARS \ + auto &v0 = P.VU.elt(0, midx); \ + const uint128_t op_mask = (UINT64_MAX >> (64 - sew)); \ + uint64_t carry = (v0 >> mpos) & 0x1; + +#define VI_LOOP_CMP_BASE \ + require(P.VU.vsew >= e8 && P.VU.vsew <= e64); \ + require_vector(true); \ + reg_t vl = P.VU.vl->read(); \ + reg_t sew = P.VU.vsew; \ + reg_t UNUSED rd_num = insn.rd(); \ + reg_t UNUSED rs1_num = insn.rs1(); \ + reg_t rs2_num = insn.rs2(); \ + for (reg_t i = P.VU.vstart->read(); i < vl; ++i) { \ + VI_LOOP_ELEMENT_SKIP(); \ + uint64_t mmask = UINT64_C(1) << mpos; \ + uint64_t &vdi = P.VU.elt(insn.rd(), midx, true); \ + uint64_t res = 0; + +#define VI_LOOP_CMP_END \ + vdi = (vdi & ~mmask) | (((res) << mpos) & mmask); \ + } \ + P.VU.vstart->write(0); + +#define VI_LOOP_MASK(op) \ + require(P.VU.vsew <= e64); \ + require_vector(true); \ + reg_t vl = P.VU.vl->read(); \ + for (reg_t i = P.VU.vstart->read(); i < vl; ++i) { \ + int midx = i / 64; \ + int mpos = i % 64; \ + uint64_t mmask = UINT64_C(1) << mpos; \ + uint64_t vs2 = P.VU.elt(insn.rs2(), midx); \ + uint64_t vs1 = P.VU.elt(insn.rs1(), midx); \ + uint64_t &res = P.VU.elt(insn.rd(), midx, true); \ + res = (res & ~mmask) | ((op) & (1ULL << mpos)); \ + } \ + P.VU.vstart->write(0); + +#define VI_LOOP_NSHIFT_BASE \ + VI_GENERAL_LOOP_BASE; \ + VI_LOOP_ELEMENT_SKIP({ \ + require(!(insn.rd() == 0 && P.VU.vflmul > 1)); \ + }); + +#define INT_ROUNDING(result, xrm, gb) \ + do { \ + const uint64_t lsb = 1UL << (gb); \ + const uint64_t lsb_half = lsb >> 1; \ + switch (xrm) { \ + case VRM::RNU: \ + result += lsb_half; \ + break; \ + case VRM::RNE: \ + if ((result & lsb_half) && ((result & (lsb_half - 1)) || (result & lsb))) \ + result += lsb; \ + break; \ + case VRM::RDN: \ + break; \ + case VRM::ROD: \ + if (result & (lsb - 1)) \ + result |= lsb; \ + break; \ + case VRM::INVALID_RM: \ + assert(true); \ + } \ + } while (0) + +// +// vector: integer and masking operand access helper +// +#define VXI_PARAMS(x) \ + type_sew_t::type &vd = P.VU.elt::type>(rd_num, i, true); \ + type_sew_t::type vs1 = P.VU.elt::type>(rs1_num, i); \ + type_sew_t::type vs2 = P.VU.elt::type>(rs2_num, i); \ + type_sew_t::type rs1 = (type_sew_t::type)RS1; \ + type_sew_t::type simm5 = (type_sew_t::type)insn.v_simm5(); + +#define VV_U_PARAMS(x) \ + type_usew_t::type &vd = P.VU.elt::type>(rd_num, i, true); \ + type_usew_t::type vs1 = P.VU.elt::type>(rs1_num, i); \ + type_usew_t::type vs2 = P.VU.elt::type>(rs2_num, i); + +#define VX_U_PARAMS(x) \ + type_usew_t::type &vd = P.VU.elt::type>(rd_num, i, true); \ + type_usew_t::type rs1 = (type_usew_t::type)RS1; \ + type_usew_t::type vs2 = P.VU.elt::type>(rs2_num, i); + +#define VI_U_PARAMS(x) \ + type_usew_t::type &vd = P.VU.elt::type>(rd_num, i, true); \ + type_usew_t::type UNUSED zimm5 = (type_usew_t::type)insn.v_zimm5(); \ + type_usew_t::type vs2 = P.VU.elt::type>(rs2_num, i); + +#define VV_PARAMS(x) \ + type_sew_t::type UNUSED &vd = P.VU.elt::type>(rd_num, i, true); \ + type_sew_t::type vs1 = P.VU.elt::type>(rs1_num, i); \ + type_sew_t::type UNUSED vs2 = P.VU.elt::type>(rs2_num, i); + +#define VX_PARAMS(x) \ + type_sew_t::type UNUSED &vd = P.VU.elt::type>(rd_num, i, true); \ + type_sew_t::type rs1 = (type_sew_t::type)RS1; \ + type_sew_t::type UNUSED vs2 = P.VU.elt::type>(rs2_num, i); + +#define VI_PARAMS(x) \ + type_sew_t::type &vd = P.VU.elt::type>(rd_num, i, true); \ + type_sew_t::type simm5 = (type_sew_t::type)insn.v_simm5(); \ + type_sew_t::type UNUSED vs2 = P.VU.elt::type>(rs2_num, i); + +#define XV_PARAMS(x) \ + type_sew_t::type &vd = P.VU.elt::type>(rd_num, i, true); \ + type_usew_t::type vs2 = P.VU.elt::type>(rs2_num, RS1); + +#define VV_SU_PARAMS(x) \ + type_sew_t::type &vd = P.VU.elt::type>(rd_num, i, true); \ + type_usew_t::type vs1 = P.VU.elt::type>(rs1_num, i); \ + type_sew_t::type vs2 = P.VU.elt::type>(rs2_num, i); + +#define VX_SU_PARAMS(x) \ + type_sew_t::type &vd = P.VU.elt::type>(rd_num, i, true); \ + type_usew_t::type rs1 = (type_usew_t::type)RS1; \ + type_sew_t::type vs2 = P.VU.elt::type>(rs2_num, i); + +#define VV_UCMP_PARAMS(x) \ + type_usew_t::type vs1 = P.VU.elt::type>(rs1_num, i); \ + type_usew_t::type vs2 = P.VU.elt::type>(rs2_num, i); + +#define VX_UCMP_PARAMS(x) \ + type_usew_t::type rs1 = (type_usew_t::type)RS1; \ + type_usew_t::type vs2 = P.VU.elt::type>(rs2_num, i); + +#define VI_UCMP_PARAMS(x) \ + type_usew_t::type vs2 = P.VU.elt::type>(rs2_num, i); + +#define VV_CMP_PARAMS(x) \ + type_sew_t::type vs1 = P.VU.elt::type>(rs1_num, i); \ + type_sew_t::type vs2 = P.VU.elt::type>(rs2_num, i); + +#define VX_CMP_PARAMS(x) \ + type_sew_t::type rs1 = (type_sew_t::type)RS1; \ + type_sew_t::type vs2 = P.VU.elt::type>(rs2_num, i); + +#define VI_CMP_PARAMS(x) \ + type_sew_t::type simm5 = (type_sew_t::type)insn.v_simm5(); \ + type_sew_t::type vs2 = P.VU.elt::type>(rs2_num, i); + +#define VI_XI_SLIDEDOWN_PARAMS(x, off) \ + auto &vd = P.VU.elt::type>(rd_num, i, true); \ + auto vs2 = P.VU.elt::type>(rs2_num, i + off); + +#define VI_XI_SLIDEUP_PARAMS(x, offset) \ + auto &vd = P.VU.elt::type>(rd_num, i, true); \ + auto vs2 = P.VU.elt::type>(rs2_num, i - offset); + +#define VI_NARROW_PARAMS(sew1, sew2) \ + auto &vd = P.VU.elt::type>(rd_num, i, true); \ + auto UNUSED vs2_u = P.VU.elt::type>(rs2_num, i); \ + auto UNUSED vs2 = P.VU.elt::type>(rs2_num, i); \ + auto zimm5 = (type_usew_t::type)insn.v_zimm5(); + +#define VX_NARROW_PARAMS(sew1, sew2) \ + auto &vd = P.VU.elt::type>(rd_num, i, true); \ + auto UNUSED vs2_u = P.VU.elt::type>(rs2_num, i); \ + auto UNUSED vs2 = P.VU.elt::type>(rs2_num, i); \ + auto rs1 = (type_sew_t::type)RS1; + +#define VV_NARROW_PARAMS(sew1, sew2) \ + auto &vd = P.VU.elt::type>(rd_num, i, true); \ + auto UNUSED vs2_u = P.VU.elt::type>(rs2_num, i); \ + auto UNUSED vs2 = P.VU.elt::type>(rs2_num, i); \ + auto vs1 = P.VU.elt::type>(rs1_num, i); + +#define XI_CARRY_PARAMS(x) \ + auto vs2 = P.VU.elt::type>(rs2_num, i); \ + auto UNUSED rs1 = (type_sew_t::type)RS1; \ + auto UNUSED simm5 = (type_sew_t::type)insn.v_simm5(); \ + +#define VV_CARRY_PARAMS(x) \ + auto vs2 = P.VU.elt::type>(rs2_num, i); \ + auto vs1 = P.VU.elt::type>(rs1_num, i); \ + +#define XI_WITH_CARRY_PARAMS(x) \ + auto vs2 = P.VU.elt::type>(rs2_num, i); \ + auto UNUSED rs1 = (type_sew_t::type)RS1; \ + auto UNUSED simm5 = (type_sew_t::type)insn.v_simm5(); \ + auto &vd = P.VU.elt::type>(rd_num, i, true); + +#define VV_WITH_CARRY_PARAMS(x) \ + auto vs2 = P.VU.elt::type>(rs2_num, i); \ + auto vs1 = P.VU.elt::type>(rs1_num, i); \ + auto &vd = P.VU.elt::type>(rd_num, i, true); + +#define VFP_V_PARAMS(width) \ + float##width##_t &vd = P.VU.elt(rd_num, i, true); \ + float##width##_t vs2 = P.VU.elt(rs2_num, i); + +#define VFP_VV_CMP_PARAMS(width) \ + float##width##_t vs1 = P.VU.elt(rs1_num, i); \ + float##width##_t vs2 = P.VU.elt(rs2_num, i); + +#define VFP_VV_PARAMS(width) \ + float##width##_t &vd = P.VU.elt(rd_num, i, true); \ + VFP_VV_CMP_PARAMS(width) + +#define VFP_VF_CMP_PARAMS(width) \ + float##width##_t rs1 = f##width(READ_FREG(rs1_num)); \ + float##width##_t vs2 = P.VU.elt(rs2_num, i); + +#define VFP_VF_PARAMS(width) \ + float##width##_t &vd = P.VU.elt(rd_num, i, true); \ + VFP_VF_CMP_PARAMS(width) + +#define CVT_FP_TO_FP_PARAMS(from_width, to_width) \ + auto vs2 = P.VU.elt(rs2_num, i); \ + auto &vd = P.VU.elt(rd_num, i, true); + +#define CVT_INT_TO_FP_PARAMS(from_width, to_width, sign) \ + auto vs2 = P.VU.elt(rs2_num, i); \ + auto &vd = P.VU.elt(rd_num, i, true); + +#define CVT_FP_TO_INT_PARAMS(from_width, to_width, sign) \ + auto vs2 = P.VU.elt(rs2_num, i); \ + auto &vd = P.VU.elt(rd_num, i, true); + +// +// vector: integer and masking operation loop +// + +#define INSNS_BASE(PARAMS, BODY) \ + if (sew == e8) { \ + PARAMS(e8); \ + BODY; \ + } else if (sew == e16) { \ + PARAMS(e16); \ + BODY; \ + } else if (sew == e32) { \ + PARAMS(e32); \ + BODY; \ + } else if (sew == e64) { \ + PARAMS(e64); \ + BODY; \ + } + +// comparision result to masking register +#define VI_LOOP_CMP_BODY(PARAMS, BODY) \ + VI_LOOP_CMP_BASE \ + INSNS_BASE(PARAMS, BODY) \ + VI_LOOP_CMP_END + +#define VI_VV_LOOP_CMP(BODY) \ + VI_CHECK_MSS(true); \ + VI_LOOP_CMP_BODY(VV_CMP_PARAMS, BODY) + +#define VI_VX_LOOP_CMP(BODY) \ + VI_CHECK_MSS(false); \ + VI_LOOP_CMP_BODY(VX_CMP_PARAMS, BODY) + +#define VI_VI_LOOP_CMP(BODY) \ + VI_CHECK_MSS(false); \ + VI_LOOP_CMP_BODY(VI_CMP_PARAMS, BODY) + +#define VI_VV_ULOOP_CMP(BODY) \ + VI_CHECK_MSS(true); \ + VI_LOOP_CMP_BODY(VV_UCMP_PARAMS, BODY) + +#define VI_VX_ULOOP_CMP(BODY) \ + VI_CHECK_MSS(false); \ + VI_LOOP_CMP_BODY(VX_UCMP_PARAMS, BODY) + +#define VI_VI_ULOOP_CMP(BODY) \ + VI_CHECK_MSS(false); \ + VI_LOOP_CMP_BODY(VI_UCMP_PARAMS, BODY) + +// merge and copy loop +#define VI_MERGE_VARS \ + VI_MASK_VARS \ + bool UNUSED use_first = (P.VU.elt(0, midx) >> mpos) & 0x1; + +#define VI_MERGE_LOOP_BASE \ + VI_GENERAL_LOOP_BASE \ + VI_MERGE_VARS + +#define VI_VV_MERGE_LOOP(BODY) \ + VI_CHECK_SSS(true); \ + VI_MERGE_LOOP_BASE \ + if (sew == e8) { \ + VV_PARAMS(e8); \ + BODY; \ + } else if (sew == e16) { \ + VV_PARAMS(e16); \ + BODY; \ + } else if (sew == e32) { \ + VV_PARAMS(e32); \ + BODY; \ + } else if (sew == e64) { \ + VV_PARAMS(e64); \ + BODY; \ + } \ + VI_LOOP_END + +#define VI_VX_MERGE_LOOP(BODY) \ + VI_CHECK_SSS(false); \ + VI_MERGE_LOOP_BASE \ + if (sew == e8) { \ + VX_PARAMS(e8); \ + BODY; \ + } else if (sew == e16) { \ + VX_PARAMS(e16); \ + BODY; \ + } else if (sew == e32) { \ + VX_PARAMS(e32); \ + BODY; \ + } else if (sew == e64) { \ + VX_PARAMS(e64); \ + BODY; \ + } \ + VI_LOOP_END + +#define VI_VI_MERGE_LOOP(BODY) \ + VI_CHECK_SSS(false); \ + VI_MERGE_LOOP_BASE \ + if (sew == e8) { \ + VI_PARAMS(e8); \ + BODY; \ + } else if (sew == e16) { \ + VI_PARAMS(e16); \ + BODY; \ + } else if (sew == e32) { \ + VI_PARAMS(e32); \ + BODY; \ + } else if (sew == e64) { \ + VI_PARAMS(e64); \ + BODY; \ + } \ + VI_LOOP_END + +#define VI_VF_MERGE_LOOP(BODY) \ + VI_CHECK_SSS(false); \ + VI_VFP_COMMON \ + for (reg_t i = P.VU.vstart->read(); i < vl; ++i) { \ + VI_MERGE_VARS \ + if (P.VU.vsew == e16) { \ + VFP_VF_PARAMS(16); \ + BODY; \ + } else if (P.VU.vsew == e32) { \ + VFP_VF_PARAMS(32); \ + BODY; \ + } else if (P.VU.vsew == e64) { \ + VFP_VF_PARAMS(64); \ + BODY; \ + } \ + VI_LOOP_END + +// reduction loop - signed +#define VI_LOOP_REDUCTION_BASE(x) \ + require(x >= e8 && x <= e64); \ + reg_t vl = P.VU.vl->read(); \ + reg_t rd_num = insn.rd(); \ + reg_t rs1_num = insn.rs1(); \ + reg_t rs2_num = insn.rs2(); \ + auto &vd_0_des = P.VU.elt::type>(rd_num, 0, true); \ + auto vd_0_res = P.VU.elt::type>(rs1_num, 0); \ + for (reg_t i = P.VU.vstart->read(); i < vl; ++i) { \ + VI_LOOP_ELEMENT_SKIP(); \ + auto vs2 = P.VU.elt::type>(rs2_num, i); \ + +#define REDUCTION_LOOP(x, BODY) \ + VI_LOOP_REDUCTION_BASE(x) \ + BODY; \ + VI_LOOP_REDUCTION_END(x) + +#define VI_VV_LOOP_REDUCTION(BODY) \ + VI_CHECK_REDUCTION(false); \ + reg_t sew = P.VU.vsew; \ + if (sew == e8) { \ + REDUCTION_LOOP(e8, BODY) \ + } else if (sew == e16) { \ + REDUCTION_LOOP(e16, BODY) \ + } else if (sew == e32) { \ + REDUCTION_LOOP(e32, BODY) \ + } else if (sew == e64) { \ + REDUCTION_LOOP(e64, BODY) \ + } + +// reduction loop - unsigned +#define VI_ULOOP_REDUCTION_BASE(x) \ + require(x >= e8 && x <= e64); \ + reg_t vl = P.VU.vl->read(); \ + reg_t rd_num = insn.rd(); \ + reg_t rs1_num = insn.rs1(); \ + reg_t rs2_num = insn.rs2(); \ + auto &vd_0_des = P.VU.elt::type>(rd_num, 0, true); \ + auto vd_0_res = P.VU.elt::type>(rs1_num, 0); \ + for (reg_t i = P.VU.vstart->read(); i < vl; ++i) { \ + VI_LOOP_ELEMENT_SKIP(); \ + auto vs2 = P.VU.elt::type>(rs2_num, i); + +#define REDUCTION_ULOOP(x, BODY) \ + VI_ULOOP_REDUCTION_BASE(x) \ + BODY; \ + VI_LOOP_REDUCTION_END(x) + +#define VI_VV_ULOOP_REDUCTION(BODY) \ + VI_CHECK_REDUCTION(false); \ + reg_t sew = P.VU.vsew; \ + if (sew == e8) { \ + REDUCTION_ULOOP(e8, BODY) \ + } else if (sew == e16) { \ + REDUCTION_ULOOP(e16, BODY) \ + } else if (sew == e32) { \ + REDUCTION_ULOOP(e32, BODY) \ + } else if (sew == e64) { \ + REDUCTION_ULOOP(e64, BODY) \ + } + +// genearl VXI signed/unsigned loop +#define VI_VV_ULOOP(BODY) \ + VI_CHECK_SSS(true) \ + VI_LOOP_BASE \ + if (sew == e8) { \ + VV_U_PARAMS(e8); \ + BODY; \ + } else if (sew == e16) { \ + VV_U_PARAMS(e16); \ + BODY; \ + } else if (sew == e32) { \ + VV_U_PARAMS(e32); \ + BODY; \ + } else if (sew == e64) { \ + VV_U_PARAMS(e64); \ + BODY; \ + } \ + VI_LOOP_END + +#define VI_VV_LOOP(BODY) \ + VI_CHECK_SSS(true) \ + VI_LOOP_BASE \ + if (sew == e8) { \ + VV_PARAMS(e8); \ + BODY; \ + } else if (sew == e16) { \ + VV_PARAMS(e16); \ + BODY; \ + } else if (sew == e32) { \ + VV_PARAMS(e32); \ + BODY; \ + } else if (sew == e64) { \ + VV_PARAMS(e64); \ + BODY; \ + } \ + VI_LOOP_END + +#define VI_VX_ULOOP(BODY) \ + VI_CHECK_SSS(false) \ + VI_LOOP_BASE \ + if (sew == e8) { \ + VX_U_PARAMS(e8); \ + BODY; \ + } else if (sew == e16) { \ + VX_U_PARAMS(e16); \ + BODY; \ + } else if (sew == e32) { \ + VX_U_PARAMS(e32); \ + BODY; \ + } else if (sew == e64) { \ + VX_U_PARAMS(e64); \ + BODY; \ + } \ + VI_LOOP_END + +#define VI_VX_LOOP(BODY) \ + VI_CHECK_SSS(false) \ + VI_LOOP_BASE \ + if (sew == e8) { \ + VX_PARAMS(e8); \ + BODY; \ + } else if (sew == e16) { \ + VX_PARAMS(e16); \ + BODY; \ + } else if (sew == e32) { \ + VX_PARAMS(e32); \ + BODY; \ + } else if (sew == e64) { \ + VX_PARAMS(e64); \ + BODY; \ + } \ + VI_LOOP_END + +#define VI_VI_ULOOP(BODY) \ + VI_CHECK_SSS(false) \ + VI_LOOP_BASE \ + if (sew == e8) { \ + VI_U_PARAMS(e8); \ + BODY; \ + } else if (sew == e16) { \ + VI_U_PARAMS(e16); \ + BODY; \ + } else if (sew == e32) { \ + VI_U_PARAMS(e32); \ + BODY; \ + } else if (sew == e64) { \ + VI_U_PARAMS(e64); \ + BODY; \ + } \ + VI_LOOP_END + +#define VI_VI_LOOP(BODY) \ + VI_CHECK_SSS(false) \ + VI_LOOP_BASE \ + if (sew == e8) { \ + VI_PARAMS(e8); \ + BODY; \ + } else if (sew == e16) { \ + VI_PARAMS(e16); \ + BODY; \ + } else if (sew == e32) { \ + VI_PARAMS(e32); \ + BODY; \ + } else if (sew == e64) { \ + VI_PARAMS(e64); \ + BODY; \ + } \ + VI_LOOP_END + +// signed unsigned operation loop (e.g. mulhsu) +#define VI_VV_SU_LOOP(BODY) \ + VI_CHECK_SSS(true) \ + VI_LOOP_BASE \ + if (sew == e8) { \ + VV_SU_PARAMS(e8); \ + BODY; \ + } else if (sew == e16) { \ + VV_SU_PARAMS(e16); \ + BODY; \ + } else if (sew == e32) { \ + VV_SU_PARAMS(e32); \ + BODY; \ + } else if (sew == e64) { \ + VV_SU_PARAMS(e64); \ + BODY; \ + } \ + VI_LOOP_END + +#define VI_VX_SU_LOOP(BODY) \ + VI_CHECK_SSS(false) \ + VI_LOOP_BASE \ + if (sew == e8) { \ + VX_SU_PARAMS(e8); \ + BODY; \ + } else if (sew == e16) { \ + VX_SU_PARAMS(e16); \ + BODY; \ + } else if (sew == e32) { \ + VX_SU_PARAMS(e32); \ + BODY; \ + } else if (sew == e64) { \ + VX_SU_PARAMS(e64); \ + BODY; \ + } \ + VI_LOOP_END + +// narrow operation loop +#define VI_VV_LOOP_NARROW(BODY) \ + VI_CHECK_SDS(true); \ + VI_LOOP_BASE \ + if (sew == e8) { \ + VV_NARROW_PARAMS(e8, e16) \ + BODY; \ + } else if (sew == e16) { \ + VV_NARROW_PARAMS(e16, e32) \ + BODY; \ + } else if (sew == e32) { \ + VV_NARROW_PARAMS(e32, e64) \ + BODY; \ + } \ + VI_LOOP_END + +#define VI_VX_LOOP_NARROW(BODY) \ + VI_CHECK_SDS(false); \ + VI_LOOP_BASE \ + if (sew == e8) { \ + VX_NARROW_PARAMS(e8, e16) \ + BODY; \ + } else if (sew == e16) { \ + VX_NARROW_PARAMS(e16, e32) \ + BODY; \ + } else if (sew == e32) { \ + VX_NARROW_PARAMS(e32, e64) \ + BODY; \ + } \ + VI_LOOP_END + +#define VI_VI_LOOP_NARROW(BODY) \ + VI_CHECK_SDS(false); \ + VI_LOOP_BASE \ + if (sew == e8) { \ + VI_NARROW_PARAMS(e8, e16) \ + BODY; \ + } else if (sew == e16) { \ + VI_NARROW_PARAMS(e16, e32) \ + BODY; \ + } else if (sew == e32) { \ + VI_NARROW_PARAMS(e32, e64) \ + BODY; \ + } \ + VI_LOOP_END + +#define VI_VI_LOOP_NSHIFT(BODY) \ + VI_CHECK_SDS(false); \ + VI_LOOP_NSHIFT_BASE \ + if (sew == e8) { \ + VI_NARROW_PARAMS(e8, e16) \ + BODY; \ + } else if (sew == e16) { \ + VI_NARROW_PARAMS(e16, e32) \ + BODY; \ + } else if (sew == e32) { \ + VI_NARROW_PARAMS(e32, e64) \ + BODY; \ + } \ + VI_LOOP_END + +#define VI_VX_LOOP_NSHIFT(BODY) \ + VI_CHECK_SDS(false); \ + VI_LOOP_NSHIFT_BASE \ + if (sew == e8) { \ + VX_NARROW_PARAMS(e8, e16) \ + BODY; \ + } else if (sew == e16) { \ + VX_NARROW_PARAMS(e16, e32) \ + BODY; \ + } else if (sew == e32) { \ + VX_NARROW_PARAMS(e32, e64) \ + BODY; \ + } \ + VI_LOOP_END + +#define VI_VV_LOOP_NSHIFT(BODY) \ + VI_CHECK_SDS(true); \ + VI_LOOP_NSHIFT_BASE \ + if (sew == e8) { \ + VV_NARROW_PARAMS(e8, e16) \ + BODY; \ + } else if (sew == e16) { \ + VV_NARROW_PARAMS(e16, e32) \ + BODY; \ + } else if (sew == e32) { \ + VV_NARROW_PARAMS(e32, e64) \ + BODY; \ + } \ + VI_LOOP_END + +// widen operation loop +#define VI_VV_LOOP_WIDEN(BODY) \ + VI_LOOP_BASE \ + if (sew == e8) { \ + VV_PARAMS(e8); \ + BODY; \ + } else if (sew == e16) { \ + VV_PARAMS(e16); \ + BODY; \ + } else if (sew == e32) { \ + VV_PARAMS(e32); \ + BODY; \ + } \ + VI_LOOP_END + +#define VI_VX_LOOP_WIDEN(BODY) \ + VI_LOOP_BASE \ + if (sew == e8) { \ + VX_PARAMS(e8); \ + BODY; \ + } else if (sew == e16) { \ + VX_PARAMS(e16); \ + BODY; \ + } else if (sew == e32) { \ + VX_PARAMS(e32); \ + BODY; \ + } \ + VI_LOOP_END + +#define VI_WIDE_OP_AND_ASSIGN(var0, var1, var2, op0, op1, sign) \ + switch (P.VU.vsew) { \ + case e8: { \ + sign##16_t UNUSED vd_w = P.VU.elt(rd_num, i); \ + P.VU.elt(rd_num, i, true) = \ + op1((sign##16_t)(sign##8_t)var0 op0 (sign##16_t)(sign##8_t)var1) + var2; \ + } \ + break; \ + case e16: { \ + sign##32_t UNUSED vd_w = P.VU.elt(rd_num, i); \ + P.VU.elt(rd_num, i, true) = \ + op1((sign##32_t)(sign##16_t)var0 op0 (sign##32_t)(sign##16_t)var1) + var2; \ + } \ + break; \ + default: { \ + sign##64_t UNUSED vd_w = P.VU.elt(rd_num, i); \ + P.VU.elt(rd_num, i, true) = \ + op1((sign##64_t)(sign##32_t)var0 op0 (sign##64_t)(sign##32_t)var1) + var2; \ + } \ + break; \ + } + +#define VI_WIDE_OP_AND_ASSIGN_MIX(var0, var1, var2, op0, op1, sign_d, sign_1, sign_2) \ + switch (P.VU.vsew) { \ + case e8: { \ + sign_d##16_t UNUSED vd_w = P.VU.elt(rd_num, i); \ + P.VU.elt(rd_num, i, true) = \ + op1((sign_1##16_t)(sign_1##8_t)var0 op0 (sign_2##16_t)(sign_2##8_t)var1) + var2; \ + } \ + break; \ + case e16: { \ + sign_d##32_t UNUSED vd_w = P.VU.elt(rd_num, i); \ + P.VU.elt(rd_num, i, true) = \ + op1((sign_1##32_t)(sign_1##16_t)var0 op0 (sign_2##32_t)(sign_2##16_t)var1) + var2; \ + } \ + break; \ + default: { \ + sign_d##64_t UNUSED vd_w = P.VU.elt(rd_num, i); \ + P.VU.elt(rd_num, i, true) = \ + op1((sign_1##64_t)(sign_1##32_t)var0 op0 (sign_2##64_t)(sign_2##32_t)var1) + var2; \ + } \ + break; \ + } + +#define VI_WIDE_WVX_OP(var0, op0, sign) \ + switch (P.VU.vsew) { \ + case e8: { \ + sign##16_t &vd_w = P.VU.elt(rd_num, i, true); \ + sign##16_t vs2_w = P.VU.elt(rs2_num, i); \ + vd_w = vs2_w op0 (sign##16_t)(sign##8_t)var0; \ + } \ + break; \ + case e16: { \ + sign##32_t &vd_w = P.VU.elt(rd_num, i, true); \ + sign##32_t vs2_w = P.VU.elt(rs2_num, i); \ + vd_w = vs2_w op0 (sign##32_t)(sign##16_t)var0; \ + } \ + break; \ + default: { \ + sign##64_t &vd_w = P.VU.elt(rd_num, i, true); \ + sign##64_t vs2_w = P.VU.elt(rs2_num, i); \ + vd_w = vs2_w op0 (sign##64_t)(sign##32_t)var0; \ + } \ + break; \ + } + +// wide reduction loop - signed +#define VI_LOOP_WIDE_REDUCTION_BASE(sew1, sew2) \ + reg_t vl = P.VU.vl->read(); \ + reg_t rd_num = insn.rd(); \ + reg_t rs1_num = insn.rs1(); \ + reg_t rs2_num = insn.rs2(); \ + auto &vd_0_des = P.VU.elt::type>(rd_num, 0, true); \ + auto vd_0_res = P.VU.elt::type>(rs1_num, 0); \ + for (reg_t i = P.VU.vstart->read(); i < vl; ++i) { \ + VI_LOOP_ELEMENT_SKIP(); \ + auto vs2 = P.VU.elt::type>(rs2_num, i); + +#define WIDE_REDUCTION_LOOP(sew1, sew2, BODY) \ + VI_LOOP_WIDE_REDUCTION_BASE(sew1, sew2) \ + BODY; \ + VI_LOOP_REDUCTION_END(sew2) + +#define VI_VV_LOOP_WIDE_REDUCTION(BODY) \ + VI_CHECK_REDUCTION(true); \ + reg_t sew = P.VU.vsew; \ + if (sew == e8) { \ + WIDE_REDUCTION_LOOP(e8, e16, BODY) \ + } else if (sew == e16) { \ + WIDE_REDUCTION_LOOP(e16, e32, BODY) \ + } else if (sew == e32) { \ + WIDE_REDUCTION_LOOP(e32, e64, BODY) \ + } + +// wide reduction loop - unsigned +#define VI_ULOOP_WIDE_REDUCTION_BASE(sew1, sew2) \ + reg_t vl = P.VU.vl->read(); \ + reg_t rd_num = insn.rd(); \ + reg_t rs1_num = insn.rs1(); \ + reg_t rs2_num = insn.rs2(); \ + auto &vd_0_des = P.VU.elt::type>(rd_num, 0, true); \ + auto vd_0_res = P.VU.elt::type>(rs1_num, 0); \ + for (reg_t i = P.VU.vstart->read(); i < vl; ++i) { \ + VI_LOOP_ELEMENT_SKIP(); \ + auto vs2 = P.VU.elt::type>(rs2_num, i); + +#define WIDE_REDUCTION_ULOOP(sew1, sew2, BODY) \ + VI_ULOOP_WIDE_REDUCTION_BASE(sew1, sew2) \ + BODY; \ + VI_LOOP_REDUCTION_END(sew2) + +#define VI_VV_ULOOP_WIDE_REDUCTION(BODY) \ + VI_CHECK_REDUCTION(true); \ + reg_t sew = P.VU.vsew; \ + if (sew == e8) { \ + WIDE_REDUCTION_ULOOP(e8, e16, BODY) \ + } else if (sew == e16) { \ + WIDE_REDUCTION_ULOOP(e16, e32, BODY) \ + } else if (sew == e32) { \ + WIDE_REDUCTION_ULOOP(e32, e64, BODY) \ + } + +// carry/borrow bit loop +#define VI_VV_LOOP_CARRY(BODY) \ + VI_CHECK_MSS(true); \ + VI_LOOP_CARRY_BASE \ + if (sew == e8) { \ + VV_CARRY_PARAMS(e8) \ + BODY; \ + } else if (sew == e16) { \ + VV_CARRY_PARAMS(e16) \ + BODY; \ + } else if (sew == e32) { \ + VV_CARRY_PARAMS(e32) \ + BODY; \ + } else if (sew == e64) { \ + VV_CARRY_PARAMS(e64) \ + BODY; \ + } \ + VI_LOOP_CARRY_END + +#define VI_XI_LOOP_CARRY(BODY) \ + VI_CHECK_MSS(false); \ + VI_LOOP_CARRY_BASE \ + if (sew == e8) { \ + XI_CARRY_PARAMS(e8) \ + BODY; \ + } else if (sew == e16) { \ + XI_CARRY_PARAMS(e16) \ + BODY; \ + } else if (sew == e32) { \ + XI_CARRY_PARAMS(e32) \ + BODY; \ + } else if (sew == e64) { \ + XI_CARRY_PARAMS(e64) \ + BODY; \ + } \ + VI_LOOP_CARRY_END + +#define VI_VV_LOOP_WITH_CARRY(BODY) \ + VI_CHECK_SSS(true); \ + VI_LOOP_WITH_CARRY_BASE \ + if (sew == e8) { \ + VV_WITH_CARRY_PARAMS(e8) \ + BODY; \ + } else if (sew == e16) { \ + VV_WITH_CARRY_PARAMS(e16) \ + BODY; \ + } else if (sew == e32) { \ + VV_WITH_CARRY_PARAMS(e32) \ + BODY; \ + } else if (sew == e64) { \ + VV_WITH_CARRY_PARAMS(e64) \ + BODY; \ + } \ + VI_LOOP_END + +#define VI_XI_LOOP_WITH_CARRY(BODY) \ + VI_CHECK_SSS(false); \ + VI_LOOP_WITH_CARRY_BASE \ + if (sew == e8) { \ + XI_WITH_CARRY_PARAMS(e8) \ + BODY; \ + } else if (sew == e16) { \ + XI_WITH_CARRY_PARAMS(e16) \ + BODY; \ + } else if (sew == e32) { \ + XI_WITH_CARRY_PARAMS(e32) \ + BODY; \ + } else if (sew == e64) { \ + XI_WITH_CARRY_PARAMS(e64) \ + BODY; \ + } \ + VI_LOOP_END + +// average loop +#define VI_VV_LOOP_AVG(op) \ +VRM xrm = p->VU.get_vround_mode(); \ +VI_VV_LOOP({ \ + uint128_t res = ((uint128_t)vs2) op vs1; \ + INT_ROUNDING(res, xrm, 1); \ + vd = res >> 1; \ +}) + +#define VI_VX_LOOP_AVG(op) \ +VRM xrm = p->VU.get_vround_mode(); \ +VI_VX_LOOP({ \ + uint128_t res = ((uint128_t)vs2) op rs1; \ + INT_ROUNDING(res, xrm, 1); \ + vd = res >> 1; \ +}) + +#define VI_VV_ULOOP_AVG(op) \ +VRM xrm = p->VU.get_vround_mode(); \ +VI_VV_ULOOP({ \ + uint128_t res = ((uint128_t)vs2) op vs1; \ + INT_ROUNDING(res, xrm, 1); \ + vd = res >> 1; \ +}) + +#define VI_VX_ULOOP_AVG(op) \ +VRM xrm = p->VU.get_vround_mode(); \ +VI_VX_ULOOP({ \ + uint128_t res = ((uint128_t)vs2) op rs1; \ + INT_ROUNDING(res, xrm, 1); \ + vd = res >> 1; \ +}) + +// +// vector: load/store helper +// +#define VI_STRIP(inx) \ + reg_t vreg_inx = inx; + +#define VI_DUPLICATE_VREG(reg_num, idx_sew) \ +reg_t index[P.VU.vlmax]; \ + for (reg_t i = 0; i < P.VU.vlmax && P.VU.vl->read() != 0; ++i) { \ + switch (idx_sew) { \ + case e8: \ + index[i] = P.VU.elt(reg_num, i); \ + break; \ + case e16: \ + index[i] = P.VU.elt(reg_num, i); \ + break; \ + case e32: \ + index[i] = P.VU.elt(reg_num, i); \ + break; \ + case e64: \ + index[i] = P.VU.elt(reg_num, i); \ + break; \ + } \ +} + +#define VI_LD(stride, offset, elt_width, is_mask_ldst) \ + const reg_t nf = insn.v_nf() + 1; \ + const reg_t vl = is_mask_ldst ? ((P.VU.vl->read() + 7) / 8) : P.VU.vl->read(); \ + const reg_t baseAddr = RS1; \ + const reg_t vd = insn.rd(); \ + VI_CHECK_LOAD(elt_width, is_mask_ldst); \ + for (reg_t i = 0; i < vl; ++i) { \ + VI_ELEMENT_SKIP; \ + VI_STRIP(i); \ + P.VU.vstart->write(i); \ + for (reg_t fn = 0; fn < nf; ++fn) { \ + elt_width##_t val = MMU.load( \ + baseAddr + (stride) + (offset) * sizeof(elt_width##_t)); \ + P.VU.elt(vd + fn * emul, vreg_inx, true) = val; \ + } \ + } \ + P.VU.vstart->write(0); + +#define VI_LD_INDEX(elt_width, is_seg) \ + const reg_t nf = insn.v_nf() + 1; \ + const reg_t vl = P.VU.vl->read(); \ + const reg_t baseAddr = RS1; \ + const reg_t vd = insn.rd(); \ + if (!is_seg) \ + require(nf == 1); \ + VI_CHECK_LD_INDEX(elt_width); \ + VI_DUPLICATE_VREG(insn.rs2(), elt_width); \ + for (reg_t i = 0; i < vl; ++i) { \ + VI_ELEMENT_SKIP; \ + VI_STRIP(i); \ + P.VU.vstart->write(i); \ + for (reg_t fn = 0; fn < nf; ++fn) { \ + switch (P.VU.vsew) { \ + case e8: \ + P.VU.elt(vd + fn * flmul, vreg_inx, true) = \ + MMU.load(baseAddr + index[i] + fn * 1); \ + break; \ + case e16: \ + P.VU.elt(vd + fn * flmul, vreg_inx, true) = \ + MMU.load(baseAddr + index[i] + fn * 2); \ + break; \ + case e32: \ + P.VU.elt(vd + fn * flmul, vreg_inx, true) = \ + MMU.load(baseAddr + index[i] + fn * 4); \ + break; \ + default: \ + P.VU.elt(vd + fn * flmul, vreg_inx, true) = \ + MMU.load(baseAddr + index[i] + fn * 8); \ + break; \ + } \ + } \ + } \ + P.VU.vstart->write(0); + +#define VI_ST(stride, offset, elt_width, is_mask_ldst) \ + const reg_t nf = insn.v_nf() + 1; \ + const reg_t vl = is_mask_ldst ? ((P.VU.vl->read() + 7) / 8) : P.VU.vl->read(); \ + const reg_t baseAddr = RS1; \ + const reg_t vs3 = insn.rd(); \ + VI_CHECK_STORE(elt_width, is_mask_ldst); \ + for (reg_t i = 0; i < vl; ++i) { \ + VI_STRIP(i) \ + VI_ELEMENT_SKIP; \ + P.VU.vstart->write(i); \ + for (reg_t fn = 0; fn < nf; ++fn) { \ + elt_width##_t val = P.VU.elt(vs3 + fn * emul, vreg_inx); \ + MMU.store( \ + baseAddr + (stride) + (offset) * sizeof(elt_width##_t), val); \ + } \ + } \ + P.VU.vstart->write(0); + +#define VI_ST_INDEX(elt_width, is_seg) \ + const reg_t nf = insn.v_nf() + 1; \ + const reg_t vl = P.VU.vl->read(); \ + const reg_t baseAddr = RS1; \ + const reg_t vs3 = insn.rd(); \ + if (!is_seg) \ + require(nf == 1); \ + VI_CHECK_ST_INDEX(elt_width); \ + VI_DUPLICATE_VREG(insn.rs2(), elt_width); \ + for (reg_t i = 0; i < vl; ++i) { \ + VI_STRIP(i) \ + VI_ELEMENT_SKIP; \ + P.VU.vstart->write(i); \ + for (reg_t fn = 0; fn < nf; ++fn) { \ + switch (P.VU.vsew) { \ + case e8: \ + MMU.store(baseAddr + index[i] + fn * 1, \ + P.VU.elt(vs3 + fn * flmul, vreg_inx)); \ + break; \ + case e16: \ + MMU.store(baseAddr + index[i] + fn * 2, \ + P.VU.elt(vs3 + fn * flmul, vreg_inx)); \ + break; \ + case e32: \ + MMU.store(baseAddr + index[i] + fn * 4, \ + P.VU.elt(vs3 + fn * flmul, vreg_inx)); \ + break; \ + default: \ + MMU.store(baseAddr + index[i] + fn * 8, \ + P.VU.elt(vs3 + fn * flmul, vreg_inx)); \ + break; \ + } \ + } \ + } \ + P.VU.vstart->write(0); + +#define VI_LDST_FF(elt_width) \ + const reg_t nf = insn.v_nf() + 1; \ + const reg_t vl = p->VU.vl->read(); \ + const reg_t baseAddr = RS1; \ + const reg_t rd_num = insn.rd(); \ + VI_CHECK_LOAD(elt_width, false); \ + bool early_stop = false; \ + for (reg_t i = p->VU.vstart->read(); i < vl; ++i) { \ + VI_STRIP(i); \ + VI_ELEMENT_SKIP; \ + \ + for (reg_t fn = 0; fn < nf; ++fn) { \ + uint64_t val; \ + try { \ + val = MMU.load( \ + baseAddr + (i * nf + fn) * sizeof(elt_width##_t)); \ + } catch (trap_t& t) { \ + if (i == 0) \ + throw; /* Only take exception on zeroth element */ \ + /* Reduce VL if an exception occurs on a later element */ \ + early_stop = true; \ + P.VU.vl->write_raw(i); \ + break; \ + } \ + p->VU.elt(rd_num + fn * emul, vreg_inx, true) = val; \ + } \ + \ + if (early_stop) { \ + break; \ + } \ + } \ + p->VU.vstart->write(0); + +#define VI_LD_WHOLE(elt_width) \ + require_vector_novtype(true); \ + require(sizeof(elt_width ## _t) * 8 <= P.VU.ELEN); \ + const reg_t baseAddr = RS1; \ + const reg_t vd = insn.rd(); \ + const reg_t len = insn.v_nf() + 1; \ + require_align(vd, len); \ + const reg_t elt_per_reg = P.VU.vlenb / sizeof(elt_width ## _t); \ + const reg_t size = len * elt_per_reg; \ + if (P.VU.vstart->read() < size) { \ + reg_t i = P.VU.vstart->read() / elt_per_reg; \ + reg_t off = P.VU.vstart->read() % elt_per_reg; \ + if (off) { \ + for (reg_t pos = off; pos < elt_per_reg; ++pos) { \ + auto val = MMU.load(baseAddr + \ + P.VU.vstart->read() * sizeof(elt_width ## _t)); \ + P.VU.elt(vd + i, pos, true) = val; \ + P.VU.vstart->write(P.VU.vstart->read() + 1); \ + } \ + ++i; \ + } \ + for (; i < len; ++i) { \ + for (reg_t pos = 0; pos < elt_per_reg; ++pos) { \ + auto val = MMU.load(baseAddr + \ + P.VU.vstart->read() * sizeof(elt_width ## _t)); \ + P.VU.elt(vd + i, pos, true) = val; \ + P.VU.vstart->write(P.VU.vstart->read() + 1); \ + } \ + } \ + } \ + P.VU.vstart->write(0); + +#define VI_ST_WHOLE \ + require_vector_novtype(true); \ + const reg_t baseAddr = RS1; \ + const reg_t vs3 = insn.rd(); \ + const reg_t len = insn.v_nf() + 1; \ + require_align(vs3, len); \ + const reg_t size = len * P.VU.vlenb; \ + \ + if (P.VU.vstart->read() < size) { \ + reg_t i = P.VU.vstart->read() / P.VU.vlenb; \ + reg_t off = P.VU.vstart->read() % P.VU.vlenb; \ + if (off) { \ + for (reg_t pos = off; pos < P.VU.vlenb; ++pos) { \ + auto val = P.VU.elt(vs3 + i, pos); \ + MMU.store(baseAddr + P.VU.vstart->read(), val); \ + P.VU.vstart->write(P.VU.vstart->read() + 1); \ + } \ + i++; \ + } \ + for (; i < len; ++i) { \ + for (reg_t pos = 0; pos < P.VU.vlenb; ++pos) { \ + auto val = P.VU.elt(vs3 + i, pos); \ + MMU.store(baseAddr + P.VU.vstart->read(), val); \ + P.VU.vstart->write(P.VU.vstart->read() + 1); \ + } \ + } \ + } \ + P.VU.vstart->write(0); + +// +// vector: amo +// +#define VI_AMO(op, type, idx_type) \ + require_vector(false); \ + require_align(insn.rd(), P.VU.vflmul); \ + require(P.VU.vsew <= P.get_xlen() && P.VU.vsew >= 32); \ + require_align(insn.rd(), P.VU.vflmul); \ + float vemul = ((float)idx_type / P.VU.vsew * P.VU.vflmul); \ + require(vemul >= 0.125 && vemul <= 8); \ + require_align(insn.rs2(), vemul); \ + if (insn.v_wd()) { \ + require_vm; \ + if (idx_type > P.VU.vsew) { \ + if (insn.rd() != insn.rs2()) \ + require_noover(insn.rd(), P.VU.vflmul, insn.rs2(), vemul); \ + } else if (idx_type < P.VU.vsew) { \ + if (vemul < 1) { \ + require_noover(insn.rd(), P.VU.vflmul, insn.rs2(), vemul); \ + } else { \ + require_noover_widen(insn.rd(), P.VU.vflmul, insn.rs2(), vemul); \ + } \ + } \ + } \ + VI_DUPLICATE_VREG(insn.rs2(), idx_type); \ + const reg_t vl = P.VU.vl->read(); \ + const reg_t baseAddr = RS1; \ + const reg_t vd = insn.rd(); \ + for (reg_t i = P.VU.vstart->read(); i < vl; ++i) { \ + VI_ELEMENT_SKIP; \ + VI_STRIP(i); \ + P.VU.vstart->write(i); \ + switch (P.VU.vsew) { \ + case e32: { \ + auto vs3 = P.VU.elt< type ## 32_t>(vd, vreg_inx); \ + auto val = MMU.amo(baseAddr + index[i], [&](type ## 32_t UNUSED lhs) { op }); \ + if (insn.v_wd()) \ + P.VU.elt< type ## 32_t>(vd, vreg_inx, true) = val; \ + } \ + break; \ + case e64: { \ + auto vs3 = P.VU.elt< type ## 64_t>(vd, vreg_inx); \ + auto val = MMU.amo(baseAddr + index[i], [&](type ## 64_t UNUSED lhs) { op }); \ + if (insn.v_wd()) \ + P.VU.elt< type ## 64_t>(vd, vreg_inx, true) = val; \ + } \ + break; \ + default: \ + require(0); \ + break; \ + } \ + } \ + P.VU.vstart->write(0); + +// vector: sign/unsiged extension +#define VI_VV_EXT(div, type) \ + require(insn.rd() != insn.rs2()); \ + require_vm; \ + reg_t from = P.VU.vsew / div; \ + require(from >= e8 && from <= e64); \ + require(((float)P.VU.vflmul / div) >= 0.125 && ((float)P.VU.vflmul / div) <= 8 ); \ + require_align(insn.rd(), P.VU.vflmul); \ + require_align(insn.rs2(), P.VU.vflmul / div); \ + if ((P.VU.vflmul / div) < 1) { \ + require_noover(insn.rd(), P.VU.vflmul, insn.rs2(), P.VU.vflmul / div); \ + } else { \ + require_noover_widen(insn.rd(), P.VU.vflmul, insn.rs2(), P.VU.vflmul / div); \ + } \ + reg_t pat = (((P.VU.vsew >> 3) << 4) | from >> 3); \ + VI_GENERAL_LOOP_BASE \ + VI_LOOP_ELEMENT_SKIP(); \ + switch (pat) { \ + case 0x21: \ + P.VU.elt(rd_num, i, true) = P.VU.elt(rs2_num, i); \ + break; \ + case 0x41: \ + P.VU.elt(rd_num, i, true) = P.VU.elt(rs2_num, i); \ + break; \ + case 0x81: \ + P.VU.elt(rd_num, i, true) = P.VU.elt(rs2_num, i); \ + break; \ + case 0x42: \ + P.VU.elt(rd_num, i, true) = P.VU.elt(rs2_num, i); \ + break; \ + case 0x82: \ + P.VU.elt(rd_num, i, true) = P.VU.elt(rs2_num, i); \ + break; \ + case 0x84: \ + P.VU.elt(rd_num, i, true) = P.VU.elt(rs2_num, i); \ + break; \ + default: \ + break; \ + } \ + VI_LOOP_END + +// +// vector: vfp helper +// +#define VI_VFP_COMMON \ + require_fp; \ + require((P.VU.vsew == e16 && p->extension_enabled(EXT_ZVFH)) || \ + (P.VU.vsew == e32 && p->extension_enabled('F')) || \ + (P.VU.vsew == e64 && p->extension_enabled('D'))); \ + require_vector(true); \ + require(STATE.frm->read() < 0x5); \ + reg_t UNUSED vl = P.VU.vl->read(); \ + reg_t UNUSED rd_num = insn.rd(); \ + reg_t UNUSED rs1_num = insn.rs1(); \ + reg_t UNUSED rs2_num = insn.rs2(); \ + softfloat_roundingMode = STATE.frm->read(); + +#define VI_VFP_LOOP_BASE \ + VI_VFP_COMMON \ + for (reg_t i = P.VU.vstart->read(); i < vl; ++i) { \ + VI_LOOP_ELEMENT_SKIP(); + +#define VI_VFP_LOOP_CMP_BASE \ + VI_VFP_COMMON \ + for (reg_t i = P.VU.vstart->read(); i < vl; ++i) { \ + VI_LOOP_ELEMENT_SKIP(); \ + uint64_t mmask = UINT64_C(1) << mpos; \ + uint64_t &vd = P.VU.elt(rd_num, midx, true); \ + uint64_t res = 0; + +#define VI_VFP_LOOP_REDUCTION_BASE(width) \ + float##width##_t vd_0 = P.VU.elt(rd_num, 0); \ + float##width##_t vs1_0 = P.VU.elt(rs1_num, 0); \ + vd_0 = vs1_0; \ + bool is_active = false; \ + for (reg_t i = P.VU.vstart->read(); i < vl; ++i) { \ + VI_LOOP_ELEMENT_SKIP(); \ + float##width##_t vs2 = P.VU.elt(rs2_num, i); \ + is_active = true; \ + +#define VI_VFP_LOOP_WIDE_REDUCTION_BASE \ + VI_VFP_COMMON \ + float64_t vd_0 = f64(P.VU.elt(rs1_num, 0).v); \ + for (reg_t i = P.VU.vstart->read(); i < vl; ++i) { \ + VI_LOOP_ELEMENT_SKIP(); + +#define VI_VFP_LOOP_END \ + } \ + P.VU.vstart->write(0); \ + +#define VI_VFP_LOOP_REDUCTION_END(x) \ + } \ + P.VU.vstart->write(0); \ + if (vl > 0) { \ + if (is_propagate && !is_active) { \ + switch (x) { \ + case e16: { \ + auto ret = f16_classify(f16(vd_0.v)); \ + if (ret & 0x300) { \ + if (ret & 0x100) { \ + softfloat_exceptionFlags |= softfloat_flag_invalid; \ + set_fp_exceptions; \ + } \ + P.VU.elt(rd_num, 0, true) = defaultNaNF16UI; \ + } else { \ + P.VU.elt(rd_num, 0, true) = vd_0.v; \ + } \ + } \ + break; \ + case e32: { \ + auto ret = f32_classify(f32(vd_0.v)); \ + if (ret & 0x300) { \ + if (ret & 0x100) { \ + softfloat_exceptionFlags |= softfloat_flag_invalid; \ + set_fp_exceptions; \ + } \ + P.VU.elt(rd_num, 0, true) = defaultNaNF32UI; \ + } else { \ + P.VU.elt(rd_num, 0, true) = vd_0.v; \ + } \ + } \ + break; \ + case e64: { \ + auto ret = f64_classify(f64(vd_0.v)); \ + if (ret & 0x300) { \ + if (ret & 0x100) { \ + softfloat_exceptionFlags |= softfloat_flag_invalid; \ + set_fp_exceptions; \ + } \ + P.VU.elt(rd_num, 0, true) = defaultNaNF64UI; \ + } else { \ + P.VU.elt(rd_num, 0, true) = vd_0.v; \ + } \ + } \ + break; \ + } \ + } else { \ + P.VU.elt::type>(rd_num, 0, true) = vd_0.v; \ + } \ + } + +#define VI_VFP_LOOP_CMP_END \ + switch (P.VU.vsew) { \ + case e16: \ + case e32: \ + case e64: { \ + vd = (vd & ~mmask) | (((res) << mpos) & mmask); \ + break; \ + } \ + default: \ + require(0); \ + break; \ + }; \ + } \ + P.VU.vstart->write(0); + +#define VI_VFP_VV_LOOP(BODY16, BODY32, BODY64) \ + VI_CHECK_SSS(true); \ + VI_VFP_LOOP_BASE \ + switch (P.VU.vsew) { \ + case e16: { \ + VFP_VV_PARAMS(16); \ + BODY16; \ + set_fp_exceptions; \ + break; \ + } \ + case e32: { \ + VFP_VV_PARAMS(32); \ + BODY32; \ + set_fp_exceptions; \ + break; \ + } \ + case e64: { \ + VFP_VV_PARAMS(64); \ + BODY64; \ + set_fp_exceptions; \ + break; \ + } \ + default: \ + require(0); \ + break; \ + }; \ + DEBUG_RVV_FP_VV; \ + VI_VFP_LOOP_END + +#define VI_VFP_V_LOOP(BODY16, BODY32, BODY64) \ + VI_CHECK_SSS(false); \ + VI_VFP_LOOP_BASE \ + switch (P.VU.vsew) { \ + case e16: { \ + VFP_V_PARAMS(16); \ + BODY16; \ + break; \ + } \ + case e32: { \ + VFP_V_PARAMS(32); \ + BODY32; \ + break; \ + } \ + case e64: { \ + VFP_V_PARAMS(64); \ + BODY64; \ + break; \ + } \ + default: \ + require(0); \ + break; \ + }; \ + set_fp_exceptions; \ + VI_VFP_LOOP_END + +#define VI_VFP_VV_LOOP_REDUCTION(BODY16, BODY32, BODY64) \ + VI_CHECK_REDUCTION(false) \ + VI_VFP_COMMON \ + switch (P.VU.vsew) { \ + case e16: { \ + VI_VFP_LOOP_REDUCTION_BASE(16) \ + BODY16; \ + set_fp_exceptions; \ + VI_VFP_LOOP_REDUCTION_END(e16) \ + break; \ + } \ + case e32: { \ + VI_VFP_LOOP_REDUCTION_BASE(32) \ + BODY32; \ + set_fp_exceptions; \ + VI_VFP_LOOP_REDUCTION_END(e32) \ + break; \ + } \ + case e64: { \ + VI_VFP_LOOP_REDUCTION_BASE(64) \ + BODY64; \ + set_fp_exceptions; \ + VI_VFP_LOOP_REDUCTION_END(e64) \ + break; \ + } \ + default: \ + require(0); \ + break; \ + }; \ + +#define VI_VFP_VV_LOOP_WIDE_REDUCTION(BODY16, BODY32) \ + VI_CHECK_REDUCTION(true) \ + VI_VFP_COMMON \ + require((P.VU.vsew == e16 && p->extension_enabled('F')) || \ + (P.VU.vsew == e32 && p->extension_enabled('D'))); \ + bool is_active = false; \ + switch (P.VU.vsew) { \ + case e16: { \ + float32_t vd_0 = P.VU.elt(rs1_num, 0); \ + for (reg_t i = P.VU.vstart->read(); i < vl; ++i) { \ + VI_LOOP_ELEMENT_SKIP(); \ + is_active = true; \ + float32_t vs2 = f16_to_f32(P.VU.elt(rs2_num, i)); \ + BODY16; \ + set_fp_exceptions; \ + VI_VFP_LOOP_REDUCTION_END(e32) \ + break; \ + } \ + case e32: { \ + float64_t vd_0 = P.VU.elt(rs1_num, 0); \ + for (reg_t i = P.VU.vstart->read(); i < vl; ++i) { \ + VI_LOOP_ELEMENT_SKIP(); \ + is_active = true; \ + float64_t vs2 = f32_to_f64(P.VU.elt(rs2_num, i)); \ + BODY32; \ + set_fp_exceptions; \ + VI_VFP_LOOP_REDUCTION_END(e64) \ + break; \ + } \ + default: \ + require(0); \ + break; \ + }; \ + +#define VI_VFP_VF_LOOP(BODY16, BODY32, BODY64) \ + VI_CHECK_SSS(false); \ + VI_VFP_LOOP_BASE \ + switch (P.VU.vsew) { \ + case e16: { \ + VFP_VF_PARAMS(16); \ + BODY16; \ + set_fp_exceptions; \ + break; \ + } \ + case e32: { \ + VFP_VF_PARAMS(32); \ + BODY32; \ + set_fp_exceptions; \ + break; \ + } \ + case e64: { \ + VFP_VF_PARAMS(64); \ + BODY64; \ + set_fp_exceptions; \ + break; \ + } \ + default: \ + require(0); \ + break; \ + }; \ + DEBUG_RVV_FP_VF; \ + VI_VFP_LOOP_END + +#define VI_VFP_VV_LOOP_CMP(BODY16, BODY32, BODY64) \ + VI_CHECK_MSS(true); \ + VI_VFP_LOOP_CMP_BASE \ + switch (P.VU.vsew) { \ + case e16: { \ + VFP_VV_CMP_PARAMS(16); \ + BODY16; \ + set_fp_exceptions; \ + break; \ + } \ + case e32: { \ + VFP_VV_CMP_PARAMS(32); \ + BODY32; \ + set_fp_exceptions; \ + break; \ + } \ + case e64: { \ + VFP_VV_CMP_PARAMS(64); \ + BODY64; \ + set_fp_exceptions; \ + break; \ + } \ + default: \ + require(0); \ + break; \ + }; \ + VI_VFP_LOOP_CMP_END \ + +#define VI_VFP_VF_LOOP_CMP(BODY16, BODY32, BODY64) \ + VI_CHECK_MSS(false); \ + VI_VFP_LOOP_CMP_BASE \ + switch (P.VU.vsew) { \ + case e16: { \ + VFP_VF_CMP_PARAMS(16); \ + BODY16; \ + set_fp_exceptions; \ + break; \ + } \ + case e32: { \ + VFP_VF_CMP_PARAMS(32); \ + BODY32; \ + set_fp_exceptions; \ + break; \ + } \ + case e64: { \ + VFP_VF_CMP_PARAMS(64); \ + BODY64; \ + set_fp_exceptions; \ + break; \ + } \ + default: \ + require(0); \ + break; \ + }; \ + VI_VFP_LOOP_CMP_END \ + +#define VI_VFP_VF_LOOP_WIDE(BODY16, BODY32) \ + VI_CHECK_DSS(false); \ + VI_VFP_LOOP_BASE \ + switch (P.VU.vsew) { \ + case e16: { \ + float32_t &vd = P.VU.elt(rd_num, i, true); \ + float32_t vs2 = f16_to_f32(P.VU.elt(rs2_num, i)); \ + float32_t rs1 = f16_to_f32(FRS1_H); \ + BODY16; \ + set_fp_exceptions; \ + break; \ + } \ + case e32: { \ + float64_t &vd = P.VU.elt(rd_num, i, true); \ + float64_t vs2 = f32_to_f64(P.VU.elt(rs2_num, i)); \ + float64_t rs1 = f32_to_f64(FRS1_F); \ + BODY32; \ + set_fp_exceptions; \ + break; \ + } \ + default: \ + require(0); \ + break; \ + }; \ + DEBUG_RVV_FP_VV; \ + VI_VFP_LOOP_END + +#define VI_VFP_VV_LOOP_WIDE(BODY16, BODY32) \ + VI_CHECK_DSS(true); \ + VI_VFP_LOOP_BASE \ + switch (P.VU.vsew) { \ + case e16: { \ + float32_t &vd = P.VU.elt(rd_num, i, true); \ + float32_t vs2 = f16_to_f32(P.VU.elt(rs2_num, i)); \ + float32_t vs1 = f16_to_f32(P.VU.elt(rs1_num, i)); \ + BODY16; \ + set_fp_exceptions; \ + break; \ + } \ + case e32: { \ + float64_t &vd = P.VU.elt(rd_num, i, true); \ + float64_t vs2 = f32_to_f64(P.VU.elt(rs2_num, i)); \ + float64_t vs1 = f32_to_f64(P.VU.elt(rs1_num, i)); \ + BODY32; \ + set_fp_exceptions; \ + break; \ + } \ + default: \ + require(0); \ + break; \ + }; \ + DEBUG_RVV_FP_VV; \ + VI_VFP_LOOP_END + +#define VI_VFP_WF_LOOP_WIDE(BODY16, BODY32) \ + VI_CHECK_DDS(false); \ + VI_VFP_LOOP_BASE \ + switch (P.VU.vsew) { \ + case e16: { \ + float32_t &vd = P.VU.elt(rd_num, i, true); \ + float32_t vs2 = P.VU.elt(rs2_num, i); \ + float32_t rs1 = f16_to_f32(FRS1_H); \ + BODY16; \ + set_fp_exceptions; \ + break; \ + } \ + case e32: { \ + float64_t &vd = P.VU.elt(rd_num, i, true); \ + float64_t vs2 = P.VU.elt(rs2_num, i); \ + float64_t rs1 = f32_to_f64(FRS1_F); \ + BODY32; \ + set_fp_exceptions; \ + break; \ + } \ + default: \ + require(0); \ + }; \ + DEBUG_RVV_FP_VV; \ + VI_VFP_LOOP_END + +#define VI_VFP_WV_LOOP_WIDE(BODY16, BODY32) \ + VI_CHECK_DDS(true); \ + VI_VFP_LOOP_BASE \ + switch (P.VU.vsew) { \ + case e16: { \ + float32_t &vd = P.VU.elt(rd_num, i, true); \ + float32_t vs2 = P.VU.elt(rs2_num, i); \ + float32_t vs1 = f16_to_f32(P.VU.elt(rs1_num, i)); \ + BODY16; \ + set_fp_exceptions; \ + break; \ + } \ + case e32: { \ + float64_t &vd = P.VU.elt(rd_num, i, true); \ + float64_t vs2 = P.VU.elt(rs2_num, i); \ + float64_t vs1 = f32_to_f64(P.VU.elt(rs1_num, i)); \ + BODY32; \ + set_fp_exceptions; \ + break; \ + } \ + default: \ + require(0); \ + }; \ + DEBUG_RVV_FP_VV; \ + VI_VFP_LOOP_END + +#define VI_VFP_LOOP_SCALE_BASE \ + require_fp; \ + require_vector(true); \ + require(STATE.frm->read() < 0x5); \ + reg_t vl = P.VU.vl->read(); \ + reg_t rd_num = insn.rd(); \ + reg_t UNUSED rs1_num = insn.rs1(); \ + reg_t rs2_num = insn.rs2(); \ + softfloat_roundingMode = STATE.frm->read(); \ + for (reg_t i = P.VU.vstart->read(); i < vl; ++i) { \ + VI_LOOP_ELEMENT_SKIP(); + +#define VI_VFP_CVT_LOOP(CVT_PARAMS, CHECK, BODY) \ + CHECK \ + VI_VFP_LOOP_SCALE_BASE \ + CVT_PARAMS \ + BODY \ + set_fp_exceptions; \ + VI_VFP_LOOP_END + +#define VI_VFP_CVT_INT_TO_FP(BODY16, BODY32, BODY64, sign) \ + VI_CHECK_SSS(false); \ + VI_VFP_COMMON \ + switch (P.VU.vsew) { \ + case e16: \ + { VI_VFP_CVT_LOOP(CVT_INT_TO_FP_PARAMS(16, 16, sign), \ + { p->extension_enabled(EXT_ZVFH); }, \ + BODY16); } \ + break; \ + case e32: \ + { VI_VFP_CVT_LOOP(CVT_INT_TO_FP_PARAMS(32, 32, sign), \ + { p->extension_enabled('F'); }, \ + BODY32); } \ + break; \ + case e64: \ + { VI_VFP_CVT_LOOP(CVT_INT_TO_FP_PARAMS(64, 64, sign), \ + { p->extension_enabled('D'); }, \ + BODY64); } \ + break; \ + default: \ + require(0); \ + break; \ + } + +#define VI_VFP_CVT_FP_TO_INT(BODY16, BODY32, BODY64, sign) \ + VI_CHECK_SSS(false); \ + VI_VFP_COMMON \ + switch (P.VU.vsew) { \ + case e16: \ + { VI_VFP_CVT_LOOP(CVT_FP_TO_INT_PARAMS(16, 16, sign), \ + { p->extension_enabled(EXT_ZVFH); }, \ + BODY16); } \ + break; \ + case e32: \ + { VI_VFP_CVT_LOOP(CVT_FP_TO_INT_PARAMS(32, 32, sign), \ + { p->extension_enabled('F'); }, \ + BODY32); } \ + break; \ + case e64: \ + { VI_VFP_CVT_LOOP(CVT_FP_TO_INT_PARAMS(64, 64, sign), \ + { p->extension_enabled('D'); }, \ + BODY64); } \ + break; \ + default: \ + require(0); \ + break; \ + } + +#define VI_VFP_WCVT_FP_TO_FP(BODY16, BODY32, \ + CHECK16, CHECK32) \ + VI_CHECK_DSS(false); \ + switch (P.VU.vsew) { \ + case e16: \ + { VI_VFP_CVT_LOOP(CVT_FP_TO_FP_PARAMS(16, 32), CHECK16, BODY16); } \ + break; \ + case e32: \ + { VI_VFP_CVT_LOOP(CVT_FP_TO_FP_PARAMS(32, 64), CHECK32, BODY32); } \ + break; \ + default: \ + require(0); \ + break; \ + } + +#define VI_VFP_WCVT_INT_TO_FP(BODY8, BODY16, BODY32, \ + CHECK8, CHECK16, CHECK32, \ + sign) \ + VI_CHECK_DSS(false); \ + switch (P.VU.vsew) { \ + case e8: \ + { VI_VFP_CVT_LOOP(CVT_INT_TO_FP_PARAMS(8, 16, sign), CHECK8, BODY8); } \ + break; \ + case e16: \ + { VI_VFP_CVT_LOOP(CVT_INT_TO_FP_PARAMS(16, 32, sign), CHECK16, BODY16); } \ + break; \ + case e32: \ + { VI_VFP_CVT_LOOP(CVT_INT_TO_FP_PARAMS(32, 64, sign), CHECK32, BODY32); } \ + break; \ + default: \ + require(0); \ + break; \ + } + +#define VI_VFP_WCVT_FP_TO_INT(BODY16, BODY32, \ + CHECK16, CHECK32, \ + sign) \ + VI_CHECK_DSS(false); \ + switch (P.VU.vsew) { \ + case e16: \ + { VI_VFP_CVT_LOOP(CVT_FP_TO_INT_PARAMS(16, 32, sign), CHECK16, BODY16); } \ + break; \ + case e32: \ + { VI_VFP_CVT_LOOP(CVT_FP_TO_INT_PARAMS(32, 64, sign), CHECK32, BODY32); } \ + break; \ + default: \ + require(0); \ + break; \ + } + +#define VI_VFP_NCVT_FP_TO_FP(BODY32, BODY64, \ + CHECK32, CHECK64) \ + VI_CHECK_SDS(false); \ + switch (P.VU.vsew) { \ + case e16: \ + { VI_VFP_CVT_LOOP(CVT_FP_TO_FP_PARAMS(32, 16), CHECK32, BODY32); } \ + break; \ + case e32: \ + { VI_VFP_CVT_LOOP(CVT_FP_TO_FP_PARAMS(64, 32), CHECK64, BODY64); } \ + break; \ + default: \ + require(0); \ + break; \ + } + +#define VI_VFP_NCVT_INT_TO_FP(BODY32, BODY64, \ + CHECK32, CHECK64, \ + sign) \ + VI_CHECK_SDS(false); \ + switch (P.VU.vsew) { \ + case e16: \ + { VI_VFP_CVT_LOOP(CVT_INT_TO_FP_PARAMS(32, 16, sign), CHECK32, BODY32); } \ + break; \ + case e32: \ + { VI_VFP_CVT_LOOP(CVT_INT_TO_FP_PARAMS(64, 32, sign), CHECK64, BODY64); } \ + break; \ + default: \ + require(0); \ + break; \ + } + +#define VI_VFP_NCVT_FP_TO_INT(BODY16, BODY32, BODY64, \ + CHECK16, CHECK32, CHECK64, \ + sign) \ + VI_CHECK_SDS(false); \ + switch (P.VU.vsew) { \ + case e8: \ + { VI_VFP_CVT_LOOP(CVT_FP_TO_INT_PARAMS(16, 8, sign), CHECK16, BODY16); } \ + break; \ + case e16: \ + { VI_VFP_CVT_LOOP(CVT_FP_TO_INT_PARAMS(32, 16, sign), CHECK32, BODY32); } \ + break; \ + case e32: \ + { VI_VFP_CVT_LOOP(CVT_FP_TO_INT_PARAMS(64, 32, sign), CHECK64, BODY64); } \ + break; \ + default: \ + require(0); \ + break; \ + } + +#endif diff --git a/vendor/riscv/riscv-isa-sim/riscv/vector_unit.cc b/vendor/riscv/riscv-isa-sim/riscv/vector_unit.cc new file mode 100644 index 000000000..ff3dd82fb --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/vector_unit.cc @@ -0,0 +1,100 @@ +// See LICENSE for license details + +#include "config.h" +#include "vector_unit.h" +#include "processor.h" +#include "arith.h" + +void vectorUnit_t::vectorUnit_t::reset() +{ + free(reg_file); + VLEN = get_vlen(); + ELEN = get_elen(); + reg_file = malloc(NVPR * vlenb); + memset(reg_file, 0, NVPR * vlenb); + + auto& csrmap = p->get_state()->csrmap; + csrmap[CSR_VXSAT] = vxsat = std::make_shared(p, CSR_VXSAT); + csrmap[CSR_VSTART] = vstart = std::make_shared(p, CSR_VSTART, /*mask*/ VLEN - 1); + csrmap[CSR_VXRM] = vxrm = std::make_shared(p, CSR_VXRM, /*mask*/ 0x3ul); + csrmap[CSR_VL] = vl = std::make_shared(p, CSR_VL, /*mask*/ 0); + csrmap[CSR_VTYPE] = vtype = std::make_shared(p, CSR_VTYPE, /*mask*/ 0); + csrmap[CSR_VLENB] = std::make_shared(p, CSR_VLENB, /*mask*/ 0, /*init*/ vlenb); + assert(VCSR_VXSAT_SHIFT == 0); // composite_csr_t assumes vxsat begins at bit 0 + csrmap[CSR_VCSR] = std::make_shared(p, CSR_VCSR, vxrm, vxsat, VCSR_VXRM_SHIFT); + + vtype->write_raw(0); + set_vl(0, 0, 0, -1); // default to illegal configuration +} + +reg_t vectorUnit_t::vectorUnit_t::set_vl(int rd, int rs1, reg_t reqVL, reg_t newType) +{ + int new_vlmul = 0; + if (vtype->read() != newType) { + vsew = 1 << (extract64(newType, 3, 3) + 3); + new_vlmul = int8_t(extract64(newType, 0, 3) << 5) >> 5; + vflmul = new_vlmul >= 0 ? 1 << new_vlmul : 1.0 / (1 << -new_vlmul); + vlmax = (VLEN/vsew) * vflmul; + vta = extract64(newType, 6, 1); + vma = extract64(newType, 7, 1); + + vill = !(vflmul >= 0.125 && vflmul <= 8) + || vsew > std::min(vflmul, 1.0f) * ELEN + || (newType >> 8) != 0; + + if (vill) { + vlmax = 0; + vtype->write_raw(UINT64_MAX << (p->get_xlen() - 1)); + } else { + vtype->write_raw(newType); + } + } + + // set vl + if (vlmax == 0) { + vl->write_raw(0); + } else if (rd == 0 && rs1 == 0) { + vl->write_raw(vl->read() > vlmax ? vlmax : vl->read()); + } else if (rd != 0 && rs1 == 0) { + vl->write_raw(vlmax); + } else if (rs1 != 0) { + vl->write_raw(reqVL > vlmax ? vlmax : reqVL); + } + + vstart->write_raw(0); + setvl_count++; + return vl->read(); +} + +template T& vectorUnit_t::elt(reg_t vReg, reg_t n, bool UNUSED is_write) { + assert(vsew != 0); + assert((VLEN >> 3)/sizeof(T) > 0); + reg_t elts_per_reg = (VLEN >> 3) / (sizeof(T)); + vReg += n / elts_per_reg; + n = n % elts_per_reg; +#ifdef WORDS_BIGENDIAN + // "V" spec 0.7.1 requires lower indices to map to lower significant + // bits when changing SEW, thus we need to index from the end on BE. + n ^= elts_per_reg - 1; +#endif + reg_referenced[vReg] = 1; + + if (unlikely(p->get_log_commits_enabled() && is_write)) + p->get_state()->log_reg_write[((vReg) << 4) | 2] = {0, 0}; + + T *regStart = (T*)((char*)reg_file + vReg * (VLEN >> 3)); + return regStart[n]; +} + +template signed char& vectorUnit_t::elt(reg_t, reg_t, bool); +template short& vectorUnit_t::elt(reg_t, reg_t, bool); +template int& vectorUnit_t::elt(reg_t, reg_t, bool); +template long& vectorUnit_t::elt(reg_t, reg_t, bool); +template long long& vectorUnit_t::elt(reg_t, reg_t, bool); +template uint8_t& vectorUnit_t::elt(reg_t, reg_t, bool); +template uint16_t& vectorUnit_t::elt(reg_t, reg_t, bool); +template uint32_t& vectorUnit_t::elt(reg_t, reg_t, bool); +template uint64_t& vectorUnit_t::elt(reg_t, reg_t, bool); +template float16_t& vectorUnit_t::elt(reg_t, reg_t, bool); +template float32_t& vectorUnit_t::elt(reg_t, reg_t, bool); +template float64_t& vectorUnit_t::elt(reg_t, reg_t, bool); diff --git a/vendor/riscv/riscv-isa-sim/riscv/vector_unit.h b/vendor/riscv/riscv-isa-sim/riscv/vector_unit.h new file mode 100644 index 000000000..b9f706c53 --- /dev/null +++ b/vendor/riscv/riscv-isa-sim/riscv/vector_unit.h @@ -0,0 +1,135 @@ +// See LICENSE for license details. +#ifndef _RISCV_VECTOR_UNIT_H +#define _RISCV_VECTOR_UNIT_H + +#include "decode.h" +#include "csrs.h" + +class processor_t; + +enum VRM{ + RNU = 0, + RNE, + RDN, + ROD, + INVALID_RM +}; + +template +struct type_usew_t; + +template<> +struct type_usew_t<8> +{ + using type=uint8_t; +}; + +template<> +struct type_usew_t<16> +{ + using type=uint16_t; +}; + +template<> +struct type_usew_t<32> +{ + using type=uint32_t; +}; + +template<> +struct type_usew_t<64> +{ + using type=uint64_t; +}; + +template +struct type_sew_t; + +template<> +struct type_sew_t<8> +{ + using type=int8_t; +}; + +template<> +struct type_sew_t<16> +{ + using type=int16_t; +}; + +template<> +struct type_sew_t<32> +{ + using type=int32_t; +}; + +template<> +struct type_sew_t<64> +{ + using type=int64_t; +}; + + +class vectorUnit_t +{ +public: + processor_t* p; + void *reg_file; + char reg_referenced[NVPR]; + int setvl_count; + reg_t vlmax; + reg_t vlenb; + csr_t_p vxsat; + vector_csr_t_p vxrm, vstart, vl, vtype; + reg_t vma, vta; + reg_t vsew; + float vflmul; + reg_t ELEN, VLEN; + bool vill; + bool vstart_alu; + + // vector element for varies SEW + template T& elt(reg_t vReg, reg_t n, bool is_write = false); + +public: + + void reset(); + + vectorUnit_t(): + p(0), + reg_file(0), + reg_referenced{0}, + setvl_count(0), + vlmax(0), + vlenb(0), + vxsat(0), + vxrm(0), + vstart(0), + vl(0), + vtype(0), + vma(0), + vta(0), + vsew(0), + vflmul(0), + ELEN(0), + VLEN(0), + vill(false), + vstart_alu(false) { + } + + ~vectorUnit_t() { + free(reg_file); + reg_file = 0; + } + + reg_t set_vl(int rd, int rs1, reg_t reqVL, reg_t newType); + + reg_t get_vlen() { return VLEN; } + reg_t get_elen() { return ELEN; } + reg_t get_slen() { return VLEN; } + + VRM get_vround_mode() { + return (VRM)(vxrm->read()); + } +}; +#endif diff --git a/vendor/riscv/riscv-isa-sim/softfloat/softfloat.mk.in b/vendor/riscv/riscv-isa-sim/softfloat/softfloat.mk.in index a20ab7ee7..e7f4a3e41 100644 --- a/vendor/riscv/riscv-isa-sim/softfloat/softfloat.mk.in +++ b/vendor/riscv/riscv-isa-sim/softfloat/softfloat.mk.in @@ -1,14 +1,5 @@ softfloat_subproject_deps = -softfloat_hdrs = \ - internals.h \ - platform.h \ - primitives.h \ - primitiveTypes.h \ - softfloat.h \ - softfloat_types.h \ - specialize.h \ - softfloat_c_srcs = \ f128_add.c \ f128_classify.c \ @@ -238,4 +229,11 @@ softfloat_install_shared_lib = yes softfloat_test_srcs = -softfloat_install_prog_srcs = +softfloat_install_hdrs = \ + softfloat.h \ + softfloat_types.h \ + primitives.h \ + internals.h \ + platform.h \ + primitiveTypes.h \ + specialize.h \ diff --git a/vendor/riscv/riscv-isa-sim/softfloat/specialize.h b/vendor/riscv/riscv-isa-sim/softfloat/specialize.h index 556476c1a..19504b6b6 100644 --- a/vendor/riscv/riscv-isa-sim/softfloat/specialize.h +++ b/vendor/riscv/riscv-isa-sim/softfloat/specialize.h @@ -111,7 +111,7 @@ struct commonNaN { char _unused; }; | location pointed to by `zPtr'. If the NaN is a signaling NaN, the invalid | exception is raised. *----------------------------------------------------------------------------*/ -#define softfloat_f16UIToCommonNaN( uiA, zPtr ) if ( ! ((uiA) & 0x0200) ) softfloat_raiseFlags( softfloat_flag_invalid ) +#define softfloat_f16UIToCommonNaN( uiA, zPtr ) if ( ! ((uiA) & 0x0200) ) (void) (zPtr), softfloat_raiseFlags( softfloat_flag_invalid ) /*---------------------------------------------------------------------------- | Converts the common NaN pointed to by `aPtr' into a 16-bit floating-point @@ -146,7 +146,7 @@ uint_fast16_t | location pointed to by `zPtr'. If the NaN is a signaling NaN, the invalid | exception is raised. *----------------------------------------------------------------------------*/ -#define softfloat_f32UIToCommonNaN( uiA, zPtr ) if ( ! ((uiA) & 0x00400000) ) softfloat_raiseFlags( softfloat_flag_invalid ) +#define softfloat_f32UIToCommonNaN( uiA, zPtr ) if ( ! ((uiA) & 0x00400000) ) (void) (zPtr), softfloat_raiseFlags( softfloat_flag_invalid ) /*---------------------------------------------------------------------------- | Converts the common NaN pointed to by `aPtr' into a 32-bit floating-point @@ -181,7 +181,7 @@ uint_fast32_t | location pointed to by `zPtr'. If the NaN is a signaling NaN, the invalid | exception is raised. *----------------------------------------------------------------------------*/ -#define softfloat_f64UIToCommonNaN( uiA, zPtr ) if ( ! ((uiA) & UINT64_C( 0x0008000000000000 )) ) softfloat_raiseFlags( softfloat_flag_invalid ) +#define softfloat_f64UIToCommonNaN( uiA, zPtr ) if ( ! ((uiA) & UINT64_C( 0x0008000000000000 )) ) (void) (zPtr), softfloat_raiseFlags( softfloat_flag_invalid ) /*---------------------------------------------------------------------------- | Converts the common NaN pointed to by `aPtr' into a 64-bit floating-point @@ -238,6 +238,9 @@ INLINE struct uint128 softfloat_commonNaNToExtF80UI( const struct commonNaN *aPtr ) { struct uint128 uiZ; + + (void) aPtr; + uiZ.v64 = defaultNaNExtF80UI64; uiZ.v0 = defaultNaNExtF80UI0; return uiZ; @@ -284,7 +287,7 @@ struct uint128 | pointed to by `zPtr'. If the NaN is a signaling NaN, the invalid exception | is raised. *----------------------------------------------------------------------------*/ -#define softfloat_f128UIToCommonNaN( uiA64, uiA0, zPtr ) if ( ! ((uiA64) & UINT64_C( 0x0000800000000000 )) ) softfloat_raiseFlags( softfloat_flag_invalid ) +#define softfloat_f128UIToCommonNaN( uiA64, uiA0, zPtr ) if ( ! ((uiA64) & UINT64_C( 0x0000800000000000 )) ) (void) (zPtr), softfloat_raiseFlags( softfloat_flag_invalid ) /*---------------------------------------------------------------------------- | Converts the common NaN pointed to by `aPtr' into a 128-bit floating-point @@ -295,6 +298,9 @@ INLINE struct uint128 softfloat_commonNaNToF128UI( const struct commonNaN *aPtr ) { struct uint128 uiZ; + + (void) aPtr; + uiZ.v64 = defaultNaNF128UI64; uiZ.v0 = defaultNaNF128UI0; return uiZ; diff --git a/vendor/riscv/riscv-isa-sim/spike_dasm/spike-dasm.cc b/vendor/riscv/riscv-isa-sim/spike_dasm/spike-dasm.cc index fa6a25ae6..3e42df5b4 100644 --- a/vendor/riscv/riscv-isa-sim/spike_dasm/spike-dasm.cc +++ b/vendor/riscv/riscv-isa-sim/spike_dasm/spike-dasm.cc @@ -6,6 +6,7 @@ // enclosed hexadecimal number, interpreted as a RISC-V // instruction. +#include "config.h" #include "disasm.h" #include "extension.h" #include @@ -14,7 +15,7 @@ #include using namespace std; -int main(int argc, char** argv) +int main(int UNUSED argc, char** argv) { string s; const char* isa = DEFAULT_ISA; @@ -27,21 +28,8 @@ int main(int argc, char** argv) parser.option(0, "isa", 1, [&](const char* s){isa = s;}); parser.parse(argv); - std::string lowercase; - for (const char *p = isa; *p; p++) - lowercase += std::tolower(*p); - - int xlen; - if (lowercase.compare(0, 4, "rv32") == 0) { - xlen = 32; - } else if (lowercase.compare(0, 4, "rv64") == 0) { - xlen = 64; - } else { - fprintf(stderr, "bad ISA string: %s\n", isa); - return 1; - } - - disassembler_t* disassembler = new disassembler_t(xlen); + isa_parser_t isa_parser(isa, DEFAULT_PRIV); + disassembler_t* disassembler = new disassembler_t(&isa_parser); if (extension) { for (auto disasm_insn : extension()->get_disasms()) { disassembler->add_insn(disasm_insn); @@ -63,14 +51,10 @@ int main(int argc, char** argv) continue; char* endp; - int64_t bits = strtoull(&s[pos], &endp, 16); + insn_bits_t bits = strtoull(&s[pos], &endp, 16); if (*endp != ')') continue; - size_t nbits = 4 * (endp - &s[pos]); - if (nbits < 64) - bits = bits << (64 - nbits) >> (64 - nbits); - string dis = disassembler->disassemble(bits); s = s.substr(0, start) + dis + s.substr(endp - &s[0] + 1); pos = start + dis.length(); diff --git a/vendor/riscv/riscv-isa-sim/spike_dasm/spike_dasm.mk.in b/vendor/riscv/riscv-isa-sim/spike_dasm/spike_dasm.mk.in index b6118fd5c..1003a7993 100644 --- a/vendor/riscv/riscv-isa-sim/spike_dasm/spike_dasm.mk.in +++ b/vendor/riscv/riscv-isa-sim/spike_dasm/spike_dasm.mk.in @@ -1,6 +1,7 @@ spike_dasm_subproject_deps = \ disasm \ - $(if $(HAVE_DLOPEN),riscv,) \ + softfloat \ + riscv \ spike_dasm_srcs = \ spike_dasm_option_parser.cc \ diff --git a/vendor/riscv/riscv-isa-sim/spike_main/spike-log-parser.cc b/vendor/riscv/riscv-isa-sim/spike_main/spike-log-parser.cc index 9481fb4f4..9bea5c51c 100644 --- a/vendor/riscv/riscv-isa-sim/spike_main/spike-log-parser.cc +++ b/vendor/riscv/riscv-isa-sim/spike_main/spike-log-parser.cc @@ -5,6 +5,7 @@ // in its inputs, then output the RISC-V instruction with the disassembly // enclosed hexadecimal number. +#include "config.h" #include #include #include @@ -16,18 +17,32 @@ using namespace std; -int main(int argc, char** argv) +int main(int UNUSED argc, char** argv) { string s; - const char* isa = DEFAULT_ISA; + const char* isa_string = DEFAULT_ISA; std::function extension; option_parser_t parser; parser.option(0, "extension", 1, [&](const char* s){extension = find_extension(s);}); - parser.option(0, "isa", 1, [&](const char* s){isa = s;}); + parser.option(0, "isa", 1, [&](const char* s){isa_string = s;}); parser.parse(argv); - processor_t p(isa, DEFAULT_PRIV, DEFAULT_VARCH, 0, 0, false, nullptr, cerr); + cfg_t cfg(/*default_initrd_bounds=*/std::make_pair((reg_t)0, (reg_t)0), + /*default_bootargs=*/nullptr, + /*default_isa=*/DEFAULT_ISA, + /*default_priv=*/DEFAULT_PRIV, + /*default_varch=*/DEFAULT_VARCH, + /*default_misaligned=*/false, + /*default_endianness*/endianness_little, + /*default_pmpregions=*/16, + /*default_mem_layout=*/std::vector(), + /*default_hartids=*/std::vector(), + /*default_real_time_clint=*/false, + /*default_trigger_count=*/4); + + isa_parser_t isa(isa_string, DEFAULT_PRIV); + processor_t p(&isa, &cfg, 0, 0, false, nullptr, cerr); if (extension) { p.register_extension(extension()); } diff --git a/vendor/riscv/riscv-isa-sim/spike_main/spike.cc b/vendor/riscv/riscv-isa-sim/spike_main/spike.cc index e2680cc92..7290f38bb 100644 --- a/vendor/riscv/riscv-isa-sim/spike_main/spike.cc +++ b/vendor/riscv/riscv-isa-sim/spike_main/spike.cc @@ -1,7 +1,10 @@ // See LICENSE for license details. +#include "config.h" +#include "cfg.h" #include "sim.h" #include "mmu.h" +#include "arith.h" #include "remote_bitbang.h" #include "cachesim.h" #include "extension.h" @@ -13,6 +16,8 @@ #include #include #include +#include +#include #include "../VERSION" static void help(int exit_code = 1) @@ -35,6 +40,7 @@ static void help(int exit_code = 1) fprintf(stderr, " --log= File name for option -l\n"); fprintf(stderr, " --debug-cmd= Read commands from file (use with -d)\n"); fprintf(stderr, " --isa= RISC-V ISA string [default %s]\n", DEFAULT_ISA); + fprintf(stderr, " --pmpregions= Number of PMP regions [default 16]\n"); fprintf(stderr, " --priv= RISC-V privilege modes supported [default %s]\n", DEFAULT_PRIV); fprintf(stderr, " --varch= RISC-V Vector uArch string [default %s]\n", DEFAULT_VARCH); fprintf(stderr, " --pc=
Override ELF entry point\n"); @@ -42,6 +48,8 @@ static void help(int exit_code = 1) fprintf(stderr, " --ic=:: Instantiate a cache model with S sets,\n"); fprintf(stderr, " --dc=:: W ways, and B-byte blocks (with S and\n"); fprintf(stderr, " --l2=:: B both powers of 2).\n"); + fprintf(stderr, " --big-endian Use a big-endian memory system.\n"); + fprintf(stderr, " --misaligned Support misaligned memory accesses\n"); fprintf(stderr, " --device= Attach MMIO plugin device from an --extlib library\n"); fprintf(stderr, " P -- Name of the MMIO plugin\n"); fprintf(stderr, " B -- Base memory address of the device\n"); @@ -49,17 +57,21 @@ static void help(int exit_code = 1) fprintf(stderr, " This flag can be used multiple times.\n"); fprintf(stderr, " The extlib flag for the library must come first.\n"); fprintf(stderr, " --log-cache-miss Generate a log of cache miss\n"); + fprintf(stderr, " --log-commits Generate a log of commits info\n"); fprintf(stderr, " --extension= Specify RoCC Extension\n"); fprintf(stderr, " This flag can be used multiple times.\n"); fprintf(stderr, " --extlib= Shared library to load\n"); fprintf(stderr, " This flag can be used multiple times.\n"); fprintf(stderr, " --rbb-port= Listen on for remote bitbang connection\n"); fprintf(stderr, " --dump-dts Print device tree string and exit\n"); + fprintf(stderr, " --dtb= Use specified device tree blob [default: auto-generate]\n"); fprintf(stderr, " --disable-dtb Don't write the device tree blob into memory\n"); fprintf(stderr, " --kernel= Load kernel flat image into memory\n"); fprintf(stderr, " --initrd= Load kernel initrd into memory\n"); - fprintf(stderr, " --bootargs= Provide custom bootargs for kernel [default: console=hvc0 earlycon=sbi]\n"); + fprintf(stderr, " --bootargs= Provide custom bootargs for kernel [default: %s]\n", + DEFAULT_KERNEL_BOOTARGS); fprintf(stderr, " --real-time-clint Increment clint time at real-time rate\n"); + fprintf(stderr, " --triggers= Number of supported triggers [default 4]\n"); fprintf(stderr, " --dm-progsize= Progsize for the debug module [default 2]\n"); fprintf(stderr, " --dm-sba= Debug system bus access supports up to " " wide accesses [default 0]\n"); @@ -69,9 +81,11 @@ static void help(int exit_code = 1) fprintf(stderr, " --dm-abstract-rti= Number of Run-Test/Idle cycles " "required for an abstract command to execute [default 0]\n"); fprintf(stderr, " --dm-no-hasel Debug module supports hasel\n"); - fprintf(stderr, " --dm-no-abstract-csr Debug module won't support abstract to authenticate\n"); + fprintf(stderr, " --dm-no-abstract-csr Debug module won't support abstract CSR access\n"); + fprintf(stderr, " --dm-no-abstract-fpr Debug module won't support abstract FPR access\n"); fprintf(stderr, " --dm-no-halt-groups Debug module won't support halt groups\n"); fprintf(stderr, " --dm-no-impebreak Debug module won't support implicit ebreak in program buffer\n"); + fprintf(stderr, " --blocksz= Cache block size (B) for CMO operations(powers of 2) [default 64]\n"); exit(exit_code); } @@ -105,45 +119,84 @@ static void read_file_bytes(const char *filename,size_t fileoff, mem->store(memoff, read_sz, (uint8_t*)&read_buf[0]); } -bool sort_mem_region(const std::pair &a, - const std::pair &b) +bool sort_mem_region(const mem_cfg_t &a, const mem_cfg_t &b) { - if (a.first == b.first) - return (a.second->size() < b.second->size()); + if (a.get_base() == b.get_base()) + return (a.get_size() < b.get_size()); else - return (a.first < b.first); + return (a.get_base() < b.get_base()); } -void merge_overlapping_memory_regions(std::vector>& mems) +static bool check_mem_overlap(const mem_cfg_t& L, const mem_cfg_t& R) { - // check the user specified memory regions and merge the overlapping or - // eliminate the containing parts + return std::max(L.get_base(), R.get_base()) <= std::min(L.get_inclusive_end(), R.get_inclusive_end()); +} + +static bool check_if_merge_covers_64bit_space(const mem_cfg_t& L, + const mem_cfg_t& R) +{ + if (!check_mem_overlap(L, R)) + return false; + + auto start = std::min(L.get_base(), R.get_base()); + auto end = std::max(L.get_inclusive_end(), R.get_inclusive_end()); + + return (start == 0ull) && (end == std::numeric_limits::max()); +} + +static mem_cfg_t merge_mem_regions(const mem_cfg_t& L, const mem_cfg_t& R) +{ + // one can merge only intersecting regions + assert(check_mem_overlap(L, R)); + + const auto merged_base = std::min(L.get_base(), R.get_base()); + const auto merged_end_incl = std::max(L.get_inclusive_end(), R.get_inclusive_end()); + const auto merged_size = merged_end_incl - merged_base + 1; + + return mem_cfg_t(merged_base, merged_size); +} + +// check the user specified memory regions and merge the overlapping or +// eliminate the containing parts +static std::vector +merge_overlapping_memory_regions(std::vector mems) +{ + if (mems.empty()) + return {}; + std::sort(mems.begin(), mems.end(), sort_mem_region); - std::vector>::iterator it = mems.begin() + 1; - while (it != mems.end()) { - reg_t start = prev(it)->first; - reg_t end = prev(it)->first + prev(it)->second->size(); - reg_t start2 = it->first; - reg_t end2 = it->first + it->second->size(); + std::vector merged_mem; + merged_mem.push_back(mems.front()); - //contains -> remove - if (start2 >= start && end2 <= end) { - it = mems.erase(it); - //parital overlapped -> extend - } else if (start2 >= start && start2 < end) { - delete prev(it)->second; - prev(it)->second = new mem_t(std::max(end, end2) - start); - it = mems.erase(it); - // no overlapping -> keep it - } else { - it++; + for (auto mem_it = std::next(mems.begin()); mem_it != mems.end(); ++mem_it) { + const auto& mem_int = *mem_it; + if (!check_mem_overlap(merged_mem.back(), mem_int)) { + merged_mem.push_back(mem_int); + continue; } + // there is a weird corner case preventing two memory regions from being + // merged: if the resulting size of a region is 2^64 bytes - currently, + // such regions are not representable by mem_cfg_t class (because the + // actual size field is effectively a 64 bit value) + // so we create two smaller memory regions that total for 2^64 bytes as + // a workaround + if (check_if_merge_covers_64bit_space(merged_mem.back(), mem_int)) { + merged_mem.clear(); + merged_mem.push_back(mem_cfg_t(0ull, 0ull - PGSIZE)); + merged_mem.push_back(mem_cfg_t(0ull - PGSIZE, PGSIZE)); + break; + } + merged_mem.back() = merge_mem_regions(merged_mem.back(), mem_int); } + + return merged_mem; } -static std::vector> make_mems(const char* arg) +static std::vector parse_mem_layout(const char* arg) { + std::vector res; + // handle legacy mem argument char* p; auto mb = strtoull(arg, &p, 0); @@ -151,11 +204,11 @@ static std::vector> make_mems(const char* arg) reg_t size = reg_t(mb) << 20; if (size != (size_t)size) throw std::runtime_error("Size would overflow size_t"); - return std::vector>(1, std::make_pair(reg_t(DRAM_BASE), new mem_t(size))); + res.push_back(mem_cfg_t(reg_t(DRAM_BASE), size)); + return res; } // handle base/size tuples - std::vector> res; while (true) { auto base = strtoull(arg, &p, 0); if (!*p || *p != ':') @@ -169,16 +222,36 @@ static std::vector> make_mems(const char* arg) if (size % PGSIZE != 0) size += PGSIZE - size % PGSIZE; - if (base + size < base) - help(); - if (size != size0) { - fprintf(stderr, "Warning: the memory at [0x%llX, 0x%llX] has been realigned\n" + fprintf(stderr, "Warning: the memory at [0x%llX, 0x%llX] has been realigned\n" "to the %ld KiB page size: [0x%llX, 0x%llX]\n", base0, base0 + size0 - 1, long(PGSIZE / 1024), base, base + size - 1); } - res.push_back(std::make_pair(reg_t(base), new mem_t(size))); + if (!mem_cfg_t::check_if_supported(base, size)) { + fprintf(stderr, "Unsupported memory region " + "{base = 0x%llX, size = 0x%llX} specified\n", + base, size); + exit(EXIT_FAILURE); + } + + const unsigned long long max_allowed_pa = (1ull << MAX_PADDR_BITS) - 1ull; + assert(max_allowed_pa <= std::numeric_limits::max()); + mem_cfg_t mem_region(base, size); + if (mem_region.get_inclusive_end() > max_allowed_pa) { + int bits_required = 64 - clz(mem_region.get_inclusive_end()); + fprintf(stderr, "Unsupported memory region " + "{base = 0x%" PRIX64 ", size = 0x%" PRIX64 "} specified," + " which requires %d bits of physical address\n" + " The largest accessible physical address " + "is 0x%llX (defined by MAX_PADDR_BITS constant, which is %d)\n", + mem_region.get_base(), mem_region.get_size(), bits_required, + max_allowed_pa, MAX_PADDR_BITS); + exit(EXIT_FAILURE); + } + + res.push_back(mem_region); + if (!*p) break; if (*p != ',') @@ -186,8 +259,20 @@ static std::vector> make_mems(const char* arg) arg = p + 1; } - merge_overlapping_memory_regions(res); - return res; + auto merged_mem = merge_overlapping_memory_regions(res); + + assert(!merged_mem.empty()); + return merged_mem; +} + +static std::vector> make_mems(const std::vector &layout) +{ + std::vector> mems; + mems.reserve(layout.size()); + for (const auto &cfg : layout) { + mems.push_back(std::make_pair(cfg.get_base(), new mem_t(cfg.get_size()))); + } + return mems; } static unsigned long atoul_safe(const char* s) @@ -207,24 +292,50 @@ static unsigned long atoul_nonzero_safe(const char* s) return res; } +static std::vector parse_hartids(const char *s) +{ + std::string const str(s); + std::stringstream stream(str); + std::vector hartids; + + int n; + while (stream >> n) { + if (n < 0) { + fprintf(stderr, "Negative hart ID %d is unsupported\n", n); + exit(-1); + } + + hartids.push_back(n); + if (stream.peek() == ',') stream.ignore(); + } + + if (hartids.empty()) { + fprintf(stderr, "No hart IDs specified\n"); + exit(-1); + } + + std::sort(hartids.begin(), hartids.end()); + + const auto dup = std::adjacent_find(hartids.begin(), hartids.end()); + if (dup != hartids.end()) { + fprintf(stderr, "Duplicate hart ID %zu\n", *dup); + exit(-1); + } + + return hartids; +} + int main(int argc, char** argv) { bool debug = false; bool halted = false; bool histogram = false; bool log = false; - bool socket = false; // command line option -s + bool UNUSED socket = false; // command line option -s bool dump_dts = false; bool dtb_enabled = true; - bool real_time_clint = false; - size_t nprocs = 1; const char* kernel = NULL; reg_t kernel_offset, kernel_size; - size_t initrd_size; - reg_t initrd_start = 0, initrd_end = 0; - const char* bootargs = NULL; - reg_t start_pc = reg_t(-1); - std::vector> mems; std::vector> plugin_devices; std::unique_ptr ic; std::unique_ptr dc; @@ -234,13 +345,11 @@ int main(int argc, char** argv) const char *log_path = nullptr; std::vector> extensions; const char* initrd = NULL; - const char* isa = DEFAULT_ISA; - const char* priv = DEFAULT_PRIV; - const char* varch = DEFAULT_VARCH; const char* dtb_file = NULL; uint16_t rbb_port = 0; bool use_rbb = false; unsigned dmi_rti = 0; + reg_t blocksz = 64; debug_module_config_t dm_config = { .progbufsize = 2, .max_sba_data_width = 0, @@ -248,22 +357,24 @@ int main(int argc, char** argv) .abstract_rti = 0, .support_hasel = true, .support_abstract_csr_access = true, + .support_abstract_fpr_access = true, .support_haltgroups = true, .support_impebreak = true }; - std::vector hartids; + cfg_arg_t nprocs(1); - auto const hartids_parser = [&](const char *s) { - std::string const str(s); - std::stringstream stream(str); - - int n; - while (stream >> n) - { - hartids.push_back(n); - if (stream.peek() == ',') stream.ignore(); - } - }; + cfg_t cfg(/*default_initrd_bounds=*/std::make_pair((reg_t)0, (reg_t)0), + /*default_bootargs=*/nullptr, + /*default_isa=*/DEFAULT_ISA, + /*default_priv=*/DEFAULT_PRIV, + /*default_varch=*/DEFAULT_VARCH, + /*default_misaligned=*/false, + /*default_endianness*/endianness_little, + /*default_pmpregions=*/16, + /*default_mem_layout=*/parse_mem_layout("2048"), + /*default_hartids=*/std::vector(), + /*default_real_time_clint=*/false, + /*default_trigger_count=*/4); auto const device_parser = [&plugin_devices](const char *s) { const std::string str(s); @@ -310,36 +421,43 @@ int main(int argc, char** argv) option_parser_t parser; parser.help(&suggest_help); - parser.option('h', "help", 0, [&](const char* s){help(0);}); - parser.option('d', 0, 0, [&](const char* s){debug = true;}); - parser.option('g', 0, 0, [&](const char* s){histogram = true;}); - parser.option('l', 0, 0, [&](const char* s){log = true;}); + parser.option('h', "help", 0, [&](const char UNUSED *s){help(0);}); + parser.option('d', 0, 0, [&](const char UNUSED *s){debug = true;}); + parser.option('g', 0, 0, [&](const char UNUSED *s){histogram = true;}); + parser.option('l', 0, 0, [&](const char UNUSED *s){log = true;}); #ifdef HAVE_BOOST_ASIO - parser.option('s', 0, 0, [&](const char* s){socket = true;}); + parser.option('s', 0, 0, [&](const char UNUSED *s){socket = true;}); #endif parser.option('p', 0, 1, [&](const char* s){nprocs = atoul_nonzero_safe(s);}); - parser.option('m', 0, 1, [&](const char* s){mems = make_mems(s);}); + parser.option('m', 0, 1, [&](const char* s){cfg.mem_layout = parse_mem_layout(s);}); // I wanted to use --halted, but for some reason that doesn't work. - parser.option('H', 0, 0, [&](const char* s){halted = true;}); + parser.option('H', 0, 0, [&](const char UNUSED *s){halted = true;}); parser.option(0, "rbb-port", 1, [&](const char* s){use_rbb = true; rbb_port = atoul_safe(s);}); - parser.option(0, "pc", 1, [&](const char* s){start_pc = strtoull(s, 0, 0);}); - parser.option(0, "hartids", 1, hartids_parser); + parser.option(0, "pc", 1, [&](const char* s){cfg.start_pc = strtoull(s, 0, 0);}); + parser.option(0, "hartids", 1, [&](const char* s){ + cfg.hartids = parse_hartids(s); + cfg.explicit_hartids = true; + }); parser.option(0, "ic", 1, [&](const char* s){ic.reset(new icache_sim_t(s));}); parser.option(0, "dc", 1, [&](const char* s){dc.reset(new dcache_sim_t(s));}); parser.option(0, "l2", 1, [&](const char* s){l2.reset(cache_sim_t::construct(s, "L2$"));}); - parser.option(0, "log-cache-miss", 0, [&](const char* s){log_cache = true;}); - parser.option(0, "isa", 1, [&](const char* s){isa = s;}); - parser.option(0, "priv", 1, [&](const char* s){priv = s;}); - parser.option(0, "varch", 1, [&](const char* s){varch = s;}); + parser.option(0, "big-endian", 0, [&](const char UNUSED *s){cfg.endianness = endianness_big;}); + parser.option(0, "misaligned", 0, [&](const char UNUSED *s){cfg.misaligned = true;}); + parser.option(0, "log-cache-miss", 0, [&](const char UNUSED *s){log_cache = true;}); + parser.option(0, "isa", 1, [&](const char* s){cfg.isa = s;}); + parser.option(0, "pmpregions", 1, [&](const char* s){cfg.pmpregions = atoul_safe(s);}); + parser.option(0, "priv", 1, [&](const char* s){cfg.priv = s;}); + parser.option(0, "varch", 1, [&](const char* s){cfg.varch = s;}); parser.option(0, "device", 1, device_parser); parser.option(0, "extension", 1, [&](const char* s){extensions.push_back(find_extension(s));}); - parser.option(0, "dump-dts", 0, [&](const char *s){dump_dts = true;}); - parser.option(0, "disable-dtb", 0, [&](const char *s){dtb_enabled = false;}); + parser.option(0, "dump-dts", 0, [&](const char UNUSED *s){dump_dts = true;}); + parser.option(0, "disable-dtb", 0, [&](const char UNUSED *s){dtb_enabled = false;}); parser.option(0, "dtb", 1, [&](const char *s){dtb_file = s;}); parser.option(0, "kernel", 1, [&](const char* s){kernel = s;}); parser.option(0, "initrd", 1, [&](const char* s){initrd = s;}); - parser.option(0, "bootargs", 1, [&](const char* s){bootargs = s;}); - parser.option(0, "real-time-clint", 0, [&](const char *s){real_time_clint = true;}); + parser.option(0, "bootargs", 1, [&](const char* s){cfg.bootargs = s;}); + parser.option(0, "real-time-clint", 0, [&](const char UNUSED *s){cfg.real_time_clint = true;}); + parser.option(0, "triggers", 1, [&](const char *s){cfg.trigger_count = atoul_safe(s);}); parser.option(0, "extlib", 1, [&](const char *s){ void *lib = dlopen(s, RTLD_NOW | RTLD_GLOBAL); if (lib == NULL) { @@ -350,23 +468,25 @@ int main(int argc, char** argv) parser.option(0, "dm-progsize", 1, [&](const char* s){dm_config.progbufsize = atoul_safe(s);}); parser.option(0, "dm-no-impebreak", 0, - [&](const char* s){dm_config.support_impebreak = false;}); + [&](const char UNUSED *s){dm_config.support_impebreak = false;}); parser.option(0, "dm-sba", 1, [&](const char* s){dm_config.max_sba_data_width = atoul_safe(s);}); parser.option(0, "dm-auth", 0, - [&](const char* s){dm_config.require_authentication = true;}); + [&](const char UNUSED *s){dm_config.require_authentication = true;}); parser.option(0, "dmi-rti", 1, [&](const char* s){dmi_rti = atoul_safe(s);}); parser.option(0, "dm-abstract-rti", 1, [&](const char* s){dm_config.abstract_rti = atoul_safe(s);}); parser.option(0, "dm-no-hasel", 0, - [&](const char* s){dm_config.support_hasel = false;}); + [&](const char UNUSED *s){dm_config.support_hasel = false;}); parser.option(0, "dm-no-abstract-csr", 0, - [&](const char* s){dm_config.support_abstract_csr_access = false;}); + [&](const char UNUSED *s){dm_config.support_abstract_csr_access = false;}); + parser.option(0, "dm-no-abstract-fpr", 0, + [&](const char UNUSED *s){dm_config.support_abstract_fpr_access = false;}); parser.option(0, "dm-no-halt-groups", 0, - [&](const char* s){dm_config.support_haltgroups = false;}); + [&](const char UNUSED *s){dm_config.support_haltgroups = false;}); parser.option(0, "log-commits", 0, - [&](const char* s){log_commits = true;}); + [&](const char UNUSED *s){log_commits = true;}); parser.option(0, "log", 1, [&](const char* s){log_path = s;}); FILE *cmd_file = NULL; @@ -376,16 +496,27 @@ int main(int argc, char** argv) exit(-1); } }); + parser.option(0, "blocksz", 1, [&](const char* s){ + blocksz = strtoull(s, 0, 0); + const unsigned min_blocksz = 16; + const unsigned max_blocksz = PGSIZE; + if (blocksz < min_blocksz || blocksz > max_blocksz || ((blocksz & (blocksz - 1))) != 0) { + fprintf(stderr, "--blocksz must be a power of 2 between %u and %u\n", + min_blocksz, max_blocksz); + exit(-1); + } + }); auto argv1 = parser.parse(argv); std::vector htif_args(argv1, (const char*const*)argv + argc); - if (mems.empty()) - mems = make_mems("2048"); if (!*argv1) help(); + std::vector> mems = make_mems(cfg.mem_layout()); + if (kernel && check_file_exists(kernel)) { + const char *isa = cfg.isa(); kernel_size = get_file_size(kernel); if (isa[2] == '6' && isa[3] == '4') kernel_offset = 0x200000; @@ -400,46 +531,41 @@ int main(int argc, char** argv) } if (initrd && check_file_exists(initrd)) { - initrd_size = get_file_size(initrd); + size_t initrd_size = get_file_size(initrd); for (auto& m : mems) { if (initrd_size && (initrd_size + 0x1000) < m.second->size()) { - initrd_end = m.first + m.second->size() - 0x1000; - initrd_start = initrd_end - initrd_size; + reg_t initrd_end = m.first + m.second->size() - 0x1000; + reg_t initrd_start = initrd_end - initrd_size; + cfg.initrd_bounds = std::make_pair(initrd_start, initrd_end); read_file_bytes(initrd, 0, m.second, initrd_start - m.first, initrd_size); break; } } } -#ifdef HAVE_BOOST_ASIO - boost::asio::io_service *io_service_ptr = NULL; // needed for socket command interface option -s - boost::asio::ip::tcp::acceptor *acceptor_ptr = NULL; - if (socket) { // if command line option -s is set - try - { // create socket server - using boost::asio::ip::tcp; - io_service_ptr = new boost::asio::io_service; - acceptor_ptr = new tcp::acceptor(*io_service_ptr, tcp::endpoint(tcp::v4(), 0)); - // aceptor is created passing argument port=0, so O.S. will choose a free port - std::string name = boost::asio::ip::host_name(); - std::cout << "Listening for debug commands on " << name.substr(0,name.find('.')) - << " port " << acceptor_ptr->local_endpoint().port() << " ." << std::endl; - // at the end, add space and some other character for convenience of javascript .split(" ") - } - catch (std::exception& e) - { - std::cerr << e.what() << std::endl; - exit(-1); - } + if (cfg.explicit_hartids) { + if (nprocs.overridden() && (nprocs() != cfg.nprocs())) { + std::cerr << "Number of specified hartids (" + << cfg.nprocs() + << ") doesn't match specified number of processors (" + << nprocs() << ").\n"; + exit(1); + } + } else { + // Set default set of hartids based on nprocs, but don't set the + // explicit_hartids flag (which means that downstream code can know that + // we've only set the number of harts, not explicitly chosen their IDs). + std::vector default_hartids; + default_hartids.reserve(nprocs()); + for (size_t i = 0; i < nprocs(); ++i) { + default_hartids.push_back(i); + } + cfg.hartids = default_hartids; } -#endif - sim_t s(isa, priv, varch, nprocs, halted, real_time_clint, - initrd_start, initrd_end, bootargs, start_pc, mems, plugin_devices, htif_args, - std::move(hartids), dm_config, log_path, dtb_enabled, dtb_file, -#ifdef HAVE_BOOST_ASIO - io_service_ptr, acceptor_ptr, -#endif + sim_t s(&cfg, halted, + mems, plugin_devices, htif_args, dm_config, log_path, dtb_enabled, dtb_file, + socket, cmd_file); std::unique_ptr remote_bitbang((remote_bitbang_t *) NULL); std::unique_ptr jtag_dtm( @@ -458,12 +584,13 @@ int main(int argc, char** argv) if (dc && l2) dc->set_miss_handler(&*l2); if (ic) ic->set_log(log_cache); if (dc) dc->set_log(log_cache); - for (size_t i = 0; i < nprocs; i++) + for (size_t i = 0; i < cfg.nprocs(); i++) { if (ic) s.get_core(i)->get_mmu()->register_memtracer(&*ic); if (dc) s.get_core(i)->get_mmu()->register_memtracer(&*dc); for (auto e : extensions) s.get_core(i)->register_extension(e()); + s.get_core(i)->get_mmu()->set_cache_blocksz(blocksz); } s.set_debug(debug); diff --git a/vendor/riscv/riscv-isa-sim/spike_main/spike_main.mk.in b/vendor/riscv/riscv-isa-sim/spike_main/spike_main.mk.in index 35bef398c..25a7a6c61 100644 --- a/vendor/riscv/riscv-isa-sim/spike_main/spike_main.mk.in +++ b/vendor/riscv/riscv-isa-sim/spike_main/spike_main.mk.in @@ -11,6 +11,6 @@ spike_main_install_prog_srcs = \ xspike.cc \ termios-xspike.cc \ -spike_main_hdrs = \ - spike_main_srcs = \ + +spike_main_CFLAGS = -fPIC diff --git a/vendor/riscv/riscv-isa-sim/spike_main/xspike.cc b/vendor/riscv/riscv-isa-sim/spike_main/xspike.cc index f8c8ca7e3..661a2067d 100644 --- a/vendor/riscv/riscv-isa-sim/spike_main/xspike.cc +++ b/vendor/riscv/riscv-isa-sim/spike_main/xspike.cc @@ -3,6 +3,7 @@ // xspike forks an xterm for spike's target machine console, // preserving the current terminal for debugging. +#include "common.h" #include #include #include @@ -12,10 +13,10 @@ #include #include -static pid_t fork_spike(int tty_fd, int argc, char** argv); +static pid_t fork_spike(int tty_fd, char** argv); static pid_t fork_xterm(int* tty_fd); -int main(int argc, char** argv) +int main(int UNUSED argc, char** argv) { int tty_fd, wait_status, ret = -1; pid_t xterm, spike; @@ -31,7 +32,7 @@ int main(int argc, char** argv) signal(SIGINT, handle_signal); - if ((spike = fork_spike(tty_fd, argc, argv)) < 0) + if ((spike = fork_spike(tty_fd, argv)) < 0) { fprintf(stderr, "could not open spike\n"); goto close_xterm; @@ -52,7 +53,7 @@ out: return ret; } -static pid_t fork_spike(int tty_fd, int argc, char** argv) +static pid_t fork_spike(int tty_fd, char** argv) { pid_t pid = fork(); if (pid < 0) diff --git a/vendor/riscv_riscv-isa-sim.lock.hjson b/vendor/riscv_riscv-isa-sim.lock.hjson index 2bf1d4499..90c711408 100644 --- a/vendor/riscv_riscv-isa-sim.lock.hjson +++ b/vendor/riscv_riscv-isa-sim.lock.hjson @@ -9,6 +9,6 @@ upstream: { url: https://github.com/riscv/riscv-isa-sim.git - rev: e93b9cbbbcd3ad0a02ae298e9f1a2d98d3ac0153 + rev: fcbdbe7946079650d0e656fa3d353e3f652d471f } } diff --git a/vendor/riscv_riscv-isa-sim.vendor.hjson b/vendor/riscv_riscv-isa-sim.vendor.hjson index d72447986..981f11b94 100644 --- a/vendor/riscv_riscv-isa-sim.vendor.hjson +++ b/vendor/riscv_riscv-isa-sim.vendor.hjson @@ -15,11 +15,11 @@ // URL url: "https://github.com/riscv/riscv-isa-sim.git", // revision - rev: "e93b9cbbbcd3ad0a02ae298e9f1a2d98d3ac0153", + rev: "fcbdbe7946079650d0e656fa3d353e3f652d471f", } // Patch dir for local changes - patch_dir: "patches/riscv-isa-sim", + patch_dir: "patches/riscv/riscv-isa-sim", // Exclusions from upstream content exclude_from_upstream: [