From c15cdb095580fe80197aab9311bda6c558c8afb0 Mon Sep 17 00:00:00 2001 From: Eyck-Alexander Jentzsch Date: Wed, 14 Aug 2024 11:49:59 +0200 Subject: [PATCH] expands return values of jit creating functions to inhibit endless trapping --- gen_input/templates/asmjit/CORENAME.cpp.gtl | 6 +++--- gen_input/templates/llvm/CORENAME.cpp.gtl | 18 +++++------------- gen_input/templates/tcc/CORENAME.cpp.gtl | 18 +++++------------- src/vm/asmjit/vm_tgc5c.cpp | 6 +++--- src/vm/llvm/vm_tgc5c.cpp | 18 +++++------------- src/vm/tcc/vm_tgc5c.cpp | 18 +++++------------- 6 files changed, 26 insertions(+), 58 deletions(-) diff --git a/gen_input/templates/asmjit/CORENAME.cpp.gtl b/gen_input/templates/asmjit/CORENAME.cpp.gtl index ad21cb8..47b07ca 100644 --- a/gen_input/templates/asmjit/CORENAME.cpp.gtl +++ b/gen_input/templates/asmjit/CORENAME.cpp.gtl @@ -202,7 +202,7 @@ private: gen_raise(jh, 0, 2); gen_sync(jh, POST_SYNC, instr_descr.size()); gen_instr_epilogue(jh); - return BRANCH; + return ILLEGAL_INSTR; } }; @@ -231,9 +231,9 @@ continuation_e vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned paddr = this->core.virt2phys(pc); auto res = this->core.read(paddr, 4, data); if (res != iss::Ok) - throw trap_access(TRAP_ID, pc.val); + return ILLEGAL_FETCH; if (instr == 0x0000006f || (instr&0xffff)==0xa001) - throw simulation_stopped(0); // 'J 0' or 'C.J 0' + return JUMP_TO_SELF; ++inst_cnt; uint32_t inst_index = instr_decoder.decode_instr(instr); compile_func f = nullptr; diff --git a/gen_input/templates/llvm/CORENAME.cpp.gtl b/gen_input/templates/llvm/CORENAME.cpp.gtl index a98b832..9c90f61 100644 --- a/gen_input/templates/llvm/CORENAME.cpp.gtl +++ b/gen_input/templates/llvm/CORENAME.cpp.gtl @@ -212,7 +212,7 @@ private: bb = this->leave_blk; this->gen_instr_epilogue(bb); this->builder.CreateBr(bb); - return std::make_tuple(BRANCH, nullptr); + return std::make_tuple(ILLEGAL_INSTR, nullptr); } }; @@ -247,19 +247,11 @@ vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, auto *const data = (uint8_t *)&instr; if(this->core.has_mmu()) paddr = this->core.virt2phys(pc); - //TODO: re-add page handling -// if ((pc.val & upper_bits) != ((pc.val + 2) & upper_bits)) { // we may cross a page boundary -// auto res = this->core.read(paddr, 2, data); -// if (res != iss::Ok) throw trap_access(TRAP_ID, pc.val); -// if ((instr & 0x3) == 0x3) { // this is a 32bit instruction -// res = this->core.read(this->core.v2p(pc + 2), 2, data + 2); -// } -// } else { auto res = this->core.read(paddr, 4, data); - if (res != iss::Ok) throw trap_access(TRAP_ID, pc.val); -// } - if (instr == 0x0000006f || (instr&0xffff)==0xa001) throw simulation_stopped(0); // 'J 0' or 'C.J 0' - // curr pc on stack + if (res != iss::Ok) + return std::make_tuple(ILLEGAL_FETCH, nullptr); + if (instr == 0x0000006f || (instr&0xffff)==0xa001) + return std::make_tuple(JUMP_TO_SELF, nullptr); ++inst_cnt; uint32_t inst_index = instr_decoder.decode_instr(instr); compile_func f = nullptr; diff --git a/gen_input/templates/tcc/CORENAME.cpp.gtl b/gen_input/templates/tcc/CORENAME.cpp.gtl index ec327a1..06317b0 100644 --- a/gen_input/templates/tcc/CORENAME.cpp.gtl +++ b/gen_input/templates/tcc/CORENAME.cpp.gtl @@ -200,7 +200,7 @@ private: this->gen_set_tval(tu, instr); vm_impl::gen_sync(tu, iss::POST_SYNC, instr_descr.size()); vm_impl::gen_trap_check(tu); - return BRANCH; + return ILLEGAL_INSTR; } }; @@ -233,19 +233,11 @@ vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, phys_addr_t paddr(pc); if(this->core.has_mmu()) paddr = this->core.virt2phys(pc); - //TODO: re-add page handling -// if ((pc.val & upper_bits) != ((pc.val + 2) & upper_bits)) { // we may cross a page boundary -// auto res = this->core.read(paddr, 2, data); -// if (res != iss::Ok) throw trap_access(TRAP_ID, pc.val); -// if ((insn & 0x3) == 0x3) { // this is a 32bit instruction -// res = this->core.read(this->core.v2p(pc + 2), 2, data + 2); -// } -// } else { auto res = this->core.read(paddr, 4, reinterpret_cast(&instr)); - if (res != iss::Ok) throw trap_access(TRAP_ID, pc.val); -// } - if (instr == 0x0000006f || (instr&0xffff)==0xa001) throw simulation_stopped(0); // 'J 0' or 'C.J 0' - // curr pc on stack + if (res != iss::Ok) + 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; diff --git a/src/vm/asmjit/vm_tgc5c.cpp b/src/vm/asmjit/vm_tgc5c.cpp index 7f394d8..deb5004 100644 --- a/src/vm/asmjit/vm_tgc5c.cpp +++ b/src/vm/asmjit/vm_tgc5c.cpp @@ -4766,7 +4766,7 @@ private: gen_raise(jh, 0, 2); gen_sync(jh, POST_SYNC, instr_descr.size()); gen_instr_epilogue(jh); - return BRANCH; + return ILLEGAL_INSTR; } }; @@ -4795,9 +4795,9 @@ continuation_e vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned paddr = this->core.virt2phys(pc); auto res = this->core.read(paddr, 4, data); if (res != iss::Ok) - throw trap_access(TRAP_ID, pc.val); + return ILLEGAL_FETCH; if (instr == 0x0000006f || (instr&0xffff)==0xa001) - throw simulation_stopped(0); // 'J 0' or 'C.J 0' + return JUMP_TO_SELF; ++inst_cnt; uint32_t inst_index = instr_decoder.decode_instr(instr); compile_func f = nullptr; diff --git a/src/vm/llvm/vm_tgc5c.cpp b/src/vm/llvm/vm_tgc5c.cpp index 7e2de93..cbbe348 100644 --- a/src/vm/llvm/vm_tgc5c.cpp +++ b/src/vm/llvm/vm_tgc5c.cpp @@ -4878,7 +4878,7 @@ private: bb = this->leave_blk; this->gen_instr_epilogue(bb); this->builder.CreateBr(bb); - return std::make_tuple(BRANCH, nullptr); + return std::make_tuple(ILLEGAL_INSTR, nullptr); } }; @@ -4913,19 +4913,11 @@ vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, auto *const data = (uint8_t *)&instr; if(this->core.has_mmu()) paddr = this->core.virt2phys(pc); - //TODO: re-add page handling -// if ((pc.val & upper_bits) != ((pc.val + 2) & upper_bits)) { // we may cross a page boundary -// auto res = this->core.read(paddr, 2, data); -// if (res != iss::Ok) throw trap_access(TRAP_ID, pc.val); -// if ((instr & 0x3) == 0x3) { // this is a 32bit instruction -// res = this->core.read(this->core.v2p(pc + 2), 2, data + 2); -// } -// } else { auto res = this->core.read(paddr, 4, data); - if (res != iss::Ok) throw trap_access(TRAP_ID, pc.val); -// } - if (instr == 0x0000006f || (instr&0xffff)==0xa001) throw simulation_stopped(0); // 'J 0' or 'C.J 0' - // curr pc on stack + if (res != iss::Ok) + return std::make_tuple(ILLEGAL_FETCH, nullptr); + if (instr == 0x0000006f || (instr&0xffff)==0xa001) + return std::make_tuple(JUMP_TO_SELF, nullptr); ++inst_cnt; uint32_t inst_index = instr_decoder.decode_instr(instr); compile_func f = nullptr; diff --git a/src/vm/tcc/vm_tgc5c.cpp b/src/vm/tcc/vm_tgc5c.cpp index 23daf58..71778f6 100644 --- a/src/vm/tcc/vm_tgc5c.cpp +++ b/src/vm/tcc/vm_tgc5c.cpp @@ -3579,7 +3579,7 @@ private: this->gen_set_tval(tu, instr); vm_impl::gen_sync(tu, iss::POST_SYNC, instr_descr.size()); vm_impl::gen_trap_check(tu); - return BRANCH; + return ILLEGAL_INSTR; } }; @@ -3612,19 +3612,11 @@ vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, phys_addr_t paddr(pc); if(this->core.has_mmu()) paddr = this->core.virt2phys(pc); - //TODO: re-add page handling -// if ((pc.val & upper_bits) != ((pc.val + 2) & upper_bits)) { // we may cross a page boundary -// auto res = this->core.read(paddr, 2, data); -// if (res != iss::Ok) throw trap_access(TRAP_ID, pc.val); -// if ((insn & 0x3) == 0x3) { // this is a 32bit instruction -// res = this->core.read(this->core.v2p(pc + 2), 2, data + 2); -// } -// } else { auto res = this->core.read(paddr, 4, reinterpret_cast(&instr)); - if (res != iss::Ok) throw trap_access(TRAP_ID, pc.val); -// } - if (instr == 0x0000006f || (instr&0xffff)==0xa001) throw simulation_stopped(0); // 'J 0' or 'C.J 0' - // curr pc on stack + if (res != iss::Ok) + 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;