From a8a27823293af3f8454f07046406146d8ee32982 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Tue, 4 Apr 2023 16:10:12 +0200 Subject: [PATCH] adds changes from latest CoreDSL description --- src/vm/interp/vm_tgc_c.cpp | 277 ++++++++++++++++++++++++------------- 1 file changed, 181 insertions(+), 96 deletions(-) diff --git a/src/vm/interp/vm_tgc_c.cpp b/src/vm/interp/vm_tgc_c.cpp index 55434d8..eaef390 100644 --- a/src/vm/interp/vm_tgc_c.cpp +++ b/src/vm/interp/vm_tgc_c.cpp @@ -1727,11 +1727,16 @@ 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) { - int64_t res = (int64_t)(int32_t)*(X+rs1 % traits::RFS) * (int64_t)(int32_t)*(X+rs2 % traits::RFS); - *(X+rd % traits::RFS) = (uint32_t)res; - } - } + if(rd >= traits::RFS || rs1 >= traits::RFS || rs2 >= traits::RFS) { + raise(0, 2); + } + else { + int64_t res = (int64_t)(int32_t)*(X+rs1) * (int64_t)(int32_t)*(X+rs2); + if(rd != 0) { + *(X+rd) = (uint32_t)res; + } + } + } TRAP_MUL:break; }// @suppress("No break at end of case") case arch::traits::opcode_e::MULH: { @@ -1750,11 +1755,16 @@ 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) { - int64_t res = (int64_t)(int32_t)*(X+rs1 % traits::RFS) * (int64_t)(int32_t)*(X+rs2 % traits::RFS); - *(X+rd % traits::RFS) = (uint32_t)(res >> traits::XLEN); - } - } + if(rd >= traits::RFS || rs1 >= traits::RFS || rs2 >= traits::RFS) { + raise(0, 2); + } + else { + int64_t res = (int64_t)(int32_t)*(X+rs1) * (int64_t)(int32_t)*(X+rs2); + if(rd != 0) { + *(X+rd) = (uint32_t)(res >> traits::XLEN); + } + } + } TRAP_MULH:break; }// @suppress("No break at end of case") case arch::traits::opcode_e::MULHSU: { @@ -1773,11 +1783,16 @@ 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) { - int64_t res = (int64_t)(int32_t)*(X+rs1 % traits::RFS) * (uint64_t)*(X+rs2 % traits::RFS); - *(X+rd % traits::RFS) = (uint32_t)(res >> traits::XLEN); - } - } + if(rd >= traits::RFS || rs1 >= traits::RFS || rs2 >= traits::RFS) { + raise(0, 2); + } + else { + int64_t res = (int64_t)(int32_t)*(X+rs1) * (uint64_t)*(X+rs2); + if(rd != 0) { + *(X+rd) = (uint32_t)(res >> traits::XLEN); + } + } + } TRAP_MULHSU:break; }// @suppress("No break at end of case") case arch::traits::opcode_e::MULHU: { @@ -1796,11 +1811,16 @@ 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) { - uint64_t res = (uint64_t)*(X+rs1 % traits::RFS) * (uint64_t)*(X+rs2 % traits::RFS); - *(X+rd % traits::RFS) = (uint32_t)(res >> traits::XLEN); - } - } + if(rd >= traits::RFS || rs1 >= traits::RFS || rs2 >= traits::RFS) { + raise(0, 2); + } + else { + uint64_t res = (uint64_t)*(X+rs1) * (uint64_t)*(X+rs2); + if(rd != 0) { + *(X+rd) = (uint32_t)(res >> traits::XLEN); + } + } + } TRAP_MULHU:break; }// @suppress("No break at end of case") case arch::traits::opcode_e::DIV: { @@ -1819,21 +1839,28 @@ 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) { - if(*(X+rs2 % traits::RFS) != 0) { - uint32_t MMIN = 1 << (traits::XLEN - 1); - if(*(X+rs1 % traits::RFS) == MMIN && (int32_t)*(X+rs2 % traits::RFS) == - 1) { - *(X+rd % traits::RFS) = MMIN; + if(rd >= traits::RFS || rs1 >= traits::RFS || rs2 >= traits::RFS) { + raise(0, 2); + } + else { + int32_t dividend = (int32_t)*(X+rs1); + int32_t divisor = (int32_t)*(X+rs2); + if(rd != 0) { + if(divisor != 0) { + uint32_t MMIN = ((uint32_t)1) << (traits::XLEN - 1); + if(*(X+rs1) == MMIN && divisor == - 1) { + *(X+rd) = MMIN; + } + else { + *(X+rd) = dividend / divisor; + } + } + else { + *(X+rd) = (int32_t)- 1; + } + } + } } - else { - *(X+rd % traits::RFS) = (int32_t)*(X+rs1 % traits::RFS) / (int32_t)*(X+rs2 % traits::RFS); - } - } - else { - *(X+rd % traits::RFS) = - 1; - } - } - } TRAP_DIV:break; }// @suppress("No break at end of case") case arch::traits::opcode_e::DIVU: { @@ -1852,15 +1879,22 @@ 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) { - if(*(X+rs2 % traits::RFS) != 0) { - *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) / *(X+rs2 % traits::RFS); - } - else { - *(X+rd % traits::RFS) = - 1; - } - } - } + if(rd >= traits::RFS || rs1 >= traits::RFS || rs2 >= traits::RFS) { + raise(0, 2); + } + else { + if(*(X+rs2) != 0) { + if(rd != 0) { + *(X+rd) = *(X+rs1) / *(X+rs2); + } + } + else { + if(rd != 0) { + *(X+rd) = (int32_t)- 1; + } + } + } + } TRAP_DIVU:break; }// @suppress("No break at end of case") case arch::traits::opcode_e::REM: { @@ -1879,21 +1913,30 @@ 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) { - if(*(X+rs2 % traits::RFS) != 0) { - uint32_t MMIN = 1 << (traits::XLEN - 1); - if(*(X+rs1 % traits::RFS) == MMIN && (int32_t)*(X+rs2 % traits::RFS) == - 1) { - *(X+rd % traits::RFS) = 0; + if(rd >= traits::RFS || rs1 >= traits::RFS || rs2 >= traits::RFS) { + raise(0, 2); + } + else { + if(*(X+rs2) != 0) { + uint32_t MMIN = 1 << (traits::XLEN - 1); + if(*(X+rs1) == MMIN && (int32_t)*(X+rs2) == - 1) { + if(rd != 0) { + *(X+rd) = 0; + } + } + else { + if(rd != 0) { + *(X+rd) = (int32_t)*(X+rs1) % (int32_t)*(X+rs2); + } + } + } + else { + if(rd != 0) { + *(X+rd) = *(X+rs1); + } + } + } } - else { - *(X+rd % traits::RFS) = (int32_t)*(X+rs1 % traits::RFS) % (int32_t)*(X+rs2 % traits::RFS); - } - } - else { - *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS); - } - } - } TRAP_REM:break; }// @suppress("No break at end of case") case arch::traits::opcode_e::REMU: { @@ -1912,15 +1955,22 @@ 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) { - if(*(X+rs2 % traits::RFS) != 0) { - *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) % *(X+rs2 % traits::RFS); - } - else { - *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS); - } - } - } + if(rd >= traits::RFS || rs1 >= traits::RFS || rs2 >= traits::RFS) { + raise(0, 2); + } + else { + if(*(X+rs2) != 0) { + if(rd != 0) { + *(X+rd) = *(X+rs1) % *(X+rs2); + } + } + else { + if(rd != 0) { + *(X+rd) = *(X+rs1); + } + } + } + } TRAP_REMU:break; }// @suppress("No break at end of case") case arch::traits::opcode_e::CADDI4SPN: { @@ -2007,8 +2057,13 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 2; // execute instruction { - if((rs1 % traits::RFS) != 0) { - *(X+rs1 % traits::RFS) = *(X+rs1 % traits::RFS) + (int8_t)sext<6>(imm); + if(rs1 >= traits::RFS) { + raise(0, 2); + } + else { + if(rs1 != 0) { + *(X+rs1) = *(X+rs1) + (int8_t)sext<6>(imm); + } } } TRAP_CADDI:break; @@ -2061,10 +2116,15 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 2; // execute instruction { - if((rd % traits::RFS) != 0) { - *(X+rd % traits::RFS) = (int8_t)sext<6>(imm); - } - } + if(rd >= traits::RFS) { + raise(0, 2); + } + else { + if(rd != 0) { + *(X+rd) = (int8_t)sext<6>(imm); + } + } + } TRAP_CLI:break; }// @suppress("No break at end of case") case arch::traits::opcode_e::CLUI: { @@ -2082,11 +2142,11 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 2; // execute instruction { - if(imm == 0) { + if(imm == 0 || rd >= traits::RFS) { raise(0, 2); } - if((rd % traits::RFS) != 0) { - *(X+rd % traits::RFS) = (int32_t)sext<18>(imm); + if(rd != 0) { + *(X+rd) = (int32_t)sext<18>(imm); } } TRAP_CLUI:break; @@ -2345,8 +2405,13 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 2; // execute instruction { - if(nzuimm) { - *(X+rs1 % traits::RFS) = *(X+rs1 % traits::RFS) << nzuimm; + if(rs1 >= traits::RFS) { + raise(0, 2); + } + else { + if(rs1 != 0) { + *(X+rs1) = *(X+rs1) << nzuimm; + } } } TRAP_CSLLI:break; @@ -2366,14 +2431,14 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 2; // execute instruction { - if(rd % traits::RFS) { + if(rd >= traits::RFS || rd == 0) { + raise(0, 2); + } + else { int32_t read_res = super::template read_mem(traits::MEM, *(X+2) + uimm); if(this->core.trap_state>=0x80000000UL) goto TRAP_CLWSP; int32_t res = read_res; - *(X+rd % traits::RFS) = (int32_t)res; - } - else { - raise(0, 2); + *(X+rd) = (int32_t)res; } } TRAP_CLWSP:break; @@ -2393,8 +2458,13 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 2; // execute instruction { - if((rd % traits::RFS) != 0) { - *(X+rd % traits::RFS) = *(X+rs2 % traits::RFS); + if(rd >= traits::RFS) { + raise(0, 2); + } + else { + if(rd != 0) { + *(X+rd) = *(X+rs2); + } } } TRAP_CMV:break; @@ -2413,7 +2483,7 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 2; // execute instruction { - if(rs1) { + if(rs1 && rs1 < traits::RFS) { *NEXT_PC = *(X+rs1 % traits::RFS) & ~ 0x1; super::ex_info.branch_taken=true; } @@ -2451,8 +2521,13 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 2; // execute instruction { - if((rd % traits::RFS) != 0) { - *(X+rd % traits::RFS) = *(X+rd % traits::RFS) + *(X+rs2 % traits::RFS); + if(rd >= traits::RFS) { + raise(0, 2); + } + else { + if(rd != 0) { + *(X+rd) = *(X+rd) + *(X+rs2); + } } } TRAP_CADD:break; @@ -2471,11 +2546,16 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 2; // execute instruction { - uint32_t new_pc = *(X+rs1 % traits::RFS); - *(X+1) = *PC + 2; - *NEXT_PC = new_pc & ~ 0x1; - super::ex_info.branch_taken=true; - } + if(rs1 >= traits::RFS) { + raise(0, 2); + } + else { + uint32_t new_pc = *(X+rs1); + *(X+1) = *PC + 2; + *NEXT_PC = new_pc & ~ 0x1; + super::ex_info.branch_taken=true; + } + } TRAP_CJALR:break; }// @suppress("No break at end of case") case arch::traits::opcode_e::CEBREAK: { @@ -2506,10 +2586,15 @@ typename vm_base::virt_addr_t vm_impl::execute_inst(finish_cond_e co *NEXT_PC = *PC + 2; // execute instruction { - uint32_t offs = *(X+2) + uimm; - super::template write_mem(traits::MEM, offs, (uint32_t)*(X+rs2 % traits::RFS)); - if(this->core.trap_state>=0x80000000UL) goto TRAP_CSWSP; - } + if(rs2 >= traits::RFS) { + raise(0, 2); + } + else { + uint32_t offs = *(X+2) + uimm; + super::template write_mem(traits::MEM, offs, (uint32_t)*(X+rs2)); + if(this->core.trap_state>=0x80000000UL) goto TRAP_CSWSP; + } + } TRAP_CSWSP:break; }// @suppress("No break at end of case") case arch::traits::opcode_e::DII: {