Compare commits
	
		
			14 Commits
		
	
	
		
			Trace_enha
			...
			feaa49d367
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| feaa49d367 | |||
| 18f33b4a68 | |||
| f096b15dbd | |||
| cb5375258a | |||
| 076b5a39ad | |||
| f40ab41899 | |||
| e8fd5143bc | |||
| 31fb51de95 | |||
| 5d481eb79d | |||
| 1c90fe765d | |||
| 52ed8b81a6 | |||
| 0703a0a845 | |||
| 0c542d42aa | |||
| 966d1616c5 | 
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -30,6 +30,5 @@ language.settings.xml | ||||
| /.gdbinit | ||||
| /*.out | ||||
| /dump.json | ||||
| /src-gen/ | ||||
| /*.yaml | ||||
| /*.json | ||||
|   | ||||
| @@ -29,32 +29,34 @@ endif() | ||||
| add_subdirectory(softfloat) | ||||
|  | ||||
| # library files | ||||
| FILE(GLOB TGC_SOURCES    ${CMAKE_CURRENT_SOURCE_DIR}/src/iss/*.cpp)  | ||||
| FILE(GLOB TGC_VM_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/vm/interp/vm_*.cpp) | ||||
| FILE(GLOB GEN_SOURCES | ||||
|     ${CMAKE_CURRENT_SOURCE_DIR}/src-gen/iss/arch/*.cpp | ||||
| 	${CMAKE_CURRENT_SOURCE_DIR}/src-gen/vm/interp/vm_*.cpp | ||||
| ) | ||||
|  | ||||
| set(LIB_SOURCES  | ||||
|     src/iss/plugin/instruction_count.cpp | ||||
| 	src/iss/arch/tgc_c.cpp | ||||
| 	src/vm/interp/vm_tgc_c.cpp | ||||
| 	src/vm/fp_functions.cpp | ||||
|     src/plugin/instruction_count.cpp | ||||
|      | ||||
|     ${TGC_SOURCES} | ||||
|     ${TGC_VM_SOURCES} | ||||
|     ${GEN_SOURCES} | ||||
| ) | ||||
| if(TARGET RapidJSON) | ||||
|     list(APPEND LIB_SOURCES src/plugin/cycle_estimate.cpp src/plugin/pctrace.cpp) | ||||
|     list(APPEND LIB_SOURCES src/iss/plugin/cycle_estimate.cpp src/iss/plugin/pctrace.cpp) | ||||
| endif() | ||||
|  | ||||
| if(WITH_LLVM) | ||||
| 	FILE(GLOB TGC_LLVM_SOURCES | ||||
| 	    ${CMAKE_CURRENT_SOURCE_DIR}/src/vm/llvm/vm_*.cpp | ||||
| 	FILE(GLOB LLVM_GEN_SOURCES | ||||
| 	    ${CMAKE_CURRENT_SOURCE_DIR}/src-gen/vm/llvm/vm_*.cpp | ||||
| 	) | ||||
| 	list(APPEND LIB_SOURCES ${TGC_LLVM_SOURCES}) | ||||
| 	list(APPEND LIB_SOURCES ${LLVM_GEN_SOURCES}) | ||||
| endif() | ||||
|  | ||||
| if(WITH_TCC) | ||||
| 	FILE(GLOB TGC_TCC_SOURCES | ||||
| 	FILE(GLOB TCC_GEN_SOURCES | ||||
| 	    ${CMAKE_CURRENT_SOURCE_DIR}/src/vm/tcc/vm_*.cpp | ||||
| 	) | ||||
| 	list(APPEND LIB_SOURCES ${TGC_TCC_SOURCES}) | ||||
| 	list(APPEND LIB_SOURCES ${TCC_GEN_SOURCES}) | ||||
| endif() | ||||
|  | ||||
| # Define the library | ||||
| @@ -69,7 +71,8 @@ if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") | ||||
| elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") | ||||
|     target_compile_options(${PROJECT_NAME} PRIVATE /wd4293) | ||||
| endif() | ||||
| target_include_directories(${PROJECT_NAME} PUBLIC incl) | ||||
| target_include_directories(${PROJECT_NAME} PUBLIC src) | ||||
| target_include_directories(${PROJECT_NAME} PUBLIC src-gen) | ||||
| target_link_libraries(${PROJECT_NAME} PUBLIC softfloat scc-util jsoncpp Boost::coroutine) | ||||
| if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") | ||||
|     target_link_libraries(${PROJECT_NAME} PUBLIC -Wl,--whole-archive dbt-rise-core -Wl,--no-whole-archive) | ||||
| @@ -117,6 +120,7 @@ project(tgc-sim) | ||||
| find_package(Boost COMPONENTS program_options thread REQUIRED) | ||||
|  | ||||
| add_executable(${PROJECT_NAME} src/main.cpp) | ||||
| FILE(GLOB TGC_SOURCES  ${CMAKE_CURRENT_SOURCE_DIR}/src-gen/iss/arch/*.cpp)  | ||||
| foreach(F IN LISTS TGC_SOURCES) | ||||
|     string(REGEX REPLACE  ".*/([^/]*)\.cpp"  "\\1" CORE_NAME_LC ${F}) | ||||
|     string(TOUPPER ${CORE_NAME_LC} CORE_NAME) | ||||
|   | ||||
| @@ -37,9 +37,9 @@ def getRegisterSizes(){ | ||||
|     return regs | ||||
| } | ||||
| %> | ||||
| #include "${coreDef.name.toLowerCase()}.h" | ||||
| #include "util/ities.h" | ||||
| #include <util/logging.h> | ||||
| #include <iss/arch/${coreDef.name.toLowerCase()}.h> | ||||
| #include <cstdio> | ||||
| #include <cstring> | ||||
| #include <fstream> | ||||
|   | ||||
							
								
								
									
										86
									
								
								gen_input/templates/CORENAME_decoder.cpp.gtl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								gen_input/templates/CORENAME_decoder.cpp.gtl
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,86 @@ | ||||
| #include "${coreDef.name.toLowerCase()}.h" | ||||
| #include <vector> | ||||
| #include <array> | ||||
| #include <cstdlib> | ||||
| #include <algorithm> | ||||
|  | ||||
| namespace iss { | ||||
| namespace arch { | ||||
| namespace { | ||||
| // according to | ||||
| // https://stackoverflow.com/questions/8871204/count-number-of-1s-in-binary-representation | ||||
| #ifdef __GCC__ | ||||
| constexpr size_t bit_count(uint32_t u) { return __builtin_popcount(u); } | ||||
| #elif __cplusplus < 201402L | ||||
| constexpr size_t uCount(uint32_t u) { return u - ((u >> 1) & 033333333333) - ((u >> 2) & 011111111111); } | ||||
| constexpr size_t bit_count(uint32_t u) { return ((uCount(u) + (uCount(u) >> 3)) & 030707070707) % 63; } | ||||
| #else | ||||
| constexpr size_t bit_count(uint32_t u) { | ||||
|     size_t uCount = u - ((u >> 1) & 033333333333) - ((u >> 2) & 011111111111); | ||||
|     return ((uCount + (uCount >> 3)) & 030707070707) % 63; | ||||
| } | ||||
| #endif | ||||
|  | ||||
| using opcode_e = traits<${coreDef.name.toLowerCase()}>::opcode_e; | ||||
|  | ||||
| /**************************************************************************** | ||||
|  * start opcode definitions | ||||
|  ****************************************************************************/ | ||||
| struct instruction_desriptor { | ||||
|     size_t length; | ||||
|     uint32_t value; | ||||
|     uint32_t mask; | ||||
|     opcode_e op; | ||||
| }; | ||||
|  | ||||
| const std::array<instruction_desriptor, ${instructions.size}> instr_descr = {{ | ||||
|      /* entries are: size, valid value, valid mask, function ptr */<%instructions.each{instr -> %> | ||||
|     {${instr.length}, ${instr.encoding}, ${instr.mask}, opcode_e::${instr.instruction.name}},<%}%> | ||||
| }}; | ||||
|  | ||||
| } | ||||
|  | ||||
| template<> | ||||
| struct instruction_decoder<${coreDef.name.toLowerCase()}> { | ||||
|     using opcode_e = traits<${coreDef.name.toLowerCase()}>::opcode_e; | ||||
|     using code_word_t=traits<${coreDef.name.toLowerCase()}>::code_word_t; | ||||
|  | ||||
|     struct instruction_pattern { | ||||
|         uint32_t value; | ||||
|         uint32_t mask; | ||||
|         opcode_e id; | ||||
|     }; | ||||
|  | ||||
|     std::array<std::vector<instruction_pattern>, 4> qlut; | ||||
|  | ||||
|     template<typename T> | ||||
|     unsigned decode_instruction(T); | ||||
|  | ||||
|     instruction_decoder() { | ||||
|         for (auto instr : instr_descr) { | ||||
|             auto quadrant = instr.value & 0x3; | ||||
|             qlut[quadrant].push_back(instruction_pattern{instr.value, instr.mask, instr.op}); | ||||
|         } | ||||
|         for(auto& lut: qlut){ | ||||
|             std::sort(std::begin(lut), std::end(lut), [](instruction_pattern const& a, instruction_pattern const& b){ | ||||
|                 return bit_count(a.mask) < bit_count(b.mask); | ||||
|             }); | ||||
|         } | ||||
|     } | ||||
| }; | ||||
|  | ||||
| template<> | ||||
| unsigned instruction_decoder<${coreDef.name.toLowerCase()}>::decode_instruction<traits<${coreDef.name.toLowerCase()}>::code_word_t>(traits<${coreDef.name.toLowerCase()}>::code_word_t instr){ | ||||
|     auto res = std::find_if(std::begin(qlut[instr&0x3]), std::end(qlut[instr&0x3]), [instr](instruction_pattern const& e){ | ||||
|         return !((instr&e.mask) ^ e.value ); | ||||
|     }); | ||||
|     return static_cast<unsigned>(res!=std::end(qlut[instr&0x3])? res->id : opcode_e::MAX_OPCODE); | ||||
| } | ||||
|  | ||||
|  | ||||
| std::unique_ptr<instruction_decoder<${coreDef.name.toLowerCase()}>> traits<${coreDef.name.toLowerCase()}>::get_decoder(){ | ||||
|     return std::make_unique<instruction_decoder<${coreDef.name.toLowerCase()}>>(); | ||||
| } | ||||
|  | ||||
| } | ||||
| } | ||||
| @@ -12,5 +12,6 @@ | ||||
| ${name}: <% instrList.findAll{!it.instruction.name.startsWith("__")}.each { %> | ||||
|   - ${it.instruction.name}: | ||||
|     encoding: ${it.encoding} | ||||
|     mask: ${it.mask}<%}}%> | ||||
|     mask: ${it.mask}<%if(it.attributes.size) {%> | ||||
|     attributes: ${it.attributes}<%}}}%> | ||||
|  | ||||
|   | ||||
| @@ -36,7 +36,7 @@ def nativeTypeSize(int size){ | ||||
|     if(size<=8) return 8; else if(size<=16) return 16; else if(size<=32) return 32; else return 64; | ||||
| } | ||||
| %> | ||||
| #include "../fp_functions.h" | ||||
| #include <vm/fp_functions.h> | ||||
| #include <iss/arch/${coreDef.name.toLowerCase()}.h> | ||||
| #include <iss/arch/riscv_hart_m_p.h> | ||||
| #include <iss/debugger/gdb_session.h> | ||||
| @@ -73,6 +73,7 @@ public: | ||||
|     using addr_t      = typename super::addr_t; | ||||
|     using reg_t       = typename traits::reg_t; | ||||
|     using mem_type_e  = typename traits::mem_type_e; | ||||
|     using opcode_e    = typename traits::opcode_e; | ||||
|      | ||||
|     vm_impl(); | ||||
|  | ||||
| @@ -303,9 +304,8 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|             case arch::traits<ARCH>::opcode_e::${instr.name}: { | ||||
|                 <%instr.fields.eachLine{%>${it} | ||||
|                 <%}%>if(this->disass_enabled){ | ||||
| 		            /* generate console output when executing the command */ | ||||
| 		            <%instr.disass.eachLine{%>${it} | ||||
| 		            <%}%> | ||||
|                     /* generate console output when executing the command */<%instr.disass.eachLine{%> | ||||
|                     ${it}<%}%> | ||||
|                 } | ||||
|                 // used registers<%instr.usedVariables.each{ k,v-> | ||||
|                 if(v.isArray) {%> | ||||
| @@ -313,9 +313,9 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 auto* ${k} = reinterpret_cast<uint${nativeTypeSize(v.type.size)}_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::${k}]); | ||||
|                 <%}}%>// calculate next pc value | ||||
|                 *NEXT_PC = *PC + ${instr.length/8}; | ||||
| 		        // execute instruction | ||||
| 		        <%instr.behavior.eachLine{%>${it} | ||||
| 		        <%}%>TRAP_${instr.name}:break; | ||||
|                 // execute instruction<%instr.behavior.eachLine{%> | ||||
|                 ${it}<%}%> | ||||
|                 TRAP_${instr.name}:break; | ||||
|             }// @suppress("No break at end of case")<%}%> | ||||
|             default: { | ||||
|                 *NEXT_PC = *PC + ((instr & 3) == 3 ? 4 : 2); | ||||
|   | ||||
							
								
								
									
										1
									
								
								incl/iss/arch/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								incl/iss/arch/.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1 +0,0 @@ | ||||
| /tgc_*.h | ||||
							
								
								
									
										2
									
								
								src-gen/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								src-gen/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| /iss | ||||
| /vm | ||||
| @@ -30,9 +30,9 @@ | ||||
|  * | ||||
|  *******************************************************************************/ | ||||
| 
 | ||||
| #include "tgc_c.h" | ||||
| #include "util/ities.h" | ||||
| #include <util/logging.h> | ||||
| #include <iss/arch/tgc_c.h> | ||||
| #include <cstdio> | ||||
| #include <cstring> | ||||
| #include <fstream> | ||||
							
								
								
									
										175
									
								
								src/iss/arch/tgc_c_decoder.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										175
									
								
								src/iss/arch/tgc_c_decoder.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,175 @@ | ||||
| #include "tgc_c.h" | ||||
| #include <vector> | ||||
| #include <array> | ||||
| #include <cstdlib> | ||||
| #include <algorithm> | ||||
|  | ||||
| namespace iss { | ||||
| namespace arch { | ||||
| namespace { | ||||
| // according to | ||||
| // https://stackoverflow.com/questions/8871204/count-number-of-1s-in-binary-representation | ||||
| #ifdef __GCC__ | ||||
| constexpr size_t bit_count(uint32_t u) { return __builtin_popcount(u); } | ||||
| #elif __cplusplus < 201402L | ||||
| constexpr size_t uCount(uint32_t u) { return u - ((u >> 1) & 033333333333) - ((u >> 2) & 011111111111); } | ||||
| constexpr size_t bit_count(uint32_t u) { return ((uCount(u) + (uCount(u) >> 3)) & 030707070707) % 63; } | ||||
| #else | ||||
| constexpr size_t bit_count(uint32_t u) { | ||||
|     size_t uCount = u - ((u >> 1) & 033333333333) - ((u >> 2) & 011111111111); | ||||
|     return ((uCount + (uCount >> 3)) & 030707070707) % 63; | ||||
| } | ||||
| #endif | ||||
|  | ||||
| using opcode_e = traits<tgc_c>::opcode_e; | ||||
|  | ||||
| /**************************************************************************** | ||||
|  * start opcode definitions | ||||
|  ****************************************************************************/ | ||||
| struct instruction_desriptor { | ||||
|     size_t length; | ||||
|     uint32_t value; | ||||
|     uint32_t mask; | ||||
|     opcode_e op; | ||||
| }; | ||||
|  | ||||
| const std::array<instruction_desriptor, 90> instr_descr = {{ | ||||
|      /* entries are: size, valid value, valid mask, function ptr */ | ||||
|     {32, 0b00000000000000000000000000110111, 0b00000000000000000000000001111111, opcode_e::LUI}, | ||||
|     {32, 0b00000000000000000000000000010111, 0b00000000000000000000000001111111, opcode_e::AUIPC}, | ||||
|     {32, 0b00000000000000000000000001101111, 0b00000000000000000000000001111111, opcode_e::JAL}, | ||||
|     {32, 0b00000000000000000000000001100111, 0b00000000000000000111000001111111, opcode_e::JALR}, | ||||
|     {32, 0b00000000000000000000000001100011, 0b00000000000000000111000001111111, opcode_e::BEQ}, | ||||
|     {32, 0b00000000000000000001000001100011, 0b00000000000000000111000001111111, opcode_e::BNE}, | ||||
|     {32, 0b00000000000000000100000001100011, 0b00000000000000000111000001111111, opcode_e::BLT}, | ||||
|     {32, 0b00000000000000000101000001100011, 0b00000000000000000111000001111111, opcode_e::BGE}, | ||||
|     {32, 0b00000000000000000110000001100011, 0b00000000000000000111000001111111, opcode_e::BLTU}, | ||||
|     {32, 0b00000000000000000111000001100011, 0b00000000000000000111000001111111, opcode_e::BGEU}, | ||||
|     {32, 0b00000000000000000000000000000011, 0b00000000000000000111000001111111, opcode_e::LB}, | ||||
|     {32, 0b00000000000000000001000000000011, 0b00000000000000000111000001111111, opcode_e::LH}, | ||||
|     {32, 0b00000000000000000010000000000011, 0b00000000000000000111000001111111, opcode_e::LW}, | ||||
|     {32, 0b00000000000000000100000000000011, 0b00000000000000000111000001111111, opcode_e::LBU}, | ||||
|     {32, 0b00000000000000000101000000000011, 0b00000000000000000111000001111111, opcode_e::LHU}, | ||||
|     {32, 0b00000000000000000000000000100011, 0b00000000000000000111000001111111, opcode_e::SB}, | ||||
|     {32, 0b00000000000000000001000000100011, 0b00000000000000000111000001111111, opcode_e::SH}, | ||||
|     {32, 0b00000000000000000010000000100011, 0b00000000000000000111000001111111, opcode_e::SW}, | ||||
|     {32, 0b00000000000000000000000000010011, 0b00000000000000000111000001111111, opcode_e::ADDI}, | ||||
|     {32, 0b00000000000000000010000000010011, 0b00000000000000000111000001111111, opcode_e::SLTI}, | ||||
|     {32, 0b00000000000000000011000000010011, 0b00000000000000000111000001111111, opcode_e::SLTIU}, | ||||
|     {32, 0b00000000000000000100000000010011, 0b00000000000000000111000001111111, opcode_e::XORI}, | ||||
|     {32, 0b00000000000000000110000000010011, 0b00000000000000000111000001111111, opcode_e::ORI}, | ||||
|     {32, 0b00000000000000000111000000010011, 0b00000000000000000111000001111111, opcode_e::ANDI}, | ||||
|     {32, 0b00000000000000000001000000010011, 0b11111110000000000111000001111111, opcode_e::SLLI}, | ||||
|     {32, 0b00000000000000000101000000010011, 0b11111110000000000111000001111111, opcode_e::SRLI}, | ||||
|     {32, 0b01000000000000000101000000010011, 0b11111110000000000111000001111111, opcode_e::SRAI}, | ||||
|     {32, 0b00000000000000000000000000110011, 0b11111110000000000111000001111111, opcode_e::ADD}, | ||||
|     {32, 0b01000000000000000000000000110011, 0b11111110000000000111000001111111, opcode_e::SUB}, | ||||
|     {32, 0b00000000000000000001000000110011, 0b11111110000000000111000001111111, opcode_e::SLL}, | ||||
|     {32, 0b00000000000000000010000000110011, 0b11111110000000000111000001111111, opcode_e::SLT}, | ||||
|     {32, 0b00000000000000000011000000110011, 0b11111110000000000111000001111111, opcode_e::SLTU}, | ||||
|     {32, 0b00000000000000000100000000110011, 0b11111110000000000111000001111111, opcode_e::XOR}, | ||||
|     {32, 0b00000000000000000101000000110011, 0b11111110000000000111000001111111, opcode_e::SRL}, | ||||
|     {32, 0b01000000000000000101000000110011, 0b11111110000000000111000001111111, opcode_e::SRA}, | ||||
|     {32, 0b00000000000000000110000000110011, 0b11111110000000000111000001111111, opcode_e::OR}, | ||||
|     {32, 0b00000000000000000111000000110011, 0b11111110000000000111000001111111, opcode_e::AND}, | ||||
|     {32, 0b00000000000000000000000000001111, 0b00000000000000000111000001111111, opcode_e::FENCE}, | ||||
|     {32, 0b00000000000000000000000001110011, 0b11111111111111111111111111111111, opcode_e::ECALL}, | ||||
|     {32, 0b00000000000100000000000001110011, 0b11111111111111111111111111111111, opcode_e::EBREAK}, | ||||
|     {32, 0b00000000001000000000000001110011, 0b11111111111111111111111111111111, opcode_e::URET}, | ||||
|     {32, 0b00010000001000000000000001110011, 0b11111111111111111111111111111111, opcode_e::SRET}, | ||||
|     {32, 0b00110000001000000000000001110011, 0b11111111111111111111111111111111, opcode_e::MRET}, | ||||
|     {32, 0b00010000010100000000000001110011, 0b11111111111111111111111111111111, opcode_e::WFI}, | ||||
|     {32, 0b01111011001000000000000001110011, 0b11111111111111111111111111111111, opcode_e::DRET}, | ||||
|     {32, 0b00000000000000000001000001110011, 0b00000000000000000111000001111111, opcode_e::CSRRW}, | ||||
|     {32, 0b00000000000000000010000001110011, 0b00000000000000000111000001111111, opcode_e::CSRRS}, | ||||
|     {32, 0b00000000000000000011000001110011, 0b00000000000000000111000001111111, opcode_e::CSRRC}, | ||||
|     {32, 0b00000000000000000101000001110011, 0b00000000000000000111000001111111, opcode_e::CSRRWI}, | ||||
|     {32, 0b00000000000000000110000001110011, 0b00000000000000000111000001111111, opcode_e::CSRRSI}, | ||||
|     {32, 0b00000000000000000111000001110011, 0b00000000000000000111000001111111, opcode_e::CSRRCI}, | ||||
|     {32, 0b00000000000000000001000000001111, 0b00000000000000000111000001111111, opcode_e::FENCE_I}, | ||||
|     {32, 0b00000010000000000000000000110011, 0b11111110000000000111000001111111, opcode_e::MUL}, | ||||
|     {32, 0b00000010000000000001000000110011, 0b11111110000000000111000001111111, opcode_e::MULH}, | ||||
|     {32, 0b00000010000000000010000000110011, 0b11111110000000000111000001111111, opcode_e::MULHSU}, | ||||
|     {32, 0b00000010000000000011000000110011, 0b11111110000000000111000001111111, opcode_e::MULHU}, | ||||
|     {32, 0b00000010000000000100000000110011, 0b11111110000000000111000001111111, opcode_e::DIV}, | ||||
|     {32, 0b00000010000000000101000000110011, 0b11111110000000000111000001111111, opcode_e::DIVU}, | ||||
|     {32, 0b00000010000000000110000000110011, 0b11111110000000000111000001111111, opcode_e::REM}, | ||||
|     {32, 0b00000010000000000111000000110011, 0b11111110000000000111000001111111, opcode_e::REMU}, | ||||
|     {16, 0b0000000000000000, 0b1110000000000011, opcode_e::CADDI4SPN}, | ||||
|     {16, 0b0100000000000000, 0b1110000000000011, opcode_e::CLW}, | ||||
|     {16, 0b1100000000000000, 0b1110000000000011, opcode_e::CSW}, | ||||
|     {16, 0b0000000000000001, 0b1110000000000011, opcode_e::CADDI}, | ||||
|     {16, 0b0000000000000001, 0b1110111110000011, opcode_e::CNOP}, | ||||
|     {16, 0b0010000000000001, 0b1110000000000011, opcode_e::CJAL}, | ||||
|     {16, 0b0100000000000001, 0b1110000000000011, opcode_e::CLI}, | ||||
|     {16, 0b0110000000000001, 0b1110000000000011, opcode_e::CLUI}, | ||||
|     {16, 0b0110000100000001, 0b1110111110000011, opcode_e::CADDI16SP}, | ||||
|     {16, 0b0110000000000001, 0b1111000001111111, opcode_e::__reserved_clui}, | ||||
|     {16, 0b1000000000000001, 0b1111110000000011, opcode_e::CSRLI}, | ||||
|     {16, 0b1000010000000001, 0b1111110000000011, opcode_e::CSRAI}, | ||||
|     {16, 0b1000100000000001, 0b1110110000000011, opcode_e::CANDI}, | ||||
|     {16, 0b1000110000000001, 0b1111110001100011, opcode_e::CSUB}, | ||||
|     {16, 0b1000110000100001, 0b1111110001100011, opcode_e::CXOR}, | ||||
|     {16, 0b1000110001000001, 0b1111110001100011, opcode_e::COR}, | ||||
|     {16, 0b1000110001100001, 0b1111110001100011, opcode_e::CAND}, | ||||
|     {16, 0b1010000000000001, 0b1110000000000011, opcode_e::CJ}, | ||||
|     {16, 0b1100000000000001, 0b1110000000000011, opcode_e::CBEQZ}, | ||||
|     {16, 0b1110000000000001, 0b1110000000000011, opcode_e::CBNEZ}, | ||||
|     {16, 0b0000000000000010, 0b1111000000000011, opcode_e::CSLLI}, | ||||
|     {16, 0b0100000000000010, 0b1110000000000011, opcode_e::CLWSP}, | ||||
|     {16, 0b1000000000000010, 0b1111000000000011, opcode_e::CMV}, | ||||
|     {16, 0b1000000000000010, 0b1111000001111111, opcode_e::CJR}, | ||||
|     {16, 0b1000000000000010, 0b1111111111111111, opcode_e::__reserved_cmv}, | ||||
|     {16, 0b1001000000000010, 0b1111000000000011, opcode_e::CADD}, | ||||
|     {16, 0b1001000000000010, 0b1111000001111111, opcode_e::CJALR}, | ||||
|     {16, 0b1001000000000010, 0b1111111111111111, opcode_e::CEBREAK}, | ||||
|     {16, 0b1100000000000010, 0b1110000000000011, opcode_e::CSWSP}, | ||||
|     {16, 0b0000000000000000, 0b1111111111111111, opcode_e::DII}, | ||||
| }}; | ||||
|  | ||||
| } | ||||
|  | ||||
| template<> | ||||
| struct instruction_decoder<tgc_c> { | ||||
|     using opcode_e = traits<tgc_c>::opcode_e; | ||||
|     using code_word_t=traits<tgc_c>::code_word_t; | ||||
|  | ||||
|     struct instruction_pattern { | ||||
|         uint32_t value; | ||||
|         uint32_t mask; | ||||
|         opcode_e id; | ||||
|     }; | ||||
|  | ||||
|     std::array<std::vector<instruction_pattern>, 4> qlut; | ||||
|  | ||||
|     template<typename T> | ||||
|     unsigned decode_instruction(T); | ||||
|  | ||||
|     instruction_decoder() { | ||||
|         for (auto instr : instr_descr) { | ||||
|             auto quadrant = instr.value & 0x3; | ||||
|             qlut[quadrant].push_back(instruction_pattern{instr.value, instr.mask, instr.op}); | ||||
|         } | ||||
|         for(auto& lut: qlut){ | ||||
|             std::sort(std::begin(lut), std::end(lut), [](instruction_pattern const& a, instruction_pattern const& b){ | ||||
|                 return bit_count(a.mask) > bit_count(b.mask); | ||||
|             }); | ||||
|         } | ||||
|     } | ||||
| }; | ||||
|  | ||||
| template<> | ||||
| unsigned instruction_decoder<tgc_c>::decode_instruction<traits<tgc_c>::code_word_t>(traits<tgc_c>::code_word_t instr){ | ||||
|     auto res = std::find_if(std::begin(qlut[instr&0x3]), std::end(qlut[instr&0x3]), [instr](instruction_pattern const& e){ | ||||
|         return !((instr&e.mask) ^ e.value ); | ||||
|     }); | ||||
|     return static_cast<unsigned>(res!=std::end(qlut[instr&0x3])? res->id : opcode_e::MAX_OPCODE); | ||||
| } | ||||
|  | ||||
|  | ||||
| std::unique_ptr<instruction_decoder<tgc_c>> traits<tgc_c>::get_decoder(){ | ||||
|     return std::make_unique<instruction_decoder<tgc_c>>(); | ||||
| } | ||||
|  | ||||
| } | ||||
| } | ||||
| @@ -4,39 +4,44 @@ | ||||
| #include "riscv_hart_m_p.h" | ||||
| #include "tgc_c.h" | ||||
| using tgc_c_plat_type = iss::arch::riscv_hart_m_p<iss::arch::tgc_c>; | ||||
| #ifdef CORE_TGC_A | ||||
| #include "riscv_hart_m_p.h" | ||||
| #include <iss/arch/tgc_a.h> | ||||
| using tgc_a_plat_type = iss::arch::riscv_hart_m_p<iss::arch::tgc_a>; | ||||
| #endif | ||||
| #ifdef CORE_TGC_B | ||||
| #include "riscv_hart_m_p.h" | ||||
| #include "tgc_b.h" | ||||
| #include <iss/arch/tgc_b.h> | ||||
| using tgc_b_plat_type = iss::arch::riscv_hart_m_p<iss::arch::tgc_b>; | ||||
| #endif | ||||
| #ifdef CORE_TGC_C_XRB_NN | ||||
| #include "riscv_hart_m_p.h" | ||||
| #include "tgc_c_xrb_nn.h" | ||||
| #include <iss/arch/tgc_c_xrb_nn.h> | ||||
| using tgc_c_xrb_nn_plat_type = iss::arch::riscv_hart_m_p<iss::arch::tgc_c_xrb_nn>; | ||||
| #endif | ||||
| #ifdef CORE_TGC_D | ||||
| #include "riscv_hart_mu_p.h" | ||||
| #include "tgc_d.h" | ||||
| #include <iss/arch/tgc_d.h> | ||||
| using tgc_d_plat_type = iss::arch::riscv_hart_mu_p<iss::arch::tgc_d, (iss::arch::features_e)(iss::arch::FEAT_PMP | iss::arch::FEAT_CLIC | iss::arch::FEAT_EXT_N)>; | ||||
| #endif | ||||
| #ifdef CORE_TGC_D_XRB_MAC | ||||
| #include "riscv_hart_mu_p.h" | ||||
| #include "tgc_d_xrb_mac.h" | ||||
| #include <iss/arch/tgc_d_xrb_mac.h> | ||||
| using tgc_d_xrb_mac_plat_type = iss::arch::riscv_hart_mu_p<iss::arch::tgc_d_xrb_mac, (iss::arch::features_e)(iss::arch::FEAT_PMP | iss::arch::FEAT_CLIC | iss::arch::FEAT_EXT_N)>; | ||||
| #endif | ||||
| #ifdef CORE_TGC_D_XRB_NN | ||||
| #include "riscv_hart_mu_p.h" | ||||
| #include "tgc_d_xrb_nn.h" | ||||
| #include <iss/arch/tgc_d_xrb_nn.h> | ||||
| using tgc_d_xrb_nn_plat_type = iss::arch::riscv_hart_mu_p<iss::arch::tgc_d_xrb_nn, (iss::arch::features_e)(iss::arch::FEAT_PMP | iss::arch::FEAT_CLIC | iss::arch::FEAT_EXT_N)>; | ||||
| #endif | ||||
| #ifdef CORE_TGC_E | ||||
| #include "riscv_hart_mu_p.h" | ||||
| #include "tgc_e.h" | ||||
| #include <iss/arch/tgc_e.h> | ||||
| using tgc_e_plat_type = iss::arch::riscv_hart_mu_p<iss::arch::tgc_e, (iss::arch::features_e)(iss::arch::FEAT_PMP | iss::arch::FEAT_CLIC | iss::arch::FEAT_EXT_N)>; | ||||
| #endif | ||||
| #ifdef CORE_TGC_X | ||||
| #include "riscv_hart_mu_p.h" | ||||
| #include "tgc_x.h" | ||||
| #include <iss/arch/tgc_x.h> | ||||
| using tgc_x_plat_type = iss::arch::riscv_hart_mu_p<iss::arch::tgc_x, (iss::arch::features_e)(iss::arch::FEAT_PMP | iss::arch::FEAT_CLIC | iss::arch::FEAT_EXT_N | iss::arch::FEAT_TCM)>; | ||||
| #endif | ||||
| 
 | ||||
| @@ -32,14 +32,14 @@ | ||||
|  *       eyck@minres.com - initial API and implementation | ||||
|  ******************************************************************************/ | ||||
| 
 | ||||
| #include "iss/plugin/cycle_estimate.h" | ||||
| #include "cycle_estimate.h" | ||||
| 
 | ||||
| #include <iss/arch_if.h> | ||||
| #include <util/logging.h> | ||||
| #include <rapidjson/document.h> | ||||
| #include <rapidjson/istreamwrapper.h> | ||||
| #include "rapidjson/writer.h" | ||||
| #include "rapidjson/stringbuffer.h" | ||||
| #include <rapidjson/writer.h> | ||||
| #include <rapidjson/stringbuffer.h> | ||||
| #include <rapidjson/ostreamwrapper.h> | ||||
| #include <rapidjson/error/en.h> | ||||
| #include <fstream> | ||||
| @@ -32,8 +32,8 @@ | ||||
|  *       eyck@minres.com - initial API and implementation | ||||
|  ******************************************************************************/ | ||||
| 
 | ||||
| #include "iss/plugin/instruction_count.h" | ||||
| #include "iss/instrumentation_if.h" | ||||
| #include "instruction_count.h" | ||||
| #include <iss/instrumentation_if.h> | ||||
| 
 | ||||
| #include <iss/arch_if.h> | ||||
| #include <util/logging.h> | ||||
| @@ -4,8 +4,8 @@ | ||||
| #include <util/ities.h> | ||||
| #include <rapidjson/document.h> | ||||
| #include <rapidjson/istreamwrapper.h> | ||||
| #include "rapidjson/writer.h" | ||||
| #include "rapidjson/stringbuffer.h" | ||||
| #include <rapidjson/writer.h> | ||||
| #include <rapidjson/stringbuffer.h> | ||||
| #include <rapidjson/ostreamwrapper.h> | ||||
| #include <rapidjson/error/en.h> | ||||
| #include <fstream> | ||||
| @@ -89,7 +89,7 @@ private: | ||||
| }; | ||||
| #endif | ||||
| 
 | ||||
| cov::cov(std::string const &filename) | ||||
| pctrace::pctrace(std::string const &filename) | ||||
| : instr_if(nullptr) | ||||
| , filename(filename) | ||||
| , output("output.trc") | ||||
| @@ -99,9 +99,9 @@ cov::cov(std::string const &filename) | ||||
| #endif | ||||
| { } | ||||
| 
 | ||||
| cov::~cov() { } | ||||
| pctrace::~pctrace() { } | ||||
| 
 | ||||
| bool cov::registration(const char *const version, vm_if& vm) { | ||||
| bool pctrace::registration(const char *const version, vm_if& vm) { | ||||
|     instr_if = vm.get_arch()->get_instrumentation_if(); | ||||
|     if(!instr_if) return false; | ||||
|     const string  core_name = instr_if->core_type_name(); | ||||
| @@ -152,7 +152,7 @@ bool cov::registration(const char *const version, vm_if& vm) { | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| void cov::callback(instr_info_t iinfo, const exec_info& einfo) { | ||||
| void pctrace::callback(instr_info_t iinfo, const exec_info& einfo) { | ||||
|     auto delay = 0; | ||||
|     size_t id = iinfo.instr_id; | ||||
|     auto entry = delays[id]; | ||||
| @@ -45,7 +45,7 @@ | ||||
| namespace iss { | ||||
| namespace plugin { | ||||
| class lz4compress_steambuf; | ||||
| class cov : public iss::vm_plugin { | ||||
| class pctrace : public iss::vm_plugin { | ||||
|     struct instr_delay { | ||||
|         std::string instr_name; | ||||
|         size_t size; | ||||
| @@ -67,17 +67,17 @@ class cov : public iss::vm_plugin { | ||||
| 
 | ||||
| public: | ||||
| 
 | ||||
|     cov(const cov &) = delete; | ||||
|     pctrace(const pctrace &) = delete; | ||||
| 
 | ||||
|     cov(const cov &&) = delete; | ||||
|     pctrace(const pctrace &&) = delete; | ||||
| 
 | ||||
|     cov(std::string const &); | ||||
|     pctrace(std::string const &); | ||||
| 
 | ||||
|     virtual ~cov(); | ||||
|     virtual ~pctrace(); | ||||
| 
 | ||||
|     cov &operator=(const cov &) = delete; | ||||
|     pctrace &operator=(const pctrace &) = delete; | ||||
| 
 | ||||
|     cov &operator=(const cov &&) = delete; | ||||
|     pctrace &operator=(const pctrace &&) = delete; | ||||
| 
 | ||||
|     bool registration(const char *const version, vm_if &arch) override; | ||||
| 
 | ||||
							
								
								
									
										10
									
								
								src/main.cpp
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								src/main.cpp
									
									
									
									
									
								
							| @@ -35,14 +35,14 @@ | ||||
|  | ||||
| #include <boost/lexical_cast.hpp> | ||||
| #include <boost/program_options.hpp> | ||||
| #include <iss/arch/tgc_mapper.h> | ||||
| #include "iss/arch/tgc_mapper.h" | ||||
| #ifdef WITH_LLVM | ||||
| #include <iss/llvm/jit_helper.h> | ||||
| #endif | ||||
| #include <iss/log_categories.h> | ||||
| #include <iss/plugin/cycle_estimate.h> | ||||
| #include <iss/plugin/instruction_count.h> | ||||
| #include <iss/plugin/pctrace.h> | ||||
| #include "iss/plugin/cycle_estimate.h" | ||||
| #include "iss/plugin/instruction_count.h" | ||||
| #include "iss/plugin/pctrace.h" | ||||
| #include <iss/plugin/loader.h> | ||||
| #if defined(HAS_LUA) | ||||
| #include <iss/plugin/lua.h> | ||||
| @@ -177,7 +177,7 @@ int main(int argc, char *argv[]) { | ||||
|                     vm->register_plugin(*ce_plugin); | ||||
|                     plugin_list.push_back(ce_plugin); | ||||
|                 } else if (plugin_name == "pctrace") { | ||||
|                     auto *plugin = new iss::plugin::cov(filename); | ||||
|                     auto *plugin = new iss::plugin::pctrace(filename); | ||||
|                     vm->register_plugin(*plugin); | ||||
|                     plugin_list.push_back(plugin); | ||||
|                } else { | ||||
|   | ||||
| @@ -38,7 +38,7 @@ | ||||
| #include <iss/iss.h> | ||||
| #include <iss/vm_types.h> | ||||
| #include <iss/plugin/loader.h> | ||||
| #include <sysc/core_complex.h> | ||||
| #include "core_complex.h" | ||||
| #include <iss/arch/tgc_mapper.h> | ||||
| #include <scc/report.h> | ||||
| #include <util/ities.h> | ||||
| @@ -405,7 +405,7 @@ void core_complex::before_end_of_elaboration() { | ||||
|                 cpu->vm->register_plugin(*plugin); | ||||
|                 plugin_list.push_back(plugin); | ||||
|             } else if (plugin_name == "pctrace") { | ||||
|                 auto *plugin = new iss::plugin::cov(filename); | ||||
|                 auto *plugin = new iss::plugin::pctrace(filename); | ||||
|                 cpu->vm->register_plugin(*plugin); | ||||
|                 plugin_list.push_back(plugin); | ||||
|             } else { | ||||
|   | ||||
							
								
								
									
										1
									
								
								src/vm/interp/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								src/vm/interp/.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1 +0,0 @@ | ||||
| /vm_tgc_*.cpp | ||||
| @@ -30,7 +30,7 @@ | ||||
|  * | ||||
|  *******************************************************************************/ | ||||
|  | ||||
| #include "../fp_functions.h" | ||||
| #include <vm/fp_functions.h> | ||||
| #include <iss/arch/tgc_c.h> | ||||
| #include <iss/arch/riscv_hart_m_p.h> | ||||
| #include <iss/debugger/gdb_session.h> | ||||
| @@ -67,6 +67,7 @@ public: | ||||
|     using addr_t      = typename super::addr_t; | ||||
|     using reg_t       = typename traits::reg_t; | ||||
|     using mem_type_e  = typename traits::mem_type_e; | ||||
|     using opcode_e    = typename traits::opcode_e; | ||||
|      | ||||
|     vm_impl(); | ||||
|  | ||||
| @@ -390,7 +391,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "lui"), | ||||
|                         fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -412,7 +412,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, {imm:#08x}", fmt::arg("mnemonic", "auipc"), | ||||
|                         fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -434,7 +433,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, {imm:#0x}", fmt::arg("mnemonic", "jal"), | ||||
|                         fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -464,7 +462,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, {rs1}, {imm:#0x}", fmt::arg("mnemonic", "jalr"), | ||||
|                         fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -495,7 +492,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "beq"), | ||||
|                         fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -524,7 +520,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bne"), | ||||
|                         fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -553,7 +548,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "blt"), | ||||
|                         fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -582,7 +576,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bge"), | ||||
|                         fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -611,7 +604,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bltu"), | ||||
|                         fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -640,7 +632,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bgeu"), | ||||
|                         fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -669,15 +660,15 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lb"), | ||||
|                         fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
|                 *NEXT_PC = *PC + 4; | ||||
|                 // execute instruction | ||||
|                 { | ||||
| 		            int8_t res = (int8_t)super::template read_mem<uint8_t>(traits::MEM, *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm)); | ||||
|                     uint8_t read_res = super::template read_mem<uint8_t>(traits::MEM, *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm)); | ||||
|                     if(this->core.trap_state) goto TRAP_LB; | ||||
|                     int8_t res = (int8_t)read_res; | ||||
|                     if((rd % traits::RFS) != 0) { | ||||
|                         *(X+rd % traits::RFS) = res; | ||||
|                     } | ||||
| @@ -694,7 +685,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lh"), | ||||
|                         fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -702,8 +692,9 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 // execute instruction | ||||
|                 { | ||||
|                     uint32_t load_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); | ||||
| 		            int16_t res = (int16_t)super::template read_mem<uint16_t>(traits::MEM, load_address); | ||||
|                     uint16_t read_res = super::template read_mem<uint16_t>(traits::MEM, load_address); | ||||
|                     if(this->core.trap_state) goto TRAP_LH; | ||||
|                     int16_t res = (int16_t)read_res; | ||||
|                     if((rd % traits::RFS) != 0) { | ||||
|                         *(X+rd % traits::RFS) = res; | ||||
|                     } | ||||
| @@ -720,7 +711,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lw"), | ||||
|                         fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -728,8 +718,9 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 // execute instruction | ||||
|                 { | ||||
|                     uint32_t load_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); | ||||
| 		            int32_t res = (int32_t)super::template read_mem<uint32_t>(traits::MEM, load_address); | ||||
|                     uint32_t read_res = super::template read_mem<uint32_t>(traits::MEM, load_address); | ||||
|                     if(this->core.trap_state) goto TRAP_LW; | ||||
|                     int32_t res = (int32_t)read_res; | ||||
|                     if((rd % traits::RFS) != 0) { | ||||
|                         *(X+rd % traits::RFS) = (uint32_t)res; | ||||
|                     } | ||||
| @@ -746,15 +737,15 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lbu"), | ||||
|                         fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
|                 *NEXT_PC = *PC + 4; | ||||
|                 // execute instruction | ||||
|                 { | ||||
| 		            uint8_t res = (uint8_t)super::template read_mem<uint8_t>(traits::MEM, *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm)); | ||||
|                     uint8_t read_res = super::template read_mem<uint8_t>(traits::MEM, *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm)); | ||||
|                     if(this->core.trap_state) goto TRAP_LBU; | ||||
|                     uint8_t res = (uint8_t)read_res; | ||||
|                     if((rd % traits::RFS) != 0) { | ||||
|                         *(X+rd % traits::RFS) = res; | ||||
|                     } | ||||
| @@ -771,7 +762,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lhu"), | ||||
|                         fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -779,8 +769,9 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 // execute instruction | ||||
|                 { | ||||
|                     uint32_t load_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); | ||||
| 		            uint16_t res = (uint16_t)super::template read_mem<uint16_t>(traits::MEM, load_address); | ||||
|                     uint16_t read_res = super::template read_mem<uint16_t>(traits::MEM, load_address); | ||||
|                     if(this->core.trap_state) goto TRAP_LHU; | ||||
|                     uint16_t res = (uint16_t)read_res; | ||||
|                     if((rd % traits::RFS) != 0) { | ||||
|                         *(X+rd % traits::RFS) = res; | ||||
|                     } | ||||
| @@ -797,7 +788,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sb"), | ||||
|                         fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -819,7 +809,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sh"), | ||||
|                         fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -842,7 +831,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sw"), | ||||
|                         fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -865,7 +853,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "addi"), | ||||
|                         fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -888,7 +875,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "slti"), | ||||
|                         fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -911,7 +897,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "sltiu"), | ||||
|                         fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -934,7 +919,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "xori"), | ||||
|                         fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -957,7 +941,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "ori"), | ||||
|                         fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -980,7 +963,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "andi"), | ||||
|                         fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -1003,7 +985,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "slli"), | ||||
|                         fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -1031,7 +1012,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "srli"), | ||||
|                         fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -1059,7 +1039,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "srai"), | ||||
|                         fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -1087,7 +1066,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "add"), | ||||
|                         fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -1110,7 +1088,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sub"), | ||||
|                         fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -1133,7 +1110,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sll"), | ||||
|                         fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -1156,7 +1132,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "slt"), | ||||
|                         fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -1179,7 +1154,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sltu"), | ||||
|                         fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -1202,7 +1176,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "xor"), | ||||
|                         fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -1225,7 +1198,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "srl"), | ||||
|                         fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -1248,7 +1220,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sra"), | ||||
|                         fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -1271,7 +1242,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "or"), | ||||
|                         fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -1294,7 +1264,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "and"), | ||||
|                         fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -1319,7 +1288,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {pred}, {succ} ({fm} , {rs1}, {rd})", fmt::arg("mnemonic", "fence"), | ||||
|                         fmt::arg("pred", pred), fmt::arg("succ", succ), fmt::arg("fm", fm), fmt::arg("rs1", name(rs1)), fmt::arg("rd", name(rd))); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers// calculate next pc value | ||||
|                 *NEXT_PC = *PC + 4; | ||||
| @@ -1334,7 +1302,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 if(this->disass_enabled){ | ||||
|                     /* generate console output when executing the command */ | ||||
|                     this->core.disass_output(pc.val, "ecall"); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers// calculate next pc value | ||||
|                 *NEXT_PC = *PC + 4; | ||||
| @@ -1348,7 +1315,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 if(this->disass_enabled){ | ||||
|                     /* generate console output when executing the command */ | ||||
|                     this->core.disass_output(pc.val, "ebreak"); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers// calculate next pc value | ||||
|                 *NEXT_PC = *PC + 4; | ||||
| @@ -1362,7 +1328,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 if(this->disass_enabled){ | ||||
|                     /* generate console output when executing the command */ | ||||
|                     this->core.disass_output(pc.val, "uret"); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers// calculate next pc value | ||||
|                 *NEXT_PC = *PC + 4; | ||||
| @@ -1376,7 +1341,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 if(this->disass_enabled){ | ||||
|                     /* generate console output when executing the command */ | ||||
|                     this->core.disass_output(pc.val, "sret"); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers// calculate next pc value | ||||
|                 *NEXT_PC = *PC + 4; | ||||
| @@ -1390,7 +1354,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 if(this->disass_enabled){ | ||||
|                     /* generate console output when executing the command */ | ||||
|                     this->core.disass_output(pc.val, "mret"); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers// calculate next pc value | ||||
|                 *NEXT_PC = *PC + 4; | ||||
| @@ -1404,7 +1367,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 if(this->disass_enabled){ | ||||
|                     /* generate console output when executing the command */ | ||||
|                     this->core.disass_output(pc.val, "wfi"); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers// calculate next pc value | ||||
|                 *NEXT_PC = *PC + 4; | ||||
| @@ -1418,7 +1380,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 if(this->disass_enabled){ | ||||
|                     /* generate console output when executing the command */ | ||||
|                     this->core.disass_output(pc.val, "dret"); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers  | ||||
|                 auto* PRIV = reinterpret_cast<uint8_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::PRIV]); | ||||
| @@ -1449,7 +1410,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrw"), | ||||
|                         fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1))); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -1458,8 +1418,9 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 { | ||||
|                     uint32_t xrs1 = *(X+rs1 % traits::RFS); | ||||
|                     if((rd % traits::RFS) != 0) { | ||||
| 		                uint32_t xrd = super::template read_mem<uint32_t>(traits::CSR, csr); | ||||
|                         uint32_t read_res = super::template read_mem<uint32_t>(traits::CSR, csr); | ||||
|                         if(this->core.trap_state) goto TRAP_CSRRW; | ||||
|                         uint32_t xrd = read_res; | ||||
|                         super::template write_mem<uint32_t>(traits::CSR, csr, xrs1); | ||||
|                         if(this->core.trap_state) goto TRAP_CSRRW; | ||||
|                         *(X+rd % traits::RFS) = xrd; | ||||
| @@ -1481,15 +1442,15 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrs"), | ||||
|                         fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1))); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
|                 *NEXT_PC = *PC + 4; | ||||
|                 // execute instruction | ||||
|                 { | ||||
| 		            uint32_t xrd = super::template read_mem<uint32_t>(traits::CSR, csr); | ||||
|                     uint32_t read_res = super::template read_mem<uint32_t>(traits::CSR, csr); | ||||
|                     if(this->core.trap_state) goto TRAP_CSRRS; | ||||
|                     uint32_t xrd = read_res; | ||||
|                     uint32_t xrs1 = *(X+rs1 % traits::RFS); | ||||
|                     if(rs1 != 0) { | ||||
|                         super::template write_mem<uint32_t>(traits::CSR, csr, xrd | xrs1); | ||||
| @@ -1511,15 +1472,15 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrc"), | ||||
|                         fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1))); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
|                 *NEXT_PC = *PC + 4; | ||||
|                 // execute instruction | ||||
|                 { | ||||
| 		            uint32_t xrd = super::template read_mem<uint32_t>(traits::CSR, csr); | ||||
|                     uint32_t read_res = super::template read_mem<uint32_t>(traits::CSR, csr); | ||||
|                     if(this->core.trap_state) goto TRAP_CSRRC; | ||||
|                     uint32_t xrd = read_res; | ||||
|                     uint32_t xrs1 = *(X+rs1 % traits::RFS); | ||||
|                     if(rs1 != 0) { | ||||
|                         super::template write_mem<uint32_t>(traits::CSR, csr, xrd & ~ xrs1); | ||||
| @@ -1541,15 +1502,15 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrwi"), | ||||
|                         fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm)); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
|                 *NEXT_PC = *PC + 4; | ||||
|                 // execute instruction | ||||
|                 { | ||||
| 		            uint32_t xrd = super::template read_mem<uint32_t>(traits::CSR, csr); | ||||
|                     uint32_t read_res = super::template read_mem<uint32_t>(traits::CSR, csr); | ||||
|                     if(this->core.trap_state) goto TRAP_CSRRWI; | ||||
|                     uint32_t xrd = read_res; | ||||
|                     super::template write_mem<uint32_t>(traits::CSR, csr, (uint32_t)zimm); | ||||
|                     if(this->core.trap_state) goto TRAP_CSRRWI; | ||||
|                     if((rd % traits::RFS) != 0) { | ||||
| @@ -1568,15 +1529,15 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrsi"), | ||||
|                         fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm)); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
|                 *NEXT_PC = *PC + 4; | ||||
|                 // execute instruction | ||||
|                 { | ||||
| 		            uint32_t xrd = super::template read_mem<uint32_t>(traits::CSR, csr); | ||||
|                     uint32_t read_res = super::template read_mem<uint32_t>(traits::CSR, csr); | ||||
|                     if(this->core.trap_state) goto TRAP_CSRRSI; | ||||
|                     uint32_t xrd = read_res; | ||||
|                     if(zimm != 0) { | ||||
|                         super::template write_mem<uint32_t>(traits::CSR, csr, xrd | (uint32_t)zimm); | ||||
|                         if(this->core.trap_state) goto TRAP_CSRRSI; | ||||
| @@ -1597,15 +1558,15 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrci"), | ||||
|                         fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm)); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
|                 *NEXT_PC = *PC + 4; | ||||
|                 // execute instruction | ||||
|                 { | ||||
| 		            uint32_t xrd = super::template read_mem<uint32_t>(traits::CSR, csr); | ||||
|                     uint32_t read_res = super::template read_mem<uint32_t>(traits::CSR, csr); | ||||
|                     if(this->core.trap_state) goto TRAP_CSRRCI; | ||||
|                     uint32_t xrd = read_res; | ||||
|                     if(zimm != 0) { | ||||
|                         super::template write_mem<uint32_t>(traits::CSR, csr, xrd & ~ ((uint32_t)zimm)); | ||||
|                         if(this->core.trap_state) goto TRAP_CSRRCI; | ||||
| @@ -1626,7 +1587,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rs1}, {rd}, {imm}", fmt::arg("mnemonic", "fence_i"), | ||||
|                         fmt::arg("rs1", name(rs1)), fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers// calculate next pc value | ||||
|                 *NEXT_PC = *PC + 4; | ||||
| @@ -1647,7 +1607,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mul"), | ||||
|                         fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -1671,7 +1630,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mulh"), | ||||
|                         fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -1695,7 +1653,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mulhsu"), | ||||
|                         fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -1719,7 +1676,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mulhu"), | ||||
|                         fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -1743,7 +1699,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "div"), | ||||
|                         fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -1777,7 +1732,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "divu"), | ||||
|                         fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -1805,7 +1759,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "rem"), | ||||
|                         fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -1839,7 +1792,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "remu"), | ||||
|                         fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -1866,7 +1818,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "caddi4spn"), | ||||
|                         fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -1892,7 +1843,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, {uimm:#05x}({rs1})", fmt::arg("mnemonic", "clw"), | ||||
|                         fmt::arg("rd", name(8+rd)), fmt::arg("uimm", uimm), fmt::arg("rs1", name(8+rs1))); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -1900,8 +1850,9 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 // execute instruction | ||||
|                 { | ||||
|                     uint32_t load_address = *(X+rs1 + 8) + uimm; | ||||
| 		            *(X+rd + 8) = (int32_t)super::template read_mem<uint32_t>(traits::MEM, load_address); | ||||
|                     uint32_t read_res = super::template read_mem<uint32_t>(traits::MEM, load_address); | ||||
|                     if(this->core.trap_state) goto TRAP_CLW; | ||||
|                     *(X+rd + 8) = (int32_t)read_res; | ||||
|                 } | ||||
|                 TRAP_CLW:break; | ||||
|             }// @suppress("No break at end of case") | ||||
| @@ -1915,7 +1866,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rs2}, {uimm:#05x}({rs1})", fmt::arg("mnemonic", "csw"), | ||||
|                         fmt::arg("rs2", name(8+rs2)), fmt::arg("uimm", uimm), fmt::arg("rs1", name(8+rs1))); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -1937,7 +1887,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "caddi"), | ||||
|                         fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -1953,7 +1902,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 if(this->disass_enabled){ | ||||
|                     /* generate console output when executing the command */ | ||||
|                     this->core.disass_output(pc.val, "cnop"); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers// calculate next pc value | ||||
|                 *NEXT_PC = *PC + 2; | ||||
| @@ -1970,7 +1918,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {imm:#05x}", fmt::arg("mnemonic", "cjal"), | ||||
|                         fmt::arg("imm", imm)); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -1992,7 +1939,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "cli"), | ||||
|                         fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -2014,7 +1960,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "clui"), | ||||
|                         fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -2038,7 +1983,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {nzimm:#05x}", fmt::arg("mnemonic", "caddi16sp"), | ||||
|                         fmt::arg("nzimm", nzimm)); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -2059,7 +2003,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 if(this->disass_enabled){ | ||||
|                     /* generate console output when executing the command */ | ||||
|                     this->core.disass_output(pc.val, "__reserved_clui"); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers// calculate next pc value | ||||
|                 *NEXT_PC = *PC + 2; | ||||
| @@ -2078,7 +2021,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rs1}, {shamt}", fmt::arg("mnemonic", "csrli"), | ||||
|                         fmt::arg("rs1", name(8+rs1)), fmt::arg("shamt", shamt)); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -2099,7 +2041,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rs1}, {shamt}", fmt::arg("mnemonic", "csrai"), | ||||
|                         fmt::arg("rs1", name(8+rs1)), fmt::arg("shamt", shamt)); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -2128,7 +2069,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "candi"), | ||||
|                         fmt::arg("rs1", name(8+rs1)), fmt::arg("imm", imm)); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -2149,7 +2089,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "csub"), | ||||
|                         fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -2170,7 +2109,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "cxor"), | ||||
|                         fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -2191,7 +2129,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "cor"), | ||||
|                         fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -2212,7 +2149,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "cand"), | ||||
|                         fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -2232,7 +2168,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {imm:#05x}", fmt::arg("mnemonic", "cj"), | ||||
|                         fmt::arg("imm", imm)); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers// calculate next pc value | ||||
|                 *NEXT_PC = *PC + 2; | ||||
| @@ -2252,7 +2187,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "cbeqz"), | ||||
|                         fmt::arg("rs1", name(8+rs1)), fmt::arg("imm", imm)); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -2275,7 +2209,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "cbnez"), | ||||
|                         fmt::arg("rs1", name(8+rs1)), fmt::arg("imm", imm)); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -2298,7 +2231,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rs1}, {nzuimm}", fmt::arg("mnemonic", "cslli"), | ||||
|                         fmt::arg("rs1", name(rs1)), fmt::arg("nzuimm", nzuimm)); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -2320,7 +2252,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, sp, {uimm:#05x}", fmt::arg("mnemonic", "clwsp"), | ||||
|                         fmt::arg("rd", name(rd)), fmt::arg("uimm", uimm)); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -2329,8 +2260,9 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 { | ||||
|                                 if(rd) { | ||||
|                                     uint32_t offs = *(X+2) + uimm; | ||||
| 		                    	    *(X+rd % traits::RFS) = (int32_t)super::template read_mem<uint32_t>(traits::MEM, offs); | ||||
|                                     uint32_t read_res = super::template read_mem<uint32_t>(traits::MEM, offs); | ||||
|                                     if(this->core.trap_state) goto TRAP_CLWSP; | ||||
|                                     *(X+rd % traits::RFS) = (int32_t)read_res; | ||||
|                                 } | ||||
|                                 else { | ||||
|                                     raise(0, 2); | ||||
| @@ -2347,7 +2279,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "cmv"), | ||||
|                         fmt::arg("rd", name(rd)), fmt::arg("rs2", name(rs2))); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -2368,7 +2299,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rs1}", fmt::arg("mnemonic", "cjr"), | ||||
|                         fmt::arg("rs1", name(rs1))); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -2389,7 +2319,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 if(this->disass_enabled){ | ||||
|                     /* generate console output when executing the command */ | ||||
|                     this->core.disass_output(pc.val, "__reserved_cmv"); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers// calculate next pc value | ||||
|                 *NEXT_PC = *PC + 2; | ||||
| @@ -2408,7 +2337,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "cadd"), | ||||
|                         fmt::arg("rd", name(rd)), fmt::arg("rs2", name(rs2))); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -2429,7 +2357,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rs1}", fmt::arg("mnemonic", "cjalr"), | ||||
|                         fmt::arg("rs1", name(rs1))); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -2447,7 +2374,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 if(this->disass_enabled){ | ||||
|                     /* generate console output when executing the command */ | ||||
|                     this->core.disass_output(pc.val, "cebreak"); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers// calculate next pc value | ||||
|                 *NEXT_PC = *PC + 2; | ||||
| @@ -2466,7 +2392,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                         "{mnemonic:10} {rs2}, {uimm:#05x}(sp)", fmt::arg("mnemonic", "cswsp"), | ||||
|                         fmt::arg("rs2", name(rs2)), fmt::arg("uimm", uimm)); | ||||
|                     this->core.disass_output(pc.val, mnemonic); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers | ||||
|                 auto* X = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);// calculate next pc value | ||||
| @@ -2483,7 +2408,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 if(this->disass_enabled){ | ||||
|                     /* generate console output when executing the command */ | ||||
|                     this->core.disass_output(pc.val, "dii"); | ||||
| 		             | ||||
|                 } | ||||
|                 // used registers// calculate next pc value | ||||
|                 *NEXT_PC = *PC + 2; | ||||
|   | ||||
| @@ -30,7 +30,7 @@ | ||||
|  * | ||||
|  *******************************************************************************/ | ||||
| 
 | ||||
| #include <iss/arch/tgf_c.h> | ||||
| #include <iss/arch/tgc_c.h> | ||||
| #include <iss/arch/riscv_hart_m_p.h> | ||||
| #include <iss/debugger/gdb_session.h> | ||||
| #include <iss/debugger/server.h> | ||||
| @@ -52,7 +52,7 @@ namespace fp_impl { | ||||
| void add_fp_functions_2_module(::llvm::Module *, unsigned, unsigned); | ||||
| } | ||||
| 
 | ||||
| namespace tgf_c { | ||||
| namespace tgc_c { | ||||
| using namespace ::llvm; | ||||
| using namespace iss::arch; | ||||
| using namespace iss::debugger; | ||||
| @@ -4151,11 +4151,11 @@ template <typename ARCH> inline void vm_impl<ARCH>::gen_trap_check(BasicBlock *b | ||||
|                           bb, this->trap_blk, 1); | ||||
| } | ||||
| 
 | ||||
| } // namespace tgf_c
 | ||||
| } // namespace tgc_c
 | ||||
| 
 | ||||
| template <> | ||||
| std::unique_ptr<vm_if> create<arch::tgf_c>(arch::tgf_c *core, unsigned short port, bool dump) { | ||||
|     auto ret = new tgf_c::vm_impl<arch::tgf_c>(*core, dump); | ||||
| std::unique_ptr<vm_if> create<arch::tgc_c>(arch::tgc_c *core, unsigned short port, bool dump) { | ||||
|     auto ret = new tgc_c::vm_impl<arch::tgc_c>(*core, dump); | ||||
|     if (port != 0) debugger::server<debugger::gdb_session>::run_server(ret, port); | ||||
|     return std::unique_ptr<vm_if>(ret); | ||||
| } | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -30,7 +30,7 @@ | ||||
|  * | ||||
|  *******************************************************************************/ | ||||
| 
 | ||||
| #include <iss/arch/tgf_c.h> | ||||
| #include <iss/arch/tgc_c.h> | ||||
| #include <iss/arch/riscv_hart_m_p.h> | ||||
| #include <iss/debugger/gdb_session.h> | ||||
| #include <iss/debugger/server.h> | ||||
| @@ -49,7 +49,7 @@ | ||||
| 
 | ||||
| namespace iss { | ||||
| namespace tcc { | ||||
| namespace tgf_c { | ||||
| namespace tgc_c { | ||||
| using namespace iss::arch; | ||||
| using namespace iss::debugger; | ||||
| 
 | ||||
| @@ -3251,8 +3251,8 @@ template <typename ARCH> void vm_impl<ARCH>::gen_trap_behavior(tu_builder& tu) { | ||||
| } // namespace mnrv32
 | ||||
| 
 | ||||
| template <> | ||||
| std::unique_ptr<vm_if> create<arch::tgf_c>(arch::tgf_c *core, unsigned short port, bool dump) { | ||||
|     auto ret = new tgf_c::vm_impl<arch::tgf_c>(*core, dump); | ||||
| std::unique_ptr<vm_if> create<arch::tgc_c>(arch::tgc_c *core, unsigned short port, bool dump) { | ||||
|     auto ret = new tgc_c::vm_impl<arch::tgc_c>(*core, dump); | ||||
|     if (port != 0) debugger::server<debugger::gdb_session>::run_server(ret, port); | ||||
|     return std::unique_ptr<vm_if>(ret); | ||||
| } | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Reference in New Issue
	
	Block a user