diff --git a/gen_input/templates/CORENAME.h.gtl b/gen_input/templates/CORENAME.h.gtl index 2a6a5b8..4cd1e49 100644 --- a/gen_input/templates/CORENAME.h.gtl +++ b/gen_input/templates/CORENAME.h.gtl @@ -131,8 +131,6 @@ struct ${coreDef.name.toLowerCase()}: public arch_if { uint8_t* get_regs_base_ptr() override; - inline uint64_t get_icount() { return reg.icount; } - inline bool should_stop() { return interrupt_sim; } inline uint64_t stop_code() { return interrupt_sim; } @@ -141,8 +139,6 @@ struct ${coreDef.name.toLowerCase()}: public arch_if { virtual iss::sync_type needed_sync() const { return iss::NO_SYNC; } - inline uint32_t get_last_branch() { return reg.last_branch; } - #pragma pack(push, 1) struct ${coreDef.name}_regs {<% diff --git a/gen_input/templates/asmjit/CORENAME.cpp.gtl b/gen_input/templates/asmjit/CORENAME.cpp.gtl index 8571d58..3b5486f 100644 --- a/gen_input/templates/asmjit/CORENAME.cpp.gtl +++ b/gen_input/templates/asmjit/CORENAME.cpp.gtl @@ -96,7 +96,7 @@ protected: using this_class = vm_impl; using compile_func = continuation_e (this_class::*)(virt_addr_t&, code_word_t, jit_holder&); - continuation_e gen_single_inst_behavior(virt_addr_t&, unsigned int &, jit_holder&) override; + continuation_e gen_single_inst_behavior(virt_addr_t&, jit_holder&) override; enum globals_e {TVAL = 0, GLOBALS_SIZE}; void gen_block_prologue(jit_holder& jh) override; void gen_block_epilogue(jit_holder& jh) override; @@ -221,7 +221,7 @@ vm_impl::vm_impl(ARCH &core, unsigned core_id, unsigned cluster_id) }()) {} template -continuation_e vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, jit_holder& jh) { +continuation_e vm_impl::gen_single_inst_behavior(virt_addr_t &pc, jit_holder& jh) { enum {TRAP_ID=1<<16}; code_word_t instr = 0; phys_addr_t paddr(pc); @@ -233,7 +233,6 @@ continuation_e vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned return ILLEGAL_FETCH; if (instr == 0x0000006f || (instr&0xffff)==0xa001) return JUMP_TO_SELF; - ++inst_cnt; uint32_t inst_index = instr_decoder.decode_instr(instr); compile_func f = nullptr; if(inst_index < instr_descr.size()) diff --git a/gen_input/templates/interp/CORENAME.cpp.gtl b/gen_input/templates/interp/CORENAME.cpp.gtl index d2ebedd..c893bbd 100644 --- a/gen_input/templates/interp/CORENAME.cpp.gtl +++ b/gen_input/templates/interp/CORENAME.cpp.gtl @@ -199,9 +199,6 @@ template void debug_fn(CODE_WORD insn) { volatile CODE_WORD x = insn; insn = 2 * x; } - -template vm_impl::vm_impl() { this(new ARCH()); } - // according to // https://stackoverflow.com/questions/8871204/count-number-of-1s-in-binary-representation #ifdef __GCC__ diff --git a/gen_input/templates/llvm/CORENAME.cpp.gtl b/gen_input/templates/llvm/CORENAME.cpp.gtl index bf5828d..c7f61dd 100644 --- a/gen_input/templates/llvm/CORENAME.cpp.gtl +++ b/gen_input/templates/llvm/CORENAME.cpp.gtl @@ -101,7 +101,7 @@ protected: return super::gen_cond_assign(cond, this->gen_ext(trueVal, size), this->gen_ext(falseVal, size)); } - std::tuple gen_single_inst_behavior(virt_addr_t &, unsigned int &, BasicBlock *) override; + std::tuple gen_single_inst_behavior(virt_addr_t &, BasicBlock *) override; void gen_leave_behavior(BasicBlock *leave_blk) override; void gen_raise_trap(uint16_t trap_id, uint16_t cause); @@ -244,7 +244,7 @@ vm_impl::vm_impl(ARCH &core, unsigned core_id, unsigned cluster_id) template std::tuple -vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, BasicBlock *this_block) { +vm_impl::gen_single_inst_behavior(virt_addr_t &pc, BasicBlock *this_block) { // we fetch at max 4 byte, alignment is 2 enum {TRAP_ID=1<<16}; code_word_t instr = 0; @@ -256,9 +256,10 @@ vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, auto res = this->core.read(paddr, 4, data); if (res != iss::Ok) return std::make_tuple(ILLEGAL_FETCH, nullptr); - if (instr == 0x0000006f || (instr&0xffff)==0xa001) + if (instr == 0x0000006f || (instr&0xffff)==0xa001){ + this->builder.CreateBr(this->leave_blk); return std::make_tuple(JUMP_TO_SELF, nullptr); - ++inst_cnt; + } uint32_t inst_index = instr_decoder.decode_instr(instr); compile_func f = nullptr; if(inst_index < instr_descr.size()) @@ -340,6 +341,10 @@ void vm_impl::gen_instr_epilogue(BasicBlock *bb) { auto* icount_val = this->builder.CreateAdd( this->builder.CreateLoad(this->get_typeptr(arch::traits::ICOUNT), get_reg_ptr(arch::traits::ICOUNT)), this->gen_const(64U, 1)); this->builder.CreateStore(icount_val, get_reg_ptr(arch::traits::ICOUNT), false); + //increment cyclecount + auto* cycle_val = this->builder.CreateAdd( + this->builder.CreateLoad(this->get_typeptr(arch::traits::CYCLE), get_reg_ptr(arch::traits::CYCLE)), this->gen_const(64U, 1)); + this->builder.CreateStore(cycle_val, get_reg_ptr(arch::traits::CYCLE), false); } } // namespace ${coreDef.name.toLowerCase()} diff --git a/gen_input/templates/tcc/CORENAME.cpp.gtl b/gen_input/templates/tcc/CORENAME.cpp.gtl index 06317b0..c4ff028 100644 --- a/gen_input/templates/tcc/CORENAME.cpp.gtl +++ b/gen_input/templates/tcc/CORENAME.cpp.gtl @@ -83,21 +83,21 @@ protected: using vm_base::get_reg_ptr; using this_class = vm_impl; - using compile_ret_t = std::tuple; + using compile_ret_t = continuation_e; using compile_func = compile_ret_t (this_class::*)(virt_addr_t &pc, code_word_t instr, tu_builder&); inline const char *name(size_t index){return traits::reg_aliases.at(index);} <% if(fcsr != null) {%> inline const char *fname(size_t index){return index < 32?name(index+traits::F0):"illegal";} - - void add_prologue(tu_builder& tu) override; <%}%> + void add_prologue(tu_builder& tu) override; + void setup_module(std::string m) override { super::setup_module(m); } - compile_ret_t gen_single_inst_behavior(virt_addr_t &, unsigned int &, tu_builder&) override; + compile_ret_t gen_single_inst_behavior(virt_addr_t &, tu_builder&) override; void gen_trap_behavior(tu_builder& tu) override; @@ -176,6 +176,7 @@ private: auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]); pc=pc+ ${instr.length/8}; gen_set_pc(tu, pc, traits::NEXT_PC); + tu("(*cycle)++;"); tu.open_scope(); this->gen_set_tval(tu, instr); <%instr.behavior.eachLine{%>${it} @@ -225,8 +226,8 @@ vm_impl::vm_impl(ARCH &core, unsigned core_id, unsigned cluster_id) }()) {} template -std::tuple -vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, tu_builder& tu) { +continuation_e +vm_impl::gen_single_inst_behavior(virt_addr_t &pc, tu_builder& tu) { // we fetch at max 4 byte, alignment is 2 enum {TRAP_ID=1<<16}; code_word_t instr = 0; @@ -238,7 +239,6 @@ vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, return ILLEGAL_FETCH; if (instr == 0x0000006f || (instr&0xffff)==0xa001) return JUMP_TO_SELF; - ++inst_cnt; uint32_t inst_index = instr_decoder.decode_instr(instr); compile_func f = nullptr; if(inst_index < instr_descr.size()) @@ -273,10 +273,12 @@ template void vm_impl::gen_trap_behavior(tu_builder& tu) { tu.store(traits::LAST_BRANCH, tu.constant(static_cast(UNKNOWN_JUMP),32)); tu("return *next_pc;"); } -<% -if(fcsr != null) {%> template void vm_impl::add_prologue(tu_builder& tu){ std::ostringstream os; + os << tu.add_reg_ptr("trap_state", arch::traits::TRAP_STATE, this->regs_base_ptr); + os << tu.add_reg_ptr("pending_trap", arch::traits::PENDING_TRAP, this->regs_base_ptr); + os << tu.add_reg_ptr("cycle", arch::traits::CYCLE, this->regs_base_ptr); +<%if(fcsr != null) {%> os << "uint32_t (*fget_flags)()=" << (uintptr_t)&fget_flags << ";\\n"; os << "uint32_t (*fadd_s)(uint32_t v1, uint32_t v2, uint8_t mode)=" << (uintptr_t)&fadd_s << ";\\n"; os << "uint32_t (*fsub_s)(uint32_t v1, uint32_t v2, uint8_t mode)=" << (uintptr_t)&fsub_s << ";\\n"; @@ -303,9 +305,9 @@ template void vm_impl::add_prologue(tu_builder& tu){ os << "uint64_t (*fcvt_32_64)(uint32_t v1, uint32_t op, uint8_t mode)=" << (uintptr_t)&fcvt_32_64 << ";\\n"; os << "uint32_t (*fcvt_64_32)(uint64_t v1, uint32_t op, uint8_t mode)=" << (uintptr_t)&fcvt_64_32 << ";\\n"; os << "uint32_t (*unbox_s)(uint64_t v)=" << (uintptr_t)&unbox_s << ";\\n"; + <%}%> tu.add_prologue(os.str()); } -<%}%> } // namespace ${coreDef.name.toLowerCase()}