integrates new tval changes

This commit is contained in:
Eyck-Alexander Jentzsch 2024-07-16 15:32:35 +02:00
parent 9996fd4833
commit 375755999a
3 changed files with 48 additions and 19 deletions

View File

@ -117,7 +117,12 @@ protected:
this->core.wait_until(type);
}
inline void set_tval(uint64_t new_tval){
tval = new_tval;
}
uint64_t fetch_count{0};
uint64_t tval{0};
using yield_t = boost::coroutines2::coroutine<void>::push_type;
using coro_t = boost::coroutines2::coroutine<void>::pull_type;
@ -341,7 +346,9 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
// this->core.reg.trap_state = this->core.reg.pending_trap;
// trap check
if(trap_state!=0){
super::core.enter_trap(trap_state, pc.val, instr);
//In case of Instruction address misaligned (cause = 0 and trapid = 0) need the targeted addr (in tval)
auto mcause = (trap_state>>16) & 0xff;
super::core.enter_trap(trap_state, pc.val, mcause ? instr:tval);
} else {
icount++;
instret++;

View File

@ -1207,7 +1207,7 @@ template <typename BASE, features_e FEAT> void riscv_hart_m_p<BASE, FEAT>::check
}
}
template <typename BASE, features_e FEAT> uint64_t riscv_hart_m_p<BASE, FEAT>::enter_trap(uint64_t flags, uint64_t addr, uint64_t instr) {
template <typename BASE, features_e FEAT> uint64_t riscv_hart_m_p<BASE, FEAT>::enter_trap(uint64_t flags, uint64_t addr, uint64_t tval) {
// flags are ACTIVE[31:31], CAUSE[30:16], TRAPID[15:0]
// calculate and write mcause val
auto const trap_id = bit_sub<0, 16>(flags);
@ -1228,10 +1228,10 @@ template <typename BASE, features_e FEAT> uint64_t riscv_hart_m_p<BASE, FEAT>::e
*/
switch(cause) {
case 0:
csr[mtval] = static_cast<reg_t>(addr);
csr[mtval] = static_cast<reg_t>(tval);
break;
case 2:
csr[mtval] = (!has_compressed() || (instr & 0x3) == 3) ? instr : instr & 0xffff;
csr[mtval] = (!has_compressed() || (tval & 0x3) == 3) ? tval : tval & 0xffff;
break;
case 3:
if((FEAT & FEAT_DEBUG) && (csr[dcsr] & 0x8000)) {

View File

@ -113,7 +113,12 @@ protected:
this->core.wait_until(type);
}
inline void set_tval(uint64_t new_tval){
tval = new_tval;
}
uint64_t fetch_count{0};
uint64_t tval{0};
using yield_t = boost::coroutines2::coroutine<void>::push_type;
using coro_t = boost::coroutines2::coroutine<void>::pull_type;
@ -463,14 +468,16 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
raise(0, traits::RV_CAUSE_ILLEGAL_INSTRUCTION);
}
else {
if(imm % traits::INSTR_ALIGNMENT) {
uint32_t new_pc = (uint32_t)((uint64_t)(*PC ) + (uint64_t)((int32_t)sext<21>(imm) ));
if(new_pc % traits::INSTR_ALIGNMENT) {
set_tval(new_pc);
raise(0, 0);
}
else {
if(rd != 0) {
*(X+rd) = (uint32_t)((uint64_t)(*PC ) + (uint64_t)(4 ));
}
*NEXT_PC = (uint32_t)((uint64_t)(*PC ) + (uint64_t)((int32_t)sext<21>(imm) ));
*NEXT_PC = new_pc;
this->core.reg.last_branch = 1;
}
}
@ -500,6 +507,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
uint32_t addr_mask = (uint32_t)- 2;
uint32_t new_pc = (uint32_t)(((uint64_t)(*(X+rs1) ) + (uint64_t)((int16_t)sext<12>(imm) )) & (int64_t)(addr_mask ));
if(new_pc % traits::INSTR_ALIGNMENT) {
set_tval(new_pc);
raise(0, 0);
}
else {
@ -534,11 +542,13 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
}
else {
if(*(X+rs1) == *(X+rs2)) {
if((uint32_t)(imm ) % traits::INSTR_ALIGNMENT) {
uint32_t new_pc = (uint32_t)((uint64_t)(*PC ) + (uint64_t)((int16_t)sext<13>(imm) ));
if(new_pc % traits::INSTR_ALIGNMENT) {
set_tval(new_pc);
raise(0, 0);
}
else {
*NEXT_PC = (uint32_t)((uint64_t)(*PC ) + (uint64_t)((int16_t)sext<13>(imm) ));
*NEXT_PC = new_pc;
this->core.reg.last_branch = 1;
}
}
@ -567,11 +577,13 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
}
else {
if(*(X+rs1) != *(X+rs2)) {
if((uint32_t)(imm ) % traits::INSTR_ALIGNMENT) {
uint32_t new_pc = (uint32_t)((uint64_t)(*PC ) + (uint64_t)((int16_t)sext<13>(imm) ));
if(new_pc % traits::INSTR_ALIGNMENT) {
set_tval(new_pc);
raise(0, 0);
}
else {
*NEXT_PC = (uint32_t)((uint64_t)(*PC ) + (uint64_t)((int16_t)sext<13>(imm) ));
*NEXT_PC = new_pc;
this->core.reg.last_branch = 1;
}
}
@ -600,11 +612,13 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
}
else {
if((int32_t)*(X+rs1) < (int32_t)*(X+rs2)) {
if((uint32_t)(imm ) % traits::INSTR_ALIGNMENT) {
uint32_t new_pc = (uint32_t)((uint64_t)(*PC ) + (uint64_t)((int16_t)sext<13>(imm) ));
if(new_pc % traits::INSTR_ALIGNMENT) {
set_tval(new_pc);
raise(0, 0);
}
else {
*NEXT_PC = (uint32_t)((uint64_t)(*PC ) + (uint64_t)((int16_t)sext<13>(imm) ));
*NEXT_PC = new_pc;
this->core.reg.last_branch = 1;
}
}
@ -633,11 +647,13 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
}
else {
if((int32_t)*(X+rs1) >= (int32_t)*(X+rs2)) {
if((uint32_t)(imm ) % traits::INSTR_ALIGNMENT) {
uint32_t new_pc = (uint32_t)((uint64_t)(*PC ) + (uint64_t)((int16_t)sext<13>(imm) ));
if(new_pc % traits::INSTR_ALIGNMENT) {
set_tval(new_pc);
raise(0, 0);
}
else {
*NEXT_PC = (uint32_t)((uint64_t)(*PC ) + (uint64_t)((int16_t)sext<13>(imm) ));
*NEXT_PC = new_pc;
this->core.reg.last_branch = 1;
}
}
@ -666,11 +682,13 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
}
else {
if(*(X+rs1) < *(X+rs2)) {
if((uint32_t)(imm ) % traits::INSTR_ALIGNMENT) {
uint32_t new_pc = (uint32_t)((uint64_t)(*PC ) + (uint64_t)((int16_t)sext<13>(imm) ));
if(new_pc % traits::INSTR_ALIGNMENT) {
set_tval(new_pc);
raise(0, 0);
}
else {
*NEXT_PC = (uint32_t)((uint64_t)(*PC ) + (uint64_t)((int16_t)sext<13>(imm) ));
*NEXT_PC = new_pc;
this->core.reg.last_branch = 1;
}
}
@ -699,11 +717,13 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
}
else {
if(*(X+rs1) >= *(X+rs2)) {
if((uint32_t)(imm ) % traits::INSTR_ALIGNMENT) {
uint32_t new_pc = (uint32_t)((uint64_t)(*PC ) + (uint64_t)((int16_t)sext<13>(imm) ));
if(new_pc % traits::INSTR_ALIGNMENT) {
set_tval(new_pc);
raise(0, 0);
}
else {
*NEXT_PC = (uint32_t)((uint64_t)(*PC ) + (uint64_t)((int16_t)sext<13>(imm) ));
*NEXT_PC = new_pc;
this->core.reg.last_branch = 1;
}
}
@ -2675,7 +2695,9 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
// this->core.reg.trap_state = this->core.reg.pending_trap;
// trap check
if(trap_state!=0){
super::core.enter_trap(trap_state, pc.val, instr);
//In case of Instruction address misaligned (cause = 0 and trapid = 0) need the targeted addr (in tval)
auto mcause = (trap_state>>16) & 0xff;
super::core.enter_trap(trap_state, pc.val, mcause ? instr:tval);
} else {
icount++;
instret++;