removes setting of NEXT_PC to max when trapping in llvm and asmjit, adds default disass to llvm
This commit is contained in:
parent
8361f88718
commit
e1b6cab890
|
@ -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
|
||||||
|
|
|
@ -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()}
|
||||||
|
|
|
@ -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
Loading…
Reference in New Issue