updates templates and vm impls for better LAST_BRANCH handling

This commit is contained in:
2024-07-22 09:04:17 +02:00
parent 4f5d9214ed
commit 0432803d82
6 changed files with 103 additions and 54 deletions

View File

@ -347,7 +347,7 @@ void vm_impl<ARCH>::gen_block_epilogue(jit_holder& jh){
mov(cc, current_next_pc, get_ptr_for(jh, traits::NEXT_PC));
mov(cc, jh.next_pc, current_next_pc);
mov(cc, get_ptr_for(jh, traits::LAST_BRANCH), std::numeric_limits<uint32_t>::max());
mov(cc, get_ptr_for(jh, traits::LAST_BRANCH), static_cast<int>(UNKNOWN_JUMP));
cc.ret(jh.next_pc);
}
template <typename ARCH>

View File

@ -338,7 +338,7 @@ template <typename ARCH>
void vm_impl<ARCH>::gen_leave_trap(unsigned lvl) {
std::vector<Value *> args{ this->core_ptr, ConstantInt::get(getContext(), APInt(64, lvl)) };
this->builder.CreateCall(this->mod->getFunction("leave_trap"), args);
this->builder.CreateStore(this->gen_const(32U, std::numeric_limits<uint32_t>::max()), get_reg_ptr(traits::LAST_BRANCH), false);
this->builder.CreateStore(this->gen_const(32U, static_cast<int>(UNKNOWN_JUMP)), get_reg_ptr(traits::LAST_BRANCH), false);
}
template <typename ARCH>
@ -366,7 +366,7 @@ void vm_impl<ARCH>::gen_trap_behavior(BasicBlock *trap_blk) {
this->adj_to64(cur_pc_val),
this->adj_to64(this->builder.CreateLoad(this->get_type(64),this->tval))};
this->builder.CreateCall(this->mod->getFunction("enter_trap"), args);
this->builder.CreateStore(this->gen_const(32U, std::numeric_limits<uint32_t>::max()), get_reg_ptr(traits::LAST_BRANCH), false);
this->builder.CreateStore(this->gen_const(32U, static_cast<int>(UNKNOWN_JUMP)), get_reg_ptr(traits::LAST_BRANCH), false);
auto *trap_addr_val = this->builder.CreateLoad(this->get_typeptr(traits::NEXT_PC), get_reg_ptr(traits::NEXT_PC), false);
this->builder.CreateRet(trap_addr_val);

View File

@ -302,13 +302,12 @@ vm_impl<ARCH>::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt,
template <typename ARCH> void vm_impl<ARCH>::gen_raise_trap(tu_builder& tu, uint16_t trap_id, uint16_t cause) {
tu(" *trap_state = {:#x};", 0x80 << 24 | (cause << 16) | trap_id);
tu.store(traits::NEXT_PC, tu.constant(std::numeric_limits<uint32_t>::max(), 32));
}
template <typename ARCH> void vm_impl<ARCH>::gen_leave_trap(tu_builder& tu, unsigned lvl) {
tu("leave_trap(core_ptr, {});", lvl);
tu.store(traits::NEXT_PC, tu.read_mem(traits::CSR, (lvl << 8) + 0x41, traits::XLEN));
tu.store(traits::LAST_BRANCH, tu.constant(std::numeric_limits<uint32_t>::max(), 32));
tu.store(traits::LAST_BRANCH, tu.constant(static_cast<int>(UNKNOWN_JUMP), 32));
}
template <typename ARCH> void vm_impl<ARCH>::gen_wait(tu_builder& tu, unsigned type) {
@ -325,7 +324,7 @@ template <typename ARCH> void vm_impl<ARCH>::gen_trap_behavior(tu_builder& tu) {
tu("trap_entry:");
this->gen_sync(tu, POST_SYNC, -1);
tu("enter_trap(core_ptr, *trap_state, *pc, tval);");
tu.store(traits::LAST_BRANCH, tu.constant(std::numeric_limits<uint32_t>::max(),32));
tu.store(traits::LAST_BRANCH, tu.constant(static_cast<int>(UNKNOWN_JUMP),32));
tu("return *next_pc;");
}