updates generate tgc_c definition

This commit is contained in:
Eyck Jentzsch 2022-07-11 22:58:10 +02:00
parent feaa49d367
commit 12ccfc055a
2 changed files with 143 additions and 216 deletions

View File

@ -53,7 +53,7 @@ template <> struct traits<tgc_c> {
static constexpr std::array<const char*, 36> reg_aliases{ static constexpr std::array<const char*, 36> reg_aliases{
{"ZERO", "RA", "SP", "GP", "TP", "T0", "T1", "T2", "S0", "S1", "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "S2", "S3", "S4", "S5", "S6", "S7", "S8", "S9", "S10", "S11", "T3", "T4", "T5", "T6", "PC", "NEXT_PC", "PRIV", "DPC"}}; {"ZERO", "RA", "SP", "GP", "TP", "T0", "T1", "T2", "S0", "S1", "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "S2", "S3", "S4", "S5", "S6", "S7", "S8", "S9", "S10", "S11", "T3", "T4", "T5", "T6", "PC", "NEXT_PC", "PRIV", "DPC"}};
enum constants {MISA_VAL=0b01000000000000000001000100000100, MARCHID_VAL=0x80000003, RFS=32, INSTR_ALIGNMENT=2, XLEN=32, CSR_SIZE=4096, fence=0, fencei=1, fencevmal=2, fencevmau=3, MUL_LEN=64}; enum constants {MISA_VAL=0b01000000000000000001000100000100, MARCHID_VAL=0x80000003, XLEN=32, INSTR_ALIGNMENT=2, RFS=32, fence=0, fencei=1, fencevmal=2, fencevmau=3, CSR_SIZE=4096, MUL_LEN=64};
constexpr static unsigned FP_REGS_SIZE = 0; constexpr static unsigned FP_REGS_SIZE = 0;
@ -81,7 +81,7 @@ template <> struct traits<tgc_c> {
enum sreg_flag_e { FLAGS }; enum sreg_flag_e { FLAGS };
enum mem_type_e { MEM, CSR, FENCE, RES }; enum mem_type_e { MEM, FENCE, RES, CSR };
enum class opcode_e : unsigned short { enum class opcode_e : unsigned short {
LUI = 0, LUI = 0,
@ -124,56 +124,53 @@ template <> struct traits<tgc_c> {
FENCE = 37, FENCE = 37,
ECALL = 38, ECALL = 38,
EBREAK = 39, EBREAK = 39,
URET = 40, MRET = 40,
SRET = 41, WFI = 41,
MRET = 42, CSRRW = 42,
WFI = 43, CSRRS = 43,
DRET = 44, CSRRC = 44,
CSRRW = 45, CSRRWI = 45,
CSRRS = 46, CSRRSI = 46,
CSRRC = 47, CSRRCI = 47,
CSRRWI = 48, FENCE_I = 48,
CSRRSI = 49, MUL = 49,
CSRRCI = 50, MULH = 50,
FENCE_I = 51, MULHSU = 51,
MUL = 52, MULHU = 52,
MULH = 53, DIV = 53,
MULHSU = 54, DIVU = 54,
MULHU = 55, REM = 55,
DIV = 56, REMU = 56,
DIVU = 57, CADDI4SPN = 57,
REM = 58, CLW = 58,
REMU = 59, CSW = 59,
CADDI4SPN = 60, CADDI = 60,
CLW = 61, CNOP = 61,
CSW = 62, CJAL = 62,
CADDI = 63, CLI = 63,
CNOP = 64, CLUI = 64,
CJAL = 65, CADDI16SP = 65,
CLI = 66, __reserved_clui = 66,
CLUI = 67, CSRLI = 67,
CADDI16SP = 68, CSRAI = 68,
__reserved_clui = 69, CANDI = 69,
CSRLI = 70, CSUB = 70,
CSRAI = 71, CXOR = 71,
CANDI = 72, COR = 72,
CSUB = 73, CAND = 73,
CXOR = 74, CJ = 74,
COR = 75, CBEQZ = 75,
CAND = 76, CBNEZ = 76,
CJ = 77, CSLLI = 77,
CBEQZ = 78, CLWSP = 78,
CBNEZ = 79, CMV = 79,
CSLLI = 80, CJR = 80,
CLWSP = 81, __reserved_cmv = 81,
CMV = 82, CADD = 82,
CJR = 83, CJALR = 83,
__reserved_cmv = 84, CEBREAK = 84,
CADD = 85, CSWSP = 85,
CJALR = 86, DII = 86,
CEBREAK = 87,
CSWSP = 88,
DII = 89,
MAX_OPCODE MAX_OPCODE
}; };
}; };

View File

@ -197,7 +197,7 @@ private:
typename arch::traits<ARCH>::opcode_e op; typename arch::traits<ARCH>::opcode_e op;
}; };
const std::array<InstructionDesriptor, 90> instr_descr = {{ const std::array<InstructionDesriptor, 87> instr_descr = {{
/* entries are: size, valid value, valid mask, function ptr */ /* entries are: size, valid value, valid mask, function ptr */
{32, 0b00000000000000000000000000110111, 0b00000000000000000000000001111111, arch::traits<ARCH>::opcode_e::LUI}, {32, 0b00000000000000000000000000110111, 0b00000000000000000000000001111111, arch::traits<ARCH>::opcode_e::LUI},
{32, 0b00000000000000000000000000010111, 0b00000000000000000000000001111111, arch::traits<ARCH>::opcode_e::AUIPC}, {32, 0b00000000000000000000000000010111, 0b00000000000000000000000001111111, arch::traits<ARCH>::opcode_e::AUIPC},
@ -239,11 +239,8 @@ private:
{32, 0b00000000000000000000000000001111, 0b00000000000000000111000001111111, arch::traits<ARCH>::opcode_e::FENCE}, {32, 0b00000000000000000000000000001111, 0b00000000000000000111000001111111, arch::traits<ARCH>::opcode_e::FENCE},
{32, 0b00000000000000000000000001110011, 0b11111111111111111111111111111111, arch::traits<ARCH>::opcode_e::ECALL}, {32, 0b00000000000000000000000001110011, 0b11111111111111111111111111111111, arch::traits<ARCH>::opcode_e::ECALL},
{32, 0b00000000000100000000000001110011, 0b11111111111111111111111111111111, arch::traits<ARCH>::opcode_e::EBREAK}, {32, 0b00000000000100000000000001110011, 0b11111111111111111111111111111111, arch::traits<ARCH>::opcode_e::EBREAK},
{32, 0b00000000001000000000000001110011, 0b11111111111111111111111111111111, arch::traits<ARCH>::opcode_e::URET},
{32, 0b00010000001000000000000001110011, 0b11111111111111111111111111111111, arch::traits<ARCH>::opcode_e::SRET},
{32, 0b00110000001000000000000001110011, 0b11111111111111111111111111111111, arch::traits<ARCH>::opcode_e::MRET}, {32, 0b00110000001000000000000001110011, 0b11111111111111111111111111111111, arch::traits<ARCH>::opcode_e::MRET},
{32, 0b00010000010100000000000001110011, 0b11111111111111111111111111111111, arch::traits<ARCH>::opcode_e::WFI}, {32, 0b00010000010100000000000001110011, 0b11111111111111111111111111111111, arch::traits<ARCH>::opcode_e::WFI},
{32, 0b01111011001000000000000001110011, 0b11111111111111111111111111111111, arch::traits<ARCH>::opcode_e::DRET},
{32, 0b00000000000000000001000001110011, 0b00000000000000000111000001111111, arch::traits<ARCH>::opcode_e::CSRRW}, {32, 0b00000000000000000001000001110011, 0b00000000000000000111000001111111, arch::traits<ARCH>::opcode_e::CSRRW},
{32, 0b00000000000000000010000001110011, 0b00000000000000000111000001111111, arch::traits<ARCH>::opcode_e::CSRRS}, {32, 0b00000000000000000010000001110011, 0b00000000000000000111000001111111, arch::traits<ARCH>::opcode_e::CSRRS},
{32, 0b00000000000000000011000001110011, 0b00000000000000000111000001111111, arch::traits<ARCH>::opcode_e::CSRRC}, {32, 0b00000000000000000011000001110011, 0b00000000000000000111000001111111, arch::traits<ARCH>::opcode_e::CSRRC},
@ -468,7 +465,7 @@ 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
{ {
int32_t new_pc = (*(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm)) & ~ 1; 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);
} }
@ -666,11 +663,12 @@ 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
{ {
uint8_t read_res = super::template read_mem<uint8_t>(traits::MEM, *(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);
if(this->core.trap_state) goto TRAP_LB; if(this->core.trap_state) goto TRAP_LB;
int8_t res = (int8_t)read_res; int8_t res = (int8_t)read_res;
if((rd % traits::RFS) != 0) { if((rd % traits::RFS) != 0) {
*(X+rd % traits::RFS) = res; *(X+rd % traits::RFS) = (int32_t)res;
} }
} }
TRAP_LB:break; TRAP_LB:break;
@ -692,11 +690,11 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
// execute instruction // execute instruction
{ {
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); int16_t read_res = super::template read_mem<int16_t>(traits::MEM, load_address);
if(this->core.trap_state) goto TRAP_LH; if(this->core.trap_state) goto TRAP_LH;
int16_t res = (int16_t)read_res; int16_t res = (int16_t)read_res;
if((rd % traits::RFS) != 0) { if((rd % traits::RFS) != 0) {
*(X+rd % traits::RFS) = res; *(X+rd % traits::RFS) = (int32_t)res;
} }
} }
TRAP_LH:break; TRAP_LH:break;
@ -718,11 +716,11 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
// execute instruction // execute instruction
{ {
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);
uint32_t read_res = super::template read_mem<uint32_t>(traits::MEM, load_address); int32_t read_res = super::template read_mem<int32_t>(traits::MEM, load_address);
if(this->core.trap_state) goto TRAP_LW; if(this->core.trap_state) goto TRAP_LW;
int32_t res = (int32_t)read_res; int32_t res = (int32_t)read_res;
if((rd % traits::RFS) != 0) { if((rd % traits::RFS) != 0) {
*(X+rd % traits::RFS) = (uint32_t)res; *(X+rd % traits::RFS) = (int32_t)res;
} }
} }
TRAP_LW:break; TRAP_LW:break;
@ -743,11 +741,12 @@ 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
{ {
uint8_t read_res = super::template read_mem<uint8_t>(traits::MEM, *(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);
if(this->core.trap_state) goto TRAP_LBU; if(this->core.trap_state) goto TRAP_LBU;
uint8_t res = (uint8_t)read_res; uint8_t res = (uint8_t)read_res;
if((rd % traits::RFS) != 0) { if((rd % traits::RFS) != 0) {
*(X+rd % traits::RFS) = res; *(X+rd % traits::RFS) = (uint32_t)res;
} }
} }
TRAP_LBU:break; TRAP_LBU:break;
@ -773,7 +772,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
if(this->core.trap_state) goto TRAP_LHU; if(this->core.trap_state) goto TRAP_LHU;
uint16_t res = (uint16_t)read_res; uint16_t res = (uint16_t)read_res;
if((rd % traits::RFS) != 0) { if((rd % traits::RFS) != 0) {
*(X+rd % traits::RFS) = res; *(X+rd % traits::RFS) = (uint32_t)res;
} }
} }
TRAP_LHU:break; TRAP_LHU:break;
@ -794,7 +793,8 @@ 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
{ {
super::template write_mem<uint8_t>(traits::MEM, *(X+rs1 % traits::RFS) + (int16_t)sext<12>(imm), (int8_t)*(X+rs2 % traits::RFS)); 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) goto TRAP_SB; if(this->core.trap_state) goto TRAP_SB;
} }
TRAP_SB:break; TRAP_SB:break;
@ -838,7 +838,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
// execute instruction // execute instruction
{ {
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, *(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) goto TRAP_SW; if(this->core.trap_state) goto TRAP_SW;
} }
TRAP_SW:break; TRAP_SW:break;
@ -882,7 +882,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
// execute instruction // execute instruction
{ {
if((rd % traits::RFS) != 0) { if((rd % traits::RFS) != 0) {
*(X+rd % traits::RFS) = (int32_t)*(X+rs1 % traits::RFS) < (int16_t)sext<12>(imm)? 1 : 0; *(X+rd % traits::RFS) = ((int32_t)*(X+rs1 % traits::RFS) < (int16_t)sext<12>(imm))? 1 : 0;
} }
} }
TRAP_SLTI:break; TRAP_SLTI:break;
@ -991,15 +991,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(shamt > 31) {
raise(0, 0);
}
else {
if((rd % traits::RFS) != 0) { if((rd % traits::RFS) != 0) {
*(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) << shamt; *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) << shamt;
} }
} }
}
TRAP_SLLI:break; TRAP_SLLI:break;
}// @suppress("No break at end of case") }// @suppress("No break at end of case")
case arch::traits<ARCH>::opcode_e::SRLI: { case arch::traits<ARCH>::opcode_e::SRLI: {
@ -1018,15 +1013,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(shamt > 31) {
raise(0, 0);
}
else {
if((rd % traits::RFS) != 0) { if((rd % traits::RFS) != 0) {
*(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) >> shamt; *(X+rd % traits::RFS) = *(X+rs1 % traits::RFS) >> shamt;
} }
} }
}
TRAP_SRLI:break; TRAP_SRLI:break;
}// @suppress("No break at end of case") }// @suppress("No break at end of case")
case arch::traits<ARCH>::opcode_e::SRAI: { case arch::traits<ARCH>::opcode_e::SRAI: {
@ -1045,15 +1035,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(shamt > 31) {
raise(0, 0);
}
else {
if((rd % traits::RFS) != 0) { if((rd % traits::RFS) != 0) {
*(X+rd % traits::RFS) = (int32_t)*(X+rs1 % traits::RFS) >> shamt; *(X+rd % traits::RFS) = (int32_t)*(X+rs1 % traits::RFS) >> shamt;
} }
} }
}
TRAP_SRAI:break; TRAP_SRAI:break;
}// @suppress("No break at end of case") }// @suppress("No break at end of case")
case arch::traits<ARCH>::opcode_e::ADD: { case arch::traits<ARCH>::opcode_e::ADD: {
@ -1324,32 +1309,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
} }
TRAP_EBREAK:break; TRAP_EBREAK:break;
}// @suppress("No break at end of case") }// @suppress("No break at end of case")
case arch::traits<ARCH>::opcode_e::URET: {
if(this->disass_enabled){
/* generate console output when executing the command */
this->core.disass_output(pc.val, "uret");
}
// used registers// calculate next pc value
*NEXT_PC = *PC + 4;
// execute instruction
{
leave(0);
}
TRAP_URET:break;
}// @suppress("No break at end of case")
case arch::traits<ARCH>::opcode_e::SRET: {
if(this->disass_enabled){
/* generate console output when executing the command */
this->core.disass_output(pc.val, "sret");
}
// used registers// calculate next pc value
*NEXT_PC = *PC + 4;
// execute instruction
{
leave(1);
}
TRAP_SRET:break;
}// @suppress("No break at end of case")
case arch::traits<ARCH>::opcode_e::MRET: { case arch::traits<ARCH>::opcode_e::MRET: {
if(this->disass_enabled){ if(this->disass_enabled){
/* generate console output when executing the command */ /* generate console output when executing the command */
@ -1376,30 +1335,6 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
} }
TRAP_WFI:break; TRAP_WFI:break;
}// @suppress("No break at end of case") }// @suppress("No break at end of case")
case arch::traits<ARCH>::opcode_e::DRET: {
if(this->disass_enabled){
/* generate console output when executing the command */
this->core.disass_output(pc.val, "dret");
}
// used registers
auto* PRIV = reinterpret_cast<uint8_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::PRIV]);
auto* DPC = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::DPC]);
// calculate next pc value
*NEXT_PC = *PC + 4;
// execute instruction
{
if(*PRIV < 4) {
raise(0, 2);
}
else {
*NEXT_PC = *DPC;
super::ex_info.branch_taken=true;
*PRIV &= 0x3;
}
}
TRAP_DRET:break;
}// @suppress("No break at end of case")
case arch::traits<ARCH>::opcode_e::CSRRW: { case arch::traits<ARCH>::opcode_e::CSRRW: {
uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rd = ((bit_sub<7,5>(instr)));
uint8_t rs1 = ((bit_sub<15,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr)));
@ -1850,7 +1785,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
// execute instruction // execute instruction
{ {
uint32_t load_address = *(X+rs1 + 8) + uimm; uint32_t load_address = *(X+rs1 + 8) + uimm;
uint32_t read_res = super::template read_mem<uint32_t>(traits::MEM, load_address); int32_t read_res = super::template read_mem<int32_t>(traits::MEM, load_address);
if(this->core.trap_state) goto TRAP_CLW; if(this->core.trap_state) goto TRAP_CLW;
*(X+rd + 8) = (int32_t)read_res; *(X+rd + 8) = (int32_t)read_res;
} }
@ -1873,7 +1808,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
// execute instruction // execute instruction
{ {
uint32_t load_address = *(X+rs1 + 8) + uimm; uint32_t load_address = *(X+rs1 + 8) + uimm;
super::template write_mem<uint32_t>(traits::MEM, load_address, *(X+rs2 + 8)); super::template write_mem<uint32_t>(traits::MEM, load_address, (int32_t)*(X+rs2 + 8));
if(this->core.trap_state) goto TRAP_CSW; if(this->core.trap_state) goto TRAP_CSW;
} }
TRAP_CSW:break; TRAP_CSW:break;
@ -1893,8 +1828,10 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
*NEXT_PC = *PC + 2; *NEXT_PC = *PC + 2;
// execute instruction // execute instruction
{ {
if((rs1 % traits::RFS) != 0) {
*(X+rs1 % traits::RFS) = *(X+rs1 % traits::RFS) + (int8_t)sext<6>(imm); *(X+rs1 % traits::RFS) = *(X+rs1 % traits::RFS) + (int8_t)sext<6>(imm);
} }
}
TRAP_CADDI:break; TRAP_CADDI:break;
}// @suppress("No break at end of case") }// @suppress("No break at end of case")
case arch::traits<ARCH>::opcode_e::CNOP: { case arch::traits<ARCH>::opcode_e::CNOP: {
@ -2027,8 +1964,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
*NEXT_PC = *PC + 2; *NEXT_PC = *PC + 2;
// execute instruction // execute instruction
{ {
uint8_t rs1_idx = rs1 + 8; *(X+rs1 + 8) = *(X+rs1 + 8) >> shamt;
*(X+rs1_idx) = *(X+rs1_idx) >> shamt;
} }
TRAP_CSRLI:break; TRAP_CSRLI:break;
}// @suppress("No break at end of case") }// @suppress("No break at end of case")
@ -2048,13 +1984,11 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
// execute instruction // execute instruction
{ {
if(shamt) { if(shamt) {
uint8_t rs1_idx = rs1 + 8; *(X+rs1 + 8) = ((int32_t)*(X+rs1 + 8)) >> shamt;
*(X+rs1_idx) = ((int32_t)*(X+rs1_idx)) >> shamt;
} }
else { else {
if(traits::XLEN == 128) { if(traits::XLEN == 128) {
uint8_t rs1_idx = rs1 + 8; *(X+rs1 + 8) = ((int32_t)*(X+rs1 + 8)) >> 64;
*(X+rs1_idx) = ((int32_t)*(X+rs1_idx)) >> 64;
} }
} }
} }
@ -2075,8 +2009,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
*NEXT_PC = *PC + 2; *NEXT_PC = *PC + 2;
// execute instruction // execute instruction
{ {
uint8_t rs1_idx = rs1 + 8; *(X+rs1 + 8) = *(X+rs1 + 8) & (int8_t)sext<6>(imm);
*(X+rs1_idx) = *(X+rs1_idx) & (int8_t)sext<6>(imm);
} }
TRAP_CANDI:break; TRAP_CANDI:break;
}// @suppress("No break at end of case") }// @suppress("No break at end of case")
@ -2095,8 +2028,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
*NEXT_PC = *PC + 2; *NEXT_PC = *PC + 2;
// execute instruction // execute instruction
{ {
uint8_t rd_idx = rd + 8; *(X+rd + 8) = *(X+rd + 8) - *(X+rs2 + 8);
*(X+rd_idx) = *(X+rd_idx) - *(X+rs2 + 8);
} }
TRAP_CSUB:break; TRAP_CSUB:break;
}// @suppress("No break at end of case") }// @suppress("No break at end of case")
@ -2115,8 +2047,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
*NEXT_PC = *PC + 2; *NEXT_PC = *PC + 2;
// execute instruction // execute instruction
{ {
uint8_t rd_idx = rd + 8; *(X+rd + 8) = *(X+rd + 8) ^ *(X+rs2 + 8);
*(X+rd_idx) = *(X+rd_idx) ^ *(X+rs2 + 8);
} }
TRAP_CXOR:break; TRAP_CXOR:break;
}// @suppress("No break at end of case") }// @suppress("No break at end of case")
@ -2135,8 +2066,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
*NEXT_PC = *PC + 2; *NEXT_PC = *PC + 2;
// execute instruction // execute instruction
{ {
uint8_t rd_idx = rd + 8; *(X+rd + 8) = *(X+rd + 8) | *(X+rs2 + 8);
*(X+rd_idx) = *(X+rd_idx) | *(X+rs2 + 8);
} }
TRAP_COR:break; TRAP_COR:break;
}// @suppress("No break at end of case") }// @suppress("No break at end of case")
@ -2155,8 +2085,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
*NEXT_PC = *PC + 2; *NEXT_PC = *PC + 2;
// execute instruction // execute instruction
{ {
uint8_t rd_idx = rd + 8; *(X+rd + 8) = *(X+rd + 8) & *(X+rs2 + 8);
*(X+rd_idx) = *(X+rd_idx) & *(X+rs2 + 8);
} }
TRAP_CAND:break; TRAP_CAND:break;
}// @suppress("No break at end of case") }// @suppress("No break at end of case")
@ -2258,11 +2187,12 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
*NEXT_PC = *PC + 2; *NEXT_PC = *PC + 2;
// execute instruction // execute instruction
{ {
if(rd) {
uint32_t offs = *(X+2) + uimm; uint32_t offs = *(X+2) + uimm;
uint32_t read_res = super::template read_mem<uint32_t>(traits::MEM, offs); int32_t read_res = super::template read_mem<int32_t>(traits::MEM, offs);
if(this->core.trap_state) goto TRAP_CLWSP; if(this->core.trap_state) goto TRAP_CLWSP;
*(X+rd % traits::RFS) = (int32_t)read_res; int32_t res = read_res;
if(rd % traits::RFS) {
*(X+rd % traits::RFS) = res;
} }
else { else {
raise(0, 2); raise(0, 2);
@ -2363,7 +2293,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
*NEXT_PC = *PC + 2; *NEXT_PC = *PC + 2;
// execute instruction // execute instruction
{ {
int32_t new_pc = *(X+rs1 % traits::RFS); uint32_t new_pc = *(X+rs1 % traits::RFS);
*(X+1) = *PC + 2; *(X+1) = *PC + 2;
*NEXT_PC = new_pc & ~ 0x1; *NEXT_PC = new_pc & ~ 0x1;
super::ex_info.branch_taken=true; super::ex_info.branch_taken=true;