From 250ea3c980772ae7dd33c9082575c5d32a38f6fa Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Thu, 6 Jul 2023 08:02:48 +0200 Subject: [PATCH] extends factory to support SystemC core wrapper --- CMakeLists.txt | 5 +- gen_input/templates/CORENAME.h.gtl | 2 +- gen_input/templates/interp/CORENAME.cpp.gtl | 30 +++- gen_input/templates/tcc/CORENAME.cpp.gtl | 30 +++- src/iss/arch/tgc_c.h | 2 +- src/iss/factory.h | 48 +++++++ src/main.cpp | 59 ++------ src/sysc/register_tgc_c.cpp | 33 +++++ src/sysc/sc_core_adapter.h | 148 ++++++++++++++++++++ src/vm/interp/vm_tgc_c.cpp | 49 +++++-- src/vm/tcc/vm_tgc_c.cpp | 49 +++++-- 11 files changed, 380 insertions(+), 75 deletions(-) create mode 100644 src/sysc/register_tgc_c.cpp create mode 100644 src/sysc/sc_core_adapter.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 2a36dad..c79d882 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -186,7 +186,10 @@ install(TARGETS tgc-sim ############################################################################### if(TARGET scc-sysc) project(dbt-rise-tgc_sc VERSION 1.0.0) - add_library(${PROJECT_NAME} src/sysc/core_complex.cpp) + add_library(${PROJECT_NAME} + src/sysc/core_complex.cpp + src/sysc/register_tgc_c.cpp + ) target_compile_definitions(${PROJECT_NAME} PUBLIC WITH_SYSTEMC) target_compile_definitions(${PROJECT_NAME} PRIVATE CORE_${CORE_NAME}) foreach(F IN LISTS TGC_SOURCES) diff --git a/gen_input/templates/CORENAME.h.gtl b/gen_input/templates/CORENAME.h.gtl index 83fb8e1..45a3ed7 100644 --- a/gen_input/templates/CORENAME.h.gtl +++ b/gen_input/templates/CORENAME.h.gtl @@ -111,7 +111,7 @@ template <> struct traits<${coreDef.name.toLowerCase()}> { enum mem_type_e { ${spaces.collect{it.name}.join(', ')} }; - enum class opcode_e : unsigned short {<%instructions.eachWithIndex{instr, index -> %> + enum class opcode_e {<%instructions.eachWithIndex{instr, index -> %> ${instr.instruction.name} = ${index},<%}%> MAX_OPCODE }; diff --git a/gen_input/templates/interp/CORENAME.cpp.gtl b/gen_input/templates/interp/CORENAME.cpp.gtl index acf7afd..cc864d8 100644 --- a/gen_input/templates/interp/CORENAME.cpp.gtl +++ b/gen_input/templates/interp/CORENAME.cpp.gtl @@ -34,10 +34,9 @@ def nativeTypeSize(int size){ if(size<=8) return 8; else if(size<=16) return 16; else if(size<=32) return 32; else return 64; } %> +#include #include #include -#include -#include #include #include #include @@ -315,3 +314,30 @@ std::unique_ptr create(arch::${coreD } } // namespace interp } // namespace iss + +#include +#include +#include +namespace iss { +namespace { +std::array dummy = { + core_factory::instance().register_creator("${coreDef.name.toLowerCase()}|m_p|interp", [](unsigned port, void*) -> std::tuple{ + auto* cpu = new iss::arch::riscv_hart_m_p(); + auto vm = new interp::${coreDef.name.toLowerCase()}::vm_impl(*cpu, false); + if (port != 0) debugger::server::run_server(vm, port); + return {cpu_ptr{cpu}, vm_ptr{vm}}; + }), + core_factory::instance().register_creator("${coreDef.name.toLowerCase()}|mu_p|interp", [](unsigned port, void*) -> std::tuple{ + auto* cpu = new iss::arch::riscv_hart_mu_p(); + auto vm = new interp::${coreDef.name.toLowerCase()}::vm_impl(*cpu, false); + if (port != 0) debugger::server::run_server(vm, port); + return {cpu_ptr{cpu}, vm_ptr{vm}}; + }) +}; +} +} +extern "C" { + bool* get_${coreDef.name.toLowerCase()}_interp_creators() { + return iss::dummy.data(); + } +} \ No newline at end of file diff --git a/gen_input/templates/tcc/CORENAME.cpp.gtl b/gen_input/templates/tcc/CORENAME.cpp.gtl index b7cec56..afb3e38 100644 --- a/gen_input/templates/tcc/CORENAME.cpp.gtl +++ b/gen_input/templates/tcc/CORENAME.cpp.gtl @@ -31,7 +31,6 @@ *******************************************************************************/ #include -#include #include #include #include @@ -310,5 +309,32 @@ std::unique_ptr create(arch::${coreD if (port != 0) debugger::server::run_server(ret, port); return std::unique_ptr(ret); } -} +} // namesapce tcc } // namespace iss + +#include +#include +#include +namespace iss { +namespace { +std::array dummy = { + core_factory::instance().register_creator("${coreDef.name.toLowerCase()}|m_p|tcc", [](unsigned port, void*) -> std::tuple{ + auto* cpu = new iss::arch::riscv_hart_m_p(); + auto vm = new tcc::${coreDef.name.toLowerCase()}::vm_impl(*cpu, false); + if (port != 0) debugger::server::run_server(vm, port); + return {cpu_ptr{cpu}, vm_ptr{vm}}; + }), + core_factory::instance().register_creator("${coreDef.name.toLowerCase()}|mu_p|tcc", [](unsigned port, void*) -> std::tuple{ + auto* cpu = new iss::arch::riscv_hart_mu_p(); + auto vm = new tcc::${coreDef.name.toLowerCase()}::vm_impl(*cpu, false); + if (port != 0) debugger::server::run_server(vm, port); + return {cpu_ptr{cpu}, vm_ptr{vm}}; + }) +}; +} +} +extern "C" { + bool* get_${coreDef.name.toLowerCase()}_tcc_creators() { + return iss::dummy.data(); + } +} \ No newline at end of file diff --git a/src/iss/arch/tgc_c.h b/src/iss/arch/tgc_c.h index f0d53f3..611ef79 100644 --- a/src/iss/arch/tgc_c.h +++ b/src/iss/arch/tgc_c.h @@ -83,7 +83,7 @@ template <> struct traits { enum mem_type_e { MEM, FENCE, RES, CSR }; - enum class opcode_e : unsigned short { + enum class opcode_e { LUI = 0, AUIPC = 1, JAL = 2, diff --git a/src/iss/factory.h b/src/iss/factory.h index 0d43538..7e45838 100644 --- a/src/iss/factory.h +++ b/src/iss/factory.h @@ -34,6 +34,12 @@ #define _ISS_FACTORY_H_ #include +#include +#include +#include +#include +#include +#include namespace iss { @@ -57,6 +63,48 @@ std::tuple create_cpu(std::string const& backend, unsigned gdb_ return {nullptr, nullptr}; } + +class core_factory { + using cpu_ptr = std::unique_ptr; + using vm_ptr= std::unique_ptr; + using base_t = std::tuple; + using create_fn = std::function; + using registry_t = std::unordered_map ; + + registry_t registry; + + core_factory() = default; + core_factory(const core_factory &) = delete; + core_factory & operator=(const core_factory &) = delete; + +public: + static core_factory & instance() { static core_factory bf; return bf; } + + bool register_creator(const std::string &, create_fn const&); + + base_t create(const std::string &, unsigned gdb_port=0, void* init_data=nullptr) const; + + std::vector get_names() { + std::vector keys{registry.size()}; + std::transform(std::begin(registry), std::end(registry), std::begin(keys), [](std::pair const& p){ + return p.first; + }); + return keys; + } +}; + +inline bool core_factory::register_creator(const std::string & className, create_fn const& fn) { + registry[className] = fn; + return true; +} + +inline core_factory::base_t core_factory::create(const std::string &className, unsigned gdb_port, void* data) const { + registry_t::const_iterator regEntry = registry.find(className); + if (regEntry != registry.end()) + return regEntry->second(gdb_port, data); + return {nullptr, nullptr}; +} + } #endif /* _ISS_FACTORY_H_ */ diff --git a/src/main.cpp b/src/main.cpp index 5aeb3f8..02ec210 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -33,7 +33,7 @@ #include #include #include -#include "iss/factory.h" +#include #include #include @@ -113,53 +113,24 @@ int main(int argc, char *argv[]) { iss::init_jit_debug(argc, argv); #endif bool dump = clim.count("dump-ir"); + auto & f = iss::core_factory::instance(); // instantiate the simulator iss::vm_ptr vm{nullptr}; iss::cpu_ptr cpu{nullptr}; std::string isa_opt(clim["isa"].as()); - if (isa_opt == "tgc_c") { - std::tie(cpu, vm) = - iss::create_cpu(clim["backend"].as(), clim["gdb-port"].as()); - } else -#ifdef CORE_TGC_B - if (isa_opt == "tgc_b") { - std::tie(cpu, vm) = - iss::create_cpu(clim["backend"].as(), clim["gdb-port"].as()); - } else -#endif -#ifdef CORE_TGC_C_XRB_NN - if (isa_opt == "tgc_c_xrb_nn") { - std::tie(cpu, vm) = - iss::create_cpu(clim["backend"].as(), clim["gdb-port"].as()); - } else -#endif -#ifdef CORE_TGC_D - if (isa_opt == "tgc_d") { - std::tie(cpu, vm) = - iss::create_cpu(clim["backend"].as(), clim["gdb-port"].as()); - } else -#endif -#ifdef CORE_TGC_D_XRB_MAC - if (isa_opt == "tgc_d_xrb_mac") { - std::tie(cpu, vm) = - iss::create_cpu(clim["backend"].as(), clim["gdb-port"].as()); - } else -#endif -#ifdef CORE_TGC_D_XRB_NN - if (isa_opt == "tgc_d_xrb_nn") { - std::tie(cpu, vm) = - iss::create_cpu(clim["backend"].as(), clim["gdb-port"].as()); - } else -#endif -#ifdef CORE_TGC_E - if (isa_opt == "tgc_e") { - std::tie(cpu, vm) = - iss::create_cpu(clim["backend"].as(), clim["gdb-port"].as()); - } else -#endif - { - LOG(ERR) << "Illegal argument value for '--isa': " << isa_opt << std::endl; - return 127; + if(isa_opt.size()==0 || isa_opt == "?") { + std::cout<<"Available cores: "<(), clim["gdb-port"].as()); + } else { + auto base_isa = isa_opt.substr(0, 5); + if(base_isa=="tgc_d" || base_isa=="tgc_e") { + isa_opt += "|mu_p_clic_pmp|"+clim["backend"].as(); + } else { + isa_opt += "|m_p|"+clim["backend"].as(); + } + std::tie(cpu, vm) = f.create(isa_opt, clim["gdb-port"].as()); } if(!cpu ){ LOG(ERR) << "Could not create cpu for isa " << isa_opt << " and backend " <()<< std::endl; diff --git a/src/sysc/register_tgc_c.cpp b/src/sysc/register_tgc_c.cpp new file mode 100644 index 0000000..2394afe --- /dev/null +++ b/src/sysc/register_tgc_c.cpp @@ -0,0 +1,33 @@ +/* + * register_tgc_c.cpp + * + * Created on: Jul 5, 2023 + * Author: eyck + */ + + + + +#include +#include +#include +#include +#include "sc_core_adapter.h" +#include "core_complex.h" + +namespace iss { +namespace { +volatile std::array dummy = { + core_factory::instance().register_creator("tgc_c|m_p|interp", [](unsigned gdb_port, void* data) -> std::tuple{ + auto cc = reinterpret_cast(data); + arch::tgc_c* lcpu = new sc_core_adapter>(cc); + return {cpu_ptr{lcpu}, vm_ptr{interp::create(lcpu, gdb_port)}}; + }), + core_factory::instance().register_creator("tgc_c|mu_p|interp", [](unsigned gdb_port, void* data) -> std::tuple{ + auto cc = reinterpret_cast(data); + arch::tgc_c* lcpu = new sc_core_adapter>(cc); + return {cpu_ptr{lcpu}, vm_ptr{interp::create(lcpu, gdb_port)}}; + }) +}; +} +} diff --git a/src/sysc/sc_core_adapter.h b/src/sysc/sc_core_adapter.h new file mode 100644 index 0000000..baaa43b --- /dev/null +++ b/src/sysc/sc_core_adapter.h @@ -0,0 +1,148 @@ +/* + * sc_core_adapter.h + * + * Created on: Jul 5, 2023 + * Author: eyck + */ + +#ifndef _SYSC_SC_CORE_ADAPTER_H_ +#define _SYSC_SC_CORE_ADAPTER_H_ + + +#include +#include +#include "core_complex.h" +#include +#include +#include + + +template +class sc_core_adapter : public PLAT { +public: + using reg_t = typename iss::arch::traits::reg_t; + using phys_addr_t = typename iss::arch::traits::phys_addr_t; + using heart_state_t = typename PLAT::hart_state_type; + sc_core_adapter(sysc::tgfs::core_complex *owner) + : owner(owner) { } + + uint32_t get_mode() { return this->reg.PRIV; } + + inline void set_interrupt_execution(bool v) { this->interrupt_sim = v?1:0; } + + inline bool get_interrupt_execution() { return this->interrupt_sim; } + + heart_state_t &get_state() { return this->state; } + + void notify_phase(iss::arch_if::exec_phase p) override { + if (p == iss::arch_if::ISTART) + owner->sync(this->instr_if.get_total_cycles()); + } + + iss::sync_type needed_sync() const override { return iss::PRE_SYNC; } + + void disass_output(uint64_t pc, const std::string instr) override { + static constexpr std::array lvl = {{'U', 'S', 'H', 'M'}}; + if (!owner->disass_output(pc, instr)) { + std::stringstream s; + s << "[p:" << lvl[this->reg.PRIV] << ";s:0x" << std::hex << std::setfill('0') + << std::setw(sizeof(reg_t) * 2) << (reg_t)this->state.mstatus << std::dec << ";c:" + << this->reg.icount + this->cycle_offset << "]"; + SCCDEBUG(owner->name())<<"disass: " + << "0x" << std::setw(16) << std::right << std::setfill('0') << std::hex << pc << "\t\t" << std::setw(40) + << std::setfill(' ') << std::left << instr << s.str(); + } + }; + + iss::status read_mem(phys_addr_t addr, unsigned length, uint8_t *const data) override { + if (addr.access && iss::access_type::DEBUG) + return owner->read_mem_dbg(addr.val, length, data) ? iss::Ok : iss::Err; + else { + return owner->read_mem(addr.val, length, data, is_fetch(addr.access)) ? iss::Ok : iss::Err; + } + } + + iss::status write_mem(phys_addr_t addr, unsigned length, const uint8_t *const data) override { + if (addr.access && iss::access_type::DEBUG) + return owner->write_mem_dbg(addr.val, length, data) ? iss::Ok : iss::Err; + else { + auto res = owner->write_mem(addr.val, length, data) ? iss::Ok : iss::Err; + // clear MTIP on mtimecmp write + if (addr.val == 0x2004000) { + reg_t val; + this->read_csr(iss::arch::mip, val); + if (val & (1ULL << 7)) this->write_csr(iss::arch::mip, val & ~(1ULL << 7)); + } + return res; + } + } + + iss::status read_csr(unsigned addr, reg_t &val) override { +#ifndef CWR_SYSTEMC + if((addr==iss::arch::time || addr==iss::arch::timeh) && owner->mtime_o.get_interface(0)){ + uint64_t time_val; + bool ret = owner->mtime_o->nb_peek(time_val); + if (addr == iss::arch::time) { + val = static_cast(time_val); + } else if (addr == iss::arch::timeh) { + if (sizeof(reg_t) != 4) return iss::Err; + val = static_cast(time_val >> 32); + } + return ret?Ok:Err; +#else + if((addr==iss::arch::time || addr==iss::arch::timeh)){ + uint64_t time_val = owner->mtime_i.read(); + if (addr == iss::arch::time) { + val = static_cast(time_val); + } else if (addr == iss::arch::timeh) { + if (sizeof(reg_t) != 4) return iss::Err; + val = static_cast(time_val >> 32); + } + return iss::Ok; +#endif + } else { + return PLAT::read_csr(addr, val); + } + } + + void wait_until(uint64_t flags) override { + SCCDEBUG(owner->name()) << "Sleeping until interrupt"; + while(this->reg.pending_trap == 0 && (this->csr[iss::arch::mip] & this->csr[iss::arch::mie]) == 0) { + sc_core::wait(wfi_evt); + } + PLAT::wait_until(flags); + } + + void local_irq(short id, bool value) { + reg_t mask = 0; + switch (id) { + case 3: // SW + mask = 1 << 3; + break; + case 7: // timer + mask = 1 << 7; + break; + case 11: // external + mask = 1 << 11; + break; + default: + if(id>15) mask = 1 << id; + break; + } + if (value) { + this->csr[iss::arch::mip] |= mask; + wfi_evt.notify(); + } else + this->csr[iss::arch::mip] &= ~mask; + this->check_interrupt(); + if(value) + SCCTRACE(owner->name()) << "Triggering interrupt " << id << " Pending trap: " << this->reg.pending_trap; + } + +private: + sysc::tgfs::core_complex *const owner; + sc_event wfi_evt; +}; + + +#endif /* _SYSC_SC_CORE_ADAPTER_H_ */ diff --git a/src/vm/interp/vm_tgc_c.cpp b/src/vm/interp/vm_tgc_c.cpp index c94b716..cfda6fe 100644 --- a/src/vm/interp/vm_tgc_c.cpp +++ b/src/vm/interp/vm_tgc_c.cpp @@ -30,10 +30,9 @@ * *******************************************************************************/ +#include #include #include -#include -#include #include #include #include @@ -1731,7 +1730,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co raise(0, 2); } else { - int64_t res = (int32_t)*(X+rs1) * (int32_t)*(X+rs2); + int64_t res = (int64_t)((int64_t)(int32_t)*(X+rs1) * (int64_t)(int32_t)*(X+rs2)); if(rd != 0) { *(X+rd) = (uint32_t)res; } @@ -1759,7 +1758,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co raise(0, 2); } else { - int64_t res = (int32_t)*(X+rs1) * (int32_t)*(X+rs2); + int64_t res = (int64_t)((int64_t)(int32_t)*(X+rs1) * (int64_t)(int32_t)*(X+rs2)); if(rd != 0) { *(X+rd) = (uint32_t)(res >> traits::XLEN); } @@ -1787,7 +1786,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co raise(0, 2); } else { - int64_t res = (int32_t)*(X+rs1) * *(X+rs2); + int64_t res = (int64_t)((int64_t)(int32_t)*(X+rs1) * (uint64_t)*(X+rs2)); if(rd != 0) { *(X+rd) = (uint32_t)(res >> traits::XLEN); } @@ -1815,7 +1814,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co raise(0, 2); } else { - uint64_t res = *(X+rs1) * *(X+rs2); + uint64_t res = (uint64_t)((uint64_t)*(X+rs1) * (uint64_t)*(X+rs2)); if(rd != 0) { *(X+rd) = (uint32_t)(res >> traits::XLEN); } @@ -2013,8 +2012,8 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 2; // execute instruction { - uint32_t load_address = (uint32_t)(*(X+rs1 + 8) + uimm); - int32_t read_res = super::template read_mem(traits::MEM, load_address); + uint32_t offs = (uint32_t)(*(X+rs1 + 8) + uimm); + int32_t read_res = super::template read_mem(traits::MEM, offs); if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CLW; *(X+rd + 8) = (uint32_t)(int32_t)read_res; } @@ -2036,8 +2035,8 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 2; // execute instruction { - uint32_t load_address = (uint32_t)(*(X+rs1 + 8) + uimm); - super::template write_mem(traits::MEM, load_address, (uint32_t)*(X+rs2 + 8)); + uint32_t offs = (uint32_t)(*(X+rs1 + 8) + uimm); + super::template write_mem(traits::MEM, offs, (uint32_t)*(X+rs2 + 8)); if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CSW; } TRAP_CSW:break; @@ -2438,8 +2437,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co uint32_t offs = (uint32_t)(*(X+2) + uimm); int32_t read_res = super::template read_mem(traits::MEM, offs); if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CLWSP; - int32_t res = (int32_t)read_res; - *(X+rd) = (uint32_t)res; + *(X+rd) = (uint32_t)(int32_t)read_res; } } TRAP_CLWSP:break; @@ -2647,3 +2645,30 @@ std::unique_ptr create(arch::tgc_c *core, unsigned short por } } // namespace interp } // namespace iss + +#include +#include +#include +namespace iss { +namespace { +std::array dummy = { + core_factory::instance().register_creator("tgc_c|m_p|interp", [](unsigned port, void*) -> std::tuple{ + auto* cpu = new iss::arch::riscv_hart_m_p(); + auto vm = new interp::tgc_c::vm_impl(*cpu, false); + if (port != 0) debugger::server::run_server(vm, port); + return {cpu_ptr{cpu}, vm_ptr{vm}}; + }), + core_factory::instance().register_creator("tgc_c|mu_p|interp", [](unsigned port, void*) -> std::tuple{ + auto* cpu = new iss::arch::riscv_hart_mu_p(); + auto vm = new interp::tgc_c::vm_impl(*cpu, false); + if (port != 0) debugger::server::run_server(vm, port); + return {cpu_ptr{cpu}, vm_ptr{vm}}; + }) +}; +} +} +extern "C" { + bool* get_tgc_c_interp_creators() { + return iss::dummy.data(); + } +} \ No newline at end of file diff --git a/src/vm/tcc/vm_tgc_c.cpp b/src/vm/tcc/vm_tgc_c.cpp index 495d97e..b760efa 100644 --- a/src/vm/tcc/vm_tgc_c.cpp +++ b/src/vm/tcc/vm_tgc_c.cpp @@ -31,7 +31,6 @@ *******************************************************************************/ #include -#include #include #include #include @@ -2024,7 +2023,7 @@ private: this->gen_raise_trap(tu, 0, 2); } else{ - auto res = tu.assignment(tu.mul(tu.ext(tu.load(rs1+ traits::X0, 0),32,false),tu.ext(tu.load(rs2+ traits::X0, 0),32,false)),64); + auto res = tu.assignment(tu.ext((tu.mul(tu.ext(tu.ext(tu.load(rs1+ traits::X0, 0),32,true),64,false),tu.ext(tu.ext(tu.load(rs2+ traits::X0, 0),32,true),64,false))),64,false),64); if(rd!=0) { tu.store(rd + traits::X0,tu.ext(res,32,true)); } @@ -2058,7 +2057,7 @@ private: this->gen_raise_trap(tu, 0, 2); } else{ - auto res = tu.assignment(tu.mul(tu.ext(tu.load(rs1+ traits::X0, 0),32,false),tu.ext(tu.load(rs2+ traits::X0, 0),32,false)),64); + auto res = tu.assignment(tu.ext((tu.mul(tu.ext(tu.ext(tu.load(rs1+ traits::X0, 0),32,true),64,false),tu.ext(tu.ext(tu.load(rs2+ traits::X0, 0),32,true),64,false))),64,false),64); if(rd!=0) { tu.store(rd + traits::X0,tu.ext((tu.lshr(res,tu.constant(static_cast(traits:: XLEN),32))),32,true)); } @@ -2092,7 +2091,7 @@ private: this->gen_raise_trap(tu, 0, 2); } else{ - auto res = tu.assignment(tu.mul(tu.ext(tu.load(rs1+ traits::X0, 0),32,false),tu.load(rs2+ traits::X0, 0)),64); + auto res = tu.assignment(tu.ext((tu.mul(tu.ext(tu.ext(tu.load(rs1+ traits::X0, 0),32,true),64,false),tu.ext(tu.load(rs2+ traits::X0, 0),64,true))),64,false),64); if(rd!=0) { tu.store(rd + traits::X0,tu.ext((tu.lshr(res,tu.constant(static_cast(traits:: XLEN),32))),32,true)); } @@ -2126,7 +2125,7 @@ private: this->gen_raise_trap(tu, 0, 2); } else{ - auto res = tu.assignment(tu.mul(tu.load(rs1+ traits::X0, 0),tu.load(rs2+ traits::X0, 0)),64); + auto res = tu.assignment(tu.ext((tu.mul(tu.ext(tu.load(rs1+ traits::X0, 0),64,true),tu.ext(tu.load(rs2+ traits::X0, 0),64,true))),64,true),64); if(rd!=0) { tu.store(rd + traits::X0,tu.ext((tu.lshr(res,tu.constant(static_cast(traits:: XLEN),32))),32,true)); } @@ -2353,8 +2352,8 @@ private: pc=pc+ 2; gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); - auto load_address = tu.assignment(tu.ext((tu.add(tu.load(rs1+ 8+ traits::X0, 0),tu.constant(uimm,8))),32,true),32); - tu.store(rd+ 8 + traits::X0,tu.ext(tu.ext(tu.read_mem(traits::MEM, load_address, 32),32,false),32,true)); + auto offs = tu.assignment(tu.ext((tu.add(tu.load(rs1+ 8+ traits::X0, 0),tu.constant(uimm,8))),32,true),32); + tu.store(rd+ 8 + traits::X0,tu.ext(tu.ext(tu.read_mem(traits::MEM, offs, 32),32,false),32,true)); auto returnValue = std::make_tuple(CONT); tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,58); @@ -2380,8 +2379,8 @@ private: pc=pc+ 2; gen_set_pc(tu, pc, traits::NEXT_PC); tu.open_scope(); - auto load_address = tu.assignment(tu.ext((tu.add(tu.load(rs1+ 8+ traits::X0, 0),tu.constant(uimm,8))),32,true),32); - tu.write_mem(traits::MEM, load_address, tu.ext(tu.load(rs2+ 8+ traits::X0, 0),32,true)); + auto offs = tu.assignment(tu.ext((tu.add(tu.load(rs1+ 8+ traits::X0, 0),tu.constant(uimm,8))),32,true),32); + tu.write_mem(traits::MEM, offs, tu.ext(tu.load(rs2+ 8+ traits::X0, 0),32,true)); auto returnValue = std::make_tuple(CONT); tu.close_scope(); vm_base::gen_sync(tu, POST_SYNC,59); @@ -2898,8 +2897,7 @@ private: } else{ auto offs = tu.assignment(tu.ext((tu.add(tu.load(2+ traits::X0, 0),tu.constant(uimm,8))),32,true),32); - auto res = tu.assignment(tu.ext(tu.read_mem(traits::MEM, offs, 32),32,false),32); - tu.store(rd + traits::X0,tu.ext(res,32,true)); + tu.store(rd + traits::X0,tu.ext(tu.ext(tu.read_mem(traits::MEM, offs, 32),32,false),32,true)); } auto returnValue = std::make_tuple(CONT); tu.close_scope(); @@ -3220,5 +3218,32 @@ std::unique_ptr create(arch::tgc_c *core, unsigned short por if (port != 0) debugger::server::run_server(ret, port); return std::unique_ptr(ret); } -} +} // namesapce tcc } // namespace iss + +#include +#include +#include +namespace iss { +namespace { +std::array dummy = { + core_factory::instance().register_creator("tgc_c|m_p|tcc", [](unsigned port, void*) -> std::tuple{ + auto* cpu = new iss::arch::riscv_hart_m_p(); + auto vm = new tcc::tgc_c::vm_impl(*cpu, false); + if (port != 0) debugger::server::run_server(vm, port); + return {cpu_ptr{cpu}, vm_ptr{vm}}; + }), + core_factory::instance().register_creator("tgc_c|mu_p|tcc", [](unsigned port, void*) -> std::tuple{ + auto* cpu = new iss::arch::riscv_hart_mu_p(); + auto vm = new tcc::tgc_c::vm_impl(*cpu, false); + if (port != 0) debugger::server::run_server(vm, port); + return {cpu_ptr{cpu}, vm_ptr{vm}}; + }) +}; +} +} +extern "C" { + bool* get_tgc_c_tcc_creators() { + return iss::dummy.data(); + } +} \ No newline at end of file