refine and fix TGC_C iss to becoem compliant

This commit is contained in:
2021-06-29 11:51:19 +02:00
parent 5d8da08ce5
commit 23b9741adf
10 changed files with 1437 additions and 774 deletions

View File

@ -33,7 +33,7 @@
def getRegisterSizes(){
def regs = registers.collect{it.size}
regs[-1]=64 // correct for NEXT_PC
regs+=[32, 32, 64] // append TRAP_STATE, PENDING_TRAP, ICOUNT
regs+=[32, 32, 64, 64, 64] // append TRAP_STATE, PENDING_TRAP, ICOUNT, CYCLE, INSTRET
return regs
}
%>

View File

@ -37,7 +37,7 @@ def nativeTypeSize(int size){
}
def getRegisterSizes(){
def regs = registers.collect{nativeTypeSize(it.size)}
regs+=[32,32, 64] // append TRAP_STATE, PENDING_TRAP, ICOUNT
regs+=[32,32, 64, 64, 64] // append TRAP_STATE, PENDING_TRAP, ICOUNT, CYCLE, INSTRET
return regs
}
def getRegisterOffsets(){
@ -94,7 +94,9 @@ template <> struct traits<${coreDef.name.toLowerCase()}> {
${registers.collect{it.name}.join(', ')}, NUM_REGS,
TRAP_STATE=NUM_REGS,
PENDING_TRAP,
ICOUNT
ICOUNT,
CYCLE,
INSTRET
};
using reg_t = uint${addrDataWidth}_t;
@ -175,6 +177,8 @@ protected:
}}%>
uint32_t trap_state = 0, pending_trap = 0;
uint64_t icount = 0;
uint64_t cycle = 0;
uint64_t instret = 0;
uint32_t last_branch;
} reg;
#pragma pack(pop)

View File

@ -219,20 +219,22 @@ private:
/* instruction ${idx}: ${instr.name} */
compile_ret_t __${generator.functionName(instr.name)}(virt_addr_t& pc, code_word_t instr){
// pre execution stuff
this->do_sync(PRE_SYNC, ${idx});
auto* PC = reinterpret_cast<uint${addrDataWidth}_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::PC]);
auto NEXT_PC = reinterpret_cast<uint${addrDataWidth}_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::NEXT_PC]);
*PC=*NEXT_PC;
auto* trap_state = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::TRAP_STATE]);
*trap_state = *reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::PENDING_TRAP]);
if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, ${idx});
<%instr.fields.eachLine{%>${it}
<%}%>if(this->disass_enabled){
/* generate console output when executing the command */
<%instr.disass.eachLine{%>${it}
<%}%>
}
// prepare execution
uint${addrDataWidth}_t* PC = reinterpret_cast<uint${addrDataWidth}_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::PC]);
uint${addrDataWidth}_t* NEXT_PC = reinterpret_cast<uint${addrDataWidth}_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::NEXT_PC]);
// used registers<%instr.usedVariables.each{ k,v->
if(v.isArray) {%>
uint${v.type.size}_t* ${k} = reinterpret_cast<uint${v.type.size}_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::${k}0]);<% }else{ %>
uint${v.type.size}_t* ${k} = reinterpret_cast<uint${v.type.size}_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::${k}]);
auto* ${k} = reinterpret_cast<uint${v.type.size}_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::${k}0]);<% }else{ %>
auto* ${k} = reinterpret_cast<uint${v.type.size}_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::${k}]);
<%}}%>// calculate next pc value
*NEXT_PC = *PC + ${instr.length/8};
// execute instruction
@ -241,11 +243,14 @@ private:
<%}%>} 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
if(*trap_state!=0){
super::core.enter_trap(*trap_state, pc.val);
super::core.enter_trap(*trap_state, pc.val, instr);
} else {
(*reinterpret_cast<uint64_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::ICOUNT]))++;
(*reinterpret_cast<uint64_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::INSTRET]))++;
}
(*reinterpret_cast<uint64_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::CYCLE]))++;
pc.val=*NEXT_PC;
return pc;
}
@ -264,7 +269,7 @@ private:
auto* trap_state = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::TRAP_STATE]);
// trap check
if(*trap_state!=0){
super::core.enter_trap(*trap_state, pc.val);
super::core.enter_trap(*trap_state, pc.val, instr);
}
pc.val=*NEXT_PC;
return pc;
@ -318,7 +323,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
!(is_count_limit_enabled(cond) && this->core.get_icount() >= icount_limit)){
auto res = fetch_ins(pc, data);
if(res!=iss::Ok){
auto new_pc = super::core.enter_trap(TRAP_ID, pc.val);
auto new_pc = super::core.enter_trap(TRAP_ID, pc.val, 0);
res = fetch_ins(virt_addr_t{access_type::FETCH, new_pc}, data);
if(res!=iss::Ok) throw simulation_stopped(0);
}