add spawn blocks
This commit is contained in:
		@@ -7,6 +7,7 @@ project(dbt-rise-tgc VERSION 1.0.0)
 | 
				
			|||||||
include(GNUInstallDirs)
 | 
					include(GNUInstallDirs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
find_package(elfio)
 | 
					find_package(elfio)
 | 
				
			||||||
 | 
					find_package(Boost COMPONENTS coroutine)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if(WITH_LLVM)
 | 
					if(WITH_LLVM)
 | 
				
			||||||
    if(DEFINED ENV{LLVM_HOME})
 | 
					    if(DEFINED ENV{LLVM_HOME})
 | 
				
			||||||
@@ -66,7 +67,7 @@ elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
 | 
				
			|||||||
    target_compile_options(${PROJECT_NAME} PRIVATE /wd4293)
 | 
					    target_compile_options(${PROJECT_NAME} PRIVATE /wd4293)
 | 
				
			||||||
endif()
 | 
					endif()
 | 
				
			||||||
target_include_directories(${PROJECT_NAME} PUBLIC incl)
 | 
					target_include_directories(${PROJECT_NAME} PUBLIC incl)
 | 
				
			||||||
target_link_libraries(${PROJECT_NAME} PUBLIC softfloat scc-util jsoncpp)
 | 
					target_link_libraries(${PROJECT_NAME} PUBLIC softfloat scc-util jsoncpp Boost::coroutine)
 | 
				
			||||||
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
 | 
					if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
 | 
				
			||||||
    target_link_libraries(${PROJECT_NAME} PUBLIC -Wl,--whole-archive dbt-core -Wl,--no-whole-archive)
 | 
					    target_link_libraries(${PROJECT_NAME} PUBLIC -Wl,--whole-archive dbt-core -Wl,--no-whole-archive)
 | 
				
			||||||
else()
 | 
					else()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -161,7 +161,7 @@ struct ${coreDef.name.toLowerCase()}: public arch_if {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    inline uint32_t get_last_branch() { return reg.last_branch; }
 | 
					    inline uint32_t get_last_branch() { return reg.last_branch; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
protected:
 | 
					
 | 
				
			||||||
#pragma pack(push, 1)
 | 
					#pragma pack(push, 1)
 | 
				
			||||||
    struct ${coreDef.name}_regs {<%
 | 
					    struct ${coreDef.name}_regs {<%
 | 
				
			||||||
        registers.each { reg -> if(reg.size>0) {%> 
 | 
					        registers.each { reg -> if(reg.size>0) {%> 
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -45,6 +45,8 @@ def nativeTypeSize(int size){
 | 
				
			|||||||
#include <iss/interp/vm_base.h>
 | 
					#include <iss/interp/vm_base.h>
 | 
				
			||||||
#include <util/logging.h>
 | 
					#include <util/logging.h>
 | 
				
			||||||
#include <sstream>
 | 
					#include <sstream>
 | 
				
			||||||
 | 
					#include <boost/coroutine2/all.hpp>
 | 
				
			||||||
 | 
					#include <functional>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef FMT_HEADER_ONLY
 | 
					#ifndef FMT_HEADER_ONLY
 | 
				
			||||||
#define FMT_HEADER_ONLY
 | 
					#define FMT_HEADER_ONLY
 | 
				
			||||||
@@ -59,6 +61,7 @@ namespace interp {
 | 
				
			|||||||
namespace ${coreDef.name.toLowerCase()} {
 | 
					namespace ${coreDef.name.toLowerCase()} {
 | 
				
			||||||
using namespace iss::arch;
 | 
					using namespace iss::arch;
 | 
				
			||||||
using namespace iss::debugger;
 | 
					using namespace iss::debugger;
 | 
				
			||||||
 | 
					using namespace std::placeholders;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template <typename ARCH> class vm_impl : public iss::interp::vm_base<ARCH> {
 | 
					template <typename ARCH> class vm_impl : public iss::interp::vm_base<ARCH> {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
@@ -130,6 +133,10 @@ protected:
 | 
				
			|||||||
        this->core.wait_until(type);
 | 
					        this->core.wait_until(type);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    using yield_t = boost::coroutines2::coroutine<void>::push_type;
 | 
				
			||||||
 | 
					    using coro_t = boost::coroutines2::coroutine<void>::pull_type;
 | 
				
			||||||
 | 
					    std::vector<coro_t> spawn_blocks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    template<typename T>
 | 
					    template<typename T>
 | 
				
			||||||
    T& pc_assign(T& val){super::ex_info.branch_taken=true; return val;}
 | 
					    T& pc_assign(T& val){super::ex_info.branch_taken=true; return val;}
 | 
				
			||||||
    inline uint8_t readSpace1(typename super::mem_type_e space, uint64_t addr){
 | 
					    inline uint8_t readSpace1(typename super::mem_type_e space, uint64_t addr){
 | 
				
			||||||
@@ -174,7 +181,9 @@ protected:
 | 
				
			|||||||
        auto sign_mask = 1ULL<<(W-1);
 | 
					        auto sign_mask = 1ULL<<(W-1);
 | 
				
			||||||
        return (from & mask) | ((from & sign_mask) ? ~mask : 0);
 | 
					        return (from & mask) | ((from & sign_mask) ? ~mask : 0);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					<%functions.each{ it.eachLine { %>
 | 
				
			||||||
 | 
					    ${it}<%}%>
 | 
				
			||||||
 | 
					<%}%>
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
    /****************************************************************************
 | 
					    /****************************************************************************
 | 
				
			||||||
     * start opcode definitions
 | 
					     * start opcode definitions
 | 
				
			||||||
@@ -196,11 +205,6 @@ private:
 | 
				
			|||||||
    /* instruction ${idx}: ${instr.name} */
 | 
					    /* instruction ${idx}: ${instr.name} */
 | 
				
			||||||
    compile_ret_t __${generator.functionName(instr.name)}(virt_addr_t& pc, code_word_t instr){
 | 
					    compile_ret_t __${generator.functionName(instr.name)}(virt_addr_t& pc, code_word_t instr){
 | 
				
			||||||
        // pre execution stuff
 | 
					        // pre execution stuff
 | 
				
			||||||
        auto* PC = reinterpret_cast<uint${addrDataWidth}_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::PC]);
 | 
					 | 
				
			||||||
        auto NEXT_PC = reinterpret_cast<uint${addrDataWidth}_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::NEXT_PC]);
 | 
					 | 
				
			||||||
        *PC=*NEXT_PC;
 | 
					 | 
				
			||||||
        auto* trap_state = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::TRAP_STATE]);
 | 
					 | 
				
			||||||
        *trap_state = *reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::PENDING_TRAP]);
 | 
					 | 
				
			||||||
        if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, ${idx});
 | 
					        if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, ${idx});
 | 
				
			||||||
        <%instr.fields.eachLine{%>${it}
 | 
					        <%instr.fields.eachLine{%>${it}
 | 
				
			||||||
        <%}%>if(this->disass_enabled){
 | 
					        <%}%>if(this->disass_enabled){
 | 
				
			||||||
@@ -208,6 +212,9 @@ private:
 | 
				
			|||||||
            <%instr.disass.eachLine{%>${it}
 | 
					            <%instr.disass.eachLine{%>${it}
 | 
				
			||||||
            <%}%>
 | 
					            <%}%>
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        auto* PC = reinterpret_cast<uint${addrDataWidth}_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::PC]);
 | 
				
			||||||
 | 
					        auto* NEXT_PC = reinterpret_cast<uint${addrDataWidth}_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::NEXT_PC]);
 | 
				
			||||||
 | 
					        auto* trap_state = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::TRAP_STATE]);
 | 
				
			||||||
        // used registers<%instr.usedVariables.each{ k,v->
 | 
					        // used registers<%instr.usedVariables.each{ k,v->
 | 
				
			||||||
            if(v.isArray) {%>
 | 
					            if(v.isArray) {%>
 | 
				
			||||||
        auto* ${k} = reinterpret_cast<uint${nativeTypeSize(v.type.size)}_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::${k}0]);<% }else{ %> 
 | 
					        auto* ${k} = reinterpret_cast<uint${nativeTypeSize(v.type.size)}_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::${k}0]);<% }else{ %> 
 | 
				
			||||||
@@ -219,6 +226,7 @@ private:
 | 
				
			|||||||
        <%instr.behavior.eachLine{%>${it}
 | 
					        <%instr.behavior.eachLine{%>${it}
 | 
				
			||||||
        <%}%>} catch(...){}
 | 
					        <%}%>} catch(...){}
 | 
				
			||||||
        // post execution stuff
 | 
					        // post execution stuff
 | 
				
			||||||
 | 
					        for(auto& spawn_block:spawn_blocks) spawn_block();
 | 
				
			||||||
        if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, ${idx});
 | 
					        if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, ${idx});
 | 
				
			||||||
        // trap check
 | 
					        // trap check
 | 
				
			||||||
        if(*trap_state!=0){
 | 
					        if(*trap_state!=0){
 | 
				
			||||||
@@ -335,6 +343,8 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
				
			|||||||
            auto f = decode_inst(insn);
 | 
					            auto f = decode_inst(insn);
 | 
				
			||||||
            auto old_pc = pc.val;
 | 
					            auto old_pc = pc.val;
 | 
				
			||||||
            pc = (this->*f)(pc, insn);
 | 
					            pc = (this->*f)(pc, insn);
 | 
				
			||||||
 | 
					            this->core.reg.PC = this->core.reg.NEXT_PC;
 | 
				
			||||||
 | 
					            this->core.reg.trap_state = this->core.reg.pending_trap;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return pc;
 | 
					    return pc;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user