Compare commits
	
		
			1 Commits
		
	
	
		
			feaa49d367
			...
			12ccfc055a
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 12ccfc055a | 
@@ -53,7 +53,7 @@ template <> struct traits<tgc_c> {
 | 
				
			|||||||
    static constexpr std::array<const char*, 36> reg_aliases{
 | 
					    static constexpr std::array<const char*, 36> reg_aliases{
 | 
				
			||||||
        {"ZERO", "RA", "SP", "GP", "TP", "T0", "T1", "T2", "S0", "S1", "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "S2", "S3", "S4", "S5", "S6", "S7", "S8", "S9", "S10", "S11", "T3", "T4", "T5", "T6", "PC", "NEXT_PC", "PRIV", "DPC"}};
 | 
					        {"ZERO", "RA", "SP", "GP", "TP", "T0", "T1", "T2", "S0", "S1", "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "S2", "S3", "S4", "S5", "S6", "S7", "S8", "S9", "S10", "S11", "T3", "T4", "T5", "T6", "PC", "NEXT_PC", "PRIV", "DPC"}};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    enum constants {MISA_VAL=0b01000000000000000001000100000100, MARCHID_VAL=0x80000003, RFS=32, INSTR_ALIGNMENT=2, XLEN=32, CSR_SIZE=4096, fence=0, fencei=1, fencevmal=2, fencevmau=3, MUL_LEN=64};
 | 
					    enum constants {MISA_VAL=0b01000000000000000001000100000100, MARCHID_VAL=0x80000003, XLEN=32, INSTR_ALIGNMENT=2, RFS=32, fence=0, fencei=1, fencevmal=2, fencevmau=3, CSR_SIZE=4096, MUL_LEN=64};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    constexpr static unsigned FP_REGS_SIZE = 0;
 | 
					    constexpr static unsigned FP_REGS_SIZE = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -81,7 +81,7 @@ template <> struct traits<tgc_c> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    enum sreg_flag_e { FLAGS };
 | 
					    enum sreg_flag_e { FLAGS };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    enum mem_type_e { MEM, CSR, FENCE, RES };
 | 
					    enum mem_type_e { MEM, FENCE, RES, CSR };
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    enum class opcode_e : unsigned short {
 | 
					    enum class opcode_e : unsigned short {
 | 
				
			||||||
        LUI = 0,
 | 
					        LUI = 0,
 | 
				
			||||||
@@ -124,56 +124,53 @@ template <> struct traits<tgc_c> {
 | 
				
			|||||||
        FENCE = 37,
 | 
					        FENCE = 37,
 | 
				
			||||||
        ECALL = 38,
 | 
					        ECALL = 38,
 | 
				
			||||||
        EBREAK = 39,
 | 
					        EBREAK = 39,
 | 
				
			||||||
        URET = 40,
 | 
					        MRET = 40,
 | 
				
			||||||
        SRET = 41,
 | 
					        WFI = 41,
 | 
				
			||||||
        MRET = 42,
 | 
					        CSRRW = 42,
 | 
				
			||||||
        WFI = 43,
 | 
					        CSRRS = 43,
 | 
				
			||||||
        DRET = 44,
 | 
					        CSRRC = 44,
 | 
				
			||||||
        CSRRW = 45,
 | 
					        CSRRWI = 45,
 | 
				
			||||||
        CSRRS = 46,
 | 
					        CSRRSI = 46,
 | 
				
			||||||
        CSRRC = 47,
 | 
					        CSRRCI = 47,
 | 
				
			||||||
        CSRRWI = 48,
 | 
					        FENCE_I = 48,
 | 
				
			||||||
        CSRRSI = 49,
 | 
					        MUL = 49,
 | 
				
			||||||
        CSRRCI = 50,
 | 
					        MULH = 50,
 | 
				
			||||||
        FENCE_I = 51,
 | 
					        MULHSU = 51,
 | 
				
			||||||
        MUL = 52,
 | 
					        MULHU = 52,
 | 
				
			||||||
        MULH = 53,
 | 
					        DIV = 53,
 | 
				
			||||||
        MULHSU = 54,
 | 
					        DIVU = 54,
 | 
				
			||||||
        MULHU = 55,
 | 
					        REM = 55,
 | 
				
			||||||
        DIV = 56,
 | 
					        REMU = 56,
 | 
				
			||||||
        DIVU = 57,
 | 
					        CADDI4SPN = 57,
 | 
				
			||||||
        REM = 58,
 | 
					        CLW = 58,
 | 
				
			||||||
        REMU = 59,
 | 
					        CSW = 59,
 | 
				
			||||||
        CADDI4SPN = 60,
 | 
					        CADDI = 60,
 | 
				
			||||||
        CLW = 61,
 | 
					        CNOP = 61,
 | 
				
			||||||
        CSW = 62,
 | 
					        CJAL = 62,
 | 
				
			||||||
        CADDI = 63,
 | 
					        CLI = 63,
 | 
				
			||||||
        CNOP = 64,
 | 
					        CLUI = 64,
 | 
				
			||||||
        CJAL = 65,
 | 
					        CADDI16SP = 65,
 | 
				
			||||||
        CLI = 66,
 | 
					        __reserved_clui = 66,
 | 
				
			||||||
        CLUI = 67,
 | 
					        CSRLI = 67,
 | 
				
			||||||
        CADDI16SP = 68,
 | 
					        CSRAI = 68,
 | 
				
			||||||
        __reserved_clui = 69,
 | 
					        CANDI = 69,
 | 
				
			||||||
        CSRLI = 70,
 | 
					        CSUB = 70,
 | 
				
			||||||
        CSRAI = 71,
 | 
					        CXOR = 71,
 | 
				
			||||||
        CANDI = 72,
 | 
					        COR = 72,
 | 
				
			||||||
        CSUB = 73,
 | 
					        CAND = 73,
 | 
				
			||||||
        CXOR = 74,
 | 
					        CJ = 74,
 | 
				
			||||||
        COR = 75,
 | 
					        CBEQZ = 75,
 | 
				
			||||||
        CAND = 76,
 | 
					        CBNEZ = 76,
 | 
				
			||||||
        CJ = 77,
 | 
					        CSLLI = 77,
 | 
				
			||||||
        CBEQZ = 78,
 | 
					        CLWSP = 78,
 | 
				
			||||||
        CBNEZ = 79,
 | 
					        CMV = 79,
 | 
				
			||||||
        CSLLI = 80,
 | 
					        CJR = 80,
 | 
				
			||||||
        CLWSP = 81,
 | 
					        __reserved_cmv = 81,
 | 
				
			||||||
        CMV = 82,
 | 
					        CADD = 82,
 | 
				
			||||||
        CJR = 83,
 | 
					        CJALR = 83,
 | 
				
			||||||
        __reserved_cmv = 84,
 | 
					        CEBREAK = 84,
 | 
				
			||||||
        CADD = 85,
 | 
					        CSWSP = 85,
 | 
				
			||||||
        CJALR = 86,
 | 
					        DII = 86,
 | 
				
			||||||
        CEBREAK = 87,
 | 
					 | 
				
			||||||
        CSWSP = 88,
 | 
					 | 
				
			||||||
        DII = 89,
 | 
					 | 
				
			||||||
        MAX_OPCODE
 | 
					        MAX_OPCODE
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -197,7 +197,7 @@ private:
 | 
				
			|||||||
        typename arch::traits<ARCH>::opcode_e op;
 | 
					        typename arch::traits<ARCH>::opcode_e op;
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const std::array<InstructionDesriptor, 90> instr_descr = {{
 | 
					    const std::array<InstructionDesriptor, 87> instr_descr = {{
 | 
				
			||||||
         /* entries are: size, valid value, valid mask, function ptr */
 | 
					         /* entries are: size, valid value, valid mask, function ptr */
 | 
				
			||||||
        {32, 0b00000000000000000000000000110111, 0b00000000000000000000000001111111, arch::traits<ARCH>::opcode_e::LUI},
 | 
					        {32, 0b00000000000000000000000000110111, 0b00000000000000000000000001111111, arch::traits<ARCH>::opcode_e::LUI},
 | 
				
			||||||
        {32, 0b00000000000000000000000000010111, 0b00000000000000000000000001111111, arch::traits<ARCH>::opcode_e::AUIPC},
 | 
					        {32, 0b00000000000000000000000000010111, 0b00000000000000000000000001111111, arch::traits<ARCH>::opcode_e::AUIPC},
 | 
				
			||||||
@@ -239,11 +239,8 @@ private:
 | 
				
			|||||||
        {32, 0b00000000000000000000000000001111, 0b00000000000000000111000001111111, arch::traits<ARCH>::opcode_e::FENCE},
 | 
					        {32, 0b00000000000000000000000000001111, 0b00000000000000000111000001111111, arch::traits<ARCH>::opcode_e::FENCE},
 | 
				
			||||||
        {32, 0b00000000000000000000000001110011, 0b11111111111111111111111111111111, arch::traits<ARCH>::opcode_e::ECALL},
 | 
					        {32, 0b00000000000000000000000001110011, 0b11111111111111111111111111111111, arch::traits<ARCH>::opcode_e::ECALL},
 | 
				
			||||||
        {32, 0b00000000000100000000000001110011, 0b11111111111111111111111111111111, arch::traits<ARCH>::opcode_e::EBREAK},
 | 
					        {32, 0b00000000000100000000000001110011, 0b11111111111111111111111111111111, arch::traits<ARCH>::opcode_e::EBREAK},
 | 
				
			||||||
        {32, 0b00000000001000000000000001110011, 0b11111111111111111111111111111111, arch::traits<ARCH>::opcode_e::URET},
 | 
					 | 
				
			||||||
        {32, 0b00010000001000000000000001110011, 0b11111111111111111111111111111111, arch::traits<ARCH>::opcode_e::SRET},
 | 
					 | 
				
			||||||
        {32, 0b00110000001000000000000001110011, 0b11111111111111111111111111111111, arch::traits<ARCH>::opcode_e::MRET},
 | 
					        {32, 0b00110000001000000000000001110011, 0b11111111111111111111111111111111, arch::traits<ARCH>::opcode_e::MRET},
 | 
				
			||||||
        {32, 0b00010000010100000000000001110011, 0b11111111111111111111111111111111, arch::traits<ARCH>::opcode_e::WFI},
 | 
					        {32, 0b00010000010100000000000001110011, 0b11111111111111111111111111111111, arch::traits<ARCH>::opcode_e::WFI},
 | 
				
			||||||
        {32, 0b01111011001000000000000001110011, 0b11111111111111111111111111111111, arch::traits<ARCH>::opcode_e::DRET},
 | 
					 | 
				
			||||||
        {32, 0b00000000000000000001000001110011, 0b00000000000000000111000001111111, arch::traits<ARCH>::opcode_e::CSRRW},
 | 
					        {32, 0b00000000000000000001000001110011, 0b00000000000000000111000001111111, arch::traits<ARCH>::opcode_e::CSRRW},
 | 
				
			||||||
        {32, 0b00000000000000000010000001110011, 0b00000000000000000111000001111111, arch::traits<ARCH>::opcode_e::CSRRS},
 | 
					        {32, 0b00000000000000000010000001110011, 0b00000000000000000111000001111111, arch::traits<ARCH>::opcode_e::CSRRS},
 | 
				
			||||||
        {32, 0b00000000000000000011000001110011, 0b00000000000000000111000001111111, arch::traits<ARCH>::opcode_e::CSRRC},
 | 
					        {32, 0b00000000000000000011000001110011, 0b00000000000000000111000001111111, arch::traits<ARCH>::opcode_e::CSRRC},
 | 
				
			||||||
@@ -397,7 +394,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
				
			|||||||
                *NEXT_PC = *PC + 4;
 | 
					                *NEXT_PC = *PC + 4;
 | 
				
			||||||
                // execute instruction
 | 
					                // execute instruction
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                                if((rd % traits::RFS) != 0) {
 | 
					                                if((rd % traits::RFS) !=  0) {
 | 
				
			||||||
                                    *(X+rd % traits::RFS) = (int32_t)imm;
 | 
					                                    *(X+rd % traits::RFS) = (int32_t)imm;
 | 
				
			||||||
                                }
 | 
					                                }
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
@@ -418,7 +415,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
				
			|||||||
                *NEXT_PC = *PC + 4;
 | 
					                *NEXT_PC = *PC + 4;
 | 
				
			||||||
                // execute instruction
 | 
					                // execute instruction
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                                if((rd % traits::RFS) != 0) {
 | 
					                                if((rd % traits::RFS) !=  0) {
 | 
				
			||||||
                                    *(X+rd % traits::RFS) = *PC + (int32_t)imm;
 | 
					                                    *(X+rd % traits::RFS) = *PC + (int32_t)imm;
 | 
				
			||||||
                                }
 | 
					                                }
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
@@ -443,8 +440,8 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
				
			|||||||
                        raise(0,  0);
 | 
					                        raise(0,  0);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    else {
 | 
					                    else {
 | 
				
			||||||
                        if((rd % traits::RFS) != 0) {
 | 
					                        if((rd % traits::RFS) !=  0) {
 | 
				
			||||||
                            *(X+rd % traits::RFS) = *PC + 4;
 | 
					                            *(X+rd % traits::RFS) = *PC +  4;
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        *NEXT_PC = *PC + (int32_t)sext<21>(imm);
 | 
					                        *NEXT_PC = *PC + (int32_t)sext<21>(imm);
 | 
				
			||||||
                        super::ex_info.branch_taken=true;
 | 
					                        super::ex_info.branch_taken=true;
 | 
				
			||||||
@@ -468,13 +465,13 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
				
			|||||||
                *NEXT_PC = *PC + 4;
 | 
					                *NEXT_PC = *PC + 4;
 | 
				
			||||||
                // execute instruction
 | 
					                // execute instruction
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    int32_t new_pc = (*(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm)) & ~ 1;
 | 
					                    uint32_t new_pc = (*(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm)) & ~ 0x1;
 | 
				
			||||||
                    if(new_pc % traits::INSTR_ALIGNMENT) {
 | 
					                    if(new_pc % traits::INSTR_ALIGNMENT) {
 | 
				
			||||||
                        raise(0,  0);
 | 
					                        raise(0,  0);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    else {
 | 
					                    else {
 | 
				
			||||||
                        if((rd % traits::RFS) != 0) {
 | 
					                        if((rd % traits::RFS) !=  0) {
 | 
				
			||||||
                            *(X+rd % traits::RFS) = *PC + 4;
 | 
					                            *(X+rd % traits::RFS) = *PC +  4;
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        *NEXT_PC = new_pc & ~ 0x1;
 | 
					                        *NEXT_PC = new_pc & ~ 0x1;
 | 
				
			||||||
                        super::ex_info.branch_taken=true;
 | 
					                        super::ex_info.branch_taken=true;
 | 
				
			||||||
@@ -666,11 +663,12 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
				
			|||||||
                *NEXT_PC = *PC + 4;
 | 
					                *NEXT_PC = *PC + 4;
 | 
				
			||||||
                // execute instruction
 | 
					                // execute instruction
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    uint8_t read_res = super::template read_mem<uint8_t>(traits::MEM, *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm));
 | 
					                    uint32_t load_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm);
 | 
				
			||||||
 | 
					                    int8_t read_res = super::template read_mem<int8_t>(traits::MEM, load_address);
 | 
				
			||||||
                    if(this->core.trap_state) goto TRAP_LB;
 | 
					                    if(this->core.trap_state) goto TRAP_LB;
 | 
				
			||||||
                    int8_t res = (int8_t)read_res;
 | 
					                    int8_t res = (int8_t)read_res;
 | 
				
			||||||
                    if((rd % traits::RFS) != 0) {
 | 
					                    if((rd % traits::RFS) !=  0) {
 | 
				
			||||||
                        *(X+rd % traits::RFS) = res;
 | 
					                        *(X+rd % traits::RFS) = (int32_t)res;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                TRAP_LB:break;
 | 
					                TRAP_LB:break;
 | 
				
			||||||
@@ -692,11 +690,11 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
				
			|||||||
                // execute instruction
 | 
					                // execute instruction
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    uint32_t load_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm);
 | 
					                    uint32_t load_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm);
 | 
				
			||||||
                    uint16_t read_res = super::template read_mem<uint16_t>(traits::MEM, load_address);
 | 
					                    int16_t read_res = super::template read_mem<int16_t>(traits::MEM, load_address);
 | 
				
			||||||
                    if(this->core.trap_state) goto TRAP_LH;
 | 
					                    if(this->core.trap_state) goto TRAP_LH;
 | 
				
			||||||
                    int16_t res = (int16_t)read_res;
 | 
					                    int16_t res = (int16_t)read_res;
 | 
				
			||||||
                    if((rd % traits::RFS) != 0) {
 | 
					                    if((rd % traits::RFS) !=  0) {
 | 
				
			||||||
                        *(X+rd % traits::RFS) = res;
 | 
					                        *(X+rd % traits::RFS) = (int32_t)res;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                TRAP_LH:break;
 | 
					                TRAP_LH:break;
 | 
				
			||||||
@@ -718,11 +716,11 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
				
			|||||||
                // execute instruction
 | 
					                // execute instruction
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    uint32_t load_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm);
 | 
					                    uint32_t load_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm);
 | 
				
			||||||
                    uint32_t read_res = super::template read_mem<uint32_t>(traits::MEM, load_address);
 | 
					                    int32_t read_res = super::template read_mem<int32_t>(traits::MEM, load_address);
 | 
				
			||||||
                    if(this->core.trap_state) goto TRAP_LW;
 | 
					                    if(this->core.trap_state) goto TRAP_LW;
 | 
				
			||||||
                    int32_t res = (int32_t)read_res;
 | 
					                    int32_t res = (int32_t)read_res;
 | 
				
			||||||
                    if((rd % traits::RFS) != 0) {
 | 
					                    if((rd % traits::RFS) !=  0) {
 | 
				
			||||||
                        *(X+rd % traits::RFS) = (uint32_t)res;
 | 
					                        *(X+rd % traits::RFS) = (int32_t)res;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                TRAP_LW:break;
 | 
					                TRAP_LW:break;
 | 
				
			||||||
@@ -743,11 +741,12 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
				
			|||||||
                *NEXT_PC = *PC + 4;
 | 
					                *NEXT_PC = *PC + 4;
 | 
				
			||||||
                // execute instruction
 | 
					                // execute instruction
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    uint8_t read_res = super::template read_mem<uint8_t>(traits::MEM, *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm));
 | 
					                    uint32_t load_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm);
 | 
				
			||||||
 | 
					                    uint8_t read_res = super::template read_mem<uint8_t>(traits::MEM, load_address);
 | 
				
			||||||
                    if(this->core.trap_state) goto TRAP_LBU;
 | 
					                    if(this->core.trap_state) goto TRAP_LBU;
 | 
				
			||||||
                    uint8_t res = (uint8_t)read_res;
 | 
					                    uint8_t res = (uint8_t)read_res;
 | 
				
			||||||
                    if((rd % traits::RFS) != 0) {
 | 
					                    if((rd % traits::RFS) !=  0) {
 | 
				
			||||||
                        *(X+rd % traits::RFS) = res;
 | 
					                        *(X+rd % traits::RFS) = (uint32_t)res;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                TRAP_LBU:break;
 | 
					                TRAP_LBU:break;
 | 
				
			||||||
@@ -772,8 +771,8 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
				
			|||||||
                    uint16_t read_res = super::template read_mem<uint16_t>(traits::MEM, load_address);
 | 
					                    uint16_t read_res = super::template read_mem<uint16_t>(traits::MEM, load_address);
 | 
				
			||||||
                    if(this->core.trap_state) goto TRAP_LHU;
 | 
					                    if(this->core.trap_state) goto TRAP_LHU;
 | 
				
			||||||
                    uint16_t res = (uint16_t)read_res;
 | 
					                    uint16_t res = (uint16_t)read_res;
 | 
				
			||||||
                    if((rd % traits::RFS) != 0) {
 | 
					                    if((rd % traits::RFS) !=  0) {
 | 
				
			||||||
                        *(X+rd % traits::RFS) = res;
 | 
					                        *(X+rd % traits::RFS) = (uint32_t)res;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                TRAP_LHU:break;
 | 
					                TRAP_LHU:break;
 | 
				
			||||||
@@ -794,9 +793,10 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
				
			|||||||
                *NEXT_PC = *PC + 4;
 | 
					                *NEXT_PC = *PC + 4;
 | 
				
			||||||
                // execute instruction
 | 
					                // execute instruction
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                                super::template write_mem<uint8_t>(traits::MEM, *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm), (int8_t)*(X+rs2 % traits::RFS));
 | 
					                    uint32_t store_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm);
 | 
				
			||||||
                                if(this->core.trap_state) goto TRAP_SB;
 | 
					                    super::template write_mem<uint8_t>(traits::MEM, store_address, (int8_t)*(X+rs2 % traits::RFS));
 | 
				
			||||||
                            }
 | 
					                    if(this->core.trap_state) goto TRAP_SB;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
                TRAP_SB:break;
 | 
					                TRAP_SB:break;
 | 
				
			||||||
            }// @suppress("No break at end of case")
 | 
					            }// @suppress("No break at end of case")
 | 
				
			||||||
            case arch::traits<ARCH>::opcode_e::SH: {
 | 
					            case arch::traits<ARCH>::opcode_e::SH: {
 | 
				
			||||||
@@ -838,7 +838,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
				
			|||||||
                // execute instruction
 | 
					                // execute instruction
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    uint32_t store_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm);
 | 
					                    uint32_t store_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm);
 | 
				
			||||||
                    super::template write_mem<uint32_t>(traits::MEM, store_address, *(X+rs2 % traits::RFS));
 | 
					                    super::template write_mem<uint32_t>(traits::MEM, store_address, (int32_t)*(X+rs2 % traits::RFS));
 | 
				
			||||||
                    if(this->core.trap_state) goto TRAP_SW;
 | 
					                    if(this->core.trap_state) goto TRAP_SW;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                TRAP_SW:break;
 | 
					                TRAP_SW:break;
 | 
				
			||||||
@@ -882,7 +882,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
				
			|||||||
                // execute instruction
 | 
					                // execute instruction
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                                if((rd % traits::RFS) !=  0) {
 | 
					                                if((rd % traits::RFS) !=  0) {
 | 
				
			||||||
                                    *(X+rd % traits::RFS) = (int32_t)*(X+rs1 % traits::RFS) < (int16_t)sext<12>(imm)?  1 :  0;
 | 
					                                    *(X+rd % traits::RFS) = ((int32_t)*(X+rs1 % traits::RFS) < (int16_t)sext<12>(imm))?  1 :  0;
 | 
				
			||||||
                                }
 | 
					                                }
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                TRAP_SLTI:break;
 | 
					                TRAP_SLTI:break;
 | 
				
			||||||
@@ -991,13 +991,8 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
				
			|||||||
                *NEXT_PC = *PC + 4;
 | 
					                *NEXT_PC = *PC + 4;
 | 
				
			||||||
                // execute instruction
 | 
					                // execute instruction
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                                if(shamt >  31) {
 | 
					                                if((rd % traits::RFS) !=  0) {
 | 
				
			||||||
                                    raise(0, 0);
 | 
					                                    *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) << shamt;
 | 
				
			||||||
                                }
 | 
					 | 
				
			||||||
                                else {
 | 
					 | 
				
			||||||
                                    if((rd % traits::RFS) !=  0) {
 | 
					 | 
				
			||||||
                                        *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) << shamt;
 | 
					 | 
				
			||||||
                                    }
 | 
					 | 
				
			||||||
                                }
 | 
					                                }
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                TRAP_SLLI:break;
 | 
					                TRAP_SLLI:break;
 | 
				
			||||||
@@ -1018,13 +1013,8 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
				
			|||||||
                *NEXT_PC = *PC + 4;
 | 
					                *NEXT_PC = *PC + 4;
 | 
				
			||||||
                // execute instruction
 | 
					                // execute instruction
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                                if(shamt >  31) {
 | 
					                                if((rd % traits::RFS) !=  0) {
 | 
				
			||||||
                                    raise(0, 0);
 | 
					                                    *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) >> shamt;
 | 
				
			||||||
                                }
 | 
					 | 
				
			||||||
                                else {
 | 
					 | 
				
			||||||
                                    if((rd % traits::RFS) !=  0) {
 | 
					 | 
				
			||||||
                                        *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) >> shamt;
 | 
					 | 
				
			||||||
                                    }
 | 
					 | 
				
			||||||
                                }
 | 
					                                }
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                TRAP_SRLI:break;
 | 
					                TRAP_SRLI:break;
 | 
				
			||||||
@@ -1045,13 +1035,8 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
				
			|||||||
                *NEXT_PC = *PC + 4;
 | 
					                *NEXT_PC = *PC + 4;
 | 
				
			||||||
                // execute instruction
 | 
					                // execute instruction
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                                if(shamt >  31) {
 | 
					                                if((rd % traits::RFS) !=  0) {
 | 
				
			||||||
                                    raise(0, 0);
 | 
					                                    *(X+rd % traits::RFS) = (int32_t)*(X+rs1 % traits::RFS) >> shamt;
 | 
				
			||||||
                                }
 | 
					 | 
				
			||||||
                                else {
 | 
					 | 
				
			||||||
                                    if((rd % traits::RFS) !=  0) {
 | 
					 | 
				
			||||||
                                        *(X+rd % traits::RFS) = (int32_t)*(X+rs1 % traits::RFS) >> shamt;
 | 
					 | 
				
			||||||
                                    }
 | 
					 | 
				
			||||||
                                }
 | 
					                                }
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                TRAP_SRAI:break;
 | 
					                TRAP_SRAI:break;
 | 
				
			||||||
@@ -1117,7 +1102,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
				
			|||||||
                // execute instruction
 | 
					                // execute instruction
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                                if((rd % traits::RFS) !=  0) {
 | 
					                                if((rd % traits::RFS) !=  0) {
 | 
				
			||||||
                                    *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) << (*(X+rs2 % traits::RFS) & (traits::XLEN - 1));
 | 
					                                    *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) << (*(X+rs2 % traits::RFS) & (traits::XLEN -  1));
 | 
				
			||||||
                                }
 | 
					                                }
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                TRAP_SLL:break;
 | 
					                TRAP_SLL:break;
 | 
				
			||||||
@@ -1205,7 +1190,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
				
			|||||||
                // execute instruction
 | 
					                // execute instruction
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                                if((rd % traits::RFS) !=  0) {
 | 
					                                if((rd % traits::RFS) !=  0) {
 | 
				
			||||||
                                    *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) >> (*(X+rs2 % traits::RFS) & (traits::XLEN - 1));
 | 
					                                    *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) >> (*(X+rs2 % traits::RFS) & (traits::XLEN -  1));
 | 
				
			||||||
                                }
 | 
					                                }
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                TRAP_SRL:break;
 | 
					                TRAP_SRL:break;
 | 
				
			||||||
@@ -1227,7 +1212,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
				
			|||||||
                // execute instruction
 | 
					                // execute instruction
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                                if((rd % traits::RFS) !=  0) {
 | 
					                                if((rd % traits::RFS) !=  0) {
 | 
				
			||||||
                                    *(X+rd % traits::RFS) = (int32_t)*(X+rs1 % traits::RFS) >> (*(X+rs2 % traits::RFS) & (traits::XLEN - 1));
 | 
					                                    *(X+rd % traits::RFS) = (int32_t)*(X+rs1 % traits::RFS) >> (*(X+rs2 % traits::RFS) & (traits::XLEN -  1));
 | 
				
			||||||
                                }
 | 
					                                }
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                TRAP_SRA:break;
 | 
					                TRAP_SRA:break;
 | 
				
			||||||
@@ -1293,7 +1278,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
				
			|||||||
                *NEXT_PC = *PC + 4;
 | 
					                *NEXT_PC = *PC + 4;
 | 
				
			||||||
                // execute instruction
 | 
					                // execute instruction
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                                super::template write_mem<uint8_t>(traits::FENCE, traits::fence, pred << 4 | succ);
 | 
					                                super::template write_mem<uint8_t>(traits::FENCE, traits::fence, pred <<  4 | succ);
 | 
				
			||||||
                                if(this->core.trap_state) goto TRAP_FENCE;
 | 
					                                if(this->core.trap_state) goto TRAP_FENCE;
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                TRAP_FENCE:break;
 | 
					                TRAP_FENCE:break;
 | 
				
			||||||
@@ -1324,32 +1309,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
				
			|||||||
                            }
 | 
					                            }
 | 
				
			||||||
                TRAP_EBREAK:break;
 | 
					                TRAP_EBREAK:break;
 | 
				
			||||||
            }// @suppress("No break at end of case")
 | 
					            }// @suppress("No break at end of case")
 | 
				
			||||||
            case arch::traits<ARCH>::opcode_e::URET: {
 | 
					 | 
				
			||||||
                if(this->disass_enabled){
 | 
					 | 
				
			||||||
                    /* generate console output when executing the command */
 | 
					 | 
				
			||||||
                    this->core.disass_output(pc.val, "uret");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                // used registers// calculate next pc value
 | 
					 | 
				
			||||||
                *NEXT_PC = *PC + 4;
 | 
					 | 
				
			||||||
                // execute instruction
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                                leave(0);
 | 
					 | 
				
			||||||
                            }
 | 
					 | 
				
			||||||
                TRAP_URET:break;
 | 
					 | 
				
			||||||
            }// @suppress("No break at end of case")
 | 
					 | 
				
			||||||
            case arch::traits<ARCH>::opcode_e::SRET: {
 | 
					 | 
				
			||||||
                if(this->disass_enabled){
 | 
					 | 
				
			||||||
                    /* generate console output when executing the command */
 | 
					 | 
				
			||||||
                    this->core.disass_output(pc.val, "sret");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                // used registers// calculate next pc value
 | 
					 | 
				
			||||||
                *NEXT_PC = *PC + 4;
 | 
					 | 
				
			||||||
                // execute instruction
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                                leave(1);
 | 
					 | 
				
			||||||
                            }
 | 
					 | 
				
			||||||
                TRAP_SRET:break;
 | 
					 | 
				
			||||||
            }// @suppress("No break at end of case")
 | 
					 | 
				
			||||||
            case arch::traits<ARCH>::opcode_e::MRET: {
 | 
					            case arch::traits<ARCH>::opcode_e::MRET: {
 | 
				
			||||||
                if(this->disass_enabled){
 | 
					                if(this->disass_enabled){
 | 
				
			||||||
                    /* generate console output when executing the command */
 | 
					                    /* generate console output when executing the command */
 | 
				
			||||||
@@ -1376,30 +1335,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
				
			|||||||
                            }
 | 
					                            }
 | 
				
			||||||
                TRAP_WFI:break;
 | 
					                TRAP_WFI:break;
 | 
				
			||||||
            }// @suppress("No break at end of case")
 | 
					            }// @suppress("No break at end of case")
 | 
				
			||||||
            case arch::traits<ARCH>::opcode_e::DRET: {
 | 
					 | 
				
			||||||
                if(this->disass_enabled){
 | 
					 | 
				
			||||||
                    /* generate console output when executing the command */
 | 
					 | 
				
			||||||
                    this->core.disass_output(pc.val, "dret");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                // used registers 
 | 
					 | 
				
			||||||
                auto* PRIV = reinterpret_cast<uint8_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::PRIV]);
 | 
					 | 
				
			||||||
                 
 | 
					 | 
				
			||||||
                auto* DPC = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::DPC]);
 | 
					 | 
				
			||||||
                // calculate next pc value
 | 
					 | 
				
			||||||
                *NEXT_PC = *PC + 4;
 | 
					 | 
				
			||||||
                // execute instruction
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    if(*PRIV < 4) {
 | 
					 | 
				
			||||||
                        raise(0,  2);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    else {
 | 
					 | 
				
			||||||
                        *NEXT_PC = *DPC;
 | 
					 | 
				
			||||||
                        super::ex_info.branch_taken=true;
 | 
					 | 
				
			||||||
                        *PRIV &=  0x3;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                TRAP_DRET:break;
 | 
					 | 
				
			||||||
            }// @suppress("No break at end of case")
 | 
					 | 
				
			||||||
            case arch::traits<ARCH>::opcode_e::CSRRW: {
 | 
					            case arch::traits<ARCH>::opcode_e::CSRRW: {
 | 
				
			||||||
                uint8_t rd = ((bit_sub<7,5>(instr)));
 | 
					                uint8_t rd = ((bit_sub<7,5>(instr)));
 | 
				
			||||||
                uint8_t rs1 = ((bit_sub<15,5>(instr)));
 | 
					                uint8_t rs1 = ((bit_sub<15,5>(instr)));
 | 
				
			||||||
@@ -1417,7 +1352,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
				
			|||||||
                // execute instruction
 | 
					                // execute instruction
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    uint32_t xrs1 = *(X+rs1 % traits::RFS);
 | 
					                    uint32_t xrs1 = *(X+rs1 % traits::RFS);
 | 
				
			||||||
                    if((rd % traits::RFS) != 0) {
 | 
					                    if((rd % traits::RFS) !=  0) {
 | 
				
			||||||
                        uint32_t read_res = super::template read_mem<uint32_t>(traits::CSR, csr);
 | 
					                        uint32_t read_res = super::template read_mem<uint32_t>(traits::CSR, csr);
 | 
				
			||||||
                        if(this->core.trap_state) goto TRAP_CSRRW;
 | 
					                        if(this->core.trap_state) goto TRAP_CSRRW;
 | 
				
			||||||
                        uint32_t xrd = read_res;
 | 
					                        uint32_t xrd = read_res;
 | 
				
			||||||
@@ -1452,11 +1387,11 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
				
			|||||||
                    if(this->core.trap_state) goto TRAP_CSRRS;
 | 
					                    if(this->core.trap_state) goto TRAP_CSRRS;
 | 
				
			||||||
                    uint32_t xrd = read_res;
 | 
					                    uint32_t xrd = read_res;
 | 
				
			||||||
                    uint32_t xrs1 = *(X+rs1 % traits::RFS);
 | 
					                    uint32_t xrs1 = *(X+rs1 % traits::RFS);
 | 
				
			||||||
                    if(rs1 != 0) {
 | 
					                    if(rs1 !=  0) {
 | 
				
			||||||
                        super::template write_mem<uint32_t>(traits::CSR, csr, xrd | xrs1);
 | 
					                        super::template write_mem<uint32_t>(traits::CSR, csr, xrd | xrs1);
 | 
				
			||||||
                        if(this->core.trap_state) goto TRAP_CSRRS;
 | 
					                        if(this->core.trap_state) goto TRAP_CSRRS;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    if((rd % traits::RFS) != 0) {
 | 
					                    if((rd % traits::RFS) !=  0) {
 | 
				
			||||||
                        *(X+rd % traits::RFS) = xrd;
 | 
					                        *(X+rd % traits::RFS) = xrd;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
@@ -1482,11 +1417,11 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
				
			|||||||
                    if(this->core.trap_state) goto TRAP_CSRRC;
 | 
					                    if(this->core.trap_state) goto TRAP_CSRRC;
 | 
				
			||||||
                    uint32_t xrd = read_res;
 | 
					                    uint32_t xrd = read_res;
 | 
				
			||||||
                    uint32_t xrs1 = *(X+rs1 % traits::RFS);
 | 
					                    uint32_t xrs1 = *(X+rs1 % traits::RFS);
 | 
				
			||||||
                    if(rs1 != 0) {
 | 
					                    if(rs1 !=  0) {
 | 
				
			||||||
                        super::template write_mem<uint32_t>(traits::CSR, csr, xrd & ~ xrs1);
 | 
					                        super::template write_mem<uint32_t>(traits::CSR, csr, xrd & ~ xrs1);
 | 
				
			||||||
                        if(this->core.trap_state) goto TRAP_CSRRC;
 | 
					                        if(this->core.trap_state) goto TRAP_CSRRC;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    if((rd % traits::RFS) != 0) {
 | 
					                    if((rd % traits::RFS) !=  0) {
 | 
				
			||||||
                        *(X+rd % traits::RFS) = xrd;
 | 
					                        *(X+rd % traits::RFS) = xrd;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
@@ -1513,7 +1448,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
				
			|||||||
                    uint32_t xrd = read_res;
 | 
					                    uint32_t xrd = read_res;
 | 
				
			||||||
                    super::template write_mem<uint32_t>(traits::CSR, csr, (uint32_t)zimm);
 | 
					                    super::template write_mem<uint32_t>(traits::CSR, csr, (uint32_t)zimm);
 | 
				
			||||||
                    if(this->core.trap_state) goto TRAP_CSRRWI;
 | 
					                    if(this->core.trap_state) goto TRAP_CSRRWI;
 | 
				
			||||||
                    if((rd % traits::RFS) != 0) {
 | 
					                    if((rd % traits::RFS) !=  0) {
 | 
				
			||||||
                        *(X+rd % traits::RFS) = xrd;
 | 
					                        *(X+rd % traits::RFS) = xrd;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
@@ -1538,11 +1473,11 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
				
			|||||||
                    uint32_t read_res = super::template read_mem<uint32_t>(traits::CSR, csr);
 | 
					                    uint32_t read_res = super::template read_mem<uint32_t>(traits::CSR, csr);
 | 
				
			||||||
                    if(this->core.trap_state) goto TRAP_CSRRSI;
 | 
					                    if(this->core.trap_state) goto TRAP_CSRRSI;
 | 
				
			||||||
                    uint32_t xrd = read_res;
 | 
					                    uint32_t xrd = read_res;
 | 
				
			||||||
                    if(zimm != 0) {
 | 
					                    if(zimm !=  0) {
 | 
				
			||||||
                        super::template write_mem<uint32_t>(traits::CSR, csr, xrd | (uint32_t)zimm);
 | 
					                        super::template write_mem<uint32_t>(traits::CSR, csr, xrd | (uint32_t)zimm);
 | 
				
			||||||
                        if(this->core.trap_state) goto TRAP_CSRRSI;
 | 
					                        if(this->core.trap_state) goto TRAP_CSRRSI;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    if((rd % traits::RFS) != 0) {
 | 
					                    if((rd % traits::RFS) !=  0) {
 | 
				
			||||||
                        *(X+rd % traits::RFS) = xrd;
 | 
					                        *(X+rd % traits::RFS) = xrd;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
@@ -1567,11 +1502,11 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
				
			|||||||
                    uint32_t read_res = super::template read_mem<uint32_t>(traits::CSR, csr);
 | 
					                    uint32_t read_res = super::template read_mem<uint32_t>(traits::CSR, csr);
 | 
				
			||||||
                    if(this->core.trap_state) goto TRAP_CSRRCI;
 | 
					                    if(this->core.trap_state) goto TRAP_CSRRCI;
 | 
				
			||||||
                    uint32_t xrd = read_res;
 | 
					                    uint32_t xrd = read_res;
 | 
				
			||||||
                    if(zimm != 0) {
 | 
					                    if(zimm !=  0) {
 | 
				
			||||||
                        super::template write_mem<uint32_t>(traits::CSR, csr, xrd & ~ ((uint32_t)zimm));
 | 
					                        super::template write_mem<uint32_t>(traits::CSR, csr, xrd & ~ ((uint32_t)zimm));
 | 
				
			||||||
                        if(this->core.trap_state) goto TRAP_CSRRCI;
 | 
					                        if(this->core.trap_state) goto TRAP_CSRRCI;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    if((rd % traits::RFS) != 0) {
 | 
					                    if((rd % traits::RFS) !=  0) {
 | 
				
			||||||
                        *(X+rd % traits::RFS) = xrd;
 | 
					                        *(X+rd % traits::RFS) = xrd;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
@@ -1706,7 +1641,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
				
			|||||||
                // execute instruction
 | 
					                // execute instruction
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    if((rd % traits::RFS) !=  0) {
 | 
					                    if((rd % traits::RFS) !=  0) {
 | 
				
			||||||
                        if(*(X+rs2 % traits::RFS) != 0) {
 | 
					                        if(*(X+rs2 % traits::RFS) !=  0) {
 | 
				
			||||||
                            uint32_t MMIN =  1 << (traits::XLEN - 1);
 | 
					                            uint32_t MMIN =  1 << (traits::XLEN - 1);
 | 
				
			||||||
                            if(*(X+rs1 % traits::RFS) == MMIN && (int32_t)*(X+rs2 % traits::RFS) == - 1) {
 | 
					                            if(*(X+rs1 % traits::RFS) == MMIN && (int32_t)*(X+rs2 % traits::RFS) == - 1) {
 | 
				
			||||||
                                *(X+rd % traits::RFS) = MMIN;
 | 
					                                *(X+rd % traits::RFS) = MMIN;
 | 
				
			||||||
@@ -1739,7 +1674,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
				
			|||||||
                // execute instruction
 | 
					                // execute instruction
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    if((rd % traits::RFS) !=  0) {
 | 
					                    if((rd % traits::RFS) !=  0) {
 | 
				
			||||||
                        if(*(X+rs2 % traits::RFS) != 0) {
 | 
					                        if(*(X+rs2 % traits::RFS) !=  0) {
 | 
				
			||||||
                            *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) / *(X+rs2 % traits::RFS);
 | 
					                            *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) / *(X+rs2 % traits::RFS);
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        else {
 | 
					                        else {
 | 
				
			||||||
@@ -1766,7 +1701,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
				
			|||||||
                // execute instruction
 | 
					                // execute instruction
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    if((rd % traits::RFS) !=  0) {
 | 
					                    if((rd % traits::RFS) !=  0) {
 | 
				
			||||||
                        if(*(X+rs2 % traits::RFS) != 0) {
 | 
					                        if(*(X+rs2 % traits::RFS) !=  0) {
 | 
				
			||||||
                            uint32_t MMIN =  1 << (traits::XLEN - 1);
 | 
					                            uint32_t MMIN =  1 << (traits::XLEN - 1);
 | 
				
			||||||
                            if(*(X+rs1 % traits::RFS) == MMIN && (int32_t)*(X+rs2 % traits::RFS) == - 1) {
 | 
					                            if(*(X+rs1 % traits::RFS) == MMIN && (int32_t)*(X+rs2 % traits::RFS) == - 1) {
 | 
				
			||||||
                                *(X+rd % traits::RFS) =  0;
 | 
					                                *(X+rd % traits::RFS) =  0;
 | 
				
			||||||
@@ -1799,7 +1734,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
				
			|||||||
                // execute instruction
 | 
					                // execute instruction
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    if((rd % traits::RFS) !=  0) {
 | 
					                    if((rd % traits::RFS) !=  0) {
 | 
				
			||||||
                        if(*(X+rs2 % traits::RFS) != 0) {
 | 
					                        if(*(X+rs2 % traits::RFS) !=  0) {
 | 
				
			||||||
                            *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) % *(X+rs2 % traits::RFS);
 | 
					                            *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) % *(X+rs2 % traits::RFS);
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        else {
 | 
					                        else {
 | 
				
			||||||
@@ -1825,7 +1760,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
				
			|||||||
                // execute instruction
 | 
					                // execute instruction
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                                if(imm) {
 | 
					                                if(imm) {
 | 
				
			||||||
                                    *(X+rd + 8) = *(X+2) + imm;
 | 
					                                    *(X+rd +  8) = *(X+2) + imm;
 | 
				
			||||||
                                }
 | 
					                                }
 | 
				
			||||||
                                else {
 | 
					                                else {
 | 
				
			||||||
                                    raise(0,  2);
 | 
					                                    raise(0,  2);
 | 
				
			||||||
@@ -1849,10 +1784,10 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
				
			|||||||
                *NEXT_PC = *PC + 2;
 | 
					                *NEXT_PC = *PC + 2;
 | 
				
			||||||
                // execute instruction
 | 
					                // execute instruction
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    uint32_t load_address = *(X+rs1 + 8) + uimm;
 | 
					                    uint32_t load_address = *(X+rs1 +  8) + uimm;
 | 
				
			||||||
                    uint32_t read_res = super::template read_mem<uint32_t>(traits::MEM, load_address);
 | 
					                    int32_t read_res = super::template read_mem<int32_t>(traits::MEM, load_address);
 | 
				
			||||||
                    if(this->core.trap_state) goto TRAP_CLW;
 | 
					                    if(this->core.trap_state) goto TRAP_CLW;
 | 
				
			||||||
                    *(X+rd + 8) = (int32_t)read_res;
 | 
					                    *(X+rd +  8) = (int32_t)read_res;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                TRAP_CLW:break;
 | 
					                TRAP_CLW:break;
 | 
				
			||||||
            }// @suppress("No break at end of case")
 | 
					            }// @suppress("No break at end of case")
 | 
				
			||||||
@@ -1872,8 +1807,8 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
				
			|||||||
                *NEXT_PC = *PC + 2;
 | 
					                *NEXT_PC = *PC + 2;
 | 
				
			||||||
                // execute instruction
 | 
					                // execute instruction
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    uint32_t load_address = *(X+rs1 + 8) + uimm;
 | 
					                    uint32_t load_address = *(X+rs1 +  8) + uimm;
 | 
				
			||||||
                    super::template write_mem<uint32_t>(traits::MEM, load_address, *(X+rs2 + 8));
 | 
					                    super::template write_mem<uint32_t>(traits::MEM, load_address, (int32_t)*(X+rs2 +  8));
 | 
				
			||||||
                    if(this->core.trap_state) goto TRAP_CSW;
 | 
					                    if(this->core.trap_state) goto TRAP_CSW;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                TRAP_CSW:break;
 | 
					                TRAP_CSW:break;
 | 
				
			||||||
@@ -1893,7 +1828,9 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
				
			|||||||
                *NEXT_PC = *PC + 2;
 | 
					                *NEXT_PC = *PC + 2;
 | 
				
			||||||
                // execute instruction
 | 
					                // execute instruction
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                                *(X+rs1 % traits::RFS) = *(X+rs1 % traits::RFS) + (int8_t)sext<6>(imm);
 | 
					                                if((rs1 % traits::RFS) !=  0) {
 | 
				
			||||||
 | 
					                                    *(X+rs1 % traits::RFS) = *(X+rs1 % traits::RFS) + (int8_t)sext<6>(imm);
 | 
				
			||||||
 | 
					                                }
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                TRAP_CADDI:break;
 | 
					                TRAP_CADDI:break;
 | 
				
			||||||
            }// @suppress("No break at end of case")
 | 
					            }// @suppress("No break at end of case")
 | 
				
			||||||
@@ -1924,7 +1861,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
				
			|||||||
                *NEXT_PC = *PC + 2;
 | 
					                *NEXT_PC = *PC + 2;
 | 
				
			||||||
                // execute instruction
 | 
					                // execute instruction
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    *(X+1) = *PC + 2;
 | 
					                    *(X+1) = *PC +  2;
 | 
				
			||||||
                    *NEXT_PC = *PC + (int16_t)sext<12>(imm);
 | 
					                    *NEXT_PC = *PC + (int16_t)sext<12>(imm);
 | 
				
			||||||
                    super::ex_info.branch_taken=true;
 | 
					                    super::ex_info.branch_taken=true;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
@@ -2027,8 +1964,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
				
			|||||||
                *NEXT_PC = *PC + 2;
 | 
					                *NEXT_PC = *PC + 2;
 | 
				
			||||||
                // execute instruction
 | 
					                // execute instruction
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    uint8_t rs1_idx = rs1 + 8;
 | 
					                    *(X+rs1 +  8) = *(X+rs1 +  8) >> shamt;
 | 
				
			||||||
                    *(X+rs1_idx) = *(X+rs1_idx) >> shamt;
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                TRAP_CSRLI:break;
 | 
					                TRAP_CSRLI:break;
 | 
				
			||||||
            }// @suppress("No break at end of case")
 | 
					            }// @suppress("No break at end of case")
 | 
				
			||||||
@@ -2047,17 +1983,15 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
				
			|||||||
                *NEXT_PC = *PC + 2;
 | 
					                *NEXT_PC = *PC + 2;
 | 
				
			||||||
                // execute instruction
 | 
					                // execute instruction
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                                if(shamt) {
 | 
					                    if(shamt) {
 | 
				
			||||||
                                    uint8_t rs1_idx = rs1 + 8;
 | 
					                        *(X+rs1 +  8) = ((int32_t)*(X+rs1 +  8)) >> shamt;
 | 
				
			||||||
                                    *(X+rs1_idx) = ((int32_t)*(X+rs1_idx)) >> shamt;
 | 
					                    }
 | 
				
			||||||
                                }
 | 
					                    else {
 | 
				
			||||||
                                else {
 | 
					                        if(traits::XLEN ==  128) {
 | 
				
			||||||
                                    if(traits::XLEN == 128) {
 | 
					                            *(X+rs1 +  8) = ((int32_t)*(X+rs1 +  8)) >>  64;
 | 
				
			||||||
                                        uint8_t rs1_idx = rs1 + 8;
 | 
					                        }
 | 
				
			||||||
                                        *(X+rs1_idx) = ((int32_t)*(X+rs1_idx)) >>  64;
 | 
					                    }
 | 
				
			||||||
                                    }
 | 
					                }
 | 
				
			||||||
                                }
 | 
					 | 
				
			||||||
                            }
 | 
					 | 
				
			||||||
                TRAP_CSRAI:break;
 | 
					                TRAP_CSRAI:break;
 | 
				
			||||||
            }// @suppress("No break at end of case")
 | 
					            }// @suppress("No break at end of case")
 | 
				
			||||||
            case arch::traits<ARCH>::opcode_e::CANDI: {
 | 
					            case arch::traits<ARCH>::opcode_e::CANDI: {
 | 
				
			||||||
@@ -2075,8 +2009,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
				
			|||||||
                *NEXT_PC = *PC + 2;
 | 
					                *NEXT_PC = *PC + 2;
 | 
				
			||||||
                // execute instruction
 | 
					                // execute instruction
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    uint8_t rs1_idx = rs1 +  8;
 | 
					                    *(X+rs1 +  8) = *(X+rs1 +  8) & (int8_t)sext<6>(imm);
 | 
				
			||||||
                    *(X+rs1_idx) = *(X+rs1_idx) & (int8_t)sext<6>(imm);
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                TRAP_CANDI:break;
 | 
					                TRAP_CANDI:break;
 | 
				
			||||||
            }// @suppress("No break at end of case")
 | 
					            }// @suppress("No break at end of case")
 | 
				
			||||||
@@ -2095,8 +2028,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
				
			|||||||
                *NEXT_PC = *PC + 2;
 | 
					                *NEXT_PC = *PC + 2;
 | 
				
			||||||
                // execute instruction
 | 
					                // execute instruction
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    uint8_t rd_idx = rd +  8;
 | 
					                    *(X+rd +  8) = *(X+rd +  8) - *(X+rs2 +  8);
 | 
				
			||||||
                    *(X+rd_idx) = *(X+rd_idx) - *(X+rs2 +  8);
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                TRAP_CSUB:break;
 | 
					                TRAP_CSUB:break;
 | 
				
			||||||
            }// @suppress("No break at end of case")
 | 
					            }// @suppress("No break at end of case")
 | 
				
			||||||
@@ -2115,8 +2047,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
				
			|||||||
                *NEXT_PC = *PC + 2;
 | 
					                *NEXT_PC = *PC + 2;
 | 
				
			||||||
                // execute instruction
 | 
					                // execute instruction
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    uint8_t rd_idx = rd +  8;
 | 
					                    *(X+rd +  8) = *(X+rd +  8) ^ *(X+rs2 +  8);
 | 
				
			||||||
                    *(X+rd_idx) = *(X+rd_idx) ^ *(X+rs2 +  8);
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                TRAP_CXOR:break;
 | 
					                TRAP_CXOR:break;
 | 
				
			||||||
            }// @suppress("No break at end of case")
 | 
					            }// @suppress("No break at end of case")
 | 
				
			||||||
@@ -2135,8 +2066,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
				
			|||||||
                *NEXT_PC = *PC + 2;
 | 
					                *NEXT_PC = *PC + 2;
 | 
				
			||||||
                // execute instruction
 | 
					                // execute instruction
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    uint8_t rd_idx = rd +  8;
 | 
					                    *(X+rd +  8) = *(X+rd +  8) | *(X+rs2 +  8);
 | 
				
			||||||
                    *(X+rd_idx) = *(X+rd_idx) | *(X+rs2 +  8);
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                TRAP_COR:break;
 | 
					                TRAP_COR:break;
 | 
				
			||||||
            }// @suppress("No break at end of case")
 | 
					            }// @suppress("No break at end of case")
 | 
				
			||||||
@@ -2155,8 +2085,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
				
			|||||||
                *NEXT_PC = *PC + 2;
 | 
					                *NEXT_PC = *PC + 2;
 | 
				
			||||||
                // execute instruction
 | 
					                // execute instruction
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    uint8_t rd_idx = rd +  8;
 | 
					                    *(X+rd +  8) = *(X+rd +  8) & *(X+rs2 +  8);
 | 
				
			||||||
                    *(X+rd_idx) = *(X+rd_idx) & *(X+rs2 +  8);
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                TRAP_CAND:break;
 | 
					                TRAP_CAND:break;
 | 
				
			||||||
            }// @suppress("No break at end of case")
 | 
					            }// @suppress("No break at end of case")
 | 
				
			||||||
@@ -2193,7 +2122,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
				
			|||||||
                *NEXT_PC = *PC + 2;
 | 
					                *NEXT_PC = *PC + 2;
 | 
				
			||||||
                // execute instruction
 | 
					                // execute instruction
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                                if(*(X+rs1 + 8) == 0) {
 | 
					                                if(*(X+rs1 +  8) ==  0) {
 | 
				
			||||||
                                    *NEXT_PC = *PC + (int16_t)sext<9>(imm);
 | 
					                                    *NEXT_PC = *PC + (int16_t)sext<9>(imm);
 | 
				
			||||||
                                    super::ex_info.branch_taken=true;
 | 
					                                    super::ex_info.branch_taken=true;
 | 
				
			||||||
                                }
 | 
					                                }
 | 
				
			||||||
@@ -2215,7 +2144,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
				
			|||||||
                *NEXT_PC = *PC + 2;
 | 
					                *NEXT_PC = *PC + 2;
 | 
				
			||||||
                // execute instruction
 | 
					                // execute instruction
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                                if(*(X+rs1 + 8) != 0) {
 | 
					                                if(*(X+rs1 +  8) !=  0) {
 | 
				
			||||||
                                    *NEXT_PC = *PC + (int16_t)sext<9>(imm);
 | 
					                                    *NEXT_PC = *PC + (int16_t)sext<9>(imm);
 | 
				
			||||||
                                    super::ex_info.branch_taken=true;
 | 
					                                    super::ex_info.branch_taken=true;
 | 
				
			||||||
                                }
 | 
					                                }
 | 
				
			||||||
@@ -2258,16 +2187,17 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
				
			|||||||
                *NEXT_PC = *PC + 2;
 | 
					                *NEXT_PC = *PC + 2;
 | 
				
			||||||
                // execute instruction
 | 
					                // execute instruction
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                                if(rd) {
 | 
					                    uint32_t offs = *(X+2) + uimm;
 | 
				
			||||||
                                    uint32_t offs = *(X+2) + uimm;
 | 
					                    int32_t read_res = super::template read_mem<int32_t>(traits::MEM, offs);
 | 
				
			||||||
                                    uint32_t read_res = super::template read_mem<uint32_t>(traits::MEM, offs);
 | 
					                    if(this->core.trap_state) goto TRAP_CLWSP;
 | 
				
			||||||
                                    if(this->core.trap_state) goto TRAP_CLWSP;
 | 
					                    int32_t res = read_res;
 | 
				
			||||||
                                    *(X+rd % traits::RFS) = (int32_t)read_res;
 | 
					                    if(rd % traits::RFS) {
 | 
				
			||||||
                                }
 | 
					                        *(X+rd % traits::RFS) = res;
 | 
				
			||||||
                                else {
 | 
					                    }
 | 
				
			||||||
                                    raise(0, 2);
 | 
					                    else {
 | 
				
			||||||
                                }
 | 
					                        raise(0, 2);
 | 
				
			||||||
                            }
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
                TRAP_CLWSP:break;
 | 
					                TRAP_CLWSP:break;
 | 
				
			||||||
            }// @suppress("No break at end of case")
 | 
					            }// @suppress("No break at end of case")
 | 
				
			||||||
            case arch::traits<ARCH>::opcode_e::CMV: {
 | 
					            case arch::traits<ARCH>::opcode_e::CMV: {
 | 
				
			||||||
@@ -2363,8 +2293,8 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
				
			|||||||
                *NEXT_PC = *PC + 2;
 | 
					                *NEXT_PC = *PC + 2;
 | 
				
			||||||
                // execute instruction
 | 
					                // execute instruction
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    int32_t new_pc = *(X+rs1 % traits::RFS);
 | 
					                    uint32_t new_pc = *(X+rs1 % traits::RFS);
 | 
				
			||||||
                    *(X+1) = *PC + 2;
 | 
					                    *(X+1) = *PC +  2;
 | 
				
			||||||
                    *NEXT_PC = new_pc & ~ 0x1;
 | 
					                    *NEXT_PC = new_pc & ~ 0x1;
 | 
				
			||||||
                    super::ex_info.branch_taken=true;
 | 
					                    super::ex_info.branch_taken=true;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user