Adapted generated code to support translation block linking

This commit is contained in:
2018-05-15 18:49:29 +02:00
parent 5b6dc36c9d
commit dfcc3ace66
17 changed files with 353 additions and 93 deletions

View File

@ -73,6 +73,7 @@ struct traits<${coreDef.name.toLowerCase()}> {
TRAP_STATE,
PENDING_TRAP,
MACHINE_STATE,
LAST_BRANCH,
ICOUNT
};
@ -140,6 +141,9 @@ struct ${coreDef.name.toLowerCase()}: public arch_if {
virtual iss::sync_type needed_sync() const { return iss::NO_SYNC; }
inline
uint32_t get_last_branch(){return reg.last_branch;}
protected:
struct ${coreDef.name}_regs {<%
allRegs.each { reg ->
@ -152,7 +156,7 @@ protected:
}
}%>
uint${generator.getSize(pc)}_t NEXT_${pc.name} = 0;
uint32_t trap_state = 0, pending_trap = 0, machine_state = 0;
uint32_t trap_state = 0, pending_trap = 0, machine_state = 0, last_branch = 0;
uint64_t icount = 0;
} reg;

View File

@ -92,8 +92,7 @@ protected:
vm::fp_impl::add_fp_functions_2_module(m, traits<ARCH>::FP_REGS_SIZE);
}
inline llvm::Value *gen_choose(llvm::Value *cond, llvm::Value *trueVal, llvm::Value *falseVal,
unsigned size) const {
inline llvm::Value *gen_choose(llvm::Value *cond, llvm::Value *trueVal, llvm::Value *falseVal, unsigned size) {
return super::gen_cond_assign(cond, this->gen_ext(trueVal, size), this->gen_ext(falseVal, size));
}
@ -266,7 +265,6 @@ vm_impl<ARCH>::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt,
}
if (insn == 0x0000006f || (insn&0xffff)==0xa001) throw simulation_stopped(0); // 'J 0' or 'C.J 0'
// curr pc on stack
typename vm_impl<ARCH>::processing_pc_entry addr(*this, pc, paddr);
++inst_cnt;
auto lut_val = extract_fields(insn);
auto f = qlut[insn & 0x3][lut_val];
@ -284,6 +282,7 @@ template <typename ARCH> void vm_impl<ARCH>::gen_leave_behavior(llvm::BasicBlock
template <typename ARCH> 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);
this->builder.CreateStore(TRAP_val, get_reg_ptr(traits<ARCH>::TRAP_STATE), true);
this->builder.CreateStore(this->gen_const(32U, std::numeric_limits<uint32_t>::max()), get_reg_ptr(traits<ARCH>::LAST_BRANCH), false);
}
template <typename ARCH> void vm_impl<ARCH>::gen_leave_trap(unsigned lvl) {
@ -293,6 +292,7 @@ template <typename ARCH> void vm_impl<ARCH>::gen_leave_trap(unsigned lvl) {
this->builder.CreateCall(this->mod->getFunction("leave_trap"), args);
auto *PC_val = this->gen_read_mem(traits<ARCH>::CSR, (lvl << 8) + 0x41, traits<ARCH>::XLEN / 8);
this->builder.CreateStore(PC_val, get_reg_ptr(traits<ARCH>::NEXT_PC), false);
this->builder.CreateStore(this->gen_const(32U, std::numeric_limits<uint32_t>::max()), get_reg_ptr(traits<ARCH>::LAST_BRANCH), false);
}
template <typename ARCH> void vm_impl<ARCH>::gen_wait(unsigned type) {
@ -305,8 +305,11 @@ template <typename ARCH> void vm_impl<ARCH>::gen_wait(unsigned type) {
template <typename ARCH> void vm_impl<ARCH>::gen_trap_behavior(llvm::BasicBlock *trap_blk) {
this->builder.SetInsertPoint(trap_blk);
auto *trap_state_val = this->builder.CreateLoad(get_reg_ptr(traits<ARCH>::TRAP_STATE), true);
std::vector<llvm::Value *> args{this->core_ptr, this->adj_to64(trap_state_val),
this->adj_to64(this->builder.CreateLoad(get_reg_ptr(traits<ARCH>::PC), false))};
this->builder.CreateStore(this->gen_const(32U, std::numeric_limits<uint32_t>::max()), get_reg_ptr(traits<ARCH>::LAST_BRANCH), false);
std::vector<llvm::Value *> args{
this->core_ptr,
this->adj_to64(trap_state_val),
this->adj_to64(this->builder.CreateLoad(get_reg_ptr(traits<ARCH>::PC), false))};
this->builder.CreateCall(this->mod->getFunction("enter_trap"), args);
auto *trap_addr_val = this->builder.CreateLoad(get_reg_ptr(traits<ARCH>::NEXT_PC), false);
this->builder.CreateRet(trap_addr_val);