Compare commits
No commits in common. "c792f50427bb445106234d9efb37e8910ab1fc55" and "8a5fe58d51b6c5d7fae5953c8cf8b26bec840537" have entirely different histories.
c792f50427
...
8a5fe58d51
|
@ -153,9 +153,6 @@ if(WITH_LLVM)
|
||||||
target_compile_definitions(${PROJECT_NAME} PRIVATE WITH_LLVM)
|
target_compile_definitions(${PROJECT_NAME} PRIVATE WITH_LLVM)
|
||||||
target_link_libraries(${PROJECT_NAME} PUBLIC ${llvm_libs})
|
target_link_libraries(${PROJECT_NAME} PUBLIC ${llvm_libs})
|
||||||
endif()
|
endif()
|
||||||
if(WITH_TCC)
|
|
||||||
target_compile_definitions(${PROJECT_NAME} PRIVATE WITH_TCC)
|
|
||||||
endif()
|
|
||||||
# Links the target exe against the libraries
|
# Links the target exe against the libraries
|
||||||
target_link_libraries(${PROJECT_NAME} PUBLIC dbt-rise-tgc)
|
target_link_libraries(${PROJECT_NAME} PUBLIC dbt-rise-tgc)
|
||||||
if(TARGET Boost::program_options)
|
if(TARGET Boost::program_options)
|
||||||
|
|
|
@ -55,12 +55,10 @@ using namespace iss::debugger;
|
||||||
|
|
||||||
template <typename ARCH> class vm_impl : public iss::tcc::vm_base<ARCH> {
|
template <typename ARCH> class vm_impl : public iss::tcc::vm_base<ARCH> {
|
||||||
public:
|
public:
|
||||||
using traits = arch::traits<ARCH>;
|
|
||||||
using super = typename iss::tcc::vm_base<ARCH>;
|
using super = typename iss::tcc::vm_base<ARCH>;
|
||||||
using virt_addr_t = typename super::virt_addr_t;
|
using virt_addr_t = typename super::virt_addr_t;
|
||||||
using phys_addr_t = typename super::phys_addr_t;
|
using phys_addr_t = typename super::phys_addr_t;
|
||||||
using code_word_t = typename super::code_word_t;
|
using code_word_t = typename super::code_word_t;
|
||||||
using mem_type_e = typename traits::mem_type_e;
|
|
||||||
using addr_t = typename super::addr_t;
|
using addr_t = typename super::addr_t;
|
||||||
using tu_builder = typename super::tu_builder;
|
using tu_builder = typename super::tu_builder;
|
||||||
|
|
||||||
|
@ -84,7 +82,7 @@ protected:
|
||||||
using compile_ret_t = std::tuple<continuation_e>;
|
using compile_ret_t = std::tuple<continuation_e>;
|
||||||
using compile_func = compile_ret_t (this_class::*)(virt_addr_t &pc, code_word_t instr, tu_builder&);
|
using compile_func = compile_ret_t (this_class::*)(virt_addr_t &pc, code_word_t instr, tu_builder&);
|
||||||
|
|
||||||
inline const char *name(size_t index){return traits::reg_aliases.at(index);}
|
inline const char *name(size_t index){return traits<ARCH>::reg_aliases.at(index);}
|
||||||
|
|
||||||
void setup_module(std::string m) override {
|
void setup_module(std::string m) override {
|
||||||
super::setup_module(m);
|
super::setup_module(m);
|
||||||
|
@ -106,10 +104,10 @@ protected:
|
||||||
|
|
||||||
inline void gen_set_pc(tu_builder& tu, virt_addr_t pc, unsigned reg_num) {
|
inline void gen_set_pc(tu_builder& tu, virt_addr_t pc, unsigned reg_num) {
|
||||||
switch(reg_num){
|
switch(reg_num){
|
||||||
case traits::NEXT_PC:
|
case traits<ARCH>::NEXT_PC:
|
||||||
tu("*next_pc = {:#x};", pc.val);
|
tu("*next_pc = {:#x};", pc.val);
|
||||||
break;
|
break;
|
||||||
case traits::PC:
|
case traits<ARCH>::PC:
|
||||||
tu("*pc = {:#x};", pc.val);
|
tu("*pc = {:#x};", pc.val);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -125,7 +123,7 @@ protected:
|
||||||
// enum { MASK16 = 0b1111110001100011, MASK32 = 0b11111111111100000111000001111111 };
|
// enum { MASK16 = 0b1111110001100011, MASK32 = 0b11111111111100000111000001111111 };
|
||||||
enum { MASK16 = 0b1111111111111111, MASK32 = 0b11111111111100000111000001111111 };
|
enum { MASK16 = 0b1111111111111111, MASK32 = 0b11111111111100000111000001111111 };
|
||||||
enum { EXTR_MASK16 = MASK16 >> 2, EXTR_MASK32 = MASK32 >> 2 };
|
enum { EXTR_MASK16 = MASK16 >> 2, EXTR_MASK32 = MASK32 >> 2 };
|
||||||
enum { LUT_SIZE = 1 << util::bit_count(static_cast<uint32_t>(EXTR_MASK32)), LUT_SIZE_C = 1 << util::bit_count(static_cast<uint32_t>(EXTR_MASK16)) };
|
enum { LUT_SIZE = 1 << util::bit_count(EXTR_MASK32), LUT_SIZE_C = 1 << util::bit_count(EXTR_MASK16) };
|
||||||
|
|
||||||
std::array<compile_func, LUT_SIZE> lut;
|
std::array<compile_func, LUT_SIZE> lut;
|
||||||
|
|
||||||
|
@ -172,12 +170,6 @@ protected:
|
||||||
}
|
}
|
||||||
return lut_val;
|
return lut_val;
|
||||||
}
|
}
|
||||||
template<unsigned W, typename U, typename S = typename std::make_signed<U>::type>
|
|
||||||
inline S sext(U from) {
|
|
||||||
auto mask = (1ULL<<W) - 1;
|
|
||||||
auto sign_mask = 1ULL<<(W-1);
|
|
||||||
return (from & mask) | ((from & sign_mask) ? ~mask : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
@ -193,27 +185,14 @@ private:
|
||||||
const std::array<InstructionDesriptor, ${instructions.size}> instr_descr = {{
|
const std::array<InstructionDesriptor, ${instructions.size}> instr_descr = {{
|
||||||
/* entries are: size, valid value, valid mask, function ptr */<%instructions.each{instr -> %>
|
/* entries are: size, valid value, valid mask, function ptr */<%instructions.each{instr -> %>
|
||||||
/* instruction ${instr.instruction.name}, encoding '${instr.encoding}' */
|
/* instruction ${instr.instruction.name}, encoding '${instr.encoding}' */
|
||||||
{${instr.length}, ${instr.encoding}, ${instr.mask}, &this_class::__${generator.functionName(instr.name)}},<%}%>
|
{${instr.length}, 0b${instr.value}, 0b${instr.mask}, &this_class::__${generator.functionName(instr.name)}},<%}%>
|
||||||
}};
|
}};
|
||||||
|
|
||||||
/* instruction definitions */<%instructions.eachWithIndex{instr, idx -> %>
|
/* instruction definitions */<%instructions.eachWithIndex{instr, idx -> %>
|
||||||
/* instruction ${idx}: ${instr.name} */
|
/* instruction ${idx}: ${instr.name} */
|
||||||
compile_ret_t __${generator.functionName(instr.name)}(virt_addr_t& pc, code_word_t instr, tu_builder& tu){
|
compile_ret_t __${generator.functionName(instr.name)}(virt_addr_t& pc, code_word_t instr, tu_builder& tu){<%instr.code.eachLine{%>
|
||||||
tu("${instr.name}_{:#010x}:", pc.val);
|
|
||||||
vm_base<ARCH>::gen_sync(tu, PRE_SYNC,${idx});
|
|
||||||
<%instr.fields.eachLine{%>${it}
|
|
||||||
<%}%>if(this->disass_enabled){
|
|
||||||
/* generate console output when executing the command */<%instr.disass.eachLine{%>
|
|
||||||
${it}<%}%>
|
${it}<%}%>
|
||||||
}
|
}
|
||||||
auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]);
|
|
||||||
pc=pc+4;
|
|
||||||
tu.open_scope();<%instr.behavior.eachLine{%>
|
|
||||||
${it}<%}%>
|
|
||||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,${idx});
|
|
||||||
gen_trap_check(tu);
|
|
||||||
return returnValue;
|
|
||||||
}
|
|
||||||
<%}%>
|
<%}%>
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* end opcode definitions
|
* end opcode definitions
|
||||||
|
@ -254,7 +233,7 @@ vm_impl<ARCH>::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt,
|
||||||
// we fetch at max 4 byte, alignment is 2
|
// we fetch at max 4 byte, alignment is 2
|
||||||
enum {TRAP_ID=1<<16};
|
enum {TRAP_ID=1<<16};
|
||||||
code_word_t insn = 0;
|
code_word_t insn = 0;
|
||||||
const typename traits::addr_t upper_bits = ~traits::PGMASK;
|
const typename traits<ARCH>::addr_t upper_bits = ~traits<ARCH>::PGMASK;
|
||||||
phys_addr_t paddr(pc);
|
phys_addr_t paddr(pc);
|
||||||
auto *const data = (uint8_t *)&insn;
|
auto *const data = (uint8_t *)&insn;
|
||||||
paddr = this->core.v2p(pc);
|
paddr = this->core.v2p(pc);
|
||||||
|
@ -281,13 +260,13 @@ vm_impl<ARCH>::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt,
|
||||||
|
|
||||||
template <typename ARCH> void vm_impl<ARCH>::gen_raise_trap(tu_builder& tu, uint16_t trap_id, uint16_t cause) {
|
template <typename ARCH> void vm_impl<ARCH>::gen_raise_trap(tu_builder& tu, uint16_t trap_id, uint16_t cause) {
|
||||||
tu(" *trap_state = {:#x};", 0x80 << 24 | (cause << 16) | trap_id);
|
tu(" *trap_state = {:#x};", 0x80 << 24 | (cause << 16) | trap_id);
|
||||||
tu.store(traits::LAST_BRANCH, tu.constant(std::numeric_limits<uint32_t>::max(), 32));
|
tu.store(tu.constant(std::numeric_limits<uint32_t>::max(), 32),traits<ARCH>::LAST_BRANCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ARCH> void vm_impl<ARCH>::gen_leave_trap(tu_builder& tu, unsigned lvl) {
|
template <typename ARCH> void vm_impl<ARCH>::gen_leave_trap(tu_builder& tu, unsigned lvl) {
|
||||||
tu("leave_trap(core_ptr, {});", lvl);
|
tu("leave_trap(core_ptr, {});", lvl);
|
||||||
tu.store(traits::NEXT_PC, tu.read_mem(traits::CSR, (lvl << 8) + 0x41, traits::XLEN));
|
tu.store(tu.read_mem(traits<ARCH>::CSR, (lvl << 8) + 0x41, traits<ARCH>::XLEN),traits<ARCH>::NEXT_PC);
|
||||||
tu.store(traits::LAST_BRANCH, tu.constant(std::numeric_limits<uint32_t>::max(), 32));
|
tu.store(tu.constant(std::numeric_limits<uint32_t>::max(), 32),traits<ARCH>::LAST_BRANCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ARCH> void vm_impl<ARCH>::gen_wait(tu_builder& tu, unsigned type) {
|
template <typename ARCH> void vm_impl<ARCH>::gen_wait(tu_builder& tu, unsigned type) {
|
||||||
|
@ -295,8 +274,8 @@ template <typename ARCH> void vm_impl<ARCH>::gen_wait(tu_builder& tu, unsigned t
|
||||||
|
|
||||||
template <typename ARCH> void vm_impl<ARCH>::gen_trap_behavior(tu_builder& tu) {
|
template <typename ARCH> void vm_impl<ARCH>::gen_trap_behavior(tu_builder& tu) {
|
||||||
tu("trap_entry:");
|
tu("trap_entry:");
|
||||||
tu("enter_trap(core_ptr, *trap_state, *pc, 0);");
|
tu("enter_trap(core_ptr, *trap_state, *pc);");
|
||||||
tu.store(traits::LAST_BRANCH, tu.constant(std::numeric_limits<uint32_t>::max(),32));
|
tu.store(tu.constant(std::numeric_limits<uint32_t>::max(),32),traits<ARCH>::LAST_BRANCH);
|
||||||
tu("return *next_pc;");
|
tu("return *next_pc;");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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, PGMASK=0b111111111111, XLEN=32, INSTR_ALIGNMENT=2, RFS=32, fence=0, fencei=1, fencevmal=2, fencevmau=3, CSR_SIZE=4096, 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;
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ std::tuple<cpu_ptr, vm_ptr> create_cpu(std::string const& backend, unsigned gdb_
|
||||||
if(backend == "llvm")
|
if(backend == "llvm")
|
||||||
return {cpu_ptr{lcpu}, vm_ptr{iss::llvm::create(lcpu, gdb_port)}};
|
return {cpu_ptr{lcpu}, vm_ptr{iss::llvm::create(lcpu, gdb_port)}};
|
||||||
#endif
|
#endif
|
||||||
#ifdef WITH_TCC
|
#ifdef WITH_LLVM
|
||||||
if(backend == "tcc")
|
if(backend == "tcc")
|
||||||
return {cpu_ptr{lcpu}, vm_ptr{iss::tcc::create(lcpu, gdb_port)}};
|
return {cpu_ptr{lcpu}, vm_ptr{iss::tcc::create(lcpu, gdb_port)}};
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -162,11 +162,11 @@ int main(int argc, char *argv[]) {
|
||||||
return 127;
|
return 127;
|
||||||
}
|
}
|
||||||
if(!cpu ){
|
if(!cpu ){
|
||||||
LOG(ERR) << "Could not create cpu for isa " << isa_opt << " and backend " <<clim["backend"].as<std::string>()<< std::endl;
|
LOG(ERR) << "Could not create cpu fore for isa " << isa_opt << " and backend " <<clim["backend"].as<std::string>()<< std::endl;
|
||||||
return 127;
|
return 127;
|
||||||
}
|
}
|
||||||
if(!vm ){
|
if(!vm ){
|
||||||
LOG(ERR) << "Could not create vm for isa " << isa_opt << " and backend " <<clim["backend"].as<std::string>()<< std::endl;
|
LOG(ERR) << "Could not create vm fore for isa " << isa_opt << " and backend " <<clim["backend"].as<std::string>()<< std::endl;
|
||||||
return 127;
|
return 127;
|
||||||
}
|
}
|
||||||
if (clim.count("plugin")) {
|
if (clim.count("plugin")) {
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue