adapt to latest changes in SCC

This commit is contained in:
Eyck Jentzsch 2022-12-05 09:15:48 +01:00
parent f585489ff5
commit 8c701d55c1
2 changed files with 467 additions and 246 deletions

View File

@ -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})

View File

@ -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: {