Generate and integrate TGF cores in Ecosystem-VP. Remove obsolete cores
This commit is contained in:
parent
03172e352d
commit
9754e3953f
@ -30,33 +30,21 @@ add_subdirectory(softfloat)
|
||||
FILE(GLOB RiscVSCHeaders ${CMAKE_CURRENT_SOURCE_DIR}/incl/sysc/*.h ${CMAKE_CURRENT_SOURCE_DIR}/incl/sysc/*/*.h)
|
||||
set(LIB_HEADERS ${RiscVSCHeaders} )
|
||||
set(LIB_SOURCES
|
||||
src/iss/rv32gc.cpp
|
||||
src/iss/rv32imac.cpp
|
||||
src/iss/rv64i.cpp
|
||||
src/iss/rv64gc.cpp
|
||||
src/iss/mnrv32.cpp
|
||||
src/iss/tgf01.cpp
|
||||
src/iss/tgf02.cpp
|
||||
src/vm/fp_functions.cpp
|
||||
src/vm/tcc/vm_mnrv32.cpp
|
||||
src/vm/tcc/vm_rv32gc.cpp
|
||||
src/vm/tcc/vm_rv32imac.cpp
|
||||
src/vm/tcc/vm_rv64i.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/vm/tcc/vm_tgf01.cpp
|
||||
src/vm/tcc/vm_tgf02.cpp
|
||||
src/vm/interp/vm_tgf01.cpp
|
||||
src/vm/interp/vm_tgf02.cpp
|
||||
src/plugin/instruction_count.cpp
|
||||
src/plugin/cycle_estimate.cpp
|
||||
)
|
||||
if(WITH_LLVM)
|
||||
set(LIB_SOURCES ${LIB_SOURCES}
|
||||
src/vm/llvm/fp_impl.cpp
|
||||
src/vm/llvm/vm_mnrv32.cpp
|
||||
src/vm/llvm/vm_rv32gc.cpp
|
||||
src/vm/llvm/vm_rv32imac.cpp
|
||||
src/vm/llvm/vm_rv64i.cpp
|
||||
src/vm/llvm/vm_rv64gc.cpp
|
||||
src/vm/llvm/vm_tgf01.cpp
|
||||
src/vm/llvm/vm_tgf02.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
|
@ -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}")
|
@ -1,6 +1,6 @@
|
||||
import "RV32I.core_desc"
|
||||
import "RVM.core_desc"
|
||||
import "RVC.core_desc"
|
||||
import "CoreDSL-Instruction-Set-Description/RV32I.core_desc"
|
||||
import "CoreDSL-Instruction-Set-Description/RVM.core_desc"
|
||||
import "CoreDSL-Instruction-Set-Description/RVC.core_desc"
|
||||
|
||||
Core TGF01 provides RV32I {
|
||||
constants {
|
||||
@ -9,6 +9,8 @@ Core TGF01 provides RV32I {
|
||||
// definitions for the architecture wrapper
|
||||
// XL ZYXWVUTSRQPONMLKJIHGFEDCBA
|
||||
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
|
||||
// XL ZYXWVUTSRQPONMLKJIHGFEDCBA
|
||||
MISA_VAL:=0b01000000000000000001000100000100;
|
||||
PGSIZE := 0x1000; //1 << 12;
|
||||
PGMASK := 0xfff; //PGSIZE-1
|
||||
}
|
||||
}
|
@ -32,7 +32,7 @@
|
||||
|
||||
#include "../fp_functions.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/server.h>
|
||||
#include <iss/iss.h>
|
||||
|
@ -31,7 +31,7 @@
|
||||
*******************************************************************************/
|
||||
|
||||
#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/server.h>
|
||||
#include <iss/iss.h>
|
||||
|
@ -31,7 +31,7 @@
|
||||
*******************************************************************************/
|
||||
|
||||
#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/server.h>
|
||||
#include <iss/iss.h>
|
||||
|
@ -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_ */
|
@ -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:
|
||||
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 phys_addr_t = typename super::phys_addr_t;
|
||||
using reg_t = typename super::reg_t;
|
||||
@ -360,97 +360,6 @@ public:
|
||||
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 PGMASK = PGSIZE - 1;
|
||||
|
||||
@ -464,8 +373,8 @@ public:
|
||||
return m[mode];
|
||||
}
|
||||
|
||||
riscv_hart_msu_vp();
|
||||
virtual ~riscv_hart_msu_vp() = default;
|
||||
riscv_hart_m_p();
|
||||
virtual ~riscv_hart_m_p() = default;
|
||||
|
||||
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,
|
||||
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 leave_trap(uint64_t flags) override;
|
||||
void wait_until(uint64_t flags) override;
|
||||
@ -493,7 +402,7 @@ public:
|
||||
protected:
|
||||
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) {}
|
||||
/**
|
||||
* get the name of this architecture
|
||||
@ -508,7 +417,7 @@ protected:
|
||||
|
||||
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;
|
||||
@ -561,7 +470,7 @@ protected:
|
||||
};
|
||||
|
||||
template <typename BASE>
|
||||
riscv_hart_msu_vp<BASE>::riscv_hart_msu_vp()
|
||||
riscv_hart_m_p<BASE>::riscv_hart_m_p()
|
||||
: state()
|
||||
, cycle_offset(0)
|
||||
, 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 = mcycleh; addr <= hpmcounter31h; ++addr) csr_wr_cb[addr] = nullptr;
|
||||
// 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_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_rd_cb[mcycle] = &riscv_hart_msu_vp<BASE>::read_cycle;
|
||||
csr_rd_cb[mcycleh] = &riscv_hart_msu_vp<BASE>::read_cycle;
|
||||
csr_rd_cb[minstret] = &riscv_hart_msu_vp<BASE>::read_cycle;
|
||||
csr_rd_cb[minstreth] = &riscv_hart_msu_vp<BASE>::read_cycle;
|
||||
csr_rd_cb[mstatus] = &riscv_hart_msu_vp<BASE>::read_status;
|
||||
csr_wr_cb[mstatus] = &riscv_hart_msu_vp<BASE>::write_status;
|
||||
csr_rd_cb[sstatus] = &riscv_hart_msu_vp<BASE>::read_status;
|
||||
csr_wr_cb[sstatus] = &riscv_hart_msu_vp<BASE>::write_status;
|
||||
csr_rd_cb[ustatus] = &riscv_hart_msu_vp<BASE>::read_status;
|
||||
csr_wr_cb[ustatus] = &riscv_hart_msu_vp<BASE>::write_status;
|
||||
csr_rd_cb[mip] = &riscv_hart_msu_vp<BASE>::read_ip;
|
||||
csr_wr_cb[mip] = &riscv_hart_msu_vp<BASE>::write_ip;
|
||||
csr_rd_cb[sip] = &riscv_hart_msu_vp<BASE>::read_ip;
|
||||
csr_wr_cb[sip] = &riscv_hart_msu_vp<BASE>::write_ip;
|
||||
csr_rd_cb[uip] = &riscv_hart_msu_vp<BASE>::read_ip;
|
||||
csr_wr_cb[uip] = &riscv_hart_msu_vp<BASE>::write_ip;
|
||||
csr_rd_cb[mie] = &riscv_hart_msu_vp<BASE>::read_ie;
|
||||
csr_wr_cb[mie] = &riscv_hart_msu_vp<BASE>::write_ie;
|
||||
csr_rd_cb[sie] = &riscv_hart_msu_vp<BASE>::read_ie;
|
||||
csr_wr_cb[sie] = &riscv_hart_msu_vp<BASE>::write_ie;
|
||||
csr_rd_cb[uie] = &riscv_hart_msu_vp<BASE>::read_ie;
|
||||
csr_wr_cb[uie] = &riscv_hart_msu_vp<BASE>::write_ie;
|
||||
csr_rd_cb[satp] = &riscv_hart_msu_vp<BASE>::read_satp;
|
||||
csr_wr_cb[satp] = &riscv_hart_msu_vp<BASE>::write_satp;
|
||||
csr_rd_cb[fcsr] = &riscv_hart_msu_vp<BASE>::read_fcsr;
|
||||
csr_wr_cb[fcsr] = &riscv_hart_msu_vp<BASE>::write_fcsr;
|
||||
csr_rd_cb[fflags] = &riscv_hart_msu_vp<BASE>::read_fcsr;
|
||||
csr_wr_cb[fflags] = &riscv_hart_msu_vp<BASE>::write_fcsr;
|
||||
csr_rd_cb[frm] = &riscv_hart_msu_vp<BASE>::read_fcsr;
|
||||
csr_wr_cb[frm] = &riscv_hart_msu_vp<BASE>::write_fcsr;
|
||||
csr_rd_cb[mcycle] = &riscv_hart_m_p<BASE>::read_cycle;
|
||||
csr_rd_cb[mcycleh] = &riscv_hart_m_p<BASE>::read_cycle;
|
||||
csr_rd_cb[minstret] = &riscv_hart_m_p<BASE>::read_cycle;
|
||||
csr_rd_cb[minstreth] = &riscv_hart_m_p<BASE>::read_cycle;
|
||||
csr_rd_cb[mstatus] = &riscv_hart_m_p<BASE>::read_status;
|
||||
csr_wr_cb[mstatus] = &riscv_hart_m_p<BASE>::write_status;
|
||||
csr_rd_cb[sstatus] = &riscv_hart_m_p<BASE>::read_status;
|
||||
csr_wr_cb[sstatus] = &riscv_hart_m_p<BASE>::write_status;
|
||||
csr_rd_cb[ustatus] = &riscv_hart_m_p<BASE>::read_status;
|
||||
csr_wr_cb[ustatus] = &riscv_hart_m_p<BASE>::write_status;
|
||||
csr_rd_cb[mip] = &riscv_hart_m_p<BASE>::read_ip;
|
||||
csr_wr_cb[mip] = &riscv_hart_m_p<BASE>::write_ip;
|
||||
csr_rd_cb[sip] = &riscv_hart_m_p<BASE>::read_ip;
|
||||
csr_wr_cb[sip] = &riscv_hart_m_p<BASE>::write_ip;
|
||||
csr_rd_cb[uip] = &riscv_hart_m_p<BASE>::read_ip;
|
||||
csr_wr_cb[uip] = &riscv_hart_m_p<BASE>::write_ip;
|
||||
csr_rd_cb[mie] = &riscv_hart_m_p<BASE>::read_ie;
|
||||
csr_wr_cb[mie] = &riscv_hart_m_p<BASE>::write_ie;
|
||||
csr_rd_cb[sie] = &riscv_hart_m_p<BASE>::read_ie;
|
||||
csr_wr_cb[sie] = &riscv_hart_m_p<BASE>::write_ie;
|
||||
csr_rd_cb[uie] = &riscv_hart_m_p<BASE>::read_ie;
|
||||
csr_wr_cb[uie] = &riscv_hart_m_p<BASE>::write_ie;
|
||||
csr_rd_cb[satp] = &riscv_hart_m_p<BASE>::read_satp;
|
||||
csr_wr_cb[satp] = &riscv_hart_m_p<BASE>::write_satp;
|
||||
csr_rd_cb[fcsr] = &riscv_hart_m_p<BASE>::read_fcsr;
|
||||
csr_wr_cb[fcsr] = &riscv_hart_m_p<BASE>::write_fcsr;
|
||||
csr_rd_cb[fflags] = &riscv_hart_m_p<BASE>::read_fcsr;
|
||||
csr_wr_cb[fflags] = &riscv_hart_m_p<BASE>::write_fcsr;
|
||||
csr_rd_cb[frm] = &riscv_hart_m_p<BASE>::read_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");
|
||||
if (fp) {
|
||||
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>
|
||||
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) {
|
||||
#ifndef NDEBUG
|
||||
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>
|
||||
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) {
|
||||
#ifndef NDEBUG
|
||||
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;
|
||||
auto req_priv_lvl = (addr >> 8) & 0x3;
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
auto req_priv_lvl = (addr >> 8) & 0x3;
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
if (addr == mcycle) {
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
if (addr == time) {
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
val = state.mstatus & hart_state<reg_t>::get_mask(req_priv_lvl);
|
||||
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;
|
||||
state.write_mstatus(val, req_priv_lvl);
|
||||
check_interrupt();
|
||||
@ -922,14 +831,14 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_status(unsig
|
||||
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];
|
||||
if (addr < mie) val &= csr[mideleg];
|
||||
if (addr < sie) val &= csr[sideleg];
|
||||
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 mask = get_irq_mask(req_priv_lvl);
|
||||
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;
|
||||
}
|
||||
|
||||
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];
|
||||
if (addr < mip) val &= csr[mideleg];
|
||||
if (addr < sip) val &= csr[sideleg];
|
||||
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 mask = get_irq_mask(req_priv_lvl);
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
if (this->reg.machine_state == PRIV_S & tvm != 0) {
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
if (this->reg.machine_state == PRIV_S & tvm != 0) {
|
||||
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();
|
||||
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) {
|
||||
case 1: // fflags, 4:0
|
||||
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;
|
||||
}
|
||||
|
||||
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) {
|
||||
case 1: // fflags, 4:0
|
||||
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>
|
||||
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;
|
||||
switch (paddr.val) {
|
||||
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>
|
||||
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;
|
||||
switch (paddr.val) {
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
state.mstatus = hart_state<reg_t>::mstatus_reset_val;
|
||||
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);
|
||||
BASE::addr_mode[3]=BASE::addr_mode[2] = vm[1].is_active()? iss::address_type::VIRTUAL : iss::address_type::PHYSICAL;
|
||||
if (state.mstatus.MPRV)
|
||||
@ -1129,7 +1038,7 @@ template <typename BASE> inline void riscv_hart_msu_vp<BASE>::update_vm_info() {
|
||||
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 ip = csr[mip];
|
||||
auto ie = csr[mie];
|
||||
@ -1157,7 +1066,7 @@ template <typename BASE> void riscv_hart_msu_vp<BASE>::check_interrupt() {
|
||||
}
|
||||
|
||||
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;
|
||||
auto it = ptw.find(addr.val >> PGSHIFT);
|
||||
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;
|
||||
// flags are ACTIVE[31:31], CAUSE[30:16], TRAPID[15:0]
|
||||
// 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;
|
||||
}
|
||||
|
||||
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 inst_priv = flags & 0x3;
|
||||
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;
|
||||
}
|
||||
|
||||
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 tw = status.TW;
|
||||
if (this->reg.machine_state == PRIV_S && tw != 0) {
|
@ -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_ */
|
@ -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_ */
|
@ -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_ */
|
@ -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_ */
|
@ -54,7 +54,7 @@ template <> struct traits<tgf01> {
|
||||
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=0b1000000000000000000000100000000};
|
||||
enum constants {XLEN=32, PCLEN=32, MISA_VAL=0b1000000000000000000000100000000, PGSIZE=0x1000, PGMASK=0xfff};
|
||||
|
||||
constexpr static unsigned FP_REGS_SIZE = 0;
|
||||
|
||||
|
@ -54,7 +54,7 @@ template <> struct traits<tgf02> {
|
||||
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=0b1000000000000000001000100000100};
|
||||
enum constants {XLEN=32, PCLEN=32, MUL_LEN=64, MISA_VAL=0b1000000000000000001000100000100, PGSIZE=0x1000, PGMASK=0xfff};
|
||||
|
||||
constexpr static unsigned FP_REGS_SIZE = 0;
|
||||
|
||||
|
@ -51,7 +51,7 @@ template <class T_begin, class T_end> class scv_tr_generator;
|
||||
namespace iss {
|
||||
class vm_if;
|
||||
namespace arch {
|
||||
template <typename BASE> class riscv_hart_msu_vp;
|
||||
template <typename BASE> class riscv_hart_m_p;
|
||||
}
|
||||
namespace debugger {
|
||||
class target_adapter_if;
|
||||
|
@ -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*>(®);
|
||||
}
|
||||
|
||||
mnrv32::phys_addr_t mnrv32::virt2phys(const iss::addr_t &pc) {
|
||||
return phys_addr_t(pc); // change logical address to physical address
|
||||
}
|
||||
|
@ -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*>(®);
|
||||
}
|
||||
|
||||
rv32gc::phys_addr_t rv32gc::virt2phys(const iss::addr_t &pc) {
|
||||
return phys_addr_t(pc); // change logical address to physical address
|
||||
}
|
||||
|
@ -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 *>(®); }
|
||||
|
||||
rv32imac::phys_addr_t rv32imac::virt2phys(const iss::addr_t &pc) {
|
||||
return phys_addr_t(pc); // change logical address to physical address
|
||||
}
|
@ -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*>(®);
|
||||
}
|
||||
|
||||
rv64gc::phys_addr_t rv64gc::virt2phys(const iss::addr_t &pc) {
|
||||
return phys_addr_t(pc); // change logical address to physical address
|
||||
}
|
||||
|
@ -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*>(®);
|
||||
}
|
||||
|
||||
rv64i::phys_addr_t rv64i::virt2phys(const iss::addr_t &pc) {
|
||||
return phys_addr_t(pc); // change logical address to physical address
|
||||
}
|
||||
|
27
src/main.cpp
27
src/main.cpp
@ -35,12 +35,9 @@
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/program_options.hpp>
|
||||
#include <iss/arch/riscv_hart_msu_vp.h>
|
||||
#include <iss/arch/rv32imac.h>
|
||||
#include <iss/arch/rv32gc.h>
|
||||
#include <iss/arch/rv64gc.h>
|
||||
#include <iss/arch/rv64i.h>
|
||||
#include <iss/arch/mnrv32.h>
|
||||
#include <iss/arch/riscv_hart_m_p.h>
|
||||
#include <iss/arch/tgf01.h>
|
||||
#include <iss/arch/tgf02.h>
|
||||
#ifdef WITH_LLVM
|
||||
#include <iss/llvm/jit_helper.h>
|
||||
#endif
|
||||
@ -55,7 +52,7 @@ using vm_ptr= std::unique_ptr<iss::vm_if>;
|
||||
|
||||
template<typename CORE>
|
||||
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")
|
||||
return {cpu_ptr{lcpu}, vm_ptr{iss::interp::create(lcpu, gdb_port)}};
|
||||
#ifdef WITH_LLVM
|
||||
@ -132,16 +129,10 @@ int main(int argc, char *argv[]) {
|
||||
vm_ptr vm{nullptr};
|
||||
cpu_ptr cpu{nullptr};
|
||||
std::string isa_opt(clim["isa"].as<std::string>());
|
||||
if (isa_opt=="mnrv32") {
|
||||
std::tie(cpu, vm) = create_cpu<iss::arch::mnrv32>(clim["backend"].as<std::string>(), clim["gdb-port"].as<unsigned>());
|
||||
} else if (isa_opt=="rv64i") {
|
||||
std::tie(cpu, vm) = create_cpu<iss::arch::rv64i>(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>());
|
||||
if (isa_opt=="tgf01") {
|
||||
std::tie(cpu, vm) = create_cpu<iss::arch::tgf01>(clim["backend"].as<std::string>(), clim["gdb-port"].as<unsigned>());
|
||||
} else if (isa_opt=="tgf02") {
|
||||
std::tie(cpu, vm) = create_cpu<iss::arch::tgf02>(clim["backend"].as<std::string>(), clim["gdb-port"].as<unsigned>());
|
||||
} else {
|
||||
LOG(ERROR) << "Illegal argument value for '--isa': " << clim["isa"].as<std::string>() << std::endl;
|
||||
return 127;
|
||||
@ -181,7 +172,7 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
uint64_t start_address = 0;
|
||||
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"))
|
||||
for (std::string input : clim["elf"].as<std::vector<std::string>>()) {
|
||||
auto start_addr = vm->get_arch()->load_file(input);
|
||||
|
@ -31,9 +31,8 @@
|
||||
*******************************************************************************/
|
||||
|
||||
#include "sysc/core_complex.h"
|
||||
#include "iss/arch/riscv_hart_msu_vp.h"
|
||||
//#include "iss/arch/rv32imac.h"
|
||||
#include "iss/arch/mnrv32.h"
|
||||
#include "iss/arch/riscv_hart_m_p.h"
|
||||
#include "iss/arch/tgf01.h"
|
||||
#include "iss/debugger/encoderdecoder.h"
|
||||
#include "iss/debugger/gdb_session.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::mnrv32;
|
||||
using core_type = iss::arch::tgf01;
|
||||
|
||||
namespace {
|
||||
|
||||
@ -91,9 +90,9 @@ std::array<const char*, 12> irq_str = { {
|
||||
"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:
|
||||
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;
|
||||
core_wrapper(core_complex *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() {
|
||||
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);
|
||||
vm = create_cpu(cpu.get(), backend.get_value(), gdb_server_port.get_value());
|
||||
#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
@ -31,8 +31,8 @@
|
||||
*******************************************************************************/
|
||||
|
||||
#include "../fp_functions.h"
|
||||
#include <iss/arch/rv64i.h>
|
||||
#include <iss/arch/riscv_hart_msu_vp.h>
|
||||
#include <iss/arch/tgf01.h>
|
||||
#include <iss/arch/riscv_hart_m_p.h>
|
||||
#include <iss/debugger/gdb_session.h>
|
||||
#include <iss/debugger/server.h>
|
||||
#include <iss/iss.h>
|
||||
@ -50,7 +50,7 @@
|
||||
|
||||
namespace iss {
|
||||
namespace interp {
|
||||
namespace rv64i {
|
||||
namespace tgf01 {
|
||||
using namespace iss::arch;
|
||||
using namespace iss::debugger;
|
||||
|
||||
@ -167,7 +167,7 @@ private:
|
||||
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 */
|
||||
/* instruction LUI */
|
||||
{32, 0b00000000000000000000000000110111, 0b00000000000000000000000001111111, &this_class::__lui},
|
||||
@ -218,11 +218,11 @@ private:
|
||||
/* instruction ANDI */
|
||||
{32, 0b00000000000000000111000000010011, 0b00000000000000000111000001111111, &this_class::__andi},
|
||||
/* instruction SLLI */
|
||||
{32, 0b00000000000000000001000000010011, 0b11111100000000000111000001111111, &this_class::__slli},
|
||||
{32, 0b00000000000000000001000000010011, 0b11111110000000000111000001111111, &this_class::__slli},
|
||||
/* instruction SRLI */
|
||||
{32, 0b00000000000000000101000000010011, 0b11111100000000000111000001111111, &this_class::__srli},
|
||||
{32, 0b00000000000000000101000000010011, 0b11111110000000000111000001111111, &this_class::__srli},
|
||||
/* instruction SRAI */
|
||||
{32, 0b01000000000000000101000000010011, 0b11111100000000000111000001111111, &this_class::__srai},
|
||||
{32, 0b01000000000000000101000000010011, 0b11111110000000000111000001111111, &this_class::__srai},
|
||||
/* instruction ADD */
|
||||
{32, 0b00000000000000000000000000110011, 0b11111110000000000111000001111111, &this_class::__add},
|
||||
/* instruction SUB */
|
||||
@ -273,30 +273,6 @@ private:
|
||||
{32, 0b00000000000000000110000001110011, 0b00000000000000000111000001111111, &this_class::__csrrsi},
|
||||
/* instruction 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 */
|
||||
@ -349,7 +325,7 @@ private:
|
||||
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 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;
|
||||
}
|
||||
this->do_sync(POST_SYNC, 1);
|
||||
@ -384,7 +360,7 @@ private:
|
||||
auto Xtmp0_val = (cur_pc_val + 4);
|
||||
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;
|
||||
auto is_cont_v = PC_val !=pc.val;
|
||||
super::template get_reg(traits<ARCH>::LAST_BRANCH) = is_cont_v?1:0;
|
||||
@ -417,7 +393,7 @@ private:
|
||||
|
||||
auto cur_pc_val = pc.val;
|
||||
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);
|
||||
{
|
||||
if((align_val != 0)) {
|
||||
@ -463,7 +439,7 @@ private:
|
||||
auto cur_pc_val = pc.val;
|
||||
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))?
|
||||
(static_cast<int64_t>(cur_pc_val) + (imm)):
|
||||
(static_cast<int32_t>(cur_pc_val) + (imm)):
|
||||
(cur_pc_val + 4);
|
||||
super::template get_reg(traits<ARCH>::NEXT_PC) = PC_val;
|
||||
auto is_cont_v = PC_val !=pc.val;
|
||||
@ -498,7 +474,7 @@ private:
|
||||
auto cur_pc_val = pc.val;
|
||||
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))?
|
||||
(static_cast<int64_t>(cur_pc_val) + (imm)):
|
||||
(static_cast<int32_t>(cur_pc_val) + (imm)):
|
||||
(cur_pc_val + 4);
|
||||
super::template get_reg(traits<ARCH>::NEXT_PC) = PC_val;
|
||||
auto is_cont_v = PC_val !=pc.val;
|
||||
@ -532,8 +508,8 @@ private:
|
||||
|
||||
auto cur_pc_val = pc.val;
|
||||
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)))?
|
||||
(static_cast<int64_t>(cur_pc_val) + (imm)):
|
||||
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<int32_t>(cur_pc_val) + (imm)):
|
||||
(cur_pc_val + 4);
|
||||
super::template get_reg(traits<ARCH>::NEXT_PC) = PC_val;
|
||||
auto is_cont_v = PC_val !=pc.val;
|
||||
@ -567,8 +543,8 @@ private:
|
||||
|
||||
auto cur_pc_val = pc.val;
|
||||
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)))?
|
||||
(static_cast<int64_t>(cur_pc_val) + (imm)):
|
||||
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<int32_t>(cur_pc_val) + (imm)):
|
||||
(cur_pc_val + 4);
|
||||
super::template get_reg(traits<ARCH>::NEXT_PC) = PC_val;
|
||||
auto is_cont_v = PC_val !=pc.val;
|
||||
@ -603,7 +579,7 @@ private:
|
||||
auto cur_pc_val = pc.val;
|
||||
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))?
|
||||
(static_cast<int64_t>(cur_pc_val) + (imm)):
|
||||
(static_cast<int32_t>(cur_pc_val) + (imm)):
|
||||
(cur_pc_val + 4);
|
||||
super::template get_reg(traits<ARCH>::NEXT_PC) = PC_val;
|
||||
auto is_cont_v = PC_val !=pc.val;
|
||||
@ -638,7 +614,7 @@ private:
|
||||
auto cur_pc_val = pc.val;
|
||||
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))?
|
||||
(static_cast<int64_t>(cur_pc_val) + (imm)):
|
||||
(static_cast<int32_t>(cur_pc_val) + (imm)):
|
||||
(cur_pc_val + 4);
|
||||
super::template get_reg(traits<ARCH>::NEXT_PC) = PC_val;
|
||||
auto is_cont_v = PC_val !=pc.val;
|
||||
@ -672,9 +648,9 @@ private:
|
||||
|
||||
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 offs_val = (static_cast<int32_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<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;
|
||||
}
|
||||
this->do_sync(POST_SYNC, 10);
|
||||
@ -706,9 +682,9 @@ private:
|
||||
|
||||
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 offs_val = (static_cast<int32_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<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;
|
||||
}
|
||||
this->do_sync(POST_SYNC, 11);
|
||||
@ -740,9 +716,9 @@ private:
|
||||
|
||||
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 offs_val = (static_cast<int32_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<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;
|
||||
}
|
||||
this->do_sync(POST_SYNC, 12);
|
||||
@ -774,9 +750,9 @@ private:
|
||||
|
||||
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 offs_val = (static_cast<int32_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<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;
|
||||
}
|
||||
this->do_sync(POST_SYNC, 13);
|
||||
@ -808,9 +784,9 @@ private:
|
||||
|
||||
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 offs_val = (static_cast<int32_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<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;
|
||||
}
|
||||
this->do_sync(POST_SYNC, 14);
|
||||
@ -842,7 +818,7 @@ private:
|
||||
|
||||
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 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);
|
||||
super::write_mem(traits<ARCH>::MEM, offs_val, static_cast<uint8_t>(MEMtmp0_val));
|
||||
this->do_sync(POST_SYNC, 15);
|
||||
@ -874,7 +850,7 @@ private:
|
||||
|
||||
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 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);
|
||||
super::write_mem(traits<ARCH>::MEM, offs_val, static_cast<uint16_t>(MEMtmp0_val));
|
||||
this->do_sync(POST_SYNC, 16);
|
||||
@ -906,7 +882,7 @@ private:
|
||||
|
||||
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 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);
|
||||
super::write_mem(traits<ARCH>::MEM, offs_val, static_cast<uint32_t>(MEMtmp0_val));
|
||||
this->do_sync(POST_SYNC, 17);
|
||||
@ -939,7 +915,7 @@ private:
|
||||
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 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;
|
||||
}
|
||||
this->do_sync(POST_SYNC, 18);
|
||||
@ -972,7 +948,7 @@ private:
|
||||
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 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:
|
||||
0;
|
||||
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val;
|
||||
@ -1006,7 +982,7 @@ private:
|
||||
|
||||
auto cur_pc_val = pc.val;
|
||||
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){
|
||||
auto Xtmp0_val = (super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0) < full_imm_val)?
|
||||
1:
|
||||
@ -1043,7 +1019,7 @@ private:
|
||||
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 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;
|
||||
}
|
||||
this->do_sync(POST_SYNC, 21);
|
||||
@ -1076,7 +1052,7 @@ private:
|
||||
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 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;
|
||||
}
|
||||
this->do_sync(POST_SYNC, 22);
|
||||
@ -1109,7 +1085,7 @@ private:
|
||||
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 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;
|
||||
}
|
||||
this->do_sync(POST_SYNC, 23);
|
||||
@ -1130,7 +1106,7 @@ private:
|
||||
|
||||
uint8_t rd = ((bit_sub<7,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){
|
||||
/* generate console output when executing the command */
|
||||
auto mnemonic = fmt::format(
|
||||
@ -1141,9 +1117,13 @@ private:
|
||||
|
||||
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 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;
|
||||
if(shamt > 31){
|
||||
raise_trap(0, 0);
|
||||
} 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);
|
||||
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 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){
|
||||
/* generate console output when executing the command */
|
||||
auto mnemonic = fmt::format(
|
||||
@ -1174,9 +1154,13 @@ private:
|
||||
|
||||
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 Xtmp0_val = (static_cast<uint64_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0))>>(shamt));
|
||||
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val;
|
||||
if(shamt > 31){
|
||||
raise_trap(0, 0);
|
||||
} 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);
|
||||
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 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){
|
||||
/* generate console output when executing the command */
|
||||
auto mnemonic = fmt::format(
|
||||
@ -1207,9 +1191,13 @@ private:
|
||||
|
||||
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 Xtmp0_val = (static_cast<int64_t>(super::template get_reg<reg_t>(rs1 + traits<ARCH>::X0))>>(shamt));
|
||||
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val;
|
||||
if(shamt > 31){
|
||||
raise_trap(0, 0);
|
||||
} 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);
|
||||
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;
|
||||
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
|
||||
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;
|
||||
}
|
||||
this->do_sync(POST_SYNC, 29);
|
||||
@ -1340,7 +1328,7 @@ private:
|
||||
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 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:
|
||||
0;
|
||||
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val;
|
||||
@ -1375,7 +1363,7 @@ private:
|
||||
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 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:
|
||||
0;
|
||||
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val;
|
||||
@ -1443,7 +1431,7 @@ private:
|
||||
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 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;
|
||||
}
|
||||
this->do_sync(POST_SYNC, 33);
|
||||
@ -1476,7 +1464,7 @@ private:
|
||||
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 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;
|
||||
}
|
||||
this->do_sync(POST_SYNC, 34);
|
||||
@ -1573,7 +1561,7 @@ private:
|
||||
auto cur_pc_val = pc.val;
|
||||
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
|
||||
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);
|
||||
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
|
||||
// trap check
|
||||
@ -1601,7 +1589,7 @@ private:
|
||||
auto cur_pc_val = pc.val;
|
||||
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
|
||||
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);
|
||||
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
|
||||
// trap check
|
||||
@ -1772,9 +1760,9 @@ private:
|
||||
auto cur_pc_val = pc.val;
|
||||
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
|
||||
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);
|
||||
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);
|
||||
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
|
||||
// trap check
|
||||
@ -1806,14 +1794,14 @@ private:
|
||||
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);
|
||||
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;
|
||||
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;
|
||||
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp1_val;
|
||||
} else {
|
||||
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);
|
||||
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;
|
||||
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);
|
||||
if(rd != 0){
|
||||
auto Xtmp0_val = xrd_val;
|
||||
@ -1852,7 +1840,7 @@ private:
|
||||
}
|
||||
if(rs1 != 0){
|
||||
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);
|
||||
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;
|
||||
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);
|
||||
if(rd != 0){
|
||||
auto Xtmp0_val = xrd_val;
|
||||
@ -1891,7 +1879,7 @@ private:
|
||||
}
|
||||
if(rs1 != 0){
|
||||
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);
|
||||
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;
|
||||
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 4;
|
||||
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;
|
||||
}
|
||||
auto CSRtmp1_val = super::template zext<uint64_t>((zimm));
|
||||
super::write_mem(traits<ARCH>::CSR, (csr), static_cast<uint64_t>(CSRtmp1_val));
|
||||
auto CSRtmp1_val = super::template zext<uint32_t>((zimm));
|
||||
super::write_mem(traits<ARCH>::CSR, (csr), static_cast<uint32_t>(CSRtmp1_val));
|
||||
this->do_sync(POST_SYNC, 49);
|
||||
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
|
||||
// trap check
|
||||
@ -1957,10 +1945,10 @@ private:
|
||||
|
||||
auto cur_pc_val = pc.val;
|
||||
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){
|
||||
auto CSRtmp0_val = (res_val | super::template zext<uint64_t>((zimm)));
|
||||
super::write_mem(traits<ARCH>::CSR, (csr), static_cast<uint64_t>(CSRtmp0_val));
|
||||
auto CSRtmp0_val = (res_val | super::template zext<uint32_t>((zimm)));
|
||||
super::write_mem(traits<ARCH>::CSR, (csr), static_cast<uint32_t>(CSRtmp0_val));
|
||||
}
|
||||
if(rd != 0){
|
||||
auto Xtmp1_val = res_val;
|
||||
@ -1995,14 +1983,14 @@ private:
|
||||
|
||||
auto cur_pc_val = pc.val;
|
||||
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){
|
||||
auto Xtmp0_val = res_val;
|
||||
super::template get_reg<reg_t>(rd + traits<ARCH>::X0)=Xtmp0_val;
|
||||
}
|
||||
if(zimm != 0){
|
||||
auto CSRtmp1_val = (res_val & ~(super::template zext<uint64_t>((zimm))));
|
||||
super::write_mem(traits<ARCH>::CSR, (csr), static_cast<uint64_t>(CSRtmp1_val));
|
||||
auto CSRtmp1_val = (res_val & ~(super::template zext<uint32_t>((zimm))));
|
||||
super::write_mem(traits<ARCH>::CSR, (csr), static_cast<uint32_t>(CSRtmp1_val));
|
||||
}
|
||||
this->do_sync(POST_SYNC, 51);
|
||||
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
|
||||
@ -2016,440 +2004,6 @@ private:
|
||||
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
|
||||
****************************************************************************/
|
||||
@ -2509,8 +2063,8 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(virt_addr_t star
|
||||
} // namespace mnrv32
|
||||
|
||||
template <>
|
||||
std::unique_ptr<vm_if> create<arch::rv64i>(arch::rv64i *core, unsigned short port, bool dump) {
|
||||
auto ret = new rv64i::vm_impl<arch::rv64i>(*core, dump);
|
||||
std::unique_ptr<vm_if> create<arch::tgf01>(arch::tgf01 *core, unsigned short port, bool dump) {
|
||||
auto ret = new tgf01::vm_impl<arch::tgf01>(*core, dump);
|
||||
if (port != 0) debugger::server<debugger::gdb_session>::run_server(ret, port);
|
||||
return std::unique_ptr<vm_if>(ret);
|
||||
}
|
@ -31,8 +31,8 @@
|
||||
*******************************************************************************/
|
||||
|
||||
#include "../fp_functions.h"
|
||||
#include <iss/arch/mnrv32.h>
|
||||
#include <iss/arch/riscv_hart_msu_vp.h>
|
||||
#include <iss/arch/tgf02.h>
|
||||
#include <iss/arch/riscv_hart_m_p.h>
|
||||
#include <iss/debugger/gdb_session.h>
|
||||
#include <iss/debugger/server.h>
|
||||
#include <iss/iss.h>
|
||||
@ -50,7 +50,7 @@
|
||||
|
||||
namespace iss {
|
||||
namespace interp {
|
||||
namespace mnrv32 {
|
||||
namespace tgf02 {
|
||||
using namespace iss::arch;
|
||||
using namespace iss::debugger;
|
||||
|
||||
@ -167,7 +167,7 @@ private:
|
||||
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 */
|
||||
/* instruction LUI */
|
||||
{32, 0b00000000000000000000000000110111, 0b00000000000000000000000001111111, &this_class::__lui},
|
||||
@ -273,6 +273,22 @@ private:
|
||||
{32, 0b00000000000000000110000001110011, 0b00000000000000000111000001111111, &this_class::__csrrsi},
|
||||
/* instruction 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 */
|
||||
{16, 0b0000000000000000, 0b1110000000000011, &this_class::__c_addi4spn},
|
||||
/* instruction C.LW */
|
||||
@ -2052,10 +2068,334 @@ private:
|
||||
return pc;
|
||||
}
|
||||
|
||||
/* instruction 52: C.ADDI4SPN */
|
||||
compile_ret_t __c_addi4spn(virt_addr_t& pc, code_word_t instr){
|
||||
/* instruction 52: MUL */
|
||||
compile_ret_t __mul(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)));
|
||||
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)));
|
||||
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){
|
||||
@ -2073,7 +2413,7 @@ private:
|
||||
}
|
||||
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;
|
||||
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);
|
||||
// trap check
|
||||
if(trap_state!=0){
|
||||
@ -2085,9 +2425,9 @@ private:
|
||||
return pc;
|
||||
}
|
||||
|
||||
/* instruction 53: C.LW */
|
||||
/* instruction 61: C.LW */
|
||||
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 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 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;
|
||||
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);
|
||||
// trap check
|
||||
if(trap_state!=0){
|
||||
@ -2117,9 +2457,9 @@ private:
|
||||
return pc;
|
||||
}
|
||||
|
||||
/* instruction 54: C.SW */
|
||||
/* instruction 62: C.SW */
|
||||
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 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 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));
|
||||
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);
|
||||
// trap check
|
||||
if(trap_state!=0){
|
||||
@ -2149,9 +2489,9 @@ private:
|
||||
return pc;
|
||||
}
|
||||
|
||||
/* instruction 55: C.ADDI */
|
||||
/* instruction 63: C.ADDI */
|
||||
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));
|
||||
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;
|
||||
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;
|
||||
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);
|
||||
// trap check
|
||||
if(trap_state!=0){
|
||||
@ -2179,9 +2519,9 @@ private:
|
||||
return pc;
|
||||
}
|
||||
|
||||
/* instruction 56: C.NOP */
|
||||
/* instruction 64: C.NOP */
|
||||
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){
|
||||
/* generate console output when executing the command */
|
||||
@ -2191,7 +2531,7 @@ private:
|
||||
auto cur_pc_val = pc.val;
|
||||
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 2;
|
||||
/* 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);
|
||||
// trap check
|
||||
if(trap_state!=0){
|
||||
@ -2203,9 +2543,9 @@ private:
|
||||
return pc;
|
||||
}
|
||||
|
||||
/* instruction 57: C.JAL */
|
||||
/* instruction 65: C.JAL */
|
||||
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));
|
||||
if(this->disass_enabled){
|
||||
@ -2224,7 +2564,7 @@ private:
|
||||
super::template get_reg(traits<ARCH>::NEXT_PC) = PC_val;
|
||||
auto is_cont_v = PC_val !=pc.val;
|
||||
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);
|
||||
// trap check
|
||||
if(trap_state!=0){
|
||||
@ -2236,9 +2576,9 @@ private:
|
||||
return pc;
|
||||
}
|
||||
|
||||
/* instruction 58: C.LI */
|
||||
/* instruction 66: C.LI */
|
||||
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));
|
||||
uint8_t rd = ((bit_sub<7,5>(instr)));
|
||||
@ -2257,7 +2597,7 @@ private:
|
||||
}
|
||||
auto Xtmp0_val = (imm);
|
||||
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);
|
||||
// trap check
|
||||
if(trap_state!=0){
|
||||
@ -2269,9 +2609,9 @@ private:
|
||||
return pc;
|
||||
}
|
||||
|
||||
/* instruction 59: C.LUI */
|
||||
/* instruction 67: C.LUI */
|
||||
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));
|
||||
uint8_t rd = ((bit_sub<7,5>(instr)));
|
||||
@ -2293,7 +2633,7 @@ private:
|
||||
}
|
||||
auto Xtmp0_val = (imm);
|
||||
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);
|
||||
// trap check
|
||||
if(trap_state!=0){
|
||||
@ -2305,9 +2645,9 @@ private:
|
||||
return pc;
|
||||
}
|
||||
|
||||
/* instruction 60: C.ADDI16SP */
|
||||
/* instruction 68: C.ADDI16SP */
|
||||
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));
|
||||
if(this->disass_enabled){
|
||||
@ -2322,7 +2662,7 @@ private:
|
||||
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));
|
||||
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);
|
||||
// trap check
|
||||
if(trap_state!=0){
|
||||
@ -2334,9 +2674,9 @@ private:
|
||||
return pc;
|
||||
}
|
||||
|
||||
/* instruction 61: C.SRLI */
|
||||
/* instruction 69: C.SRLI */
|
||||
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 rs1 = ((bit_sub<7,3>(instr)));
|
||||
@ -2353,7 +2693,7 @@ private:
|
||||
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));
|
||||
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);
|
||||
// trap check
|
||||
if(trap_state!=0){
|
||||
@ -2365,9 +2705,9 @@ private:
|
||||
return pc;
|
||||
}
|
||||
|
||||
/* instruction 62: C.SRAI */
|
||||
/* instruction 70: C.SRAI */
|
||||
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 rs1 = ((bit_sub<7,3>(instr)));
|
||||
@ -2384,7 +2724,7 @@ private:
|
||||
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));
|
||||
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);
|
||||
// trap check
|
||||
if(trap_state!=0){
|
||||
@ -2396,9 +2736,9 @@ private:
|
||||
return pc;
|
||||
}
|
||||
|
||||
/* instruction 63: C.ANDI */
|
||||
/* instruction 71: C.ANDI */
|
||||
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));
|
||||
uint8_t rs1 = ((bit_sub<7,3>(instr)));
|
||||
@ -2415,7 +2755,7 @@ private:
|
||||
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));
|
||||
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);
|
||||
// trap check
|
||||
if(trap_state!=0){
|
||||
@ -2427,9 +2767,9 @@ private:
|
||||
return pc;
|
||||
}
|
||||
|
||||
/* instruction 64: C.SUB */
|
||||
/* instruction 72: C.SUB */
|
||||
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 rd = ((bit_sub<7,3>(instr)));
|
||||
@ -2446,7 +2786,7 @@ private:
|
||||
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));
|
||||
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);
|
||||
// trap check
|
||||
if(trap_state!=0){
|
||||
@ -2458,9 +2798,9 @@ private:
|
||||
return pc;
|
||||
}
|
||||
|
||||
/* instruction 65: C.XOR */
|
||||
/* instruction 73: C.XOR */
|
||||
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 rd = ((bit_sub<7,3>(instr)));
|
||||
@ -2477,7 +2817,7 @@ private:
|
||||
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));
|
||||
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);
|
||||
// trap check
|
||||
if(trap_state!=0){
|
||||
@ -2489,9 +2829,9 @@ private:
|
||||
return pc;
|
||||
}
|
||||
|
||||
/* instruction 66: C.OR */
|
||||
/* instruction 74: C.OR */
|
||||
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 rd = ((bit_sub<7,3>(instr)));
|
||||
@ -2508,7 +2848,7 @@ private:
|
||||
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));
|
||||
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);
|
||||
// trap check
|
||||
if(trap_state!=0){
|
||||
@ -2520,9 +2860,9 @@ private:
|
||||
return pc;
|
||||
}
|
||||
|
||||
/* instruction 67: C.AND */
|
||||
/* instruction 75: C.AND */
|
||||
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 rd = ((bit_sub<7,3>(instr)));
|
||||
@ -2539,7 +2879,7 @@ private:
|
||||
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));
|
||||
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);
|
||||
// trap check
|
||||
if(trap_state!=0){
|
||||
@ -2551,9 +2891,9 @@ private:
|
||||
return pc;
|
||||
}
|
||||
|
||||
/* instruction 68: C.J */
|
||||
/* instruction 76: C.J */
|
||||
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));
|
||||
if(this->disass_enabled){
|
||||
@ -2570,7 +2910,7 @@ private:
|
||||
super::template get_reg(traits<ARCH>::NEXT_PC) = PC_val;
|
||||
auto is_cont_v = PC_val !=pc.val;
|
||||
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);
|
||||
// trap check
|
||||
if(trap_state!=0){
|
||||
@ -2582,9 +2922,9 @@ private:
|
||||
return pc;
|
||||
}
|
||||
|
||||
/* instruction 69: C.BEQZ */
|
||||
/* instruction 77: C.BEQZ */
|
||||
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));
|
||||
uint8_t rs1 = ((bit_sub<7,3>(instr)));
|
||||
@ -2604,7 +2944,7 @@ private:
|
||||
super::template get_reg(traits<ARCH>::NEXT_PC) = PC_val;
|
||||
auto is_cont_v = PC_val !=pc.val;
|
||||
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);
|
||||
// trap check
|
||||
if(trap_state!=0){
|
||||
@ -2616,9 +2956,9 @@ private:
|
||||
return pc;
|
||||
}
|
||||
|
||||
/* instruction 70: C.BNEZ */
|
||||
/* instruction 78: C.BNEZ */
|
||||
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));
|
||||
uint8_t rs1 = ((bit_sub<7,3>(instr)));
|
||||
@ -2638,7 +2978,7 @@ private:
|
||||
super::template get_reg(traits<ARCH>::NEXT_PC) = PC_val;
|
||||
auto is_cont_v = PC_val !=pc.val;
|
||||
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);
|
||||
// trap check
|
||||
if(trap_state!=0){
|
||||
@ -2650,9 +2990,9 @@ private:
|
||||
return pc;
|
||||
}
|
||||
|
||||
/* instruction 71: C.SLLI */
|
||||
/* instruction 79: C.SLLI */
|
||||
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 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));
|
||||
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);
|
||||
// trap check
|
||||
if(trap_state!=0){
|
||||
@ -2683,9 +3023,9 @@ private:
|
||||
return pc;
|
||||
}
|
||||
|
||||
/* instruction 72: C.LWSP */
|
||||
/* instruction 80: C.LWSP */
|
||||
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 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 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;
|
||||
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);
|
||||
// trap check
|
||||
if(trap_state!=0){
|
||||
@ -2714,9 +3054,9 @@ private:
|
||||
return pc;
|
||||
}
|
||||
|
||||
/* instruction 73: C.MV */
|
||||
/* instruction 81: C.MV */
|
||||
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 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;
|
||||
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;
|
||||
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);
|
||||
// trap check
|
||||
if(trap_state!=0){
|
||||
@ -2744,9 +3084,9 @@ private:
|
||||
return pc;
|
||||
}
|
||||
|
||||
/* instruction 74: C.JR */
|
||||
/* instruction 82: C.JR */
|
||||
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)));
|
||||
if(this->disass_enabled){
|
||||
@ -2762,7 +3102,7 @@ private:
|
||||
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>::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);
|
||||
// trap check
|
||||
if(trap_state!=0){
|
||||
@ -2774,9 +3114,9 @@ private:
|
||||
return pc;
|
||||
}
|
||||
|
||||
/* instruction 75: C.ADD */
|
||||
/* instruction 83: C.ADD */
|
||||
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 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;
|
||||
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;
|
||||
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);
|
||||
// trap check
|
||||
if(trap_state!=0){
|
||||
@ -2804,9 +3144,9 @@ private:
|
||||
return pc;
|
||||
}
|
||||
|
||||
/* instruction 76: C.JALR */
|
||||
/* instruction 84: C.JALR */
|
||||
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)));
|
||||
if(this->disass_enabled){
|
||||
@ -2824,7 +3164,7 @@ private:
|
||||
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>::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);
|
||||
// trap check
|
||||
if(trap_state!=0){
|
||||
@ -2836,9 +3176,9 @@ private:
|
||||
return pc;
|
||||
}
|
||||
|
||||
/* instruction 77: C.EBREAK */
|
||||
/* instruction 85: C.EBREAK */
|
||||
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){
|
||||
/* generate console output when executing the command */
|
||||
@ -2848,7 +3188,7 @@ private:
|
||||
auto cur_pc_val = pc.val;
|
||||
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 2;
|
||||
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);
|
||||
// trap check
|
||||
if(trap_state!=0){
|
||||
@ -2860,9 +3200,9 @@ private:
|
||||
return pc;
|
||||
}
|
||||
|
||||
/* instruction 78: C.SWSP */
|
||||
/* instruction 86: C.SWSP */
|
||||
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 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 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));
|
||||
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);
|
||||
// trap check
|
||||
if(trap_state!=0){
|
||||
@ -2891,9 +3231,9 @@ private:
|
||||
return pc;
|
||||
}
|
||||
|
||||
/* instruction 79: DII */
|
||||
/* instruction 87: DII */
|
||||
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){
|
||||
/* generate console output when executing the command */
|
||||
@ -2903,7 +3243,7 @@ private:
|
||||
auto cur_pc_val = pc.val;
|
||||
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + 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);
|
||||
// trap check
|
||||
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
|
||||
|
||||
template <>
|
||||
std::unique_ptr<vm_if> create<arch::mnrv32>(arch::mnrv32 *core, unsigned short port, bool dump) {
|
||||
auto ret = new mnrv32::vm_impl<arch::mnrv32>(*core, dump);
|
||||
std::unique_ptr<vm_if> create<arch::tgf02>(arch::tgf02 *core, unsigned short port, bool dump) {
|
||||
auto ret = new tgf02::vm_impl<arch::tgf02>(*core, dump);
|
||||
if (port != 0) debugger::server<debugger::gdb_session>::run_server(ret, port);
|
||||
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
@ -31,7 +31,7 @@
|
||||
*******************************************************************************/
|
||||
|
||||
#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/server.h>
|
||||
#include <iss/iss.h>
|
||||
|
@ -31,7 +31,7 @@
|
||||
*******************************************************************************/
|
||||
|
||||
#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/server.h>
|
||||
#include <iss/iss.h>
|
||||
|
Loading…
Reference in New Issue
Block a user