fix handling of exceptions while accessing address spaces
This commit is contained in:
Submodule gen_input/CoreDSL-Instruction-Set-Description updated: a5f12b0659...cf601042ed
@ -155,14 +155,42 @@ protected:
|
||||
|
||||
template<typename T>
|
||||
T& pc_assign(T& val){super::ex_info.branch_taken=true; return val;}
|
||||
inline uint8_t readSpace1(typename super::mem_type_e space, uint64_t addr){return super::template read_mem<uint8_t>(space, addr);}
|
||||
inline uint16_t readSpace2(typename super::mem_type_e space, uint64_t addr){return super::template read_mem<uint16_t>(space, addr);}
|
||||
inline uint32_t readSpace4(typename super::mem_type_e space, uint64_t addr){return super::template read_mem<uint32_t>(space, addr);}
|
||||
inline uint64_t readSpace8(typename super::mem_type_e space, uint64_t addr){return super::template read_mem<uint64_t>(space, addr);}
|
||||
inline void writeSpace1(typename super::mem_type_e space, uint64_t addr, uint8_t data){super::write_mem(space, addr, data);}
|
||||
inline void writeSpace2(typename super::mem_type_e space, uint64_t addr, uint16_t data){super::write_mem(space, addr, data);}
|
||||
inline void writeSpace4(typename super::mem_type_e space, uint64_t addr, uint32_t data){super::write_mem(space, addr, data);}
|
||||
inline void writeSpace8(typename super::mem_type_e space, uint64_t addr, uint64_t data){super::write_mem(space, addr, data);}
|
||||
inline uint8_t readSpace1(typename super::mem_type_e space, uint64_t addr){
|
||||
auto ret = super::template read_mem<uint8_t>(space, addr);
|
||||
if(this->template get_reg<uint32_t>(traits::TRAP_STATE)) throw 0;
|
||||
return ret;
|
||||
}
|
||||
inline uint16_t readSpace2(typename super::mem_type_e space, uint64_t addr){
|
||||
auto ret = super::template read_mem<uint16_t>(space, addr);
|
||||
if(this->template get_reg<uint32_t>(traits::TRAP_STATE)) throw 0;
|
||||
return ret;
|
||||
}
|
||||
inline uint32_t readSpace4(typename super::mem_type_e space, uint64_t addr){
|
||||
auto ret = super::template read_mem<uint32_t>(space, addr);
|
||||
if(this->template get_reg<uint32_t>(traits::TRAP_STATE)) throw 0;
|
||||
return ret;
|
||||
}
|
||||
inline uint64_t readSpace8(typename super::mem_type_e space, uint64_t addr){
|
||||
auto ret = super::template read_mem<uint64_t>(space, addr);
|
||||
if(this->template get_reg<uint32_t>(traits::TRAP_STATE)) throw 0;
|
||||
return ret;
|
||||
}
|
||||
inline void writeSpace1(typename super::mem_type_e space, uint64_t addr, uint8_t data){
|
||||
super::write_mem(space, addr, data);
|
||||
if(this->template get_reg<uint32_t>(traits::TRAP_STATE)) throw 0;
|
||||
}
|
||||
inline void writeSpace2(typename super::mem_type_e space, uint64_t addr, uint16_t data){
|
||||
super::write_mem(space, addr, data);
|
||||
if(this->template get_reg<uint32_t>(traits::TRAP_STATE)) throw 0;
|
||||
}
|
||||
inline void writeSpace4(typename super::mem_type_e space, uint64_t addr, uint32_t data){
|
||||
super::write_mem(space, addr, data);
|
||||
if(this->template get_reg<uint32_t>(traits::TRAP_STATE)) throw 0;
|
||||
}
|
||||
inline void writeSpace8(typename super::mem_type_e space, uint64_t addr, uint64_t data){
|
||||
super::write_mem(space, addr, data);
|
||||
if(this->template get_reg<uint32_t>(traits::TRAP_STATE)) throw 0;
|
||||
}
|
||||
template<unsigned W, typename U, typename S = typename std::make_signed<U>::type>
|
||||
inline S sext(U from) {
|
||||
auto mask = (1ULL<<W) - 1;
|
||||
@ -208,8 +236,10 @@ private:
|
||||
<%}}%>// calculate next pc value
|
||||
*NEXT_PC = *PC + ${instr.length/8};
|
||||
// execute instruction
|
||||
try {
|
||||
<%instr.behavior.eachLine{%>${it}
|
||||
<%}%>// post execution stuff
|
||||
<%}%>} catch(...){}
|
||||
// post execution stuff
|
||||
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, ${idx});
|
||||
auto* trap_state = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::TRAP_STATE]);
|
||||
// trap check
|
||||
@ -228,7 +258,7 @@ private:
|
||||
uint32_t* PC = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::PC]);
|
||||
uint32_t* NEXT_PC = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::NEXT_PC]);
|
||||
*NEXT_PC = *PC + ((instr & 3) == 3 ? 4 : 2);
|
||||
raise(0, 11);
|
||||
raise(0, 2);
|
||||
// post execution stuff
|
||||
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, static_cast<unsigned>(arch::traits<ARCH>::opcode_e::MAX_OPCODE));
|
||||
auto* trap_state = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::TRAP_STATE]);
|
||||
|
Reference in New Issue
Block a user