diff --git a/gen_input/CoreDSL-Instruction-Set-Description b/gen_input/CoreDSL-Instruction-Set-Description index ab8ac70..998444f 160000 --- a/gen_input/CoreDSL-Instruction-Set-Description +++ b/gen_input/CoreDSL-Instruction-Set-Description @@ -1 +1 @@ -Subproject commit ab8ac7045927ca1d12e0142c476cd2e146083169 +Subproject commit 998444fba8e9273fda6a4d9c89303b62129500f2 diff --git a/gen_input/TGFS.core_desc b/gen_input/TGFS.core_desc index f2d668b..c0aeb2b 100644 --- a/gen_input/TGFS.core_desc +++ b/gen_input/TGFS.core_desc @@ -24,4 +24,4 @@ Core TGF_C provides RV32I, RV32M, RV32IC { unsigned PGSIZE = 0x1000; //1 << 12; unsigned PGMASK = 0xfff; //PGSIZE-1 } -} \ No newline at end of file +} diff --git a/gen_input/templates/interp/CORENAME.cpp.gtl b/gen_input/templates/interp/CORENAME.cpp.gtl index 3e93c82..57db9ca 100644 --- a/gen_input/templates/interp/CORENAME.cpp.gtl +++ b/gen_input/templates/interp/CORENAME.cpp.gtl @@ -29,7 +29,14 @@ * POSSIBILITY OF SUCH DAMAGE. * *******************************************************************************/ - +<% +def getRegisterSizes(){ + def regs = registers.collect{it.size} + regs[-1]=64 // correct for NEXT_PC + regs+=[32, 32, 32, 32, 64] // append TRAP_STATE, PENDING_TRAP, MACHINE_STATE, LAST_BRANCH, ICOUNT + return regs +} +%> #include "util/ities.h" #include #include @@ -41,8 +48,8 @@ using namespace iss::arch; constexpr std::array iss::arch::traits::reg_names; constexpr std::array iss::arch::traits::reg_aliases; -constexpr std::array iss::arch::traits::reg_bit_widths; -constexpr std::array iss::arch::traits::reg_byte_offsets; +constexpr std::array iss::arch::traits::reg_bit_widths; +constexpr std::array iss::arch::traits::reg_byte_offsets; ${coreDef.name.toLowerCase()}::${coreDef.name.toLowerCase()}() { reg.icount = 0; diff --git a/gen_input/templates/interp/CORENAME.h.gtl b/gen_input/templates/interp/CORENAME.h.gtl index df96375..67d4714 100644 --- a/gen_input/templates/interp/CORENAME.h.gtl +++ b/gen_input/templates/interp/CORENAME.h.gtl @@ -29,7 +29,24 @@ * POSSIBILITY OF SUCH DAMAGE. * *******************************************************************************/ - +<% +def getRegisterSizes(){ + def regs = registers.collect{it.size} + regs[-1]=pc.size // correct for NEXT_PC + regs+=[32, 32, 32, 32, 64] // append TRAP_STATE, PENDING_TRAP, MACHINE_STATE, LAST_BRANCH, ICOUNT + return regs +} +def getRegisterOffsets(){ + def regs = registers.collect{it.offset} + def offs= regs[-1] + // append TRAP_STATE, PENDING_TRAP, MACHINE_STATE, LAST_BRANCH, ICOUNT offsets starting with NEXT_PC size + [pc.size/8, 4, 4, 4, 4].each{ sz -> + regs+=offs+sz + offs+=sz + } + return regs +} +%> #ifndef _${coreDef.name.toUpperCase()}_H_ #define _${coreDef.name.toUpperCase()}_H_ @@ -61,7 +78,6 @@ template <> struct traits<${coreDef.name.toLowerCase()}> { registers.each { reg -> %> ${reg.name},<% }%> - NUM_REGS, NEXT_${pc.name}=NUM_REGS, TRAP_STATE, PENDING_TRAP, @@ -80,11 +96,11 @@ template <> struct traits<${coreDef.name.toLowerCase()}> { using phys_addr_t = iss::typed_addr_t; - static constexpr std::array reg_bit_widths{ - {${registers.collect{it.size}.join(',')}}}; + static constexpr std::array reg_bit_widths{ + {${getRegisterSizes().join(',')}}}; - static constexpr std::array reg_byte_offsets{ - {${registers.collect{it.offset}.join(',')}}}; + static constexpr std::array reg_byte_offsets{ + {${getRegisterOffsets().join(',')}}}; static const uint64_t addr_mask = (reg_t(1) << (XLEN - 1)) | ((reg_t(1) << (XLEN - 1)) - 1); @@ -137,9 +153,9 @@ struct ${coreDef.name.toLowerCase()}: public arch_if { protected: struct ${coreDef.name}_regs {<% - registers.each { reg ->%> + registers.each { reg -> if(reg.size>0) {%> uint${reg.size}_t ${reg.name} = 0;<% - }%> + }}%> uint${pc.size}_t NEXT_${pc.name} = 0; uint32_t trap_state = 0, pending_trap = 0, machine_state = 0, last_branch = 0; uint64_t icount = 0; diff --git a/gen_input/templates/interp/vm_CORENAME.cpp.gtl b/gen_input/templates/interp/vm_CORENAME.cpp.gtl index bc9f9c2..6a3bbe6 100644 --- a/gen_input/templates/interp/vm_CORENAME.cpp.gtl +++ b/gen_input/templates/interp/vm_CORENAME.cpp.gtl @@ -185,27 +185,32 @@ private: /* instruction definitions */<%instructions.eachWithIndex{instr, idx -> %> /* instruction ${idx}: ${instr.name} */ compile_ret_t __${generator.functionName(instr.name)}(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, ${idx}); - <%instr.fields.eachLine{%>${it} - <%}%>if(this->disass_enabled){ - /* generate console output when executing the command */ - <%instr.disass.eachLine{%>${it} - <%}%>} - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + ${instr.length/8}; - uint${addrDataWidth}_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint${addrDataWidth}_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - <%instr.behavior.eachLine{%>${it} - <%}%>this->do_sync(POST_SYNC, ${idx}); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, ${idx}); + <%instr.fields.eachLine{%>${it} + <%}%>if(this->disass_enabled){ + /* generate console output when executing the command */ + <%instr.disass.eachLine{%>${it} + <%}%> + } + // prepare execution + uint${addrDataWidth}_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint${addrDataWidth}_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + <%instr.behavior.eachLine{%>${it} + <%}%>// post execution stuff<% if(instr.modifiesPC) { %> + super::template get_reg(arch::traits::NEXT_PC) = super::template get_reg(arch::traits::PC);<% } else { %> + super::template get_reg(arch::traits::NEXT_PC) = pc.val + ${instr.length/8};<% } %> + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, ${idx}); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } <%}%> /**************************************************************************** diff --git a/incl/iss/arch/tgf_c.h b/incl/iss/arch/tgf_c.h index d1db620..042dedb 100644 --- a/incl/iss/arch/tgf_c.h +++ b/incl/iss/arch/tgf_c.h @@ -47,11 +47,11 @@ template <> struct traits { constexpr static char const* const core_type = "TGF_C"; - static constexpr std::array reg_names{ - {"X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "X10", "X11", "X12", "X13", "X14", "X15", "X16", "X17", "X18", "X19", "X20", "X21", "X22", "X23", "X24", "X25", "X26", "X27", "X28", "X29", "X30", "X31", "PC"}}; + static constexpr std::array reg_names{ + {"X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "X10", "X11", "X12", "X13", "X14", "X15", "X16", "X17", "X18", "X19", "X20", "X21", "X22", "X23", "X24", "X25", "X26", "X27", "X28", "X29", "X30", "X31", "PC", "NUM_REGS"}}; - static constexpr std::array reg_aliases{ - {"ZERO", "RA", "SP", "GP", "TP", "T0", "T1", "T2", "S0", "S1", "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "S2", "S3", "S4", "S5", "S6", "S7", "S8", "S9", "S10", "S11", "T3", "T4", "T5", "T6", "PC"}}; + static constexpr std::array reg_aliases{ + {"X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "X10", "X11", "X12", "X13", "X14", "X15", "X16", "X17", "X18", "X19", "X20", "X21", "X22", "X23", "X24", "X25", "X26", "X27", "X28", "X29", "X30", "X31", "PC", "NUM_REGS"}}; enum constants {XLEN=32, PCLEN=32, MISA_VAL=0b1000000000000000001000100000100, PGSIZE=0x1000, PGMASK=0xfff, CSR_SIZE=4096, fence=0, fencei=1, fencevmal=2, fencevmau=3, MUL_LEN=64}; @@ -110,11 +110,11 @@ template <> struct traits { using phys_addr_t = iss::typed_addr_t; - static constexpr std::array reg_bit_widths{ - {32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32}}; + static constexpr std::array reg_bit_widths{ + {32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,64}}; - static constexpr std::array reg_byte_offsets{ - {0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128}}; + static constexpr std::array reg_byte_offsets{ + {0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,132,136,140,144,148,152}}; static const uint64_t addr_mask = (reg_t(1) << (XLEN - 1)) | ((reg_t(1) << (XLEN - 1)) - 1); diff --git a/src/iss/tgf_c.cpp b/src/iss/tgf_c.cpp index a035dbe..dd8c15a 100644 --- a/src/iss/tgf_c.cpp +++ b/src/iss/tgf_c.cpp @@ -39,10 +39,10 @@ using namespace iss::arch; -constexpr std::array iss::arch::traits::reg_names; -constexpr std::array iss::arch::traits::reg_aliases; -constexpr std::array iss::arch::traits::reg_bit_widths; -constexpr std::array iss::arch::traits::reg_byte_offsets; +constexpr std::array iss::arch::traits::reg_names; +constexpr std::array iss::arch::traits::reg_aliases; +constexpr std::array iss::arch::traits::reg_bit_widths; +constexpr std::array iss::arch::traits::reg_byte_offsets; tgf_c::tgf_c() { reg.icount = 0; diff --git a/src/main.cpp b/src/main.cpp index b44af9f..64d8ca5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -83,7 +83,7 @@ int main(int argc, char *argv[]) { ("elf", po::value>(), "ELF file(s) to load") ("mem,m", po::value(), "the memory input file") ("plugin,p", po::value>(), "plugin to activate") - ("backend", po::value()->default_value("tcc"), "the memory input file") + ("backend", po::value()->default_value("interp"), "the memory input file") ("isa", po::value()->default_value("tgf_c"), "isa to use for simulation"); // clang-format on auto parsed = po::command_line_parser(argc, argv).options(desc).allow_unregistered().run(); diff --git a/src/vm/interp/vm_tgf_c.cpp b/src/vm/interp/vm_tgf_c.cpp index 0d79d87..77bcda8 100644 --- a/src/vm/interp/vm_tgf_c.cpp +++ b/src/vm/interp/vm_tgf_c.cpp @@ -359,2705 +359,3057 @@ private: /* instruction definitions */ /* instruction 0: LUI */ compile_ret_t __lui(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 0); - uint8_t rd = ((bit_sub<7,5>(instr))); - int32_t imm = signextend((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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - if(rd != 0) *(X+(rd)) = imm; - this->do_sync(POST_SYNC, 0); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 0); + uint8_t rd = ((bit_sub<7,5>(instr))); + int32_t imm = signextend((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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + if(rd != 0) *(X+rd) = imm; + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 0); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 1: AUIPC */ compile_ret_t __auipc(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 1); - uint8_t rd = ((bit_sub<7,5>(instr))); - int32_t imm = signextend((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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - if(rd != 0) *(X+(rd)) = *PC + imm; - this->do_sync(POST_SYNC, 1); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 1); + uint8_t rd = ((bit_sub<7,5>(instr))); + int32_t imm = signextend((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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + if(rd != 0) *(X+rd) = *PC + imm; + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 1); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 2: JAL */ compile_ret_t __jal(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 2); - uint8_t rd = ((bit_sub<7,5>(instr))); - int32_t imm = signextend((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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - { - if(rd != 0) *(X+(rd)) = *PC + 4; - *PC = *PC + imm; - } - this->do_sync(POST_SYNC, 2); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 2); + uint8_t rd = ((bit_sub<7,5>(instr))); + int32_t imm = signextend((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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + { + if(rd != 0) *(X+rd) = *PC + 4; + *PC = *PC + imm; + } + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = super::template get_reg(arch::traits::PC); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 2); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 3: JALR */ compile_ret_t __jalr(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 3); - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - int16_t imm = signextend((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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - { - int32_t new_pc = *(X+(rs1)) + imm; - if(rd != 0) *(X+(rd)) = *PC + 4; - *PC = new_pc & ~ 0x1; - } - this->do_sync(POST_SYNC, 3); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 3); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + { + int32_t new_pc = *(X+rs1) + imm; + if(rd != 0) *(X+rd) = *PC + 4; + *PC = new_pc & ~ 0x1; + } + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = super::template get_reg(arch::traits::PC); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 3); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 4: BEQ */ compile_ret_t __beq(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 4); - int16_t imm = signextend((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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - *PC = *(X+(rs1)) == *(X+(rs2))? *PC + imm : *PC + 4; - this->do_sync(POST_SYNC, 4); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 4); + int16_t imm = signextend((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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + *PC = *(X+rs1) == *(X+rs2)? *PC + imm : *PC + 4; + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = super::template get_reg(arch::traits::PC); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 4); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 5: BNE */ compile_ret_t __bne(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 5); - int16_t imm = signextend((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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - *PC = *(X+(rs1)) != *(X+(rs2))? *PC + imm : *PC + 4; - this->do_sync(POST_SYNC, 5); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 5); + int16_t imm = signextend((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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + *PC = *(X+rs1) != *(X+rs2)? *PC + imm : *PC + 4; + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = super::template get_reg(arch::traits::PC); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 5); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 6: BLT */ compile_ret_t __blt(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 6); - int16_t imm = signextend((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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - *PC = *(X+(rs1)) < *(X+(rs2))? *PC + imm : *PC + 4; - this->do_sync(POST_SYNC, 6); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 6); + int16_t imm = signextend((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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + *PC = *(X+rs1) < *(X+rs2)? *PC + imm : *PC + 4; + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = super::template get_reg(arch::traits::PC); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 6); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 7: BGE */ compile_ret_t __bge(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 7); - int16_t imm = signextend((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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - *PC = *(X+(rs1)) >= *(X+(rs2))? *PC + imm : *PC + 4; - this->do_sync(POST_SYNC, 7); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 7); + int16_t imm = signextend((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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + *PC = *(X+rs1) >= *(X+rs2)? *PC + imm : *PC + 4; + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = super::template get_reg(arch::traits::PC); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 7); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 8: BLTU */ compile_ret_t __bltu(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 8); - int16_t imm = signextend((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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - *PC = *(X+(rs1)) < *(X+(rs2))? *PC + imm : *PC + 4; - this->do_sync(POST_SYNC, 8); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 8); + int16_t imm = signextend((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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + *PC = *(X+rs1) < *(X+rs2)? *PC + imm : *PC + 4; + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = super::template get_reg(arch::traits::PC); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 8); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 9: BGEU */ compile_ret_t __bgeu(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 9); - int16_t imm = signextend((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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - *PC = *(X+(rs1)) >= *(X+(rs2))? *PC + imm : *PC + 4; - this->do_sync(POST_SYNC, 9); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 9); + int16_t imm = signextend((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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + *PC = *(X+rs1) >= *(X+rs2)? *PC + imm : *PC + 4; + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = super::template get_reg(arch::traits::PC); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 9); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 10: LB */ compile_ret_t __lb(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 10); - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - int16_t imm = signextend((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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - if(rd != 0) *(X+(rd)) = readSpace4(traits::MEM, *(X+(rs1)) + imm); - this->do_sync(POST_SYNC, 10); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 10); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + if(rd != 0) *(X+rd) = readSpace1(traits::MEM, *(X+rs1) + imm); + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 10); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 11: LH */ compile_ret_t __lh(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 11); - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - int16_t imm = signextend((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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - if(rd != 0) *(X+(rd)) = (short)readSpace2(traits::MEM, *(X+(rs1)) + imm); - this->do_sync(POST_SYNC, 11); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 11); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + if(rd != 0) *(X+rd) = (int16_t)readSpace2(traits::MEM, *(X+rs1) + imm); + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 11); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 12: LW */ compile_ret_t __lw(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 12); - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - int16_t imm = signextend((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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - if(rd != 0) *(X+(rd)) = (int)readSpace4(traits::MEM, *(X+(rs1)) + imm); - this->do_sync(POST_SYNC, 12); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 12); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + if(rd != 0) *(X+rd) = (int32_t)readSpace4(traits::MEM, *(X+rs1) + imm); + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 12); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 13: LBU */ compile_ret_t __lbu(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 13); - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - int16_t imm = signextend((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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - if(rd != 0) *(X+(rd)) = (unsigned char)readSpace1(traits::MEM, *(X+(rs1)) + imm); - this->do_sync(POST_SYNC, 13); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 13); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + if(rd != 0) *(X+rd) = (uint8_t)readSpace1(traits::MEM, *(X+rs1) + imm); + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 13); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 14: LHU */ compile_ret_t __lhu(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 14); - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - int16_t imm = signextend((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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - if(rd != 0) *(X+(rd)) = (unsigned short)readSpace2(traits::MEM, *(X+(rs1)) + imm); - this->do_sync(POST_SYNC, 14); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 14); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + if(rd != 0) *(X+rd) = (uint16_t)readSpace2(traits::MEM, *(X+rs1) + imm); + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 14); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 15: SB */ compile_ret_t __sb(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 15); - int16_t imm = signextend((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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - writeSpace1(traits::MEM, *(X+(rs1)) + imm, (char)*(X+(rs2))); - this->do_sync(POST_SYNC, 15); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 15); + int16_t imm = signextend((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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + writeSpace1(traits::MEM, *(X+rs1) + imm, (int8_t)*(X+rs2)); + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 15); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 16: SH */ compile_ret_t __sh(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 16); - int16_t imm = signextend((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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - writeSpace2(traits::MEM, *(X+(rs1)) + imm, (short)*(X+(rs2))); - this->do_sync(POST_SYNC, 16); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 16); + int16_t imm = signextend((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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + writeSpace2(traits::MEM, *(X+rs1) + imm, (int16_t)*(X+rs2)); + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 16); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 17: SW */ compile_ret_t __sw(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 17); - int16_t imm = signextend((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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - writeSpace4(traits::MEM, *(X+(rs1)) + imm, *(X+(rs2))); - this->do_sync(POST_SYNC, 17); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 17); + int16_t imm = signextend((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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + writeSpace4(traits::MEM, *(X+rs1) + imm, *(X+rs2)); + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 17); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 18: ADDI */ compile_ret_t __addi(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 18); - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - int16_t imm = signextend((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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - if(rd != 0) *(X+(rd)) = *(X+(rs1)) + imm; - this->do_sync(POST_SYNC, 18); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 18); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + if(rd != 0) *(X+rd) = *(X+rs1) + imm; + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 18); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 19: SLTI */ compile_ret_t __slti(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 19); - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - int16_t imm = signextend((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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - if(rd != 0) *(X+(rd)) = *(X+(rs1)) < imm? 1 : 0; - this->do_sync(POST_SYNC, 19); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 19); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + if(rd != 0) *(X+rd) = *(X+rs1) < imm? 1 : 0; + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 19); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 20: SLTIU */ compile_ret_t __sltiu(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 20); - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - int16_t imm = signextend((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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - if(rd != 0) *(X+(rd)) = (unsigned)*(X+(rs1)) < (unsigned)(int)imm? 1 : 0; - this->do_sync(POST_SYNC, 20); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 20); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + if(rd != 0) *(X+rd) = (uint8_t)*(X+rs1) < (uint8_t)(int32_t)imm? 1 : 0; + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 20); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 21: XORI */ compile_ret_t __xori(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 21); - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - int16_t imm = signextend((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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - if(rd != 0) *(X+(rd)) = *(X+(rs1)) ^ imm; - this->do_sync(POST_SYNC, 21); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 21); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + if(rd != 0) *(X+rd) = *(X+rs1) ^ imm; + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 21); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 22: ORI */ compile_ret_t __ori(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 22); - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - int16_t imm = signextend((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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - if(rd != 0) *(X+(rd)) = *(X+(rs1)) | imm; - this->do_sync(POST_SYNC, 22); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 22); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + if(rd != 0) *(X+rd) = *(X+rs1) | imm; + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 22); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 23: ANDI */ compile_ret_t __andi(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 23); - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - int16_t imm = signextend((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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - if(rd != 0) *(X+(rd)) = *(X+(rs1)) & imm; - this->do_sync(POST_SYNC, 23); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 23); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + if(rd != 0) *(X+rd) = *(X+rs1) & imm; + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 23); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 24: SLLI */ compile_ret_t __slli(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 24); - 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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - if(shamt > 31) { - raise(0, 0); - } - else { - if(rd != 0) *(X+(rd)) = *(X+(rs1)) << shamt; - } - this->do_sync(POST_SYNC, 24); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 24); + 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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + if(shamt > 31) { + raise(0, 0); + } + else { + if(rd != 0) *(X+rd) = *(X+rs1) << shamt; + } + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 24); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 25: SRLI */ compile_ret_t __srli(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 25); - 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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - if(shamt > 31) { - raise(0, 0); - } - else { - if(rd != 0) *(X+(rd)) = ((unsigned)*(X+(rs1))) >> shamt; - } - this->do_sync(POST_SYNC, 25); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 25); + 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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + if(shamt > 31) { + raise(0, 0); + } + else { + if(rd != 0) *(X+rd) = ((uint8_t)*(X+rs1)) >> shamt; + } + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 25); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 26: SRAI */ compile_ret_t __srai(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 26); - 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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - if(shamt > 31) { - raise(0, 0); - } - else { - if(rd != 0) *(X+(rd)) = *(X+(rs1)) >> shamt; - } - this->do_sync(POST_SYNC, 26); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 26); + 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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + if(shamt > 31) { + raise(0, 0); + } + else { + if(rd != 0) *(X+rd) = *(X+rs1) >> shamt; + } + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 26); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 27: ADD */ compile_ret_t __add(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 27); - 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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - if(rd != 0) *(X+(rd)) = *(X+(rs1)) + *(X+(rs2)); - this->do_sync(POST_SYNC, 27); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 27); + 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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + if(rd != 0) *(X+rd) = *(X+rs1) + *(X+rs2); + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 27); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 28: SUB */ compile_ret_t __sub(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 28); - 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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - if(rd != 0) *(X+(rd)) = *(X+(rs1)) - *(X+(rs2)); - this->do_sync(POST_SYNC, 28); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 28); + 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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + if(rd != 0) *(X+rd) = *(X+rs1) - *(X+rs2); + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 28); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 29: SLL */ compile_ret_t __sll(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 29); - 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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - if(rd != 0) *(X+(rd)) = *(X+(rs1)) << (*(X+(rs2)) & (traits::XLEN - 1)); - this->do_sync(POST_SYNC, 29); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 29); + 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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + if(rd != 0) *(X+rd) = *(X+rs1) << (*(X+rs2) & (traits::XLEN - 1)); + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 29); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 30: SLT */ compile_ret_t __slt(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 30); - 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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - if(rd != 0) *(X+(rd)) = *(X+(rs1)) < *(X+(rs2))? 1 : 0; - this->do_sync(POST_SYNC, 30); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 30); + 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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + if(rd != 0) *(X+rd) = *(X+rs1) < *(X+rs2)? 1 : 0; + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 30); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 31: SLTU */ compile_ret_t __sltu(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 31); - 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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - if(rd != 0) *(X+(rd)) = (uint32_t)*(X+(rs1)) < (uint32_t)*(X+(rs2))? 1 : 0; - this->do_sync(POST_SYNC, 31); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 31); + 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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + if(rd != 0) *(X+rd) = (uint32_t)*(X+rs1) < (uint32_t)*(X+rs2)? 1 : 0; + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 31); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 32: XOR */ compile_ret_t __xor(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 32); - 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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - if(rd != 0) *(X+(rd)) = *(X+(rs1)) ^ *(X+(rs2)); - this->do_sync(POST_SYNC, 32); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 32); + 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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + if(rd != 0) *(X+rd) = *(X+rs1) ^ *(X+rs2); + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 32); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 33: SRL */ compile_ret_t __srl(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 33); - 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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - if(rd != 0) *(X+(rd)) = *(X+(rs1)) << (*(X+(rs2)) & (traits::XLEN - 1)); - this->do_sync(POST_SYNC, 33); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 33); + 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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + if(rd != 0) *(X+rd) = *(X+rs1) << (*(X+rs2) & (traits::XLEN - 1)); + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 33); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 34: SRA */ compile_ret_t __sra(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 34); - 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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - if(rd != 0) *(X+(rd)) = *(X+(rs1)) >> (*(X+(rs2)) & (traits::XLEN - 1)); - this->do_sync(POST_SYNC, 34); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 34); + 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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + if(rd != 0) *(X+rd) = *(X+rs1) >> (*(X+rs2) & (traits::XLEN - 1)); + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 34); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 35: OR */ compile_ret_t __or(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 35); - 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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - if(rd != 0) *(X+(rd)) = *(X+(rs1)) | *(X+(rs2)); - this->do_sync(POST_SYNC, 35); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 35); + 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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + if(rd != 0) *(X+rd) = *(X+rs1) | *(X+rs2); + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 35); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 36: AND */ compile_ret_t __and(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 36); - 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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - if(rd != 0) *(X+(rd)) = *(X+(rs1)) & *(X+(rs2)); - this->do_sync(POST_SYNC, 36); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 36); + 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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + if(rd != 0) *(X+rd) = *(X+rs1) & *(X+rs2); + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 36); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 37: FENCE */ compile_ret_t __fence(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 37); - 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))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - this->core.disass_output(pc.val, "fence"); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - writeSpace4(traits::FENCE, traits::fence, pred << 4 | succ); - this->do_sync(POST_SYNC, 37); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 37); + 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))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + this->core.disass_output(pc.val, "fence"); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + writeSpace1(traits::FENCE, traits::fence, pred << 4 | succ); + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 37); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 38: FENCE_I */ compile_ret_t __fence_i(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 38); - 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 */ - this->core.disass_output(pc.val, "fence_i"); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - writeSpace2(traits::FENCE, traits::fencei, imm); - this->do_sync(POST_SYNC, 38); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 38); + 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 */ + this->core.disass_output(pc.val, "fence_i"); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + writeSpace2(traits::FENCE, traits::fencei, imm); + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 38); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 39: ECALL */ compile_ret_t __ecall(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 39); - if(this->disass_enabled){ - /* generate console output when executing the command */ - this->core.disass_output(pc.val, "ecall"); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - raise(0, 11); - this->do_sync(POST_SYNC, 39); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 39); + if(this->disass_enabled){ + /* generate console output when executing the command */ + this->core.disass_output(pc.val, "ecall"); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + raise(0, 11); + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 39); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 40: EBREAK */ compile_ret_t __ebreak(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 40); - if(this->disass_enabled){ - /* generate console output when executing the command */ - this->core.disass_output(pc.val, "ebreak"); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - raise(0, 3); - this->do_sync(POST_SYNC, 40); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 40); + if(this->disass_enabled){ + /* generate console output when executing the command */ + this->core.disass_output(pc.val, "ebreak"); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + raise(0, 3); + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 40); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 41: URET */ compile_ret_t __uret(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 41); - if(this->disass_enabled){ - /* generate console output when executing the command */ - this->core.disass_output(pc.val, "uret"); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - leave(0); - this->do_sync(POST_SYNC, 41); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 41); + if(this->disass_enabled){ + /* generate console output when executing the command */ + this->core.disass_output(pc.val, "uret"); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + leave(0); + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 41); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 42: SRET */ compile_ret_t __sret(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 42); - if(this->disass_enabled){ - /* generate console output when executing the command */ - this->core.disass_output(pc.val, "sret"); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - leave(1); - this->do_sync(POST_SYNC, 42); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 42); + if(this->disass_enabled){ + /* generate console output when executing the command */ + this->core.disass_output(pc.val, "sret"); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + leave(1); + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 42); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 43: MRET */ compile_ret_t __mret(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 43); - if(this->disass_enabled){ - /* generate console output when executing the command */ - this->core.disass_output(pc.val, "mret"); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - leave(3); - this->do_sync(POST_SYNC, 43); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 43); + if(this->disass_enabled){ + /* generate console output when executing the command */ + this->core.disass_output(pc.val, "mret"); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + leave(3); + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 43); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 44: WFI */ compile_ret_t __wfi(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 44); - if(this->disass_enabled){ - /* generate console output when executing the command */ - this->core.disass_output(pc.val, "wfi"); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - wait(1); - this->do_sync(POST_SYNC, 44); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 44); + if(this->disass_enabled){ + /* generate console output when executing the command */ + this->core.disass_output(pc.val, "wfi"); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + wait(1); + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 44); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 45: SFENCE_VMA */ compile_ret_t __sfence_vma(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 45); - 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 */ - this->core.disass_output(pc.val, "sfence_vma"); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - { - writeSpace4(traits::FENCE, traits::fencevmal, (unsigned)rs1); - writeSpace4(traits::FENCE, traits::fencevmau, (unsigned)rs2); - } - this->do_sync(POST_SYNC, 45); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 45); + 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 */ + this->core.disass_output(pc.val, "sfence_vma"); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + { + writeSpace1(traits::FENCE, traits::fencevmal, (uint8_t)rs1); + writeSpace1(traits::FENCE, traits::fencevmau, (uint8_t)rs2); + } + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 45); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 46: CSRRW */ compile_ret_t __csrrw(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 46); - 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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - { - uint32_t rs_val = *(X+(rs1)); - if(rd != 0) { - uint32_t csr_val = readSpace4(traits::CSR, csr); - writeSpace4(traits::CSR, csr, rs_val); - *(X+(rd)) = csr_val; - } - else { - writeSpace4(traits::CSR, csr, rs_val); - } - } - this->do_sync(POST_SYNC, 46); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 46); + 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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + { + uint32_t rs_val = *(X+rs1); + if(rd != 0) { + uint32_t csr_val = readSpace4(traits::CSR, csr); + writeSpace4(traits::CSR, csr, rs_val); + *(X+rd) = csr_val; + } + else { + writeSpace4(traits::CSR, csr, rs_val); + } + } + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 46); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 47: CSRRS */ compile_ret_t __csrrs(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 47); - 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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - { - uint32_t xrd = readSpace4(traits::CSR, csr); - uint32_t xrs1 = *(X+(rs1)); - if(rd != 0) *(X+(rd)) = xrd; - if(rs1 != 0) writeSpace4(traits::CSR, csr, xrd | xrs1); - } - this->do_sync(POST_SYNC, 47); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 47); + 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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + { + uint32_t xrd = readSpace4(traits::CSR, csr); + uint32_t xrs1 = *(X+rs1); + if(rd != 0) *(X+rd) = xrd; + if(rs1 != 0) writeSpace4(traits::CSR, csr, xrd | xrs1); + } + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 47); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 48: CSRRC */ compile_ret_t __csrrc(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 48); - 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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - { - uint32_t xrd = readSpace4(traits::CSR, csr); - uint32_t xrs1 = *(X+(rs1)); - if(rd != 0) *(X+(rd)) = xrd; - if(rs1 != 0) writeSpace4(traits::CSR, csr, xrd & ~ xrs1); - } - this->do_sync(POST_SYNC, 48); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 48); + 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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + { + uint32_t xrd = readSpace4(traits::CSR, csr); + uint32_t xrs1 = *(X+rs1); + if(rd != 0) *(X+rd) = xrd; + if(rs1 != 0) writeSpace4(traits::CSR, csr, xrd & ~ xrs1); + } + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 48); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 49: CSRRWI */ compile_ret_t __csrrwi(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 49); - 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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - { - if(rd != 0) *(X+(rd)) = readSpace4(traits::CSR, csr); - writeSpace4(traits::CSR, csr, (uint32_t)zimm); - } - this->do_sync(POST_SYNC, 49); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 49); + 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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + { + if(rd != 0) *(X+rd) = readSpace4(traits::CSR, csr); + writeSpace4(traits::CSR, csr, (uint32_t)zimm); + } + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 49); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 50: CSRRSI */ compile_ret_t __csrrsi(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 50); - 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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - { - uint32_t res = readSpace4(traits::CSR, csr); - if(zimm != 0) writeSpace4(traits::CSR, csr, res | (uint32_t)zimm); - if(rd != 0) *(X+(rd)) = res; - } - this->do_sync(POST_SYNC, 50); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 50); + 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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + { + uint32_t res = readSpace4(traits::CSR, csr); + if(zimm != 0) writeSpace4(traits::CSR, csr, res | (uint32_t)zimm); + if(rd != 0) *(X+rd) = res; + } + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 50); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 51: CSRRCI */ compile_ret_t __csrrci(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 51); - 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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - { - uint32_t res = readSpace4(traits::CSR, csr); - if(rd != 0) *(X+(rd)) = res; - if(zimm != 0) writeSpace4(traits::CSR, csr, res & ~ ((uint32_t)zimm)); - } - this->do_sync(POST_SYNC, 51); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 51); + 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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + { + uint32_t res = readSpace4(traits::CSR, csr); + if(rd != 0) *(X+rd) = res; + if(zimm != 0) writeSpace4(traits::CSR, csr, res & ~ ((uint32_t)zimm)); + } + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 51); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 52: MUL */ compile_ret_t __mul(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 52); - 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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - { - if(rd != 0) { - int64_t res = (int64_t)*(X+(rs1)) * (int64_t)*(X+(rs2)); - *(X+(rd)) = (uint32_t)res; - } - } - this->do_sync(POST_SYNC, 52); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 52); + 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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + { + if(rd != 0) { + int64_t res = (int64_t)*(X+rs1) * (int64_t)*(X+rs2); + *(X+rd) = (uint32_t)res; + } + } + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 52); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 53: MULH */ compile_ret_t __mulh(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 53); - 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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - { - if(rd != 0) { - int64_t res = (int64_t)*(X+(rs1)) * (int64_t)*(X+(rs2)); - *(X+(rd)) = (uint32_t)(res >> traits::XLEN); - } - } - this->do_sync(POST_SYNC, 53); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 53); + 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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + { + if(rd != 0) { + int64_t res = (int64_t)*(X+rs1) * (int64_t)*(X+rs2); + *(X+rd) = (uint32_t)(res >> traits::XLEN); + } + } + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 53); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 54: MULHSU */ compile_ret_t __mulhsu(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 54); - 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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - { - if(rd != 0) { - int64_t res = (int64_t)*(X+(rs1)) * (uint64_t)*(X+(rs2)); - *(X+(rd)) = (uint32_t)res; - } - } - this->do_sync(POST_SYNC, 54); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 54); + 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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + { + if(rd != 0) { + int64_t res = (int64_t)*(X+rs1) * (uint64_t)*(X+rs2); + *(X+rd) = (uint32_t)res; + } + } + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 54); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 55: MULHU */ compile_ret_t __mulhu(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 55); - 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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - { - if(rd != 0) { - uint64_t res = (uint64_t)*(X+(rs1)) * (uint64_t)*(X+(rs2)); - *(X+(rd)) = (uint32_t)res; - } - } - this->do_sync(POST_SYNC, 55); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 55); + 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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + { + if(rd != 0) { + uint64_t res = (uint64_t)*(X+rs1) * (uint64_t)*(X+rs2); + *(X+rd) = (uint32_t)res; + } + } + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 55); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 56: DIV */ compile_ret_t __div(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 56); - 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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - { - if(rd != 0) { - if(*(X+(rs2)) != 0) { - uint32_t MMIN = 1 << (traits::XLEN - 1); - if(*(X+(rs1)) == MMIN && (signed)*(X+(rs2)) == - 1) *(X+(rd)) = MMIN; - else *(X+(rd)) = (signed)*(X+(rs1)) / (signed)*(X+(rs2)); - } - else *(X+(rd)) = - 1; - } - } - this->do_sync(POST_SYNC, 56); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 56); + 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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + { + if(rd != 0) { + if(*(X+rs2) != 0) { + uint32_t MMIN = 1 << (traits::XLEN - 1); + if(*(X+rs1) == MMIN && (int8_t)*(X+rs2) == - 1) *(X+rd) = MMIN; + else *(X+rd) = (int8_t)*(X+rs1) / (int8_t)*(X+rs2); + } + else *(X+rd) = - 1; + } + } + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 56); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 57: DIVU */ compile_ret_t __divu(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 57); - 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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - { - if(rd != 0) { - if(*(X+(rs2)) != 0) *(X+(rd)) = *(X+(rs1)) / *(X+(rs2)); - else *(X+(rd)) = - 1; - } - } - this->do_sync(POST_SYNC, 57); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 57); + 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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + { + if(rd != 0) { + if(*(X+rs2) != 0) *(X+rd) = *(X+rs1) / *(X+rs2); + else *(X+rd) = - 1; + } + } + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 57); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 58: REM */ compile_ret_t __rem(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 58); - 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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - { - if(rd != 0) { - if(*(X+(rs2)) != 0) { - uint32_t MMIN = 1 << (traits::XLEN - 1); - if(*(X+(rs1)) == MMIN && *(X+(rs2)) == - 1) *(X+(rd)) = 0; - else *(X+(rd)) = (signed)*(X+(rs1)) % (signed)*(X+(rs2)); - } - else *(X+(rd)) = *(X+(rs1)); - } - } - this->do_sync(POST_SYNC, 58); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 58); + 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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + { + if(rd != 0) { + if(*(X+rs2) != 0) { + uint32_t MMIN = 1 << (traits::XLEN - 1); + if(*(X+rs1) == MMIN && *(X+rs2) == - 1) *(X+rd) = 0; + else *(X+rd) = (int8_t)*(X+rs1) % (int8_t)*(X+rs2); + } + else *(X+rd) = *(X+rs1); + } + } + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 58); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 59: REMU */ compile_ret_t __remu(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 59); - 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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 4; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - { - if(rd != 0) { - if(*(X+(rs2)) != 0) *(X+(rd)) = *(X+(rs1)) % *(X+(rs2)); - else *(X+(rd)) = *(X+(rs1)); - } - } - this->do_sync(POST_SYNC, 59); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 59); + 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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + { + if(rd != 0) { + if(*(X+rs2) != 0) *(X+rd) = *(X+rs1) % *(X+rs2); + else *(X+rd) = *(X+rs1); + } + } + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 4; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 59); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 60: CADDI4SPN */ compile_ret_t __caddi4spn(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 60); - 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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 2; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - { - if(imm == 0) raise(0, 2); - *(X+(rd + 8)) = *(X+(2)) + imm; - } - this->do_sync(POST_SYNC, 60); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 60); + 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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + { + if(imm == 0) raise(0, 2); + *(X+(rd + 8)) = *(X+2) + imm; + } + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 2; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 60); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 61: CLW */ compile_ret_t __clw(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 61); - 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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 2; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - { - uint32_t offs = *(X+(rs1 + 8)) + uimm; - *(X+(rd + 8)) = (int)readSpace4(traits::MEM, offs); - } - this->do_sync(POST_SYNC, 61); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 61); + 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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + { + uint32_t offs = *(X+(rs1 + 8)) + uimm; + *(X+(rd + 8)) = (int32_t)readSpace4(traits::MEM, offs); + } + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 2; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 61); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 62: CSW */ compile_ret_t __csw(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 62); - 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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 2; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - { - unsigned offs = *(X+(rs1 + 8)) + uimm; - writeSpace4(traits::MEM, offs, *(X+(rs2 + 8))); - } - this->do_sync(POST_SYNC, 62); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 62); + 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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + { + uint8_t offs = *(X+(rs1 + 8)) + uimm; + writeSpace4(traits::MEM, offs, *(X+(rs2 + 8))); + } + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 2; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 62); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 63: CADDI */ compile_ret_t __caddi(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 63); - int8_t imm = signextend((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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 2; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - *(X+(rs1)) = (signed)*(X+(rs1)) + imm; - this->do_sync(POST_SYNC, 63); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 63); + int8_t imm = signextend((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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + *(X+rs1) = (int8_t)*(X+rs1) + imm; + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 2; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 63); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 64: CNOP */ compile_ret_t __cnop(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 64); - if(this->disass_enabled){ - /* generate console output when executing the command */ - this->core.disass_output(pc.val, "cnop"); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 2; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - { - } - this->do_sync(POST_SYNC, 64); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 64); + if(this->disass_enabled){ + /* generate console output when executing the command */ + this->core.disass_output(pc.val, "cnop"); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + { + } + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 2; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 64); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 65: CJAL */ compile_ret_t __cjal(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 65); - int16_t imm = signextend((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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 2; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - { - *(X+(1)) = *PC + 2; - *PC = (signed)*PC + imm; - } - this->do_sync(POST_SYNC, 65); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 65); + int16_t imm = signextend((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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + { + *(X+1) = *PC + 2; + *PC = (int8_t)*PC + imm; + } + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = super::template get_reg(arch::traits::PC); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 65); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 66: CLI */ compile_ret_t __cli(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 66); - int8_t imm = signextend((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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 2; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - { - if(rd == 0) raise(0, 2); - *(X+(rd)) = imm; - } - this->do_sync(POST_SYNC, 66); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 66); + int8_t imm = signextend((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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + { + if(rd == 0) raise(0, 2); + *(X+rd) = imm; + } + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 2; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 66); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 67: CLUI */ compile_ret_t __clui(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 67); - int32_t imm = signextend((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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 2; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - { - if(rd == 0) raise(0, 2); - if(imm == 0) raise(0, 2); - *(X+(rd)) = imm; - } - this->do_sync(POST_SYNC, 67); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 67); + int32_t imm = signextend((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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + { + if(rd == 0) raise(0, 2); + if(imm == 0) raise(0, 2); + *(X+rd) = imm; + } + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 2; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 67); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 68: CADDI16SP */ compile_ret_t __caddi16sp(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 68); - int16_t imm = signextend((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} {imm:#05x}", fmt::arg("mnemonic", "caddi16sp"), - fmt::arg("imm", imm)); - this->core.disass_output(pc.val, mnemonic); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 2; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - *(X+(2)) = (signed)*(X+(2)) + imm; - this->do_sync(POST_SYNC, 68); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 68); + int16_t imm = signextend((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} {imm:#05x}", fmt::arg("mnemonic", "caddi16sp"), + fmt::arg("imm", imm)); + this->core.disass_output(pc.val, mnemonic); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + *(X+2) = (int8_t)*(X+2) + imm; + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 2; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 68); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 69: CSRLI */ compile_ret_t __csrli(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 69); - 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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 2; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - { - unsigned rs1_idx = rs1 + 8; - *(X+(rs1_idx)) = *(X+(rs1_idx)) << shamt; - } - this->do_sync(POST_SYNC, 69); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 69); + 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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + { + uint8_t rs1_idx = rs1 + 8; + *(X+rs1_idx) = *(X+rs1_idx) << shamt; + } + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 2; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 69); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 70: CSRAI */ compile_ret_t __csrai(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 70); - 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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 2; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - { - unsigned rs1_idx = rs1 + 8; - *(X+(rs1_idx)) = ((signed)*(X+(rs1_idx))) >> shamt; - } - this->do_sync(POST_SYNC, 70); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 70); + 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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + { + uint8_t rs1_idx = rs1 + 8; + *(X+rs1_idx) = ((int8_t)*(X+rs1_idx)) >> shamt; + } + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 2; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 70); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 71: CANDI */ compile_ret_t __candi(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 71); - int8_t imm = signextend((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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 2; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - { - unsigned rs1_idx = rs1 + 8; - *(X+(rs1_idx)) = *(X+(rs1_idx)) & imm; - } - this->do_sync(POST_SYNC, 71); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 71); + int8_t imm = signextend((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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + { + uint8_t rs1_idx = rs1 + 8; + *(X+rs1_idx) = *(X+rs1_idx) & imm; + } + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 2; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 71); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 72: CSUB */ compile_ret_t __csub(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 72); - 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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 2; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - { - unsigned rd_idx = rd + 8; - *(X+(rd_idx)) = *(X+(rd_idx)) - *(X+(rs2 + 8)); - } - this->do_sync(POST_SYNC, 72); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 72); + 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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + { + uint8_t rd_idx = rd + 8; + *(X+rd_idx) = *(X+rd_idx) - *(X+(rs2 + 8)); + } + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 2; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 72); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 73: CXOR */ compile_ret_t __cxor(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 73); - 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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 2; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - { - unsigned rd_idx = rd + 8; - *(X+(rd_idx)) = *(X+(rd_idx)) ^ *(X+(rs2 + 8)); - } - this->do_sync(POST_SYNC, 73); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 73); + 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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + { + uint8_t rd_idx = rd + 8; + *(X+rd_idx) = *(X+rd_idx) ^ *(X+(rs2 + 8)); + } + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 2; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 73); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 74: COR */ compile_ret_t __cor(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 74); - 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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 2; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - { - unsigned rd_idx = rd + 8; - *(X+(rd_idx)) = *(X+(rd_idx)) | *(X+(rs2 + 8)); - } - this->do_sync(POST_SYNC, 74); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 74); + 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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + { + uint8_t rd_idx = rd + 8; + *(X+rd_idx) = *(X+rd_idx) | *(X+(rs2 + 8)); + } + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 2; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 74); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 75: CAND */ compile_ret_t __cand(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 75); - 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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 2; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - { - unsigned rd_idx = rd + 8; - *(X+(rd_idx)) = *(X+(rd_idx)) & *(X+(rs2 + 8)); - } - this->do_sync(POST_SYNC, 75); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 75); + 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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + { + uint8_t rd_idx = rd + 8; + *(X+rd_idx) = *(X+rd_idx) & *(X+(rs2 + 8)); + } + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 2; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 75); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 76: CJ */ compile_ret_t __cj(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 76); - int16_t imm = signextend((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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 2; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - *PC = (signed)*PC + imm; - this->do_sync(POST_SYNC, 76); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 76); + int16_t imm = signextend((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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + *PC = (int8_t)*PC + imm; + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = super::template get_reg(arch::traits::PC); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 76); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 77: CBEQZ */ compile_ret_t __cbeqz(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 77); - int16_t imm = signextend((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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 2; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - *PC = *(X+(rs1 + 8)) == 0? (signed)*PC + imm : *PC + 2; - this->do_sync(POST_SYNC, 77); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 77); + int16_t imm = signextend((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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + *PC = *(X+(rs1 + 8)) == 0? (int8_t)*PC + imm : *PC + 2; + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = super::template get_reg(arch::traits::PC); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 77); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 78: CBNEZ */ compile_ret_t __cbnez(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 78); - int16_t imm = signextend((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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 2; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - *PC = *(X+(rs1 + 8)) != 0? (signed)*PC + imm : *PC + 2; - this->do_sync(POST_SYNC, 78); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 78); + int16_t imm = signextend((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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + *PC = *(X+(rs1 + 8)) != 0? (int8_t)*PC + imm : *PC + 2; + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = super::template get_reg(arch::traits::PC); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 78); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 79: CSLLI */ compile_ret_t __cslli(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 79); - uint8_t shamt = ((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}, {shamt}", fmt::arg("mnemonic", "cslli"), - fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); - this->core.disass_output(pc.val, mnemonic); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 2; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - { - if(rs1 == 0) raise(0, 2); - *(X+(rs1)) = *(X+(rs1)) << shamt; - } - this->do_sync(POST_SYNC, 79); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 79); + uint8_t shamt = ((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}, {shamt}", fmt::arg("mnemonic", "cslli"), + fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); + this->core.disass_output(pc.val, mnemonic); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + { + if(rs1 == 0) raise(0, 2); + *(X+rs1) = *(X+rs1) << shamt; + } + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 2; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 79); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 80: CLWSP */ compile_ret_t __clwsp(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 80); - 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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 2; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - { - unsigned offs = *(X+(2)) + uimm; - *(X+(rd)) = (int32_t)readSpace4(traits::MEM, offs); - } - this->do_sync(POST_SYNC, 80); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 80); + 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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + { + uint8_t offs = *(X+2) + uimm; + *(X+rd) = (int32_t)readSpace4(traits::MEM, offs); + } + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 2; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 80); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 81: CMV */ compile_ret_t __cmv(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 81); - 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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 2; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - *(X+(rd)) = *(X+(rs2)); - this->do_sync(POST_SYNC, 81); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 81); + 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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + *(X+rd) = *(X+rs2); + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 2; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 81); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 82: CJR */ compile_ret_t __cjr(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 82); - 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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 2; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - *PC = *(X+(rs1)); - this->do_sync(POST_SYNC, 82); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 82); + 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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + *PC = *(X+rs1); + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = super::template get_reg(arch::traits::PC); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 82); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 83: CADD */ compile_ret_t __cadd(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 83); - 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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 2; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - *(X+(rd)) = *(X+(rd)) + *(X+(rs2)); - this->do_sync(POST_SYNC, 83); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 83); + 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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + *(X+rd) = *(X+rd) + *(X+rs2); + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 2; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 83); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 84: CJALR */ compile_ret_t __cjalr(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 84); - 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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 2; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - { - *(X+(1)) = *PC + 2; - *PC = *(X+(rs1)); - } - this->do_sync(POST_SYNC, 84); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 84); + 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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + { + *(X+1) = *PC + 2; + *PC = *(X+rs1); + } + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = super::template get_reg(arch::traits::PC); + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 84); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 85: CEBREAK */ compile_ret_t __cebreak(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 85); - if(this->disass_enabled){ - /* generate console output when executing the command */ - this->core.disass_output(pc.val, "cebreak"); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 2; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - raise(0, 3); - this->do_sync(POST_SYNC, 85); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 85); + if(this->disass_enabled){ + /* generate console output when executing the command */ + this->core.disass_output(pc.val, "cebreak"); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + raise(0, 3); + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 2; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 85); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 86: CSWSP */ compile_ret_t __cswsp(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 86); - 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); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 2; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - { - unsigned offs = *(X+(2)) + uimm; - writeSpace4(traits::MEM, offs, (uint32_t)*(X+(rs2))); - } - this->do_sync(POST_SYNC, 86); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 86); + 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); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + { + uint8_t offs = *(X+2) + uimm; + writeSpace4(traits::MEM, offs, (uint32_t)*(X+rs2)); + } + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 2; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 86); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /* instruction 87: DII */ compile_ret_t __dii(virt_addr_t& pc, code_word_t instr){ - this->do_sync(PRE_SYNC, 87); - if(this->disass_enabled){ - /* generate console output when executing the command */ - this->core.disass_output(pc.val, "dii"); - } - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 2; - uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::X0); - uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::PC); - raise(0, 2); - this->do_sync(POST_SYNC, 87); - auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); - // trap check - if(trap_state!=0){ - auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); - last_br = std::numeric_limits::max(); - super::core.enter_trap(trap_state, cur_pc_val); - } - pc.val=super::template get_reg(arch::traits::NEXT_PC); - return pc; + // pre execution stuff + this->do_sync(PRE_SYNC, 87); + if(this->disass_enabled){ + /* generate console output when executing the command */ + this->core.disass_output(pc.val, "dii"); + + } + // prepare execution + uint32_t* X = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::X0]); + uint32_t* PC = reinterpret_cast(this->regs_base_ptr+arch::traits::reg_byte_offsets[arch::traits::PC]); + // execute instruction + raise(0, 2); + // post execution stuff + super::template get_reg(arch::traits::NEXT_PC) = pc.val + 2; + if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 87); + auto& trap_state = super::template get_reg(arch::traits::TRAP_STATE); + // trap check + if(trap_state!=0){ + auto& last_br = super::template get_reg(arch::traits::LAST_BRANCH); + last_br = std::numeric_limits::max(); + super::core.enter_trap(trap_state, pc.val); + } + pc.val=super::template get_reg(arch::traits::NEXT_PC); + return pc; } /****************************************************************************