diff --git a/CMakeLists.txt b/CMakeLists.txt index 0825ec4..13c15d3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.3) +cmake_minimum_required(VERSION 3.12) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/../cmake) # main (top) cmake dir set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake) # project specific cmake dir @@ -66,7 +66,7 @@ set(LIBRARY_NAME riscv) # Define the library add_library(${LIBRARY_NAME} ${LIB_SOURCES}) SET(${LIBRARY_NAME} -Wl,-whole-archive -l${LIBRARY_NAME} -Wl,-no-whole-archive) -target_link_libraries(${LIBRARY_NAME} softfloat dbt-core tinycc scc-util) +target_link_libraries(${LIBRARY_NAME} softfloat dbt-core scc-util) set_target_properties(${LIBRARY_NAME} PROPERTIES VERSION ${VERSION} # ${VERSION} was defined in the main CMakeLists. FRAMEWORK FALSE diff --git a/softfloat/CMakeLists.txt b/softfloat/CMakeLists.txt index 8c13151..db9892e 100644 --- a/softfloat/CMakeLists.txt +++ b/softfloat/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.3) +cmake_minimum_required(VERSION 3.12) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/../cmake) # main (top) cmake dir set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake) # project specific cmake dir diff --git a/src/vm/llvm/vm_rv64i.cpp b/src/vm/llvm/vm_rv64i.cpp index 74a4cdf..961f019 100644 --- a/src/vm/llvm/vm_rv64i.cpp +++ b/src/vm/llvm/vm_rv64i.cpp @@ -57,11 +57,11 @@ namespace rv64i { using namespace iss::arch; using namespace llvm; using namespace iss::debugger; -using namespace iss::vm::llvm; +using namespace iss::llvm; template class vm_impl : public vm_base { public: - using super = typename iss::vm::llvm::vm_base; + using super = typename iss::llvm::vm_base; using virt_addr_t = typename super::virt_addr_t; using phys_addr_t = typename super::phys_addr_t; using code_word_t = typename super::code_word_t; diff --git a/src/vm/tcc/vm_mnrv32.cpp b/src/vm/tcc/vm_mnrv32.cpp index ef55987..984605f 100644 --- a/src/vm/tcc/vm_mnrv32.cpp +++ b/src/vm/tcc/vm_mnrv32.cpp @@ -111,16 +111,16 @@ protected: void gen_trap_behavior(std::ostringstream& os) override; - void gen_trap_check(std::ostringstream& os){} + void gen_trap_check(std::ostringstream& os){ + os<< fmt::format("if(*(uint32_t){})!=0) goto trap_blk;\n", get_reg_ptr(arch::traits::TRAP_STATE)); + } inline Value *gen_reg_load(unsigned i, unsigned level = 0) { return this->builder.CreateLoad(get_reg_ptr(i), false); } - inline void gen_set_pc(virt_addr_t pc, unsigned reg_num) { - Value *next_pc_v = this->builder.CreateSExtOrTrunc(this->gen_const(traits::XLEN, pc.val), - this->get_type(traits::XLEN)); - this->builder.CreateStore(next_pc_v, get_reg_ptr(reg_num), true); + inline void gen_set_pc(std::ostringstream& os, virt_addr_t pc, unsigned reg_num) { + os<< fmt::format("*((uint64_t*){}) = {}\n", get_reg_ptr(reg_num), pc.val); } // some compile time constants @@ -301,11 +301,36 @@ private: /* instruction 1: AUIPC */ compile_ret_t __auipc(virt_addr_t& pc, code_word_t instr, std::ostringstream& os){ - } + os<gen_sync(os, PRE_SYNC, 1); + + uint8_t rd = ((bit_sub<7,5>(instr))); + int32_t imm = signextend((bit_sub<12,20>(instr) << 12)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#08x}", fmt::arg("mnemonic", "auipc"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + os<core_ptr, pc.val, mnemonic); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + os<::X0)); + } + this->gen_set_pc(os, pc, traits::NEXT_PC); + this->gen_sync(os, POST_SYNC, 1); + this->gen_trap_check(os); + return std::make_tuple(CONT); + } /* instruction 2: JAL */ compile_ret_t __jal(virt_addr_t& pc, code_word_t instr, std::ostringstream& os){ - this->gen_sync(PRE_SYNC, 0); + this->gen_sync(os, PRE_SYNC, 0); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -320,6 +345,9 @@ private: auto cur_pc_val = pc.val; pc=pc+4; + + + } /* instruction 3: JALR */ @@ -521,12 +549,12 @@ private: /**************************************************************************** * end opcode definitions ****************************************************************************/ - compile_ret_t illegal_intruction(virt_addr_t &pc, code_word_t instr, std::ostringstream& oss) { - vm_impl::gen_sync(iss::PRE_SYNC, instr_descr.size()); + compile_ret_t illegal_intruction(virt_addr_t &pc, code_word_t instr, std::ostringstream& os) { + this->gen_sync(os, iss::PRE_SYNC, instr_descr.size()); pc = pc + ((instr & 3) == 3 ? 4 : 2); gen_raise_trap(0, 2); // illegal instruction trap - vm_impl::gen_sync(iss::POST_SYNC, instr_descr.size()); - vm_impl::gen_trap_check(oss); + this->gen_sync(os, iss::POST_SYNC, instr_descr.size()); + this->gen_trap_check(os); return BRANCH; } }; diff --git a/src/vm/tcc/vm_rv64i.cpp b/src/vm/tcc/vm_rv64i.cpp index eed1ce4..5e28a30 100644 --- a/src/vm/tcc/vm_rv64i.cpp +++ b/src/vm/tcc/vm_rv64i.cpp @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include #ifndef FMT_HEADER_ONLY @@ -57,11 +57,10 @@ namespace tcc { namespace rv64i { using namespace iss::arch; using namespace iss::debugger; -using namespace iss::vm::llvm; template class vm_impl : public vm_base { public: - using super = typename iss::vm::llvm::vm_base; + using super = typename iss::tcc::vm_base; using virt_addr_t = typename super::virt_addr_t; using phys_addr_t = typename super::phys_addr_t; using code_word_t = typename super::code_word_t; @@ -114,16 +113,14 @@ protected: void gen_trap_behavior(BasicBlock *) override; - void gen_trap_check(BasicBlock *bb); + std::string gen_trap_check(BasicBlock *bb); inline Value *gen_reg_load(unsigned i, unsigned level = 0) { return this->builder.CreateLoad(get_reg_ptr(i), false); } - inline void gen_set_pc(virt_addr_t pc, unsigned reg_num) { - Value *next_pc_v = this->builder.CreateSExtOrTrunc(this->gen_const(traits::XLEN, pc.val), - this->get_type(traits::XLEN)); - this->builder.CreateStore(next_pc_v, get_reg_ptr(reg_num), true); + inline std::string gen_set_pc(virt_addr_t pc, unsigned reg_num) { + return fmt::format("*((uint64_t*){}) = {}\n", get_reg_ptr(reg_num), next_pc_v.val); } // some compile time constants @@ -328,6 +325,33 @@ private: /* instruction 1: AUIPC */ compile_ret_t __auipc(virt_addr_t& pc, code_word_t instr, std::ostringstream& os){ + os<gen_sync(PRE_SYNC, 1); + + uint8_t rd = ((bit_sub<7,5>(instr))); + int32_t imm = signextend((bit_sub<12,20>(instr) << 12)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#08x}", fmt::arg("mnemonic", "auipc"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + os<core_ptr, pc.val, mnemonic); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + os<::X0)); + } + os<gen_set_pc(pc, traits::NEXT_PC); + os<gen_sync(POST_SYNC, 1); + os<gen_trap_check(bb); + return std::make_tuple(CONT); + } /* instruction 2: JAL */ @@ -684,12 +708,9 @@ template void vm_impl::gen_trap_behavior(BasicBlock *trap_ this->builder.CreateRet(trap_addr_val); } -template inline void vm_impl::gen_trap_check(BasicBlock *bb) { - auto *v = this->builder.CreateLoad(get_reg_ptr(arch::traits::TRAP_STATE), true); - this->gen_cond_branch(this->builder.CreateICmp( - ICmpInst::ICMP_EQ, v, - ConstantInt::get(getContext(), APInt(v->getType()->getIntegerBitWidth(), 0))), - bb, this->trap_blk, 1); +template inline std::string vm_impl::gen_trap_check(BasicBlock *bb) { + return fmt::format("if(*(uint32_t){})!=0) goto trap_blk;\n", get_reg_ptr(arch::traits::TRAP_STATE)); + } } // namespace rv64i