Restructured DBT function to encapsulate the compilation process
This should enable the implementation of multi-threading of the compilation process
This commit is contained in:
		| @@ -16,7 +16,8 @@ set(APP_SOURCES main.cpp) | ||||
| set(LIBRARY_NAME risc-v) | ||||
|  | ||||
| # Define the library | ||||
| add_library(${LIBRARY_NAME} SHARED ${LIB_SOURCES}) | ||||
| #add_library(${LIBRARY_NAME} SHARED ${LIB_SOURCES}) | ||||
| add_library(${LIBRARY_NAME} ${LIB_SOURCES}) | ||||
| SET(${LIBRARY_NAME} -Wl,-whole-archive -l${LIBRARY_NAME} -Wl,-no-whole-archive) | ||||
| set_target_properties(${LIBRARY_NAME} PROPERTIES | ||||
|   VERSION ${VERSION}  # ${VERSION} was defined in the main CMakeLists. | ||||
|   | ||||
| @@ -62,7 +62,7 @@ public: | ||||
|  | ||||
|     vm_impl(); | ||||
|  | ||||
|     vm_impl(ARCH &core, bool dump = false); | ||||
|     vm_impl(ARCH &core, unsigned core_id = 0, unsigned cluster_id = 0); | ||||
|  | ||||
|     void enableDebug(bool enable) { super::sync_exec = super::ALL_SYNC; } | ||||
|  | ||||
| @@ -102,13 +102,13 @@ protected: | ||||
|  | ||||
|  | ||||
|     inline llvm::Value *gen_reg_load(unsigned i, unsigned level = 0) { | ||||
|         return this->builder->CreateLoad(get_reg_ptr(i), false); | ||||
|         return this->builder.CreateLoad(get_reg_ptr(i), false); | ||||
|     } | ||||
|  | ||||
|     inline void gen_set_pc(virt_addr_t pc, unsigned reg_num) { | ||||
|         llvm::Value *next_pc_v = this->builder->CreateSExtOrTrunc(this->gen_const(traits<ARCH>::XLEN, pc.val), | ||||
|         llvm::Value *next_pc_v = this->builder.CreateSExtOrTrunc(this->gen_const(traits<ARCH>::XLEN, pc.val), | ||||
|                                                                   this->get_type(traits<ARCH>::XLEN)); | ||||
|         this->builder->CreateStore(next_pc_v, get_reg_ptr(reg_num), true); | ||||
|         this->builder.CreateStore(next_pc_v, get_reg_ptr(reg_num), true); | ||||
|     } | ||||
|  | ||||
|     // some compile time constants | ||||
| @@ -186,30 +186,11 @@ private: | ||||
|      ****************************************************************************/ | ||||
|     std::tuple<vm::continuation_e, llvm::BasicBlock *> illegal_intruction(virt_addr_t &pc, code_word_t instr, | ||||
|                                                                           llvm::BasicBlock *bb) { | ||||
|         bb->setName("illegal_instruction"); | ||||
|  | ||||
| //        this->gen_sync(iss::PRE_SYNC); | ||||
| //        if(this->disass_enabled){ | ||||
| //            /* generate console output when executing the command */ | ||||
| //            boost::format ins_fmter("DB x%1$d"); | ||||
| //            ins_fmter % (uint64_t)instr; | ||||
| //            std::vector<llvm::Value*> args { | ||||
| //                this->core_ptr, | ||||
| //                this->gen_const(64, pc.val), | ||||
| //                this->builder->CreateGlobalStringPtr(ins_fmter.str()), | ||||
| //            }; | ||||
| //            this->builder->CreateCall(this->mod->getFunction("print_disass"), args); | ||||
| //        } | ||||
| //        pc = pc + ((instr & 3) == 3 ? 4 : 2); | ||||
| //        this->gen_raise_trap(0, 2);     // illegal instruction trap | ||||
| //        this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ | ||||
| //        this->gen_trap_check(this->leave_blk); | ||||
| //        return std::make_tuple(iss::vm::BRANCH, nullptr); | ||||
|         // this->gen_sync(iss::PRE_SYNC); | ||||
|         this->builder->CreateStore(this->builder->CreateLoad(get_reg_ptr(traits<ARCH>::NEXT_PC), true), | ||||
|         this->gen_sync(iss::PRE_SYNC); | ||||
|         this->builder.CreateStore(this->builder.CreateLoad(get_reg_ptr(traits<ARCH>::NEXT_PC), true), | ||||
|                                    get_reg_ptr(traits<ARCH>::PC), true); | ||||
|         this->builder->CreateStore( | ||||
|             this->builder->CreateAdd(this->builder->CreateLoad(get_reg_ptr(traits<ARCH>::ICOUNT), true), | ||||
|         this->builder.CreateStore( | ||||
|             this->builder.CreateAdd(this->builder.CreateLoad(get_reg_ptr(traits<ARCH>::ICOUNT), true), | ||||
|                                      this->gen_const(64U, 1)), | ||||
|             get_reg_ptr(traits<ARCH>::ICOUNT), true); | ||||
|         if (this->debugging_enabled()) this->gen_sync(iss::PRE_SYNC); | ||||
| @@ -229,8 +210,8 @@ template <typename CODE_WORD> void debug_fn(CODE_WORD insn) { | ||||
| template <typename ARCH> vm_impl<ARCH>::vm_impl() { this(new ARCH()); } | ||||
|  | ||||
| template <typename ARCH> | ||||
| vm_impl<ARCH>::vm_impl(ARCH &core, bool dump) | ||||
| : vm::vm_base<ARCH>(core, dump) { | ||||
| vm_impl<ARCH>::vm_impl(ARCH &core, unsigned core_id, unsigned cluster_id) | ||||
| : vm::vm_base<ARCH>(core, core_id, cluster_id) { | ||||
|     qlut[0] = lut_00.data(); | ||||
|     qlut[1] = lut_01.data(); | ||||
|     qlut[2] = lut_10.data(); | ||||
| @@ -239,7 +220,6 @@ vm_impl<ARCH>::vm_impl(ARCH &core, bool dump) | ||||
|         auto quantrant = instr.value & 0x3; | ||||
|         expand_bit_mask(29, lutmasks[quantrant], instr.value >> 2, instr.mask >> 2, 0, qlut[quantrant], instr.op); | ||||
|     } | ||||
|     this->sync_exec = static_cast<sync_type>(this->sync_exec | core.needed_sync()); | ||||
| } | ||||
|  | ||||
| template <typename ARCH> | ||||
| @@ -278,44 +258,44 @@ vm_impl<ARCH>::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, | ||||
| } | ||||
|  | ||||
| template <typename ARCH> void vm_impl<ARCH>::gen_leave_behavior(llvm::BasicBlock *leave_blk) { | ||||
|     this->builder->SetInsertPoint(leave_blk); | ||||
|     this->builder->CreateRet(this->builder->CreateLoad(get_reg_ptr(arch::traits<ARCH>::NEXT_PC), false)); | ||||
|     this->builder.SetInsertPoint(leave_blk); | ||||
|     this->builder.CreateRet(this->builder.CreateLoad(get_reg_ptr(arch::traits<ARCH>::NEXT_PC), false)); | ||||
| } | ||||
|  | ||||
| template <typename ARCH> void vm_impl<ARCH>::gen_raise_trap(uint16_t trap_id, uint16_t cause) { | ||||
|     auto *TRAP_val = this->gen_const(32, 0x80 << 24 | (cause << 16) | trap_id); | ||||
|     this->builder->CreateStore(TRAP_val, get_reg_ptr(traits<ARCH>::TRAP_STATE), true); | ||||
|     this->builder.CreateStore(TRAP_val, get_reg_ptr(traits<ARCH>::TRAP_STATE), true); | ||||
| } | ||||
|  | ||||
| template <typename ARCH> void vm_impl<ARCH>::gen_leave_trap(unsigned lvl) { | ||||
|     std::vector<llvm::Value *> args{ | ||||
|         this->core_ptr, llvm::ConstantInt::get(getContext(), llvm::APInt(64, lvl)), | ||||
|     }; | ||||
|     this->builder->CreateCall(this->mod->getFunction("leave_trap"), args); | ||||
|     this->builder.CreateCall(this->mod->getFunction("leave_trap"), args); | ||||
|     auto *PC_val = this->gen_read_mem(traits<ARCH>::CSR, (lvl << 8) + 0x41, traits<ARCH>::XLEN / 8); | ||||
|     this->builder->CreateStore(PC_val, get_reg_ptr(traits<ARCH>::NEXT_PC), false); | ||||
|     this->builder.CreateStore(PC_val, get_reg_ptr(traits<ARCH>::NEXT_PC), false); | ||||
| } | ||||
|  | ||||
| template <typename ARCH> void vm_impl<ARCH>::gen_wait(unsigned type) { | ||||
|     std::vector<llvm::Value *> args{ | ||||
|         this->core_ptr, llvm::ConstantInt::get(getContext(), llvm::APInt(64, type)), | ||||
|     }; | ||||
|     this->builder->CreateCall(this->mod->getFunction("wait"), args); | ||||
|     this->builder.CreateCall(this->mod->getFunction("wait"), args); | ||||
| } | ||||
|  | ||||
| template <typename ARCH> void vm_impl<ARCH>::gen_trap_behavior(llvm::BasicBlock *trap_blk) { | ||||
|     this->builder->SetInsertPoint(trap_blk); | ||||
|     auto *trap_state_val = this->builder->CreateLoad(get_reg_ptr(traits<ARCH>::TRAP_STATE), true); | ||||
|     this->builder.SetInsertPoint(trap_blk); | ||||
|     auto *trap_state_val = this->builder.CreateLoad(get_reg_ptr(traits<ARCH>::TRAP_STATE), true); | ||||
|     std::vector<llvm::Value *> args{this->core_ptr, this->adj_to64(trap_state_val), | ||||
|                                     this->adj_to64(this->builder->CreateLoad(get_reg_ptr(traits<ARCH>::PC), false))}; | ||||
|     this->builder->CreateCall(this->mod->getFunction("enter_trap"), args); | ||||
|     auto *trap_addr_val = this->builder->CreateLoad(get_reg_ptr(traits<ARCH>::NEXT_PC), false); | ||||
|     this->builder->CreateRet(trap_addr_val); | ||||
|                                     this->adj_to64(this->builder.CreateLoad(get_reg_ptr(traits<ARCH>::PC), false))}; | ||||
|     this->builder.CreateCall(this->mod->getFunction("enter_trap"), args); | ||||
|     auto *trap_addr_val = this->builder.CreateLoad(get_reg_ptr(traits<ARCH>::NEXT_PC), false); | ||||
|     this->builder.CreateRet(trap_addr_val); | ||||
| } | ||||
|  | ||||
| template <typename ARCH> inline void vm_impl<ARCH>::gen_trap_check(llvm::BasicBlock *bb) { | ||||
|     auto *v = this->builder->CreateLoad(get_reg_ptr(arch::traits<ARCH>::TRAP_STATE), true); | ||||
|     this->gen_cond_branch(this->builder->CreateICmp( | ||||
|     auto *v = this->builder.CreateLoad(get_reg_ptr(arch::traits<ARCH>::TRAP_STATE), true); | ||||
|     this->gen_cond_branch(this->builder.CreateICmp( | ||||
|                               ICmpInst::ICMP_EQ, v, | ||||
|                               llvm::ConstantInt::get(getContext(), llvm::APInt(v->getType()->getIntegerBitWidth(), 0))), | ||||
|                           bb, this->trap_blk, 1); | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -67,6 +67,6 @@ void rv32imac::reset(uint64_t address) { | ||||
|  | ||||
| uint8_t *rv32imac::get_regs_base_ptr() { return reinterpret_cast<uint8_t *>(®); } | ||||
|  | ||||
| rv32imac::phys_addr_t rv32imac::v2p(const iss::addr_t &pc) { | ||||
| rv32imac::phys_addr_t rv32imac::virt2phys(const iss::addr_t &pc) { | ||||
|     return phys_addr_t(pc); // change logical address to physical address | ||||
| } | ||||
|   | ||||
| @@ -67,6 +67,6 @@ void rv64ia::reset(uint64_t address) { | ||||
|  | ||||
| uint8_t *rv64ia::get_regs_base_ptr() { return reinterpret_cast<uint8_t *>(®); } | ||||
|  | ||||
| rv64ia::phys_addr_t rv64ia::v2p(const iss::addr_t &pc) { | ||||
| rv64ia::phys_addr_t rv64ia::virt2phys(const iss::addr_t &pc) { | ||||
|     return phys_addr_t(pc); // change logical address to physical address | ||||
| } | ||||
|   | ||||
| @@ -54,7 +54,7 @@ int main(int argc, char *argv[]) { | ||||
|     // clang-format off | ||||
|     desc.add_options() | ||||
|         ("help,h", "Print help message") | ||||
|         ("loglevel,l", po::value<int>()->implicit_value(2), "Sets logging verbosity") | ||||
|         ("verbose,v", po::value<int>()->implicit_value(0), "Sets logging verbosity") | ||||
|         ("logfile,f", po::value<std::string>(), "Sets default log file.") | ||||
|         ("disass,d", po::value<std::string>()->implicit_value(""), "Enables disassembly") | ||||
|         ("elf", po::value<std::vector<std::string>>(), "ELF file(s) to load") | ||||
| @@ -62,10 +62,8 @@ int main(int argc, char *argv[]) { | ||||
|         ("input,i", po::value<std::string>(), "the elf file to load (instead of hex files)") | ||||
|         ("dump-ir", "dump the intermediate representation") | ||||
|         ("cycles,c", po::value<int64_t>()->default_value(-1), "number of cycles to run") | ||||
|         ("systemc,s", "Run as SystemC simulation") | ||||
|         ("time", po::value<int>(), "SystemC simulation time in ms") | ||||
|         ("reset,r", po::value<std::string>(), "reset address") | ||||
|         ("trace", po::value<uint8_t>(), "enable tracing, or cmbintation of 1=signals and 2=TX text, 4=TX compressed text, 6=TX in SQLite") | ||||
|         ("mem,m", po::value<std::string>(), "the memory input file") | ||||
|         ("isa", po::value<std::string>()->default_value("rv32imac"), "isa to use for simulation"); | ||||
|     // clang-format on | ||||
| @@ -86,8 +84,8 @@ int main(int argc, char *argv[]) { | ||||
|     } | ||||
|     std::vector<std::string> args = collect_unrecognized(parsed.options, po::include_positional); | ||||
|  | ||||
|     if (clim.count("loglevel")) { | ||||
|         auto l = logging::as_log_level(clim["loglevel"].as<int>()); | ||||
|     if (clim.count("verbose")) { | ||||
|         auto l = logging::as_log_level(clim["verbose"].as<int>()); | ||||
|         LOGGER(DEFAULT)::reporting_level() = l; | ||||
|         LOGGER(connection)::reporting_level() = l; | ||||
|     } | ||||
| @@ -104,18 +102,20 @@ int main(int argc, char *argv[]) { | ||||
|         bool dump = clim.count("dump-ir"); | ||||
|         // instantiate the simulator | ||||
|         std::unique_ptr<iss::vm_if> vm{nullptr}; | ||||
|         if (clim["isa"].as<std::string>().substr(0, 4)=="rv64") { | ||||
|         std::string isa_opt(clim["isa"].as<std::string>()); | ||||
|         if (isa_opt.substr(0, 4)=="rv64") { | ||||
|             iss::arch::rv64ia* cpu = new iss::arch::riscv_hart_msu_vp<iss::arch::rv64ia>(); | ||||
|             vm = iss::create(cpu, clim["gdb-port"].as<unsigned>(), dump); | ||||
|         } else if (clim["isa"].as<std::string>().substr(0, 4)=="rv32") { | ||||
|             vm = iss::create(cpu, clim["gdb-port"].as<unsigned>()); | ||||
|         } else if (isa_opt.substr(0, 4)=="rv32") { | ||||
|             iss::arch::rv32imac* cpu = new iss::arch::riscv_hart_msu_vp<iss::arch::rv32imac>(); | ||||
|             vm = iss::create(cpu, clim["gdb-port"].as<unsigned>(), dump); | ||||
|             vm = iss::create(cpu, clim["gdb-port"].as<unsigned>()); | ||||
|         } else { | ||||
|             LOG(ERROR) << "Illegal argument value for '--isa': " << clim["isa"].as<std::string>() << std::endl; | ||||
|             return 127; | ||||
|         } | ||||
|         if (clim.count("elf")) | ||||
|             for (std::string input : clim["elf"].as<std::vector<std::string>>()) vm->get_arch()->load_file(input); | ||||
|             for (std::string input : clim["elf"].as<std::vector<std::string>>()) | ||||
|                 vm->get_arch()->load_file(input); | ||||
|         if (clim.count("mem")) | ||||
|             vm->get_arch()->load_file(clim["mem"].as<std::string>(), iss::arch::traits<iss::arch::rv32imac>::MEM); | ||||
|         for (std::string input : args) vm->get_arch()->load_file(input);// treat remaining arguments as elf files | ||||
| @@ -138,7 +138,7 @@ int main(int argc, char *argv[]) { | ||||
|         } | ||||
|         int64_t cycles = -1; | ||||
|         cycles = clim["cycles"].as<int64_t>(); | ||||
|         return vm->start(cycles); | ||||
|         return vm->start(cycles, dump); | ||||
|     } catch (std::exception &e) { | ||||
|         LOG(ERROR) << "Unhandled Exception reached the top of main: " << e.what() << ", application will now exit" | ||||
|                    << std::endl; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user