From ab554539e37566f7ca8f06d5ddf701bdf231a110 Mon Sep 17 00:00:00 2001 From: eyck Date: Tue, 29 Dec 2020 08:48:22 +0000 Subject: [PATCH] first version of tgf_c based on CoreDSL 2.0 --- gen_input/CoreDSL-Instruction-Set-Description | 2 +- gen_input/TGFS.core_desc | 22 +- gen_input/minres_rv.core_desc | 74 - .../templates/interp/incl-CORENAME.h.gtl | 99 +- .../templates/interp/src-CORENAME.cpp.gtl | 48 +- .../templates/interp/vm-vm_CORENAME.cpp.gtl | 61 +- incl/iss/arch/tgf_c.h | 115 +- src/iss/tgf_c.cpp | 6 +- src/vm/interp/vm_tgf_c.cpp | 5161 ++++++++--------- 9 files changed, 2609 insertions(+), 2979 deletions(-) delete mode 100644 gen_input/minres_rv.core_desc diff --git a/gen_input/CoreDSL-Instruction-Set-Description b/gen_input/CoreDSL-Instruction-Set-Description index 3bb3763..3786181 160000 --- a/gen_input/CoreDSL-Instruction-Set-Description +++ b/gen_input/CoreDSL-Instruction-Set-Description @@ -1 +1 @@ -Subproject commit 3bb3763e9277642333b42f0f5bd4bd15c1546bb7 +Subproject commit 378618192944debf5a5dee759aa1a517aec0941b diff --git a/gen_input/TGFS.core_desc b/gen_input/TGFS.core_desc index 29944f6..cc22ca1 100644 --- a/gen_input/TGFS.core_desc +++ b/gen_input/TGFS.core_desc @@ -4,25 +4,25 @@ import "CoreDSL-Instruction-Set-Description/RVC.core_desc" Core TGF_B provides RV32I { constants { - XLEN:=32; - PCLEN:=32; + unsigned XLEN=32; + unsigned PCLEN=32; // definitions for the architecture wrapper // XL ZYXWVUTSRQPONMLKJIHGFEDCBA - MISA_VAL:=0b01000000000000000000000100000000; - PGSIZE := 0x1000; //1 << 12; - PGMASK := 0xfff; //PGSIZE-1 + unsigned MISA_VAL=0b01000000000000000000000100000000; + unsigned PGSIZE = 0x1000; //1 << 12; + unsigned PGMASK = 0xfff; //PGSIZE-1 } } Core TGF_C provides RV32I, RV32M, RV32IC { constants { - XLEN:=32; - PCLEN:=32; - MUL_LEN:=64; + unsigned XLEN=32; + unsigned PCLEN=32; + unsigned MUL_LEN=64; // definitions for the architecture wrapper // XL ZYXWVUTSRQPONMLKJIHGFEDCBA - MISA_VAL:=0b01000000000000000001000100000100; - PGSIZE := 0x1000; //1 << 12; - PGMASK := 0xfff; //PGSIZE-1 + unsigned MISA_VAL=0b01000000000000000001000100000100; + unsigned PGSIZE = 0x1000; //1 << 12; + unsigned PGMASK = 0xfff; //PGSIZE-1 } } \ No newline at end of file diff --git a/gen_input/minres_rv.core_desc b/gen_input/minres_rv.core_desc deleted file mode 100644 index b4246ce..0000000 --- a/gen_input/minres_rv.core_desc +++ /dev/null @@ -1,74 +0,0 @@ -import "RV32I.core_desc" -import "RV64I.core_desc" -import "RVM.core_desc" -import "RVA.core_desc" -import "RVC.core_desc" -import "RVF.core_desc" -import "RVD.core_desc" - - -Core MNRV32 provides RV32I, RV32IC { - constants { - XLEN:=32; - PCLEN:=32; - // definitions for the architecture wrapper - // XL ZYXWVUTSRQPONMLKJIHGFEDCBA - MISA_VAL:=0b01000000000101000001000100000101; - PGSIZE := 0x1000; //1 << 12; - PGMASK := 0xfff; //PGSIZE-1 - } -} - -Core RV32IMAC provides RV32I, RV32M, RV32A, RV32IC { - constants { - XLEN:=32; - PCLEN:=32; - MUL_LEN:=64; - // definitions for the architecture wrapper - // XL ZYXWVUTSRQPONMLKJIHGFEDCBA - MISA_VAL:=0b01000000000101000001000100000101; - PGSIZE := 0x1000; //1 << 12; - PGMASK := 0xfff; //PGSIZE-1 - } -} - -Core RV32GC provides RV32I, RV32M, RV32A, RV32F, RV32D, RV32IC, RV32FC, RV32DC { - constants { - XLEN:=32; - FLEN:=64; - PCLEN:=32; - MUL_LEN:=64; - // definitions for the architecture wrapper - // XL ZYXWVUTSRQPONMLKJIHGFEDCBA - MISA_VAL:=0b01000000000101000001000100101101; - PGSIZE := 0x1000; //1 << 12; - PGMASK := 0xfff; //PGSIZE-1 - } -} - -Core RV64I provides RV64I { - constants { - XLEN:=64; - PCLEN:=64; - // definitions for the architecture wrapper - // XL ZYXWVUTSRQPONMLKJIHGFEDCBA - MISA_VAL:=0b10000000000001000000000100000000; - PGSIZE := 0x1000; //1 << 12; - PGMASK := 0xfff; //PGSIZE-1 - } -} - -Core RV64GC provides RV64I, RV64M, RV64A, RV64F, RV64D, RV32FC, RV32DC, RV64IC { - constants { - XLEN:=64; - FLEN:=64; - PCLEN:=64; - MUL_LEN:=128; - // definitions for the architecture wrapper - // XL ZYXWVUTSRQPONMLKJIHGFEDCBA - MISA_VAL:=0b01000000000101000001000100101101; - PGSIZE := 0x1000; //1 << 12; - PGMASK := 0xfff; //PGSIZE-1 - } -} - diff --git a/gen_input/templates/interp/incl-CORENAME.h.gtl b/gen_input/templates/interp/incl-CORENAME.h.gtl index 0a5b99f..f31aba9 100644 --- a/gen_input/templates/interp/incl-CORENAME.h.gtl +++ b/gen_input/templates/interp/incl-CORENAME.h.gtl @@ -30,48 +30,6 @@ * *******************************************************************************/ -<% -import com.minres.coredsl.coreDsl.Register -import com.minres.coredsl.coreDsl.RegisterFile -import com.minres.coredsl.coreDsl.RegisterAlias -def getTypeSize(size){ - if(size > 32) 64 else if(size > 16) 32 else if(size > 8) 16 else 8 -} -def getOriginalName(reg){ - if( reg.original instanceof RegisterFile) { - if( reg.index != null ) { - return reg.original.name+generator.generateHostCode(reg.index) - } else { - return reg.original.name - } - } else if(reg.original instanceof Register){ - return reg.original.name - } -} -def getRegisterNames(){ - def regNames = [] - allRegs.each { reg -> - if( reg instanceof RegisterFile) { - (reg.range.right..reg.range.left).each{ - regNames+=reg.name.toLowerCase()+it - } - } else if(reg instanceof Register){ - regNames+=reg.name.toLowerCase() - } - } - return regNames -} -def getRegisterAliasNames(){ - def regMap = allRegs.findAll{it instanceof RegisterAlias }.collectEntries {[getOriginalName(it), it.name]} - return allRegs.findAll{it instanceof Register || it instanceof RegisterFile}.collect{reg -> - if( reg instanceof RegisterFile) { - return (reg.range.right..reg.range.left).collect{ (regMap[reg.name]?:regMap[reg.name+it]?:reg.name.toLowerCase()+it).toLowerCase() } - } else if(reg instanceof Register){ - regMap[reg.name]?:reg.name.toLowerCase() - } - }.flatten() -} -%> #ifndef _${coreDef.name.toUpperCase()}_H_ #define _${coreDef.name.toUpperCase()}_H_ @@ -89,25 +47,19 @@ template <> struct traits<${coreDef.name.toLowerCase()}> { constexpr static char const* const core_type = "${coreDef.name}"; - static constexpr std::array reg_names{ - {"${getRegisterNames().join("\", \"")}"}}; + static constexpr std::array reg_names{ + {"${registers.collect{it.name}.join('", "')}"}}; - static constexpr std::array reg_aliases{ - {"${getRegisterAliasNames().join("\", \"")}"}}; + static constexpr std::array reg_aliases{ + {"${registers.collect{it.alias}.join('", "')}"}}; - enum constants {${coreDef.constants.collect{c -> c.name+"="+c.value}.join(', ')}}; + enum constants {${constants.collect{c -> c.name+"="+c.value}.join(', ')}}; - constexpr static unsigned FP_REGS_SIZE = ${coreDef.constants.find {it.name=='FLEN'}?.value?:0}; + constexpr static unsigned FP_REGS_SIZE = ${constants.find {it.name=='FLEN'}?.value?:0}; enum reg_e {<% - allRegs.each { reg -> - if( reg instanceof RegisterFile) { - (reg.range.right..reg.range.left).each{%> - ${reg.name}${it},<% - } - } else if(reg instanceof Register){ %> + registers.each { reg -> %> ${reg.name},<% - } }%> NUM_REGS, NEXT_${pc.name}=NUM_REGS, @@ -115,15 +67,10 @@ template <> struct traits<${coreDef.name.toLowerCase()}> { PENDING_TRAP, MACHINE_STATE, LAST_BRANCH, - ICOUNT<% - allRegs.each { reg -> - if(reg instanceof RegisterAlias){ def aliasname=getOriginalName(reg)%>, - ${reg.name} = ${aliasname}<% - } - }%> + ICOUNT }; - using reg_t = uint${regDataWidth}_t; + using reg_t = uint${addrDataWidth}_t; using addr_t = uint${addrDataWidth}_t; @@ -133,17 +80,17 @@ template <> struct traits<${coreDef.name.toLowerCase()}> { using phys_addr_t = iss::typed_addr_t; - static constexpr std::array reg_bit_widths{ - {${regSizes.join(",")}}}; + static constexpr std::array reg_bit_widths{ + {${registers.collect{it.size}.join(',')}}}; - static constexpr std::array reg_byte_offsets{ - {${regOffsets.join(",")}}}; + static constexpr std::array reg_byte_offsets{ + {${registers.collect{it.offset}.join(',')}}}; static const uint64_t addr_mask = (reg_t(1) << (XLEN - 1)) | ((reg_t(1) << (XLEN - 1)) - 1); enum sreg_flag_e { FLAGS }; - enum mem_type_e { ${allSpaces.collect{s -> s.name}.join(', ')} }; + enum mem_type_e { ${spaces.collect{it.name}.join(', ')} }; }; struct ${coreDef.name.toLowerCase()}: public arch_if { @@ -190,16 +137,10 @@ struct ${coreDef.name.toLowerCase()}: public arch_if { protected: struct ${coreDef.name}_regs {<% - allRegs.each { reg -> - if( reg instanceof RegisterFile) { - (reg.range.right..reg.range.left).each{%> - uint${generator.getSize(reg)}_t ${reg.name}${it} = 0;<% - } - } else if(reg instanceof Register){ %> - uint${generator.getSize(reg)}_t ${reg.name} = 0;<% - } + registers.each { reg ->%> + uint${reg.size}_t ${reg.name} = 0;<% }%> - uint${generator.getSize(pc)}_t NEXT_${pc.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; } reg; @@ -208,10 +149,10 @@ protected: uint64_t interrupt_sim=0; <% -def fcsr = allRegs.find {it.name=='FCSR'} +def fcsr = registers.find {it.name=='FCSR'} if(fcsr != null) {%> - uint${generator.getSize(fcsr)}_t get_fcsr(){return reg.FCSR;} - void set_fcsr(uint${generator.getSize(fcsr)}_t val){reg.FCSR = val;} + uint${fcsr.size}_t get_fcsr(){return reg.FCSR;} + void set_fcsr(uint${fcsr.size}_t val){reg.FCSR = val;} <%} else { %> uint32_t get_fcsr(){return 0;} void set_fcsr(uint32_t val){} diff --git a/gen_input/templates/interp/src-CORENAME.cpp.gtl b/gen_input/templates/interp/src-CORENAME.cpp.gtl index 8ed478f..a257137 100644 --- a/gen_input/templates/interp/src-CORENAME.cpp.gtl +++ b/gen_input/templates/interp/src-CORENAME.cpp.gtl @@ -29,45 +29,7 @@ * POSSIBILITY OF SUCH DAMAGE. * *******************************************************************************/ - <% -import com.minres.coredsl.coreDsl.Register -import com.minres.coredsl.coreDsl.RegisterFile -import com.minres.coredsl.coreDsl.RegisterAlias -def getOriginalName(reg){ - if( reg.original instanceof RegisterFile) { - if( reg.index != null ) { - return reg.original.name+generator.generateHostCode(reg.index) - } else { - return reg.original.name - } - } else if(reg.original instanceof Register){ - return reg.original.name - } -} -def getRegisterNames(){ - def regNames = [] - allRegs.each { reg -> - if( reg instanceof RegisterFile) { - (reg.range.right..reg.range.left).each{ - regNames+=reg.name.toLowerCase()+it - } - } else if(reg instanceof Register){ - regNames+=reg.name.toLowerCase() - } - } - return regNames -} -def getRegisterAliasNames(){ - def regMap = allRegs.findAll{it instanceof RegisterAlias }.collectEntries {[getOriginalName(it), it.name]} - return allRegs.findAll{it instanceof Register || it instanceof RegisterFile}.collect{reg -> - if( reg instanceof RegisterFile) { - return (reg.range.right..reg.range.left).collect{ (regMap[reg.name]?:regMap[reg.name+it]?:reg.name.toLowerCase()+it).toLowerCase() } - } else if(reg instanceof Register){ - regMap[reg.name]?:reg.name.toLowerCase() - } - }.flatten() -} -%> + #include "util/ities.h" #include #include @@ -77,10 +39,10 @@ def getRegisterAliasNames(){ 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; ${coreDef.name.toLowerCase()}::${coreDef.name.toLowerCase()}() { reg.icount = 0; diff --git a/gen_input/templates/interp/vm-vm_CORENAME.cpp.gtl b/gen_input/templates/interp/vm-vm_CORENAME.cpp.gtl index 17dd09d..bc9f9c2 100644 --- a/gen_input/templates/interp/vm-vm_CORENAME.cpp.gtl +++ b/gen_input/templates/interp/vm-vm_CORENAME.cpp.gtl @@ -56,13 +56,14 @@ using namespace iss::debugger; template class vm_impl : public iss::interp::vm_base { public: - using super = typename iss::interp::vm_base; + using traits = arch::traits; + using super = typename iss::interp::vm_base; using virt_addr_t = typename super::virt_addr_t; using phys_addr_t = typename super::phys_addr_t; using code_word_t = typename super::code_word_t; - using addr_t = typename super::addr_t; - using reg_t = typename traits::reg_t; - using iss::interp::vm_base::get_reg; + using addr_t = typename super::addr_t; + using reg_t = typename traits::reg_t; + using mem_type_e = typename traits::mem_type_e; vm_impl(); @@ -82,7 +83,7 @@ protected: using compile_ret_t = virt_addr_t; using compile_func = compile_ret_t (this_class::*)(virt_addr_t &pc, code_word_t instr); - inline const char *name(size_t index){return traits::reg_aliases.at(index);} + inline const char *name(size_t index){return traits::reg_aliases.at(index);} virt_addr_t execute_inst(virt_addr_t start, std::function pred) override; @@ -138,23 +139,31 @@ protected: return lut_val; } - void raise_trap(uint16_t trap_id, uint16_t cause){ + void raise(uint16_t trap_id, uint16_t cause){ auto trap_val = 0x80ULL << 24 | (cause << 16) | trap_id; - this->template get_reg(arch::traits::TRAP_STATE) = trap_val; - this->template get_reg(arch::traits::NEXT_PC) = std::numeric_limits::max(); + this->template get_reg(traits::TRAP_STATE) = trap_val; + this->template get_reg(traits::NEXT_PC) = std::numeric_limits::max(); } - void leave_trap(unsigned lvl){ + void leave(unsigned lvl){ this->core.leave_trap(lvl); - auto pc_val = super::template read_mem(traits::CSR, (lvl << 8) + 0x41); - this->template get_reg(arch::traits::NEXT_PC) = pc_val; - this->template get_reg(arch::traits::LAST_BRANCH) = std::numeric_limits::max(); + auto pc_val = super::template read_mem(traits::CSR, (lvl << 8) + 0x41); + this->template get_reg(traits::NEXT_PC) = pc_val; + this->template get_reg(traits::LAST_BRANCH) = std::numeric_limits::max(); } void wait(unsigned type){ this->core.wait_until(type); } + inline uint8_t readSpace1(typename super::mem_type_e space, uint64_t addr){return super::template read_mem(space, addr);} + inline uint16_t readSpace2(typename super::mem_type_e space, uint64_t addr){return super::template read_mem(space, addr);} + inline uint32_t readSpace4(typename super::mem_type_e space, uint64_t addr){return super::template read_mem(space, addr);} + inline uint64_t readSpace8(typename super::mem_type_e space, uint64_t addr){return super::template read_mem(space, addr);} + inline void writeSpace1(typename super::mem_type_e space, uint64_t addr, uint8_t data){super::write_mem(space, addr, data);} + inline void writeSpace2(typename super::mem_type_e space, uint64_t addr, uint16_t data){super::write_mem(space, addr, data);} + inline void writeSpace4(typename super::mem_type_e space, uint64_t addr, uint32_t data){super::write_mem(space, addr, data);} + inline void writeSpace8(typename super::mem_type_e space, uint64_t addr, uint64_t data){super::write_mem(space, addr, data);} private: /**************************************************************************** @@ -170,13 +179,33 @@ private: const std::array instr_descr = {{ /* entries are: size, valid value, valid mask, function ptr */<%instructions.each{instr -> %> /* instruction ${instr.instruction.name} */ - {${instr.length}, ${instr.value}, ${instr.mask}, &this_class::__${generator.functionName(instr.name)}},<%}%> + {${instr.length}, ${instr.encoding}, ${instr.mask}, &this_class::__${generator.functionName(instr.name)}},<%}%> }}; /* 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){<%instr.code.eachLine{%> - ${it}<%}%> + 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; } <%}%> /**************************************************************************** @@ -212,7 +241,7 @@ template typename vm_base::virt_addr_t vm_impl::execute_inst(virt_addr_t start, std::function pred) { // we fetch at max 4 byte, alignment is 2 enum {TRAP_ID=1<<16}; - const typename traits::addr_t upper_bits = ~traits::PGMASK; + const typename traits::addr_t upper_bits = ~traits::PGMASK; code_word_t insn = 0; auto *const data = (uint8_t *)&insn; auto pc=start; diff --git a/incl/iss/arch/tgf_c.h b/incl/iss/arch/tgf_c.h index a008841..4424509 100644 --- a/incl/iss/arch/tgf_c.h +++ b/incl/iss/arch/tgf_c.h @@ -30,7 +30,6 @@ * *******************************************************************************/ - #ifndef _TGF_C_H_ #define _TGF_C_H_ @@ -49,12 +48,12 @@ 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"}}; + {"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_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"}}; + {"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"}}; - enum constants {XLEN=32, PCLEN=32, MUL_LEN=64, MISA_VAL=0b1000000000000000001000100000100, PGSIZE=0x1000, PGMASK=0xfff}; + enum constants {XLEN=32, PCLEN=32, MUL_LEN=64, MISA_VAL=0b1000000000000000001000100000100, PGSIZE=0x1000, PGMASK=0xfff, CSR_SIZE=4096, fence=0, fencei=1, fencevmal=2, fencevmau=3}; constexpr static unsigned FP_REGS_SIZE = 0; @@ -98,39 +97,7 @@ template <> struct traits { PENDING_TRAP, MACHINE_STATE, LAST_BRANCH, - ICOUNT, - ZERO = X0, - RA = X1, - SP = X2, - GP = X3, - TP = X4, - T0 = X5, - T1 = X6, - T2 = X7, - S0 = X8, - S1 = X9, - A0 = X10, - A1 = X11, - A2 = X12, - A3 = X13, - A4 = X14, - A5 = X15, - A6 = X16, - A7 = X17, - S2 = X18, - S3 = X19, - S4 = X20, - S5 = X21, - S6 = X22, - S7 = X23, - S8 = X24, - S9 = X25, - S10 = X26, - S11 = X27, - T3 = X28, - T4 = X29, - T5 = X30, - T6 = X31 + ICOUNT }; using reg_t = uint32_t; @@ -143,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,32,32,32,32,32,64}}; + 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_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,160}}; + 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 const uint64_t addr_mask = (reg_t(1) << (XLEN - 1)) | ((reg_t(1) << (XLEN - 1)) - 1); @@ -199,39 +166,39 @@ struct tgf_c: public arch_if { inline uint32_t get_last_branch() { return reg.last_branch; } protected: - struct TGF_C_regs { - uint32_t X0 = 0; - uint32_t X1 = 0; - uint32_t X2 = 0; - uint32_t X3 = 0; - uint32_t X4 = 0; - uint32_t X5 = 0; - uint32_t X6 = 0; - uint32_t X7 = 0; - uint32_t X8 = 0; - uint32_t X9 = 0; - uint32_t X10 = 0; - uint32_t X11 = 0; - uint32_t X12 = 0; - uint32_t X13 = 0; - uint32_t X14 = 0; - uint32_t X15 = 0; - uint32_t X16 = 0; - uint32_t X17 = 0; - uint32_t X18 = 0; - uint32_t X19 = 0; - uint32_t X20 = 0; - uint32_t X21 = 0; - uint32_t X22 = 0; - uint32_t X23 = 0; - uint32_t X24 = 0; - uint32_t X25 = 0; - uint32_t X26 = 0; - uint32_t X27 = 0; - uint32_t X28 = 0; - uint32_t X29 = 0; - uint32_t X30 = 0; - uint32_t X31 = 0; + struct TGF_C_regs { + uint32_t X0 = 0; + uint32_t X1 = 0; + uint32_t X2 = 0; + uint32_t X3 = 0; + uint32_t X4 = 0; + uint32_t X5 = 0; + uint32_t X6 = 0; + uint32_t X7 = 0; + uint32_t X8 = 0; + uint32_t X9 = 0; + uint32_t X10 = 0; + uint32_t X11 = 0; + uint32_t X12 = 0; + uint32_t X13 = 0; + uint32_t X14 = 0; + uint32_t X15 = 0; + uint32_t X16 = 0; + uint32_t X17 = 0; + uint32_t X18 = 0; + uint32_t X19 = 0; + uint32_t X20 = 0; + uint32_t X21 = 0; + uint32_t X22 = 0; + uint32_t X23 = 0; + uint32_t X24 = 0; + uint32_t X25 = 0; + uint32_t X26 = 0; + uint32_t X27 = 0; + uint32_t X28 = 0; + uint32_t X29 = 0; + uint32_t X30 = 0; + uint32_t X31 = 0; uint32_t PC = 0; uint32_t NEXT_PC = 0; uint32_t trap_state = 0, pending_trap = 0, machine_state = 0, last_branch = 0; diff --git a/src/iss/tgf_c.cpp b/src/iss/tgf_c.cpp index 93f818f..9fb2382 100644 --- a/src/iss/tgf_c.cpp +++ b/src/iss/tgf_c.cpp @@ -29,7 +29,7 @@ * POSSIBILITY OF SUCH DAMAGE. * *******************************************************************************/ - + #include "util/ities.h" #include #include @@ -41,8 +41,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; tgf_c::tgf_c() { reg.icount = 0; diff --git a/src/vm/interp/vm_tgf_c.cpp b/src/vm/interp/vm_tgf_c.cpp index 07f67a5..0d79d87 100644 --- a/src/vm/interp/vm_tgf_c.cpp +++ b/src/vm/interp/vm_tgf_c.cpp @@ -56,13 +56,14 @@ using namespace iss::debugger; template class vm_impl : public iss::interp::vm_base { public: - using super = typename iss::interp::vm_base; + using traits = arch::traits; + using super = typename iss::interp::vm_base; using virt_addr_t = typename super::virt_addr_t; using phys_addr_t = typename super::phys_addr_t; using code_word_t = typename super::code_word_t; - using addr_t = typename super::addr_t; - using reg_t = typename traits::reg_t; - using iss::interp::vm_base::get_reg; + using addr_t = typename super::addr_t; + using reg_t = typename traits::reg_t; + using mem_type_e = typename traits::mem_type_e; vm_impl(); @@ -82,7 +83,7 @@ protected: using compile_ret_t = virt_addr_t; using compile_func = compile_ret_t (this_class::*)(virt_addr_t &pc, code_word_t instr); - inline const char *name(size_t index){return traits::reg_aliases.at(index);} + inline const char *name(size_t index){return traits::reg_aliases.at(index);} virt_addr_t execute_inst(virt_addr_t start, std::function pred) override; @@ -138,23 +139,31 @@ protected: return lut_val; } - void raise_trap(uint16_t trap_id, uint16_t cause){ + void raise(uint16_t trap_id, uint16_t cause){ auto trap_val = 0x80ULL << 24 | (cause << 16) | trap_id; - this->template get_reg(arch::traits::TRAP_STATE) = trap_val; - this->template get_reg(arch::traits::NEXT_PC) = std::numeric_limits::max(); + this->template get_reg(traits::TRAP_STATE) = trap_val; + this->template get_reg(traits::NEXT_PC) = std::numeric_limits::max(); } - void leave_trap(unsigned lvl){ + void leave(unsigned lvl){ this->core.leave_trap(lvl); - auto pc_val = super::template read_mem(traits::CSR, (lvl << 8) + 0x41); - this->template get_reg(arch::traits::NEXT_PC) = pc_val; - this->template get_reg(arch::traits::LAST_BRANCH) = std::numeric_limits::max(); + auto pc_val = super::template read_mem(traits::CSR, (lvl << 8) + 0x41); + this->template get_reg(traits::NEXT_PC) = pc_val; + this->template get_reg(traits::LAST_BRANCH) = std::numeric_limits::max(); } void wait(unsigned type){ this->core.wait_until(type); } + inline uint8_t readSpace1(typename super::mem_type_e space, uint64_t addr){return super::template read_mem(space, addr);} + inline uint16_t readSpace2(typename super::mem_type_e space, uint64_t addr){return super::template read_mem(space, addr);} + inline uint32_t readSpace4(typename super::mem_type_e space, uint64_t addr){return super::template read_mem(space, addr);} + inline uint64_t readSpace8(typename super::mem_type_e space, uint64_t addr){return super::template read_mem(space, addr);} + inline void writeSpace1(typename super::mem_type_e space, uint64_t addr, uint8_t data){super::write_mem(space, addr, data);} + inline void writeSpace2(typename super::mem_type_e space, uint64_t addr, uint16_t data){super::write_mem(space, addr, data);} + inline void writeSpace4(typename super::mem_type_e space, uint64_t addr, uint32_t data){super::write_mem(space, addr, data);} + inline void writeSpace8(typename super::mem_type_e space, uint64_t addr, uint64_t data){super::write_mem(space, addr, data);} private: /**************************************************************************** @@ -259,7 +268,7 @@ private: {32, 0b00110000001000000000000001110011, 0b11111111111111111111111111111111, &this_class::__mret}, /* instruction WFI */ {32, 0b00010000010100000000000001110011, 0b11111111111111111111111111111111, &this_class::__wfi}, - /* instruction SFENCE.VMA */ + /* instruction SFENCE_VMA */ {32, 0b00010010000000000000000001110011, 0b11111110000000000111111111111111, &this_class::__sfence_vma}, /* instruction CSRRW */ {32, 0b00000000000000000001000001110011, 0b00000000000000000111000001111111, &this_class::__csrrw}, @@ -289,60 +298,60 @@ private: {32, 0b00000010000000000110000000110011, 0b11111110000000000111000001111111, &this_class::__rem}, /* instruction REMU */ {32, 0b00000010000000000111000000110011, 0b11111110000000000111000001111111, &this_class::__remu}, - /* instruction C.ADDI4SPN */ - {16, 0b0000000000000000, 0b1110000000000011, &this_class::__c_addi4spn}, - /* instruction C.LW */ - {16, 0b0100000000000000, 0b1110000000000011, &this_class::__c_lw}, - /* instruction C.SW */ - {16, 0b1100000000000000, 0b1110000000000011, &this_class::__c_sw}, - /* instruction C.ADDI */ - {16, 0b0000000000000001, 0b1110000000000011, &this_class::__c_addi}, - /* instruction C.NOP */ - {16, 0b0000000000000001, 0b1111111111111111, &this_class::__c_nop}, - /* instruction C.JAL */ - {16, 0b0010000000000001, 0b1110000000000011, &this_class::__c_jal}, - /* instruction C.LI */ - {16, 0b0100000000000001, 0b1110000000000011, &this_class::__c_li}, - /* instruction C.LUI */ - {16, 0b0110000000000001, 0b1110000000000011, &this_class::__c_lui}, - /* instruction C.ADDI16SP */ - {16, 0b0110000100000001, 0b1110111110000011, &this_class::__c_addi16sp}, - /* instruction C.SRLI */ - {16, 0b1000000000000001, 0b1111110000000011, &this_class::__c_srli}, - /* instruction C.SRAI */ - {16, 0b1000010000000001, 0b1111110000000011, &this_class::__c_srai}, - /* instruction C.ANDI */ - {16, 0b1000100000000001, 0b1110110000000011, &this_class::__c_andi}, - /* instruction C.SUB */ - {16, 0b1000110000000001, 0b1111110001100011, &this_class::__c_sub}, - /* instruction C.XOR */ - {16, 0b1000110000100001, 0b1111110001100011, &this_class::__c_xor}, - /* instruction C.OR */ - {16, 0b1000110001000001, 0b1111110001100011, &this_class::__c_or}, - /* instruction C.AND */ - {16, 0b1000110001100001, 0b1111110001100011, &this_class::__c_and}, - /* instruction C.J */ - {16, 0b1010000000000001, 0b1110000000000011, &this_class::__c_j}, - /* instruction C.BEQZ */ - {16, 0b1100000000000001, 0b1110000000000011, &this_class::__c_beqz}, - /* instruction C.BNEZ */ - {16, 0b1110000000000001, 0b1110000000000011, &this_class::__c_bnez}, - /* instruction C.SLLI */ - {16, 0b0000000000000010, 0b1111000000000011, &this_class::__c_slli}, - /* instruction C.LWSP */ - {16, 0b0100000000000010, 0b1110000000000011, &this_class::__c_lwsp}, - /* instruction C.MV */ - {16, 0b1000000000000010, 0b1111000000000011, &this_class::__c_mv}, - /* instruction C.JR */ - {16, 0b1000000000000010, 0b1111000001111111, &this_class::__c_jr}, - /* instruction C.ADD */ - {16, 0b1001000000000010, 0b1111000000000011, &this_class::__c_add}, - /* instruction C.JALR */ - {16, 0b1001000000000010, 0b1111000001111111, &this_class::__c_jalr}, - /* instruction C.EBREAK */ - {16, 0b1001000000000010, 0b1111111111111111, &this_class::__c_ebreak}, - /* instruction C.SWSP */ - {16, 0b1100000000000010, 0b1110000000000011, &this_class::__c_swsp}, + /* instruction CADDI4SPN */ + {16, 0b0000000000000000, 0b1110000000000011, &this_class::__caddi4spn}, + /* instruction CLW */ + {16, 0b0100000000000000, 0b1110000000000011, &this_class::__clw}, + /* instruction CSW */ + {16, 0b1100000000000000, 0b1110000000000011, &this_class::__csw}, + /* instruction CADDI */ + {16, 0b0000000000000001, 0b1110000000000011, &this_class::__caddi}, + /* instruction CNOP */ + {16, 0b0000000000000001, 0b1111111111111111, &this_class::__cnop}, + /* instruction CJAL */ + {16, 0b0010000000000001, 0b1110000000000011, &this_class::__cjal}, + /* instruction CLI */ + {16, 0b0100000000000001, 0b1110000000000011, &this_class::__cli}, + /* instruction CLUI */ + {16, 0b0110000000000001, 0b1110000000000011, &this_class::__clui}, + /* instruction CADDI16SP */ + {16, 0b0110000100000001, 0b1110111110000011, &this_class::__caddi16sp}, + /* instruction CSRLI */ + {16, 0b1000000000000001, 0b1111110000000011, &this_class::__csrli}, + /* instruction CSRAI */ + {16, 0b1000010000000001, 0b1111110000000011, &this_class::__csrai}, + /* instruction CANDI */ + {16, 0b1000100000000001, 0b1110110000000011, &this_class::__candi}, + /* instruction CSUB */ + {16, 0b1000110000000001, 0b1111110001100011, &this_class::__csub}, + /* instruction CXOR */ + {16, 0b1000110000100001, 0b1111110001100011, &this_class::__cxor}, + /* instruction COR */ + {16, 0b1000110001000001, 0b1111110001100011, &this_class::__cor}, + /* instruction CAND */ + {16, 0b1000110001100001, 0b1111110001100011, &this_class::__cand}, + /* instruction CJ */ + {16, 0b1010000000000001, 0b1110000000000011, &this_class::__cj}, + /* instruction CBEQZ */ + {16, 0b1100000000000001, 0b1110000000000011, &this_class::__cbeqz}, + /* instruction CBNEZ */ + {16, 0b1110000000000001, 0b1110000000000011, &this_class::__cbnez}, + /* instruction CSLLI */ + {16, 0b0000000000000010, 0b1111000000000011, &this_class::__cslli}, + /* instruction CLWSP */ + {16, 0b0100000000000010, 0b1110000000000011, &this_class::__clwsp}, + /* instruction CMV */ + {16, 0b1000000000000010, 0b1111000000000011, &this_class::__cmv}, + /* instruction CJR */ + {16, 0b1000000000000010, 0b1111000001111111, &this_class::__cjr}, + /* instruction CADD */ + {16, 0b1001000000000010, 0b1111000000000011, &this_class::__cadd}, + /* instruction CJALR */ + {16, 0b1001000000000010, 0b1111000001111111, &this_class::__cjalr}, + /* instruction CEBREAK */ + {16, 0b1001000000000010, 0b1111111111111111, &this_class::__cebreak}, + /* instruction CSWSP */ + {16, 0b1100000000000010, 0b1110000000000011, &this_class::__cswsp}, /* instruction DII */ {16, 0b0000000000000000, 0b1111111111111111, &this_class::__dii}, }}; @@ -350,2909 +359,2705 @@ 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; - if(rd != 0){ - auto Xtmp0_val = (imm); - super::template get_reg(rd + traits::X0)=Xtmp0_val; - } - 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; + 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; } /* 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; - if(rd != 0){ - auto Xtmp0_val = (static_cast(cur_pc_val) + (imm)); - super::template get_reg(rd + traits::X0)=Xtmp0_val; - } - 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; + 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; } /* 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; - if(rd != 0){ - auto Xtmp0_val = (cur_pc_val + 4); - super::template get_reg(rd + traits::X0)=Xtmp0_val; - } - auto PC_val = (static_cast(cur_pc_val) + (imm)); - super::template get_reg(traits::NEXT_PC) = PC_val; - auto is_cont_v = PC_val !=pc.val; - super::template get_reg(traits::LAST_BRANCH) = is_cont_v?1:0; - 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; + 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; } /* 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; - auto new_pc_val = (static_cast(super::template get_reg(rs1 + traits::X0)) + (imm)); - if(rd != 0){ - auto Xtmp0_val = (cur_pc_val + 4); - super::template get_reg(rd + traits::X0)=Xtmp0_val; - } - auto PC_val = (new_pc_val & ~(0x1)); - super::template get_reg(traits::NEXT_PC) = PC_val; - super::template get_reg(traits::LAST_BRANCH) = std::numeric_limits::max(); - 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; + 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; } /* 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; - auto PC_val = (super::template get_reg(rs1 + traits::X0) == super::template get_reg(rs2 + traits::X0))? - (static_cast(cur_pc_val) + (imm)): - (cur_pc_val + 4); - super::template get_reg(traits::NEXT_PC) = PC_val; - auto is_cont_v = PC_val !=pc.val; - super::template get_reg(traits::LAST_BRANCH) = is_cont_v?1:0; - 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; + 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; } /* 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; - auto PC_val = (super::template get_reg(rs1 + traits::X0) != super::template get_reg(rs2 + traits::X0))? - (static_cast(cur_pc_val) + (imm)): - (cur_pc_val + 4); - super::template get_reg(traits::NEXT_PC) = PC_val; - auto is_cont_v = PC_val !=pc.val; - super::template get_reg(traits::LAST_BRANCH) = is_cont_v?1:0; - 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; + 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; } /* 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; - auto PC_val = (static_cast(super::template get_reg(rs1 + traits::X0)) < static_cast(super::template get_reg(rs2 + traits::X0)))? - (static_cast(cur_pc_val) + (imm)): - (cur_pc_val + 4); - super::template get_reg(traits::NEXT_PC) = PC_val; - auto is_cont_v = PC_val !=pc.val; - super::template get_reg(traits::LAST_BRANCH) = is_cont_v?1:0; - 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; + 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; } /* 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; - auto PC_val = (static_cast(super::template get_reg(rs1 + traits::X0)) >= static_cast(super::template get_reg(rs2 + traits::X0)))? - (static_cast(cur_pc_val) + (imm)): - (cur_pc_val + 4); - super::template get_reg(traits::NEXT_PC) = PC_val; - auto is_cont_v = PC_val !=pc.val; - super::template get_reg(traits::LAST_BRANCH) = is_cont_v?1:0; - 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; + 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; } /* 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; - auto PC_val = (super::template get_reg(rs1 + traits::X0) < super::template get_reg(rs2 + traits::X0))? - (static_cast(cur_pc_val) + (imm)): - (cur_pc_val + 4); - super::template get_reg(traits::NEXT_PC) = PC_val; - auto is_cont_v = PC_val !=pc.val; - super::template get_reg(traits::LAST_BRANCH) = is_cont_v?1:0; - 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; + 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; } /* 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; - auto PC_val = (super::template get_reg(rs1 + traits::X0) >= super::template get_reg(rs2 + traits::X0))? - (static_cast(cur_pc_val) + (imm)): - (cur_pc_val + 4); - super::template get_reg(traits::NEXT_PC) = PC_val; - auto is_cont_v = PC_val !=pc.val; - super::template get_reg(traits::LAST_BRANCH) = is_cont_v?1:0; - 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; + 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; } /* 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; - auto offs_val = (static_cast(super::template get_reg(rs1 + traits::X0)) + (imm)); - if(rd != 0){ - auto Xtmp0_val = super::template sext(super::template read_mem(traits::MEM, offs_val)); - super::template get_reg(rd + traits::X0)=Xtmp0_val; - } - 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; + 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; } /* 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; - auto offs_val = (static_cast(super::template get_reg(rs1 + traits::X0)) + (imm)); - if(rd != 0){ - auto Xtmp0_val = super::template sext(super::template read_mem(traits::MEM, offs_val)); - super::template get_reg(rd + traits::X0)=Xtmp0_val; - } - 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; + 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; } /* 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; - auto offs_val = (static_cast(super::template get_reg(rs1 + traits::X0)) + (imm)); - if(rd != 0){ - auto Xtmp0_val = super::template sext(super::template read_mem(traits::MEM, offs_val)); - super::template get_reg(rd + traits::X0)=Xtmp0_val; - } - 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; + 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; } /* 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; - auto offs_val = (static_cast(super::template get_reg(rs1 + traits::X0)) + (imm)); - if(rd != 0){ - auto Xtmp0_val = super::template zext(super::template read_mem(traits::MEM, offs_val)); - super::template get_reg(rd + traits::X0)=Xtmp0_val; - } - 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; + 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; } /* 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; - auto offs_val = (static_cast(super::template get_reg(rs1 + traits::X0)) + (imm)); - if(rd != 0){ - auto Xtmp0_val = super::template zext(super::template read_mem(traits::MEM, offs_val)); - super::template get_reg(rd + traits::X0)=Xtmp0_val; - } - 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; + 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; } /* 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; - auto offs_val = (static_cast(super::template get_reg(rs1 + traits::X0)) + (imm)); - auto MEMtmp0_val = super::template get_reg(rs2 + traits::X0); - super::write_mem(traits::MEM, offs_val, static_cast(MEMtmp0_val)); - 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; + 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; } /* 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; - auto offs_val = (static_cast(super::template get_reg(rs1 + traits::X0)) + (imm)); - auto MEMtmp0_val = super::template get_reg(rs2 + traits::X0); - super::write_mem(traits::MEM, offs_val, static_cast(MEMtmp0_val)); - 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; + 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; } /* 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; - auto offs_val = (static_cast(super::template get_reg(rs1 + traits::X0)) + (imm)); - auto MEMtmp0_val = super::template get_reg(rs2 + traits::X0); - super::write_mem(traits::MEM, offs_val, static_cast(MEMtmp0_val)); - 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; + 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; } /* 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; - if(rd != 0){ - auto Xtmp0_val = (static_cast(super::template get_reg(rs1 + traits::X0)) + (imm)); - super::template get_reg(rd + traits::X0)=Xtmp0_val; - } - 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; + 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; } /* 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; - if(rd != 0){ - auto Xtmp0_val = (static_cast(super::template get_reg(rs1 + traits::X0)) < (imm))? - 1: - 0; - super::template get_reg(rd + traits::X0)=Xtmp0_val; - } - 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; + 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; } /* 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; - int32_t full_imm_val = imm; - if(rd != 0){ - auto Xtmp0_val = (super::template get_reg(rs1 + traits::X0) < full_imm_val)? - 1: - 0; - super::template get_reg(rd + traits::X0)=Xtmp0_val; - } - 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; + 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; } /* 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; - if(rd != 0){ - auto Xtmp0_val = (static_cast(super::template get_reg(rs1 + traits::X0)) ^ (imm)); - super::template get_reg(rd + traits::X0)=Xtmp0_val; - } - 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; + 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; } /* 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; - if(rd != 0){ - auto Xtmp0_val = (static_cast(super::template get_reg(rs1 + traits::X0)) | (imm)); - super::template get_reg(rd + traits::X0)=Xtmp0_val; - } - 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; + 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; } /* 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; - if(rd != 0){ - auto Xtmp0_val = (static_cast(super::template get_reg(rs1 + traits::X0)) & (imm)); - super::template get_reg(rd + traits::X0)=Xtmp0_val; - } - 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; + 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; } /* 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; - if(shamt > 31){ - raise_trap(0, 0); - } else { - if(rd != 0){ - auto Xtmp0_val = (super::template get_reg(rs1 + traits::X0)<<(shamt)); - super::template get_reg(rd + traits::X0)=Xtmp0_val; - } - } - 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; + 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; } /* 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; - if(shamt > 31){ - raise_trap(0, 0); - } else { - if(rd != 0){ - auto Xtmp0_val = (static_cast(super::template get_reg(rs1 + traits::X0))>>(shamt)); - super::template get_reg(rd + traits::X0)=Xtmp0_val; - } - } - 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; + 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; } /* 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; - if(shamt > 31){ - raise_trap(0, 0); - } else { - if(rd != 0){ - auto Xtmp0_val = (static_cast(super::template get_reg(rs1 + traits::X0))>>(shamt)); - super::template get_reg(rd + traits::X0)=Xtmp0_val; - } - } - 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; + 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; } /* 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; - if(rd != 0){ - auto Xtmp0_val = (super::template get_reg(rs1 + traits::X0) + super::template get_reg(rs2 + traits::X0)); - super::template get_reg(rd + traits::X0)=Xtmp0_val; - } - 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; + 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; } /* 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; - if(rd != 0){ - auto Xtmp0_val = (super::template get_reg(rs1 + traits::X0) - super::template get_reg(rs2 + traits::X0)); - super::template get_reg(rd + traits::X0)=Xtmp0_val; - } - 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; + 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; } /* 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; - if(rd != 0){ - auto Xtmp0_val = (super::template get_reg(rs1 + traits::X0)<<(super::template get_reg(rs2 + traits::X0) & ((32) - 1))); - super::template get_reg(rd + traits::X0)=Xtmp0_val; - } - 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; + 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; } /* 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; - if(rd != 0){ - auto Xtmp0_val = (static_cast(super::template get_reg(rs1 + traits::X0)) < static_cast(super::template get_reg(rs2 + traits::X0)))? - 1: - 0; - super::template get_reg(rd + traits::X0)=Xtmp0_val; - } - 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; + 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; } /* 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; - if(rd != 0){ - auto Xtmp0_val = (super::template zext(super::template get_reg(rs1 + traits::X0)) < super::template zext(super::template get_reg(rs2 + traits::X0)))? - 1: - 0; - super::template get_reg(rd + traits::X0)=Xtmp0_val; - } - 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; + 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; } /* 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; - if(rd != 0){ - auto Xtmp0_val = (super::template get_reg(rs1 + traits::X0) ^ super::template get_reg(rs2 + traits::X0)); - super::template get_reg(rd + traits::X0)=Xtmp0_val; - } - 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; + 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; } /* 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; - if(rd != 0){ - auto Xtmp0_val = (static_cast(super::template get_reg(rs1 + traits::X0))>>(super::template get_reg(rs2 + traits::X0) & ((32) - 1))); - super::template get_reg(rd + traits::X0)=Xtmp0_val; - } - 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; + 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; } /* 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; - if(rd != 0){ - auto Xtmp0_val = (static_cast(super::template get_reg(rs1 + traits::X0))>>(super::template get_reg(rs2 + traits::X0) & ((32) - 1))); - super::template get_reg(rd + traits::X0)=Xtmp0_val; - } - 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; + 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; } /* 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; - if(rd != 0){ - auto Xtmp0_val = (super::template get_reg(rs1 + traits::X0) | super::template get_reg(rs2 + traits::X0)); - super::template get_reg(rd + traits::X0)=Xtmp0_val; - } - 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; + 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; } /* 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; - if(rd != 0){ - auto Xtmp0_val = (super::template get_reg(rs1 + traits::X0) & super::template get_reg(rs2 + traits::X0)); - super::template get_reg(rd + traits::X0)=Xtmp0_val; - } - 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; + 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; } /* 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; - auto FENCEtmp0_val = (((pred) << 4) | (succ)); - super::write_mem(traits::FENCE, (0), static_cast(FENCEtmp0_val)); - 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; + 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; } /* 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; - auto FENCEtmp0_val = (imm); - super::write_mem(traits::FENCE, (1), static_cast(FENCEtmp0_val)); - 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; + 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; } /* 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; - raise_trap(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; + 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; } /* 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; - raise_trap(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; + 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; } /* 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; - leave_trap(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; + 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; } /* 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; - leave_trap(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; + 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; } /* 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; - leave_trap(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; + 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; } /* 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; - 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; + 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; } - /* instruction 45: SFENCE.VMA */ + /* 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; - auto FENCEtmp0_val = (rs1); - super::write_mem(traits::FENCE, (2), static_cast(FENCEtmp0_val)); - auto FENCEtmp1_val = (rs2); - super::write_mem(traits::FENCE, (3), static_cast(FENCEtmp1_val)); - 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; + 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; } /* 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; - auto rs_val_val = super::template get_reg(rs1 + traits::X0); - if(rd != 0){ - auto csr_val_val = super::template read_mem(traits::CSR, (csr)); - auto CSRtmp0_val = rs_val_val; - super::write_mem(traits::CSR, (csr), static_cast(CSRtmp0_val)); - auto Xtmp1_val = csr_val_val; - super::template get_reg(rd + traits::X0)=Xtmp1_val; - } else { - auto CSRtmp2_val = rs_val_val; - super::write_mem(traits::CSR, (csr), static_cast(CSRtmp2_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; + 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; } /* 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; - auto xrd_val = super::template read_mem(traits::CSR, (csr)); - auto xrs1_val = super::template get_reg(rs1 + traits::X0); - if(rd != 0){ - auto Xtmp0_val = xrd_val; - super::template get_reg(rd + traits::X0)=Xtmp0_val; - } - if(rs1 != 0){ - auto CSRtmp1_val = (xrd_val | xrs1_val); - super::write_mem(traits::CSR, (csr), static_cast(CSRtmp1_val)); - } - 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; + 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; } /* 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; - auto xrd_val = super::template read_mem(traits::CSR, (csr)); - auto xrs1_val = super::template get_reg(rs1 + traits::X0); - if(rd != 0){ - auto Xtmp0_val = xrd_val; - super::template get_reg(rd + traits::X0)=Xtmp0_val; - } - if(rs1 != 0){ - auto CSRtmp1_val = (xrd_val & ~(xrs1_val)); - super::write_mem(traits::CSR, (csr), static_cast(CSRtmp1_val)); - } - 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; + 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; } /* 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; - if(rd != 0){ - auto Xtmp0_val = super::template read_mem(traits::CSR, (csr)); - super::template get_reg(rd + traits::X0)=Xtmp0_val; - } - auto CSRtmp1_val = super::template zext((zimm)); - super::write_mem(traits::CSR, (csr), static_cast(CSRtmp1_val)); - 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; + 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; } /* 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; - auto res_val = super::template read_mem(traits::CSR, (csr)); - if(zimm != 0){ - auto CSRtmp0_val = (res_val | super::template zext((zimm))); - super::write_mem(traits::CSR, (csr), static_cast(CSRtmp0_val)); - } - if(rd != 0){ - auto Xtmp1_val = res_val; - super::template get_reg(rd + traits::X0)=Xtmp1_val; - } - 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; + 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; } /* 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; - auto res_val = super::template read_mem(traits::CSR, (csr)); - if(rd != 0){ - auto Xtmp0_val = res_val; - super::template get_reg(rd + traits::X0)=Xtmp0_val; - } - if(zimm != 0){ - auto CSRtmp1_val = (res_val & ~(super::template zext((zimm)))); - super::write_mem(traits::CSR, (csr), static_cast(CSRtmp1_val)); - } - 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; + 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; } /* 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; - if(rd != 0){ - auto res_val = (super::template zext(super::template get_reg(rs1 + traits::X0)) * super::template zext(super::template get_reg(rs2 + traits::X0))); - auto Xtmp0_val = super::template zext(res_val); - super::template get_reg(rd + traits::X0)=Xtmp0_val; - } - 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; + 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; } /* 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; - if(rd != 0){ - auto res_val = (super::template sext(super::template get_reg(rs1 + traits::X0)) * super::template sext(super::template get_reg(rs2 + traits::X0))); - auto Xtmp0_val = super::template zext((res_val >> (32))); - super::template get_reg(rd + traits::X0)=Xtmp0_val; - } - 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; + 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; } /* 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; - if(rd != 0){ - auto res_val = (super::template sext(super::template get_reg(rs1 + traits::X0)) * super::template zext(super::template get_reg(rs2 + traits::X0))); - auto Xtmp0_val = super::template zext((res_val >> (32))); - super::template get_reg(rd + traits::X0)=Xtmp0_val; - } - 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; + 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; } /* 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; - if(rd != 0){ - auto res_val = (super::template zext(super::template get_reg(rs1 + traits::X0)) * super::template zext(super::template get_reg(rs2 + traits::X0))); - auto Xtmp0_val = super::template zext((res_val >> (32))); - super::template get_reg(rd + traits::X0)=Xtmp0_val; - } - 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; + 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; } /* 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; - if(rd != 0){ - { - if((super::template get_reg(rs2 + traits::X0) != 0)) { - uint32_t M1_val = - 1; - uint8_t XLM1_val = 32 - 1; - uint32_t ONE_val = 1; - uint32_t MMIN_val = ONE_val << XLM1_val; - { - if(((super::template get_reg(rs1 + traits::X0) == MMIN_val) && (super::template get_reg(rs2 + traits::X0) == M1_val))) { - auto Xtmp0_val = MMIN_val; - super::template get_reg(rd + traits::X0)=Xtmp0_val; - } - else { - auto Xtmp1_val = (static_cast(super::template get_reg(rs1 + traits::X0)) / static_cast(super::template get_reg(rs2 + traits::X0))); - super::template get_reg(rd + traits::X0)=Xtmp1_val; - } - } - } - else { - auto Xtmp2_val = -(1); - super::template get_reg(rd + traits::X0)=Xtmp2_val; - } - } - } - 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; + 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; } /* 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; - if(rd != 0){ - { - if((super::template get_reg(rs2 + traits::X0) != 0)) { - auto Xtmp0_val = (super::template get_reg(rs1 + traits::X0) / super::template get_reg(rs2 + traits::X0)); - super::template get_reg(rd + traits::X0)=Xtmp0_val; - } - else { - auto Xtmp1_val = -(1); - super::template get_reg(rd + traits::X0)=Xtmp1_val; - } - } - } - 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; + 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; } /* 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; - if(rd != 0){ - { - if((super::template get_reg(rs2 + traits::X0) != 0)) { - uint32_t M1_val = - 1; - uint32_t XLM1_val = 32 - 1; - uint32_t ONE_val = 1; - uint32_t MMIN_val = ONE_val << XLM1_val; - { - if(((super::template get_reg(rs1 + traits::X0) == MMIN_val) && (super::template get_reg(rs2 + traits::X0) == M1_val))) { - auto Xtmp0_val = 0; - super::template get_reg(rd + traits::X0)=Xtmp0_val; - } - else { - auto Xtmp1_val = (static_cast(super::template get_reg(rs1 + traits::X0)) % static_cast(super::template get_reg(rs2 + traits::X0))); - super::template get_reg(rd + traits::X0)=Xtmp1_val; - } - } - } - else { - auto Xtmp2_val = super::template get_reg(rs1 + traits::X0); - super::template get_reg(rd + traits::X0)=Xtmp2_val; - } - } - } - 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; + 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; } /* 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; - if(rd != 0){ - { - if((super::template get_reg(rs2 + traits::X0) != 0)) { - auto Xtmp0_val = (super::template get_reg(rs1 + traits::X0) % super::template get_reg(rs2 + traits::X0)); - super::template get_reg(rd + traits::X0)=Xtmp0_val; - } - else { - auto Xtmp1_val = super::template get_reg(rs1 + traits::X0); - super::template get_reg(rd + traits::X0)=Xtmp1_val; - } - } - } - 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; + 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; } - /* instruction 60: C.ADDI4SPN */ - compile_ret_t __c_addi4spn(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", "c.addi4spn"), - 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; - if(imm == 0){ - raise_trap(0, 2); - } - auto Xtmp0_val = (super::template get_reg(2 + traits::X0) + (imm)); - super::template get_reg(rd + 8 + traits::X0)=Xtmp0_val; - 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; + /* 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; } - /* instruction 61: C.LW */ - compile_ret_t __c_lw(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", "c.lw"), - 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; - auto offs_val = (super::template get_reg(rs1 + 8 + traits::X0) + (uimm)); - auto Xtmp0_val = super::template sext(super::template read_mem(traits::MEM, offs_val)); - super::template get_reg(rd + 8 + traits::X0)=Xtmp0_val; - 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; + /* 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; } - /* instruction 62: C.SW */ - compile_ret_t __c_sw(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", "c.sw"), - 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; - auto offs_val = (super::template get_reg(rs1 + 8 + traits::X0) + (uimm)); - auto MEMtmp0_val = super::template get_reg(rs2 + 8 + traits::X0); - super::write_mem(traits::MEM, offs_val, static_cast(MEMtmp0_val)); - 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; + /* 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; } - /* instruction 63: C.ADDI */ - compile_ret_t __c_addi(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", "c.addi"), - 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; - auto Xtmp0_val = (static_cast(super::template get_reg(rs1 + traits::X0)) + (imm)); - super::template get_reg(rs1 + traits::X0)=Xtmp0_val; - 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; + /* 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; } - /* instruction 64: C.NOP */ - compile_ret_t __c_nop(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, "c.nop"); - } - - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 2; - /* TODO: describe operations for C.NOP ! */ - 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; + /* 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; } - /* instruction 65: C.JAL */ - compile_ret_t __c_jal(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", "c.jal"), - 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; - auto Xtmp0_val = (cur_pc_val + 2); - super::template get_reg(1 + traits::X0)=Xtmp0_val; - auto PC_val = (static_cast(cur_pc_val) + (imm)); - super::template get_reg(traits::NEXT_PC) = PC_val; - auto is_cont_v = PC_val !=pc.val; - super::template get_reg(traits::LAST_BRANCH) = is_cont_v?1:0; - 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; + /* 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; } - /* instruction 66: C.LI */ - compile_ret_t __c_li(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", "c.li"), - 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; - if(rd == 0){ - raise_trap(0, 2); - } - auto Xtmp0_val = (imm); - super::template get_reg(rd + traits::X0)=Xtmp0_val; - 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; + /* 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; } - /* instruction 67: C.LUI */ - compile_ret_t __c_lui(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", "c.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 + 2; - if(rd == 0){ - raise_trap(0, 2); - } - if(imm == 0){ - raise_trap(0, 2); - } - auto Xtmp0_val = (imm); - super::template get_reg(rd + traits::X0)=Xtmp0_val; - 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; + /* 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; } - /* instruction 68: C.ADDI16SP */ - compile_ret_t __c_addi16sp(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", "c.addi16sp"), - 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; - auto Xtmp0_val = (static_cast(super::template get_reg(2 + traits::X0)) + (imm)); - super::template get_reg(2 + traits::X0)=Xtmp0_val; - 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; + /* 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; } - /* instruction 69: C.SRLI */ - compile_ret_t __c_srli(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", "c.srli"), - 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; - uint8_t rs1_idx_val = rs1 + 8; - auto Xtmp0_val = (static_cast(super::template get_reg(rs1_idx_val + traits::X0))>>(shamt)); - super::template get_reg(rs1_idx_val + traits::X0)=Xtmp0_val; - 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; + /* 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; } - /* instruction 70: C.SRAI */ - compile_ret_t __c_srai(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", "c.srai"), - 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; - uint8_t rs1_idx_val = rs1 + 8; - auto Xtmp0_val = (static_cast(super::template get_reg(rs1_idx_val + traits::X0))>>(shamt)); - super::template get_reg(rs1_idx_val + traits::X0)=Xtmp0_val; - 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; + /* 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; } - /* instruction 71: C.ANDI */ - compile_ret_t __c_andi(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", "c.andi"), - 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; - uint8_t rs1_idx_val = rs1 + 8; - auto Xtmp0_val = (static_cast(super::template get_reg(rs1_idx_val + traits::X0)) & (imm)); - super::template get_reg(rs1_idx_val + traits::X0)=Xtmp0_val; - 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; + /* 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; } - /* instruction 72: C.SUB */ - compile_ret_t __c_sub(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", "c.sub"), - 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; - uint8_t rd_idx_val = rd + 8; - auto Xtmp0_val = (super::template get_reg(rd_idx_val + traits::X0) - super::template get_reg(rs2 + 8 + traits::X0)); - super::template get_reg(rd_idx_val + traits::X0)=Xtmp0_val; - 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; + /* 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; } - /* instruction 73: C.XOR */ - compile_ret_t __c_xor(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", "c.xor"), - 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; - uint8_t rd_idx_val = rd + 8; - auto Xtmp0_val = (super::template get_reg(rd_idx_val + traits::X0) ^ super::template get_reg(rs2 + 8 + traits::X0)); - super::template get_reg(rd_idx_val + traits::X0)=Xtmp0_val; - 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; + /* 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; } - /* instruction 74: C.OR */ - compile_ret_t __c_or(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", "c.or"), - 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; - uint8_t rd_idx_val = rd + 8; - auto Xtmp0_val = (super::template get_reg(rd_idx_val + traits::X0) | super::template get_reg(rs2 + 8 + traits::X0)); - super::template get_reg(rd_idx_val + traits::X0)=Xtmp0_val; - 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; + /* 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; } - /* instruction 75: C.AND */ - compile_ret_t __c_and(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", "c.and"), - 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; - uint8_t rd_idx_val = rd + 8; - auto Xtmp0_val = (super::template get_reg(rd_idx_val + traits::X0) & super::template get_reg(rs2 + 8 + traits::X0)); - super::template get_reg(rd_idx_val + traits::X0)=Xtmp0_val; - 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; + /* 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; } - /* instruction 76: C.J */ - compile_ret_t __c_j(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", "c.j"), - 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; - auto PC_val = (static_cast(cur_pc_val) + (imm)); - super::template get_reg(traits::NEXT_PC) = PC_val; - auto is_cont_v = PC_val !=pc.val; - super::template get_reg(traits::LAST_BRANCH) = is_cont_v?1:0; - 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; + /* 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; } - /* instruction 77: C.BEQZ */ - compile_ret_t __c_beqz(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", "c.beqz"), - 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; - auto PC_val = (super::template get_reg(rs1 + 8 + traits::X0) == 0)? - (static_cast(cur_pc_val) + (imm)): - (cur_pc_val + 2); - super::template get_reg(traits::NEXT_PC) = PC_val; - auto is_cont_v = PC_val !=pc.val; - super::template get_reg(traits::LAST_BRANCH) = is_cont_v?1:0; - 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; + /* 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; } - /* instruction 78: C.BNEZ */ - compile_ret_t __c_bnez(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", "c.bnez"), - 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; - auto PC_val = (super::template get_reg(rs1 + 8 + traits::X0) != 0)? - (static_cast(cur_pc_val) + (imm)): - (cur_pc_val + 2); - super::template get_reg(traits::NEXT_PC) = PC_val; - auto is_cont_v = PC_val !=pc.val; - super::template get_reg(traits::LAST_BRANCH) = is_cont_v?1:0; - 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; + /* 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; } - /* instruction 79: C.SLLI */ - compile_ret_t __c_slli(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", "c.slli"), - 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; - if(rs1 == 0){ - raise_trap(0, 2); - } - auto Xtmp0_val = (super::template get_reg(rs1 + traits::X0)<<(shamt)); - super::template get_reg(rs1 + traits::X0)=Xtmp0_val; - 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; + /* 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; } - /* instruction 80: C.LWSP */ - compile_ret_t __c_lwsp(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", "c.lwsp"), - 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; - auto offs_val = (super::template get_reg(2 + traits::X0) + (uimm)); - auto Xtmp0_val = super::template sext(super::template read_mem(traits::MEM, offs_val)); - super::template get_reg(rd + traits::X0)=Xtmp0_val; - 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; + /* 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; } - /* instruction 81: C.MV */ - compile_ret_t __c_mv(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", "c.mv"), - 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; - auto Xtmp0_val = super::template get_reg(rs2 + traits::X0); - super::template get_reg(rd + traits::X0)=Xtmp0_val; - 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; + /* 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; } - /* instruction 82: C.JR */ - compile_ret_t __c_jr(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", "c.jr"), - 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; - auto PC_val = super::template get_reg(rs1 + traits::X0); - super::template get_reg(traits::NEXT_PC) = PC_val; - super::template get_reg(traits::LAST_BRANCH) = std::numeric_limits::max(); - 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; + /* 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; } - /* instruction 83: C.ADD */ - compile_ret_t __c_add(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", "c.add"), - 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; - auto Xtmp0_val = (super::template get_reg(rd + traits::X0) + super::template get_reg(rs2 + traits::X0)); - super::template get_reg(rd + traits::X0)=Xtmp0_val; - 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; + /* 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; } - /* instruction 84: C.JALR */ - compile_ret_t __c_jalr(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", "c.jalr"), - 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; - auto Xtmp0_val = (cur_pc_val + 2); - super::template get_reg(1 + traits::X0)=Xtmp0_val; - auto PC_val = super::template get_reg(rs1 + traits::X0); - super::template get_reg(traits::NEXT_PC) = PC_val; - super::template get_reg(traits::LAST_BRANCH) = std::numeric_limits::max(); - 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; + /* 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; } - /* instruction 85: C.EBREAK */ - compile_ret_t __c_ebreak(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, "c.ebreak"); - } - - auto cur_pc_val = pc.val; - super::template get_reg(arch::traits::NEXT_PC) = cur_pc_val + 2; - raise_trap(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; + /* 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; } - /* instruction 86: C.SWSP */ - compile_ret_t __c_swsp(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", "c.swsp"), - 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; - auto offs_val = (super::template get_reg(2 + traits::X0) + (uimm)); - auto MEMtmp0_val = super::template get_reg(rs2 + traits::X0); - super::write_mem(traits::MEM, offs_val, static_cast(MEMtmp0_val)); - 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; + /* 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; } /* 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; - raise_trap(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; + 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; } /**************************************************************************** @@ -3288,7 +3093,7 @@ template typename vm_base::virt_addr_t vm_impl::execute_inst(virt_addr_t start, std::function pred) { // we fetch at max 4 byte, alignment is 2 enum {TRAP_ID=1<<16}; - const typename traits::addr_t upper_bits = ~traits::PGMASK; + const typename traits::addr_t upper_bits = ~traits::PGMASK; code_word_t insn = 0; auto *const data = (uint8_t *)&insn; auto pc=start;