Compare commits
	
		
			14 Commits
		
	
	
		
			msvc_compa
			...
			b17682e50e
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| b17682e50e | |||
| 5866acf565 | |||
| 6acf73a40f | |||
| 2f15d9676e | |||
| d78fcc48e5 | |||
| 4186723d37 | |||
| 17ee7b138d | |||
| aa84a27a5b | |||
| 438e598a4a | |||
| 174259155d | |||
| ba9339a50d | |||
| 65b4db5eca | |||
| 0fd82f1f3c | |||
| a3084456fd | 
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -31,3 +31,4 @@ language.settings.xml
 | 
				
			|||||||
/*.out
 | 
					/*.out
 | 
				
			||||||
/dump.json
 | 
					/dump.json
 | 
				
			||||||
/src-gen/
 | 
					/src-gen/
 | 
				
			||||||
 | 
					/*.yaml
 | 
				
			||||||
 
 | 
				
			|||||||
 Submodule gen_input/CoreDSL-Instruction-Set-Description updated: 8d9a0fb149...9e3119a806
									
								
							
							
								
								
									
										14
									
								
								gen_input/TGC_B.core_desc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								gen_input/TGC_B.core_desc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
				
			|||||||
 | 
					import "CoreDSL-Instruction-Set-Description/RV32I.core_desc"
 | 
				
			||||||
 | 
					import "CoreDSL-Instruction-Set-Description/RVM.core_desc"
 | 
				
			||||||
 | 
					import "CoreDSL-Instruction-Set-Description/RVC.core_desc"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Core TGC_B provides RV32I {
 | 
				
			||||||
 | 
						architectural_state {
 | 
				
			||||||
 | 
					        XLEN=32;
 | 
				
			||||||
 | 
					        // definitions for the architecture wrapper
 | 
				
			||||||
 | 
					        //                    XL    ZYXWVUTSRQPONMLKJIHGFEDCBA
 | 
				
			||||||
 | 
					        unsigned MISA_VAL = 0b01000000000000000000000100000000;
 | 
				
			||||||
 | 
					        unsigned MARCHID_VAL = 0x80000002;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										13
									
								
								gen_input/TGC_C.core_desc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								gen_input/TGC_C.core_desc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
				
			|||||||
 | 
					import "CoreDSL-Instruction-Set-Description/RV32I.core_desc"
 | 
				
			||||||
 | 
					import "CoreDSL-Instruction-Set-Description/RVM.core_desc"
 | 
				
			||||||
 | 
					import "CoreDSL-Instruction-Set-Description/RVC.core_desc"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Core TGC_C provides RV32I, RV32M, RV32IC {
 | 
				
			||||||
 | 
					    architectural_state {
 | 
				
			||||||
 | 
					        XLEN=32;
 | 
				
			||||||
 | 
					        // definitions for the architecture wrapper
 | 
				
			||||||
 | 
					        //                    XL    ZYXWVUTSRQPONMLKJIHGFEDCBA
 | 
				
			||||||
 | 
					        unsigned MISA_VAL = 0b01000000000000000001000100000100;
 | 
				
			||||||
 | 
					        unsigned MARCHID_VAL = 0x80000003;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										13
									
								
								gen_input/TGC_D.core_desc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								gen_input/TGC_D.core_desc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
				
			|||||||
 | 
					import "CoreDSL-Instruction-Set-Description/RV32I.core_desc"
 | 
				
			||||||
 | 
					import "CoreDSL-Instruction-Set-Description/RVM.core_desc"
 | 
				
			||||||
 | 
					import "CoreDSL-Instruction-Set-Description/RVC.core_desc"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Core TGC_D provides RV32I, RV32M, RV32IC {
 | 
				
			||||||
 | 
					    architectural_state {
 | 
				
			||||||
 | 
					        XLEN=32;
 | 
				
			||||||
 | 
					        // definitions for the architecture wrapper
 | 
				
			||||||
 | 
					        //                    XL    ZYXWVUTSRQPONMLKJIHGFEDCBA
 | 
				
			||||||
 | 
					        unsigned MISA_VAL = 0b01000000000000000001000100000100;
 | 
				
			||||||
 | 
					        unsigned MARCHID_VAL = 0x80000004;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										73
									
								
								gen_input/TGC_D_XRB_MAC.core_desc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								gen_input/TGC_D_XRB_MAC.core_desc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,73 @@
 | 
				
			|||||||
 | 
					import "CoreDSL-Instruction-Set-Description/RISCVBase.core_desc"
 | 
				
			||||||
 | 
					import "CoreDSL-Instruction-Set-Description/RV32I.core_desc"
 | 
				
			||||||
 | 
					import "CoreDSL-Instruction-Set-Description/RVM.core_desc"
 | 
				
			||||||
 | 
					import "CoreDSL-Instruction-Set-Description/RVC.core_desc"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					InstructionSet X_RB_MAC extends RISCVBase {
 | 
				
			||||||
 | 
					  architectural_state {
 | 
				
			||||||
 | 
					    register unsigned<64> ACC;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  instructions {
 | 
				
			||||||
 | 
					    RESET_ACC { // v-- funct7       v-- funct3
 | 
				
			||||||
 | 
					      encoding: 7'd0 :: 10'b0 :: 3'd0 :: 5'b0 :: 7'b0001011;
 | 
				
			||||||
 | 
					      behavior: ACC = 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    GET_ACC_LO {
 | 
				
			||||||
 | 
					      encoding: 7'd1 :: 10'b0 :: 3'd0 :: rd[4:0] :: 7'b0001011;
 | 
				
			||||||
 | 
					      behavior: if (rd != 0) X[rd] = ACC[31:0];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    GET_ACC_HI {
 | 
				
			||||||
 | 
					      encoding: 7'd2 :: 10'b0 :: 3'd0 :: rd[4:0] :: 7'b0001011;
 | 
				
			||||||
 | 
					      behavior: if (rd != 0) X[rd] = ACC[63:32];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    MACU_32 {
 | 
				
			||||||
 | 
					      encoding: 7'd0 :: rs2[4:0] :: rs1[4:0] :: 3'd1 :: 5'b0 :: 7'b0001011;
 | 
				
			||||||
 | 
					      behavior: {
 | 
				
			||||||
 | 
					        unsigned<64> mul = X[rs1]    * X[rs2];
 | 
				
			||||||
 | 
					        unsigned<33> add = mul[31:0] + ACC[31:0];
 | 
				
			||||||
 | 
					        ACC = add[31:0];
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    MACS_32 {
 | 
				
			||||||
 | 
					      encoding: 7'd1 :: rs2[4:0] :: rs1[4:0] :: 3'd1 :: 5'b0 :: 7'b0001011;
 | 
				
			||||||
 | 
					      behavior: {
 | 
				
			||||||
 | 
					        signed<64> mul = ((signed) X[rs1])    * ((signed) X[rs2]);
 | 
				
			||||||
 | 
					        signed<33> add = ((signed) mul[31:0]) + ((signed) ACC[31:0]);
 | 
				
			||||||
 | 
					        ACC = add[31:0]; // bit range always yields unsigned type
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    MACU_64 {
 | 
				
			||||||
 | 
					      encoding: 7'd0 :: rs2[4:0] :: rs1[4:0] :: 3'd2 :: 5'b0 :: 7'b0001011;
 | 
				
			||||||
 | 
					      behavior: {
 | 
				
			||||||
 | 
					        unsigned<64> mul = X[rs1] * X[rs2];
 | 
				
			||||||
 | 
					        unsigned<65> add = mul    + ACC;
 | 
				
			||||||
 | 
					        ACC = add[63:0];
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    MACS_64 {
 | 
				
			||||||
 | 
					      encoding: 7'd1 :: rs2[4:0] :: rs1[4:0] :: 3'd2 :: 5'b0 :: 7'b0001011;
 | 
				
			||||||
 | 
					      behavior: {
 | 
				
			||||||
 | 
					        signed<64> mul = ((signed) X[rs1]) * ((signed) X[rs2]);
 | 
				
			||||||
 | 
					        signed<65> add =           mul     + ((signed) ACC);
 | 
				
			||||||
 | 
					        ACC = add[63:0];
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Core TGC_D_XRB_MAC provides RV32I, RV32M, RV32IC, X_RB_MAC {
 | 
				
			||||||
 | 
					    architectural_state {
 | 
				
			||||||
 | 
					        XLEN=32;
 | 
				
			||||||
 | 
					        // definitions for the architecture wrapper
 | 
				
			||||||
 | 
					        //                    XL    ZYXWVUTSRQPONMLKJIHGFEDCBA
 | 
				
			||||||
 | 
					        unsigned MISA_VAL = 0b01000000000000000001000100000100;
 | 
				
			||||||
 | 
					        unsigned MARCHID_VAL = 0x80000004;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,37 +0,0 @@
 | 
				
			|||||||
import "CoreDSL-Instruction-Set-Description/RV32I.core_desc"
 | 
					 | 
				
			||||||
import "CoreDSL-Instruction-Set-Description/RVM.core_desc"
 | 
					 | 
				
			||||||
import "CoreDSL-Instruction-Set-Description/RVC.core_desc"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Core TGC_B provides RV32I {
 | 
					 | 
				
			||||||
	architectural_state {
 | 
					 | 
				
			||||||
        unsigned XLEN=32;
 | 
					 | 
				
			||||||
        unsigned PCLEN=32;
 | 
					 | 
				
			||||||
        // definitions for the architecture wrapper
 | 
					 | 
				
			||||||
        //                    XL    ZYXWVUTSRQPONMLKJIHGFEDCBA
 | 
					 | 
				
			||||||
        unsigned MISA_VAL = 0b01000000000000000000000100000000;
 | 
					 | 
				
			||||||
        unsigned PGSIZE = 0x1000; //1 << 12;
 | 
					 | 
				
			||||||
        unsigned PGMASK = 0xfff; //PGSIZE-1
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Core TGC_C provides RV32I, RV32M, RV32IC {
 | 
					 | 
				
			||||||
    architectural_state {
 | 
					 | 
				
			||||||
        unsigned XLEN=32;
 | 
					 | 
				
			||||||
        unsigned PCLEN=32;
 | 
					 | 
				
			||||||
        // definitions for the architecture wrapper
 | 
					 | 
				
			||||||
        //                    XL    ZYXWVUTSRQPONMLKJIHGFEDCBA
 | 
					 | 
				
			||||||
        unsigned MISA_VAL = 0b01000000000000000001000100000100;
 | 
					 | 
				
			||||||
        unsigned PGSIZE = 0x1000; //1 << 12;
 | 
					 | 
				
			||||||
        unsigned PGMASK = 0xfff; //PGSIZE-1
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Core TGC_D provides RV32I, RV32M, RV32IC {
 | 
					 | 
				
			||||||
    architectural_state {
 | 
					 | 
				
			||||||
        unsigned XLEN=32;
 | 
					 | 
				
			||||||
        unsigned PCLEN=32;
 | 
					 | 
				
			||||||
        // definitions for the architecture wrapper
 | 
					 | 
				
			||||||
        //                    XL    ZYXWVUTSRQPONMLKJIHGFEDCBA
 | 
					 | 
				
			||||||
        unsigned MISA_VAL = 0b01000000000000000001000100000100;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										16
									
								
								gen_input/templates/CORENAME_instr.yaml.gtl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								gen_input/templates/CORENAME_instr.yaml.gtl
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
				
			|||||||
 | 
					<% def getInstructionGroups() {
 | 
				
			||||||
 | 
					    def instrGroups = [:]
 | 
				
			||||||
 | 
					    instructions.each {
 | 
				
			||||||
 | 
					        def groupName = it['instruction'].eContainer().name
 | 
				
			||||||
 | 
					        if(!instrGroups.containsKey(groupName)) {
 | 
				
			||||||
 | 
					            instrGroups[groupName]=[]
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        instrGroups[groupName]+=it;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    instrGroups
 | 
				
			||||||
 | 
					}%><%getInstructionGroups().each{name, instrList -> %>
 | 
				
			||||||
 | 
					${name}: <% instrList.findAll{!it.instruction.name.startsWith("__")}.each { %>
 | 
				
			||||||
 | 
					  - ${it.instruction.name}:
 | 
				
			||||||
 | 
					    encoding: ${it.encoding}
 | 
				
			||||||
 | 
					    mask: ${it.mask}<%}}%>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -324,6 +324,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
				
			|||||||
            if (is_jump_to_self_enabled(cond) &&
 | 
					            if (is_jump_to_self_enabled(cond) &&
 | 
				
			||||||
                    (insn == 0x0000006f || (insn&0xffff)==0xa001)) throw simulation_stopped(0); // 'J 0' or 'C.J 0'
 | 
					                    (insn == 0x0000006f || (insn&0xffff)==0xa001)) throw simulation_stopped(0); // 'J 0' or 'C.J 0'
 | 
				
			||||||
            auto f = decode_inst(insn);
 | 
					            auto f = decode_inst(insn);
 | 
				
			||||||
 | 
					            auto old_pc = pc.val;
 | 
				
			||||||
            pc = (this->*f)(pc, insn);
 | 
					            pc = (this->*f)(pc, insn);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -307,7 +307,7 @@ riscv_hart_m_p<BASE>::riscv_hart_m_p()
 | 
				
			|||||||
    // reset values
 | 
					    // reset values
 | 
				
			||||||
    csr[misa] = traits<BASE>::MISA_VAL;
 | 
					    csr[misa] = traits<BASE>::MISA_VAL;
 | 
				
			||||||
    csr[mvendorid] = 0x669;
 | 
					    csr[mvendorid] = 0x669;
 | 
				
			||||||
    csr[marchid] = 0x80000003;
 | 
					    csr[marchid] = traits<BASE>::MARCHID_VAL;
 | 
				
			||||||
    csr[mimpid] = 1;
 | 
					    csr[mimpid] = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    uart_buf.str("");
 | 
					    uart_buf.str("");
 | 
				
			||||||
@@ -362,8 +362,8 @@ riscv_hart_m_p<BASE>::riscv_hart_m_p()
 | 
				
			|||||||
    csr_rd_cb[mie] = &this_class::read_ie;
 | 
					    csr_rd_cb[mie] = &this_class::read_ie;
 | 
				
			||||||
    csr_wr_cb[mie] = &this_class::write_ie;
 | 
					    csr_wr_cb[mie] = &this_class::write_ie;
 | 
				
			||||||
    csr_rd_cb[mhartid] = &this_class::read_hartid;
 | 
					    csr_rd_cb[mhartid] = &this_class::read_hartid;
 | 
				
			||||||
    csr_rd_cb[mcounteren] = &this_class::read_null;
 | 
					//    csr_rd_cb[mcounteren] = &this_class::read_null;
 | 
				
			||||||
    csr_wr_cb[mcounteren] = &this_class::write_null;
 | 
					//    csr_wr_cb[mcounteren] = &this_class::write_null;
 | 
				
			||||||
    csr_wr_cb[misa] = &this_class::write_null;
 | 
					    csr_wr_cb[misa] = &this_class::write_null;
 | 
				
			||||||
    csr_wr_cb[mvendorid] = &this_class::write_null;
 | 
					    csr_wr_cb[mvendorid] = &this_class::write_null;
 | 
				
			||||||
    csr_wr_cb[marchid] = &this_class::write_null;
 | 
					    csr_wr_cb[marchid] = &this_class::write_null;
 | 
				
			||||||
@@ -920,7 +920,16 @@ template <typename BASE> uint64_t riscv_hart_m_p<BASE>::enter_trap(uint64_t flag
 | 
				
			|||||||
    if (trap_id == 0) { // exception
 | 
					    if (trap_id == 0) { // exception
 | 
				
			||||||
        // store ret addr in xepc register
 | 
					        // store ret addr in xepc register
 | 
				
			||||||
        csr[mepc] = static_cast<reg_t>(addr) & get_pc_mask(); // store actual address instruction of exception
 | 
					        csr[mepc] = static_cast<reg_t>(addr) & get_pc_mask(); // store actual address instruction of exception
 | 
				
			||||||
        csr[mtval] = cause==2?((instr & 0x3)==3?instr:instr&0xffff):fault_data;
 | 
					        switch(cause){
 | 
				
			||||||
 | 
					        case 0:
 | 
				
			||||||
 | 
					            csr[mtval] = addr;
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case 2:
 | 
				
			||||||
 | 
					            csr[mtval] = (instr & 0x3)==3?instr:instr&0xffff;
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        default:
 | 
				
			||||||
 | 
					            csr[mtval] = fault_data;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        fault_data = 0;
 | 
					        fault_data = 0;
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        csr[mepc] = this->reg.NEXT_PC & get_pc_mask(); // store next address if interrupt
 | 
					        csr[mepc] = this->reg.NEXT_PC & get_pc_mask(); // store next address if interrupt
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -145,7 +145,7 @@ public:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        mstatus_t mstatus;
 | 
					        mstatus_t mstatus;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        static const reg_t mstatus_reset_val = 0;
 | 
					        static const reg_t mstatus_reset_val = 0x1800;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void write_mstatus(T val, unsigned priv_lvl) {
 | 
					        void write_mstatus(T val, unsigned priv_lvl) {
 | 
				
			||||||
            auto mask = get_mask(priv_lvl);
 | 
					            auto mask = get_mask(priv_lvl);
 | 
				
			||||||
@@ -398,7 +398,7 @@ private:
 | 
				
			|||||||
    iss::status read_ip(unsigned addr, reg_t &val);
 | 
					    iss::status read_ip(unsigned addr, reg_t &val);
 | 
				
			||||||
    iss::status write_ip(unsigned addr, reg_t val);
 | 
					    iss::status write_ip(unsigned addr, reg_t val);
 | 
				
			||||||
    iss::status read_hartid(unsigned addr, reg_t &val);
 | 
					    iss::status read_hartid(unsigned addr, reg_t &val);
 | 
				
			||||||
    iss::status write_mepc(unsigned addr, reg_t val);
 | 
					    iss::status write_epc(unsigned addr, reg_t val);
 | 
				
			||||||
    iss::status read_satp(unsigned addr, reg_t &val);
 | 
					    iss::status read_satp(unsigned addr, reg_t &val);
 | 
				
			||||||
    iss::status write_satp(unsigned addr, reg_t val);
 | 
					    iss::status write_satp(unsigned addr, reg_t val);
 | 
				
			||||||
    iss::status read_fcsr(unsigned addr, reg_t &val);
 | 
					    iss::status read_fcsr(unsigned addr, reg_t &val);
 | 
				
			||||||
@@ -419,7 +419,7 @@ riscv_hart_msu_vp<BASE>::riscv_hart_msu_vp()
 | 
				
			|||||||
    // reset values
 | 
					    // reset values
 | 
				
			||||||
    csr[misa] = traits<BASE>::MISA_VAL;
 | 
					    csr[misa] = traits<BASE>::MISA_VAL;
 | 
				
			||||||
    csr[mvendorid] = 0x669;
 | 
					    csr[mvendorid] = 0x669;
 | 
				
			||||||
    csr[marchid] = 0x80000003;
 | 
					    csr[marchid] = traits<BASE>::MARCHID_VAL;
 | 
				
			||||||
    csr[mimpid] = 1;
 | 
					    csr[mimpid] = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    uart_buf.str("");
 | 
					    uart_buf.str("");
 | 
				
			||||||
@@ -954,7 +954,7 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_ip(unsigned
 | 
				
			|||||||
    return iss::Ok;
 | 
					    return iss::Ok;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template <typename BASE> iss::status riscv_hart_m_p<BASE>::write_epc(unsigned addr, reg_t val) {
 | 
					template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_epc(unsigned addr, reg_t val) {
 | 
				
			||||||
    csr[addr] = val & get_pc_mask();
 | 
					    csr[addr] = val & get_pc_mask();
 | 
				
			||||||
    return iss::Ok;
 | 
					    return iss::Ok;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -146,7 +146,7 @@ public:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        mstatus_t mstatus;
 | 
					        mstatus_t mstatus;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        static const reg_t mstatus_reset_val = 0;
 | 
					        static const reg_t mstatus_reset_val = 0x1800; // MPP set to 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void write_mstatus(T val, unsigned priv_lvl) {
 | 
					        void write_mstatus(T val, unsigned priv_lvl) {
 | 
				
			||||||
            auto mask = get_mask(priv_lvl);
 | 
					            auto mask = get_mask(priv_lvl);
 | 
				
			||||||
@@ -349,7 +349,7 @@ riscv_hart_mu_p<BASE, FEAT>::riscv_hart_mu_p()
 | 
				
			|||||||
    // reset values
 | 
					    // reset values
 | 
				
			||||||
    csr[misa] = traits<BASE>::MISA_VAL;
 | 
					    csr[misa] = traits<BASE>::MISA_VAL;
 | 
				
			||||||
    csr[mvendorid] = 0x669;
 | 
					    csr[mvendorid] = 0x669;
 | 
				
			||||||
    csr[marchid] = 0x80000004;
 | 
					    csr[marchid] = traits<BASE>::MARCHID_VAL;
 | 
				
			||||||
    csr[mimpid] = 1;
 | 
					    csr[mimpid] = 1;
 | 
				
			||||||
    csr[mclicbase] = 0xc0000000; // TODO: should be taken from YAML file
 | 
					    csr[mclicbase] = 0xc0000000; // TODO: should be taken from YAML file
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -543,25 +543,27 @@ template <typename BASE, features_e FEAT> bool riscv_hart_mu_p<BASE, FEAT>::pmp_
 | 
				
			|||||||
    constexpr auto PMP_NA4 =0x2U;
 | 
					    constexpr auto PMP_NA4 =0x2U;
 | 
				
			||||||
    constexpr auto PMP_NAPOT =0x3U;
 | 
					    constexpr auto PMP_NAPOT =0x3U;
 | 
				
			||||||
    reg_t base = 0;
 | 
					    reg_t base = 0;
 | 
				
			||||||
 | 
					    auto any_active = false;
 | 
				
			||||||
    for (size_t i = 0; i < 16; i++) {
 | 
					    for (size_t i = 0; i < 16; i++) {
 | 
				
			||||||
        reg_t tor = csr[pmpaddr0+i] << PMP_SHIFT;
 | 
					        reg_t tor = csr[pmpaddr0+i] << PMP_SHIFT;
 | 
				
			||||||
        uint8_t cfg = csr[pmpcfg0+(i/4)]>>(i%4);
 | 
					        uint8_t cfg = csr[pmpcfg0+(i/4)]>>(i%4);
 | 
				
			||||||
        if (cfg & PMP_A) {
 | 
					        if (cfg & PMP_A) {
 | 
				
			||||||
 | 
					            any_active=true;
 | 
				
			||||||
            auto pmp_a = (cfg & PMP_A) >> 3;
 | 
					            auto pmp_a = (cfg & PMP_A) >> 3;
 | 
				
			||||||
            bool is_tor = pmp_a == PMP_TOR;
 | 
					            auto is_tor = pmp_a == PMP_TOR;
 | 
				
			||||||
            bool is_na4 = pmp_a == PMP_NA4;
 | 
					            auto is_na4 = pmp_a == PMP_NA4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            reg_t mask = (csr[pmpaddr0+i] << 1) | (!is_na4);
 | 
					            reg_t mask = (csr[pmpaddr0+i] << 1) | (!is_na4);
 | 
				
			||||||
            mask = ~(mask & ~(mask + 1)) << PMP_SHIFT;
 | 
					            mask = ~(mask & ~(mask + 1)) << PMP_SHIFT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Check each 4-byte sector of the access
 | 
					            // Check each 4-byte sector of the access
 | 
				
			||||||
            bool any_match = false;
 | 
					            auto any_match = false;
 | 
				
			||||||
            bool all_match = true;
 | 
					            auto all_match = true;
 | 
				
			||||||
            for (reg_t offset = 0; offset < len; offset += 1 << PMP_SHIFT) {
 | 
					            for (reg_t offset = 0; offset < len; offset += 1 << PMP_SHIFT) {
 | 
				
			||||||
                reg_t cur_addr = addr + offset;
 | 
					                reg_t cur_addr = addr + offset;
 | 
				
			||||||
                bool napot_match = ((cur_addr ^ tor) & mask) == 0;
 | 
					                auto napot_match = ((cur_addr ^ tor) & mask) == 0;
 | 
				
			||||||
                bool tor_match = base <= cur_addr && cur_addr < tor;
 | 
					                auto tor_match = base <= cur_addr && cur_addr < tor;
 | 
				
			||||||
                bool match = is_tor ? tor_match : napot_match;
 | 
					                auto match = is_tor ? tor_match : napot_match;
 | 
				
			||||||
                any_match |= match;
 | 
					                any_match |= match;
 | 
				
			||||||
                all_match &= match;
 | 
					                all_match &= match;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@@ -577,7 +579,7 @@ template <typename BASE, features_e FEAT> bool riscv_hart_mu_p<BASE, FEAT>::pmp_
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        base = tor;
 | 
					        base = tor;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return this->reg.PRIV == PRIV_M;
 | 
					    return !any_active || this->reg.PRIV == PRIV_M;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -926,8 +928,6 @@ template <typename BASE, features_e FEAT> iss::status riscv_hart_mu_p<BASE, FEAT
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
template <typename BASE, features_e FEAT> iss::status riscv_hart_mu_p<BASE, FEAT>::write_ie(unsigned addr, reg_t val) {
 | 
					template <typename BASE, features_e FEAT> iss::status riscv_hart_mu_p<BASE, FEAT>::write_ie(unsigned addr, reg_t val) {
 | 
				
			||||||
    auto mask = get_irq_wrmask((addr >> 8) & 0x3);
 | 
					    auto mask = get_irq_wrmask((addr >> 8) & 0x3);
 | 
				
			||||||
    if(this->reg.PRIV==0)
 | 
					 | 
				
			||||||
        mask&= ~(0xff<<4); // STIE and UTIE are read only in user and supervisor mode
 | 
					 | 
				
			||||||
    csr[mie] = (csr[mie] & ~mask) | (val & mask);
 | 
					    csr[mie] = (csr[mie] & ~mask) | (val & mask);
 | 
				
			||||||
    check_interrupt();
 | 
					    check_interrupt();
 | 
				
			||||||
    return iss::Ok;
 | 
					    return iss::Ok;
 | 
				
			||||||
@@ -1256,6 +1256,11 @@ template <typename BASE, features_e FEAT> uint64_t riscv_hart_mu_p<BASE, FEAT>::
 | 
				
			|||||||
template <typename BASE, features_e FEAT> uint64_t riscv_hart_mu_p<BASE, FEAT>::leave_trap(uint64_t flags) {
 | 
					template <typename BASE, features_e FEAT> uint64_t riscv_hart_mu_p<BASE, FEAT>::leave_trap(uint64_t flags) {
 | 
				
			||||||
    auto cur_priv = this->reg.PRIV;
 | 
					    auto cur_priv = this->reg.PRIV;
 | 
				
			||||||
    auto inst_priv = (flags & 0x3)? 3:0;
 | 
					    auto inst_priv = (flags & 0x3)? 3:0;
 | 
				
			||||||
 | 
					    if(inst_priv>cur_priv){
 | 
				
			||||||
 | 
					        auto trap_val =  0x80ULL << 24 | (2 << 16); // illegal instruction
 | 
				
			||||||
 | 
					        this->reg.trap_state = trap_val;
 | 
				
			||||||
 | 
					        this->reg.NEXT_PC = std::numeric_limits<uint32_t>::max();
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
        auto status = state.mstatus;
 | 
					        auto status = state.mstatus;
 | 
				
			||||||
        // pop the relevant lower-privilege interrupt enable and privilege mode stack
 | 
					        // pop the relevant lower-privilege interrupt enable and privilege mode stack
 | 
				
			||||||
        // clear respective yIE
 | 
					        // clear respective yIE
 | 
				
			||||||
@@ -1277,6 +1282,7 @@ template <typename BASE, features_e FEAT> uint64_t riscv_hart_mu_p<BASE, FEAT>::
 | 
				
			|||||||
        CLOG(INFO, disass) << "Executing xRET , changing privilege level from " << lvl[cur_priv] << " to "
 | 
					        CLOG(INFO, disass) << "Executing xRET , changing privilege level from " << lvl[cur_priv] << " to "
 | 
				
			||||||
                           << lvl[this->reg.PRIV];
 | 
					                           << lvl[this->reg.PRIV];
 | 
				
			||||||
        check_interrupt();
 | 
					        check_interrupt();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    return this->reg.NEXT_PC;
 | 
					    return this->reg.NEXT_PC;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -51,9 +51,9 @@ template <> struct traits<tgc_c> {
 | 
				
			|||||||
        {"X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "X10", "X11", "X12", "X13", "X14", "X15", "X16", "X17", "X18", "X19", "X20", "X21", "X22", "X23", "X24", "X25", "X26", "X27", "X28", "X29", "X30", "X31", "PC", "NEXT_PC", "PRIV"}};
 | 
					        {"X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "X10", "X11", "X12", "X13", "X14", "X15", "X16", "X17", "X18", "X19", "X20", "X21", "X22", "X23", "X24", "X25", "X26", "X27", "X28", "X29", "X30", "X31", "PC", "NEXT_PC", "PRIV"}};
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
    static constexpr std::array<const char*, 35> reg_aliases{
 | 
					    static constexpr std::array<const char*, 35> reg_aliases{
 | 
				
			||||||
        {"X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "X10", "X11", "X12", "X13", "X14", "X15", "X16", "X17", "X18", "X19", "X20", "X21", "X22", "X23", "X24", "X25", "X26", "X27", "X28", "X29", "X30", "X31", "PC", "NEXT_PC", "PRIV"}};
 | 
					        {"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"}};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    enum constants {XLEN=32, PCLEN=32, MISA_VAL=0b01000000000000000001000100000100, PGSIZE=0x1000, PGMASK=0b111111111111, CSR_SIZE=4096, fence=0, fencei=1, fencevmal=2, fencevmau=3, MUL_LEN=64};
 | 
					    enum constants {MISA_VAL=0b01000000000000000001000100000100, MARCHID_VAL=0x80000003, XLEN=32, CSR_SIZE=4096, INSTR_ALIGNMENT=2, fence=0, fencei=1, fencevmal=2, fencevmau=3, MUL_LEN=64};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    constexpr static unsigned FP_REGS_SIZE = 0;
 | 
					    constexpr static unsigned FP_REGS_SIZE = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										11
									
								
								src/main.cpp
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								src/main.cpp
									
									
									
									
									
								
							@@ -49,6 +49,11 @@ using tgc_b_plat_type = iss::arch::riscv_hart_m_p<iss::arch::tgc_b>;
 | 
				
			|||||||
#include "iss/arch/tgc_d.h"
 | 
					#include "iss/arch/tgc_d.h"
 | 
				
			||||||
using tgc_d_plat_type = iss::arch::riscv_hart_mu_p<iss::arch::tgc_d, (iss::arch::features_e)(iss::arch::FEAT_PMP | iss::arch::FEAT_CLIC | iss::arch::FEAT_EXT_N)>;
 | 
					using tgc_d_plat_type = iss::arch::riscv_hart_mu_p<iss::arch::tgc_d, (iss::arch::features_e)(iss::arch::FEAT_PMP | iss::arch::FEAT_CLIC | iss::arch::FEAT_EXT_N)>;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					#ifdef CORE_TGC_D_XRB_MAC
 | 
				
			||||||
 | 
					#include "iss/arch/riscv_hart_mu_p.h"
 | 
				
			||||||
 | 
					#include "iss/arch/tgc_d_xrb_mac.h"
 | 
				
			||||||
 | 
					using tgc_d_xrb_mac_plat_type = iss::arch::riscv_hart_mu_p<iss::arch::tgc_d_xrb_mac, (iss::arch::features_e)(iss::arch::FEAT_PMP | iss::arch::FEAT_CLIC | iss::arch::FEAT_EXT_N)>;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
#ifdef WITH_LLVM
 | 
					#ifdef WITH_LLVM
 | 
				
			||||||
#include <iss/llvm/jit_helper.h>
 | 
					#include <iss/llvm/jit_helper.h>
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
@@ -138,6 +143,12 @@ int main(int argc, char *argv[]) {
 | 
				
			|||||||
            std::tie(cpu, vm) =
 | 
					            std::tie(cpu, vm) =
 | 
				
			||||||
                iss::create_cpu<tgc_d_plat_type>(clim["backend"].as<std::string>(), clim["gdb-port"].as<unsigned>());
 | 
					                iss::create_cpu<tgc_d_plat_type>(clim["backend"].as<std::string>(), clim["gdb-port"].as<unsigned>());
 | 
				
			||||||
        } else
 | 
					        } else
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#ifdef CORE_TGC_D_XRB_MAC
 | 
				
			||||||
 | 
					        if (isa_opt == "tgc_d_xrb_mac") {
 | 
				
			||||||
 | 
					            std::tie(cpu, vm) =
 | 
				
			||||||
 | 
					                iss::create_cpu<tgc_d_xrb_mac_plat_type>(clim["backend"].as<std::string>(), clim["gdb-port"].as<unsigned>());
 | 
				
			||||||
 | 
					        } else
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            LOG(ERROR) << "Illegal argument value for '--isa': " << clim["isa"].as<std::string>() << std::endl;
 | 
					            LOG(ERROR) << "Illegal argument value for '--isa': " << clim["isa"].as<std::string>() << std::endl;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -44,6 +44,11 @@ using tgc_c_plat_type = iss::arch::riscv_hart_m_p<iss::arch::tgc_c>;
 | 
				
			|||||||
#include "iss/arch/tgc_d.h"
 | 
					#include "iss/arch/tgc_d.h"
 | 
				
			||||||
using tgc_d_plat_type = iss::arch::riscv_hart_mu_p<iss::arch::tgc_d, iss::arch::FEAT_PMP>;
 | 
					using tgc_d_plat_type = iss::arch::riscv_hart_mu_p<iss::arch::tgc_d, iss::arch::FEAT_PMP>;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					#ifdef CORE_TGC_D_XRB_MAC
 | 
				
			||||||
 | 
					#include "iss/arch/riscv_hart_mu_p.h"
 | 
				
			||||||
 | 
					#include "iss/arch/tgc_d_xrb_mac.h"
 | 
				
			||||||
 | 
					using tgc_d_xrb_mac_plat_type = iss::arch::riscv_hart_mu_p<iss::arch::tgc_d_xrb_mac, iss::arch::FEAT_PMP>;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
#include "iss/debugger/encoderdecoder.h"
 | 
					#include "iss/debugger/encoderdecoder.h"
 | 
				
			||||||
#include "iss/debugger/gdb_session.h"
 | 
					#include "iss/debugger/gdb_session.h"
 | 
				
			||||||
#include "iss/debugger/server.h"
 | 
					#include "iss/debugger/server.h"
 | 
				
			||||||
@@ -285,6 +290,9 @@ public:
 | 
				
			|||||||
#endif
 | 
					#endif
 | 
				
			||||||
#ifdef CORE_TGC_D
 | 
					#ifdef CORE_TGC_D
 | 
				
			||||||
        CREATE_CORE(tgc_d)
 | 
					        CREATE_CORE(tgc_d)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#ifdef CORE_TGC_D_XRB_MACD
 | 
				
			||||||
 | 
					        CREATE_CORE(tgc_d_xrb_mac)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            LOG(ERROR) << "Illegal argument value for core type: " << type << std::endl;
 | 
					            LOG(ERROR) << "Illegal argument value for core type: " << type << std::endl;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -463,9 +463,14 @@ private:
 | 
				
			|||||||
        // execute instruction
 | 
					        // execute instruction
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
					            if(imm % traits::INSTR_ALIGNMENT) {
 | 
				
			||||||
 | 
					                raise(0,  0);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else {
 | 
				
			||||||
                if(rd != 0) *(X+rd) = *PC + 4; 
 | 
					                if(rd != 0) *(X+rd) = *PC + 4; 
 | 
				
			||||||
                pc_assign(*NEXT_PC) = *PC + (int32_t)sext<21>(imm);
 | 
					                pc_assign(*NEXT_PC) = *PC + (int32_t)sext<21>(imm);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        } catch(...){}
 | 
					        } catch(...){}
 | 
				
			||||||
        // post execution stuff
 | 
					        // post execution stuff
 | 
				
			||||||
        if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 2);
 | 
					        if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 2);
 | 
				
			||||||
@@ -507,10 +512,15 @@ private:
 | 
				
			|||||||
        // execute instruction
 | 
					        // execute instruction
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            int32_t new_pc = *(X+rs1) + (int16_t)sext<12>(imm);
 | 
					            int32_t new_pc = (*(X+rs1) + (int16_t)sext<12>(imm)) & ~ 1;
 | 
				
			||||||
 | 
					            if(new_pc % traits::INSTR_ALIGNMENT) {
 | 
				
			||||||
 | 
					                raise(0,  0);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else {
 | 
				
			||||||
                if(rd != 0) *(X+rd) = *PC + 4; 
 | 
					                if(rd != 0) *(X+rd) = *PC + 4; 
 | 
				
			||||||
                pc_assign(*NEXT_PC) = new_pc & ~ 0x1;
 | 
					                pc_assign(*NEXT_PC) = new_pc & ~ 0x1;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        } catch(...){}
 | 
					        } catch(...){}
 | 
				
			||||||
        // post execution stuff
 | 
					        // post execution stuff
 | 
				
			||||||
        if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 3);
 | 
					        if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 3);
 | 
				
			||||||
@@ -551,7 +561,12 @@ private:
 | 
				
			|||||||
        *NEXT_PC = *PC + 4;
 | 
					        *NEXT_PC = *PC + 4;
 | 
				
			||||||
        // execute instruction
 | 
					        // execute instruction
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
        if(*(X+rs1) == *(X+rs2)) pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm); 
 | 
					        {
 | 
				
			||||||
 | 
					            if(*(X+rs1) == *(X+rs2)) if(imm % traits::INSTR_ALIGNMENT) {
 | 
				
			||||||
 | 
					                raise(0,  0);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        } catch(...){}
 | 
					        } catch(...){}
 | 
				
			||||||
        // post execution stuff
 | 
					        // post execution stuff
 | 
				
			||||||
        if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 4);
 | 
					        if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 4);
 | 
				
			||||||
@@ -592,7 +607,12 @@ private:
 | 
				
			|||||||
        *NEXT_PC = *PC + 4;
 | 
					        *NEXT_PC = *PC + 4;
 | 
				
			||||||
        // execute instruction
 | 
					        // execute instruction
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
        if(*(X+rs1) != *(X+rs2)) pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm); 
 | 
					        {
 | 
				
			||||||
 | 
					            if(*(X+rs1) != *(X+rs2)) if(imm % traits::INSTR_ALIGNMENT) {
 | 
				
			||||||
 | 
					                raise(0,  0);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        } catch(...){}
 | 
					        } catch(...){}
 | 
				
			||||||
        // post execution stuff
 | 
					        // post execution stuff
 | 
				
			||||||
        if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 5);
 | 
					        if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 5);
 | 
				
			||||||
@@ -633,7 +653,12 @@ private:
 | 
				
			|||||||
        *NEXT_PC = *PC + 4;
 | 
					        *NEXT_PC = *PC + 4;
 | 
				
			||||||
        // execute instruction
 | 
					        // execute instruction
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
        if((int32_t)*(X+rs1) < (int32_t)*(X+rs2)) pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm); 
 | 
					        {
 | 
				
			||||||
 | 
					            if((int32_t)*(X+rs1) < (int32_t)*(X+rs2)) if(imm % traits::INSTR_ALIGNMENT) {
 | 
				
			||||||
 | 
					                raise(0,  0);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        } catch(...){}
 | 
					        } catch(...){}
 | 
				
			||||||
        // post execution stuff
 | 
					        // post execution stuff
 | 
				
			||||||
        if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 6);
 | 
					        if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 6);
 | 
				
			||||||
@@ -674,7 +699,12 @@ private:
 | 
				
			|||||||
        *NEXT_PC = *PC + 4;
 | 
					        *NEXT_PC = *PC + 4;
 | 
				
			||||||
        // execute instruction
 | 
					        // execute instruction
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
        if((int32_t)*(X+rs1) >= (int32_t)*(X+rs2)) pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm); 
 | 
					        {
 | 
				
			||||||
 | 
					            if((int32_t)*(X+rs1) >= (int32_t)*(X+rs2)) if(imm % traits::INSTR_ALIGNMENT) {
 | 
				
			||||||
 | 
					                raise(0,  0);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        } catch(...){}
 | 
					        } catch(...){}
 | 
				
			||||||
        // post execution stuff
 | 
					        // post execution stuff
 | 
				
			||||||
        if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 7);
 | 
					        if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 7);
 | 
				
			||||||
@@ -715,7 +745,12 @@ private:
 | 
				
			|||||||
        *NEXT_PC = *PC + 4;
 | 
					        *NEXT_PC = *PC + 4;
 | 
				
			||||||
        // execute instruction
 | 
					        // execute instruction
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
        if(*(X+rs1) < *(X+rs2)) pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm); 
 | 
					        {
 | 
				
			||||||
 | 
					            if(*(X+rs1) < *(X+rs2)) if(imm % traits::INSTR_ALIGNMENT) {
 | 
				
			||||||
 | 
					                raise(0,  0);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        } catch(...){}
 | 
					        } catch(...){}
 | 
				
			||||||
        // post execution stuff
 | 
					        // post execution stuff
 | 
				
			||||||
        if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 8);
 | 
					        if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 8);
 | 
				
			||||||
@@ -756,7 +791,12 @@ private:
 | 
				
			|||||||
        *NEXT_PC = *PC + 4;
 | 
					        *NEXT_PC = *PC + 4;
 | 
				
			||||||
        // execute instruction
 | 
					        // execute instruction
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
        if(*(X+rs1) >= *(X+rs2)) pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm); 
 | 
					        {
 | 
				
			||||||
 | 
					            if(*(X+rs1) >= *(X+rs2)) if(imm % traits::INSTR_ALIGNMENT) {
 | 
				
			||||||
 | 
					                raise(0,  0);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else pc_assign(*NEXT_PC) = *PC + (int16_t)sext<13>(imm);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        } catch(...){}
 | 
					        } catch(...){}
 | 
				
			||||||
        // post execution stuff
 | 
					        // post execution stuff
 | 
				
			||||||
        if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 9);
 | 
					        if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 9);
 | 
				
			||||||
@@ -4138,9 +4178,10 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
				
			|||||||
            this->do_sync(POST_SYNC, std::numeric_limits<unsigned>::max());
 | 
					            this->do_sync(POST_SYNC, std::numeric_limits<unsigned>::max());
 | 
				
			||||||
            pc.val = super::core.enter_trap(std::numeric_limits<uint64_t>::max(), pc.val, 0);
 | 
					            pc.val = super::core.enter_trap(std::numeric_limits<uint64_t>::max(), pc.val, 0);
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            if (is_jump_to_self_enabled(cond) && (insn == 0x0000006f || (insn&0xffff)==0xa001))
 | 
					            if (is_jump_to_self_enabled(cond) &&
 | 
				
			||||||
                throw simulation_stopped(0); // 'J 0' or 'C.J 0'
 | 
					                    (insn == 0x0000006f || (insn&0xffff)==0xa001)) throw simulation_stopped(0); // 'J 0' or 'C.J 0'
 | 
				
			||||||
            auto f = decode_inst(insn);
 | 
					            auto f = decode_inst(insn);
 | 
				
			||||||
 | 
					            auto old_pc = pc.val;
 | 
				
			||||||
            pc = (this->*f)(pc, insn);
 | 
					            pc = (this->*f)(pc, insn);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user