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