From: Andrew Waterman Date: Sat, 4 Apr 2015 04:53:22 +0000 (-0700) Subject: Support setting ISA/subsets with --isa flag X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c4350ef6ef6259e48509e125fd2d051969dc6efa;p=riscv-isa-sim.git Support setting ISA/subsets with --isa flag Default is RV64IMAFDC. Can do things like --isa=RV32 (which implies IMAFDC) --isa=IM (which implies RV64) --isa=RV64IMAFDXhwacha --- diff --git a/config.h.in b/config.h.in index 5293fa8..f5608c5 100644 --- a/config.h.in +++ b/config.h.in @@ -33,21 +33,12 @@ /* Define if subproject MCPPBS_SPROJ_NORM is enabled */ #undef RISCV_ENABLED -/* Define if 64-bit mode is supported */ -#undef RISCV_ENABLE_64BIT - /* Enable commit log generation */ #undef RISCV_ENABLE_COMMITLOG -/* Define if floating-point instructions are supported */ -#undef RISCV_ENABLE_FPU - /* Enable PC histogram generation */ #undef RISCV_ENABLE_HISTOGRAM -/* Define if RISC-V Compressed is supported */ -#undef RISCV_ENABLE_RVC - /* Define if subproject MCPPBS_SPROJ_NORM is enabled */ #undef SOFTFLOAT_ENABLED diff --git a/configure b/configure index bed5307..5db4d53 100755 --- a/configure +++ b/configure @@ -664,9 +664,6 @@ enable_option_checking enable_stow enable_optional_subprojects with_fesvr -enable_fpu -enable_rvc -enable_64bit enable_commitlog enable_histogram ' @@ -1300,9 +1297,6 @@ Optional Features: --enable-stow Enable stow-based install --enable-optional-subprojects Enable all optional subprojects - --disable-fpu Disable floating-point - --disable-rvc Disable RISC-V Compressed - --disable-64bit Disable 64-bit mode --enable-commitlog Enable commit log generation --enable-histogram Enable PC histogram generation @@ -3979,6 +3973,67 @@ ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ex ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dlopen" >&5 +$as_echo_n "checking for library containing dlopen... " >&6; } +if ${ac_cv_search_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +for ac_lib in '' dl dld; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_cxx_try_link "$LINENO"; then : + ac_cv_search_dlopen=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_dlopen+:} false; then : + break +fi +done +if ${ac_cv_search_dlopen+:} false; then : + +else + ac_cv_search_dlopen=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_dlopen" >&5 +$as_echo "$ac_cv_search_dlopen" >&6; } +ac_res=$ac_cv_search_dlopen +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +else + + as_fn_error $? "unable to find the dlopen() function" "$LINENO" 5 + +fi + + # Check whether --with-fesvr was given. if test "${with_fesvr+set}" = set; then : @@ -4086,45 +4141,6 @@ else fi -# Check whether --enable-fpu was given. -if test "${enable_fpu+set}" = set; then : - enableval=$enable_fpu; -fi - -if test "x$enable_fpu" != "xno"; then : - - -$as_echo "#define RISCV_ENABLE_FPU /**/" >>confdefs.h - - -fi - -# Check whether --enable-rvc was given. -if test "${enable_rvc+set}" = set; then : - enableval=$enable_rvc; -fi - -if test "x$enable_rvc" != "xno"; then : - - -$as_echo "#define RISCV_ENABLE_RVC /**/" >>confdefs.h - - -fi - -# Check whether --enable-64bit was given. -if test "${enable_64bit+set}" = set; then : - enableval=$enable_64bit; -fi - -if test "x$enable_64bit" != "xno"; then : - - -$as_echo "#define RISCV_ENABLE_64BIT /**/" >>confdefs.h - - -fi - # Check whether --enable-commitlog was given. if test "${enable_commitlog+set}" = set; then : enableval=$enable_commitlog; @@ -4330,66 +4346,6 @@ $as_echo "$as_me: configuring default subproject : spike_main" >&6;} $as_echo "#define SPIKE_MAIN_ENABLED /**/" >>confdefs.h - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dlopen" >&5 -$as_echo_n "checking for library containing dlopen... " >&6; } -if ${ac_cv_search_dlopen+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char dlopen (); -int -main () -{ -return dlopen (); - ; - return 0; -} -_ACEOF -for ac_lib in '' dl dld; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_cxx_try_link "$LINENO"; then : - ac_cv_search_dlopen=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if ${ac_cv_search_dlopen+:} false; then : - break -fi -done -if ${ac_cv_search_dlopen+:} false; then : - -else - ac_cv_search_dlopen=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_dlopen" >&5 -$as_echo "$ac_cv_search_dlopen" >&6; } -ac_res=$ac_cv_search_dlopen -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -else - - as_fn_error $? "unable to find the dlopen() function" "$LINENO" 5 - -fi - diff --git a/riscv/decode.h b/riscv/decode.h index 55f03ff..4d4c447 100644 --- a/riscv/decode.h +++ b/riscv/decode.h @@ -45,14 +45,6 @@ const int NFPR = 32; #define FSR_NXA (FPEXC_NX << FSR_AEXC_SHIFT) #define FSR_AEXC (FSR_NVA | FSR_OFA | FSR_UFA | FSR_DZA | FSR_NXA) -#ifdef RISCV_ENABLE_RVC -# define INSN_ALIGNMENT 2 -# define require_rvc -#else -# define INSN_ALIGNMENT 4 -# define require_rvc throw trap_illegal_instruction() -#endif - #define insn_length(x) \ (((x) & 0x03) < 0x03 ? 2 : \ ((x) & 0x1f) < 0x1f ? 4 : \ @@ -173,11 +165,8 @@ private: #define require_privilege(p) if (get_field(STATE.mstatus, MSTATUS_PRV) < (p)) throw trap_illegal_instruction() #define require_rv64 if(unlikely(xlen != 64)) throw trap_illegal_instruction() #define require_rv32 if(unlikely(xlen != 32)) throw trap_illegal_instruction() -#ifdef RISCV_ENABLE_FPU -# define require_fp if (unlikely((STATE.mstatus & MSTATUS_FS) == 0)) throw trap_illegal_instruction() -#else -# define require_fp throw trap_illegal_instruction() -#endif +#define require_extension(s) if (!p->supports_extension(s)) throw trap_illegal_instruction() +#define require_fp if (unlikely((STATE.mstatus & MSTATUS_FS) == 0)) throw trap_illegal_instruction() #define require_accelerator if (unlikely((STATE.mstatus & MSTATUS_XS) == 0)) throw trap_illegal_instruction() #define set_fp_exceptions ({ STATE.fflags |= softfloat_exceptionFlags; \ @@ -189,7 +178,7 @@ private: #define zext_xlen(x) (((reg_t)(x) << (64-xlen)) >> (64-xlen)) #define set_pc(x) \ - do { if ((x) & (INSN_ALIGNMENT-1)) \ + do { if (unlikely(((x) & 2)) && !p->supports_extension('C')) \ throw trap_instruction_address_misaligned(x); \ npc = sext_xlen(x); \ } while(0) diff --git a/riscv/encoding.h b/riscv/encoding.h index 0c83ca2..8891ab3 100644 --- a/riscv/encoding.h +++ b/riscv/encoding.h @@ -48,7 +48,8 @@ #define VM_MBB 1 #define VM_MBBID 2 #define VM_SV32 4 -#define VM_SV43 5 +#define VM_SV39 5 +#define VM_SV48 6 #define UA_RV32 0 #define UA_RV64 4 @@ -69,7 +70,8 @@ #define PTE_R 0x040 // Referenced #define PTE_D 0x080 // Dirty #define PTE_SOFT 0x300 // Reserved for Software -#define PTE_PPN_SHIFT 10 +#define RV64_PTE_PPN_SHIFT 26 +#define RV32_PTE_PPN_SHIFT 10 #define PTE_TYPE_INVALID 0 #define PTE_TYPE_TABLE 1 #define PTE_TYPE_U 2 @@ -105,13 +107,13 @@ # define MSTATUS_HA MSTATUS64_HA # define MSTATUS_SD MSTATUS64_SD # define SSTATUS_SD SSTATUS64_SD -# define RISCV_PGLEVELS 3 /* Sv39 */ # define RISCV_PGLEVEL_BITS 9 +# define PTE_PPN_SHIFT RV64_PTE_PPN_SHIFT #else # define MSTATUS_SD MSTATUS32_SD # define SSTATUS_SD SSTATUS32_SD -# define RISCV_PGLEVELS 2 /* Sv32 */ # define RISCV_PGLEVEL_BITS 10 +# define PTE_PPN_SHIFT RV32_PTE_PPN_SHIFT #endif #define RISCV_PGSHIFT 12 #define RISCV_PGSIZE (1 << RISCV_PGSHIFT) diff --git a/riscv/extensions.cc b/riscv/extensions.cc new file mode 100644 index 0000000..315621f --- /dev/null +++ b/riscv/extensions.cc @@ -0,0 +1,35 @@ +#include "extension.h" +#include +#include +#include + +static std::map>& extensions() +{ + static std::map> v; + return v; +} + +void register_extension(const char* name, std::function f) +{ + extensions()[name] = f; +} + +std::function find_extension(const char* name) +{ + if (!extensions().count(name)) { + // try to find extension xyz by loading libxyz.so + std::string libname = std::string("lib") + name + ".so"; + if (!dlopen(libname.c_str(), RTLD_LAZY)) { + fprintf(stderr, "couldn't find extension '%s' (or library '%s')\n", + name, libname.c_str()); + exit(-1); + } + if (!extensions().count(name)) { + fprintf(stderr, "couldn't find extension '%s' in shared library '%s'\n", + name, libname.c_str()); + exit(-1); + } + } + + return extensions()[name]; +} diff --git a/riscv/insns/amoadd_d.h b/riscv/insns/amoadd_d.h index c6bacaf..9c7c124 100644 --- a/riscv/insns/amoadd_d.h +++ b/riscv/insns/amoadd_d.h @@ -1,3 +1,4 @@ +require_extension('A'); require_rv64; reg_t v = MMU.load_uint64(RS1); MMU.store_uint64(RS1, RS2 + v); diff --git a/riscv/insns/amoadd_w.h b/riscv/insns/amoadd_w.h index 8eb9e2b..7ac59b0 100644 --- a/riscv/insns/amoadd_w.h +++ b/riscv/insns/amoadd_w.h @@ -1,3 +1,4 @@ +require_extension('A'); reg_t v = MMU.load_int32(RS1); MMU.store_uint32(RS1, RS2 + v); WRITE_RD(v); diff --git a/riscv/insns/amoand_d.h b/riscv/insns/amoand_d.h index d896ec1..7aa6386 100644 --- a/riscv/insns/amoand_d.h +++ b/riscv/insns/amoand_d.h @@ -1,3 +1,4 @@ +require_extension('A'); require_rv64; reg_t v = MMU.load_uint64(RS1); MMU.store_uint64(RS1, RS2 & v); diff --git a/riscv/insns/amoand_w.h b/riscv/insns/amoand_w.h index 32ea7f7..7db2160 100644 --- a/riscv/insns/amoand_w.h +++ b/riscv/insns/amoand_w.h @@ -1,3 +1,4 @@ +require_extension('A'); reg_t v = MMU.load_int32(RS1); MMU.store_uint32(RS1, RS2 & v); WRITE_RD(v); diff --git a/riscv/insns/amomax_d.h b/riscv/insns/amomax_d.h index 0a66214..0f6da18 100644 --- a/riscv/insns/amomax_d.h +++ b/riscv/insns/amomax_d.h @@ -1,3 +1,4 @@ +require_extension('A'); require_rv64; sreg_t v = MMU.load_int64(RS1); MMU.store_uint64(RS1, std::max(sreg_t(RS2),v)); diff --git a/riscv/insns/amomax_w.h b/riscv/insns/amomax_w.h index a255116..8c9222b 100644 --- a/riscv/insns/amomax_w.h +++ b/riscv/insns/amomax_w.h @@ -1,3 +1,4 @@ +require_extension('A'); int32_t v = MMU.load_int32(RS1); MMU.store_uint32(RS1, std::max(int32_t(RS2),v)); WRITE_RD(v); diff --git a/riscv/insns/amomaxu_d.h b/riscv/insns/amomaxu_d.h index dbdb1d2..6760f91 100644 --- a/riscv/insns/amomaxu_d.h +++ b/riscv/insns/amomaxu_d.h @@ -1,3 +1,4 @@ +require_extension('A'); require_rv64; reg_t v = MMU.load_uint64(RS1); MMU.store_uint64(RS1, std::max(RS2,v)); diff --git a/riscv/insns/amomaxu_w.h b/riscv/insns/amomaxu_w.h index 448814b..fc83dc3 100644 --- a/riscv/insns/amomaxu_w.h +++ b/riscv/insns/amomaxu_w.h @@ -1,3 +1,4 @@ +require_extension('A'); uint32_t v = MMU.load_int32(RS1); MMU.store_uint32(RS1, std::max(uint32_t(RS2),v)); WRITE_RD((int32_t)v); diff --git a/riscv/insns/amomin_d.h b/riscv/insns/amomin_d.h index 2ad8eef..8d08984 100644 --- a/riscv/insns/amomin_d.h +++ b/riscv/insns/amomin_d.h @@ -1,3 +1,4 @@ +require_extension('A'); require_rv64; sreg_t v = MMU.load_int64(RS1); MMU.store_uint64(RS1, std::min(sreg_t(RS2),v)); diff --git a/riscv/insns/amomin_w.h b/riscv/insns/amomin_w.h index 28efa15..31a8df8 100644 --- a/riscv/insns/amomin_w.h +++ b/riscv/insns/amomin_w.h @@ -1,3 +1,4 @@ +require_extension('A'); int32_t v = MMU.load_int32(RS1); MMU.store_uint32(RS1, std::min(int32_t(RS2),v)); WRITE_RD(v); diff --git a/riscv/insns/amominu_d.h b/riscv/insns/amominu_d.h index 88fe724..8a77edc 100644 --- a/riscv/insns/amominu_d.h +++ b/riscv/insns/amominu_d.h @@ -1,3 +1,4 @@ +require_extension('A'); require_rv64; reg_t v = MMU.load_uint64(RS1); MMU.store_uint64(RS1, std::min(RS2,v)); diff --git a/riscv/insns/amominu_w.h b/riscv/insns/amominu_w.h index 459b201..2b6aaa3 100644 --- a/riscv/insns/amominu_w.h +++ b/riscv/insns/amominu_w.h @@ -1,3 +1,4 @@ +require_extension('A'); uint32_t v = MMU.load_int32(RS1); MMU.store_uint32(RS1, std::min(uint32_t(RS2),v)); WRITE_RD((int32_t)v); diff --git a/riscv/insns/amoor_d.h b/riscv/insns/amoor_d.h index 58a64e0..5a69717 100644 --- a/riscv/insns/amoor_d.h +++ b/riscv/insns/amoor_d.h @@ -1,3 +1,4 @@ +require_extension('A'); require_rv64; reg_t v = MMU.load_uint64(RS1); MMU.store_uint64(RS1, RS2 | v); diff --git a/riscv/insns/amoor_w.h b/riscv/insns/amoor_w.h index c178f9a..f5b96b9 100644 --- a/riscv/insns/amoor_w.h +++ b/riscv/insns/amoor_w.h @@ -1,3 +1,4 @@ +require_extension('A'); reg_t v = MMU.load_int32(RS1); MMU.store_uint32(RS1, RS2 | v); WRITE_RD(v); diff --git a/riscv/insns/amoswap_d.h b/riscv/insns/amoswap_d.h index 9f34eaa..8cf1411 100644 --- a/riscv/insns/amoswap_d.h +++ b/riscv/insns/amoswap_d.h @@ -1,3 +1,4 @@ +require_extension('A'); require_rv64; reg_t v = MMU.load_uint64(RS1); MMU.store_uint64(RS1, RS2); diff --git a/riscv/insns/amoswap_w.h b/riscv/insns/amoswap_w.h index 148b5bc..0764d59 100644 --- a/riscv/insns/amoswap_w.h +++ b/riscv/insns/amoswap_w.h @@ -1,3 +1,4 @@ +require_extension('A'); reg_t v = MMU.load_int32(RS1); MMU.store_uint32(RS1, RS2); WRITE_RD(v); diff --git a/riscv/insns/amoxor_d.h b/riscv/insns/amoxor_d.h index acd8b61..3970822 100644 --- a/riscv/insns/amoxor_d.h +++ b/riscv/insns/amoxor_d.h @@ -1,3 +1,4 @@ +require_extension('A'); require_rv64; reg_t v = MMU.load_uint64(RS1); MMU.store_uint64(RS1, RS2 ^ v); diff --git a/riscv/insns/amoxor_w.h b/riscv/insns/amoxor_w.h index 3a87b6e..9889b64 100644 --- a/riscv/insns/amoxor_w.h +++ b/riscv/insns/amoxor_w.h @@ -1,3 +1,4 @@ +require_extension('A'); reg_t v = MMU.load_int32(RS1); MMU.store_uint32(RS1, RS2 ^ v); WRITE_RD(v); diff --git a/riscv/insns/c_add.h b/riscv/insns/c_add.h index b2ba34f..c349fc0 100644 --- a/riscv/insns/c_add.h +++ b/riscv/insns/c_add.h @@ -1,2 +1,2 @@ -require_rvc; +require_extension('C'); WRITE_RD(sext_xlen(RVC_RS1 + RVC_RS2)); diff --git a/riscv/insns/c_addi.h b/riscv/insns/c_addi.h index 762f5c2..ad278f1 100644 --- a/riscv/insns/c_addi.h +++ b/riscv/insns/c_addi.h @@ -1,2 +1,2 @@ -require_rvc; +require_extension('C'); WRITE_RD(sext_xlen(RVC_RS2 + insn.rvc_imm())); diff --git a/riscv/insns/c_addi4.h b/riscv/insns/c_addi4.h index 90f3d81..3c9b7b2 100644 --- a/riscv/insns/c_addi4.h +++ b/riscv/insns/c_addi4.h @@ -1,2 +1,2 @@ -require_rvc; +require_extension('C'); WRITE_RD(sext_xlen(RVC_RS2 + insn.rvc_lwsp_imm())); diff --git a/riscv/insns/c_addiw.h b/riscv/insns/c_addiw.h index 33f970c..1b81834 100644 --- a/riscv/insns/c_addiw.h +++ b/riscv/insns/c_addiw.h @@ -1,3 +1,3 @@ -require_rvc; +require_extension('C'); require_rv64; WRITE_RD(sext32(RVC_RS2 + insn.rvc_imm())); diff --git a/riscv/insns/c_addw.h b/riscv/insns/c_addw.h index c474cda..fef554d 100644 --- a/riscv/insns/c_addw.h +++ b/riscv/insns/c_addw.h @@ -1,3 +1,3 @@ -require_rvc; +require_extension('C'); require_rv64; WRITE_RD(sext32(RVC_RS1 + RVC_RS2)); diff --git a/riscv/insns/c_beqz.h b/riscv/insns/c_beqz.h index 8fee5bc..35c1196 100644 --- a/riscv/insns/c_beqz.h +++ b/riscv/insns/c_beqz.h @@ -1,3 +1,3 @@ -require_rvc; +require_extension('C'); if (RVC_RS1S == 0) set_pc(pc + insn.rvc_b_imm()); diff --git a/riscv/insns/c_bnez.h b/riscv/insns/c_bnez.h index a1a5666..1e40ea7 100644 --- a/riscv/insns/c_bnez.h +++ b/riscv/insns/c_bnez.h @@ -1,3 +1,3 @@ -require_rvc; +require_extension('C'); if (RVC_RS1S != 0) set_pc(pc + insn.rvc_b_imm()); diff --git a/riscv/insns/c_j.h b/riscv/insns/c_j.h index f57022d..6d8939c 100644 --- a/riscv/insns/c_j.h +++ b/riscv/insns/c_j.h @@ -1,2 +1,2 @@ -require_rvc; +require_extension('C'); set_pc(pc + insn.rvc_j_imm()); diff --git a/riscv/insns/c_jalr.h b/riscv/insns/c_jalr.h index 9fd7f5d..ef6edfc 100644 --- a/riscv/insns/c_jalr.h +++ b/riscv/insns/c_jalr.h @@ -1,4 +1,4 @@ -require_rvc; +require_extension('C'); reg_t tmp = npc; set_pc(RVC_RS1 & ~reg_t(1)); WRITE_RD(tmp); diff --git a/riscv/insns/c_ld.h b/riscv/insns/c_ld.h index 37b0ee2..df0f5c3 100644 --- a/riscv/insns/c_ld.h +++ b/riscv/insns/c_ld.h @@ -1,3 +1,3 @@ -require_rvc; +require_extension('C'); require_rv64; WRITE_RVC_RDS(MMU.load_int64(RVC_RS1S + insn.rvc_ld_imm())); diff --git a/riscv/insns/c_ldsp.h b/riscv/insns/c_ldsp.h index 0b8bcbe..42665cf 100644 --- a/riscv/insns/c_ldsp.h +++ b/riscv/insns/c_ldsp.h @@ -1,3 +1,3 @@ -require_rvc; +require_extension('C'); require_rv64; WRITE_RD(MMU.load_int64(RVC_SP + insn.rvc_ldsp_imm())); diff --git a/riscv/insns/c_li.h b/riscv/insns/c_li.h index b53c958..06d7bf2 100644 --- a/riscv/insns/c_li.h +++ b/riscv/insns/c_li.h @@ -1,4 +1,4 @@ -require_rvc; +require_extension('C'); if (insn.rvc_rd() == 0) { if (insn.rvc_imm() == -32) // c.sbreak throw trap_breakpoint(); diff --git a/riscv/insns/c_lui.h b/riscv/insns/c_lui.h index abdb78e..4bd4f87 100644 --- a/riscv/insns/c_lui.h +++ b/riscv/insns/c_lui.h @@ -1,2 +1,2 @@ -require_rvc; +require_extension('C'); WRITE_RD(insn.rvc_imm() << 12); diff --git a/riscv/insns/c_lw.h b/riscv/insns/c_lw.h index 9c6f470..f2fc299 100644 --- a/riscv/insns/c_lw.h +++ b/riscv/insns/c_lw.h @@ -1,2 +1,2 @@ -require_rvc; +require_extension('C'); WRITE_RVC_RDS(MMU.load_int32(RVC_RS1S + insn.rvc_lw_imm())); diff --git a/riscv/insns/c_lwsp.h b/riscv/insns/c_lwsp.h index 8d9b9e3..ed4dcf3 100644 --- a/riscv/insns/c_lwsp.h +++ b/riscv/insns/c_lwsp.h @@ -1,2 +1,2 @@ -require_rvc; +require_extension('C'); WRITE_RD(MMU.load_int32(RVC_SP + insn.rvc_lwsp_imm())); diff --git a/riscv/insns/c_mv.h b/riscv/insns/c_mv.h index 6de6584..bc05cfe 100644 --- a/riscv/insns/c_mv.h +++ b/riscv/insns/c_mv.h @@ -1,2 +1,2 @@ -require_rvc; +require_extension('C'); WRITE_RD(RVC_RS1); diff --git a/riscv/insns/c_sd.h b/riscv/insns/c_sd.h index 13de934..9262d04 100644 --- a/riscv/insns/c_sd.h +++ b/riscv/insns/c_sd.h @@ -1,3 +1,3 @@ -require_rvc; +require_extension('C'); require_rv64; MMU.store_uint64(RVC_RS1S + insn.rvc_ld_imm(), RVC_RS2S); diff --git a/riscv/insns/c_sdsp.h b/riscv/insns/c_sdsp.h index 6028b0f..e8b5170 100644 --- a/riscv/insns/c_sdsp.h +++ b/riscv/insns/c_sdsp.h @@ -1,3 +1,3 @@ -require_rvc; +require_extension('C'); require_rv64; MMU.store_uint64(RVC_SP + insn.rvc_ldsp_imm(), RVC_RS2); diff --git a/riscv/insns/c_slli.h b/riscv/insns/c_slli.h index fb6dffd..de3683b 100644 --- a/riscv/insns/c_slli.h +++ b/riscv/insns/c_slli.h @@ -1,4 +1,4 @@ -require_rvc; +require_extension('C'); if (insn.rvc_imm() >= xlen) throw trap_illegal_instruction(); WRITE_RD(sext_xlen(RVC_RS2 << insn.rvc_imm())); diff --git a/riscv/insns/c_sw.h b/riscv/insns/c_sw.h index 34deb9d..3073e9d 100644 --- a/riscv/insns/c_sw.h +++ b/riscv/insns/c_sw.h @@ -1,2 +1,2 @@ -require_rvc; +require_extension('C'); MMU.store_uint32(RVC_RS1S + insn.rvc_lw_imm(), RVC_RS2S); diff --git a/riscv/insns/c_swsp.h b/riscv/insns/c_swsp.h index bbb5ad0..6f3fef0 100644 --- a/riscv/insns/c_swsp.h +++ b/riscv/insns/c_swsp.h @@ -1,2 +1,2 @@ -require_rvc; +require_extension('C'); MMU.store_uint32(RVC_SP + insn.rvc_lwsp_imm(), RVC_RS2); diff --git a/riscv/insns/div.h b/riscv/insns/div.h index 3ad613a..9cbe8d6 100644 --- a/riscv/insns/div.h +++ b/riscv/insns/div.h @@ -1,3 +1,4 @@ +require_extension('M'); sreg_t lhs = sext_xlen(RS1); sreg_t rhs = sext_xlen(RS2); if(rhs == 0) diff --git a/riscv/insns/divu.h b/riscv/insns/divu.h index 4887ce0..31d7585 100644 --- a/riscv/insns/divu.h +++ b/riscv/insns/divu.h @@ -1,3 +1,4 @@ +require_extension('M'); reg_t lhs = zext_xlen(RS1); reg_t rhs = zext_xlen(RS2); if(rhs == 0) diff --git a/riscv/insns/divuw.h b/riscv/insns/divuw.h index a613d95..e127619 100644 --- a/riscv/insns/divuw.h +++ b/riscv/insns/divuw.h @@ -1,3 +1,4 @@ +require_extension('M'); require_rv64; reg_t lhs = zext32(RS1); reg_t rhs = zext32(RS2); diff --git a/riscv/insns/divw.h b/riscv/insns/divw.h index bd4e999..11be17e 100644 --- a/riscv/insns/divw.h +++ b/riscv/insns/divw.h @@ -1,3 +1,4 @@ +require_extension('M'); require_rv64; sreg_t lhs = sext32(RS1); sreg_t rhs = sext32(RS2); diff --git a/riscv/insns/fadd_d.h b/riscv/insns/fadd_d.h index e06efb8..3e5963d 100644 --- a/riscv/insns/fadd_d.h +++ b/riscv/insns/fadd_d.h @@ -1,3 +1,4 @@ +require_extension('D'); require_fp; softfloat_roundingMode = RM; WRITE_FRD(f64_mulAdd(FRS1, 0x3ff0000000000000ULL, FRS2)); diff --git a/riscv/insns/fadd_h.h b/riscv/insns/fadd_h.h deleted file mode 100644 index e69de29..0000000 diff --git a/riscv/insns/fadd_s.h b/riscv/insns/fadd_s.h index c43135d..a35a524 100644 --- a/riscv/insns/fadd_s.h +++ b/riscv/insns/fadd_s.h @@ -1,3 +1,4 @@ +require_extension('F'); require_fp; softfloat_roundingMode = RM; WRITE_FRD(f32_mulAdd(FRS1, 0x3f800000, FRS2)); diff --git a/riscv/insns/fclass_d.h b/riscv/insns/fclass_d.h index bd42d45..f4883ef 100644 --- a/riscv/insns/fclass_d.h +++ b/riscv/insns/fclass_d.h @@ -1,2 +1,3 @@ +require_extension('D'); require_fp; WRITE_RD(f64_classify(FRS1)); diff --git a/riscv/insns/fclass_s.h b/riscv/insns/fclass_s.h index a010266..a2d5b63 100644 --- a/riscv/insns/fclass_s.h +++ b/riscv/insns/fclass_s.h @@ -1,2 +1,3 @@ +require_extension('F'); require_fp; WRITE_RD(f32_classify(FRS1)); diff --git a/riscv/insns/fcvt_d_h.h b/riscv/insns/fcvt_d_h.h deleted file mode 100644 index e69de29..0000000 diff --git a/riscv/insns/fcvt_d_l.h b/riscv/insns/fcvt_d_l.h index e0e1824..08716cf 100644 --- a/riscv/insns/fcvt_d_l.h +++ b/riscv/insns/fcvt_d_l.h @@ -1,3 +1,4 @@ +require_extension('D'); require_rv64; require_fp; softfloat_roundingMode = RM; diff --git a/riscv/insns/fcvt_d_lu.h b/riscv/insns/fcvt_d_lu.h index ee33848..306d7fe 100644 --- a/riscv/insns/fcvt_d_lu.h +++ b/riscv/insns/fcvt_d_lu.h @@ -1,3 +1,4 @@ +require_extension('D'); require_rv64; require_fp; softfloat_roundingMode = RM; diff --git a/riscv/insns/fcvt_d_s.h b/riscv/insns/fcvt_d_s.h index 0024330..177e77c 100644 --- a/riscv/insns/fcvt_d_s.h +++ b/riscv/insns/fcvt_d_s.h @@ -1,3 +1,4 @@ +require_extension('D'); require_fp; softfloat_roundingMode = RM; WRITE_FRD(f32_to_f64(FRS1)); diff --git a/riscv/insns/fcvt_d_w.h b/riscv/insns/fcvt_d_w.h index ce56974..4c4861c 100644 --- a/riscv/insns/fcvt_d_w.h +++ b/riscv/insns/fcvt_d_w.h @@ -1,3 +1,4 @@ +require_extension('D'); require_fp; softfloat_roundingMode = RM; WRITE_FRD(i32_to_f64((int32_t)RS1)); diff --git a/riscv/insns/fcvt_d_wu.h b/riscv/insns/fcvt_d_wu.h index 4c56248..1dbf218 100644 --- a/riscv/insns/fcvt_d_wu.h +++ b/riscv/insns/fcvt_d_wu.h @@ -1,3 +1,4 @@ +require_extension('D'); require_fp; softfloat_roundingMode = RM; WRITE_FRD(ui32_to_f64((uint32_t)RS1)); diff --git a/riscv/insns/fcvt_h_d.h b/riscv/insns/fcvt_h_d.h deleted file mode 100644 index e69de29..0000000 diff --git a/riscv/insns/fcvt_h_l.h b/riscv/insns/fcvt_h_l.h deleted file mode 100644 index e69de29..0000000 diff --git a/riscv/insns/fcvt_h_lu.h b/riscv/insns/fcvt_h_lu.h deleted file mode 100644 index e69de29..0000000 diff --git a/riscv/insns/fcvt_h_s.h b/riscv/insns/fcvt_h_s.h deleted file mode 100644 index e69de29..0000000 diff --git a/riscv/insns/fcvt_h_w.h b/riscv/insns/fcvt_h_w.h deleted file mode 100644 index e69de29..0000000 diff --git a/riscv/insns/fcvt_h_wu.h b/riscv/insns/fcvt_h_wu.h deleted file mode 100644 index e69de29..0000000 diff --git a/riscv/insns/fcvt_l_d.h b/riscv/insns/fcvt_l_d.h index 55dbe27..ee323f3 100644 --- a/riscv/insns/fcvt_l_d.h +++ b/riscv/insns/fcvt_l_d.h @@ -1,3 +1,4 @@ +require_extension('D'); require_rv64; require_fp; softfloat_roundingMode = RM; diff --git a/riscv/insns/fcvt_l_h.h b/riscv/insns/fcvt_l_h.h deleted file mode 100644 index e69de29..0000000 diff --git a/riscv/insns/fcvt_l_s.h b/riscv/insns/fcvt_l_s.h index ea1e5a7..6079a69 100644 --- a/riscv/insns/fcvt_l_s.h +++ b/riscv/insns/fcvt_l_s.h @@ -1,3 +1,4 @@ +require_extension('F'); require_rv64; require_fp; softfloat_roundingMode = RM; diff --git a/riscv/insns/fcvt_lu_d.h b/riscv/insns/fcvt_lu_d.h index 7be12ed..b6004ea 100644 --- a/riscv/insns/fcvt_lu_d.h +++ b/riscv/insns/fcvt_lu_d.h @@ -1,3 +1,4 @@ +require_extension('D'); require_rv64; require_fp; softfloat_roundingMode = RM; diff --git a/riscv/insns/fcvt_lu_h.h b/riscv/insns/fcvt_lu_h.h deleted file mode 100644 index e69de29..0000000 diff --git a/riscv/insns/fcvt_lu_s.h b/riscv/insns/fcvt_lu_s.h index 04501c1..af8e1ab 100644 --- a/riscv/insns/fcvt_lu_s.h +++ b/riscv/insns/fcvt_lu_s.h @@ -1,3 +1,4 @@ +require_extension('F'); require_rv64; require_fp; softfloat_roundingMode = RM; diff --git a/riscv/insns/fcvt_s_d.h b/riscv/insns/fcvt_s_d.h index 28a1d69..c1c9f0c 100644 --- a/riscv/insns/fcvt_s_d.h +++ b/riscv/insns/fcvt_s_d.h @@ -1,3 +1,4 @@ +require_extension('D'); require_fp; softfloat_roundingMode = RM; WRITE_FRD(f64_to_f32(FRS1)); diff --git a/riscv/insns/fcvt_s_h.h b/riscv/insns/fcvt_s_h.h deleted file mode 100644 index e69de29..0000000 diff --git a/riscv/insns/fcvt_s_l.h b/riscv/insns/fcvt_s_l.h index 723b9e4..9abcc80 100644 --- a/riscv/insns/fcvt_s_l.h +++ b/riscv/insns/fcvt_s_l.h @@ -1,3 +1,4 @@ +require_extension('F'); require_rv64; require_fp; softfloat_roundingMode = RM; diff --git a/riscv/insns/fcvt_s_lu.h b/riscv/insns/fcvt_s_lu.h index b58b395..70c676e 100644 --- a/riscv/insns/fcvt_s_lu.h +++ b/riscv/insns/fcvt_s_lu.h @@ -1,3 +1,4 @@ +require_extension('F'); require_rv64; require_fp; softfloat_roundingMode = RM; diff --git a/riscv/insns/fcvt_s_w.h b/riscv/insns/fcvt_s_w.h index 05445fa..1ddabd8 100644 --- a/riscv/insns/fcvt_s_w.h +++ b/riscv/insns/fcvt_s_w.h @@ -1,3 +1,4 @@ +require_extension('F'); require_fp; softfloat_roundingMode = RM; WRITE_FRD(i32_to_f32((int32_t)RS1)); diff --git a/riscv/insns/fcvt_s_wu.h b/riscv/insns/fcvt_s_wu.h index ca8d2b6..c1394c3 100644 --- a/riscv/insns/fcvt_s_wu.h +++ b/riscv/insns/fcvt_s_wu.h @@ -1,3 +1,4 @@ +require_extension('F'); require_fp; softfloat_roundingMode = RM; WRITE_FRD(ui32_to_f32((uint32_t)RS1)); diff --git a/riscv/insns/fcvt_w_d.h b/riscv/insns/fcvt_w_d.h index a5186b5..bac8a9b 100644 --- a/riscv/insns/fcvt_w_d.h +++ b/riscv/insns/fcvt_w_d.h @@ -1,3 +1,4 @@ +require_extension('D'); require_fp; softfloat_roundingMode = RM; WRITE_RD(sext32(f64_to_i32(FRS1, RM, true))); diff --git a/riscv/insns/fcvt_w_h.h b/riscv/insns/fcvt_w_h.h deleted file mode 100644 index e69de29..0000000 diff --git a/riscv/insns/fcvt_w_s.h b/riscv/insns/fcvt_w_s.h index 1d82deb..81bc89f 100644 --- a/riscv/insns/fcvt_w_s.h +++ b/riscv/insns/fcvt_w_s.h @@ -1,3 +1,4 @@ +require_extension('F'); require_fp; softfloat_roundingMode = RM; WRITE_RD(sext32(f32_to_i32(FRS1, RM, true))); diff --git a/riscv/insns/fcvt_wu_d.h b/riscv/insns/fcvt_wu_d.h index 5cf44d1..353ae6d 100644 --- a/riscv/insns/fcvt_wu_d.h +++ b/riscv/insns/fcvt_wu_d.h @@ -1,3 +1,4 @@ +require_extension('D'); require_fp; softfloat_roundingMode = RM; WRITE_RD(sext32(f64_to_ui32(FRS1, RM, true))); diff --git a/riscv/insns/fcvt_wu_h.h b/riscv/insns/fcvt_wu_h.h deleted file mode 100644 index e69de29..0000000 diff --git a/riscv/insns/fcvt_wu_s.h b/riscv/insns/fcvt_wu_s.h index 5b4c444..2c1ff00 100644 --- a/riscv/insns/fcvt_wu_s.h +++ b/riscv/insns/fcvt_wu_s.h @@ -1,3 +1,4 @@ +require_extension('F'); require_fp; softfloat_roundingMode = RM; WRITE_RD(sext32(f32_to_ui32(FRS1, RM, true))); diff --git a/riscv/insns/fdiv_d.h b/riscv/insns/fdiv_d.h index e215702..d52ac66 100644 --- a/riscv/insns/fdiv_d.h +++ b/riscv/insns/fdiv_d.h @@ -1,3 +1,4 @@ +require_extension('D'); require_fp; softfloat_roundingMode = RM; WRITE_FRD(f64_div(FRS1, FRS2)); diff --git a/riscv/insns/fdiv_h.h b/riscv/insns/fdiv_h.h deleted file mode 100644 index e69de29..0000000 diff --git a/riscv/insns/fdiv_s.h b/riscv/insns/fdiv_s.h index 2644d08..cf54c57 100644 --- a/riscv/insns/fdiv_s.h +++ b/riscv/insns/fdiv_s.h @@ -1,3 +1,4 @@ +require_extension('F'); require_fp; softfloat_roundingMode = RM; WRITE_FRD(f32_div(FRS1, FRS2)); diff --git a/riscv/insns/feq_d.h b/riscv/insns/feq_d.h index 516fb59..43d9c1c 100644 --- a/riscv/insns/feq_d.h +++ b/riscv/insns/feq_d.h @@ -1,3 +1,4 @@ +require_extension('D'); require_fp; WRITE_RD(f64_eq(FRS1, FRS2)); set_fp_exceptions; diff --git a/riscv/insns/feq_h.h b/riscv/insns/feq_h.h deleted file mode 100644 index e69de29..0000000 diff --git a/riscv/insns/feq_s.h b/riscv/insns/feq_s.h index b44da24..7d42634 100644 --- a/riscv/insns/feq_s.h +++ b/riscv/insns/feq_s.h @@ -1,3 +1,4 @@ +require_extension('F'); require_fp; WRITE_RD(f32_eq(FRS1, FRS2)); set_fp_exceptions; diff --git a/riscv/insns/fld.h b/riscv/insns/fld.h index 1bc83cf..0b50b8a 100644 --- a/riscv/insns/fld.h +++ b/riscv/insns/fld.h @@ -1,2 +1,3 @@ +require_extension('D'); require_fp; WRITE_FRD(MMU.load_int64(RS1 + insn.i_imm())); diff --git a/riscv/insns/fle_d.h b/riscv/insns/fle_d.h index 72dcc7e..7f6a84d 100644 --- a/riscv/insns/fle_d.h +++ b/riscv/insns/fle_d.h @@ -1,3 +1,4 @@ +require_extension('D'); require_fp; WRITE_RD(f64_le(FRS1, FRS2)); set_fp_exceptions; diff --git a/riscv/insns/fle_h.h b/riscv/insns/fle_h.h deleted file mode 100644 index e69de29..0000000 diff --git a/riscv/insns/fle_s.h b/riscv/insns/fle_s.h index 9c85b4a..0884c51 100644 --- a/riscv/insns/fle_s.h +++ b/riscv/insns/fle_s.h @@ -1,3 +1,4 @@ +require_extension('F'); require_fp; WRITE_RD(f32_le(FRS1, FRS2)); set_fp_exceptions; diff --git a/riscv/insns/flh.h b/riscv/insns/flh.h deleted file mode 100644 index e69de29..0000000 diff --git a/riscv/insns/flt_d.h b/riscv/insns/flt_d.h index 335e4a8..9fda98d 100644 --- a/riscv/insns/flt_d.h +++ b/riscv/insns/flt_d.h @@ -1,3 +1,4 @@ +require_extension('D'); require_fp; WRITE_RD(f64_lt(FRS1, FRS2)); set_fp_exceptions; diff --git a/riscv/insns/flt_h.h b/riscv/insns/flt_h.h deleted file mode 100644 index e69de29..0000000 diff --git a/riscv/insns/flt_s.h b/riscv/insns/flt_s.h index 7a21785..830b0a0 100644 --- a/riscv/insns/flt_s.h +++ b/riscv/insns/flt_s.h @@ -1,3 +1,4 @@ +require_extension('F'); require_fp; WRITE_RD(f32_lt(FRS1, FRS2)); set_fp_exceptions; diff --git a/riscv/insns/flw.h b/riscv/insns/flw.h index a5f7d16..b94ba5d 100644 --- a/riscv/insns/flw.h +++ b/riscv/insns/flw.h @@ -1,2 +1,3 @@ +require_extension('F'); require_fp; WRITE_FRD(MMU.load_int32(RS1 + insn.i_imm())); diff --git a/riscv/insns/fmadd_d.h b/riscv/insns/fmadd_d.h index 8640e7f..8605e0b 100644 --- a/riscv/insns/fmadd_d.h +++ b/riscv/insns/fmadd_d.h @@ -1,3 +1,4 @@ +require_extension('D'); require_fp; softfloat_roundingMode = RM; WRITE_FRD(f64_mulAdd(FRS1, FRS2, FRS3)); diff --git a/riscv/insns/fmadd_h.h b/riscv/insns/fmadd_h.h deleted file mode 100644 index e69de29..0000000 diff --git a/riscv/insns/fmadd_s.h b/riscv/insns/fmadd_s.h index f8b0a5f..95196b7 100644 --- a/riscv/insns/fmadd_s.h +++ b/riscv/insns/fmadd_s.h @@ -1,3 +1,4 @@ +require_extension('F'); require_fp; softfloat_roundingMode = RM; WRITE_FRD(f32_mulAdd(FRS1, FRS2, FRS3)); diff --git a/riscv/insns/fmax_d.h b/riscv/insns/fmax_d.h index a26aeab..eb156de 100644 --- a/riscv/insns/fmax_d.h +++ b/riscv/insns/fmax_d.h @@ -1,3 +1,4 @@ +require_extension('D'); require_fp; WRITE_FRD(isNaNF64UI(FRS2) || f64_le_quiet(FRS2,FRS1) /* && FRS1 not NaN */ ? FRS1 : FRS2); diff --git a/riscv/insns/fmax_h.h b/riscv/insns/fmax_h.h deleted file mode 100644 index e69de29..0000000 diff --git a/riscv/insns/fmax_s.h b/riscv/insns/fmax_s.h index b16134b..215a6d1 100644 --- a/riscv/insns/fmax_s.h +++ b/riscv/insns/fmax_s.h @@ -1,3 +1,4 @@ +require_extension('F'); require_fp; WRITE_FRD(isNaNF32UI(FRS2) || f32_le_quiet(FRS2,FRS1) /* && FRS1 not NaN */ ? FRS1 : FRS2); diff --git a/riscv/insns/fmin_d.h b/riscv/insns/fmin_d.h index c095ade..02ea681 100644 --- a/riscv/insns/fmin_d.h +++ b/riscv/insns/fmin_d.h @@ -1,3 +1,4 @@ +require_extension('D'); require_fp; WRITE_FRD(isNaNF64UI(FRS2) || f64_lt_quiet(FRS1,FRS2) /* && FRS1 not NaN */ ? FRS1 : FRS2); diff --git a/riscv/insns/fmin_h.h b/riscv/insns/fmin_h.h deleted file mode 100644 index e69de29..0000000 diff --git a/riscv/insns/fmin_s.h b/riscv/insns/fmin_s.h index e2fdc5c..cc673a0 100644 --- a/riscv/insns/fmin_s.h +++ b/riscv/insns/fmin_s.h @@ -1,3 +1,4 @@ +require_extension('F'); require_fp; WRITE_FRD(isNaNF32UI(FRS2) || f32_lt_quiet(FRS1,FRS2) /* && FRS1 not NaN */ ? FRS1 : FRS2); diff --git a/riscv/insns/fmsub_d.h b/riscv/insns/fmsub_d.h index 13e9fcc..696f822 100644 --- a/riscv/insns/fmsub_d.h +++ b/riscv/insns/fmsub_d.h @@ -1,3 +1,4 @@ +require_extension('D'); require_fp; softfloat_roundingMode = RM; WRITE_FRD(f64_mulAdd(FRS1, FRS2, FRS3 ^ (uint64_t)INT64_MIN)); diff --git a/riscv/insns/fmsub_h.h b/riscv/insns/fmsub_h.h deleted file mode 100644 index e69de29..0000000 diff --git a/riscv/insns/fmsub_s.h b/riscv/insns/fmsub_s.h index c6aa418..9251277 100644 --- a/riscv/insns/fmsub_s.h +++ b/riscv/insns/fmsub_s.h @@ -1,3 +1,4 @@ +require_extension('F'); require_fp; softfloat_roundingMode = RM; WRITE_FRD(f32_mulAdd(FRS1, FRS2, FRS3 ^ (uint32_t)INT32_MIN)); diff --git a/riscv/insns/fmul_d.h b/riscv/insns/fmul_d.h index e2ca1c2..d74c316 100644 --- a/riscv/insns/fmul_d.h +++ b/riscv/insns/fmul_d.h @@ -1,3 +1,4 @@ +require_extension('D'); require_fp; softfloat_roundingMode = RM; WRITE_FRD(f64_mulAdd(FRS1, FRS2, (FRS1 ^ FRS2) & (uint64_t)INT64_MIN)); diff --git a/riscv/insns/fmul_h.h b/riscv/insns/fmul_h.h deleted file mode 100644 index e69de29..0000000 diff --git a/riscv/insns/fmul_s.h b/riscv/insns/fmul_s.h index f564803..284aeb3 100644 --- a/riscv/insns/fmul_s.h +++ b/riscv/insns/fmul_s.h @@ -1,3 +1,4 @@ +require_extension('F'); require_fp; softfloat_roundingMode = RM; WRITE_FRD(f32_mulAdd(FRS1, FRS2, (FRS1 ^ FRS2) & (uint32_t)INT32_MIN)); diff --git a/riscv/insns/fmv_d_x.h b/riscv/insns/fmv_d_x.h index f01811d..c3f6049 100644 --- a/riscv/insns/fmv_d_x.h +++ b/riscv/insns/fmv_d_x.h @@ -1,3 +1,4 @@ +require_extension('D'); require_rv64; require_fp; WRITE_FRD(RS1); diff --git a/riscv/insns/fmv_h_x.h b/riscv/insns/fmv_h_x.h deleted file mode 100644 index e69de29..0000000 diff --git a/riscv/insns/fmv_s_x.h b/riscv/insns/fmv_s_x.h index f3eac82..f0f95ac 100644 --- a/riscv/insns/fmv_s_x.h +++ b/riscv/insns/fmv_s_x.h @@ -1,2 +1,3 @@ +require_extension('F'); require_fp; WRITE_FRD(RS1); diff --git a/riscv/insns/fmv_x_d.h b/riscv/insns/fmv_x_d.h index d3c1d7a..b97d7f5 100644 --- a/riscv/insns/fmv_x_d.h +++ b/riscv/insns/fmv_x_d.h @@ -1,3 +1,4 @@ +require_extension('D'); require_rv64; require_fp; WRITE_RD(FRS1); diff --git a/riscv/insns/fmv_x_h.h b/riscv/insns/fmv_x_h.h deleted file mode 100644 index e69de29..0000000 diff --git a/riscv/insns/fmv_x_s.h b/riscv/insns/fmv_x_s.h index 46a9488..1bee87f 100644 --- a/riscv/insns/fmv_x_s.h +++ b/riscv/insns/fmv_x_s.h @@ -1,2 +1,3 @@ +require_extension('F'); require_fp; WRITE_RD(sext32(FRS1)); diff --git a/riscv/insns/fnmadd_d.h b/riscv/insns/fnmadd_d.h index 705470b..bed6172 100644 --- a/riscv/insns/fnmadd_d.h +++ b/riscv/insns/fnmadd_d.h @@ -1,3 +1,4 @@ +require_extension('D'); require_fp; softfloat_roundingMode = RM; WRITE_FRD(f64_mulAdd(FRS1 ^ (uint64_t)INT64_MIN, FRS2, FRS3 ^ (uint64_t)INT64_MIN)); diff --git a/riscv/insns/fnmadd_h.h b/riscv/insns/fnmadd_h.h deleted file mode 100644 index e69de29..0000000 diff --git a/riscv/insns/fnmadd_s.h b/riscv/insns/fnmadd_s.h index 2df321b..1378ae3 100644 --- a/riscv/insns/fnmadd_s.h +++ b/riscv/insns/fnmadd_s.h @@ -1,3 +1,4 @@ +require_extension('F'); require_fp; softfloat_roundingMode = RM; WRITE_FRD(f32_mulAdd(FRS1 ^ (uint32_t)INT32_MIN, FRS2, FRS3 ^ (uint32_t)INT32_MIN)); diff --git a/riscv/insns/fnmsub_d.h b/riscv/insns/fnmsub_d.h index c38d2bf..340090a 100644 --- a/riscv/insns/fnmsub_d.h +++ b/riscv/insns/fnmsub_d.h @@ -1,3 +1,4 @@ +require_extension('D'); require_fp; softfloat_roundingMode = RM; WRITE_FRD(f64_mulAdd(FRS1 ^ (uint64_t)INT64_MIN, FRS2, FRS3)); diff --git a/riscv/insns/fnmsub_h.h b/riscv/insns/fnmsub_h.h deleted file mode 100644 index e69de29..0000000 diff --git a/riscv/insns/fnmsub_s.h b/riscv/insns/fnmsub_s.h index c3fa995..3be27d0 100644 --- a/riscv/insns/fnmsub_s.h +++ b/riscv/insns/fnmsub_s.h @@ -1,3 +1,4 @@ +require_extension('F'); require_fp; softfloat_roundingMode = RM; WRITE_FRD(f32_mulAdd(FRS1 ^ (uint32_t)INT32_MIN, FRS2, FRS3)); diff --git a/riscv/insns/fsd.h b/riscv/insns/fsd.h index fe90a6b..63cc8e5 100644 --- a/riscv/insns/fsd.h +++ b/riscv/insns/fsd.h @@ -1,2 +1,3 @@ +require_extension('D'); require_fp; MMU.store_uint64(RS1 + insn.s_imm(), FRS2); diff --git a/riscv/insns/fsgnj_d.h b/riscv/insns/fsgnj_d.h index 74ef3f6..52648a1 100644 --- a/riscv/insns/fsgnj_d.h +++ b/riscv/insns/fsgnj_d.h @@ -1,2 +1,3 @@ +require_extension('D'); require_fp; WRITE_FRD((FRS1 &~ INT64_MIN) | (FRS2 & INT64_MIN)); diff --git a/riscv/insns/fsgnj_h.h b/riscv/insns/fsgnj_h.h deleted file mode 100644 index e69de29..0000000 diff --git a/riscv/insns/fsgnj_s.h b/riscv/insns/fsgnj_s.h index 4f852b4..4c91ff3 100644 --- a/riscv/insns/fsgnj_s.h +++ b/riscv/insns/fsgnj_s.h @@ -1,2 +1,3 @@ +require_extension('F'); require_fp; WRITE_FRD((FRS1 &~ (uint32_t)INT32_MIN) | (FRS2 & (uint32_t)INT32_MIN)); diff --git a/riscv/insns/fsgnjn_d.h b/riscv/insns/fsgnjn_d.h index e214f1d..cdec924 100644 --- a/riscv/insns/fsgnjn_d.h +++ b/riscv/insns/fsgnjn_d.h @@ -1,2 +1,3 @@ +require_extension('D'); require_fp; WRITE_FRD((FRS1 &~ INT64_MIN) | ((~FRS2) & INT64_MIN)); diff --git a/riscv/insns/fsgnjn_h.h b/riscv/insns/fsgnjn_h.h deleted file mode 100644 index e69de29..0000000 diff --git a/riscv/insns/fsgnjn_s.h b/riscv/insns/fsgnjn_s.h index b098150..f91a7b0 100644 --- a/riscv/insns/fsgnjn_s.h +++ b/riscv/insns/fsgnjn_s.h @@ -1,2 +1,3 @@ +require_extension('F'); require_fp; WRITE_FRD((FRS1 &~ (uint32_t)INT32_MIN) | ((~FRS2) & (uint32_t)INT32_MIN)); diff --git a/riscv/insns/fsgnjx_d.h b/riscv/insns/fsgnjx_d.h index 2bcef6f..b09d24c 100644 --- a/riscv/insns/fsgnjx_d.h +++ b/riscv/insns/fsgnjx_d.h @@ -1,2 +1,3 @@ +require_extension('D'); require_fp; WRITE_FRD(FRS1 ^ (FRS2 & INT64_MIN)); diff --git a/riscv/insns/fsgnjx_h.h b/riscv/insns/fsgnjx_h.h deleted file mode 100644 index e69de29..0000000 diff --git a/riscv/insns/fsgnjx_s.h b/riscv/insns/fsgnjx_s.h index 69b2d98..1fd2de6 100644 --- a/riscv/insns/fsgnjx_s.h +++ b/riscv/insns/fsgnjx_s.h @@ -1,2 +1,3 @@ +require_extension('F'); require_fp; WRITE_FRD(FRS1 ^ (FRS2 & (uint32_t)INT32_MIN)); diff --git a/riscv/insns/fsh.h b/riscv/insns/fsh.h deleted file mode 100644 index e69de29..0000000 diff --git a/riscv/insns/fsqrt_d.h b/riscv/insns/fsqrt_d.h index 0ff5daa..812438c 100644 --- a/riscv/insns/fsqrt_d.h +++ b/riscv/insns/fsqrt_d.h @@ -1,3 +1,4 @@ +require_extension('D'); require_fp; softfloat_roundingMode = RM; WRITE_FRD(f64_sqrt(FRS1)); diff --git a/riscv/insns/fsqrt_h.h b/riscv/insns/fsqrt_h.h deleted file mode 100644 index e69de29..0000000 diff --git a/riscv/insns/fsqrt_s.h b/riscv/insns/fsqrt_s.h index ea1f31a..d77acab 100644 --- a/riscv/insns/fsqrt_s.h +++ b/riscv/insns/fsqrt_s.h @@ -1,3 +1,4 @@ +require_extension('F'); require_fp; softfloat_roundingMode = RM; WRITE_FRD(f32_sqrt(FRS1)); diff --git a/riscv/insns/fsub_d.h b/riscv/insns/fsub_d.h index 238ee9e..6ffc6b3 100644 --- a/riscv/insns/fsub_d.h +++ b/riscv/insns/fsub_d.h @@ -1,3 +1,4 @@ +require_extension('D'); require_fp; softfloat_roundingMode = RM; WRITE_FRD(f64_mulAdd(FRS1, 0x3ff0000000000000ULL, FRS2 ^ (uint64_t)INT64_MIN)); diff --git a/riscv/insns/fsub_h.h b/riscv/insns/fsub_h.h deleted file mode 100644 index e69de29..0000000 diff --git a/riscv/insns/fsub_s.h b/riscv/insns/fsub_s.h index a30b4f9..6a0f853 100644 --- a/riscv/insns/fsub_s.h +++ b/riscv/insns/fsub_s.h @@ -1,3 +1,4 @@ +require_extension('F'); require_fp; softfloat_roundingMode = RM; WRITE_FRD(f32_mulAdd(FRS1, 0x3f800000, FRS2 ^ (uint32_t)INT32_MIN)); diff --git a/riscv/insns/fsw.h b/riscv/insns/fsw.h index 85c8091..3135e9b 100644 --- a/riscv/insns/fsw.h +++ b/riscv/insns/fsw.h @@ -1,2 +1,3 @@ +require_extension('F'); require_fp; MMU.store_uint32(RS1 + insn.s_imm(), FRS2); diff --git a/riscv/insns/lr_d.h b/riscv/insns/lr_d.h index 94c4bf7..077590f 100644 --- a/riscv/insns/lr_d.h +++ b/riscv/insns/lr_d.h @@ -1,3 +1,4 @@ +require_extension('A'); require_rv64; p->get_state()->load_reservation = RS1; WRITE_RD(MMU.load_int64(RS1)); diff --git a/riscv/insns/lr_w.h b/riscv/insns/lr_w.h index 2b95419..767251f 100644 --- a/riscv/insns/lr_w.h +++ b/riscv/insns/lr_w.h @@ -1,2 +1,3 @@ +require_extension('A'); p->get_state()->load_reservation = RS1; WRITE_RD(MMU.load_int32(RS1)); diff --git a/riscv/insns/mul.h b/riscv/insns/mul.h index c6b5331..0102d36 100644 --- a/riscv/insns/mul.h +++ b/riscv/insns/mul.h @@ -1 +1,2 @@ +require_extension('M'); WRITE_RD(sext_xlen(RS1 * RS2)); diff --git a/riscv/insns/mulh.h b/riscv/insns/mulh.h index 567e213..051382a 100644 --- a/riscv/insns/mulh.h +++ b/riscv/insns/mulh.h @@ -1,3 +1,4 @@ +require_extension('M'); if (xlen == 64) WRITE_RD(mulh(RS1, RS2)); else diff --git a/riscv/insns/mulhsu.h b/riscv/insns/mulhsu.h index 5eeb89c..c53f90b 100644 --- a/riscv/insns/mulhsu.h +++ b/riscv/insns/mulhsu.h @@ -1,3 +1,4 @@ +require_extension('M'); if (xlen == 64) WRITE_RD(mulhsu(RS1, RS2)); else diff --git a/riscv/insns/mulhu.h b/riscv/insns/mulhu.h index ce6a21e..1ae3650 100644 --- a/riscv/insns/mulhu.h +++ b/riscv/insns/mulhu.h @@ -1,3 +1,4 @@ +require_extension('M'); if (xlen == 64) WRITE_RD(mulhu(RS1, RS2)); else diff --git a/riscv/insns/mulw.h b/riscv/insns/mulw.h index 184dd41..ed55545 100644 --- a/riscv/insns/mulw.h +++ b/riscv/insns/mulw.h @@ -1,2 +1,3 @@ +require_extension('M'); require_rv64; WRITE_RD(sext32(RS1 * RS2)); diff --git a/riscv/insns/rem.h b/riscv/insns/rem.h index d074f26..8587995 100644 --- a/riscv/insns/rem.h +++ b/riscv/insns/rem.h @@ -1,3 +1,4 @@ +require_extension('M'); sreg_t lhs = sext_xlen(RS1); sreg_t rhs = sext_xlen(RS2); if(rhs == 0) diff --git a/riscv/insns/remu.h b/riscv/insns/remu.h index c291947..e74774c 100644 --- a/riscv/insns/remu.h +++ b/riscv/insns/remu.h @@ -1,3 +1,4 @@ +require_extension('M'); reg_t lhs = zext_xlen(RS1); reg_t rhs = zext_xlen(RS2); if(rhs == 0) diff --git a/riscv/insns/remuw.h b/riscv/insns/remuw.h index e487516..b239c8f 100644 --- a/riscv/insns/remuw.h +++ b/riscv/insns/remuw.h @@ -1,3 +1,4 @@ +require_extension('M'); require_rv64; reg_t lhs = zext32(RS1); reg_t rhs = zext32(RS2); diff --git a/riscv/insns/remw.h b/riscv/insns/remw.h index 2bae1a8..56221cc 100644 --- a/riscv/insns/remw.h +++ b/riscv/insns/remw.h @@ -1,3 +1,4 @@ +require_extension('M'); require_rv64; sreg_t lhs = sext32(RS1); sreg_t rhs = sext32(RS2); diff --git a/riscv/insns/sc_d.h b/riscv/insns/sc_d.h index 2108079..01a45ce 100644 --- a/riscv/insns/sc_d.h +++ b/riscv/insns/sc_d.h @@ -1,3 +1,4 @@ +require_extension('A'); require_rv64; if (RS1 == p->get_state()->load_reservation) { diff --git a/riscv/insns/sc_w.h b/riscv/insns/sc_w.h index 729973d..68ec577 100644 --- a/riscv/insns/sc_w.h +++ b/riscv/insns/sc_w.h @@ -1,3 +1,4 @@ +require_extension('A'); if (RS1 == p->get_state()->load_reservation) { MMU.store_uint32(RS1, RS2); diff --git a/riscv/insns/sltiu.h b/riscv/insns/sltiu.h index c4478fd..f398457 100644 --- a/riscv/insns/sltiu.h +++ b/riscv/insns/sltiu.h @@ -1 +1 @@ -WRITE_RD(RS1 < insn.i_imm()); +WRITE_RD(RS1 < reg_t(insn.i_imm())); diff --git a/riscv/mmu.cc b/riscv/mmu.cc index 2519f84..e6bbbd4 100644 --- a/riscv/mmu.cc +++ b/riscv/mmu.cc @@ -4,6 +4,12 @@ #include "sim.h" #include "processor.h" +#define LEVELS(xlen) ((xlen) == 32 ? 2 : 3) +#define PPN_SHIFT(xlen) ((xlen) == 32 ? 10 : 26) +#define PTIDXBITS(xlen) ((xlen) == 32 ? 10 : 9) +#define VPN_BITS(xlen) (PTIDXBITS(xlen) * LEVELS(xlen)) +#define VA_BITS(xlen) (VPN_BITS(xlen) + PGSHIFT) + mmu_t::mmu_t(char* _mem, size_t _memsz) : mem(_mem), memsz(_memsz), proc(NULL) { @@ -79,25 +85,26 @@ void* mmu_t::refill_tlb(reg_t addr, reg_t bytes, bool store, bool fetch) return mem + paddr; } -pte_t mmu_t::walk(reg_t addr, bool supervisor, bool store, bool fetch) +reg_t mmu_t::walk(reg_t addr, bool supervisor, bool store, bool fetch) { - reg_t msb_mask = -(reg_t(1) << (VA_BITS-1)); + reg_t msb_mask = -(reg_t(1) << (VA_BITS(proc->xlen) - 1)); if ((addr & msb_mask) != 0 && (addr & msb_mask) != msb_mask) return -1; // address isn't properly sign-extended reg_t base = proc->get_state()->sptbr; - int ptshift = (LEVELS-1)*PTIDXBITS; - for (reg_t i = 0; i < LEVELS; i++, ptshift -= PTIDXBITS) { - reg_t idx = (addr >> (PGSHIFT+ptshift)) & ((1<max_xlen; + int ptshift = (LEVELS(xlen) - 1) * PTIDXBITS(xlen); + for (reg_t i = 0; i < LEVELS(xlen); i++, ptshift -= PTIDXBITS(xlen)) { + reg_t idx = (addr >> (PGSHIFT+ptshift)) & ((1<= memsz) return -1; - pte_t* ppte = (pte_t*)(mem+pte_addr); - reg_t ppn = *ppte >> PTE_PPN_SHIFT; + reg_t* ppte = (reg_t*)(mem+pte_addr); + reg_t ppn = *ppte >> PPN_SHIFT(xlen); if ((*ppte & PTE_TYPE) == PTE_TYPE_TABLE) { // next level of page table base = ppn << PGSHIFT; diff --git a/riscv/mmu.h b/riscv/mmu.h index d6f446b..a8853d3 100644 --- a/riscv/mmu.h +++ b/riscv/mmu.h @@ -12,13 +12,8 @@ #include // virtual memory configuration -typedef reg_t pte_t; -const reg_t LEVELS = sizeof(pte_t) == 8 ? 3 : 2; -const reg_t PGSHIFT = 12; -const reg_t PTIDXBITS = PGSHIFT - (sizeof(pte_t) == 8 ? 3 : 2); +#define PGSHIFT 12 const reg_t PGSIZE = 1 << PGSHIFT; -const reg_t VPN_BITS = PTIDXBITS * LEVELS; -const reg_t VA_BITS = VPN_BITS + PGSHIFT; struct insn_fetch_t { @@ -153,7 +148,7 @@ private: void* refill_tlb(reg_t addr, reg_t bytes, bool store, bool fetch); // perform a page table walk for a given VA; set referenced/dirty bits - pte_t walk(reg_t addr, bool supervisor, bool store, bool fetch); + reg_t walk(reg_t addr, bool supervisor, bool store, bool fetch); // translate a virtual address to a physical address void* translate(reg_t addr, reg_t bytes, bool store, bool fetch) diff --git a/riscv/processor.cc b/riscv/processor.cc index 51e56b1..1187265 100644 --- a/riscv/processor.cc +++ b/riscv/processor.cc @@ -19,13 +19,17 @@ #undef STATE #define STATE state -processor_t::processor_t(sim_t* _sim, mmu_t* _mmu, uint32_t _id) - : sim(_sim), mmu(_mmu), ext(NULL), disassembler(new disassembler_t), - id(_id), run(false), debug(false) +processor_t::processor_t(const char* isa, sim_t* sim, uint32_t id) + : sim(sim), ext(NULL), disassembler(new disassembler_t), + id(id), run(false), debug(false) { - reset(true); + parse_isa_string(isa); + + mmu = new mmu_t(sim->mem, sim->memsz); mmu->set_processor(this); + reset(true); + #define DECLARE_INSN(name, match, mask) REGISTER_INSN(this, name, match, mask) #include "encoding.h" #undef DECLARE_INSN @@ -44,19 +48,62 @@ processor_t::~processor_t() } #endif + delete mmu; delete disassembler; } +static void bad_isa_string(const char* isa) +{ + fprintf(stderr, "error: bad --isa option %s\n", isa); + abort(); +} + +void processor_t::parse_isa_string(const char* isa) +{ + const char* p = isa; + const char* all_subsets = "IMAFDC"; + + max_xlen = 64; + if (strncmp(p, "RV32", 4) == 0) + max_xlen = 32, p += 4; + else if (strncmp(p, "RV64", 4) == 0) + p += 4; + else if (strncmp(p, "RV", 2) == 0) + p += 2; + + if (!*p) + p = all_subsets; + else if (*p != 'I') + bad_isa_string(isa); + + memset(subsets, 0, sizeof(subsets)); + + while (*p) { + if (auto next = strchr(all_subsets, *p)) { + subsets[(int)*p] = true; + all_subsets = next + 1; + p++; + } else if (*p == 'X') { + const char* ext = p+1, *end = ext; + while (islower(*end)) + end++; + register_extension(find_extension(std::string(ext, end - ext).c_str())()); + p = end; + } else { + bad_isa_string(isa); + } + } + + if (supports_extension('D') && !supports_extension('F')) + bad_isa_string(isa); +} + void state_t::reset() { memset(this, 0, sizeof(*this)); mstatus = set_field(mstatus, MSTATUS_PRV, PRV_M); mstatus = set_field(mstatus, MSTATUS_PRV1, PRV_S); mstatus = set_field(mstatus, MSTATUS_PRV2, PRV_S); -#ifdef RISCV_ENABLE_64BIT - mstatus = set_field(mstatus, MSTATUS64_UA, UA_RV64); - mstatus = set_field(mstatus, MSTATUS64_SA, UA_RV64); -#endif pc = 0x100; load_reservation = -1; } @@ -79,7 +126,7 @@ void processor_t::reset(bool value) return; run = !value; - state.reset(); // reset the core + state.reset(); set_csr(CSR_MSTATUS, state.mstatus); if (ext) @@ -88,7 +135,7 @@ void processor_t::reset(bool value) void processor_t::raise_interrupt(reg_t which) { - throw trap_t(((reg_t)1 << 63) | which); + throw trap_t(((reg_t)1 << (max_xlen-1)) | which); } void processor_t::take_interrupt() @@ -286,20 +333,19 @@ static bool validate_priv(reg_t priv) return priv == PRV_U || priv == PRV_S || priv == PRV_M; } -static bool validate_arch(reg_t arch) +static bool validate_arch(int max_xlen, reg_t arch) { -#ifdef RISCV_ENABLE_64BIT - if (arch == UA_RV64) return true; -#endif + if (max_xlen == 64 && arch == UA_RV64) + return true; return arch == UA_RV32; } -static bool validate_vm(reg_t vm) +static bool validate_vm(int max_xlen, reg_t vm) { - // TODO: VM_SV32 support -#ifdef RISCV_ENABLE_64BIT - if (vm == VM_SV43) return true; -#endif + if (max_xlen == 64 && vm == VM_SV39) + return true; + if (max_xlen == 32 && vm == VM_SV32) + return true; return vm == VM_MBARE; } @@ -340,7 +386,7 @@ void processor_t::set_csr(int which, reg_t val) mask |= MSTATUS_XS; state.mstatus = (state.mstatus & ~mask) | (val & mask); - if (validate_vm(get_field(val, MSTATUS_VM))) + if (validate_vm(max_xlen, get_field(val, MSTATUS_VM))) state.mstatus = (state.mstatus & ~MSTATUS_VM) | (val & MSTATUS_VM); if (validate_priv(get_field(val, MSTATUS_MPRV))) state.mstatus = (state.mstatus & ~MSTATUS_MPRV) | (val & MSTATUS_MPRV); @@ -352,26 +398,26 @@ void processor_t::set_csr(int which, reg_t val) state.mstatus = (state.mstatus & ~MSTATUS_PRV2) | (val & MSTATUS_PRV2); if (validate_priv(get_field(val, MSTATUS_PRV3))) state.mstatus = (state.mstatus & ~MSTATUS_PRV3) | (val & MSTATUS_PRV3); - xlen = 32; bool dirty = (state.mstatus & MSTATUS_FS) == MSTATUS_FS; dirty |= (state.mstatus & MSTATUS_XS) == MSTATUS_XS; -#ifndef RISCV_ENABLE_64BIT - state.mstatus = set_field(state.mstatus, MSTATUS32_SD, dirty); -#else - state.mstatus = set_field(state.mstatus, MSTATUS64_SD, dirty); - - if (validate_arch(get_field(val, MSTATUS64_UA))) - state.mstatus = (state.mstatus & ~MSTATUS64_UA) | (val & MSTATUS64_UA); - if (validate_arch(get_field(val, MSTATUS64_SA))) - state.mstatus = (state.mstatus & ~MSTATUS64_SA) | (val & MSTATUS64_SA); - switch (get_field(state.mstatus, MSTATUS_PRV)) { - case PRV_U: if (get_field(state.mstatus, MSTATUS64_UA)) xlen = 64; break; - case PRV_S: if (get_field(state.mstatus, MSTATUS64_SA)) xlen = 64; break; - case PRV_M: xlen = 64; break; - default: abort(); + xlen = 32; + if (max_xlen == 32) { + state.mstatus = set_field(state.mstatus, MSTATUS32_SD, dirty); + } else { + state.mstatus = set_field(state.mstatus, MSTATUS64_SD, dirty); + + if (validate_arch(max_xlen, get_field(val, MSTATUS64_UA))) + state.mstatus = (state.mstatus & ~MSTATUS64_UA) | (val & MSTATUS64_UA); + if (validate_arch(max_xlen, get_field(val, MSTATUS64_SA))) + state.mstatus = (state.mstatus & ~MSTATUS64_SA) | (val & MSTATUS64_SA); + switch (get_field(state.mstatus, MSTATUS_PRV)) { + case PRV_U: if (get_field(state.mstatus, MSTATUS64_UA)) xlen = 64; break; + case PRV_S: if (get_field(state.mstatus, MSTATUS64_SA)) xlen = 64; break; + case PRV_M: xlen = 64; break; + default: abort(); + } } -#endif break; } case CSR_SSTATUS: @@ -458,8 +504,8 @@ reg_t processor_t::get_csr(int which) case CSR_STVEC: return state.stvec; case CSR_STIMECMP: return state.stimecmp; case CSR_SCAUSE: - if (xlen == 32 && (state.scause >> 63) != 0) - return state.scause | ((reg_t)1 << 31); + if (max_xlen > xlen) + return state.scause | ((state.scause >> (max_xlen-1)) << (xlen-1)); return state.scause; case CSR_SPTBR: return state.sptbr; case CSR_SASID: return 0; diff --git a/riscv/processor.h b/riscv/processor.h index e9d9c4f..c0acad9 100644 --- a/riscv/processor.h +++ b/riscv/processor.h @@ -71,7 +71,7 @@ struct state_t class processor_t { public: - processor_t(sim_t* _sim, mmu_t* _mmu, uint32_t _id); + processor_t(const char* isa, sim_t* sim, uint32_t id); ~processor_t(); void set_debug(bool value); @@ -86,6 +86,7 @@ public: mmu_t* get_mmu() { return mmu; } state_t* get_state() { return &state; } extension_t* get_extension() { return ext; } + bool supports_extension(unsigned char ext) { return subsets[ext]; } void push_privilege_stack(); void pop_privilege_stack(); void yield_load_reservation() { state.load_reservation = (reg_t)-1; } @@ -100,7 +101,9 @@ private: extension_t* ext; disassembler_t* disassembler; state_t state; + bool subsets[256]; uint32_t id; + int max_xlen; int xlen; bool run; // !reset bool debug; @@ -119,6 +122,7 @@ private: friend class mmu_t; friend class extension_t; + void parse_isa_string(const char* isa); void build_opcode_map(); insn_func_t decode_insn(insn_t insn); }; diff --git a/riscv/riscv.ac b/riscv/riscv.ac index 0b095e8..2a8ee53 100644 --- a/riscv/riscv.ac +++ b/riscv/riscv.ac @@ -1,5 +1,9 @@ AC_LANG_CPLUSPLUS +AC_SEARCH_LIBS([dlopen], [dl dld], [], [ + AC_MSG_ERROR([unable to find the dlopen() function]) +]) + AC_ARG_WITH([fesvr], [AS_HELP_STRING([--with-fesvr], [path to your fesvr installation if not in a standard location])], @@ -13,21 +17,6 @@ AC_CHECK_LIB(fesvr, libfesvr_is_present, [], [AC_MSG_ERROR([libfesvr is required AC_CHECK_LIB(pthread, pthread_create, [], [AC_MSG_ERROR([libpthread is required])]) -AC_ARG_ENABLE([fpu], AS_HELP_STRING([--disable-fpu], [Disable floating-point])) -AS_IF([test "x$enable_fpu" != "xno"], [ - AC_DEFINE([RISCV_ENABLE_FPU],,[Define if floating-point instructions are supported]) -]) - -AC_ARG_ENABLE([rvc], AS_HELP_STRING([--disable-rvc], [Disable RISC-V Compressed])) -AS_IF([test "x$enable_rvc" != "xno"], [ - AC_DEFINE([RISCV_ENABLE_RVC],,[Define if RISC-V Compressed is supported]) -]) - -AC_ARG_ENABLE([64bit], AS_HELP_STRING([--disable-64bit], [Disable 64-bit mode])) -AS_IF([test "x$enable_64bit" != "xno"], [ - AC_DEFINE([RISCV_ENABLE_64BIT],,[Define if 64-bit mode is supported]) -]) - 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]) diff --git a/riscv/riscv.mk.in b/riscv/riscv.mk.in index 9e5aa9f..d307259 100644 --- a/riscv/riscv.mk.in +++ b/riscv/riscv.mk.in @@ -35,6 +35,7 @@ riscv_srcs = \ mmu.cc \ disasm.cc \ extension.cc \ + extensions.cc \ rocc.cc \ regnames.cc \ $(riscv_gen_srcs) \ @@ -42,7 +43,7 @@ riscv_srcs = \ riscv_test_srcs = riscv_gen_hdrs = \ - icache.h \ + icache.h \ riscv_gen_srcs = \ $(addsuffix .cc, $(call get_insn_list,$(src_dir)/riscv/encoding.h)) diff --git a/riscv/sim.cc b/riscv/sim.cc index 9490af3..0fdd829 100644 --- a/riscv/sim.cc +++ b/riscv/sim.cc @@ -18,7 +18,8 @@ static void handle_signal(int sig) signal(sig, &handle_signal); } -sim_t::sim_t(size_t nprocs, size_t mem_mb, const std::vector& args) +sim_t::sim_t(const char* isa, size_t nprocs, size_t mem_mb, + const std::vector& args) : htif(new htif_isasim_t(this, args)), procs(std::max(nprocs, size_t(1))), current_step(0), current_proc(0), debug(false) { @@ -40,20 +41,14 @@ sim_t::sim_t(size_t nprocs, size_t mem_mb, const std::vector& args) debug_mmu = new mmu_t(mem, memsz); - for (size_t i = 0; i < procs.size(); i++) { - procs[i] = new processor_t(this, new mmu_t(mem, memsz), i); - } - + for (size_t i = 0; i < procs.size(); i++) + procs[i] = new processor_t(isa, this, i); } sim_t::~sim_t() { for (size_t i = 0; i < procs.size(); i++) - { - mmu_t* pmmu = procs[i]->get_mmu(); delete procs[i]; - delete pmmu; - } delete debug_mmu; free(mem); } diff --git a/riscv/sim.h b/riscv/sim.h index 9e1362e..ca1ad6f 100644 --- a/riscv/sim.h +++ b/riscv/sim.h @@ -15,7 +15,8 @@ class htif_isasim_t; class sim_t { public: - sim_t(size_t _nprocs, size_t mem_mb, const std::vector& htif_args); + sim_t(const char* isa, size_t _nprocs, size_t mem_mb, + const std::vector& htif_args); ~sim_t(); // run the simulation to completion @@ -72,6 +73,7 @@ private: reg_t get_tohost(const std::vector& args); friend class htif_isasim_t; + friend class processor_t; }; extern volatile bool ctrlc_pressed; diff --git a/spike_main/extensions.cc b/spike_main/extensions.cc deleted file mode 100644 index 315621f..0000000 --- a/spike_main/extensions.cc +++ /dev/null @@ -1,35 +0,0 @@ -#include "extension.h" -#include -#include -#include - -static std::map>& extensions() -{ - static std::map> v; - return v; -} - -void register_extension(const char* name, std::function f) -{ - extensions()[name] = f; -} - -std::function find_extension(const char* name) -{ - if (!extensions().count(name)) { - // try to find extension xyz by loading libxyz.so - std::string libname = std::string("lib") + name + ".so"; - if (!dlopen(libname.c_str(), RTLD_LAZY)) { - fprintf(stderr, "couldn't find extension '%s' (or library '%s')\n", - name, libname.c_str()); - exit(-1); - } - if (!extensions().count(name)) { - fprintf(stderr, "couldn't find extension '%s' in shared library '%s'\n", - name, libname.c_str()); - exit(-1); - } - } - - return extensions()[name]; -} diff --git a/spike_main/spike.cc b/spike_main/spike.cc index ab5cea5..7a85bd1 100644 --- a/spike_main/spike.cc +++ b/spike_main/spike.cc @@ -17,11 +17,12 @@ static void help() { fprintf(stderr, "usage: spike [host options] [target options]\n"); fprintf(stderr, "Host Options:\n"); - fprintf(stderr, " -p Simulate processors\n"); - fprintf(stderr, " -m Provide MB of target memory\n"); + fprintf(stderr, " -p Simulate processors [default 1]\n"); + fprintf(stderr, " -m Provide MiB of target memory [default 4096]\n"); fprintf(stderr, " -d Interactive debug mode\n"); fprintf(stderr, " -g Track histogram of PCs\n"); fprintf(stderr, " -h Print this help message\n"); + fprintf(stderr, " --isa= RISC-V ISA string [default RV64IMAFDC]\n"); 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"); @@ -40,6 +41,7 @@ int main(int argc, char** argv) std::unique_ptr dc; std::unique_ptr l2; std::function extension; + const char* isa = "RV64"; option_parser_t parser; parser.help(&help); @@ -51,6 +53,7 @@ int main(int argc, char** argv) 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, "isa", 1, [&](const char* s){isa = s;}); parser.option(0, "extension", 1, [&](const char* s){extension = find_extension(s);}); parser.option(0, "extlib", 1, [&](const char *s){ void *lib = dlopen(s, RTLD_NOW | RTLD_GLOBAL); @@ -64,7 +67,7 @@ int main(int argc, char** argv) if (!*argv1) help(); std::vector htif_args(argv1, (const char*const*)argv + argc); - sim_t s(nprocs, mem_mb, htif_args); + sim_t s(isa, nprocs, mem_mb, htif_args); if (ic && l2) ic->set_miss_handler(&*l2); if (dc && l2) dc->set_miss_handler(&*l2); diff --git a/spike_main/spike_main.ac b/spike_main/spike_main.ac index b913c35..e69de29 100644 --- a/spike_main/spike_main.ac +++ b/spike_main/spike_main.ac @@ -1,3 +0,0 @@ -AC_SEARCH_LIBS([dlopen], [dl dld], [], [ - AC_MSG_ERROR([unable to find the dlopen() function]) -]) diff --git a/spike_main/spike_main.mk.in b/spike_main/spike_main.mk.in index dd67998..500446f 100644 --- a/spike_main/spike_main.mk.in +++ b/spike_main/spike_main.mk.in @@ -11,4 +11,3 @@ spike_main_install_prog_srcs = \ spike_main_hdrs = \ spike_main_srcs = \ - extensions.cc \