diff --git a/gen_input/templates/interp/CORENAME.cpp.gtl b/gen_input/templates/interp/CORENAME.cpp.gtl index da349ba..99e60ac 100644 --- a/gen_input/templates/interp/CORENAME.cpp.gtl +++ b/gen_input/templates/interp/CORENAME.cpp.gtl @@ -117,6 +117,8 @@ protected: this->core.wait_until(type); } + uint64_t fetch_count{0}; + using yield_t = boost::coroutines2::coroutine::push_type; using coro_t = boost::coroutines2::coroutine::pull_type; std::vector spawn_blocks; @@ -219,6 +221,7 @@ private: }); } } + typename arch::traits::opcode_e decode_instr(decoding_tree_node* node, code_word_t word){ if(!node->children.size()){ if(node->instrs.size() == 1) return node->instrs[0].op; @@ -268,16 +271,20 @@ vm_impl::vm_impl(ARCH &core, unsigned core_id, unsigned cluster_id) populate_decoding_tree(root); } -inline bool is_count_limit_enabled(finish_cond_e cond){ +inline bool is_icount_limit_enabled(finish_cond_e cond){ return (cond & finish_cond_e::ICOUNT_LIMIT) == finish_cond_e::ICOUNT_LIMIT; } +inline bool is_fcount_limit_enabled(finish_cond_e cond){ + return (cond & finish_cond_e::FCOUNT_LIMIT) == finish_cond_e::FCOUNT_LIMIT; +} + inline bool is_jump_to_self_enabled(finish_cond_e cond){ return (cond & finish_cond_e::JUMP_TO_SELF) == finish_cond_e::JUMP_TO_SELF; } template -typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e cond, virt_addr_t start, uint64_t icount_limit){ +typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e cond, virt_addr_t start, uint64_t count_limit){ auto pc=start; auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); auto* NEXT_PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::NEXT_PC]); @@ -290,7 +297,9 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto *const data = reinterpret_cast(&instr); while(!this->core.should_stop() && - !(is_count_limit_enabled(cond) && icount >= icount_limit)){ + !(is_icount_limit_enabled(cond) && icount >= count_limit) && + !(is_fcount_limit_enabled(cond) && fetch_count >= count_limit)){ + fetch_count++; if(fetch_ins(pc, data)!=iss::Ok){ this->do_sync(POST_SYNC, std::numeric_limits::max()); pc.val = super::core.enter_trap(std::numeric_limits::max(), pc.val, 0); diff --git a/src/vm/interp/vm_tgc5c.cpp b/src/vm/interp/vm_tgc5c.cpp index 0411fd2..a8d1e8f 100644 --- a/src/vm/interp/vm_tgc5c.cpp +++ b/src/vm/interp/vm_tgc5c.cpp @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2021 MINRES Technologies GmbH + * Copyright (C) 20217-2024 MINRES Technologies GmbH * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -113,6 +113,8 @@ protected: this->core.wait_until(type); } + uint64_t fetch_count{0}; + using yield_t = boost::coroutines2::coroutine::push_type; using coro_t = boost::coroutines2::coroutine::pull_type; std::vector spawn_blocks; @@ -299,6 +301,7 @@ private: }); } } + typename arch::traits::opcode_e decode_instr(decoding_tree_node* node, code_word_t word){ if(!node->children.size()){ if(node->instrs.size() == 1) return node->instrs[0].op; @@ -348,16 +351,20 @@ vm_impl::vm_impl(ARCH &core, unsigned core_id, unsigned cluster_id) populate_decoding_tree(root); } -inline bool is_count_limit_enabled(finish_cond_e cond){ +inline bool is_icount_limit_enabled(finish_cond_e cond){ return (cond & finish_cond_e::ICOUNT_LIMIT) == finish_cond_e::ICOUNT_LIMIT; } +inline bool is_fcount_limit_enabled(finish_cond_e cond){ + return (cond & finish_cond_e::FCOUNT_LIMIT) == finish_cond_e::FCOUNT_LIMIT; +} + inline bool is_jump_to_self_enabled(finish_cond_e cond){ return (cond & finish_cond_e::JUMP_TO_SELF) == finish_cond_e::JUMP_TO_SELF; } template -typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e cond, virt_addr_t start, uint64_t icount_limit){ +typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e cond, virt_addr_t start, uint64_t count_limit){ auto pc=start; auto* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); auto* NEXT_PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::NEXT_PC]); @@ -370,7 +377,9 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto *const data = reinterpret_cast(&instr); while(!this->core.should_stop() && - !(is_count_limit_enabled(cond) && icount >= icount_limit)){ + !(is_icount_limit_enabled(cond) && icount >= count_limit) && + !(is_fcount_limit_enabled(cond) && fetch_count >= count_limit)){ + fetch_count++; if(fetch_ins(pc, data)!=iss::Ok){ this->do_sync(POST_SYNC, std::numeric_limits::max()); pc.val = super::core.enter_trap(std::numeric_limits::max(), pc.val, 0); @@ -2718,4 +2727,4 @@ volatile std::array dummy = { }; } } -// clang-format on +// clang-format on \ No newline at end of file