From 8c701d55c1afe10cfa9d82bb215487b8ab9d0a28 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Mon, 5 Dec 2022 09:15:48 +0100 Subject: [PATCH] adapt to latest changes in SCC --- CMakeLists.txt | 1 + src/vm/interp/vm_tgc_c.cpp | 712 ++++++++++++++++++++++++------------- 2 files changed, 467 insertions(+), 246 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7693201..c0a92a6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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}) diff --git a/src/vm/interp/vm_tgc_c.cpp b/src/vm/interp/vm_tgc_c.cpp index 6a0f8cb..826c770 100644 --- a/src/vm/interp/vm_tgc_c.cpp +++ b/src/vm/interp/vm_tgc_c.cpp @@ -358,8 +358,13 @@ typename vm_base::virt_addr_t vm_impl::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::virt_addr_t vm_impl::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::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction { - if(imm % traits::INSTR_ALIGNMENT) { - raise(0, 0); - } - else { - if((rd % traits::RFS) != 0) { - *(X+rd % traits::RFS) = *PC + 4; - } - *NEXT_PC = *PC + (int32_t)sext<21>(imm); - super::ex_info.branch_taken=true; - } - } + if(rd >= traits::RFS) { + raise(0, 2); + } + else { + if(imm % traits::INSTR_ALIGNMENT) { + raise(0, 0); + } + else { + 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::opcode_e::JALR: { @@ -429,18 +444,23 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction { - 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; - } - *NEXT_PC = new_pc & ~ 0x1; - super::ex_info.branch_taken=true; - } - } + 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 != 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::opcode_e::BEQ: { @@ -459,16 +479,21 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction { - if(*(X+rs1 % traits::RFS) == *(X+rs2 % traits::RFS)) { - if(imm % traits::INSTR_ALIGNMENT) { - raise(0, 0); - } - else { - *NEXT_PC = *PC + (int16_t)sext<13>(imm); - super::ex_info.branch_taken=true; - } - } - } + 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); + } + else { + *NEXT_PC = *PC + (int16_t)sext<13>(imm); + super::ex_info.branch_taken=true; + } + } + } + } TRAP_BEQ:break; }// @suppress("No break at end of case") case arch::traits::opcode_e::BNE: { @@ -487,16 +512,21 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction { - if(*(X+rs1 % traits::RFS) != *(X+rs2 % traits::RFS)) { - if(imm % traits::INSTR_ALIGNMENT) { - raise(0, 0); - } - else { - *NEXT_PC = *PC + (int16_t)sext<13>(imm); - super::ex_info.branch_taken=true; - } - } - } + 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); + } + else { + *NEXT_PC = *PC + (int16_t)sext<13>(imm); + super::ex_info.branch_taken=true; + } + } + } + } TRAP_BNE:break; }// @suppress("No break at end of case") case arch::traits::opcode_e::BLT: { @@ -515,16 +545,21 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction { - if((int32_t)*(X+rs1 % traits::RFS) < (int32_t)*(X+rs2 % traits::RFS)) { - if(imm % traits::INSTR_ALIGNMENT) { - raise(0, 0); - } - else { - *NEXT_PC = *PC + (int16_t)sext<13>(imm); - super::ex_info.branch_taken=true; - } - } - } + 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); + } + else { + *NEXT_PC = *PC + (int16_t)sext<13>(imm); + super::ex_info.branch_taken=true; + } + } + } + } TRAP_BLT:break; }// @suppress("No break at end of case") case arch::traits::opcode_e::BGE: { @@ -543,16 +578,21 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction { - if((int32_t)*(X+rs1 % traits::RFS) >= (int32_t)*(X+rs2 % traits::RFS)) { - if(imm % traits::INSTR_ALIGNMENT) { - raise(0, 0); - } - else { - *NEXT_PC = *PC + (int16_t)sext<13>(imm); - super::ex_info.branch_taken=true; - } - } - } + 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); + } + else { + *NEXT_PC = *PC + (int16_t)sext<13>(imm); + super::ex_info.branch_taken=true; + } + } + } + } TRAP_BGE:break; }// @suppress("No break at end of case") case arch::traits::opcode_e::BLTU: { @@ -571,16 +611,21 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction { - if(*(X+rs1 % traits::RFS) < *(X+rs2 % traits::RFS)) { - if(imm % traits::INSTR_ALIGNMENT) { - raise(0, 0); - } - else { - *NEXT_PC = *PC + (int16_t)sext<13>(imm); - super::ex_info.branch_taken=true; - } - } - } + 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); + } + else { + *NEXT_PC = *PC + (int16_t)sext<13>(imm); + super::ex_info.branch_taken=true; + } + } + } + } TRAP_BLTU:break; }// @suppress("No break at end of case") case arch::traits::opcode_e::BGEU: { @@ -599,16 +644,21 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction { - if(*(X+rs1 % traits::RFS) >= *(X+rs2 % traits::RFS)) { - if(imm % traits::INSTR_ALIGNMENT) { - raise(0, 0); - } - else { - *NEXT_PC = *PC + (int16_t)sext<13>(imm); - super::ex_info.branch_taken=true; - } - } - } + 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); + } + else { + *NEXT_PC = *PC + (int16_t)sext<13>(imm); + super::ex_info.branch_taken=true; + } + } + } + } TRAP_BGEU:break; }// @suppress("No break at end of case") case arch::traits::opcode_e::LB: { @@ -627,14 +677,19 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction { - uint32_t load_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); - int8_t read_res = super::template read_mem(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 >= 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(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; }// @suppress("No break at end of case") case arch::traits::opcode_e::LH: { @@ -653,14 +708,19 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction { - uint32_t load_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); - int16_t read_res = super::template read_mem(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 >= 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(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; }// @suppress("No break at end of case") case arch::traits::opcode_e::LW: { @@ -679,14 +739,19 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction { - uint32_t load_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); - int32_t read_res = super::template read_mem(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 >= 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(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; }// @suppress("No break at end of case") case arch::traits::opcode_e::LBU: { @@ -705,14 +770,19 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction { - uint32_t load_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); - uint8_t read_res = super::template read_mem(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 >= 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(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; }// @suppress("No break at end of case") case arch::traits::opcode_e::LHU: { @@ -731,14 +801,19 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction { - uint32_t load_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); - uint16_t read_res = super::template read_mem(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 >= 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(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; }// @suppress("No break at end of case") case arch::traits::opcode_e::SB: { @@ -757,10 +832,15 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction { - uint32_t store_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); - super::template write_mem(traits::MEM, store_address, (int8_t)*(X+rs2 % traits::RFS)); - if(this->core.trap_state>=0x80000000UL) goto TRAP_SB; - } + 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(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::opcode_e::SH: { @@ -779,10 +859,15 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction { - uint32_t store_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); - super::template write_mem(traits::MEM, store_address, (int16_t)*(X+rs2 % traits::RFS)); - if(this->core.trap_state>=0x80000000UL) goto TRAP_SH; - } + 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(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::opcode_e::SW: { @@ -801,10 +886,15 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction { - uint32_t store_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm); - super::template write_mem(traits::MEM, store_address, (int32_t)*(X+rs2 % traits::RFS)); - if(this->core.trap_state>=0x80000000UL) goto TRAP_SW; - } + 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(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::opcode_e::ADDI: { @@ -823,8 +913,13 @@ typename vm_base::virt_addr_t vm_impl::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::virt_addr_t vm_impl::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::virt_addr_t vm_impl::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::virt_addr_t vm_impl::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::virt_addr_t vm_impl::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::virt_addr_t vm_impl::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::virt_addr_t vm_impl::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::virt_addr_t vm_impl::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::virt_addr_t vm_impl::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::virt_addr_t vm_impl::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::virt_addr_t vm_impl::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::virt_addr_t vm_impl::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::virt_addr_t vm_impl::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::virt_addr_t vm_impl::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::virt_addr_t vm_impl::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::virt_addr_t vm_impl::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::virt_addr_t vm_impl::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::virt_addr_t vm_impl::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::virt_addr_t vm_impl::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::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction { - uint32_t xrs1 = *(X+rs1 % traits::RFS); - if((rd % traits::RFS) != 0) { - uint32_t read_res = super::template read_mem(traits::CSR, csr); - if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRW; - uint32_t xrd = read_res; - super::template write_mem(traits::CSR, csr, xrs1); - if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRW; - *(X+rd % traits::RFS) = xrd; - } - else { - super::template write_mem(traits::CSR, csr, xrs1); - if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRW; - } - } + if(rd >= traits::RFS || rs1 >= traits::RFS) { + raise(0, 2); + } + else { + uint32_t xrs1 = *(X+rs1 % traits::RFS); + if(rd != 0) { + uint32_t read_res = super::template read_mem(traits::CSR, csr); + if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRW; + uint32_t xrd = read_res; + super::template write_mem(traits::CSR, csr, xrs1); + if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRW; + *(X+rd) = xrd; + } + else { + super::template write_mem(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::opcode_e::CSRRS: { @@ -1347,18 +1542,23 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction { - uint32_t read_res = super::template read_mem(traits::CSR, csr); - if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRS; - uint32_t xrd = read_res; - uint32_t xrs1 = *(X+rs1 % traits::RFS); - if(rs1 != 0) { - super::template write_mem(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 >= traits::RFS || rs1 >= traits::RFS) { + raise(0, 2); + } + else { + uint32_t read_res = super::template read_mem(traits::CSR, csr); + if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRS; + uint32_t xrd = read_res; + uint32_t xrs1 = *(X+rs1 % traits::RFS); + if(rs1 != 0) { + super::template write_mem(traits::CSR, csr, xrd | xrs1); + if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRS; + } + if(rd != 0) { + *(X+rd) = xrd; + } + } + } TRAP_CSRRS:break; }// @suppress("No break at end of case") case arch::traits::opcode_e::CSRRC: { @@ -1377,18 +1577,23 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction { - uint32_t read_res = super::template read_mem(traits::CSR, csr); - if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRC; - uint32_t xrd = read_res; - uint32_t xrs1 = *(X+rs1 % traits::RFS); - if(rs1 != 0) { - super::template write_mem(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 >= traits::RFS || rs1 >= traits::RFS) { + raise(0, 2); + } + else { + uint32_t read_res = super::template read_mem(traits::CSR, csr); + if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRC; + uint32_t xrd = read_res; + uint32_t xrs1 = *(X+rs1 % traits::RFS); + if(rs1 != 0) { + super::template write_mem(traits::CSR, csr, xrd & ~ xrs1); + if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRC; + } + if(rd != 0) { + *(X+rd) = xrd; + } + } + } TRAP_CSRRC:break; }// @suppress("No break at end of case") case arch::traits::opcode_e::CSRRWI: { @@ -1407,15 +1612,20 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction { - uint32_t read_res = super::template read_mem(traits::CSR, csr); - if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRWI; - uint32_t xrd = read_res; - super::template write_mem(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 >= traits::RFS) { + raise(0, 2); + } + else { + uint32_t read_res = super::template read_mem(traits::CSR, csr); + if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRWI; + uint32_t xrd = read_res; + super::template write_mem(traits::CSR, csr, (uint32_t)zimm); + if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRWI; + if(rd != 0) { + *(X+rd) = xrd; + } + } + } TRAP_CSRRWI:break; }// @suppress("No break at end of case") case arch::traits::opcode_e::CSRRSI: { @@ -1434,17 +1644,22 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction { - uint32_t read_res = super::template read_mem(traits::CSR, csr); - if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRSI; - uint32_t xrd = read_res; - if(zimm != 0) { - super::template write_mem(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 >= traits::RFS) { + raise(0, 2); + } + else { + uint32_t read_res = super::template read_mem(traits::CSR, csr); + if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRSI; + uint32_t xrd = read_res; + if(zimm != 0) { + super::template write_mem(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; }// @suppress("No break at end of case") case arch::traits::opcode_e::CSRRCI: { @@ -1463,17 +1678,22 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 4; // execute instruction { - uint32_t read_res = super::template read_mem(traits::CSR, csr); - if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRCI; - uint32_t xrd = read_res; - if(zimm != 0) { - super::template write_mem(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 >= traits::RFS) { + raise(0, 2); + } + else { + uint32_t read_res = super::template read_mem(traits::CSR, csr); + if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRCI; + uint32_t xrd = read_res; + if(zimm != 0) { + super::template write_mem(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; }// @suppress("No break at end of case") case arch::traits::opcode_e::FENCE_I: {