integrates new tval changes
This commit is contained in:
parent
9996fd4833
commit
375755999a
@ -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++;
|
||||
|
@ -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)) {
|
||||
|
@ -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++;
|
||||
|
Loading…
Reference in New Issue
Block a user