From 250ea3c980772ae7dd33c9082575c5d32a38f6fa Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Thu, 6 Jul 2023 08:02:48 +0200 Subject: [PATCH 01/13] 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 From e95f422aabf33b15ae5ff569711f057a115ba9bd Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Sun, 9 Jul 2023 20:13:26 +0200 Subject: [PATCH 02/13] cleans vm implementation up --- gen_input/templates/interp/CORENAME.cpp.gtl | 7 +------ gen_input/templates/tcc/CORENAME.cpp.gtl | 7 +------ src/vm/interp/vm_tgc_c.cpp | 8 ++------ src/vm/tcc/vm_tgc_c.cpp | 7 +------ 4 files changed, 5 insertions(+), 24 deletions(-) diff --git a/gen_input/templates/interp/CORENAME.cpp.gtl b/gen_input/templates/interp/CORENAME.cpp.gtl index cc864d8..cd84028 100644 --- a/gen_input/templates/interp/CORENAME.cpp.gtl +++ b/gen_input/templates/interp/CORENAME.cpp.gtl @@ -320,7 +320,7 @@ std::unique_ptr create(arch::${coreD #include namespace iss { namespace { -std::array dummy = { +volatile 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); @@ -336,8 +336,3 @@ std::array dummy = { }; } } -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 afb3e38..f7a2baf 100644 --- a/gen_input/templates/tcc/CORENAME.cpp.gtl +++ b/gen_input/templates/tcc/CORENAME.cpp.gtl @@ -317,7 +317,7 @@ std::unique_ptr create(arch::${coreD #include namespace iss { namespace { -std::array dummy = { +volatile 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); @@ -333,8 +333,3 @@ std::array dummy = { }; } } -extern "C" { - bool* get_${coreDef.name.toLowerCase()}_tcc_creators() { - return iss::dummy.data(); - } -} \ No newline at end of file diff --git a/src/vm/interp/vm_tgc_c.cpp b/src/vm/interp/vm_tgc_c.cpp index cfda6fe..d1e6596 100644 --- a/src/vm/interp/vm_tgc_c.cpp +++ b/src/vm/interp/vm_tgc_c.cpp @@ -2651,7 +2651,7 @@ std::unique_ptr create(arch::tgc_c *core, unsigned short por #include namespace iss { namespace { -std::array dummy = { +volatile 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); @@ -2667,8 +2667,4 @@ std::array dummy = { }; } } -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 b760efa..8027571 100644 --- a/src/vm/tcc/vm_tgc_c.cpp +++ b/src/vm/tcc/vm_tgc_c.cpp @@ -3226,7 +3226,7 @@ std::unique_ptr create(arch::tgc_c *core, unsigned short por #include namespace iss { namespace { -std::array dummy = { +volatile 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); @@ -3242,8 +3242,3 @@ std::array dummy = { }; } } -extern "C" { - bool* get_tgc_c_tcc_creators() { - return iss::dummy.data(); - } -} \ No newline at end of file From 1cef7de8c7f61331f4456f468d1cb7469bff813b Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Sun, 9 Jul 2023 20:15:12 +0200 Subject: [PATCH 03/13] fixes missing namespaces --- src/sysc/sc_core_adapter.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sysc/sc_core_adapter.h b/src/sysc/sc_core_adapter.h index baaa43b..9544765 100644 --- a/src/sysc/sc_core_adapter.h +++ b/src/sysc/sc_core_adapter.h @@ -88,7 +88,7 @@ public: if (sizeof(reg_t) != 4) return iss::Err; val = static_cast(time_val >> 32); } - return ret?Ok:Err; + return ret?iss::Ok:iss::Err; #else if((addr==iss::arch::time || addr==iss::arch::timeh)){ uint64_t time_val = owner->mtime_i.read(); @@ -141,7 +141,7 @@ public: private: sysc::tgfs::core_complex *const owner; - sc_event wfi_evt; + sc_core::sc_event wfi_evt; }; From 145a0cf68b848b32a2916ea295a461e9ceb7daaf Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Sun, 9 Jul 2023 20:24:45 +0200 Subject: [PATCH 04/13] updates registration of cores for sysc --- CMakeLists.txt | 2 +- src/sysc/register_tgc_c.cpp | 58 ++++++++++++++++++++++++++++--------- 2 files changed, 46 insertions(+), 14 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c79d882..b269918 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,7 +48,7 @@ else() string(TOUPPER ${CORE} CORE) list(APPEND LIB_DEFINES CORE_${CORE}) endforeach() - message("Defines are ${LIB_DEFINES}") + message("Core defines are ${LIB_DEFINES}") endif() if(TARGET RapidJSON OR TARGET RapidJSON::RapidJSON) diff --git a/src/sysc/register_tgc_c.cpp b/src/sysc/register_tgc_c.cpp index 2394afe..8d86788 100644 --- a/src/sysc/register_tgc_c.cpp +++ b/src/sysc/register_tgc_c.cpp @@ -1,12 +1,34 @@ -/* - * register_tgc_c.cpp +/******************************************************************************* + * Copyright (C) 2023 MINRES Technologies GmbH + * All rights reserved. * - * Created on: Jul 5, 2023 - * Author: eyck - */ - - - + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + *******************************************************************************/ #include #include @@ -17,16 +39,26 @@ namespace iss { namespace { -volatile std::array dummy = { +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)}}; + arch::tgc_c* cpu = new sc_core_adapter>(cc); + return {cpu_ptr{cpu}, vm_ptr{interp::create(cpu, 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)}}; + arch::tgc_c* cpu = new sc_core_adapter>(cc); + return {cpu_ptr{cpu}, vm_ptr{interp::create(cpu, gdb_port)}}; + }), + core_factory::instance().register_creator("tgc_c|m_p|tcc", [](unsigned gdb_port, void* data) -> std::tuple{ + auto cc = reinterpret_cast(data); + arch::tgc_c* cpu = new sc_core_adapter>(cc); + return {cpu_ptr{cpu}, vm_ptr{tcc::create(cpu, gdb_port)}}; + }), + core_factory::instance().register_creator("tgc_c|mu_p|tcc", [](unsigned gdb_port, void* data) -> std::tuple{ + auto cc = reinterpret_cast(data); + arch::tgc_c* cpu = new sc_core_adapter>(cc); + return {cpu_ptr{cpu}, vm_ptr{tcc::create(cpu, gdb_port)}}; }) }; } From b4b03f7850331e03331c3bc3dee2672524eb8208 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Sun, 9 Jul 2023 22:20:50 +0200 Subject: [PATCH 05/13] fixes build system to handle TCC properly --- CMakeLists.txt | 69 +++---- gen_input/templates/interp/CORENAME.cpp.gtl | 2 +- gen_input/templates/tcc/CORENAME.cpp.gtl | 2 +- src/sysc/core_complex.cpp | 195 +++----------------- src/sysc/register_tgc_c.cpp | 20 +- src/sysc/sc_core_adapter.h | 17 +- src/sysc/sc_core_adapter_if.h | 30 +++ src/vm/tcc/vm_tgc_c.cpp | 4 +- 8 files changed, 123 insertions(+), 216 deletions(-) create mode 100644 src/sysc/sc_core_adapter_if.h diff --git a/CMakeLists.txt b/CMakeLists.txt index b269918..f8480fb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,49 +32,41 @@ add_subdirectory(softfloat) set(LIB_SOURCES src/iss/plugin/instruction_count.cpp src/iss/arch/tgc_c.cpp + src/vm/tcc/vm_tgc_c.cpp src/vm/interp/vm_tgc_c.cpp src/vm/fp_functions.cpp ) +if(WITH_TCC) + list(APPEND LIB_SOURCES src/vm/tcc/vm_tgc_c.cpp) +endif() # library files -if(TARGET ${CORE_NAME}_cpp) - list(APPEND LIB_SOURCES ${${CORE_NAME}_OUTPUT_FILES}) -else() - FILE(GLOB GEN_ISS_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src-gen/iss/arch/*.cpp) - FILE(GLOB GEN_VM_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src-gen/vm/interp/vm_*.cpp) - list(APPEND LIB_SOURCES ${GEN_ISS_SOURCES} ${GEN_VM_SOURCES}) - foreach(FILEPATH ${GEN_ISS_SOURCES}) - get_filename_component(CORE ${FILEPATH} NAME_WE) - string(TOUPPER ${CORE} CORE) - list(APPEND LIB_DEFINES CORE_${CORE}) - endforeach() - message("Core defines are ${LIB_DEFINES}") +FILE(GLOB GEN_ISS_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src-gen/iss/arch/*.cpp) +FILE(GLOB GEN_VM_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src-gen/vm/interp/vm_*.cpp) +list(APPEND LIB_SOURCES ${GEN_ISS_SOURCES} ${GEN_VM_SOURCES}) +foreach(FILEPATH ${GEN_ISS_SOURCES}) + get_filename_component(CORE ${FILEPATH} NAME_WE) + string(TOUPPER ${CORE} CORE) + list(APPEND LIB_DEFINES CORE_${CORE}) +endforeach() +message("Core defines are ${LIB_DEFINES}") + +if(WITH_LLVM) + FILE(GLOB LLVM_GEN_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src-gen/vm/llvm/vm_*.cpp) + list(APPEND LIB_SOURCES ${LLVM_GEN_SOURCES}) +endif() + +if(WITH_TCC) + FILE(GLOB TCC_GEN_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src-gen/vm/tcc/vm_*.cpp) + list(APPEND LIB_SOURCES ${TCC_GEN_SOURCES}) endif() if(TARGET RapidJSON OR TARGET RapidJSON::RapidJSON) list(APPEND LIB_SOURCES src/iss/plugin/cycle_estimate.cpp src/iss/plugin/pctrace.cpp) endif() -if(WITH_LLVM) - FILE(GLOB LLVM_GEN_SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/src-gen/vm/llvm/vm_*.cpp - ) - list(APPEND LIB_SOURCES ${LLVM_GEN_SOURCES}) -endif() - -if(WITH_TCC) - FILE(GLOB TCC_GEN_SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/src/vm/tcc/vm_*.cpp - ) - list(APPEND LIB_SOURCES ${TCC_GEN_SOURCES}) -endif() - # Define the library add_library(${PROJECT_NAME} ${LIB_SOURCES}) -# list code gen dependencies -if(TARGET ${CORE_NAME}_cpp) - add_dependencies(${PROJECT_NAME} ${CORE_NAME}_cpp) -endif() if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") target_compile_options(${PROJECT_NAME} PRIVATE -Wno-shift-count-overflow) @@ -185,11 +177,17 @@ install(TARGETS tgc-sim # ############################################################################### if(TARGET scc-sysc) - project(dbt-rise-tgc_sc VERSION 1.0.0) + if(BUILD_SHARED_LIBS) + set(THIS_PROJECT_NAME dbt-rise-tgc_sc) + else() + set(THIS_PROJECT_NAME dbt-rise-tgc_sc_lib) + endif() + project(${THIS_PROJECT_NAME} VERSION 1.0.0) add_library(${PROJECT_NAME} src/sysc/core_complex.cpp src/sysc/register_tgc_c.cpp ) + target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src) target_compile_definitions(${PROJECT_NAME} PUBLIC WITH_SYSTEMC) target_compile_definitions(${PROJECT_NAME} PRIVATE CORE_${CORE_NAME}) foreach(F IN LISTS TGC_SOURCES) @@ -219,5 +217,14 @@ if(TARGET scc-sysc) PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/sysc # headers for mac (note the different component -> different package) INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} # headers ) + if(NOT BUILD_SHARED_LIBS) + add_library(dbt-rise-tgc_sc INTERFACE) + target_include_directories(dbt-rise-tgc_sc INTERFACE $) + target_include_directories(dbt-rise-tgc_sc INTERFACE $) + target_link_libraries(dbt-rise-tgc_sc INTERFACE + -Wl,--whole-archive,$,--no-whole-archive + $ + scc-sysc) + endif() endif() diff --git a/gen_input/templates/interp/CORENAME.cpp.gtl b/gen_input/templates/interp/CORENAME.cpp.gtl index cd84028..5d6cc35 100644 --- a/gen_input/templates/interp/CORENAME.cpp.gtl +++ b/gen_input/templates/interp/CORENAME.cpp.gtl @@ -304,7 +304,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co return pc; } -} +} // namespace ${coreDef.name.toLowerCase()} template <> std::unique_ptr create(arch::${coreDef.name.toLowerCase()} *core, unsigned short port, bool dump) { diff --git a/gen_input/templates/tcc/CORENAME.cpp.gtl b/gen_input/templates/tcc/CORENAME.cpp.gtl index f7a2baf..1b000ea 100644 --- a/gen_input/templates/tcc/CORENAME.cpp.gtl +++ b/gen_input/templates/tcc/CORENAME.cpp.gtl @@ -301,7 +301,7 @@ template void vm_impl::gen_trap_behavior(tu_builder& tu) { tu("return *next_pc;"); } -} // namespace mnrv32 +} // namespace ${coreDef.name.toLowerCase()} template <> std::unique_ptr create(arch::${coreDef.name.toLowerCase()} *core, unsigned short port, bool dump) { diff --git a/src/sysc/core_complex.cpp b/src/sysc/core_complex.cpp index b135117..e3b0433 100644 --- a/src/sysc/core_complex.cpp +++ b/src/sysc/core_complex.cpp @@ -37,10 +37,11 @@ #include #include #include +#include #ifndef WIN32 #include #endif -#include "core_complex.h" +#include "sc_core_adapter_if.h" #include #include #include @@ -85,136 +86,9 @@ using namespace sc_core; namespace { iss::debugger::encoder_decoder encdec; - std::array lvl = {{'U', 'S', 'H', 'M'}}; } -template -class core_wrapper_t : public PLAT { -public: - using reg_t = typename arch::traits::reg_t; - using phys_addr_t = typename arch::traits::phys_addr_t; - using heart_state_t = typename PLAT::hart_state_type; - core_wrapper_t(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()); - } - - sync_type needed_sync() const override { return PRE_SYNC; } - - void disass_output(uint64_t pc, const std::string instr) override { - 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(); - } - }; - - status read_mem(phys_addr_t addr, unsigned length, uint8_t *const data) override { - if (addr.access && access_type::DEBUG) - return owner->read_mem_dbg(addr.val, length, data) ? Ok : Err; - else { - return owner->read_mem(addr.val, length, data, is_fetch(addr.access)) ? Ok : Err; - } - } - - status write_mem(phys_addr_t addr, unsigned length, const uint8_t *const data) override { - if (addr.access && access_type::DEBUG) - return owner->write_mem_dbg(addr.val, length, data) ? Ok : Err; - else { - auto res = owner->write_mem(addr.val, length, data) ? Ok : Err; - // clear MTIP on mtimecmp write - if (addr.val == 0x2004000) { - reg_t val; - this->read_csr(arch::mip, val); - if (val & (1ULL << 7)) this->write_csr(arch::mip, val & ~(1ULL << 7)); - } - return res; - } - } - - status read_csr(unsigned addr, reg_t &val) override { -#ifndef CWR_SYSTEMC - if((addr==arch::time || addr==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==arch::time || addr==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 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[arch::mip] & this->csr[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[arch::mip] |= mask; - wfi_evt.notify(); - } else - this->csr[arch::mip] &= ~mask; - this->check_interrupt(); - if(value) - SCCTRACE(owner->name()) << "Triggering interrupt " << id << " Pending trap: " << this->reg.pending_trap; - } - -private: - core_complex *const owner; - sc_event wfi_evt; -}; - int cmd_sysc(int argc, char *argv[], debugger::out_func of, debugger::data_func df, debugger::target_adapter_if *tgt_adapter) { if (argc > 1) { @@ -262,45 +136,34 @@ public: std::function set_interrupt_execution; std::function local_irq; - template - std::tuple create_core(std::string const& backend, unsigned gdb_port, uint32_t hart_id){ - auto* lcpu = new core_wrapper_t(owner); - lcpu->set_mhartid(hart_id); - get_mode = [lcpu]() { return lcpu->get_mode(); }; - get_state = [lcpu]() { return lcpu->get_state().mstatus.backing.val; }; - get_interrupt_execution = [lcpu]() { return lcpu->get_interrupt_execution(); }; - set_interrupt_execution = [lcpu](bool b) { return lcpu->set_interrupt_execution(b); }; - local_irq = [lcpu](short s, bool b) { return lcpu->local_irq(s, b); }; - if(backend == "interp") - return {cpu_ptr{lcpu}, vm_ptr{iss::interp::create(static_cast(lcpu), gdb_port)}}; -#ifdef WITH_LLVM - if(backend == "llvm") - return {cpu_ptr{lcpu}, vm_ptr{iss::llvm::create(lcpu, gdb_port)}}; -#endif -#ifdef WITH_TCC - if(backend == "tcc") - s return {cpu_ptr{lcpu}, vm_ptr{iss::tcc::create(lcpu, gdb_port)}}; -#endif - return {nullptr, nullptr}; - } - void create_cpu(std::string const& type, std::string const& backend, unsigned gdb_port, uint32_t hart_id){ - CREATE_CORE(tgc_c) -#ifdef CORE_TGC_B - CREATE_CORE(tgc_b) -#endif -#ifdef CORE_TGC_D - CREATE_CORE(tgc_d) -#endif -#ifdef CORE_TGC_D_XRB_MAC - CREATE_CORE(tgc_d_xrb_mac) -#endif -#ifdef CORE_TGC_D_XRB_NN - CREATE_CORE(tgc_d_xrb_nn) -#endif - { - LOG(ERR) << "Illegal argument value for core type: " << type << std::endl; + auto & f = iss::core_factory::instance(); + if(type.size()==0 || type == "?") { + std::cout<<"Available cores: "<(*cpu).set_mhartid(hart_id); + get_mode = [this]() { return reinterpret_cast(*cpu).get_mode(); }; + get_state = [this]() { return reinterpret_cast(*cpu).get_state(); }; + get_interrupt_execution = [this]() { return reinterpret_cast(*cpu).get_interrupt_execution(); }; + set_interrupt_execution = [this](bool b) { return reinterpret_cast(*cpu).set_interrupt_execution(b); }; + local_irq = [this](short s, bool b) { return reinterpret_cast(*cpu).local_irq(s, b); }; + auto *srv = debugger::server::get(); if (srv) tgt_adapter = srv->get_target(); if (tgt_adapter) @@ -634,5 +497,5 @@ bool core_complex::write_mem_dbg(uint64_t addr, unsigned length, const uint8_t * gp.set_streaming_width(length); return dbus->transport_dbg(gp) == length; } -} /* namespace SiFive */ +} /* namespace tgfs */ } /* namespace sysc */ diff --git a/src/sysc/register_tgc_c.cpp b/src/sysc/register_tgc_c.cpp index 8d86788..1fe4194 100644 --- a/src/sysc/register_tgc_c.cpp +++ b/src/sysc/register_tgc_c.cpp @@ -38,28 +38,34 @@ #include "core_complex.h" namespace iss { -namespace { -volatile std::array dummy = { +namespace interp { +volatile std::array tgc_init = { 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* cpu = new sc_core_adapter>(cc); - return {cpu_ptr{cpu}, vm_ptr{interp::create(cpu, gdb_port)}}; + return {cpu_ptr{cpu}, vm_ptr{create(cpu, 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* cpu = new sc_core_adapter>(cc); - return {cpu_ptr{cpu}, vm_ptr{interp::create(cpu, gdb_port)}}; - }), + return {cpu_ptr{cpu}, vm_ptr{create(cpu, gdb_port)}}; + }) +}; +} +#if defined(WITH_TCC) +namespace tcc { +volatile std::array tgc_init = { core_factory::instance().register_creator("tgc_c|m_p|tcc", [](unsigned gdb_port, void* data) -> std::tuple{ auto cc = reinterpret_cast(data); arch::tgc_c* cpu = new sc_core_adapter>(cc); - return {cpu_ptr{cpu}, vm_ptr{tcc::create(cpu, gdb_port)}}; + return {cpu_ptr{cpu}, vm_ptr{create(cpu, gdb_port)}}; }), core_factory::instance().register_creator("tgc_c|mu_p|tcc", [](unsigned gdb_port, void* data) -> std::tuple{ auto cc = reinterpret_cast(data); arch::tgc_c* cpu = new sc_core_adapter>(cc); - return {cpu_ptr{cpu}, vm_ptr{tcc::create(cpu, gdb_port)}}; + return {cpu_ptr{cpu}, vm_ptr{create(cpu, gdb_port)}}; }) }; } +#endif } diff --git a/src/sysc/sc_core_adapter.h b/src/sysc/sc_core_adapter.h index 9544765..77c293f 100644 --- a/src/sysc/sc_core_adapter.h +++ b/src/sysc/sc_core_adapter.h @@ -11,14 +11,13 @@ #include #include -#include "core_complex.h" +#include "sc_core_adapter_if.h" #include #include #include - template -class sc_core_adapter : public PLAT { +class sc_core_adapter : public PLAT, public sc_core_adapter_if { public: using reg_t = typename iss::arch::traits::reg_t; using phys_addr_t = typename iss::arch::traits::phys_addr_t; @@ -26,13 +25,15 @@ public: sc_core_adapter(sysc::tgfs::core_complex *owner) : owner(owner) { } - uint32_t get_mode() { return this->reg.PRIV; } + void set_mhartid(unsigned id) override { PLAT::set_mhartid(id); } - inline void set_interrupt_execution(bool v) { this->interrupt_sim = v?1:0; } + uint32_t get_mode() override { return this->reg.PRIV; } - inline bool get_interrupt_execution() { return this->interrupt_sim; } + void set_interrupt_execution(bool v) override { this->interrupt_sim = v?1:0; } - heart_state_t &get_state() { return this->state; } + bool get_interrupt_execution() override { return this->interrupt_sim; } + + uint64_t get_state() override { return this->state.mstatus.backing.val; } void notify_phase(iss::arch_if::exec_phase p) override { if (p == iss::arch_if::ISTART) @@ -113,7 +114,7 @@ public: PLAT::wait_until(flags); } - void local_irq(short id, bool value) { + void local_irq(short id, bool value) override { reg_t mask = 0; switch (id) { case 3: // SW diff --git a/src/sysc/sc_core_adapter_if.h b/src/sysc/sc_core_adapter_if.h new file mode 100644 index 0000000..5445ee0 --- /dev/null +++ b/src/sysc/sc_core_adapter_if.h @@ -0,0 +1,30 @@ +/* + * sc_core_adapter.h + * + * Created on: Jul 5, 2023 + * Author: eyck + */ + +#ifndef _SYSC_SC_CORE_ADAPTER_IF_H_ +#define _SYSC_SC_CORE_ADAPTER_IF_H_ + + +#include +#include +#include "core_complex.h" +#include +#include +#include + +struct sc_core_adapter_if { + virtual void set_mhartid(unsigned) = 0; + virtual uint32_t get_mode() = 0; + virtual uint64_t get_state() = 0; + virtual bool get_interrupt_execution() = 0; + virtual void set_interrupt_execution(bool v) = 0; + virtual void local_irq(short id, bool value) = 0; + virtual ~sc_core_adapter_if() = default; +}; + + +#endif /* _SYSC_SC_CORE_ADAPTER_IF_H_ */ diff --git a/src/vm/tcc/vm_tgc_c.cpp b/src/vm/tcc/vm_tgc_c.cpp index 8027571..371aa95 100644 --- a/src/vm/tcc/vm_tgc_c.cpp +++ b/src/vm/tcc/vm_tgc_c.cpp @@ -3210,7 +3210,7 @@ template void vm_impl::gen_trap_behavior(tu_builder& tu) { tu("return *next_pc;"); } -} // namespace mnrv32 +} // namespace tgc_c template <> std::unique_ptr create(arch::tgc_c *core, unsigned short port, bool dump) { @@ -3218,7 +3218,7 @@ 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 tcc } // namespace iss #include From 57da07eb17c2cfcdca2a4a62c674173b0ec1897e Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Mon, 10 Jul 2023 12:52:48 +0200 Subject: [PATCH 06/13] rework sc wrapper build --- CMakeLists.txt | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f8480fb..d7977b3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -178,37 +178,39 @@ install(TARGETS tgc-sim ############################################################################### if(TARGET scc-sysc) if(BUILD_SHARED_LIBS) - set(THIS_PROJECT_NAME dbt-rise-tgc_sc) + set(DBT_RISE_SC_LIB_NAME dbt-rise-tgc_sc) else() - set(THIS_PROJECT_NAME dbt-rise-tgc_sc_lib) + set(DBT_RISE_SC_LIB_NAME dbt-rise-tgc_sc_lib) + set(CREATE_INTERFACE_LIB ON) endif() - project(${THIS_PROJECT_NAME} VERSION 1.0.0) - add_library(${PROJECT_NAME} + project(dbt-rise-tgc_sc VERSION 1.0.0) + + add_library(${DBT_RISE_SC_LIB_NAME} src/sysc/core_complex.cpp src/sysc/register_tgc_c.cpp ) - target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src) - target_compile_definitions(${PROJECT_NAME} PUBLIC WITH_SYSTEMC) - target_compile_definitions(${PROJECT_NAME} PRIVATE CORE_${CORE_NAME}) + target_include_directories(${DBT_RISE_SC_LIB_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src) + target_compile_definitions(${DBT_RISE_SC_LIB_NAME} PUBLIC WITH_SYSTEMC) + target_compile_definitions(${DBT_RISE_SC_LIB_NAME} PRIVATE CORE_${CORE_NAME}) foreach(F IN LISTS TGC_SOURCES) if (${F} MATCHES ".*/arch/([^/]*)\.cpp") string(REGEX REPLACE ".*/([^/]*)\.cpp" "\\1" CORE_NAME_LC ${F}) string(TOUPPER ${CORE_NAME_LC} CORE_NAME) - target_compile_definitions(${PROJECT_NAME} PRIVATE CORE_${CORE_NAME}) + target_compile_definitions(${DBT_RISE_SC_LIB_NAME} PRIVATE CORE_${CORE_NAME}) endif() endforeach() - target_link_libraries(${PROJECT_NAME} PUBLIC dbt-rise-tgc scc-sysc) + target_link_libraries(${DBT_RISE_SC_LIB_NAME} PUBLIC dbt-rise-tgc scc-sysc) if(WITH_LLVM) - target_link_libraries(${PROJECT_NAME} PUBLIC ${llvm_libs}) + target_link_libraries(${DBT_RISE_SC_LIB_NAME} PUBLIC ${llvm_libs}) endif() set(LIB_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/src/sysc/core_complex.h) - set_target_properties(${PROJECT_NAME} PROPERTIES + set_target_properties(${DBT_RISE_SC_LIB_NAME} PROPERTIES VERSION ${PROJECT_VERSION} FRAMEWORK FALSE PUBLIC_HEADER "${LIB_HEADERS}" # specify the public headers ) - install(TARGETS ${PROJECT_NAME} COMPONENT ${PROJECT_NAME} + install(TARGETS ${DBT_RISE_SC_LIB_NAME} COMPONENT ${PROJECT_NAME} EXPORT ${PROJECT_NAME}Targets # for downstream dependencies ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} # static lib RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} # binaries @@ -217,13 +219,13 @@ if(TARGET scc-sysc) PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/sysc # headers for mac (note the different component -> different package) INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} # headers ) - if(NOT BUILD_SHARED_LIBS) + if(CREATE_INTERFACE_LIB) add_library(dbt-rise-tgc_sc INTERFACE) - target_include_directories(dbt-rise-tgc_sc INTERFACE $) - target_include_directories(dbt-rise-tgc_sc INTERFACE $) + target_include_directories(dbt-rise-tgc_sc INTERFACE + $) target_link_libraries(dbt-rise-tgc_sc INTERFACE - -Wl,--whole-archive,$,--no-whole-archive - $ + -Wl,--whole-archive,$,--no-whole-archive + $ scc-sysc) endif() endif() From 0b719a4b576a3ea1520193ab5a28442a939a5e4b Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Mon, 10 Jul 2023 20:39:02 +0200 Subject: [PATCH 07/13] fixes literal type --- gen_input/templates/CORENAME.h.gtl | 2 +- src/iss/arch/tgc_c.h | 2 +- src/vm/interp/vm_tgc_c.cpp | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/gen_input/templates/CORENAME.h.gtl b/gen_input/templates/CORENAME.h.gtl index 45a3ed7..2debd97 100644 --- a/gen_input/templates/CORENAME.h.gtl +++ b/gen_input/templates/CORENAME.h.gtl @@ -55,7 +55,7 @@ def byteSize(int size){ return 128; } def getCString(def val){ - return val.toString() + return val.toString()+'ULL' } %> #ifndef _${coreDef.name.toUpperCase()}_H_ diff --git a/src/iss/arch/tgc_c.h b/src/iss/arch/tgc_c.h index 611ef79..2f33ca5 100644 --- a/src/iss/arch/tgc_c.h +++ b/src/iss/arch/tgc_c.h @@ -53,7 +53,7 @@ template <> struct traits { static constexpr std::array 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"}}; - enum constants {MISA_VAL=1073746180, MARCHID_VAL=2147483651, 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=1073746180ULL, MARCHID_VAL=2147483651ULL, XLEN=32ULL, INSTR_ALIGNMENT=2ULL, RFS=32ULL, fence=0ULL, fencei=1ULL, fencevmal=2ULL, fencevmau=3ULL, CSR_SIZE=4096ULL, MUL_LEN=64ULL}; constexpr static unsigned FP_REGS_SIZE = 0; diff --git a/src/vm/interp/vm_tgc_c.cpp b/src/vm/interp/vm_tgc_c.cpp index d1e6596..3b409df 100644 --- a/src/vm/interp/vm_tgc_c.cpp +++ b/src/vm/interp/vm_tgc_c.cpp @@ -2635,7 +2635,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co return pc; } -} +} // namespace tgc_c template <> std::unique_ptr create(arch::tgc_c *core, unsigned short port, bool dump) { @@ -2667,4 +2667,3 @@ volatile std::array dummy = { }; } } - From 957145ca84a08c957950a7ff832182862e9a0728 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Fri, 14 Jul 2023 11:11:03 +0200 Subject: [PATCH 08/13] add SystemC ISS factory --- CMakeLists.txt | 33 ++------ gen_input/templates/interp/CORENAME.cpp.gtl | 4 +- gen_input/templates/tcc/CORENAME.cpp.gtl | 4 +- src/iss/factory.h | 24 +++--- src/sysc/core_complex.cpp | 27 ++++--- src/sysc/iss_factory.h | 88 +++++++++++++++++++++ src/sysc/register_tgc_c.cpp | 19 ++--- src/sysc/sc_core_adapter.h | 6 +- src/sysc/sc_core_adapter_if.h | 5 +- src/vm/tcc/vm_tgc_c.cpp | 4 +- 10 files changed, 144 insertions(+), 70 deletions(-) create mode 100644 src/sysc/iss_factory.h diff --git a/CMakeLists.txt b/CMakeLists.txt index d7977b3..a2a546f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -177,40 +177,32 @@ install(TARGETS tgc-sim # ############################################################################### if(TARGET scc-sysc) - if(BUILD_SHARED_LIBS) - set(DBT_RISE_SC_LIB_NAME dbt-rise-tgc_sc) - else() - set(DBT_RISE_SC_LIB_NAME dbt-rise-tgc_sc_lib) - set(CREATE_INTERFACE_LIB ON) - endif() project(dbt-rise-tgc_sc VERSION 1.0.0) - - add_library(${DBT_RISE_SC_LIB_NAME} + add_library(${PROJECT_NAME} src/sysc/core_complex.cpp src/sysc/register_tgc_c.cpp ) - target_include_directories(${DBT_RISE_SC_LIB_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src) - target_compile_definitions(${DBT_RISE_SC_LIB_NAME} PUBLIC WITH_SYSTEMC) - target_compile_definitions(${DBT_RISE_SC_LIB_NAME} PRIVATE CORE_${CORE_NAME}) + target_compile_definitions(${PROJECT_NAME} PUBLIC WITH_SYSTEMC) + target_compile_definitions(${PROJECT_NAME} PRIVATE CORE_${CORE_NAME}) foreach(F IN LISTS TGC_SOURCES) if (${F} MATCHES ".*/arch/([^/]*)\.cpp") string(REGEX REPLACE ".*/([^/]*)\.cpp" "\\1" CORE_NAME_LC ${F}) string(TOUPPER ${CORE_NAME_LC} CORE_NAME) - target_compile_definitions(${DBT_RISE_SC_LIB_NAME} PRIVATE CORE_${CORE_NAME}) + target_compile_definitions(${PROJECT_NAME} PRIVATE CORE_${CORE_NAME}) endif() endforeach() - target_link_libraries(${DBT_RISE_SC_LIB_NAME} PUBLIC dbt-rise-tgc scc-sysc) + target_link_libraries(${PROJECT_NAME} PUBLIC dbt-rise-tgc scc-sysc) if(WITH_LLVM) - target_link_libraries(${DBT_RISE_SC_LIB_NAME} PUBLIC ${llvm_libs}) + target_link_libraries(${PROJECT_NAME} PUBLIC ${llvm_libs}) endif() set(LIB_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/src/sysc/core_complex.h) - set_target_properties(${DBT_RISE_SC_LIB_NAME} PROPERTIES + set_target_properties(${PROJECT_NAME} PROPERTIES VERSION ${PROJECT_VERSION} FRAMEWORK FALSE PUBLIC_HEADER "${LIB_HEADERS}" # specify the public headers ) - install(TARGETS ${DBT_RISE_SC_LIB_NAME} COMPONENT ${PROJECT_NAME} + install(TARGETS ${PROJECT_NAME} COMPONENT ${PROJECT_NAME} EXPORT ${PROJECT_NAME}Targets # for downstream dependencies ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} # static lib RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} # binaries @@ -219,14 +211,5 @@ if(TARGET scc-sysc) PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/sysc # headers for mac (note the different component -> different package) INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} # headers ) - if(CREATE_INTERFACE_LIB) - add_library(dbt-rise-tgc_sc INTERFACE) - target_include_directories(dbt-rise-tgc_sc INTERFACE - $) - target_link_libraries(dbt-rise-tgc_sc INTERFACE - -Wl,--whole-archive,$,--no-whole-archive - $ - scc-sysc) - endif() endif() diff --git a/gen_input/templates/interp/CORENAME.cpp.gtl b/gen_input/templates/interp/CORENAME.cpp.gtl index 5d6cc35..5629249 100644 --- a/gen_input/templates/interp/CORENAME.cpp.gtl +++ b/gen_input/templates/interp/CORENAME.cpp.gtl @@ -321,13 +321,13 @@ std::unique_ptr create(arch::${coreD namespace iss { namespace { volatile std::array dummy = { - core_factory::instance().register_creator("${coreDef.name.toLowerCase()}|m_p|interp", [](unsigned port, void*) -> std::tuple{ + 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{ + 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); diff --git a/gen_input/templates/tcc/CORENAME.cpp.gtl b/gen_input/templates/tcc/CORENAME.cpp.gtl index 1b000ea..2121964 100644 --- a/gen_input/templates/tcc/CORENAME.cpp.gtl +++ b/gen_input/templates/tcc/CORENAME.cpp.gtl @@ -318,13 +318,13 @@ std::unique_ptr create(arch::${coreD namespace iss { namespace { volatile std::array dummy = { - core_factory::instance().register_creator("${coreDef.name.toLowerCase()}|m_p|tcc", [](unsigned port, void*) -> std::tuple{ + 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{ + 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); diff --git a/src/iss/factory.h b/src/iss/factory.h index 7e45838..c24fefb 100644 --- a/src/iss/factory.h +++ b/src/iss/factory.h @@ -80,9 +80,17 @@ class core_factory { public: static core_factory & instance() { static core_factory bf; return bf; } - bool register_creator(const std::string &, create_fn const&); + bool register_creator(const std::string & className, create_fn const& fn) { + registry[className] = fn; + return true; + } - base_t create(const std::string &, unsigned gdb_port=0, void* init_data=nullptr) const; + base_t create(std::string const& className, unsigned gdb_port=0, void* init_data=nullptr) const { + registry_t::const_iterator regEntry = registry.find(className); + if (regEntry != registry.end()) + return regEntry->second(gdb_port, init_data); + return {nullptr, nullptr}; + } std::vector get_names() { std::vector keys{registry.size()}; @@ -93,18 +101,6 @@ public: } }; -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/sysc/core_complex.cpp b/src/sysc/core_complex.cpp index e3b0433..be25f53 100644 --- a/src/sysc/core_complex.cpp +++ b/src/sysc/core_complex.cpp @@ -37,7 +37,7 @@ #include #include #include -#include +#include "iss_factory.h" #ifndef WIN32 #include #endif @@ -128,7 +128,9 @@ public: void reset(uint64_t addr){vm->reset(addr);} inline void start(){vm->start();} - inline std::pair load_file(std::string const& name){ return cpu->load_file(name);}; + inline std::pair load_file(std::string const& name){ + iss::arch_if* cc = cpu->get_arch_if(); + return cc->load_file(name);}; std::function get_mode; std::function get_state; @@ -137,7 +139,7 @@ public: std::function local_irq; void create_cpu(std::string const& type, std::string const& backend, unsigned gdb_port, uint32_t hart_id){ - auto & f = iss::core_factory::instance(); + auto & f = sysc::iss_factory::instance(); if(type.size()==0 || type == "?") { std::cout<<"Available cores: "<(*cpu).set_mhartid(hart_id); - get_mode = [this]() { return reinterpret_cast(*cpu).get_mode(); }; - get_state = [this]() { return reinterpret_cast(*cpu).get_state(); }; - get_interrupt_execution = [this]() { return reinterpret_cast(*cpu).get_interrupt_execution(); }; - set_interrupt_execution = [this](bool b) { return reinterpret_cast(*cpu).set_interrupt_execution(b); }; - local_irq = [this](short s, bool b) { return reinterpret_cast(*cpu).local_irq(s, b); }; + auto* sc_cpu_if = reinterpret_cast(cpu.get()); + sc_cpu_if->set_mhartid(hart_id); + get_mode = [sc_cpu_if]() { return sc_cpu_if->get_mode(); }; + get_state = [sc_cpu_if]() { return sc_cpu_if->get_state(); }; + get_interrupt_execution = [sc_cpu_if]() { return sc_cpu_if->get_interrupt_execution(); }; + set_interrupt_execution = [sc_cpu_if](bool b) { return sc_cpu_if->set_interrupt_execution(b); }; + local_irq = [sc_cpu_if](short s, bool b) { return sc_cpu_if->local_irq(s, b); }; auto *srv = debugger::server::get(); if (srv) tgt_adapter = srv->get_target(); @@ -176,7 +179,7 @@ public: core_complex * const owner; vm_ptr vm{nullptr}; - cpu_ptr cpu{nullptr}; + sc_cpu_ptr cpu{nullptr}; iss::debugger::target_adapter_if *tgt_adapter{nullptr}; }; diff --git a/src/sysc/iss_factory.h b/src/sysc/iss_factory.h new file mode 100644 index 0000000..f29a5b0 --- /dev/null +++ b/src/sysc/iss_factory.h @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright (C) 2021 MINRES Technologies GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + *******************************************************************************/ + +#ifndef _ISS_FACTORY_H_ +#define _ISS_FACTORY_H_ + +#include +#include "sc_core_adapter_if.h" +#include +#include +#include +#include +#include +#include + +namespace sysc { + +using sc_cpu_ptr = std::unique_ptr; +using vm_ptr= std::unique_ptr; + +class iss_factory { +public: + using base_t = std::tuple; + using create_fn = std::function; + using registry_t = std::unordered_map ; + + iss_factory() = default; + iss_factory(const iss_factory &) = delete; + iss_factory & operator=(const iss_factory &) = delete; + + static iss_factory & instance() { static iss_factory bf; return bf; } + + bool register_creator(const std::string & className, create_fn const& fn) { + registry[className] = fn; + return true; + } + + base_t create(std::string const& className, unsigned gdb_port=0, void* init_data=nullptr) const { + registry_t::const_iterator regEntry = registry.find(className); + if (regEntry != registry.end()) + return regEntry->second(gdb_port, init_data); + return {nullptr, nullptr}; + } + + 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; + } +private: + registry_t registry; + +}; + +} + +#endif /* _ISS_FACTORY_H_ */ diff --git a/src/sysc/register_tgc_c.cpp b/src/sysc/register_tgc_c.cpp index 1fe4194..efd46b0 100644 --- a/src/sysc/register_tgc_c.cpp +++ b/src/sysc/register_tgc_c.cpp @@ -30,7 +30,7 @@ * *******************************************************************************/ -#include +#include "iss_factory.h" #include #include #include @@ -39,16 +39,17 @@ namespace iss { namespace interp { +using namespace sysc; volatile std::array tgc_init = { - 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* cpu = new sc_core_adapter>(cc); - return {cpu_ptr{cpu}, vm_ptr{create(cpu, gdb_port)}}; + iss_factory::instance().register_creator("tgc_c|m_p|interp", [](unsigned gdb_port, void* data) -> iss_factory::base_t { + auto* cc = reinterpret_cast(data); + auto* cpu = new sc_core_adapter>(cc); + return {sysc::sc_cpu_ptr{cpu}, vm_ptr{create(static_cast(cpu), 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* cpu = new sc_core_adapter>(cc); - return {cpu_ptr{cpu}, vm_ptr{create(cpu, gdb_port)}}; + iss_factory::instance().register_creator("tgc_c|mu_p|interp", [](unsigned gdb_port, void* data) -> iss_factory::base_t { + auto* cc = reinterpret_cast(data); + auto* cpu = new sc_core_adapter>(cc); + return {sysc::sc_cpu_ptr{cpu}, vm_ptr{create(static_cast(cpu), gdb_port)}}; }) }; } diff --git a/src/sysc/sc_core_adapter.h b/src/sysc/sc_core_adapter.h index 77c293f..bbd1465 100644 --- a/src/sysc/sc_core_adapter.h +++ b/src/sysc/sc_core_adapter.h @@ -16,6 +16,7 @@ #include #include +namespace sysc { template class sc_core_adapter : public PLAT, public sc_core_adapter_if { public: @@ -25,6 +26,8 @@ public: sc_core_adapter(sysc::tgfs::core_complex *owner) : owner(owner) { } + iss::arch_if* get_arch_if() override { return this;} + void set_mhartid(unsigned id) override { PLAT::set_mhartid(id); } uint32_t get_mode() override { return this->reg.PRIV; } @@ -144,6 +147,5 @@ private: sysc::tgfs::core_complex *const owner; sc_core::sc_event wfi_evt; }; - - +} #endif /* _SYSC_SC_CORE_ADAPTER_H_ */ diff --git a/src/sysc/sc_core_adapter_if.h b/src/sysc/sc_core_adapter_if.h index 5445ee0..05a2c61 100644 --- a/src/sysc/sc_core_adapter_if.h +++ b/src/sysc/sc_core_adapter_if.h @@ -16,7 +16,9 @@ #include #include +namespace sysc { struct sc_core_adapter_if { + virtual iss::arch_if* get_arch_if() = 0; virtual void set_mhartid(unsigned) = 0; virtual uint32_t get_mode() = 0; virtual uint64_t get_state() = 0; @@ -25,6 +27,5 @@ struct sc_core_adapter_if { virtual void local_irq(short id, bool value) = 0; virtual ~sc_core_adapter_if() = default; }; - - +} #endif /* _SYSC_SC_CORE_ADAPTER_IF_H_ */ diff --git a/src/vm/tcc/vm_tgc_c.cpp b/src/vm/tcc/vm_tgc_c.cpp index 371aa95..fee3a87 100644 --- a/src/vm/tcc/vm_tgc_c.cpp +++ b/src/vm/tcc/vm_tgc_c.cpp @@ -3229,13 +3229,13 @@ namespace { volatile 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); + 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); + 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}}; }) From 720236ec3faf87246d15252278532a054c042875 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Fri, 14 Jul 2023 12:51:51 +0200 Subject: [PATCH 09/13] add generated core registration --- CMakeLists.txt | 11 +++- gen_input/templates/CORENAME_sysc.cpp.gtl | 72 +++++++++++++++++++++++ src-gen/.gitignore | 3 +- src/sysc/register_tgc_c.cpp | 8 +-- 4 files changed, 87 insertions(+), 7 deletions(-) create mode 100644 gen_input/templates/CORENAME_sysc.cpp.gtl diff --git a/CMakeLists.txt b/CMakeLists.txt index a2a546f..0f07fd8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,6 +10,10 @@ find_package(elfio QUIET) find_package(Boost COMPONENTS coroutine) find_package(jsoncpp) +if(TARGET tcc::tcc) + set(WITH_TCC ON) +endif() + if(WITH_LLVM) if(DEFINED ENV{LLVM_HOME}) find_path (LLVM_DIR LLVM-Config.cmake $ENV{LLVM_HOME}/lib/cmake/llvm) @@ -178,10 +182,13 @@ install(TARGETS tgc-sim ############################################################################### if(TARGET scc-sysc) project(dbt-rise-tgc_sc VERSION 1.0.0) - add_library(${PROJECT_NAME} + set(LIB_SOURCES src/sysc/core_complex.cpp src/sysc/register_tgc_c.cpp - ) + ) + FILE(GLOB GEN_SC_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src-gen/sysc/register_*.cpp) + list(APPEND LIB_SOURCES ${GEN_SC_SOURCES}) + add_library(${PROJECT_NAME} ${LIB_SOURCES}) 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_sysc.cpp.gtl b/gen_input/templates/CORENAME_sysc.cpp.gtl new file mode 100644 index 0000000..e56e7db --- /dev/null +++ b/gen_input/templates/CORENAME_sysc.cpp.gtl @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright (C) 2023 MINRES Technologies GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + *******************************************************************************/ + +#include "iss_factory.h" +#include +#include +#include +#include "sc_core_adapter.h" +#include "core_complex.h" + +namespace iss { +namespace interp { +using namespace sysc; +volatile std::array ${coreDef.name.toLowerCase()}_init = { + iss_factory::instance().register_creator("${coreDef.name.toLowerCase()}|m_p|interp", [](unsigned gdb_port, void* data) -> iss_factory::base_t { + auto* cc = reinterpret_cast(data); + auto* cpu = new sc_core_adapter>(cc); + return {sysc::sc_cpu_ptr{cpu}, vm_ptr{create(static_cast(cpu), gdb_port)}}; + }), + iss_factory::instance().register_creator("${coreDef.name.toLowerCase()}|mu_p|interp", [](unsigned gdb_port, void* data) -> iss_factory::base_t { + auto* cc = reinterpret_cast(data); + auto* cpu = new sc_core_adapter>(cc); + return {sysc::sc_cpu_ptr{cpu}, vm_ptr{create(static_cast(cpu), gdb_port)}}; + }) +}; +} +#if defined(WITH_TCC) +namespace tcc { +volatile std::array ${coreDef.name.toLowerCase()}_init = { + core_factory::instance().register_creator("${coreDef.name.toLowerCase()}|m_p|tcc", [](unsigned gdb_port, void* data) -> std::tuple{ + auto cc = reinterpret_cast(data); + auto* cpu = new sc_core_adapter>(cc); + return {cpu_ptr{cpu}, vm_ptr{create(static_cast(cpu), gdb_port)}}; + }), + core_factory::instance().register_creator("${coreDef.name.toLowerCase()}|mu_p|tcc", [](unsigned gdb_port, void* data) -> std::tuple{ + auto cc = reinterpret_cast(data); + auto* cpu = new sc_core_adapter>(cc); + return {cpu_ptr{cpu}, vm_ptr{create(static_cast(cpu), gdb_port)}}; + }) +}; +} +#endif +} diff --git a/src-gen/.gitignore b/src-gen/.gitignore index d3fcb35..454f93f 100644 --- a/src-gen/.gitignore +++ b/src-gen/.gitignore @@ -1,2 +1,3 @@ /iss -/vm \ No newline at end of file +/vm +/sysc \ No newline at end of file diff --git a/src/sysc/register_tgc_c.cpp b/src/sysc/register_tgc_c.cpp index efd46b0..31a99a5 100644 --- a/src/sysc/register_tgc_c.cpp +++ b/src/sysc/register_tgc_c.cpp @@ -58,13 +58,13 @@ namespace tcc { volatile std::array tgc_init = { core_factory::instance().register_creator("tgc_c|m_p|tcc", [](unsigned gdb_port, void* data) -> std::tuple{ auto cc = reinterpret_cast(data); - arch::tgc_c* cpu = new sc_core_adapter>(cc); - return {cpu_ptr{cpu}, vm_ptr{create(cpu, gdb_port)}}; + auto* cpu = new sc_core_adapter>(cc); + return {cpu_ptr{cpu}, vm_ptr{create(static_cast(cpu), gdb_port)}}; }), core_factory::instance().register_creator("tgc_c|mu_p|tcc", [](unsigned gdb_port, void* data) -> std::tuple{ auto cc = reinterpret_cast(data); - arch::tgc_c* cpu = new sc_core_adapter>(cc); - return {cpu_ptr{cpu}, vm_ptr{create(cpu, gdb_port)}}; + auto* cpu = new sc_core_adapter>(cc); + return {cpu_ptr{cpu}, vm_ptr{create(static_cast(cpu), gdb_port)}}; }) }; } From a0ca3cdfa53bea29a20e6abf532afb7980f5bdb2 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Thu, 13 Jul 2023 09:42:39 +0200 Subject: [PATCH 10/13] revive LLVM support (WIP) --- CMakeLists.txt | 18 +++++++++++------- src/main.cpp | 2 +- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0f07fd8..bc11091 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,13 +15,17 @@ if(TARGET tcc::tcc) endif() if(WITH_LLVM) - if(DEFINED ENV{LLVM_HOME}) - find_path (LLVM_DIR LLVM-Config.cmake $ENV{LLVM_HOME}/lib/cmake/llvm) - endif(DEFINED ENV{LLVM_HOME}) - find_package(LLVM REQUIRED CONFIG) - message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}") - message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}") - llvm_map_components_to_libnames(llvm_libs support core mcjit x86codegen x86asmparser) + if(FALSE) + if(DEFINED ENV{LLVM_HOME}) + find_path (LLVM_DIR LLVM-Config.cmake $ENV{LLVM_HOME}/lib/cmake/llvm) + endif(DEFINED ENV{LLVM_HOME}) + find_package(LLVM REQUIRED CONFIG) + message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}") + message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}") + llvm_map_components_to_libnames(llvm_libs support core mcjit x86codegen x86asmparser) + else() + find_package(LLVM REQUIRED LLVMSupport LLVMCore LLVMMCJIT LLVMX86CodeGen LLVMX86AsmParser) + endif() endif() #Mac needed variables (adapt for your needs - http://www.cmake.org/Wiki/CMake_RPATH_handling#Mac_OS_X_and_the_RPATH) diff --git a/src/main.cpp b/src/main.cpp index 02ec210..0452578 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -39,7 +39,7 @@ #include #include "iss/arch/tgc_mapper.h" #ifdef WITH_LLVM -#include +#include #endif #include #include "iss/plugin/cycle_estimate.h" From 9459632f6cdc01a8e5bc323eb3ca457733d7d66b Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Mon, 17 Jul 2023 19:52:50 +0200 Subject: [PATCH 11/13] adds llvm build support incl. conan --- CMakeLists.txt | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bc11091..c8fe6a4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,14 +15,14 @@ if(TARGET tcc::tcc) endif() if(WITH_LLVM) - if(FALSE) - if(DEFINED ENV{LLVM_HOME}) - find_path (LLVM_DIR LLVM-Config.cmake $ENV{LLVM_HOME}/lib/cmake/llvm) - endif(DEFINED ENV{LLVM_HOME}) - find_package(LLVM REQUIRED CONFIG) - message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}") - message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}") - llvm_map_components_to_libnames(llvm_libs support core mcjit x86codegen x86asmparser) + if(DEFINED ENV{LLVM_HOME}) + find_path (LLVM_DIR LLVM-Config.cmake $ENV{LLVM_HOME}/lib/cmake/llvm) + endif(DEFINED ENV{LLVM_HOME}) + find_package(LLVM QUIET CONFIG) + if(LLVM_FOUND) + message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}") + message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}") + llvm_map_components_to_libnames(llvm_libs support core mcjit x86codegen x86asmparser) else() find_package(LLVM REQUIRED LLVMSupport LLVMCore LLVMMCJIT LLVMX86CodeGen LLVMX86AsmParser) endif() From 94e46b996884f9836f8b2adbe13f7e5c2671faa6 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Mon, 17 Jul 2023 19:57:09 +0200 Subject: [PATCH 12/13] adds some cleanup --- CMakeLists.txt | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c8fe6a4..5ad2123 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,7 @@ endif() if(WITH_LLVM) if(DEFINED ENV{LLVM_HOME}) find_path (LLVM_DIR LLVM-Config.cmake $ENV{LLVM_HOME}/lib/cmake/llvm) - endif(DEFINED ENV{LLVM_HOME}) + endif() find_package(LLVM QUIET CONFIG) if(LLVM_FOUND) message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}") @@ -28,13 +28,6 @@ if(WITH_LLVM) endif() endif() -#Mac needed variables (adapt for your needs - http://www.cmake.org/Wiki/CMake_RPATH_handling#Mac_OS_X_and_the_RPATH) -#set(CMAKE_MACOSX_RPATH ON) -#set(CMAKE_SKIP_BUILD_RPATH FALSE) -#set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) -#set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") -#set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) - add_subdirectory(softfloat) set(LIB_SOURCES From edba497fa16ae0f56a5a9e043af62d09484c0e33 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Wed, 19 Jul 2023 08:19:38 +0200 Subject: [PATCH 13/13] fixes linker isseu using whole-archive --- CMakeLists.txt | 8 +++++--- cmake/flink.cmake | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 cmake/flink.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 5ad2123..8559904 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,10 +1,12 @@ cmake_minimum_required(VERSION 3.12) +list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) ############################################################################### # ############################################################################### project(dbt-rise-tgc VERSION 1.0.0) include(GNUInstallDirs) +include(flink) find_package(elfio QUIET) find_package(Boost COMPONENTS coroutine) @@ -82,8 +84,8 @@ if(TARGET jsoncpp::jsoncpp) else() target_link_libraries(${PROJECT_NAME} PUBLIC jsoncpp) endif() -if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" AND BUILD_SHARED_LIBS) - target_link_libraries(${PROJECT_NAME} PUBLIC -Wl,--whole-archive dbt-rise-core -Wl,--no-whole-archive) +if(BUILD_SHARED_LIBS) + target_force_link_libraries(${PROJECT_NAME} PUBLIC dbt-rise-core) else() target_link_libraries(${PROJECT_NAME} PUBLIC dbt-rise-core) endif() @@ -154,7 +156,7 @@ if(WITH_TCC) target_compile_definitions(${PROJECT_NAME} PRIVATE WITH_TCC) endif() # Links the target exe against the libraries -target_link_libraries(${PROJECT_NAME} PUBLIC dbt-rise-tgc) +target_force_link_libraries(${PROJECT_NAME} PUBLIC dbt-rise-tgc) if(TARGET Boost::program_options) target_link_libraries(${PROJECT_NAME} PUBLIC Boost::program_options) else() diff --git a/cmake/flink.cmake b/cmake/flink.cmake new file mode 100644 index 0000000..69b5c9f --- /dev/null +++ b/cmake/flink.cmake @@ -0,0 +1,35 @@ +# according to https://github.com/horance-liu/flink.cmake/tree/master +# SPDX-License-Identifier: Apache-2.0 + +include(CMakeParseArguments) + +function(target_do_force_link_libraries target visibility lib) + if(MSVC) + target_link_libraries(${target} ${visibility} "/WHOLEARCHIVE:${lib}") + elseif(APPLE) + target_link_libraries(${target} ${visibility} -Wl,-force_load ${lib}) + else() + target_link_libraries(${target} ${visibility} -Wl,--whole-archive ${lib} -Wl,--no-whole-archive) + endif() +endfunction() + +function(target_force_link_libraries target) + cmake_parse_arguments(FLINK + "" + "" + "PUBLIC;INTERFACE;PRIVATE" + ${ARGN} + ) + + foreach(lib IN LISTS FLINK_PUBLIC) + target_do_force_link_libraries(${target} PUBLIC ${lib}) + endforeach() + + foreach(lib IN LISTS FLINK_INTERFACE) + target_do_force_link_libraries(${target} INTERFACE ${lib}) + endforeach() + + foreach(lib IN LISTS FLINK_PRIVATE) + target_do_force_link_libraries(${target} PRIVATE ${lib}) + endforeach() +endfunction() \ No newline at end of file