adapt to latest changes in SCC
This commit is contained in:
parent
f585489ff5
commit
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(rd >= traits::RFS) {
|
||||||
|
raise(0, 2);
|
||||||
|
}
|
||||||
|
else {
|
||||||
if(imm % traits::INSTR_ALIGNMENT) {
|
if(imm % traits::INSTR_ALIGNMENT) {
|
||||||
raise(0, 0);
|
raise(0, 0);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if((rd % traits::RFS) != 0) {
|
if(rd != 0) {
|
||||||
*(X+rd % traits::RFS) = *PC + 4;
|
*(X+rd) = *PC + 4;
|
||||||
}
|
}
|
||||||
*NEXT_PC = *PC + (int32_t)sext<21>(imm);
|
*NEXT_PC = *PC + (int32_t)sext<21>(imm);
|
||||||
super::ex_info.branch_taken=true;
|
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
|
||||||
{
|
{
|
||||||
|
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;
|
uint32_t new_pc = (*(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm)) & ~ 0x1;
|
||||||
if(new_pc % traits::INSTR_ALIGNMENT) {
|
if(new_pc % traits::INSTR_ALIGNMENT) {
|
||||||
raise(0, 0);
|
raise(0, 0);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if((rd % traits::RFS) != 0) {
|
if(rd != 0) {
|
||||||
*(X+rd % traits::RFS) = *PC + 4;
|
*(X+rd) = *PC + 4;
|
||||||
}
|
}
|
||||||
*NEXT_PC = new_pc & ~ 0x1;
|
*NEXT_PC = new_pc & ~ 0x1;
|
||||||
super::ex_info.branch_taken=true;
|
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,6 +479,10 @@ 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(rs2 >= traits::RFS || rs1 >= traits::RFS) {
|
||||||
|
raise(0, 2);
|
||||||
|
}
|
||||||
|
else {
|
||||||
if(*(X+rs1 % traits::RFS) == *(X+rs2 % traits::RFS)) {
|
if(*(X+rs1 % traits::RFS) == *(X+rs2 % traits::RFS)) {
|
||||||
if(imm % traits::INSTR_ALIGNMENT) {
|
if(imm % traits::INSTR_ALIGNMENT) {
|
||||||
raise(0, 0);
|
raise(0, 0);
|
||||||
|
@ -469,6 +493,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
TRAP_BEQ:break;
|
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,6 +512,10 @@ 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(rs2 >= traits::RFS || rs1 >= traits::RFS) {
|
||||||
|
raise(0, 2);
|
||||||
|
}
|
||||||
|
else {
|
||||||
if(*(X+rs1 % traits::RFS) != *(X+rs2 % traits::RFS)) {
|
if(*(X+rs1 % traits::RFS) != *(X+rs2 % traits::RFS)) {
|
||||||
if(imm % traits::INSTR_ALIGNMENT) {
|
if(imm % traits::INSTR_ALIGNMENT) {
|
||||||
raise(0, 0);
|
raise(0, 0);
|
||||||
|
@ -497,6 +526,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
TRAP_BNE:break;
|
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,6 +545,10 @@ 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(rs2 >= traits::RFS || rs1 >= traits::RFS) {
|
||||||
|
raise(0, 2);
|
||||||
|
}
|
||||||
|
else {
|
||||||
if((int32_t)*(X+rs1 % traits::RFS) < (int32_t)*(X+rs2 % traits::RFS)) {
|
if((int32_t)*(X+rs1 % traits::RFS) < (int32_t)*(X+rs2 % traits::RFS)) {
|
||||||
if(imm % traits::INSTR_ALIGNMENT) {
|
if(imm % traits::INSTR_ALIGNMENT) {
|
||||||
raise(0, 0);
|
raise(0, 0);
|
||||||
|
@ -525,6 +559,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
TRAP_BLT:break;
|
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,6 +578,10 @@ 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(rs2 >= traits::RFS || rs1 >= traits::RFS) {
|
||||||
|
raise(0, 2);
|
||||||
|
}
|
||||||
|
else {
|
||||||
if((int32_t)*(X+rs1 % traits::RFS) >= (int32_t)*(X+rs2 % traits::RFS)) {
|
if((int32_t)*(X+rs1 % traits::RFS) >= (int32_t)*(X+rs2 % traits::RFS)) {
|
||||||
if(imm % traits::INSTR_ALIGNMENT) {
|
if(imm % traits::INSTR_ALIGNMENT) {
|
||||||
raise(0, 0);
|
raise(0, 0);
|
||||||
|
@ -553,6 +592,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
TRAP_BGE:break;
|
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,6 +611,10 @@ 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(rs2 >= traits::RFS || rs1 >= traits::RFS) {
|
||||||
|
raise(0, 2);
|
||||||
|
}
|
||||||
|
else {
|
||||||
if(*(X+rs1 % traits::RFS) < *(X+rs2 % traits::RFS)) {
|
if(*(X+rs1 % traits::RFS) < *(X+rs2 % traits::RFS)) {
|
||||||
if(imm % traits::INSTR_ALIGNMENT) {
|
if(imm % traits::INSTR_ALIGNMENT) {
|
||||||
raise(0, 0);
|
raise(0, 0);
|
||||||
|
@ -581,6 +625,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
TRAP_BLTU:break;
|
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,6 +644,10 @@ 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(rs2 >= traits::RFS || rs1 >= traits::RFS) {
|
||||||
|
raise(0, 2);
|
||||||
|
}
|
||||||
|
else {
|
||||||
if(*(X+rs1 % traits::RFS) >= *(X+rs2 % traits::RFS)) {
|
if(*(X+rs1 % traits::RFS) >= *(X+rs2 % traits::RFS)) {
|
||||||
if(imm % traits::INSTR_ALIGNMENT) {
|
if(imm % traits::INSTR_ALIGNMENT) {
|
||||||
raise(0, 0);
|
raise(0, 0);
|
||||||
|
@ -609,6 +658,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
TRAP_BGEU:break;
|
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,12 +677,17 @@ 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 || rs1 >= traits::RFS) {
|
||||||
|
raise(0, 2);
|
||||||
|
}
|
||||||
|
else {
|
||||||
uint32_t load_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm);
|
uint32_t load_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm);
|
||||||
int8_t read_res = super::template read_mem<int8_t>(traits::MEM, load_address);
|
int8_t read_res = super::template read_mem<int8_t>(traits::MEM, load_address);
|
||||||
if(this->core.trap_state>=0x80000000UL) goto TRAP_LB;
|
if(this->core.trap_state>=0x80000000UL) goto TRAP_LB;
|
||||||
int8_t res = (int8_t)read_res;
|
int8_t res = (int8_t)read_res;
|
||||||
if((rd % traits::RFS) != 0) {
|
if(rd != 0) {
|
||||||
*(X+rd % traits::RFS) = (int32_t)res;
|
*(X+rd) = (int32_t)res;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TRAP_LB:break;
|
TRAP_LB:break;
|
||||||
|
@ -653,12 +708,17 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||||
*NEXT_PC = *PC + 4;
|
*NEXT_PC = *PC + 4;
|
||||||
// execute instruction
|
// execute instruction
|
||||||
{
|
{
|
||||||
|
if(rd >= traits::RFS || rs1 >= traits::RFS) {
|
||||||
|
raise(0, 2);
|
||||||
|
}
|
||||||
|
else {
|
||||||
uint32_t load_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm);
|
uint32_t load_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm);
|
||||||
int16_t read_res = super::template read_mem<int16_t>(traits::MEM, load_address);
|
int16_t read_res = super::template read_mem<int16_t>(traits::MEM, load_address);
|
||||||
if(this->core.trap_state>=0x80000000UL) goto TRAP_LH;
|
if(this->core.trap_state>=0x80000000UL) goto TRAP_LH;
|
||||||
int16_t res = (int16_t)read_res;
|
int16_t res = (int16_t)read_res;
|
||||||
if((rd % traits::RFS) != 0) {
|
if(rd != 0) {
|
||||||
*(X+rd % traits::RFS) = (int32_t)res;
|
*(X+rd) = (int32_t)res;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TRAP_LH:break;
|
TRAP_LH:break;
|
||||||
|
@ -679,12 +739,17 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||||
*NEXT_PC = *PC + 4;
|
*NEXT_PC = *PC + 4;
|
||||||
// execute instruction
|
// execute instruction
|
||||||
{
|
{
|
||||||
|
if(rd >= traits::RFS || rs1 >= traits::RFS) {
|
||||||
|
raise(0, 2);
|
||||||
|
}
|
||||||
|
else {
|
||||||
uint32_t load_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm);
|
uint32_t load_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm);
|
||||||
int32_t read_res = super::template read_mem<int32_t>(traits::MEM, load_address);
|
int32_t read_res = super::template read_mem<int32_t>(traits::MEM, load_address);
|
||||||
if(this->core.trap_state>=0x80000000UL) goto TRAP_LW;
|
if(this->core.trap_state>=0x80000000UL) goto TRAP_LW;
|
||||||
int32_t res = (int32_t)read_res;
|
int32_t res = (int32_t)read_res;
|
||||||
if((rd % traits::RFS) != 0) {
|
if(rd != 0) {
|
||||||
*(X+rd % traits::RFS) = (int32_t)res;
|
*(X+rd) = (int32_t)res;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TRAP_LW:break;
|
TRAP_LW:break;
|
||||||
|
@ -705,12 +770,17 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||||
*NEXT_PC = *PC + 4;
|
*NEXT_PC = *PC + 4;
|
||||||
// execute instruction
|
// execute instruction
|
||||||
{
|
{
|
||||||
|
if(rd >= traits::RFS || rs1 >= traits::RFS) {
|
||||||
|
raise(0, 2);
|
||||||
|
}
|
||||||
|
else {
|
||||||
uint32_t load_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm);
|
uint32_t load_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm);
|
||||||
uint8_t read_res = super::template read_mem<uint8_t>(traits::MEM, load_address);
|
uint8_t read_res = super::template read_mem<uint8_t>(traits::MEM, load_address);
|
||||||
if(this->core.trap_state>=0x80000000UL) goto TRAP_LBU;
|
if(this->core.trap_state>=0x80000000UL) goto TRAP_LBU;
|
||||||
uint8_t res = (uint8_t)read_res;
|
uint8_t res = (uint8_t)read_res;
|
||||||
if((rd % traits::RFS) != 0) {
|
if(rd != 0) {
|
||||||
*(X+rd % traits::RFS) = (uint32_t)res;
|
*(X+rd) = (uint32_t)res;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TRAP_LBU:break;
|
TRAP_LBU:break;
|
||||||
|
@ -731,12 +801,17 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||||
*NEXT_PC = *PC + 4;
|
*NEXT_PC = *PC + 4;
|
||||||
// execute instruction
|
// execute instruction
|
||||||
{
|
{
|
||||||
|
if(rd >= traits::RFS || rs1 >= traits::RFS) {
|
||||||
|
raise(0, 2);
|
||||||
|
}
|
||||||
|
else {
|
||||||
uint32_t load_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm);
|
uint32_t load_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm);
|
||||||
uint16_t read_res = super::template read_mem<uint16_t>(traits::MEM, load_address);
|
uint16_t read_res = super::template read_mem<uint16_t>(traits::MEM, load_address);
|
||||||
if(this->core.trap_state>=0x80000000UL) goto TRAP_LHU;
|
if(this->core.trap_state>=0x80000000UL) goto TRAP_LHU;
|
||||||
uint16_t res = (uint16_t)read_res;
|
uint16_t res = (uint16_t)read_res;
|
||||||
if((rd % traits::RFS) != 0) {
|
if(rd != 0) {
|
||||||
*(X+rd % traits::RFS) = (uint32_t)res;
|
*(X+rd) = (uint32_t)res;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TRAP_LHU:break;
|
TRAP_LHU:break;
|
||||||
|
@ -757,10 +832,15 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||||
*NEXT_PC = *PC + 4;
|
*NEXT_PC = *PC + 4;
|
||||||
// execute instruction
|
// execute instruction
|
||||||
{
|
{
|
||||||
|
if(rs2 >= traits::RFS || rs1 >= traits::RFS) {
|
||||||
|
raise(0, 2);
|
||||||
|
}
|
||||||
|
else {
|
||||||
uint32_t store_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm);
|
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));
|
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;
|
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
|
||||||
{
|
{
|
||||||
|
if(rs2 >= traits::RFS || rs1 >= traits::RFS) {
|
||||||
|
raise(0, 2);
|
||||||
|
}
|
||||||
|
else {
|
||||||
uint32_t store_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm);
|
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));
|
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;
|
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
|
||||||
{
|
{
|
||||||
|
if(rs2 >= traits::RFS || rs1 >= traits::RFS) {
|
||||||
|
raise(0, 2);
|
||||||
|
}
|
||||||
|
else {
|
||||||
uint32_t store_address = *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm);
|
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));
|
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;
|
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
|
||||||
{
|
{
|
||||||
|
if(rd >= traits::RFS || rs1 >= traits::RFS) {
|
||||||
|
raise(0, 2);
|
||||||
|
}
|
||||||
|
else {
|
||||||
uint32_t xrs1 = *(X+rs1 % traits::RFS);
|
uint32_t xrs1 = *(X+rs1 % traits::RFS);
|
||||||
if((rd % traits::RFS) != 0) {
|
if(rd != 0) {
|
||||||
uint32_t read_res = super::template read_mem<uint32_t>(traits::CSR, csr);
|
uint32_t read_res = super::template read_mem<uint32_t>(traits::CSR, csr);
|
||||||
if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRW;
|
if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRW;
|
||||||
uint32_t xrd = read_res;
|
uint32_t xrd = read_res;
|
||||||
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 % traits::RFS) = xrd;
|
*(X+rd) = xrd;
|
||||||
}
|
}
|
||||||
else {
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
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,6 +1542,10 @@ 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 || rs1 >= traits::RFS) {
|
||||||
|
raise(0, 2);
|
||||||
|
}
|
||||||
|
else {
|
||||||
uint32_t read_res = super::template read_mem<uint32_t>(traits::CSR, csr);
|
uint32_t read_res = super::template read_mem<uint32_t>(traits::CSR, csr);
|
||||||
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 xrd = read_res;
|
||||||
|
@ -1355,8 +1554,9 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||||
super::template write_mem<uint32_t>(traits::CSR, csr, xrd | xrs1);
|
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;
|
||||||
}
|
}
|
||||||
if((rd % traits::RFS) != 0) {
|
if(rd != 0) {
|
||||||
*(X+rd % traits::RFS) = xrd;
|
*(X+rd) = xrd;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TRAP_CSRRS:break;
|
TRAP_CSRRS:break;
|
||||||
|
@ -1377,6 +1577,10 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||||
*NEXT_PC = *PC + 4;
|
*NEXT_PC = *PC + 4;
|
||||||
// execute instruction
|
// execute instruction
|
||||||
{
|
{
|
||||||
|
if(rd >= traits::RFS || rs1 >= traits::RFS) {
|
||||||
|
raise(0, 2);
|
||||||
|
}
|
||||||
|
else {
|
||||||
uint32_t read_res = super::template read_mem<uint32_t>(traits::CSR, csr);
|
uint32_t read_res = super::template read_mem<uint32_t>(traits::CSR, csr);
|
||||||
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 xrd = read_res;
|
||||||
|
@ -1385,8 +1589,9 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||||
super::template write_mem<uint32_t>(traits::CSR, csr, xrd & ~ xrs1);
|
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;
|
||||||
}
|
}
|
||||||
if((rd % traits::RFS) != 0) {
|
if(rd != 0) {
|
||||||
*(X+rd % traits::RFS) = xrd;
|
*(X+rd) = xrd;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TRAP_CSRRC:break;
|
TRAP_CSRRC:break;
|
||||||
|
@ -1407,13 +1612,18 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||||
*NEXT_PC = *PC + 4;
|
*NEXT_PC = *PC + 4;
|
||||||
// execute instruction
|
// execute instruction
|
||||||
{
|
{
|
||||||
|
if(rd >= traits::RFS) {
|
||||||
|
raise(0, 2);
|
||||||
|
}
|
||||||
|
else {
|
||||||
uint32_t read_res = super::template read_mem<uint32_t>(traits::CSR, csr);
|
uint32_t read_res = super::template read_mem<uint32_t>(traits::CSR, csr);
|
||||||
if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRWI;
|
if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRWI;
|
||||||
uint32_t xrd = read_res;
|
uint32_t xrd = read_res;
|
||||||
super::template write_mem<uint32_t>(traits::CSR, csr, (uint32_t)zimm);
|
super::template write_mem<uint32_t>(traits::CSR, csr, (uint32_t)zimm);
|
||||||
if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRWI;
|
if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRWI;
|
||||||
if((rd % traits::RFS) != 0) {
|
if(rd != 0) {
|
||||||
*(X+rd % traits::RFS) = xrd;
|
*(X+rd) = xrd;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TRAP_CSRRWI:break;
|
TRAP_CSRRWI:break;
|
||||||
|
@ -1434,6 +1644,10 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||||
*NEXT_PC = *PC + 4;
|
*NEXT_PC = *PC + 4;
|
||||||
// execute instruction
|
// execute instruction
|
||||||
{
|
{
|
||||||
|
if(rd >= traits::RFS) {
|
||||||
|
raise(0, 2);
|
||||||
|
}
|
||||||
|
else {
|
||||||
uint32_t read_res = super::template read_mem<uint32_t>(traits::CSR, csr);
|
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;
|
uint32_t xrd = read_res;
|
||||||
|
@ -1441,8 +1655,9 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||||
super::template write_mem<uint32_t>(traits::CSR, csr, xrd | (uint32_t)zimm);
|
super::template write_mem<uint32_t>(traits::CSR, csr, xrd | (uint32_t)zimm);
|
||||||
if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRSI;
|
if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRSI;
|
||||||
}
|
}
|
||||||
if((rd % traits::RFS) != 0) {
|
if(rd != 0) {
|
||||||
*(X+rd % traits::RFS) = xrd;
|
*(X+rd) = xrd;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TRAP_CSRRSI:break;
|
TRAP_CSRRSI:break;
|
||||||
|
@ -1463,6 +1678,10 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||||
*NEXT_PC = *PC + 4;
|
*NEXT_PC = *PC + 4;
|
||||||
// execute instruction
|
// execute instruction
|
||||||
{
|
{
|
||||||
|
if(rd >= traits::RFS) {
|
||||||
|
raise(0, 2);
|
||||||
|
}
|
||||||
|
else {
|
||||||
uint32_t read_res = super::template read_mem<uint32_t>(traits::CSR, csr);
|
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;
|
uint32_t xrd = read_res;
|
||||||
|
@ -1470,8 +1689,9 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
||||||
super::template write_mem<uint32_t>(traits::CSR, csr, xrd & ~ ((uint32_t)zimm));
|
super::template write_mem<uint32_t>(traits::CSR, csr, xrd & ~ ((uint32_t)zimm));
|
||||||
if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRCI;
|
if(this->core.trap_state>=0x80000000UL) goto TRAP_CSRRCI;
|
||||||
}
|
}
|
||||||
if((rd % traits::RFS) != 0) {
|
if(rd != 0) {
|
||||||
*(X+rd % traits::RFS) = xrd;
|
*(X+rd) = xrd;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TRAP_CSRRCI:break;
|
TRAP_CSRRCI:break;
|
||||||
|
|
Loading…
Reference in New Issue