allows functions in interp and updates generated
This commit is contained in:
		@@ -15,59 +15,51 @@ RV32I:
 | 
			
		||||
  - JAL:
 | 
			
		||||
    encoding: 0b00000000000000000000000001101111
 | 
			
		||||
    mask: 0b00000000000000000000000001111111
 | 
			
		||||
    attributes: [[name:no_cont]]
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   true
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - JALR:
 | 
			
		||||
    encoding: 0b00000000000000000000000001100111
 | 
			
		||||
    mask: 0b00000000000000000111000001111111
 | 
			
		||||
    attributes: [[name:no_cont]]
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   true
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - BEQ:
 | 
			
		||||
    encoding: 0b00000000000000000000000001100011
 | 
			
		||||
    mask: 0b00000000000000000111000001111111
 | 
			
		||||
    attributes: [[name:no_cont], [name:cond]]
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   true
 | 
			
		||||
    delay:   [1,1]
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - BNE:
 | 
			
		||||
    encoding: 0b00000000000000000001000001100011
 | 
			
		||||
    mask: 0b00000000000000000111000001111111
 | 
			
		||||
    attributes: [[name:no_cont], [name:cond]]
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   true
 | 
			
		||||
    delay:   [1,1]
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - BLT:
 | 
			
		||||
    encoding: 0b00000000000000000100000001100011
 | 
			
		||||
    mask: 0b00000000000000000111000001111111
 | 
			
		||||
    attributes: [[name:no_cont], [name:cond]]
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   true
 | 
			
		||||
    delay:   [1,1]
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - BGE:
 | 
			
		||||
    encoding: 0b00000000000000000101000001100011
 | 
			
		||||
    mask: 0b00000000000000000111000001111111
 | 
			
		||||
    attributes: [[name:no_cont], [name:cond]]
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   true
 | 
			
		||||
    delay:   [1,1]
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - BLTU:
 | 
			
		||||
    encoding: 0b00000000000000000110000001100011
 | 
			
		||||
    mask: 0b00000000000000000111000001111111
 | 
			
		||||
    attributes: [[name:no_cont], [name:cond]]
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   true
 | 
			
		||||
    delay:   [1,1]
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - BGEU:
 | 
			
		||||
    encoding: 0b00000000000000000111000001100011
 | 
			
		||||
    mask: 0b00000000000000000111000001111111
 | 
			
		||||
    attributes: [[name:no_cont], [name:cond]]
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   true
 | 
			
		||||
    delay:   [1,1]
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - LB:
 | 
			
		||||
    encoding: 0b00000000000000000000000000000011
 | 
			
		||||
    mask: 0b00000000000000000111000001111111
 | 
			
		||||
@@ -239,14 +231,12 @@ RV32I:
 | 
			
		||||
  - ECALL:
 | 
			
		||||
    encoding: 0b00000000000000000000000001110011
 | 
			
		||||
    mask: 0b11111111111111111111111111111111
 | 
			
		||||
    attributes: [[name:no_cont]]
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - EBREAK:
 | 
			
		||||
    encoding: 0b00000000000100000000000001110011
 | 
			
		||||
    mask: 0b11111111111111111111111111111111
 | 
			
		||||
    attributes: [[name:no_cont]]
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
@@ -391,7 +381,6 @@ RV32IC:
 | 
			
		||||
  - CJAL:
 | 
			
		||||
    encoding: 0b0010000000000001
 | 
			
		||||
    mask: 0b1110000000000011
 | 
			
		||||
    attributes: [[name:no_cont]]
 | 
			
		||||
    size:   16
 | 
			
		||||
    branch:   true
 | 
			
		||||
    delay:   1
 | 
			
		||||
@@ -458,24 +447,21 @@ RV32IC:
 | 
			
		||||
  - CJ:
 | 
			
		||||
    encoding: 0b1010000000000001
 | 
			
		||||
    mask: 0b1110000000000011
 | 
			
		||||
    attributes: [[name:no_cont]]
 | 
			
		||||
    size:   16
 | 
			
		||||
    branch:   true
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - CBEQZ:
 | 
			
		||||
    encoding: 0b1100000000000001
 | 
			
		||||
    mask: 0b1110000000000011
 | 
			
		||||
    attributes: [[name:no_cont], [name:cond]]
 | 
			
		||||
    size:   16
 | 
			
		||||
    branch:   true
 | 
			
		||||
    delay:   [1,1]
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - CBNEZ:
 | 
			
		||||
    encoding: 0b1110000000000001
 | 
			
		||||
    mask: 0b1110000000000011
 | 
			
		||||
    attributes: [[name:no_cont], [name:cond]]
 | 
			
		||||
    size:   16
 | 
			
		||||
    branch:   true
 | 
			
		||||
    delay:   [1,1]
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - CSLLI:
 | 
			
		||||
    encoding: 0b0000000000000010
 | 
			
		||||
    mask: 0b1111000000000011
 | 
			
		||||
@@ -497,7 +483,6 @@ RV32IC:
 | 
			
		||||
  - CJR:
 | 
			
		||||
    encoding: 0b1000000000000010
 | 
			
		||||
    mask: 0b1111000001111111
 | 
			
		||||
    attributes: [[name:no_cont]]
 | 
			
		||||
    size:   16
 | 
			
		||||
    branch:   true
 | 
			
		||||
    delay:   1
 | 
			
		||||
@@ -510,14 +495,12 @@ RV32IC:
 | 
			
		||||
  - CJALR:
 | 
			
		||||
    encoding: 0b1001000000000010
 | 
			
		||||
    mask: 0b1111000001111111
 | 
			
		||||
    attributes: [[name:no_cont]]
 | 
			
		||||
    size:   16
 | 
			
		||||
    branch:   true
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - CEBREAK:
 | 
			
		||||
    encoding: 0b1001000000000010
 | 
			
		||||
    mask: 0b1111111111111111
 | 
			
		||||
    attributes: [[name:no_cont]]
 | 
			
		||||
    size:   16
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
@@ -530,7 +513,6 @@ RV32IC:
 | 
			
		||||
  - DII:
 | 
			
		||||
    encoding: 0b0000000000000000
 | 
			
		||||
    mask: 0b1111111111111111
 | 
			
		||||
    attributes: [[name:no_cont]]
 | 
			
		||||
    size:   16
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
 
 | 
			
		||||
@@ -43,6 +43,7 @@ def nativeTypeSize(int size){
 | 
			
		||||
#include <sstream>
 | 
			
		||||
#include <boost/coroutine2/all.hpp>
 | 
			
		||||
#include <functional>
 | 
			
		||||
#include <exception>
 | 
			
		||||
 | 
			
		||||
#ifndef FMT_HEADER_ONLY
 | 
			
		||||
#define FMT_HEADER_ONLY
 | 
			
		||||
@@ -59,6 +60,10 @@ using namespace iss::arch;
 | 
			
		||||
using namespace iss::debugger;
 | 
			
		||||
using namespace std::placeholders;
 | 
			
		||||
 | 
			
		||||
struct memory_access_exception : public std::exception{
 | 
			
		||||
    memory_access_exception(){}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename ARCH> class vm_impl : public iss::interp::vm_base<ARCH> {
 | 
			
		||||
public:
 | 
			
		||||
    using traits = arch::traits<ARCH>;
 | 
			
		||||
@@ -91,30 +96,9 @@ protected:
 | 
			
		||||
 | 
			
		||||
    inline const char *name(size_t index){return index<traits::reg_aliases.size()?traits::reg_aliases[index]:"illegal";}
 | 
			
		||||
 | 
			
		||||
    typename arch::traits<ARCH>::opcode_e decode_inst_id(code_word_t instr);
 | 
			
		||||
    virt_addr_t execute_inst(finish_cond_e cond, virt_addr_t start, uint64_t icount_limit) override;
 | 
			
		||||
 | 
			
		||||
    // some compile time constants
 | 
			
		||||
    // enum { MASK16 = 0b1111110001100011, MASK32 = 0b11111111111100000111000001111111 };
 | 
			
		||||
    enum { MASK16 = 0b1111111111111111, MASK32 = 0b11111111111100000111000001111111 };
 | 
			
		||||
    enum { EXTR_MASK16 = MASK16 >> 2, EXTR_MASK32 = MASK32 >> 2 };
 | 
			
		||||
    enum {
 | 
			
		||||
        LUT_SIZE = 1 << util::bit_count(static_cast<uint32_t>(EXTR_MASK32)),
 | 
			
		||||
        LUT_SIZE_C = 1 << util::bit_count(static_cast<uint32_t>(EXTR_MASK16))
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    std::array<compile_func, LUT_SIZE> lut;
 | 
			
		||||
 | 
			
		||||
    std::array<compile_func, LUT_SIZE_C> lut_00, lut_01, lut_10;
 | 
			
		||||
    std::array<compile_func, LUT_SIZE> lut_11;
 | 
			
		||||
 | 
			
		||||
    struct instruction_pattern {
 | 
			
		||||
        uint32_t value;
 | 
			
		||||
        uint32_t mask;
 | 
			
		||||
        typename arch::traits<ARCH>::opcode_e id;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    std::array<std::vector<instruction_pattern>, 4> qlut;
 | 
			
		||||
 | 
			
		||||
    inline void raise(uint16_t trap_id, uint16_t cause){
 | 
			
		||||
        auto trap_val =  0x80ULL << 24 | (cause << 16) | trap_id;
 | 
			
		||||
@@ -314,6 +298,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
            // pre execution stuff
 | 
			
		||||
             this->core.reg.last_branch = 0;
 | 
			
		||||
            if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, static_cast<unsigned>(inst_id));
 | 
			
		||||
            try{
 | 
			
		||||
                switch(inst_id){<%instructions.eachWithIndex{instr, idx -> %>
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::${instr.name}: {
 | 
			
		||||
                    <%instr.fields.eachLine{%>${it}
 | 
			
		||||
@@ -329,13 +314,14 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                    *NEXT_PC = *PC + ${instr.length/8};
 | 
			
		||||
                    // execute instruction<%instr.behavior.eachLine{%>
 | 
			
		||||
                    ${it}<%}%>
 | 
			
		||||
                TRAP_${instr.name}:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")<%}%>
 | 
			
		||||
                default: {
 | 
			
		||||
                    *NEXT_PC = *PC + ((instr & 3) == 3 ? 4 : 2);
 | 
			
		||||
                    raise(0,  2);
 | 
			
		||||
                }
 | 
			
		||||
                }
 | 
			
		||||
            }catch(memory_access_exception& e){}
 | 
			
		||||
            // post execution stuff
 | 
			
		||||
            process_spawn_blocks();
 | 
			
		||||
            if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, static_cast<unsigned>(inst_id));
 | 
			
		||||
 
 | 
			
		||||
@@ -167,8 +167,9 @@ private:
 | 
			
		||||
        auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]);
 | 
			
		||||
        pc=pc+ ${instr.length/8};
 | 
			
		||||
        gen_set_pc(tu, pc, traits::NEXT_PC);
 | 
			
		||||
        tu.open_scope();<%instr.behavior.eachLine{%>
 | 
			
		||||
        ${it}<%}%>
 | 
			
		||||
        tu.open_scope();
 | 
			
		||||
        <%instr.behavior.eachLine{%>${it}
 | 
			
		||||
        <%}%>
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,${idx});
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
 
 | 
			
		||||
@@ -39,6 +39,7 @@
 | 
			
		||||
#include <sstream>
 | 
			
		||||
#include <boost/coroutine2/all.hpp>
 | 
			
		||||
#include <functional>
 | 
			
		||||
#include <exception>
 | 
			
		||||
 | 
			
		||||
#ifndef FMT_HEADER_ONLY
 | 
			
		||||
#define FMT_HEADER_ONLY
 | 
			
		||||
@@ -55,6 +56,10 @@ using namespace iss::arch;
 | 
			
		||||
using namespace iss::debugger;
 | 
			
		||||
using namespace std::placeholders;
 | 
			
		||||
 | 
			
		||||
struct memory_access_exception : public std::exception{
 | 
			
		||||
    memory_access_exception(){}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename ARCH> class vm_impl : public iss::interp::vm_base<ARCH> {
 | 
			
		||||
public:
 | 
			
		||||
    using traits = arch::traits<ARCH>;
 | 
			
		||||
@@ -87,30 +92,9 @@ protected:
 | 
			
		||||
 | 
			
		||||
    inline const char *name(size_t index){return index<traits::reg_aliases.size()?traits::reg_aliases[index]:"illegal";}
 | 
			
		||||
 | 
			
		||||
    typename arch::traits<ARCH>::opcode_e decode_inst_id(code_word_t instr);
 | 
			
		||||
    virt_addr_t execute_inst(finish_cond_e cond, virt_addr_t start, uint64_t icount_limit) override;
 | 
			
		||||
 | 
			
		||||
    // some compile time constants
 | 
			
		||||
    // enum { MASK16 = 0b1111110001100011, MASK32 = 0b11111111111100000111000001111111 };
 | 
			
		||||
    enum { MASK16 = 0b1111111111111111, MASK32 = 0b11111111111100000111000001111111 };
 | 
			
		||||
    enum { EXTR_MASK16 = MASK16 >> 2, EXTR_MASK32 = MASK32 >> 2 };
 | 
			
		||||
    enum {
 | 
			
		||||
        LUT_SIZE = 1 << util::bit_count(static_cast<uint32_t>(EXTR_MASK32)),
 | 
			
		||||
        LUT_SIZE_C = 1 << util::bit_count(static_cast<uint32_t>(EXTR_MASK16))
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    std::array<compile_func, LUT_SIZE> lut;
 | 
			
		||||
 | 
			
		||||
    std::array<compile_func, LUT_SIZE_C> lut_00, lut_01, lut_10;
 | 
			
		||||
    std::array<compile_func, LUT_SIZE> lut_11;
 | 
			
		||||
 | 
			
		||||
    struct instruction_pattern {
 | 
			
		||||
        uint32_t value;
 | 
			
		||||
        uint32_t mask;
 | 
			
		||||
        typename arch::traits<ARCH>::opcode_e id;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    std::array<std::vector<instruction_pattern>, 4> qlut;
 | 
			
		||||
 | 
			
		||||
    inline void raise(uint16_t trap_id, uint16_t cause){
 | 
			
		||||
        auto trap_val =  0x80ULL << 24 | (cause << 16) | trap_id;
 | 
			
		||||
@@ -394,6 +378,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
            // pre execution stuff
 | 
			
		||||
             this->core.reg.last_branch = 0;
 | 
			
		||||
            if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, static_cast<unsigned>(inst_id));
 | 
			
		||||
            try{
 | 
			
		||||
                switch(inst_id){
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::LUI: {
 | 
			
		||||
                    uint8_t rd = ((bit_sub<7,5>(instr)));
 | 
			
		||||
@@ -419,7 +404,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_LUI:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::AUIPC: {
 | 
			
		||||
                    uint8_t rd = ((bit_sub<7,5>(instr)));
 | 
			
		||||
@@ -445,7 +430,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_AUIPC:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::JAL: {
 | 
			
		||||
                    uint8_t rd = ((bit_sub<7,5>(instr)));
 | 
			
		||||
@@ -478,7 +463,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_JAL:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::JALR: {
 | 
			
		||||
                    uint8_t rd = ((bit_sub<7,5>(instr)));
 | 
			
		||||
@@ -513,7 +498,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_JALR:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::BEQ: {
 | 
			
		||||
                    uint16_t imm = ((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12));
 | 
			
		||||
@@ -546,7 +531,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_BEQ:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::BNE: {
 | 
			
		||||
                    uint16_t imm = ((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12));
 | 
			
		||||
@@ -579,7 +564,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_BNE:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::BLT: {
 | 
			
		||||
                    uint16_t imm = ((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12));
 | 
			
		||||
@@ -612,7 +597,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_BLT:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::BGE: {
 | 
			
		||||
                    uint16_t imm = ((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12));
 | 
			
		||||
@@ -645,7 +630,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_BGE:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::BLTU: {
 | 
			
		||||
                    uint16_t imm = ((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12));
 | 
			
		||||
@@ -678,7 +663,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_BLTU:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::BGEU: {
 | 
			
		||||
                    uint16_t imm = ((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12));
 | 
			
		||||
@@ -711,7 +696,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_BGEU:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::LB: {
 | 
			
		||||
                    uint8_t rd = ((bit_sub<7,5>(instr)));
 | 
			
		||||
@@ -735,14 +720,14 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                    else {
 | 
			
		||||
                                        uint32_t load_address = (uint32_t)(*(X+rs1) + (int16_t)sext<12>(imm));
 | 
			
		||||
                                        int8_t read_res = super::template read_mem<int8_t>(traits::MEM, load_address);
 | 
			
		||||
                                    if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_LB;
 | 
			
		||||
                                        if(this->core.reg.trap_state>=0x80000000UL) throw memory_access_exception();
 | 
			
		||||
                                        int8_t res = (int8_t)read_res;
 | 
			
		||||
                                        if(rd !=  0) {
 | 
			
		||||
                                            *(X+rd) = (uint32_t)res;
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_LB:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::LH: {
 | 
			
		||||
                    uint8_t rd = ((bit_sub<7,5>(instr)));
 | 
			
		||||
@@ -766,14 +751,14 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                    else {
 | 
			
		||||
                                        uint32_t load_address = (uint32_t)(*(X+rs1) + (int16_t)sext<12>(imm));
 | 
			
		||||
                                        int16_t read_res = super::template read_mem<int16_t>(traits::MEM, load_address);
 | 
			
		||||
                                    if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_LH;
 | 
			
		||||
                                        if(this->core.reg.trap_state>=0x80000000UL) throw memory_access_exception();
 | 
			
		||||
                                        int16_t res = (int16_t)read_res;
 | 
			
		||||
                                        if(rd !=  0) {
 | 
			
		||||
                                            *(X+rd) = (uint32_t)res;
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_LH:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::LW: {
 | 
			
		||||
                    uint8_t rd = ((bit_sub<7,5>(instr)));
 | 
			
		||||
@@ -797,14 +782,14 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                    else {
 | 
			
		||||
                                        uint32_t load_address = (uint32_t)(*(X+rs1) + (int16_t)sext<12>(imm));
 | 
			
		||||
                                        int32_t read_res = super::template read_mem<int32_t>(traits::MEM, load_address);
 | 
			
		||||
                                    if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_LW;
 | 
			
		||||
                                        if(this->core.reg.trap_state>=0x80000000UL) throw memory_access_exception();
 | 
			
		||||
                                        int32_t res = (int32_t)read_res;
 | 
			
		||||
                                        if(rd !=  0) {
 | 
			
		||||
                                            *(X+rd) = (uint32_t)res;
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_LW:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::LBU: {
 | 
			
		||||
                    uint8_t rd = ((bit_sub<7,5>(instr)));
 | 
			
		||||
@@ -828,14 +813,14 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                    else {
 | 
			
		||||
                                        uint32_t load_address = (uint32_t)(*(X+rs1) + (int16_t)sext<12>(imm));
 | 
			
		||||
                                        uint8_t read_res = super::template read_mem<uint8_t>(traits::MEM, load_address);
 | 
			
		||||
                                    if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_LBU;
 | 
			
		||||
                                        if(this->core.reg.trap_state>=0x80000000UL) throw memory_access_exception();
 | 
			
		||||
                                        uint8_t res = read_res;
 | 
			
		||||
                                        if(rd !=  0) {
 | 
			
		||||
                                            *(X+rd) = (uint32_t)res;
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_LBU:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::LHU: {
 | 
			
		||||
                    uint8_t rd = ((bit_sub<7,5>(instr)));
 | 
			
		||||
@@ -859,14 +844,14 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                    else {
 | 
			
		||||
                                        uint32_t load_address = (uint32_t)(*(X+rs1) + (int16_t)sext<12>(imm));
 | 
			
		||||
                                        uint16_t read_res = super::template read_mem<uint16_t>(traits::MEM, load_address);
 | 
			
		||||
                                    if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_LHU;
 | 
			
		||||
                                        if(this->core.reg.trap_state>=0x80000000UL) throw memory_access_exception();
 | 
			
		||||
                                        uint16_t res = read_res;
 | 
			
		||||
                                        if(rd !=  0) {
 | 
			
		||||
                                            *(X+rd) = (uint32_t)res;
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_LHU:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::SB: {
 | 
			
		||||
                    uint16_t imm = ((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5));
 | 
			
		||||
@@ -890,10 +875,10 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                    else {
 | 
			
		||||
                                        uint32_t store_address = (uint32_t)(*(X+rs1) + (int16_t)sext<12>(imm));
 | 
			
		||||
                                        super::template write_mem<uint8_t>(traits::MEM, store_address, (uint8_t)*(X+rs2));
 | 
			
		||||
                                    if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_SB;
 | 
			
		||||
                                        if(this->core.reg.trap_state>=0x80000000UL) throw memory_access_exception();
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_SB:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::SH: {
 | 
			
		||||
                    uint16_t imm = ((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5));
 | 
			
		||||
@@ -917,10 +902,10 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                    else {
 | 
			
		||||
                                        uint32_t store_address = (uint32_t)(*(X+rs1) + (int16_t)sext<12>(imm));
 | 
			
		||||
                                        super::template write_mem<uint16_t>(traits::MEM, store_address, (uint16_t)*(X+rs2));
 | 
			
		||||
                                    if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_SH;
 | 
			
		||||
                                        if(this->core.reg.trap_state>=0x80000000UL) throw memory_access_exception();
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_SH:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::SW: {
 | 
			
		||||
                    uint16_t imm = ((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5));
 | 
			
		||||
@@ -944,10 +929,10 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                    else {
 | 
			
		||||
                                        uint32_t store_address = (uint32_t)(*(X+rs1) + (int16_t)sext<12>(imm));
 | 
			
		||||
                                        super::template write_mem<uint32_t>(traits::MEM, store_address, (uint32_t)*(X+rs2));
 | 
			
		||||
                                    if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_SW;
 | 
			
		||||
                                        if(this->core.reg.trap_state>=0x80000000UL) throw memory_access_exception();
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_SW:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::ADDI: {
 | 
			
		||||
                    uint8_t rd = ((bit_sub<7,5>(instr)));
 | 
			
		||||
@@ -974,7 +959,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_ADDI:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::SLTI: {
 | 
			
		||||
                    uint8_t rd = ((bit_sub<7,5>(instr)));
 | 
			
		||||
@@ -1001,7 +986,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_SLTI:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::SLTIU: {
 | 
			
		||||
                    uint8_t rd = ((bit_sub<7,5>(instr)));
 | 
			
		||||
@@ -1028,7 +1013,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_SLTIU:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::XORI: {
 | 
			
		||||
                    uint8_t rd = ((bit_sub<7,5>(instr)));
 | 
			
		||||
@@ -1055,7 +1040,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_XORI:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::ORI: {
 | 
			
		||||
                    uint8_t rd = ((bit_sub<7,5>(instr)));
 | 
			
		||||
@@ -1082,7 +1067,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_ORI:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::ANDI: {
 | 
			
		||||
                    uint8_t rd = ((bit_sub<7,5>(instr)));
 | 
			
		||||
@@ -1109,7 +1094,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_ANDI:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::SLLI: {
 | 
			
		||||
                    uint8_t rd = ((bit_sub<7,5>(instr)));
 | 
			
		||||
@@ -1136,7 +1121,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_SLLI:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::SRLI: {
 | 
			
		||||
                    uint8_t rd = ((bit_sub<7,5>(instr)));
 | 
			
		||||
@@ -1163,7 +1148,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_SRLI:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::SRAI: {
 | 
			
		||||
                    uint8_t rd = ((bit_sub<7,5>(instr)));
 | 
			
		||||
@@ -1190,7 +1175,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_SRAI:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::ADD: {
 | 
			
		||||
                    uint8_t rd = ((bit_sub<7,5>(instr)));
 | 
			
		||||
@@ -1217,7 +1202,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_ADD:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::SUB: {
 | 
			
		||||
                    uint8_t rd = ((bit_sub<7,5>(instr)));
 | 
			
		||||
@@ -1244,7 +1229,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_SUB:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::SLL: {
 | 
			
		||||
                    uint8_t rd = ((bit_sub<7,5>(instr)));
 | 
			
		||||
@@ -1271,7 +1256,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_SLL:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::SLT: {
 | 
			
		||||
                    uint8_t rd = ((bit_sub<7,5>(instr)));
 | 
			
		||||
@@ -1298,7 +1283,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_SLT:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::SLTU: {
 | 
			
		||||
                    uint8_t rd = ((bit_sub<7,5>(instr)));
 | 
			
		||||
@@ -1325,7 +1310,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_SLTU:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::XOR: {
 | 
			
		||||
                    uint8_t rd = ((bit_sub<7,5>(instr)));
 | 
			
		||||
@@ -1352,7 +1337,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_XOR:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::SRL: {
 | 
			
		||||
                    uint8_t rd = ((bit_sub<7,5>(instr)));
 | 
			
		||||
@@ -1379,7 +1364,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_SRL:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::SRA: {
 | 
			
		||||
                    uint8_t rd = ((bit_sub<7,5>(instr)));
 | 
			
		||||
@@ -1406,7 +1391,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_SRA:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::OR: {
 | 
			
		||||
                    uint8_t rd = ((bit_sub<7,5>(instr)));
 | 
			
		||||
@@ -1433,7 +1418,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_OR:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::AND: {
 | 
			
		||||
                    uint8_t rd = ((bit_sub<7,5>(instr)));
 | 
			
		||||
@@ -1460,7 +1445,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_AND:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::FENCE: {
 | 
			
		||||
                    uint8_t rd = ((bit_sub<7,5>(instr)));
 | 
			
		||||
@@ -1480,9 +1465,9 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                    // execute instruction
 | 
			
		||||
                    {
 | 
			
		||||
                                    super::template write_mem<uint32_t>(traits::FENCE, traits::fence, (uint8_t)pred <<  4 | succ);
 | 
			
		||||
                                if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_FENCE;
 | 
			
		||||
                                    if(this->core.reg.trap_state>=0x80000000UL) throw memory_access_exception();
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_FENCE:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::ECALL: {
 | 
			
		||||
                    if(this->disass_enabled){
 | 
			
		||||
@@ -1495,7 +1480,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                    {
 | 
			
		||||
                                    raise(0,  11);
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_ECALL:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::EBREAK: {
 | 
			
		||||
                    if(this->disass_enabled){
 | 
			
		||||
@@ -1508,7 +1493,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                    {
 | 
			
		||||
                                    raise(0,  3);
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_EBREAK:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::MRET: {
 | 
			
		||||
                    if(this->disass_enabled){
 | 
			
		||||
@@ -1521,7 +1506,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                    {
 | 
			
		||||
                                    leave(3);
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_MRET:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::WFI: {
 | 
			
		||||
                    if(this->disass_enabled){
 | 
			
		||||
@@ -1534,7 +1519,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                    {
 | 
			
		||||
                                    wait(1);
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_WFI:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::CSRRW: {
 | 
			
		||||
                    uint8_t rd = ((bit_sub<7,5>(instr)));
 | 
			
		||||
@@ -1559,19 +1544,19 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                        uint32_t xrs1 = *(X+rs1);
 | 
			
		||||
                                        if(rd !=  0) {
 | 
			
		||||
                                            uint32_t read_res = super::template read_mem<uint32_t>(traits::CSR, csr);
 | 
			
		||||
                                        if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CSRRW;
 | 
			
		||||
                                            if(this->core.reg.trap_state>=0x80000000UL) throw memory_access_exception();
 | 
			
		||||
                                            uint32_t xrd = read_res;
 | 
			
		||||
                                            super::template write_mem<uint32_t>(traits::CSR, csr, xrs1);
 | 
			
		||||
                                        if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CSRRW;
 | 
			
		||||
                                            if(this->core.reg.trap_state>=0x80000000UL) throw memory_access_exception();
 | 
			
		||||
                                            *(X+rd) = xrd;
 | 
			
		||||
                                        }
 | 
			
		||||
                                        else {
 | 
			
		||||
                                            super::template write_mem<uint32_t>(traits::CSR, csr, xrs1);
 | 
			
		||||
                                        if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CSRRW;
 | 
			
		||||
                                            if(this->core.reg.trap_state>=0x80000000UL) throw memory_access_exception();
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_CSRRW:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::CSRRS: {
 | 
			
		||||
                    uint8_t rd = ((bit_sub<7,5>(instr)));
 | 
			
		||||
@@ -1594,19 +1579,19 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                    }
 | 
			
		||||
                                    else {
 | 
			
		||||
                                        uint32_t read_res = super::template read_mem<uint32_t>(traits::CSR, csr);
 | 
			
		||||
                                    if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CSRRS;
 | 
			
		||||
                                        if(this->core.reg.trap_state>=0x80000000UL) throw memory_access_exception();
 | 
			
		||||
                                        uint32_t xrd = read_res;
 | 
			
		||||
                                        uint32_t xrs1 = *(X+rs1);
 | 
			
		||||
                                        if(rs1 !=  0) {
 | 
			
		||||
                                            super::template write_mem<uint32_t>(traits::CSR, csr, xrd | xrs1);
 | 
			
		||||
                                        if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CSRRS;
 | 
			
		||||
                                            if(this->core.reg.trap_state>=0x80000000UL) throw memory_access_exception();
 | 
			
		||||
                                        }
 | 
			
		||||
                                        if(rd !=  0) {
 | 
			
		||||
                                            *(X+rd) = xrd;
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_CSRRS:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::CSRRC: {
 | 
			
		||||
                    uint8_t rd = ((bit_sub<7,5>(instr)));
 | 
			
		||||
@@ -1629,19 +1614,19 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                    }
 | 
			
		||||
                                    else {
 | 
			
		||||
                                        uint32_t read_res = super::template read_mem<uint32_t>(traits::CSR, csr);
 | 
			
		||||
                                    if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CSRRC;
 | 
			
		||||
                                        if(this->core.reg.trap_state>=0x80000000UL) throw memory_access_exception();
 | 
			
		||||
                                        uint32_t xrd = read_res;
 | 
			
		||||
                                        uint32_t xrs1 = *(X+rs1);
 | 
			
		||||
                                        if(rs1 !=  0) {
 | 
			
		||||
                                            super::template write_mem<uint32_t>(traits::CSR, csr, xrd & ~ xrs1);
 | 
			
		||||
                                        if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CSRRC;
 | 
			
		||||
                                            if(this->core.reg.trap_state>=0x80000000UL) throw memory_access_exception();
 | 
			
		||||
                                        }
 | 
			
		||||
                                        if(rd !=  0) {
 | 
			
		||||
                                            *(X+rd) = xrd;
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_CSRRC:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::CSRRWI: {
 | 
			
		||||
                    uint8_t rd = ((bit_sub<7,5>(instr)));
 | 
			
		||||
@@ -1664,16 +1649,16 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                    }
 | 
			
		||||
                                    else {
 | 
			
		||||
                                        uint32_t read_res = super::template read_mem<uint32_t>(traits::CSR, csr);
 | 
			
		||||
                                    if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CSRRWI;
 | 
			
		||||
                                        if(this->core.reg.trap_state>=0x80000000UL) throw memory_access_exception();
 | 
			
		||||
                                        uint32_t xrd = read_res;
 | 
			
		||||
                                        super::template write_mem<uint32_t>(traits::CSR, csr, (uint32_t)zimm);
 | 
			
		||||
                                    if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CSRRWI;
 | 
			
		||||
                                        if(this->core.reg.trap_state>=0x80000000UL) throw memory_access_exception();
 | 
			
		||||
                                        if(rd !=  0) {
 | 
			
		||||
                                            *(X+rd) = xrd;
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_CSRRWI:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::CSRRSI: {
 | 
			
		||||
                    uint8_t rd = ((bit_sub<7,5>(instr)));
 | 
			
		||||
@@ -1696,18 +1681,18 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                    }
 | 
			
		||||
                                    else {
 | 
			
		||||
                                        uint32_t read_res = super::template read_mem<uint32_t>(traits::CSR, csr);
 | 
			
		||||
                                    if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CSRRSI;
 | 
			
		||||
                                        if(this->core.reg.trap_state>=0x80000000UL) throw memory_access_exception();
 | 
			
		||||
                                        uint32_t xrd = read_res;
 | 
			
		||||
                                        if(zimm !=  0) {
 | 
			
		||||
                                            super::template write_mem<uint32_t>(traits::CSR, csr, xrd | (uint32_t)zimm);
 | 
			
		||||
                                        if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CSRRSI;
 | 
			
		||||
                                            if(this->core.reg.trap_state>=0x80000000UL) throw memory_access_exception();
 | 
			
		||||
                                        }
 | 
			
		||||
                                        if(rd !=  0) {
 | 
			
		||||
                                            *(X+rd) = xrd;
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_CSRRSI:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::CSRRCI: {
 | 
			
		||||
                    uint8_t rd = ((bit_sub<7,5>(instr)));
 | 
			
		||||
@@ -1730,18 +1715,18 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                    }
 | 
			
		||||
                                    else {
 | 
			
		||||
                                        uint32_t read_res = super::template read_mem<uint32_t>(traits::CSR, csr);
 | 
			
		||||
                                    if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CSRRCI;
 | 
			
		||||
                                        if(this->core.reg.trap_state>=0x80000000UL) throw memory_access_exception();
 | 
			
		||||
                                        uint32_t xrd = read_res;
 | 
			
		||||
                                        if(zimm !=  0) {
 | 
			
		||||
                                            super::template write_mem<uint32_t>(traits::CSR, csr, xrd & ~ ((uint32_t)zimm));
 | 
			
		||||
                                        if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CSRRCI;
 | 
			
		||||
                                            if(this->core.reg.trap_state>=0x80000000UL) throw memory_access_exception();
 | 
			
		||||
                                        }
 | 
			
		||||
                                        if(rd !=  0) {
 | 
			
		||||
                                            *(X+rd) = xrd;
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_CSRRCI:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::FENCE_I: {
 | 
			
		||||
                    uint8_t rd = ((bit_sub<7,5>(instr)));
 | 
			
		||||
@@ -1759,9 +1744,9 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                    // execute instruction
 | 
			
		||||
                    {
 | 
			
		||||
                                    super::template write_mem<uint32_t>(traits::FENCE, traits::fencei, imm);
 | 
			
		||||
                                if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_FENCE_I;
 | 
			
		||||
                                    if(this->core.reg.trap_state>=0x80000000UL) throw memory_access_exception();
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_FENCE_I:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::MUL: {
 | 
			
		||||
                    uint8_t rd = ((bit_sub<7,5>(instr)));
 | 
			
		||||
@@ -1789,7 +1774,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_MUL:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::MULH: {
 | 
			
		||||
                    uint8_t rd = ((bit_sub<7,5>(instr)));
 | 
			
		||||
@@ -1817,7 +1802,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_MULH:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::MULHSU: {
 | 
			
		||||
                    uint8_t rd = ((bit_sub<7,5>(instr)));
 | 
			
		||||
@@ -1845,7 +1830,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_MULHSU:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::MULHU: {
 | 
			
		||||
                    uint8_t rd = ((bit_sub<7,5>(instr)));
 | 
			
		||||
@@ -1873,7 +1858,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_MULHU:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::DIV: {
 | 
			
		||||
                    uint8_t rd = ((bit_sub<7,5>(instr)));
 | 
			
		||||
@@ -1913,7 +1898,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_DIV:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::DIVU: {
 | 
			
		||||
                    uint8_t rd = ((bit_sub<7,5>(instr)));
 | 
			
		||||
@@ -1947,7 +1932,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_DIVU:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::REM: {
 | 
			
		||||
                    uint8_t rd = ((bit_sub<7,5>(instr)));
 | 
			
		||||
@@ -1989,7 +1974,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_REM:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::REMU: {
 | 
			
		||||
                    uint8_t rd = ((bit_sub<7,5>(instr)));
 | 
			
		||||
@@ -2023,7 +2008,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_REMU:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::CADDI4SPN: {
 | 
			
		||||
                    uint8_t rd = ((bit_sub<2,3>(instr)));
 | 
			
		||||
@@ -2047,7 +2032,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                        raise(0,  2);
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_CADDI4SPN:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::CLW: {
 | 
			
		||||
                    uint8_t rd = ((bit_sub<2,3>(instr)));
 | 
			
		||||
@@ -2067,10 +2052,10 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                    {
 | 
			
		||||
                        uint32_t offs = (uint32_t)(*(X+rs1 +  8) + uimm);
 | 
			
		||||
                        int32_t read_res = super::template read_mem<int32_t>(traits::MEM, offs);
 | 
			
		||||
                    if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CLW;
 | 
			
		||||
                        if(this->core.reg.trap_state>=0x80000000UL) throw memory_access_exception();
 | 
			
		||||
                        *(X+rd +  8) = (uint32_t)(int32_t)read_res;
 | 
			
		||||
                    }
 | 
			
		||||
                TRAP_CLW:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::CSW: {
 | 
			
		||||
                    uint8_t rs2 = ((bit_sub<2,3>(instr)));
 | 
			
		||||
@@ -2090,9 +2075,9 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                    {
 | 
			
		||||
                        uint32_t offs = (uint32_t)(*(X+rs1 +  8) + uimm);
 | 
			
		||||
                        super::template write_mem<uint32_t>(traits::MEM, offs, (uint32_t)*(X+rs2 +  8));
 | 
			
		||||
                    if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CSW;
 | 
			
		||||
                        if(this->core.reg.trap_state>=0x80000000UL) throw memory_access_exception();
 | 
			
		||||
                    }
 | 
			
		||||
                TRAP_CSW:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::CADDI: {
 | 
			
		||||
                    uint8_t imm = ((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5));
 | 
			
		||||
@@ -2118,7 +2103,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_CADDI:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::CNOP: {
 | 
			
		||||
                    uint8_t nzimm = ((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5));
 | 
			
		||||
@@ -2131,7 +2116,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                    // execute instruction
 | 
			
		||||
                    {
 | 
			
		||||
                    }
 | 
			
		||||
                TRAP_CNOP:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::CJAL: {
 | 
			
		||||
                    uint16_t imm = ((bit_sub<2,1>(instr) << 5) | (bit_sub<3,3>(instr) << 1) | (bit_sub<6,1>(instr) << 7) | (bit_sub<7,1>(instr) << 6) | (bit_sub<8,1>(instr) << 10) | (bit_sub<9,2>(instr) << 8) | (bit_sub<11,1>(instr) << 4) | (bit_sub<12,1>(instr) << 11));
 | 
			
		||||
@@ -2151,7 +2136,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                        *NEXT_PC = (uint32_t)(*PC + (int16_t)sext<12>(imm));
 | 
			
		||||
                        this->core.reg.last_branch = 1;
 | 
			
		||||
                    }
 | 
			
		||||
                TRAP_CJAL:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::CLI: {
 | 
			
		||||
                    uint8_t imm = ((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5));
 | 
			
		||||
@@ -2177,7 +2162,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_CLI:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::CLUI: {
 | 
			
		||||
                    uint32_t imm = ((bit_sub<2,5>(instr) << 12) | (bit_sub<12,1>(instr) << 17));
 | 
			
		||||
@@ -2201,7 +2186,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                            *(X+rd) = (uint32_t)((int32_t)sext<18>(imm));
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                TRAP_CLUI:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::CADDI16SP: {
 | 
			
		||||
                    uint16_t nzimm = ((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 7) | (bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 4) | (bit_sub<12,1>(instr) << 9));
 | 
			
		||||
@@ -2224,7 +2209,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                        raise(0,  2);
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_CADDI16SP:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::__reserved_clui: {
 | 
			
		||||
                    uint8_t rd = ((bit_sub<7,5>(instr)));
 | 
			
		||||
@@ -2238,7 +2223,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                    {
 | 
			
		||||
                                    raise(0,  2);
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP___reserved_clui:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::CSRLI: {
 | 
			
		||||
                    uint8_t shamt = ((bit_sub<2,5>(instr)));
 | 
			
		||||
@@ -2257,7 +2242,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                    {
 | 
			
		||||
                        *(X+rs1 +  8) = *(X+rs1 +  8) >> shamt;
 | 
			
		||||
                    }
 | 
			
		||||
                TRAP_CSRLI:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::CSRAI: {
 | 
			
		||||
                    uint8_t shamt = ((bit_sub<2,5>(instr)));
 | 
			
		||||
@@ -2283,7 +2268,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                TRAP_CSRAI:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::CANDI: {
 | 
			
		||||
                    uint8_t imm = ((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5));
 | 
			
		||||
@@ -2302,7 +2287,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                    {
 | 
			
		||||
                        *(X+rs1 +  8) = (uint32_t)(*(X+rs1 +  8) & (int8_t)sext<6>(imm));
 | 
			
		||||
                    }
 | 
			
		||||
                TRAP_CANDI:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::CSUB: {
 | 
			
		||||
                    uint8_t rs2 = ((bit_sub<2,3>(instr)));
 | 
			
		||||
@@ -2321,7 +2306,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                    {
 | 
			
		||||
                        *(X+rd +  8) = (uint32_t)(*(X+rd +  8) - *(X+rs2 +  8));
 | 
			
		||||
                    }
 | 
			
		||||
                TRAP_CSUB:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::CXOR: {
 | 
			
		||||
                    uint8_t rs2 = ((bit_sub<2,3>(instr)));
 | 
			
		||||
@@ -2340,7 +2325,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                    {
 | 
			
		||||
                        *(X+rd +  8) = *(X+rd +  8) ^ *(X+rs2 +  8);
 | 
			
		||||
                    }
 | 
			
		||||
                TRAP_CXOR:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::COR: {
 | 
			
		||||
                    uint8_t rs2 = ((bit_sub<2,3>(instr)));
 | 
			
		||||
@@ -2359,7 +2344,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                    {
 | 
			
		||||
                        *(X+rd +  8) = *(X+rd +  8) | *(X+rs2 +  8);
 | 
			
		||||
                    }
 | 
			
		||||
                TRAP_COR:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::CAND: {
 | 
			
		||||
                    uint8_t rs2 = ((bit_sub<2,3>(instr)));
 | 
			
		||||
@@ -2378,7 +2363,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                    {
 | 
			
		||||
                        *(X+rd +  8) = *(X+rd +  8) & *(X+rs2 +  8);
 | 
			
		||||
                    }
 | 
			
		||||
                TRAP_CAND:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::CJ: {
 | 
			
		||||
                    uint16_t imm = ((bit_sub<2,1>(instr) << 5) | (bit_sub<3,3>(instr) << 1) | (bit_sub<6,1>(instr) << 7) | (bit_sub<7,1>(instr) << 6) | (bit_sub<8,1>(instr) << 10) | (bit_sub<9,2>(instr) << 8) | (bit_sub<11,1>(instr) << 4) | (bit_sub<12,1>(instr) << 11));
 | 
			
		||||
@@ -2396,7 +2381,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                    *NEXT_PC = (uint32_t)(*PC + (int16_t)sext<12>(imm));
 | 
			
		||||
                                    this->core.reg.last_branch = 1;
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_CJ:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::CBEQZ: {
 | 
			
		||||
                    uint16_t imm = ((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 1) | (bit_sub<5,2>(instr) << 6) | (bit_sub<10,2>(instr) << 3) | (bit_sub<12,1>(instr) << 8));
 | 
			
		||||
@@ -2418,7 +2403,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                        this->core.reg.last_branch = 1;
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_CBEQZ:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::CBNEZ: {
 | 
			
		||||
                    uint16_t imm = ((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 1) | (bit_sub<5,2>(instr) << 6) | (bit_sub<10,2>(instr) << 3) | (bit_sub<12,1>(instr) << 8));
 | 
			
		||||
@@ -2440,7 +2425,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                        this->core.reg.last_branch = 1;
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_CBNEZ:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::CSLLI: {
 | 
			
		||||
                    uint8_t nzuimm = ((bit_sub<2,5>(instr)));
 | 
			
		||||
@@ -2466,7 +2451,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_CSLLI:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::CLWSP: {
 | 
			
		||||
                    uint8_t uimm = ((bit_sub<2,2>(instr) << 6) | (bit_sub<4,3>(instr) << 2) | (bit_sub<12,1>(instr) << 5));
 | 
			
		||||
@@ -2489,11 +2474,11 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                        else {
 | 
			
		||||
                            uint32_t offs = (uint32_t)(*(X+2) + uimm);
 | 
			
		||||
                            int32_t read_res = super::template read_mem<int32_t>(traits::MEM, offs);
 | 
			
		||||
                        if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CLWSP;
 | 
			
		||||
                            if(this->core.reg.trap_state>=0x80000000UL) throw memory_access_exception();
 | 
			
		||||
                            *(X+rd) = (uint32_t)(int32_t)read_res;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                TRAP_CLWSP:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::CMV: {
 | 
			
		||||
                    uint8_t rs2 = ((bit_sub<2,5>(instr)));
 | 
			
		||||
@@ -2519,7 +2504,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_CMV:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::CJR: {
 | 
			
		||||
                    uint8_t rs1 = ((bit_sub<7,5>(instr)));
 | 
			
		||||
@@ -2543,7 +2528,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                        raise(0, 2);
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_CJR:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::__reserved_cmv: {
 | 
			
		||||
                    if(this->disass_enabled){
 | 
			
		||||
@@ -2556,7 +2541,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                    {
 | 
			
		||||
                                    raise(0, 2);
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP___reserved_cmv:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::CADD: {
 | 
			
		||||
                    uint8_t rs2 = ((bit_sub<2,5>(instr)));
 | 
			
		||||
@@ -2582,7 +2567,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_CADD:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::CJALR: {
 | 
			
		||||
                    uint8_t rs1 = ((bit_sub<7,5>(instr)));
 | 
			
		||||
@@ -2608,7 +2593,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                        this->core.reg.last_branch = 1;
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_CJALR:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::CEBREAK: {
 | 
			
		||||
                    if(this->disass_enabled){
 | 
			
		||||
@@ -2621,7 +2606,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                    {
 | 
			
		||||
                                    raise(0,  3);
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_CEBREAK:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::CSWSP: {
 | 
			
		||||
                    uint8_t rs2 = ((bit_sub<2,5>(instr)));
 | 
			
		||||
@@ -2644,10 +2629,10 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                    else {
 | 
			
		||||
                                        uint32_t offs = (uint32_t)(*(X+2) + uimm);
 | 
			
		||||
                                        super::template write_mem<uint32_t>(traits::MEM, offs, (uint32_t)*(X+rs2));
 | 
			
		||||
                                    if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CSWSP;
 | 
			
		||||
                                        if(this->core.reg.trap_state>=0x80000000UL) throw memory_access_exception();
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_CSWSP:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                case arch::traits<ARCH>::opcode_e::DII: {
 | 
			
		||||
                    if(this->disass_enabled){
 | 
			
		||||
@@ -2660,13 +2645,14 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                    {
 | 
			
		||||
                                    raise(0,  2);
 | 
			
		||||
                                }
 | 
			
		||||
                TRAP_DII:break;
 | 
			
		||||
                    break;
 | 
			
		||||
                }// @suppress("No break at end of case")
 | 
			
		||||
                default: {
 | 
			
		||||
                    *NEXT_PC = *PC + ((instr & 3) == 3 ? 4 : 2);
 | 
			
		||||
                    raise(0,  2);
 | 
			
		||||
                }
 | 
			
		||||
                }
 | 
			
		||||
            }catch(memory_access_exception& e){}
 | 
			
		||||
            // post execution stuff
 | 
			
		||||
            process_spawn_blocks();
 | 
			
		||||
            if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, static_cast<unsigned>(inst_id));
 | 
			
		||||
 
 | 
			
		||||
@@ -120,57 +120,7 @@ protected:
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // some compile time constants
 | 
			
		||||
    // enum { MASK16 = 0b1111110001100011, MASK32 = 0b11111111111100000111000001111111 };
 | 
			
		||||
    enum { MASK16 = 0b1111111111111111, MASK32 = 0b11111111111100000111000001111111 };
 | 
			
		||||
    enum { EXTR_MASK16 = MASK16 >> 2, EXTR_MASK32 = MASK32 >> 2 };
 | 
			
		||||
    enum { LUT_SIZE = 1 << util::bit_count(static_cast<uint32_t>(EXTR_MASK32)), LUT_SIZE_C = 1 << util::bit_count(static_cast<uint32_t>(EXTR_MASK16)) };
 | 
			
		||||
    
 | 
			
		||||
    std::array<compile_func, LUT_SIZE> lut;
 | 
			
		||||
 | 
			
		||||
    std::array<compile_func, LUT_SIZE_C> lut_00, lut_01, lut_10;
 | 
			
		||||
    std::array<compile_func, LUT_SIZE> lut_11;
 | 
			
		||||
 | 
			
		||||
    std::array<compile_func *, 4> qlut;
 | 
			
		||||
 | 
			
		||||
    std::array<const uint32_t, 4> lutmasks = {{EXTR_MASK16, EXTR_MASK16, EXTR_MASK16, EXTR_MASK32}};
 | 
			
		||||
 | 
			
		||||
    void expand_bit_mask(int pos, uint32_t mask, uint32_t value, uint32_t valid, uint32_t idx, compile_func lut[],
 | 
			
		||||
                         compile_func f) {
 | 
			
		||||
        if (pos < 0) {
 | 
			
		||||
            lut[idx] = f;
 | 
			
		||||
        } else {
 | 
			
		||||
            auto bitmask = 1UL << pos;
 | 
			
		||||
            if ((mask & bitmask) == 0) {
 | 
			
		||||
                expand_bit_mask(pos - 1, mask, value, valid, idx, lut, f);
 | 
			
		||||
            } else {
 | 
			
		||||
                if ((valid & bitmask) == 0) {
 | 
			
		||||
                    expand_bit_mask(pos - 1, mask, value, valid, (idx << 1), lut, f);
 | 
			
		||||
                    expand_bit_mask(pos - 1, mask, value, valid, (idx << 1) + 1, lut, f);
 | 
			
		||||
                } else {
 | 
			
		||||
                    auto new_val = idx << 1;
 | 
			
		||||
                    if ((value & bitmask) != 0) new_val++;
 | 
			
		||||
                    expand_bit_mask(pos - 1, mask, value, valid, new_val, lut, f);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    inline uint32_t extract_fields(uint32_t val) { return extract_fields(29, val >> 2, lutmasks[val & 0x3], 0); }
 | 
			
		||||
 | 
			
		||||
    uint32_t extract_fields(int pos, uint32_t val, uint32_t mask, uint32_t lut_val) {
 | 
			
		||||
        if (pos >= 0) {
 | 
			
		||||
            auto bitmask = 1UL << pos;
 | 
			
		||||
            if ((mask & bitmask) == 0) {
 | 
			
		||||
                lut_val = extract_fields(pos - 1, val, mask, lut_val);
 | 
			
		||||
            } else {
 | 
			
		||||
                auto new_val = lut_val << 1;
 | 
			
		||||
                if ((val & bitmask) != 0) new_val++;
 | 
			
		||||
                lut_val = extract_fields(pos - 1, val, mask, new_val);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return lut_val;
 | 
			
		||||
    }
 | 
			
		||||
    template<unsigned W, typename U, typename S = typename std::make_signed<U>::type>
 | 
			
		||||
    inline S sext(U from) {
 | 
			
		||||
        auto mask = (1ULL<<W) - 1;
 | 
			
		||||
@@ -182,14 +132,23 @@ private:
 | 
			
		||||
    /****************************************************************************
 | 
			
		||||
     * start opcode definitions
 | 
			
		||||
     ****************************************************************************/
 | 
			
		||||
    struct InstructionDesriptor {
 | 
			
		||||
    struct instruction_descriptor {
 | 
			
		||||
        size_t length;
 | 
			
		||||
        uint32_t value;
 | 
			
		||||
        uint32_t mask;
 | 
			
		||||
        compile_func op;
 | 
			
		||||
    };
 | 
			
		||||
    struct decoding_tree_node{
 | 
			
		||||
        std::vector<instruction_descriptor> instrs;
 | 
			
		||||
        std::vector<decoding_tree_node*> children;
 | 
			
		||||
        uint32_t submask = std::numeric_limits<uint32_t>::max();
 | 
			
		||||
        uint32_t value;
 | 
			
		||||
        decoding_tree_node(uint32_t value) : value(value){}
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    const std::array<InstructionDesriptor, 87> instr_descr = {{
 | 
			
		||||
    decoding_tree_node* root {nullptr};
 | 
			
		||||
 | 
			
		||||
    const std::array<instruction_descriptor, 87> instr_descr = {{
 | 
			
		||||
         /* entries are: size, valid value, valid mask, function ptr */
 | 
			
		||||
        /* instruction LUI, encoding '0b00000000000000000000000000110111' */
 | 
			
		||||
        {32, 0b00000000000000000000000000110111, 0b00000000000000000000000001111111, &this_class::__lui},
 | 
			
		||||
@@ -394,6 +353,7 @@ private:
 | 
			
		||||
        	}
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,0);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -426,6 +386,7 @@ private:
 | 
			
		||||
        	}
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,1);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -465,6 +426,7 @@ private:
 | 
			
		||||
        	}
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(BRANCH);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,2);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -506,6 +468,7 @@ private:
 | 
			
		||||
        	tu.close_scope();
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(BRANCH);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,3);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -545,6 +508,7 @@ private:
 | 
			
		||||
        	tu.close_scope();
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(BRANCH);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,4);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -584,6 +548,7 @@ private:
 | 
			
		||||
        	tu.close_scope();
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(BRANCH);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,5);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -623,6 +588,7 @@ private:
 | 
			
		||||
        	tu.close_scope();
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(BRANCH);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,6);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -662,6 +628,7 @@ private:
 | 
			
		||||
        	tu.close_scope();
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(BRANCH);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,7);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -701,6 +668,7 @@ private:
 | 
			
		||||
        	tu.close_scope();
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(BRANCH);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,8);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -740,6 +708,7 @@ private:
 | 
			
		||||
        	tu.close_scope();
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(BRANCH);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,9);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -775,6 +744,7 @@ private:
 | 
			
		||||
        	}
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,10);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -810,6 +780,7 @@ private:
 | 
			
		||||
        	}
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,11);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -845,6 +816,7 @@ private:
 | 
			
		||||
        	}
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,12);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -880,6 +852,7 @@ private:
 | 
			
		||||
        	}
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,13);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -915,6 +888,7 @@ private:
 | 
			
		||||
        	}
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,14);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -947,6 +921,7 @@ private:
 | 
			
		||||
        	tu.write_mem(traits::MEM, store_address, tu.ext(tu.load(rs2+ traits::X0, 0),8,true));
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,15);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -979,6 +954,7 @@ private:
 | 
			
		||||
        	tu.write_mem(traits::MEM, store_address, tu.ext(tu.load(rs2+ traits::X0, 0),16,true));
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,16);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -1011,6 +987,7 @@ private:
 | 
			
		||||
        	tu.write_mem(traits::MEM, store_address, tu.ext(tu.load(rs2+ traits::X0, 0),32,true));
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,17);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -1044,6 +1021,7 @@ private:
 | 
			
		||||
        	}
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,18);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -1077,6 +1055,7 @@ private:
 | 
			
		||||
        	}
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,19);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -1110,6 +1089,7 @@ private:
 | 
			
		||||
        	}
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,20);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -1143,6 +1123,7 @@ private:
 | 
			
		||||
        	}
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,21);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -1176,6 +1157,7 @@ private:
 | 
			
		||||
        	}
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,22);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -1209,6 +1191,7 @@ private:
 | 
			
		||||
        	}
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,23);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -1242,6 +1225,7 @@ private:
 | 
			
		||||
        	}
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,24);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -1275,6 +1259,7 @@ private:
 | 
			
		||||
        	}
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,25);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -1308,6 +1293,7 @@ private:
 | 
			
		||||
        	}
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,26);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -1341,6 +1327,7 @@ private:
 | 
			
		||||
        	}
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,27);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -1374,6 +1361,7 @@ private:
 | 
			
		||||
        	}
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,28);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -1407,6 +1395,7 @@ private:
 | 
			
		||||
        	}
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,29);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -1440,6 +1429,7 @@ private:
 | 
			
		||||
        	}
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,30);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -1473,6 +1463,7 @@ private:
 | 
			
		||||
        	}
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,31);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -1506,6 +1497,7 @@ private:
 | 
			
		||||
        	}
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,32);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -1539,6 +1531,7 @@ private:
 | 
			
		||||
        	}
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,33);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -1572,6 +1565,7 @@ private:
 | 
			
		||||
        	}
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,34);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -1605,6 +1599,7 @@ private:
 | 
			
		||||
        	}
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,35);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -1638,6 +1633,7 @@ private:
 | 
			
		||||
        	}
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,36);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -1666,6 +1662,7 @@ private:
 | 
			
		||||
        tu.open_scope();
 | 
			
		||||
        tu.write_mem(traits::FENCE, static_cast<uint32_t>(traits:: fence), tu.constant((uint8_t)pred<< 4|succ,8));
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,37);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -1686,6 +1683,7 @@ private:
 | 
			
		||||
        tu.open_scope();
 | 
			
		||||
        this->gen_raise_trap(tu, 0,  11);
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,38);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -1706,6 +1704,7 @@ private:
 | 
			
		||||
        tu.open_scope();
 | 
			
		||||
        this->gen_raise_trap(tu, 0,  3);
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,39);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -1726,6 +1725,7 @@ private:
 | 
			
		||||
        tu.open_scope();
 | 
			
		||||
        this->gen_leave_trap(tu, 3);
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,40);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -1746,6 +1746,7 @@ private:
 | 
			
		||||
        tu.open_scope();
 | 
			
		||||
        this->gen_wait(tu, 1);
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,41);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -1784,6 +1785,7 @@ private:
 | 
			
		||||
        	}
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,42);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -1822,6 +1824,7 @@ private:
 | 
			
		||||
        	}
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,43);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -1860,6 +1863,7 @@ private:
 | 
			
		||||
        	}
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,44);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -1895,6 +1899,7 @@ private:
 | 
			
		||||
        	}
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,45);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -1932,6 +1937,7 @@ private:
 | 
			
		||||
        	}
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,46);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -1969,6 +1975,7 @@ private:
 | 
			
		||||
        	}
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,47);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -1995,6 +2002,7 @@ private:
 | 
			
		||||
        tu.open_scope();
 | 
			
		||||
        tu.write_mem(traits::FENCE, static_cast<uint32_t>(traits:: fencei), tu.constant(imm,16));
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,48);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -2029,6 +2037,7 @@ private:
 | 
			
		||||
        	}
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,49);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -2063,6 +2072,7 @@ private:
 | 
			
		||||
        	}
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,50);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -2097,6 +2107,7 @@ private:
 | 
			
		||||
        	}
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,51);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -2131,6 +2142,7 @@ private:
 | 
			
		||||
        	}
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,52);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -2174,6 +2186,7 @@ private:
 | 
			
		||||
        	}
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,53);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -2213,6 +2226,7 @@ private:
 | 
			
		||||
        	tu.close_scope();
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,54);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -2259,6 +2273,7 @@ private:
 | 
			
		||||
        	tu.close_scope();
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,55);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -2298,6 +2313,7 @@ private:
 | 
			
		||||
        	tu.close_scope();
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,56);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -2328,6 +2344,7 @@ private:
 | 
			
		||||
        	this->gen_raise_trap(tu, 0,  2);
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,57);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -2355,6 +2372,7 @@ private:
 | 
			
		||||
        auto offs = tu.assignment(tu.ext((tu.add(tu.load(rs1+ 8+ traits::X0, 0),tu.constant(uimm,8))),32,true),32);
 | 
			
		||||
        tu.store(rd+ 8 + traits::X0,tu.ext(tu.ext(tu.read_mem(traits::MEM, offs, 32),32,false),32,true));
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,58);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -2382,6 +2400,7 @@ private:
 | 
			
		||||
        auto offs = tu.assignment(tu.ext((tu.add(tu.load(rs1+ 8+ traits::X0, 0),tu.constant(uimm,8))),32,true),32);
 | 
			
		||||
        tu.write_mem(traits::MEM, offs, tu.ext(tu.load(rs2+ 8+ traits::X0, 0),32,true));
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,59);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -2414,6 +2433,7 @@ private:
 | 
			
		||||
        	}
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,60);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -2434,6 +2454,7 @@ private:
 | 
			
		||||
        gen_set_pc(tu, pc, traits::NEXT_PC);
 | 
			
		||||
        tu.open_scope();
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,61);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -2461,6 +2482,7 @@ private:
 | 
			
		||||
        tu.store(traits::NEXT_PC, PC_val_v);
 | 
			
		||||
        tu.store(traits::LAST_BRANCH, tu.constant(2U, 2));
 | 
			
		||||
        auto returnValue = std::make_tuple(BRANCH);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,62);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -2493,6 +2515,7 @@ private:
 | 
			
		||||
        	}
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,63);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -2523,6 +2546,7 @@ private:
 | 
			
		||||
            tu.store(rd + traits::X0,tu.constant((uint32_t)((int32_t)sext<18>(imm)),32));
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,64);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -2552,6 +2576,7 @@ private:
 | 
			
		||||
        	this->gen_raise_trap(tu, 0,  2);
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,65);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -2573,6 +2598,7 @@ private:
 | 
			
		||||
        tu.open_scope();
 | 
			
		||||
        this->gen_raise_trap(tu, 0,  2);
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,66);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -2598,6 +2624,7 @@ private:
 | 
			
		||||
        tu.open_scope();
 | 
			
		||||
        tu.store(rs1+ 8 + traits::X0,tu.lshr(tu.load(rs1+ 8+ traits::X0, 0),tu.constant(shamt,8)));
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,67);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -2628,6 +2655,7 @@ private:
 | 
			
		||||
        	}
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,68);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -2653,6 +2681,7 @@ private:
 | 
			
		||||
        tu.open_scope();
 | 
			
		||||
        tu.store(rs1+ 8 + traits::X0,tu.ext((tu.bitwise_and(tu.load(rs1+ 8+ traits::X0, 0),tu.constant((int8_t)sext<6>(imm),8))),32,true));
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,69);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -2678,6 +2707,7 @@ private:
 | 
			
		||||
        tu.open_scope();
 | 
			
		||||
        tu.store(rd+ 8 + traits::X0,tu.ext((tu.sub(tu.load(rd+ 8+ traits::X0, 0),tu.load(rs2+ 8+ traits::X0, 0))),32,true));
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,70);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -2703,6 +2733,7 @@ private:
 | 
			
		||||
        tu.open_scope();
 | 
			
		||||
        tu.store(rd+ 8 + traits::X0,tu.bitwise_xor(tu.load(rd+ 8+ traits::X0, 0),tu.load(rs2+ 8+ traits::X0, 0)));
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,71);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -2728,6 +2759,7 @@ private:
 | 
			
		||||
        tu.open_scope();
 | 
			
		||||
        tu.store(rd+ 8 + traits::X0,tu.bitwise_or(tu.load(rd+ 8+ traits::X0, 0),tu.load(rs2+ 8+ traits::X0, 0)));
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,72);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -2753,6 +2785,7 @@ private:
 | 
			
		||||
        tu.open_scope();
 | 
			
		||||
        tu.store(rd+ 8 + traits::X0,tu.bitwise_and(tu.load(rd+ 8+ traits::X0, 0),tu.load(rs2+ 8+ traits::X0, 0)));
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,73);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -2779,6 +2812,7 @@ private:
 | 
			
		||||
        tu.store(traits::NEXT_PC, PC_val_v);
 | 
			
		||||
        tu.store(traits::LAST_BRANCH, tu.constant(2U, 2));
 | 
			
		||||
        auto returnValue = std::make_tuple(BRANCH);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,74);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -2808,6 +2842,7 @@ private:
 | 
			
		||||
        tu.store(traits::LAST_BRANCH, tu.constant(2U, 2));
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        auto returnValue = std::make_tuple(BRANCH);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,75);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -2837,6 +2872,7 @@ private:
 | 
			
		||||
        tu.store(traits::LAST_BRANCH, tu.constant(2U, 2));
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        auto returnValue = std::make_tuple(BRANCH);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,76);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -2869,6 +2905,7 @@ private:
 | 
			
		||||
        	}
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,77);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -2900,6 +2937,7 @@ private:
 | 
			
		||||
        	tu.store(rd + traits::X0,tu.ext(tu.ext(tu.read_mem(traits::MEM, offs, 32),32,false),32,true));
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,78);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -2932,6 +2970,7 @@ private:
 | 
			
		||||
        	}
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,79);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -2963,6 +3002,7 @@ private:
 | 
			
		||||
        	this->gen_raise_trap(tu, 0, 2);
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(BRANCH);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,80);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -2983,6 +3023,7 @@ private:
 | 
			
		||||
        tu.open_scope();
 | 
			
		||||
        this->gen_raise_trap(tu, 0, 2);
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,81);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -3015,6 +3056,7 @@ private:
 | 
			
		||||
        	}
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,82);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -3048,6 +3090,7 @@ private:
 | 
			
		||||
        	tu.store(traits::LAST_BRANCH, tu.constant(2U, 2));
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(BRANCH);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,83);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -3068,6 +3111,7 @@ private:
 | 
			
		||||
        tu.open_scope();
 | 
			
		||||
        this->gen_raise_trap(tu, 0,  3);
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,84);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -3099,6 +3143,7 @@ private:
 | 
			
		||||
        	tu.write_mem(traits::MEM, offs, tu.ext(tu.load(rs2+ traits::X0, 0),32,true));
 | 
			
		||||
        }
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,85);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -3119,6 +3164,7 @@ private:
 | 
			
		||||
        tu.open_scope();
 | 
			
		||||
        this->gen_raise_trap(tu, 0,  2);
 | 
			
		||||
        auto returnValue = std::make_tuple(CONT);
 | 
			
		||||
        
 | 
			
		||||
        tu.close_scope();
 | 
			
		||||
        vm_base<ARCH>::gen_sync(tu, POST_SYNC,86);
 | 
			
		||||
        gen_trap_check(tu);
 | 
			
		||||
@@ -3136,6 +3182,59 @@ private:
 | 
			
		||||
        vm_impl::gen_trap_check(tu);
 | 
			
		||||
        return BRANCH;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    //decoding functionality
 | 
			
		||||
 | 
			
		||||
    void populate_decoding_tree(decoding_tree_node* root){
 | 
			
		||||
        //create submask
 | 
			
		||||
        for(auto instr: root->instrs){
 | 
			
		||||
            root->submask &= instr.mask;
 | 
			
		||||
        }
 | 
			
		||||
        //put each instr according to submask&encoding into children
 | 
			
		||||
        for(auto instr: root->instrs){
 | 
			
		||||
            bool foundMatch = false;
 | 
			
		||||
            for(auto child: root->children){
 | 
			
		||||
                //use value as identifying trait
 | 
			
		||||
                if(child->value == (instr.value&root->submask)){
 | 
			
		||||
                    child->instrs.push_back(instr);
 | 
			
		||||
                    foundMatch = true;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            if(!foundMatch){
 | 
			
		||||
                decoding_tree_node* child = new decoding_tree_node(instr.value&root->submask);
 | 
			
		||||
                child->instrs.push_back(instr);
 | 
			
		||||
                root->children.push_back(child);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        root->instrs.clear();
 | 
			
		||||
        //call populate_decoding_tree for all children
 | 
			
		||||
        if(root->children.size() >1)
 | 
			
		||||
            for(auto child: root->children){
 | 
			
		||||
                populate_decoding_tree(child);      
 | 
			
		||||
            }
 | 
			
		||||
        else{
 | 
			
		||||
            //sort instrs by value of the mask, this works bc we want to have the least restrictive one last
 | 
			
		||||
            std::sort(root->children[0]->instrs.begin(), root->children[0]->instrs.end(), [](const instruction_descriptor& instr1, const instruction_descriptor& instr2) {
 | 
			
		||||
            return instr1.mask > instr2.mask;
 | 
			
		||||
            }); 
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    compile_func decode_instr(decoding_tree_node* node, code_word_t word){
 | 
			
		||||
        if(!node->children.size()){
 | 
			
		||||
            if(node->instrs.size() == 1) return node->instrs[0].op;
 | 
			
		||||
            for(auto instr : node->instrs){
 | 
			
		||||
                if((instr.mask&word) == instr.value) return instr.op;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else{
 | 
			
		||||
            for(auto child : node->children){
 | 
			
		||||
                if (child->value == (node->submask&word)){
 | 
			
		||||
                    return decode_instr(child, word);
 | 
			
		||||
                }  
 | 
			
		||||
            }  
 | 
			
		||||
        }
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename CODE_WORD> void debug_fn(CODE_WORD instr) {
 | 
			
		||||
@@ -3148,14 +3247,11 @@ template <typename ARCH> vm_impl<ARCH>::vm_impl() { this(new ARCH()); }
 | 
			
		||||
template <typename ARCH>
 | 
			
		||||
vm_impl<ARCH>::vm_impl(ARCH &core, unsigned core_id, unsigned cluster_id)
 | 
			
		||||
: vm_base<ARCH>(core, core_id, cluster_id) {
 | 
			
		||||
    qlut[0] = lut_00.data();
 | 
			
		||||
    qlut[1] = lut_01.data();
 | 
			
		||||
    qlut[2] = lut_10.data();
 | 
			
		||||
    qlut[3] = lut_11.data();
 | 
			
		||||
    root = new decoding_tree_node(std::numeric_limits<uint32_t>::max());
 | 
			
		||||
    for(auto instr:instr_descr){
 | 
			
		||||
        auto quantrant = instr.value & 0x3;
 | 
			
		||||
        expand_bit_mask(29, lutmasks[quantrant], instr.value >> 2, instr.mask >> 2, 0, qlut[quantrant], instr.op);
 | 
			
		||||
        root->instrs.push_back(instr);
 | 
			
		||||
    }
 | 
			
		||||
    populate_decoding_tree(root);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename ARCH>
 | 
			
		||||
@@ -3171,7 +3267,7 @@ vm_impl<ARCH>::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt,
 | 
			
		||||
//    if ((pc.val & upper_bits) != ((pc.val + 2) & upper_bits)) { // we may cross a page boundary
 | 
			
		||||
//        auto res = this->core.read(paddr, 2, data);
 | 
			
		||||
//        if (res != iss::Ok) throw trap_access(TRAP_ID, pc.val);
 | 
			
		||||
//        if ((instr & 0x3) == 0x3) { // this is a 32bit instruction
 | 
			
		||||
//        if ((insn & 0x3) == 0x3) { // this is a 32bit instruction
 | 
			
		||||
//            res = this->core.read(this->core.v2p(pc + 2), 2, data + 2);
 | 
			
		||||
//        }
 | 
			
		||||
//    } else {
 | 
			
		||||
@@ -3181,8 +3277,7 @@ vm_impl<ARCH>::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt,
 | 
			
		||||
    if (instr == 0x0000006f || (instr&0xffff)==0xa001) throw simulation_stopped(0); // 'J 0' or 'C.J 0'
 | 
			
		||||
    // curr pc on stack
 | 
			
		||||
    ++inst_cnt;
 | 
			
		||||
    auto lut_val = extract_fields(instr);
 | 
			
		||||
    auto f = qlut[instr & 0x3][lut_val];
 | 
			
		||||
    auto f = decode_instr(root, instr);
 | 
			
		||||
    if (f == nullptr) {
 | 
			
		||||
        f = &this_class::illegal_intruction;
 | 
			
		||||
    }
 | 
			
		||||
@@ -3218,7 +3313,7 @@ std::unique_ptr<vm_if> create<arch::tgc5c>(arch::tgc5c *core, unsigned short por
 | 
			
		||||
    if (port != 0) debugger::server<debugger::gdb_session>::run_server(ret, port);
 | 
			
		||||
    return std::unique_ptr<vm_if>(ret);
 | 
			
		||||
}
 | 
			
		||||
} // namespace tcc
 | 
			
		||||
} // namesapce tcc
 | 
			
		||||
} // namespace iss
 | 
			
		||||
 | 
			
		||||
#include <iss/factory.h>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user