18 Commits

Author SHA1 Message Date
57347ae4d9 fixes cppcheck flagged issues 2022-07-23 13:49:10 +02:00
4876f18ba9 adds windows compatibility fixes 2022-07-18 11:43:42 +02:00
a53ee42e13 updates TGC_C according to CoreDSL description update 2022-07-12 22:34:22 +02:00
12ccfc055a updates generate tgc_c definition 2022-07-11 22:58:10 +02:00
feaa49d367 removes decoder again as there is some issue 2022-06-20 00:39:11 +02:00
18f33b4a68 fixes ordering of instructions for decoding 2022-06-19 16:52:29 +02:00
f096b15dbd factors decoder into separate component 2022-06-19 13:17:31 +02:00
cb5375258a removes compilatioon of unneeded files 2022-06-10 07:19:46 +02:00
076b5a39ad fix class naming 2022-06-02 08:30:49 +02:00
f40ab41899 fix left-over from layout refactoring 2022-06-02 08:30:02 +02:00
e8fd5143bc fix build options for standalone ISS 2022-05-31 11:05:26 +02:00
31fb51de95 update tgc_c generated code 2022-05-30 22:15:44 +02:00
5d481eb79d fix generation of non-exception code 2022-05-30 22:04:16 +02:00
1c90fe765d Merge remote-tracking branch 'origin/Trace_enhancement' into develop 2022-05-30 14:18:09 +02:00
52ed8b81a6 fixed template to work with previous code generator 2022-05-30 14:08:02 +02:00
0703a0a845 update tgc-mapper 2022-05-30 07:45:32 +02:00
0c542d42aa separate generated sources 2022-05-21 12:48:28 +02:00
966d1616c5 change source code to unified layout 2022-05-21 11:55:24 +02:00
35 changed files with 2560 additions and 7088 deletions

1
.gitignore vendored
View File

@ -30,6 +30,5 @@ language.settings.xml
/.gdbinit /.gdbinit
/*.out /*.out
/dump.json /dump.json
/src-gen/
/*.yaml /*.yaml
/*.json /*.json

View File

@ -29,32 +29,34 @@ endif()
add_subdirectory(softfloat) add_subdirectory(softfloat)
# library files # library files
FILE(GLOB TGC_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/iss/*.cpp) FILE(GLOB GEN_SOURCES
FILE(GLOB TGC_VM_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/vm/interp/vm_*.cpp) ${CMAKE_CURRENT_SOURCE_DIR}/src-gen/iss/arch/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src-gen/vm/interp/vm_*.cpp
)
set(LIB_SOURCES set(LIB_SOURCES
src/vm/fp_functions.cpp src/iss/plugin/instruction_count.cpp
src/plugin/instruction_count.cpp src/iss/arch/tgc_c.cpp
src/vm/interp/vm_tgc_c.cpp
${TGC_SOURCES} src/vm/fp_functions.cpp
${TGC_VM_SOURCES} ${GEN_SOURCES}
) )
if(TARGET RapidJSON) if(TARGET RapidJSON)
list(APPEND LIB_SOURCES src/plugin/cycle_estimate.cpp src/plugin/pctrace.cpp) list(APPEND LIB_SOURCES src/iss/plugin/cycle_estimate.cpp src/iss/plugin/pctrace.cpp)
endif() endif()
if(WITH_LLVM) if(WITH_LLVM)
FILE(GLOB TGC_LLVM_SOURCES FILE(GLOB LLVM_GEN_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/src/vm/llvm/vm_*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src-gen/vm/llvm/vm_*.cpp
) )
list(APPEND LIB_SOURCES ${TGC_LLVM_SOURCES}) list(APPEND LIB_SOURCES ${LLVM_GEN_SOURCES})
endif() endif()
if(WITH_TCC) if(WITH_TCC)
FILE(GLOB TGC_TCC_SOURCES FILE(GLOB TCC_GEN_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/src/vm/tcc/vm_*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/vm/tcc/vm_*.cpp
) )
list(APPEND LIB_SOURCES ${TGC_TCC_SOURCES}) list(APPEND LIB_SOURCES ${TCC_GEN_SOURCES})
endif() endif()
# Define the library # Define the library
@ -69,7 +71,8 @@ if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
target_compile_options(${PROJECT_NAME} PRIVATE /wd4293) target_compile_options(${PROJECT_NAME} PRIVATE /wd4293)
endif() endif()
target_include_directories(${PROJECT_NAME} PUBLIC incl) target_include_directories(${PROJECT_NAME} PUBLIC src)
target_include_directories(${PROJECT_NAME} PUBLIC src-gen)
target_link_libraries(${PROJECT_NAME} PUBLIC softfloat scc-util jsoncpp Boost::coroutine) target_link_libraries(${PROJECT_NAME} PUBLIC softfloat scc-util jsoncpp Boost::coroutine)
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
target_link_libraries(${PROJECT_NAME} PUBLIC -Wl,--whole-archive dbt-rise-core -Wl,--no-whole-archive) target_link_libraries(${PROJECT_NAME} PUBLIC -Wl,--whole-archive dbt-rise-core -Wl,--no-whole-archive)
@ -117,6 +120,7 @@ project(tgc-sim)
find_package(Boost COMPONENTS program_options thread REQUIRED) find_package(Boost COMPONENTS program_options thread REQUIRED)
add_executable(${PROJECT_NAME} src/main.cpp) add_executable(${PROJECT_NAME} src/main.cpp)
FILE(GLOB TGC_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src-gen/iss/arch/*.cpp)
foreach(F IN LISTS TGC_SOURCES) foreach(F IN LISTS TGC_SOURCES)
string(REGEX REPLACE ".*/([^/]*)\.cpp" "\\1" CORE_NAME_LC ${F}) string(REGEX REPLACE ".*/([^/]*)\.cpp" "\\1" CORE_NAME_LC ${F})
string(TOUPPER ${CORE_NAME_LC} CORE_NAME) string(TOUPPER ${CORE_NAME_LC} CORE_NAME)

View File

@ -37,9 +37,9 @@ def getRegisterSizes(){
return regs return regs
} }
%> %>
#include "${coreDef.name.toLowerCase()}.h"
#include "util/ities.h" #include "util/ities.h"
#include <util/logging.h> #include <util/logging.h>
#include <iss/arch/${coreDef.name.toLowerCase()}.h>
#include <cstdio> #include <cstdio>
#include <cstring> #include <cstring>
#include <fstream> #include <fstream>

View File

@ -0,0 +1,86 @@
#include "${coreDef.name.toLowerCase()}.h"
#include <vector>
#include <array>
#include <cstdlib>
#include <algorithm>
namespace iss {
namespace arch {
namespace {
// according to
// https://stackoverflow.com/questions/8871204/count-number-of-1s-in-binary-representation
#ifdef __GCC__
constexpr size_t bit_count(uint32_t u) { return __builtin_popcount(u); }
#elif __cplusplus < 201402L
constexpr size_t uCount(uint32_t u) { return u - ((u >> 1) & 033333333333) - ((u >> 2) & 011111111111); }
constexpr size_t bit_count(uint32_t u) { return ((uCount(u) + (uCount(u) >> 3)) & 030707070707) % 63; }
#else
constexpr size_t bit_count(uint32_t u) {
size_t uCount = u - ((u >> 1) & 033333333333) - ((u >> 2) & 011111111111);
return ((uCount + (uCount >> 3)) & 030707070707) % 63;
}
#endif
using opcode_e = traits<${coreDef.name.toLowerCase()}>::opcode_e;
/****************************************************************************
* start opcode definitions
****************************************************************************/
struct instruction_desriptor {
size_t length;
uint32_t value;
uint32_t mask;
opcode_e op;
};
const std::array<instruction_desriptor, ${instructions.size}> instr_descr = {{
/* entries are: size, valid value, valid mask, function ptr */<%instructions.each{instr -> %>
{${instr.length}, ${instr.encoding}, ${instr.mask}, opcode_e::${instr.instruction.name}},<%}%>
}};
}
template<>
struct instruction_decoder<${coreDef.name.toLowerCase()}> {
using opcode_e = traits<${coreDef.name.toLowerCase()}>::opcode_e;
using code_word_t=traits<${coreDef.name.toLowerCase()}>::code_word_t;
struct instruction_pattern {
uint32_t value;
uint32_t mask;
opcode_e id;
};
std::array<std::vector<instruction_pattern>, 4> qlut;
template<typename T>
unsigned decode_instruction(T);
instruction_decoder() {
for (auto instr : instr_descr) {
auto quadrant = instr.value & 0x3;
qlut[quadrant].push_back(instruction_pattern{instr.value, instr.mask, instr.op});
}
for(auto& lut: qlut){
std::sort(std::begin(lut), std::end(lut), [](instruction_pattern const& a, instruction_pattern const& b){
return bit_count(a.mask) < bit_count(b.mask);
});
}
}
};
template<>
unsigned instruction_decoder<${coreDef.name.toLowerCase()}>::decode_instruction<traits<${coreDef.name.toLowerCase()}>::code_word_t>(traits<${coreDef.name.toLowerCase()}>::code_word_t instr){
auto res = std::find_if(std::begin(qlut[instr&0x3]), std::end(qlut[instr&0x3]), [instr](instruction_pattern const& e){
return !((instr&e.mask) ^ e.value );
});
return static_cast<unsigned>(res!=std::end(qlut[instr&0x3])? res->id : opcode_e::MAX_OPCODE);
}
std::unique_ptr<instruction_decoder<${coreDef.name.toLowerCase()}>> traits<${coreDef.name.toLowerCase()}>::get_decoder(){
return std::make_unique<instruction_decoder<${coreDef.name.toLowerCase()}>>();
}
}
}

View File

@ -12,5 +12,6 @@
${name}: <% instrList.findAll{!it.instruction.name.startsWith("__")}.each { %> ${name}: <% instrList.findAll{!it.instruction.name.startsWith("__")}.each { %>
- ${it.instruction.name}: - ${it.instruction.name}:
encoding: ${it.encoding} encoding: ${it.encoding}
mask: ${it.mask}<%}}%> mask: ${it.mask}<%if(it.attributes.size) {%>
attributes: ${it.attributes}<%}}}%>

View File

@ -36,7 +36,7 @@ def nativeTypeSize(int size){
if(size<=8) return 8; else if(size<=16) return 16; else if(size<=32) return 32; else return 64; if(size<=8) return 8; else if(size<=16) return 16; else if(size<=32) return 32; else return 64;
} }
%> %>
#include "../fp_functions.h" #include <vm/fp_functions.h>
#include <iss/arch/${coreDef.name.toLowerCase()}.h> #include <iss/arch/${coreDef.name.toLowerCase()}.h>
#include <iss/arch/riscv_hart_m_p.h> #include <iss/arch/riscv_hart_m_p.h>
#include <iss/debugger/gdb_session.h> #include <iss/debugger/gdb_session.h>
@ -73,6 +73,7 @@ public:
using addr_t = typename super::addr_t; using addr_t = typename super::addr_t;
using reg_t = typename traits::reg_t; using reg_t = typename traits::reg_t;
using mem_type_e = typename traits::mem_type_e; using mem_type_e = typename traits::mem_type_e;
using opcode_e = typename traits::opcode_e;
vm_impl(); vm_impl();
@ -301,22 +302,21 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, static_cast<unsigned>(inst_id)); if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, static_cast<unsigned>(inst_id));
switch(inst_id){<%instructions.eachWithIndex{instr, idx -> %> switch(inst_id){<%instructions.eachWithIndex{instr, idx -> %>
case arch::traits<ARCH>::opcode_e::${instr.name}: { case arch::traits<ARCH>::opcode_e::${instr.name}: {
<%instr.fields.eachLine{%>${it} <%instr.fields.eachLine{%>${it}
<%}%>if(this->disass_enabled){ <%}%>if(this->disass_enabled){
/* generate console output when executing the command */ /* generate console output when executing the command */<%instr.disass.eachLine{%>
<%instr.disass.eachLine{%>${it} ${it}<%}%>
<%}%> }
} // used registers<%instr.usedVariables.each{ k,v->
// used registers<%instr.usedVariables.each{ k,v-> if(v.isArray) {%>
if(v.isArray) {%> auto* ${k} = reinterpret_cast<uint${nativeTypeSize(v.type.size)}_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::${k}0]);<% }else{ %>
auto* ${k} = reinterpret_cast<uint${nativeTypeSize(v.type.size)}_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::${k}0]);<% }else{ %> auto* ${k} = reinterpret_cast<uint${nativeTypeSize(v.type.size)}_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::${k}]);
auto* ${k} = reinterpret_cast<uint${nativeTypeSize(v.type.size)}_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::${k}]); <%}}%>// calculate next pc value
<%}}%>// calculate next pc value *NEXT_PC = *PC + ${instr.length/8};
*NEXT_PC = *PC + ${instr.length/8}; // execute instruction<%instr.behavior.eachLine{%>
// execute instruction ${it}<%}%>
<%instr.behavior.eachLine{%>${it} TRAP_${instr.name}:break;
<%}%>TRAP_${instr.name}:break; }// @suppress("No break at end of case")<%}%>
}// @suppress("No break at end of case")<%}%>
default: { default: {
*NEXT_PC = *PC + ((instr & 3) == 3 ? 4 : 2); *NEXT_PC = *PC + ((instr & 3) == 3 ? 4 : 2);
raise(0, 2); raise(0, 2);

View File

@ -30,10 +30,10 @@
* *
*******************************************************************************/ *******************************************************************************/
#include <iss/arch/${coreDef.name.toLowerCase()}.h>
#include <iss/arch/riscv_hart_m_p.h>
#include <iss/debugger/gdb_session.h> #include <iss/debugger/gdb_session.h>
#include <iss/debugger/server.h> #include <iss/debugger/server.h>
#include <iss/arch/${coreDef.name.toLowerCase()}.h>
#include <iss/arch/riscv_hart_m_p.h>
#include <iss/iss.h> #include <iss/iss.h>
#include <iss/llvm/vm_base.h> #include <iss/llvm/vm_base.h>
#include <util/logging.h> #include <util/logging.h>

View File

@ -1 +0,0 @@
/tgc_*.h

2
src-gen/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
/iss
/vm

View File

@ -477,10 +477,10 @@ template <typename BASE, features_e FEAT> std::pair<uint64_t, bool> riscv_hart_m
if (fp) { if (fp) {
std::array<char, 5> buf; std::array<char, 5> buf;
auto n = fread(buf.data(), 1, 4, fp); auto n = fread(buf.data(), 1, 4, fp);
fclose(fp);
if (n != 4) throw std::runtime_error("input file has insufficient size"); if (n != 4) throw std::runtime_error("input file has insufficient size");
buf[4] = 0; buf[4] = 0;
if (strcmp(buf.data() + 1, "ELF") == 0) { if (strcmp(buf.data() + 1, "ELF") == 0) {
fclose(fp);
// Create elfio reader // Create elfio reader
ELFIO::elfio reader; ELFIO::elfio reader;
// Load ELF data // Load ELF data
@ -571,12 +571,12 @@ iss::status riscv_hart_m_p<BASE, FEAT>::read(const address_type type, const acce
if (unlikely(is_fetch(access) && (addr&(alignment-1)))) { if (unlikely(is_fetch(access) && (addr&(alignment-1)))) {
fault_data = addr; fault_data = addr;
if (is_debug(access)) throw trap_access(0, addr); if (is_debug(access)) throw trap_access(0, addr);
this->trap_state = (1 << 31); // issue trap 0 this->trap_state = (1UL << 31); // issue trap 0
return iss::Err; return iss::Err;
} }
try { try {
if(!is_debug(access) && (addr&(alignment-1))){ if(!is_debug(access) && (addr&(alignment-1))){
this->trap_state = 1<<31 | 4<<16; this->trap_state = (1UL << 31) | 4<<16;
fault_data=addr; fault_data=addr;
return iss::Err; return iss::Err;
} }
@ -595,12 +595,12 @@ iss::status riscv_hart_m_p<BASE, FEAT>::read(const address_type type, const acce
res = read_mem( phys_addr, length, data); res = read_mem( phys_addr, length, data);
} }
if (unlikely(res != iss::Ok)){ if (unlikely(res != iss::Ok)){
this->trap_state = (1 << 31) | (5 << 16); // issue trap 5 (load access fault this->trap_state = (1UL << 31) | (5 << 16); // issue trap 5 (load access fault
fault_data=addr; fault_data=addr;
} }
return res; return res;
} catch (trap_access &ta) { } catch (trap_access &ta) {
this->trap_state = (1 << 31) | ta.id; this->trap_state = (1UL << 31) | ta.id;
fault_data=ta.addr; fault_data=ta.addr;
return iss::Err; return iss::Err;
} }
@ -626,7 +626,7 @@ iss::status riscv_hart_m_p<BASE, FEAT>::read(const address_type type, const acce
} }
return iss::Ok; return iss::Ok;
} catch (trap_access &ta) { } catch (trap_access &ta) {
this->trap_state = (1 << 31) | ta.id; this->trap_state = (1UL << 31) | ta.id;
fault_data=ta.addr; fault_data=ta.addr;
return iss::Err; return iss::Err;
} }
@ -664,12 +664,12 @@ iss::status riscv_hart_m_p<BASE, FEAT>::write(const address_type type, const acc
if (unlikely((access && iss::access_type::FETCH) && (addr & 0x1) == 1)) { if (unlikely((access && iss::access_type::FETCH) && (addr & 0x1) == 1)) {
fault_data = addr; fault_data = addr;
if (access && iss::access_type::DEBUG) throw trap_access(0, addr); if (access && iss::access_type::DEBUG) throw trap_access(0, addr);
this->trap_state = (1 << 31); // issue trap 0 this->trap_state = (1UL << 31); // issue trap 0
return iss::Err; return iss::Err;
} }
try { try {
if(length>1 && (addr&(length-1)) && (access&access_type::DEBUG) != access_type::DEBUG){ if(length>1 && (addr&(length-1)) && (access&access_type::DEBUG) != access_type::DEBUG){
this->trap_state = 1<<31 | 6<<16; this->trap_state = (1UL << 31) | 6<<16;
fault_data=addr; fault_data=addr;
return iss::Err; return iss::Err;
} }
@ -688,12 +688,12 @@ iss::status riscv_hart_m_p<BASE, FEAT>::write(const address_type type, const acc
res = write_mem( phys_addr, length, data); res = write_mem( phys_addr, length, data);
} }
if (unlikely(res != iss::Ok)) { if (unlikely(res != iss::Ok)) {
this->trap_state = (1 << 31) | (7 << 16); // issue trap 7 (Store/AMO access fault) this->trap_state = (1UL << 31) | (7 << 16); // issue trap 7 (Store/AMO access fault)
fault_data=addr; fault_data=addr;
} }
return res; return res;
} catch (trap_access &ta) { } catch (trap_access &ta) {
this->trap_state = (1 << 31) | ta.id; this->trap_state = (1UL << 31) | ta.id;
fault_data=ta.addr; fault_data=ta.addr;
return iss::Err; return iss::Err;
} }
@ -753,7 +753,7 @@ iss::status riscv_hart_m_p<BASE, FEAT>::write(const address_type type, const acc
} }
return iss::Ok; return iss::Ok;
} catch (trap_access &ta) { } catch (trap_access &ta) {
this->trap_state = (1 << 31) | ta.id; this->trap_state = (1UL << 31) | ta.id;
fault_data=ta.addr; fault_data=ta.addr;
return iss::Err; return iss::Err;
} }

View File

@ -526,10 +526,10 @@ template <typename BASE, features_e FEAT> std::pair<uint64_t, bool> riscv_hart_m
if (fp) { if (fp) {
std::array<char, 5> buf; std::array<char, 5> buf;
auto n = fread(buf.data(), 1, 4, fp); auto n = fread(buf.data(), 1, 4, fp);
fclose(fp);
if (n != 4) throw std::runtime_error("input file has insufficient size"); if (n != 4) throw std::runtime_error("input file has insufficient size");
buf[4] = 0; buf[4] = 0;
if (strcmp(buf.data() + 1, "ELF") == 0) { if (strcmp(buf.data() + 1, "ELF") == 0) {
fclose(fp);
// Create elfio reader // Create elfio reader
ELFIO::elfio reader; ELFIO::elfio reader;
// Load ELF data // Load ELF data
@ -708,7 +708,7 @@ iss::status riscv_hart_mu_p<BASE, FEAT>::read(const address_type type, const acc
if(!pmp_check(access, addr, length) && !is_debug(access)) { if(!pmp_check(access, addr, length) && !is_debug(access)) {
fault_data = addr; fault_data = addr;
if (is_debug(access)) throw trap_access(0, addr); if (is_debug(access)) throw trap_access(0, addr);
this->trap_state = (1 << 31) | ((access==access_type::FETCH?1:5) << 16); // issue trap 1 this->trap_state = (1UL << 31) | ((access==access_type::FETCH?1:5) << 16); // issue trap 1
return iss::Err; return iss::Err;
} }
} }
@ -716,12 +716,12 @@ iss::status riscv_hart_mu_p<BASE, FEAT>::read(const address_type type, const acc
if (unlikely(is_fetch(access) && (addr&(alignment-1)))) { if (unlikely(is_fetch(access) && (addr&(alignment-1)))) {
fault_data = addr; fault_data = addr;
if (is_debug(access)) throw trap_access(0, addr); if (is_debug(access)) throw trap_access(0, addr);
this->trap_state = (1 << 31); // issue trap 0 this->trap_state = (1UL << 31); // issue trap 0
return iss::Err; return iss::Err;
} }
try { try {
if(!is_debug(access) && (addr&(alignment-1))){ if(!is_debug(access) && (addr&(alignment-1))){
this->trap_state = 1<<31 | 4<<16; this->trap_state = (1UL << 31) | 4<<16;
fault_data=addr; fault_data=addr;
return iss::Err; return iss::Err;
} }
@ -740,12 +740,12 @@ iss::status riscv_hart_mu_p<BASE, FEAT>::read(const address_type type, const acc
res = read_mem( phys_addr, length, data); res = read_mem( phys_addr, length, data);
} }
if (unlikely(res != iss::Ok)){ if (unlikely(res != iss::Ok)){
this->trap_state = (1 << 31) | (5 << 16); // issue trap 5 (load access fault this->trap_state = (1UL << 31) | (5 << 16); // issue trap 5 (load access fault
fault_data=addr; fault_data=addr;
} }
return res; return res;
} catch (trap_access &ta) { } catch (trap_access &ta) {
this->trap_state = (1 << 31) | ta.id; this->trap_state = (1UL << 31) | ta.id;
fault_data=ta.addr; fault_data=ta.addr;
return iss::Err; return iss::Err;
} }
@ -771,7 +771,7 @@ iss::status riscv_hart_mu_p<BASE, FEAT>::read(const address_type type, const acc
} }
return iss::Ok; return iss::Ok;
} catch (trap_access &ta) { } catch (trap_access &ta) {
this->trap_state = (1 << 31) | ta.id; this->trap_state = (1UL << 31) | ta.id;
fault_data=ta.addr; fault_data=ta.addr;
return iss::Err; return iss::Err;
} }
@ -810,19 +810,19 @@ iss::status riscv_hart_mu_p<BASE, FEAT>::write(const address_type type, const ac
if(!pmp_check(access, addr, length) && (access&access_type::DEBUG) != access_type::DEBUG) { if(!pmp_check(access, addr, length) && (access&access_type::DEBUG) != access_type::DEBUG) {
fault_data = addr; fault_data = addr;
if (access && iss::access_type::DEBUG) throw trap_access(0, addr); if (access && iss::access_type::DEBUG) throw trap_access(0, addr);
this->trap_state = (1 << 31) | (7 << 16); // issue trap 1 this->trap_state = (1UL << 31) | (7 << 16); // issue trap 1
return iss::Err; return iss::Err;
} }
} }
if (unlikely((access && iss::access_type::FETCH) && (addr & 0x1) == 1)) { if (unlikely((access && iss::access_type::FETCH) && (addr & 0x1) == 1)) {
fault_data = addr; fault_data = addr;
if (access && iss::access_type::DEBUG) throw trap_access(0, addr); if (access && iss::access_type::DEBUG) throw trap_access(0, addr);
this->trap_state = (1 << 31); // issue trap 0 this->trap_state = (1UL << 31); // issue trap 0
return iss::Err; return iss::Err;
} }
try { try {
if(length>1 && (addr&(length-1)) && (access&access_type::DEBUG) != access_type::DEBUG){ if(length>1 && (addr&(length-1)) && (access&access_type::DEBUG) != access_type::DEBUG){
this->trap_state = 1<<31 | 6<<16; this->trap_state = (1UL << 31) | 6<<16;
fault_data=addr; fault_data=addr;
return iss::Err; return iss::Err;
} }
@ -841,12 +841,12 @@ iss::status riscv_hart_mu_p<BASE, FEAT>::write(const address_type type, const ac
res = write_mem( phys_addr, length, data); res = write_mem( phys_addr, length, data);
} }
if (unlikely(res != iss::Ok)) { if (unlikely(res != iss::Ok)) {
this->trap_state = (1 << 31) | (7 << 16); // issue trap 7 (Store/AMO access fault) this->trap_state = (1UL << 31) | (7 << 16); // issue trap 7 (Store/AMO access fault)
fault_data=addr; fault_data=addr;
} }
return res; return res;
} catch (trap_access &ta) { } catch (trap_access &ta) {
this->trap_state = (1 << 31) | ta.id; this->trap_state = (1UL << 31) | ta.id;
fault_data=ta.addr; fault_data=ta.addr;
return iss::Err; return iss::Err;
} }
@ -906,7 +906,7 @@ iss::status riscv_hart_mu_p<BASE, FEAT>::write(const address_type type, const ac
} }
return iss::Ok; return iss::Ok;
} catch (trap_access &ta) { } catch (trap_access &ta) {
this->trap_state = (1 << 31) | ta.id; this->trap_state = (1UL << 31) | ta.id;
fault_data=ta.addr; fault_data=ta.addr;
return iss::Err; return iss::Err;
} }

View File

@ -30,9 +30,9 @@
* *
*******************************************************************************/ *******************************************************************************/
#include "tgc_c.h"
#include "util/ities.h" #include "util/ities.h"
#include <util/logging.h> #include <util/logging.h>
#include <iss/arch/tgc_c.h>
#include <cstdio> #include <cstdio>
#include <cstring> #include <cstring>
#include <fstream> #include <fstream>

View File

@ -53,7 +53,7 @@ template <> struct traits<tgc_c> {
static constexpr std::array<const char*, 36> reg_aliases{ static constexpr std::array<const char*, 36> 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", "NEXT_PC", "PRIV", "DPC"}}; {"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", "NEXT_PC", "PRIV", "DPC"}};
enum constants {MISA_VAL=0b01000000000000000001000100000100, MARCHID_VAL=0x80000003, RFS=32, INSTR_ALIGNMENT=2, XLEN=32, CSR_SIZE=4096, fence=0, fencei=1, fencevmal=2, fencevmau=3, MUL_LEN=64}; enum constants {MISA_VAL=0b01000000000000000001000100000100, MARCHID_VAL=0x80000003, XLEN=32, INSTR_ALIGNMENT=2, RFS=32, fence=0, fencei=1, fencevmal=2, fencevmau=3, CSR_SIZE=4096, MUL_LEN=64};
constexpr static unsigned FP_REGS_SIZE = 0; constexpr static unsigned FP_REGS_SIZE = 0;
@ -81,7 +81,7 @@ template <> struct traits<tgc_c> {
enum sreg_flag_e { FLAGS }; enum sreg_flag_e { FLAGS };
enum mem_type_e { MEM, CSR, FENCE, RES }; enum mem_type_e { MEM, FENCE, RES, CSR };
enum class opcode_e : unsigned short { enum class opcode_e : unsigned short {
LUI = 0, LUI = 0,
@ -124,56 +124,53 @@ template <> struct traits<tgc_c> {
FENCE = 37, FENCE = 37,
ECALL = 38, ECALL = 38,
EBREAK = 39, EBREAK = 39,
URET = 40, MRET = 40,
SRET = 41, WFI = 41,
MRET = 42, CSRRW = 42,
WFI = 43, CSRRS = 43,
DRET = 44, CSRRC = 44,
CSRRW = 45, CSRRWI = 45,
CSRRS = 46, CSRRSI = 46,
CSRRC = 47, CSRRCI = 47,
CSRRWI = 48, FENCE_I = 48,
CSRRSI = 49, MUL = 49,
CSRRCI = 50, MULH = 50,
FENCE_I = 51, MULHSU = 51,
MUL = 52, MULHU = 52,
MULH = 53, DIV = 53,
MULHSU = 54, DIVU = 54,
MULHU = 55, REM = 55,
DIV = 56, REMU = 56,
DIVU = 57, CADDI4SPN = 57,
REM = 58, CLW = 58,
REMU = 59, CSW = 59,
CADDI4SPN = 60, CADDI = 60,
CLW = 61, CNOP = 61,
CSW = 62, CJAL = 62,
CADDI = 63, CLI = 63,
CNOP = 64, CLUI = 64,
CJAL = 65, CADDI16SP = 65,
CLI = 66, __reserved_clui = 66,
CLUI = 67, CSRLI = 67,
CADDI16SP = 68, CSRAI = 68,
__reserved_clui = 69, CANDI = 69,
CSRLI = 70, CSUB = 70,
CSRAI = 71, CXOR = 71,
CANDI = 72, COR = 72,
CSUB = 73, CAND = 73,
CXOR = 74, CJ = 74,
COR = 75, CBEQZ = 75,
CAND = 76, CBNEZ = 76,
CJ = 77, CSLLI = 77,
CBEQZ = 78, CLWSP = 78,
CBNEZ = 79, CMV = 79,
CSLLI = 80, CJR = 80,
CLWSP = 81, __reserved_cmv = 81,
CMV = 82, CADD = 82,
CJR = 83, CJALR = 83,
__reserved_cmv = 84, CEBREAK = 84,
CADD = 85, CSWSP = 85,
CJALR = 86, DII = 86,
CEBREAK = 87,
CSWSP = 88,
DII = 89,
MAX_OPCODE MAX_OPCODE
}; };
}; };

View File

@ -0,0 +1,175 @@
#include "tgc_c.h"
#include <vector>
#include <array>
#include <cstdlib>
#include <algorithm>
namespace iss {
namespace arch {
namespace {
// according to
// https://stackoverflow.com/questions/8871204/count-number-of-1s-in-binary-representation
#ifdef __GCC__
constexpr size_t bit_count(uint32_t u) { return __builtin_popcount(u); }
#elif __cplusplus < 201402L
constexpr size_t uCount(uint32_t u) { return u - ((u >> 1) & 033333333333) - ((u >> 2) & 011111111111); }
constexpr size_t bit_count(uint32_t u) { return ((uCount(u) + (uCount(u) >> 3)) & 030707070707) % 63; }
#else
constexpr size_t bit_count(uint32_t u) {
size_t uCount = u - ((u >> 1) & 033333333333) - ((u >> 2) & 011111111111);
return ((uCount + (uCount >> 3)) & 030707070707) % 63;
}
#endif
using opcode_e = traits<tgc_c>::opcode_e;
/****************************************************************************
* start opcode definitions
****************************************************************************/
struct instruction_desriptor {
size_t length;
uint32_t value;
uint32_t mask;
opcode_e op;
};
const std::array<instruction_desriptor, 90> instr_descr = {{
/* entries are: size, valid value, valid mask, function ptr */
{32, 0b00000000000000000000000000110111, 0b00000000000000000000000001111111, opcode_e::LUI},
{32, 0b00000000000000000000000000010111, 0b00000000000000000000000001111111, opcode_e::AUIPC},
{32, 0b00000000000000000000000001101111, 0b00000000000000000000000001111111, opcode_e::JAL},
{32, 0b00000000000000000000000001100111, 0b00000000000000000111000001111111, opcode_e::JALR},
{32, 0b00000000000000000000000001100011, 0b00000000000000000111000001111111, opcode_e::BEQ},
{32, 0b00000000000000000001000001100011, 0b00000000000000000111000001111111, opcode_e::BNE},
{32, 0b00000000000000000100000001100011, 0b00000000000000000111000001111111, opcode_e::BLT},
{32, 0b00000000000000000101000001100011, 0b00000000000000000111000001111111, opcode_e::BGE},
{32, 0b00000000000000000110000001100011, 0b00000000000000000111000001111111, opcode_e::BLTU},
{32, 0b00000000000000000111000001100011, 0b00000000000000000111000001111111, opcode_e::BGEU},
{32, 0b00000000000000000000000000000011, 0b00000000000000000111000001111111, opcode_e::LB},
{32, 0b00000000000000000001000000000011, 0b00000000000000000111000001111111, opcode_e::LH},
{32, 0b00000000000000000010000000000011, 0b00000000000000000111000001111111, opcode_e::LW},
{32, 0b00000000000000000100000000000011, 0b00000000000000000111000001111111, opcode_e::LBU},
{32, 0b00000000000000000101000000000011, 0b00000000000000000111000001111111, opcode_e::LHU},
{32, 0b00000000000000000000000000100011, 0b00000000000000000111000001111111, opcode_e::SB},
{32, 0b00000000000000000001000000100011, 0b00000000000000000111000001111111, opcode_e::SH},
{32, 0b00000000000000000010000000100011, 0b00000000000000000111000001111111, opcode_e::SW},
{32, 0b00000000000000000000000000010011, 0b00000000000000000111000001111111, opcode_e::ADDI},
{32, 0b00000000000000000010000000010011, 0b00000000000000000111000001111111, opcode_e::SLTI},
{32, 0b00000000000000000011000000010011, 0b00000000000000000111000001111111, opcode_e::SLTIU},
{32, 0b00000000000000000100000000010011, 0b00000000000000000111000001111111, opcode_e::XORI},
{32, 0b00000000000000000110000000010011, 0b00000000000000000111000001111111, opcode_e::ORI},
{32, 0b00000000000000000111000000010011, 0b00000000000000000111000001111111, opcode_e::ANDI},
{32, 0b00000000000000000001000000010011, 0b11111110000000000111000001111111, opcode_e::SLLI},
{32, 0b00000000000000000101000000010011, 0b11111110000000000111000001111111, opcode_e::SRLI},
{32, 0b01000000000000000101000000010011, 0b11111110000000000111000001111111, opcode_e::SRAI},
{32, 0b00000000000000000000000000110011, 0b11111110000000000111000001111111, opcode_e::ADD},
{32, 0b01000000000000000000000000110011, 0b11111110000000000111000001111111, opcode_e::SUB},
{32, 0b00000000000000000001000000110011, 0b11111110000000000111000001111111, opcode_e::SLL},
{32, 0b00000000000000000010000000110011, 0b11111110000000000111000001111111, opcode_e::SLT},
{32, 0b00000000000000000011000000110011, 0b11111110000000000111000001111111, opcode_e::SLTU},
{32, 0b00000000000000000100000000110011, 0b11111110000000000111000001111111, opcode_e::XOR},
{32, 0b00000000000000000101000000110011, 0b11111110000000000111000001111111, opcode_e::SRL},
{32, 0b01000000000000000101000000110011, 0b11111110000000000111000001111111, opcode_e::SRA},
{32, 0b00000000000000000110000000110011, 0b11111110000000000111000001111111, opcode_e::OR},
{32, 0b00000000000000000111000000110011, 0b11111110000000000111000001111111, opcode_e::AND},
{32, 0b00000000000000000000000000001111, 0b00000000000000000111000001111111, opcode_e::FENCE},
{32, 0b00000000000000000000000001110011, 0b11111111111111111111111111111111, opcode_e::ECALL},
{32, 0b00000000000100000000000001110011, 0b11111111111111111111111111111111, opcode_e::EBREAK},
{32, 0b00000000001000000000000001110011, 0b11111111111111111111111111111111, opcode_e::URET},
{32, 0b00010000001000000000000001110011, 0b11111111111111111111111111111111, opcode_e::SRET},
{32, 0b00110000001000000000000001110011, 0b11111111111111111111111111111111, opcode_e::MRET},
{32, 0b00010000010100000000000001110011, 0b11111111111111111111111111111111, opcode_e::WFI},
{32, 0b01111011001000000000000001110011, 0b11111111111111111111111111111111, opcode_e::DRET},
{32, 0b00000000000000000001000001110011, 0b00000000000000000111000001111111, opcode_e::CSRRW},
{32, 0b00000000000000000010000001110011, 0b00000000000000000111000001111111, opcode_e::CSRRS},
{32, 0b00000000000000000011000001110011, 0b00000000000000000111000001111111, opcode_e::CSRRC},
{32, 0b00000000000000000101000001110011, 0b00000000000000000111000001111111, opcode_e::CSRRWI},
{32, 0b00000000000000000110000001110011, 0b00000000000000000111000001111111, opcode_e::CSRRSI},
{32, 0b00000000000000000111000001110011, 0b00000000000000000111000001111111, opcode_e::CSRRCI},
{32, 0b00000000000000000001000000001111, 0b00000000000000000111000001111111, opcode_e::FENCE_I},
{32, 0b00000010000000000000000000110011, 0b11111110000000000111000001111111, opcode_e::MUL},
{32, 0b00000010000000000001000000110011, 0b11111110000000000111000001111111, opcode_e::MULH},
{32, 0b00000010000000000010000000110011, 0b11111110000000000111000001111111, opcode_e::MULHSU},
{32, 0b00000010000000000011000000110011, 0b11111110000000000111000001111111, opcode_e::MULHU},
{32, 0b00000010000000000100000000110011, 0b11111110000000000111000001111111, opcode_e::DIV},
{32, 0b00000010000000000101000000110011, 0b11111110000000000111000001111111, opcode_e::DIVU},
{32, 0b00000010000000000110000000110011, 0b11111110000000000111000001111111, opcode_e::REM},
{32, 0b00000010000000000111000000110011, 0b11111110000000000111000001111111, opcode_e::REMU},
{16, 0b0000000000000000, 0b1110000000000011, opcode_e::CADDI4SPN},
{16, 0b0100000000000000, 0b1110000000000011, opcode_e::CLW},
{16, 0b1100000000000000, 0b1110000000000011, opcode_e::CSW},
{16, 0b0000000000000001, 0b1110000000000011, opcode_e::CADDI},
{16, 0b0000000000000001, 0b1110111110000011, opcode_e::CNOP},
{16, 0b0010000000000001, 0b1110000000000011, opcode_e::CJAL},
{16, 0b0100000000000001, 0b1110000000000011, opcode_e::CLI},
{16, 0b0110000000000001, 0b1110000000000011, opcode_e::CLUI},
{16, 0b0110000100000001, 0b1110111110000011, opcode_e::CADDI16SP},
{16, 0b0110000000000001, 0b1111000001111111, opcode_e::__reserved_clui},
{16, 0b1000000000000001, 0b1111110000000011, opcode_e::CSRLI},
{16, 0b1000010000000001, 0b1111110000000011, opcode_e::CSRAI},
{16, 0b1000100000000001, 0b1110110000000011, opcode_e::CANDI},
{16, 0b1000110000000001, 0b1111110001100011, opcode_e::CSUB},
{16, 0b1000110000100001, 0b1111110001100011, opcode_e::CXOR},
{16, 0b1000110001000001, 0b1111110001100011, opcode_e::COR},
{16, 0b1000110001100001, 0b1111110001100011, opcode_e::CAND},
{16, 0b1010000000000001, 0b1110000000000011, opcode_e::CJ},
{16, 0b1100000000000001, 0b1110000000000011, opcode_e::CBEQZ},
{16, 0b1110000000000001, 0b1110000000000011, opcode_e::CBNEZ},
{16, 0b0000000000000010, 0b1111000000000011, opcode_e::CSLLI},
{16, 0b0100000000000010, 0b1110000000000011, opcode_e::CLWSP},
{16, 0b1000000000000010, 0b1111000000000011, opcode_e::CMV},
{16, 0b1000000000000010, 0b1111000001111111, opcode_e::CJR},
{16, 0b1000000000000010, 0b1111111111111111, opcode_e::__reserved_cmv},
{16, 0b1001000000000010, 0b1111000000000011, opcode_e::CADD},
{16, 0b1001000000000010, 0b1111000001111111, opcode_e::CJALR},
{16, 0b1001000000000010, 0b1111111111111111, opcode_e::CEBREAK},
{16, 0b1100000000000010, 0b1110000000000011, opcode_e::CSWSP},
{16, 0b0000000000000000, 0b1111111111111111, opcode_e::DII},
}};
}
template<>
struct instruction_decoder<tgc_c> {
using opcode_e = traits<tgc_c>::opcode_e;
using code_word_t=traits<tgc_c>::code_word_t;
struct instruction_pattern {
uint32_t value;
uint32_t mask;
opcode_e id;
};
std::array<std::vector<instruction_pattern>, 4> qlut;
template<typename T>
unsigned decode_instruction(T);
instruction_decoder() {
for (auto instr : instr_descr) {
auto quadrant = instr.value & 0x3;
qlut[quadrant].push_back(instruction_pattern{instr.value, instr.mask, instr.op});
}
for(auto& lut: qlut){
std::sort(std::begin(lut), std::end(lut), [](instruction_pattern const& a, instruction_pattern const& b){
return bit_count(a.mask) > bit_count(b.mask);
});
}
}
};
template<>
unsigned instruction_decoder<tgc_c>::decode_instruction<traits<tgc_c>::code_word_t>(traits<tgc_c>::code_word_t instr){
auto res = std::find_if(std::begin(qlut[instr&0x3]), std::end(qlut[instr&0x3]), [instr](instruction_pattern const& e){
return !((instr&e.mask) ^ e.value );
});
return static_cast<unsigned>(res!=std::end(qlut[instr&0x3])? res->id : opcode_e::MAX_OPCODE);
}
std::unique_ptr<instruction_decoder<tgc_c>> traits<tgc_c>::get_decoder(){
return std::make_unique<instruction_decoder<tgc_c>>();
}
}
}

View File

@ -4,39 +4,44 @@
#include "riscv_hart_m_p.h" #include "riscv_hart_m_p.h"
#include "tgc_c.h" #include "tgc_c.h"
using tgc_c_plat_type = iss::arch::riscv_hart_m_p<iss::arch::tgc_c>; using tgc_c_plat_type = iss::arch::riscv_hart_m_p<iss::arch::tgc_c>;
#ifdef CORE_TGC_A
#include "riscv_hart_m_p.h"
#include <iss/arch/tgc_a.h>
using tgc_a_plat_type = iss::arch::riscv_hart_m_p<iss::arch::tgc_a>;
#endif
#ifdef CORE_TGC_B #ifdef CORE_TGC_B
#include "riscv_hart_m_p.h" #include "riscv_hart_m_p.h"
#include "tgc_b.h" #include <iss/arch/tgc_b.h>
using tgc_b_plat_type = iss::arch::riscv_hart_m_p<iss::arch::tgc_b>; using tgc_b_plat_type = iss::arch::riscv_hart_m_p<iss::arch::tgc_b>;
#endif #endif
#ifdef CORE_TGC_C_XRB_NN #ifdef CORE_TGC_C_XRB_NN
#include "riscv_hart_m_p.h" #include "riscv_hart_m_p.h"
#include "tgc_c_xrb_nn.h" #include <iss/arch/tgc_c_xrb_nn.h>
using tgc_c_xrb_nn_plat_type = iss::arch::riscv_hart_m_p<iss::arch::tgc_c_xrb_nn>; using tgc_c_xrb_nn_plat_type = iss::arch::riscv_hart_m_p<iss::arch::tgc_c_xrb_nn>;
#endif #endif
#ifdef CORE_TGC_D #ifdef CORE_TGC_D
#include "riscv_hart_mu_p.h" #include "riscv_hart_mu_p.h"
#include "tgc_d.h" #include <iss/arch/tgc_d.h>
using tgc_d_plat_type = iss::arch::riscv_hart_mu_p<iss::arch::tgc_d, (iss::arch::features_e)(iss::arch::FEAT_PMP | iss::arch::FEAT_CLIC | iss::arch::FEAT_EXT_N)>; using tgc_d_plat_type = iss::arch::riscv_hart_mu_p<iss::arch::tgc_d, (iss::arch::features_e)(iss::arch::FEAT_PMP | iss::arch::FEAT_CLIC | iss::arch::FEAT_EXT_N)>;
#endif #endif
#ifdef CORE_TGC_D_XRB_MAC #ifdef CORE_TGC_D_XRB_MAC
#include "riscv_hart_mu_p.h" #include "riscv_hart_mu_p.h"
#include "tgc_d_xrb_mac.h" #include <iss/arch/tgc_d_xrb_mac.h>
using tgc_d_xrb_mac_plat_type = iss::arch::riscv_hart_mu_p<iss::arch::tgc_d_xrb_mac, (iss::arch::features_e)(iss::arch::FEAT_PMP | iss::arch::FEAT_CLIC | iss::arch::FEAT_EXT_N)>; using tgc_d_xrb_mac_plat_type = iss::arch::riscv_hart_mu_p<iss::arch::tgc_d_xrb_mac, (iss::arch::features_e)(iss::arch::FEAT_PMP | iss::arch::FEAT_CLIC | iss::arch::FEAT_EXT_N)>;
#endif #endif
#ifdef CORE_TGC_D_XRB_NN #ifdef CORE_TGC_D_XRB_NN
#include "riscv_hart_mu_p.h" #include "riscv_hart_mu_p.h"
#include "tgc_d_xrb_nn.h" #include <iss/arch/tgc_d_xrb_nn.h>
using tgc_d_xrb_nn_plat_type = iss::arch::riscv_hart_mu_p<iss::arch::tgc_d_xrb_nn, (iss::arch::features_e)(iss::arch::FEAT_PMP | iss::arch::FEAT_CLIC | iss::arch::FEAT_EXT_N)>; using tgc_d_xrb_nn_plat_type = iss::arch::riscv_hart_mu_p<iss::arch::tgc_d_xrb_nn, (iss::arch::features_e)(iss::arch::FEAT_PMP | iss::arch::FEAT_CLIC | iss::arch::FEAT_EXT_N)>;
#endif #endif
#ifdef CORE_TGC_E #ifdef CORE_TGC_E
#include "riscv_hart_mu_p.h" #include "riscv_hart_mu_p.h"
#include "tgc_e.h" #include <iss/arch/tgc_e.h>
using tgc_e_plat_type = iss::arch::riscv_hart_mu_p<iss::arch::tgc_e, (iss::arch::features_e)(iss::arch::FEAT_PMP | iss::arch::FEAT_CLIC | iss::arch::FEAT_EXT_N)>; using tgc_e_plat_type = iss::arch::riscv_hart_mu_p<iss::arch::tgc_e, (iss::arch::features_e)(iss::arch::FEAT_PMP | iss::arch::FEAT_CLIC | iss::arch::FEAT_EXT_N)>;
#endif #endif
#ifdef CORE_TGC_X #ifdef CORE_TGC_X
#include "riscv_hart_mu_p.h" #include "riscv_hart_mu_p.h"
#include "tgc_x.h" #include <iss/arch/tgc_x.h>
using tgc_x_plat_type = iss::arch::riscv_hart_mu_p<iss::arch::tgc_x, (iss::arch::features_e)(iss::arch::FEAT_PMP | iss::arch::FEAT_CLIC | iss::arch::FEAT_EXT_N | iss::arch::FEAT_TCM)>; using tgc_x_plat_type = iss::arch::riscv_hart_mu_p<iss::arch::tgc_x, (iss::arch::features_e)(iss::arch::FEAT_PMP | iss::arch::FEAT_CLIC | iss::arch::FEAT_EXT_N | iss::arch::FEAT_TCM)>;
#endif #endif

View File

@ -32,14 +32,14 @@
* eyck@minres.com - initial API and implementation * eyck@minres.com - initial API and implementation
******************************************************************************/ ******************************************************************************/
#include "iss/plugin/cycle_estimate.h" #include "cycle_estimate.h"
#include <iss/arch_if.h> #include <iss/arch_if.h>
#include <util/logging.h> #include <util/logging.h>
#include <rapidjson/document.h> #include <rapidjson/document.h>
#include <rapidjson/istreamwrapper.h> #include <rapidjson/istreamwrapper.h>
#include "rapidjson/writer.h" #include <rapidjson/writer.h>
#include "rapidjson/stringbuffer.h" #include <rapidjson/stringbuffer.h>
#include <rapidjson/ostreamwrapper.h> #include <rapidjson/ostreamwrapper.h>
#include <rapidjson/error/en.h> #include <rapidjson/error/en.h>
#include <fstream> #include <fstream>

View File

@ -45,7 +45,7 @@ namespace iss {
namespace plugin { namespace plugin {
class cycle_estimate: public iss::vm_plugin { class cycle_estimate: public vm_plugin {
BEGIN_BF_DECL(instr_desc, uint32_t) BEGIN_BF_DECL(instr_desc, uint32_t)
BF_FIELD(taken, 24, 8) BF_FIELD(taken, 24, 8)
BF_FIELD(not_taken, 16, 8) BF_FIELD(not_taken, 16, 8)

View File

@ -32,8 +32,8 @@
* eyck@minres.com - initial API and implementation * eyck@minres.com - initial API and implementation
******************************************************************************/ ******************************************************************************/
#include "iss/plugin/instruction_count.h" #include "instruction_count.h"
#include "iss/instrumentation_if.h" #include <iss/instrumentation_if.h>
#include <iss/arch_if.h> #include <iss/arch_if.h>
#include <util/logging.h> #include <util/logging.h>

View File

@ -4,8 +4,8 @@
#include <util/ities.h> #include <util/ities.h>
#include <rapidjson/document.h> #include <rapidjson/document.h>
#include <rapidjson/istreamwrapper.h> #include <rapidjson/istreamwrapper.h>
#include "rapidjson/writer.h" #include <rapidjson/writer.h>
#include "rapidjson/stringbuffer.h" #include <rapidjson/stringbuffer.h>
#include <rapidjson/ostreamwrapper.h> #include <rapidjson/ostreamwrapper.h>
#include <rapidjson/error/en.h> #include <rapidjson/error/en.h>
#include <fstream> #include <fstream>
@ -89,7 +89,7 @@ private:
}; };
#endif #endif
cov::cov(std::string const &filename) pctrace::pctrace(std::string const &filename)
: instr_if(nullptr) : instr_if(nullptr)
, filename(filename) , filename(filename)
, output("output.trc") , output("output.trc")
@ -99,9 +99,9 @@ cov::cov(std::string const &filename)
#endif #endif
{ } { }
cov::~cov() { } pctrace::~pctrace() { }
bool cov::registration(const char *const version, vm_if& vm) { bool pctrace::registration(const char *const version, vm_if& vm) {
instr_if = vm.get_arch()->get_instrumentation_if(); instr_if = vm.get_arch()->get_instrumentation_if();
if(!instr_if) return false; if(!instr_if) return false;
const string core_name = instr_if->core_type_name(); const string core_name = instr_if->core_type_name();
@ -152,7 +152,7 @@ bool cov::registration(const char *const version, vm_if& vm) {
return true; return true;
} }
void cov::callback(instr_info_t iinfo, const exec_info& einfo) { void pctrace::callback(instr_info_t iinfo, const exec_info& einfo) {
auto delay = 0; auto delay = 0;
size_t id = iinfo.instr_id; size_t id = iinfo.instr_id;
auto entry = delays[id]; auto entry = delays[id];

View File

@ -45,7 +45,7 @@
namespace iss { namespace iss {
namespace plugin { namespace plugin {
class lz4compress_steambuf; class lz4compress_steambuf;
class cov : public iss::vm_plugin { class pctrace : public iss::vm_plugin {
struct instr_delay { struct instr_delay {
std::string instr_name; std::string instr_name;
size_t size; size_t size;
@ -67,17 +67,17 @@ class cov : public iss::vm_plugin {
public: public:
cov(const cov &) = delete; pctrace(const pctrace &) = delete;
cov(const cov &&) = delete; pctrace(const pctrace &&) = delete;
cov(std::string const &); pctrace(std::string const &);
virtual ~cov(); virtual ~pctrace();
cov &operator=(const cov &) = delete; pctrace &operator=(const pctrace &) = delete;
cov &operator=(const cov &&) = delete; pctrace &operator=(const pctrace &&) = delete;
bool registration(const char *const version, vm_if &arch) override; bool registration(const char *const version, vm_if &arch) override;

View File

@ -1,236 +1,241 @@
/******************************************************************************* /*******************************************************************************
* Copyright (C) 2017, 2018 MINRES Technologies GmbH * Copyright (C) 2017, 2018 MINRES Technologies GmbH
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, * 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
* *
* 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
* *
* 3. Neither the name of the copyright holder nor the names of its contributors * 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 * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * 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 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
*******************************************************************************/ *******************************************************************************/
#include <iostream> #include <iostream>
#include <iss/factory.h> #include "iss/factory.h"
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include <boost/program_options.hpp> #include <boost/program_options.hpp>
#include <iss/arch/tgc_mapper.h> #include "iss/arch/tgc_mapper.h"
#ifdef WITH_LLVM #ifdef WITH_LLVM
#include <iss/llvm/jit_helper.h> #include <iss/llvm/jit_helper.h>
#endif #endif
#include <iss/log_categories.h> #include <iss/log_categories.h>
#include <iss/plugin/cycle_estimate.h> #include "iss/plugin/cycle_estimate.h"
#include <iss/plugin/instruction_count.h> #include "iss/plugin/instruction_count.h"
#include <iss/plugin/pctrace.h> #include "iss/plugin/pctrace.h"
#include <iss/plugin/loader.h> #ifndef WIN32
#if defined(HAS_LUA) #include <iss/plugin/loader.h>
#include <iss/plugin/lua.h> #endif
#endif #if defined(HAS_LUA)
#include <iss/plugin/lua.h>
namespace po = boost::program_options; #endif
int main(int argc, char *argv[]) { namespace po = boost::program_options;
/*
* Define and parse the program options int main(int argc, char *argv[]) {
*/ /*
po::variables_map clim; * Define and parse the program options
po::options_description desc("Options"); */
// clang-format off po::variables_map clim;
desc.add_options() po::options_description desc("Options");
("help,h", "Print help message") // clang-format off
("verbose,v", po::value<int>()->implicit_value(0), "Sets logging verbosity") desc.add_options()
("logfile,l", po::value<std::string>(), "Sets default log file.") ("help,h", "Print help message")
("disass,d", po::value<std::string>()->implicit_value(""), "Enables disassembly") ("verbose,v", po::value<int>()->implicit_value(0), "Sets logging verbosity")
("gdb-port,g", po::value<unsigned>()->default_value(0), "enable gdb server and specify port to use") ("logfile,l", po::value<std::string>(), "Sets default log file.")
("instructions,i", po::value<uint64_t>()->default_value(std::numeric_limits<uint64_t>::max()), "max. number of instructions to simulate") ("disass,d", po::value<std::string>()->implicit_value(""), "Enables disassembly")
("reset,r", po::value<std::string>(), "reset address") ("gdb-port,g", po::value<unsigned>()->default_value(0), "enable gdb server and specify port to use")
("dump-ir", "dump the intermediate representation") ("instructions,i", po::value<uint64_t>()->default_value(std::numeric_limits<uint64_t>::max()), "max. number of instructions to simulate")
("elf,f", po::value<std::vector<std::string>>(), "ELF file(s) to load") ("reset,r", po::value<std::string>(), "reset address")
("mem,m", po::value<std::string>(), "the memory input file") ("dump-ir", "dump the intermediate representation")
("plugin,p", po::value<std::vector<std::string>>(), "plugin to activate") ("elf,f", po::value<std::vector<std::string>>(), "ELF file(s) to load")
("backend", po::value<std::string>()->default_value("interp"), "the memory input file") ("mem,m", po::value<std::string>(), "the memory input file")
("isa", po::value<std::string>()->default_value("tgc_c"), "isa to use for simulation"); ("plugin,p", po::value<std::vector<std::string>>(), "plugin to activate")
// clang-format on ("backend", po::value<std::string>()->default_value("interp"), "the memory input file")
auto parsed = po::command_line_parser(argc, argv).options(desc).allow_unregistered().run(); ("isa", po::value<std::string>()->default_value("tgc_c"), "isa to use for simulation");
try { // clang-format on
po::store(parsed, clim); // can throw auto parsed = po::command_line_parser(argc, argv).options(desc).allow_unregistered().run();
// --help option try {
if (clim.count("help")) { po::store(parsed, clim); // can throw
std::cout << "DBT-RISE-RiscV simulator for RISC-V" << std::endl << desc << std::endl; // --help option
return 0; if (clim.count("help")) {
} std::cout << "DBT-RISE-RiscV simulator for RISC-V" << std::endl << desc << std::endl;
po::notify(clim); // throws on error, so do after help in case return 0;
} catch (po::error &e) { }
// there are problems po::notify(clim); // throws on error, so do after help in case
std::cerr << "ERROR: " << e.what() << std::endl << std::endl; } catch (po::error &e) {
std::cerr << desc << std::endl; // there are problems
return 1; std::cerr << "ERROR: " << e.what() << std::endl << std::endl;
} std::cerr << desc << std::endl;
std::vector<std::string> args = collect_unrecognized(parsed.options, po::include_positional); return 1;
}
LOGGER(DEFAULT)::print_time() = false; std::vector<std::string> args = collect_unrecognized(parsed.options, po::include_positional);
LOGGER(connection)::print_time() = false;
if (clim.count("verbose")) { LOGGER(DEFAULT)::print_time() = false;
auto l = logging::as_log_level(clim["verbose"].as<int>()); LOGGER(connection)::print_time() = false;
LOGGER(DEFAULT)::reporting_level() = l; if (clim.count("verbose")) {
LOGGER(connection)::reporting_level() = l; auto l = logging::as_log_level(clim["verbose"].as<int>());
} LOGGER(DEFAULT)::reporting_level() = l;
if (clim.count("logfile")) { LOGGER(connection)::reporting_level() = l;
// configure the connection logger }
auto f = fopen(clim["logfile"].as<std::string>().c_str(), "w"); if (clim.count("logfile")) {
LOG_OUTPUT(DEFAULT)::stream() = f; // configure the connection logger
LOG_OUTPUT(connection)::stream() = f; auto f = fopen(clim["logfile"].as<std::string>().c_str(), "w");
} LOG_OUTPUT(DEFAULT)::stream() = f;
LOG_OUTPUT(connection)::stream() = f;
std::vector<iss::vm_plugin *> plugin_list; }
auto res = 0;
try { std::vector<iss::vm_plugin *> plugin_list;
#ifdef WITH_LLVM auto res = 0;
// application code comes here // try {
iss::init_jit_debug(argc, argv); #ifdef WITH_LLVM
#endif // application code comes here //
bool dump = clim.count("dump-ir"); iss::init_jit_debug(argc, argv);
// instantiate the simulator #endif
iss::vm_ptr vm{nullptr}; bool dump = clim.count("dump-ir");
iss::cpu_ptr cpu{nullptr}; // instantiate the simulator
std::string isa_opt(clim["isa"].as<std::string>()); iss::vm_ptr vm{nullptr};
if (isa_opt == "tgc_c") { iss::cpu_ptr cpu{nullptr};
std::tie(cpu, vm) = std::string isa_opt(clim["isa"].as<std::string>());
iss::create_cpu<tgc_c_plat_type>(clim["backend"].as<std::string>(), clim["gdb-port"].as<unsigned>()); if (isa_opt == "tgc_c") {
} else std::tie(cpu, vm) =
#ifdef CORE_TGC_B iss::create_cpu<tgc_c_plat_type>(clim["backend"].as<std::string>(), clim["gdb-port"].as<unsigned>());
if (isa_opt == "tgc_b") { } else
std::tie(cpu, vm) = #ifdef CORE_TGC_B
iss::create_cpu<tgc_b_plat_type>(clim["backend"].as<std::string>(), clim["gdb-port"].as<unsigned>()); if (isa_opt == "tgc_b") {
} else std::tie(cpu, vm) =
#endif iss::create_cpu<tgc_b_plat_type>(clim["backend"].as<std::string>(), clim["gdb-port"].as<unsigned>());
#ifdef CORE_TGC_C_XRB_NN } else
if (isa_opt == "tgc_c_xrb_nn") { #endif
std::tie(cpu, vm) = #ifdef CORE_TGC_C_XRB_NN
iss::create_cpu<tgc_c_xrb_nn_plat_type>(clim["backend"].as<std::string>(), clim["gdb-port"].as<unsigned>()); if (isa_opt == "tgc_c_xrb_nn") {
} else std::tie(cpu, vm) =
#endif iss::create_cpu<tgc_c_xrb_nn_plat_type>(clim["backend"].as<std::string>(), clim["gdb-port"].as<unsigned>());
#ifdef CORE_TGC_D } else
if (isa_opt == "tgc_d") { #endif
std::tie(cpu, vm) = #ifdef CORE_TGC_D
iss::create_cpu<tgc_d_plat_type>(clim["backend"].as<std::string>(), clim["gdb-port"].as<unsigned>()); if (isa_opt == "tgc_d") {
} else std::tie(cpu, vm) =
#endif iss::create_cpu<tgc_d_plat_type>(clim["backend"].as<std::string>(), clim["gdb-port"].as<unsigned>());
#ifdef CORE_TGC_D_XRB_MAC } else
if (isa_opt == "tgc_d_xrb_mac") { #endif
std::tie(cpu, vm) = #ifdef CORE_TGC_D_XRB_MAC
iss::create_cpu<tgc_d_xrb_mac_plat_type>(clim["backend"].as<std::string>(), clim["gdb-port"].as<unsigned>()); if (isa_opt == "tgc_d_xrb_mac") {
} else std::tie(cpu, vm) =
#endif iss::create_cpu<tgc_d_xrb_mac_plat_type>(clim["backend"].as<std::string>(), clim["gdb-port"].as<unsigned>());
#ifdef CORE_TGC_D_XRB_NN } else
if (isa_opt == "tgc_d_xrb_nn") { #endif
std::tie(cpu, vm) = #ifdef CORE_TGC_D_XRB_NN
iss::create_cpu<tgc_d_xrb_nn_plat_type>(clim["backend"].as<std::string>(), clim["gdb-port"].as<unsigned>()); if (isa_opt == "tgc_d_xrb_nn") {
} else std::tie(cpu, vm) =
#endif iss::create_cpu<tgc_d_xrb_nn_plat_type>(clim["backend"].as<std::string>(), clim["gdb-port"].as<unsigned>());
#ifdef CORE_TGC_E } else
if (isa_opt == "tgc_e") { #endif
std::tie(cpu, vm) = #ifdef CORE_TGC_E
iss::create_cpu<tgc_e_plat_type>(clim["backend"].as<std::string>(), clim["gdb-port"].as<unsigned>()); if (isa_opt == "tgc_e") {
} else std::tie(cpu, vm) =
#endif iss::create_cpu<tgc_e_plat_type>(clim["backend"].as<std::string>(), clim["gdb-port"].as<unsigned>());
{ } else
#endif
{
LOG(ERR) << "Illegal argument value for '--isa': " << isa_opt << std::endl; LOG(ERR) << "Illegal argument value for '--isa': " << isa_opt << std::endl;
return 127; return 127;
} }
if (clim.count("plugin")) { if (clim.count("plugin")) {
for (std::string const& opt_val : clim["plugin"].as<std::vector<std::string>>()) { for (std::string const& opt_val : clim["plugin"].as<std::vector<std::string>>()) {
std::string plugin_name=opt_val; std::string plugin_name=opt_val;
std::string filename{"cycles.txt"}; std::string filename{"cycles.txt"};
std::size_t found = opt_val.find('='); std::size_t found = opt_val.find('=');
if (found != std::string::npos) { if (found != std::string::npos) {
plugin_name = opt_val.substr(0, found); plugin_name = opt_val.substr(0, found);
filename = opt_val.substr(found + 1, opt_val.size()); filename = opt_val.substr(found + 1, opt_val.size());
} }
if (plugin_name == "ic") { if (plugin_name == "ic") {
auto *ic_plugin = new iss::plugin::instruction_count(filename); auto *ic_plugin = new iss::plugin::instruction_count(filename);
vm->register_plugin(*ic_plugin); vm->register_plugin(*ic_plugin);
plugin_list.push_back(ic_plugin); plugin_list.push_back(ic_plugin);
} else if (plugin_name == "ce") { } else if (plugin_name == "ce") {
auto *ce_plugin = new iss::plugin::cycle_estimate(filename); auto *ce_plugin = new iss::plugin::cycle_estimate(filename);
vm->register_plugin(*ce_plugin); vm->register_plugin(*ce_plugin);
plugin_list.push_back(ce_plugin); plugin_list.push_back(ce_plugin);
} else if (plugin_name == "pctrace") { } else if (plugin_name == "pctrace") {
auto *plugin = new iss::plugin::cov(filename); auto *plugin = new iss::plugin::pctrace(filename);
vm->register_plugin(*plugin); vm->register_plugin(*plugin);
plugin_list.push_back(plugin); plugin_list.push_back(plugin);
} else { } else {
std::array<char const*, 1> a{{filename.c_str()}}; #ifndef WIN32
iss::plugin::loader l(plugin_name, {{"initPlugin"}}); std::array<char const*, 1> a{{filename.c_str()}};
auto* plugin = l.call_function<iss::vm_plugin*>("initPlugin", a.size(), a.data()); iss::plugin::loader l(plugin_name, {{"initPlugin"}});
if(plugin){ auto* plugin = l.call_function<iss::vm_plugin*>("initPlugin", a.size(), a.data());
vm->register_plugin(*plugin); if(plugin){
plugin_list.push_back(plugin); vm->register_plugin(*plugin);
} else { plugin_list.push_back(plugin);
} else
#endif
{
LOG(ERR) << "Unknown plugin name: " << plugin_name << ", valid names are 'ce', 'ic'" << std::endl; LOG(ERR) << "Unknown plugin name: " << plugin_name << ", valid names are 'ce', 'ic'" << std::endl;
return 127; return 127;
} }
} }
} }
} }
if (clim.count("disass")) { if (clim.count("disass")) {
vm->setDisassEnabled(true); vm->setDisassEnabled(true);
LOGGER(disass)::reporting_level() = logging::INFO; LOGGER(disass)::reporting_level() = logging::INFO;
LOGGER(disass)::print_time() = false; LOGGER(disass)::print_time() = false;
auto file_name = clim["disass"].as<std::string>(); auto file_name = clim["disass"].as<std::string>();
if (file_name.length() > 0) { if (file_name.length() > 0) {
LOG_OUTPUT(disass)::stream() = fopen(file_name.c_str(), "w"); LOG_OUTPUT(disass)::stream() = fopen(file_name.c_str(), "w");
LOGGER(disass)::print_severity() = false; LOGGER(disass)::print_severity() = false;
} }
} }
uint64_t start_address = 0; uint64_t start_address = 0;
if (clim.count("mem")) if (clim.count("mem"))
vm->get_arch()->load_file(clim["mem"].as<std::string>()); vm->get_arch()->load_file(clim["mem"].as<std::string>());
if (clim.count("elf")) if (clim.count("elf"))
for (std::string input : clim["elf"].as<std::vector<std::string>>()) { for (std::string input : clim["elf"].as<std::vector<std::string>>()) {
auto start_addr = vm->get_arch()->load_file(input); auto start_addr = vm->get_arch()->load_file(input);
if (start_addr.second) start_address = start_addr.first; if (start_addr.second) start_address = start_addr.first;
} }
for (std::string input : args) { for (std::string input : args) {
auto start_addr = vm->get_arch()->load_file(input); // treat remaining arguments as elf files auto start_addr = vm->get_arch()->load_file(input); // treat remaining arguments as elf files
if (start_addr.second) start_address = start_addr.first; if (start_addr.second) start_address = start_addr.first;
} }
if (clim.count("reset")) { if (clim.count("reset")) {
auto str = clim["reset"].as<std::string>(); auto str = clim["reset"].as<std::string>();
start_address = str.find("0x") == 0 ? std::stoull(str.substr(2), nullptr, 16) : std::stoull(str, nullptr, 10); start_address = str.find("0x") == 0 ? std::stoull(str.substr(2), nullptr, 16) : std::stoull(str, nullptr, 10);
} }
vm->reset(start_address); vm->reset(start_address);
auto cycles = clim["instructions"].as<uint64_t>(); auto cycles = clim["instructions"].as<uint64_t>();
res = vm->start(cycles, dump); res = vm->start(cycles, dump);
} catch (std::exception &e) { } catch (std::exception &e) {
LOG(ERR) << "Unhandled Exception reached the top of main: " << e.what() << ", application will now exit" LOG(ERR) << "Unhandled Exception reached the top of main: " << e.what() << ", application will now exit"
<< std::endl; << std::endl;
res = 2; res = 2;
} }
// cleanup to let plugins report of needed // cleanup to let plugins report of needed
for (auto *p : plugin_list) { for (auto *p : plugin_list) {
delete p; delete p;
} }
return res; return res;
} }

View File

@ -30,15 +30,17 @@
* *
*******************************************************************************/ *******************************************************************************/
// clang-format off // clang-format off
#include <iss/debugger/gdb_session.h> #include <iss/debugger/gdb_session.h>
#include <iss/debugger/encoderdecoder.h> #include <iss/debugger/encoderdecoder.h>
#include <iss/debugger/server.h> #include <iss/debugger/server.h>
#include <iss/debugger/target_adapter_if.h> #include <iss/debugger/target_adapter_if.h>
#include <iss/iss.h> #include <iss/iss.h>
#include <iss/vm_types.h> #include <iss/vm_types.h>
#include <iss/plugin/loader.h> #ifndef WIN32
#include <sysc/core_complex.h> #include <iss/plugin/loader.h>
#endif
#include "core_complex.h"
#include <iss/arch/tgc_mapper.h> #include <iss/arch/tgc_mapper.h>
#include <scc/report.h> #include <scc/report.h>
#include <util/ities.h> #include <util/ities.h>
@ -49,7 +51,7 @@
#include <iss/plugin/instruction_count.h> #include <iss/plugin/instruction_count.h>
#include <iss/plugin/pctrace.h> #include <iss/plugin/pctrace.h>
// clang-format on // clang-format on
#define STR(X) #X #define STR(X) #X
#define CREATE_CORE(CN) \ #define CREATE_CORE(CN) \
@ -68,12 +70,12 @@ using namespace scv_tr;
#define GET_PROP_VALUE(P) P.getValue() #define GET_PROP_VALUE(P) P.getValue()
#endif #endif
#ifdef _MSC_VER #ifdef _MSC_VER
// not #if defined(_WIN32) || defined(_WIN64) because we have strncasecmp in mingw // not #if defined(_WIN32) || defined(_WIN64) because we have strncasecmp in mingw
#define strncasecmp _strnicmp #define strncasecmp _strnicmp
#define strcasecmp _stricmp #define strcasecmp _stricmp
#endif #endif
namespace sysc { namespace sysc {
namespace tgfs { namespace tgfs {
using namespace std; using namespace std;
@ -296,7 +298,7 @@ public:
CREATE_CORE(tgc_d_xrb_nn) CREATE_CORE(tgc_d_xrb_nn)
#endif #endif
{ {
LOG(ERR) << "Illegal argument value for core type: " << type << std::endl; LOG(ERR) << "Illegal argument value for core type: " << type << std::endl;
} }
auto *srv = debugger::server<debugger::gdb_session>::get(); auto *srv = debugger::server<debugger::gdb_session>::get();
if (srv) tgt_adapter = srv->get_target(); if (srv) tgt_adapter = srv->get_target();
@ -405,10 +407,11 @@ void core_complex::before_end_of_elaboration() {
cpu->vm->register_plugin(*plugin); cpu->vm->register_plugin(*plugin);
plugin_list.push_back(plugin); plugin_list.push_back(plugin);
} else if (plugin_name == "pctrace") { } else if (plugin_name == "pctrace") {
auto *plugin = new iss::plugin::cov(filename); auto *plugin = new iss::plugin::pctrace(filename);
cpu->vm->register_plugin(*plugin); cpu->vm->register_plugin(*plugin);
plugin_list.push_back(plugin); plugin_list.push_back(plugin);
} else { } else {
#ifndef WIN32
std::array<char const*, 1> a{{filename.c_str()}}; std::array<char const*, 1> a{{filename.c_str()}};
iss::plugin::loader l(plugin_name, {{"initPlugin"}}); iss::plugin::loader l(plugin_name, {{"initPlugin"}});
auto* plugin = l.call_function<iss::vm_plugin*>("initPlugin", a.size(), a.data()); auto* plugin = l.call_function<iss::vm_plugin*>("initPlugin", a.size(), a.data());
@ -416,6 +419,7 @@ void core_complex::before_end_of_elaboration() {
cpu->vm->register_plugin(*plugin); cpu->vm->register_plugin(*plugin);
plugin_list.push_back(plugin); plugin_list.push_back(plugin);
} else } else
#endif
SCCERR(SCMOD) << "Unknown plugin '" << plugin_name << "' or plugin not found"; SCCERR(SCMOD) << "Unknown plugin '" << plugin_name << "' or plugin not found";
} }
} }

View File

@ -1 +0,0 @@
/vm_tgc_*.cpp

File diff suppressed because it is too large Load Diff

View File

@ -30,7 +30,7 @@
* *
*******************************************************************************/ *******************************************************************************/
#include <iss/arch/tgf_c.h> #include <iss/arch/tgc_c.h>
#include <iss/arch/riscv_hart_m_p.h> #include <iss/arch/riscv_hart_m_p.h>
#include <iss/debugger/gdb_session.h> #include <iss/debugger/gdb_session.h>
#include <iss/debugger/server.h> #include <iss/debugger/server.h>
@ -52,7 +52,7 @@ namespace fp_impl {
void add_fp_functions_2_module(::llvm::Module *, unsigned, unsigned); void add_fp_functions_2_module(::llvm::Module *, unsigned, unsigned);
} }
namespace tgf_c { namespace tgc_c {
using namespace ::llvm; using namespace ::llvm;
using namespace iss::arch; using namespace iss::arch;
using namespace iss::debugger; using namespace iss::debugger;
@ -4151,11 +4151,11 @@ template <typename ARCH> inline void vm_impl<ARCH>::gen_trap_check(BasicBlock *b
bb, this->trap_blk, 1); bb, this->trap_blk, 1);
} }
} // namespace tgf_c } // namespace tgc_c
template <> template <>
std::unique_ptr<vm_if> create<arch::tgf_c>(arch::tgf_c *core, unsigned short port, bool dump) { std::unique_ptr<vm_if> create<arch::tgc_c>(arch::tgc_c *core, unsigned short port, bool dump) {
auto ret = new tgf_c::vm_impl<arch::tgf_c>(*core, dump); auto ret = new tgc_c::vm_impl<arch::tgc_c>(*core, dump);
if (port != 0) debugger::server<debugger::gdb_session>::run_server(ret, port); if (port != 0) debugger::server<debugger::gdb_session>::run_server(ret, port);
return std::unique_ptr<vm_if>(ret); return std::unique_ptr<vm_if>(ret);
} }

File diff suppressed because it is too large Load Diff

View File

@ -30,7 +30,7 @@
* *
*******************************************************************************/ *******************************************************************************/
#include <iss/arch/tgf_c.h> #include <iss/arch/tgc_c.h>
#include <iss/arch/riscv_hart_m_p.h> #include <iss/arch/riscv_hart_m_p.h>
#include <iss/debugger/gdb_session.h> #include <iss/debugger/gdb_session.h>
#include <iss/debugger/server.h> #include <iss/debugger/server.h>
@ -49,7 +49,7 @@
namespace iss { namespace iss {
namespace tcc { namespace tcc {
namespace tgf_c { namespace tgc_c {
using namespace iss::arch; using namespace iss::arch;
using namespace iss::debugger; using namespace iss::debugger;
@ -3251,8 +3251,8 @@ template <typename ARCH> void vm_impl<ARCH>::gen_trap_behavior(tu_builder& tu) {
} // namespace mnrv32 } // namespace mnrv32
template <> template <>
std::unique_ptr<vm_if> create<arch::tgf_c>(arch::tgf_c *core, unsigned short port, bool dump) { std::unique_ptr<vm_if> create<arch::tgc_c>(arch::tgc_c *core, unsigned short port, bool dump) {
auto ret = new tgf_c::vm_impl<arch::tgf_c>(*core, dump); auto ret = new tgc_c::vm_impl<arch::tgc_c>(*core, dump);
if (port != 0) debugger::server<debugger::gdb_session>::run_server(ret, port); if (port != 0) debugger::server<debugger::gdb_session>::run_server(ret, port);
return std::unique_ptr<vm_if>(ret); return std::unique_ptr<vm_if>(ret);
} }

File diff suppressed because it is too large Load Diff