Compare commits
	
		
			1 Commits
		
	
	
		
			f585489ff5
			...
			8c701d55c1
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 8c701d55c1 | 
| @@ -8,6 +8,7 @@ include(GNUInstallDirs) | ||||
|  | ||||
| find_package(elfio QUIET) | ||||
| find_package(Boost COMPONENTS coroutine) | ||||
| find_package(jsoncpp) | ||||
|  | ||||
| if(WITH_LLVM) | ||||
|     if(DEFINED ENV{LLVM_HOME}) | ||||
|   | ||||
| @@ -358,8 +358,13 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 *NEXT_PC = *PC + 4; | ||||
|                 // execute instruction | ||||
|                 { | ||||
|                                 if((rd % traits::RFS) !=  0) { | ||||
|                                     *(X+rd % traits::RFS) = (int32_t)imm; | ||||
|                                 if(rd >= traits::RFS) { | ||||
|                                     raise(0,  2); | ||||
|                                 } | ||||
|                                 else { | ||||
|                                     if(rd !=  0) { | ||||
|                                         *(X+rd) = (int32_t)imm; | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                 TRAP_LUI:break; | ||||
| @@ -379,8 +384,13 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 *NEXT_PC = *PC + 4; | ||||
|                 // execute instruction | ||||
|                 { | ||||
|                                 if((rd % traits::RFS) !=  0) { | ||||
|                                     *(X+rd % traits::RFS) = *PC + (int32_t)imm; | ||||
|                                 if(rd >= traits::RFS) { | ||||
|                                     raise(0,  2); | ||||
|                                 } | ||||
|                                 else { | ||||
|                                     if(rd !=  0) { | ||||
|                                         *(X+rd) = *PC + (int32_t)imm; | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                 TRAP_AUIPC:break; | ||||
| @@ -400,17 +410,22 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 *NEXT_PC = *PC + 4; | ||||
|                 // execute instruction | ||||
|                 { | ||||
|                                 if(rd >= traits::RFS) { | ||||
|                                     raise(0,  2); | ||||
|                                 } | ||||
|                                 else { | ||||
|                                     if(imm % traits::INSTR_ALIGNMENT) { | ||||
|                                         raise(0,  0); | ||||
|                                     } | ||||
|                                     else { | ||||
|                         if((rd % traits::RFS) !=  0) { | ||||
|                             *(X+rd % traits::RFS) = *PC +  4; | ||||
|                                         if(rd !=  0) { | ||||
|                                             *(X+rd) = *PC +  4; | ||||
|                                         } | ||||
|                                         *NEXT_PC = *PC + (int32_t)sext<21>(imm); | ||||
|                                         super::ex_info.branch_taken=true; | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                 TRAP_JAL:break; | ||||
|             }// @suppress("No break at end of case") | ||||
|             case arch::traits<ARCH>::opcode_e::JALR: { | ||||
| @@ -429,18 +444,23 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 *NEXT_PC = *PC + 4; | ||||
|                 // execute instruction | ||||
|                 { | ||||
|                                 if(rd >= traits::RFS || rs1 >= traits::RFS) { | ||||
|                                     raise(0,  2); | ||||
|                                 } | ||||
|                                 else { | ||||
|                                     uint32_t new_pc = (*(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm)) & ~ 0x1; | ||||
|                                     if(new_pc % traits::INSTR_ALIGNMENT) { | ||||
|                                         raise(0,  0); | ||||
|                                     } | ||||
|                                     else { | ||||
|                         if((rd % traits::RFS) !=  0) { | ||||
|                             *(X+rd % traits::RFS) = *PC +  4; | ||||
|                                         if(rd !=  0) { | ||||
|                                             *(X+rd) = *PC +  4; | ||||
|                                         } | ||||
|                                         *NEXT_PC = new_pc & ~ 0x1; | ||||
|                                         super::ex_info.branch_taken=true; | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                 TRAP_JALR:break; | ||||
|             }// @suppress("No break at end of case") | ||||
|             case arch::traits<ARCH>::opcode_e::BEQ: { | ||||
| @@ -459,6 +479,10 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 *NEXT_PC = *PC + 4; | ||||
|                 // execute instruction | ||||
|                 { | ||||
|                                 if(rs2 >= traits::RFS || rs1 >= traits::RFS) { | ||||
|                                     raise(0,  2); | ||||
|                                 } | ||||
|                                 else { | ||||
|                                     if(*(X+rs1 % traits::RFS) == *(X+rs2 % traits::RFS)) { | ||||
|                                         if(imm % traits::INSTR_ALIGNMENT) { | ||||
|                                             raise(0,  0); | ||||
| @@ -469,6 +493,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                                         } | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                 TRAP_BEQ:break; | ||||
|             }// @suppress("No break at end of case") | ||||
|             case arch::traits<ARCH>::opcode_e::BNE: { | ||||
| @@ -487,6 +512,10 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 *NEXT_PC = *PC + 4; | ||||
|                 // execute instruction | ||||
|                 { | ||||
|                                 if(rs2 >= traits::RFS || rs1 >= traits::RFS) { | ||||
|                                     raise(0,  2); | ||||
|                                 } | ||||
|                                 else { | ||||
|                                     if(*(X+rs1 % traits::RFS) != *(X+rs2 % traits::RFS)) { | ||||
|                                         if(imm % traits::INSTR_ALIGNMENT) { | ||||
|                                             raise(0,  0); | ||||
| @@ -497,6 +526,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                                         } | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                 TRAP_BNE:break; | ||||
|             }// @suppress("No break at end of case") | ||||
|             case arch::traits<ARCH>::opcode_e::BLT: { | ||||
| @@ -515,6 +545,10 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 *NEXT_PC = *PC + 4; | ||||
|                 // execute instruction | ||||
|                 { | ||||
|                                 if(rs2 >= traits::RFS || rs1 >= traits::RFS) { | ||||
|                                     raise(0,  2); | ||||
|                                 } | ||||
|                                 else { | ||||
|                                     if((int32_t)*(X+rs1 % traits::RFS) < (int32_t)*(X+rs2 % traits::RFS)) { | ||||
|                                         if(imm % traits::INSTR_ALIGNMENT) { | ||||
|                                             raise(0,  0); | ||||
| @@ -525,6 +559,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                                         } | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                 TRAP_BLT:break; | ||||
|             }// @suppress("No break at end of case") | ||||
|             case arch::traits<ARCH>::opcode_e::BGE: { | ||||
| @@ -543,6 +578,10 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 *NEXT_PC = *PC + 4; | ||||
|                 // execute instruction | ||||
|                 { | ||||
|                                 if(rs2 >= traits::RFS || rs1 >= traits::RFS) { | ||||
|                                     raise(0,  2); | ||||
|                                 } | ||||
|                                 else { | ||||
|                                     if((int32_t)*(X+rs1 % traits::RFS) >= (int32_t)*(X+rs2 % traits::RFS)) { | ||||
|                                         if(imm % traits::INSTR_ALIGNMENT) { | ||||
|                                             raise(0,  0); | ||||
| @@ -553,6 +592,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                                         } | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                 TRAP_BGE:break; | ||||
|             }// @suppress("No break at end of case") | ||||
|             case arch::traits<ARCH>::opcode_e::BLTU: { | ||||
| @@ -571,6 +611,10 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 *NEXT_PC = *PC + 4; | ||||
|                 // execute instruction | ||||
|                 { | ||||
|                                 if(rs2 >= traits::RFS || rs1 >= traits::RFS) { | ||||
|                                     raise(0,  2); | ||||
|                                 } | ||||
|                                 else { | ||||
|                                     if(*(X+rs1 % traits::RFS) < *(X+rs2 % traits::RFS)) { | ||||
|                                         if(imm % traits::INSTR_ALIGNMENT) { | ||||
|                                             raise(0,  0); | ||||
| @@ -581,6 +625,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                                         } | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                 TRAP_BLTU:break; | ||||
|             }// @suppress("No break at end of case") | ||||
|             case arch::traits<ARCH>::opcode_e::BGEU: { | ||||
| @@ -599,6 +644,10 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 *NEXT_PC = *PC + 4; | ||||
|                 // execute instruction | ||||
|                 { | ||||
|                                 if(rs2 >= traits::RFS || rs1 >= traits::RFS) { | ||||
|                                     raise(0,  2); | ||||
|                                 } | ||||
|                                 else { | ||||
|                                     if(*(X+rs1 % traits::RFS) >= *(X+rs2 % traits::RFS)) { | ||||
|                                         if(imm % traits::INSTR_ALIGNMENT) { | ||||
|                                             raise(0,  0); | ||||
| @@ -609,6 +658,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                                         } | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                 TRAP_BGEU:break; | ||||
|             }// @suppress("No break at end of case") | ||||
|             case arch::traits<ARCH>::opcode_e::LB: { | ||||
| @@ -627,12 +677,17 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 *NEXT_PC = *PC + 4; | ||||
|                 // execute instruction | ||||
|                 { | ||||
|                                 if(rd >= traits::RFS || rs1 >= traits::RFS) { | ||||
|                                     raise(0,  2); | ||||
|                                 } | ||||
|                                 else { | ||||
|                                     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>=0x80000000UL) goto TRAP_LB; | ||||
|                                     int8_t res = (int8_t)read_res; | ||||
|                     if((rd % traits::RFS) !=  0) { | ||||
|                         *(X+rd % traits::RFS) = (int32_t)res; | ||||
|                                     if(rd !=  0) { | ||||
|                                         *(X+rd) = (int32_t)res; | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                 TRAP_LB:break; | ||||
| @@ -653,12 +708,17 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 *NEXT_PC = *PC + 4; | ||||
|                 // execute instruction | ||||
|                 { | ||||
|                                 if(rd >= traits::RFS || rs1 >= traits::RFS) { | ||||
|                                     raise(0,  2); | ||||
|                                 } | ||||
|                                 else { | ||||
|                                     uint32_t load_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); | ||||
|                                     int16_t read_res = super::template read_mem<int16_t>(traits::MEM, load_address); | ||||
|                                     if(this->core.trap_state>=0x80000000UL) goto TRAP_LH; | ||||
|                                     int16_t res = (int16_t)read_res; | ||||
|                     if((rd % traits::RFS) !=  0) { | ||||
|                         *(X+rd % traits::RFS) = (int32_t)res; | ||||
|                                     if(rd !=  0) { | ||||
|                                         *(X+rd) = (int32_t)res; | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                 TRAP_LH:break; | ||||
| @@ -679,12 +739,17 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 *NEXT_PC = *PC + 4; | ||||
|                 // execute instruction | ||||
|                 { | ||||
|                                 if(rd >= traits::RFS || rs1 >= traits::RFS) { | ||||
|                                     raise(0,  2); | ||||
|                                 } | ||||
|                                 else { | ||||
|                                     uint32_t load_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); | ||||
|                                     int32_t read_res = super::template read_mem<int32_t>(traits::MEM, load_address); | ||||
|                                     if(this->core.trap_state>=0x80000000UL) goto TRAP_LW; | ||||
|                                     int32_t res = (int32_t)read_res; | ||||
|                     if((rd % traits::RFS) !=  0) { | ||||
|                         *(X+rd % traits::RFS) = (int32_t)res; | ||||
|                                     if(rd !=  0) { | ||||
|                                         *(X+rd) = (int32_t)res; | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                 TRAP_LW:break; | ||||
| @@ -705,12 +770,17 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 *NEXT_PC = *PC + 4; | ||||
|                 // execute instruction | ||||
|                 { | ||||
|                                 if(rd >= traits::RFS || rs1 >= traits::RFS) { | ||||
|                                     raise(0,  2); | ||||
|                                 } | ||||
|                                 else { | ||||
|                                     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>=0x80000000UL) goto TRAP_LBU; | ||||
|                                     uint8_t res = (uint8_t)read_res; | ||||
|                     if((rd % traits::RFS) !=  0) { | ||||
|                         *(X+rd % traits::RFS) = (uint32_t)res; | ||||
|                                     if(rd !=  0) { | ||||
|                                         *(X+rd) = (uint32_t)res; | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                 TRAP_LBU:break; | ||||
| @@ -731,12 +801,17 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 *NEXT_PC = *PC + 4; | ||||
|                 // execute instruction | ||||
|                 { | ||||
|                                 if(rd >= traits::RFS || rs1 >= traits::RFS) { | ||||
|                                     raise(0,  2); | ||||
|                                 } | ||||
|                                 else { | ||||
|                                     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); | ||||
|                                     if(this->core.trap_state>=0x80000000UL) goto TRAP_LHU; | ||||
|                                     uint16_t res = (uint16_t)read_res; | ||||
|                     if((rd % traits::RFS) !=  0) { | ||||
|                         *(X+rd % traits::RFS) = (uint32_t)res; | ||||
|                                     if(rd !=  0) { | ||||
|                                         *(X+rd) = (uint32_t)res; | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                 TRAP_LHU:break; | ||||
| @@ -757,10 +832,15 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 *NEXT_PC = *PC + 4; | ||||
|                 // execute instruction | ||||
|                 { | ||||
|                                 if(rs2 >= traits::RFS || rs1 >= traits::RFS) { | ||||
|                                     raise(0,  2); | ||||
|                                 } | ||||
|                                 else { | ||||
|                                     uint32_t store_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); | ||||
|                                     super::template write_mem<uint8_t>(traits::MEM, store_address, (int8_t)*(X+rs2 % traits::RFS)); | ||||
|                                     if(this->core.trap_state>=0x80000000UL) goto TRAP_SB; | ||||
|                                 } | ||||
|                             } | ||||
|                 TRAP_SB:break; | ||||
|             }// @suppress("No break at end of case") | ||||
|             case arch::traits<ARCH>::opcode_e::SH: { | ||||
| @@ -779,10 +859,15 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 *NEXT_PC = *PC + 4; | ||||
|                 // execute instruction | ||||
|                 { | ||||
|                                 if(rs2 >= traits::RFS || rs1 >= traits::RFS) { | ||||
|                                     raise(0,  2); | ||||
|                                 } | ||||
|                                 else { | ||||
|                                     uint32_t store_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); | ||||
|                                     super::template write_mem<uint16_t>(traits::MEM, store_address, (int16_t)*(X+rs2 % traits::RFS)); | ||||
|                                     if(this->core.trap_state>=0x80000000UL) goto TRAP_SH; | ||||
|                                 } | ||||
|                             } | ||||
|                 TRAP_SH:break; | ||||
|             }// @suppress("No break at end of case") | ||||
|             case arch::traits<ARCH>::opcode_e::SW: { | ||||
| @@ -801,10 +886,15 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 *NEXT_PC = *PC + 4; | ||||
|                 // execute instruction | ||||
|                 { | ||||
|                                 if(rs2 >= traits::RFS || rs1 >= traits::RFS) { | ||||
|                                     raise(0,  2); | ||||
|                                 } | ||||
|                                 else { | ||||
|                                     uint32_t store_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); | ||||
|                                     super::template write_mem<uint32_t>(traits::MEM, store_address, (int32_t)*(X+rs2 % traits::RFS)); | ||||
|                                     if(this->core.trap_state>=0x80000000UL) goto TRAP_SW; | ||||
|                                 } | ||||
|                             } | ||||
|                 TRAP_SW:break; | ||||
|             }// @suppress("No break at end of case") | ||||
|             case arch::traits<ARCH>::opcode_e::ADDI: { | ||||
| @@ -823,8 +913,13 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 *NEXT_PC = *PC + 4; | ||||
|                 // execute instruction | ||||
|                 { | ||||
|                                 if((rd % traits::RFS) !=  0) { | ||||
|                                     *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); | ||||
|                                 if(rd >= traits::RFS || rs1 >= traits::RFS) { | ||||
|                                     raise(0,  2); | ||||
|                                 } | ||||
|                                 else { | ||||
|                                     if(rd !=  0) { | ||||
|                                         *(X+rd) = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                 TRAP_ADDI:break; | ||||
| @@ -845,8 +940,13 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 *NEXT_PC = *PC + 4; | ||||
|                 // execute instruction | ||||
|                 { | ||||
|                                 if((rd % traits::RFS) !=  0) { | ||||
|                                     *(X+rd % traits::RFS) = ((int32_t)*(X+rs1 % traits::RFS) < (int16_t)sext<12>(imm))?  1 :  0; | ||||
|                                 if(rd >= traits::RFS || rs1 >= traits::RFS) { | ||||
|                                     raise(0,  2); | ||||
|                                 } | ||||
|                                 else { | ||||
|                                     if(rd !=  0) { | ||||
|                                         *(X+rd) = ((int32_t)*(X+rs1 % traits::RFS) < (int16_t)sext<12>(imm))?  1 :  0; | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                 TRAP_SLTI:break; | ||||
| @@ -867,8 +967,13 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 *NEXT_PC = *PC + 4; | ||||
|                 // execute instruction | ||||
|                 { | ||||
|                                 if((rd % traits::RFS) !=  0) { | ||||
|                                     *(X+rd % traits::RFS) = (*(X+rs1 % traits::RFS) < (uint32_t)((int16_t)sext<12>(imm)))?  1 :  0; | ||||
|                                 if(rd >= traits::RFS || rs1 >= traits::RFS) { | ||||
|                                     raise(0,  2); | ||||
|                                 } | ||||
|                                 else { | ||||
|                                     if(rd !=  0) { | ||||
|                                         *(X+rd) = (*(X+rs1 % traits::RFS) < (uint32_t)((int16_t)sext<12>(imm)))?  1 :  0; | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                 TRAP_SLTIU:break; | ||||
| @@ -889,8 +994,13 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 *NEXT_PC = *PC + 4; | ||||
|                 // execute instruction | ||||
|                 { | ||||
|                                 if((rd % traits::RFS) !=  0) { | ||||
|                                     *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) ^ (int16_t)sext<12>(imm); | ||||
|                                 if(rd >= traits::RFS || rs1 >= traits::RFS) { | ||||
|                                     raise(0,  2); | ||||
|                                 } | ||||
|                                 else { | ||||
|                                     if(rd !=  0) { | ||||
|                                         *(X+rd) = *(X+rs1 % traits::RFS) ^ (int16_t)sext<12>(imm); | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                 TRAP_XORI:break; | ||||
| @@ -911,8 +1021,13 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 *NEXT_PC = *PC + 4; | ||||
|                 // execute instruction | ||||
|                 { | ||||
|                                 if((rd % traits::RFS) !=  0) { | ||||
|                                     *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) | (int16_t)sext<12>(imm); | ||||
|                                 if(rd >= traits::RFS || rs1 >= traits::RFS) { | ||||
|                                     raise(0,  2); | ||||
|                                 } | ||||
|                                 else { | ||||
|                                     if(rd !=  0) { | ||||
|                                         *(X+rd) = *(X+rs1 % traits::RFS) | (int16_t)sext<12>(imm); | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                 TRAP_ORI:break; | ||||
| @@ -933,8 +1048,13 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 *NEXT_PC = *PC + 4; | ||||
|                 // execute instruction | ||||
|                 { | ||||
|                                 if((rd % traits::RFS) !=  0) { | ||||
|                                     *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) & (int16_t)sext<12>(imm); | ||||
|                                 if(rd >= traits::RFS || rs1 >= traits::RFS) { | ||||
|                                     raise(0,  2); | ||||
|                                 } | ||||
|                                 else { | ||||
|                                     if(rd !=  0) { | ||||
|                                         *(X+rd) = *(X+rs1 % traits::RFS) & (int16_t)sext<12>(imm); | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                 TRAP_ANDI:break; | ||||
| @@ -955,8 +1075,13 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 *NEXT_PC = *PC + 4; | ||||
|                 // execute instruction | ||||
|                 { | ||||
|                                 if((rd % traits::RFS) !=  0) { | ||||
|                                     *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) << shamt; | ||||
|                                 if(rd >= traits::RFS || rs1 >= traits::RFS) { | ||||
|                                     raise(0,  2); | ||||
|                                 } | ||||
|                                 else { | ||||
|                                     if(rd !=  0) { | ||||
|                                         *(X+rd) = *(X+rs1 % traits::RFS) << shamt; | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                 TRAP_SLLI:break; | ||||
| @@ -977,8 +1102,13 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 *NEXT_PC = *PC + 4; | ||||
|                 // execute instruction | ||||
|                 { | ||||
|                                 if((rd % traits::RFS) !=  0) { | ||||
|                                     *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) >> shamt; | ||||
|                                 if(rd >= traits::RFS || rs1 >= traits::RFS) { | ||||
|                                     raise(0,  2); | ||||
|                                 } | ||||
|                                 else { | ||||
|                                     if(rd !=  0) { | ||||
|                                         *(X+rd) = *(X+rs1 % traits::RFS) >> shamt; | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                 TRAP_SRLI:break; | ||||
| @@ -999,8 +1129,13 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 *NEXT_PC = *PC + 4; | ||||
|                 // execute instruction | ||||
|                 { | ||||
|                                 if((rd % traits::RFS) !=  0) { | ||||
|                                     *(X+rd % traits::RFS) = (int32_t)*(X+rs1 % traits::RFS) >> shamt; | ||||
|                                 if(rd >= traits::RFS || rs1 >= traits::RFS) { | ||||
|                                     raise(0,  2); | ||||
|                                 } | ||||
|                                 else { | ||||
|                                     if(rd !=  0) { | ||||
|                                         *(X+rd) = (int32_t)*(X+rs1 % traits::RFS) >> shamt; | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                 TRAP_SRAI:break; | ||||
| @@ -1021,8 +1156,13 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 *NEXT_PC = *PC + 4; | ||||
|                 // execute instruction | ||||
|                 { | ||||
|                                 if((rd % traits::RFS) !=  0) { | ||||
|                                     *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) + *(X+rs2 % traits::RFS); | ||||
|                                 if(rd >= traits::RFS || rs1 >= traits::RFS || rs2 >= traits::RFS) { | ||||
|                                     raise(0,  2); | ||||
|                                 } | ||||
|                                 else { | ||||
|                                     if(rd !=  0) { | ||||
|                                         *(X+rd) = *(X+rs1 % traits::RFS) + *(X+rs2 % traits::RFS); | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                 TRAP_ADD:break; | ||||
| @@ -1043,8 +1183,13 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 *NEXT_PC = *PC + 4; | ||||
|                 // execute instruction | ||||
|                 { | ||||
|                                 if((rd % traits::RFS) !=  0) { | ||||
|                                     *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) - *(X+rs2 % traits::RFS); | ||||
|                                 if(rd >= traits::RFS || rs1 >= traits::RFS || rs2 >= traits::RFS) { | ||||
|                                     raise(0,  2); | ||||
|                                 } | ||||
|                                 else { | ||||
|                                     if(rd !=  0) { | ||||
|                                         *(X+rd) = *(X+rs1 % traits::RFS) - *(X+rs2 % traits::RFS); | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                 TRAP_SUB:break; | ||||
| @@ -1065,8 +1210,13 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 *NEXT_PC = *PC + 4; | ||||
|                 // execute instruction | ||||
|                 { | ||||
|                                 if((rd % traits::RFS) !=  0) { | ||||
|                                     *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) << (*(X+rs2 % traits::RFS) & (traits::XLEN -  1)); | ||||
|                                 if(rd >= traits::RFS || rs1 >= traits::RFS || rs2 >= traits::RFS) { | ||||
|                                     raise(0,  2); | ||||
|                                 } | ||||
|                                 else { | ||||
|                                     if(rd !=  0) { | ||||
|                                         *(X+rd) = *(X+rs1 % traits::RFS) << (*(X+rs2 % traits::RFS) & (traits::XLEN -  1)); | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                 TRAP_SLL:break; | ||||
| @@ -1087,8 +1237,18 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 *NEXT_PC = *PC + 4; | ||||
|                 // execute instruction | ||||
|                 { | ||||
|                                 if((rd % traits::RFS) !=  0) { | ||||
|                                     *(X+rd % traits::RFS) = (int32_t)*(X+rs1 % traits::RFS) < (int32_t)*(X+rs2 % traits::RFS)?  1 :  0; | ||||
|                                 if(rd >= traits::RFS || rs1 >= traits::RFS || rs2 >= traits::RFS) { | ||||
|                                     raise(0,  2); | ||||
|                                 } | ||||
|                                 else { | ||||
|                                     if(rd >= traits::RFS || rs1 >= traits::RFS || rs2 >= traits::RFS) { | ||||
|                                         raise(0,  2); | ||||
|                                     } | ||||
|                                     else { | ||||
|                                         if(rd !=  0) { | ||||
|                                             *(X+rd) = (int32_t)*(X+rs1 % traits::RFS) < (int32_t)*(X+rs2 % traits::RFS)?  1 :  0; | ||||
|                                         } | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                 TRAP_SLT:break; | ||||
| @@ -1109,8 +1269,13 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 *NEXT_PC = *PC + 4; | ||||
|                 // execute instruction | ||||
|                 { | ||||
|                                 if((rd % traits::RFS) !=  0) { | ||||
|                                     *(X+rd % traits::RFS) = (uint32_t)*(X+rs1 % traits::RFS) < (uint32_t)*(X+rs2 % traits::RFS)?  1 :  0; | ||||
|                                 if(rd >= traits::RFS || rs1 >= traits::RFS || rs2 >= traits::RFS) { | ||||
|                                     raise(0,  2); | ||||
|                                 } | ||||
|                                 else { | ||||
|                                     if(rd !=  0) { | ||||
|                                         *(X+rd) = (uint32_t)*(X+rs1 % traits::RFS) < (uint32_t)*(X+rs2 % traits::RFS)?  1 :  0; | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                 TRAP_SLTU:break; | ||||
| @@ -1131,8 +1296,13 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 *NEXT_PC = *PC + 4; | ||||
|                 // execute instruction | ||||
|                 { | ||||
|                                 if((rd % traits::RFS) !=  0) { | ||||
|                                     *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) ^ *(X+rs2 % traits::RFS); | ||||
|                                 if(rd >= traits::RFS || rs1 >= traits::RFS || rs2 >= traits::RFS) { | ||||
|                                     raise(0,  2); | ||||
|                                 } | ||||
|                                 else { | ||||
|                                     if(rd !=  0) { | ||||
|                                         *(X+rd) = *(X+rs1 % traits::RFS) ^ *(X+rs2 % traits::RFS); | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                 TRAP_XOR:break; | ||||
| @@ -1153,8 +1323,13 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 *NEXT_PC = *PC + 4; | ||||
|                 // execute instruction | ||||
|                 { | ||||
|                                 if((rd % traits::RFS) !=  0) { | ||||
|                                     *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) >> (*(X+rs2 % traits::RFS) & (traits::XLEN -  1)); | ||||
|                                 if(rd >= traits::RFS || rs1 >= traits::RFS || rs2 >= traits::RFS) { | ||||
|                                     raise(0,  2); | ||||
|                                 } | ||||
|                                 else { | ||||
|                                     if(rd !=  0) { | ||||
|                                         *(X+rd) = *(X+rs1 % traits::RFS) >> (*(X+rs2 % traits::RFS) & (traits::XLEN -  1)); | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                 TRAP_SRL:break; | ||||
| @@ -1175,8 +1350,13 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 *NEXT_PC = *PC + 4; | ||||
|                 // execute instruction | ||||
|                 { | ||||
|                                 if((rd % traits::RFS) !=  0) { | ||||
|                                     *(X+rd % traits::RFS) = (int32_t)*(X+rs1 % traits::RFS) >> (*(X+rs2 % traits::RFS) & (traits::XLEN -  1)); | ||||
|                                 if(rd >= traits::RFS || rs1 >= traits::RFS || rs2 >= traits::RFS) { | ||||
|                                     raise(0,  2); | ||||
|                                 } | ||||
|                                 else { | ||||
|                                     if(rd !=  0) { | ||||
|                                         *(X+rd) = (int32_t)*(X+rs1 % traits::RFS) >> (*(X+rs2 % traits::RFS) & (traits::XLEN -  1)); | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                 TRAP_SRA:break; | ||||
| @@ -1197,8 +1377,13 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 *NEXT_PC = *PC + 4; | ||||
|                 // execute instruction | ||||
|                 { | ||||
|                                 if((rd % traits::RFS) !=  0) { | ||||
|                                     *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) | *(X+rs2 % traits::RFS); | ||||
|                                 if(rd >= traits::RFS || rs1 >= traits::RFS || rs2 >= traits::RFS) { | ||||
|                                     raise(0,  2); | ||||
|                                 } | ||||
|                                 else { | ||||
|                                     if(rd !=  0) { | ||||
|                                         *(X+rd) = *(X+rs1 % traits::RFS) | *(X+rs2 % traits::RFS); | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                 TRAP_OR:break; | ||||
| @@ -1219,8 +1404,13 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 *NEXT_PC = *PC + 4; | ||||
|                 // execute instruction | ||||
|                 { | ||||
|                                 if((rd % traits::RFS) !=  0) { | ||||
|                                     *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) & *(X+rs2 % traits::RFS); | ||||
|                                 if(rd >= traits::RFS || rs1 >= traits::RFS || rs2 >= traits::RFS) { | ||||
|                                     raise(0,  2); | ||||
|                                 } | ||||
|                                 else { | ||||
|                                     if(rd !=  0) { | ||||
|                                         *(X+rd) = *(X+rs1 % traits::RFS) & *(X+rs2 % traits::RFS); | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                 TRAP_AND:break; | ||||
| @@ -1315,20 +1505,25 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 *NEXT_PC = *PC + 4; | ||||
|                 // execute instruction | ||||
|                 { | ||||
|                                 if(rd >= traits::RFS || rs1 >= traits::RFS) { | ||||
|                                     raise(0,  2); | ||||
|                                 } | ||||
|                                 else { | ||||
|                                     uint32_t xrs1 = *(X+rs1 % traits::RFS); | ||||
|                     if((rd % traits::RFS) !=  0) { | ||||
|                                     if(rd !=  0) { | ||||
|                                         uint32_t read_res = super::template read_mem<uint32_t>(traits::CSR, csr); | ||||
|                                         if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRW; | ||||
|                                         uint32_t xrd = read_res; | ||||
|                                         super::template write_mem<uint32_t>(traits::CSR, csr, xrs1); | ||||
|                                         if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRW; | ||||
|                         *(X+rd % traits::RFS) = xrd; | ||||
|                                         *(X+rd) = xrd; | ||||
|                                     } | ||||
|                                     else { | ||||
|                                         super::template write_mem<uint32_t>(traits::CSR, csr, xrs1); | ||||
|                                         if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRW; | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                 TRAP_CSRRW:break; | ||||
|             }// @suppress("No break at end of case") | ||||
|             case arch::traits<ARCH>::opcode_e::CSRRS: { | ||||
| @@ -1347,6 +1542,10 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 *NEXT_PC = *PC + 4; | ||||
|                 // execute instruction | ||||
|                 { | ||||
|                                 if(rd >= traits::RFS || rs1 >= traits::RFS) { | ||||
|                                     raise(0,  2); | ||||
|                                 } | ||||
|                                 else { | ||||
|                                     uint32_t read_res = super::template read_mem<uint32_t>(traits::CSR, csr); | ||||
|                                     if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRS; | ||||
|                                     uint32_t xrd = read_res; | ||||
| @@ -1355,8 +1554,9 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                                         super::template write_mem<uint32_t>(traits::CSR, csr, xrd | xrs1); | ||||
|                                         if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRS; | ||||
|                                     } | ||||
|                     if((rd % traits::RFS) !=  0) { | ||||
|                         *(X+rd % traits::RFS) = xrd; | ||||
|                                     if(rd !=  0) { | ||||
|                                         *(X+rd) = xrd; | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                 TRAP_CSRRS:break; | ||||
| @@ -1377,6 +1577,10 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 *NEXT_PC = *PC + 4; | ||||
|                 // execute instruction | ||||
|                 { | ||||
|                                 if(rd >= traits::RFS || rs1 >= traits::RFS) { | ||||
|                                     raise(0,  2); | ||||
|                                 } | ||||
|                                 else { | ||||
|                                     uint32_t read_res = super::template read_mem<uint32_t>(traits::CSR, csr); | ||||
|                                     if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRC; | ||||
|                                     uint32_t xrd = read_res; | ||||
| @@ -1385,8 +1589,9 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                                         super::template write_mem<uint32_t>(traits::CSR, csr, xrd & ~ xrs1); | ||||
|                                         if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRC; | ||||
|                                     } | ||||
|                     if((rd % traits::RFS) !=  0) { | ||||
|                         *(X+rd % traits::RFS) = xrd; | ||||
|                                     if(rd !=  0) { | ||||
|                                         *(X+rd) = xrd; | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                 TRAP_CSRRC:break; | ||||
| @@ -1407,13 +1612,18 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 *NEXT_PC = *PC + 4; | ||||
|                 // execute instruction | ||||
|                 { | ||||
|                                 if(rd >= traits::RFS) { | ||||
|                                     raise(0,  2); | ||||
|                                 } | ||||
|                                 else { | ||||
|                                     uint32_t read_res = super::template read_mem<uint32_t>(traits::CSR, csr); | ||||
|                                     if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRWI; | ||||
|                                     uint32_t xrd = read_res; | ||||
|                                     super::template write_mem<uint32_t>(traits::CSR, csr, (uint32_t)zimm); | ||||
|                                     if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRWI; | ||||
|                     if((rd % traits::RFS) !=  0) { | ||||
|                         *(X+rd % traits::RFS) = xrd; | ||||
|                                     if(rd !=  0) { | ||||
|                                         *(X+rd) = xrd; | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                 TRAP_CSRRWI:break; | ||||
| @@ -1434,6 +1644,10 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 *NEXT_PC = *PC + 4; | ||||
|                 // execute instruction | ||||
|                 { | ||||
|                                 if(rd >= traits::RFS) { | ||||
|                                     raise(0,  2); | ||||
|                                 } | ||||
|                                 else { | ||||
|                                     uint32_t read_res = super::template read_mem<uint32_t>(traits::CSR, csr); | ||||
|                                     if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRSI; | ||||
|                                     uint32_t xrd = read_res; | ||||
| @@ -1441,8 +1655,9 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                                         super::template write_mem<uint32_t>(traits::CSR, csr, xrd | (uint32_t)zimm); | ||||
|                                         if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRSI; | ||||
|                                     } | ||||
|                     if((rd % traits::RFS) !=  0) { | ||||
|                         *(X+rd % traits::RFS) = xrd; | ||||
|                                     if(rd !=  0) { | ||||
|                                         *(X+rd) = xrd; | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                 TRAP_CSRRSI:break; | ||||
| @@ -1463,6 +1678,10 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                 *NEXT_PC = *PC + 4; | ||||
|                 // execute instruction | ||||
|                 { | ||||
|                                 if(rd >= traits::RFS) { | ||||
|                                     raise(0,  2); | ||||
|                                 } | ||||
|                                 else { | ||||
|                                     uint32_t read_res = super::template read_mem<uint32_t>(traits::CSR, csr); | ||||
|                                     if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRCI; | ||||
|                                     uint32_t xrd = read_res; | ||||
| @@ -1470,8 +1689,9 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co | ||||
|                                         super::template write_mem<uint32_t>(traits::CSR, csr, xrd & ~ ((uint32_t)zimm)); | ||||
|                                         if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRCI; | ||||
|                                     } | ||||
|                     if((rd % traits::RFS) !=  0) { | ||||
|                         *(X+rd % traits::RFS) = xrd; | ||||
|                                     if(rd !=  0) { | ||||
|                                         *(X+rd) = xrd; | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                 TRAP_CSRRCI:break; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user