removes setting of NEXT_PC to max when trapping in llvm and asmjit, adds default disass to llvm

This commit is contained in:
Eyck-Alexander Jentzsch 2024-07-18 12:02:40 +02:00
parent 8361f88718
commit e1b6cab890
4 changed files with 545 additions and 278 deletions

View File

@ -357,7 +357,6 @@ inline void vm_impl<ARCH>::gen_raise(jit_holder& jh, uint16_t trap_id, uint16_t
auto tmp1 = get_reg_for(cc, traits::TRAP_STATE); auto tmp1 = get_reg_for(cc, traits::TRAP_STATE);
mov(cc, tmp1, 0x80ULL << 24 | (cause << 16) | trap_id); mov(cc, tmp1, 0x80ULL << 24 | (cause << 16) | trap_id);
mov(cc, get_ptr_for(jh, traits::TRAP_STATE), tmp1); mov(cc, get_ptr_for(jh, traits::TRAP_STATE), tmp1);
mov(cc, jh.next_pc, std::numeric_limits<uint32_t>::max());
} }
} // namespace tgc5c } // namespace tgc5c

View File

@ -105,6 +105,7 @@ protected:
void set_tval(uint64_t new_tval); void set_tval(uint64_t new_tval);
void set_tval(Value* new_tval); void set_tval(Value* new_tval);
void gen_trap_behavior(BasicBlock *) override; void gen_trap_behavior(BasicBlock *) override;
void gen_instr_prologue();
void gen_instr_epilogue(BasicBlock *bb); void gen_instr_epilogue(BasicBlock *bb);
inline Value *gen_reg_load(unsigned i, unsigned level = 0) { inline Value *gen_reg_load(unsigned i, unsigned level = 0) {
@ -164,14 +165,22 @@ private:
<%}%>if(this->disass_enabled){ <%}%>if(this->disass_enabled){
/* generate console output when executing the command */<%instr.disass.eachLine{%> /* generate console output when executing the command */<%instr.disass.eachLine{%>
${it}<%}%> ${it}<%}%>
std::vector<Value*> args {
this->core_ptr,
this->gen_const(64, pc.val),
this->builder.CreateGlobalStringPtr(mnemonic),
};
this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
} }
bb->setName(fmt::format("${instr.name}_0x{:X}",pc.val)); bb->setName(fmt::format("${instr.name}_0x{:X}",pc.val));
this->gen_sync(PRE_SYNC,${idx}); this->gen_sync(PRE_SYNC,${idx});
auto cur_pc_val = this->gen_const(32,pc.val);
this->gen_set_pc(pc, traits::PC);
this->set_tval(instr);
pc=pc+ ${instr.length/8}; pc=pc+ ${instr.length/8};
this->gen_set_pc(pc, traits::NEXT_PC); this->gen_set_pc(pc, traits::NEXT_PC);
this->set_tval(instr);
this->gen_instr_prologue();
/*generate behavior*/ /*generate behavior*/
<%instr.behavior.eachLine{%>${it} <%instr.behavior.eachLine{%>${it}
<%}%> <%}%>
@ -321,15 +330,12 @@ template <typename ARCH>
void vm_impl<ARCH>::gen_raise_trap(uint16_t trap_id, uint16_t cause) { void vm_impl<ARCH>::gen_raise_trap(uint16_t trap_id, uint16_t cause) {
auto *TRAP_val = this->gen_const(32, 0x80 << 24 | (cause << 16) | trap_id); auto *TRAP_val = this->gen_const(32, 0x80 << 24 | (cause << 16) | trap_id);
this->builder.CreateStore(TRAP_val, get_reg_ptr(traits::TRAP_STATE), true); this->builder.CreateStore(TRAP_val, get_reg_ptr(traits::TRAP_STATE), true);
this->builder.CreateStore(this->gen_const(32U, std::numeric_limits<uint32_t>::max()), get_reg_ptr(traits::LAST_BRANCH), false);
} }
template <typename ARCH> template <typename ARCH>
void vm_impl<ARCH>::gen_leave_trap(unsigned lvl) { void vm_impl<ARCH>::gen_leave_trap(unsigned lvl) {
std::vector<Value *> args{ this->core_ptr, ConstantInt::get(getContext(), APInt(64, 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.CreateCall(this->mod->getFunction("leave_trap"), args);
auto *PC_val = this->gen_read_mem(traits::CSR, (lvl << 8) + 0x41, traits::XLEN / 8);
this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false);
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, std::numeric_limits<uint32_t>::max()), get_reg_ptr(traits::LAST_BRANCH), false);
} }
@ -352,14 +358,24 @@ template <typename ARCH>
void vm_impl<ARCH>::gen_trap_behavior(BasicBlock *trap_blk) { void vm_impl<ARCH>::gen_trap_behavior(BasicBlock *trap_blk) {
this->builder.SetInsertPoint(trap_blk); this->builder.SetInsertPoint(trap_blk);
auto *trap_state_val = this->builder.CreateLoad(this->get_typeptr(traits::TRAP_STATE), get_reg_ptr(traits::TRAP_STATE), true); auto *trap_state_val = this->builder.CreateLoad(this->get_typeptr(traits::TRAP_STATE), get_reg_ptr(traits::TRAP_STATE), true);
this->builder.CreateStore(this->gen_const(32U, std::numeric_limits<uint32_t>::max()), auto *cur_pc_val = this->builder.CreateLoad(this->get_typeptr(traits::PC), get_reg_ptr(traits::PC), true);
get_reg_ptr(traits::LAST_BRANCH), false); std::vector<Value *> args{this->core_ptr,
std::vector<Value *> args{this->core_ptr, this->adj_to64(trap_state_val), this->adj_to64(trap_state_val),
this->adj_to64(cur_pc_val),
this->adj_to64(this->builder.CreateLoad(this->get_type(64),this->tval))}; this->adj_to64(this->builder.CreateLoad(this->get_type(64),this->tval))};
this->builder.CreateCall(this->mod->getFunction("enter_trap"), args); 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);
auto *trap_addr_val = this->builder.CreateLoad(this->get_typeptr(traits::NEXT_PC), get_reg_ptr(traits::NEXT_PC), 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); this->builder.CreateRet(trap_addr_val);
} }
template <typename ARCH>
void vm_impl<ARCH>::gen_instr_prologue() {
auto* trap_val =
this->builder.CreateLoad(this->get_typeptr(arch::traits<ARCH>::PENDING_TRAP), get_reg_ptr(arch::traits<ARCH>::PENDING_TRAP));
this->builder.CreateStore(trap_val, get_reg_ptr(arch::traits<ARCH>::TRAP_STATE), false);
}
template <typename ARCH> template <typename ARCH>
void vm_impl<ARCH>::gen_instr_epilogue(BasicBlock *bb) { void vm_impl<ARCH>::gen_instr_epilogue(BasicBlock *bb) {
@ -370,6 +386,10 @@ void vm_impl<ARCH>::gen_instr_epilogue(BasicBlock *bb) {
ConstantInt::get(getContext(), APInt(v->getType()->getIntegerBitWidth(), 0))), ConstantInt::get(getContext(), APInt(v->getType()->getIntegerBitWidth(), 0))),
target_bb, this->trap_blk, 1); target_bb, this->trap_blk, 1);
this->builder.SetInsertPoint(target_bb); this->builder.SetInsertPoint(target_bb);
// update icount
auto* icount_val = this->builder.CreateAdd(
this->builder.CreateLoad(this->get_typeptr(arch::traits<ARCH>::ICOUNT), get_reg_ptr(arch::traits<ARCH>::ICOUNT)), this->gen_const(64U, 1));
this->builder.CreateStore(icount_val, get_reg_ptr(arch::traits<ARCH>::ICOUNT), false);
} }
} // namespace ${coreDef.name.toLowerCase()} } // namespace ${coreDef.name.toLowerCase()}

View File

@ -4880,7 +4880,6 @@ inline void vm_impl<ARCH>::gen_raise(jit_holder& jh, uint16_t trap_id, uint16_t
auto tmp1 = get_reg_for(cc, traits::TRAP_STATE); auto tmp1 = get_reg_for(cc, traits::TRAP_STATE);
mov(cc, tmp1, 0x80ULL << 24 | (cause << 16) | trap_id); mov(cc, tmp1, 0x80ULL << 24 | (cause << 16) | trap_id);
mov(cc, get_ptr_for(jh, traits::TRAP_STATE), tmp1); mov(cc, get_ptr_for(jh, traits::TRAP_STATE), tmp1);
mov(cc, jh.next_pc, std::numeric_limits<uint32_t>::max());
} }
} // namespace tgc5c } // namespace tgc5c

File diff suppressed because it is too large Load Diff