Generate and integrate TGF cores in Ecosystem-VP. Remove obsolete cores

This commit is contained in:
Stanislaw Kaushanski 2020-08-24 15:01:54 +02:00
parent 03172e352d
commit 9754e3953f
39 changed files with 944 additions and 72865 deletions

View File

@ -30,33 +30,21 @@ add_subdirectory(softfloat)
FILE(GLOB RiscVSCHeaders ${CMAKE_CURRENT_SOURCE_DIR}/incl/sysc/*.h ${CMAKE_CURRENT_SOURCE_DIR}/incl/sysc/*/*.h) FILE(GLOB RiscVSCHeaders ${CMAKE_CURRENT_SOURCE_DIR}/incl/sysc/*.h ${CMAKE_CURRENT_SOURCE_DIR}/incl/sysc/*/*.h)
set(LIB_HEADERS ${RiscVSCHeaders} ) set(LIB_HEADERS ${RiscVSCHeaders} )
set(LIB_SOURCES set(LIB_SOURCES
src/iss/rv32gc.cpp src/iss/tgf01.cpp
src/iss/rv32imac.cpp src/iss/tgf02.cpp
src/iss/rv64i.cpp
src/iss/rv64gc.cpp
src/iss/mnrv32.cpp
src/vm/fp_functions.cpp src/vm/fp_functions.cpp
src/vm/tcc/vm_mnrv32.cpp src/vm/tcc/vm_tgf01.cpp
src/vm/tcc/vm_rv32gc.cpp src/vm/tcc/vm_tgf02.cpp
src/vm/tcc/vm_rv32imac.cpp src/vm/interp/vm_tgf01.cpp
src/vm/tcc/vm_rv64i.cpp src/vm/interp/vm_tgf02.cpp
src/vm/tcc/vm_rv64gc.cpp
src/vm/interp/vm_mnrv32.cpp
src/vm/interp/vm_rv32gc.cpp
src/vm/interp/vm_rv32imac.cpp
src/vm/interp/vm_rv64i.cpp
src/vm/interp/vm_rv64gc.cpp
src/plugin/instruction_count.cpp src/plugin/instruction_count.cpp
src/plugin/cycle_estimate.cpp src/plugin/cycle_estimate.cpp
) )
if(WITH_LLVM) if(WITH_LLVM)
set(LIB_SOURCES ${LIB_SOURCES} set(LIB_SOURCES ${LIB_SOURCES}
src/vm/llvm/fp_impl.cpp src/vm/llvm/fp_impl.cpp
src/vm/llvm/vm_mnrv32.cpp src/vm/llvm/vm_tgf01.cpp
src/vm/llvm/vm_rv32gc.cpp src/vm/llvm/vm_tgf02.cpp
src/vm/llvm/vm_rv32imac.cpp
src/vm/llvm/vm_rv64i.cpp
src/vm/llvm/vm_rv64gc.cpp
) )
endif() endif()

View File

@ -1,119 +0,0 @@
cmake_minimum_required(VERSION 3.3)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake ${CMAKE_CURRENT_SOURCE_DIR}/sc-components/cmake)
set(ENABLE_SCV TRUE CACHE BOOL "Enable use of SCV")
set(ENABLE_SHARED TRUE CACHE BOOL "Build shared libraries")
include(GitFunctions)
get_branch_from_git()
# if we are not on master or develop set the submodules to develop
IF(NOT ${GIT_BRANCH} MATCHES "master")
IF(NOT ${GIT_BRANCH} MATCHES "develop")
message(STATUS "main branch is '${GIT_BRANCH}', setting submodules to 'develop'")
set(GIT_BRANCH develop)
endif()
endif()
### set the directory names of the submodules
set(GIT_SUBMODULES elfio libGIS sc-components dbt-core)
set(GIT_SUBMODULE_DIR_sc-components .)
set(GIT_SUBMODULE_DIR_dbt-core .)
### set each submodules's commit or tag that is to be checked out
### (leave empty if you want master)
#set(GIT_SUBMODULE_VERSION_sc-comp 3af6b9836589b082c19d9131c5d0b7afa8ddd7cd)
set(GIT_SUBMODULE_BRANCH_sc-components ${GIT_BRANCH})
set(GIT_SUBMODULE_BRANCH_dbt-core ${GIT_BRANCH})
include(GNUInstallDirs)
include(Submodules)
include(Conan)
#enable_testing()
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-march=native" COMPILER_SUPPORTS_MARCH_NATIVE)
if(COMPILER_SUPPORTS_MARCH_NATIVE)
if("${CMAKE_BUILD_TYPE}" STREQUAL "")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native")
elseif(NOT(${CMAKE_BUILD_TYPE} STREQUAL "RelWithDebInfo"))
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native")
endif()
endif()
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
set(warnings "-Wall -Wextra -Werror")
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_GLIBCXX_USE_CXX11_ABI=0")
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG")
set(CMAKE_C_FLAGS_RELEASE "-O3 -DNDEBUG")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
set(warnings "/W4 /WX /EHsc")
endif()
setup_conan()
# This line finds the boost lib and headers.
set(Boost_NO_BOOST_CMAKE ON) # Don't do a find_package in config mode before searching for a regular boost install.
find_package(Boost COMPONENTS program_options system thread filesystem REQUIRED)
if(DEFINED ENV{LLVM_HOME})
find_path (LLVM_DIR LLVM-Config.cmake $ENV{LLVM_HOME}/lib/cmake/llvm)
endif(DEFINED ENV{LLVM_HOME})
find_package(LLVM REQUIRED CONFIG)
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
llvm_map_components_to_libnames(llvm_libs support core mcjit x86codegen x86asmparser)
find_package(Threads)
find_package(Tcmalloc)
find_package(ZLIB)
find_package(SystemC)
if(SystemC_FOUND)
message(STATUS "SystemC headers at ${SystemC_INCLUDE_DIRS}")
message(STATUS "SystemC library at ${SystemC_LIBRARY_DIRS}")
if(SCV_FOUND)
message(STATUS "SCV headers at ${SCV_INCLUDE_DIRS}")
message(STATUS "SCV library at ${SCV_LIBRARY_DIRS}")
endif(SCV_FOUND)
if(CCI_FOUND)
message(STATUS "CCI headers at ${CCI_INCLUDE_DIRS}")
message(STATUS "CCI library at ${CCI_LIBRARY_DIRS}")
endif()
endif(SystemC_FOUND)
set(PROJECT_3PARTY_DIRS external)
include(clang-format)
set(ENABLE_CLANG_TIDY OFF CACHE BOOL "Add clang-tidy automatically to builds")
if (ENABLE_CLANG_TIDY)
find_program (CLANG_TIDY_EXE NAMES "clang-tidy" PATHS /usr/local/opt/llvm/bin )
if (CLANG_TIDY_EXE)
message(STATUS "clang-tidy found: ${CLANG_TIDY_EXE}")
set(CLANG_TIDY_CHECKS "-*,modernize-*")
set(CMAKE_CXX_CLANG_TIDY "${CLANG_TIDY_EXE};-checks=${CLANG_TIDY_CHECKS};-header-filter='${CMAKE_SOURCE_DIR}/*';-fix"
CACHE STRING "" FORCE)
else()
message(AUTHOR_WARNING "clang-tidy not found!")
set(CMAKE_CXX_CLANG_TIDY "" CACHE STRING "" FORCE) # delete it
endif()
endif()
# Set the version number of your project here (format is MAJOR.MINOR.PATCHLEVEL - e.g. 1.0.0)
set(VERSION_MAJOR "1")
set(VERSION_MINOR "0")
set(VERSION_PATCH "0")
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
add_subdirectory(external)
add_subdirectory(dbt-core)
add_subdirectory(sc-components)
add_subdirectory(softfloat)
GET_DIRECTORY_PROPERTY(SOFTFLOAT_INCLUDE_DIRS DIRECTORY softfloat DEFINITION SOFTFLOAT_INCLUDE_DIRS)
add_subdirectory(riscv)
add_subdirectory(platform)
message(STATUS "Build Type: ${CMAKE_BUILD_TYPE}")

View File

@ -1,6 +1,6 @@
import "RV32I.core_desc" import "CoreDSL-Instruction-Set-Description/RV32I.core_desc"
import "RVM.core_desc" import "CoreDSL-Instruction-Set-Description/RVM.core_desc"
import "RVC.core_desc" import "CoreDSL-Instruction-Set-Description/RVC.core_desc"
Core TGF01 provides RV32I { Core TGF01 provides RV32I {
constants { constants {
@ -9,6 +9,8 @@ Core TGF01 provides RV32I {
// definitions for the architecture wrapper // definitions for the architecture wrapper
// XL ZYXWVUTSRQPONMLKJIHGFEDCBA // XL ZYXWVUTSRQPONMLKJIHGFEDCBA
MISA_VAL:=0b01000000000000000000000100000000; MISA_VAL:=0b01000000000000000000000100000000;
PGSIZE := 0x1000; //1 << 12;
PGMASK := 0xfff; //PGSIZE-1
} }
} }
@ -20,5 +22,7 @@ Core TGF02 provides RV32I, RV32M, RV32IC {
// definitions for the architecture wrapper // definitions for the architecture wrapper
// XL ZYXWVUTSRQPONMLKJIHGFEDCBA // XL ZYXWVUTSRQPONMLKJIHGFEDCBA
MISA_VAL:=0b01000000000000000001000100000100; MISA_VAL:=0b01000000000000000001000100000100;
PGSIZE := 0x1000; //1 << 12;
PGMASK := 0xfff; //PGSIZE-1
} }
} }

View File

@ -32,7 +32,7 @@
#include "../fp_functions.h" #include "../fp_functions.h"
#include <iss/arch/${coreDef.name.toLowerCase()}.h> #include <iss/arch/${coreDef.name.toLowerCase()}.h>
#include <iss/arch/riscv_hart_msu_vp.h> #include <iss/arch/riscv_hart_m_p.h>
#include <iss/debugger/gdb_session.h> #include <iss/debugger/gdb_session.h>
#include <iss/debugger/server.h> #include <iss/debugger/server.h>
#include <iss/iss.h> #include <iss/iss.h>

View File

@ -31,7 +31,7 @@
*******************************************************************************/ *******************************************************************************/
#include <iss/arch/${coreDef.name.toLowerCase()}.h> #include <iss/arch/${coreDef.name.toLowerCase()}.h>
#include <iss/arch/riscv_hart_msu_vp.h> #include <iss/arch/riscv_hart_m_p.h>
#include <iss/debugger/gdb_session.h> #include <iss/debugger/gdb_session.h>
#include <iss/debugger/server.h> #include <iss/debugger/server.h>
#include <iss/iss.h> #include <iss/iss.h>

View File

@ -31,7 +31,7 @@
*******************************************************************************/ *******************************************************************************/
#include <iss/arch/${coreDef.name.toLowerCase()}.h> #include <iss/arch/${coreDef.name.toLowerCase()}.h>
#include <iss/arch/riscv_hart_msu_vp.h> #include <iss/arch/riscv_hart_m_p.h>
#include <iss/debugger/gdb_session.h> #include <iss/debugger/gdb_session.h>
#include <iss/debugger/server.h> #include <iss/debugger/server.h>
#include <iss/iss.h> #include <iss/iss.h>

View File

@ -1,252 +0,0 @@
/*******************************************************************************
* Copyright (C) 2017, 2018 MINRES Technologies GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*******************************************************************************/
#ifndef _MNRV32_H_
#define _MNRV32_H_
#include <array>
#include <iss/arch/traits.h>
#include <iss/arch_if.h>
#include <iss/vm_if.h>
namespace iss {
namespace arch {
struct mnrv32;
template <> struct traits<mnrv32> {
constexpr static char const* const core_type = "MNRV32";
static constexpr std::array<const char*, 33> reg_names{
{"x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26", "x27", "x28", "x29", "x30", "x31", "pc"}};
static constexpr std::array<const char*, 33> reg_aliases{
{"zero", "ra", "sp", "gp", "tp", "t0", "t1", "t2", "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6", "pc"}};
enum constants {XLEN=32, PCLEN=32, MISA_VAL=0b1000000000101000001000100000101, PGSIZE=0x1000, PGMASK=0xfff};
constexpr static unsigned FP_REGS_SIZE = 0;
enum reg_e {
X0,
X1,
X2,
X3,
X4,
X5,
X6,
X7,
X8,
X9,
X10,
X11,
X12,
X13,
X14,
X15,
X16,
X17,
X18,
X19,
X20,
X21,
X22,
X23,
X24,
X25,
X26,
X27,
X28,
X29,
X30,
X31,
PC,
NUM_REGS,
NEXT_PC=NUM_REGS,
TRAP_STATE,
PENDING_TRAP,
MACHINE_STATE,
LAST_BRANCH,
ICOUNT,
ZERO = X0,
RA = X1,
SP = X2,
GP = X3,
TP = X4,
T0 = X5,
T1 = X6,
T2 = X7,
S0 = X8,
S1 = X9,
A0 = X10,
A1 = X11,
A2 = X12,
A3 = X13,
A4 = X14,
A5 = X15,
A6 = X16,
A7 = X17,
S2 = X18,
S3 = X19,
S4 = X20,
S5 = X21,
S6 = X22,
S7 = X23,
S8 = X24,
S9 = X25,
S10 = X26,
S11 = X27,
T3 = X28,
T4 = X29,
T5 = X30,
T6 = X31
};
using reg_t = uint32_t;
using addr_t = uint32_t;
using code_word_t = uint32_t; //TODO: check removal
using virt_addr_t = iss::typed_addr_t<iss::address_type::VIRTUAL>;
using phys_addr_t = iss::typed_addr_t<iss::address_type::PHYSICAL>;
static constexpr std::array<const uint32_t, 39> reg_bit_widths{
{32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,64}};
static constexpr std::array<const uint32_t, 40> reg_byte_offsets{
{0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,132,136,140,144,148,152,160}};
static const uint64_t addr_mask = (reg_t(1) << (XLEN - 1)) | ((reg_t(1) << (XLEN - 1)) - 1);
enum sreg_flag_e { FLAGS };
enum mem_type_e { MEM, CSR, FENCE, RES };
};
struct mnrv32: public arch_if {
using virt_addr_t = typename traits<mnrv32>::virt_addr_t;
using phys_addr_t = typename traits<mnrv32>::phys_addr_t;
using reg_t = typename traits<mnrv32>::reg_t;
using addr_t = typename traits<mnrv32>::addr_t;
mnrv32();
~mnrv32();
void reset(uint64_t address=0) override;
uint8_t* get_regs_base_ptr() override;
/// deprecated
void get_reg(short idx, std::vector<uint8_t>& value) override {}
void set_reg(short idx, const std::vector<uint8_t>& value) override {}
/// deprecated
bool get_flag(int flag) override {return false;}
void set_flag(int, bool value) override {};
/// deprecated
void update_flags(operations op, uint64_t opr1, uint64_t opr2) override {};
inline uint64_t get_icount() { return reg.icount; }
inline bool should_stop() { return interrupt_sim; }
inline uint64_t stop_code() { return interrupt_sim; }
inline phys_addr_t v2p(const iss::addr_t& addr){
if (addr.space != traits<mnrv32>::MEM || addr.type == iss::address_type::PHYSICAL ||
addr_mode[static_cast<uint16_t>(addr.access)&0x3]==address_type::PHYSICAL) {
return phys_addr_t(addr.access, addr.space, addr.val&traits<mnrv32>::addr_mask);
} else
return virt2phys(addr);
}
virtual phys_addr_t virt2phys(const iss::addr_t& addr);
virtual iss::sync_type needed_sync() const { return iss::NO_SYNC; }
inline uint32_t get_last_branch() { return reg.last_branch; }
protected:
struct MNRV32_regs {
uint32_t X0 = 0;
uint32_t X1 = 0;
uint32_t X2 = 0;
uint32_t X3 = 0;
uint32_t X4 = 0;
uint32_t X5 = 0;
uint32_t X6 = 0;
uint32_t X7 = 0;
uint32_t X8 = 0;
uint32_t X9 = 0;
uint32_t X10 = 0;
uint32_t X11 = 0;
uint32_t X12 = 0;
uint32_t X13 = 0;
uint32_t X14 = 0;
uint32_t X15 = 0;
uint32_t X16 = 0;
uint32_t X17 = 0;
uint32_t X18 = 0;
uint32_t X19 = 0;
uint32_t X20 = 0;
uint32_t X21 = 0;
uint32_t X22 = 0;
uint32_t X23 = 0;
uint32_t X24 = 0;
uint32_t X25 = 0;
uint32_t X26 = 0;
uint32_t X27 = 0;
uint32_t X28 = 0;
uint32_t X29 = 0;
uint32_t X30 = 0;
uint32_t X31 = 0;
uint32_t PC = 0;
uint32_t NEXT_PC = 0;
uint32_t trap_state = 0, pending_trap = 0, machine_state = 0, last_branch = 0;
uint64_t icount = 0;
} reg;
std::array<address_type, 4> addr_mode;
uint64_t interrupt_sim=0;
uint32_t get_fcsr(){return 0;}
void set_fcsr(uint32_t val){}
};
}
}
#endif /* _MNRV32_H_ */

View File

@ -268,10 +268,10 @@ public:
}; };
} }
template <typename BASE> class riscv_hart_msu_vp : public BASE { template <typename BASE> class riscv_hart_m_p : public BASE {
public: public:
using super = BASE; using super = BASE;
using this_class = riscv_hart_msu_vp<BASE>; using this_class = riscv_hart_m_p<BASE>;
using virt_addr_t = typename super::virt_addr_t; using virt_addr_t = typename super::virt_addr_t;
using phys_addr_t = typename super::phys_addr_t; using phys_addr_t = typename super::phys_addr_t;
using reg_t = typename super::reg_t; using reg_t = typename super::reg_t;
@ -360,97 +360,6 @@ public:
return {0, 0, 0, 0}; // dummy return {0, 0, 0, 0}; // dummy
} }
}; };
// specialization 64bit
template <typename T> class hart_state<T, typename std::enable_if<std::is_same<T, uint64_t>::value>::type> {
public:
BEGIN_BF_DECL(mstatus_t, T);
// SD bit is read-only and is set when either the FS or XS bits encode a Dirty state (i.e., SD=((FS==11) OR XS==11)))
BF_FIELD(SD, 63, 1);
// value of XLEN for S-mode
BF_FIELD(SXL, 34, 2);
// value of XLEN for U-mode
BF_FIELD(UXL, 32, 2);
// Trap SRET
BF_FIELD(TSR, 22, 1);
// Timeout Wait
BF_FIELD(TW, 21, 1);
// Trap Virtual Memory
BF_FIELD(TVM, 20, 1);
// Make eXecutable Readable
BF_FIELD(MXR, 19, 1);
// permit Supervisor User Memory access
BF_FIELD(SUM, 18, 1);
// Modify PRiVilege
BF_FIELD(MPRV, 17, 1);
// status of additional user-mode extensions and associated state, All off/None dirty or clean, some on/None dirty, some clean/Some dirty
BF_FIELD(XS, 15, 2);
// floating-point unit status Off/Initial/Clean/Dirty
BF_FIELD(FS, 13, 2);
// machine previous privilege
BF_FIELD(MPP, 11, 2);
// supervisor previous privilege
BF_FIELD(SPP, 8, 1);
// previous machine interrupt-enable
BF_FIELD(MPIE, 7, 1);
// previous supervisor interrupt-enable
BF_FIELD(SPIE, 5, 1);
// previous user interrupt-enable
BF_FIELD(UPIE, 4, 1);
// machine interrupt-enable
BF_FIELD(MIE, 3, 1);
// supervisor interrupt-enable
BF_FIELD(SIE, 1, 1);
// user interrupt-enable
BF_FIELD(UIE, 0, 1);
END_BF_DECL();
mstatus_t mstatus;
static const reg_t mstatus_reset_val = 0xa00000000;
void write_mstatus(T val, unsigned priv_lvl) {
T old_val = mstatus;
auto mask = get_mask(priv_lvl);
auto new_val = (old_val & ~mask) | (val & mask);
if ((new_val & mstatus.SXL.Mask) == 0) {
new_val |= old_val & mstatus.SXL.Mask;
}
if ((new_val & mstatus.UXL.Mask) == 0) {
new_val |= old_val & mstatus.UXL.Mask;
}
mstatus = new_val;
}
T satp;
static constexpr T get_misa() { return (2ULL << 62) | ISA_I | ISA_M | ISA_A | ISA_U | ISA_S | ISA_M; }
static constexpr T get_mask(unsigned priv_lvl) {
uint64_t ret;
switch (priv_lvl) {
case PRIV_U: ret = 0x8000000f00000011ULL;break; // 0b1...0 1111 0000 0000 0111 1111 1111 1001 1011 1011
case PRIV_S: ret = 0x8000000f000de133ULL;break; // 0b1...0 0011 0000 0000 0000 1101 1110 0001 0011 0011
default: ret = 0x8000000f007ff9ddULL;break; // 0b1...0 1111 0000 0000 0111 1111 1111 1001 1011 1011
}
return ret;
}
static inline vm_info decode_vm_info(uint32_t state, T sptbr) {
if (state == PRIV_M) return {0, 0, 0, 0};
if (state <= PRIV_S)
switch (bit_sub<60, 4>(sptbr)) {
case 0: return {0, 0, 0, 0}; // off
case 8: return {3, 9, 8, bit_sub<0, 44>(sptbr) << PGSHIFT};// SV39
case 9: return {4, 9, 8, bit_sub<0, 44>(sptbr) << PGSHIFT};// SV48
case 10: return {5, 9, 8, bit_sub<0, 44>(sptbr) << PGSHIFT};// SV57
case 11: return {6, 9, 8, bit_sub<0, 44>(sptbr) << PGSHIFT};// SV64
default: abort();
}
abort();
return {0, 0, 0, 0}; // dummy
}
};
const typename super::reg_t PGSIZE = 1 << PGSHIFT; const typename super::reg_t PGSIZE = 1 << PGSHIFT;
const typename super::reg_t PGMASK = PGSIZE - 1; const typename super::reg_t PGMASK = PGSIZE - 1;
@ -464,8 +373,8 @@ public:
return m[mode]; return m[mode];
} }
riscv_hart_msu_vp(); riscv_hart_m_p();
virtual ~riscv_hart_msu_vp() = default; virtual ~riscv_hart_m_p() = default;
void reset(uint64_t address) override; void reset(uint64_t address) override;
@ -478,7 +387,7 @@ public:
iss::status write(const address_type type, const access_type access, const uint32_t space, iss::status write(const address_type type, const access_type access, const uint32_t space,
const uint64_t addr, const unsigned length, const uint8_t *const data) override; const uint64_t addr, const unsigned length, const uint8_t *const data) override;
virtual uint64_t enter_trap(uint64_t flags) override { return riscv_hart_msu_vp::enter_trap(flags, fault_data); } virtual uint64_t enter_trap(uint64_t flags) override { return riscv_hart_m_p::enter_trap(flags, fault_data); }
virtual uint64_t enter_trap(uint64_t flags, uint64_t addr) override; virtual uint64_t enter_trap(uint64_t flags, uint64_t addr) override;
virtual uint64_t leave_trap(uint64_t flags) override; virtual uint64_t leave_trap(uint64_t flags) override;
void wait_until(uint64_t flags) override; void wait_until(uint64_t flags) override;
@ -493,7 +402,7 @@ public:
protected: protected:
struct riscv_instrumentation_if : public iss::instrumentation_if { struct riscv_instrumentation_if : public iss::instrumentation_if {
riscv_instrumentation_if(riscv_hart_msu_vp<BASE> &arch) riscv_instrumentation_if(riscv_hart_m_p<BASE> &arch)
: arch(arch) {} : arch(arch) {}
/** /**
* get the name of this architecture * get the name of this architecture
@ -508,7 +417,7 @@ protected:
virtual void set_curr_instr_cycles(unsigned cycles) { arch.cycle_offset += cycles - 1; }; virtual void set_curr_instr_cycles(unsigned cycles) { arch.cycle_offset += cycles - 1; };
riscv_hart_msu_vp<BASE> &arch; riscv_hart_m_p<BASE> &arch;
}; };
friend struct riscv_instrumentation_if; friend struct riscv_instrumentation_if;
@ -561,7 +470,7 @@ protected:
}; };
template <typename BASE> template <typename BASE>
riscv_hart_msu_vp<BASE>::riscv_hart_msu_vp() riscv_hart_m_p<BASE>::riscv_hart_m_p()
: state() : state()
, cycle_offset(0) , cycle_offset(0)
, instr_if(*this) { , instr_if(*this) {
@ -572,43 +481,43 @@ riscv_hart_msu_vp<BASE>::riscv_hart_msu_vp()
for (unsigned addr = mcycle; addr <= hpmcounter31; ++addr) csr_wr_cb[addr] = nullptr; for (unsigned addr = mcycle; addr <= hpmcounter31; ++addr) csr_wr_cb[addr] = nullptr;
for (unsigned addr = mcycleh; addr <= hpmcounter31h; ++addr) csr_wr_cb[addr] = nullptr; for (unsigned addr = mcycleh; addr <= hpmcounter31h; ++addr) csr_wr_cb[addr] = nullptr;
// special handling // special handling
csr_rd_cb[time] = &riscv_hart_msu_vp<BASE>::read_time; csr_rd_cb[time] = &riscv_hart_m_p<BASE>::read_time;
csr_wr_cb[time] = nullptr; csr_wr_cb[time] = nullptr;
csr_rd_cb[timeh] = &riscv_hart_msu_vp<BASE>::read_time; csr_rd_cb[timeh] = &riscv_hart_m_p<BASE>::read_time;
csr_wr_cb[timeh] = nullptr; csr_wr_cb[timeh] = nullptr;
csr_rd_cb[mcycle] = &riscv_hart_msu_vp<BASE>::read_cycle; csr_rd_cb[mcycle] = &riscv_hart_m_p<BASE>::read_cycle;
csr_rd_cb[mcycleh] = &riscv_hart_msu_vp<BASE>::read_cycle; csr_rd_cb[mcycleh] = &riscv_hart_m_p<BASE>::read_cycle;
csr_rd_cb[minstret] = &riscv_hart_msu_vp<BASE>::read_cycle; csr_rd_cb[minstret] = &riscv_hart_m_p<BASE>::read_cycle;
csr_rd_cb[minstreth] = &riscv_hart_msu_vp<BASE>::read_cycle; csr_rd_cb[minstreth] = &riscv_hart_m_p<BASE>::read_cycle;
csr_rd_cb[mstatus] = &riscv_hart_msu_vp<BASE>::read_status; csr_rd_cb[mstatus] = &riscv_hart_m_p<BASE>::read_status;
csr_wr_cb[mstatus] = &riscv_hart_msu_vp<BASE>::write_status; csr_wr_cb[mstatus] = &riscv_hart_m_p<BASE>::write_status;
csr_rd_cb[sstatus] = &riscv_hart_msu_vp<BASE>::read_status; csr_rd_cb[sstatus] = &riscv_hart_m_p<BASE>::read_status;
csr_wr_cb[sstatus] = &riscv_hart_msu_vp<BASE>::write_status; csr_wr_cb[sstatus] = &riscv_hart_m_p<BASE>::write_status;
csr_rd_cb[ustatus] = &riscv_hart_msu_vp<BASE>::read_status; csr_rd_cb[ustatus] = &riscv_hart_m_p<BASE>::read_status;
csr_wr_cb[ustatus] = &riscv_hart_msu_vp<BASE>::write_status; csr_wr_cb[ustatus] = &riscv_hart_m_p<BASE>::write_status;
csr_rd_cb[mip] = &riscv_hart_msu_vp<BASE>::read_ip; csr_rd_cb[mip] = &riscv_hart_m_p<BASE>::read_ip;
csr_wr_cb[mip] = &riscv_hart_msu_vp<BASE>::write_ip; csr_wr_cb[mip] = &riscv_hart_m_p<BASE>::write_ip;
csr_rd_cb[sip] = &riscv_hart_msu_vp<BASE>::read_ip; csr_rd_cb[sip] = &riscv_hart_m_p<BASE>::read_ip;
csr_wr_cb[sip] = &riscv_hart_msu_vp<BASE>::write_ip; csr_wr_cb[sip] = &riscv_hart_m_p<BASE>::write_ip;
csr_rd_cb[uip] = &riscv_hart_msu_vp<BASE>::read_ip; csr_rd_cb[uip] = &riscv_hart_m_p<BASE>::read_ip;
csr_wr_cb[uip] = &riscv_hart_msu_vp<BASE>::write_ip; csr_wr_cb[uip] = &riscv_hart_m_p<BASE>::write_ip;
csr_rd_cb[mie] = &riscv_hart_msu_vp<BASE>::read_ie; csr_rd_cb[mie] = &riscv_hart_m_p<BASE>::read_ie;
csr_wr_cb[mie] = &riscv_hart_msu_vp<BASE>::write_ie; csr_wr_cb[mie] = &riscv_hart_m_p<BASE>::write_ie;
csr_rd_cb[sie] = &riscv_hart_msu_vp<BASE>::read_ie; csr_rd_cb[sie] = &riscv_hart_m_p<BASE>::read_ie;
csr_wr_cb[sie] = &riscv_hart_msu_vp<BASE>::write_ie; csr_wr_cb[sie] = &riscv_hart_m_p<BASE>::write_ie;
csr_rd_cb[uie] = &riscv_hart_msu_vp<BASE>::read_ie; csr_rd_cb[uie] = &riscv_hart_m_p<BASE>::read_ie;
csr_wr_cb[uie] = &riscv_hart_msu_vp<BASE>::write_ie; csr_wr_cb[uie] = &riscv_hart_m_p<BASE>::write_ie;
csr_rd_cb[satp] = &riscv_hart_msu_vp<BASE>::read_satp; csr_rd_cb[satp] = &riscv_hart_m_p<BASE>::read_satp;
csr_wr_cb[satp] = &riscv_hart_msu_vp<BASE>::write_satp; csr_wr_cb[satp] = &riscv_hart_m_p<BASE>::write_satp;
csr_rd_cb[fcsr] = &riscv_hart_msu_vp<BASE>::read_fcsr; csr_rd_cb[fcsr] = &riscv_hart_m_p<BASE>::read_fcsr;
csr_wr_cb[fcsr] = &riscv_hart_msu_vp<BASE>::write_fcsr; csr_wr_cb[fcsr] = &riscv_hart_m_p<BASE>::write_fcsr;
csr_rd_cb[fflags] = &riscv_hart_msu_vp<BASE>::read_fcsr; csr_rd_cb[fflags] = &riscv_hart_m_p<BASE>::read_fcsr;
csr_wr_cb[fflags] = &riscv_hart_msu_vp<BASE>::write_fcsr; csr_wr_cb[fflags] = &riscv_hart_m_p<BASE>::write_fcsr;
csr_rd_cb[frm] = &riscv_hart_msu_vp<BASE>::read_fcsr; csr_rd_cb[frm] = &riscv_hart_m_p<BASE>::read_fcsr;
csr_wr_cb[frm] = &riscv_hart_msu_vp<BASE>::write_fcsr; csr_wr_cb[frm] = &riscv_hart_m_p<BASE>::write_fcsr;
} }
template <typename BASE> std::pair<uint64_t, bool> riscv_hart_msu_vp<BASE>::load_file(std::string name, int type) { template <typename BASE> std::pair<uint64_t, bool> riscv_hart_m_p<BASE>::load_file(std::string name, int type) {
FILE *fp = fopen(name.c_str(), "r"); FILE *fp = fopen(name.c_str(), "r");
if (fp) { if (fp) {
std::array<char, 5> buf; std::array<char, 5> buf;
@ -653,7 +562,7 @@ template <typename BASE> std::pair<uint64_t, bool> riscv_hart_msu_vp<BASE>::load
} }
template <typename BASE> template <typename BASE>
iss::status riscv_hart_msu_vp<BASE>::read(const address_type type, const access_type access, const uint32_t space, iss::status riscv_hart_m_p<BASE>::read(const address_type type, const access_type access, const uint32_t space,
const uint64_t addr, const unsigned length, uint8_t *const data) { const uint64_t addr, const unsigned length, uint8_t *const data) {
#ifndef NDEBUG #ifndef NDEBUG
if (access && iss::access_type::DEBUG) { if (access && iss::access_type::DEBUG) {
@ -733,7 +642,7 @@ iss::status riscv_hart_msu_vp<BASE>::read(const address_type type, const access_
} }
template <typename BASE> template <typename BASE>
iss::status riscv_hart_msu_vp<BASE>::write(const address_type type, const access_type access, const uint32_t space, iss::status riscv_hart_m_p<BASE>::write(const address_type type, const access_type access, const uint32_t space,
const uint64_t addr, const unsigned length, const uint8_t *const data) { const uint64_t addr, const unsigned length, const uint8_t *const data) {
#ifndef NDEBUG #ifndef NDEBUG
const char *prefix = (access && iss::access_type::DEBUG) ? "debug " : ""; const char *prefix = (access && iss::access_type::DEBUG) ? "debug " : "";
@ -855,7 +764,7 @@ iss::status riscv_hart_msu_vp<BASE>::write(const address_type type, const access
} }
} }
template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_csr(unsigned addr, reg_t &val) { template <typename BASE> iss::status riscv_hart_m_p<BASE>::read_csr(unsigned addr, reg_t &val) {
if (addr >= csr.size()) return iss::Err; if (addr >= csr.size()) return iss::Err;
auto req_priv_lvl = (addr >> 8) & 0x3; auto req_priv_lvl = (addr >> 8) & 0x3;
if (this->reg.machine_state < req_priv_lvl) throw illegal_instruction_fault(this->fault_data); if (this->reg.machine_state < req_priv_lvl) throw illegal_instruction_fault(this->fault_data);
@ -869,7 +778,7 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_csr(unsigned
return (this->*f)(addr, val); return (this->*f)(addr, val);
} }
template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_csr(unsigned addr, reg_t val) { template <typename BASE> iss::status riscv_hart_m_p<BASE>::write_csr(unsigned addr, reg_t val) {
if (addr >= csr.size()) return iss::Err; if (addr >= csr.size()) return iss::Err;
auto req_priv_lvl = (addr >> 8) & 0x3; auto req_priv_lvl = (addr >> 8) & 0x3;
if (this->reg.machine_state < req_priv_lvl) if (this->reg.machine_state < req_priv_lvl)
@ -886,7 +795,7 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_csr(unsigned
return (this->*f)(addr, val); return (this->*f)(addr, val);
} }
template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_cycle(unsigned addr, reg_t &val) { template <typename BASE> iss::status riscv_hart_m_p<BASE>::read_cycle(unsigned addr, reg_t &val) {
auto cycle_val = this->reg.icount + cycle_offset; auto cycle_val = this->reg.icount + cycle_offset;
if (addr == mcycle) { if (addr == mcycle) {
val = static_cast<reg_t>(cycle_val); val = static_cast<reg_t>(cycle_val);
@ -897,7 +806,7 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_cycle(unsigne
return iss::Ok; return iss::Ok;
} }
template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_time(unsigned addr, reg_t &val) { template <typename BASE> iss::status riscv_hart_m_p<BASE>::read_time(unsigned addr, reg_t &val) {
uint64_t time_val = (this->reg.icount + cycle_offset) / (100000000 / 32768 - 1); //-> ~3052; uint64_t time_val = (this->reg.icount + cycle_offset) / (100000000 / 32768 - 1); //-> ~3052;
if (addr == time) { if (addr == time) {
val = static_cast<reg_t>(time_val); val = static_cast<reg_t>(time_val);
@ -908,13 +817,13 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_time(unsigned
return iss::Ok; return iss::Ok;
} }
template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_status(unsigned addr, reg_t &val) { template <typename BASE> iss::status riscv_hart_m_p<BASE>::read_status(unsigned addr, reg_t &val) {
auto req_priv_lvl = (addr >> 8) & 0x3; auto req_priv_lvl = (addr >> 8) & 0x3;
val = state.mstatus & hart_state<reg_t>::get_mask(req_priv_lvl); val = state.mstatus & hart_state<reg_t>::get_mask(req_priv_lvl);
return iss::Ok; return iss::Ok;
} }
template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_status(unsigned addr, reg_t val) { template <typename BASE> iss::status riscv_hart_m_p<BASE>::write_status(unsigned addr, reg_t val) {
auto req_priv_lvl = (addr >> 8) & 0x3; auto req_priv_lvl = (addr >> 8) & 0x3;
state.write_mstatus(val, req_priv_lvl); state.write_mstatus(val, req_priv_lvl);
check_interrupt(); check_interrupt();
@ -922,14 +831,14 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_status(unsig
return iss::Ok; return iss::Ok;
} }
template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_ie(unsigned addr, reg_t &val) { template <typename BASE> iss::status riscv_hart_m_p<BASE>::read_ie(unsigned addr, reg_t &val) {
val = csr[mie]; val = csr[mie];
if (addr < mie) val &= csr[mideleg]; if (addr < mie) val &= csr[mideleg];
if (addr < sie) val &= csr[sideleg]; if (addr < sie) val &= csr[sideleg];
return iss::Ok; return iss::Ok;
} }
template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_ie(unsigned addr, reg_t val) { template <typename BASE> iss::status riscv_hart_m_p<BASE>::write_ie(unsigned addr, reg_t val) {
auto req_priv_lvl = (addr >> 8) & 0x3; auto req_priv_lvl = (addr >> 8) & 0x3;
auto mask = get_irq_mask(req_priv_lvl); auto mask = get_irq_mask(req_priv_lvl);
csr[mie] = (csr[mie] & ~mask) | (val & mask); csr[mie] = (csr[mie] & ~mask) | (val & mask);
@ -937,14 +846,14 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_ie(unsigned
return iss::Ok; return iss::Ok;
} }
template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_ip(unsigned addr, reg_t &val) { template <typename BASE> iss::status riscv_hart_m_p<BASE>::read_ip(unsigned addr, reg_t &val) {
val = csr[mip]; val = csr[mip];
if (addr < mip) val &= csr[mideleg]; if (addr < mip) val &= csr[mideleg];
if (addr < sip) val &= csr[sideleg]; if (addr < sip) val &= csr[sideleg];
return iss::Ok; return iss::Ok;
} }
template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_ip(unsigned addr, reg_t val) { template <typename BASE> iss::status riscv_hart_m_p<BASE>::write_ip(unsigned addr, reg_t val) {
auto req_priv_lvl = (addr >> 8) & 0x3; auto req_priv_lvl = (addr >> 8) & 0x3;
auto mask = get_irq_mask(req_priv_lvl); auto mask = get_irq_mask(req_priv_lvl);
mask &= ~(1 << 7); // MTIP is read only mask &= ~(1 << 7); // MTIP is read only
@ -953,7 +862,7 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_ip(unsigned
return iss::Ok; return iss::Ok;
} }
template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_satp(unsigned addr, reg_t &val) { template <typename BASE> iss::status riscv_hart_m_p<BASE>::read_satp(unsigned addr, reg_t &val) {
reg_t tvm = state.mstatus.TVM; reg_t tvm = state.mstatus.TVM;
if (this->reg.machine_state == PRIV_S & tvm != 0) { if (this->reg.machine_state == PRIV_S & tvm != 0) {
this->reg.trap_state = (1 << 31) | (2 << 16); this->reg.trap_state = (1 << 31) | (2 << 16);
@ -964,7 +873,7 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_satp(unsigned
return iss::Ok; return iss::Ok;
} }
template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_satp(unsigned addr, reg_t val) { template <typename BASE> iss::status riscv_hart_m_p<BASE>::write_satp(unsigned addr, reg_t val) {
reg_t tvm = state.mstatus.TVM; reg_t tvm = state.mstatus.TVM;
if (this->reg.machine_state == PRIV_S & tvm != 0) { if (this->reg.machine_state == PRIV_S & tvm != 0) {
this->reg.trap_state = (1 << 31) | (2 << 16); this->reg.trap_state = (1 << 31) | (2 << 16);
@ -975,7 +884,7 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_satp(unsigne
update_vm_info(); update_vm_info();
return iss::Ok; return iss::Ok;
} }
template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_fcsr(unsigned addr, reg_t &val) { template <typename BASE> iss::status riscv_hart_m_p<BASE>::read_fcsr(unsigned addr, reg_t &val) {
switch (addr) { switch (addr) {
case 1: // fflags, 4:0 case 1: // fflags, 4:0
val = bit_sub<0, 5>(this->get_fcsr()); val = bit_sub<0, 5>(this->get_fcsr());
@ -992,7 +901,7 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_fcsr(unsigned
return iss::Ok; return iss::Ok;
} }
template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_fcsr(unsigned addr, reg_t val) { template <typename BASE> iss::status riscv_hart_m_p<BASE>::write_fcsr(unsigned addr, reg_t val) {
switch (addr) { switch (addr) {
case 1: // fflags, 4:0 case 1: // fflags, 4:0
this->set_fcsr((this->get_fcsr() & 0xffffffe0) | (val & 0x1f)); this->set_fcsr((this->get_fcsr() & 0xffffffe0) | (val & 0x1f));
@ -1010,7 +919,7 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_fcsr(unsigne
} }
template <typename BASE> template <typename BASE>
iss::status riscv_hart_msu_vp<BASE>::read_mem(phys_addr_t paddr, unsigned length, uint8_t *const data) { iss::status riscv_hart_m_p<BASE>::read_mem(phys_addr_t paddr, unsigned length, uint8_t *const data) {
if ((paddr.val + length) > mem.size()) return iss::Err; if ((paddr.val + length) > mem.size()) return iss::Err;
switch (paddr.val) { switch (paddr.val) {
case 0x0200BFF8: { // CLINT base, mtime reg case 0x0200BFF8: { // CLINT base, mtime reg
@ -1035,7 +944,7 @@ iss::status riscv_hart_msu_vp<BASE>::read_mem(phys_addr_t paddr, unsigned length
} }
template <typename BASE> template <typename BASE>
iss::status riscv_hart_msu_vp<BASE>::write_mem(phys_addr_t paddr, unsigned length, const uint8_t *const data) { iss::status riscv_hart_m_p<BASE>::write_mem(phys_addr_t paddr, unsigned length, const uint8_t *const data) {
if ((paddr.val + length) > mem.size()) return iss::Err; if ((paddr.val + length) > mem.size()) return iss::Err;
switch (paddr.val) { switch (paddr.val) {
case 0x10013000: // UART0 base, TXFIFO reg case 0x10013000: // UART0 base, TXFIFO reg
@ -1112,13 +1021,13 @@ iss::status riscv_hart_msu_vp<BASE>::write_mem(phys_addr_t paddr, unsigned lengt
return iss::Ok; return iss::Ok;
} }
template <typename BASE> inline void riscv_hart_msu_vp<BASE>::reset(uint64_t address) { template <typename BASE> inline void riscv_hart_m_p<BASE>::reset(uint64_t address) {
BASE::reset(address); BASE::reset(address);
state.mstatus = hart_state<reg_t>::mstatus_reset_val; state.mstatus = hart_state<reg_t>::mstatus_reset_val;
update_vm_info(); update_vm_info();
} }
template <typename BASE> inline void riscv_hart_msu_vp<BASE>::update_vm_info() { template <typename BASE> inline void riscv_hart_m_p<BASE>::update_vm_info() {
vm[1] = hart_state<reg_t>::decode_vm_info(this->reg.machine_state, state.satp); vm[1] = hart_state<reg_t>::decode_vm_info(this->reg.machine_state, state.satp);
BASE::addr_mode[3]=BASE::addr_mode[2] = vm[1].is_active()? iss::address_type::VIRTUAL : iss::address_type::PHYSICAL; BASE::addr_mode[3]=BASE::addr_mode[2] = vm[1].is_active()? iss::address_type::VIRTUAL : iss::address_type::PHYSICAL;
if (state.mstatus.MPRV) if (state.mstatus.MPRV)
@ -1129,7 +1038,7 @@ template <typename BASE> inline void riscv_hart_msu_vp<BASE>::update_vm_info() {
ptw.clear(); ptw.clear();
} }
template <typename BASE> void riscv_hart_msu_vp<BASE>::check_interrupt() { template <typename BASE> void riscv_hart_m_p<BASE>::check_interrupt() {
auto status = state.mstatus; auto status = state.mstatus;
auto ip = csr[mip]; auto ip = csr[mip];
auto ie = csr[mie]; auto ie = csr[mie];
@ -1157,7 +1066,7 @@ template <typename BASE> void riscv_hart_msu_vp<BASE>::check_interrupt() {
} }
template <typename BASE> template <typename BASE>
typename riscv_hart_msu_vp<BASE>::phys_addr_t riscv_hart_msu_vp<BASE>::virt2phys(const iss::addr_t &addr) { typename riscv_hart_m_p<BASE>::phys_addr_t riscv_hart_m_p<BASE>::virt2phys(const iss::addr_t &addr) {
const auto type = addr.access & iss::access_type::FUNC; const auto type = addr.access & iss::access_type::FUNC;
auto it = ptw.find(addr.val >> PGSHIFT); auto it = ptw.find(addr.val >> PGSHIFT);
if (it != ptw.end()) { if (it != ptw.end()) {
@ -1249,7 +1158,7 @@ typename riscv_hart_msu_vp<BASE>::phys_addr_t riscv_hart_msu_vp<BASE>::virt2phys
} }
} }
template <typename BASE> uint64_t riscv_hart_msu_vp<BASE>::enter_trap(uint64_t flags, uint64_t addr) { template <typename BASE> uint64_t riscv_hart_m_p<BASE>::enter_trap(uint64_t flags, uint64_t addr) {
auto cur_priv = this->reg.machine_state; auto cur_priv = this->reg.machine_state;
// flags are ACTIVE[31:31], CAUSE[30:16], TRAPID[15:0] // flags are ACTIVE[31:31], CAUSE[30:16], TRAPID[15:0]
// calculate and write mcause val // calculate and write mcause val
@ -1326,7 +1235,7 @@ template <typename BASE> uint64_t riscv_hart_msu_vp<BASE>::enter_trap(uint64_t f
return this->reg.NEXT_PC; return this->reg.NEXT_PC;
} }
template <typename BASE> uint64_t riscv_hart_msu_vp<BASE>::leave_trap(uint64_t flags) { template <typename BASE> uint64_t riscv_hart_m_p<BASE>::leave_trap(uint64_t flags) {
auto cur_priv = this->reg.machine_state; auto cur_priv = this->reg.machine_state;
auto inst_priv = flags & 0x3; auto inst_priv = flags & 0x3;
auto status = state.mstatus; auto status = state.mstatus;
@ -1364,7 +1273,7 @@ template <typename BASE> uint64_t riscv_hart_msu_vp<BASE>::leave_trap(uint64_t f
return this->reg.NEXT_PC; return this->reg.NEXT_PC;
} }
template <typename BASE> void riscv_hart_msu_vp<BASE>::wait_until(uint64_t flags) { template <typename BASE> void riscv_hart_m_p<BASE>::wait_until(uint64_t flags) {
auto status = state.mstatus; auto status = state.mstatus;
auto tw = status.TW; auto tw = status.TW;
if (this->reg.machine_state == PRIV_S && tw != 0) { if (this->reg.machine_state == PRIV_S && tw != 0) {

View File

@ -1,318 +0,0 @@
/*******************************************************************************
* Copyright (C) 2017, 2018 MINRES Technologies GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*******************************************************************************/
#ifndef _RV32GC_H_
#define _RV32GC_H_
#include <array>
#include <iss/arch/traits.h>
#include <iss/arch_if.h>
#include <iss/vm_if.h>
namespace iss {
namespace arch {
struct rv32gc;
template <> struct traits<rv32gc> {
constexpr static char const* const core_type = "RV32GC";
static constexpr std::array<const char*, 66> reg_names{
{"x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26", "x27", "x28", "x29", "x30", "x31", "pc", "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", "fcsr"}};
static constexpr std::array<const char*, 66> reg_aliases{
{"zero", "ra", "sp", "gp", "tp", "t0", "t1", "t2", "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6", "pc", "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", "fcsr"}};
enum constants {XLEN=32, FLEN=64, PCLEN=32, MUL_LEN=64, MISA_VAL=0b1000000000101000001000100101101, PGSIZE=0x1000, PGMASK=0xfff};
constexpr static unsigned FP_REGS_SIZE = 64;
enum reg_e {
X0,
X1,
X2,
X3,
X4,
X5,
X6,
X7,
X8,
X9,
X10,
X11,
X12,
X13,
X14,
X15,
X16,
X17,
X18,
X19,
X20,
X21,
X22,
X23,
X24,
X25,
X26,
X27,
X28,
X29,
X30,
X31,
PC,
F0,
F1,
F2,
F3,
F4,
F5,
F6,
F7,
F8,
F9,
F10,
F11,
F12,
F13,
F14,
F15,
F16,
F17,
F18,
F19,
F20,
F21,
F22,
F23,
F24,
F25,
F26,
F27,
F28,
F29,
F30,
F31,
FCSR,
NUM_REGS,
NEXT_PC=NUM_REGS,
TRAP_STATE,
PENDING_TRAP,
MACHINE_STATE,
LAST_BRANCH,
ICOUNT,
ZERO = X0,
RA = X1,
SP = X2,
GP = X3,
TP = X4,
T0 = X5,
T1 = X6,
T2 = X7,
S0 = X8,
S1 = X9,
A0 = X10,
A1 = X11,
A2 = X12,
A3 = X13,
A4 = X14,
A5 = X15,
A6 = X16,
A7 = X17,
S2 = X18,
S3 = X19,
S4 = X20,
S5 = X21,
S6 = X22,
S7 = X23,
S8 = X24,
S9 = X25,
S10 = X26,
S11 = X27,
T3 = X28,
T4 = X29,
T5 = X30,
T6 = X31
};
using reg_t = uint32_t;
using addr_t = uint32_t;
using code_word_t = uint32_t; //TODO: check removal
using virt_addr_t = iss::typed_addr_t<iss::address_type::VIRTUAL>;
using phys_addr_t = iss::typed_addr_t<iss::address_type::PHYSICAL>;
static constexpr std::array<const uint32_t, 72> reg_bit_widths{
{32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,32,32,32,32,32,32,64}};
static constexpr std::array<const uint32_t, 73> reg_byte_offsets{
{0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,136,144,152,160,168,176,184,192,200,208,216,224,232,240,248,256,264,272,280,288,296,304,312,320,328,336,344,352,360,368,376,384,392,396,400,404,408,412,416,424}};
static const uint64_t addr_mask = (reg_t(1) << (XLEN - 1)) | ((reg_t(1) << (XLEN - 1)) - 1);
enum sreg_flag_e { FLAGS };
enum mem_type_e { MEM, CSR, FENCE, RES };
};
struct rv32gc: public arch_if {
using virt_addr_t = typename traits<rv32gc>::virt_addr_t;
using phys_addr_t = typename traits<rv32gc>::phys_addr_t;
using reg_t = typename traits<rv32gc>::reg_t;
using addr_t = typename traits<rv32gc>::addr_t;
rv32gc();
~rv32gc();
void reset(uint64_t address=0) override;
uint8_t* get_regs_base_ptr() override;
/// deprecated
void get_reg(short idx, std::vector<uint8_t>& value) override {}
void set_reg(short idx, const std::vector<uint8_t>& value) override {}
/// deprecated
bool get_flag(int flag) override {return false;}
void set_flag(int, bool value) override {};
/// deprecated
void update_flags(operations op, uint64_t opr1, uint64_t opr2) override {};
inline uint64_t get_icount() { return reg.icount; }
inline bool should_stop() { return interrupt_sim; }
inline uint64_t stop_code() { return interrupt_sim; }
inline phys_addr_t v2p(const iss::addr_t& addr){
if (addr.space != traits<rv32gc>::MEM || addr.type == iss::address_type::PHYSICAL ||
addr_mode[static_cast<uint16_t>(addr.access)&0x3]==address_type::PHYSICAL) {
return phys_addr_t(addr.access, addr.space, addr.val&traits<rv32gc>::addr_mask);
} else
return virt2phys(addr);
}
virtual phys_addr_t virt2phys(const iss::addr_t& addr);
virtual iss::sync_type needed_sync() const { return iss::NO_SYNC; }
inline uint32_t get_last_branch() { return reg.last_branch; }
protected:
struct RV32GC_regs {
uint32_t X0 = 0;
uint32_t X1 = 0;
uint32_t X2 = 0;
uint32_t X3 = 0;
uint32_t X4 = 0;
uint32_t X5 = 0;
uint32_t X6 = 0;
uint32_t X7 = 0;
uint32_t X8 = 0;
uint32_t X9 = 0;
uint32_t X10 = 0;
uint32_t X11 = 0;
uint32_t X12 = 0;
uint32_t X13 = 0;
uint32_t X14 = 0;
uint32_t X15 = 0;
uint32_t X16 = 0;
uint32_t X17 = 0;
uint32_t X18 = 0;
uint32_t X19 = 0;
uint32_t X20 = 0;
uint32_t X21 = 0;
uint32_t X22 = 0;
uint32_t X23 = 0;
uint32_t X24 = 0;
uint32_t X25 = 0;
uint32_t X26 = 0;
uint32_t X27 = 0;
uint32_t X28 = 0;
uint32_t X29 = 0;
uint32_t X30 = 0;
uint32_t X31 = 0;
uint32_t PC = 0;
uint64_t F0 = 0;
uint64_t F1 = 0;
uint64_t F2 = 0;
uint64_t F3 = 0;
uint64_t F4 = 0;
uint64_t F5 = 0;
uint64_t F6 = 0;
uint64_t F7 = 0;
uint64_t F8 = 0;
uint64_t F9 = 0;
uint64_t F10 = 0;
uint64_t F11 = 0;
uint64_t F12 = 0;
uint64_t F13 = 0;
uint64_t F14 = 0;
uint64_t F15 = 0;
uint64_t F16 = 0;
uint64_t F17 = 0;
uint64_t F18 = 0;
uint64_t F19 = 0;
uint64_t F20 = 0;
uint64_t F21 = 0;
uint64_t F22 = 0;
uint64_t F23 = 0;
uint64_t F24 = 0;
uint64_t F25 = 0;
uint64_t F26 = 0;
uint64_t F27 = 0;
uint64_t F28 = 0;
uint64_t F29 = 0;
uint64_t F30 = 0;
uint64_t F31 = 0;
uint32_t FCSR = 0;
uint32_t NEXT_PC = 0;
uint32_t trap_state = 0, pending_trap = 0, machine_state = 0, last_branch = 0;
uint64_t icount = 0;
} reg;
std::array<address_type, 4> addr_mode;
uint64_t interrupt_sim=0;
uint32_t get_fcsr(){return reg.FCSR;}
void set_fcsr(uint32_t val){reg.FCSR = val;}
};
}
}
#endif /* _RV32GC_H_ */

View File

@ -1,252 +0,0 @@
/*******************************************************************************
* Copyright (C) 2017, 2018 MINRES Technologies GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*******************************************************************************/
#ifndef _RV32IMAC_H_
#define _RV32IMAC_H_
#include <array>
#include <iss/arch/traits.h>
#include <iss/arch_if.h>
#include <iss/vm_if.h>
namespace iss {
namespace arch {
struct rv32imac;
template <> struct traits<rv32imac> {
constexpr static char const* const core_type = "RV32IMAC";
static constexpr std::array<const char*, 33> reg_names{
{"x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26", "x27", "x28", "x29", "x30", "x31", "pc"}};
static constexpr std::array<const char*, 33> reg_aliases{
{"zero", "ra", "sp", "gp", "tp", "t0", "t1", "t2", "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6", "pc"}};
enum constants {XLEN=32, PCLEN=32, MUL_LEN=64, MISA_VAL=0b1000000000101000001000100000101, PGSIZE=0x1000, PGMASK=0xfff};
constexpr static unsigned FP_REGS_SIZE = 0;
enum reg_e {
X0,
X1,
X2,
X3,
X4,
X5,
X6,
X7,
X8,
X9,
X10,
X11,
X12,
X13,
X14,
X15,
X16,
X17,
X18,
X19,
X20,
X21,
X22,
X23,
X24,
X25,
X26,
X27,
X28,
X29,
X30,
X31,
PC,
NUM_REGS,
NEXT_PC=NUM_REGS,
TRAP_STATE,
PENDING_TRAP,
MACHINE_STATE,
LAST_BRANCH,
ICOUNT,
ZERO = X0,
RA = X1,
SP = X2,
GP = X3,
TP = X4,
T0 = X5,
T1 = X6,
T2 = X7,
S0 = X8,
S1 = X9,
A0 = X10,
A1 = X11,
A2 = X12,
A3 = X13,
A4 = X14,
A5 = X15,
A6 = X16,
A7 = X17,
S2 = X18,
S3 = X19,
S4 = X20,
S5 = X21,
S6 = X22,
S7 = X23,
S8 = X24,
S9 = X25,
S10 = X26,
S11 = X27,
T3 = X28,
T4 = X29,
T5 = X30,
T6 = X31
};
using reg_t = uint32_t;
using addr_t = uint32_t;
using code_word_t = uint32_t; //TODO: check removal
using virt_addr_t = iss::typed_addr_t<iss::address_type::VIRTUAL>;
using phys_addr_t = iss::typed_addr_t<iss::address_type::PHYSICAL>;
static constexpr std::array<const uint32_t, 39> reg_bit_widths{
{32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,64}};
static constexpr std::array<const uint32_t, 40> reg_byte_offsets{
{0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,132,136,140,144,148,152,160}};
static const uint64_t addr_mask = (reg_t(1) << (XLEN - 1)) | ((reg_t(1) << (XLEN - 1)) - 1);
enum sreg_flag_e { FLAGS };
enum mem_type_e { MEM, CSR, FENCE, RES };
};
struct rv32imac: public arch_if {
using virt_addr_t = typename traits<rv32imac>::virt_addr_t;
using phys_addr_t = typename traits<rv32imac>::phys_addr_t;
using reg_t = typename traits<rv32imac>::reg_t;
using addr_t = typename traits<rv32imac>::addr_t;
rv32imac();
~rv32imac();
void reset(uint64_t address=0) override;
uint8_t* get_regs_base_ptr() override;
/// deprecated
void get_reg(short idx, std::vector<uint8_t>& value) override {}
void set_reg(short idx, const std::vector<uint8_t>& value) override {}
/// deprecated
bool get_flag(int flag) override {return false;}
void set_flag(int, bool value) override {};
/// deprecated
void update_flags(operations op, uint64_t opr1, uint64_t opr2) override {};
inline uint64_t get_icount() { return reg.icount; }
inline bool should_stop() { return interrupt_sim; }
inline uint64_t stop_code() { return interrupt_sim; }
inline phys_addr_t v2p(const iss::addr_t& addr){
if (addr.space != traits<rv32imac>::MEM || addr.type == iss::address_type::PHYSICAL ||
addr_mode[static_cast<uint16_t>(addr.access)&0x3]==address_type::PHYSICAL) {
return phys_addr_t(addr.access, addr.space, addr.val&traits<rv32imac>::addr_mask);
} else
return virt2phys(addr);
}
virtual phys_addr_t virt2phys(const iss::addr_t& addr);
virtual iss::sync_type needed_sync() const { return iss::NO_SYNC; }
inline uint32_t get_last_branch() { return reg.last_branch; }
protected:
struct RV32IMAC_regs {
uint32_t X0 = 0;
uint32_t X1 = 0;
uint32_t X2 = 0;
uint32_t X3 = 0;
uint32_t X4 = 0;
uint32_t X5 = 0;
uint32_t X6 = 0;
uint32_t X7 = 0;
uint32_t X8 = 0;
uint32_t X9 = 0;
uint32_t X10 = 0;
uint32_t X11 = 0;
uint32_t X12 = 0;
uint32_t X13 = 0;
uint32_t X14 = 0;
uint32_t X15 = 0;
uint32_t X16 = 0;
uint32_t X17 = 0;
uint32_t X18 = 0;
uint32_t X19 = 0;
uint32_t X20 = 0;
uint32_t X21 = 0;
uint32_t X22 = 0;
uint32_t X23 = 0;
uint32_t X24 = 0;
uint32_t X25 = 0;
uint32_t X26 = 0;
uint32_t X27 = 0;
uint32_t X28 = 0;
uint32_t X29 = 0;
uint32_t X30 = 0;
uint32_t X31 = 0;
uint32_t PC = 0;
uint32_t NEXT_PC = 0;
uint32_t trap_state = 0, pending_trap = 0, machine_state = 0, last_branch = 0;
uint64_t icount = 0;
} reg;
std::array<address_type, 4> addr_mode;
uint64_t interrupt_sim=0;
uint32_t get_fcsr(){return 0;}
void set_fcsr(uint32_t val){}
};
}
}
#endif /* _RV32IMAC_H_ */

View File

@ -1,318 +0,0 @@
/*******************************************************************************
* Copyright (C) 2017, 2018 MINRES Technologies GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*******************************************************************************/
#ifndef _RV64GC_H_
#define _RV64GC_H_
#include <array>
#include <iss/arch/traits.h>
#include <iss/arch_if.h>
#include <iss/vm_if.h>
namespace iss {
namespace arch {
struct rv64gc;
template <> struct traits<rv64gc> {
constexpr static char const* const core_type = "RV64GC";
static constexpr std::array<const char*, 66> reg_names{
{"x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26", "x27", "x28", "x29", "x30", "x31", "pc", "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", "fcsr"}};
static constexpr std::array<const char*, 66> reg_aliases{
{"zero", "ra", "sp", "gp", "tp", "t0", "t1", "t2", "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6", "pc", "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", "fcsr"}};
enum constants {XLEN=64, FLEN=64, PCLEN=64, MUL_LEN=128, MISA_VAL=0b1000000000101000001000100101101, PGSIZE=0x1000, PGMASK=0xfff};
constexpr static unsigned FP_REGS_SIZE = 64;
enum reg_e {
X0,
X1,
X2,
X3,
X4,
X5,
X6,
X7,
X8,
X9,
X10,
X11,
X12,
X13,
X14,
X15,
X16,
X17,
X18,
X19,
X20,
X21,
X22,
X23,
X24,
X25,
X26,
X27,
X28,
X29,
X30,
X31,
PC,
F0,
F1,
F2,
F3,
F4,
F5,
F6,
F7,
F8,
F9,
F10,
F11,
F12,
F13,
F14,
F15,
F16,
F17,
F18,
F19,
F20,
F21,
F22,
F23,
F24,
F25,
F26,
F27,
F28,
F29,
F30,
F31,
FCSR,
NUM_REGS,
NEXT_PC=NUM_REGS,
TRAP_STATE,
PENDING_TRAP,
MACHINE_STATE,
LAST_BRANCH,
ICOUNT,
ZERO = X0,
RA = X1,
SP = X2,
GP = X3,
TP = X4,
T0 = X5,
T1 = X6,
T2 = X7,
S0 = X8,
S1 = X9,
A0 = X10,
A1 = X11,
A2 = X12,
A3 = X13,
A4 = X14,
A5 = X15,
A6 = X16,
A7 = X17,
S2 = X18,
S3 = X19,
S4 = X20,
S5 = X21,
S6 = X22,
S7 = X23,
S8 = X24,
S9 = X25,
S10 = X26,
S11 = X27,
T3 = X28,
T4 = X29,
T5 = X30,
T6 = X31
};
using reg_t = uint64_t;
using addr_t = uint64_t;
using code_word_t = uint64_t; //TODO: check removal
using virt_addr_t = iss::typed_addr_t<iss::address_type::VIRTUAL>;
using phys_addr_t = iss::typed_addr_t<iss::address_type::PHYSICAL>;
static constexpr std::array<const uint32_t, 72> reg_bit_widths{
{64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,32,64,32,32,32,32,64}};
static constexpr std::array<const uint32_t, 73> reg_byte_offsets{
{0,8,16,24,32,40,48,56,64,72,80,88,96,104,112,120,128,136,144,152,160,168,176,184,192,200,208,216,224,232,240,248,256,264,272,280,288,296,304,312,320,328,336,344,352,360,368,376,384,392,400,408,416,424,432,440,448,456,464,472,480,488,496,504,512,520,528,536,540,544,548,552,560}};
static const uint64_t addr_mask = (reg_t(1) << (XLEN - 1)) | ((reg_t(1) << (XLEN - 1)) - 1);
enum sreg_flag_e { FLAGS };
enum mem_type_e { MEM, CSR, FENCE, RES };
};
struct rv64gc: public arch_if {
using virt_addr_t = typename traits<rv64gc>::virt_addr_t;
using phys_addr_t = typename traits<rv64gc>::phys_addr_t;
using reg_t = typename traits<rv64gc>::reg_t;
using addr_t = typename traits<rv64gc>::addr_t;
rv64gc();
~rv64gc();
void reset(uint64_t address=0) override;
uint8_t* get_regs_base_ptr() override;
/// deprecated
void get_reg(short idx, std::vector<uint8_t>& value) override {}
void set_reg(short idx, const std::vector<uint8_t>& value) override {}
/// deprecated
bool get_flag(int flag) override {return false;}
void set_flag(int, bool value) override {};
/// deprecated
void update_flags(operations op, uint64_t opr1, uint64_t opr2) override {};
inline uint64_t get_icount() { return reg.icount; }
inline bool should_stop() { return interrupt_sim; }
inline uint64_t stop_code() { return interrupt_sim; }
inline phys_addr_t v2p(const iss::addr_t& addr){
if (addr.space != traits<rv64gc>::MEM || addr.type == iss::address_type::PHYSICAL ||
addr_mode[static_cast<uint16_t>(addr.access)&0x3]==address_type::PHYSICAL) {
return phys_addr_t(addr.access, addr.space, addr.val&traits<rv64gc>::addr_mask);
} else
return virt2phys(addr);
}
virtual phys_addr_t virt2phys(const iss::addr_t& addr);
virtual iss::sync_type needed_sync() const { return iss::NO_SYNC; }
inline uint32_t get_last_branch() { return reg.last_branch; }
protected:
struct RV64GC_regs {
uint64_t X0 = 0;
uint64_t X1 = 0;
uint64_t X2 = 0;
uint64_t X3 = 0;
uint64_t X4 = 0;
uint64_t X5 = 0;
uint64_t X6 = 0;
uint64_t X7 = 0;
uint64_t X8 = 0;
uint64_t X9 = 0;
uint64_t X10 = 0;
uint64_t X11 = 0;
uint64_t X12 = 0;
uint64_t X13 = 0;
uint64_t X14 = 0;
uint64_t X15 = 0;
uint64_t X16 = 0;
uint64_t X17 = 0;
uint64_t X18 = 0;
uint64_t X19 = 0;
uint64_t X20 = 0;
uint64_t X21 = 0;
uint64_t X22 = 0;
uint64_t X23 = 0;
uint64_t X24 = 0;
uint64_t X25 = 0;
uint64_t X26 = 0;
uint64_t X27 = 0;
uint64_t X28 = 0;
uint64_t X29 = 0;
uint64_t X30 = 0;
uint64_t X31 = 0;
uint64_t PC = 0;
uint64_t F0 = 0;
uint64_t F1 = 0;
uint64_t F2 = 0;
uint64_t F3 = 0;
uint64_t F4 = 0;
uint64_t F5 = 0;
uint64_t F6 = 0;
uint64_t F7 = 0;
uint64_t F8 = 0;
uint64_t F9 = 0;
uint64_t F10 = 0;
uint64_t F11 = 0;
uint64_t F12 = 0;
uint64_t F13 = 0;
uint64_t F14 = 0;
uint64_t F15 = 0;
uint64_t F16 = 0;
uint64_t F17 = 0;
uint64_t F18 = 0;
uint64_t F19 = 0;
uint64_t F20 = 0;
uint64_t F21 = 0;
uint64_t F22 = 0;
uint64_t F23 = 0;
uint64_t F24 = 0;
uint64_t F25 = 0;
uint64_t F26 = 0;
uint64_t F27 = 0;
uint64_t F28 = 0;
uint64_t F29 = 0;
uint64_t F30 = 0;
uint64_t F31 = 0;
uint32_t FCSR = 0;
uint64_t NEXT_PC = 0;
uint32_t trap_state = 0, pending_trap = 0, machine_state = 0, last_branch = 0;
uint64_t icount = 0;
} reg;
std::array<address_type, 4> addr_mode;
uint64_t interrupt_sim=0;
uint32_t get_fcsr(){return reg.FCSR;}
void set_fcsr(uint32_t val){reg.FCSR = val;}
};
}
}
#endif /* _RV64GC_H_ */

View File

@ -1,252 +0,0 @@
/*******************************************************************************
* Copyright (C) 2017, 2018 MINRES Technologies GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*******************************************************************************/
#ifndef _RV64I_H_
#define _RV64I_H_
#include <array>
#include <iss/arch/traits.h>
#include <iss/arch_if.h>
#include <iss/vm_if.h>
namespace iss {
namespace arch {
struct rv64i;
template <> struct traits<rv64i> {
constexpr static char const* const core_type = "RV64I";
static constexpr std::array<const char*, 33> reg_names{
{"x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26", "x27", "x28", "x29", "x30", "x31", "pc"}};
static constexpr std::array<const char*, 33> reg_aliases{
{"zero", "ra", "sp", "gp", "tp", "t0", "t1", "t2", "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6", "pc"}};
enum constants {XLEN=64, PCLEN=64, MISA_VAL=0b10000000000001000000000100000000, PGSIZE=0x1000, PGMASK=0xfff};
constexpr static unsigned FP_REGS_SIZE = 0;
enum reg_e {
X0,
X1,
X2,
X3,
X4,
X5,
X6,
X7,
X8,
X9,
X10,
X11,
X12,
X13,
X14,
X15,
X16,
X17,
X18,
X19,
X20,
X21,
X22,
X23,
X24,
X25,
X26,
X27,
X28,
X29,
X30,
X31,
PC,
NUM_REGS,
NEXT_PC=NUM_REGS,
TRAP_STATE,
PENDING_TRAP,
MACHINE_STATE,
LAST_BRANCH,
ICOUNT,
ZERO = X0,
RA = X1,
SP = X2,
GP = X3,
TP = X4,
T0 = X5,
T1 = X6,
T2 = X7,
S0 = X8,
S1 = X9,
A0 = X10,
A1 = X11,
A2 = X12,
A3 = X13,
A4 = X14,
A5 = X15,
A6 = X16,
A7 = X17,
S2 = X18,
S3 = X19,
S4 = X20,
S5 = X21,
S6 = X22,
S7 = X23,
S8 = X24,
S9 = X25,
S10 = X26,
S11 = X27,
T3 = X28,
T4 = X29,
T5 = X30,
T6 = X31
};
using reg_t = uint64_t;
using addr_t = uint64_t;
using code_word_t = uint64_t; //TODO: check removal
using virt_addr_t = iss::typed_addr_t<iss::address_type::VIRTUAL>;
using phys_addr_t = iss::typed_addr_t<iss::address_type::PHYSICAL>;
static constexpr std::array<const uint32_t, 39> reg_bit_widths{
{64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,32,32,32,32,64}};
static constexpr std::array<const uint32_t, 40> reg_byte_offsets{
{0,8,16,24,32,40,48,56,64,72,80,88,96,104,112,120,128,136,144,152,160,168,176,184,192,200,208,216,224,232,240,248,256,264,272,276,280,284,288,296}};
static const uint64_t addr_mask = (reg_t(1) << (XLEN - 1)) | ((reg_t(1) << (XLEN - 1)) - 1);
enum sreg_flag_e { FLAGS };
enum mem_type_e { MEM, CSR, FENCE, RES };
};
struct rv64i: public arch_if {
using virt_addr_t = typename traits<rv64i>::virt_addr_t;
using phys_addr_t = typename traits<rv64i>::phys_addr_t;
using reg_t = typename traits<rv64i>::reg_t;
using addr_t = typename traits<rv64i>::addr_t;
rv64i();
~rv64i();
void reset(uint64_t address=0) override;
uint8_t* get_regs_base_ptr() override;
/// deprecated
void get_reg(short idx, std::vector<uint8_t>& value) override {}
void set_reg(short idx, const std::vector<uint8_t>& value) override {}
/// deprecated
bool get_flag(int flag) override {return false;}
void set_flag(int, bool value) override {};
/// deprecated
void update_flags(operations op, uint64_t opr1, uint64_t opr2) override {};
inline uint64_t get_icount() { return reg.icount; }
inline bool should_stop() { return interrupt_sim; }
inline uint64_t stop_code() { return interrupt_sim; }
inline phys_addr_t v2p(const iss::addr_t& addr){
if (addr.space != traits<rv64i>::MEM || addr.type == iss::address_type::PHYSICAL ||
addr_mode[static_cast<uint16_t>(addr.access)&0x3]==address_type::PHYSICAL) {
return phys_addr_t(addr.access, addr.space, addr.val&traits<rv64i>::addr_mask);
} else
return virt2phys(addr);
}
virtual phys_addr_t virt2phys(const iss::addr_t& addr);
virtual iss::sync_type needed_sync() const { return iss::NO_SYNC; }
inline uint32_t get_last_branch() { return reg.last_branch; }
protected:
struct RV64I_regs {
uint64_t X0 = 0;
uint64_t X1 = 0;
uint64_t X2 = 0;
uint64_t X3 = 0;
uint64_t X4 = 0;
uint64_t X5 = 0;
uint64_t X6 = 0;
uint64_t X7 = 0;
uint64_t X8 = 0;
uint64_t X9 = 0;
uint64_t X10 = 0;
uint64_t X11 = 0;
uint64_t X12 = 0;
uint64_t X13 = 0;
uint64_t X14 = 0;
uint64_t X15 = 0;
uint64_t X16 = 0;
uint64_t X17 = 0;
uint64_t X18 = 0;
uint64_t X19 = 0;
uint64_t X20 = 0;
uint64_t X21 = 0;
uint64_t X22 = 0;
uint64_t X23 = 0;
uint64_t X24 = 0;
uint64_t X25 = 0;
uint64_t X26 = 0;
uint64_t X27 = 0;
uint64_t X28 = 0;
uint64_t X29 = 0;
uint64_t X30 = 0;
uint64_t X31 = 0;
uint64_t PC = 0;
uint64_t NEXT_PC = 0;
uint32_t trap_state = 0, pending_trap = 0, machine_state = 0, last_branch = 0;
uint64_t icount = 0;
} reg;
std::array<address_type, 4> addr_mode;
uint64_t interrupt_sim=0;
uint32_t get_fcsr(){return 0;}
void set_fcsr(uint32_t val){}
};
}
}
#endif /* _RV64I_H_ */

View File

@ -54,7 +54,7 @@ template <> struct traits<tgf01> {
static constexpr std::array<const char*, 33> reg_aliases{ static constexpr std::array<const char*, 33> reg_aliases{
{"zero", "ra", "sp", "gp", "tp", "t0", "t1", "t2", "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6", "pc"}}; {"zero", "ra", "sp", "gp", "tp", "t0", "t1", "t2", "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6", "pc"}};
enum constants {XLEN=32, PCLEN=32, MISA_VAL=0b1000000000000000000000100000000}; enum constants {XLEN=32, PCLEN=32, MISA_VAL=0b1000000000000000000000100000000, PGSIZE=0x1000, PGMASK=0xfff};
constexpr static unsigned FP_REGS_SIZE = 0; constexpr static unsigned FP_REGS_SIZE = 0;

View File

@ -54,7 +54,7 @@ template <> struct traits<tgf02> {
static constexpr std::array<const char*, 33> reg_aliases{ static constexpr std::array<const char*, 33> reg_aliases{
{"zero", "ra", "sp", "gp", "tp", "t0", "t1", "t2", "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6", "pc"}}; {"zero", "ra", "sp", "gp", "tp", "t0", "t1", "t2", "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6", "pc"}};
enum constants {XLEN=32, PCLEN=32, MUL_LEN=64, MISA_VAL=0b1000000000000000001000100000100}; enum constants {XLEN=32, PCLEN=32, MUL_LEN=64, MISA_VAL=0b1000000000000000001000100000100, PGSIZE=0x1000, PGMASK=0xfff};
constexpr static unsigned FP_REGS_SIZE = 0; constexpr static unsigned FP_REGS_SIZE = 0;

View File

@ -51,7 +51,7 @@ template <class T_begin, class T_end> class scv_tr_generator;
namespace iss { namespace iss {
class vm_if; class vm_if;
namespace arch { namespace arch {
template <typename BASE> class riscv_hart_msu_vp; template <typename BASE> class riscv_hart_m_p;
} }
namespace debugger { namespace debugger {
class target_adapter_if; class target_adapter_if;

View File

@ -1,71 +0,0 @@
/*******************************************************************************
* Copyright (C) 2017, 2018 MINRES Technologies GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*******************************************************************************/
#include "util/ities.h"
#include <util/logging.h>
#include <iss/arch/mnrv32.h>
#include <cstdio>
#include <cstring>
#include <fstream>
using namespace iss::arch;
constexpr std::array<const char*, 33> iss::arch::traits<iss::arch::mnrv32>::reg_names;
constexpr std::array<const char*, 33> iss::arch::traits<iss::arch::mnrv32>::reg_aliases;
constexpr std::array<const uint32_t, 39> iss::arch::traits<iss::arch::mnrv32>::reg_bit_widths;
constexpr std::array<const uint32_t, 40> iss::arch::traits<iss::arch::mnrv32>::reg_byte_offsets;
mnrv32::mnrv32() {
reg.icount = 0;
}
mnrv32::~mnrv32() = default;
void mnrv32::reset(uint64_t address) {
for(size_t i=0; i<traits<mnrv32>::NUM_REGS; ++i) set_reg(i, std::vector<uint8_t>(sizeof(traits<mnrv32>::reg_t),0));
reg.PC=address;
reg.NEXT_PC=reg.PC;
reg.trap_state=0;
reg.machine_state=0x3;
reg.icount=0;
}
uint8_t *mnrv32::get_regs_base_ptr() {
return reinterpret_cast<uint8_t*>(&reg);
}
mnrv32::phys_addr_t mnrv32::virt2phys(const iss::addr_t &pc) {
return phys_addr_t(pc); // change logical address to physical address
}

View File

@ -1,72 +0,0 @@
/*******************************************************************************
* Copyright (C) 2017, 2018 MINRES Technologies GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*******************************************************************************/
#include "util/ities.h"
#include <util/logging.h>
#include <iss/arch/rv32gc.h>
#include <fstream>
#include <cstdio>
#include <cstring>
using namespace iss::arch;
constexpr std::array<const char*, 66> iss::arch::traits<iss::arch::rv32gc>::reg_names;
constexpr std::array<const char*, 66> iss::arch::traits<iss::arch::rv32gc>::reg_aliases;
constexpr std::array<const uint32_t, 72> iss::arch::traits<iss::arch::rv32gc>::reg_bit_widths;
constexpr std::array<const uint32_t, 73> iss::arch::traits<iss::arch::rv32gc>::reg_byte_offsets;
rv32gc::rv32gc() {
reg.icount=0;
}
rv32gc::~rv32gc(){
}
void rv32gc::reset(uint64_t address) {
for(size_t i=0; i<traits<rv32gc>::NUM_REGS; ++i) set_reg(i, std::vector<uint8_t>(sizeof(traits<rv32gc>::reg_t),0));
reg.PC=address;
reg.NEXT_PC=reg.PC;
reg.trap_state=0;
reg.machine_state=0x3;
reg.icount=0;
}
uint8_t* rv32gc::get_regs_base_ptr(){
return reinterpret_cast<uint8_t*>(&reg);
}
rv32gc::phys_addr_t rv32gc::virt2phys(const iss::addr_t &pc) {
return phys_addr_t(pc); // change logical address to physical address
}

View File

@ -1,69 +0,0 @@
/*******************************************************************************
* Copyright (C) 2017, 2018 MINRES Technologies GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*******************************************************************************/
#include "util/ities.h"
#include <util/logging.h>
#include <iss/arch/rv32imac.h>
#include <cstdio>
#include <cstring>
#include <fstream>
using namespace iss::arch;
constexpr std::array<const char*, 33> iss::arch::traits<iss::arch::rv32imac>::reg_names;
constexpr std::array<const char*, 33> iss::arch::traits<iss::arch::rv32imac>::reg_aliases;
constexpr std::array<const uint32_t, 39> iss::arch::traits<iss::arch::rv32imac>::reg_bit_widths;
constexpr std::array<const uint32_t, 40> iss::arch::traits<iss::arch::rv32imac>::reg_byte_offsets;
rv32imac::rv32imac() {
reg.icount = 0;
reg.machine_state = 0x3;
}
rv32imac::~rv32imac() = default;
void rv32imac::reset(uint64_t address) {
for (size_t i = 0; i < traits<rv32imac>::NUM_REGS; ++i)
set_reg(i, std::vector<uint8_t>(sizeof(traits<rv32imac>::reg_t), 0));
reg.PC = address;
reg.NEXT_PC = reg.PC;
reg.trap_state = 0;
reg.machine_state = 0x3;
}
uint8_t *rv32imac::get_regs_base_ptr() { return reinterpret_cast<uint8_t *>(&reg); }
rv32imac::phys_addr_t rv32imac::virt2phys(const iss::addr_t &pc) {
return phys_addr_t(pc); // change logical address to physical address
}

View File

@ -1,73 +0,0 @@
/*******************************************************************************
* Copyright (C) 2017, 2018 MINRES Technologies GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*******************************************************************************/
#include "util/ities.h"
#include <util/logging.h>
#include <iss/arch/rv64gc.h>
#include <cstdio>
#include <cstring>
#include <fstream>
using namespace iss::arch;
constexpr std::array<const char*, 66> iss::arch::traits<iss::arch::rv64gc>::reg_names;
constexpr std::array<const char*, 66> iss::arch::traits<iss::arch::rv64gc>::reg_aliases;
constexpr std::array<const uint32_t, 72> iss::arch::traits<iss::arch::rv64gc>::reg_bit_widths;
constexpr std::array<const uint32_t, 73> iss::arch::traits<iss::arch::rv64gc>::reg_byte_offsets;
rv64gc::rv64gc() {
reg.icount = 0;
}
rv64gc::~rv64gc() = default;
void rv64gc::reset(uint64_t address) {
for(size_t i=0; i<traits<rv64gc>::NUM_REGS; ++i) set_reg(i, std::vector<uint8_t>(sizeof(traits<rv64gc>::reg_t),0));
reg.PC=address;
reg.NEXT_PC=reg.PC;
reg.trap_state=0;
reg.machine_state=0x3;
reg.icount=0;
}
uint8_t *rv64gc::get_regs_base_ptr() {
return reinterpret_cast<uint8_t*>(&reg);
}
rv64gc::phys_addr_t rv64gc::virt2phys(const iss::addr_t &pc) {
return phys_addr_t(pc); // change logical address to physical address
}

View File

@ -1,71 +0,0 @@
/*******************************************************************************
* Copyright (C) 2017, 2018 MINRES Technologies GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*******************************************************************************/
#include "util/ities.h"
#include <util/logging.h>
#include <iss/arch/rv64i.h>
#include <cstdio>
#include <cstring>
#include <fstream>
using namespace iss::arch;
constexpr std::array<const char*, 33> iss::arch::traits<iss::arch::rv64i>::reg_names;
constexpr std::array<const char*, 33> iss::arch::traits<iss::arch::rv64i>::reg_aliases;
constexpr std::array<const uint32_t, 39> iss::arch::traits<iss::arch::rv64i>::reg_bit_widths;
constexpr std::array<const uint32_t, 40> iss::arch::traits<iss::arch::rv64i>::reg_byte_offsets;
rv64i::rv64i() {
reg.icount = 0;
}
rv64i::~rv64i() = default;
void rv64i::reset(uint64_t address) {
for(size_t i=0; i<traits<rv64i>::NUM_REGS; ++i) set_reg(i, std::vector<uint8_t>(sizeof(traits<rv64i>::reg_t),0));
reg.PC=address;
reg.NEXT_PC=reg.PC;
reg.trap_state=0;
reg.machine_state=0x3;
reg.icount=0;
}
uint8_t *rv64i::get_regs_base_ptr() {
return reinterpret_cast<uint8_t*>(&reg);
}
rv64i::phys_addr_t rv64i::virt2phys(const iss::addr_t &pc) {
return phys_addr_t(pc); // change logical address to physical address
}

View File

@ -35,12 +35,9 @@
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include <boost/program_options.hpp> #include <boost/program_options.hpp>
#include <iss/arch/riscv_hart_msu_vp.h> #include <iss/arch/riscv_hart_m_p.h>
#include <iss/arch/rv32imac.h> #include <iss/arch/tgf01.h>
#include <iss/arch/rv32gc.h> #include <iss/arch/tgf02.h>
#include <iss/arch/rv64gc.h>
#include <iss/arch/rv64i.h>
#include <iss/arch/mnrv32.h>
#ifdef WITH_LLVM #ifdef WITH_LLVM
#include <iss/llvm/jit_helper.h> #include <iss/llvm/jit_helper.h>
#endif #endif
@ -55,7 +52,7 @@ using vm_ptr= std::unique_ptr<iss::vm_if>;
template<typename CORE> template<typename CORE>
std::tuple<cpu_ptr, vm_ptr> create_cpu(std::string const& backend, unsigned gdb_port){ std::tuple<cpu_ptr, vm_ptr> create_cpu(std::string const& backend, unsigned gdb_port){
CORE* lcpu = new iss::arch::riscv_hart_msu_vp<CORE>(); CORE* lcpu = new iss::arch::riscv_hart_m_p<CORE>();
if(backend == "interp") if(backend == "interp")
return {cpu_ptr{lcpu}, vm_ptr{iss::interp::create(lcpu, gdb_port)}}; return {cpu_ptr{lcpu}, vm_ptr{iss::interp::create(lcpu, gdb_port)}};
#ifdef WITH_LLVM #ifdef WITH_LLVM
@ -132,16 +129,10 @@ int main(int argc, char *argv[]) {
vm_ptr vm{nullptr}; vm_ptr vm{nullptr};
cpu_ptr cpu{nullptr}; cpu_ptr cpu{nullptr};
std::string isa_opt(clim["isa"].as<std::string>()); std::string isa_opt(clim["isa"].as<std::string>());
if (isa_opt=="mnrv32") { if (isa_opt=="tgf01") {
std::tie(cpu, vm) = create_cpu<iss::arch::mnrv32>(clim["backend"].as<std::string>(), clim["gdb-port"].as<unsigned>()); std::tie(cpu, vm) = create_cpu<iss::arch::tgf01>(clim["backend"].as<std::string>(), clim["gdb-port"].as<unsigned>());
} else if (isa_opt=="rv64i") { } else if (isa_opt=="tgf02") {
std::tie(cpu, vm) = create_cpu<iss::arch::rv64i>(clim["backend"].as<std::string>(), clim["gdb-port"].as<unsigned>()); std::tie(cpu, vm) = create_cpu<iss::arch::tgf02>(clim["backend"].as<std::string>(), clim["gdb-port"].as<unsigned>());
} else if (isa_opt=="rv64gc") {
std::tie(cpu, vm) = create_cpu<iss::arch::rv64gc>(clim["backend"].as<std::string>(), clim["gdb-port"].as<unsigned>());
} else if (isa_opt=="rv32imac") {
std::tie(cpu, vm) = create_cpu<iss::arch::rv32imac>(clim["backend"].as<std::string>(), clim["gdb-port"].as<unsigned>());
} else if (isa_opt=="rv32gc") {
std::tie(cpu, vm) = create_cpu<iss::arch::rv32gc>(clim["backend"].as<std::string>(), clim["gdb-port"].as<unsigned>());
} else { } else {
LOG(ERROR) << "Illegal argument value for '--isa': " << clim["isa"].as<std::string>() << std::endl; LOG(ERROR) << "Illegal argument value for '--isa': " << clim["isa"].as<std::string>() << std::endl;
return 127; return 127;
@ -181,7 +172,7 @@ int main(int argc, char *argv[]) {
} }
uint64_t start_address = 0; uint64_t start_address = 0;
if (clim.count("mem")) if (clim.count("mem"))
vm->get_arch()->load_file(clim["mem"].as<std::string>(), iss::arch::traits<iss::arch::mnrv32>::MEM); vm->get_arch()->load_file(clim["mem"].as<std::string>(), iss::arch::traits<iss::arch::tgf01>::MEM);
if (clim.count("elf")) if (clim.count("elf"))
for (std::string input : clim["elf"].as<std::vector<std::string>>()) { for (std::string input : clim["elf"].as<std::vector<std::string>>()) {
auto start_addr = vm->get_arch()->load_file(input); auto start_addr = vm->get_arch()->load_file(input);

View File

@ -31,9 +31,8 @@
*******************************************************************************/ *******************************************************************************/
#include "sysc/core_complex.h" #include "sysc/core_complex.h"
#include "iss/arch/riscv_hart_msu_vp.h" #include "iss/arch/riscv_hart_m_p.h"
//#include "iss/arch/rv32imac.h" #include "iss/arch/tgf01.h"
#include "iss/arch/mnrv32.h"
#include "iss/debugger/encoderdecoder.h" #include "iss/debugger/encoderdecoder.h"
#include "iss/debugger/gdb_session.h" #include "iss/debugger/gdb_session.h"
#include "iss/debugger/server.h" #include "iss/debugger/server.h"
@ -61,7 +60,7 @@ iss::debugger::encoder_decoder encdec;
} }
//using core_type = iss::arch::rv32imac; //using core_type = iss::arch::rv32imac;
using core_type = iss::arch::mnrv32; using core_type = iss::arch::tgf01;
namespace { namespace {
@ -91,9 +90,9 @@ std::array<const char*, 12> irq_str = { {
"User external interrupt", "Supervisor external interrupt", "Reserved", "Machine external interrupt" } }; "User external interrupt", "Supervisor external interrupt", "Reserved", "Machine external interrupt" } };
} }
class core_wrapper : public iss::arch::riscv_hart_msu_vp<core_type> { class core_wrapper : public iss::arch::riscv_hart_m_p<core_type> {
public: public:
using base_type = arch::riscv_hart_msu_vp<core_type>; using base_type = arch::riscv_hart_m_p<core_type>;
using phys_addr_t = typename arch::traits<core_type>::phys_addr_t; using phys_addr_t = typename arch::traits<core_type>::phys_addr_t;
core_wrapper(core_complex *owner) core_wrapper(core_complex *owner)
: owner(owner) : owner(owner)
@ -287,7 +286,7 @@ vm_ptr create_cpu(core_wrapper* cpu, std::string const& backend, unsigned gdb_po
} }
void core_complex::before_end_of_elaboration() { void core_complex::before_end_of_elaboration() {
SCCDEBUG(SCMOD)<<"instantiating iss::arch::mnrv32 with "<<backend.get_value()<<" backend"; SCCDEBUG(SCMOD)<<"instantiating iss::arch::tgf with "<<backend.get_value()<<" backend";
cpu = scc::make_unique<core_wrapper>(this); cpu = scc::make_unique<core_wrapper>(this);
vm = create_cpu(cpu.get(), backend.get_value(), gdb_server_port.get_value()); vm = create_cpu(cpu.get(), backend.get_value(), gdb_server_port.get_value());
#ifdef WITH_SCV #ifdef WITH_SCV

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -31,8 +31,8 @@
*******************************************************************************/ *******************************************************************************/
#include "../fp_functions.h" #include "../fp_functions.h"
#include <iss/arch/rv64i.h> #include <iss/arch/tgf01.h>
#include <iss/arch/riscv_hart_msu_vp.h> #include <iss/arch/riscv_hart_m_p.h>
#include <iss/debugger/gdb_session.h> #include <iss/debugger/gdb_session.h>
#include <iss/debugger/server.h> #include <iss/debugger/server.h>
#include <iss/iss.h> #include <iss/iss.h>
@ -50,7 +50,7 @@
namespace iss { namespace iss {
namespace interp { namespace interp {
namespace rv64i { namespace tgf01 {
using namespace iss::arch; using namespace iss::arch;
using namespace iss::debugger; using namespace iss::debugger;
@ -167,7 +167,7 @@ private:
compile_func op; compile_func op;
}; };
const std::array<InstructionDesriptor, 64> instr_descr = {{ const std::array<InstructionDesriptor, 52> instr_descr = {{
/* entries are: size, valid value, valid mask, function ptr */ /* entries are: size, valid value, valid mask, function ptr */
/* instruction LUI */ /* instruction LUI */
{32, 0b00000000000000000000000000110111, 0b00000000000000000000000001111111, &this_class::__lui}, {32, 0b00000000000000000000000000110111, 0b00000000000000000000000001111111, &this_class::__lui},
@ -218,11 +218,11 @@ private:
/* instruction ANDI */ /* instruction ANDI */
{32, 0b00000000000000000111000000010011, 0b00000000000000000111000001111111, &this_class::__andi}, {32, 0b00000000000000000111000000010011, 0b00000000000000000111000001111111, &this_class::__andi},
/* instruction SLLI */ /* instruction SLLI */
{32, 0b00000000000000000001000000010011, 0b11111100000000000111000001111111, &this_class::__slli}, {32, 0b00000000000000000001000000010011, 0b11111110000000000111000001111111, &this_class::__slli},
/* instruction SRLI */ /* instruction SRLI */
{32, 0b00000000000000000101000000010011, 0b11111100000000000111000001111111, &this_class::__srli}, {32, 0b00000000000000000101000000010011, 0b11111110000000000111000001111111, &this_class::__srli},
/* instruction SRAI */ /* instruction SRAI */
{32, 0b01000000000000000101000000010011, 0b11111100000000000111000001111111, &this_class::__srai}, {32, 0b01000000000000000101000000010011, 0b11111110000000000111000001111111, &this_class::__srai},
/* instruction ADD */ /* instruction ADD */
{32, 0b00000000000000000000000000110011, 0b11111110000000000111000001111111, &this_class::__add}, {32, 0b00000000000000000000000000110011, 0b11111110000000000111000001111111, &this_class::__add},
/* instruction SUB */ /* instruction SUB */
@ -273,30 +273,6 @@ private:
{32, 0b00000000000000000110000001110011, 0b00000000000000000111000001111111, &this_class::__csrrsi}, {32, 0b00000000000000000110000001110011, 0b00000000000000000111000001111111, &this_class::__csrrsi},
/* instruction CSRRCI */ /* instruction CSRRCI */
{32, 0b00000000000000000111000001110011, 0b00000000000000000111000001111111, &this_class::__csrrci}, {32, 0b00000000000000000111000001110011, 0b00000000000000000111000001111111, &this_class::__csrrci},
/* instruction LWU */
{32, 0b00000000000000000110000000000011, 0b00000000000000000111000001111111, &this_class::__lwu},
/* instruction LD */
{32, 0b00000000000000000011000000000011, 0b00000000000000000111000001111111, &this_class::__ld},
/* instruction SD */
{32, 0b00000000000000000011000000100011, 0b00000000000000000111000001111111, &this_class::__sd},
/* instruction ADDIW */
{32, 0b00000000000000000000000000011011, 0b00000000000000000111000001111111, &this_class::__addiw},
/* instruction SLLIW */
{32, 0b00000000000000000001000000011011, 0b11111110000000000111000001111111, &this_class::__slliw},
/* instruction SRLIW */
{32, 0b00000000000000000101000000011011, 0b11111110000000000111000001111111, &this_class::__srliw},
/* instruction SRAIW */
{32, 0b01000000000000000101000000011011, 0b11111110000000000111000001111111, &this_class::__sraiw},
/* instruction ADDW */
{32, 0b00000000000000000000000000111011, 0b11111110000000000111000001111111, &this_class::__addw},
/* instruction SUBW */
{32, 0b01000000000000000000000000111011, 0b11111110000000000111000001111111, &this_class::__subw},
/* instruction SLLW */
{32, 0b00000000000000000001000000111011, 0b11111110000000000111000001111111, &this_class::__sllw},
/* instruction SRLW */
{32, 0b00000000000000000101000000111011, 0b11111110000000000111000001111111, &this_class::__srlw},
/* instruction SRAW */
{32, 0b01000000000000000101000000111011, 0b11111110000000000111000001111111, &this_class::__sraw},
}}; }};
/* instruction definitions */ /* instruction definitions */
@ -349,7 +325,7 @@ private:
auto cur_pc_val = pc.val; auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4; super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
if(rd != 0){ if(rd != 0){
auto Xtmp0_val = (static_cast<int64_t>(cur_pc_val) + (imm)); auto Xtmp0_val = (static_cast<int32_t>(cur_pc_val) + (imm));
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val; super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val;
} }
this->do_sync(POST_SYNC, 1); this->do_sync(POST_SYNC, 1);
@ -384,7 +360,7 @@ private:
auto Xtmp0_val = (cur_pc_val + 4); auto Xtmp0_val = (cur_pc_val + 4);
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val; super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val;
} }
auto PC_val = (static_cast<int64_t>(cur_pc_val) + (imm)); auto PC_val = (static_cast<int32_t>(cur_pc_val) + (imm));
super::template get_reg(traits<ARCH>::NEXT_PC) = PC_val; super::template get_reg(traits<ARCH>::NEXT_PC) = PC_val;
auto is_cont_v = PC_val !=pc.val; auto is_cont_v = PC_val !=pc.val;
super::template get_reg(traits<ARCH>::LAST_BRANCH) = is_cont_v?1:0; super::template get_reg(traits<ARCH>::LAST_BRANCH) = is_cont_v?1:0;
@ -417,7 +393,7 @@ private:
auto cur_pc_val = pc.val; auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4; super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
auto new_pc_val = (static_cast<int64_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)) + (imm)); auto new_pc_val = (static_cast<int32_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)) + (imm));
auto align_val = (new_pc_val & 0x2); auto align_val = (new_pc_val & 0x2);
{ {
if((align_val != 0)) { if((align_val != 0)) {
@ -463,7 +439,7 @@ private:
auto cur_pc_val = pc.val; auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4; super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
auto PC_val = (super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0) == super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0))? auto PC_val = (super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0) == super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0))?
(static_cast<int64_t>(cur_pc_val) + (imm)): (static_cast<int32_t>(cur_pc_val) + (imm)):
(cur_pc_val + 4); (cur_pc_val + 4);
super::template get_reg(traits<ARCH>::NEXT_PC) = PC_val; super::template get_reg(traits<ARCH>::NEXT_PC) = PC_val;
auto is_cont_v = PC_val !=pc.val; auto is_cont_v = PC_val !=pc.val;
@ -498,7 +474,7 @@ private:
auto cur_pc_val = pc.val; auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4; super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
auto PC_val = (super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0) != super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0))? auto PC_val = (super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0) != super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0))?
(static_cast<int64_t>(cur_pc_val) + (imm)): (static_cast<int32_t>(cur_pc_val) + (imm)):
(cur_pc_val + 4); (cur_pc_val + 4);
super::template get_reg(traits<ARCH>::NEXT_PC) = PC_val; super::template get_reg(traits<ARCH>::NEXT_PC) = PC_val;
auto is_cont_v = PC_val !=pc.val; auto is_cont_v = PC_val !=pc.val;
@ -532,8 +508,8 @@ private:
auto cur_pc_val = pc.val; auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4; super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
auto PC_val = (static_cast<int64_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)) < static_cast<int64_t>(super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0)))? auto PC_val = (static_cast<int32_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)) < static_cast<int32_t>(super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0)))?
(static_cast<int64_t>(cur_pc_val) + (imm)): (static_cast<int32_t>(cur_pc_val) + (imm)):
(cur_pc_val + 4); (cur_pc_val + 4);
super::template get_reg(traits<ARCH>::NEXT_PC) = PC_val; super::template get_reg(traits<ARCH>::NEXT_PC) = PC_val;
auto is_cont_v = PC_val !=pc.val; auto is_cont_v = PC_val !=pc.val;
@ -567,8 +543,8 @@ private:
auto cur_pc_val = pc.val; auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4; super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
auto PC_val = (static_cast<int64_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)) >= static_cast<int64_t>(super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0)))? auto PC_val = (static_cast<int32_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)) >= static_cast<int32_t>(super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0)))?
(static_cast<int64_t>(cur_pc_val) + (imm)): (static_cast<int32_t>(cur_pc_val) + (imm)):
(cur_pc_val + 4); (cur_pc_val + 4);
super::template get_reg(traits<ARCH>::NEXT_PC) = PC_val; super::template get_reg(traits<ARCH>::NEXT_PC) = PC_val;
auto is_cont_v = PC_val !=pc.val; auto is_cont_v = PC_val !=pc.val;
@ -603,7 +579,7 @@ private:
auto cur_pc_val = pc.val; auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4; super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
auto PC_val = (super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0) < super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0))? auto PC_val = (super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0) < super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0))?
(static_cast<int64_t>(cur_pc_val) + (imm)): (static_cast<int32_t>(cur_pc_val) + (imm)):
(cur_pc_val + 4); (cur_pc_val + 4);
super::template get_reg(traits<ARCH>::NEXT_PC) = PC_val; super::template get_reg(traits<ARCH>::NEXT_PC) = PC_val;
auto is_cont_v = PC_val !=pc.val; auto is_cont_v = PC_val !=pc.val;
@ -638,7 +614,7 @@ private:
auto cur_pc_val = pc.val; auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4; super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
auto PC_val = (super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0) >= super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0))? auto PC_val = (super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0) >= super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0))?
(static_cast<int64_t>(cur_pc_val) + (imm)): (static_cast<int32_t>(cur_pc_val) + (imm)):
(cur_pc_val + 4); (cur_pc_val + 4);
super::template get_reg(traits<ARCH>::NEXT_PC) = PC_val; super::template get_reg(traits<ARCH>::NEXT_PC) = PC_val;
auto is_cont_v = PC_val !=pc.val; auto is_cont_v = PC_val !=pc.val;
@ -672,9 +648,9 @@ private:
auto cur_pc_val = pc.val; auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4; super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
auto offs_val = (static_cast<int64_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)) + (imm)); auto offs_val = (static_cast<int32_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)) + (imm));
if(rd != 0){ if(rd != 0){
auto Xtmp0_val = super::template sext<int64_t>(super::template read_mem<uint8_t>(traits<ARCH>::MEM, offs_val)); auto Xtmp0_val = super::template sext<int32_t>(super::template read_mem<uint8_t>(traits<ARCH>::MEM, offs_val));
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val; super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val;
} }
this->do_sync(POST_SYNC, 10); this->do_sync(POST_SYNC, 10);
@ -706,9 +682,9 @@ private:
auto cur_pc_val = pc.val; auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4; super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
auto offs_val = (static_cast<int64_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)) + (imm)); auto offs_val = (static_cast<int32_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)) + (imm));
if(rd != 0){ if(rd != 0){
auto Xtmp0_val = super::template sext<int64_t>(super::template read_mem<uint16_t>(traits<ARCH>::MEM, offs_val)); auto Xtmp0_val = super::template sext<int32_t>(super::template read_mem<uint16_t>(traits<ARCH>::MEM, offs_val));
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val; super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val;
} }
this->do_sync(POST_SYNC, 11); this->do_sync(POST_SYNC, 11);
@ -740,9 +716,9 @@ private:
auto cur_pc_val = pc.val; auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4; super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
auto offs_val = (static_cast<int64_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)) + (imm)); auto offs_val = (static_cast<int32_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)) + (imm));
if(rd != 0){ if(rd != 0){
auto Xtmp0_val = super::template sext<int64_t>(super::template read_mem<uint32_t>(traits<ARCH>::MEM, offs_val)); auto Xtmp0_val = super::template sext<int32_t>(super::template read_mem<uint32_t>(traits<ARCH>::MEM, offs_val));
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val; super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val;
} }
this->do_sync(POST_SYNC, 12); this->do_sync(POST_SYNC, 12);
@ -774,9 +750,9 @@ private:
auto cur_pc_val = pc.val; auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4; super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
auto offs_val = (static_cast<int64_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)) + (imm)); auto offs_val = (static_cast<int32_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)) + (imm));
if(rd != 0){ if(rd != 0){
auto Xtmp0_val = super::template zext<uint64_t>(super::template read_mem<uint8_t>(traits<ARCH>::MEM, offs_val)); auto Xtmp0_val = super::template zext<uint32_t>(super::template read_mem<uint8_t>(traits<ARCH>::MEM, offs_val));
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val; super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val;
} }
this->do_sync(POST_SYNC, 13); this->do_sync(POST_SYNC, 13);
@ -808,9 +784,9 @@ private:
auto cur_pc_val = pc.val; auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4; super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
auto offs_val = (static_cast<int64_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)) + (imm)); auto offs_val = (static_cast<int32_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)) + (imm));
if(rd != 0){ if(rd != 0){
auto Xtmp0_val = super::template zext<uint64_t>(super::template read_mem<uint16_t>(traits<ARCH>::MEM, offs_val)); auto Xtmp0_val = super::template zext<uint32_t>(super::template read_mem<uint16_t>(traits<ARCH>::MEM, offs_val));
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val; super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val;
} }
this->do_sync(POST_SYNC, 14); this->do_sync(POST_SYNC, 14);
@ -842,7 +818,7 @@ private:
auto cur_pc_val = pc.val; auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4; super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
auto offs_val = (static_cast<int64_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)) + (imm)); auto offs_val = (static_cast<int32_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)) + (imm));
auto MEMtmp0_val = super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0); auto MEMtmp0_val = super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0);
super::write_mem(traits<ARCH>::MEM, offs_val, static_cast<uint8_t>(MEMtmp0_val)); super::write_mem(traits<ARCH>::MEM, offs_val, static_cast<uint8_t>(MEMtmp0_val));
this->do_sync(POST_SYNC, 15); this->do_sync(POST_SYNC, 15);
@ -874,7 +850,7 @@ private:
auto cur_pc_val = pc.val; auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4; super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
auto offs_val = (static_cast<int64_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)) + (imm)); auto offs_val = (static_cast<int32_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)) + (imm));
auto MEMtmp0_val = super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0); auto MEMtmp0_val = super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0);
super::write_mem(traits<ARCH>::MEM, offs_val, static_cast<uint16_t>(MEMtmp0_val)); super::write_mem(traits<ARCH>::MEM, offs_val, static_cast<uint16_t>(MEMtmp0_val));
this->do_sync(POST_SYNC, 16); this->do_sync(POST_SYNC, 16);
@ -906,7 +882,7 @@ private:
auto cur_pc_val = pc.val; auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4; super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
auto offs_val = (static_cast<int64_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)) + (imm)); auto offs_val = (static_cast<int32_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)) + (imm));
auto MEMtmp0_val = super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0); auto MEMtmp0_val = super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0);
super::write_mem(traits<ARCH>::MEM, offs_val, static_cast<uint32_t>(MEMtmp0_val)); super::write_mem(traits<ARCH>::MEM, offs_val, static_cast<uint32_t>(MEMtmp0_val));
this->do_sync(POST_SYNC, 17); this->do_sync(POST_SYNC, 17);
@ -939,7 +915,7 @@ private:
auto cur_pc_val = pc.val; auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4; super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
if(rd != 0){ if(rd != 0){
auto Xtmp0_val = (static_cast<int64_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)) + (imm)); auto Xtmp0_val = (static_cast<int32_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)) + (imm));
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val; super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val;
} }
this->do_sync(POST_SYNC, 18); this->do_sync(POST_SYNC, 18);
@ -972,7 +948,7 @@ private:
auto cur_pc_val = pc.val; auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4; super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
if(rd != 0){ if(rd != 0){
auto Xtmp0_val = (static_cast<int64_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)) < (imm))? auto Xtmp0_val = (static_cast<int32_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)) < (imm))?
1: 1:
0; 0;
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val; super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val;
@ -1006,7 +982,7 @@ private:
auto cur_pc_val = pc.val; auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4; super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
int64_t full_imm_val = imm; int32_t full_imm_val = imm;
if(rd != 0){ if(rd != 0){
auto Xtmp0_val = (super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0) < full_imm_val)? auto Xtmp0_val = (super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0) < full_imm_val)?
1: 1:
@ -1043,7 +1019,7 @@ private:
auto cur_pc_val = pc.val; auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4; super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
if(rd != 0){ if(rd != 0){
auto Xtmp0_val = (static_cast<int64_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)) ^ (imm)); auto Xtmp0_val = (static_cast<int32_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)) ^ (imm));
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val; super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val;
} }
this->do_sync(POST_SYNC, 21); this->do_sync(POST_SYNC, 21);
@ -1076,7 +1052,7 @@ private:
auto cur_pc_val = pc.val; auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4; super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
if(rd != 0){ if(rd != 0){
auto Xtmp0_val = (static_cast<int64_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)) | (imm)); auto Xtmp0_val = (static_cast<int32_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)) | (imm));
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val; super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val;
} }
this->do_sync(POST_SYNC, 22); this->do_sync(POST_SYNC, 22);
@ -1109,7 +1085,7 @@ private:
auto cur_pc_val = pc.val; auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4; super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
if(rd != 0){ if(rd != 0){
auto Xtmp0_val = (static_cast<int64_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)) & (imm)); auto Xtmp0_val = (static_cast<int32_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)) & (imm));
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val; super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val;
} }
this->do_sync(POST_SYNC, 23); this->do_sync(POST_SYNC, 23);
@ -1130,7 +1106,7 @@ private:
uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rd = ((bit_sub<7,5>(instr)));
uint8_t rs1 = ((bit_sub<15,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr)));
uint8_t shamt = ((bit_sub<20,6>(instr))); uint8_t shamt = ((bit_sub<20,5>(instr)));
if(this->disass_enabled){ if(this->disass_enabled){
/* generate console output when executing the command */ /* generate console output when executing the command */
auto mnemonic = fmt::format( auto mnemonic = fmt::format(
@ -1141,9 +1117,13 @@ private:
auto cur_pc_val = pc.val; auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4; super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
if(rd != 0){ if(shamt > 31){
auto Xtmp0_val = (super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)<<(shamt)); raise_trap(0, 0);
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val; } else {
if(rd != 0){
auto Xtmp0_val = (super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)<<(shamt));
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val;
}
} }
this->do_sync(POST_SYNC, 24); this->do_sync(POST_SYNC, 24);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE); auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
@ -1163,7 +1143,7 @@ private:
uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rd = ((bit_sub<7,5>(instr)));
uint8_t rs1 = ((bit_sub<15,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr)));
uint8_t shamt = ((bit_sub<20,6>(instr))); uint8_t shamt = ((bit_sub<20,5>(instr)));
if(this->disass_enabled){ if(this->disass_enabled){
/* generate console output when executing the command */ /* generate console output when executing the command */
auto mnemonic = fmt::format( auto mnemonic = fmt::format(
@ -1174,9 +1154,13 @@ private:
auto cur_pc_val = pc.val; auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4; super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
if(rd != 0){ if(shamt > 31){
auto Xtmp0_val = (static_cast<uint64_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0))>>(shamt)); raise_trap(0, 0);
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val; } else {
if(rd != 0){
auto Xtmp0_val = (static_cast<uint32_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0))>>(shamt));
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val;
}
} }
this->do_sync(POST_SYNC, 25); this->do_sync(POST_SYNC, 25);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE); auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
@ -1196,7 +1180,7 @@ private:
uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rd = ((bit_sub<7,5>(instr)));
uint8_t rs1 = ((bit_sub<15,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr)));
uint8_t shamt = ((bit_sub<20,6>(instr))); uint8_t shamt = ((bit_sub<20,5>(instr)));
if(this->disass_enabled){ if(this->disass_enabled){
/* generate console output when executing the command */ /* generate console output when executing the command */
auto mnemonic = fmt::format( auto mnemonic = fmt::format(
@ -1207,9 +1191,13 @@ private:
auto cur_pc_val = pc.val; auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4; super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
if(rd != 0){ if(shamt > 31){
auto Xtmp0_val = (static_cast<int64_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0))>>(shamt)); raise_trap(0, 0);
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val; } else {
if(rd != 0){
auto Xtmp0_val = (static_cast<int32_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0))>>(shamt));
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val;
}
} }
this->do_sync(POST_SYNC, 26); this->do_sync(POST_SYNC, 26);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE); auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
@ -1307,7 +1295,7 @@ private:
auto cur_pc_val = pc.val; auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4; super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
if(rd != 0){ if(rd != 0){
auto Xtmp0_val = (super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)<<(super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0) & ((64) - 1))); auto Xtmp0_val = (super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)<<(super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0) & ((32) - 1)));
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val; super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val;
} }
this->do_sync(POST_SYNC, 29); this->do_sync(POST_SYNC, 29);
@ -1340,7 +1328,7 @@ private:
auto cur_pc_val = pc.val; auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4; super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
if(rd != 0){ if(rd != 0){
auto Xtmp0_val = (static_cast<int64_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)) < static_cast<int64_t>(super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0)))? auto Xtmp0_val = (static_cast<int32_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)) < static_cast<int32_t>(super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0)))?
1: 1:
0; 0;
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val; super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val;
@ -1375,7 +1363,7 @@ private:
auto cur_pc_val = pc.val; auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4; super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
if(rd != 0){ if(rd != 0){
auto Xtmp0_val = (super::template zext<uint64_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)) < super::template zext<uint64_t>(super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0)))? auto Xtmp0_val = (super::template zext<uint32_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)) < super::template zext<uint32_t>(super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0)))?
1: 1:
0; 0;
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val; super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val;
@ -1443,7 +1431,7 @@ private:
auto cur_pc_val = pc.val; auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4; super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
if(rd != 0){ if(rd != 0){
auto Xtmp0_val = (static_cast<uint64_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0))>>(super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0) & ((64) - 1))); auto Xtmp0_val = (static_cast<uint32_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0))>>(super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0) & ((32) - 1)));
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val; super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val;
} }
this->do_sync(POST_SYNC, 33); this->do_sync(POST_SYNC, 33);
@ -1476,7 +1464,7 @@ private:
auto cur_pc_val = pc.val; auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4; super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
if(rd != 0){ if(rd != 0){
auto Xtmp0_val = (static_cast<int64_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0))>>(super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0) & ((64) - 1))); auto Xtmp0_val = (static_cast<int32_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0))>>(super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0) & ((32) - 1)));
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val; super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val;
} }
this->do_sync(POST_SYNC, 34); this->do_sync(POST_SYNC, 34);
@ -1573,7 +1561,7 @@ private:
auto cur_pc_val = pc.val; auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4; super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
auto FENCEtmp0_val = (((pred) << 4) | (succ)); auto FENCEtmp0_val = (((pred) << 4) | (succ));
super::write_mem(traits<ARCH>::FENCE, (0), static_cast<uint64_t>(FENCEtmp0_val)); super::write_mem(traits<ARCH>::FENCE, (0), static_cast<uint32_t>(FENCEtmp0_val));
this->do_sync(POST_SYNC, 37); this->do_sync(POST_SYNC, 37);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE); auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
// trap check // trap check
@ -1601,7 +1589,7 @@ private:
auto cur_pc_val = pc.val; auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4; super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
auto FENCEtmp0_val = (imm); auto FENCEtmp0_val = (imm);
super::write_mem(traits<ARCH>::FENCE, (1), static_cast<uint64_t>(FENCEtmp0_val)); super::write_mem(traits<ARCH>::FENCE, (1), static_cast<uint32_t>(FENCEtmp0_val));
this->do_sync(POST_SYNC, 38); this->do_sync(POST_SYNC, 38);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE); auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
// trap check // trap check
@ -1772,9 +1760,9 @@ private:
auto cur_pc_val = pc.val; auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4; super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
auto FENCEtmp0_val = (rs1); auto FENCEtmp0_val = (rs1);
super::write_mem(traits<ARCH>::FENCE, (2), static_cast<uint64_t>(FENCEtmp0_val)); super::write_mem(traits<ARCH>::FENCE, (2), static_cast<uint32_t>(FENCEtmp0_val));
auto FENCEtmp1_val = (rs2); auto FENCEtmp1_val = (rs2);
super::write_mem(traits<ARCH>::FENCE, (3), static_cast<uint64_t>(FENCEtmp1_val)); super::write_mem(traits<ARCH>::FENCE, (3), static_cast<uint32_t>(FENCEtmp1_val));
this->do_sync(POST_SYNC, 45); this->do_sync(POST_SYNC, 45);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE); auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
// trap check // trap check
@ -1806,14 +1794,14 @@ private:
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4; super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
auto rs_val_val = super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0); auto rs_val_val = super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0);
if(rd != 0){ if(rd != 0){
auto csr_val_val = super::template read_mem<uint64_t>(traits<ARCH>::CSR, (csr)); auto csr_val_val = super::template read_mem<uint32_t>(traits<ARCH>::CSR, (csr));
auto CSRtmp0_val = rs_val_val; auto CSRtmp0_val = rs_val_val;
super::write_mem(traits<ARCH>::CSR, (csr), static_cast<uint64_t>(CSRtmp0_val)); super::write_mem(traits<ARCH>::CSR, (csr), static_cast<uint32_t>(CSRtmp0_val));
auto Xtmp1_val = csr_val_val; auto Xtmp1_val = csr_val_val;
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp1_val; super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp1_val;
} else { } else {
auto CSRtmp2_val = rs_val_val; auto CSRtmp2_val = rs_val_val;
super::write_mem(traits<ARCH>::CSR, (csr), static_cast<uint64_t>(CSRtmp2_val)); super::write_mem(traits<ARCH>::CSR, (csr), static_cast<uint32_t>(CSRtmp2_val));
} }
this->do_sync(POST_SYNC, 46); this->do_sync(POST_SYNC, 46);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE); auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
@ -1844,7 +1832,7 @@ private:
auto cur_pc_val = pc.val; auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4; super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
auto xrd_val = super::template read_mem<uint64_t>(traits<ARCH>::CSR, (csr)); auto xrd_val = super::template read_mem<uint32_t>(traits<ARCH>::CSR, (csr));
auto xrs1_val = super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0); auto xrs1_val = super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0);
if(rd != 0){ if(rd != 0){
auto Xtmp0_val = xrd_val; auto Xtmp0_val = xrd_val;
@ -1852,7 +1840,7 @@ private:
} }
if(rs1 != 0){ if(rs1 != 0){
auto CSRtmp1_val = (xrd_val | xrs1_val); auto CSRtmp1_val = (xrd_val | xrs1_val);
super::write_mem(traits<ARCH>::CSR, (csr), static_cast<uint64_t>(CSRtmp1_val)); super::write_mem(traits<ARCH>::CSR, (csr), static_cast<uint32_t>(CSRtmp1_val));
} }
this->do_sync(POST_SYNC, 47); this->do_sync(POST_SYNC, 47);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE); auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
@ -1883,7 +1871,7 @@ private:
auto cur_pc_val = pc.val; auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4; super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
auto xrd_val = super::template read_mem<uint64_t>(traits<ARCH>::CSR, (csr)); auto xrd_val = super::template read_mem<uint32_t>(traits<ARCH>::CSR, (csr));
auto xrs1_val = super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0); auto xrs1_val = super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0);
if(rd != 0){ if(rd != 0){
auto Xtmp0_val = xrd_val; auto Xtmp0_val = xrd_val;
@ -1891,7 +1879,7 @@ private:
} }
if(rs1 != 0){ if(rs1 != 0){
auto CSRtmp1_val = (xrd_val & ~(xrs1_val)); auto CSRtmp1_val = (xrd_val & ~(xrs1_val));
super::write_mem(traits<ARCH>::CSR, (csr), static_cast<uint64_t>(CSRtmp1_val)); super::write_mem(traits<ARCH>::CSR, (csr), static_cast<uint32_t>(CSRtmp1_val));
} }
this->do_sync(POST_SYNC, 48); this->do_sync(POST_SYNC, 48);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE); auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
@ -1923,11 +1911,11 @@ private:
auto cur_pc_val = pc.val; auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4; super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
if(rd != 0){ if(rd != 0){
auto Xtmp0_val = super::template read_mem<uint64_t>(traits<ARCH>::CSR, (csr)); auto Xtmp0_val = super::template read_mem<uint32_t>(traits<ARCH>::CSR, (csr));
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val; super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val;
} }
auto CSRtmp1_val = super::template zext<uint64_t>((zimm)); auto CSRtmp1_val = super::template zext<uint32_t>((zimm));
super::write_mem(traits<ARCH>::CSR, (csr), static_cast<uint64_t>(CSRtmp1_val)); super::write_mem(traits<ARCH>::CSR, (csr), static_cast<uint32_t>(CSRtmp1_val));
this->do_sync(POST_SYNC, 49); this->do_sync(POST_SYNC, 49);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE); auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
// trap check // trap check
@ -1957,10 +1945,10 @@ private:
auto cur_pc_val = pc.val; auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4; super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
auto res_val = super::template read_mem<uint64_t>(traits<ARCH>::CSR, (csr)); auto res_val = super::template read_mem<uint32_t>(traits<ARCH>::CSR, (csr));
if(zimm != 0){ if(zimm != 0){
auto CSRtmp0_val = (res_val | super::template zext<uint64_t>((zimm))); auto CSRtmp0_val = (res_val | super::template zext<uint32_t>((zimm)));
super::write_mem(traits<ARCH>::CSR, (csr), static_cast<uint64_t>(CSRtmp0_val)); super::write_mem(traits<ARCH>::CSR, (csr), static_cast<uint32_t>(CSRtmp0_val));
} }
if(rd != 0){ if(rd != 0){
auto Xtmp1_val = res_val; auto Xtmp1_val = res_val;
@ -1995,14 +1983,14 @@ private:
auto cur_pc_val = pc.val; auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4; super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
auto res_val = super::template read_mem<uint64_t>(traits<ARCH>::CSR, (csr)); auto res_val = super::template read_mem<uint32_t>(traits<ARCH>::CSR, (csr));
if(rd != 0){ if(rd != 0){
auto Xtmp0_val = res_val; auto Xtmp0_val = res_val;
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val; super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val;
} }
if(zimm != 0){ if(zimm != 0){
auto CSRtmp1_val = (res_val & ~(super::template zext<uint64_t>((zimm)))); auto CSRtmp1_val = (res_val & ~(super::template zext<uint32_t>((zimm))));
super::write_mem(traits<ARCH>::CSR, (csr), static_cast<uint64_t>(CSRtmp1_val)); super::write_mem(traits<ARCH>::CSR, (csr), static_cast<uint32_t>(CSRtmp1_val));
} }
this->do_sync(POST_SYNC, 51); this->do_sync(POST_SYNC, 51);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE); auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
@ -2016,440 +2004,6 @@ private:
return pc; return pc;
} }
/* instruction 52: LWU */
compile_ret_t __lwu(virt_addr_t& pc, code_word_t instr){
this->do_sync(PRE_SYNC, 52);
uint8_t rd = ((bit_sub<7,5>(instr)));
uint8_t rs1 = ((bit_sub<15,5>(instr)));
int16_t imm = signextend<int16_t,12>((bit_sub<20,12>(instr)));
if(this->disass_enabled){
/* generate console output when executing the command */
auto mnemonic = fmt::format(
"{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lwu"),
fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1)));
this->core.disass_output(pc.val, mnemonic);
}
auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
auto offs_val = (static_cast<int64_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)) + (imm));
if(rd != 0){
auto Xtmp0_val = super::template zext<uint64_t>(super::template read_mem<uint32_t>(traits<ARCH>::MEM, offs_val));
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val;
}
this->do_sync(POST_SYNC, 52);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
// trap check
if(trap_state!=0){
auto& last_br = super::template get_reg<uint32_t>(arch::traits<ARCH>::LAST_BRANCH);
last_br = std::numeric_limits<uint32_t>::max();
super::core.enter_trap(trap_state, cur_pc_val);
}
pc.val=super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC);
return pc;
}
/* instruction 53: LD */
compile_ret_t __ld(virt_addr_t& pc, code_word_t instr){
this->do_sync(PRE_SYNC, 53);
uint8_t rd = ((bit_sub<7,5>(instr)));
uint8_t rs1 = ((bit_sub<15,5>(instr)));
int16_t imm = signextend<int16_t,12>((bit_sub<20,12>(instr)));
if(this->disass_enabled){
/* generate console output when executing the command */
auto mnemonic = fmt::format(
"{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "ld"),
fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1)));
this->core.disass_output(pc.val, mnemonic);
}
auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
auto offs_val = (static_cast<int64_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)) + (imm));
if(rd != 0){
auto Xtmp0_val = super::template sext<int64_t>(super::template read_mem<uint64_t>(traits<ARCH>::MEM, offs_val));
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val;
}
this->do_sync(POST_SYNC, 53);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
// trap check
if(trap_state!=0){
auto& last_br = super::template get_reg<uint32_t>(arch::traits<ARCH>::LAST_BRANCH);
last_br = std::numeric_limits<uint32_t>::max();
super::core.enter_trap(trap_state, cur_pc_val);
}
pc.val=super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC);
return pc;
}
/* instruction 54: SD */
compile_ret_t __sd(virt_addr_t& pc, code_word_t instr){
this->do_sync(PRE_SYNC, 54);
int16_t imm = signextend<int16_t,12>((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5));
uint8_t rs1 = ((bit_sub<15,5>(instr)));
uint8_t rs2 = ((bit_sub<20,5>(instr)));
if(this->disass_enabled){
/* generate console output when executing the command */
auto mnemonic = fmt::format(
"{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sd"),
fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1)));
this->core.disass_output(pc.val, mnemonic);
}
auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
auto offs_val = (static_cast<int64_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)) + (imm));
auto MEMtmp0_val = super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0);
super::write_mem(traits<ARCH>::MEM, offs_val, static_cast<uint64_t>(MEMtmp0_val));
this->do_sync(POST_SYNC, 54);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
// trap check
if(trap_state!=0){
auto& last_br = super::template get_reg<uint32_t>(arch::traits<ARCH>::LAST_BRANCH);
last_br = std::numeric_limits<uint32_t>::max();
super::core.enter_trap(trap_state, cur_pc_val);
}
pc.val=super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC);
return pc;
}
/* instruction 55: ADDIW */
compile_ret_t __addiw(virt_addr_t& pc, code_word_t instr){
this->do_sync(PRE_SYNC, 55);
uint8_t rd = ((bit_sub<7,5>(instr)));
uint8_t rs1 = ((bit_sub<15,5>(instr)));
int16_t imm = signextend<int16_t,12>((bit_sub<20,12>(instr)));
if(this->disass_enabled){
/* generate console output when executing the command */
auto mnemonic = fmt::format(
"{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "addiw"),
fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm));
this->core.disass_output(pc.val, mnemonic);
}
auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
if(rd != 0){
auto res_val = (static_cast<int32_t>(static_cast<uint32_t>(
super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)
)) + (imm));
auto Xtmp0_val = super::template sext<int64_t>(res_val);
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val;
}
this->do_sync(POST_SYNC, 55);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
// trap check
if(trap_state!=0){
auto& last_br = super::template get_reg<uint32_t>(arch::traits<ARCH>::LAST_BRANCH);
last_br = std::numeric_limits<uint32_t>::max();
super::core.enter_trap(trap_state, cur_pc_val);
}
pc.val=super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC);
return pc;
}
/* instruction 56: SLLIW */
compile_ret_t __slliw(virt_addr_t& pc, code_word_t instr){
this->do_sync(PRE_SYNC, 56);
uint8_t rd = ((bit_sub<7,5>(instr)));
uint8_t rs1 = ((bit_sub<15,5>(instr)));
uint8_t shamt = ((bit_sub<20,5>(instr)));
if(this->disass_enabled){
/* generate console output when executing the command */
auto mnemonic = fmt::format(
"{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "slliw"),
fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt));
this->core.disass_output(pc.val, mnemonic);
}
auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
if(rd != 0){
auto sh_val_val = (static_cast<uint32_t>(
super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)
)<<(shamt));
auto Xtmp0_val = super::template sext<int64_t>(sh_val_val);
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val;
}
this->do_sync(POST_SYNC, 56);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
// trap check
if(trap_state!=0){
auto& last_br = super::template get_reg<uint32_t>(arch::traits<ARCH>::LAST_BRANCH);
last_br = std::numeric_limits<uint32_t>::max();
super::core.enter_trap(trap_state, cur_pc_val);
}
pc.val=super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC);
return pc;
}
/* instruction 57: SRLIW */
compile_ret_t __srliw(virt_addr_t& pc, code_word_t instr){
this->do_sync(PRE_SYNC, 57);
uint8_t rd = ((bit_sub<7,5>(instr)));
uint8_t rs1 = ((bit_sub<15,5>(instr)));
uint8_t shamt = ((bit_sub<20,5>(instr)));
if(this->disass_enabled){
/* generate console output when executing the command */
auto mnemonic = fmt::format(
"{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "srliw"),
fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt));
this->core.disass_output(pc.val, mnemonic);
}
auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
if(rd != 0){
auto sh_val_val = (static_cast<uint32_t>(static_cast<uint32_t>(
super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)
))>>(shamt));
auto Xtmp0_val = super::template sext<int64_t>(sh_val_val);
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val;
}
this->do_sync(POST_SYNC, 57);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
// trap check
if(trap_state!=0){
auto& last_br = super::template get_reg<uint32_t>(arch::traits<ARCH>::LAST_BRANCH);
last_br = std::numeric_limits<uint32_t>::max();
super::core.enter_trap(trap_state, cur_pc_val);
}
pc.val=super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC);
return pc;
}
/* instruction 58: SRAIW */
compile_ret_t __sraiw(virt_addr_t& pc, code_word_t instr){
this->do_sync(PRE_SYNC, 58);
uint8_t rd = ((bit_sub<7,5>(instr)));
uint8_t rs1 = ((bit_sub<15,5>(instr)));
uint8_t shamt = ((bit_sub<20,5>(instr)));
if(this->disass_enabled){
/* generate console output when executing the command */
auto mnemonic = fmt::format(
"{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "sraiw"),
fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt));
this->core.disass_output(pc.val, mnemonic);
}
auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
if(rd != 0){
auto sh_val_val = (static_cast<int32_t>(static_cast<uint32_t>(
super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)
))>>(shamt));
auto Xtmp0_val = super::template sext<int64_t>(sh_val_val);
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val;
}
this->do_sync(POST_SYNC, 58);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
// trap check
if(trap_state!=0){
auto& last_br = super::template get_reg<uint32_t>(arch::traits<ARCH>::LAST_BRANCH);
last_br = std::numeric_limits<uint32_t>::max();
super::core.enter_trap(trap_state, cur_pc_val);
}
pc.val=super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC);
return pc;
}
/* instruction 59: ADDW */
compile_ret_t __addw(virt_addr_t& pc, code_word_t instr){
this->do_sync(PRE_SYNC, 59);
uint8_t rd = ((bit_sub<7,5>(instr)));
uint8_t rs1 = ((bit_sub<15,5>(instr)));
uint8_t rs2 = ((bit_sub<20,5>(instr)));
if(this->disass_enabled){
/* generate console output when executing the command */
this->core.disass_output(pc.val, "addw");
}
auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
if(rd != 0){
auto res_val = (static_cast<uint32_t>(
super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)
) + static_cast<uint32_t>(
super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0)
));
auto Xtmp0_val = super::template sext<int64_t>(res_val);
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val;
}
this->do_sync(POST_SYNC, 59);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
// trap check
if(trap_state!=0){
auto& last_br = super::template get_reg<uint32_t>(arch::traits<ARCH>::LAST_BRANCH);
last_br = std::numeric_limits<uint32_t>::max();
super::core.enter_trap(trap_state, cur_pc_val);
}
pc.val=super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC);
return pc;
}
/* instruction 60: SUBW */
compile_ret_t __subw(virt_addr_t& pc, code_word_t instr){
this->do_sync(PRE_SYNC, 60);
uint8_t rd = ((bit_sub<7,5>(instr)));
uint8_t rs1 = ((bit_sub<15,5>(instr)));
uint8_t rs2 = ((bit_sub<20,5>(instr)));
if(this->disass_enabled){
/* generate console output when executing the command */
this->core.disass_output(pc.val, "subw");
}
auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
if(rd != 0){
auto res_val = (static_cast<uint32_t>(
super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)
) - static_cast<uint32_t>(
super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0)
));
auto Xtmp0_val = super::template sext<int64_t>(res_val);
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val;
}
this->do_sync(POST_SYNC, 60);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
// trap check
if(trap_state!=0){
auto& last_br = super::template get_reg<uint32_t>(arch::traits<ARCH>::LAST_BRANCH);
last_br = std::numeric_limits<uint32_t>::max();
super::core.enter_trap(trap_state, cur_pc_val);
}
pc.val=super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC);
return pc;
}
/* instruction 61: SLLW */
compile_ret_t __sllw(virt_addr_t& pc, code_word_t instr){
this->do_sync(PRE_SYNC, 61);
uint8_t rd = ((bit_sub<7,5>(instr)));
uint8_t rs1 = ((bit_sub<15,5>(instr)));
uint8_t rs2 = ((bit_sub<20,5>(instr)));
if(this->disass_enabled){
/* generate console output when executing the command */
auto mnemonic = fmt::format(
"{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sllw"),
fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)));
this->core.disass_output(pc.val, mnemonic);
}
auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
if(rd != 0){
uint32_t mask_val = 0x1f;
auto count_val = (static_cast<uint32_t>(
super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0)
) & mask_val);
auto sh_val_val = (static_cast<uint32_t>(
super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)
)<<count_val);
auto Xtmp0_val = super::template sext<int64_t>(sh_val_val);
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val;
}
this->do_sync(POST_SYNC, 61);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
// trap check
if(trap_state!=0){
auto& last_br = super::template get_reg<uint32_t>(arch::traits<ARCH>::LAST_BRANCH);
last_br = std::numeric_limits<uint32_t>::max();
super::core.enter_trap(trap_state, cur_pc_val);
}
pc.val=super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC);
return pc;
}
/* instruction 62: SRLW */
compile_ret_t __srlw(virt_addr_t& pc, code_word_t instr){
this->do_sync(PRE_SYNC, 62);
uint8_t rd = ((bit_sub<7,5>(instr)));
uint8_t rs1 = ((bit_sub<15,5>(instr)));
uint8_t rs2 = ((bit_sub<20,5>(instr)));
if(this->disass_enabled){
/* generate console output when executing the command */
auto mnemonic = fmt::format(
"{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "srlw"),
fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)));
this->core.disass_output(pc.val, mnemonic);
}
auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
if(rd != 0){
uint32_t mask_val = 0x1f;
auto count_val = (static_cast<uint32_t>(
super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0)
) & mask_val);
auto sh_val_val = (static_cast<uint32_t>(static_cast<uint32_t>(
super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)
))>>count_val);
auto Xtmp0_val = super::template sext<int64_t>(sh_val_val);
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val;
}
this->do_sync(POST_SYNC, 62);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
// trap check
if(trap_state!=0){
auto& last_br = super::template get_reg<uint32_t>(arch::traits<ARCH>::LAST_BRANCH);
last_br = std::numeric_limits<uint32_t>::max();
super::core.enter_trap(trap_state, cur_pc_val);
}
pc.val=super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC);
return pc;
}
/* instruction 63: SRAW */
compile_ret_t __sraw(virt_addr_t& pc, code_word_t instr){
this->do_sync(PRE_SYNC, 63);
uint8_t rd = ((bit_sub<7,5>(instr)));
uint8_t rs1 = ((bit_sub<15,5>(instr)));
uint8_t rs2 = ((bit_sub<20,5>(instr)));
if(this->disass_enabled){
/* generate console output when executing the command */
auto mnemonic = fmt::format(
"{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sraw"),
fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)));
this->core.disass_output(pc.val, mnemonic);
}
auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
if(rd != 0){
uint32_t mask_val = 0x1f;
auto count_val = (static_cast<uint32_t>(
super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0)
) & mask_val);
auto sh_val_val = (static_cast<int32_t>(static_cast<uint32_t>(
super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)
))>>count_val);
auto Xtmp0_val = super::template sext<int64_t>(sh_val_val);
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val;
}
this->do_sync(POST_SYNC, 63);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
// trap check
if(trap_state!=0){
auto& last_br = super::template get_reg<uint32_t>(arch::traits<ARCH>::LAST_BRANCH);
last_br = std::numeric_limits<uint32_t>::max();
super::core.enter_trap(trap_state, cur_pc_val);
}
pc.val=super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC);
return pc;
}
/**************************************************************************** /****************************************************************************
* end opcode definitions * end opcode definitions
****************************************************************************/ ****************************************************************************/
@ -2509,8 +2063,8 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(virt_addr_t star
} // namespace mnrv32 } // namespace mnrv32
template <> template <>
std::unique_ptr<vm_if> create<arch::rv64i>(arch::rv64i *core, unsigned short port, bool dump) { std::unique_ptr<vm_if> create<arch::tgf01>(arch::tgf01 *core, unsigned short port, bool dump) {
auto ret = new rv64i::vm_impl<arch::rv64i>(*core, dump); auto ret = new tgf01::vm_impl<arch::tgf01>(*core, dump);
if (port != 0) debugger::server<debugger::gdb_session>::run_server(ret, port); if (port != 0) debugger::server<debugger::gdb_session>::run_server(ret, port);
return std::unique_ptr<vm_if>(ret); return std::unique_ptr<vm_if>(ret);
} }

View File

@ -31,8 +31,8 @@
*******************************************************************************/ *******************************************************************************/
#include "../fp_functions.h" #include "../fp_functions.h"
#include <iss/arch/mnrv32.h> #include <iss/arch/tgf02.h>
#include <iss/arch/riscv_hart_msu_vp.h> #include <iss/arch/riscv_hart_m_p.h>
#include <iss/debugger/gdb_session.h> #include <iss/debugger/gdb_session.h>
#include <iss/debugger/server.h> #include <iss/debugger/server.h>
#include <iss/iss.h> #include <iss/iss.h>
@ -50,7 +50,7 @@
namespace iss { namespace iss {
namespace interp { namespace interp {
namespace mnrv32 { namespace tgf02 {
using namespace iss::arch; using namespace iss::arch;
using namespace iss::debugger; using namespace iss::debugger;
@ -167,7 +167,7 @@ private:
compile_func op; compile_func op;
}; };
const std::array<InstructionDesriptor, 80> instr_descr = {{ const std::array<InstructionDesriptor, 88> instr_descr = {{
/* entries are: size, valid value, valid mask, function ptr */ /* entries are: size, valid value, valid mask, function ptr */
/* instruction LUI */ /* instruction LUI */
{32, 0b00000000000000000000000000110111, 0b00000000000000000000000001111111, &this_class::__lui}, {32, 0b00000000000000000000000000110111, 0b00000000000000000000000001111111, &this_class::__lui},
@ -273,6 +273,22 @@ private:
{32, 0b00000000000000000110000001110011, 0b00000000000000000111000001111111, &this_class::__csrrsi}, {32, 0b00000000000000000110000001110011, 0b00000000000000000111000001111111, &this_class::__csrrsi},
/* instruction CSRRCI */ /* instruction CSRRCI */
{32, 0b00000000000000000111000001110011, 0b00000000000000000111000001111111, &this_class::__csrrci}, {32, 0b00000000000000000111000001110011, 0b00000000000000000111000001111111, &this_class::__csrrci},
/* instruction MUL */
{32, 0b00000010000000000000000000110011, 0b11111110000000000111000001111111, &this_class::__mul},
/* instruction MULH */
{32, 0b00000010000000000001000000110011, 0b11111110000000000111000001111111, &this_class::__mulh},
/* instruction MULHSU */
{32, 0b00000010000000000010000000110011, 0b11111110000000000111000001111111, &this_class::__mulhsu},
/* instruction MULHU */
{32, 0b00000010000000000011000000110011, 0b11111110000000000111000001111111, &this_class::__mulhu},
/* instruction DIV */
{32, 0b00000010000000000100000000110011, 0b11111110000000000111000001111111, &this_class::__div},
/* instruction DIVU */
{32, 0b00000010000000000101000000110011, 0b11111110000000000111000001111111, &this_class::__divu},
/* instruction REM */
{32, 0b00000010000000000110000000110011, 0b11111110000000000111000001111111, &this_class::__rem},
/* instruction REMU */
{32, 0b00000010000000000111000000110011, 0b11111110000000000111000001111111, &this_class::__remu},
/* instruction C.ADDI4SPN */ /* instruction C.ADDI4SPN */
{16, 0b0000000000000000, 0b1110000000000011, &this_class::__c_addi4spn}, {16, 0b0000000000000000, 0b1110000000000011, &this_class::__c_addi4spn},
/* instruction C.LW */ /* instruction C.LW */
@ -2052,10 +2068,334 @@ private:
return pc; return pc;
} }
/* instruction 52: C.ADDI4SPN */ /* instruction 52: MUL */
compile_ret_t __c_addi4spn(virt_addr_t& pc, code_word_t instr){ compile_ret_t __mul(virt_addr_t& pc, code_word_t instr){
this->do_sync(PRE_SYNC, 52); this->do_sync(PRE_SYNC, 52);
uint8_t rd = ((bit_sub<7,5>(instr)));
uint8_t rs1 = ((bit_sub<15,5>(instr)));
uint8_t rs2 = ((bit_sub<20,5>(instr)));
if(this->disass_enabled){
/* generate console output when executing the command */
auto mnemonic = fmt::format(
"{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mul"),
fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)));
this->core.disass_output(pc.val, mnemonic);
}
auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
if(rd != 0){
auto res_val = (super::template zext<uint64_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)) * super::template zext<uint64_t>(super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0)));
auto Xtmp0_val = super::template zext<uint32_t>(res_val);
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val;
}
this->do_sync(POST_SYNC, 52);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
// trap check
if(trap_state!=0){
auto& last_br = super::template get_reg<uint32_t>(arch::traits<ARCH>::LAST_BRANCH);
last_br = std::numeric_limits<uint32_t>::max();
super::core.enter_trap(trap_state, cur_pc_val);
}
pc.val=super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC);
return pc;
}
/* instruction 53: MULH */
compile_ret_t __mulh(virt_addr_t& pc, code_word_t instr){
this->do_sync(PRE_SYNC, 53);
uint8_t rd = ((bit_sub<7,5>(instr)));
uint8_t rs1 = ((bit_sub<15,5>(instr)));
uint8_t rs2 = ((bit_sub<20,5>(instr)));
if(this->disass_enabled){
/* generate console output when executing the command */
auto mnemonic = fmt::format(
"{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mulh"),
fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)));
this->core.disass_output(pc.val, mnemonic);
}
auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
if(rd != 0){
auto res_val = (super::template sext<int64_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)) * super::template sext<int64_t>(super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0)));
auto Xtmp0_val = super::template zext<uint32_t>((res_val >> (32)));
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val;
}
this->do_sync(POST_SYNC, 53);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
// trap check
if(trap_state!=0){
auto& last_br = super::template get_reg<uint32_t>(arch::traits<ARCH>::LAST_BRANCH);
last_br = std::numeric_limits<uint32_t>::max();
super::core.enter_trap(trap_state, cur_pc_val);
}
pc.val=super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC);
return pc;
}
/* instruction 54: MULHSU */
compile_ret_t __mulhsu(virt_addr_t& pc, code_word_t instr){
this->do_sync(PRE_SYNC, 54);
uint8_t rd = ((bit_sub<7,5>(instr)));
uint8_t rs1 = ((bit_sub<15,5>(instr)));
uint8_t rs2 = ((bit_sub<20,5>(instr)));
if(this->disass_enabled){
/* generate console output when executing the command */
auto mnemonic = fmt::format(
"{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mulhsu"),
fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)));
this->core.disass_output(pc.val, mnemonic);
}
auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
if(rd != 0){
auto res_val = (super::template sext<int64_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)) * super::template zext<uint64_t>(super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0)));
auto Xtmp0_val = super::template zext<uint32_t>((res_val >> (32)));
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val;
}
this->do_sync(POST_SYNC, 54);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
// trap check
if(trap_state!=0){
auto& last_br = super::template get_reg<uint32_t>(arch::traits<ARCH>::LAST_BRANCH);
last_br = std::numeric_limits<uint32_t>::max();
super::core.enter_trap(trap_state, cur_pc_val);
}
pc.val=super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC);
return pc;
}
/* instruction 55: MULHU */
compile_ret_t __mulhu(virt_addr_t& pc, code_word_t instr){
this->do_sync(PRE_SYNC, 55);
uint8_t rd = ((bit_sub<7,5>(instr)));
uint8_t rs1 = ((bit_sub<15,5>(instr)));
uint8_t rs2 = ((bit_sub<20,5>(instr)));
if(this->disass_enabled){
/* generate console output when executing the command */
auto mnemonic = fmt::format(
"{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mulhu"),
fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)));
this->core.disass_output(pc.val, mnemonic);
}
auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
if(rd != 0){
auto res_val = (super::template zext<uint64_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)) * super::template zext<uint64_t>(super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0)));
auto Xtmp0_val = super::template zext<uint32_t>((res_val >> (32)));
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val;
}
this->do_sync(POST_SYNC, 55);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
// trap check
if(trap_state!=0){
auto& last_br = super::template get_reg<uint32_t>(arch::traits<ARCH>::LAST_BRANCH);
last_br = std::numeric_limits<uint32_t>::max();
super::core.enter_trap(trap_state, cur_pc_val);
}
pc.val=super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC);
return pc;
}
/* instruction 56: DIV */
compile_ret_t __div(virt_addr_t& pc, code_word_t instr){
this->do_sync(PRE_SYNC, 56);
uint8_t rd = ((bit_sub<7,5>(instr)));
uint8_t rs1 = ((bit_sub<15,5>(instr)));
uint8_t rs2 = ((bit_sub<20,5>(instr)));
if(this->disass_enabled){
/* generate console output when executing the command */
auto mnemonic = fmt::format(
"{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "div"),
fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)));
this->core.disass_output(pc.val, mnemonic);
}
auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
if(rd != 0){
{
if((super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0) != 0)) {
uint32_t M1_val = - 1;
uint8_t XLM1_val = 32 - 1;
uint32_t ONE_val = 1;
uint32_t MMIN_val = ONE_val << XLM1_val;
{
if(((super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0) == MMIN_val) && (super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0) == M1_val))) {
auto Xtmp0_val = MMIN_val;
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val;
}
else {
auto Xtmp1_val = (static_cast<int32_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)) / static_cast<int32_t>(super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0)));
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp1_val;
}
}
}
else {
auto Xtmp2_val = -(1);
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp2_val;
}
}
}
this->do_sync(POST_SYNC, 56);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
// trap check
if(trap_state!=0){
auto& last_br = super::template get_reg<uint32_t>(arch::traits<ARCH>::LAST_BRANCH);
last_br = std::numeric_limits<uint32_t>::max();
super::core.enter_trap(trap_state, cur_pc_val);
}
pc.val=super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC);
return pc;
}
/* instruction 57: DIVU */
compile_ret_t __divu(virt_addr_t& pc, code_word_t instr){
this->do_sync(PRE_SYNC, 57);
uint8_t rd = ((bit_sub<7,5>(instr)));
uint8_t rs1 = ((bit_sub<15,5>(instr)));
uint8_t rs2 = ((bit_sub<20,5>(instr)));
if(this->disass_enabled){
/* generate console output when executing the command */
auto mnemonic = fmt::format(
"{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "divu"),
fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)));
this->core.disass_output(pc.val, mnemonic);
}
auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
if(rd != 0){
{
if((super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0) != 0)) {
auto Xtmp0_val = (super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0) / super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0));
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val;
}
else {
auto Xtmp1_val = -(1);
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp1_val;
}
}
}
this->do_sync(POST_SYNC, 57);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
// trap check
if(trap_state!=0){
auto& last_br = super::template get_reg<uint32_t>(arch::traits<ARCH>::LAST_BRANCH);
last_br = std::numeric_limits<uint32_t>::max();
super::core.enter_trap(trap_state, cur_pc_val);
}
pc.val=super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC);
return pc;
}
/* instruction 58: REM */
compile_ret_t __rem(virt_addr_t& pc, code_word_t instr){
this->do_sync(PRE_SYNC, 58);
uint8_t rd = ((bit_sub<7,5>(instr)));
uint8_t rs1 = ((bit_sub<15,5>(instr)));
uint8_t rs2 = ((bit_sub<20,5>(instr)));
if(this->disass_enabled){
/* generate console output when executing the command */
auto mnemonic = fmt::format(
"{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "rem"),
fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)));
this->core.disass_output(pc.val, mnemonic);
}
auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
if(rd != 0){
{
if((super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0) != 0)) {
uint32_t M1_val = - 1;
uint32_t XLM1_val = 32 - 1;
uint32_t ONE_val = 1;
uint32_t MMIN_val = ONE_val << XLM1_val;
{
if(((super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0) == MMIN_val) && (super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0) == M1_val))) {
auto Xtmp0_val = 0;
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val;
}
else {
auto Xtmp1_val = (static_cast<int32_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)) % static_cast<int32_t>(super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0)));
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp1_val;
}
}
}
else {
auto Xtmp2_val = super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0);
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp2_val;
}
}
}
this->do_sync(POST_SYNC, 58);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
// trap check
if(trap_state!=0){
auto& last_br = super::template get_reg<uint32_t>(arch::traits<ARCH>::LAST_BRANCH);
last_br = std::numeric_limits<uint32_t>::max();
super::core.enter_trap(trap_state, cur_pc_val);
}
pc.val=super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC);
return pc;
}
/* instruction 59: REMU */
compile_ret_t __remu(virt_addr_t& pc, code_word_t instr){
this->do_sync(PRE_SYNC, 59);
uint8_t rd = ((bit_sub<7,5>(instr)));
uint8_t rs1 = ((bit_sub<15,5>(instr)));
uint8_t rs2 = ((bit_sub<20,5>(instr)));
if(this->disass_enabled){
/* generate console output when executing the command */
auto mnemonic = fmt::format(
"{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "remu"),
fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)));
this->core.disass_output(pc.val, mnemonic);
}
auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
if(rd != 0){
{
if((super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0) != 0)) {
auto Xtmp0_val = (super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0) % super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0));
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val;
}
else {
auto Xtmp1_val = super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0);
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp1_val;
}
}
}
this->do_sync(POST_SYNC, 59);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
// trap check
if(trap_state!=0){
auto& last_br = super::template get_reg<uint32_t>(arch::traits<ARCH>::LAST_BRANCH);
last_br = std::numeric_limits<uint32_t>::max();
super::core.enter_trap(trap_state, cur_pc_val);
}
pc.val=super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC);
return pc;
}
/* instruction 60: C.ADDI4SPN */
compile_ret_t __c_addi4spn(virt_addr_t& pc, code_word_t instr){
this->do_sync(PRE_SYNC, 60);
uint8_t rd = ((bit_sub<2,3>(instr))); uint8_t rd = ((bit_sub<2,3>(instr)));
uint16_t imm = ((bit_sub<5,1>(instr) << 3) | (bit_sub<6,1>(instr) << 2) | (bit_sub<7,4>(instr) << 6) | (bit_sub<11,2>(instr) << 4)); uint16_t imm = ((bit_sub<5,1>(instr) << 3) | (bit_sub<6,1>(instr) << 2) | (bit_sub<7,4>(instr) << 6) | (bit_sub<11,2>(instr) << 4));
if(this->disass_enabled){ if(this->disass_enabled){
@ -2073,7 +2413,7 @@ private:
} }
auto Xtmp0_val = (super::template get_reg<reg_t>(2 + traits<ARCH>::X0) + (imm)); auto Xtmp0_val = (super::template get_reg<reg_t>(2 + traits<ARCH>::X0) + (imm));
super::template get_reg<reg_t>(rd + 8 + traits<ARCH>::X0)=Xtmp0_val; super::template get_reg<reg_t>(rd + 8 + traits<ARCH>::X0)=Xtmp0_val;
this->do_sync(POST_SYNC, 52); this->do_sync(POST_SYNC, 60);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE); auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
// trap check // trap check
if(trap_state!=0){ if(trap_state!=0){
@ -2085,9 +2425,9 @@ private:
return pc; return pc;
} }
/* instruction 53: C.LW */ /* instruction 61: C.LW */
compile_ret_t __c_lw(virt_addr_t& pc, code_word_t instr){ compile_ret_t __c_lw(virt_addr_t& pc, code_word_t instr){
this->do_sync(PRE_SYNC, 53); this->do_sync(PRE_SYNC, 61);
uint8_t rd = ((bit_sub<2,3>(instr))); uint8_t rd = ((bit_sub<2,3>(instr)));
uint8_t uimm = ((bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 2) | (bit_sub<10,3>(instr) << 3)); uint8_t uimm = ((bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 2) | (bit_sub<10,3>(instr) << 3));
@ -2105,7 +2445,7 @@ private:
auto offs_val = (super::template get_reg<reg_t>(rs1 + 8 + traits<ARCH>::X0) + (uimm)); auto offs_val = (super::template get_reg<reg_t>(rs1 + 8 + traits<ARCH>::X0) + (uimm));
auto Xtmp0_val = super::template sext<int32_t>(super::template read_mem<uint32_t>(traits<ARCH>::MEM, offs_val)); auto Xtmp0_val = super::template sext<int32_t>(super::template read_mem<uint32_t>(traits<ARCH>::MEM, offs_val));
super::template get_reg<reg_t>(rd + 8 + traits<ARCH>::X0)=Xtmp0_val; super::template get_reg<reg_t>(rd + 8 + traits<ARCH>::X0)=Xtmp0_val;
this->do_sync(POST_SYNC, 53); this->do_sync(POST_SYNC, 61);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE); auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
// trap check // trap check
if(trap_state!=0){ if(trap_state!=0){
@ -2117,9 +2457,9 @@ private:
return pc; return pc;
} }
/* instruction 54: C.SW */ /* instruction 62: C.SW */
compile_ret_t __c_sw(virt_addr_t& pc, code_word_t instr){ compile_ret_t __c_sw(virt_addr_t& pc, code_word_t instr){
this->do_sync(PRE_SYNC, 54); this->do_sync(PRE_SYNC, 62);
uint8_t rs2 = ((bit_sub<2,3>(instr))); uint8_t rs2 = ((bit_sub<2,3>(instr)));
uint8_t uimm = ((bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 2) | (bit_sub<10,3>(instr) << 3)); uint8_t uimm = ((bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 2) | (bit_sub<10,3>(instr) << 3));
@ -2137,7 +2477,7 @@ private:
auto offs_val = (super::template get_reg<reg_t>(rs1 + 8 + traits<ARCH>::X0) + (uimm)); auto offs_val = (super::template get_reg<reg_t>(rs1 + 8 + traits<ARCH>::X0) + (uimm));
auto MEMtmp0_val = super::template get_reg<reg_t>(rs2 + 8 + traits<ARCH>::X0); auto MEMtmp0_val = super::template get_reg<reg_t>(rs2 + 8 + traits<ARCH>::X0);
super::write_mem(traits<ARCH>::MEM, offs_val, static_cast<uint32_t>(MEMtmp0_val)); super::write_mem(traits<ARCH>::MEM, offs_val, static_cast<uint32_t>(MEMtmp0_val));
this->do_sync(POST_SYNC, 54); this->do_sync(POST_SYNC, 62);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE); auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
// trap check // trap check
if(trap_state!=0){ if(trap_state!=0){
@ -2149,9 +2489,9 @@ private:
return pc; return pc;
} }
/* instruction 55: C.ADDI */ /* instruction 63: C.ADDI */
compile_ret_t __c_addi(virt_addr_t& pc, code_word_t instr){ compile_ret_t __c_addi(virt_addr_t& pc, code_word_t instr){
this->do_sync(PRE_SYNC, 55); this->do_sync(PRE_SYNC, 63);
int8_t imm = signextend<int8_t,6>((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); int8_t imm = signextend<int8_t,6>((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5));
uint8_t rs1 = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<7,5>(instr)));
@ -2167,7 +2507,7 @@ private:
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 2; super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 2;
auto Xtmp0_val = (static_cast<int32_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)) + (imm)); auto Xtmp0_val = (static_cast<int32_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)) + (imm));
super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)=Xtmp0_val; super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)=Xtmp0_val;
this->do_sync(POST_SYNC, 55); this->do_sync(POST_SYNC, 63);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE); auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
// trap check // trap check
if(trap_state!=0){ if(trap_state!=0){
@ -2179,9 +2519,9 @@ private:
return pc; return pc;
} }
/* instruction 56: C.NOP */ /* instruction 64: C.NOP */
compile_ret_t __c_nop(virt_addr_t& pc, code_word_t instr){ compile_ret_t __c_nop(virt_addr_t& pc, code_word_t instr){
this->do_sync(PRE_SYNC, 56); this->do_sync(PRE_SYNC, 64);
if(this->disass_enabled){ if(this->disass_enabled){
/* generate console output when executing the command */ /* generate console output when executing the command */
@ -2191,7 +2531,7 @@ private:
auto cur_pc_val = pc.val; auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 2; super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 2;
/* TODO: describe operations for C.NOP ! */ /* TODO: describe operations for C.NOP ! */
this->do_sync(POST_SYNC, 56); this->do_sync(POST_SYNC, 64);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE); auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
// trap check // trap check
if(trap_state!=0){ if(trap_state!=0){
@ -2203,9 +2543,9 @@ private:
return pc; return pc;
} }
/* instruction 57: C.JAL */ /* instruction 65: C.JAL */
compile_ret_t __c_jal(virt_addr_t& pc, code_word_t instr){ compile_ret_t __c_jal(virt_addr_t& pc, code_word_t instr){
this->do_sync(PRE_SYNC, 57); this->do_sync(PRE_SYNC, 65);
int16_t imm = signextend<int16_t,12>((bit_sub<2,1>(instr) << 5) | (bit_sub<3,3>(instr) << 1) | (bit_sub<6,1>(instr) << 7) | (bit_sub<7,1>(instr) << 6) | (bit_sub<8,1>(instr) << 10) | (bit_sub<9,2>(instr) << 8) | (bit_sub<11,1>(instr) << 4) | (bit_sub<12,1>(instr) << 11)); int16_t imm = signextend<int16_t,12>((bit_sub<2,1>(instr) << 5) | (bit_sub<3,3>(instr) << 1) | (bit_sub<6,1>(instr) << 7) | (bit_sub<7,1>(instr) << 6) | (bit_sub<8,1>(instr) << 10) | (bit_sub<9,2>(instr) << 8) | (bit_sub<11,1>(instr) << 4) | (bit_sub<12,1>(instr) << 11));
if(this->disass_enabled){ if(this->disass_enabled){
@ -2224,7 +2564,7 @@ private:
super::template get_reg(traits<ARCH>::NEXT_PC) = PC_val; super::template get_reg(traits<ARCH>::NEXT_PC) = PC_val;
auto is_cont_v = PC_val !=pc.val; auto is_cont_v = PC_val !=pc.val;
super::template get_reg(traits<ARCH>::LAST_BRANCH) = is_cont_v?1:0; super::template get_reg(traits<ARCH>::LAST_BRANCH) = is_cont_v?1:0;
this->do_sync(POST_SYNC, 57); this->do_sync(POST_SYNC, 65);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE); auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
// trap check // trap check
if(trap_state!=0){ if(trap_state!=0){
@ -2236,9 +2576,9 @@ private:
return pc; return pc;
} }
/* instruction 58: C.LI */ /* instruction 66: C.LI */
compile_ret_t __c_li(virt_addr_t& pc, code_word_t instr){ compile_ret_t __c_li(virt_addr_t& pc, code_word_t instr){
this->do_sync(PRE_SYNC, 58); this->do_sync(PRE_SYNC, 66);
int8_t imm = signextend<int8_t,6>((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); int8_t imm = signextend<int8_t,6>((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5));
uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rd = ((bit_sub<7,5>(instr)));
@ -2257,7 +2597,7 @@ private:
} }
auto Xtmp0_val = (imm); auto Xtmp0_val = (imm);
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val; super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val;
this->do_sync(POST_SYNC, 58); this->do_sync(POST_SYNC, 66);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE); auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
// trap check // trap check
if(trap_state!=0){ if(trap_state!=0){
@ -2269,9 +2609,9 @@ private:
return pc; return pc;
} }
/* instruction 59: C.LUI */ /* instruction 67: C.LUI */
compile_ret_t __c_lui(virt_addr_t& pc, code_word_t instr){ compile_ret_t __c_lui(virt_addr_t& pc, code_word_t instr){
this->do_sync(PRE_SYNC, 59); this->do_sync(PRE_SYNC, 67);
int32_t imm = signextend<int32_t,18>((bit_sub<2,5>(instr) << 12) | (bit_sub<12,1>(instr) << 17)); int32_t imm = signextend<int32_t,18>((bit_sub<2,5>(instr) << 12) | (bit_sub<12,1>(instr) << 17));
uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rd = ((bit_sub<7,5>(instr)));
@ -2293,7 +2633,7 @@ private:
} }
auto Xtmp0_val = (imm); auto Xtmp0_val = (imm);
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val; super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val;
this->do_sync(POST_SYNC, 59); this->do_sync(POST_SYNC, 67);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE); auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
// trap check // trap check
if(trap_state!=0){ if(trap_state!=0){
@ -2305,9 +2645,9 @@ private:
return pc; return pc;
} }
/* instruction 60: C.ADDI16SP */ /* instruction 68: C.ADDI16SP */
compile_ret_t __c_addi16sp(virt_addr_t& pc, code_word_t instr){ compile_ret_t __c_addi16sp(virt_addr_t& pc, code_word_t instr){
this->do_sync(PRE_SYNC, 60); this->do_sync(PRE_SYNC, 68);
int16_t imm = signextend<int16_t,10>((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 7) | (bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 4) | (bit_sub<12,1>(instr) << 9)); int16_t imm = signextend<int16_t,10>((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 7) | (bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 4) | (bit_sub<12,1>(instr) << 9));
if(this->disass_enabled){ if(this->disass_enabled){
@ -2322,7 +2662,7 @@ private:
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 2; super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 2;
auto Xtmp0_val = (static_cast<int32_t>(super::template get_reg<reg_t>(2 + traits<ARCH>::X0)) + (imm)); auto Xtmp0_val = (static_cast<int32_t>(super::template get_reg<reg_t>(2 + traits<ARCH>::X0)) + (imm));
super::template get_reg<reg_t>(2 + traits<ARCH>::X0)=Xtmp0_val; super::template get_reg<reg_t>(2 + traits<ARCH>::X0)=Xtmp0_val;
this->do_sync(POST_SYNC, 60); this->do_sync(POST_SYNC, 68);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE); auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
// trap check // trap check
if(trap_state!=0){ if(trap_state!=0){
@ -2334,9 +2674,9 @@ private:
return pc; return pc;
} }
/* instruction 61: C.SRLI */ /* instruction 69: C.SRLI */
compile_ret_t __c_srli(virt_addr_t& pc, code_word_t instr){ compile_ret_t __c_srli(virt_addr_t& pc, code_word_t instr){
this->do_sync(PRE_SYNC, 61); this->do_sync(PRE_SYNC, 69);
uint8_t shamt = ((bit_sub<2,5>(instr))); uint8_t shamt = ((bit_sub<2,5>(instr)));
uint8_t rs1 = ((bit_sub<7,3>(instr))); uint8_t rs1 = ((bit_sub<7,3>(instr)));
@ -2353,7 +2693,7 @@ private:
uint8_t rs1_idx_val = rs1 + 8; uint8_t rs1_idx_val = rs1 + 8;
auto Xtmp0_val = (static_cast<uint32_t>(super::template get_reg<reg_t>(rs1_idx_val + traits<ARCH>::X0))>>(shamt)); auto Xtmp0_val = (static_cast<uint32_t>(super::template get_reg<reg_t>(rs1_idx_val + traits<ARCH>::X0))>>(shamt));
super::template get_reg<reg_t>(rs1_idx_val + traits<ARCH>::X0)=Xtmp0_val; super::template get_reg<reg_t>(rs1_idx_val + traits<ARCH>::X0)=Xtmp0_val;
this->do_sync(POST_SYNC, 61); this->do_sync(POST_SYNC, 69);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE); auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
// trap check // trap check
if(trap_state!=0){ if(trap_state!=0){
@ -2365,9 +2705,9 @@ private:
return pc; return pc;
} }
/* instruction 62: C.SRAI */ /* instruction 70: C.SRAI */
compile_ret_t __c_srai(virt_addr_t& pc, code_word_t instr){ compile_ret_t __c_srai(virt_addr_t& pc, code_word_t instr){
this->do_sync(PRE_SYNC, 62); this->do_sync(PRE_SYNC, 70);
uint8_t shamt = ((bit_sub<2,5>(instr))); uint8_t shamt = ((bit_sub<2,5>(instr)));
uint8_t rs1 = ((bit_sub<7,3>(instr))); uint8_t rs1 = ((bit_sub<7,3>(instr)));
@ -2384,7 +2724,7 @@ private:
uint8_t rs1_idx_val = rs1 + 8; uint8_t rs1_idx_val = rs1 + 8;
auto Xtmp0_val = (static_cast<int32_t>(super::template get_reg<reg_t>(rs1_idx_val + traits<ARCH>::X0))>>(shamt)); auto Xtmp0_val = (static_cast<int32_t>(super::template get_reg<reg_t>(rs1_idx_val + traits<ARCH>::X0))>>(shamt));
super::template get_reg<reg_t>(rs1_idx_val + traits<ARCH>::X0)=Xtmp0_val; super::template get_reg<reg_t>(rs1_idx_val + traits<ARCH>::X0)=Xtmp0_val;
this->do_sync(POST_SYNC, 62); this->do_sync(POST_SYNC, 70);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE); auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
// trap check // trap check
if(trap_state!=0){ if(trap_state!=0){
@ -2396,9 +2736,9 @@ private:
return pc; return pc;
} }
/* instruction 63: C.ANDI */ /* instruction 71: C.ANDI */
compile_ret_t __c_andi(virt_addr_t& pc, code_word_t instr){ compile_ret_t __c_andi(virt_addr_t& pc, code_word_t instr){
this->do_sync(PRE_SYNC, 63); this->do_sync(PRE_SYNC, 71);
int8_t imm = signextend<int8_t,6>((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); int8_t imm = signextend<int8_t,6>((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5));
uint8_t rs1 = ((bit_sub<7,3>(instr))); uint8_t rs1 = ((bit_sub<7,3>(instr)));
@ -2415,7 +2755,7 @@ private:
uint8_t rs1_idx_val = rs1 + 8; uint8_t rs1_idx_val = rs1 + 8;
auto Xtmp0_val = (static_cast<int32_t>(super::template get_reg<reg_t>(rs1_idx_val + traits<ARCH>::X0)) & (imm)); auto Xtmp0_val = (static_cast<int32_t>(super::template get_reg<reg_t>(rs1_idx_val + traits<ARCH>::X0)) & (imm));
super::template get_reg<reg_t>(rs1_idx_val + traits<ARCH>::X0)=Xtmp0_val; super::template get_reg<reg_t>(rs1_idx_val + traits<ARCH>::X0)=Xtmp0_val;
this->do_sync(POST_SYNC, 63); this->do_sync(POST_SYNC, 71);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE); auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
// trap check // trap check
if(trap_state!=0){ if(trap_state!=0){
@ -2427,9 +2767,9 @@ private:
return pc; return pc;
} }
/* instruction 64: C.SUB */ /* instruction 72: C.SUB */
compile_ret_t __c_sub(virt_addr_t& pc, code_word_t instr){ compile_ret_t __c_sub(virt_addr_t& pc, code_word_t instr){
this->do_sync(PRE_SYNC, 64); this->do_sync(PRE_SYNC, 72);
uint8_t rs2 = ((bit_sub<2,3>(instr))); uint8_t rs2 = ((bit_sub<2,3>(instr)));
uint8_t rd = ((bit_sub<7,3>(instr))); uint8_t rd = ((bit_sub<7,3>(instr)));
@ -2446,7 +2786,7 @@ private:
uint8_t rd_idx_val = rd + 8; uint8_t rd_idx_val = rd + 8;
auto Xtmp0_val = (super::template get_reg<reg_t>(rd_idx_val + traits<ARCH>::X0) - super::template get_reg<reg_t>(rs2 + 8 + traits<ARCH>::X0)); auto Xtmp0_val = (super::template get_reg<reg_t>(rd_idx_val + traits<ARCH>::X0) - super::template get_reg<reg_t>(rs2 + 8 + traits<ARCH>::X0));
super::template get_reg<reg_t>(rd_idx_val + traits<ARCH>::X0)=Xtmp0_val; super::template get_reg<reg_t>(rd_idx_val + traits<ARCH>::X0)=Xtmp0_val;
this->do_sync(POST_SYNC, 64); this->do_sync(POST_SYNC, 72);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE); auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
// trap check // trap check
if(trap_state!=0){ if(trap_state!=0){
@ -2458,9 +2798,9 @@ private:
return pc; return pc;
} }
/* instruction 65: C.XOR */ /* instruction 73: C.XOR */
compile_ret_t __c_xor(virt_addr_t& pc, code_word_t instr){ compile_ret_t __c_xor(virt_addr_t& pc, code_word_t instr){
this->do_sync(PRE_SYNC, 65); this->do_sync(PRE_SYNC, 73);
uint8_t rs2 = ((bit_sub<2,3>(instr))); uint8_t rs2 = ((bit_sub<2,3>(instr)));
uint8_t rd = ((bit_sub<7,3>(instr))); uint8_t rd = ((bit_sub<7,3>(instr)));
@ -2477,7 +2817,7 @@ private:
uint8_t rd_idx_val = rd + 8; uint8_t rd_idx_val = rd + 8;
auto Xtmp0_val = (super::template get_reg<reg_t>(rd_idx_val + traits<ARCH>::X0) ^ super::template get_reg<reg_t>(rs2 + 8 + traits<ARCH>::X0)); auto Xtmp0_val = (super::template get_reg<reg_t>(rd_idx_val + traits<ARCH>::X0) ^ super::template get_reg<reg_t>(rs2 + 8 + traits<ARCH>::X0));
super::template get_reg<reg_t>(rd_idx_val + traits<ARCH>::X0)=Xtmp0_val; super::template get_reg<reg_t>(rd_idx_val + traits<ARCH>::X0)=Xtmp0_val;
this->do_sync(POST_SYNC, 65); this->do_sync(POST_SYNC, 73);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE); auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
// trap check // trap check
if(trap_state!=0){ if(trap_state!=0){
@ -2489,9 +2829,9 @@ private:
return pc; return pc;
} }
/* instruction 66: C.OR */ /* instruction 74: C.OR */
compile_ret_t __c_or(virt_addr_t& pc, code_word_t instr){ compile_ret_t __c_or(virt_addr_t& pc, code_word_t instr){
this->do_sync(PRE_SYNC, 66); this->do_sync(PRE_SYNC, 74);
uint8_t rs2 = ((bit_sub<2,3>(instr))); uint8_t rs2 = ((bit_sub<2,3>(instr)));
uint8_t rd = ((bit_sub<7,3>(instr))); uint8_t rd = ((bit_sub<7,3>(instr)));
@ -2508,7 +2848,7 @@ private:
uint8_t rd_idx_val = rd + 8; uint8_t rd_idx_val = rd + 8;
auto Xtmp0_val = (super::template get_reg<reg_t>(rd_idx_val + traits<ARCH>::X0) | super::template get_reg<reg_t>(rs2 + 8 + traits<ARCH>::X0)); auto Xtmp0_val = (super::template get_reg<reg_t>(rd_idx_val + traits<ARCH>::X0) | super::template get_reg<reg_t>(rs2 + 8 + traits<ARCH>::X0));
super::template get_reg<reg_t>(rd_idx_val + traits<ARCH>::X0)=Xtmp0_val; super::template get_reg<reg_t>(rd_idx_val + traits<ARCH>::X0)=Xtmp0_val;
this->do_sync(POST_SYNC, 66); this->do_sync(POST_SYNC, 74);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE); auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
// trap check // trap check
if(trap_state!=0){ if(trap_state!=0){
@ -2520,9 +2860,9 @@ private:
return pc; return pc;
} }
/* instruction 67: C.AND */ /* instruction 75: C.AND */
compile_ret_t __c_and(virt_addr_t& pc, code_word_t instr){ compile_ret_t __c_and(virt_addr_t& pc, code_word_t instr){
this->do_sync(PRE_SYNC, 67); this->do_sync(PRE_SYNC, 75);
uint8_t rs2 = ((bit_sub<2,3>(instr))); uint8_t rs2 = ((bit_sub<2,3>(instr)));
uint8_t rd = ((bit_sub<7,3>(instr))); uint8_t rd = ((bit_sub<7,3>(instr)));
@ -2539,7 +2879,7 @@ private:
uint8_t rd_idx_val = rd + 8; uint8_t rd_idx_val = rd + 8;
auto Xtmp0_val = (super::template get_reg<reg_t>(rd_idx_val + traits<ARCH>::X0) & super::template get_reg<reg_t>(rs2 + 8 + traits<ARCH>::X0)); auto Xtmp0_val = (super::template get_reg<reg_t>(rd_idx_val + traits<ARCH>::X0) & super::template get_reg<reg_t>(rs2 + 8 + traits<ARCH>::X0));
super::template get_reg<reg_t>(rd_idx_val + traits<ARCH>::X0)=Xtmp0_val; super::template get_reg<reg_t>(rd_idx_val + traits<ARCH>::X0)=Xtmp0_val;
this->do_sync(POST_SYNC, 67); this->do_sync(POST_SYNC, 75);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE); auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
// trap check // trap check
if(trap_state!=0){ if(trap_state!=0){
@ -2551,9 +2891,9 @@ private:
return pc; return pc;
} }
/* instruction 68: C.J */ /* instruction 76: C.J */
compile_ret_t __c_j(virt_addr_t& pc, code_word_t instr){ compile_ret_t __c_j(virt_addr_t& pc, code_word_t instr){
this->do_sync(PRE_SYNC, 68); this->do_sync(PRE_SYNC, 76);
int16_t imm = signextend<int16_t,12>((bit_sub<2,1>(instr) << 5) | (bit_sub<3,3>(instr) << 1) | (bit_sub<6,1>(instr) << 7) | (bit_sub<7,1>(instr) << 6) | (bit_sub<8,1>(instr) << 10) | (bit_sub<9,2>(instr) << 8) | (bit_sub<11,1>(instr) << 4) | (bit_sub<12,1>(instr) << 11)); int16_t imm = signextend<int16_t,12>((bit_sub<2,1>(instr) << 5) | (bit_sub<3,3>(instr) << 1) | (bit_sub<6,1>(instr) << 7) | (bit_sub<7,1>(instr) << 6) | (bit_sub<8,1>(instr) << 10) | (bit_sub<9,2>(instr) << 8) | (bit_sub<11,1>(instr) << 4) | (bit_sub<12,1>(instr) << 11));
if(this->disass_enabled){ if(this->disass_enabled){
@ -2570,7 +2910,7 @@ private:
super::template get_reg(traits<ARCH>::NEXT_PC) = PC_val; super::template get_reg(traits<ARCH>::NEXT_PC) = PC_val;
auto is_cont_v = PC_val !=pc.val; auto is_cont_v = PC_val !=pc.val;
super::template get_reg(traits<ARCH>::LAST_BRANCH) = is_cont_v?1:0; super::template get_reg(traits<ARCH>::LAST_BRANCH) = is_cont_v?1:0;
this->do_sync(POST_SYNC, 68); this->do_sync(POST_SYNC, 76);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE); auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
// trap check // trap check
if(trap_state!=0){ if(trap_state!=0){
@ -2582,9 +2922,9 @@ private:
return pc; return pc;
} }
/* instruction 69: C.BEQZ */ /* instruction 77: C.BEQZ */
compile_ret_t __c_beqz(virt_addr_t& pc, code_word_t instr){ compile_ret_t __c_beqz(virt_addr_t& pc, code_word_t instr){
this->do_sync(PRE_SYNC, 69); this->do_sync(PRE_SYNC, 77);
int16_t imm = signextend<int16_t,9>((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 1) | (bit_sub<5,2>(instr) << 6) | (bit_sub<10,2>(instr) << 3) | (bit_sub<12,1>(instr) << 8)); int16_t imm = signextend<int16_t,9>((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 1) | (bit_sub<5,2>(instr) << 6) | (bit_sub<10,2>(instr) << 3) | (bit_sub<12,1>(instr) << 8));
uint8_t rs1 = ((bit_sub<7,3>(instr))); uint8_t rs1 = ((bit_sub<7,3>(instr)));
@ -2604,7 +2944,7 @@ private:
super::template get_reg(traits<ARCH>::NEXT_PC) = PC_val; super::template get_reg(traits<ARCH>::NEXT_PC) = PC_val;
auto is_cont_v = PC_val !=pc.val; auto is_cont_v = PC_val !=pc.val;
super::template get_reg(traits<ARCH>::LAST_BRANCH) = is_cont_v?1:0; super::template get_reg(traits<ARCH>::LAST_BRANCH) = is_cont_v?1:0;
this->do_sync(POST_SYNC, 69); this->do_sync(POST_SYNC, 77);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE); auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
// trap check // trap check
if(trap_state!=0){ if(trap_state!=0){
@ -2616,9 +2956,9 @@ private:
return pc; return pc;
} }
/* instruction 70: C.BNEZ */ /* instruction 78: C.BNEZ */
compile_ret_t __c_bnez(virt_addr_t& pc, code_word_t instr){ compile_ret_t __c_bnez(virt_addr_t& pc, code_word_t instr){
this->do_sync(PRE_SYNC, 70); this->do_sync(PRE_SYNC, 78);
int16_t imm = signextend<int16_t,9>((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 1) | (bit_sub<5,2>(instr) << 6) | (bit_sub<10,2>(instr) << 3) | (bit_sub<12,1>(instr) << 8)); int16_t imm = signextend<int16_t,9>((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 1) | (bit_sub<5,2>(instr) << 6) | (bit_sub<10,2>(instr) << 3) | (bit_sub<12,1>(instr) << 8));
uint8_t rs1 = ((bit_sub<7,3>(instr))); uint8_t rs1 = ((bit_sub<7,3>(instr)));
@ -2638,7 +2978,7 @@ private:
super::template get_reg(traits<ARCH>::NEXT_PC) = PC_val; super::template get_reg(traits<ARCH>::NEXT_PC) = PC_val;
auto is_cont_v = PC_val !=pc.val; auto is_cont_v = PC_val !=pc.val;
super::template get_reg(traits<ARCH>::LAST_BRANCH) = is_cont_v?1:0; super::template get_reg(traits<ARCH>::LAST_BRANCH) = is_cont_v?1:0;
this->do_sync(POST_SYNC, 70); this->do_sync(POST_SYNC, 78);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE); auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
// trap check // trap check
if(trap_state!=0){ if(trap_state!=0){
@ -2650,9 +2990,9 @@ private:
return pc; return pc;
} }
/* instruction 71: C.SLLI */ /* instruction 79: C.SLLI */
compile_ret_t __c_slli(virt_addr_t& pc, code_word_t instr){ compile_ret_t __c_slli(virt_addr_t& pc, code_word_t instr){
this->do_sync(PRE_SYNC, 71); this->do_sync(PRE_SYNC, 79);
uint8_t shamt = ((bit_sub<2,5>(instr))); uint8_t shamt = ((bit_sub<2,5>(instr)));
uint8_t rs1 = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<7,5>(instr)));
@ -2671,7 +3011,7 @@ private:
} }
auto Xtmp0_val = (super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)<<(shamt)); auto Xtmp0_val = (super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)<<(shamt));
super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)=Xtmp0_val; super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0)=Xtmp0_val;
this->do_sync(POST_SYNC, 71); this->do_sync(POST_SYNC, 79);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE); auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
// trap check // trap check
if(trap_state!=0){ if(trap_state!=0){
@ -2683,9 +3023,9 @@ private:
return pc; return pc;
} }
/* instruction 72: C.LWSP */ /* instruction 80: C.LWSP */
compile_ret_t __c_lwsp(virt_addr_t& pc, code_word_t instr){ compile_ret_t __c_lwsp(virt_addr_t& pc, code_word_t instr){
this->do_sync(PRE_SYNC, 72); this->do_sync(PRE_SYNC, 80);
uint8_t uimm = ((bit_sub<2,2>(instr) << 6) | (bit_sub<4,3>(instr) << 2) | (bit_sub<12,1>(instr) << 5)); uint8_t uimm = ((bit_sub<2,2>(instr) << 6) | (bit_sub<4,3>(instr) << 2) | (bit_sub<12,1>(instr) << 5));
uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rd = ((bit_sub<7,5>(instr)));
@ -2702,7 +3042,7 @@ private:
auto offs_val = (super::template get_reg<reg_t>(2 + traits<ARCH>::X0) + (uimm)); auto offs_val = (super::template get_reg<reg_t>(2 + traits<ARCH>::X0) + (uimm));
auto Xtmp0_val = super::template sext<int32_t>(super::template read_mem<uint32_t>(traits<ARCH>::MEM, offs_val)); auto Xtmp0_val = super::template sext<int32_t>(super::template read_mem<uint32_t>(traits<ARCH>::MEM, offs_val));
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val; super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val;
this->do_sync(POST_SYNC, 72); this->do_sync(POST_SYNC, 80);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE); auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
// trap check // trap check
if(trap_state!=0){ if(trap_state!=0){
@ -2714,9 +3054,9 @@ private:
return pc; return pc;
} }
/* instruction 73: C.MV */ /* instruction 81: C.MV */
compile_ret_t __c_mv(virt_addr_t& pc, code_word_t instr){ compile_ret_t __c_mv(virt_addr_t& pc, code_word_t instr){
this->do_sync(PRE_SYNC, 73); this->do_sync(PRE_SYNC, 81);
uint8_t rs2 = ((bit_sub<2,5>(instr))); uint8_t rs2 = ((bit_sub<2,5>(instr)));
uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rd = ((bit_sub<7,5>(instr)));
@ -2732,7 +3072,7 @@ private:
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 2; super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 2;
auto Xtmp0_val = super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0); auto Xtmp0_val = super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0);
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val; super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val;
this->do_sync(POST_SYNC, 73); this->do_sync(POST_SYNC, 81);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE); auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
// trap check // trap check
if(trap_state!=0){ if(trap_state!=0){
@ -2744,9 +3084,9 @@ private:
return pc; return pc;
} }
/* instruction 74: C.JR */ /* instruction 82: C.JR */
compile_ret_t __c_jr(virt_addr_t& pc, code_word_t instr){ compile_ret_t __c_jr(virt_addr_t& pc, code_word_t instr){
this->do_sync(PRE_SYNC, 74); this->do_sync(PRE_SYNC, 82);
uint8_t rs1 = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<7,5>(instr)));
if(this->disass_enabled){ if(this->disass_enabled){
@ -2762,7 +3102,7 @@ private:
auto PC_val = super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0); auto PC_val = super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0);
super::template get_reg(traits<ARCH>::NEXT_PC) = PC_val; super::template get_reg(traits<ARCH>::NEXT_PC) = PC_val;
super::template get_reg(traits<ARCH>::LAST_BRANCH) = std::numeric_limits<uint32_t>::max(); super::template get_reg(traits<ARCH>::LAST_BRANCH) = std::numeric_limits<uint32_t>::max();
this->do_sync(POST_SYNC, 74); this->do_sync(POST_SYNC, 82);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE); auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
// trap check // trap check
if(trap_state!=0){ if(trap_state!=0){
@ -2774,9 +3114,9 @@ private:
return pc; return pc;
} }
/* instruction 75: C.ADD */ /* instruction 83: C.ADD */
compile_ret_t __c_add(virt_addr_t& pc, code_word_t instr){ compile_ret_t __c_add(virt_addr_t& pc, code_word_t instr){
this->do_sync(PRE_SYNC, 75); this->do_sync(PRE_SYNC, 83);
uint8_t rs2 = ((bit_sub<2,5>(instr))); uint8_t rs2 = ((bit_sub<2,5>(instr)));
uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rd = ((bit_sub<7,5>(instr)));
@ -2792,7 +3132,7 @@ private:
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 2; super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 2;
auto Xtmp0_val = (super::template get_reg<reg_t>(rd + traits<ARCH>::X0) + super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0)); auto Xtmp0_val = (super::template get_reg<reg_t>(rd + traits<ARCH>::X0) + super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0));
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val; super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val;
this->do_sync(POST_SYNC, 75); this->do_sync(POST_SYNC, 83);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE); auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
// trap check // trap check
if(trap_state!=0){ if(trap_state!=0){
@ -2804,9 +3144,9 @@ private:
return pc; return pc;
} }
/* instruction 76: C.JALR */ /* instruction 84: C.JALR */
compile_ret_t __c_jalr(virt_addr_t& pc, code_word_t instr){ compile_ret_t __c_jalr(virt_addr_t& pc, code_word_t instr){
this->do_sync(PRE_SYNC, 76); this->do_sync(PRE_SYNC, 84);
uint8_t rs1 = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<7,5>(instr)));
if(this->disass_enabled){ if(this->disass_enabled){
@ -2824,7 +3164,7 @@ private:
auto PC_val = super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0); auto PC_val = super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0);
super::template get_reg(traits<ARCH>::NEXT_PC) = PC_val; super::template get_reg(traits<ARCH>::NEXT_PC) = PC_val;
super::template get_reg(traits<ARCH>::LAST_BRANCH) = std::numeric_limits<uint32_t>::max(); super::template get_reg(traits<ARCH>::LAST_BRANCH) = std::numeric_limits<uint32_t>::max();
this->do_sync(POST_SYNC, 76); this->do_sync(POST_SYNC, 84);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE); auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
// trap check // trap check
if(trap_state!=0){ if(trap_state!=0){
@ -2836,9 +3176,9 @@ private:
return pc; return pc;
} }
/* instruction 77: C.EBREAK */ /* instruction 85: C.EBREAK */
compile_ret_t __c_ebreak(virt_addr_t& pc, code_word_t instr){ compile_ret_t __c_ebreak(virt_addr_t& pc, code_word_t instr){
this->do_sync(PRE_SYNC, 77); this->do_sync(PRE_SYNC, 85);
if(this->disass_enabled){ if(this->disass_enabled){
/* generate console output when executing the command */ /* generate console output when executing the command */
@ -2848,7 +3188,7 @@ private:
auto cur_pc_val = pc.val; auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 2; super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 2;
raise_trap(0, 3); raise_trap(0, 3);
this->do_sync(POST_SYNC, 77); this->do_sync(POST_SYNC, 85);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE); auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
// trap check // trap check
if(trap_state!=0){ if(trap_state!=0){
@ -2860,9 +3200,9 @@ private:
return pc; return pc;
} }
/* instruction 78: C.SWSP */ /* instruction 86: C.SWSP */
compile_ret_t __c_swsp(virt_addr_t& pc, code_word_t instr){ compile_ret_t __c_swsp(virt_addr_t& pc, code_word_t instr){
this->do_sync(PRE_SYNC, 78); this->do_sync(PRE_SYNC, 86);
uint8_t rs2 = ((bit_sub<2,5>(instr))); uint8_t rs2 = ((bit_sub<2,5>(instr)));
uint8_t uimm = ((bit_sub<7,2>(instr) << 6) | (bit_sub<9,4>(instr) << 2)); uint8_t uimm = ((bit_sub<7,2>(instr) << 6) | (bit_sub<9,4>(instr) << 2));
@ -2879,7 +3219,7 @@ private:
auto offs_val = (super::template get_reg<reg_t>(2 + traits<ARCH>::X0) + (uimm)); auto offs_val = (super::template get_reg<reg_t>(2 + traits<ARCH>::X0) + (uimm));
auto MEMtmp0_val = super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0); auto MEMtmp0_val = super::template get_reg<reg_t>(rs2 + traits<ARCH>::X0);
super::write_mem(traits<ARCH>::MEM, offs_val, static_cast<uint32_t>(MEMtmp0_val)); super::write_mem(traits<ARCH>::MEM, offs_val, static_cast<uint32_t>(MEMtmp0_val));
this->do_sync(POST_SYNC, 78); this->do_sync(POST_SYNC, 86);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE); auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
// trap check // trap check
if(trap_state!=0){ if(trap_state!=0){
@ -2891,9 +3231,9 @@ private:
return pc; return pc;
} }
/* instruction 79: DII */ /* instruction 87: DII */
compile_ret_t __dii(virt_addr_t& pc, code_word_t instr){ compile_ret_t __dii(virt_addr_t& pc, code_word_t instr){
this->do_sync(PRE_SYNC, 79); this->do_sync(PRE_SYNC, 87);
if(this->disass_enabled){ if(this->disass_enabled){
/* generate console output when executing the command */ /* generate console output when executing the command */
@ -2903,7 +3243,7 @@ private:
auto cur_pc_val = pc.val; auto cur_pc_val = pc.val;
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 2; super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 2;
raise_trap(0, 2); raise_trap(0, 2);
this->do_sync(POST_SYNC, 79); this->do_sync(POST_SYNC, 87);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE); auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
// trap check // trap check
if(trap_state!=0){ if(trap_state!=0){
@ -2974,8 +3314,8 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(virt_addr_t star
} // namespace mnrv32 } // namespace mnrv32
template <> template <>
std::unique_ptr<vm_if> create<arch::mnrv32>(arch::mnrv32 *core, unsigned short port, bool dump) { std::unique_ptr<vm_if> create<arch::tgf02>(arch::tgf02 *core, unsigned short port, bool dump) {
auto ret = new mnrv32::vm_impl<arch::mnrv32>(*core, dump); auto ret = new tgf02::vm_impl<arch::tgf02>(*core, dump);
if (port != 0) debugger::server<debugger::gdb_session>::run_server(ret, port); if (port != 0) debugger::server<debugger::gdb_session>::run_server(ret, port);
return std::unique_ptr<vm_if>(ret); return std::unique_ptr<vm_if>(ret);
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -31,7 +31,7 @@
*******************************************************************************/ *******************************************************************************/
#include <iss/arch/tgf01.h> #include <iss/arch/tgf01.h>
#include <iss/arch/riscv_hart_msu_vp.h> #include <iss/arch/riscv_hart_m_p.h>
#include <iss/debugger/gdb_session.h> #include <iss/debugger/gdb_session.h>
#include <iss/debugger/server.h> #include <iss/debugger/server.h>
#include <iss/iss.h> #include <iss/iss.h>

View File

@ -31,7 +31,7 @@
*******************************************************************************/ *******************************************************************************/
#include <iss/arch/tgf02.h> #include <iss/arch/tgf02.h>
#include <iss/arch/riscv_hart_msu_vp.h> #include <iss/arch/riscv_hart_m_p.h>
#include <iss/debugger/gdb_session.h> #include <iss/debugger/gdb_session.h>
#include <iss/debugger/server.h> #include <iss/debugger/server.h>
#include <iss/iss.h> #include <iss/iss.h>