diff --git a/src/vm/interp/vm_tgc_c.cpp b/src/vm/interp/vm_tgc_c.cpp index 9866654..c8b2461 100644 --- a/src/vm/interp/vm_tgc_c.cpp +++ b/src/vm/interp/vm_tgc_c.cpp @@ -382,2113 +382,2040 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, static_cast(inst_id)); switch(inst_id){ case arch::traits::opcode_e::LUI: { - uint8_t rd = ((bit_sub<7,5>(instr))); - uint32_t imm = ((bit_sub<12,20>(instr) << 12)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "lui"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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(...){} - TRAP_LUI:break; - }// @suppress("No break at end of case") + uint8_t rd = ((bit_sub<7,5>(instr))); + uint32_t imm = ((bit_sub<12,20>(instr) << 12)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "lui"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 + { + 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)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm:#08x}", fmt::arg("mnemonic", "auipc"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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(...){} - TRAP_AUIPC:break; - }// @suppress("No break at end of case") + uint8_t rd = ((bit_sub<7,5>(instr))); + uint32_t imm = ((bit_sub<12,20>(instr) << 12)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#08x}", fmt::arg("mnemonic", "auipc"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 + { + 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)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm:#0x}", fmt::arg("mnemonic", "jal"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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 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)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#0x}", fmt::arg("mnemonic", "jal"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 { - 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); - } - } - - } catch(...){} - TRAP_JAL:break; - }// @suppress("No break at end of case") + if(imm % traits::INSTR_ALIGNMENT) { + raise(0, 0); + } + else { + 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; + } + } + 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))); - uint16_t imm = ((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {imm:#0x}", fmt::arg("mnemonic", "jalr"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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 rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint16_t imm = ((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm:#0x}", fmt::arg("mnemonic", "jalr"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 { - 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; - } - } - - } catch(...){} - TRAP_JALR:break; - }// @suppress("No break at end of case") + 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; + } + *NEXT_PC = new_pc & ~ 0x1; + super::ex_info.branch_taken=true; + } + } + 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))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "beq"), - fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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 { + 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))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "beq"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 { - 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); - } - } - - } catch(...){} - TRAP_BEQ:break; - }// @suppress("No break at end of case") + 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; + } + } + } + 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))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bne"), - fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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 { + 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))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bne"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 { - 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); - } - } - - } catch(...){} - TRAP_BNE:break; - }// @suppress("No break at end of case") + 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; + } + } + } + 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))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "blt"), - fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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 { + 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))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "blt"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 { - 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); - } - } - - } catch(...){} - TRAP_BLT:break; - }// @suppress("No break at end of case") + 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; + } + } + } + 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))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bge"), - fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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 { + 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))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bge"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 { - 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); - } - } - - } catch(...){} - TRAP_BGE:break; - }// @suppress("No break at end of case") + 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; + } + } + } + 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))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bltu"), - fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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 { + 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))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bltu"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 { - 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); - } - } - - } catch(...){} - TRAP_BLTU:break; - }// @suppress("No break at end of case") + 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; + } + } + } + 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))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bgeu"), - fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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 { + 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))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bgeu"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 { - 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); - } - } - - } catch(...){} - TRAP_BGEU:break; - }// @suppress("No break at end of case") + 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; + } + } + } + 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))); - uint16_t imm = ((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lb"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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 rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint16_t imm = ((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lb"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 { - 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; - } - - } catch(...){} - TRAP_LB:break; - }// @suppress("No break at end of case") + uint8_t read_res = super::template read_mem(traits::MEM, *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm)); + if(this->core.trap_state) goto TRAP_LB; + int8_t res = (int8_t)read_res; + if((rd % traits::RFS) != 0) { + *(X+rd % traits::RFS) = res; + } + } + 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))); - uint16_t imm = ((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lh"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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 rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint16_t imm = ((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lh"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 { - 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; - } - - } catch(...){} - TRAP_LH:break; - }// @suppress("No break at end of case") + uint32_t load_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); + uint16_t read_res = super::template read_mem(traits::MEM, load_address); + if(this->core.trap_state) goto TRAP_LH; + int16_t res = (int16_t)read_res; + if((rd % traits::RFS) != 0) { + *(X+rd % traits::RFS) = res; + } + } + 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))); - uint16_t imm = ((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lw"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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 rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint16_t imm = ((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lw"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 { - 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; - } - - } catch(...){} - TRAP_LW:break; - }// @suppress("No break at end of case") + uint32_t load_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); + uint32_t read_res = super::template read_mem(traits::MEM, load_address); + if(this->core.trap_state) goto TRAP_LW; + int32_t res = (int32_t)read_res; + if((rd % traits::RFS) != 0) { + *(X+rd % traits::RFS) = (uint32_t)res; + } + } + 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))); - uint16_t imm = ((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lbu"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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 rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint16_t imm = ((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lbu"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 { - 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; - } - - } catch(...){} - TRAP_LBU:break; - }// @suppress("No break at end of case") + uint8_t read_res = super::template read_mem(traits::MEM, *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm)); + if(this->core.trap_state) goto TRAP_LBU; + uint8_t res = (uint8_t)read_res; + if((rd % traits::RFS) != 0) { + *(X+rd % traits::RFS) = res; + } + } + 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))); - uint16_t imm = ((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lhu"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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 rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint16_t imm = ((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lhu"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 { - 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; - } - - } catch(...){} - TRAP_LHU:break; - }// @suppress("No break at end of case") + uint32_t load_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); + uint16_t read_res = super::template read_mem(traits::MEM, load_address); + if(this->core.trap_state) goto TRAP_LHU; + uint16_t res = (uint16_t)read_res; + if((rd % traits::RFS) != 0) { + *(X+rd % traits::RFS) = res; + } + } + 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))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sb"), - fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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(...){} - TRAP_SB:break; - }// @suppress("No break at end of case") + uint16_t imm = ((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sb"), + fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 + { + 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))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sh"), - fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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 { + uint16_t imm = ((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sh"), + fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 { - uint32_t store_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); - writeSpace2(traits::MEM, store_address, (int16_t)*(X+rs2 % traits::RFS)); - } - - } catch(...){} - TRAP_SH:break; - }// @suppress("No break at end of case") + uint32_t store_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); + super::template write_mem(traits::MEM, store_address, (int16_t)*(X+rs2 % traits::RFS)); + if(this->core.trap_state) goto TRAP_SH; + } + 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))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sw"), - fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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 { + uint16_t imm = ((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sw"), + fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 { - uint32_t store_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); - writeSpace4(traits::MEM, store_address, *(X+rs2 % traits::RFS)); - } - - } catch(...){} - TRAP_SW:break; - }// @suppress("No break at end of case") + uint32_t store_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); + super::template write_mem(traits::MEM, store_address, *(X+rs2 % traits::RFS)); + if(this->core.trap_state) goto TRAP_SW; + } + 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))); - uint16_t imm = ((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "addi"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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(...){} - TRAP_ADDI:break; - }// @suppress("No break at end of case") + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint16_t imm = ((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "addi"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 + { + 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))); - uint16_t imm = ((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "slti"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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(...){} - TRAP_SLTI:break; - }// @suppress("No break at end of case") + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint16_t imm = ((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "slti"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 + { + 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))); - uint16_t imm = ((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "sltiu"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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(...){} - TRAP_SLTIU:break; - }// @suppress("No break at end of case") + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint16_t imm = ((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "sltiu"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 + { + 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))); - uint16_t imm = ((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "xori"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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(...){} - TRAP_XORI:break; - }// @suppress("No break at end of case") + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint16_t imm = ((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "xori"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 + { + 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))); - uint16_t imm = ((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "ori"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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(...){} - TRAP_ORI:break; - }// @suppress("No break at end of case") + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint16_t imm = ((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "ori"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 + { + 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))); - uint16_t imm = ((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "andi"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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(...){} - TRAP_ANDI:break; - }// @suppress("No break at end of case") + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint16_t imm = ((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "andi"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 + { + 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))); - uint8_t shamt = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "slli"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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(...){} - TRAP_SLLI:break; - }// @suppress("No break at end of case") + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t shamt = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "slli"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 + { + 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))); - uint8_t shamt = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "srli"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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(...){} - TRAP_SRLI:break; - }// @suppress("No break at end of case") + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t shamt = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "srli"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 + { + 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))); - uint8_t shamt = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "srai"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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(...){} - TRAP_SRAI:break; - }// @suppress("No break at end of case") + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t shamt = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "srai"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 + { + 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))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "add"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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(...){} - TRAP_ADD:break; - }// @suppress("No break at end of case") + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "add"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 + { + 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))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sub"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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(...){} - TRAP_SUB:break; - }// @suppress("No break at end of case") + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sub"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 + { + 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))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sll"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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(...){} - TRAP_SLL:break; - }// @suppress("No break at end of case") + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sll"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 + { + 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))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "slt"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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(...){} - TRAP_SLT:break; - }// @suppress("No break at end of case") + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "slt"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 + { + 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))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sltu"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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(...){} - TRAP_SLTU:break; - }// @suppress("No break at end of case") + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sltu"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 + { + 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))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "xor"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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(...){} - TRAP_XOR:break; - }// @suppress("No break at end of case") + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "xor"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 + { + 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))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "srl"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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(...){} - TRAP_SRL:break; - }// @suppress("No break at end of case") + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "srl"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 + { + 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))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sra"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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(...){} - TRAP_SRA:break; - }// @suppress("No break at end of case") + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sra"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 + { + 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))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "or"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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(...){} - TRAP_OR:break; - }// @suppress("No break at end of case") + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "or"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 + { + 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))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "and"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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(...){} - TRAP_AND:break; - }// @suppress("No break at end of case") + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "and"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 + { + 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))); - uint8_t succ = ((bit_sub<20,4>(instr))); - uint8_t pred = ((bit_sub<24,4>(instr))); - uint8_t fm = ((bit_sub<28,4>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {pred}, {succ} ({fm} , {rs1}, {rd})", fmt::arg("mnemonic", "fence"), - fmt::arg("pred", pred), fmt::arg("succ", succ), fmt::arg("fm", fm), fmt::arg("rs1", name(rs1)), fmt::arg("rd", name(rd))); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - writeSpace1(traits::FENCE, traits::fence, pred << 4 | succ); - - } catch(...){} - TRAP_FENCE:break; - }// @suppress("No break at end of case") + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t succ = ((bit_sub<20,4>(instr))); + uint8_t pred = ((bit_sub<24,4>(instr))); + uint8_t fm = ((bit_sub<28,4>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {pred}, {succ} ({fm} , {rs1}, {rd})", fmt::arg("mnemonic", "fence"), + fmt::arg("pred", pred), fmt::arg("succ", succ), fmt::arg("fm", fm), fmt::arg("rs1", name(rs1)), fmt::arg("rd", name(rd))); + this->core.disass_output(pc.val, mnemonic); + } + // used registers// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + { + 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 */ - this->core.disass_output(pc.val, "ecall"); - - } - // used registers// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - raise(0, 11); - - } catch(...){} - TRAP_ECALL:break; - }// @suppress("No break at end of case") + if(this->disass_enabled){ + /* generate console output when executing the command */ + this->core.disass_output(pc.val, "ecall"); + } + // used registers// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + { + 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 */ - this->core.disass_output(pc.val, "ebreak"); - - } - // used registers// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - raise(0, 3); - - } catch(...){} - TRAP_EBREAK:break; - }// @suppress("No break at end of case") + if(this->disass_enabled){ + /* generate console output when executing the command */ + this->core.disass_output(pc.val, "ebreak"); + } + // used registers// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + { + 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 */ - this->core.disass_output(pc.val, "uret"); - - } - // used registers// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - leave(0); - - } catch(...){} - TRAP_URET:break; - }// @suppress("No break at end of case") + if(this->disass_enabled){ + /* generate console output when executing the command */ + this->core.disass_output(pc.val, "uret"); + } + // used registers// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + { + 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 */ - this->core.disass_output(pc.val, "sret"); - - } - // used registers// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - leave(1); - - } catch(...){} - TRAP_SRET:break; - }// @suppress("No break at end of case") + if(this->disass_enabled){ + /* generate console output when executing the command */ + this->core.disass_output(pc.val, "sret"); + } + // used registers// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + { + 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 */ - this->core.disass_output(pc.val, "mret"); - - } - // used registers// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - leave(3); - - } catch(...){} - TRAP_MRET:break; - }// @suppress("No break at end of case") + if(this->disass_enabled){ + /* generate console output when executing the command */ + this->core.disass_output(pc.val, "mret"); + } + // used registers// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + { + 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 */ - this->core.disass_output(pc.val, "wfi"); - - } - // used registers// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - wait(1); - - } catch(...){} - TRAP_WFI:break; - }// @suppress("No break at end of case") + if(this->disass_enabled){ + /* generate console output when executing the command */ + this->core.disass_output(pc.val, "wfi"); + } + // used registers// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + { + 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 */ - this->core.disass_output(pc.val, "dret"); - - } - // used registers - auto* PRIV = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PRIV]); - - auto* DPC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::DPC]); - // calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { + if(this->disass_enabled){ + /* generate console output when executing the command */ + this->core.disass_output(pc.val, "dret"); + } + // used registers + auto* PRIV = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PRIV]); + + auto* DPC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::DPC]); + // calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction { - if(*PRIV < 4) raise(0, 2); - else { - pc_assign(*NEXT_PC) = *DPC; - *PRIV &= 0x3; - } - } - - } catch(...){} - TRAP_DRET:break; - }// @suppress("No break at end of case") + if(*PRIV < 4) { + raise(0, 2); + } + else { + *NEXT_PC = *DPC; + super::ex_info.branch_taken=true; + *PRIV &= 0x3; + } + } + 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))); - uint16_t csr = ((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrw"), - fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1))); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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 rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint16_t csr = ((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrw"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1))); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 { - uint32_t xrs1 = *(X+rs1 % traits::RFS); - if((rd % traits::RFS) != 0) { - uint32_t xrd = readSpace4(traits::CSR, csr); - writeSpace4(traits::CSR, csr, xrs1); - *(X+rd % traits::RFS) = xrd; - } - else { - writeSpace4(traits::CSR, csr, xrs1); - } - } - - } catch(...){} - TRAP_CSRRW:break; - }// @suppress("No break at end of case") + uint32_t xrs1 = *(X+rs1 % traits::RFS); + if((rd % traits::RFS) != 0) { + uint32_t read_res = super::template read_mem(traits::CSR, csr); + if(this->core.trap_state) goto TRAP_CSRRW; + uint32_t xrd = read_res; + super::template write_mem(traits::CSR, csr, xrs1); + if(this->core.trap_state) goto TRAP_CSRRW; + *(X+rd % traits::RFS) = xrd; + } + else { + super::template write_mem(traits::CSR, csr, xrs1); + if(this->core.trap_state) goto TRAP_CSRRW; + } + } + 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))); - uint16_t csr = ((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrs"), - fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1))); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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 rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint16_t csr = ((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrs"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1))); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 { - uint32_t xrd = readSpace4(traits::CSR, csr); - 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; - } - - } catch(...){} - TRAP_CSRRS:break; - }// @suppress("No break at end of case") + uint32_t read_res = super::template read_mem(traits::CSR, csr); + if(this->core.trap_state) goto TRAP_CSRRS; + uint32_t xrd = read_res; + uint32_t xrs1 = *(X+rs1 % traits::RFS); + 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; + } + } + 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))); - uint16_t csr = ((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrc"), - fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1))); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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 rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint16_t csr = ((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrc"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1))); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 { - uint32_t xrd = readSpace4(traits::CSR, csr); - 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; - } - - } catch(...){} - TRAP_CSRRC:break; - }// @suppress("No break at end of case") + uint32_t read_res = super::template read_mem(traits::CSR, csr); + if(this->core.trap_state) goto TRAP_CSRRC; + uint32_t xrd = read_res; + uint32_t xrs1 = *(X+rs1 % traits::RFS); + 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; + } + } + 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))); - uint16_t csr = ((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrwi"), - fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm)); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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 rd = ((bit_sub<7,5>(instr))); + uint8_t zimm = ((bit_sub<15,5>(instr))); + uint16_t csr = ((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrwi"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm)); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 { - uint32_t xrd = readSpace4(traits::CSR, csr); - writeSpace4(traits::CSR, csr, (uint32_t)zimm); - if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = xrd; - } - - } catch(...){} - TRAP_CSRRWI:break; - }// @suppress("No break at end of case") + uint32_t read_res = super::template read_mem(traits::CSR, csr); + if(this->core.trap_state) goto TRAP_CSRRWI; + uint32_t xrd = read_res; + 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; + } + } + 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))); - uint16_t csr = ((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrsi"), - fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm)); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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 rd = ((bit_sub<7,5>(instr))); + uint8_t zimm = ((bit_sub<15,5>(instr))); + uint16_t csr = ((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrsi"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm)); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 { - 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; - } - - } catch(...){} - TRAP_CSRRSI:break; - }// @suppress("No break at end of case") + uint32_t read_res = super::template read_mem(traits::CSR, csr); + if(this->core.trap_state) goto TRAP_CSRRSI; + uint32_t xrd = read_res; + 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; + } + } + 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))); - uint16_t csr = ((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrci"), - fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm)); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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 rd = ((bit_sub<7,5>(instr))); + uint8_t zimm = ((bit_sub<15,5>(instr))); + uint16_t csr = ((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrci"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm)); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 { - 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; - } - - } catch(...){} - TRAP_CSRRCI:break; - }// @suppress("No break at end of case") + uint32_t read_res = super::template read_mem(traits::CSR, csr); + if(this->core.trap_state) goto TRAP_CSRRCI; + uint32_t xrd = read_res; + 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; + } + } + 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))); - uint16_t imm = ((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {rd}, {imm}", fmt::arg("mnemonic", "fence_i"), - fmt::arg("rs1", name(rs1)), fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers// calculate next pc value - *NEXT_PC = *PC + 4; - // execute instruction - try { - writeSpace2(traits::FENCE, traits::fencei, imm); - - } catch(...){} - TRAP_FENCE_I:break; - }// @suppress("No break at end of case") + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint16_t imm = ((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rd}, {imm}", fmt::arg("mnemonic", "fence_i"), + fmt::arg("rs1", name(rs1)), fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + this->core.disass_output(pc.val, mnemonic); + } + // used registers// calculate next pc value + *NEXT_PC = *PC + 4; + // execute instruction + { + 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))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mul"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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 rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mul"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 { - 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(...){} - TRAP_MUL:break; - }// @suppress("No break at end of case") + 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; + } + } + 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))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mulh"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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 rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mulh"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 { - 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(...){} - TRAP_MULH:break; - }// @suppress("No break at end of case") + 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); + } + } + 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))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mulhsu"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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 rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mulhsu"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 { - 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(...){} - TRAP_MULHSU:break; - }// @suppress("No break at end of case") + 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); + } + } + 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))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mulhu"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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 rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mulhu"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 { - 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(...){} - TRAP_MULHU:break; - }// @suppress("No break at end of case") + 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); + } + } + 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))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "div"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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 rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "div"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 { - 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); - } - else *(X+rd % traits::RFS) = - 1; - } - } - - } catch(...){} - TRAP_DIV:break; - }// @suppress("No break at end of case") + 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); + } + } + else { + *(X+rd % traits::RFS) = - 1; + } + } + } + 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))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "divu"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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 rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "divu"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 { - 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; - } - } - - } catch(...){} - TRAP_DIVU:break; - }// @suppress("No break at end of case") + 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; + } + } + } + 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))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "rem"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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 rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "rem"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 { - 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); - } - else *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS); - } - } - - } catch(...){} - TRAP_REM:break; - }// @suppress("No break at end of case") + 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); + } + } + else { + *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS); + } + } + } + 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))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "remu"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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 rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "remu"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 { - 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); - } - } - - } catch(...){} - TRAP_REMU:break; - }// @suppress("No break at end of case") + 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); + } + } + } + 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)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "caddi4spn"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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(...){} - TRAP_CADDI4SPN:break; - }// @suppress("No break at end of case") + 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)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "caddi4spn"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 + { + 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)); - uint8_t rs1 = ((bit_sub<7,3>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {uimm:#05x}({rs1})", fmt::arg("mnemonic", "clw"), - fmt::arg("rd", name(8+rd)), fmt::arg("uimm", uimm), fmt::arg("rs1", name(8+rs1))); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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 = ((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)); + uint8_t rs1 = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {uimm:#05x}({rs1})", fmt::arg("mnemonic", "clw"), + fmt::arg("rd", name(8+rd)), fmt::arg("uimm", uimm), fmt::arg("rs1", name(8+rs1))); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 { - uint32_t load_address = *(X+rs1 + 8) + uimm; - *(X+rd + 8) = (int32_t)readSpace4(traits::MEM, load_address); - } - - } catch(...){} - TRAP_CLW:break; - }// @suppress("No break at end of case") + uint32_t load_address = *(X+rs1 + 8) + uimm; + uint32_t read_res = super::template read_mem(traits::MEM, load_address); + if(this->core.trap_state) goto TRAP_CLW; + *(X+rd + 8) = (int32_t)read_res; + } + 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)); - uint8_t rs1 = ((bit_sub<7,3>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs2}, {uimm:#05x}({rs1})", fmt::arg("mnemonic", "csw"), - fmt::arg("rs2", name(8+rs2)), fmt::arg("uimm", uimm), fmt::arg("rs1", name(8+rs1))); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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 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)); + uint8_t rs1 = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs2}, {uimm:#05x}({rs1})", fmt::arg("mnemonic", "csw"), + fmt::arg("rs2", name(8+rs2)), fmt::arg("uimm", uimm), fmt::arg("rs1", name(8+rs1))); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 { - uint32_t load_address = *(X+rs1 + 8) + uimm; - writeSpace4(traits::MEM, load_address, *(X+rs2 + 8)); - } - - } catch(...){} - TRAP_CSW:break; - }// @suppress("No break at end of case") + uint32_t load_address = *(X+rs1 + 8) + uimm; + super::template write_mem(traits::MEM, load_address, *(X+rs2 + 8)); + if(this->core.trap_state) goto TRAP_CSW; + } + 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))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "caddi"), - fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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(...){} - TRAP_CADDI:break; - }// @suppress("No break at end of case") + uint8_t imm = ((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); + uint8_t rs1 = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "caddi"), + fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 + { + *(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){ - /* generate console output when executing the command */ - this->core.disass_output(pc.val, "cnop"); - - } - // used registers// calculate next pc value - *NEXT_PC = *PC + 2; - // execute instruction - try { + uint8_t nzimm = ((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + this->core.disass_output(pc.val, "cnop"); + } + // used registers// calculate next pc value + *NEXT_PC = *PC + 2; + // execute instruction { - } - - } catch(...){} - TRAP_CNOP:break; - }// @suppress("No break at end of case") + } + 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){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {imm:#05x}", fmt::arg("mnemonic", "cjal"), - fmt::arg("imm", imm)); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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 { + 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){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {imm:#05x}", fmt::arg("mnemonic", "cjal"), + fmt::arg("imm", imm)); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 { - *(X+1) = *PC + 2; - pc_assign(*NEXT_PC) = *PC + (int16_t)sext<12>(imm); - } - - } catch(...){} - TRAP_CJAL:break; - }// @suppress("No break at end of case") + *(X+1) = *PC + 2; + *NEXT_PC = *PC + (int16_t)sext<12>(imm); + super::ex_info.branch_taken=true; + } + 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))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "cli"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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 imm = ((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); + uint8_t rd = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "cli"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 { - if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = (int8_t)sext<6>(imm); - } - - } catch(...){} - TRAP_CLI:break; - }// @suppress("No break at end of case") + if((rd % traits::RFS) != 0) { + *(X+rd % traits::RFS) = (int8_t)sext<6>(imm); + } + } + 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))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "clui"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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 imm = ((bit_sub<2,5>(instr) << 12) | (bit_sub<12,1>(instr) << 17)); + uint8_t rd = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "clui"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 { - if(imm == 0) raise(0, 2); - if((rd % traits::RFS) != 0) *(X+rd % traits::RFS) = (int32_t)sext<18>(imm); - } - - } catch(...){} - TRAP_CLUI:break; - }// @suppress("No break at end of case") + if(imm == 0) { + raise(0, 2); + } + if((rd % traits::RFS) != 0) { + *(X+rd % traits::RFS) = (int32_t)sext<18>(imm); + } + } + 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){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {nzimm:#05x}", fmt::arg("mnemonic", "caddi16sp"), - fmt::arg("nzimm", nzimm)); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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(...){} - TRAP_CADDI16SP:break; - }// @suppress("No break at end of case") + 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){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {nzimm:#05x}", fmt::arg("mnemonic", "caddi16sp"), + fmt::arg("nzimm", nzimm)); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 + { + 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){ - /* generate console output when executing the command */ - this->core.disass_output(pc.val, "__reserved_clui"); - - } - // used registers// calculate next pc value - *NEXT_PC = *PC + 2; - // execute instruction - try { - raise(0, 2); - - } catch(...){} - TRAP___reserved_clui:break; - }// @suppress("No break at end of case") + uint8_t rd = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + this->core.disass_output(pc.val, "__reserved_clui"); + } + // used registers// calculate next pc value + *NEXT_PC = *PC + 2; + // execute instruction + { + 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))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {shamt}", fmt::arg("mnemonic", "csrli"), - fmt::arg("rs1", name(8+rs1)), fmt::arg("shamt", shamt)); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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 shamt = ((bit_sub<2,5>(instr))); + uint8_t rs1 = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {shamt}", fmt::arg("mnemonic", "csrli"), + fmt::arg("rs1", name(8+rs1)), fmt::arg("shamt", shamt)); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 { - uint8_t rs1_idx = rs1 + 8; - *(X+rs1_idx) = *(X+rs1_idx) >> shamt; - } - - } catch(...){} - TRAP_CSRLI:break; - }// @suppress("No break at end of case") + uint8_t rs1_idx = rs1 + 8; + *(X+rs1_idx) = *(X+rs1_idx) >> shamt; + } + 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))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {shamt}", fmt::arg("mnemonic", "csrai"), - fmt::arg("rs1", name(8+rs1)), fmt::arg("shamt", shamt)); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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(...){} - TRAP_CSRAI:break; - }// @suppress("No break at end of case") + uint8_t shamt = ((bit_sub<2,5>(instr))); + uint8_t rs1 = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {shamt}", fmt::arg("mnemonic", "csrai"), + fmt::arg("rs1", name(8+rs1)), fmt::arg("shamt", shamt)); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 + { + 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))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "candi"), - fmt::arg("rs1", name(8+rs1)), fmt::arg("imm", imm)); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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 imm = ((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); + uint8_t rs1 = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "candi"), + fmt::arg("rs1", name(8+rs1)), fmt::arg("imm", imm)); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 { - uint8_t rs1_idx = rs1 + 8; - *(X+rs1_idx) = *(X+rs1_idx) & (int8_t)sext<6>(imm); - } - - } catch(...){} - TRAP_CANDI:break; - }// @suppress("No break at end of case") + uint8_t rs1_idx = rs1 + 8; + *(X+rs1_idx) = *(X+rs1_idx) & (int8_t)sext<6>(imm); + } + 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))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "csub"), - fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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 rs2 = ((bit_sub<2,3>(instr))); + uint8_t rd = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "csub"), + fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 { - uint8_t rd_idx = rd + 8; - *(X+rd_idx) = *(X+rd_idx) - *(X+rs2 + 8); - } - - } catch(...){} - TRAP_CSUB:break; - }// @suppress("No break at end of case") + uint8_t rd_idx = rd + 8; + *(X+rd_idx) = *(X+rd_idx) - *(X+rs2 + 8); + } + 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))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "cxor"), - fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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 rs2 = ((bit_sub<2,3>(instr))); + uint8_t rd = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "cxor"), + fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 { - uint8_t rd_idx = rd + 8; - *(X+rd_idx) = *(X+rd_idx) ^ *(X+rs2 + 8); - } - - } catch(...){} - TRAP_CXOR:break; - }// @suppress("No break at end of case") + uint8_t rd_idx = rd + 8; + *(X+rd_idx) = *(X+rd_idx) ^ *(X+rs2 + 8); + } + 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))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "cor"), - fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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 rs2 = ((bit_sub<2,3>(instr))); + uint8_t rd = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "cor"), + fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 { - uint8_t rd_idx = rd + 8; - *(X+rd_idx) = *(X+rd_idx) | *(X+rs2 + 8); - } - - } catch(...){} - TRAP_COR:break; - }// @suppress("No break at end of case") + uint8_t rd_idx = rd + 8; + *(X+rd_idx) = *(X+rd_idx) | *(X+rs2 + 8); + } + 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))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "cand"), - fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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 rs2 = ((bit_sub<2,3>(instr))); + uint8_t rd = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "cand"), + fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 { - uint8_t rd_idx = rd + 8; - *(X+rd_idx) = *(X+rd_idx) & *(X+rs2 + 8); - } - - } catch(...){} - TRAP_CAND:break; - }// @suppress("No break at end of case") + uint8_t rd_idx = rd + 8; + *(X+rd_idx) = *(X+rd_idx) & *(X+rs2 + 8); + } + 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){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {imm:#05x}", fmt::arg("mnemonic", "cj"), - fmt::arg("imm", imm)); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers// calculate next pc value - *NEXT_PC = *PC + 2; - // execute instruction - try { - pc_assign(*NEXT_PC) = *PC + (int16_t)sext<12>(imm); - - } catch(...){} - TRAP_CJ:break; - }// @suppress("No break at end of case") + 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){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {imm:#05x}", fmt::arg("mnemonic", "cj"), + fmt::arg("imm", imm)); + this->core.disass_output(pc.val, mnemonic); + } + // used registers// calculate next pc value + *NEXT_PC = *PC + 2; + // execute instruction + { + *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))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "cbeqz"), - fmt::arg("rs1", name(8+rs1)), fmt::arg("imm", imm)); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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(...){} - TRAP_CBEQZ:break; - }// @suppress("No break at end of case") + 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))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "cbeqz"), + fmt::arg("rs1", name(8+rs1)), fmt::arg("imm", imm)); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 + { + 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))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "cbnez"), - fmt::arg("rs1", name(8+rs1)), fmt::arg("imm", imm)); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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(...){} - TRAP_CBNEZ:break; - }// @suppress("No break at end of case") + 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))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "cbnez"), + fmt::arg("rs1", name(8+rs1)), fmt::arg("imm", imm)); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 + { + 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))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {nzuimm}", fmt::arg("mnemonic", "cslli"), - fmt::arg("rs1", name(rs1)), fmt::arg("nzuimm", nzuimm)); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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(...){} - TRAP_CSLLI:break; - }// @suppress("No break at end of case") + uint8_t nzuimm = ((bit_sub<2,5>(instr))); + uint8_t rs1 = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {nzuimm}", fmt::arg("mnemonic", "cslli"), + fmt::arg("rs1", name(rs1)), fmt::arg("nzuimm", nzuimm)); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 + { + 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))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, sp, {uimm:#05x}", fmt::arg("mnemonic", "clwsp"), - fmt::arg("rd", name(rd)), fmt::arg("uimm", uimm)); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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(...){} - TRAP_CLWSP:break; - }// @suppress("No break at end of case") + 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))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, sp, {uimm:#05x}", fmt::arg("mnemonic", "clwsp"), + fmt::arg("rd", name(rd)), fmt::arg("uimm", uimm)); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 + { + if(rd) { + uint32_t offs = *(X+2) + uimm; + uint32_t read_res = super::template read_mem(traits::MEM, offs); + if(this->core.trap_state) goto TRAP_CLWSP; + *(X+rd % traits::RFS) = (int32_t)read_res; + } + 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))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "cmv"), - fmt::arg("rd", name(rd)), fmt::arg("rs2", name(rs2))); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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(...){} - TRAP_CMV:break; - }// @suppress("No break at end of case") + uint8_t rs2 = ((bit_sub<2,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "cmv"), + fmt::arg("rd", name(rd)), fmt::arg("rs2", name(rs2))); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 + { + 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){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}", fmt::arg("mnemonic", "cjr"), - fmt::arg("rs1", name(rs1))); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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(...){} - TRAP_CJR:break; - }// @suppress("No break at end of case") + uint8_t rs1 = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}", fmt::arg("mnemonic", "cjr"), + fmt::arg("rs1", name(rs1))); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 + { + 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 */ - this->core.disass_output(pc.val, "__reserved_cmv"); - - } - // used registers// calculate next pc value - *NEXT_PC = *PC + 2; - // execute instruction - try { - raise(0, 2); - - } catch(...){} - TRAP___reserved_cmv:break; - }// @suppress("No break at end of case") + if(this->disass_enabled){ + /* generate console output when executing the command */ + this->core.disass_output(pc.val, "__reserved_cmv"); + } + // used registers// calculate next pc value + *NEXT_PC = *PC + 2; + // execute instruction + { + 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))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "cadd"), - fmt::arg("rd", name(rd)), fmt::arg("rs2", name(rs2))); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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(...){} - TRAP_CADD:break; - }// @suppress("No break at end of case") + uint8_t rs2 = ((bit_sub<2,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "cadd"), + fmt::arg("rd", name(rd)), fmt::arg("rs2", name(rs2))); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 + { + 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){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}", fmt::arg("mnemonic", "cjalr"), - fmt::arg("rs1", name(rs1))); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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 = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}", fmt::arg("mnemonic", "cjalr"), + fmt::arg("rs1", name(rs1))); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 { - int32_t new_pc = *(X+rs1 % traits::RFS); - *(X+1) = *PC + 2; - pc_assign(*NEXT_PC) = new_pc & ~ 0x1; - } - - } catch(...){} - TRAP_CJALR:break; - }// @suppress("No break at end of case") + int32_t new_pc = *(X+rs1 % traits::RFS); + *(X+1) = *PC + 2; + *NEXT_PC = new_pc & ~ 0x1; + super::ex_info.branch_taken=true; + } + 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 */ - this->core.disass_output(pc.val, "cebreak"); - - } - // used registers// calculate next pc value - *NEXT_PC = *PC + 2; - // execute instruction - try { - raise(0, 3); - - } catch(...){} - 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)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs2}, {uimm:#05x}(sp)", fmt::arg("mnemonic", "cswsp"), - fmt::arg("rs2", name(rs2)), fmt::arg("uimm", uimm)); - this->core.disass_output(pc.val, mnemonic); - - } - // used registers - 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(this->disass_enabled){ + /* generate console output when executing the command */ + this->core.disass_output(pc.val, "cebreak"); + } + // used registers// calculate next pc value + *NEXT_PC = *PC + 2; + // execute instruction { - uint32_t offs = *(X+2) + uimm; - writeSpace4(traits::MEM, offs, (uint32_t)*(X+rs2 % traits::RFS)); - } - - } catch(...){} - TRAP_CSWSP:break; - }// @suppress("No break at end of case") + 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)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs2}, {uimm:#05x}(sp)", fmt::arg("mnemonic", "cswsp"), + fmt::arg("rs2", name(rs2)), fmt::arg("uimm", uimm)); + this->core.disass_output(pc.val, mnemonic); + } + // used registers + 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 + { + uint32_t offs = *(X+2) + uimm; + super::template write_mem(traits::MEM, offs, (uint32_t)*(X+rs2 % traits::RFS)); + if(this->core.trap_state) goto TRAP_CSWSP; + } + 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 */ - this->core.disass_output(pc.val, "dii"); - - } - // used registers// calculate next pc value - *NEXT_PC = *PC + 2; - // execute instruction - try { - raise(0, 2); - - } catch(...){} - TRAP_DII:break; - }// @suppress("No break at end of case") + if(this->disass_enabled){ + /* generate console output when executing the command */ + this->core.disass_output(pc.val, "dii"); + } + // used registers// calculate next pc value + *NEXT_PC = *PC + 2; + // execute instruction + { + 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);