rework abort conditions
This commit is contained in:
parent
ff3fa19208
commit
4e0f20eba0
|
@ -85,7 +85,7 @@ protected:
|
||||||
|
|
||||||
inline const char *name(size_t index){return traits::reg_aliases.at(index);}
|
inline const char *name(size_t index){return traits::reg_aliases.at(index);}
|
||||||
|
|
||||||
virt_addr_t execute_inst(virt_addr_t start, std::function<bool(virt_addr_t&)> pred) override;
|
virt_addr_t execute_inst(finish_cond_e cond, virt_addr_t start, uint64_t icount_limit) override;
|
||||||
|
|
||||||
// some compile time constants
|
// some compile time constants
|
||||||
// enum { MASK16 = 0b1111110001100011, MASK32 = 0b11111111111100000111000001111111 };
|
// enum { MASK16 = 0b1111110001100011, MASK32 = 0b11111111111100000111000001111111 };
|
||||||
|
@ -273,19 +273,21 @@ vm_impl<ARCH>::vm_impl(ARCH &core, unsigned core_id, unsigned cluster_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ARCH>
|
template <typename ARCH>
|
||||||
typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(virt_addr_t start, std::function<bool(virt_addr_t&)> pred) {
|
typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e cond, virt_addr_t start, uint64_t icount_limit){
|
||||||
// we fetch at max 4 byte, alignment is 2
|
// we fetch at max 4 byte, alignment is 2
|
||||||
enum {TRAP_ID=1<<16};
|
enum {TRAP_ID=1<<16};
|
||||||
code_word_t insn = 0;
|
code_word_t insn = 0;
|
||||||
auto *const data = (uint8_t *)&insn;
|
auto *const data = (uint8_t *)&insn;
|
||||||
auto pc=start;
|
auto pc=start;
|
||||||
while(pred(pc)){
|
while(!core.should_stop() &&
|
||||||
|
!((cond & finish_cond_e::COUNT_LIMIT) && core.get_icount() < icount)){
|
||||||
auto res = fetch_ins(pc, data);
|
auto res = fetch_ins(pc, data);
|
||||||
if(res!=iss::Ok){
|
if(res!=iss::Ok){
|
||||||
auto new_pc = super::core.enter_trap(TRAP_ID, pc.val);
|
auto new_pc = super::core.enter_trap(TRAP_ID, pc.val);
|
||||||
res = fetch_ins(virt_addr_t{access_type::FETCH, new_pc}, data);
|
res = fetch_ins(virt_addr_t{access_type::FETCH, new_pc}, data);
|
||||||
if(res!=iss::Ok) throw simulation_stopped(0);
|
if(res!=iss::Ok) throw simulation_stopped(0);
|
||||||
}
|
}
|
||||||
|
if ((cond & finish_cond_e::JUMP_TO_SELF) && (insn == 0x0000006f || (insn&0xffff)==0xa001)) throw simulation_stopped(0); // 'J 0' or 'C.J 0'
|
||||||
auto lut_val = extract_fields(insn);
|
auto lut_val = extract_fields(insn);
|
||||||
auto f = qlut[insn & 0x3][lut_val];
|
auto f = qlut[insn & 0x3][lut_val];
|
||||||
if (!f)
|
if (!f)
|
||||||
|
|
|
@ -85,7 +85,7 @@ protected:
|
||||||
|
|
||||||
inline const char *name(size_t index){return traits::reg_aliases.at(index);}
|
inline const char *name(size_t index){return traits::reg_aliases.at(index);}
|
||||||
|
|
||||||
virt_addr_t execute_inst(virt_addr_t start, std::function<bool(virt_addr_t&)> pred) override;
|
virt_addr_t execute_inst(finish_cond_e cond, virt_addr_t start, uint64_t icount_limit) override;
|
||||||
|
|
||||||
// some compile time constants
|
// some compile time constants
|
||||||
// enum { MASK16 = 0b1111110001100011, MASK32 = 0b11111111111100000111000001111111 };
|
// enum { MASK16 = 0b1111110001100011, MASK32 = 0b11111111111100000111000001111111 };
|
||||||
|
@ -3436,19 +3436,23 @@ vm_impl<ARCH>::vm_impl(ARCH &core, unsigned core_id, unsigned cluster_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ARCH>
|
template <typename ARCH>
|
||||||
typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(virt_addr_t start, std::function<bool(virt_addr_t&)> pred) {
|
typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e cond, virt_addr_t start, uint64_t icount_limit){
|
||||||
// we fetch at max 4 byte, alignment is 2
|
// we fetch at max 4 byte, alignment is 2
|
||||||
enum {TRAP_ID=1<<16};
|
enum {TRAP_ID=1<<16};
|
||||||
code_word_t insn = 0;
|
code_word_t insn = 0;
|
||||||
auto *const data = (uint8_t *)&insn;
|
auto *const data = (uint8_t *)&insn;
|
||||||
auto pc=start;
|
auto pc=start;
|
||||||
while(pred(pc)){
|
while(!this->core.should_stop() &&
|
||||||
|
!((cond & finish_cond_e::COUNT_LIMIT) == finish_cond_e::COUNT_LIMIT &&
|
||||||
|
this->core.get_icount() < icount_limit)){
|
||||||
auto res = fetch_ins(pc, data);
|
auto res = fetch_ins(pc, data);
|
||||||
if(res!=iss::Ok){
|
if(res!=iss::Ok){
|
||||||
auto new_pc = super::core.enter_trap(TRAP_ID, pc.val);
|
auto new_pc = super::core.enter_trap(TRAP_ID, pc.val);
|
||||||
res = fetch_ins(virt_addr_t{access_type::FETCH, new_pc}, data);
|
res = fetch_ins(virt_addr_t{access_type::FETCH, new_pc}, data);
|
||||||
if(res!=iss::Ok) throw simulation_stopped(0);
|
if(res!=iss::Ok) throw simulation_stopped(0);
|
||||||
}
|
}
|
||||||
|
if ((cond & finish_cond_e::JUMP_TO_SELF) == finish_cond_e::JUMP_TO_SELF &&
|
||||||
|
(insn == 0x0000006f || (insn&0xffff)==0xa001)) throw simulation_stopped(0); // 'J 0' or 'C.J 0'
|
||||||
auto lut_val = extract_fields(insn);
|
auto lut_val = extract_fields(insn);
|
||||||
auto f = qlut[insn & 0x3][lut_val];
|
auto f = qlut[insn & 0x3][lut_val];
|
||||||
if (!f)
|
if (!f)
|
||||||
|
|
Loading…
Reference in New Issue