Compare commits
	
		
			1 Commits
		
	
	
		
			f585489ff5
			...
			8c701d55c1
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 8c701d55c1 | 
| @@ -8,6 +8,7 @@ include(GNUInstallDirs) | |||||||
|  |  | ||||||
| find_package(elfio QUIET) | find_package(elfio QUIET) | ||||||
| find_package(Boost COMPONENTS coroutine) | find_package(Boost COMPONENTS coroutine) | ||||||
|  | find_package(jsoncpp) | ||||||
|  |  | ||||||
| if(WITH_LLVM) | if(WITH_LLVM) | ||||||
|     if(DEFINED ENV{LLVM_HOME}) |     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; |                 *NEXT_PC = *PC + 4; | ||||||
|                 // execute instruction |                 // execute instruction | ||||||
|                 { |                 { | ||||||
|                                 if((rd % traits::RFS) !=  0) { |                                 if(rd >= traits::RFS) { | ||||||
|                                     *(X+rd % traits::RFS) = (int32_t)imm; |                                     raise(0,  2); | ||||||
|  |                                 } | ||||||
|  |                                 else { | ||||||
|  |                                     if(rd !=  0) { | ||||||
|  |                                         *(X+rd) = (int32_t)imm; | ||||||
|  |                                     } | ||||||
|                                 } |                                 } | ||||||
|                             } |                             } | ||||||
|                 TRAP_LUI:break; |                 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; |                 *NEXT_PC = *PC + 4; | ||||||
|                 // execute instruction |                 // execute instruction | ||||||
|                 { |                 { | ||||||
|                                 if((rd % traits::RFS) !=  0) { |                                 if(rd >= traits::RFS) { | ||||||
|                                     *(X+rd % traits::RFS) = *PC + (int32_t)imm; |                                     raise(0,  2); | ||||||
|  |                                 } | ||||||
|  |                                 else { | ||||||
|  |                                     if(rd !=  0) { | ||||||
|  |                                         *(X+rd) = *PC + (int32_t)imm; | ||||||
|  |                                     } | ||||||
|                                 } |                                 } | ||||||
|                             } |                             } | ||||||
|                 TRAP_AUIPC:break; |                 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; |                 *NEXT_PC = *PC + 4; | ||||||
|                 // execute instruction |                 // execute instruction | ||||||
|                 { |                 { | ||||||
|                     if(imm % traits::INSTR_ALIGNMENT) { |                                 if(rd >= traits::RFS) { | ||||||
|                         raise(0,  0); |                                     raise(0,  2); | ||||||
|                     } |                                 } | ||||||
|                     else { |                                 else { | ||||||
|                         if((rd % traits::RFS) !=  0) { |                                     if(imm % traits::INSTR_ALIGNMENT) { | ||||||
|                             *(X+rd % traits::RFS) = *PC +  4; |                                         raise(0,  0); | ||||||
|                         } |                                     } | ||||||
|                         *NEXT_PC = *PC + (int32_t)sext<21>(imm); |                                     else { | ||||||
|                         super::ex_info.branch_taken=true; |                                         if(rd !=  0) { | ||||||
|                     } |                                             *(X+rd) = *PC +  4; | ||||||
|                 } |                                         } | ||||||
|  |                                         *NEXT_PC = *PC + (int32_t)sext<21>(imm); | ||||||
|  |                                         super::ex_info.branch_taken=true; | ||||||
|  |                                     } | ||||||
|  |                                 } | ||||||
|  |                             } | ||||||
|                 TRAP_JAL:break; |                 TRAP_JAL:break; | ||||||
|             }// @suppress("No break at end of case") |             }// @suppress("No break at end of case") | ||||||
|             case arch::traits<ARCH>::opcode_e::JALR: { |             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; |                 *NEXT_PC = *PC + 4; | ||||||
|                 // execute instruction |                 // execute instruction | ||||||
|                 { |                 { | ||||||
|                     uint32_t new_pc = (*(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm)) & ~ 0x1; |                                 if(rd >= traits::RFS || rs1 >= traits::RFS) { | ||||||
|                     if(new_pc % traits::INSTR_ALIGNMENT) { |                                     raise(0,  2); | ||||||
|                         raise(0,  0); |                                 } | ||||||
|                     } |                                 else { | ||||||
|                     else { |                                     uint32_t new_pc = (*(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm)) & ~ 0x1; | ||||||
|                         if((rd % traits::RFS) !=  0) { |                                     if(new_pc % traits::INSTR_ALIGNMENT) { | ||||||
|                             *(X+rd % traits::RFS) = *PC +  4; |                                         raise(0,  0); | ||||||
|                         } |                                     } | ||||||
|                         *NEXT_PC = new_pc & ~ 0x1; |                                     else { | ||||||
|                         super::ex_info.branch_taken=true; |                                         if(rd !=  0) { | ||||||
|                     } |                                             *(X+rd) = *PC +  4; | ||||||
|                 } |                                         } | ||||||
|  |                                         *NEXT_PC = new_pc & ~ 0x1; | ||||||
|  |                                         super::ex_info.branch_taken=true; | ||||||
|  |                                     } | ||||||
|  |                                 } | ||||||
|  |                             } | ||||||
|                 TRAP_JALR:break; |                 TRAP_JALR:break; | ||||||
|             }// @suppress("No break at end of case") |             }// @suppress("No break at end of case") | ||||||
|             case arch::traits<ARCH>::opcode_e::BEQ: { |             case arch::traits<ARCH>::opcode_e::BEQ: { | ||||||
| @@ -459,16 +479,21 @@ 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(*(X+rs1 % traits::RFS) == *(X+rs2 % traits::RFS)) { |                                 if(rs2 >= traits::RFS || rs1 >= traits::RFS) { | ||||||
|                         if(imm % traits::INSTR_ALIGNMENT) { |                                     raise(0,  2); | ||||||
|                             raise(0,  0); |                                 } | ||||||
|                         } |                                 else { | ||||||
|                         else { |                                     if(*(X+rs1 % traits::RFS) == *(X+rs2 % traits::RFS)) { | ||||||
|                             *NEXT_PC = *PC + (int16_t)sext<13>(imm); |                                         if(imm % traits::INSTR_ALIGNMENT) { | ||||||
|                             super::ex_info.branch_taken=true; |                                             raise(0,  0); | ||||||
|                         } |                                         } | ||||||
|                     } |                                         else { | ||||||
|                 } |                                             *NEXT_PC = *PC + (int16_t)sext<13>(imm); | ||||||
|  |                                             super::ex_info.branch_taken=true; | ||||||
|  |                                         } | ||||||
|  |                                     } | ||||||
|  |                                 } | ||||||
|  |                             } | ||||||
|                 TRAP_BEQ:break; |                 TRAP_BEQ:break; | ||||||
|             }// @suppress("No break at end of case") |             }// @suppress("No break at end of case") | ||||||
|             case arch::traits<ARCH>::opcode_e::BNE: { |             case arch::traits<ARCH>::opcode_e::BNE: { | ||||||
| @@ -487,16 +512,21 @@ 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(*(X+rs1 % traits::RFS) != *(X+rs2 % traits::RFS)) { |                                 if(rs2 >= traits::RFS || rs1 >= traits::RFS) { | ||||||
|                         if(imm % traits::INSTR_ALIGNMENT) { |                                     raise(0,  2); | ||||||
|                             raise(0,  0); |                                 } | ||||||
|                         } |                                 else { | ||||||
|                         else { |                                     if(*(X+rs1 % traits::RFS) != *(X+rs2 % traits::RFS)) { | ||||||
|                             *NEXT_PC = *PC + (int16_t)sext<13>(imm); |                                         if(imm % traits::INSTR_ALIGNMENT) { | ||||||
|                             super::ex_info.branch_taken=true; |                                             raise(0,  0); | ||||||
|                         } |                                         } | ||||||
|                     } |                                         else { | ||||||
|                 } |                                             *NEXT_PC = *PC + (int16_t)sext<13>(imm); | ||||||
|  |                                             super::ex_info.branch_taken=true; | ||||||
|  |                                         } | ||||||
|  |                                     } | ||||||
|  |                                 } | ||||||
|  |                             } | ||||||
|                 TRAP_BNE:break; |                 TRAP_BNE:break; | ||||||
|             }// @suppress("No break at end of case") |             }// @suppress("No break at end of case") | ||||||
|             case arch::traits<ARCH>::opcode_e::BLT: { |             case arch::traits<ARCH>::opcode_e::BLT: { | ||||||
| @@ -515,16 +545,21 @@ 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((int32_t)*(X+rs1 % traits::RFS) < (int32_t)*(X+rs2 % traits::RFS)) { |                                 if(rs2 >= traits::RFS || rs1 >= traits::RFS) { | ||||||
|                         if(imm % traits::INSTR_ALIGNMENT) { |                                     raise(0,  2); | ||||||
|                             raise(0,  0); |                                 } | ||||||
|                         } |                                 else { | ||||||
|                         else { |                                     if((int32_t)*(X+rs1 % traits::RFS) < (int32_t)*(X+rs2 % traits::RFS)) { | ||||||
|                             *NEXT_PC = *PC + (int16_t)sext<13>(imm); |                                         if(imm % traits::INSTR_ALIGNMENT) { | ||||||
|                             super::ex_info.branch_taken=true; |                                             raise(0,  0); | ||||||
|                         } |                                         } | ||||||
|                     } |                                         else { | ||||||
|                 } |                                             *NEXT_PC = *PC + (int16_t)sext<13>(imm); | ||||||
|  |                                             super::ex_info.branch_taken=true; | ||||||
|  |                                         } | ||||||
|  |                                     } | ||||||
|  |                                 } | ||||||
|  |                             } | ||||||
|                 TRAP_BLT:break; |                 TRAP_BLT:break; | ||||||
|             }// @suppress("No break at end of case") |             }// @suppress("No break at end of case") | ||||||
|             case arch::traits<ARCH>::opcode_e::BGE: { |             case arch::traits<ARCH>::opcode_e::BGE: { | ||||||
| @@ -543,16 +578,21 @@ 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((int32_t)*(X+rs1 % traits::RFS) >= (int32_t)*(X+rs2 % traits::RFS)) { |                                 if(rs2 >= traits::RFS || rs1 >= traits::RFS) { | ||||||
|                         if(imm % traits::INSTR_ALIGNMENT) { |                                     raise(0,  2); | ||||||
|                             raise(0,  0); |                                 } | ||||||
|                         } |                                 else { | ||||||
|                         else { |                                     if((int32_t)*(X+rs1 % traits::RFS) >= (int32_t)*(X+rs2 % traits::RFS)) { | ||||||
|                             *NEXT_PC = *PC + (int16_t)sext<13>(imm); |                                         if(imm % traits::INSTR_ALIGNMENT) { | ||||||
|                             super::ex_info.branch_taken=true; |                                             raise(0,  0); | ||||||
|                         } |                                         } | ||||||
|                     } |                                         else { | ||||||
|                 } |                                             *NEXT_PC = *PC + (int16_t)sext<13>(imm); | ||||||
|  |                                             super::ex_info.branch_taken=true; | ||||||
|  |                                         } | ||||||
|  |                                     } | ||||||
|  |                                 } | ||||||
|  |                             } | ||||||
|                 TRAP_BGE:break; |                 TRAP_BGE:break; | ||||||
|             }// @suppress("No break at end of case") |             }// @suppress("No break at end of case") | ||||||
|             case arch::traits<ARCH>::opcode_e::BLTU: { |             case arch::traits<ARCH>::opcode_e::BLTU: { | ||||||
| @@ -571,16 +611,21 @@ 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(*(X+rs1 % traits::RFS) < *(X+rs2 % traits::RFS)) { |                                 if(rs2 >= traits::RFS || rs1 >= traits::RFS) { | ||||||
|                         if(imm % traits::INSTR_ALIGNMENT) { |                                     raise(0,  2); | ||||||
|                             raise(0,  0); |                                 } | ||||||
|                         } |                                 else { | ||||||
|                         else { |                                     if(*(X+rs1 % traits::RFS) < *(X+rs2 % traits::RFS)) { | ||||||
|                             *NEXT_PC = *PC + (int16_t)sext<13>(imm); |                                         if(imm % traits::INSTR_ALIGNMENT) { | ||||||
|                             super::ex_info.branch_taken=true; |                                             raise(0,  0); | ||||||
|                         } |                                         } | ||||||
|                     } |                                         else { | ||||||
|                 } |                                             *NEXT_PC = *PC + (int16_t)sext<13>(imm); | ||||||
|  |                                             super::ex_info.branch_taken=true; | ||||||
|  |                                         } | ||||||
|  |                                     } | ||||||
|  |                                 } | ||||||
|  |                             } | ||||||
|                 TRAP_BLTU:break; |                 TRAP_BLTU:break; | ||||||
|             }// @suppress("No break at end of case") |             }// @suppress("No break at end of case") | ||||||
|             case arch::traits<ARCH>::opcode_e::BGEU: { |             case arch::traits<ARCH>::opcode_e::BGEU: { | ||||||
| @@ -599,16 +644,21 @@ 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(*(X+rs1 % traits::RFS) >= *(X+rs2 % traits::RFS)) { |                                 if(rs2 >= traits::RFS || rs1 >= traits::RFS) { | ||||||
|                         if(imm % traits::INSTR_ALIGNMENT) { |                                     raise(0,  2); | ||||||
|                             raise(0,  0); |                                 } | ||||||
|                         } |                                 else { | ||||||
|                         else { |                                     if(*(X+rs1 % traits::RFS) >= *(X+rs2 % traits::RFS)) { | ||||||
|                             *NEXT_PC = *PC + (int16_t)sext<13>(imm); |                                         if(imm % traits::INSTR_ALIGNMENT) { | ||||||
|                             super::ex_info.branch_taken=true; |                                             raise(0,  0); | ||||||
|                         } |                                         } | ||||||
|                     } |                                         else { | ||||||
|                 } |                                             *NEXT_PC = *PC + (int16_t)sext<13>(imm); | ||||||
|  |                                             super::ex_info.branch_taken=true; | ||||||
|  |                                         } | ||||||
|  |                                     } | ||||||
|  |                                 } | ||||||
|  |                             } | ||||||
|                 TRAP_BGEU:break; |                 TRAP_BGEU:break; | ||||||
|             }// @suppress("No break at end of case") |             }// @suppress("No break at end of case") | ||||||
|             case arch::traits<ARCH>::opcode_e::LB: { |             case arch::traits<ARCH>::opcode_e::LB: { | ||||||
| @@ -627,14 +677,19 @@ 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 | ||||||
|                 { |                 { | ||||||
|                     uint32_t load_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); |                                 if(rd >= traits::RFS || rs1 >= traits::RFS) { | ||||||
|                     int8_t read_res = super::template read_mem<int8_t>(traits::MEM, load_address); |                                     raise(0,  2); | ||||||
|                     if(this->core.trap_state>=0x80000000UL) goto TRAP_LB; |                                 } | ||||||
|                     int8_t res = (int8_t)read_res; |                                 else { | ||||||
|                     if((rd % traits::RFS) !=  0) { |                                     uint32_t load_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); | ||||||
|                         *(X+rd % traits::RFS) = (int32_t)res; |                                     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 !=  0) { | ||||||
|  |                                         *(X+rd) = (int32_t)res; | ||||||
|  |                                     } | ||||||
|  |                                 } | ||||||
|  |                             } | ||||||
|                 TRAP_LB:break; |                 TRAP_LB:break; | ||||||
|             }// @suppress("No break at end of case") |             }// @suppress("No break at end of case") | ||||||
|             case arch::traits<ARCH>::opcode_e::LH: { |             case arch::traits<ARCH>::opcode_e::LH: { | ||||||
| @@ -653,14 +708,19 @@ 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 | ||||||
|                 { |                 { | ||||||
|                     uint32_t load_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); |                                 if(rd >= traits::RFS || rs1 >= traits::RFS) { | ||||||
|                     int16_t read_res = super::template read_mem<int16_t>(traits::MEM, load_address); |                                     raise(0,  2); | ||||||
|                     if(this->core.trap_state>=0x80000000UL) goto TRAP_LH; |                                 } | ||||||
|                     int16_t res = (int16_t)read_res; |                                 else { | ||||||
|                     if((rd % traits::RFS) !=  0) { |                                     uint32_t load_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); | ||||||
|                         *(X+rd % traits::RFS) = (int32_t)res; |                                     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 !=  0) { | ||||||
|  |                                         *(X+rd) = (int32_t)res; | ||||||
|  |                                     } | ||||||
|  |                                 } | ||||||
|  |                             } | ||||||
|                 TRAP_LH:break; |                 TRAP_LH:break; | ||||||
|             }// @suppress("No break at end of case") |             }// @suppress("No break at end of case") | ||||||
|             case arch::traits<ARCH>::opcode_e::LW: { |             case arch::traits<ARCH>::opcode_e::LW: { | ||||||
| @@ -679,14 +739,19 @@ 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 | ||||||
|                 { |                 { | ||||||
|                     uint32_t load_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); |                                 if(rd >= traits::RFS || rs1 >= traits::RFS) { | ||||||
|                     int32_t read_res = super::template read_mem<int32_t>(traits::MEM, load_address); |                                     raise(0,  2); | ||||||
|                     if(this->core.trap_state>=0x80000000UL) goto TRAP_LW; |                                 } | ||||||
|                     int32_t res = (int32_t)read_res; |                                 else { | ||||||
|                     if((rd % traits::RFS) !=  0) { |                                     uint32_t load_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); | ||||||
|                         *(X+rd % traits::RFS) = (int32_t)res; |                                     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 !=  0) { | ||||||
|  |                                         *(X+rd) = (int32_t)res; | ||||||
|  |                                     } | ||||||
|  |                                 } | ||||||
|  |                             } | ||||||
|                 TRAP_LW:break; |                 TRAP_LW:break; | ||||||
|             }// @suppress("No break at end of case") |             }// @suppress("No break at end of case") | ||||||
|             case arch::traits<ARCH>::opcode_e::LBU: { |             case arch::traits<ARCH>::opcode_e::LBU: { | ||||||
| @@ -705,14 +770,19 @@ 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 | ||||||
|                 { |                 { | ||||||
|                     uint32_t load_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); |                                 if(rd >= traits::RFS || rs1 >= traits::RFS) { | ||||||
|                     uint8_t read_res = super::template read_mem<uint8_t>(traits::MEM, load_address); |                                     raise(0,  2); | ||||||
|                     if(this->core.trap_state>=0x80000000UL) goto TRAP_LBU; |                                 } | ||||||
|                     uint8_t res = (uint8_t)read_res; |                                 else { | ||||||
|                     if((rd % traits::RFS) !=  0) { |                                     uint32_t load_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); | ||||||
|                         *(X+rd % traits::RFS) = (uint32_t)res; |                                     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 !=  0) { | ||||||
|  |                                         *(X+rd) = (uint32_t)res; | ||||||
|  |                                     } | ||||||
|  |                                 } | ||||||
|  |                             } | ||||||
|                 TRAP_LBU:break; |                 TRAP_LBU:break; | ||||||
|             }// @suppress("No break at end of case") |             }// @suppress("No break at end of case") | ||||||
|             case arch::traits<ARCH>::opcode_e::LHU: { |             case arch::traits<ARCH>::opcode_e::LHU: { | ||||||
| @@ -731,14 +801,19 @@ 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 | ||||||
|                 { |                 { | ||||||
|                     uint32_t load_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); |                                 if(rd >= traits::RFS || rs1 >= traits::RFS) { | ||||||
|                     uint16_t read_res = super::template read_mem<uint16_t>(traits::MEM, load_address); |                                     raise(0,  2); | ||||||
|                     if(this->core.trap_state>=0x80000000UL) goto TRAP_LHU; |                                 } | ||||||
|                     uint16_t res = (uint16_t)read_res; |                                 else { | ||||||
|                     if((rd % traits::RFS) !=  0) { |                                     uint32_t load_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); | ||||||
|                         *(X+rd % traits::RFS) = (uint32_t)res; |                                     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 !=  0) { | ||||||
|  |                                         *(X+rd) = (uint32_t)res; | ||||||
|  |                                     } | ||||||
|  |                                 } | ||||||
|  |                             } | ||||||
|                 TRAP_LHU:break; |                 TRAP_LHU:break; | ||||||
|             }// @suppress("No break at end of case") |             }// @suppress("No break at end of case") | ||||||
|             case arch::traits<ARCH>::opcode_e::SB: { |             case arch::traits<ARCH>::opcode_e::SB: { | ||||||
| @@ -757,10 +832,15 @@ 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 | ||||||
|                 { |                 { | ||||||
|                     uint32_t store_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); |                                 if(rs2 >= traits::RFS || rs1 >= traits::RFS) { | ||||||
|                     super::template write_mem<uint8_t>(traits::MEM, store_address, (int8_t)*(X+rs2 % traits::RFS)); |                                     raise(0,  2); | ||||||
|                     if(this->core.trap_state>=0x80000000UL) goto TRAP_SB; |                                 } | ||||||
|                 } |                                 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; |                 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: { | ||||||
| @@ -779,10 +859,15 @@ 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 | ||||||
|                 { |                 { | ||||||
|                     uint32_t store_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); |                                 if(rs2 >= traits::RFS || rs1 >= traits::RFS) { | ||||||
|                     super::template write_mem<uint16_t>(traits::MEM, store_address, (int16_t)*(X+rs2 % traits::RFS)); |                                     raise(0,  2); | ||||||
|                     if(this->core.trap_state>=0x80000000UL) goto TRAP_SH; |                                 } | ||||||
|                 } |                                 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; |                 TRAP_SH:break; | ||||||
|             }// @suppress("No break at end of case") |             }// @suppress("No break at end of case") | ||||||
|             case arch::traits<ARCH>::opcode_e::SW: { |             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; |                 *NEXT_PC = *PC + 4; | ||||||
|                 // execute instruction |                 // execute instruction | ||||||
|                 { |                 { | ||||||
|                     uint32_t store_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); |                                 if(rs2 >= traits::RFS || rs1 >= traits::RFS) { | ||||||
|                     super::template write_mem<uint32_t>(traits::MEM, store_address, (int32_t)*(X+rs2 % traits::RFS)); |                                     raise(0,  2); | ||||||
|                     if(this->core.trap_state>=0x80000000UL) goto TRAP_SW; |                                 } | ||||||
|                 } |                                 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; |                 TRAP_SW:break; | ||||||
|             }// @suppress("No break at end of case") |             }// @suppress("No break at end of case") | ||||||
|             case arch::traits<ARCH>::opcode_e::ADDI: { |             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; |                 *NEXT_PC = *PC + 4; | ||||||
|                 // execute instruction |                 // execute instruction | ||||||
|                 { |                 { | ||||||
|                                 if((rd % traits::RFS) !=  0) { |                                 if(rd >= traits::RFS || rs1 >= traits::RFS) { | ||||||
|                                     *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); |                                     raise(0,  2); | ||||||
|  |                                 } | ||||||
|  |                                 else { | ||||||
|  |                                     if(rd !=  0) { | ||||||
|  |                                         *(X+rd) = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); | ||||||
|  |                                     } | ||||||
|                                 } |                                 } | ||||||
|                             } |                             } | ||||||
|                 TRAP_ADDI:break; |                 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; |                 *NEXT_PC = *PC + 4; | ||||||
|                 // execute instruction |                 // execute instruction | ||||||
|                 { |                 { | ||||||
|                                 if((rd % traits::RFS) !=  0) { |                                 if(rd >= traits::RFS || rs1 >= traits::RFS) { | ||||||
|                                     *(X+rd % traits::RFS) = ((int32_t)*(X+rs1 % traits::RFS) < (int16_t)sext<12>(imm))?  1 :  0; |                                     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; |                 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; |                 *NEXT_PC = *PC + 4; | ||||||
|                 // execute instruction |                 // execute instruction | ||||||
|                 { |                 { | ||||||
|                                 if((rd % traits::RFS) !=  0) { |                                 if(rd >= traits::RFS || rs1 >= traits::RFS) { | ||||||
|                                     *(X+rd % traits::RFS) = (*(X+rs1 % traits::RFS) < (uint32_t)((int16_t)sext<12>(imm)))?  1 :  0; |                                     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; |                 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; |                 *NEXT_PC = *PC + 4; | ||||||
|                 // execute instruction |                 // execute instruction | ||||||
|                 { |                 { | ||||||
|                                 if((rd % traits::RFS) !=  0) { |                                 if(rd >= traits::RFS || rs1 >= traits::RFS) { | ||||||
|                                     *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) ^ (int16_t)sext<12>(imm); |                                     raise(0,  2); | ||||||
|  |                                 } | ||||||
|  |                                 else { | ||||||
|  |                                     if(rd !=  0) { | ||||||
|  |                                         *(X+rd) = *(X+rs1 % traits::RFS) ^ (int16_t)sext<12>(imm); | ||||||
|  |                                     } | ||||||
|                                 } |                                 } | ||||||
|                             } |                             } | ||||||
|                 TRAP_XORI:break; |                 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; |                 *NEXT_PC = *PC + 4; | ||||||
|                 // execute instruction |                 // execute instruction | ||||||
|                 { |                 { | ||||||
|                                 if((rd % traits::RFS) !=  0) { |                                 if(rd >= traits::RFS || rs1 >= traits::RFS) { | ||||||
|                                     *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) | (int16_t)sext<12>(imm); |                                     raise(0,  2); | ||||||
|  |                                 } | ||||||
|  |                                 else { | ||||||
|  |                                     if(rd !=  0) { | ||||||
|  |                                         *(X+rd) = *(X+rs1 % traits::RFS) | (int16_t)sext<12>(imm); | ||||||
|  |                                     } | ||||||
|                                 } |                                 } | ||||||
|                             } |                             } | ||||||
|                 TRAP_ORI:break; |                 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; |                 *NEXT_PC = *PC + 4; | ||||||
|                 // execute instruction |                 // execute instruction | ||||||
|                 { |                 { | ||||||
|                                 if((rd % traits::RFS) !=  0) { |                                 if(rd >= traits::RFS || rs1 >= traits::RFS) { | ||||||
|                                     *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) & (int16_t)sext<12>(imm); |                                     raise(0,  2); | ||||||
|  |                                 } | ||||||
|  |                                 else { | ||||||
|  |                                     if(rd !=  0) { | ||||||
|  |                                         *(X+rd) = *(X+rs1 % traits::RFS) & (int16_t)sext<12>(imm); | ||||||
|  |                                     } | ||||||
|                                 } |                                 } | ||||||
|                             } |                             } | ||||||
|                 TRAP_ANDI:break; |                 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; |                 *NEXT_PC = *PC + 4; | ||||||
|                 // execute instruction |                 // execute instruction | ||||||
|                 { |                 { | ||||||
|                                 if((rd % traits::RFS) !=  0) { |                                 if(rd >= traits::RFS || rs1 >= traits::RFS) { | ||||||
|                                     *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) << shamt; |                                     raise(0,  2); | ||||||
|  |                                 } | ||||||
|  |                                 else { | ||||||
|  |                                     if(rd !=  0) { | ||||||
|  |                                         *(X+rd) = *(X+rs1 % traits::RFS) << shamt; | ||||||
|  |                                     } | ||||||
|                                 } |                                 } | ||||||
|                             } |                             } | ||||||
|                 TRAP_SLLI:break; |                 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; |                 *NEXT_PC = *PC + 4; | ||||||
|                 // execute instruction |                 // execute instruction | ||||||
|                 { |                 { | ||||||
|                                 if((rd % traits::RFS) !=  0) { |                                 if(rd >= traits::RFS || rs1 >= traits::RFS) { | ||||||
|                                     *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) >> shamt; |                                     raise(0,  2); | ||||||
|  |                                 } | ||||||
|  |                                 else { | ||||||
|  |                                     if(rd !=  0) { | ||||||
|  |                                         *(X+rd) = *(X+rs1 % traits::RFS) >> shamt; | ||||||
|  |                                     } | ||||||
|                                 } |                                 } | ||||||
|                             } |                             } | ||||||
|                 TRAP_SRLI:break; |                 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; |                 *NEXT_PC = *PC + 4; | ||||||
|                 // execute instruction |                 // execute instruction | ||||||
|                 { |                 { | ||||||
|                                 if((rd % traits::RFS) !=  0) { |                                 if(rd >= traits::RFS || rs1 >= traits::RFS) { | ||||||
|                                     *(X+rd % traits::RFS) = (int32_t)*(X+rs1 % traits::RFS) >> shamt; |                                     raise(0,  2); | ||||||
|  |                                 } | ||||||
|  |                                 else { | ||||||
|  |                                     if(rd !=  0) { | ||||||
|  |                                         *(X+rd) = (int32_t)*(X+rs1 % traits::RFS) >> shamt; | ||||||
|  |                                     } | ||||||
|                                 } |                                 } | ||||||
|                             } |                             } | ||||||
|                 TRAP_SRAI:break; |                 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; |                 *NEXT_PC = *PC + 4; | ||||||
|                 // execute instruction |                 // execute instruction | ||||||
|                 { |                 { | ||||||
|                                 if((rd % traits::RFS) !=  0) { |                                 if(rd >= traits::RFS || rs1 >= traits::RFS || rs2 >= traits::RFS) { | ||||||
|                                     *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) + *(X+rs2 % traits::RFS); |                                     raise(0,  2); | ||||||
|  |                                 } | ||||||
|  |                                 else { | ||||||
|  |                                     if(rd !=  0) { | ||||||
|  |                                         *(X+rd) = *(X+rs1 % traits::RFS) + *(X+rs2 % traits::RFS); | ||||||
|  |                                     } | ||||||
|                                 } |                                 } | ||||||
|                             } |                             } | ||||||
|                 TRAP_ADD:break; |                 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; |                 *NEXT_PC = *PC + 4; | ||||||
|                 // execute instruction |                 // execute instruction | ||||||
|                 { |                 { | ||||||
|                                 if((rd % traits::RFS) !=  0) { |                                 if(rd >= traits::RFS || rs1 >= traits::RFS || rs2 >= traits::RFS) { | ||||||
|                                     *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) - *(X+rs2 % traits::RFS); |                                     raise(0,  2); | ||||||
|  |                                 } | ||||||
|  |                                 else { | ||||||
|  |                                     if(rd !=  0) { | ||||||
|  |                                         *(X+rd) = *(X+rs1 % traits::RFS) - *(X+rs2 % traits::RFS); | ||||||
|  |                                     } | ||||||
|                                 } |                                 } | ||||||
|                             } |                             } | ||||||
|                 TRAP_SUB:break; |                 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; |                 *NEXT_PC = *PC + 4; | ||||||
|                 // execute instruction |                 // execute instruction | ||||||
|                 { |                 { | ||||||
|                                 if((rd % traits::RFS) !=  0) { |                                 if(rd >= traits::RFS || rs1 >= traits::RFS || rs2 >= traits::RFS) { | ||||||
|                                     *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) << (*(X+rs2 % traits::RFS) & (traits::XLEN -  1)); |                                     raise(0,  2); | ||||||
|  |                                 } | ||||||
|  |                                 else { | ||||||
|  |                                     if(rd !=  0) { | ||||||
|  |                                         *(X+rd) = *(X+rs1 % traits::RFS) << (*(X+rs2 % traits::RFS) & (traits::XLEN -  1)); | ||||||
|  |                                     } | ||||||
|                                 } |                                 } | ||||||
|                             } |                             } | ||||||
|                 TRAP_SLL:break; |                 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; |                 *NEXT_PC = *PC + 4; | ||||||
|                 // execute instruction |                 // execute instruction | ||||||
|                 { |                 { | ||||||
|                                 if((rd % traits::RFS) !=  0) { |                                 if(rd >= traits::RFS || rs1 >= traits::RFS || rs2 >= traits::RFS) { | ||||||
|                                     *(X+rd % traits::RFS) = (int32_t)*(X+rs1 % traits::RFS) < (int32_t)*(X+rs2 % traits::RFS)?  1 :  0; |                                     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; |                 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; |                 *NEXT_PC = *PC + 4; | ||||||
|                 // execute instruction |                 // execute instruction | ||||||
|                 { |                 { | ||||||
|                                 if((rd % traits::RFS) !=  0) { |                                 if(rd >= traits::RFS || rs1 >= traits::RFS || rs2 >= traits::RFS) { | ||||||
|                                     *(X+rd % traits::RFS) = (uint32_t)*(X+rs1 % traits::RFS) < (uint32_t)*(X+rs2 % traits::RFS)?  1 :  0; |                                     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; |                 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; |                 *NEXT_PC = *PC + 4; | ||||||
|                 // execute instruction |                 // execute instruction | ||||||
|                 { |                 { | ||||||
|                                 if((rd % traits::RFS) !=  0) { |                                 if(rd >= traits::RFS || rs1 >= traits::RFS || rs2 >= traits::RFS) { | ||||||
|                                     *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) ^ *(X+rs2 % traits::RFS); |                                     raise(0,  2); | ||||||
|  |                                 } | ||||||
|  |                                 else { | ||||||
|  |                                     if(rd !=  0) { | ||||||
|  |                                         *(X+rd) = *(X+rs1 % traits::RFS) ^ *(X+rs2 % traits::RFS); | ||||||
|  |                                     } | ||||||
|                                 } |                                 } | ||||||
|                             } |                             } | ||||||
|                 TRAP_XOR:break; |                 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; |                 *NEXT_PC = *PC + 4; | ||||||
|                 // execute instruction |                 // execute instruction | ||||||
|                 { |                 { | ||||||
|                                 if((rd % traits::RFS) !=  0) { |                                 if(rd >= traits::RFS || rs1 >= traits::RFS || rs2 >= traits::RFS) { | ||||||
|                                     *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) >> (*(X+rs2 % traits::RFS) & (traits::XLEN -  1)); |                                     raise(0,  2); | ||||||
|  |                                 } | ||||||
|  |                                 else { | ||||||
|  |                                     if(rd !=  0) { | ||||||
|  |                                         *(X+rd) = *(X+rs1 % traits::RFS) >> (*(X+rs2 % traits::RFS) & (traits::XLEN -  1)); | ||||||
|  |                                     } | ||||||
|                                 } |                                 } | ||||||
|                             } |                             } | ||||||
|                 TRAP_SRL:break; |                 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; |                 *NEXT_PC = *PC + 4; | ||||||
|                 // execute instruction |                 // execute instruction | ||||||
|                 { |                 { | ||||||
|                                 if((rd % traits::RFS) !=  0) { |                                 if(rd >= traits::RFS || rs1 >= traits::RFS || rs2 >= traits::RFS) { | ||||||
|                                     *(X+rd % traits::RFS) = (int32_t)*(X+rs1 % traits::RFS) >> (*(X+rs2 % traits::RFS) & (traits::XLEN -  1)); |                                     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; |                 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; |                 *NEXT_PC = *PC + 4; | ||||||
|                 // execute instruction |                 // execute instruction | ||||||
|                 { |                 { | ||||||
|                                 if((rd % traits::RFS) !=  0) { |                                 if(rd >= traits::RFS || rs1 >= traits::RFS || rs2 >= traits::RFS) { | ||||||
|                                     *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) | *(X+rs2 % traits::RFS); |                                     raise(0,  2); | ||||||
|  |                                 } | ||||||
|  |                                 else { | ||||||
|  |                                     if(rd !=  0) { | ||||||
|  |                                         *(X+rd) = *(X+rs1 % traits::RFS) | *(X+rs2 % traits::RFS); | ||||||
|  |                                     } | ||||||
|                                 } |                                 } | ||||||
|                             } |                             } | ||||||
|                 TRAP_OR:break; |                 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; |                 *NEXT_PC = *PC + 4; | ||||||
|                 // execute instruction |                 // execute instruction | ||||||
|                 { |                 { | ||||||
|                                 if((rd % traits::RFS) !=  0) { |                                 if(rd >= traits::RFS || rs1 >= traits::RFS || rs2 >= traits::RFS) { | ||||||
|                                     *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) & *(X+rs2 % traits::RFS); |                                     raise(0,  2); | ||||||
|  |                                 } | ||||||
|  |                                 else { | ||||||
|  |                                     if(rd !=  0) { | ||||||
|  |                                         *(X+rd) = *(X+rs1 % traits::RFS) & *(X+rs2 % traits::RFS); | ||||||
|  |                                     } | ||||||
|                                 } |                                 } | ||||||
|                             } |                             } | ||||||
|                 TRAP_AND:break; |                 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; |                 *NEXT_PC = *PC + 4; | ||||||
|                 // execute instruction |                 // execute instruction | ||||||
|                 { |                 { | ||||||
|                     uint32_t xrs1 = *(X+rs1 % traits::RFS); |                                 if(rd >= traits::RFS || rs1 >= traits::RFS) { | ||||||
|                     if((rd % traits::RFS) !=  0) { |                                     raise(0,  2); | ||||||
|                         uint32_t read_res = super::template read_mem<uint32_t>(traits::CSR, csr); |                                 } | ||||||
|                         if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRW; |                                 else { | ||||||
|                         uint32_t xrd = read_res; |                                     uint32_t xrs1 = *(X+rs1 % traits::RFS); | ||||||
|                         super::template write_mem<uint32_t>(traits::CSR, csr, xrs1); |                                     if(rd !=  0) { | ||||||
|                         if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRW; |                                         uint32_t read_res = super::template read_mem<uint32_t>(traits::CSR, csr); | ||||||
|                         *(X+rd % traits::RFS) = xrd; |                                         if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRW; | ||||||
|                     } |                                         uint32_t xrd = read_res; | ||||||
|                     else { |                                         super::template write_mem<uint32_t>(traits::CSR, csr, xrs1); | ||||||
|                         super::template write_mem<uint32_t>(traits::CSR, csr, xrs1); |                                         if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRW; | ||||||
|                         if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRW; |                                         *(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; |                 TRAP_CSRRW:break; | ||||||
|             }// @suppress("No break at end of case") |             }// @suppress("No break at end of case") | ||||||
|             case arch::traits<ARCH>::opcode_e::CSRRS: { |             case arch::traits<ARCH>::opcode_e::CSRRS: { | ||||||
| @@ -1347,18 +1542,23 @@ 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 | ||||||
|                 { |                 { | ||||||
|                     uint32_t read_res = super::template read_mem<uint32_t>(traits::CSR, csr); |                                 if(rd >= traits::RFS || rs1 >= traits::RFS) { | ||||||
|                     if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRS; |                                     raise(0,  2); | ||||||
|                     uint32_t xrd = read_res; |                                 } | ||||||
|                     uint32_t xrs1 = *(X+rs1 % traits::RFS); |                                 else { | ||||||
|                     if(rs1 !=  0) { |                                     uint32_t read_res = super::template read_mem<uint32_t>(traits::CSR, csr); | ||||||
|                         super::template write_mem<uint32_t>(traits::CSR, csr, xrd | xrs1); |                                     if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRS; | ||||||
|                         if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRS; |                                     uint32_t xrd = read_res; | ||||||
|                     } |                                     uint32_t xrs1 = *(X+rs1 % traits::RFS); | ||||||
|                     if((rd % traits::RFS) !=  0) { |                                     if(rs1 !=  0) { | ||||||
|                         *(X+rd % traits::RFS) = xrd; |                                         super::template write_mem<uint32_t>(traits::CSR, csr, xrd | xrs1); | ||||||
|                     } |                                         if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRS; | ||||||
|                 } |                                     } | ||||||
|  |                                     if(rd !=  0) { | ||||||
|  |                                         *(X+rd) = xrd; | ||||||
|  |                                     } | ||||||
|  |                                 } | ||||||
|  |                             } | ||||||
|                 TRAP_CSRRS:break; |                 TRAP_CSRRS:break; | ||||||
|             }// @suppress("No break at end of case") |             }// @suppress("No break at end of case") | ||||||
|             case arch::traits<ARCH>::opcode_e::CSRRC: { |             case arch::traits<ARCH>::opcode_e::CSRRC: { | ||||||
| @@ -1377,18 +1577,23 @@ 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 | ||||||
|                 { |                 { | ||||||
|                     uint32_t read_res = super::template read_mem<uint32_t>(traits::CSR, csr); |                                 if(rd >= traits::RFS || rs1 >= traits::RFS) { | ||||||
|                     if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRC; |                                     raise(0,  2); | ||||||
|                     uint32_t xrd = read_res; |                                 } | ||||||
|                     uint32_t xrs1 = *(X+rs1 % traits::RFS); |                                 else { | ||||||
|                     if(rs1 !=  0) { |                                     uint32_t read_res = super::template read_mem<uint32_t>(traits::CSR, csr); | ||||||
|                         super::template write_mem<uint32_t>(traits::CSR, csr, xrd & ~ xrs1); |                                     if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRC; | ||||||
|                         if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRC; |                                     uint32_t xrd = read_res; | ||||||
|                     } |                                     uint32_t xrs1 = *(X+rs1 % traits::RFS); | ||||||
|                     if((rd % traits::RFS) !=  0) { |                                     if(rs1 !=  0) { | ||||||
|                         *(X+rd % traits::RFS) = xrd; |                                         super::template write_mem<uint32_t>(traits::CSR, csr, xrd & ~ xrs1); | ||||||
|                     } |                                         if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRC; | ||||||
|                 } |                                     } | ||||||
|  |                                     if(rd !=  0) { | ||||||
|  |                                         *(X+rd) = xrd; | ||||||
|  |                                     } | ||||||
|  |                                 } | ||||||
|  |                             } | ||||||
|                 TRAP_CSRRC:break; |                 TRAP_CSRRC:break; | ||||||
|             }// @suppress("No break at end of case") |             }// @suppress("No break at end of case") | ||||||
|             case arch::traits<ARCH>::opcode_e::CSRRWI: { |             case arch::traits<ARCH>::opcode_e::CSRRWI: { | ||||||
| @@ -1407,15 +1612,20 @@ 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 | ||||||
|                 { |                 { | ||||||
|                     uint32_t read_res = super::template read_mem<uint32_t>(traits::CSR, csr); |                                 if(rd >= traits::RFS) { | ||||||
|                     if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRWI; |                                     raise(0,  2); | ||||||
|                     uint32_t xrd = read_res; |                                 } | ||||||
|                     super::template write_mem<uint32_t>(traits::CSR, csr, (uint32_t)zimm); |                                 else { | ||||||
|                     if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRWI; |                                     uint32_t read_res = super::template read_mem<uint32_t>(traits::CSR, csr); | ||||||
|                     if((rd % traits::RFS) !=  0) { |                                     if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRWI; | ||||||
|                         *(X+rd % traits::RFS) = xrd; |                                     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 !=  0) { | ||||||
|  |                                         *(X+rd) = xrd; | ||||||
|  |                                     } | ||||||
|  |                                 } | ||||||
|  |                             } | ||||||
|                 TRAP_CSRRWI:break; |                 TRAP_CSRRWI:break; | ||||||
|             }// @suppress("No break at end of case") |             }// @suppress("No break at end of case") | ||||||
|             case arch::traits<ARCH>::opcode_e::CSRRSI: { |             case arch::traits<ARCH>::opcode_e::CSRRSI: { | ||||||
| @@ -1434,17 +1644,22 @@ 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 | ||||||
|                 { |                 { | ||||||
|                     uint32_t read_res = super::template read_mem<uint32_t>(traits::CSR, csr); |                                 if(rd >= traits::RFS) { | ||||||
|                     if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRSI; |                                     raise(0,  2); | ||||||
|                     uint32_t xrd = read_res; |                                 } | ||||||
|                     if(zimm !=  0) { |                                 else { | ||||||
|                         super::template write_mem<uint32_t>(traits::CSR, csr, xrd | (uint32_t)zimm); |                                     uint32_t read_res = super::template read_mem<uint32_t>(traits::CSR, csr); | ||||||
|                         if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRSI; |                                     if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRSI; | ||||||
|                     } |                                     uint32_t xrd = read_res; | ||||||
|                     if((rd % traits::RFS) !=  0) { |                                     if(zimm !=  0) { | ||||||
|                         *(X+rd % traits::RFS) = xrd; |                                         super::template write_mem<uint32_t>(traits::CSR, csr, xrd | (uint32_t)zimm); | ||||||
|                     } |                                         if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRSI; | ||||||
|                 } |                                     } | ||||||
|  |                                     if(rd !=  0) { | ||||||
|  |                                         *(X+rd) = xrd; | ||||||
|  |                                     } | ||||||
|  |                                 } | ||||||
|  |                             } | ||||||
|                 TRAP_CSRRSI:break; |                 TRAP_CSRRSI:break; | ||||||
|             }// @suppress("No break at end of case") |             }// @suppress("No break at end of case") | ||||||
|             case arch::traits<ARCH>::opcode_e::CSRRCI: { |             case arch::traits<ARCH>::opcode_e::CSRRCI: { | ||||||
| @@ -1463,17 +1678,22 @@ 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 | ||||||
|                 { |                 { | ||||||
|                     uint32_t read_res = super::template read_mem<uint32_t>(traits::CSR, csr); |                                 if(rd >= traits::RFS) { | ||||||
|                     if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRCI; |                                     raise(0,  2); | ||||||
|                     uint32_t xrd = read_res; |                                 } | ||||||
|                     if(zimm !=  0) { |                                 else { | ||||||
|                         super::template write_mem<uint32_t>(traits::CSR, csr, xrd & ~ ((uint32_t)zimm)); |                                     uint32_t read_res = super::template read_mem<uint32_t>(traits::CSR, csr); | ||||||
|                         if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRCI; |                                     if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRCI; | ||||||
|                     } |                                     uint32_t xrd = read_res; | ||||||
|                     if((rd % traits::RFS) !=  0) { |                                     if(zimm !=  0) { | ||||||
|                         *(X+rd % traits::RFS) = xrd; |                                         super::template write_mem<uint32_t>(traits::CSR, csr, xrd & ~ ((uint32_t)zimm)); | ||||||
|                     } |                                         if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRCI; | ||||||
|                 } |                                     } | ||||||
|  |                                     if(rd !=  0) { | ||||||
|  |                                         *(X+rd) = xrd; | ||||||
|  |                                     } | ||||||
|  |                                 } | ||||||
|  |                             } | ||||||
|                 TRAP_CSRRCI:break; |                 TRAP_CSRRCI:break; | ||||||
|             }// @suppress("No break at end of case") |             }// @suppress("No break at end of case") | ||||||
|             case arch::traits<ARCH>::opcode_e::FENCE_I: { |             case arch::traits<ARCH>::opcode_e::FENCE_I: { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user