From df16378605ac71a296cc645ea805fd5e70cddb7a Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Wed, 18 May 2022 19:10:34 +0200 Subject: [PATCH] update template for changed code generator --- gen_input/templates/interp/CORENAME.cpp.gtl | 6 +- src/vm/interp/vm_tgc_c.cpp | 1132 ++++++++++--------- 2 files changed, 615 insertions(+), 523 deletions(-) diff --git a/gen_input/templates/interp/CORENAME.cpp.gtl b/gen_input/templates/interp/CORENAME.cpp.gtl index 76449f6..f0cb153 100644 --- a/gen_input/templates/interp/CORENAME.cpp.gtl +++ b/gen_input/templates/interp/CORENAME.cpp.gtl @@ -314,11 +314,9 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co <%}}%>// calculate next pc value *NEXT_PC = *PC + ${instr.length/8}; // execute instruction - try { <%instr.behavior.eachLine{%>${it} - <%}%>} catch(...){} - } - break;<%}%> + <%}%>TRAP_${instr.name}:break; + }// @suppress("No break at end of case")<%}%> default: { *NEXT_PC = *PC + ((instr & 3) == 3 ? 4 : 2); raise(0, 2); diff --git a/src/vm/interp/vm_tgc_c.cpp b/src/vm/interp/vm_tgc_c.cpp index f6605ee..0e1ad99 100644 --- a/src/vm/interp/vm_tgc_c.cpp +++ b/src/vm/interp/vm_tgc_c.cpp @@ -396,11 +396,13 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { - if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = (int32_t)imm; - } catch(...){} - } - break; + { + if((rd % traits::RFS) != 0) { + *(X+rd % traits::RFS) = (int32_t)imm; + } + } + TRAP_LUI:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::AUIPC: { uint8_t rd = ((bit_sub<7,5>(instr))); uint32_t imm = ((bit_sub<12,20>(instr) << 12)); @@ -416,11 +418,13 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { - if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = *PC + (int32_t)imm; - } catch(...){} - } - break; + { + if((rd % traits::RFS) != 0) { + *(X+rd % traits::RFS) = *PC + (int32_t)imm; + } + } + TRAP_AUIPC:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::JAL: { uint8_t rd = ((bit_sub<7,5>(instr))); uint32_t imm = ((bit_sub<12,8>(instr) << 12) | (bit_sub<20,1>(instr) << 11) | (bit_sub<21,10>(instr) << 1) | (bit_sub<31,1>(instr) << 20)); @@ -436,19 +440,20 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { { if(imm % traits::INSTR_ALIGNMENT) { raise(0, 0); } else { - if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = *PC + 4; - pc_assign(*NEXT_PC) = *PC + (int32_t)sext<21>(imm); + if((rd % traits::RFS) != 0) { + *(X+rd % traits::RFS) = *PC + 4; + } + *NEXT_PC = *PC + (int32_t)sext<21>(imm); + super::ex_info.branch_taken=true; } } - } catch(...){} - } - break; + TRAP_JAL:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::JALR: { uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -465,20 +470,21 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { { int32_t new_pc = (*(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm)) & ~ 1; if(new_pc % traits::INSTR_ALIGNMENT) { raise(0, 0); } else { - if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = *PC + 4; - pc_assign(*NEXT_PC) = new_pc & ~ 0x1; + if((rd % traits::RFS) != 0) { + *(X+rd % traits::RFS) = *PC + 4; + } + *NEXT_PC = new_pc & ~ 0x1; + super::ex_info.branch_taken=true; } } - } catch(...){} - } - break; + TRAP_JALR:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::BEQ: { uint16_t imm = ((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -495,18 +501,19 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { { - if(*(X+rs1 % traits::RFS) == *(X+rs2 % traits::RFS)) if(imm % traits::INSTR_ALIGNMENT) { - raise(0, 0); - } - else { - pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm); + if(*(X+rs1 % traits::RFS) == *(X+rs2 % traits::RFS)) { + if(imm % traits::INSTR_ALIGNMENT) { + raise(0, 0); + } + else { + *NEXT_PC = *PC + (int16_t)sext<13>(imm); + super::ex_info.branch_taken=true; + } } } - } catch(...){} - } - break; + TRAP_BEQ:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::BNE: { uint16_t imm = ((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -523,18 +530,19 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { { - if(*(X+rs1 % traits::RFS) != *(X+rs2 % traits::RFS)) if(imm % traits::INSTR_ALIGNMENT) { - raise(0, 0); - } - else { - pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm); + if(*(X+rs1 % traits::RFS) != *(X+rs2 % traits::RFS)) { + if(imm % traits::INSTR_ALIGNMENT) { + raise(0, 0); + } + else { + *NEXT_PC = *PC + (int16_t)sext<13>(imm); + super::ex_info.branch_taken=true; + } } } - } catch(...){} - } - break; + TRAP_BNE:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::BLT: { uint16_t imm = ((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -551,18 +559,19 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { { - if((int32_t)*(X+rs1 % traits::RFS) < (int32_t)*(X+rs2 % traits::RFS)) if(imm % traits::INSTR_ALIGNMENT) { - raise(0, 0); - } - else { - pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm); + if((int32_t)*(X+rs1 % traits::RFS) < (int32_t)*(X+rs2 % traits::RFS)) { + if(imm % traits::INSTR_ALIGNMENT) { + raise(0, 0); + } + else { + *NEXT_PC = *PC + (int16_t)sext<13>(imm); + super::ex_info.branch_taken=true; + } } } - } catch(...){} - } - break; + TRAP_BLT:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::BGE: { uint16_t imm = ((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -579,18 +588,19 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { { - if((int32_t)*(X+rs1 % traits::RFS) >= (int32_t)*(X+rs2 % traits::RFS)) if(imm % traits::INSTR_ALIGNMENT) { - raise(0, 0); - } - else { - pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm); + if((int32_t)*(X+rs1 % traits::RFS) >= (int32_t)*(X+rs2 % traits::RFS)) { + if(imm % traits::INSTR_ALIGNMENT) { + raise(0, 0); + } + else { + *NEXT_PC = *PC + (int16_t)sext<13>(imm); + super::ex_info.branch_taken=true; + } } } - } catch(...){} - } - break; + TRAP_BGE:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::BLTU: { uint16_t imm = ((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -607,18 +617,19 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { { - if(*(X+rs1 % traits::RFS) < *(X+rs2 % traits::RFS)) if(imm % traits::INSTR_ALIGNMENT) { - raise(0, 0); - } - else { - pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm); + if(*(X+rs1 % traits::RFS) < *(X+rs2 % traits::RFS)) { + if(imm % traits::INSTR_ALIGNMENT) { + raise(0, 0); + } + else { + *NEXT_PC = *PC + (int16_t)sext<13>(imm); + super::ex_info.branch_taken=true; + } } } - } catch(...){} - } - break; + TRAP_BLTU:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::BGEU: { uint16_t imm = ((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -635,18 +646,19 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { { - if(*(X+rs1 % traits::RFS) >= *(X+rs2 % traits::RFS)) if(imm % traits::INSTR_ALIGNMENT) { - raise(0, 0); - } - else { - pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm); + if(*(X+rs1 % traits::RFS) >= *(X+rs2 % traits::RFS)) { + if(imm % traits::INSTR_ALIGNMENT) { + raise(0, 0); + } + else { + *NEXT_PC = *PC + (int16_t)sext<13>(imm); + super::ex_info.branch_taken=true; + } } } - } catch(...){} - } - break; + TRAP_BGEU:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::LB: { uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -663,14 +675,15 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { { - int8_t res = (int8_t)readSpace1(traits::MEM, *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm)); - if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = res; + int8_t res = (int8_t)super::template read_mem(traits::MEM, *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm)); + if(this->core.trap_state) goto TRAP_LB; + if((rd % traits::RFS) != 0) { + *(X+rd % traits::RFS) = res; + } } - } catch(...){} - } - break; + TRAP_LB:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::LH: { uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -687,15 +700,16 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { { uint32_t load_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); - int16_t res = (int16_t)readSpace2(traits::MEM, load_address); - if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = res; + int16_t res = (int16_t)super::template read_mem(traits::MEM, load_address); + if(this->core.trap_state) goto TRAP_LH; + if((rd % traits::RFS) != 0) { + *(X+rd % traits::RFS) = res; + } } - } catch(...){} - } - break; + TRAP_LH:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::LW: { uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -712,15 +726,16 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { { uint32_t load_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); - int32_t res = (int32_t)readSpace4(traits::MEM, load_address); - if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = (uint32_t)res; + int32_t res = (int32_t)super::template read_mem(traits::MEM, load_address); + if(this->core.trap_state) goto TRAP_LW; + if((rd % traits::RFS) != 0) { + *(X+rd % traits::RFS) = (uint32_t)res; + } } - } catch(...){} - } - break; + TRAP_LW:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::LBU: { uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -737,14 +752,15 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { { - uint8_t res = (uint8_t)readSpace1(traits::MEM, *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm)); - if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = res; + uint8_t res = (uint8_t)super::template read_mem(traits::MEM, *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm)); + if(this->core.trap_state) goto TRAP_LBU; + if((rd % traits::RFS) != 0) { + *(X+rd % traits::RFS) = res; + } } - } catch(...){} - } - break; + TRAP_LBU:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::LHU: { uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -761,15 +777,16 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { { uint32_t load_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); - uint16_t res = (uint16_t)readSpace2(traits::MEM, load_address); - if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = res; + uint16_t res = (uint16_t)super::template read_mem(traits::MEM, load_address); + if(this->core.trap_state) goto TRAP_LHU; + if((rd % traits::RFS) != 0) { + *(X+rd % traits::RFS) = res; + } } - } catch(...){} - } - break; + TRAP_LHU:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::SB: { uint16_t imm = ((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -786,11 +803,12 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { - writeSpace1(traits::MEM, *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm), (int8_t)*(X+rs2 % traits::RFS)); - } catch(...){} - } - break; + { + super::template write_mem(traits::MEM, *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm), (int8_t)*(X+rs2 % traits::RFS)); + if(this->core.trap_state) goto TRAP_SB; + } + TRAP_SB:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::SH: { uint16_t imm = ((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -807,14 +825,13 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { { uint32_t store_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); - writeSpace2(traits::MEM, store_address, (int16_t)*(X+rs2 % traits::RFS)); + super::template write_mem(traits::MEM, store_address, (int16_t)*(X+rs2 % traits::RFS)); + if(this->core.trap_state) goto TRAP_SH; } - } catch(...){} - } - break; + TRAP_SH:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::SW: { uint16_t imm = ((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -831,14 +848,13 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { { uint32_t store_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); - writeSpace4(traits::MEM, store_address, *(X+rs2 % traits::RFS)); + super::template write_mem(traits::MEM, store_address, *(X+rs2 % traits::RFS)); + if(this->core.trap_state) goto TRAP_SW; } - } catch(...){} - } - break; + TRAP_SW:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::ADDI: { uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -855,11 +871,13 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { - if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); - } catch(...){} - } - break; + { + if((rd % traits::RFS) != 0) { + *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); + } + } + TRAP_ADDI:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::SLTI: { uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -876,11 +894,13 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { - if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = (int32_t)*(X+rs1 % traits::RFS) < (int16_t)sext<12>(imm)? 1 : 0; - } catch(...){} - } - break; + { + if((rd % traits::RFS) != 0) { + *(X+rd % traits::RFS) = (int32_t)*(X+rs1 % traits::RFS) < (int16_t)sext<12>(imm)? 1 : 0; + } + } + TRAP_SLTI:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::SLTIU: { uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -897,11 +917,13 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { - if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = (*(X+rs1 % traits::RFS) < (uint32_t)((int16_t)sext<12>(imm)))? 1 : 0; - } catch(...){} - } - break; + { + if((rd % traits::RFS) != 0) { + *(X+rd % traits::RFS) = (*(X+rs1 % traits::RFS) < (uint32_t)((int16_t)sext<12>(imm)))? 1 : 0; + } + } + TRAP_SLTIU:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::XORI: { uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -918,11 +940,13 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { - if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) ^ (int16_t)sext<12>(imm); - } catch(...){} - } - break; + { + if((rd % traits::RFS) != 0) { + *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) ^ (int16_t)sext<12>(imm); + } + } + TRAP_XORI:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::ORI: { uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -939,11 +963,13 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { - if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) | (int16_t)sext<12>(imm); - } catch(...){} - } - break; + { + if((rd % traits::RFS) != 0) { + *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) | (int16_t)sext<12>(imm); + } + } + TRAP_ORI:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::ANDI: { uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -960,11 +986,13 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { - if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) & (int16_t)sext<12>(imm); - } catch(...){} - } - break; + { + if((rd % traits::RFS) != 0) { + *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) & (int16_t)sext<12>(imm); + } + } + TRAP_ANDI:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::SLLI: { uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -981,16 +1009,18 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { - if(shamt > 31) { - raise(0, 0); - } - else { - if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) << shamt; - } - } catch(...){} - } - break; + { + if(shamt > 31) { + raise(0, 0); + } + else { + if((rd % traits::RFS) != 0) { + *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) << shamt; + } + } + } + TRAP_SLLI:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::SRLI: { uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1007,16 +1037,18 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { - if(shamt > 31) { - raise(0, 0); - } - else { - if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) >> shamt; - } - } catch(...){} - } - break; + { + if(shamt > 31) { + raise(0, 0); + } + else { + if((rd % traits::RFS) != 0) { + *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) >> shamt; + } + } + } + TRAP_SRLI:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::SRAI: { uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1033,16 +1065,18 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { - if(shamt > 31) { - raise(0, 0); - } - else { - if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = (int32_t)*(X+rs1 % traits::RFS) >> shamt; - } - } catch(...){} - } - break; + { + if(shamt > 31) { + raise(0, 0); + } + else { + if((rd % traits::RFS) != 0) { + *(X+rd % traits::RFS) = (int32_t)*(X+rs1 % traits::RFS) >> shamt; + } + } + } + TRAP_SRAI:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::ADD: { uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1059,11 +1093,13 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { - if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) + *(X+rs2 % traits::RFS); - } catch(...){} - } - break; + { + if((rd % traits::RFS) != 0) { + *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) + *(X+rs2 % traits::RFS); + } + } + TRAP_ADD:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::SUB: { uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1080,11 +1116,13 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { - if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) - *(X+rs2 % traits::RFS); - } catch(...){} - } - break; + { + if((rd % traits::RFS) != 0) { + *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) - *(X+rs2 % traits::RFS); + } + } + TRAP_SUB:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::SLL: { uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1101,11 +1139,13 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { - if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) << (*(X+rs2 % traits::RFS) & (traits::XLEN - 1)); - } catch(...){} - } - break; + { + if((rd % traits::RFS) != 0) { + *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) << (*(X+rs2 % traits::RFS) & (traits::XLEN - 1)); + } + } + TRAP_SLL:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::SLT: { uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1122,11 +1162,13 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { - if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = (int32_t)*(X+rs1 % traits::RFS) < (int32_t)*(X+rs2 % traits::RFS)? 1 : 0; - } catch(...){} - } - break; + { + if((rd % traits::RFS) != 0) { + *(X+rd % traits::RFS) = (int32_t)*(X+rs1 % traits::RFS) < (int32_t)*(X+rs2 % traits::RFS)? 1 : 0; + } + } + TRAP_SLT:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::SLTU: { uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1143,11 +1185,13 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { - if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = (uint32_t)*(X+rs1 % traits::RFS) < (uint32_t)*(X+rs2 % traits::RFS)? 1 : 0; - } catch(...){} - } - break; + { + if((rd % traits::RFS) != 0) { + *(X+rd % traits::RFS) = (uint32_t)*(X+rs1 % traits::RFS) < (uint32_t)*(X+rs2 % traits::RFS)? 1 : 0; + } + } + TRAP_SLTU:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::XOR: { uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1164,11 +1208,13 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { - if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) ^ *(X+rs2 % traits::RFS); - } catch(...){} - } - break; + { + if((rd % traits::RFS) != 0) { + *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) ^ *(X+rs2 % traits::RFS); + } + } + TRAP_XOR:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::SRL: { uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1185,11 +1231,13 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { - if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) >> (*(X+rs2 % traits::RFS) & (traits::XLEN - 1)); - } catch(...){} - } - break; + { + if((rd % traits::RFS) != 0) { + *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) >> (*(X+rs2 % traits::RFS) & (traits::XLEN - 1)); + } + } + TRAP_SRL:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::SRA: { uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1206,11 +1254,13 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { - if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = (int32_t)*(X+rs1 % traits::RFS) >> (*(X+rs2 % traits::RFS) & (traits::XLEN - 1)); - } catch(...){} - } - break; + { + if((rd % traits::RFS) != 0) { + *(X+rd % traits::RFS) = (int32_t)*(X+rs1 % traits::RFS) >> (*(X+rs2 % traits::RFS) & (traits::XLEN - 1)); + } + } + TRAP_SRA:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::OR: { uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1227,11 +1277,13 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { - if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) | *(X+rs2 % traits::RFS); - } catch(...){} - } - break; + { + if((rd % traits::RFS) != 0) { + *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) | *(X+rs2 % traits::RFS); + } + } + TRAP_OR:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::AND: { uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1248,11 +1300,13 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { - if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) & *(X+rs2 % traits::RFS); - } catch(...){} - } - break; + { + if((rd % traits::RFS) != 0) { + *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) & *(X+rs2 % traits::RFS); + } + } + TRAP_AND:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::FENCE: { uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1270,11 +1324,12 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // used registers// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { - writeSpace1(traits::FENCE, traits::fence, pred << 4 | succ); - } catch(...){} - } - break; + { + super::template write_mem(traits::FENCE, traits::fence, pred << 4 | succ); + if(this->core.trap_state) goto TRAP_FENCE; + } + TRAP_FENCE:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::ECALL: { if(this->disass_enabled){ /* generate console output when executing the command */ @@ -1284,11 +1339,11 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // used registers// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { - raise(0, 11); - } catch(...){} - } - break; + { + raise(0, 11); + } + TRAP_ECALL:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::EBREAK: { if(this->disass_enabled){ /* generate console output when executing the command */ @@ -1298,11 +1353,11 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // used registers// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { - raise(0, 3); - } catch(...){} - } - break; + { + raise(0, 3); + } + TRAP_EBREAK:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::URET: { if(this->disass_enabled){ /* generate console output when executing the command */ @@ -1312,11 +1367,11 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // used registers// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { - leave(0); - } catch(...){} - } - break; + { + leave(0); + } + TRAP_URET:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::SRET: { if(this->disass_enabled){ /* generate console output when executing the command */ @@ -1326,11 +1381,11 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // used registers// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { - leave(1); - } catch(...){} - } - break; + { + leave(1); + } + TRAP_SRET:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::MRET: { if(this->disass_enabled){ /* generate console output when executing the command */ @@ -1340,11 +1395,11 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // used registers// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { - leave(3); - } catch(...){} - } - break; + { + leave(3); + } + TRAP_MRET:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::WFI: { if(this->disass_enabled){ /* generate console output when executing the command */ @@ -1354,11 +1409,11 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // used registers// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { - wait(1); - } catch(...){} - } - break; + { + wait(1); + } + TRAP_WFI:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::DRET: { if(this->disass_enabled){ /* generate console output when executing the command */ @@ -1372,17 +1427,18 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { { - if(*PRIV < 4) raise(0, 2); + if(*PRIV < 4) { + raise(0, 2); + } else { - pc_assign(*NEXT_PC) = *DPC; + *NEXT_PC = *DPC; + super::ex_info.branch_taken=true; *PRIV &= 0x3; } } - } catch(...){} - } - break; + TRAP_DRET:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::CSRRW: { uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1399,21 +1455,22 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { { uint32_t xrs1 = *(X+rs1 % traits::RFS); if((rd % traits::RFS) != 0) { - uint32_t xrd = readSpace4(traits::CSR, csr); - writeSpace4(traits::CSR, csr, xrs1); + uint32_t xrd = super::template read_mem(traits::CSR, csr); + if(this->core.trap_state) goto TRAP_CSRRW; + super::template write_mem(traits::CSR, csr, xrs1); + if(this->core.trap_state) goto TRAP_CSRRW; *(X+rd % traits::RFS) = xrd; } else { - writeSpace4(traits::CSR, csr, xrs1); + super::template write_mem(traits::CSR, csr, xrs1); + if(this->core.trap_state) goto TRAP_CSRRW; } } - } catch(...){} - } - break; + TRAP_CSRRW:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::CSRRS: { uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1430,16 +1487,20 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { { - uint32_t xrd = readSpace4(traits::CSR, csr); + uint32_t xrd = super::template read_mem(traits::CSR, csr); + if(this->core.trap_state) goto TRAP_CSRRS; uint32_t xrs1 = *(X+rs1 % traits::RFS); - if(rs1 != 0) writeSpace4(traits::CSR, csr, xrd | xrs1); - if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = xrd; + if(rs1 != 0) { + super::template write_mem(traits::CSR, csr, xrd | xrs1); + if(this->core.trap_state) goto TRAP_CSRRS; + } + if((rd % traits::RFS) != 0) { + *(X+rd % traits::RFS) = xrd; + } } - } catch(...){} - } - break; + TRAP_CSRRS:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::CSRRC: { uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1456,16 +1517,20 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { { - uint32_t xrd = readSpace4(traits::CSR, csr); + uint32_t xrd = super::template read_mem(traits::CSR, csr); + if(this->core.trap_state) goto TRAP_CSRRC; uint32_t xrs1 = *(X+rs1 % traits::RFS); - if(rs1 != 0) writeSpace4(traits::CSR, csr, xrd & ~ xrs1); - if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = xrd; + if(rs1 != 0) { + super::template write_mem(traits::CSR, csr, xrd & ~ xrs1); + if(this->core.trap_state) goto TRAP_CSRRC; + } + if((rd % traits::RFS) != 0) { + *(X+rd % traits::RFS) = xrd; + } } - } catch(...){} - } - break; + TRAP_CSRRC:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::CSRRWI: { uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t zimm = ((bit_sub<15,5>(instr))); @@ -1482,15 +1547,17 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { { - uint32_t xrd = readSpace4(traits::CSR, csr); - writeSpace4(traits::CSR, csr, (uint32_t)zimm); - if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = xrd; + uint32_t xrd = super::template read_mem(traits::CSR, csr); + if(this->core.trap_state) goto TRAP_CSRRWI; + super::template write_mem(traits::CSR, csr, (uint32_t)zimm); + if(this->core.trap_state) goto TRAP_CSRRWI; + if((rd % traits::RFS) != 0) { + *(X+rd % traits::RFS) = xrd; + } } - } catch(...){} - } - break; + TRAP_CSRRWI:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::CSRRSI: { uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t zimm = ((bit_sub<15,5>(instr))); @@ -1507,15 +1574,19 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { { - uint32_t xrd = readSpace4(traits::CSR, csr); - if(zimm != 0) writeSpace4(traits::CSR, csr, xrd | (uint32_t)zimm); - if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = xrd; + uint32_t xrd = super::template read_mem(traits::CSR, csr); + if(this->core.trap_state) goto TRAP_CSRRSI; + if(zimm != 0) { + super::template write_mem(traits::CSR, csr, xrd | (uint32_t)zimm); + if(this->core.trap_state) goto TRAP_CSRRSI; + } + if((rd % traits::RFS) != 0) { + *(X+rd % traits::RFS) = xrd; + } } - } catch(...){} - } - break; + TRAP_CSRRSI:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::CSRRCI: { uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t zimm = ((bit_sub<15,5>(instr))); @@ -1532,15 +1603,19 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { { - uint32_t xrd = readSpace4(traits::CSR, csr); - if(zimm != 0) writeSpace4(traits::CSR, csr, xrd & ~ ((uint32_t)zimm)); - if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = xrd; + uint32_t xrd = super::template read_mem(traits::CSR, csr); + if(this->core.trap_state) goto TRAP_CSRRCI; + if(zimm != 0) { + super::template write_mem(traits::CSR, csr, xrd & ~ ((uint32_t)zimm)); + if(this->core.trap_state) goto TRAP_CSRRCI; + } + if((rd % traits::RFS) != 0) { + *(X+rd % traits::RFS) = xrd; + } } - } catch(...){} - } - break; + TRAP_CSRRCI:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::FENCE_I: { uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1556,11 +1631,12 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // used registers// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { - writeSpace2(traits::FENCE, traits::fencei, imm); - } catch(...){} - } - break; + { + super::template write_mem(traits::FENCE, traits::fencei, imm); + if(this->core.trap_state) goto TRAP_FENCE_I; + } + TRAP_FENCE_I:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::MUL: { uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1577,16 +1653,14 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { { if((rd % traits::RFS) != 0) { int64_t res = (int64_t)(int32_t)*(X+rs1 % traits::RFS) * (int64_t)(int32_t)*(X+rs2 % traits::RFS); *(X+rd % traits::RFS) = (uint32_t)res; } } - } catch(...){} - } - break; + TRAP_MUL:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::MULH: { uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1603,16 +1677,14 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { { if((rd % traits::RFS) != 0) { int64_t res = (int64_t)(int32_t)*(X+rs1 % traits::RFS) * (int64_t)(int32_t)*(X+rs2 % traits::RFS); *(X+rd % traits::RFS) = (uint32_t)(res >> traits::XLEN); } } - } catch(...){} - } - break; + TRAP_MULH:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::MULHSU: { uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1629,16 +1701,14 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { { if((rd % traits::RFS) != 0) { int64_t res = (int64_t)(int32_t)*(X+rs1 % traits::RFS) * (uint64_t)*(X+rs2 % traits::RFS); *(X+rd % traits::RFS) = (uint32_t)(res >> traits::XLEN); } } - } catch(...){} - } - break; + TRAP_MULHSU:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::MULHU: { uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1655,16 +1725,14 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { { if((rd % traits::RFS) != 0) { uint64_t res = (uint64_t)*(X+rs1 % traits::RFS) * (uint64_t)*(X+rs2 % traits::RFS); *(X+rd % traits::RFS) = (uint32_t)(res >> traits::XLEN); } } - } catch(...){} - } - break; + TRAP_MULHU:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::DIV: { uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1681,20 +1749,24 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { { if((rd % traits::RFS) != 0) { if(*(X+rs2 % traits::RFS) != 0) { uint32_t MMIN = 1 << (traits::XLEN - 1); - if(*(X+rs1 % traits::RFS) == MMIN && (int32_t)*(X+rs2 % traits::RFS) == - 1) *(X+rd % traits::RFS) = MMIN; - else *(X+rd % traits::RFS) = (int32_t)*(X+rs1 % traits::RFS) / (int32_t)*(X+rs2 % traits::RFS); + if(*(X+rs1 % traits::RFS) == MMIN && (int32_t)*(X+rs2 % traits::RFS) == - 1) { + *(X+rd % traits::RFS) = MMIN; + } + else { + *(X+rd % traits::RFS) = (int32_t)*(X+rs1 % traits::RFS) / (int32_t)*(X+rs2 % traits::RFS); + } + } + else { + *(X+rd % traits::RFS) = - 1; } - else *(X+rd % traits::RFS) = - 1; } } - } catch(...){} - } - break; + TRAP_DIV:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::DIVU: { uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1711,16 +1783,18 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { { if((rd % traits::RFS) != 0) { - if(*(X+rs2 % traits::RFS) != 0) *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) / *(X+rs2 % traits::RFS); - else *(X+rd % traits::RFS) = - 1; + if(*(X+rs2 % traits::RFS) != 0) { + *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) / *(X+rs2 % traits::RFS); + } + else { + *(X+rd % traits::RFS) = - 1; + } } } - } catch(...){} - } - break; + TRAP_DIVU:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::REM: { uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1737,20 +1811,24 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { { if((rd % traits::RFS) != 0) { if(*(X+rs2 % traits::RFS) != 0) { uint32_t MMIN = 1 << (traits::XLEN - 1); - if(*(X+rs1 % traits::RFS) == MMIN && (int32_t)*(X+rs2 % traits::RFS) == - 1) *(X+rd % traits::RFS) = 0; - else *(X+rd % traits::RFS) = (int32_t)*(X+rs1 % traits::RFS) % (int32_t)*(X+rs2 % traits::RFS); + if(*(X+rs1 % traits::RFS) == MMIN && (int32_t)*(X+rs2 % traits::RFS) == - 1) { + *(X+rd % traits::RFS) = 0; + } + else { + *(X+rd % traits::RFS) = (int32_t)*(X+rs1 % traits::RFS) % (int32_t)*(X+rs2 % traits::RFS); + } + } + else { + *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS); } - else *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS); } } - } catch(...){} - } - break; + TRAP_REM:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::REMU: { uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1767,16 +1845,18 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 4; // execute instruction - try { { if((rd % traits::RFS) != 0) { - if(*(X+rs2 % traits::RFS) != 0) *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) % *(X+rs2 % traits::RFS); - else *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS); + if(*(X+rs2 % traits::RFS) != 0) { + *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) % *(X+rs2 % traits::RFS); + } + else { + *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS); + } } } - } catch(...){} - } - break; + TRAP_REMU:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::CADDI4SPN: { uint8_t rd = ((bit_sub<2,3>(instr))); uint16_t imm = ((bit_sub<5,1>(instr) << 3) | (bit_sub<6,1>(instr) << 2) | (bit_sub<7,4>(instr) << 6) | (bit_sub<11,2>(instr) << 4)); @@ -1792,12 +1872,16 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 2; // execute instruction - try { - if(imm) *(X+rd + 8) = *(X+2) + imm; - else raise(0, 2); - } catch(...){} - } - break; + { + if(imm) { + *(X+rd + 8) = *(X+2) + imm; + } + else { + raise(0, 2); + } + } + TRAP_CADDI4SPN:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::CLW: { uint8_t rd = ((bit_sub<2,3>(instr))); uint8_t uimm = ((bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 2) | (bit_sub<10,3>(instr) << 3)); @@ -1814,14 +1898,13 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 2; // execute instruction - try { { uint32_t load_address = *(X+rs1 + 8) + uimm; - *(X+rd + 8) = (int32_t)readSpace4(traits::MEM, load_address); + *(X+rd + 8) = (int32_t)super::template read_mem(traits::MEM, load_address); + if(this->core.trap_state) goto TRAP_CLW; } - } catch(...){} - } - break; + TRAP_CLW:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::CSW: { uint8_t rs2 = ((bit_sub<2,3>(instr))); uint8_t uimm = ((bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 2) | (bit_sub<10,3>(instr) << 3)); @@ -1838,14 +1921,13 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 2; // execute instruction - try { { uint32_t load_address = *(X+rs1 + 8) + uimm; - writeSpace4(traits::MEM, load_address, *(X+rs2 + 8)); + super::template write_mem(traits::MEM, load_address, *(X+rs2 + 8)); + if(this->core.trap_state) goto TRAP_CSW; } - } catch(...){} - } - break; + TRAP_CSW:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::CADDI: { uint8_t imm = ((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); uint8_t rs1 = ((bit_sub<7,5>(instr))); @@ -1861,11 +1943,11 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 2; // execute instruction - try { - *(X+rs1 % traits::RFS) = *(X+rs1 % traits::RFS) + (int8_t)sext<6>(imm); - } catch(...){} - } - break; + { + *(X+rs1 % traits::RFS) = *(X+rs1 % traits::RFS) + (int8_t)sext<6>(imm); + } + TRAP_CADDI:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::CNOP: { uint8_t nzimm = ((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); if(this->disass_enabled){ @@ -1876,12 +1958,10 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // used registers// calculate next pc value *NEXT_PC = *PC + 2; // execute instruction - try { { } - } catch(...){} - } - break; + TRAP_CNOP:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::CJAL: { uint16_t imm = ((bit_sub<2,1>(instr) << 5) | (bit_sub<3,3>(instr) << 1) | (bit_sub<6,1>(instr) << 7) | (bit_sub<7,1>(instr) << 6) | (bit_sub<8,1>(instr) << 10) | (bit_sub<9,2>(instr) << 8) | (bit_sub<11,1>(instr) << 4) | (bit_sub<12,1>(instr) << 11)); if(this->disass_enabled){ @@ -1896,14 +1976,13 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 2; // execute instruction - try { { *(X+1) = *PC + 2; - pc_assign(*NEXT_PC) = *PC + (int16_t)sext<12>(imm); + *NEXT_PC = *PC + (int16_t)sext<12>(imm); + super::ex_info.branch_taken=true; } - } catch(...){} - } - break; + TRAP_CJAL:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::CLI: { uint8_t imm = ((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); uint8_t rd = ((bit_sub<7,5>(instr))); @@ -1919,13 +1998,13 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 2; // execute instruction - try { { - if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = (int8_t)sext<6>(imm); + if((rd % traits::RFS) != 0) { + *(X+rd % traits::RFS) = (int8_t)sext<6>(imm); + } } - } catch(...){} - } - break; + TRAP_CLI:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::CLUI: { uint32_t imm = ((bit_sub<2,5>(instr) << 12) | (bit_sub<12,1>(instr) << 17)); uint8_t rd = ((bit_sub<7,5>(instr))); @@ -1941,14 +2020,16 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 2; // execute instruction - try { { - if(imm == 0) raise(0, 2); - if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = (int32_t)sext<18>(imm); + if(imm == 0) { + raise(0, 2); + } + if((rd % traits::RFS) != 0) { + *(X+rd % traits::RFS) = (int32_t)sext<18>(imm); + } } - } catch(...){} - } - break; + TRAP_CLUI:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::CADDI16SP: { uint16_t nzimm = ((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 7) | (bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 4) | (bit_sub<12,1>(instr) << 9)); if(this->disass_enabled){ @@ -1963,12 +2044,16 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 2; // execute instruction - try { - if(nzimm) *(X+2) = *(X+2) + (int16_t)sext<10>(nzimm); - else raise(0, 2); - } catch(...){} - } - break; + { + if(nzimm) { + *(X+2) = *(X+2) + (int16_t)sext<10>(nzimm); + } + else { + raise(0, 2); + } + } + TRAP_CADDI16SP:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::__reserved_clui: { uint8_t rd = ((bit_sub<7,5>(instr))); if(this->disass_enabled){ @@ -1979,11 +2064,11 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // used registers// calculate next pc value *NEXT_PC = *PC + 2; // execute instruction - try { - raise(0, 2); - } catch(...){} - } - break; + { + raise(0, 2); + } + TRAP___reserved_clui:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::CSRLI: { uint8_t shamt = ((bit_sub<2,5>(instr))); uint8_t rs1 = ((bit_sub<7,3>(instr))); @@ -1999,14 +2084,12 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 2; // execute instruction - try { { uint8_t rs1_idx = rs1 + 8; *(X+rs1_idx) = *(X+rs1_idx) >> shamt; } - } catch(...){} - } - break; + TRAP_CSRLI:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::CSRAI: { uint8_t shamt = ((bit_sub<2,5>(instr))); uint8_t rs1 = ((bit_sub<7,3>(instr))); @@ -2022,18 +2105,20 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 2; // execute instruction - try { - if(shamt) { - uint8_t rs1_idx = rs1 + 8; - *(X+rs1_idx) = ((int32_t)*(X+rs1_idx)) >> shamt; - } - else if(traits::XLEN == 128) { - uint8_t rs1_idx = rs1 + 8; - *(X+rs1_idx) = ((int32_t)*(X+rs1_idx)) >> 64; - } - } catch(...){} - } - break; + { + if(shamt) { + uint8_t rs1_idx = rs1 + 8; + *(X+rs1_idx) = ((int32_t)*(X+rs1_idx)) >> shamt; + } + else { + if(traits::XLEN == 128) { + uint8_t rs1_idx = rs1 + 8; + *(X+rs1_idx) = ((int32_t)*(X+rs1_idx)) >> 64; + } + } + } + TRAP_CSRAI:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::CANDI: { uint8_t imm = ((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); uint8_t rs1 = ((bit_sub<7,3>(instr))); @@ -2049,14 +2134,12 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 2; // execute instruction - try { { uint8_t rs1_idx = rs1 + 8; *(X+rs1_idx) = *(X+rs1_idx) & (int8_t)sext<6>(imm); } - } catch(...){} - } - break; + TRAP_CANDI:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::CSUB: { uint8_t rs2 = ((bit_sub<2,3>(instr))); uint8_t rd = ((bit_sub<7,3>(instr))); @@ -2072,14 +2155,12 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 2; // execute instruction - try { { uint8_t rd_idx = rd + 8; *(X+rd_idx) = *(X+rd_idx) - *(X+rs2 + 8); } - } catch(...){} - } - break; + TRAP_CSUB:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::CXOR: { uint8_t rs2 = ((bit_sub<2,3>(instr))); uint8_t rd = ((bit_sub<7,3>(instr))); @@ -2095,14 +2176,12 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 2; // execute instruction - try { { uint8_t rd_idx = rd + 8; *(X+rd_idx) = *(X+rd_idx) ^ *(X+rs2 + 8); } - } catch(...){} - } - break; + TRAP_CXOR:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::COR: { uint8_t rs2 = ((bit_sub<2,3>(instr))); uint8_t rd = ((bit_sub<7,3>(instr))); @@ -2118,14 +2197,12 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 2; // execute instruction - try { { uint8_t rd_idx = rd + 8; *(X+rd_idx) = *(X+rd_idx) | *(X+rs2 + 8); } - } catch(...){} - } - break; + TRAP_COR:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::CAND: { uint8_t rs2 = ((bit_sub<2,3>(instr))); uint8_t rd = ((bit_sub<7,3>(instr))); @@ -2141,14 +2218,12 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 2; // execute instruction - try { { uint8_t rd_idx = rd + 8; *(X+rd_idx) = *(X+rd_idx) & *(X+rs2 + 8); } - } catch(...){} - } - break; + TRAP_CAND:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::CJ: { uint16_t imm = ((bit_sub<2,1>(instr) << 5) | (bit_sub<3,3>(instr) << 1) | (bit_sub<6,1>(instr) << 7) | (bit_sub<7,1>(instr) << 6) | (bit_sub<8,1>(instr) << 10) | (bit_sub<9,2>(instr) << 8) | (bit_sub<11,1>(instr) << 4) | (bit_sub<12,1>(instr) << 11)); if(this->disass_enabled){ @@ -2162,11 +2237,12 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // used registers// calculate next pc value *NEXT_PC = *PC + 2; // execute instruction - try { - pc_assign(*NEXT_PC) = *PC + (int16_t)sext<12>(imm); - } catch(...){} - } - break; + { + *NEXT_PC = *PC + (int16_t)sext<12>(imm); + super::ex_info.branch_taken=true; + } + TRAP_CJ:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::CBEQZ: { uint16_t imm = ((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 1) | (bit_sub<5,2>(instr) << 6) | (bit_sub<10,2>(instr) << 3) | (bit_sub<12,1>(instr) << 8)); uint8_t rs1 = ((bit_sub<7,3>(instr))); @@ -2182,11 +2258,14 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 2; // execute instruction - try { - if(*(X+rs1 + 8) == 0) pc_assign(*NEXT_PC) = *PC + (int16_t)sext<9>(imm); - } catch(...){} - } - break; + { + if(*(X+rs1 + 8) == 0) { + *NEXT_PC = *PC + (int16_t)sext<9>(imm); + super::ex_info.branch_taken=true; + } + } + TRAP_CBEQZ:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::CBNEZ: { uint16_t imm = ((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 1) | (bit_sub<5,2>(instr) << 6) | (bit_sub<10,2>(instr) << 3) | (bit_sub<12,1>(instr) << 8)); uint8_t rs1 = ((bit_sub<7,3>(instr))); @@ -2202,11 +2281,14 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 2; // execute instruction - try { - if(*(X+rs1 + 8) != 0) pc_assign(*NEXT_PC) = *PC + (int16_t)sext<9>(imm); - } catch(...){} - } - break; + { + if(*(X+rs1 + 8) != 0) { + *NEXT_PC = *PC + (int16_t)sext<9>(imm); + super::ex_info.branch_taken=true; + } + } + TRAP_CBNEZ:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::CSLLI: { uint8_t nzuimm = ((bit_sub<2,5>(instr))); uint8_t rs1 = ((bit_sub<7,5>(instr))); @@ -2222,11 +2304,13 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 2; // execute instruction - try { - if(nzuimm) *(X+rs1 % traits::RFS) = *(X+rs1 % traits::RFS) << nzuimm; - } catch(...){} - } - break; + { + if(nzuimm) { + *(X+rs1 % traits::RFS) = *(X+rs1 % traits::RFS) << nzuimm; + } + } + TRAP_CSLLI:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::CLWSP: { uint8_t uimm = ((bit_sub<2,2>(instr) << 6) | (bit_sub<4,3>(instr) << 2) | (bit_sub<12,1>(instr) << 5)); uint8_t rd = ((bit_sub<7,5>(instr))); @@ -2242,15 +2326,18 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 2; // execute instruction - try { - if(rd) { - uint32_t offs = *(X+2) + uimm; - *(X+rd % traits::RFS) = (int32_t)readSpace4(traits::MEM, offs); - } - else raise(0, 2); - } catch(...){} - } - break; + { + if(rd) { + uint32_t offs = *(X+2) + uimm; + *(X+rd % traits::RFS) = (int32_t)super::template read_mem(traits::MEM, offs); + if(this->core.trap_state) goto TRAP_CLWSP; + } + else { + raise(0, 2); + } + } + TRAP_CLWSP:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::CMV: { uint8_t rs2 = ((bit_sub<2,5>(instr))); uint8_t rd = ((bit_sub<7,5>(instr))); @@ -2266,11 +2353,13 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 2; // execute instruction - try { - if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = *(X+rs2 % traits::RFS); - } catch(...){} - } - break; + { + if((rd % traits::RFS) != 0) { + *(X+rd % traits::RFS) = *(X+rs2 % traits::RFS); + } + } + TRAP_CMV:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::CJR: { uint8_t rs1 = ((bit_sub<7,5>(instr))); if(this->disass_enabled){ @@ -2285,12 +2374,17 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 2; // execute instruction - try { - if(rs1) pc_assign(*NEXT_PC) = *(X+rs1 % traits::RFS) & ~ 0x1; - else raise(0, 2); - } catch(...){} - } - break; + { + if(rs1) { + *NEXT_PC = *(X+rs1 % traits::RFS) & ~ 0x1; + super::ex_info.branch_taken=true; + } + else { + raise(0, 2); + } + } + TRAP_CJR:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::__reserved_cmv: { if(this->disass_enabled){ /* generate console output when executing the command */ @@ -2300,11 +2394,11 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // used registers// calculate next pc value *NEXT_PC = *PC + 2; // execute instruction - try { - raise(0, 2); - } catch(...){} - } - break; + { + raise(0, 2); + } + TRAP___reserved_cmv:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::CADD: { uint8_t rs2 = ((bit_sub<2,5>(instr))); uint8_t rd = ((bit_sub<7,5>(instr))); @@ -2320,11 +2414,13 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 2; // execute instruction - try { - if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = *(X+rd % traits::RFS) + *(X+rs2 % traits::RFS); - } catch(...){} - } - break; + { + if((rd % traits::RFS) != 0) { + *(X+rd % traits::RFS) = *(X+rd % traits::RFS) + *(X+rs2 % traits::RFS); + } + } + TRAP_CADD:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::CJALR: { uint8_t rs1 = ((bit_sub<7,5>(instr))); if(this->disass_enabled){ @@ -2339,15 +2435,14 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 2; // execute instruction - try { { int32_t new_pc = *(X+rs1 % traits::RFS); *(X+1) = *PC + 2; - pc_assign(*NEXT_PC) = new_pc & ~ 0x1; + *NEXT_PC = new_pc & ~ 0x1; + super::ex_info.branch_taken=true; } - } catch(...){} - } - break; + TRAP_CJALR:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::CEBREAK: { if(this->disass_enabled){ /* generate console output when executing the command */ @@ -2357,11 +2452,11 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // used registers// calculate next pc value *NEXT_PC = *PC + 2; // execute instruction - try { - raise(0, 3); - } catch(...){} - } - break; + { + raise(0, 3); + } + TRAP_CEBREAK:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::CSWSP: { uint8_t rs2 = ((bit_sub<2,5>(instr))); uint8_t uimm = ((bit_sub<7,2>(instr) << 6) | (bit_sub<9,4>(instr) << 2)); @@ -2377,14 +2472,13 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co auto* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]);// calculate next pc value *NEXT_PC = *PC + 2; // execute instruction - try { { uint32_t offs = *(X+2) + uimm; - writeSpace4(traits::MEM, offs, (uint32_t)*(X+rs2 % traits::RFS)); + super::template write_mem(traits::MEM, offs, (uint32_t)*(X+rs2 % traits::RFS)); + if(this->core.trap_state) goto TRAP_CSWSP; } - } catch(...){} - } - break; + TRAP_CSWSP:break; + }// @suppress("No break at end of case") case arch::traits::opcode_e::DII: { if(this->disass_enabled){ /* generate console output when executing the command */ @@ -2394,11 +2488,11 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co // used registers// calculate next pc value *NEXT_PC = *PC + 2; // execute instruction - try { - raise(0, 2); - } catch(...){} - } - break; + { + raise(0, 2); + } + TRAP_DII:break; + }// @suppress("No break at end of case") default: { *NEXT_PC = *PC + ((instr & 3) == 3 ? 4 : 2); raise(0, 2);